1 /* 2 * Copyright (C) 2013 Huawei Ltd. 3 * Author: Jiang Liu <liuj97@gmail.com> 4 * 5 * Based on arch/arm/kernel/jump_label.c 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 #include <linux/kernel.h> 20 #include <linux/jump_label.h> 21 #include <asm/insn.h> 22 23 #ifdef HAVE_JUMP_LABEL 24 25 static void __arch_jump_label_transform(struct jump_entry *entry, 26 enum jump_label_type type, 27 bool is_static) 28 { 29 void *addr = (void *)entry->code; 30 u32 insn; 31 32 if (type == JUMP_LABEL_ENABLE) { 33 insn = aarch64_insn_gen_branch_imm(entry->code, 34 entry->target, 35 AARCH64_INSN_BRANCH_NOLINK); 36 } else { 37 insn = aarch64_insn_gen_nop(); 38 } 39 40 if (is_static) 41 aarch64_insn_patch_text_nosync(addr, insn); 42 else 43 aarch64_insn_patch_text(&addr, &insn, 1); 44 } 45 46 void arch_jump_label_transform(struct jump_entry *entry, 47 enum jump_label_type type) 48 { 49 __arch_jump_label_transform(entry, type, false); 50 } 51 52 void arch_jump_label_transform_static(struct jump_entry *entry, 53 enum jump_label_type type) 54 { 55 __arch_jump_label_transform(entry, type, true); 56 } 57 58 #endif /* HAVE_JUMP_LABEL */ 59