linux-riscv.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] RISC-V KVM selftests improvements
@ 2025-04-30  0:18 Atish Patra
  2025-04-30  0:18 ` [PATCH v2 1/3] KVM: riscv: selftests: Align the trap information wiht pt_regs Atish Patra
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Atish Patra @ 2025-04-30  0:18 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paolo Bonzini, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Alexandre Ghiti, Andrew Jones
  Cc: kvm, kvm-riscv, linux-riscv, linux-kselftest, linux-kernel,
	Atish Patra

This series improves the following tests.
1. Get-reg-list : Adds vector support
2. SBI PMU test : Distinguish between different types of illegal exception

The first patch is just helper patch that adds stval support during
exception handling.

Signed-off-by: Atish Patra <atishp@rivosinc.com>
---
Changes in v2:
- Rebased on top of Linux 6.15-rc4
- Changed from ex_regs to pt_regs based on Drew's suggestion. 
- Dropped Anup's review on PATCH1 as it is significantly changed from last review.
- Moved the instruction decoding macros to a common header file.
- Improved the vector reg list test as per the feedback.
- Link to v1: https://lore.kernel.org/r/20250324-kvm_selftest_improve-v1-0-583620219d4f@rivosinc.com

---
Atish Patra (3):
      KVM: riscv: selftests: Align the trap information wiht pt_regs
      KVM: riscv: selftests: Decode stval to identify exact exception type
      KVM: riscv: selftests: Add vector extension tests

 .../selftests/kvm/include/riscv/processor.h        |  23 ++-
 tools/testing/selftests/kvm/lib/riscv/handlers.S   | 164 ++++++++++++---------
 tools/testing/selftests/kvm/lib/riscv/processor.c  |   2 +-
 tools/testing/selftests/kvm/riscv/arch_timer.c     |   2 +-
 tools/testing/selftests/kvm/riscv/ebreak_test.c    |   2 +-
 tools/testing/selftests/kvm/riscv/get-reg-list.c   | 133 +++++++++++++++++
 tools/testing/selftests/kvm/riscv/sbi_pmu_test.c   |  24 ++-
 7 files changed, 270 insertions(+), 80 deletions(-)
---
base-commit: f15d97df5afae16f40ecef942031235d1c6ba14f
change-id: 20250324-kvm_selftest_improve-9bedb9f0a6d3
--
Regards,
Atish patra


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 1/3] KVM: riscv: selftests: Align the trap information wiht pt_regs
  2025-04-30  0:18 [PATCH v2 0/3] RISC-V KVM selftests improvements Atish Patra
@ 2025-04-30  0:18 ` Atish Patra
  2025-04-30  7:05   ` Andrew Jones
  2025-04-30  0:18 ` [PATCH v2 2/3] KVM: riscv: selftests: Decode stval to identify exact exception type Atish Patra
  2025-04-30  0:18 ` [PATCH v2 3/3] KVM: riscv: selftests: Add vector extension tests Atish Patra
  2 siblings, 1 reply; 10+ messages in thread
From: Atish Patra @ 2025-04-30  0:18 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paolo Bonzini, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Alexandre Ghiti, Andrew Jones
  Cc: kvm, kvm-riscv, linux-riscv, linux-kselftest, linux-kernel,
	Atish Patra

The current exeception register structure in selftests are missing
few registers (e.g stval). Instead of adding it manually, change
the ex_regs to align with pt_regs to make it future proof.

Suggested-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
---
 .../selftests/kvm/include/riscv/processor.h        |  10 +-
 tools/testing/selftests/kvm/lib/riscv/handlers.S   | 164 ++++++++++++---------
 tools/testing/selftests/kvm/lib/riscv/processor.c  |   2 +-
 tools/testing/selftests/kvm/riscv/arch_timer.c     |   2 +-
 tools/testing/selftests/kvm/riscv/ebreak_test.c    |   2 +-
 tools/testing/selftests/kvm/riscv/sbi_pmu_test.c   |   4 +-
 6 files changed, 104 insertions(+), 80 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
index 5f389166338c..1b5aef87de0f 100644
--- a/tools/testing/selftests/kvm/include/riscv/processor.h
+++ b/tools/testing/selftests/kvm/include/riscv/processor.h
@@ -60,7 +60,8 @@ static inline bool __vcpu_has_sbi_ext(struct kvm_vcpu *vcpu, uint64_t sbi_ext)
 	return __vcpu_has_ext(vcpu, RISCV_SBI_EXT_REG(sbi_ext));
 }
 
-struct ex_regs {
+struct pt_regs {
+	unsigned long epc;
 	unsigned long ra;
 	unsigned long sp;
 	unsigned long gp;
@@ -92,16 +93,19 @@ struct ex_regs {
 	unsigned long t4;
 	unsigned long t5;
 	unsigned long t6;
-	unsigned long epc;
+	/* Supervisor/Machine CSRs */
 	unsigned long status;
+	unsigned long badaddr;
 	unsigned long cause;
+	/* a0 value before the syscall */
+	unsigned long orig_a0;
 };
 
 #define NR_VECTORS  2
 #define NR_EXCEPTIONS  32
 #define EC_MASK  (NR_EXCEPTIONS - 1)
 
-typedef void(*exception_handler_fn)(struct ex_regs *);
+typedef void(*exception_handler_fn)(struct pt_regs *);
 
 void vm_init_vector_tables(struct kvm_vm *vm);
 void vcpu_init_vector_tables(struct kvm_vcpu *vcpu);
diff --git a/tools/testing/selftests/kvm/lib/riscv/handlers.S b/tools/testing/selftests/kvm/lib/riscv/handlers.S
index aa0abd3f35bb..9c99b258cae7 100644
--- a/tools/testing/selftests/kvm/lib/riscv/handlers.S
+++ b/tools/testing/selftests/kvm/lib/riscv/handlers.S
@@ -9,86 +9,106 @@
 
 #include <asm/csr.h>
 
+#ifdef __ASSEMBLY__
+#define __ASM_STR(x)	x
+#else
+#define __ASM_STR(x)	#x
+#endif
+
+#if __riscv_xlen == 64
+#define __REG_SEL(a, b)	__ASM_STR(a)
+#elif __riscv_xlen == 32
+#define __REG_SEL(a, b)	__ASM_STR(b)
+#else
+#error "Unexpected __riscv_xlen"
+#endif
+
+#define REG_L		__REG_SEL(ld, lw)
+#define REG_S		__REG_SEL(sd, sw)
+
 .macro save_context
-	addi  sp, sp, (-8*34)
-	sd    x1, 0(sp)
-	sd    x2, 8(sp)
-	sd    x3, 16(sp)
-	sd    x4, 24(sp)
-	sd    x5, 32(sp)
-	sd    x6, 40(sp)
-	sd    x7, 48(sp)
-	sd    x8, 56(sp)
-	sd    x9, 64(sp)
-	sd    x10, 72(sp)
-	sd    x11, 80(sp)
-	sd    x12, 88(sp)
-	sd    x13, 96(sp)
-	sd    x14, 104(sp)
-	sd    x15, 112(sp)
-	sd    x16, 120(sp)
-	sd    x17, 128(sp)
-	sd    x18, 136(sp)
-	sd    x19, 144(sp)
-	sd    x20, 152(sp)
-	sd    x21, 160(sp)
-	sd    x22, 168(sp)
-	sd    x23, 176(sp)
-	sd    x24, 184(sp)
-	sd    x25, 192(sp)
-	sd    x26, 200(sp)
-	sd    x27, 208(sp)
-	sd    x28, 216(sp)
-	sd    x29, 224(sp)
-	sd    x30, 232(sp)
-	sd    x31, 240(sp)
+	addi  sp, sp, (-8*36)
+	REG_S    x1, 8(sp)
+	REG_S    x2, 16(sp)
+	REG_S    x3, 24(sp)
+	REG_S    x4, 32(sp)
+	REG_S    x5, 40(sp)
+	REG_S    x6, 48(sp)
+	REG_S    x7, 56(sp)
+	REG_S    x8, 64(sp)
+	REG_S    x9, 72(sp)
+	REG_S    x10, 80(sp)
+	REG_S    x11, 88(sp)
+	REG_S    x12, 96(sp)
+	REG_S    x13, 104(sp)
+	REG_S    x14, 112(sp)
+	REG_S    x15, 120(sp)
+	REG_S    x16, 128(sp)
+	REG_S    x17, 136(sp)
+	REG_S    x18, 144(sp)
+	REG_S    x19, 152(sp)
+	REG_S    x20, 160(sp)
+	REG_S    x21, 168(sp)
+	REG_S    x22, 176(sp)
+	REG_S    x23, 184(sp)
+	REG_S    x24, 192(sp)
+	REG_S    x25, 200(sp)
+	REG_S    x26, 208(sp)
+	REG_S    x27, 216(sp)
+	REG_S    x28, 224(sp)
+	REG_S    x29, 232(sp)
+	REG_S    x30, 240(sp)
+	REG_S    x31, 248(sp)
 	csrr  s0, CSR_SEPC
 	csrr  s1, CSR_SSTATUS
-	csrr  s2, CSR_SCAUSE
-	sd    s0, 248(sp)
-	sd    s1, 256(sp)
-	sd    s2, 264(sp)
+	csrr  s2, CSR_STVAL
+	csrr  s3, CSR_SCAUSE
+	REG_S    s0, 0(sp)
+	REG_S    s1, 256(sp)
+	REG_S    s2, 264(sp)
+	REG_S    s3, 272(sp)
 .endm
 
 .macro restore_context
-	ld    s2, 264(sp)
-	ld    s1, 256(sp)
-	ld    s0, 248(sp)
-	csrw  CSR_SCAUSE, s2
+	REG_L    s3, 272(sp)
+	REG_L    s2, 264(sp)
+	REG_L    s1, 256(sp)
+	REG_L    s0, 0(sp)
+	csrw  CSR_SCAUSE, s3
 	csrw  CSR_SSTATUS, s1
 	csrw  CSR_SEPC, s0
-	ld    x31, 240(sp)
-	ld    x30, 232(sp)
-	ld    x29, 224(sp)
-	ld    x28, 216(sp)
-	ld    x27, 208(sp)
-	ld    x26, 200(sp)
-	ld    x25, 192(sp)
-	ld    x24, 184(sp)
-	ld    x23, 176(sp)
-	ld    x22, 168(sp)
-	ld    x21, 160(sp)
-	ld    x20, 152(sp)
-	ld    x19, 144(sp)
-	ld    x18, 136(sp)
-	ld    x17, 128(sp)
-	ld    x16, 120(sp)
-	ld    x15, 112(sp)
-	ld    x14, 104(sp)
-	ld    x13, 96(sp)
-	ld    x12, 88(sp)
-	ld    x11, 80(sp)
-	ld    x10, 72(sp)
-	ld    x9, 64(sp)
-	ld    x8, 56(sp)
-	ld    x7, 48(sp)
-	ld    x6, 40(sp)
-	ld    x5, 32(sp)
-	ld    x4, 24(sp)
-	ld    x3, 16(sp)
-	ld    x2, 8(sp)
-	ld    x1, 0(sp)
-	addi  sp, sp, (8*34)
+	REG_L    x31, 248(sp)
+	REG_L    x30, 240(sp)
+	REG_L    x29, 232(sp)
+	REG_L    x28, 224(sp)
+	REG_L    x27, 216(sp)
+	REG_L    x26, 208(sp)
+	REG_L    x25, 200(sp)
+	REG_L    x24, 192(sp)
+	REG_L    x23, 184(sp)
+	REG_L    x22, 176(sp)
+	REG_L    x21, 168(sp)
+	REG_L    x20, 160(sp)
+	REG_L    x19, 152(sp)
+	REG_L    x18, 144(sp)
+	REG_L    x17, 136(sp)
+	REG_L    x16, 128(sp)
+	REG_L    x15, 120(sp)
+	REG_L    x14, 112(sp)
+	REG_L    x13, 104(sp)
+	REG_L    x12, 96(sp)
+	REG_L    x11, 88(sp)
+	REG_L    x10, 80(sp)
+	REG_L    x9, 72(sp)
+	REG_L    x8, 64(sp)
+	REG_L    x7, 56(sp)
+	REG_L    x6, 48(sp)
+	REG_L    x5, 40(sp)
+	REG_L    x4, 32(sp)
+	REG_L    x3, 24(sp)
+	REG_L    x2, 16(sp)
+	REG_L    x1, 8(sp)
+	addi  sp, sp, (8*36)
 .endm
 
 .balign 4
diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
index dd663bcf0cc0..2eac7d4b59e9 100644
--- a/tools/testing/selftests/kvm/lib/riscv/processor.c
+++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
@@ -402,7 +402,7 @@ struct handlers {
 	exception_handler_fn exception_handlers[NR_VECTORS][NR_EXCEPTIONS];
 };
 
-void route_exception(struct ex_regs *regs)
+void route_exception(struct pt_regs *regs)
 {
 	struct handlers *handlers = (struct handlers *)exception_handlers;
 	int vector = 0, ec;
diff --git a/tools/testing/selftests/kvm/riscv/arch_timer.c b/tools/testing/selftests/kvm/riscv/arch_timer.c
index 9e370800a6a2..f962fefc48fa 100644
--- a/tools/testing/selftests/kvm/riscv/arch_timer.c
+++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
@@ -15,7 +15,7 @@
 
 static int timer_irq = IRQ_S_TIMER;
 
-static void guest_irq_handler(struct ex_regs *regs)
+static void guest_irq_handler(struct pt_regs *regs)
 {
 	uint64_t xcnt, xcnt_diff_us, cmp;
 	unsigned int intid = regs->cause & ~CAUSE_IRQ_FLAG;
diff --git a/tools/testing/selftests/kvm/riscv/ebreak_test.c b/tools/testing/selftests/kvm/riscv/ebreak_test.c
index cfed6c727bfc..739d17befb5a 100644
--- a/tools/testing/selftests/kvm/riscv/ebreak_test.c
+++ b/tools/testing/selftests/kvm/riscv/ebreak_test.c
@@ -27,7 +27,7 @@ static void guest_code(void)
 	GUEST_DONE();
 }
 
-static void guest_breakpoint_handler(struct ex_regs *regs)
+static void guest_breakpoint_handler(struct pt_regs *regs)
 {
 	WRITE_ONCE(sw_bp_addr, regs->epc);
 	regs->epc += 4;
diff --git a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
index 03406de4989d..6e66833e5941 100644
--- a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
+++ b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
@@ -128,7 +128,7 @@ static void stop_counter(unsigned long counter, unsigned long stop_flags)
 		       "Unable to stop counter %ld error %ld\n", counter, ret.error);
 }
 
-static void guest_illegal_exception_handler(struct ex_regs *regs)
+static void guest_illegal_exception_handler(struct pt_regs *regs)
 {
 	__GUEST_ASSERT(regs->cause == EXC_INST_ILLEGAL,
 		       "Unexpected exception handler %lx\n", regs->cause);
@@ -138,7 +138,7 @@ static void guest_illegal_exception_handler(struct ex_regs *regs)
 	regs->epc += 4;
 }
 
-static void guest_irq_handler(struct ex_regs *regs)
+static void guest_irq_handler(struct pt_regs *regs)
 {
 	unsigned int irq_num = regs->cause & ~CAUSE_IRQ_FLAG;
 	struct riscv_pmu_snapshot_data *snapshot_data = snapshot_gva;

-- 
2.43.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 2/3] KVM: riscv: selftests: Decode stval to identify exact exception type
  2025-04-30  0:18 [PATCH v2 0/3] RISC-V KVM selftests improvements Atish Patra
  2025-04-30  0:18 ` [PATCH v2 1/3] KVM: riscv: selftests: Align the trap information wiht pt_regs Atish Patra
