Commit 971199ad authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull arm64 fixes from Will Deacon:

 - Preserve old 'tt_core' UAPI for Hisilicon L3C PMU driver

 - Ensure linear alias of kprobes instruction page is not writable

 - Fix kernel stack unwinding from BPF

 - Fix build warnings from the Fujitsu uncore PMU documentation

 - Fix hang with deferred 'struct page' initialisation and MTE

 - Consolidate KPTI page-table re-writing code

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  arm64: mte: Do not flag the zero page as PG_mte_tagged
  docs: perf: Fujitsu: Fix htmldocs build warnings and errors
  arm64: mm: Move KPTI helpers to mmu.c
  tracing: Fix the bug where bpf_get_stackid returns -EFAULT on the ARM64
  arm64: kprobes: call set_memory_rox() for kprobe page
  drivers/perf: hisi: Add tt_core_deprecated for compatibility
parents 22153362 f620d66a
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -15,15 +15,19 @@ The driver provides a description of its available events and configuration
options in sysfs, see /sys/bus/event_sources/devices/mac_iod<iod>_mac<mac>_ch<ch>/
and /sys/bus/event_sources/devices/pci_iod<iod>_pci<pci>/.
This driver exports:

- formats, used by perf user space and other tools to configure events
- events, used by perf user space and other tools to create events
  symbolically, e.g.:
  symbolically, e.g.::

    perf stat -a -e mac_iod0_mac0_ch0/event=0x21/ ls
    perf stat -a -e pci_iod0_pci0/event=0x24/ ls

- cpumask, used by perf user space and other tools to know on which CPUs
  to open the events

This driver supports the following events for MAC:

- cycles
  This event counts MAC cycles at MAC frequency.
- read-count
@@ -77,6 +81,7 @@ Examples for use with perf::
  perf stat -e mac_iod0_mac0_ch0/ea-mac/ ls

And, this driver supports the following events for PCI:

- pci-port0-cycles
  This event counts PCI cycles at PCI frequency in port0.
- pci-port0-read-count
+4 −0
Original line number Diff line number Diff line
@@ -66,6 +66,10 @@ specified as a bitmap::

This will only count the operations from core/thread 0 and 1 in this cluster.

User should not use tt_core_deprecated to specify the core/thread filtering.
This option is provided for backward compatiblility and only support 8bit
which may not cover all the core/thread sharing L3C.

2. Tracetag allow the user to chose to count only read, write or atomic
operations via the tt_req parameeter in perf. The default value counts all
operations. tt_req is 3bits, 3'b100 represents read operations, 3'b101
+1 −0
Original line number Diff line number Diff line
@@ -153,6 +153,7 @@ ftrace_partial_regs(const struct ftrace_regs *fregs, struct pt_regs *regs)
	regs->pc = afregs->pc;
	regs->regs[29] = afregs->fp;
	regs->regs[30] = afregs->lr;
	regs->pstate = PSR_MODE_EL1h;
	return regs;
}

+6 −1
Original line number Diff line number Diff line
@@ -79,7 +79,6 @@ extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
extern void *fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot);
extern void mark_linear_text_alias_ro(void);
extern int split_kernel_leaf_mapping(unsigned long start, unsigned long end);
extern void init_idmap_kpti_bbml2_flag(void);
extern void linear_map_maybe_split_to_ptes(void);

/*
@@ -107,5 +106,11 @@ static inline bool kaslr_requires_kpti(void)
	return true;
}

#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
void kpti_install_ng_mappings(void);
#else
static inline void kpti_install_ng_mappings(void) {}
#endif

#endif	/* !__ASSEMBLY__ */
#endif
+7 −101
Original line number Diff line number Diff line
@@ -1941,104 +1941,6 @@ static bool has_pmuv3(const struct arm64_cpu_capabilities *entry, int scope)
}
#endif

#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
#define KPTI_NG_TEMP_VA		(-(1UL << PMD_SHIFT))

extern
void create_kpti_ng_temp_pgd(pgd_t *pgdir, phys_addr_t phys, unsigned long virt,
			     phys_addr_t size, pgprot_t prot,
			     phys_addr_t (*pgtable_alloc)(enum pgtable_type), int flags);

static phys_addr_t __initdata kpti_ng_temp_alloc;

