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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user