diff options
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.patch | 109 |
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 |