@@ -219,17 +219,38 @@ static inline void vmexit_fill_RSB(void)
219219#endif
220220}
221221
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+
222232static inline void indirect_branch_prediction_barrier (void )
223233{
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 ();
233254}
234255
235256#endif /* __ASSEMBLY__ */
0 commit comments