[PATCH] loongarch: expose LAMCAS existence via cpuinfo and hwcap

Rong Bao posted 1 patch 2 weeks, 6 days ago
arch/loongarch/include/asm/cpu-features.h |  1 +
arch/loongarch/include/asm/cpu.h          | 64 ++++++++++++-----------
arch/loongarch/include/uapi/asm/hwcap.h   |  1 +
arch/loongarch/kernel/cpu-probe.c         |  4 ++
arch/loongarch/kernel/proc.c              |  2 +
5 files changed, 41 insertions(+), 31 deletions(-)
[PATCH] loongarch: expose LAMCAS existence via cpuinfo and hwcap
Posted by Rong Bao 2 weeks, 6 days ago
Currently, neither /proc/cpuinfo nor hwcap exposes the existence of the
LAMCAS extension, which is part of LA64v1.1. For example, on a Loongson
3B6000, /proc/cpuinfo is as follows:

        processor               : 23
        package                 : 0
        core                    : 11
        global_id               : 31
        CPU Family              : Loongson-64bit
        Model Name              : Loongson-3B6000
        PRID                    : LA664 (0014d011)
        CPU Revision            : 0x11
        FPU Revision            : 0x01
        CPU MHz                 : 2200.00
        BogoMIPS                : 4400.00
        TLB Entries             : 2112
        Address Sizes           : 48 bits physical, 48 bits virtual
        ISA                     : loongarch32r loongarch32s loongarch64
        Features                : cpucfg lam lam_bh scq ual fpu lsx lasx
        crc32 complex crypto lspw lvz lbt_x86 lbt_arm lbt_mips
        Hardware Watchpoint     : yes, iwatch count: 8, dwatch count: 4

... while the CPUCFG 2 instruction reads "0x7e7ccfcf", whose bit 28 is 1,
indicating the actual presence of LAMCAS.

This hinders user-space inspection and detection of LAMCAS. For example,
in SpiderMonkey, we need to switch to larchintrin.h and raw __cpucfg()
to manually perform the bit extraction. Also, a curious user reading
/proc/cpuinfo might be puzzled by the lack (of display) of LAMCAS.

