Skip to content

Commit 35a813e

Browse files
committed
Merge tag 'printk-for-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux
Pull printk updates from Petr Mladek: - Add new "hash_pointers=[auto|always|never]" boot parameter to force the hashing even with "slab_debug" enabled - Allow to stop CPU, after losing nbcon console ownership during panic(), even without proper NMI - Allow to use the printk kthread immediately even for the 1st registered nbcon - Compiler warning removal * tag 'printk-for-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux: printk: nbcon: Allow reacquire during panic printk: Allow to use the printk kthread immediately even for 1st nbcon slab: Decouple slab_debug and no_hash_pointers vsprintf: Use __diag macros to disable '-Wsuggest-attribute=format' compiler-gcc.h: Introduce __diag_GCC_all
2 parents 99b773d + 3db488c commit 35a813e

File tree

8 files changed

+170
-58
lines changed

8 files changed

+170
-58
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,6 +1828,27 @@
18281828
backtraces on all cpus.
18291829
Format: 0 | 1
18301830

1831+
hash_pointers=
1832+
[KNL,EARLY]
1833+
By default, when pointers are printed to the console
1834+
or buffers via the %p format string, that pointer is
1835+
"hashed", i.e. obscured by hashing the pointer value.
1836+
This is a security feature that hides actual kernel
1837+
addresses from unprivileged users, but it also makes
1838+
debugging the kernel more difficult since unequal
1839+
pointers can no longer be compared. The choices are:
1840+
Format: { auto | always | never }
1841+
Default: auto
1842+
1843+
auto - Hash pointers unless slab_debug is enabled.
1844+
always - Always hash pointers (even if slab_debug is
1845+
enabled).
1846+
never - Never hash pointers. This option should only
1847+
be specified when debugging the kernel. Do
1848+
not use on production kernels. The boot
1849+
param "no_hash_pointers" is an alias for
1850+
this mode.
1851+
18311852
hashdist= [KNL,NUMA] Large hashes allocated during boot
18321853
are distributed across NUMA nodes. Defaults on
18331854
for 64-bit NUMA, off otherwise.
@@ -4216,18 +4237,7 @@
42164237

42174238
no_hash_pointers
42184239
[KNL,EARLY]
4219-
Force pointers printed to the console or buffers to be
4220-
unhashed. By default, when a pointer is printed via %p
4221-
format string, that pointer is "hashed", i.e. obscured
4222-
by hashing the pointer value. This is a security feature
4223-
that hides actual kernel addresses from unprivileged
4224-
users, but it also makes debugging the kernel more
4225-
difficult since unequal pointers can no longer be
4226-
compared. However, if this command-line option is
4227-
specified, then all normal pointers will have their true
4228-
value printed. This option should only be specified when
4229-
debugging the kernel. Please do not use on production
4230-
kernels.
4240+
Alias for "hash_pointers=never".
42314241

42324242
nohibernate [HIBERNATION] Disable hibernation and resume.
42334243

@@ -6644,6 +6654,10 @@
66446654
Documentation/admin-guide/mm/slab.rst.
66456655
(slub_debug legacy name also accepted for now)
66466656

6657+
Using this option implies the "no_hash_pointers"
6658+
option which can be undone by adding the
6659+
"hash_pointers=always" option.
6660+
66476661
slab_max_order= [MM]
66486662
Determines the maximum allowed order for slabs.
66496663
A high setting may cause OOMs due to memory

include/linux/compiler-gcc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@
127127
#define __diag_GCC_8(s)
128128
#endif
129129

130+
#define __diag_GCC_all(s) __diag(s)
131+
130132
#define __diag_ignore_all(option, comment) \
131133
__diag(__diag_GCC_ignore option)
132134

include/linux/sprintf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ __scanf(2, 0) int vsscanf(const char *, const char *, va_list);
2323

2424
/* These are for specific cases, do not use without real need */
2525
extern bool no_hash_pointers;
26-
int no_hash_pointers_enable(char *str);
26+
void hash_pointers_finalize(bool slub_debug);
2727

2828
/* Used for Rust formatting ('%pA') */
2929
char *rust_fmt_argument(char *buf, char *end, const void *ptr);

