]> Git Repo - linux.git/commitdiff
Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64...
authorLinus Torvalds <[email protected]>
Mon, 8 Jul 2019 16:54:55 +0000 (09:54 -0700)
committerLinus Torvalds <[email protected]>
Mon, 8 Jul 2019 16:54:55 +0000 (09:54 -0700)
Pull arm64 updates from Catalin Marinas:

 - arm64 support for syscall emulation via PTRACE_SYSEMU{,_SINGLESTEP}

 - Wire up VM_FLUSH_RESET_PERMS for arm64, allowing the core code to
   manage the permissions of executable vmalloc regions more strictly

 - Slight performance improvement by keeping softirqs enabled while
   touching the FPSIMD/SVE state (kernel_neon_begin/end)

 - Expose a couple of ARMv8.5 features to user (HWCAP): CondM (new
   XAFLAG and AXFLAG instructions for floating point comparison flags
   manipulation) and FRINT (rounding floating point numbers to integers)

 - Re-instate ARM64_PSEUDO_NMI support which was previously marked as
   BROKEN due to some bugs (now fixed)

 - Improve parking of stopped CPUs and implement an arm64-specific
   panic_smp_self_stop() to avoid warning on not being able to stop
   secondary CPUs during panic

 - perf: enable the ARM Statistical Profiling Extensions (SPE) on ACPI
   platforms

 - perf: DDR performance monitor support for iMX8QXP

 - cache_line_size() can now be set from DT or ACPI/PPTT if provided to
   cope with a system cache info not exposed via the CPUID registers

 - Avoid warning on hardware cache line size greater than
   ARCH_DMA_MINALIGN if the system is fully coherent

 - arm64 do_page_fault() and hugetlb cleanups

 - Refactor set_pte_at() to avoid redundant READ_ONCE(*ptep)

 - Ignore ACPI 5.1 FADTs reported as 5.0 (infer from the
   'arm_boot_flags' introduced in 5.1)

 - CONFIG_RANDOMIZE_BASE now enabled in defconfig

 - Allow the selection of ARM64_MODULE_PLTS, currently only done via
   RANDOMIZE_BASE (and an erratum workaround), allowing modules to spill
   over into the vmalloc area

 - Make ZONE_DMA32 configurable

* tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (54 commits)
  perf: arm_spe: Enable ACPI/Platform automatic module loading
  arm_pmu: acpi: spe: Add initial MADT/SPE probing
  ACPI/PPTT: Add function to return ACPI 6.3 Identical tokens
  ACPI/PPTT: Modify node flag detection to find last IDENTICAL
  x86/entry: Simplify _TIF_SYSCALL_EMU handling
  arm64: rename dump_instr as dump_kernel_instr
  arm64/mm: Drop [PTE|PMD]_TYPE_FAULT
  arm64: Implement panic_smp_self_stop()
  arm64: Improve parking of stopped CPUs
  arm64: Expose FRINT capabilities to userspace
  arm64: Expose ARMv8.5 CondM capability to userspace
  arm64: defconfig: enable CONFIG_RANDOMIZE_BASE
  arm64: ARM64_MODULES_PLTS must depend on MODULES
  arm64: bpf: do not allocate executable memory
  arm64/kprobes: set VM_FLUSH_RESET_PERMS on kprobe instruction pages
  arm64/mm: wire up CONFIG_ARCH_HAS_SET_DIRECT_MAP
  arm64: module: create module allocations without exec permissions
  arm64: Allow user selection of ARM64_MODULE_PLTS
  acpi/arm64: ignore 5.1 FADTs that are reported as 5.0
  arm64: Allow selecting Pseudo-NMI again
  ...

46 files changed:
1  2 
MAINTAINERS
arch/arm64/configs/defconfig
arch/arm64/include/asm/acpi.h
arch/arm64/include/asm/arch_gicv3.h
arch/arm64/include/asm/cache.h
arch/arm64/include/asm/cacheflush.h
arch/arm64/include/asm/cpufeature.h
arch/arm64/include/asm/daifflags.h
arch/arm64/include/asm/fpsimd.h
arch/arm64/include/asm/hwcap.h
arch/arm64/include/asm/irqflags.h
arch/arm64/include/asm/kvm_host.h
arch/arm64/include/asm/pgtable-hwdef.h
arch/arm64/include/asm/pgtable-prot.h
arch/arm64/include/asm/pgtable.h
arch/arm64/include/asm/ptrace.h
arch/arm64/include/asm/simd.h
arch/arm64/include/asm/sysreg.h
arch/arm64/include/asm/thread_info.h
arch/arm64/include/uapi/asm/ptrace.h
arch/arm64/kernel/acpi.c
arch/arm64/kernel/cacheinfo.c
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/cpuinfo.c
arch/arm64/kernel/entry.S
arch/arm64/kernel/fpsimd.c
arch/arm64/kernel/irq.c
arch/arm64/kernel/module.c
arch/arm64/kernel/process.c
arch/arm64/kernel/ptrace.c
arch/arm64/kernel/smp.c
arch/arm64/kernel/traps.c
arch/arm64/kvm/hyp/switch.c
arch/arm64/mm/dma-mapping.c
arch/arm64/mm/fault.c
arch/arm64/mm/init.c
arch/arm64/mm/mmu.c
arch/arm64/mm/pageattr.c
arch/arm64/net/bpf_jit_comp.c
arch/x86/entry/common.c
drivers/irqchip/irq-gic-v3.c
drivers/perf/arm_pmu_acpi.c
drivers/perf/arm_spe_pmu.c
include/linux/perf/arm_pmu.h
kernel/ptrace.c
mm/vmalloc.c

diff --combined MAINTAINERS
index 677ef41cb012ca2a3f4fb9ee56bdc45c450ff6cc,a2a8b567d5e83d130a0637caeca2c1779d4b96de..49408383b2aa0b35b90cee60d745e11bc68d97e8
@@@ -364,7 -364,7 +364,7 @@@ F: drivers/acpi/fan.
  
  ACPI FOR ARM64 (ACPI/arm64)
  M:    Lorenzo Pieralisi <[email protected]>
 -M:    Hanjun Guo <[email protected]>
 +M:    Hanjun Guo <[email protected]>
  M:    Sudeep Holla <[email protected]>
  L:    [email protected]
  L:    [email protected] (moderated for non-subscribers)
@@@ -1235,7 -1235,7 +1235,7 @@@ F:      arch/arm/lib/floppydma.
  F:    arch/arm/include/asm/floppy.h
  
  ARM PMU PROFILING AND DEBUGGING
 -M:    Will Deacon <will[email protected]>
 +M:    Will Deacon <will@kernel.org>
  M:    Mark Rutland <[email protected]>
  S:    Maintained
  L:    [email protected] (moderated for non-subscribers)
@@@ -1307,7 -1307,7 +1307,7 @@@ F:      Documentation/devicetree/bindings/in
  F:    drivers/irqchip/irq-vic.c
  
  ARM SMMU DRIVERS
 -M:    Will Deacon <will[email protected]>
 +M:    Will Deacon <will@kernel.org>
  R:    Robin Murphy <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
@@@ -2085,7 -2085,7 +2085,7 @@@ F:      drivers/tty/serial/msm_serial.
  F:    drivers/usb/dwc3/dwc3-qcom.c
  F:    include/dt-bindings/*/qcom*
  F:    include/linux/*/qcom*
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/agross/linux.git
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git
  
  ARM/RADISYS ENP2611 MACHINE SUPPORT
  M:    Lennert Buytenhek <[email protected]>
@@@ -2550,7 -2550,7 +2550,7 @@@ F:      drivers/i2c/busses/i2c-xiic.
  
  ARM64 PORT (AARCH64 ARCHITECTURE)
  M:    Catalin Marinas <[email protected]>
 -M:    Will Deacon <will[email protected]>
 +M:    Will Deacon <will@kernel.org>
  L:    [email protected] (moderated for non-subscribers)
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
  S:    Maintained
@@@ -2734,7 -2734,7 +2734,7 @@@ S:      Maintaine
  F:    drivers/net/wireless/atmel/atmel*
  
  ATOMIC INFRASTRUCTURE
 -M:    Will Deacon <will[email protected]>
 +M:    Will Deacon <will@kernel.org>
  M:    Peter Zijlstra <[email protected]>
  R:    Boqun Feng <[email protected]>
  L:    [email protected]
@@@ -3121,8 -3121,7 +3121,8 @@@ F:      arch/arm/mach-bcm
  
  BROADCOM BCM2835 ARM ARCHITECTURE
  M:    Eric Anholt <[email protected]>
 -M:    Stefan Wahren <[email protected]>
 +M:    Stefan Wahren <[email protected]>
 +L:    [email protected]
  L:    [email protected] (moderated for non-subscribers)
  L:    [email protected] (moderated for non-subscribers)
  T:    git git://github.com/anholt/linux
@@@ -3152,7 -3151,6 +3152,7 @@@ F:      arch/arm/boot/dts/bcm953012
  
  BROADCOM BCM53573 ARM ARCHITECTURE
  M:    RafaÅ‚ MiÅ‚ecki <[email protected]>
 +L:    [email protected]
  L:    [email protected]
  S:    Maintained
  F:    arch/arm/boot/dts/bcm53573*
@@@ -3942,14 -3940,6 +3942,14 @@@ M:    Miguel Ojeda <miguel.ojeda.sandonis@
  S:    Maintained
  F:    .clang-format
  
 +CLANG/LLVM BUILD SUPPORT
 +L:    [email protected]
 +W:    https://clangbuiltlinux.github.io/
 +B:    https://github.com/ClangBuiltLinux/linux/issues
 +C:    irc://chat.freenode.net/clangbuiltlinux
 +S:    Supported
 +K:    \b(?i:clang|llvm)\b
 +
  CLEANCACHE API
  M:    Konrad Rzeszutek Wilk <[email protected]>
  L:    [email protected]
@@@ -6244,6 -6234,7 +6244,6 @@@ F:      include/linux/ipmi-fru.
  K:    fmc_d.*register
  
  FPGA MANAGER FRAMEWORK
 -M:    Alan Tull <[email protected]>
  M:    Moritz Fischer <[email protected]>
  L:    [email protected]
  S:    Maintained
  S:    Maintained
  F:    drivers/i2c/busses/i2c-cpm.c
  
+ FREESCALE IMX DDR PMU DRIVER
+ M:    Frank Li <[email protected]>
+ L:    [email protected]
+ S:    Maintained
+ F:    drivers/perf/fsl_imx8_ddr_perf.c
+ F:    Documentation/devicetree/bindings/perf/fsl-imx-ddr.txt
  FREESCALE IMX LPI2C DRIVER
  M:    Dong Aisheng <[email protected]>
  L:    [email protected]
@@@ -7810,7 -7808,7 +7817,7 @@@ INGENIC JZ4780 NAND DRIVE
  M:    Harvey Hunt <[email protected]>
  L:    [email protected]
  S:    Maintained
 -F:    drivers/mtd/nand/raw/jz4780_*
 +F:    drivers/mtd/nand/raw/ingenic/
  
  INOTIFY
  M:    Jan Kara <[email protected]>
@@@ -8575,7 -8573,7 +8582,7 @@@ S:      Odd Fixe
  
  KERNEL NFSD, SUNRPC, AND LOCKD SERVERS
  M:    "J. Bruce Fields" <[email protected]>
 -M:    Jeff Layton <[email protected]>
 +M:    Chuck Lever <[email protected]>
  L:    [email protected]
  W:    http://nfs.sourceforge.net/
  T:    git git://linux-nfs.org/~bfields/linux.git
@@@ -9130,7 -9128,7 +9137,7 @@@ F:      drivers/misc/lkdtm/
  LINUX KERNEL MEMORY CONSISTENCY MODEL (LKMM)
  M:    Alan Stern <[email protected]>
  M:    Andrea Parri <[email protected]>
 -M:    Will Deacon <will[email protected]>
 +M:    Will Deacon <will@kernel.org>
  M:    Peter Zijlstra <[email protected]>
  M:    Boqun Feng <[email protected]>
  M:    Nicholas Piggin <[email protected]>
@@@ -9238,7 -9236,7 +9245,7 @@@ F:      Documentation/admin-guide/LSM/LoadPi
  LOCKING PRIMITIVES
  M:    Peter Zijlstra <[email protected]>
  M:    Ingo Molnar <[email protected]>
 -M:    Will Deacon <will[email protected]>
 +M:    Will Deacon <will@kernel.org>
  L:    [email protected]
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking/core
  S:    Maintained
@@@ -10559,7 -10557,7 +10566,7 @@@ F:   arch/arm/boot/dts/mmp
  F:    arch/arm/mach-mmp/
  
  MMU GATHER AND TLB INVALIDATION
 -M:    Will Deacon <will[email protected]>
 +M:    Will Deacon <will@kernel.org>
  M:    "Aneesh Kumar K.V" <[email protected]>
  M:    Andrew Morton <[email protected]>
  M:    Nick Piggin <[email protected]>
