blob: e7b3b1375ca92bb43c8dd222202a2e15c30c641d [file] [log] [blame]
Alexander Graf0e60a692009-12-05 12:44:24 +01001/*
2 * QEMU S390x KVM implementation
3 *
4 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
Christian Borntraegerccb084d2012-11-12 01:44:10 +00005 * Copyright IBM Corp. 2012
Alexander Graf0e60a692009-12-05 12:44:24 +01006 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
Christian Borntraegerccb084d2012-11-12 01:44:10 +000017 * Contributions after 2012-10-29 are licensed under the terms of the
18 * GNU GPL, version 2 or (at your option) any later version.
19 *
20 * You should have received a copy of the GNU (Lesser) General Public
Alexander Graf0e60a692009-12-05 12:44:24 +010021 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24#include <sys/types.h>
25#include <sys/ioctl.h>
26#include <sys/mman.h>
27
28#include <linux/kvm.h>
29#include <asm/ptrace.h>
30
31#include "qemu-common.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010032#include "qemu/timer.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010033#include "sysemu/sysemu.h"
34#include "sysemu/kvm.h"
Alexander Graf0e60a692009-12-05 12:44:24 +010035#include "cpu.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010036#include "sysemu/device_tree.h"
Christian Borntraeger08eb8c82013-04-26 11:24:47 +080037#include "qapi/qmp/qjson.h"
38#include "monitor/monitor.h"
Alexander Graf0e60a692009-12-05 12:44:24 +010039
40/* #define DEBUG_KVM */
41
42#ifdef DEBUG_KVM
Peter Maydelle67137c2013-07-29 13:16:37 +010043#define DPRINTF(fmt, ...) \
Alexander Graf0e60a692009-12-05 12:44:24 +010044 do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
45#else
Peter Maydelle67137c2013-07-29 13:16:37 +010046#define DPRINTF(fmt, ...) \
Alexander Graf0e60a692009-12-05 12:44:24 +010047 do { } while (0)
48#endif
49
50#define IPA0_DIAG 0x8300
51#define IPA0_SIGP 0xae00
Cornelia Huck09b99872013-01-24 02:28:07 +000052#define IPA0_B2 0xb200
53#define IPA0_B9 0xb900
54#define IPA0_EB 0xeb00
Alexander Graf0e60a692009-12-05 12:44:24 +010055
56#define PRIV_SCLP_CALL 0x20
Cornelia Huck09b99872013-01-24 02:28:07 +000057#define PRIV_CSCH 0x30
58#define PRIV_HSCH 0x31
59#define PRIV_MSCH 0x32
60#define PRIV_SSCH 0x33
61#define PRIV_STSCH 0x34
62#define PRIV_TSCH 0x35
63#define PRIV_TPI 0x36
64#define PRIV_SAL 0x37
65#define PRIV_RSCH 0x38
66#define PRIV_STCRW 0x39
67#define PRIV_STCPS 0x3a
68#define PRIV_RCHP 0x3b
69#define PRIV_SCHM 0x3c
70#define PRIV_CHSC 0x5f
71#define PRIV_SIGA 0x74
72#define PRIV_XSCH 0x76
73#define PRIV_SQBS 0x8a
74#define PRIV_EQBS 0x9c
Eugene (jno) Dvurechenski268846b2013-06-19 17:27:15 +020075#define DIAG_IPL 0x308
Alexander Graf0e60a692009-12-05 12:44:24 +010076#define DIAG_KVM_HYPERCALL 0x500
77#define DIAG_KVM_BREAKPOINT 0x501
78
Alexander Graf0e60a692009-12-05 12:44:24 +010079#define ICPT_INSTRUCTION 0x04
80#define ICPT_WAITPSW 0x1c
81#define ICPT_SOFT_INTERCEPT 0x24
82#define ICPT_CPU_STOP 0x28
83#define ICPT_IO 0x40
84
Jan Kiszka94a8d392011-01-21 21:48:17 +010085const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
86 KVM_CAP_LAST_INFO
87};
88
Christian Borntraeger5b08b342012-10-29 02:13:21 +000089static int cap_sync_regs;
Dominik Dingel819bd302013-09-05 13:54:39 +020090static int cap_async_pf;
Christian Borntraeger5b08b342012-10-29 02:13:21 +000091
Stefan Weil575ddeb2013-09-29 20:56:45 +020092static void *legacy_s390_alloc(size_t size);
Markus Armbruster91138032013-07-31 15:11:08 +020093
Jan Kiszkacad1e282011-01-21 21:48:16 +010094int kvm_arch_init(KVMState *s)
Alexander Graf0e60a692009-12-05 12:44:24 +010095{
Christian Borntraeger5b08b342012-10-29 02:13:21 +000096 cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS);
Dominik Dingel819bd302013-09-05 13:54:39 +020097 cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF);
Markus Armbruster91138032013-07-31 15:11:08 +020098 if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
99 || !kvm_check_extension(s, KVM_CAP_S390_COW)) {
100 phys_mem_set_alloc(legacy_s390_alloc);
101 }
Alexander Graf0e60a692009-12-05 12:44:24 +0100102 return 0;
103}
104
Eduardo Habkostb164e482013-01-22 18:25:01 -0200105unsigned long kvm_arch_vcpu_id(CPUState *cpu)
106{
107 return cpu->cpu_index;
108}
109
Andreas Färber20d695a2012-10-31 06:57:49 +0100110int kvm_arch_init_vcpu(CPUState *cpu)
Alexander Graf0e60a692009-12-05 12:44:24 +0100111{
Christian Borntraeger1c9d2a12013-02-04 22:53:25 +0000112 /* nothing todo yet */
113 return 0;
Alexander Graf0e60a692009-12-05 12:44:24 +0100114}
115
Andreas Färber20d695a2012-10-31 06:57:49 +0100116void kvm_arch_reset_vcpu(CPUState *cpu)
Alexander Graf0e60a692009-12-05 12:44:24 +0100117{
Alexander Graf419831d2013-01-07 16:44:27 +0100118 /* The initial reset call is needed here to reset in-kernel
119 * vcpu data that we can't access directly from QEMU
120 * (i.e. with older kernels which don't support sync_regs/ONE_REG).
121 * Before this ioctl cpu_synchronize_state() is called in common kvm
122 * code (kvm-all) */
Jens Freimann70bada02013-01-07 05:27:14 +0000123 if (kvm_vcpu_ioctl(cpu, KVM_S390_INITIAL_RESET, NULL)) {
124 perror("Can't reset vcpu\n");
125 }
Alexander Graf0e60a692009-12-05 12:44:24 +0100126}
127
Andreas Färber20d695a2012-10-31 06:57:49 +0100128int kvm_arch_put_registers(CPUState *cs, int level)
Alexander Graf0e60a692009-12-05 12:44:24 +0100129{
Andreas Färber20d695a2012-10-31 06:57:49 +0100130 S390CPU *cpu = S390_CPU(cs);
131 CPUS390XState *env = &cpu->env;
Jason J. Herne420840e2013-04-25 04:25:50 +0000132 struct kvm_one_reg reg;
Christian Borntraeger5b08b342012-10-29 02:13:21 +0000133 struct kvm_sregs sregs;
Alexander Graf0e60a692009-12-05 12:44:24 +0100134 struct kvm_regs regs;
135 int ret;
136 int i;
137
Christian Borntraeger5b08b342012-10-29 02:13:21 +0000138 /* always save the PSW and the GPRS*/
Andreas Färberf7575c962012-12-01 06:18:14 +0100139 cs->kvm_run->psw_addr = env->psw.addr;
140 cs->kvm_run->psw_mask = env->psw.mask;
Alexander Graf0e60a692009-12-05 12:44:24 +0100141
Andreas Färberf7575c962012-12-01 06:18:14 +0100142 if (cap_sync_regs && cs->kvm_run->kvm_valid_regs & KVM_SYNC_GPRS) {
Christian Borntraeger5b08b342012-10-29 02:13:21 +0000143 for (i = 0; i < 16; i++) {
Andreas Färberf7575c962012-12-01 06:18:14 +0100144 cs->kvm_run->s.regs.gprs[i] = env->regs[i];
145 cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_GPRS;
Christian Borntraeger5b08b342012-10-29 02:13:21 +0000146 }
147 } else {
148 for (i = 0; i < 16; i++) {
149 regs.gprs[i] = env->regs[i];
150 }
Andreas Färber1bc22652012-10-31 06:06:49 +0100151 ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &regs);
Christian Borntraeger5b08b342012-10-29 02:13:21 +0000152 if (ret < 0) {
153 return ret;
154 }
155 }
156
157 /* Do we need to save more than that? */
158 if (level == KVM_PUT_RUNTIME_STATE) {
159 return 0;
160 }
161
Dominik Dingel44c68de2013-10-01 16:28:23 +0200162 reg.id = KVM_REG_S390_CPU_TIMER;
163 reg.addr = (__u64)&(env->cputm);
164 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
165 if (ret < 0) {
166 return ret;
167 }
168
169 reg.id = KVM_REG_S390_CLOCK_COMP;
170 reg.addr = (__u64)&(env->ckc);
171 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
172 if (ret < 0) {
173 return ret;
174 }
175
176 reg.id = KVM_REG_S390_TODPR;
177 reg.addr = (__u64)&(env->todpr);
178 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
179 if (ret < 0) {
180 return ret;
181 }
182
Dominik Dingel819bd302013-09-05 13:54:39 +0200183 if (cap_async_pf) {
184 reg.id = KVM_REG_S390_PFTOKEN;
185 reg.addr = (__u64)&(env->pfault_token);
186 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
187 if (ret < 0) {
188 return ret;
189 }
190
191 reg.id = KVM_REG_S390_PFCOMPARE;
192 reg.addr = (__u64)&(env->pfault_compare);
193 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
194 if (ret < 0) {
195 return ret;
196 }
197
198 reg.id = KVM_REG_S390_PFSELECT;
199 reg.addr = (__u64)&(env->pfault_select);
200 ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
201 if (ret < 0) {
202 return ret;
203 }
204 }
205
Christian Borntraeger5b08b342012-10-29 02:13:21 +0000206 if (cap_sync_regs &&
Andreas Färberf7575c962012-12-01 06:18:14 +0100207 cs->kvm_run->kvm_valid_regs & KVM_SYNC_ACRS &&
208 cs->kvm_run->kvm_valid_regs & KVM_SYNC_CRS) {
Christian Borntraeger5b08b342012-10-29 02:13:21 +0000209 for (i = 0; i < 16; i++) {
Andreas Färberf7575c962012-12-01 06:18:14 +0100210 cs->kvm_run->s.regs.acrs[i] = env->aregs[i];
211 cs->kvm_run->s.regs.crs[i] = env->cregs[i];
Christian Borntraeger5b08b342012-10-29 02:13:21 +0000212 }
Andreas Färberf7575c962012-12-01 06:18:14 +0100213 cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_ACRS;
214 cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_CRS;
Christian Borntraeger5b08b342012-10-29 02:13:21 +0000215 } else {
216 for (i = 0; i < 16; i++) {
217 sregs.acrs[i] = env->aregs[i];
218 sregs.crs[i] = env->cregs[i];
219 }
Andreas Färber1bc22652012-10-31 06:06:49 +0100220 ret = kvm_vcpu_ioctl(cs, KVM_SET_SREGS, &sregs);
Christian Borntraeger5b08b342012-10-29 02:13:21 +0000221 if (ret < 0) {
222 return ret;
223 }
224 }
225
226 /* Finally the prefix */
Andreas Färberf7575c962012-12-01 06:18:14 +0100227 if (cap_sync_regs && cs->kvm_run->kvm_valid_regs & KVM_SYNC_PREFIX) {
228 cs->kvm_run->s.regs.prefix = env->psa;
229 cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_PREFIX;
Christian Borntraeger5b08b342012-10-29 02:13:21 +0000230 } else {
231 /* prefix is only supported via sync regs */
232 }
233 return 0;
Alexander Graf0e60a692009-12-05 12:44:24 +0100234}
235
Andreas Färber20d695a2012-10-31 06:57:49 +0100236int kvm_arch_get_registers(CPUState *cs)
Alexander Graf0e60a692009-12-05 12:44:24 +0100237{
Andreas Färber20d695a2012-10-31 06:57:49 +0100238 S390CPU *cpu = S390_CPU(cs);
239 CPUS390XState *env = &cpu->env;
Jason J. Herne420840e2013-04-25 04:25:50 +0000240 struct kvm_one_reg reg;
Dominik Dingel44c68de2013-10-01 16:28:23 +0200241 struct kvm_sregs sregs;
242 struct kvm_regs regs;
243 int i, r;
Jason J. Herne420840e2013-04-25 04:25:50 +0000244
Dominik Dingel44c68de2013-10-01 16:28:23 +0200245 /* get the PSW */
246 env->psw.addr = cs->kvm_run->psw_addr;
247 env->psw.mask = cs->kvm_run->psw_mask;
248
249 /* the GPRS */
250 if (cap_sync_regs && cs->kvm_run->kvm_valid_regs & KVM_SYNC_GPRS) {
251 for (i = 0; i < 16; i++) {
252 env->regs[i] = cs->kvm_run->s.regs.gprs[i];
253 }
254 } else {
255 r = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);
256 if (r < 0) {
257 return r;
258 }
259 for (i = 0; i < 16; i++) {
260 env->regs[i] = regs.gprs[i];
261 }
Jason J. Herne420840e2013-04-25 04:25:50 +0000262 }
263
Dominik Dingel44c68de2013-10-01 16:28:23 +0200264 /* The ACRS and CRS */
265 if (cap_sync_regs &&
266 cs->kvm_run->kvm_valid_regs & KVM_SYNC_ACRS &&
267 cs->kvm_run->kvm_valid_regs & KVM_SYNC_CRS) {
268 for (i = 0; i < 16; i++) {
269 env->aregs[i] = cs->kvm_run->s.regs.acrs[i];
270 env->cregs[i] = cs->kvm_run->s.regs.crs[i];
271 }
272 } else {
273 r = kvm_vcpu_ioctl(cs, KVM_GET_SREGS, &sregs);
274 if (r < 0) {
275 return r;
276 }
277 for (i = 0; i < 16; i++) {
278 env->aregs[i] = sregs.acrs[i];
279 env->cregs[i] = sregs.crs[i];
280 }
281 }
282
283 /* The prefix */
284 if (cap_sync_regs && cs->kvm_run->kvm_valid_regs & KVM_SYNC_PREFIX) {
285 env->psa = cs->kvm_run->s.regs.prefix;
286 }
287
288 /* One Regs */
Jason J. Herne420840e2013-04-25 04:25:50 +0000289 reg.id = KVM_REG_S390_CPU_TIMER;
290 reg.addr = (__u64)&(env->cputm);
291 r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
292 if (r < 0) {
293 return r;
294 }
295
296 reg.id = KVM_REG_S390_CLOCK_COMP;
297 reg.addr = (__u64)&(env->ckc);
298 r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
299 if (r < 0) {
300 return r;
301 }
302
303 reg.id = KVM_REG_S390_TODPR;
304 reg.addr = (__u64)&(env->todpr);
305 r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
306 if (r < 0) {
307 return r;
308 }
309
Dominik Dingel819bd302013-09-05 13:54:39 +0200310 if (cap_async_pf) {
311 reg.id = KVM_REG_S390_PFTOKEN;
312 reg.addr = (__u64)&(env->pfault_token);
313 r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
314 if (r < 0) {
315 return r;
316 }
317
318 reg.id = KVM_REG_S390_PFCOMPARE;
319 reg.addr = (__u64)&(env->pfault_compare);
320 r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
321 if (r < 0) {
322 return r;
323 }
324
325 reg.id = KVM_REG_S390_PFSELECT;
326 reg.addr = (__u64)&(env->pfault_select);
327 r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
328 if (r < 0) {
329 return r;
330 }
331 }
332
Alexander Graf0e60a692009-12-05 12:44:24 +0100333 return 0;
334}
335
Christian Borntraegerfdec9912012-06-15 05:10:30 +0000336/*
337 * Legacy layout for s390:
338 * Older S390 KVM requires the topmost vma of the RAM to be
339 * smaller than an system defined value, which is at least 256GB.
340 * Larger systems have larger values. We put the guest between
341 * the end of data segment (system break) and this value. We
342 * use 32GB as a base to have enough room for the system break
343 * to grow. We also have to use MAP parameters that avoid
344 * read-only mapping of guest pages.
345 */
Stefan Weil575ddeb2013-09-29 20:56:45 +0200346static void *legacy_s390_alloc(size_t size)
Christian Borntraegerfdec9912012-06-15 05:10:30 +0000347{
348 void *mem;
349
350 mem = mmap((void *) 0x800000000ULL, size,
351 PROT_EXEC|PROT_READ|PROT_WRITE,
352 MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
Markus Armbruster39228252013-07-31 15:11:11 +0200353 return mem == MAP_FAILED ? NULL : mem;
Christian Borntraegerfdec9912012-06-15 05:10:30 +0000354}
355
Andreas Färber20d695a2012-10-31 06:57:49 +0100356int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
Alexander Graf0e60a692009-12-05 12:44:24 +0100357{
358 static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};
359
Christian Borntraeger9282b732013-07-26 17:48:06 +0200360 if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
361 cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)diag_501, 4, 1)) {
Alexander Graf0e60a692009-12-05 12:44:24 +0100362 return -EINVAL;
363 }
364 return 0;
365}
366
Andreas Färber20d695a2012-10-31 06:57:49 +0100367int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
Alexander Graf0e60a692009-12-05 12:44:24 +0100368{
369 uint8_t t[4];
370 static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};
371
Christian Borntraeger9282b732013-07-26 17:48:06 +0200372 if (cpu_memory_rw_debug(cs, bp->pc, t, 4, 0)) {
Alexander Graf0e60a692009-12-05 12:44:24 +0100373 return -EINVAL;
374 } else if (memcmp(t, diag_501, 4)) {
375 return -EINVAL;
Christian Borntraeger9282b732013-07-26 17:48:06 +0200376 } else if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) {
Alexander Graf0e60a692009-12-05 12:44:24 +0100377 return -EINVAL;
378 }
379
380 return 0;
381}
382
Andreas Färber20d695a2012-10-31 06:57:49 +0100383void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
Alexander Graf0e60a692009-12-05 12:44:24 +0100384{
Alexander Graf0e60a692009-12-05 12:44:24 +0100385}
386
Andreas Färber20d695a2012-10-31 06:57:49 +0100387void kvm_arch_post_run(CPUState *cpu, struct kvm_run *run)
Alexander Graf0e60a692009-12-05 12:44:24 +0100388{
Alexander Graf0e60a692009-12-05 12:44:24 +0100389}
390
Andreas Färber20d695a2012-10-31 06:57:49 +0100391int kvm_arch_process_async_events(CPUState *cs)
Marcelo Tosatti0af691d2010-05-04 09:45:27 -0300392{
Cornelia Huck225dc992013-03-15 10:57:40 +0100393 return cs->halted;
Marcelo Tosatti0af691d2010-05-04 09:45:27 -0300394}
395
Andreas Färber1bc22652012-10-31 06:06:49 +0100396void kvm_s390_interrupt_internal(S390CPU *cpu, int type, uint32_t parm,
Alexander Grafbcec36e2011-04-15 17:32:47 +0200397 uint64_t parm64, int vm)
Alexander Graf0e60a692009-12-05 12:44:24 +0100398{
Andreas Färber1bc22652012-10-31 06:06:49 +0100399 CPUState *cs = CPU(cpu);
Alexander Graf0e60a692009-12-05 12:44:24 +0100400 struct kvm_s390_interrupt kvmint;
401 int r;
402
Andreas Färbera60f24b2012-12-01 05:35:08 +0100403 if (!cs->kvm_state) {
Alexander Graf0e60a692009-12-05 12:44:24 +0100404 return;
405 }
406
Alexander Graf0e60a692009-12-05 12:44:24 +0100407 kvmint.type = type;
408 kvmint.parm = parm;
409 kvmint.parm64 = parm64;
410
411 if (vm) {
Andreas Färbera60f24b2012-12-01 05:35:08 +0100412 r = kvm_vm_ioctl(cs->kvm_state, KVM_S390_INTERRUPT, &kvmint);
Alexander Graf0e60a692009-12-05 12:44:24 +0100413 } else {
Andreas Färber1bc22652012-10-31 06:06:49 +0100414 r = kvm_vcpu_ioctl(cs, KVM_S390_INTERRUPT, &kvmint);
Alexander Graf0e60a692009-12-05 12:44:24 +0100415 }
416
417 if (r < 0) {
418 fprintf(stderr, "KVM failed to inject interrupt\n");
419 exit(1);
420 }
421}
422
Andreas Färber1bc22652012-10-31 06:06:49 +0100423void kvm_s390_virtio_irq(S390CPU *cpu, int config_change, uint64_t token)
Alexander Graf0e60a692009-12-05 12:44:24 +0100424{
Andreas Färber1bc22652012-10-31 06:06:49 +0100425 kvm_s390_interrupt_internal(cpu, KVM_S390_INT_VIRTIO, config_change,
Alexander Graf0e60a692009-12-05 12:44:24 +0100426 token, 1);
427}
428
Andreas Färber1bc22652012-10-31 06:06:49 +0100429void kvm_s390_interrupt(S390CPU *cpu, int type, uint32_t code)
Alexander Graf0e60a692009-12-05 12:44:24 +0100430{
Andreas Färber1bc22652012-10-31 06:06:49 +0100431 kvm_s390_interrupt_internal(cpu, type, code, 0, 0);
Alexander Graf0e60a692009-12-05 12:44:24 +0100432}
433
Andreas Färber1bc22652012-10-31 06:06:49 +0100434static void enter_pgmcheck(S390CPU *cpu, uint16_t code)
Alexander Graf0e60a692009-12-05 12:44:24 +0100435{
Andreas Färber1bc22652012-10-31 06:06:49 +0100436 kvm_s390_interrupt(cpu, KVM_S390_PROGRAM_INT, code);
Alexander Graf0e60a692009-12-05 12:44:24 +0100437}
438
Andreas Färber1bc22652012-10-31 06:06:49 +0100439static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
Alexander Grafbcec36e2011-04-15 17:32:47 +0200440 uint16_t ipbh0)
Alexander Graf0e60a692009-12-05 12:44:24 +0100441{
Andreas Färber1bc22652012-10-31 06:06:49 +0100442 CPUS390XState *env = &cpu->env;
Thomas Hutha0fa2cb2014-01-13 12:19:03 +0100443 uint64_t sccb;
444 uint32_t code;
Alexander Graf0e60a692009-12-05 12:44:24 +0100445 int r = 0;
446
Andreas Färbercb446ec2013-05-01 14:24:52 +0200447 cpu_synchronize_state(CPU(cpu));
Alexander Graf0e60a692009-12-05 12:44:24 +0100448 sccb = env->regs[ipbh0 & 0xf];
449 code = env->regs[(ipbh0 & 0xf0) >> 4];
450
Thomas Huth6e252802014-01-13 12:55:55 +0100451 r = sclp_service_call(env, sccb, code);
Christian Borntraeger9abf5672012-07-23 21:37:04 +0000452 if (r < 0) {
Andreas Färber1bc22652012-10-31 06:06:49 +0100453 enter_pgmcheck(cpu, -r);
Alexander Graf0e60a692009-12-05 12:44:24 +0100454 }
Andreas Färberf7575c962012-12-01 06:18:14 +0100455 setcc(cpu, r);
Alexander Graf81f7c562011-03-23 10:58:07 +0100456
Alexander Graf0e60a692009-12-05 12:44:24 +0100457 return 0;
458}
459
Cornelia Huck09b99872013-01-24 02:28:07 +0000460static int kvm_handle_css_inst(S390CPU *cpu, struct kvm_run *run,
461 uint8_t ipa0, uint8_t ipa1, uint8_t ipb)
462{
Cornelia Huck09b99872013-01-24 02:28:07 +0000463 CPUS390XState *env = &cpu->env;
464
465 if (ipa0 != 0xb2) {
466 /* Not handled for now. */
467 return -1;
468 }
Jason J. Herne3474b672013-04-25 04:25:51 +0000469
Dominik Dingel44c68de2013-10-01 16:28:23 +0200470 cpu_synchronize_state(CPU(cpu));
Jason J. Herne3474b672013-04-25 04:25:51 +0000471
Cornelia Huck09b99872013-01-24 02:28:07 +0000472 switch (ipa1) {
473 case PRIV_XSCH:
Thomas Huth5d9bf1c2013-07-01 15:44:18 +0200474 ioinst_handle_xsch(cpu, env->regs[1]);
Cornelia Huck09b99872013-01-24 02:28:07 +0000475 break;
476 case PRIV_CSCH:
Thomas Huth5d9bf1c2013-07-01 15:44:18 +0200477 ioinst_handle_csch(cpu, env->regs[1]);
Cornelia Huck09b99872013-01-24 02:28:07 +0000478 break;
479 case PRIV_HSCH:
Thomas Huth5d9bf1c2013-07-01 15:44:18 +0200480 ioinst_handle_hsch(cpu, env->regs[1]);
Cornelia Huck09b99872013-01-24 02:28:07 +0000481 break;
482 case PRIV_MSCH:
Thomas Huth5d9bf1c2013-07-01 15:44:18 +0200483 ioinst_handle_msch(cpu, env->regs[1], run->s390_sieic.ipb);
Cornelia Huck09b99872013-01-24 02:28:07 +0000484 break;
485 case PRIV_SSCH:
Thomas Huth5d9bf1c2013-07-01 15:44:18 +0200486 ioinst_handle_ssch(cpu, env->regs[1], run->s390_sieic.ipb);
Cornelia Huck09b99872013-01-24 02:28:07 +0000487 break;
488 case PRIV_STCRW:
Thomas Huth5d9bf1c2013-07-01 15:44:18 +0200489 ioinst_handle_stcrw(cpu, run->s390_sieic.ipb);
Cornelia Huck09b99872013-01-24 02:28:07 +0000490 break;
491 case PRIV_STSCH:
Thomas Huth5d9bf1c2013-07-01 15:44:18 +0200492 ioinst_handle_stsch(cpu, env->regs[1], run->s390_sieic.ipb);
Cornelia Huck09b99872013-01-24 02:28:07 +0000493 break;
494 case PRIV_TSCH:
495 /* We should only get tsch via KVM_EXIT_S390_TSCH. */
496 fprintf(stderr, "Spurious tsch intercept\n");
497 break;
498 case PRIV_CHSC:
Thomas Huth5d9bf1c2013-07-01 15:44:18 +0200499 ioinst_handle_chsc(cpu, run->s390_sieic.ipb);
Cornelia Huck09b99872013-01-24 02:28:07 +0000500 break;
501 case PRIV_TPI:
502 /* This should have been handled by kvm already. */
503 fprintf(stderr, "Spurious tpi intercept\n");
504 break;
505 case PRIV_SCHM:
Thomas Huth5d9bf1c2013-07-01 15:44:18 +0200506 ioinst_handle_schm(cpu, env->regs[1], env->regs[2],
507 run->s390_sieic.ipb);
Cornelia Huck09b99872013-01-24 02:28:07 +0000508 break;
509 case PRIV_RSCH:
Thomas Huth5d9bf1c2013-07-01 15:44:18 +0200510 ioinst_handle_rsch(cpu, env->regs[1]);
Cornelia Huck09b99872013-01-24 02:28:07 +0000511 break;
512 case PRIV_RCHP:
Thomas Huth5d9bf1c2013-07-01 15:44:18 +0200513 ioinst_handle_rchp(cpu, env->regs[1]);
Cornelia Huck09b99872013-01-24 02:28:07 +0000514 break;
515 case PRIV_STCPS:
516 /* We do not provide this instruction, it is suppressed. */
Cornelia Huck09b99872013-01-24 02:28:07 +0000517 break;
518 case PRIV_SAL:
Thomas Huth5d9bf1c2013-07-01 15:44:18 +0200519 ioinst_handle_sal(cpu, env->regs[1]);
Cornelia Huck09b99872013-01-24 02:28:07 +0000520 break;
Thomas Huthc1e8dfb2013-06-24 15:17:34 +0200521 case PRIV_SIGA:
522 /* Not provided, set CC = 3 for subchannel not operational */
Thomas Huth5d9bf1c2013-07-01 15:44:18 +0200523 setcc(cpu, 3);
Thomas Huthc1e8dfb2013-06-24 15:17:34 +0200524 break;
Cornelia Huck09b99872013-01-24 02:28:07 +0000525 default:
Thomas Huthc1e8dfb2013-06-24 15:17:34 +0200526 return -1;
Cornelia Huck09b99872013-01-24 02:28:07 +0000527 }
528
Thomas Huthc1e8dfb2013-06-24 15:17:34 +0200529 return 0;
Cornelia Huck09b99872013-01-24 02:28:07 +0000530}
531
532static int handle_priv(S390CPU *cpu, struct kvm_run *run,
533 uint8_t ipa0, uint8_t ipa1)
Alexander Graf0e60a692009-12-05 12:44:24 +0100534{
535 int r = 0;
536 uint16_t ipbh0 = (run->s390_sieic.ipb & 0xffff0000) >> 16;
Cornelia Huck09b99872013-01-24 02:28:07 +0000537 uint8_t ipb = run->s390_sieic.ipb & 0xff;
Alexander Graf0e60a692009-12-05 12:44:24 +0100538
Peter Maydelle67137c2013-07-29 13:16:37 +0100539 DPRINTF("KVM: PRIV: %d\n", ipa1);
Alexander Graf0e60a692009-12-05 12:44:24 +0100540 switch (ipa1) {
541 case PRIV_SCLP_CALL:
Andreas Färber1bc22652012-10-31 06:06:49 +0100542 r = kvm_sclp_service_call(cpu, run, ipbh0);
Alexander Graf0e60a692009-12-05 12:44:24 +0100543 break;
544 default:
Thomas Huthc1e8dfb2013-06-24 15:17:34 +0200545 r = kvm_handle_css_inst(cpu, run, ipa0, ipa1, ipb);
546 if (r == -1) {
547 DPRINTF("KVM: unhandled PRIV: 0x%x\n", ipa1);
Cornelia Huck09b99872013-01-24 02:28:07 +0000548 }
Alexander Graf0e60a692009-12-05 12:44:24 +0100549 break;
550 }
551
552 return r;
553}
554
Andreas Färber4fd6dd02013-06-21 17:17:00 +0200555static int handle_hypercall(S390CPU *cpu, struct kvm_run *run)
Alexander Graf0e60a692009-12-05 12:44:24 +0100556{
Andreas Färber4fd6dd02013-06-21 17:17:00 +0200557 CPUS390XState *env = &cpu->env;
Thomas Huth77319f22014-01-14 13:32:23 +0100558 int ret;
Jason J. Herne3474b672013-04-25 04:25:51 +0000559
Dominik Dingel44c68de2013-10-01 16:28:23 +0200560 cpu_synchronize_state(CPU(cpu));
Thomas Huth77319f22014-01-14 13:32:23 +0100561 ret = s390_virtio_hypercall(env);
562 if (ret == -EINVAL) {
563 enter_pgmcheck(cpu, PGM_SPECIFICATION);
564 return 0;
565 }
Alexander Graf0e60a692009-12-05 12:44:24 +0100566
Thomas Huth77319f22014-01-14 13:32:23 +0100567 return ret;
Alexander Graf0e60a692009-12-05 12:44:24 +0100568}
569
Eugene (jno) Dvurechenski268846b2013-06-19 17:27:15 +0200570static void kvm_handle_diag_308(S390CPU *cpu, struct kvm_run *run)
571{
572 uint64_t r1, r3;
573
574 cpu_synchronize_state(CPU(cpu));
575 r1 = (run->s390_sieic.ipa & 0x00f0) >> 8;
576 r3 = run->s390_sieic.ipa & 0x000f;
577 handle_diag_308(&cpu->env, r1, r3);
578}
579
Cornelia Huck638129f2013-12-17 18:27:33 +0100580#define DIAG_KVM_CODE_MASK 0x000000000000ffff
581
582static int handle_diag(S390CPU *cpu, struct kvm_run *run, uint32_t ipb)
Alexander Graf0e60a692009-12-05 12:44:24 +0100583{
584 int r = 0;
Cornelia Huck638129f2013-12-17 18:27:33 +0100585 uint16_t func_code;
Alexander Graf0e60a692009-12-05 12:44:24 +0100586
Cornelia Huck638129f2013-12-17 18:27:33 +0100587 /*
588 * For any diagnose call we support, bits 48-63 of the resulting
589 * address specify the function code; the remainder is ignored.
590 */
591 func_code = decode_basedisp_rs(&cpu->env, ipb) & DIAG_KVM_CODE_MASK;
592 switch (func_code) {
Eugene (jno) Dvurechenski268846b2013-06-19 17:27:15 +0200593 case DIAG_IPL:
594 kvm_handle_diag_308(cpu, run);
595 break;
Christian Borntraeger39fbc5c2013-08-30 11:06:56 +0200596 case DIAG_KVM_HYPERCALL:
597 r = handle_hypercall(cpu, run);
598 break;
599 case DIAG_KVM_BREAKPOINT:
600 sleep(10);
601 break;
602 default:
Cornelia Huck638129f2013-12-17 18:27:33 +0100603 DPRINTF("KVM: unknown DIAG: 0x%x\n", func_code);
Christian Borntraeger39fbc5c2013-08-30 11:06:56 +0200604 r = -1;
605 break;
Alexander Graf0e60a692009-12-05 12:44:24 +0100606 }
607
608 return r;
609}
610
Thomas Huthb20a4612013-12-17 14:22:07 +0100611static int kvm_s390_cpu_start(S390CPU *cpu)
612{
613 s390_add_running_cpu(cpu);
614 qemu_cpu_kick(CPU(cpu));
615 DPRINTF("DONE: KVM cpu start: %p\n", &cpu->env);
616 return 0;
617}
618
Eugene (jno) Dvurechenski7f7f9752012-12-05 15:50:07 +0100619int kvm_s390_cpu_restart(S390CPU *cpu)
Alexander Graf0e60a692009-12-05 12:44:24 +0100620{
Andreas Färber1bc22652012-10-31 06:06:49 +0100621 kvm_s390_interrupt(cpu, KVM_S390_RESTART, 0);
Andreas Färber49e15872013-01-30 12:48:25 +0000622 s390_add_running_cpu(cpu);
Andreas Färberc08d7422012-05-03 04:34:15 +0200623 qemu_cpu_kick(CPU(cpu));
Eugene (jno) Dvurechenski7f7f9752012-12-05 15:50:07 +0100624 DPRINTF("DONE: KVM cpu restart: %p\n", &cpu->env);
Alexander Graf0e60a692009-12-05 12:44:24 +0100625 return 0;
626}
627
Andreas Färber1bc22652012-10-31 06:06:49 +0100628static int s390_cpu_initial_reset(S390CPU *cpu)
Alexander Graf0e60a692009-12-05 12:44:24 +0100629{
Andreas Färbercb446ec2013-05-01 14:24:52 +0200630 CPUState *cs = CPU(cpu);
Andreas Färber1bc22652012-10-31 06:06:49 +0100631 CPUS390XState *env = &cpu->env;
Alexander Grafd5900812010-05-14 16:14:31 +0200632 int i;
633
Andreas Färber49e15872013-01-30 12:48:25 +0000634 s390_del_running_cpu(cpu);
Andreas Färbercb446ec2013-05-01 14:24:52 +0200635 if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL) < 0) {
Alexander Grafd5900812010-05-14 16:14:31 +0200636 perror("cannot init reset vcpu");
637 }
638
639 /* Manually zero out all registers */
Andreas Färbercb446ec2013-05-01 14:24:52 +0200640 cpu_synchronize_state(cs);
Alexander Grafd5900812010-05-14 16:14:31 +0200641 for (i = 0; i < 16; i++) {
642 env->regs[i] = 0;
643 }
644
Peter Maydelle67137c2013-07-29 13:16:37 +0100645 DPRINTF("DONE: SIGP initial reset: %p\n", env);
Alexander Grafd5900812010-05-14 16:14:31 +0200646 return 0;
Alexander Graf0e60a692009-12-05 12:44:24 +0100647}
648
Thomas Huthb8031ad2013-12-17 14:22:08 +0100649#define SIGP_ORDER_MASK 0x000000ff
650
Andreas Färberf7575c962012-12-01 06:18:14 +0100651static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
Alexander Graf0e60a692009-12-05 12:44:24 +0100652{
Andreas Färberf7575c962012-12-01 06:18:14 +0100653 CPUS390XState *env = &cpu->env;
Alexander Graf0e60a692009-12-05 12:44:24 +0100654 uint8_t order_code;
Alexander Graf0e60a692009-12-05 12:44:24 +0100655 uint16_t cpu_addr;
Andreas Färber45fa7692012-05-03 04:28:14 +0200656 S390CPU *target_cpu;
Thomas Huth3796f0e2013-12-17 14:22:09 +0100657 uint64_t *statusreg = &env->regs[ipa1 >> 4];
658 int cc;
Alexander Graf0e60a692009-12-05 12:44:24 +0100659
Andreas Färbercb446ec2013-05-01 14:24:52 +0200660 cpu_synchronize_state(CPU(cpu));
Alexander Graf0e60a692009-12-05 12:44:24 +0100661
662 /* get order code */
Thomas Huthb8031ad2013-12-17 14:22:08 +0100663 order_code = decode_basedisp_rs(env, run->s390_sieic.ipb) & SIGP_ORDER_MASK;
Alexander Graf0e60a692009-12-05 12:44:24 +0100664
Alexander Graf0e60a692009-12-05 12:44:24 +0100665 cpu_addr = env->regs[ipa1 & 0x0f];
Andreas Färber45fa7692012-05-03 04:28:14 +0200666 target_cpu = s390_cpu_addr2state(cpu_addr);
667 if (target_cpu == NULL) {
Thomas Huth3796f0e2013-12-17 14:22:09 +0100668 cc = 3; /* not operational */
Alexander Graf0e60a692009-12-05 12:44:24 +0100669 goto out;
670 }
671
672 switch (order_code) {
Thomas Huthb20a4612013-12-17 14:22:07 +0100673 case SIGP_START:
Thomas Huth3796f0e2013-12-17 14:22:09 +0100674 cc = kvm_s390_cpu_start(target_cpu);
Thomas Huthb20a4612013-12-17 14:22:07 +0100675 break;
Thomas Huth0b9972a2013-12-17 14:22:06 +0100676 case SIGP_RESTART:
Thomas Huth3796f0e2013-12-17 14:22:09 +0100677 cc = kvm_s390_cpu_restart(target_cpu);
Thomas Huth0b9972a2013-12-17 14:22:06 +0100678 break;
679 case SIGP_SET_ARCH:
Thomas Huth07880822014-01-22 17:02:46 +0100680 *statusreg &= 0xffffffff00000000UL;
681 *statusreg |= SIGP_STAT_INVALID_PARAMETER;
682 cc = 1; /* status stored */
683 break;
Thomas Huth0b9972a2013-12-17 14:22:06 +0100684 case SIGP_INITIAL_CPU_RESET:
Thomas Huth3796f0e2013-12-17 14:22:09 +0100685 cc = s390_cpu_initial_reset(target_cpu);
Thomas Huth0b9972a2013-12-17 14:22:06 +0100686 break;
687 default:
Thomas Huth3796f0e2013-12-17 14:22:09 +0100688 DPRINTF("KVM: unknown SIGP: 0x%x\n", order_code);
689 *statusreg &= 0xffffffff00000000UL;
690 *statusreg |= SIGP_STAT_INVALID_ORDER;
691 cc = 1; /* status stored */
Thomas Huth0b9972a2013-12-17 14:22:06 +0100692 break;
Alexander Graf0e60a692009-12-05 12:44:24 +0100693 }
694
695out:
Thomas Huth3796f0e2013-12-17 14:22:09 +0100696 setcc(cpu, cc);
Alexander Graf0e60a692009-12-05 12:44:24 +0100697 return 0;
698}
699
Thomas Huthd2ee7742013-07-02 14:45:16 +0200700static void handle_instruction(S390CPU *cpu, struct kvm_run *run)
Alexander Graf0e60a692009-12-05 12:44:24 +0100701{
702 unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
703 uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
Alexander Grafd7963c42009-12-17 13:56:47 +0100704 int r = -1;
Alexander Graf0e60a692009-12-05 12:44:24 +0100705
Peter Maydelle67137c2013-07-29 13:16:37 +0100706 DPRINTF("handle_instruction 0x%x 0x%x\n",
707 run->s390_sieic.ipa, run->s390_sieic.ipb);
Alexander Graf0e60a692009-12-05 12:44:24 +0100708 switch (ipa0) {
Cornelia Huck09b99872013-01-24 02:28:07 +0000709 case IPA0_B2:
710 case IPA0_B9:
711 case IPA0_EB:
712 r = handle_priv(cpu, run, ipa0 >> 8, ipa1);
713 break;
714 case IPA0_DIAG:
Cornelia Huck638129f2013-12-17 18:27:33 +0100715 r = handle_diag(cpu, run, run->s390_sieic.ipb);
Cornelia Huck09b99872013-01-24 02:28:07 +0000716 break;
717 case IPA0_SIGP:
718 r = handle_sigp(cpu, run, ipa1);
719 break;
Alexander Graf0e60a692009-12-05 12:44:24 +0100720 }
721
722 if (r < 0) {
Andreas Färber1bc22652012-10-31 06:06:49 +0100723 enter_pgmcheck(cpu, 0x0001);
Alexander Graf0e60a692009-12-05 12:44:24 +0100724 }
Alexander Graf0e60a692009-12-05 12:44:24 +0100725}
726
Andreas Färberf7575c962012-12-01 06:18:14 +0100727static bool is_special_wait_psw(CPUState *cs)
Christian Borntraegereca3ed02012-04-22 23:52:25 +0000728{
729 /* signal quiesce */
Andreas Färberf7575c962012-12-01 06:18:14 +0100730 return cs->kvm_run->psw_addr == 0xfffUL;
Christian Borntraegereca3ed02012-04-22 23:52:25 +0000731}
732
Andreas Färber1bc22652012-10-31 06:06:49 +0100733static int handle_intercept(S390CPU *cpu)
Alexander Graf0e60a692009-12-05 12:44:24 +0100734{
Andreas Färberf7575c962012-12-01 06:18:14 +0100735 CPUState *cs = CPU(cpu);
736 struct kvm_run *run = cs->kvm_run;
Alexander Graf0e60a692009-12-05 12:44:24 +0100737 int icpt_code = run->s390_sieic.icptcode;
738 int r = 0;
739
Peter Maydelle67137c2013-07-29 13:16:37 +0100740 DPRINTF("intercept: 0x%x (at 0x%lx)\n", icpt_code,
Andreas Färberf7575c962012-12-01 06:18:14 +0100741 (long)cs->kvm_run->psw_addr);
Alexander Graf0e60a692009-12-05 12:44:24 +0100742 switch (icpt_code) {
743 case ICPT_INSTRUCTION:
Thomas Huthd2ee7742013-07-02 14:45:16 +0200744 handle_instruction(cpu, run);
Alexander Graf0e60a692009-12-05 12:44:24 +0100745 break;
746 case ICPT_WAITPSW:
Christian Borntraeger08eb8c82013-04-26 11:24:47 +0800747 /* disabled wait, since enabled wait is handled in kernel */
748 if (s390_del_running_cpu(cpu) == 0) {
749 if (is_special_wait_psw(cs)) {
750 qemu_system_shutdown_request();
751 } else {
752 QObject *data;
753
754 data = qobject_from_jsonf("{ 'action': %s }", "pause");
755 monitor_protocol_event(QEVENT_GUEST_PANICKED, data);
756 qobject_decref(data);
757 vm_stop(RUN_STATE_GUEST_PANICKED);
758 }
Christian Borntraegereca3ed02012-04-22 23:52:25 +0000759 }
760 r = EXCP_HALTED;
761 break;
Christian Borntraeger854e42f2011-10-04 05:20:59 +0000762 case ICPT_CPU_STOP:
Andreas Färber49e15872013-01-30 12:48:25 +0000763 if (s390_del_running_cpu(cpu) == 0) {
Christian Borntraeger854e42f2011-10-04 05:20:59 +0000764 qemu_system_shutdown_request();
765 }
766 r = EXCP_HALTED;
Alexander Graf0e60a692009-12-05 12:44:24 +0100767 break;
768 case ICPT_SOFT_INTERCEPT:
769 fprintf(stderr, "KVM unimplemented icpt SOFT\n");
770 exit(1);
771 break;
Alexander Graf0e60a692009-12-05 12:44:24 +0100772 case ICPT_IO:
773 fprintf(stderr, "KVM unimplemented icpt IO\n");
774 exit(1);
775 break;
776 default:
777 fprintf(stderr, "Unknown intercept code: %d\n", icpt_code);
778 exit(1);
779 break;
780 }
781
782 return r;
783}
784
Cornelia Huck09b99872013-01-24 02:28:07 +0000785static int handle_tsch(S390CPU *cpu)
786{
787 CPUS390XState *env = &cpu->env;
788 CPUState *cs = CPU(cpu);
789 struct kvm_run *run = cs->kvm_run;
790 int ret;
791
Dominik Dingel44c68de2013-10-01 16:28:23 +0200792 cpu_synchronize_state(cs);
Jason J. Herne3474b672013-04-25 04:25:51 +0000793
Cornelia Huck09b99872013-01-24 02:28:07 +0000794 ret = ioinst_handle_tsch(env, env->regs[1], run->s390_tsch.ipb);
795 if (ret >= 0) {
796 /* Success; set condition code. */
797 setcc(cpu, ret);
798 ret = 0;
799 } else if (ret < -1) {
800 /*
801 * Failure.
802 * If an I/O interrupt had been dequeued, we have to reinject it.
803 */
804 if (run->s390_tsch.dequeued) {
805 uint16_t subchannel_id = run->s390_tsch.subchannel_id;
806 uint16_t subchannel_nr = run->s390_tsch.subchannel_nr;
807 uint32_t io_int_parm = run->s390_tsch.io_int_parm;
808 uint32_t io_int_word = run->s390_tsch.io_int_word;
809 uint32_t type = ((subchannel_id & 0xff00) << 24) |
810 ((subchannel_id & 0x00060) << 22) | (subchannel_nr << 16);
811
812 kvm_s390_interrupt_internal(cpu, type,
813 ((uint32_t)subchannel_id << 16)
814 | subchannel_nr,
815 ((uint64_t)io_int_parm << 32)
816 | io_int_word, 1);
817 }
818 ret = 0;
819 }
820 return ret;
821}
822
Andreas Färber20d695a2012-10-31 06:57:49 +0100823int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
Alexander Graf0e60a692009-12-05 12:44:24 +0100824{
Andreas Färber20d695a2012-10-31 06:57:49 +0100825 S390CPU *cpu = S390_CPU(cs);
Alexander Graf0e60a692009-12-05 12:44:24 +0100826 int ret = 0;
827
828 switch (run->exit_reason) {
829 case KVM_EXIT_S390_SIEIC:
Andreas Färber1bc22652012-10-31 06:06:49 +0100830 ret = handle_intercept(cpu);
Alexander Graf0e60a692009-12-05 12:44:24 +0100831 break;
832 case KVM_EXIT_S390_RESET:
Jens Freimannadd142e2012-04-22 23:52:23 +0000833 qemu_system_reset_request();
Alexander Graf0e60a692009-12-05 12:44:24 +0100834 break;
Cornelia Huck09b99872013-01-24 02:28:07 +0000835 case KVM_EXIT_S390_TSCH:
836 ret = handle_tsch(cpu);
837 break;
Alexander Graf0e60a692009-12-05 12:44:24 +0100838 default:
839 fprintf(stderr, "Unknown KVM exit: %d\n", run->exit_reason);
840 break;
841 }
842
Jan Kiszkabb4ea392011-03-15 12:26:28 +0100843 if (ret == 0) {
844 ret = EXCP_INTERRUPT;
Jan Kiszkabb4ea392011-03-15 12:26:28 +0100845 }
Alexander Graf0e60a692009-12-05 12:44:24 +0100846 return ret;
847}
Gleb Natapov4513d922010-05-10 11:21:34 +0300848
Andreas Färber20d695a2012-10-31 06:57:49 +0100849bool kvm_arch_stop_on_emulation_error(CPUState *cpu)
Gleb Natapov4513d922010-05-10 11:21:34 +0300850{
851 return true;
852}
Jan Kiszkaa1b87fe2011-02-01 22:15:51 +0100853
Andreas Färber20d695a2012-10-31 06:57:49 +0100854int kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr)
Jan Kiszkaa1b87fe2011-02-01 22:15:51 +0100855{
856 return 1;
857}
858
859int kvm_arch_on_sigbus(int code, void *addr)
860{
861 return 1;
862}
Cornelia Huck09b99872013-01-24 02:28:07 +0000863
864void kvm_s390_io_interrupt(S390CPU *cpu, uint16_t subchannel_id,
865 uint16_t subchannel_nr, uint32_t io_int_parm,
866 uint32_t io_int_word)
867{
868 uint32_t type;
869
870 type = ((subchannel_id & 0xff00) << 24) |
871 ((subchannel_id & 0x00060) << 22) | (subchannel_nr << 16);
872 kvm_s390_interrupt_internal(cpu, type,
873 ((uint32_t)subchannel_id << 16) | subchannel_nr,
874 ((uint64_t)io_int_parm << 32) | io_int_word, 1);
875}
876
877void kvm_s390_crw_mchk(S390CPU *cpu)
878{
879 kvm_s390_interrupt_internal(cpu, KVM_S390_MCHK, 1 << 28,
880 0x00400f1d40330000, 1);
881}
882
883void kvm_s390_enable_css_support(S390CPU *cpu)
884{
885 struct kvm_enable_cap cap = {};
886 int r;
887
888 /* Activate host kernel channel subsystem support. */
889 cap.cap = KVM_CAP_S390_CSS_SUPPORT;
890 r = kvm_vcpu_ioctl(CPU(cpu), KVM_ENABLE_CAP, &cap);
891 assert(r == 0);
892}
Alexey Kardashevskiy48475e12013-06-12 17:26:53 +1000893
894void kvm_arch_init_irq_routing(KVMState *s)
895{
896}
Cornelia Huckb4436a02013-02-15 10:18:43 +0100897
Cornelia Huckcc3ac9c2013-06-28 09:28:06 +0200898int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
899 int vq, bool assign)
Cornelia Huckb4436a02013-02-15 10:18:43 +0100900{
901 struct kvm_ioeventfd kick = {
902 .flags = KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY |
903 KVM_IOEVENTFD_FLAG_DATAMATCH,
Cornelia Huckcc3ac9c2013-06-28 09:28:06 +0200904 .fd = event_notifier_get_fd(notifier),
Cornelia Huckb4436a02013-02-15 10:18:43 +0100905 .datamatch = vq,
906 .addr = sch,
907 .len = 8,
908 };
909 if (!kvm_check_extension(kvm_state, KVM_CAP_IOEVENTFD)) {
910 return -ENOSYS;
911 }
912 if (!assign) {
913 kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN;
914 }
915 return kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick);
916}