|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] x86/mm: don't bypass preemption checks
commit 17608703c65bf080b0a9f024f9b370872b9f2c05
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Jun 28 09:03:09 2018 +0200
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Jun 28 09:03:09 2018 +0200
x86/mm: don't bypass preemption checks
While unlikely, it is not impossible for a multi-vCPU guest to leverage
bypasses of preemption checks to drive Xen into an unbounded loop.
This is XSA-264.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
xen/arch/x86/mm.c | 33 ++++++++++++++++-----------------
1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 2b743921c3..bcf46c0743 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -2551,7 +2551,7 @@ static int _put_page_type(struct page_info *page, bool
preemptible,
nx = x & ~(PGT_validated|PGT_partial);
if ( unlikely((y = cmpxchg(&page->u.inuse.type_info,
x, nx)) != x) )
- continue;
+ break;
/* We cleared the 'valid bit' so we do the clean up. */
rc = _put_final_page_type(page, x, preemptible, ptpg);
if ( x & PGT_partial )
@@ -2574,7 +2574,18 @@ static int _put_page_type(struct page_info *page, bool
preemptible,
else
BUG_ON(!IS_ENABLED(CONFIG_PV_LINEAR_PT));
- break;
+ /* fall through */
+ default:
+ if ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x)
)
+ break;
+
+ if ( ptpg && PGT_type_equal(x, ptpg->u.inuse.type_info) )
+ {
+ dec_linear_uses(page);
+ dec_linear_entries(ptpg);
+ }
+
+ return 0;
case PGT_locked:
ASSERT_UNREACHABLE();
@@ -2587,23 +2598,12 @@ static int _put_page_type(struct page_info *page, bool
preemptible,
*/
cpu_relax();
y = page->u.inuse.type_info;
- continue;
- }
-
- if ( likely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) == x) )
break;
+ }
if ( preemptible && hypercall_preempt_check() )
return -EINTR;
}
-
- if ( ptpg && PGT_type_equal(x, ptpg->u.inuse.type_info) )
- {
- dec_linear_uses(page);
- dec_linear_entries(ptpg);
- }
-
- return 0;
}
@@ -2704,12 +2704,11 @@ static int _get_page_type(struct page_info *page,
unsigned long type,
if ( !(x & PGT_partial) )
{
/* Someone else is updating validation of this page. Wait... */
- while ( (y = page->u.inuse.type_info) == x )
- {
+ do {
if ( preemptible && hypercall_preempt_check() )
return -EINTR;
cpu_relax();
- }
+ } while ( (y = page->u.inuse.type_info) == x );
continue;
}
/* Type ref count was left at 1 when PGT_partial got set. */
--
generated by git-patchbot for /home/xen/git/xen.git#staging
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |