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