Expose the existence of LAMCAS via cpuinfo and hwcap. The definition
point of the new LOONGARCH_CPU_LAMCAS flag is chosen to match the
practices in commit 1dd3e8a8eeb4059fb34b07578362380cf35b7ed5 ("LoongArch:
Define instruction formats for AM{SWAP/ADD}.{B/H} and DBAR").

After this patch, /proc/cpuinfo looks like the following:

        processor               : 23
        package                 : 0
        core                    : 11
        global_id               : 31
        CPU Family              : Loongson-64bit
        Model Name              : Loongson-3B6000
        PRID                    : LA664 (0014d011)
        CPU Revision            : 0x11
        FPU Revision            : 0x01
        CPU MHz                 : 2200.00
        BogoMIPS                : 4400.00
        TLB Entries             : 2112
        Address Sizes           : 48 bits physical, 48 bits virtual
        ISA                     : loongarch32r loongarch32s loongarch64
        Features                : cpucfg lam lam_bh lamcas scq ual fpu lsx
        lasx crc32 complex crypto lspw lvz lbt_x86 lbt_arm lbt_mips
        Hardware Watchpoint     : yes, iwatch count: 8, dwatch count: 4

Note the addition of "lamcas" to the "Features" row.

Link: https://bugzil.la/2069431 ("[loong64] Use LA64v1.1 LAMCAS
 extension to simplify atomic cmpxchg operations")
Signed-off-by: Rong Bao <rong.bao@csmantle.top>
---
 arch/loongarch/include/asm/cpu-features.h |  1 +
 arch/loongarch/include/asm/cpu.h          | 64 ++++++++++++-----------
 arch/loongarch/include/uapi/asm/hwcap.h   |  1 +
 arch/loongarch/kernel/cpu-probe.c         |  4 ++
 arch/loongarch/kernel/proc.c              |  2 +
 5 files changed, 41 insertions(+), 31 deletions(-)

diff --git a/arch/loongarch/include/asm/cpu-features.h b/arch/loongarch/include/asm/cpu-features.h
index 62059c5551b9cdcc63c26033f8ccb44d63b18482..19cb0ccd0fb62bbbeb80a31bc447c101560bed32 100644
--- a/arch/loongarch/include/asm/cpu-features.h
+++ b/arch/loongarch/include/asm/cpu-features.h
@@ -36,6 +36,7 @@
 #define cpu_has_cpucfg		cpu_opt(LOONGARCH_CPU_CPUCFG)
 #define cpu_has_lam		cpu_opt(LOONGARCH_CPU_LAM)
 #define cpu_has_lam_bh		cpu_opt(LOONGARCH_CPU_LAM_BH)
+#define cpu_has_lamcas		cpu_opt(LOONGARCH_CPU_LAMCAS)
 #define cpu_has_scq		cpu_opt(LOONGARCH_CPU_SCQ)
 #define cpu_has_ual		cpu_opt(LOONGARCH_CPU_UAL)
 #define cpu_has_fpu		cpu_opt(LOONGARCH_CPU_FPU)
diff --git a/arch/loongarch/include/asm/cpu.h b/arch/loongarch/include/asm/cpu.h
index 91b96938861eb9f81882b128ab0bd0a925ce0dbb..334ca9d69ec4a649848133d0a81555bfc37fbf9d 100644
--- a/arch/loongarch/include/asm/cpu.h
+++ b/arch/loongarch/include/asm/cpu.h
@@ -96,41 +96,43 @@ static inline char *id_to_core_name(unsigned int id)
 #define CPU_FEATURE_CPUCFG		0	/* CPU has CPUCFG */
 #define CPU_FEATURE_LAM			1	/* CPU has Atomic instructions */
 #define CPU_FEATURE_LAM_BH		2	/* CPU has AM{SWAP/ADD}[_DB].{B/H} instructions */
-#define CPU_FEATURE_SCQ			3	/* CPU has SC.Q instruction */
-#define CPU_FEATURE_UAL			4	/* CPU supports unaligned access */
-#define CPU_FEATURE_FPU			5	/* CPU has FPU */
-#define CPU_FEATURE_LSX			6	/* CPU has LSX (128-bit SIMD) */
-#define CPU_FEATURE_LASX		7	/* CPU has LASX (256-bit SIMD) */
-#define CPU_FEATURE_CRC32		8	/* CPU has CRC32 instructions */
-#define CPU_FEATURE_COMPLEX		9	/* CPU has Complex instructions */
-#define CPU_FEATURE_CRYPTO		10	/* CPU has Crypto instructions */
-#define CPU_FEATURE_LVZ			11	/* CPU has Virtualization extension */
-#define CPU_FEATURE_LBT_X86		12	/* CPU has X86 Binary Translation */
-#define CPU_FEATURE_LBT_ARM		13	/* CPU has ARM Binary Translation */
-#define CPU_FEATURE_LBT_MIPS		14	/* CPU has MIPS Binary Translation */
-#define CPU_FEATURE_TLB			15	/* CPU has TLB */
-#define CPU_FEATURE_CSR			16	/* CPU has CSR */
-#define CPU_FEATURE_IOCSR		17	/* CPU has IOCSR */
-#define CPU_FEATURE_WATCH		18	/* CPU has watchpoint registers */
-#define CPU_FEATURE_VINT		19	/* CPU has vectored interrupts */
-#define CPU_FEATURE_CSRIPI		20	/* CPU has CSR-IPI */
-#define CPU_FEATURE_EXTIOI		21	/* CPU has EXT-IOI */
-#define CPU_FEATURE_PREFETCH		22	/* CPU has prefetch instructions */
-#define CPU_FEATURE_PMP			23	/* CPU has perfermance counter */
-#define CPU_FEATURE_SCALEFREQ		24	/* CPU supports cpufreq scaling */
-#define CPU_FEATURE_FLATMODE		25	/* CPU has flat mode */
-#define CPU_FEATURE_EIODECODE		26	/* CPU has EXTIOI interrupt pin decode mode */
-#define CPU_FEATURE_GUESTID		27	/* CPU has GuestID feature */
-#define CPU_FEATURE_HYPERVISOR		28	/* CPU has hypervisor (running in VM) */
-#define CPU_FEATURE_PTW			29	/* CPU has hardware page table walker */
-#define CPU_FEATURE_LSPW		30	/* CPU has LSPW (lddir/ldpte instructions) */
-#define CPU_FEATURE_MSGINT		31	/* CPU has MSG interrupt */
-#define CPU_FEATURE_AVECINT		32	/* CPU has AVEC interrupt */
-#define CPU_FEATURE_REDIRECTINT		33	/* CPU has interrupt remapping */
+#define CPU_FEATURE_LAMCAS		3	/* CPU has AMCAS[_DB].{B/H/W/D} instructions */
+#define CPU_FEATURE_SCQ			4	/* CPU has SC.Q instruction */
+#define CPU_FEATURE_UAL			5	/* CPU supports unaligned access */
+#define CPU_FEATURE_FPU			6	/* CPU has FPU */
+#define CPU_FEATURE_LSX			7	/* CPU has LSX (128-bit SIMD) */
+#define CPU_FEATURE_LASX		8	/* CPU has LASX (256-bit SIMD) */
+#define CPU_FEATURE_CRC32		9	/* CPU has CRC32 instructions */
+#define CPU_FEATURE_COMPLEX		10	/* CPU has Complex instructions */
+#define CPU_FEATURE_CRYPTO		11	/* CPU has Crypto instructions */
+#define CPU_FEATURE_LVZ			12	/* CPU has Virtualization extension */
+#define CPU_FEATURE_LBT_X86		13	/* CPU has X86 Binary Translation */
+#define CPU_FEATURE_LBT_ARM		14	/* CPU has ARM Binary Translation */
+#define CPU_FEATURE_LBT_MIPS		15	/* CPU has MIPS Binary Translation */
+#define CPU_FEATURE_TLB			16	/* CPU has TLB */
+#define CPU_FEATURE_CSR			17	/* CPU has CSR */
+#define CPU_FEATURE_IOCSR		18	/* CPU has IOCSR */
+#define CPU_FEATURE_WATCH		19	/* CPU has watchpoint registers */
+#define CPU_FEATURE_VINT		20	/* CPU has vectored interrupts */
+#define CPU_FEATURE_CSRIPI		21	/* CPU has CSR-IPI */
+#define CPU_FEATURE_EXTIOI		22	/* CPU has EXT-IOI */
+#define CPU_FEATURE_PREFETCH		23	/* CPU has prefetch instructions */
+#define CPU_FEATURE_PMP			24	/* CPU has perfermance counter */
+#define CPU_FEATURE_SCALEFREQ		25	/* CPU supports cpufreq scaling */
+#define CPU_FEATURE_FLATMODE		26	/* CPU has flat mode */
+#define CPU_FEATURE_EIODECODE		27	/* CPU has EXTIOI interrupt pin decode mode */
+#define CPU_FEATURE_GUESTID		28	/* CPU has GuestID feature */
+#define CPU_FEATURE_HYPERVISOR		29	/* CPU has hypervisor (running in VM) */
+#define CPU_FEATURE_PTW			30	/* CPU has hardware page table walker */
+#define CPU_FEATURE_LSPW		31	/* CPU has LSPW (lddir/ldpte instructions) */
+#define CPU_FEATURE_MSGINT		32	/* CPU has MSG interrupt */
+#define CPU_FEATURE_AVECINT		33	/* CPU has AVEC interrupt */
+#define CPU_FEATURE_REDIRECTINT		34	/* CPU has interrupt remapping */
 
 #define LOONGARCH_CPU_CPUCFG		BIT_ULL(CPU_FEATURE_CPUCFG)
 #define LOONGARCH_CPU_LAM		BIT_ULL(CPU_FEATURE_LAM)
 #define LOONGARCH_CPU_LAM_BH		BIT_ULL(CPU_FEATURE_LAM_BH)
+#define LOONGARCH_CPU_LAMCAS		BIT_ULL(CPU_FEATURE_LAMCAS)
 #define LOONGARCH_CPU_SCQ		BIT_ULL(CPU_FEATURE_SCQ)
 #define LOONGARCH_CPU_UAL		BIT_ULL(CPU_FEATURE_UAL)
 #define LOONGARCH_CPU_FPU		BIT_ULL(CPU_FEATURE_FPU)
diff --git a/arch/loongarch/include/uapi/asm/hwcap.h b/arch/loongarch/include/uapi/asm/hwcap.h
index 90e96113ba51003cd4dde5c7c79744f5e0755a03..d354787b937c3ae9eb8c3d58a4e7e96bd066f6fd 100644
--- a/arch/loongarch/include/uapi/asm/hwcap.h
+++ b/arch/loongarch/include/uapi/asm/hwcap.h
@@ -20,5 +20,6 @@
 #define HWCAP_LOONGARCH_LSPW		(1 << 14)
 #define HWCAP_LOONGARCH_SCQ		(1 << 15)
 #define HWCAP_LOONGARCH_LAM_BH		(1 << 16)
+#define HWCAP_LOONGARCH_LAMCAS		(1 << 17)
 
 #endif /* _UAPI_ASM_HWCAP_H */
diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
index 74d31f260dfd889e66a1f55c5bcc47a3657d101f..93176e4d017b4d8fc82c817a7064af0656133c15 100644
--- a/arch/loongarch/kernel/cpu-probe.c
+++ b/arch/loongarch/kernel/cpu-probe.c
@@ -182,6 +182,10 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
 		c->options |= LOONGARCH_CPU_LAM_BH;
 		elf_hwcap |= HWCAP_LOONGARCH_LAM_BH;
 	}
