From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5665F3537E0; Mon, 22 Jun 2026 04:01:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782100902; cv=none; b=A77fVTNg+0HI8tCBj3/7F82o6PDame/2JdGPawK01/H3nrX2MyFBYFXDSajYSCsDkiDL9YBXOYu2me0MbkHGCLSL8ScghGdWnL785fhB/KabkXqYVVsn3TUK6PUcYUm0clLzvJn6A2z5uShZokUvvnNv8z4PbAwkgy03yO54ils= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782100902; c=relaxed/simple; bh=TVUTi3JzfDP6+5V/37ec117+w6OR65FVI5bIsfJZApA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ho6jXs3YhNbRPVaTdz8Wbug2rfIk7uW6qsn9Jyi9OgQ4xpMnQRUoP7Ij1SeW9/NhgQP7n+m01nhp61tUWY91qI9PfDKO45AaQqjHcFvujmMMaGZU5QCKZpiKm1G2nae1G6dpqhinArEzltsQw+Js8Zb37yoQz/+rewZNSAXZJz0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Q4AOBYjl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Q4AOBYjl" Received: by smtp.kernel.org (Postfix) with ESMTPS id 35DEFC2BCFD; Mon, 22 Jun 2026 04:01:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1782100902; bh=TVUTi3JzfDP6+5V/37ec117+w6OR65FVI5bIsfJZApA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Q4AOBYjlxIBqxzMIEV3PLP2UaHQnNf09AVYFW/j9dCpu2/frUABGIn/9dv9O1xDK2 rnOODipLb1VwSN/TV78VqjNdgWoaXzcwyyxDl7ytdHBMGINu80z7T7Zx/SNw8NuhEU fZkNZRPy4MRCyTX8dNhnGxXDngcYv4OdtuCrFAa/xFJ+4CFDdgVEFkHfMCafe1fKlU fZ5+DeVDB3Kxp8SVWvMiMaztSYfuiuIRWzUP3T2M0s8OXpXzATTLpXqHSAzJ7Lrh1v ZoyAb/tfmIscpN+RHs6G4gKJcJo/p3bHbO6SAsHFymaBdJnrCzFO0rFeUB1z0CsjcX CFaAG2Z+VGefw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2BBC2CDB471; Mon, 22 Jun 2026 04:01:42 +0000 (UTC) From: Charlie Jenkins via B4 Relay Date: Sun, 21 Jun 2026 21:01:31 -0700 Subject: [PATCH v2 13/16] KVM: riscv: selftests: Add csr emulation test Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260621-riscv_insn_table-v2-13-7f0810ee2274@gmail.com> References: <20260621-riscv_insn_table-v2-0-7f0810ee2274@gmail.com> In-Reply-To: <20260621-riscv_insn_table-v2-0-7f0810ee2274@gmail.com> To: Paul Walmsley , Palmer Dabbelt , Nam Cao , Alexandre Ghiti , Anup Patel , Atish Patra , Conor Dooley , Paolo Bonzini , Andrew Morton , Shuah Khan , =?utf-8?q?Radim_Kr=C4=8Dm=C3=A1=C5=99?= Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, linux-kselftest@vger.kernel.org, Charlie Jenkins X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1782100900; l=4572; i=thecharlesjenkins@gmail.com; s=20260605; h=from:subject:message-id; bh=UIPBSpc0H3jB7+KpJxg4F5rG4rgb2Zzku6x9eNCAhf8=; b=LkA15MenggXoi151d45SYPIEvfF6f5Fo3rW9bGmHd1LZ5uSRXUZT9goc9vyY3EB3pqtMjq6G7 wPZWWace2SQCE3C+XBtQd73He4AWPCES9KyX40XDcpXuv8kW6z3sMPA X-Developer-Key: i=thecharlesjenkins@gmail.com; a=ed25519; pk=ajnnRQ98PIdwKp4HeMkq9U32okYbnh6Zb4G3o5XXvkg= X-Endpoint-Received: by B4 Relay for thecharlesjenkins@gmail.com/20260605 with auth_id=810 X-Original-From: Charlie Jenkins Reply-To: thecharlesjenkins@gmail.com From: Charlie Jenkins Introduce a kvm test that uses the emulated test csr to validate that all emulated reads/writes to csrs function as expected. Signed-off-by: Charlie Jenkins --- tools/testing/selftests/kvm/Makefile.kvm | 1 + tools/testing/selftests/kvm/riscv/csr_test.c | 126 +++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm index 07a5fc2bf67c..88ccd15e8f94 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -212,6 +212,7 @@ TEST_GEN_PROGS_s390 += s390/irq_routing TEST_GEN_PROGS_s390 += mmu_stress_test TEST_GEN_PROGS_riscv = $(TEST_GEN_PROGS_COMMON) +TEST_GEN_PROGS_riscv += riscv/csr_test TEST_GEN_PROGS_riscv += riscv/sbi_pmu_test TEST_GEN_PROGS_riscv += riscv/ebreak_test TEST_GEN_PROGS_riscv += riscv/mmio_test diff --git a/tools/testing/selftests/kvm/riscv/csr_test.c b/tools/testing/selftests/kvm/riscv/csr_test.c new file mode 100644 index 000000000000..b3e8b99b6e92 --- /dev/null +++ b/tools/testing/selftests/kvm/riscv/csr_test.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * csr_test.c - Tests the csr functionality. + */ +#include "kvm_util.h" +#include "ucall_common.h" + +#define CSR_TEST 0x240 +#define FP 0x00006000 + +/* + * Use the fcsr as a U-mode accesible csr and compare against the custom 'test' + * hypervisor csr (currently using vsscratch) + */ +#define test_csr(write, initial, mode) \ +static void test_##write(void) \ +{ \ + unsigned long hypervisor_result, reference_result, old_hypervisor; \ + unsigned long mask = 0x15; \ + asm volatile ( \ + "csrs sstatus, %[enable_fp]\n" \ + "csrw fcsr, %[init]\n" \ + #write" zero, fcsr, %[mask]\n" \ + "csrr %[ref_res], fcsr\n" \ + : [ref_res] "=&r" (reference_result) \ + : [enable_fp] "r" (FP), [mask] #mode(mask), [init] "r" (initial) \ + : "memory" \ + ); \ + asm volatile ( \ + "csrw %[test_csr], %[init]\n" \ + #write" %[old], %[test_csr], %[mask]\n" \ + "csrr %[hyp_res], %[test_csr]\n" \ + : [hyp_res] "=&r" (hypervisor_result), [old] "=&r" (old_hypervisor) \ + : [test_csr] "i"(CSR_TEST), [mask] #mode(mask), [init] "r" (initial) \ + : "memory" \ + ); \ + /* Check that writing works */ \ + GUEST_ASSERT_EQ(reference_result, hypervisor_result); \ + /* Check that reading works */ \ + GUEST_ASSERT_EQ(old_hypervisor, initial); \ + GUEST_DONE(); \ +} + +test_csr(csrrw, 0x0, r) +test_csr(csrrs, 0x0, r) +test_csr(csrrc, 0x15, r) +test_csr(csrrwi, 0x0, i) +test_csr(csrrsi, 0x0, i) +test_csr(csrrci, 0x15, i) + +static void run(void *guest_code, char *instruction) +{ + struct ucall uc; + struct kvm_vm *vm; + struct kvm_vcpu *vcpu; + + vm = vm_create_with_one_vcpu(&vcpu, guest_code); + + kvm_create_device(vm, KVM_DEV_TYPE_TEST); + + vcpu_run(vcpu); + + TEST_ASSERT(get_ucall(vcpu, &uc) == UCALL_DONE, + "CSR instruction '%s' failed: '%s'", instruction, + uc.buffer); + + kvm_vm_free(vm); +} + +static void check_test_csr_guest(void) +{ + unsigned long scause, stvec; + + asm volatile( + "la %[stvec], 1f\n" + "csrw stvec, %[stvec]\n" + "csrwi %[test_csr], 0x0\n" + "1:\n" + "csrr %[scause], scause\n" + : [scause] "=&r" (scause), [stvec] "=&r" (stvec) + : [test_csr] "i" (CSR_TEST) + ); + + /* An illegal instruction will be generated if CONFIG_RISCV_KVM_TEST_CSR is not enabled. */ + if (scause == 2) + GUEST_FAIL("CONFIG_RISCV_KVM_TEST_CSR not enabled.\n"); + GUEST_DONE(); +} + +static int check_test_csr(void) +{ + struct ucall uc; + struct kvm_vm *vm; + struct kvm_vcpu *vcpu; + int success; + + vm = vm_create_with_one_vcpu(&vcpu, check_test_csr_guest); + + /* Skip if CONFIG_KVM_MMIO_TEST not enabled */ + if (!kvm_create_device(vm, KVM_DEV_TYPE_TEST)) + exit(KSFT_SKIP); + + vcpu_run(vcpu); + + success = get_ucall(vcpu, &uc) == UCALL_DONE; + + kvm_vm_free(vm); + + return success; +} + +int main(void) +{ + /* Skip if CONFIG_RISCV_KVM_TEST_CSR not enabled */ + if (!check_test_csr()) + exit(KSFT_SKIP); + + run(test_csrrw, "csrrw"); + run(test_csrrs, "csrrs"); + run(test_csrrc, "csrrc"); + run(test_csrrwi, "csrrwi"); + run(test_csrrsi, "csrrsi"); + run(test_csrrci, "csrrci"); + + return 0; +} -- 2.54.0