1537ba9daSTianrui Zhao /* SPDX-License-Identifier: GPL-2.0-or-later */ 2537ba9daSTianrui Zhao /* 3537ba9daSTianrui Zhao * QEMU LoongArch KVM 4537ba9daSTianrui Zhao * 5537ba9daSTianrui Zhao * Copyright (c) 2023 Loongson Technology Corporation Limited 6537ba9daSTianrui Zhao */ 7537ba9daSTianrui Zhao 8537ba9daSTianrui Zhao #include "qemu/osdep.h" 9537ba9daSTianrui Zhao #include <sys/ioctl.h> 10537ba9daSTianrui Zhao #include <linux/kvm.h> 11537ba9daSTianrui Zhao 12537ba9daSTianrui Zhao #include "qemu/timer.h" 13537ba9daSTianrui Zhao #include "qemu/error-report.h" 14537ba9daSTianrui Zhao #include "qemu/main-loop.h" 15537ba9daSTianrui Zhao #include "sysemu/sysemu.h" 16537ba9daSTianrui Zhao #include "sysemu/kvm.h" 17537ba9daSTianrui Zhao #include "sysemu/kvm_int.h" 18537ba9daSTianrui Zhao #include "hw/pci/pci.h" 19537ba9daSTianrui Zhao #include "exec/memattrs.h" 20537ba9daSTianrui Zhao #include "exec/address-spaces.h" 21537ba9daSTianrui Zhao #include "hw/boards.h" 22537ba9daSTianrui Zhao #include "hw/irq.h" 23537ba9daSTianrui Zhao #include "qemu/log.h" 24537ba9daSTianrui Zhao #include "hw/loader.h" 25537ba9daSTianrui Zhao #include "sysemu/runstate.h" 26537ba9daSTianrui Zhao #include "cpu-csr.h" 27537ba9daSTianrui Zhao #include "kvm_loongarch.h" 28f8447436STianrui Zhao #include "trace.h" 29537ba9daSTianrui Zhao 30537ba9daSTianrui Zhao static bool cap_has_mp_state; 31537ba9daSTianrui Zhao const KVMCapabilityInfo kvm_arch_required_capabilities[] = { 32537ba9daSTianrui Zhao KVM_CAP_LAST_INFO 33537ba9daSTianrui Zhao }; 34537ba9daSTianrui Zhao 35f8447436STianrui Zhao static int kvm_loongarch_get_regs_core(CPUState *cs) 36f8447436STianrui Zhao { 37f8447436STianrui Zhao int ret = 0; 38f8447436STianrui Zhao int i; 39f8447436STianrui Zhao struct kvm_regs regs; 40f3b603b9SPhilippe Mathieu-Daudé CPULoongArchState *env = cpu_env(cs); 41f8447436STianrui Zhao 42f8447436STianrui Zhao /* Get the current register set as KVM seems it */ 43f8447436STianrui Zhao ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, ®s); 44f8447436STianrui Zhao if (ret < 0) { 45f8447436STianrui Zhao trace_kvm_failed_get_regs_core(strerror(errno)); 46f8447436STianrui Zhao return ret; 47f8447436STianrui Zhao } 48f8447436STianrui Zhao /* gpr[0] value is always 0 */ 49f8447436STianrui Zhao env->gpr[0] = 0; 50f8447436STianrui Zhao for (i = 1; i < 32; i++) { 51f8447436STianrui Zhao env->gpr[i] = regs.gpr[i]; 52f8447436STianrui Zhao } 53f8447436STianrui Zhao 54f8447436STianrui Zhao env->pc = regs.pc; 55f8447436STianrui Zhao return ret; 56f8447436STianrui Zhao } 57f8447436STianrui Zhao 58f8447436STianrui Zhao static int kvm_loongarch_put_regs_core(CPUState *cs) 59f8447436STianrui Zhao { 60f8447436STianrui Zhao int ret = 0; 61f8447436STianrui Zhao int i; 62f8447436STianrui Zhao struct kvm_regs regs; 63f3b603b9SPhilippe Mathieu-Daudé CPULoongArchState *env = cpu_env(cs); 64f8447436STianrui Zhao 65f8447436STianrui Zhao /* Set the registers based on QEMU's view of things */ 66f8447436STianrui Zhao for (i = 0; i < 32; i++) { 67f8447436STianrui Zhao regs.gpr[i] = env->gpr[i]; 68f8447436STianrui Zhao } 69f8447436STianrui Zhao 70f8447436STianrui Zhao regs.pc = env->pc; 71f8447436STianrui Zhao ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s); 72f8447436STianrui Zhao if (ret < 0) { 73f8447436STianrui Zhao trace_kvm_failed_put_regs_core(strerror(errno)); 74f8447436STianrui Zhao } 75f8447436STianrui Zhao 76f8447436STianrui Zhao return ret; 77f8447436STianrui Zhao } 78f8447436STianrui Zhao 79f8447436STianrui Zhao static int kvm_loongarch_get_csr(CPUState *cs) 80f8447436STianrui Zhao { 81f8447436STianrui Zhao int ret = 0; 82f3b603b9SPhilippe Mathieu-Daudé CPULoongArchState *env = cpu_env(cs); 83f8447436STianrui Zhao 84f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD), 85f8447436STianrui Zhao &env->CSR_CRMD); 86f8447436STianrui Zhao 87f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD), 88f8447436STianrui Zhao &env->CSR_PRMD); 89f8447436STianrui Zhao 90f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN), 91f8447436STianrui Zhao &env->CSR_EUEN); 92f8447436STianrui Zhao 93f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC), 94f8447436STianrui Zhao &env->CSR_MISC); 95f8447436STianrui Zhao 96f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG), 97f8447436STianrui Zhao &env->CSR_ECFG); 98f8447436STianrui Zhao 99f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT), 100f8447436STianrui Zhao &env->CSR_ESTAT); 101f8447436STianrui Zhao 102f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA), 103f8447436STianrui Zhao &env->CSR_ERA); 104f8447436STianrui Zhao 105f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV), 106f8447436STianrui Zhao &env->CSR_BADV); 107f8447436STianrui Zhao 108f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI), 109f8447436STianrui Zhao &env->CSR_BADI); 110f8447436STianrui Zhao 111f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY), 112f8447436STianrui Zhao &env->CSR_EENTRY); 113f8447436STianrui Zhao 114f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX), 115f8447436STianrui Zhao &env->CSR_TLBIDX); 116f8447436STianrui Zhao 117f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI), 118f8447436STianrui Zhao &env->CSR_TLBEHI); 119f8447436STianrui Zhao 120f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0), 121f8447436STianrui Zhao &env->CSR_TLBELO0); 122f8447436STianrui Zhao 123f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1), 124f8447436STianrui Zhao &env->CSR_TLBELO1); 125f8447436STianrui Zhao 126f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID), 127f8447436STianrui Zhao &env->CSR_ASID); 128f8447436STianrui Zhao 129f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL), 130f8447436STianrui Zhao &env->CSR_PGDL); 131f8447436STianrui Zhao 132f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH), 133f8447436STianrui Zhao &env->CSR_PGDH); 134f8447436STianrui Zhao 135f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD), 136f8447436STianrui Zhao &env->CSR_PGD); 137f8447436STianrui Zhao 138f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL), 139f8447436STianrui Zhao &env->CSR_PWCL); 140f8447436STianrui Zhao 141f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH), 142f8447436STianrui Zhao &env->CSR_PWCH); 143f8447436STianrui Zhao 144f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS), 145f8447436STianrui Zhao &env->CSR_STLBPS); 146f8447436STianrui Zhao 147f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG), 148f8447436STianrui Zhao &env->CSR_RVACFG); 149f8447436STianrui Zhao 150f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID), 151f8447436STianrui Zhao &env->CSR_CPUID); 152f8447436STianrui Zhao 153f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1), 154f8447436STianrui Zhao &env->CSR_PRCFG1); 155f8447436STianrui Zhao 156f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2), 157f8447436STianrui Zhao &env->CSR_PRCFG2); 158f8447436STianrui Zhao 159f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3), 160f8447436STianrui Zhao &env->CSR_PRCFG3); 161f8447436STianrui Zhao 162f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)), 163f8447436STianrui Zhao &env->CSR_SAVE[0]); 164f8447436STianrui Zhao 165f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)), 166f8447436STianrui Zhao &env->CSR_SAVE[1]); 167f8447436STianrui Zhao 168f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)), 169f8447436STianrui Zhao &env->CSR_SAVE[2]); 170f8447436STianrui Zhao 171f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)), 172f8447436STianrui Zhao &env->CSR_SAVE[3]); 173f8447436STianrui Zhao 174f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)), 175f8447436STianrui Zhao &env->CSR_SAVE[4]); 176f8447436STianrui Zhao 177f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)), 178f8447436STianrui Zhao &env->CSR_SAVE[5]); 179f8447436STianrui Zhao 180f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)), 181f8447436STianrui Zhao &env->CSR_SAVE[6]); 182f8447436STianrui Zhao 183f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)), 184f8447436STianrui Zhao &env->CSR_SAVE[7]); 185f8447436STianrui Zhao 186f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID), 187f8447436STianrui Zhao &env->CSR_TID); 188f8447436STianrui Zhao 189f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC), 190f8447436STianrui Zhao &env->CSR_CNTC); 191f8447436STianrui Zhao 192f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR), 193f8447436STianrui Zhao &env->CSR_TICLR); 194f8447436STianrui Zhao 195f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL), 196f8447436STianrui Zhao &env->CSR_LLBCTL); 197f8447436STianrui Zhao 198f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1), 199f8447436STianrui Zhao &env->CSR_IMPCTL1); 200f8447436STianrui Zhao 201f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2), 202f8447436STianrui Zhao &env->CSR_IMPCTL2); 203f8447436STianrui Zhao 204f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY), 205f8447436STianrui Zhao &env->CSR_TLBRENTRY); 206f8447436STianrui Zhao 207f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV), 208f8447436STianrui Zhao &env->CSR_TLBRBADV); 209f8447436STianrui Zhao 210f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA), 211f8447436STianrui Zhao &env->CSR_TLBRERA); 212f8447436STianrui Zhao 213f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE), 214f8447436STianrui Zhao &env->CSR_TLBRSAVE); 215f8447436STianrui Zhao 216f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0), 217f8447436STianrui Zhao &env->CSR_TLBRELO0); 218f8447436STianrui Zhao 219f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1), 220f8447436STianrui Zhao &env->CSR_TLBRELO1); 221f8447436STianrui Zhao 222f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI), 223f8447436STianrui Zhao &env->CSR_TLBREHI); 224f8447436STianrui Zhao 225f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD), 226f8447436STianrui Zhao &env->CSR_TLBRPRMD); 227f8447436STianrui Zhao 228f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)), 229f8447436STianrui Zhao &env->CSR_DMW[0]); 230f8447436STianrui Zhao 231f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)), 232f8447436STianrui Zhao &env->CSR_DMW[1]); 233f8447436STianrui Zhao 234f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)), 235f8447436STianrui Zhao &env->CSR_DMW[2]); 236f8447436STianrui Zhao 237f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)), 238f8447436STianrui Zhao &env->CSR_DMW[3]); 239f8447436STianrui Zhao 240f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL), 241f8447436STianrui Zhao &env->CSR_TVAL); 242f8447436STianrui Zhao 243f8447436STianrui Zhao ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG), 244f8447436STianrui Zhao &env->CSR_TCFG); 245f8447436STianrui Zhao 246f8447436STianrui Zhao return ret; 247f8447436STianrui Zhao } 248f8447436STianrui Zhao 24961f6e150SBibo Mao static int kvm_loongarch_put_csr(CPUState *cs, int level) 250f8447436STianrui Zhao { 251f8447436STianrui Zhao int ret = 0; 252f3b603b9SPhilippe Mathieu-Daudé CPULoongArchState *env = cpu_env(cs); 253f8447436STianrui Zhao 254f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD), 255f8447436STianrui Zhao &env->CSR_CRMD); 256f8447436STianrui Zhao 257f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD), 258f8447436STianrui Zhao &env->CSR_PRMD); 259f8447436STianrui Zhao 260f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN), 261f8447436STianrui Zhao &env->CSR_EUEN); 262f8447436STianrui Zhao 263f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC), 264f8447436STianrui Zhao &env->CSR_MISC); 265f8447436STianrui Zhao 266f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG), 267f8447436STianrui Zhao &env->CSR_ECFG); 268f8447436STianrui Zhao 269f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT), 270f8447436STianrui Zhao &env->CSR_ESTAT); 271f8447436STianrui Zhao 272f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA), 273f8447436STianrui Zhao &env->CSR_ERA); 274f8447436STianrui Zhao 275f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV), 276f8447436STianrui Zhao &env->CSR_BADV); 277f8447436STianrui Zhao 278f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI), 279f8447436STianrui Zhao &env->CSR_BADI); 280f8447436STianrui Zhao 281f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY), 282f8447436STianrui Zhao &env->CSR_EENTRY); 283f8447436STianrui Zhao 284f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX), 285f8447436STianrui Zhao &env->CSR_TLBIDX); 286f8447436STianrui Zhao 287f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI), 288f8447436STianrui Zhao &env->CSR_TLBEHI); 289f8447436STianrui Zhao 290f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0), 291f8447436STianrui Zhao &env->CSR_TLBELO0); 292f8447436STianrui Zhao 293f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1), 294f8447436STianrui Zhao &env->CSR_TLBELO1); 295f8447436STianrui Zhao 296f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID), 297f8447436STianrui Zhao &env->CSR_ASID); 298f8447436STianrui Zhao 299f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL), 300f8447436STianrui Zhao &env->CSR_PGDL); 301f8447436STianrui Zhao 302f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH), 303f8447436STianrui Zhao &env->CSR_PGDH); 304f8447436STianrui Zhao 305f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD), 306f8447436STianrui Zhao &env->CSR_PGD); 307f8447436STianrui Zhao 308f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL), 309f8447436STianrui Zhao &env->CSR_PWCL); 310f8447436STianrui Zhao 311f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH), 312f8447436STianrui Zhao &env->CSR_PWCH); 313f8447436STianrui Zhao 314f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS), 315f8447436STianrui Zhao &env->CSR_STLBPS); 316f8447436STianrui Zhao 317f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG), 318f8447436STianrui Zhao &env->CSR_RVACFG); 319f8447436STianrui Zhao 32061f6e150SBibo Mao /* CPUID is constant after poweron, it should be set only once */ 32161f6e150SBibo Mao if (level >= KVM_PUT_FULL_STATE) { 322f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID), 323f8447436STianrui Zhao &env->CSR_CPUID); 32461f6e150SBibo Mao } 325f8447436STianrui Zhao 326f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1), 327f8447436STianrui Zhao &env->CSR_PRCFG1); 328f8447436STianrui Zhao 329f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2), 330f8447436STianrui Zhao &env->CSR_PRCFG2); 331f8447436STianrui Zhao 332f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3), 333f8447436STianrui Zhao &env->CSR_PRCFG3); 334f8447436STianrui Zhao 335f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)), 336f8447436STianrui Zhao &env->CSR_SAVE[0]); 337f8447436STianrui Zhao 338f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)), 339f8447436STianrui Zhao &env->CSR_SAVE[1]); 340f8447436STianrui Zhao 341f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)), 342f8447436STianrui Zhao &env->CSR_SAVE[2]); 343f8447436STianrui Zhao 344f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)), 345f8447436STianrui Zhao &env->CSR_SAVE[3]); 346f8447436STianrui Zhao 347f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)), 348f8447436STianrui Zhao &env->CSR_SAVE[4]); 349f8447436STianrui Zhao 350f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)), 351f8447436STianrui Zhao &env->CSR_SAVE[5]); 352f8447436STianrui Zhao 353f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)), 354f8447436STianrui Zhao &env->CSR_SAVE[6]); 355f8447436STianrui Zhao 356f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)), 357f8447436STianrui Zhao &env->CSR_SAVE[7]); 358f8447436STianrui Zhao 359f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID), 360f8447436STianrui Zhao &env->CSR_TID); 361f8447436STianrui Zhao 362f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC), 363f8447436STianrui Zhao &env->CSR_CNTC); 364f8447436STianrui Zhao 365f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR), 366f8447436STianrui Zhao &env->CSR_TICLR); 367f8447436STianrui Zhao 368f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL), 369f8447436STianrui Zhao &env->CSR_LLBCTL); 370f8447436STianrui Zhao 371f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1), 372f8447436STianrui Zhao &env->CSR_IMPCTL1); 373f8447436STianrui Zhao 374f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2), 375f8447436STianrui Zhao &env->CSR_IMPCTL2); 376f8447436STianrui Zhao 377f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY), 378f8447436STianrui Zhao &env->CSR_TLBRENTRY); 379f8447436STianrui Zhao 380f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV), 381f8447436STianrui Zhao &env->CSR_TLBRBADV); 382f8447436STianrui Zhao 383f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA), 384f8447436STianrui Zhao &env->CSR_TLBRERA); 385f8447436STianrui Zhao 386f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE), 387f8447436STianrui Zhao &env->CSR_TLBRSAVE); 388f8447436STianrui Zhao 389f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0), 390f8447436STianrui Zhao &env->CSR_TLBRELO0); 391f8447436STianrui Zhao 392f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1), 393f8447436STianrui Zhao &env->CSR_TLBRELO1); 394f8447436STianrui Zhao 395f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI), 396f8447436STianrui Zhao &env->CSR_TLBREHI); 397f8447436STianrui Zhao 398f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD), 399f8447436STianrui Zhao &env->CSR_TLBRPRMD); 400f8447436STianrui Zhao 401f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)), 402f8447436STianrui Zhao &env->CSR_DMW[0]); 403f8447436STianrui Zhao 404f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)), 405f8447436STianrui Zhao &env->CSR_DMW[1]); 406f8447436STianrui Zhao 407f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)), 408f8447436STianrui Zhao &env->CSR_DMW[2]); 409f8447436STianrui Zhao 410f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)), 411f8447436STianrui Zhao &env->CSR_DMW[3]); 412f8447436STianrui Zhao /* 413f8447436STianrui Zhao * timer cfg must be put at last since it is used to enable 414f8447436STianrui Zhao * guest timer 415f8447436STianrui Zhao */ 416f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL), 417f8447436STianrui Zhao &env->CSR_TVAL); 418f8447436STianrui Zhao 419f8447436STianrui Zhao ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG), 420f8447436STianrui Zhao &env->CSR_TCFG); 421f8447436STianrui Zhao return ret; 422f8447436STianrui Zhao } 423f8447436STianrui Zhao 424f8447436STianrui Zhao static int kvm_loongarch_get_regs_fp(CPUState *cs) 425f8447436STianrui Zhao { 426f8447436STianrui Zhao int ret, i; 427f8447436STianrui Zhao struct kvm_fpu fpu; 428f3b603b9SPhilippe Mathieu-Daudé CPULoongArchState *env = cpu_env(cs); 429f8447436STianrui Zhao 430f8447436STianrui Zhao ret = kvm_vcpu_ioctl(cs, KVM_GET_FPU, &fpu); 431f8447436STianrui Zhao if (ret < 0) { 432f8447436STianrui Zhao trace_kvm_failed_get_fpu(strerror(errno)); 433f8447436STianrui Zhao return ret; 434f8447436STianrui Zhao } 435f8447436STianrui Zhao 436f8447436STianrui Zhao env->fcsr0 = fpu.fcsr; 437f8447436STianrui Zhao for (i = 0; i < 32; i++) { 438f8447436STianrui Zhao env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0]; 439f8447436STianrui Zhao } 440f8447436STianrui Zhao for (i = 0; i < 8; i++) { 441f8447436STianrui Zhao env->cf[i] = fpu.fcc & 0xFF; 442f8447436STianrui Zhao fpu.fcc = fpu.fcc >> 8; 443f8447436STianrui Zhao } 444f8447436STianrui Zhao 445f8447436STianrui Zhao return ret; 446f8447436STianrui Zhao } 447f8447436STianrui Zhao 448f8447436STianrui Zhao static int kvm_loongarch_put_regs_fp(CPUState *cs) 449f8447436STianrui Zhao { 450f8447436STianrui Zhao int ret, i; 451f8447436STianrui Zhao struct kvm_fpu fpu; 452f3b603b9SPhilippe Mathieu-Daudé CPULoongArchState *env = cpu_env(cs); 453f8447436STianrui Zhao 454f8447436STianrui Zhao fpu.fcsr = env->fcsr0; 455f8447436STianrui Zhao fpu.fcc = 0; 456f8447436STianrui Zhao for (i = 0; i < 32; i++) { 457f8447436STianrui Zhao fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0]; 458f8447436STianrui Zhao } 459f8447436STianrui Zhao 460f8447436STianrui Zhao for (i = 0; i < 8; i++) { 461f8447436STianrui Zhao fpu.fcc |= env->cf[i] << (8 * i); 462f8447436STianrui Zhao } 463f8447436STianrui Zhao 464f8447436STianrui Zhao ret = kvm_vcpu_ioctl(cs, KVM_SET_FPU, &fpu); 465f8447436STianrui Zhao if (ret < 0) { 466f8447436STianrui Zhao trace_kvm_failed_put_fpu(strerror(errno)); 467f8447436STianrui Zhao } 468f8447436STianrui Zhao 469f8447436STianrui Zhao return ret; 470f8447436STianrui Zhao } 471f8447436STianrui Zhao 472f8447436STianrui Zhao void kvm_arch_reset_vcpu(CPULoongArchState *env) 473f8447436STianrui Zhao { 474f8447436STianrui Zhao env->mp_state = KVM_MP_STATE_RUNNABLE; 475f8447436STianrui Zhao } 476f8447436STianrui Zhao 477f8447436STianrui Zhao static int kvm_loongarch_get_mpstate(CPUState *cs) 478f8447436STianrui Zhao { 479f8447436STianrui Zhao int ret = 0; 480f8447436STianrui Zhao struct kvm_mp_state mp_state; 481f3b603b9SPhilippe Mathieu-Daudé CPULoongArchState *env = cpu_env(cs); 482f8447436STianrui Zhao 483f8447436STianrui Zhao if (cap_has_mp_state) { 484f8447436STianrui Zhao ret = kvm_vcpu_ioctl(cs, KVM_GET_MP_STATE, &mp_state); 485f8447436STianrui Zhao if (ret) { 486f8447436STianrui Zhao trace_kvm_failed_get_mpstate(strerror(errno)); 487f8447436STianrui Zhao return ret; 488f8447436STianrui Zhao } 489f8447436STianrui Zhao env->mp_state = mp_state.mp_state; 490f8447436STianrui Zhao } 491f8447436STianrui Zhao 492f8447436STianrui Zhao return ret; 493f8447436STianrui Zhao } 494f8447436STianrui Zhao 495f8447436STianrui Zhao static int kvm_loongarch_put_mpstate(CPUState *cs) 496f8447436STianrui Zhao { 497f8447436STianrui Zhao int ret = 0; 498f8447436STianrui Zhao struct kvm_mp_state mp_state = { 499f3b603b9SPhilippe Mathieu-Daudé .mp_state = cpu_env(cs)->mp_state 500f8447436STianrui Zhao }; 501f8447436STianrui Zhao 502f8447436STianrui Zhao if (cap_has_mp_state) { 503f8447436STianrui Zhao ret = kvm_vcpu_ioctl(cs, KVM_SET_MP_STATE, &mp_state); 504f8447436STianrui Zhao if (ret) { 505f8447436STianrui Zhao trace_kvm_failed_put_mpstate(strerror(errno)); 506f8447436STianrui Zhao } 507f8447436STianrui Zhao } 508f8447436STianrui Zhao 509f8447436STianrui Zhao return ret; 510f8447436STianrui Zhao } 511f8447436STianrui Zhao 512f8447436STianrui Zhao static int kvm_loongarch_get_cpucfg(CPUState *cs) 513f8447436STianrui Zhao { 514f8447436STianrui Zhao int i, ret = 0; 515f8447436STianrui Zhao uint64_t val; 516f3b603b9SPhilippe Mathieu-Daudé CPULoongArchState *env = cpu_env(cs); 517f8447436STianrui Zhao 518f8447436STianrui Zhao for (i = 0; i < 21; i++) { 519f8447436STianrui Zhao ret = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val); 520f8447436STianrui Zhao if (ret < 0) { 521f8447436STianrui Zhao trace_kvm_failed_get_cpucfg(strerror(errno)); 522f8447436STianrui Zhao } 523f8447436STianrui Zhao env->cpucfg[i] = (uint32_t)val; 524f8447436STianrui Zhao } 525f8447436STianrui Zhao return ret; 526f8447436STianrui Zhao } 527f8447436STianrui Zhao 528fc700996SSong Gao static int kvm_check_cpucfg2(CPUState *cs) 529fc700996SSong Gao { 530fc700996SSong Gao int ret; 531fc700996SSong Gao uint64_t val; 532fc700996SSong Gao struct kvm_device_attr attr = { 533fc700996SSong Gao .group = KVM_LOONGARCH_VCPU_CPUCFG, 534fc700996SSong Gao .attr = 2, 535fc700996SSong Gao .addr = (uint64_t)&val, 536fc700996SSong Gao }; 537f3b603b9SPhilippe Mathieu-Daudé CPULoongArchState *env = cpu_env(cs); 538fc700996SSong Gao 539fc700996SSong Gao ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr); 540fc700996SSong Gao 541fc700996SSong Gao if (!ret) { 542fc700996SSong Gao kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr); 543fc700996SSong Gao env->cpucfg[2] &= val; 544fc700996SSong Gao 545fc700996SSong Gao if (FIELD_EX32(env->cpucfg[2], CPUCFG2, FP)) { 546fc700996SSong Gao /* The FP minimal version is 1. */ 547fc700996SSong Gao env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, FP_VER, 1); 548fc700996SSong Gao } 549fc700996SSong Gao 550fc700996SSong Gao if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LLFTP)) { 551fc700996SSong Gao /* The LLFTP minimal version is 1. */ 552fc700996SSong Gao env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LLFTP_VER, 1); 553fc700996SSong Gao } 554fc700996SSong Gao } 555fc700996SSong Gao 556fc700996SSong Gao return ret; 557fc700996SSong Gao } 558fc700996SSong Gao 559f8447436STianrui Zhao static int kvm_loongarch_put_cpucfg(CPUState *cs) 560f8447436STianrui Zhao { 561f8447436STianrui Zhao int i, ret = 0; 562f3b603b9SPhilippe Mathieu-Daudé CPULoongArchState *env = cpu_env(cs); 563f8447436STianrui Zhao uint64_t val; 564f8447436STianrui Zhao 565f8447436STianrui Zhao for (i = 0; i < 21; i++) { 566f8447436STianrui Zhao if (i == 2) { 567fc700996SSong Gao ret = kvm_check_cpucfg2(cs); 568fc700996SSong Gao if (ret) { 569fc700996SSong Gao return ret; 570f8447436STianrui Zhao } 571fc700996SSong Gao } 572fc700996SSong Gao val = env->cpucfg[i]; 573f8447436STianrui Zhao ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val); 574f8447436STianrui Zhao if (ret < 0) { 575f8447436STianrui Zhao trace_kvm_failed_put_cpucfg(strerror(errno)); 576f8447436STianrui Zhao } 577f8447436STianrui Zhao } 578f8447436STianrui Zhao return ret; 579f8447436STianrui Zhao } 580f8447436STianrui Zhao 581537ba9daSTianrui Zhao int kvm_arch_get_registers(CPUState *cs) 582537ba9daSTianrui Zhao { 583f8447436STianrui Zhao int ret; 584f8447436STianrui Zhao 585f8447436STianrui Zhao ret = kvm_loongarch_get_regs_core(cs); 586f8447436STianrui Zhao if (ret) { 587f8447436STianrui Zhao return ret; 588537ba9daSTianrui Zhao } 589f8447436STianrui Zhao 590*5872966dSBibo Mao ret = kvm_loongarch_get_cpucfg(cs); 591*5872966dSBibo Mao if (ret) { 592*5872966dSBibo Mao return ret; 593*5872966dSBibo Mao } 594*5872966dSBibo Mao 595f8447436STianrui Zhao ret = kvm_loongarch_get_csr(cs); 596f8447436STianrui Zhao if (ret) { 597f8447436STianrui Zhao return ret; 598f8447436STianrui Zhao } 599f8447436STianrui Zhao 600f8447436STianrui Zhao ret = kvm_loongarch_get_regs_fp(cs); 601f8447436STianrui Zhao if (ret) { 602f8447436STianrui Zhao return ret; 603f8447436STianrui Zhao } 604f8447436STianrui Zhao 605f8447436STianrui Zhao ret = kvm_loongarch_get_mpstate(cs); 606f8447436STianrui Zhao return ret; 607f8447436STianrui Zhao } 608f8447436STianrui Zhao 609537ba9daSTianrui Zhao int kvm_arch_put_registers(CPUState *cs, int level) 610537ba9daSTianrui Zhao { 611f8447436STianrui Zhao int ret; 612f8447436STianrui Zhao 613f8447436STianrui Zhao ret = kvm_loongarch_put_regs_core(cs); 614f8447436STianrui Zhao if (ret) { 615f8447436STianrui Zhao return ret; 616f8447436STianrui Zhao } 617f8447436STianrui Zhao 618*5872966dSBibo Mao ret = kvm_loongarch_put_cpucfg(cs); 619*5872966dSBibo Mao if (ret) { 620*5872966dSBibo Mao return ret; 621*5872966dSBibo Mao } 622*5872966dSBibo Mao 62361f6e150SBibo Mao ret = kvm_loongarch_put_csr(cs, level); 624f8447436STianrui Zhao if (ret) { 625f8447436STianrui Zhao return ret; 626f8447436STianrui Zhao } 627f8447436STianrui Zhao 628f8447436STianrui Zhao ret = kvm_loongarch_put_regs_fp(cs); 629f8447436STianrui Zhao if (ret) { 630f8447436STianrui Zhao return ret; 631f8447436STianrui Zhao } 632f8447436STianrui Zhao 633f8447436STianrui Zhao ret = kvm_loongarch_put_mpstate(cs); 634f8447436STianrui Zhao return ret; 635537ba9daSTianrui Zhao } 636537ba9daSTianrui Zhao 637d11681c9STianrui Zhao static void kvm_loongarch_vm_stage_change(void *opaque, bool running, 638d11681c9STianrui Zhao RunState state) 639d11681c9STianrui Zhao { 640d11681c9STianrui Zhao int ret; 641d11681c9STianrui Zhao CPUState *cs = opaque; 642d11681c9STianrui Zhao LoongArchCPU *cpu = LOONGARCH_CPU(cs); 643d11681c9STianrui Zhao 644d11681c9STianrui Zhao if (running) { 645d11681c9STianrui Zhao ret = kvm_set_one_reg(cs, KVM_REG_LOONGARCH_COUNTER, 646d11681c9STianrui Zhao &cpu->kvm_state_counter); 647d11681c9STianrui Zhao if (ret < 0) { 648d11681c9STianrui Zhao trace_kvm_failed_put_counter(strerror(errno)); 649d11681c9STianrui Zhao } 650d11681c9STianrui Zhao } else { 651d11681c9STianrui Zhao ret = kvm_get_one_reg(cs, KVM_REG_LOONGARCH_COUNTER, 652d11681c9STianrui Zhao &cpu->kvm_state_counter); 653d11681c9STianrui Zhao if (ret < 0) { 654d11681c9STianrui Zhao trace_kvm_failed_get_counter(strerror(errno)); 655d11681c9STianrui Zhao } 656d11681c9STianrui Zhao } 657d11681c9STianrui Zhao } 658d11681c9STianrui Zhao 659537ba9daSTianrui Zhao int kvm_arch_init_vcpu(CPUState *cs) 660537ba9daSTianrui Zhao { 661d11681c9STianrui Zhao qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs); 662537ba9daSTianrui Zhao return 0; 663537ba9daSTianrui Zhao } 664537ba9daSTianrui Zhao 665537ba9daSTianrui Zhao int kvm_arch_destroy_vcpu(CPUState *cs) 666537ba9daSTianrui Zhao { 667537ba9daSTianrui Zhao return 0; 668537ba9daSTianrui Zhao } 669537ba9daSTianrui Zhao 670537ba9daSTianrui Zhao unsigned long kvm_arch_vcpu_id(CPUState *cs) 671537ba9daSTianrui Zhao { 672537ba9daSTianrui Zhao return cs->cpu_index; 673537ba9daSTianrui Zhao } 674537ba9daSTianrui Zhao 675537ba9daSTianrui Zhao int kvm_arch_release_virq_post(int virq) 676537ba9daSTianrui Zhao { 677537ba9daSTianrui Zhao return 0; 678537ba9daSTianrui Zhao } 679537ba9daSTianrui Zhao 680537ba9daSTianrui Zhao int kvm_arch_msi_data_to_gsi(uint32_t data) 681537ba9daSTianrui Zhao { 682537ba9daSTianrui Zhao abort(); 683537ba9daSTianrui Zhao } 684537ba9daSTianrui Zhao 685537ba9daSTianrui Zhao int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, 686537ba9daSTianrui Zhao uint64_t address, uint32_t data, PCIDevice *dev) 687537ba9daSTianrui Zhao { 688537ba9daSTianrui Zhao return 0; 689537ba9daSTianrui Zhao } 690537ba9daSTianrui Zhao 691537ba9daSTianrui Zhao int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route, 692537ba9daSTianrui Zhao int vector, PCIDevice *dev) 693537ba9daSTianrui Zhao { 694537ba9daSTianrui Zhao return 0; 695537ba9daSTianrui Zhao } 696537ba9daSTianrui Zhao 697537ba9daSTianrui Zhao void kvm_arch_init_irq_routing(KVMState *s) 698537ba9daSTianrui Zhao { 699537ba9daSTianrui Zhao } 700537ba9daSTianrui Zhao 701537ba9daSTianrui Zhao int kvm_arch_get_default_type(MachineState *ms) 702537ba9daSTianrui Zhao { 703537ba9daSTianrui Zhao return 0; 704537ba9daSTianrui Zhao } 705537ba9daSTianrui Zhao 706537ba9daSTianrui Zhao int kvm_arch_init(MachineState *ms, KVMState *s) 707537ba9daSTianrui Zhao { 70841958c99STianrui Zhao cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE); 709537ba9daSTianrui Zhao return 0; 710537ba9daSTianrui Zhao } 711537ba9daSTianrui Zhao 712537ba9daSTianrui Zhao int kvm_arch_irqchip_create(KVMState *s) 713537ba9daSTianrui Zhao { 714537ba9daSTianrui Zhao return 0; 715537ba9daSTianrui Zhao } 716537ba9daSTianrui Zhao 717537ba9daSTianrui Zhao void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) 718537ba9daSTianrui Zhao { 719537ba9daSTianrui Zhao } 720537ba9daSTianrui Zhao 721537ba9daSTianrui Zhao MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) 722537ba9daSTianrui Zhao { 723537ba9daSTianrui Zhao return MEMTXATTRS_UNSPECIFIED; 724537ba9daSTianrui Zhao } 725537ba9daSTianrui Zhao 726537ba9daSTianrui Zhao int kvm_arch_process_async_events(CPUState *cs) 727537ba9daSTianrui Zhao { 728537ba9daSTianrui Zhao return cs->halted; 729537ba9daSTianrui Zhao } 730537ba9daSTianrui Zhao 731537ba9daSTianrui Zhao bool kvm_arch_stop_on_emulation_error(CPUState *cs) 732537ba9daSTianrui Zhao { 733537ba9daSTianrui Zhao return true; 734537ba9daSTianrui Zhao } 735537ba9daSTianrui Zhao 736537ba9daSTianrui Zhao int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) 737537ba9daSTianrui Zhao { 738a05a950fSTianrui Zhao int ret = 0; 739f3b603b9SPhilippe Mathieu-Daudé CPULoongArchState *env = cpu_env(cs); 740a05a950fSTianrui Zhao MemTxAttrs attrs = {}; 741a05a950fSTianrui Zhao 742a05a950fSTianrui Zhao attrs.requester_id = env_cpu(env)->cpu_index; 743a05a950fSTianrui Zhao 744a05a950fSTianrui Zhao trace_kvm_arch_handle_exit(run->exit_reason); 745a05a950fSTianrui Zhao switch (run->exit_reason) { 746a05a950fSTianrui Zhao case KVM_EXIT_LOONGARCH_IOCSR: 7475e90b8dbSBibo Mao address_space_rw(env->address_space_iocsr, 748a05a950fSTianrui Zhao run->iocsr_io.phys_addr, 749a05a950fSTianrui Zhao attrs, 750a05a950fSTianrui Zhao run->iocsr_io.data, 751a05a950fSTianrui Zhao run->iocsr_io.len, 752a05a950fSTianrui Zhao run->iocsr_io.is_write); 753a05a950fSTianrui Zhao break; 754a05a950fSTianrui Zhao default: 755a05a950fSTianrui Zhao ret = -1; 756a05a950fSTianrui Zhao warn_report("KVM: unknown exit reason %d", run->exit_reason); 757a05a950fSTianrui Zhao break; 758a05a950fSTianrui Zhao } 759a05a950fSTianrui Zhao return ret; 760537ba9daSTianrui Zhao } 761537ba9daSTianrui Zhao 7628dcbad51STianrui Zhao int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level) 7638dcbad51STianrui Zhao { 7648dcbad51STianrui Zhao struct kvm_interrupt intr; 7658dcbad51STianrui Zhao CPUState *cs = CPU(cpu); 7668dcbad51STianrui Zhao 7678dcbad51STianrui Zhao if (level) { 7688dcbad51STianrui Zhao intr.irq = irq; 7698dcbad51STianrui Zhao } else { 7708dcbad51STianrui Zhao intr.irq = -irq; 7718dcbad51STianrui Zhao } 7728dcbad51STianrui Zhao 7738dcbad51STianrui Zhao trace_kvm_set_intr(irq, level); 7748dcbad51STianrui Zhao return kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); 7758dcbad51STianrui Zhao } 7768dcbad51STianrui Zhao 777537ba9daSTianrui Zhao void kvm_arch_accel_class_init(ObjectClass *oc) 778537ba9daSTianrui Zhao { 779537ba9daSTianrui Zhao } 780