From: Hans-Jörg Höxer Subject: Re: vmm(4): For SEV-ES use GUEST_INTERRUPT_MASK To: Date: Wed, 30 Apr 2025 16:32:38 +0200 Hi, I should mention: This diff is relevant to existing VM setups. But it should not change behaviour. A change would be a regression. So tests are welcome. Take care, HJ. On Wed, Apr 30, 2025 at 04:26:37PM +0200, Hans-Jörg Höxer wrote: > Hi, > > this is diff 2/3. As vmm(4) cannot access a SEV-ES guests rflags > register, we have to use the GUEST_INTERRUPT_MASK field from the VMCB > for SEV-ES enabled guests. > > Take care, > HJ. > > --------------------------------------------------------------- > commit 939134e1a692824d0f8d94ea566102637ff2b800 > Author: Hans-Joerg Hoexer > Date: Tue Nov 12 14:55:11 2024 +0100 > > vmm(4): For SEV-ES use GUEST_INTERRUPT_MASK > > Due to state encryption we can not determine the state of the > interrupt enable flag from the FLAGS register. Therefore the VMCB > provides at offset 0x68 bit 1 the current state of this flag. > > However, only when this is a SEV-ES enabled guest. Otherwise, we > have to use the FLAGS register. > > diff --git a/sys/arch/amd64/amd64/vmm_machdep.c b/sys/arch/amd64/amd64/vmm_machdep.c > index 3d5c58de71d..28809aa57d2 100644 > --- a/sys/arch/amd64/amd64/vmm_machdep.c > +++ b/sys/arch/amd64/amd64/vmm_machdep.c > @@ -98,6 +98,7 @@ int vmx_load_pdptes(struct vcpu *); > int vmx_handle_exit(struct vcpu *); > int svm_handle_exit(struct vcpu *); > int svm_handle_efercr(struct vcpu *, uint64_t); > +int svm_get_iflag(struct vcpu *, uint64_t); > int svm_handle_msr(struct vcpu *); > int vmm_handle_xsetbv(struct vcpu *, uint64_t *); > int vmx_handle_xsetbv(struct vcpu *); > @@ -4149,7 +4150,7 @@ svm_handle_hlt(struct vcpu *vcpu) > /* All HLT insns are 1 byte */ > vcpu->vc_gueststate.vg_rip += 1; > > - if (!(rflags & PSL_I)) { > + if (!svm_get_iflag(vcpu, rflags)) { > DPRINTF("%s: guest halted with interrupts disabled\n", > __func__); > return (EIO); > @@ -4245,7 +4246,7 @@ svm_handle_exit(struct vcpu *vcpu) > > switch (exit_reason) { > case SVM_VMEXIT_VINTR: > - if (!(rflags & PSL_I)) { > + if (!svm_get_iflag(vcpu, rflags)) { > DPRINTF("%s: impossible interrupt window exit " > "config\n", __func__); > ret = EINVAL; > @@ -4369,6 +4370,23 @@ svm_handle_efercr(struct vcpu *vcpu, uint64_t exit_reason) > return (0); > } > > +/* > + * svm_get_iflag > + * > + * With SEV-ES the hypervisor has no access to the flags register. > + * Only the the state of the PSL_I is proivded by v_intr_shadow in > + * the VMCB. > + */ > +int > +svm_get_iflag(struct vcpu *vcpu, uint64_t rflags) > +{ > + struct vmcb *vmcb = (struct vmcb *)vcpu->vc_control_va; > + > + if (vcpu->vc_seves) > + return (vmcb->v_intr_shadow & SMV_GUEST_INTR_MASK); > + return (rflags & PSL_I); > +} > + > /* > * vmx_handle_exit > * > @@ -6421,7 +6439,7 @@ vcpu_run_svm(struct vcpu *vcpu, struct vm_run_params *vrp) > */ > ret = svm_handle_exit(vcpu); > > - if (vcpu->vc_gueststate.vg_rflags & PSL_I) > + if (svm_get_iflag(vcpu, vcpu->vc_gueststate.vg_rflags)) > vcpu->vc_irqready = 1; > else > vcpu->vc_irqready = 0; > diff --git a/sys/arch/amd64/include/vmmvar.h b/sys/arch/amd64/include/vmmvar.h > index 22c60907f1a..22d892ae2f3 100644 > --- a/sys/arch/amd64/include/vmmvar.h > +++ b/sys/arch/amd64/include/vmmvar.h > @@ -627,6 +627,8 @@ struct vmcb_segment { > #define SVM_ENABLE_SEV (1ULL << 1) > #define SVM_SEVES_ENABLE (1ULL << 2) > > +#define SMV_GUEST_INTR_MASK (1ULL << 1) > + > #define SVM_LBRVIRT_ENABLE (1ULL << 0) > > struct vmcb { -- Dr. Hans-Jörg Höxer Hans-Joerg_Hoexer@genua.de Senior Expert Kryptographie eXtreme Kernel and Crypto Development genua GmbH Domagkstrasse 7, 85551 Kirchheim bei München tel +49 89 991950-0, fax -999, www.genua.eu Geschäftsführer: Matthias Ochs, Marc Tesch Amtsgericht München HRB 98238 genua ist ein Unternehmen der Bundesdruckerei-Gruppe.