Commit 3f35db4e authored by Will Deacon's avatar Will Deacon
Browse files

Merge branch 'for-next/cpufeature' into for-next/core

* for-next/cpufeature:
  arm64: Align boot cpucap handling with system cpucap handling
  arm64: Cleanup system cpucap handling
  arm64: Kconfig: drop KAISER reference from KPTI option description
  arm64: mm: Only map KPTI trampoline if it is going to be used
  arm64: Get rid of ARM64_HAS_NO_HW_PREFETCH
parents 2cc14f52 eb15d707
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1549,7 +1549,7 @@ config ARCH_FORCE_MAX_ORDER
	  Don't change if unsure.

config UNMAP_KERNEL_AT_EL0
	bool "Unmap kernel when running in userspace (aka \"KAISER\")" if EXPERT
	bool "Unmap kernel when running in userspace (KPTI)" if EXPERT
	default y
	help
	  Speculation attacks against some high-performance processors can
+1 −0
Original line number Diff line number Diff line
@@ -617,6 +617,7 @@ static inline bool id_aa64pfr1_mte(u64 pfr1)
	return val >= ID_AA64PFR1_EL1_MTE_MTE2;
}

void __init setup_boot_cpu_features(void);
void __init setup_system_features(void);
void __init setup_user_features(void);

+57 −62
Original line number Diff line number Diff line
@@ -1081,25 +1081,6 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)

	if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
		init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid);

	/*
	 * Initialize the indirect array of CPU capabilities pointers before we
	 * handle the boot CPU below.
	 */
	init_cpucap_indirect_list();

	/*
	 * Detect broken pseudo-NMI. Must be called _before_ the call to
	 * setup_boot_cpu_capabilities() since it interacts with
	 * can_use_gic_priorities().
	 */
	detect_system_supports_pseudo_nmi();

	/*
	 * Detect and enable early CPU capabilities based on the boot CPU,
	 * after we have initialised the CPU feature infrastructure.
	 */
	setup_boot_cpu_capabilities();
}

static void update_cpu_ftr_reg(struct arm64_ftr_reg *reg, u64 new)
@@ -1584,16 +1565,6 @@ static bool has_useable_gicv3_cpuif(const struct arm64_cpu_capabilities *entry,
	return has_sre;
}

static bool has_no_hw_prefetch(const struct arm64_cpu_capabilities *entry, int __unused)
{
	u32 midr = read_cpuid_id();

	/* Cavium ThunderX pass 1.x and 2.x */
	return midr_is_cpu_model_range(midr, MIDR_THUNDERX,
		MIDR_CPU_VAR_REV(0, 0),
		MIDR_CPU_VAR_REV(1, MIDR_REVISION_MASK));
}

static bool has_cache_idc(const struct arm64_cpu_capabilities *entry,
			  int scope)
{
@@ -2321,12 +2292,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
		ARM64_CPUID_FIELDS(ID_AA64ISAR0_EL1, ATOMIC, IMP)
	},
#endif /* CONFIG_ARM64_LSE_ATOMICS */
	{
		.desc = "Software prefetching using PRFM",
		.capability = ARM64_HAS_NO_HW_PREFETCH,
		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
		.matches = has_no_hw_prefetch,
	},
	{
		.desc = "Virtualization Host Extensions",
		.capability = ARM64_HAS_VIRT_HOST_EXTN,
@@ -3271,14 +3236,6 @@ void check_local_cpu_capabilities(void)
		verify_local_cpu_capabilities();
}

static void __init setup_boot_cpu_capabilities(void)
{
	/* Detect capabilities with either SCOPE_BOOT_CPU or SCOPE_LOCAL_CPU */
	update_cpu_capabilities(SCOPE_BOOT_CPU | SCOPE_LOCAL_CPU);
	/* Enable the SCOPE_BOOT_CPU capabilities alone right away */
	enable_cpu_capabilities(SCOPE_BOOT_CPU);
}

