Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 17 Aug 2023 13:29:31 GMT
From:      Corvin =?utf-8?Q?K=C3=B6hne?= <corvink@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 82eece443ee3 - stable/13 - bhyve: fix vCPU single-stepping on VMX
Message-ID:  <202308171329.37HDTVsp030649@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by corvink:

URL: https://cgit.FreeBSD.org/src/commit/?id=82eece443ee3eed9a04481e7127271985734ddff

commit 82eece443ee3eed9a04481e7127271985734ddff
Author:     Bojan Novković <bojan.novkovic@fer.hr>
AuthorDate: 2023-05-09 07:02:04 +0000
Commit:     Corvin Köhne <corvink@FreeBSD.org>
CommitDate: 2023-08-17 13:06:29 +0000

    bhyve: fix vCPU single-stepping on VMX
    
    This patch fixes virtual machine single stepping on VMX hosts.
    
    Currently, when using bhyve's gdb stub, each attempt at single-stepping
    a vCPU lands in a timer interrupt. The current single-stepping mechanism
    uses the Monitor Trap Flag feature to cause VMEXIT after a single
    instruction is executed. Unfortunately, the SDM states that MTF causes
    VMEXITs for the next instruction that gets executed, which is often not
    what the person using the debugger expects. [1]
    
    This patch adds a new VM capability that masks interrupts on a vCPU by
    blocking interrupt injection and modifies the gdb stub to use the newly
    added capability while single-stepping a vCPU.
    
    [1] Intel SDM 26.5.2 Vol. 3C
    
    Reviewed by:            corvink, jbh
    MFC after:              1 week
    Differential Revision:  https://reviews.freebsd.org/D39949
    
    (cherry picked from commit fefac543590db4e1461235b7c936f46026d0f318)
---
 sys/amd64/include/vmm.h   | 1 +
 sys/amd64/vmm/intel/vmx.c | 7 +++++++
 usr.sbin/bhyve/gdb.c      | 5 +++++
 3 files changed, 13 insertions(+)

diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index 29797ad04e0d..84b689dd7391 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -500,6 +500,7 @@ enum vm_cap_type {
 	VM_CAP_RDPID,
 	VM_CAP_RDTSCP,
 	VM_CAP_IPI_EXIT,
+	VM_CAP_MASK_HWINTR,
 	VM_CAP_MAX
 };
 
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index 3a0693a29e80..9c2672c9ae23 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -1439,6 +1439,10 @@ vmx_inject_interrupts(struct vmx_vcpu *vcpu, struct vlapic *vlapic,
 	uint64_t rflags, entryinfo;
 	uint32_t gi, info;
 
+	if (vcpu->cap.set & (1 << VM_CAP_MASK_HWINTR)) {
+		return;
+	}
+
 	if (vcpu->state.nextrip != guestrip) {
 		gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
 		if (gi & HWINTR_BLOCKING) {
@@ -3634,6 +3638,9 @@ vmx_setcap(void *vcpui, int type, int val)
 		vlapic = vm_lapic(vcpu->vcpu);
 		vlapic->ipi_exit = val;
 		break;
+	case VM_CAP_MASK_HWINTR:		
+		retval = 0;
+		break;
 	default:
 		break;
 	}
diff --git a/usr.sbin/bhyve/gdb.c b/usr.sbin/bhyve/gdb.c
index 6c1315a8371d..03f684e002ce 100644
--- a/usr.sbin/bhyve/gdb.c
+++ b/usr.sbin/bhyve/gdb.c
@@ -795,6 +795,9 @@ gdb_cpu_resume(int vcpu)
 	if (vs->stepping) {
 		error = vm_set_capability(ctx, vcpu, VM_CAP_MTRAP_EXIT, 1);
 		assert(error == 0);
+
+		error = vm_set_capability(ctx, vcpu, VM_CAP_MASK_HWINTR, 1);
+		assert(error == 0);
 	}
 }
 
@@ -845,6 +848,8 @@ gdb_cpu_mtrap(int vcpu)
 		vs->stepping = false;
 		vs->stepped = true;
 		vm_set_capability(ctx, vcpu, VM_CAP_MTRAP_EXIT, 0);
+		vm_set_capability(ctx, vcpu, VM_CAP_MASK_HWINTR, 0);
+
 		while (vs->stepped) {
 			if (stopped_vcpu == -1) {
 				debug("$vCPU %d reporting step\n", vcpu);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202308171329.37HDTVsp030649>