Commit 4bc352ff authored by Shanker Donthineni's avatar Shanker Donthineni Committed by Will Deacon
Browse files

arm64: KVM: Use SMCCC_ARCH_WORKAROUND_1 for Falkor BP hardening



The function SMCCC_ARCH_WORKAROUND_1 was introduced as part of SMC
V1.1 Calling Convention to mitigate CVE-2017-5715. This patch uses
the standard call SMCCC_ARCH_WORKAROUND_1 for Falkor chips instead
of Silicon provider service ID 0xC2001700.

Cc: <stable@vger.kernel.org> # 4.14+
Signed-off-by: default avatarShanker Donthineni <shankerd@codeaurora.org>
[maz: reworked errata framework integration]
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent d8312a3f
Loading
Loading
Loading
Loading
+6 −7
Original line number Diff line number Diff line
@@ -43,13 +43,12 @@
#define ARM64_SVE				22
#define ARM64_UNMAP_KERNEL_AT_EL0		23
#define ARM64_HARDEN_BRANCH_PREDICTOR		24
#define ARM64_HARDEN_BP_POST_GUEST_EXIT		25
#define ARM64_HAS_RAS_EXTN			26
#define ARM64_WORKAROUND_843419			27
#define ARM64_HAS_CACHE_IDC			28
#define ARM64_HAS_CACHE_DIC			29
#define ARM64_HW_DBM				30
#define ARM64_HAS_RAS_EXTN			25
#define ARM64_WORKAROUND_843419			26
#define ARM64_HAS_CACHE_IDC			27
#define ARM64_HAS_CACHE_DIC			28
#define ARM64_HW_DBM				29

#define ARM64_NCAPS				31
#define ARM64_NCAPS				30

#endif /* __ASM_CPUCAPS_H */
+0 −2
Original line number Diff line number Diff line
@@ -71,8 +71,6 @@ extern u32 __kvm_get_mdcr_el2(void);

extern u32 __init_stage2_translation(void);

extern void __qcom_hyp_sanitize_btac_predictors(void);

#else /* __ASSEMBLY__ */

.macro get_host_ctxt reg, tmp
+0 −8
Original line number Diff line number Diff line
@@ -74,14 +74,6 @@ ENTRY(__bp_harden_hyp_vecs_end)

	.popsection

ENTRY(__qcom_hyp_sanitize_link_stack_start)
	stp     x29, x30, [sp, #-16]!
	.rept	16
	bl	. + 4
	.endr
	ldp	x29, x30, [sp], #16
ENTRY(__qcom_hyp_sanitize_link_stack_end)

.macro smccc_workaround_1 inst
	sub	sp, sp, #(8 * 4)
	stp	x2, x3, [sp, #(8 * 0)]
+19 −47
Original line number Diff line number Diff line
@@ -87,8 +87,6 @@ atomic_t arm64_el2_vector_last_slot = ATOMIC_INIT(-1);
DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);

#ifdef CONFIG_KVM
extern char __qcom_hyp_sanitize_link_stack_start[];
extern char __qcom_hyp_sanitize_link_stack_end[];
extern char __smccc_workaround_1_smc_start[];
extern char __smccc_workaround_1_smc_end[];
extern char __smccc_workaround_1_hvc_start[];
@@ -132,8 +130,6 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
	spin_unlock(&bp_lock);
}
#else
#define __qcom_hyp_sanitize_link_stack_start	NULL
#define __qcom_hyp_sanitize_link_stack_end	NULL
#define __smccc_workaround_1_smc_start		NULL
#define __smccc_workaround_1_smc_end		NULL
#define __smccc_workaround_1_hvc_start		NULL
@@ -178,12 +174,25 @@ static void call_hvc_arch_workaround_1(void)
	arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
}

static void qcom_link_stack_sanitization(void)
{
	u64 tmp;

	asm volatile("mov	%0, x30		\n"
		     ".rept	16		\n"
		     "bl	. + 4		\n"
		     ".endr			\n"
		     "mov	x30, %0		\n"
		     : "=&r" (tmp));
}

static void
enable_smccc_arch_workaround_1(const struct arm64_cpu_capabilities *entry)
{
	bp_hardening_cb_t cb;
	void *smccc_start, *smccc_end;
	struct arm_smccc_res res;
	u32 midr = read_cpuid_id();

	if (!entry->matches(entry, SCOPE_LOCAL_CPU))
		return;
@@ -216,30 +225,14 @@ enable_smccc_arch_workaround_1(const struct arm64_cpu_capabilities *entry)
		return;
	}

	if (((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR) ||
	    ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1))
		cb = qcom_link_stack_sanitization;

	install_bp_hardening_cb(entry, cb, smccc_start, smccc_end);

	return;
}

static void qcom_link_stack_sanitization(void)
{
	u64 tmp;

	asm volatile("mov	%0, x30		\n"
		     ".rept	16		\n"
		     "bl	. + 4		\n"
		     ".endr			\n"
		     "mov	x30, %0		\n"
		     : "=&r" (tmp));
}

static void
qcom_enable_link_stack_sanitization(const struct arm64_cpu_capabilities *entry)
{
	install_bp_hardening_cb(entry, qcom_link_stack_sanitization,
				__qcom_hyp_sanitize_link_stack_start,
				__qcom_hyp_sanitize_link_stack_end);
}
#endif	/* CONFIG_HARDEN_BRANCH_PREDICTOR */

#define CAP_MIDR_RANGE(model, v_min, r_min, v_max, r_max)	\
@@ -324,27 +317,11 @@ static const struct midr_range arm64_bp_harden_smccc_cpus[] = {
	MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
	MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN),
	MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2),
	{},
};

static const struct midr_range qcom_bp_harden_cpus[] = {
	MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1),
	MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR),
	{},
};

static const struct arm64_cpu_capabilities arm64_bp_harden_list[] = {
	{
		CAP_MIDR_RANGE_LIST(arm64_bp_harden_smccc_cpus),
		.cpu_enable = enable_smccc_arch_workaround_1,
	},
	{
		CAP_MIDR_RANGE_LIST(qcom_bp_harden_cpus),
		.cpu_enable = qcom_enable_link_stack_sanitization,
	},
	{},
};

#endif

#ifndef ERRATA_MIDR_ALL_VERSIONS
@@ -495,13 +472,8 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
	{
		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
		.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
		.matches = multi_entry_cap_matches,
		.cpu_enable = multi_entry_cap_cpu_enable,
		.match_list = arm64_bp_harden_list,
	},
	{
		.capability = ARM64_HARDEN_BP_POST_GUEST_EXIT,
		ERRATA_MIDR_RANGE_LIST(qcom_bp_harden_cpus),
		.cpu_enable = enable_smccc_arch_workaround_1,
		ERRATA_MIDR_RANGE_LIST(arm64_bp_harden_smccc_cpus),
	},
#endif
#ifdef CONFIG_HARDEN_EL2_VECTORS
+0 −12
Original line number Diff line number Diff line
@@ -209,15 +209,3 @@ alternative_endif

	eret
ENDPROC(__fpsimd_guest_restore)

ENTRY(__qcom_hyp_sanitize_btac_predictors)
	/**
	 * Call SMC64 with Silicon provider serviceID 23<<8 (0xc2001700)
	 * 0xC2000000-0xC200FFFF: assigned to SiP Service Calls
	 * b15-b0: contains SiP functionID
	 */
	movz    x0, #0x1700
	movk    x0, #0xc200, lsl #16
	smc     #0
	ret
ENDPROC(__qcom_hyp_sanitize_btac_predictors)
Loading