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