@ 2025-04-30  0:18 ` Atish Patra
  2025-04-30  7:09   ` Andrew Jones
  2025-04-30  0:18 ` [PATCH v2 3/3] KVM: riscv: selftests: Add vector extension tests Atish Patra
  2 siblings, 1 reply; 10+ messages in thread
From: Atish Patra @ 2025-04-30  0:18 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paolo Bonzini, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Alexandre Ghiti, Andrew Jones
  Cc: kvm, kvm-riscv, linux-riscv, linux-kselftest, linux-kernel,
	Atish Patra

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.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
---
 .../testing/selftests/kvm/include/riscv/processor.h  | 13 +++++++++++++
 tools/testing/selftests/kvm/riscv/sbi_pmu_test.c     | 20 ++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
index 1b5aef87de0f..162f303d9daa 100644
--- a/tools/testing/selftests/kvm/include/riscv/processor.h
+++ b/tools/testing/selftests/kvm/include/riscv/processor.h
@@ -11,6 +11,19 @@
 #include <asm/csr.h>
 #include "kvm_util.h"
 
+#define INSN_OPCODE_MASK	0x007c
+#define INSN_OPCODE_SHIFT	2
+#define INSN_OPCODE_SYSTEM	28
+
+#define INSN_MASK_FUNCT3	0x7000
+#define INSN_SHIFT_FUNCT3	12
+
+#define INSN_CSR_MASK		0xfff00000
+#define INSN_CSR_SHIFT		20
+
+#define GET_RM(insn)            (((insn) & INSN_MASK_FUNCT3) >> INSN_SHIFT_FUNCT3)
+#define GET_CSR_NUM(insn)       (((insn) & INSN_CSR_MASK) >> INSN_CSR_SHIFT)
+
 static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t subtype,
 				    uint64_t idx, uint64_t size)
 {
diff --git a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
index 6e66833e5941..3c47268df262 100644
--- a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
+++ b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
@@ -130,9 +130,29 @@ static void stop_counter(unsigned long counter, unsigned long stop_flags)
 
 static void guest_illegal_exception_handler(struct pt_regs *regs)
 {
+	unsigned long insn;
+	int opcode, csr_num, funct3;
+
 	__GUEST_ASSERT(regs->cause == EXC_INST_ILLEGAL,
 		       "Unexpected exception handler %lx\n", regs->cause);
 
+	insn = regs->badaddr;
+	opcode = (insn & INSN_OPCODE_MASK) >> INSN_OPCODE_SHIFT;
+	__GUEST_ASSERT(opcode == INSN_OPCODE_SYSTEM,
+		       "Unexpected instruction with opcode 0x%x insn 0x%lx\n", opcode, insn);
+
+	csr_num = GET_CSR_NUM(insn);
+	funct3 = GET_RM(insn);
+	/* Validate if it is a CSR read/write operation */
+	__GUEST_ASSERT(funct3 <= 7 && (funct3 != 0 && funct3 != 4),
+		       "Unexpected system opcode with funct3 0x%x csr_num 0x%x\n",
+		       funct3, csr_num);
+
+	/* Validate if it is a HPMCOUNTER CSR operation */
+	__GUEST_ASSERT((csr_num >= CSR_CYCLE && csr_num <= CSR_HPMCOUNTER31) ||
+		       (csr_num >= CSR_CYCLEH && csr_num <= CSR_HPMCOUNTER31H),
+		       "Unexpected csr_num 0x%x\n", csr_num);
+
 	illegal_handler_invoked = true;
 	/* skip the trapping instruction */
 	regs->epc += 4;

-- 
2.43.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 3/3] KVM: riscv: selftests: Add vector extension tests
  2025-04-30  0:18 [PATCH v2 0/3] RISC-V KVM selftests improvements Atish Patra
  2025-04-30  0:18 ` [PATCH v2 1/3] KVM: riscv: selftests: Align the trap information wiht pt_regs Atish Patra
  2025-04-30  0:18 ` [PATCH v2 2/3] KVM: riscv: selftests: Decode stval to identify exact exception type Atish Patra
@ 2025-04-30  0:18 ` Atish Patra
  2025-04-30  7:17   ` Andrew Jones
  2 siblings, 1 reply; 10+ messages in thread
From: Atish Patra @ 2025-04-30  0:18 UTC (permalink / raw)
  To: Anup Patel, Atish Patra, Paolo Bonzini, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Alexandre Ghiti, Andrew Jones
  Cc: kvm, kvm-riscv, linux-riscv, linux-kselftest, linux-kernel,
	Atish Patra

Add vector related tests with the ISA extension standard template.
However, the vector registers are bit tricky as the register length is
variable based on vlenb value of the system. That's why the macros are
defined with a default and overidden with actual value at runtime.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
---
 tools/testing/selftests/kvm/riscv/get-reg-list.c | 133 +++++++++++++++++++++++
 1 file changed, 133 insertions(+)

diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
index 569f2d67c9b8..814dd981ce0b 100644
--- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
+++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
@@ -17,6 +17,15 @@ enum {
 	VCPU_FEATURE_SBI_EXT,
 };
 
+enum {
+	KVM_RISC_V_REG_OFFSET_VSTART = 0,
+	KVM_RISC_V_REG_OFFSET_VL,
+	KVM_RISC_V_REG_OFFSET_VTYPE,
+	KVM_RISC_V_REG_OFFSET_VCSR,
+	KVM_RISC_V_REG_OFFSET_VLENB,
+	KVM_RISC_V_REG_OFFSET_MAX,
+};
+
 static bool isa_ext_cant_disable[KVM_RISCV_ISA_EXT_MAX];
 
 bool filter_reg(__u64 reg)
@@ -143,6 +152,39 @@ bool check_reject_set(int err)
 	return err == EINVAL;
 }
 
+static int override_vector_reg_size(struct kvm_vcpu *vcpu, struct vcpu_reg_sublist *s,
+				    uint64_t feature)
+{
+	unsigned long vlenb_reg = 0;
+	int rc;
+	u64 reg, size;
+
+	/* Enable V extension so that we can get the vlenb register */
+	rc = __vcpu_set_reg(vcpu, feature, 1);
+	if (rc)
+		return rc;
+
+	__vcpu_get_reg(vcpu, s->regs[KVM_RISC_V_REG_OFFSET_VLENB], &vlenb_reg);
+
+	if (!vlenb_reg) {
+		TEST_FAIL("Can't compute vector register size from zero vlenb\n");
+		return -EPERM;
+	}
+
+	size = __builtin_ctzl(vlenb_reg);
+	size <<= KVM_REG_SIZE_SHIFT;
+
+	for (int i = 0; i < 32; i++) {
+		reg = KVM_REG_RISCV | KVM_REG_RISCV_VECTOR | size | KVM_REG_RISCV_VECTOR_REG(i);
+		s->regs[KVM_RISC_V_REG_OFFSET_MAX + i] = reg;
+	}
+
+	/* We should assert if disabling failed here while enabling succeeded before */
+	vcpu_set_reg(vcpu, feature, 0);
+
+	return 0;
+}
+
 void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
 {
 	unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
@@ -172,6 +214,13 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
 		if (!s->feature)
 			continue;
 
+		if (s->feature == KVM_RISCV_ISA_EXT_V) {
+			feature = RISCV_ISA_EXT_REG(s->feature);
+			rc = override_vector_reg_size(vcpu, s, feature);
+			if (rc)
+				goto skip;
+		}
+
 		switch (s->feature_type) {
 		case VCPU_FEATURE_ISA_EXT:
 			feature = RISCV_ISA_EXT_REG(s->feature);
@@ -186,6 +235,7 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
 		/* Try to enable the desired extension */
 		__vcpu_set_reg(vcpu, feature, 1);
 
+skip:
 		/* Double check whether the desired extension was enabled */
 		__TEST_REQUIRE(__vcpu_has_ext(vcpu, feature),
 			       "%s not available, skipping tests", s->name);
@@ -410,6 +460,35 @@ static const char *fp_d_id_to_str(const char *prefix, __u64 id)
 	return strdup_printf("%lld /* UNKNOWN */", reg_off);
 }
 
+static const char *vector_id_to_str(const char *prefix, __u64 id)
+{
+	/* reg_off is the offset into struct __riscv_v_ext_state */
+	__u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_VECTOR);
+	int reg_index = 0;
+
+	assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_VECTOR);
+
+	if (reg_off >= KVM_REG_RISCV_VECTOR_REG(0))
+		reg_index = reg_off -  KVM_REG_RISCV_VECTOR_REG(0);
+	switch (reg_off) {
+	case KVM_REG_RISCV_VECTOR_REG(0) ...
+	     KVM_REG_RISCV_VECTOR_REG(31):
+		return strdup_printf("KVM_REG_RISCV_VECTOR_REG(%d)", reg_index);
+	case KVM_REG_RISCV_VECTOR_CSR_REG(vstart):
+		return "KVM_REG_RISCV_VECTOR_CSR_REG(vstart)";
+	case KVM_REG_RISCV_VECTOR_CSR_REG(vl):
+		return "KVM_REG_RISCV_VECTOR_CSR_REG(vl)";
+	case KVM_REG_RISCV_VECTOR_CSR_REG(vtype):
+		return "KVM_REG_RISCV_VECTOR_CSR_REG(vtype)";
+	case KVM_REG_RISCV_VECTOR_CSR_REG(vcsr):
+		return "KVM_REG_RISCV_VECTOR_CSR_REG(vcsr)";
+	case KVM_REG_RISCV_VECTOR_CSR_REG(vlenb):
+		return "KVM_REG_RISCV_VECTOR_CSR_REG(vlenb)";
+	}
+
+	return strdup_printf("%lld /* UNKNOWN */", reg_off);
+}
+
 #define KVM_ISA_EXT_ARR(ext)		\
 [KVM_RISCV_ISA_EXT_##ext] = "KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_" #ext
 
@@ -639,6 +718,9 @@ void print_reg(const char *prefix, __u64 id)
 	case KVM_REG_SIZE_U128:
 		reg_size = "KVM_REG_SIZE_U128";
 		break;
+	case KVM_REG_SIZE_U256:
+		reg_size = "KVM_REG_SIZE_U256";
+		break;
 	default:
 		printf("\tKVM_REG_RISCV | (%lld << KVM_REG_SIZE_SHIFT) | 0x%llx /* UNKNOWN */,\n",
 		       (id & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT, id & ~REG_MASK);
@@ -670,6 +752,10 @@ void print_reg(const char *prefix, __u64 id)
 		printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_FP_D | %s,\n",
 				reg_size, fp_d_id_to_str(prefix, id));
 		break;
+	case KVM_REG_RISCV_VECTOR:
+		printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_VECTOR | %s,\n",
+		       reg_size, vector_id_to_str(prefix, id));
+		break;
 	case KVM_REG_RISCV_ISA_EXT:
 		printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_ISA_EXT | %s,\n",
 				reg_size, isa_ext_id_to_str(prefix, id));
@@ -874,6 +960,48 @@ static __u64 fp_d_regs[] = {
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_D,
 };
 
+/* Define a default vector registers with length. This will be overwritten at runtime */
+static __u64 vector_regs[] = {
+	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vstart),
+	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vl),
+	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vtype),
+	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vcsr),
+	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vlenb),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(0),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(1),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(2),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(3),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(4),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(5),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(6),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(7),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(8),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(9),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(10),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(11),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(12),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(13),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(14),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(15),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(16),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(17),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(18),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(19),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(20),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(21),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(22),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(23),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(24),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(25),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(26),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(27),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(28),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(29),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(30),
+	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(31),
+	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_V,
+};
+
 #define SUBLIST_BASE \
 	{"base", .regs = base_regs, .regs_n = ARRAY_SIZE(base_regs), \
 	 .skips_set = base_skips_set, .skips_set_n = ARRAY_SIZE(base_skips_set),}
@@ -898,6 +1026,9 @@ static __u64 fp_d_regs[] = {
 	{"fp_d", .feature = KVM_RISCV_ISA_EXT_D, .regs = fp_d_regs, \
 		.regs_n = ARRAY_SIZE(fp_d_regs),}
 
+#define SUBLIST_V \
+	{"v", .feature = KVM_RISCV_ISA_EXT_V, .regs = vector_regs, .regs_n = ARRAY_SIZE(vector_regs),}
+
 #define KVM_ISA_EXT_SIMPLE_CONFIG(ext, extu)			\
 static __u64 regs_##ext[] = {					\
 	KVM_REG_RISCV | KVM_REG_SIZE_ULONG |			\
@@ -966,6 +1097,7 @@ KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
 KVM_ISA_EXT_SUBLIST_CONFIG(aia, AIA);
 KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, FP_F);
 KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, FP_D);
+KVM_ISA_EXT_SUBLIST_CONFIG(v, V);
 KVM_ISA_EXT_SIMPLE_CONFIG(h, H);
 KVM_ISA_EXT_SIMPLE_CONFIG(smnpm, SMNPM);
 KVM_ISA_EXT_SUBLIST_CONFIG(smstateen, SMSTATEEN);
@@ -1040,6 +1172,7 @@ struct vcpu_reg_list *vcpu_configs[] = {
 	&config_fp_f,
 	&config_fp_d,
 	&config_h,
+	&config_v,
 	&config_smnpm,
 	&config_smstateen,
 	&config_sscofpmf,

-- 
2.43.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/3] KVM: riscv: selftests: Align the trap information wiht pt_regs
  2025-04-30  0:18 ` [PATCH v2 1/3] KVM: riscv: selftests: Align the trap information wiht pt_regs Atish Patra
