summaryrefslogtreecommitdiffstats
path: root/system/xen/xsa/xsa299-4.12-0008-x86-mm-Collapse-PTF_partial_set-and-PTF_partial_gene.patch
diff options
context:
space:
mode:
Diffstat (limited to 'system/xen/xsa/xsa299-4.12-0008-x86-mm-Collapse-PTF_partial_set-and-PTF_partial_gene.patch')
-rw-r--r--system/xen/xsa/xsa299-4.12-0008-x86-mm-Collapse-PTF_partial_set-and-PTF_partial_gene.patch227
1 files changed, 227 insertions, 0 deletions
diff --git a/system/xen/xsa/xsa299-4.12-0008-x86-mm-Collapse-PTF_partial_set-and-PTF_partial_gene.patch b/system/xen/xsa/xsa299-4.12-0008-x86-mm-Collapse-PTF_partial_set-and-PTF_partial_gene.patch
new file mode 100644
index 0000000000..6cf41d1cd6
--- /dev/null
+++ b/system/xen/xsa/xsa299-4.12-0008-x86-mm-Collapse-PTF_partial_set-and-PTF_partial_gene.patch
@@ -0,0 +1,227 @@
+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
+