summaryrefslogtreecommitdiff
path: root/arch/arm64/kernel/bpi.S
blob: d3fd8bf42d868c8ebf0eda59a02093aec089fb07 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * Contains CPU specific branch predictor invalidation sequences
 *
 * Copyright (C) 2018 ARM Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/linkage.h>
#include <linux/arm-smccc.h>

.macro ventry target
	.rept 31
	nop
	.endr
	b	\target
.endm

.macro vectors target
	ventry \target + 0x000
	ventry \target + 0x080
	ventry \target + 0x100
	ventry \target + 0x180

	ventry \target + 0x200
	ventry \target + 0x280
	ventry \target + 0x300
	ventry \target + 0x380

	ventry \target + 0x400
	ventry \target + 0x480
	ventry \target + 0x500
	ventry \target + 0x580

	ventry \target + 0x600
	ventry \target + 0x680
	ventry \target + 0x700
	ventry \target + 0x780
.endm

	.align	11
ENTRY(__bp_harden_hyp_vecs_start)
	.rept 4
	vectors __kvm_hyp_vector
	.endr
ENTRY(__bp_harden_hyp_vecs_end)

.macro smccc_workaround_1 inst
	sub	sp, sp, #(8 * 4)
	stp	x2, x3, [sp, #(8 * 0)]
	stp	x0, x1, [sp, #(8 * 2)]
	mov	w0, #ARM_SMCCC_ARCH_WORKAROUND_1
	\inst	#0
	ldp	x2, x3, [sp, #(8 * 0)]
	ldp	x0, x1, [sp, #(8 * 2)]
	add	sp, sp, #(8 * 4)
.endm

ENTRY(__smccc_workaround_1_smc_start)
	smccc_workaround_1	smc
ENTRY(__smccc_workaround_1_smc_end)

ENTRY(__smccc_workaround_1_hvc_start)
	smccc_workaround_1	hvc
ENTRY(__smccc_workaround_1_hvc_end)

ENTRY(__smccc_workaround_3_smc_start)
	sub     sp, sp, #(8 * 4)
	stp     x2, x3, [sp, #(8 * 0)]
	stp     x0, x1, [sp, #(8 * 2)]
	mov     w0, #ARM_SMCCC_ARCH_WORKAROUND_3
	smc     #0
	ldp     x2, x3, [sp, #(8 * 0)]
	ldp     x0, x1, [sp, #(8 * 2)]
	add     sp, sp, #(8 * 4)
ENTRY(__smccc_workaround_3_smc_end)

ENTRY(__spectre_bhb_loop_k8_start)
	sub     sp, sp, #(8 * 2)
	stp     x0, x1, [sp, #(8 * 0)]
	mov     x0, #8
2:	b       . + 4
	subs    x0, x0, #1
	b.ne    2b
	dsb     nsh
	isb
	ldp     x0, x1, [sp, #(8 * 0)]
	add     sp, sp, #(8 * 2)
ENTRY(__spectre_bhb_loop_k8_end)

ENTRY(__spectre_bhb_loop_k24_start)
	sub     sp, sp, #(8 * 2)
	stp     x0, x1, [sp, #(8 * 0)]
	mov     x0, #24
2:	b       . + 4
	subs    x0, x0, #1
	b.ne    2b
	dsb     nsh
	isb
	ldp     x0, x1, [sp, #(8 * 0)]
	add     sp, sp, #(8 * 2)
ENTRY(__spectre_bhb_loop_k24_end)

ENTRY(__spectre_bhb_loop_k32_start)
	sub     sp, sp, #(8 * 2)
	stp     x0, x1, [sp, #(8 * 0)]
	mov     x0, #32
2:	b       . + 4
	subs    x0, x0, #1
	b.ne    2b
	dsb     nsh
	isb
	ldp     x0, x1, [sp, #(8 * 0)]
	add     sp, sp, #(8 * 2)
ENTRY(__spectre_bhb_loop_k32_end)

ENTRY(__spectre_bhb_clearbhb_start)
	hint	#22	/* aka clearbhb */
	isb
ENTRY(__spectre_bhb_clearbhb_end)