v2:
- improve commit logs
- reorder patches: patches 1-6 are prereqs for patch 7
Add some more __noreturn annotations.
Many of these have been flushed out by kernel IBT support which made
objtool vmlinux validation much more common.
These annotations are generally a good thing as they improve readability
and code generation.
Guilherme G. Piccoli (1):
x86/hyperv: Mark hv_ghcb_terminate() as noreturn
Josh Poimboeuf (10):
init: Mark [arch_call_]rest_init() __noreturn
init: Mark start_kernel() __noreturn
x86/head: Mark *_start_kernel() __noreturn
arm64/cpu: Mark cpu_park_loop() and friends __noreturn
cpu: Mark panic_smp_self_stop() __noreturn
cpu: Mark nmi_panic_self_stop() __noreturn
objtool: Include weak functions in global_noreturns check
btrfs: Mark btrfs_assertfail() __noreturn
x86/cpu: Mark {hlt,resume}_play_dead() __noreturn
scsi: message: fusion: Mark mpt_halt_firmware() __noreturn
arch/arm/kernel/smp.c | 2 +-
arch/arm64/include/asm/exception.h | 4 ++--
arch/arm64/include/asm/smp.h | 7 +++----
arch/arm64/kernel/entry-common.c | 2 +-
arch/arm64/kernel/smp.c | 10 ++++++----
arch/arm64/kernel/traps.c | 3 +--
arch/powerpc/kernel/setup_64.c | 2 +-
arch/s390/kernel/setup.c | 2 +-
arch/x86/hyperv/ivm.c | 2 +-
arch/x86/include/asm/mshyperv.h | 2 +-
arch/x86/include/asm/reboot.h | 1 -
arch/x86/include/asm/setup.h | 6 +++---
arch/x86/include/asm/smp.h | 2 +-
arch/x86/kernel/head32.c | 2 +-
arch/x86/kernel/head64.c | 4 ++--
arch/x86/kernel/reboot.c | 2 +-
arch/x86/kernel/smpboot.c | 2 +-
arch/x86/power/cpu.c | 2 +-
drivers/message/fusion/mptbase.c | 2 +-
drivers/message/fusion/mptbase.h | 2 +-
fs/btrfs/messages.c | 2 +-
fs/btrfs/messages.h | 2 +-
include/linux/smp.h | 4 ++--
include/linux/start_kernel.h | 6 +++---
init/main.c | 6 +++---
kernel/panic.c | 4 ++--
tools/objtool/check.c | 20 ++++++++++++++++----
27 files changed, 58 insertions(+), 47 deletions(-)
--
2.39.2
In preparation for marking panic_smp_self_stop() __noreturn across the
kernel, first mark the arm64 implementation of cpu_park_loop() and
related functions __noreturn.
Signed-off-by: Josh Poimboeuf <[email protected]>
---
arch/arm64/include/asm/exception.h | 4 ++--
arch/arm64/include/asm/smp.h | 6 +++---
arch/arm64/kernel/entry-common.c | 2 +-
arch/arm64/kernel/smp.c | 8 +++++---
arch/arm64/kernel/traps.c | 3 +--
5 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index 92963f98afec..e73af709cb7a 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -31,7 +31,7 @@ static inline unsigned long disr_to_esr(u64 disr)
return esr;
}
-asmlinkage void handle_bad_stack(struct pt_regs *regs);
+asmlinkage void __noreturn handle_bad_stack(struct pt_regs *regs);
asmlinkage void el1t_64_sync_handler(struct pt_regs *regs);
asmlinkage void el1t_64_irq_handler(struct pt_regs *regs);
@@ -80,5 +80,5 @@ void do_el1_fpac(struct pt_regs *regs, unsigned long esr);
void do_serror(struct pt_regs *regs, unsigned long esr);
void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags);
-void panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigned long far);
+void __noreturn panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigned long far);
#endif /* __ASM_EXCEPTION_H */
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 5733a31bab08..07f4ea1490f4 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -101,9 +101,9 @@ extern int __cpu_disable(void);
extern void __cpu_die(unsigned int cpu);
extern void __noreturn cpu_die(void);
-extern void cpu_die_early(void);
+extern void __noreturn cpu_die_early(void);
-static inline void cpu_park_loop(void)
+static inline void __noreturn cpu_park_loop(void)
{
for (;;) {
wfe();
@@ -123,7 +123,7 @@ static inline void update_cpu_boot_status(int val)
* which calls for a kernel panic. Update the boot status and park the calling
* CPU.
*/
-static inline void cpu_panic_kernel(void)
+static inline void __noreturn cpu_panic_kernel(void)
{
update_cpu_boot_status(CPU_PANIC_KERNEL);
cpu_park_loop();
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index cce1167199e3..3af3c01c93a6 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -840,7 +840,7 @@ UNHANDLED(el0t, 32, error)
#endif /* CONFIG_COMPAT */
#ifdef CONFIG_VMAP_STACK
-asmlinkage void noinstr handle_bad_stack(struct pt_regs *regs)
+asmlinkage void noinstr __noreturn handle_bad_stack(struct pt_regs *regs)
{
unsigned long esr = read_sysreg(esr_el1);
unsigned long far = read_sysreg(far_el1);
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index d5d09a18b4f8..07d156fddb5f 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -398,7 +398,7 @@ static void __cpu_try_die(int cpu)
* Kill the calling secondary CPU, early in bringup before it is turned
* online.
*/
-void cpu_die_early(void)
+void __noreturn cpu_die_early(void)
{
int cpu = smp_processor_id();
@@ -816,7 +816,7 @@ void arch_irq_work_raise(void)
}
#endif
-static void local_cpu_stop(void)
+static void __noreturn local_cpu_stop(void)
{
set_cpu_online(smp_processor_id(), false);
@@ -839,7 +839,7 @@ void panic_smp_self_stop(void)
static atomic_t waiting_for_crash_ipi = ATOMIC_INIT(0);
#endif
-static void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
+static void __noreturn ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
{
#ifdef CONFIG_KEXEC_CORE
crash_save_cpu(regs, cpu);
@@ -854,6 +854,8 @@ static void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
/* just in case */
cpu_park_loop();
+#else
+ BUG();
#endif
}
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 4a79ba100799..4bb1b8f47298 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -863,7 +863,7 @@ void bad_el0_sync(struct pt_regs *regs, int reason, unsigned long esr)
DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack)
__aligned(16);
-void panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigned long far)
+void __noreturn panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigned long far)
{
unsigned long tsk_stk = (unsigned long)current->stack;
unsigned long irq_stk = (unsigned long)this_cpu_read(irq_stack_ptr);
@@ -905,7 +905,6 @@ void __noreturn arm64_serror_panic(struct pt_regs *regs, unsigned long esr)
nmi_panic(regs, "Asynchronous SError Interrupt");
cpu_park_loop();
- unreachable();
}
bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned long esr)
--
2.39.2
If a global function doesn't return, and its prototype has the
__noreturn attribute, its weak counterpart must also not return so that
it matches the prototype and meets call site expectations.
To properly follow the compiled control flow at the call sites, change
the global_noreturns check to include both global and weak functions.
On the other hand, if a weak function isn't in global_noreturns, assume
the prototype doesn't have __noreturn. Even if the weak function
doesn't return, call sites treat it like a returnable function.
Fixes the following warning:
kernel/sched/build_policy.o: warning: objtool: do_idle() falls through to next function play_idle_precise()
Reported-by: kernel test robot <[email protected]>
Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
Signed-off-by: Josh Poimboeuf <[email protected]>
---
tools/objtool/check.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index ed42717463f9..94c16436d990 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -236,14 +236,14 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
if (!func)
return false;
- if (func->bind == STB_WEAK)
- return false;
-
- if (func->bind == STB_GLOBAL)
+ if (func->bind == STB_GLOBAL || func->bind == STB_WEAK)
for (i = 0; i < ARRAY_SIZE(global_noreturns); i++)
if (!strcmp(func->name, global_noreturns[i]))
return true;
+ if (func->bind == STB_WEAK)
+ return false;
+
if (!func->len)
return false;
--
2.39.2
In preparation for improving objtool's handling of weak noreturn
functions, mark nmi_panic_self_stop() __noreturn.
Signed-off-by: Josh Poimboeuf <[email protected]>
---
arch/x86/include/asm/reboot.h | 1 -
arch/x86/kernel/reboot.c | 2 +-
include/linux/smp.h | 2 +-
kernel/panic.c | 2 +-
tools/objtool/check.c | 1 +
5 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h
index bc5b4d788c08..9177b4354c3f 100644
--- a/arch/x86/include/asm/reboot.h
+++ b/arch/x86/include/asm/reboot.h
@@ -28,7 +28,6 @@ void __noreturn machine_real_restart(unsigned int type);
void cpu_emergency_disable_virtualization(void);
typedef void (*nmi_shootdown_cb)(int, struct pt_regs*);
-void nmi_panic_self_stop(struct pt_regs *regs);
void nmi_shootdown_cpus(nmi_shootdown_cb callback);
void run_crash_ipi_callback(struct pt_regs *regs);
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index d03c551defcc..3adbe97015c1 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -920,7 +920,7 @@ void run_crash_ipi_callback(struct pt_regs *regs)
}
/* Override the weak function in kernel/panic.c */
-void nmi_panic_self_stop(struct pt_regs *regs)
+void __noreturn nmi_panic_self_stop(struct pt_regs *regs)
{
while (1) {
/* If no CPU is preparing crash dump, we simply loop here. */
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 2a737b39cf0a..7b93504eed26 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -60,7 +60,7 @@ int smp_call_function_single_async(int cpu, struct __call_single_data *csd);
* Architecture-dependent code may override them.
*/
void __noreturn panic_smp_self_stop(void);
-void nmi_panic_self_stop(struct pt_regs *regs);
+void __noreturn nmi_panic_self_stop(struct pt_regs *regs);
void crash_smp_send_stop(void);
/*
diff --git a/kernel/panic.c b/kernel/panic.c
index 5e4982db8dc9..886d2ebd0a0d 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -151,7 +151,7 @@ void __weak __noreturn panic_smp_self_stop(void)
* Stop ourselves in NMI context if another CPU has already panicked. Arch code
* may override this to prepare for crash dumping, e.g. save regs info.
*/
-void __weak nmi_panic_self_stop(struct pt_regs *regs)
+void __weak __noreturn nmi_panic_self_stop(struct pt_regs *regs)
{
panic_smp_self_stop();
}
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 43946188cd2c..ed42717463f9 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -217,6 +217,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"lbug_with_loc",
"machine_real_restart",
"make_task_dead",
+ "nmi_panic_self_stop",
"panic",
"panic_smp_self_stop",
"rest_init",
--
2.39.2
mpt_halt_firmware() doesn't return. Mark it as such.
Fixes the following warnings:
vmlinux.o: warning: objtool: mptscsih_abort+0x7f4: unreachable instruction
vmlinux.o: warning: objtool: mptctl_timeout_expired+0x310: unreachable instruction
Reported-by: kernel test robot <[email protected]>
Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
Reported-by: Mark Rutland <[email protected]>
Debugged-by: Peter Zijlstra <[email protected]>
Signed-off-by: Josh Poimboeuf <[email protected]>
---
drivers/message/fusion/mptbase.c | 2 +-
drivers/message/fusion/mptbase.h | 2 +-
tools/objtool/check.c | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 9b3ba2df71c7..4f0afce8428d 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -6935,7 +6935,7 @@ EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
* @ioc: Pointer to MPT_ADAPTER structure
*
**/
-void
+void __noreturn
mpt_halt_firmware(MPT_ADAPTER *ioc)
{
u32 ioc_raw_state;
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 4bd0682c65d3..0f226cdad64f 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -945,7 +945,7 @@ extern int mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc,
u8 phys_disk_num);
extern int mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc);
extern void mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc);
-extern void mpt_halt_firmware(MPT_ADAPTER *ioc);
+extern void __noreturn mpt_halt_firmware(MPT_ADAPTER *ioc);
/*
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index a42a2af99ea2..8586d4c36600 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -219,6 +219,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"lbug_with_loc",
"machine_real_restart",
"make_task_dead",
+ "mpt_halt_firmware",
"nmi_panic_self_stop",
"panic",
"panic_smp_self_stop",
--
2.39.2
In preparation for improving objtool's handling of weak noreturn
functions, mark panic_smp_self_stop() __noreturn.
Signed-off-by: Josh Poimboeuf <[email protected]>
---
arch/arm/kernel/smp.c | 2 +-
arch/arm64/include/asm/smp.h | 1 -
arch/arm64/kernel/smp.c | 2 +-
arch/powerpc/kernel/setup_64.c | 2 +-
include/linux/smp.h | 2 +-
kernel/panic.c | 2 +-
tools/objtool/check.c | 1 +
7 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index d6be4507d22d..f4a4ac028b6b 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -779,7 +779,7 @@ void smp_send_stop(void)
* kdump fails. So split out the panic_smp_self_stop() and add
* set_cpu_online(smp_processor_id(), false).
*/
-void panic_smp_self_stop(void)
+void __noreturn panic_smp_self_stop(void)
{
pr_debug("CPU %u will stop doing anything useful since another CPU has paniced\n",
smp_processor_id());
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 07f4ea1490f4..f2d26235bfb4 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -143,7 +143,6 @@ bool cpus_are_stuck_in_kernel(void);
extern void crash_smp_send_stop(void);
extern bool smp_crash_stop_failed(void);
-extern void panic_smp_self_stop(void);
#endif /* ifndef __ASSEMBLY__ */
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 07d156fddb5f..05fe797e4203 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -830,7 +830,7 @@ static void __noreturn local_cpu_stop(void)
* that cpu_online_mask gets correctly updated and smp_send_stop() can skip
* CPUs that have already stopped themselves.
*/
-void panic_smp_self_stop(void)
+void __noreturn panic_smp_self_stop(void)
{
local_cpu_stop();
}
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index b2e0d3ce4261..246201d0d879 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -480,7 +480,7 @@ void early_setup_secondary(void)
#endif /* CONFIG_SMP */
-void panic_smp_self_stop(void)
+void __noreturn panic_smp_self_stop(void)
{
hard_irq_disable();
spin_begin();
diff --git a/include/linux/smp.h b/include/linux/smp.h
index a80ab58ae3f1..2a737b39cf0a 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -59,7 +59,7 @@ int smp_call_function_single_async(int cpu, struct __call_single_data *csd);
* Cpus stopping functions in panic. All have default weak definitions.
* Architecture-dependent code may override them.
*/
-void panic_smp_self_stop(void);
+void __noreturn panic_smp_self_stop(void);
void nmi_panic_self_stop(struct pt_regs *regs);
void crash_smp_send_stop(void);
diff --git a/kernel/panic.c b/kernel/panic.c
index 5cfea8302d23..5e4982db8dc9 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -141,7 +141,7 @@ EXPORT_SYMBOL(panic_blink);
/*
* Stop ourself in panic -- architecture code may override this
*/
-void __weak panic_smp_self_stop(void)
+void __weak __noreturn panic_smp_self_stop(void)
{
while (1)
cpu_relax();
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 4e89342dd8fb..43946188cd2c 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -218,6 +218,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"machine_real_restart",
"make_task_dead",
"panic",
+ "panic_smp_self_stop",
"rest_init",
"rewind_stack_and_make_dead",
"sev_es_terminate",
--
2.39.2
Now that start_kernel() is __noreturn, mark its chain of callers
__noreturn.
Signed-off-by: Josh Poimboeuf <[email protected]>
---
arch/x86/include/asm/setup.h | 6 +++---
arch/x86/kernel/head32.c | 2 +-
arch/x86/kernel/head64.c | 4 ++--
tools/objtool/check.c | 2 ++
4 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index f37cbff7354c..f3495623ac99 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -125,11 +125,11 @@ void clear_bss(void);
#ifdef __i386__
-asmlinkage void __init i386_start_kernel(void);
+asmlinkage void __init __noreturn i386_start_kernel(void);
#else
-asmlinkage void __init x86_64_start_kernel(char *real_mode);
-asmlinkage void __init x86_64_start_reservations(char *real_mode_data);
+asmlinkage void __init __noreturn x86_64_start_kernel(char *real_mode);
+asmlinkage void __init __noreturn x86_64_start_reservations(char *real_mode_data);
#endif /* __i386__ */
#endif /* _SETUP */
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index ec6fefbfd3c0..10c27b4261eb 100644
--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -29,7 +29,7 @@ static void __init i386_default_early_setup(void)
x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc;
}
-asmlinkage __visible void __init i386_start_kernel(void)
+asmlinkage __visible void __init __noreturn i386_start_kernel(void)
{
/* Make sure IDT is set up before any exception happens */
idt_setup_early_handler();
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 387e4b12e823..49f7629b17f7 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -471,7 +471,7 @@ static void __init copy_bootdata(char *real_mode_data)
sme_unmap_bootdata(real_mode_data);
}
-asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
+asmlinkage __visible void __init __noreturn x86_64_start_kernel(char * real_mode_data)
{
/*
* Build-time sanity checks on the kernel image and module
@@ -537,7 +537,7 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
x86_64_start_reservations(real_mode_data);
}
-void __init x86_64_start_reservations(char *real_mode_data)
+void __init __noreturn x86_64_start_reservations(char *real_mode_data)
{
/* version is always not zero if it is copied */
if (!boot_params.hdr.version)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index a6f9a4aeb77b..4e89342dd8fb 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -225,6 +225,8 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"start_kernel",
"stop_this_cpu",
"usercopy_abort",
+ "x86_64_start_kernel",
+ "x86_64_start_reservations",
"xen_cpu_bringup_again",
"xen_start_kernel",
};
--
2.39.2
From: "Guilherme G. Piccoli" <[email protected]>
Annotate the function prototype and definition as noreturn to prevent
objtool warnings like:
vmlinux.o: warning: objtool: hyperv_init+0x55c: unreachable instruction
Also, as per Josh's suggestion, add it to the global_noreturns list.
As a comparison, an objdump output without the annotation:
[...]
1b63: mov $0x1,%esi
1b68: xor %edi,%edi
1b6a: callq ffffffff8102f680 <hv_ghcb_terminate>
1b6f: jmpq ffffffff82f217ec <hyperv_init+0x9c> # unreachable
1b74: cmpq $0xffffffffffffffff,-0x702a24(%rip)
[...]
Now, after adding the __noreturn to the function prototype:
[...]
17df: callq ffffffff8102f6d0 <hv_ghcb_negotiate_protocol>
17e4: test %al,%al
17e6: je ffffffff82f21bb9 <hyperv_init+0x469>
[...] <many insns>
1bb9: mov $0x1,%esi
1bbe: xor %edi,%edi
1bc0: callq ffffffff8102f680 <hv_ghcb_terminate>
1bc5: nopw %cs:0x0(%rax,%rax,1) # end of function
Reported-by: Arnd Bergmann <[email protected]>
Link: https://lore.kernel.org/r/[email protected]/
Signed-off-by: Guilherme G. Piccoli <[email protected]>
Reviewed-by: Michael Kelley <[email protected]>
Signed-off-by: Josh Poimboeuf <[email protected]>
---
arch/x86/hyperv/ivm.c | 2 +-
arch/x86/include/asm/mshyperv.h | 2 +-
tools/objtool/check.c | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index 1dbcbd9da74d..4f79dc76042d 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -127,7 +127,7 @@ static enum es_result hv_ghcb_hv_call(struct ghcb *ghcb, u64 exit_code,
return ES_OK;
}
-void hv_ghcb_terminate(unsigned int set, unsigned int reason)
+void __noreturn hv_ghcb_terminate(unsigned int set, unsigned int reason)
{
u64 val = GHCB_MSR_TERM_REQ;
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 4c4c0ec3b62e..09c26e658bcc 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -212,7 +212,7 @@ int hv_set_mem_host_visibility(unsigned long addr, int numpages, bool visible);
void hv_ghcb_msr_write(u64 msr, u64 value);
void hv_ghcb_msr_read(u64 msr, u64 *value);
bool hv_ghcb_negotiate_protocol(void);
-void hv_ghcb_terminate(unsigned int set, unsigned int reason);
+void __noreturn hv_ghcb_terminate(unsigned int set, unsigned int reason);
#else
static inline void hv_ghcb_msr_write(u64 msr, u64 value) {}
static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {}
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 8586d4c36600..e23d12041be0 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -213,6 +213,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"ex_handler_msr_mce",
"fortify_panic",
"hlt_play_dead",
+ "hv_ghcb_terminate",
"kthread_complete_and_exit",
"kthread_exit",
"kunit_try_catch_throw",
--
2.39.2
Fixes the following warning:
vmlinux.o: warning: objtool: resume_play_dead+0x21: unreachable instruction
Reported-by: kernel test robot <[email protected]>
Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
Signed-off-by: Josh Poimboeuf <[email protected]>
---
arch/x86/include/asm/smp.h | 2 +-
arch/x86/kernel/smpboot.c | 2 +-
arch/x86/power/cpu.c | 2 +-
tools/objtool/check.c | 2 ++
4 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index e6d1d2810e38..47ce4c79a3b0 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -125,7 +125,7 @@ int native_cpu_up(unsigned int cpunum, struct task_struct *tidle);
int native_cpu_disable(void);
int common_cpu_die(unsigned int cpu);
void native_cpu_die(unsigned int cpu);
-void hlt_play_dead(void);
+void __noreturn hlt_play_dead(void);
void native_play_dead(void);
void play_dead_common(void);
void wbinvd_on_cpu(int cpu);
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 9013bb28255a..a6da3f94b7b6 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1816,7 +1816,7 @@ static inline void mwait_play_dead(void)
}
}
-void hlt_play_dead(void)
+void __noreturn hlt_play_dead(void)
{
if (__this_cpu_read(cpu_info.x86) >= 4)
wbinvd();
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 236447ee9beb..7a4d5e911415 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -288,7 +288,7 @@ EXPORT_SYMBOL(restore_processor_state);
#endif
#if defined(CONFIG_HIBERNATION) && defined(CONFIG_HOTPLUG_CPU)
-static void resume_play_dead(void)
+static void __noreturn resume_play_dead(void)
{
play_dead_common();
tboot_shutdown(TB_SHUTDOWN_WFS);
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 0b3522d66ddf..a42a2af99ea2 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -212,6 +212,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"do_task_dead",
"ex_handler_msr_mce",
"fortify_panic",
+ "hlt_play_dead",
"kthread_complete_and_exit",
"kthread_exit",
"kunit_try_catch_throw",
@@ -222,6 +223,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"panic",
"panic_smp_self_stop",
"rest_init",
+ "resume_play_dead",
"rewind_stack_and_make_dead",
"sev_es_terminate",
"snp_abort",
--
2.39.2
Fixes a bunch of warnings including:
vmlinux.o: warning: objtool: select_reloc_root+0x314: unreachable instruction
vmlinux.o: warning: objtool: finish_inode_if_needed+0x15b1: unreachable instruction
vmlinux.o: warning: objtool: get_bio_sector_nr+0x259: unreachable instruction
vmlinux.o: warning: objtool: raid_wait_read_end_io+0xc26: unreachable instruction
vmlinux.o: warning: objtool: raid56_parity_alloc_scrub_rbio+0x37b: unreachable instruction
...
Reported-by: kernel test robot <[email protected]>
Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
Signed-off-by: Josh Poimboeuf <[email protected]>
---
fs/btrfs/messages.c | 2 +-
fs/btrfs/messages.h | 2 +-
tools/objtool/check.c | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/messages.c b/fs/btrfs/messages.c
index fde5aaa6e7c9..310a05cf95ef 100644
--- a/fs/btrfs/messages.c
+++ b/fs/btrfs/messages.c
@@ -253,7 +253,7 @@ void __cold _btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt,
#endif
#ifdef CONFIG_BTRFS_ASSERT
-void __cold btrfs_assertfail(const char *expr, const char *file, int line)
+void __cold __noreturn btrfs_assertfail(const char *expr, const char *file, int line)
{
pr_err("assertion failed: %s, in %s:%d\n", expr, file, line);
BUG();
diff --git a/fs/btrfs/messages.h b/fs/btrfs/messages.h
index 8c516ee58ff9..ac2d1982ba3d 100644
--- a/fs/btrfs/messages.h
+++ b/fs/btrfs/messages.h
@@ -160,7 +160,7 @@ do { \
} while (0)
#ifdef CONFIG_BTRFS_ASSERT
-void __cold btrfs_assertfail(const char *expr, const char *file, int line);
+void __cold __noreturn btrfs_assertfail(const char *expr, const char *file, int line);
#define ASSERT(expr) \
(likely(expr) ? (void)0 : btrfs_assertfail(#expr, __FILE__, __LINE__))
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 94c16436d990..0b3522d66ddf 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -204,6 +204,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"__ubsan_handle_builtin_unreachable",
"arch_call_rest_init",
"arch_cpu_idle_dead",
+ "btrfs_assertfail",
"cpu_bringup_and_idle",
"cpu_startup_entry",
"do_exit",
--
2.39.2
On Wed, Apr 12, 2023 at 04:49:38PM -0700, Josh Poimboeuf wrote:
> Fixes a bunch of warnings including:
>
> vmlinux.o: warning: objtool: select_reloc_root+0x314: unreachable instruction
> vmlinux.o: warning: objtool: finish_inode_if_needed+0x15b1: unreachable instruction
> vmlinux.o: warning: objtool: get_bio_sector_nr+0x259: unreachable instruction
> vmlinux.o: warning: objtool: raid_wait_read_end_io+0xc26: unreachable instruction
> vmlinux.o: warning: objtool: raid56_parity_alloc_scrub_rbio+0x37b: unreachable instruction
> ...
>
> Reported-by: kernel test robot <[email protected]>
> Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
> Signed-off-by: Josh Poimboeuf <[email protected]>
I'll add this one to btrfs queue, thanks.
On Wed, 12 Apr 2023, Josh Poimboeuf wrote:
> If a global function doesn't return, and its prototype has the
> __noreturn attribute, its weak counterpart must also not return so that
> it matches the prototype and meets call site expectations.
>
> To properly follow the compiled control flow at the call sites, change
> the global_noreturns check to include both global and weak functions.
>
> On the other hand, if a weak function isn't in global_noreturns, assume
> the prototype doesn't have __noreturn. Even if the weak function
> doesn't return, call sites treat it like a returnable function.
>
> Fixes the following warning:
>
> kernel/sched/build_policy.o: warning: objtool: do_idle() falls through to next function play_idle_precise()
>
> Reported-by: kernel test robot <[email protected]>
> Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
> Signed-off-by: Josh Poimboeuf <[email protected]>
Reviewed-by: Miroslav Benes <[email protected]>
The rest of the patch set looks good to me too.
M
On 13/4/23 07:49, Josh Poimboeuf wrote:
> Fixes a bunch of warnings including:
>
> vmlinux.o: warning: objtool: select_reloc_root+0x314: unreachable instruction
> vmlinux.o: warning: objtool: finish_inode_if_needed+0x15b1: unreachable instruction
> vmlinux.o: warning: objtool: get_bio_sector_nr+0x259: unreachable instruction
> vmlinux.o: warning: objtool: raid_wait_read_end_io+0xc26: unreachable instruction
> vmlinux.o: warning: objtool: raid56_parity_alloc_scrub_rbio+0x37b: unreachable instruction
> ...
>
> Reported-by: kernel test robot <[email protected]>
> Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
> Signed-off-by: Josh Poimboeuf <[email protected]>
LGTM.
Reviewed-by: Anand Jain <[email protected]>
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 6e36a56a5f617262c0e8ae7e961487361c720b9e
Gitweb: https://git.kernel.org/tip/6e36a56a5f617262c0e8ae7e961487361c720b9e
Author: Josh Poimboeuf <[email protected]>
AuthorDate: Wed, 12 Apr 2023 16:49:40 -07:00
Committer: Peter Zijlstra <[email protected]>
CommitterDate: Fri, 14 Apr 2023 17:31:27 +02:00
scsi: message: fusion: Mark mpt_halt_firmware() __noreturn
mpt_halt_firmware() doesn't return. Mark it as such.
Fixes the following warnings:
vmlinux.o: warning: objtool: mptscsih_abort+0x7f4: unreachable instruction
vmlinux.o: warning: objtool: mptctl_timeout_expired+0x310: unreachable instruction
Reported-by: kernel test robot <[email protected]>
Reported-by: Mark Rutland <[email protected]>
Debugged-by: Peter Zijlstra <[email protected]>
Signed-off-by: Josh Poimboeuf <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Link: https://lore.kernel.org/r/d8129817423422355bf30e90dadc6764261b53e0.1681342859.git.jpoimboe@kernel.org
---
drivers/message/fusion/mptbase.c | 2 +-
drivers/message/fusion/mptbase.h | 2 +-
tools/objtool/check.c | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 9b3ba2d..4f0afce 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -6935,7 +6935,7 @@ EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
* @ioc: Pointer to MPT_ADAPTER structure
*
**/
-void
+void __noreturn
mpt_halt_firmware(MPT_ADAPTER *ioc)
{
u32 ioc_raw_state;
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 4bd0682..0f226cd 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -945,7 +945,7 @@ extern int mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc,
u8 phys_disk_num);
extern int mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc);
extern void mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc);
-extern void mpt_halt_firmware(MPT_ADAPTER *ioc);
+extern void __noreturn mpt_halt_firmware(MPT_ADAPTER *ioc);
/*
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 724a63b..e1b01ea 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -219,6 +219,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"lbug_with_loc",
"machine_real_restart",
"make_task_dead",
+ "mpt_halt_firmware",
"nmi_panic_self_stop",
"panic",
"panic_smp_self_stop",
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 611d4c716db0141cfc436994dc5aff1d69c924ad
Gitweb: https://git.kernel.org/tip/611d4c716db0141cfc436994dc5aff1d69c924ad
Author: Guilherme G. Piccoli <[email protected]>
AuthorDate: Wed, 12 Apr 2023 16:49:41 -07:00
Committer: Peter Zijlstra <[email protected]>
CommitterDate: Fri, 14 Apr 2023 17:31:28 +02:00
x86/hyperv: Mark hv_ghcb_terminate() as noreturn
Annotate the function prototype and definition as noreturn to prevent
objtool warnings like:
vmlinux.o: warning: objtool: hyperv_init+0x55c: unreachable instruction
Also, as per Josh's suggestion, add it to the global_noreturns list.
As a comparison, an objdump output without the annotation:
[...]
1b63: mov $0x1,%esi
1b68: xor %edi,%edi
1b6a: callq ffffffff8102f680 <hv_ghcb_terminate>
1b6f: jmpq ffffffff82f217ec <hyperv_init+0x9c> # unreachable
1b74: cmpq $0xffffffffffffffff,-0x702a24(%rip)
[...]
Now, after adding the __noreturn to the function prototype:
[...]
17df: callq ffffffff8102f6d0 <hv_ghcb_negotiate_protocol>
17e4: test %al,%al
17e6: je ffffffff82f21bb9 <hyperv_init+0x469>
[...] <many insns>
1bb9: mov $0x1,%esi
1bbe: xor %edi,%edi
1bc0: callq ffffffff8102f680 <hv_ghcb_terminate>
1bc5: nopw %cs:0x0(%rax,%rax,1) # end of function
Reported-by: Arnd Bergmann <[email protected]>
Signed-off-by: Guilherme G. Piccoli <[email protected]>
Signed-off-by: Josh Poimboeuf <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Reviewed-by: Michael Kelley <[email protected]>
Link: https://lore.kernel.org/r/32453a703dfcf0d007b473c9acbf70718222b74b.1681342859.git.jpoimboe@kernel.org
---
arch/x86/hyperv/ivm.c | 2 +-
arch/x86/include/asm/mshyperv.h | 2 +-
tools/objtool/check.c | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
index 1dbcbd9..4f79dc7 100644
--- a/arch/x86/hyperv/ivm.c
+++ b/arch/x86/hyperv/ivm.c
@@ -127,7 +127,7 @@ static enum es_result hv_ghcb_hv_call(struct ghcb *ghcb, u64 exit_code,
return ES_OK;
}
-void hv_ghcb_terminate(unsigned int set, unsigned int reason)
+void __noreturn hv_ghcb_terminate(unsigned int set, unsigned int reason)
{
u64 val = GHCB_MSR_TERM_REQ;
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 4c4c0ec..09c26e6 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -212,7 +212,7 @@ int hv_set_mem_host_visibility(unsigned long addr, int numpages, bool visible);
void hv_ghcb_msr_write(u64 msr, u64 value);
void hv_ghcb_msr_read(u64 msr, u64 *value);
bool hv_ghcb_negotiate_protocol(void);
-void hv_ghcb_terminate(unsigned int set, unsigned int reason);
+void __noreturn hv_ghcb_terminate(unsigned int set, unsigned int reason);
#else
static inline void hv_ghcb_msr_write(u64 msr, u64 value) {}
static inline void hv_ghcb_msr_read(u64 msr, u64 *value) {}
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index e1b01ea..5b600bb 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -213,6 +213,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"ex_handler_msr_mce",
"fortify_panic",
"hlt_play_dead",
+ "hv_ghcb_terminate",
"kthread_complete_and_exit",
"kthread_exit",
"kunit_try_catch_throw",
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 52668badd34b4b346f32c33a9bcba069a06c3caa
Gitweb: https://git.kernel.org/tip/52668badd34b4b346f32c33a9bcba069a06c3caa
Author: Josh Poimboeuf <[email protected]>
AuthorDate: Wed, 12 Apr 2023 16:49:39 -07:00
Committer: Peter Zijlstra <[email protected]>
CommitterDate: Fri, 14 Apr 2023 17:31:27 +02:00
x86/cpu: Mark {hlt,resume}_play_dead() __noreturn
Fixes the following warning:
vmlinux.o: warning: objtool: resume_play_dead+0x21: unreachable instruction
Reported-by: kernel test robot <[email protected]>
Signed-off-by: Josh Poimboeuf <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Link: https://lore.kernel.org/r/ce1407c4bf88b1334fe40413126343792a77ca50.1681342859.git.jpoimboe@kernel.org
---
arch/x86/include/asm/smp.h | 2 +-
arch/x86/kernel/smpboot.c | 2 +-
arch/x86/power/cpu.c | 2 +-
tools/objtool/check.c | 2 ++
4 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index e6d1d28..47ce4c7 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -125,7 +125,7 @@ int native_cpu_up(unsigned int cpunum, struct task_struct *tidle);
int native_cpu_disable(void);
int common_cpu_die(unsigned int cpu);
void native_cpu_die(unsigned int cpu);
-void hlt_play_dead(void);
+void __noreturn hlt_play_dead(void);
void native_play_dead(void);
void play_dead_common(void);
void wbinvd_on_cpu(int cpu);
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 9013bb2..a6da3f9 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1816,7 +1816,7 @@ static inline void mwait_play_dead(void)
}
}
-void hlt_play_dead(void)
+void __noreturn hlt_play_dead(void)
{
if (__this_cpu_read(cpu_info.x86) >= 4)
wbinvd();
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index 236447e..7a4d5e9 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -288,7 +288,7 @@ EXPORT_SYMBOL(restore_processor_state);
#endif
#if defined(CONFIG_HIBERNATION) && defined(CONFIG_HOTPLUG_CPU)
-static void resume_play_dead(void)
+static void __noreturn resume_play_dead(void)
{
play_dead_common();
tboot_shutdown(TB_SHUTDOWN_WFS);
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index ceb9848..724a63b 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -212,6 +212,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"do_task_dead",
"ex_handler_msr_mce",
"fortify_panic",
+ "hlt_play_dead",
"kthread_complete_and_exit",
"kthread_exit",
"kunit_try_catch_throw",
@@ -222,6 +223,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"panic",
"panic_smp_self_stop",
"rest_init",
+ "resume_play_dead",
"rewind_stack_and_make_dead",
"sev_es_terminate",
"snp_abort",
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 4208d2d79837ef70f260d6170e3ac7fd6fde7788
Gitweb: https://git.kernel.org/tip/4208d2d79837ef70f260d6170e3ac7fd6fde7788
Author: Josh Poimboeuf <[email protected]>
AuthorDate: Wed, 12 Apr 2023 16:49:33 -07:00
Committer: Peter Zijlstra <[email protected]>
CommitterDate: Fri, 14 Apr 2023 17:31:24 +02:00
x86/head: Mark *_start_kernel() __noreturn
Now that start_kernel() is __noreturn, mark its chain of callers
__noreturn.
Signed-off-by: Josh Poimboeuf <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Link: https://lore.kernel.org/r/c2525f96b88be98ee027ee0291d58003036d4120.1681342859.git.jpoimboe@kernel.org
---
arch/x86/include/asm/setup.h | 6 +++---
arch/x86/kernel/head32.c | 2 +-
arch/x86/kernel/head64.c | 4 ++--
tools/objtool/check.c | 2 ++
4 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index f37cbff..f349562 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -125,11 +125,11 @@ void clear_bss(void);
#ifdef __i386__
-asmlinkage void __init i386_start_kernel(void);
+asmlinkage void __init __noreturn i386_start_kernel(void);
#else
-asmlinkage void __init x86_64_start_kernel(char *real_mode);
-asmlinkage void __init x86_64_start_reservations(char *real_mode_data);
+asmlinkage void __init __noreturn x86_64_start_kernel(char *real_mode);
+asmlinkage void __init __noreturn x86_64_start_reservations(char *real_mode_data);
#endif /* __i386__ */
#endif /* _SETUP */
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index ec6fefb..10c27b4 100644
--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -29,7 +29,7 @@ static void __init i386_default_early_setup(void)
x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc;
}
-asmlinkage __visible void __init i386_start_kernel(void)
+asmlinkage __visible void __init __noreturn i386_start_kernel(void)
{
/* Make sure IDT is set up before any exception happens */
idt_setup_early_handler();
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 387e4b1..49f7629 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -471,7 +471,7 @@ static void __init copy_bootdata(char *real_mode_data)
sme_unmap_bootdata(real_mode_data);
}
-asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
+asmlinkage __visible void __init __noreturn x86_64_start_kernel(char * real_mode_data)
{
/*
* Build-time sanity checks on the kernel image and module
@@ -537,7 +537,7 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
x86_64_start_reservations(real_mode_data);
}
-void __init x86_64_start_reservations(char *real_mode_data)
+void __init __noreturn x86_64_start_reservations(char *real_mode_data)
{
/* version is always not zero if it is copied */
if (!boot_params.hdr.version)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 9aaad9d..a436bc1 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -225,6 +225,8 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"start_kernel",
"stop_this_cpu",
"usercopy_abort",
+ "x86_64_start_kernel",
+ "x86_64_start_reservations",
"xen_cpu_bringup_again",
"xen_start_kernel",
};
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 5ab6876c7843db5fe8bef691c5fdb92518b12070
Gitweb: https://git.kernel.org/tip/5ab6876c7843db5fe8bef691c5fdb92518b12070
Author: Josh Poimboeuf <[email protected]>
AuthorDate: Wed, 12 Apr 2023 16:49:34 -07:00
Committer: Peter Zijlstra <[email protected]>
CommitterDate: Fri, 14 Apr 2023 17:31:24 +02:00
arm64/cpu: Mark cpu_park_loop() and friends __noreturn
In preparation for marking panic_smp_self_stop() __noreturn across the
kernel, first mark the arm64 implementation of cpu_park_loop() and
related functions __noreturn.
Signed-off-by: Josh Poimboeuf <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Link: https://lore.kernel.org/r/55787d3193ea3e295ccbb097abfab0a10ae49d45.1681342859.git.jpoimboe@kernel.org
---
arch/arm64/include/asm/exception.h | 4 ++--
arch/arm64/include/asm/smp.h | 6 +++---
arch/arm64/kernel/entry-common.c | 2 +-
arch/arm64/kernel/smp.c | 8 +++++---
arch/arm64/kernel/traps.c | 3 +--
5 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index 92963f9..e73af70 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -31,7 +31,7 @@ static inline unsigned long disr_to_esr(u64 disr)
return esr;
}
-asmlinkage void handle_bad_stack(struct pt_regs *regs);
+asmlinkage void __noreturn handle_bad_stack(struct pt_regs *regs);
asmlinkage void el1t_64_sync_handler(struct pt_regs *regs);
asmlinkage void el1t_64_irq_handler(struct pt_regs *regs);
@@ -80,5 +80,5 @@ void do_el1_fpac(struct pt_regs *regs, unsigned long esr);
void do_serror(struct pt_regs *regs, unsigned long esr);
void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags);
-void panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigned long far);
+void __noreturn panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigned long far);
#endif /* __ASM_EXCEPTION_H */
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 5733a31..07f4ea1 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -101,9 +101,9 @@ extern int __cpu_disable(void);
extern void __cpu_die(unsigned int cpu);
extern void __noreturn cpu_die(void);
-extern void cpu_die_early(void);
+extern void __noreturn cpu_die_early(void);
-static inline void cpu_park_loop(void)
+static inline void __noreturn cpu_park_loop(void)
{
for (;;) {
wfe();
@@ -123,7 +123,7 @@ static inline void update_cpu_boot_status(int val)
* which calls for a kernel panic. Update the boot status and park the calling
* CPU.
*/
-static inline void cpu_panic_kernel(void)
+static inline void __noreturn cpu_panic_kernel(void)
{
update_cpu_boot_status(CPU_PANIC_KERNEL);
cpu_park_loop();
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index cce1167..3af3c01 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -840,7 +840,7 @@ UNHANDLED(el0t, 32, error)
#endif /* CONFIG_COMPAT */
#ifdef CONFIG_VMAP_STACK
-asmlinkage void noinstr handle_bad_stack(struct pt_regs *regs)
+asmlinkage void noinstr __noreturn handle_bad_stack(struct pt_regs *regs)
{
unsigned long esr = read_sysreg(esr_el1);
unsigned long far = read_sysreg(far_el1);
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index d5d09a1..07d156f 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -398,7 +398,7 @@ static void __cpu_try_die(int cpu)
* Kill the calling secondary CPU, early in bringup before it is turned
* online.
*/
-void cpu_die_early(void)
+void __noreturn cpu_die_early(void)
{
int cpu = smp_processor_id();
@@ -816,7 +816,7 @@ void arch_irq_work_raise(void)
}
#endif
-static void local_cpu_stop(void)
+static void __noreturn local_cpu_stop(void)
{
set_cpu_online(smp_processor_id(), false);
@@ -839,7 +839,7 @@ void panic_smp_self_stop(void)
static atomic_t waiting_for_crash_ipi = ATOMIC_INIT(0);
#endif
-static void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
+static void __noreturn ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
{
#ifdef CONFIG_KEXEC_CORE
crash_save_cpu(regs, cpu);
@@ -854,6 +854,8 @@ static void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
/* just in case */
cpu_park_loop();
+#else
+ BUG();
#endif
}
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 4a79ba1..4bb1b8f 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -863,7 +863,7 @@ void bad_el0_sync(struct pt_regs *regs, int reason, unsigned long esr)
DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack)
__aligned(16);
-void panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigned long far)
+void __noreturn panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigned long far)
{
unsigned long tsk_stk = (unsigned long)current->stack;
unsigned long irq_stk = (unsigned long)this_cpu_read(irq_stack_ptr);
@@ -905,7 +905,6 @@ void __noreturn arm64_serror_panic(struct pt_regs *regs, unsigned long esr)
nmi_panic(regs, "Asynchronous SError Interrupt");
cpu_park_loop();
- unreachable();
}
bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned long esr)
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 27dea14c7f05106f39850a9239874cd38703b405
Gitweb: https://git.kernel.org/tip/27dea14c7f05106f39850a9239874cd38703b405
Author: Josh Poimboeuf <[email protected]>
AuthorDate: Wed, 12 Apr 2023 16:49:36 -07:00
Committer: Peter Zijlstra <[email protected]>
CommitterDate: Fri, 14 Apr 2023 17:31:26 +02:00
cpu: Mark nmi_panic_self_stop() __noreturn
In preparation for improving objtool's handling of weak noreturn
functions, mark nmi_panic_self_stop() __noreturn.
Signed-off-by: Josh Poimboeuf <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Link: https://lore.kernel.org/r/316fc6dfab5a8c4e024c7185484a1ee5fb0afb79.1681342859.git.jpoimboe@kernel.org
---
arch/x86/include/asm/reboot.h | 1 -
arch/x86/kernel/reboot.c | 2 +-
include/linux/smp.h | 2 +-
kernel/panic.c | 2 +-
tools/objtool/check.c | 1 +
5 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h
index bc5b4d7..9177b43 100644
--- a/arch/x86/include/asm/reboot.h
+++ b/arch/x86/include/asm/reboot.h
@@ -28,7 +28,6 @@ void __noreturn machine_real_restart(unsigned int type);
void cpu_emergency_disable_virtualization(void);
typedef void (*nmi_shootdown_cb)(int, struct pt_regs*);
-void nmi_panic_self_stop(struct pt_regs *regs);
void nmi_shootdown_cpus(nmi_shootdown_cb callback);
void run_crash_ipi_callback(struct pt_regs *regs);
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index d03c551..3adbe97 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -920,7 +920,7 @@ void run_crash_ipi_callback(struct pt_regs *regs)
}
/* Override the weak function in kernel/panic.c */
-void nmi_panic_self_stop(struct pt_regs *regs)
+void __noreturn nmi_panic_self_stop(struct pt_regs *regs)
{
while (1) {
/* If no CPU is preparing crash dump, we simply loop here. */
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 2a737b3..7b93504 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -60,7 +60,7 @@ int smp_call_function_single_async(int cpu, struct __call_single_data *csd);
* Architecture-dependent code may override them.
*/
void __noreturn panic_smp_self_stop(void);
-void nmi_panic_self_stop(struct pt_regs *regs);
+void __noreturn nmi_panic_self_stop(struct pt_regs *regs);
void crash_smp_send_stop(void);
/*
diff --git a/kernel/panic.c b/kernel/panic.c
index 5e4982d..886d2eb 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -151,7 +151,7 @@ void __weak __noreturn panic_smp_self_stop(void)
* Stop ourselves in NMI context if another CPU has already panicked. Arch code
* may override this to prepare for crash dumping, e.g. save regs info.
*/
-void __weak nmi_panic_self_stop(struct pt_regs *regs)
+void __weak __noreturn nmi_panic_self_stop(struct pt_regs *regs)
{
panic_smp_self_stop();
}
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 4b52ed6..8d073bf 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -217,6 +217,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"lbug_with_loc",
"machine_real_restart",
"make_task_dead",
+ "nmi_panic_self_stop",
"panic",
"panic_smp_self_stop",
"rest_init",
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 7412a60decec2a6744cf773280ff17a0f89e8395
Gitweb: https://git.kernel.org/tip/7412a60decec2a6744cf773280ff17a0f89e8395
Author: Josh Poimboeuf <[email protected]>
AuthorDate: Wed, 12 Apr 2023 16:49:35 -07:00
Committer: Peter Zijlstra <[email protected]>
CommitterDate: Fri, 14 Apr 2023 17:31:25 +02:00
cpu: Mark panic_smp_self_stop() __noreturn
In preparation for improving objtool's handling of weak noreturn
functions, mark panic_smp_self_stop() __noreturn.
Signed-off-by: Josh Poimboeuf <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Link: https://lore.kernel.org/r/92d76ab5c8bf660f04fdcd3da1084519212de248.1681342859.git.jpoimboe@kernel.org
---
arch/arm/kernel/smp.c | 2 +-
arch/arm64/include/asm/smp.h | 1 -
arch/arm64/kernel/smp.c | 2 +-
arch/powerpc/kernel/setup_64.c | 2 +-
include/linux/smp.h | 2 +-
kernel/panic.c | 2 +-
tools/objtool/check.c | 1 +
7 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index d6be450..f4a4ac0 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -779,7 +779,7 @@ void smp_send_stop(void)
* kdump fails. So split out the panic_smp_self_stop() and add
* set_cpu_online(smp_processor_id(), false).
*/
-void panic_smp_self_stop(void)
+void __noreturn panic_smp_self_stop(void)
{
pr_debug("CPU %u will stop doing anything useful since another CPU has paniced\n",
smp_processor_id());
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 07f4ea1..f2d2623 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -143,7 +143,6 @@ bool cpus_are_stuck_in_kernel(void);
extern void crash_smp_send_stop(void);
extern bool smp_crash_stop_failed(void);
-extern void panic_smp_self_stop(void);
#endif /* ifndef __ASSEMBLY__ */
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 07d156f..05fe797 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -830,7 +830,7 @@ static void __noreturn local_cpu_stop(void)
* that cpu_online_mask gets correctly updated and smp_send_stop() can skip
* CPUs that have already stopped themselves.
*/
-void panic_smp_self_stop(void)
+void __noreturn panic_smp_self_stop(void)
{
local_cpu_stop();
}
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index b2e0d3c..246201d 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -480,7 +480,7 @@ void early_setup_secondary(void)
#endif /* CONFIG_SMP */
-void panic_smp_self_stop(void)
+void __noreturn panic_smp_self_stop(void)
{
hard_irq_disable();
spin_begin();
diff --git a/include/linux/smp.h b/include/linux/smp.h
index a80ab58..2a737b3 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -59,7 +59,7 @@ int smp_call_function_single_async(int cpu, struct __call_single_data *csd);
* Cpus stopping functions in panic. All have default weak definitions.
* Architecture-dependent code may override them.
*/
-void panic_smp_self_stop(void);
+void __noreturn panic_smp_self_stop(void);
void nmi_panic_self_stop(struct pt_regs *regs);
void crash_smp_send_stop(void);
diff --git a/kernel/panic.c b/kernel/panic.c
index 5cfea83..5e4982d 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -141,7 +141,7 @@ EXPORT_SYMBOL(panic_blink);
/*
* Stop ourself in panic -- architecture code may override this
*/
-void __weak panic_smp_self_stop(void)
+void __weak __noreturn panic_smp_self_stop(void)
{
while (1)
cpu_relax();
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index a436bc1..4b52ed6 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -218,6 +218,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"machine_real_restart",
"make_task_dead",
"panic",
+ "panic_smp_self_stop",
"rest_init",
"rewind_stack_and_make_dead",
"sev_es_terminate",
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 1c47c8758a11345ac643fa68cb70b708a6668883
Gitweb: https://git.kernel.org/tip/1c47c8758a11345ac643fa68cb70b708a6668883
Author: Josh Poimboeuf <[email protected]>
AuthorDate: Wed, 12 Apr 2023 16:49:37 -07:00
Committer: Peter Zijlstra <[email protected]>
CommitterDate: Fri, 14 Apr 2023 17:31:26 +02:00
objtool: Include weak functions in global_noreturns check
If a global function doesn't return, and its prototype has the
__noreturn attribute, its weak counterpart must also not return so that
it matches the prototype and meets call site expectations.
To properly follow the compiled control flow at the call sites, change
the global_noreturns check to include both global and weak functions.
On the other hand, if a weak function isn't in global_noreturns, assume
the prototype doesn't have __noreturn. Even if the weak function
doesn't return, call sites treat it like a returnable function.
Fixes the following warning:
kernel/sched/build_policy.o: warning: objtool: do_idle() falls through to next function play_idle_precise()
Reported-by: kernel test robot <[email protected]>
Signed-off-by: Josh Poimboeuf <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Reviewed-by: Miroslav Benes <[email protected]>
Link: https://lore.kernel.org/r/ede3460d63f4a65d282c86f1175bd2662c2286ba.1681342859.git.jpoimboe@kernel.org
---
tools/objtool/check.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 8d073bf..ae0c942 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -236,14 +236,14 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
if (!func)
return false;
- if (func->bind == STB_WEAK)
- return false;
-
- if (func->bind == STB_GLOBAL)
+ if (func->bind == STB_GLOBAL || func->bind == STB_WEAK)
for (i = 0; i < ARRAY_SIZE(global_noreturns); i++)
if (!strcmp(func->name, global_noreturns[i]))
return true;
+ if (func->bind == STB_WEAK)
+ return false;
+
if (!func->len)
return false;
The following commit has been merged into the objtool/core branch of tip:
Commit-ID: 09c5ae30d007514a1be870fa5873ad55c3319f3a
Gitweb: https://git.kernel.org/tip/09c5ae30d007514a1be870fa5873ad55c3319f3a
Author: Josh Poimboeuf <[email protected]>
AuthorDate: Wed, 12 Apr 2023 16:49:38 -07:00
Committer: Peter Zijlstra <[email protected]>
CommitterDate: Fri, 14 Apr 2023 17:31:26 +02:00
btrfs: Mark btrfs_assertfail() __noreturn
Fixes a bunch of warnings including:
vmlinux.o: warning: objtool: select_reloc_root+0x314: unreachable instruction
vmlinux.o: warning: objtool: finish_inode_if_needed+0x15b1: unreachable instruction
vmlinux.o: warning: objtool: get_bio_sector_nr+0x259: unreachable instruction
vmlinux.o: warning: objtool: raid_wait_read_end_io+0xc26: unreachable instruction
vmlinux.o: warning: objtool: raid56_parity_alloc_scrub_rbio+0x37b: unreachable instruction
...
Reported-by: kernel test robot <[email protected]>
Signed-off-by: Josh Poimboeuf <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Link: https://lore.kernel.org/r/960bd9c0c9e3cfc409ba9c35a17644b11b832956.1681342859.git.jpoimboe@kernel.org
---
fs/btrfs/messages.c | 2 +-
fs/btrfs/messages.h | 2 +-
tools/objtool/check.c | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/messages.c b/fs/btrfs/messages.c
index fde5aaa..310a05c 100644
--- a/fs/btrfs/messages.c
+++ b/fs/btrfs/messages.c
@@ -253,7 +253,7 @@ void __cold _btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt,
#endif
#ifdef CONFIG_BTRFS_ASSERT
-void __cold btrfs_assertfail(const char *expr, const char *file, int line)
+void __cold __noreturn btrfs_assertfail(const char *expr, const char *file, int line)
{
pr_err("assertion failed: %s, in %s:%d\n", expr, file, line);
BUG();
diff --git a/fs/btrfs/messages.h b/fs/btrfs/messages.h
index 8c516ee..ac2d198 100644
--- a/fs/btrfs/messages.h
+++ b/fs/btrfs/messages.h
@@ -160,7 +160,7 @@ do { \
} while (0)
#ifdef CONFIG_BTRFS_ASSERT
-void __cold btrfs_assertfail(const char *expr, const char *file, int line);
+void __cold __noreturn btrfs_assertfail(const char *expr, const char *file, int line);
#define ASSERT(expr) \
(likely(expr) ? (void)0 : btrfs_assertfail(#expr, __FILE__, __LINE__))
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index ae0c942..ceb9848 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -204,6 +204,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
"__ubsan_handle_builtin_unreachable",
"arch_call_rest_init",
"arch_cpu_idle_dead",
+ "btrfs_assertfail",
"cpu_bringup_and_idle",
"cpu_startup_entry",
"do_exit",