Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 18 Mar 2016 03:03:47 +0000 (20:03 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 18 Mar 2016 03:03:47 +0000 (20:03 -0700)
Pull arm64 updates from Catalin Marinas:
 "Here are the main arm64 updates for 4.6.  There are some relatively
  intrusive changes to support KASLR, the reworking of the kernel
  virtual memory layout and initial page table creation.

  Summary:

   - Initial page table creation reworked to avoid breaking large block
     mappings (huge pages) into smaller ones.  The ARM architecture
     requires break-before-make in such cases to avoid TLB conflicts but
     that's not always possible on live page tables

   - Kernel virtual memory layout: the kernel image is no longer linked
     to the bottom of the linear mapping (PAGE_OFFSET) but at the bottom
     of the vmalloc space, allowing the kernel to be loaded (nearly)
     anywhere in physical RAM

   - Kernel ASLR: position independent kernel Image and modules being
     randomly mapped in the vmalloc space with the randomness is
     provided by UEFI (efi_get_random_bytes() patches merged via the
     arm64 tree, acked by Matt Fleming)

   - Implement relative exception tables for arm64, required by KASLR
     (initial code for ARCH_HAS_RELATIVE_EXTABLE added to lib/extable.c
     but actual x86 conversion to deferred to 4.7 because of the merge
     dependencies)

   - Support for the User Access Override feature of ARMv8.2: this
     allows uaccess functions (get_user etc.) to be implemented using
     LDTR/STTR instructions.  Such instructions, when run by the kernel,
     perform unprivileged accesses adding an extra level of protection.
     The set_fs() macro is used to "upgrade" such instruction to
     privileged accesses via the UAO bit

   - Half-precision floating point support (part of ARMv8.2)

   - Optimisations for CPUs with or without a hardware prefetcher (using
     run-time code patching)

   - copy_page performance improvement to deal with 128 bytes at a time

   - Sanity checks on the CPU capabilities (via CPUID) to prevent
     incompatible secondary CPUs from being brought up (e.g.  weird
     big.LITTLE configurations)

   - valid_user_regs() reworked for better sanity check of the
     sigcontext information (restored pstate information)

   - ACPI parking protocol implementation

   - CONFIG_DEBUG_RODATA enabled by default

   - VDSO code marked as read-only

   - DEBUG_PAGEALLOC support

   - ARCH_HAS_UBSAN_SANITIZE_ALL enabled

   - Erratum workaround Cavium ThunderX SoC

   - set_pte_at() fix for PROT_NONE mappings

   - Code clean-ups"

* tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (99 commits)
  arm64: kasan: Fix zero shadow mapping overriding kernel image shadow
  arm64: kasan: Use actual memory node when populating the kernel image shadow
  arm64: Update PTE_RDONLY in set_pte_at() for PROT_NONE permission
  arm64: Fix misspellings in comments.
  arm64: efi: add missing frame pointer assignment
  arm64: make mrs_s prefixing implicit in read_cpuid
  arm64: enable CONFIG_DEBUG_RODATA by default
  arm64: Rework valid_user_regs
  arm64: mm: check at build time that PAGE_OFFSET divides the VA space evenly
  arm64: KVM: Move kvm_call_hyp back to its original localtion
  arm64: mm: treat memstart_addr as a signed quantity
  arm64: mm: list kernel sections in order
  arm64: lse: deal with clobbered IP registers after branch via PLT
  arm64: mm: dump: Use VA_START directly instead of private LOWEST_ADDR
  arm64: kconfig: add submenu for 8.2 architectural features
  arm64: kernel: acpi: fix ioremap in ACPI parking protocol cpu_postboot
  arm64: Add support for Half precision floating point
  arm64: Remove fixmap include fragility
  arm64: Add workaround for Cavium erratum 27456
  arm64: mm: Mark .rodata as RO
  ...

25 files changed:
1  2 
arch/arm/include/asm/kvm_asm.h
arch/arm/kvm/arm.c
arch/arm64/Kconfig
arch/arm64/Makefile
arch/arm64/include/asm/cpufeature.h
arch/arm64/include/asm/kvm_arm.h
arch/arm64/include/asm/kvm_asm.h
arch/arm64/include/asm/kvm_host.h
arch/arm64/include/asm/kvm_mmu.h
arch/arm64/include/asm/pgtable.h
arch/arm64/kernel/asm-offsets.c
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/debug-monitors.c
arch/arm64/kernel/head.S
arch/arm64/kernel/image.h
arch/arm64/kernel/setup.c
arch/arm64/kernel/smp.c
arch/arm64/kvm/hyp.S
arch/arm64/kvm/hyp/debug-sr.c
arch/arm64/kvm/sys_regs.c
arch/arm64/mm/fault.c
arch/arm64/mm/init.c
drivers/of/fdt.c
include/linux/efi.h
scripts/sortextable.c

Simple merge
index 76552b51c7aea64fb9b8cc84436abad526991732,975da6cfbf5917e604b576027189469d95cd4a52..3e0fb66d8e053b5bbd7317d8bbcedf69950833dc
@@@ -1051,10 -982,9 +1051,10 @@@ static void cpu_init_hyp_mode(void *dum
        pgd_ptr = kvm_mmu_get_httbr();
        stack_page = __this_cpu_read(kvm_arm_hyp_stack_page);
        hyp_stack_ptr = stack_page + PAGE_SIZE;
-       vector_ptr = (unsigned long)__kvm_hyp_vector;
+       vector_ptr = (unsigned long)kvm_ksym_ref(__kvm_hyp_vector);
  
        __cpu_init_hyp_mode(boot_pgd_ptr, pgd_ptr, hyp_stack_ptr, vector_ptr);
 +      __cpu_init_stage2();
  
        kvm_arm_init_debug();
  }
@@@ -1220,16 -1074,18 +1220,18 @@@ static int init_hyp_mode(void
        /*
         * Map the Hyp-code called directly from the host
         */
-       err = create_hyp_mappings(__hyp_text_start, __hyp_text_end);
 -      err = create_hyp_mappings(kvm_ksym_ref(__kvm_hyp_code_start),
 -                                kvm_ksym_ref(__kvm_hyp_code_end));
++      err = create_hyp_mappings(kvm_ksym_ref(__hyp_text_start),
++                                kvm_ksym_ref(__hyp_text_end));
        if (err) {
                kvm_err("Cannot map world-switch code\n");
 -              goto out_free_mappings;
 +              goto out_err;
        }
  
-       err = create_hyp_mappings(__start_rodata, __end_rodata);
+       err = create_hyp_mappings(kvm_ksym_ref(__start_rodata),
+                                 kvm_ksym_ref(__end_rodata));
        if (err) {
                kvm_err("Cannot map rodata section\n");
 -              goto out_free_mappings;
 +              goto out_err;
        }
  
        /*
index b3f2522d266d802221bf22d2f5c56349631cab0c,dbd47bb9caf2158feb03621657ed3f67ac5f514e..4f436220384f847bbdee53cd7a8bce5fa089da61
@@@ -748,21 -767,86 +765,99 @@@ config ARM64_LSE_ATOMIC
          not support these instructions and requires the kernel to be
          built with binutils >= 2.25.
  
 +config ARM64_VHE
 +      bool "Enable support for Virtualization Host Extensions (VHE)"
 +      default y
 +      help
 +        Virtualization Host Extensions (VHE) allow the kernel to run
 +        directly at EL2 (instead of EL1) on processors that support
 +        it. This leads to better performance for KVM, as they reduce
 +        the cost of the world switch.
 +
 +        Selecting this option allows the VHE feature to be detected
 +        at runtime, and does not affect processors that do not
 +        implement this feature.
 +
  endmenu
  
+ menu "ARMv8.2 architectural features"
+ config ARM64_UAO
+       bool "Enable support for User Access Override (UAO)"
+       default y
+       help
+         User Access Override (UAO; part of the ARMv8.2 Extensions)
+         causes the 'unprivileged' variant of the load/store instructions to
+         be overriden to be privileged.
+         This option changes get_user() and friends to use the 'unprivileged'
+         variant of the load/store instructions. This ensures that user-space
+         really did have access to the supplied memory. When addr_limit is
+         set to kernel memory the UAO bit will be set, allowing privileged
+         access to kernel memory.
+         Choosing this option will cause copy_to_user() et al to use user-space
+         memory permissions.
+         The feature is detected at runtime, the kernel will use the
+         regular load/store instructions if the cpu does not implement the
+         feature.
+ endmenu
+ config ARM64_MODULE_CMODEL_LARGE
+       bool
+ config ARM64_MODULE_PLTS
+       bool
+       select ARM64_MODULE_CMODEL_LARGE
+       select HAVE_MOD_ARCH_SPECIFIC
+ config RELOCATABLE
+       bool
+       help
+         This builds the kernel as a Position Independent Executable (PIE),
+         which retains all relocation metadata required to relocate the
+         kernel binary at runtime to a different virtual address than the
+         address it was linked at.
+         Since AArch64 uses the RELA relocation format, this requires a
+         relocation pass at runtime even if the kernel is loaded at the
+         same address it was linked at.
+ config RANDOMIZE_BASE
+       bool "Randomize the address of the kernel image"
+       select ARM64_MODULE_PLTS
+       select RELOCATABLE
+       help
+         Randomizes the virtual address at which the kernel image is
+         loaded, as a security feature that deters exploit attempts
+         relying on knowledge of the location of kernel internals.
+         It is the bootloader's job to provide entropy, by passing a
+         random u64 value in /chosen/kaslr-seed at kernel entry.
+         When booting via the UEFI stub, it will invoke the firmware's
+         EFI_RNG_PROTOCOL implementation (if available) to supply entropy
+         to the kernel proper. In addition, it will randomise the physical
+         location of the kernel Image as well.
+         If unsure, say N.
+ config RANDOMIZE_MODULE_REGION_FULL
+       bool "Randomize the module region independently from the core kernel"
+       depends on RANDOMIZE_BASE
+       default y
+       help
+         Randomizes the location of the module region without considering the
+         location of the core kernel. This way, it is impossible for modules
+         to leak information about the location of core kernel data structures
+         but it does imply that function calls between modules and the core
+         kernel will need to be resolved via veneers in the module PLT.
+         When this option is not set, the module region will be randomized over
+         a limited range that contains the [_stext, _etext] interval of the
+         core kernel, so branch relocations are always in range.
  endmenu
  
  menu "Boot options"
Simple merge
index a5c769b1c65b9dbd0a34f381ee603f447421ba5e,f6f7423e51d0537026ae9803f9c25208bab112f6..b9b649422fca22f9f333ee4bc11b0addd24dc59c
  #define ARM64_HAS_LSE_ATOMICS                 5
  #define ARM64_WORKAROUND_CAVIUM_23154         6
  #define ARM64_WORKAROUND_834220                       7
- /* #define ARM64_HAS_NO_HW_PREFETCH           8 */
- /* #define ARM64_HAS_UAO                      9 */
- /* #define ARM64_ALT_PAN_NOT_UAO              10 */
+ #define ARM64_HAS_NO_HW_PREFETCH              8
+ #define ARM64_HAS_UAO                         9
+ #define ARM64_ALT_PAN_NOT_UAO                 10
 +#define ARM64_HAS_VIRT_HOST_EXTN              11
+ #define ARM64_WORKAROUND_CAVIUM_27456         12
  
- #define ARM64_NCAPS                           12
+ #define ARM64_NCAPS                           13
  
  #ifndef __ASSEMBLY__
  
Simple merge
Simple merge
Simple merge
Simple merge
index 819aff5d593f701d1101d4cc42dbec8cedbc80aa,e308807105e22c4b89238a3c3407e4716c28c6aa..989fef16d4614994829e81c9f10c614d039e5b86
  /*
   * VMALLOC and SPARSEMEM_VMEMMAP ranges.
   *
 - * VMEMAP_SIZE: allows the whole VA space to be covered by a struct page array
 + * VMEMAP_SIZE: allows the whole linear region to be covered by a struct page array
   *    (rounded up to PUD_SIZE).
-  * VMALLOC_START: beginning of the kernel VA space
+  * VMALLOC_START: beginning of the kernel vmalloc space
   * VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space,
   *    fixed mappings and modules
   */
  #define VMEMMAP_SIZE          ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE)
  
- #ifndef CONFIG_KASAN
- #define VMALLOC_START         (VA_START)
- #else
- #include <asm/kasan.h>
- #define VMALLOC_START         (KASAN_SHADOW_END + SZ_64K)
- #endif
+ #define VMALLOC_START         (MODULES_END)
  #define VMALLOC_END           (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
  
 -#define vmemmap                       ((struct page *)(VMALLOC_END + SZ_64K))
 +#define VMEMMAP_START         (VMALLOC_END + SZ_64K)
 +#define vmemmap                       ((struct page *)VMEMMAP_START - \
 +                               SECTION_ALIGN_DOWN(memstart_addr >> PAGE_SHIFT))
  
  #define FIRST_USER_ADDRESS    0UL
  
Simple merge
index ba745199297e3b086d0b28320305f4f8885eb48e,392c67eb9fa641170f2121f2a929e5abf8eb2f68..943f5140e0f33d592a78d179b8c8d68e5851e837
  #include <asm/cpu.h>
  #include <asm/cpufeature.h>
  #include <asm/cpu_ops.h>
+ #include <asm/mmu_context.h>
  #include <asm/processor.h>
  #include <asm/sysreg.h>
 +#include <asm/virt.h>
  
  unsigned long elf_hwcap __read_mostly;
  EXPORT_SYMBOL_GPL(elf_hwcap);
@@@ -622,11 -647,18 +648,23 @@@ static bool has_useable_gicv3_cpuif(con
        return has_sre;
  }
  
+ static bool has_no_hw_prefetch(const struct arm64_cpu_capabilities *entry)
+ {
+       u32 midr = read_cpuid_id();
+       u32 rv_min, rv_max;
+       /* Cavium ThunderX pass 1.x and 2.x */
+       rv_min = 0;
+       rv_max = (1 << MIDR_VARIANT_SHIFT) | MIDR_REVISION_MASK;
+       return MIDR_IS_CPU_MODEL_RANGE(midr, MIDR_THUNDERX, rv_min, rv_max);
+ }
 +static bool runs_at_el2(const struct arm64_cpu_capabilities *entry)
 +{
 +      return is_kernel_in_hyp_mode();
 +}
 +
  static const struct arm64_cpu_capabilities arm64_features[] = {
        {
                .desc = "GIC system register CPU interface",
                .min_field_value = 2,
        },
  #endif /* CONFIG_AS_LSE && CONFIG_ARM64_LSE_ATOMICS */
+       {
+               .desc = "Software prefetching using PRFM",
+               .capability = ARM64_HAS_NO_HW_PREFETCH,
+               .matches = has_no_hw_prefetch,
+       },
+ #ifdef CONFIG_ARM64_UAO
+       {
+               .desc = "User Access Override",
+               .capability = ARM64_HAS_UAO,
+               .matches = has_cpuid_feature,
+               .sys_reg = SYS_ID_AA64MMFR2_EL1,
+               .field_pos = ID_AA64MMFR2_UAO_SHIFT,
+               .min_field_value = 1,
+               .enable = cpu_enable_uao,
+       },
+ #endif /* CONFIG_ARM64_UAO */
+ #ifdef CONFIG_ARM64_PAN
+       {
+               .capability = ARM64_ALT_PAN_NOT_UAO,
+               .matches = cpufeature_pan_not_uao,
+       },
+ #endif /* CONFIG_ARM64_PAN */
 +      {
 +              .desc = "Virtualization Host Extensions",
 +              .capability = ARM64_HAS_VIRT_HOST_EXTN,
 +              .matches = runs_at_el2,
 +      },
        {},
  };
  
Simple merge
index 6f2f37743d3b34994b9d91fb1f99890910accbad,50c2134a4aaffc99989f4ab71a3c8fd86271ffa7..6ebd204da16ab680fc66cf1669536170e495bc3a
@@@ -29,8 -29,8 +29,9 @@@
  #include <asm/asm-offsets.h>
  #include <asm/cache.h>
  #include <asm/cputype.h>
+ #include <asm/elf.h>
  #include <asm/kernel-pgtable.h>
 +#include <asm/kvm_arm.h>
  #include <asm/memory.h>
  #include <asm/pgtable-hwdef.h>
  #include <asm/pgtable.h>
Simple merge
Simple merge
Simple merge
index 0689a74e6ba0b493ffc669448e34b34579c9f5ec,870578f84b1ca8940d47a9ea2a90b1600a1148e1..48f19a37b3df552a08db7b186a65ae4fad4b32e4
  
  #include <linux/linkage.h>
  
 +#include <asm/alternative.h>
  #include <asm/assembler.h>
 +#include <asm/cpufeature.h>
  
  /*
-  * u64 kvm_call_hyp(void *hypfn, ...);
+  * u64 __kvm_call_hyp(void *hypfn, ...);
   *
   * This is not really a variadic function in the classic C-way and care must
   * be taken when calling this to ensure parameters are passed in registers
   * used to implement __hyp_get_vectors in the same way as in
   * arch/arm64/kernel/hyp_stub.S.
   */
- ENTRY(kvm_call_hyp)
+ ENTRY(__kvm_call_hyp)
 +alternative_if_not ARM64_HAS_VIRT_HOST_EXTN   
        hvc     #0
        ret
- ENDPROC(kvm_call_hyp)
 +alternative_else
 +      b       __vhe_hyp_call
 +      nop
 +alternative_endif
+ ENDPROC(__kvm_call_hyp)
index 053cf8b057c19d556c8fccacd41374abe0fc449f,2f8bca8af295b9029ba5780307d2a680495d08fb..33342a776ec75845069a93381a3465cdf435509a
  #include <linux/compiler.h>
  #include <linux/kvm_host.h>
  
+ #include <asm/debug-monitors.h>
  #include <asm/kvm_asm.h>
 -#include <asm/kvm_mmu.h>
 -
 -#include "hyp.h"
 +#include <asm/kvm_hyp.h>
  
  #define read_debug(r,n)               read_sysreg(r##n##_el1)
  #define write_debug(v,r,n)    write_sysreg(v, r##n##_el1)
Simple merge
Simple merge
index 7802f216a67a588ab778b7d2b7649a2979e68b87,8c3d7dd91c25c237a5b8fc400bf1f6294adeec1e..61a38eaf0895c5db483594a6411cc9b460761cb4
@@@ -317,11 -382,16 +382,16 @@@ void __init mem_init(void
  #ifdef CONFIG_KASAN
                  MLG(KASAN_SHADOW_START, KASAN_SHADOW_END),
  #endif
+                 MLM(MODULES_VADDR, MODULES_END),
                  MLG(VMALLOC_START, VMALLOC_END),
+                 MLK_ROUNDUP(_text, __start_rodata),
+                 MLK_ROUNDUP(__start_rodata, _etext),
+                 MLK_ROUNDUP(__init_begin, __init_end),
+                 MLK_ROUNDUP(_sdata, _edata),
  #ifdef CONFIG_SPARSEMEM_VMEMMAP
 -                MLG((unsigned long)vmemmap,
 -                    (unsigned long)vmemmap + VMEMMAP_SIZE),
 +                MLG(VMEMMAP_START,
 +                    VMEMMAP_START + VMEMMAP_SIZE),
-                 MLM((unsigned long)virt_to_page(PAGE_OFFSET),
+                 MLM((unsigned long)phys_to_page(memblock_start_of_DRAM()),
                      (unsigned long)virt_to_page(high_memory)),
  #endif
                  MLK(FIXADDR_START, FIXADDR_TOP),
Simple merge
Simple merge
index 7b29fb14f870283ae4174e34643640150f7e098b,19d83647846cf5213157e5d99fab9ed8a8a70757..62a1822e0f41beece4606304c4ce0412bbd5e4cb
@@@ -310,10 -281,8 +310,11 @@@ do_file(char const *const fname
                break;
        case EM_386:
        case EM_X86_64:
 +              custom_sort = x86_sort_relative_table;
 +              break;
 +
        case EM_S390:
+       case EM_AARCH64:
                custom_sort = sort_relative_table;
                break;
        case EM_ARCOMPACT: