diff options
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r-- | drivers/kvm/kvm_main.c | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index d154487b7729..09a04bc9541d 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "kvm.h" | 18 | #include "kvm.h" |
19 | #include "x86_emulate.h" | 19 | #include "x86_emulate.h" |
20 | #include "segment_descriptor.h" | 20 | #include "segment_descriptor.h" |
21 | #include "irq.h" | ||
21 | 22 | ||
22 | #include <linux/kvm.h> | 23 | #include <linux/kvm.h> |
23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
@@ -378,6 +379,7 @@ static void kvm_destroy_vm(struct kvm *kvm) | |||
378 | spin_unlock(&kvm_lock); | 379 | spin_unlock(&kvm_lock); |
379 | kvm_io_bus_destroy(&kvm->pio_bus); | 380 | kvm_io_bus_destroy(&kvm->pio_bus); |
380 | kvm_io_bus_destroy(&kvm->mmio_bus); | 381 | kvm_io_bus_destroy(&kvm->mmio_bus); |
382 | kfree(kvm->vpic); | ||
381 | kvm_free_vcpus(kvm); | 383 | kvm_free_vcpus(kvm); |
382 | kvm_free_physmem(kvm); | 384 | kvm_free_physmem(kvm); |
383 | kfree(kvm); | 385 | kfree(kvm); |
@@ -1258,7 +1260,8 @@ EXPORT_SYMBOL_GPL(emulate_instruction); | |||
1258 | 1260 | ||
1259 | int kvm_emulate_halt(struct kvm_vcpu *vcpu) | 1261 | int kvm_emulate_halt(struct kvm_vcpu *vcpu) |
1260 | { | 1262 | { |
1261 | if (vcpu->irq_summary) | 1263 | if (vcpu->irq_summary || |
1264 | (irqchip_in_kernel(vcpu->kvm) && kvm_cpu_has_interrupt(vcpu))) | ||
1262 | return 1; | 1265 | return 1; |
1263 | 1266 | ||
1264 | vcpu->run->exit_reason = KVM_EXIT_HLT; | 1267 | vcpu->run->exit_reason = KVM_EXIT_HLT; |
@@ -2715,6 +2718,30 @@ static long kvm_vm_ioctl(struct file *filp, | |||
2715 | goto out; | 2718 | goto out; |
2716 | break; | 2719 | break; |
2717 | } | 2720 | } |
2721 | case KVM_CREATE_IRQCHIP: | ||
2722 | r = -ENOMEM; | ||
2723 | kvm->vpic = kvm_create_pic(kvm); | ||
2724 | if (kvm->vpic) | ||
2725 | r = 0; | ||
2726 | else | ||
2727 | goto out; | ||
2728 | break; | ||
2729 | case KVM_IRQ_LINE: { | ||
2730 | struct kvm_irq_level irq_event; | ||
2731 | |||
2732 | r = -EFAULT; | ||
2733 | if (copy_from_user(&irq_event, argp, sizeof irq_event)) | ||
2734 | goto out; | ||
2735 | if (irqchip_in_kernel(kvm)) { | ||
2736 | if (irq_event.irq < 16) | ||
2737 | kvm_pic_set_irq(pic_irqchip(kvm), | ||
2738 | irq_event.irq, | ||
2739 | irq_event.level); | ||
2740 | /* TODO: IOAPIC */ | ||
2741 | r = 0; | ||
2742 | } | ||
2743 | break; | ||
2744 | } | ||
2718 | default: | 2745 | default: |
2719 | ; | 2746 | ; |
2720 | } | 2747 | } |
@@ -2825,12 +2852,19 @@ static long kvm_dev_ioctl(struct file *filp, | |||
2825 | r = 0; | 2852 | r = 0; |
2826 | break; | 2853 | break; |
2827 | } | 2854 | } |
2828 | case KVM_CHECK_EXTENSION: | 2855 | case KVM_CHECK_EXTENSION: { |
2829 | /* | 2856 | int ext = (long)argp; |
2830 | * No extensions defined at present. | 2857 | |
2831 | */ | 2858 | switch (ext) { |
2832 | r = 0; | 2859 | case KVM_CAP_IRQCHIP: |
2860 | r = 1; | ||
2861 | break; | ||
2862 | default: | ||
2863 | r = 0; | ||
2864 | break; | ||
2865 | } | ||
2833 | break; | 2866 | break; |
2867 | } | ||
2834 | case KVM_GET_VCPU_MMAP_SIZE: | 2868 | case KVM_GET_VCPU_MMAP_SIZE: |
2835 | r = -EINVAL; | 2869 | r = -EINVAL; |
2836 | if (arg) | 2870 | if (arg) |