1bfac263fSPaolo Bonzini /* SPDX-License-Identifier: GPL-2.0 */ 2bfac263fSPaolo Bonzini #ifndef __KVM_X86_VMENTER_H 3bfac263fSPaolo Bonzini #define __KVM_X86_VMENTER_H 4bfac263fSPaolo Bonzini 5*c3029c38SChang S. Bae #include <asm/kvm_vcpu_regs.h> 6*c3029c38SChang S. Bae 7bfac263fSPaolo Bonzini #define KVM_ENTER_VMRESUME BIT(0) 8bfac263fSPaolo Bonzini #define KVM_ENTER_SAVE_SPEC_CTRL BIT(1) 9bfac263fSPaolo Bonzini #define KVM_ENTER_CLEAR_CPU_BUFFERS_FOR_MMIO BIT(2) 10bfac263fSPaolo Bonzini 114b275d0fSPaolo Bonzini #ifdef __ASSEMBLER__ 124b275d0fSPaolo Bonzini .macro RESTORE_GUEST_SPEC_CTRL_BODY guest_spec_ctrl:req, label:req 134b275d0fSPaolo Bonzini /* 144b275d0fSPaolo Bonzini * SPEC_CTRL handling: if the guest's SPEC_CTRL value differs from the 154b275d0fSPaolo Bonzini * host's, write the MSR. This is kept out-of-line so that the common 164b275d0fSPaolo Bonzini * case does not have to jump. 174b275d0fSPaolo Bonzini * 184b275d0fSPaolo Bonzini * IMPORTANT: To avoid RSB underflow attacks and any other nastiness, 194b275d0fSPaolo Bonzini * there must not be any returns or indirect branches between this code 204b275d0fSPaolo Bonzini * and vmentry. 214b275d0fSPaolo Bonzini */ 224b275d0fSPaolo Bonzini #ifdef CONFIG_X86_64 234b275d0fSPaolo Bonzini mov \guest_spec_ctrl, %rdx 244b275d0fSPaolo Bonzini cmp PER_CPU_VAR(x86_spec_ctrl_current), %rdx 254b275d0fSPaolo Bonzini je \label 264b275d0fSPaolo Bonzini movl %edx, %eax 274b275d0fSPaolo Bonzini shr $32, %rdx 284b275d0fSPaolo Bonzini #else 294b275d0fSPaolo Bonzini mov \guest_spec_ctrl, %eax 304b275d0fSPaolo Bonzini mov PER_CPU_VAR(x86_spec_ctrl_current), %ecx 314b275d0fSPaolo Bonzini xor %eax, %ecx 324b275d0fSPaolo Bonzini mov 4 + \guest_spec_ctrl, %edx 334b275d0fSPaolo Bonzini mov PER_CPU_VAR(x86_spec_ctrl_current + 4), %esi 344b275d0fSPaolo Bonzini xor %edx, %esi 354b275d0fSPaolo Bonzini or %esi, %ecx 364b275d0fSPaolo Bonzini je \label 374b275d0fSPaolo Bonzini #endif 384b275d0fSPaolo Bonzini mov $MSR_IA32_SPEC_CTRL, %ecx 394b275d0fSPaolo Bonzini wrmsr 404b275d0fSPaolo Bonzini .endm 414b275d0fSPaolo Bonzini 424b275d0fSPaolo Bonzini .macro RESTORE_HOST_SPEC_CTRL_BODY guest_spec_ctrl:req, enter_flags:req, label:req 434b275d0fSPaolo Bonzini /* Same for after vmexit. */ 444b275d0fSPaolo Bonzini mov $MSR_IA32_SPEC_CTRL, %ecx 454b275d0fSPaolo Bonzini 464b275d0fSPaolo Bonzini /* 474b275d0fSPaolo Bonzini * Load the value that the guest had written into MSR_IA32_SPEC_CTRL, 484b275d0fSPaolo Bonzini * if it was not intercepted during guest execution. 494b275d0fSPaolo Bonzini */ 504b275d0fSPaolo Bonzini testl $KVM_ENTER_SAVE_SPEC_CTRL, \enter_flags 514b275d0fSPaolo Bonzini jz 998f 524b275d0fSPaolo Bonzini rdmsr 534b275d0fSPaolo Bonzini movl %eax, \guest_spec_ctrl 544b275d0fSPaolo Bonzini movl %edx, 4 + \guest_spec_ctrl 554b275d0fSPaolo Bonzini 998: 564b275d0fSPaolo Bonzini /* Now restore the host value of the MSR if different from the guest's. */ 574b275d0fSPaolo Bonzini #ifdef CONFIG_X86_64 584b275d0fSPaolo Bonzini mov PER_CPU_VAR(x86_spec_ctrl_current), %rdx 594b275d0fSPaolo Bonzini cmp \guest_spec_ctrl, %rdx 60344ebd21SPaolo Bonzini /* 61344ebd21SPaolo Bonzini * For legacy IBRS, the IBRS bit always needs to be written after 62344ebd21SPaolo Bonzini * transitioning from a less privileged predictor mode, regardless of 63344ebd21SPaolo Bonzini * whether the guest/host values differ. 64344ebd21SPaolo Bonzini */ 65344ebd21SPaolo Bonzini ALTERNATIVE __stringify(je \label), "", X86_FEATURE_KERNEL_IBRS 664b275d0fSPaolo Bonzini movl %edx, %eax 674b275d0fSPaolo Bonzini shr $32, %rdx 684b275d0fSPaolo Bonzini #else 694b275d0fSPaolo Bonzini mov PER_CPU_VAR(x86_spec_ctrl_current), %eax 704b275d0fSPaolo Bonzini mov \guest_spec_ctrl, %esi 714b275d0fSPaolo Bonzini xor %eax, %esi 724b275d0fSPaolo Bonzini mov PER_CPU_VAR(x86_spec_ctrl_current + 4), %edx 734b275d0fSPaolo Bonzini mov 4 + \guest_spec_ctrl, %edi 744b275d0fSPaolo Bonzini xor %edx, %edi 754b275d0fSPaolo Bonzini or %edi, %esi 76344ebd21SPaolo Bonzini ALTERNATIVE __stringify(je \label), "", X86_FEATURE_KERNEL_IBRS 774b275d0fSPaolo Bonzini #endif 784b275d0fSPaolo Bonzini wrmsr 794b275d0fSPaolo Bonzini .endm 804b275d0fSPaolo Bonzini 81*c3029c38SChang S. Bae #define WORD_SIZE (BITS_PER_LONG / 8) 82*c3029c38SChang S. Bae 83*c3029c38SChang S. Bae .macro LOAD_REGS src:req, regs_ofs:req, regs:vararg 84*c3029c38SChang S. Bae .irp reg, \regs 85*c3029c38SChang S. Bae REG_NUM reg_num \reg 86*c3029c38SChang S. Bae mov (\regs_ofs + reg_num * WORD_SIZE)(\src), \reg 87*c3029c38SChang S. Bae .endr 88*c3029c38SChang S. Bae .endm 89*c3029c38SChang S. Bae 90*c3029c38SChang S. Bae .macro STORE_REGS dst:req, regs_ofs:req, regs:vararg 91*c3029c38SChang S. Bae .irp reg, \regs 92*c3029c38SChang S. Bae REG_NUM reg_num \reg 93*c3029c38SChang S. Bae mov \reg, (\regs_ofs + reg_num * WORD_SIZE)(\dst) 94*c3029c38SChang S. Bae .endr 95*c3029c38SChang S. Bae .endm 96*c3029c38SChang S. Bae 97*c3029c38SChang S. Bae .macro POP_REGS dst:req, regs_ofs:req, regs:vararg 98*c3029c38SChang S. Bae .irp reg, \regs 99*c3029c38SChang S. Bae REG_NUM reg_num \reg 100*c3029c38SChang S. Bae pop (\regs_ofs + reg_num * WORD_SIZE)(\dst) 101*c3029c38SChang S. Bae .endr 102*c3029c38SChang S. Bae .endm 103*c3029c38SChang S. Bae 104*c3029c38SChang S. Bae .macro CLEAR_REGS regs:vararg 105*c3029c38SChang S. Bae .irp reg, \regs 106*c3029c38SChang S. Bae xorl \reg, \reg 107*c3029c38SChang S. Bae .endr 108*c3029c38SChang S. Bae .endm 109*c3029c38SChang S. Bae 1104b275d0fSPaolo Bonzini #endif /* __ASSEMBLER__ */ 111bfac263fSPaolo Bonzini #endif /* __KVM_X86_VMENTER_H */ 112