diff options
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r-- | drivers/kvm/kvm_main.c | 82 |
1 files changed, 82 insertions, 0 deletions
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 | ||
900 | static 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 | |||
923 | static 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 | |||
900 | static gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) | 947 | static 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 | } |