[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] Why does xc_map_foreign_range() refuse to map pfns below 1M from a domU

On 12/04/2013 12:36 PM, Jan Beulich wrote:
On 04.12.13 at 12:23, Tomasz Wroblewski <tomasz.wroblewski@xxxxxxxxxx> 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 <Ian.Campbell@xxxxxxxxxx> 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)
remap_area_pfn_pte() (mmu.c)
pfn_pte() (somewhere, one of the pgtable.h hdrs)
__pte() (paravirt.h)
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;

Xen-devel mailing list



Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.