From: Ashok Raj Date: Thu, 1 Feb 2018 21:59:43 +0000 (+0100) Subject: KVM/x86: Add IBPB support X-Git-Tag: v4.1.12-124.31.3~395 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=556289539b00bdc5673a8cf4a9c39c02996faac4;p=users%2Fjedix%2Flinux-maple.git KVM/x86: Add IBPB support commit 15d45071523d89b3fb7372e2135fbd72f6af9506 The Indirect Branch Predictor Barrier (IBPB) is an indirect branch control mechanism. It keeps earlier branches from influencing later ones. Unlike IBRS and STIBP, IBPB does not define a new mode of operation. It's a command that ensures predicted branch targets aren't used after the barrier. Although IBRS and IBPB are enumerated by the same CPUID enumeration, IBPB is very different. IBPB helps mitigate against three potential attacks: * Mitigate guests from being attacked by other guests. - This is addressed by issing IBPB when we do a guest switch. * Mitigate attacks from guest/ring3->host/ring3. These would require a IBPB during context switch in host, or after VMEXIT. The host process has two ways to mitigate - Either it can be compiled with retpoline - If its going through context switch, and has set !dumpable then there is a IBPB in that path. (Tim's patch: https://patchwork.kernel.org/patch/10192871) - The case where after a VMEXIT you return back to Qemu might make Qemu attackable from guest when Qemu isn't compiled with retpoline. There are issues reported when doing IBPB on every VMEXIT that resulted in some tsc calibration woes in guest. * Mitigate guest/ring0->host/ring0 attacks. When host kernel is using retpoline it is safe against these attacks. If host kernel isn't using retpoline we might need to do a IBPB flush on every VMEXIT. Even when using retpoline for indirect calls, in certain conditions 'ret' can use the BTB on Skylake-era CPUs. There are other mitigations available like RSB stuffing/clearing. * IBPB is issued only for SVM during svm_free_vcpu(). VMX has a vmclear and SVM doesn't. Follow discussion here: https://lkml.org/lkml/2018/1/15/146 Please refer to the following spec for more details on the enumeration and control. Refer here to get documentation about mitigations. https://software.intel.com/en-us/side-channel-security-support [peterz: rebase and changelog rewrite] [karahmed: - rebase - vmx: expose PRED_CMD if guest has it in CPUID - svm: only pass through IBPB if guest has it in CPUID - vmx: support !cpu_has_vmx_msr_bitmap()] - vmx: support nested] [dwmw2: Expose CPUID bit too (AMD IBPB only for now as we lack IBRS) PRED_CMD is a write-only MSR] Signed-off-by: Ashok Raj Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: David Woodhouse Signed-off-by: KarimAllah Ahmed Signed-off-by: Thomas Gleixner Reviewed-by: Konrad Rzeszutek Wilk Cc: Andrea Arcangeli Cc: Andi Kleen Cc: kvm@vger.kernel.org Cc: Asit Mallick Cc: Linus Torvalds Cc: Andy Lutomirski Cc: Dave Hansen Cc: Arjan Van De Ven Cc: Greg KH Cc: Jun Nakajima Cc: Paolo Bonzini Cc: Dan Williams Cc: Tim Chen Link: http://lkml.kernel.org/r/1515720739-43819-6-git-send-email-ashok.raj@intel.com Link: https://lkml.kernel.org/r/1517522386-18410-3-git-send-email-karahmed@amazon.de Signed-off-by: Greg Kroah-Hartman (cherry picked from commit d395d69de67ea95760e1f207eb0f6fdfbcb6e069) Orabug: 28703712 Signed-off-by: George Kennedy Reviewed-by: Konrad Rzeszutek Wilk Signed-off-by: Brian Maly Conflicts: arch/x86/kvm/cpuid.c arch/x86/kvm/svm.c arch/x86/kvm/vmx.c [ manual merge - functionality is not a match with upstream nor UEK5 ] Signed-off-by: Brian Maly --- diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 10d8aa32c07f9..11d98d3f4070f 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -3299,6 +3299,16 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) case MSR_IA32_SPEC_CTRL: svm->spec_ctrl = data; break; + case MSR_IA32_PRED_CMD: + if (data & ~FEATURE_SET_IBPB) + return 1; + + if (!data) + break; + + if (ibpb_inuse) + wrmsrl(MSR_IA32_PRED_CMD, FEATURE_SET_IBPB); + break; case MSR_AMD64_VIRT_SPEC_CTRL: if (data & ~SPEC_CTRL_SSBD) return 1; diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 5bda65682185c..1f821e1c881da 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2964,6 +2964,16 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_IA32_SPEC_CTRL: to_vmx(vcpu)->spec_ctrl = data; break; + case MSR_IA32_PRED_CMD: + if (data & ~FEATURE_SET_IBPB) + return 1; + + if (!data) + break; + + if (ibpb_inuse) + wrmsrl(MSR_IA32_PRED_CMD, FEATURE_SET_IBPB); + break; case MSR_IA32_ARCH_CAPABILITIES: vmx->arch_capabilities = data; break;