|
|
1.1 root 1: /*
2: * QEMU S390x KVM implementation
3: *
4: * Copyright (c) 2009 Alexander Graf <[email protected]>
5: *
6: * This library is free software; you can redistribute it and/or
7: * modify it under the terms of the GNU Lesser General Public
8: * License as published by the Free Software Foundation; either
9: * version 2 of the License, or (at your option) any later version.
10: *
11: * This library is distributed in the hope that it will be useful,
12: * but WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14: * Lesser General Public License for more details.
15: *
16: * You should have received a copy of the GNU Lesser General Public
17: * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18: */
19:
20: #include <sys/types.h>
21: #include <sys/ioctl.h>
22: #include <sys/mman.h>
23:
24: #include <linux/kvm.h>
25: #include <asm/ptrace.h>
26:
27: #include "qemu-common.h"
28: #include "qemu-timer.h"
29: #include "sysemu.h"
30: #include "kvm.h"
31: #include "cpu.h"
32: #include "device_tree.h"
33:
34: /* #define DEBUG_KVM */
35:
36: #ifdef DEBUG_KVM
37: #define dprintf(fmt, ...) \
38: do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
39: #else
40: #define dprintf(fmt, ...) \
41: do { } while (0)
42: #endif
43:
44: #define IPA0_DIAG 0x8300
45: #define IPA0_SIGP 0xae00
46: #define IPA0_PRIV 0xb200
47:
48: #define PRIV_SCLP_CALL 0x20
49: #define DIAG_KVM_HYPERCALL 0x500
50: #define DIAG_KVM_BREAKPOINT 0x501
51:
52: #define SCP_LENGTH 0x00
53: #define SCP_FUNCTION_CODE 0x02
54: #define SCP_CONTROL_MASK 0x03
55: #define SCP_RESPONSE_CODE 0x06
56: #define SCP_MEM_CODE 0x08
57: #define SCP_INCREMENT 0x0a
58:
59: #define ICPT_INSTRUCTION 0x04
60: #define ICPT_WAITPSW 0x1c
61: #define ICPT_SOFT_INTERCEPT 0x24
62: #define ICPT_CPU_STOP 0x28
63: #define ICPT_IO 0x40
64:
65: #define SIGP_RESTART 0x06
66: #define SIGP_INITIAL_CPU_RESET 0x0b
67: #define SIGP_STORE_STATUS_ADDR 0x0e
68: #define SIGP_SET_ARCH 0x12
69:
70: #define SCLP_CMDW_READ_SCP_INFO 0x00020001
71: #define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
72:
1.1.1.3 ! root 73: const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
! 74: KVM_CAP_LAST_INFO
! 75: };
! 76:
! 77: int kvm_arch_init(KVMState *s)
1.1 root 78: {
79: return 0;
80: }
81:
82: int kvm_arch_init_vcpu(CPUState *env)
83: {
84: int ret = 0;
85:
86: if (kvm_vcpu_ioctl(env, KVM_S390_INITIAL_RESET, NULL) < 0) {
87: perror("cannot init reset vcpu");
88: }
89:
90: return ret;
91: }
92:
93: void kvm_arch_reset_vcpu(CPUState *env)
94: {
95: /* FIXME: add code to reset vcpu. */
96: }
97:
1.1.1.2 root 98: int kvm_arch_put_registers(CPUState *env, int level)
1.1 root 99: {
100: struct kvm_regs regs;
101: int ret;
102: int i;
103:
104: ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, ®s);
105: if (ret < 0) {
106: return ret;
107: }
108:
109: for (i = 0; i < 16; i++) {
110: regs.gprs[i] = env->regs[i];
111: }
112:
113: ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, ®s);
114: if (ret < 0) {
115: return ret;
116: }
117:
118: env->kvm_run->psw_addr = env->psw.addr;
119: env->kvm_run->psw_mask = env->psw.mask;
120:
121: return ret;
122: }
123:
124: int kvm_arch_get_registers(CPUState *env)
125: {
1.1.1.3 ! root 126: int ret;
1.1 root 127: struct kvm_regs regs;
128: int i;
129:
130: ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, ®s);
131: if (ret < 0) {
132: return ret;
133: }
134:
135: for (i = 0; i < 16; i++) {
136: env->regs[i] = regs.gprs[i];
137: }
138:
139: env->psw.addr = env->kvm_run->psw_addr;
140: env->psw.mask = env->kvm_run->psw_mask;
141:
142: return 0;
143: }
144:
145: int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
146: {
147: static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};
148:
149: if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
150: cpu_memory_rw_debug(env, bp->pc, (uint8_t *)diag_501, 4, 1)) {
151: return -EINVAL;
152: }
153: return 0;
154: }
155:
156: int kvm_arch_remove_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
157: {
158: uint8_t t[4];
159: static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};
160:
161: if (cpu_memory_rw_debug(env, bp->pc, t, 4, 0)) {
162: return -EINVAL;
163: } else if (memcmp(t, diag_501, 4)) {
164: return -EINVAL;
165: } else if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) {
166: return -EINVAL;
167: }
168:
169: return 0;
170: }
171:
172: int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
173: {
174: return 0;
175: }
176:
177: int kvm_arch_post_run(CPUState *env, struct kvm_run *run)
178: {
179: return 0;
180: }
181:
1.1.1.2 root 182: int kvm_arch_process_irqchip_events(CPUState *env)
183: {
184: return 0;
185: }
186:
1.1 root 187: static void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm,
188: uint64_t parm64, int vm)
189: {
190: struct kvm_s390_interrupt kvmint;
191: int r;
192:
193: if (!env->kvm_state) {
194: return;
195: }
196:
197: env->halted = 0;
1.1.1.2 root 198: env->exception_index = -1;
1.1 root 199:
200: kvmint.type = type;
201: kvmint.parm = parm;
202: kvmint.parm64 = parm64;
203:
204: if (vm) {
205: r = kvm_vm_ioctl(env->kvm_state, KVM_S390_INTERRUPT, &kvmint);
206: } else {
207: r = kvm_vcpu_ioctl(env, KVM_S390_INTERRUPT, &kvmint);
208: }
209:
210: if (r < 0) {
211: fprintf(stderr, "KVM failed to inject interrupt\n");
212: exit(1);
213: }
214: }
215:
216: void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t token)
217: {
218: kvm_s390_interrupt_internal(env, KVM_S390_INT_VIRTIO, config_change,
219: token, 1);
220: }
221:
222: static void kvm_s390_interrupt(CPUState *env, int type, uint32_t code)
223: {
224: kvm_s390_interrupt_internal(env, type, code, 0, 0);
225: }
226:
227: static void enter_pgmcheck(CPUState *env, uint16_t code)
228: {
229: kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code);
230: }
231:
232: static void setcc(CPUState *env, uint64_t cc)
233: {
234: env->kvm_run->psw_mask &= ~(3ul << 44);
235: env->kvm_run->psw_mask |= (cc & 3) << 44;
236:
237: env->psw.mask &= ~(3ul << 44);
238: env->psw.mask |= (cc & 3) << 44;
239: }
240:
241: static int sclp_service_call(CPUState *env, struct kvm_run *run, uint16_t ipbh0)
242: {
243: uint32_t sccb;
244: uint64_t code;
245: int r = 0;
246:
247: cpu_synchronize_state(env);
248: sccb = env->regs[ipbh0 & 0xf];
249: code = env->regs[(ipbh0 & 0xf0) >> 4];
250:
251: dprintf("sclp(0x%x, 0x%lx)\n", sccb, code);
252:
253: if (sccb & ~0x7ffffff8ul) {
254: fprintf(stderr, "KVM: invalid sccb address 0x%x\n", sccb);
255: r = -1;
256: goto out;
257: }
258:
259: switch(code) {
260: case SCLP_CMDW_READ_SCP_INFO:
261: case SCLP_CMDW_READ_SCP_INFO_FORCED:
262: stw_phys(sccb + SCP_MEM_CODE, ram_size >> 20);
263: stb_phys(sccb + SCP_INCREMENT, 1);
264: stw_phys(sccb + SCP_RESPONSE_CODE, 0x10);
265: setcc(env, 0);
266:
267: kvm_s390_interrupt_internal(env, KVM_S390_INT_SERVICE,
268: sccb & ~3, 0, 1);
269: break;
270: default:
271: dprintf("KVM: invalid sclp call 0x%x / 0x%lx\n", sccb, code);
272: r = -1;
273: break;
274: }
275:
276: out:
277: if (r < 0) {
278: setcc(env, 3);
279: }
280: return 0;
281: }
282:
283: static int handle_priv(CPUState *env, struct kvm_run *run, uint8_t ipa1)
284: {
285: int r = 0;
286: uint16_t ipbh0 = (run->s390_sieic.ipb & 0xffff0000) >> 16;
287:
288: dprintf("KVM: PRIV: %d\n", ipa1);
289: switch (ipa1) {
290: case PRIV_SCLP_CALL:
291: r = sclp_service_call(env, run, ipbh0);
292: break;
293: default:
294: dprintf("KVM: unknown PRIV: 0x%x\n", ipa1);
295: r = -1;
296: break;
297: }
298:
299: return r;
300: }
301:
302: static int handle_hypercall(CPUState *env, struct kvm_run *run)
303: {
304: int r;
305:
306: cpu_synchronize_state(env);
307: r = s390_virtio_hypercall(env);
308:
309: return r;
310: }
311:
312: static int handle_diag(CPUState *env, struct kvm_run *run, int ipb_code)
313: {
314: int r = 0;
315:
316: switch (ipb_code) {
317: case DIAG_KVM_HYPERCALL:
318: r = handle_hypercall(env, run);
319: break;
320: case DIAG_KVM_BREAKPOINT:
321: sleep(10);
322: break;
323: default:
324: dprintf("KVM: unknown DIAG: 0x%x\n", ipb_code);
325: r = -1;
326: break;
327: }
328:
329: return r;
330: }
331:
332: static int s390_cpu_restart(CPUState *env)
333: {
334: kvm_s390_interrupt(env, KVM_S390_RESTART, 0);
335: env->halted = 0;
1.1.1.2 root 336: env->exception_index = -1;
1.1 root 337: qemu_cpu_kick(env);
338: dprintf("DONE: SIGP cpu restart: %p\n", env);
339: return 0;
340: }
341:
342: static int s390_store_status(CPUState *env, uint32_t parameter)
343: {
344: /* XXX */
345: fprintf(stderr, "XXX SIGP store status\n");
346: return -1;
347: }
348:
349: static int s390_cpu_initial_reset(CPUState *env)
350: {
1.1.1.2 root 351: int i;
352:
353: if (kvm_vcpu_ioctl(env, KVM_S390_INITIAL_RESET, NULL) < 0) {
354: perror("cannot init reset vcpu");
355: }
356:
357: /* Manually zero out all registers */
358: cpu_synchronize_state(env);
359: for (i = 0; i < 16; i++) {
360: env->regs[i] = 0;
361: }
362:
363: dprintf("DONE: SIGP initial reset: %p\n", env);
364: return 0;
1.1 root 365: }
366:
367: static int handle_sigp(CPUState *env, struct kvm_run *run, uint8_t ipa1)
368: {
369: uint8_t order_code;
370: uint32_t parameter;
371: uint16_t cpu_addr;
372: uint8_t t;
373: int r = -1;
374: CPUState *target_env;
375:
376: cpu_synchronize_state(env);
377:
378: /* get order code */
379: order_code = run->s390_sieic.ipb >> 28;
380: if (order_code > 0) {
381: order_code = env->regs[order_code];
382: }
383: order_code += (run->s390_sieic.ipb & 0x0fff0000) >> 16;
384:
385: /* get parameters */
386: t = (ipa1 & 0xf0) >> 4;
387: if (!(t % 2)) {
388: t++;
389: }
390:
391: parameter = env->regs[t] & 0x7ffffe00;
392: cpu_addr = env->regs[ipa1 & 0x0f];
393:
394: target_env = s390_cpu_addr2state(cpu_addr);
395: if (!target_env) {
396: goto out;
397: }
398:
399: switch (order_code) {
400: case SIGP_RESTART:
401: r = s390_cpu_restart(target_env);
402: break;
403: case SIGP_STORE_STATUS_ADDR:
404: r = s390_store_status(target_env, parameter);
405: break;
406: case SIGP_SET_ARCH:
407: /* make the caller panic */
408: return -1;
409: case SIGP_INITIAL_CPU_RESET:
410: r = s390_cpu_initial_reset(target_env);
411: break;
412: default:
413: fprintf(stderr, "KVM: unknown SIGP: 0x%x\n", ipa1);
414: break;
415: }
416:
417: out:
418: setcc(env, r ? 3 : 0);
419: return 0;
420: }
421:
422: static int handle_instruction(CPUState *env, struct kvm_run *run)
423: {
424: unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
425: uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
426: int ipb_code = (run->s390_sieic.ipb & 0x0fff0000) >> 16;
427: int r = -1;
428:
429: dprintf("handle_instruction 0x%x 0x%x\n", run->s390_sieic.ipa, run->s390_sieic.ipb);
430: switch (ipa0) {
431: case IPA0_PRIV:
432: r = handle_priv(env, run, ipa1);
433: break;
434: case IPA0_DIAG:
435: r = handle_diag(env, run, ipb_code);
436: break;
437: case IPA0_SIGP:
438: r = handle_sigp(env, run, ipa1);
439: break;
440: }
441:
442: if (r < 0) {
443: enter_pgmcheck(env, 0x0001);
444: }
445: return r;
446: }
447:
448: static int handle_intercept(CPUState *env)
449: {
450: struct kvm_run *run = env->kvm_run;
451: int icpt_code = run->s390_sieic.icptcode;
452: int r = 0;
453:
454: dprintf("intercept: 0x%x (at 0x%lx)\n", icpt_code, env->kvm_run->psw_addr);
455: switch (icpt_code) {
456: case ICPT_INSTRUCTION:
457: r = handle_instruction(env, run);
458: break;
459: case ICPT_WAITPSW:
460: /* XXX What to do on system shutdown? */
461: env->halted = 1;
462: env->exception_index = EXCP_HLT;
463: break;
464: case ICPT_SOFT_INTERCEPT:
465: fprintf(stderr, "KVM unimplemented icpt SOFT\n");
466: exit(1);
467: break;
468: case ICPT_CPU_STOP:
469: qemu_system_shutdown_request();
470: break;
471: case ICPT_IO:
472: fprintf(stderr, "KVM unimplemented icpt IO\n");
473: exit(1);
474: break;
475: default:
476: fprintf(stderr, "Unknown intercept code: %d\n", icpt_code);
477: exit(1);
478: break;
479: }
480:
481: return r;
482: }
483:
484: int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
485: {
486: int ret = 0;
487:
488: switch (run->exit_reason) {
489: case KVM_EXIT_S390_SIEIC:
490: ret = handle_intercept(env);
491: break;
492: case KVM_EXIT_S390_RESET:
493: fprintf(stderr, "RESET not implemented\n");
494: exit(1);
495: break;
496: default:
497: fprintf(stderr, "Unknown KVM exit: %d\n", run->exit_reason);
498: break;
499: }
500:
501: return ret;
502: }
1.1.1.2 root 503:
504: bool kvm_arch_stop_on_emulation_error(CPUState *env)
505: {
506: return true;
507: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.