Blame view
arch/mips/kernel/jump_label.c
1.27 KB
94bb0c1ab MIPS: jump label:... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (c) 2010 Cavium Networks, Inc. */ #include <linux/jump_label.h> #include <linux/kernel.h> #include <linux/memory.h> #include <linux/mutex.h> #include <linux/types.h> #include <linux/cpu.h> #include <asm/cacheflush.h> #include <asm/inst.h> #ifdef HAVE_JUMP_LABEL #define J_RANGE_MASK ((1ul << 28) - 1) void arch_jump_label_transform(struct jump_entry *e, enum jump_label_type type) { union mips_instruction insn; union mips_instruction *insn_p = (union mips_instruction *)(unsigned long)e->code; /* Jump only works within a 256MB aligned region. */ BUG_ON((e->target & ~J_RANGE_MASK) != (e->code & ~J_RANGE_MASK)); /* Target must have 4 byte alignment. */ BUG_ON((e->target & 3) != 0); if (type == JUMP_LABEL_ENABLE) { insn.j_format.opcode = j_op; insn.j_format.target = (e->target & J_RANGE_MASK) >> 2; } else { insn.word = 0; /* nop */ } get_online_cpus(); mutex_lock(&text_mutex); *insn_p = insn; flush_icache_range((unsigned long)insn_p, (unsigned long)insn_p + sizeof(*insn_p)); mutex_unlock(&text_mutex); put_online_cpus(); } #endif /* HAVE_JUMP_LABEL */ |