summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2020-09-02 17:14:58 +0200
committerSebastian Andrzej Siewior <bigeasy@linutronix.de>2020-09-02 17:14:58 +0200
commit44720d4bfbf882109ae80c67314d7f8d633261f7 (patch)
treeeed335c501c0c1e285a4bb27863591597012fae5
parentc8161ca246b9e010fa418efe8941889721a142c0 (diff)
downloadlinux-rt-44720d4bfbf882109ae80c67314d7f8d633261f7.tar.gz
[ANNOUNCE] v5.9-rc3-rt3v5.9-rc3-rt3-patches
Dear RT folks! I'm pleased to announce the v5.9-rc3-rt3 patch set. Changes since v5.9-rc3-rt2: - Correct a compile issue in the i915 driver. Reported by Carsten Emde and Daniel Wagner. - Mark Marshall reported a crash on PowerPC. The reason for the crash is a race in exec_mmap() vs a context switch and is not limited to PowerPC. This race is present since v5.4.3-rt1 and is addressed in two changes: - commit 38cf307c1f201 ("mm: fix kthread_use_mm() vs TLB invalidate") which is part of v5.9-rc1. - patch "mm: fix exec activate_mm vs TLB shootdown and lazy tlb switching race" by Nicholas Piggin which has been posted for review and is not yet merged upstream. Known issues - It has been pointed out that due to changes to the printk code the internal buffer representation changed. This is only an issue if tools like `crash' are used to extract the printk buffer from a kernel memory image. The delta patch against v5.9-rc3-rt2 is appended below and can be found here: https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.9/incr/patch-5.9-rc3-rt2-rt3.patch.xz You can get this release via the git tree at: git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git v5.9-rc3-rt3 The RT patch against v5.9-rc3 can be found here: https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.9/older/patch-5.9-rc3-rt3.patch.xz The split quilt queue is available at: https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.9/older/patches-5.9-rc3-rt3.tar.xz Sebastian Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-rw-r--r--patches/0020-serial-8250-implement-write_atomic.patch22
-rw-r--r--patches/block-mq-drop-preempt-disable.patch2
-rw-r--r--patches/drivers-tty-fix-omap-lock-crap.patch4
-rw-r--r--patches/drm-i915-Don-t-disable-interrupts-on-PREEMPT_RT-duri.patch73
-rw-r--r--patches/drmi915_Use_local_lockunlock_irq()_in_intel_pipe_update_startend().patch123
-rw-r--r--patches/localversion.patch2
-rw-r--r--patches/md-raid5-percpu-handling-rt-aware.patch2
-rw-r--r--patches/mm-fix-exec-activate_mm-vs-TLB-shootdown-and-lazy-tl.patch102
-rw-r--r--patches/serial-8250-only-atomic-lock-for-console.patch12
-rw-r--r--patches/serial-8250-remove-that-trylock-in-serial8250_consol.patch4
-rw-r--r--patches/series7
-rw-r--r--patches/x86-kvm-require-const-tsc-for-rt.patch2
12 files changed, 206 insertions, 149 deletions
diff --git a/patches/0020-serial-8250-implement-write_atomic.patch b/patches/0020-serial-8250-implement-write_atomic.patch
index 6f689a090316..e0b52325853f 100644
--- a/patches/0020-serial-8250-implement-write_atomic.patch
+++ b/patches/0020-serial-8250-implement-write_atomic.patch
@@ -290,7 +290,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
serial8250_rpm_put(up);
}
-@@ -2438,7 +2476,7 @@ void serial8250_do_shutdown(struct uart_
+@@ -2441,7 +2479,7 @@ void serial8250_do_shutdown(struct uart_
*/
spin_lock_irqsave(&port->lock, flags);
up->ier = 0;
@@ -299,7 +299,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
spin_unlock_irqrestore(&port->lock, flags);
synchronize_irq(port->irq);
-@@ -2765,7 +2803,7 @@ serial8250_do_set_termios(struct uart_po
+@@ -2768,7 +2806,7 @@ serial8250_do_set_termios(struct uart_po
if (up->capabilities & UART_CAP_RTOIE)
up->ier |= UART_IER_RTOIE;
@@ -308,7 +308,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (up->capabilities & UART_CAP_EFR) {
unsigned char efr = 0;
-@@ -3231,7 +3269,7 @@ EXPORT_SYMBOL_GPL(serial8250_set_default
+@@ -3234,7 +3272,7 @@ EXPORT_SYMBOL_GPL(serial8250_set_default
#ifdef CONFIG_SERIAL_8250_CONSOLE
@@ -317,7 +317,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
{
struct uart_8250_port *up = up_to_u8250p(port);
-@@ -3239,6 +3277,18 @@ static void serial8250_console_putchar(s
+@@ -3242,6 +3280,18 @@ static void serial8250_console_putchar(s
serial_port_out(port, UART_TX, ch);
}
@@ -336,7 +336,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
/*
* Restore serial console when h/w power-off detected
*/
-@@ -3260,6 +3310,42 @@ static void serial8250_console_restore(s
+@@ -3263,6 +3313,42 @@ static void serial8250_console_restore(s
serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS);
}
@@ -379,7 +379,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
/*
* Print a string to the serial port trying not to disturb
* any possible real use of the port...
-@@ -3275,25 +3361,12 @@ void serial8250_console_write(struct uar
+@@ -3278,25 +3364,12 @@ void serial8250_console_write(struct uar
struct uart_8250_em485 *em485 = up->em485;
struct uart_port *port = &up->port;
unsigned long flags;
@@ -407,7 +407,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
/* check scratch reg to see if port powered off during system sleep */
if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) {
-@@ -3307,7 +3380,9 @@ void serial8250_console_write(struct uar
+@@ -3310,7 +3383,9 @@ void serial8250_console_write(struct uar
mdelay(port->rs485.delay_rts_before_send);
}
@@ -417,7 +417,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
/*
* Finally, wait for transmitter to become empty
-@@ -3321,7 +3396,7 @@ void serial8250_console_write(struct uar
+@@ -3324,7 +3399,7 @@ void serial8250_console_write(struct uar
up->rs485_stop_tx(up);
}
@@ -426,7 +426,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
/*
* The receive handling will happen properly because the
-@@ -3333,8 +3408,7 @@ void serial8250_console_write(struct uar
+@@ -3336,8 +3411,7 @@ void serial8250_console_write(struct uar
if (up->msr_saved_flags)
serial8250_modem_status(up);
@@ -436,7 +436,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
static unsigned int probe_baud(struct uart_port *port)
-@@ -3354,6 +3428,7 @@ static unsigned int probe_baud(struct ua
+@@ -3357,6 +3431,7 @@ static unsigned int probe_baud(struct ua
int serial8250_console_setup(struct uart_port *port, char *options, bool probe)
{
@@ -444,7 +444,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
int baud = 9600;
int bits = 8;
int parity = 'n';
-@@ -3363,6 +3438,8 @@ int serial8250_console_setup(struct uart
+@@ -3366,6 +3441,8 @@ int serial8250_console_setup(struct uart
if (!port->iobase && !port->membase)
return -ENODEV;
diff --git a/patches/block-mq-drop-preempt-disable.patch b/patches/block-mq-drop-preempt-disable.patch
index 87bb7ee04c08..40569618ebce 100644
--- a/patches/block-mq-drop-preempt-disable.patch
+++ b/patches/block-mq-drop-preempt-disable.patch
@@ -13,7 +13,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
-@@ -1599,14 +1599,14 @@ static void __blk_mq_delay_run_hw_queue(
+@@ -1608,14 +1608,14 @@ static void __blk_mq_delay_run_hw_queue(
return;
if (!async && !(hctx->flags & BLK_MQ_F_BLOCKING)) {
diff --git a/patches/drivers-tty-fix-omap-lock-crap.patch b/patches/drivers-tty-fix-omap-lock-crap.patch
index 01c691f0b717..1e7206eb5b34 100644
--- a/patches/drivers-tty-fix-omap-lock-crap.patch
+++ b/patches/drivers-tty-fix-omap-lock-crap.patch
@@ -13,7 +13,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
-@@ -1303,13 +1303,10 @@ serial_omap_console_write(struct console
+@@ -1301,13 +1301,10 @@ serial_omap_console_write(struct console
pm_runtime_get_sync(up->dev);
@@ -30,7 +30,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
/*
* First save the IER then disable the interrupts
-@@ -1338,8 +1335,7 @@ serial_omap_console_write(struct console
+@@ -1336,8 +1333,7 @@ serial_omap_console_write(struct console
pm_runtime_mark_last_busy(up->dev);
pm_runtime_put_autosuspend(up->dev);
if (locked)
diff --git a/patches/drm-i915-Don-t-disable-interrupts-on-PREEMPT_RT-duri.patch b/patches/drm-i915-Don-t-disable-interrupts-on-PREEMPT_RT-duri.patch
new file mode 100644
index 000000000000..867c70691953
--- /dev/null
+++ b/patches/drm-i915-Don-t-disable-interrupts-on-PREEMPT_RT-duri.patch
@@ -0,0 +1,73 @@
+From: Mike Galbraith <umgwanakikbuti@gmail.com>
+Date: Sat, 27 Feb 2016 09:01:42 +0100
+Subject: [PATCH] drm/i915: Don't disable interrupts on PREEMPT_RT during
+ atomic updates
+
+Commit
+ 8d7849db3eab7 ("drm/i915: Make sprite updates atomic")
+
+started disabling interrupts across atomic updates. This breaks on PREEMPT_RT
+because within this section the code attempt to acquire spinlock_t locks which
+are sleeping locks on PREEMPT_RT.
+
+According to the comment the interrupts are disabled to avoid random delays and
+not required for protection or synchronisation.
+
+Don't disable interrupts on PREEMPT_RT during atomic updates.
+
+[bigeasy: drop local locks, commit message]
+
+Signed-off-by: Mike Galbraith <umgwanakikbuti@gmail.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/gpu/drm/i915/display/intel_sprite.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/i915/display/intel_sprite.c
++++ b/drivers/gpu/drm/i915/display/intel_sprite.c
+@@ -118,7 +118,8 @@ void intel_pipe_update_start(const struc
+ "PSR idle timed out 0x%x, atomic update may fail\n",
+ psr_status);
+
+- local_irq_disable();
++ if (!IS_ENABLED(CONFIG_PREEMPT_RT))
++ local_irq_disable();
+
+ crtc->debug.min_vbl = min;
+ crtc->debug.max_vbl = max;
+@@ -143,11 +144,13 @@ void intel_pipe_update_start(const struc
+ break;
+ }
+
+- local_irq_enable();
++ if (!IS_ENABLED(CONFIG_PREEMPT_RT))
++ local_irq_enable();
+
+ timeout = schedule_timeout(timeout);
+
+- local_irq_disable();
++ if (!IS_ENABLED(CONFIG_PREEMPT_RT))
++ local_irq_disable();
+ }
+
+ finish_wait(wq, &wait);
+@@ -180,7 +183,8 @@ void intel_pipe_update_start(const struc
+ return;
+
+ irq_disable:
+- local_irq_disable();
++ if (!IS_ENABLED(CONFIG_PREEMPT_RT))
++ local_irq_disable();
+ }
+
+ /**
+@@ -218,7 +222,8 @@ void intel_pipe_update_end(struct intel_
+ new_crtc_state->uapi.event = NULL;
+ }
+
+- local_irq_enable();
++ if (!IS_ENABLED(CONFIG_PREEMPT_RT))
++ local_irq_enable();
+
+ if (intel_vgpu_active(dev_priv))
+ return;
diff --git a/patches/drmi915_Use_local_lockunlock_irq()_in_intel_pipe_update_startend().patch b/patches/drmi915_Use_local_lockunlock_irq()_in_intel_pipe_update_startend().patch
deleted file mode 100644
index 276d8897e0bb..000000000000
--- a/patches/drmi915_Use_local_lockunlock_irq()_in_intel_pipe_update_startend().patch
+++ /dev/null
@@ -1,123 +0,0 @@
-Subject: drm,i915: Use local_lock/unlock_irq() in intel_pipe_update_start/end()
-From: Mike Galbraith <umgwanakikbuti@gmail.com>
-Date: Sat, 27 Feb 2016 09:01:42 +0100
-
-
-[ 8.014039] BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:918
-[ 8.014041] in_atomic(): 0, irqs_disabled(): 1, pid: 78, name: kworker/u4:4
-[ 8.014045] CPU: 1 PID: 78 Comm: kworker/u4:4 Not tainted 4.1.7-rt7 #5
-[ 8.014055] Workqueue: events_unbound async_run_entry_fn
-[ 8.014059] 0000000000000000 ffff880037153748 ffffffff815f32c9 0000000000000002
-[ 8.014063] ffff88013a50e380 ffff880037153768 ffffffff815ef075 ffff8800372c06c8
-[ 8.014066] ffff8800372c06c8 ffff880037153778 ffffffff8107c0b3 ffff880037153798
-[ 8.014067] Call Trace:
-[ 8.014074] [<ffffffff815f32c9>] dump_stack+0x4a/0x61
-[ 8.014078] [<ffffffff815ef075>] ___might_sleep.part.93+0xe9/0xee
-[ 8.014082] [<ffffffff8107c0b3>] ___might_sleep+0x53/0x80
-[ 8.014086] [<ffffffff815f9064>] rt_spin_lock+0x24/0x50
-[ 8.014090] [<ffffffff8109368b>] prepare_to_wait+0x2b/0xa0
-[ 8.014152] [<ffffffffa016c04c>] intel_pipe_update_start+0x17c/0x300 [i915]
-[ 8.014156] [<ffffffff81093b40>] ? prepare_to_wait_event+0x120/0x120
-[ 8.014201] [<ffffffffa0158f36>] intel_begin_crtc_commit+0x166/0x1e0 [i915]
-[ 8.014215] [<ffffffffa00c806d>] drm_atomic_helper_commit_planes+0x5d/0x1a0 [drm_kms_helper]
-[ 8.014260] [<ffffffffa0171e9b>] intel_atomic_commit+0xab/0xf0 [i915]
-[ 8.014288] [<ffffffffa00654c7>] drm_atomic_commit+0x37/0x60 [drm]
-[ 8.014298] [<ffffffffa00c6fcd>] drm_atomic_helper_plane_set_property+0x8d/0xd0 [drm_kms_helper]
-[ 8.014301] [<ffffffff815f77d9>] ? __ww_mutex_lock+0x39/0x40
-[ 8.014319] [<ffffffffa0053b3d>] drm_mode_plane_set_obj_prop+0x2d/0x90 [drm]
-[ 8.014328] [<ffffffffa00c8edb>] restore_fbdev_mode+0x6b/0xf0 [drm_kms_helper]
-[ 8.014337] [<ffffffffa00cae49>] drm_fb_helper_restore_fbdev_mode_unlocked+0x29/0x80 [drm_kms_helper]
-[ 8.014346] [<ffffffffa00caec2>] drm_fb_helper_set_par+0x22/0x50 [drm_kms_helper]
-[ 8.014390] [<ffffffffa016dfba>] intel_fbdev_set_par+0x1a/0x60 [i915]
-[ 8.014394] [<ffffffff81327dc4>] fbcon_init+0x4f4/0x580
-[ 8.014398] [<ffffffff8139ef4c>] visual_init+0xbc/0x120
-[ 8.014401] [<ffffffff813a1623>] do_bind_con_driver+0x163/0x330
-[ 8.014405] [<ffffffff813a1b2c>] do_take_over_console+0x11c/0x1c0
-[ 8.014408] [<ffffffff813236e3>] do_fbcon_takeover+0x63/0xd0
-[ 8.014410] [<ffffffff81328965>] fbcon_event_notify+0x785/0x8d0
-[ 8.014413] [<ffffffff8107c12d>] ? __might_sleep+0x4d/0x90
-[ 8.014416] [<ffffffff810775fe>] notifier_call_chain+0x4e/0x80
-[ 8.014419] [<ffffffff810779cd>] __blocking_notifier_call_chain+0x4d/0x70
-[ 8.014422] [<ffffffff81077a06>] blocking_notifier_call_chain+0x16/0x20
-[ 8.014425] [<ffffffff8132b48b>] fb_notifier_call_chain+0x1b/0x20
-[ 8.014428] [<ffffffff8132d8fa>] register_framebuffer+0x21a/0x350
-[ 8.014439] [<ffffffffa00cb164>] drm_fb_helper_initial_config+0x274/0x3e0 [drm_kms_helper]
-[ 8.014483] [<ffffffffa016f1cb>] intel_fbdev_initial_config+0x1b/0x20 [i915]
-[ 8.014486] [<ffffffff8107912c>] async_run_entry_fn+0x4c/0x160
-[ 8.014490] [<ffffffff81070ffa>] process_one_work+0x14a/0x470
-[ 8.014493] [<ffffffff81071489>] worker_thread+0x169/0x4c0
-[ 8.014496] [<ffffffff81071320>] ? process_one_work+0x470/0x470
-[ 8.014499] [<ffffffff81076606>] kthread+0xc6/0xe0
-[ 8.014502] [<ffffffff81070000>] ? queue_work_on+0x80/0x110
-[ 8.014506] [<ffffffff81076540>] ? kthread_worker_fn+0x1c0/0x1c0
-
-Signed-off-by: Mike Galbraith <umgwanakikbuti@gmail.com>
-Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Cc: linux-rt-users <linux-rt-users@vger.kernel.org>
-Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
----
- drivers/gpu/drm/i915/display/intel_display_types.h | 2 ++
- drivers/gpu/drm/i915/display/intel_sprite.c | 10 +++++-----
- 2 files changed, 7 insertions(+), 5 deletions(-)
-
---- a/drivers/gpu/drm/i915/display/intel_display_types.h
-+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
-@@ -29,6 +29,7 @@
- #include <linux/async.h>
- #include <linux/i2c.h>
- #include <linux/sched/clock.h>
-+#include <linux/local_lock.h>
-
- #include <drm/drm_atomic.h>
- #include <drm/drm_crtc.h>
-@@ -1149,6 +1150,7 @@ struct intel_crtc {
- #ifdef CONFIG_DEBUG_FS
- struct intel_pipe_crc pipe_crc;
- #endif
-+ local_lock_t pipe_update_lock;
- };
-
- struct intel_plane {
---- a/drivers/gpu/drm/i915/display/intel_sprite.c
-+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
-@@ -118,7 +118,7 @@ void intel_pipe_update_start(const struc
- "PSR idle timed out 0x%x, atomic update may fail\n",
- psr_status);
-
-- local_irq_disable();
-+ local_lock_irq(&crtc->pipe_update_lock);
-
- crtc->debug.min_vbl = min;
- crtc->debug.max_vbl = max;
-@@ -143,11 +143,11 @@ void intel_pipe_update_start(const struc
- break;
- }
-
-- local_irq_enable();
-+ local_unlock_irq(&crtc->pipe_update_lock);
-
- timeout = schedule_timeout(timeout);
-
-- local_irq_disable();
-+ local_lock_irq(&crtc->pipe_update_lock);
- }
-
- finish_wait(wq, &wait);
-@@ -180,7 +180,7 @@ void intel_pipe_update_start(const struc
- return;
-
- irq_disable:
-- local_irq_disable();
-+ local_lock_irq(&crtc->pipe_update_lock);
- }
-
- /**
-@@ -218,7 +218,7 @@ void intel_pipe_update_end(struct intel_
- new_crtc_state->uapi.event = NULL;
- }
-
-- local_irq_enable();
-+ local_unlock_irq(&crtc->pipe_update_lock);
-
- if (intel_vgpu_active(dev_priv))
- return;
diff --git a/patches/localversion.patch b/patches/localversion.patch
index 279489a1d145..e36eb4b6666a 100644
--- a/patches/localversion.patch
+++ b/patches/localversion.patch
@@ -10,4 +10,4 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
--- /dev/null
+++ b/localversion-rt
@@ -0,0 +1 @@
-+-rt2
++-rt3
diff --git a/patches/md-raid5-percpu-handling-rt-aware.patch b/patches/md-raid5-percpu-handling-rt-aware.patch
index 077b7ffd2793..c06e6ed34fe7 100644
--- a/patches/md-raid5-percpu-handling-rt-aware.patch
+++ b/patches/md-raid5-percpu-handling-rt-aware.patch
@@ -41,7 +41,7 @@ Tested-by: Udo van den Heuvel <udovdh@xs4all.nl>
}
static void free_stripe(struct kmem_cache *sc, struct stripe_head *sh)
-@@ -6899,6 +6901,7 @@ static int raid456_cpu_up_prepare(unsign
+@@ -6902,6 +6904,7 @@ static int raid456_cpu_up_prepare(unsign
__func__, cpu);
return -ENOMEM;
}
diff --git a/patches/mm-fix-exec-activate_mm-vs-TLB-shootdown-and-lazy-tl.patch b/patches/mm-fix-exec-activate_mm-vs-TLB-shootdown-and-lazy-tl.patch
new file mode 100644
index 000000000000..79c4f6d3802b
--- /dev/null
+++ b/patches/mm-fix-exec-activate_mm-vs-TLB-shootdown-and-lazy-tl.patch
@@ -0,0 +1,102 @@
+From: Nicholas Piggin <npiggin@gmail.com>
+Date: Fri, 28 Aug 2020 20:00:19 +1000
+Subject: [PATCH] mm: fix exec activate_mm vs TLB shootdown and lazy tlb
+ switching race
+
+Reading and modifying current->mm and current->active_mm and switching
+mm should be done with irqs off, to prevent races seeing an intermediate
+state.
+
+This is similar to commit 38cf307c1f20 ("mm: fix kthread_use_mm() vs TLB
+invalidate"). At exec-time when the new mm is activated, the old one
+should usually be single-threaded and no longer used, unless something
+else is holding an mm_users reference (which may be possible).
+
+Absent other mm_users, there is also a race with preemption and lazy tlb
+switching. Consider the kernel_execve case where the current thread is
+using a lazy tlb active mm:
+
+ call_usermodehelper()
+ kernel_execve()
+ old_mm = current->mm;
+ active_mm = current->active_mm;
+ *** preempt *** --------------------> schedule()
+ prev->active_mm = NULL;
+ mmdrop(prev active_mm);
+ ...
+ <-------------------- schedule()
+ current->mm = mm;
+ current->active_mm = mm;
+ if (!old_mm)
+ mmdrop(active_mm);
+
+If we switch back to the kernel thread from a different mm, there is a
+double free of the old active_mm, and a missing free of the new one.
+
+Closing this race only requires interrupts to be disabled while ->mm
+and ->active_mm are being switched, but the TLB problem requires also
+holding interrupts off over activate_mm. Unfortunately not all archs
+can do that yet, e.g., arm defers the switch if irqs are disabled and
+expects finish_arch_post_lock_switch() to be called to complete the
+flush; um takes a blocking lock in activate_mm().
+
+So as a first step, disable interrupts across the mm/active_mm updates
+to close the lazy tlb preempt race, and provide an arch option to
+extend that to activate_mm which allows architectures doing IPI based
+TLB shootdowns to close the second race.
+
+This is a bit ugly, but in the interest of fixing the bug and backporting
+before all architectures are converted this is a compromise.
+
+Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ arch/Kconfig | 7 +++++++
+ fs/exec.c | 17 +++++++++++++++--
+ 2 files changed, 22 insertions(+), 2 deletions(-)
+
+--- a/arch/Kconfig
++++ b/arch/Kconfig
+@@ -414,6 +414,13 @@ config MMU_GATHER_NO_GATHER
+ bool
+ depends on MMU_GATHER_TABLE_FREE
+
++config ARCH_WANT_IRQS_OFF_ACTIVATE_MM
++ bool
++ help
++ Temporary select until all architectures can be converted to have
++ irqs disabled over activate_mm. Architectures that do IPI based TLB
++ shootdowns should enable this.
++
+ config ARCH_HAVE_NMI_SAFE_CMPXCHG
+ bool
+
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -1130,11 +1130,24 @@ static int exec_mmap(struct mm_struct *m
+ }
+
+ task_lock(tsk);
+- active_mm = tsk->active_mm;
+ membarrier_exec_mmap(mm);
+- tsk->mm = mm;
++
++ local_irq_disable();
++ active_mm = tsk->active_mm;
+ tsk->active_mm = mm;
++ tsk->mm = mm;
++ /*
++ * This prevents preemption while active_mm is being loaded and
++ * it and mm are being updated, which could cause problems for
++ * lazy tlb mm refcounting when these are updated by context
++ * switches. Not all architectures can handle irqs off over
++ * activate_mm yet.
++ */
++ if (!IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM))
++ local_irq_enable();
+ activate_mm(active_mm, mm);
++ if (IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM))
++ local_irq_enable();
+ tsk->mm->vmacache_seqnum = 0;
+ vmacache_flush(tsk);
+ task_unlock(tsk);
diff --git a/patches/serial-8250-only-atomic-lock-for-console.patch b/patches/serial-8250-only-atomic-lock-for-console.patch
index e9d5c4da70bb..df3ac1702e09 100644
--- a/patches/serial-8250-only-atomic-lock-for-console.patch
+++ b/patches/serial-8250-only-atomic-lock-for-console.patch
@@ -315,7 +315,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
serial8250_rpm_put(up);
}
-@@ -2478,7 +2431,7 @@ void serial8250_do_shutdown(struct uart_
+@@ -2481,7 +2434,7 @@ void serial8250_do_shutdown(struct uart_
*/
spin_lock_irqsave(&port->lock, flags);
up->ier = 0;
@@ -324,7 +324,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
spin_unlock_irqrestore(&port->lock, flags);
synchronize_irq(port->irq);
-@@ -2805,7 +2758,7 @@ serial8250_do_set_termios(struct uart_po
+@@ -2808,7 +2761,7 @@ serial8250_do_set_termios(struct uart_po
if (up->capabilities & UART_CAP_RTOIE)
up->ier |= UART_IER_RTOIE;
@@ -333,7 +333,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (up->capabilities & UART_CAP_EFR) {
unsigned char efr = 0;
-@@ -3317,12 +3270,13 @@ void serial8250_console_write_atomic(str
+@@ -3320,12 +3273,13 @@ void serial8250_console_write_atomic(str
{
struct uart_port *port = &up->port;
unsigned int flags;
@@ -348,7 +348,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (atomic_fetch_inc(&up->console_printing)) {
uart_console_write(port, "\n", 1,
-@@ -3332,7 +3286,7 @@ void serial8250_console_write_atomic(str
+@@ -3335,7 +3289,7 @@ void serial8250_console_write_atomic(str
atomic_dec(&up->console_printing);
wait_for_xmitr(up, BOTH_EMPTY);
@@ -357,7 +357,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
console_atomic_unlock(flags);
}
-@@ -3352,12 +3306,13 @@ void serial8250_console_write(struct uar
+@@ -3355,12 +3309,13 @@ void serial8250_console_write(struct uar
struct uart_8250_em485 *em485 = up->em485;
struct uart_port *port = &up->port;
unsigned long flags;
@@ -372,7 +372,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
/* check scratch reg to see if port powered off during system sleep */
if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) {
-@@ -3386,8 +3341,7 @@ void serial8250_console_write(struct uar
+@@ -3389,8 +3344,7 @@ void serial8250_console_write(struct uar
if (em485->tx_stopped)
up->rs485_stop_tx(up);
}
diff --git a/patches/serial-8250-remove-that-trylock-in-serial8250_consol.patch b/patches/serial-8250-remove-that-trylock-in-serial8250_consol.patch
index e40c5b051c15..4fb8bccef655 100644
--- a/patches/serial-8250-remove-that-trylock-in-serial8250_consol.patch
+++ b/patches/serial-8250-remove-that-trylock-in-serial8250_consol.patch
@@ -13,7 +13,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
-@@ -3315,17 +3315,9 @@ void serial8250_console_write_atomic(str
+@@ -3318,17 +3318,9 @@ void serial8250_console_write_atomic(str
{
struct uart_port *port = &up->port;
unsigned int flags;
@@ -31,7 +31,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
touch_nmi_watchdog();
clear_ier(up);
-@@ -3340,9 +3332,6 @@ void serial8250_console_write_atomic(str
+@@ -3343,9 +3335,6 @@ void serial8250_console_write_atomic(str
wait_for_xmitr(up, BOTH_EMPTY);
restore_ier(up);
diff --git a/patches/series b/patches/series
index 45800e6004a6..9d2a58243f3a 100644
--- a/patches/series
+++ b/patches/series
@@ -56,6 +56,11 @@ serial-8250-only-atomic-lock-for-console.patch
serial-8250-fsl-ingenic-mtk-fix-atomic-console.patch
printk-fix-ifnullfree.cocci-warnings.patch
+# Part of [PATCH 0/4] more mm switching vs TLB shootdown and lazy tlb
+# Date: Fri, 28 Aug 2020 20:00:18 +1000
+# https://lkml.kernel.org/r/20200828100022.1099682-2-npiggin@gmail.com
+mm-fix-exec-activate_mm-vs-TLB-shootdown-and-lazy-tl.patch
+
############################################################
# POSTED
############################################################
@@ -351,7 +356,7 @@ lockdep-disable-self-test.patch
# I915
# Low prio
drmradeoni915_Use_preempt_disableenable_rt()_where_recommended.patch
-drmi915_Use_local_lockunlock_irq()_in_intel_pipe_update_startend().patch
+drm-i915-Don-t-disable-interrupts-on-PREEMPT_RT-duri.patch
drm-i915-disable-tracing-on-RT.patch
drm-i915-skip-DRM_I915_LOW_LEVEL_TRACEPOINTS-with-NO.patch
drm-i915-gt-Only-disable-interrupts-for-the-timeline.patch
diff --git a/patches/x86-kvm-require-const-tsc-for-rt.patch b/patches/x86-kvm-require-const-tsc-for-rt.patch
index 8f2bf9850a50..046549210d40 100644
--- a/patches/x86-kvm-require-const-tsc-for-rt.patch
+++ b/patches/x86-kvm-require-const-tsc-for-rt.patch
@@ -14,7 +14,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
-@@ -7499,6 +7499,14 @@ int kvm_arch_init(void *opaque)
+@@ -7496,6 +7496,14 @@ int kvm_arch_init(void *opaque)
goto out;
}