Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dff9d3c2 authored by David S. Miller's avatar David S. Miller Committed by Steven Rostedt
Browse files

jump label: Add sparc64 support



Add jump label support for sparc64.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
LKML-Reference: <3b5b071fcdb2afb7f67cacecfa78b14c740278a7.1284733808.git.jbaron@redhat.com>
Signed-off-by: default avatarJason Baron <jbaron@redhat.com>

[ cleaned up some formatting ]

Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent d9f5ab7b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+32 −0
Original line number Diff line number Diff line
#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
+2 −0
Original line number Diff line number Diff line
@@ -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
+47 −0
Original line number Diff line number Diff line
#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
+6 −0
Original line number Diff line number Diff line
@@ -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;