]> Git Repo - J-linux.git/commitdiff
Merge branches 'for-next/kvm-build-fix', 'for-next/va-refactor', 'for-next/lto',...
authorCatalin Marinas <[email protected]>
Wed, 9 Dec 2020 18:04:35 +0000 (18:04 +0000)
committerCatalin Marinas <[email protected]>
Wed, 9 Dec 2020 18:04:35 +0000 (18:04 +0000)
* for-next/kvm-build-fix:
  : Fix KVM build issues with 64K pages
  KVM: arm64: Fix build error in user_mem_abort()

* for-next/va-refactor:
  : VA layout changes
  arm64: mm: don't assume struct page is always 64 bytes
  Documentation/arm64: fix RST layout of memory.rst
  arm64: mm: tidy up top of kernel VA space
  arm64: mm: make vmemmap region a projection of the linear region
  arm64: mm: extend linear region for 52-bit VA configurations

* for-next/lto:
  : Upgrade READ_ONCE() to RCpc acquire on arm64 with LTO
  arm64: lto: Strengthen READ_ONCE() to acquire when CONFIG_LTO=y
  arm64: alternatives: Remove READ_ONCE() usage during patch operation
  arm64: cpufeatures: Add capability for LDAPR instruction
  arm64: alternatives: Split up alternative.h
  arm64: uaccess: move uao_* alternatives to asm-uaccess.h

* for-next/mem-hotplug:
  : Memory hotplug improvements
  arm64/mm/hotplug: Ensure early memory sections are all online
  arm64/mm/hotplug: Enable MEM_OFFLINE event handling
  arm64/mm/hotplug: Register boot memory hot remove notifier earlier
  arm64: mm: account for hotplug memory when randomizing the linear region

* for-next/cppc-ffh:
  : Add CPPC FFH support using arm64 AMU counters
  arm64: abort counter_read_on_cpu() when irqs_disabled()
  arm64: implement CPPC FFH support using AMUs
  arm64: split counter validation function
  arm64: wrap and generalise counter read functions

* for-next/pad-image-header:
  : Pad Image header to 64KB and unmap it
  arm64: head: tidy up the Image header definition
  arm64/head: avoid symbol names pointing into first 64 KB of kernel image
  arm64: omit [_text, _stext) from permanent kernel mapping

* for-next/zone-dma-default-32-bit:
  : Default to 32-bit wide ZONE_DMA (previously reduced to 1GB for RPi4)
  of: unittest: Fix build on architectures without CONFIG_OF_ADDRESS
  mm: Remove examples from enum zone_type comment
  arm64: mm: Set ZONE_DMA size based on early IORT scan
  arm64: mm: Set ZONE_DMA size based on devicetree's dma-ranges
  of: unittest: Add test for of_dma_get_max_cpu_address()
  of/address: Introduce of_dma_get_max_cpu_address()
  arm64: mm: Move zone_dma_bits initialization into zone_sizes_init()
  arm64: mm: Move reserve_crashkernel() into mem_init()
  arm64: Force NO_BLOCK_MAPPINGS if crashkernel reservation is required
  arm64: Ignore any DMA offsets in the max_zone_phys() calculation

* for-next/signal-tag-bits:
  : Expose the FAR_EL1 tag bits in siginfo
  arm64: expose FAR_EL1 tag bits in siginfo
  signal: define the SA_EXPOSE_TAGBITS bit in sa_flags
  signal: define the SA_UNSUPPORTED bit in sa_flags
  arch: provide better documentation for the arch-specific SA_* flags
  signal: clear non-uapi flag bits when passing/returning sa_flags
  arch: move SA_* definitions to generic headers
  parisc: start using signal-defs.h
  parisc: Drop parisc special case for __sighandler_t

* for-next/cmdline-extended:
  : Add support for CONFIG_CMDLINE_EXTENDED
  arm64: Extend the kernel command line from the bootloader
  arm64: kaslr: Refactor early init command line parsing

1  2  3  4  5  6  7  8  9 
arch/arm64/Kconfig
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/vmlinux.lds.S
arch/arm64/kvm/mmu.c
arch/arm64/mm/init.c
arch/arm64/mm/mmu.c

diff --combined arch/arm64/Kconfig
index 51259274a819aac5013b967195f4add0554e906e,c6092cbb39af113c689492681d9f04511dbe23b2,0f8b2e35ba993e51a5df074a6580edb96e0c33fc,1515f6f153a0dc9a3ebc4220442686138a9f7859,1515f6f153a0dc9a3ebc4220442686138a9f7859,1515f6f153a0dc9a3ebc4220442686138a9f7859,1515f6f153a0dc9a3ebc4220442686138a9f7859,1515f6f153a0dc9a3ebc4220442686138a9f7859,b5f5a9f41795b5a74f2c8dda669f780b2eeb8108..2272a95057275e6f09758b3339e352c7ac16c96c
@@@@@@@@@@ -29,6 -29,7 -29,7 -29,7 -29,7 -29,7 -29,7 -29,7 -29,7 +29,7 @@@@@@@@@@ config ARM6
                select ARCH_HAS_SETUP_DMA_OPS
                select ARCH_HAS_SET_DIRECT_MAP
                select ARCH_HAS_SET_MEMORY
+               select ARCH_STACKWALK
                select ARCH_HAS_STRICT_KERNEL_RWX
                select ARCH_HAS_STRICT_MODULE_RWX
                select ARCH_HAS_SYNC_DMA_FOR_DEVICE
                select GENERIC_CPU_VULNERABILITIES
                select GENERIC_EARLY_IOREMAP
                select GENERIC_IDLE_POLL_SETUP
+               select GENERIC_IRQ_IPI
                select GENERIC_IRQ_MULTI_HANDLER
                select GENERIC_IRQ_PROBE
                select GENERIC_IRQ_SHOW
                select GENERIC_VDSO_TIME_NS
                select HANDLE_DOMAIN_IRQ
                select HARDIRQS_SW_RESEND
+               select HAVE_MOVE_PMD
                select HAVE_PCI
                select HAVE_ACPI_APEI if (ACPI && EFI)
                select HAVE_ALIGNED_STRUCT_PAGE if SLUB
                select PCI_SYSCALL if PCI
                select POWER_RESET
                select POWER_SUPPLY
+               select SET_FS
                select SPARSE_IRQ
                select SWIOTLB
                select SYSCTL_EXCEPTION_TRACE
@@@@@@@@@@ -211,12 -215,18 -215,18 -215,18 -215,18 -215,18 -215,18 -215,18 -215,18 +215,18 @@@@@@@@@@ config ARM64_PAGE_SHIF
                default 14 if ARM64_16K_PAGES
                default 12
         
-        config ARM64_CONT_SHIFT
+        config ARM64_CONT_PTE_SHIFT
                int
                default 5 if ARM64_64K_PAGES
                default 7 if ARM64_16K_PAGES
                default 4
         
+        config ARM64_CONT_PMD_SHIFT
+               int
+               default 5 if ARM64_64K_PAGES
+               default 5 if ARM64_16K_PAGES
+               default 4
+        
         config ARCH_MMAP_RND_BITS_MIN
                default 14 if ARM64_64K_PAGES
                default 16 if ARM64_16K_PAGES
