mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'objtool-urgent-2025-04-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull objtool fixes from Ingo Molnar:
"These are objtool fixes and updates by Josh Poimboeuf, centered around
the fallout from the new CONFIG_OBJTOOL_WERROR=y feature, which,
despite its default-off nature, increased the profile/impact of
objtool warnings:
- Improve error handling and the presentation of warnings/errors
- Revert the new summary warning line that some test-bot tools
interpreted as new regressions
- Fix a number of objtool warnings in various drivers, core kernel
code and architecture code. About half of them are potential
problems related to out-of-bounds accesses or potential undefined
behavior, the other half are additional objtool annotations
- Update objtool to latest (known) compiler quirks and objtool bugs
triggered by compiler code generation
- Misc fixes"
* tag 'objtool-urgent-2025-04-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (36 commits)
objtool/loongarch: Add unwind hints in prepare_frametrace()
rcu-tasks: Always inline rcu_irq_work_resched()
context_tracking: Always inline ct_{nmi,irq}_{enter,exit}()
sched/smt: Always inline sched_smt_active()
objtool: Fix verbose disassembly if CROSS_COMPILE isn't set
objtool: Change "warning:" to "error: " for fatal errors
objtool: Always fail on fatal errors
Revert "objtool: Increase per-function WARN_FUNC() rate limit"
objtool: Append "()" to function name in "unexpected end of section" warning
objtool: Ignore end-of-section jumps for KCOV/GCOV
objtool: Silence more KCOV warnings, part 2
objtool, drm/vmwgfx: Don't ignore vmw_send_msg() for ORC
objtool: Fix STACK_FRAME_NON_STANDARD for cold subfunctions
objtool: Fix segfault in ignore_unreachable_insn()
objtool: Fix NULL printf() '%s' argument in builtin-check.c:save_argv()
objtool, lkdtm: Obfuscate the do_nothing() pointer
objtool, regulator: rk808: Remove potential undefined behavior in rk806_set_mode_dcdc()
objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler()
objtool, Input: cyapa - Remove undefined behavior in cyapa_update_fw_store()
objtool, panic: Disable SMAP in __stack_chk_fail()
...
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <asm/asm.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/loongarch.h>
|
||||
#include <asm/unwind_hints.h>
|
||||
#include <linux/stringify.h>
|
||||
|
||||
enum stack_type {
|
||||
@@ -43,6 +44,7 @@ int get_stack_info(unsigned long stack, struct task_struct *task, struct stack_i
|
||||
static __always_inline void prepare_frametrace(struct pt_regs *regs)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
UNWIND_HINT_SAVE
|
||||
/* Save $ra */
|
||||
STORE_ONE_REG(1)
|
||||
/* Use $ra to save PC */
|
||||
@@ -80,6 +82,7 @@ static __always_inline void prepare_frametrace(struct pt_regs *regs)
|
||||
STORE_ONE_REG(29)
|
||||
STORE_ONE_REG(30)
|
||||
STORE_ONE_REG(31)
|
||||
UNWIND_HINT_RESTORE
|
||||
: "=m" (regs->csr_era)
|
||||
: "r" (regs->regs)
|
||||
: "memory");
|
||||
|
||||
@@ -23,6 +23,14 @@
|
||||
UNWIND_HINT sp_reg=ORC_REG_SP type=UNWIND_HINT_TYPE_CALL
|
||||
.endm
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#else /* !__ASSEMBLY__ */
|
||||
|
||||
#define UNWIND_HINT_SAVE \
|
||||
UNWIND_HINT(UNWIND_HINT_TYPE_SAVE, 0, 0, 0)
|
||||
|
||||
#define UNWIND_HINT_RESTORE \
|
||||
UNWIND_HINT(UNWIND_HINT_TYPE_RESTORE, 0, 0, 0)
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_LOONGARCH_UNWIND_HINTS_H */
|
||||
|
||||
@@ -16,7 +16,8 @@ static __always_inline unsigned int __arch_hweight32(unsigned int w)
|
||||
{
|
||||
unsigned int res;
|
||||
|
||||
asm_inline (ALTERNATIVE("call __sw_hweight32",
|
||||
asm_inline (ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE
|
||||
"call __sw_hweight32",
|
||||
"popcntl %[val], %[cnt]", X86_FEATURE_POPCNT)
|
||||
: [cnt] "=" REG_OUT (res), ASM_CALL_CONSTRAINT
|
||||
: [val] REG_IN (w));
|
||||
@@ -45,7 +46,8 @@ static __always_inline unsigned long __arch_hweight64(__u64 w)
|
||||
{
|
||||
unsigned long res;
|
||||
|
||||
asm_inline (ALTERNATIVE("call __sw_hweight64",
|
||||
asm_inline (ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE
|
||||
"call __sw_hweight64",
|
||||
"popcntq %[val], %[cnt]", X86_FEATURE_POPCNT)
|
||||
: [cnt] "=" REG_OUT (res), ASM_CALL_CONSTRAINT
|
||||
: [val] REG_IN (w));
|
||||
|
||||
@@ -16,23 +16,23 @@
|
||||
#ifdef __ASSEMBLER__
|
||||
|
||||
#define ASM_CLAC \
|
||||
ALTERNATIVE "", "clac", X86_FEATURE_SMAP
|
||||
ALTERNATIVE __stringify(ANNOTATE_IGNORE_ALTERNATIVE), "clac", X86_FEATURE_SMAP
|
||||
|
||||
#define ASM_STAC \
|
||||
ALTERNATIVE "", "stac", X86_FEATURE_SMAP
|
||||
ALTERNATIVE __stringify(ANNOTATE_IGNORE_ALTERNATIVE), "stac", X86_FEATURE_SMAP
|
||||
|
||||
#else /* __ASSEMBLER__ */
|
||||
|
||||
static __always_inline void clac(void)
|
||||
{
|
||||
/* Note: a barrier is implicit in alternative() */
|
||||
alternative("", "clac", X86_FEATURE_SMAP);
|
||||
alternative(ANNOTATE_IGNORE_ALTERNATIVE "", "clac", X86_FEATURE_SMAP);
|
||||
}
|
||||
|
||||
static __always_inline void stac(void)
|
||||
{
|
||||
/* Note: a barrier is implicit in alternative() */
|
||||
alternative("", "stac", X86_FEATURE_SMAP);
|
||||
alternative(ANNOTATE_IGNORE_ALTERNATIVE "", "stac", X86_FEATURE_SMAP);
|
||||
}
|
||||
|
||||
static __always_inline unsigned long smap_save(void)
|
||||
@@ -40,7 +40,8 @@ static __always_inline unsigned long smap_save(void)
|
||||
unsigned long flags;
|
||||
|
||||
asm volatile ("# smap_save\n\t"
|
||||
ALTERNATIVE("", "pushf; pop %0; " "clac" "\n\t",
|
||||
ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE
|
||||
"", "pushf; pop %0; clac",
|
||||
X86_FEATURE_SMAP)
|
||||
: "=rm" (flags) : : "memory", "cc");
|
||||
|
||||
@@ -50,16 +51,22 @@ static __always_inline unsigned long smap_save(void)
|
||||
static __always_inline void smap_restore(unsigned long flags)
|
||||
{
|
||||
asm volatile ("# smap_restore\n\t"
|
||||
ALTERNATIVE("", "push %0; popf\n\t",
|
||||
ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE
|
||||
"", "push %0; popf",
|
||||
X86_FEATURE_SMAP)
|
||||
: : "g" (flags) : "memory", "cc");
|
||||
}
|
||||
|
||||
/* These macros can be used in asm() statements */
|
||||
#define ASM_CLAC \
|
||||
ALTERNATIVE("", "clac", X86_FEATURE_SMAP)
|
||||
ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "", "clac", X86_FEATURE_SMAP)
|
||||
#define ASM_STAC \
|
||||
ALTERNATIVE("", "stac", X86_FEATURE_SMAP)
|
||||
ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "", "stac", X86_FEATURE_SMAP)
|
||||
|
||||
#define ASM_CLAC_UNSAFE \
|
||||
ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "clac", X86_FEATURE_SMAP)
|
||||
#define ASM_STAC_UNSAFE \
|
||||
ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "stac", X86_FEATURE_SMAP)
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
|
||||
@@ -231,14 +231,12 @@ static __always_inline void __xen_stac(void)
|
||||
* Suppress objtool seeing the STAC/CLAC and getting confused about it
|
||||
* calling random code with AC=1.
|
||||
*/
|
||||
asm volatile(ANNOTATE_IGNORE_ALTERNATIVE
|
||||
ASM_STAC ::: "memory", "flags");
|
||||
asm volatile(ASM_STAC_UNSAFE ::: "memory", "flags");
|
||||
}
|
||||
|
||||
static __always_inline void __xen_clac(void)
|
||||
{
|
||||
asm volatile(ANNOTATE_IGNORE_ALTERNATIVE
|
||||
ASM_CLAC ::: "memory", "flags");
|
||||
asm volatile(ASM_CLAC_UNSAFE ::: "memory", "flags");
|
||||
}
|
||||
|
||||
static inline long
|
||||
|
||||
@@ -289,7 +289,7 @@ static int vmw_send_msg(struct rpc_channel *channel, const char *msg)
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
STACK_FRAME_NON_STANDARD(vmw_send_msg);
|
||||
STACK_FRAME_NON_STANDARD_FP(vmw_send_msg);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1080,8 +1080,8 @@ static ssize_t cyapa_update_fw_store(struct device *dev,
|
||||
char fw_name[NAME_MAX];
|
||||
int ret, error;
|
||||
|
||||
if (count >= NAME_MAX) {
|
||||
dev_err(dev, "File name too long\n");
|
||||
if (!count || count >= NAME_MAX) {
|
||||
dev_err(dev, "Bad file name size\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -2701,8 +2701,11 @@ static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
|
||||
u8 ratio;
|
||||
|
||||
if (state->revision == 0x8090) {
|
||||
u32 internal = dib8000_read32(state, 23) / 1000;
|
||||
|
||||
ratio = 4;
|
||||
unit_khz_dds_val = (1<<26) / (dib8000_read32(state, 23) / 1000);
|
||||
|
||||
unit_khz_dds_val = (1<<26) / (internal ?: 1);
|
||||
if (offset_khz < 0)
|
||||
dds = (1 << 26) - (abs_offset_khz * unit_khz_dds_val);
|
||||
else
|
||||
|
||||
@@ -28,6 +28,13 @@ static const unsigned long rodata = 0xAA55AA55;
|
||||
/* This is marked __ro_after_init, so it should ultimately be .rodata. */
|
||||
static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
|
||||
|
||||
/*
|
||||
* This is a pointer to do_nothing() which is initialized at runtime rather
|
||||
* than build time to avoid objtool IBT validation warnings caused by an
|
||||
* inlined unrolled memcpy() in execute_location().
|
||||
*/
|
||||
static void __ro_after_init *do_nothing_ptr;
|
||||
|
||||
/*
|
||||
* This just returns to the caller. It is designed to be copied into
|
||||
* non-executable memory regions.
|
||||
@@ -65,13 +72,12 @@ static noinline __nocfi void execute_location(void *dst, bool write)
|
||||
{
|
||||
void (*func)(void);
|
||||
func_desc_t fdesc;
|
||||
void *do_nothing_text = dereference_function_descriptor(do_nothing);
|
||||
|
||||
pr_info("attempting ok execution at %px\n", do_nothing_text);
|
||||
pr_info("attempting ok execution at %px\n", do_nothing_ptr);
|
||||
do_nothing();
|
||||
|
||||
if (write == CODE_WRITE) {
|
||||
memcpy(dst, do_nothing_text, EXEC_SIZE);
|
||||
memcpy(dst, do_nothing_ptr, EXEC_SIZE);
|
||||
flush_icache_range((unsigned long)dst,
|
||||
(unsigned long)dst + EXEC_SIZE);
|
||||
}
|
||||
@@ -267,6 +273,8 @@ static void lkdtm_ACCESS_NULL(void)
|
||||
|
||||
void __init lkdtm_perms_init(void)
|
||||
{
|
||||
do_nothing_ptr = dereference_function_descriptor(do_nothing);
|
||||
|
||||
/* Make sure we can write to __ro_after_init values during __init */
|
||||
ro_after_init |= 0xAA;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ static int nvmet_ctrl_state_show(struct seq_file *m, void *p)
|
||||
bool sep = false;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(csts_state_names); i++) {
|
||||
int state = BIT(i);
|
||||
|
||||
if (!(ctrl->csts & state))
|
||||
|
||||
@@ -270,8 +270,8 @@ static const unsigned int rk817_buck1_4_ramp_table[] = {
|
||||
|
||||
static int rk806_set_mode_dcdc(struct regulator_dev *rdev, unsigned int mode)
|
||||
{
|
||||
int rid = rdev_get_id(rdev);
|
||||
int ctr_bit, reg;
|
||||
unsigned int rid = rdev_get_id(rdev);
|
||||
unsigned int ctr_bit, reg;
|
||||
|
||||
reg = RK806_POWER_FPWM_EN0 + rid / 8;
|
||||
ctr_bit = rid % 8;
|
||||
|
||||
@@ -302,7 +302,7 @@ static void amd_set_spi_freq(struct amd_spi *amd_spi, u32 speed_hz)
|
||||
{
|
||||
unsigned int i, spd7_val, alt_spd;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(amd_spi_freq); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(amd_spi_freq)-1; i++)
|
||||
if (speed_hz >= amd_spi_freq[i].speed_hz)
|
||||
break;
|
||||
|
||||
|
||||
@@ -10,12 +10,12 @@ void ct_irq_exit_irqson(void);
|
||||
void ct_nmi_enter(void);
|
||||
void ct_nmi_exit(void);
|
||||
#else
|
||||
static inline void ct_irq_enter(void) { }
|
||||
static inline void ct_irq_exit(void) { }
|
||||
static __always_inline void ct_irq_enter(void) { }
|
||||
static __always_inline void ct_irq_exit(void) { }
|
||||
static inline void ct_irq_enter_irqson(void) { }
|
||||
static inline void ct_irq_exit_irqson(void) { }
|
||||
static inline void ct_nmi_enter(void) { }
|
||||
static inline void ct_nmi_exit(void) { }
|
||||
static __always_inline void ct_nmi_enter(void) { }
|
||||
static __always_inline void ct_nmi_exit(void) { }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -134,10 +134,6 @@
|
||||
.size name, .-name
|
||||
#endif
|
||||
|
||||
/* If symbol 'name' is treated as a subroutine (gets called, and returns)
|
||||
* then please use ENDPROC to mark 'name' as STT_FUNC for the benefit of
|
||||
* static analysis tools such as stack depth analyzer.
|
||||
*/
|
||||
#ifndef ENDPROC
|
||||
/* deprecated, use SYM_FUNC_END */
|
||||
#define ENDPROC(name) \
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
* In asm, there are two kinds of code: normal C-type callable functions and
|
||||
* the rest. The normal callable functions can be called by other code, and
|
||||
* don't do anything unusual with the stack. Such normal callable functions
|
||||
* are annotated with the ENTRY/ENDPROC macros. Most asm code falls in this
|
||||
* are annotated with SYM_FUNC_{START,END}. Most asm code falls in this
|
||||
* category. In this case, no special debugging annotations are needed because
|
||||
* objtool can automatically generate the ORC data for the ORC unwinder to read
|
||||
* at runtime.
|
||||
|
||||
@@ -132,7 +132,7 @@ static inline void rcu_sysrq_end(void) { }
|
||||
#if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_KVM_XFER_TO_GUEST_WORK))
|
||||
void rcu_irq_work_resched(void);
|
||||
#else
|
||||
static inline void rcu_irq_work_resched(void) { }
|
||||
static __always_inline void rcu_irq_work_resched(void) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RCU_NOCB_CPU
|
||||
|
||||
@@ -12,7 +12,7 @@ static __always_inline bool sched_smt_active(void)
|
||||
return static_branch_likely(&sched_smt_present);
|
||||
}
|
||||
#else
|
||||
static inline bool sched_smt_active(void) { return false; }
|
||||
static __always_inline bool sched_smt_active(void) { return false; }
|
||||
#endif
|
||||
|
||||
void arch_smt_update(void);
|
||||
|
||||
@@ -833,9 +833,15 @@ device_initcall(register_warn_debugfs);
|
||||
*/
|
||||
__visible noinstr void __stack_chk_fail(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
instrumentation_begin();
|
||||
flags = user_access_save();
|
||||
|
||||
panic("stack-protector: Kernel stack is corrupted in: %pB",
|
||||
__builtin_return_address(0));
|
||||
|
||||
user_access_restore(flags);
|
||||
instrumentation_end();
|
||||
}
|
||||
EXPORT_SYMBOL(__stack_chk_fail);
|
||||
|
||||
@@ -275,9 +275,9 @@ objtool-args-$(CONFIG_MITIGATION_SLS) += --sls
|
||||
objtool-args-$(CONFIG_STACK_VALIDATION) += --stackval
|
||||
objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE) += --static-call
|
||||
objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION) += --uaccess
|
||||
objtool-args-$(CONFIG_GCOV_KERNEL) += --no-unreachable
|
||||
objtool-args-$(or $(CONFIG_GCOV_KERNEL),$(CONFIG_KCOV)) += --no-unreachable
|
||||
objtool-args-$(CONFIG_PREFIX_SYMBOLS) += --prefix=$(CONFIG_FUNCTION_PADDING_BYTES)
|
||||
objtool-args-$(CONFIG_OBJTOOL_WERROR) += --Werror --backtrace
|
||||
objtool-args-$(CONFIG_OBJTOOL_WERROR) += --Werror
|
||||
|
||||
objtool-args = $(objtool-args-y) \
|
||||
$(if $(delay-objtool), --link) \
|
||||
|
||||
@@ -30,13 +30,20 @@ endif
|
||||
# objtool for vmlinux.o
|
||||
# ---------------------------------------------------------------------------
|
||||
#
|
||||
# For LTO and IBT, objtool doesn't run on individual translation units.
|
||||
# Run everything on vmlinux instead.
|
||||
# For delay-objtool (IBT or LTO), objtool doesn't run on individual translation
|
||||
# units. Instead it runs on vmlinux.o.
|
||||
#
|
||||
# For !delay-objtool + CONFIG_NOINSTR_VALIDATION, it runs on both translation
|
||||
# units and vmlinux.o, with the latter only used for noinstr/unret validation.
|
||||
|
||||
objtool-enabled := $(or $(delay-objtool),$(CONFIG_NOINSTR_VALIDATION))
|
||||
|
||||
vmlinux-objtool-args-$(delay-objtool) += $(objtool-args-y)
|
||||
vmlinux-objtool-args-$(CONFIG_GCOV_KERNEL) += --no-unreachable
|
||||
ifeq ($(delay-objtool),y)
|
||||
vmlinux-objtool-args-y += $(objtool-args-y)
|
||||
else
|
||||
vmlinux-objtool-args-$(CONFIG_OBJTOOL_WERROR) += --Werror
|
||||
endif
|
||||
|
||||
vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION) += --noinstr \
|
||||
$(if $(or $(CONFIG_MITIGATION_UNRET_ENTRY),$(CONFIG_MITIGATION_SRSO)), --unret)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user