Module Name: src
Committed By: maxv
Date: Wed Apr 3 19:10:58 UTC 2019
Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86.c nvmm_x86.h nvmm_x86_vmx.c
Log Message:
VMX: if PAT is not valid, #GP on WRMSR, rather than crashing the guest.
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/nvmm/x86/nvmm_x86.c
cvs rdiff -u -r1.9 -r1.10 src/sys/dev/nvmm/x86/nvmm_x86.h
cvs rdiff -u -r1.22 -r1.23 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/nvmm/x86/nvmm_x86.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86.c:1.4 src/sys/dev/nvmm/x86/nvmm_x86.c:1.5
--- src/sys/dev/nvmm/x86/nvmm_x86.c:1.4 Wed Apr 3 17:32:58 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86.c Wed Apr 3 19:10:58 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm_x86.c,v 1.4 2019/04/03 17:32:58 maxv Exp $ */
+/* $NetBSD: nvmm_x86.c,v 1.5 2019/04/03 19:10:58 maxv Exp $ */
/*
* Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.4 2019/04/03 17:32:58 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86.c,v 1.5 2019/04/03 19:10:58 maxv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -313,3 +313,19 @@ const struct nvmm_x86_cpuid_mask nvmm_cp
CPUID_EM64T | CPUID_3DNOW2 |
CPUID_3DNOW
};
+
+bool
+nvmm_x86_pat_validate(uint64_t val)
+{
+ uint8_t *pat = (uint8_t *)&val;
+ size_t i;
+
+ for (i = 0; i < 8; i++) {
+ if (__predict_false(pat[i] & ~__BITS(2,0)))
+ return false;
+ if (__predict_false(pat[i] == 2 || pat[i] == 3))
+ return false;
+ }
+
+ return true;
+}
Index: src/sys/dev/nvmm/x86/nvmm_x86.h
diff -u src/sys/dev/nvmm/x86/nvmm_x86.h:1.9 src/sys/dev/nvmm/x86/nvmm_x86.h:1.10
--- src/sys/dev/nvmm/x86/nvmm_x86.h:1.9 Wed Apr 3 17:32:58 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86.h Wed Apr 3 19:10:58 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm_x86.h,v 1.9 2019/04/03 17:32:58 maxv Exp $ */
+/* $NetBSD: nvmm_x86.h,v 1.10 2019/04/03 19:10:58 maxv Exp $ */
/*
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -186,6 +186,7 @@ extern const struct nvmm_x64_state nvmm_
extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000001;
extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000007;
extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000001;
+bool nvmm_x86_pat_validate(uint64_t);
#endif
#endif /* ASM_NVMM */
Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.22 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.23
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.22 Wed Apr 3 18:05:55 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c Wed Apr 3 19:10:58 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm_x86_vmx.c,v 1.22 2019/04/03 18:05:55 maxv Exp $ */
+/* $NetBSD: nvmm_x86_vmx.c,v 1.23 2019/04/03 19:10:58 maxv Exp $ */
/*
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.22 2019/04/03 18:05:55 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.23 2019/04/03 19:10:58 maxv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -1502,7 +1502,11 @@ vmx_inkernel_handle_msr(struct nvmm_mach
goto handled;
}
if (exit->u.msr.msr == MSR_CR_PAT) {
- vmx_vmwrite(VMCS_GUEST_IA32_PAT, exit->u.msr.val);
+ val = exit->u.msr.val;
+ if (__predict_false(!nvmm_x86_pat_validate(val))) {
+ goto error;
+ }
+ vmx_vmwrite(VMCS_GUEST_IA32_PAT, val);
goto handled;
}
if (exit->u.msr.msr == MSR_MISC_ENABLE) {
@@ -1522,6 +1526,10 @@ vmx_inkernel_handle_msr(struct nvmm_mach
handled:
vmx_inkernel_advance();
return true;
+
+error:
+ vmx_inject_gp(mach, vcpu);
+ return true;
}
static void