summaryrefslogtreecommitdiffstats
path: root/system/xen/xsa/xsa299-4.12-0008-x86-mm-Collapse-PTF_partial_set-and-PTF_partial_gene.patch
blob: 6cf41d1cd6941ed79c215481823631dd7d07b428 (plain)
From 8a8d836f7f7418e659d37817a66cd7a6b115042b Mon Sep 17 00:00:00 2001
From: George Dunlap <george.dunlap@citrix.com>
Date: Thu, 10 Oct 2019 17:57:49 +0100
Subject: [PATCH 08/11] x86/mm: Collapse PTF_partial_set and
 PTF_partial_general_ref into one

...now that they are equivalent.  No functional change intended.

Reported-by: George Dunlap <george.dunlap@citrix.com>
Signed-off-by: George Dunlap <george.dunlap@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/mm.c        | 50 +++++++++++-----------------------------
 xen/include/asm-x86/mm.h | 29 +++++++++++------------
 2 files changed, 26 insertions(+), 53 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 4d3ebf341d..886e93b8aa 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -1097,13 +1097,12 @@ get_page_from_l1e(
 
 /*
  * The following flags are used to specify behavior of various get and
- * put commands.  The first two are also stored in page->partial_flags
- * to indicate the state of the page pointed to by
+ * put commands.  The first is also stored in page->partial_flags to
+ * indicate the state of the page pointed to by
  * page->pte[page->nr_validated_entries].  See the comment in mm.h for
  * more information.
  */
 #define PTF_partial_set           (1 << 0)
-#define PTF_partial_general_ref   (1 << 1)
 #define PTF_preemptible           (1 << 2)
 #define PTF_defer                 (1 << 3)
 #define PTF_retain_ref_on_restart (1 << 4)
@@ -1115,13 +1114,10 @@ static int get_page_and_type_from_mfn(
     struct page_info *page = mfn_to_page(mfn);
     int rc;
     bool preemptible = flags & PTF_preemptible,
-         partial_ref = flags & PTF_partial_general_ref,
          partial_set = flags & PTF_partial_set,
          retain_ref  = flags & PTF_retain_ref_on_restart;
 
-    ASSERT(partial_ref == partial_set);
-
-    if ( likely(!partial_ref) &&
+    if ( likely(!partial_set) &&
          unlikely(!get_page_from_mfn(mfn, d)) )
         return -EINVAL;
 
@@ -1131,14 +1127,14 @@ static int get_page_and_type_from_mfn(
      * Retain the refcount if:
      * - page is fully validated (rc == 0)
      * - page is not validated (rc < 0) but:
-     *   - We came in with a reference (partial_ref)
+     *   - We came in with a reference (partial_set)
      *   - page is partially validated (rc == -ERESTART), and the
      *     caller has asked the ref to be retained in that case
      *   - page is partially validated but there's been an error
      *     (page == current->arch.old_guest_table)
      *
-     * The partial_ref-on-error clause is worth an explanation.  There
-     * are two scenarios where partial_ref might be true coming in:
+     * The partial_set-on-error clause is worth an explanation.  There
+     * are two scenarios where partial_set might be true coming in:
      * - mfn has been partially promoted / demoted as type `type`;
      *   i.e. has PGT_partial set
      * - mfn has been partially demoted as L(type+1) (i.e., a linear
@@ -1161,7 +1157,7 @@ static int get_page_and_type_from_mfn(
      * count retained unless we succeeded, or the operation was
      * preemptible.
      */
-    if ( likely(!rc) || partial_ref )
+    if ( likely(!rc) || partial_set )
         /* nothing */;
     else if ( page == current->arch.old_guest_table ||
               (retain_ref && rc == -ERESTART) )
@@ -1359,13 +1355,7 @@ static int put_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn,
         struct page_info *pg = l2e_get_page(l2e);
         struct page_info *ptpg = mfn_to_page(_mfn(pfn));
 
-        if ( (flags & (PTF_partial_set | PTF_partial_general_ref)) ==
-              PTF_partial_set )
-        {
-            /* partial_set should always imply partial_ref */
-            BUG();
-        }
-        else if ( flags & PTF_defer )
+        if ( flags & PTF_defer )
         {
             current->arch.old_guest_ptpg = ptpg;
             current->arch.old_guest_table = pg;
@@ -1405,13 +1395,6 @@ static int put_page_from_l3e(l3_pgentry_t l3e, unsigned long pfn,
 
     pg = l3e_get_page(l3e);
 
-    if ( (flags & (PTF_partial_set | PTF_partial_general_ref)) ==
-         PTF_partial_set )
-    {
-        /* partial_set should always imply partial_ref */
-        BUG();
-    }
-
     if ( flags & PTF_defer )
     {
         current->arch.old_guest_ptpg = mfn_to_page(_mfn(pfn));
@@ -1436,13 +1419,6 @@ static int put_page_from_l4e(l4_pgentry_t l4e, unsigned long pfn,
     {
         struct page_info *pg = l4e_get_page(l4e);
 
-        if ( (flags & (PTF_partial_set | PTF_partial_general_ref)) ==
-              PTF_partial_set )
-        {
-            /* partial_set should always imply partial_ref */
-            BUG();
-        }
-
         if ( flags & PTF_defer )
         {
             current->arch.old_guest_ptpg = mfn_to_page(_mfn(pfn));
@@ -1676,7 +1652,7 @@ static int alloc_l3_table(struct page_info *page)
         {
             page->nr_validated_ptes = i;
             /* Set 'set', leave 'general ref' set if this entry was set */
-            page->partial_flags = PTF_partial_set | PTF_partial_general_ref;
+            page->partial_flags = PTF_partial_set;
         }
         else if ( rc == -EINTR && i )
         {
@@ -1859,7 +1835,7 @@ static int alloc_l4_table(struct page_info *page)
         {
             page->nr_validated_ptes = i;
             /* Set 'set', leave 'general ref' set if this entry was set */
-            page->partial_flags = PTF_partial_set | PTF_partial_general_ref;
+            page->partial_flags = PTF_partial_set;
         }
         else if ( rc < 0 )
         {
@@ -1956,7 +1932,7 @@ static int free_l2_table(struct page_info *page)
     else if ( rc == -ERESTART )
     {
         page->nr_validated_ptes = i;
-        page->partial_flags = PTF_partial_set | PTF_partial_general_ref;
+        page->partial_flags = PTF_partial_set;
     }
     else if ( rc == -EINTR && i < L2_PAGETABLE_ENTRIES - 1 )
     {
@@ -2004,7 +1980,7 @@ static int free_l3_table(struct page_info *page)
     if ( rc == -ERESTART )
     {
         page->nr_validated_ptes = i;
-        page->partial_flags = PTF_partial_set | PTF_partial_general_ref;
+        page->partial_flags = PTF_partial_set;
     }
     else if ( rc == -EINTR && i < L3_PAGETABLE_ENTRIES - 1 )
     {
@@ -2035,7 +2011,7 @@ static int free_l4_table(struct page_info *page)
     if ( rc == -ERESTART )
     {
         page->nr_validated_ptes = i;
-        page->partial_flags = PTF_partial_set | PTF_partial_general_ref;
+        page->partial_flags = PTF_partial_set;
     }
     else if ( rc == -EINTR && i < L4_PAGETABLE_ENTRIES - 1 )
     {
diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h
index 02079e1324..f0fd35bf6b 100644
--- a/xen/include/asm-x86/mm.h
+++ b/xen/include/asm-x86/mm.h
@@ -233,7 +233,7 @@ struct page_info
          * operation on the current page.  (That page may or may not
          * still have PGT_partial set.)
          *
-         * If PTF_partial_general_ref is set, then the PTE at
+         * Additionally, if PTF_partial_set is set, then the PTE at
          * @nr_validated_ptef holds a general reference count for the
          * page.
          *
@@ -242,23 +242,20 @@ struct page_info
          *   interrupted
          * - During validation, if an invalid entry is encountered and
          *   validation is preemptible
-         * - During validation, if PTF_partial_general_ref was set on
-         *   this entry to begin with (perhaps because it picked up a
+         * - During validation, if PTF_partial_set was set on this
+         *   entry to begin with (perhaps because it picked up a
          *   previous operation)
          *
-         * When resuming validation, if PTF_partial_general_ref is
-         * clear, then a general reference must be re-acquired; if it
-         * is set, no reference should be acquired.
+         * When resuming validation, if PTF_partial_set is clear, then
+         * a general reference must be re-acquired; if it is set, no
+         * reference should be acquired.
          *
-         * When resuming de-validation, if PTF_partial_general_ref is
-         * clear, no reference should be dropped; if it is set, a
-         * reference should be dropped.
+         * When resuming de-validation, if PTF_partial_set is clear,
+         * no reference should be dropped; if it is set, a reference
+         * should be dropped.
          *
-         * NB at the moment, PTF_partial_set should be set if and only if
-         * PTF_partial_general_ref is set.
-         *
-         * NB that PTF_partial_set and PTF_partial_general_ref are
-         * defined in mm.c, the only place where they are used.
+         * NB that PTF_partial_set is defined in mm.c, the only place
+         * where it is used.
          *
          * The 3rd field, @linear_pt_count, indicates
          * - by a positive value, how many same-level page table entries a page
@@ -268,8 +265,8 @@ struct page_info
          */
         struct {
             u16 nr_validated_ptes:PAGETABLE_ORDER + 1;
-            u16 :16 - PAGETABLE_ORDER - 1 - 2;
-            u16 partial_flags:2;
+            u16 :16 - PAGETABLE_ORDER - 1 - 1;
+            u16 partial_flags:1;
             s16 linear_pt_count;
         };
 
-- 
2.23.0