@@@@@@@@@@ -321,16 -331,16 -331,16 -331,16 -331,16 -331,16 -331,16 -331,16 -331,16 +331,16 @@@@@@@@@@ config BROKEN_GAS_INS
         config KASAN_SHADOW_OFFSET
                hex
                depends on KASAN
- -------       default 0xdfffa00000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && !KASAN_SW_TAGS
- -------       default 0xdfffd00000000000 if ARM64_VA_BITS_47 && !KASAN_SW_TAGS
- -------       default 0xdffffe8000000000 if ARM64_VA_BITS_42 && !KASAN_SW_TAGS
- -------       default 0xdfffffd000000000 if ARM64_VA_BITS_39 && !KASAN_SW_TAGS
- -------       default 0xdffffffa00000000 if ARM64_VA_BITS_36 && !KASAN_SW_TAGS
- -------       default 0xefff900000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && KASAN_SW_TAGS
- -------       default 0xefffc80000000000 if ARM64_VA_BITS_47 && KASAN_SW_TAGS
- -------       default 0xeffffe4000000000 if ARM64_VA_BITS_42 && KASAN_SW_TAGS
- -------       default 0xefffffc800000000 if ARM64_VA_BITS_39 && KASAN_SW_TAGS
- -------       default 0xeffffff900000000 if ARM64_VA_BITS_36 && KASAN_SW_TAGS
+ +++++++       default 0xdfff800000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && !KASAN_SW_TAGS
+ +++++++       default 0xdfffc00000000000 if ARM64_VA_BITS_47 && !KASAN_SW_TAGS
+ +++++++       default 0xdffffe0000000000 if ARM64_VA_BITS_42 && !KASAN_SW_TAGS
+ +++++++       default 0xdfffffc000000000 if ARM64_VA_BITS_39 && !KASAN_SW_TAGS
+ +++++++       default 0xdffffff800000000 if ARM64_VA_BITS_36 && !KASAN_SW_TAGS
+ +++++++       default 0xefff800000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && KASAN_SW_TAGS
+ +++++++       default 0xefffc00000000000 if ARM64_VA_BITS_47 && KASAN_SW_TAGS
+ +++++++       default 0xeffffe0000000000 if ARM64_VA_BITS_42 && KASAN_SW_TAGS
+ +++++++       default 0xefffffc000000000 if ARM64_VA_BITS_39 && KASAN_SW_TAGS
+ +++++++       default 0xeffffff800000000 if ARM64_VA_BITS_36 && KASAN_SW_TAGS
                default 0xffffffffffffffff
         
         source "arch/arm64/Kconfig.platforms"
@@@@@@@@@@ -626,6 -636,26 -636,26 -636,26 -636,26 -636,26 -636,26 -636,26 -636,26 +636,26 @@@@@@@@@@ config ARM64_ERRATUM_154241
         
                  If unsure, say Y.
         
+        config ARM64_ERRATUM_1508412
+               bool "Cortex-A77: 1508412: workaround deadlock on sequence of NC/Device load and store exclusive or PAR read"
+               default y
+               help
+                 This option adds a workaround for Arm Cortex-A77 erratum 1508412.
+        
+                 Affected Cortex-A77 cores (r0p0, r1p0) could deadlock on a sequence
+                 of a store-exclusive or read of PAR_EL1 and a load with device or
+                 non-cacheable memory attributes. The workaround depends on a firmware
+                 counterpart.
+        
+                 KVM guests must also have the workaround implemented or they can
+                 deadlock the system.
+        
+                 Work around the issue by inserting DMB SY barriers around PAR_EL1
+                 register reads and warning KVM users. The DMB barrier is sufficient
+                 to prevent a speculative PAR_EL1 read.
+        
+                 If unsure, say Y.
+        
         config CAVIUM_ERRATUM_22375
                bool "Cavium erratum 22375, 24313"
                default y
         config NODES_SHIFT
                int "Maximum NUMA Nodes (as a power of 2)"
                range 1 10
-               default "2"
+               default "4"
                depends on NEED_MULTIPLE_NODES
                help
                  Specify the maximum number of NUMA Nodes available on the target
@@@@@@@@@@ -1033,19 -1063,6 -1063,6 -1063,6 -1063,6 -1063,6 -1063,6 -1063,6 -1063,6 +1063,6 @@@@@@@@@@ config ARCH_ENABLE_SPLIT_PMD_PTLOC
         config CC_HAVE_SHADOW_CALL_STACK
                def_bool $(cc-option, -fsanitize=shadow-call-stack -ffixed-x18)
         
-        config SECCOMP
-               bool "Enable seccomp to safely compute untrusted bytecode"
-               help
-                 This kernel feature is useful for number crunching applications
-                 that may need to compute untrusted bytecode during their
-                 execution. By using pipes or other transports made available to
-                 the process as file descriptors supporting the read/write
-                 syscalls, it's possible to isolate those applications in
-                 their own address space using seccomp. Once seccomp is
-                 enabled via prctl(PR_SET_SECCOMP), it cannot be disabled
-                 and the task is only allowed to execute a few safe syscalls
-                 defined by each seccomp mode.
-        
         config PARAVIRT
                bool "Enable paravirtualization code"
                help
@@@@@@@@@@ -1371,6 -1388,6 -1388,9 -1388,6 -1388,6 -1388,6 -1388,6 -1388,6 -1388,6 +1388,9 @@@@@@@@@@ config ARM64_PA
                 The feature is detected at runtime, and will remain as a 'nop'
                 instruction if the cpu does not implement the feature.
         
++ ++++++config AS_HAS_LDAPR
++ ++++++       def_bool $(as-instr,.arch_extension rcpc)
++ ++++++
         config ARM64_LSE_ATOMICS
                bool
                default ARM64_USE_LSE_ATOMICS
@@@@@@@@@@ -1604,8 -1621,6 -1624,6 -1621,6 -1621,6 -1621,6 -1621,6 -1621,6 -1621,6 +1624,6 @@@@@@@@@@ config ARM64_BTI_KERNE
                depends on CC_HAS_BRANCH_PROT_PAC_RET_BTI
                # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94697
                depends on !CC_IS_GCC || GCC_VERSION >= 100100
-               # https://reviews.llvm.org/rGb8ae3fdfa579dbf366b1bb1cbfdbf8c51db7fa55
-               depends on !CC_IS_CLANG || CLANG_VERSION >= 100001
                depends on !(CC_IS_CLANG && GCOV_KERNEL)
                depends on (!FUNCTION_GRAPH_TRACER || DYNAMIC_FTRACE_WITH_REGS)
                help
                  provides a high bandwidth, cryptographically secure
                  hardware random number generator.
         
