1d9052a96SAnup 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
kvm_cpu__set_debug_fd(int fd)122e996783SAnup Patel void kvm_cpu__set_debug_fd(int fd)
132e996783SAnup Patel {
142e996783SAnup Patel debug_fd = fd;
152e996783SAnup Patel }
162e996783SAnup Patel
kvm_cpu__get_debug_fd(void)172e996783SAnup Patel int kvm_cpu__get_debug_fd(void)
182e996783SAnup Patel {
192e996783SAnup Patel return debug_fd;
202e996783SAnup Patel }
212e996783SAnup Patel
kvm_cpu__arch_init(struct kvm * kvm,unsigned long cpu_id)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
kvm_cpu__arch_nmi(struct kvm_cpu * cpu)1312e996783SAnup Patel void kvm_cpu__arch_nmi(struct kvm_cpu *cpu)
1322e996783SAnup Patel {
1332e996783SAnup Patel }
1342e996783SAnup Patel
kvm_cpu__delete(struct kvm_cpu * vcpu)1352e996783SAnup Patel void kvm_cpu__delete(struct kvm_cpu *vcpu)
1362e996783SAnup Patel {
13742bfe448SAnup Patel free(vcpu);
1382e996783SAnup Patel }
1392e996783SAnup Patel
kvm_cpu_riscv_sbi(struct kvm_cpu * vcpu)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:
165*027784f4SAndrew Jones vcpu->kvm_run->riscv_sbi.ret[0] = SBI_SUCCESS;
1664ddaa424SAnup Patel addr = vcpu->kvm_run->riscv_sbi.args[1];
1674ddaa424SAnup Patel #if __riscv_xlen == 32
1684ddaa424SAnup Patel addr |= (u64)vcpu->kvm_run->riscv_sbi.args[2] << 32;
1694ddaa424SAnup Patel #endif
1704ddaa424SAnup Patel if (!vcpu->kvm_run->riscv_sbi.args[0])
1714ddaa424SAnup Patel break;
1724ddaa424SAnup Patel str_start = guest_flat_to_host(vcpu->kvm, addr);
1734ddaa424SAnup Patel addr += vcpu->kvm_run->riscv_sbi.args[0] - 1;
1744ddaa424SAnup Patel str_end = guest_flat_to_host(vcpu->kvm, addr);
1754ddaa424SAnup Patel if (!str_start || !str_end) {
1764ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] =
1774ddaa424SAnup Patel SBI_ERR_INVALID_PARAM;
1784ddaa424SAnup Patel break;
1794ddaa424SAnup Patel }
1804ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[1] = 0;
1814ddaa424SAnup Patel while (str_start <= str_end) {
1824ddaa424SAnup Patel if (vcpu->kvm_run->riscv_sbi.function_id ==
1834ddaa424SAnup Patel SBI_EXT_DBCN_CONSOLE_WRITE) {
1844ddaa424SAnup Patel term_putc(str_start, 1, 0);
1854ddaa424SAnup Patel } else {
1864ddaa424SAnup Patel if (!term_readable(0))
1874ddaa424SAnup Patel break;
1884ddaa424SAnup Patel *str_start = term_getc(vcpu->kvm, 0);
1894ddaa424SAnup Patel }
1904ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[1]++;
1914ddaa424SAnup Patel str_start++;
1924ddaa424SAnup Patel }
1934ddaa424SAnup Patel break;
1944ddaa424SAnup Patel case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE:
1954ddaa424SAnup Patel ch = vcpu->kvm_run->riscv_sbi.args[0];
1964ddaa424SAnup Patel term_putc(&ch, 1, 0);
1974ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] = 0;
1984ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[1] = 0;
1994ddaa424SAnup Patel break;
2004ddaa424SAnup Patel default:
2014ddaa424SAnup Patel vcpu->kvm_run->riscv_sbi.ret[0] =
2024ddaa424SAnup Patel SBI_ERR_NOT_SUPPORTED;
2034ddaa424SAnup Patel break;
2044ddaa424SAnup Patel }
2054ddaa424SAnup Patel break;
206721da166SAnup Patel default:
207721da166SAnup Patel dprintf(dfd, "Unhandled SBI call\n");
208721da166SAnup Patel dprintf(dfd, "extension_id=0x%lx function_id=0x%lx\n",
209721da166SAnup Patel vcpu->kvm_run->riscv_sbi.extension_id,
210721da166SAnup Patel vcpu->kvm_run->riscv_sbi.function_id);
211721da166SAnup Patel dprintf(dfd, "args[0]=0x%lx args[1]=0x%lx\n",
212721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[0],
213721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[1]);
214721da166SAnup Patel dprintf(dfd, "args[2]=0x%lx args[3]=0x%lx\n",
215721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[2],
216721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[3]);
217721da166SAnup Patel dprintf(dfd, "args[4]=0x%lx args[5]=0x%lx\n",
218721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[4],
219721da166SAnup Patel vcpu->kvm_run->riscv_sbi.args[5]);
220721da166SAnup Patel ret = false;
221721da166SAnup Patel break;
222721da166SAnup Patel };
223721da166SAnup Patel
224721da166SAnup Patel return ret;
225721da166SAnup Patel }
226721da166SAnup Patel
kvm_cpu_riscv_csr(struct kvm_cpu * vcpu)227d9052a96SAnup Patel static bool kvm_cpu_riscv_csr(struct kvm_cpu *vcpu)
228d9052a96SAnup Patel {
229d9052a96SAnup Patel int dfd = kvm_cpu__get_debug_fd();
230d9052a96SAnup Patel bool ret = true;
231d9052a96SAnup Patel
232d9052a96SAnup Patel switch (vcpu->kvm_run->riscv_csr.csr_num) {
233d9052a96SAnup Patel case CSR_SEED:
234d9052a96SAnup Patel /*
235d9052a96SAnup Patel * We ignore the new_value and write_mask and simply
236d9052a96SAnup Patel * return a random value as SEED.
237d9052a96SAnup Patel */
238d9052a96SAnup Patel vcpu->kvm_run->riscv_csr.ret_value = SEED_OPST_ES16;
239d9052a96SAnup Patel vcpu->kvm_run->riscv_csr.ret_value |= rand() & SEED_ENTROPY_MASK;
240d9052a96SAnup Patel break;
241d9052a96SAnup Patel default:
242d9052a96SAnup Patel dprintf(dfd, "Unhandled CSR access\n");
243d9052a96SAnup Patel dprintf(dfd, "csr_num=0x%lx new_value=0x%lx\n",
244d9052a96SAnup Patel vcpu->kvm_run->riscv_csr.csr_num,
245d9052a96SAnup Patel vcpu->kvm_run->riscv_csr.new_value);
246d9052a96SAnup Patel dprintf(dfd, "write_mask=0x%lx ret_value=0x%lx\n",
247d9052a96SAnup Patel vcpu->kvm_run->riscv_csr.write_mask,
248d9052a96SAnup Patel vcpu->kvm_run->riscv_csr.ret_value);
249d9052a96SAnup Patel ret = false;
250d9052a96SAnup Patel break;
251d9052a96SAnup Patel }
252d9052a96SAnup Patel
253d9052a96SAnup Patel return ret;
254d9052a96SAnup Patel }
255d9052a96SAnup Patel
kvm_cpu__handle_exit(struct kvm_cpu * vcpu)2562e996783SAnup Patel bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
2572e996783SAnup Patel {
258721da166SAnup Patel switch (vcpu->kvm_run->exit_reason) {
259721da166SAnup Patel case KVM_EXIT_RISCV_SBI:
260721da166SAnup Patel return kvm_cpu_riscv_sbi(vcpu);
261d9052a96SAnup Patel case KVM_EXIT_RISCV_CSR:
262d9052a96SAnup Patel return kvm_cpu_riscv_csr(vcpu);
263721da166SAnup Patel default:
264721da166SAnup Patel break;
265721da166SAnup Patel };
266721da166SAnup Patel
2672e996783SAnup Patel return false;
2682e996783SAnup Patel }
2692e996783SAnup Patel
kvm_cpu__show_page_tables(struct kvm_cpu * vcpu)2702e996783SAnup Patel void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu)
2712e996783SAnup Patel {
2722e996783SAnup Patel }
2732e996783SAnup Patel
kvm_cpu__reset_vcpu(struct kvm_cpu * vcpu)2742e996783SAnup Patel void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
2752e996783SAnup Patel {
27642bfe448SAnup Patel struct kvm *kvm = vcpu->kvm;
27742bfe448SAnup Patel struct kvm_mp_state mp_state;
27842bfe448SAnup Patel struct kvm_one_reg reg;
27942bfe448SAnup Patel unsigned long data;
28042bfe448SAnup Patel
28142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_MP_STATE, &mp_state) < 0)
28242bfe448SAnup Patel die_perror("KVM_GET_MP_STATE failed");
28342bfe448SAnup Patel
28442bfe448SAnup Patel /*
28542bfe448SAnup Patel * If MP state is stopped then it means Linux KVM RISC-V emulates
28642bfe448SAnup Patel * SBI v0.2 (or higher) with HART power managment and give VCPU
28742bfe448SAnup Patel * will power-up at boot-time by boot VCPU. For such VCPU, we
28842bfe448SAnup Patel * don't update PC, A0 and A1 here.
28942bfe448SAnup Patel */
29042bfe448SAnup Patel if (mp_state.mp_state == KVM_MP_STATE_STOPPED)
29142bfe448SAnup Patel return;
29242bfe448SAnup Patel
29342bfe448SAnup Patel reg.addr = (unsigned long)&data;
29442bfe448SAnup Patel
29542bfe448SAnup Patel data = kvm->arch.kern_guest_start;
29642bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.pc);
29742bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
29842bfe448SAnup Patel die_perror("KVM_SET_ONE_REG failed (pc)");
29942bfe448SAnup Patel
30042bfe448SAnup Patel data = vcpu->cpu_id;
30142bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a0);
30242bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
30342bfe448SAnup Patel die_perror("KVM_SET_ONE_REG failed (a0)");
30442bfe448SAnup Patel
30542bfe448SAnup Patel data = kvm->arch.dtb_guest_start;
30642bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a1);
30742bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
30842bfe448SAnup Patel die_perror("KVM_SET_ONE_REG failed (a1)");
3092e996783SAnup Patel }
3102e996783SAnup Patel
kvm_cpu__get_endianness(struct kvm_cpu * vcpu)3112e996783SAnup Patel int kvm_cpu__get_endianness(struct kvm_cpu *vcpu)
3122e996783SAnup Patel {
3132e996783SAnup Patel return VIRTIO_ENDIAN_LE;
3142e996783SAnup Patel }
3152e996783SAnup Patel
kvm_cpu__show_code(struct kvm_cpu * vcpu)3162e996783SAnup Patel void kvm_cpu__show_code(struct kvm_cpu *vcpu)
3172e996783SAnup Patel {
31842bfe448SAnup Patel struct kvm_one_reg reg;
31942bfe448SAnup Patel unsigned long data;
32042bfe448SAnup Patel int debug_fd = kvm_cpu__get_debug_fd();
32142bfe448SAnup Patel
32242bfe448SAnup Patel reg.addr = (unsigned long)&data;
32342bfe448SAnup Patel
32442bfe448SAnup Patel dprintf(debug_fd, "\n*PC:\n");
32542bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.pc);
32642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
32742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (show_code @ PC)");
32842bfe448SAnup Patel
32942bfe448SAnup Patel kvm__dump_mem(vcpu->kvm, data, 32, debug_fd);
33042bfe448SAnup Patel
33142bfe448SAnup Patel dprintf(debug_fd, "\n*RA:\n");
33242bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.ra);
33342bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
33442bfe448SAnup Patel die("KVM_GET_ONE_REG failed (show_code @ RA)");
33542bfe448SAnup Patel
33642bfe448SAnup Patel kvm__dump_mem(vcpu->kvm, data, 32, debug_fd);
33742bfe448SAnup Patel }
33842bfe448SAnup Patel
kvm_cpu__show_csrs(struct kvm_cpu * vcpu)33942bfe448SAnup Patel static void kvm_cpu__show_csrs(struct kvm_cpu *vcpu)
34042bfe448SAnup Patel {
34142bfe448SAnup Patel struct kvm_one_reg reg;
34242bfe448SAnup Patel struct kvm_riscv_csr csr;
34342bfe448SAnup Patel unsigned long data;
34442bfe448SAnup Patel int debug_fd = kvm_cpu__get_debug_fd();
34542bfe448SAnup Patel
34642bfe448SAnup Patel reg.addr = (unsigned long)&data;
34742bfe448SAnup Patel dprintf(debug_fd, "\n Control Status Registers:\n");
34842bfe448SAnup Patel dprintf(debug_fd, " ------------------------\n");
34942bfe448SAnup Patel
35042bfe448SAnup Patel reg.id = RISCV_CSR_REG(sstatus);
35142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
35242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sstatus)");
35342bfe448SAnup Patel csr.sstatus = data;
35442bfe448SAnup Patel
35542bfe448SAnup Patel reg.id = RISCV_CSR_REG(sie);
35642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
35742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sie)");
35842bfe448SAnup Patel csr.sie = data;
35942bfe448SAnup Patel
36042bfe448SAnup Patel reg.id = RISCV_CSR_REG(stvec);
36142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
36242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (stvec)");
36342bfe448SAnup Patel csr.stvec = data;
36442bfe448SAnup Patel
36542bfe448SAnup Patel reg.id = RISCV_CSR_REG(sip);
36642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
36742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sip)");
36842bfe448SAnup Patel csr.sip = data;
36942bfe448SAnup Patel
37042bfe448SAnup Patel reg.id = RISCV_CSR_REG(satp);
37142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
37242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (satp)");
37342bfe448SAnup Patel csr.satp = data;
37442bfe448SAnup Patel
37542bfe448SAnup Patel reg.id = RISCV_CSR_REG(stval);
37642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
37742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (stval)");
37842bfe448SAnup Patel csr.stval = data;
37942bfe448SAnup Patel
38042bfe448SAnup Patel reg.id = RISCV_CSR_REG(scause);
38142bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
38242bfe448SAnup Patel die("KVM_GET_ONE_REG failed (SCAUSE)");
38342bfe448SAnup Patel csr.scause = data;
38442bfe448SAnup Patel
38542bfe448SAnup Patel reg.id = RISCV_CSR_REG(sscratch);
38642bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
38742bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sscartch)");
38842bfe448SAnup Patel csr.sscratch = data;
38942bfe448SAnup Patel dprintf(debug_fd, " SSTATUS: 0x%016lx\n", csr.sstatus);
39042bfe448SAnup Patel dprintf(debug_fd, " SIE: 0x%016lx\n", csr.sie);
39142bfe448SAnup Patel dprintf(debug_fd, " STVEC: 0x%016lx\n", csr.stvec);
39242bfe448SAnup Patel dprintf(debug_fd, " SIP: 0x%016lx\n", csr.sip);
39342bfe448SAnup Patel dprintf(debug_fd, " SATP: 0x%016lx\n", csr.satp);
39442bfe448SAnup Patel dprintf(debug_fd, " STVAL: 0x%016lx\n", csr.stval);
39542bfe448SAnup Patel dprintf(debug_fd, " SCAUSE: 0x%016lx\n", csr.scause);
39642bfe448SAnup Patel dprintf(debug_fd, " SSCRATCH: 0x%016lx\n", csr.sscratch);
3972e996783SAnup Patel }
3982e996783SAnup Patel
kvm_cpu__show_registers(struct kvm_cpu * vcpu)3992e996783SAnup Patel void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
4002e996783SAnup Patel {
40142bfe448SAnup Patel struct kvm_one_reg reg;
40242bfe448SAnup Patel unsigned long data;
40342bfe448SAnup Patel int debug_fd = kvm_cpu__get_debug_fd();
40442bfe448SAnup Patel struct kvm_riscv_core core;
40542bfe448SAnup Patel
40642bfe448SAnup Patel reg.addr = (unsigned long)&data;
40742bfe448SAnup Patel
40842bfe448SAnup Patel reg.id = RISCV_CORE_REG(mode);
40942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
41042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (mode)");
41142bfe448SAnup Patel core.mode = data;
41242bfe448SAnup Patel
41342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.pc);
41442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
41542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (pc)");
41642bfe448SAnup Patel core.regs.pc = data;
41742bfe448SAnup Patel
41842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.ra);
41942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
42042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (ra)");
42142bfe448SAnup Patel core.regs.ra = data;
42242bfe448SAnup Patel
42342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.sp);
42442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
42542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (sp)");
42642bfe448SAnup Patel core.regs.sp = data;
42742bfe448SAnup Patel
42842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.gp);
42942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
43042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (gp)");
43142bfe448SAnup Patel core.regs.gp = data;
43242bfe448SAnup Patel
43342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.tp);
43442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
43542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (tp)");
43642bfe448SAnup Patel core.regs.tp = data;
43742bfe448SAnup Patel
43842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t0);
43942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
44042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t0)");
44142bfe448SAnup Patel core.regs.t0 = data;
44242bfe448SAnup Patel
44342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t1);
44442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
44542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t1)");
44642bfe448SAnup Patel core.regs.t1 = data;
44742bfe448SAnup Patel
44842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t2);
44942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
45042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t2)");
45142bfe448SAnup Patel core.regs.t2 = data;
45242bfe448SAnup Patel
45342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s0);
45442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
45542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s0)");
45642bfe448SAnup Patel core.regs.s0 = data;
45742bfe448SAnup Patel
45842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s1);
45942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
46042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s1)");
46142bfe448SAnup Patel core.regs.s1 = data;
46242bfe448SAnup Patel
46342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a0);
46442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
46542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a0)");
46642bfe448SAnup Patel core.regs.a0 = data;
46742bfe448SAnup Patel
46842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a1);
46942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
47042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a1)");
47142bfe448SAnup Patel core.regs.a1 = data;
47242bfe448SAnup Patel
47342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a2);
47442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
47542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a2)");
47642bfe448SAnup Patel core.regs.a2 = data;
47742bfe448SAnup Patel
47842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a3);
47942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
48042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a3)");
48142bfe448SAnup Patel core.regs.a3 = data;
48242bfe448SAnup Patel
48342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a4);
48442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
48542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a4)");
48642bfe448SAnup Patel core.regs.a4 = data;
48742bfe448SAnup Patel
48842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a5);
48942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
49042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a5)");
49142bfe448SAnup Patel core.regs.a5 = data;
49242bfe448SAnup Patel
49342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a6);
49442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
49542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a6)");
49642bfe448SAnup Patel core.regs.a6 = data;
49742bfe448SAnup Patel
49842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.a7);
49942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
50042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (a7)");
50142bfe448SAnup Patel core.regs.a7 = data;
50242bfe448SAnup Patel
50342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s2);
50442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
50542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s2)");
50642bfe448SAnup Patel core.regs.s2 = data;
50742bfe448SAnup Patel
50842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s3);
50942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
51042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s3)");
51142bfe448SAnup Patel core.regs.s3 = data;
51242bfe448SAnup Patel
51342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s4);
51442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
51542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s4)");
51642bfe448SAnup Patel core.regs.s4 = data;
51742bfe448SAnup Patel
51842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s5);
51942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
52042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s5)");
52142bfe448SAnup Patel core.regs.s5 = data;
52242bfe448SAnup Patel
52342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s6);
52442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
52542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s6)");
52642bfe448SAnup Patel core.regs.s6 = data;
52742bfe448SAnup Patel
52842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s7);
52942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
53042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s7)");
53142bfe448SAnup Patel core.regs.s7 = data;
53242bfe448SAnup Patel
53342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s8);
53442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
53542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s8)");
53642bfe448SAnup Patel core.regs.s8 = data;
53742bfe448SAnup Patel
53842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s9);
53942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
54042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s9)");
54142bfe448SAnup Patel core.regs.s9 = data;
54242bfe448SAnup Patel
54342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s10);
54442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
54542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s10)");
54642bfe448SAnup Patel core.regs.s10 = data;
54742bfe448SAnup Patel
54842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.s11);
54942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
55042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (s11)");
55142bfe448SAnup Patel core.regs.s11 = data;
55242bfe448SAnup Patel
55342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t3);
55442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
55542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t3)");
55642bfe448SAnup Patel core.regs.t3 = data;
55742bfe448SAnup Patel
55842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t4);
55942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
56042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t4)");
56142bfe448SAnup Patel core.regs.t4 = data;
56242bfe448SAnup Patel
56342bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t5);
56442bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
56542bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t5)");
56642bfe448SAnup Patel core.regs.t5 = data;
56742bfe448SAnup Patel
56842bfe448SAnup Patel reg.id = RISCV_CORE_REG(regs.t6);
56942bfe448SAnup Patel if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
57042bfe448SAnup Patel die("KVM_GET_ONE_REG failed (t6)");
57142bfe448SAnup Patel core.regs.t6 = data;
57242bfe448SAnup Patel
57342bfe448SAnup Patel dprintf(debug_fd, "\n General Purpose Registers:\n");
57442bfe448SAnup Patel dprintf(debug_fd, " -------------------------\n");
57542bfe448SAnup Patel dprintf(debug_fd, " MODE: 0x%lx\n", data);
57642bfe448SAnup Patel dprintf(debug_fd, " PC: 0x%016lx RA: 0x%016lx SP: 0x%016lx GP: 0x%016lx\n",
57742bfe448SAnup Patel core.regs.pc, core.regs.ra, core.regs.sp, core.regs.gp);
57842bfe448SAnup Patel dprintf(debug_fd, " TP: 0x%016lx T0: 0x%016lx T1: 0x%016lx T2: 0x%016lx\n",
57942bfe448SAnup Patel core.regs.tp, core.regs.t0, core.regs.t1, core.regs.t2);
58042bfe448SAnup Patel dprintf(debug_fd, " S0: 0x%016lx S1: 0x%016lx A0: 0x%016lx A1: 0x%016lx\n",
58142bfe448SAnup Patel core.regs.s0, core.regs.s1, core.regs.a0, core.regs.a1);
58242bfe448SAnup Patel dprintf(debug_fd, " A2: 0x%016lx A3: 0x%016lx A4: 0x%016lx A5: 0x%016lx\n",
58342bfe448SAnup Patel core.regs.a2, core.regs.a3, core.regs.a4, core.regs.a5);
58442bfe448SAnup Patel dprintf(debug_fd, " A6: 0x%016lx A7: 0x%016lx S2: 0x%016lx S3: 0x%016lx\n",
58542bfe448SAnup Patel core.regs.a6, core.regs.a7, core.regs.s2, core.regs.s3);
58642bfe448SAnup Patel dprintf(debug_fd, " S4: 0x%016lx S5: 0x%016lx S6: 0x%016lx S7: 0x%016lx\n",
58742bfe448SAnup Patel core.regs.s4, core.regs.s5, core.regs.s6, core.regs.s7);
58842bfe448SAnup Patel dprintf(debug_fd, " S8: 0x%016lx S9: 0x%016lx S10: 0x%016lx S11: 0x%016lx\n",
58942bfe448SAnup Patel core.regs.s8, core.regs.s9, core.regs.s10, core.regs.s11);
59042bfe448SAnup Patel dprintf(debug_fd, " T3: 0x%016lx T4: 0x%016lx T5: 0x%016lx T6: 0x%016lx\n",
59142bfe448SAnup Patel core.regs.t3, core.regs.t4, core.regs.t5, core.regs.t6);
59242bfe448SAnup Patel
59342bfe448SAnup Patel kvm_cpu__show_csrs(vcpu);
5942e996783SAnup Patel }
595