summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpd <pd@cvs.openbsd.org>2020-02-17 18:16:11 +0000
committerpd <pd@cvs.openbsd.org>2020-02-17 18:16:11 +0000
commit89611257a976f11b1b262bc9e5255f5ecb849835 (patch)
treef01a48f973427c16ed8f1c9b081df91b8b00ae20
parentcda2c267be3339e4724a1127d3f881c3910f178d (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.c21
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);
}