mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
x86/srso: Add IBPB on VMEXIT
Upstream commit: d893832d0e
Add the option to flush IBPB only on VMEXIT in order to protect from
malicious guests but one otherwise trusts the software that runs on the
hypervisor.
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
79c8091888
commit
c9ae63d773
@@ -310,6 +310,7 @@
|
|||||||
|
|
||||||
#define X86_FEATURE_SRSO (11*32+24) /* "" AMD BTB untrain RETs */
|
#define X86_FEATURE_SRSO (11*32+24) /* "" AMD BTB untrain RETs */
|
||||||
#define X86_FEATURE_SRSO_ALIAS (11*32+25) /* "" AMD BTB untrain RETs through aliasing */
|
#define X86_FEATURE_SRSO_ALIAS (11*32+25) /* "" AMD BTB untrain RETs through aliasing */
|
||||||
|
#define X86_FEATURE_IBPB_ON_VMEXIT (11*32+26) /* "" Issue an IBPB only on VMEXIT */
|
||||||
|
|
||||||
/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
|
/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
|
||||||
#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
|
#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
|
||||||
|
|||||||
@@ -2316,6 +2316,7 @@ enum srso_mitigation {
|
|||||||
SRSO_MITIGATION_MICROCODE,
|
SRSO_MITIGATION_MICROCODE,
|
||||||
SRSO_MITIGATION_SAFE_RET,
|
SRSO_MITIGATION_SAFE_RET,
|
||||||
SRSO_MITIGATION_IBPB,
|
SRSO_MITIGATION_IBPB,
|
||||||
|
SRSO_MITIGATION_IBPB_ON_VMEXIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum srso_mitigation_cmd {
|
enum srso_mitigation_cmd {
|
||||||
@@ -2323,6 +2324,7 @@ enum srso_mitigation_cmd {
|
|||||||
SRSO_CMD_MICROCODE,
|
SRSO_CMD_MICROCODE,
|
||||||
SRSO_CMD_SAFE_RET,
|
SRSO_CMD_SAFE_RET,
|
||||||
SRSO_CMD_IBPB,
|
SRSO_CMD_IBPB,
|
||||||
|
SRSO_CMD_IBPB_ON_VMEXIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * const srso_strings[] = {
|
static const char * const srso_strings[] = {
|
||||||
@@ -2330,6 +2332,7 @@ static const char * const srso_strings[] = {
|
|||||||
[SRSO_MITIGATION_MICROCODE] = "Mitigation: microcode",
|
[SRSO_MITIGATION_MICROCODE] = "Mitigation: microcode",
|
||||||
[SRSO_MITIGATION_SAFE_RET] = "Mitigation: safe RET",
|
[SRSO_MITIGATION_SAFE_RET] = "Mitigation: safe RET",
|
||||||
[SRSO_MITIGATION_IBPB] = "Mitigation: IBPB",
|
[SRSO_MITIGATION_IBPB] = "Mitigation: IBPB",
|
||||||
|
[SRSO_MITIGATION_IBPB_ON_VMEXIT] = "Mitigation: IBPB on VMEXIT only"
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum srso_mitigation srso_mitigation __ro_after_init = SRSO_MITIGATION_NONE;
|
static enum srso_mitigation srso_mitigation __ro_after_init = SRSO_MITIGATION_NONE;
|
||||||
@@ -2348,6 +2351,8 @@ static int __init srso_parse_cmdline(char *str)
|
|||||||
srso_cmd = SRSO_CMD_SAFE_RET;
|
srso_cmd = SRSO_CMD_SAFE_RET;
|
||||||
else if (!strcmp(str, "ibpb"))
|
else if (!strcmp(str, "ibpb"))
|
||||||
srso_cmd = SRSO_CMD_IBPB;
|
srso_cmd = SRSO_CMD_IBPB;
|
||||||
|
else if (!strcmp(str, "ibpb-vmexit"))
|
||||||
|
srso_cmd = SRSO_CMD_IBPB_ON_VMEXIT;
|
||||||
else
|
else
|
||||||
pr_err("Ignoring unknown SRSO option (%s).", str);
|
pr_err("Ignoring unknown SRSO option (%s).", str);
|
||||||
|
|
||||||
@@ -2431,6 +2436,20 @@ static void __init srso_select_mitigation(void)
|
|||||||
pr_err("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n");
|
pr_err("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n");
|
||||||
goto pred_cmd;
|
goto pred_cmd;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SRSO_CMD_IBPB_ON_VMEXIT:
|
||||||
|
if (IS_ENABLED(CONFIG_CPU_SRSO)) {
|
||||||
|
if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) {
|
||||||
|
setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT);
|
||||||
|
srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pr_err("WARNING: kernel not compiled with CPU_SRSO.\n");
|
||||||
|
goto pred_cmd;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1485,7 +1485,9 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
|||||||
|
|
||||||
if (sd->current_vmcb != svm->vmcb) {
|
if (sd->current_vmcb != svm->vmcb) {
|
||||||
sd->current_vmcb = svm->vmcb;
|
sd->current_vmcb = svm->vmcb;
|
||||||
indirect_branch_prediction_barrier();
|
|
||||||
|
if (!cpu_feature_enabled(X86_FEATURE_IBPB_ON_VMEXIT))
|
||||||
|
indirect_branch_prediction_barrier();
|
||||||
}
|
}
|
||||||
if (kvm_vcpu_apicv_active(vcpu))
|
if (kvm_vcpu_apicv_active(vcpu))
|
||||||
avic_vcpu_load(vcpu, cpu);
|
avic_vcpu_load(vcpu, cpu);
|
||||||
|
|||||||
@@ -223,6 +223,9 @@ SYM_FUNC_START(__svm_vcpu_run)
|
|||||||
*/
|
*/
|
||||||
UNTRAIN_RET
|
UNTRAIN_RET
|
||||||
|
|
||||||
|
/* SRSO */
|
||||||
|
ALTERNATIVE "", "call entry_ibpb", X86_FEATURE_IBPB_ON_VMEXIT
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear all general purpose registers except RSP and RAX to prevent
|
* Clear all general purpose registers except RSP and RAX to prevent
|
||||||
* speculative use of the guest's values, even those that are reloaded
|
* speculative use of the guest's values, even those that are reloaded
|
||||||
|
|||||||
Reference in New Issue
Block a user