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" 19e2132e0bSSanjay Lal #include "qemu/error-report.h" 20e2132e0bSSanjay Lal #include "qemu/timer.h" 21e2132e0bSSanjay Lal #include "sysemu/sysemu.h" 22e2132e0bSSanjay Lal #include "sysemu/kvm.h" 23e2132e0bSSanjay Lal #include "sysemu/cpus.h" 24e2132e0bSSanjay Lal #include "kvm_mips.h" 254c663752SPaolo Bonzini #include "exec/memattrs.h" 26e2132e0bSSanjay Lal 27e2132e0bSSanjay Lal #define DEBUG_KVM 0 28e2132e0bSSanjay Lal 29e2132e0bSSanjay Lal #define DPRINTF(fmt, ...) \ 30e2132e0bSSanjay Lal do { if (DEBUG_KVM) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0) 31e2132e0bSSanjay Lal 32152db36aSJames Hogan static int kvm_mips_fpu_cap; 33bee62662SJames Hogan static int kvm_mips_msa_cap; 34152db36aSJames Hogan 35e2132e0bSSanjay Lal const KVMCapabilityInfo kvm_arch_required_capabilities[] = { 36e2132e0bSSanjay Lal KVM_CAP_LAST_INFO 37e2132e0bSSanjay Lal }; 38e2132e0bSSanjay Lal 39e2132e0bSSanjay Lal static void kvm_mips_update_state(void *opaque, int running, RunState state); 40e2132e0bSSanjay Lal 41e2132e0bSSanjay Lal unsigned long kvm_arch_vcpu_id(CPUState *cs) 42e2132e0bSSanjay Lal { 43e2132e0bSSanjay Lal return cs->cpu_index; 44e2132e0bSSanjay Lal } 45e2132e0bSSanjay Lal 46b16565b3SMarcel Apfelbaum int kvm_arch_init(MachineState *ms, KVMState *s) 47e2132e0bSSanjay Lal { 48e2132e0bSSanjay Lal /* MIPS has 128 signals */ 49e2132e0bSSanjay Lal kvm_set_sigmask_len(s, 16); 50e2132e0bSSanjay Lal 51152db36aSJames Hogan kvm_mips_fpu_cap = kvm_check_extension(s, KVM_CAP_MIPS_FPU); 52bee62662SJames Hogan kvm_mips_msa_cap = kvm_check_extension(s, KVM_CAP_MIPS_MSA); 53152db36aSJames Hogan 54e2132e0bSSanjay Lal DPRINTF("%s\n", __func__); 55e2132e0bSSanjay Lal return 0; 56e2132e0bSSanjay Lal } 57e2132e0bSSanjay Lal 58d525ffabSPaolo Bonzini int kvm_arch_irqchip_create(MachineState *ms, KVMState *s) 59d525ffabSPaolo Bonzini { 60d525ffabSPaolo Bonzini return 0; 61d525ffabSPaolo Bonzini } 62d525ffabSPaolo Bonzini 63e2132e0bSSanjay Lal int kvm_arch_init_vcpu(CPUState *cs) 64e2132e0bSSanjay Lal { 65152db36aSJames Hogan MIPSCPU *cpu = MIPS_CPU(cs); 66152db36aSJames Hogan CPUMIPSState *env = &cpu->env; 67e2132e0bSSanjay Lal int ret = 0; 68e2132e0bSSanjay Lal 69e2132e0bSSanjay Lal qemu_add_vm_change_state_handler(kvm_mips_update_state, cs); 70e2132e0bSSanjay Lal 71152db36aSJames Hogan if (kvm_mips_fpu_cap && env->CP0_Config1 & (1 << CP0C1_FP)) { 72152db36aSJames Hogan ret = kvm_vcpu_enable_cap(cs, KVM_CAP_MIPS_FPU, 0, 0); 73152db36aSJames Hogan if (ret < 0) { 74152db36aSJames Hogan /* mark unsupported so it gets disabled on reset */ 75152db36aSJames Hogan kvm_mips_fpu_cap = 0; 76152db36aSJames Hogan ret = 0; 77152db36aSJames Hogan } 78152db36aSJames Hogan } 79152db36aSJames Hogan 80bee62662SJames Hogan if (kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) { 81bee62662SJames Hogan ret = kvm_vcpu_enable_cap(cs, KVM_CAP_MIPS_MSA, 0, 0); 82bee62662SJames Hogan if (ret < 0) { 83bee62662SJames Hogan /* mark unsupported so it gets disabled on reset */ 84bee62662SJames Hogan kvm_mips_msa_cap = 0; 85bee62662SJames Hogan ret = 0; 86bee62662SJames Hogan } 87bee62662SJames Hogan } 88bee62662SJames Hogan 89e2132e0bSSanjay Lal DPRINTF("%s\n", __func__); 90e2132e0bSSanjay Lal return ret; 91e2132e0bSSanjay Lal } 92e2132e0bSSanjay Lal 93e2132e0bSSanjay Lal void kvm_mips_reset_vcpu(MIPSCPU *cpu) 94e2132e0bSSanjay Lal { 950e928b12SJames Hogan CPUMIPSState *env = &cpu->env; 960e928b12SJames Hogan 97152db36aSJames Hogan if (!kvm_mips_fpu_cap && env->CP0_Config1 & (1 << CP0C1_FP)) { 98*2ab4b135SAlistair Francis warn_report("KVM does not support FPU, disabling"); 990e928b12SJames Hogan env->CP0_Config1 &= ~(1 << CP0C1_FP); 1000e928b12SJames Hogan } 101bee62662SJames Hogan if (!kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) { 102*2ab4b135SAlistair Francis warn_report("KVM does not support MSA, disabling"); 103bee62662SJames Hogan env->CP0_Config3 &= ~(1 << CP0C3_MSAP); 104bee62662SJames Hogan } 1050e928b12SJames Hogan 106e2132e0bSSanjay Lal DPRINTF("%s\n", __func__); 107e2132e0bSSanjay Lal } 108e2132e0bSSanjay Lal 109e2132e0bSSanjay Lal int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) 110e2132e0bSSanjay Lal { 111e2132e0bSSanjay Lal DPRINTF("%s\n", __func__); 112e2132e0bSSanjay Lal return 0; 113e2132e0bSSanjay Lal } 114e2132e0bSSanjay Lal 115e2132e0bSSanjay Lal int kvm_arch_remove_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 static inline int cpu_mips_io_interrupts_pending(MIPSCPU *cpu) 122e2132e0bSSanjay Lal { 123e2132e0bSSanjay Lal CPUMIPSState *env = &cpu->env; 124e2132e0bSSanjay Lal 125e2132e0bSSanjay Lal return env->CP0_Cause & (0x1 << (2 + CP0Ca_IP)); 126e2132e0bSSanjay Lal } 127e2132e0bSSanjay Lal 128e2132e0bSSanjay Lal 129e2132e0bSSanjay Lal void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) 130e2132e0bSSanjay Lal { 131e2132e0bSSanjay Lal MIPSCPU *cpu = MIPS_CPU(cs); 132e2132e0bSSanjay Lal int r; 133e2132e0bSSanjay Lal struct kvm_mips_interrupt intr; 134e2132e0bSSanjay Lal 1354b8523eeSJan Kiszka qemu_mutex_lock_iothread(); 1364b8523eeSJan Kiszka 137e2132e0bSSanjay Lal if ((cs->interrupt_request & CPU_INTERRUPT_HARD) && 138e2132e0bSSanjay Lal cpu_mips_io_interrupts_pending(cpu)) { 139e2132e0bSSanjay Lal intr.cpu = -1; 140e2132e0bSSanjay Lal intr.irq = 2; 141e2132e0bSSanjay Lal r = kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); 142e2132e0bSSanjay Lal if (r < 0) { 143e2132e0bSSanjay Lal error_report("%s: cpu %d: failed to inject IRQ %x", 144e2132e0bSSanjay Lal __func__, cs->cpu_index, intr.irq); 145e2132e0bSSanjay Lal } 146e2132e0bSSanjay Lal } 1474b8523eeSJan Kiszka 1484b8523eeSJan Kiszka qemu_mutex_unlock_iothread(); 149e2132e0bSSanjay Lal } 150e2132e0bSSanjay Lal 1514c663752SPaolo Bonzini MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) 152e2132e0bSSanjay Lal { 1534c663752SPaolo Bonzini return MEMTXATTRS_UNSPECIFIED; 154e2132e0bSSanjay Lal } 155e2132e0bSSanjay Lal 156e2132e0bSSanjay Lal int kvm_arch_process_async_events(CPUState *cs) 157e2132e0bSSanjay Lal { 158e2132e0bSSanjay Lal return cs->halted; 159e2132e0bSSanjay Lal } 160e2132e0bSSanjay Lal 161e2132e0bSSanjay Lal int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) 162e2132e0bSSanjay Lal { 163e2132e0bSSanjay Lal int ret; 164e2132e0bSSanjay Lal 165e2132e0bSSanjay Lal DPRINTF("%s\n", __func__); 166e2132e0bSSanjay Lal switch (run->exit_reason) { 167e2132e0bSSanjay Lal default: 168e2132e0bSSanjay Lal error_report("%s: unknown exit reason %d", 169e2132e0bSSanjay Lal __func__, run->exit_reason); 170e2132e0bSSanjay Lal ret = -1; 171e2132e0bSSanjay Lal break; 172e2132e0bSSanjay Lal } 173e2132e0bSSanjay Lal 174e2132e0bSSanjay Lal return ret; 175e2132e0bSSanjay Lal } 176e2132e0bSSanjay Lal 177e2132e0bSSanjay Lal bool kvm_arch_stop_on_emulation_error(CPUState *cs) 178e2132e0bSSanjay Lal { 179e2132e0bSSanjay Lal DPRINTF("%s\n", __func__); 180e2132e0bSSanjay Lal return true; 181e2132e0bSSanjay Lal } 182e2132e0bSSanjay Lal 183e2132e0bSSanjay Lal void kvm_arch_init_irq_routing(KVMState *s) 184e2132e0bSSanjay Lal { 185e2132e0bSSanjay Lal } 186e2132e0bSSanjay Lal 187e2132e0bSSanjay Lal int kvm_mips_set_interrupt(MIPSCPU *cpu, int irq, int level) 188e2132e0bSSanjay Lal { 189e2132e0bSSanjay Lal CPUState *cs = CPU(cpu); 190e2132e0bSSanjay Lal struct kvm_mips_interrupt intr; 191e2132e0bSSanjay Lal 192e2132e0bSSanjay Lal if (!kvm_enabled()) { 193e2132e0bSSanjay Lal return 0; 194e2132e0bSSanjay Lal } 195e2132e0bSSanjay Lal 196e2132e0bSSanjay Lal intr.cpu = -1; 197e2132e0bSSanjay Lal 198e2132e0bSSanjay Lal if (level) { 199e2132e0bSSanjay Lal intr.irq = irq; 200e2132e0bSSanjay Lal } else { 201e2132e0bSSanjay Lal intr.irq = -irq; 202e2132e0bSSanjay Lal } 203e2132e0bSSanjay Lal 204e2132e0bSSanjay Lal kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); 205e2132e0bSSanjay Lal 206e2132e0bSSanjay Lal return 0; 207e2132e0bSSanjay Lal } 208e2132e0bSSanjay Lal 209e2132e0bSSanjay Lal int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level) 210e2132e0bSSanjay Lal { 211e2132e0bSSanjay Lal CPUState *cs = current_cpu; 212e2132e0bSSanjay Lal CPUState *dest_cs = CPU(cpu); 213e2132e0bSSanjay Lal struct kvm_mips_interrupt intr; 214e2132e0bSSanjay Lal 215e2132e0bSSanjay Lal if (!kvm_enabled()) { 216e2132e0bSSanjay Lal return 0; 217e2132e0bSSanjay Lal } 218e2132e0bSSanjay Lal 219e2132e0bSSanjay Lal intr.cpu = dest_cs->cpu_index; 220e2132e0bSSanjay Lal 221e2132e0bSSanjay Lal if (level) { 222e2132e0bSSanjay Lal intr.irq = irq; 223e2132e0bSSanjay Lal } else { 224e2132e0bSSanjay Lal intr.irq = -irq; 225e2132e0bSSanjay Lal } 226e2132e0bSSanjay Lal 227e2132e0bSSanjay Lal DPRINTF("%s: CPU %d, IRQ: %d\n", __func__, intr.cpu, intr.irq); 228e2132e0bSSanjay Lal 229e2132e0bSSanjay Lal kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); 230e2132e0bSSanjay Lal 231e2132e0bSSanjay Lal return 0; 232e2132e0bSSanjay Lal } 233e2132e0bSSanjay Lal 234e2132e0bSSanjay Lal #define MIPS_CP0_32(_R, _S) \ 2355a2db896SJames Hogan (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U32 | (8 * (_R) + (_S))) 236e2132e0bSSanjay Lal 237e2132e0bSSanjay Lal #define MIPS_CP0_64(_R, _S) \ 2385a2db896SJames Hogan (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S))) 239e2132e0bSSanjay Lal 240e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_INDEX MIPS_CP0_32(0, 0) 241e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_CONTEXT MIPS_CP0_64(4, 0) 242e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_USERLOCAL MIPS_CP0_64(4, 2) 243e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_PAGEMASK MIPS_CP0_32(5, 0) 244e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_WIRED MIPS_CP0_32(6, 0) 245e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_HWRENA MIPS_CP0_32(7, 0) 246e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_BADVADDR MIPS_CP0_64(8, 0) 247e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_COUNT MIPS_CP0_32(9, 0) 248e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_ENTRYHI MIPS_CP0_64(10, 0) 249e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_COMPARE MIPS_CP0_32(11, 0) 250e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_STATUS MIPS_CP0_32(12, 0) 251e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_CAUSE MIPS_CP0_32(13, 0) 252e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_EPC MIPS_CP0_64(14, 0) 253461a1582SJames Hogan #define KVM_REG_MIPS_CP0_PRID MIPS_CP0_32(15, 0) 25403cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0) 25503cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG1 MIPS_CP0_32(16, 1) 25603cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG2 MIPS_CP0_32(16, 2) 25703cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG3 MIPS_CP0_32(16, 3) 25803cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG4 MIPS_CP0_32(16, 4) 25903cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG5 MIPS_CP0_32(16, 5) 260e2132e0bSSanjay Lal #define KVM_REG_MIPS_CP0_ERROREPC MIPS_CP0_64(30, 0) 261e2132e0bSSanjay Lal 262e2132e0bSSanjay Lal static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id, 263e2132e0bSSanjay Lal int32_t *addr) 264e2132e0bSSanjay Lal { 265e2132e0bSSanjay Lal struct kvm_one_reg cp0reg = { 266e2132e0bSSanjay Lal .id = reg_id, 267f8b3e48bSJames Hogan .addr = (uintptr_t)addr 268e2132e0bSSanjay Lal }; 269e2132e0bSSanjay Lal 270e2132e0bSSanjay Lal return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg); 271e2132e0bSSanjay Lal } 272e2132e0bSSanjay Lal 2730759487bSJames Hogan static inline int kvm_mips_put_one_ureg(CPUState *cs, uint64_t reg_id, 2740759487bSJames Hogan uint32_t *addr) 2750759487bSJames Hogan { 2760759487bSJames Hogan struct kvm_one_reg cp0reg = { 2770759487bSJames Hogan .id = reg_id, 2780759487bSJames Hogan .addr = (uintptr_t)addr 2790759487bSJames Hogan }; 2800759487bSJames Hogan 2810759487bSJames Hogan return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg); 2820759487bSJames Hogan } 2830759487bSJames Hogan 284e2132e0bSSanjay Lal static inline int kvm_mips_put_one_ulreg(CPUState *cs, uint64_t reg_id, 285e2132e0bSSanjay Lal target_ulong *addr) 286e2132e0bSSanjay Lal { 287e2132e0bSSanjay Lal uint64_t val64 = *addr; 288e2132e0bSSanjay Lal struct kvm_one_reg cp0reg = { 289e2132e0bSSanjay Lal .id = reg_id, 290e2132e0bSSanjay Lal .addr = (uintptr_t)&val64 291e2132e0bSSanjay Lal }; 292e2132e0bSSanjay Lal 293e2132e0bSSanjay Lal return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg); 294e2132e0bSSanjay Lal } 295e2132e0bSSanjay Lal 296e2132e0bSSanjay Lal static inline int kvm_mips_put_one_reg64(CPUState *cs, uint64_t reg_id, 297d319f83fSJames Hogan int64_t *addr) 298d319f83fSJames Hogan { 299d319f83fSJames Hogan struct kvm_one_reg cp0reg = { 300d319f83fSJames Hogan .id = reg_id, 301d319f83fSJames Hogan .addr = (uintptr_t)addr 302d319f83fSJames Hogan }; 303d319f83fSJames Hogan 304d319f83fSJames Hogan return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg); 305d319f83fSJames Hogan } 306d319f83fSJames Hogan 307d319f83fSJames Hogan static inline int kvm_mips_put_one_ureg64(CPUState *cs, uint64_t reg_id, 308e2132e0bSSanjay Lal uint64_t *addr) 309e2132e0bSSanjay Lal { 310e2132e0bSSanjay Lal struct kvm_one_reg cp0reg = { 311e2132e0bSSanjay Lal .id = reg_id, 312e2132e0bSSanjay Lal .addr = (uintptr_t)addr 313e2132e0bSSanjay Lal }; 314e2132e0bSSanjay Lal 315e2132e0bSSanjay Lal return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg); 316e2132e0bSSanjay Lal } 317e2132e0bSSanjay Lal 318e2132e0bSSanjay Lal static inline int kvm_mips_get_one_reg(CPUState *cs, uint64_t reg_id, 319e2132e0bSSanjay Lal int32_t *addr) 320e2132e0bSSanjay Lal { 321e2132e0bSSanjay Lal struct kvm_one_reg cp0reg = { 322e2132e0bSSanjay Lal .id = reg_id, 323f8b3e48bSJames Hogan .addr = (uintptr_t)addr 324e2132e0bSSanjay Lal }; 325e2132e0bSSanjay Lal 326f8b3e48bSJames Hogan return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg); 327e2132e0bSSanjay Lal } 328e2132e0bSSanjay Lal 3290759487bSJames Hogan static inline int kvm_mips_get_one_ureg(CPUState *cs, uint64_t reg_id, 3300759487bSJames Hogan uint32_t *addr) 3310759487bSJames Hogan { 3320759487bSJames Hogan struct kvm_one_reg cp0reg = { 3330759487bSJames Hogan .id = reg_id, 3340759487bSJames Hogan .addr = (uintptr_t)addr 3350759487bSJames Hogan }; 3360759487bSJames Hogan 3370759487bSJames Hogan return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg); 3380759487bSJames Hogan } 3390759487bSJames Hogan 340182f42fdSPeter Maydell static inline int kvm_mips_get_one_ulreg(CPUState *cs, uint64_t reg_id, 341e2132e0bSSanjay Lal target_ulong *addr) 342e2132e0bSSanjay Lal { 343e2132e0bSSanjay Lal int ret; 344e2132e0bSSanjay Lal uint64_t val64 = 0; 345e2132e0bSSanjay Lal struct kvm_one_reg cp0reg = { 346e2132e0bSSanjay Lal .id = reg_id, 347e2132e0bSSanjay Lal .addr = (uintptr_t)&val64 348e2132e0bSSanjay Lal }; 349e2132e0bSSanjay Lal 350e2132e0bSSanjay Lal ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg); 351e2132e0bSSanjay Lal if (ret >= 0) { 352e2132e0bSSanjay Lal *addr = val64; 353e2132e0bSSanjay Lal } 354e2132e0bSSanjay Lal return ret; 355e2132e0bSSanjay Lal } 356e2132e0bSSanjay Lal 357182f42fdSPeter Maydell static inline int kvm_mips_get_one_reg64(CPUState *cs, uint64_t reg_id, 358d319f83fSJames Hogan int64_t *addr) 359d319f83fSJames Hogan { 360d319f83fSJames Hogan struct kvm_one_reg cp0reg = { 361d319f83fSJames Hogan .id = reg_id, 362d319f83fSJames Hogan .addr = (uintptr_t)addr 363d319f83fSJames Hogan }; 364d319f83fSJames Hogan 365d319f83fSJames Hogan return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg); 366d319f83fSJames Hogan } 367d319f83fSJames Hogan 368d319f83fSJames Hogan static inline int kvm_mips_get_one_ureg64(CPUState *cs, uint64_t reg_id, 369e2132e0bSSanjay Lal uint64_t *addr) 370e2132e0bSSanjay Lal { 371e2132e0bSSanjay Lal struct kvm_one_reg cp0reg = { 372e2132e0bSSanjay Lal .id = reg_id, 373e2132e0bSSanjay Lal .addr = (uintptr_t)addr 374e2132e0bSSanjay Lal }; 375e2132e0bSSanjay Lal 376e2132e0bSSanjay Lal return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg); 377e2132e0bSSanjay Lal } 378e2132e0bSSanjay Lal 37903cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG_MASK (1U << CP0C0_M) 380152db36aSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG1_MASK ((1U << CP0C1_M) | \ 381152db36aSJames Hogan (1U << CP0C1_FP)) 38203cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG2_MASK (1U << CP0C2_M) 383bee62662SJames Hogan #define KVM_REG_MIPS_CP0_CONFIG3_MASK ((1U << CP0C3_M) | \ 384bee62662SJames Hogan (1U << CP0C3_MSAP)) 38503cbfd7bSJames Hogan #define KVM_REG_MIPS_CP0_CONFIG4_MASK (1U << CP0C4_M) 386bee62662SJames Hogan #define KVM_REG_MIPS_CP0_CONFIG5_MASK ((1U << CP0C5_MSAEn) | \ 387bee62662SJames Hogan (1U << CP0C5_UFE) | \ 388152db36aSJames Hogan (1U << CP0C5_FRE) | \ 389152db36aSJames Hogan (1U << CP0C5_UFR)) 39003cbfd7bSJames Hogan 39103cbfd7bSJames Hogan static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id, 39203cbfd7bSJames Hogan int32_t *addr, int32_t mask) 39303cbfd7bSJames Hogan { 39403cbfd7bSJames Hogan int err; 39503cbfd7bSJames Hogan int32_t tmp, change; 39603cbfd7bSJames Hogan 39703cbfd7bSJames Hogan err = kvm_mips_get_one_reg(cs, reg_id, &tmp); 39803cbfd7bSJames Hogan if (err < 0) { 39903cbfd7bSJames Hogan return err; 40003cbfd7bSJames Hogan } 40103cbfd7bSJames Hogan 40203cbfd7bSJames Hogan /* only change bits in mask */ 40303cbfd7bSJames Hogan change = (*addr ^ tmp) & mask; 40403cbfd7bSJames Hogan if (!change) { 40503cbfd7bSJames Hogan return 0; 40603cbfd7bSJames Hogan } 40703cbfd7bSJames Hogan 40803cbfd7bSJames Hogan tmp = tmp ^ change; 40903cbfd7bSJames Hogan return kvm_mips_put_one_reg(cs, reg_id, &tmp); 41003cbfd7bSJames Hogan } 41103cbfd7bSJames Hogan 412e2132e0bSSanjay Lal /* 413e2132e0bSSanjay Lal * We freeze the KVM timer when either the VM clock is stopped or the state is 414e2132e0bSSanjay Lal * saved (the state is dirty). 415e2132e0bSSanjay Lal */ 416e2132e0bSSanjay Lal 417e2132e0bSSanjay Lal /* 418e2132e0bSSanjay Lal * Save the state of the KVM timer when VM clock is stopped or state is synced 419e2132e0bSSanjay Lal * to QEMU. 420e2132e0bSSanjay Lal */ 421e2132e0bSSanjay Lal static int kvm_mips_save_count(CPUState *cs) 422e2132e0bSSanjay Lal { 423e2132e0bSSanjay Lal MIPSCPU *cpu = MIPS_CPU(cs); 424e2132e0bSSanjay Lal CPUMIPSState *env = &cpu->env; 425e2132e0bSSanjay Lal uint64_t count_ctl; 426e2132e0bSSanjay Lal int err, ret = 0; 427e2132e0bSSanjay Lal 428e2132e0bSSanjay Lal /* freeze KVM timer */ 429d319f83fSJames Hogan err = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl); 430e2132e0bSSanjay Lal if (err < 0) { 431e2132e0bSSanjay Lal DPRINTF("%s: Failed to get COUNT_CTL (%d)\n", __func__, err); 432e2132e0bSSanjay Lal ret = err; 433e2132e0bSSanjay Lal } else if (!(count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) { 434e2132e0bSSanjay Lal count_ctl |= KVM_REG_MIPS_COUNT_CTL_DC; 435d319f83fSJames Hogan err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl); 436e2132e0bSSanjay Lal if (err < 0) { 437e2132e0bSSanjay Lal DPRINTF("%s: Failed to set COUNT_CTL.DC=1 (%d)\n", __func__, err); 438e2132e0bSSanjay Lal ret = err; 439e2132e0bSSanjay Lal } 440e2132e0bSSanjay Lal } 441e2132e0bSSanjay Lal 442e2132e0bSSanjay Lal /* read CP0_Cause */ 443e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CAUSE, &env->CP0_Cause); 444e2132e0bSSanjay Lal if (err < 0) { 445e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_CAUSE (%d)\n", __func__, err); 446e2132e0bSSanjay Lal ret = err; 447e2132e0bSSanjay Lal } 448e2132e0bSSanjay Lal 449e2132e0bSSanjay Lal /* read CP0_Count */ 450e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_COUNT, &env->CP0_Count); 451e2132e0bSSanjay Lal if (err < 0) { 452e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_COUNT (%d)\n", __func__, err); 453e2132e0bSSanjay Lal ret = err; 454e2132e0bSSanjay Lal } 455e2132e0bSSanjay Lal 456e2132e0bSSanjay Lal return ret; 457e2132e0bSSanjay Lal } 458e2132e0bSSanjay Lal 459e2132e0bSSanjay Lal /* 460e2132e0bSSanjay Lal * Restore the state of the KVM timer when VM clock is restarted or state is 461e2132e0bSSanjay Lal * synced to KVM. 462e2132e0bSSanjay Lal */ 463e2132e0bSSanjay Lal static int kvm_mips_restore_count(CPUState *cs) 464e2132e0bSSanjay Lal { 465e2132e0bSSanjay Lal MIPSCPU *cpu = MIPS_CPU(cs); 466e2132e0bSSanjay Lal CPUMIPSState *env = &cpu->env; 467e2132e0bSSanjay Lal uint64_t count_ctl; 468e2132e0bSSanjay Lal int err_dc, err, ret = 0; 469e2132e0bSSanjay Lal 470e2132e0bSSanjay Lal /* check the timer is frozen */ 471d319f83fSJames Hogan err_dc = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl); 472e2132e0bSSanjay Lal if (err_dc < 0) { 473e2132e0bSSanjay Lal DPRINTF("%s: Failed to get COUNT_CTL (%d)\n", __func__, err_dc); 474e2132e0bSSanjay Lal ret = err_dc; 475e2132e0bSSanjay Lal } else if (!(count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) { 476e2132e0bSSanjay Lal /* freeze timer (sets COUNT_RESUME for us) */ 477e2132e0bSSanjay Lal count_ctl |= KVM_REG_MIPS_COUNT_CTL_DC; 478d319f83fSJames Hogan err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl); 479e2132e0bSSanjay Lal if (err < 0) { 480e2132e0bSSanjay Lal DPRINTF("%s: Failed to set COUNT_CTL.DC=1 (%d)\n", __func__, err); 481e2132e0bSSanjay Lal ret = err; 482e2132e0bSSanjay Lal } 483e2132e0bSSanjay Lal } 484e2132e0bSSanjay Lal 485e2132e0bSSanjay Lal /* load CP0_Cause */ 486e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_CAUSE, &env->CP0_Cause); 487e2132e0bSSanjay Lal if (err < 0) { 488e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_CAUSE (%d)\n", __func__, err); 489e2132e0bSSanjay Lal ret = err; 490e2132e0bSSanjay Lal } 491e2132e0bSSanjay Lal 492e2132e0bSSanjay Lal /* load CP0_Count */ 493e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_COUNT, &env->CP0_Count); 494e2132e0bSSanjay Lal if (err < 0) { 495e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_COUNT (%d)\n", __func__, err); 496e2132e0bSSanjay Lal ret = err; 497e2132e0bSSanjay Lal } 498e2132e0bSSanjay Lal 499e2132e0bSSanjay Lal /* resume KVM timer */ 500e2132e0bSSanjay Lal if (err_dc >= 0) { 501e2132e0bSSanjay Lal count_ctl &= ~KVM_REG_MIPS_COUNT_CTL_DC; 502d319f83fSJames Hogan err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl); 503e2132e0bSSanjay Lal if (err < 0) { 504e2132e0bSSanjay Lal DPRINTF("%s: Failed to set COUNT_CTL.DC=0 (%d)\n", __func__, err); 505e2132e0bSSanjay Lal ret = err; 506e2132e0bSSanjay Lal } 507e2132e0bSSanjay Lal } 508e2132e0bSSanjay Lal 509e2132e0bSSanjay Lal return ret; 510e2132e0bSSanjay Lal } 511e2132e0bSSanjay Lal 512e2132e0bSSanjay Lal /* 513e2132e0bSSanjay Lal * Handle the VM clock being started or stopped 514e2132e0bSSanjay Lal */ 515e2132e0bSSanjay Lal static void kvm_mips_update_state(void *opaque, int running, RunState state) 516e2132e0bSSanjay Lal { 517e2132e0bSSanjay Lal CPUState *cs = opaque; 518e2132e0bSSanjay Lal int ret; 519e2132e0bSSanjay Lal uint64_t count_resume; 520e2132e0bSSanjay Lal 521e2132e0bSSanjay Lal /* 522e2132e0bSSanjay Lal * If state is already dirty (synced to QEMU) then the KVM timer state is 523e2132e0bSSanjay Lal * already saved and can be restored when it is synced back to KVM. 524e2132e0bSSanjay Lal */ 525e2132e0bSSanjay Lal if (!running) { 52699f31832SSergio Andres Gomez Del Real if (!cs->vcpu_dirty) { 527e2132e0bSSanjay Lal ret = kvm_mips_save_count(cs); 528e2132e0bSSanjay Lal if (ret < 0) { 529e2132e0bSSanjay Lal fprintf(stderr, "Failed saving count\n"); 530e2132e0bSSanjay Lal } 531e2132e0bSSanjay Lal } 532e2132e0bSSanjay Lal } else { 533e2132e0bSSanjay Lal /* Set clock restore time to now */ 534906b53a2SPaolo Bonzini count_resume = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); 535d319f83fSJames Hogan ret = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_RESUME, 536e2132e0bSSanjay Lal &count_resume); 537e2132e0bSSanjay Lal if (ret < 0) { 538e2132e0bSSanjay Lal fprintf(stderr, "Failed setting COUNT_RESUME\n"); 539e2132e0bSSanjay Lal return; 540e2132e0bSSanjay Lal } 541e2132e0bSSanjay Lal 54299f31832SSergio Andres Gomez Del Real if (!cs->vcpu_dirty) { 543e2132e0bSSanjay Lal ret = kvm_mips_restore_count(cs); 544e2132e0bSSanjay Lal if (ret < 0) { 545e2132e0bSSanjay Lal fprintf(stderr, "Failed restoring count\n"); 546e2132e0bSSanjay Lal } 547e2132e0bSSanjay Lal } 548e2132e0bSSanjay Lal } 549e2132e0bSSanjay Lal } 550e2132e0bSSanjay Lal 551152db36aSJames Hogan static int kvm_mips_put_fpu_registers(CPUState *cs, int level) 552152db36aSJames Hogan { 553152db36aSJames Hogan MIPSCPU *cpu = MIPS_CPU(cs); 554152db36aSJames Hogan CPUMIPSState *env = &cpu->env; 555152db36aSJames Hogan int err, ret = 0; 556152db36aSJames Hogan unsigned int i; 557152db36aSJames Hogan 558152db36aSJames Hogan /* Only put FPU state if we're emulating a CPU with an FPU */ 559152db36aSJames Hogan if (env->CP0_Config1 & (1 << CP0C1_FP)) { 560152db36aSJames Hogan /* FPU Control Registers */ 561152db36aSJames Hogan if (level == KVM_PUT_FULL_STATE) { 562152db36aSJames Hogan err = kvm_mips_put_one_ureg(cs, KVM_REG_MIPS_FCR_IR, 563152db36aSJames Hogan &env->active_fpu.fcr0); 564152db36aSJames Hogan if (err < 0) { 565152db36aSJames Hogan DPRINTF("%s: Failed to put FCR_IR (%d)\n", __func__, err); 566152db36aSJames Hogan ret = err; 567152db36aSJames Hogan } 568152db36aSJames Hogan } 569152db36aSJames Hogan err = kvm_mips_put_one_ureg(cs, KVM_REG_MIPS_FCR_CSR, 570152db36aSJames Hogan &env->active_fpu.fcr31); 571152db36aSJames Hogan if (err < 0) { 572152db36aSJames Hogan DPRINTF("%s: Failed to put FCR_CSR (%d)\n", __func__, err); 573152db36aSJames Hogan ret = err; 574152db36aSJames Hogan } 575152db36aSJames Hogan 576bee62662SJames Hogan /* 577bee62662SJames Hogan * FPU register state is a subset of MSA vector state, so don't put FPU 578bee62662SJames Hogan * registers if we're emulating a CPU with MSA. 579bee62662SJames Hogan */ 580bee62662SJames Hogan if (!(env->CP0_Config3 & (1 << CP0C3_MSAP))) { 581152db36aSJames Hogan /* Floating point registers */ 582152db36aSJames Hogan for (i = 0; i < 32; ++i) { 583152db36aSJames Hogan if (env->CP0_Status & (1 << CP0St_FR)) { 584152db36aSJames Hogan err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_FPR_64(i), 585152db36aSJames Hogan &env->active_fpu.fpr[i].d); 586152db36aSJames Hogan } else { 587152db36aSJames Hogan err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FPR_32(i), 588152db36aSJames Hogan &env->active_fpu.fpr[i].w[FP_ENDIAN_IDX]); 589152db36aSJames Hogan } 590152db36aSJames Hogan if (err < 0) { 591152db36aSJames Hogan DPRINTF("%s: Failed to put FPR%u (%d)\n", __func__, i, err); 592152db36aSJames Hogan ret = err; 593152db36aSJames Hogan } 594152db36aSJames Hogan } 595152db36aSJames Hogan } 596bee62662SJames Hogan } 597bee62662SJames Hogan 598bee62662SJames Hogan /* Only put MSA state if we're emulating a CPU with MSA */ 599bee62662SJames Hogan if (env->CP0_Config3 & (1 << CP0C3_MSAP)) { 600bee62662SJames Hogan /* MSA Control Registers */ 601bee62662SJames Hogan if (level == KVM_PUT_FULL_STATE) { 602bee62662SJames Hogan err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_MSA_IR, 603bee62662SJames Hogan &env->msair); 604bee62662SJames Hogan if (err < 0) { 605bee62662SJames Hogan DPRINTF("%s: Failed to put MSA_IR (%d)\n", __func__, err); 606bee62662SJames Hogan ret = err; 607bee62662SJames Hogan } 608bee62662SJames Hogan } 609bee62662SJames Hogan err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_MSA_CSR, 610bee62662SJames Hogan &env->active_tc.msacsr); 611bee62662SJames Hogan if (err < 0) { 612bee62662SJames Hogan DPRINTF("%s: Failed to put MSA_CSR (%d)\n", __func__, err); 613bee62662SJames Hogan ret = err; 614bee62662SJames Hogan } 615bee62662SJames Hogan 616bee62662SJames Hogan /* Vector registers (includes FP registers) */ 617bee62662SJames Hogan for (i = 0; i < 32; ++i) { 618bee62662SJames Hogan /* Big endian MSA not supported by QEMU yet anyway */ 619bee62662SJames Hogan err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_VEC_128(i), 620bee62662SJames Hogan env->active_fpu.fpr[i].wr.d); 621bee62662SJames Hogan if (err < 0) { 622bee62662SJames Hogan DPRINTF("%s: Failed to put VEC%u (%d)\n", __func__, i, err); 623bee62662SJames Hogan ret = err; 624bee62662SJames Hogan } 625bee62662SJames Hogan } 626bee62662SJames Hogan } 627152db36aSJames Hogan 628152db36aSJames Hogan return ret; 629152db36aSJames Hogan } 630152db36aSJames Hogan 631152db36aSJames Hogan static int kvm_mips_get_fpu_registers(CPUState *cs) 632152db36aSJames Hogan { 633152db36aSJames Hogan MIPSCPU *cpu = MIPS_CPU(cs); 634152db36aSJames Hogan CPUMIPSState *env = &cpu->env; 635152db36aSJames Hogan int err, ret = 0; 636152db36aSJames Hogan unsigned int i; 637152db36aSJames Hogan 638152db36aSJames Hogan /* Only get FPU state if we're emulating a CPU with an FPU */ 639152db36aSJames Hogan if (env->CP0_Config1 & (1 << CP0C1_FP)) { 640152db36aSJames Hogan /* FPU Control Registers */ 641152db36aSJames Hogan err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FCR_IR, 642152db36aSJames Hogan &env->active_fpu.fcr0); 643152db36aSJames Hogan if (err < 0) { 644152db36aSJames Hogan DPRINTF("%s: Failed to get FCR_IR (%d)\n", __func__, err); 645152db36aSJames Hogan ret = err; 646152db36aSJames Hogan } 647152db36aSJames Hogan err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FCR_CSR, 648152db36aSJames Hogan &env->active_fpu.fcr31); 649152db36aSJames Hogan if (err < 0) { 650152db36aSJames Hogan DPRINTF("%s: Failed to get FCR_CSR (%d)\n", __func__, err); 651152db36aSJames Hogan ret = err; 652152db36aSJames Hogan } else { 653152db36aSJames Hogan restore_fp_status(env); 654152db36aSJames Hogan } 655152db36aSJames Hogan 656bee62662SJames Hogan /* 657bee62662SJames Hogan * FPU register state is a subset of MSA vector state, so don't save FPU 658bee62662SJames Hogan * registers if we're emulating a CPU with MSA. 659bee62662SJames Hogan */ 660bee62662SJames Hogan if (!(env->CP0_Config3 & (1 << CP0C3_MSAP))) { 661152db36aSJames Hogan /* Floating point registers */ 662152db36aSJames Hogan for (i = 0; i < 32; ++i) { 663152db36aSJames Hogan if (env->CP0_Status & (1 << CP0St_FR)) { 664152db36aSJames Hogan err = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_FPR_64(i), 665152db36aSJames Hogan &env->active_fpu.fpr[i].d); 666152db36aSJames Hogan } else { 667152db36aSJames Hogan err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FPR_32(i), 668152db36aSJames Hogan &env->active_fpu.fpr[i].w[FP_ENDIAN_IDX]); 669152db36aSJames Hogan } 670152db36aSJames Hogan if (err < 0) { 671152db36aSJames Hogan DPRINTF("%s: Failed to get FPR%u (%d)\n", __func__, i, err); 672152db36aSJames Hogan ret = err; 673152db36aSJames Hogan } 674152db36aSJames Hogan } 675152db36aSJames Hogan } 676bee62662SJames Hogan } 677bee62662SJames Hogan 678bee62662SJames Hogan /* Only get MSA state if we're emulating a CPU with MSA */ 679bee62662SJames Hogan if (env->CP0_Config3 & (1 << CP0C3_MSAP)) { 680bee62662SJames Hogan /* MSA Control Registers */ 681bee62662SJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_MSA_IR, 682bee62662SJames Hogan &env->msair); 683bee62662SJames Hogan if (err < 0) { 684bee62662SJames Hogan DPRINTF("%s: Failed to get MSA_IR (%d)\n", __func__, err); 685bee62662SJames Hogan ret = err; 686bee62662SJames Hogan } 687bee62662SJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_MSA_CSR, 688bee62662SJames Hogan &env->active_tc.msacsr); 689bee62662SJames Hogan if (err < 0) { 690bee62662SJames Hogan DPRINTF("%s: Failed to get MSA_CSR (%d)\n", __func__, err); 691bee62662SJames Hogan ret = err; 692bee62662SJames Hogan } else { 693bee62662SJames Hogan restore_msa_fp_status(env); 694bee62662SJames Hogan } 695bee62662SJames Hogan 696bee62662SJames Hogan /* Vector registers (includes FP registers) */ 697bee62662SJames Hogan for (i = 0; i < 32; ++i) { 698bee62662SJames Hogan /* Big endian MSA not supported by QEMU yet anyway */ 699bee62662SJames Hogan err = kvm_mips_get_one_reg64(cs, KVM_REG_MIPS_VEC_128(i), 700bee62662SJames Hogan env->active_fpu.fpr[i].wr.d); 701bee62662SJames Hogan if (err < 0) { 702bee62662SJames Hogan DPRINTF("%s: Failed to get VEC%u (%d)\n", __func__, i, err); 703bee62662SJames Hogan ret = err; 704bee62662SJames Hogan } 705bee62662SJames Hogan } 706bee62662SJames Hogan } 707152db36aSJames Hogan 708152db36aSJames Hogan return ret; 709152db36aSJames Hogan } 710152db36aSJames Hogan 711152db36aSJames Hogan 712e2132e0bSSanjay Lal static int kvm_mips_put_cp0_registers(CPUState *cs, int level) 713e2132e0bSSanjay Lal { 714e2132e0bSSanjay Lal MIPSCPU *cpu = MIPS_CPU(cs); 715e2132e0bSSanjay Lal CPUMIPSState *env = &cpu->env; 716e2132e0bSSanjay Lal int err, ret = 0; 717e2132e0bSSanjay Lal 718e2132e0bSSanjay Lal (void)level; 719e2132e0bSSanjay Lal 720e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_INDEX, &env->CP0_Index); 721e2132e0bSSanjay Lal if (err < 0) { 722e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_INDEX (%d)\n", __func__, err); 723e2132e0bSSanjay Lal ret = err; 724e2132e0bSSanjay Lal } 725e2132e0bSSanjay Lal err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_CONTEXT, 726e2132e0bSSanjay Lal &env->CP0_Context); 727e2132e0bSSanjay Lal if (err < 0) { 728e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_CONTEXT (%d)\n", __func__, err); 729e2132e0bSSanjay Lal ret = err; 730e2132e0bSSanjay Lal } 731e2132e0bSSanjay Lal err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_USERLOCAL, 732e2132e0bSSanjay Lal &env->active_tc.CP0_UserLocal); 733e2132e0bSSanjay Lal if (err < 0) { 734e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_USERLOCAL (%d)\n", __func__, err); 735e2132e0bSSanjay Lal ret = err; 736e2132e0bSSanjay Lal } 737e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PAGEMASK, 738e2132e0bSSanjay Lal &env->CP0_PageMask); 739e2132e0bSSanjay Lal if (err < 0) { 740e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_PAGEMASK (%d)\n", __func__, err); 741e2132e0bSSanjay Lal ret = err; 742e2132e0bSSanjay Lal } 743e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_WIRED, &env->CP0_Wired); 744e2132e0bSSanjay Lal if (err < 0) { 745e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_WIRED (%d)\n", __func__, err); 746e2132e0bSSanjay Lal ret = err; 747e2132e0bSSanjay Lal } 748e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_HWRENA, &env->CP0_HWREna); 749e2132e0bSSanjay Lal if (err < 0) { 750e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_HWRENA (%d)\n", __func__, err); 751e2132e0bSSanjay Lal ret = err; 752e2132e0bSSanjay Lal } 753e2132e0bSSanjay Lal err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_BADVADDR, 754e2132e0bSSanjay Lal &env->CP0_BadVAddr); 755e2132e0bSSanjay Lal if (err < 0) { 756e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_BADVADDR (%d)\n", __func__, err); 757e2132e0bSSanjay Lal ret = err; 758e2132e0bSSanjay Lal } 759e2132e0bSSanjay Lal 760e2132e0bSSanjay Lal /* If VM clock stopped then state will be restored when it is restarted */ 761e2132e0bSSanjay Lal if (runstate_is_running()) { 762e2132e0bSSanjay Lal err = kvm_mips_restore_count(cs); 763e2132e0bSSanjay Lal if (err < 0) { 764e2132e0bSSanjay Lal ret = err; 765e2132e0bSSanjay Lal } 766e2132e0bSSanjay Lal } 767e2132e0bSSanjay Lal 768e2132e0bSSanjay Lal err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ENTRYHI, 769e2132e0bSSanjay Lal &env->CP0_EntryHi); 770e2132e0bSSanjay Lal if (err < 0) { 771e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_ENTRYHI (%d)\n", __func__, err); 772e2132e0bSSanjay Lal ret = err; 773e2132e0bSSanjay Lal } 774e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_COMPARE, 775e2132e0bSSanjay Lal &env->CP0_Compare); 776e2132e0bSSanjay Lal if (err < 0) { 777e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_COMPARE (%d)\n", __func__, err); 778e2132e0bSSanjay Lal ret = err; 779e2132e0bSSanjay Lal } 780e2132e0bSSanjay Lal err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_STATUS, &env->CP0_Status); 781e2132e0bSSanjay Lal if (err < 0) { 782e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_STATUS (%d)\n", __func__, err); 783e2132e0bSSanjay Lal ret = err; 784e2132e0bSSanjay Lal } 785e2132e0bSSanjay Lal err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_EPC, &env->CP0_EPC); 786e2132e0bSSanjay Lal if (err < 0) { 787e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_EPC (%d)\n", __func__, err); 788e2132e0bSSanjay Lal ret = err; 789e2132e0bSSanjay Lal } 790461a1582SJames Hogan err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PRID, &env->CP0_PRid); 791461a1582SJames Hogan if (err < 0) { 792461a1582SJames Hogan DPRINTF("%s: Failed to put CP0_PRID (%d)\n", __func__, err); 793461a1582SJames Hogan ret = err; 794461a1582SJames Hogan } 79503cbfd7bSJames Hogan err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG, 79603cbfd7bSJames Hogan &env->CP0_Config0, 79703cbfd7bSJames Hogan KVM_REG_MIPS_CP0_CONFIG_MASK); 79803cbfd7bSJames Hogan if (err < 0) { 79903cbfd7bSJames Hogan DPRINTF("%s: Failed to change CP0_CONFIG (%d)\n", __func__, err); 80003cbfd7bSJames Hogan ret = err; 80103cbfd7bSJames Hogan } 80203cbfd7bSJames Hogan err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG1, 80303cbfd7bSJames Hogan &env->CP0_Config1, 80403cbfd7bSJames Hogan KVM_REG_MIPS_CP0_CONFIG1_MASK); 80503cbfd7bSJames Hogan if (err < 0) { 80603cbfd7bSJames Hogan DPRINTF("%s: Failed to change CP0_CONFIG1 (%d)\n", __func__, err); 80703cbfd7bSJames Hogan ret = err; 80803cbfd7bSJames Hogan } 80903cbfd7bSJames Hogan err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG2, 81003cbfd7bSJames Hogan &env->CP0_Config2, 81103cbfd7bSJames Hogan KVM_REG_MIPS_CP0_CONFIG2_MASK); 81203cbfd7bSJames Hogan if (err < 0) { 81303cbfd7bSJames Hogan DPRINTF("%s: Failed to change CP0_CONFIG2 (%d)\n", __func__, err); 81403cbfd7bSJames Hogan ret = err; 81503cbfd7bSJames Hogan } 81603cbfd7bSJames Hogan err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG3, 81703cbfd7bSJames Hogan &env->CP0_Config3, 81803cbfd7bSJames Hogan KVM_REG_MIPS_CP0_CONFIG3_MASK); 81903cbfd7bSJames Hogan if (err < 0) { 82003cbfd7bSJames Hogan DPRINTF("%s: Failed to change CP0_CONFIG3 (%d)\n", __func__, err); 82103cbfd7bSJames Hogan ret = err; 82203cbfd7bSJames Hogan } 82303cbfd7bSJames Hogan err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG4, 82403cbfd7bSJames Hogan &env->CP0_Config4, 82503cbfd7bSJames Hogan KVM_REG_MIPS_CP0_CONFIG4_MASK); 82603cbfd7bSJames Hogan if (err < 0) { 82703cbfd7bSJames Hogan DPRINTF("%s: Failed to change CP0_CONFIG4 (%d)\n", __func__, err); 82803cbfd7bSJames Hogan ret = err; 82903cbfd7bSJames Hogan } 83003cbfd7bSJames Hogan err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG5, 83103cbfd7bSJames Hogan &env->CP0_Config5, 83203cbfd7bSJames Hogan KVM_REG_MIPS_CP0_CONFIG5_MASK); 83303cbfd7bSJames Hogan if (err < 0) { 83403cbfd7bSJames Hogan DPRINTF("%s: Failed to change CP0_CONFIG5 (%d)\n", __func__, err); 83503cbfd7bSJames Hogan ret = err; 83603cbfd7bSJames Hogan } 837e2132e0bSSanjay Lal err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC, 838e2132e0bSSanjay Lal &env->CP0_ErrorEPC); 839e2132e0bSSanjay Lal if (err < 0) { 840e2132e0bSSanjay Lal DPRINTF("%s: Failed to put CP0_ERROREPC (%d)\n", __func__, err); 841e2132e0bSSanjay Lal ret = err; 842e2132e0bSSanjay Lal } 843e2132e0bSSanjay Lal 844e2132e0bSSanjay Lal return ret; 845e2132e0bSSanjay Lal } 846e2132e0bSSanjay Lal 847e2132e0bSSanjay Lal static int kvm_mips_get_cp0_registers(CPUState *cs) 848e2132e0bSSanjay Lal { 849e2132e0bSSanjay Lal MIPSCPU *cpu = MIPS_CPU(cs); 850e2132e0bSSanjay Lal CPUMIPSState *env = &cpu->env; 851e2132e0bSSanjay Lal int err, ret = 0; 852e2132e0bSSanjay Lal 853e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_INDEX, &env->CP0_Index); 854e2132e0bSSanjay Lal if (err < 0) { 855e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_INDEX (%d)\n", __func__, err); 856e2132e0bSSanjay Lal ret = err; 857e2132e0bSSanjay Lal } 858e2132e0bSSanjay Lal err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_CONTEXT, 859e2132e0bSSanjay Lal &env->CP0_Context); 860e2132e0bSSanjay Lal if (err < 0) { 861e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_CONTEXT (%d)\n", __func__, err); 862e2132e0bSSanjay Lal ret = err; 863e2132e0bSSanjay Lal } 864e2132e0bSSanjay Lal err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_USERLOCAL, 865e2132e0bSSanjay Lal &env->active_tc.CP0_UserLocal); 866e2132e0bSSanjay Lal if (err < 0) { 867e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_USERLOCAL (%d)\n", __func__, err); 868e2132e0bSSanjay Lal ret = err; 869e2132e0bSSanjay Lal } 870e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PAGEMASK, 871e2132e0bSSanjay Lal &env->CP0_PageMask); 872e2132e0bSSanjay Lal if (err < 0) { 873e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_PAGEMASK (%d)\n", __func__, err); 874e2132e0bSSanjay Lal ret = err; 875e2132e0bSSanjay Lal } 876e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_WIRED, &env->CP0_Wired); 877e2132e0bSSanjay Lal if (err < 0) { 878e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_WIRED (%d)\n", __func__, err); 879e2132e0bSSanjay Lal ret = err; 880e2132e0bSSanjay Lal } 881e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_HWRENA, &env->CP0_HWREna); 882e2132e0bSSanjay Lal if (err < 0) { 883e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_HWRENA (%d)\n", __func__, err); 884e2132e0bSSanjay Lal ret = err; 885e2132e0bSSanjay Lal } 886e2132e0bSSanjay Lal err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_BADVADDR, 887e2132e0bSSanjay Lal &env->CP0_BadVAddr); 888e2132e0bSSanjay Lal if (err < 0) { 889e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_BADVADDR (%d)\n", __func__, err); 890e2132e0bSSanjay Lal ret = err; 891e2132e0bSSanjay Lal } 892e2132e0bSSanjay Lal err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_ENTRYHI, 893e2132e0bSSanjay Lal &env->CP0_EntryHi); 894e2132e0bSSanjay Lal if (err < 0) { 895e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_ENTRYHI (%d)\n", __func__, err); 896e2132e0bSSanjay Lal ret = err; 897e2132e0bSSanjay Lal } 898e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_COMPARE, 899e2132e0bSSanjay Lal &env->CP0_Compare); 900e2132e0bSSanjay Lal if (err < 0) { 901e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_COMPARE (%d)\n", __func__, err); 902e2132e0bSSanjay Lal ret = err; 903e2132e0bSSanjay Lal } 904e2132e0bSSanjay Lal err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_STATUS, &env->CP0_Status); 905e2132e0bSSanjay Lal if (err < 0) { 906e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_STATUS (%d)\n", __func__, err); 907e2132e0bSSanjay Lal ret = err; 908e2132e0bSSanjay Lal } 909e2132e0bSSanjay Lal 910e2132e0bSSanjay Lal /* If VM clock stopped then state was already saved when it was stopped */ 911e2132e0bSSanjay Lal if (runstate_is_running()) { 912e2132e0bSSanjay Lal err = kvm_mips_save_count(cs); 913e2132e0bSSanjay Lal if (err < 0) { 914e2132e0bSSanjay Lal ret = err; 915e2132e0bSSanjay Lal } 916e2132e0bSSanjay Lal } 917e2132e0bSSanjay Lal 918e2132e0bSSanjay Lal err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_EPC, &env->CP0_EPC); 919e2132e0bSSanjay Lal if (err < 0) { 920e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_EPC (%d)\n", __func__, err); 921e2132e0bSSanjay Lal ret = err; 922e2132e0bSSanjay Lal } 923461a1582SJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PRID, &env->CP0_PRid); 924461a1582SJames Hogan if (err < 0) { 925461a1582SJames Hogan DPRINTF("%s: Failed to get CP0_PRID (%d)\n", __func__, err); 926461a1582SJames Hogan ret = err; 927461a1582SJames Hogan } 92803cbfd7bSJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG, &env->CP0_Config0); 92903cbfd7bSJames Hogan if (err < 0) { 93003cbfd7bSJames Hogan DPRINTF("%s: Failed to get CP0_CONFIG (%d)\n", __func__, err); 93103cbfd7bSJames Hogan ret = err; 93203cbfd7bSJames Hogan } 93303cbfd7bSJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG1, &env->CP0_Config1); 93403cbfd7bSJames Hogan if (err < 0) { 93503cbfd7bSJames Hogan DPRINTF("%s: Failed to get CP0_CONFIG1 (%d)\n", __func__, err); 93603cbfd7bSJames Hogan ret = err; 93703cbfd7bSJames Hogan } 93803cbfd7bSJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG2, &env->CP0_Config2); 93903cbfd7bSJames Hogan if (err < 0) { 94003cbfd7bSJames Hogan DPRINTF("%s: Failed to get CP0_CONFIG2 (%d)\n", __func__, err); 94103cbfd7bSJames Hogan ret = err; 94203cbfd7bSJames Hogan } 94303cbfd7bSJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG3, &env->CP0_Config3); 94403cbfd7bSJames Hogan if (err < 0) { 94503cbfd7bSJames Hogan DPRINTF("%s: Failed to get CP0_CONFIG3 (%d)\n", __func__, err); 94603cbfd7bSJames Hogan ret = err; 94703cbfd7bSJames Hogan } 94803cbfd7bSJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG4, &env->CP0_Config4); 94903cbfd7bSJames Hogan if (err < 0) { 95003cbfd7bSJames Hogan DPRINTF("%s: Failed to get CP0_CONFIG4 (%d)\n", __func__, err); 95103cbfd7bSJames Hogan ret = err; 95203cbfd7bSJames Hogan } 95303cbfd7bSJames Hogan err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG5, &env->CP0_Config5); 95403cbfd7bSJames Hogan if (err < 0) { 95503cbfd7bSJames Hogan DPRINTF("%s: Failed to get CP0_CONFIG5 (%d)\n", __func__, err); 95603cbfd7bSJames Hogan ret = err; 95703cbfd7bSJames Hogan } 958e2132e0bSSanjay Lal err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC, 959e2132e0bSSanjay Lal &env->CP0_ErrorEPC); 960e2132e0bSSanjay Lal if (err < 0) { 961e2132e0bSSanjay Lal DPRINTF("%s: Failed to get CP0_ERROREPC (%d)\n", __func__, err); 962e2132e0bSSanjay Lal ret = err; 963e2132e0bSSanjay Lal } 964e2132e0bSSanjay Lal 965e2132e0bSSanjay Lal return ret; 966e2132e0bSSanjay Lal } 967e2132e0bSSanjay Lal 968e2132e0bSSanjay Lal int kvm_arch_put_registers(CPUState *cs, int level) 969e2132e0bSSanjay Lal { 970e2132e0bSSanjay Lal MIPSCPU *cpu = MIPS_CPU(cs); 971e2132e0bSSanjay Lal CPUMIPSState *env = &cpu->env; 972e2132e0bSSanjay Lal struct kvm_regs regs; 973e2132e0bSSanjay Lal int ret; 974e2132e0bSSanjay Lal int i; 975e2132e0bSSanjay Lal 976e2132e0bSSanjay Lal /* Set the registers based on QEMU's view of things */ 977e2132e0bSSanjay Lal for (i = 0; i < 32; i++) { 97802dae26aSJames Hogan regs.gpr[i] = (int64_t)(target_long)env->active_tc.gpr[i]; 979e2132e0bSSanjay Lal } 980e2132e0bSSanjay Lal 98102dae26aSJames Hogan regs.hi = (int64_t)(target_long)env->active_tc.HI[0]; 98202dae26aSJames Hogan regs.lo = (int64_t)(target_long)env->active_tc.LO[0]; 98302dae26aSJames Hogan regs.pc = (int64_t)(target_long)env->active_tc.PC; 984e2132e0bSSanjay Lal 985e2132e0bSSanjay Lal ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s); 986e2132e0bSSanjay Lal 987e2132e0bSSanjay Lal if (ret < 0) { 988e2132e0bSSanjay Lal return ret; 989e2132e0bSSanjay Lal } 990e2132e0bSSanjay Lal 991e2132e0bSSanjay Lal ret = kvm_mips_put_cp0_registers(cs, level); 992e2132e0bSSanjay Lal if (ret < 0) { 993e2132e0bSSanjay Lal return ret; 994e2132e0bSSanjay Lal } 995e2132e0bSSanjay Lal 996152db36aSJames Hogan ret = kvm_mips_put_fpu_registers(cs, level); 997152db36aSJames Hogan if (ret < 0) { 998152db36aSJames Hogan return ret; 999152db36aSJames Hogan } 1000152db36aSJames Hogan 1001e2132e0bSSanjay Lal return ret; 1002e2132e0bSSanjay Lal } 1003e2132e0bSSanjay Lal 1004e2132e0bSSanjay Lal int kvm_arch_get_registers(CPUState *cs) 1005e2132e0bSSanjay Lal { 1006e2132e0bSSanjay Lal MIPSCPU *cpu = MIPS_CPU(cs); 1007e2132e0bSSanjay Lal CPUMIPSState *env = &cpu->env; 1008e2132e0bSSanjay Lal int ret = 0; 1009e2132e0bSSanjay Lal struct kvm_regs regs; 1010e2132e0bSSanjay Lal int i; 1011e2132e0bSSanjay Lal 1012e2132e0bSSanjay Lal /* Get the current register set as KVM seems it */ 1013e2132e0bSSanjay Lal ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, ®s); 1014e2132e0bSSanjay Lal 1015e2132e0bSSanjay Lal if (ret < 0) { 1016e2132e0bSSanjay Lal return ret; 1017e2132e0bSSanjay Lal } 1018e2132e0bSSanjay Lal 1019e2132e0bSSanjay Lal for (i = 0; i < 32; i++) { 1020e2132e0bSSanjay Lal env->active_tc.gpr[i] = regs.gpr[i]; 1021e2132e0bSSanjay Lal } 1022e2132e0bSSanjay Lal 1023e2132e0bSSanjay Lal env->active_tc.HI[0] = regs.hi; 1024e2132e0bSSanjay Lal env->active_tc.LO[0] = regs.lo; 1025e2132e0bSSanjay Lal env->active_tc.PC = regs.pc; 1026e2132e0bSSanjay Lal 1027e2132e0bSSanjay Lal kvm_mips_get_cp0_registers(cs); 1028152db36aSJames Hogan kvm_mips_get_fpu_registers(cs); 1029e2132e0bSSanjay Lal 1030e2132e0bSSanjay Lal return ret; 1031e2132e0bSSanjay Lal } 10329e03a040SFrank Blaschka 10339e03a040SFrank Blaschka int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, 1034dc9f06caSPavel Fedin uint64_t address, uint32_t data, PCIDevice *dev) 10359e03a040SFrank Blaschka { 10369e03a040SFrank Blaschka return 0; 10379e03a040SFrank Blaschka } 10381850b6b7SEric Auger 103938d87493SPeter Xu int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route, 104038d87493SPeter Xu int vector, PCIDevice *dev) 104138d87493SPeter Xu { 104238d87493SPeter Xu return 0; 104338d87493SPeter Xu } 104438d87493SPeter Xu 104538d87493SPeter Xu int kvm_arch_release_virq_post(int virq) 104638d87493SPeter Xu { 104738d87493SPeter Xu return 0; 104838d87493SPeter Xu } 104938d87493SPeter Xu 10501850b6b7SEric Auger int kvm_arch_msi_data_to_gsi(uint32_t data) 10511850b6b7SEric Auger { 10521850b6b7SEric Auger abort(); 10531850b6b7SEric Auger } 1054