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