+	if (config & CPUCFG2_LAMCAS) {
+		c->options |= LOONGARCH_CPU_LAMCAS;
+		elf_hwcap |= HWCAP_LOONGARCH_LAMCAS;
+	}
 	if (config & CPUCFG2_SCQ) {
 		c->options |= LOONGARCH_CPU_SCQ;
 		elf_hwcap |= HWCAP_LOONGARCH_SCQ;
diff --git a/arch/loongarch/kernel/proc.c b/arch/loongarch/kernel/proc.c
index d4ce5b585453700caf2187c3dcc8f4f3cc8a9226..f86be83ad6f134c5793667fa6dbe2bf82fd58a2e 100644
--- a/arch/loongarch/kernel/proc.c
+++ b/arch/loongarch/kernel/proc.c
@@ -66,6 +66,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 		seq_puts(m, " lam");
 	if (cpu_has_lam_bh)
 		seq_puts(m, " lam_bh");
+	if (cpu_has_lamcas)
+		seq_puts(m, " lamcas");
 	if (cpu_has_scq)
 		seq_puts(m, " scq");
 	if (cpu_has_ual)

base-commit: 654ae5d73c05bd2943d65636ce6cd0aa46e62f18
-- 
2.55.0
Re: [PATCH] loongarch: expose LAMCAS existence via cpuinfo and hwcap
Posted by Huacai Chen 2 weeks, 6 days ago
Hi, Rong,

On Sat, Sep 5, 2026 at 11:21 AM Rong Bao <rong.bao@csmantle.top> wrote:
>
> Currently, neither /proc/cpuinfo nor hwcap exposes the existence of the
> LAMCAS extension, which is part of LA64v1.1. For example, on a Loongson
> 3B6000, /proc/cpuinfo is as follows:
>
>         processor               : 23
>         package                 : 0
>         core                    : 11
>         global_id               : 31
>         CPU Family              : Loongson-64bit
>         Model Name              : Loongson-3B6000
>         PRID                    : LA664 (0014d011)
>         CPU Revision            : 0x11
>         FPU Revision            : 0x01
>         CPU MHz                 : 2200.00
>         BogoMIPS                : 4400.00
>         TLB Entries             : 2112
>         Address Sizes           : 48 bits physical, 48 bits virtual
>         ISA                     : loongarch32r loongarch32s loongarch64
>         Features                : cpucfg lam lam_bh scq ual fpu lsx lasx
>         crc32 complex crypto lspw lvz lbt_x86 lbt_arm lbt_mips
>         Hardware Watchpoint     : yes, iwatch count: 8, dwatch count: 4
>
> ... while the CPUCFG 2 instruction reads "0x7e7ccfcf", whose bit 28 is 1,
> indicating the actual presence of LAMCAS.
Can we use LAM_CAS in the code, which is similar to LAM_BH? And please
use LoongArch in the subject.

Huacai

>
> This hinders user-space inspection and detection of LAMCAS. For example,
> in SpiderMonkey, we need to switch to larchintrin.h and raw __cpucfg()
> to manually perform the bit extraction. Also, a curious user reading
> /proc/cpuinfo might be puzzled by the lack (of display) of LAMCAS.
>
> Expose the existence of LAMCAS via cpuinfo and hwcap. The definition
> point of the new LOONGARCH_CPU_LAMCAS flag is chosen to match the
> practices in commit 1dd3e8a8eeb4059fb34b07578362380cf35b7ed5 ("LoongArch:
> Define instruction formats for AM{SWAP/ADD}.{B/H} and DBAR").
>
> After this patch, /proc/cpuinfo looks like the following:
>
>         processor               : 23
>         package                 : 0
>         core                    : 11
>         global_id               : 31
>         CPU Family              : Loongson-64bit
>         Model Name              : Loongson-3B6000
>         PRID                    : LA664 (0014d011)
>         CPU Revision            : 0x11
>         FPU Revision            : 0x01
>         CPU MHz                 : 2200.00
>         BogoMIPS                : 4400.00
>         TLB Entries             : 2112
>         Address Sizes           : 48 bits physical, 48 bits virtual
>         ISA                     : loongarch32r loongarch32s loongarch64
>         Features                : cpucfg lam lam_bh lamcas scq ual fpu lsx
>         lasx crc32 complex crypto lspw lvz lbt_x86 lbt_arm lbt_mips
>         Hardware Watchpoint     : yes, iwatch count: 8, dwatch count: 4
>
> Note the addition of "lamcas" to the "Features" row.
>
> Link: https://bugzil.la/2069431 ("[loong64] Use LA64v1.1 LAMCAS
>  extension to simplify atomic cmpxchg operations")
> Signed-off-by: Rong Bao <rong.bao@csmantle.top>
> ---
>  arch/loongarch/include/asm/cpu-features.h |  1 +
>  arch/loongarch/include/asm/cpu.h          | 64 ++++++++++++-----------
>  arch/loongarch/include/uapi/asm/hwcap.h   |  1 +
>  arch/loongarch/kernel/cpu-probe.c         |  4 ++
>  arch/loongarch/kernel/proc.c              |  2 +
>  5 files changed, 41 insertions(+), 31 deletions(-)
>
> diff --git a/arch/loongarch/include/asm/cpu-features.h b/arch/loongarch/include/asm/cpu-features.h
> index 62059c5551b9cdcc63c26033f8ccb44d63b18482..19cb0ccd0fb62bbbeb80a31bc447c101560bed32 100644
> --- a/arch/loongarch/include/asm/cpu-features.h
> +++ b/arch/loongarch/include/asm/cpu-features.h
> @@ -36,6 +36,7 @@
>  #define cpu_has_cpucfg         cpu_opt(LOONGARCH_CPU_CPUCFG)
>  #define cpu_has_lam            cpu_opt(LOONGARCH_CPU_LAM)
>  #define cpu_has_lam_bh         cpu_opt(LOONGARCH_CPU_LAM_BH)
> +#define cpu_has_lamcas         cpu_opt(LOONGARCH_CPU_LAMCAS)
>  #define cpu_has_scq            cpu_opt(LOONGARCH_CPU_SCQ)
>  #define cpu_has_ual            cpu_opt(LOONGARCH_CPU_UAL)
>  #define cpu_has_fpu            cpu_opt(LOONGARCH_CPU_FPU)
> diff --git a/arch/loongarch/include/asm/cpu.h b/arch/loongarch/include/asm/cpu.h
> index 91b96938861eb9f81882b128ab0bd0a925ce0dbb..334ca9d69ec4a649848133d0a81555bfc37fbf9d 100644
> --- a/arch/loongarch/include/asm/cpu.h
> +++ b/arch/loongarch/include/asm/cpu.h
> @@ -96,41 +96,43 @@ static inline char *id_to_core_name(unsigned int id)
>  #define CPU_FEATURE_CPUCFG             0       /* CPU has CPUCFG */
>  #define CPU_FEATURE_LAM                        1       /* CPU has Atomic instructions */
>  #define CPU_FEATURE_LAM_BH             2       /* CPU has AM{SWAP/ADD}[_DB].{B/H} instructions */
> -#define CPU_FEATURE_SCQ                        3       /* CPU has SC.Q instruction */
> -#define CPU_FEATURE_UAL                        4       /* CPU supports unaligned access */
> -#define CPU_FEATURE_FPU                        5       /* CPU has FPU */
> -#define CPU_FEATURE_LSX                        6       /* CPU has LSX (128-bit SIMD) */
> -#define CPU_FEATURE_LASX               7       /* CPU has LASX (256-bit SIMD) */
> -#define CPU_FEATURE_CRC32              8       /* CPU has CRC32 instructions */
> -#define CPU_FEATURE_COMPLEX            9       /* CPU has Complex instructions */
> -#define CPU_FEATURE_CRYPTO             10      /* CPU has Crypto instructions */
> -#define CPU_FEATURE_LVZ                        11      /* CPU has Virtualization extension */
> -#define CPU_FEATURE_LBT_X86            12      /* CPU has X86 Binary Translation */
> -#define CPU_FEATURE_LBT_ARM            13      /* CPU has ARM Binary Translation */
> -#define CPU_FEATURE_LBT_MIPS           14      /* CPU has MIPS Binary Translation */
> -#define CPU_FEATURE_TLB                        15      /* CPU has TLB */
> -#define CPU_FEATURE_CSR                        16      /* CPU has CSR */
> -#define CPU_FEATURE_IOCSR              17      /* CPU has IOCSR */
> -#define CPU_FEATURE_WATCH              18      /* CPU has watchpoint registers */
> -#define CPU_FEATURE_VINT               19      /* CPU has vectored interrupts */
> -#define CPU_FEATURE_CSRIPI             20      /* CPU has CSR-IPI */
> -#define CPU_FEATURE_EXTIOI             21      /* CPU has EXT-IOI */
> -#define CPU_FEATURE_PREFETCH           22      /* CPU has prefetch instructions */
> -#define CPU_FEATURE_PMP                        23      /* CPU has perfermance counter */
> -#define CPU_FEATURE_SCALEFREQ          24      /* CPU supports cpufreq scaling */
> -#define CPU_FEATURE_FLATMODE           25      /* CPU has flat mode */
> -#define CPU_FEATURE_EIODECODE          26      /* CPU has EXTIOI interrupt pin decode mode */
> -#define CPU_FEATURE_GUESTID            27      /* CPU has GuestID feature */
> -#define CPU_FEATURE_HYPERVISOR         28      /* CPU has hypervisor (running in VM) */
> -#define CPU_FEATURE_PTW                        29      /* CPU has hardware page table walker */
> -#define CPU_FEATURE_LSPW               30      /* CPU has LSPW (lddir/ldpte instructions) */
> -#define CPU_FEATURE_MSGINT             31      /* CPU has MSG interrupt */
> -#define CPU_FEATURE_AVECINT            32      /* CPU has AVEC interrupt */
> -#define CPU_FEATURE_REDIRECTINT                33      /* CPU has interrupt remapping */
> +#define CPU_FEATURE_LAMCAS             3       /* CPU has AMCAS[_DB].{B/H/W/D} instructions */
> +#define CPU_FEATURE_SCQ                        4       /* CPU has SC.Q instruction */
> +#define CPU_FEATURE_UAL                        5       /* CPU supports unaligned access */
> +#define CPU_FEATURE_FPU                        6       /* CPU has FPU */
> +#define CPU_FEATURE_LSX                        7       /* CPU has LSX (128-bit SIMD) */
> +#define CPU_FEATURE_LASX               8       /* CPU has LASX (256-bit SIMD) */
> +#define CPU_FEATURE_CRC32              9       /* CPU has CRC32 instructions */
> +#define CPU_FEATURE_COMPLEX            10      /* CPU has Complex instructions */
> +#define CPU_FEATURE_CRYPTO             11      /* CPU has Crypto instructions */
> +#define CPU_FEATURE_LVZ                        12      /* CPU has Virtualization extension */
> +#define CPU_FEATURE_LBT_X86            13      /* CPU has X86 Binary Translation */
> +#define CPU_FEATURE_LBT_ARM            14      /* CPU has ARM Binary Translation */
> +#define CPU_FEATURE_LBT_MIPS           15      /* CPU has MIPS Binary Translation */
> +#define CPU_FEATURE_TLB                        16      /* CPU has TLB */
> +#define CPU_FEATURE_CSR                        17      /* CPU has CSR */
> +#define CPU_FEATURE_IOCSR              18      /* CPU has IOCSR */
> +#define CPU_FEATURE_WATCH              19      /* CPU has watchpoint registers */
> +#define CPU_FEATURE_VINT               20      /* CPU has vectored interrupts */
> +#define CPU_FEATURE_CSRIPI             21      /* CPU has CSR-IPI */
> +#define CPU_FEATURE_EXTIOI             22      /* CPU has EXT-IOI */
> +#define CPU_FEATURE_PREFETCH           23      /* CPU has prefetch instructions */
> +#define CPU_FEATURE_PMP                        24      /* CPU has perfermance counter */
> +#define CPU_FEATURE_SCALEFREQ          25      /* CPU supports cpufreq scaling */
> +#define CPU_FEATURE_FLATMODE           26      /* CPU has flat mode */
> +#define CPU_FEATURE_EIODECODE          27      /* CPU has EXTIOI interrupt pin decode mode */
> +#define CPU_FEATURE_GUESTID            28      /* CPU has GuestID feature */
> +#define CPU_FEATURE_HYPERVISOR         29      /* CPU has hypervisor (running in VM) */
> +#define CPU_FEATURE_PTW                        30      /* CPU has hardware page table walker */
> +#define CPU_FEATURE_LSPW               31      /* CPU has LSPW (lddir/ldpte instructions) */
> +#define CPU_FEATURE_MSGINT             32      /* CPU has MSG interrupt */
> +#define CPU_FEATURE_AVECINT            33      /* CPU has AVEC interrupt */
> +#define CPU_FEATURE_REDIRECTINT                34      /* CPU has interrupt remapping */
>
>  #define LOONGARCH_CPU_CPUCFG           BIT_ULL(CPU_FEATURE_CPUCFG)
>  #define LOONGARCH_CPU_LAM              BIT_ULL(CPU_FEATURE_LAM)
>  #define LOONGARCH_CPU_LAM_BH           BIT_ULL(CPU_FEATURE_LAM_BH)
> +#define LOONGARCH_CPU_LAMCAS           BIT_ULL(CPU_FEATURE_LAMCAS)
>  #define LOONGARCH_CPU_SCQ              BIT_ULL(CPU_FEATURE_SCQ)
>  #define LOONGARCH_CPU_UAL              BIT_ULL(CPU_FEATURE_UAL)
>  #define LOONGARCH_CPU_FPU              BIT_ULL(CPU_FEATURE_FPU)
> diff --git a/arch/loongarch/include/uapi/asm/hwcap.h b/arch/loongarch/include/uapi/asm/hwcap.h
> index 90e96113ba51003cd4dde5c7c79744f5e0755a03..d354787b937c3ae9eb8c3d58a4e7e96bd066f6fd 100644
> --- a/arch/loongarch/include/uapi/asm/hwcap.h
> +++ b/arch/loongarch/include/uapi/asm/hwcap.h
> @@ -20,5 +20,6 @@
>  #define HWCAP_LOONGARCH_LSPW           (1 << 14)
>  #define HWCAP_LOONGARCH_SCQ            (1 << 15)
>  #define HWCAP_LOONGARCH_LAM_BH         (1 << 16)
> +#define HWCAP_LOONGARCH_LAMCAS         (1 << 17)
>
>  #endif /* _UAPI_ASM_HWCAP_H */
> diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
> index 74d31f260dfd889e66a1f55c5bcc47a3657d101f..93176e4d017b4d8fc82c817a7064af0656133c15 100644
> --- a/arch/loongarch/kernel/cpu-probe.c
> +++ b/arch/loongarch/kernel/cpu-probe.c
> @@ -182,6 +182,10 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
>                 c->options |= LOONGARCH_CPU_LAM_BH;
>                 elf_hwcap |= HWCAP_LOONGARCH_LAM_BH;
>         }
> +       if (config & CPUCFG2_LAMCAS) {
> +               c->options |= LOONGARCH_CPU_LAMCAS;
> +               elf_hwcap |= HWCAP_LOONGARCH_LAMCAS;
> +       }
>         if (config & CPUCFG2_SCQ) {
>                 c->options |= LOONGARCH_CPU_SCQ;
>                 elf_hwcap |= HWCAP_LOONGARCH_SCQ;
> diff --git a/arch/loongarch/kernel/proc.c b/arch/loongarch/kernel/proc.c
> index d4ce5b585453700caf2187c3dcc8f4f3cc8a9226..f86be83ad6f134c5793667fa6dbe2bf82fd58a2e 100644
> --- a/arch/loongarch/kernel/proc.c
> +++ b/arch/loongarch/kernel/proc.c
> @@ -66,6 +66,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
>                 seq_puts(m, " lam");
>         if (cpu_has_lam_bh)
>                 seq_puts(m, " lam_bh");
> +       if (cpu_has_lamcas)
> +               seq_puts(m, " lamcas");
>         if (cpu_has_scq)
>                 seq_puts(m, " scq");
>         if (cpu_has_ual)
>
> base-commit: 654ae5d73c05bd2943d65636ce6cd0aa46e62f18
> --
> 2.55.0
>
Re: [PATCH] loongarch: expose LAMCAS existence via cpuinfo and hwcap
Posted by Rong Bao 2 weeks, 6 days ago
Hi Huacai,


On 2026-09-05 12:46, Huacai Chen wrote:
> [...]
>>          Features                : cpucfg lam lam_bh scq ual fpu lsx lasx
>>          crc32 complex crypto lspw lvz lbt_x86 lbt_arm lbt_mips
>>          Hardware Watchpoint     : yes, iwatch count: 8, dwatch count: 4
>>
>> ... while the CPUCFG 2 instruction reads "0x7e7ccfcf", whose bit 28 is 1,
>> indicating the actual presence of LAMCAS.
> Can we use LAM_CAS in the code, which is similar to LAM_BH?


I originally chose "LAMCAS" and not "LAM_CAS" deliberately to match the 
manual spelling. For example, in "LoongArch Reference Manual, Volume 1 
(version 1.10)"[^0], Table 3 reads as follows:

 > 27	LAM_BH	1 indicates support AM{SWAP/ADD}[_DB].{B/H}.
 > 28	LAMCAS	1 indicates support AMCAS[_DB].{B/H/W/D}.

Also, in "Toolchain Conventions of the LoongArch(tm) Architecture, 
Version 1.2"[^1], these two extensions are also stylized with different 
hyphenation:

 > -mlam-bh	-m[no-]lam-bh	Enable atomic operations 
am{swap/add}[_db].{b/h}.	LoongArch V1.1
 > -mlamcas	-m[no-]lamcas	Enable atomic compare-and-swap instructions 
amcas[_db].{b/h/w/d}.	LoongArch V1.1

So I think the name "LAMCAS" maintains the consistency with existing 
specifications and literature better than "LAM_CAS".

> [...] And please use LoongArch in the subject.


Sure. I will fix this in v2.


[^0]: 
https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#the-configuration-information-accessible-by-the-cpucfg-instruction
[^1]: 
https://github.com/loongson/la-toolchain-conventions/blob/36d207cd76301618624d10e67daf7b7f1c060411/LoongArch-toolchain-conventions-EN.adoc?plain=1#L176-L184

-- 
Regards,
Rong Bao
Re: [PATCH] loongarch: expose LAMCAS existence via cpuinfo and hwcap
Posted by Xi Ruoyao 2 weeks, 6 days ago
On Sat, 2026-09-05 at 12:58 +0800, Rong Bao wrote:
> Hi Huacai,
> 
> 
> On 2026-09-05 12:46, Huacai Chen wrote:
> > [...]
> > >          Features                : cpucfg lam lam_bh scq ual fpu lsx lasx
> > >          crc32 complex crypto lspw lvz lbt_x86 lbt_arm lbt_mips
> > >          Hardware Watchpoint     : yes, iwatch count: 8, dwatch count: 4
> > > 
> > > ... while the CPUCFG 2 instruction reads "0x7e7ccfcf", whose bit 28 is 1,
> > > indicating the actual presence of LAMCAS.
> > Can we use LAM_CAS in the code, which is similar to LAM_BH?
> 
> 
> I originally chose "LAMCAS" and not "LAM_CAS" deliberately to match the 
> manual spelling. For example, in "LoongArch Reference Manual, Volume 1
> (version 1.10)"[^0], Table 3 reads as follows:
> 
>  > 27	LAM_BH	1 indicates support AM{SWAP/ADD}[_DB].{B/H}.
>  > 28	LAMCAS	1 indicates support AMCAS[_DB].{B/H/W/D}.
> 
> Also, in "Toolchain Conventions of the LoongArch(tm) Architecture, 
> Version 1.2"[^1], these two extensions are also stylized with different 
> hyphenation:
> 
>  > -mlam-bh	-m[no-]lam-bh	Enable atomic operations 
> am{swap/add}[_db].{b/h}.	LoongArch V1.1
>  > -mlamcas	-m[no-]lamcas	Enable atomic compare-and-swap instructions 
> amcas[_db].{b/h/w/d}.	LoongArch V1.1

I wrote them for GCC and I just verbatim copied the identifiers from the
reference manual.

But IIRC we've once discussed this and concluded that the user space
should just use cpucfg unless the feature requires kernel support (i.e.
LSX, LASX, and LBT must be checked via HWCAP instead of cpucfg as they
require the kernel to enable the hardware unit and manage the context
switch)?

Maybe using HWCAP instead of cpucfg can be useful as well when the
kernel can detect a hardware/firmware bug and remove the corresponding
bit from HWCAP, but the previous discussion about buggy LA364E firmware
implementation (causing sc.q semantic error) concluded that the kernel
will be very unlikely to ship such a work around.  And AFAIK there's no
such a bug reported for LAMCAS ever...

-- 
Xi Ruoyao <xry111@xry111.site>