+        config ARM64_AS_HAS_MTE
+               # Initial support for MTE went in binutils 2.32.0, checked with
+               # ".arch armv8.5-a+memtag" below. However, this was incomplete
+               # as a late addition to the final architecture spec (LDGM/STGM)
+               # is only supported in the newer 2.32.x and 2.33 binutils
+               # versions, hence the extra "stgm" instruction check below.
+               def_bool $(as-instr,.arch armv8.5-a+memtag\nstgm xzr$(comma)[x0])
+        
+        config ARM64_MTE
+               bool "Memory Tagging Extension support"
+               default y
+               depends on ARM64_AS_HAS_MTE && ARM64_TAGGED_ADDR_ABI
+               select ARCH_USES_HIGH_VMA_FLAGS
+               help
+                 Memory Tagging (part of the ARMv8.5 Extensions) provides
+                 architectural support for run-time, always-on detection of
+                 various classes of memory error to aid with software debugging
+                 to eliminate vulnerabilities arising from memory-unsafe
+                 languages.
+        
+                 This option enables the support for the Memory Tagging
+                 Extension at EL0 (i.e. for userspace).
+        
+                 Selecting this option allows the feature to be detected at
+                 runtime. Any secondary CPU not implementing this feature will
+                 not be allowed a late bring-up.
+        
+                 Userspace binaries that want to use this feature must
+                 explicitly opt in. The mechanism for the userspace is
+                 described in:
+        
+                 Documentation/arm64/memory-tagging-extension.rst.
+        
         endmenu
         
         config ARM64_SVE
                  entering them here. As a minimum, you should specify the the
                  root device (e.g. root=/dev/nfs).
         
++++++++ choice
++++++++        prompt "Kernel command line type" if CMDLINE != ""
++++++++        default CMDLINE_FROM_BOOTLOADER
++++++++        help
++++++++          Choose how the kernel will handle the provided default kernel
++++++++          command line string.
++++++++ 
++++++++ config CMDLINE_FROM_BOOTLOADER
++++++++        bool "Use bootloader kernel arguments if available"
++++++++        help
++++++++          Uses the command-line options passed by the boot loader. If
++++++++          the boot loader doesn't provide any, the default kernel command
++++++++          string provided in CMDLINE will be used.
++++++++ 
++++++++ config CMDLINE_EXTEND
++++++++        bool "Extend bootloader kernel arguments"
++++++++        help
++++++++          The command-line arguments provided by the boot loader will be
++++++++          appended to the default kernel command string.
++++++++ 
         config CMDLINE_FORCE
                bool "Always use the default kernel command string"
--------        depends on CMDLINE != ""
                help
                  Always use the default kernel command string, even if the boot
                  loader passes other arguments to the kernel.
                  This is useful if you cannot or don't want to change the
                  command-line options your boot loader passes to the kernel.
         
++++++++ endchoice
++++++++ 
         config EFI_STUB
                bool
         
@@@@@@@@@@ -1850,6 -1898,10 -1901,10 -1898,10 -1898,10 -1898,10 -1898,10 -1898,10 -1919,10 +1922,10 @@@@@@@@@@ config ARCH_ENABLE_HUGEPAGE_MIGRATIO
                def_bool y
                depends on HUGETLB_PAGE && MIGRATION
         
+        config ARCH_ENABLE_THP_MIGRATION
+               def_bool y
+               depends on TRANSPARENT_HUGEPAGE
+        
         menu "Power management options"
         
         source "kernel/power/Kconfig"
index a4debb63ebfbf329d9e6b006b3029b933a382aaf,dcc165b3fc046b8573a579f04dd3e71474c7c471,b7b6804cb9312977402e1b073b164c59592edf9d,dcc165b3fc046b8573a579f04dd3e71474c7c471,6b08ae74ad0aa6c6f2a1f09b5aa4bda9ecac1dc8,dcc165b3fc046b8573a579f04dd3e71474c7c471,dcc165b3fc046b8573a579f04dd3e71474c7c471,dcc165b3fc046b8573a579f04dd3e71474c7c471,dcc165b3fc046b8573a579f04dd3e71474c7c471..bffcd55668c7fe4ff3c4feb250780af2494d6a8b
         #include <asm/cpu_ops.h>
         #include <asm/fpsimd.h>
         #include <asm/mmu_context.h>
+        #include <asm/mte.h>
         #include <asm/processor.h>
         #include <asm/sysreg.h>
         #include <asm/traps.h>
@@@@@@@@@@ -197,9 -198,9 -198,9 -198,9 -198,9 -198,9 -198,9 -198,9 -198,9 +198,9 @@@@@@@@@@ static const struct arm64_ftr_bits ftr_
                ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_FCMA_SHIFT, 4, 0),
                ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_JSCVT_SHIFT, 4, 0),
                ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),
-                              FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_API_SHIFT, 4, 0),
+                              FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_API_SHIFT, 4, 0),
                ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),
-                              FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_APA_SHIFT, 4, 0),
+                              FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_APA_SHIFT, 4, 0),
                ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_DPB_SHIFT, 4, 0),
                ARM64_FTR_END,
         };
@@@@@@@@@@ -227,6 -228,8 -228,8 -228,8 -228,8 -228,8 -228,8 -228,8 -228,8 +228,8 @@@@@@@@@@ static const struct arm64_ftr_bits ftr_
         static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
                ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_MPAMFRAC_SHIFT, 4, 0),
                ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_RASFRAC_SHIFT, 4, 0),
+               ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_MTE),
+                              FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_MTE_SHIFT, 4, ID_AA64PFR1_MTE_NI),
                ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR1_SSBS_SHIFT, 4, ID_AA64PFR1_SSBS_PSTATE_NI),
                ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_BTI),
                                            FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_BT_SHIFT, 4, 0),
@@@@@@@@@@ -1111,6 -1114,7 -1114,7 -1114,7 -1114,7 -1114,7 -1114,7 -1114,7 -1114,7 +1114,7 @@@@@@@@@@ u64 read_sanitised_ftr_reg(u32 id
                        return 0;
                return regp->sys_val;
         }
+        EXPORT_SYMBOL_GPL(read_sanitised_ftr_reg);
         
         #define read_sysreg_case(r)    \
                case r:         return read_sysreg_s(r)
@@@@@@@@@@ -1443,6 -1447,7 -1447,7 -1447,7 -1447,7 -1447,7 -1447,7 -1447,7 -1447,7 +1447,7 @@@@@@@@@@ static inline void __cpu_enable_hw_dbm(
         
                write_sysreg(tcr, tcr_el1);
                isb();
+               local_flush_tlb_all();
         }
         
         static bool cpu_has_broken_dbm(void)
@@@@@@@@@@ -1521,8 -1526,8 -1526,8 -1526,8 -1526,10 -1526,8 -1526,8 -1526,8 -1526,8 +1526,10 @@@@@@@@@@ bool cpu_has_amu_feat(int cpu
                return cpumask_test_cpu(cpu, &amu_cpus);
         }
         
---- ----/* Initialize the use of AMU counters for frequency invariance */
---- ----extern void init_cpu_freq_invariance_counters(void);
++++ ++++int get_cpu_with_amu_feat(void)
++++ ++++{
++++ ++++       return cpumask_any(&amu_cpus);
++++ ++++}
         
         static void cpu_amu_enable(struct arm64_cpu_capabilities const *cap)
         {
                        pr_info("detected CPU%d: Activity Monitors Unit (AMU)\n",
                                smp_processor_id());
                        cpumask_set_cpu(smp_processor_id(), &amu_cpus);
---- ----               init_cpu_freq_invariance_counters();
++++ ++++               update_freq_counters_refs();
                }
         }
         
@@@@@@@@@@ -1552,6 -1557,6 -1557,6 -1557,6 -1559,11 -1557,6 -1557,6 -1557,6 -1557,6 +1559,11 @@@@@@@@@@ static bool has_amu(const struct arm64_
         
                return true;
         }
++++ ++++#else
++++ ++++int get_cpu_with_amu_feat(void)
++++ ++++{
++++ ++++       return nr_cpu_ids;
++++ ++++}
         #endif
         
         #ifdef CONFIG_ARM64_VHE
