Add RISC-V KVM selftests to verify the SBI Steal-Time Accounting (STA) shared memory alignment requirements.
The SBI specification requires the STA shared memory GPA to be 64-byte aligned, or set to all-ones to explicitly disable steal-time accounting. This test verifies that KVM enforces the expected behavior when configuring the SBI STA shared memory via KVM_SET_ONE_REG. Specifically, the test checks that: - misaligned GPAs are rejected with -EINVAL - 64-byte aligned GPAs are accepted - INVALID_GPA correctly disables steal-time accounting Signed-off-by: Jiakai Xu <[email protected]> Signed-off-by: Jiakai Xu <[email protected]> --- .../selftests/kvm/include/riscv/processor.h | 4 +++ tools/testing/selftests/kvm/steal_time.c | 33 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/tools/testing/selftests/kvm/include/riscv/processor.h b/tools/testing/selftests/kvm/include/riscv/processor.h index e58282488beb3..c3551d129d2f6 100644 --- a/tools/testing/selftests/kvm/include/riscv/processor.h +++ b/tools/testing/selftests/kvm/include/riscv/processor.h @@ -62,6 +62,10 @@ static inline uint64_t __kvm_reg_id(uint64_t type, uint64_t subtype, KVM_REG_RISCV_SBI_SINGLE, \ idx, KVM_REG_SIZE_ULONG) +#define RISCV_SBI_STA_REG(idx) __kvm_reg_id(KVM_REG_RISCV_SBI_STATE, \ + KVM_REG_RISCV_SBI_STA, \ + idx, KVM_REG_SIZE_ULONG) + bool __vcpu_has_ext(struct kvm_vcpu *vcpu, uint64_t ext); static inline bool __vcpu_has_isa_ext(struct kvm_vcpu *vcpu, uint64_t isa_ext) diff --git a/tools/testing/selftests/kvm/steal_time.c b/tools/testing/selftests/kvm/steal_time.c index 8edc1fca345ba..30b98d1b601c3 100644 --- a/tools/testing/selftests/kvm/steal_time.c +++ b/tools/testing/selftests/kvm/steal_time.c @@ -209,6 +209,7 @@ static void steal_time_dump(struct kvm_vm *vm, uint32_t vcpu_idx) /* SBI STA shmem must have 64-byte alignment */ #define STEAL_TIME_SIZE ((sizeof(struct sta_struct) + 63) & ~63) +#define INVALID_GPA (~(u64)0) static vm_paddr_t st_gpa[NR_VCPUS]; @@ -301,6 +302,34 @@ static void steal_time_dump(struct kvm_vm *vm, uint32_t vcpu_idx) pr_info("\n"); } +static void test_riscv_sta_shmem_alignment(struct kvm_vcpu *vcpu) +{ + struct kvm_one_reg reg; + uint64_t shmem; + int ret; + + reg.id = RISCV_SBI_STA_REG(0); + reg.addr = (uint64_t)&shmem; + + /* Case 1: misaligned GPA */ + shmem = ST_GPA_BASE + 1; + ret = __vcpu_ioctl(vcpu, KVM_SET_ONE_REG, ®); + TEST_ASSERT(ret == -1 && errno == EINVAL, + "misaligned STA shmem should return -EINVAL"); + + /* Case 2: 64-byte aligned GPA */ + shmem = ST_GPA_BASE; + ret = __vcpu_ioctl(vcpu, KVM_SET_ONE_REG, ®); + TEST_ASSERT(ret == 0, + "aligned STA shmem should succeed"); + + /* Case 3: INVALID_GPA disables STA */ + shmem = INVALID_GPA; + ret = __vcpu_ioctl(vcpu, KVM_SET_ONE_REG, ®); + TEST_ASSERT(ret == 0, + "INVALID_GPA should disable STA successfully"); +} + #endif static void *do_steal_time(void *arg) @@ -369,6 +398,10 @@ int main(int ac, char **av) TEST_REQUIRE(is_steal_time_supported(vcpus[0])); ksft_set_plan(NR_VCPUS); +#ifdef __riscv + test_riscv_sta_shmem_alignment(vcpus[0]); +#endif + /* Run test on each VCPU */ for (i = 0; i < NR_VCPUS; ++i) { steal_time_init(vcpus[i], i); -- 2.34.1

