[xen master] x86/mm: don't bypass preemption checks

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen master] x86/mm: don't bypass preemption checks

patchbot
commit 17608703c65bf080b0a9f024f9b370872b9f2c05
Author:     Jan Beulich <[hidden email]>
AuthorDate: Thu Jun 28 09:03:09 2018 +0200
Commit:     Jan Beulich <[hidden email]>
CommitDate: Thu Jun 28 09:03:09 2018 +0200

    x86/mm: don't bypass preemption checks
   
    While unlikely, it is not impossible for a multi-vCPU guest to leverage
    bypasses of preemption checks to drive Xen into an unbounded loop.
   
    This is XSA-264.
   
    Signed-off-by: Jan Beulich <[hidden email]>
    Reviewed-by: Andrew Cooper <[hidden email]>
---
 xen/arch/x86/mm.c | 33 ++++++++++++++++-----------------
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 2b743921c3..bcf46c0743 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -2551,7 +2551,7 @@ static int _put_page_type(struct page_info *page, bool preemptible,
                 nx = x & ~(PGT_validated|PGT_partial);
                 if ( unlikely((y = cmpxchg(&page->u.inuse.type_info,
                                            x, nx)) != x) )
-                    continue;
+                    break;
                 /* We cleared the 'valid bit' so we do the clean up. */
                 rc = _put_final_page_type(page, x, preemptible, ptpg);
                 if ( x & PGT_partial )
@@ -2574,7 +2574,18 @@ static int _put_page_type(struct page_info *page, bool preemptible,
             else
                 BUG_ON(!IS_ENABLED(CONFIG_PV_LINEAR_PT));
 
-            break;
+            /* fall through */
+        default:
+            if ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x) )
+                break;
+
+            if ( ptpg && PGT_type_equal(x, ptpg->u.inuse.type_info) )
+            {
+                dec_linear_uses(page);
+                dec_linear_entries(ptpg);
+            }
+
+            return 0;
 
         case PGT_locked:
             ASSERT_UNREACHABLE();
@@ -2587,23 +2598,12 @@ static int _put_page_type(struct page_info *page, bool preemptible,
              */
             cpu_relax();
             y = page->u.inuse.type_info;
-            continue;
-        }
-
-        if ( likely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) == x) )
             break;
+        }
 
         if ( preemptible && hypercall_preempt_check() )
             return -EINTR;
     }
-
-    if ( ptpg && PGT_type_equal(x, ptpg->u.inuse.type_info) )
-    {
-        dec_linear_uses(page);
-        dec_linear_entries(ptpg);
-    }
-
-    return 0;
 }
 
 
@@ -2704,12 +2704,11 @@ static int _get_page_type(struct page_info *page, unsigned long type,
             if ( !(x & PGT_partial) )
             {
                 /* Someone else is updating validation of this page. Wait... */
-                while ( (y = page->u.inuse.type_info) == x )
-                {
+                do {
                     if ( preemptible && hypercall_preempt_check() )
                         return -EINTR;
                     cpu_relax();
-                }
+                } while ( (y = page->u.inuse.type_info) == x );
                 continue;
             }
             /* Type ref count was left at 1 when PGT_partial got set. */
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
[hidden email]
https://lists.xenproject.org/xen-changelog