Commit d29e4723 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Will Deacon:
 "The main thing here is reviving hugetlb support using contiguous ptes,
  which we ended up reverting at the last minute in 4.5 pending a fix
  which went into the core mm/ code during the recent merge window.

   - Revert a previous revert and get hugetlb going with contiguous hints
   - Wire up missing compat syscalls
   - Enable CONFIG_SET_MODULE_RONX by default
   - Add missing line to our compat /proc/cpuinfo output
   - Clarify levels in our page table dumps
   - Fix booting with RANDOMIZE_TEXT_OFFSET enabled
   - Misc fixes to the ARM CPU PMU driver (refcounting, probe failure)
   - Remove some dead code and update a comment"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  arm64: fix alignment when RANDOMIZE_TEXT_OFFSET is enabled
  arm64: move {PAGE,CONT}_SHIFT into Kconfig
  arm64: mm: dump: log span level
  arm64: update stale PAGE_OFFSET comment
  drivers/perf: arm_pmu: Avoid leaking pmu->irq_affinity on error
  drivers/perf: arm_pmu: Defer the setting of __oprofile_cpu_pmu
  drivers/perf: arm_pmu: Fix reference count of a device_node in of_pmu_irq_cfg
  arm64: report CPU number in bad_mode
  arm64: unistd32.h: wire up missing syscalls for compat tasks
  arm64: Provide "model name" in /proc/cpuinfo for PER_LINUX32 tasks
  arm64: enable CONFIG_SET_MODULE_RONX by default
  arm64: Remove orphaned __addr_ok() definition
  Revert "arm64: hugetlb: partial revert of 66b3923a"