@@@@@@@@@@ -1606,11 -1611,37 -1611,37 -1611,37 -1618,37 -1611,37 -1611,37 -1611,37 -1611,37 +1618,37 @@@@@@@@@@ static void cpu_clear_disr(const struc
         #endif /* CONFIG_ARM64_RAS_EXTN */
         
         #ifdef CONFIG_ARM64_PTR_AUTH
-        static bool has_address_auth(const struct arm64_cpu_capabilities *entry,
-                                    int __unused)
+        static bool has_address_auth_cpucap(const struct arm64_cpu_capabilities *entry, int scope)
         {
-               return __system_matches_cap(ARM64_HAS_ADDRESS_AUTH_ARCH) ||
-                      __system_matches_cap(ARM64_HAS_ADDRESS_AUTH_IMP_DEF);
+               int boot_val, sec_val;
+        
+               /* We don't expect to be called with SCOPE_SYSTEM */
+               WARN_ON(scope == SCOPE_SYSTEM);
+               /*
+                * The ptr-auth feature levels are not intercompatible with lower
+                * levels. Hence we must match ptr-auth feature level of the secondary
+                * CPUs with that of the boot CPU. The level of boot cpu is fetched
+                * from the sanitised register whereas direct register read is done for
+                * the secondary CPUs.
+                * The sanitised feature state is guaranteed to match that of the
+                * boot CPU as a mismatched secondary CPU is parked before it gets
+                * a chance to update the state, with the capability.
+                */
+               boot_val = cpuid_feature_extract_field(read_sanitised_ftr_reg(entry->sys_reg),
+                                                      entry->field_pos, entry->sign);
+               if (scope & SCOPE_BOOT_CPU)
+                       return boot_val >= entry->min_field_value;
+               /* Now check for the secondary CPUs with SCOPE_LOCAL_CPU scope */
+               sec_val = cpuid_feature_extract_field(__read_sysreg_by_encoding(entry->sys_reg),
+                                                     entry->field_pos, entry->sign);
+               return sec_val == boot_val;
+        }
+        
+        static bool has_address_auth_metacap(const struct arm64_cpu_capabilities *entry,
+                                            int scope)
+        {
+               return has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_ARCH], scope) ||
+                      has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_IMP_DEF], scope);
         }
         
         static bool has_generic_auth(const struct arm64_cpu_capabilities *entry,
@@@@@@@@@@ -1660,6 -1691,22 -1691,22 -1691,22 -1698,22 -1691,22 -1691,22 -1691,22 -1691,22 +1698,22 @@@@@@@@@@ static void bti_enable(const struct arm
         }
         #endif /* CONFIG_ARM64_BTI */
         
+        #ifdef CONFIG_ARM64_MTE
+        static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
+        {
+               static bool cleared_zero_page = false;
+        
+               /*
+                * Clear the tags in the zero page. This needs to be done via the
+                * linear map which has the Tagged attribute.
+                */
+               if (!cleared_zero_page) {
+                       cleared_zero_page = true;
+                       mte_clear_page_tags(lm_alias(empty_zero_page));
+               }
+        }
+        #endif /* CONFIG_ARM64_MTE */
+        
         /* Internal helper functions to match cpu capability type */
         static bool
         cpucap_late_cpu_optional(const struct arm64_cpu_capabilities *cap)
@@@@@@@@@@ -1976,7 -2023,7 -2023,7 -2023,7 -2030,7 -2023,7 -2023,7 -2023,7 -2023,7 +2030,7 @@@@@@@@@@ static const struct arm64_cpu_capabilit
                        .sign = FTR_UNSIGNED,
                        .field_pos = ID_AA64ISAR1_APA_SHIFT,
                        .min_field_value = ID_AA64ISAR1_APA_ARCHITECTED,
-                       .matches = has_cpuid_feature,
+                       .matches = has_address_auth_cpucap,
                },
                {
                        .desc = "Address authentication (IMP DEF algorithm)",
                        .sign = FTR_UNSIGNED,
                        .field_pos = ID_AA64ISAR1_API_SHIFT,
                        .min_field_value = ID_AA64ISAR1_API_IMP_DEF,
-                       .matches = has_cpuid_feature,
+                       .matches = has_address_auth_cpucap,
                },
                {
                        .capability = ARM64_HAS_ADDRESS_AUTH,
                        .type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
-                       .matches = has_address_auth,
+                       .matches = has_address_auth_metacap,
                },
                {
                        .desc = "Generic authentication (architected algorithm)",
                        .sign = FTR_UNSIGNED,
                },
         #endif
+        #ifdef CONFIG_ARM64_MTE
+               {
+                       .desc = "Memory Tagging Extension",
+                       .capability = ARM64_MTE,
+                       .type = ARM64_CPUCAP_STRICT_BOOT_CPU_FEATURE,
+                       .matches = has_cpuid_feature,
+                       .sys_reg = SYS_ID_AA64PFR1_EL1,
+                       .field_pos = ID_AA64PFR1_MTE_SHIFT,
+                       .min_field_value = ID_AA64PFR1_MTE,
+                       .sign = FTR_UNSIGNED,
+                       .cpu_enable = cpu_enable_mte,
+               },
+        #endif /* CONFIG_ARM64_MTE */
++ ++++++       {
++ ++++++               .desc = "RCpc load-acquire (LDAPR)",
++ ++++++               .capability = ARM64_HAS_LDAPR,
++ ++++++               .type = ARM64_CPUCAP_SYSTEM_FEATURE,
++ ++++++               .sys_reg = SYS_ID_AA64ISAR1_EL1,
++ ++++++               .sign = FTR_UNSIGNED,
++ ++++++               .field_pos = ID_AA64ISAR1_LRCPC_SHIFT,
++ ++++++               .matches = has_cpuid_feature,
++ ++++++               .min_field_value = 1,
++ ++++++       },
                {},
         };
         
@@@@@@@@@@ -2192,6 -2252,9 -2262,9 -2252,9 -2259,9 -2252,9 -2252,9 -2252,9 -2252,9 +2269,9 @@@@@@@@@@ static const struct arm64_cpu_capabilit
                HWCAP_MULTI_CAP(ptr_auth_hwcap_addr_matches, CAP_HWCAP, KERNEL_HWCAP_PACA),
                HWCAP_MULTI_CAP(ptr_auth_hwcap_gen_matches, CAP_HWCAP, KERNEL_HWCAP_PACG),
         #endif
+        #ifdef CONFIG_ARM64_MTE
+               HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE),
+        #endif /* CONFIG_ARM64_MTE */
                {},
         };
         
index d52e6b5dbfd3e95aa4d76addb44f0944898b0fb5,1bda604f4c704bd22f810c02fcacd60d720c43e4,d6cdcf4aa6a54d11e717d96387de229ea0c93aee,1bda604f4c704bd22f810c02fcacd60d720c43e4,1bda604f4c704bd22f810c02fcacd60d720c43e4,48b222f1c700d4d59eafe54149682fe8bfcd5f9f,1bda604f4c704bd22f810c02fcacd60d720c43e4,1bda604f4c704bd22f810c02fcacd60d720c43e4,1bda604f4c704bd22f810c02fcacd60d720c43e4..94a08e3e32b1c2e5e051ea70024609e0ad7de185
@@@@@@@@@@ -6,6 -6,7 -6,7 -6,7 -6,7 -6,7 -6,7 -6,7 -6,7 +6,7 @@@@@@@@@@
          */
         
         #define RO_EXCEPTION_TABLE_ALIGN       8
