aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/xen/p2m.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 8b7f18e200aa..b89983e9656f 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -263,6 +263,10 @@ void xen_setup_mfn_list_list(void)
263 HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = 263 HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
264 virt_to_mfn(p2m_top_mfn); 264 virt_to_mfn(p2m_top_mfn);
265 HYPERVISOR_shared_info->arch.max_pfn = xen_max_p2m_pfn; 265 HYPERVISOR_shared_info->arch.max_pfn = xen_max_p2m_pfn;
266 HYPERVISOR_shared_info->arch.p2m_generation = 0;
267 HYPERVISOR_shared_info->arch.p2m_vaddr = (unsigned long)xen_p2m_addr;
268 HYPERVISOR_shared_info->arch.p2m_cr3 =
269 xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir));
266} 270}
267 271
268/* Set up p2m_top to point to the domain-builder provided p2m pages */ 272/* Set up p2m_top to point to the domain-builder provided p2m pages */
@@ -478,8 +482,12 @@ static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *pte_pg)
478 482
479 ptechk = lookup_address(vaddr, &level); 483 ptechk = lookup_address(vaddr, &level);
480 if (ptechk == pte_pg) { 484 if (ptechk == pte_pg) {
485 HYPERVISOR_shared_info->arch.p2m_generation++;
486 wmb(); /* Tools are synchronizing via p2m_generation. */
481 set_pmd(pmdp, 487 set_pmd(pmdp,
482 __pmd(__pa(pte_newpg[i]) | _KERNPG_TABLE)); 488 __pmd(__pa(pte_newpg[i]) | _KERNPG_TABLE));
489 wmb(); /* Tools are synchronizing via p2m_generation. */
490 HYPERVISOR_shared_info->arch.p2m_generation++;
483 pte_newpg[i] = NULL; 491 pte_newpg[i] = NULL;
484 } 492 }
485 493
@@ -577,8 +585,12 @@ static bool alloc_p2m(unsigned long pfn)
577 spin_lock_irqsave(&p2m_update_lock, flags); 585 spin_lock_irqsave(&p2m_update_lock, flags);
578 586
579 if (pte_pfn(*ptep) == p2m_pfn) { 587 if (pte_pfn(*ptep) == p2m_pfn) {
588 HYPERVISOR_shared_info->arch.p2m_generation++;
589 wmb(); /* Tools are synchronizing via p2m_generation. */
580 set_pte(ptep, 590 set_pte(ptep,
581 pfn_pte(PFN_DOWN(__pa(p2m)), PAGE_KERNEL)); 591 pfn_pte(PFN_DOWN(__pa(p2m)), PAGE_KERNEL));
592 wmb(); /* Tools are synchronizing via p2m_generation. */
593 HYPERVISOR_shared_info->arch.p2m_generation++;
582 if (mid_mfn) 594 if (mid_mfn)
583 mid_mfn[mididx] = virt_to_mfn(p2m); 595 mid_mfn[mididx] = virt_to_mfn(p2m);
584 p2m = NULL; 596 p2m = NULL;
@@ -630,6 +642,11 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
630 return true; 642 return true;
631 } 643 }
632 644
645 /*
646 * The interface requires atomic updates on p2m elements.
647 * xen_safe_write_ulong() is using __put_user which does an atomic
648 * store via asm().
649 */
633 if (likely(!xen_safe_write_ulong(xen_p2m_addr + pfn, mfn))) 650 if (likely(!xen_safe_write_ulong(xen_p2m_addr + pfn, mfn)))
634 return true; 651 return true;
635 652