-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
clang-12 -fsanitize=array-bounds messes with __builtin_constant_p(): invalid asm #1310
Comments
Sent a workaround and some more explanation to the driver maintainers: https://lore.kernel.org/lkml/20210225094324.3542511-1-arnd@kernel.org/ |
clang-12 fails to build the etm4x driver with -fsanitize=array-bounds: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ It appears that the __builin_constant_p() check in read_etm4x_sysreg_offset() falsely returns 'true' here because clang decides finds that an out-of-bounds access to config->cntr_val[] cannot happen, and then it unrolls the loop with constant register numbers. Then when actually emitting the output, it fails to figure out the value again. While this is incorrect behavior in clang, it is easy to work around by avoiding the out-of-bounds array access. Do this by limiting the loop counter to the actual dimension of the array. Link: ClangBuiltLinux#1310 Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Is that the letter
https://godbolt.org/z/3PrzGe Was the reduced case over-reduced? Irrespective of the __builtin_constant_p, I'm curious if there's underlying inline asm we fail to parse. |
The underlying problem is passing a register number that is constant according to __builtin_constant_p() but not a literal. The original bug complains about this instruction:
where the long arithmetic operation is something that the compiler can evaluate to a constant expression at compile-time, but passing it into an inline assembly as a string breaks because 'reg' is not known to the assembler. The __builtin_constant_p() check works for all the other cases because the argument is usually either a number literal expanded from another macro, or a variable that is not known at compile time. This means the problem is a misuse of __builtin_constant_p() in the kernel that breaks in a few corner cases. |
Is there a config available to reproduce this issue? |
I can still reproduce it with the attached defconfig. I have sent a patch, but that was not accepted so far. I don't think there is anything clang can do to avoid this problem though, as the code in the driver is clearly fragile. One can either rewrite it more thoroughly to avoid the use of these macros (which will make the code slower) or fix it up every time the compiler runs into a corner case with the __builtin_constant_p(). https://lore.kernel.org/linux-arm-kernel/20210225094324.3542511-1-arnd@kernel.org/ |
Sent a new patch: https://lore.kernel.org/lkml/20210429145752.3218324-1-arnd@kernel.org/ |
clang-12 fails to build the etm4x driver with -fsanitize=array-bounds, where it decides to unroll certain loops in a way that result in a C variable getting put into an inline assembly <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ This only happened in a few loops in which the array bounds sanitizer added a special case for an array overflow that clang determined to be possible, but any compiler is free to unroll any of the loops in the same way that breaks the sysreg macros. Introduce helper functions that perform a sysreg access with a non-constant register number and use them in each call that passes a loop counter. Link: ClangBuiltLinux#1310 Link: https://lore.kernel.org/lkml/20210225094324.3542511-1-arnd@kernel.org/ Signed-off-by: Arnd Bergmann <arnd@arndb.de>
In #1625 I was able to determine that this is reproducible with: $ ARCH=arm64 make LLVM=1 -j72 defconfig
$ ./scripts/config -e CONFIG_CORESIGHT -e CONFIG_CORESIGHT_SOURCE_ETM4X -e UBSAN -e UBSAN_TRAP
$ ARCH=arm64 make LLVM=1 -j72 olddefconfig drivers/hwtracing/coresight/coresight-etm4x-core.o @arndb was there ever a v3? |
Looks like someone else sent a v3, but that also had feedback that AFAICT was never followed up on. |
When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construction inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Replace unsafe uses of calls to etm4x_relaxed_read32 with csdev_access_read32 when the parameter is an expression that would be invalid inline asm so that it does not depend on the ability of the compiler to optimize __builtin_constant_p of the expression to true. Only when the second parameter of etm4x_relaxed_read32 expands to an expression dependent on a loop induction variable do we need to fix this. This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux#1310 Suggested-by: Arnd Bergmann <arnd@kernel.org> Suggested-by: Tao Zhang <quic_taozha@quicinc.com> Suggested-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org> (cherry picked from commit 1693fe9ba2ef4add6d7cfa71154be48eb9ee72ff) Signed-off-by: Jack Vogel <jack.vogel@oracle.com>
BugLink: https://bugs.launchpad.net/bugs/1990564 [ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Kamal Mostafa <kamal@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
BugLink: https://bugs.launchpad.net/bugs/1990564 [ Upstream commit 4d45bc8 ] When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Kamal Mostafa <kamal@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
mainline inclusion from mainline-v5.19-rc3 commit 4d45bc8 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5YCYK CVE: NA Reference: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com -------------------------------------------------------------------------- When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com
mainline inclusion from mainline-v5.19-rc3 commit 4d45bc8 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5YCYK CVE: NA Reference: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com -------------------------------------------------------------------------- When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com
JIRA: https://issues.redhat.com/browse/RHEL-21456 commit 4d45bc82df667ad9e9cb8361830e54fc1264e993 Author: Nick Desaulniers <ndesaulniers@google.com> Date: Fri, 8 Jul 2022 16:15:20 -0700 When the following configs are enabled: * CORESIGHT * CORESIGHT_SOURCE_ETM4X * UBSAN * UBSAN_TRAP Clang fails assemble the kernel with the error: <instantiation>:1:7: error: expected constant expression in '.inst' directive .inst (0xd5200000|((((2) << 19) | ((1) << 16) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 7) & 0x7)) << 12) | ((((((((((0x160 + (i * 4))))) >> 2))) & 0xf)) << 8) | (((((((((((0x160 + (i * 4))))) >> 2))) >> 4) & 0x7)) << 5)))|(.L__reg_num_x8)) ^ drivers/hwtracing/coresight/coresight-etm4x-core.c:702:4: note: while in macro instantiation etm4x_relaxed_read32(csa, TRCCNTVRn(i)); ^ drivers/hwtracing/coresight/coresight-etm4x.h:403:4: note: expanded from macro 'etm4x_relaxed_read32' read_etm4x_sysreg_offset((offset), false))) ^ drivers/hwtracing/coresight/coresight-etm4x.h:383:12: note: expanded from macro 'read_etm4x_sysreg_offset' __val = read_etm4x_sysreg_const_offset((offset)); \ ^ drivers/hwtracing/coresight/coresight-etm4x.h:149:2: note: expanded from macro 'read_etm4x_sysreg_const_offset' READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset)) ^ drivers/hwtracing/coresight/coresight-etm4x.h:144:2: note: expanded from macro 'READ_ETM4x_REG' read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg))) ^ arch/arm64/include/asm/sysreg.h:1108:15: note: expanded from macro 'read_sysreg_s' asm volatile(__mrs_s("%0", r) : "=r" (__val)); \ ^ arch/arm64/include/asm/sysreg.h:1074:2: note: expanded from macro '__mrs_s' " mrs_s " v ", " __stringify(r) "\n" \ ^ Consider the definitions of TRCSSCSRn and TRCCNTVRn: drivers/hwtracing/coresight/coresight-etm4x.h:56 #define TRCCNTVRn(n) (0x160 + (n * 4)) drivers/hwtracing/coresight/coresight-etm4x.h:81 #define TRCSSCSRn(n) (0x2A0 + (n * 4)) Where the macro parameter is expanded to i; a loop induction variable from etm4_disable_hw. When any compiler can determine that loops may be unrolled, then the __builtin_constant_p check in read_etm4x_sysreg_offset() defined in drivers/hwtracing/coresight/coresight-etm4x.h may evaluate to true. This can lead to the expression `(0x160 + (i * 4))` being passed to read_etm4x_sysreg_const_offset. Via the trace above, this is passed through READ_ETM4x_REG, read_sysreg_s, and finally to __mrs_s where it is string-ified and used directly in inline asm. Regardless of which compiler or compiler options determine whether a loop can or can't be unrolled, which determines whether __builtin_constant_p evaluates to true when passed an expression using a loop induction variable, it is NEVER safe to allow the preprocessor to construct inline asm like: asm volatile (".inst (0x160 + (i * 4))" : "=r"(__val)); ^ expected constant expression Instead of read_etm4x_sysreg_offset() using __builtin_constant_p(), use __is_constexpr from include/linux/const.h instead to ensure only expressions that are valid integer constant expressions get passed through to read_sysreg_s(). This is not a bug in clang; it's a potentially unsafe use of the macro arguments in read_etm4x_sysreg_offset dependent on __builtin_constant_p. Link: ClangBuiltLinux/linux#1310 Reported-by: Arnd Bergmann <arnd@kernel.org> Reported-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20220708231520.3958391-1-ndesaulniers@google.com Signed-off-by: Mark Salter <msalter@redhat.com>
Some randconfig kernel builds result in an incorrect asm instruction based on a .insn directive with a non-constant value
This comes from a deeply nested macro in the coresight kernel driver, but I reduced it to
The problem happens with clang-12 and clang-13, but I could not reproduce it with clang-11.
https://godbolt.org/z/bKMsno
The text was updated successfully, but these errors were encountered: