Commit dc2286f3 authored by Marc Zyngier's avatar Marc Zyngier
Browse files

Merge branch 'kvm-arm64/vector-rework' into kvmarm-master/next



Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parents 6e5d8c71 4f6a36fe
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -100,7 +100,7 @@ hypervisor maps kernel pages in EL2 at a fixed (and potentially
random) offset from the linear mapping. See the kern_hyp_va macro and
random) offset from the linear mapping. See the kern_hyp_va macro and
kvm_update_va_mask function for more details. MMIO devices such as
kvm_update_va_mask function for more details. MMIO devices such as
GICv2 gets mapped next to the HYP idmap page, as do vectors when
GICv2 gets mapped next to the HYP idmap page, as do vectors when
ARM64_HARDEN_EL2_VECTORS is selected for particular CPUs.
ARM64_SPECTRE_V3A is enabled for particular CPUs.


When using KVM with the Virtualization Host Extensions, no additional
When using KVM with the Virtualization Host Extensions, no additional
mappings are created, since the host kernel runs directly in EL2.
mappings are created, since the host kernel runs directly in EL2.
+1 −1
Original line number Original line Diff line number Diff line
@@ -21,7 +21,7 @@
#define ARM64_HAS_VIRT_HOST_EXTN		11
#define ARM64_HAS_VIRT_HOST_EXTN		11
#define ARM64_WORKAROUND_CAVIUM_27456		12
#define ARM64_WORKAROUND_CAVIUM_27456		12
#define ARM64_HAS_32BIT_EL0			13
#define ARM64_HAS_32BIT_EL0			13
#define ARM64_HARDEN_EL2_VECTORS		14
#define ARM64_SPECTRE_V3A			14
#define ARM64_HAS_CNP				15
#define ARM64_HAS_CNP				15
#define ARM64_HAS_NO_FPSIMD			16
#define ARM64_HAS_NO_FPSIMD			16
#define ARM64_WORKAROUND_REPEAT_TLBI		17
#define ARM64_WORKAROUND_REPEAT_TLBI		17
+0 −5
Original line number Original line Diff line number Diff line
@@ -34,8 +34,6 @@
 */
 */
#define KVM_VECTOR_PREAMBLE	(2 * AARCH64_INSN_SIZE)
#define KVM_VECTOR_PREAMBLE	(2 * AARCH64_INSN_SIZE)


#define __SMCCC_WORKAROUND_1_SMC_SZ 36

#define KVM_HOST_SMCCC_ID(id)						\
#define KVM_HOST_SMCCC_ID(id)						\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
			   ARM_SMCCC_SMC_64,				\
			   ARM_SMCCC_SMC_64,				\
@@ -175,7 +173,6 @@ extern unsigned long kvm_arm_hyp_percpu_base[NR_CPUS];
DECLARE_KVM_NVHE_SYM(__per_cpu_start);
DECLARE_KVM_NVHE_SYM(__per_cpu_start);
DECLARE_KVM_NVHE_SYM(__per_cpu_end);
DECLARE_KVM_NVHE_SYM(__per_cpu_end);


extern atomic_t arm64_el2_vector_last_slot;
DECLARE_KVM_HYP_SYM(__bp_harden_hyp_vecs);
DECLARE_KVM_HYP_SYM(__bp_harden_hyp_vecs);
#define __bp_harden_hyp_vecs	CHOOSE_HYP_SYM(__bp_harden_hyp_vecs)
#define __bp_harden_hyp_vecs	CHOOSE_HYP_SYM(__bp_harden_hyp_vecs)


@@ -196,8 +193,6 @@ extern void __vgic_v3_init_lrs(void);


extern u32 __kvm_get_mdcr_el2(void);
extern u32 __kvm_get_mdcr_el2(void);


extern char __smccc_workaround_1_smc[__SMCCC_WORKAROUND_1_SMC_SZ];

