mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
x86/vmx: use a MEMF_no_refcount domheap page for APIC_DEFAULT_PHYS_BASE
vmx_alloc_vlapic_mapping() currently contains some very odd looking code that allocates a MEMF_no_owner domheap page and then shares with the guest as if it were a xenheap page. This then requires vmx_free_vlapic_mapping() to call a special function in the mm code: free_shared_domheap_page(). By using a MEMF_no_refcount domheap page instead, the odd looking code in vmx_alloc_vlapic_mapping() can simply use get_page_and_type() to set up a writable mapping before insertion in the P2M and vmx_free_vlapic_mapping() can simply release the page using put_page_alloc_ref() followed by put_page_and_type(). This then allows free_shared_domheap_page() to be purged. Signed-off-by: Paul Durrant <pdurrant@amazon.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
This commit is contained in:
1 parent
c793d13944
commit
ea3daabff5
3 files changed
+18
-15
No files matched your search
@@ -3029,12 +3029,22 @@ static int vmx_alloc_vlapic_mapping(struct domain *d)
|
||||
if ( !cpu_has_vmx_virtualize_apic_accesses )
|
||||
return 0;
|
||||
|
||||
pg = alloc_domheap_page(d, MEMF_no_owner);
|
||||
pg = alloc_domheap_page(d, MEMF_no_refcount);
|
||||
if ( !pg )
|
||||
return -ENOMEM;
|
||||
|
||||
if ( !get_page_and_type(pg, d, PGT_writable_page) )
|
||||
{
|
||||
/*
|
||||
* The domain can't possibly know about this page yet, so failure
|
||||
* here is a clear indication of something fishy going on.
|
||||
*/
|
||||
domain_crash(d);
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
mfn = page_to_mfn(pg);
|
||||
clear_domain_page(mfn);
|
||||
share_xen_page_with_guest(pg, d, SHARE_rw);
|
||||
d->arch.hvm.vmx.apic_access_mfn = mfn;
|
||||
|
||||
return set_mmio_p2m_entry(d, paddr_to_pfn(APIC_DEFAULT_PHYS_BASE), mfn,
|
||||
@@ -3048,7 +3058,12 @@ static void vmx_free_vlapic_mapping(struct domain *d)
|
||||
|
||||
d->arch.hvm.vmx.apic_access_mfn = _mfn(0);
|
||||
if ( !mfn_eq(mfn, _mfn(0)) )
|
||||
free_shared_domheap_page(mfn_to_page(mfn));
|
||||
{
|
||||
struct page_info *pg = mfn_to_page(mfn);
|
||||
|
||||
put_page_alloc_ref(pg);
|
||||
put_page_and_type(pg);
|
||||
}
|
||||
}
|
||||
|
||||
static void vmx_install_vlapic_mapping(struct vcpu *v)
|
||||
|
||||
@@ -502,16 +502,6 @@ void share_xen_page_with_guest(struct page_info *page, struct domain *d,
|
||||
spin_unlock(&d->page_alloc_lock);
|
||||
}
|
||||
|
||||
void free_shared_domheap_page(struct page_info *page)
|
||||
{
|
||||
put_page_alloc_ref(page);
|
||||
if ( !test_and_clear_bit(_PGC_xen_heap, &page->count_info) )
|
||||
ASSERT_UNREACHABLE();
|
||||
page->u.inuse.type_info = 0;
|
||||
page_set_owner(page, NULL);
|
||||
free_domheap_page(page);
|
||||
}
|
||||
|
||||
void make_cr3(struct vcpu *v, mfn_t mfn)
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
|
||||
@@ -320,8 +320,6 @@ struct page_info
|
||||
|
||||
#define maddr_get_owner(ma) (page_get_owner(maddr_to_page((ma))))
|
||||
|
||||
extern void free_shared_domheap_page(struct page_info *page);
|
||||
|
||||
#define frame_table ((struct page_info *)FRAMETABLE_VIRT_START)
|
||||
extern unsigned long max_page;
|
||||
extern unsigned long total_pages;
|
||||
|
||||