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();
  }
        /*
         * 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;
        }
  
        /*
 
          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"
 
  #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__
  
 
  /*
   * 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
  
 
  #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);
        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,
 +      },
        {},
  };
  
 
  #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>
 
  
  #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)
 
  #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)
 
  #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),
 
                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: