xref: /linux/arch/riscv/kvm/vcpu_insn.c (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2019 Western Digital Corporation or its affiliates.
4  * Copyright (c) 2022 Ventana Micro Systems Inc.
5  */
6 
7 #include <linux/bitops.h>
8 #include <linux/kvm_host.h>
9 
10 #include <asm/cpufeature.h>
11 #include <asm/insn.h>
12 #include "trace.h"
13 
14 struct insn_func {
15 	unsigned long mask;
16 	unsigned long match;
17 	/*
18 	 * Possible return values are as follows:
19 	 * 1) Returns < 0 for error case
20 	 * 2) Returns 0 for exit to user-space
21 	 * 3) Returns 1 to continue with next sepc
22 	 * 4) Returns 2 to continue with same sepc
23 	 * 5) Returns 3 to inject illegal instruction trap and continue
24 	 * 6) Returns 4 to inject virtual instruction trap and continue
25 	 *
26 	 * Use enum kvm_insn_return for return values
27 	 */
28 	int (*func)(struct kvm_vcpu *vcpu, struct kvm_run *run, ulong insn);
29 };
30 
31 static int truly_illegal_insn(struct kvm_vcpu *vcpu, struct kvm_run *run,
32 			      ulong insn)
33 {
34 	struct kvm_cpu_trap utrap = { 0 };
35 
36 	/* Redirect trap to Guest VCPU */
37 	utrap.sepc = vcpu->arch.guest_context.sepc;
38 	utrap.scause = EXC_INST_ILLEGAL;
39 	utrap.stval = insn;
40 	utrap.htval = 0;
41 	utrap.htinst = 0;
42 	kvm_riscv_vcpu_trap_redirect(vcpu, &utrap);
43 
44 	return 1;
45 }
46 
47 static int truly_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run,
48 			      ulong insn)
49 {
50 	struct kvm_cpu_trap utrap = { 0 };
51 
52 	/* Redirect trap to Guest VCPU */
53 	utrap.sepc = vcpu->arch.guest_context.sepc;
54 	utrap.scause = EXC_VIRTUAL_INST_FAULT;
55 	utrap.stval = insn;
56 	utrap.htval = 0;
57 	utrap.htinst = 0;
58 	kvm_riscv_vcpu_trap_redirect(vcpu, &utrap);
59 
60 	return 1;
61 }
62 
63 /**
64  * kvm_riscv_vcpu_wfi -- Emulate wait for interrupt (WFI) behaviour
65  *
66  * @vcpu: The VCPU pointer
67  */
68 void kvm_riscv_vcpu_wfi(struct kvm_vcpu *vcpu)
69 {
70 	if (!kvm_arch_vcpu_runnable(vcpu)) {
71 		kvm_vcpu_srcu_read_unlock(vcpu);
72 		kvm_vcpu_halt(vcpu);
73 		kvm_vcpu_srcu_read_lock(vcpu);
74 	}
75 }
76 
77 static int wfi_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ulong insn)
78 {
79 	vcpu->stat.wfi_exit_stat++;
80 	kvm_riscv_vcpu_wfi(vcpu);
81 	return KVM_INSN_CONTINUE_NEXT_SEPC;
82 }
83 
84 static int wrs_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ulong insn)
85 {
86 	vcpu->stat.wrs_exit_stat++;
87 	kvm_vcpu_on_spin(vcpu, vcpu->arch.guest_context.sstatus & SR_SPP);
88 	return KVM_INSN_CONTINUE_NEXT_SEPC;
89 }
90 
91 struct csr_func {
92 	unsigned int base;
93 	unsigned int count;
94 	/*
95 	 * Possible return values are as same as "func" callback in
96 	 * "struct insn_func".
97 	 */
98 	int (*func)(struct kvm_vcpu *vcpu, unsigned int csr_num,
99 		    unsigned long *val, unsigned long new_val,
100 		    unsigned long wr_mask);
101 };
102 
103 static int seed_csr_rmw(struct kvm_vcpu *vcpu, unsigned int csr_num,
104 			unsigned long *val, unsigned long new_val,
105 			unsigned long wr_mask)
106 {
107 	if (!riscv_isa_extension_available(vcpu->arch.isa, ZKR))
108 		return KVM_INSN_ILLEGAL_TRAP;
109 
110 	return KVM_INSN_EXIT_TO_USER_SPACE;
111 }
112 
113 static const struct csr_func csr_funcs[] = {
114 	KVM_RISCV_VCPU_AIA_CSR_FUNCS
115 	KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS
116 	{ .base = CSR_SEED, .count = 1, .func = seed_csr_rmw },
117 };
118 
119 /**
120  * kvm_riscv_vcpu_csr_return -- Handle CSR read/write after user space
121  *				emulation or in-kernel emulation
122  *
123  * @vcpu: The VCPU pointer
124  * @run:  The VCPU run struct containing the CSR data
125  *
126  * Returns > 0 upon failure and 0 upon success
127  */
128 int kvm_riscv_vcpu_csr_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
129 {
130 	ulong insn;
131 
132 	if (vcpu->arch.csr_decode.return_handled)
133 		return 0;
134 	vcpu->arch.csr_decode.return_handled = 1;
135 
136 	/* Update destination register for CSR reads */
137 	insn = vcpu->arch.csr_decode.insn;
138 	if ((insn >> SH_RD) & MASK_RX)
139 		SET_RD(insn, &vcpu->arch.guest_context,
140 		       run->riscv_csr.ret_value);
141 
142 	/* Move to next instruction */
143 	vcpu->arch.guest_context.sepc += INSN_LEN(insn);
144 
145 	return 0;
146 }
147 
148 static int csr_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, ulong insn)
149 {
150 	int i, rc = KVM_INSN_ILLEGAL_TRAP;
151 	unsigned int csr_num = insn >> SH_RS2;
152 	unsigned int rs1_num = (insn >> SH_RS1) & MASK_RX;
153 	ulong rs1_val = GET_RS1(insn, &vcpu->arch.guest_context);
154 	const struct csr_func *tcfn, *cfn = NULL;
155 	ulong val = 0, wr_mask = 0, new_val = 0;
156 
157 	/* Decode the CSR instruction */
158 	switch (GET_FUNCT3(insn)) {
159 	case GET_FUNCT3(INSN_MATCH_CSRRW):
160 		wr_mask = -1UL;
161 		new_val = rs1_val;
162 		break;
163 	case GET_FUNCT3(INSN_MATCH_CSRRS):
164 		wr_mask = rs1_val;
165 		new_val = -1UL;
166 		break;
167 	case GET_FUNCT3(INSN_MATCH_CSRRC):
168 		wr_mask = rs1_val;
169 		new_val = 0;
170 		break;
171 	case GET_FUNCT3(INSN_MATCH_CSRRWI):
172 		wr_mask = -1UL;
173 		new_val = rs1_num;
174 		break;
175 	case GET_FUNCT3(INSN_MATCH_CSRRSI):
176 		wr_mask = rs1_num;
177 		new_val = -1UL;
178 		break;
179 	case GET_FUNCT3(INSN_MATCH_CSRRCI):
180 		wr_mask = rs1_num;
181 		new_val = 0;
182 		break;
183 	default:
184 		return rc;
185 	}
186 
187 	/* Save instruction decode info */
188 	vcpu->arch.csr_decode.insn = insn;
189 	vcpu->arch.csr_decode.return_handled = 0;
190 
191 	/* Update CSR details in kvm_run struct */
192 	run->riscv_csr.csr_num = csr_num;
193 	run->riscv_csr.new_value = new_val;
194 	run->riscv_csr.write_mask = wr_mask;
195 	run->riscv_csr.ret_value = 0;
196 
197 	/* Find in-kernel CSR function */
198 	for (i = 0; i < ARRAY_SIZE(csr_funcs); i++) {
199 		tcfn = &csr_funcs[i];
200 		if ((tcfn->base <= csr_num) &&
201 		    (csr_num < (tcfn->base + tcfn->count))) {
202 			cfn = tcfn;
203 			break;
204 		}
205 	}
206 
207 	/* First try in-kernel CSR emulation */
208 	if (cfn && cfn->func) {
209 		rc = cfn->func(vcpu, csr_num, &val, new_val, wr_mask);
210 		if (rc > KVM_INSN_EXIT_TO_USER_SPACE) {
211 			if (rc == KVM_INSN_CONTINUE_NEXT_SEPC) {
212 				run->riscv_csr.ret_value = val;
213 				vcpu->stat.csr_exit_kernel++;
214 				kvm_riscv_vcpu_csr_return(vcpu, run);
215 				rc = KVM_INSN_CONTINUE_SAME_SEPC;
216 			}
217 			return rc;
218 		}
219 	}
220 
221 	/* Exit to user-space for CSR emulation */
222 	if (rc <= KVM_INSN_EXIT_TO_USER_SPACE) {
223 		vcpu->stat.csr_exit_user++;
224 		run->exit_reason = KVM_EXIT_RISCV_CSR;
225 	}
226 
227 	return rc;
228 }
229 
230 static const struct insn_func system_opcode_funcs[] = {
231 	{
232 		.mask  = INSN_MASK_CSRRW,
233 		.match = INSN_MATCH_CSRRW,
234 		.func  = csr_insn,
235 	},
236 	{
237 		.mask  = INSN_MASK_CSRRS,
238 		.match = INSN_MATCH_CSRRS,
239 		.func  = csr_insn,
240 	},
241 	{
242 		.mask  = INSN_MASK_CSRRC,
243 		.match = INSN_MATCH_CSRRC,
244 		.func  = csr_insn,
245 	},
246 	{
247 		.mask  = INSN_MASK_CSRRWI,
248 		.match = INSN_MATCH_CSRRWI,
249 		.func  = csr_insn,
250 	},
251 	{
252 		.mask  = INSN_MASK_CSRRSI,
253 		.match = INSN_MATCH_CSRRSI,
254 		.func  = csr_insn,
255 	},
256 	{
257 		.mask  = INSN_MASK_CSRRCI,
258 		.match = INSN_MATCH_CSRRCI,
259 		.func  = csr_insn,
260 	},
261 	{
262 		.mask  = INSN_MASK_WFI,
263 		.match = INSN_MATCH_WFI,
264 		.func  = wfi_insn,
265 	},
266 	{
267 		.mask  = INSN_MASK_WRS,
268 		.match = INSN_MATCH_WRS,
269 		.func  = wrs_insn,
270 	},
271 };
272 
273 static int system_opcode_insn(struct kvm_vcpu *vcpu, struct kvm_run *run,
274 			      ulong insn)
275 {
276 	int i, rc = KVM_INSN_ILLEGAL_TRAP;
277 	const struct insn_func *ifn;
278 
279 	for (i = 0; i < ARRAY_SIZE(system_opcode_funcs); i++) {
280 		ifn = &system_opcode_funcs[i];
281 		if ((insn & ifn->mask) == ifn->match) {
282 			rc = ifn->func(vcpu, run, insn);
283 			break;
284 		}
285 	}
286 
287 	switch (rc) {
288 	case KVM_INSN_ILLEGAL_TRAP:
289 		return truly_illegal_insn(vcpu, run, insn);
290 	case KVM_INSN_VIRTUAL_TRAP:
291 		return truly_virtual_insn(vcpu, run, insn);
292 	case KVM_INSN_CONTINUE_NEXT_SEPC:
293 		vcpu->arch.guest_context.sepc += INSN_LEN(insn);
294 		break;
295 	default:
296 		break;
297 	}
298 
299 	return (rc <= 0) ? rc : 1;
300 }
301 
302 static bool is_load_guest_page_fault(unsigned long scause)
303 {
304 	/**
305 	 * If a g-stage page fault occurs, the direct approach
306 	 * is to let the g-stage page fault handler handle it
307 	 * naturally, however, calling the g-stage page fault
308 	 * handler here seems rather strange.
309 	 * Considering this is a corner case, we can directly
310 	 * return to the guest and re-execute the same PC, this
311 	 * will trigger a g-stage page fault again and then the
312 	 * regular g-stage page fault handler will populate
313 	 * g-stage page table.
314 	 */
315 	return (scause == EXC_LOAD_GUEST_PAGE_FAULT);
316 }
317 
318 /**
319  * kvm_riscv_vcpu_virtual_insn -- Handle virtual instruction trap
320  *
321  * @vcpu: The VCPU pointer
322  * @run:  The VCPU run struct containing the mmio data
323  * @trap: Trap details
324  *
325  * Returns > 0 to continue run-loop
326  * Returns   0 to exit run-loop and handle in user-space.
327  * Returns < 0 to report failure and exit run-loop
328  */
329 int kvm_riscv_vcpu_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run,
330 				struct kvm_cpu_trap *trap)
331 {
332 	unsigned long insn = trap->stval;
333 	struct kvm_cpu_trap utrap = { 0 };
334 	struct kvm_cpu_context *ct;
335 
336 	if (unlikely(INSN_IS_16BIT(insn))) {
337 		if (insn == 0) {
338 			ct = &vcpu->arch.guest_context;
339 			insn = kvm_riscv_vcpu_unpriv_read(vcpu, true,
340 							  ct->sepc,
341 							  &utrap);
342 			if (utrap.scause) {
343 				if (is_load_guest_page_fault(utrap.scause))
344 					return 1;
345 				utrap.sepc = ct->sepc;
346 				kvm_riscv_vcpu_trap_redirect(vcpu, &utrap);
347 				return 1;
348 			}
349 		}
350 		if (INSN_IS_16BIT(insn))
351 			return truly_illegal_insn(vcpu, run, insn);
352 	}
353 
354 	switch ((insn & INSN_OPCODE_MASK) >> INSN_OPCODE_SHIFT) {
355 	case INSN_OPCODE_SYSTEM:
356 		return system_opcode_insn(vcpu, run, insn);
357 	default:
358 		return truly_illegal_insn(vcpu, run, insn);
359 	}
360 }
361 
362 /**
363  * kvm_riscv_vcpu_mmio_load -- Emulate MMIO load instruction
364  *
365  * @vcpu: The VCPU pointer
366  * @run:  The VCPU run struct containing the mmio data
367  * @fault_addr: Guest physical address to load
368  * @htinst: Transformed encoding of the load instruction
369  *
370  * Returns > 0 to continue run-loop
371  * Returns   0 to exit run-loop and handle in user-space.
372  * Returns < 0 to report failure and exit run-loop
373  */
374 int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run,
375 			     gpa_t fault_addr,
376 			     unsigned long htinst)
377 {
378 	u8 data_buf[8];
379 	unsigned long insn, raw_insn;
380 	int shift = 0, len = 0, insn_len = 0;
381 	struct kvm_cpu_trap utrap = { 0 };
382 	struct kvm_cpu_context *ct = &vcpu->arch.guest_context;
383 
384 	/* Determine trapped instruction */
385 	if (htinst & 0x1) {
386 		/*
387 		 * Bit[0] == 1 implies trapped instruction value is
388 		 * transformed instruction or custom instruction.
389 		 */
390 		insn = htinst | INSN_16BIT_MASK;
391 		insn_len = (htinst & BIT(1)) ? INSN_LEN(insn) : 2;
392 	} else {
393 		/*
394 		 * Bit[0] == 0 implies trapped instruction value is
395 		 * zero or special value.
396 		 */
397 		insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc,
398 						  &utrap);
399 		if (utrap.scause) {
400 			if (is_load_guest_page_fault(utrap.scause))
401 				return 1;
402 			/* Redirect trap if we failed to read instruction */
403 			utrap.sepc = ct->sepc;
404 			kvm_riscv_vcpu_trap_redirect(vcpu, &utrap);
405 			return 1;
406 		}
407 		insn_len = INSN_LEN(insn);
408 	}
409 	raw_insn = insn;
410 
411 	/* Decode length of MMIO and shift */
412 	if ((insn & INSN_MASK_LW) == INSN_MATCH_LW) {
413 		len = 4;
414 		shift = 8 * (sizeof(ulong) - len);
415 	} else if ((insn & INSN_MASK_LB) == INSN_MATCH_LB) {
416 		len = 1;
417 		shift = 8 * (sizeof(ulong) - len);
418 	} else if ((insn & INSN_MASK_LBU) == INSN_MATCH_LBU) {
419 		len = 1;
420 #ifdef CONFIG_64BIT
421 	} else if ((insn & INSN_MASK_LD) == INSN_MATCH_LD) {
422 		len = 8;
423 		shift = 8 * (sizeof(ulong) - len);
424 	} else if ((insn & INSN_MASK_LWU) == INSN_MATCH_LWU) {
425 		len = 4;
426 #endif
427 	} else if ((insn & INSN_MASK_LH) == INSN_MATCH_LH) {
428 		len = 2;
429 		shift = 8 * (sizeof(ulong) - len);
430 	} else if ((insn & INSN_MASK_LHU) == INSN_MATCH_LHU) {
431 		len = 2;
432 #ifdef CONFIG_64BIT
433 	} else if ((insn & INSN_MASK_C_LD) == INSN_MATCH_C_LD) {
434 		len = 8;
435 		shift = 8 * (sizeof(ulong) - len);
436 		insn = RVC_RS2S(insn) << SH_RD;
437 	} else if ((insn & INSN_MASK_C_LDSP) == INSN_MATCH_C_LDSP &&
438 		   ((insn >> SH_RD) & 0x1f)) {
439 		len = 8;
440 		shift = 8 * (sizeof(ulong) - len);
441 #endif
442 	} else if ((insn & INSN_MASK_C_LW) == INSN_MATCH_C_LW) {
443 		len = 4;
444 		shift = 8 * (sizeof(ulong) - len);
445 		insn = RVC_RS2S(insn) << SH_RD;
446 	} else if ((insn & INSN_MASK_C_LWSP) == INSN_MATCH_C_LWSP &&
447 		   ((insn >> SH_RD) & 0x1f)) {
448 		len = 4;
449 		shift = 8 * (sizeof(ulong) - len);
450 	} else {
451 		return -EOPNOTSUPP;
452 	}
453 
454 	/* Fault address should be aligned to length of MMIO */
455 	if (fault_addr & (len - 1))
456 		return -EIO;
457 
458 	trace_kvm_mmio_emulate(vcpu->vcpu_id, ct->sepc, raw_insn, fault_addr,
459 			       false, len);
460 
461 	/* Save instruction decode info */
462 	vcpu->arch.mmio_decode.insn = insn;
463 	vcpu->arch.mmio_decode.insn_len = insn_len;
464 	vcpu->arch.mmio_decode.shift = shift;
465 	vcpu->arch.mmio_decode.len = len;
466 	vcpu->arch.mmio_decode.return_handled = 0;
467 
468 	/* Update MMIO details in kvm_run struct */
469 	run->mmio.is_write = false;
470 	run->mmio.phys_addr = fault_addr;
471 	run->mmio.len = len;
472 
473 	/* Try to handle MMIO access in the kernel */
474 	if (!kvm_io_bus_read(vcpu, KVM_MMIO_BUS, fault_addr, len, data_buf)) {
475 		/* Successfully handled MMIO access in the kernel so resume */
476 		memcpy(run->mmio.data, data_buf, len);
477 		vcpu->stat.mmio_exit_kernel++;
478 		kvm_riscv_vcpu_mmio_return(vcpu, run);
479 		return 1;
480 	}
481 
482 	/* Exit to userspace for MMIO emulation */
483 	vcpu->stat.mmio_exit_user++;
484 	run->exit_reason = KVM_EXIT_MMIO;
485 
486 	return 0;
487 }
488 
489 /**
490  * kvm_riscv_vcpu_mmio_store -- Emulate MMIO store instruction
491  *
492  * @vcpu: The VCPU pointer
493  * @run:  The VCPU run struct containing the mmio data
494  * @fault_addr: Guest physical address to store
495  * @htinst: Transformed encoding of the store instruction
496  *
497  * Returns > 0 to continue run-loop
498  * Returns   0 to exit run-loop and handle in user-space.
499  * Returns < 0 to report failure and exit run-loop
500  */
501 int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run,
502 			      gpa_t fault_addr,
503 			      unsigned long htinst)
504 {
505 	u8 data8;
506 	u16 data16;
507 	u32 data32;
508 	u64 data64;
509 	ulong data;
510 	unsigned long insn, raw_insn;
511 	int len = 0, insn_len = 0;
512 	struct kvm_cpu_trap utrap = { 0 };
513 	struct kvm_cpu_context *ct = &vcpu->arch.guest_context;
514 
515 	/* Determine trapped instruction */
516 	if (htinst & 0x1) {
517 		/*
518 		 * Bit[0] == 1 implies trapped instruction value is
519 		 * transformed instruction or custom instruction.
520 		 */
521 		insn = htinst | INSN_16BIT_MASK;
522 		insn_len = (htinst & BIT(1)) ? INSN_LEN(insn) : 2;
523 	} else {
524 		/*
525 		 * Bit[0] == 0 implies trapped instruction value is
526 		 * zero or special value.
527 		 */
528 		insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc,
529 						  &utrap);
530 		if (utrap.scause) {
531 			if (is_load_guest_page_fault(utrap.scause))
532 				return 1;
533 			/* Redirect trap if we failed to read instruction */
534 			utrap.sepc = ct->sepc;
535 			kvm_riscv_vcpu_trap_redirect(vcpu, &utrap);
536 			return 1;
537 		}
538 		insn_len = INSN_LEN(insn);
539 	}
540 	raw_insn = insn;
541 
542 	data = GET_RS2(insn, &vcpu->arch.guest_context);
543 	data8 = data16 = data32 = data64 = data;
544 
545 	if ((insn & INSN_MASK_SW) == INSN_MATCH_SW) {
546 		len = 4;
547 	} else if ((insn & INSN_MASK_SB) == INSN_MATCH_SB) {
548 		len = 1;
549 #ifdef CONFIG_64BIT
550 	} else if ((insn & INSN_MASK_SD) == INSN_MATCH_SD) {
551 		len = 8;
552 #endif
553 	} else if ((insn & INSN_MASK_SH) == INSN_MATCH_SH) {
554 		len = 2;
555 #ifdef CONFIG_64BIT
556 	} else if ((insn & INSN_MASK_C_SD) == INSN_MATCH_C_SD) {
557 		len = 8;
558 		data64 = GET_RS2S(insn, &vcpu->arch.guest_context);
559 	} else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP &&
560 		   ((insn >> SH_RD) & 0x1f)) {
561 		len = 8;
562 		data64 = GET_RS2C(insn, &vcpu->arch.guest_context);
563 #endif
564 	} else if ((insn & INSN_MASK_C_SW) == INSN_MATCH_C_SW) {
565 		len = 4;
566 		data32 = GET_RS2S(insn, &vcpu->arch.guest_context);
567 	} else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP &&
568 		   ((insn >> SH_RD) & 0x1f)) {
569 		len = 4;
570 		data32 = GET_RS2C(insn, &vcpu->arch.guest_context);
571 	} else {
572 		return -EOPNOTSUPP;
573 	}
574 
575 	/* Fault address should be aligned to length of MMIO */
576 	if (fault_addr & (len - 1))
577 		return -EIO;
578 
579 	trace_kvm_mmio_emulate(vcpu->vcpu_id, ct->sepc, raw_insn, fault_addr,
580 			       true, len);
581 
582 	/* Save instruction decode info */
583 	vcpu->arch.mmio_decode.insn = insn;
584 	vcpu->arch.mmio_decode.insn_len = insn_len;
585 	vcpu->arch.mmio_decode.shift = 0;
586 	vcpu->arch.mmio_decode.len = len;
587 	vcpu->arch.mmio_decode.return_handled = 0;
588 
589 	/* Copy data to kvm_run instance */
590 	switch (len) {
591 	case 1:
592 		*((u8 *)run->mmio.data) = data8;
593 		break;
594 	case 2:
595 		*((u16 *)run->mmio.data) = data16;
596 		break;
597 	case 4:
598 		*((u32 *)run->mmio.data) = data32;
599 		break;
600 	case 8:
601 		*((u64 *)run->mmio.data) = data64;
602 		break;
603 	default:
604 		return -EOPNOTSUPP;
605 	}
606 
607 	/* Update MMIO details in kvm_run struct */
608 	run->mmio.is_write = true;
609 	run->mmio.phys_addr = fault_addr;
610 	run->mmio.len = len;
611 
612 	/* Try to handle MMIO access in the kernel */
613 	if (!kvm_io_bus_write(vcpu, KVM_MMIO_BUS,
614 			      fault_addr, len, run->mmio.data)) {
615 		/* Successfully handled MMIO access in the kernel so resume */
616 		vcpu->stat.mmio_exit_kernel++;
617 		kvm_riscv_vcpu_mmio_return(vcpu, run);
618 		return 1;
619 	}
620 
621 	/* Exit to userspace for MMIO emulation */
622 	vcpu->stat.mmio_exit_user++;
623 	run->exit_reason = KVM_EXIT_MMIO;
624 
625 	return 0;
626 }
627 
628 /**
629  * kvm_riscv_vcpu_mmio_return -- Handle MMIO loads after user space emulation
630  *			     or in-kernel IO emulation
631  *
632  * @vcpu: The VCPU pointer
633  * @run:  The VCPU run struct containing the mmio data
634  */
635 int kvm_riscv_vcpu_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
636 {
637 	u8 data8;
638 	u16 data16;
639 	u32 data32;
640 	u64 data64;
641 	ulong insn;
642 	int len, shift;
643 
644 	if (vcpu->arch.mmio_decode.return_handled)
645 		return 0;
646 
647 	vcpu->arch.mmio_decode.return_handled = 1;
648 	insn = vcpu->arch.mmio_decode.insn;
649 
650 	if (run->mmio.is_write)
651 		goto done;
652 
653 	len = vcpu->arch.mmio_decode.len;
654 	shift = vcpu->arch.mmio_decode.shift;
655 
656 	switch (len) {
657 	case 1:
658 		data8 = *((u8 *)run->mmio.data);
659 		SET_RD(insn, &vcpu->arch.guest_context,
660 			(long)((ulong)data8 << shift) >> shift);
661 		break;
662 	case 2:
663 		data16 = *((u16 *)run->mmio.data);
664 		SET_RD(insn, &vcpu->arch.guest_context,
665 			(long)((ulong)data16 << shift) >> shift);
666 		break;
667 	case 4:
668 		data32 = *((u32 *)run->mmio.data);
669 		SET_RD(insn, &vcpu->arch.guest_context,
670 			(long)((ulong)data32 << shift) >> shift);
671 		break;
672 	case 8:
673 		data64 = *((u64 *)run->mmio.data);
674 		SET_RD(insn, &vcpu->arch.guest_context,
675 			(long)((ulong)data64 << shift) >> shift);
676 		break;
677 	default:
678 		return -EOPNOTSUPP;
679 	}
680 
681 done:
682 	/* Move to next instruction */
683 	vcpu->arch.guest_context.sepc += vcpu->arch.mmio_decode.insn_len;
684 
685 	return 0;
686 }
687