12e996783SAnup Patel #include "kvm/kvm-cpu.h" 22e996783SAnup Patel #include "kvm/kvm.h" 32e996783SAnup Patel #include "kvm/virtio.h" 4721da166SAnup Patel #include "kvm/sbi.h" 52e996783SAnup Patel #include "kvm/term.h" 62e996783SAnup Patel 72e996783SAnup Patel #include <asm/ptrace.h> 82e996783SAnup Patel 92e996783SAnup Patel static int debug_fd; 102e996783SAnup Patel 112e996783SAnup Patel void kvm_cpu__set_debug_fd(int fd) 122e996783SAnup Patel { 132e996783SAnup Patel debug_fd = fd; 142e996783SAnup Patel } 152e996783SAnup Patel 162e996783SAnup Patel int kvm_cpu__get_debug_fd(void) 172e996783SAnup Patel { 182e996783SAnup Patel return debug_fd; 192e996783SAnup Patel } 202e996783SAnup Patel 212e996783SAnup Patel struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id) 222e996783SAnup Patel { 2342bfe448SAnup Patel struct kvm_cpu *vcpu; 2442bfe448SAnup Patel u64 timebase = 0; 259e9cfde5SAnup Patel unsigned long isa = 0, id = 0; 26a416fdc2SAnup Patel unsigned long masks[KVM_REG_RISCV_SBI_MULTI_REG_LAST + 1] = { 0 }; 27a416fdc2SAnup Patel int i, coalesced_offset, mmap_size; 2842bfe448SAnup Patel struct kvm_one_reg reg; 2942bfe448SAnup Patel 3042bfe448SAnup Patel vcpu = calloc(1, sizeof(struct kvm_cpu)); 3142bfe448SAnup Patel if (!vcpu) 322e996783SAnup Patel return NULL; 3342bfe448SAnup Patel 3442bfe448SAnup Patel vcpu->vcpu_fd = ioctl(kvm->vm_fd, KVM_CREATE_VCPU, cpu_id); 3542bfe448SAnup Patel if (vcpu->vcpu_fd < 0) 3642bfe448SAnup Patel die_perror("KVM_CREATE_VCPU ioctl"); 3742bfe448SAnup Patel 3842bfe448SAnup Patel reg.id = RISCV_CONFIG_REG(isa); 3942bfe448SAnup Patel reg.addr = (unsigned long)&isa; 4042bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 4142bfe448SAnup Patel die("KVM_GET_ONE_REG failed (config.isa)"); 4242bfe448SAnup Patel 4342bfe448SAnup Patel reg.id = RISCV_TIMER_REG(frequency); 4442bfe448SAnup Patel reg.addr = (unsigned long)&timebase; 4542bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 4642bfe448SAnup Patel die("KVM_GET_ONE_REG failed (timer.frequency)"); 4742bfe448SAnup Patel 4842bfe448SAnup Patel mmap_size = ioctl(kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0); 4942bfe448SAnup Patel if (mmap_size < 0) 5042bfe448SAnup Patel die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl"); 5142bfe448SAnup Patel 5242bfe448SAnup Patel vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED, 5342bfe448SAnup Patel vcpu->vcpu_fd, 0); 5442bfe448SAnup Patel if (vcpu->kvm_run == MAP_FAILED) 5542bfe448SAnup Patel die("unable to mmap vcpu fd"); 5642bfe448SAnup Patel 5742bfe448SAnup Patel coalesced_offset = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, 5842bfe448SAnup Patel KVM_CAP_COALESCED_MMIO); 5942bfe448SAnup Patel if (coalesced_offset) 6042bfe448SAnup Patel vcpu->ring = (void *)vcpu->kvm_run + 6142bfe448SAnup Patel (coalesced_offset * PAGE_SIZE); 6242bfe448SAnup Patel 6342bfe448SAnup Patel reg.id = RISCV_CONFIG_REG(isa); 6442bfe448SAnup Patel reg.addr = (unsigned long)&isa; 6542bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 6642bfe448SAnup Patel die("KVM_SET_ONE_REG failed (config.isa)"); 6742bfe448SAnup Patel 689e9cfde5SAnup Patel if (kvm->cfg.arch.custom_mvendorid) { 699e9cfde5SAnup Patel id = kvm->cfg.arch.custom_mvendorid; 709e9cfde5SAnup Patel reg.id = RISCV_CONFIG_REG(mvendorid); 719e9cfde5SAnup Patel reg.addr = (unsigned long)&id; 729e9cfde5SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 739e9cfde5SAnup Patel die("KVM_SET_ONE_REG failed (config.mvendorid)"); 749e9cfde5SAnup Patel } 759e9cfde5SAnup Patel 769e9cfde5SAnup Patel if (kvm->cfg.arch.custom_marchid) { 779e9cfde5SAnup Patel id = kvm->cfg.arch.custom_marchid; 789e9cfde5SAnup Patel reg.id = RISCV_CONFIG_REG(marchid); 799e9cfde5SAnup Patel reg.addr = (unsigned long)&id; 809e9cfde5SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 819e9cfde5SAnup Patel die("KVM_SET_ONE_REG failed (config.marchid)"); 829e9cfde5SAnup Patel } 839e9cfde5SAnup Patel 849e9cfde5SAnup Patel if (kvm->cfg.arch.custom_mimpid) { 859e9cfde5SAnup Patel id = kvm->cfg.arch.custom_mimpid; 869e9cfde5SAnup Patel reg.id = RISCV_CONFIG_REG(mimpid); 879e9cfde5SAnup Patel reg.addr = (unsigned long)&id; 889e9cfde5SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 899e9cfde5SAnup Patel die("KVM_SET_ONE_REG failed (config.mimpid)"); 909e9cfde5SAnup Patel } 919e9cfde5SAnup Patel 92a416fdc2SAnup Patel for (i = 0; i < KVM_RISCV_SBI_EXT_MAX; i++) { 93a416fdc2SAnup Patel if (!kvm->cfg.arch.sbi_ext_disabled[i]) 94a416fdc2SAnup Patel continue; 95a416fdc2SAnup Patel masks[KVM_REG_RISCV_SBI_MULTI_REG(i)] |= 96a416fdc2SAnup Patel KVM_REG_RISCV_SBI_MULTI_MASK(i); 97a416fdc2SAnup Patel } 98a416fdc2SAnup Patel for (i = 0; i <= KVM_REG_RISCV_SBI_MULTI_REG_LAST; i++) { 99a416fdc2SAnup Patel if (!masks[i]) 100a416fdc2SAnup Patel continue; 101a416fdc2SAnup Patel 102a416fdc2SAnup Patel reg.id = RISCV_SBI_EXT_REG(KVM_REG_RISCV_SBI_MULTI_DIS, i); 103a416fdc2SAnup Patel reg.addr = (unsigned long)&masks[i]; 104a416fdc2SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 105a416fdc2SAnup Patel die("KVM_SET_ONE_REG failed (sbi_ext %d)", i); 106a416fdc2SAnup Patel } 107a416fdc2SAnup Patel 108*4ddaa424SAnup Patel /* Force enable SBI debug console if not disabled from command line */ 109*4ddaa424SAnup Patel if (!kvm->cfg.arch.sbi_ext_disabled[KVM_RISCV_SBI_EXT_DBCN]) { 110*4ddaa424SAnup Patel id = 1; 111*4ddaa424SAnup Patel reg.id = RISCV_SBI_EXT_REG(KVM_REG_RISCV_SBI_SINGLE, 112*4ddaa424SAnup Patel KVM_RISCV_SBI_EXT_DBCN); 113*4ddaa424SAnup Patel reg.addr = (unsigned long)&id; 114*4ddaa424SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 115*4ddaa424SAnup Patel pr_warning("KVM_SET_ONE_REG failed (sbi_ext %d)", 116*4ddaa424SAnup Patel KVM_RISCV_SBI_EXT_DBCN); 117*4ddaa424SAnup Patel } 118*4ddaa424SAnup Patel 11942bfe448SAnup Patel /* Populate the vcpu structure. */ 12042bfe448SAnup Patel vcpu->kvm = kvm; 12142bfe448SAnup Patel vcpu->cpu_id = cpu_id; 12242bfe448SAnup Patel vcpu->riscv_isa = isa; 12342bfe448SAnup Patel vcpu->riscv_xlen = __riscv_xlen; 12442bfe448SAnup Patel vcpu->riscv_timebase = timebase; 12542bfe448SAnup Patel vcpu->is_running = true; 12642bfe448SAnup Patel 12742bfe448SAnup Patel return vcpu; 1282e996783SAnup Patel } 1292e996783SAnup Patel 1302e996783SAnup Patel void kvm_cpu__arch_nmi(struct kvm_cpu *cpu) 1312e996783SAnup Patel { 1322e996783SAnup Patel } 1332e996783SAnup Patel 1342e996783SAnup Patel void kvm_cpu__delete(struct kvm_cpu *vcpu) 1352e996783SAnup Patel { 13642bfe448SAnup Patel free(vcpu); 1372e996783SAnup Patel } 1382e996783SAnup Patel 139721da166SAnup Patel static bool kvm_cpu_riscv_sbi(struct kvm_cpu *vcpu) 140721da166SAnup Patel { 141721da166SAnup Patel char ch; 142*4ddaa424SAnup Patel u64 addr; 143721da166SAnup Patel bool ret = true; 144*4ddaa424SAnup Patel char *str_start, *str_end; 145721da166SAnup Patel int dfd = kvm_cpu__get_debug_fd(); 146721da166SAnup Patel 147721da166SAnup Patel switch (vcpu->kvm_run->riscv_sbi.extension_id) { 148721da166SAnup Patel case SBI_EXT_0_1_CONSOLE_PUTCHAR: 149721da166SAnup Patel ch = vcpu->kvm_run->riscv_sbi.args[0]; 150721da166SAnup Patel term_putc(&ch, 1, 0); 151721da166SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] = 0; 152721da166SAnup Patel break; 153721da166SAnup Patel case SBI_EXT_0_1_CONSOLE_GETCHAR: 154721da166SAnup Patel if (term_readable(0)) 155721da166SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] = 156721da166SAnup Patel term_getc(vcpu->kvm, 0); 157721da166SAnup Patel else 158721da166SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] = SBI_ERR_FAILURE; 159721da166SAnup Patel break; 160*4ddaa424SAnup Patel case SBI_EXT_DBCN: 161*4ddaa424SAnup Patel switch (vcpu->kvm_run->riscv_sbi.function_id) { 162*4ddaa424SAnup Patel case SBI_EXT_DBCN_CONSOLE_WRITE: 163*4ddaa424SAnup Patel case SBI_EXT_DBCN_CONSOLE_READ: 164*4ddaa424SAnup Patel addr = vcpu->kvm_run->riscv_sbi.args[1]; 165*4ddaa424SAnup Patel #if __riscv_xlen == 32 166*4ddaa424SAnup Patel addr |= (u64)vcpu->kvm_run->riscv_sbi.args[2] << 32; 167*4ddaa424SAnup Patel #endif 168*4ddaa424SAnup Patel if (!vcpu->kvm_run->riscv_sbi.args[0]) 169*4ddaa424SAnup Patel break; 170*4ddaa424SAnup Patel str_start = guest_flat_to_host(vcpu->kvm, addr); 171*4ddaa424SAnup Patel addr += vcpu->kvm_run->riscv_sbi.args[0] - 1; 172*4ddaa424SAnup Patel str_end = guest_flat_to_host(vcpu->kvm, addr); 173*4ddaa424SAnup Patel if (!str_start || !str_end) { 174*4ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] = 175*4ddaa424SAnup Patel SBI_ERR_INVALID_PARAM; 176*4ddaa424SAnup Patel break; 177*4ddaa424SAnup Patel } 178*4ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[1] = 0; 179*4ddaa424SAnup Patel while (str_start <= str_end) { 180*4ddaa424SAnup Patel if (vcpu->kvm_run->riscv_sbi.function_id == 181*4ddaa424SAnup Patel SBI_EXT_DBCN_CONSOLE_WRITE) { 182*4ddaa424SAnup Patel term_putc(str_start, 1, 0); 183*4ddaa424SAnup Patel } else { 184*4ddaa424SAnup Patel if (!term_readable(0)) 185*4ddaa424SAnup Patel break; 186*4ddaa424SAnup Patel *str_start = term_getc(vcpu->kvm, 0); 187*4ddaa424SAnup Patel } 188*4ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[1]++; 189*4ddaa424SAnup Patel str_start++; 190*4ddaa424SAnup Patel } 191*4ddaa424SAnup Patel break; 192*4ddaa424SAnup Patel case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: 193*4ddaa424SAnup Patel ch = vcpu->kvm_run->riscv_sbi.args[0]; 194*4ddaa424SAnup Patel term_putc(&ch, 1, 0); 195*4ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] = 0; 196*4ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[1] = 0; 197*4ddaa424SAnup Patel break; 198*4ddaa424SAnup Patel default: 199*4ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] = 200*4ddaa424SAnup Patel SBI_ERR_NOT_SUPPORTED; 201*4ddaa424SAnup Patel break; 202*4ddaa424SAnup Patel } 203*4ddaa424SAnup Patel break; 204721da166SAnup Patel default: 205721da166SAnup Patel dprintf(dfd, "Unhandled SBI call\n"); 206721da166SAnup Patel dprintf(dfd, "extension_id=0x%lx function_id=0x%lx\n", 207721da166SAnup Patel vcpu->kvm_run->riscv_sbi.extension_id, 208721da166SAnup Patel vcpu->kvm_run->riscv_sbi.function_id); 209721da166SAnup Patel dprintf(dfd, "args[0]=0x%lx args[1]=0x%lx\n", 210721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[0], 211721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[1]); 212721da166SAnup Patel dprintf(dfd, "args[2]=0x%lx args[3]=0x%lx\n", 213721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[2], 214721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[3]); 215721da166SAnup Patel dprintf(dfd, "args[4]=0x%lx args[5]=0x%lx\n", 216721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[4], 217721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[5]); 218721da166SAnup Patel ret = false; 219721da166SAnup Patel break; 220721da166SAnup Patel }; 221721da166SAnup Patel 222721da166SAnup Patel return ret; 223721da166SAnup Patel } 224721da166SAnup Patel 2252e996783SAnup Patel bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu) 2262e996783SAnup Patel { 227721da166SAnup Patel switch (vcpu->kvm_run->exit_reason) { 228721da166SAnup Patel case KVM_EXIT_RISCV_SBI: 229721da166SAnup Patel return kvm_cpu_riscv_sbi(vcpu); 230721da166SAnup Patel default: 231721da166SAnup Patel break; 232721da166SAnup Patel }; 233721da166SAnup Patel 2342e996783SAnup Patel return false; 2352e996783SAnup Patel } 2362e996783SAnup Patel 2372e996783SAnup Patel void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu) 2382e996783SAnup Patel { 2392e996783SAnup Patel } 2402e996783SAnup Patel 2412e996783SAnup Patel void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu) 2422e996783SAnup Patel { 24342bfe448SAnup Patel struct kvm *kvm = vcpu->kvm; 24442bfe448SAnup Patel struct kvm_mp_state mp_state; 24542bfe448SAnup Patel struct kvm_one_reg reg; 24642bfe448SAnup Patel unsigned long data; 24742bfe448SAnup Patel 24842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_MP_STATE, &mp_state) < 0) 24942bfe448SAnup Patel die_perror("KVM_GET_MP_STATE failed"); 25042bfe448SAnup Patel 25142bfe448SAnup Patel /* 25242bfe448SAnup Patel * If MP state is stopped then it means Linux KVM RISC-V emulates 25342bfe448SAnup Patel * SBI v0.2 (or higher) with HART power managment and give VCPU 25442bfe448SAnup Patel * will power-up at boot-time by boot VCPU. For such VCPU, we 25542bfe448SAnup Patel * don't update PC, A0 and A1 here. 25642bfe448SAnup Patel */ 25742bfe448SAnup Patel if (mp_state.mp_state == KVM_MP_STATE_STOPPED) 25842bfe448SAnup Patel return; 25942bfe448SAnup Patel 26042bfe448SAnup Patel reg.addr = (unsigned long)&data; 26142bfe448SAnup Patel 26242bfe448SAnup Patel data = kvm->arch.kern_guest_start; 26342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.pc); 26442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 26542bfe448SAnup Patel die_perror("KVM_SET_ONE_REG failed (pc)"); 26642bfe448SAnup Patel 26742bfe448SAnup Patel data = vcpu->cpu_id; 26842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a0); 26942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 27042bfe448SAnup Patel die_perror("KVM_SET_ONE_REG failed (a0)"); 27142bfe448SAnup Patel 27242bfe448SAnup Patel data = kvm->arch.dtb_guest_start; 27342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a1); 27442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 27542bfe448SAnup Patel die_perror("KVM_SET_ONE_REG failed (a1)"); 2762e996783SAnup Patel } 2772e996783SAnup Patel 2782e996783SAnup Patel int kvm_cpu__get_endianness(struct kvm_cpu *vcpu) 2792e996783SAnup Patel { 2802e996783SAnup Patel return VIRTIO_ENDIAN_LE; 2812e996783SAnup Patel } 2822e996783SAnup Patel 2832e996783SAnup Patel void kvm_cpu__show_code(struct kvm_cpu *vcpu) 2842e996783SAnup Patel { 28542bfe448SAnup Patel struct kvm_one_reg reg; 28642bfe448SAnup Patel unsigned long data; 28742bfe448SAnup Patel int debug_fd = kvm_cpu__get_debug_fd(); 28842bfe448SAnup Patel 28942bfe448SAnup Patel reg.addr = (unsigned long)&data; 29042bfe448SAnup Patel 29142bfe448SAnup Patel dprintf(debug_fd, "\n*PC:\n"); 29242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.pc); 29342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 29442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (show_code @ PC)"); 29542bfe448SAnup Patel 29642bfe448SAnup Patel kvm__dump_mem(vcpu->kvm, data, 32, debug_fd); 29742bfe448SAnup Patel 29842bfe448SAnup Patel dprintf(debug_fd, "\n*RA:\n"); 29942bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.ra); 30042bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 30142bfe448SAnup Patel die("KVM_GET_ONE_REG failed (show_code @ RA)"); 30242bfe448SAnup Patel 30342bfe448SAnup Patel kvm__dump_mem(vcpu->kvm, data, 32, debug_fd); 30442bfe448SAnup Patel } 30542bfe448SAnup Patel 30642bfe448SAnup Patel static void kvm_cpu__show_csrs(struct kvm_cpu *vcpu) 30742bfe448SAnup Patel { 30842bfe448SAnup Patel struct kvm_one_reg reg; 30942bfe448SAnup Patel struct kvm_riscv_csr csr; 31042bfe448SAnup Patel unsigned long data; 31142bfe448SAnup Patel int debug_fd = kvm_cpu__get_debug_fd(); 31242bfe448SAnup Patel 31342bfe448SAnup Patel reg.addr = (unsigned long)&data; 31442bfe448SAnup Patel dprintf(debug_fd, "\n Control Status Registers:\n"); 31542bfe448SAnup Patel dprintf(debug_fd, " ------------------------\n"); 31642bfe448SAnup Patel 31742bfe448SAnup Patel reg.id = RISCV_CSR_REG(sstatus); 31842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 31942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sstatus)"); 32042bfe448SAnup Patel csr.sstatus = data; 32142bfe448SAnup Patel 32242bfe448SAnup Patel reg.id = RISCV_CSR_REG(sie); 32342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 32442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sie)"); 32542bfe448SAnup Patel csr.sie = data; 32642bfe448SAnup Patel 32742bfe448SAnup Patel reg.id = RISCV_CSR_REG(stvec); 32842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 32942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (stvec)"); 33042bfe448SAnup Patel csr.stvec = data; 33142bfe448SAnup Patel 33242bfe448SAnup Patel reg.id = RISCV_CSR_REG(sip); 33342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 33442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sip)"); 33542bfe448SAnup Patel csr.sip = data; 33642bfe448SAnup Patel 33742bfe448SAnup Patel reg.id = RISCV_CSR_REG(satp); 33842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 33942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (satp)"); 34042bfe448SAnup Patel csr.satp = data; 34142bfe448SAnup Patel 34242bfe448SAnup Patel reg.id = RISCV_CSR_REG(stval); 34342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 34442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (stval)"); 34542bfe448SAnup Patel csr.stval = data; 34642bfe448SAnup Patel 34742bfe448SAnup Patel reg.id = RISCV_CSR_REG(scause); 34842bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 34942bfe448SAnup Patel die("KVM_GET_ONE_REG failed (SCAUSE)"); 35042bfe448SAnup Patel csr.scause = data; 35142bfe448SAnup Patel 35242bfe448SAnup Patel reg.id = RISCV_CSR_REG(sscratch); 35342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 35442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sscartch)"); 35542bfe448SAnup Patel csr.sscratch = data; 35642bfe448SAnup Patel dprintf(debug_fd, " SSTATUS: 0x%016lx\n", csr.sstatus); 35742bfe448SAnup Patel dprintf(debug_fd, " SIE: 0x%016lx\n", csr.sie); 35842bfe448SAnup Patel dprintf(debug_fd, " STVEC: 0x%016lx\n", csr.stvec); 35942bfe448SAnup Patel dprintf(debug_fd, " SIP: 0x%016lx\n", csr.sip); 36042bfe448SAnup Patel dprintf(debug_fd, " SATP: 0x%016lx\n", csr.satp); 36142bfe448SAnup Patel dprintf(debug_fd, " STVAL: 0x%016lx\n", csr.stval); 36242bfe448SAnup Patel dprintf(debug_fd, " SCAUSE: 0x%016lx\n", csr.scause); 36342bfe448SAnup Patel dprintf(debug_fd, " SSCRATCH: 0x%016lx\n", csr.sscratch); 3642e996783SAnup Patel } 3652e996783SAnup Patel 3662e996783SAnup Patel void kvm_cpu__show_registers(struct kvm_cpu *vcpu) 3672e996783SAnup Patel { 36842bfe448SAnup Patel struct kvm_one_reg reg; 36942bfe448SAnup Patel unsigned long data; 37042bfe448SAnup Patel int debug_fd = kvm_cpu__get_debug_fd(); 37142bfe448SAnup Patel struct kvm_riscv_core core; 37242bfe448SAnup Patel 37342bfe448SAnup Patel reg.addr = (unsigned long)&data; 37442bfe448SAnup Patel 37542bfe448SAnup Patel reg.id = RISCV_CORE_REG(mode); 37642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 37742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (mode)"); 37842bfe448SAnup Patel core.mode = data; 37942bfe448SAnup Patel 38042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.pc); 38142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 38242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (pc)"); 38342bfe448SAnup Patel core.regs.pc = data; 38442bfe448SAnup Patel 38542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.ra); 38642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 38742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (ra)"); 38842bfe448SAnup Patel core.regs.ra = data; 38942bfe448SAnup Patel 39042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.sp); 39142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 39242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sp)"); 39342bfe448SAnup Patel core.regs.sp = data; 39442bfe448SAnup Patel 39542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.gp); 39642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 39742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (gp)"); 39842bfe448SAnup Patel core.regs.gp = data; 39942bfe448SAnup Patel 40042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.tp); 40142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 40242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (tp)"); 40342bfe448SAnup Patel core.regs.tp = data; 40442bfe448SAnup Patel 40542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t0); 40642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 40742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t0)"); 40842bfe448SAnup Patel core.regs.t0 = data; 40942bfe448SAnup Patel 41042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t1); 41142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 41242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t1)"); 41342bfe448SAnup Patel core.regs.t1 = data; 41442bfe448SAnup Patel 41542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t2); 41642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 41742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t2)"); 41842bfe448SAnup Patel core.regs.t2 = data; 41942bfe448SAnup Patel 42042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s0); 42142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 42242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s0)"); 42342bfe448SAnup Patel core.regs.s0 = data; 42442bfe448SAnup Patel 42542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s1); 42642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 42742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s1)"); 42842bfe448SAnup Patel core.regs.s1 = data; 42942bfe448SAnup Patel 43042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a0); 43142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 43242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a0)"); 43342bfe448SAnup Patel core.regs.a0 = data; 43442bfe448SAnup Patel 43542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a1); 43642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 43742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a1)"); 43842bfe448SAnup Patel core.regs.a1 = data; 43942bfe448SAnup Patel 44042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a2); 44142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 44242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a2)"); 44342bfe448SAnup Patel core.regs.a2 = data; 44442bfe448SAnup Patel 44542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a3); 44642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 44742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a3)"); 44842bfe448SAnup Patel core.regs.a3 = data; 44942bfe448SAnup Patel 45042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a4); 45142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 45242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a4)"); 45342bfe448SAnup Patel core.regs.a4 = data; 45442bfe448SAnup Patel 45542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a5); 45642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 45742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a5)"); 45842bfe448SAnup Patel core.regs.a5 = data; 45942bfe448SAnup Patel 46042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a6); 46142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 46242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a6)"); 46342bfe448SAnup Patel core.regs.a6 = data; 46442bfe448SAnup Patel 46542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a7); 46642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 46742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a7)"); 46842bfe448SAnup Patel core.regs.a7 = data; 46942bfe448SAnup Patel 47042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s2); 47142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 47242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s2)"); 47342bfe448SAnup Patel core.regs.s2 = data; 47442bfe448SAnup Patel 47542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s3); 47642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 47742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s3)"); 47842bfe448SAnup Patel core.regs.s3 = data; 47942bfe448SAnup Patel 48042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s4); 48142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 48242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s4)"); 48342bfe448SAnup Patel core.regs.s4 = data; 48442bfe448SAnup Patel 48542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s5); 48642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 48742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s5)"); 48842bfe448SAnup Patel core.regs.s5 = data; 48942bfe448SAnup Patel 49042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s6); 49142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 49242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s6)"); 49342bfe448SAnup Patel core.regs.s6 = data; 49442bfe448SAnup Patel 49542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s7); 49642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 49742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s7)"); 49842bfe448SAnup Patel core.regs.s7 = data; 49942bfe448SAnup Patel 50042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s8); 50142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 50242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s8)"); 50342bfe448SAnup Patel core.regs.s8 = data; 50442bfe448SAnup Patel 50542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s9); 50642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 50742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s9)"); 50842bfe448SAnup Patel core.regs.s9 = data; 50942bfe448SAnup Patel 51042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s10); 51142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 51242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s10)"); 51342bfe448SAnup Patel core.regs.s10 = data; 51442bfe448SAnup Patel 51542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s11); 51642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 51742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s11)"); 51842bfe448SAnup Patel core.regs.s11 = data; 51942bfe448SAnup Patel 52042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t3); 52142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 52242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t3)"); 52342bfe448SAnup Patel core.regs.t3 = data; 52442bfe448SAnup Patel 52542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t4); 52642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 52742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t4)"); 52842bfe448SAnup Patel core.regs.t4 = data; 52942bfe448SAnup Patel 53042bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t5); 53142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 53242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t5)"); 53342bfe448SAnup Patel core.regs.t5 = data; 53442bfe448SAnup Patel 53542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t6); 53642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0) 53742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t6)"); 53842bfe448SAnup Patel core.regs.t6 = data; 53942bfe448SAnup Patel 54042bfe448SAnup Patel dprintf(debug_fd, "\n General Purpose Registers:\n"); 54142bfe448SAnup Patel dprintf(debug_fd, " -------------------------\n"); 54242bfe448SAnup Patel dprintf(debug_fd, " MODE: 0x%lx\n", data); 54342bfe448SAnup Patel dprintf(debug_fd, " PC: 0x%016lx RA: 0x%016lx SP: 0x%016lx GP: 0x%016lx\n", 54442bfe448SAnup Patel core.regs.pc, core.regs.ra, core.regs.sp, core.regs.gp); 54542bfe448SAnup Patel dprintf(debug_fd, " TP: 0x%016lx T0: 0x%016lx T1: 0x%016lx T2: 0x%016lx\n", 54642bfe448SAnup Patel core.regs.tp, core.regs.t0, core.regs.t1, core.regs.t2); 54742bfe448SAnup Patel dprintf(debug_fd, " S0: 0x%016lx S1: 0x%016lx A0: 0x%016lx A1: 0x%016lx\n", 54842bfe448SAnup Patel core.regs.s0, core.regs.s1, core.regs.a0, core.regs.a1); 54942bfe448SAnup Patel dprintf(debug_fd, " A2: 0x%016lx A3: 0x%016lx A4: 0x%016lx A5: 0x%016lx\n", 55042bfe448SAnup Patel core.regs.a2, core.regs.a3, core.regs.a4, core.regs.a5); 55142bfe448SAnup Patel dprintf(debug_fd, " A6: 0x%016lx A7: 0x%016lx S2: 0x%016lx S3: 0x%016lx\n", 55242bfe448SAnup Patel core.regs.a6, core.regs.a7, core.regs.s2, core.regs.s3); 55342bfe448SAnup Patel dprintf(debug_fd, " S4: 0x%016lx S5: 0x%016lx S6: 0x%016lx S7: 0x%016lx\n", 55442bfe448SAnup Patel core.regs.s4, core.regs.s5, core.regs.s6, core.regs.s7); 55542bfe448SAnup Patel dprintf(debug_fd, " S8: 0x%016lx S9: 0x%016lx S10: 0x%016lx S11: 0x%016lx\n", 55642bfe448SAnup Patel core.regs.s8, core.regs.s9, core.regs.s10, core.regs.s11); 55742bfe448SAnup Patel dprintf(debug_fd, " T3: 0x%016lx T4: 0x%016lx T5: 0x%016lx T6: 0x%016lx\n", 55842bfe448SAnup Patel core.regs.t3, core.regs.t4, core.regs.t5, core.regs.t6); 55942bfe448SAnup Patel 56042bfe448SAnup Patel kvm_cpu__show_csrs(vcpu); 5612e996783SAnup Patel } 562