diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2007-07-27 17:16:56 +1000 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-10-13 10:18:20 +0200 |
commit | fb3f0f51d92d1496f9628ca6f0fb06a48dc9ed2a (patch) | |
tree | 38da1073dae5f30fd8f162669bb5a86959f8ace5 /drivers/kvm/vmx.c | |
parent | a2fa3e9f52d875f7d4ca98434603b8756be71ba8 (diff) | |
download | lwn-fb3f0f51d92d1496f9628ca6f0fb06a48dc9ed2a.tar.gz lwn-fb3f0f51d92d1496f9628ca6f0fb06a48dc9ed2a.zip |
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>
Diffstat (limited to 'drivers/kvm/vmx.c')
-rw-r--r-- | drivers/kvm/vmx.c | 65 |
1 files changed, 40 insertions, 25 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index 96837d6ed50b..df5787823309 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c @@ -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; - - return 0; - -out_free: - if (vmx->host_msrs) - kfree(vmx->host_msrs); - - if (vmx->guest_msrs) - kfree(vmx->guest_msrs); - + vmx_vcpu_load(&vmx->vcpu); + err = vmx_vcpu_setup(&vmx->vcpu); + vmx_vcpu_put(&vmx->vcpu); + if (err) + goto free_vmcs; + + 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, }; |