KVM: Dynamically allocate vcpus
This patch converts the vcpus array in "struct kvm" to a pointer array, and changes the "vcpu_create" and "vcpu_setup" hooks into one "vcpu_create" call which does the allocation and initialization of the vcpu (calling back into the kvm_vcpu_init core helper). Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Avi Kivity <avi@qumranet.com>
This commit is contained in:

committed by
Avi Kivity

parent
a2fa3e9f52
commit
fb3f0f51d9
@@ -39,7 +39,7 @@ struct vmcs {
|
||||
};
|
||||
|
||||
struct vcpu_vmx {
|
||||
struct kvm_vcpu *vcpu;
|
||||
struct kvm_vcpu vcpu;
|
||||
int launched;
|
||||
struct kvm_msr_entry *guest_msrs;
|
||||
struct kvm_msr_entry *host_msrs;
|
||||
@@ -60,7 +60,7 @@ struct vcpu_vmx {
|
||||
|
||||
static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return (struct vcpu_vmx*)vcpu->_priv;
|
||||
return container_of(vcpu, struct vcpu_vmx, vcpu);
|
||||
}
|
||||
|
||||
static int init_rmode_tss(struct kvm *kvm);
|
||||
@@ -2302,46 +2302,62 @@ static void vmx_free_vmcs(struct kvm_vcpu *vcpu)
|
||||
|
||||
static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
|
||||
vmx_free_vmcs(vcpu);
|
||||
kfree(vmx->host_msrs);
|
||||
kfree(vmx->guest_msrs);
|
||||
kvm_vcpu_uninit(vcpu);
|
||||
kfree(vmx);
|
||||
}
|
||||
|
||||
static int vmx_create_vcpu(struct kvm_vcpu *vcpu)
|
||||
static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
|
||||
{
|
||||
struct vcpu_vmx *vmx;
|
||||
int err;
|
||||
struct vcpu_vmx *vmx = kzalloc(sizeof(*vmx), GFP_KERNEL);
|
||||
|
||||
vmx = kzalloc(sizeof(*vmx), GFP_KERNEL);
|
||||
if (!vmx)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
err = kvm_vcpu_init(&vmx->vcpu, kvm, id);
|
||||
if (err)
|
||||
goto free_vcpu;
|
||||
|
||||
vmx->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!vmx->guest_msrs)
|
||||
goto out_free;
|
||||
if (!vmx->guest_msrs) {
|
||||
err = -ENOMEM;
|
||||
goto uninit_vcpu;
|
||||
}
|
||||
|
||||
vmx->host_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!vmx->host_msrs)
|
||||
goto out_free;
|
||||
goto free_guest_msrs;
|
||||
|
||||
vmx->vmcs = alloc_vmcs();
|
||||
if (!vmx->vmcs)
|
||||
goto out_free;
|
||||
goto free_msrs;
|
||||
|
||||
vmcs_clear(vmx->vmcs);
|
||||
|
||||
vmx->vcpu = vcpu;
|
||||
vcpu->_priv = vmx;
|
||||
vmx_vcpu_load(&vmx->vcpu);
|
||||
err = vmx_vcpu_setup(&vmx->vcpu);
|
||||
vmx_vcpu_put(&vmx->vcpu);
|
||||
if (err)
|
||||
goto free_vmcs;
|
||||
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
if (vmx->host_msrs)
|
||||
kfree(vmx->host_msrs);
|
||||
|
||||
if (vmx->guest_msrs)
|
||||
kfree(vmx->guest_msrs);
|
||||
return &vmx->vcpu;
|
||||
|
||||
free_vmcs:
|
||||
free_vmcs(vmx->vmcs);
|
||||
free_msrs:
|
||||
kfree(vmx->host_msrs);
|
||||
free_guest_msrs:
|
||||
kfree(vmx->guest_msrs);
|
||||
uninit_vcpu:
|
||||
kvm_vcpu_uninit(&vmx->vcpu);
|
||||
free_vcpu:
|
||||
kfree(vmx);
|
||||
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static struct kvm_arch_ops vmx_arch_ops = {
|
||||
@@ -2389,7 +2405,6 @@ static struct kvm_arch_ops vmx_arch_ops = {
|
||||
|
||||
.run = vmx_vcpu_run,
|
||||
.skip_emulated_instruction = skip_emulated_instruction,
|
||||
.vcpu_setup = vmx_vcpu_setup,
|
||||
.patch_hypercall = vmx_patch_hypercall,
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user