kvm.c 12.8 KB
Newer Older
A
Alexander Graf 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
/*
 * QEMU S390x KVM implementation
 *
 * Copyright (c) 2009 Alexander Graf <agraf@suse.de>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

#include <linux/kvm.h>
#include <asm/ptrace.h>

#include "qemu-common.h"
#include "qemu-timer.h"
#include "sysemu.h"
#include "kvm.h"
#include "cpu.h"
#include "device_tree.h"

/* #define DEBUG_KVM */

#ifdef DEBUG_KVM
#define dprintf(fmt, ...) \
    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
#else
#define dprintf(fmt, ...) \
    do { } while (0)
#endif

#define IPA0_DIAG                       0x8300
#define IPA0_SIGP                       0xae00
#define IPA0_PRIV                       0xb200

#define PRIV_SCLP_CALL                  0x20
#define DIAG_KVM_HYPERCALL              0x500
#define DIAG_KVM_BREAKPOINT             0x501

#define ICPT_INSTRUCTION                0x04
#define ICPT_WAITPSW                    0x1c
#define ICPT_SOFT_INTERCEPT             0x24
#define ICPT_CPU_STOP                   0x28
#define ICPT_IO                         0x40

#define SIGP_RESTART                    0x06
#define SIGP_INITIAL_CPU_RESET          0x0b
#define SIGP_STORE_STATUS_ADDR          0x0e
#define SIGP_SET_ARCH                   0x12

#define SCLP_CMDW_READ_SCP_INFO         0x00020001
#define SCLP_CMDW_READ_SCP_INFO_FORCED  0x00120001

66 67 68 69
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
    KVM_CAP_LAST_INFO
};

70
int kvm_arch_init(KVMState *s)
A
Alexander Graf 已提交
71 72 73 74
{
    return 0;
}

75
int kvm_arch_init_vcpu(CPUS390XState *env)
A
Alexander Graf 已提交
76 77 78 79 80 81 82 83 84 85
{
    int ret = 0;

    if (kvm_vcpu_ioctl(env, KVM_S390_INITIAL_RESET, NULL) < 0) {
        perror("cannot init reset vcpu");
    }

    return ret;
}

86
void kvm_arch_reset_vcpu(CPUS390XState *env)
A
Alexander Graf 已提交
87 88 89 90
{
    /* FIXME: add code to reset vcpu. */
}

91
int kvm_arch_put_registers(CPUS390XState *env, int level)
A
Alexander Graf 已提交
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
{
    struct kvm_regs regs;
    int ret;
    int i;

    ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
    if (ret < 0) {
        return ret;
    }

    for (i = 0; i < 16; i++) {
        regs.gprs[i] = env->regs[i];
    }

    ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, &regs);
    if (ret < 0) {
        return ret;
    }

    env->kvm_run->psw_addr = env->psw.addr;
    env->kvm_run->psw_mask = env->psw.mask;

    return ret;
}

117
int kvm_arch_get_registers(CPUS390XState *env)
A
Alexander Graf 已提交
118
{
A
Alexander Graf 已提交
119
    int ret;
A
Alexander Graf 已提交
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
    struct kvm_regs regs;
    int i;

    ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
    if (ret < 0) {
        return ret;
    }

    for (i = 0; i < 16; i++) {
        env->regs[i] = regs.gprs[i];
    }

    env->psw.addr = env->kvm_run->psw_addr;
    env->psw.mask = env->kvm_run->psw_mask;

    return 0;
}

138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
/*
 * Legacy layout for s390:
 * Older S390 KVM requires the topmost vma of the RAM to be
 * smaller than an system defined value, which is at least 256GB.
 * Larger systems have larger values. We put the guest between
 * the end of data segment (system break) and this value. We
 * use 32GB as a base to have enough room for the system break
 * to grow. We also have to use MAP parameters that avoid
 * read-only mapping of guest pages.
 */
static void *legacy_s390_alloc(ram_addr_t size)
{
    void *mem;

    mem = mmap((void *) 0x800000000ULL, size,
               PROT_EXEC|PROT_READ|PROT_WRITE,
               MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
    if (mem == MAP_FAILED) {
        fprintf(stderr, "Allocating RAM failed\n");
        abort();
    }
    return mem;
}

void *kvm_arch_vmalloc(ram_addr_t size)
{
    /* Can we use the standard allocation ? */
    if (kvm_check_extension(kvm_state, KVM_CAP_S390_GMAP) &&
        kvm_check_extension(kvm_state, KVM_CAP_S390_COW)) {
        return NULL;
    } else {
        return legacy_s390_alloc(size);
    }
}

173
int kvm_arch_insert_sw_breakpoint(CPUS390XState *env, struct kvm_sw_breakpoint *bp)
A
Alexander Graf 已提交
174 175 176 177 178 179 180 181 182 183
{
    static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};

    if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
        cpu_memory_rw_debug(env, bp->pc, (uint8_t *)diag_501, 4, 1)) {
        return -EINVAL;
    }
    return 0;
}

