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
This commit is contained in:
John Baldwin
2022-11-18 10:01:05 -08:00
parent d030f941e6
commit 950af9ffc6
7 changed files with 56 additions and 5 deletions
+6 -1
View File
@@ -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);
+3 -1
View File
@@ -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);
+1
View File
@@ -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 */
+3 -1
View File
@@ -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;
+1
View File
@@ -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;
+2
View File
@@ -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;
+40 -2
View File
@@ -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)
{