Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Interface for managing mitigations for Spectre vulnerabilities.
0004  *
0005  * Copyright (C) 2020 Google LLC
0006  * Author: Will Deacon <will@kernel.org>
0007  */
0008 
0009 #ifndef __ASM_SPECTRE_H
0010 #define __ASM_SPECTRE_H
0011 
0012 #define BP_HARDEN_EL2_SLOTS 4
0013 #define __BP_HARDEN_HYP_VECS_SZ ((BP_HARDEN_EL2_SLOTS - 1) * SZ_2K)
0014 
0015 #ifndef __ASSEMBLY__
0016 
0017 #include <linux/percpu.h>
0018 
0019 #include <asm/cpufeature.h>
0020 #include <asm/virt.h>
0021 
0022 /* Watch out, ordering is important here. */
0023 enum mitigation_state {
0024     SPECTRE_UNAFFECTED,
0025     SPECTRE_MITIGATED,
0026     SPECTRE_VULNERABLE,
0027 };
0028 
0029 struct task_struct;
0030 
0031 /*
0032  * Note: the order of this enum corresponds to __bp_harden_hyp_vecs and
0033  * we rely on having the direct vectors first.
0034  */
0035 enum arm64_hyp_spectre_vector {
0036     /*
0037      * Take exceptions directly to __kvm_hyp_vector. This must be
0038      * 0 so that it used by default when mitigations are not needed.
0039      */
0040     HYP_VECTOR_DIRECT,
0041 
0042     /*
0043      * Bounce via a slot in the hypervisor text mapping of
0044      * __bp_harden_hyp_vecs, which contains an SMC call.
0045      */
0046     HYP_VECTOR_SPECTRE_DIRECT,
0047 
0048     /*
0049      * Bounce via a slot in a special mapping of __bp_harden_hyp_vecs
0050      * next to the idmap page.
0051      */
0052     HYP_VECTOR_INDIRECT,
0053 
0054     /*
0055      * Bounce via a slot in a special mapping of __bp_harden_hyp_vecs
0056      * next to the idmap page, which contains an SMC call.
0057      */
0058     HYP_VECTOR_SPECTRE_INDIRECT,
0059 };
0060 
0061 typedef void (*bp_hardening_cb_t)(void);
0062 
0063 struct bp_hardening_data {
0064     enum arm64_hyp_spectre_vector   slot;
0065     bp_hardening_cb_t       fn;
0066 };
0067 
0068 DECLARE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);
0069 
0070 /* Called during entry so must be __always_inline */
0071 static __always_inline void arm64_apply_bp_hardening(void)
0072 {
0073     struct bp_hardening_data *d;
0074 
0075     if (!cpus_have_const_cap(ARM64_SPECTRE_V2))
0076         return;
0077 
0078     d = this_cpu_ptr(&bp_hardening_data);
0079     if (d->fn)
0080         d->fn();
0081 }
0082 
0083 enum mitigation_state arm64_get_spectre_v2_state(void);
0084 bool has_spectre_v2(const struct arm64_cpu_capabilities *cap, int scope);
0085 void spectre_v2_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
0086 
0087 bool has_spectre_v3a(const struct arm64_cpu_capabilities *cap, int scope);
0088 void spectre_v3a_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
0089 
0090 enum mitigation_state arm64_get_spectre_v4_state(void);
0091 bool has_spectre_v4(const struct arm64_cpu_capabilities *cap, int scope);
0092 void spectre_v4_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
0093 void spectre_v4_enable_task_mitigation(struct task_struct *tsk);
0094 
0095 enum mitigation_state arm64_get_meltdown_state(void);
0096 
0097 enum mitigation_state arm64_get_spectre_bhb_state(void);
0098 bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
0099 u8 spectre_bhb_loop_affected(int scope);
0100 void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
0101 #endif  /* __ASSEMBLY__ */
0102 #endif  /* __ASM_SPECTRE_H */