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

Merge remote-tracking branch 'arm64/for-next/vhe-only' into kvmarm-master/next



Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parents e6290032 2d726d0d
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -2279,8 +2279,7 @@
				   state is kept private from the host.
				   Not valid if the kernel is running in EL2.

			Defaults to VHE/nVHE based on hardware support and
			the value of CONFIG_ARM64_VHE.
			Defaults to VHE/nVHE based on hardware support.

	kvm-arm.vgic_v3_group0_trap=
			[KVM,ARM] Trap guest accesses to GICv3 group-0
+0 −13
Original line number Diff line number Diff line
@@ -1416,19 +1416,6 @@ config ARM64_USE_LSE_ATOMICS
	  built with binutils >= 2.25 in order for the new instructions
	  to be used.

config ARM64_VHE
	bool "Enable support for Virtualization Host Extensions (VHE)"
	default y
	help
	  Virtualization Host Extensions (VHE) allow the kernel to run
	  directly at EL2 (instead of EL1) on processors that support
	  it. This leads to better performance for KVM, as they reduce
	  the cost of the world switch.

	  Selecting this option allows the VHE feature to be detected
	  at runtime, and does not affect processors that do not
	  implement this feature.

endmenu

menu "ARMv8.2 architectural features"
+17 −0
Original line number Diff line number Diff line
@@ -63,6 +63,23 @@ struct arm64_ftr_bits {
	s64		safe_val; /* safe value for FTR_EXACT features */
};

/*
 * Describe the early feature override to the core override code:
 *
 * @val			Values that are to be merged into the final
 *			sanitised value of the register. Only the bitfields
 *			set to 1 in @mask are valid
 * @mask		Mask of the features that are overridden by @val
 *
 * A @mask field set to full-1 indicates that the corresponding field
 * in @val is a valid override.
 *
 * A @mask field set to full-0 with the corresponding @val field set
 * to full-0 denotes that this field has no override
 *
 * A @mask field set to full-0 with the corresponding @val field set
 * to full-1 denotes thath this field has an invalid override.
 */
struct arm64_ftr_override {
	u64		val;
	u64		mask;
+6 −4
Original line number Diff line number Diff line
@@ -808,6 +808,12 @@ static void __init init_cpu_ftr_reg(u32 sys_reg, u64 new)
					reg->name,
					ftrp->shift + ftrp->width - 1,
					ftrp->shift, str, tmp);
		} else if ((ftr_mask & reg->override->val) == ftr_mask) {
			reg->override->val &= ~ftr_mask;
			pr_warn("%s[%d:%d]: impossible override, ignored\n",
				reg->name,
				ftrp->shift + ftrp->width - 1,
				ftrp->shift);
		}

		val = arm64_ftr_set_value(ftrp, val, ftr_new);
@@ -1616,7 +1622,6 @@ int get_cpu_with_amu_feat(void)
}
#endif

#ifdef CONFIG_ARM64_VHE
static bool runs_at_el2(const struct arm64_cpu_capabilities *entry, int __unused)
{
	return is_kernel_in_hyp_mode();
@@ -1635,7 +1640,6 @@ static void cpu_copy_el2regs(const struct arm64_cpu_capabilities *__unused)
	if (!alternative_is_applied(ARM64_HAS_VIRT_HOST_EXTN))
		write_sysreg(read_sysreg(tpidr_el1), tpidr_el2);
}
#endif

static void cpu_has_fwb(const struct arm64_cpu_capabilities *__unused)
{
@@ -1838,7 +1842,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
		.matches = has_no_hw_prefetch,
	},
#ifdef CONFIG_ARM64_VHE
	{
		.desc = "Virtualization Host Extensions",
		.capability = ARM64_HAS_VIRT_HOST_EXTN,
@@ -1846,7 +1849,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
		.matches = runs_at_el2,
		.cpu_enable = cpu_copy_el2regs,
	},
#endif	/* CONFIG_ARM64_VHE */
	{
		.desc = "32-bit EL0 Support",
		.capability = ARM64_HAS_32BIT_EL0,
+36 −3
Original line number Diff line number Diff line
@@ -477,14 +477,13 @@ EXPORT_SYMBOL(kimage_vaddr)
 * booted in EL1 or EL2 respectively.
 */
SYM_FUNC_START(init_kernel_el)
	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
	msr	sctlr_el1, x0

	mrs	x0, CurrentEL
	cmp	x0, #CurrentEL_EL2
	b.eq	init_el2

SYM_INNER_LABEL(init_el1, SYM_L_LOCAL)
	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
	msr	sctlr_el1, x0
	isb
	mov_q	x0, INIT_PSTATE_EL1
	msr	spsr_el1, x0
@@ -504,9 +503,43 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
	msr	vbar_el2, x0
	isb

	/*
	 * Fruity CPUs seem to have HCR_EL2.E2H set to RES1,
	 * making it impossible to start in nVHE mode. Is that
	 * compliant with the architecture? Absolutely not!
	 */
	mrs	x0, hcr_el2
	and	x0, x0, #HCR_E2H
	cbz	x0, 1f

	/* Switching to VHE requires a sane SCTLR_EL1 as a start */
	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
	msr_s	SYS_SCTLR_EL12, x0

	/*
	 * Force an eret into a helper "function", and let it return
	 * to our original caller... This makes sure that we have
	 * initialised the basic PSTATE state.
	 */
	mov	x0, #INIT_PSTATE_EL2
	msr	spsr_el1, x0
	adr	x0, __cpu_stick_to_vhe
	msr	elr_el1, x0
	eret

1:
	mov_q	x0, INIT_SCTLR_EL1_MMU_OFF
	msr	sctlr_el1, x0

	msr	elr_el2, lr
	mov	w0, #BOOT_CPU_MODE_EL2
	eret

__cpu_stick_to_vhe:
	mov	x0, #HVC_VHE_RESTART
	hvc	#0
	mov	x0, #BOOT_CPU_MODE_EL2
	ret
SYM_FUNC_END(init_kernel_el)

/*
Loading