* [PATCH 0/6] Enable strict percpu address space checks
@ 2024-11-26 17:21 Uros Bizjak
2024-11-26 17:21 ` [PATCH 1/6] x86/kgdb: Use IS_ERR_PCPU() macro Uros Bizjak
` (6 more replies)
0 siblings, 7 replies; 10+ messages in thread
From: Uros Bizjak @ 2024-11-26 17:21 UTC (permalink / raw)
To: x86, linux-sparse, 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,
Luc Van Oostenryck, Nadav Amit, Brian Gerst, H . Peter Anvin,
Peter Zijlstra
This patchset enables 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.
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: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Cc: Nadav Amit <nadav.amit@gmail.com>
Cc: Brian Gerst <brgerst@gmail.com>
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 | 34 +++++++++++++++++++---------
arch/x86/kernel/kgdb.c | 2 +-
fs/bcachefs/util.h | 2 +-
include/asm-generic/percpu.h | 41 +++++++++++++++++++++++-----------
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, 80 insertions(+), 36 deletions(-)
--
2.42.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/6] x86/kgdb: Use IS_ERR_PCPU() macro
2024-11-26 17:21 [PATCH 0/6] Enable strict percpu address space checks Uros Bizjak
@ 2024-11-26 17:21 ` Uros Bizjak
2024-11-26 17:21 ` [PATCH 2/6] compiler.h: Introduce TYPEOF_UNQUAL() macro Uros Bizjak
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Uros Bizjak @ 2024-11-26 17:21 UTC (permalink / raw)
To: x86, linux-sparse, linux-mm, linux-kernel, linux-bcachefs,
linux-arch, netdev
Cc: Uros Bizjak, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Dennis Zhou, Tejun Heo,
Christoph Lameter, Linus Torvalds, Andy Lutomirski,
Luc Van Oostenryck, Nadav Amit, 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>
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: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Cc: Nadav Amit <nadav.amit@gmail.com>
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 related [flat|nested] 10+ messages in thread
* [PATCH 2/6] compiler.h: Introduce TYPEOF_UNQUAL() macro
2024-11-26 17:21 [PATCH 0/6] Enable strict percpu address space checks Uros Bizjak
2024-11-26 17:21 ` [PATCH 1/6] x86/kgdb: Use IS_ERR_PCPU() macro Uros Bizjak
@ 2024-11-26 17:21 ` Uros Bizjak
2024-11-26 17:21 ` [PATCH 3/6] percpu: Use TYPEOF_UNQUAL() in variable declarations Uros Bizjak
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Uros Bizjak @ 2024-11-26 17:21 UTC (permalink / raw)
To: x86, linux-sparse, linux-mm, linux-kernel, linux-bcachefs,
linux-arch, netdev
Cc: Uros Bizjak, Luc Van Oostenryck, Thomas Gleixner, Dennis Zhou,
Tejun Heo, Christoph Lameter, Linus Torvalds, Andy Lutomirski,
Ingo Molnar, Nadav Amit, 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>
Cc: Luc Van Oostenryck <luc.vanoostenryck@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: Nadav Amit <nadav.amit@gmail.com>
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..bb0bde335129 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 unqual_typeof() 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 related [flat|nested] 10+ messages in thread
* [PATCH 3/6] percpu: Use TYPEOF_UNQUAL() in variable declarations
2024-11-26 17:21 [PATCH 0/6] Enable strict percpu address space checks Uros Bizjak
2024-11-26 17:21 ` [PATCH 1/6] x86/kgdb: Use IS_ERR_PCPU() macro Uros Bizjak
2024-11-26 17:21 ` [PATCH 2/6] compiler.h: Introduce TYPEOF_UNQUAL() macro Uros Bizjak
@ 2024-11-26 17:21 ` Uros Bizjak
2024-11-26 17:21 ` [PATCH 4/6] percpu: Use TYPEOF_UNQUAL() in *_cpu_ptr() accessors Uros Bizjak
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Uros Bizjak @ 2024-11-26 17:21 UTC (permalink / raw)
To: x86, linux-sparse, linux-mm, linux-kernel, linux-bcachefs,
linux-arch, netdev
Cc: Uros Bizjak, Dennis Zhou, Tejun Heo, Christoph Lameter,
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, Luc Van Oostenryck, Nadav Amit, 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>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Christoph Lameter <cl@linux.com>
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: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Cc: Nadav Amit <nadav.amit@gmail.com>
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 related [flat|nested] 10+ messages in thread
* [PATCH 4/6] percpu: Use TYPEOF_UNQUAL() in *_cpu_ptr() accessors
2024-11-26 17:21 [PATCH 0/6] Enable strict percpu address space checks Uros Bizjak
` (2 preceding siblings ...)
2024-11-26 17:21 ` [PATCH 3/6] percpu: Use TYPEOF_UNQUAL() in variable declarations Uros Bizjak
@ 2024-11-26 17:21 ` Uros Bizjak
2024-11-26 17:21 ` [PATCH 5/6] percpu: Repurpose __percpu tag as a named address space qualifier Uros Bizjak
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Uros Bizjak @ 2024-11-26 17:21 UTC (permalink / raw)
To: x86, linux-sparse, linux-mm, linux-kernel, linux-bcachefs,
linux-arch, netdev
Cc: Uros Bizjak, Dennis Zhou, Tejun Heo, Christoph Lameter,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Linus Torvalds, Andy Lutomirski,
Luc Van Oostenryck, Nadav Amit, 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>
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: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Cc: Nadav Amit <nadav.amit@gmail.com>
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 related [flat|nested] 10+ messages in thread
* [PATCH 5/6] percpu: Repurpose __percpu tag as a named address space qualifier
2024-11-26 17:21 [PATCH 0/6] Enable strict percpu address space checks Uros Bizjak
` (3 preceding siblings ...)
2024-11-26 17:21 ` [PATCH 4/6] percpu: Use TYPEOF_UNQUAL() in *_cpu_ptr() accessors Uros Bizjak
@ 2024-11-26 17:21 ` Uros Bizjak
2024-11-26 17:21 ` [PATCH 6/6] percpu/x86: Enable strict percpu checks via named AS qualifiers Uros Bizjak
2024-12-04 7:24 ` [PATCH 0/6] Enable strict percpu address space checks Dan Carpenter
6 siblings, 0 replies; 10+ messages in thread
From: Uros Bizjak @ 2024-11-26 17:21 UTC (permalink / raw)
To: x86, linux-sparse, linux-mm, linux-kernel, linux-bcachefs,
linux-arch, netdev
Cc: Uros Bizjak, Arnd Bergmann, Thomas Gleixner, Dennis Zhou,
Tejun Heo, Christoph Lameter, Linus Torvalds, Andy Lutomirski,
Ingo Molnar, Luc Van Oostenryck, Nadav Amit, Brian Gerst,
H. Peter Anvin, Peter Zijlstra
The patch introduces per_cpu_qual define and repurposes __percpu
tag as a named address space qualifier using the new define.
Arches can now conditionally define __per_cpu_qual as their
named address space qualifier for percpu variables.
Signed-off-by: Uros Bizjak <ubizjak@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: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Cc: Nadav Amit <nadav.amit@gmail.com>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Peter Zijlstra <peterz@infradead.org>
---
include/asm-generic/percpu.h | 15 +++++++++++++++
include/linux/compiler_types.h | 2 +-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
index 50597b975a49..3b93b168faa1 100644
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -6,6 +6,21 @@
#include <linux/threads.h>
#include <linux/percpu-defs.h>
+/*
+ * per_cpu_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).
+ */
+#ifdef __per_cpu_qual
+# define per_cpu_qual __per_cpu_qual
+#else
+# define per_cpu_qual
+#endif
+
#ifdef CONFIG_SMP
/*
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index 981cc3d7e3aa..877fe0c43c5d 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 per_cpu_qual BTF_TYPE_TAG(percpu)
# define __rcu BTF_TYPE_TAG(rcu)
# define __chk_user_ptr(x) (void)0
--
2.42.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/6] percpu/x86: Enable strict percpu checks via named AS qualifiers
2024-11-26 17:21 [PATCH 0/6] Enable strict percpu address space checks Uros Bizjak
` (4 preceding siblings ...)
2024-11-26 17:21 ` [PATCH 5/6] percpu: Repurpose __percpu tag as a named address space qualifier Uros Bizjak
@ 2024-11-26 17:21 ` Uros Bizjak
2024-11-29 15:45 ` Nadav Amit
2024-12-04 7:24 ` [PATCH 0/6] Enable strict percpu address space checks Dan Carpenter
6 siblings, 1 reply; 10+ messages in thread
From: Uros Bizjak @ 2024-11-26 17:21 UTC (permalink / raw)
To: x86, linux-sparse, linux-mm, linux-kernel, linux-bcachefs,
linux-arch, netdev
Cc: Uros Bizjak, Dennis Zhou, Tejun Heo, Christoph Lameter,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Linus Torvalds, Andy Lutomirski,
Luc Van Oostenryck, Nadav Amit, 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>
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: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Cc: Nadav Amit <nadav.amit@gmail.com>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
---
arch/x86/include/asm/percpu.h | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index 27f668660abe..61b875243ea3 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -95,9 +95,19 @@
#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)))
+#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 __per_cpu_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 related [flat|nested] 10+ messages in thread
* Re: [PATCH 6/6] percpu/x86: Enable strict percpu checks via named AS qualifiers
2024-11-26 17:21 ` [PATCH 6/6] percpu/x86: Enable strict percpu checks via named AS qualifiers Uros Bizjak
@ 2024-11-29 15:45 ` Nadav Amit
2024-11-29 16:33 ` Uros Bizjak
0 siblings, 1 reply; 10+ messages in thread
From: Nadav Amit @ 2024-11-29 15:45 UTC (permalink / raw)
To: Uros Bizjak
Cc: the arch/x86 maintainers, linux-sparse,
open list:MEMORY MANAGEMENT, Linux Kernel Mailing List,
linux-bcachefs, linux-arch, netdev, Dennis Zhou, Tejun Heo,
Christoph Lameter, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Linus Torvalds, Andy Lutomirski,
Luc Van Oostenryck, Brian Gerst, Peter Zijlstra
> On 26 Nov 2024, at 19:21, Uros Bizjak <ubizjak@gmail.com> wrote:
>
> 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.
[snip]
> @@ -95,9 +95,19 @@
>
> #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)))
> +#if defined(CONFIG_USE_X86_SEG_SUPPORT) && \
> + defined(CONFIG_CC_HAS_TYPEOF_UNQUAL) && !defined(__CHECKER__)
Is the __CHECKER__ check because of sparse, as in patch 2/6 ?
If so, do you want to add a similar comment here?
Other than that, I went over the different patches and it looks good as
much as I can tell.
If it means anything, you have for the series
Acked-by: Nadav Amit <nadav.amit@gmail.com <mailto:nadav.amit@gmail.com>>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 6/6] percpu/x86: Enable strict percpu checks via named AS qualifiers
2024-11-29 15:45 ` Nadav Amit
@ 2024-11-29 16:33 ` Uros Bizjak
0 siblings, 0 replies; 10+ messages in thread
From: Uros Bizjak @ 2024-11-29 16:33 UTC (permalink / raw)
To: Nadav Amit
Cc: the arch/x86 maintainers, linux-sparse,
open list:MEMORY MANAGEMENT, Linux Kernel Mailing List,
linux-bcachefs, linux-arch, netdev, Dennis Zhou, Tejun Heo,
Christoph Lameter, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, H. Peter Anvin, Linus Torvalds, Andy Lutomirski,
Luc Van Oostenryck, Brian Gerst, Peter Zijlstra
On Fri, Nov 29, 2024 at 4:45 PM Nadav Amit <nadav.amit@gmail.com> wrote:
>
>
> > On 26 Nov 2024, at 19:21, Uros Bizjak <ubizjak@gmail.com> wrote:
> >
> > 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.
>
> [snip]
>
> > @@ -95,9 +95,19 @@
> >
> > #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)))
> > +#if defined(CONFIG_USE_X86_SEG_SUPPORT) && \
> > + defined(CONFIG_CC_HAS_TYPEOF_UNQUAL) && !defined(__CHECKER__)
>
> Is the __CHECKER__ check because of sparse, as in patch 2/6 ?
> If so, do you want to add a similar comment here?
Yes, this is the same check. We can declare _percpu variables in
__seg_gs named address space only when __typeof_unqual__ is used. I
will add a comment in the next revision of the patchset.
> Other than that, I went over the different patches and it looks good as
> much as I can tell.
>
> If it means anything, you have for the series
>
> Acked-by: Nadav Amit <nadav.amit@gmail.com <mailto:nadav.amit@gmail.com>>
Thanks!
Uros.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/6] Enable strict percpu address space checks
2024-11-26 17:21 [PATCH 0/6] Enable strict percpu address space checks Uros Bizjak
` (5 preceding siblings ...)
2024-11-26 17:21 ` [PATCH 6/6] percpu/x86: Enable strict percpu checks via named AS qualifiers Uros Bizjak
@ 2024-12-04 7:24 ` Dan Carpenter
6 siblings, 0 replies; 10+ messages in thread
From: Dan Carpenter @ 2024-12-04 7:24 UTC (permalink / raw)
To: Uros Bizjak
Cc: x86, linux-sparse, linux-mm, linux-kernel, linux-bcachefs,
linux-arch, netdev, Thomas Gleixner, Dennis Zhou, Tejun Heo,
Christoph Lameter, Linus Torvalds, Andy Lutomirski, Ingo Molnar,
Luc Van Oostenryck, Nadav Amit, Brian Gerst, H . Peter Anvin,
Peter Zijlstra
On Tue, Nov 26, 2024 at 06:21:17PM +0100, Uros Bizjak wrote:
> This patchset enables 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.
I don't think it would be super hard to add support to Sparse. The only places
where typeof and typeof_unqual are different is that you have to mask away the
qualifiers in examine_typeof()?
I would take over Sparse maintainership but I'm far too sloppy to do it. We
should get Greg to take over, he likes abandoned projects. ;)
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
---
ast-inspect.c | 1 +
ctags.c | 1 +
dissect.c | 1 +
evaluate.c | 3 ++-
parse.c | 24 +++++++++++++++++++++---
show-parse.c | 1 +
symbol.c | 17 ++++++++++++++++-
symbol.h | 1 +
8 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/ast-inspect.c b/ast-inspect.c
index b510cd9b1d2c..e940a93a411e 100644
--- a/ast-inspect.c
+++ b/ast-inspect.c
@@ -110,6 +110,7 @@ static const char *symbol_type_name(enum type type)
[SYM_UNION] = "SYM_UNION",
[SYM_ENUM] = "SYM_ENUM",
[SYM_TYPEOF] = "SYM_TYPEOF",
+ [SYM_TYPEOF_UNQUAL] = "SYM_TYPEOF_UNQUAL",
[SYM_BITFIELD] = "SYM_BITFIELD",
[SYM_LABEL] = "SYM_LABEL",
[SYM_RESTRICT] = "SYM_RESTRICT",
diff --git a/ctags.c b/ctags.c
index aa5f9718d847..afdc42b77b98 100644
--- a/ctags.c
+++ b/ctags.c
@@ -151,6 +151,7 @@ static void examine_symbol(struct symbol *sym)
sym->kind = 'e';
case SYM_PTR:
case SYM_TYPEOF:
+ case SYM_TYPEOF_UNQUAL:
case SYM_BITFIELD:
case SYM_FN:
case SYM_ARRAY:
diff --git a/dissect.c b/dissect.c
index 300d5ca99c97..9419c5931fbb 100644
--- a/dissect.c
+++ b/dissect.c
@@ -212,6 +212,7 @@ static void examine_sym_node(struct symbol *node, struct symbol *parent)
while ((base = node->ctype.base_type) != NULL)
switch (base->type) {
case SYM_TYPEOF:
+ case SYM_TYPEOF_UNQUAL:
node->ctype.base_type =
do_expression(U_VOID, base->initializer);
break;
diff --git a/evaluate.c b/evaluate.c
index fe716f631987..85a6447ba3ce 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -358,7 +358,8 @@ static inline int classify_type(struct symbol *type, struct symbol **base)
};
if (type->type == SYM_NODE)
type = type->ctype.base_type;
- if (type->type == SYM_TYPEOF) {
+ if (type->type == SYM_TYPEOF ||
+ type->type == SYM_TYPEOF_UNQUAL) {
type = examine_symbol_type(type);
if (type->type == SYM_NODE)
type = type->ctype.base_type;
diff --git a/parse.c b/parse.c
index f868bf63a0f5..95894bf5e54d 100644
--- a/parse.c
+++ b/parse.c
@@ -54,7 +54,7 @@ static struct token *handle_attributes(struct token *token, struct decl_state *c
typedef struct token *declarator_t(struct token *, struct symbol *, struct decl_state *);
static declarator_t
struct_specifier, union_specifier, enum_specifier,
- attribute_specifier, typeof_specifier,
+ attribute_specifier, typeof_specifier, typeof_unqual_specifier,
storage_specifier, thread_specifier;
static declarator_t generic_qualifier;
static declarator_t autotype_specifier;
@@ -196,6 +196,13 @@ static struct symbol_op typeof_op = {
.set = Set_S|Set_T,
};
+static struct symbol_op typeof_unqual_op = {
+ .type = KW_SPECIFIER,
+ .declarator = typeof_unqual_specifier,
+ .test = Set_Any,
+ .set = Set_S|Set_T,
+};
+
static struct symbol_op autotype_op = {
.type = KW_SPECIFIER,
.declarator = autotype_specifier,
@@ -480,6 +487,7 @@ static struct init_keyword {
/* Typedef ... */
N("typedef", &typedef_op, .mods = MOD_USERTYPE),
A("typeof", &typeof_op),
+ A("typeof_unqual", &typeof_unqual_op),
N("__auto_type", &autotype_op),
/* Type qualifiers */
@@ -1052,7 +1060,7 @@ static struct token *enum_specifier(struct token *token, struct symbol *sym, str
return ret;
}
-static struct token *typeof_specifier(struct token *token, struct symbol *sym, struct decl_state *ctx)
+static struct token *typeof_specifier_helper(struct token *token, struct symbol *sym, struct decl_state *ctx, bool qual)
{
if (!match_op(token, '(')) {
@@ -1065,7 +1073,7 @@ static struct token *typeof_specifier(struct token *token, struct symbol *sym, s
ctx->ctype.base_type = sym->ctype.base_type;
apply_ctype(token->pos, &ctx->ctype, &sym->ctype);
} else {
- struct symbol *typeof_sym = alloc_symbol(token->pos, SYM_TYPEOF);
+ struct symbol *typeof_sym = alloc_symbol(token->pos, qual? SYM_TYPEOF : SYM_TYPEOF_UNQUAL);
token = parse_expression(token->next, &typeof_sym->initializer);
typeof_sym->endpos = token->pos;
@@ -1078,6 +1086,16 @@ static struct token *typeof_specifier(struct token *token, struct symbol *sym, s
return expect(token, ')', "after typeof");
}
+static struct token *typeof_specifier(struct token *token, struct symbol *sym, struct decl_state *ctx)
+{
+ return typeof_specifier_helper(token, sym, ctx, true);
+}
+
+static struct token *typeof_unqual_specifier(struct token *token, struct symbol *sym, struct decl_state *ctx)
+{
+ return typeof_specifier_helper(token, sym, ctx, false);
+}
+
static struct token *autotype_specifier(struct token *token, struct symbol *sym, struct decl_state *ctx)
{
ctx->ctype.base_type = &autotype_ctype;
diff --git a/show-parse.c b/show-parse.c
index e2fc18bb4b3d..ceb6b3cb6f82 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -59,6 +59,7 @@ static void do_debug_symbol(struct symbol *sym, int indent)
[SYM_UNION] = "unin",
[SYM_ENUM] = "enum",
[SYM_TYPEOF] = "tpof",
+ [SYM_TYPEOF_UNQUAL] = "tpof_unqual",
[SYM_BITFIELD] = "bitf",
[SYM_LABEL] = "labl",
[SYM_RESTRICT] = "rstr",
diff --git a/symbol.c b/symbol.c
index 91352a3a447b..7060acb666d9 100644
--- a/symbol.c
+++ b/symbol.c
@@ -541,7 +541,7 @@ static struct symbol *examine_pointer_type(struct symbol *sym)
return sym;
}
-static struct symbol *examine_typeof(struct symbol *sym)
+static struct symbol *examine_typeof_helper(struct symbol *sym, bool qual)
{
struct symbol *base = evaluate_expression(sym->initializer);
unsigned long mod = 0;
@@ -550,6 +550,8 @@ static struct symbol *examine_typeof(struct symbol *sym)
base = &bad_ctype;
if (base->type == SYM_NODE) {
mod |= base->ctype.modifiers & MOD_TYPEOF;
+ if (!qual)
+ mod &= ~MOD_QUALIFIER;
base = base->ctype.base_type;
}
if (base->type == SYM_BITFIELD)
@@ -560,6 +562,16 @@ static struct symbol *examine_typeof(struct symbol *sym)
return examine_node_type(sym);
}
+static struct symbol *examine_typeof(struct symbol *sym)
+{
+ return examine_typeof_helper(sym, true);
+}
+
+static struct symbol *examine_typeof_unqual(struct symbol *sym)
+{
+ return examine_typeof_helper(sym, false);
+}
+
/*
* Fill in type size and alignment information for
* regular SYM_TYPE things.
@@ -595,6 +607,8 @@ struct symbol *examine_symbol_type(struct symbol * sym)
return sym;
case SYM_TYPEOF:
return examine_typeof(sym);
+ case SYM_TYPEOF_UNQUAL:
+ return examine_typeof_unqual(sym);
case SYM_PREPROCESSOR:
sparse_error(sym->pos, "ctype on preprocessor command? (%s)", show_ident(sym->ident));
return NULL;
@@ -628,6 +642,7 @@ const char* get_type_name(enum type type)
[SYM_UNION] = "union",
[SYM_ENUM] = "enum",
[SYM_TYPEOF] = "typeof",
+ [SYM_TYPEOF_UNQUAL] = "typeof_unqual",
[SYM_BITFIELD] = "bitfield",
[SYM_LABEL] = "label",
[SYM_RESTRICT] = "restrict",
diff --git a/symbol.h b/symbol.h
index 88130c15d4bd..3552d4391621 100644
--- a/symbol.h
+++ b/symbol.h
@@ -65,6 +65,7 @@ enum type {
SYM_UNION,
SYM_ENUM,
SYM_TYPEOF,
+ SYM_TYPEOF_UNQUAL,
SYM_BITFIELD,
SYM_LABEL,
SYM_RESTRICT,
--
2.45.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2024-12-04 7:24 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-26 17:21 [PATCH 0/6] Enable strict percpu address space checks Uros Bizjak
2024-11-26 17:21 ` [PATCH 1/6] x86/kgdb: Use IS_ERR_PCPU() macro Uros Bizjak
2024-11-26 17:21 ` [PATCH 2/6] compiler.h: Introduce TYPEOF_UNQUAL() macro Uros Bizjak
2024-11-26 17:21 ` [PATCH 3/6] percpu: Use TYPEOF_UNQUAL() in variable declarations Uros Bizjak
2024-11-26 17:21 ` [PATCH 4/6] percpu: Use TYPEOF_UNQUAL() in *_cpu_ptr() accessors Uros Bizjak
2024-11-26 17:21 ` [PATCH 5/6] percpu: Repurpose __percpu tag as a named address space qualifier Uros Bizjak
2024-11-26 17:21 ` [PATCH 6/6] percpu/x86: Enable strict percpu checks via named AS qualifiers Uros Bizjak
2024-11-29 15:45 ` Nadav Amit
2024-11-29 16:33 ` Uros Bizjak
2024-12-04 7:24 ` [PATCH 0/6] Enable strict percpu address space checks Dan Carpenter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).