Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 472e9506 authored by Will Deacon's avatar Will Deacon Committed by Greg Kroah-Hartman
Browse files

FROMLIST: arm64: entry: Add fake CPU feature for unmapping the kernel at EL0



Allow explicit disabling of the entry trampoline on the kernel command
line (kpti=off) by adding a fake CPU feature (ARM64_UNMAP_KERNEL_AT_EL0)
that can be used to toggle the alternative sequences in our entry code and
avoid use of the trampoline altogether if desired. This also allows us to
make use of a static key in arm64_kernel_unmapped_at_el0().

Reviewed-by: default avatarMark Rutland <mark.rutland@arm.com>
Tested-by: default avatarLaura Abbott <labbott@redhat.com>
Tested-by: default avatarShanker Donthineni <shankerd@codeaurora.org>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
(cherry picked from git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git


 commit ea1e3de85e94d711f63437c04624aa0e8de5c8b3)

Change-Id: I11cb874d12a7d0921f452c62b0752e0028a8e0a7
[ghackmann@google.com:
 - adjust context
 - apply cpucaps.h changes to cpufeature.h
 - replace cpus_have_const_cap() with cpus_have_cap()
 - tweak unmap_kernel_at_el0() declaration to match 4.4 APIs]
Signed-off-by: default avatarGreg Hackmann <ghackmann@google.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 59eae0db
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -35,8 +35,9 @@
#define ARM64_ALT_PAN_NOT_UAO			10
#define ARM64_HAS_VIRT_HOST_EXTN		11
#define ARM64_WORKAROUND_CAVIUM_27456		12
#define ARM64_UNMAP_KERNEL_AT_EL0		23

#define ARM64_NCAPS				13
#define ARM64_NCAPS				24

#ifndef __ASSEMBLY__

+2 −1
Original line number Diff line number Diff line
@@ -34,7 +34,8 @@ typedef struct {

static inline bool arm64_kernel_unmapped_at_el0(void)
{
	return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0);
	return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0) &&
	       cpus_have_cap(ARM64_UNMAP_KERNEL_AT_EL0);
}

extern void paging_init(void);
+39 −0
Original line number Diff line number Diff line
@@ -650,6 +650,39 @@ static bool has_no_hw_prefetch(const struct arm64_cpu_capabilities *entry)
	return MIDR_IS_CPU_MODEL_RANGE(midr, MIDR_THUNDERX, rv_min, rv_max);
}

#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */

static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry)
{
	/* Forced on command line? */
	if (__kpti_forced) {
		pr_info_once("kernel page table isolation forced %s by command line option\n",
			     __kpti_forced > 0 ? "ON" : "OFF");
		return __kpti_forced > 0;
	}

	/* Useful for KASLR robustness */
	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE))
		return true;

	return false;
}

static int __init parse_kpti(char *str)
{
	bool enabled;
	int ret = strtobool(str, &enabled);

	if (ret)
		return ret;

	__kpti_forced = enabled ? 1 : -1;
	return 0;
}
__setup("kpti=", parse_kpti);
#endif	/* CONFIG_UNMAP_KERNEL_AT_EL0 */

static const struct arm64_cpu_capabilities arm64_features[] = {
	{
		.desc = "GIC system register CPU interface",
@@ -702,6 +735,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
		.matches = cpufeature_pan_not_uao,
	},
#endif /* CONFIG_ARM64_PAN */
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
	{
		.capability = ARM64_UNMAP_KERNEL_AT_EL0,
		.matches = unmap_kernel_at_el0,
	},
#endif
	{},
};

+5 −4
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@
	.macro kernel_ventry, el, label, regsize = 64
	.align 7
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
alternative_if ARM64_UNMAP_KERNEL_AT_EL0
	.if	\el == 0
	.if	\regsize == 64
	mrs	x30, tpidrro_el0
@@ -82,6 +83,7 @@
	mov	x30, xzr
	.endif
	.endif
alternative_else_nop_endif
#endif

	sub	sp, sp, #S_FRAME_SIZE
@@ -287,10 +289,9 @@ alternative_else_nop_endif
	ldr	lr, [sp, #S_LR]
	add	sp, sp, #S_FRAME_SIZE		// restore sp

#ifndef CONFIG_UNMAP_KERNEL_AT_EL0
	eret
#else
	.if	\el == 0
alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
	bne	4f
	msr	far_el1, x30
	tramp_alias	x30, tramp_exit_native
@@ -298,10 +299,10 @@ alternative_else_nop_endif
4:
	tramp_alias	x30, tramp_exit_compat
	br	x30
#endif
	.else
	eret
	.endif
#endif
	.endm

	.macro	irq_stack_entry