Hi Linus,
please pull the following fixes for the Xtensa architecture.
The following changes since commit ce522ba9ef7e2d9fb22a39eb3371c0c64e2a433e:
Linux 5.18-rc2 (2022-04-10 14:21:36 -1000)
are available in the Git repository at:
https://github.com/jcmvbkbc/linux-xtensa.git tags/xtensa-20220416
for you to fetch changes up to 839769c35477d4acc2369e45000ca7b0b6af39a7:
xtensa: fix a7 clobbering in coprocessor context load/store (2022-04-15 18:44:02 -0700)
----------------------------------------------------------------
Xtensa fixes for v5.18:
- fix patching CPU selection in patch_text
- fix potential deadlock in ISS platform serial driver
- fix potential register clobbering in coprocessor exception handler
----------------------------------------------------------------
Duoming Zhou (1):
arch: xtensa: platforms: Fix deadlock in rs_close()
Guo Ren (1):
xtensa: patch_text: Fixup last cpu should be master
Max Filippov (1):
xtensa: fix a7 clobbering in coprocessor context load/store
arch/xtensa/kernel/coprocessor.S | 4 ++--
arch/xtensa/kernel/jump_label.c | 2 +-
arch/xtensa/platforms/iss/console.c | 8 --------
3 files changed, 3 insertions(+), 11 deletions(-)
--
Thanks.
-- Max
From: Duoming Zhou <[email protected]>
There is a deadlock in rs_close(), which is shown
below:
(Thread 1) | (Thread 2)
| rs_open()
rs_close() | mod_timer()
spin_lock_bh() //(1) | (wait a time)
... | rs_poll()
del_timer_sync() | spin_lock() //(2)
(wait timer to stop) | ...
We hold timer_lock in position (1) of thread 1 and
use del_timer_sync() to wait timer to stop, but timer handler
also need timer_lock in position (2) of thread 2.
As a result, rs_close() will block forever.
This patch deletes the redundant timer_lock in order to
prevent the deadlock. Because there is no race condition
between rs_close, rs_open and rs_poll.
Signed-off-by: Duoming Zhou <[email protected]>
Message-Id: <[email protected]>
Signed-off-by: Max Filippov <[email protected]>
---
arch/xtensa/platforms/iss/console.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c
index 81d7c7e8f7e9..10b79d3c74e0 100644
--- a/arch/xtensa/platforms/iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -36,24 +36,19 @@ static void rs_poll(struct timer_list *);
static struct tty_driver *serial_driver;
static struct tty_port serial_port;
static DEFINE_TIMER(serial_timer, rs_poll);
-static DEFINE_SPINLOCK(timer_lock);
static int rs_open(struct tty_struct *tty, struct file * filp)
{
- spin_lock_bh(&timer_lock);
if (tty->count == 1)
mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
- spin_unlock_bh(&timer_lock);
return 0;
}
static void rs_close(struct tty_struct *tty, struct file * filp)
{
- spin_lock_bh(&timer_lock);
if (tty->count == 1)
del_timer_sync(&serial_timer);
- spin_unlock_bh(&timer_lock);
}
@@ -73,8 +68,6 @@ static void rs_poll(struct timer_list *unused)
int rd = 1;
unsigned char c;
- spin_lock(&timer_lock);
-
while (simc_poll(0)) {
rd = simc_read(0, &c, 1);
if (rd <= 0)
@@ -87,7 +80,6 @@ static void rs_poll(struct timer_list *unused)
tty_flip_buffer_push(port);
if (rd)
mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
- spin_unlock(&timer_lock);
}
--
2.30.2
From: Guo Ren <[email protected]>
These patch_text implementations are using stop_machine_cpuslocked
infrastructure with atomic cpu_count. The original idea: When the
master CPU patch_text, the others should wait for it. But current
implementation is using the first CPU as master, which couldn't
guarantee the remaining CPUs are waiting. This patch changes the
last CPU as the master to solve the potential risk.
Fixes: 64711f9a47d4 ("xtensa: implement jump_label support")
Signed-off-by: Guo Ren <[email protected]>
Signed-off-by: Guo Ren <[email protected]>
Reviewed-by: Max Filippov <[email protected]>
Reviewed-by: Masami Hiramatsu <[email protected]>
Cc: <[email protected]>
Message-Id: <[email protected]>
Signed-off-by: Max Filippov <[email protected]>
---
arch/xtensa/kernel/jump_label.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/xtensa/kernel/jump_label.c b/arch/xtensa/kernel/jump_label.c
index 0dde21e0d3de..ad1841cecdfb 100644
--- a/arch/xtensa/kernel/jump_label.c
+++ b/arch/xtensa/kernel/jump_label.c
@@ -40,7 +40,7 @@ static int patch_text_stop_machine(void *data)
{
struct patch *patch = data;
- if (atomic_inc_return(&patch->cpu_count) == 1) {
+ if (atomic_inc_return(&patch->cpu_count) == num_online_cpus()) {
local_patch_text(patch->addr, patch->data, patch->sz);
atomic_inc(&patch->cpu_count);
} else {
--
2.30.2
The pull request you sent on Tue, 19 Apr 2022 23:16:08 -0700:
> https://github.com/jcmvbkbc/linux-xtensa.git tags/xtensa-20220416
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/b253435746d9a4a701b5f09211b9c14d3370d0da
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
Fast coprocessor exception handler saves a3..a6, but coprocessor context
load/store code uses a4..a7 as temporaries, potentially clobbering a7.
'Potentially' because coprocessor state load/store macros may not use
all four temporary registers (and neither FPU nor HiFi macros do).
Use a3..a6 as intended.
Cc: [email protected]
Fixes: c658eac628aa ("[XTENSA] Add support for configurable registers and coprocessors")
Signed-off-by: Max Filippov <[email protected]>
---
arch/xtensa/kernel/coprocessor.S | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S
index 45cc0ae0af6f..c7b9f12896f2 100644
--- a/arch/xtensa/kernel/coprocessor.S
+++ b/arch/xtensa/kernel/coprocessor.S
@@ -29,7 +29,7 @@
.if XTENSA_HAVE_COPROCESSOR(x); \
.align 4; \
.Lsave_cp_regs_cp##x: \
- xchal_cp##x##_store a2 a4 a5 a6 a7; \
+ xchal_cp##x##_store a2 a3 a4 a5 a6; \
jx a0; \
.endif
@@ -46,7 +46,7 @@
.if XTENSA_HAVE_COPROCESSOR(x); \
.align 4; \
.Lload_cp_regs_cp##x: \
- xchal_cp##x##_load a2 a4 a5 a6 a7; \
+ xchal_cp##x##_load a2 a3 a4 a5 a6; \
jx a0; \
.endif
--
2.30.2