diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-08-27 09:16:04 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-08-27 09:16:04 +0000 |
commit | 39d4ecb3e8d2b04919a71f48fb27c1f52b1bcbf6 (patch) | |
tree | be60153d6680099a6292d1717c3f9738b3eabc9d /sys/arch/amd64 | |
parent | 508cabb40c98c7678b14db8b71ce0c5402430fd7 (diff) |
Enable AMD SEV support in vmm(4).
Bring the pieces for vmm(4) to support guests with SEV memory
encryption on AMD CPUs. The corresponding vmd(8) changes will
follow.
Emulate cpuid 0x8000001f so the guest can discover SEV features.
Allow vmd(8) to enable SEV on VM creation. Inform vmd(8) about the
c-bit position and ASID assigned to each VCPU.
Note that vmd(8) has to be rebuilt with the new header files.
from hshoexer@; input dv@; OK mlarkin@
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r-- | sys/arch/amd64/amd64/identcpu.c | 4 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/vmm_machdep.c | 54 | ||||
-rw-r--r-- | sys/arch/amd64/include/cpu.h | 3 | ||||
-rw-r--r-- | sys/arch/amd64/include/vmmvar.h | 9 |
4 files changed, 47 insertions, 23 deletions
diff --git a/sys/arch/amd64/amd64/identcpu.c b/sys/arch/amd64/amd64/identcpu.c index a6e31e50255..755e0eeaafb 100644 --- a/sys/arch/amd64/amd64/identcpu.c +++ b/sys/arch/amd64/amd64/identcpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: identcpu.c,v 1.146 2024/07/08 14:46:47 mpi Exp $ */ +/* $OpenBSD: identcpu.c,v 1.147 2024/08/27 09:16:03 bluhm Exp $ */ /* $NetBSD: identcpu.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */ /* @@ -66,7 +66,7 @@ char cpu_model[48]; int cpuspeed; int amd64_has_xcrypt; -int amd64_pos_cbit; +int amd64_pos_cbit; /* C bit position for SEV */ int has_rdrand; int has_rdseed; diff --git a/sys/arch/amd64/amd64/vmm_machdep.c b/sys/arch/amd64/amd64/vmm_machdep.c index 0df3d8b070f..c84fbb3273c 100644 --- a/sys/arch/amd64/amd64/vmm_machdep.c +++ b/sys/arch/amd64/amd64/vmm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm_machdep.c,v 1.32 2024/08/22 04:53:07 mlarkin Exp $ */ +/* $OpenBSD: vmm_machdep.c,v 1.33 2024/08/27 09:16:03 bluhm Exp $ */ /* * Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org> * @@ -82,9 +82,9 @@ int vcpu_reset_regs(struct vcpu *, struct vcpu_reg_state *); int vcpu_reset_regs_vmx(struct vcpu *, struct vcpu_reg_state *); int vcpu_reset_regs_svm(struct vcpu *, struct vcpu_reg_state *); int vcpu_reload_vmcs_vmx(struct vcpu *); -int vcpu_init(struct vcpu *); +int vcpu_init(struct vcpu *, struct vm_create_params *); int vcpu_init_vmx(struct vcpu *); -int vcpu_init_svm(struct vcpu *); +int vcpu_init_svm(struct vcpu *, struct vm_create_params *); int vcpu_run_vmx(struct vcpu *, struct vm_run_params *); int vcpu_run_svm(struct vcpu *, struct vm_run_params *); void vcpu_deinit(struct vcpu *); @@ -1890,7 +1890,6 @@ vcpu_reset_regs_svm(struct vcpu *vcpu, struct vcpu_reg_state *vrs) { struct vmcb *vmcb; int ret; - uint16_t asid; vmcb = (struct vmcb *)vcpu->vc_control_va; @@ -1963,14 +1962,7 @@ vcpu_reset_regs_svm(struct vcpu *vcpu, struct vcpu_reg_state *vrs) svm_setmsrbr(vcpu, MSR_PSTATEDEF(0)); /* Guest VCPU ASID */ - if (vmm_alloc_vpid(&asid)) { - DPRINTF("%s: could not allocate asid\n", __func__); - ret = EINVAL; - goto exit; - } - - vmcb->v_asid = asid; - vcpu->vc_vpid = asid; + vmcb->v_asid = vcpu->vc_vpid; /* TLB Control - First time in, flush all*/ vmcb->v_tlb_control = SVM_TLB_CONTROL_FLUSH_ALL; @@ -1985,9 +1977,13 @@ vcpu_reset_regs_svm(struct vcpu *vcpu, struct vcpu_reg_state *vrs) PATENTRY(6, PAT_UCMINUS) | PATENTRY(7, PAT_UC); /* NPT */ - vmcb->v_np_enable = 1; + vmcb->v_np_enable = SVM_ENABLE_NP; vmcb->v_n_cr3 = vcpu->vc_parent->vm_map->pmap->pm_pdirpa; + /* SEV */ + if (vcpu->vc_sev) + vmcb->v_np_enable |= SVM_ENABLE_SEV; + /* Enable SVME in EFER (must always be set) */ vmcb->v_efer |= EFER_SVME; @@ -1998,7 +1994,6 @@ vcpu_reset_regs_svm(struct vcpu *vcpu, struct vcpu_reg_state *vrs) vcpu->vc_parent->vm_map->pmap->eptp = 0; -exit: return ret; } @@ -3086,6 +3081,7 @@ vcpu_reset_regs(struct vcpu *vcpu, struct vcpu_reg_state *vrs) * * Parameters: * vcpu: the VCPU structure being initialized + * vcp: parameters provided by vmd(8) * * Return values: * 0: the VCPU was initialized successfully @@ -3093,8 +3089,9 @@ vcpu_reset_regs(struct vcpu *vcpu, struct vcpu_reg_state *vrs) * EINVAL: an error occurred during VCPU initialization */ int -vcpu_init_svm(struct vcpu *vcpu) +vcpu_init_svm(struct vcpu *vcpu, struct vm_create_params *vcp) { + uint16_t asid; int ret = 0; /* Allocate VMCB VA */ @@ -3176,6 +3173,21 @@ vcpu_init_svm(struct vcpu *vcpu) (uint64_t)vcpu->vc_svm_ioio_va, (uint64_t)vcpu->vc_svm_ioio_pa); + /* Guest VCPU ASID */ + if (vmm_alloc_vpid(&asid)) { + DPRINTF("%s: could not allocate asid\n", __func__); + ret = EINVAL; + goto exit; + } + vcpu->vc_vpid = asid; + + /* Shall we enable SEV? */ + vcpu->vc_sev = vcp->vcp_sev; + + /* Inform vmd(8) about ASID and C bit position. */ + vcp->vcp_poscbit = amd64_pos_cbit; + vcp->vcp_asid[vcpu->vc_id] = vcpu->vc_vpid; + exit: if (ret) vcpu_deinit_svm(vcpu); @@ -3189,7 +3201,7 @@ exit: * Calls the architecture-specific VCPU init routine */ int -vcpu_init(struct vcpu *vcpu) +vcpu_init(struct vcpu *vcpu, struct vm_create_params *vcp) { int ret = 0; @@ -3207,7 +3219,7 @@ vcpu_init(struct vcpu *vcpu) if (vmm_softc->mode == VMM_MODE_EPT) ret = vcpu_init_vmx(vcpu); else if (vmm_softc->mode == VMM_MODE_RVI) - ret = vcpu_init_svm(vcpu); + ret = vcpu_init_svm(vcpu, vcp); else panic("%s: unknown vmm mode: %d", __func__, vmm_softc->mode); @@ -6285,7 +6297,7 @@ vmm_handle_cpuid(struct vcpu *vcpu) *rdx = 0; break; case 0x80000000: /* Extended function level */ - *rax = 0x80000008; /* curcpu()->ci_pnfeatset */ + *rax = 0x8000001f; /* curcpu()->ci_pnfeatset */ *rbx = 0; *rcx = 0; *rdx = 0; @@ -6345,6 +6357,12 @@ vmm_handle_cpuid(struct vcpu *vcpu) *rcx = ecx; *rdx = edx; break; + case 0x8000001f: /* encryption features (AMD) */ + *rax = eax; + *rbx = ebx; + *rcx = ecx; + *rdx = edx; + break; default: DPRINTF("%s: unsupported rax=0x%llx\n", __func__, *rax); *rax = 0; diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index f5aada4d4d3..ca198b24a69 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.175 2024/07/21 19:41:31 bluhm Exp $ */ +/* $OpenBSD: cpu.h,v 1.176 2024/08/27 09:16:03 bluhm Exp $ */ /* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */ /*- @@ -415,6 +415,7 @@ void x86_print_cacheinfo(struct cpu_info *); void identifycpu(struct cpu_info *); int cpu_amd64speed(int *); extern int cpuspeed; +extern int amd64_pos_cbit; /* machdep.c */ void dumpconf(void); diff --git a/sys/arch/amd64/include/vmmvar.h b/sys/arch/amd64/include/vmmvar.h index 3f35e520926..f652bc1b83f 100644 --- a/sys/arch/amd64/include/vmmvar.h +++ b/sys/arch/amd64/include/vmmvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vmmvar.h,v 1.104 2024/07/14 07:57:42 dv Exp $ */ +/* $OpenBSD: vmmvar.h,v 1.105 2024/08/27 09:16:03 bluhm Exp $ */ /* * Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org> * @@ -624,6 +624,7 @@ enum { /* Forward declarations */ struct vm; +struct vm_create_params; /* * Implementation-specific cpu state @@ -636,6 +637,9 @@ struct vmcb_segment { uint64_t vs_base; /* 008h */ }; +#define SVM_ENABLE_NP (1ULL << 0) +#define SVM_ENABLE_SEV (1ULL << 1) + struct vmcb { union { struct { @@ -893,6 +897,7 @@ struct vcpu { paddr_t vc_svm_hsa_pa; vaddr_t vc_svm_ioio_va; paddr_t vc_svm_ioio_pa; + int vc_sev; /* [I] */ }; SLIST_HEAD(vcpu_head, vcpu); @@ -921,7 +926,7 @@ int vmm_start(void); int vmm_stop(void); int vm_impl_init(struct vm *, struct proc *); void vm_impl_deinit(struct vm *); -int vcpu_init(struct vcpu *); +int vcpu_init(struct vcpu *, struct vm_create_params *); void vcpu_deinit(struct vcpu *); int vm_rwregs(struct vm_rwregs_params *, int); int vcpu_reset_regs(struct vcpu *, struct vcpu_reg_state *); |