18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _ASM_X86_SPECCTRL_H_
38c2ecf20Sopenharmony_ci#define _ASM_X86_SPECCTRL_H_
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <linux/thread_info.h>
68c2ecf20Sopenharmony_ci#include <asm/nospec-branch.h>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci/*
98c2ecf20Sopenharmony_ci * On VMENTER we must preserve whatever view of the SPEC_CTRL MSR
108c2ecf20Sopenharmony_ci * the guest has, while on VMEXIT we restore the host view. This
118c2ecf20Sopenharmony_ci * would be easier if SPEC_CTRL were architecturally maskable or
128c2ecf20Sopenharmony_ci * shadowable for guests but this is not (currently) the case.
138c2ecf20Sopenharmony_ci * Takes the guest view of SPEC_CTRL MSR as a parameter and also
148c2ecf20Sopenharmony_ci * the guest's version of VIRT_SPEC_CTRL, if emulated.
158c2ecf20Sopenharmony_ci */
168c2ecf20Sopenharmony_ciextern void x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool guest);
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci/**
198c2ecf20Sopenharmony_ci * x86_spec_ctrl_set_guest - Set speculation control registers for the guest
208c2ecf20Sopenharmony_ci * @guest_spec_ctrl:		The guest content of MSR_SPEC_CTRL
218c2ecf20Sopenharmony_ci * @guest_virt_spec_ctrl:	The guest controlled bits of MSR_VIRT_SPEC_CTRL
228c2ecf20Sopenharmony_ci *				(may get translated to MSR_AMD64_LS_CFG bits)
238c2ecf20Sopenharmony_ci *
248c2ecf20Sopenharmony_ci * Avoids writing to the MSR if the content/bits are the same
258c2ecf20Sopenharmony_ci */
268c2ecf20Sopenharmony_cistatic inline
278c2ecf20Sopenharmony_civoid x86_spec_ctrl_set_guest(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl)
288c2ecf20Sopenharmony_ci{
298c2ecf20Sopenharmony_ci	x86_virt_spec_ctrl(guest_spec_ctrl, guest_virt_spec_ctrl, true);
308c2ecf20Sopenharmony_ci}
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci/**
338c2ecf20Sopenharmony_ci * x86_spec_ctrl_restore_host - Restore host speculation control registers
348c2ecf20Sopenharmony_ci * @guest_spec_ctrl:		The guest content of MSR_SPEC_CTRL
358c2ecf20Sopenharmony_ci * @guest_virt_spec_ctrl:	The guest controlled bits of MSR_VIRT_SPEC_CTRL
368c2ecf20Sopenharmony_ci *				(may get translated to MSR_AMD64_LS_CFG bits)
378c2ecf20Sopenharmony_ci *
388c2ecf20Sopenharmony_ci * Avoids writing to the MSR if the content/bits are the same
398c2ecf20Sopenharmony_ci */
408c2ecf20Sopenharmony_cistatic inline
418c2ecf20Sopenharmony_civoid x86_spec_ctrl_restore_host(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl)
428c2ecf20Sopenharmony_ci{
438c2ecf20Sopenharmony_ci	x86_virt_spec_ctrl(guest_spec_ctrl, guest_virt_spec_ctrl, false);
448c2ecf20Sopenharmony_ci}
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci/* AMD specific Speculative Store Bypass MSR data */
478c2ecf20Sopenharmony_ciextern u64 x86_amd_ls_cfg_base;
488c2ecf20Sopenharmony_ciextern u64 x86_amd_ls_cfg_ssbd_mask;
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_cistatic inline u64 ssbd_tif_to_spec_ctrl(u64 tifn)
518c2ecf20Sopenharmony_ci{
528c2ecf20Sopenharmony_ci	BUILD_BUG_ON(TIF_SSBD < SPEC_CTRL_SSBD_SHIFT);
538c2ecf20Sopenharmony_ci	return (tifn & _TIF_SSBD) >> (TIF_SSBD - SPEC_CTRL_SSBD_SHIFT);
548c2ecf20Sopenharmony_ci}
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistatic inline u64 stibp_tif_to_spec_ctrl(u64 tifn)
578c2ecf20Sopenharmony_ci{
588c2ecf20Sopenharmony_ci	BUILD_BUG_ON(TIF_SPEC_IB < SPEC_CTRL_STIBP_SHIFT);
598c2ecf20Sopenharmony_ci	return (tifn & _TIF_SPEC_IB) >> (TIF_SPEC_IB - SPEC_CTRL_STIBP_SHIFT);
608c2ecf20Sopenharmony_ci}
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_cistatic inline unsigned long ssbd_spec_ctrl_to_tif(u64 spec_ctrl)
638c2ecf20Sopenharmony_ci{
648c2ecf20Sopenharmony_ci	BUILD_BUG_ON(TIF_SSBD < SPEC_CTRL_SSBD_SHIFT);
658c2ecf20Sopenharmony_ci	return (spec_ctrl & SPEC_CTRL_SSBD) << (TIF_SSBD - SPEC_CTRL_SSBD_SHIFT);
668c2ecf20Sopenharmony_ci}
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cistatic inline unsigned long stibp_spec_ctrl_to_tif(u64 spec_ctrl)
698c2ecf20Sopenharmony_ci{
708c2ecf20Sopenharmony_ci	BUILD_BUG_ON(TIF_SPEC_IB < SPEC_CTRL_STIBP_SHIFT);
718c2ecf20Sopenharmony_ci	return (spec_ctrl & SPEC_CTRL_STIBP) << (TIF_SPEC_IB - SPEC_CTRL_STIBP_SHIFT);
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_cistatic inline u64 ssbd_tif_to_amd_ls_cfg(u64 tifn)
758c2ecf20Sopenharmony_ci{
768c2ecf20Sopenharmony_ci	return (tifn & _TIF_SSBD) ? x86_amd_ls_cfg_ssbd_mask : 0ULL;
778c2ecf20Sopenharmony_ci}
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP
808c2ecf20Sopenharmony_ciextern void speculative_store_bypass_ht_init(void);
818c2ecf20Sopenharmony_ci#else
828c2ecf20Sopenharmony_cistatic inline void speculative_store_bypass_ht_init(void) { }
838c2ecf20Sopenharmony_ci#endif
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ciextern void speculation_ctrl_update(unsigned long tif);
868c2ecf20Sopenharmony_ciextern void speculation_ctrl_update_current(void);
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci#endif
89