diff options
author | pd <pd@cvs.openbsd.org> | 2020-02-17 18:16:11 +0000 |
---|---|---|
committer | pd <pd@cvs.openbsd.org> | 2020-02-17 18:16:11 +0000 |
commit | 89611257a976f11b1b262bc9e5255f5ecb849835 (patch) | |
tree | f01a48f973427c16ed8f1c9b081df91b8b00ae20 | |
parent | cda2c267be3339e4724a1127d3f881c3910f178d (diff) |
vmm: check guest cpl and xsave_mask in xsetbv handler
Reported by Maxime Villard.
ok kettenis@ brynet@
-rw-r--r-- | sys/arch/amd64/amd64/vmm.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/sys/arch/amd64/amd64/vmm.c b/sys/arch/amd64/amd64/vmm.c index 20fc41b77aa..386b8a07845 100644 --- a/sys/arch/amd64/amd64/vmm.c +++ b/sys/arch/amd64/amd64/vmm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm.c,v 1.261 2020/02/17 16:38:19 claudio Exp $ */ +/* $OpenBSD: vmm.c,v 1.262 2020/02/17 18:16:10 pd Exp $ */ /* * Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org> * @@ -6042,19 +6042,30 @@ svm_handle_xsetbv(struct vcpu *vcpu) int vmm_handle_xsetbv(struct vcpu *vcpu, uint64_t *rax) { - uint64_t *rdx, *rcx; + uint64_t *rdx, *rcx, val; rcx = &vcpu->vc_gueststate.vg_rcx; rdx = &vcpu->vc_gueststate.vg_rdx; + if (vmm_get_guest_cpu_cpl(vcpu) != 0) { + DPRINTF("%s: guest cpl not zero\n", __func__); + return (vmm_inject_gp(vcpu)); + } + if (*rcx != 0) { DPRINTF("%s: guest specified invalid xcr register number " "%lld\n", __func__, *rcx); - /* XXX this should #GP(0) instead of killing the guest */ - return (EINVAL); + return (vmm_inject_gp(vcpu)); + } + + val = *rax + (*rdx << 32); + if (val & ~xsave_mask) { + DPRINTF("%s: guest specified xcr0 outside xsave_mask %lld\n", + __func__, val); + return (vmm_inject_gp(vcpu)); } - vcpu->vc_gueststate.vg_xcr0 = *rax + (*rdx << 32); + vcpu->vc_gueststate.vg_xcr0 = val; return (0); } |