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