@@ -219,17 +219,38 @@ static inline void vmexit_fill_RSB(void)
219
219
#endif
220
220
}
221
221
222
+ #define alternative_msr_write (_msr , _val , _feature ) \
223
+ asm volatile(ALTERNATIVE("", \
224
+ "movl %[msr], %%ecx\n\t" \
225
+ "movl %[val], %%eax\n\t" \
226
+ "movl $0, %%edx\n\t" \
227
+ "wrmsr", \
228
+ _feature) \
229
+ : : [msr] "i" (_msr), [val] "i" (_val) \
230
+ : "eax", "ecx", "edx", "memory")
231
+
222
232
static inline void indirect_branch_prediction_barrier (void )
223
233
{
224
- asm volatile (ALTERNATIVE ("" ,
225
- "movl %[msr], %%ecx\n\t"
226
- "movl %[val], %%eax\n\t"
227
- "movl $0, %%edx\n\t"
228
- "wrmsr" ,
229
- X86_FEATURE_USE_IBPB )
230
- : : [msr ] "i" (MSR_IA32_PRED_CMD ),
231
- [val ] "i" (PRED_CMD_IBPB )
232
- : "eax" , "ecx" , "edx" , "memory" );
234
+ alternative_msr_write (MSR_IA32_PRED_CMD , PRED_CMD_IBPB ,
235
+ X86_FEATURE_USE_IBPB );
236
+ }
237
+
238
+ /*
239
+ * With retpoline, we must use IBRS to restrict branch prediction
240
+ * before calling into firmware.
241
+ */
242
+ static inline void firmware_restrict_branch_speculation_start (void )
243
+ {
244
+ preempt_disable ();
245
+ alternative_msr_write (MSR_IA32_SPEC_CTRL , SPEC_CTRL_IBRS ,
246
+ X86_FEATURE_USE_IBRS_FW );
247
+ }
248
+
249
+ static inline void firmware_restrict_branch_speculation_end (void )
250
+ {
251
+ alternative_msr_write (MSR_IA32_SPEC_CTRL , 0 ,
252
+ X86_FEATURE_USE_IBRS_FW );
253
+ preempt_enable ();
233
254
}
234
255
235
256
#endif /* __ASSEMBLY__ */
0 commit comments