@@@ -12048,7 -12046,7 +12055,7 @@@ S:   Maintaine
  F:    drivers/pci/controller/dwc/*layerscape*
  
  PCI DRIVER FOR GENERIC OF HOSTS
 -M:    Will Deacon <will[email protected]>
 +M:    Will Deacon <will@kernel.org>
  L:    [email protected]
  L:    [email protected] (moderated for non-subscribers)
  S:    Maintained
@@@ -13066,6 -13064,7 +13073,6 @@@ F:   Documentation/devicetree/bindings/ne
  
  QUALCOMM GENERIC INTERFACE I2C DRIVER
  M:    Alok Chauhan <[email protected]>
 -M:    Karthikeyan Ramasubramanian <[email protected]>
  L:    [email protected]
  L:    [email protected]
  S:    Supported
@@@ -14344,15 -14343,6 +14351,15 @@@ S: Supporte
  K:    sifive
  N:    sifive
  
 +SIFIVE FU540 SYSTEM-ON-CHIP
 +M:    Paul Walmsley <[email protected]>
 +M:    Palmer Dabbelt <[email protected]>
 +L:    [email protected]
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pjw/sifive.git
 +S:    Supported
 +K:    fu540
 +N:    fu540
 +
  SILEAD TOUCHSCREEN DRIVER
  M:    Hans de Goede <[email protected]>
  L:    [email protected]
@@@ -14413,7 -14403,7 +14420,7 @@@ F:   lib/test_siphash.
  F:    include/linux/siphash.h
  
  SIOX
 -M:    Gavin Schenk <g.schenk@eckelmann.de>
 +M:    Thorsten Scherer <t.scherer@eckelmann.de>
  M:    Uwe Kleine-König <[email protected]>
  R:    Pengutronix Kernel Team <[email protected]>
  S:    Supported
@@@ -15012,7 -15002,7 +15019,7 @@@ S:   Odd Fixe
  F:    drivers/net/ethernet/adaptec/starfire*
  
  STEC S1220 SKD DRIVER
 -M:    Bart Van Assche <bart.vanassche@wdc.com>
 +M:    Damien Le Moal <Damien.LeMoal@wdc.com>
  L:    [email protected]
  S:    Maintained
  F:    drivers/block/skd*[ch]
@@@ -15503,7 -15493,6 +15510,7 @@@ F:   drivers/dma/tegra
  
  TEGRA I2C DRIVER
  M:    Laxman Dewangan <[email protected]>
 +R:    Dmitry Osipenko <[email protected]>
  S:    Supported
  F:    drivers/i2c/busses/i2c-tegra.c
  
@@@ -17330,7 -17319,7 +17337,7 @@@ F:   Documentation/ABI/stable/sysfs-hyper
  F:    Documentation/ABI/testing/sysfs-hypervisor-xen
  
  XEN NETWORK BACKEND DRIVER
 -M:    Wei Liu <wei.liu[email protected]>
 +M:    Wei Liu <wei.liu@kernel.org>
  M:    Paul Durrant <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
  L:    [email protected]
index 6bca5b082ea4e6a84430568c89b7532f9e076d62,a7cbf7cd84b4d7c132549c3be0fee09ef46ee254..dd827e64e5fe620b1e4fbdc712adc405ccb9ccc1
@@@ -68,6 -68,7 +68,7 @@@ CONFIG_KEXEC=
  CONFIG_CRASH_DUMP=y
  CONFIG_XEN=y
  CONFIG_COMPAT=y
+ CONFIG_RANDOMIZE_BASE=y
  CONFIG_HIBERNATION=y
  CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
  CONFIG_ARM_CPUIDLE=y
@@@ -613,7 -614,6 +614,7 @@@ CONFIG_RTC_DRV_TEGRA=
  CONFIG_RTC_DRV_IMX_SC=m
  CONFIG_RTC_DRV_XGENE=y
  CONFIG_DMADEVICES=y
 +CONFIG_FSL_EDMA=y
  CONFIG_DMA_BCM2835=m
  CONFIG_K3_DMA=y
  CONFIG_MV_XOR=y
index ada0bc480a1b26e01ecb7e903149ce03d8e7e269,d10399b9f99813f53040abab4f41ec16756fd2dd..b263e239cb599993f459dedbc0f1306cc1a1f5d2
@@@ -1,9 -1,12 +1,9 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   *  Copyright (C) 2013-2014, Linaro Ltd.
   *    Author: Al Stone <[email protected]>
   *    Author: Graeme Gregory <[email protected]>
   *    Author: Hanjun Guo <[email protected]>
 - *
 - *  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
 - *  published by the Free Software Foundation;
   */
  
  #ifndef _ASM_ACPI_H
@@@ -38,6 -41,9 +38,9 @@@
        (!(entry) || (entry)->header.length < ACPI_MADT_GICC_MIN_LENGTH || \
        (unsigned long)(entry) + (entry)->header.length > (end))
  
+ #define ACPI_MADT_GICC_SPE  (ACPI_OFFSET(struct acpi_madt_generic_interrupt, \
+       spe_interrupt) + sizeof(u16))
  /* Basic configuration for ACPI */
  #ifdef        CONFIG_ACPI
  pgprot_t __acpi_get_mem_attribute(phys_addr_t addr);
index 2247908e55d60ba2743a4b16aa2e206d6bf81fbf,9e991b6287060f99b2a9c16b20b2c5a7b6bd2430..79155a8cfe7c06026a583ea9a5a9f0218b543971
@@@ -1,8 -1,19 +1,8 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * arch/arm64/include/asm/arch_gicv3.h
   *
   * Copyright (C) 2015 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #ifndef __ASM_ARCH_GICV3_H
  #define __ASM_ARCH_GICV3_H
@@@ -152,7 -163,9 +152,9 @@@ static inline bool gic_prio_masking_ena
  
  static inline void gic_pmr_mask_irqs(void)
  {
-       BUILD_BUG_ON(GICD_INT_DEF_PRI <= GIC_PRIO_IRQOFF);
+       BUILD_BUG_ON(GICD_INT_DEF_PRI < (GIC_PRIO_IRQOFF |
+                                        GIC_PRIO_PSR_I_SET));
+       BUILD_BUG_ON(GICD_INT_DEF_PRI >= GIC_PRIO_IRQON);
        gic_write_pmr(GIC_PRIO_IRQOFF);
  }
  
index a05db636981a0d9b2470e69c567b5e7313a647c5,d24b7c1ecd9b0683442a72843627aa1bbd718f84..64eeaa41e7caa2c76083ffdafd993abc7df17f4f
@@@ -1,6 -1,17 +1,6 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #ifndef __ASM_CACHE_H
  #define __ASM_CACHE_H
@@@ -80,12 -91,15 +80,15 @@@ static inline u32 cache_type_cwg(void
  
  #define __read_mostly __attribute__((__section__(".data..read_mostly")))
  
- static inline int cache_line_size(void)
+ static inline int cache_line_size_of_cpu(void)
  {
        u32 cwg = cache_type_cwg();
        return cwg ? 4 << cwg : ARCH_DMA_MINALIGN;
  }
  
+ int cache_line_size(void);
  /*
   * Read the effective value of CTR_EL0.
   *
index 1fe4467442aa7bdae3f7d8c8d8adc0a61fa1aa87,b9ee5510067fc62537c52f0f449d5154af15081e..665c78e0665a65ea89f40442bef31b55bebf9147
@@@ -1,9 -1,20 +1,9 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Based on arch/arm/include/asm/cacheflush.h
   *
   * Copyright (C) 1999-2002 Russell King.
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #ifndef __ASM_CACHEFLUSH_H
  #define __ASM_CACHEFLUSH_H
@@@ -176,4 -187,7 +176,7 @@@ static inline void flush_cache_vunmap(u
  
  int set_memory_valid(unsigned long addr, int numpages, int enable);
  
+ int set_direct_map_invalid_noflush(struct page *page);
+ int set_direct_map_default_noflush(struct page *page);
  #endif
index 373799b7982f6368e0493c6d788c46f066a6e946,693a086e2148caedd112f3aebe2a73df9286812e..3d8db50d9ae2f8ccff4db5722593e2f0a4a1d21d
@@@ -1,6 -1,9 +1,6 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Copyright (C) 2014 Linaro Ltd. <[email protected]>
 - *
 - * 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
 - * published by the Free Software Foundation.
   */
  
  #ifndef __ASM_CPUFEATURE_H
@@@ -614,6 -617,12 +614,12 @@@ static inline bool system_uses_irq_prio
               cpus_have_const_cap(ARM64_HAS_IRQ_PRIO_MASKING);
  }
  
+ static inline bool system_has_prio_mask_debugging(void)
+ {
+       return IS_ENABLED(CONFIG_ARM64_DEBUG_PRIORITY_MASKING) &&
+              system_uses_irq_prio_masking();
+ }
  #define ARM64_SSBD_UNKNOWN            -1
  #define ARM64_SSBD_FORCE_DISABLE      0
  #define ARM64_SSBD_KERNEL             1
index 6dd8a8723525eee3e1aaaead889b5e9ebd50cfb1,eca5bee1d85b23db1606c4049cbbafeb6300e438..987926ed535e36e856882c6138ee0f7ea54f6576
@@@ -1,12 -1,24 +1,13 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Copyright (C) 2017 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #ifndef __ASM_DAIFFLAGS_H
  #define __ASM_DAIFFLAGS_H
  
  #include <linux/irqflags.h>
  
+ #include <asm/arch_gicv3.h>
  #include <asm/cpufeature.h>
  
  #define DAIF_PROCCTX          0
  /* mask/save/unmask/restore all exceptions, including interrupts. */
  static inline void local_daif_mask(void)
  {
+       WARN_ON(system_has_prio_mask_debugging() &&
+               (read_sysreg_s(SYS_ICC_PMR_EL1) == (GIC_PRIO_IRQOFF |
+                                                   GIC_PRIO_PSR_I_SET)));
        asm volatile(
                "msr    daifset, #0xf           // local_daif_mask\n"
                :
                :
                : "memory");
+       /* Don't really care for a dsb here, we don't intend to enable IRQs */
+       if (system_uses_irq_prio_masking())
+               gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
        trace_hardirqs_off();
  }
  
@@@ -32,7 -53,7 +42,7 @@@ static inline unsigned long local_daif_
  
        if (system_uses_irq_prio_masking()) {
                /* If IRQs are masked with PMR, reflect it in the flags */
-               if (read_sysreg_s(SYS_ICC_PMR_EL1) <= GIC_PRIO_IRQOFF)
+               if (read_sysreg_s(SYS_ICC_PMR_EL1) != GIC_PRIO_IRQON)
                        flags |= PSR_I_BIT;
        }
  