parents 5306d766 aed7eb83
...@@ -113,6 +113,18 @@ config ARCH_PHYS_ADDR_T_64BIT ...@@ -113,6 +113,18 @@ config ARCH_PHYS_ADDR_T_64BIT
config MMU config MMU
def_bool y def_bool y
config ARM64_PAGE_SHIFT
int
default 16 if ARM64_64K_PAGES
default 14 if ARM64_16K_PAGES
default 12
config ARM64_CONT_SHIFT
int
default 5 if ARM64_64K_PAGES
default 7 if ARM64_16K_PAGES
default 4
config ARCH_MMAP_RND_BITS_MIN config ARCH_MMAP_RND_BITS_MIN
default 14 if ARM64_64K_PAGES default 14 if ARM64_64K_PAGES
default 16 if ARM64_16K_PAGES default 16 if ARM64_16K_PAGES
......
...@@ -12,7 +12,8 @@ config ARM64_PTDUMP ...@@ -12,7 +12,8 @@ config ARM64_PTDUMP
who are working in architecture specific areas of the kernel. who are working in architecture specific areas of the kernel.
It is probably not a good idea to enable this feature in a production It is probably not a good idea to enable this feature in a production
kernel. kernel.
If in doubt, say "N"
If in doubt, say N.
config PID_IN_CONTEXTIDR config PID_IN_CONTEXTIDR
bool "Write the current PID to the CONTEXTIDR register" bool "Write the current PID to the CONTEXTIDR register"
...@@ -38,15 +39,15 @@ config ARM64_RANDOMIZE_TEXT_OFFSET ...@@ -38,15 +39,15 @@ config ARM64_RANDOMIZE_TEXT_OFFSET
value. value.
config DEBUG_SET_MODULE_RONX config DEBUG_SET_MODULE_RONX
bool "Set loadable kernel module data as NX and text as RO" bool "Set loadable kernel module data as NX and text as RO"
depends on MODULES depends on MODULES
help default y
This option helps catch unintended modifications to loadable help
kernel module's text and read-only data. It also prevents execution Is this is set, kernel module text and rodata will be made read-only.
of module data. Such protection may interfere with run-time code This is to help catch accidental or malicious attempts to change the
patching and dynamic kernel tracing - and they might also protect kernel's executable code.
against certain classes of kernel exploits.
If in doubt, say "N". If in doubt, say Y.
config DEBUG_RODATA config DEBUG_RODATA
bool "Make kernel text and rodata read-only" bool "Make kernel text and rodata read-only"
...@@ -56,7 +57,7 @@ config DEBUG_RODATA ...@@ -56,7 +57,7 @@ config DEBUG_RODATA
is to help catch accidental or malicious attempts to change the is to help catch accidental or malicious attempts to change the
kernel's executable code. kernel's executable code.
If in doubt, say Y If in doubt, say Y.
config DEBUG_ALIGN_RODATA config DEBUG_ALIGN_RODATA
depends on DEBUG_RODATA depends on DEBUG_RODATA
...@@ -69,7 +70,7 @@ config DEBUG_ALIGN_RODATA ...@@ -69,7 +70,7 @@ config DEBUG_ALIGN_RODATA
alignment and potentially wasted space. Turn on this option if alignment and potentially wasted space. Turn on this option if
performance is more important than memory pressure. performance is more important than memory pressure.
If in doubt, say N If in doubt, say N.
source "drivers/hwtracing/coresight/Kconfig" source "drivers/hwtracing/coresight/Kconfig"
......
...@@ -60,7 +60,9 @@ head-y := arch/arm64/kernel/head.o ...@@ -60,7 +60,9 @@ head-y := arch/arm64/kernel/head.o
# The byte offset of the kernel image in RAM from the start of RAM. # The byte offset of the kernel image in RAM from the start of RAM.
ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y) ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y)
TEXT_OFFSET := $(shell awk 'BEGIN {srand(); printf "0x%03x000\n", int(512 * rand())}') TEXT_OFFSET := $(shell awk "BEGIN {srand(); printf \"0x%06x\n\", \
int(2 * 1024 * 1024 / (2 ^ $(CONFIG_ARM64_PAGE_SHIFT)) * \
rand()) * (2 ^ $(CONFIG_ARM64_PAGE_SHIFT))}")
else else
TEXT_OFFSET := 0x00080000 TEXT_OFFSET := 0x00080000
endif endif
......
...@@ -160,14 +160,14 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm, ...@@ -160,14 +160,14 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
#define STACK_RND_MASK (0x3ffff >> (PAGE_SHIFT - 12)) #define STACK_RND_MASK (0x3ffff >> (PAGE_SHIFT - 12))
#endif #endif
#ifdef CONFIG_COMPAT
#ifdef __AARCH64EB__ #ifdef __AARCH64EB__
#define COMPAT_ELF_PLATFORM ("v8b") #define COMPAT_ELF_PLATFORM ("v8b")
#else #else
#define COMPAT_ELF_PLATFORM ("v8l") #define COMPAT_ELF_PLATFORM ("v8l")
#endif #endif
#ifdef CONFIG_COMPAT
#define COMPAT_ELF_ET_DYN_BASE (2 * TASK_SIZE_32 / 3) #define COMPAT_ELF_ET_DYN_BASE (2 * TASK_SIZE_32 / 3)
/* AArch32 registers. */ /* AArch32 registers. */
......
...@@ -55,8 +55,9 @@ ...@@ -55,8 +55,9 @@
#define VMEMMAP_SIZE (UL(1) << (VA_BITS - PAGE_SHIFT - 1 + STRUCT_PAGE_MAX_SHIFT)) #define VMEMMAP_SIZE (UL(1) << (VA_BITS - PAGE_SHIFT - 1 + STRUCT_PAGE_MAX_SHIFT))
/* /*
* PAGE_OFFSET - the virtual address of the start of the kernel image (top * PAGE_OFFSET - the virtual address of the start of the linear map (top
* (VA_BITS - 1)) * (VA_BITS - 1))
* KIMAGE_VADDR - the virtual address of the start of the kernel image
* VA_BITS - the maximum number of bits for virtual addresses. * VA_BITS - the maximum number of bits for virtual addresses.
* VA_START - the first kernel virtual address. * VA_START - the first kernel virtual address.
* TASK_SIZE - the maximum size of a user space task. * TASK_SIZE - the maximum size of a user space task.
......
...@@ -23,16 +23,8 @@ ...@@ -23,16 +23,8 @@
/* PAGE_SHIFT determines the page size */ /* PAGE_SHIFT determines the page size */
/* CONT_SHIFT determines the number of pages which can be tracked together */ /* CONT_SHIFT determines the number of pages which can be tracked together */
#ifdef CONFIG_ARM64_64K_PAGES #define PAGE_SHIFT CONFIG_ARM64_PAGE_SHIFT
#define PAGE_SHIFT 16 #define CONT_SHIFT CONFIG_ARM64_CONT_SHIFT
#define CONT_SHIFT 5
#elif defined(CONFIG_ARM64_16K_PAGES)
#define PAGE_SHIFT 14
#define CONT_SHIFT 7
#else
#define PAGE_SHIFT 12
#define CONT_SHIFT 4
#endif
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1)) #define PAGE_MASK (~(PAGE_SIZE-1))
......
...@@ -80,19 +80,6 @@ static inline void set_fs(mm_segment_t fs) ...@@ -80,19 +80,6 @@ static inline void set_fs(mm_segment_t fs)
#define segment_eq(a, b) ((a) == (b)) #define segment_eq(a, b) ((a) == (b))
/*
* Return 1 if addr < current->addr_limit, 0 otherwise.
*/
#define __addr_ok(addr) \
({ \
unsigned long flag; \
asm("cmp %1, %0; cset %0, lo" \
: "=&r" (flag) \
: "r" (addr), "0" (current_thread_info()->addr_limit) \
: "cc"); \
flag; \
})
/* /*
* Test whether a block of memory is a valid user space address. * Test whether a block of memory is a valid user space address.
* Returns 1 if the range is valid, 0 otherwise. * Returns 1 if the range is valid, 0 otherwise.
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE+2) #define __ARM_NR_compat_cacheflush (__ARM_NR_COMPAT_BASE+2)
#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE+5) #define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE+5)
#define __NR_compat_syscalls 390 #define __NR_compat_syscalls 394
#endif #endif
#define __ARCH_WANT_SYS_CLONE #define __ARCH_WANT_SYS_CLONE
......
...@@ -801,6 +801,14 @@ __SYSCALL(__NR_execveat, compat_sys_execveat) ...@@ -801,6 +801,14 @@ __SYSCALL(__NR_execveat, compat_sys_execveat)
__SYSCALL(__NR_userfaultfd, sys_userfaultfd) __SYSCALL(__NR_userfaultfd, sys_userfaultfd)
#define __NR_membarrier 389 #define __NR_membarrier 389
__SYSCALL(__NR_membarrier, sys_membarrier) __SYSCALL(__NR_membarrier, sys_membarrier)
#define __NR_mlock2 390
__SYSCALL(__NR_mlock2, sys_mlock2)
#define __NR_copy_file_range 391
__SYSCALL(__NR_copy_file_range, sys_copy_file_range)
#define __NR_preadv2 392
__SYSCALL(__NR_preadv2, compat_sys_preadv2)
#define __NR_pwritev2 393
__SYSCALL(__NR_pwritev2, compat_sys_pwritev2)
/* /*
* Please add new compat syscalls above this comment and update * Please add new compat syscalls above this comment and update
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/bug.h> #include <linux/bug.h>
#include <linux/compat.h>
#include <linux/elf.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/personality.h> #include <linux/personality.h>
...@@ -104,6 +106,7 @@ static const char *const compat_hwcap2_str[] = { ...@@ -104,6 +106,7 @@ static const char *const compat_hwcap2_str[] = {
static int c_show(struct seq_file *m, void *v) static int c_show(struct seq_file *m, void *v)
{ {
int i, j; int i, j;
bool compat = personality(current->personality) == PER_LINUX32;
for_each_online_cpu(i) { for_each_online_cpu(i) {
struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i); struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
...@@ -115,6 +118,9 @@ static int c_show(struct seq_file *m, void *v) ...@@ -115,6 +118,9 @@ static int c_show(struct seq_file *m, void *v)
* "processor". Give glibc what it expects. * "processor". Give glibc what it expects.
*/ */
seq_printf(m, "processor\t: %d\n", i); seq_printf(m, "processor\t: %d\n", i);
if (compat)
seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
loops_per_jiffy / (500000UL/HZ), loops_per_jiffy / (500000UL/HZ),
...@@ -127,7 +133,7 @@ static int c_show(struct seq_file *m, void *v) ...@@ -127,7 +133,7 @@ static int c_show(struct seq_file *m, void *v)
* software which does already (at least for 32-bit). * software which does already (at least for 32-bit).
*/ */
seq_puts(m, "Features\t:"); seq_puts(m, "Features\t:");
if (personality(current->personality) == PER_LINUX32) { if (compat) {
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
for (j = 0; compat_hwcap_str[j]; j++) for (j = 0; compat_hwcap_str[j]; j++)
if (compat_elf_hwcap & (1 << j)) if (compat_elf_hwcap & (1 << j))
......
...@@ -477,8 +477,9 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr) ...@@ -477,8 +477,9 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
void __user *pc = (void __user *)instruction_pointer(regs); void __user *pc = (void __user *)instruction_pointer(regs);
console_verbose(); console_verbose();
pr_crit("Bad mode in %s handler detected, code 0x%08x -- %s\n", pr_crit("Bad mode in %s handler detected on CPU%d, code 0x%08x -- %s\n",
handler[reason], esr, esr_get_class_string(esr)); handler[reason], smp_processor_id(), esr,
esr_get_class_string(esr));
__show_regs(regs); __show_regs(regs);
info.si_signo = SIGILL; info.si_signo = SIGILL;
......
...@@ -150,6 +150,7 @@ static const struct prot_bits pte_bits[] = { ...@@ -150,6 +150,7 @@ static const struct prot_bits pte_bits[] = {
struct pg_level { struct pg_level {
const struct prot_bits *bits; const struct prot_bits *bits;
const char *name;
size_t num; size_t num;
u64 mask; u64 mask;
}; };
...@@ -157,15 +158,19 @@ struct pg_level { ...@@ -157,15 +158,19 @@ struct pg_level {
static struct pg_level pg_level[] = { static struct pg_level pg_level[] = {
{ {
}, { /* pgd */ }, { /* pgd */
.name = "PGD",
.bits = pte_bits, .bits = pte_bits,
.num = ARRAY_SIZE(pte_bits), .num = ARRAY_SIZE(pte_bits),
}, { /* pud */ }, { /* pud */
.name = (CONFIG_PGTABLE_LEVELS > 3) ? "PUD" : "PGD",
.bits = pte_bits, .bits = pte_bits,
.num = ARRAY_SIZE(pte_bits), .num = ARRAY_SIZE(pte_bits),
}, { /* pmd */ }, { /* pmd */
.name = (CONFIG_PGTABLE_LEVELS > 2) ? "PMD" : "PGD",
.bits = pte_bits, .bits = pte_bits,
.num = ARRAY_SIZE(pte_bits), .num = ARRAY_SIZE(pte_bits),
}, { /* pte */ }, { /* pte */
.name = "PTE",
.bits = pte_bits, .bits = pte_bits,
.num = ARRAY_SIZE(pte_bits), .num = ARRAY_SIZE(pte_bits),
}, },
...@@ -214,7 +219,8 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level, ...@@ -214,7 +219,8 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
delta >>= 10; delta >>= 10;
unit++; unit++;
} }
seq_printf(st->seq, "%9lu%c", delta, *unit); seq_printf(st->seq, "%9lu%c %s", delta, *unit,
pg_level[st->level].name);
if (pg_level[st->level].bits) if (pg_level[st->level].bits)
dump_prot(st, pg_level[st->level].bits, dump_prot(st, pg_level[st->level].bits,
pg_level[st->level].num); pg_level[st->level].num);
......
...@@ -306,6 +306,10 @@ static __init int setup_hugepagesz(char *opt) ...@@ -306,6 +306,10 @@ static __init int setup_hugepagesz(char *opt)
hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT); hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT);
} else if (ps == PUD_SIZE) { } else if (ps == PUD_SIZE) {
hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
} else if (ps == (PAGE_SIZE * CONT_PTES)) {
hugetlb_add_hstate(CONT_PTE_SHIFT);
} else if (ps == (PMD_SIZE * CONT_PMDS)) {
hugetlb_add_hstate((PMD_SHIFT + CONT_PMD_SHIFT) - PAGE_SHIFT);
} else { } else {
hugetlb_bad_size(); hugetlb_bad_size();
pr_err("hugepagesz: Unsupported page size %lu K\n", ps >> 10); pr_err("hugepagesz: Unsupported page size %lu K\n", ps >> 10);
...@@ -314,3 +318,13 @@ static __init int setup_hugepagesz(char *opt) ...@@ -314,3 +318,13 @@ static __init int setup_hugepagesz(char *opt)
return 1; return 1;
} }
__setup("hugepagesz=", setup_hugepagesz); __setup("hugepagesz=", setup_hugepagesz);
#ifdef CONFIG_ARM64_64K_PAGES
static __init int add_default_hugepagesz(void)
{
if (size_to_hstate(CONT_PTES * PAGE_SIZE) == NULL)
hugetlb_add_hstate(CONT_PMD_SHIFT);
return 0;
}
arch_initcall(add_default_hugepagesz);
#endif
...@@ -950,17 +950,14 @@ static int of_pmu_irq_cfg(struct arm_pmu *pmu) ...@@ -950,17 +950,14 @@ static int of_pmu_irq_cfg(struct arm_pmu *pmu)
/* For SPIs, we need to track the affinity per IRQ */ /* For SPIs, we need to track the affinity per IRQ */
if (using_spi) { if (using_spi) {
if (i >= pdev->num_resources) { if (i >= pdev->num_resources)
of_node_put(dn);
break; break;
}
irqs[i] = cpu; irqs[i] = cpu;
} }
/* Keep track of the CPUs containing this PMU type */ /* Keep track of the CPUs containing this PMU type */
cpumask_set_cpu(cpu, &pmu->supported_cpus); cpumask_set_cpu(cpu, &pmu->supported_cpus);
of_node_put(dn);
i++; i++;
} while (1); } while (1);
...@@ -995,9 +992,6 @@ int arm_pmu_device_probe(struct platform_device *pdev, ...@@ -995,9 +992,6 @@ int arm_pmu_device_probe(struct platform_device *pdev,
armpmu_init(pmu); armpmu_init(pmu);
if (!__oprofile_cpu_pmu)
__oprofile_cpu_pmu = pmu;
pmu->plat_device = pdev; pmu->plat_device = pdev;
if (node && (of_id = of_match_node(of_table, pdev->dev.of_node))) { if (node && (of_id = of_match_node(of_table, pdev->dev.of_node))) {
...@@ -1033,6 +1027,9 @@ int arm_pmu_device_probe(struct platform_device *pdev, ...@@ -1033,6 +1027,9 @@ int arm_pmu_device_probe(struct platform_device *pdev,
if (ret) if (ret)
goto out_destroy; goto out_destroy;
if (!__oprofile_cpu_pmu)
__oprofile_cpu_pmu = pmu;
pr_info("enabled with %s PMU driver, %d counters available\n", pr_info("enabled with %s PMU driver, %d counters available\n",
pmu->name, pmu->num_events); pmu->name, pmu->num_events);
...@@ -1043,6 +1040,7 @@ out_destroy: ...@@ -1043,6 +1040,7 @@ out_destroy:
out_free: out_free:
pr_info("%s: failed to register PMU devices!\n", pr_info("%s: failed to register PMU devices!\n",
of_node_full_name(node)); of_node_full_name(node));
kfree(pmu->irq_affinity);
kfree(pmu); kfree(pmu);
return ret; return ret;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment