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 #ifdef HAVE_JUMP_LABEL 13 14 void arch_jump_label_transform(struct jump_entry *entry, 15 enum jump_label_type type) 16 { 17 u32 *insn = (u32 *) (unsigned long) entry->code; 18 u32 val; 19 20 if (type == JUMP_LABEL_JMP) { 21 s32 off = (s32)entry->target - (s32)entry->code; 22 bool use_v9_branch = false; 23 24 BUG_ON(off & 3); 25 26 #ifdef CONFIG_SPARC64 27 if (off <= 0xfffff && off >= -0x100000) 28 use_v9_branch = true; 29 #endif 30 if (use_v9_branch) { 31 /* WDISP19 - target is . + immed << 2 */ 32 /* ba,pt %xcc, . + off */ 33 val = 0x10680000 | (((u32) off >> 2) & 0x7ffff); 34 } else { 35 /* WDISP22 - target is . + immed << 2 */ 36 BUG_ON(off > 0x7fffff); 37 BUG_ON(off < -0x800000); 38 /* ba . + off */ 39 val = 0x10800000 | (((u32) off >> 2) & 0x3fffff); 40 } 41 } else { 42 val = 0x01000000; 43 } 44 45 mutex_lock(&text_mutex); 46 *insn = val; 47 flushi(insn); 48 mutex_unlock(&text_mutex); 49 } 50 51 #endif 52