@@@ -45,39 -66,50 +55,50 @@@ static inline void local_daif_restore(u
  {
        bool irq_disabled = flags & PSR_I_BIT;
  
+       WARN_ON(system_has_prio_mask_debugging() &&
+               !(read_sysreg(daif) & PSR_I_BIT));
        if (!irq_disabled) {
                trace_hardirqs_on();
  
-               if (system_uses_irq_prio_masking())
-                       arch_local_irq_enable();
-       } else if (!(flags & PSR_A_BIT)) {
-               /*
-                * If interrupts are disabled but we can take
-                * asynchronous errors, we can take NMIs
-                */
                if (system_uses_irq_prio_masking()) {
-                       flags &= ~PSR_I_BIT;
+                       gic_write_pmr(GIC_PRIO_IRQON);
+                       dsb(sy);
+               }
+       } else if (system_uses_irq_prio_masking()) {
+               u64 pmr;
+               if (!(flags & PSR_A_BIT)) {
                        /*
-                        * There has been concern that the write to daif
-                        * might be reordered before this write to PMR.
-                        * From the ARM ARM DDI 0487D.a, section D1.7.1
-                        * "Accessing PSTATE fields":
-                        *   Writes to the PSTATE fields have side-effects on
-                        *   various aspects of the PE operation. All of these
-                        *   side-effects are guaranteed:
-                        *     - Not to be visible to earlier instructions in
-                        *       the execution stream.
-                        *     - To be visible to later instructions in the
-                        *       execution stream
-                        *
-                        * Also, writes to PMR are self-synchronizing, so no
-                        * interrupts with a lower priority than PMR is signaled
-                        * to the PE after the write.
-                        *
-                        * So we don't need additional synchronization here.
+                        * If interrupts are disabled but we can take
+                        * asynchronous errors, we can take NMIs
                         */
-                       arch_local_irq_disable();
+                       flags &= ~PSR_I_BIT;
+                       pmr = GIC_PRIO_IRQOFF;
+               } else {
+                       pmr = GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET;
                }
+               /*
+                * There has been concern that the write to daif
+                * might be reordered before this write to PMR.
+                * From the ARM ARM DDI 0487D.a, section D1.7.1
+                * "Accessing PSTATE fields":
+                *   Writes to the PSTATE fields have side-effects on
+                *   various aspects of the PE operation. All of these
+                *   side-effects are guaranteed:
+                *     - Not to be visible to earlier instructions in
+                *       the execution stream.
+                *     - To be visible to later instructions in the
+                *       execution stream
+                *
+                * Also, writes to PMR are self-synchronizing, so no
+                * interrupts with a lower priority than PMR is signaled
+                * to the PE after the write.
+                *
+                * So we don't need additional synchronization here.
+                */
+               gic_write_pmr(pmr);
        }
  
        write_sysreg(flags, daif);
index 897029c8e9b548dc213b34d693b0b3b22351b573,4154851c21abd6b67246c58769f0592a842e78b0..b6a2c352f4c3fd64726115f478d1c6a4fd60b040
@@@ -1,6 -1,17 +1,6 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #ifndef __ASM_FP_H
  #define __ASM_FP_H
@@@ -37,8 -48,6 +37,6 @@@ struct task_struct
  extern void fpsimd_save_state(struct user_fpsimd_state *state);
  extern void fpsimd_load_state(struct user_fpsimd_state *state);
  
- extern void fpsimd_save(void);
  extern void fpsimd_thread_switch(struct task_struct *next);
  extern void fpsimd_flush_thread(void);
  
@@@ -52,8 -61,7 +50,7 @@@ extern void fpsimd_bind_state_to_cpu(st
                                     void *sve_state, unsigned int sve_vl);
  
  extern void fpsimd_flush_task_state(struct task_struct *target);
- extern void fpsimd_flush_cpu_state(void);
- extern void sve_flush_cpu_state(void);
+ extern void fpsimd_save_and_flush_cpu_state(void);
  
  /* Maximum VL that SVE VL-agnostic software can transparently support */
  #define SVE_VL_ARCH_MAX 0x100
index e5d9420cd258293a9ab91c08d8543bef741c6069,8371202e0a8bf284a2dbeaf004f2dad54c0cf80e..3d2f2472a36cfdebe9b174ab13d0d752e526d2e7
@@@ -1,6 -1,17 +1,6 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #ifndef __ASM_HWCAP_H
  #define __ASM_HWCAP_H
@@@ -84,6 -95,8 +84,8 @@@
  #define KERNEL_HWCAP_SVEBITPERM               __khwcap2_feature(SVEBITPERM)
  #define KERNEL_HWCAP_SVESHA3          __khwcap2_feature(SVESHA3)
  #define KERNEL_HWCAP_SVESM4           __khwcap2_feature(SVESM4)
+ #define KERNEL_HWCAP_FLAGM2           __khwcap2_feature(FLAGM2)
+ #define KERNEL_HWCAP_FRINT            __khwcap2_feature(FRINT)
  
  /*
   * This yields a mask that user programs can use to figure out what
index 66853fde60f93d231662f1477ccd7cb7c2319e92,cac2d2a3c24e9d098773716ed100b9890f28226d..7872f260c9ee3e14755e916230be06095a936dbf
@@@ -1,6 -1,17 +1,6 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #ifndef __ASM_IRQFLAGS_H
  #define __ASM_IRQFLAGS_H
   */
  static inline void arch_local_irq_enable(void)
  {
+       if (system_has_prio_mask_debugging()) {
+               u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1);
+               WARN_ON_ONCE(pmr != GIC_PRIO_IRQON && pmr != GIC_PRIO_IRQOFF);
+       }
        asm volatile(ALTERNATIVE(
                "msr    daifclr, #2             // arch_local_irq_enable\n"
                "nop",
  
  static inline void arch_local_irq_disable(void)
  {
+       if (system_has_prio_mask_debugging()) {
+               u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1);
+               WARN_ON_ONCE(pmr != GIC_PRIO_IRQON && pmr != GIC_PRIO_IRQOFF);
+       }
        asm volatile(ALTERNATIVE(
                "msr    daifset, #2             // arch_local_irq_disable",
                __msr_s(SYS_ICC_PMR_EL1, "%0"),
   */
  static inline unsigned long arch_local_save_flags(void)
  {
-       unsigned long daif_bits;
        unsigned long flags;
  
-       daif_bits = read_sysreg(daif);
-       /*
-        * The asm is logically equivalent to:
-        *
-        * if (system_uses_irq_prio_masking())
-        *      flags = (daif_bits & PSR_I_BIT) ?
-        *                      GIC_PRIO_IRQOFF :
-        *                      read_sysreg_s(SYS_ICC_PMR_EL1);
-        * else
-        *      flags = daif_bits;
-        */
        asm volatile(ALTERNATIVE(
-                       "mov    %0, %1\n"
-                       "nop\n"
-                       "nop",
-                       __mrs_s("%0", SYS_ICC_PMR_EL1)
-                       "ands   %1, %1, " __stringify(PSR_I_BIT) "\n"
-                       "csel   %0, %0, %2, eq",
-                       ARM64_HAS_IRQ_PRIO_MASKING)
-               : "=&r" (flags), "+r" (daif_bits)
-               : "r" ((unsigned long) GIC_PRIO_IRQOFF)
+               "mrs    %0, daif",
+               __mrs_s("%0", SYS_ICC_PMR_EL1),
+               ARM64_HAS_IRQ_PRIO_MASKING)
+               : "=&r" (flags)
+               :
                : "memory");
  
        return flags;
  }
  
+ static inline int arch_irqs_disabled_flags(unsigned long flags)
+ {
+       int res;
+       asm volatile(ALTERNATIVE(
+               "and    %w0, %w1, #" __stringify(PSR_I_BIT),
+               "eor    %w0, %w1, #" __stringify(GIC_PRIO_IRQON),
+               ARM64_HAS_IRQ_PRIO_MASKING)
+               : "=&r" (res)
+               : "r" ((int) flags)
+               : "memory");
+       return res;
+ }
  static inline unsigned long arch_local_irq_save(void)
  {
        unsigned long flags;
  
        flags = arch_local_save_flags();
  
-       arch_local_irq_disable();
+       /*
+        * There are too many states with IRQs disabled, just keep the current
+        * state if interrupts are already disabled/masked.
+        */
+       if (!arch_irqs_disabled_flags(flags))
+               arch_local_irq_disable();
  
        return flags;
  }
@@@ -108,26 -134,10 +123,10 @@@ static inline void arch_local_irq_resto
                        __msr_s(SYS_ICC_PMR_EL1, "%0")
                        "dsb    sy",
                        ARM64_HAS_IRQ_PRIO_MASKING)
-               : "+r" (flags)
                :
+               : "r" (flags)
                : "memory");
  }
  
- static inline int arch_irqs_disabled_flags(unsigned long flags)
- {
-       int res;
-       asm volatile(ALTERNATIVE(
-                       "and    %w0, %w1, #" __stringify(PSR_I_BIT) "\n"
-                       "nop",
-                       "cmp    %w1, #" __stringify(GIC_PRIO_IRQOFF) "\n"
-                       "cset   %w0, ls",
-                       ARM64_HAS_IRQ_PRIO_MASKING)
-               : "=&r" (res)
-               : "r" ((int) flags)
-               : "memory");
-       return res;
- }
  #endif
  #endif
index c328191aa202f5075ec64550a78c11f376cd7c66,33410635b0154abe892d6aa938eb60e8e6e0a4db..9f19c354b165c30b1a7c04811232b3e0ec319896
@@@ -1,4 -1,3 +1,4 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Copyright (C) 2012,2013 - ARM Ltd
   * Author: Marc Zyngier <[email protected]>
@@@ -6,6 -5,18 +6,6 @@@
   * Derived from arch/arm/include/asm/kvm_host.h:
   * Copyright (C) 2012 - Virtual Open Systems and Columbia University
   * Author: Christoffer Dall <[email protected]>
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #ifndef __ARM64_KVM_HOST_H__
@@@ -597,11 -608,12 +597,12 @@@ static inline void kvm_arm_vhe_guest_en
         * will not signal the CPU of interrupts of lower priority, and the
         * only way to get out will be via guest exceptions.
         * Naturally, we want to avoid this.
+        *
+        * local_daif_mask() already sets GIC_PRIO_PSR_I_SET, we just need a
+        * dsb to ensure the redistributor is forwards EL2 IRQs to the CPU.
         */
-       if (system_uses_irq_prio_masking()) {
-               gic_write_pmr(GIC_PRIO_IRQON);
+       if (system_uses_irq_prio_masking())
                dsb(sy);
-       }
  }
  
  static inline void kvm_arm_vhe_guest_exit(void)
index 30e5e67749e54ee20f512ebd0a79c9729912baa0,529e83f8e6079e24d1b65bb8af1a3a6b4d2eccb0..db92950bb1a0f3a888069643dded8af7e41d6282
@@@ -1,6 -1,17 +1,6 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #ifndef __ASM_PGTABLE_HWDEF_H
  #define __ASM_PGTABLE_HWDEF_H
   * Level 2 descriptor (PMD).
   */
  #define PMD_TYPE_MASK         (_AT(pmdval_t, 3) << 0)
- #define PMD_TYPE_FAULT                (_AT(pmdval_t, 0) << 0)
  #define PMD_TYPE_TABLE                (_AT(pmdval_t, 3) << 0)
  #define PMD_TYPE_SECT         (_AT(pmdval_t, 1) << 0)
  #define PMD_TABLE_BIT         (_AT(pmdval_t, 1) << 1)
  /*
   * Level 3 descriptor (PTE).
   */
+ #define PTE_VALID             (_AT(pteval_t, 1) << 0)
  #define PTE_TYPE_MASK         (_AT(pteval_t, 3) << 0)
- #define PTE_TYPE_FAULT                (_AT(pteval_t, 0) << 0)
  #define PTE_TYPE_PAGE         (_AT(pteval_t, 3) << 0)
  #define PTE_TABLE_BIT         (_AT(pteval_t, 1) << 1)
  #define PTE_USER              (_AT(pteval_t, 1) << 6)         /* AP[1] */
index c81583be034b42f543c3293b19bde47f99547189,38c7148e20232c704421c1c7efc815c63eadb107..f318258a14be77629a5db1800c71d7860482e8ba
@@@ -1,6 -1,17 +1,6 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Copyright (C) 2016 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #ifndef __ASM_PGTABLE_PROT_H
  #define __ASM_PGTABLE_PROT_H
@@@ -13,7 -24,6 +13,6 @@@
  /*
   * Software defined PTE bits definition.
   */
- #define PTE_VALID             (_AT(pteval_t, 1) << 0)
  #define PTE_WRITE             (PTE_DBM)                /* same as DBM (51) */
  #define PTE_DIRTY             (_AT(pteval_t, 1) << 55)
  #define PTE_SPECIAL           (_AT(pteval_t, 1) << 56)
index fca26759081a78bb7ed2fdcca61ef8a0dbc49e8d,2023eab19d73abb57097b481e97894296daf2d58..3052381baaeb87e457e5c5aba59cb390b152f4e8
@@@ -1,6 -1,17 +1,6 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #ifndef __ASM_PGTABLE_H
  #define __ASM_PGTABLE_H
@@@ -235,29 -246,42 +235,42 @@@ extern void __sync_icache_dcache(pte_t 
   *
   *   PTE_DIRTY || (PTE_WRITE && !PTE_RDONLY)
   */
- static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
-                             pte_t *ptep, pte_t pte)
+ static inline void __check_racy_pte_update(struct mm_struct *mm, pte_t *ptep,
+                                          pte_t pte)
  {
        pte_t old_pte;
  
-       if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte))
-               __sync_icache_dcache(pte);
+       if (!IS_ENABLED(CONFIG_DEBUG_VM))
+               return;
+       old_pte = READ_ONCE(*ptep);
+       if (!pte_valid(old_pte) || !pte_valid(pte))
+               return;
+       if (mm != current->active_mm && atomic_read(&mm->mm_users) <= 1)
+               return;
  
        /*
-        * If the existing pte is valid, check for potential race with
-        * hardware updates of the pte (ptep_set_access_flags safely changes
-        * valid ptes without going through an invalid entry).
+        * Check for potential race with hardware updates of the pte
+        * (ptep_set_access_flags safely changes valid ptes without going
+        * through an invalid entry).
         */
-       old_pte = READ_ONCE(*ptep);
-       if (IS_ENABLED(CONFIG_DEBUG_VM) && pte_valid(old_pte) && pte_valid(pte) &&
-          (mm == current->active_mm || atomic_read(&mm->mm_users) > 1)) {
-               VM_WARN_ONCE(!pte_young(pte),
-                            "%s: racy access flag clearing: 0x%016llx -> 0x%016llx",
-                            __func__, pte_val(old_pte), pte_val(pte));
-               VM_WARN_ONCE(pte_write(old_pte) && !pte_dirty(pte),
-                            "%s: racy dirty state clearing: 0x%016llx -> 0x%016llx",
-                            __func__, pte_val(old_pte), pte_val(pte));
-       }
+       VM_WARN_ONCE(!pte_young(pte),
+                    "%s: racy access flag clearing: 0x%016llx -> 0x%016llx",
+                    __func__, pte_val(old_pte), pte_val(pte));
+       VM_WARN_ONCE(pte_write(old_pte) && !pte_dirty(pte),
+                    "%s: racy dirty state clearing: 0x%016llx -> 0x%016llx",
+                    __func__, pte_val(old_pte), pte_val(pte));
+ }
+ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+                             pte_t *ptep, pte_t pte)
+ {
+       if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte))
+               __sync_icache_dcache(pte);
+       __check_racy_pte_update(mm, ptep, pte);
  
        set_pte(ptep, pte);
  }
@@@ -324,9 -348,14 +337,14 @@@ static inline pmd_t pte_pmd(pte_t pte
        return __pmd(pte_val(pte));
  }
  
- static inline pgprot_t mk_sect_prot(pgprot_t prot)
+ static inline pgprot_t mk_pud_sect_prot(pgprot_t prot)
+ {
+       return __pgprot((pgprot_val(prot) & ~PUD_TABLE_BIT) | PUD_TYPE_SECT);
+ }
+ static inline pgprot_t mk_pmd_sect_prot(pgprot_t prot)
  {
-       return __pgprot(pgprot_val(prot) & ~PTE_TABLE_BIT);
+       return __pgprot((pgprot_val(prot) & ~PMD_TABLE_BIT) | PMD_TYPE_SECT);
  }
  
  #ifdef CONFIG_NUMA_BALANCING
@@@ -801,7 -830,8 +819,7 @@@ extern int kern_addr_valid(unsigned lon
  
  #include <asm-generic/pgtable.h>
  
 -void pgd_cache_init(void);
 -#define pgtable_cache_init    pgd_cache_init
 +static inline void pgtable_cache_init(void) { }
  
  /*
   * On AArch64, the cache coherency is handled via the set_pte_at() function.
index dad858b6adc6da1a4a95c0f974cfe06f72860d0d,da2242248466748e9ab26aacca67e03e92e5b7df..81693244f58d6abbe186dfac94689a8a19544887
@@@ -1,9 -1,20 +1,9 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Based on arch/arm/include/asm/ptrace.h
   *
   * Copyright (C) 1996-2003 Russell King
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #ifndef __ASM_PTRACE_H
  #define __ASM_PTRACE_H
   * means masking more IRQs (or at least that the same IRQs remain masked).
   *
   * To mask interrupts, we clear the most significant bit of PMR.
+  *
+  * Some code sections either automatically switch back to PSR.I or explicitly
+  * require to not use priority masking. If bit GIC_PRIO_PSR_I_SET is included
+  * in the  the priority mask, it indicates that PSR.I should be set and
+  * interrupt disabling temporarily does not rely on IRQ priorities.
   */
- #define GIC_PRIO_IRQON                0xf0
- #define GIC_PRIO_IRQOFF               (GIC_PRIO_IRQON & ~0x80)
+ #define GIC_PRIO_IRQON                        0xc0
+ #define GIC_PRIO_IRQOFF                       (GIC_PRIO_IRQON & ~0x80)
+ #define GIC_PRIO_PSR_I_SET            (1 << 4)
  
  /* Additional SPSR bits not exposed in the UABI */
  #define PSR_IL_BIT            (1 << 20)
index 7e245b9e03a5fb16c20047e92cec4b966315c362,a6307e43b8c2d077bad66fb0e960f357c8f6595f..7434844036d39fb356ed901995d8e1edd54a7003
@@@ -1,6 -1,9 +1,6 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Copyright (C) 2017 Linaro Ltd. <[email protected]>
 - *
 - * 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 published
 - * by the Free Software Foundation.
   */
  
  #ifndef __ASM_SIMD_H
@@@ -12,9 -15,9 +12,9 @@@
  #include <linux/preempt.h>
  #include <linux/types.h>
  
- #ifdef CONFIG_KERNEL_MODE_NEON
+ DECLARE_PER_CPU(bool, fpsimd_context_busy);
  
- DECLARE_PER_CPU(bool, kernel_neon_busy);
+ #ifdef CONFIG_KERNEL_MODE_NEON
  
  /*
   * may_use_simd - whether it is allowable at this time to issue SIMD
  static __must_check inline bool may_use_simd(void)
  {
        /*
-        * kernel_neon_busy is only set while preemption is disabled,
+        * fpsimd_context_busy is only set while preemption is disabled,
         * and is clear whenever preemption is enabled. Since
-        * this_cpu_read() is atomic w.r.t. preemption, kernel_neon_busy
+        * this_cpu_read() is atomic w.r.t. preemption, fpsimd_context_busy
         * cannot change under our feet -- if it's set we cannot be
         * migrated, and if it's clear we cannot be migrated to a CPU
         * where it is set.
         */
        return !in_irq() && !irqs_disabled() && !in_nmi() &&
-               !this_cpu_read(kernel_neon_busy);
+               !this_cpu_read(fpsimd_context_busy);
  }
  
  #else /* ! CONFIG_KERNEL_MODE_NEON */