@ 2025-04-30  7:05   ` Andrew Jones
  2025-04-30  7:18     ` Atish Patra
  0 siblings, 1 reply; 10+ messages in thread
From: Andrew Jones @ 2025-04-30  7:05 UTC (permalink / raw)
  To: Atish Patra
  Cc: Anup Patel, Atish Patra, Paolo Bonzini, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Alexandre Ghiti, kvm, kvm-riscv, linux-riscv,
	linux-kselftest, linux-kernel

On Tue, Apr 29, 2025 at 05:18:45PM -0700, Atish Patra wrote:
> The current exeception register structure in selftests are missing
> few registers (e.g stval). Instead of adding it manually, change
> the ex_regs to align with pt_regs to make it future proof.
> 
> Suggested-by: Andrew Jones <ajones@ventanamicro.com>
> Signed-off-by: Atish Patra <atishp@rivosinc.com>
> ---
>  .../selftests/kvm/include/riscv/processor.h        |  10 +-
>  tools/testing/selftests/kvm/lib/riscv/handlers.S   | 164 ++++++++++++---------
>  tools/testing/selftests/kvm/lib/riscv/processor.c  |   2 +-
>  tools/testing/selftests/kvm/riscv/arch_timer.c     |   2 +-
>  tools/testing/selftests/kvm/riscv/ebreak_test.c    |   2 +-
>  tools/testing/selftests/kvm/riscv/sbi_pmu_test.c   |   4 +-
>  6 files changed, 104 insertions(+), 80 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
> index 5f389166338c..1b5aef87de0f 100644
> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> @@ -60,7 +60,8 @@ static inline bool __vcpu_has_sbi_ext(struct kvm_vcpu *vcpu, uint64_t sbi_ext)
>  	return __vcpu_has_ext(vcpu, RISCV_SBI_EXT_REG(sbi_ext));
>  }
>  
> -struct ex_regs {
> +struct pt_regs {
> +	unsigned long epc;
>  	unsigned long ra;
>  	unsigned long sp;
>  	unsigned long gp;
> @@ -92,16 +93,19 @@ struct ex_regs {
>  	unsigned long t4;
>  	unsigned long t5;
>  	unsigned long t6;
> -	unsigned long epc;
> +	/* Supervisor/Machine CSRs */
>  	unsigned long status;
> +	unsigned long badaddr;
>  	unsigned long cause;
> +	/* a0 value before the syscall */
> +	unsigned long orig_a0;
>  };
>  
>  #define NR_VECTORS  2
>  #define NR_EXCEPTIONS  32
>  #define EC_MASK  (NR_EXCEPTIONS - 1)
>  
> -typedef void(*exception_handler_fn)(struct ex_regs *);
> +typedef void(*exception_handler_fn)(struct pt_regs *);
>  
>  void vm_init_vector_tables(struct kvm_vm *vm);
>  void vcpu_init_vector_tables(struct kvm_vcpu *vcpu);
> diff --git a/tools/testing/selftests/kvm/lib/riscv/handlers.S b/tools/testing/selftests/kvm/lib/riscv/handlers.S
> index aa0abd3f35bb..9c99b258cae7 100644
> --- a/tools/testing/selftests/kvm/lib/riscv/handlers.S
> +++ b/tools/testing/selftests/kvm/lib/riscv/handlers.S
> @@ -9,86 +9,106 @@
>  
>  #include <asm/csr.h>
>  
> +#ifdef __ASSEMBLY__
> +#define __ASM_STR(x)	x
> +#else
> +#define __ASM_STR(x)	#x
> +#endif

We should always have __ASSEMBLY__ (or actually __ASSMEBLER__) defined
when compiling this .S file.

> +
> +#if __riscv_xlen == 64
> +#define __REG_SEL(a, b)	__ASM_STR(a)
> +#elif __riscv_xlen == 32
> +#define __REG_SEL(a, b)	__ASM_STR(b)
> +#else
> +#error "Unexpected __riscv_xlen"
> +#endif
> +
> +#define REG_L		__REG_SEL(ld, lw)
> +#define REG_S		__REG_SEL(sd, sw)

We don't need these macros since we only support 64-bit. We always
have -DCONFIG_64BIT appended to CFLAGS. But it doesn't hurt to
have them either...

> +
>  .macro save_context
> -	addi  sp, sp, (-8*34)
> -	sd    x1, 0(sp)
> -	sd    x2, 8(sp)
> -	sd    x3, 16(sp)
> -	sd    x4, 24(sp)
> -	sd    x5, 32(sp)
> -	sd    x6, 40(sp)
> -	sd    x7, 48(sp)
> -	sd    x8, 56(sp)
> -	sd    x9, 64(sp)
> -	sd    x10, 72(sp)
> -	sd    x11, 80(sp)
> -	sd    x12, 88(sp)
> -	sd    x13, 96(sp)
> -	sd    x14, 104(sp)
> -	sd    x15, 112(sp)
> -	sd    x16, 120(sp)
> -	sd    x17, 128(sp)
> -	sd    x18, 136(sp)
> -	sd    x19, 144(sp)
> -	sd    x20, 152(sp)
> -	sd    x21, 160(sp)
> -	sd    x22, 168(sp)
> -	sd    x23, 176(sp)
> -	sd    x24, 184(sp)
> -	sd    x25, 192(sp)
> -	sd    x26, 200(sp)
> -	sd    x27, 208(sp)
> -	sd    x28, 216(sp)
> -	sd    x29, 224(sp)
> -	sd    x30, 232(sp)
> -	sd    x31, 240(sp)
> +	addi  sp, sp, (-8*36)
> +	REG_S    x1, 8(sp)
> +	REG_S    x2, 16(sp)
> +	REG_S    x3, 24(sp)
> +	REG_S    x4, 32(sp)
> +	REG_S    x5, 40(sp)
> +	REG_S    x6, 48(sp)
> +	REG_S    x7, 56(sp)
> +	REG_S    x8, 64(sp)
> +	REG_S    x9, 72(sp)
> +	REG_S    x10, 80(sp)
> +	REG_S    x11, 88(sp)
> +	REG_S    x12, 96(sp)
> +	REG_S    x13, 104(sp)
> +	REG_S    x14, 112(sp)
> +	REG_S    x15, 120(sp)
> +	REG_S    x16, 128(sp)
> +	REG_S    x17, 136(sp)
> +	REG_S    x18, 144(sp)
> +	REG_S    x19, 152(sp)
> +	REG_S    x20, 160(sp)
> +	REG_S    x21, 168(sp)
> +	REG_S    x22, 176(sp)
> +	REG_S    x23, 184(sp)
> +	REG_S    x24, 192(sp)
> +	REG_S    x25, 200(sp)
> +	REG_S    x26, 208(sp)
> +	REG_S    x27, 216(sp)
> +	REG_S    x28, 224(sp)
> +	REG_S    x29, 232(sp)
> +	REG_S    x30, 240(sp)
> +	REG_S    x31, 248(sp)
>  	csrr  s0, CSR_SEPC
>  	csrr  s1, CSR_SSTATUS
> -	csrr  s2, CSR_SCAUSE
> -	sd    s0, 248(sp)
> -	sd    s1, 256(sp)
> -	sd    s2, 264(sp)
> +	csrr  s2, CSR_STVAL
> +	csrr  s3, CSR_SCAUSE
> +	REG_S    s0, 0(sp)
> +	REG_S    s1, 256(sp)
> +	REG_S    s2, 264(sp)
> +	REG_S    s3, 272(sp)
>  .endm
>  
>  .macro restore_context
> -	ld    s2, 264(sp)
> -	ld    s1, 256(sp)
> -	ld    s0, 248(sp)
> -	csrw  CSR_SCAUSE, s2
> +	REG_L    s3, 272(sp)
> +	REG_L    s2, 264(sp)
> +	REG_L    s1, 256(sp)
> +	REG_L    s0, 0(sp)
> +	csrw  CSR_SCAUSE, s3
>  	csrw  CSR_SSTATUS, s1
>  	csrw  CSR_SEPC, s0
> -	ld    x31, 240(sp)
> -	ld    x30, 232(sp)
> -	ld    x29, 224(sp)
> -	ld    x28, 216(sp)
> -	ld    x27, 208(sp)
> -	ld    x26, 200(sp)
> -	ld    x25, 192(sp)
> -	ld    x24, 184(sp)
> -	ld    x23, 176(sp)
> -	ld    x22, 168(sp)
> -	ld    x21, 160(sp)
> -	ld    x20, 152(sp)
> -	ld    x19, 144(sp)
> -	ld    x18, 136(sp)
> -	ld    x17, 128(sp)
> -	ld    x16, 120(sp)
> -	ld    x15, 112(sp)
> -	ld    x14, 104(sp)
> -	ld    x13, 96(sp)
> -	ld    x12, 88(sp)
> -	ld    x11, 80(sp)
> -	ld    x10, 72(sp)
> -	ld    x9, 64(sp)
> -	ld    x8, 56(sp)
> -	ld    x7, 48(sp)
> -	ld    x6, 40(sp)
> -	ld    x5, 32(sp)
> -	ld    x4, 24(sp)
> -	ld    x3, 16(sp)
> -	ld    x2, 8(sp)
> -	ld    x1, 0(sp)
> -	addi  sp, sp, (8*34)
> +	REG_L    x31, 248(sp)
> +	REG_L    x30, 240(sp)
> +	REG_L    x29, 232(sp)
> +	REG_L    x28, 224(sp)
> +	REG_L    x27, 216(sp)
> +	REG_L    x26, 208(sp)
> +	REG_L    x25, 200(sp)
> +	REG_L    x24, 192(sp)
> +	REG_L    x23, 184(sp)
> +	REG_L    x22, 176(sp)
> +	REG_L    x21, 168(sp)
> +	REG_L    x20, 160(sp)
> +	REG_L    x19, 152(sp)
> +	REG_L    x18, 144(sp)
> +	REG_L    x17, 136(sp)
> +	REG_L    x16, 128(sp)
> +	REG_L    x15, 120(sp)
> +	REG_L    x14, 112(sp)
> +	REG_L    x13, 104(sp)
> +	REG_L    x12, 96(sp)
> +	REG_L    x11, 88(sp)
> +	REG_L    x10, 80(sp)
> +	REG_L    x9, 72(sp)
> +	REG_L    x8, 64(sp)
> +	REG_L    x7, 56(sp)
> +	REG_L    x6, 48(sp)
> +	REG_L    x5, 40(sp)
> +	REG_L    x4, 32(sp)
> +	REG_L    x3, 24(sp)
> +	REG_L    x2, 16(sp)
> +	REG_L    x1, 8(sp)
> +	addi  sp, sp, (8*36)
>  .endm
>  
>  .balign 4
> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
> index dd663bcf0cc0..2eac7d4b59e9 100644
> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
> @@ -402,7 +402,7 @@ struct handlers {
>  	exception_handler_fn exception_handlers[NR_VECTORS][NR_EXCEPTIONS];
>  };
>  
> -void route_exception(struct ex_regs *regs)
> +void route_exception(struct pt_regs *regs)
>  {
>  	struct handlers *handlers = (struct handlers *)exception_handlers;
>  	int vector = 0, ec;
> diff --git a/tools/testing/selftests/kvm/riscv/arch_timer.c b/tools/testing/selftests/kvm/riscv/arch_timer.c
> index 9e370800a6a2..f962fefc48fa 100644
> --- a/tools/testing/selftests/kvm/riscv/arch_timer.c
> +++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
> @@ -15,7 +15,7 @@
>  
>  static int timer_irq = IRQ_S_TIMER;
>  
> -static void guest_irq_handler(struct ex_regs *regs)
> +static void guest_irq_handler(struct pt_regs *regs)
>  {
>  	uint64_t xcnt, xcnt_diff_us, cmp;
>  	unsigned int intid = regs->cause & ~CAUSE_IRQ_FLAG;
> diff --git a/tools/testing/selftests/kvm/riscv/ebreak_test.c b/tools/testing/selftests/kvm/riscv/ebreak_test.c
> index cfed6c727bfc..739d17befb5a 100644
> --- a/tools/testing/selftests/kvm/riscv/ebreak_test.c
> +++ b/tools/testing/selftests/kvm/riscv/ebreak_test.c
> @@ -27,7 +27,7 @@ static void guest_code(void)
>  	GUEST_DONE();
>  }
>  
> -static void guest_breakpoint_handler(struct ex_regs *regs)
> +static void guest_breakpoint_handler(struct pt_regs *regs)
>  {
>  	WRITE_ONCE(sw_bp_addr, regs->epc);
>  	regs->epc += 4;
> diff --git a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
> index 03406de4989d..6e66833e5941 100644
> --- a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
> +++ b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
> @@ -128,7 +128,7 @@ static void stop_counter(unsigned long counter, unsigned long stop_flags)
>  		       "Unable to stop counter %ld error %ld\n", counter, ret.error);
>  }
>  
> -static void guest_illegal_exception_handler(struct ex_regs *regs)
> +static void guest_illegal_exception_handler(struct pt_regs *regs)
>  {
>  	__GUEST_ASSERT(regs->cause == EXC_INST_ILLEGAL,
>  		       "Unexpected exception handler %lx\n", regs->cause);
> @@ -138,7 +138,7 @@ static void guest_illegal_exception_handler(struct ex_regs *regs)
>  	regs->epc += 4;
>  }
>  
> -static void guest_irq_handler(struct ex_regs *regs)
> +static void guest_irq_handler(struct pt_regs *regs)
>  {
>  	unsigned int irq_num = regs->cause & ~CAUSE_IRQ_FLAG;
>  	struct riscv_pmu_snapshot_data *snapshot_data = snapshot_gva;
> 
> -- 
> 2.43.0
>

Other than the macro comments,

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>

Thanks,
drew

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 2/3] KVM: riscv: selftests: Decode stval to identify exact exception type
  2025-04-30  0:18 ` [PATCH v2 2/3] KVM: riscv: selftests: Decode stval to identify exact exception type Atish Patra
@ 2025-04-30  7:09   ` Andrew Jones
  2025-04-30  7:20     ` Atish Patra
  0 siblings, 1 reply; 10+ messages in thread
From: Andrew Jones @ 2025-04-30  7:09 UTC (permalink / raw)
  To: Atish Patra
  Cc: Anup Patel, Atish Patra, Paolo Bonzini, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Alexandre Ghiti, kvm, kvm-riscv, linux-riscv,
	linux-kselftest, linux-kernel

On Tue, Apr 29, 2025 at 05:18:46PM -0700, Atish Patra wrote:
> 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.
> 
> Reviewed-by: Anup Patel <anup@brainfault.org>
> Signed-off-by: Atish Patra <atishp@rivosinc.com>
> ---
>  .../testing/selftests/kvm/include/riscv/processor.h  | 13 +++++++++++++
>  tools/testing/selftests/kvm/riscv/sbi_pmu_test.c     | 20 ++++++++++++++++++++
>  2 files changed, 33 insertions(+)
> 
> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
> index 1b5aef87de0f..162f303d9daa 100644
> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
> @@ -11,6 +11,19 @@
>  #include <asm/csr.h>
>  #include "kvm_util.h"
>  
> +#define INSN_OPCODE_MASK	0x007c
> +#define INSN_OPCODE_SHIFT	2
> +#define INSN_OPCODE_SYSTEM	28
> +
> +#define INSN_MASK_FUNCT3	0x7000
> +#define INSN_SHIFT_FUNCT3	12
> +
> +#define INSN_CSR_MASK		0xfff00000
> +#define INSN_CSR_SHIFT		20
> +
> +#define GET_RM(insn)            (((insn) & INSN_MASK_FUNCT3) >> INSN_SHIFT_FUNCT3)
> +#define GET_CSR_NUM(insn)       (((insn) & INSN_CSR_MASK) >> INSN_CSR_SHIFT)
> +
>  static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t subtype,
>  				    uint64_t idx, uint64_t size)
>  {
> diff --git a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
> index 6e66833e5941..3c47268df262 100644
> --- a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
> +++ b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
> @@ -130,9 +130,29 @@ static void stop_counter(unsigned long counter, unsigned long stop_flags)
>  
>  static void guest_illegal_exception_handler(struct pt_regs *regs)
>  {
> +	unsigned long insn;
> +	int opcode, csr_num, funct3;
> +
>  	__GUEST_ASSERT(regs->cause == EXC_INST_ILLEGAL,
>  		       "Unexpected exception handler %lx\n", regs->cause);
>  
> +	insn = regs->badaddr;
> +	opcode = (insn & INSN_OPCODE_MASK) >> INSN_OPCODE_SHIFT;
> +	__GUEST_ASSERT(opcode == INSN_OPCODE_SYSTEM,
> +		       "Unexpected instruction with opcode 0x%x insn 0x%lx\n", opcode, insn);
> +
> +	csr_num = GET_CSR_NUM(insn);
> +	funct3 = GET_RM(insn);
> +	/* Validate if it is a CSR read/write operation */
> +	__GUEST_ASSERT(funct3 <= 7 && (funct3 != 0 && funct3 != 4),
> +		       "Unexpected system opcode with funct3 0x%x csr_num 0x%x\n",
> +		       funct3, csr_num);
> +
> +	/* Validate if it is a HPMCOUNTER CSR operation */
> +	__GUEST_ASSERT((csr_num >= CSR_CYCLE && csr_num <= CSR_HPMCOUNTER31) ||
> +		       (csr_num >= CSR_CYCLEH && csr_num <= CSR_HPMCOUNTER31H),

We should never get csr accesses to the rv32 high registers since we only
support 64-bit.

> +		       "Unexpected csr_num 0x%x\n", csr_num);
> +
>  	illegal_handler_invoked = true;
>  	/* skip the trapping instruction */
>  	regs->epc += 4;
> 
> -- 
> 2.43.0
>

Otherwise,

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 3/3] KVM: riscv: selftests: Add vector extension tests
  2025-04-30  0:18 ` [PATCH v2 3/3] KVM: riscv: selftests: Add vector extension tests Atish Patra
@ 2025-04-30  7:17   ` Andrew Jones
  2025-04-30  7:22     ` Atish Patra
  0 siblings, 1 reply; 10+ messages in thread
From: Andrew Jones @ 2025-04-30  7:17 UTC (permalink / raw)
  To: Atish Patra
  Cc: Anup Patel, Atish Patra, Paolo Bonzini, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Alexandre Ghiti, kvm, kvm-riscv, linux-riscv,
	linux-kselftest, linux-kernel

On Tue, Apr 29, 2025 at 05:18:47PM -0700, Atish Patra wrote:
> Add vector related tests with the ISA extension standard template.
> However, the vector registers are bit tricky as the register length is
> variable based on vlenb value of the system. That's why the macros are
> defined with a default and overidden with actual value at runtime.
> 
> Reviewed-by: Anup Patel <anup@brainfault.org>
> Signed-off-by: Atish Patra <atishp@rivosinc.com>
> ---
>  tools/testing/selftests/kvm/riscv/get-reg-list.c | 133 +++++++++++++++++++++++
>  1 file changed, 133 insertions(+)
> 
> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> index 569f2d67c9b8..814dd981ce0b 100644
> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
> @@ -17,6 +17,15 @@ enum {
>  	VCPU_FEATURE_SBI_EXT,
>  };
>  
> +enum {
> +	KVM_RISC_V_REG_OFFSET_VSTART = 0,
> +	KVM_RISC_V_REG_OFFSET_VL,
> +	KVM_RISC_V_REG_OFFSET_VTYPE,
> +	KVM_RISC_V_REG_OFFSET_VCSR,
> +	KVM_RISC_V_REG_OFFSET_VLENB,
> +	KVM_RISC_V_REG_OFFSET_MAX,
> +};
> +
>  static bool isa_ext_cant_disable[KVM_RISCV_ISA_EXT_MAX];
>  
>  bool filter_reg(__u64 reg)
> @@ -143,6 +152,39 @@ bool check_reject_set(int err)
>  	return err == EINVAL;
>  }
>  
> +static int override_vector_reg_size(struct kvm_vcpu *vcpu, struct vcpu_reg_sublist *s,
> +				    uint64_t feature)
> +{
> +	unsigned long vlenb_reg = 0;
> +	int rc;
> +	u64 reg, size;
> +
> +	/* Enable V extension so that we can get the vlenb register */
> +	rc = __vcpu_set_reg(vcpu, feature, 1);
> +	if (rc)
> +		return rc;
> +
> +	__vcpu_get_reg(vcpu, s->regs[KVM_RISC_V_REG_OFFSET_VLENB], &vlenb_reg);

We can remove the underscores from this call since it shouldn't fail, as
we know we've successfully enabled the V extension at this point.

> +
> +	if (!vlenb_reg) {
> +		TEST_FAIL("Can't compute vector register size from zero vlenb\n");
> +		return -EPERM;
> +	}
> +
> +	size = __builtin_ctzl(vlenb_reg);
> +	size <<= KVM_REG_SIZE_SHIFT;
> +
> +	for (int i = 0; i < 32; i++) {
> +		reg = KVM_REG_RISCV | KVM_REG_RISCV_VECTOR | size | KVM_REG_RISCV_VECTOR_REG(i);
> +		s->regs[KVM_RISC_V_REG_OFFSET_MAX + i] = reg;
> +	}
> +
> +	/* We should assert if disabling failed here while enabling succeeded before */
> +	vcpu_set_reg(vcpu, feature, 0);
> +
> +	return 0;
> +}
> +
>  void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>  {
>  	unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
> @@ -172,6 +214,13 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>  		if (!s->feature)
>  			continue;
>  
> +		if (s->feature == KVM_RISCV_ISA_EXT_V) {
> +			feature = RISCV_ISA_EXT_REG(s->feature);
> +			rc = override_vector_reg_size(vcpu, s, feature);
> +			if (rc)
> +				goto skip;
> +		}
> +
>  		switch (s->feature_type) {
>  		case VCPU_FEATURE_ISA_EXT:
>  			feature = RISCV_ISA_EXT_REG(s->feature);
> @@ -186,6 +235,7 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>  		/* Try to enable the desired extension */
>  		__vcpu_set_reg(vcpu, feature, 1);
>  
> +skip:
>  		/* Double check whether the desired extension was enabled */
>  		__TEST_REQUIRE(__vcpu_has_ext(vcpu, feature),
>  			       "%s not available, skipping tests", s->name);
> @@ -410,6 +460,35 @@ static const char *fp_d_id_to_str(const char *prefix, __u64 id)
>  	return strdup_printf("%lld /* UNKNOWN */", reg_off);
>  }
>  
> +static const char *vector_id_to_str(const char *prefix, __u64 id)
> +{
> +	/* reg_off is the offset into struct __riscv_v_ext_state */
> +	__u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_VECTOR);
> +	int reg_index = 0;
> +
> +	assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_VECTOR);
> +
> +	if (reg_off >= KVM_REG_RISCV_VECTOR_REG(0))
> +		reg_index = reg_off -  KVM_REG_RISCV_VECTOR_REG(0);
> +	switch (reg_off) {
> +	case KVM_REG_RISCV_VECTOR_REG(0) ...
> +	     KVM_REG_RISCV_VECTOR_REG(31):
> +		return strdup_printf("KVM_REG_RISCV_VECTOR_REG(%d)", reg_index);
> +	case KVM_REG_RISCV_VECTOR_CSR_REG(vstart):
> +		return "KVM_REG_RISCV_VECTOR_CSR_REG(vstart)";
> +	case KVM_REG_RISCV_VECTOR_CSR_REG(vl):
> +		return "KVM_REG_RISCV_VECTOR_CSR_REG(vl)";
> +	case KVM_REG_RISCV_VECTOR_CSR_REG(vtype):
> +		return "KVM_REG_RISCV_VECTOR_CSR_REG(vtype)";
> +	case KVM_REG_RISCV_VECTOR_CSR_REG(vcsr):
> +		return "KVM_REG_RISCV_VECTOR_CSR_REG(vcsr)";
> +	case KVM_REG_RISCV_VECTOR_CSR_REG(vlenb):
> +		return "KVM_REG_RISCV_VECTOR_CSR_REG(vlenb)";
> +	}
> +
> +	return strdup_printf("%lld /* UNKNOWN */", reg_off);
> +}
> +
>  #define KVM_ISA_EXT_ARR(ext)		\
>  [KVM_RISCV_ISA_EXT_##ext] = "KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_" #ext
>  
> @@ -639,6 +718,9 @@ void print_reg(const char *prefix, __u64 id)
>  	case KVM_REG_SIZE_U128:
>  		reg_size = "KVM_REG_SIZE_U128";
>  		break;
> +	case KVM_REG_SIZE_U256:
> +		reg_size = "KVM_REG_SIZE_U256";
> +		break;
>  	default:
>  		printf("\tKVM_REG_RISCV | (%lld << KVM_REG_SIZE_SHIFT) | 0x%llx /* UNKNOWN */,\n",
>  		       (id & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT, id & ~REG_MASK);
> @@ -670,6 +752,10 @@ void print_reg(const char *prefix, __u64 id)
>  		printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_FP_D | %s,\n",
>  				reg_size, fp_d_id_to_str(prefix, id));
>  		break;
> +	case KVM_REG_RISCV_VECTOR:
> +		printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_VECTOR | %s,\n",
> +		       reg_size, vector_id_to_str(prefix, id));
> +		break;
>  	case KVM_REG_RISCV_ISA_EXT:
>  		printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_ISA_EXT | %s,\n",
>  				reg_size, isa_ext_id_to_str(prefix, id));
> @@ -874,6 +960,48 @@ static __u64 fp_d_regs[] = {
>  	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_D,
>  };
>  
> +/* Define a default vector registers with length. This will be overwritten at runtime */
> +static __u64 vector_regs[] = {
> +	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vstart),
> +	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vl),
> +	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vtype),
> +	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vcsr),
> +	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vlenb),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(0),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(1),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(2),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(3),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(4),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(5),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(6),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(7),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(8),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(9),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(10),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(11),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(12),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(13),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(14),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(15),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(16),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(17),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(18),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(19),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(20),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(21),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(22),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(23),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(24),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(25),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(26),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(27),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(28),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(29),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(30),
> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(31),
> +	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_V,
> +};
> +
>  #define SUBLIST_BASE \
>  	{"base", .regs = base_regs, .regs_n = ARRAY_SIZE(base_regs), \
>  	 .skips_set = base_skips_set, .skips_set_n = ARRAY_SIZE(base_skips_set),}
> @@ -898,6 +1026,9 @@ static __u64 fp_d_regs[] = {
>  	{"fp_d", .feature = KVM_RISCV_ISA_EXT_D, .regs = fp_d_regs, \
>  		.regs_n = ARRAY_SIZE(fp_d_regs),}
>  
> +#define SUBLIST_V \
> +	{"v", .feature = KVM_RISCV_ISA_EXT_V, .regs = vector_regs, .regs_n = ARRAY_SIZE(vector_regs),}
> +
>  #define KVM_ISA_EXT_SIMPLE_CONFIG(ext, extu)			\
>  static __u64 regs_##ext[] = {					\
>  	KVM_REG_RISCV | KVM_REG_SIZE_ULONG |			\
> @@ -966,6 +1097,7 @@ KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
>  KVM_ISA_EXT_SUBLIST_CONFIG(aia, AIA);
>  KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, FP_F);
>  KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, FP_D);
> +KVM_ISA_EXT_SUBLIST_CONFIG(v, V);
>  KVM_ISA_EXT_SIMPLE_CONFIG(h, H);
>  KVM_ISA_EXT_SIMPLE_CONFIG(smnpm, SMNPM);
>  KVM_ISA_EXT_SUBLIST_CONFIG(smstateen, SMSTATEEN);
> @@ -1040,6 +1172,7 @@ struct vcpu_reg_list *vcpu_configs[] = {
>  	&config_fp_f,
>  	&config_fp_d,
>  	&config_h,
> +	&config_v,
>  	&config_smnpm,
>  	&config_smstateen,
>  	&config_sscofpmf,
> 
> -- 
> 2.43.0
>

Otherwise,

Reviewed-by: Andrew Jones <ajones@ventanamicro.com>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/3] KVM: riscv: selftests: Align the trap information wiht pt_regs
  2025-04-30  7:05   ` Andrew Jones
@ 2025-04-30  7:18     ` Atish Patra
  0 siblings, 0 replies; 10+ messages in thread
