aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/traps.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2013-05-02 16:35:50 +0200
committerJan Beulich <jbeulich@suse.com>2013-05-02 16:35:50 +0200
commite2e6b7b627fec0d7a769ab46441f2985ebccbf04 (patch)
tree6997d096f5b9dfa4a91c474d8801fc1eb76a44cd /xen/arch/x86/traps.c
parent6cdc9be2a5f2a87b4504404fbf648d16d9503c19 (diff)
downloadxen-e2e6b7b627fec0d7a769ab46441f2985ebccbf04.tar.gz
xen-e2e6b7b627fec0d7a769ab46441f2985ebccbf04.tar.bz2
xen-e2e6b7b627fec0d7a769ab46441f2985ebccbf04.zip
x86: make new_guest_cr3() preemptible
... as it may take significant amounts of time. This is part of CVE-2013-1918 / XSA-45. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Tim Deegan <tim@xen.org>
Diffstat (limited to 'xen/arch/x86/traps.c')
-rw-r--r--xen/arch/x86/traps.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index d36eddd229..4de9313c74 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -2322,12 +2322,23 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
gfn = !is_pv_32on64_vcpu(v)
? xen_cr3_to_pfn(*reg) : compat_cr3_to_pfn(*reg);
page = get_page_from_gfn(v->domain, gfn, NULL, P2M_ALLOC);
- rc = page ? new_guest_cr3(page_to_mfn(page)) : 0;
if ( page )
+ {
+ rc = new_guest_cr3(page_to_mfn(page));
put_page(page);
+ }
+ else
+ rc = -EINVAL;
domain_unlock(v->domain);
- if ( rc == 0 ) /* not okay */
+ switch ( rc )
+ {
+ case 0:
+ break;
+ case -EAGAIN: /* retry after preemption */
+ goto skip;
+ default: /* not okay */
goto fail;
+ }
break;
}