aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/kvm_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r--drivers/kvm/kvm_main.c46
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
1259int kvm_emulate_halt(struct kvm_vcpu *vcpu) 1261int 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)