File xsa299-9.patch of Package xen.26348

From 4e0388af70146faaef6443a8b57807cd61e0960f 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 09/12] 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(-)

--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -757,13 +757,12 @@ static int __get_page_type(struct page_i
 
 /*
  * 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)
@@ -776,13 +775,10 @@ static int get_page_and_type_from_pagenr
     struct page_info *page = mfn_to_page(page_nr);
     int rc;
     bool_t 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_pagenr(page_nr, d)) )
         return -EINVAL;
 
@@ -792,14 +788,14 @@ static int get_page_and_type_from_pagenr
      * 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
@@ -822,7 +818,7 @@ static int get_page_and_type_from_pagenr
      * 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) )
@@ -1513,13 +1509,7 @@ static int put_page_from_l2e(l2_pgentry_
         struct page_info *pg = l2e_get_page(l2e);
         struct page_info *ptpg = mfn_to_page(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;
@@ -1559,13 +1549,6 @@ static int put_page_from_l3e(l3_pgentry_
 
     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(pfn);
@@ -1590,13 +1573,6 @@ static int put_page_from_l4e(l4_pgentry_
     {
         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(pfn);
@@ -1825,7 +1801,7 @@ static int alloc_l3_table(struct page_in
         {
             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 )
         {
@@ -1928,7 +1904,7 @@ static int alloc_l4_table(struct page_in
         {
             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 )
         {
@@ -2026,7 +2002,7 @@ static int free_l2_table(struct page_inf
     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 )
     {
@@ -2077,7 +2053,7 @@ static int free_l3_table(struct page_inf
     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 )
     {
@@ -2108,7 +2084,7 @@ static int free_l4_table(struct page_inf
     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 )
     {
--- a/xen/include/asm-x86/mm.h
+++ b/xen/include/asm-x86/mm.h
@@ -146,7 +146,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.
          *
@@ -155,23 +155,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 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 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_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
@@ -181,8 +178,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;
         };
 
openSUSE Build Service is sponsored by