Skip to content

Commit a370c24

Browse files
Alexandre Ghitipalmer-dabbelt
authored andcommitted
riscv: Disable preemption when using patch_map()
patch_map() uses fixmap mappings to circumvent the non-writability of the kernel text mapping. The __set_fixmap() function only flushes the current cpu tlb, it does not emit an IPI so we must make sure that while we use a fixmap mapping, the current task is not migrated on another cpu which could miss the newly introduced fixmap mapping. So in order to avoid any task migration, disable the preemption. Reported-by: Andrea Parri <[email protected]> Closes: https://lore.kernel.org/all/ZcS+GAaM25LXsBOl@andrea/ Reported-by: Andy Chiu <[email protected]> Closes: https://lore.kernel.org/linux-riscv/CABgGipUMz3Sffu-CkmeUB1dKVwVQ73+7=sgC45-m0AE9RCjOZg@mail.gmail.com/ Fixes: cad539b ("riscv: implement a memset like function for text") Fixes: 0ff7c3b ("riscv: Use text_mutex instead of patch_lock") Co-developed-by: Andy Chiu <[email protected]> Signed-off-by: Andy Chiu <[email protected]> Signed-off-by: Alexandre Ghiti <[email protected]> Acked-by: Puranjay Mohan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 8a48ea8 commit a370c24

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

arch/riscv/kernel/patch.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ static int __patch_insn_set(void *addr, u8 c, size_t len)
8080
*/
8181
lockdep_assert_held(&text_mutex);
8282

83+
preempt_disable();
84+
8385
if (across_pages)
8486
patch_map(addr + PAGE_SIZE, FIX_TEXT_POKE1);
8587

@@ -92,6 +94,8 @@ static int __patch_insn_set(void *addr, u8 c, size_t len)
9294
if (across_pages)
9395
patch_unmap(FIX_TEXT_POKE1);
9496

97+
preempt_enable();
98+
9599
return 0;
96100
}
97101
NOKPROBE_SYMBOL(__patch_insn_set);
@@ -122,6 +126,8 @@ static int __patch_insn_write(void *addr, const void *insn, size_t len)
122126
if (!riscv_patch_in_stop_machine)
123127
lockdep_assert_held(&text_mutex);
124128

129+
preempt_disable();
130+
125131
if (across_pages)
126132
patch_map(addr + PAGE_SIZE, FIX_TEXT_POKE1);
127133

@@ -134,6 +140,8 @@ static int __patch_insn_write(void *addr, const void *insn, size_t len)
134140
if (across_pages)
135141
patch_unmap(FIX_TEXT_POKE1);
136142

143+
preempt_enable();
144+
137145
return ret;
138146
}
139147
NOKPROBE_SYMBOL(__patch_insn_write);

0 commit comments

Comments
 (0)