]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 12 Nov 2015 23:33:11 +0000 (15:33 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 12 Nov 2015 23:33:11 +0000 (15:33 -0800)
Pull arm64 fixes and clean-ups from Catalin Marinas:
 "Here's a second pull request for this merging window with some
  fixes/clean-ups:

   - __cmpxchg_double*() return type fix to avoid truncation of a long
     to int and subsequent logical "not" in cmpxchg_double()
     misinterpreting the operation success/failure

   - BPF fixes for mod and div by zero

   - Fix compilation with STRICT_MM_TYPECHECKS enabled

   - VDSO build fix without libgcov

   - Some static and __maybe_unused annotations

   - Kconfig clean-up (FRAME_POINTER)

   - defconfig update for CRYPTO_CRC32_ARM64"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  arm64: suspend: make hw_breakpoint_restore static
  arm64: mmu: make split_pud and fixup_executable static
  arm64: smp: make of_parse_and_init_cpus static
  arm64: use linux/types.h in kvm.h
  arm64: build vdso without libgcov
  arm64: mark cpus_have_hwcap as __maybe_unused
  arm64: remove redundant FRAME_POINTER kconfig option and force to select it
  arm64: fix R/O permissions of FDT mapping
  arm64: fix STRICT_MM_TYPECHECKS issue in PTE_CONT manipulation
  arm64: bpf: fix mod-by-zero case
  arm64: bpf: fix div-by-zero case
  arm64: Enable CRYPTO_CRC32_ARM64 in defconfig
  arm64: cmpxchg_dbl: fix return value type

1  2 
arch/arm64/Kconfig
arch/arm64/configs/defconfig
arch/arm64/include/asm/pgtable.h
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/suspend.c
arch/arm64/net/bpf_jit_comp.c

diff --combined arch/arm64/Kconfig
index 851fe11c6069d47a714a87840d6a18a3278d0af8,40e1151fb7715101744740078048d3a4f305f8bd..9ac16a482ff1e690b9b6aa66a09225cec831966b
@@@ -27,6 -27,7 +27,7 @@@ config ARM6
        select CPU_PM if (SUSPEND || CPU_IDLE)
        select DCACHE_WORD_ACCESS
        select EDAC_SUPPORT
+       select FRAME_POINTER
        select GENERIC_ALLOCATOR
        select GENERIC_CLOCKEVENTS
        select GENERIC_CLOCKEVENTS_BROADCAST
@@@ -76,7 -77,6 +77,7 @@@
        select HAVE_PERF_USER_STACK_DUMP
        select HAVE_RCU_TABLE_FREE
        select HAVE_SYSCALL_TRACEPOINTS
 +      select IOMMU_DMA if IOMMU_SUPPORT
        select IRQ_DOMAIN
        select IRQ_FORCED_THREADING
        select MODULES_USE_ELF_RELA
@@@ -352,33 -352,6 +353,33 @@@ config ARM64_ERRATUM_84341
  
          If unsure, say Y.
  
 +config CAVIUM_ERRATUM_22375
 +      bool "Cavium erratum 22375, 24313"
 +      default y
 +      help
 +        Enable workaround for erratum 22375, 24313.
 +
 +        This implements two gicv3-its errata workarounds for ThunderX. Both
 +        with small impact affecting only ITS table allocation.
 +
 +          erratum 22375: only alloc 8MB table size
 +          erratum 24313: ignore memory access type
 +
 +        The fixes are in ITS initialization and basically ignore memory access
 +        type and table size provided by the TYPER and BASER registers.
 +
 +        If unsure, say Y.
 +
 +config CAVIUM_ERRATUM_23154
 +      bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
 +      default y
 +      help
 +        The gicv3 of ThunderX requires a modified version for
 +        reading the IAR status to ensure data synchronization
 +        (access to icc_iar1_el1 is not sync'ed before and after).
 +
 +        If unsure, say Y.
 +
  endmenu
  
  
index 2f71f9cdd39c90be282b09d44bb0e795ab0181c6,f106bb29d5053c535425b707aa36b82694a01930..bdd7aa358d2a5bc232dc510e789e61939416f700
@@@ -34,12 -34,11 +34,12 @@@ CONFIG_MODULE_UNLOAD=
  CONFIG_ARCH_BCM_IPROC=y
  CONFIG_ARCH_BERLIN=y
  CONFIG_ARCH_EXYNOS7=y
 -CONFIG_ARCH_FSL_LS2085A=y
 +CONFIG_ARCH_LAYERSCAPE=y
  CONFIG_ARCH_HISI=y
  CONFIG_ARCH_MEDIATEK=y
  CONFIG_ARCH_ROCKCHIP=y
  CONFIG_ARCH_SEATTLE=y
 +CONFIG_ARCH_STRATIX10=y
  CONFIG_ARCH_TEGRA=y
  CONFIG_ARCH_TEGRA_132_SOC=y
  CONFIG_ARCH_QCOM=y
@@@ -50,7 -49,6 +50,7 @@@ CONFIG_ARCH_XGENE=
  CONFIG_ARCH_ZYNQMP=y
  CONFIG_PCI=y
  CONFIG_PCI_MSI=y
 +CONFIG_PCI_HOST_GENERIC=y
  CONFIG_PCI_XGENE=y
  CONFIG_SMP=y
  CONFIG_SCHED_MC=y
@@@ -123,11 -121,8 +123,11 @@@ CONFIG_SERIAL_XILINX_PS_UART=
  CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
  CONFIG_VIRTIO_CONSOLE=y
  # CONFIG_HW_RANDOM is not set
 +CONFIG_I2C=y
 +CONFIG_I2C_QUP=y
  CONFIG_SPI=y
  CONFIG_SPI_PL022=y
 +CONFIG_SPI_QUP=y
  CONFIG_PINCTRL_MSM8916=y
  CONFIG_GPIO_PL061=y
  CONFIG_GPIO_XGENE=y
@@@ -136,7 -131,6 +136,7 @@@ CONFIG_POWER_RESET_SYSCON=
  # CONFIG_HWMON is not set
  CONFIG_REGULATOR=y
  CONFIG_REGULATOR_FIXED_VOLTAGE=y
 +CONFIG_REGULATOR_QCOM_SMD_RPM=y
  CONFIG_FB=y
  CONFIG_FB_ARMCLCD=y
  CONFIG_FRAMEBUFFER_CONSOLE=y
@@@ -169,18 -163,12 +169,18 @@@ CONFIG_LEDS_TRIGGER_CPU=
  CONFIG_RTC_CLASS=y
  CONFIG_RTC_DRV_EFI=y
  CONFIG_RTC_DRV_XGENE=y
 +CONFIG_DMADEVICES=y
 +CONFIG_QCOM_BAM_DMA=y
  CONFIG_VIRTIO_PCI=y
  CONFIG_VIRTIO_BALLOON=y
  CONFIG_VIRTIO_MMIO=y
  CONFIG_COMMON_CLK_QCOM=y
  CONFIG_MSM_GCC_8916=y
 +CONFIG_HWSPINLOCK_QCOM=y
  # CONFIG_IOMMU_SUPPORT is not set
 +CONFIG_QCOM_SMEM=y
 +CONFIG_QCOM_SMD=y
 +CONFIG_QCOM_SMD_RPM=y
  CONFIG_PHY_XGENE=y
  CONFIG_EXT2_FS=y
  CONFIG_EXT3_FS=y
@@@ -224,3 -212,4 +224,4 @@@ CONFIG_CRYPTO_GHASH_ARM64_CE=
  CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
  CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
  CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
+ CONFIG_CRYPTO_CRC32_ARM64=y
index f3acf421ded4f55616abd7b68a7dcf83081e6f38,1c99d5610bc7033959cd7fbdc8b208a0af05fee4..9819a9426b69a936017e508a6cab907040c9c67a
@@@ -67,10 -67,8 +67,10 @@@ extern void __pgd_error(const char *fil
  #define PROT_DEFAULT          (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
  #define PROT_SECT_DEFAULT     (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
  
 +#define PROT_DEVICE_nGnRnE    (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
  #define PROT_DEVICE_nGnRE     (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
  #define PROT_NORMAL_NC                (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL_NC))
 +#define PROT_NORMAL_WT                (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL_WT))
  #define PROT_NORMAL           (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL))
  
  #define PROT_SECT_DEVICE_nGnRE        (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
@@@ -80,6 -78,7 +80,7 @@@
  #define _PAGE_DEFAULT         (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
  
  #define PAGE_KERNEL           __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE)
+ #define PAGE_KERNEL_RO                __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_RDONLY)
  #define PAGE_KERNEL_EXEC      __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE)
  #define PAGE_KERNEL_EXEC_CONT __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_CONT)
  
index 52f0d7a5a1c2e0ea0629d51da7204723bd531f66,6ecb824817901414a7b1f320715a2d28094bd5d3..c8cf89223b5a8ceb3564e77cc5a6893e5c8eb99d
@@@ -578,8 -578,6 +578,8 @@@ u64 read_system_reg(u32 id
        return regp->sys_val;
  }
  
 +#include <linux/irqchip/arm-gic-v3.h>
 +
  static bool
  feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)
  {
@@@ -597,26 -595,11 +597,26 @@@ has_cpuid_feature(const struct arm64_cp
        return feature_matches(val, entry);
  }
  
 +static bool has_useable_gicv3_cpuif(const struct arm64_cpu_capabilities *entry)
 +{
 +      bool has_sre;
 +
 +      if (!has_cpuid_feature(entry))
 +              return false;
 +
 +      has_sre = gic_enable_sre();
 +      if (!has_sre)
 +              pr_warn_once("%s present but disabled by higher exception level\n",
 +                           entry->desc);
 +
 +      return has_sre;
 +}
 +
  static const struct arm64_cpu_capabilities arm64_features[] = {
        {
                .desc = "GIC system register CPU interface",
                .capability = ARM64_HAS_SYSREG_GIC_CPUIF,
 -              .matches = has_cpuid_feature,
 +              .matches = has_useable_gicv3_cpuif,
                .sys_reg = SYS_ID_AA64PFR0_EL1,
                .field_pos = ID_AA64PFR0_GIC_SHIFT,
                .min_field_value = 1,
@@@ -696,7 -679,7 +696,7 @@@ static void cap_set_hwcap(const struct 
  }
  
  /* Check if we have a particular HWCAP enabled */
- static bool cpus_have_hwcap(const struct arm64_cpu_capabilities *cap)
+ static bool __maybe_unused cpus_have_hwcap(const struct arm64_cpu_capabilities *cap)
  {
        bool rc;
  
index 40f7b33a22dafce27c3491d181170760916aec04,d87403e8ba1dab582c31c58f93aef52886425e63..fce95e17cf7f268fdfc0dd5c2d91e00b1152fb3f
@@@ -41,7 -41,7 +41,7 @@@ void notrace __cpu_suspend_save(struct 
   * time the notifier runs debug exceptions might have been enabled already,
   * with HW breakpoints registers content still in an unknown state.
   */
- void (*hw_breakpoint_restore)(void *);
static void (*hw_breakpoint_restore)(void *);
  void __init cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *))
  {
        /* Prevent multiple restore hook initializations */
@@@ -80,21 -80,17 +80,21 @@@ int cpu_suspend(unsigned long arg, int 
        if (ret == 0) {
                /*
                 * We are resuming from reset with TTBR0_EL1 set to the
 -               * idmap to enable the MMU; restore the active_mm mappings in
 -               * TTBR0_EL1 unless the active_mm == &init_mm, in which case
 -               * the thread entered cpu_suspend with TTBR0_EL1 set to
 -               * reserved TTBR0 page tables and should be restored as such.
 +               * idmap to enable the MMU; set the TTBR0 to the reserved
 +               * page tables to prevent speculative TLB allocations, flush
 +               * the local tlb and set the default tcr_el1.t0sz so that
 +               * the TTBR0 address space set-up is properly restored.
 +               * If the current active_mm != &init_mm we entered cpu_suspend
 +               * with mappings in TTBR0 that must be restored, so we switch
 +               * them back to complete the address space configuration
 +               * restoration before returning.
                 */
 -              if (mm == &init_mm)
 -                      cpu_set_reserved_ttbr0();
 -              else
 -                      cpu_switch_mm(mm->pgd, mm);
 -
 +              cpu_set_reserved_ttbr0();
                local_flush_tlb_all();
 +              cpu_set_default_tcr_t0sz();
 +
 +              if (mm != &init_mm)
 +                      cpu_switch_mm(mm->pgd, mm);
  
                /*
                 * Restore per-cpu offset before any kernel
index a44e5293c6f58adb288e9c0d0549fcbe26c98daa,6217f80702d2ab627494ea04ef85d22e0ed34dec..cf3c7d4a1b585a928d9b4451ee268141d95d7088
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * BPF JIT compiler for ARM64
   *
-  * Copyright (C) 2014 Zi Shen Lim <zlim.lnx@gmail.com>
+  * Copyright (C) 2014-2015 Zi Shen Lim <zlim.lnx@gmail.com>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
@@@ -225,6 -225,17 +225,17 @@@ static int build_insn(const struct bpf_
        u8 jmp_cond;
        s32 jmp_offset;
  
+ #define check_imm(bits, imm) do {                             \
+       if ((((imm) > 0) && ((imm) >> (bits))) ||               \
+           (((imm) < 0) && (~(imm) >> (bits)))) {              \
+               pr_info("[%2d] imm=%d(0x%x) out of range\n",    \
+                       i, imm, imm);                           \
+               return -EINVAL;                                 \
+       }                                                       \
+ } while (0)
+ #define check_imm19(imm) check_imm(19, imm)
+ #define check_imm26(imm) check_imm(26, imm)
        switch (code) {
        /* dst = src */
        case BPF_ALU | BPF_MOV | BPF_X:
                break;
        case BPF_ALU | BPF_DIV | BPF_X:
        case BPF_ALU64 | BPF_DIV | BPF_X:
-               emit(A64_UDIV(is64, dst, dst, src), ctx);
-               break;
        case BPF_ALU | BPF_MOD | BPF_X:
        case BPF_ALU64 | BPF_MOD | BPF_X:
-               ctx->tmp_used = 1;
-               emit(A64_UDIV(is64, tmp, dst, src), ctx);
-               emit(A64_MUL(is64, tmp, tmp, src), ctx);
-               emit(A64_SUB(is64, dst, dst, tmp), ctx);
+       {
+               const u8 r0 = bpf2a64[BPF_REG_0];
+               /* if (src == 0) return 0 */
+               jmp_offset = 3; /* skip ahead to else path */
+               check_imm19(jmp_offset);
+               emit(A64_CBNZ(is64, src, jmp_offset), ctx);
+               emit(A64_MOVZ(1, r0, 0, 0), ctx);
+               jmp_offset = epilogue_offset(ctx);
+               check_imm26(jmp_offset);
+               emit(A64_B(jmp_offset), ctx);
+               /* else */
+               switch (BPF_OP(code)) {
+               case BPF_DIV:
+                       emit(A64_UDIV(is64, dst, dst, src), ctx);
+                       break;
+               case BPF_MOD:
+                       ctx->tmp_used = 1;
+                       emit(A64_UDIV(is64, tmp, dst, src), ctx);
+                       emit(A64_MUL(is64, tmp, tmp, src), ctx);
+                       emit(A64_SUB(is64, dst, dst, tmp), ctx);
+                       break;
+               }
                break;
+       }
        case BPF_ALU | BPF_LSH | BPF_X:
        case BPF_ALU64 | BPF_LSH | BPF_X:
                emit(A64_LSLV(is64, dst, dst, src), ctx);
@@@ -393,17 -422,6 +422,6 @@@ emit_bswap_uxt
                emit(A64_ASR(is64, dst, dst, imm), ctx);
                break;
  
- #define check_imm(bits, imm) do {                             \
-       if ((((imm) > 0) && ((imm) >> (bits))) ||               \
-           (((imm) < 0) && (~(imm) >> (bits)))) {              \
-               pr_info("[%2d] imm=%d(0x%x) out of range\n",    \
-                       i, imm, imm);                           \
-               return -EINVAL;                                 \
-       }                                                       \
- } while (0)
- #define check_imm19(imm) check_imm(19, imm)
- #define check_imm26(imm) check_imm(26, imm)
        /* JUMP off */
        case BPF_JMP | BPF_JA:
                jmp_offset = bpf2a64_offset(i + off, i, ctx);
@@@ -744,7 -762,7 +762,7 @@@ void bpf_int_jit_compile(struct bpf_pro
  
        set_memory_ro((unsigned long)header, header->pages);
        prog->bpf_func = (void *)ctx.image;
 -      prog->jited = true;
 +      prog->jited = 1;
  out:
        kfree(ctx.offset);
  }