| 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ | 
|---|
| 2 | /* | 
|---|
| 3 | * internal.h - printk internal definitions | 
|---|
| 4 | */ | 
|---|
| 5 | #include <linux/console.h> | 
|---|
| 6 | #include <linux/percpu.h> | 
|---|
| 7 | #include <linux/types.h> | 
|---|
| 8 |  | 
|---|
| 9 | #if defined(CONFIG_PRINTK) && defined(CONFIG_SYSCTL) | 
|---|
| 10 | struct ctl_table; | 
|---|
| 11 | void __init printk_sysctl_init(void); | 
|---|
| 12 | int devkmsg_sysctl_set_loglvl(const struct ctl_table *table, int write, | 
|---|
| 13 | void *buffer, size_t *lenp, loff_t *ppos); | 
|---|
| 14 | #else | 
|---|
| 15 | #define printk_sysctl_init() do { } while (0) | 
|---|
| 16 | #endif | 
|---|
| 17 |  | 
|---|
| 18 | #define con_printk(lvl, con, fmt, ...)				\ | 
|---|
| 19 | printk(lvl pr_fmt("%s%sconsole [%s%d] " fmt),		\ | 
|---|
| 20 | (con->flags & CON_NBCON) ? "" : "legacy ",	\ | 
|---|
| 21 | (con->flags & CON_BOOT) ? "boot" : "",		\ | 
|---|
| 22 | con->name, con->index, ##__VA_ARGS__) | 
|---|
| 23 |  | 
|---|
| 24 | /* | 
|---|
| 25 | * Identify if legacy printing is forced in a dedicated kthread. If | 
|---|
| 26 | * true, all printing via console lock occurs within a dedicated | 
|---|
| 27 | * legacy printer thread. The only exception is on panic, after the | 
|---|
| 28 | * nbcon consoles have had their chance to print the panic messages | 
|---|
| 29 | * first. | 
|---|
| 30 | */ | 
|---|
| 31 | #ifdef CONFIG_PREEMPT_RT | 
|---|
| 32 | # define force_legacy_kthread()	(true) | 
|---|
| 33 | #else | 
|---|
| 34 | # define force_legacy_kthread()	(false) | 
|---|
| 35 | #endif | 
|---|
| 36 |  | 
|---|
| 37 | #ifdef CONFIG_PRINTK | 
|---|
| 38 |  | 
|---|
| 39 | #ifdef CONFIG_PRINTK_CALLER | 
|---|
| 40 | #define PRINTK_PREFIX_MAX	48 | 
|---|
| 41 | #else | 
|---|
| 42 | #define PRINTK_PREFIX_MAX	32 | 
|---|
| 43 | #endif | 
|---|
| 44 |  | 
|---|
| 45 | /* | 
|---|
| 46 | * the maximum size of a formatted record (i.e. with prefix added | 
|---|
| 47 | * per line and dropped messages or in extended message format) | 
|---|
| 48 | */ | 
|---|
| 49 | #define PRINTK_MESSAGE_MAX	2048 | 
|---|
| 50 |  | 
|---|
| 51 | /* the maximum size allowed to be reserved for a record */ | 
|---|
| 52 | #define PRINTKRB_RECORD_MAX	1024 | 
|---|
| 53 |  | 
|---|
| 54 | /* Flags for a single printk record. */ | 
|---|
| 55 | enum printk_info_flags { | 
|---|
| 56 | /* always show on console, ignore console_loglevel */ | 
|---|
| 57 | LOG_FORCE_CON	= 1, | 
|---|
| 58 | LOG_NEWLINE	= 2,	/* text ended with a newline */ | 
|---|
| 59 | LOG_CONT	= 8,	/* text is a fragment of a continuation line */ | 
|---|
| 60 | }; | 
|---|
| 61 |  | 
|---|
| 62 | struct printk_ringbuffer; | 
|---|
| 63 | struct dev_printk_info; | 
|---|
| 64 |  | 
|---|
| 65 | extern struct printk_ringbuffer *prb; | 
|---|
| 66 | extern bool printk_kthreads_running; | 
|---|
| 67 | extern bool printk_kthreads_ready; | 
|---|
| 68 | extern bool debug_non_panic_cpus; | 
|---|
| 69 |  | 
|---|
| 70 | __printf(4, 0) | 
|---|
| 71 | int vprintk_store(int facility, int level, | 
|---|
| 72 | const struct dev_printk_info *dev_info, | 
|---|
| 73 | const char *fmt, va_list args); | 
|---|
| 74 |  | 
|---|
| 75 | __printf(1, 0) int vprintk_default(const char *fmt, va_list args); | 
|---|
| 76 |  | 
|---|
| 77 | void __printk_safe_enter(void); | 
|---|
| 78 | void __printk_safe_exit(void); | 
|---|
| 79 |  | 
|---|
| 80 | bool printk_percpu_data_ready(void); | 
|---|
| 81 |  | 
|---|
| 82 | #define printk_safe_enter_irqsave(flags)	\ | 
|---|
| 83 | do {					\ | 
|---|
| 84 | local_irq_save(flags);		\ | 
|---|
| 85 | __printk_safe_enter();		\ | 
|---|
| 86 | } while (0) | 
|---|
| 87 |  | 
|---|
| 88 | #define printk_safe_exit_irqrestore(flags)	\ | 
|---|
| 89 | do {					\ | 
|---|
| 90 | __printk_safe_exit();		\ | 
|---|
| 91 | local_irq_restore(flags);	\ | 
|---|
| 92 | } while (0) | 
|---|
| 93 |  | 
|---|
| 94 | void defer_console_output(void); | 
|---|
| 95 | bool is_printk_legacy_deferred(void); | 
|---|
| 96 | bool is_printk_force_console(void); | 
|---|
| 97 |  | 
|---|
| 98 | u16 printk_parse_prefix(const char *text, int *level, | 
|---|
| 99 | enum printk_info_flags *flags); | 
|---|
| 100 | void console_lock_spinning_enable(void); | 
|---|
| 101 | int console_lock_spinning_disable_and_check(int cookie); | 
|---|
| 102 |  | 
|---|
| 103 | u64 nbcon_seq_read(struct console *con); | 
|---|
| 104 | void nbcon_seq_force(struct console *con, u64 seq); | 
|---|
| 105 | bool nbcon_alloc(struct console *con); | 
|---|
| 106 | void nbcon_free(struct console *con); | 
|---|
| 107 | enum nbcon_prio nbcon_get_default_prio(void); | 
|---|
| 108 | void nbcon_atomic_flush_pending(void); | 
|---|
| 109 | bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, | 
|---|
| 110 | int cookie, bool use_atomic); | 
|---|
| 111 | bool nbcon_kthread_create(struct console *con); | 
|---|
| 112 | void nbcon_kthread_stop(struct console *con); | 
|---|
| 113 | void nbcon_kthreads_wake(void); | 
|---|
| 114 |  | 
|---|
| 115 | /* | 
|---|
| 116 | * Check if the given console is currently capable and allowed to print | 
|---|
| 117 | * records. Note that this function does not consider the current context, | 
|---|
| 118 | * which can also play a role in deciding if @con can be used to print | 
|---|
| 119 | * records. | 
|---|
| 120 | */ | 
|---|
| 121 | static inline bool console_is_usable(struct console *con, short flags, bool use_atomic) | 
|---|
| 122 | { | 
|---|
| 123 | if (!(flags & CON_ENABLED)) | 
|---|
| 124 | return false; | 
|---|
| 125 |  | 
|---|
| 126 | if ((flags & CON_SUSPENDED)) | 
|---|
| 127 | return false; | 
|---|
| 128 |  | 
|---|
| 129 | if (flags & CON_NBCON) { | 
|---|
| 130 | /* The write_atomic() callback is optional. */ | 
|---|
| 131 | if (use_atomic && !con->write_atomic) | 
|---|
| 132 | return false; | 
|---|
| 133 |  | 
|---|
| 134 | /* | 
|---|
| 135 | * For the !use_atomic case, @printk_kthreads_running is not | 
|---|
| 136 | * checked because the write_thread() callback is also used | 
|---|
| 137 | * via the legacy loop when the printer threads are not | 
|---|
| 138 | * available. | 
|---|
| 139 | */ | 
|---|
| 140 | } else { | 
|---|
| 141 | if (!con->write) | 
|---|
| 142 | return false; | 
|---|
| 143 | } | 
|---|
| 144 |  | 
|---|
| 145 | /* | 
|---|
| 146 | * Console drivers may assume that per-cpu resources have been | 
|---|
| 147 | * allocated. So unless they're explicitly marked as being able to | 
|---|
| 148 | * cope (CON_ANYTIME) don't call them until this CPU is officially up. | 
|---|
| 149 | */ | 
|---|
| 150 | if (!cpu_online(raw_smp_processor_id()) && !(flags & CON_ANYTIME)) | 
|---|
| 151 | return false; | 
|---|
| 152 |  | 
|---|
| 153 | return true; | 
|---|
| 154 | } | 
|---|
| 155 |  | 
|---|
| 156 | /** | 
|---|
| 157 | * nbcon_kthread_wake - Wake up a console printing thread | 
|---|
| 158 | * @con:	Console to operate on | 
|---|
| 159 | */ | 
|---|
| 160 | static inline void nbcon_kthread_wake(struct console *con) | 
|---|
| 161 | { | 
|---|
| 162 | /* | 
|---|
| 163 | * Guarantee any new records can be seen by tasks preparing to wait | 
|---|
| 164 | * before this context checks if the rcuwait is empty. | 
|---|
| 165 | * | 
|---|
| 166 | * The full memory barrier in rcuwait_wake_up() pairs with the full | 
|---|
| 167 | * memory barrier within set_current_state() of | 
|---|
| 168 | * ___rcuwait_wait_event(), which is called after prepare_to_rcuwait() | 
|---|
| 169 | * adds the waiter but before it has checked the wait condition. | 
|---|
| 170 | * | 
|---|
| 171 | * This pairs with nbcon_kthread_func:A. | 
|---|
| 172 | */ | 
|---|
| 173 | rcuwait_wake_up(w: &con->rcuwait); /* LMM(nbcon_kthread_wake:A) */ | 
|---|
| 174 | } | 
|---|
| 175 |  | 
|---|
| 176 | #else | 
|---|
| 177 |  | 
|---|
| 178 | #define PRINTK_PREFIX_MAX	0 | 
|---|
| 179 | #define PRINTK_MESSAGE_MAX	0 | 
|---|
| 180 | #define PRINTKRB_RECORD_MAX	0 | 
|---|
| 181 |  | 
|---|
| 182 | #define printk_kthreads_running (false) | 
|---|
| 183 | #define printk_kthreads_ready (false) | 
|---|
| 184 |  | 
|---|
| 185 | /* | 
|---|
| 186 | * In !PRINTK builds we still export console_sem | 
|---|
| 187 | * semaphore and some of console functions (console_unlock()/etc.), so | 
|---|
| 188 | * printk-safe must preserve the existing local IRQ guarantees. | 
|---|
| 189 | */ | 
|---|
| 190 | #define printk_safe_enter_irqsave(flags) local_irq_save(flags) | 
|---|
| 191 | #define printk_safe_exit_irqrestore(flags) local_irq_restore(flags) | 
|---|
| 192 |  | 
|---|
| 193 | static inline bool printk_percpu_data_ready(void) { return false; } | 
|---|
| 194 | static inline void defer_console_output(void) { } | 
|---|
| 195 | static inline bool is_printk_legacy_deferred(void) { return false; } | 
|---|
| 196 | static inline u64 nbcon_seq_read(struct console *con) { return 0; } | 
|---|
| 197 | static inline void nbcon_seq_force(struct console *con, u64 seq) { } | 
|---|
| 198 | static inline bool nbcon_alloc(struct console *con) { return false; } | 
|---|
| 199 | static inline void nbcon_free(struct console *con) { } | 
|---|
| 200 | static inline enum nbcon_prio nbcon_get_default_prio(void) { return NBCON_PRIO_NONE; } | 
|---|
| 201 | static inline void nbcon_atomic_flush_pending(void) { } | 
|---|
| 202 | static inline bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, | 
|---|
| 203 | int cookie, bool use_atomic) { return false; } | 
|---|
| 204 | static inline void nbcon_kthread_wake(struct console *con) { } | 
|---|
| 205 | static inline void nbcon_kthreads_wake(void) { } | 
|---|
| 206 |  | 
|---|
| 207 | static inline bool console_is_usable(struct console *con, short flags, | 
|---|
| 208 | bool use_atomic) { return false; } | 
|---|
| 209 |  | 
|---|
| 210 | #endif /* CONFIG_PRINTK */ | 
|---|
| 211 |  | 
|---|
| 212 | extern bool have_boot_console; | 
|---|
| 213 | extern bool have_nbcon_console; | 
|---|
| 214 | extern bool have_legacy_console; | 
|---|
| 215 | extern bool legacy_allow_panic_sync; | 
|---|
| 216 |  | 
|---|
| 217 | /** | 
|---|
| 218 | * struct console_flush_type - Define available console flush methods | 
|---|
| 219 | * @nbcon_atomic:	Flush directly using nbcon_atomic() callback | 
|---|
| 220 | * @nbcon_offload:	Offload flush to printer thread | 
|---|
| 221 | * @legacy_direct:	Call the legacy loop in this context | 
|---|
| 222 | * @legacy_offload:	Offload the legacy loop into IRQ or legacy thread | 
|---|
| 223 | * | 
|---|
| 224 | * Note that the legacy loop also flushes the nbcon consoles. | 
|---|
| 225 | */ | 
|---|
| 226 | struct console_flush_type { | 
|---|
| 227 | bool	nbcon_atomic; | 
|---|
| 228 | bool	nbcon_offload; | 
|---|
| 229 | bool	legacy_direct; | 
|---|
| 230 | bool	legacy_offload; | 
|---|
| 231 | }; | 
|---|
| 232 |  | 
|---|
| 233 | /* | 
|---|
| 234 | * Identify which console flushing methods should be used in the context of | 
|---|
| 235 | * the caller. | 
|---|
| 236 | */ | 
|---|
| 237 | static inline void printk_get_console_flush_type(struct console_flush_type *ft) | 
|---|
| 238 | { | 
|---|
| 239 | memset(s: ft, c: 0, n: sizeof(*ft)); | 
|---|
| 240 |  | 
|---|
| 241 | switch (nbcon_get_default_prio()) { | 
|---|
| 242 | case NBCON_PRIO_NORMAL: | 
|---|
| 243 | if (have_nbcon_console && !have_boot_console) { | 
|---|
| 244 | if (printk_kthreads_running) | 
|---|
| 245 | ft->nbcon_offload = true; | 
|---|
| 246 | else | 
|---|
| 247 | ft->nbcon_atomic = true; | 
|---|
| 248 | } | 
|---|
| 249 |  | 
|---|
| 250 | /* Legacy consoles are flushed directly when possible. */ | 
|---|
| 251 | if (have_legacy_console || have_boot_console) { | 
|---|
| 252 | if (!is_printk_legacy_deferred()) | 
|---|
| 253 | ft->legacy_direct = true; | 
|---|
| 254 | else | 
|---|
| 255 | ft->legacy_offload = true; | 
|---|
| 256 | } | 
|---|
| 257 | break; | 
|---|
| 258 |  | 
|---|
| 259 | case NBCON_PRIO_EMERGENCY: | 
|---|
| 260 | if (have_nbcon_console && !have_boot_console) | 
|---|
| 261 | ft->nbcon_atomic = true; | 
|---|
| 262 |  | 
|---|
| 263 | /* Legacy consoles are flushed directly when possible. */ | 
|---|
| 264 | if (have_legacy_console || have_boot_console) { | 
|---|
| 265 | if (!is_printk_legacy_deferred()) | 
|---|
| 266 | ft->legacy_direct = true; | 
|---|
| 267 | else | 
|---|
| 268 | ft->legacy_offload = true; | 
|---|
| 269 | } | 
|---|
| 270 | break; | 
|---|
| 271 |  | 
|---|
| 272 | case NBCON_PRIO_PANIC: | 
|---|
| 273 | /* | 
|---|
| 274 | * In panic, the nbcon consoles will directly print. But | 
|---|
| 275 | * only allowed if there are no boot consoles. | 
|---|
| 276 | */ | 
|---|
| 277 | if (have_nbcon_console && !have_boot_console) | 
|---|
| 278 | ft->nbcon_atomic = true; | 
|---|
| 279 |  | 
|---|
| 280 | if (have_legacy_console || have_boot_console) { | 
|---|
| 281 | /* | 
|---|
| 282 | * This is the same decision as NBCON_PRIO_NORMAL | 
|---|
| 283 | * except that offloading never occurs in panic. | 
|---|
| 284 | * | 
|---|
| 285 | * Note that console_flush_on_panic() will flush | 
|---|
| 286 | * legacy consoles anyway, even if unsafe. | 
|---|
| 287 | */ | 
|---|
| 288 | if (!is_printk_legacy_deferred()) | 
|---|
| 289 | ft->legacy_direct = true; | 
|---|
| 290 |  | 
|---|
| 291 | /* | 
|---|
| 292 | * In panic, if nbcon atomic printing occurs, | 
|---|
| 293 | * the legacy consoles must remain silent until | 
|---|
| 294 | * explicitly allowed. | 
|---|
| 295 | */ | 
|---|
| 296 | if (ft->nbcon_atomic && !legacy_allow_panic_sync) | 
|---|
| 297 | ft->legacy_direct = false; | 
|---|
| 298 | } | 
|---|
| 299 | break; | 
|---|
| 300 |  | 
|---|
| 301 | default: | 
|---|
| 302 | WARN_ON_ONCE(1); | 
|---|
| 303 | break; | 
|---|
| 304 | } | 
|---|
| 305 | } | 
|---|
| 306 |  | 
|---|
| 307 | extern struct printk_buffers printk_shared_pbufs; | 
|---|
| 308 |  | 
|---|
| 309 | /** | 
|---|
| 310 | * struct printk_buffers - Buffers to read/format/output printk messages. | 
|---|
| 311 | * @outbuf:	After formatting, contains text to output. | 
|---|
| 312 | * @scratchbuf:	Used as temporary ringbuffer reading and string-print space. | 
|---|
| 313 | */ | 
|---|
| 314 | struct printk_buffers { | 
|---|
| 315 | char	outbuf[PRINTK_MESSAGE_MAX]; | 
|---|
| 316 | char	scratchbuf[PRINTKRB_RECORD_MAX]; | 
|---|
| 317 | }; | 
|---|
| 318 |  | 
|---|
| 319 | /** | 
|---|
| 320 | * struct printk_message - Container for a prepared printk message. | 
|---|
| 321 | * @pbufs:	printk buffers used to prepare the message. | 
|---|
| 322 | * @outbuf_len:	The length of prepared text in @pbufs->outbuf to output. This | 
|---|
| 323 | *		does not count the terminator. A value of 0 means there is | 
|---|
| 324 | *		nothing to output and this record should be skipped. | 
|---|
| 325 | * @seq:	The sequence number of the record used for @pbufs->outbuf. | 
|---|
| 326 | * @dropped:	The number of dropped records from reading @seq. | 
|---|
| 327 | */ | 
|---|
| 328 | struct printk_message { | 
|---|
| 329 | struct printk_buffers	*pbufs; | 
|---|
| 330 | unsigned int		outbuf_len; | 
|---|
| 331 | u64			seq; | 
|---|
| 332 | unsigned long		dropped; | 
|---|
| 333 | }; | 
|---|
| 334 |  | 
|---|
| 335 | bool printk_get_next_message(struct printk_message *pmsg, u64 seq, | 
|---|
| 336 | bool is_extended, bool may_supress); | 
|---|
| 337 |  | 
|---|
| 338 | #ifdef CONFIG_PRINTK | 
|---|
| 339 | void console_prepend_dropped(struct printk_message *pmsg, unsigned long dropped); | 
|---|
| 340 | void console_prepend_replay(struct printk_message *pmsg); | 
|---|
| 341 | #endif | 
|---|
| 342 |  | 
|---|
| 343 | #ifdef CONFIG_SMP | 
|---|
| 344 | bool is_printk_cpu_sync_owner(void); | 
|---|
| 345 | #else | 
|---|
| 346 | static inline bool is_printk_cpu_sync_owner(void) { return false; } | 
|---|
| 347 | #endif | 
|---|
| 348 |  | 
|---|