Commit | Line | Data |
---|---|---|
5288fbf0 | 1 | /* |
a53c8fab | 2 | * handling interprocessor communication |
5288fbf0 | 3 | * |
b13d3580 | 4 | * Copyright IBM Corp. 2008, 2013 |
5288fbf0 CB |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License (version 2 only) | |
8 | * as published by the Free Software Foundation. | |
9 | * | |
10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | |
11 | * Christian Borntraeger <borntraeger@de.ibm.com> | |
9ace903d | 12 | * Christian Ehrhardt <ehrhardt@de.ibm.com> |
5288fbf0 CB |
13 | */ |
14 | ||
15 | #include <linux/kvm.h> | |
16 | #include <linux/kvm_host.h> | |
5a0e3ad6 | 17 | #include <linux/slab.h> |
a9ae32c3 | 18 | #include <asm/sigp.h> |
5288fbf0 CB |
19 | #include "gaccess.h" |
20 | #include "kvm-s390.h" | |
5786fffa | 21 | #include "trace.h" |
5288fbf0 | 22 | |
3d95c7d2 | 23 | static int __sigp_sense(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu, |
5a32c1af | 24 | u64 *reg) |
5288fbf0 | 25 | { |
1ee0bc55 | 26 | struct kvm_s390_local_interrupt *li; |
1ee0bc55 | 27 | int cpuflags; |
5288fbf0 CB |
28 | int rc; |
29 | ||
1ee0bc55 JF |
30 | li = &dst_vcpu->arch.local_int; |
31 | ||
32 | cpuflags = atomic_read(li->cpuflags); | |
33 | if (!(cpuflags & (CPUSTAT_ECALL_PEND | CPUSTAT_STOPPED))) | |
21b26c08 CH |
34 | rc = SIGP_CC_ORDER_CODE_ACCEPTED; |
35 | else { | |
5288fbf0 | 36 | *reg &= 0xffffffff00000000UL; |
1ee0bc55 | 37 | if (cpuflags & CPUSTAT_ECALL_PEND) |
21b26c08 | 38 | *reg |= SIGP_STATUS_EXT_CALL_PENDING; |
1ee0bc55 | 39 | if (cpuflags & CPUSTAT_STOPPED) |
21b26c08 | 40 | *reg |= SIGP_STATUS_STOPPED; |
ea1918dd | 41 | rc = SIGP_CC_STATUS_STORED; |
5288fbf0 | 42 | } |
5288fbf0 | 43 | |
3d95c7d2 DH |
44 | VCPU_EVENT(vcpu, 4, "sensed status of cpu %x rc %x", dst_vcpu->vcpu_id, |
45 | rc); | |
5288fbf0 CB |
46 | return rc; |
47 | } | |
48 | ||
07b03035 DH |
49 | static int __inject_sigp_emergency(struct kvm_vcpu *vcpu, |
50 | struct kvm_vcpu *dst_vcpu) | |
5288fbf0 | 51 | { |
383d0b05 | 52 | struct kvm_s390_irq irq = { |
22ff4a33 | 53 | .type = KVM_S390_INT_EMERGENCY, |
383d0b05 | 54 | .u.emerg.code = vcpu->vcpu_id, |
22ff4a33 | 55 | }; |
22ff4a33 | 56 | int rc = 0; |
5288fbf0 | 57 | |
383d0b05 | 58 | rc = kvm_s390_inject_vcpu(dst_vcpu, &irq); |
22ff4a33 | 59 | if (!rc) |
3d95c7d2 DH |
60 | VCPU_EVENT(vcpu, 4, "sent sigp emerg to cpu %x", |
61 | dst_vcpu->vcpu_id); | |
5288fbf0 | 62 | |
22ff4a33 | 63 | return rc ? rc : SIGP_CC_ORDER_CODE_ACCEPTED; |
7697e71f CE |
64 | } |
65 | ||
07b03035 DH |
66 | static int __sigp_emergency(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu) |
67 | { | |
68 | return __inject_sigp_emergency(vcpu, dst_vcpu); | |
69 | } | |
70 | ||
3d95c7d2 DH |
71 | static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, |
72 | struct kvm_vcpu *dst_vcpu, | |
b13d3580 TH |
73 | u16 asn, u64 *reg) |
74 | { | |
b13d3580 TH |
75 | const u64 psw_int_mask = PSW_MASK_IO | PSW_MASK_EXT; |
76 | u16 p_asn, s_asn; | |
77 | psw_t *psw; | |
78 | u32 flags; | |
79 | ||
b13d3580 TH |
80 | flags = atomic_read(&dst_vcpu->arch.sie_block->cpuflags); |
81 | psw = &dst_vcpu->arch.sie_block->gpsw; | |
82 | p_asn = dst_vcpu->arch.sie_block->gcr[4] & 0xffff; /* Primary ASN */ | |
83 | s_asn = dst_vcpu->arch.sie_block->gcr[3] & 0xffff; /* Secondary ASN */ | |
84 | ||
07b03035 | 85 | /* Inject the emergency signal? */ |
b13d3580 TH |
86 | if (!(flags & CPUSTAT_STOPPED) |
87 | || (psw->mask & psw_int_mask) != psw_int_mask | |
88 | || ((flags & CPUSTAT_WAIT) && psw->addr != 0) | |
89 | || (!(flags & CPUSTAT_WAIT) && (asn == p_asn || asn == s_asn))) { | |
07b03035 | 90 | return __inject_sigp_emergency(vcpu, dst_vcpu); |
b13d3580 TH |
91 | } else { |
92 | *reg &= 0xffffffff00000000UL; | |
93 | *reg |= SIGP_STATUS_INCORRECT_STATE; | |
94 | return SIGP_CC_STATUS_STORED; | |
95 | } | |
96 | } | |
97 | ||
3d95c7d2 DH |
98 | static int __sigp_external_call(struct kvm_vcpu *vcpu, |
99 | struct kvm_vcpu *dst_vcpu) | |
7697e71f | 100 | { |
383d0b05 | 101 | struct kvm_s390_irq irq = { |
22ff4a33 | 102 | .type = KVM_S390_INT_EXTERNAL_CALL, |
383d0b05 | 103 | .u.extcall.code = vcpu->vcpu_id, |
22ff4a33 | 104 | }; |
22ff4a33 | 105 | int rc; |
7697e71f | 106 | |
383d0b05 | 107 | rc = kvm_s390_inject_vcpu(dst_vcpu, &irq); |
22ff4a33 | 108 | if (!rc) |
3d95c7d2 DH |
109 | VCPU_EVENT(vcpu, 4, "sent sigp ext call to cpu %x", |
110 | dst_vcpu->vcpu_id); | |
7697e71f | 111 | |
22ff4a33 | 112 | return rc ? rc : SIGP_CC_ORDER_CODE_ACCEPTED; |
5288fbf0 CB |
113 | } |
114 | ||
a6cc3108 | 115 | static int __sigp_stop(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu) |
9ace903d | 116 | { |
6cddd432 DH |
117 | struct kvm_s390_irq irq = { |
118 | .type = KVM_S390_SIGP_STOP, | |
119 | }; | |
9ace903d CE |
120 | int rc; |
121 | ||
6cddd432 DH |
122 | rc = kvm_s390_inject_vcpu(dst_vcpu, &irq); |
123 | if (rc == -EBUSY) | |
124 | rc = SIGP_CC_BUSY; | |
125 | else if (rc == 0) | |
126 | VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", | |
127 | dst_vcpu->vcpu_id); | |
e879892c | 128 | |
a6cc3108 DH |
129 | return rc; |
130 | } | |
131 | ||
132 | static int __sigp_stop_and_store_status(struct kvm_vcpu *vcpu, | |
133 | struct kvm_vcpu *dst_vcpu, u64 *reg) | |
134 | { | |
6cddd432 DH |
135 | struct kvm_s390_irq irq = { |
136 | .type = KVM_S390_SIGP_STOP, | |
137 | .u.stop.flags = KVM_S390_STOP_FLAG_STORE_STATUS, | |
138 | }; | |
a6cc3108 DH |
139 | int rc; |
140 | ||
6cddd432 DH |
141 | rc = kvm_s390_inject_vcpu(dst_vcpu, &irq); |
142 | if (rc == -EBUSY) | |
143 | rc = SIGP_CC_BUSY; | |
144 | else if (rc == 0) | |
145 | VCPU_EVENT(vcpu, 4, "sent sigp stop and store status to cpu %x", | |
146 | dst_vcpu->vcpu_id); | |
e879892c | 147 | |
5288fbf0 CB |
148 | return rc; |
149 | } | |
150 | ||
151 | static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) | |
152 | { | |
153 | int rc; | |
3c038e6b DD |
154 | unsigned int i; |
155 | struct kvm_vcpu *v; | |
5288fbf0 CB |
156 | |
157 | switch (parameter & 0xff) { | |
158 | case 0: | |
ea1918dd | 159 | rc = SIGP_CC_NOT_OPERATIONAL; |
5288fbf0 CB |
160 | break; |
161 | case 1: | |
162 | case 2: | |
3c038e6b DD |
163 | kvm_for_each_vcpu(i, v, vcpu->kvm) { |
164 | v->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID; | |
165 | kvm_clear_async_pf_completion_queue(v); | |
166 | } | |
167 | ||
ea1918dd | 168 | rc = SIGP_CC_ORDER_CODE_ACCEPTED; |
5288fbf0 CB |
169 | break; |
170 | default: | |
b8e660b8 | 171 | rc = -EOPNOTSUPP; |
5288fbf0 CB |
172 | } |
173 | return rc; | |
174 | } | |
175 | ||
3d95c7d2 DH |
176 | static int __sigp_set_prefix(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu, |
177 | u32 address, u64 *reg) | |
5288fbf0 | 178 | { |
a3a9c59a DH |
179 | struct kvm_s390_irq irq = { |
180 | .type = KVM_S390_SIGP_SET_PREFIX, | |
181 | .u.prefix.address = address & 0x7fffe000u, | |
182 | }; | |
5288fbf0 | 183 | int rc; |
5288fbf0 | 184 | |
665170cb HC |
185 | /* |
186 | * Make sure the new value is valid memory. We only need to check the | |
187 | * first page, since address is 8k aligned and memory pieces are always | |
188 | * at least 1MB aligned and have at least a size of 1MB. | |
189 | */ | |
a3a9c59a | 190 | if (kvm_is_error_gpa(vcpu->kvm, irq.u.prefix.address)) { |
0744426e | 191 | *reg &= 0xffffffff00000000UL; |
a9ae32c3 | 192 | *reg |= SIGP_STATUS_INVALID_PARAMETER; |
ea1918dd | 193 | return SIGP_CC_STATUS_STORED; |
5288fbf0 CB |
194 | } |
195 | ||
a3a9c59a DH |
196 | rc = kvm_s390_inject_vcpu(dst_vcpu, &irq); |
197 | if (rc == -EBUSY) { | |
0744426e HC |
198 | *reg &= 0xffffffff00000000UL; |
199 | *reg |= SIGP_STATUS_INCORRECT_STATE; | |
a3a9c59a DH |
200 | return SIGP_CC_STATUS_STORED; |
201 | } else if (rc == 0) { | |
202 | VCPU_EVENT(vcpu, 4, "set prefix of cpu %02x to %x", | |
203 | dst_vcpu->vcpu_id, irq.u.prefix.address); | |
5288fbf0 CB |
204 | } |
205 | ||
5288fbf0 CB |
206 | return rc; |
207 | } | |
208 | ||
3d95c7d2 DH |
209 | static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu, |
210 | struct kvm_vcpu *dst_vcpu, | |
211 | u32 addr, u64 *reg) | |
00e9e435 | 212 | { |
00e9e435 TH |
213 | int flags; |
214 | int rc; | |
215 | ||
00e9e435 | 216 | flags = atomic_read(dst_vcpu->arch.local_int.cpuflags); |
00e9e435 TH |
217 | if (!(flags & CPUSTAT_STOPPED)) { |
218 | *reg &= 0xffffffff00000000UL; | |
219 | *reg |= SIGP_STATUS_INCORRECT_STATE; | |
220 | return SIGP_CC_STATUS_STORED; | |
221 | } | |
222 | ||
223 | addr &= 0x7ffffe00; | |
224 | rc = kvm_s390_store_status_unloaded(dst_vcpu, addr); | |
225 | if (rc == -EFAULT) { | |
226 | *reg &= 0xffffffff00000000UL; | |
227 | *reg |= SIGP_STATUS_INVALID_PARAMETER; | |
228 | rc = SIGP_CC_STATUS_STORED; | |
229 | } | |
230 | return rc; | |
231 | } | |
232 | ||
3d95c7d2 DH |
233 | static int __sigp_sense_running(struct kvm_vcpu *vcpu, |
234 | struct kvm_vcpu *dst_vcpu, u64 *reg) | |
bd59d3a4 | 235 | { |
1ee0bc55 | 236 | struct kvm_s390_local_interrupt *li; |
bd59d3a4 | 237 | int rc; |
bd59d3a4 | 238 | |
1ee0bc55 JF |
239 | li = &dst_vcpu->arch.local_int; |
240 | if (atomic_read(li->cpuflags) & CPUSTAT_RUNNING) { | |
241 | /* running */ | |
242 | rc = SIGP_CC_ORDER_CODE_ACCEPTED; | |
243 | } else { | |
244 | /* not running */ | |
245 | *reg &= 0xffffffff00000000UL; | |
246 | *reg |= SIGP_STATUS_NOT_RUNNING; | |
247 | rc = SIGP_CC_STATUS_STORED; | |
bd59d3a4 | 248 | } |
bd59d3a4 | 249 | |
3d95c7d2 DH |
250 | VCPU_EVENT(vcpu, 4, "sensed running status of cpu %x rc %x", |
251 | dst_vcpu->vcpu_id, rc); | |
bd59d3a4 CH |
252 | |
253 | return rc; | |
254 | } | |
255 | ||
b8983830 DH |
256 | static int __prepare_sigp_re_start(struct kvm_vcpu *vcpu, |
257 | struct kvm_vcpu *dst_vcpu, u8 order_code) | |
151104a7 | 258 | { |
3d95c7d2 | 259 | struct kvm_s390_local_interrupt *li = &dst_vcpu->arch.local_int; |
b8983830 DH |
260 | /* handle (RE)START in user space */ |
261 | int rc = -EOPNOTSUPP; | |
151104a7 | 262 | |
6cddd432 | 263 | /* make sure we don't race with STOP irq injection */ |
4ae3c081 | 264 | spin_lock(&li->lock); |
6cddd432 | 265 | if (kvm_s390_is_stop_irq_pending(dst_vcpu)) |
ea1918dd | 266 | rc = SIGP_CC_BUSY; |
4ae3c081 | 267 | spin_unlock(&li->lock); |
1ee0bc55 | 268 | |
151104a7 JF |
269 | return rc; |
270 | } | |
271 | ||
b8983830 DH |
272 | static int __prepare_sigp_cpu_reset(struct kvm_vcpu *vcpu, |
273 | struct kvm_vcpu *dst_vcpu, u8 order_code) | |
274 | { | |
275 | /* handle (INITIAL) CPU RESET in user space */ | |
276 | return -EOPNOTSUPP; | |
277 | } | |
278 | ||
279 | static int __prepare_sigp_unknown(struct kvm_vcpu *vcpu, | |
280 | struct kvm_vcpu *dst_vcpu) | |
281 | { | |
282 | /* handle unknown orders in user space */ | |
283 | return -EOPNOTSUPP; | |
284 | } | |
285 | ||
3526a66b DH |
286 | static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code, |
287 | u16 cpu_addr, u32 parameter, u64 *status_reg) | |
5288fbf0 | 288 | { |
5288fbf0 | 289 | int rc; |
3d95c7d2 DH |
290 | struct kvm_vcpu *dst_vcpu; |
291 | ||
292 | if (cpu_addr >= KVM_MAX_VCPUS) | |
293 | return SIGP_CC_NOT_OPERATIONAL; | |
294 | ||
295 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | |
296 | if (!dst_vcpu) | |
297 | return SIGP_CC_NOT_OPERATIONAL; | |
5288fbf0 | 298 | |
5288fbf0 CB |
299 | switch (order_code) { |
300 | case SIGP_SENSE: | |
301 | vcpu->stat.instruction_sigp_sense++; | |
3d95c7d2 | 302 | rc = __sigp_sense(vcpu, dst_vcpu, status_reg); |
5288fbf0 | 303 | break; |
7697e71f CE |
304 | case SIGP_EXTERNAL_CALL: |
305 | vcpu->stat.instruction_sigp_external_call++; | |
3d95c7d2 | 306 | rc = __sigp_external_call(vcpu, dst_vcpu); |
7697e71f | 307 | break; |
a9ae32c3 | 308 | case SIGP_EMERGENCY_SIGNAL: |
5288fbf0 | 309 | vcpu->stat.instruction_sigp_emergency++; |
3d95c7d2 | 310 | rc = __sigp_emergency(vcpu, dst_vcpu); |
5288fbf0 CB |
311 | break; |
312 | case SIGP_STOP: | |
313 | vcpu->stat.instruction_sigp_stop++; | |
a6cc3108 | 314 | rc = __sigp_stop(vcpu, dst_vcpu); |
5288fbf0 | 315 | break; |
a9ae32c3 | 316 | case SIGP_STOP_AND_STORE_STATUS: |
42cb0c9f | 317 | vcpu->stat.instruction_sigp_stop_store_status++; |
a6cc3108 | 318 | rc = __sigp_stop_and_store_status(vcpu, dst_vcpu, status_reg); |
5288fbf0 | 319 | break; |
00e9e435 | 320 | case SIGP_STORE_STATUS_AT_ADDRESS: |
42cb0c9f | 321 | vcpu->stat.instruction_sigp_store_status++; |
3d95c7d2 | 322 | rc = __sigp_store_status_at_addr(vcpu, dst_vcpu, parameter, |
3526a66b | 323 | status_reg); |
5288fbf0 CB |
324 | break; |
325 | case SIGP_SET_PREFIX: | |
326 | vcpu->stat.instruction_sigp_prefix++; | |
3d95c7d2 | 327 | rc = __sigp_set_prefix(vcpu, dst_vcpu, parameter, status_reg); |
5288fbf0 | 328 | break; |
b13d3580 | 329 | case SIGP_COND_EMERGENCY_SIGNAL: |
42cb0c9f | 330 | vcpu->stat.instruction_sigp_cond_emergency++; |
3d95c7d2 | 331 | rc = __sigp_conditional_emergency(vcpu, dst_vcpu, parameter, |
3526a66b | 332 | status_reg); |
b13d3580 | 333 | break; |
bd59d3a4 CH |
334 | case SIGP_SENSE_RUNNING: |
335 | vcpu->stat.instruction_sigp_sense_running++; | |
3d95c7d2 | 336 | rc = __sigp_sense_running(vcpu, dst_vcpu, status_reg); |
bd59d3a4 | 337 | break; |
58bc33b2 | 338 | case SIGP_START: |
42cb0c9f | 339 | vcpu->stat.instruction_sigp_start++; |
b8983830 | 340 | rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code); |
58bc33b2 | 341 | break; |
5288fbf0 CB |
342 | case SIGP_RESTART: |
343 | vcpu->stat.instruction_sigp_restart++; | |
b8983830 DH |
344 | rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code); |
345 | break; | |
346 | case SIGP_INITIAL_CPU_RESET: | |
42cb0c9f | 347 | vcpu->stat.instruction_sigp_init_cpu_reset++; |
b8983830 DH |
348 | rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code); |
349 | break; | |
350 | case SIGP_CPU_RESET: | |
42cb0c9f | 351 | vcpu->stat.instruction_sigp_cpu_reset++; |
b8983830 | 352 | rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code); |
cc92d6de | 353 | break; |
5288fbf0 | 354 | default: |
42cb0c9f | 355 | vcpu->stat.instruction_sigp_unknown++; |
b8983830 | 356 | rc = __prepare_sigp_unknown(vcpu, dst_vcpu); |
3526a66b DH |
357 | } |
358 | ||
b8983830 DH |
359 | if (rc == -EOPNOTSUPP) |
360 | VCPU_EVENT(vcpu, 4, | |
361 | "sigp order %u -> cpu %x: handled in user space", | |
362 | order_code, dst_vcpu->vcpu_id); | |
363 | ||
3526a66b DH |
364 | return rc; |
365 | } | |
366 | ||
367 | int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) | |
368 | { | |
369 | int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4; | |
370 | int r3 = vcpu->arch.sie_block->ipa & 0x000f; | |
371 | u32 parameter; | |
372 | u16 cpu_addr = vcpu->run->s.regs.gprs[r3]; | |
373 | u8 order_code; | |
374 | int rc; | |
375 | ||
376 | /* sigp in userspace can exit */ | |
377 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | |
378 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | |
379 | ||
380 | order_code = kvm_s390_get_base_disp_rs(vcpu); | |
381 | ||
382 | if (r1 % 2) | |
383 | parameter = vcpu->run->s.regs.gprs[r1]; | |
384 | else | |
385 | parameter = vcpu->run->s.regs.gprs[r1 + 1]; | |
386 | ||
387 | trace_kvm_s390_handle_sigp(vcpu, order_code, cpu_addr, parameter); | |
388 | switch (order_code) { | |
389 | case SIGP_SET_ARCHITECTURE: | |
390 | vcpu->stat.instruction_sigp_arch++; | |
391 | rc = __sigp_set_arch(vcpu, parameter); | |
392 | break; | |
393 | default: | |
394 | rc = handle_sigp_dst(vcpu, order_code, cpu_addr, | |
395 | parameter, | |
396 | &vcpu->run->s.regs.gprs[r1]); | |
5288fbf0 CB |
397 | } |
398 | ||
399 | if (rc < 0) | |
400 | return rc; | |
401 | ||
949c007a | 402 | kvm_s390_set_psw_cc(vcpu, rc); |
5288fbf0 CB |
403 | return 0; |
404 | } | |
4953919f DH |
405 | |
406 | /* | |
407 | * Handle SIGP partial execution interception. | |
408 | * | |
409 | * This interception will occur at the source cpu when a source cpu sends an | |
410 | * external call to a target cpu and the target cpu has the WAIT bit set in | |
411 | * its cpuflags. Interception will occurr after the interrupt indicator bits at | |
412 | * the target cpu have been set. All error cases will lead to instruction | |
413 | * interception, therefore nothing is to be checked or prepared. | |
414 | */ | |
415 | int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu) | |
416 | { | |
417 | int r3 = vcpu->arch.sie_block->ipa & 0x000f; | |
418 | u16 cpu_addr = vcpu->run->s.regs.gprs[r3]; | |
419 | struct kvm_vcpu *dest_vcpu; | |
420 | u8 order_code = kvm_s390_get_base_disp_rs(vcpu); | |
421 | ||
422 | trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr); | |
423 | ||
424 | if (order_code == SIGP_EXTERNAL_CALL) { | |
425 | dest_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | |
426 | BUG_ON(dest_vcpu == NULL); | |
427 | ||
0e9c85a5 | 428 | kvm_s390_vcpu_wakeup(dest_vcpu); |
4953919f DH |
429 | kvm_s390_set_psw_cc(vcpu, SIGP_CC_ORDER_CODE_ACCEPTED); |
430 | return 0; | |
431 | } | |
432 | ||
433 | return -EOPNOTSUPP; | |
434 | } |