@@ -70,6 +70,10 @@ DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);
70
70
extern char __psci_hyp_bp_inval_start [], __psci_hyp_bp_inval_end [];
71
71
extern char __qcom_hyp_sanitize_link_stack_start [];
72
72
extern char __qcom_hyp_sanitize_link_stack_end [];
73
+ extern char __smccc_workaround_1_smc_start [];
74
+ extern char __smccc_workaround_1_smc_end [];
75
+ extern char __smccc_workaround_1_hvc_start [];
76
+ extern char __smccc_workaround_1_hvc_end [];
73
77
74
78
static void __copy_hyp_vect_bpi (int slot , const char * hyp_vecs_start ,
75
79
const char * hyp_vecs_end )
@@ -116,6 +120,10 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
116
120
#define __psci_hyp_bp_inval_end NULL
117
121
#define __qcom_hyp_sanitize_link_stack_start NULL
118
122
#define __qcom_hyp_sanitize_link_stack_end NULL
123
+ #define __smccc_workaround_1_smc_start NULL
124
+ #define __smccc_workaround_1_smc_end NULL
125
+ #define __smccc_workaround_1_hvc_start NULL
126
+ #define __smccc_workaround_1_hvc_end NULL
119
127
120
128
static void __install_bp_hardening_cb (bp_hardening_cb_t fn ,
121
129
const char * hyp_vecs_start ,
@@ -142,17 +150,75 @@ static void install_bp_hardening_cb(const struct arm64_cpu_capabilities *entry,
142
150
__install_bp_hardening_cb (fn , hyp_vecs_start , hyp_vecs_end );
143
151
}
144
152
153
+ #include <uapi/linux/psci.h>
154
+ #include <linux/arm-smccc.h>
145
155
#include <linux/psci.h>
146
156
157
+ static void call_smc_arch_workaround_1 (void )
158
+ {
159
+ arm_smccc_1_1_smc (ARM_SMCCC_ARCH_WORKAROUND_1 , NULL );
160
+ }
161
+
162
+ static void call_hvc_arch_workaround_1 (void )
163
+ {
164
+ arm_smccc_1_1_hvc (ARM_SMCCC_ARCH_WORKAROUND_1 , NULL );
165
+ }
166
+
167
+ static bool check_smccc_arch_workaround_1 (const struct arm64_cpu_capabilities * entry )
168
+ {
169
+ bp_hardening_cb_t cb ;
170
+ void * smccc_start , * smccc_end ;
171
+ struct arm_smccc_res res ;
172
+
173
+ if (!entry -> matches (entry , SCOPE_LOCAL_CPU ))
174
+ return false;
175
+
176
+ if (psci_ops .smccc_version == SMCCC_VERSION_1_0 )
177
+ return false;
178
+
179
+ switch (psci_ops .conduit ) {
180
+ case PSCI_CONDUIT_HVC :
181
+ arm_smccc_1_1_hvc (ARM_SMCCC_ARCH_FEATURES_FUNC_ID ,
182
+ ARM_SMCCC_ARCH_WORKAROUND_1 , & res );
183
+ if (res .a0 )
184
+ return false;
185
+ cb = call_hvc_arch_workaround_1 ;
186
+ smccc_start = __smccc_workaround_1_hvc_start ;
187
+ smccc_end = __smccc_workaround_1_hvc_end ;
188
+ break ;
189
+
190
+ case PSCI_CONDUIT_SMC :
191
+ arm_smccc_1_1_smc (ARM_SMCCC_ARCH_FEATURES_FUNC_ID ,
192
+ ARM_SMCCC_ARCH_WORKAROUND_1 , & res );
193
+ if (res .a0 )
194
+ return false;
195
+ cb = call_smc_arch_workaround_1 ;
196
+ smccc_start = __smccc_workaround_1_smc_start ;
197
+ smccc_end = __smccc_workaround_1_smc_end ;
198
+ break ;
199
+
200
+ default :
201
+ return false;
202
+ }
203
+
204
+ install_bp_hardening_cb (entry , cb , smccc_start , smccc_end );
205
+
206
+ return true;
207
+ }
208
+
147
209
static int enable_psci_bp_hardening (void * data )
148
210
{
149
211
const struct arm64_cpu_capabilities * entry = data ;
150
212
151
- if (psci_ops .get_version )
213
+ if (psci_ops .get_version ) {
214
+ if (check_smccc_arch_workaround_1 (entry ))
215
+ return 0 ;
216
+
152
217
install_bp_hardening_cb (entry ,
153
218
(bp_hardening_cb_t )psci_ops .get_version ,
154
219
__psci_hyp_bp_inval_start ,
155
220
__psci_hyp_bp_inval_end );
221
+ }
156
222
157
223
return 0 ;
158
224
}
0 commit comments