diff options
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.patch | 227 |
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 + |