|
@@ -219,17 +219,38 @@ static inline void vmexit_fill_RSB(void)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+#define alternative_msr_write(_msr, _val, _feature) \
|
|
|
+ asm volatile(ALTERNATIVE("", \
|
|
|
+ "movl %[msr], %%ecx\n\t" \
|
|
|
+ "movl %[val], %%eax\n\t" \
|
|
|
+ "movl $0, %%edx\n\t" \
|
|
|
+ "wrmsr", \
|
|
|
+ _feature) \
|
|
|
+ : : [msr] "i" (_msr), [val] "i" (_val) \
|
|
|
+ : "eax", "ecx", "edx", "memory")
|
|
|
+
|
|
|
static inline void indirect_branch_prediction_barrier(void)
|
|
|
{
|
|
|
- asm volatile(ALTERNATIVE("",
|
|
|
- "movl %[msr], %%ecx\n\t"
|
|
|
- "movl %[val], %%eax\n\t"
|
|
|
- "movl $0, %%edx\n\t"
|
|
|
- "wrmsr",
|
|
|
- X86_FEATURE_USE_IBPB)
|
|
|
- : : [msr] "i" (MSR_IA32_PRED_CMD),
|
|
|
- [val] "i" (PRED_CMD_IBPB)
|
|
|
- : "eax", "ecx", "edx", "memory");
|
|
|
+ alternative_msr_write(MSR_IA32_PRED_CMD, PRED_CMD_IBPB,
|
|
|
+ X86_FEATURE_USE_IBPB);
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * With retpoline, we must use IBRS to restrict branch prediction
|
|
|
+ * before calling into firmware.
|
|
|
+ */
|
|
|
+static inline void firmware_restrict_branch_speculation_start(void)
|
|
|
+{
|
|
|
+ preempt_disable();
|
|
|
+ alternative_msr_write(MSR_IA32_SPEC_CTRL, SPEC_CTRL_IBRS,
|
|
|
+ X86_FEATURE_USE_IBRS_FW);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void firmware_restrict_branch_speculation_end(void)
|
|
|
+{
|
|
|
+ alternative_msr_write(MSR_IA32_SPEC_CTRL, 0,
|
|
|
+ X86_FEATURE_USE_IBRS_FW);
|
|
|
+ preempt_enable();
|
|
|
}
|
|
|
|
|
|
#endif /* __ASSEMBLY__ */
|