+        #define RUNTIME_DISCARD_EXIT
         
         #include <asm-generic/vmlinux.lds.h>
         #include <asm/cache.h>
                 * matching the same input section name.  There is no documented
                 * order of matching.
                 */
+               DISCARDS
                /DISCARD/ : {
-                       EXIT_CALL
-                       *(.discard)
-                       *(.discard.*)
                        *(.interp .dynamic)
                        *(.dynsym .dynstr .hash .gnu.hash)
-                       *(.eh_frame)
                }
         
-               . = KIMAGE_VADDR + TEXT_OFFSET;
+               . = KIMAGE_VADDR;
         
                .head.text : {
                        _text = .;
                        HEAD_TEXT
                }
----- ---       .text : {                       /* Real text segment            */
+++++ +++       .text : ALIGN(SEGMENT_ALIGN) {  /* Real text segment            */
                        _stext = .;             /* Text and read-only data      */
                                IRQENTRY_TEXT
                                SOFTIRQENTRY_TEXT
                        *(.got)                 /* Global offset table          */
                }
         
+               /*
+                * Make sure that the .got.plt is either completely empty or it
+                * contains only the lazy dispatch entries.
+                */
+               .got.plt : { *(.got.plt) }
+               ASSERT(SIZEOF(.got.plt) == 0 || SIZEOF(.got.plt) == 0x18,
+                      "Unexpected GOT/PLT entries detected!")
+        
                . = ALIGN(SEGMENT_ALIGN);
                _etext = .;                     /* End of text section */
         
                        INIT_CALLS
                        CON_INITCALL
                        INIT_RAM_FS
-- ------               *(.init.rodata.* .init.bss)     /* from the EFI stub */
++ ++++++               *(.init.altinstructions .init.rodata.* .init.bss)       /* from the EFI stub */
                }
                .exit.data : {
                        EXIT_DATA
                _end = .;
         
                STABS_DEBUG
+               DWARF_DEBUG
+               ELF_DETAILS
         
                HEAD_SYMBOLS
+        
+               /*
+                * Sections that should stay zero sized, which is safer to
+                * explicitly check instead of blindly discarding.
+                */
+               .plt : {
+                       *(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt)
+               }
+               ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
+        
+               .data.rel.ro : { *(.data.rel.ro) }
+               ASSERT(SIZEOF(.data.rel.ro) == 0, "Unexpected RELRO detected!")
         }
         
         #include "image-vars.h"
