git: 950af9ffc616 - main - vmm: Expose struct vcpu as an opaque type.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 18 Nov 2022 18:26:34 UTC
The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=950af9ffc616ee573a1ce6ef0c841e897b13dfc4 commit 950af9ffc616ee573a1ce6ef0c841e897b13dfc4 Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2022-11-18 18:01:05 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2022-11-18 18:25:36 +0000 vmm: Expose struct vcpu as an opaque type. Pass a pointer to the current struct vcpu to the vcpu_init callback and save this pointer in the CPU-specific vcpu structures. Add routines to fetch a struct vcpu by index from a VM and to query the VM and vcpuid from a struct vcpu. Reviewed by: corvink, markj Differential Revision: https://reviews.freebsd.org/D37156 --- sys/amd64/include/vmm.h | 7 ++++++- sys/amd64/vmm/amd/svm.c | 4 +++- sys/amd64/vmm/amd/svm_softc.h | 1 + sys/amd64/vmm/intel/vmx.c | 4 +++- sys/amd64/vmm/intel/vmx.h | 1 + sys/amd64/vmm/io/vlapic_priv.h | 2 ++ sys/amd64/vmm/vmm.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 7 files changed, 56 insertions(+), 5 deletions(-) diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h index 5737c47842e3..41b7b2ba2dc3 100644 --- a/sys/amd64/include/vmm.h +++ b/sys/amd64/include/vmm.h @@ -143,6 +143,7 @@ enum x2apic_state { #ifdef _KERNEL CTASSERT(VM_MAX_NAMELEN >= VM_MIN_NAMELEN); +struct vcpu; struct vm; struct vm_exception; struct seg_desc; @@ -170,7 +171,8 @@ typedef void * (*vmi_init_func_t)(struct vm *vm, struct pmap *pmap); typedef int (*vmi_run_func_t)(void *vcpui, register_t rip, struct pmap *pmap, struct vm_eventinfo *info); typedef void (*vmi_cleanup_func_t)(void *vmi); -typedef void * (*vmi_vcpu_init_func_t)(void *vmi, int vcpu_id); +typedef void * (*vmi_vcpu_init_func_t)(void *vmi, struct vcpu *vcpu, + int vcpu_id); typedef void (*vmi_vcpu_cleanup_func_t)(void *vcpui); typedef int (*vmi_get_register_t)(void *vcpui, int num, uint64_t *retval); typedef int (*vmi_set_register_t)(void *vcpui, int num, uint64_t val); @@ -268,6 +270,9 @@ void vm_nmi_clear(struct vm *vm, int vcpuid); int vm_inject_extint(struct vm *vm, int vcpu); int vm_extint_pending(struct vm *vm, int vcpuid); void vm_extint_clear(struct vm *vm, int vcpuid); +int vcpu_vcpuid(struct vcpu *vcpu); +struct vm *vcpu_vm(struct vcpu *vcpu); +struct vcpu *vm_vcpu(struct vm *vm, int cpu); struct vlapic *vm_lapic(struct vm *vm, int cpu); struct vioapic *vm_ioapic(struct vm *vm); struct vhpet *vm_hpet(struct vm *vm); diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c index a8008fd4c032..5eeef4b9a0fe 100644 --- a/sys/amd64/vmm/amd/svm.c +++ b/sys/amd64/vmm/amd/svm.c @@ -609,13 +609,14 @@ svm_init(struct vm *vm, pmap_t pmap) } static void * -svm_vcpu_init(void *vmi, int vcpuid) +svm_vcpu_init(void *vmi, struct vcpu *vcpu1, int vcpuid) { struct svm_softc *sc = vmi; struct svm_vcpu *vcpu; vcpu = malloc(sizeof(*vcpu), M_SVM, M_WAITOK | M_ZERO); vcpu->sc = sc; + vcpu->vcpu = vcpu1; vcpu->vcpuid = vcpuid; vcpu->vmcb = malloc_aligned(sizeof(struct vmcb), PAGE_SIZE, M_SVM, M_WAITOK | M_ZERO); @@ -2409,6 +2410,7 @@ svm_vlapic_init(void *vcpui) vcpu = vcpui; vlapic = malloc(sizeof(struct vlapic), M_SVM_VLAPIC, M_WAITOK | M_ZERO); vlapic->vm = vcpu->sc->vm; + vlapic->vcpu = vcpu->vcpu; vlapic->vcpuid = vcpu->vcpuid; vlapic->apic_page = malloc_aligned(PAGE_SIZE, PAGE_SIZE, M_SVM_VLAPIC, M_WAITOK | M_ZERO); diff --git a/sys/amd64/vmm/amd/svm_softc.h b/sys/amd64/vmm/amd/svm_softc.h index e958cc62b343..5cc2da5343a0 100644 --- a/sys/amd64/vmm/amd/svm_softc.h +++ b/sys/amd64/vmm/amd/svm_softc.h @@ -45,6 +45,7 @@ struct asid { struct svm_vcpu { struct svm_softc *sc; + struct vcpu *vcpu; struct vmcb *vmcb; /* hardware saved vcpu context */ struct svm_regctx swctx; /* software saved vcpu context */ uint64_t vmcb_pa; /* VMCB physical address */ diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index 47e3be32c1b0..ec1b5c80dcff 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -1110,7 +1110,7 @@ vmx_init(struct vm *vm, pmap_t pmap) } static void * -vmx_vcpu_init(void *vmi, int vcpuid) +vmx_vcpu_init(void *vmi, struct vcpu *vcpu1, int vcpuid) { struct vmx *vmx = vmi; struct vmcs *vmcs; @@ -1120,6 +1120,7 @@ vmx_vcpu_init(void *vmi, int vcpuid) vcpu = malloc(sizeof(*vcpu), M_VMX, M_WAITOK | M_ZERO); vcpu->vmx = vmx; + vcpu->vcpu = vcpu1; vcpu->vcpuid = vcpuid; vcpu->vmcs = malloc_aligned(sizeof(*vmcs), PAGE_SIZE, M_VMX, M_WAITOK | M_ZERO); @@ -4074,6 +4075,7 @@ vmx_vlapic_init(void *vcpui) vlapic = malloc(sizeof(struct vlapic_vtx), M_VLAPIC, M_WAITOK | M_ZERO); vlapic->vm = vmx->vm; + vlapic->vcpu = vcpu->vcpu; vlapic->vcpuid = vcpu->vcpuid; vlapic->apic_page = (struct LAPIC *)vcpu->apic_page; diff --git a/sys/amd64/vmm/intel/vmx.h b/sys/amd64/vmm/intel/vmx.h index 80719b003b1a..87a3660340f6 100644 --- a/sys/amd64/vmm/intel/vmx.h +++ b/sys/amd64/vmm/intel/vmx.h @@ -128,6 +128,7 @@ enum { struct vmx_vcpu { struct vmx *vmx; + struct vcpu *vcpu; struct vmcs *vmcs; struct apic_page *apic_page; struct pir_desc *pir_desc; diff --git a/sys/amd64/vmm/io/vlapic_priv.h b/sys/amd64/vmm/io/vlapic_priv.h index 4b3e9009e68c..2ac0cbf68117 100644 --- a/sys/amd64/vmm/io/vlapic_priv.h +++ b/sys/amd64/vmm/io/vlapic_priv.h @@ -138,6 +138,7 @@ enum boot_state { #define VLAPIC_MAXLVT_INDEX APIC_LVT_CMCI +struct vcpu; struct vlapic; struct vlapic_ops { @@ -151,6 +152,7 @@ struct vlapic_ops { struct vlapic { struct vm *vm; + struct vcpu *vcpu; int vcpuid; struct LAPIC *apic_page; struct vlapic_ops ops; diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c index 4985cef7bbbe..18423a4951fd 100644 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -104,8 +104,10 @@ struct vlapic; struct vcpu { struct mtx mtx; /* (o) protects 'state' and 'hostcpu' */ enum vcpu_state state; /* (o) vcpu state */ + int vcpuid; /* (o) */ int hostcpu; /* (o) vcpu's host cpu */ int reqidle; /* (i) request vcpu to idle */ + struct vm *vm; /* (o) */ void *cookie; /* (i) cpu-specific data */ struct vlapic *vlapic; /* (i) APIC device model */ enum x2apic_state x2apic_state; /* (i) APIC mode */ @@ -184,6 +186,21 @@ struct vm { uint16_t maxcpus; /* (o) max pluggable cpus */ }; +#define VMM_CTR0(vcpu, format) \ + VCPU_CTR0((vcpu)->vm, (vcpu)->vcpuid, format) + +#define VMM_CTR1(vcpu, format, p1) \ + VCPU_CTR1((vcpu)->vm, (vcpu)->vcpuid, format, p1) + +#define VMM_CTR2(vcpu, format, p1, p2) \ + VCPU_CTR2((vcpu)->vm, (vcpu)->vcpuid, format, p1, p2) + +#define VMM_CTR3(vcpu, format, p1, p2, p3) \ + VCPU_CTR3((vcpu)->vm, (vcpu)->vcpuid, format, p1, p2, p3) + +#define VMM_CTR4(vcpu, format, p1, p2, p3, p4) \ + VCPU_CTR4((vcpu)->vm, (vcpu)->vcpuid, format, p1, p2, p3, p4) + static int vmm_initialized; static void vmmops_panic(void); @@ -212,7 +229,8 @@ DEFINE_VMMOPS_IFUNC(void *, init, (struct vm *vm, struct pmap *pmap)) DEFINE_VMMOPS_IFUNC(int, run, (void *vcpui, register_t rip, struct pmap *pmap, struct vm_eventinfo *info)) DEFINE_VMMOPS_IFUNC(void, cleanup, (void *vmi)) -DEFINE_VMMOPS_IFUNC(void *, vcpu_init, (void *vmi, int vcpu_id)) +DEFINE_VMMOPS_IFUNC(void *, vcpu_init, (void *vmi, struct vcpu *vcpu, + int vcpu_id)) DEFINE_VMMOPS_IFUNC(void, vcpu_cleanup, (void *vcpui)) DEFINE_VMMOPS_IFUNC(int, getreg, (void *vcpui, int num, uint64_t *retval)) DEFINE_VMMOPS_IFUNC(int, setreg, (void *vcpui, int num, uint64_t val)) @@ -327,12 +345,14 @@ vcpu_init(struct vm *vm, int vcpu_id, bool create) vcpu_lock_init(vcpu); vcpu->state = VCPU_IDLE; vcpu->hostcpu = NOCPU; + vcpu->vcpuid = vcpu_id; + vcpu->vm = vm; vcpu->guestfpu = fpu_save_area_alloc(); vcpu->stats = vmm_stat_alloc(); vcpu->tsc_offset = 0; } - vcpu->cookie = vmmops_vcpu_init(vm->cookie, vcpu_id); + vcpu->cookie = vmmops_vcpu_init(vm->cookie, vcpu, vcpu_id); vcpu->vlapic = vmmops_vlapic_init(vcpu->cookie); vm_set_x2apic_state(vm, vcpu_id, X2APIC_DISABLED); vcpu->reqidle = 0; @@ -2300,6 +2320,24 @@ vm_set_capability(struct vm *vm, int vcpu, int type, int val) return (vmmops_setcap(vcpu_cookie(vm, vcpu), type, val)); } +struct vm * +vcpu_vm(struct vcpu *vcpu) +{ + return (vcpu->vm); +} + +int +vcpu_vcpuid(struct vcpu *vcpu) +{ + return (vcpu->vcpuid); +} + +struct vcpu * +vm_vcpu(struct vm *vm, int vcpuid) +{ + return (&vm->vcpu[vcpuid]); +} + struct vlapic * vm_lapic(struct vm *vm, int cpu) {