aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@citrix.com>2015-07-22 09:48:09 -0400
committerDavid Vrabel <david.vrabel@citrix.com>2015-10-23 09:20:28 -0400
commit8edfcf882eb91ec9028c7334f90f6ef3db5b0fcf (patch)
tree75ed19641906ab1774f4c4a180caaf6f703c1db5
parent1cf6a6c82918c9aad4bb73a7e7379a649e4d8e50 (diff)
x86/xen: export xen_alloc_p2m_entry()
Rename alloc_p2m() to xen_alloc_p2m_entry() and export it. This is useful for ensuring that a p2m entry is allocated (i.e., not a shared missing or identity entry) so that subsequent set_phys_to_machine() calls will require no further allocations. Signed-off-by: David Vrabel <david.vrabel@citrix.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> --- v3: - Make xen_alloc_p2m_entry() a nop on auto-xlate guests.
-rw-r--r--arch/x86/include/asm/xen/page.h2
-rw-r--r--arch/x86/xen/p2m.c19
2 files changed, 15 insertions, 6 deletions
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index 0679e11d2cf7..b922fa4bb4a1 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -43,6 +43,8 @@ extern unsigned long *xen_p2m_addr;
43extern unsigned long xen_p2m_size; 43extern unsigned long xen_p2m_size;
44extern unsigned long xen_max_p2m_pfn; 44extern unsigned long xen_max_p2m_pfn;
45 45
46extern int xen_alloc_p2m_entry(unsigned long pfn);
47
46extern unsigned long get_phys_to_machine(unsigned long pfn); 48extern unsigned long get_phys_to_machine(unsigned long pfn);
47extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); 49extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
48extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); 50extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 660b3cfef234..cab9f766bb06 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -530,7 +530,7 @@ static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *pte_pg)
530 * the new pages are installed with cmpxchg; if we lose the race then 530 * the new pages are installed with cmpxchg; if we lose the race then
531 * simply free the page we allocated and use the one that's there. 531 * simply free the page we allocated and use the one that's there.
532 */ 532 */
533static bool alloc_p2m(unsigned long pfn) 533int xen_alloc_p2m_entry(unsigned long pfn)
534{ 534{
535 unsigned topidx; 535 unsigned topidx;
536 unsigned long *top_mfn_p, *mid_mfn; 536 unsigned long *top_mfn_p, *mid_mfn;
@@ -540,6 +540,9 @@ static bool alloc_p2m(unsigned long pfn)
540 unsigned long addr = (unsigned long)(xen_p2m_addr + pfn); 540 unsigned long addr = (unsigned long)(xen_p2m_addr + pfn);
541 unsigned long p2m_pfn; 541 unsigned long p2m_pfn;
542 542
543 if (xen_feature(XENFEAT_auto_translated_physmap))
544 return 0;
545
543 ptep = lookup_address(addr, &level); 546 ptep = lookup_address(addr, &level);
544 BUG_ON(!ptep || level != PG_LEVEL_4K); 547 BUG_ON(!ptep || level != PG_LEVEL_4K);
545 pte_pg = (pte_t *)((unsigned long)ptep & ~(PAGE_SIZE - 1)); 548 pte_pg = (pte_t *)((unsigned long)ptep & ~(PAGE_SIZE - 1));
@@ -548,7 +551,7 @@ static bool alloc_p2m(unsigned long pfn)
548 /* PMD level is missing, allocate a new one */ 551 /* PMD level is missing, allocate a new one */
549 ptep = alloc_p2m_pmd(addr, pte_pg); 552 ptep = alloc_p2m_pmd(addr, pte_pg);
550 if (!ptep) 553 if (!ptep)
551 return false; 554 return -ENOMEM;
552 } 555 }
553 556
554 if (p2m_top_mfn && pfn < MAX_P2M_PFN) { 557 if (p2m_top_mfn && pfn < MAX_P2M_PFN) {
@@ -566,7 +569,7 @@ static bool alloc_p2m(unsigned long pfn)
566 569
567 mid_mfn = alloc_p2m_page(); 570 mid_mfn = alloc_p2m_page();
568 if (!mid_mfn) 571 if (!mid_mfn)
569 return false; 572 return -ENOMEM;
570 573
571 p2m_mid_mfn_init(mid_mfn, p2m_missing); 574 p2m_mid_mfn_init(mid_mfn, p2m_missing);
572 575
@@ -592,7 +595,7 @@ static bool alloc_p2m(unsigned long pfn)
592 595
593 p2m = alloc_p2m_page(); 596 p2m = alloc_p2m_page();
594 if (!p2m) 597 if (!p2m)
595 return false; 598 return -ENOMEM;
596 599
597 if (p2m_pfn == PFN_DOWN(__pa(p2m_missing))) 600 if (p2m_pfn == PFN_DOWN(__pa(p2m_missing)))
598 p2m_init(p2m); 601 p2m_init(p2m);
@@ -625,8 +628,9 @@ static bool alloc_p2m(unsigned long pfn)
625 HYPERVISOR_shared_info->arch.max_pfn = xen_p2m_last_pfn; 628 HYPERVISOR_shared_info->arch.max_pfn = xen_p2m_last_pfn;
626 } 629 }
627 630
628 return true; 631 return 0;
629} 632}
633EXPORT_SYMBOL(xen_alloc_p2m_entry);
630 634
631unsigned long __init set_phys_range_identity(unsigned long pfn_s, 635unsigned long __init set_phys_range_identity(unsigned long pfn_s,
632 unsigned long pfn_e) 636 unsigned long pfn_e)
@@ -688,7 +692,10 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
688bool set_phys_to_machine(unsigned long pfn, unsigned long mfn) 692bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
689{ 693{
690 if (unlikely(!__set_phys_to_machine(pfn, mfn))) { 694 if (unlikely(!__set_phys_to_machine(pfn, mfn))) {
691 if (!alloc_p2m(pfn)) 695 int ret;
696
697 ret = xen_alloc_p2m_entry(pfn);
698 if (ret < 0)
692 return false; 699 return false;
693 700
694 return __set_phys_to_machine(pfn, mfn); 701 return __set_phys_to_machine(pfn, mfn);