diff options
author | Zhigang Lu <zlu@ezchip.com> | 2015-09-30 10:11:45 +0800 |
---|---|---|
committer | Chris Metcalf <cmetcalf@ezchip.com> | 2016-01-04 15:09:31 -0500 |
commit | 65a792e84f25d1436698f999224b2cf5d7594546 (patch) | |
tree | fe87043a2d810dbb94fde139db4f6ea3da0e0a25 /arch/tile/kernel/jump_label.c | |
parent | f419e6f63c5afea00d7c17ebf54f2d265f5c4d7e (diff) | |
download | op-kernel-dev-65a792e84f25d1436698f999224b2cf5d7594546.zip op-kernel-dev-65a792e84f25d1436698f999224b2cf5d7594546.tar.gz |
tile/jump_label: add jump label support for TILE-Gx
Add the arch-specific code to support jump label for TILE-Gx. This
code shares NOP instruction with ftrace, so we move it to a common
header file.
Reviewed-by: Chris Metcalf <cmetcalf@ezchip.com>
Signed-off-by: Zhigang Lu <zlu@ezchip.com>
Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com>
Diffstat (limited to 'arch/tile/kernel/jump_label.c')
-rw-r--r-- | arch/tile/kernel/jump_label.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/arch/tile/kernel/jump_label.c b/arch/tile/kernel/jump_label.c new file mode 100644 index 0000000..07802d5 --- /dev/null +++ b/arch/tile/kernel/jump_label.c @@ -0,0 +1,64 @@ +/* + * Copyright 2015 Tilera Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for + * more details. + * + * jump label TILE-Gx support + */ + +#include <linux/jump_label.h> +#include <linux/memory.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/cpu.h> + +#include <asm/cacheflush.h> +#include <asm/insn.h> + +#ifdef HAVE_JUMP_LABEL + +static void __jump_label_transform(struct jump_entry *e, + enum jump_label_type type) +{ + tilegx_bundle_bits opcode; + /* Operate on writable kernel text mapping. */ + unsigned long pc_wr = ktext_writable_addr(e->code); + + if (type == JUMP_LABEL_JMP) + opcode = tilegx_gen_branch(e->code, e->target, false); + else + opcode = NOP(); + + *(tilegx_bundle_bits *)pc_wr = opcode; + /* Make sure that above mem writes were issued towards the memory. */ + smp_wmb(); +} + +void arch_jump_label_transform(struct jump_entry *e, + enum jump_label_type type) +{ + get_online_cpus(); + mutex_lock(&text_mutex); + + __jump_label_transform(e, type); + flush_icache_range(e->code, e->code + sizeof(tilegx_bundle_bits)); + + mutex_unlock(&text_mutex); + put_online_cpus(); +} + +__init_or_module void arch_jump_label_transform_static(struct jump_entry *e, + enum jump_label_type type) +{ + __jump_label_transform(e, type); +} + +#endif /* HAVE_JUMP_LABEL */ |