]> git.dujemihanovic.xyz Git - linux.git/commit
riscv: Disable preemption while handling PR_RISCV_CTX_SW_FENCEI_OFF
authorCharlie Jenkins <charlie@rivosinc.com>
Tue, 3 Sep 2024 22:52:34 +0000 (15:52 -0700)
committerPalmer Dabbelt <palmer@rivosinc.com>
Wed, 11 Sep 2024 03:38:46 +0000 (20:38 -0700)
commit7c1e5b9690b0e14acead4ff98d8a6c40f2dff54b
tree93ac7e394a3df6db78ae01b144b8d176c9ea5045
parent2840dadf0dde92638d13b97998026c5fcddbdceb
riscv: Disable preemption while handling PR_RISCV_CTX_SW_FENCEI_OFF

The icache will be flushed in switch_to() if force_icache_flush is true,
or in flush_icache_deferred() if icache_stale_mask is set. Between
setting force_icache_flush to false and calculating the new
icache_stale_mask, preemption needs to be disabled. There are two
reasons for this:

1. If CPU migration happens between force_icache_flush = false, and the
   icache_stale_mask is set, an icache flush will not be emitted.
2. smp_processor_id() is used in set_icache_stale_mask() to mark the
   current CPU as not needing another flush since a flush will have
   happened either by userspace or by the kernel when performing the
   migration. smp_processor_id() is currently called twice with preemption
   enabled which causes a race condition. It allows
   icache_stale_mask to be populated with inconsistent CPU ids.

Resolve these two issues by setting the icache_stale_mask before setting
force_icache_flush to false, and using get_cpu()/put_cpu() to obtain the
smp_processor_id().

Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
Fixes: 6b9391b581fd ("riscv: Include riscv_set_icache_flush_ctx prctl")
Link: https://lore.kernel.org/r/20240903-fix_fencei_optimization-v2-1-8025f20171fc@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/mm/cacheflush.c