Commit dc802f2b authored by Marc Zyngier's avatar Marc Zyngier Committed by Will Deacon
Browse files

arm64: Rework ARM_ERRATUM_1414080 handling



The current handling of erratum 1414080 has the side effect that
cntkctl_el1 can get changed for both 32 and 64bit tasks.

This isn't a problem so far, but if we ever need to mitigate another
of these errata on the 64bit side, we'd better keep the messing with
cntkctl_el1 local to 32bit tasks.

For that, make sure that on entering the kernel from a 32bit tasks,
userspace access to cntvct gets enabled, and disabled returning to
userspace, while it never gets changed for 64bit tasks.

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Reviewed-by: default avatarMark Rutland <mark.rutland@arm.com>
Link: https://lore.kernel.org/r/20200706163802.1836732-5-maz@kernel.org


[will: removed branch instructions per Mark's review comments]
Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent 4b661d61
Loading
Loading
Loading
Loading
+19 −15
Original line number Diff line number Diff line
@@ -167,6 +167,17 @@ alternative_cb_end
	stp	x28, x29, [sp, #16 * 14]

	.if	\el == 0
	.if	\regsize == 32
	// If we're returning from a 32-bit task on a system affected by
	// 1418040 then re-enable userspace access to the virtual counter.
#ifdef CONFIG_ARM64_ERRATUM_1418040
alternative_if ARM64_WORKAROUND_1418040
	mrs	x0, cntkctl_el1
	orr	x0, x0, #2	// ARCH_TIMER_USR_VCT_ACCESS_EN
	msr	cntkctl_el1, x0
alternative_else_nop_endif
#endif
	.endif
	clear_gp_regs
	mrs	x21, sp_el0
	ldr_this_cpu	tsk, __entry_task, x20
@@ -320,6 +331,14 @@ alternative_else_nop_endif
	tst	x22, #PSR_MODE32_BIT		// native task?
	b.eq	3f

#ifdef CONFIG_ARM64_ERRATUM_1418040
alternative_if ARM64_WORKAROUND_1418040
	mrs	x0, cntkctl_el1
	bic	x0, x0, #2			// ARCH_TIMER_USR_VCT_ACCESS_EN
	msr	cntkctl_el1, x0
alternative_else_nop_endif
#endif

#ifdef CONFIG_ARM64_ERRATUM_845719
alternative_if ARM64_WORKAROUND_845719
#ifdef CONFIG_PID_IN_CONTEXTIDR
@@ -331,21 +350,6 @@ alternative_if ARM64_WORKAROUND_845719
alternative_else_nop_endif
#endif
3:
#ifdef CONFIG_ARM64_ERRATUM_1418040
alternative_if_not ARM64_WORKAROUND_1418040
	b	4f
alternative_else_nop_endif
	/*
	 * if (x22.mode32 == cntkctl_el1.el0vcten)
	 *     cntkctl_el1.el0vcten = ~cntkctl_el1.el0vcten
	 */
	mrs	x1, cntkctl_el1
	eon	x0, x1, x22, lsr #3
	tbz	x0, #1, 4f
	eor	x1, x1, #2	// ARCH_TIMER_USR_VCT_ACCESS_EN
	msr	cntkctl_el1, x1
4:
#endif
	scs_save tsk, x0

	/* No kernel C function calls after this as user keys are set. */