@@@@@@@@@@ -287,4 -307,4 -307,4 -307,4 -307,4 -307,4 -307,4 -307,4 -307,4 +307,4 @@@@@@@@@@ ASSERT((__entry_tramp_text_end - __entr
         /*
          * If padding is applied before .head.text, virt<->phys conversions will fail.
          */
-        ASSERT(_text == (KIMAGE_VADDR + TEXT_OFFSET), "HEAD is misaligned")
+        ASSERT(_text == KIMAGE_VADDR, "HEAD is misaligned")
diff --combined arch/arm64/kvm/mmu.c
index a109c500182787abc6f6b680f0a1cde21fd6eb28,57972bdb213ab25849e1df59c9bf51735031e9e9,57972bdb213ab25849e1df59c9bf51735031e9e9,57972bdb213ab25849e1df59c9bf51735031e9e9,57972bdb213ab25849e1df59c9bf51735031e9e9,57972bdb213ab25849e1df59c9bf51735031e9e9,57972bdb213ab25849e1df59c9bf51735031e9e9,57972bdb213ab25849e1df59c9bf51735031e9e9,57972bdb213ab25849e1df59c9bf51735031e9e9..1a01da9fdc99cd11a9912c31e4893d94cf070cb4
@@@@@@@@@@ -759,7 -759,7 -759,7 -759,7 -759,7 -759,7 -759,7 -759,7 -759,7 +759,7 @@@@@@@@@@ static int user_mem_abort(struct kvm_vc
                struct kvm_pgtable *pgt;
         
                write_fault = kvm_is_write_fault(vcpu);
-               exec_fault = kvm_vcpu_trap_is_iabt(vcpu);
+               exec_fault = kvm_vcpu_trap_is_exec_fault(vcpu);
                VM_BUG_ON(write_fault && exec_fault);
         
                if (fault_status == FSC_PERM && !write_fault && !exec_fault) {
                }
         
                switch (vma_shift) {
 ++++++++#ifndef __PAGETABLE_PMD_FOLDED
                case PUD_SHIFT:
                        if (fault_supports_stage2_huge_mapping(memslot, hva, PUD_SIZE))
                                break;
                        fallthrough;
 ++++++++#endif
                case CONT_PMD_SHIFT:
                        vma_shift = PMD_SHIFT;
                        fallthrough;
@@@@@@@@@@ -999,7 -997,7 -997,7 -997,7 -997,7 -997,7 -997,7 -997,7 -997,7 +999,7 @@@@@@@@@@ int kvm_handle_guest_abort(struct kvm_v
                                goto out;
                        }
         
-                       if (kvm_vcpu_dabt_iss1tw(vcpu)) {
+                       if (kvm_vcpu_abt_iss1tw(vcpu)) {
                                kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
                                ret = 1;
                                goto out_unlock;
diff --combined arch/arm64/mm/init.c
index 481d22c32a2e7fb08d0a061bb46a9ebe40414891,7e15d92836d8a1faf59013e4be0ea0c839f65242,095540667f0fdd7ed408202264ffd57d5c22d0da,93458820bc5355f5a87cd1e2d671fc78a6a09dec,095540667f0fdd7ed408202264ffd57d5c22d0da,aa438b9d7f408619cf2481ddd11bbc08f8058702,5e534d674c9c011fbb07abcb24306ab4ec9db7e6,095540667f0fdd7ed408202264ffd57d5c22d0da,095540667f0fdd7ed408202264ffd57d5c22d0da..fbd452e12397b6d8198ca0b3b6bd9385917ee328
         #include <linux/of.h>
         #include <linux/of_fdt.h>
         #include <linux/dma-direct.h>
-        #include <linux/dma-mapping.h>
-        #include <linux/dma-contiguous.h>
+        #include <linux/dma-map-ops.h>
         #include <linux/efi.h>
         #include <linux/swiotlb.h>
         #include <linux/vmalloc.h>
         #include <linux/kexec.h>
         #include <linux/crash_dump.h>
         #include <linux/hugetlb.h>
++++++ ++#include <linux/acpi_iort.h>
         
         #include <asm/boot.h>
         #include <asm/fixmap.h>
         #include <asm/tlb.h>
         #include <asm/alternative.h>
         
------ --#define ARM64_ZONE_DMA_BITS    30
------ --
         /*
          * We need to be able to catch inadvertent references to memstart_addr
          * that occur (potentially in generic code) before arm64_memblock_init()
         s64 memstart_addr __ro_after_init = -1;
         EXPORT_SYMBOL(memstart_addr);
         
-        s64 physvirt_offset __ro_after_init;
-        EXPORT_SYMBOL(physvirt_offset);
-        
-        struct page *vmemmap __ro_after_init;
-        EXPORT_SYMBOL(vmemmap);
-        
         /*
          * We create both ZONE_DMA and ZONE_DMA32. ZONE_DMA covers the first 1G of
          * memory as some devices, namely the Raspberry Pi 4, have peripherals with
@@@@@@@@@@ -182,21 -175,21 -175,21 -175,21 -175,21 -175,21 -174,34 -175,21 -175,21 +174,34 @@@@@@@@@@ static void __init reserve_elfcorehdr(v
         #endif /* CONFIG_CRASH_DUMP */
         
         /*
------ -- * Return the maximum physical address for a zone with a given address size
------ -- * limit. It currently assumes that for memory starting above 4G, 32-bit
------ -- * devices will use a DMA offset.
++++++ ++ * Return the maximum physical address for a zone accessible by the given bits
++++++ ++ * limit. If DRAM starts above 32-bit, expand the zone to the maximum
++++++ ++ * available memory, otherwise cap it at 32-bit.
          */
         static phys_addr_t __init max_zone_phys(unsigned int zone_bits)
         {
------ --       phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, zone_bits);
------ --       return min(offset + (1ULL << zone_bits), memblock_end_of_DRAM());
++++++ ++       phys_addr_t zone_mask = DMA_BIT_MASK(zone_bits);
++++++ ++       phys_addr_t phys_start = memblock_start_of_DRAM();
++++++ ++
++++++ ++       if (phys_start > U32_MAX)
++++++ ++               zone_mask = PHYS_ADDR_MAX;
++++++ ++       else if (phys_start > zone_mask)
++++++ ++               zone_mask = U32_MAX;
++++++ ++
++++++ ++       return min(zone_mask, memblock_end_of_DRAM() - 1) + 1;
         }
         
         static void __init zone_sizes_init(unsigned long min, unsigned long max)
         {
                unsigned long max_zone_pfns[MAX_NR_ZONES]  = {0};
++++++ ++       unsigned int __maybe_unused acpi_zone_dma_bits;
++++++ ++       unsigned int __maybe_unused dt_zone_dma_bits;
         
         #ifdef CONFIG_ZONE_DMA
++++++ ++       acpi_zone_dma_bits = fls64(acpi_iort_dma_get_max_cpu_address());
++++++ ++       dt_zone_dma_bits = fls64(of_dma_get_max_cpu_address(NULL));
++++++ ++       zone_dma_bits = min3(32U, dt_zone_dma_bits, acpi_zone_dma_bits);
++++++ ++       arm64_dma_phys_limit = max_zone_phys(zone_dma_bits);
                max_zone_pfns[ZONE_DMA] = PFN_DOWN(arm64_dma_phys_limit);
         #endif
         #ifdef CONFIG_ZONE_DMA32
@@@@@@@@@@ -276,7 -269,7 -269,7 -269,7 -269,7 -269,7 -281,7 -269,7 -269,7 +281,7 @@@@@@@@@@ static void __init fdt_enforce_memory_r
         
         void __init arm64_memblock_init(void)
         {
- -------       const s64 linear_region_size = BIT(vabits_actual - 1);
+ +++++++       const s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual);
         
                /* Handle linux,usable-memory-range property */
                fdt_enforce_memory_region();
                memstart_addr = round_down(memblock_start_of_DRAM(),
                                           ARM64_MEMSTART_ALIGN);
         
-               physvirt_offset = PHYS_OFFSET - PAGE_OFFSET;
-        
-               vmemmap = ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT));
-        
-               /*
-                * If we are running with a 52-bit kernel VA config on a system that
-                * does not support it, we have to offset our vmemmap and physvirt_offset
-                * s.t. we avoid the 52-bit portion of the direct linear map
-                */
-               if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52) && (vabits_actual != 52)) {
-                       vmemmap += (_PAGE_OFFSET(48) - _PAGE_OFFSET(52)) >> PAGE_SHIFT;
-                       physvirt_offset = PHYS_OFFSET - _PAGE_OFFSET(48);
-               }
-        
                /*
                 * Remove the memory that we will not be able to cover with the
                 * linear mapping. Take care not to clip the kernel which may be
                        memblock_remove(0, memstart_addr);
                }
         
+               /*
+                * If we are running with a 52-bit kernel VA config on a system that
+                * does not support it, we have to place the available physical
+                * memory in the 48-bit addressable part of the linear region, i.e.,
+                * we have to move it upward. Since memstart_addr represents the
+                * physical address of PAGE_OFFSET, we have to *subtract* from it.
+                */
+               if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52) && (vabits_actual != 52))
+                       memstart_addr -= _PAGE_OFFSET(48) - _PAGE_OFFSET(52);
+        
                /*
                 * Apply the memory limit if it was set. Since the kernel may be loaded
                 * high up in memory, add back the kernel region that must be accessible
         
                if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
                        extern u16 memstart_offset_seed;
--- -----               u64 range = linear_region_size -
--- -----                           (memblock_end_of_DRAM() - memblock_start_of_DRAM());
+++ +++++               u64 mmfr0 = read_cpuid(ID_AA64MMFR0_EL1);
+++ +++++               int parange = cpuid_feature_extract_unsigned_field(
+++ +++++                                       mmfr0, ID_AA64MMFR0_PARANGE_SHIFT);
+++ +++++               s64 range = linear_region_size -
+++ +++++                           BIT(id_aa64mmfr0_parange_to_phys_shift(parange));
         
                        /*
                         * If the size of the linear region exceeds, by a sufficient
--- -----                * margin, the size of the region that the available physical
--- -----                * memory spans, randomize the linear region as well.
+++ +++++                * margin, the size of the region that the physical memory can
+++ +++++                * span, randomize the linear region as well.
                         */
