diff options
author | He, Qing <qing.he@intel.com> | 2007-07-26 04:05:18 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-10-13 04:18:25 -0400 |
commit | 6ceb9d791eeeb0a5493958f5d6d4dc7d91e59cf7 (patch) | |
tree | 8cef21acf9346fdbea36075029dc007fe969b51e /drivers | |
parent | 9cf98828d12285d1fb43e774c8c100a55f8f34e1 (diff) |
KVM: Add get/set irqchip ioctls for in-kernel PIC live migration support
This patch adds two new ioctls to dump and write kernel irqchips for
save/restore and live migration. PIC s/r and l/m is implemented in this
patch.
Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: Qing He <qing.he@intel.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/kvm/i8259.c | 5 | ||||
-rw-r--r-- | drivers/kvm/irq.h | 1 | ||||
-rw-r--r-- | drivers/kvm/kvm_main.c | 82 |
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 | ||
122 | void kvm_pic_update_irq(struct kvm_pic *s) | ||
123 | { | ||
124 | pic_update_irq(s); | ||
125 | } | ||
126 | |||
122 | void kvm_pic_set_irq(void *opaque, int irq, int level) | 127 | void 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); | |||
59 | int kvm_pic_read_irq(struct kvm_pic *s); | 59 | int kvm_pic_read_irq(struct kvm_pic *s); |
60 | int kvm_cpu_get_interrupt(struct kvm_vcpu *v); | 60 | int kvm_cpu_get_interrupt(struct kvm_vcpu *v); |
61 | int kvm_cpu_has_interrupt(struct kvm_vcpu *v); | 61 | int kvm_cpu_has_interrupt(struct kvm_vcpu *v); |
62 | void 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 | ||
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 | } |