aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/x86.c
diff options
context:
space:
mode:
authorZhang Xiantao <xiantao.zhang@intel.com>2007-11-14 07:38:21 -0500
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:53:02 -0500
commite9b11c17552afe684e9e5d0444309a3ddf410116 (patch)
treef0905a61791645dbede13cbdf017ea458ffa54c5 /drivers/kvm/x86.c
parent97896d04a14669b146c17d779b81ec7a339deeb3 (diff)
KVM: Portability: Add vcpu and hardware management arch hooks
Add the following hooks: void decache_vcpus_on_cpu(int cpu); int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu); void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu); void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu); void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu); void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu); struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id); void kvm_arch_vcpu_destory(struct kvm_vcpu *vcpu); int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu); void kvm_arch_hardware_enable(void *garbage); void kvm_arch_hardware_disable(void *garbage); int kvm_arch_hardware_setup(void); void kvm_arch_hardware_unsetup(void); void kvm_arch_check_processor_compat(void *rtn); Signed-off-by: Zhang Xiantao <xiantao.zhang@intel.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/x86.c')
-rw-r--r--drivers/kvm/x86.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c
index 2edc53ec8b3..4902b35060f 100644
--- a/drivers/kvm/x86.c
+++ b/drivers/kvm/x86.c
@@ -564,6 +564,41 @@ out:
564 return r; 564 return r;
565} 565}
566 566
567/*
568 * Make sure that a cpu that is being hot-unplugged does not have any vcpus
569 * cached on it.
570 */
571void decache_vcpus_on_cpu(int cpu)
572{
573 struct kvm *vm;
574 struct kvm_vcpu *vcpu;
575 int i;
576
577 spin_lock(&kvm_lock);
578 list_for_each_entry(vm, &vm_list, vm_list)
579 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
580 vcpu = vm->vcpus[i];
581 if (!vcpu)
582 continue;
583 /*
584 * If the vcpu is locked, then it is running on some
585 * other cpu and therefore it is not cached on the
586 * cpu in question.
587 *
588 * If it's not locked, check the last cpu it executed
589 * on.
590 */
591 if (mutex_trylock(&vcpu->mutex)) {
592 if (vcpu->cpu == cpu) {
593 kvm_x86_ops->vcpu_decache(vcpu);
594 vcpu->cpu = -1;
595 }
596 mutex_unlock(&vcpu->mutex);
597 }
598 }
599 spin_unlock(&kvm_lock);
600}
601
567long kvm_arch_dev_ioctl(struct file *filp, 602long kvm_arch_dev_ioctl(struct file *filp,
568 unsigned int ioctl, unsigned long arg) 603 unsigned int ioctl, unsigned long arg)
569{ 604{
@@ -2319,3 +2354,125 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
2319 fx_restore(&vcpu->host_fx_image); 2354 fx_restore(&vcpu->host_fx_image);
2320} 2355}
2321EXPORT_SYMBOL_GPL(kvm_put_guest_fpu); 2356EXPORT_SYMBOL_GPL(kvm_put_guest_fpu);
2357
2358void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
2359{
2360 kvm_x86_ops->vcpu_free(vcpu);
2361}
2362
2363struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
2364 unsigned int id)
2365{
2366 int r;
2367 struct kvm_vcpu *vcpu = kvm_x86_ops->vcpu_create(kvm, id);
2368
2369 if (IS_ERR(vcpu)) {
2370 r = -ENOMEM;
2371 goto fail;
2372 }
2373
2374 /* We do fxsave: this must be aligned. */
2375 BUG_ON((unsigned long)&vcpu->host_fx_image & 0xF);
2376
2377 vcpu_load(vcpu);
2378 r = kvm_arch_vcpu_reset(vcpu);
2379 if (r == 0)
2380 r = kvm_mmu_setup(vcpu);
2381 vcpu_put(vcpu);
2382 if (r < 0)
2383 goto free_vcpu;
2384
2385 return vcpu;
2386free_vcpu:
2387 kvm_x86_ops->vcpu_free(vcpu);
2388fail:
2389 return ERR_PTR(r);
2390}
2391
2392void kvm_arch_vcpu_destory(struct kvm_vcpu *vcpu)
2393{
2394 vcpu_load(vcpu);
2395 kvm_mmu_unload(vcpu);
2396 vcpu_put(vcpu);
2397
2398 kvm_x86_ops->vcpu_free(vcpu);
2399}
2400
2401int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu)
2402{
2403 return kvm_x86_ops->vcpu_reset(vcpu);
2404}
2405
2406void kvm_arch_hardware_enable(void *garbage)
2407{
2408 kvm_x86_ops->hardware_enable(garbage);
2409}
2410
2411void kvm_arch_hardware_disable(void *garbage)
2412{
2413 kvm_x86_ops->hardware_disable(garbage);
2414}
2415
2416int kvm_arch_hardware_setup(void)
2417{
2418 return kvm_x86_ops->hardware_setup();
2419}
2420
2421void kvm_arch_hardware_unsetup(void)
2422{
2423 kvm_x86_ops->hardware_unsetup();
2424}
2425
2426void kvm_arch_check_processor_compat(void *rtn)
2427{
2428 kvm_x86_ops->check_processor_compatibility(rtn);
2429}
2430
2431int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
2432{
2433 struct page *page;
2434 struct kvm *kvm;
2435 int r;
2436
2437 BUG_ON(vcpu->kvm == NULL);
2438 kvm = vcpu->kvm;
2439
2440 vcpu->mmu.root_hpa = INVALID_PAGE;
2441 if (!irqchip_in_kernel(kvm) || vcpu->vcpu_id == 0)
2442 vcpu->mp_state = VCPU_MP_STATE_RUNNABLE;
2443 else
2444 vcpu->mp_state = VCPU_MP_STATE_UNINITIALIZED;
2445
2446 page = alloc_page(GFP_KERNEL | __GFP_ZERO);
2447 if (!page) {
2448 r = -ENOMEM;
2449 goto fail;
2450 }
2451 vcpu->pio_data = page_address(page);
2452
2453 r = kvm_mmu_create(vcpu);
2454 if (r < 0)
2455 goto fail_free_pio_data;
2456
2457 if (irqchip_in_kernel(kvm)) {
2458 r = kvm_create_lapic(vcpu);
2459 if (r < 0)
2460 goto fail_mmu_destroy;
2461 }
2462
2463 return 0;
2464
2465fail_mmu_destroy:
2466 kvm_mmu_destroy(vcpu);
2467fail_free_pio_data:
2468 free_page((unsigned long)vcpu->pio_data);
2469fail:
2470 return r;
2471}
2472
2473void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
2474{
2475 kvm_free_lapic(vcpu);
2476 kvm_mmu_destroy(vcpu);
2477 free_page((unsigned long)vcpu->pio_data);
2478}