index cd7f7ce1a56a61060411d85af34916d0cf4c03fa,6019727718075b0d6ce2e8ec25ebcfebb09a634c..d0bd4ffcf2c463afde0c5459c8ad03d0c679d267
@@@ -1,9 -1,20 +1,9 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Macros for accessing system registers with older binutils.
   *
   * Copyright (C) 2014 ARM Ltd.
   * Author: Catalin Marinas <[email protected]>
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #ifndef __ASM_SYSREG_H
  
  /* id_aa64isar1 */
  #define ID_AA64ISAR1_SB_SHIFT         36
+ #define ID_AA64ISAR1_FRINTTS_SHIFT    32
  #define ID_AA64ISAR1_GPI_SHIFT                28
  #define ID_AA64ISAR1_GPA_SHIFT                24
  #define ID_AA64ISAR1_LRCPC_SHIFT      20
index 2372e97db29cc8e4867396305fb55cfab4f4208f,c285d1ce7186c501ad3eb3b844829f8d357a8f1f..180b34ec59650a9bcbca37ae4c7fbba373251e09
@@@ -1,9 -1,20 +1,9 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Based on arch/arm/include/asm/thread_info.h
   *
   * Copyright (C) 2002 Russell King.
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #ifndef __ASM_THREAD_INFO_H
  #define __ASM_THREAD_INFO_H
@@@ -64,7 -75,8 +64,8 @@@ void arch_release_task_struct(struct ta
   *  TIF_SYSCALL_TRACE - syscall trace active
   *  TIF_SYSCALL_TRACEPOINT - syscall tracepoint for ftrace
   *  TIF_SYSCALL_AUDIT - syscall auditing
 - *  TIF_SECOMP                - syscall secure computing
 + *  TIF_SECCOMP               - syscall secure computing
+  *  TIF_SYSCALL_EMU     - syscall emulation active
   *  TIF_SIGPENDING    - signal pending
   *  TIF_NEED_RESCHED  - rescheduling necessary
   *  TIF_NOTIFY_RESUME - callback before returning to user
@@@ -80,6 -92,7 +81,7 @@@
  #define TIF_SYSCALL_AUDIT     9
  #define TIF_SYSCALL_TRACEPOINT        10
  #define TIF_SECCOMP           11
+ #define TIF_SYSCALL_EMU               12
  #define TIF_MEMDIE            18      /* is terminating due to OOM killer */
  #define TIF_FREEZE            19
  #define TIF_RESTORE_SIGMASK   20
  #define _TIF_SYSCALL_AUDIT    (1 << TIF_SYSCALL_AUDIT)
  #define _TIF_SYSCALL_TRACEPOINT       (1 << TIF_SYSCALL_TRACEPOINT)
  #define _TIF_SECCOMP          (1 << TIF_SECCOMP)
+ #define _TIF_SYSCALL_EMU      (1 << TIF_SYSCALL_EMU)
  #define _TIF_UPROBE           (1 << TIF_UPROBE)
  #define _TIF_FSCHECK          (1 << TIF_FSCHECK)
  #define _TIF_32BIT            (1 << TIF_32BIT)
  
  #define _TIF_SYSCALL_WORK     (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
                                 _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
-                                _TIF_NOHZ)
+                                _TIF_NOHZ | _TIF_SYSCALL_EMU)
  
  #define INIT_THREAD_INFO(tsk)                                         \
  {                                                                     \
index e932284993d401ca3b5fda787f616eb626931bfb,627ac57c1581eda41b52695525fa9170ac099b3f..7ed9294e20045d31b25cb9dc54f0d4b37e84bf15
  #define PSR_x         0x0000ff00      /* Extension            */
  #define PSR_c         0x000000ff      /* Control              */
  
+ /* syscall emulation path in ptrace */
+ #define PTRACE_SYSEMU           31
+ #define PTRACE_SYSEMU_SINGLESTEP  32
  
  #ifndef __ASSEMBLY__
  
 -#include <linux/prctl.h>
 -
  /*
   * User structures for general purpose, floating point and debug registers.
   */
@@@ -111,10 -116,10 +114,10 @@@ struct user_sve_header 
  
  /*
   * Common SVE_PT_* flags:
 - * These must be kept in sync with prctl interface in <linux/ptrace.h>
 + * These must be kept in sync with prctl interface in <linux/prctl.h>
   */
 -#define SVE_PT_VL_INHERIT             (PR_SVE_VL_INHERIT >> 16)
 -#define SVE_PT_VL_ONEXEC              (PR_SVE_SET_VL_ONEXEC >> 16)
 +#define SVE_PT_VL_INHERIT             ((1 << 17) /* PR_SVE_VL_INHERIT */ >> 16)
 +#define SVE_PT_VL_ONEXEC              ((1 << 18) /* PR_SVE_SET_VL_ONEXEC */ >> 16)
  
  
  /*
   *    FPCR    uint32_t                        FPCR
   *
   * Additional data might be appended in the future.
 + *
 + * The Z-, P- and FFR registers are represented in memory in an endianness-
 + * invariant layout which differs from the layout used for the FPSIMD
 + * V-registers on big-endian systems: see sigcontext.h for more explanation.
   */
  
  #define SVE_PT_SVE_ZREG_SIZE(vq)      __SVE_ZREG_SIZE(vq)
diff --combined arch/arm64/kernel/acpi.c
index 2804330c95dc290b962c44b854e62c8c7a92795c,7722e85fb69c30207e57b3183c187c7e9edfdf6e..3a58e9db5cfe79e17354f1950b5f07282f9e23e5
@@@ -1,4 -1,3 +1,4 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   *  ARM64 Specific Low-Level ACPI Boot Support
   *
@@@ -8,6 -7,10 +8,6 @@@
   *    Author: Hanjun Guo <[email protected]>
   *    Author: Tomasz Nowicki <[email protected]>
   *    Author: Naresh Bhat <[email protected]>
 - *
 - *  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
 - *  published by the Free Software Foundation.
   */
  
  #define pr_fmt(fmt) "ACPI: " fmt
@@@ -152,10 -155,14 +152,14 @@@ static int __init acpi_fadt_sanity_chec
         */
        if (table->revision < 5 ||
           (table->revision == 5 && fadt->minor_revision < 1)) {
-               pr_err("Unsupported FADT revision %d.%d, should be 5.1+\n",
+               pr_err(FW_BUG "Unsupported FADT revision %d.%d, should be 5.1+\n",
                       table->revision, fadt->minor_revision);
-               ret = -EINVAL;
-               goto out;
+               if (!fadt->arm_boot_flags) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+               pr_err("FADT has ARM boot flags set, assuming 5.1\n");
        }
  
        if (!(fadt->flags & ACPI_FADT_HW_REDUCED)) {
index 880d79904d36ae12c54efbe24fcd0a3b7b4db25f,969fcc3be556b15753ea19141cc5c52a154085df..7fa6828bb488ace623cb826d0b717cbea92210c5
@@@ -1,9 -1,20 +1,9 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   *  ARM64 cacheinfo support
   *
   *  Copyright (C) 2015 ARM Ltd.
   *  All Rights Reserved
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 - * kind, whether express or implied; without even the implied warranty
 - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #include <linux/acpi.h>
  #define CLIDR_CTYPE(clidr, level)     \
        (((clidr) & CLIDR_CTYPE_MASK(level)) >> CLIDR_CTYPE_SHIFT(level))
  
+ int cache_line_size(void)
+ {
+       if (coherency_max_size != 0)
+               return coherency_max_size;
+       return cache_line_size_of_cpu();
+ }
+ EXPORT_SYMBOL_GPL(cache_line_size);
  static inline enum cache_type get_cache_type(int level)
  {
        u64 clidr;
index aabdabf52fdb5c5ded704c0ac4e6fe64aa5ad2f2,a0f00917b8b9cc59874e055a4f5fe3dc165b32f2..f29f36a65175c2f0f318710d2909d7635c1f848b
@@@ -1,8 -1,19 +1,8 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Contains CPU feature definitions
   *
   * Copyright (C) 2015 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #define pr_fmt(fmt) "CPU features: " fmt
@@@ -819,7 -830,6 +819,7 @@@ static u64 __read_sysreg_by_encoding(u3
  
        read_sysreg_case(SYS_ID_AA64PFR0_EL1);
        read_sysreg_case(SYS_ID_AA64PFR1_EL1);
 +      read_sysreg_case(SYS_ID_AA64ZFR0_EL1);
        read_sysreg_case(SYS_ID_AA64DFR0_EL1);
        read_sysreg_case(SYS_ID_AA64DFR1_EL1);
        read_sysreg_case(SYS_ID_AA64MMFR0_EL1);
@@@ -1184,14 -1194,14 +1184,14 @@@ static struct undef_hook ssbs_emulation
  static void cpu_enable_ssbs(const struct arm64_cpu_capabilities *__unused)
  {
        static bool undef_hook_registered = false;
-       static DEFINE_SPINLOCK(hook_lock);
+       static DEFINE_RAW_SPINLOCK(hook_lock);
  
-       spin_lock(&hook_lock);
+       raw_spin_lock(&hook_lock);
        if (!undef_hook_registered) {
                register_undef_hook(&ssbs_emulation_hook);
                undef_hook_registered = true;
        }
-       spin_unlock(&hook_lock);
+       raw_spin_unlock(&hook_lock);
  
        if (arm64_get_ssbd_state() == ARM64_SSBD_FORCE_DISABLE) {
                sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_DSSBS);
@@@ -1618,6 -1628,7 +1618,7 @@@ static const struct arm64_cpu_capabilit
        HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_DP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDDP),
        HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_FHM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDFHM),
        HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FLAGM),
+       HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_FLAGM2),
        HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_FP),
        HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FPHP),
        HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_ASIMD),
        HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FCMA),
        HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_LRCPC),
        HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC),
+       HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FRINTTS_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FRINT),
        HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_SB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SB),
        HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
  #ifdef CONFIG_ARM64_SVE
index 0593665fc7b481dbfaaab4ba9093e51368037e24,fda8ded8b739083d871a0c725e8052eb8b91c532..876055e373525999e1775dbd2a1bc482c9359b62
@@@ -1,8 -1,18 +1,8 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Record and handle CPU attributes.
   *
   * Copyright (C) 2014 ARM Ltd.
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  #include <asm/arch_timer.h>
  #include <asm/cache.h>
@@@ -82,6 -92,8 +82,8 @@@ static const char *const hwcap_str[] = 
        "svebitperm",
        "svesha3",
        "svesm4",
+       "flagm2",
+       "frint",
        NULL
  };
  
index 2df8d0a1d980bb41c5f5559fe190a3bca52252ba,165da78815c52f8cbf54af53715b3713b2216071..9cdc4592da3efdbd8f1bd8ade319b094f6e8da4f
@@@ -1,10 -1,21 +1,10 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Low-level exception handling code
   *
   * Copyright (C) 2012 ARM Ltd.
   * Authors:   Catalin Marinas <[email protected]>
   *            Will Deacon <[email protected]>
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #include <linux/arm-smccc.h>
@@@ -247,6 -258,7 +247,7 @@@ alternative_else_nop_endi
        /*
         * Registers that may be useful after this macro is invoked:
         *
+        * x20 - ICC_PMR_EL1
         * x21 - aborted SP
         * x22 - aborted PC
         * x23 - aborted PSTATE
@@@ -424,6 -436,38 +425,38 @@@ tsk      .req    x28             // current thread_inf
        irq_stack_exit
        .endm
  
+ #ifdef CONFIG_ARM64_PSEUDO_NMI
+       /*
+        * Set res to 0 if irqs were unmasked in interrupted context.
+        * Otherwise set res to non-0 value.
+        */
+       .macro  test_irqs_unmasked res:req, pmr:req
+ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
+       sub     \res, \pmr, #GIC_PRIO_IRQON
+ alternative_else
+       mov     \res, xzr
+ alternative_endif
+       .endm
+ #endif
+       .macro  gic_prio_kentry_setup, tmp:req
+ #ifdef CONFIG_ARM64_PSEUDO_NMI
+       alternative_if ARM64_HAS_IRQ_PRIO_MASKING
+       mov     \tmp, #(GIC_PRIO_PSR_I_SET | GIC_PRIO_IRQON)
+       msr_s   SYS_ICC_PMR_EL1, \tmp
+       alternative_else_nop_endif
+ #endif
+       .endm
+       .macro  gic_prio_irq_setup, pmr:req, tmp:req
+ #ifdef CONFIG_ARM64_PSEUDO_NMI
+       alternative_if ARM64_HAS_IRQ_PRIO_MASKING
+       orr     \tmp, \pmr, #GIC_PRIO_PSR_I_SET
+       msr_s   SYS_ICC_PMR_EL1, \tmp
+       alternative_else_nop_endif
+ #endif
+       .endm
        .text
  
  /*
@@@ -602,6 -646,7 +635,7 @@@ el1_dbg
        cmp     x24, #ESR_ELx_EC_BRK64          // if BRK64
        cinc    x24, x24, eq                    // set bit '0'
        tbz     x24, #0, el1_inv                // EL1 only
+       gic_prio_kentry_setup tmp=x3
        mrs     x0, far_el1
        mov     x2, sp                          // struct pt_regs
        bl      do_debug_exception
@@@ -619,20 -664,18 +653,18 @@@ ENDPROC(el1_sync
        .align  6
  el1_irq:
        kernel_entry 1
+       gic_prio_irq_setup pmr=x20, tmp=x1
        enable_da_f
- #ifdef CONFIG_TRACE_IRQFLAGS
  #ifdef CONFIG_ARM64_PSEUDO_NMI
- alternative_if ARM64_HAS_IRQ_PRIO_MASKING
-       ldr     x20, [sp, #S_PMR_SAVE]
- alternative_else
-       mov     x20, #GIC_PRIO_IRQON
- alternative_endif
-       cmp     x20, #GIC_PRIO_IRQOFF
-       /* Irqs were disabled, don't trace */
-       b.ls    1f
+       test_irqs_unmasked      res=x0, pmr=x20
+       cbz     x0, 1f
+       bl      asm_nmi_enter
+ 1:
  #endif
