summaryrefslogtreecommitdiffstats
path: root/system/xen/xsa/xsa299-4.12-0003-x86-mm-Separate-out-partial_pte-tristate-into-indivi.patch
diff options
context:
space:
mode:
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.patch618
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
-