jump label: Add sparc64 support
Add jump label support for sparc64. Signed-off-by: David S. Miller <davem@davemloft.net> LKML-Reference: <3b5b071fcdb2afb7f67cacecfa78b14c740278a7.1284733808.git.jbaron@redhat.com> Signed-off-by: Jason Baron <jbaron@redhat.com> [ cleaned up some formatting ] Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
This commit is contained in:
parent
d9f5ab7b1c
commit
dff9d3c215
|
@ -30,6 +30,7 @@ config SPARC
|
|||
select PERF_USE_VMALLOC
|
||||
select HAVE_DMA_ATTRS
|
||||
select HAVE_DMA_API_DEBUG
|
||||
select HAVE_ARCH_JUMP_LABEL if !CC_OPTIMIZE_FOR_SIZE
|
||||
|
||||
config SPARC32
|
||||
def_bool !64BIT
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef _ASM_SPARC_JUMP_LABEL_H
|
||||
#define _ASM_SPARC_JUMP_LABEL_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#define JUMP_LABEL_NOP_SIZE 4
|
||||
|
||||
#define JUMP_LABEL(key, label) \
|
||||
do { \
|
||||
asm goto("1:\n\t" \
|
||||
"nop\n\t" \
|
||||
"nop\n\t" \
|
||||
".pushsection __jump_table, \"a\"\n\t"\
|
||||
".word 1b, %l[" #label "], %c0\n\t" \
|
||||
".popsection \n\t" \
|
||||
: : "i" (key) : : label);\
|
||||
} while (0)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
typedef u32 jump_label_t;
|
||||
|
||||
struct jump_entry {
|
||||
jump_label_t code;
|
||||
jump_label_t target;
|
||||
jump_label_t key;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -119,3 +119,5 @@ obj-$(CONFIG_COMPAT) += $(audit--y)
|
|||
|
||||
pc--$(CONFIG_PERF_EVENTS) := perf_event.o
|
||||
obj-$(CONFIG_SPARC64) += $(pc--y)
|
||||
|
||||
obj-$(CONFIG_SPARC64) += jump_label.o
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/cpu.h>
|
||||
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/memory.h>
|
||||
|
||||
#ifdef HAVE_JUMP_LABEL
|
||||
|
||||
void arch_jump_label_transform(struct jump_entry *entry,
|
||||
enum jump_label_type type)
|
||||
{
|
||||
u32 val;
|
||||
u32 *insn = (u32 *) (unsigned long) entry->code;
|
||||
|
||||
if (type == JUMP_LABEL_ENABLE) {
|
||||
s32 off = (s32)entry->target - (s32)entry->code;
|
||||
|
||||
#ifdef CONFIG_SPARC64
|
||||
/* ba,pt %xcc, . + (off << 2) */
|
||||
val = 0x10680000 | ((u32) off >> 2);
|
||||
#else
|
||||
/* ba . + (off << 2) */
|
||||
val = 0x10800000 | ((u32) off >> 2);
|
||||
#endif
|
||||
} else {
|
||||
val = 0x01000000;
|
||||
}
|
||||
|
||||
get_online_cpus();
|
||||
mutex_lock(&text_mutex);
|
||||
*insn = val;
|
||||
flushi(insn);
|
||||
mutex_unlock(&text_mutex);
|
||||
put_online_cpus();
|
||||
}
|
||||
|
||||
void arch_jump_label_text_poke_early(jump_label_t addr)
|
||||
{
|
||||
u32 *insn_p = (u32 *) (unsigned long) addr;
|
||||
|
||||
*insn_p = 0x01000000;
|
||||
flushi(insn_p);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -18,6 +18,9 @@
|
|||
#include <asm/spitfire.h>
|
||||
|
||||
#ifdef CONFIG_SPARC64
|
||||
|
||||
#include <linux/jump_label.h>
|
||||
|
||||
static void *module_map(unsigned long size)
|
||||
{
|
||||
struct vm_struct *area;
|
||||
|
@ -227,6 +230,9 @@ int module_finalize(const Elf_Ehdr *hdr,
|
|||
const Elf_Shdr *sechdrs,
|
||||
struct module *me)
|
||||
{
|
||||
/* make jump label nops */
|
||||
jump_label_apply_nops(me);
|
||||
|
||||
/* Cheetah's I-cache is fully coherent. */
|
||||
if (tlb_type == spitfire) {
|
||||
unsigned long va;
|
||||
|
|
Loading…
Reference in New Issue