/*
/*
 * Obtain the PC-relative address of a kernel symbol
 * Obtain the PC-relative address of a kernel symbol
 * s: symbol
 * s: symbol
+0 −46
Original line number Original line Diff line number Diff line
@@ -248,52 +248,6 @@ static inline int kvm_write_guest_lock(struct kvm *kvm, gpa_t gpa,
	return ret;
	return ret;
}
}


/*
 * EL2 vectors can be mapped and rerouted in a number of ways,
 * depending on the kernel configuration and CPU present:
 *
 * - If the CPU is affected by Spectre-v2, the hardening sequence is
 *   placed in one of the vector slots, which is executed before jumping
 *   to the real vectors.
 *
 * - If the CPU also has the ARM64_HARDEN_EL2_VECTORS cap, the slot
 *   containing the hardening sequence is mapped next to the idmap page,
 *   and executed before jumping to the real vectors.
 *
 * - If the CPU only has the ARM64_HARDEN_EL2_VECTORS cap, then an
 *   empty slot is selected, mapped next to the idmap page, and
 *   executed before jumping to the real vectors.
 *
 * Note that ARM64_HARDEN_EL2_VECTORS is somewhat incompatible with
 * VHE, as we don't have hypervisor-specific mappings. If the system
 * is VHE and yet selects this capability, it will be ignored.
 */
extern void *__kvm_bp_vect_base;
extern int __kvm_harden_el2_vector_slot;

static inline void *kvm_get_hyp_vector(void)
{
	struct bp_hardening_data *data = arm64_get_bp_hardening_data();
	void *vect = kern_hyp_va(kvm_ksym_ref(__kvm_hyp_vector));
	int slot = -1;

	if (cpus_have_const_cap(ARM64_SPECTRE_V2) && data->fn) {
		vect = kern_hyp_va(kvm_ksym_ref(__bp_harden_hyp_vecs));
		slot = data->hyp_vectors_slot;
	}

	if (this_cpu_has_cap(ARM64_HARDEN_EL2_VECTORS) && !has_vhe()) {
		vect = __kvm_bp_vect_base;
		if (slot == -1)
			slot = __kvm_harden_el2_vector_slot;
	}

	if (slot != -1)
		vect += slot * SZ_2K;

	return vect;
}

#define kvm_phys_to_vttbr(addr)		phys_to_ttbr(addr)
#define kvm_phys_to_vttbr(addr)		phys_to_ttbr(addr)


static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu)
static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu)
+0 −29
Original line number Original line Diff line number Diff line
@@ -12,9 +12,6 @@
#define USER_ASID_FLAG	(UL(1) << USER_ASID_BIT)
#define USER_ASID_FLAG	(UL(1) << USER_ASID_BIT)
#define TTBR_ASID_MASK	(UL(0xffff) << 48)
#define TTBR_ASID_MASK	(UL(0xffff) << 48)


#define BP_HARDEN_EL2_SLOTS 4
#define __BP_HARDEN_HYP_VECS_SZ (BP_HARDEN_EL2_SLOTS * SZ_2K)

#ifndef __ASSEMBLY__
#ifndef __ASSEMBLY__


#include <linux/refcount.h>
#include <linux/refcount.h>
@@ -41,32 +38,6 @@ static inline bool arm64_kernel_unmapped_at_el0(void)
	return cpus_have_const_cap(ARM64_UNMAP_KERNEL_AT_EL0);
	return cpus_have_const_cap(ARM64_UNMAP_KERNEL_AT_EL0);
}
}


typedef void (*bp_hardening_cb_t)(void);

struct bp_hardening_data {
	int			hyp_vectors_slot;
	bp_hardening_cb_t	fn;
};

DECLARE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);

static inline struct bp_hardening_data *arm64_get_bp_hardening_data(void)
{
	return this_cpu_ptr(&bp_hardening_data);
}

static inline void arm64_apply_bp_hardening(void)
{
	struct bp_hardening_data *d;

	if (!cpus_have_const_cap(ARM64_SPECTRE_V2))
		return;

	d = arm64_get_bp_hardening_data();
	if (d->fn)
		d->fn();
}

extern void arm64_memblock_init(void);
extern void arm64_memblock_init(void);
extern void paging_init(void);
extern void paging_init(void);
extern void bootmem_init(void);
extern void bootmem_init(void);
Loading