aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/kvm/i8259.c5
-rw-r--r--drivers/kvm/irq.h1
-rw-r--r--drivers/kvm/kvm_main.c82
3 files changed, 88 insertions, 0 deletions
diff --git a/drivers/kvm/i8259.c b/drivers/kvm/i8259.c
index ee6030dc5c04..a679157bc599 100644
--- a/drivers/kvm/i8259.c
+++ b/drivers/kvm/i8259.c
@@ -119,6 +119,11 @@ static void pic_update_irq(struct kvm_pic *s)
119 s->irq_request(s->irq_request_opaque, 0); 119 s->irq_request(s->irq_request_opaque, 0);
120} 120}
121 121
122void kvm_pic_update_irq(struct kvm_pic *s)
123{
124 pic_update_irq(s);
125}
126
122void kvm_pic_set_irq(void *opaque, int irq, int level) 127void kvm_pic_set_irq(void *opaque, int irq, int level)
123{ 128{
124 struct kvm_pic *s = opaque; 129 struct kvm_pic *s = opaque;
diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index 6ed856a41e23..4034f6576cd9 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -59,6 +59,7 @@ void kvm_pic_set_irq(void *opaque, int irq, int level);
59int kvm_pic_read_irq(struct kvm_pic *s); 59int kvm_pic_read_irq(struct kvm_pic *s);
60int kvm_cpu_get_interrupt(struct kvm_vcpu *v); 60int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
61int kvm_cpu_has_interrupt(struct kvm_vcpu *v); 61int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
62void kvm_pic_update_irq(struct kvm_pic *s);
62 63
63#define IOAPIC_NUM_PINS 24 64#define IOAPIC_NUM_PINS 24
64#define IOAPIC_VERSION_ID 0x11 /* IOAPIC version */ 65#define IOAPIC_VERSION_ID 0x11 /* IOAPIC version */
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 5063b3addbbf..6e2c5f3f33fb 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -897,6 +897,53 @@ out:
897 return r; 897 return r;
898} 898}
899 899
900static int kvm_vm_ioctl_get_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
901{
902 int r;
903
904 r = 0;
905 switch (chip->chip_id) {
906 case KVM_IRQCHIP_PIC_MASTER:
907 memcpy (&chip->chip.pic,
908 &pic_irqchip(kvm)->pics[0],
909 sizeof(struct kvm_pic_state));
910 break;
911 case KVM_IRQCHIP_PIC_SLAVE:
912 memcpy (&chip->chip.pic,
913 &pic_irqchip(kvm)->pics[1],
914 sizeof(struct kvm_pic_state));
915 break;
916 default:
917 r = -EINVAL;
918 break;
919 }
920 return r;
921}
922
923static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
924{
925 int r;
926
927 r = 0;
928 switch (chip->chip_id) {
929 case KVM_IRQCHIP_PIC_MASTER:
930 memcpy (&pic_irqchip(kvm)->pics[0],
931 &chip->chip.pic,
932 sizeof(struct kvm_pic_state));
933 break;
934 case KVM_IRQCHIP_PIC_SLAVE:
935 memcpy (&pic_irqchip(kvm)->pics[1],
936 &chip->chip.pic,
937 sizeof(struct kvm_pic_state));
938 break;
939 default:
940 r = -EINVAL;
941 break;
942 }
943 kvm_pic_update_irq(pic_irqchip(kvm));
944 return r;
945}
946
900static gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) 947static gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
901{ 948{
902 int i; 949 int i;
@@ -2835,6 +2882,41 @@ static long kvm_vm_ioctl(struct file *filp,
2835 } 2882 }
2836 break; 2883 break;
2837 } 2884 }
2885 case KVM_GET_IRQCHIP: {
2886 /* 0: PIC master, 1: PIC slave, 2: IOAPIC */
2887 struct kvm_irqchip chip;
2888
2889 r = -EFAULT;
2890 if (copy_from_user(&chip, argp, sizeof chip))
2891 goto out;
2892 r = -ENXIO;
2893 if (!irqchip_in_kernel(kvm))
2894 goto out;
2895 r = kvm_vm_ioctl_get_irqchip(kvm, &chip);
2896 if (r)
2897 goto out;
2898 r = -EFAULT;
2899 if (copy_to_user(argp, &chip, sizeof chip))
2900 goto out;
2901 r = 0;
2902 break;
2903 }
2904 case KVM_SET_IRQCHIP: {
2905 /* 0: PIC master, 1: PIC slave, 2: IOAPIC */
2906 struct kvm_irqchip chip;
2907
2908 r = -EFAULT;
2909 if (copy_from_user(&chip, argp, sizeof chip))
2910 goto out;
2911 r = -ENXIO;
2912 if (!irqchip_in_kernel(kvm))
2913 goto out;
2914 r = kvm_vm_ioctl_set_irqchip(kvm, &chip);
2915 if (r)
2916 goto out;
2917 r = 0;
2918 break;
2919 }
2838 default: 2920 default:
2839 ; 2921 ;
2840 } 2922 }