summaryrefslogtreecommitdiff
path: root/drivers/kvm/vmx.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2007-07-27 17:16:56 +1000
committerAvi Kivity <avi@qumranet.com>2007-10-13 10:18:20 +0200
commitfb3f0f51d92d1496f9628ca6f0fb06a48dc9ed2a (patch)
tree38da1073dae5f30fd8f162669bb5a86959f8ace5 /drivers/kvm/vmx.c
parenta2fa3e9f52d875f7d4ca98434603b8756be71ba8 (diff)
downloadlwn-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.c65
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,
};