From c4dd2dc622b253fc78d8ba8550d86d4891b071dc Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 19 Jun 2018 15:11:44 +0100 Subject: [PATCH] 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 Reviewed-by: Andrew Cooper Gbp-Pq: Name x86mm-dont-bypass-preemption-checks.patch --- xen/arch/x86/mm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index c80f842599..f439fc4e74 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -2661,7 +2661,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; + goto maybe_preempt; /* We cleared the 'valid bit' so we do the clean up. */ rc = _put_final_page_type(page, x, preemptible, ptpg); ptpg = NULL; @@ -2697,12 +2697,13 @@ static int _put_page_type(struct page_info *page, bool preemptible, */ cpu_relax(); y = page->u.inuse.type_info; - continue; + goto maybe_preempt; } if ( likely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) == x) ) break; + maybe_preempt: if ( preemptible && hypercall_preempt_check() ) return -EINTR; } @@ -2806,12 +2807,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. */ -- 2.30.2