1e2132e0bSSanjay Lal /* 2e2132e0bSSanjay Lal * This file is subject to the terms and conditions of the GNU General Public 3e2132e0bSSanjay Lal * License. See the file "COPYING" in the main directory of this archive 4e2132e0bSSanjay Lal * for more details. 5e2132e0bSSanjay Lal * 6e2132e0bSSanjay Lal * KVM/MIPS: MIPS specific KVM APIs 7e2132e0bSSanjay Lal * 8e2132e0bSSanjay Lal * Copyright (C) 2012-2014 Imagination Technologies Ltd. 9e2132e0bSSanjay Lal * Authors: Sanjay Lal <sanjayl@kymasys.com> 10e2132e0bSSanjay Lal */ 11e2132e0bSSanjay Lal 12c684822aSPeter Maydell #include "qemu/osdep.h" 13e2132e0bSSanjay Lal #include <sys/ioctl.h> 14e2132e0bSSanjay Lal 15e2132e0bSSanjay Lal #include <linux/kvm.h> 16e2132e0bSSanjay Lal 17e2132e0bSSanjay Lal #include "qemu-common.h" 1833c11879SPaolo Bonzini #include "cpu.h" 1926aa3d9aSPhilippe Mathieu-Daudé #include "internal.h" 20e2132e0bSSanjay Lal #include "qemu/error-report.h" 21db725815SMarkus Armbruster #include "qemu/main-loop.h" 22e2132e0bSSanjay Lal #include "qemu/timer.h" 23e2132e0bSSanjay Lal #include "sysemu/kvm.h" 2454d31236SMarkus Armbruster #include "sysemu/runstate.h" 25e2132e0bSSanjay Lal #include "sysemu/cpus.h" 26e2132e0bSSanjay Lal #include "kvm_mips.h" 274c663752SPaolo Bonzini #include "exec/memattrs.h" 28e2132e0bSSanjay Lal 29e2132e0bSSanjay Lal #define DEBUG_KVM 0 30e2132e0bSSanjay Lal 31e2132e0bSSanjay Lal #define DPRINTF(fmt, ...) \ 32e2132e0bSSanjay Lal do { if (DEBUG_KVM) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0) 33e2132e0bSSanjay Lal 34152db36aSJames Hogan static int kvm_mips_fpu_cap; 35bee62662SJames Hogan static int kvm_mips_msa_cap; 36152db36aSJames Hogan 37e2132e0bSSanjay Lal const KVMCapabilityInfo kvm_arch_required_capabilities[] = { 38e2132e0bSSanjay Lal KVM_CAP_LAST_INFO 39e2132e0bSSanjay Lal }; 40e2132e0bSSanjay Lal 41e2132e0bSSanjay Lal static void kvm_mips_update_state(void *opaque, int running, RunState state); 42e2132e0bSSanjay Lal 43e2132e0bSSanjay Lal unsigned long kvm_arch_vcpu_id(CPUState *cs) 44e2132e0bSSanjay Lal { 45e2132e0bSSanjay Lal return cs->cpu_index; 46e2132e0bSSanjay Lal } 47e2132e0bSSanjay Lal 48b16565b3SMarcel Apfelbaum int kvm_arch_init(MachineState *ms, KVMState *s) 49e2132e0bSSanjay Lal { 50e2132e0bSSanjay Lal /* MIPS has 128 signals */ 51e2132e0bSSanjay Lal kvm_set_sigmask_len(s, 16); 52e2132e0bSSanjay Lal 53152db36aSJames Hogan kvm_mips_fpu_cap = kvm_check_extension(s, KVM_CAP_MIPS_FPU); 54bee62662SJames Hogan kvm_mips_msa_cap = kvm_check_extension(s, KVM_CAP_MIPS_MSA); 55152db36aSJames Hogan 56e2132e0bSSanjay Lal DPRINTF("%s\n", __func__); 57e2132e0bSSanjay Lal return 0; 58e2132e0bSSanjay Lal } 59e2132e0bSSanjay Lal 60*4376c40dSPaolo Bonzini int kvm_arch_irqchip_create(KVMState *s) 61d525ffabSPaolo Bonzini { 62d525ffabSPaolo Bonzini return 0; 63d525ffabSPaolo Bonzini } 64d525ffabSPaolo Bonzini 65e2132e0bSSanjay Lal int kvm_arch_init_vcpu(CPUState *cs) 66e2132e0bSSanjay Lal { 67152db36aSJames Hogan MIPSCPU *cpu = MIPS_CPU(cs); 68152db36aSJames Hogan CPUMIPSState *env = &cpu->env; 69e2132e0bSSanjay Lal int ret = 0; 70e2132e0bSSanjay Lal 71e2132e0bSSanjay Lal qemu_add_vm_change_state_handler(kvm_mips_update_state, cs); 72e2132e0bSSanjay Lal 73152db36aSJames Hogan if (kvm_mips_fpu_cap && env->CP0_Config1 & (1 << CP0C1_FP)) { 74152db36aSJames Hogan ret = kvm_vcpu_enable_cap(cs, KVM_CAP_MIPS_FPU, 0, 0); 75152db36aSJames Hogan if (ret < 0) { 76152db36aSJames Hogan /* mark unsupported so it gets disabled on reset */ 77152db36aSJames Hogan kvm_mips_fpu_cap = 0; 78152db36aSJames Hogan ret = 0; 79152db36aSJames Hogan } 80152db36aSJames Hogan } 81152db36aSJames Hogan 82bee62662SJames Hogan if (kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) { 83bee62662SJames Hogan ret = kvm_vcpu_enable_cap(cs, KVM_CAP_MIPS_MSA, 0, 0); 84bee62662SJames Hogan if (ret < 0) { 85bee62662SJames Hogan /* mark unsupported so it gets disabled on reset */ 86bee62662SJames Hogan kvm_mips_msa_cap = 0; 87bee62662SJames Hogan ret = 0; 88bee62662SJames Hogan } 89bee62662SJames Hogan } 90bee62662SJames Hogan 91e2132e0bSSanjay Lal DPRINTF("%s\n", __func__); 92e2132e0bSSanjay Lal return ret; 93e2132e0bSSanjay Lal } 94e2132e0bSSanjay Lal 95b1115c99SLiran Alon int kvm_arch_destroy_vcpu(CPUState *cs) 96b1115c99SLiran Alon { 97b1115c99SLiran Alon return 0; 98b1115c99SLiran Alon } 99b1115c99SLiran Alon 100e2132e0bSSanjay Lal void kvm_mips_reset_vcpu(MIPSCPU *cpu) 101e2132e0bSSanjay Lal { 1020e928b12SJames Hogan CPUMIPSState *env = &cpu->env; 1030e928b12SJames Hogan 104152db36aSJames Hogan if (!kvm_mips_fpu_cap && env->CP0_Config1 & (1 << CP0C1_FP)) { 1052ab4b135SAlistair Francis warn_report("KVM does not support FPU, disabling"); 1060e928b12SJames Hogan env->CP0_Config1 &= ~(1 << CP0C1_FP); 1070e928b12SJames Hogan } 108bee62662SJames Hogan if (!kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) { 1092ab4b135SAlistair Francis warn_report("KVM does not support MSA, disabling"); 110bee62662SJames Hogan env->CP0_Config3 &= ~(1 << CP0C3_MSAP); 111bee62662SJames Hogan } 1120e928b12SJames Hogan 113e2132e0bSSanjay Lal DPRINTF("%s\n", __func__); 114e2132e0bSSanjay Lal } 115e2132e0bSSanjay Lal 116e2132e0bSSanjay Lal int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) 117e2132e0bSSanjay Lal { 118e2132e0bSSanjay Lal DPRINTF("%s\n", __func__); 119e2132e0bSSanjay Lal return 0; 120e2132e0bSSanjay Lal } 121e2132e0bSSanjay Lal 122e2132e0bSSanjay Lal int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) 123e2132e0bSSanjay Lal { 124e2132e0bSSanjay Lal DPRINTF("%s\n", __func__); 125e2132e0bSSanjay Lal return 0; 126e2132e0bSSanjay Lal } 127e2132e0bSSanjay Lal 128e2132e0bSSanjay Lal static inline int cpu_mips_io_interrupts_pending(MIPSCPU *cpu) 129e2132e0bSSanjay Lal { 130e2132e0bSSanjay Lal CPUMIPSState *env = &cpu->env; 131e2132e0bSSanjay Lal 132e2132e0bSSanjay Lal return env->CP0_Cause & (0x1 << (2 + CP0Ca_IP)); 133e2132e0bSSanjay Lal } 134e2132e0bSSanjay Lal 135e2132e0bSSanjay Lal 136e2132e0bSSanjay Lal void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) 137e2132e0bSSanjay Lal { 138e2132e0bSSanjay Lal MIPSCPU *cpu = MIPS_CPU(cs); 139e2132e0bSSanjay Lal int r; 140e2132e0bSSanjay Lal struct kvm_mips_interrupt intr; 141e2132e0bSSanjay Lal 1424b8523eeSJan Kiszka qemu_mutex_lock_iothread(); 1434b8523eeSJan Kiszka 144e2132e0bSSanjay Lal if ((cs->interrupt_request & CPU_INTERRUPT_HARD) && 145e2132e0bSSanjay Lal cpu_mips_io_interrupts_pending(cpu)) { 146e2132e0bSSanjay Lal intr.cpu = -1; 147e2132e0bSSanjay Lal intr.irq = 2; 148e2132e0bSSanjay Lal r = kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); 149e2132e0bSSanjay Lal if (r < 0) { 150e2132e0bSSanjay Lal error_report("%s: cpu %d: failed to inject IRQ %x", 151e2132e0bSSanjay Lal __func__, cs->cpu_index, intr.irq); 152e2132e0bSSanjay Lal } 153e2132e0bSSanjay Lal } 1544b8523eeSJan Kiszka 1554b8523eeSJan Kiszka qemu_mutex_unlock_iothread(); 156e2132e0bSSanjay Lal } 157e2132e0bSSanjay Lal 1584c663752SPaolo Bonzini MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) 159e2132e0bSSanjay Lal { 1604c663752SPaolo Bonzini return MEMTXATTRS_UNSPECIFIED; 161e2132e0bSSanjay Lal } 162e2132e0bSSanjay Lal 163e2132e0bSSanjay Lal int kvm_arch_process_async_events(CPUState *cs) 164e2132e0bSSanjay Lal { 165e2132e0bSSanjay Lal return cs->halted; 166e2132e0bSSanjay Lal } 167e2132e0bSSanjay Lal 168e2132e0bSSanjay Lal int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) 169e2132e0bSSanjay Lal { 170e2132e0bSSanjay Lal int ret; 171e2132e0bSSanjay Lal 172e2132e0bSSanjay Lal DPRINTF("%s\n", __func__); 173e2132e0bSSanjay Lal switch (run->exit_reason) { 174e2132e0bSSanjay Lal default: 175e2132e0bSSanjay Lal error_report("%s: unknown exit reason %d", 176e2132e0bSSanjay Lal __func__, run->exit_reason); 177e2132e0bSSanjay Lal ret = -1; 178e2132e0bSSanjay Lal break; 179e2132e0bSSanjay Lal } 180e2132e0bSSanjay Lal 181e2132e0bSSanjay Lal return ret; 182e2132e0bSSanjay Lal } 183e2132e0bSSanjay Lal 184e2132e0bSSanjay Lal bool kvm_arch_stop_on_emulation_error(CPUState *cs) 185e2132e0bSSanjay Lal { 186e2132e0bSSanjay Lal DPRINTF("%s\n", __func__); 187e2132e0bSSanjay Lal return true; 188e2132e0bSSanjay Lal } 189e2132e0bSSanjay Lal 190e2132e0bSSanjay Lal void kvm_arch_init_irq_routing(KVMState *s) 191e2132e0bSSanjay Lal { 192e2132e0bSSanjay Lal } 193e2132e0bSSanjay Lal 194e2132e0bSSanjay Lal int kvm_mips_set_interrupt(MIPSCPU *cpu, int irq, int level) 195e2132e0bSSanjay Lal { 196e2132e0bSSanjay Lal CPUState *cs = CPU(cpu); 197e2132e0bSSanjay Lal struct kvm_mips_interrupt intr; 198e2132e0bSSanjay Lal 199e2132e0bSSanjay Lal if (!kvm_enabled()) { 200e2132e0bSSanjay Lal return 0; 201e2132e0bSSanjay Lal } 202e2132e0bSSanjay Lal 203e2132e0bSSanjay Lal intr.cpu = -1; 204e2132e0bSSanjay Lal 205e2132e0bSSanjay Lal if (level) { 206e2132e0bSSanjay Lal intr.irq = irq; 207e2132e0bSSanjay Lal } else { 208e2132e0bSSanjay Lal intr.irq = -irq; 209e2132e0bSSanjay Lal } 210e2132e0bSSanjay Lal 211e2132e0bSSanjay Lal kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); 212e2132e0bSSanjay Lal 213e2132e0bSSanjay Lal return 0; 214e2132e0bSSanjay Lal } 215e2132e0bSSanjay Lal 216e2132e0bSSanjay Lal int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level) 217e2132e0bSSanjay Lal { 218e2132e0bSSanjay Lal CPUState *cs = current_cpu; 219e2132e0bSSanjay Lal CPUState *dest_cs = CPU(cpu); 220e2132e0bSSanjay Lal struct kvm_mips_interrupt intr; 221e2132e0bSSanjay Lal 222e2132e0bSSanjay Lal if (!kvm_enabled()) { 223e2132e0bSSanjay Lal return 0; 224e2132e0bSSanjay Lal } 225e2132e0bSSanjay Lal 226e2132e0bSSanjay Lal intr.cpu = dest_cs->cpu_index; 227e2132e0bSSanjay Lal 228e2132e0bSSanjay Lal if (level) { 229e2132e0bSSanjay Lal intr.irq = irq; 230e2132e0bSSanjay Lal } else { 231e2132e0bSSanjay Lal intr.irq = -irq; 232e2132e0bSSanjay Lal } 233e2132e0bSSanjay Lal 234e2132e0bSSanjay Lal DPRINTF("%s: CPU %d, IRQ: %d\n", __func__, intr.cpu, intr.irq); 235e2132e0bSSanjay Lal 236e2132e0bSSanjay Lal kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); 237e2132e0bSSanjay Lal 238e2132e0bSSanjay Lal return 0; 239e2132e0bSSanjay Lal } 240e2132e0bSSanjay Lal 241e2132e0bSSanjay Lal #define MIPS_CP0_32(_R, _S) \ 2425a2db896SJames Hogan (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U32 | (8 * (_R) + (_S))) 243e2132e0bSSanjay Lal 244e2132e0bSSanjay Lal #define MIPS_CP0_64(_R, _S) \ 2455a2db896SJames Hogan (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S))) 246e2132e0bSSanjay Lal 247e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_INDEX MIPS_CP0_32(0, 0) 248e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_CONTEXT MIPS_CP0_64(4, 0) 249e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_USERLOCAL MIPS_CP0_64(4, 2) 250e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_PAGEMASK MIPS_CP0_32(5, 0) 251e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_WIRED MIPS_CP0_32(6, 0) 252e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_HWRENA MIPS_CP0_32(7, 0) 253e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_BADVADDR MIPS_CP0_64(8, 0) 254e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_COUNT MIPS_CP0_32(9, 0) 255e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_ENTRYHI MIPS_CP0_64(10, 0) 256e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_COMPARE MIPS_CP0_32(11, 0) 257e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_STATUS MIPS_CP0_32(12, 0) 258e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_CAUSE MIPS_CP0_32(13, 0) 259e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_EPC MIPS_CP0_64(14, 0) 260461a1582SJames Hogan #define KVM_REG_MIPS_CP0_PRID MIPS_CP0_32(15, 0) 26103cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0) 26203cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG1 MIPS_CP0_32(16, 1) 26303cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG2 MIPS_CP0_32(16, 2) 26403cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG3 MIPS_CP0_32(16, 3) 26503cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG4 MIPS_CP0_32(16, 4) 26603cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG5 MIPS_CP0_32(16, 5) 267e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_ERROREPC MIPS_CP0_64(30, 0) 268e2132e0bSSanjay Lal 269e2132e0bSSanjay Lal static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id, 270e2132e0bSSanjay Lal int32_t *addr) 271e2132e0bSSanjay Lal { 272e2132e0bSSanjay Lal struct kvm_one_reg cp0reg = { 273e2132e0bSSanjay Lal .id = reg_id, 274f8b3e48bSJames Hogan .addr = (uintptr_t)addr 275e2132e0bSSanjay Lal }; 276e2132e0bSSanjay Lal 277e2132e0bSSanjay Lal return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg); 278e2132e0bSSanjay Lal } 279e2132e0bSSanjay Lal 2800759487bSJames Hogan static inline int kvm_mips_put_one_ureg(CPUState *cs, uint64_t reg_id, 2810759487bSJames Hogan uint32_t *addr) 2820759487bSJames Hogan { 2830759487bSJames Hogan struct kvm_one_reg cp0reg = { 2840759487bSJames Hogan .id = reg_id, 2850759487bSJames Hogan .addr = (uintptr_t)addr 2860759487bSJames Hogan }; 2870759487bSJames Hogan 2880759487bSJames Hogan return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg); 2890759487bSJames Hogan } 2900759487bSJames Hogan 291e2132e0bSSanjay Lal static inline int kvm_mips_put_one_ulreg(CPUState *cs, uint64_t reg_id, 292e2132e0bSSanjay Lal target_ulong *addr) 293e2132e0bSSanjay Lal { 294e2132e0bSSanjay Lal uint64_t val64 = *addr; 295e2132e0bSSanjay Lal struct kvm_one_reg cp0reg = { 296e2132e0bSSanjay Lal .id = reg_id, 297e2132e0bSSanjay Lal .addr = (uintptr_t)&val64 298e2132e0bSSanjay Lal }; 299e2132e0bSSanjay Lal 300e2132e0bSSanjay Lal return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg); 301e2132e0bSSanjay Lal } 302e2132e0bSSanjay Lal 303e2132e0bSSanjay Lal static inline int kvm_mips_put_one_reg64(CPUState *cs, uint64_t reg_id, 304d319f83fSJames Hogan int64_t *addr) 305d319f83fSJames Hogan { 306d319f83fSJames Hogan struct kvm_one_reg cp0reg = { 307d319f83fSJames Hogan .id = reg_id, 308d319f83fSJames Hogan .addr = (uintptr_t)addr 309d319f83fSJames Hogan }; 310d319f83fSJames Hogan 311d319f83fSJames Hogan return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg); 312d319f83fSJames Hogan } 313d319f83fSJames Hogan 314d319f83fSJames Hogan static inline int kvm_mips_put_one_ureg64(CPUState *cs, uint64_t reg_id, 315e2132e0bSSanjay Lal uint64_t *addr) 316e2132e0bSSanjay Lal { 317e2132e0bSSanjay Lal struct kvm_one_reg cp0reg = { 318e2132e0bSSanjay Lal .id = reg_id, 319e2132e0bSSanjay Lal .addr = (uintptr_t)addr 320e2132e0bSSanjay Lal }; 321e2132e0bSSanjay Lal 322e2132e0bSSanjay Lal return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg); 323e2132e0bSSanjay Lal } 324e2132e0bSSanjay Lal 325e2132e0bSSanjay Lal static inline int kvm_mips_get_one_reg(CPUState *cs, uint64_t reg_id, 326e2132e0bSSanjay Lal int32_t *addr) 327e2132e0bSSanjay Lal { 328e2132e0bSSanjay Lal struct kvm_one_reg cp0reg = { 329e2132e0bSSanjay Lal .id = reg_id, 330f8b3e48bSJames Hogan .addr = (uintptr_t)addr 331e2132e0bSSanjay Lal }; 332e2132e0bSSanjay Lal 333f8b3e48bSJames Hogan return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg); 334e2132e0bSSanjay Lal } 335e2132e0bSSanjay Lal 3360759487bSJames Hogan static inline int kvm_mips_get_one_ureg(CPUState *cs, uint64_t reg_id, 3370759487bSJames Hogan uint32_t *addr) 3380759487bSJames Hogan { 3390759487bSJames Hogan struct kvm_one_reg cp0reg = { 3400759487bSJames Hogan .id = reg_id, 3410759487bSJames Hogan .addr = (uintptr_t)addr 3420759487bSJames Hogan }; 3430759487bSJames Hogan 3440759487bSJames Hogan return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg); 3450759487bSJames Hogan } 3460759487bSJames Hogan 347182f42fdSPeter Maydell static inline int kvm_mips_get_one_ulreg(CPUState *cs, uint64_t reg_id, 348e2132e0bSSanjay Lal target_ulong *addr) 349e2132e0bSSanjay Lal { 350e2132e0bSSanjay Lal int ret; 351e2132e0bSSanjay Lal uint64_t val64 = 0; 352e2132e0bSSanjay Lal struct kvm_one_reg cp0reg = { 353e2132e0bSSanjay Lal .id = reg_id, 354e2132e0bSSanjay Lal .addr = (uintptr_t)&val64 355e2132e0bSSanjay Lal }; 356e2132e0bSSanjay Lal 357e2132e0bSSanjay Lal ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg); 358e2132e0bSSanjay Lal if (ret >= 0) { 359e2132e0bSSanjay Lal *addr = val64; 360e2132e0bSSanjay Lal } 361e2132e0bSSanjay Lal return ret; 362e2132e0bSSanjay Lal } 363e2132e0bSSanjay Lal 364182f42fdSPeter Maydell static inline int kvm_mips_get_one_reg64(CPUState *cs, uint64_t reg_id, 365d319f83fSJames Hogan int64_t *addr) 366d319f83fSJames Hogan { 367d319f83fSJames Hogan struct kvm_one_reg cp0reg = { 368d319f83fSJames Hogan .id = reg_id, 369d319f83fSJames Hogan .addr = (uintptr_t)addr 370d319f83fSJames Hogan }; 371d319f83fSJames Hogan 372d319f83fSJames Hogan return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg); 373d319f83fSJames Hogan } 374d319f83fSJames Hogan 375d319f83fSJames Hogan static inline int kvm_mips_get_one_ureg64(CPUState *cs, uint64_t reg_id, 376e2132e0bSSanjay Lal uint64_t *addr) 377e2132e0bSSanjay Lal { 378e2132e0bSSanjay Lal struct kvm_one_reg cp0reg = { 379e2132e0bSSanjay Lal .id = reg_id, 380e2132e0bSSanjay Lal .addr = (uintptr_t)addr 381e2132e0bSSanjay Lal }; 382e2132e0bSSanjay Lal 383e2132e0bSSanjay Lal return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg); 384e2132e0bSSanjay Lal } 385e2132e0bSSanjay Lal 38603cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG_MASK (1U << CP0C0_M) 387152db36aSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG1_MASK ((1U << CP0C1_M) | \ 388152db36aSJames Hogan (1U << CP0C1_FP)) 38903cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG2_MASK (1U << CP0C2_M) 390bee62662SJames Hogan #define KVM_REG_MIPS_CP0_CONFIG3_MASK ((1U << CP0C3_M) | \ 391bee62662SJames Hogan (1U << CP0C3_MSAP)) 39203cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG4_MASK (1U << CP0C4_M) 393bee62662SJames Hogan #define KVM_REG_MIPS_CP0_CONFIG5_MASK ((1U << CP0C5_MSAEn) | \ 394bee62662SJames Hogan (1U << CP0C5_UFE) | \ 395152db36aSJames Hogan (1U << CP0C5_FRE) | \ 396152db36aSJames Hogan (1U << CP0C5_UFR)) 39703cbfd7bSJames Hogan 39803cbfd7bSJames Hogan static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id, 39903cbfd7bSJames Hogan int32_t *addr, int32_t mask) 40003cbfd7bSJames Hogan { 40103cbfd7bSJames Hogan int err; 40203cbfd7bSJames Hogan int32_t tmp, change; 40303cbfd7bSJames Hogan 40403cbfd7bSJames Hogan err = kvm_mips_get_one_reg(cs, reg_id, &tmp); 40503cbfd7bSJames Hogan if (err < 0) { 40603cbfd7bSJames Hogan return err; 40703cbfd7bSJames Hogan } 40803cbfd7bSJames Hogan 40903cbfd7bSJames Hogan /* only change bits in mask */ 41003cbfd7bSJames Hogan change = (*addr ^ tmp) & mask; 41103cbfd7bSJames Hogan if (!change) { 41203cbfd7bSJames Hogan return 0; 41303cbfd7bSJames Hogan } 41403cbfd7bSJames Hogan 41503cbfd7bSJames Hogan tmp = tmp ^ change; 41603cbfd7bSJames Hogan return kvm_mips_put_one_reg(cs, reg_id, &tmp); 41703cbfd7bSJames Hogan } 41803cbfd7bSJames Hogan 419e2132e0bSSanjay Lal /* 420e2132e0bSSanjay Lal * We freeze the KVM timer when either the VM clock is stopped or the state is 421e2132e0bSSanjay Lal * saved (the state is dirty). 422e2132e0bSSanjay Lal */ 423e2132e0bSSanjay Lal 424e2132e0bSSanjay Lal /* 425e2132e0bSSanjay Lal * Save the state of the KVM timer when VM clock is stopped or state is synced 426e2132e0bSSanjay Lal * to QEMU. 427e2132e0bSSanjay Lal */ 428e2132e0bSSanjay Lal static int kvm_mips_save_count(CPUState *cs) 429e2132e0bSSanjay Lal { 430e2132e0bSSanjay Lal MIPSCPU *cpu = MIPS_CPU(cs); 431e2132e0bSSanjay Lal CPUMIPSState *env = &cpu->env; 432e2132e0bSSanjay Lal uint64_t count_ctl; 433e2132e0bSSanjay Lal int err, ret = 0; 434e2132e0bSSanjay Lal 435e2132e0bSSanjay Lal /* freeze KVM timer */ 436d319f83fSJames Hogan err = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl); 437e2132e0bSSanjay Lal if (err < 0) { 438e2132e0bSSanjay Lal DPRINTF("%s: Failed to get COUNT_CTL (%d)\n", __func__, err); 439e2132e0bSSanjay Lal ret = err; 440e2132e0bSSanjay Lal } else if (!(count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) { 441e2132e0bSSanjay Lal count_ctl |= KVM_REG_MIPS_COUNT_CTL_DC; 442d319f83fSJames Hogan err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl); 443e2132e0bSSanjay Lal if (err < 0) { 444e2132e0bSSanjay Lal DPRINTF("%s: Failed to set COUNT_CTL.DC=1 (%d)\n", __func__, err); 445e2132e0bSSanjay Lal ret = err; 446e2132e0bSSanjay Lal } 447e2132e0bSSanjay Lal } 448e2132e0bSSanjay Lal 449e2132e0bSSanjay Lal /* read CP0_Cause */ 450e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CAUSE, &env->CP0_Cause); 451e2132e0bSSanjay Lal if (err < 0) { 452e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_CAUSE (%d)\n", __func__, err); 453e2132e0bSSanjay Lal ret = err; 454e2132e0bSSanjay Lal } 455e2132e0bSSanjay Lal 456e2132e0bSSanjay Lal /* read CP0_Count */ 457e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_COUNT, &env->CP0_Count); 458e2132e0bSSanjay Lal if (err < 0) { 459e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_COUNT (%d)\n", __func__, err); 460e2132e0bSSanjay Lal ret = err; 461e2132e0bSSanjay Lal } 462e2132e0bSSanjay Lal 463e2132e0bSSanjay Lal return ret; 464e2132e0bSSanjay Lal } 465e2132e0bSSanjay Lal 466e2132e0bSSanjay Lal /* 467e2132e0bSSanjay Lal * Restore the state of the KVM timer when VM clock is restarted or state is 468e2132e0bSSanjay Lal * synced to KVM. 469e2132e0bSSanjay Lal */ 470e2132e0bSSanjay Lal static int kvm_mips_restore_count(CPUState *cs) 471e2132e0bSSanjay Lal { 472e2132e0bSSanjay Lal MIPSCPU *cpu = MIPS_CPU(cs); 473e2132e0bSSanjay Lal CPUMIPSState *env = &cpu->env; 474e2132e0bSSanjay Lal uint64_t count_ctl; 475e2132e0bSSanjay Lal int err_dc, err, ret = 0; 476e2132e0bSSanjay Lal 477e2132e0bSSanjay Lal /* check the timer is frozen */ 478d319f83fSJames Hogan err_dc = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl); 479e2132e0bSSanjay Lal if (err_dc < 0) { 480e2132e0bSSanjay Lal DPRINTF("%s: Failed to get COUNT_CTL (%d)\n", __func__, err_dc); 481e2132e0bSSanjay Lal ret = err_dc; 482e2132e0bSSanjay Lal } else if (!(count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) { 483e2132e0bSSanjay Lal /* freeze timer (sets COUNT_RESUME for us) */ 484e2132e0bSSanjay Lal count_ctl |= KVM_REG_MIPS_COUNT_CTL_DC; 485d319f83fSJames Hogan err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl); 486e2132e0bSSanjay Lal if (err < 0) { 487e2132e0bSSanjay Lal DPRINTF("%s: Failed to set COUNT_CTL.DC=1 (%d)\n", __func__, err); 488e2132e0bSSanjay Lal ret = err; 489e2132e0bSSanjay Lal } 490e2132e0bSSanjay Lal } 491e2132e0bSSanjay Lal 492e2132e0bSSanjay Lal /* load CP0_Cause */ 493e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_CAUSE, &env->CP0_Cause); 494e2132e0bSSanjay Lal if (err < 0) { 495e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_CAUSE (%d)\n", __func__, err); 496e2132e0bSSanjay Lal ret = err; 497e2132e0bSSanjay Lal } 498e2132e0bSSanjay Lal 499e2132e0bSSanjay Lal /* load CP0_Count */ 500e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_COUNT, &env->CP0_Count); 501e2132e0bSSanjay Lal if (err < 0) { 502e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_COUNT (%d)\n", __func__, err); 503e2132e0bSSanjay Lal ret = err; 504e2132e0bSSanjay Lal } 505e2132e0bSSanjay Lal 506e2132e0bSSanjay Lal /* resume KVM timer */ 507e2132e0bSSanjay Lal if (err_dc >= 0) { 508e2132e0bSSanjay Lal count_ctl &= ~KVM_REG_MIPS_COUNT_CTL_DC; 509d319f83fSJames Hogan err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl); 510e2132e0bSSanjay Lal if (err < 0) { 511e2132e0bSSanjay Lal DPRINTF("%s: Failed to set COUNT_CTL.DC=0 (%d)\n", __func__, err); 512e2132e0bSSanjay Lal ret = err; 513e2132e0bSSanjay Lal } 514e2132e0bSSanjay Lal } 515e2132e0bSSanjay Lal 516e2132e0bSSanjay Lal return ret; 517e2132e0bSSanjay Lal } 518e2132e0bSSanjay Lal 519e2132e0bSSanjay Lal /* 520e2132e0bSSanjay Lal * Handle the VM clock being started or stopped 521e2132e0bSSanjay Lal */ 522e2132e0bSSanjay Lal static void kvm_mips_update_state(void *opaque, int running, RunState state) 523e2132e0bSSanjay Lal { 524e2132e0bSSanjay Lal CPUState *cs = opaque; 525e2132e0bSSanjay Lal int ret; 526e2132e0bSSanjay Lal uint64_t count_resume; 527e2132e0bSSanjay Lal 528e2132e0bSSanjay Lal /* 529e2132e0bSSanjay Lal * If state is already dirty (synced to QEMU) then the KVM timer state is 530e2132e0bSSanjay Lal * already saved and can be restored when it is synced back to KVM. 531e2132e0bSSanjay Lal */ 532e2132e0bSSanjay Lal if (!running) { 53399f31832SSergio Andres Gomez Del Real if (!cs->vcpu_dirty) { 534e2132e0bSSanjay Lal ret = kvm_mips_save_count(cs); 535e2132e0bSSanjay Lal if (ret < 0) { 536288cb949SAlistair Francis warn_report("Failed saving count"); 537e2132e0bSSanjay Lal } 538e2132e0bSSanjay Lal } 539e2132e0bSSanjay Lal } else { 540e2132e0bSSanjay Lal /* Set clock restore time to now */ 541906b53a2SPaolo Bonzini count_resume = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); 542d319f83fSJames Hogan ret = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_RESUME, 543e2132e0bSSanjay Lal &count_resume); 544e2132e0bSSanjay Lal if (ret < 0) { 545288cb949SAlistair Francis warn_report("Failed setting COUNT_RESUME"); 546e2132e0bSSanjay Lal return; 547e2132e0bSSanjay Lal } 548e2132e0bSSanjay Lal 54999f31832SSergio Andres Gomez Del Real if (!cs->vcpu_dirty) { 550e2132e0bSSanjay Lal ret = kvm_mips_restore_count(cs); 551e2132e0bSSanjay Lal if (ret < 0) { 552288cb949SAlistair Francis warn_report("Failed restoring count"); 553e2132e0bSSanjay Lal } 554e2132e0bSSanjay Lal } 555e2132e0bSSanjay Lal } 556e2132e0bSSanjay Lal } 557e2132e0bSSanjay Lal 558152db36aSJames Hogan static int kvm_mips_put_fpu_registers(CPUState *cs, int level) 559152db36aSJames Hogan { 560152db36aSJames Hogan MIPSCPU *cpu = MIPS_CPU(cs); 561152db36aSJames Hogan CPUMIPSState *env = &cpu->env; 562152db36aSJames Hogan int err, ret = 0; 563152db36aSJames Hogan unsigned int i; 564152db36aSJames Hogan 565152db36aSJames Hogan /* Only put FPU state if we're emulating a CPU with an FPU */ 566152db36aSJames Hogan if (env->CP0_Config1 & (1 << CP0C1_FP)) { 567152db36aSJames Hogan /* FPU Control Registers */ 568152db36aSJames Hogan if (level == KVM_PUT_FULL_STATE) { 569152db36aSJames Hogan err = kvm_mips_put_one_ureg(cs, KVM_REG_MIPS_FCR_IR, 570152db36aSJames Hogan &env->active_fpu.fcr0); 571152db36aSJames Hogan if (err < 0) { 572152db36aSJames Hogan DPRINTF("%s: Failed to put FCR_IR (%d)\n", __func__, err); 573152db36aSJames Hogan ret = err; 574152db36aSJames Hogan } 575152db36aSJames Hogan } 576152db36aSJames Hogan err = kvm_mips_put_one_ureg(cs, KVM_REG_MIPS_FCR_CSR, 577152db36aSJames Hogan &env->active_fpu.fcr31); 578152db36aSJames Hogan if (err < 0) { 579152db36aSJames Hogan DPRINTF("%s: Failed to put FCR_CSR (%d)\n", __func__, err); 580152db36aSJames Hogan ret = err; 581152db36aSJames Hogan } 582152db36aSJames Hogan 583bee62662SJames Hogan /* 584bee62662SJames Hogan * FPU register state is a subset of MSA vector state, so don't put FPU 585bee62662SJames Hogan * registers if we're emulating a CPU with MSA. 586bee62662SJames Hogan */ 587bee62662SJames Hogan if (!(env->CP0_Config3 & (1 << CP0C3_MSAP))) { 588152db36aSJames Hogan /* Floating point registers */ 589152db36aSJames Hogan for (i = 0; i < 32; ++i) { 590152db36aSJames Hogan if (env->CP0_Status & (1 << CP0St_FR)) { 591152db36aSJames Hogan err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_FPR_64(i), 592152db36aSJames Hogan &env->active_fpu.fpr[i].d); 593152db36aSJames Hogan } else { 594152db36aSJames Hogan err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FPR_32(i), 595152db36aSJames Hogan &env->active_fpu.fpr[i].w[FP_ENDIAN_IDX]); 596152db36aSJames Hogan } 597152db36aSJames Hogan if (err < 0) { 598152db36aSJames Hogan DPRINTF("%s: Failed to put FPR%u (%d)\n", __func__, i, err); 599152db36aSJames Hogan ret = err; 600152db36aSJames Hogan } 601152db36aSJames Hogan } 602152db36aSJames Hogan } 603bee62662SJames Hogan } 604bee62662SJames Hogan 605bee62662SJames Hogan /* Only put MSA state if we're emulating a CPU with MSA */ 606bee62662SJames Hogan if (env->CP0_Config3 & (1 << CP0C3_MSAP)) { 607bee62662SJames Hogan /* MSA Control Registers */ 608bee62662SJames Hogan if (level == KVM_PUT_FULL_STATE) { 609bee62662SJames Hogan err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_MSA_IR, 610bee62662SJames Hogan &env->msair); 611bee62662SJames Hogan if (err < 0) { 612bee62662SJames Hogan DPRINTF("%s: Failed to put MSA_IR (%d)\n", __func__, err); 613bee62662SJames Hogan ret = err; 614bee62662SJames Hogan } 615bee62662SJames Hogan } 616bee62662SJames Hogan err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_MSA_CSR, 617bee62662SJames Hogan &env->active_tc.msacsr); 618bee62662SJames Hogan if (err < 0) { 619bee62662SJames Hogan DPRINTF("%s: Failed to put MSA_CSR (%d)\n", __func__, err); 620bee62662SJames Hogan ret = err; 621bee62662SJames Hogan } 622bee62662SJames Hogan 623bee62662SJames Hogan /* Vector registers (includes FP registers) */ 624bee62662SJames Hogan for (i = 0; i < 32; ++i) { 625bee62662SJames Hogan /* Big endian MSA not supported by QEMU yet anyway */ 626bee62662SJames Hogan err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_VEC_128(i), 627bee62662SJames Hogan env->active_fpu.fpr[i].wr.d); 628bee62662SJames Hogan if (err < 0) { 629bee62662SJames Hogan DPRINTF("%s: Failed to put VEC%u (%d)\n", __func__, i, err); 630bee62662SJames Hogan ret = err; 631bee62662SJames Hogan } 632bee62662SJames Hogan } 633bee62662SJames Hogan } 634152db36aSJames Hogan 635152db36aSJames Hogan return ret; 636152db36aSJames Hogan } 637152db36aSJames Hogan 638152db36aSJames Hogan static int kvm_mips_get_fpu_registers(CPUState *cs) 639152db36aSJames Hogan { 640152db36aSJames Hogan MIPSCPU *cpu = MIPS_CPU(cs); 641152db36aSJames Hogan CPUMIPSState *env = &cpu->env; 642152db36aSJames Hogan int err, ret = 0; 643152db36aSJames Hogan unsigned int i; 644152db36aSJames Hogan 645152db36aSJames Hogan /* Only get FPU state if we're emulating a CPU with an FPU */ 646152db36aSJames Hogan if (env->CP0_Config1 & (1 << CP0C1_FP)) { 647152db36aSJames Hogan /* FPU Control Registers */ 648152db36aSJames Hogan err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FCR_IR, 649152db36aSJames Hogan &env->active_fpu.fcr0); 650152db36aSJames Hogan if (err < 0) { 651152db36aSJames Hogan DPRINTF("%s: Failed to get FCR_IR (%d)\n", __func__, err); 652152db36aSJames Hogan ret = err; 653152db36aSJames Hogan } 654152db36aSJames Hogan err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FCR_CSR, 655152db36aSJames Hogan &env->active_fpu.fcr31); 656152db36aSJames Hogan if (err < 0) { 657152db36aSJames Hogan DPRINTF("%s: Failed to get FCR_CSR (%d)\n", __func__, err); 658152db36aSJames Hogan ret = err; 659152db36aSJames Hogan } else { 660152db36aSJames Hogan restore_fp_status(env); 661152db36aSJames Hogan } 662152db36aSJames Hogan 663bee62662SJames Hogan /* 664bee62662SJames Hogan * FPU register state is a subset of MSA vector state, so don't save FPU 665bee62662SJames Hogan * registers if we're emulating a CPU with MSA. 666bee62662SJames Hogan */ 667bee62662SJames Hogan if (!(env->CP0_Config3 & (1 << CP0C3_MSAP))) { 668152db36aSJames Hogan /* Floating point registers */ 669152db36aSJames Hogan for (i = 0; i < 32; ++i) { 670152db36aSJames Hogan if (env->CP0_Status & (1 << CP0St_FR)) { 671152db36aSJames Hogan err = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_FPR_64(i), 672152db36aSJames Hogan &env->active_fpu.fpr[i].d); 673152db36aSJames Hogan } else { 674152db36aSJames Hogan err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FPR_32(i), 675152db36aSJames Hogan &env->active_fpu.fpr[i].w[FP_ENDIAN_IDX]); 676152db36aSJames Hogan } 677152db36aSJames Hogan if (err < 0) { 678152db36aSJames Hogan DPRINTF("%s: Failed to get FPR%u (%d)\n", __func__, i, err); 679152db36aSJames Hogan ret = err; 680152db36aSJames Hogan } 681152db36aSJames Hogan } 682152db36aSJames Hogan } 683bee62662SJames Hogan } 684bee62662SJames Hogan 685bee62662SJames Hogan /* Only get MSA state if we're emulating a CPU with MSA */ 686bee62662SJames Hogan if (env->CP0_Config3 & (1 << CP0C3_MSAP)) { 687bee62662SJames Hogan /* MSA Control Registers */ 688bee62662SJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_MSA_IR, 689bee62662SJames Hogan &env->msair); 690bee62662SJames Hogan if (err < 0) { 691bee62662SJames Hogan DPRINTF("%s: Failed to get MSA_IR (%d)\n", __func__, err); 692bee62662SJames Hogan ret = err; 693bee62662SJames Hogan } 694bee62662SJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_MSA_CSR, 695bee62662SJames Hogan &env->active_tc.msacsr); 696bee62662SJames Hogan if (err < 0) { 697bee62662SJames Hogan DPRINTF("%s: Failed to get MSA_CSR (%d)\n", __func__, err); 698bee62662SJames Hogan ret = err; 699bee62662SJames Hogan } else { 700bee62662SJames Hogan restore_msa_fp_status(env); 701bee62662SJames Hogan } 702bee62662SJames Hogan 703bee62662SJames Hogan /* Vector registers (includes FP registers) */ 704bee62662SJames Hogan for (i = 0; i < 32; ++i) { 705bee62662SJames Hogan /* Big endian MSA not supported by QEMU yet anyway */ 706bee62662SJames Hogan err = kvm_mips_get_one_reg64(cs, KVM_REG_MIPS_VEC_128(i), 707bee62662SJames Hogan env->active_fpu.fpr[i].wr.d); 708bee62662SJames Hogan if (err < 0) { 709bee62662SJames Hogan DPRINTF("%s: Failed to get VEC%u (%d)\n", __func__, i, err); 710bee62662SJames Hogan ret = err; 711bee62662SJames Hogan } 712bee62662SJames Hogan } 713bee62662SJames Hogan } 714152db36aSJames Hogan 715152db36aSJames Hogan return ret; 716152db36aSJames Hogan } 717152db36aSJames Hogan 718152db36aSJames Hogan 719e2132e0bSSanjay Lal static int kvm_mips_put_cp0_registers(CPUState *cs, int level) 720e2132e0bSSanjay Lal { 721e2132e0bSSanjay Lal MIPSCPU *cpu = MIPS_CPU(cs); 722e2132e0bSSanjay Lal CPUMIPSState *env = &cpu->env; 723e2132e0bSSanjay Lal int err, ret = 0; 724e2132e0bSSanjay Lal 725e2132e0bSSanjay Lal (void)level; 726e2132e0bSSanjay Lal 727e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_INDEX, &env->CP0_Index); 728e2132e0bSSanjay Lal if (err < 0) { 729e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_INDEX (%d)\n", __func__, err); 730e2132e0bSSanjay Lal ret = err; 731e2132e0bSSanjay Lal } 732e2132e0bSSanjay Lal err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_CONTEXT, 733e2132e0bSSanjay Lal &env->CP0_Context); 734e2132e0bSSanjay Lal if (err < 0) { 735e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_CONTEXT (%d)\n", __func__, err); 736e2132e0bSSanjay Lal ret = err; 737e2132e0bSSanjay Lal } 738e2132e0bSSanjay Lal err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_USERLOCAL, 739e2132e0bSSanjay Lal &env->active_tc.CP0_UserLocal); 740e2132e0bSSanjay Lal if (err < 0) { 741e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_USERLOCAL (%d)\n", __func__, err); 742e2132e0bSSanjay Lal ret = err; 743e2132e0bSSanjay Lal } 744e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PAGEMASK, 745e2132e0bSSanjay Lal &env->CP0_PageMask); 746e2132e0bSSanjay Lal if (err < 0) { 747e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_PAGEMASK (%d)\n", __func__, err); 748e2132e0bSSanjay Lal ret = err; 749e2132e0bSSanjay Lal } 750e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_WIRED, &env->CP0_Wired); 751e2132e0bSSanjay Lal if (err < 0) { 752e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_WIRED (%d)\n", __func__, err); 753e2132e0bSSanjay Lal ret = err; 754e2132e0bSSanjay Lal } 755e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_HWRENA, &env->CP0_HWREna); 756e2132e0bSSanjay Lal if (err < 0) { 757e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_HWRENA (%d)\n", __func__, err); 758e2132e0bSSanjay Lal ret = err; 759e2132e0bSSanjay Lal } 760e2132e0bSSanjay Lal err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_BADVADDR, 761e2132e0bSSanjay Lal &env->CP0_BadVAddr); 762e2132e0bSSanjay Lal if (err < 0) { 763e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_BADVADDR (%d)\n", __func__, err); 764e2132e0bSSanjay Lal ret = err; 765e2132e0bSSanjay Lal } 766e2132e0bSSanjay Lal 767e2132e0bSSanjay Lal /* If VM clock stopped then state will be restored when it is restarted */ 768e2132e0bSSanjay Lal if (runstate_is_running()) { 769e2132e0bSSanjay Lal err = kvm_mips_restore_count(cs); 770e2132e0bSSanjay Lal if (err < 0) { 771e2132e0bSSanjay Lal ret = err; 772e2132e0bSSanjay Lal } 773e2132e0bSSanjay Lal } 774e2132e0bSSanjay Lal 775e2132e0bSSanjay Lal err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ENTRYHI, 776e2132e0bSSanjay Lal &env->CP0_EntryHi); 777e2132e0bSSanjay Lal if (err < 0) { 778e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_ENTRYHI (%d)\n", __func__, err); 779e2132e0bSSanjay Lal ret = err; 780e2132e0bSSanjay Lal } 781e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_COMPARE, 782e2132e0bSSanjay Lal &env->CP0_Compare); 783e2132e0bSSanjay Lal if (err < 0) { 784e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_COMPARE (%d)\n", __func__, err); 785e2132e0bSSanjay Lal ret = err; 786e2132e0bSSanjay Lal } 787e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_STATUS, &env->CP0_Status); 788e2132e0bSSanjay Lal if (err < 0) { 789e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_STATUS (%d)\n", __func__, err); 790e2132e0bSSanjay Lal ret = err; 791e2132e0bSSanjay Lal } 792e2132e0bSSanjay Lal err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_EPC, &env->CP0_EPC); 793e2132e0bSSanjay Lal if (err < 0) { 794e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_EPC (%d)\n", __func__, err); 795e2132e0bSSanjay Lal ret = err; 796e2132e0bSSanjay Lal } 797461a1582SJames Hogan err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PRID, &env->CP0_PRid); 798461a1582SJames Hogan if (err < 0) { 799461a1582SJames Hogan DPRINTF("%s: Failed to put CP0_PRID (%d)\n", __func__, err); 800461a1582SJames Hogan ret = err; 801461a1582SJames Hogan } 80203cbfd7bSJames Hogan err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG, 80303cbfd7bSJames Hogan &env->CP0_Config0, 80403cbfd7bSJames Hogan KVM_REG_MIPS_CP0_CONFIG_MASK); 80503cbfd7bSJames Hogan if (err < 0) { 80603cbfd7bSJames Hogan DPRINTF("%s: Failed to change CP0_CONFIG (%d)\n", __func__, err); 80703cbfd7bSJames Hogan ret = err; 80803cbfd7bSJames Hogan } 80903cbfd7bSJames Hogan err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG1, 81003cbfd7bSJames Hogan &env->CP0_Config1, 81103cbfd7bSJames Hogan KVM_REG_MIPS_CP0_CONFIG1_MASK); 81203cbfd7bSJames Hogan if (err < 0) { 81303cbfd7bSJames Hogan DPRINTF("%s: Failed to change CP0_CONFIG1 (%d)\n", __func__, err); 81403cbfd7bSJames Hogan ret = err; 81503cbfd7bSJames Hogan } 81603cbfd7bSJames Hogan err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG2, 81703cbfd7bSJames Hogan &env->CP0_Config2, 81803cbfd7bSJames Hogan KVM_REG_MIPS_CP0_CONFIG2_MASK); 81903cbfd7bSJames Hogan if (err < 0) { 82003cbfd7bSJames Hogan DPRINTF("%s: Failed to change CP0_CONFIG2 (%d)\n", __func__, err); 82103cbfd7bSJames Hogan ret = err; 82203cbfd7bSJames Hogan } 82303cbfd7bSJames Hogan err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG3, 82403cbfd7bSJames Hogan &env->CP0_Config3, 82503cbfd7bSJames Hogan KVM_REG_MIPS_CP0_CONFIG3_MASK); 82603cbfd7bSJames Hogan if (err < 0) { 82703cbfd7bSJames Hogan DPRINTF("%s: Failed to change CP0_CONFIG3 (%d)\n", __func__, err); 82803cbfd7bSJames Hogan ret = err; 82903cbfd7bSJames Hogan } 83003cbfd7bSJames Hogan err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG4, 83103cbfd7bSJames Hogan &env->CP0_Config4, 83203cbfd7bSJames Hogan KVM_REG_MIPS_CP0_CONFIG4_MASK); 83303cbfd7bSJames Hogan if (err < 0) { 83403cbfd7bSJames Hogan DPRINTF("%s: Failed to change CP0_CONFIG4 (%d)\n", __func__, err); 83503cbfd7bSJames Hogan ret = err; 83603cbfd7bSJames Hogan } 83703cbfd7bSJames Hogan err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG5, 83803cbfd7bSJames Hogan &env->CP0_Config5, 83903cbfd7bSJames Hogan KVM_REG_MIPS_CP0_CONFIG5_MASK); 84003cbfd7bSJames Hogan if (err < 0) { 84103cbfd7bSJames Hogan DPRINTF("%s: Failed to change CP0_CONFIG5 (%d)\n", __func__, err); 84203cbfd7bSJames Hogan ret = err; 84303cbfd7bSJames Hogan } 844e2132e0bSSanjay Lal err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC, 845e2132e0bSSanjay Lal &env->CP0_ErrorEPC); 846e2132e0bSSanjay Lal if (err < 0) { 847e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_ERROREPC (%d)\n", __func__, err); 848e2132e0bSSanjay Lal ret = err; 849e2132e0bSSanjay Lal } 850e2132e0bSSanjay Lal 851e2132e0bSSanjay Lal return ret; 852e2132e0bSSanjay Lal } 853e2132e0bSSanjay Lal 854e2132e0bSSanjay Lal static int kvm_mips_get_cp0_registers(CPUState *cs) 855e2132e0bSSanjay Lal { 856e2132e0bSSanjay Lal MIPSCPU *cpu = MIPS_CPU(cs); 857e2132e0bSSanjay Lal CPUMIPSState *env = &cpu->env; 858e2132e0bSSanjay Lal int err, ret = 0; 859e2132e0bSSanjay Lal 860e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_INDEX, &env->CP0_Index); 861e2132e0bSSanjay Lal if (err < 0) { 862e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_INDEX (%d)\n", __func__, err); 863e2132e0bSSanjay Lal ret = err; 864e2132e0bSSanjay Lal } 865e2132e0bSSanjay Lal err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_CONTEXT, 866e2132e0bSSanjay Lal &env->CP0_Context); 867e2132e0bSSanjay Lal if (err < 0) { 868e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_CONTEXT (%d)\n", __func__, err); 869e2132e0bSSanjay Lal ret = err; 870e2132e0bSSanjay Lal } 871e2132e0bSSanjay Lal err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_USERLOCAL, 872e2132e0bSSanjay Lal &env->active_tc.CP0_UserLocal); 873e2132e0bSSanjay Lal if (err < 0) { 874e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_USERLOCAL (%d)\n", __func__, err); 875e2132e0bSSanjay Lal ret = err; 876e2132e0bSSanjay Lal } 877e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PAGEMASK, 878e2132e0bSSanjay Lal &env->CP0_PageMask); 879e2132e0bSSanjay Lal if (err < 0) { 880e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_PAGEMASK (%d)\n", __func__, err); 881e2132e0bSSanjay Lal ret = err; 882e2132e0bSSanjay Lal } 883e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_WIRED, &env->CP0_Wired); 884e2132e0bSSanjay Lal if (err < 0) { 885e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_WIRED (%d)\n", __func__, err); 886e2132e0bSSanjay Lal ret = err; 887e2132e0bSSanjay Lal } 888e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_HWRENA, &env->CP0_HWREna); 889e2132e0bSSanjay Lal if (err < 0) { 890e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_HWRENA (%d)\n", __func__, err); 891e2132e0bSSanjay Lal ret = err; 892e2132e0bSSanjay Lal } 893e2132e0bSSanjay Lal err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_BADVADDR, 894e2132e0bSSanjay Lal &env->CP0_BadVAddr); 895e2132e0bSSanjay Lal if (err < 0) { 896e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_BADVADDR (%d)\n", __func__, err); 897e2132e0bSSanjay Lal ret = err; 898e2132e0bSSanjay Lal } 899e2132e0bSSanjay Lal err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_ENTRYHI, 900e2132e0bSSanjay Lal &env->CP0_EntryHi); 901e2132e0bSSanjay Lal if (err < 0) { 902e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_ENTRYHI (%d)\n", __func__, err); 903e2132e0bSSanjay Lal ret = err; 904e2132e0bSSanjay Lal } 905e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_COMPARE, 906e2132e0bSSanjay Lal &env->CP0_Compare); 907e2132e0bSSanjay Lal if (err < 0) { 908e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_COMPARE (%d)\n", __func__, err); 909e2132e0bSSanjay Lal ret = err; 910e2132e0bSSanjay Lal } 911e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_STATUS, &env->CP0_Status); 912e2132e0bSSanjay Lal if (err < 0) { 913e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_STATUS (%d)\n", __func__, err); 914e2132e0bSSanjay Lal ret = err; 915e2132e0bSSanjay Lal } 916e2132e0bSSanjay Lal 917e2132e0bSSanjay Lal /* If VM clock stopped then state was already saved when it was stopped */ 918e2132e0bSSanjay Lal if (runstate_is_running()) { 919e2132e0bSSanjay Lal err = kvm_mips_save_count(cs); 920e2132e0bSSanjay Lal if (err < 0) { 921e2132e0bSSanjay Lal ret = err; 922e2132e0bSSanjay Lal } 923e2132e0bSSanjay Lal } 924e2132e0bSSanjay Lal 925e2132e0bSSanjay Lal err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_EPC, &env->CP0_EPC); 926e2132e0bSSanjay Lal if (err < 0) { 927e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_EPC (%d)\n", __func__, err); 928e2132e0bSSanjay Lal ret = err; 929e2132e0bSSanjay Lal } 930461a1582SJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PRID, &env->CP0_PRid); 931461a1582SJames Hogan if (err < 0) { 932461a1582SJames Hogan DPRINTF("%s: Failed to get CP0_PRID (%d)\n", __func__, err); 933461a1582SJames Hogan ret = err; 934461a1582SJames Hogan } 93503cbfd7bSJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG, &env->CP0_Config0); 93603cbfd7bSJames Hogan if (err < 0) { 93703cbfd7bSJames Hogan DPRINTF("%s: Failed to get CP0_CONFIG (%d)\n", __func__, err); 93803cbfd7bSJames Hogan ret = err; 93903cbfd7bSJames Hogan } 94003cbfd7bSJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG1, &env->CP0_Config1); 94103cbfd7bSJames Hogan if (err < 0) { 94203cbfd7bSJames Hogan DPRINTF("%s: Failed to get CP0_CONFIG1 (%d)\n", __func__, err); 94303cbfd7bSJames Hogan ret = err; 94403cbfd7bSJames Hogan } 94503cbfd7bSJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG2, &env->CP0_Config2); 94603cbfd7bSJames Hogan if (err < 0) { 94703cbfd7bSJames Hogan DPRINTF("%s: Failed to get CP0_CONFIG2 (%d)\n", __func__, err); 94803cbfd7bSJames Hogan ret = err; 94903cbfd7bSJames Hogan } 95003cbfd7bSJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG3, &env->CP0_Config3); 95103cbfd7bSJames Hogan if (err < 0) { 95203cbfd7bSJames Hogan DPRINTF("%s: Failed to get CP0_CONFIG3 (%d)\n", __func__, err); 95303cbfd7bSJames Hogan ret = err; 95403cbfd7bSJames Hogan } 95503cbfd7bSJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG4, &env->CP0_Config4); 95603cbfd7bSJames Hogan if (err < 0) { 95703cbfd7bSJames Hogan DPRINTF("%s: Failed to get CP0_CONFIG4 (%d)\n", __func__, err); 95803cbfd7bSJames Hogan ret = err; 95903cbfd7bSJames Hogan } 96003cbfd7bSJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG5, &env->CP0_Config5); 96103cbfd7bSJames Hogan if (err < 0) { 96203cbfd7bSJames Hogan DPRINTF("%s: Failed to get CP0_CONFIG5 (%d)\n", __func__, err); 96303cbfd7bSJames Hogan ret = err; 96403cbfd7bSJames Hogan } 965e2132e0bSSanjay Lal err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC, 966e2132e0bSSanjay Lal &env->CP0_ErrorEPC); 967e2132e0bSSanjay Lal if (err < 0) { 968e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_ERROREPC (%d)\n", __func__, err); 969e2132e0bSSanjay Lal ret = err; 970e2132e0bSSanjay Lal } 971e2132e0bSSanjay Lal 972e2132e0bSSanjay Lal return ret; 973e2132e0bSSanjay Lal } 974e2132e0bSSanjay Lal 975e2132e0bSSanjay Lal int kvm_arch_put_registers(CPUState *cs, int level) 976e2132e0bSSanjay Lal { 977e2132e0bSSanjay Lal MIPSCPU *cpu = MIPS_CPU(cs); 978e2132e0bSSanjay Lal CPUMIPSState *env = &cpu->env; 979e2132e0bSSanjay Lal struct kvm_regs regs; 980e2132e0bSSanjay Lal int ret; 981e2132e0bSSanjay Lal int i; 982e2132e0bSSanjay Lal 983e2132e0bSSanjay Lal /* Set the registers based on QEMU's view of things */ 984e2132e0bSSanjay Lal for (i = 0; i < 32; i++) { 98502dae26aSJames Hogan regs.gpr[i] = (int64_t)(target_long)env->active_tc.gpr[i]; 986e2132e0bSSanjay Lal } 987e2132e0bSSanjay Lal 98802dae26aSJames Hogan regs.hi = (int64_t)(target_long)env->active_tc.HI[0]; 98902dae26aSJames Hogan regs.lo = (int64_t)(target_long)env->active_tc.LO[0]; 99002dae26aSJames Hogan regs.pc = (int64_t)(target_long)env->active_tc.PC; 991e2132e0bSSanjay Lal 992e2132e0bSSanjay Lal ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s); 993e2132e0bSSanjay Lal 994e2132e0bSSanjay Lal if (ret < 0) { 995e2132e0bSSanjay Lal return ret; 996e2132e0bSSanjay Lal } 997e2132e0bSSanjay Lal 998e2132e0bSSanjay Lal ret = kvm_mips_put_cp0_registers(cs, level); 999e2132e0bSSanjay Lal if (ret < 0) { 1000e2132e0bSSanjay Lal return ret; 1001e2132e0bSSanjay Lal } 1002e2132e0bSSanjay Lal 1003152db36aSJames Hogan ret = kvm_mips_put_fpu_registers(cs, level); 1004152db36aSJames Hogan if (ret < 0) { 1005152db36aSJames Hogan return ret; 1006152db36aSJames Hogan } 1007152db36aSJames Hogan 1008e2132e0bSSanjay Lal return ret; 1009e2132e0bSSanjay Lal } 1010e2132e0bSSanjay Lal 1011e2132e0bSSanjay Lal int kvm_arch_get_registers(CPUState *cs) 1012e2132e0bSSanjay Lal { 1013e2132e0bSSanjay Lal MIPSCPU *cpu = MIPS_CPU(cs); 1014e2132e0bSSanjay Lal CPUMIPSState *env = &cpu->env; 1015e2132e0bSSanjay Lal int ret = 0; 1016e2132e0bSSanjay Lal struct kvm_regs regs; 1017e2132e0bSSanjay Lal int i; 1018e2132e0bSSanjay Lal 1019e2132e0bSSanjay Lal /* Get the current register set as KVM seems it */ 1020e2132e0bSSanjay Lal ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, ®s); 1021e2132e0bSSanjay Lal 1022e2132e0bSSanjay Lal if (ret < 0) { 1023e2132e0bSSanjay Lal return ret; 1024e2132e0bSSanjay Lal } 1025e2132e0bSSanjay Lal 1026e2132e0bSSanjay Lal for (i = 0; i < 32; i++) { 1027e2132e0bSSanjay Lal env->active_tc.gpr[i] = regs.gpr[i]; 1028e2132e0bSSanjay Lal } 1029e2132e0bSSanjay Lal 1030e2132e0bSSanjay Lal env->active_tc.HI[0] = regs.hi; 1031e2132e0bSSanjay Lal env->active_tc.LO[0] = regs.lo; 1032e2132e0bSSanjay Lal env->active_tc.PC = regs.pc; 1033e2132e0bSSanjay Lal 1034e2132e0bSSanjay Lal kvm_mips_get_cp0_registers(cs); 1035152db36aSJames Hogan kvm_mips_get_fpu_registers(cs); 1036e2132e0bSSanjay Lal 1037e2132e0bSSanjay Lal return ret; 1038e2132e0bSSanjay Lal } 10399e03a040SFrank Blaschka 10409e03a040SFrank Blaschka int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, 1041dc9f06caSPavel Fedin uint64_t address, uint32_t data, PCIDevice *dev) 10429e03a040SFrank Blaschka { 10439e03a040SFrank Blaschka return 0; 10449e03a040SFrank Blaschka } 10451850b6b7SEric Auger 104638d87493SPeter Xu int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route, 104738d87493SPeter Xu int vector, PCIDevice *dev) 104838d87493SPeter Xu { 104938d87493SPeter Xu return 0; 105038d87493SPeter Xu } 105138d87493SPeter Xu 105238d87493SPeter Xu int kvm_arch_release_virq_post(int virq) 105338d87493SPeter Xu { 105438d87493SPeter Xu return 0; 105538d87493SPeter Xu } 105638d87493SPeter Xu 10571850b6b7SEric Auger int kvm_arch_msi_data_to_gsi(uint32_t data) 10581850b6b7SEric Auger { 10591850b6b7SEric Auger abort(); 10601850b6b7SEric Auger } 1061