summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0007-printk-nbcon-Use-driver-synchronization-while-un-reg.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches-rt/0007-printk-nbcon-Use-driver-synchronization-while-un-reg.patch')
-rw-r--r--debian/patches-rt/0007-printk-nbcon-Use-driver-synchronization-while-un-reg.patch109
1 files changed, 109 insertions, 0 deletions
diff --git a/debian/patches-rt/0007-printk-nbcon-Use-driver-synchronization-while-un-reg.patch b/debian/patches-rt/0007-printk-nbcon-Use-driver-synchronization-while-un-reg.patch
new file mode 100644
index 0000000000..08e2d52852
--- /dev/null
+++ b/debian/patches-rt/0007-printk-nbcon-Use-driver-synchronization-while-un-reg.patch
@@ -0,0 +1,109 @@
+From: John Ogness <john.ogness@linutronix.de>
+Date: Fri, 15 Mar 2024 15:38:22 +0000
+Subject: [PATCH 07/46] printk: nbcon: Use driver synchronization while
+ (un)registering
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.9/older/patches-6.9-rt5.tar.xz
+
+Console drivers typically have to deal with access to the
+hardware via user input/output (such as an interactive login
+shell) and output of kernel messages via printk() calls.
+
+They use some classic driver-specific locking mechanism in most
+situations. But console->write_atomic() callbacks, used by nbcon
+consoles, are synchronized only by acquiring the console
+context.
+
+The synchronization via the console context ownership is possible
+only when the console driver is registered. It is when a
+particular device driver is connected with a particular console
+driver.
+
+The two synchronization mechanisms must be synchronized between
+each other. It is tricky because the console context ownership
+is quite special. It might be taken over by a higher priority
+context. Also CPU migration must be disabled. The most tricky
+part is to (dis)connect these two mechanisms during the console
+(un)registration.
+
+Use the driver-specific locking callbacks: device_lock(),
+device_unlock(). They allow taking the device-specific lock
+while the device is being (un)registered by the related console
+driver.
+
+For example, these callbacks lock/unlock the port lock for
+serial port drivers.
+
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ kernel/printk/printk.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+--- a/kernel/printk/printk.c
++++ b/kernel/printk/printk.c
+@@ -3466,6 +3466,7 @@ void register_console(struct console *ne
+ struct console *con;
+ bool bootcon_registered = false;
+ bool realcon_registered = false;
++ unsigned long flags;
+ u64 init_seq;
+ int err;
+
+@@ -3553,6 +3554,19 @@ void register_console(struct console *ne
+ }
+
+ /*
++ * If another context is actively using the hardware of this new
++ * console, it will not be aware of the nbcon synchronization. This
++ * is a risk that two contexts could access the hardware
++ * simultaneously if this new console is used for atomic printing
++ * and the other context is still using the hardware.
++ *
++ * Use the driver synchronization to ensure that the hardware is not
++ * in use while this new console transitions to being registered.
++ */
++ if ((newcon->flags & CON_NBCON) && newcon->write_atomic)
++ newcon->device_lock(newcon, &flags);
++
++ /*
+ * Put this console in the list - keep the
+ * preferred driver at the head of the list.
+ */
+@@ -3576,6 +3590,10 @@ void register_console(struct console *ne
+ * register_console() completes.
+ */
+
++ /* This new console is now registered. */
++ if ((newcon->flags & CON_NBCON) && newcon->write_atomic)
++ newcon->device_unlock(newcon, flags);
++
+ console_sysfs_notify();
+
+ /*
+@@ -3604,6 +3622,7 @@ EXPORT_SYMBOL(register_console);
+ /* Must be called under console_list_lock(). */
+ static int unregister_console_locked(struct console *console)
+ {
++ unsigned long flags;
+ int res;
+
+ lockdep_assert_console_list_lock_held();
+@@ -3622,8 +3641,18 @@ static int unregister_console_locked(str
+ if (!console_is_registered_locked(console))
+ return -ENODEV;
+
++ /*
++ * Use the driver synchronization to ensure that the hardware is not
++ * in use while this console transitions to being unregistered.
++ */
++ if ((console->flags & CON_NBCON) && console->write_atomic)
++ console->device_lock(console, &flags);
++
+ hlist_del_init_rcu(&console->node);
+
++ if ((console->flags & CON_NBCON) && console->write_atomic)
++ console->device_unlock(console, flags);
++
+ /*
+ * <HISTORICAL>
+ * If this isn't the last console and it has CON_CONSDEV set, we