18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci#ifndef _ASM_POWERPC_JUMP_LABEL_H
38c2ecf20Sopenharmony_ci#define _ASM_POWERPC_JUMP_LABEL_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci/*
68c2ecf20Sopenharmony_ci * Copyright 2010 Michael Ellerman, IBM Corp.
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__
108c2ecf20Sopenharmony_ci#include <linux/types.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <asm/feature-fixups.h>
138c2ecf20Sopenharmony_ci#include <asm/asm-const.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#define JUMP_ENTRY_TYPE		stringify_in_c(FTR_ENTRY_LONG)
168c2ecf20Sopenharmony_ci#define JUMP_LABEL_NOP_SIZE	4
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistatic __always_inline bool arch_static_branch(struct static_key *key, bool branch)
198c2ecf20Sopenharmony_ci{
208c2ecf20Sopenharmony_ci	asm_volatile_goto("1:\n\t"
218c2ecf20Sopenharmony_ci		 "nop # arch_static_branch\n\t"
228c2ecf20Sopenharmony_ci		 ".pushsection __jump_table,  \"aw\"\n\t"
238c2ecf20Sopenharmony_ci		 JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t"
248c2ecf20Sopenharmony_ci		 ".popsection \n\t"
258c2ecf20Sopenharmony_ci		 : :  "i" (&((char *)key)[branch]) : : l_yes);
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci	return false;
288c2ecf20Sopenharmony_cil_yes:
298c2ecf20Sopenharmony_ci	return true;
308c2ecf20Sopenharmony_ci}
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_cistatic __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
338c2ecf20Sopenharmony_ci{
348c2ecf20Sopenharmony_ci	asm_volatile_goto("1:\n\t"
358c2ecf20Sopenharmony_ci		 "b %l[l_yes] # arch_static_branch_jump\n\t"
368c2ecf20Sopenharmony_ci		 ".pushsection __jump_table,  \"aw\"\n\t"
378c2ecf20Sopenharmony_ci		 JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t"
388c2ecf20Sopenharmony_ci		 ".popsection \n\t"
398c2ecf20Sopenharmony_ci		 : :  "i" (&((char *)key)[branch]) : : l_yes);
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	return false;
428c2ecf20Sopenharmony_cil_yes:
438c2ecf20Sopenharmony_ci	return true;
448c2ecf20Sopenharmony_ci}
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC64
478c2ecf20Sopenharmony_citypedef u64 jump_label_t;
488c2ecf20Sopenharmony_ci#else
498c2ecf20Sopenharmony_citypedef u32 jump_label_t;
508c2ecf20Sopenharmony_ci#endif
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_cistruct jump_entry {
538c2ecf20Sopenharmony_ci	jump_label_t code;
548c2ecf20Sopenharmony_ci	jump_label_t target;
558c2ecf20Sopenharmony_ci	jump_label_t key;
568c2ecf20Sopenharmony_ci};
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci#else
598c2ecf20Sopenharmony_ci#define ARCH_STATIC_BRANCH(LABEL, KEY)		\
608c2ecf20Sopenharmony_ci1098:	nop;					\
618c2ecf20Sopenharmony_ci	.pushsection __jump_table, "aw";	\
628c2ecf20Sopenharmony_ci	FTR_ENTRY_LONG 1098b, LABEL, KEY;	\
638c2ecf20Sopenharmony_ci	.popsection
648c2ecf20Sopenharmony_ci#endif
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci#endif /* _ASM_POWERPC_JUMP_LABEL_H */
67