+ #ifdef CONFIG_TRACE_IRQFLAGS
        bl      trace_hardirqs_off
- 1:
  #endif
  
        irq_handler
@@@ -651,14 -694,23 +683,23 @@@ alternative_else_nop_endi
        bl      preempt_schedule_irq            // irq en/disable is done inside
  1:
  #endif
- #ifdef CONFIG_TRACE_IRQFLAGS
  #ifdef CONFIG_ARM64_PSEUDO_NMI
        /*
-        * if IRQs were disabled when we received the interrupt, we have an NMI
-        * and we are not re-enabling interrupt upon eret. Skip tracing.
+        * When using IRQ priority masking, we can get spurious interrupts while
+        * PMR is set to GIC_PRIO_IRQOFF. An NMI might also have occurred in a
+        * section with interrupts disabled. Skip tracing in those cases.
         */
-       cmp     x20, #GIC_PRIO_IRQOFF
-       b.ls    1f
+       test_irqs_unmasked      res=x0, pmr=x20
+       cbz     x0, 1f
+       bl      asm_nmi_exit
+ 1:
+ #endif
+ #ifdef CONFIG_TRACE_IRQFLAGS
+ #ifdef CONFIG_ARM64_PSEUDO_NMI
+       test_irqs_unmasked      res=x0, pmr=x20
+       cbnz    x0, 1f
  #endif
        bl      trace_hardirqs_on
  1:
@@@ -776,6 -828,7 +817,7 @@@ el0_ia
         * Instruction abort handling
         */
        mrs     x26, far_el1
+       gic_prio_kentry_setup tmp=x0
        enable_da_f
  #ifdef CONFIG_TRACE_IRQFLAGS
        bl      trace_hardirqs_off
@@@ -821,6 -874,7 +863,7 @@@ el0_sp_pc
         * Stack or PC alignment exception handling
         */
        mrs     x26, far_el1
+       gic_prio_kentry_setup tmp=x0
        enable_da_f
  #ifdef CONFIG_TRACE_IRQFLAGS
        bl      trace_hardirqs_off
@@@ -855,11 -909,12 +898,12 @@@ el0_dbg
         * Debug exception handling
         */
        tbnz    x24, #0, el0_inv                // EL0 only
+       gic_prio_kentry_setup tmp=x3
        mrs     x0, far_el1
        mov     x1, x25
        mov     x2, sp
        bl      do_debug_exception
-       enable_daif
+       enable_da_f
        ct_user_exit
        b       ret_to_user
  el0_inv:
