-/* $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>
*
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 *);
{
struct vmcb *vmcb;
int ret;
- uint16_t asid;
vmcb = (struct vmcb *)vcpu->vc_control_va;
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;
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;
vcpu->vc_parent->vm_map->pmap->eptp = 0;
-exit:
return ret;
}
*
* Parameters:
* vcpu: the VCPU structure being initialized
+ * vcp: parameters provided by vmd(8)
*
* Return values:
* 0: the VCPU was initialized successfully
* 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 */
(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);
* 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;
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);
*rdx = 0;
break;
case 0x80000000: /* Extended function level */
- *rax = 0x80000008; /* curcpu()->ci_pnfeatset */
+ *rax = 0x8000001f; /* curcpu()->ci_pnfeatset */
*rbx = 0;
*rcx = 0;
*rdx = 0;
*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;
-/* $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>
*
/* Forward declarations */
struct vm;
+struct vm_create_params;
/*
* Implementation-specific cpu state
uint64_t vs_base; /* 008h */
};
+#define SVM_ENABLE_NP (1ULL << 0)
+#define SVM_ENABLE_SEV (1ULL << 1)
+
struct vmcb {
union {
struct {
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);
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 *);
-/* $OpenBSD: vmm.c,v 1.2 2023/05/13 23:15:28 dv Exp $ */
+/* $OpenBSD: vmm.c,v 1.3 2024/08/27 09:16:03 bluhm Exp $ */
/*
* Copyright (c) 2014-2023 Mike Larkin <mlarkin@openbsd.org>
*
vcpu = pool_get(&vcpu_pool, PR_WAITOK | PR_ZERO);
vcpu->vc_parent = vm;
- if ((ret = vcpu_init(vcpu)) != 0) {
+ vcpu->vc_id = vm->vm_vcpu_ct;
+ vm->vm_vcpu_ct++;
+ if ((ret = vcpu_init(vcpu, vcp)) != 0) {
printf("failed to init vcpu %d for vm %p\n", i, vm);
vm_teardown(&vm);
return (ret);
}
- vcpu->vc_id = vm->vm_vcpu_ct;
- vm->vm_vcpu_ct++;
/* Publish vcpu to list, inheriting the reference. */
SLIST_INSERT_HEAD(&vm->vm_vcpu_list, vcpu, vc_vcpu_link);
}