From nobody Fri Dec 19 09:35:36 2025 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 934342E8E01; Tue, 4 Nov 2025 11:37:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762256231; cv=none; b=Kf3QL9dwEsLJBiaOnJAW0CpxJJvsHYC/uOtxu9acME3QpOPkI+QXOtSpODwNrxggqkNnGulmYjbJ3uaSbfMa24SnVYU6jc9B8ykaWe3FpQ1USIJfeP+uC/d5lVDru86FX+Fij3glksZM9eboqkZBkw33O8spi5C6b2ms436tkgw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762256231; c=relaxed/simple; bh=/eL7qO9Bg4rxngtC4qoLPKMphY8SvbMqkKlEZehmPKM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=LLW+o3PHKodvpb1nmUij0pxJXJ5T4DkVj2tjt47vvJUwcaFrVQuN2bmbb+gDNQOLcpz+PvQXvlPWirTZKAxv4bv74E1IrNlw3UI2NKOlUJuiozjbpbbRJ6h8Uy3oQ9x+13WYk87Dpz0IIrwPL0Ux0sdWIdEcaqQ1xyyZpPT41Vw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [10.2.5.213]) by gateway (Coremail) with SMTP id _____8DxM9Bg5QlpYbQeAA--.1385S3; Tue, 04 Nov 2025 19:37:04 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.213]) by front1 (Coremail) with SMTP id qMiowJDx_8Nc5QlpQTImAQ--.54832S3; Tue, 04 Nov 2025 19:37:04 +0800 (CST) From: Bibo Mao To: Paolo Bonzini , Sean Christopherson , Huacai Chen , Tianrui Zhao , Shuah Khan Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, loongarch@lists.linux.dev, linux-kselftest@vger.kernel.org Subject: [PATCH v2 1/7] KVM: LoongArch: selftests: Add system registers save and restore on exception Date: Tue, 4 Nov 2025 19:36:53 +0800 Message-Id: <20251104113700.1561752-2-maobibo@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20251104113700.1561752-1-maobibo@loongson.cn> References: <20251104113700.1561752-1-maobibo@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJDx_8Nc5QlpQTImAQ--.54832S3 X-CM-SenderInfo: xpdruxter6z05rqj20fqof0/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Content-Type: text/plain; charset="utf-8" When system returns from exception with ertn instruction, PC comes from LOONGARCH_CSR_ERA, and CSR_CRMD comes LOONGARCH_CSR_PRMD. Here save CSR register CSR_ERA and CSR_PRMD in stack, and restore them from stack. So it can be modified by exception handler in future. Signed-off-by: Bibo Mao --- tools/testing/selftests/kvm/include/loongarch/processor.h | 5 ++++- tools/testing/selftests/kvm/lib/loongarch/exception.S | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/include/loongarch/processor.h b/to= ols/testing/selftests/kvm/include/loongarch/processor.h index 6427a3275e6a..374caddfb0db 100644 --- a/tools/testing/selftests/kvm/include/loongarch/processor.h +++ b/tools/testing/selftests/kvm/include/loongarch/processor.h @@ -124,18 +124,21 @@ struct ex_regs { unsigned long pc; unsigned long estat; unsigned long badv; + unsigned long prmd; }; =20 #define PC_OFFSET_EXREGS offsetof(struct ex_regs, pc) #define ESTAT_OFFSET_EXREGS offsetof(struct ex_regs, estat) #define BADV_OFFSET_EXREGS offsetof(struct ex_regs, badv) +#define PRMD_OFFSET_EXREGS offsetof(struct ex_regs, prmd) #define EXREGS_SIZE sizeof(struct ex_regs) =20 #else #define PC_OFFSET_EXREGS ((EXREGS_GPRS + 0) * 8) #define ESTAT_OFFSET_EXREGS ((EXREGS_GPRS + 1) * 8) #define BADV_OFFSET_EXREGS ((EXREGS_GPRS + 2) * 8) -#define EXREGS_SIZE ((EXREGS_GPRS + 3) * 8) +#define PRMD_OFFSET_EXREGS ((EXREGS_GPRS + 3) * 8) +#define EXREGS_SIZE ((EXREGS_GPRS + 4) * 8) #endif =20 #endif /* SELFTEST_KVM_PROCESSOR_H */ diff --git a/tools/testing/selftests/kvm/lib/loongarch/exception.S b/tools/= testing/selftests/kvm/lib/loongarch/exception.S index 88bfa505c6f5..3f1e4b67c5ae 100644 --- a/tools/testing/selftests/kvm/lib/loongarch/exception.S +++ b/tools/testing/selftests/kvm/lib/loongarch/exception.S @@ -51,9 +51,15 @@ handle_exception: st.d t0, sp, ESTAT_OFFSET_EXREGS csrrd t0, LOONGARCH_CSR_BADV st.d t0, sp, BADV_OFFSET_EXREGS + csrrd t0, LOONGARCH_CSR_PRMD + st.d t0, sp, PRMD_OFFSET_EXREGS =20 or a0, sp, zero bl route_exception + ld.d t0, sp, PC_OFFSET_EXREGS + csrwr t0, LOONGARCH_CSR_ERA + ld.d t0, sp, PRMD_OFFSET_EXREGS + csrwr t0, LOONGARCH_CSR_PRMD restore_gprs sp csrrd sp, LOONGARCH_CSR_KS0 ertn --=20 2.39.3 From nobody Fri Dec 19 09:35:36 2025 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C74D52E8B97; Tue, 4 Nov 2025 11:37:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762256233; cv=none; b=M49t6JQQkXawDbn41sCoH3wXjyKx3GeE7lgp/24nySHe7DM9RVTqXShNbPVM6qD226xmACXIwPKz4kU1nUnIvu/dQA16uia2O4r3jTc067LztMrkfFldihAXPjiqCSl0F36ITZSP3154NWF6pMUNfC75kbpa1/c7MV88KJm0KmU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762256233; c=relaxed/simple; bh=gz86dfn0DGmFu2yHhSbwFeWjke9Ber3pSX10dPmWSo8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=PmPvaoXmfZTdTwCnrUB3kOG+AyAPjWorB/VGAJC1+h9xj7cxbZRxlSjSI0SB2o54e9JGNIQ2BWvsszOQtwX5CfcKvGq5gGLBLsaDIj8BFJoCodYBr2eA6T2i8M2MWu+VZfLpa6a/XuvZL7xOu+JsMjF7OfJusi1VFmvt7Jxf+Ak= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [10.2.5.213]) by gateway (Coremail) with SMTP id _____8Dxvr9k5QlpZrQeAA--.64892S3; Tue, 04 Nov 2025 19:37:08 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.213]) by front1 (Coremail) with SMTP id qMiowJBxjcFk5QlpTjImAQ--.63810S2; Tue, 04 Nov 2025 19:37:08 +0800 (CST) From: Bibo Mao To: Paolo Bonzini , Sean Christopherson , Huacai Chen , Tianrui Zhao , Shuah Khan Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, loongarch@lists.linux.dev, linux-kselftest@vger.kernel.org Subject: [PATCH v2 2/7] KVM: LoongArch: selftests: Add exception handler register interface Date: Tue, 4 Nov 2025 19:36:54 +0800 Message-Id: <20251104113700.1561752-3-maobibo@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20251104113700.1561752-1-maobibo@loongson.cn> References: <20251104113700.1561752-1-maobibo@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJBxjcFk5QlpTjImAQ--.63810S2 X-CM-SenderInfo: xpdruxter6z05rqj20fqof0/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Content-Type: text/plain; charset="utf-8" Add interrupt and exception handler register interface. When exception happens, execute registered exception handler if exists, else report error. Signed-off-by: Bibo Mao --- .../kvm/include/loongarch/processor.h | 14 +++++++++ .../selftests/kvm/lib/loongarch/processor.c | 29 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/tools/testing/selftests/kvm/include/loongarch/processor.h b/to= ols/testing/selftests/kvm/include/loongarch/processor.h index 374caddfb0db..a18ac7bff303 100644 --- a/tools/testing/selftests/kvm/include/loongarch/processor.h +++ b/tools/testing/selftests/kvm/include/loongarch/processor.h @@ -84,6 +84,11 @@ #define LOONGARCH_CSR_EUEN 0x2 #define LOONGARCH_CSR_ECFG 0x4 #define LOONGARCH_CSR_ESTAT 0x5 /* Exception status */ +#define CSR_ESTAT_EXC_SHIFT 16 +#define CSR_ESTAT_EXC_WIDTH 6 +#define CSR_ESTAT_EXC (0x3f << CSR_ESTAT_EXC_SHIFT) +#define EXCCODE_INT 0 /* Interrupt */ +#define INT_TI 11 /* Timer interrupt*/ #define LOONGARCH_CSR_ERA 0x6 /* ERA */ #define LOONGARCH_CSR_BADV 0x7 /* Bad virtual address */ #define LOONGARCH_CSR_EENTRY 0xc @@ -133,6 +138,15 @@ struct ex_regs { #define PRMD_OFFSET_EXREGS offsetof(struct ex_regs, prmd) #define EXREGS_SIZE sizeof(struct ex_regs) =20 +#define VECTOR_NUM 64 +typedef void(*handler_fn)(struct ex_regs *); +struct handlers { + handler_fn exception_handlers[VECTOR_NUM]; +}; + +void vm_init_descriptor_tables(struct kvm_vm *vm); +void vm_install_exception_handler(struct kvm_vm *vm, int vector, handler_f= n handler); + #else #define PC_OFFSET_EXREGS ((EXREGS_GPRS + 0) * 8) #define ESTAT_OFFSET_EXREGS ((EXREGS_GPRS + 1) * 8) diff --git a/tools/testing/selftests/kvm/lib/loongarch/processor.c b/tools/= testing/selftests/kvm/lib/loongarch/processor.c index 0ac1abcb71cb..be537c5ff74e 100644 --- a/tools/testing/selftests/kvm/lib/loongarch/processor.c +++ b/tools/testing/selftests/kvm/lib/loongarch/processor.c @@ -11,6 +11,7 @@ #define LOONGARCH_GUEST_STACK_VADDR_MIN 0x200000 =20 static vm_paddr_t invalid_pgtable[4]; +static vm_vaddr_t exception_handlers; =20 static uint64_t virt_pte_index(struct kvm_vm *vm, vm_vaddr_t gva, int leve= l) { @@ -184,6 +185,13 @@ void assert_on_unhandled_exception(struct kvm_vcpu *vc= pu) void route_exception(struct ex_regs *regs) { unsigned long pc, estat, badv; + int vector; + struct handlers *handlers; + + handlers =3D (struct handlers *)exception_handlers; + vector =3D (regs->estat & CSR_ESTAT_EXC) >> CSR_ESTAT_EXC_SHIFT; + if (handlers && handlers->exception_handlers[vector]) + return handlers->exception_handlers[vector](regs); =20 pc =3D regs->pc; badv =3D regs->badv; @@ -192,6 +200,27 @@ void route_exception(struct ex_regs *regs) while (1) ; } =20 +void vm_init_descriptor_tables(struct kvm_vm *vm) +{ + void *addr; + + vm->handlers =3D __vm_vaddr_alloc(vm, sizeof(struct handlers), + LOONGARCH_GUEST_STACK_VADDR_MIN, MEM_REGION_DATA); + + addr =3D addr_gva2hva(vm, vm->handlers); + memset(addr, 0, vm->page_size); + exception_handlers =3D vm->handlers; + sync_global_to_guest(vm, exception_handlers); +} + +void vm_install_exception_handler(struct kvm_vm *vm, int vector, handler_f= n handler) +{ + struct handlers *handlers =3D addr_gva2hva(vm, vm->handlers); + + assert(vector < VECTOR_NUM); + handlers->exception_handlers[vector] =3D handler; +} + void vcpu_args_set(struct kvm_vcpu *vcpu, unsigned int num, ...) { int i; --=20 2.39.3 From nobody Fri Dec 19 09:35:36 2025 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 324DB2EBDC8; Tue, 4 Nov 2025 11:37:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762256235; cv=none; b=IHU0laDastJNe8w+u3NU2yjrfFYZaz5CwrvIXUOmm10twiUMbk7Cn8VRDV8FcBJhRlfgP2k9ASMRyggZCs48JzyIX2W6fPFC7JY1XK0IY/KmULBqgIPGq9zzgB3r6xcry3IRKZMX8oZYHHZUmao92huh0qpja/ZohFJaIHSjP/Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762256235; c=relaxed/simple; bh=3Cn90PzoAgXIMBrFrlCRw0RCGioUkGTP36E1XXAVHxw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=nq2Fm/gg+ivHhTUy5eU7ZM+hXQN/PUsD9rtWr1jx06yEmSPGwZf4PpUFGLPsWVzzRbzJpewdAtZadJe2k4e8NwBwRlKCBCEmJiiXE8kweE3IQkCpO4Hgl/KzmWJPuortxefE8TIlG+6o1ijQT2TmAoTC4cLNnOlS/jd7oBcc6CE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [10.2.5.213]) by gateway (Coremail) with SMTP id _____8DxP9Nm5Qlpa7QeAA--.65179S3; Tue, 04 Nov 2025 19:37:10 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.213]) by front1 (Coremail) with SMTP id qMiowJBxjcFk5QlpTjImAQ--.63810S3; Tue, 04 Nov 2025 19:37:09 +0800 (CST) From: Bibo Mao To: Paolo Bonzini , Sean Christopherson , Huacai Chen , Tianrui Zhao , Shuah Khan Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, loongarch@lists.linux.dev, linux-kselftest@vger.kernel.org Subject: [PATCH v2 3/7] KVM: LoongArch: selftests: Add basic interfaces Date: Tue, 4 Nov 2025 19:36:55 +0800 Message-Id: <20251104113700.1561752-4-maobibo@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20251104113700.1561752-1-maobibo@loongson.cn> References: <20251104113700.1561752-1-maobibo@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJBxjcFk5QlpTjImAQ--.63810S3 X-CM-SenderInfo: xpdruxter6z05rqj20fqof0/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Content-Type: text/plain; charset="utf-8" Add some basic function interfaces such as CSR register access, local irq enable or disable APIs. Signed-off-by: Bibo Mao --- .../kvm/include/loongarch/processor.h | 52 +++++++++++++++++++ .../selftests/kvm/lib/loongarch/processor.c | 5 ++ 2 files changed, 57 insertions(+) diff --git a/tools/testing/selftests/kvm/include/loongarch/processor.h b/to= ols/testing/selftests/kvm/include/loongarch/processor.h index a18ac7bff303..b027f8f4dac7 100644 --- a/tools/testing/selftests/kvm/include/loongarch/processor.h +++ b/tools/testing/selftests/kvm/include/loongarch/processor.h @@ -118,6 +118,28 @@ #define CSR_TLBREHI_PS_SHIFT 0 #define CSR_TLBREHI_PS (0x3fUL << CSR_TLBREHI_PS_SHIFT) =20 +#define csr_read(csr) \ +({ \ + register unsigned long __v; \ + __asm__ __volatile__( \ + "csrrd %[val], %[reg]\n\t" \ + : [val] "=3Dr" (__v) \ + : [reg] "i" (csr) \ + : "memory"); \ + __v; \ +}) + +#define csr_write(v, csr) \ +({ \ + register unsigned long __v =3D v; \ + __asm__ __volatile__ ( \ + "csrwr %[val], %[reg]\n\t" \ + : [val] "+r" (__v) \ + : [reg] "i" (csr) \ + : "memory"); \ + __v; \ +}) + #define EXREGS_GPRS (32) =20 #ifndef __ASSEMBLER__ @@ -147,6 +169,36 @@ struct handlers { void vm_init_descriptor_tables(struct kvm_vm *vm); void vm_install_exception_handler(struct kvm_vm *vm, int vector, handler_f= n handler); =20 +static inline void local_irq_enable(void) +{ + unsigned int flags =3D CSR_CRMD_IE; + + register unsigned int mask asm("$t0") =3D CSR_CRMD_IE; + + __asm__ __volatile__( + "csrxchg %[val], %[mask], %[reg]\n\t" + : [val] "+r" (flags) + : [mask] "r" (mask), [reg] "i" (LOONGARCH_CSR_CRMD) + : "memory"); +} + +static inline void local_irq_disable(void) +{ + unsigned int flags =3D 0; + + register unsigned int mask asm("$t0") =3D CSR_CRMD_IE; + + __asm__ __volatile__( + "csrxchg %[val], %[mask], %[reg]\n\t" + : [val] "+r" (flags) + : [mask] "r" (mask), [reg] "i" (LOONGARCH_CSR_CRMD) + : "memory"); +} + +static inline void cpu_relax(void) +{ + asm volatile("nop" ::: "memory"); +} #else #define PC_OFFSET_EXREGS ((EXREGS_GPRS + 0) * 8) #define ESTAT_OFFSET_EXREGS ((EXREGS_GPRS + 1) * 8) diff --git a/tools/testing/selftests/kvm/lib/loongarch/processor.c b/tools/= testing/selftests/kvm/lib/loongarch/processor.c index be537c5ff74e..20ba476ccb72 100644 --- a/tools/testing/selftests/kvm/lib/loongarch/processor.c +++ b/tools/testing/selftests/kvm/lib/loongarch/processor.c @@ -373,3 +373,8 @@ void vcpu_arch_set_entry_point(struct kvm_vcpu *vcpu, v= oid *guest_code) regs.pc =3D (uint64_t)guest_code; vcpu_regs_set(vcpu, ®s); } + +uint32_t guest_get_vcpuid(void) +{ + return csr_read(LOONGARCH_CSR_CPUID); +} --=20 2.39.3 From nobody Fri Dec 19 09:35:36 2025 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 57A4C2EACEF; Tue, 4 Nov 2025 11:37:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762256250; cv=none; b=FosiXZtGgCuhwQaCnN6euhRhSVGWSW4Y3mwBiiJzal9et1VUn8uLlfLDfU5BjEAqdSpHoiz3YSRvNAighJoe6ThpEycM65D1uXJfPwGDakdDIfbPL2PFwxtP1JjJvJW5vknlO+2ywwU7mZALcvg3IDxM2tc/ILg9ilwJR+jCUGU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762256250; c=relaxed/simple; bh=m5g1Nc2sKkHb+08sJPs96gk/KbEO0sV6nYP1M3eBi40=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=q3WyaQ8P1MBihszqb4EV6u8E2GzXN/0w3pvU6IqaQfja8RdN9MvYv1NOhuASuDkiZKpfOXzMFpRlUzhw1Y88FPdkbMtAV00PdU53VxgBJLlYxznIMYkoHi/veeTjmlo71WC8J8sm4cdO5fvlrdotAHLFvRmzrw+dx4fLN8ilu+s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [10.2.5.213]) by gateway (Coremail) with SMTP id _____8DxudFu5QlpgrQeAA--.1948S3; Tue, 04 Nov 2025 19:37:18 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.213]) by front1 (Coremail) with SMTP id qMiowJCxM+Rr5QlpWDImAQ--.51821S2; Tue, 04 Nov 2025 19:37:15 +0800 (CST) From: Bibo Mao To: Paolo Bonzini , Sean Christopherson , Huacai Chen , Shuah Khan , Tianrui Zhao , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-kselftest@vger.kernel.org, loongarch@lists.linux.dev, linux-riscv@lists.infradead.org Subject: [PATCH v2 4/7] KVM: LoongArch: selftests: Add timer test case with one-shot mode Date: Tue, 4 Nov 2025 19:36:56 +0800 Message-Id: <20251104113700.1561752-5-maobibo@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20251104113700.1561752-1-maobibo@loongson.cn> References: <20251104113700.1561752-1-maobibo@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJCxM+Rr5QlpWDImAQ--.51821S2 X-CM-SenderInfo: xpdruxter6z05rqj20fqof0/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Content-Type: text/plain; charset="utf-8" Add timer test case based on common arch_timer code, one-shot mode is tested with timer interrupt. Signed-off-by: Bibo Mao --- tools/testing/selftests/kvm/Makefile.kvm | 10 +- .../kvm/include/loongarch/arch_timer.h | 79 +++++++++++++++ .../kvm/include/loongarch/processor.h | 10 ++ .../selftests/kvm/lib/loongarch/processor.c | 4 +- .../selftests/kvm/loongarch/arch_timer.c | 98 +++++++++++++++++++ 5 files changed, 196 insertions(+), 5 deletions(-) create mode 100644 tools/testing/selftests/kvm/include/loongarch/arch_time= r.h create mode 100644 tools/testing/selftests/kvm/loongarch/arch_timer.c diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index 148d427ff24b..662adf8f309b 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -183,6 +183,8 @@ TEST_GEN_PROGS_arm64 +=3D memslot_perf_test TEST_GEN_PROGS_arm64 +=3D mmu_stress_test TEST_GEN_PROGS_arm64 +=3D rseq_test TEST_GEN_PROGS_arm64 +=3D steal_time +SPLIT_TESTS_arm64 +=3D arch_timer +SPLIT_TESTS_arm64 +=3D get-reg-list =20 TEST_GEN_PROGS_s390 =3D $(TEST_GEN_PROGS_COMMON) TEST_GEN_PROGS_s390 +=3D s390/memop @@ -209,6 +211,8 @@ TEST_GEN_PROGS_riscv +=3D memslot_perf_test TEST_GEN_PROGS_riscv +=3D mmu_stress_test TEST_GEN_PROGS_riscv +=3D rseq_test TEST_GEN_PROGS_riscv +=3D steal_time +SPLIT_TESTS_riscv +=3D arch_timer +SPLIT_TESTS_riscv +=3D get-reg-list =20 TEST_GEN_PROGS_loongarch +=3D coalesced_io_test TEST_GEN_PROGS_loongarch +=3D demand_paging_test @@ -222,10 +226,10 @@ TEST_GEN_PROGS_loongarch +=3D kvm_page_table_test TEST_GEN_PROGS_loongarch +=3D memslot_modification_stress_test TEST_GEN_PROGS_loongarch +=3D memslot_perf_test TEST_GEN_PROGS_loongarch +=3D set_memory_region_test +TEST_GEN_PROGS_loongarch +=3D arch_timer +SPLIT_TESTS_loongarch =3D arch_timer =20 -SPLIT_TESTS +=3D arch_timer -SPLIT_TESTS +=3D get-reg-list - +SPLIT_TESTS +=3D $(SPLIT_TESTS_$(ARCH)) TEST_PROGS +=3D $(TEST_PROGS_$(ARCH)) TEST_GEN_PROGS +=3D $(TEST_GEN_PROGS_$(ARCH)) TEST_GEN_PROGS_EXTENDED +=3D $(TEST_GEN_PROGS_EXTENDED_$(ARCH)) diff --git a/tools/testing/selftests/kvm/include/loongarch/arch_timer.h b/t= ools/testing/selftests/kvm/include/loongarch/arch_timer.h new file mode 100644 index 000000000000..94b1cba2744d --- /dev/null +++ b/tools/testing/selftests/kvm/include/loongarch/arch_timer.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * LoongArch Constant Timer specific interface + */ +#ifndef SELFTEST_KVM_ARCH_TIMER_H +#define SELFTEST_KVM_ARCH_TIMER_H + +#include "processor.h" +/* LoongArch timer frequency is constant 100MHZ */ +#define TIMER_FREQ (100UL << 20) +#define msec_to_cycles(msec) (TIMER_FREQ * (unsigned long)(msec) / 1000) +#define usec_to_cycles(usec) (TIMER_FREQ * (unsigned long)(usec) / 1000000) +#define cycles_to_usec(cycles) ((unsigned long)(cycles) * 1000000 / TIMER_= FREQ) + +static inline unsigned long timer_get_cycles(void) +{ + unsigned long val =3D 0; + + __asm__ __volatile__( + "rdtime.d %0, $zero\n\t" + : "=3Dr"(val) + : + ); + + return val; +} + +static inline void timer_set_next_cmp_ms(unsigned int msec, bool period) +{ + unsigned long val; + + val =3D msec_to_cycles(msec) & CSR_TCFG_VAL; + val |=3D CSR_TCFG_EN; + if (period) + val |=3D CSR_TCFG_PERIOD; + csr_write(val, LOONGARCH_CSR_TCFG); +} + +static inline unsigned long timer_get_val(void) +{ + return csr_read(LOONGARCH_CSR_TVAL); +} + +static inline unsigned long timer_get_cfg(void) +{ + return csr_read(LOONGARCH_CSR_TCFG); +} + +static inline void timer_irq_enable(void) +{ + unsigned long val; + + val =3D csr_read(LOONGARCH_CSR_ECFG); + val |=3D ECFGF_TIMER; + csr_write(val, LOONGARCH_CSR_ECFG); +} + +static inline void timer_irq_disable(void) +{ + unsigned long val; + + val =3D csr_read(LOONGARCH_CSR_ECFG); + val &=3D ~ECFGF_TIMER; + csr_write(val, LOONGARCH_CSR_ECFG); +} + +static inline void __delay(uint64_t cycles) +{ + uint64_t start =3D timer_get_cycles(); + + while ((timer_get_cycles() - start) < cycles) + cpu_relax(); +} + +static inline void udelay(unsigned long usec) +{ + __delay(usec_to_cycles(usec)); +} +#endif /* SELFTEST_KVM_ARCH_TIMER_H */ diff --git a/tools/testing/selftests/kvm/include/loongarch/processor.h b/to= ols/testing/selftests/kvm/include/loongarch/processor.h index b027f8f4dac7..61f6e215046b 100644 --- a/tools/testing/selftests/kvm/include/loongarch/processor.h +++ b/tools/testing/selftests/kvm/include/loongarch/processor.h @@ -83,6 +83,8 @@ #define LOONGARCH_CSR_PRMD 0x1 #define LOONGARCH_CSR_EUEN 0x2 #define LOONGARCH_CSR_ECFG 0x4 +#define ECFGB_TIMER 11 +#define ECFGF_TIMER (BIT_ULL(ECFGB_TIMER)) #define LOONGARCH_CSR_ESTAT 0x5 /* Exception status */ #define CSR_ESTAT_EXC_SHIFT 16 #define CSR_ESTAT_EXC_WIDTH 6 @@ -111,6 +113,14 @@ #define LOONGARCH_CSR_KS1 0x31 #define LOONGARCH_CSR_TMID 0x40 #define LOONGARCH_CSR_TCFG 0x41 +#define CSR_TCFG_VAL (BIT_ULL(48) - BIT_ULL(2)) +#define CSR_TCFG_PERIOD_SHIFT 1 +#define CSR_TCFG_PERIOD (0x1UL << CSR_TCFG_PERIOD_SHIFT) +#define CSR_TCFG_EN (0x1UL) +#define LOONGARCH_CSR_TVAL 0x42 +#define LOONGARCH_CSR_TINTCLR 0x44 /* Timer interrupt clear */ +#define CSR_TINTCLR_TI_SHIFT 0 +#define CSR_TINTCLR_TI (1 << CSR_TINTCLR_TI_SHIFT) /* TLB refill exception entry */ #define LOONGARCH_CSR_TLBRENTRY 0x88 #define LOONGARCH_CSR_TLBRSAVE 0x8b diff --git a/tools/testing/selftests/kvm/lib/loongarch/processor.c b/tools/= testing/selftests/kvm/lib/loongarch/processor.c index 20ba476ccb72..436990258068 100644 --- a/tools/testing/selftests/kvm/lib/loongarch/processor.c +++ b/tools/testing/selftests/kvm/lib/loongarch/processor.c @@ -271,8 +271,8 @@ static void loongarch_vcpu_setup(struct kvm_vcpu *vcpu) TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode); } =20 - /* user mode and page enable mode */ - val =3D PLV_USER | CSR_CRMD_PG; + /* kernel mode and page enable mode */ + val =3D PLV_KERN | CSR_CRMD_PG; loongarch_set_csr(vcpu, LOONGARCH_CSR_CRMD, val); loongarch_set_csr(vcpu, LOONGARCH_CSR_PRMD, val); loongarch_set_csr(vcpu, LOONGARCH_CSR_EUEN, 1); diff --git a/tools/testing/selftests/kvm/loongarch/arch_timer.c b/tools/tes= ting/selftests/kvm/loongarch/arch_timer.c new file mode 100644 index 000000000000..2a2cebcf3885 --- /dev/null +++ b/tools/testing/selftests/kvm/loongarch/arch_timer.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * + * The test validates one-shot constant timer IRQ using CSR_TCFG and + * CSR_TVAL registers. + */ +#include "arch_timer.h" +#include "kvm_util.h" +#include "processor.h" +#include "timer_test.h" +#include "ucall_common.h" + +static void guest_irq_handler(struct ex_regs *regs) +{ + uint64_t xcnt, val, cfg, xcnt_diff_us; + unsigned int intid; + uint32_t cpu =3D guest_get_vcpuid(); + struct test_vcpu_shared_data *shared_data =3D &vcpu_shared_data[cpu]; + + intid =3D !!(regs->estat & BIT(INT_TI)); + + /* Make sure we are dealing with the correct timer IRQ */ + GUEST_ASSERT_EQ(intid, 1); + + cfg =3D timer_get_cfg(); + + /* + * On physical machine, value of LOONGARCH_CSR_TVAL is BIT_ULL(48) - 1 + * On virtual machine, its value counts down from BIT_ULL(48) - 1 + */ + val =3D timer_get_val(); + xcnt =3D timer_get_cycles(); + xcnt_diff_us =3D cycles_to_usec(xcnt - shared_data->xcnt); + + /* Basic 'timer condition met' check */ + __GUEST_ASSERT(val > cfg, + "val =3D 0x%lx, cfg =3D 0x%lx, xcnt_diff_us =3D 0x%lx", + val, cfg, xcnt_diff_us); + + csr_write(CSR_TINTCLR_TI, LOONGARCH_CSR_TINTCLR); + WRITE_ONCE(shared_data->nr_iter, shared_data->nr_iter + 1); +} + +static void guest_test_oneshot_timer(uint32_t cpu) +{ + uint32_t irq_iter, config_iter; + uint64_t us; + struct test_vcpu_shared_data *shared_data =3D &vcpu_shared_data[cpu]; + + shared_data->nr_iter =3D 0; + shared_data->guest_stage =3D 0; + us =3D msecs_to_usecs(test_args.timer_period_ms) + test_args.timer_err_ma= rgin_us; + for (config_iter =3D 0; config_iter < test_args.nr_iter; config_iter++) { + shared_data->xcnt =3D timer_get_cycles(); + + /* Setup the next interrupt */ + timer_set_next_cmp_ms(test_args.timer_period_ms, false); + /* Setup a timeout for the interrupt to arrive */ + udelay(us); + + irq_iter =3D READ_ONCE(shared_data->nr_iter); + __GUEST_ASSERT(config_iter + 1 =3D=3D irq_iter, + "config_iter + 1 =3D 0x%x, irq_iter =3D 0x%x.\n" + " Guest timer interrupt was not triggered within the specified\n" + " interval, try to increase the error margin by [-e] option.\n", + config_iter + 1, irq_iter); + } +} + +static void guest_code(void) +{ + uint32_t cpu =3D guest_get_vcpuid(); + + timer_irq_enable(); + local_irq_enable(); + guest_test_oneshot_timer(cpu); + + GUEST_DONE(); +} + +struct kvm_vm *test_vm_create(void) +{ + struct kvm_vm *vm; + int nr_vcpus =3D test_args.nr_vcpus; + + vm =3D vm_create_with_vcpus(nr_vcpus, guest_code, vcpus); + vm_init_descriptor_tables(vm); + vm_install_exception_handler(vm, EXCCODE_INT, guest_irq_handler); + + /* Make all the test's cmdline args visible to the guest */ + sync_global_to_guest(vm, test_args); + return vm; +} + +void test_vm_cleanup(struct kvm_vm *vm) +{ + kvm_vm_free(vm); +} --=20 2.39.3 From nobody Fri Dec 19 09:35:36 2025 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 832342E8E00; Tue, 4 Nov 2025 11:37:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762256245; cv=none; b=CqQF92+jXRETUDB8AvI1DFP5UcUDILCB9QipCO1AaIo3F0LoqV+82aZH8U5l7LcbdQTQILUMyjhYzMqzlnv3IEuQDwEyXR8XXRS4sqOr3Ch3hthW5ggyouhPElUet/FrsWlQHhlB1gzaqtoJ0gaPgkDP1IZHkSIiAun1Zb6Yqvs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762256245; c=relaxed/simple; bh=edbj2W3W9sG89u/NiKy0Vr7p5pOwZjU4SCA7YpuQaJ0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BlD0yv4j8gWGc5ng/yGGThw8ZvGFiDBfS8d96vQifVRltRhfCjS/DNw9tzNszGAptEsC5SwiH3MwGDuslqqEE70evWh/QPTlwHjoK2dv45b9iBAKspIo9Cm2eoWGR/eL31b4YOVpZUzIUGE0mh9oUF1UoYUrz0ohZ1ua8Fpxong= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [10.2.5.213]) by gateway (Coremail) with SMTP id _____8Axjr9t5Qlpf7QeAA--.64813S3; Tue, 04 Nov 2025 19:37:17 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.213]) by front1 (Coremail) with SMTP id qMiowJCxM+Rr5QlpWDImAQ--.51821S3; Tue, 04 Nov 2025 19:37:17 +0800 (CST) From: Bibo Mao To: Paolo Bonzini , Sean Christopherson , Huacai Chen , Tianrui Zhao , Shuah Khan Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, loongarch@lists.linux.dev, linux-kselftest@vger.kernel.org Subject: [PATCH v2 5/7] KVM: LoongArch: selftests: Add period mode timer test Date: Tue, 4 Nov 2025 19:36:57 +0800 Message-Id: <20251104113700.1561752-6-maobibo@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20251104113700.1561752-1-maobibo@loongson.cn> References: <20251104113700.1561752-1-maobibo@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJCxM+Rr5QlpWDImAQ--.51821S3 X-CM-SenderInfo: xpdruxter6z05rqj20fqof0/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Content-Type: text/plain; charset="utf-8" Period mode timer is added. Timer only need program once with period mode, its compared tick value will reload when timer is fired. Signed-off-by: Bibo Mao --- .../kvm/include/loongarch/arch_timer.h | 5 ++++ .../selftests/kvm/loongarch/arch_timer.c | 28 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/tools/testing/selftests/kvm/include/loongarch/arch_timer.h b/t= ools/testing/selftests/kvm/include/loongarch/arch_timer.h index 94b1cba2744d..b6399e748f72 100644 --- a/tools/testing/selftests/kvm/include/loongarch/arch_timer.h +++ b/tools/testing/selftests/kvm/include/loongarch/arch_timer.h @@ -36,6 +36,11 @@ static inline void timer_set_next_cmp_ms(unsigned int ms= ec, bool period) csr_write(val, LOONGARCH_CSR_TCFG); } =20 +static inline void disable_timer(void) +{ + csr_write(0, LOONGARCH_CSR_TCFG); +} + static inline unsigned long timer_get_val(void) { return csr_read(LOONGARCH_CSR_TVAL); diff --git a/tools/testing/selftests/kvm/loongarch/arch_timer.c b/tools/tes= ting/selftests/kvm/loongarch/arch_timer.c index 2a2cebcf3885..a4a39f24bb7e 100644 --- a/tools/testing/selftests/kvm/loongarch/arch_timer.c +++ b/tools/testing/selftests/kvm/loongarch/arch_timer.c @@ -23,6 +23,13 @@ static void guest_irq_handler(struct ex_regs *regs) GUEST_ASSERT_EQ(intid, 1); =20 cfg =3D timer_get_cfg(); + if (cfg & CSR_TCFG_PERIOD) { + WRITE_ONCE(shared_data->nr_iter, shared_data->nr_iter - 1); + if (shared_data->nr_iter =3D=3D 0) + disable_timer(); + csr_write(CSR_TINTCLR_TI, LOONGARCH_CSR_TINTCLR); + return; + } =20 /* * On physical machine, value of LOONGARCH_CSR_TVAL is BIT_ULL(48) - 1 @@ -67,6 +74,26 @@ static void guest_test_oneshot_timer(uint32_t cpu) } } =20 +static void guest_test_period_timer(uint32_t cpu) +{ + uint32_t irq_iter; + uint64_t us; + struct test_vcpu_shared_data *shared_data =3D &vcpu_shared_data[cpu]; + + shared_data->nr_iter =3D test_args.nr_iter; + shared_data->xcnt =3D timer_get_cycles(); + us =3D msecs_to_usecs(test_args.timer_period_ms) + test_args.timer_err_ma= rgin_us; + timer_set_next_cmp_ms(test_args.timer_period_ms, true); + /* Setup a timeout for the interrupt to arrive */ + udelay(us * test_args.nr_iter); + irq_iter =3D READ_ONCE(shared_data->nr_iter); + __GUEST_ASSERT(irq_iter =3D=3D 0, + "irq_iter =3D 0x%x.\n" + " Guest period timer interrupt was not triggered within the specified\= n" + " interval, try to increase the error margin by [-e] option.\n", + irq_iter); +} + static void guest_code(void) { uint32_t cpu =3D guest_get_vcpuid(); @@ -74,6 +101,7 @@ static void guest_code(void) timer_irq_enable(); local_irq_enable(); guest_test_oneshot_timer(cpu); + guest_test_period_timer(cpu); =20 GUEST_DONE(); } --=20 2.39.3 From nobody Fri Dec 19 09:35:36 2025 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D2A082E8E00; Tue, 4 Nov 2025 11:37:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762256250; cv=none; b=kokDVXpoD7DnZYzFQSicRIajURtaIb19yyVyZeD92PjB/mCxOfP/+hszSTsxdv9P23WQPpjyrEt8irGSMt315jwTV6M+7Iplje1tb7j9/TolBaFBlS21DlC80/NQ7+TKfUSl+A190q+p2D94hDDu6qgzMN+FnfDF/Y4hb/2m6Jo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762256250; c=relaxed/simple; bh=QbU9byuyS/78QGuYQ8ONZCVTLzdJyLHYPbvjHKhqSfQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=pANUpVbikb/OZTzmCvTjtOMpq+EK9veS5tjnpk0j/vGAwlk4ODuzZNdzujLDyLqETk0R96klvFT0kdSE4rPDUNlNl2T09VNwEC4TVG4d7bgo8qGGrX74Agt01iViFdgyRMO8VP22QJLxRpZ45MbjBPY+7goqI/pJoRLp6mU56So= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [10.2.5.213]) by gateway (Coremail) with SMTP id _____8BxndJw5QlpiLQeAA--.576S3; Tue, 04 Nov 2025 19:37:20 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.213]) by front1 (Coremail) with SMTP id qMiowJAx+8Bw5QlpZDImAQ--.57838S2; Tue, 04 Nov 2025 19:37:20 +0800 (CST) From: Bibo Mao To: Paolo Bonzini , Sean Christopherson , Huacai Chen , Shuah Khan Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-kselftest@vger.kernel.org Subject: [PATCH v2 6/7] KVM: LoongArch: selftests: Add SW emulated timer test Date: Tue, 4 Nov 2025 19:36:58 +0800 Message-Id: <20251104113700.1561752-7-maobibo@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20251104113700.1561752-1-maobibo@loongson.cn> References: <20251104113700.1561752-1-maobibo@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJAx+8Bw5QlpZDImAQ--.57838S2 X-CM-SenderInfo: xpdruxter6z05rqj20fqof0/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Content-Type: text/plain; charset="utf-8" This test case setup one-shot timer and execute idle instruction immediately to indicate giving up CPU, hypervisor will emulate SW hrtimer and wakeup vCPU when SW hrtimer is fired. Signed-off-by: Bibo Mao --- .../selftests/kvm/loongarch/arch_timer.c | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tools/testing/selftests/kvm/loongarch/arch_timer.c b/tools/tes= ting/selftests/kvm/loongarch/arch_timer.c index a4a39f24bb7e..579132a082cd 100644 --- a/tools/testing/selftests/kvm/loongarch/arch_timer.c +++ b/tools/testing/selftests/kvm/loongarch/arch_timer.c @@ -94,6 +94,45 @@ static void guest_test_period_timer(uint32_t cpu) irq_iter); } =20 +static void do_idle(void) +{ + unsigned int intid; + unsigned long estat; + + __asm__ __volatile__("idle 0" : : : "memory"); + + estat =3D csr_read(LOONGARCH_CSR_ESTAT); + intid =3D !!(estat & BIT(INT_TI)); + + /* Make sure pending timer IRQ arrived */ + GUEST_ASSERT_EQ(intid, 1); + csr_write(CSR_TINTCLR_TI, LOONGARCH_CSR_TINTCLR); +} + +static void guest_test_emulate_timer(uint32_t cpu) +{ + uint32_t config_iter; + uint64_t xcnt_diff_us, us; + struct test_vcpu_shared_data *shared_data =3D &vcpu_shared_data[cpu]; + + local_irq_disable(); + shared_data->nr_iter =3D 0; + us =3D msecs_to_usecs(test_args.timer_period_ms); + for (config_iter =3D 0; config_iter < test_args.nr_iter; config_iter++) { + shared_data->xcnt =3D timer_get_cycles(); + + /* Setup the next interrupt */ + timer_set_next_cmp_ms(test_args.timer_period_ms, false); + do_idle(); + + xcnt_diff_us =3D cycles_to_usec(timer_get_cycles() - shared_data->xcnt); + __GUEST_ASSERT(xcnt_diff_us >=3D us, + "xcnt_diff_us =3D 0x%lx, us =3D 0x%lx.\n", + xcnt_diff_us, us); + } + local_irq_enable(); +} + static void guest_code(void) { uint32_t cpu =3D guest_get_vcpuid(); @@ -102,6 +141,7 @@ static void guest_code(void) local_irq_enable(); guest_test_oneshot_timer(cpu); guest_test_period_timer(cpu); + guest_test_emulate_timer(cpu); =20 GUEST_DONE(); } --=20 2.39.3 From nobody Fri Dec 19 09:35:36 2025 Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B43762F1FF6; Tue, 4 Nov 2025 11:37:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762256252; cv=none; b=ZWDx2+2arLS9q6XhrMbemvffoVLs9UdDG+qm4xNl0TeDhw9fL8eoq+2IjC6EDI2xw23bfajnVkMSQha+UupUSb0Mr3QEFBPvM7Qpc7MOFXfWK7bR9kF5Wq3FRQky4ixiEsW02u2z1NdxrYoiiOlhWs+dwFPFB/1MiHlLMXJZvhk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762256252; c=relaxed/simple; bh=EYH/yVHdnb089sbM06R3GlT36iMXXinhgjkzboFZYQI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=YUYPrcfQS0moD5A4HNsiu65wWKDsKiA025IGjpQYyqUtwI3cCllI5E3lKXoNZgaW8hcJLfqvG20wzMoAit0mHsKah2heXG/fhQMaAclvwbMjPr0P91avmXIj2hV7jYpOF1S4UJSVMovUcmh6M6w7mirghZI637YsRvc/p1UdvIg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn; spf=pass smtp.mailfrom=loongson.cn; arc=none smtp.client-ip=114.242.206.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [10.2.5.213]) by gateway (Coremail) with SMTP id _____8CxqdFy5QlpjbQeAA--.1524S3; Tue, 04 Nov 2025 19:37:22 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.213]) by front1 (Coremail) with SMTP id qMiowJAx+8Bw5QlpZDImAQ--.57838S3; Tue, 04 Nov 2025 19:37:21 +0800 (CST) From: Bibo Mao To: Paolo Bonzini , Sean Christopherson , Huacai Chen , Tianrui Zhao , Shuah Khan Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, loongarch@lists.linux.dev, linux-kselftest@vger.kernel.org Subject: [PATCH v2 7/7] KVM: LoongArch: selftests: Add time counter test Date: Tue, 4 Nov 2025 19:36:59 +0800 Message-Id: <20251104113700.1561752-8-maobibo@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20251104113700.1561752-1-maobibo@loongson.cn> References: <20251104113700.1561752-1-maobibo@loongson.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJAx+8Bw5QlpZDImAQ--.57838S3 X-CM-SenderInfo: xpdruxter6z05rqj20fqof0/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Content-Type: text/plain; charset="utf-8" With time counter test, it is to verify that time count starts from 0 and always grows up then. Signed-off-by: Bibo Mao --- .../selftests/kvm/lib/loongarch/processor.c | 9 ++++++ .../selftests/kvm/loongarch/arch_timer.c | 29 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/tools/testing/selftests/kvm/lib/loongarch/processor.c b/tools/= testing/selftests/kvm/lib/loongarch/processor.c index 436990258068..ac2ffd076bff 100644 --- a/tools/testing/selftests/kvm/lib/loongarch/processor.c +++ b/tools/testing/selftests/kvm/lib/loongarch/processor.c @@ -3,6 +3,7 @@ #include #include =20 +#include #include "kvm_util.h" #include "processor.h" #include "ucall_common.h" @@ -256,6 +257,11 @@ static void loongarch_set_csr(struct kvm_vcpu *vcpu, u= int64_t id, uint64_t val) __vcpu_set_reg(vcpu, csrid, val); } =20 +static void loongarch_set_reg(struct kvm_vcpu *vcpu, uint64_t id, uint64_t= val) +{ + __vcpu_set_reg(vcpu, id, val); +} + static void loongarch_vcpu_setup(struct kvm_vcpu *vcpu) { int width; @@ -279,6 +285,9 @@ static void loongarch_vcpu_setup(struct kvm_vcpu *vcpu) loongarch_set_csr(vcpu, LOONGARCH_CSR_ECFG, 0); loongarch_set_csr(vcpu, LOONGARCH_CSR_TCFG, 0); loongarch_set_csr(vcpu, LOONGARCH_CSR_ASID, 1); + /* time count start from 0 */ + val =3D 0; + loongarch_set_reg(vcpu, KVM_REG_LOONGARCH_COUNTER, val); =20 val =3D 0; width =3D vm->page_shift - 3; diff --git a/tools/testing/selftests/kvm/loongarch/arch_timer.c b/tools/tes= ting/selftests/kvm/loongarch/arch_timer.c index 579132a082cd..f3a25a0163fc 100644 --- a/tools/testing/selftests/kvm/loongarch/arch_timer.c +++ b/tools/testing/selftests/kvm/loongarch/arch_timer.c @@ -133,10 +133,39 @@ static void guest_test_emulate_timer(uint32_t cpu) local_irq_enable(); } =20 +static void guest_time_count_test(uint32_t cpu) +{ + uint32_t config_iter; + unsigned long start, end, prev, us; + + /* Assuming that test case starts to run in 1 second */ + start =3D timer_get_cycles(); + us =3D msec_to_cycles(1000); + __GUEST_ASSERT(start <=3D us, + "start =3D 0x%lx, us =3D 0x%lx.\n", + start, us); + + us =3D msec_to_cycles(test_args.timer_period_ms); + for (config_iter =3D 0; config_iter < test_args.nr_iter; config_iter++) { + start =3D timer_get_cycles(); + end =3D start + us; + /* test time count growing up always */ + while (start < end) { + prev =3D start; + start =3D timer_get_cycles(); + __GUEST_ASSERT(prev <=3D start, + "prev =3D 0x%lx, start =3D 0x%lx.\n", + prev, start); + } + } +} + static void guest_code(void) { uint32_t cpu =3D guest_get_vcpuid(); =20 + /* must run at first */ + guest_time_count_test(cpu); timer_irq_enable(); local_irq_enable(); guest_test_oneshot_timer(cpu); --=20 2.39.3