diff options
| author | David Vrabel <david.vrabel@citrix.com> | 2015-07-22 09:48:09 -0400 |
|---|---|---|
| committer | David Vrabel <david.vrabel@citrix.com> | 2015-10-23 09:20:28 -0400 |
| commit | 8edfcf882eb91ec9028c7334f90f6ef3db5b0fcf (patch) | |
| tree | 75ed19641906ab1774f4c4a180caaf6f703c1db5 | |
| parent | 1cf6a6c82918c9aad4bb73a7e7379a649e4d8e50 (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.h | 2 | ||||
| -rw-r--r-- | arch/x86/xen/p2m.c | 19 |
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; | |||
| 43 | extern unsigned long xen_p2m_size; | 43 | extern unsigned long xen_p2m_size; |
| 44 | extern unsigned long xen_max_p2m_pfn; | 44 | extern unsigned long xen_max_p2m_pfn; |
| 45 | 45 | ||
| 46 | extern int xen_alloc_p2m_entry(unsigned long pfn); | ||
| 47 | |||
| 46 | extern unsigned long get_phys_to_machine(unsigned long pfn); | 48 | extern unsigned long get_phys_to_machine(unsigned long pfn); |
| 47 | extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); | 49 | extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); |
| 48 | extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); | 50 | extern 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 | */ |
| 533 | static bool alloc_p2m(unsigned long pfn) | 533 | int 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 | } |
| 633 | EXPORT_SYMBOL(xen_alloc_p2m_entry); | ||
| 630 | 634 | ||
| 631 | unsigned long __init set_phys_range_identity(unsigned long pfn_s, | 635 | unsigned 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) | |||
| 688 | bool set_phys_to_machine(unsigned long pfn, unsigned long mfn) | 692 | bool 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); |
