Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/nvmm/x86 nvmm-x86: improve the handling of RFLAGS.RF
details: https://anonhg.NetBSD.org/src/rev/65779a2d12e0
branches: trunk
changeset: 937779:65779a2d12e0
user: maxv <maxv%NetBSD.org@localhost>
date: Wed Aug 26 16:32:02 2020 +0000
description:
nvmm-x86: improve the handling of RFLAGS.RF
- When injecting certain exceptions, set RF. For us to have an up-to-date
view of RFLAGS, we commit the state before the event.
- When advancing RIP, clear RF.
diffstat:
sys/dev/nvmm/x86/nvmm_x86_svm.c | 31 +++++++++++++++++++++++++------
sys/dev/nvmm/x86/nvmm_x86_vmx.c | 40 ++++++++++++++++++++++++++++++++--------
2 files changed, 57 insertions(+), 14 deletions(-)
diffs (183 lines):
diff -r b387f91ca180 -r 65779a2d12e0 sys/dev/nvmm/x86/nvmm_x86_svm.c
--- a/sys/dev/nvmm/x86/nvmm_x86_svm.c Wed Aug 26 16:30:50 2020 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_svm.c Wed Aug 26 16:32:02 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm_x86_svm.c,v 1.72 2020/08/26 16:29:19 maxv Exp $ */
+/* $NetBSD: nvmm_x86_svm.c,v 1.73 2020/08/26 16:32:02 maxv Exp $ */
/*
* Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.72 2020/08/26 16:29:19 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.73 2020/08/26 16:32:02 maxv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -676,8 +676,22 @@
svm_vmcb_cache_flush(vmcb, VMCB_CTRL_VMCB_CLEAN_I);
}
+static inline bool
+svm_excp_has_rf(uint8_t vector)
+{
+ switch (vector) {
+ case 1: /* #DB */
+ case 4: /* #OF */
+ case 8: /* #DF */
+ case 18: /* #MC */
+ return false;
+ default:
+ return true;
+ }
+}
+
static inline int
-svm_event_has_error(uint8_t vector)
+svm_excp_has_error(uint8_t vector)
{
switch (vector) {
case 8: /* #DF */
@@ -717,7 +731,10 @@
return EINVAL;
if (vector == 3 || vector == 0)
return EINVAL;
- err = svm_event_has_error(vector);
+ if (svm_excp_has_rf(vector)) {
+ vmcb->state.rflags |= PSL_RF;
+ }
+ err = svm_excp_has_error(vector);
break;
case NVMM_VCPU_EVENT_INTR:
type = SVM_EVENT_TYPE_HW_INT;
@@ -790,6 +807,7 @@
* debugger.
*/
vmcb->state.rip = vmcb->ctrl.nrip;
+ vmcb->state.rflags &= ~PSL_RF;
vmcb->ctrl.intr &= ~VMCB_CTRL_INTR_SHADOW;
}
@@ -1473,11 +1491,12 @@
uint64_t machgen;
int hcpu;
+ svm_vcpu_state_commit(vcpu);
+ comm->state_cached = 0;
+
if (__predict_false(svm_vcpu_event_commit(vcpu) != 0)) {
return EINVAL;
}
- svm_vcpu_state_commit(vcpu);
- comm->state_cached = 0;
kpreempt_disable();
hcpu = cpu_number();
diff -r b387f91ca180 -r 65779a2d12e0 sys/dev/nvmm/x86/nvmm_x86_vmx.c
--- a/sys/dev/nvmm/x86/nvmm_x86_vmx.c Wed Aug 26 16:30:50 2020 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_vmx.c Wed Aug 26 16:32:02 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm_x86_vmx.c,v 1.73 2020/08/26 16:30:50 maxv Exp $ */
+/* $NetBSD: nvmm_x86_vmx.c,v 1.74 2020/08/26 16:32:02 maxv Exp $ */
/*
* Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.73 2020/08/26 16:30:50 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.74 2020/08/26 16:32:02 maxv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -1038,8 +1038,22 @@
vmx_vmwrite(VMCS_PROCBASED_CTLS, ctls1);
}
+static inline bool
+vmx_excp_has_rf(uint8_t vector)
+{
+ switch (vector) {
+ case 1: /* #DB */
+ case 4: /* #OF */
+ case 8: /* #DF */
+ case 18: /* #MC */
+ return false;
+ default:
+ return true;
+ }
+}
+
static inline int
-vmx_event_has_error(uint8_t vector)
+vmx_excp_has_error(uint8_t vector)
{
switch (vector) {
case 8: /* #DF */
@@ -1062,9 +1076,9 @@
struct nvmm_comm_page *comm = vcpu->comm;
struct vmx_cpudata *cpudata = vcpu->cpudata;
int type = 0, err = 0, ret = EINVAL;
+ uint64_t rflags, info, error;
u_int evtype;
uint8_t vector;
- uint64_t info, error;
evtype = comm->event.type;
vector = comm->event.vector;
@@ -1079,8 +1093,12 @@
goto out;
if (vector == 3 || vector == 0)
goto out;
+ if (vmx_excp_has_rf(vector)) {
+ rflags = vmx_vmread(VMCS_GUEST_RFLAGS);
+ vmx_vmwrite(VMCS_GUEST_RFLAGS, rflags | PSL_RF);
+ }
type = INTR_TYPE_HW_EXC;
- err = vmx_event_has_error(vector);
+ err = vmx_excp_has_error(vector);
break;
case NVMM_VCPU_EVENT_INTR:
type = INTR_TYPE_EXT_INT;
@@ -1151,16 +1169,21 @@
static inline void
vmx_inkernel_advance(void)
{
- uint64_t rip, inslen, intstate;
+ uint64_t rip, inslen, intstate, rflags;
/*
* Maybe we should also apply single-stepping and debug exceptions.
* Matters for guest-ring3, because it can execute 'cpuid' under a
* debugger.
*/
+
inslen = vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH);
rip = vmx_vmread(VMCS_GUEST_RIP);
vmx_vmwrite(VMCS_GUEST_RIP, rip + inslen);
+
+ rflags = vmx_vmread(VMCS_GUEST_RFLAGS);
+ vmx_vmwrite(VMCS_GUEST_RFLAGS, rflags & ~PSL_RF);
+
intstate = vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY);
vmx_vmwrite(VMCS_GUEST_INTERRUPTIBILITY,
intstate & ~(INT_STATE_STI|INT_STATE_MOVSS));
@@ -2160,12 +2183,13 @@
vmx_vmcs_enter(vcpu);
+ vmx_vcpu_state_commit(vcpu);
+ comm->state_cached = 0;
+
if (__predict_false(vmx_vcpu_event_commit(vcpu) != 0)) {
vmx_vmcs_leave(vcpu);
return EINVAL;
}
- vmx_vcpu_state_commit(vcpu);
- comm->state_cached = 0;
ci = curcpu();
hcpu = cpu_number();
Home |
Main Index |
Thread Index |
Old Index