xref: /kvmtool/riscv/kvm-cpu.c (revision 4ddaa4249e0c59a9ef6e09c1e32b042dd01e4c08)
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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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, &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