aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/p2m.c
diff options
context:
space:
mode:
authorJuergen Gross <jgross@suse.com>2015-07-17 00:51:23 -0400
committerDavid Vrabel <david.vrabel@citrix.com>2015-08-20 07:24:17 -0400
commit4b9c9a11803eaa73b3223da9fcaea39b2f919d80 (patch)
tree3973c139bfba58b46d36d86c1ce272e58f2c3bf0 /arch/x86/xen/p2m.c
parent17fb46b1190b677a37cdd636e2aa30052109f51b (diff)
xen: save linear p2m list address in shared info structure
The virtual address of the linear p2m list should be stored in the shared info structure read by the Xen tools to be able to support 64 bit pv-domains larger than 512 GB. Additionally the linear p2m list interface includes a generation count which is changed prior to and after each mapping change of the p2m list. Reading the generation count the Xen tools can detect changes of the mappings and re-read the p2m list eventually. Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: David Vrabel <david.vrabel@citrix.com> Acked-by: Konrad Rzeszutek Wilk <Konrad.wilk@oracle.com> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Diffstat (limited to 'arch/x86/xen/p2m.c')
-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