Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP7:GA
xen.23267
61f933aa-SVM-SPEC_CTRL-entry-exit-logic.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 61f933aa-SVM-SPEC_CTRL-entry-exit-logic.patch of Package xen.23267
# Commit 614cec7d79d76786f5638a6e4da0576b57732ca1 # Date 2022-02-01 13:20:44 +0000 # Author Andrew Cooper <andrew.cooper3@citrix.com> # Committer Andrew Cooper <andrew.cooper3@citrix.com> x86/svm: VMEntry/Exit logic for MSR_SPEC_CTRL Hardware maintains both host and guest versions of MSR_SPEC_CTRL, but guests run with the logical OR of both values. Therefore, in principle we want to clear Xen's value before entering the guest. However, for migration compatibility (future work), and for performance reasons with SEV-SNP guests, we want the ability to use a nonzero value behind the guest's back. Use vcpu_msrs to hold this value, with the guest value in the VMCB. On the VMEntry path, adjusting MSR_SPEC_CTRL must be done after CLGI so as to be atomic with respect to NMIs/etc. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> --- a/xen/arch/x86/hvm/svm/entry.S +++ b/xen/arch/x86/hvm/svm/entry.S @@ -59,11 +59,23 @@ __UNLIKELY_END(nsvm_hap) mov %rsp, %rdi call svm_vmenter_helper - mov VCPU_arch_msrs(%rbx), %rax - mov VCPUMSR_spec_ctrl_raw(%rax), %eax + CLGI /* WARNING! `ret`, `call *`, `jmp *` not safe beyond this point. */ - /* SPEC_CTRL_EXIT_TO_SVM (nothing currently) */ + /* SPEC_CTRL_EXIT_TO_SVM Req: b=curr %rsp=regs/cpuinfo, Clob: acd */ + .macro svm_vmentry_spec_ctrl + mov VCPU_arch_msrs(%rbx), %rax + movzbl CPUINFO_last_spec_ctrl(%rsp), %edx + mov VCPUMSR_spec_ctrl_raw(%rax), %eax + cmp %edx, %eax + je 1f /* Skip write if value is correct. */ + mov $MSR_SPEC_CTRL, %ecx + xor %edx, %edx + wrmsr + mov %al, CPUINFO_last_spec_ctrl(%rsp) +1: /* No Spectre v1 concerns. Execution will hit VMRUN imminently. */ + .endm + ALTERNATIVE "", svm_vmentry_spec_ctrl, X86_FEATURE_SC_MSR_HVM pop %r15 pop %r14 @@ -82,7 +94,6 @@ __UNLIKELY_END(nsvm_hap) pop %rsi pop %rdi - CLGI sti VMRUN @@ -90,8 +101,21 @@ __UNLIKELY_END(nsvm_hap) GET_CURRENT(bx) - /* SPEC_CTRL_ENTRY_FROM_SVM Req: b=curr %rsp=regs/cpuinfo, Clob: ac */ + /* SPEC_CTRL_ENTRY_FROM_SVM Req: %rsp=regs/cpuinfo Clob: acd */ ALTERNATIVE "", DO_OVERWRITE_RSB, X86_FEATURE_SC_RSB_HVM + + .macro svm_vmexit_spec_ctrl + /* + * Write to MSR_SPEC_CTRL unconditionally, for the RAS[:32] + * flushing side effect. + */ + mov $MSR_SPEC_CTRL, %ecx + movzbl CPUINFO_xen_spec_ctrl(%rsp), %eax + xor %edx, %edx + wrmsr + mov %al, CPUINFO_last_spec_ctrl(%rsp) + .endm + ALTERNATIVE "", svm_vmexit_spec_ctrl, X86_FEATURE_SC_MSR_HVM /* WARNING! `ret`, `call *`, `jmp *` not safe before this point. */ STGI --- a/xen/include/asm-x86/msr.h +++ b/xen/include/asm-x86/msr.h @@ -287,6 +287,15 @@ struct vcpu_msrs * * For VT-x guests, the guest value is held in the MSR guest load/save * list. + * + * For SVM, the guest value lives in the VMCB, and hardware saves/restores + * the host value automatically. However, guests run with the OR of the + * host and guest value, which allows Xen to set protections behind the + * guest's back. + * + * We must clear/restore Xen's value before/after VMRUN to avoid unduly + * influencing the guest. In order to support "behind the guest's back" + * protections, we load this value (commonly 0) before VMRUN. */ struct { uint32_t raw; --- a/xen/include/asm-x86/spec_ctrl_asm.h +++ b/xen/include/asm-x86/spec_ctrl_asm.h @@ -46,6 +46,9 @@ * - On VMX by using MSR load/save lists to have vmentry/exit atomically * load/save the guest value. Xen's value is loaded in regular code, and * there is no need to use the shadow logic (below). + * - On SVM by altering MSR_SPEC_CTRL inside the CLGI/STGI region. This + * makes the changes atomic with respect to NMIs/etc, so no need for + * shadowing logic. * * Factor 2 is harder. We maintain a shadow_spec_ctrl value, and a use_shadow * boolean in the per cpu spec_ctrl_flags. The synchronous use is: --- a/xen/arch/x86/x86_64/asm-offsets.c +++ b/xen/arch/x86/x86_64/asm-offsets.c @@ -120,6 +120,7 @@ void __dummy__(void) OFFSET(CPUINFO_pv_cr3, struct cpu_info, pv_cr3); OFFSET(CPUINFO_shadow_spec_ctrl, struct cpu_info, shadow_spec_ctrl); OFFSET(CPUINFO_xen_spec_ctrl, struct cpu_info, xen_spec_ctrl); + OFFSET(CPUINFO_last_spec_ctrl, struct cpu_info, last_spec_ctrl); OFFSET(CPUINFO_spec_ctrl_flags, struct cpu_info, spec_ctrl_flags); OFFSET(CPUINFO_root_pgt_changed, struct cpu_info, root_pgt_changed); OFFSET(CPUINFO_use_pv_cr3, struct cpu_info, use_pv_cr3);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor