diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2007-07-27 03:16:56 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-10-13 04:18:20 -0400 |
commit | fb3f0f51d92d1496f9628ca6f0fb06a48dc9ed2a (patch) | |
tree | 38da1073dae5f30fd8f162669bb5a86959f8ace5 /drivers/kvm/vmx.c | |
parent | a2fa3e9f52d875f7d4ca98434603b8756be71ba8 (diff) |
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 { | |||
39 | }; | 39 | }; |
40 | 40 | ||
41 | struct vcpu_vmx { | 41 | struct vcpu_vmx { |
42 | struct kvm_vcpu *vcpu; | 42 | struct kvm_vcpu vcpu; |
43 | int launched; | 43 | int launched; |
44 | struct kvm_msr_entry *guest_msrs; | 44 | struct kvm_msr_entry *guest_msrs; |
45 | struct kvm_msr_entry *host_msrs; | 45 | struct kvm_msr_entry *host_msrs; |
@@ -60,7 +60,7 @@ struct vcpu_vmx { | |||
60 | 60 | ||
61 | static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu) | 61 | static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu) |
62 | { | 62 | { |
63 | return (struct vcpu_vmx*)vcpu->_priv; | 63 | return container_of(vcpu, struct vcpu_vmx, vcpu); |
64 | } | 64 | } |
65 | 65 | ||
66 | static int init_rmode_tss(struct kvm *kvm); | 66 | static int init_rmode_tss(struct kvm *kvm); |
@@ -2302,46 +2302,62 @@ static void vmx_free_vmcs(struct kvm_vcpu *vcpu) | |||
2302 | 2302 | ||
2303 | static void vmx_free_vcpu(struct kvm_vcpu *vcpu) | 2303 | static void vmx_free_vcpu(struct kvm_vcpu *vcpu) |
2304 | { | 2304 | { |
2305 | struct vcpu_vmx *vmx = to_vmx(vcpu); | ||
2306 | |||
2305 | vmx_free_vmcs(vcpu); | 2307 | vmx_free_vmcs(vcpu); |
2308 | kfree(vmx->host_msrs); | ||
2309 | kfree(vmx->guest_msrs); | ||
2310 | kvm_vcpu_uninit(vcpu); | ||
2311 | kfree(vmx); | ||
2306 | } | 2312 | } |
2307 | 2313 | ||
2308 | static int vmx_create_vcpu(struct kvm_vcpu *vcpu) | 2314 | static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) |
2309 | { | 2315 | { |
2310 | struct vcpu_vmx *vmx; | 2316 | int err; |
2317 | struct vcpu_vmx *vmx = kzalloc(sizeof(*vmx), GFP_KERNEL); | ||
2311 | 2318 | ||
2312 | vmx = kzalloc(sizeof(*vmx), GFP_KERNEL); | ||
2313 | if (!vmx) | 2319 | if (!vmx) |
2314 | return -ENOMEM; | 2320 | return ERR_PTR(-ENOMEM); |
2321 | |||
2322 | err = kvm_vcpu_init(&vmx->vcpu, kvm, id); | ||
2323 | if (err) | ||
2324 | goto free_vcpu; | ||
2315 | 2325 | ||
2316 | vmx->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL); | 2326 | vmx->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL); |
2317 | if (!vmx->guest_msrs) | 2327 | if (!vmx->guest_msrs) { |
2318 | goto out_free; | 2328 | err = -ENOMEM; |
2329 | goto uninit_vcpu; | ||
2330 | } | ||
2319 | 2331 | ||
2320 | vmx->host_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL); | 2332 | vmx->host_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL); |
2321 | if (!vmx->host_msrs) | 2333 | if (!vmx->host_msrs) |
2322 | goto out_free; | 2334 | goto free_guest_msrs; |
2323 | 2335 | ||
2324 | vmx->vmcs = alloc_vmcs(); | 2336 | vmx->vmcs = alloc_vmcs(); |
2325 | if (!vmx->vmcs) | 2337 | if (!vmx->vmcs) |
2326 | goto out_free; | 2338 | goto free_msrs; |
2327 | 2339 | ||
2328 | vmcs_clear(vmx->vmcs); | 2340 | vmcs_clear(vmx->vmcs); |
2329 | 2341 | ||
2330 | vmx->vcpu = vcpu; | 2342 | vmx_vcpu_load(&vmx->vcpu); |
2331 | vcpu->_priv = vmx; | 2343 | err = vmx_vcpu_setup(&vmx->vcpu); |
2332 | 2344 | vmx_vcpu_put(&vmx->vcpu); | |
2333 | return 0; | 2345 | if (err) |
2334 | 2346 | goto free_vmcs; | |
2335 | out_free: | 2347 | |
2336 | if (vmx->host_msrs) | 2348 | return &vmx->vcpu; |
2337 | kfree(vmx->host_msrs); | 2349 | |
2338 | 2350 | free_vmcs: | |
2339 | if (vmx->guest_msrs) | 2351 | free_vmcs(vmx->vmcs); |
2340 | kfree(vmx->guest_msrs); | 2352 | free_msrs: |
2341 | 2353 | kfree(vmx->host_msrs); | |
2354 | free_guest_msrs: | ||
2355 | kfree(vmx->guest_msrs); | ||
2356 | uninit_vcpu: | ||
2357 | kvm_vcpu_uninit(&vmx->vcpu); | ||
2358 | free_vcpu: | ||
2342 | kfree(vmx); | 2359 | kfree(vmx); |
2343 | 2360 | return ERR_PTR(err); | |
2344 | return -ENOMEM; | ||
2345 | } | 2361 | } |
2346 | 2362 | ||
2347 | static struct kvm_arch_ops vmx_arch_ops = { | 2363 | static struct kvm_arch_ops vmx_arch_ops = { |
@@ -2389,7 +2405,6 @@ static struct kvm_arch_ops vmx_arch_ops = { | |||
2389 | 2405 | ||
2390 | .run = vmx_vcpu_run, | 2406 | .run = vmx_vcpu_run, |
2391 | .skip_emulated_instruction = skip_emulated_instruction, | 2407 | .skip_emulated_instruction = skip_emulated_instruction, |
2392 | .vcpu_setup = vmx_vcpu_setup, | ||
2393 | .patch_hypercall = vmx_patch_hypercall, | 2408 | .patch_hypercall = vmx_patch_hypercall, |
2394 | }; | 2409 | }; |
2395 | 2410 | ||