Skip to content

[PW_SID:1141880] riscv: signal: protect regs->status RMW from concurrent preemption - #2425

Open
linux-riscv-bot wants to merge 2 commits into
workflow__riscv__fixesfrom
pw1141880
Open

[PW_SID:1141880] riscv: signal: protect regs->status RMW from concurrent preemption#2425
linux-riscv-bot wants to merge 2 commits into
workflow__riscv__fixesfrom
pw1141880

Conversation

@linux-riscv-bot

Copy link
Copy Markdown

PR for series 1141880 applied to workflow__riscv__fixes

Name: riscv: signal: protect regs->status RMW from concurrent preemption
URL: https://patchwork.kernel.org/project/linux-riscv/list/?series=1141880
Version: 1

Linux RISC-V bot and others added 2 commits August 7, 2026 03:32
__fstate_clean() performs a non-atomic read-modify-write (RMW) on
task_pt_regs(current)->status to clear the FS bits. This RMW is
unprotected - it runs with preemption enabled and IRQs on during
signal delivery (setup_rt_frame -> fstate_save) and sigreturn
(restore_fp_state -> fstate_restore).

If a reschedule IPI or timer interrupt triggers preemption between
the load and store of this RMW, __switch_to_vector() calls
riscv_v_vstate_set_restore() which modifies the VS bits of the
same regs->status. When the preempted task resumes, it stores back
the stale value captured before preemption, overwriting the VS
update and restoring VS=DIRTY while TIF_RISCV_V_DEFER_RESTORE
remains set - a combination that should never occur and leads to
vector state corruption.

The race window:

  __fstate_clean (signal path)      set_restore (schedule path)
  -----------------------------     -----------------------------
  ld  a0, regs->status  // VS=DIRTY, FS=DIRTY
                                     <- preempted (reschedule IPI)
                                     regs->status VS = INITIAL
                                     set TIF_RISCV_V_DEFER_RESTORE
                                     <- resumed
  andi a0, ~FS
  ori  a0, FS_CLEAN     // stale a0 still has VS=DIRTY
  sd   a0, regs->status // overwrites VS=INITIAL with VS=DIRTY
  -> result: VS=DIRTY + DEFER -> ANOMALY

Fix by adding preempt_disable/enable around the RMW in
__fstate_clean() and fstate_off(). riscv_v_vstate_set_restore()
has the identical hazard: it is called from __restore_v_state()
(sigreturn path) with preemption enabled, and it can race the same
way against the scheduler's own call to riscv_v_vstate_set_restore()
for the same task in __switch_to_vector(). Wrap that call site with
preempt_disable/enable as well.

Add WARN_ON_ONCE(preemptible()) to riscv_v_vstate_restore()
to catch any future unprotected callers at development time.

Signed-off-by: Guobin Zhang <guobin.zhang@intel.com>
Signed-off-by: Linux RISC-V bot <linux.riscv.bot@gmail.com>
@linux-riscv-bot

Copy link
Copy Markdown
Author

Patch 1: "riscv: signal: protect regs->status RMW from concurrent preemption"
build-rv32-defconfig
Desc: Builds riscv32 defconfig
Duration: 116.67 seconds
Result: PASS

@linux-riscv-bot

Copy link
Copy Markdown
Author

Patch 1: "riscv: signal: protect regs->status RMW from concurrent preemption"
build-rv64-clang-allmodconfig
Desc: Builds riscv64 allmodconfig with Clang, and checks for errors and added warnings
Duration: 1403.70 seconds
Result: PASS

@linux-riscv-bot

Copy link
Copy Markdown
Author

Patch 1: "riscv: signal: protect regs->status RMW from concurrent preemption"
build-rv64-gcc-allmodconfig
Desc: Builds riscv64 allmodconfig with GCC, and checks for errors and added warnings
Duration: 1734.75 seconds
Result: PASS

@linux-riscv-bot

Copy link
Copy Markdown
Author

Patch 1: "riscv: signal: protect regs->status RMW from concurrent preemption"
build-rv64-nommu-k210-defconfig
Desc: Builds riscv64 defconfig with NOMMU for K210
Duration: 19.86 seconds
Result: PASS

@linux-riscv-bot

Copy link
Copy Markdown
Author

Patch 1: "riscv: signal: protect regs->status RMW from concurrent preemption"
build-rv64-nommu-k210-virt
Desc: Builds riscv64 defconfig with NOMMU for the virt platform
Duration: 21.00 seconds
Result: PASS

@linux-riscv-bot

Copy link
Copy Markdown
Author

Patch 1: "riscv: signal: protect regs->status RMW from concurrent preemption"
checkpatch
Desc: Runs checkpatch.pl on the patch
Duration: 0.93 seconds
Result: PASS

@linux-riscv-bot

Copy link
Copy Markdown
Author

Patch 1: "riscv: signal: protect regs->status RMW from concurrent preemption"
dtb-warn-rv64
Desc: Checks for Device Tree warnings/errors
Duration: 79.16 seconds
Result: PASS

@linux-riscv-bot

Copy link
Copy Markdown
Author

Patch 1: "riscv: signal: protect regs->status RMW from concurrent preemption"
header-inline
Desc: Detects static functions without inline keyword in header files
Duration: 0.22 seconds
Result: PASS

@linux-riscv-bot

Copy link
Copy Markdown
Author

Patch 1: "riscv: signal: protect regs->status RMW from concurrent preemption"
kdoc
Desc: Detects for kdoc errors
Duration: 0.70 seconds
Result: PASS

@linux-riscv-bot

Copy link
Copy Markdown
Author

Patch 1: "riscv: signal: protect regs->status RMW from concurrent preemption"
module-param
Desc: Detect module_param changes
Duration: 0.23 seconds
Result: PASS

@linux-riscv-bot

Copy link
Copy Markdown
Author

Patch 1: "riscv: signal: protect regs->status RMW from concurrent preemption"
verify-fixes
Desc: Verifies that the Fixes: tags exist
Duration: 0.21 seconds
Result: PASS

@linux-riscv-bot

Copy link
Copy Markdown
Author

Patch 1: "riscv: signal: protect regs->status RMW from concurrent preemption"
verify-signedoff
Desc: Verifies that Signed-off-by: tags are correct
Duration: 6.57 seconds
Result: PASS

@linux-riscv-bot
linux-riscv-bot force-pushed the workflow__riscv__fixes branch from abf8962 to 9fa746d Compare August 8, 2026 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants