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:
Paul Durrant authored and Andrew Cooper committed 2020-02-14 14:24:50 +00:00
1 parent c793d13944
commit ea3daabff5
3 files changed
+18 -15

No files matched your search

+18 -3
View File
@@ -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)
-10
View File
@@ -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;
-2
View File
@@ -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;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.