This is the 4.9.114 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAltUeE0ACgkQONu9yGCS aT4CSw//Zx5kAiLzeHgW4cremUB343o2apjiRd9HqVJwyYQIxEWyKbxh8+/urmkz dR2Mz+zAEbM/cbvsmoUru1Zu1lFloGBF1Vlc7/FLeFjBa2x/aEnkwUaQ6d2Q4iFC C5rBVQdNYEmKng6FxqijJwRzIjYRdH0+3svz6AxyTVpeuLf7qIBsx6tf50dUqbaj zz0l/TJE6uz14d3ZyaH8I17iSCS/AmdJLzEENuPivJydQXrsgf4etzseXshyykuL 2ZZ00+xpvoBd8ISjcwhHYVFIrU17hmDaOPVkl1F7XeVeBOIpOUU8iu7l/2gOOl1Q mQbQX3F98rPYbhAZEK0r93XLDB5jOt7JzLYNHunKGA/AWA1BTPdw7zJJMSlJgLiV QT9j5s8PjAAXoGRIMmE+zvV/1Y34EB0bY0kW7BRe0nTSCiz9UKlbEBRPirS9cjO8 aZ5+xJvf8ALhxeIAlQORBpjLu3ypzgC9jOqQIUTYVQuPEKYuWbqw1vdRvqi288MT rq67rND1Yjx/QswuG9YFK8PVOegCMj2/+GCgyAI0XV1w6uB7i1gJ6YAoWcojn9qZ os6OGelaYciJADJDsEUPeSg9Simsxy/twrQTomJNYCys9/fuleUkKUzpMKQUcl13 eerFstBmJsC2JMjwHMh6vUxM2/njQbxrANnJt8Arrdpd7IpcgKA= =WxwP -----END PGP SIGNATURE----- Merge 4.9.114 into android-4.9 Changes in 4.9.114 MIPS: Use async IPIs for arch_trigger_cpumask_backtrace() compiler, clang: suppress warning for unused static inline functions compiler, clang: properly override 'inline' for clang compiler, clang: always inline when CONFIG_OPTIMIZE_INLINING is disabled compiler-gcc.h: Add __attribute__((gnu_inline)) to all inline declarations x86/asm: Add _ASM_ARG* constants for argument registers to <asm/asm.h> x86/paravirt: Make native_save_fl() extern inline ocfs2: subsystem.su_mutex is required while accessing the item->ci_parent ocfs2: ip_alloc_sem should be taken in ocfs2_get_block() mtd: m25p80: consider max message size in m25p80_read bcm63xx_enet: correct clock usage bcm63xx_enet: do not write to random DMA channel on BCM6345 crypto: crypto4xx - remove bad list_del crypto: crypto4xx - fix crypto4xx_build_pdr, crypto4xx_build_sdr leak atm: zatm: Fix potential Spectre v1 ipvlan: fix IFLA_MTU ignored on NEWLINK net: dccp: avoid crash in ccid3_hc_rx_send_feedback() net: dccp: switch rx_tstamp_last_feedback to monotonic clock net/mlx5: Fix incorrect raw command length parsing net/mlx5: Fix wrong size allocation for QoS ETC TC regitster net_sched: blackhole: tell upper qdisc about dropped packets net: sungem: fix rx checksum support qed: Fix use of incorrect size in memcpy call. qed: Limit msix vectors in kdump kernel to the minimum required count. qmi_wwan: add support for the Dell Wireless 5821e module r8152: napi hangup fix after disconnect tcp: fix Fast Open key endianness tcp: prevent bogus FRTO undos with non-SACK flows vhost_net: validate sock before trying to put its fd net/packet: fix use-after-free net/mlx5: Fix command interface race in polling mode net: cxgb3_main: fix potential Spectre v1 rtlwifi: rtl8821ae: fix firmware is not ready to run net: lan78xx: Fix race in tx pending skb size calculation netfilter: ebtables: reject non-bridge targets reiserfs: fix buffer overflow with long warning messages KEYS: DNS: fix parsing multiple options netfilter: ipv6: nf_defrag: drop skb dst before queueing rds: avoid unenecessary cong_update in loop transport net/nfc: Avoid stalls when nfc_alloc_send_skb() returned NULL. arm64: assembler: introduce ldr_this_cpu KVM: arm64: Store vcpu on the stack during __guest_enter() KVM: arm/arm64: Convert kvm_host_cpu_state to a static per-cpu allocation KVM: arm64: Change hyp_panic()s dependency on tpidr_el2 arm64: alternatives: use tpidr_el2 on VHE hosts KVM: arm64: Stop save/restoring host tpidr_el1 on VHE arm64: alternatives: Add dynamic patching feature KVM: arm/arm64: Do not use kern_hyp_va() with kvm_vgic_global_state KVM: arm64: Avoid storing the vcpu pointer on the stack arm/arm64: smccc: Add SMCCC-specific return codes arm64: Call ARCH_WORKAROUND_2 on transitions between EL0 and EL1 arm64: Add per-cpu infrastructure to call ARCH_WORKAROUND_2 arm64: Add ARCH_WORKAROUND_2 probing arm64: Add 'ssbd' command-line option arm64: ssbd: Add global mitigation state accessor arm64: ssbd: Skip apply_ssbd if not using dynamic mitigation arm64: ssbd: Restore mitigation status on CPU resume arm64: ssbd: Introduce thread flag to control userspace mitigation arm64: ssbd: Add prctl interface for per-thread mitigation arm64: KVM: Add HYP per-cpu accessors arm64: KVM: Add ARCH_WORKAROUND_2 support for guests arm64: KVM: Handle guest's ARCH_WORKAROUND_2 requests arm64: KVM: Add ARCH_WORKAROUND_2 discovery through ARCH_FEATURES_FUNC_ID string: drop __must_check from strscpy() and restore strscpy() usages in cgroup Linux 4.9.114 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
dbcb74867c
71 changed files with 1307 additions and 267 deletions
|
|
@ -4035,6 +4035,23 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
spia_pedr=
|
||||
spia_peddr=
|
||||
|
||||
ssbd= [ARM64,HW]
|
||||
Speculative Store Bypass Disable control
|
||||
|
||||
On CPUs that are vulnerable to the Speculative
|
||||
Store Bypass vulnerability and offer a
|
||||
firmware based mitigation, this parameter
|
||||
indicates how the mitigation should be used:
|
||||
|
||||
force-on: Unconditionally enable mitigation for
|
||||
for both kernel and userspace
|
||||
force-off: Unconditionally disable mitigation for
|
||||
for both kernel and userspace
|
||||
kernel: Always enable mitigation in the
|
||||
kernel, and offer a prctl interface
|
||||
to allow userspace to register its
|
||||
interest in being mitigated too.
|
||||
|
||||
stack_guard_gap= [MM]
|
||||
override the default stack gap protection. The value
|
||||
is in page units and it defines how many pages prior
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -1,6 +1,6 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 113
|
||||
SUBLEVEL = 114
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
|
|
|||
|
|
@ -327,4 +327,16 @@ static inline bool kvm_arm_harden_branch_predictor(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
#define KVM_SSBD_UNKNOWN -1
|
||||
#define KVM_SSBD_FORCE_DISABLE 0
|
||||
#define KVM_SSBD_KERNEL 1
|
||||
#define KVM_SSBD_FORCE_ENABLE 2
|
||||
#define KVM_SSBD_MITIGATED 3
|
||||
|
||||
static inline int kvm_arm_have_ssbd(void)
|
||||
{
|
||||
/* No way to detect it yet, pretend it is not there. */
|
||||
return KVM_SSBD_UNKNOWN;
|
||||
}
|
||||
|
||||
#endif /* __ARM_KVM_HOST_H__ */
|
||||
|
|
|
|||
|
|
@ -28,6 +28,13 @@
|
|||
*/
|
||||
#define kern_hyp_va(kva) (kva)
|
||||
|
||||
/* Contrary to arm64, there is no need to generate a PC-relative address */
|
||||
#define hyp_symbol_addr(s) \
|
||||
({ \
|
||||
typeof(s) *addr = &(s); \
|
||||
addr; \
|
||||
})
|
||||
|
||||
/*
|
||||
* KVM_MMU_CACHE_MIN_PAGES is the number of stage2 page table translation levels.
|
||||
*/
|
||||
|
|
@ -249,6 +256,11 @@ static inline int kvm_map_vectors(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int hyp_map_aux_data(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __ARM_KVM_MMU_H__ */
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@
|
|||
__asm__(".arch_extension virt");
|
||||
#endif
|
||||
|
||||
DEFINE_PER_CPU(kvm_cpu_context_t, kvm_host_cpu_state);
|
||||
static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
|
||||
static kvm_cpu_context_t __percpu *kvm_host_cpu_state;
|
||||
static unsigned long hyp_default_vectors;
|
||||
|
||||
/* Per-CPU variable containing the currently running vcpu. */
|
||||
|
|
@ -338,7 +338,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
|||
}
|
||||
|
||||
vcpu->cpu = cpu;
|
||||
vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state);
|
||||
vcpu->arch.host_cpu_context = this_cpu_ptr(&kvm_host_cpu_state);
|
||||
|
||||
kvm_arm_set_running_vcpu(vcpu);
|
||||
}
|
||||
|
|
@ -1199,19 +1199,8 @@ static inline void hyp_cpu_pm_exit(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void teardown_common_resources(void)
|
||||
{
|
||||
free_percpu(kvm_host_cpu_state);
|
||||
}
|
||||
|
||||
static int init_common_resources(void)
|
||||
{
|
||||
kvm_host_cpu_state = alloc_percpu(kvm_cpu_context_t);
|
||||
if (!kvm_host_cpu_state) {
|
||||
kvm_err("Cannot allocate host CPU state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* set size of VMID supported by CPU */
|
||||
kvm_vmid_bits = kvm_get_vmid_bits();
|
||||
kvm_info("%d-bit VMID\n", kvm_vmid_bits);
|
||||
|
|
@ -1369,7 +1358,7 @@ static int init_hyp_mode(void)
|
|||
for_each_possible_cpu(cpu) {
|
||||
kvm_cpu_context_t *cpu_ctxt;
|
||||
|
||||
cpu_ctxt = per_cpu_ptr(kvm_host_cpu_state, cpu);
|
||||
cpu_ctxt = per_cpu_ptr(&kvm_host_cpu_state, cpu);
|
||||
err = create_hyp_mappings(cpu_ctxt, cpu_ctxt + 1, PAGE_HYP);
|
||||
|
||||
if (err) {
|
||||
|
|
@ -1378,6 +1367,12 @@ static int init_hyp_mode(void)
|
|||
}
|
||||
}
|
||||
|
||||
err = hyp_map_aux_data();
|
||||
if (err) {
|
||||
kvm_err("Cannot map host auxilary data: %d\n", err);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
kvm_info("Hyp mode initialized successfully\n");
|
||||
|
||||
return 0;
|
||||
|
|
@ -1447,7 +1442,6 @@ int kvm_arch_init(void *opaque)
|
|||
out_hyp:
|
||||
teardown_hyp_mode();
|
||||
out_err:
|
||||
teardown_common_resources();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ static int kvm_psci_call(struct kvm_vcpu *vcpu)
|
|||
int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u32 func_id = smccc_get_function(vcpu);
|
||||
u32 val = PSCI_RET_NOT_SUPPORTED;
|
||||
u32 val = SMCCC_RET_NOT_SUPPORTED;
|
||||
u32 feature;
|
||||
|
||||
switch (func_id) {
|
||||
|
|
@ -415,7 +415,21 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
|
|||
switch(feature) {
|
||||
case ARM_SMCCC_ARCH_WORKAROUND_1:
|
||||
if (kvm_arm_harden_branch_predictor())
|
||||
val = 0;
|
||||
val = SMCCC_RET_SUCCESS;
|
||||
break;
|
||||
case ARM_SMCCC_ARCH_WORKAROUND_2:
|
||||
switch (kvm_arm_have_ssbd()) {
|
||||
case KVM_SSBD_FORCE_DISABLE:
|
||||
case KVM_SSBD_UNKNOWN:
|
||||
break;
|
||||
case KVM_SSBD_KERNEL:
|
||||
val = SMCCC_RET_SUCCESS;
|
||||
break;
|
||||
case KVM_SSBD_FORCE_ENABLE:
|
||||
case KVM_SSBD_MITIGATED:
|
||||
val = SMCCC_RET_NOT_REQUIRED;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -778,6 +778,15 @@ config HARDEN_BRANCH_PREDICTOR
|
|||
|
||||
If unsure, say Y.
|
||||
|
||||
config ARM64_SSBD
|
||||
bool "Speculative Store Bypass Disable" if EXPERT
|
||||
default y
|
||||
help
|
||||
This enables mitigation of the bypassing of previous stores
|
||||
by speculative loads.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
menuconfig ARMV8_DEPRECATED
|
||||
bool "Emulate deprecated/obsolete ARMv8 instructions"
|
||||
depends on COMPAT
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#include <asm/cpucaps.h>
|
||||
#include <asm/insn.h>
|
||||
|
||||
#define ARM64_CB_PATCH ARM64_NCAPS
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/init.h>
|
||||
|
|
@ -11,6 +13,8 @@
|
|||
#include <linux/stddef.h>
|
||||
#include <linux/stringify.h>
|
||||
|
||||
extern int alternatives_applied;
|
||||
|
||||
struct alt_instr {
|
||||
s32 orig_offset; /* offset to original instruction */
|
||||
s32 alt_offset; /* offset to replacement instruction */
|
||||
|
|
@ -19,12 +23,19 @@ struct alt_instr {
|
|||
u8 alt_len; /* size of new instruction(s), <= orig_len */
|
||||
};
|
||||
|
||||
typedef void (*alternative_cb_t)(struct alt_instr *alt,
|
||||
__le32 *origptr, __le32 *updptr, int nr_inst);
|
||||
|
||||
void __init apply_alternatives_all(void);
|
||||
void apply_alternatives(void *start, size_t length);
|
||||
|
||||
#define ALTINSTR_ENTRY(feature) \
|
||||
#define ALTINSTR_ENTRY(feature,cb) \
|
||||
" .word 661b - .\n" /* label */ \
|
||||
" .if " __stringify(cb) " == 0\n" \
|
||||
" .word 663f - .\n" /* new instruction */ \
|
||||
" .else\n" \
|
||||
" .word " __stringify(cb) "- .\n" /* callback */ \
|
||||
" .endif\n" \
|
||||
" .hword " __stringify(feature) "\n" /* feature bit */ \
|
||||
" .byte 662b-661b\n" /* source len */ \
|
||||
" .byte 664f-663f\n" /* replacement len */
|
||||
|
|
@ -42,15 +53,18 @@ void apply_alternatives(void *start, size_t length);
|
|||
* but most assemblers die if insn1 or insn2 have a .inst. This should
|
||||
* be fixed in a binutils release posterior to 2.25.51.0.2 (anything
|
||||
* containing commit 4e4d08cf7399b606 or c1baaddf8861).
|
||||
*
|
||||
* Alternatives with callbacks do not generate replacement instructions.
|
||||
*/
|
||||
#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled) \
|
||||
#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled, cb) \
|
||||
".if "__stringify(cfg_enabled)" == 1\n" \
|
||||
"661:\n\t" \
|
||||
oldinstr "\n" \
|
||||
"662:\n" \
|
||||
".pushsection .altinstructions,\"a\"\n" \
|
||||
ALTINSTR_ENTRY(feature) \
|
||||
ALTINSTR_ENTRY(feature,cb) \
|
||||
".popsection\n" \
|
||||
" .if " __stringify(cb) " == 0\n" \
|
||||
".pushsection .altinstr_replacement, \"a\"\n" \
|
||||
"663:\n\t" \
|
||||
newinstr "\n" \
|
||||
|
|
@ -58,11 +72,17 @@ void apply_alternatives(void *start, size_t length);
|
|||
".popsection\n\t" \
|
||||
".org . - (664b-663b) + (662b-661b)\n\t" \
|
||||
".org . - (662b-661b) + (664b-663b)\n" \
|
||||
".else\n\t" \
|
||||
"663:\n\t" \
|
||||
"664:\n\t" \
|
||||
".endif\n" \
|
||||
".endif\n"
|
||||
|
||||
#define _ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg, ...) \
|
||||
__ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg))
|
||||
__ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg), 0)
|
||||
|
||||
#define ALTERNATIVE_CB(oldinstr, cb) \
|
||||
__ALTERNATIVE_CFG(oldinstr, "NOT_AN_INSTRUCTION", ARM64_CB_PATCH, 1, cb)
|
||||
#else
|
||||
|
||||
#include <asm/assembler.h>
|
||||
|
|
@ -129,6 +149,14 @@ void apply_alternatives(void *start, size_t length);
|
|||
661:
|
||||
.endm
|
||||
|
||||
.macro alternative_cb cb
|
||||
.set .Lasm_alt_mode, 0
|
||||
.pushsection .altinstructions, "a"
|
||||
altinstruction_entry 661f, \cb, ARM64_CB_PATCH, 662f-661f, 0
|
||||
.popsection
|
||||
661:
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Provide the other half of the alternative code sequence.
|
||||
*/
|
||||
|
|
@ -154,6 +182,13 @@ void apply_alternatives(void *start, size_t length);
|
|||
.org . - (662b-661b) + (664b-663b)
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Callback-based alternative epilogue
|
||||
*/
|
||||
.macro alternative_cb_end
|
||||
662:
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Provides a trivial alternative or default sequence consisting solely
|
||||
* of NOPs. The number of NOPs is chosen automatically to match the
|
||||
|
|
|
|||
|
|
@ -269,6 +269,36 @@ lr .req x30 // link register
|
|||
ldr \dst, [\dst, \tmp]
|
||||
.endm
|
||||
|
||||
/*
|
||||
* @dst: Result of per_cpu(sym, smp_processor_id())
|
||||
* @sym: The name of the per-cpu variable
|
||||
* @tmp: scratch register
|
||||
*/
|
||||
.macro adr_this_cpu, dst, sym, tmp
|
||||
adr_l \dst, \sym
|
||||
alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
|
||||
mrs \tmp, tpidr_el1
|
||||
alternative_else
|
||||
mrs \tmp, tpidr_el2
|
||||
alternative_endif
|
||||
add \dst, \dst, \tmp
|
||||
.endm
|
||||
|
||||
/*
|
||||
* @dst: Result of READ_ONCE(per_cpu(sym, smp_processor_id()))
|
||||
* @sym: The name of the per-cpu variable
|
||||
* @tmp: scratch register
|
||||
*/
|
||||
.macro ldr_this_cpu dst, sym, tmp
|
||||
adr_l \dst, \sym
|
||||
alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
|
||||
mrs \tmp, tpidr_el1
|
||||
alternative_else
|
||||
mrs \tmp, tpidr_el2
|
||||
alternative_endif
|
||||
ldr \dst, [\dst, \tmp]
|
||||
.endm
|
||||
|
||||
/*
|
||||
* vma_vm_mm - get mm pointer from vma pointer (vma->vm_mm)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -34,10 +34,10 @@
|
|||
#define ARM64_HAS_32BIT_EL0 13
|
||||
#define ARM64_HYP_OFFSET_LOW 14
|
||||
#define ARM64_MISMATCHED_CACHE_LINE_SIZE 15
|
||||
#define ARM64_UNMAP_KERNEL_AT_EL0 16
|
||||
#define ARM64_HARDEN_BRANCH_PREDICTOR 17
|
||||
#define ARM64_SSBD 18
|
||||
|
||||
#define ARM64_UNMAP_KERNEL_AT_EL0 23
|
||||
#define ARM64_HARDEN_BRANCH_PREDICTOR 24
|
||||
|
||||
#define ARM64_NCAPS 25
|
||||
#define ARM64_NCAPS 19
|
||||
|
||||
#endif /* __ASM_CPUCAPS_H */
|
||||
|
|
|
|||
|
|
@ -227,6 +227,28 @@ static inline bool system_uses_ttbr0_pan(void)
|
|||
!cpus_have_cap(ARM64_HAS_PAN);
|
||||
}
|
||||
|
||||
#define ARM64_SSBD_UNKNOWN -1
|
||||
#define ARM64_SSBD_FORCE_DISABLE 0
|
||||
#define ARM64_SSBD_KERNEL 1
|
||||
#define ARM64_SSBD_FORCE_ENABLE 2
|
||||
#define ARM64_SSBD_MITIGATED 3
|
||||
|
||||
static inline int arm64_get_ssbd_state(void)
|
||||
{
|
||||
#ifdef CONFIG_ARM64_SSBD
|
||||
extern int ssbd_state;
|
||||
return ssbd_state;
|
||||
#else
|
||||
return ARM64_SSBD_UNKNOWN;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM64_SSBD
|
||||
void arm64_set_ssbd_mitigation(bool state);
|
||||
#else
|
||||
static inline void arm64_set_ssbd_mitigation(bool state) {}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@
|
|||
#define KVM_ARM64_DEBUG_DIRTY_SHIFT 0
|
||||
#define KVM_ARM64_DEBUG_DIRTY (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT)
|
||||
|
||||
#define VCPU_WORKAROUND_2_FLAG_SHIFT 0
|
||||
#define VCPU_WORKAROUND_2_FLAG (_AC(1, UL) << VCPU_WORKAROUND_2_FLAG_SHIFT)
|
||||
|
||||
/* Translate a kernel address of @sym into its equivalent linear mapping */
|
||||
#define kvm_ksym_ref(sym) \
|
||||
({ \
|
||||
void *val = &sym; \
|
||||
|
|
@ -65,6 +69,43 @@ extern u32 __kvm_get_mdcr_el2(void);
|
|||
|
||||
extern u32 __init_stage2_translation(void);
|
||||
|
||||
/* Home-grown __this_cpu_{ptr,read} variants that always work at HYP */
|
||||
#define __hyp_this_cpu_ptr(sym) \
|
||||
({ \
|
||||
void *__ptr = hyp_symbol_addr(sym); \
|
||||
__ptr += read_sysreg(tpidr_el2); \
|
||||
(typeof(&sym))__ptr; \
|
||||
})
|
||||
|
||||
#define __hyp_this_cpu_read(sym) \
|
||||
({ \
|
||||
*__hyp_this_cpu_ptr(sym); \
|
||||
})
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
.macro hyp_adr_this_cpu reg, sym, tmp
|
||||
adr_l \reg, \sym
|
||||
mrs \tmp, tpidr_el2
|
||||
add \reg, \reg, \tmp
|
||||
.endm
|
||||
|
||||
.macro hyp_ldr_this_cpu reg, sym, tmp
|
||||
adr_l \reg, \sym
|
||||
mrs \tmp, tpidr_el2
|
||||
ldr \reg, [\reg, \tmp]
|
||||
.endm
|
||||
|
||||
.macro get_host_ctxt reg, tmp
|
||||
hyp_adr_this_cpu \reg, kvm_host_cpu_state, \tmp
|
||||
.endm
|
||||
|
||||
.macro get_vcpu_ptr vcpu, ctxt
|
||||
get_host_ctxt \ctxt, \vcpu
|
||||
ldr \vcpu, [\ctxt, #HOST_CONTEXT_VCPU]
|
||||
kern_hyp_va \vcpu
|
||||
.endm
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __ARM_KVM_ASM_H__ */
|
||||
|
|
|
|||
|
|
@ -197,6 +197,8 @@ struct kvm_cpu_context {
|
|||
u64 sys_regs[NR_SYS_REGS];
|
||||
u32 copro[NR_COPRO_REGS];
|
||||
};
|
||||
|
||||
struct kvm_vcpu *__hyp_running_vcpu;
|
||||
};
|
||||
|
||||
typedef struct kvm_cpu_context kvm_cpu_context_t;
|
||||
|
|
@ -211,6 +213,9 @@ struct kvm_vcpu_arch {
|
|||
/* Exception Information */
|
||||
struct kvm_vcpu_fault_info fault;
|
||||
|
||||
/* State of various workarounds, see kvm_asm.h for bit assignment */
|
||||
u64 workaround_flags;
|
||||
|
||||
/* Guest debug state */
|
||||
u64 debug_flags;
|
||||
|
||||
|
|
@ -354,10 +359,15 @@ int kvm_perf_teardown(void);
|
|||
|
||||
struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
|
||||
|
||||
void __kvm_set_tpidr_el2(u64 tpidr_el2);
|
||||
DECLARE_PER_CPU(kvm_cpu_context_t, kvm_host_cpu_state);
|
||||
|
||||
static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
|
||||
unsigned long hyp_stack_ptr,
|
||||
unsigned long vector_ptr)
|
||||
{
|
||||
u64 tpidr_el2;
|
||||
|
||||
/*
|
||||
* Call initialization code, and switch to the full blown HYP code.
|
||||
* If the cpucaps haven't been finalized yet, something has gone very
|
||||
|
|
@ -366,6 +376,16 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
|
|||
*/
|
||||
BUG_ON(!static_branch_likely(&arm64_const_caps_ready));
|
||||
__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
|
||||
|
||||
/*
|
||||
* Calculate the raw per-cpu offset without a translation from the
|
||||
* kernel's mapping to the linear mapping, and store it in tpidr_el2
|
||||
* so that we can use adr_l to access per-cpu variables in EL2.
|
||||
*/
|
||||
tpidr_el2 = (u64)this_cpu_ptr(&kvm_host_cpu_state)
|
||||
- (u64)kvm_ksym_ref(kvm_host_cpu_state);
|
||||
|
||||
kvm_call_hyp(__kvm_set_tpidr_el2, tpidr_el2);
|
||||
}
|
||||
|
||||
void __kvm_hyp_teardown(void);
|
||||
|
|
@ -405,4 +425,27 @@ static inline bool kvm_arm_harden_branch_predictor(void)
|
|||
return cpus_have_const_cap(ARM64_HARDEN_BRANCH_PREDICTOR);
|
||||
}
|
||||
|
||||
#define KVM_SSBD_UNKNOWN -1
|
||||
#define KVM_SSBD_FORCE_DISABLE 0
|
||||
#define KVM_SSBD_KERNEL 1
|
||||
#define KVM_SSBD_FORCE_ENABLE 2
|
||||
#define KVM_SSBD_MITIGATED 3
|
||||
|
||||
static inline int kvm_arm_have_ssbd(void)
|
||||
{
|
||||
switch (arm64_get_ssbd_state()) {
|
||||
case ARM64_SSBD_FORCE_DISABLE:
|
||||
return KVM_SSBD_FORCE_DISABLE;
|
||||
case ARM64_SSBD_KERNEL:
|
||||
return KVM_SSBD_KERNEL;
|
||||
case ARM64_SSBD_FORCE_ENABLE:
|
||||
return KVM_SSBD_FORCE_ENABLE;
|
||||
case ARM64_SSBD_MITIGATED:
|
||||
return KVM_SSBD_MITIGATED;
|
||||
case ARM64_SSBD_UNKNOWN:
|
||||
default:
|
||||
return KVM_SSBD_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __ARM64_KVM_HOST_H__ */
|
||||
|
|
|
|||
|
|
@ -130,6 +130,26 @@ static inline unsigned long __kern_hyp_va(unsigned long v)
|
|||
|
||||
#define kern_hyp_va(v) ((typeof(v))(__kern_hyp_va((unsigned long)(v))))
|
||||
|
||||
/*
|
||||
* Obtain the PC-relative address of a kernel symbol
|
||||
* s: symbol
|
||||
*
|
||||
* The goal of this macro is to return a symbol's address based on a
|
||||
* PC-relative computation, as opposed to a loading the VA from a
|
||||
* constant pool or something similar. This works well for HYP, as an
|
||||
* absolute VA is guaranteed to be wrong. Only use this if trying to
|
||||
* obtain the address of a symbol (i.e. not something you obtained by
|
||||
* following a pointer).
|
||||
*/
|
||||
#define hyp_symbol_addr(s) \
|
||||
({ \
|
||||
typeof(s) *addr; \
|
||||
asm("adrp %0, %1\n" \
|
||||
"add %0, %0, :lo12:%1\n" \
|
||||
: "=r" (addr) : "S" (&s)); \
|
||||
addr; \
|
||||
})
|
||||
|
||||
/*
|
||||
* We currently only support a 40bit IPA.
|
||||
*/
|
||||
|
|
@ -367,5 +387,29 @@ static inline int kvm_map_vectors(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM64_SSBD
|
||||
DECLARE_PER_CPU_READ_MOSTLY(u64, arm64_ssbd_callback_required);
|
||||
|
||||
static inline int hyp_map_aux_data(void)
|
||||
{
|
||||
int cpu, err;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
u64 *ptr;
|
||||
|
||||
ptr = per_cpu_ptr(&arm64_ssbd_callback_required, cpu);
|
||||
err = create_hyp_mappings(ptr, ptr + 1, PAGE_HYP);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static inline int hyp_map_aux_data(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ARM64_KVM_MMU_H__ */
|
||||
|
|
|
|||
|
|
@ -17,10 +17,14 @@
|
|||
#define __ASM_PERCPU_H
|
||||
|
||||
#include <asm/stack_pointer.h>
|
||||
#include <asm/alternative.h>
|
||||
|
||||
static inline void set_my_cpu_offset(unsigned long off)
|
||||
{
|
||||
asm volatile("msr tpidr_el1, %0" :: "r" (off) : "memory");
|
||||
asm volatile(ALTERNATIVE("msr tpidr_el1, %0",
|
||||
"msr tpidr_el2, %0",
|
||||
ARM64_HAS_VIRT_HOST_EXTN)
|
||||
:: "r" (off) : "memory");
|
||||
}
|
||||
|
||||
static inline unsigned long __my_cpu_offset(void)
|
||||
|
|
@ -31,7 +35,10 @@ static inline unsigned long __my_cpu_offset(void)
|
|||
* We want to allow caching the value, so avoid using volatile and
|
||||
* instead use a fake stack read to hazard against barrier().
|
||||
*/
|
||||
asm("mrs %0, tpidr_el1" : "=r" (off) :
|
||||
asm(ALTERNATIVE("mrs %0, tpidr_el1",
|
||||
"mrs %0, tpidr_el2",
|
||||
ARM64_HAS_VIRT_HOST_EXTN)
|
||||
: "=r" (off) :
|
||||
"Q" (*(const unsigned long *)current_stack_pointer));
|
||||
|
||||
return off;
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ struct thread_info {
|
|||
#define TIF_RESTORE_SIGMASK 20
|
||||
#define TIF_SINGLESTEP 21
|
||||
#define TIF_32BIT 22 /* 32bit process */
|
||||
#define TIF_SSBD 23 /* Wants SSB mitigation */
|
||||
|
||||
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
|
||||
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
|
|||
arm64-obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o
|
||||
arm64-obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o \
|
||||
cpu-reset.o
|
||||
arm64-obj-$(CONFIG_ARM64_SSBD) += ssbd.o
|
||||
|
||||
ifeq ($(CONFIG_KVM),y)
|
||||
arm64-obj-$(CONFIG_HARDEN_BRANCH_PREDICTOR) += bpi.o
|
||||
|
|
|
|||
|
|
@ -28,10 +28,12 @@
|
|||
#include <asm/sections.h>
|
||||
#include <linux/stop_machine.h>
|
||||
|
||||
#define __ALT_PTR(a,f) (u32 *)((void *)&(a)->f + (a)->f)
|
||||
#define __ALT_PTR(a,f) ((void *)&(a)->f + (a)->f)
|
||||
#define ALT_ORIG_PTR(a) __ALT_PTR(a, orig_offset)
|
||||
#define ALT_REPL_PTR(a) __ALT_PTR(a, alt_offset)
|
||||
|
||||
int alternatives_applied;
|
||||
|
||||
struct alt_region {
|
||||
struct alt_instr *begin;
|
||||
struct alt_instr *end;
|
||||
|
|
@ -105,31 +107,52 @@ static u32 get_alt_insn(struct alt_instr *alt, u32 *insnptr, u32 *altinsnptr)
|
|||
return insn;
|
||||
}
|
||||
|
||||
static void patch_alternative(struct alt_instr *alt,
|
||||
__le32 *origptr, __le32 *updptr, int nr_inst)
|
||||
{
|
||||
__le32 *replptr;
|
||||
int i;
|
||||
|
||||
replptr = ALT_REPL_PTR(alt);
|
||||
for (i = 0; i < nr_inst; i++) {
|
||||
u32 insn;
|
||||
|
||||
insn = get_alt_insn(alt, origptr + i, replptr + i);
|
||||
updptr[i] = cpu_to_le32(insn);
|
||||
}
|
||||
}
|
||||
|
||||
static void __apply_alternatives(void *alt_region)
|
||||
{
|
||||
struct alt_instr *alt;
|
||||
struct alt_region *region = alt_region;
|
||||
u32 *origptr, *replptr;
|
||||
__le32 *origptr;
|
||||
alternative_cb_t alt_cb;
|
||||
|
||||
for (alt = region->begin; alt < region->end; alt++) {
|
||||
u32 insn;
|
||||
int i, nr_inst;
|
||||
int nr_inst;
|
||||
|
||||
if (!cpus_have_cap(alt->cpufeature))
|
||||
/* Use ARM64_CB_PATCH as an unconditional patch */
|
||||
if (alt->cpufeature < ARM64_CB_PATCH &&
|
||||
!cpus_have_cap(alt->cpufeature))
|
||||
continue;
|
||||
|
||||
BUG_ON(alt->alt_len != alt->orig_len);
|
||||
if (alt->cpufeature == ARM64_CB_PATCH)
|
||||
BUG_ON(alt->alt_len != 0);
|
||||
else
|
||||
BUG_ON(alt->alt_len != alt->orig_len);
|
||||
|
||||
pr_info_once("patching kernel code\n");
|
||||
|
||||
origptr = ALT_ORIG_PTR(alt);
|
||||
replptr = ALT_REPL_PTR(alt);
|
||||
nr_inst = alt->alt_len / sizeof(insn);
|
||||
nr_inst = alt->orig_len / AARCH64_INSN_SIZE;
|
||||
|
||||
for (i = 0; i < nr_inst; i++) {
|
||||
insn = get_alt_insn(alt, origptr + i, replptr + i);
|
||||
*(origptr + i) = cpu_to_le32(insn);
|
||||
}
|
||||
if (alt->cpufeature < ARM64_CB_PATCH)
|
||||
alt_cb = patch_alternative;
|
||||
else
|
||||
alt_cb = ALT_REPL_PTR(alt);
|
||||
|
||||
alt_cb(alt, origptr, origptr, nr_inst);
|
||||
|
||||
flush_icache_range((uintptr_t)origptr,
|
||||
(uintptr_t)(origptr + nr_inst));
|
||||
|
|
@ -142,7 +165,6 @@ static void __apply_alternatives(void *alt_region)
|
|||
*/
|
||||
static int __apply_alternatives_multi_stop(void *unused)
|
||||
{
|
||||
static int patched = 0;
|
||||
struct alt_region region = {
|
||||
.begin = (struct alt_instr *)__alt_instructions,
|
||||
.end = (struct alt_instr *)__alt_instructions_end,
|
||||
|
|
@ -150,14 +172,14 @@ static int __apply_alternatives_multi_stop(void *unused)
|
|||
|
||||
/* We always have a CPU 0 at this point (__init) */
|
||||
if (smp_processor_id()) {
|
||||
while (!READ_ONCE(patched))
|
||||
while (!READ_ONCE(alternatives_applied))
|
||||
cpu_relax();
|
||||
isb();
|
||||
} else {
|
||||
BUG_ON(patched);
|
||||
BUG_ON(alternatives_applied);
|
||||
__apply_alternatives(®ion);
|
||||
/* Barriers provided by the cache flushing */
|
||||
WRITE_ONCE(patched, 1);
|
||||
WRITE_ONCE(alternatives_applied, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -130,11 +130,13 @@ int main(void)
|
|||
BLANK();
|
||||
#ifdef CONFIG_KVM_ARM_HOST
|
||||
DEFINE(VCPU_CONTEXT, offsetof(struct kvm_vcpu, arch.ctxt));
|
||||
DEFINE(VCPU_WORKAROUND_FLAGS, offsetof(struct kvm_vcpu, arch.workaround_flags));
|
||||
DEFINE(CPU_GP_REGS, offsetof(struct kvm_cpu_context, gp_regs));
|
||||
DEFINE(CPU_USER_PT_REGS, offsetof(struct kvm_regs, regs));
|
||||
DEFINE(CPU_FP_REGS, offsetof(struct kvm_regs, fp_regs));
|
||||
DEFINE(VCPU_FPEXC32_EL2, offsetof(struct kvm_vcpu, arch.ctxt.sys_regs[FPEXC32_EL2]));
|
||||
DEFINE(VCPU_HOST_CONTEXT, offsetof(struct kvm_vcpu, arch.host_cpu_context));
|
||||
DEFINE(HOST_CONTEXT_VCPU, offsetof(struct kvm_cpu_context, __hyp_running_vcpu));
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_PM
|
||||
DEFINE(CPU_SUSPEND_SZ, sizeof(struct cpu_suspend_ctx));
|
||||
|
|
|
|||
|
|
@ -187,6 +187,178 @@ static int enable_smccc_arch_workaround_1(void *data)
|
|||
}
|
||||
#endif /* CONFIG_HARDEN_BRANCH_PREDICTOR */
|
||||
|
||||
#ifdef CONFIG_ARM64_SSBD
|
||||
DEFINE_PER_CPU_READ_MOSTLY(u64, arm64_ssbd_callback_required);
|
||||
|
||||
int ssbd_state __read_mostly = ARM64_SSBD_KERNEL;
|
||||
|
||||
static const struct ssbd_options {
|
||||
const char *str;
|
||||
int state;
|
||||
} ssbd_options[] = {
|
||||
{ "force-on", ARM64_SSBD_FORCE_ENABLE, },
|
||||
{ "force-off", ARM64_SSBD_FORCE_DISABLE, },
|
||||
{ "kernel", ARM64_SSBD_KERNEL, },
|
||||
};
|
||||
|
||||
static int __init ssbd_cfg(char *buf)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!buf || !buf[0])
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ssbd_options); i++) {
|
||||
int len = strlen(ssbd_options[i].str);
|
||||
|
||||
if (strncmp(buf, ssbd_options[i].str, len))
|
||||
continue;
|
||||
|
||||
ssbd_state = ssbd_options[i].state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
early_param("ssbd", ssbd_cfg);
|
||||
|
||||
void __init arm64_update_smccc_conduit(struct alt_instr *alt,
|
||||
__le32 *origptr, __le32 *updptr,
|
||||
int nr_inst)
|
||||
{
|
||||
u32 insn;
|
||||
|
||||
BUG_ON(nr_inst != 1);
|
||||
|
||||
switch (psci_ops.conduit) {
|
||||
case PSCI_CONDUIT_HVC:
|
||||
insn = aarch64_insn_get_hvc_value();
|
||||
break;
|
||||
case PSCI_CONDUIT_SMC:
|
||||
insn = aarch64_insn_get_smc_value();
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
*updptr = cpu_to_le32(insn);
|
||||
}
|
||||
|
||||
void __init arm64_enable_wa2_handling(struct alt_instr *alt,
|
||||
__le32 *origptr, __le32 *updptr,
|
||||
int nr_inst)
|
||||
{
|
||||
BUG_ON(nr_inst != 1);
|
||||
/*
|
||||
* Only allow mitigation on EL1 entry/exit and guest
|
||||
* ARCH_WORKAROUND_2 handling if the SSBD state allows it to
|
||||
* be flipped.
|
||||
*/
|
||||
if (arm64_get_ssbd_state() == ARM64_SSBD_KERNEL)
|
||||
*updptr = cpu_to_le32(aarch64_insn_gen_nop());
|
||||
}
|
||||
|
||||
void arm64_set_ssbd_mitigation(bool state)
|
||||
{
|
||||
switch (psci_ops.conduit) {
|
||||
case PSCI_CONDUIT_HVC:
|
||||
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
|
||||
break;
|
||||
|
||||
case PSCI_CONDUIT_SMC:
|
||||
arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
|
||||
int scope)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
bool required = true;
|
||||
s32 val;
|
||||
|
||||
WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
|
||||
|
||||
if (psci_ops.smccc_version == SMCCC_VERSION_1_0) {
|
||||
ssbd_state = ARM64_SSBD_UNKNOWN;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (psci_ops.conduit) {
|
||||
case PSCI_CONDUIT_HVC:
|
||||
arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
|
||||
ARM_SMCCC_ARCH_WORKAROUND_2, &res);
|
||||
break;
|
||||
|
||||
case PSCI_CONDUIT_SMC:
|
||||
arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
|
||||
ARM_SMCCC_ARCH_WORKAROUND_2, &res);
|
||||
break;
|
||||
|
||||
default:
|
||||
ssbd_state = ARM64_SSBD_UNKNOWN;
|
||||
return false;
|
||||
}
|
||||
|
||||
val = (s32)res.a0;
|
||||
|
||||
switch (val) {
|
||||
case SMCCC_RET_NOT_SUPPORTED:
|
||||
ssbd_state = ARM64_SSBD_UNKNOWN;
|
||||
return false;
|
||||
|
||||
case SMCCC_RET_NOT_REQUIRED:
|
||||
pr_info_once("%s mitigation not required\n", entry->desc);
|
||||
ssbd_state = ARM64_SSBD_MITIGATED;
|
||||
return false;
|
||||
|
||||
case SMCCC_RET_SUCCESS:
|
||||
required = true;
|
||||
break;
|
||||
|
||||
case 1: /* Mitigation not required on this CPU */
|
||||
required = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (ssbd_state) {
|
||||
case ARM64_SSBD_FORCE_DISABLE:
|
||||
pr_info_once("%s disabled from command-line\n", entry->desc);
|
||||
arm64_set_ssbd_mitigation(false);
|
||||
required = false;
|
||||
break;
|
||||
|
||||
case ARM64_SSBD_KERNEL:
|
||||
if (required) {
|
||||
__this_cpu_write(arm64_ssbd_callback_required, 1);
|
||||
arm64_set_ssbd_mitigation(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case ARM64_SSBD_FORCE_ENABLE:
|
||||
pr_info_once("%s forced from command-line\n", entry->desc);
|
||||
arm64_set_ssbd_mitigation(true);
|
||||
required = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
WARN_ON(1);
|
||||
break;
|
||||
}
|
||||
|
||||
return required;
|
||||
}
|
||||
#endif /* CONFIG_ARM64_SSBD */
|
||||
|
||||
#define MIDR_RANGE(model, min, max) \
|
||||
.def_scope = SCOPE_LOCAL_CPU, \
|
||||
.matches = is_affected_midr_range, \
|
||||
|
|
@ -309,6 +481,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
|
|||
MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2),
|
||||
.enable = enable_smccc_arch_workaround_1,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARM64_SSBD
|
||||
{
|
||||
.desc = "Speculative Store Bypass Disable",
|
||||
.def_scope = SCOPE_LOCAL_CPU,
|
||||
.capability = ARM64_SSBD,
|
||||
.matches = has_ssbd_mitigation,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue