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