kernel/printk/internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ struct dev_printk_info;
6464

6565
extern struct printk_ringbuffer *prb;
6666
extern bool printk_kthreads_running;
67+
extern bool printk_kthreads_ready;
6768
extern bool debug_non_panic_cpus;
6869

6970
__printf(4, 0)
@@ -179,6 +180,7 @@ static inline void nbcon_kthread_wake(struct console *con)
179180
#define PRINTKRB_RECORD_MAX 0
180181

181182
#define printk_kthreads_running (false)
183+
#define printk_kthreads_ready (false)
182184

183185
/*
184186
* In !PRINTK builds we still export console_sem

kernel/printk/nbcon.c

Lines changed: 65 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,9 @@ static void nbcon_seq_try_update(struct nbcon_context *ctxt, u64 new_seq)
214214

215215
/**
216216
* nbcon_context_try_acquire_direct - Try to acquire directly
217-
* @ctxt: The context of the caller
218-
* @cur: The current console state
217+
* @ctxt: The context of the caller
218+
* @cur: The current console state
219+
* @is_reacquire: This acquire is a reacquire
219220
*
220221
* Acquire the console when it is released. Also acquire the console when
221222
* the current owner has a lower priority and the console is in a safe state.
@@ -225,32 +226,38 @@ static void nbcon_seq_try_update(struct nbcon_context *ctxt, u64 new_seq)
225226
*
226227
* Errors:
227228
*
228-
* -EPERM: A panic is in progress and this is not the panic CPU.
229-
* Or the current owner or waiter has the same or higher
230-
* priority. No acquire method can be successful in
231-
* this case.
229+
* -EPERM: A panic is in progress and this is neither the panic
230+
* CPU nor is this a reacquire. Or the current owner or
231+
* waiter has the same or higher priority. No acquire
232+
* method can be successful in these cases.
232233
*
233234
* -EBUSY: The current owner has a lower priority but the console
234235
* in an unsafe state. The caller should try using
235236
* the handover acquire method.
236237
*/
237238
static int nbcon_context_try_acquire_direct(struct nbcon_context *ctxt,
238-
struct nbcon_state *cur)
239+
struct nbcon_state *cur, bool is_reacquire)
239240
{
240241
unsigned int cpu = smp_processor_id();
241242
struct console *con = ctxt->console;
242243
struct nbcon_state new;
243244

244245
do {
245246
/*
246-
* Panic does not imply that the console is owned. However, it
247-
* is critical that non-panic CPUs during panic are unable to
248-
* acquire ownership in order to satisfy the assumptions of
249-
* nbcon_waiter_matches(). In particular, the assumption that
250-
* lower priorities are ignored during panic.
247+
* Panic does not imply that the console is owned. However,
248+
* since all non-panic CPUs are stopped during panic(), it
249+
* is safer to have them avoid gaining console ownership.
250+
*
251+
* If this acquire is a reacquire (and an unsafe takeover
252+
* has not previously occurred) then it is allowed to attempt
253+
* a direct acquire in panic. This gives console drivers an
254+
* opportunity to perform any necessary cleanup if they were
255+
* interrupted by the panic CPU while printing.
251256
*/
252-
if (other_cpu_in_panic())
257+
if (other_cpu_in_panic() &&
258+
(!is_reacquire || cur->unsafe_takeover)) {
253259
return -EPERM;
260+
}
254261

255262
if (ctxt->prio <= cur->prio || ctxt->prio <= cur->req_prio)
256263
return -EPERM;
@@ -301,8 +308,9 @@ static bool nbcon_waiter_matches(struct nbcon_state *cur, int expected_prio)
301308
* Event #1 implies this context is EMERGENCY.
302309
* Event #2 implies the new context is PANIC.
303310
* Event #3 occurs when panic() has flushed the console.
304-
* Events #4 and #5 are not possible due to the other_cpu_in_panic()
305-
* check in nbcon_context_try_acquire_direct().
311+
* Event #4 occurs when a non-panic CPU reacquires.
312+
* Event #5 is not possible due to the other_cpu_in_panic() check
313+
* in nbcon_context_try_acquire_handover().
306314
*/
307315

308316
return (cur->req_prio == expected_prio);
@@ -431,6 +439,16 @@ static int nbcon_context_try_acquire_handover(struct nbcon_context *ctxt,
431439
WARN_ON_ONCE(ctxt->prio <= cur->prio || ctxt->prio <= cur->req_prio);
432440
WARN_ON_ONCE(!cur->unsafe);
433441

442+
/*
443+
* Panic does not imply that the console is owned. However, it
444+
* is critical that non-panic CPUs during panic are unable to
445+
* wait for a handover in order to satisfy the assumptions of
446+
* nbcon_waiter_matches(). In particular, the assumption that
447+
* lower priorities are ignored during panic.
448+
*/
449+
if (other_cpu_in_panic())
450+
return -EPERM;
451+
434452
/* Handover is not possible on the same CPU. */
435453
if (cur->cpu == cpu)
436454
return -EBUSY;
@@ -558,7 +576,8 @@ static struct printk_buffers panic_nbcon_pbufs;
558576

559577
/**
560578
* nbcon_context_try_acquire - Try to acquire nbcon console
561-
* @ctxt: The context of the caller
579+
* @ctxt: The context of the caller
580+
* @is_reacquire: This acquire is a reacquire
562581
*
563582
* Context: Under @ctxt->con->device_lock() or local_irq_save().
564583
* Return: True if the console was acquired. False otherwise.
@@ -568,7 +587,7 @@ static struct printk_buffers panic_nbcon_pbufs;
568587
* in an unsafe state. Otherwise, on success the caller may assume
569588
* the console is not in an unsafe state.
570589
*/
571-
static bool nbcon_context_try_acquire(struct nbcon_context *ctxt)
590+
static bool nbcon_context_try_acquire(struct nbcon_context *ctxt, bool is_reacquire)
572591
{
573592
unsigned int cpu = smp_processor_id();
574593
struct console *con = ctxt->console;
@@ -577,7 +596,7 @@ static bool nbcon_context_try_acquire(struct nbcon_context *ctxt)
577596

578597
nbcon_state_read(con, &cur);
579598
try_again:
580-
err = nbcon_context_try_acquire_direct(ctxt, &cur);
599+
err = nbcon_context_try_acquire_direct(ctxt, &cur, is_reacquire);
581600
if (err != -EBUSY)
582601
goto out;
583602

@@ -913,7 +932,7 @@ void nbcon_reacquire_nobuf(struct nbcon_write_context *wctxt)
913932
{
914933
struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt);
915934

916-
while (!nbcon_context_try_acquire(ctxt))
935+
while (!nbcon_context_try_acquire(ctxt, true))
917936
cpu_relax();
918937

919938
nbcon_write_context_set_buf(wctxt, NULL, 0);
@@ -1101,7 +1120,7 @@ static bool nbcon_emit_one(struct nbcon_write_context *wctxt, bool use_atomic)
11011120
cant_migrate();
11021121
}
11031122

1104-
if (!nbcon_context_try_acquire(ctxt))
1123+
if (!nbcon_context_try_acquire(ctxt, false))
11051124
goto out;
11061125

11071126
/*
@@ -1486,7 +1505,7 @@ static int __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq,
14861505
ctxt->prio = nbcon_get_default_prio();
14871506
ctxt->allow_unsafe_takeover = allow_unsafe_takeover;
14881507

1489-
if (!nbcon_context_try_acquire(ctxt))
1508+
if (!nbcon_context_try_acquire(ctxt, false))
14901509
return -EPERM;
14911510

14921511
while (nbcon_seq_read(con) < stop_seq) {
@@ -1671,6 +1690,9 @@ bool nbcon_alloc(struct console *con)
16711690
{
16721691
struct nbcon_state state = { };
16731692

1693+
/* Synchronize the kthread start. */
1694+
lockdep_assert_console_list_lock_held();
1695+
16741696
/* The write_thread() callback is mandatory. */
16751697
if (WARN_ON(!con->write_thread))
16761698
return false;
@@ -1701,12 +1723,15 @@ bool nbcon_alloc(struct console *con)
17011723
return false;
17021724
}
17031725

1704-
if (printk_kthreads_running) {
1726+
if (printk_kthreads_ready && !have_boot_console) {
17051727
if (!nbcon_kthread_create(con)) {
17061728
kfree(con->pbufs);
17071729
con->pbufs = NULL;
17081730
return false;
17091731
}
1732+
1733+
/* Might be the first kthread. */
1734+
printk_kthreads_running = true;
17101735
}
17111736
}
17121737

@@ -1716,14 +1741,30 @@ bool nbcon_alloc(struct console *con)
17161741
/**
17171742
* nbcon_free - Free and cleanup the nbcon console specific data
17181743
* @con: Console to free/cleanup nbcon data
1744+
*
1745+
* Important: @have_nbcon_console must be updated before calling
1746+
* this function. In particular, it can be set only when there
1747+
* is still another nbcon console registered.
17191748
*/
17201749
void nbcon_free(struct console *con)
17211750
{
17221751
struct nbcon_state state = { };
17231752

1724-
if (printk_kthreads_running)
1753+
/* Synchronize the kthread stop. */
1754+
lockdep_assert_console_list_lock_held();
1755+
1756+
if (printk_kthreads_running) {
17251757
nbcon_kthread_stop(con);
17261758

1759+
/* Might be the last nbcon console.
1760+
*
1761+
* Do not rely on printk_kthreads_check_locked(). It is not
1762+
* called in some code paths, see nbcon_free() callers.
1763+
*/
1764+
if (!have_nbcon_console)
1765+
printk_kthreads_running = false;
1766+
}
1767+
17271768
nbcon_state_set(con, &state);
17281769

17291770
/* Boot consoles share global printk buffers. */
@@ -1762,7 +1803,7 @@ bool nbcon_device_try_acquire(struct console *con)
17621803
ctxt->console = con;
17631804
ctxt->prio = NBCON_PRIO_NORMAL;
17641805

1765-
if (!nbcon_context_try_acquire(ctxt))
1806+
if (!nbcon_context_try_acquire(ctxt, false))
17661807
return false;
17671808

17681809
if (!nbcon_context_enter_unsafe(ctxt))

kernel/printk/printk.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3574,7 +3574,7 @@ EXPORT_SYMBOL(console_resume);
35743574
static int unregister_console_locked(struct console *console);
35753575

35763576
/* True when system boot is far enough to create printer threads. */
3577-
static bool printk_kthreads_ready __ro_after_init;
3577+
bool printk_kthreads_ready __ro_after_init;
35783578

35793579
static struct task_struct *printk_legacy_kthread;
35803580

@@ -3713,6 +3713,7 @@ static void printk_kthreads_check_locked(void)
37133713
if (!printk_kthreads_ready)
37143714
return;
37153715

3716+
/* Start or stop the legacy kthread when needed. */
37163717
if (have_legacy_console || have_boot_console) {
37173718
if (!printk_legacy_kthread &&
37183719
force_legacy_kthread() &&
@@ -4204,14 +4205,6 @@ static int unregister_console_locked(struct console *console)
42044205
*/
42054206
synchronize_srcu(&console_srcu);
42064207

4207-
if (console->flags & CON_NBCON)
4208-
nbcon_free(console);
4209-
4210-
console_sysfs_notify();
4211-
4212-
if (console->exit)
4213-
res = console->exit(console);
4214-
42154208
/*
42164209
* With this console gone, the global flags tracking registered
42174210
* console types may have changed. Update them.
@@ -4232,6 +4225,15 @@ static int unregister_console_locked(struct console *console)
42324225
if (!found_nbcon_con)
42334226
have_nbcon_console = found_nbcon_con;
42344227

4228+
/* @have_nbcon_console must be updated before calling nbcon_free(). */
4229+
if (console->flags & CON_NBCON)
4230+
nbcon_free(console);
4231+
4232+
console_sysfs_notify();
4233+
4234+
if (console->exit)
4235+
res = console->exit(console);
4236+
42354237
/* Changed console list, may require printer threads to start/stop. */
42364238
printk_kthreads_check_locked();
42374239

0 commit comments

Comments
 (0)