Index | Thread | Search

From:
Hans-Jörg Höxer <hshoexer@genua.de>
Subject:
SEV-ES: vmm(4): Handle MSR gexit
To:
<tech@openbsd.org>
Date:
Tue, 20 May 2025 12:23:04 +0200

Download raw body.

Thread
Hi,

next bit, MSR related GEXIT:

    Fill in the actual handler for MSR related VMGEXIT:  The SEV-ES
    guest sends vmm(4) A, C and D GPRs for wrmsr; and C for rdmsr.  For
    wrmsr vmm(4) returns nothing to the guest; for rdmsr the 64bit
    result is split into EAX and EDX.
    
    As with "normal" SVM_VMEXIT_MSR, svm_handle_msr() does the actual
    work.

Take care,
HJ.

--------------------------------------------------------------------------
commit e16349e4d36f0efa87400ce304f4bc77a5cb2987
Author: Hans-Joerg Hoexer <hshoexer@genua.de>
Date:   Thu Jan 16 14:10:04 2025 +0100

    vmm(4): Handle MSR gexit
    
    Fill in the actual handler for MSR related VMGEXIT:  The SEV-ES
    guest sends vmm(4) A, C and D GPRs for wrmsr; and C for rdmsr.  For
    wrmsr vmm(4) returns nothing to the guest; for rdmsr the 64bit
    result is split into EAX and EDX.
    
    As with "normal" SVM_VMEXIT_MSR, svm_handle_msr() does the actual
    work.

diff --git a/sys/arch/amd64/amd64/vmm_machdep.c b/sys/arch/amd64/amd64/vmm_machdep.c
index c6bba94700a..9bcf3f3fffe 100644
--- a/sys/arch/amd64/amd64/vmm_machdep.c
+++ b/sys/arch/amd64/amd64/vmm_machdep.c
@@ -4382,6 +4382,17 @@ svm_gexit_sync_host(struct vcpu *vcpu)
 		ghcb_valbm_set(expected_bm, GHCB_RAX);
 		ghcb_valbm_set(expected_bm, GHCB_RCX);
 		break;
+	case SVM_VMEXIT_MSR:
+		if (ghcb->v_sw_exitinfo1 == 1) {
+			/* WRMSR */
+			ghcb_valbm_set(expected_bm, GHCB_RAX);
+			ghcb_valbm_set(expected_bm, GHCB_RCX);
+			ghcb_valbm_set(expected_bm, GHCB_RDX);
+		} else {
+			/* RDMSR */
+			ghcb_valbm_set(expected_bm, GHCB_RCX);
+		}
+		break;
 	default:
 		return (EINVAL);
 	}
@@ -4438,6 +4449,15 @@ svm_gexit_sync_guest(struct vcpu *vcpu)
 		ghcb_valbm_set(valid_bm, GHCB_RCX);
 		ghcb_valbm_set(valid_bm, GHCB_RDX);
 		break;
+	case SVM_VMEXIT_MSR:
+		if (svm_sw_exitinfo1 == 1) {
+			/* WRMSR -- nothing to return */
+		} else {
+			/* RDMSR */
+			ghcb_valbm_set(valid_bm, GHCB_RAX);
+			ghcb_valbm_set(valid_bm, GHCB_RDX);
+		}
+		break;
 	default:
 		return (EINVAL);
 	}
@@ -4503,6 +4523,11 @@ svm_handle_gexit(struct vcpu *vcpu)
 		vcpu->vc_gueststate.vg_rax = vmcb->v_rax;
 		syncout = 1;
 		break;
+	case SVM_VMEXIT_MSR:
+		error = svm_handle_msr(vcpu);
+		vmcb->v_rip = vcpu->vc_gueststate.vg_rip;
+		syncout = 1;
+		break;
 	default:
 		DPRINTF("%s: unknown exit 0x%llx\n", __func__,
 		    vmcb->v_exitcode);