diff options
-rw-r--r-- | arch/x86/xen/p2m.c | 17 |
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 | ||