From: Hans-Jörg Höxer Subject: Re: [EXT] Re: SEV-ES: respect minimum ASID value To: Date: Mon, 28 Apr 2025 10:49:33 +0200 Hi, On Sat, Apr 26, 2025 at 08:51:42PM +0200, Alexander Bluhm wrote: > ... > Can we please put extern declarations in a header file? > +extern int amd64_min_noes_asid; > In a C file, other than where it is defined, can easily lead to > mistakes when something in the code changes. ack. > Function name _vmm_alloc_vpid() with an underscore looks strange. > Can we call it vmm_alloc_vpid_vcpu() ? ack. Update diff below. Take care, HJ. ------------------------------------------------------------------ commit e13ab6cb2dd5ce625202e3ffb94a7f933db28dfe Author: Hans-Joerg Hoexer Date: Wed Jul 10 13:25:04 2024 +0200 vmm: minimum ASID for non-SEVES guests Introduce vmm_alloc_asid() to be used by SVM base VMs. No change for VMX based VMs. diff --git a/sys/arch/amd64/amd64/identcpu.c b/sys/arch/amd64/amd64/identcpu.c index 18ecbc8f4c8..1a9a99e9bbb 100644 --- a/sys/arch/amd64/amd64/identcpu.c +++ b/sys/arch/amd64/amd64/identcpu.c @@ -67,6 +67,7 @@ int cpuspeed; int amd64_has_xcrypt; int amd64_pos_cbit; /* C bit position for SEV */ +int amd64_min_noes_asid; int has_rdrand; int has_rdseed; @@ -710,6 +711,7 @@ identifycpu(struct cpu_info *ci) 'd', CPUID_MEMBER(ci_feature_amdsev_edx), CPUID_AMDSEV_EDX_BITS); amd64_pos_cbit = (ci->ci_feature_amdsev_ebx & 0x3f); + amd64_min_noes_asid = (ci->ci_feature_amdsev_edx); } printf("\n"); diff --git a/sys/arch/amd64/amd64/vmm_machdep.c b/sys/arch/amd64/amd64/vmm_machdep.c index e1a17583fe3..9b5d56da27b 100644 --- a/sys/arch/amd64/amd64/vmm_machdep.c +++ b/sys/arch/amd64/amd64/vmm_machdep.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -124,7 +125,9 @@ int svm_fault_page(struct vcpu *, paddr_t); int vmx_fault_page(struct vcpu *, paddr_t); int vmx_handle_np_fault(struct vcpu *); int svm_handle_np_fault(struct vcpu *); +int vmm_alloc_vpid_vcpu(uint16_t *, struct vcpu *); int vmm_alloc_vpid(uint16_t *); +int vmm_alloc_asid(uint16_t *, struct vcpu *); void vmm_free_vpid(uint16_t); const char *vcpu_state_decode(u_int); const char *vmx_exit_reason_decode(uint32_t); @@ -2766,7 +2769,7 @@ vcpu_init_svm(struct vcpu *vcpu, struct vm_create_params *vcp) int ret = 0; /* Allocate an ASID early to avoid km_alloc if we're out of ASIDs. */ - if (vmm_alloc_vpid(&vcpu->vc_vpid)) + if (vmm_alloc_asid(&vcpu->vc_vpid, vcpu)) return (ENOMEM); /* Allocate VMCB VA */ @@ -6354,27 +6357,32 @@ vcpu_run_svm(struct vcpu *vcpu, struct vm_run_params *vrp) } /* - * vmm_alloc_vpid + * vmm_alloc_vpid_vcpu * * Sets the memory location pointed to by "vpid" to the next available VPID - * or ASID. + * or ASID. For SEV-ES consider minimum ASID value for non-ES enabled guests. * * Parameters: * vpid: Pointer to location to receive the next VPID/ASID + * vcpu: Pointer to VCPU data structure * * Return Values: * 0: The operation completed successfully * ENOMEM: No VPIDs/ASIDs were available. Content of 'vpid' is unchanged. */ int -vmm_alloc_vpid(uint16_t *vpid) +vmm_alloc_vpid_vcpu(uint16_t *vpid, struct vcpu *vcpu) { - uint16_t i; + uint16_t i, minasid; uint8_t idx, bit; struct vmm_softc *sc = vmm_softc; rw_enter_write(&vmm_softc->vpid_lock); - for (i = 1; i <= sc->max_vpid; i++) { + if (vcpu == NULL || vcpu->vc_seves) + minasid = 1; + else + minasid = amd64_min_noes_asid; + for (i = minasid; i <= sc->max_vpid; i++) { idx = i / 8; bit = i - (idx * 8); @@ -6396,6 +6404,18 @@ vmm_alloc_vpid(uint16_t *vpid) return ENOMEM; } +int +vmm_alloc_vpid(uint16_t *vpid) +{ + return vmm_alloc_vpid_vcpu(vpid, NULL); +} + +int +vmm_alloc_asid(uint16_t *asid, struct vcpu *vcpu) +{ + return vmm_alloc_vpid_vcpu(asid, vcpu); +} + /* * vmm_free_vpid * diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index fc560c0ffce..77ad7bf0f34 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -416,6 +416,7 @@ void identifycpu(struct cpu_info *); int cpu_amd64speed(int *); extern int cpuspeed; extern int amd64_pos_cbit; +extern int amd64_min_noes_asid; /* machdep.c */ void dumpconf(void);