git: 950af9ffc616 - main - vmm: Expose struct vcpu as an opaque type.

From: John Baldwin <jhb_at_FreeBSD.org>
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)
 {