Skip to content

Commit 3608b17

Browse files
atishp04avpatel
authored andcommitted
KVM: riscv: selftests: Decode stval to identify exact exception type
Currently, the sbi_pmu_test continues if the exception type is illegal instruction because access to hpmcounter will generate that. However illegal instruction exception may occur due to the other reasons which should result in test assertion. Use the stval to decode the exact type of instructions and which csrs are being accessed if it is csr access instructions. Assert in all cases except if it is a csr access instructions that access valid PMU related registers. Take this opportunity to remove the CSR_CYCLEH reference as the test is compiled for RV64 only. Reviewed-by: Anup Patel <anup@brainfault.org> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Signed-off-by: Atish Patra <atishp@rivosinc.com> Link: https://lore.kernel.org/r/20250430-kvm_selftest_improve-v3-2-eea270ff080b@rivosinc.com Signed-off-by: Anup Patel <anup@brainfault.org>
1 parent e23bb06 commit 3608b17

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

tools/testing/selftests/kvm/include/riscv/processor.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@
1111
#include <asm/csr.h>
1212
#include "kvm_util.h"
1313

14+
#define INSN_OPCODE_MASK 0x007c
15+
#define INSN_OPCODE_SHIFT 2
16+
#define INSN_OPCODE_SYSTEM 28
17+
18+
#define INSN_MASK_FUNCT3 0x7000
19+
#define INSN_SHIFT_FUNCT3 12
20+
21+
#define INSN_CSR_MASK 0xfff00000
22+
#define INSN_CSR_SHIFT 20
23+
24+
#define GET_RM(insn) (((insn) & INSN_MASK_FUNCT3) >> INSN_SHIFT_FUNCT3)
25+
#define GET_CSR_NUM(insn) (((insn) & INSN_CSR_MASK) >> INSN_CSR_SHIFT)
26+
1427
static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t subtype,
1528
uint64_t idx, uint64_t size)
1629
{

tools/testing/selftests/kvm/riscv/sbi_pmu_test.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ unsigned long pmu_csr_read_num(int csr_num)
7373

7474
switch (csr_num) {
7575
switchcase_csr_read_32(CSR_CYCLE, ret)
76-
switchcase_csr_read_32(CSR_CYCLEH, ret)
7776
default :
7877
break;
7978
}
@@ -130,9 +129,28 @@ static void stop_counter(unsigned long counter, unsigned long stop_flags)
130129

131130
static void guest_illegal_exception_handler(struct pt_regs *regs)
132131
{
132+
unsigned long insn;
133+
int opcode, csr_num, funct3;
134+
133135
__GUEST_ASSERT(regs->cause == EXC_INST_ILLEGAL,
134136
"Unexpected exception handler %lx\n", regs->cause);
135137

138+
insn = regs->badaddr;
139+
opcode = (insn & INSN_OPCODE_MASK) >> INSN_OPCODE_SHIFT;
140+
__GUEST_ASSERT(opcode == INSN_OPCODE_SYSTEM,
141+
"Unexpected instruction with opcode 0x%x insn 0x%lx\n", opcode, insn);
142+
143+
csr_num = GET_CSR_NUM(insn);
144+
funct3 = GET_RM(insn);
145+
/* Validate if it is a CSR read/write operation */
146+
__GUEST_ASSERT(funct3 <= 7 && (funct3 != 0 && funct3 != 4),
147+
"Unexpected system opcode with funct3 0x%x csr_num 0x%x\n",
148+
funct3, csr_num);
149+
150+
/* Validate if it is a HPMCOUNTER CSR operation */
151+
__GUEST_ASSERT((csr_num >= CSR_CYCLE && csr_num <= CSR_HPMCOUNTER31),
152+
"Unexpected csr_num 0x%x\n", csr_num);
153+
136154
illegal_handler_invoked = true;
137155
/* skip the trapping instruction */
138156
regs->epc += 4;

0 commit comments

Comments
 (0)