1/* 2 * Copyright 2015 Tilera Corporation. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, version 2. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 11 * NON INFRINGEMENT. See the GNU General Public License for 12 * more details. 13 * 14 * jump label TILE-Gx support 15 */ 16 17#include <linux/jump_label.h> 18#include <linux/memory.h> 19#include <linux/module.h> 20#include <linux/mutex.h> 21#include <linux/cpu.h> 22 23#include <asm/cacheflush.h> 24#include <asm/insn.h> 25 26#ifdef HAVE_JUMP_LABEL 27 28static void __jump_label_transform(struct jump_entry *e, 29 enum jump_label_type type) 30{ 31 tilegx_bundle_bits opcode; 32 /* Operate on writable kernel text mapping. */ 33 unsigned long pc_wr = ktext_writable_addr(e->code); 34 35 if (type == JUMP_LABEL_JMP) 36 opcode = tilegx_gen_branch(e->code, e->target, false); 37 else 38 opcode = NOP(); 39 40 *(tilegx_bundle_bits *)pc_wr = opcode; 41 /* Make sure that above mem writes were issued towards the memory. */ 42 smp_wmb(); 43} 44 45void arch_jump_label_transform(struct jump_entry *e, 46 enum jump_label_type type) 47{ 48 mutex_lock(&text_mutex); 49 50 __jump_label_transform(e, type); 51 flush_icache_range(e->code, e->code + sizeof(tilegx_bundle_bits)); 52 53 mutex_unlock(&text_mutex); 54} 55 56__init_or_module void arch_jump_label_transform_static(struct jump_entry *e, 57 enum jump_label_type type) 58{ 59 __jump_label_transform(e, type); 60} 61 62#endif /* HAVE_JUMP_LABEL */ 63