|
|
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 ICPT_INSTRUCTION 0x04
53: #define ICPT_WAITPSW 0x1c
54: #define ICPT_SOFT_INTERCEPT 0x24
55: #define ICPT_CPU_STOP 0x28
56: #define ICPT_IO 0x40
57:
58: #define SIGP_RESTART 0x06
59: #define SIGP_INITIAL_CPU_RESET 0x0b
60: #define SIGP_STORE_STATUS_ADDR 0x0e
61: #define SIGP_SET_ARCH 0x12
62:
63: #define SCLP_CMDW_READ_SCP_INFO 0x00020001
64: #define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
65:
1.1.1.3 root 66: const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
67: KVM_CAP_LAST_INFO
68: };
69:
70: int kvm_arch_init(KVMState *s)
1.1 root 71: {
72: return 0;
73: }
74:
75: int kvm_arch_init_vcpu(CPUState *env)
76: {
77: int ret = 0;
78:
79: if (kvm_vcpu_ioctl(env, KVM_S390_INITIAL_RESET, NULL) < 0) {
80: perror("cannot init reset vcpu");
81: }
82:
83: return ret;
84: }
85:
86: void kvm_arch_reset_vcpu(CPUState *env)
87: {
88: /* FIXME: add code to reset vcpu. */
89: }
90:
1.1.1.2 root 91: int kvm_arch_put_registers(CPUState *env, int level)
1.1 root 92: {
93: struct kvm_regs regs;
94: int ret;
95: int i;
96:
97: ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, ®s);
98: if (ret < 0) {
99: return ret;
100: }
101:
102: for (i = 0; i < 16; i++) {
103: regs.gprs[i] = env->regs[i];
104: }
105:
106: ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, ®s);
107: if (ret < 0) {
108: return ret;
109: }
110:
111: env->kvm_run->psw_addr = env->psw.addr;
112: env->kvm_run->psw_mask = env->psw.mask;
113:
114: return ret;
115: }
116:
117: int kvm_arch_get_registers(CPUState *env)
118: {
1.1.1.3 root 119: int ret;
1.1 root 120: struct kvm_regs regs;
121: int i;
122:
123: ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, ®s);
124: if (ret < 0) {
125: return ret;
126: }
127:
128: for (i = 0; i < 16; i++) {
129: env->regs[i] = regs.gprs[i];
130: }
131:
132: env->psw.addr = env->kvm_run->psw_addr;
133: env->psw.mask = env->kvm_run->psw_mask;
134:
135: return 0;
136: }
137:
138: int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
139: {
140: static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};
141:
142: if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
143: cpu_memory_rw_debug(env, bp->pc, (uint8_t *)diag_501, 4, 1)) {
144: return -EINVAL;
145: }
146: return 0;
147: }
148:
149: int kvm_arch_remove_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
150: {
151: uint8_t t[4];
152: static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};
153:
154: if (cpu_memory_rw_debug(env, bp->pc, t, 4, 0)) {
155: return -EINVAL;
156: } else if (memcmp(t, diag_501, 4)) {
157: return -EINVAL;
158: } else if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) {
159: return -EINVAL;
160: }
161:
162: return 0;
163: }
164:
1.1.1.4 ! root 165: void kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
1.1 root 166: {
167: }
168:
1.1.1.4 ! root 169: void kvm_arch_post_run(CPUState *env, struct kvm_run *run)
1.1 root 170: {
171: }
172:
1.1.1.4 ! root 173: int kvm_arch_process_async_events(CPUState *env)
1.1.1.2 root 174: {
1.1.1.4 ! root 175: return env->halted;
1.1.1.2 root 176: }
177:
1.1.1.4 ! root 178: void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm,
! 179: uint64_t parm64, int vm)
1.1 root 180: {
181: struct kvm_s390_interrupt kvmint;
182: int r;
183:
184: if (!env->kvm_state) {
185: return;
186: }
187:
188: env->halted = 0;
1.1.1.2 root 189: env->exception_index = -1;
1.1.1.4 ! root 190: qemu_cpu_kick(env);
1.1 root 191:
192: kvmint.type = type;
193: kvmint.parm = parm;
194: kvmint.parm64 = parm64;
195:
196: if (vm) {
197: r = kvm_vm_ioctl(env->kvm_state, KVM_S390_INTERRUPT, &kvmint);
198: } else {
199: r = kvm_vcpu_ioctl(env, KVM_S390_INTERRUPT, &kvmint);
200: }
201:
202: if (r < 0) {
203: fprintf(stderr, "KVM failed to inject interrupt\n");
204: exit(1);
205: }
206: }
207:
208: void kvm_s390_virtio_irq(CPUState *env, int config_change, uint64_t token)
209: {
210: kvm_s390_interrupt_internal(env, KVM_S390_INT_VIRTIO, config_change,
211: token, 1);
212: }
213:
1.1.1.4 ! root 214: void kvm_s390_interrupt(CPUState *env, int type, uint32_t code)
1.1 root 215: {
216: kvm_s390_interrupt_internal(env, type, code, 0, 0);
217: }
218:
219: static void enter_pgmcheck(CPUState *env, uint16_t code)
220: {
221: kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code);
222: }
223:
1.1.1.4 ! root 224: static inline void setcc(CPUState *env, uint64_t cc)
1.1 root 225: {
1.1.1.4 ! root 226: env->kvm_run->psw_mask &= ~(3ull << 44);
1.1 root 227: env->kvm_run->psw_mask |= (cc & 3) << 44;
228:
229: env->psw.mask &= ~(3ul << 44);
230: env->psw.mask |= (cc & 3) << 44;
231: }
232:
1.1.1.4 ! root 233: static int kvm_sclp_service_call(CPUState *env, struct kvm_run *run,
! 234: uint16_t ipbh0)
1.1 root 235: {
236: uint32_t sccb;
237: uint64_t code;
238: int r = 0;
239:
240: cpu_synchronize_state(env);
241: sccb = env->regs[ipbh0 & 0xf];
242: code = env->regs[(ipbh0 & 0xf0) >> 4];
243:
1.1.1.4 ! root 244: r = sclp_service_call(env, sccb, code);
! 245: if (r) {
1.1 root 246: setcc(env, 3);
247: }
1.1.1.4 ! root 248:
1.1 root 249: return 0;
250: }
251:
252: static int handle_priv(CPUState *env, struct kvm_run *run, uint8_t ipa1)
253: {
254: int r = 0;
255: uint16_t ipbh0 = (run->s390_sieic.ipb & 0xffff0000) >> 16;
256:
257: dprintf("KVM: PRIV: %d\n", ipa1);
258: switch (ipa1) {
259: case PRIV_SCLP_CALL:
1.1.1.4 ! root 260: r = kvm_sclp_service_call(env, run, ipbh0);
1.1 root 261: break;
262: default:
263: dprintf("KVM: unknown PRIV: 0x%x\n", ipa1);
264: r = -1;
265: break;
266: }
267:
268: return r;
269: }
270:
271: static int handle_hypercall(CPUState *env, struct kvm_run *run)
272: {
273: cpu_synchronize_state(env);
1.1.1.4 ! root 274: env->regs[2] = s390_virtio_hypercall(env, env->regs[2], env->regs[1]);
1.1 root 275:
1.1.1.4 ! root 276: return 0;
1.1 root 277: }
278:
279: static int handle_diag(CPUState *env, struct kvm_run *run, int ipb_code)
280: {
281: int r = 0;
282:
283: switch (ipb_code) {
284: case DIAG_KVM_HYPERCALL:
285: r = handle_hypercall(env, run);
286: break;
287: case DIAG_KVM_BREAKPOINT:
288: sleep(10);
289: break;
290: default:
291: dprintf("KVM: unknown DIAG: 0x%x\n", ipb_code);
292: r = -1;
293: break;
294: }
295:
296: return r;
297: }
298:
299: static int s390_cpu_restart(CPUState *env)
300: {
301: kvm_s390_interrupt(env, KVM_S390_RESTART, 0);
302: env->halted = 0;
1.1.1.2 root 303: env->exception_index = -1;
1.1 root 304: qemu_cpu_kick(env);
305: dprintf("DONE: SIGP cpu restart: %p\n", env);
306: return 0;
307: }
308:
309: static int s390_store_status(CPUState *env, uint32_t parameter)
310: {
311: /* XXX */
312: fprintf(stderr, "XXX SIGP store status\n");
313: return -1;
314: }
315:
316: static int s390_cpu_initial_reset(CPUState *env)
317: {
1.1.1.2 root 318: int i;
319:
320: if (kvm_vcpu_ioctl(env, KVM_S390_INITIAL_RESET, NULL) < 0) {
321: perror("cannot init reset vcpu");
322: }
323:
324: /* Manually zero out all registers */
325: cpu_synchronize_state(env);
326: for (i = 0; i < 16; i++) {
327: env->regs[i] = 0;
328: }
329:
330: dprintf("DONE: SIGP initial reset: %p\n", env);
331: return 0;
1.1 root 332: }
333:
334: static int handle_sigp(CPUState *env, struct kvm_run *run, uint8_t ipa1)
335: {
336: uint8_t order_code;
337: uint32_t parameter;
338: uint16_t cpu_addr;
339: uint8_t t;
340: int r = -1;
341: CPUState *target_env;
342:
343: cpu_synchronize_state(env);
344:
345: /* get order code */
346: order_code = run->s390_sieic.ipb >> 28;
347: if (order_code > 0) {
348: order_code = env->regs[order_code];
349: }
350: order_code += (run->s390_sieic.ipb & 0x0fff0000) >> 16;
351:
352: /* get parameters */
353: t = (ipa1 & 0xf0) >> 4;
354: if (!(t % 2)) {
355: t++;
356: }
357:
358: parameter = env->regs[t] & 0x7ffffe00;
359: cpu_addr = env->regs[ipa1 & 0x0f];
360:
361: target_env = s390_cpu_addr2state(cpu_addr);
362: if (!target_env) {
363: goto out;
364: }
365:
366: switch (order_code) {
367: case SIGP_RESTART:
368: r = s390_cpu_restart(target_env);
369: break;
370: case SIGP_STORE_STATUS_ADDR:
371: r = s390_store_status(target_env, parameter);
372: break;
373: case SIGP_SET_ARCH:
374: /* make the caller panic */
375: return -1;
376: case SIGP_INITIAL_CPU_RESET:
377: r = s390_cpu_initial_reset(target_env);
378: break;
379: default:
1.1.1.4 ! root 380: fprintf(stderr, "KVM: unknown SIGP: 0x%x\n", order_code);
1.1 root 381: break;
382: }
383:
384: out:
385: setcc(env, r ? 3 : 0);
386: return 0;
387: }
388:
389: static int handle_instruction(CPUState *env, struct kvm_run *run)
390: {
391: unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
392: uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
393: int ipb_code = (run->s390_sieic.ipb & 0x0fff0000) >> 16;
394: int r = -1;
395:
396: dprintf("handle_instruction 0x%x 0x%x\n", run->s390_sieic.ipa, run->s390_sieic.ipb);
397: switch (ipa0) {
398: case IPA0_PRIV:
399: r = handle_priv(env, run, ipa1);
400: break;
401: case IPA0_DIAG:
402: r = handle_diag(env, run, ipb_code);
403: break;
404: case IPA0_SIGP:
405: r = handle_sigp(env, run, ipa1);
406: break;
407: }
408:
409: if (r < 0) {
410: enter_pgmcheck(env, 0x0001);
411: }
1.1.1.4 ! root 412: return 0;
1.1 root 413: }
414:
415: static int handle_intercept(CPUState *env)
416: {
417: struct kvm_run *run = env->kvm_run;
418: int icpt_code = run->s390_sieic.icptcode;
419: int r = 0;
420:
1.1.1.4 ! root 421: dprintf("intercept: 0x%x (at 0x%lx)\n", icpt_code,
! 422: (long)env->kvm_run->psw_addr);
1.1 root 423: switch (icpt_code) {
424: case ICPT_INSTRUCTION:
425: r = handle_instruction(env, run);
426: break;
427: case ICPT_WAITPSW:
428: /* XXX What to do on system shutdown? */
429: env->halted = 1;
430: env->exception_index = EXCP_HLT;
431: break;
432: case ICPT_SOFT_INTERCEPT:
433: fprintf(stderr, "KVM unimplemented icpt SOFT\n");
434: exit(1);
435: break;
436: case ICPT_CPU_STOP:
437: qemu_system_shutdown_request();
438: break;
439: case ICPT_IO:
440: fprintf(stderr, "KVM unimplemented icpt IO\n");
441: exit(1);
442: break;
443: default:
444: fprintf(stderr, "Unknown intercept code: %d\n", icpt_code);
445: exit(1);
446: break;
447: }
448:
449: return r;
450: }
451:
452: int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
453: {
454: int ret = 0;
455:
456: switch (run->exit_reason) {
457: case KVM_EXIT_S390_SIEIC:
458: ret = handle_intercept(env);
459: break;
460: case KVM_EXIT_S390_RESET:
461: fprintf(stderr, "RESET not implemented\n");
462: exit(1);
463: break;
464: default:
465: fprintf(stderr, "Unknown KVM exit: %d\n", run->exit_reason);
466: break;
467: }
468:
1.1.1.4 ! root 469: if (ret == 0) {
! 470: ret = EXCP_INTERRUPT;
! 471: } else if (ret > 0) {
! 472: ret = 0;
! 473: }
1.1 root 474: return ret;
475: }
1.1.1.2 root 476:
477: bool kvm_arch_stop_on_emulation_error(CPUState *env)
478: {
479: return true;
480: }
1.1.1.4 ! root 481:
! 482: int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
! 483: {
! 484: return 1;
! 485: }
! 486:
! 487: int kvm_arch_on_sigbus(int code, void *addr)
! 488: {
! 489: return 1;
! 490: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.