]> xenbits.xensource.com Git - people/julieng/linux-arm.git/commitdiff
x86/xen: export xen_alloc_p2m_entry()
authorDavid Vrabel <david.vrabel@citrix.com>
Wed, 22 Jul 2015 13:48:09 +0000 (14:48 +0100)
committerDavid Vrabel <david.vrabel@citrix.com>
Tue, 29 Sep 2015 16:00:04 +0000 (17:00 +0100)
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.

arch/x86/include/asm/xen/page.h
arch/x86/xen/p2m.c

index 0679e11d2cf7ddf4f7a72bee6db3f4368aff37d1..b922fa4bb4a1049bc9efa84aaf97b2e2ab391897 100644 (file)
@@ -43,6 +43,8 @@ extern unsigned long *xen_p2m_addr;
 extern unsigned long  xen_p2m_size;
 extern unsigned long  xen_max_p2m_pfn;
 
+extern int xen_alloc_p2m_entry(unsigned long pfn);
+
 extern unsigned long get_phys_to_machine(unsigned long pfn);
 extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
 extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
index bfc08b13044b181c5948e5a2f22c205e900e0b47..4ea676a49b6b05d3e0e73c8dc7fb2676c2a942a1 100644 (file)
@@ -519,7 +519,7 @@ static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *pte_pg)
  * the new pages are installed with cmpxchg; if we lose the race then
  * simply free the page we allocated and use the one that's there.
  */
-static bool alloc_p2m(unsigned long pfn)
+int xen_alloc_p2m_entry(unsigned long pfn)
 {
        unsigned topidx;
        unsigned long *top_mfn_p, *mid_mfn;
@@ -529,6 +529,9 @@ static bool alloc_p2m(unsigned long pfn)
        unsigned long addr = (unsigned long)(xen_p2m_addr + pfn);
        unsigned long p2m_pfn;
 
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return 0;
+
        ptep = lookup_address(addr, &level);
        BUG_ON(!ptep || level != PG_LEVEL_4K);
        pte_pg = (pte_t *)((unsigned long)ptep & ~(PAGE_SIZE - 1));
@@ -537,7 +540,7 @@ static bool alloc_p2m(unsigned long pfn)
                /* PMD level is missing, allocate a new one */
                ptep = alloc_p2m_pmd(addr, pte_pg);
                if (!ptep)
-                       return false;
+                       return -ENOMEM;
        }
 
        if (p2m_top_mfn && pfn < MAX_P2M_PFN) {
@@ -555,7 +558,7 @@ static bool alloc_p2m(unsigned long pfn)
 
                        mid_mfn = alloc_p2m_page();
                        if (!mid_mfn)
-                               return false;
+                               return -ENOMEM;
 
                        p2m_mid_mfn_init(mid_mfn, p2m_missing);
 
@@ -581,7 +584,7 @@ static bool alloc_p2m(unsigned long pfn)
 
                p2m = alloc_p2m_page();
                if (!p2m)
-                       return false;
+                       return -ENOMEM;
 
                if (p2m_pfn == PFN_DOWN(__pa(p2m_missing)))
                        p2m_init(p2m);
@@ -608,8 +611,9 @@ static bool alloc_p2m(unsigned long pfn)
                        free_p2m_page(p2m);
        }
 
-       return true;
+       return 0;
 }
+EXPORT_SYMBOL(xen_alloc_p2m_entry);
 
 unsigned long __init set_phys_range_identity(unsigned long pfn_s,
                                      unsigned long pfn_e)
@@ -671,7 +675,10 @@ bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn)
 bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
 {
        if (unlikely(!__set_phys_to_machine(pfn, mfn))) {
-               if (!alloc_p2m(pfn))
+               int ret;
+
+               ret = xen_alloc_p2m_entry(pfn);
+               if (ret < 0)
                        return false;
 
                return __set_phys_to_machine(pfn, mfn);