linux/arch/sparc/kernel/jump_label.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/kernel.h>
   3#include <linux/types.h>
   4#include <linux/mutex.h>
   5#include <linux/cpu.h>
   6
   7#include <linux/jump_label.h>
   8#include <linux/memory.h>
   9
  10#include <asm/cacheflush.h>
  11
  12void arch_jump_label_transform(struct jump_entry *entry,
  13                               enum jump_label_type type)
  14{
  15        u32 *insn = (u32 *) (unsigned long) entry->code;
  16        u32 val;
  17
  18        if (type == JUMP_LABEL_JMP) {
  19                s32 off = (s32)entry->target - (s32)entry->code;
  20                bool use_v9_branch = false;
  21
  22                BUG_ON(off & 3);
  23
  24#ifdef CONFIG_SPARC64
  25                if (off <= 0xfffff && off >= -0x100000)
  26                        use_v9_branch = true;
  27#endif
  28                if (use_v9_branch) {
  29                        /* WDISP19 - target is . + immed << 2 */
  30                        /* ba,pt %xcc, . + off */
  31                        val = 0x10680000 | (((u32) off >> 2) & 0x7ffff);
  32                } else {
  33                        /* WDISP22 - target is . + immed << 2 */
  34                        BUG_ON(off > 0x7fffff);
  35                        BUG_ON(off < -0x800000);
  36                        /* ba . + off */
  37                        val = 0x10800000 | (((u32) off >> 2) & 0x3fffff);
  38                }
  39        } else {
  40                val = 0x01000000;
  41        }
  42
  43        mutex_lock(&text_mutex);
  44        *insn = val;
  45        flushi(insn);
  46        mutex_unlock(&text_mutex);
  47}
  48