Add some basic function interfaces such as CSR register access,
local irq enable or disable APIs.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
.../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/tools/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)
+#define csr_read(csr) \
+({ \
+ register unsigned long __v; \
+ __asm__ __volatile__( \
+ "csrrd %[val], %[reg]\n\t" \
+ : [val] "=r" (__v) \
+ : [reg] "i" (csr) \
+ : "memory"); \
+ __v; \
+})
+
+#define csr_write(v, csr) \
+({ \
+ register unsigned long __v = v; \
+ __asm__ __volatile__ ( \
+ "csrwr %[val], %[reg]\n\t" \
+ : [val] "+r" (__v) \
+ : [reg] "i" (csr) \
+ : "memory"); \
+ __v; \
+})
+
#define EXREGS_GPRS (32)
#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_fn handler);
+static inline void local_irq_enable(void)
+{
+ unsigned int flags = CSR_CRMD_IE;
+
+ register unsigned int mask asm("$t0") = 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 = 0;
+
+ register unsigned int mask asm("$t0") = 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, void *guest_code)
regs.pc = (uint64_t)guest_code;
vcpu_regs_set(vcpu, ®s);
}
+
+uint32_t guest_get_vcpuid(void)
+{
+ return csr_read(LOONGARCH_CSR_CPUID);
+}
--
2.39.3
Hi, Bibo,
On Tue, Nov 4, 2025 at 7:37 PM Bibo Mao <maobibo@loongson.cn> wrote:
>
> Add some basic function interfaces such as CSR register access,
> local irq enable or disable APIs.
This is "basic interfaces", so better to be before Patch-2 (or keep
the order but change the subject)?
Huacai
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
> .../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/tools/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)
>
> +#define csr_read(csr) \
> +({ \
> + register unsigned long __v; \
> + __asm__ __volatile__( \
> + "csrrd %[val], %[reg]\n\t" \
> + : [val] "=r" (__v) \
> + : [reg] "i" (csr) \
> + : "memory"); \
> + __v; \
> +})
> +
> +#define csr_write(v, csr) \
> +({ \
> + register unsigned long __v = v; \
> + __asm__ __volatile__ ( \
> + "csrwr %[val], %[reg]\n\t" \
> + : [val] "+r" (__v) \
> + : [reg] "i" (csr) \
> + : "memory"); \
> + __v; \
> +})
> +
> #define EXREGS_GPRS (32)
>
> #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_fn handler);
>
> +static inline void local_irq_enable(void)
> +{
> + unsigned int flags = CSR_CRMD_IE;
> +
> + register unsigned int mask asm("$t0") = 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 = 0;
> +
> + register unsigned int mask asm("$t0") = 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, void *guest_code)
> regs.pc = (uint64_t)guest_code;
> vcpu_regs_set(vcpu, ®s);
> }
> +
> +uint32_t guest_get_vcpuid(void)
> +{
> + return csr_read(LOONGARCH_CSR_CPUID);
> +}
> --
> 2.39.3
>
© 2016 - 2025 Red Hat, Inc.