184
int kvm_arch_remove_sw_breakpoint(CPUS390XState *env, struct kvm_sw_breakpoint *bp)
A
Alexander Graf 已提交
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
{
    uint8_t t[4];
    static const uint8_t diag_501[] = {0x83, 0x24, 0x05, 0x01};

    if (cpu_memory_rw_debug(env, bp->pc, t, 4, 0)) {
        return -EINVAL;
    } else if (memcmp(t, diag_501, 4)) {
        return -EINVAL;
    } else if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) {
        return -EINVAL;
    }

    return 0;
}

200
void kvm_arch_pre_run(CPUS390XState *env, struct kvm_run *run)
A
Alexander Graf 已提交
201 202 203
{
}

204
void kvm_arch_post_run(CPUS390XState *env, struct kvm_run *run)
A
Alexander Graf 已提交
205 206 207
{
}

208
int kvm_arch_process_async_events(CPUS390XState *env)
M
Marcelo Tosatti 已提交
209
{
210
    return env->halted;
M
Marcelo Tosatti 已提交
211 212
}

213
void kvm_s390_interrupt_internal(CPUS390XState *env, int type, uint32_t parm,
214
                                 uint64_t parm64, int vm)
A
Alexander Graf 已提交
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
{
    struct kvm_s390_interrupt kvmint;
    int r;

    if (!env->kvm_state) {
        return;
    }

    kvmint.type = type;
    kvmint.parm = parm;
    kvmint.parm64 = parm64;

    if (vm) {
        r = kvm_vm_ioctl(env->kvm_state, KVM_S390_INTERRUPT, &kvmint);
    } else {
        r = kvm_vcpu_ioctl(env, KVM_S390_INTERRUPT, &kvmint);
    }

    if (r < 0) {
        fprintf(stderr, "KVM failed to inject interrupt\n");
        exit(1);
    }
}

239
void kvm_s390_virtio_irq(CPUS390XState *env, int config_change, uint64_t token)
A
Alexander Graf 已提交
240 241 242 243 244
{
    kvm_s390_interrupt_internal(env, KVM_S390_INT_VIRTIO, config_change,
                                token, 1);
}

245
void kvm_s390_interrupt(CPUS390XState *env, int type, uint32_t code)
A
Alexander Graf 已提交
246 247 248 249
{
    kvm_s390_interrupt_internal(env, type, code, 0, 0);
}

250
static void enter_pgmcheck(CPUS390XState *env, uint16_t code)
A
Alexander Graf 已提交
251 252 253 254
{
    kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code);
}

255
static inline void setcc(CPUS390XState *env, uint64_t cc)
A
Alexander Graf 已提交
256
{
A
Alexander Graf 已提交
257
    env->kvm_run->psw_mask &= ~(3ull << 44);
A
Alexander Graf 已提交
258 259 260 261 262 263
    env->kvm_run->psw_mask |= (cc & 3) << 44;

    env->psw.mask &= ~(3ul << 44);
    env->psw.mask |= (cc & 3) << 44;
}

264
static int kvm_sclp_service_call(CPUS390XState *env, struct kvm_run *run,
265
                                 uint16_t ipbh0)
A
Alexander Graf 已提交
266 267 268 269 270 271 272 273 274
{
    uint32_t sccb;
    uint64_t code;
    int r = 0;

    cpu_synchronize_state(env);
    sccb = env->regs[ipbh0 & 0xf];
    code = env->regs[(ipbh0 & 0xf0) >> 4];

A
Alexander Graf 已提交
275 276
    r = sclp_service_call(env, sccb, code);
    if (r) {
A
Alexander Graf 已提交
277 278
        setcc(env, 3);
    }
A
Alexander Graf 已提交
279

A
Alexander Graf 已提交
280 281 282
    return 0;
}

