1*d9052a96SAnup Patel #include "kvm/csr.h" 22e996783SAnup Patel #include "kvm/kvm-cpu.h" 32e996783SAnup Patel #include "kvm/kvm.h" 42e996783SAnup Patel #include "kvm/virtio.h" 5721da166SAnup Patel #include "kvm/sbi.h" 62e996783SAnup Patel #include "kvm/term.h" 72e996783SAnup Patel 82e996783SAnup Patel #include <asm/ptrace.h> 92e996783SAnup Patel 102e996783SAnup Patel static int debug_fd; 112e996783SAnup Patel 122e996783SAnup Patel void kvm_cpu__set_debug_fd(int fd) 132e996783SAnup Patel { 142e996783SAnup Patel debug_fd = fd; 152e996783SAnup Patel } 162e996783SAnup Patel 172e996783SAnup Patel int kvm_cpu__get_debug_fd(void) 182e996783SAnup Patel { 192e996783SAnup Patel return debug_fd; 202e996783SAnup Patel } 212e996783SAnup Patel 222e996783SAnup Patel struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id) 232e996783SAnup Patel { 2442bfe448SAnup Patel struct kvm_cpu *vcpu; 2542bfe448SAnup Patel u64 timebase = 0; 269e9cfde5SAnup Patel unsigned long isa = 0, id = 0; 27a416fdc2SAnup Patel unsigned long masks[KVM_REG_RISCV_SBI_MULTI_REG_LAST + 1] = { 0 }; 28a416fdc2SAnup Patel int i, coalesced_offset, mmap_size; 2942bfe448SAnup Patel struct kvm_one_reg reg; 3042bfe448SAnup Patel 3142bfe448SAnup Patel vcpu = calloc(1, sizeof(struct kvm_cpu)); 3242bfe448SAnup Patel if (!vcpu) 332e996783SAnup Patel return NULL; 3442bfe448SAnup Patel 3542bfe448SAnup Patel vcpu->vcpu_fd = ioctl(kvm->vm_fd, KVM_CREATE_VCPU, cpu_id); 3642bfe448SAnup Patel if (vcpu->vcpu_fd < 0) 3742bfe448SAnup Patel die_perror("KVM_CREATE_VCPU ioctl"); 3842bfe448SAnup Patel 3942bfe448SAnup Patel reg.id = RISCV_CONFIG_REG(isa); 4042bfe448SAnup Patel reg.addr = (unsigned long)&isa; 4142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 4242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (config.isa)"); 4342bfe448SAnup Patel 4442bfe448SAnup Patel reg.id = RISCV_TIMER_REG(frequency); 4542bfe448SAnup Patel reg.addr = (unsigned long)&timebase; 4642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 4742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (timer.frequency)"); 4842bfe448SAnup Patel 4942bfe448SAnup Patel mmap_size = ioctl(kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0); 5042bfe448SAnup Patel if (mmap_size < 0) 5142bfe448SAnup Patel die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl"); 5242bfe448SAnup Patel 5342bfe448SAnup Patel vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED, 5442bfe448SAnup Patel vcpu->vcpu_fd, 0); 5542bfe448SAnup Patel if (vcpu->kvm_run == MAP_FAILED) 5642bfe448SAnup Patel die("unable to mmap vcpu fd"); 5742bfe448SAnup Patel 5842bfe448SAnup Patel coalesced_offset = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, 5942bfe448SAnup Patel KVM_CAP_COALESCED_MMIO); 6042bfe448SAnup Patel if (coalesced_offset) 6142bfe448SAnup Patel vcpu->ring = (void *)vcpu->kvm_run + 6242bfe448SAnup Patel (coalesced_offset * PAGE_SIZE); 6342bfe448SAnup Patel 6442bfe448SAnup Patel reg.id = RISCV_CONFIG_REG(isa); 6542bfe448SAnup Patel reg.addr = (unsigned long)&isa; 6642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 6742bfe448SAnup Patel die("KVM_SET_ONE_REG failed (config.isa)"); 6842bfe448SAnup Patel 699e9cfde5SAnup Patel if (kvm->cfg.arch.custom_mvendorid) { 709e9cfde5SAnup Patel id = kvm->cfg.arch.custom_mvendorid; 719e9cfde5SAnup Patel reg.id = RISCV_CONFIG_REG(mvendorid); 729e9cfde5SAnup Patel reg.addr = (unsigned long)&id; 739e9cfde5SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 749e9cfde5SAnup Patel die("KVM_SET_ONE_REG failed (config.mvendorid)"); 759e9cfde5SAnup Patel } 769e9cfde5SAnup Patel 779e9cfde5SAnup Patel if (kvm->cfg.arch.custom_marchid) { 789e9cfde5SAnup Patel id = kvm->cfg.arch.custom_marchid; 799e9cfde5SAnup Patel reg.id = RISCV_CONFIG_REG(marchid); 809e9cfde5SAnup Patel reg.addr = (unsigned long)&id; 819e9cfde5SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 829e9cfde5SAnup Patel die("KVM_SET_ONE_REG failed (config.marchid)"); 839e9cfde5SAnup Patel } 849e9cfde5SAnup Patel 859e9cfde5SAnup Patel if (kvm->cfg.arch.custom_mimpid) { 869e9cfde5SAnup Patel id = kvm->cfg.arch.custom_mimpid; 879e9cfde5SAnup Patel reg.id = RISCV_CONFIG_REG(mimpid); 889e9cfde5SAnup Patel reg.addr = (unsigned long)&id; 899e9cfde5SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 909e9cfde5SAnup Patel die("KVM_SET_ONE_REG failed (config.mimpid)"); 919e9cfde5SAnup Patel } 929e9cfde5SAnup Patel 93a416fdc2SAnup Patel for (i = 0; i < KVM_RISCV_SBI_EXT_MAX; i++) { 94a416fdc2SAnup Patel if (!kvm->cfg.arch.sbi_ext_disabled[i]) 95a416fdc2SAnup Patel continue; 96a416fdc2SAnup Patel masks[KVM_REG_RISCV_SBI_MULTI_REG(i)] |= 97a416fdc2SAnup Patel KVM_REG_RISCV_SBI_MULTI_MASK(i); 98a416fdc2SAnup Patel } 99a416fdc2SAnup Patel for (i = 0; i <= KVM_REG_RISCV_SBI_MULTI_REG_LAST; i++) { 100a416fdc2SAnup Patel if (!masks[i]) 101a416fdc2SAnup Patel continue; 102a416fdc2SAnup Patel 103a416fdc2SAnup Patel reg.id = RISCV_SBI_EXT_REG(KVM_REG_RISCV_SBI_MULTI_DIS, i); 104a416fdc2SAnup Patel reg.addr = (unsigned long)&masks[i]; 105a416fdc2SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 106a416fdc2SAnup Patel die("KVM_SET_ONE_REG failed (sbi_ext %d)", i); 107a416fdc2SAnup Patel } 108a416fdc2SAnup Patel 1094ddaa424SAnup Patel /* Force enable SBI debug console if not disabled from command line */ 1104ddaa424SAnup Patel if (!kvm->cfg.arch.sbi_ext_disabled[KVM_RISCV_SBI_EXT_DBCN]) { 1114ddaa424SAnup Patel id = 1; 1124ddaa424SAnup Patel reg.id = RISCV_SBI_EXT_REG(KVM_REG_RISCV_SBI_SINGLE, 1134ddaa424SAnup Patel KVM_RISCV_SBI_EXT_DBCN); 1144ddaa424SAnup Patel reg.addr = (unsigned long)&id; 1154ddaa424SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 1164ddaa424SAnup Patel pr_warning("KVM_SET_ONE_REG failed (sbi_ext %d)", 1174ddaa424SAnup Patel KVM_RISCV_SBI_EXT_DBCN); 1184ddaa424SAnup Patel } 1194ddaa424SAnup Patel 12042bfe448SAnup Patel /* Populate the vcpu structure. */ 12142bfe448SAnup Patel vcpu->kvm = kvm; 12242bfe448SAnup Patel vcpu->cpu_id = cpu_id; 12342bfe448SAnup Patel vcpu->riscv_isa = isa; 12442bfe448SAnup Patel vcpu->riscv_xlen = __riscv_xlen; 12542bfe448SAnup Patel vcpu->riscv_timebase = timebase; 12642bfe448SAnup Patel vcpu->is_running = true; 12742bfe448SAnup Patel 12842bfe448SAnup Patel return vcpu; 1292e996783SAnup Patel } 1302e996783SAnup Patel 1312e996783SAnup Patel void kvm_cpu__arch_nmi(struct kvm_cpu *cpu) 1322e996783SAnup Patel { 1332e996783SAnup Patel } 1342e996783SAnup Patel 1352e996783SAnup Patel void kvm_cpu__delete(struct kvm_cpu *vcpu) 1362e996783SAnup Patel { 13742bfe448SAnup Patel free(vcpu); 1382e996783SAnup Patel } 1392e996783SAnup Patel 140721da166SAnup Patel static bool kvm_cpu_riscv_sbi(struct kvm_cpu *vcpu) 141721da166SAnup Patel { 142721da166SAnup Patel char ch; 1434ddaa424SAnup Patel u64 addr; 144721da166SAnup Patel bool ret = true; 1454ddaa424SAnup Patel char *str_start, *str_end; 146721da166SAnup Patel int dfd = kvm_cpu__get_debug_fd(); 147721da166SAnup Patel 148721da166SAnup Patel switch (vcpu->kvm_run->riscv_sbi.extension_id) { 149721da166SAnup Patel case SBI_EXT_0_1_CONSOLE_PUTCHAR: 150721da166SAnup Patel ch = vcpu->kvm_run->riscv_sbi.args[0]; 151721da166SAnup Patel term_putc(&ch, 1, 0); 152721da166SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] = 0; 153721da166SAnup Patel break; 154721da166SAnup Patel case SBI_EXT_0_1_CONSOLE_GETCHAR: 155721da166SAnup Patel if (term_readable(0)) 156721da166SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] = 157721da166SAnup Patel term_getc(vcpu->kvm, 0); 158721da166SAnup Patel else 159721da166SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] = SBI_ERR_FAILURE; 160721da166SAnup Patel break; 1614ddaa424SAnup Patel case SBI_EXT_DBCN: 1624ddaa424SAnup Patel switch (vcpu->kvm_run->riscv_sbi.function_id) { 1634ddaa424SAnup Patel case SBI_EXT_DBCN_CONSOLE_WRITE: 1644ddaa424SAnup Patel case SBI_EXT_DBCN_CONSOLE_READ: 1654ddaa424SAnup Patel addr = vcpu->kvm_run->riscv_sbi.args[1]; 1664ddaa424SAnup Patel #if __riscv_xlen == 32 1674ddaa424SAnup Patel addr |= (u64)vcpu->kvm_run->riscv_sbi.args[2] << 32; 1684ddaa424SAnup Patel #endif 1694ddaa424SAnup Patel if (!vcpu->kvm_run->riscv_sbi.args[0]) 1704ddaa424SAnup Patel break; 1714ddaa424SAnup Patel str_start = guest_flat_to_host(vcpu->kvm, addr); 1724ddaa424SAnup Patel addr += vcpu->kvm_run->riscv_sbi.args[0] - 1; 1734ddaa424SAnup Patel str_end = guest_flat_to_host(vcpu->kvm, addr); 1744ddaa424SAnup Patel if (!str_start || !str_end) { 1754ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] = 1764ddaa424SAnup Patel SBI_ERR_INVALID_PARAM; 1774ddaa424SAnup Patel break; 1784ddaa424SAnup Patel } 1794ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[1] = 0; 1804ddaa424SAnup Patel while (str_start <= str_end) { 1814ddaa424SAnup Patel if (vcpu->kvm_run->riscv_sbi.function_id == 1824ddaa424SAnup Patel SBI_EXT_DBCN_CONSOLE_WRITE) { 1834ddaa424SAnup Patel term_putc(str_start, 1, 0); 1844ddaa424SAnup Patel } else { 1854ddaa424SAnup Patel if (!term_readable(0)) 1864ddaa424SAnup Patel break; 1874ddaa424SAnup Patel *str_start = term_getc(vcpu->kvm, 0); 1884ddaa424SAnup Patel } 1894ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[1]++; 1904ddaa424SAnup Patel str_start++; 1914ddaa424SAnup Patel } 1924ddaa424SAnup Patel break; 1934ddaa424SAnup Patel case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: 1944ddaa424SAnup Patel ch = vcpu->kvm_run->riscv_sbi.args[0]; 1954ddaa424SAnup Patel term_putc(&ch, 1, 0); 1964ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] = 0; 1974ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[1] = 0; 1984ddaa424SAnup Patel break; 1994ddaa424SAnup Patel default: 2004ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] = 2014ddaa424SAnup Patel SBI_ERR_NOT_SUPPORTED; 2024ddaa424SAnup Patel break; 2034ddaa424SAnup Patel } 2044ddaa424SAnup Patel break; 205721da166SAnup Patel default: 206721da166SAnup Patel dprintf(dfd, "Unhandled SBI call\n"); 207721da166SAnup Patel dprintf(dfd, "extension_id=0x%lx function_id=0x%lx\n", 208721da166SAnup Patel vcpu->kvm_run->riscv_sbi.extension_id, 209721da166SAnup Patel vcpu->kvm_run->riscv_sbi.function_id); 210721da166SAnup Patel dprintf(dfd, "args[0]=0x%lx args[1]=0x%lx\n", 211721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[0], 212721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[1]); 213721da166SAnup Patel dprintf(dfd, "args[2]=0x%lx args[3]=0x%lx\n", 214721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[2], 215721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[3]); 216721da166SAnup Patel dprintf(dfd, "args[4]=0x%lx args[5]=0x%lx\n", 217721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[4], 218721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[5]); 219721da166SAnup Patel ret = false; 220721da166SAnup Patel break; 221721da166SAnup Patel }; 222721da166SAnup Patel 223721da166SAnup Patel return ret; 224721da166SAnup Patel } 225721da166SAnup Patel 226*d9052a96SAnup Patel static bool kvm_cpu_riscv_csr(struct kvm_cpu *vcpu) 227*d9052a96SAnup Patel { 228*d9052a96SAnup Patel int dfd = kvm_cpu__get_debug_fd(); 229*d9052a96SAnup Patel bool ret = true; 230*d9052a96SAnup Patel 231*d9052a96SAnup Patel switch (vcpu->kvm_run->riscv_csr.csr_num) { 232*d9052a96SAnup Patel case CSR_SEED: 233*d9052a96SAnup Patel /* 234*d9052a96SAnup Patel * We ignore the new_value and write_mask and simply 235*d9052a96SAnup Patel * return a random value as SEED. 236*d9052a96SAnup Patel */ 237*d9052a96SAnup Patel vcpu->kvm_run->riscv_csr.ret_value = SEED_OPST_ES16; 238*d9052a96SAnup Patel vcpu->kvm_run->riscv_csr.ret_value |= rand() & SEED_ENTROPY_MASK; 239*d9052a96SAnup Patel break; 240*d9052a96SAnup Patel default: 241*d9052a96SAnup Patel dprintf(dfd, "Unhandled CSR access\n"); 242*d9052a96SAnup Patel dprintf(dfd, "csr_num=0x%lx new_value=0x%lx\n", 243*d9052a96SAnup Patel vcpu->kvm_run->riscv_csr.csr_num, 244*d9052a96SAnup Patel vcpu->kvm_run->riscv_csr.new_value); 245*d9052a96SAnup Patel dprintf(dfd, "write_mask=0x%lx ret_value=0x%lx\n", 246*d9052a96SAnup Patel vcpu->kvm_run->riscv_csr.write_mask, 247*d9052a96SAnup Patel vcpu->kvm_run->riscv_csr.ret_value); 248*d9052a96SAnup Patel ret = false; 249*d9052a96SAnup Patel break; 250*d9052a96SAnup Patel } 251*d9052a96SAnup Patel 252*d9052a96SAnup Patel return ret; 253*d9052a96SAnup Patel } 254*d9052a96SAnup Patel 2552e996783SAnup Patel bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu) 2562e996783SAnup Patel { 257721da166SAnup Patel switch (vcpu->kvm_run->exit_reason) { 258721da166SAnup Patel case KVM_EXIT_RISCV_SBI: 259721da166SAnup Patel return kvm_cpu_riscv_sbi(vcpu); 260*d9052a96SAnup Patel case KVM_EXIT_RISCV_CSR: 261*d9052a96SAnup Patel return kvm_cpu_riscv_csr(vcpu); 262721da166SAnup Patel default: 263721da166SAnup Patel break; 264721da166SAnup Patel }; 265721da166SAnup Patel 2662e996783SAnup Patel return false; 2672e996783SAnup Patel } 2682e996783SAnup Patel 2692e996783SAnup Patel void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu) 2702e996783SAnup Patel { 2712e996783SAnup Patel } 2722e996783SAnup Patel 2732e996783SAnup Patel void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu) 2742e996783SAnup Patel { 27542bfe448SAnup Patel struct kvm *kvm = vcpu->kvm; 27642bfe448SAnup Patel struct kvm_mp_state mp_state; 27742bfe448SAnup Patel struct kvm_one_reg reg; 27842bfe448SAnup Patel unsigned long data; 27942bfe448SAnup Patel 28042bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_MP_STATE, &mp_state) < 0) 28142bfe448SAnup Patel die_perror("KVM_GET_MP_STATE failed"); 28242bfe448SAnup Patel 28342bfe448SAnup Patel /* 28442bfe448SAnup Patel * If MP state is stopped then it means Linux KVM RISC-V emulates 28542bfe448SAnup Patel * SBI v0.2 (or higher) with HART power managment and give VCPU 28642bfe448SAnup Patel * will power-up at boot-time by boot VCPU. For such VCPU, we 28742bfe448SAnup Patel * don't update PC, A0 and A1 here. 28842bfe448SAnup Patel */ 28942bfe448SAnup Patel if (mp_state.mp_state == KVM_MP_STATE_STOPPED) 29042bfe448SAnup Patel return; 29142bfe448SAnup Patel 29242bfe448SAnup Patel reg.addr = (unsigned long)&data; 29342bfe448SAnup Patel 29442bfe448SAnup Patel data = kvm->arch.kern_guest_start; 29542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.pc); 29642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 29742bfe448SAnup Patel die_perror("KVM_SET_ONE_REG failed (pc)"); 29842bfe448SAnup Patel 29942bfe448SAnup Patel data = vcpu->cpu_id; 30042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a0); 30142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 30242bfe448SAnup Patel die_perror("KVM_SET_ONE_REG failed (a0)"); 30342bfe448SAnup Patel 30442bfe448SAnup Patel data = kvm->arch.dtb_guest_start; 30542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a1); 30642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 30742bfe448SAnup Patel die_perror("KVM_SET_ONE_REG failed (a1)"); 3082e996783SAnup Patel } 3092e996783SAnup Patel 3102e996783SAnup Patel int kvm_cpu__get_endianness(struct kvm_cpu *vcpu) 3112e996783SAnup Patel { 3122e996783SAnup Patel return VIRTIO_ENDIAN_LE; 3132e996783SAnup Patel } 3142e996783SAnup Patel 3152e996783SAnup Patel void kvm_cpu__show_code(struct kvm_cpu *vcpu) 3162e996783SAnup Patel { 31742bfe448SAnup Patel struct kvm_one_reg reg; 31842bfe448SAnup Patel unsigned long data; 31942bfe448SAnup Patel int debug_fd = kvm_cpu__get_debug_fd(); 32042bfe448SAnup Patel 32142bfe448SAnup Patel reg.addr = (unsigned long)&data; 32242bfe448SAnup Patel 32342bfe448SAnup Patel dprintf(debug_fd, "\n*PC:\n"); 32442bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.pc); 32542bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 32642bfe448SAnup Patel die("KVM_GET_ONE_REG failed (show_code @ PC)"); 32742bfe448SAnup Patel 32842bfe448SAnup Patel kvm__dump_mem(vcpu->kvm, data, 32, debug_fd); 32942bfe448SAnup Patel 33042bfe448SAnup Patel dprintf(debug_fd, "\n*RA:\n"); 33142bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.ra); 33242bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 33342bfe448SAnup Patel die("KVM_GET_ONE_REG failed (show_code @ RA)"); 33442bfe448SAnup Patel 33542bfe448SAnup Patel kvm__dump_mem(vcpu->kvm, data, 32, debug_fd); 33642bfe448SAnup Patel } 33742bfe448SAnup Patel 33842bfe448SAnup Patel static void kvm_cpu__show_csrs(struct kvm_cpu *vcpu) 33942bfe448SAnup Patel { 34042bfe448SAnup Patel struct kvm_one_reg reg; 34142bfe448SAnup Patel struct kvm_riscv_csr csr; 34242bfe448SAnup Patel unsigned long data; 34342bfe448SAnup Patel int debug_fd = kvm_cpu__get_debug_fd(); 34442bfe448SAnup Patel 34542bfe448SAnup Patel reg.addr = (unsigned long)&data; 34642bfe448SAnup Patel dprintf(debug_fd, "\n Control Status Registers:\n"); 34742bfe448SAnup Patel dprintf(debug_fd, " ------------------------\n"); 34842bfe448SAnup Patel 34942bfe448SAnup Patel reg.id = RISCV_CSR_REG(sstatus); 35042bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 35142bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sstatus)"); 35242bfe448SAnup Patel csr.sstatus = data; 35342bfe448SAnup Patel 35442bfe448SAnup Patel reg.id = RISCV_CSR_REG(sie); 35542bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 35642bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sie)"); 35742bfe448SAnup Patel csr.sie = data; 35842bfe448SAnup Patel 35942bfe448SAnup Patel reg.id = RISCV_CSR_REG(stvec); 36042bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 36142bfe448SAnup Patel die("KVM_GET_ONE_REG failed (stvec)"); 36242bfe448SAnup Patel csr.stvec = data; 36342bfe448SAnup Patel 36442bfe448SAnup Patel reg.id = RISCV_CSR_REG(sip); 36542bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 36642bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sip)"); 36742bfe448SAnup Patel csr.sip = data; 36842bfe448SAnup Patel 36942bfe448SAnup Patel reg.id = RISCV_CSR_REG(satp); 37042bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 37142bfe448SAnup Patel die("KVM_GET_ONE_REG failed (satp)"); 37242bfe448SAnup Patel csr.satp = data; 37342bfe448SAnup Patel 37442bfe448SAnup Patel reg.id = RISCV_CSR_REG(stval); 37542bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 37642bfe448SAnup Patel die("KVM_GET_ONE_REG failed (stval)"); 37742bfe448SAnup Patel csr.stval = data; 37842bfe448SAnup Patel 37942bfe448SAnup Patel reg.id = RISCV_CSR_REG(scause); 38042bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 38142bfe448SAnup Patel die("KVM_GET_ONE_REG failed (SCAUSE)"); 38242bfe448SAnup Patel csr.scause = data; 38342bfe448SAnup Patel 38442bfe448SAnup Patel reg.id = RISCV_CSR_REG(sscratch); 38542bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 38642bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sscartch)"); 38742bfe448SAnup Patel csr.sscratch = data; 38842bfe448SAnup Patel dprintf(debug_fd, " SSTATUS: 0x%016lx\n", csr.sstatus); 38942bfe448SAnup Patel dprintf(debug_fd, " SIE: 0x%016lx\n", csr.sie); 39042bfe448SAnup Patel dprintf(debug_fd, " STVEC: 0x%016lx\n", csr.stvec); 39142bfe448SAnup Patel dprintf(debug_fd, " SIP: 0x%016lx\n", csr.sip); 39242bfe448SAnup Patel dprintf(debug_fd, " SATP: 0x%016lx\n", csr.satp); 39342bfe448SAnup Patel dprintf(debug_fd, " STVAL: 0x%016lx\n", csr.stval); 39442bfe448SAnup Patel dprintf(debug_fd, " SCAUSE: 0x%016lx\n", csr.scause); 39542bfe448SAnup Patel dprintf(debug_fd, " SSCRATCH: 0x%016lx\n", csr.sscratch); 3962e996783SAnup Patel } 3972e996783SAnup Patel 3982e996783SAnup Patel void kvm_cpu__show_registers(struct kvm_cpu *vcpu) 3992e996783SAnup Patel { 40042bfe448SAnup Patel struct kvm_one_reg reg; 40142bfe448SAnup Patel unsigned long data; 40242bfe448SAnup Patel int debug_fd = kvm_cpu__get_debug_fd(); 40342bfe448SAnup Patel struct kvm_riscv_core core; 40442bfe448SAnup Patel 40542bfe448SAnup Patel reg.addr = (unsigned long)&data; 40642bfe448SAnup Patel 40742bfe448SAnup Patel reg.id = RISCV_CORE_REG(mode); 40842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 40942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (mode)"); 41042bfe448SAnup Patel core.mode = data; 41142bfe448SAnup Patel 41242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.pc); 41342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 41442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (pc)"); 41542bfe448SAnup Patel core.regs.pc = data; 41642bfe448SAnup Patel 41742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.ra); 41842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 41942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (ra)"); 42042bfe448SAnup Patel core.regs.ra = data; 42142bfe448SAnup Patel 42242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.sp); 42342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 42442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sp)"); 42542bfe448SAnup Patel core.regs.sp = data; 42642bfe448SAnup Patel 42742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.gp); 42842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 42942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (gp)"); 43042bfe448SAnup Patel core.regs.gp = data; 43142bfe448SAnup Patel 43242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.tp); 43342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 43442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (tp)"); 43542bfe448SAnup Patel core.regs.tp = data; 43642bfe448SAnup Patel 43742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t0); 43842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 43942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t0)"); 44042bfe448SAnup Patel core.regs.t0 = data; 44142bfe448SAnup Patel 44242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t1); 44342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 44442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t1)"); 44542bfe448SAnup Patel core.regs.t1 = data; 44642bfe448SAnup Patel 44742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t2); 44842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 44942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t2)"); 45042bfe448SAnup Patel core.regs.t2 = data; 45142bfe448SAnup Patel 45242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s0); 45342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 45442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s0)"); 45542bfe448SAnup Patel core.regs.s0 = data; 45642bfe448SAnup Patel 45742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s1); 45842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 45942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s1)"); 46042bfe448SAnup Patel core.regs.s1 = data; 46142bfe448SAnup Patel 46242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a0); 46342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 46442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a0)"); 46542bfe448SAnup Patel core.regs.a0 = data; 46642bfe448SAnup Patel 46742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a1); 46842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 46942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a1)"); 47042bfe448SAnup Patel core.regs.a1 = data; 47142bfe448SAnup Patel 47242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a2); 47342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 47442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a2)"); 47542bfe448SAnup Patel core.regs.a2 = data; 47642bfe448SAnup Patel 47742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a3); 47842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 47942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a3)"); 48042bfe448SAnup Patel core.regs.a3 = data; 48142bfe448SAnup Patel 48242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a4); 48342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 48442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a4)"); 48542bfe448SAnup Patel core.regs.a4 = data; 48642bfe448SAnup Patel 48742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a5); 48842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 48942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a5)"); 49042bfe448SAnup Patel core.regs.a5 = data; 49142bfe448SAnup Patel 49242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a6); 49342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 49442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a6)"); 49542bfe448SAnup Patel core.regs.a6 = data; 49642bfe448SAnup Patel 49742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a7); 49842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 49942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a7)"); 50042bfe448SAnup Patel core.regs.a7 = data; 50142bfe448SAnup Patel 50242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s2); 50342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 50442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s2)"); 50542bfe448SAnup Patel core.regs.s2 = data; 50642bfe448SAnup Patel 50742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s3); 50842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 50942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s3)"); 51042bfe448SAnup Patel core.regs.s3 = data; 51142bfe448SAnup Patel 51242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s4); 51342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 51442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s4)"); 51542bfe448SAnup Patel core.regs.s4 = data; 51642bfe448SAnup Patel 51742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s5); 51842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 51942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s5)"); 52042bfe448SAnup Patel core.regs.s5 = data; 52142bfe448SAnup Patel 52242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s6); 52342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 52442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s6)"); 52542bfe448SAnup Patel core.regs.s6 = data; 52642bfe448SAnup Patel 52742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s7); 52842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 52942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s7)"); 53042bfe448SAnup Patel core.regs.s7 = data; 53142bfe448SAnup Patel 53242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s8); 53342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 53442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s8)"); 53542bfe448SAnup Patel core.regs.s8 = data; 53642bfe448SAnup Patel 53742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s9); 53842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 53942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s9)"); 54042bfe448SAnup Patel core.regs.s9 = data; 54142bfe448SAnup Patel 54242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s10); 54342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 54442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s10)"); 54542bfe448SAnup Patel core.regs.s10 = data; 54642bfe448SAnup Patel 54742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s11); 54842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 54942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s11)"); 55042bfe448SAnup Patel core.regs.s11 = data; 55142bfe448SAnup Patel 55242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t3); 55342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 55442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t3)"); 55542bfe448SAnup Patel core.regs.t3 = data; 55642bfe448SAnup Patel 55742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t4); 55842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 55942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t4)"); 56042bfe448SAnup Patel core.regs.t4 = data; 56142bfe448SAnup Patel 56242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t5); 56342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 56442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t5)"); 56542bfe448SAnup Patel core.regs.t5 = data; 56642bfe448SAnup Patel 56742bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t6); 56842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 56942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t6)"); 57042bfe448SAnup Patel core.regs.t6 = data; 57142bfe448SAnup Patel 57242bfe448SAnup Patel dprintf(debug_fd, "\n General Purpose Registers:\n"); 57342bfe448SAnup Patel dprintf(debug_fd, " -------------------------\n"); 57442bfe448SAnup Patel dprintf(debug_fd, " MODE: 0x%lx\n", data); 57542bfe448SAnup Patel dprintf(debug_fd, " PC: 0x%016lx RA: 0x%016lx SP: 0x%016lx GP: 0x%016lx\n", 57642bfe448SAnup Patel core.regs.pc, core.regs.ra, core.regs.sp, core.regs.gp); 57742bfe448SAnup Patel dprintf(debug_fd, " TP: 0x%016lx T0: 0x%016lx T1: 0x%016lx T2: 0x%016lx\n", 57842bfe448SAnup Patel core.regs.tp, core.regs.t0, core.regs.t1, core.regs.t2); 57942bfe448SAnup Patel dprintf(debug_fd, " S0: 0x%016lx S1: 0x%016lx A0: 0x%016lx A1: 0x%016lx\n", 58042bfe448SAnup Patel core.regs.s0, core.regs.s1, core.regs.a0, core.regs.a1); 58142bfe448SAnup Patel dprintf(debug_fd, " A2: 0x%016lx A3: 0x%016lx A4: 0x%016lx A5: 0x%016lx\n", 58242bfe448SAnup Patel core.regs.a2, core.regs.a3, core.regs.a4, core.regs.a5); 58342bfe448SAnup Patel dprintf(debug_fd, " A6: 0x%016lx A7: 0x%016lx S2: 0x%016lx S3: 0x%016lx\n", 58442bfe448SAnup Patel core.regs.a6, core.regs.a7, core.regs.s2, core.regs.s3); 58542bfe448SAnup Patel dprintf(debug_fd, " S4: 0x%016lx S5: 0x%016lx S6: 0x%016lx S7: 0x%016lx\n", 58642bfe448SAnup Patel core.regs.s4, core.regs.s5, core.regs.s6, core.regs.s7); 58742bfe448SAnup Patel dprintf(debug_fd, " S8: 0x%016lx S9: 0x%016lx S10: 0x%016lx S11: 0x%016lx\n", 58842bfe448SAnup Patel core.regs.s8, core.regs.s9, core.regs.s10, core.regs.s11); 58942bfe448SAnup Patel dprintf(debug_fd, " T3: 0x%016lx T4: 0x%016lx T5: 0x%016lx T6: 0x%016lx\n", 59042bfe448SAnup Patel core.regs.t3, core.regs.t4, core.regs.t5, core.regs.t6); 59142bfe448SAnup Patel 59242bfe448SAnup Patel kvm_cpu__show_csrs(vcpu); 5932e996783SAnup Patel } 594