This patch adds support to migrate vcpu interrupts. Two new vcpu ioctls are added which get/set the complete status of pending interrupts in one go. The ioctls are marked as available with the new capability KVM_CAP_S390_IRQ_STATE. We can not use a ONEREG, as the number of pending local interrupts is not constant and depends on the number of CPUs. To retrieve the interrupt state we add an ioctl KVM_S390_GET_IRQ_STATE. Its input parameter is a pointer to a struct kvm_s390_irq_state which has a buffer and length. For all currently pending interrupts, we copy a struct kvm_s390_irq into the buffer and pass it to userspace. To store interrupt state into a buffer provided by userspace, we add an ioctl KVM_S390_SET_IRQ_STATE. It passes a struct kvm_s390_irq_state into the kernel and injects all interrupts contained in the buffer.
Unified · Split
| @@ -2875,6 +2875,67 @@ KVM_S390_MCHK - machine check interrupt; parameters in .mchk · 2874 unmodified lines | |||
| 2875 | 2875 | ||
| 2876 | Note that the vcpu ioctl is asynchronous to vcpu execution. | 2876 | Note that the vcpu ioctl is asynchronous to vcpu execution. |
| 2877 | 2877 | ||
| 2878 | 4.94 KVM_S390_GET_IRQ_STATE | ||
| 2879 | |||
| 2880 | Capability: KVM_CAP_S390_IRQ_STATE | ||
| 2881 | Architectures: s390 | ||
| 2882 | Type: vcpu ioctl | ||
| 2883 | Parameters: struct kvm_s390_irq_state (out) | ||
| 2884 | Returns: >= number of bytes copied into buffer, | ||
| 2885 | -EINVAL if buffer size is 0, | ||
| 2886 | -ENOBUFS if buffer size is too small to fit all pending interrupts, | ||
| 2887 | -EFAULT if the buffer address was invalid | ||
| 2888 | |||
| 2889 | This ioctl allows userspace to retrieve the complete state of all currently | ||
| 2890 | pending interrupts in a single buffer. Use cases include migration | ||
| 2891 | and introspection. The parameter structure contains the address of a | ||
| 2892 | userspace buffer and its length: | ||
| 2893 | |||
| 2894 | struct kvm_s390_irq_state { | ||
| 2895 | __u64 buf; | ||
| 2896 | __u32 flags; | ||
| 2897 | __u32 len; | ||
| 2898 | __u32 reserved[4]; | ||
| 2899 | }; | ||
| 2900 | |||
| 2901 | Userspace passes in the above struct and for each pending interrupt a | ||
| 2902 | struct kvm_s390_irq is copied to the provided buffer. | ||
| 2903 | |||
| 2904 | If -ENOBUFS is returned the buffer provided was too small and userspace | ||
| 2905 | may retry with a bigger buffer. | ||
| 2906 | |||
| 2907 | 4.95 KVM_S390_SET_IRQ_STATE | ||
| 2908 | |||
| 2909 | Capability: KVM_CAP_S390_IRQ_STATE | ||
| 2910 | Architectures: s390 | ||
| 2911 | Type: vcpu ioctl | ||
| 2912 | Parameters: struct kvm_s390_irq_state (in) | ||
| 2913 | Returns: 0 on success, | ||
| 2914 | -EFAULT if the buffer address was invalid, | ||
| 2915 | -EINVAL for an invalid buffer length (see below), | ||
| 2916 | -EBUSY if there were already interrupts pending, | ||
| 2917 | errors occurring when actually injecting the | ||
| 2918 | interrupt. See KVM_S390_IRQ. | ||
| 2919 | |||
| 2920 | This ioctl allows userspace to set the complete state of all cpu-local | ||
| 2921 | interrupts currently pending for the vcpu. It is intended for restoring | ||
| 2922 | interrupt state after a migration. The input parameter is a userspace buffer | ||
| 2923 | containing a struct kvm_s390_irq_state: | ||
| 2924 | |||
| 2925 | struct kvm_s390_irq_state { | ||
| 2926 | __u64 buf; | ||
| 2927 | __u32 len; | ||
| 2928 | __u32 pad; | ||
| 2929 | }; | ||
| 2930 | |||
| 2931 | The userspace memory referenced by buf contains a struct kvm_s390_irq | ||
| 2932 | for each interrupt to be injected into the guest. | ||
| 2933 | If one of the interrupts could not be injected for some reason the | ||
| 2934 | ioctl aborts. | ||
| 2935 | |||
| 2936 | len must be a multiple of sizeof(struct kvm_s390_irq). It must be > 0 | ||
| 2937 | and it must not exceed (max_vcpus + 32) * sizeof(struct kvm_s390_irq), | ||
| 2938 | which is the maximum number of possibly pending cpu-local interrupts. | ||
| 2878 | 2939 | ||
| 2879 | 5. The kvm_run structure | 2940 | 5. The kvm_run structure |
| 2880 | ------------------------ | 2941 | ------------------------ |
| @@ -2123,3 +2123,143 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm, · 2122 unmodified lines | |||
| 2123 | { | 2123 | { |
| 2124 | return -EINVAL; | 2124 | return -EINVAL; |
| 2125 | } | 2125 | } |
| 2126 | |||
| 2127 | int kvm_s390_set_irq_state(struct kvm_vcpu *vcpu, void __user *irqstate, int len) | ||
| 2128 | { | ||
| 2129 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
| 2130 | struct kvm_s390_irq *buf; | ||
| 2131 | int r = 0; | ||
| 2132 | int n; | ||
| 2133 | |||
| 2134 | buf = vmalloc(len); | ||
| 2135 | if (!buf) | ||
| 2136 | return -ENOMEM; | ||
| 2137 | |||
| 2138 | if (copy_from_user((void *) buf, irqstate, len)) { | ||
| 2139 | r = -EFAULT; | ||
| 2140 | goto out_free; | ||
| 2141 | } | ||
| 2142 | |||
| 2143 | /* | ||
| 2144 | * Don't allow setting the interrupt state | ||
| 2145 | * when there are already interrupts pending | ||
| 2146 | */ | ||
| 2147 | spin_lock(&li->lock); | ||
| 2148 | if (li->pending_irqs) { | ||
| 2149 | r = -EBUSY; | ||
| 2150 | goto out_unlock; | ||
| 2151 | } | ||
| 2152 | |||
| 2153 | for (n = 0; n < len / sizeof(*buf); n++) { | ||
| 2154 | r = do_inject_vcpu(vcpu, &buf[n]); | ||
| 2155 | if (r) | ||
| 2156 | break; | ||
| 2157 | } | ||
| 2158 | |||
| 2159 | out_unlock: | ||
| 2160 | spin_unlock(&li->lock); | ||
| 2161 | out_free: | ||
| 2162 | vfree(buf); | ||
| 2163 | |||
| 2164 | return r; | ||
| 2165 | } | ||
| 2166 | |||
| 2167 | static void store_local_irq(struct kvm_s390_local_interrupt *li, | ||
| 2168 | struct kvm_s390_irq *irq, | ||
| 2169 | unsigned long irq_type) | ||
| 2170 | { | ||
| 2171 | switch (irq_type) { | ||
| 2172 | case IRQ_PEND_MCHK_EX: | ||
| 2173 | case IRQ_PEND_MCHK_REP: | ||
| 2174 | irq->type = KVM_S390_MCHK; | ||
| 2175 | irq->u.mchk = li->irq.mchk; | ||
| 2176 | break; | ||
| 2177 | case IRQ_PEND_PROG: | ||
| 2178 | irq->type = KVM_S390_PROGRAM_INT; | ||
| 2179 | irq->u.pgm = li->irq.pgm; | ||
| 2180 | break; | ||
| 2181 | case IRQ_PEND_PFAULT_INIT: | ||
| 2182 | irq->type = KVM_S390_INT_PFAULT_INIT; | ||
| 2183 | irq->u.ext = li->irq.ext; | ||
| 2184 | break; | ||
| 2185 | case IRQ_PEND_EXT_EXTERNAL: | ||
| 2186 | irq->type = KVM_S390_INT_EXTERNAL_CALL; | ||
| 2187 | irq->u.extcall = li->irq.extcall; | ||
| 2188 | break; | ||
| 2189 | case IRQ_PEND_EXT_CLOCK_COMP: | ||
| 2190 | irq->type = KVM_S390_INT_CLOCK_COMP; | ||
| 2191 | break; | ||
| 2192 | case IRQ_PEND_EXT_CPU_TIMER: | ||
| 2193 | irq->type = KVM_S390_INT_CPU_TIMER; | ||
| 2194 | break; | ||
| 2195 | case IRQ_PEND_SIGP_STOP: | ||
| 2196 | irq->type = KVM_S390_SIGP_STOP; | ||
| 2197 | irq->u.stop = li->irq.stop; | ||
| 2198 | break; | ||
| 2199 | case IRQ_PEND_RESTART: | ||
| 2200 | irq->type = KVM_S390_RESTART; | ||
| 2201 | break; | ||
| 2202 | case IRQ_PEND_SET_PREFIX: | ||
| 2203 | irq->type = KVM_S390_SIGP_SET_PREFIX; | ||
| 2204 | irq->u.prefix = li->irq.prefix; | ||
| 2205 | break; | ||
| 2206 | } | ||
| 2207 | } | ||
| 2208 | |||
| 2209 | int kvm_s390_get_irq_state(struct kvm_vcpu *vcpu, __u8 __user *buf, int len) | ||
| 2210 | { | ||
| 2211 | uint8_t sigp_ctrl = vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].sigp_ctrl; | ||
| 2212 | unsigned long sigp_emerg_pending[BITS_TO_LONGS(KVM_MAX_VCPUS)]; | ||
| 2213 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
| 2214 | unsigned long pending_irqs; | ||
| 2215 | struct kvm_s390_irq irq; | ||
| 2216 | unsigned long irq_type; | ||
| 2217 | int cpuaddr; | ||
| 2218 | int n = 0; | ||
| 2219 | |||
| 2220 | spin_lock(&li->lock); | ||
| 2221 | pending_irqs = li->pending_irqs; | ||
| 2222 | memcpy(&sigp_emerg_pending, &li->sigp_emerg_pending, | ||
| 2223 | sizeof(sigp_emerg_pending)); | ||
| 2224 | spin_unlock(&li->lock); | ||
| 2225 | |||
| 2226 | for_each_set_bit(irq_type, &pending_irqs, IRQ_PEND_COUNT) { | ||
| 2227 | memset(&irq, 0, sizeof(irq)); | ||
| 2228 | if (irq_type == IRQ_PEND_EXT_EMERGENCY) | ||
| 2229 | continue; | ||
| 2230 | if (n + sizeof(irq) > len) | ||
| 2231 | return -ENOBUFS; | ||
| 2232 | store_local_irq(&vcpu->arch.local_int, &irq, irq_type); | ||
| 2233 | if (copy_to_user(&buf[n], &irq, sizeof(irq))) | ||
| 2234 | return -EFAULT; | ||
| 2235 | n += sizeof(irq); | ||
| 2236 | } | ||
| 2237 | |||
| 2238 | if (test_bit(IRQ_PEND_EXT_EMERGENCY, &pending_irqs)) { | ||
| 2239 | for_each_set_bit(cpuaddr, sigp_emerg_pending, KVM_MAX_VCPUS) { | ||
| 2240 | memset(&irq, 0, sizeof(irq)); | ||
| 2241 | if (n + sizeof(irq) > len) | ||
| 2242 | return -ENOBUFS; | ||
| 2243 | irq.type = KVM_S390_INT_EMERGENCY; | ||
| 2244 | irq.u.emerg.code = cpuaddr; | ||
| 2245 | if (copy_to_user(&buf[n], &irq, sizeof(irq))) | ||
| 2246 | return -EFAULT; | ||
| 2247 | n += sizeof(irq); | ||
| 2248 | } | ||
| 2249 | } | ||
| 2250 | |||
| 2251 | if ((sigp_ctrl & SIGP_CTRL_C) && | ||
| 2252 | (atomic_read(&vcpu->arch.sie_block->cpuflags) & | ||
| 2253 | CPUSTAT_ECALL_PEND)) { | ||
| 2254 | if (n + sizeof(irq) > len) | ||
| 2255 | return -ENOBUFS; | ||
| 2256 | memset(&irq, 0, sizeof(irq)); | ||
| 2257 | irq.type = KVM_S390_INT_EXTERNAL_CALL; | ||
| 2258 | irq.u.extcall.code = sigp_ctrl & SIGP_CTRL_SCN_MASK; | ||
| 2259 | if (copy_to_user(&buf[n], &irq, sizeof(irq))) | ||
| 2260 | return -EFAULT; | ||
| 2261 | n += sizeof(irq); | ||
| 2262 | } | ||
| 2263 | |||
| 2264 | return n; | ||
| 2265 | } | ||
| @@ -41,6 +41,9 @@ · 40 unmodified lines | |||
| 41 | #include "trace-s390.h" | 41 | #include "trace-s390.h" |
| 42 | 42 | ||
| 43 | #define MEM_OP_MAX_SIZE 65536 /* Maximum transfer size for KVM_S390_MEM_OP */ | 43 | #define MEM_OP_MAX_SIZE 65536 /* Maximum transfer size for KVM_S390_MEM_OP */ |
| 44 | #define LOCAL_IRQS 32 | ||
| 45 | #define VCPU_IRQS_MAX_BUF (sizeof(struct kvm_s390_irq) * \ | ||
| 46 | (KVM_MAX_VCPUS + LOCAL_IRQS)) | ||
| 44 | 47 | ||
| 45 | #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU | 48 | #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU |
| 46 | 49 | ||
| @@ -181,6 +184,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) · 134 unmodified lines | |||
| 181 | case KVM_CAP_S390_USER_SIGP: | 184 | case KVM_CAP_S390_USER_SIGP: |
| 182 | case KVM_CAP_S390_USER_STSI: | 185 | case KVM_CAP_S390_USER_STSI: |
| 183 | case KVM_CAP_S390_SKEYS: | 186 | case KVM_CAP_S390_SKEYS: |
| 187 | case KVM_CAP_S390_IRQ_STATE: | ||
| 184 | r = 1; | 188 | r = 1; |
| 185 | break; | 189 | break; |
| 186 | case KVM_CAP_S390_MEM_OP: | 190 | case KVM_CAP_S390_MEM_OP: |
| @@ -2500,6 +2504,38 @@ long kvm_arch_vcpu_ioctl(struct file *filp, · 2313 unmodified lines | |||
| 2500 | r = -EFAULT; | 2504 | r = -EFAULT; |
| 2501 | break; | 2505 | break; |
| 2502 | } | 2506 | } |
| 2507 | case KVM_S390_SET_IRQ_STATE: { | ||
| 2508 | struct kvm_s390_irq_state irq_state; | ||
| 2509 | |||
| 2510 | r = -EFAULT; | ||
| 2511 | if (copy_from_user(&irq_state, argp, sizeof(irq_state))) | ||
| 2512 | break; | ||
| 2513 | if (irq_state.len > VCPU_IRQS_MAX_BUF || | ||
| 2514 | irq_state.len == 0 || | ||
| 2515 | irq_state.len % sizeof(struct kvm_s390_irq) > 0) { | ||
| 2516 | r = -EINVAL; | ||
| 2517 | break; | ||
| 2518 | } | ||
| 2519 | r = kvm_s390_set_irq_state(vcpu, | ||
| 2520 | (void __user *) irq_state.buf, | ||
| 2521 | irq_state.len); | ||
| 2522 | break; | ||
| 2523 | } | ||
| 2524 | case KVM_S390_GET_IRQ_STATE: { | ||
| 2525 | struct kvm_s390_irq_state irq_state; | ||
| 2526 | |||
| 2527 | r = -EFAULT; | ||
| 2528 | if (copy_from_user(&irq_state, argp, sizeof(irq_state))) | ||
| 2529 | break; | ||
| 2530 | if (irq_state.len == 0) { | ||
| 2531 | r = -EINVAL; | ||
| 2532 | break; | ||
| 2533 | } | ||
| 2534 | r = kvm_s390_get_irq_state(vcpu, | ||
| 2535 | (__u8 __user *) irq_state.buf, | ||
| 2536 | irq_state.len); | ||
| 2537 | break; | ||
| 2538 | } | ||
| 2503 | default: | 2539 | default: |
| 2504 | r = -ENOTTY; | 2540 | r = -ENOTTY; |
| 2505 | } | 2541 | } |
| @@ -272,6 +272,10 @@ int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu); · 271 unmodified lines | |||
| 272 | extern struct kvm_device_ops kvm_flic_ops; | 272 | extern struct kvm_device_ops kvm_flic_ops; |
| 273 | int kvm_s390_is_stop_irq_pending(struct kvm_vcpu *vcpu); | 273 | int kvm_s390_is_stop_irq_pending(struct kvm_vcpu *vcpu); |
| 274 | void kvm_s390_clear_stop_irq(struct kvm_vcpu *vcpu); | 274 | void kvm_s390_clear_stop_irq(struct kvm_vcpu *vcpu); |
| 275 | int kvm_s390_set_irq_state(struct kvm_vcpu *vcpu, | ||
| 276 | void __user *buf, int len); | ||
| 277 | int kvm_s390_get_irq_state(struct kvm_vcpu *vcpu, | ||
| 278 | __u8 __user *buf, int len); | ||
| 275 | 279 | ||
| 276 | /* implemented in guestdbg.c */ | 280 | /* implemented in guestdbg.c */ |
| 277 | void kvm_s390_backup_guest_per_regs(struct kvm_vcpu *vcpu); | 281 | void kvm_s390_backup_guest_per_regs(struct kvm_vcpu *vcpu); |
| @@ -558,6 +558,13 @@ struct kvm_s390_irq { · 557 unmodified lines | |||
| 558 | } u; | 558 | } u; |
| 559 | }; | 559 | }; |
| 560 | 560 | ||
| 561 | struct kvm_s390_irq_state { | ||
| 562 | __u64 buf; | ||
| 563 | __u32 flags; | ||
| 564 | __u32 len; | ||
| 565 | __u32 reserved[4]; | ||
| 566 | }; | ||
| 567 | |||
| 561 | /* for KVM_SET_GUEST_DEBUG */ | 568 | /* for KVM_SET_GUEST_DEBUG */ |
| 562 | 569 | ||
| 563 | #define KVM_GUESTDBG_ENABLE 0x00000001 | 570 | #define KVM_GUESTDBG_ENABLE 0x00000001 |
| @@ -803,6 +810,7 @@ struct kvm_ppc_smmu_info { · 239 unmodified lines | |||
| 803 | #define KVM_CAP_S390_USER_STSI 109 | 810 | #define KVM_CAP_S390_USER_STSI 109 |
| 804 | #define KVM_CAP_S390_SKEYS 110 | 811 | #define KVM_CAP_S390_SKEYS 110 |
| 805 | #define KVM_CAP_S390_INJECT_IRQ 113 | 812 | #define KVM_CAP_S390_INJECT_IRQ 113 |
| 813 | #define KVM_CAP_S390_IRQ_STATE 114 | ||
| 806 | 814 | ||
| 807 | #ifdef KVM_CAP_IRQ_ROUTING | 815 | #ifdef KVM_CAP_IRQ_ROUTING |
| 808 | 816 | ||
| @@ -1185,6 +1193,9 @@ struct kvm_s390_ucas_mapping { · 376 unmodified lines | |||
| 1185 | #define KVM_S390_SET_SKEYS _IOW(KVMIO, 0xb3, struct kvm_s390_skeys) | 1193 | #define KVM_S390_SET_SKEYS _IOW(KVMIO, 0xb3, struct kvm_s390_skeys) |
| 1186 | /* Available with KVM_CAP_S390_INJECT_IRQ */ | 1194 | /* Available with KVM_CAP_S390_INJECT_IRQ */ |
| 1187 | #define KVM_S390_IRQ _IOW(KVMIO, 0xb4, struct kvm_s390_irq) | 1195 | #define KVM_S390_IRQ _IOW(KVMIO, 0xb4, struct kvm_s390_irq) |
| 1196 | /* Available with KVM_CAP_S390_IRQ_STATE */ | ||
| 1197 | #define KVM_S390_SET_IRQ_STATE _IOW(KVMIO, 0xb5, struct kvm_s390_irq_state) | ||
| 1198 | #define KVM_S390_GET_IRQ_STATE _IOW(KVMIO, 0xb6, struct kvm_s390_irq_state) | ||
| 1188 | 1199 | ||
| 1189 | #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) | 1200 | #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) |
| 1190 | #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) | 1201 | #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) |