From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Cooper Subject: Re: [PATCH] VMX: allocate APIC access page from domain heap Date: Wed, 16 Dec 2015 12:11:47 +0000 Message-ID: <56715503.3000905@citrix.com> References: <5671277C02000078000BFFFD@prv-mh.provo.novell.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1a9Avz-0004OP-B1 for xen-devel@lists.xenproject.org; Wed, 16 Dec 2015 12:11:55 +0000 In-Reply-To: <5671277C02000078000BFFFD@prv-mh.provo.novell.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Jan Beulich , xen-devel Cc: Kevin Tian , Keir Fraser , Jun Nakajima List-Id: xen-devel@lists.xenproject.org On 16/12/15 07:57, Jan Beulich wrote: > ... since we don't need its virtual address anywhere (it's a > placeholder page only after all). For this wo work (and possibly be "to work" > done elsewhere too) share_xen_page_with_guest() needs to mark pages > handed to it as Xen heap ones. > > To be on the safe side, also explicitly clear the page (not having done > so was okay due to the XSA-100 fix, but is still a latent bug since we > don't formally guarantee allocations to come out zeroed, and in fact > this property may disappear again as soon as the asynchronous runtime > scrubbing patches arrive). > > Signed-off-by: Jan Beulich > --- > Alternatives might be to use a > - global (or perhaps per-node) page across VMs (on the basis that VMs > shouldn't be writing into that page anyway) I am surprised by the concern about a zeroed page, yet not concerned by sharing this page across VMs. Even though we can get away with sharing it across VMs, we should probably avoid it, to be on the safe side. It is only 1 page per VM. > - fake MFN pointing into nowhere (would need to ensure no side effects > can occur, like PCIe errors or NMIs) > > --- a/xen/arch/x86/hvm/vmx/vmx.c > +++ b/xen/arch/x86/hvm/vmx/vmx.c > @@ -2402,19 +2402,21 @@ gp_fault: > > static int vmx_alloc_vlapic_mapping(struct domain *d) > { > - void *apic_va; > + struct page_info *pg; > + unsigned long mfn; > > if ( !cpu_has_vmx_virtualize_apic_accesses ) > return 0; > > - apic_va = alloc_xenheap_page(); > - if ( apic_va == NULL ) > + pg = alloc_domheap_page(d, MEMF_no_owner); > + if ( !pg ) > return -ENOMEM; > - share_xen_page_with_guest(virt_to_page(apic_va), d, XENSHARE_writable); > - d->arch.hvm_domain.vmx.apic_access_mfn = virt_to_mfn(apic_va); > - set_mmio_p2m_entry(d, paddr_to_pfn(APIC_DEFAULT_PHYS_BASE), > - _mfn(virt_to_mfn(apic_va)), PAGE_ORDER_4K, > - p2m_get_hostp2m(d)->default_access); > + mfn = page_to_mfn(pg); > + clear_domain_page(mfn); > + share_xen_page_with_guest(pg, d, XENSHARE_writable); > + d->arch.hvm_domain.vmx.apic_access_mfn = mfn; > + set_mmio_p2m_entry(d, paddr_to_pfn(APIC_DEFAULT_PHYS_BASE), _mfn(mfn), > + PAGE_ORDER_4K, p2m_get_hostp2m(d)->default_access); > > return 0; > } > @@ -2422,8 +2424,16 @@ static int vmx_alloc_vlapic_mapping(stru > static void vmx_free_vlapic_mapping(struct domain *d) > { > unsigned long mfn = d->arch.hvm_domain.vmx.apic_access_mfn; > + > if ( mfn != 0 ) > - free_xenheap_page(mfn_to_virt(mfn)); > + { > + struct page_info *pg = mfn_to_page(mfn); > + > + if ( test_and_clear_bit(_PGC_allocated, &pg->count_info) ) > + put_page(pg); > + clear_bit(_PGC_xen_heap, &pg->count_info); This is a different teardown procedure to the allocation. Instead, it would be better to either ASSERT that _PGC_allocated is set, or move the _PGC_xen_heap change into the if() condition. ~Andrew > + free_domheap_page(pg); > + } > } > > static void vmx_install_vlapic_mapping(struct vcpu *v) > --- a/xen/arch/x86/mm.c > +++ b/xen/arch/x86/mm.c > @@ -454,7 +454,7 @@ void share_xen_page_with_guest( > /* Only add to the allocation list if the domain isn't dying. */ > if ( !d->is_dying ) > { > - page->count_info |= PGC_allocated | 1; > + page->count_info |= PGC_xen_heap | PGC_allocated | 1; > if ( unlikely(d->xenheap_pages++ == 0) ) > get_knownalive_domain(d); > page_list_add_tail(page, &d->xenpage_list); > > >