diff options
Diffstat (limited to 'system/xen/xsa/xsa299-4.12-0003-x86-mm-Separate-out-partial_pte-tristate-into-indivi.patch')
-rw-r--r-- | system/xen/xsa/xsa299-4.12-0003-x86-mm-Separate-out-partial_pte-tristate-into-indivi.patch | 618 |
1 files changed, 0 insertions, 618 deletions
diff --git a/system/xen/xsa/xsa299-4.12-0003-x86-mm-Separate-out-partial_pte-tristate-into-indivi.patch b/system/xen/xsa/xsa299-4.12-0003-x86-mm-Separate-out-partial_pte-tristate-into-indivi.patch deleted file mode 100644 index 226e5487b1..0000000000 --- a/system/xen/xsa/xsa299-4.12-0003-x86-mm-Separate-out-partial_pte-tristate-into-indivi.patch +++ /dev/null @@ -1,618 +0,0 @@ -From 0f9f61e5737fdd346550ec6e30161fa99e4653fa 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 03/11] x86/mm: Separate out partial_pte tristate into - individual flags - -At the moment, partial_pte is a tri-state that contains two distinct bits -of information: - -1. If zero, the pte at index [nr_validated_ptes] is un-validated. If - non-zero, the pte was last seen with PGT_partial set. - -2. If positive, the pte at index [nr_validated_ptes] does not hold a - general reference count. If negative, it does. - -To make future patches more clear, separate out this functionality -into two distinct, named bits: PTF_partial_set (for #1) and -PTF_partial_general_ref (for #2). - -Additionally, a number of functions which need this information also -take other flags to control behavior (such as `preemptible` and -`defer`). These are hard to read in the caller (since you only see -'true' or 'false'), and ugly when many are added together. In -preparation for adding yet another flag in a future patch, collapse -all of these into a single `flag` variable. - -NB that this does mean checking for what was previously the '-1' -condition a bit more ugly in the put_page_from_lNe functions (since -you have to check for both partial_set and general ref); but this -clause will go away in a future patch. - -Also note that the original comment had an off-by-one error: -partial_flags (like partial_pte before it) concerns -plNe[nr_validated_ptes], not plNe[nr_validated_ptes+1]. - -No functional change intended. - -This is part of XSA-299. - -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 | 165 ++++++++++++++++++++++++--------------- - xen/include/asm-x86/mm.h | 41 +++++++--- - 2 files changed, 128 insertions(+), 78 deletions(-) - -diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c -index a1b55c10ff..3f6f8cc9b8 100644 ---- a/xen/arch/x86/mm.c -+++ b/xen/arch/x86/mm.c -@@ -1094,20 +1094,35 @@ get_page_from_l1e( - } - - #ifdef CONFIG_PV -+ -+/* -+ * 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 -+ * 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) -+ - static int get_page_and_type_from_mfn( - mfn_t mfn, unsigned long type, struct domain *d, -- int partial, int preemptible) -+ unsigned int flags) - { - struct page_info *page = mfn_to_page(mfn); - int rc; -+ bool preemptible = flags & PTF_preemptible, -+ partial_ref = flags & PTF_partial_general_ref; - -- if ( likely(partial >= 0) && -+ if ( likely(!partial_ref) && - unlikely(!get_page_from_mfn(mfn, d)) ) - return -EINVAL; - - rc = _get_page_type(page, type, preemptible); - -- if ( unlikely(rc) && partial >= 0 && -+ if ( unlikely(rc) && !partial_ref && - (!preemptible || page != current->arch.old_guest_table) ) - put_page(page); - -@@ -1117,7 +1132,7 @@ static int get_page_and_type_from_mfn( - define_get_linear_pagetable(l2); - static int - get_page_from_l2e( -- l2_pgentry_t l2e, unsigned long pfn, struct domain *d, int partial) -+ l2_pgentry_t l2e, unsigned long pfn, struct domain *d, unsigned int flags) - { - unsigned long mfn = l2e_get_pfn(l2e); - int rc; -@@ -1129,8 +1144,9 @@ get_page_from_l2e( - return -EINVAL; - } - -- rc = get_page_and_type_from_mfn(_mfn(mfn), PGT_l1_page_table, d, -- partial, false); -+ ASSERT(!(flags & PTF_preemptible)); -+ -+ rc = get_page_and_type_from_mfn(_mfn(mfn), PGT_l1_page_table, d, flags); - if ( unlikely(rc == -EINVAL) && get_l2_linear_pagetable(l2e, pfn, d) ) - rc = 0; - -@@ -1140,7 +1156,7 @@ get_page_from_l2e( - define_get_linear_pagetable(l3); - static int - get_page_from_l3e( -- l3_pgentry_t l3e, unsigned long pfn, struct domain *d, int partial) -+ l3_pgentry_t l3e, unsigned long pfn, struct domain *d, unsigned int flags) - { - int rc; - -@@ -1152,7 +1168,7 @@ get_page_from_l3e( - } - - rc = get_page_and_type_from_mfn( -- l3e_get_mfn(l3e), PGT_l2_page_table, d, partial, 1); -+ l3e_get_mfn(l3e), PGT_l2_page_table, d, flags | PTF_preemptible); - if ( unlikely(rc == -EINVAL) && - !is_pv_32bit_domain(d) && - get_l3_linear_pagetable(l3e, pfn, d) ) -@@ -1164,7 +1180,7 @@ get_page_from_l3e( - define_get_linear_pagetable(l4); - static int - get_page_from_l4e( -- l4_pgentry_t l4e, unsigned long pfn, struct domain *d, int partial) -+ l4_pgentry_t l4e, unsigned long pfn, struct domain *d, unsigned int flags) - { - int rc; - -@@ -1176,7 +1192,7 @@ get_page_from_l4e( - } - - rc = get_page_and_type_from_mfn( -- l4e_get_mfn(l4e), PGT_l3_page_table, d, partial, 1); -+ l4e_get_mfn(l4e), PGT_l3_page_table, d, flags | PTF_preemptible); - if ( unlikely(rc == -EINVAL) && get_l4_linear_pagetable(l4e, pfn, d) ) - rc = 0; - -@@ -1277,7 +1293,7 @@ static void put_data_page(struct page_info *page, bool writeable) - * Note also that this automatically deals correctly with linear p.t.'s. - */ - static int put_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn, -- int partial, bool defer) -+ unsigned int flags) - { - int rc = 0; - -@@ -1300,12 +1316,13 @@ 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 ( unlikely(partial > 0) ) -+ if ( (flags & (PTF_partial_set | PTF_partial_general_ref)) == -+ PTF_partial_set ) - { -- ASSERT(!defer); -+ ASSERT(!(flags & PTF_defer)); - rc = _put_page_type(pg, true, ptpg); - } -- else if ( defer ) -+ else if ( flags & PTF_defer ) - { - current->arch.old_guest_ptpg = ptpg; - current->arch.old_guest_table = pg; -@@ -1322,7 +1339,7 @@ static int put_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn, - } - - static int put_page_from_l3e(l3_pgentry_t l3e, unsigned long pfn, -- int partial, bool defer) -+ unsigned int flags) - { - struct page_info *pg; - int rc; -@@ -1345,13 +1362,14 @@ static int put_page_from_l3e(l3_pgentry_t l3e, unsigned long pfn, - - pg = l3e_get_page(l3e); - -- if ( unlikely(partial > 0) ) -+ if ( (flags & (PTF_partial_set | PTF_partial_general_ref)) == -+ PTF_partial_set ) - { -- ASSERT(!defer); -+ ASSERT(!(flags & PTF_defer)); - return _put_page_type(pg, true, mfn_to_page(_mfn(pfn))); - } - -- if ( defer ) -+ if ( flags & PTF_defer ) - { - current->arch.old_guest_ptpg = mfn_to_page(_mfn(pfn)); - current->arch.old_guest_table = pg; -@@ -1366,7 +1384,7 @@ static int put_page_from_l3e(l3_pgentry_t l3e, unsigned long pfn, - } - - static int put_page_from_l4e(l4_pgentry_t l4e, unsigned long pfn, -- int partial, bool defer) -+ unsigned int flags) - { - int rc = 1; - -@@ -1375,13 +1393,14 @@ static int put_page_from_l4e(l4_pgentry_t l4e, unsigned long pfn, - { - struct page_info *pg = l4e_get_page(l4e); - -- if ( unlikely(partial > 0) ) -+ if ( (flags & (PTF_partial_set | PTF_partial_general_ref)) == -+ PTF_partial_set ) - { -- ASSERT(!defer); -+ ASSERT(!(flags & PTF_defer)); - return _put_page_type(pg, true, mfn_to_page(_mfn(pfn))); - } - -- if ( defer ) -+ if ( flags & PTF_defer ) - { - current->arch.old_guest_ptpg = mfn_to_page(_mfn(pfn)); - current->arch.old_guest_table = pg; -@@ -1492,12 +1511,13 @@ static int alloc_l2_table(struct page_info *page, unsigned long type) - unsigned long pfn = mfn_x(page_to_mfn(page)); - l2_pgentry_t *pl2e; - unsigned int i; -- int rc = 0, partial = page->partial_pte; -+ int rc = 0; -+ unsigned int partial_flags = page->partial_flags; - - pl2e = map_domain_page(_mfn(pfn)); - - for ( i = page->nr_validated_ptes; i < L2_PAGETABLE_ENTRIES; -- i++, partial = 0 ) -+ i++, partial_flags = 0 ) - { - l2_pgentry_t l2e; - -@@ -1520,17 +1540,18 @@ static int alloc_l2_table(struct page_info *page, unsigned long type) - rc = -EINTR; - } - else -- rc = get_page_from_l2e(l2e, pfn, d, partial); -+ rc = get_page_from_l2e(l2e, pfn, d, partial_flags); - - if ( rc == -ERESTART ) - { - page->nr_validated_ptes = i; -- page->partial_pte = partial ?: 1; -+ /* Set 'set', retain 'general ref' */ -+ page->partial_flags = partial_flags | PTF_partial_set; - } - else if ( rc == -EINTR && i ) - { - page->nr_validated_ptes = i; -- page->partial_pte = 0; -+ page->partial_flags = 0; - rc = -ERESTART; - } - else if ( rc < 0 && rc != -EINTR ) -@@ -1539,7 +1560,7 @@ static int alloc_l2_table(struct page_info *page, unsigned long type) - if ( i ) - { - page->nr_validated_ptes = i; -- page->partial_pte = 0; -+ page->partial_flags = 0; - current->arch.old_guest_ptpg = NULL; - current->arch.old_guest_table = page; - } -@@ -1563,7 +1584,8 @@ static int alloc_l3_table(struct page_info *page) - unsigned long pfn = mfn_x(page_to_mfn(page)); - l3_pgentry_t *pl3e; - unsigned int i; -- int rc = 0, partial = page->partial_pte; -+ int rc = 0; -+ unsigned int partial_flags = page->partial_flags; - - pl3e = map_domain_page(_mfn(pfn)); - -@@ -1578,7 +1600,7 @@ static int alloc_l3_table(struct page_info *page) - memset(pl3e + 4, 0, (L3_PAGETABLE_ENTRIES - 4) * sizeof(*pl3e)); - - for ( i = page->nr_validated_ptes; i < L3_PAGETABLE_ENTRIES; -- i++, partial = 0 ) -+ i++, partial_flags = 0 ) - { - l3_pgentry_t l3e = pl3e[i]; - -@@ -1597,7 +1619,8 @@ static int alloc_l3_table(struct page_info *page) - else - rc = get_page_and_type_from_mfn( - l3e_get_mfn(l3e), -- PGT_l2_page_table | PGT_pae_xen_l2, d, partial, 1); -+ PGT_l2_page_table | PGT_pae_xen_l2, d, -+ partial_flags | PTF_preemptible); - } - else if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) ) - { -@@ -1606,17 +1629,18 @@ static int alloc_l3_table(struct page_info *page) - rc = -EINTR; - } - else -- rc = get_page_from_l3e(l3e, pfn, d, partial); -+ rc = get_page_from_l3e(l3e, pfn, d, partial_flags); - - if ( rc == -ERESTART ) - { - page->nr_validated_ptes = i; -- page->partial_pte = partial ?: 1; -+ /* Set 'set', leave 'general ref' set if this entry was set */ -+ page->partial_flags = partial_flags | PTF_partial_set; - } - else if ( rc == -EINTR && i ) - { - page->nr_validated_ptes = i; -- page->partial_pte = 0; -+ page->partial_flags = 0; - rc = -ERESTART; - } - if ( rc < 0 ) -@@ -1633,7 +1657,7 @@ static int alloc_l3_table(struct page_info *page) - if ( i ) - { - page->nr_validated_ptes = i; -- page->partial_pte = 0; -+ page->partial_flags = 0; - current->arch.old_guest_ptpg = NULL; - current->arch.old_guest_table = page; - } -@@ -1767,10 +1791,11 @@ static int alloc_l4_table(struct page_info *page) - unsigned long pfn = mfn_x(page_to_mfn(page)); - l4_pgentry_t *pl4e = map_domain_page(_mfn(pfn)); - unsigned int i; -- int rc = 0, partial = page->partial_pte; -+ int rc = 0; -+ unsigned int partial_flags = page->partial_flags; - - for ( i = page->nr_validated_ptes; i < L4_PAGETABLE_ENTRIES; -- i++, partial = 0 ) -+ i++, partial_flags = 0 ) - { - l4_pgentry_t l4e; - -@@ -1786,12 +1811,13 @@ static int alloc_l4_table(struct page_info *page) - rc = -EINTR; - } - else -- rc = get_page_from_l4e(l4e, pfn, d, partial); -+ rc = get_page_from_l4e(l4e, pfn, d, partial_flags); - - if ( rc == -ERESTART ) - { - page->nr_validated_ptes = i; -- page->partial_pte = partial ?: 1; -+ /* Set 'set', leave 'general ref' set if this entry was set */ -+ page->partial_flags = partial_flags | PTF_partial_set; - } - else if ( rc < 0 ) - { -@@ -1801,7 +1827,7 @@ static int alloc_l4_table(struct page_info *page) - if ( i ) - { - page->nr_validated_ptes = i; -- page->partial_pte = 0; -+ page->partial_flags = 0; - if ( rc == -EINTR ) - rc = -ERESTART; - else -@@ -1853,19 +1879,20 @@ static int free_l2_table(struct page_info *page) - struct domain *d = page_get_owner(page); - unsigned long pfn = mfn_x(page_to_mfn(page)); - l2_pgentry_t *pl2e; -- int rc = 0, partial = page->partial_pte; -- unsigned int i = page->nr_validated_ptes - !partial; -+ int rc = 0; -+ unsigned int partial_flags = page->partial_flags, -+ i = page->nr_validated_ptes - !(partial_flags & PTF_partial_set); - - pl2e = map_domain_page(_mfn(pfn)); - - for ( ; ; ) - { - if ( is_guest_l2_slot(d, page->u.inuse.type_info, i) ) -- rc = put_page_from_l2e(pl2e[i], pfn, partial, false); -+ rc = put_page_from_l2e(pl2e[i], pfn, partial_flags); - if ( rc < 0 ) - break; - -- partial = 0; -+ partial_flags = 0; - - if ( !i-- ) - break; -@@ -1887,12 +1914,14 @@ static int free_l2_table(struct page_info *page) - else if ( rc == -ERESTART ) - { - page->nr_validated_ptes = i; -- page->partial_pte = partial ?: -1; -+ page->partial_flags = (partial_flags & PTF_partial_set) ? -+ partial_flags : -+ (PTF_partial_set | PTF_partial_general_ref); - } - else if ( rc == -EINTR && i < L2_PAGETABLE_ENTRIES - 1 ) - { - page->nr_validated_ptes = i + 1; -- page->partial_pte = 0; -+ page->partial_flags = 0; - rc = -ERESTART; - } - -@@ -1904,18 +1933,19 @@ static int free_l3_table(struct page_info *page) - struct domain *d = page_get_owner(page); - unsigned long pfn = mfn_x(page_to_mfn(page)); - l3_pgentry_t *pl3e; -- int rc = 0, partial = page->partial_pte; -- unsigned int i = page->nr_validated_ptes - !partial; -+ int rc = 0; -+ unsigned int partial_flags = page->partial_flags, -+ i = page->nr_validated_ptes - !(partial_flags & PTF_partial_set); - - pl3e = map_domain_page(_mfn(pfn)); - - for ( ; ; ) - { -- rc = put_page_from_l3e(pl3e[i], pfn, partial, 0); -+ rc = put_page_from_l3e(pl3e[i], pfn, partial_flags); - if ( rc < 0 ) - break; - -- partial = 0; -+ partial_flags = 0; - if ( rc == 0 ) - pl3e[i] = unadjust_guest_l3e(pl3e[i], d); - -@@ -1934,12 +1964,14 @@ static int free_l3_table(struct page_info *page) - if ( rc == -ERESTART ) - { - page->nr_validated_ptes = i; -- page->partial_pte = partial ?: -1; -+ page->partial_flags = (partial_flags & PTF_partial_set) ? -+ partial_flags : -+ (PTF_partial_set | PTF_partial_general_ref); - } - else if ( rc == -EINTR && i < L3_PAGETABLE_ENTRIES - 1 ) - { - page->nr_validated_ptes = i + 1; -- page->partial_pte = 0; -+ page->partial_flags = 0; - rc = -ERESTART; - } - return rc > 0 ? 0 : rc; -@@ -1950,26 +1982,29 @@ static int free_l4_table(struct page_info *page) - struct domain *d = page_get_owner(page); - unsigned long pfn = mfn_x(page_to_mfn(page)); - l4_pgentry_t *pl4e = map_domain_page(_mfn(pfn)); -- int rc = 0, partial = page->partial_pte; -- unsigned int i = page->nr_validated_ptes - !partial; -+ int rc = 0; -+ unsigned partial_flags = page->partial_flags, -+ i = page->nr_validated_ptes - !(partial_flags & PTF_partial_set); - - do { - if ( is_guest_l4_slot(d, i) ) -- rc = put_page_from_l4e(pl4e[i], pfn, partial, 0); -+ rc = put_page_from_l4e(pl4e[i], pfn, partial_flags); - if ( rc < 0 ) - break; -- partial = 0; -+ partial_flags = 0; - } while ( i-- ); - - if ( rc == -ERESTART ) - { - page->nr_validated_ptes = i; -- page->partial_pte = partial ?: -1; -+ page->partial_flags = (partial_flags & PTF_partial_set) ? -+ partial_flags : -+ (PTF_partial_set | PTF_partial_general_ref); - } - else if ( rc == -EINTR && i < L4_PAGETABLE_ENTRIES - 1 ) - { - page->nr_validated_ptes = i + 1; -- page->partial_pte = 0; -+ page->partial_flags = 0; - rc = -ERESTART; - } - -@@ -2247,7 +2282,7 @@ static int mod_l2_entry(l2_pgentry_t *pl2e, - return -EBUSY; - } - -- put_page_from_l2e(ol2e, pfn, 0, true); -+ put_page_from_l2e(ol2e, pfn, PTF_defer); - - return rc; - } -@@ -2315,7 +2350,7 @@ static int mod_l3_entry(l3_pgentry_t *pl3e, - if ( !create_pae_xen_mappings(d, pl3e) ) - BUG(); - -- put_page_from_l3e(ol3e, pfn, 0, 1); -+ put_page_from_l3e(ol3e, pfn, PTF_defer); - return rc; - } - -@@ -2378,7 +2413,7 @@ static int mod_l4_entry(l4_pgentry_t *pl4e, - return -EFAULT; - } - -- put_page_from_l4e(ol4e, pfn, 0, 1); -+ put_page_from_l4e(ol4e, pfn, PTF_defer); - return rc; - } - #endif /* CONFIG_PV */ -@@ -2649,7 +2684,7 @@ int free_page_type(struct page_info *page, unsigned long type, - if ( !(type & PGT_partial) ) - { - page->nr_validated_ptes = 1U << PAGETABLE_ORDER; -- page->partial_pte = 0; -+ page->partial_flags = 0; - } - - switch ( type & PGT_type_mask ) -@@ -2946,7 +2981,7 @@ static int _get_page_type(struct page_info *page, unsigned long type, - if ( !(x & PGT_partial) ) - { - page->nr_validated_ptes = 0; -- page->partial_pte = 0; -+ page->partial_flags = 0; - } - page->linear_pt_count = 0; - rc = alloc_page_type(page, type, preemptible); -@@ -3122,7 +3157,7 @@ int new_guest_cr3(mfn_t mfn) - return 0; - } - -- rc = get_page_and_type_from_mfn(mfn, PGT_root_page_table, d, 0, 1); -+ rc = get_page_and_type_from_mfn(mfn, PGT_root_page_table, d, PTF_preemptible); - switch ( rc ) - { - case 0: -@@ -3473,7 +3508,7 @@ long do_mmuext_op( - if ( op.arg1.mfn != 0 ) - { - rc = get_page_and_type_from_mfn( -- _mfn(op.arg1.mfn), PGT_root_page_table, currd, 0, 1); -+ _mfn(op.arg1.mfn), PGT_root_page_table, currd, PTF_preemptible); - - if ( unlikely(rc) ) - { -diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h -index 6faa563167..8406ac3c37 100644 ---- a/xen/include/asm-x86/mm.h -+++ b/xen/include/asm-x86/mm.h -@@ -228,19 +228,34 @@ struct page_info - * setting the flag must not drop that reference, whereas the instance - * clearing it will have to. - * -- * If @partial_pte is positive then PTE at @nr_validated_ptes+1 has -- * been partially validated. This implies that the general reference -- * to the page (acquired from get_page_from_lNe()) would be dropped -- * (again due to the apparent failure) and hence must be re-acquired -- * when resuming the validation, but must not be dropped when picking -- * up the page for invalidation. -+ * If partial_flags & PTF_partial_set is set, then the page at -+ * at @nr_validated_ptes had PGT_partial set as a result of an -+ * operation on the current page. (That page may or may not -+ * still have PGT_partial set.) - * -- * If @partial_pte is negative then PTE at @nr_validated_ptes+1 has -- * been partially invalidated. This is basically the opposite case of -- * above, i.e. the general reference to the page was not dropped in -- * put_page_from_lNe() (due to the apparent failure), and hence it -- * must be dropped when the put operation is resumed (and completes), -- * but it must not be acquired if picking up the page for validation. -+ * If PTF_partial_general_ref is set, then the PTE at -+ * @nr_validated_ptef holds a general reference count for the -+ * page. -+ * -+ * This happens: -+ * - During de-validation, if de-validation of the page was -+ * 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 we're picking -+ * up from a partial de-validation). -+ * -+ * 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. -+ * -+ * NB that PTF_partial_set and PTF_partial_general_ref are -+ * defined in mm.c, the only place where they are used. - * - * The 3rd field, @linear_pt_count, indicates - * - by a positive value, how many same-level page table entries a page -@@ -251,7 +266,7 @@ struct page_info - struct { - u16 nr_validated_ptes:PAGETABLE_ORDER + 1; - u16 :16 - PAGETABLE_ORDER - 1 - 2; -- s16 partial_pte:2; -+ u16 partial_flags:2; - s16 linear_pt_count; - }; - --- -2.23.0 - |