Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/xtensa/include/asm/jump_label.h
26451 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
/* Copyright (C) 2018 Cadence Design Systems Inc. */
3
4
#ifndef _ASM_XTENSA_JUMP_LABEL_H
5
#define _ASM_XTENSA_JUMP_LABEL_H
6
7
#ifndef __ASSEMBLER__
8
9
#include <linux/types.h>
10
11
#define JUMP_LABEL_NOP_SIZE 3
12
13
static __always_inline bool arch_static_branch(struct static_key *key,
14
bool branch)
15
{
16
asm goto("1:\n\t"
17
"_nop\n\t"
18
".pushsection __jump_table, \"aw\"\n\t"
19
".word 1b, %l[l_yes], %c0\n\t"
20
".popsection\n\t"
21
: : "i" (&((char *)key)[branch]) : : l_yes);
22
23
return false;
24
l_yes:
25
return true;
26
}
27
28
static __always_inline bool arch_static_branch_jump(struct static_key *key,
29
bool branch)
30
{
31
/*
32
* Xtensa assembler will mark certain points in the code
33
* as unreachable, so that later assembler or linker relaxation
34
* passes could use them. A spot right after the J instruction
35
* is one such point. Assembler and/or linker may insert padding
36
* or literals here, breaking code flow in case the J instruction
37
* is later replaced with NOP. Put a label right after the J to
38
* make it reachable and wrap both into a no-transform block
39
* to avoid any assembler interference with this.
40
*/
41
asm goto("1:\n\t"
42
".begin no-transform\n\t"
43
"_j %l[l_yes]\n\t"
44
"2:\n\t"
45
".end no-transform\n\t"
46
".pushsection __jump_table, \"aw\"\n\t"
47
".word 1b, %l[l_yes], %c0\n\t"
48
".popsection\n\t"
49
: : "i" (&((char *)key)[branch]) : : l_yes);
50
51
return false;
52
l_yes:
53
return true;
54
}
55
56
typedef u32 jump_label_t;
57
58
struct jump_entry {
59
jump_label_t code;
60
jump_label_t target;
61
jump_label_t key;
62
};
63
64
#endif /* __ASSEMBLER__ */
65
#endif
66
67