283
static int handle_priv(CPUS390XState *env, struct kvm_run *run, uint8_t ipa1)
A
Alexander Graf 已提交
284 285 286 287 288 289 290
{
    int r = 0;
    uint16_t ipbh0 = (run->s390_sieic.ipb & 0xffff0000) >> 16;

    dprintf("KVM: PRIV: %d\n", ipa1);
    switch (ipa1) {
        case PRIV_SCLP_CALL:
291
            r = kvm_sclp_service_call(env, run, ipbh0);
A
Alexander Graf 已提交
292 293 294 295 296 297 298 299 300 301
            break;
        default:
            dprintf("KVM: unknown PRIV: 0x%x\n", ipa1);
            r = -1;
            break;
    }

    return r;
}

302
static int handle_hypercall(CPUS390XState *env, struct kvm_run *run)
A
Alexander Graf 已提交
303 304
{
    cpu_synchronize_state(env);
305
    env->regs[2] = s390_virtio_hypercall(env, env->regs[2], env->regs[1]);
A
Alexander Graf 已提交
306

307
    return 0;
A
Alexander Graf 已提交
308 309
}

310
static int handle_diag(CPUS390XState *env, struct kvm_run *run, int ipb_code)
A
Alexander Graf 已提交
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
{
    int r = 0;

    switch (ipb_code) {
        case DIAG_KVM_HYPERCALL:
            r = handle_hypercall(env, run);
            break;
        case DIAG_KVM_BREAKPOINT:
            sleep(10);
            break;
        default:
            dprintf("KVM: unknown DIAG: 0x%x\n", ipb_code);
            r = -1;
            break;
    }

    return r;
}

330
static int s390_cpu_restart(S390CPU *cpu)
A
Alexander Graf 已提交
331
{
332 333
    CPUS390XState *env = &cpu->env;

A
Alexander Graf 已提交
334
    kvm_s390_interrupt(env, KVM_S390_RESTART, 0);
335
    s390_add_running_cpu(env);
A
Alexander Graf 已提交
336 337 338 339 340
    qemu_cpu_kick(env);
    dprintf("DONE: SIGP cpu restart: %p\n", env);
    return 0;
}

341
static int s390_store_status(CPUS390XState *env, uint32_t parameter)
A
Alexander Graf 已提交
342 343 344 345 346 347
{
    /* XXX */
    fprintf(stderr, "XXX SIGP store status\n");
    return -1;
}

348
static int s390_cpu_initial_reset(CPUS390XState *env)
A
Alexander Graf 已提交
349
{
350 351
    int i;

352
    s390_del_running_cpu(env);
353 354 355 356 357 358 359 360 361 362 363 364
    if (kvm_vcpu_ioctl(env, KVM_S390_INITIAL_RESET, NULL) < 0) {
        perror("cannot init reset vcpu");
    }

    /* Manually zero out all registers */
    cpu_synchronize_state(env);
    for (i = 0; i < 16; i++) {
        env->regs[i] = 0;
    }

    dprintf("DONE: SIGP initial reset: %p\n", env);
    return 0;
A
Alexander Graf 已提交
365 366
}

367
static int handle_sigp(CPUS390XState *env, struct kvm_run *run, uint8_t ipa1)
A
Alexander Graf 已提交
368 369 370 371 372 373
{
    uint8_t order_code;
    uint32_t parameter;
    uint16_t cpu_addr;
    uint8_t t;
    int r = -1;
374
    S390CPU *target_cpu;
375
    CPUS390XState *target_env;
A
Alexander Graf 已提交
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394

    cpu_synchronize_state(env);

    /* get order code */
    order_code = run->s390_sieic.ipb >> 28;
    if (order_code > 0) {
        order_code = env->regs[order_code];
    }
    order_code += (run->s390_sieic.ipb & 0x0fff0000) >> 16;

    /* get parameters */
    t = (ipa1 & 0xf0) >> 4;
    if (!(t % 2)) {
        t++;
    }

    parameter = env->regs[t] & 0x7ffffe00;
    cpu_addr = env->regs[ipa1 & 0x0f];

395 396
    target_cpu = s390_cpu_addr2state(cpu_addr);
    if (target_cpu == NULL) {
A
Alexander Graf 已提交
397 398
        goto out;
    }
399
    target_env = &target_cpu->env;
A
Alexander Graf 已提交
400 401 402

    switch (order_code) {
        case SIGP_RESTART:
403
            r = s390_cpu_restart(target_cpu);
A
Alexander Graf 已提交
404 405 406 407 408 409 410 411 412 413 414
            break;
        case SIGP_STORE_STATUS_ADDR:
            r = s390_store_status(target_env, parameter);
            break;
        case SIGP_SET_ARCH:
            /* make the caller panic */
            return -1;
        case SIGP_INITIAL_CPU_RESET:
            r = s390_cpu_initial_reset(target_env);
            break;
        default:
415
            fprintf(stderr, "KVM: unknown SIGP: 0x%x\n", order_code);
A
Alexander Graf 已提交
416 417 418 419 420 421 422 423
            break;
    }

out:
    setcc(env, r ? 3 : 0);
    return 0;
}

