Commit 35a813e0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 99b773d7 3db488c8
Loading
Loading
Loading
Loading
+26 −12
Original line number Diff line number Diff line
@@ -1828,6 +1828,27 @@
			backtraces on all cpus.
			Format: 0 | 1

	hash_pointers=
			[KNL,EARLY]
			By default, when pointers are printed to the console
			or buffers via the %p format string, that pointer is
			"hashed", i.e. obscured by hashing the pointer value.
			This is a security feature that hides actual kernel
			addresses from unprivileged users, but it also makes
			debugging the kernel more difficult since unequal
			pointers can no longer be compared. The choices are:
			Format: { auto | always | never }
			Default: auto

			auto   - Hash pointers unless slab_debug is enabled.
			always - Always hash pointers (even if slab_debug is
				 enabled).
			never  - Never hash pointers. This option should only
				 be specified when debugging the kernel. Do
				 not use on production kernels. The boot
				 param "no_hash_pointers" is an alias for
				 this mode.

	hashdist=	[KNL,NUMA] Large hashes allocated during boot
			are distributed across NUMA nodes.  Defaults on
			for 64-bit NUMA, off otherwise.
@@ -4216,18 +4237,7 @@

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

	nohibernate	[HIBERNATION] Disable hibernation and resume.

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

			Using this option implies the "no_hash_pointers"
			option which can be undone by adding the
			"hash_pointers=always" option.

	slab_max_order= [MM]
			Determines the maximum allowed order for slabs.
			A high setting may cause OOMs due to memory
+2 −0
Original line number Diff line number Diff line
@@ -127,6 +127,8 @@
#define __diag_GCC_8(s)
#endif

#define __diag_GCC_all(s)	__diag(s)

#define __diag_ignore_all(option, comment) \
	__diag(__diag_GCC_ignore option)

+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ __scanf(2, 0) int vsscanf(const char *, const char *, va_list);

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

/* Used for Rust formatting ('%pA') */
char *rust_fmt_argument(char *buf, char *end, const void *ptr);
+2 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ struct dev_printk_info;

extern struct printk_ringbuffer *prb;
extern bool printk_kthreads_running;
extern bool printk_kthreads_ready;
extern bool debug_non_panic_cpus;

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

#define printk_kthreads_running (false)
#define printk_kthreads_ready (false)

/*
 * In !PRINTK builds we still export console_sem
+65 −24
Original line number Diff line number Diff line
@@ -216,6 +216,7 @@ static void nbcon_seq_try_update(struct nbcon_context *ctxt, u64 new_seq)
 * nbcon_context_try_acquire_direct - Try to acquire directly
 * @ctxt:		The context of the caller
 * @cur:		The current console state
 * @is_reacquire:	This acquire is a reacquire
 *
 * Acquire the console when it is released. Also acquire the console when
 * the current owner has a lower priority and the console is in a safe state.
@@ -225,17 +226,17 @@ static void nbcon_seq_try_update(struct nbcon_context *ctxt, u64 new_seq)
 *
 * Errors:
 *
 *	-EPERM:		A panic is in progress and this is not the panic CPU.
 *			Or the current owner or waiter has the same or higher
 *			priority. No acquire method can be successful in
 *			this case.
 *	-EPERM:		A panic is in progress and this is neither the panic
 *			CPU nor is this a reacquire. Or the current owner or
 *			waiter has the same or higher priority. No acquire
 *			method can be successful in these cases.
 *
 *	-EBUSY:		The current owner has a lower priority but the console
 *			in an unsafe state. The caller should try using
 *			the handover acquire method.
 */
static int nbcon_context_try_acquire_direct(struct nbcon_context *ctxt,
					    struct nbcon_state *cur)
					    struct nbcon_state *cur, bool is_reacquire)
{
	unsigned int cpu = smp_processor_id();
	struct console *con = ctxt->console;
@@ -243,14 +244,20 @@ static int nbcon_context_try_acquire_direct(struct nbcon_context *ctxt,

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

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

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

	/*
	 * Panic does not imply that the console is owned. However, it
	 * is critical that non-panic CPUs during panic are unable to
	 * wait for a handover in order to satisfy the assumptions of
	 * nbcon_waiter_matches(). In particular, the assumption that
	 * lower priorities are ignored during panic.
	 */
	if (other_cpu_in_panic())
		return -EPERM;

	/* Handover is not possible on the same CPU. */
	if (cur->cpu == cpu)
		return -EBUSY;
@@ -559,6 +577,7 @@ static struct printk_buffers panic_nbcon_pbufs;
/**
 * nbcon_context_try_acquire - Try to acquire nbcon console
 * @ctxt:		The context of the caller
 * @is_reacquire:	This acquire is a reacquire
 *
 * Context:	Under @ctxt->con->device_lock() or local_irq_save().
 * Return:	True if the console was acquired. False otherwise.
@@ -568,7 +587,7 @@ static struct printk_buffers panic_nbcon_pbufs;
 * in an unsafe state. Otherwise, on success the caller may assume
 * the console is not in an unsafe state.
 */
static bool nbcon_context_try_acquire(struct nbcon_context *ctxt)
static bool nbcon_context_try_acquire(struct nbcon_context *ctxt, bool is_reacquire)
{
	unsigned int cpu = smp_processor_id();
	struct console *con = ctxt->console;
@@ -577,7 +596,7 @@ static bool nbcon_context_try_acquire(struct nbcon_context *ctxt)

	nbcon_state_read(con, &cur);
try_again:
	err = nbcon_context_try_acquire_direct(ctxt, &cur);
	err = nbcon_context_try_acquire_direct(ctxt, &cur, is_reacquire);
	if (err != -EBUSY)
		goto out;

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

	while (!nbcon_context_try_acquire(ctxt))
	while (!nbcon_context_try_acquire(ctxt, true))
		cpu_relax();

	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)
		cant_migrate();
	}

	if (!nbcon_context_try_acquire(ctxt))
	if (!nbcon_context_try_acquire(ctxt, false))
		goto out;

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

	if (!nbcon_context_try_acquire(ctxt))
	if (!nbcon_context_try_acquire(ctxt, false))
		return -EPERM;

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

	/* Synchronize the kthread start. */
	lockdep_assert_console_list_lock_held();

	/* The write_thread() callback is mandatory. */
	if (WARN_ON(!con->write_thread))
		return false;
@@ -1701,12 +1723,15 @@ bool nbcon_alloc(struct console *con)
			return false;
		}

		if (printk_kthreads_running) {
		if (printk_kthreads_ready && !have_boot_console) {
			if (!nbcon_kthread_create(con)) {
				kfree(con->pbufs);
				con->pbufs = NULL;
				return false;
			}

			/* Might be the first kthread. */
			printk_kthreads_running = true;
		}
	}

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

	if (printk_kthreads_running)
	/* Synchronize the kthread stop. */
	lockdep_assert_console_list_lock_held();

	if (printk_kthreads_running) {
		nbcon_kthread_stop(con);

		/* Might be the last nbcon console.
		 *
		 * Do not rely on printk_kthreads_check_locked(). It is not
		 * called in some code paths, see nbcon_free() callers.
		 */
		if (!have_nbcon_console)
			printk_kthreads_running = false;
	}

	nbcon_state_set(con, &state);

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

	if (!nbcon_context_try_acquire(ctxt))
	if (!nbcon_context_try_acquire(ctxt, false))
		return false;

	if (!nbcon_context_enter_unsafe(ctxt))
Loading