hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
kernel/kernel/printk/printk.c
....@@ -47,6 +47,7 @@
4747 #include <linux/sched/clock.h>
4848 #include <linux/sched/debug.h>
4949 #include <linux/sched/task_stack.h>
50
+#include <linux/irqstage.h>
5051
5152 #include <linux/uaccess.h>
5253 #include <asm/sections.h>
....@@ -2188,6 +2189,73 @@
21882189 }
21892190 #endif
21902191
2192
+#ifdef CONFIG_RAW_PRINTK
2193
+static struct console *raw_console;
2194
+static DEFINE_HARD_SPINLOCK(raw_console_lock);
2195
+
2196
+void raw_puts(const char *s, size_t len)
2197
+{
2198
+ unsigned long flags;
2199
+
2200
+ raw_spin_lock_irqsave(&raw_console_lock, flags);
2201
+ if (raw_console)
2202
+ raw_console->write_raw(raw_console, s, len);
2203
+ raw_spin_unlock_irqrestore(&raw_console_lock, flags);
2204
+}
2205
+EXPORT_SYMBOL(raw_puts);
2206
+
2207
+void raw_vprintk(const char *fmt, va_list ap)
2208
+{
2209
+ char buf[256];
2210
+ size_t n;
2211
+
2212
+ if (raw_console == NULL || console_suspended)
2213
+ return;
2214
+
2215
+ touch_nmi_watchdog();
2216
+ n = vscnprintf(buf, sizeof(buf), fmt, ap);
2217
+ raw_puts(buf, n);
2218
+}
2219
+EXPORT_SYMBOL(raw_vprintk);
2220
+
2221
+asmlinkage __visible void raw_printk(const char *fmt, ...)
2222
+{
2223
+ va_list ap;
2224
+
2225
+ va_start(ap, fmt);
2226
+ raw_vprintk(fmt, ap);
2227
+ va_end(ap);
2228
+}
2229
+EXPORT_SYMBOL(raw_printk);
2230
+
2231
+static inline void register_raw_console(struct console *newcon)
2232
+{
2233
+ unsigned long flags;
2234
+
2235
+ raw_spin_lock_irqsave(&raw_console_lock, flags);
2236
+ if (newcon->write_raw)
2237
+ raw_console = newcon;
2238
+ raw_spin_unlock_irqrestore(&raw_console_lock, flags);
2239
+}
2240
+
2241
+static inline void unregister_raw_console(struct console *oldcon)
2242
+{
2243
+ unsigned long flags;
2244
+
2245
+ raw_spin_lock_irqsave(&raw_console_lock, flags);
2246
+ if (oldcon == raw_console)
2247
+ raw_console = NULL;
2248
+ raw_spin_unlock_irqrestore(&raw_console_lock, flags);
2249
+}
2250
+
2251
+#else
2252
+
2253
+static inline void register_raw_console(struct console *newcon) { }
2254
+
2255
+static inline void unregister_raw_console(struct console *oldcon) { }
2256
+
2257
+#endif
2258
+
21912259 static int __add_preferred_console(char *name, int idx, char *options,
21922260 char *brl_options, bool user_specified)
21932261 {
....@@ -2854,6 +2922,9 @@
28542922 if (err || newcon->flags & CON_BRL)
28552923 return;
28562924
2925
+ /* The latest raw console to register is current. */
2926
+ register_raw_console(newcon);
2927
+
28572928 /*
28582929 * If we have a bootconsole, and are switching to a real console,
28592930 * don't print everything out again, since when the boot console, and
....@@ -2938,6 +3009,8 @@
29383009 (console->flags & CON_BOOT) ? "boot" : "" ,
29393010 console->name, console->index);
29403011
3012
+ unregister_raw_console(console);
3013
+
29413014 res = _braille_unregister_console(console);
29423015 if (res < 0)
29433016 return res;