[Xen-devel,for-4.10] xen/x86: p2m-pod: Prevent infinite loop when shattering 1GB pages

Message ID 20171101145020.6881-1-julien.grall@linaro.org
State New
Headers show
Series
  • [Xen-devel,for-4.10] xen/x86: p2m-pod: Prevent infinite loop when shattering 1GB pages
Related show

Commit Message

Julien Grall Nov. 1, 2017, 2:50 p.m.
The PoD subsystem only have pool of 4KB and 2MB pages. When it comes
accross a 1GB mapping, it will be splitted in 2MB one using
p2m_set_entry and request the caller to retry (see ept_get_entry for
instance).

p2m_set_entry may fail to shatter if it is not possible to
allocate memory for the new page table. However, the error is not
progated resulting to the callers to retry infinitely the PoD.

Prevent the infinite loop by return false when it is not possible to
shatter the 1GB mapping.

Signed-off-by: Julien Grall <julien.grall@linaro.org>

---

    This is a potential candidate to backport and for Xen 4.10. Without
    it, there a potential for infinite loop if the memory is exhausted.
---
 xen/arch/x86/mm/p2m-pod.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

Patch

diff --git a/xen/arch/x86/mm/p2m-pod.c b/xen/arch/x86/mm/p2m-pod.c
index 0a811ccf28..69269a0bd1 100644
--- a/xen/arch/x86/mm/p2m-pod.c
+++ b/xen/arch/x86/mm/p2m-pod.c
@@ -1103,6 +1103,8 @@  p2m_pod_demand_populate(struct p2m_domain *p2m, gfn_t gfn,
      */
     if ( order == PAGE_ORDER_1G )
     {
+        int rc;
+
         pod_unlock(p2m);
         /*
          * Note that we are supposed to call p2m_set_entry() 512 times to
@@ -1113,9 +1115,9 @@  p2m_pod_demand_populate(struct p2m_domain *p2m, gfn_t gfn,
          * NOTE: In a fine-grained p2m locking scenario this operation
          * may need to promote its locking from gfn->1g superpage
          */
-        p2m_set_entry(p2m, gfn_aligned, INVALID_MFN, PAGE_ORDER_2M,
-                      p2m_populate_on_demand, p2m->default_access);
-        return true;
+        rc = p2m_set_entry(p2m, gfn_aligned, INVALID_MFN, PAGE_ORDER_2M,
+                           p2m_populate_on_demand, p2m->default_access);
+        return !rc;
     }
 
     /* Only reclaim if we're in actual need of more cache. */