Commit a72a70a4 authored by Mao Minkai's avatar Mao Minkai Committed by guzitao
Browse files

sw64: add jump_label support

Sunway inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8Y8CY



--------------------------------

Add jump_label support for SW64.

Signed-off-by: default avatarMao Minkai <maominkai@wxiat.com>
Reviewed-by: default avatarHe Sheng <hesheng@wxiat.com>
Signed-off-by: default avatarGu Zitao <guzitao@wxiat.com>
parent 4b0906fc
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */

#ifndef _ASM_SW64_JUMP_LABEL_H
#define _ASM_SW64_JUMP_LABEL_H

#ifndef __ASSEMBLY__

#include <linux/types.h>
#include <asm/insn.h>

#define JUMP_LABEL_NOP_SIZE		SW64_INSN_SIZE

static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
{
	asm_volatile_goto("1: nop\n\t"
			".pushsection __jump_table,  \"aw\"\n\t"
			".align 3\n\t"
			".quad 1b, %l[l_yes], %0\n\t"
			".popsection\n\t"
			:  :  "i"(&((char *)key)[branch]) :  : l_yes);

	return false;
l_yes:
	return true;
}

static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
{
	asm_volatile_goto("1: br %l[l_yes]\n\t"
			".pushsection __jump_table,  \"aw\"\n\t"
			".align 3\n\t"
			".quad 1b, %l[l_yes], %0\n\t"
			".popsection\n\t"
			:  :  "i"(&((char *)key)[branch]) :  : l_yes);

	return false;
l_yes:
	return true;
}

typedef u64 jump_label_t;

struct jump_entry {
	jump_label_t code;
	jump_label_t target;
	jump_label_t key;
};

#endif /* __ASSEMBLY__ */
#endif /* _ASM_SW64_JUMP_LABEL_H */
+32 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0

#include <linux/jump_label.h>

#include <asm/bug.h>
#include <asm/cacheflush.h>

void arch_jump_label_transform(struct jump_entry *entry,
			       enum jump_label_type type)
{
	u32 *insnp = (u32 *)entry->code;
	u32 insn;

	if (type == JUMP_LABEL_JMP) {
		insn = sw64_insn_br(R31, (entry->code), entry->target);
		BUG_ON(insn == -1);
	} else {
		insn = sw64_insn_nop();
	}

	*insnp = insn;

	flush_icache_range(entry->code, entry->code + SW64_INSN_SIZE);
}

void arch_jump_label_transform_static(struct jump_entry *entry,
				      enum jump_label_type type)
{
	/*
	 * no need to rewrite NOP
	 */
}