mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-26 14:17:26 -04:00
riscv: Use text_mutex instead of patch_lock
We don't need the additional lock protection when patching the text. There are two patching interfaces here: - patch_text: patch code and always synchronize with stop_machine() - patch_text_nosync: patch code without synchronization, it's caller's responsibility to synchronize all CPUs if needed. For the first one, stop_machine() is protected by its own mutex, and also the irq is already disabled here. For the second one, in risc-v real case now, it would be used to ftrace patching the mcount function, since it already running under kstop_machine(), no other thread will run, so we could use text_mutex on ftrace side. Signed-off-by: Zong Li <zong.li@sifive.com> Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com> Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
This commit is contained in:
parent
5303df244c
commit
0ff7c3b331
2 changed files with 20 additions and 6 deletions
|
@ -7,10 +7,23 @@
|
||||||
|
|
||||||
#include <linux/ftrace.h>
|
#include <linux/ftrace.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
#include <linux/memory.h>
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/patch.h>
|
#include <asm/patch.h>
|
||||||
|
|
||||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||||
|
int ftrace_arch_code_modify_prepare(void) __acquires(&text_mutex)
|
||||||
|
{
|
||||||
|
mutex_lock(&text_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ftrace_arch_code_modify_post_process(void) __releases(&text_mutex)
|
||||||
|
{
|
||||||
|
mutex_unlock(&text_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ftrace_check_current_call(unsigned long hook_pos,
|
static int ftrace_check_current_call(unsigned long hook_pos,
|
||||||
unsigned int *expected)
|
unsigned int *expected)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
#include <linux/memory.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/stop_machine.h>
|
#include <linux/stop_machine.h>
|
||||||
#include <asm/kprobes.h>
|
#include <asm/kprobes.h>
|
||||||
|
@ -18,8 +19,6 @@ struct patch_insn {
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_MMU
|
#ifdef CONFIG_MMU
|
||||||
static DEFINE_RAW_SPINLOCK(patch_lock);
|
|
||||||
|
|
||||||
static void *patch_map(void *addr, int fixmap)
|
static void *patch_map(void *addr, int fixmap)
|
||||||
{
|
{
|
||||||
uintptr_t uintaddr = (uintptr_t) addr;
|
uintptr_t uintaddr = (uintptr_t) addr;
|
||||||
|
@ -49,10 +48,14 @@ static int patch_insn_write(void *addr, const void *insn, size_t len)
|
||||||
{
|
{
|
||||||
void *waddr = addr;
|
void *waddr = addr;
|
||||||
bool across_pages = (((uintptr_t) addr & ~PAGE_MASK) + len) > PAGE_SIZE;
|
bool across_pages = (((uintptr_t) addr & ~PAGE_MASK) + len) > PAGE_SIZE;
|
||||||
unsigned long flags = 0;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
raw_spin_lock_irqsave(&patch_lock, flags);
|
/*
|
||||||
|
* Before reaching here, it was expected to lock the text_mutex
|
||||||
|
* already, so we don't need to give another lock here and could
|
||||||
|
* ensure that it was safe between each cores.
|
||||||
|
*/
|
||||||
|
lockdep_assert_held(&text_mutex);
|
||||||
|
|
||||||
if (across_pages)
|
if (across_pages)
|
||||||
patch_map(addr + len, FIX_TEXT_POKE1);
|
patch_map(addr + len, FIX_TEXT_POKE1);
|
||||||
|
@ -66,8 +69,6 @@ static int patch_insn_write(void *addr, const void *insn, size_t len)
|
||||||
if (across_pages)
|
if (across_pages)
|
||||||
patch_unmap(FIX_TEXT_POKE1);
|
patch_unmap(FIX_TEXT_POKE1);
|
||||||
|
|
||||||
raw_spin_unlock_irqrestore(&patch_lock, flags);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
NOKPROBE_SYMBOL(patch_insn_write);
|
NOKPROBE_SYMBOL(patch_insn_write);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue