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 12 void 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