FYI, this breaks the build is CONFIG_PAGING_LEVELS != 4
p2m.c: In function `p2m_change_type_global':
p2m.c:2211: error: `i4' undeclared (first use in this function)
p2m.c:2211: error: (Each undeclared identifier is reported only once
p2m.c:2211: error: for each function it appears in.)
MRJ
On Thu, Dec 17, 2009 at 1:41 AM, Xen patchbot-unstable
<patchbot-unstable@xxxxxxxxxxxxxxxxxxx> wrote:
> # HG changeset patch
> # User Keir Fraser <keir.fraser@xxxxxxxxxx>
> # Date 1261031276 0
> # Node ID 257bd5e90294b7e768224c89908745e66efcbcac
> # Parent 34d620a47c636c0c72b1270ef6410953909a1bdc
> M2P translation cannot be handled through flat table with only one slot per
> MFN
> when an MFN is shared. However, all existing calls can either infer the GFN
> (for
> example p2m table destructor) or will not need to know GFN for shared pages.
> This patch identifies and fixes all the M2P accessors, either by removing the
> translation altogether or by making the relevant modifications. Shared MFNs
> have
> a special value of SHARED_M2P_ENTRY stored in their M2P table slot.
>
> Signed-off-by: Grzegorz Milos <Grzegorz.Milos@xxxxxxxxxx>
> ---
> xen/arch/x86/cpu/mcheck/mce_intel.c | 4 ++++
> xen/arch/x86/domain_build.c | 1 +
> xen/arch/x86/mm.c | 17 +++++++++++++++--
> xen/arch/x86/mm/mem_sharing.c | 17 +++++++++++------
> xen/arch/x86/mm/p2m.c | 29 ++++++++++++++++++++++-------
> xen/arch/x86/mm/paging.c | 2 ++
> xen/arch/x86/mm/shadow/multi.c | 4 ++++
> xen/arch/x86/mm/shadow/private.h | 2 ++
> xen/arch/x86/traps.c | 18 +++++++++++++++---
> xen/common/domctl.c | 1 +
> xen/common/grant_table.c | 2 ++
> xen/common/memory.c | 30 +++++++++++++++++++++++++++---
> xen/drivers/passthrough/iommu.c | 1 +
> xen/include/asm-x86/mm.h | 22 +++++++++++++++++-----
> 14 files changed, 124 insertions(+), 26 deletions(-)
>
> diff -r 34d620a47c63 -r 257bd5e90294 xen/arch/x86/cpu/mcheck/mce_intel.c
> --- a/xen/arch/x86/cpu/mcheck/mce_intel.c Thu Dec 17 06:27:56 2009 +0000
> +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c Thu Dec 17 06:27:56 2009 +0000
> @@ -356,6 +356,10 @@ static void intel_UCR_handler(struct mci
> /* Fill vMCE# injection and vMCE# MSR virtualization "
> * "related data */
> bank->mc_domid = result->owner;
> + /* XXX: Cannot handle shared pages yet
> + * (this should identify all domains and gfn mapping to
> + * the mfn in question) */
> + BUG_ON( result->owner == DOMID_COW );
> if ( result->owner != DOMID_XEN ) {
> d = get_domain_by_id(result->owner);
> gfn =
> diff -r 34d620a47c63 -r 257bd5e90294 xen/arch/x86/domain_build.c
> --- a/xen/arch/x86/domain_build.c Thu Dec 17 06:27:56 2009 +0000
> +++ b/xen/arch/x86/domain_build.c Thu Dec 17 06:27:56 2009 +0000
> @@ -931,6 +931,7 @@ int __init construct_dom0(
> page_list_for_each ( page, &d->page_list )
> {
> mfn = page_to_mfn(page);
> + BUG_ON(SHARED_M2P(get_gpfn_from_mfn(mfn)));
> if ( get_gpfn_from_mfn(mfn) >= count )
> {
> BUG_ON(is_pv_32bit_domain(d));
> diff -r 34d620a47c63 -r 257bd5e90294 xen/arch/x86/mm.c
> --- a/xen/arch/x86/mm.c Thu Dec 17 06:27:56 2009 +0000
> +++ b/xen/arch/x86/mm.c Thu Dec 17 06:27:56 2009 +0000
> @@ -2138,7 +2138,9 @@ int free_page_type(struct page_info *pag
>
> gmfn = mfn_to_gmfn(owner, page_to_mfn(page));
> ASSERT(VALID_M2P(gmfn));
> - shadow_remove_all_shadows(owner->vcpu[0], _mfn(gmfn));
> + /* Page sharing not supported for shadowed domains */
> + if(!SHARED_M2P(gmfn))
> + shadow_remove_all_shadows(owner->vcpu[0], _mfn(gmfn));
> }
>
> if ( !(type & PGT_partial) )
> @@ -4234,12 +4236,22 @@ long arch_memory_op(int op, XEN_GUEST_HA
> spin_unlock(&d->grant_table->lock);
> break;
> case XENMAPSPACE_gmfn:
> - xatp.idx = gmfn_to_mfn(d, xatp.idx);
> + {
> + p2m_type_t p2mt;
> +
> + xatp.idx = mfn_x(gfn_to_mfn_unshare(d, xatp.idx, &p2mt, 0));
> + /* If the page is still shared, exit early */
> + if ( p2m_is_shared(p2mt) )
> + {
> + rcu_unlock_domain(d);
> + return -ENOMEM;
> + }
> if ( !get_page_from_pagenr(xatp.idx, d) )
> break;
> mfn = xatp.idx;
> page = mfn_to_page(mfn);
> break;
> + }
> default:
> break;
> }
> @@ -4268,6 +4280,7 @@ long arch_memory_op(int op, XEN_GUEST_HA
>
> /* Unmap from old location, if any. */
> gpfn = get_gpfn_from_mfn(mfn);
> + ASSERT( gpfn != SHARED_M2P_ENTRY );
> if ( gpfn != INVALID_M2P_ENTRY )
> guest_physmap_remove_page(d, gpfn, mfn, 0);
>
> diff -r 34d620a47c63 -r 257bd5e90294 xen/arch/x86/mm/mem_sharing.c
> --- a/xen/arch/x86/mm/mem_sharing.c Thu Dec 17 06:27:56 2009 +0000
> +++ b/xen/arch/x86/mm/mem_sharing.c Thu Dec 17 06:27:56 2009 +0000
> @@ -216,6 +216,9 @@ int mem_sharing_nominate_page(struct dom
> goto out;
> }
>
> + /* Update m2p entry to SHARED_M2P_ENTRY */
> + set_gpfn_from_mfn(mfn_x(mfn), SHARED_M2P_ENTRY);
> +
> ret = 0;
>
> out:
> @@ -260,9 +263,11 @@ private_page_found:
> printk("Could not change p2m type.\n");
> BUG();
> }
> -
> - return 0;
> -}
> -
> -
> -
> + /* Update m2p entry */
> + set_gpfn_from_mfn(mfn_x(page_to_mfn(page)), gfn);
> +
> + return 0;
> +}
> +
> +
> +
> diff -r 34d620a47c63 -r 257bd5e90294 xen/arch/x86/mm/p2m.c
> --- a/xen/arch/x86/mm/p2m.c Thu Dec 17 06:27:56 2009 +0000
> +++ b/xen/arch/x86/mm/p2m.c Thu Dec 17 06:27:56 2009 +0000
> @@ -1601,6 +1601,8 @@ int p2m_alloc_table(struct domain *d,
> {
> mfn = page_to_mfn(page);
> gfn = get_gpfn_from_mfn(mfn_x(mfn));
> + /* Pages should not be shared that early */
> + ASSERT(gfn != SHARED_M2P_ENTRY);
> page_count++;
> if (
> #ifdef __x86_64__
> @@ -1709,6 +1711,13 @@ static void audit_p2m(struct domain *d)
> orphans_d++;
> //P2M_PRINTK("orphaned guest page: mfn=%#lx has debug gfn\n",
> // mfn);
> + continue;
> + }
> +
> + if ( gfn == SHARED_P2M_ENTRY)
> + {
> + P2M_PRINTK("shared mfn (%lx) on domain page list!\n",
> + mfn);
> continue;
> }
>
> @@ -1803,7 +1812,9 @@ static void audit_p2m(struct domain *d)
> for ( i1 = 0; i1 < L1_PAGETABLE_ENTRIES; i1++)
> {
> m2pfn = get_gpfn_from_mfn(mfn+i1);
> - if ( m2pfn != (gfn + i1) )
> + /* Allow shared M2Ps */
> + if ( (m2pfn != (gfn + i1)) &&
> + (m2pfn != SHARED_M2P_ENTRY) )
> {
> pmbad++;
> P2M_PRINTK("mismatch: gfn %#lx -> mfn %#lx"
> @@ -1834,7 +1845,8 @@ static void audit_p2m(struct domain *d)
> m2pfn = get_gpfn_from_mfn(mfn);
> if ( m2pfn != gfn &&
> type != p2m_mmio_direct &&
> - !p2m_is_grant(type) )
> + !p2m_is_grant(type) &&
> + !p2m_is_shared(type) )
> {
> pmbad++;
> printk("mismatch: gfn %#lx -> mfn %#lx"
> @@ -2137,12 +2149,11 @@ void p2m_change_type_global(struct domai
> l1_pgentry_t *l1e;
> l2_pgentry_t *l2e;
> mfn_t l1mfn, l2mfn;
> - int i1, i2;
> + unsigned long i1, i2, i3;
> l3_pgentry_t *l3e;
> - int i3;
> #if CONFIG_PAGING_LEVELS == 4
> l4_pgentry_t *l4e;
> - int i4;
> + unsigned long i4;
> #endif /* CONFIG_PAGING_LEVELS == 4 */
>
> BUG_ON(p2m_is_grant(ot) || p2m_is_grant(nt));
> @@ -2193,7 +2204,10 @@ void p2m_change_type_global(struct domai
> if ( p2m_flags_to_type(flags) != ot )
> continue;
> mfn = l2e_get_pfn(l2e[i2]);
> - gfn = get_gpfn_from_mfn(mfn);
> + /* Do not use get_gpfn_from_mfn because it may return
> + SHARED_M2P_ENTRY */
> + gfn = (i2 + (i3 + (i4 * L3_PAGETABLE_ENTRIES))
> + * L2_PAGETABLE_ENTRIES) * L1_PAGETABLE_ENTRIES;
> flags = p2m_type_to_flags(nt);
> l1e_content = l1e_from_pfn(mfn, flags | _PAGE_PSE);
> paging_write_p2m_entry(d, gfn, (l1_pgentry_t *)&l2e[i2],
> @@ -2210,7 +2224,8 @@ void p2m_change_type_global(struct domai
> if ( p2m_flags_to_type(flags) != ot )
> continue;
> mfn = l1e_get_pfn(l1e[i1]);
> - gfn = get_gpfn_from_mfn(mfn);
> + gfn = i1 + (i2 + (i3 + (i4 * L3_PAGETABLE_ENTRIES))
> + * L2_PAGETABLE_ENTRIES) * L1_PAGETABLE_ENTRIES;
> /* create a new 1le entry with the new type */
> flags = p2m_type_to_flags(nt);
> l1e_content = l1e_from_pfn(mfn, flags);
> diff -r 34d620a47c63 -r 257bd5e90294 xen/arch/x86/mm/paging.c
> --- a/xen/arch/x86/mm/paging.c Thu Dec 17 06:27:56 2009 +0000
> +++ b/xen/arch/x86/mm/paging.c Thu Dec 17 06:27:56 2009 +0000
> @@ -280,6 +280,8 @@ void paging_mark_dirty(struct domain *d,
>
> /* We /really/ mean PFN here, even for non-translated guests. */
> pfn = get_gpfn_from_mfn(mfn_x(gmfn));
> + /* Shared MFNs should NEVER be marked dirty */
> + BUG_ON(SHARED_M2P(pfn));
>
> /*
> * Values with the MSB set denote MFNs that aren't really part of the
> diff -r 34d620a47c63 -r 257bd5e90294 xen/arch/x86/mm/shadow/multi.c
> --- a/xen/arch/x86/mm/shadow/multi.c Thu Dec 17 06:27:56 2009 +0000
> +++ b/xen/arch/x86/mm/shadow/multi.c Thu Dec 17 06:27:56 2009 +0000
> @@ -1070,6 +1070,8 @@ static inline void shadow_vram_get_l1e(s
> return;
>
> gfn = mfn_to_gfn(d, mfn);
> + /* Page sharing not supported on shadow PTs */
> + BUG_ON(SHARED_M2P(gfn));
>
> if ( (gfn >= dirty_vram->begin_pfn) && (gfn < dirty_vram->end_pfn) )
> {
> @@ -1099,6 +1101,8 @@ static inline void shadow_vram_put_l1e(s
> return;
>
> gfn = mfn_to_gfn(d, mfn);
> + /* Page sharing not supported on shadow PTs */
> + BUG_ON(SHARED_M2P(gfn));
>
> if ( (gfn >= dirty_vram->begin_pfn) && (gfn < dirty_vram->end_pfn) )
> {
> diff -r 34d620a47c63 -r 257bd5e90294 xen/arch/x86/mm/shadow/private.h
> --- a/xen/arch/x86/mm/shadow/private.h Thu Dec 17 06:27:56 2009 +0000
> +++ b/xen/arch/x86/mm/shadow/private.h Thu Dec 17 06:27:56 2009 +0000
> @@ -565,6 +565,8 @@ sh_mfn_is_dirty(struct domain *d, mfn_t
>
> /* We /really/ mean PFN here, even for non-translated guests. */
> pfn = get_gpfn_from_mfn(mfn_x(gmfn));
> + /* Page sharing not supported for shadow domains */
> + BUG_ON(SHARED_M2P(pfn));
> if ( unlikely(!VALID_M2P(pfn)) )
> return 0;
>
> diff -r 34d620a47c63 -r 257bd5e90294 xen/arch/x86/traps.c
> --- a/xen/arch/x86/traps.c Thu Dec 17 06:27:56 2009 +0000
> +++ b/xen/arch/x86/traps.c Thu Dec 17 06:27:56 2009 +0000
> @@ -2088,15 +2088,27 @@ static int emulate_privileged_op(struct
> break;
>
> case 3: /* Read CR3 */
> + {
> + unsigned long mfn;
> +
> if ( !is_pv_32on64_vcpu(v) )
> + {
> + mfn = pagetable_get_pfn(v->arch.guest_table);
> *reg = xen_pfn_to_cr3(mfn_to_gmfn(
> - v->domain, pagetable_get_pfn(v->arch.guest_table)));
> + v->domain, mfn));
> + }
> #ifdef CONFIG_COMPAT
> else
> + {
> + mfn = l4e_get_pfn(*(l4_pgentry_t
> *)__va(pagetable_get_paddr(v->arch.guest_table)));
> *reg = compat_pfn_to_cr3(mfn_to_gmfn(
> - v->domain, l4e_get_pfn(*(l4_pgentry_t
> *)__va(pagetable_get_paddr(v->arch.guest_table)))));
> + v->domain, mfn));
> + }
> #endif
> - break;
> + /* PTs should not be shared */
> + BUG_ON(page_get_owner(mfn_to_page(mfn)) == dom_cow);
> + }
> + break;
>
> case 4: /* Read CR4 */
> *reg = v->arch.guest_context.ctrlreg[4];
> diff -r 34d620a47c63 -r 257bd5e90294 xen/common/domctl.c
> --- a/xen/common/domctl.c Thu Dec 17 06:27:56 2009 +0000
> +++ b/xen/common/domctl.c Thu Dec 17 06:27:56 2009 +0000
> @@ -137,6 +137,7 @@ void getdomaininfo(struct domain *d, str
> info->tot_pages = d->tot_pages;
> info->max_pages = d->max_pages;
> info->shared_info_frame = mfn_to_gmfn(d,
> __pa(d->shared_info)>>PAGE_SHIFT);
> + BUG_ON(SHARED_M2P(info->shared_info_frame));
>
> memcpy(info->handle, d->handle, sizeof(xen_domain_handle_t));
> }
> diff -r 34d620a47c63 -r 257bd5e90294 xen/common/grant_table.c
> --- a/xen/common/grant_table.c Thu Dec 17 06:27:56 2009 +0000
> +++ b/xen/common/grant_table.c Thu Dec 17 06:27:56 2009 +0000
> @@ -1195,6 +1195,8 @@ gnttab_setup_table(
> for ( i = 0; i < op.nr_frames; i++ )
> {
> gmfn = gnttab_shared_gmfn(d, d->grant_table, i);
> + /* Grant tables cannot be shared */
> + BUG_ON(SHARED_M2P(gmfn));
> (void)copy_to_guest_offset(op.frame_list, i, &gmfn, 1);
> }
>
> diff -r 34d620a47c63 -r 257bd5e90294 xen/common/memory.c
> --- a/xen/common/memory.c Thu Dec 17 06:27:56 2009 +0000
> +++ b/xen/common/memory.c Thu Dec 17 06:27:56 2009 +0000
> @@ -22,6 +22,7 @@
> #include <xen/tmem.h>
> #include <asm/current.h>
> #include <asm/hardirq.h>
> +#include <asm/p2m.h>
> #include <xen/numa.h>
> #include <public/memory.h>
> #include <xsm/xsm.h>
> @@ -151,9 +152,10 @@ int guest_remove_page(struct domain *d,
> int guest_remove_page(struct domain *d, unsigned long gmfn)
> {
> struct page_info *page;
> + p2m_type_t p2mt;
> unsigned long mfn;
>
> - mfn = gmfn_to_mfn(d, gmfn);
> + mfn = mfn_x(gfn_to_mfn(d, gmfn, &p2mt));
> if ( unlikely(!mfn_valid(mfn)) )
> {
> gdprintk(XENLOG_INFO, "Domain %u page number %lx invalid\n",
> @@ -162,6 +164,15 @@ int guest_remove_page(struct domain *d,
> }
>
> page = mfn_to_page(mfn);
> + /* If gmfn is shared, just drop the guest reference (which may or may not
> + * free the page) */
> + if(p2m_is_shared(p2mt))
> + {
> + put_page_and_type(page);
> + guest_physmap_remove_page(d, gmfn, mfn, 0);
> + return 1;
> + }
> +
> if ( unlikely(!get_page(page, d)) )
> {
> gdprintk(XENLOG_INFO, "Bad page free for domain %u\n", d->domain_id);
> @@ -319,7 +330,15 @@ static long memory_exchange(XEN_GUEST_HA
>
> for ( k = 0; k < (1UL << exch.in.extent_order); k++ )
> {
> - mfn = gmfn_to_mfn(d, gmfn + k);
> + p2m_type_t p2mt;
> +
> + /* Shared pages cannot be exchanged */
> + mfn = mfn_x(gfn_to_mfn_unshare(d, gmfn + k, &p2mt, 0));
> + if ( p2m_is_shared(p2mt) )
> + {
> + rc = -ENOMEM;
> + goto fail;
> + }
> if ( unlikely(!mfn_valid(mfn)) )
> {
> rc = -EINVAL;
> @@ -358,10 +377,15 @@ static long memory_exchange(XEN_GUEST_HA
> /* Destroy final reference to each input page. */
> while ( (page = page_list_remove_head(&in_chunk_list)) )
> {
> + unsigned long gfn;
> +
> if ( !test_and_clear_bit(_PGC_allocated, &page->count_info) )
> BUG();
> mfn = page_to_mfn(page);
> - guest_physmap_remove_page(d, mfn_to_gmfn(d, mfn), mfn, 0);
> + gfn = mfn_to_gmfn(d, mfn);
> + /* Pages were unshared above */
> + BUG_ON(SHARED_M2P(gfn));
> + guest_physmap_remove_page(d, gfn, mfn, 0);
> put_page(page);
> }
>
> diff -r 34d620a47c63 -r 257bd5e90294 xen/drivers/passthrough/iommu.c
> --- a/xen/drivers/passthrough/iommu.c Thu Dec 17 06:27:56 2009 +0000
> +++ b/xen/drivers/passthrough/iommu.c Thu Dec 17 06:27:56 2009 +0000
> @@ -168,6 +168,7 @@ static int iommu_populate_page_table(str
> if ( is_hvm_domain(d) ||
> (page->u.inuse.type_info & PGT_type_mask) == PGT_writable_page )
> {
> + BUG_ON(SHARED_M2P(mfn_to_gmfn(d, page_to_mfn(page))));
> rc = hd->platform_ops->map_page(
> d, mfn_to_gmfn(d, page_to_mfn(page)), page_to_mfn(page));
> if (rc)
> diff -r 34d620a47c63 -r 257bd5e90294 xen/include/asm-x86/mm.h
> --- a/xen/include/asm-x86/mm.h Thu Dec 17 06:27:56 2009 +0000
> +++ b/xen/include/asm-x86/mm.h Thu Dec 17 06:27:56 2009 +0000
> @@ -438,15 +438,27 @@ TYPE_SAFE(unsigned long,mfn);
> #define machine_to_phys_mapping ((unsigned long *)RDWR_MPT_VIRT_START)
> #define INVALID_M2P_ENTRY (~0UL)
> #define VALID_M2P(_e) (!((_e) & (1UL<<(BITS_PER_LONG-1))))
> +#define SHARED_M2P_ENTRY (~0UL - 1UL)
> +#define SHARED_M2P(_e) ((_e) == SHARED_M2P_ENTRY)
>
> #ifdef CONFIG_COMPAT
> #define compat_machine_to_phys_mapping ((unsigned int
> *)RDWR_COMPAT_MPT_VIRT_START)
> -#define set_gpfn_from_mfn(mfn, pfn) \
> +#define set_gpfn_from_mfn(mfn, pfn) ({ \
> + struct domain *d = page_get_owner(__mfn_to_page(mfn)); \
> + unsigned long entry = (d && (d == dom_cow)) ? \
> + SHARED_M2P_ENTRY : (pfn); \
> ((void)((mfn) >= (RDWR_COMPAT_MPT_VIRT_END - RDWR_COMPAT_MPT_VIRT_START)
> / 4 || \
> - (compat_machine_to_phys_mapping[(mfn)] = (unsigned int)(pfn))), \
> - machine_to_phys_mapping[(mfn)] = (pfn))
> -#else
> -#define set_gpfn_from_mfn(mfn, pfn) (machine_to_phys_mapping[(mfn)] = (pfn))
> + (compat_machine_to_phys_mapping[(mfn)] = (unsigned
> int)(entry))), \
> + machine_to_phys_mapping[(mfn)] = (entry)); \
> + })
> +#else
> +#define set_gpfn_from_mfn(mfn, pfn) ({ \
> + struct domain *d = page_get_owner(__mfn_to_page(mfn)); \
> + if(d && (d == dom_cow)) \
> + machine_to_phys_mapping[(mfn)] = SHARED_M2P_ENTRY; \
> + else \
> + machine_to_phys_mapping[(mfn)] = (pfn); \
> + })
> #endif
> #define get_gpfn_from_mfn(mfn) (machine_to_phys_mapping[(mfn)])
>
>
> _______________________________________________
> Xen-changelog mailing list
> Xen-changelog@xxxxxxxxxxxxxxxxxxx
> http://lists.xensource.com/xen-changelog
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|