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

Reply via email to