--- -----               if (memstart_offset_seed > 0 && range >= ARM64_MEMSTART_ALIGN) {
+++ +++++               if (memstart_offset_seed > 0 && range >= (s64)ARM64_MEMSTART_ALIGN) {
                                range /= ARM64_MEMSTART_ALIGN;
                                memstart_addr -= ARM64_MEMSTART_ALIGN *
                                                 ((range * memstart_offset_seed) >> 16);
                 * Register the kernel text, kernel data, initrd, and initial
                 * pagetables with memblock.
                 */
----- ---       memblock_reserve(__pa_symbol(_text), _end - _text);
+++++ +++       memblock_reserve(__pa_symbol(_stext), _end - _stext);
                if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && phys_initrd_size) {
                        /* the generic initrd code expects virtual addresses */
                        initrd_start = __phys_to_virt(phys_initrd_start);
         
                early_init_fdt_scan_reserved_mem();
         
------ --       if (IS_ENABLED(CONFIG_ZONE_DMA)) {
------ --               zone_dma_bits = ARM64_ZONE_DMA_BITS;
------ --               arm64_dma_phys_limit = max_zone_phys(ARM64_ZONE_DMA_BITS);
------ --       }
------ --
                if (IS_ENABLED(CONFIG_ZONE_DMA32))
                        arm64_dma32_phys_limit = max_zone_phys(32);
                else
                        arm64_dma32_phys_limit = PHYS_MASK + 1;
         
------ --       reserve_crashkernel();
------ --
                reserve_elfcorehdr();
         
                high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
@@@@@@@@@@ -429,6 -418,8 -418,8 -421,8 -418,8 -418,8 -423,8 -418,8 -418,8 +426,8 @@@@@@@@@@ void __init bootmem_init(void
                arm64_hugetlb_cma_reserve();
         #endif
         
+               dma_pernuma_cma_reserve();
+        
                /*
                 * sparse_init() tries to allocate memory from memblock, so must be
                 * done after the fixed reservations
                sparse_init();
                zone_sizes_init(min, max);
         
++++++ ++       /*
++++++ ++        * request_standard_resources() depends on crashkernel's memory being
++++++ ++        * reserved, so do it here.
++++++ ++        */
++++++ ++       reserve_crashkernel();
++++++ ++
                memblock_dump_all();
         }
         
@@@@@@@@@@ -471,12 -462,10 -462,10 -465,10 -462,10 -462,10 -473,10 -462,10 -462,10 +476,10 @@@@@@@@@@ static inline void free_memmap(unsigne
          */
         static void __init free_unused_memmap(void)
         {
-               unsigned long start, prev_end = 0;
-               struct memblock_region *reg;
-        
-               for_each_memblock(memory, reg) {
-                       start = __phys_to_pfn(reg->base);
+               unsigned long start, end, prev_end = 0;
+               int i;
         
+               for_each_mem_pfn_range(i, MAX_NUMNODES, &start, &end, NULL) {
         #ifdef CONFIG_SPARSEMEM
                        /*
                         * Take care not to free memmap entries that don't exist due
                         * memmap entries are valid from the bank end aligned to
                         * MAX_ORDER_NR_PAGES.
                         */
-                       prev_end = ALIGN(__phys_to_pfn(reg->base + reg->size),
-                                        MAX_ORDER_NR_PAGES);
+                       prev_end = ALIGN(end, MAX_ORDER_NR_PAGES);
                }
         
         #ifdef CONFIG_SPARSEMEM
diff --combined arch/arm64/mm/mmu.c
index 75df62fea1b68ab6ea2863a241c7b8a6e5ca6374,1c0f3e02f731edd8b962b2d62a8954236b91c3d7,1c0f3e02f731edd8b962b2d62a8954236b91c3d7,f293f2222f503d99ab6fc7c87fdc79b0da107d23,1c0f3e02f731edd8b962b2d62a8954236b91c3d7,e6f2accaeade2d3ab740416b5251e3e12de8a57f,7e9be63150670adc0f21c2b7f731a99dcb28c586,1c0f3e02f731edd8b962b2d62a8954236b91c3d7,1c0f3e02f731edd8b962b2d62a8954236b91c3d7..fe0721a44376297df3591c669d046611724896f1
@@@@@@@@@@ -122,7 -122,7 -122,7 -122,7 -122,7 -122,7 -122,7 -122,7 -122,7 +122,7 @@@@@@@@@@ static bool pgattr_change_is_safe(u64 o
                 * The following mapping attributes may be updated in live
                 * kernel mappings without the need for break-before-make.
                 */
-               static const pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG;
+               pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE | PTE_NG;
         
                /* creating or taking down mappings is always safe */
                if (old == 0 || new == 0)
                if (old & ~new & PTE_NG)
                        return false;
         
+               /*
+                * Changing the memory type between Normal and Normal-Tagged is safe
+                * since Tagged is considered a permission attribute from the
+                * mismatched attribute aliases perspective.
+                */
+               if (((old & PTE_ATTRINDX_MASK) == PTE_ATTRINDX(MT_NORMAL) ||
+                    (old & PTE_ATTRINDX_MASK) == PTE_ATTRINDX(MT_NORMAL_TAGGED)) &&
+                   ((new & PTE_ATTRINDX_MASK) == PTE_ATTRINDX(MT_NORMAL) ||
+                    (new & PTE_ATTRINDX_MASK) == PTE_ATTRINDX(MT_NORMAL_TAGGED)))
+                       mask |= PTE_ATTRINDX_MASK;
+        
                return ((old ^ new) & ~mask) == 0;
         }
         
@@@@@@@@@@ -453,19 -464,20 -464,20 -464,20 -464,20 -464,20 -464,35 -464,20 -464,20 +464,35 @@@@@@@@@@ void __init mark_linear_text_alias_ro(v
                /*
                 * Remove the write permissions from the linear alias of .text/.rodata
                 */
----- ---       update_mapping_prot(__pa_symbol(_text), (unsigned long)lm_alias(_text),
----- ---                           (unsigned long)__init_begin - (unsigned long)_text,
+++++ +++       update_mapping_prot(__pa_symbol(_stext), (unsigned long)lm_alias(_stext),
+++++ +++                           (unsigned long)__init_begin - (unsigned long)_stext,
                                    PAGE_KERNEL_RO);
         }
         
++++++ ++static bool crash_mem_map __initdata;
++++++ ++
++++++ ++static int __init enable_crash_mem_map(char *arg)
++++++ ++{
++++++ ++       /*
++++++ ++        * Proper parameter parsing is done by reserve_crashkernel(). We only
++++++ ++        * need to know if the linear map has to avoid block mappings so that
++++++ ++        * the crashkernel reservations can be unmapped later.
++++++ ++        */
++++++ ++       crash_mem_map = true;
++++++ ++
++++++ ++       return 0;
++++++ ++}
++++++ ++early_param("crashkernel", enable_crash_mem_map);
++++++ ++
         static void __init map_mem(pgd_t *pgdp)
         {
----- ---       phys_addr_t kernel_start = __pa_symbol(_text);
+++++ +++       phys_addr_t kernel_start = __pa_symbol(_stext);
                phys_addr_t kernel_end = __pa_symbol(__init_begin);
-               struct memblock_region *reg;
+               phys_addr_t start, end;
                int flags = 0;
+               u64 i;
         
------ --       if (rodata_full || debug_pagealloc_enabled())
++++++ ++       if (rodata_full || crash_mem_map || debug_pagealloc_enabled())
                        flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
         
                /*
                 * the following for-loop
                 */
                memblock_mark_nomap(kernel_start, kernel_end - kernel_start);
------ --#ifdef CONFIG_KEXEC_CORE
------ --       if (crashk_res.end)
------ --               memblock_mark_nomap(crashk_res.start,
------ --                                   resource_size(&crashk_res));
------ --#endif
         
                /* map all the memory banks */
-               for_each_memblock(memory, reg) {
-                       phys_addr_t start = reg->base;
-                       phys_addr_t end = start + reg->size;
-        
+               for_each_mem_range(i, &start, &end) {
                        if (start >= end)
                                break;
-                       if (memblock_is_nomap(reg))
-                               continue;
-        
-                       __map_memblock(pgdp, start, end, PAGE_KERNEL, flags);
+                       /*
+                        * The linear map must allow allocation tags reading/writing
+                        * if MTE is present. Otherwise, it has the same attributes as
+                        * PAGE_KERNEL.
+                        */
+                       __map_memblock(pgdp, start, end, PAGE_KERNEL_TAGGED, flags);
                }
         
                /*
----- ---        * Map the linear alias of the [_text, __init_begin) interval
+++++ +++        * Map the linear alias of the [_stext, __init_begin) interval
                 * as non-executable now, and remove the write permission in
                 * mark_linear_text_alias_ro() below (which will be called after
                 * alternative patching has completed). This makes the contents
                __map_memblock(pgdp, kernel_start, kernel_end,
                               PAGE_KERNEL, NO_CONT_MAPPINGS);
                memblock_clear_nomap(kernel_start, kernel_end - kernel_start);
------ --
------ --#ifdef CONFIG_KEXEC_CORE
------ --       /*
------ --        * Use page-level mappings here so that we can shrink the region
------ --        * in page granularity and put back unused memory to buddy system
------ --        * through /sys/kernel/kexec_crash_size interface.
------ --        */
------ --       if (crashk_res.end) {
------ --               __map_memblock(pgdp, crashk_res.start, crashk_res.end + 1,
------ --                              PAGE_KERNEL,
------ --                              NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS);
------ --               memblock_clear_nomap(crashk_res.start,
------ --                                    resource_size(&crashk_res));
------ --       }
------ --#endif
         }
         
         void mark_rodata_ro(void)
@@@@@@@@@@ -654,7 -665,7 -665,7 -665,7 -665,7 -665,7 -660,7 -665,7 -665,7 +660,7 @@@@@@@@@@ static void __init map_kernel(pgd_t *pg
                 * Only rodata will be remapped with different permissions later on,
                 * all other segments are allowed to use contiguous mappings.
                 */
----- ---       map_kernel_segment(pgdp, _text, _etext, text_prot, &vmlinux_text, 0,
+++++ +++       map_kernel_segment(pgdp, _stext, _etext, text_prot, &vmlinux_text, 0,
                                   VM_NO_GUARD);
                map_kernel_segment(pgdp, __start_rodata, __inittext_begin, PAGE_KERNEL,
                                   &vmlinux_rodata, NO_CONT_MAPPINGS, VM_NO_GUARD);
@@@@@@@@@@ -1482,13 -1493,13 -1493,13 -1493,43 -1493,13 -1493,13 -1488,13 -1493,13 -1493,13 +1488,43 @@@@@@@@@@ static int prevent_bootmem_remove_notif
                unsigned long end_pfn = arg->start_pfn + arg->nr_pages;
                unsigned long pfn = arg->start_pfn;
         
--- -----       if (action != MEM_GOING_OFFLINE)
+++ +++++       if ((action != MEM_GOING_OFFLINE) && (action != MEM_OFFLINE))
                        return NOTIFY_OK;
         
                for (; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
+++ +++++               unsigned long start = PFN_PHYS(pfn);
+++ +++++               unsigned long end = start + (1UL << PA_SECTION_SHIFT);
+++ +++++
                        ms = __pfn_to_section(pfn);
--- -----               if (early_section(ms))
+++ +++++               if (!early_section(ms))
+++ +++++                       continue;
+++ +++++
+++ +++++               if (action == MEM_GOING_OFFLINE) {
+++ +++++                       /*
+++ +++++                        * Boot memory removal is not supported. Prevent
+++ +++++                        * it via blocking any attempted offline request
+++ +++++                        * for the boot memory and just report it.
+++ +++++                        */
+++ +++++                       pr_warn("Boot memory [%lx %lx] offlining attempted\n", start, end);
                                return NOTIFY_BAD;
+++ +++++               } else if (action == MEM_OFFLINE) {
+++ +++++                       /*
+++ +++++                        * This should have never happened. Boot memory
+++ +++++                        * offlining should have been prevented by this
+++ +++++                        * very notifier. Probably some memory removal
+++ +++++                        * procedure might have changed which would then
+++ +++++                        * require further debug.
+++ +++++                        */
+++ +++++                       pr_err("Boot memory [%lx %lx] offlined\n", start, end);
+++ +++++
+++ +++++                       /*
+++ +++++                        * Core memory hotplug does not process a return
+++ +++++                        * code from the notifier for MEM_OFFLINE events.
+++ +++++                        * The error condition has been reported. Return
+++ +++++                        * from here as if ignored.
+++ +++++                        */
+++ +++++                       return NOTIFY_DONE;
+++ +++++               }
                }
                return NOTIFY_OK;
         }
@@@@@@@@@@ -1497,9 -1508,9 -1508,9 -1538,66 -1508,9 -1508,9 -1503,9 -1508,9 -1508,9 +1533,66 @@@@@@@@@@ static struct notifier_block prevent_bo
                .notifier_call = prevent_bootmem_remove_notifier,
         };
         
+++ +++++/*
+++ +++++ * This ensures that boot memory sections on the platform are online
+++ +++++ * from early boot. Memory sections could not be prevented from being
+++ +++++ * offlined, unless for some reason they are not online to begin with.
+++ +++++ * This helps validate the basic assumption on which the above memory
+++ +++++ * event notifier works to prevent boot memory section offlining and
+++ +++++ * its possible removal.
+++ +++++ */
+++ +++++static void validate_bootmem_online(void)
+++ +++++{
+++ +++++       phys_addr_t start, end, addr;
+++ +++++       struct mem_section *ms;
+++ +++++       u64 i;
+++ +++++
+++ +++++       /*
+++ +++++        * Scanning across all memblock might be expensive
+++ +++++        * on some big memory systems. Hence enable this
+++ +++++        * validation only with DEBUG_VM.
+++ +++++        */
+++ +++++       if (!IS_ENABLED(CONFIG_DEBUG_VM))
+++ +++++               return;
+++ +++++
+++ +++++       for_each_mem_range(i, &start, &end) {
+++ +++++               for (addr = start; addr < end; addr += (1UL << PA_SECTION_SHIFT)) {
+++ +++++                       ms = __pfn_to_section(PHYS_PFN(addr));
+++ +++++
+++ +++++                       /*
+++ +++++                        * All memory ranges in the system at this point
+++ +++++                        * should have been marked as early sections.
+++ +++++                        */
+++ +++++                       WARN_ON(!early_section(ms));
+++ +++++
+++ +++++                       /*
+++ +++++                        * Memory notifier mechanism here to prevent boot
+++ +++++                        * memory offlining depends on the fact that each
+++ +++++                        * early section memory on the system is initially
+++ +++++                        * online. Otherwise a given memory section which
+++ +++++                        * is already offline will be overlooked and can
+++ +++++                        * be removed completely. Call out such sections.
+++ +++++                        */
+++ +++++                       if (!online_section(ms))
+++ +++++                               pr_err("Boot memory [%llx %llx] is offline, can be removed\n",
+++ +++++                                       addr, addr + (1UL << PA_SECTION_SHIFT));
+++ +++++               }
+++ +++++       }
+++ +++++}
+++ +++++
         static int __init prevent_bootmem_remove_init(void)
         {
--- -----       return register_memory_notifier(&prevent_bootmem_remove_nb);
+++ +++++       int ret = 0;
+++ +++++
+++ +++++       if (!IS_ENABLED(CONFIG_MEMORY_HOTREMOVE))
+++ +++++               return ret;
+++ +++++
+++ +++++       validate_bootmem_online();
+++ +++++       ret = register_memory_notifier(&prevent_bootmem_remove_nb);
+++ +++++       if (ret)
+++ +++++               pr_err("%s: Notifier registration failed %d\n", __func__, ret);
+++ +++++
+++ +++++       return ret;
         }
--- -----device_initcall(prevent_bootmem_remove_init);
+++ +++++early_initcall(prevent_bootmem_remove_init);
         #endif
This page took 0.174667 seconds and 4 git commands to generate.