File 5b34882d-x86-mm-dont-bypass-preemption-checks.patch of Package xen.7985
# Commit 17608703c65bf080b0a9f024f9b370872b9f2c05
# Date 2018-06-28 09:03:09 +0200
# Author Jan Beulich <jbeulich@suse.com>
# Committer Jan Beulich <jbeulich@suse.com>
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@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -2526,7 +2526,7 @@ static int _put_page_type(struct page_in
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;
@@ -2558,12 +2558,13 @@ static int _put_page_type(struct page_in
*/
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;
}
@@ -2676,12 +2677,11 @@ static int __get_page_type(struct page_i
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. */