From: Atish Patra @ 2025-04-30  7:18 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Anup Patel, Atish Patra, Paolo Bonzini, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Alexandre Ghiti, kvm, kvm-riscv, linux-riscv,
	linux-kselftest, linux-kernel


On 4/30/25 12:05 AM, Andrew Jones wrote:
> On Tue, Apr 29, 2025 at 05:18:45PM -0700, Atish Patra wrote:
>> The current exeception register structure in selftests are missing
>> few registers (e.g stval). Instead of adding it manually, change
>> the ex_regs to align with pt_regs to make it future proof.
>>
>> Suggested-by: Andrew Jones <ajones@ventanamicro.com>
>> Signed-off-by: Atish Patra <atishp@rivosinc.com>
>> ---
>>   .../selftests/kvm/include/riscv/processor.h        |  10 +-
>>   tools/testing/selftests/kvm/lib/riscv/handlers.S   | 164 ++++++++++++---------
>>   tools/testing/selftests/kvm/lib/riscv/processor.c  |   2 +-
>>   tools/testing/selftests/kvm/riscv/arch_timer.c     |   2 +-
>>   tools/testing/selftests/kvm/riscv/ebreak_test.c    |   2 +-
>>   tools/testing/selftests/kvm/riscv/sbi_pmu_test.c   |   4 +-
>>   6 files changed, 104 insertions(+), 80 deletions(-)
>>
>> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
>> index 5f389166338c..1b5aef87de0f 100644
>> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
>> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
>> @@ -60,7 +60,8 @@ static inline bool __vcpu_has_sbi_ext(struct kvm_vcpu *vcpu, uint64_t sbi_ext)
>>   	return __vcpu_has_ext(vcpu, RISCV_SBI_EXT_REG(sbi_ext));
>>   }
>>   
>> -struct ex_regs {
>> +struct pt_regs {
>> +	unsigned long epc;
>>   	unsigned long ra;
>>   	unsigned long sp;
>>   	unsigned long gp;
>> @@ -92,16 +93,19 @@ struct ex_regs {
>>   	unsigned long t4;
>>   	unsigned long t5;
>>   	unsigned long t6;
>> -	unsigned long epc;
>> +	/* Supervisor/Machine CSRs */
>>   	unsigned long status;
>> +	unsigned long badaddr;
>>   	unsigned long cause;
>> +	/* a0 value before the syscall */
>> +	unsigned long orig_a0;
>>   };
>>   
>>   #define NR_VECTORS  2
>>   #define NR_EXCEPTIONS  32
>>   #define EC_MASK  (NR_EXCEPTIONS - 1)
>>   
>> -typedef void(*exception_handler_fn)(struct ex_regs *);
>> +typedef void(*exception_handler_fn)(struct pt_regs *);
>>   
>>   void vm_init_vector_tables(struct kvm_vm *vm);
>>   void vcpu_init_vector_tables(struct kvm_vcpu *vcpu);
>> diff --git a/tools/testing/selftests/kvm/lib/riscv/handlers.S b/tools/testing/selftests/kvm/lib/riscv/handlers.S
>> index aa0abd3f35bb..9c99b258cae7 100644
>> --- a/tools/testing/selftests/kvm/lib/riscv/handlers.S
>> +++ b/tools/testing/selftests/kvm/lib/riscv/handlers.S
>> @@ -9,86 +9,106 @@
>>   
>>   #include <asm/csr.h>
>>   
>> +#ifdef __ASSEMBLY__
>> +#define __ASM_STR(x)	x
>> +#else
>> +#define __ASM_STR(x)	#x
>> +#endif
> We should always have __ASSEMBLY__ (or actually __ASSMEBLER__) defined
> when compiling this .S file.
>
>> +
>> +#if __riscv_xlen == 64
>> +#define __REG_SEL(a, b)	__ASM_STR(a)
>> +#elif __riscv_xlen == 32
>> +#define __REG_SEL(a, b)	__ASM_STR(b)
>> +#else
>> +#error "Unexpected __riscv_xlen"
>> +#endif
>> +
>> +#define REG_L		__REG_SEL(ld, lw)
>> +#define REG_S		__REG_SEL(sd, sw)
> We don't need these macros since we only support 64-bit. We always
> have -DCONFIG_64BIT appended to CFLAGS. But it doesn't hurt to
> have them either...

Ah yes. I will remove the macros and restore the original code.

>> +
>>   .macro save_context
>> -	addi  sp, sp, (-8*34)
>> -	sd    x1, 0(sp)
>> -	sd    x2, 8(sp)
>> -	sd    x3, 16(sp)
>> -	sd    x4, 24(sp)
>> -	sd    x5, 32(sp)
>> -	sd    x6, 40(sp)
>> -	sd    x7, 48(sp)
>> -	sd    x8, 56(sp)
>> -	sd    x9, 64(sp)
>> -	sd    x10, 72(sp)
>> -	sd    x11, 80(sp)
>> -	sd    x12, 88(sp)
>> -	sd    x13, 96(sp)
>> -	sd    x14, 104(sp)
>> -	sd    x15, 112(sp)
>> -	sd    x16, 120(sp)
>> -	sd    x17, 128(sp)
>> -	sd    x18, 136(sp)
>> -	sd    x19, 144(sp)
>> -	sd    x20, 152(sp)
>> -	sd    x21, 160(sp)
>> -	sd    x22, 168(sp)
>> -	sd    x23, 176(sp)
>> -	sd    x24, 184(sp)
>> -	sd    x25, 192(sp)
>> -	sd    x26, 200(sp)
>> -	sd    x27, 208(sp)
>> -	sd    x28, 216(sp)
>> -	sd    x29, 224(sp)
>> -	sd    x30, 232(sp)
>> -	sd    x31, 240(sp)
>> +	addi  sp, sp, (-8*36)
>> +	REG_S    x1, 8(sp)
>> +	REG_S    x2, 16(sp)
>> +	REG_S    x3, 24(sp)
>> +	REG_S    x4, 32(sp)
>> +	REG_S    x5, 40(sp)
>> +	REG_S    x6, 48(sp)
>> +	REG_S    x7, 56(sp)
>> +	REG_S    x8, 64(sp)
>> +	REG_S    x9, 72(sp)
>> +	REG_S    x10, 80(sp)
>> +	REG_S    x11, 88(sp)
>> +	REG_S    x12, 96(sp)
>> +	REG_S    x13, 104(sp)
>> +	REG_S    x14, 112(sp)
>> +	REG_S    x15, 120(sp)
>> +	REG_S    x16, 128(sp)
>> +	REG_S    x17, 136(sp)
>> +	REG_S    x18, 144(sp)
>> +	REG_S    x19, 152(sp)
>> +	REG_S    x20, 160(sp)
>> +	REG_S    x21, 168(sp)
>> +	REG_S    x22, 176(sp)
>> +	REG_S    x23, 184(sp)
>> +	REG_S    x24, 192(sp)
>> +	REG_S    x25, 200(sp)
>> +	REG_S    x26, 208(sp)
>> +	REG_S    x27, 216(sp)
>> +	REG_S    x28, 224(sp)
>> +	REG_S    x29, 232(sp)
>> +	REG_S    x30, 240(sp)
>> +	REG_S    x31, 248(sp)
>>   	csrr  s0, CSR_SEPC
>>   	csrr  s1, CSR_SSTATUS
>> -	csrr  s2, CSR_SCAUSE
>> -	sd    s0, 248(sp)
>> -	sd    s1, 256(sp)
>> -	sd    s2, 264(sp)
>> +	csrr  s2, CSR_STVAL
>> +	csrr  s3, CSR_SCAUSE
>> +	REG_S    s0, 0(sp)
>> +	REG_S    s1, 256(sp)
>> +	REG_S    s2, 264(sp)
>> +	REG_S    s3, 272(sp)
>>   .endm
>>   
>>   .macro restore_context
>> -	ld    s2, 264(sp)
>> -	ld    s1, 256(sp)
>> -	ld    s0, 248(sp)
>> -	csrw  CSR_SCAUSE, s2
>> +	REG_L    s3, 272(sp)
>> +	REG_L    s2, 264(sp)
>> +	REG_L    s1, 256(sp)
>> +	REG_L    s0, 0(sp)
>> +	csrw  CSR_SCAUSE, s3
>>   	csrw  CSR_SSTATUS, s1
>>   	csrw  CSR_SEPC, s0
>> -	ld    x31, 240(sp)
>> -	ld    x30, 232(sp)
>> -	ld    x29, 224(sp)
>> -	ld    x28, 216(sp)
>> -	ld    x27, 208(sp)
>> -	ld    x26, 200(sp)
>> -	ld    x25, 192(sp)
>> -	ld    x24, 184(sp)
>> -	ld    x23, 176(sp)
>> -	ld    x22, 168(sp)
>> -	ld    x21, 160(sp)
>> -	ld    x20, 152(sp)
>> -	ld    x19, 144(sp)
>> -	ld    x18, 136(sp)
>> -	ld    x17, 128(sp)
>> -	ld    x16, 120(sp)
>> -	ld    x15, 112(sp)
>> -	ld    x14, 104(sp)
>> -	ld    x13, 96(sp)
>> -	ld    x12, 88(sp)
>> -	ld    x11, 80(sp)
>> -	ld    x10, 72(sp)
>> -	ld    x9, 64(sp)
>> -	ld    x8, 56(sp)
>> -	ld    x7, 48(sp)
>> -	ld    x6, 40(sp)
>> -	ld    x5, 32(sp)
>> -	ld    x4, 24(sp)
>> -	ld    x3, 16(sp)
>> -	ld    x2, 8(sp)
>> -	ld    x1, 0(sp)
>> -	addi  sp, sp, (8*34)
>> +	REG_L    x31, 248(sp)
>> +	REG_L    x30, 240(sp)
>> +	REG_L    x29, 232(sp)
>> +	REG_L    x28, 224(sp)
>> +	REG_L    x27, 216(sp)
>> +	REG_L    x26, 208(sp)
>> +	REG_L    x25, 200(sp)
>> +	REG_L    x24, 192(sp)
>> +	REG_L    x23, 184(sp)
>> +	REG_L    x22, 176(sp)
>> +	REG_L    x21, 168(sp)
>> +	REG_L    x20, 160(sp)
>> +	REG_L    x19, 152(sp)
>> +	REG_L    x18, 144(sp)
>> +	REG_L    x17, 136(sp)
>> +	REG_L    x16, 128(sp)
>> +	REG_L    x15, 120(sp)
>> +	REG_L    x14, 112(sp)
>> +	REG_L    x13, 104(sp)
>> +	REG_L    x12, 96(sp)
>> +	REG_L    x11, 88(sp)
>> +	REG_L    x10, 80(sp)
>> +	REG_L    x9, 72(sp)
>> +	REG_L    x8, 64(sp)
>> +	REG_L    x7, 56(sp)
>> +	REG_L    x6, 48(sp)
>> +	REG_L    x5, 40(sp)
>> +	REG_L    x4, 32(sp)
>> +	REG_L    x3, 24(sp)
>> +	REG_L    x2, 16(sp)
>> +	REG_L    x1, 8(sp)
>> +	addi  sp, sp, (8*36)
>>   .endm
>>   
>>   .balign 4
>> diff --git a/tools/testing/selftests/kvm/lib/riscv/processor.c b/tools/testing/selftests/kvm/lib/riscv/processor.c
>> index dd663bcf0cc0..2eac7d4b59e9 100644
>> --- a/tools/testing/selftests/kvm/lib/riscv/processor.c
>> +++ b/tools/testing/selftests/kvm/lib/riscv/processor.c
>> @@ -402,7 +402,7 @@ struct handlers {
>>   	exception_handler_fn exception_handlers[NR_VECTORS][NR_EXCEPTIONS];
>>   };
>>   
>> -void route_exception(struct ex_regs *regs)
>> +void route_exception(struct pt_regs *regs)
>>   {
>>   	struct handlers *handlers = (struct handlers *)exception_handlers;
>>   	int vector = 0, ec;
>> diff --git a/tools/testing/selftests/kvm/riscv/arch_timer.c b/tools/testing/selftests/kvm/riscv/arch_timer.c
>> index 9e370800a6a2..f962fefc48fa 100644
>> --- a/tools/testing/selftests/kvm/riscv/arch_timer.c
>> +++ b/tools/testing/selftests/kvm/riscv/arch_timer.c
>> @@ -15,7 +15,7 @@
>>   
>>   static int timer_irq = IRQ_S_TIMER;
>>   
>> -static void guest_irq_handler(struct ex_regs *regs)
>> +static void guest_irq_handler(struct pt_regs *regs)
>>   {
>>   	uint64_t xcnt, xcnt_diff_us, cmp;
>>   	unsigned int intid = regs->cause & ~CAUSE_IRQ_FLAG;
>> diff --git a/tools/testing/selftests/kvm/riscv/ebreak_test.c b/tools/testing/selftests/kvm/riscv/ebreak_test.c
>> index cfed6c727bfc..739d17befb5a 100644
>> --- a/tools/testing/selftests/kvm/riscv/ebreak_test.c
>> +++ b/tools/testing/selftests/kvm/riscv/ebreak_test.c
>> @@ -27,7 +27,7 @@ static void guest_code(void)
>>   	GUEST_DONE();
>>   }
>>   
>> -static void guest_breakpoint_handler(struct ex_regs *regs)
>> +static void guest_breakpoint_handler(struct pt_regs *regs)
>>   {
>>   	WRITE_ONCE(sw_bp_addr, regs->epc);
>>   	regs->epc += 4;
>> diff --git a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
>> index 03406de4989d..6e66833e5941 100644
>> --- a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
>> +++ b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
>> @@ -128,7 +128,7 @@ static void stop_counter(unsigned long counter, unsigned long stop_flags)
>>   		       "Unable to stop counter %ld error %ld\n", counter, ret.error);
>>   }
>>   
>> -static void guest_illegal_exception_handler(struct ex_regs *regs)
>> +static void guest_illegal_exception_handler(struct pt_regs *regs)
>>   {
>>   	__GUEST_ASSERT(regs->cause == EXC_INST_ILLEGAL,
>>   		       "Unexpected exception handler %lx\n", regs->cause);
>> @@ -138,7 +138,7 @@ static void guest_illegal_exception_handler(struct ex_regs *regs)
>>   	regs->epc += 4;
>>   }
>>   
>> -static void guest_irq_handler(struct ex_regs *regs)
>> +static void guest_irq_handler(struct pt_regs *regs)
>>   {
>>   	unsigned int irq_num = regs->cause & ~CAUSE_IRQ_FLAG;
>>   	struct riscv_pmu_snapshot_data *snapshot_data = snapshot_gva;
>>
>> -- 
>> 2.43.0
>>
> Other than the macro comments,
>
> Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
>
> Thanks,
> drew

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 2/3] KVM: riscv: selftests: Decode stval to identify exact exception type
  2025-04-30  7:09   ` Andrew Jones
@ 2025-04-30  7:20     ` Atish Patra
  0 siblings, 0 replies; 10+ messages in thread
From: Atish Patra @ 2025-04-30  7:20 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Anup Patel, Atish Patra, Paolo Bonzini, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Alexandre Ghiti, kvm, kvm-riscv, linux-riscv,
	linux-kselftest, linux-kernel


On 4/30/25 12:09 AM, Andrew Jones wrote:
> On Tue, Apr 29, 2025 at 05:18:46PM -0700, Atish Patra wrote:
>> 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.
>>
>> Reviewed-by: Anup Patel <anup@brainfault.org>
>> Signed-off-by: Atish Patra <atishp@rivosinc.com>
>> ---
>>   .../testing/selftests/kvm/include/riscv/processor.h  | 13 +++++++++++++
>>   tools/testing/selftests/kvm/riscv/sbi_pmu_test.c     | 20 ++++++++++++++++++++
>>   2 files changed, 33 insertions(+)
>>
>> diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h
>> index 1b5aef87de0f..162f303d9daa 100644
>> --- a/tools/testing/selftests/kvm/include/riscv/processor.h
>> +++ b/tools/testing/selftests/kvm/include/riscv/processor.h
>> @@ -11,6 +11,19 @@
>>   #include <asm/csr.h>
>>   #include "kvm_util.h"
>>   
>> +#define INSN_OPCODE_MASK	0x007c
>> +#define INSN_OPCODE_SHIFT	2
>> +#define INSN_OPCODE_SYSTEM	28
>> +
>> +#define INSN_MASK_FUNCT3	0x7000
>> +#define INSN_SHIFT_FUNCT3	12
>> +
>> +#define INSN_CSR_MASK		0xfff00000
>> +#define INSN_CSR_SHIFT		20
>> +
>> +#define GET_RM(insn)            (((insn) & INSN_MASK_FUNCT3) >> INSN_SHIFT_FUNCT3)
>> +#define GET_CSR_NUM(insn)       (((insn) & INSN_CSR_MASK) >> INSN_CSR_SHIFT)
>> +
>>   static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t subtype,
>>   				    uint64_t idx, uint64_t size)
>>   {
>> diff --git a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
>> index 6e66833e5941..3c47268df262 100644
>> --- a/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
>> +++ b/tools/testing/selftests/kvm/riscv/sbi_pmu_test.c
>> @@ -130,9 +130,29 @@ static void stop_counter(unsigned long counter, unsigned long stop_flags)
>>   
>>   static void guest_illegal_exception_handler(struct pt_regs *regs)
>>   {
>> +	unsigned long insn;
>> +	int opcode, csr_num, funct3;
>> +
>>   	__GUEST_ASSERT(regs->cause == EXC_INST_ILLEGAL,
>>   		       "Unexpected exception handler %lx\n", regs->cause);
>>   
>> +	insn = regs->badaddr;
>> +	opcode = (insn & INSN_OPCODE_MASK) >> INSN_OPCODE_SHIFT;
>> +	__GUEST_ASSERT(opcode == INSN_OPCODE_SYSTEM,
>> +		       "Unexpected instruction with opcode 0x%x insn 0x%lx\n", opcode, insn);
>> +
>> +	csr_num = GET_CSR_NUM(insn);
>> +	funct3 = GET_RM(insn);
>> +	/* Validate if it is a CSR read/write operation */
>> +	__GUEST_ASSERT(funct3 <= 7 && (funct3 != 0 && funct3 != 4),
>> +		       "Unexpected system opcode with funct3 0x%x csr_num 0x%x\n",
>> +		       funct3, csr_num);
>> +
>> +	/* Validate if it is a HPMCOUNTER CSR operation */
>> +	__GUEST_ASSERT((csr_num >= CSR_CYCLE && csr_num <= CSR_HPMCOUNTER31) ||
>> +		       (csr_num >= CSR_CYCLEH && csr_num <= CSR_HPMCOUNTER31H),
> We should never get csr accesses to the rv32 high registers since we only
> support 64-bit.

Sure. I will remove that along with CSR_CYCLEH in pmu_csr_read_num.

>> +		       "Unexpected csr_num 0x%x\n", csr_num);
>> +
>>   	illegal_handler_invoked = true;
>>   	/* skip the trapping instruction */
>>   	regs->epc += 4;
>>
>> -- 
>> 2.43.0
>>
> Otherwise,
>
> Reviewed-by: Andrew Jones <ajones@ventanamicro.com>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 3/3] KVM: riscv: selftests: Add vector extension tests
  2025-04-30  7:17   ` Andrew Jones
@ 2025-04-30  7:22     ` Atish Patra
  0 siblings, 0 replies; 10+ messages in thread
From: Atish Patra @ 2025-04-30  7:22 UTC (permalink / raw)
  To: Andrew Jones
  Cc: Anup Patel, Atish Patra, Paolo Bonzini, Shuah Khan, Paul Walmsley,
	Palmer Dabbelt, Alexandre Ghiti, kvm, kvm-riscv, linux-riscv,
	linux-kselftest, linux-kernel


On 4/30/25 12:17 AM, Andrew Jones wrote:
> On Tue, Apr 29, 2025 at 05:18:47PM -0700, Atish Patra wrote:
>> Add vector related tests with the ISA extension standard template.
>> However, the vector registers are bit tricky as the register length is
>> variable based on vlenb value of the system. That's why the macros are
>> defined with a default and overidden with actual value at runtime.
>>
>> Reviewed-by: Anup Patel <anup@brainfault.org>
>> Signed-off-by: Atish Patra <atishp@rivosinc.com>
>> ---
>>   tools/testing/selftests/kvm/riscv/get-reg-list.c | 133 +++++++++++++++++++++++
>>   1 file changed, 133 insertions(+)
>>
>> diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c
>> index 569f2d67c9b8..814dd981ce0b 100644
>> --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c
>> +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c
>> @@ -17,6 +17,15 @@ enum {
>>   	VCPU_FEATURE_SBI_EXT,
>>   };
>>   
>> +enum {
>> +	KVM_RISC_V_REG_OFFSET_VSTART = 0,
>> +	KVM_RISC_V_REG_OFFSET_VL,
>> +	KVM_RISC_V_REG_OFFSET_VTYPE,
>> +	KVM_RISC_V_REG_OFFSET_VCSR,
>> +	KVM_RISC_V_REG_OFFSET_VLENB,
>> +	KVM_RISC_V_REG_OFFSET_MAX,
>> +};
>> +
>>   static bool isa_ext_cant_disable[KVM_RISCV_ISA_EXT_MAX];
>>   
>>   bool filter_reg(__u64 reg)
>> @@ -143,6 +152,39 @@ bool check_reject_set(int err)
>>   	return err == EINVAL;
>>   }
>>   
>> +static int override_vector_reg_size(struct kvm_vcpu *vcpu, struct vcpu_reg_sublist *s,
>> +				    uint64_t feature)
>> +{
>> +	unsigned long vlenb_reg = 0;
>> +	int rc;
>> +	u64 reg, size;
>> +
>> +	/* Enable V extension so that we can get the vlenb register */
>> +	rc = __vcpu_set_reg(vcpu, feature, 1);
>> +	if (rc)
>> +		return rc;
>> +
>> +	__vcpu_get_reg(vcpu, s->regs[KVM_RISC_V_REG_OFFSET_VLENB], &vlenb_reg);
> We can remove the underscores from this call since it shouldn't fail, as
> we know we've successfully enabled the V extension at this point.
good point. I will remove it.
>> +
>> +	if (!vlenb_reg) {
>> +		TEST_FAIL("Can't compute vector register size from zero vlenb\n");
>> +		return -EPERM;
>> +	}
>> +
>> +	size = __builtin_ctzl(vlenb_reg);
>> +	size <<= KVM_REG_SIZE_SHIFT;
>> +
>> +	for (int i = 0; i < 32; i++) {
>> +		reg = KVM_REG_RISCV | KVM_REG_RISCV_VECTOR | size | KVM_REG_RISCV_VECTOR_REG(i);
>> +		s->regs[KVM_RISC_V_REG_OFFSET_MAX + i] = reg;
>> +	}
>> +
>> +	/* We should assert if disabling failed here while enabling succeeded before */
>> +	vcpu_set_reg(vcpu, feature, 0);
>> +
>> +	return 0;
>> +}
>> +
>>   void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>>   {
>>   	unsigned long isa_ext_state[KVM_RISCV_ISA_EXT_MAX] = { 0 };
>> @@ -172,6 +214,13 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>>   		if (!s->feature)
>>   			continue;
>>   
>> +		if (s->feature == KVM_RISCV_ISA_EXT_V) {
>> +			feature = RISCV_ISA_EXT_REG(s->feature);
>> +			rc = override_vector_reg_size(vcpu, s, feature);
>> +			if (rc)
>> +				goto skip;
>> +		}
>> +
>>   		switch (s->feature_type) {
>>   		case VCPU_FEATURE_ISA_EXT:
>>   			feature = RISCV_ISA_EXT_REG(s->feature);
>> @@ -186,6 +235,7 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
>>   		/* Try to enable the desired extension */
>>   		__vcpu_set_reg(vcpu, feature, 1);
>>   
>> +skip:
>>   		/* Double check whether the desired extension was enabled */
>>   		__TEST_REQUIRE(__vcpu_has_ext(vcpu, feature),
>>   			       "%s not available, skipping tests", s->name);
>> @@ -410,6 +460,35 @@ static const char *fp_d_id_to_str(const char *prefix, __u64 id)
>>   	return strdup_printf("%lld /* UNKNOWN */", reg_off);
>>   }
>>   
>> +static const char *vector_id_to_str(const char *prefix, __u64 id)
>> +{
>> +	/* reg_off is the offset into struct __riscv_v_ext_state */
>> +	__u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_VECTOR);
>> +	int reg_index = 0;
>> +
>> +	assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_VECTOR);
>> +
>> +	if (reg_off >= KVM_REG_RISCV_VECTOR_REG(0))
>> +		reg_index = reg_off -  KVM_REG_RISCV_VECTOR_REG(0);
>> +	switch (reg_off) {
>> +	case KVM_REG_RISCV_VECTOR_REG(0) ...
>> +	     KVM_REG_RISCV_VECTOR_REG(31):
>> +		return strdup_printf("KVM_REG_RISCV_VECTOR_REG(%d)", reg_index);
>> +	case KVM_REG_RISCV_VECTOR_CSR_REG(vstart):
>> +		return "KVM_REG_RISCV_VECTOR_CSR_REG(vstart)";
>> +	case KVM_REG_RISCV_VECTOR_CSR_REG(vl):
>> +		return "KVM_REG_RISCV_VECTOR_CSR_REG(vl)";
>> +	case KVM_REG_RISCV_VECTOR_CSR_REG(vtype):
>> +		return "KVM_REG_RISCV_VECTOR_CSR_REG(vtype)";
>> +	case KVM_REG_RISCV_VECTOR_CSR_REG(vcsr):
>> +		return "KVM_REG_RISCV_VECTOR_CSR_REG(vcsr)";
>> +	case KVM_REG_RISCV_VECTOR_CSR_REG(vlenb):
>> +		return "KVM_REG_RISCV_VECTOR_CSR_REG(vlenb)";
>> +	}
>> +
>> +	return strdup_printf("%lld /* UNKNOWN */", reg_off);
>> +}
>> +
>>   #define KVM_ISA_EXT_ARR(ext)		\
>>   [KVM_RISCV_ISA_EXT_##ext] = "KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_" #ext
>>   
>> @@ -639,6 +718,9 @@ void print_reg(const char *prefix, __u64 id)
>>   	case KVM_REG_SIZE_U128:
>>   		reg_size = "KVM_REG_SIZE_U128";
>>   		break;
>> +	case KVM_REG_SIZE_U256:
>> +		reg_size = "KVM_REG_SIZE_U256";
>> +		break;
>>   	default:
>>   		printf("\tKVM_REG_RISCV | (%lld << KVM_REG_SIZE_SHIFT) | 0x%llx /* UNKNOWN */,\n",
>>   		       (id & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT, id & ~REG_MASK);
>> @@ -670,6 +752,10 @@ void print_reg(const char *prefix, __u64 id)
>>   		printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_FP_D | %s,\n",
>>   				reg_size, fp_d_id_to_str(prefix, id));
>>   		break;
>> +	case KVM_REG_RISCV_VECTOR:
>> +		printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_VECTOR | %s,\n",
>> +		       reg_size, vector_id_to_str(prefix, id));
>> +		break;
>>   	case KVM_REG_RISCV_ISA_EXT:
>>   		printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_ISA_EXT | %s,\n",
>>   				reg_size, isa_ext_id_to_str(prefix, id));
>> @@ -874,6 +960,48 @@ static __u64 fp_d_regs[] = {
>>   	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_D,
>>   };
>>   
>> +/* Define a default vector registers with length. This will be overwritten at runtime */
>> +static __u64 vector_regs[] = {
>> +	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vstart),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vl),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vtype),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vcsr),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_CSR_REG(vlenb),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(0),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(1),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(2),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(3),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(4),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(5),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(6),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(7),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(8),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(9),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(10),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(11),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(12),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(13),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(14),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(15),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(16),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(17),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(18),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(19),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(20),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(21),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(22),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(23),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(24),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(25),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(26),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(27),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(28),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(29),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(30),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_U128 | KVM_REG_RISCV_VECTOR | KVM_REG_RISCV_VECTOR_REG(31),
>> +	KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_V,
>> +};
>> +
>>   #define SUBLIST_BASE \
>>   	{"base", .regs = base_regs, .regs_n = ARRAY_SIZE(base_regs), \
>>   	 .skips_set = base_skips_set, .skips_set_n = ARRAY_SIZE(base_skips_set),}
>> @@ -898,6 +1026,9 @@ static __u64 fp_d_regs[] = {
>>   	{"fp_d", .feature = KVM_RISCV_ISA_EXT_D, .regs = fp_d_regs, \
>>   		.regs_n = ARRAY_SIZE(fp_d_regs),}
>>   
>> +#define SUBLIST_V \
>> +	{"v", .feature = KVM_RISCV_ISA_EXT_V, .regs = vector_regs, .regs_n = ARRAY_SIZE(vector_regs),}
>> +
>>   #define KVM_ISA_EXT_SIMPLE_CONFIG(ext, extu)			\
>>   static __u64 regs_##ext[] = {					\
>>   	KVM_REG_RISCV | KVM_REG_SIZE_ULONG |			\
>> @@ -966,6 +1097,7 @@ KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
>>   KVM_ISA_EXT_SUBLIST_CONFIG(aia, AIA);
>>   KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, FP_F);
>>   KVM_ISA_EXT_SUBLIST_CONFIG(fp_d, FP_D);
>> +KVM_ISA_EXT_SUBLIST_CONFIG(v, V);
>>   KVM_ISA_EXT_SIMPLE_CONFIG(h, H);
>>   KVM_ISA_EXT_SIMPLE_CONFIG(smnpm, SMNPM);
>>   KVM_ISA_EXT_SUBLIST_CONFIG(smstateen, SMSTATEEN);
>> @@ -1040,6 +1172,7 @@ struct vcpu_reg_list *vcpu_configs[] = {
>>   	&config_fp_f,
>>   	&config_fp_d,
>>   	&config_h,
>> +	&config_v,
>>   	&config_smnpm,
>>   	&config_smstateen,
>>   	&config_sscofpmf,
>>
>> -- 
>> 2.43.0
>>
> Otherwise,
>
> Reviewed-by: Andrew Jones <ajones@ventanamicro.com>

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2025-04-30  7:33 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-30  0:18 [PATCH v2 0/3] RISC-V KVM selftests improvements Atish Patra
2025-04-30  0:18 ` [PATCH v2 1/3] KVM: riscv: selftests: Align the trap information wiht pt_regs Atish Patra
2025-04-30  7:05   ` Andrew Jones
2025-04-30  7:18     ` Atish Patra
2025-04-30  0:18 ` [PATCH v2 2/3] KVM: riscv: selftests: Decode stval to identify exact exception type Atish Patra
2025-04-30  7:09   ` Andrew Jones
2025-04-30  7:20     ` Atish Patra
2025-04-30  0:18 ` [PATCH v2 3/3] KVM: riscv: selftests: Add vector extension tests Atish Patra
2025-04-30  7:17   ` Andrew Jones
2025-04-30  7:22     ` Atish Patra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).