424
static int handle_instruction(CPUS390XState *env, struct kvm_run *run)
A
Alexander Graf 已提交
425 426 427 428
{
    unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
    uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
    int ipb_code = (run->s390_sieic.ipb & 0x0fff0000) >> 16;
429
    int r = -1;
A
Alexander Graf 已提交
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446

    dprintf("handle_instruction 0x%x 0x%x\n", run->s390_sieic.ipa, run->s390_sieic.ipb);
    switch (ipa0) {
        case IPA0_PRIV:
            r = handle_priv(env, run, ipa1);
            break;
        case IPA0_DIAG:
            r = handle_diag(env, run, ipb_code);
            break;
        case IPA0_SIGP:
            r = handle_sigp(env, run, ipa1);
            break;
    }

    if (r < 0) {
        enter_pgmcheck(env, 0x0001);
    }
A
Alexander Graf 已提交
447
    return 0;
A
Alexander Graf 已提交
448 449
}

450 451 452 453 454 455
static bool is_special_wait_psw(CPUS390XState *env)
{
    /* signal quiesce */
    return env->kvm_run->psw_addr == 0xfffUL;
}

456
static int handle_intercept(CPUS390XState *env)
A
Alexander Graf 已提交
457 458 459 460 461
{
    struct kvm_run *run = env->kvm_run;
    int icpt_code = run->s390_sieic.icptcode;
    int r = 0;

A
Alexander Graf 已提交
462 463
    dprintf("intercept: 0x%x (at 0x%lx)\n", icpt_code,
            (long)env->kvm_run->psw_addr);
A
Alexander Graf 已提交
464 465 466 467 468
    switch (icpt_code) {
        case ICPT_INSTRUCTION:
            r = handle_instruction(env, run);
            break;
        case ICPT_WAITPSW:
469 470 471 472 473 474
            if (s390_del_running_cpu(env) == 0 &&
                is_special_wait_psw(env)) {
                qemu_system_shutdown_request();
            }
            r = EXCP_HALTED;
            break;
475 476 477 478 479
        case ICPT_CPU_STOP:
            if (s390_del_running_cpu(env) == 0) {
                qemu_system_shutdown_request();
            }
            r = EXCP_HALTED;
A
Alexander Graf 已提交
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
            break;
        case ICPT_SOFT_INTERCEPT:
            fprintf(stderr, "KVM unimplemented icpt SOFT\n");
            exit(1);
            break;
        case ICPT_IO:
            fprintf(stderr, "KVM unimplemented icpt IO\n");
            exit(1);
            break;
        default:
            fprintf(stderr, "Unknown intercept code: %d\n", icpt_code);
            exit(1);
            break;
    }

    return r;
}

498
int kvm_arch_handle_exit(CPUS390XState *env, struct kvm_run *run)
A
Alexander Graf 已提交
499 500 501 502 503 504 505 506
{
    int ret = 0;

    switch (run->exit_reason) {
        case KVM_EXIT_S390_SIEIC:
            ret = handle_intercept(env);
            break;
        case KVM_EXIT_S390_RESET:
507
            qemu_system_reset_request();
A
Alexander Graf 已提交
508 509 510 511 512 513
            break;
        default:
            fprintf(stderr, "Unknown KVM exit: %d\n", run->exit_reason);
            break;
    }

514 515 516
    if (ret == 0) {
        ret = EXCP_INTERRUPT;
    }
A
Alexander Graf 已提交
517 518
    return ret;
}
519

520
bool kvm_arch_stop_on_emulation_error(CPUS390XState *env)
521 522 523
{
    return true;
}
524

525
int kvm_arch_on_sigbus_vcpu(CPUS390XState *env, int code, void *addr)
526 527 528 529 530 531 532 533
{
    return 1;
}

int kvm_arch_on_sigbus(int code, void *addr)
{
    return 1;
}