linux/arch/powerpc/kernel/static_call.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/memory.h>
   3#include <linux/static_call.h>
   4
   5#include <asm/code-patching.h>
   6
   7void arch_static_call_transform(void *site, void *tramp, void *func, bool tail)
   8{
   9        int err;
  10        bool is_ret0 = (func == __static_call_return0);
  11        unsigned long target = (unsigned long)(is_ret0 ? tramp + PPC_SCT_RET0 : func);
  12        bool is_short = is_offset_in_branch_range((long)target - (long)tramp);
  13
  14        if (!tramp)
  15                return;
  16
  17        mutex_lock(&text_mutex);
  18
  19        if (func && !is_short) {
  20                err = patch_instruction(tramp + PPC_SCT_DATA, ppc_inst(target));
  21                if (err)
  22                        goto out;
  23        }
  24
  25        if (!func)
  26                err = patch_instruction(tramp, ppc_inst(PPC_RAW_BLR()));
  27        else if (is_short)
  28                err = patch_branch(tramp, target, 0);
  29        else
  30                err = patch_instruction(tramp, ppc_inst(PPC_RAW_NOP()));
  31out:
  32        mutex_unlock(&text_mutex);
  33
  34        if (err)
  35                panic("%s: patching failed %pS at %pS\n", __func__, func, tramp);
  36}
  37EXPORT_SYMBOL_GPL(arch_static_call_transform);
  38