From: Hans-Jörg Höxer Subject: SEV-ES: vmm(4): Handle MSR gexit To: Date: Tue, 20 May 2025 12:23:04 +0200 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 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);