bool this_cpu_has_cap(unsigned int n)
{
	if (!WARN_ON(preemptible()) && n < ARM64_NCAPS) {
@@ -3334,37 +3291,52 @@ unsigned long cpu_get_elf_hwcap2(void)
	return elf_hwcap[1];
}

void __init setup_system_features(void)
static void __init setup_boot_cpu_capabilities(void)
{
	int i;
	/*
	 * The system-wide safe feature feature register values have been
	 * finalized. Finalize and log the available system capabilities.
	 * The boot CPU's feature register values have been recorded. Detect
	 * boot cpucaps and local cpucaps for the boot CPU, then enable and
	 * patch alternatives for the available boot cpucaps.
	 */
	update_cpu_capabilities(SCOPE_SYSTEM);
	if (IS_ENABLED(CONFIG_ARM64_SW_TTBR0_PAN) &&
	    !cpus_have_cap(ARM64_HAS_PAN))
		pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n");
	update_cpu_capabilities(SCOPE_BOOT_CPU | SCOPE_LOCAL_CPU);
	enable_cpu_capabilities(SCOPE_BOOT_CPU);
	apply_boot_alternatives();
}

void __init setup_boot_cpu_features(void)
{
	/*
	 * Enable all the available capabilities which have not been enabled
	 * already.
	 * Initialize the indirect array of CPU capabilities pointers before we
	 * handle the boot CPU.
	 */
	enable_cpu_capabilities(SCOPE_ALL & ~SCOPE_BOOT_CPU);
	init_cpucap_indirect_list();

	kpti_install_ng_mappings();
	/*
	 * Detect broken pseudo-NMI. Must be called _before_ the call to
	 * setup_boot_cpu_capabilities() since it interacts with
	 * can_use_gic_priorities().
	 */
	detect_system_supports_pseudo_nmi();

	sve_setup();
	sme_setup();
	setup_boot_cpu_capabilities();
}

static void __init setup_system_capabilities(void)
{
	/*
	 * Check for sane CTR_EL0.CWG value.
	 * The system-wide safe feature register values have been finalized.
	 * Detect, enable, and patch alternatives for the available system
	 * cpucaps.
	 */
	if (!cache_type_cwg())
		pr_warn("No Cache Writeback Granule information, assuming %d\n",
			ARCH_DMA_MINALIGN);
	update_cpu_capabilities(SCOPE_SYSTEM);
	enable_cpu_capabilities(SCOPE_ALL & ~SCOPE_BOOT_CPU);
	apply_alternatives_all();

	for (i = 0; i < ARM64_NCAPS; i++) {
	/*
	 * Log any cpucaps with a cpumask as these aren't logged by
	 * update_cpu_capabilities().
	 */
	for (int i = 0; i < ARM64_NCAPS; i++) {
		const struct arm64_cpu_capabilities *caps = cpucap_ptrs[i];

		if (caps && caps->cpus && caps->desc &&
@@ -3372,6 +3344,29 @@ void __init setup_system_features(void)
			pr_info("detected: %s on CPU%*pbl\n",
				caps->desc, cpumask_pr_args(caps->cpus));
	}

	/*
	 * TTBR0 PAN doesn't have its own cpucap, so log it manually.
	 */
	if (system_uses_ttbr0_pan())
		pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n");
}

void __init setup_system_features(void)
{
	setup_system_capabilities();

	kpti_install_ng_mappings();

	sve_setup();
	sme_setup();

	/*
	 * Check for sane CTR_EL0.CWG value.
	 */
	if (!cache_type_cwg())
		pr_warn("No Cache Writeback Granule information, assuming %d\n",
			ARCH_DMA_MINALIGN);
}

void __init setup_user_features(void)
+2 −2
Original line number Diff line number Diff line
@@ -1171,7 +1171,7 @@ void __init sve_setup(void)
	unsigned long b;
	int max_bit;

	if (!cpus_have_cap(ARM64_SVE))
	if (!system_supports_sve())
		return;

	/*
@@ -1301,7 +1301,7 @@ void __init sme_setup(void)
	struct vl_info *info = &vl_info[ARM64_VEC_SME];
	int min_bit, max_bit;

	if (!cpus_have_cap(ARM64_SME))
	if (!system_supports_sme())
		return;

	/*
+3 −9
Original line number Diff line number Diff line
@@ -439,9 +439,8 @@ static void __init hyp_mode_check(void)
void __init smp_cpus_done(unsigned int max_cpus)
{
	pr_info("SMP: Total of %d processors activated.\n", num_online_cpus());
	setup_system_features();
	hyp_mode_check();
	apply_alternatives_all();
	setup_system_features();
	setup_user_features();
	mark_linear_text_alias_ro();
}
@@ -454,14 +453,9 @@ void __init smp_prepare_boot_cpu(void)
	 * freed shortly, so we must move over to the runtime per-cpu area.
	 */
	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
	cpuinfo_store_boot_cpu();

	/*
	 * We now know enough about the boot CPU to apply the
	 * alternatives that cannot wait until interrupt handling
	 * and/or scheduling is enabled.
	 */
	apply_boot_alternatives();
	cpuinfo_store_boot_cpu();
	setup_boot_cpu_features();

	/* Conditionally switch to GIC PMR for interrupt masking */
	if (system_uses_irq_prio_masking())
Loading