|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86: don't wrongly trigger linear page table assertion
commit 2c458dfcb59f3d9d8a35fc5ffbf780b6ed7a26a6
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Nov 16 10:37:29 2017 +0100
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Nov 16 10:37:29 2017 +0100
x86: don't wrongly trigger linear page table assertion
_put_page_type() may do multiple iterations until its cmpxchg()
succeeds. It invokes set_tlbflush_timestamp() on the first
iteration, however. Code inside the function takes care of this, but
- the assertion in _put_final_page_type() would trigger on the second
iteration if time stamps in a debug build are permitted to be
sufficiently much wider than the default 6 bits (see WRAP_MASK in
flushtlb.c),
- it returning -EINTR (for a continuation to be scheduled) would leave
the page inconsistent state (until the re-invocation completes).
Make the set_tlbflush_timestamp() invocation conditional, bypassing it
(for now) only in the case we really can't tolerate the stamp to be
stored.
This is part of XSA-240.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Reviewed-by: George Dunlap <george.dunlap@xxxxxxxxxx>
---
xen/arch/x86/mm.c | 23 ++++++++---------------
1 file changed, 8 insertions(+), 15 deletions(-)
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 64ccd70..886a5ee 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -2477,26 +2477,19 @@ static int _put_page_type(struct page_info *page, bool
preemptible,
break;
}
-#ifdef CONFIG_PV_LINEAR_PT
- if ( ptpg && PGT_type_equal(x, ptpg->u.inuse.type_info) )
+ if ( !ptpg || !PGT_type_equal(x, ptpg->u.inuse.type_info) )
{
/*
* set_tlbflush_timestamp() accesses the same union
- * linear_pt_count lives in. Unvalidated page table pages,
- * however, should occur during domain destruction only
- * anyway. Updating of linear_pt_count luckily is not
- * necessary anymore for a dying domain.
+ * linear_pt_count lives in. Pages (including page table ones),
+ * however, don't need their flush time stamp set except when
+ * the last reference is being dropped. For page table pages
+ * this happens in _put_final_page_type().
*/
- ASSERT(page_get_owner(page)->is_dying);
- ASSERT(page->linear_pt_count < 0);
- ASSERT(ptpg->linear_pt_count > 0);
- ptpg = NULL;
+ set_tlbflush_timestamp(page);
}
-#else /* CONFIG_PV_LINEAR_PT */
- BUG_ON(ptpg && PGT_type_equal(x, ptpg->u.inuse.type_info));
-#endif
-
- set_tlbflush_timestamp(page);
+ else
+ BUG_ON(!IS_ENABLED(CONFIG_PV_LINEAR_PT));
}
else if ( unlikely((nx & (PGT_locked | PGT_count_mask)) ==
(PGT_locked | 1)) )
--
generated by git-patchbot for /home/xen/git/xen.git#master
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |