From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tomasz Wroblewski Subject: Re: Why does xc_map_foreign_range() refuse to map pfns below 1M from a domU Date: Wed, 4 Dec 2013 13:01:10 +0100 Message-ID: <529F1986.6030109@citrix.com> References: <1386085913.13256.52.camel@kazak.uk.xensource.com> <1386086974.13256.60.camel@kazak.uk.xensource.com> <529E16B0.5010104@citrix.com> <20131203190741.GB31373@phenom.dumpdata.com> <529F02D5.8090206@citrix.com> <529F12AD0200007800109E63@nat28.tlf.novell.com> <1386153568.15530.24.camel@kazak.uk.xensource.com> <529F15360200007800109EA3@nat28.tlf.novell.com> <1386153913.15530.27.camel@kazak.uk.xensource.com> <529F17DD0200007800109EDA@nat28.tlf.novell.com> <1386155067.17466.16.camel@kazak.uk.xensource.com> <529F109F.8080508@citrix.com> <529F21D10200007800109F6B@nat28.tlf.novell.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; Format="flowed" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <529F21D10200007800109F6B@nat28.tlf.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 Cc: Razvan Cojocaru , Ian Campbell , "xen-devel@lists.xen.org" List-Id: xen-devel@lists.xenproject.org On 12/04/2013 12:36 PM, Jan Beulich wrote: >>>> On 04.12.13 at 12:23, Tomasz Wroblewski wrote: >> On 12/04/2013 12:04 PM, Ian Campbell wrote: >>> On Wed, 2013-12-04 at 10:54 +0000, Jan Beulich wrote: >>>>>>> On 04.12.13 at 11:45, Ian Campbell wrote: >>>>> Correct. The check for mapping domain 0's 1:1 map is overly broad I >>>>> think, and erroneously prevents a domU from mapping a foreign PFN < 1M. >>>> >>>> But that's the source of my not understanding: xen_make_pte() >>>> derives addr from the passed in pte, and that pte can - for a >>>> foreign domain's page - hardly hold a PFN. Otherwise how would >>>> the translation to MFN be supposed to happen? Yet, if it's a >>>> machine address that's coming in, it can't point into the low 1Mb. >>> >>> Isn't it a foreign gpfn at this point, which for an HVM guest is >>> actually a PFN not an MFN? >>> >>> You are making me think I might be talking out my a**e though, because >>> what is a foreign mapping even doing in xen_make_pte -- those need to be >>> instantiated in a special way. >>> >> I believe the callpath for this is >> >> xen_remap_domain_range() (mmu.c) >> | >> v >> remap_area_pfn_pte() (mmu.c) >> | >> v >> pfn_pte() (somewhere, one of the pgtable.h hdrs) >> | >> v >> __pte() (paravirt.h) >> | >> v >> xen_make_pte (mmu.c) via pv_mmu_ops.make_pte >> >> Sorry, can't offer much insight as to why addr in pte holds the hvm's PFN, >> but it seems the case. > > But that's a fundamental thing to explain. As Ian says - foreign PFNs > shouldn't make it here, or else how do you know how to translate > them to MFNs (as you can't consult the local P2M table to do so)? > I was under the impression that the translation is done inside in xen inside HYPERVISOR_mmu_update, which gets called from xen_remap_domain_mfn_range shortly after setting up the ptes via xen_make_pte: int xen_remap_domain_mfn_range(struct vm_area_struct *vma, unsigned long addr, xen_pfn_t mfn, int nr, pgprot_t prot, unsigned domid, struct page **pages) ... err = apply_to_page_range(vma->vm_mm, addr, range, remap_area_mfn_pte_fn, &rmd); ^^^ this calls xen_make_pte via the callpath I quoted in previous post if (err) goto out; err = HYPERVISOR_mmu_update(mmu_update, batch, NULL, domid); ^^^ this goes into xen and does p2m translation and mmu setup etc if (err < 0) goto out; ...