static phys_addr_t __init kpti_ng_pgd_alloc(enum pgtable_type type)
{
	kpti_ng_temp_alloc -= PAGE_SIZE;
	return kpti_ng_temp_alloc;
}

static int __init __kpti_install_ng_mappings(void *__unused)
{
	typedef void (kpti_remap_fn)(int, int, phys_addr_t, unsigned long);
	extern kpti_remap_fn idmap_kpti_install_ng_mappings;
	kpti_remap_fn *remap_fn;

	int cpu = smp_processor_id();
	int levels = CONFIG_PGTABLE_LEVELS;
	int order = order_base_2(levels);
	u64 kpti_ng_temp_pgd_pa = 0;
	pgd_t *kpti_ng_temp_pgd;
	u64 alloc = 0;

	if (levels == 5 && !pgtable_l5_enabled())
		levels = 4;
	else if (levels == 4 && !pgtable_l4_enabled())
		levels = 3;

	remap_fn = (void *)__pa_symbol(idmap_kpti_install_ng_mappings);

	if (!cpu) {
		alloc = __get_free_pages(GFP_ATOMIC | __GFP_ZERO, order);
		kpti_ng_temp_pgd = (pgd_t *)(alloc + (levels - 1) * PAGE_SIZE);
		kpti_ng_temp_alloc = kpti_ng_temp_pgd_pa = __pa(kpti_ng_temp_pgd);

		//
		// Create a minimal page table hierarchy that permits us to map
		// the swapper page tables temporarily as we traverse them.
		//
		// The physical pages are laid out as follows:
		//
		// +--------+-/-------+-/------ +-/------ +-\\\--------+
		// :  PTE[] : | PMD[] : | PUD[] : | P4D[] : ||| PGD[]  :
		// +--------+-\-------+-\------ +-\------ +-///--------+
		//      ^
		// The first page is mapped into this hierarchy at a PMD_SHIFT
		// aligned virtual address, so that we can manipulate the PTE
		// level entries while the mapping is active. The first entry
		// covers the PTE[] page itself, the remaining entries are free
		// to be used as a ad-hoc fixmap.
		//
		create_kpti_ng_temp_pgd(kpti_ng_temp_pgd, __pa(alloc),
					KPTI_NG_TEMP_VA, PAGE_SIZE, PAGE_KERNEL,
					kpti_ng_pgd_alloc, 0);
	}

	cpu_install_idmap();
	remap_fn(cpu, num_online_cpus(), kpti_ng_temp_pgd_pa, KPTI_NG_TEMP_VA);
	cpu_uninstall_idmap();

	if (!cpu) {
		free_pages(alloc, order);
		arm64_use_ng_mappings = true;
	}

	return 0;
}

static void __init kpti_install_ng_mappings(void)
{
	/* Check whether KPTI is going to be used */
	if (!arm64_kernel_unmapped_at_el0())
		return;

	/*
	 * We don't need to rewrite the page-tables if either we've done
	 * it already or we have KASLR enabled and therefore have not
	 * created any global mappings at all.
	 */
	if (arm64_use_ng_mappings)
		return;

	init_idmap_kpti_bbml2_flag();
	stop_machine(__kpti_install_ng_mappings, NULL, cpu_online_mask);
}

#else
static inline void kpti_install_ng_mappings(void)
{
}
#endif	/* CONFIG_UNMAP_KERNEL_AT_EL0 */

static void cpu_enable_kpti(struct arm64_cpu_capabilities const *cap)
{
	if (__this_cpu_read(this_cpu_vector) == vectors) {
@@ -2419,17 +2321,21 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused)
#ifdef CONFIG_ARM64_MTE
static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
{
	static bool cleared_zero_page = false;

	sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ATA | SCTLR_EL1_ATA0);

	mte_cpu_setup();

	/*
	 * Clear the tags in the zero page. This needs to be done via the
	 * linear map which has the Tagged attribute.
	 * linear map which has the Tagged attribute. Since this page is
	 * always mapped as pte_special(), set_pte_at() will not attempt to
	 * clear the tags or set PG_mte_tagged.
	 */
	if (try_page_mte_tagging(ZERO_PAGE(0))) {
	if (!cleared_zero_page) {
		cleared_zero_page = true;
		mte_clear_page_tags(lm_alias(empty_zero_page));
		set_page_mte_tagged(ZERO_PAGE(0));
	}

	kasan_init_hw_tags_cpu();
Loading