@@@ -876,7 -931,9 +920,9 @@@ ENDPROC(el0_sync
  el0_irq:
        kernel_entry 0
  el0_irq_naked:
+       gic_prio_irq_setup pmr=x20, tmp=x0
        enable_da_f
  #ifdef CONFIG_TRACE_IRQFLAGS
        bl      trace_hardirqs_off
  #endif
@@@ -898,6 -955,7 +944,7 @@@ ENDPROC(el0_irq
  el1_error:
        kernel_entry 1
        mrs     x1, esr_el1
+       gic_prio_kentry_setup tmp=x2
        enable_dbg
        mov     x0, sp
        bl      do_serror
@@@ -908,10 -966,11 +955,11 @@@ el0_error
        kernel_entry 0
  el0_error_naked:
        mrs     x1, esr_el1
+       gic_prio_kentry_setup tmp=x2
        enable_dbg
        mov     x0, sp
        bl      do_serror
-       enable_daif
+       enable_da_f
        ct_user_exit
        b       ret_to_user
  ENDPROC(el0_error)
@@@ -932,6 -991,7 +980,7 @@@ work_pending
   */
  ret_to_user:
        disable_daif
+       gic_prio_kentry_setup tmp=x3
        ldr     x1, [tsk, #TSK_TI_FLAGS]
        and     x2, x1, #_TIF_WORK_MASK
        cbnz    x2, work_pending
@@@ -948,6 -1008,7 +997,7 @@@ ENDPROC(ret_to_user
   */
        .align  6
  el0_svc:
+       gic_prio_kentry_setup tmp=x1
        mov     x0, sp
        bl      el0_svc_handler
        b       ret_to_user
index 0cfcf5c237c58b02af94abcc5a8b515850124846,c7c454df2779faf874b5d8bf2c27aee42cfc36ce..eec4776ae5f01a81ebe4c0f57f5626c8866e4d42
@@@ -1,9 -1,20 +1,9 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * FP/SIMD context switching and fault handling
   *
   * Copyright (C) 2012 ARM Ltd.
   * Author: Catalin Marinas <[email protected]>
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #include <linux/bitmap.h>
@@@ -28,7 -39,6 +28,7 @@@
  #include <linux/slab.h>
  #include <linux/stddef.h>
  #include <linux/sysctl.h>
 +#include <linux/swab.h>
  
  #include <asm/esr.h>
  #include <asm/fpsimd.h>
@@@ -82,7 -92,8 +82,8 @@@
   * To prevent this from racing with the manipulation of the task's FPSIMD state
   * from task context and thereby corrupting the state, it is necessary to
   * protect any manipulation of a task's fpsimd_state or TIF_FOREIGN_FPSTATE
-  * flag with local_bh_disable() unless softirqs are already masked.
+  * flag with {, __}get_cpu_fpsimd_context(). This will still allow softirqs to
+  * run but prevent them to use FPSIMD.
   *
   * For a certain task, the sequence may look something like this:
   * - the task gets scheduled in; if both the task's fpsimd_cpu field
@@@ -145,6 -156,56 +146,56 @@@ extern void __percpu *efi_sve_state
  
  #endif /* ! CONFIG_ARM64_SVE */
  
+ DEFINE_PER_CPU(bool, fpsimd_context_busy);
+ EXPORT_PER_CPU_SYMBOL(fpsimd_context_busy);
+ static void __get_cpu_fpsimd_context(void)
+ {
+       bool busy = __this_cpu_xchg(fpsimd_context_busy, true);
+       WARN_ON(busy);
+ }
+ /*
+  * Claim ownership of the CPU FPSIMD context for use by the calling context.
+  *
+  * The caller may freely manipulate the FPSIMD context metadata until
+  * put_cpu_fpsimd_context() is called.
+  *
+  * The double-underscore version must only be called if you know the task
+  * can't be preempted.
+  */
+ static void get_cpu_fpsimd_context(void)
+ {
+       preempt_disable();
+       __get_cpu_fpsimd_context();
+ }
+ static void __put_cpu_fpsimd_context(void)
+ {
+       bool busy = __this_cpu_xchg(fpsimd_context_busy, false);
+       WARN_ON(!busy); /* No matching get_cpu_fpsimd_context()? */
+ }
+ /*
+  * Release the CPU FPSIMD context.
+  *
+  * Must be called from a context in which get_cpu_fpsimd_context() was
+  * previously called, with no call to put_cpu_fpsimd_context() in the
+  * meantime.
+  */
+ static void put_cpu_fpsimd_context(void)
+ {
+       __put_cpu_fpsimd_context();
+       preempt_enable();
+ }
+ static bool have_cpu_fpsimd_context(void)
+ {
+       return !preemptible() && __this_cpu_read(fpsimd_context_busy);
+ }
  /*
   * Call __sve_free() directly only if you know task can't be scheduled
   * or preempted.
@@@ -215,12 -276,10 +266,10 @@@ static void sve_free(struct task_struc
   * This function should be called only when the FPSIMD/SVE state in
   * thread_struct is known to be up to date, when preparing to enter
   * userspace.
-  *
-  * Softirqs (and preemption) must be disabled.
   */
  static void task_fpsimd_load(void)
  {
-       WARN_ON(!in_softirq() && !irqs_disabled());
+       WARN_ON(!have_cpu_fpsimd_context());
  
        if (system_supports_sve() && test_thread_flag(TIF_SVE))
                sve_load_state(sve_pffr(&current->thread),
  /*
   * Ensure FPSIMD/SVE storage in memory for the loaded context is up to
   * date with respect to the CPU registers.
-  *
-  * Softirqs (and preemption) must be disabled.
   */
- void fpsimd_save(void)
static void fpsimd_save(void)
  {
        struct fpsimd_last_state_struct const *last =
                this_cpu_ptr(&fpsimd_last_state);
        /* set by fpsimd_bind_task_to_cpu() or fpsimd_bind_state_to_cpu() */
  
-       WARN_ON(!in_softirq() && !irqs_disabled());
+       WARN_ON(!have_cpu_fpsimd_context());
  
        if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
                if (system_supports_sve() && test_thread_flag(TIF_SVE)) {
@@@ -342,29 -399,13 +389,30 @@@ static int __init sve_sysctl_init(void
  #define ZREG(sve_state, vq, n) ((char *)(sve_state) +         \
        (SVE_SIG_ZREG_OFFSET(vq, n) - SVE_SIG_REGS_OFFSET))
  
 +#ifdef CONFIG_CPU_BIG_ENDIAN
 +static __uint128_t arm64_cpu_to_le128(__uint128_t x)
 +{
 +      u64 a = swab64(x);
 +      u64 b = swab64(x >> 64);
 +
 +      return ((__uint128_t)a << 64) | b;
 +}
 +#else
 +static __uint128_t arm64_cpu_to_le128(__uint128_t x)
 +{
 +      return x;
 +}
 +#endif
 +
 +#define arm64_le128_to_cpu(x) arm64_cpu_to_le128(x)
 +
  /*
   * Transfer the FPSIMD state in task->thread.uw.fpsimd_state to
   * task->thread.sve_state.
   *
   * Task can be a non-runnable task, or current.  In the latter case,
-  * softirqs (and preemption) must be disabled.
+  * the caller must have ownership of the cpu FPSIMD context before calling
+  * this function.
   * task->thread.sve_state must point to at least sve_state_size(task)
   * bytes of allocated kernel memory.
   * task->thread.uw.fpsimd_state must be up to date before calling this
@@@ -376,16 -417,14 +424,16 @@@ static void fpsimd_to_sve(struct task_s
        void *sst = task->thread.sve_state;
        struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state;
        unsigned int i;
 +      __uint128_t *p;
  
        if (!system_supports_sve())
                return;
  
        vq = sve_vq_from_vl(task->thread.sve_vl);
 -      for (i = 0; i < 32; ++i)
 -              memcpy(ZREG(sst, vq, i), &fst->vregs[i],
 -                     sizeof(fst->vregs[i]));
 +      for (i = 0; i < 32; ++i) {
 +              p = (__uint128_t *)ZREG(sst, vq, i);
 +              *p = arm64_cpu_to_le128(fst->vregs[i]);
 +      }
  }
  
  /*
   * task->thread.uw.fpsimd_state.
   *
   * Task can be a non-runnable task, or current.  In the latter case,
-  * softirqs (and preemption) must be disabled.
+  * the caller must have ownership of the cpu FPSIMD context before calling
+  * this function.
   * task->thread.sve_state must point to at least sve_state_size(task)
   * bytes of allocated kernel memory.
   * task->thread.sve_state must be up to date before calling this function.
@@@ -404,16 -444,14 +453,16 @@@ static void sve_to_fpsimd(struct task_s
        void const *sst = task->thread.sve_state;
        struct user_fpsimd_state *fst = &task->thread.uw.fpsimd_state;
        unsigned int i;
 +      __uint128_t const *p;
  
        if (!system_supports_sve())
                return;
  
        vq = sve_vq_from_vl(task->thread.sve_vl);
 -      for (i = 0; i < 32; ++i)
 -              memcpy(&fst->vregs[i], ZREG(sst, vq, i),
 -                     sizeof(fst->vregs[i]));
 +      for (i = 0; i < 32; ++i) {
 +              p = (__uint128_t const *)ZREG(sst, vq, i);
 +              fst->vregs[i] = arm64_le128_to_cpu(*p);
 +      }
  }
  
  #ifdef CONFIG_ARM64_SVE
@@@ -502,7 -540,6 +551,7 @@@ void sve_sync_from_fpsimd_zeropad(struc
        void *sst = task->thread.sve_state;
        struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state;
        unsigned int i;
 +      __uint128_t *p;
  
        if (!test_tsk_thread_flag(task, TIF_SVE))
                return;
  
        memset(sst, 0, SVE_SIG_REGS_SIZE(vq));
  
 -      for (i = 0; i < 32; ++i)
 -              memcpy(ZREG(sst, vq, i), &fst->vregs[i],
 -                     sizeof(fst->vregs[i]));
 +      for (i = 0; i < 32; ++i) {
 +              p = (__uint128_t *)ZREG(sst, vq, i);
 +              *p = arm64_cpu_to_le128(fst->vregs[i]);
 +      }
  }
  
  int sve_set_vector_length(struct task_struct *task,
         * non-SVE thread.
         */
        if (task == current) {
-               local_bh_disable();
+               get_cpu_fpsimd_context();
  
                fpsimd_save();
        }
                sve_to_fpsimd(task);
  
        if (task == current)
-               local_bh_enable();
+               put_cpu_fpsimd_context();
  
        /*
         * Force reallocation of task SVE state to the correct size
@@@ -880,7 -916,7 +929,7 @@@ asmlinkage void do_sve_acc(unsigned in
  
        sve_alloc(current);
  
-       local_bh_disable();
+       get_cpu_fpsimd_context();
  
        fpsimd_save();
  
        if (test_and_set_thread_flag(TIF_SVE))
                WARN_ON(1); /* SVE access shouldn't have trapped */
  
-       local_bh_enable();
+       put_cpu_fpsimd_context();
  }
  
  /*
@@@ -935,6 -971,8 +984,8 @@@ void fpsimd_thread_switch(struct task_s
        if (!system_supports_fpsimd())
                return;
  
+       __get_cpu_fpsimd_context();
        /* Save unsaved fpsimd state, if any: */
        fpsimd_save();
  
  
        update_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE,
                               wrong_task || wrong_cpu);
+       __put_cpu_fpsimd_context();
  }
  
  void fpsimd_flush_thread(void)
        if (!system_supports_fpsimd())
                return;
  
-       local_bh_disable();
+       get_cpu_fpsimd_context();
  
        fpsimd_flush_task_state(current);
        memset(&current->thread.uw.fpsimd_state, 0,
                        current->thread.sve_vl_onexec = 0;
        }
  
-       local_bh_enable();
+       put_cpu_fpsimd_context();
  }
  
  /*
@@@ -1011,9 -1051,9 +1064,9 @@@ void fpsimd_preserve_current_state(void
        if (!system_supports_fpsimd())
                return;
  
-       local_bh_disable();
+       get_cpu_fpsimd_context();
        fpsimd_save();
-       local_bh_enable();
+       put_cpu_fpsimd_context();
  }
  
  /*
@@@ -1030,7 -1070,8 +1083,8 @@@ void fpsimd_signal_preserve_current_sta
  
  /*
   * Associate current's FPSIMD context with this cpu
-  * Preemption must be disabled when calling this function.
+  * The caller must have ownership of the cpu FPSIMD context before calling
+  * this function.
   */
  void fpsimd_bind_task_to_cpu(void)
  {
@@@ -1076,14 -1117,14 +1130,14 @@@ void fpsimd_restore_current_state(void
        if (!system_supports_fpsimd())
                return;
  
-       local_bh_disable();
+       get_cpu_fpsimd_context();
  
        if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) {
                task_fpsimd_load();
                fpsimd_bind_task_to_cpu();
        }
  
-       local_bh_enable();
+       put_cpu_fpsimd_context();
  }
  
  /*
@@@ -1096,7 -1137,7 +1150,7 @@@ void fpsimd_update_current_state(struc
        if (!system_supports_fpsimd())
                return;
  
-       local_bh_disable();
+       get_cpu_fpsimd_context();
  
        current->thread.uw.fpsimd_state = *state;
        if (system_supports_sve() && test_thread_flag(TIF_SVE))
  
        clear_thread_flag(TIF_FOREIGN_FPSTATE);
  
-       local_bh_enable();
+       put_cpu_fpsimd_context();
  }
  
  /*
@@@ -1133,18 -1174,29 +1187,29 @@@ void fpsimd_flush_task_state(struct tas
  
  /*
   * Invalidate any task's FPSIMD state that is present on this cpu.
-  * This function must be called with softirqs disabled.
+  * The FPSIMD context should be acquired with get_cpu_fpsimd_context()
+  * before calling this function.
   */
- void fpsimd_flush_cpu_state(void)
static void fpsimd_flush_cpu_state(void)
  {
        __this_cpu_write(fpsimd_last_state.st, NULL);
        set_thread_flag(TIF_FOREIGN_FPSTATE);
  }
  
- #ifdef CONFIG_KERNEL_MODE_NEON
+ /*
+  * Save the FPSIMD state to memory and invalidate cpu view.
+  * This function must be called with preemption disabled.
+  */
+ void fpsimd_save_and_flush_cpu_state(void)
+ {
+       WARN_ON(preemptible());
+       __get_cpu_fpsimd_context();
+       fpsimd_save();
+       fpsimd_flush_cpu_state();
+       __put_cpu_fpsimd_context();
+ }
  
- DEFINE_PER_CPU(bool, kernel_neon_busy);
- EXPORT_PER_CPU_SYMBOL(kernel_neon_busy);
+ #ifdef CONFIG_KERNEL_MODE_NEON
  
  /*
   * Kernel-side NEON support functions
@@@ -1170,19 -1222,13 +1235,13 @@@ void kernel_neon_begin(void
  
        BUG_ON(!may_use_simd());
  
-       local_bh_disable();
-       __this_cpu_write(kernel_neon_busy, true);
+       get_cpu_fpsimd_context();
  
        /* Save unsaved fpsimd state, if any: */
        fpsimd_save();
  
        /* Invalidate any task state remaining in the fpsimd regs: */
        fpsimd_flush_cpu_state();
-       preempt_disable();
-       local_bh_enable();
  }
  EXPORT_SYMBOL(kernel_neon_begin);
  
   */
  void kernel_neon_end(void)
  {
-       bool busy;
        if (!system_supports_fpsimd())
                return;
  
-       busy = __this_cpu_xchg(kernel_neon_busy, false);
-       WARN_ON(!busy); /* No matching kernel_neon_begin()? */
-       preempt_enable();
+       put_cpu_fpsimd_context();
  }
  EXPORT_SYMBOL(kernel_neon_end);
  
@@@ -1297,8 -1338,7 +1351,7 @@@ static int fpsimd_cpu_pm_notifier(struc
  {
        switch (cmd) {
        case CPU_PM_ENTER:
-               fpsimd_save();
-               fpsimd_flush_cpu_state();
+               fpsimd_save_and_flush_cpu_state();
                break;
        case CPU_PM_EXIT:
                break;
diff --combined arch/arm64/kernel/irq.c
index c70034fbd4ce0e9820d07ae9279f4c28643c3e7f,e8daa7aa77bcf063b9a8d60f2a9bbc599e14e151..04a327ccf84da11d32cb1a46814b16b97e0306dd
@@@ -1,4 -1,3 +1,4 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Based on arch/arm/kernel/irq.c
   *
@@@ -8,6 -7,18 +8,6 @@@
   * Dynamic Tick Timer written by Tony Lindgren <[email protected]> and
   * Tuukka Tikkanen <[email protected]>.
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #include <linux/kernel_stat.h>
  #include <linux/smp.h>
  #include <linux/init.h>
  #include <linux/irqchip.h>
+ #include <linux/kprobes.h>
  #include <linux/seq_file.h>
  #include <linux/vmalloc.h>
+ #include <asm/daifflags.h>
  #include <asm/vmap_stack.h>
  
  unsigned long irq_err_count;
@@@ -64,4 -77,28 +66,28 @@@ void __init init_IRQ(void
        irqchip_init();
        if (!handle_arch_irq)
                panic("No interrupt controller found.");
+       if (system_uses_irq_prio_masking()) {
+               /*
+                * Now that we have a stack for our IRQ handler, set
+                * the PMR/PSR pair to a consistent state.
+                */
+               WARN_ON(read_sysreg(daif) & PSR_A_BIT);
+               local_daif_restore(DAIF_PROCCTX_NOIRQ);
+       }
+ }
+ /*
+  * Stubs to make nmi_enter/exit() code callable from ASM
+  */
+ asmlinkage void notrace asm_nmi_enter(void)
+ {
+       nmi_enter();
+ }
+ NOKPROBE_SYMBOL(asm_nmi_enter);
+ asmlinkage void notrace asm_nmi_exit(void)
+ {
+       nmi_exit();
  }
+ NOKPROBE_SYMBOL(asm_nmi_exit);
index 71530e080ecc6e1b828a50d362728ff82c694194,5b5936b7868c4dd09cbd0aec012666cec74373cd..46e643e307082c0fee4129724ea74e9a98c99201
@@@ -1,9 -1,20 +1,9 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * AArch64 loadable module support.
   *
   * Copyright (C) 2012 ARM Limited
   *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 - *
   * Author: Will Deacon <[email protected]>
   */
  
@@@ -21,7 -32,6 +21,7 @@@
  
  void *module_alloc(unsigned long size)
  {
 +      u64 module_alloc_end = module_alloc_base + MODULES_VSIZE;
        gfp_t gfp_mask = GFP_KERNEL;
        void *p;
  
        if (IS_ENABLED(CONFIG_ARM64_MODULE_PLTS))
                gfp_mask |= __GFP_NOWARN;
  
 +      if (IS_ENABLED(CONFIG_KASAN))
 +              /* don't exceed the static module region - see below */
 +              module_alloc_end = MODULES_END;
 +
        p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
-                               module_alloc_end, gfp_mask, PAGE_KERNEL_EXEC, 0,
 -                              module_alloc_base + MODULES_VSIZE,
 -                              gfp_mask, PAGE_KERNEL, 0,
++                              module_alloc_end, gfp_mask, PAGE_KERNEL, 0,
                                NUMA_NO_NODE, __builtin_return_address(0));
  
        if (!p && IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) &&
@@@ -50,7 -57,7 +50,7 @@@
                 */
                p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
                                module_alloc_base + SZ_2G, GFP_KERNEL,
-                               PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
+                               PAGE_KERNEL, 0, NUMA_NO_NODE,
                                __builtin_return_address(0));
  
        if (p && (kasan_module_alloc(p, size) < 0)) {
index 9856395ccdb708aea9608f79624abe829e671e11,58efc3727778bd58e4fff12f3f10a19c69c09830..6a869d9f304f73f4e6d91f52e5c4ac446fc9bf1a
@@@ -1,10 -1,21 +1,10 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Based on arch/arm/kernel/process.c
   *
   * Original Copyright (C) 1995  Linus Torvalds
   * Copyright (C) 1996-2000 Russell King - Converted to ARM.
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #include <stdarg.h>
@@@ -83,7 -94,7 +83,7 @@@ static void __cpu_do_idle_irqprio(void
         * be raised.
         */
        pmr = gic_read_pmr();
-       gic_write_pmr(GIC_PRIO_IRQON);
+       gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
  
        __cpu_do_idle();
  
index da2441d7b0660cfbcae43a302e974dfcc54f2ba3,9353355cb91afbe32431d2a7343e0c3da2a159c4..3cf3b135027e3fae6e26017ba8406f8a80b19f0f
@@@ -1,4 -1,3 +1,4 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Based on arch/arm/kernel/ptrace.c
   *
@@@ -6,6 -5,18 +6,6 @@@
   * edited by Linus Torvalds
   * ARM modifications Copyright (C) 2000 Russell King
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #include <linux/audit.h>
@@@ -1808,8 -1819,12 +1808,12 @@@ static void tracehook_report_syscall(st
  
  int syscall_trace_enter(struct pt_regs *regs)
  {
-       if (test_thread_flag(TIF_SYSCALL_TRACE))
+       if (test_thread_flag(TIF_SYSCALL_TRACE) ||
+               test_thread_flag(TIF_SYSCALL_EMU)) {
                tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+               if (!in_syscall(regs) || test_thread_flag(TIF_SYSCALL_EMU))
+                       return -1;
+       }
  
        /* Do the secure computing after ptrace; failures should be fast. */
        if (secure_computing(NULL) == -1)
diff --combined arch/arm64/kernel/smp.c
index 6dcf9607d7707795100b5316e8f68c6a50611fc5,434d6714358bdfde7221d547995209bc91fdd708..9286ee6749e8ce42fd498c1c1714fc216e4f67b3
@@@ -1,9 -1,20 +1,9 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * SMP initialisation and IPI support
   * Based on arch/arm/kernel/smp.c
   *
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #include <linux/acpi.h>
@@@ -181,11 -192,7 +181,7 @@@ static void init_gic_priority_masking(v
  
        WARN_ON(!(cpuflags & PSR_I_BIT));
  
-       gic_write_pmr(GIC_PRIO_IRQOFF);
-       /* We can only unmask PSR.I if we can take aborts */
-       if (!(cpuflags & PSR_A_BIT))
-               write_sysreg(cpuflags & ~PSR_I_BIT, daif);
+       gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
  }
  
  /*
@@@ -834,18 -841,23 +830,23 @@@ void arch_irq_work_raise(void
  }
  #endif
  
- /*
-  * ipi_cpu_stop - handle IPI from smp_send_stop()
-  */
- static void ipi_cpu_stop(unsigned int cpu)
+ static void local_cpu_stop(void)
  {
-       set_cpu_online(cpu, false);
+       set_cpu_online(smp_processor_id(), false);
  
        local_daif_mask();
        sdei_mask_local_cpu();
+       cpu_park_loop();
+ }
  
-       while (1)
-               cpu_relax();
+ /*
+  * We need to implement panic_smp_self_stop() for parallel panic() calls, so
+  * that cpu_online_mask gets correctly updated and smp_send_stop() can skip
+  * CPUs that have already stopped themselves.
+  */
+ void panic_smp_self_stop(void)
+ {
+       local_cpu_stop();
  }
  
  #ifdef CONFIG_KEXEC_CORE
@@@ -898,7 -910,7 +899,7 @@@ void handle_IPI(int ipinr, struct pt_re
  
        case IPI_CPU_STOP:
                irq_enter();
-               ipi_cpu_stop(cpu);
+               local_cpu_stop();
                irq_exit();
                break;
  
index 985721a1264c907e5d4ae161cc4e03e4943bb2e7,8a395523adcf1d9e79d999543936a460a7adc51d..a835a1a53826e850fb9c4210c6e87f333d055050
@@@ -1,9 -1,20 +1,9 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Based on arch/arm/kernel/traps.c
   *
   * Copyright (C) 1995-2009 Russell King
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #include <linux/bug.h>
@@@ -55,16 -66,19 +55,19 @@@ static void dump_backtrace_entry(unsign
        printk(" %pS\n", (void *)where);
  }
  
- static void __dump_instr(const char *lvl, struct pt_regs *regs)
+ static void dump_kernel_instr(const char *lvl, struct pt_regs *regs)
  {
        unsigned long addr = instruction_pointer(regs);
        char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
        int i;
  
+       if (user_mode(regs))
+               return;
        for (i = -4; i < 1; i++) {
                unsigned int val, bad;
  
-               bad = get_user(val, &((u32 *)addr)[i]);
+               bad = aarch64_insn_read(&((u32 *)addr)[i], &val);
  
                if (!bad)
                        p += sprintf(p, i == 0 ? "(%08x) " : "%08x ", val);
                        break;
                }
        }
-       printk("%sCode: %s\n", lvl, str);
- }
  
- static void dump_instr(const char *lvl, struct pt_regs *regs)
- {
-       if (!user_mode(regs)) {
-               mm_segment_t fs = get_fs();
-               set_fs(KERNEL_DS);
-               __dump_instr(lvl, regs);
-               set_fs(fs);
-       } else {
-               __dump_instr(lvl, regs);
-       }
+       printk("%sCode: %s\n", lvl, str);
  }
  
  void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
@@@ -171,8 -174,7 +163,7 @@@ static int __die(const char *str, int e
        print_modules();
        show_regs(regs);
  
-       if (!user_mode(regs))
-               dump_instr(KERN_EMERG, regs);
+       dump_kernel_instr(KERN_EMERG, regs);
  
        return ret;
  }
index b0041812bca929a35258cc9550d13e6817b3c59f,b89fcf0173b748739417ee9e724ff0134aff7f3c..58f281b6ca4a97d50167899cd6d5ddfb29f708f3
@@@ -1,7 -1,18 +1,7 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Copyright (C) 2015 - ARM Ltd
   * Author: Marc Zyngier <[email protected]>
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #include <linux/arm-smccc.h>
@@@ -604,7 -615,7 +604,7 @@@ int __hyp_text __kvm_vcpu_run_nvhe(stru
         * Naturally, we want to avoid this.
         */
        if (system_uses_irq_prio_masking()) {
-               gic_write_pmr(GIC_PRIO_IRQON);
+               gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
                dsb(sy);
        }
  
index 5992eb9a9a08e6f315ea77db0b7fe7c2aa0e0781,ff410195dc1cfa5f8994fedbc55cd0cff61e329c..1d17dbeafe7605f6c5efe63ae192b35e27046faf
@@@ -1,9 -1,20 +1,9 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * SWIOTLB-based DMA API implementation
   *
   * Copyright (C) 2012 ARM Ltd.
   * Author: Catalin Marinas <[email protected]>
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #include <linux/gfp.h>
@@@ -80,10 -91,6 +80,6 @@@ static int __swiotlb_mmap_pfn(struct vm
  
  static int __init arm64_dma_init(void)
  {
-       WARN_TAINT(ARCH_DMA_MINALIGN < cache_line_size(),
-                  TAINT_CPU_OUT_OF_SPEC,
-                  "ARCH_DMA_MINALIGN smaller than CTR_EL0.CWG (%d < %d)",
-                  ARCH_DMA_MINALIGN, cache_line_size());
        return dma_atomic_pool_init(GFP_DMA32, __pgprot(PROT_NORMAL_NC));
  }
  arch_initcall(arm64_dma_init);
@@@ -461,6 -468,14 +457,14 @@@ static void __iommu_setup_dma_ops(struc
  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
                        const struct iommu_ops *iommu, bool coherent)
  {
+       int cls = cache_line_size_of_cpu();
+       WARN_TAINT(!coherent && cls > ARCH_DMA_MINALIGN,
+                  TAINT_CPU_OUT_OF_SPEC,
+                  "%s %s: ARCH_DMA_MINALIGN smaller than CTR_EL0.CWG (%d < %d)",
+                  dev_driver_string(dev), dev_name(dev),
+                  ARCH_DMA_MINALIGN, cls);
        dev->dma_coherent = coherent;
        __iommu_setup_dma_ops(dev, dma_base, size, iommu);
  
diff --combined arch/arm64/mm/fault.c
index 2d115016feb428ffb2fbd26d3fe0e522e1069c42,582061dec89fae077d516c2366349bae917f6c7d..c8c61b1eb479b358a614cb56907b10422e00f34b
@@@ -1,10 -1,21 +1,10 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Based on arch/arm/mm/fault.c
   *
   * Copyright (C) 1995  Linus Torvalds
   * Copyright (C) 1995-2004 Russell King
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #include <linux/acpi.h>
@@@ -384,40 -395,31 +384,31 @@@ static void do_bad_area(unsigned long a
  #define VM_FAULT_BADACCESS    0x020000
  
  static vm_fault_t __do_page_fault(struct mm_struct *mm, unsigned long addr,
-                          unsigned int mm_flags, unsigned long vm_flags,
-                          struct task_struct *tsk)
+                          unsigned int mm_flags, unsigned long vm_flags)
  {
-       struct vm_area_struct *vma;
-       vm_fault_t fault;
+       struct vm_area_struct *vma = find_vma(mm, addr);
  
-       vma = find_vma(mm, addr);
-       fault = VM_FAULT_BADMAP;
        if (unlikely(!vma))
-               goto out;
-       if (unlikely(vma->vm_start > addr))
-               goto check_stack;
+               return VM_FAULT_BADMAP;
  
        /*
         * Ok, we have a good vm_area for this memory access, so we can handle
         * it.
         */
- good_area:
+       if (unlikely(vma->vm_start > addr)) {
+               if (!(vma->vm_flags & VM_GROWSDOWN))
+                       return VM_FAULT_BADMAP;
+               if (expand_stack(vma, addr))
+                       return VM_FAULT_BADMAP;
+       }
        /*
         * Check that the permissions on the VMA allow for the fault which
         * occurred.
         */
-       if (!(vma->vm_flags & vm_flags)) {
-               fault = VM_FAULT_BADACCESS;
-               goto out;
-       }
+       if (!(vma->vm_flags & vm_flags))
+               return VM_FAULT_BADACCESS;
        return handle_mm_fault(vma, addr & PAGE_MASK, mm_flags);
- check_stack:
-       if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
-               goto good_area;
- out:
-       return fault;
  }
  
  static bool is_el0_instruction_abort(unsigned int esr)
        return ESR_ELx_EC(esr) == ESR_ELx_EC_IABT_LOW;
  }
  
+ /*
+  * Note: not valid for EL1 DC IVAC, but we never use that such that it
+  * should fault. EL0 cannot issue DC IVAC (undef).
+  */
+ static bool is_write_abort(unsigned int esr)
+ {
+       return (esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM);
+ }
  static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
                                   struct pt_regs *regs)
  {
        const struct fault_info *inf;
-       struct task_struct *tsk;
-       struct mm_struct *mm;
+       struct mm_struct *mm = current->mm;
        vm_fault_t fault, major = 0;
        unsigned long vm_flags = VM_READ | VM_WRITE;
        unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
        if (notify_page_fault(regs, esr))
                return 0;
  
-       tsk = current;
-       mm  = tsk->mm;
        /*
         * If we're in an interrupt or have no user context, we must not take
         * the fault.
  
        if (is_el0_instruction_abort(esr)) {
                vm_flags = VM_EXEC;
-       } else if ((esr & ESR_ELx_WNR) && !(esr & ESR_ELx_CM)) {
+               mm_flags |= FAULT_FLAG_INSTRUCTION;
+       } else if (is_write_abort(esr)) {
                vm_flags = VM_WRITE;
                mm_flags |= FAULT_FLAG_WRITE;
        }
@@@ -492,12 -500,14 +489,14 @@@ retry
                 */
                might_sleep();
  #ifdef CONFIG_DEBUG_VM
-               if (!user_mode(regs) && !search_exception_tables(regs->pc))
+               if (!user_mode(regs) && !search_exception_tables(regs->pc)) {
+                       up_read(&mm->mmap_sem);
                        goto no_context;
+               }
  #endif
        }
  
-       fault = __do_page_fault(mm, addr, mm_flags, vm_flags, tsk);
+       fault = __do_page_fault(mm, addr, mm_flags, vm_flags);
        major |= fault & VM_FAULT_MAJOR;
  
        if (fault & VM_FAULT_RETRY) {
                 * that point.
                 */
                if (major) {
-                       tsk->maj_flt++;
+                       current->maj_flt++;
                        perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs,
                                      addr);
                } else {
-                       tsk->min_flt++;
+                       current->min_flt++;
                        perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs,
                                      addr);
                }
diff --combined arch/arm64/mm/init.c
index 749c9b269f0873d6de18bf85ec59a299b3b6b352,f643bd45ff699a65cd4afc849a9bd0e2bc3bc833..f3c795278def0ea01704c6b38fe3d2d140351224
@@@ -1,9 -1,20 +1,9 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Based on arch/arm/mm/init.c
   *
   * Copyright (C) 1995-2005 Russell King
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #include <linux/kernel.h>
@@@ -180,8 -191,9 +180,9 @@@ static void __init zone_sizes_init(unsi
  {
        unsigned long max_zone_pfns[MAX_NR_ZONES]  = {0};
  
-       if (IS_ENABLED(CONFIG_ZONE_DMA32))
-               max_zone_pfns[ZONE_DMA32] = PFN_DOWN(max_zone_dma_phys());
+ #ifdef CONFIG_ZONE_DMA32
+       max_zone_pfns[ZONE_DMA32] = PFN_DOWN(max_zone_dma_phys());
+ #endif
        max_zone_pfns[ZONE_NORMAL] = max;
  
        free_area_init_nodes(max_zone_pfns);
diff --combined arch/arm64/mm/mmu.c
index e5ae8663f2305812c281fda575f109187db8c4e6,21f3931c73fd3357f4b6d8b8dc070e990cc35dda..3645f29bd814705cf2356de7186c64f3dd16f570
@@@ -1,9 -1,20 +1,9 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Based on arch/arm/mm/mmu.c
   *
   * Copyright (C) 1995-2005 Russell King
   * Copyright (C) 2012 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #include <linux/cache.h>
@@@ -765,7 -776,7 +765,7 @@@ int __meminit vmemmap_populate(unsigne
  
        return 0;
  }
- #endif        /* CONFIG_ARM64_64K_PAGES */
+ #endif        /* !ARM64_SWAPPER_USES_SECTION_MAPS */
  void vmemmap_free(unsigned long start, unsigned long end,
                struct vmem_altmap *altmap)
  {
@@@ -960,32 -971,28 +960,28 @@@ int __init arch_ioremap_pmd_supported(v
  
  int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot)
  {
-       pgprot_t sect_prot = __pgprot(PUD_TYPE_SECT |
-                                       pgprot_val(mk_sect_prot(prot)));
-       pud_t new_pud = pfn_pud(__phys_to_pfn(phys), sect_prot);
+       pud_t new_pud = pfn_pud(__phys_to_pfn(phys), mk_pud_sect_prot(prot));
  
        /* Only allow permission changes for now */
        if (!pgattr_change_is_safe(READ_ONCE(pud_val(*pudp)),
                                   pud_val(new_pud)))
                return 0;
  
-       BUG_ON(phys & ~PUD_MASK);
+       VM_BUG_ON(phys & ~PUD_MASK);
        set_pud(pudp, new_pud);
        return 1;
  }
  
  int pmd_set_huge(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot)
  {
-       pgprot_t sect_prot = __pgprot(PMD_TYPE_SECT |
-                                       pgprot_val(mk_sect_prot(prot)));
-       pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), sect_prot);
+       pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), mk_pmd_sect_prot(prot));
  
        /* Only allow permission changes for now */
        if (!pgattr_change_is_safe(READ_ONCE(pmd_val(*pmdp)),
                                   pmd_val(new_pmd)))
                return 0;
  
-       BUG_ON(phys & ~PMD_MASK);
+       VM_BUG_ON(phys & ~PMD_MASK);
        set_pmd(pmdp, new_pmd);
        return 1;
  }
diff --combined arch/arm64/mm/pageattr.c
index 47b057bfa8032b8c84b0abca294ffb0d6c64890f,9c6b9039ec8f5a9aff9a4755807f4e9fc889060b..fcdcf6cd7677e0c0d02067d567f6df5255b17fe2
@@@ -1,6 -1,14 +1,6 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 - *
 - * This program is free software; you can redistribute it and/or modify
 - * it under the terms of the GNU General Public License version 2 and
 - * only version 2 as published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
   */
  #include <linux/kernel.h>
  #include <linux/mm.h>
@@@ -151,17 -159,48 +151,48 @@@ int set_memory_valid(unsigned long addr
                                        __pgprot(PTE_VALID));
  }
  
- #ifdef CONFIG_DEBUG_PAGEALLOC
+ int set_direct_map_invalid_noflush(struct page *page)
+ {
+       struct page_change_data data = {
+               .set_mask = __pgprot(0),
+               .clear_mask = __pgprot(PTE_VALID),
+       };
+       if (!rodata_full)
+               return 0;
+       return apply_to_page_range(&init_mm,
+                                  (unsigned long)page_address(page),
+                                  PAGE_SIZE, change_page_range, &data);
+ }
+ int set_direct_map_default_noflush(struct page *page)
+ {
+       struct page_change_data data = {
+               .set_mask = __pgprot(PTE_VALID | PTE_WRITE),
+               .clear_mask = __pgprot(PTE_RDONLY),
+       };
+       if (!rodata_full)
+               return 0;
+       return apply_to_page_range(&init_mm,
+                                  (unsigned long)page_address(page),
+                                  PAGE_SIZE, change_page_range, &data);
+ }
  void __kernel_map_pages(struct page *page, int numpages, int enable)
  {
+       if (!debug_pagealloc_enabled() && !rodata_full)
+               return;
        set_memory_valid((unsigned long)page_address(page), numpages, enable);
  }
- #ifdef CONFIG_HIBERNATION
  /*
-  * When built with CONFIG_DEBUG_PAGEALLOC and CONFIG_HIBERNATION, this function
-  * is used to determine if a linear map page has been marked as not-valid by
-  * CONFIG_DEBUG_PAGEALLOC. Walk the page table and check the PTE_VALID bit.
-  * This is based on kern_addr_valid(), which almost does what we need.
+  * This function is used to determine if a linear map page has been marked as
+  * not-valid. Walk the page table and check the PTE_VALID bit. This is based
+  * on kern_addr_valid(), which almost does what we need.
   *
   * Because this is only called on the kernel linear map,  p?d_sect() implies
   * p?d_present(). When debug_pagealloc is enabled, sections mappings are
@@@ -175,6 -214,9 +206,9 @@@ bool kernel_page_present(struct page *p
        pte_t *ptep;
        unsigned long addr = (unsigned long)page_address(page);
  
+       if (!debug_pagealloc_enabled() && !rodata_full)
+               return true;
        pgdp = pgd_offset_k(addr);
        if (pgd_none(READ_ONCE(*pgdp)))
                return false;
        ptep = pte_offset_kernel(pmdp, addr);
        return pte_valid(READ_ONCE(*ptep));
  }
- #endif /* CONFIG_HIBERNATION */
- #endif /* CONFIG_DEBUG_PAGEALLOC */
index 87c568807925e265d95d47b017644cc398c8ef0d,aef4ff467222c883cd8eea01f88bc020f2544909..f5b437f8a22b4042f29d4e8c55b181efd3350210
@@@ -1,8 -1,19 +1,8 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * BPF JIT compiler for ARM64
   *
   * Copyright (C) 2014-2016 Zi Shen Lim <[email protected]>
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #define pr_fmt(fmt) "bpf_jit: " fmt
@@@ -970,7 -981,7 +970,7 @@@ void *bpf_jit_alloc_exec(unsigned long 
  {
        return __vmalloc_node_range(size, PAGE_SIZE, BPF_JIT_REGION_START,
                                    BPF_JIT_REGION_END, GFP_KERNEL,
-                                   PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
+                                   PAGE_KERNEL, 0, NUMA_NO_NODE,
                                    __builtin_return_address(0));
  }
  
diff --combined arch/x86/entry/common.c
index 2418804e66b4d8ec686b13c480de04c8c3ad141f,0a61705d62ec37b2fb03426caef26ba4a063d182..536b574b61613403618c3db62d72c6adac91af98
@@@ -1,7 -1,7 +1,7 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * common.c - C code for kernel entry and exit
   * Copyright (c) 2015 Andrew Lutomirski
 - * GPL v2
   *
   * Based on asm and ptrace code by many authors.  The code here originated
   * in ptrace.c and signal.c.
@@@ -72,23 -72,18 +72,18 @@@ static long syscall_trace_enter(struct 
  
        struct thread_info *ti = current_thread_info();
        unsigned long ret = 0;
-       bool emulated = false;
        u32 work;
  
        if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
                BUG_ON(regs != task_pt_regs(current));
  
-       work = READ_ONCE(ti->flags) & _TIF_WORK_SYSCALL_ENTRY;
+       work = READ_ONCE(ti->flags);
  
-       if (unlikely(work & _TIF_SYSCALL_EMU))
-               emulated = true;
-       if ((emulated || (work & _TIF_SYSCALL_TRACE)) &&
-           tracehook_report_syscall_entry(regs))
-               return -1L;
-       if (emulated)
-               return -1L;
+       if (work & (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU)) {
+               ret = tracehook_report_syscall_entry(regs);
+               if (ret || (work & _TIF_SYSCALL_EMU))
+                       return -1L;
+       }
  
  #ifdef CONFIG_SECCOMP
        /*
index 6377cb864f4c4a180b64dd85a00e20d62e71ba01,b176700bb3878cfb827a8bda643e1bb2c84474ac..f3e44d6d9255cf73ceae5d1b144ef7d9f7b9c48f
@@@ -1,7 -1,18 +1,7 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Copyright (C) 2013-2017 ARM Limited, All Rights Reserved.
   * Author: Marc Zyngier <[email protected]>
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  #define pr_fmt(fmt)   "GICv3: " fmt
@@@ -461,8 -472,12 +461,12 @@@ static void gic_deactivate_unhandled(u3
  
  static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs)
  {
+       bool irqs_enabled = interrupts_enabled(regs);
        int err;
  
+       if (irqs_enabled)
+               nmi_enter();
        if (static_branch_likely(&supports_deactivate_key))
                gic_write_eoir(irqnr);
        /*
        err = handle_domain_nmi(gic_data.domain, irqnr, regs);
        if (err)
                gic_deactivate_unhandled(irqnr);
+       if (irqs_enabled)
+               nmi_exit();
  }
  
  static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
index d2c2978409d24aadc7d0dd2585367005cd1e51c4,864d7ebe45e926b0223c2b2df8a8fe6bee7777a2..acce8781c456cd7a3e36ca07bc8d18946a7fefd1
@@@ -1,8 -1,11 +1,8 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * ACPI probing code for ARM performance counters.
   *
   * Copyright (C) 2017 ARM Ltd.
 - *
 - * 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
 - * published by the Free Software Foundation.
   */
  
  #include <linux/acpi.h>
@@@ -71,6 -74,76 +71,76 @@@ static void arm_pmu_acpi_unregister_irq
        acpi_unregister_gsi(gsi);
  }
  
+ #if IS_ENABLED(CONFIG_ARM_SPE_PMU)
+ static struct resource spe_resources[] = {
+       {
+               /* irq */
+               .flags          = IORESOURCE_IRQ,
+       }
+ };
+ static struct platform_device spe_dev = {
+       .name = ARMV8_SPE_PDEV_NAME,
+       .id = -1,
+       .resource = spe_resources,
+       .num_resources = ARRAY_SIZE(spe_resources)
+ };
+ /*
+  * For lack of a better place, hook the normal PMU MADT walk
+  * and create a SPE device if we detect a recent MADT with
+  * a homogeneous PPI mapping.
+  */
+ static void arm_spe_acpi_register_device(void)
+ {
+       int cpu, hetid, irq, ret;
+       bool first = true;
+       u16 gsi = 0;
+       /*
+        * Sanity check all the GICC tables for the same interrupt number.
+        * For now, we only support homogeneous ACPI/SPE machines.
+        */
+       for_each_possible_cpu(cpu) {
+               struct acpi_madt_generic_interrupt *gicc;
+               gicc = acpi_cpu_get_madt_gicc(cpu);
+               if (gicc->header.length < ACPI_MADT_GICC_SPE)
+                       return;
+               if (first) {
+                       gsi = gicc->spe_interrupt;
+                       if (!gsi)
+                               return;
+                       hetid = find_acpi_cpu_topology_hetero_id(cpu);
+                       first = false;
+               } else if ((gsi != gicc->spe_interrupt) ||
+                          (hetid != find_acpi_cpu_topology_hetero_id(cpu))) {
+                       pr_warn("ACPI: SPE must be homogeneous\n");
+                       return;
+               }
+       }
+       irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE,
+                               ACPI_ACTIVE_HIGH);
+       if (irq < 0) {
+               pr_warn("ACPI: SPE Unable to register interrupt: %d\n", gsi);
+               return;
+       }
+       spe_resources[0].start = irq;
+       ret = platform_device_register(&spe_dev);
+       if (ret < 0) {
+               pr_warn("ACPI: SPE: Unable to register device\n");
+               acpi_unregister_gsi(gsi);
+       }
+ }
+ #else
+ static inline void arm_spe_acpi_register_device(void)
+ {
+ }
+ #endif /* CONFIG_ARM_SPE_PMU */
  static int arm_pmu_acpi_parse_irqs(void)
  {
        int irq, cpu, irq_cpu, err;
@@@ -276,6 -349,8 +346,8 @@@ static int arm_pmu_acpi_init(void
        if (acpi_disabled)
                return 0;
  
+       arm_spe_acpi_register_device();
        ret = arm_pmu_acpi_parse_irqs();
        if (ret)
                return ret;
index 49b4909252555598b6c665dd0d27a49a11e35ecf,4fb65c61c8eab102c7dd8d3205f039a1a65997a5..4e4984a55cd1b1d823bca44c840a49e7d8cf889f
@@@ -1,8 -1,19 +1,8 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Perf support for the Statistical Profiling Extension, introduced as
   * part of ARMv8.2.
   *
 - * 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
 - * published by the Free Software Foundation.
 - *
 - * This program is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - * GNU General Public License for more details.
 - *
 - * You should have received a copy of the GNU General Public License
 - * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 - *
   * Copyright (C) 2016 ARM Limited
   *
   * Author: Will Deacon <[email protected]>
@@@ -27,6 -38,7 +27,7 @@@
  #include <linux/of_address.h>
  #include <linux/of_device.h>
  #include <linux/perf_event.h>
+ #include <linux/perf/arm_pmu.h>
  #include <linux/platform_device.h>
  #include <linux/printk.h>
  #include <linux/slab.h>
@@@ -1157,7 -1169,13 +1158,13 @@@ static const struct of_device_id arm_sp
  };
  MODULE_DEVICE_TABLE(of, arm_spe_pmu_of_match);
  
- static int arm_spe_pmu_device_dt_probe(struct platform_device *pdev)
+ static const struct platform_device_id arm_spe_match[] = {
+       { ARMV8_SPE_PDEV_NAME, 0},
+       { }
+ };
+ MODULE_DEVICE_TABLE(platform, arm_spe_match);
+ static int arm_spe_pmu_device_probe(struct platform_device *pdev)
  {
        int ret;
        struct arm_spe_pmu *spe_pmu;
@@@ -1217,11 -1235,12 +1224,12 @@@ static int arm_spe_pmu_device_remove(st
  }
  
  static struct platform_driver arm_spe_pmu_driver = {
+       .id_table = arm_spe_match,
        .driver = {
                .name           = DRVNAME,
                .of_match_table = of_match_ptr(arm_spe_pmu_of_match),
        },
-       .probe  = arm_spe_pmu_device_dt_probe,
+       .probe  = arm_spe_pmu_device_probe,
        .remove = arm_spe_pmu_device_remove,
  };
  
index a9b0ee408fbd44232644ade36fd86846d2d4c243,784bc58f165aa128247f2622a12daaeee6ff485d..71f525a35ac2b6abcebe8549e8bc3a6dfebfa43d
@@@ -1,8 -1,12 +1,8 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   *  linux/arch/arm/include/asm/pmu.h
   *
   *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
 - *
 - * 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
 - * published by the Free Software Foundation.
 - *
   */
  
  #ifndef __ARM_PMU_H__
@@@ -171,4 -175,6 +171,6 @@@ void armpmu_free_irq(int irq, int cpu)
  
  #endif /* CONFIG_ARM_PMU */
  
+ #define ARMV8_SPE_PDEV_NAME "arm,spe-v1"
  #endif /* __ARM_PMU_H__ */
diff --combined kernel/ptrace.c
index 705887f63288d4694c5bccd5c77900cbddc1f843,ab14654b24367a06fa150e35b21cb99e56fb348a..83a531cea2f3789fd42320e4bb5d03670be0f92a
@@@ -79,7 -79,9 +79,7 @@@ void __ptrace_link(struct task_struct *
   */
  static void ptrace_link(struct task_struct *child, struct task_struct *new_parent)
  {
 -      rcu_read_lock();
 -      __ptrace_link(child, new_parent, __task_cred(new_parent));
 -      rcu_read_unlock();
 +      __ptrace_link(child, new_parent, current_cred());
  }
  
  /**
@@@ -116,6 -118,9 +116,9 @@@ void __ptrace_unlink(struct task_struc
        BUG_ON(!child->ptrace);
  
        clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ #ifdef TIF_SYSCALL_EMU
+       clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
+ #endif
  
        child->parent = child->real_parent;
        list_del_init(&child->ptrace_entry);
@@@ -322,16 -327,6 +325,16 @@@ static int __ptrace_may_access(struct t
        return -EPERM;
  ok:
        rcu_read_unlock();
 +      /*
 +       * If a task drops privileges and becomes nondumpable (through a syscall
 +       * like setresuid()) while we are trying to access it, we must ensure
 +       * that the dumpability is read after the credentials; otherwise,
 +       * we may be able to attach to a task that we shouldn't be able to
 +       * attach to (as if the task had dropped privileges without becoming
 +       * nondumpable).
 +       * Pairs with a write barrier in commit_creds().
 +       */
 +      smp_rmb();
        mm = task->mm;
        if (mm &&
            ((get_dumpable(mm) != SUID_DUMP_USER) &&
@@@ -713,10 -708,6 +716,10 @@@ static int ptrace_peek_siginfo(struct t
        if (arg.nr < 0)
                return -EINVAL;
  
 +      /* Ensure arg.off fits in an unsigned long */
 +      if (arg.off > ULONG_MAX)
 +              return 0;
 +
        if (arg.flags & PTRACE_PEEKSIGINFO_SHARED)
                pending = &child->signal->shared_pending;
        else
  
        for (i = 0; i < arg.nr; ) {
                kernel_siginfo_t info;
 -              s32 off = arg.off + i;
 +              unsigned long off = arg.off + i;
 +              bool found = false;
  
                spin_lock_irq(&child->sighand->siglock);
                list_for_each_entry(q, &pending->list, list) {
                        if (!off--) {
 +                              found = true;
                                copy_siginfo(&info, &q->info);
                                break;
                        }
                }
                spin_unlock_irq(&child->sighand->siglock);
  
 -              if (off >= 0) /* beyond the end of the list */
 +              if (!found) /* beyond the end of the list */
                        break;
  
  #ifdef CONFIG_COMPAT
diff --combined mm/vmalloc.c
index 0f76cca32a1ce2508bb42caf518d3d966f6550cd,6bd7b515995c057552ca23811143f8db7609495f..030a544e66020fb6af8b0719b551c5848a55aead
@@@ -913,7 -913,7 +913,7 @@@ adjust_va_to_fit_type(struct vmap_area 
        unsigned long nva_start_addr, unsigned long size,
        enum fit_type type)
  {
 -      struct vmap_area *lva;
 +      struct vmap_area *lva = NULL;
  
        if (type == FL_FIT_TYPE) {
                /*
        if (type != FL_FIT_TYPE) {
                augment_tree_propagate_from(va);
  
 -              if (type == NE_FIT_TYPE)
 +              if (lva)        /* type == NE_FIT_TYPE */
                        insert_vmap_area_augment(lva, &va->rb_node,
                                &free_vmap_area_root, &free_vmap_area_list);
        }
@@@ -2123,22 -2123,11 +2123,11 @@@ static inline void set_area_direct_map(
  /* Handle removing and resetting vm mappings related to the vm_struct. */
  static void vm_remove_mappings(struct vm_struct *area, int deallocate_pages)
  {
 -      unsigned long addr = (unsigned long)area->addr;
        unsigned long start = ULONG_MAX, end = 0;
        int flush_reset = area->flags & VM_FLUSH_RESET_PERMS;
 +      int flush_dmap = 0;
        int i;
  
-       /*
-        * The below block can be removed when all architectures that have
-        * direct map permissions also have set_direct_map_() implementations.
-        * This is concerned with resetting the direct map any an vm alias with
-        * execute permissions, without leaving a RW+X window.
-        */
-       if (flush_reset && !IS_ENABLED(CONFIG_ARCH_HAS_SET_DIRECT_MAP)) {
-               set_memory_nx((unsigned long)area->addr, area->nr_pages);
-               set_memory_rw((unsigned long)area->addr, area->nr_pages);
-       }
        remove_vm_area(area->addr);
  
        /* If this is not VM_FLUSH_RESET_PERMS memory, no need for the below. */
         * the vm_unmap_aliases() flush includes the direct map.
         */
        for (i = 0; i < area->nr_pages; i++) {
 -              if (page_address(area->pages[i])) {
 +              unsigned long addr = (unsigned long)page_address(area->pages[i]);
 +              if (addr) {
                        start = min(addr, start);
 -                      end = max(addr, end);
 +                      end = max(addr + PAGE_SIZE, end);
 +                      flush_dmap = 1;
                }
        }
  
         * reset the direct map permissions to the default.
         */
        set_area_direct_map(area, set_direct_map_invalid_noflush);
 -      _vm_unmap_aliases(start, end, 1);
 +      _vm_unmap_aliases(start, end, flush_dmap);
        set_area_direct_map(area, set_direct_map_default_noflush);
  }
  
This page took 0.301434 seconds and 4 git commands to generate.