Commit c20c4a08 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull arm64 fixes from Will Deacon:
 "Here are another three arm64 fixes for 5.6, all pretty minor. Main
  thing is fixing a silly bug in the fsl_imx8_ddr PMU driver where we
  would zero the counters when disabling them.

   - Fix misreporting of ASID limit when KPTI is enabled

   - Fix busted NULL pointer checks for GICC structure in ACPI PMU code

   - Avoid nobbling the "fsl_imx8_ddr" PMU counters when disabling them"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  arm64: context: Fix ASID limit in boot messages
  drivers/perf: arm_pmu_acpi: Fix incorrect checking of gicc pointer
  drivers/perf: fsl_imx8_ddr: Correct the CLEAR bit definition
parents aeb542a1 9abd515a
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -260,14 +260,26 @@ asmlinkage void post_ttbr_update_workaround(void)
			CONFIG_CAVIUM_ERRATUM_27456));
}

static int asids_init(void)
static int asids_update_limit(void)
{
	asid_bits = get_cpu_asid_bits();
	unsigned long num_available_asids = NUM_USER_ASIDS;

	if (arm64_kernel_unmapped_at_el0())
		num_available_asids /= 2;
	/*
	 * Expect allocation after rollover to fail if we don't have at least
	 * one more ASID than CPUs. ASID #0 is reserved for init_mm.
	 */
	WARN_ON(NUM_USER_ASIDS - 1 <= num_possible_cpus());
	WARN_ON(num_available_asids - 1 <= num_possible_cpus());
	pr_info("ASID allocator initialised with %lu entries\n",
		num_available_asids);
	return 0;
}
arch_initcall(asids_update_limit);

static int asids_init(void)
{
	asid_bits = get_cpu_asid_bits();
	atomic64_set(&asid_generation, ASID_FIRST_VERSION);
	asid_map = kcalloc(BITS_TO_LONGS(NUM_USER_ASIDS), sizeof(*asid_map),
			   GFP_KERNEL);
@@ -282,8 +294,6 @@ static int asids_init(void)
	 */
	if (IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0))
		set_kpti_asid_bits();

	pr_info("ASID allocator initialised with %lu entries\n", NUM_USER_ASIDS);
	return 0;
}
early_initcall(asids_init);
+2 −5
Original line number Diff line number Diff line
@@ -24,8 +24,6 @@ static int arm_pmu_acpi_register_irq(int cpu)
	int gsi, trigger;

	gicc = acpi_cpu_get_madt_gicc(cpu);
	if (WARN_ON(!gicc))
		return -EINVAL;

	gsi = gicc->performance_interrupt;

@@ -64,10 +62,9 @@ static void arm_pmu_acpi_unregister_irq(int cpu)
	int gsi;

	gicc = acpi_cpu_get_madt_gicc(cpu);
	if (!gicc)
		return;

	gsi = gicc->performance_interrupt;
	if (gsi)
		acpi_unregister_gsi(gsi);
}

+6 −4
Original line number Diff line number Diff line
@@ -388,9 +388,10 @@ static void ddr_perf_counter_enable(struct ddr_pmu *pmu, int config,

	if (enable) {
		/*
		 * must disable first, then enable again
		 * otherwise, cycle counter will not work
		 * if previous state is enabled.
		 * cycle counter is special which should firstly write 0 then
		 * write 1 into CLEAR bit to clear it. Other counters only
		 * need write 0 into CLEAR bit and it turns out to be 1 by
		 * hardware. Below enable flow is harmless for all counters.
		 */
		writel(0, pmu->base + reg);
		val = CNTL_EN | CNTL_CLEAR;
@@ -398,7 +399,8 @@ static void ddr_perf_counter_enable(struct ddr_pmu *pmu, int config,
		writel(val, pmu->base + reg);
	} else {
		/* Disable counter */
		writel(0, pmu->base + reg);
		val = readl_relaxed(pmu->base + reg) & CNTL_EN_MASK;
		writel(val, pmu->base + reg);
	}
}