* [PATCH v3 0/6] Enable strict percpu address space checks
@ 2024-12-08 20:45 Uros Bizjak
2024-12-08 20:45 ` [PATCH v3 1/6] x86/kgdb: Use IS_ERR_PCPU() macro Uros Bizjak
` (7 more replies)
0 siblings, 8 replies; 14+ messages in thread
From: Uros Bizjak @ 2024-12-08 20:45 UTC (permalink / raw)
To: x86, linux-mm, linux-kernel, linux-bcachefs, linux-arch, netdev
Cc: Uros Bizjak, Thomas Gleixner, Dennis Zhou, Tejun Heo,
Christoph Lameter, Linus Torvalds, Andy Lutomirski, Ingo Molnar,
Nadav Amit, Brian Gerst, Dan Carpenter, H . Peter Anvin,
Peter Zijlstra
Enable strict percpu address space checks via x86 named address space
qualifiers. Percpu variables are declared in __seg_gs/__seg_fs named
AS and kept named AS qualified until they are dereferenced via percpu
accessor. This approach enables various compiler checks for
cross-namespace variable assignments.
Please note that current version of sparse doesn't know anything about
__typeof_unqual__() operator. Avoid the usage of __typeof_unqual__()
when sparse checking is active to prevent sparse errors with unknowing
keyword. The proposed patch by Dan Carpenter to implement
__typeof_unqual__() handling in sparse is located at:
https://lore.kernel.org/lkml/5b8d0dee-8fb6-45af-ba6c-7f74aff9a4b8@stanley.mountain/
v2: - Add comment to remove test for __CHECKER__ once sparse learns
about __typeof_unqual__.
- Add Acked-by: tags.
v3: - Rename __per_cpu_qual to __percpu_qual.
- Add more Acked-by: tags.
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Christoph Lameter <cl@linux.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Nadav Amit <nadav.amit@gmail.com>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dan Carpenter <dan.carpenter@linaro.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Uros Bizjak (6):
x86/kgdb: Use IS_ERR_PCPU() macro
compiler.h: Introduce TYPEOF_UNQUAL() macro
percpu: Use TYPEOF_UNQUAL() in variable declarations
percpu: Use TYPEOF_UNQUAL() in *_cpu_ptr() accessors
percpu: Repurpose __percpu tag as a named address space qualifier
percpu/x86: Enable strict percpu checks via named AS qualifiers
arch/x86/include/asm/percpu.h | 38 ++++++++++++++++++++++++---------
arch/x86/kernel/kgdb.c | 2 +-
fs/bcachefs/util.h | 2 +-
include/asm-generic/percpu.h | 39 ++++++++++++++++++++++------------
include/linux/compiler.h | 13 ++++++++++++
include/linux/compiler_types.h | 2 +-
include/linux/part_stat.h | 2 +-
include/linux/percpu-defs.h | 6 +++---
include/net/snmp.h | 5 ++---
init/Kconfig | 3 +++
kernel/locking/percpu-rwsem.c | 2 +-
net/mpls/internal.h | 4 ++--
12 files changed, 82 insertions(+), 36 deletions(-)
--
2.42.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v3 1/6] x86/kgdb: Use IS_ERR_PCPU() macro
2024-12-08 20:45 [PATCH v3 0/6] Enable strict percpu address space checks Uros Bizjak
@ 2024-12-08 20:45 ` Uros Bizjak
2024-12-08 20:45 ` [PATCH v3 2/6] compiler.h: Introduce TYPEOF_UNQUAL() macro Uros Bizjak
` (6 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Uros Bizjak @ 2024-12-08 20:45 UTC (permalink / raw)
To: x86, linux-mm, linux-kernel, linux-bcachefs, linux-arch, netdev
Cc: Uros Bizjak, Nadav Amit, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, Dennis Zhou,
Tejun Heo, Christoph Lameter, Linus Torvalds, Andy Lutomirski,
Brian Gerst, Peter Zijlstra
Use IS_ERR_PCPU() when checking the error pointer in the percpu
address space. This macro adds intermediate cast to unsigned long
when switching named address spaces.
The patch will avoid future build errors due to pointer address space
mismatch with enabled strict percpu address space checks.
Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Acked-by: Nadav Amit <nadav.amit@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Christoph Lameter <cl@linux.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
---
arch/x86/kernel/kgdb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index 9c9faa1634fb..102641fd2172 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -655,7 +655,7 @@ void kgdb_arch_late(void)
if (breakinfo[i].pev)
continue;
breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL, NULL);
- if (IS_ERR((void * __force)breakinfo[i].pev)) {
+ if (IS_ERR_PCPU(breakinfo[i].pev)) {
printk(KERN_ERR "kgdb: Could not allocate hw"
"breakpoints\nDisabling the kernel debugger\n");
breakinfo[i].pev = NULL;
--
2.42.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v3 2/6] compiler.h: Introduce TYPEOF_UNQUAL() macro
2024-12-08 20:45 [PATCH v3 0/6] Enable strict percpu address space checks Uros Bizjak
2024-12-08 20:45 ` [PATCH v3 1/6] x86/kgdb: Use IS_ERR_PCPU() macro Uros Bizjak
@ 2024-12-08 20:45 ` Uros Bizjak
2024-12-09 11:30 ` Peter Zijlstra
2024-12-08 20:45 ` [PATCH v3 3/6] percpu: Use TYPEOF_UNQUAL() in variable declarations Uros Bizjak
` (5 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Uros Bizjak @ 2024-12-08 20:45 UTC (permalink / raw)
To: x86, linux-mm, linux-kernel, linux-bcachefs, linux-arch, netdev
Cc: Uros Bizjak, Nadav Amit, Thomas Gleixner, Dennis Zhou, Tejun Heo,
Christoph Lameter, Linus Torvalds, Andy Lutomirski, Ingo Molnar,
Brian Gerst, Denys Vlasenko, H. Peter Anvin
Define TYPEOF_UNQUAL() to use __typeof_unqual__() as typeof operator
when available, to return unqualified type of the expression.
Current version of sparse doesn't know anything about __typeof_unqual__()
operator. Avoid the usage of __typeof_unqual__() when sparse checking
is active to prevent sparse errors with unknowing keyword.
Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Acked-by: Nadav Amit <nadav.amit@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Christoph Lameter <cl@linux.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Peter Zijlstra <peterz@infradead.org
---
include/linux/compiler.h | 13 +++++++++++++
init/Kconfig | 3 +++
2 files changed, 16 insertions(+)
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 469a64dd6495..ec0429d7a153 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -321,6 +321,19 @@ static inline void *offset_to_ptr(const int *off)
*/
#define prevent_tail_call_optimization() mb()
+/*
+ * Define TYPEOF_UNQUAL() to use __typeof_unqual__() as typeof
+ * operator when available, to return unqualified type of the exp.
+ *
+ * XXX: Remove test for __CHECKER__ once
+ * sparse learns about __typeof_unqual__.
+ */
+#if defined(CONFIG_CC_HAS_TYPEOF_UNQUAL) && !defined(__CHECKER__)
+# define TYPEOF_UNQUAL(exp) __typeof_unqual__(exp)
+#else
+# define TYPEOF_UNQUAL(exp) __typeof__(exp)
+#endif
+
#include <asm/rwonce.h>
#endif /* __LINUX_COMPILER_H */
diff --git a/init/Kconfig b/init/Kconfig
index a20e6efd3f0f..c1f9eb3d5f2e 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -894,6 +894,9 @@ config ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
config CC_HAS_INT128
def_bool !$(cc-option,$(m64-flag) -D__SIZEOF_INT128__=0) && 64BIT
+config CC_HAS_TYPEOF_UNQUAL
+ def_bool $(success,echo 'int foo (int a) { __typeof_unqual__(a) b = a; return b; }' | $(CC) -x c - -S -o /dev/null)
+
config CC_IMPLICIT_FALLTHROUGH
string
default "-Wimplicit-fallthrough=5" if CC_IS_GCC && $(cc-option,-Wimplicit-fallthrough=5)
--
2.42.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v3 3/6] percpu: Use TYPEOF_UNQUAL() in variable declarations
2024-12-08 20:45 [PATCH v3 0/6] Enable strict percpu address space checks Uros Bizjak
2024-12-08 20:45 ` [PATCH v3 1/6] x86/kgdb: Use IS_ERR_PCPU() macro Uros Bizjak
2024-12-08 20:45 ` [PATCH v3 2/6] compiler.h: Introduce TYPEOF_UNQUAL() macro Uros Bizjak
@ 2024-12-08 20:45 ` Uros Bizjak
2024-12-08 20:45 ` [PATCH v3 4/6] percpu: Use TYPEOF_UNQUAL() in *_cpu_ptr() accessors Uros Bizjak
` (4 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Uros Bizjak @ 2024-12-08 20:45 UTC (permalink / raw)
To: x86, linux-mm, linux-kernel, linux-bcachefs, linux-arch, netdev
Cc: Uros Bizjak, Nadav Amit, Christoph Lameter, Dennis Zhou,
Tejun Heo, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, H. Peter Anvin, Kent Overstreet,
Arnd Bergmann, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Peter Zijlstra, Will Deacon, Waiman Long,
Boqun Feng, Linus Torvalds, Brian Gerst
Use TYPEOF_UNQUAL() to declare variables as a corresponding
type without named address space qualifier to avoid
"‘__seg_gs’ specified for auto variable ‘var’" errors.
Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Acked-by: Nadav Amit <nadav.amit@gmail.com>
Acked-by: Christoph Lameter <cl@linux.com>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Kent Overstreet <kent.overstreet@linux.dev>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Brian Gerst <brgerst@gmail.com>
---
arch/x86/include/asm/percpu.h | 10 +++++-----
fs/bcachefs/util.h | 2 +-
include/asm-generic/percpu.h | 26 +++++++++++++-------------
include/linux/part_stat.h | 2 +-
include/linux/percpu-defs.h | 4 ++--
include/net/snmp.h | 5 ++---
kernel/locking/percpu-rwsem.c | 2 +-
net/mpls/internal.h | 4 ++--
8 files changed, 27 insertions(+), 28 deletions(-)
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index e525cd85f999..666e4137b09f 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -180,7 +180,7 @@ do { \
__pcpu_type_##size pto_val__ = __pcpu_cast_##size(_val); \
\
if (0) { \
- typeof(_var) pto_tmp__; \
+ TYPEOF_UNQUAL(_var) pto_tmp__; \
pto_tmp__ = (_val); \
(void)pto_tmp__; \
} \
@@ -219,7 +219,7 @@ do { \
__pcpu_type_##size pto_val__ = __pcpu_cast_##size(_val); \
\
if (0) { \
- typeof(_var) pto_tmp__; \
+ TYPEOF_UNQUAL(_var) pto_tmp__; \
pto_tmp__ = (_val); \
(void)pto_tmp__; \
} \
@@ -240,7 +240,7 @@ do { \
(val) == (typeof(val))-1)) ? (int)(val) : 0; \
\
if (0) { \
- typeof(var) pao_tmp__; \
+ TYPEOF_UNQUAL(var) pao_tmp__; \
pao_tmp__ = (val); \
(void)pao_tmp__; \
} \
@@ -273,7 +273,7 @@ do { \
*/
#define raw_percpu_xchg_op(_var, _nval) \
({ \
- typeof(_var) pxo_old__ = raw_cpu_read(_var); \
+ TYPEOF_UNQUAL(_var) pxo_old__ = raw_cpu_read(_var); \
\
raw_cpu_write(_var, _nval); \
\
@@ -287,7 +287,7 @@ do { \
*/
#define this_percpu_xchg_op(_var, _nval) \
({ \
- typeof(_var) pxo_old__ = this_cpu_read(_var); \
+ TYPEOF_UNQUAL(_var) pxo_old__ = this_cpu_read(_var); \
\
do { } while (!this_cpu_try_cmpxchg(_var, &pxo_old__, _nval)); \
\
diff --git a/fs/bcachefs/util.h b/fs/bcachefs/util.h
index fb02c1c36004..415a5803b8f4 100644
--- a/fs/bcachefs/util.h
+++ b/fs/bcachefs/util.h
@@ -586,7 +586,7 @@ do { \
#define per_cpu_sum(_p) \
({ \
- typeof(*_p) _ret = 0; \
+ TYPEOF_UNQUAL(*_p) _ret = 0; \
\
int cpu; \
for_each_possible_cpu(cpu) \
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
index 94cbd50cc870..50597b975a49 100644
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -74,7 +74,7 @@ do { \
#define raw_cpu_generic_add_return(pcp, val) \
({ \
- typeof(pcp) *__p = raw_cpu_ptr(&(pcp)); \
+ TYPEOF_UNQUAL(pcp) *__p = raw_cpu_ptr(&(pcp)); \
\
*__p += val; \
*__p; \
@@ -82,8 +82,8 @@ do { \
#define raw_cpu_generic_xchg(pcp, nval) \
({ \
- typeof(pcp) *__p = raw_cpu_ptr(&(pcp)); \
- typeof(pcp) __ret; \
+ TYPEOF_UNQUAL(pcp) *__p = raw_cpu_ptr(&(pcp)); \
+ TYPEOF_UNQUAL(pcp) __ret; \
__ret = *__p; \
*__p = nval; \
__ret; \
@@ -91,7 +91,7 @@ do { \
#define __cpu_fallback_try_cmpxchg(pcp, ovalp, nval, _cmpxchg) \
({ \
- typeof(pcp) __val, __old = *(ovalp); \
+ TYPEOF_UNQUAL(pcp) __val, __old = *(ovalp); \
__val = _cmpxchg(pcp, __old, nval); \
if (__val != __old) \
*(ovalp) = __val; \
@@ -100,8 +100,8 @@ do { \
#define raw_cpu_generic_try_cmpxchg(pcp, ovalp, nval) \
({ \
- typeof(pcp) *__p = raw_cpu_ptr(&(pcp)); \
- typeof(pcp) __val = *__p, ___old = *(ovalp); \
+ TYPEOF_UNQUAL(pcp) *__p = raw_cpu_ptr(&(pcp)); \
+ TYPEOF_UNQUAL(pcp) __val = *__p, ___old = *(ovalp); \
bool __ret; \
if (__val == ___old) { \
*__p = nval; \
@@ -115,14 +115,14 @@ do { \
#define raw_cpu_generic_cmpxchg(pcp, oval, nval) \
({ \
- typeof(pcp) __old = (oval); \
+ TYPEOF_UNQUAL(pcp) __old = (oval); \
raw_cpu_generic_try_cmpxchg(pcp, &__old, nval); \
__old; \
})
#define __this_cpu_generic_read_nopreempt(pcp) \
({ \
- typeof(pcp) ___ret; \
+ TYPEOF_UNQUAL(pcp) ___ret; \
preempt_disable_notrace(); \
___ret = READ_ONCE(*raw_cpu_ptr(&(pcp))); \
preempt_enable_notrace(); \
@@ -131,7 +131,7 @@ do { \
#define __this_cpu_generic_read_noirq(pcp) \
({ \
- typeof(pcp) ___ret; \
+ TYPEOF_UNQUAL(pcp) ___ret; \
unsigned long ___flags; \
raw_local_irq_save(___flags); \
___ret = raw_cpu_generic_read(pcp); \
@@ -141,7 +141,7 @@ do { \
#define this_cpu_generic_read(pcp) \
({ \
- typeof(pcp) __ret; \
+ TYPEOF_UNQUAL(pcp) __ret; \
if (__native_word(pcp)) \
__ret = __this_cpu_generic_read_nopreempt(pcp); \
else \
@@ -160,7 +160,7 @@ do { \
#define this_cpu_generic_add_return(pcp, val) \
({ \
- typeof(pcp) __ret; \
+ TYPEOF_UNQUAL(pcp) __ret; \
unsigned long __flags; \
raw_local_irq_save(__flags); \
__ret = raw_cpu_generic_add_return(pcp, val); \
@@ -170,7 +170,7 @@ do { \
#define this_cpu_generic_xchg(pcp, nval) \
({ \
- typeof(pcp) __ret; \
+ TYPEOF_UNQUAL(pcp) __ret; \
unsigned long __flags; \
raw_local_irq_save(__flags); \
__ret = raw_cpu_generic_xchg(pcp, nval); \
@@ -190,7 +190,7 @@ do { \
#define this_cpu_generic_cmpxchg(pcp, oval, nval) \
({ \
- typeof(pcp) __ret; \
+ TYPEOF_UNQUAL(pcp) __ret; \
unsigned long __flags; \
raw_local_irq_save(__flags); \
__ret = raw_cpu_generic_cmpxchg(pcp, oval, nval); \
diff --git a/include/linux/part_stat.h b/include/linux/part_stat.h
index ac8c44dd8237..c5e9cac0575e 100644
--- a/include/linux/part_stat.h
+++ b/include/linux/part_stat.h
@@ -33,7 +33,7 @@ struct disk_stats {
#define part_stat_read(part, field) \
({ \
- typeof((part)->bd_stats->field) res = 0; \
+ TYPEOF_UNQUAL((part)->bd_stats->field) res = 0; \
unsigned int _cpu; \
for_each_possible_cpu(_cpu) \
res += per_cpu_ptr((part)->bd_stats, _cpu)->field; \
diff --git a/include/linux/percpu-defs.h b/include/linux/percpu-defs.h
index 35842d1e3879..266297b21a5d 100644
--- a/include/linux/percpu-defs.h
+++ b/include/linux/percpu-defs.h
@@ -320,7 +320,7 @@ static __always_inline void __this_cpu_preempt_check(const char *op) { }
#define __pcpu_size_call_return(stem, variable) \
({ \
- typeof(variable) pscr_ret__; \
+ TYPEOF_UNQUAL(variable) pscr_ret__; \
__verify_pcpu_ptr(&(variable)); \
switch(sizeof(variable)) { \
case 1: pscr_ret__ = stem##1(variable); break; \
@@ -335,7 +335,7 @@ static __always_inline void __this_cpu_preempt_check(const char *op) { }
#define __pcpu_size_call_return2(stem, variable, ...) \
({ \
- typeof(variable) pscr2_ret__; \
+ TYPEOF_UNQUAL(variable) pscr2_ret__; \
__verify_pcpu_ptr(&(variable)); \
switch(sizeof(variable)) { \
case 1: pscr2_ret__ = stem##1(variable, __VA_ARGS__); break; \
diff --git a/include/net/snmp.h b/include/net/snmp.h
index 468a67836e2f..4cb4326dfebe 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -159,7 +159,7 @@ struct linux_tls_mib {
#define __SNMP_ADD_STATS64(mib, field, addend) \
do { \
- __typeof__(*mib) *ptr = raw_cpu_ptr(mib); \
+ TYPEOF_UNQUAL(*mib) *ptr = raw_cpu_ptr(mib); \
u64_stats_update_begin(&ptr->syncp); \
ptr->mibs[field] += addend; \
u64_stats_update_end(&ptr->syncp); \
@@ -176,8 +176,7 @@ struct linux_tls_mib {
#define SNMP_INC_STATS64(mib, field) SNMP_ADD_STATS64(mib, field, 1)
#define __SNMP_UPD_PO_STATS64(mib, basefield, addend) \
do { \
- __typeof__(*mib) *ptr; \
- ptr = raw_cpu_ptr((mib)); \
+ TYPEOF_UNQUAL(*mib) *ptr = raw_cpu_ptr(mib); \
u64_stats_update_begin(&ptr->syncp); \
ptr->mibs[basefield##PKTS]++; \
ptr->mibs[basefield##OCTETS] += addend; \
diff --git a/kernel/locking/percpu-rwsem.c b/kernel/locking/percpu-rwsem.c
index 6083883c4fe0..d6964fc29f51 100644
--- a/kernel/locking/percpu-rwsem.c
+++ b/kernel/locking/percpu-rwsem.c
@@ -184,7 +184,7 @@ EXPORT_SYMBOL_GPL(__percpu_down_read);
#define per_cpu_sum(var) \
({ \
- typeof(var) __sum = 0; \
+ TYPEOF_UNQUAL(var) __sum = 0; \
int cpu; \
compiletime_assert_atomic_type(__sum); \
for_each_possible_cpu(cpu) \
diff --git a/net/mpls/internal.h b/net/mpls/internal.h
index b9f492ddf93b..83c629529b57 100644
--- a/net/mpls/internal.h
+++ b/net/mpls/internal.h
@@ -33,7 +33,7 @@ struct mpls_dev {
#define MPLS_INC_STATS_LEN(mdev, len, pkts_field, bytes_field) \
do { \
- __typeof__(*(mdev)->stats) *ptr = \
+ TYPEOF_UNQUAL(*(mdev)->stats) *ptr = \
raw_cpu_ptr((mdev)->stats); \
local_bh_disable(); \
u64_stats_update_begin(&ptr->syncp); \
@@ -45,7 +45,7 @@ struct mpls_dev {
#define MPLS_INC_STATS(mdev, field) \
do { \
- __typeof__(*(mdev)->stats) *ptr = \
+ TYPEOF_UNQUAL(*(mdev)->stats) *ptr = \
raw_cpu_ptr((mdev)->stats); \
local_bh_disable(); \
u64_stats_update_begin(&ptr->syncp); \
--
2.42.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v3 4/6] percpu: Use TYPEOF_UNQUAL() in *_cpu_ptr() accessors
2024-12-08 20:45 [PATCH v3 0/6] Enable strict percpu address space checks Uros Bizjak
` (2 preceding siblings ...)
2024-12-08 20:45 ` [PATCH v3 3/6] percpu: Use TYPEOF_UNQUAL() in variable declarations Uros Bizjak
@ 2024-12-08 20:45 ` Uros Bizjak
2024-12-08 20:45 ` [PATCH v3 5/6] percpu: Repurpose __percpu tag as a named address space qualifier Uros Bizjak
` (3 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Uros Bizjak @ 2024-12-08 20:45 UTC (permalink / raw)
To: x86, linux-mm, linux-kernel, linux-bcachefs, linux-arch, netdev
Cc: Uros Bizjak, Nadav Amit, Christoph Lameter, Dennis Zhou,
Tejun Heo, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Linus Torvalds, Andy Lutomirski,
Brian Gerst, Peter Zijlstra
Use TYPEOF_UNQUAL() macro to declare the return type of *_cpu_ptr()
accessors in the generic named address space to avoid access to
data from pointer to non-enclosed address space type of errors.
Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Acked-by: Nadav Amit <nadav.amit@gmail.com>
Acked-by: Christoph Lameter <cl@linux.com>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
---
arch/x86/include/asm/percpu.h | 8 ++++++--
include/linux/percpu-defs.h | 2 +-
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index 666e4137b09f..27f668660abe 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -73,10 +73,14 @@
unsigned long tcp_ptr__ = raw_cpu_read_long(this_cpu_off); \
\
tcp_ptr__ += (__force unsigned long)(_ptr); \
- (typeof(*(_ptr)) __kernel __force *)tcp_ptr__; \
+ (TYPEOF_UNQUAL(*(_ptr)) __force __kernel *)tcp_ptr__; \
})
#else
-#define arch_raw_cpu_ptr(_ptr) ({ BUILD_BUG(); (typeof(_ptr))0; })
+#define arch_raw_cpu_ptr(_ptr) \
+({ \
+ BUILD_BUG(); \
+ (TYPEOF_UNQUAL(*(_ptr)) __force __kernel *)0; \
+})
#endif
#define PER_CPU_VAR(var) %__percpu_seg:(var)__percpu_rel
diff --git a/include/linux/percpu-defs.h b/include/linux/percpu-defs.h
index 266297b21a5d..2921ea97d242 100644
--- a/include/linux/percpu-defs.h
+++ b/include/linux/percpu-defs.h
@@ -223,7 +223,7 @@ do { \
#define PERCPU_PTR(__p) \
({ \
unsigned long __pcpu_ptr = (__force unsigned long)(__p); \
- (typeof(*(__p)) __force __kernel *)(__pcpu_ptr); \
+ (TYPEOF_UNQUAL(*(__p)) __force __kernel *)(__pcpu_ptr); \
})
#ifdef CONFIG_SMP
--
2.42.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v3 5/6] percpu: Repurpose __percpu tag as a named address space qualifier
2024-12-08 20:45 [PATCH v3 0/6] Enable strict percpu address space checks Uros Bizjak
` (3 preceding siblings ...)
2024-12-08 20:45 ` [PATCH v3 4/6] percpu: Use TYPEOF_UNQUAL() in *_cpu_ptr() accessors Uros Bizjak
@ 2024-12-08 20:45 ` Uros Bizjak
2024-12-08 20:45 ` [PATCH v3 6/6] percpu/x86: Enable strict percpu checks via named AS qualifiers Uros Bizjak
` (2 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Uros Bizjak @ 2024-12-08 20:45 UTC (permalink / raw)
To: x86, linux-mm, linux-kernel, linux-bcachefs, linux-arch, netdev
Cc: Uros Bizjak, Nadav Amit, Arnd Bergmann, Thomas Gleixner,
Dennis Zhou, Tejun Heo, Christoph Lameter, Linus Torvalds,
Andy Lutomirski, Ingo Molnar, Brian Gerst, H. Peter Anvin,
Peter Zijlstra
The patch introduces __percpu_qual define and repurposes __percpu
tag as a named address space qualifier using the new define.
Arches can now conditionally define __percpu_qual as their
named address space qualifier for percpu variables.
Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Acked-by: Nadav Amit <nadav.amit@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Christoph Lameter <cl@linux.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Peter Zijlstra <peterz@infradead.org>
---
v3: - Rename __per_cpu_qual to __percpu_qual.
---
include/asm-generic/percpu.h | 13 +++++++++++++
include/linux/compiler_types.h | 2 +-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
index 50597b975a49..02aeca21479a 100644
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -6,6 +6,19 @@
#include <linux/threads.h>
#include <linux/percpu-defs.h>
+/*
+ * __percpu_qual is the qualifier for the percpu named address space.
+ *
+ * Most arches use generic named address space for percpu variables but
+ * some arches define percpu variables in different named address space
+ * (on the x86 arch, percpu variable may be declared as being relative
+ * to the %fs or %gs segments using __seg_fs or __seg_gs named address
+ * space qualifier).
+ */
+#ifndef __percpu_qual
+# define __percpu_qual
+#endif
+
#ifdef CONFIG_SMP
/*
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index 981cc3d7e3aa..5d6544545658 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -57,7 +57,7 @@ static inline void __chk_io_ptr(const volatile void __iomem *ptr) { }
# define __user BTF_TYPE_TAG(user)
# endif
# define __iomem
-# define __percpu BTF_TYPE_TAG(percpu)
+# define __percpu __percpu_qual BTF_TYPE_TAG(percpu)
# define __rcu BTF_TYPE_TAG(rcu)
# define __chk_user_ptr(x) (void)0
--
2.42.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v3 6/6] percpu/x86: Enable strict percpu checks via named AS qualifiers
2024-12-08 20:45 [PATCH v3 0/6] Enable strict percpu address space checks Uros Bizjak
` (4 preceding siblings ...)
2024-12-08 20:45 ` [PATCH v3 5/6] percpu: Repurpose __percpu tag as a named address space qualifier Uros Bizjak
@ 2024-12-08 20:45 ` Uros Bizjak
2024-12-10 3:59 ` [PATCH v3 0/6] Enable strict percpu address space checks Dennis Zhou
2024-12-13 3:35 ` Andrew Morton
7 siblings, 0 replies; 14+ messages in thread
From: Uros Bizjak @ 2024-12-08 20:45 UTC (permalink / raw)
To: x86, linux-mm, linux-kernel, linux-bcachefs, linux-arch, netdev
Cc: Uros Bizjak, Nadav Amit, Dennis Zhou, Tejun Heo,
Christoph Lameter, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Linus Torvalds, Andy Lutomirski,
Brian Gerst, Peter Zijlstra
This patch declares percpu variables in __seg_gs/__seg_fs named AS
and keeps them named AS qualified until they are dereferenced with
percpu accessor. This approach enables various compiler check
for cross-namespace variable assignments.
Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Acked-by: Nadav Amit <nadav.amit@gmail.com>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Christoph Lameter <cl@linux.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
---
v2: - Add comment to remove test for __CHECKER__ once sparse learns
about __typeof_unqual__.
---
arch/x86/include/asm/percpu.h | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index 27f668660abe..1ef08289e667 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -95,9 +95,23 @@
#endif /* CONFIG_SMP */
-#define __my_cpu_type(var) typeof(var) __percpu_seg_override
-#define __my_cpu_ptr(ptr) (__my_cpu_type(*(ptr))*)(__force uintptr_t)(ptr)
-#define __my_cpu_var(var) (*__my_cpu_ptr(&(var)))
+/*
+ * XXX: Remove test for __CHECKER__ once
+ * sparse learns about __typeof_unqual__.
+ */
+#if defined(CONFIG_USE_X86_SEG_SUPPORT) && \
+ defined(CONFIG_CC_HAS_TYPEOF_UNQUAL) && !defined(__CHECKER__)
+# define __my_cpu_type(var) typeof(var)
+# define __my_cpu_ptr(ptr) (ptr)
+# define __my_cpu_var(var) (var)
+
+# define __percpu_qual __percpu_seg_override
+#else
+# define __my_cpu_type(var) typeof(var) __percpu_seg_override
+# define __my_cpu_ptr(ptr) (__my_cpu_type(*(ptr))*)(__force uintptr_t)(ptr)
+# define __my_cpu_var(var) (*__my_cpu_ptr(&(var)))
+#endif
+
#define __percpu_arg(x) __percpu_prefix "%" #x
#define __force_percpu_arg(x) __force_percpu_prefix "%" #x
--
2.42.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 2/6] compiler.h: Introduce TYPEOF_UNQUAL() macro
2024-12-08 20:45 ` [PATCH v3 2/6] compiler.h: Introduce TYPEOF_UNQUAL() macro Uros Bizjak
@ 2024-12-09 11:30 ` Peter Zijlstra
2024-12-09 13:01 ` Uros Bizjak
2024-12-10 16:37 ` Uros Bizjak
0 siblings, 2 replies; 14+ messages in thread
From: Peter Zijlstra @ 2024-12-09 11:30 UTC (permalink / raw)
To: Uros Bizjak
Cc: x86, linux-mm, linux-kernel, linux-bcachefs, linux-arch, netdev,
Nadav Amit, Thomas Gleixner, Dennis Zhou, Tejun Heo,
Christoph Lameter, Linus Torvalds, Andy Lutomirski, Ingo Molnar,
Brian Gerst, Denys Vlasenko, H. Peter Anvin
On Sun, Dec 08, 2024 at 09:45:17PM +0100, Uros Bizjak wrote:
> Define TYPEOF_UNQUAL() to use __typeof_unqual__() as typeof operator
> when available, to return unqualified type of the expression.
>
> Current version of sparse doesn't know anything about __typeof_unqual__()
> operator. Avoid the usage of __typeof_unqual__() when sparse checking
> is active to prevent sparse errors with unknowing keyword.
Ooooh, new toys.
I suppose __unqual_scalar_typeof() wants to be using this when
available?
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 2/6] compiler.h: Introduce TYPEOF_UNQUAL() macro
2024-12-09 11:30 ` Peter Zijlstra
@ 2024-12-09 13:01 ` Uros Bizjak
2024-12-10 16:37 ` Uros Bizjak
1 sibling, 0 replies; 14+ messages in thread
From: Uros Bizjak @ 2024-12-09 13:01 UTC (permalink / raw)
To: Peter Zijlstra
Cc: x86, linux-mm, linux-kernel, linux-bcachefs, linux-arch, netdev,
Nadav Amit, Thomas Gleixner, Dennis Zhou, Tejun Heo,
Christoph Lameter, Linus Torvalds, Andy Lutomirski, Ingo Molnar,
Brian Gerst, Denys Vlasenko, H. Peter Anvin
[-- Attachment #1: Type: text/plain, Size: 676 bytes --]
On Mon, Dec 9, 2024 at 12:30 PM Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Sun, Dec 08, 2024 at 09:45:17PM +0100, Uros Bizjak wrote:
> > Define TYPEOF_UNQUAL() to use __typeof_unqual__() as typeof operator
> > when available, to return unqualified type of the expression.
> >
> > Current version of sparse doesn't know anything about __typeof_unqual__()
> > operator. Avoid the usage of __typeof_unqual__() when sparse checking
> > is active to prevent sparse errors with unknowing keyword.
>
> Ooooh, new toys.
>
> I suppose __unqual_scalar_typeof() wants to be using this when
> available?
Yes, the attached patch compiles and boots OK.
Uros.
[-- Attachment #2: unqual_scalar_typeof.diff.txt --]
[-- Type: text/plain, Size: 1289 bytes --]
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index 5d6544545658..87a9ce3ebd13 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -486,15 +486,19 @@ struct ftrace_likely_data {
* __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving
* non-scalar types unchanged.
*/
+
+#if defined(CONFIG_CC_HAS_TYPEOF_UNQUAL) && !defined(__CHECKER__)
+# define __unqual_scalar_typeof(x) __typeof_unqual__(x)
+#else
/*
* Prefer C11 _Generic for better compile-times and simpler code. Note: 'char'
* is not type-compatible with 'signed char', and we define a separate case.
*/
-#define __scalar_type_to_expr_cases(type) \
+ #define __scalar_type_to_expr_cases(type) \
unsigned type: (unsigned type)0, \
signed type: (signed type)0
-#define __unqual_scalar_typeof(x) typeof( \
+ #define __unqual_scalar_typeof(x) typeof( \
_Generic((x), \
char: (char)0, \
__scalar_type_to_expr_cases(char), \
@@ -503,6 +507,7 @@ struct ftrace_likely_data {
__scalar_type_to_expr_cases(long), \
__scalar_type_to_expr_cases(long long), \
default: (x)))
+#endif
/* Is this type a native word size -- useful for atomic operations */
#define __native_word(t) \
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 0/6] Enable strict percpu address space checks
2024-12-08 20:45 [PATCH v3 0/6] Enable strict percpu address space checks Uros Bizjak
` (5 preceding siblings ...)
2024-12-08 20:45 ` [PATCH v3 6/6] percpu/x86: Enable strict percpu checks via named AS qualifiers Uros Bizjak
@ 2024-12-10 3:59 ` Dennis Zhou
2024-12-13 3:35 ` Andrew Morton
7 siblings, 0 replies; 14+ messages in thread
From: Dennis Zhou @ 2024-12-10 3:59 UTC (permalink / raw)
To: Uros Bizjak
Cc: x86, linux-mm, linux-kernel, linux-bcachefs, linux-arch, netdev,
Thomas Gleixner, Tejun Heo, Christoph Lameter, Linus Torvalds,
Andy Lutomirski, Ingo Molnar, Nadav Amit, Brian Gerst,
Dan Carpenter, H . Peter Anvin, Peter Zijlstra
Hi Uros,
On Sun, Dec 08, 2024 at 09:45:15PM +0100, Uros Bizjak wrote:
> Enable strict percpu address space checks via x86 named address space
> qualifiers. Percpu variables are declared in __seg_gs/__seg_fs named
> AS and kept named AS qualified until they are dereferenced via percpu
> accessor. This approach enables various compiler checks for
> cross-namespace variable assignments.
>
> Please note that current version of sparse doesn't know anything about
> __typeof_unqual__() operator. Avoid the usage of __typeof_unqual__()
> when sparse checking is active to prevent sparse errors with unknowing
> keyword. The proposed patch by Dan Carpenter to implement
> __typeof_unqual__() handling in sparse is located at:
>
> https://lore.kernel.org/lkml/5b8d0dee-8fb6-45af-ba6c-7f74aff9a4b8@stanley.mountain/
>
> v2: - Add comment to remove test for __CHECKER__ once sparse learns
> about __typeof_unqual__.
> - Add Acked-by: tags.
> v3: - Rename __per_cpu_qual to __percpu_qual.
> - Add more Acked-by: tags.
>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Dennis Zhou <dennis@kernel.org>
> Cc: Tejun Heo <tj@kernel.org>
> Cc: Christoph Lameter <cl@linux.com>
> Cc: Linus Torvalds <torvalds@linux-foundation.org>
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Nadav Amit <nadav.amit@gmail.com>
> Cc: Brian Gerst <brgerst@gmail.com>
> Cc: Dan Carpenter <dan.carpenter@linaro.org>
> Cc: H. Peter Anvin <hpa@zytor.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
>
> Uros Bizjak (6):
> x86/kgdb: Use IS_ERR_PCPU() macro
> compiler.h: Introduce TYPEOF_UNQUAL() macro
> percpu: Use TYPEOF_UNQUAL() in variable declarations
> percpu: Use TYPEOF_UNQUAL() in *_cpu_ptr() accessors
> percpu: Repurpose __percpu tag as a named address space qualifier
> percpu/x86: Enable strict percpu checks via named AS qualifiers
>
> arch/x86/include/asm/percpu.h | 38 ++++++++++++++++++++++++---------
> arch/x86/kernel/kgdb.c | 2 +-
> fs/bcachefs/util.h | 2 +-
> include/asm-generic/percpu.h | 39 ++++++++++++++++++++++------------
> include/linux/compiler.h | 13 ++++++++++++
> include/linux/compiler_types.h | 2 +-
> include/linux/part_stat.h | 2 +-
> include/linux/percpu-defs.h | 6 +++---
> include/net/snmp.h | 5 ++---
> init/Kconfig | 3 +++
> kernel/locking/percpu-rwsem.c | 2 +-
> net/mpls/internal.h | 4 ++--
> 12 files changed, 82 insertions(+), 36 deletions(-)
>
> --
> 2.42.0
>
This all looks good to me.
Acked-by: Dennis Zhou <dennis@kernel.org>
Thanks,
Dennis
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 2/6] compiler.h: Introduce TYPEOF_UNQUAL() macro
2024-12-09 11:30 ` Peter Zijlstra
2024-12-09 13:01 ` Uros Bizjak
@ 2024-12-10 16:37 ` Uros Bizjak
1 sibling, 0 replies; 14+ messages in thread
From: Uros Bizjak @ 2024-12-10 16:37 UTC (permalink / raw)
To: Peter Zijlstra
Cc: x86, linux-mm, linux-kernel, linux-bcachefs, linux-arch, netdev,
Nadav Amit, Thomas Gleixner, Dennis Zhou, Tejun Heo,
Christoph Lameter, Linus Torvalds, Andy Lutomirski, Ingo Molnar,
Brian Gerst, Denys Vlasenko, H. Peter Anvin, Nathan Chancellor
[-- Attachment #1: Type: text/plain, Size: 1659 bytes --]
On Mon, Dec 9, 2024 at 12:30 PM Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Sun, Dec 08, 2024 at 09:45:17PM +0100, Uros Bizjak wrote:
> > Define TYPEOF_UNQUAL() to use __typeof_unqual__() as typeof operator
> > when available, to return unqualified type of the expression.
> >
> > Current version of sparse doesn't know anything about __typeof_unqual__()
> > operator. Avoid the usage of __typeof_unqual__() when sparse checking
> > is active to prevent sparse errors with unknowing keyword.
>
> Ooooh, new toys.
>
> I suppose __unqual_scalar_typeof() wants to be using this when
> available?
Not only that, the new toy enables clang to check kernel's address
spaces in a generic way using address_space attribute.
Please find attached a follow-up patch that enables __percpu checks
for all targets, supported by clang. Clang is a little bit pickier
than gcc about named address space declarations (it warns for use of
duplicated address space attribute), so the patch in addition to the
obvious
+# define __percpu_qual __attribute__((address_space(3)))
also fixes a couple of macros that could result in a duplicated
address space attribute.
The patch, applied as a follow-up to the series, survives allyesconfig
compilation with clang-19 and produces a bootable kernel. The patch
was tested only for x86_64 target, for other targets a couple of
trivial fixes would be necessary (a cast or a substitution of typeof()
with TYPEOF_UNQUAL()).
AFAICS, the same approach using clang's address_space attribute can be
implemented to also check other address spaces: __user, __iommu and
__rcu.
Uros.
[-- Attachment #2: percpu-clang.diff.txt --]
[-- Type: text/plain, Size: 2238 bytes --]
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
index 02aeca21479a..4109d828a564 100644
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -16,7 +16,12 @@
* space qualifier).
*/
#ifndef __percpu_qual
-# define __percpu_qual
+# if __has_attribute(address_space) && \
+ defined(CONFIG_CC_HAS_TYPEOF_UNQUAL) && !defined(__CHECKER__)
+# define __percpu_qual __attribute__((address_space(3)))
+# else
+# define __percpu_qual
+# endif
#endif
#ifdef CONFIG_SMP
diff --git a/include/linux/device.h b/include/linux/device.h
index 667cb6db9019..1d6a55d5250a 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -431,9 +431,9 @@ static inline int __devm_add_action_or_reset(struct device *dev, void (*action)(
* RETURNS:
* Pointer to allocated memory on success, NULL on failure.
*/
-#define devm_alloc_percpu(dev, type) \
- ((typeof(type) __percpu *)__devm_alloc_percpu((dev), sizeof(type), \
- __alignof__(type)))
+#define devm_alloc_percpu(dev, type) \
+ ((TYPEOF_UNQUAL(type) __percpu *)__devm_alloc_percpu((dev), \
+ sizeof(type), __alignof__(type)))
void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
size_t align);
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index 52b5ea663b9f..c3bf040aba66 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -148,13 +148,13 @@ extern void __percpu *pcpu_alloc_noprof(size_t size, size_t align, bool reserved
alloc_hooks(pcpu_alloc_noprof(_size, _align, true, GFP_KERNEL))
#define alloc_percpu_gfp(type, gfp) \
- (typeof(type) __percpu *)__alloc_percpu_gfp(sizeof(type), \
+ (TYPEOF_UNQUAL(type) __percpu *)__alloc_percpu_gfp(sizeof(type), \
__alignof__(type), gfp)
#define alloc_percpu(type) \
- (typeof(type) __percpu *)__alloc_percpu(sizeof(type), \
+ (TYPEOF_UNQUAL(type) __percpu *)__alloc_percpu(sizeof(type), \
__alignof__(type))
#define alloc_percpu_noprof(type) \
- ((typeof(type) __percpu *)pcpu_alloc_noprof(sizeof(type), \
+ ((TYPEOF_UNQUAL(type) __percpu *)pcpu_alloc_noprof(sizeof(type), \
__alignof__(type), false, GFP_KERNEL))
extern void free_percpu(void __percpu *__pdata);
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 0/6] Enable strict percpu address space checks
2024-12-08 20:45 [PATCH v3 0/6] Enable strict percpu address space checks Uros Bizjak
` (6 preceding siblings ...)
2024-12-10 3:59 ` [PATCH v3 0/6] Enable strict percpu address space checks Dennis Zhou
@ 2024-12-13 3:35 ` Andrew Morton
2024-12-13 4:28 ` Uros Bizjak
2024-12-13 7:13 ` Dan Carpenter
7 siblings, 2 replies; 14+ messages in thread
From: Andrew Morton @ 2024-12-13 3:35 UTC (permalink / raw)
To: Uros Bizjak
Cc: x86, linux-mm, linux-kernel, linux-bcachefs, linux-arch, netdev,
Thomas Gleixner, Dennis Zhou, Tejun Heo, Christoph Lameter,
Linus Torvalds, Andy Lutomirski, Ingo Molnar, Nadav Amit,
Brian Gerst, Dan Carpenter, H . Peter Anvin, Peter Zijlstra
On Sun, 8 Dec 2024 21:45:15 +0100 Uros Bizjak <ubizjak@gmail.com> wrote:
> Enable strict percpu address space checks via x86 named address space
> qualifiers. Percpu variables are declared in __seg_gs/__seg_fs named
> AS and kept named AS qualified until they are dereferenced via percpu
> accessor. This approach enables various compiler checks for
> cross-namespace variable assignments.
>
> Please note that current version of sparse doesn't know anything about
> __typeof_unqual__() operator. Avoid the usage of __typeof_unqual__()
> when sparse checking is active to prevent sparse errors with unknowing
> keyword. The proposed patch by Dan Carpenter to implement
> __typeof_unqual__() handling in sparse is located at:
google("what the hell is typeof_unequal") failed me.
I think it would be nice to include within the changelog (and code
comments!) an explanation-for-others of what this thing is and why
anyone would want to use it. Rather than assuming that all kernel
developers are typeof() experts!
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 0/6] Enable strict percpu address space checks
2024-12-13 3:35 ` Andrew Morton
@ 2024-12-13 4:28 ` Uros Bizjak
2024-12-13 7:13 ` Dan Carpenter
1 sibling, 0 replies; 14+ messages in thread
From: Uros Bizjak @ 2024-12-13 4:28 UTC (permalink / raw)
To: Andrew Morton
Cc: x86, linux-mm, linux-kernel, linux-bcachefs, linux-arch, netdev,
Thomas Gleixner, Dennis Zhou, Tejun Heo, Christoph Lameter,
Linus Torvalds, Andy Lutomirski, Ingo Molnar, Nadav Amit,
Brian Gerst, Dan Carpenter, H . Peter Anvin, Peter Zijlstra
On Fri, Dec 13, 2024 at 4:35 AM Andrew Morton <akpm@linux-foundation.org> wrote:
>
> On Sun, 8 Dec 2024 21:45:15 +0100 Uros Bizjak <ubizjak@gmail.com> wrote:
>
> > Enable strict percpu address space checks via x86 named address space
> > qualifiers. Percpu variables are declared in __seg_gs/__seg_fs named
> > AS and kept named AS qualified until they are dereferenced via percpu
> > accessor. This approach enables various compiler checks for
> > cross-namespace variable assignments.
> >
> > Please note that current version of sparse doesn't know anything about
> > __typeof_unqual__() operator. Avoid the usage of __typeof_unqual__()
> > when sparse checking is active to prevent sparse errors with unknowing
> > keyword. The proposed patch by Dan Carpenter to implement
> > __typeof_unqual__() handling in sparse is located at:
>
> google("what the hell is typeof_unequal") failed me.
It is not "typeof_unequal", but "typeof_unqual", as in "unqualified".
Apparently, google does not like expletives, googling for "What is
typeof_unqual?" returns some very informative hits, e.g.:
https://en.cppreference.com/w/c/keyword/typeof_unqual
https://learn.microsoft.com/en-us/cpp/c-language/typeof-unqual-c?view=msvc-170
https://gcc.gnu.org/onlinedocs/gcc/Typeof.html
https://dev.to/pauljlucas/typeof-in-c23-55p2
> I think it would be nice to include within the changelog (and code
> comments!) an explanation-for-others of what this thing is and why
> anyone would want to use it. Rather than assuming that all kernel
> developers are typeof() experts!
The comment above definition of TYPEOF_UNQUAL in [PATCH 2/6]
summarises the above as:
+ * Define TYPEOF_UNQUAL() to use __typeof_unqual__() as typeof
+ * operator when available, to return unqualified type of the exp.
which is basically what the standard says in its reference document.
Thanks,
Uros.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v3 0/6] Enable strict percpu address space checks
2024-12-13 3:35 ` Andrew Morton
2024-12-13 4:28 ` Uros Bizjak
@ 2024-12-13 7:13 ` Dan Carpenter
1 sibling, 0 replies; 14+ messages in thread
From: Dan Carpenter @ 2024-12-13 7:13 UTC (permalink / raw)
To: Andrew Morton
Cc: Uros Bizjak, x86, linux-mm, linux-kernel, linux-bcachefs,
linux-arch, netdev, Thomas Gleixner, Dennis Zhou, Tejun Heo,
Christoph Lameter, Linus Torvalds, Andy Lutomirski, Ingo Molnar,
Nadav Amit, Brian Gerst, H . Peter Anvin, Peter Zijlstra
On Thu, Dec 12, 2024 at 07:35:41PM -0800, Andrew Morton wrote:
> On Sun, 8 Dec 2024 21:45:15 +0100 Uros Bizjak <ubizjak@gmail.com> wrote:
>
> > Enable strict percpu address space checks via x86 named address space
> > qualifiers. Percpu variables are declared in __seg_gs/__seg_fs named
> > AS and kept named AS qualified until they are dereferenced via percpu
> > accessor. This approach enables various compiler checks for
> > cross-namespace variable assignments.
> >
> > Please note that current version of sparse doesn't know anything about
> > __typeof_unqual__() operator. Avoid the usage of __typeof_unqual__()
> > when sparse checking is active to prevent sparse errors with unknowing
> > keyword. The proposed patch by Dan Carpenter to implement
> > __typeof_unqual__() handling in sparse is located at:
>
> google("what the hell is typeof_unequal") failed me.
I'm glad I'm not the only person who read that as "equal" instead of
"qualified".
regards,
dan carpenter
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2024-12-13 7:13 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-12-08 20:45 [PATCH v3 0/6] Enable strict percpu address space checks Uros Bizjak
2024-12-08 20:45 ` [PATCH v3 1/6] x86/kgdb: Use IS_ERR_PCPU() macro Uros Bizjak
2024-12-08 20:45 ` [PATCH v3 2/6] compiler.h: Introduce TYPEOF_UNQUAL() macro Uros Bizjak
2024-12-09 11:30 ` Peter Zijlstra
2024-12-09 13:01 ` Uros Bizjak
2024-12-10 16:37 ` Uros Bizjak
2024-12-08 20:45 ` [PATCH v3 3/6] percpu: Use TYPEOF_UNQUAL() in variable declarations Uros Bizjak
2024-12-08 20:45 ` [PATCH v3 4/6] percpu: Use TYPEOF_UNQUAL() in *_cpu_ptr() accessors Uros Bizjak
2024-12-08 20:45 ` [PATCH v3 5/6] percpu: Repurpose __percpu tag as a named address space qualifier Uros Bizjak
2024-12-08 20:45 ` [PATCH v3 6/6] percpu/x86: Enable strict percpu checks via named AS qualifiers Uros Bizjak
2024-12-10 3:59 ` [PATCH v3 0/6] Enable strict percpu address space checks Dennis Zhou
2024-12-13 3:35 ` Andrew Morton
2024-12-13 4:28 ` Uros Bizjak
2024-12-13 7:13 ` Dan Carpenter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox