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:
committed by
Steven Rostedt
parent
d9f5ab7b1c
commit
dff9d3c215
@@ -30,6 +30,7 @@ config SPARC
|
|||||||
select PERF_USE_VMALLOC
|
select PERF_USE_VMALLOC
|
||||||
select HAVE_DMA_ATTRS
|
select HAVE_DMA_ATTRS
|
||||||
select HAVE_DMA_API_DEBUG
|
select HAVE_DMA_API_DEBUG
|
||||||
|
select HAVE_ARCH_JUMP_LABEL if !CC_OPTIMIZE_FOR_SIZE
|
||||||
|
|
||||||
config SPARC32
|
config SPARC32
|
||||||
def_bool !64BIT
|
def_bool !64BIT
|
||||||
|
32
arch/sparc/include/asm/jump_label.h
Normal file
32
arch/sparc/include/asm/jump_label.h
Normal file
@@ -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
|
pc--$(CONFIG_PERF_EVENTS) := perf_event.o
|
||||||
obj-$(CONFIG_SPARC64) += $(pc--y)
|
obj-$(CONFIG_SPARC64) += $(pc--y)
|
||||||
|
|
||||||
|
obj-$(CONFIG_SPARC64) += jump_label.o
|
||||||
|
47
arch/sparc/kernel/jump_label.c
Normal file
47
arch/sparc/kernel/jump_label.c
Normal file
@@ -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>
|
#include <asm/spitfire.h>
|
||||||
|
|
||||||
#ifdef CONFIG_SPARC64
|
#ifdef CONFIG_SPARC64
|
||||||
|
|
||||||
|
#include <linux/jump_label.h>
|
||||||
|
|
||||||
static void *module_map(unsigned long size)
|
static void *module_map(unsigned long size)
|
||||||
{
|
{
|
||||||
struct vm_struct *area;
|
struct vm_struct *area;
|
||||||
@@ -227,6 +230,9 @@ int module_finalize(const Elf_Ehdr *hdr,
|
|||||||
const Elf_Shdr *sechdrs,
|
const Elf_Shdr *sechdrs,
|
||||||
struct module *me)
|
struct module *me)
|
||||||
{
|
{
|
||||||
|
/* make jump label nops */
|
||||||
|
jump_label_apply_nops(me);
|
||||||
|
|
||||||
/* Cheetah's I-cache is fully coherent. */
|
/* Cheetah's I-cache is fully coherent. */
|
||||||
if (tlb_type == spitfire) {
|
if (tlb_type == spitfire) {
|
||||||
unsigned long va;
|
unsigned long va;
|
||||||
|
Reference in New Issue
Block a user