Browse Source

Merge tag 'v4.19.79' of http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into ti-linux-4.19.y

This is the 4.19.79 stable release

* tag 'v4.19.79' of http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable: (627 commits)
  Linux 4.19.79
  nl80211: validate beacon head
  cfg80211: Use const more consistently in for_each_element macros
  cfg80211: add and use strongly typed element iteration macros
  staging: erofs: detect potential multiref due to corrupted images
  staging: erofs: add two missing erofs_workgroup_put for corrupted images
  staging: erofs: some compressed cluster should be submitted for corrupted images
  staging: erofs: fix an error handling in erofs_readdir()
  coresight: etm4x: Use explicit barriers on enable/disable
  vfs: Fix EOVERFLOW testing in put_compat_statfs64
  arm64/speculation: Support 'mitigations=' cmdline option
  arm64: Use firmware to detect CPUs that are not affected by Spectre-v2
  arm64: Force SSBS on context switch
  arm64: ssbs: Don't treat CPUs with SSBS as unaffected by SSB
  arm64: add sysfs vulnerability show for speculative store bypass
  arm64: add sysfs vulnerability show for spectre-v2
  arm64: Always enable spectre-v2 vulnerability detection
  arm64: Advertise mitigation of Spectre-v2, or lack thereof
  arm64: Provide a command line to disable spectre_v2 mitigation
  arm64: Always enable ssb vulnerability detection
  ...

Signed-off-by: Dan Murphy <dmurphy@ti.com>
Dan Murphy 6 years ago
parent
commit
957bfef413
100 changed files with 1012 additions and 327 deletions
  1. 9 7
      Documentation/admin-guide/kernel-parameters.txt
  2. 4 0
      Documentation/arm64/elf_hwcaps.txt
  3. 1 1
      Documentation/filesystems/overlayfs.txt
  4. 1 1
      Makefile
  5. 3 2
      arch/arm/Kconfig
  6. 1 0
      arch/arm/boot/dts/exynos5420-peach-pit.dts
  7. 1 0
      arch/arm/boot/dts/exynos5800-peach-pi.dts
  8. 1 0
      arch/arm/boot/dts/imx7-colibri.dtsi
  9. 2 2
      arch/arm/boot/dts/imx7d-cl-som-imx7.dts
  10. 2 1
      arch/arm/mach-omap1/ams-delta-fiq-handler.S
  11. 1 3
      arch/arm/mach-omap1/ams-delta-fiq.c
  12. 3 0
      arch/arm/mach-omap2/omap4-common.c
  13. 2 1
      arch/arm/mach-omap2/omap_hwmod_7xx_data.c
  14. 1 1
      arch/arm/mach-zynq/platsmp.c
  15. 2 2
      arch/arm/mm/fault.c
  16. 1 0
      arch/arm/mm/fault.h
  17. 7 1
      arch/arm/mm/init.c
  18. 13 3
      arch/arm/mm/mmap.c
  19. 16 0
      arch/arm/mm/mmu.c
  20. 1 0
      arch/arm/plat-samsung/watchdog-reset.c
  21. 1 0
      arch/arm64/Kconfig
  22. 3 0
      arch/arm64/boot/dts/rockchip/rk3328.dtsi
  23. 3 3
      arch/arm64/include/asm/cmpxchg.h
  24. 2 1
      arch/arm64/include/asm/cpucaps.h
  25. 0 4
      arch/arm64/include/asm/cpufeature.h
  26. 11 10
      arch/arm64/include/asm/cputype.h
  27. 11 0
      arch/arm64/include/asm/kvm_host.h
  28. 5 1
      arch/arm64/include/asm/pgtable.h
  29. 17 0
      arch/arm64/include/asm/processor.h
  30. 1 0
      arch/arm64/include/asm/ptrace.h
  31. 15 4
      arch/arm64/include/asm/sysreg.h
  32. 1 0
      arch/arm64/include/asm/tlbflush.h
  33. 1 0
      arch/arm64/include/uapi/asm/hwcap.h
  34. 1 0
      arch/arm64/include/uapi/asm/ptrace.h
  35. 202 69
      arch/arm64/kernel/cpu_errata.c
  36. 120 18
      arch/arm64/kernel/cpufeature.c
  37. 1 0
      arch/arm64/kernel/cpuinfo.c
  38. 31 0
      arch/arm64/kernel/process.c
  39. 8 7
      arch/arm64/kernel/ptrace.c
  40. 21 0
      arch/arm64/kernel/ssbd.c
  41. 11 0
      arch/arm64/kvm/hyp/sysreg-sr.c
  42. 5 1
      arch/arm64/mm/mmap.c
  43. 9 0
      arch/arm64/mm/proc.S
  44. 6 2
      arch/ia64/kernel/module.c
  45. 0 9
      arch/m68k/include/asm/atarihw.h
  46. 5 1
      arch/m68k/include/asm/io_mm.h
  47. 1 0
      arch/m68k/include/asm/macintosh.h
  48. 16 0
      arch/mips/include/asm/cpu-features.h
  49. 4 0
      arch/mips/include/asm/cpu.h
  50. 4 0
      arch/mips/include/asm/mipsregs.h
  51. 13 0
      arch/mips/kernel/cpu-probe.c
  52. 4 0
      arch/mips/kernel/proc.c
  53. 12 2
      arch/mips/mm/mmap.c
  54. 1 1
      arch/mips/mm/tlbex.c
  55. 2 2
      arch/powerpc/include/asm/cputable.h
  56. 1 2
      arch/powerpc/include/asm/futex.h
  57. 1 1
      arch/powerpc/include/asm/opal.h
  58. 1 0
      arch/powerpc/include/asm/uaccess.h
  59. 28 2
      arch/powerpc/kernel/dt_cpu_ftrs.c
  60. 10 1
      arch/powerpc/kernel/eeh_driver.c
  61. 4 0
      arch/powerpc/kernel/exceptions-64s.S
  62. 10 1
      arch/powerpc/kernel/mce.c
  63. 13 6
      arch/powerpc/kernel/mce_power.c
  64. 8 3
      arch/powerpc/kernel/rtas.c
  65. 1 0
      arch/powerpc/kernel/traps.c
  66. 18 6
      arch/powerpc/kvm/book3s_hv.c
  67. 1 1
      arch/powerpc/kvm/book3s_hv_rm_mmu.c
  68. 23 13
      arch/powerpc/kvm/book3s_hv_rmhandlers.S
  69. 10 8
      arch/powerpc/kvm/book3s_xive.c
  70. 1 1
      arch/powerpc/mm/hash_native_64.c
  71. 8 1
      arch/powerpc/mm/hash_utils_64.c
  72. 7 9
      arch/powerpc/mm/pgtable-radix.c
  73. 2 2
      arch/powerpc/mm/tlb-radix.c
  74. 6 6
      arch/powerpc/platforms/powernv/opal-imc.c
  75. 1 1
      arch/powerpc/platforms/powernv/opal-wrappers.S
  76. 7 4
      arch/powerpc/platforms/powernv/opal.c
  77. 23 15
      arch/powerpc/platforms/powernv/pci-ioda-tce.c
  78. 1 1
      arch/powerpc/platforms/powernv/pci.h
  79. 6 2
      arch/powerpc/platforms/pseries/lpar.c
  80. 9 0
      arch/powerpc/platforms/pseries/mobility.c
  81. 3 0
      arch/powerpc/platforms/pseries/setup.c
  82. 11 0
      arch/powerpc/sysdev/xive/native.c
  83. 9 6
      arch/powerpc/xmon/xmon.c
  84. 5 1
      arch/riscv/kernel/entry.S
  85. 6 0
      arch/s390/crypto/aes_s390.c
  86. 5 4
      arch/s390/hypfs/inode.c
  87. 16 6
      arch/s390/kernel/process.c
  88. 2 1
      arch/s390/kernel/topology.c
  89. 10 0
      arch/s390/kvm/interrupt.c
  90. 4 2
      arch/s390/kvm/kvm-s390.c
  91. 7 5
      arch/s390/net/bpf_jit_comp.c
  92. 1 0
      arch/x86/Makefile
  93. 10 3
      arch/x86/events/amd/ibs.c
  94. 6 0
      arch/x86/events/intel/core.c
  95. 5 3
      arch/x86/hyperv/mmu.c
  96. 3 0
      arch/x86/include/asm/intel-family.h
  97. 8 4
      arch/x86/include/asm/perf_event.h
  98. 3 1
      arch/x86/include/asm/uaccess.h
  99. 71 44
      arch/x86/kernel/apic/apic.c
  100. 7 1
      arch/x86/kernel/apic/io_apic.c

+ 9 - 7
Documentation/admin-guide/kernel-parameters.txt

@@ -2503,8 +2503,8 @@
 			http://repo.or.cz/w/linux-2.6/mini2440.git
 			http://repo.or.cz/w/linux-2.6/mini2440.git
 
 
 	mitigations=
 	mitigations=
-			[X86,PPC,S390] Control optional mitigations for CPU
-			vulnerabilities.  This is a set of curated,
+			[X86,PPC,S390,ARM64] Control optional mitigations for
+			CPU vulnerabilities.  This is a set of curated,
 			arch-independent options, each of which is an
 			arch-independent options, each of which is an
 			aggregation of existing arch-specific options.
 			aggregation of existing arch-specific options.
 
 
@@ -2513,12 +2513,14 @@
 				improves system performance, but it may also
 				improves system performance, but it may also
 				expose users to several CPU vulnerabilities.
 				expose users to several CPU vulnerabilities.
 				Equivalent to: nopti [X86,PPC]
 				Equivalent to: nopti [X86,PPC]
+					       kpti=0 [ARM64]
 					       nospectre_v1 [PPC]
 					       nospectre_v1 [PPC]
 					       nobp=0 [S390]
 					       nobp=0 [S390]
 					       nospectre_v1 [X86]
 					       nospectre_v1 [X86]
-					       nospectre_v2 [X86,PPC,S390]
+					       nospectre_v2 [X86,PPC,S390,ARM64]
 					       spectre_v2_user=off [X86]
 					       spectre_v2_user=off [X86]
 					       spec_store_bypass_disable=off [X86,PPC]
 					       spec_store_bypass_disable=off [X86,PPC]
+					       ssbd=force-off [ARM64]
 					       l1tf=off [X86]
 					       l1tf=off [X86]
 					       mds=off [X86]
 					       mds=off [X86]
 
 
@@ -2866,10 +2868,10 @@
 			(bounds check bypass). With this option data leaks
 			(bounds check bypass). With this option data leaks
 			are possible in the system.
 			are possible in the system.
 
 
-	nospectre_v2	[X86,PPC_FSL_BOOK3E] Disable all mitigations for the Spectre variant 2
-			(indirect branch prediction) vulnerability. System may
-			allow data leaks with this option, which is equivalent
-			to spectre_v2=off.
+	nospectre_v2	[X86,PPC_FSL_BOOK3E,ARM64] Disable all mitigations for
+			the Spectre variant 2 (indirect branch prediction)
+			vulnerability. System may allow data leaks with this
+			option.
 
 
 	nospec_store_bypass_disable
 	nospec_store_bypass_disable
 			[HW] Disable all mitigations for the Speculative Store Bypass vulnerability
 			[HW] Disable all mitigations for the Speculative Store Bypass vulnerability

+ 4 - 0
Documentation/arm64/elf_hwcaps.txt

@@ -178,3 +178,7 @@ HWCAP_ILRCPC
 HWCAP_FLAGM
 HWCAP_FLAGM
 
 
     Functionality implied by ID_AA64ISAR0_EL1.TS == 0b0001.
     Functionality implied by ID_AA64ISAR0_EL1.TS == 0b0001.
+
+HWCAP_SSBS
+
+    Functionality implied by ID_AA64PFR1_EL1.SSBS == 0b0010.

+ 1 - 1
Documentation/filesystems/overlayfs.txt

@@ -302,7 +302,7 @@ beneath or above the path of another overlay lower layer path.
 
 
 Using an upper layer path and/or a workdir path that are already used by
 Using an upper layer path and/or a workdir path that are already used by
 another overlay mount is not allowed and may fail with EBUSY.  Using
 another overlay mount is not allowed and may fail with EBUSY.  Using
-partially overlapping paths is not allowed but will not fail with EBUSY.
+partially overlapping paths is not allowed and may fail with EBUSY.
 If files are accessed from two overlayfs mounts which share or overlap the
 If files are accessed from two overlayfs mounts which share or overlap the
 upper layer and/or workdir path the behavior of the overlay is undefined,
 upper layer and/or workdir path the behavior of the overlay is undefined,
 though it will not result in a crash or deadlock.
 though it will not result in a crash or deadlock.

+ 1 - 1
Makefile

@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 4
 VERSION = 4
 PATCHLEVEL = 19
 PATCHLEVEL = 19
-SUBLEVEL = 73
+SUBLEVEL = 79
 EXTRAVERSION =
 EXTRAVERSION =
 NAME = "People's Front"
 NAME = "People's Front"
 
 

+ 3 - 2
arch/arm/Kconfig

@@ -1586,8 +1586,9 @@ config ARM_PATCH_IDIV
 	  code to do integer division.
 	  code to do integer division.
 
 
 config AEABI
 config AEABI
-	bool "Use the ARM EABI to compile the kernel" if !CPU_V7 && !CPU_V7M && !CPU_V6 && !CPU_V6K
-	default CPU_V7 || CPU_V7M || CPU_V6 || CPU_V6K
+	bool "Use the ARM EABI to compile the kernel" if !CPU_V7 && \
+		!CPU_V7M && !CPU_V6 && !CPU_V6K && !CC_IS_CLANG
+	default CPU_V7 || CPU_V7M || CPU_V6 || CPU_V6K || CC_IS_CLANG
 	help
 	help
 	  This option allows for the kernel to be compiled using the latest
 	  This option allows for the kernel to be compiled using the latest
 	  ARM ABI (aka EABI).  This is only useful if you are using a user
 	  ARM ABI (aka EABI).  This is only useful if you are using a user

+ 1 - 0
arch/arm/boot/dts/exynos5420-peach-pit.dts

@@ -437,6 +437,7 @@
 				regulator-name = "vdd_ldo10";
 				regulator-name = "vdd_ldo10";
 				regulator-min-microvolt = <1800000>;
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <1800000>;
 				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
 				regulator-state-mem {
 				regulator-state-mem {
 					regulator-off-in-suspend;
 					regulator-off-in-suspend;
 				};
 				};

+ 1 - 0
arch/arm/boot/dts/exynos5800-peach-pi.dts

@@ -437,6 +437,7 @@
 				regulator-name = "vdd_ldo10";
 				regulator-name = "vdd_ldo10";
 				regulator-min-microvolt = <1800000>;
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <1800000>;
 				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
 				regulator-state-mem {
 				regulator-state-mem {
 					regulator-off-in-suspend;
 					regulator-off-in-suspend;
 				};
 				};

+ 1 - 0
arch/arm/boot/dts/imx7-colibri.dtsi

@@ -323,6 +323,7 @@
 	vmmc-supply = <&reg_module_3v3>;
 	vmmc-supply = <&reg_module_3v3>;
 	vqmmc-supply = <&reg_DCDC3>;
 	vqmmc-supply = <&reg_DCDC3>;
 	non-removable;
 	non-removable;
+	sdhci-caps-mask = <0x80000000 0x0>;
 };
 };
 
 
 &iomuxc {
 &iomuxc {

+ 2 - 2
arch/arm/boot/dts/imx7d-cl-som-imx7.dts

@@ -43,7 +43,7 @@
 			  <&clks IMX7D_ENET1_TIME_ROOT_CLK>;
 			  <&clks IMX7D_ENET1_TIME_ROOT_CLK>;
 	assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
 	assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
 	assigned-clock-rates = <0>, <100000000>;
 	assigned-clock-rates = <0>, <100000000>;
-	phy-mode = "rgmii";
+	phy-mode = "rgmii-id";
 	phy-handle = <&ethphy0>;
 	phy-handle = <&ethphy0>;
 	fsl,magic-packet;
 	fsl,magic-packet;
 	status = "okay";
 	status = "okay";
@@ -69,7 +69,7 @@
 			  <&clks IMX7D_ENET2_TIME_ROOT_CLK>;
 			  <&clks IMX7D_ENET2_TIME_ROOT_CLK>;
 	assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
 	assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
 	assigned-clock-rates = <0>, <100000000>;
 	assigned-clock-rates = <0>, <100000000>;
-	phy-mode = "rgmii";
+	phy-mode = "rgmii-id";
 	phy-handle = <&ethphy1>;
 	phy-handle = <&ethphy1>;
 	fsl,magic-packet;
 	fsl,magic-packet;
 	status = "okay";
 	status = "okay";

+ 2 - 1
arch/arm/mach-omap1/ams-delta-fiq-handler.S

@@ -135,6 +135,8 @@ restart:
 	orr r11, r11, r13			@ mask all requested interrupts
 	orr r11, r11, r13			@ mask all requested interrupts
 	str r11, [r12, #OMAP1510_GPIO_INT_MASK]
 	str r11, [r12, #OMAP1510_GPIO_INT_MASK]
 
 
+	str r13, [r12, #OMAP1510_GPIO_INT_STATUS] @ ack all requested interrupts
+
 	ands r10, r13, #KEYBRD_CLK_MASK		@ extract keyboard status - set?
 	ands r10, r13, #KEYBRD_CLK_MASK		@ extract keyboard status - set?
 	beq hksw				@ no - try next source
 	beq hksw				@ no - try next source
 
 
@@ -142,7 +144,6 @@ restart:
 	@@@@@@@@@@@@@@@@@@@@@@
 	@@@@@@@@@@@@@@@@@@@@@@
 	@ Keyboard clock FIQ mode interrupt handler
 	@ Keyboard clock FIQ mode interrupt handler
 	@ r10 now contains KEYBRD_CLK_MASK, use it
 	@ r10 now contains KEYBRD_CLK_MASK, use it
-	str r10, [r12, #OMAP1510_GPIO_INT_STATUS]	@ ack the interrupt
 	bic r11, r11, r10				@ unmask it
 	bic r11, r11, r10				@ unmask it
 	str r11, [r12, #OMAP1510_GPIO_INT_MASK]
 	str r11, [r12, #OMAP1510_GPIO_INT_MASK]
 
 

+ 1 - 3
arch/arm/mach-omap1/ams-delta-fiq.c

@@ -73,9 +73,7 @@ static irqreturn_t deferred_fiq(int irq, void *dev_id)
 			 * interrupts default to since commit 80ac93c27441
 			 * interrupts default to since commit 80ac93c27441
 			 * requires interrupt already acked and unmasked.
 			 * requires interrupt already acked and unmasked.
 			 */
 			 */
-			if (irq_chip->irq_ack)
-				irq_chip->irq_ack(d);
-			if (irq_chip->irq_unmask)
+			if (!WARN_ON_ONCE(!irq_chip->irq_unmask))
 				irq_chip->irq_unmask(d);
 				irq_chip->irq_unmask(d);
 		}
 		}
 		for (; irq_counter[gpio] < fiq_count; irq_counter[gpio]++)
 		for (; irq_counter[gpio] < fiq_count; irq_counter[gpio]++)

+ 3 - 0
arch/arm/mach-omap2/omap4-common.c

@@ -131,6 +131,9 @@ static int __init omap4_sram_init(void)
 	struct device_node *np;
 	struct device_node *np;
 	struct gen_pool *sram_pool;
 	struct gen_pool *sram_pool;
 
 
+	if (!soc_is_omap44xx() && !soc_is_omap54xx())
+		return 0;
+
 	np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu");
 	np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu");
 	if (!np)
 	if (!np)
 		pr_warn("%s:Unable to allocate sram needed to handle errata I688\n",
 		pr_warn("%s:Unable to allocate sram needed to handle errata I688\n",

+ 2 - 1
arch/arm/mach-omap2/omap_hwmod_7xx_data.c

@@ -539,7 +539,8 @@ static struct omap_hwmod dra7xx_dcan2_hwmod = {
 static struct omap_hwmod_class_sysconfig dra7xx_epwmss_sysc = {
 static struct omap_hwmod_class_sysconfig dra7xx_epwmss_sysc = {
 	.rev_offs	= 0x0,
 	.rev_offs	= 0x0,
 	.sysc_offs	= 0x4,
 	.sysc_offs	= 0x4,
-	.sysc_flags	= SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET,
+	.sysc_flags	= SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+			  SYSC_HAS_RESET_STATUS,
 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
 	.sysc_fields	= &omap_hwmod_sysc_type2,
 	.sysc_fields	= &omap_hwmod_sysc_type2,
 };
 };

+ 1 - 1
arch/arm/mach-zynq/platsmp.c

@@ -65,7 +65,7 @@ int zynq_cpun_start(u32 address, int cpu)
 			* 0x4: Jump by mov instruction
 			* 0x4: Jump by mov instruction
 			* 0x8: Jumping address
 			* 0x8: Jumping address
 			*/
 			*/
-			memcpy((__force void *)zero, &zynq_secondary_trampoline,
+			memcpy_toio(zero, &zynq_secondary_trampoline,
 							trampoline_size);
 							trampoline_size);
 			writel(address, zero + trampoline_size);
 			writel(address, zero + trampoline_size);
 
 

+ 2 - 2
arch/arm/mm/fault.c

@@ -216,7 +216,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma)
 {
 {
 	unsigned int mask = VM_READ | VM_WRITE | VM_EXEC;
 	unsigned int mask = VM_READ | VM_WRITE | VM_EXEC;
 
 
-	if (fsr & FSR_WRITE)
+	if ((fsr & FSR_WRITE) && !(fsr & FSR_CM))
 		mask = VM_WRITE;
 		mask = VM_WRITE;
 	if (fsr & FSR_LNX_PF)
 	if (fsr & FSR_LNX_PF)
 		mask = VM_EXEC;
 		mask = VM_EXEC;
@@ -287,7 +287,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 
 
 	if (user_mode(regs))
 	if (user_mode(regs))
 		flags |= FAULT_FLAG_USER;
 		flags |= FAULT_FLAG_USER;
-	if (fsr & FSR_WRITE)
+	if ((fsr & FSR_WRITE) && !(fsr & FSR_CM))
 		flags |= FAULT_FLAG_WRITE;
 		flags |= FAULT_FLAG_WRITE;
 
 
 	/*
 	/*

+ 1 - 0
arch/arm/mm/fault.h

@@ -6,6 +6,7 @@
  * Fault status register encodings.  We steal bit 31 for our own purposes.
  * Fault status register encodings.  We steal bit 31 for our own purposes.
  */
  */
 #define FSR_LNX_PF		(1 << 31)
 #define FSR_LNX_PF		(1 << 31)
+#define FSR_CM			(1 << 13)
 #define FSR_WRITE		(1 << 11)
 #define FSR_WRITE		(1 << 11)
 #define FSR_FS4			(1 << 10)
 #define FSR_FS4			(1 << 10)
 #define FSR_FS3_0		(15)
 #define FSR_FS3_0		(15)

+ 7 - 1
arch/arm/mm/init.c

@@ -196,6 +196,11 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max_low,
 #ifdef CONFIG_HAVE_ARCH_PFN_VALID
 #ifdef CONFIG_HAVE_ARCH_PFN_VALID
 int pfn_valid(unsigned long pfn)
 int pfn_valid(unsigned long pfn)
 {
 {
+	phys_addr_t addr = __pfn_to_phys(pfn);
+
+	if (__phys_to_pfn(addr) != pfn)
+		return 0;
+
 	return memblock_is_map_memory(__pfn_to_phys(pfn));
 	return memblock_is_map_memory(__pfn_to_phys(pfn));
 }
 }
 EXPORT_SYMBOL(pfn_valid);
 EXPORT_SYMBOL(pfn_valid);
@@ -713,7 +718,8 @@ static void update_sections_early(struct section_perm perms[], int n)
 		if (t->flags & PF_KTHREAD)
 		if (t->flags & PF_KTHREAD)
 			continue;
 			continue;
 		for_each_thread(t, s)
 		for_each_thread(t, s)
-			set_section_perms(perms, n, true, s->mm);
+			if (s->mm)
+				set_section_perms(perms, n, true, s->mm);
 	}
 	}
 	set_section_perms(perms, n, true, current->active_mm);
 	set_section_perms(perms, n, true, current->active_mm);
 	set_section_perms(perms, n, true, &init_mm);
 	set_section_perms(perms, n, true, &init_mm);

+ 13 - 3
arch/arm/mm/mmap.c

@@ -18,8 +18,9 @@
 	 (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
 	 (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
 
 
 /* gap between mmap and stack */
 /* gap between mmap and stack */
-#define MIN_GAP (128*1024*1024UL)
-#define MAX_GAP ((TASK_SIZE)/6*5)
+#define MIN_GAP		(128*1024*1024UL)
+#define MAX_GAP		((STACK_TOP)/6*5)
+#define STACK_RND_MASK	(0x7ff >> (PAGE_SHIFT - 12))
 
 
 static int mmap_is_legacy(struct rlimit *rlim_stack)
 static int mmap_is_legacy(struct rlimit *rlim_stack)
 {
 {
@@ -35,13 +36,22 @@ static int mmap_is_legacy(struct rlimit *rlim_stack)
 static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
 static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
 {
 {
 	unsigned long gap = rlim_stack->rlim_cur;
 	unsigned long gap = rlim_stack->rlim_cur;
+	unsigned long pad = stack_guard_gap;
+
+	/* Account for stack randomization if necessary */
+	if (current->flags & PF_RANDOMIZE)
+		pad += (STACK_RND_MASK << PAGE_SHIFT);
+
+	/* Values close to RLIM_INFINITY can overflow. */
+	if (gap + pad > gap)
+		gap += pad;
 
 
 	if (gap < MIN_GAP)
 	if (gap < MIN_GAP)
 		gap = MIN_GAP;
 		gap = MIN_GAP;
 	else if (gap > MAX_GAP)
 	else if (gap > MAX_GAP)
 		gap = MAX_GAP;
 		gap = MAX_GAP;
 
 
-	return PAGE_ALIGN(TASK_SIZE - gap - rnd);
+	return PAGE_ALIGN(STACK_TOP - gap - rnd);
 }
 }
 
 
 /*
 /*

+ 16 - 0
arch/arm/mm/mmu.c

@@ -1175,6 +1175,22 @@ void __init adjust_lowmem_bounds(void)
 	 */
 	 */
 	vmalloc_limit = (u64)(uintptr_t)vmalloc_min - PAGE_OFFSET + PHYS_OFFSET;
 	vmalloc_limit = (u64)(uintptr_t)vmalloc_min - PAGE_OFFSET + PHYS_OFFSET;
 
 
+	/*
+	 * The first usable region must be PMD aligned. Mark its start
+	 * as MEMBLOCK_NOMAP if it isn't
+	 */
+	for_each_memblock(memory, reg) {
+		if (!memblock_is_nomap(reg)) {
+			if (!IS_ALIGNED(reg->base, PMD_SIZE)) {
+				phys_addr_t len;
+
+				len = round_up(reg->base, PMD_SIZE) - reg->base;
+				memblock_mark_nomap(reg->base, len);
+			}
+			break;
+		}
+	}
+
 	for_each_memblock(memory, reg) {
 	for_each_memblock(memory, reg) {
 		phys_addr_t block_start = reg->base;
 		phys_addr_t block_start = reg->base;
 		phys_addr_t block_end = reg->base + reg->size;
 		phys_addr_t block_end = reg->base + reg->size;

+ 1 - 0
arch/arm/plat-samsung/watchdog-reset.c

@@ -62,6 +62,7 @@ void samsung_wdt_reset(void)
 #ifdef CONFIG_OF
 #ifdef CONFIG_OF
 static const struct of_device_id s3c2410_wdt_match[] = {
 static const struct of_device_id s3c2410_wdt_match[] = {
 	{ .compatible = "samsung,s3c2410-wdt" },
 	{ .compatible = "samsung,s3c2410-wdt" },
+	{ .compatible = "samsung,s3c6410-wdt" },
 	{},
 	{},
 };
 };
 
 

+ 1 - 0
arch/arm64/Kconfig

@@ -84,6 +84,7 @@ config ARM64
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CLOCKEVENTS_BROADCAST
 	select GENERIC_CLOCKEVENTS_BROADCAST
 	select GENERIC_CPU_AUTOPROBE
 	select GENERIC_CPU_AUTOPROBE
+	select GENERIC_CPU_VULNERABILITIES
 	select GENERIC_EARLY_IOREMAP
 	select GENERIC_EARLY_IOREMAP
 	select GENERIC_IDLE_POLL_SETUP
 	select GENERIC_IDLE_POLL_SETUP
 	select GENERIC_IRQ_MULTI_HANDLER
 	select GENERIC_IRQ_MULTI_HANDLER

+ 3 - 0
arch/arm64/boot/dts/rockchip/rk3328.dtsi

@@ -708,6 +708,7 @@
 			 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
 			 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
 		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		fifo-depth = <0x100>;
 		fifo-depth = <0x100>;
+		max-frequency = <150000000>;
 		status = "disabled";
 		status = "disabled";
 	};
 	};
 
 
@@ -719,6 +720,7 @@
 			 <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
 			 <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
 		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		fifo-depth = <0x100>;
 		fifo-depth = <0x100>;
+		max-frequency = <150000000>;
 		status = "disabled";
 		status = "disabled";
 	};
 	};
 
 
@@ -730,6 +732,7 @@
 			 <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
 			 <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
 		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
 		fifo-depth = <0x100>;
 		fifo-depth = <0x100>;
+		max-frequency = <150000000>;
 		status = "disabled";
 		status = "disabled";
 	};
 	};
 
 

+ 3 - 3
arch/arm64/include/asm/cmpxchg.h

@@ -74,7 +74,7 @@ __XCHG_CASE( ,  ,  mb_8, dmb ish, nop,  , a, l, "memory")
 #undef __XCHG_CASE
 #undef __XCHG_CASE
 
 
 #define __XCHG_GEN(sfx)							\
 #define __XCHG_GEN(sfx)							\
-static inline unsigned long __xchg##sfx(unsigned long x,		\
+static __always_inline  unsigned long __xchg##sfx(unsigned long x,	\
 					volatile void *ptr,		\
 					volatile void *ptr,		\
 					int size)			\
 					int size)			\
 {									\
 {									\
@@ -116,7 +116,7 @@ __XCHG_GEN(_mb)
 #define xchg(...)		__xchg_wrapper( _mb, __VA_ARGS__)
 #define xchg(...)		__xchg_wrapper( _mb, __VA_ARGS__)
 
 
 #define __CMPXCHG_GEN(sfx)						\
 #define __CMPXCHG_GEN(sfx)						\
-static inline unsigned long __cmpxchg##sfx(volatile void *ptr,		\
+static __always_inline unsigned long __cmpxchg##sfx(volatile void *ptr,	\
 					   unsigned long old,		\
 					   unsigned long old,		\
 					   unsigned long new,		\
 					   unsigned long new,		\
 					   int size)			\
 					   int size)			\
@@ -223,7 +223,7 @@ __CMPWAIT_CASE( ,  , 8);
 #undef __CMPWAIT_CASE
 #undef __CMPWAIT_CASE
 
 
 #define __CMPWAIT_GEN(sfx)						\
 #define __CMPWAIT_GEN(sfx)						\
-static inline void __cmpwait##sfx(volatile void *ptr,			\
+static __always_inline void __cmpwait##sfx(volatile void *ptr,		\
 				  unsigned long val,			\
 				  unsigned long val,			\
 				  int size)				\
 				  int size)				\
 {									\
 {									\

+ 2 - 1
arch/arm64/include/asm/cpucaps.h

@@ -52,7 +52,8 @@
 #define ARM64_MISMATCHED_CACHE_TYPE		31
 #define ARM64_MISMATCHED_CACHE_TYPE		31
 #define ARM64_HAS_STAGE2_FWB			32
 #define ARM64_HAS_STAGE2_FWB			32
 #define ARM64_WORKAROUND_1463225		33
 #define ARM64_WORKAROUND_1463225		33
+#define ARM64_SSBS				34
 
 
-#define ARM64_NCAPS				34
+#define ARM64_NCAPS				35
 
 
 #endif /* __ASM_CPUCAPS_H */
 #endif /* __ASM_CPUCAPS_H */

+ 0 - 4
arch/arm64/include/asm/cpufeature.h

@@ -525,11 +525,7 @@ static inline int arm64_get_ssbd_state(void)
 #endif
 #endif
 }
 }
 
 
-#ifdef CONFIG_ARM64_SSBD
 void arm64_set_ssbd_mitigation(bool state);
 void arm64_set_ssbd_mitigation(bool state);
-#else
-static inline void arm64_set_ssbd_mitigation(bool state) {}
-#endif
 
 
 #endif /* __ASSEMBLY__ */
 #endif /* __ASSEMBLY__ */
 
 

+ 11 - 10
arch/arm64/include/asm/cputype.h

@@ -62,14 +62,6 @@
 #define MIDR_CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
 #define MIDR_CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
 			     MIDR_ARCHITECTURE_MASK)
 			     MIDR_ARCHITECTURE_MASK)
 
 
-#define MIDR_IS_CPU_MODEL_RANGE(midr, model, rv_min, rv_max)		\
-({									\
-	u32 _model = (midr) & MIDR_CPU_MODEL_MASK;			\
-	u32 rv = (midr) & (MIDR_REVISION_MASK | MIDR_VARIANT_MASK);	\
-									\
-	_model == (model) && rv >= (rv_min) && rv <= (rv_max);		\
- })
-
 #define ARM_CPU_IMP_ARM			0x41
 #define ARM_CPU_IMP_ARM			0x41
 #define ARM_CPU_IMP_APM			0x50
 #define ARM_CPU_IMP_APM			0x50
 #define ARM_CPU_IMP_CAVIUM		0x43
 #define ARM_CPU_IMP_CAVIUM		0x43
@@ -153,10 +145,19 @@ struct midr_range {
 
 
 #define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf)
 #define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf)
 
 
+static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min,
+					   u32 rv_max)
+{
+	u32 _model = midr & MIDR_CPU_MODEL_MASK;
+	u32 rv = midr & (MIDR_REVISION_MASK | MIDR_VARIANT_MASK);
+
+	return _model == model && rv >= rv_min && rv <= rv_max;
+}
+
 static inline bool is_midr_in_range(u32 midr, struct midr_range const *range)
 static inline bool is_midr_in_range(u32 midr, struct midr_range const *range)
 {
 {
-	return MIDR_IS_CPU_MODEL_RANGE(midr, range->model,
-				 range->rv_min, range->rv_max);
+	return midr_is_cpu_model_range(midr, range->model,
+				       range->rv_min, range->rv_max);
 }
 }
 
 
 static inline bool
 static inline bool

+ 11 - 0
arch/arm64/include/asm/kvm_host.h

@@ -398,6 +398,8 @@ struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
 
 
 DECLARE_PER_CPU(kvm_cpu_context_t, kvm_host_cpu_state);
 DECLARE_PER_CPU(kvm_cpu_context_t, kvm_host_cpu_state);
 
 
+void __kvm_enable_ssbs(void);
+
 static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
 static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
 				       unsigned long hyp_stack_ptr,
 				       unsigned long hyp_stack_ptr,
 				       unsigned long vector_ptr)
 				       unsigned long vector_ptr)
@@ -418,6 +420,15 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
 	 */
 	 */
 	BUG_ON(!static_branch_likely(&arm64_const_caps_ready));
 	BUG_ON(!static_branch_likely(&arm64_const_caps_ready));
 	__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr, tpidr_el2);
 	__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr, tpidr_el2);
+
+	/*
+	 * Disabling SSBD on a non-VHE system requires us to enable SSBS
+	 * at EL2.
+	 */
+	if (!has_vhe() && this_cpu_has_cap(ARM64_SSBS) &&
+	    arm64_get_ssbd_state() == ARM64_SSBD_FORCE_DISABLE) {
+		kvm_call_hyp(__kvm_enable_ssbs);
+	}
 }
 }
 
 
 static inline bool kvm_arch_check_sve_has_vhe(void)
 static inline bool kvm_arch_check_sve_has_vhe(void)

+ 5 - 1
arch/arm64/include/asm/pgtable.h

@@ -224,8 +224,10 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
 	 * Only if the new pte is valid and kernel, otherwise TLB maintenance
 	 * Only if the new pte is valid and kernel, otherwise TLB maintenance
 	 * or update_mmu_cache() have the necessary barriers.
 	 * or update_mmu_cache() have the necessary barriers.
 	 */
 	 */
-	if (pte_valid_not_user(pte))
+	if (pte_valid_not_user(pte)) {
 		dsb(ishst);
 		dsb(ishst);
+		isb();
+	}
 }
 }
 
 
 extern void __sync_icache_dcache(pte_t pteval);
 extern void __sync_icache_dcache(pte_t pteval);
@@ -432,6 +434,7 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
 {
 {
 	WRITE_ONCE(*pmdp, pmd);
 	WRITE_ONCE(*pmdp, pmd);
 	dsb(ishst);
 	dsb(ishst);
+	isb();
 }
 }
 
 
 static inline void pmd_clear(pmd_t *pmdp)
 static inline void pmd_clear(pmd_t *pmdp)
@@ -483,6 +486,7 @@ static inline void set_pud(pud_t *pudp, pud_t pud)
 {
 {
 	WRITE_ONCE(*pudp, pud);
 	WRITE_ONCE(*pudp, pud);
 	dsb(ishst);
 	dsb(ishst);
+	isb();
 }
 }
 
 
 static inline void pud_clear(pud_t *pudp)
 static inline void pud_clear(pud_t *pudp)

+ 17 - 0
arch/arm64/include/asm/processor.h

@@ -177,11 +177,25 @@ static inline void start_thread_common(struct pt_regs *regs, unsigned long pc)
 	regs->pc = pc;
 	regs->pc = pc;
 }
 }
 
 
+static inline void set_ssbs_bit(struct pt_regs *regs)
+{
+	regs->pstate |= PSR_SSBS_BIT;
+}
+
+static inline void set_compat_ssbs_bit(struct pt_regs *regs)
+{
+	regs->pstate |= PSR_AA32_SSBS_BIT;
+}
+
 static inline void start_thread(struct pt_regs *regs, unsigned long pc,
 static inline void start_thread(struct pt_regs *regs, unsigned long pc,
 				unsigned long sp)
 				unsigned long sp)
 {
 {
 	start_thread_common(regs, pc);
 	start_thread_common(regs, pc);
 	regs->pstate = PSR_MODE_EL0t;
 	regs->pstate = PSR_MODE_EL0t;
+
+	if (arm64_get_ssbd_state() != ARM64_SSBD_FORCE_ENABLE)
+		set_ssbs_bit(regs);
+
 	regs->sp = sp;
 	regs->sp = sp;
 }
 }
 
 
@@ -198,6 +212,9 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
 	regs->pstate |= PSR_AA32_E_BIT;
 	regs->pstate |= PSR_AA32_E_BIT;
 #endif
 #endif
 
 
+	if (arm64_get_ssbd_state() != ARM64_SSBD_FORCE_ENABLE)
+		set_compat_ssbs_bit(regs);
+
 	regs->compat_sp = sp;
 	regs->compat_sp = sp;
 }
 }
 #endif
 #endif

+ 1 - 0
arch/arm64/include/asm/ptrace.h

@@ -50,6 +50,7 @@
 #define PSR_AA32_I_BIT		0x00000080
 #define PSR_AA32_I_BIT		0x00000080
 #define PSR_AA32_A_BIT		0x00000100
 #define PSR_AA32_A_BIT		0x00000100
 #define PSR_AA32_E_BIT		0x00000200
 #define PSR_AA32_E_BIT		0x00000200
+#define PSR_AA32_SSBS_BIT	0x00800000
 #define PSR_AA32_DIT_BIT	0x01000000
 #define PSR_AA32_DIT_BIT	0x01000000
 #define PSR_AA32_Q_BIT		0x08000000
 #define PSR_AA32_Q_BIT		0x08000000
 #define PSR_AA32_V_BIT		0x10000000
 #define PSR_AA32_V_BIT		0x10000000

+ 15 - 4
arch/arm64/include/asm/sysreg.h

@@ -86,11 +86,14 @@
 
 
 #define REG_PSTATE_PAN_IMM		sys_reg(0, 0, 4, 0, 4)
 #define REG_PSTATE_PAN_IMM		sys_reg(0, 0, 4, 0, 4)
 #define REG_PSTATE_UAO_IMM		sys_reg(0, 0, 4, 0, 3)
 #define REG_PSTATE_UAO_IMM		sys_reg(0, 0, 4, 0, 3)
+#define REG_PSTATE_SSBS_IMM		sys_reg(0, 3, 4, 0, 1)
 
 
 #define SET_PSTATE_PAN(x) __emit_inst(0xd5000000 | REG_PSTATE_PAN_IMM |	\
 #define SET_PSTATE_PAN(x) __emit_inst(0xd5000000 | REG_PSTATE_PAN_IMM |	\
 				      (!!x)<<8 | 0x1f)
 				      (!!x)<<8 | 0x1f)
 #define SET_PSTATE_UAO(x) __emit_inst(0xd5000000 | REG_PSTATE_UAO_IMM |	\
 #define SET_PSTATE_UAO(x) __emit_inst(0xd5000000 | REG_PSTATE_UAO_IMM |	\
 				      (!!x)<<8 | 0x1f)
 				      (!!x)<<8 | 0x1f)
+#define SET_PSTATE_SSBS(x) __emit_inst(0xd5000000 | REG_PSTATE_SSBS_IMM | \
+				       (!!x)<<8 | 0x1f)
 
 
 #define SYS_DC_ISW			sys_insn(1, 0, 7, 6, 2)
 #define SYS_DC_ISW			sys_insn(1, 0, 7, 6, 2)
 #define SYS_DC_CSW			sys_insn(1, 0, 7, 10, 2)
 #define SYS_DC_CSW			sys_insn(1, 0, 7, 10, 2)
@@ -419,6 +422,7 @@
 #define SYS_ICH_LR15_EL2		__SYS__LR8_EL2(7)
 #define SYS_ICH_LR15_EL2		__SYS__LR8_EL2(7)
 
 
 /* Common SCTLR_ELx flags. */
 /* Common SCTLR_ELx flags. */
+#define SCTLR_ELx_DSSBS	(1UL << 44)
 #define SCTLR_ELx_EE    (1 << 25)
 #define SCTLR_ELx_EE    (1 << 25)
 #define SCTLR_ELx_IESB	(1 << 21)
 #define SCTLR_ELx_IESB	(1 << 21)
 #define SCTLR_ELx_WXN	(1 << 19)
 #define SCTLR_ELx_WXN	(1 << 19)
@@ -439,7 +443,7 @@
 			 (1 << 10) | (1 << 13) | (1 << 14) | (1 << 15) | \
 			 (1 << 10) | (1 << 13) | (1 << 14) | (1 << 15) | \
 			 (1 << 17) | (1 << 20) | (1 << 24) | (1 << 26) | \
 			 (1 << 17) | (1 << 20) | (1 << 24) | (1 << 26) | \
 			 (1 << 27) | (1 << 30) | (1 << 31) | \
 			 (1 << 27) | (1 << 30) | (1 << 31) | \
-			 (0xffffffffUL << 32))
+			 (0xffffefffUL << 32))
 
 
 #ifdef CONFIG_CPU_BIG_ENDIAN
 #ifdef CONFIG_CPU_BIG_ENDIAN
 #define ENDIAN_SET_EL2		SCTLR_ELx_EE
 #define ENDIAN_SET_EL2		SCTLR_ELx_EE
@@ -453,7 +457,7 @@
 #define SCTLR_EL2_SET	(SCTLR_ELx_IESB   | ENDIAN_SET_EL2   | SCTLR_EL2_RES1)
 #define SCTLR_EL2_SET	(SCTLR_ELx_IESB   | ENDIAN_SET_EL2   | SCTLR_EL2_RES1)
 #define SCTLR_EL2_CLEAR	(SCTLR_ELx_M      | SCTLR_ELx_A    | SCTLR_ELx_C   | \
 #define SCTLR_EL2_CLEAR	(SCTLR_ELx_M      | SCTLR_ELx_A    | SCTLR_ELx_C   | \
 			 SCTLR_ELx_SA     | SCTLR_ELx_I    | SCTLR_ELx_WXN | \
 			 SCTLR_ELx_SA     | SCTLR_ELx_I    | SCTLR_ELx_WXN | \
-			 ENDIAN_CLEAR_EL2 | SCTLR_EL2_RES0)
+			 SCTLR_ELx_DSSBS | ENDIAN_CLEAR_EL2 | SCTLR_EL2_RES0)
 
 
 #if (SCTLR_EL2_SET ^ SCTLR_EL2_CLEAR) != 0xffffffffffffffff
 #if (SCTLR_EL2_SET ^ SCTLR_EL2_CLEAR) != 0xffffffffffffffff
 #error "Inconsistent SCTLR_EL2 set/clear bits"
 #error "Inconsistent SCTLR_EL2 set/clear bits"
@@ -477,7 +481,7 @@
 			 (1 << 29))
 			 (1 << 29))
 #define SCTLR_EL1_RES0  ((1 << 6)  | (1 << 10) | (1 << 13) | (1 << 17) | \
 #define SCTLR_EL1_RES0  ((1 << 6)  | (1 << 10) | (1 << 13) | (1 << 17) | \
 			 (1 << 27) | (1 << 30) | (1 << 31) | \
 			 (1 << 27) | (1 << 30) | (1 << 31) | \
-			 (0xffffffffUL << 32))
+			 (0xffffefffUL << 32))
 
 
 #ifdef CONFIG_CPU_BIG_ENDIAN
 #ifdef CONFIG_CPU_BIG_ENDIAN
 #define ENDIAN_SET_EL1		(SCTLR_EL1_E0E | SCTLR_ELx_EE)
 #define ENDIAN_SET_EL1		(SCTLR_EL1_E0E | SCTLR_ELx_EE)
@@ -494,7 +498,7 @@
 			 ENDIAN_SET_EL1 | SCTLR_EL1_UCI  | SCTLR_EL1_RES1)
 			 ENDIAN_SET_EL1 | SCTLR_EL1_UCI  | SCTLR_EL1_RES1)
 #define SCTLR_EL1_CLEAR	(SCTLR_ELx_A   | SCTLR_EL1_CP15BEN | SCTLR_EL1_ITD    |\
 #define SCTLR_EL1_CLEAR	(SCTLR_ELx_A   | SCTLR_EL1_CP15BEN | SCTLR_EL1_ITD    |\
 			 SCTLR_EL1_UMA | SCTLR_ELx_WXN     | ENDIAN_CLEAR_EL1 |\
 			 SCTLR_EL1_UMA | SCTLR_ELx_WXN     | ENDIAN_CLEAR_EL1 |\
-			 SCTLR_EL1_RES0)
+			 SCTLR_ELx_DSSBS | SCTLR_EL1_RES0)
 
 
 #if (SCTLR_EL1_SET ^ SCTLR_EL1_CLEAR) != 0xffffffffffffffff
 #if (SCTLR_EL1_SET ^ SCTLR_EL1_CLEAR) != 0xffffffffffffffff
 #error "Inconsistent SCTLR_EL1 set/clear bits"
 #error "Inconsistent SCTLR_EL1 set/clear bits"
@@ -544,6 +548,13 @@
 #define ID_AA64PFR0_EL0_64BIT_ONLY	0x1
 #define ID_AA64PFR0_EL0_64BIT_ONLY	0x1
 #define ID_AA64PFR0_EL0_32BIT_64BIT	0x2
 #define ID_AA64PFR0_EL0_32BIT_64BIT	0x2
 
 
+/* id_aa64pfr1 */
+#define ID_AA64PFR1_SSBS_SHIFT		4
+
+#define ID_AA64PFR1_SSBS_PSTATE_NI	0
+#define ID_AA64PFR1_SSBS_PSTATE_ONLY	1
+#define ID_AA64PFR1_SSBS_PSTATE_INSNS	2
+
 /* id_aa64mmfr0 */
 /* id_aa64mmfr0 */
 #define ID_AA64MMFR0_TGRAN4_SHIFT	28
 #define ID_AA64MMFR0_TGRAN4_SHIFT	28
 #define ID_AA64MMFR0_TGRAN64_SHIFT	24
 #define ID_AA64MMFR0_TGRAN64_SHIFT	24

+ 1 - 0
arch/arm64/include/asm/tlbflush.h

@@ -224,6 +224,7 @@ static inline void __flush_tlb_kernel_pgtable(unsigned long kaddr)
 
 
 	__tlbi(vaae1is, addr);
 	__tlbi(vaae1is, addr);
 	dsb(ish);
 	dsb(ish);
+	isb();
 }
 }
 #endif
 #endif
 
 

+ 1 - 0
arch/arm64/include/uapi/asm/hwcap.h

@@ -48,5 +48,6 @@
 #define HWCAP_USCAT		(1 << 25)
 #define HWCAP_USCAT		(1 << 25)
 #define HWCAP_ILRCPC		(1 << 26)
 #define HWCAP_ILRCPC		(1 << 26)
 #define HWCAP_FLAGM		(1 << 27)
 #define HWCAP_FLAGM		(1 << 27)
+#define HWCAP_SSBS		(1 << 28)
 
 
 #endif /* _UAPI__ASM_HWCAP_H */
 #endif /* _UAPI__ASM_HWCAP_H */

+ 1 - 0
arch/arm64/include/uapi/asm/ptrace.h

@@ -46,6 +46,7 @@
 #define PSR_I_BIT	0x00000080
 #define PSR_I_BIT	0x00000080
 #define PSR_A_BIT	0x00000100
 #define PSR_A_BIT	0x00000100
 #define PSR_D_BIT	0x00000200
 #define PSR_D_BIT	0x00000200
+#define PSR_SSBS_BIT	0x00001000
 #define PSR_PAN_BIT	0x00400000
 #define PSR_PAN_BIT	0x00400000
 #define PSR_UAO_BIT	0x00800000
 #define PSR_UAO_BIT	0x00800000
 #define PSR_V_BIT	0x10000000
 #define PSR_V_BIT	0x10000000

+ 202 - 69
arch/arm64/kernel/cpu_errata.c

@@ -19,6 +19,7 @@
 #include <linux/arm-smccc.h>
 #include <linux/arm-smccc.h>
 #include <linux/psci.h>
 #include <linux/psci.h>
 #include <linux/types.h>
 #include <linux/types.h>
+#include <linux/cpu.h>
 #include <asm/cpu.h>
 #include <asm/cpu.h>
 #include <asm/cputype.h>
 #include <asm/cputype.h>
 #include <asm/cpufeature.h>
 #include <asm/cpufeature.h>
@@ -87,7 +88,6 @@ cpu_enable_trap_ctr_access(const struct arm64_cpu_capabilities *__unused)
 
 
 atomic_t arm64_el2_vector_last_slot = ATOMIC_INIT(-1);
 atomic_t arm64_el2_vector_last_slot = ATOMIC_INIT(-1);
 
 
-#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
 #include <asm/mmu_context.h>
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
 
 
@@ -109,9 +109,9 @@ static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,
 	__flush_icache_range((uintptr_t)dst, (uintptr_t)dst + SZ_2K);
 	__flush_icache_range((uintptr_t)dst, (uintptr_t)dst + SZ_2K);
 }
 }
 
 
-static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
-				      const char *hyp_vecs_start,
-				      const char *hyp_vecs_end)
+static void install_bp_hardening_cb(bp_hardening_cb_t fn,
+				    const char *hyp_vecs_start,
+				    const char *hyp_vecs_end)
 {
 {
 	static DEFINE_SPINLOCK(bp_lock);
 	static DEFINE_SPINLOCK(bp_lock);
 	int cpu, slot = -1;
 	int cpu, slot = -1;
@@ -138,7 +138,7 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
 #define __smccc_workaround_1_smc_start		NULL
 #define __smccc_workaround_1_smc_start		NULL
 #define __smccc_workaround_1_smc_end		NULL
 #define __smccc_workaround_1_smc_end		NULL
 
 
-static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
+static void install_bp_hardening_cb(bp_hardening_cb_t fn,
 				      const char *hyp_vecs_start,
 				      const char *hyp_vecs_start,
 				      const char *hyp_vecs_end)
 				      const char *hyp_vecs_end)
 {
 {
@@ -146,23 +146,6 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
 }
 }
 #endif	/* CONFIG_KVM_INDIRECT_VECTORS */
 #endif	/* CONFIG_KVM_INDIRECT_VECTORS */
 
 
-static void  install_bp_hardening_cb(const struct arm64_cpu_capabilities *entry,
-				     bp_hardening_cb_t fn,
-				     const char *hyp_vecs_start,
-				     const char *hyp_vecs_end)
-{
-	u64 pfr0;
-
-	if (!entry->matches(entry, SCOPE_LOCAL_CPU))
-		return;
-
-	pfr0 = read_cpuid(ID_AA64PFR0_EL1);
-	if (cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_CSV2_SHIFT))
-		return;
-
-	__install_bp_hardening_cb(fn, hyp_vecs_start, hyp_vecs_end);
-}
-
 #include <uapi/linux/psci.h>
 #include <uapi/linux/psci.h>
 #include <linux/arm-smccc.h>
 #include <linux/arm-smccc.h>
 #include <linux/psci.h>
 #include <linux/psci.h>
@@ -189,60 +172,83 @@ static void qcom_link_stack_sanitization(void)
 		     : "=&r" (tmp));
 		     : "=&r" (tmp));
 }
 }
 
 
-static void
-enable_smccc_arch_workaround_1(const struct arm64_cpu_capabilities *entry)
+static bool __nospectre_v2;
+static int __init parse_nospectre_v2(char *str)
+{
+	__nospectre_v2 = true;
+	return 0;
+}
+early_param("nospectre_v2", parse_nospectre_v2);
+
+/*
+ * -1: No workaround
+ *  0: No workaround required
+ *  1: Workaround installed
+ */
+static int detect_harden_bp_fw(void)
 {
 {
 	bp_hardening_cb_t cb;
 	bp_hardening_cb_t cb;
 	void *smccc_start, *smccc_end;
 	void *smccc_start, *smccc_end;
 	struct arm_smccc_res res;
 	struct arm_smccc_res res;
 	u32 midr = read_cpuid_id();
 	u32 midr = read_cpuid_id();
 
 
-	if (!entry->matches(entry, SCOPE_LOCAL_CPU))
-		return;
-
 	if (psci_ops.smccc_version == SMCCC_VERSION_1_0)
 	if (psci_ops.smccc_version == SMCCC_VERSION_1_0)
-		return;
+		return -1;
 
 
 	switch (psci_ops.conduit) {
 	switch (psci_ops.conduit) {
 	case PSCI_CONDUIT_HVC:
 	case PSCI_CONDUIT_HVC:
 		arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
 		arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
 				  ARM_SMCCC_ARCH_WORKAROUND_1, &res);
 				  ARM_SMCCC_ARCH_WORKAROUND_1, &res);
-		if ((int)res.a0 < 0)
-			return;
-		cb = call_hvc_arch_workaround_1;
-		/* This is a guest, no need to patch KVM vectors */
-		smccc_start = NULL;
-		smccc_end = NULL;
+		switch ((int)res.a0) {
+		case 1:
+			/* Firmware says we're just fine */
+			return 0;
+		case 0:
+			cb = call_hvc_arch_workaround_1;
+			/* This is a guest, no need to patch KVM vectors */
+			smccc_start = NULL;
+			smccc_end = NULL;
+			break;
+		default:
+			return -1;
+		}
 		break;
 		break;
 
 
 	case PSCI_CONDUIT_SMC:
 	case PSCI_CONDUIT_SMC:
 		arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
 		arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
 				  ARM_SMCCC_ARCH_WORKAROUND_1, &res);
 				  ARM_SMCCC_ARCH_WORKAROUND_1, &res);
-		if ((int)res.a0 < 0)
-			return;
-		cb = call_smc_arch_workaround_1;
-		smccc_start = __smccc_workaround_1_smc_start;
-		smccc_end = __smccc_workaround_1_smc_end;
+		switch ((int)res.a0) {
+		case 1:
+			/* Firmware says we're just fine */
+			return 0;
+		case 0:
+			cb = call_smc_arch_workaround_1;
+			smccc_start = __smccc_workaround_1_smc_start;
+			smccc_end = __smccc_workaround_1_smc_end;
+			break;
+		default:
+			return -1;
+		}
 		break;
 		break;
 
 
 	default:
 	default:
-		return;
+		return -1;
 	}
 	}
 
 
 	if (((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR) ||
 	if (((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR) ||
 	    ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1))
 	    ((midr & MIDR_CPU_MODEL_MASK) == MIDR_QCOM_FALKOR_V1))
 		cb = qcom_link_stack_sanitization;
 		cb = qcom_link_stack_sanitization;
 
 
-	install_bp_hardening_cb(entry, cb, smccc_start, smccc_end);
+	if (IS_ENABLED(CONFIG_HARDEN_BRANCH_PREDICTOR))
+		install_bp_hardening_cb(cb, smccc_start, smccc_end);
 
 
-	return;
+	return 1;
 }
 }
-#endif	/* CONFIG_HARDEN_BRANCH_PREDICTOR */
 
 
-#ifdef CONFIG_ARM64_SSBD
 DEFINE_PER_CPU_READ_MOSTLY(u64, arm64_ssbd_callback_required);
 DEFINE_PER_CPU_READ_MOSTLY(u64, arm64_ssbd_callback_required);
 
 
 int ssbd_state __read_mostly = ARM64_SSBD_KERNEL;
 int ssbd_state __read_mostly = ARM64_SSBD_KERNEL;
+static bool __ssb_safe = true;
 
 
 static const struct ssbd_options {
 static const struct ssbd_options {
 	const char	*str;
 	const char	*str;
@@ -312,6 +318,19 @@ void __init arm64_enable_wa2_handling(struct alt_instr *alt,
 
 
 void arm64_set_ssbd_mitigation(bool state)
 void arm64_set_ssbd_mitigation(bool state)
 {
 {
+	if (!IS_ENABLED(CONFIG_ARM64_SSBD)) {
+		pr_info_once("SSBD disabled by kernel configuration\n");
+		return;
+	}
+
+	if (this_cpu_has_cap(ARM64_SSBS)) {
+		if (state)
+			asm volatile(SET_PSTATE_SSBS(0));
+		else
+			asm volatile(SET_PSTATE_SSBS(1));
+		return;
+	}
+
 	switch (psci_ops.conduit) {
 	switch (psci_ops.conduit) {
 	case PSCI_CONDUIT_HVC:
 	case PSCI_CONDUIT_HVC:
 		arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
 		arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
@@ -333,11 +352,28 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
 	struct arm_smccc_res res;
 	struct arm_smccc_res res;
 	bool required = true;
 	bool required = true;
 	s32 val;
 	s32 val;
+	bool this_cpu_safe = false;
 
 
 	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
 	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
 
 
+	if (cpu_mitigations_off())
+		ssbd_state = ARM64_SSBD_FORCE_DISABLE;
+
+	/* delay setting __ssb_safe until we get a firmware response */
+	if (is_midr_in_range_list(read_cpuid_id(), entry->midr_range_list))
+		this_cpu_safe = true;
+
+	if (this_cpu_has_cap(ARM64_SSBS)) {
+		if (!this_cpu_safe)
+			__ssb_safe = false;
+		required = false;
+		goto out_printmsg;
+	}
+
 	if (psci_ops.smccc_version == SMCCC_VERSION_1_0) {
 	if (psci_ops.smccc_version == SMCCC_VERSION_1_0) {
 		ssbd_state = ARM64_SSBD_UNKNOWN;
 		ssbd_state = ARM64_SSBD_UNKNOWN;
+		if (!this_cpu_safe)
+			__ssb_safe = false;
 		return false;
 		return false;
 	}
 	}
 
 
@@ -354,6 +390,8 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
 
 
 	default:
 	default:
 		ssbd_state = ARM64_SSBD_UNKNOWN;
 		ssbd_state = ARM64_SSBD_UNKNOWN;
+		if (!this_cpu_safe)
+			__ssb_safe = false;
 		return false;
 		return false;
 	}
 	}
 
 
@@ -362,14 +400,18 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
 	switch (val) {
 	switch (val) {
 	case SMCCC_RET_NOT_SUPPORTED:
 	case SMCCC_RET_NOT_SUPPORTED:
 		ssbd_state = ARM64_SSBD_UNKNOWN;
 		ssbd_state = ARM64_SSBD_UNKNOWN;
+		if (!this_cpu_safe)
+			__ssb_safe = false;
 		return false;
 		return false;
 
 
+	/* machines with mixed mitigation requirements must not return this */
 	case SMCCC_RET_NOT_REQUIRED:
 	case SMCCC_RET_NOT_REQUIRED:
 		pr_info_once("%s mitigation not required\n", entry->desc);
 		pr_info_once("%s mitigation not required\n", entry->desc);
 		ssbd_state = ARM64_SSBD_MITIGATED;
 		ssbd_state = ARM64_SSBD_MITIGATED;
 		return false;
 		return false;
 
 
 	case SMCCC_RET_SUCCESS:
 	case SMCCC_RET_SUCCESS:
+		__ssb_safe = false;
 		required = true;
 		required = true;
 		break;
 		break;
 
 
@@ -379,12 +421,13 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
 
 
 	default:
 	default:
 		WARN_ON(1);
 		WARN_ON(1);
+		if (!this_cpu_safe)
+			__ssb_safe = false;
 		return false;
 		return false;
 	}
 	}
 
 
 	switch (ssbd_state) {
 	switch (ssbd_state) {
 	case ARM64_SSBD_FORCE_DISABLE:
 	case ARM64_SSBD_FORCE_DISABLE:
-		pr_info_once("%s disabled from command-line\n", entry->desc);
 		arm64_set_ssbd_mitigation(false);
 		arm64_set_ssbd_mitigation(false);
 		required = false;
 		required = false;
 		break;
 		break;
@@ -397,7 +440,6 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
 		break;
 		break;
 
 
 	case ARM64_SSBD_FORCE_ENABLE:
 	case ARM64_SSBD_FORCE_ENABLE:
-		pr_info_once("%s forced from command-line\n", entry->desc);
 		arm64_set_ssbd_mitigation(true);
 		arm64_set_ssbd_mitigation(true);
 		required = true;
 		required = true;
 		break;
 		break;
@@ -407,9 +449,27 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
 		break;
 		break;
 	}
 	}
 
 
+out_printmsg:
+	switch (ssbd_state) {
+	case ARM64_SSBD_FORCE_DISABLE:
+		pr_info_once("%s disabled from command-line\n", entry->desc);
+		break;
+
+	case ARM64_SSBD_FORCE_ENABLE:
+		pr_info_once("%s forced from command-line\n", entry->desc);
+		break;
+	}
+
 	return required;
 	return required;
 }
 }
-#endif	/* CONFIG_ARM64_SSBD */
+
+/* known invulnerable cores */
+static const struct midr_range arm64_ssb_cpus[] = {
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A35),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A53),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A55),
+	{},
+};
 
 
 #ifdef CONFIG_ARM64_ERRATUM_1463225
 #ifdef CONFIG_ARM64_ERRATUM_1463225
 DEFINE_PER_CPU(int, __in_cortex_a76_erratum_1463225_wa);
 DEFINE_PER_CPU(int, __in_cortex_a76_erratum_1463225_wa);
@@ -464,6 +524,10 @@ has_cortex_a76_erratum_1463225(const struct arm64_cpu_capabilities *entry,
 	.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,			\
 	.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,			\
 	CAP_MIDR_RANGE_LIST(midr_list)
 	CAP_MIDR_RANGE_LIST(midr_list)
 
 
+/* Track overall mitigation state. We are only mitigated if all cores are ok */
+static bool __hardenbp_enab = true;
+static bool __spectrev2_safe = true;
+
 /*
 /*
  * Generic helper for handling capabilties with multiple (match,enable) pairs
  * Generic helper for handling capabilties with multiple (match,enable) pairs
  * of call backs, sharing the same capability bit.
  * of call backs, sharing the same capability bit.
@@ -496,26 +560,63 @@ multi_entry_cap_cpu_enable(const struct arm64_cpu_capabilities *entry)
 			caps->cpu_enable(caps);
 			caps->cpu_enable(caps);
 }
 }
 
 
-#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
-
 /*
 /*
- * List of CPUs where we need to issue a psci call to
- * harden the branch predictor.
+ * List of CPUs that do not need any Spectre-v2 mitigation at all.
  */
  */
-static const struct midr_range arm64_bp_harden_smccc_cpus[] = {
-	MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
-	MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
-	MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
-	MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
-	MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN),
-	MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2),
-	MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR_V1),
-	MIDR_ALL_VERSIONS(MIDR_QCOM_FALKOR),
-	MIDR_ALL_VERSIONS(MIDR_NVIDIA_DENVER),
-	{},
+static const struct midr_range spectre_v2_safe_list[] = {
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A35),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A53),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A55),
+	{ /* sentinel */ }
 };
 };
 
 
-#endif
+/*
+ * Track overall bp hardening for all heterogeneous cores in the machine.
+ * We are only considered "safe" if all booted cores are known safe.
+ */
+static bool __maybe_unused
+check_branch_predictor(const struct arm64_cpu_capabilities *entry, int scope)
+{
+	int need_wa;
+
+	WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
+
+	/* If the CPU has CSV2 set, we're safe */
+	if (cpuid_feature_extract_unsigned_field(read_cpuid(ID_AA64PFR0_EL1),
+						 ID_AA64PFR0_CSV2_SHIFT))
+		return false;
+
+	/* Alternatively, we have a list of unaffected CPUs */
+	if (is_midr_in_range_list(read_cpuid_id(), spectre_v2_safe_list))
+		return false;
+
+	/* Fallback to firmware detection */
+	need_wa = detect_harden_bp_fw();
+	if (!need_wa)
+		return false;
+
+	__spectrev2_safe = false;
+
+	if (!IS_ENABLED(CONFIG_HARDEN_BRANCH_PREDICTOR)) {
+		pr_warn_once("spectrev2 mitigation disabled by kernel configuration\n");
+		__hardenbp_enab = false;
+		return false;
+	}
+
+	/* forced off */
+	if (__nospectre_v2 || cpu_mitigations_off()) {
+		pr_info_once("spectrev2 mitigation disabled by command line option\n");
+		__hardenbp_enab = false;
+		return false;
+	}
+
+	if (need_wa < 0) {
+		pr_warn_once("ARM_SMCCC_ARCH_WORKAROUND_1 missing from firmware\n");
+		__hardenbp_enab = false;
+	}
+
+	return (need_wa > 0);
+}
 
 
 #ifdef CONFIG_HARDEN_EL2_VECTORS
 #ifdef CONFIG_HARDEN_EL2_VECTORS
 
 
@@ -674,13 +775,11 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		ERRATA_MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
 		ERRATA_MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
 	},
 	},
 #endif
 #endif
-#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
 	{
 	{
 		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
 		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
-		.cpu_enable = enable_smccc_arch_workaround_1,
-		ERRATA_MIDR_RANGE_LIST(arm64_bp_harden_smccc_cpus),
+		.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
+		.matches = check_branch_predictor,
 	},
 	},
-#endif
 #ifdef CONFIG_HARDEN_EL2_VECTORS
 #ifdef CONFIG_HARDEN_EL2_VECTORS
 	{
 	{
 		.desc = "EL2 vector hardening",
 		.desc = "EL2 vector hardening",
@@ -688,14 +787,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		ERRATA_MIDR_RANGE_LIST(arm64_harden_el2_vectors),
 		ERRATA_MIDR_RANGE_LIST(arm64_harden_el2_vectors),
 	},
 	},
 #endif
 #endif
-#ifdef CONFIG_ARM64_SSBD
 	{
 	{
 		.desc = "Speculative Store Bypass Disable",
 		.desc = "Speculative Store Bypass Disable",
 		.capability = ARM64_SSBD,
 		.capability = ARM64_SSBD,
 		.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
 		.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
 		.matches = has_ssbd_mitigation,
 		.matches = has_ssbd_mitigation,
+		.midr_range_list = arm64_ssb_cpus,
 	},
 	},
-#endif
 #ifdef CONFIG_ARM64_ERRATUM_1463225
 #ifdef CONFIG_ARM64_ERRATUM_1463225
 	{
 	{
 		.desc = "ARM erratum 1463225",
 		.desc = "ARM erratum 1463225",
@@ -707,3 +805,38 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 	{
 	{
 	}
 	}
 };
 };
+
+ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	return sprintf(buf, "Mitigation: __user pointer sanitization\n");
+}
+
+ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	if (__spectrev2_safe)
+		return sprintf(buf, "Not affected\n");
+
+	if (__hardenbp_enab)
+		return sprintf(buf, "Mitigation: Branch predictor hardening\n");
+
+	return sprintf(buf, "Vulnerable\n");
+}
+
+ssize_t cpu_show_spec_store_bypass(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	if (__ssb_safe)
+		return sprintf(buf, "Not affected\n");
+
+	switch (ssbd_state) {
+	case ARM64_SSBD_KERNEL:
+	case ARM64_SSBD_FORCE_ENABLE:
+		if (IS_ENABLED(CONFIG_ARM64_SSBD))
+			return sprintf(buf,
+			    "Mitigation: Speculative Store Bypass disabled via prctl\n");
+	}
+
+	return sprintf(buf, "Vulnerable\n");
+}

+ 120 - 18
arch/arm64/kernel/cpufeature.c

@@ -24,6 +24,7 @@
 #include <linux/stop_machine.h>
 #include <linux/stop_machine.h>
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/mm.h>
+#include <linux/cpu.h>
 #include <asm/cpu.h>
 #include <asm/cpu.h>
 #include <asm/cpufeature.h>
 #include <asm/cpufeature.h>
 #include <asm/cpu_ops.h>
 #include <asm/cpu_ops.h>
@@ -164,6 +165,11 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
 	ARM64_FTR_END,
 	ARM64_FTR_END,
 };
 };
 
 
+static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
+	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_SSBS_SHIFT, 4, ID_AA64PFR1_SSBS_PSTATE_NI),
+	ARM64_FTR_END,
+};
+
 static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
 static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
 	/*
 	/*
 	 * We already refuse to boot CPUs that don't support our configured
 	 * We already refuse to boot CPUs that don't support our configured
@@ -379,7 +385,7 @@ static const struct __ftr_reg_entry {
 
 
 	/* Op1 = 0, CRn = 0, CRm = 4 */
 	/* Op1 = 0, CRn = 0, CRm = 4 */
 	ARM64_FTR_REG(SYS_ID_AA64PFR0_EL1, ftr_id_aa64pfr0),
 	ARM64_FTR_REG(SYS_ID_AA64PFR0_EL1, ftr_id_aa64pfr0),
-	ARM64_FTR_REG(SYS_ID_AA64PFR1_EL1, ftr_raz),
+	ARM64_FTR_REG(SYS_ID_AA64PFR1_EL1, ftr_id_aa64pfr1),
 	ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_raz),
 	ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_raz),
 
 
 	/* Op1 = 0, CRn = 0, CRm = 5 */
 	/* Op1 = 0, CRn = 0, CRm = 5 */
@@ -669,7 +675,6 @@ void update_cpu_features(int cpu,
 
 
 	/*
 	/*
 	 * EL3 is not our concern.
 	 * EL3 is not our concern.
-	 * ID_AA64PFR1 is currently RES0.
 	 */
 	 */
 	taint |= check_update_ftr_reg(SYS_ID_AA64PFR0_EL1, cpu,
 	taint |= check_update_ftr_reg(SYS_ID_AA64PFR0_EL1, cpu,
 				      info->reg_id_aa64pfr0, boot->reg_id_aa64pfr0);
 				      info->reg_id_aa64pfr0, boot->reg_id_aa64pfr0);
@@ -846,7 +851,7 @@ static bool has_no_hw_prefetch(const struct arm64_cpu_capabilities *entry, int _
 	u32 midr = read_cpuid_id();
 	u32 midr = read_cpuid_id();
 
 
 	/* Cavium ThunderX pass 1.x and 2.x */
 	/* Cavium ThunderX pass 1.x and 2.x */
-	return MIDR_IS_CPU_MODEL_RANGE(midr, MIDR_THUNDERX,
+	return midr_is_cpu_model_range(midr, MIDR_THUNDERX,
 		MIDR_CPU_VAR_REV(0, 0),
 		MIDR_CPU_VAR_REV(0, 0),
 		MIDR_CPU_VAR_REV(1, MIDR_REVISION_MASK));
 		MIDR_CPU_VAR_REV(1, MIDR_REVISION_MASK));
 }
 }
@@ -885,7 +890,7 @@ static bool has_cache_dic(const struct arm64_cpu_capabilities *entry,
 	return ctr & BIT(CTR_DIC_SHIFT);
 	return ctr & BIT(CTR_DIC_SHIFT);
 }
 }
 
 
-#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+static bool __meltdown_safe = true;
 static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */
 static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */
 
 
 static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
 static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
@@ -895,9 +900,25 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
 	static const struct midr_range kpti_safe_list[] = {
 	static const struct midr_range kpti_safe_list[] = {
 		MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2),
 		MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2),
 		MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN),
 		MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A35),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A53),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A55),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
+		MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
 		{ /* sentinel */ }
 		{ /* sentinel */ }
 	};
 	};
-	char const *str = "command line option";
+	char const *str = "kpti command line option";
+	bool meltdown_safe;
+
+	meltdown_safe = is_midr_in_range_list(read_cpuid_id(), kpti_safe_list);
+
+	/* Defer to CPU feature registers */
+	if (has_cpuid_feature(entry, scope))
+		meltdown_safe = true;
+
+	if (!meltdown_safe)
+		__meltdown_safe = false;
 
 
 	/*
 	/*
 	 * For reasons that aren't entirely clear, enabling KPTI on Cavium
 	 * For reasons that aren't entirely clear, enabling KPTI on Cavium
@@ -909,6 +930,24 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
 		__kpti_forced = -1;
 		__kpti_forced = -1;
 	}
 	}
 
 
+	/* Useful for KASLR robustness */
+	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && kaslr_offset() > 0) {
+		if (!__kpti_forced) {
+			str = "KASLR";
+			__kpti_forced = 1;
+		}
+	}
+
+	if (cpu_mitigations_off() && !__kpti_forced) {
+		str = "mitigations=off";
+		__kpti_forced = -1;
+	}
+
+	if (!IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) {
+		pr_info_once("kernel page table isolation disabled by kernel configuration\n");
+		return false;
+	}
+
 	/* Forced? */
 	/* Forced? */
 	if (__kpti_forced) {
 	if (__kpti_forced) {
 		pr_info_once("kernel page table isolation forced %s by %s\n",
 		pr_info_once("kernel page table isolation forced %s by %s\n",
@@ -916,18 +955,10 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
 		return __kpti_forced > 0;
 		return __kpti_forced > 0;
 	}
 	}
 
 
-	/* Useful for KASLR robustness */
-	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE))
-		return true;
-
-	/* Don't force KPTI for CPUs that are not vulnerable */
-	if (is_midr_in_range_list(read_cpuid_id(), kpti_safe_list))
-		return false;
-
-	/* Defer to CPU feature registers */
-	return !has_cpuid_feature(entry, scope);
+	return !meltdown_safe;
 }
 }
 
 
+#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
 static void
 static void
 kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused)
 kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused)
 {
 {
@@ -952,6 +983,12 @@ kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused)
 
 
 	return;
 	return;
 }
 }
+#else
+static void
+kpti_install_ng_mappings(const struct arm64_cpu_capabilities *__unused)
+{
+}
+#endif	/* CONFIG_UNMAP_KERNEL_AT_EL0 */
 
 
 static int __init parse_kpti(char *str)
 static int __init parse_kpti(char *str)
 {
 {
@@ -965,7 +1002,6 @@ static int __init parse_kpti(char *str)
 	return 0;
 	return 0;
 }
 }
 early_param("kpti", parse_kpti);
 early_param("kpti", parse_kpti);
-#endif	/* CONFIG_UNMAP_KERNEL_AT_EL0 */
 
 
 #ifdef CONFIG_ARM64_HW_AFDBM
 #ifdef CONFIG_ARM64_HW_AFDBM
 static inline void __cpu_enable_hw_dbm(void)
 static inline void __cpu_enable_hw_dbm(void)
@@ -1061,6 +1097,48 @@ static void cpu_has_fwb(const struct arm64_cpu_capabilities *__unused)
 	WARN_ON(val & (7 << 27 | 7 << 21));
 	WARN_ON(val & (7 << 27 | 7 << 21));
 }
 }
 
 
+#ifdef CONFIG_ARM64_SSBD
+static int ssbs_emulation_handler(struct pt_regs *regs, u32 instr)
+{
+	if (user_mode(regs))
+		return 1;
+
+	if (instr & BIT(CRm_shift))
+		regs->pstate |= PSR_SSBS_BIT;
+	else
+		regs->pstate &= ~PSR_SSBS_BIT;
+
+	arm64_skip_faulting_instruction(regs, 4);
+	return 0;
+}
+
+static struct undef_hook ssbs_emulation_hook = {
+	.instr_mask	= ~(1U << CRm_shift),
+	.instr_val	= 0xd500001f | REG_PSTATE_SSBS_IMM,
+	.fn		= ssbs_emulation_handler,
+};
+
+static void cpu_enable_ssbs(const struct arm64_cpu_capabilities *__unused)
+{
+	static bool undef_hook_registered = false;
+	static DEFINE_SPINLOCK(hook_lock);
+
+	spin_lock(&hook_lock);
+	if (!undef_hook_registered) {
+		register_undef_hook(&ssbs_emulation_hook);
+		undef_hook_registered = true;
+	}
+	spin_unlock(&hook_lock);
+
+	if (arm64_get_ssbd_state() == ARM64_SSBD_FORCE_DISABLE) {
+		sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_DSSBS);
+		arm64_set_ssbd_mitigation(false);
+	} else {
+		arm64_set_ssbd_mitigation(true);
+	}
+}
+#endif /* CONFIG_ARM64_SSBD */
+
 static const struct arm64_cpu_capabilities arm64_features[] = {
 static const struct arm64_cpu_capabilities arm64_features[] = {
 	{
 	{
 		.desc = "GIC system register CPU interface",
 		.desc = "GIC system register CPU interface",
@@ -1144,7 +1222,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.field_pos = ID_AA64PFR0_EL0_SHIFT,
 		.field_pos = ID_AA64PFR0_EL0_SHIFT,
 		.min_field_value = ID_AA64PFR0_EL0_32BIT_64BIT,
 		.min_field_value = ID_AA64PFR0_EL0_32BIT_64BIT,
 	},
 	},
-#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
 	{
 	{
 		.desc = "Kernel page table isolation (KPTI)",
 		.desc = "Kernel page table isolation (KPTI)",
 		.capability = ARM64_UNMAP_KERNEL_AT_EL0,
 		.capability = ARM64_UNMAP_KERNEL_AT_EL0,
@@ -1160,7 +1237,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = unmap_kernel_at_el0,
 		.matches = unmap_kernel_at_el0,
 		.cpu_enable = kpti_install_ng_mappings,
 		.cpu_enable = kpti_install_ng_mappings,
 	},
 	},
-#endif
 	{
 	{
 		/* FP/SIMD is not implemented */
 		/* FP/SIMD is not implemented */
 		.capability = ARM64_HAS_NO_FPSIMD,
 		.capability = ARM64_HAS_NO_FPSIMD,
@@ -1247,6 +1323,19 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_hw_dbm,
 		.matches = has_hw_dbm,
 		.cpu_enable = cpu_enable_hw_dbm,
 		.cpu_enable = cpu_enable_hw_dbm,
 	},
 	},
+#endif
+#ifdef CONFIG_ARM64_SSBD
+	{
+		.desc = "Speculative Store Bypassing Safe (SSBS)",
+		.capability = ARM64_SSBS,
+		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
+		.matches = has_cpuid_feature,
+		.sys_reg = SYS_ID_AA64PFR1_EL1,
+		.field_pos = ID_AA64PFR1_SSBS_SHIFT,
+		.sign = FTR_UNSIGNED,
+		.min_field_value = ID_AA64PFR1_SSBS_PSTATE_ONLY,
+		.cpu_enable = cpu_enable_ssbs,
+	},
 #endif
 #endif
 	{},
 	{},
 };
 };
@@ -1293,6 +1382,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 #ifdef CONFIG_ARM64_SVE
 #ifdef CONFIG_ARM64_SVE
 	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, HWCAP_SVE),
 	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, HWCAP_SVE),
 #endif
 #endif
+	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, HWCAP_SSBS),
 	{},
 	{},
 };
 };
 
 
@@ -1787,3 +1877,15 @@ void cpu_clear_disr(const struct arm64_cpu_capabilities *__unused)
 	/* Firmware may have left a deferred SError in this register. */
 	/* Firmware may have left a deferred SError in this register. */
 	write_sysreg_s(0, SYS_DISR_EL1);
 	write_sysreg_s(0, SYS_DISR_EL1);
 }
 }
+
+ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr,
+			  char *buf)
+{
+	if (__meltdown_safe)
+		return sprintf(buf, "Not affected\n");
+
+	if (arm64_kernel_unmapped_at_el0())
+		return sprintf(buf, "Mitigation: PTI\n");
+
+	return sprintf(buf, "Vulnerable\n");
+}

+ 1 - 0
arch/arm64/kernel/cpuinfo.c

@@ -81,6 +81,7 @@ static const char *const hwcap_str[] = {
 	"uscat",
 	"uscat",
 	"ilrcpc",
 	"ilrcpc",
 	"flagm",
 	"flagm",
+	"ssbs",
 	NULL
 	NULL
 };
 };
 
 

+ 31 - 0
arch/arm64/kernel/process.c

@@ -358,6 +358,10 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
 		if (IS_ENABLED(CONFIG_ARM64_UAO) &&
 		if (IS_ENABLED(CONFIG_ARM64_UAO) &&
 		    cpus_have_const_cap(ARM64_HAS_UAO))
 		    cpus_have_const_cap(ARM64_HAS_UAO))
 			childregs->pstate |= PSR_UAO_BIT;
 			childregs->pstate |= PSR_UAO_BIT;
+
+		if (arm64_get_ssbd_state() == ARM64_SSBD_FORCE_DISABLE)
+			set_ssbs_bit(childregs);
+
 		p->thread.cpu_context.x19 = stack_start;
 		p->thread.cpu_context.x19 = stack_start;
 		p->thread.cpu_context.x20 = stk_sz;
 		p->thread.cpu_context.x20 = stk_sz;
 	}
 	}
@@ -397,6 +401,32 @@ void uao_thread_switch(struct task_struct *next)
 	}
 	}
 }
 }
 
 
+/*
+ * Force SSBS state on context-switch, since it may be lost after migrating
+ * from a CPU which treats the bit as RES0 in a heterogeneous system.
+ */
+static void ssbs_thread_switch(struct task_struct *next)
+{
+	struct pt_regs *regs = task_pt_regs(next);
+
+	/*
+	 * Nothing to do for kernel threads, but 'regs' may be junk
+	 * (e.g. idle task) so check the flags and bail early.
+	 */
+	if (unlikely(next->flags & PF_KTHREAD))
+		return;
+
+	/* If the mitigation is enabled, then we leave SSBS clear. */
+	if ((arm64_get_ssbd_state() == ARM64_SSBD_FORCE_ENABLE) ||
+	    test_tsk_thread_flag(next, TIF_SSBD))
+		return;
+
+	if (compat_user_mode(regs))
+		set_compat_ssbs_bit(regs);
+	else if (user_mode(regs))
+		set_ssbs_bit(regs);
+}
+
 /*
 /*
  * We store our current task in sp_el0, which is clobbered by userspace. Keep a
  * We store our current task in sp_el0, which is clobbered by userspace. Keep a
  * shadow copy so that we can restore this upon entry from userspace.
  * shadow copy so that we can restore this upon entry from userspace.
@@ -425,6 +455,7 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
 	contextidr_thread_switch(next);
 	contextidr_thread_switch(next);
 	entry_task_switch(next);
 	entry_task_switch(next);
 	uao_thread_switch(next);
 	uao_thread_switch(next);
+	ssbs_thread_switch(next);
 
 
 	/*
 	/*
 	 * Complete any pending TLB or cache maintenance on this CPU in case
 	 * Complete any pending TLB or cache maintenance on this CPU in case

+ 8 - 7
arch/arm64/kernel/ptrace.c

@@ -1666,19 +1666,20 @@ void syscall_trace_exit(struct pt_regs *regs)
 }
 }
 
 
 /*
 /*
- * SPSR_ELx bits which are always architecturally RES0 per ARM DDI 0487C.a
- * We also take into account DIT (bit 24), which is not yet documented, and
- * treat PAN and UAO as RES0 bits, as they are meaningless at EL0, and may be
- * allocated an EL0 meaning in future.
+ * SPSR_ELx bits which are always architecturally RES0 per ARM DDI 0487D.a.
+ * We permit userspace to set SSBS (AArch64 bit 12, AArch32 bit 23) which is
+ * not described in ARM DDI 0487D.a.
+ * We treat PAN and UAO as RES0 bits, as they are meaningless at EL0, and may
+ * be allocated an EL0 meaning in future.
  * Userspace cannot use these until they have an architectural meaning.
  * Userspace cannot use these until they have an architectural meaning.
  * Note that this follows the SPSR_ELx format, not the AArch32 PSR format.
  * Note that this follows the SPSR_ELx format, not the AArch32 PSR format.
  * We also reserve IL for the kernel; SS is handled dynamically.
  * We also reserve IL for the kernel; SS is handled dynamically.
  */
  */
 #define SPSR_EL1_AARCH64_RES0_BITS \
 #define SPSR_EL1_AARCH64_RES0_BITS \
-	(GENMASK_ULL(63,32) | GENMASK_ULL(27, 25) | GENMASK_ULL(23, 22) | \
-	 GENMASK_ULL(20, 10) | GENMASK_ULL(5, 5))
+	(GENMASK_ULL(63, 32) | GENMASK_ULL(27, 25) | GENMASK_ULL(23, 22) | \
+	 GENMASK_ULL(20, 13) | GENMASK_ULL(11, 10) | GENMASK_ULL(5, 5))
 #define SPSR_EL1_AARCH32_RES0_BITS \
 #define SPSR_EL1_AARCH32_RES0_BITS \
-	(GENMASK_ULL(63,32) | GENMASK_ULL(23, 22) | GENMASK_ULL(20,20))
+	(GENMASK_ULL(63, 32) | GENMASK_ULL(22, 22) | GENMASK_ULL(20, 20))
 
 
 static int valid_compat_regs(struct user_pt_regs *regs)
 static int valid_compat_regs(struct user_pt_regs *regs)
 {
 {

+ 21 - 0
arch/arm64/kernel/ssbd.c

@@ -3,13 +3,31 @@
  * Copyright (C) 2018 ARM Ltd, All Rights Reserved.
  * Copyright (C) 2018 ARM Ltd, All Rights Reserved.
  */
  */
 
 
+#include <linux/compat.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
 #include <linux/prctl.h>
 #include <linux/prctl.h>
 #include <linux/sched.h>
 #include <linux/sched.h>
+#include <linux/sched/task_stack.h>
 #include <linux/thread_info.h>
 #include <linux/thread_info.h>
 
 
 #include <asm/cpufeature.h>
 #include <asm/cpufeature.h>
 
 
+static void ssbd_ssbs_enable(struct task_struct *task)
+{
+	u64 val = is_compat_thread(task_thread_info(task)) ?
+		  PSR_AA32_SSBS_BIT : PSR_SSBS_BIT;
+
+	task_pt_regs(task)->pstate |= val;
+}
+
+static void ssbd_ssbs_disable(struct task_struct *task)
+{
+	u64 val = is_compat_thread(task_thread_info(task)) ?
+		  PSR_AA32_SSBS_BIT : PSR_SSBS_BIT;
+
+	task_pt_regs(task)->pstate &= ~val;
+}
+
 /*
 /*
  * prctl interface for SSBD
  * prctl interface for SSBD
  * FIXME: Drop the below ifdefery once merged in 4.18.
  * FIXME: Drop the below ifdefery once merged in 4.18.
@@ -47,12 +65,14 @@ static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl)
 			return -EPERM;
 			return -EPERM;
 		task_clear_spec_ssb_disable(task);
 		task_clear_spec_ssb_disable(task);
 		clear_tsk_thread_flag(task, TIF_SSBD);
 		clear_tsk_thread_flag(task, TIF_SSBD);
+		ssbd_ssbs_enable(task);
 		break;
 		break;
 	case PR_SPEC_DISABLE:
 	case PR_SPEC_DISABLE:
 		if (state == ARM64_SSBD_FORCE_DISABLE)
 		if (state == ARM64_SSBD_FORCE_DISABLE)
 			return -EPERM;
 			return -EPERM;
 		task_set_spec_ssb_disable(task);
 		task_set_spec_ssb_disable(task);
 		set_tsk_thread_flag(task, TIF_SSBD);
 		set_tsk_thread_flag(task, TIF_SSBD);
+		ssbd_ssbs_disable(task);
 		break;
 		break;
 	case PR_SPEC_FORCE_DISABLE:
 	case PR_SPEC_FORCE_DISABLE:
 		if (state == ARM64_SSBD_FORCE_DISABLE)
 		if (state == ARM64_SSBD_FORCE_DISABLE)
@@ -60,6 +80,7 @@ static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl)
 		task_set_spec_ssb_disable(task);
 		task_set_spec_ssb_disable(task);
 		task_set_spec_ssb_force_disable(task);
 		task_set_spec_ssb_force_disable(task);
 		set_tsk_thread_flag(task, TIF_SSBD);
 		set_tsk_thread_flag(task, TIF_SSBD);
+		ssbd_ssbs_disable(task);
 		break;
 		break;
 	default:
 	default:
 		return -ERANGE;
 		return -ERANGE;

+ 11 - 0
arch/arm64/kvm/hyp/sysreg-sr.c

@@ -293,3 +293,14 @@ void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu)
 
 
 	vcpu->arch.sysregs_loaded_on_cpu = false;
 	vcpu->arch.sysregs_loaded_on_cpu = false;
 }
 }
+
+void __hyp_text __kvm_enable_ssbs(void)
+{
+	u64 tmp;
+
+	asm volatile(
+	"mrs	%0, sctlr_el2\n"
+	"orr	%0, %0, %1\n"
+	"msr	sctlr_el2, %0"
+	: "=&r" (tmp) : "L" (SCTLR_ELx_DSSBS));
+}

+ 5 - 1
arch/arm64/mm/mmap.c

@@ -65,7 +65,11 @@ unsigned long arch_mmap_rnd(void)
 static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
 static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
 {
 {
 	unsigned long gap = rlim_stack->rlim_cur;
 	unsigned long gap = rlim_stack->rlim_cur;
-	unsigned long pad = (STACK_RND_MASK << PAGE_SHIFT) + stack_guard_gap;
+	unsigned long pad = stack_guard_gap;
+
+	/* Account for stack randomization if necessary */
+	if (current->flags & PF_RANDOMIZE)
+		pad += (STACK_RND_MASK << PAGE_SHIFT);
 
 
 	/* Values close to RLIM_INFINITY can overflow. */
 	/* Values close to RLIM_INFINITY can overflow. */
 	if (gap + pad > gap)
 	if (gap + pad > gap)

+ 9 - 0
arch/arm64/mm/proc.S

@@ -294,6 +294,15 @@ skip_pgd:
 	msr	sctlr_el1, x18
 	msr	sctlr_el1, x18
 	isb
 	isb
 
 
+	/*
+	 * Invalidate the local I-cache so that any instructions fetched
+	 * speculatively from the PoC are discarded, since they may have
+	 * been dynamically patched at the PoU.
+	 */
+	ic	iallu
+	dsb	nsh
+	isb
+
 	/* Set the flag to zero to indicate that we're all done */
 	/* Set the flag to zero to indicate that we're all done */
 	str	wzr, [flag_ptr]
 	str	wzr, [flag_ptr]
 	ret
 	ret

+ 6 - 2
arch/ia64/kernel/module.c

@@ -914,10 +914,14 @@ module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mo
 void
 void
 module_arch_cleanup (struct module *mod)
 module_arch_cleanup (struct module *mod)
 {
 {
-	if (mod->arch.init_unw_table)
+	if (mod->arch.init_unw_table) {
 		unw_remove_unwind_table(mod->arch.init_unw_table);
 		unw_remove_unwind_table(mod->arch.init_unw_table);
-	if (mod->arch.core_unw_table)
+		mod->arch.init_unw_table = NULL;
+	}
+	if (mod->arch.core_unw_table) {
 		unw_remove_unwind_table(mod->arch.core_unw_table);
 		unw_remove_unwind_table(mod->arch.core_unw_table);
+		mod->arch.core_unw_table = NULL;
+	}
 }
 }
 
 
 void *dereference_module_function_descriptor(struct module *mod, void *ptr)
 void *dereference_module_function_descriptor(struct module *mod, void *ptr)

+ 0 - 9
arch/m68k/include/asm/atarihw.h

@@ -22,7 +22,6 @@
 
 
 #include <linux/types.h>
 #include <linux/types.h>
 #include <asm/bootinfo-atari.h>
 #include <asm/bootinfo-atari.h>
-#include <asm/raw_io.h>
 #include <asm/kmap.h>
 #include <asm/kmap.h>
 
 
 extern u_long atari_mch_cookie;
 extern u_long atari_mch_cookie;
@@ -126,14 +125,6 @@ extern struct atari_hw_present atari_hw_present;
  */
  */
 
 
 
 
-#define atari_readb   raw_inb
-#define atari_writeb  raw_outb
-
-#define atari_inb_p   raw_inb
-#define atari_outb_p  raw_outb
-
-
-
 #include <linux/mm.h>
 #include <linux/mm.h>
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
 
 

+ 5 - 1
arch/m68k/include/asm/io_mm.h

@@ -29,7 +29,11 @@
 #include <asm-generic/iomap.h>
 #include <asm-generic/iomap.h>
 
 
 #ifdef CONFIG_ATARI
 #ifdef CONFIG_ATARI
-#include <asm/atarihw.h>
+#define atari_readb   raw_inb
+#define atari_writeb  raw_outb
+
+#define atari_inb_p   raw_inb
+#define atari_outb_p  raw_outb
 #endif
 #endif
 
 
 
 

+ 1 - 0
arch/m68k/include/asm/macintosh.h

@@ -4,6 +4,7 @@
 
 
 #include <linux/seq_file.h>
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 
 
 #include <asm/bootinfo-mac.h>
 #include <asm/bootinfo-mac.h>
 
 

+ 16 - 0
arch/mips/include/asm/cpu-features.h

@@ -387,6 +387,22 @@
 #define cpu_has_dsp3		__ase(MIPS_ASE_DSP3)
 #define cpu_has_dsp3		__ase(MIPS_ASE_DSP3)
 #endif
 #endif
 
 
+#ifndef cpu_has_loongson_mmi
+#define cpu_has_loongson_mmi		__ase(MIPS_ASE_LOONGSON_MMI)
+#endif
+
+#ifndef cpu_has_loongson_cam
+#define cpu_has_loongson_cam		__ase(MIPS_ASE_LOONGSON_CAM)
+#endif
+
+#ifndef cpu_has_loongson_ext
+#define cpu_has_loongson_ext		__ase(MIPS_ASE_LOONGSON_EXT)
+#endif
+
+#ifndef cpu_has_loongson_ext2
+#define cpu_has_loongson_ext2		__ase(MIPS_ASE_LOONGSON_EXT2)
+#endif
+
 #ifndef cpu_has_mipsmt
 #ifndef cpu_has_mipsmt
 #define cpu_has_mipsmt		__isa_lt_and_ase(6, MIPS_ASE_MIPSMT)
 #define cpu_has_mipsmt		__isa_lt_and_ase(6, MIPS_ASE_MIPSMT)
 #endif
 #endif

+ 4 - 0
arch/mips/include/asm/cpu.h

@@ -436,5 +436,9 @@ enum cpu_type_enum {
 #define MIPS_ASE_MSA		0x00000100 /* MIPS SIMD Architecture */
 #define MIPS_ASE_MSA		0x00000100 /* MIPS SIMD Architecture */
 #define MIPS_ASE_DSP3		0x00000200 /* Signal Processing ASE Rev 3*/
 #define MIPS_ASE_DSP3		0x00000200 /* Signal Processing ASE Rev 3*/
 #define MIPS_ASE_MIPS16E2	0x00000400 /* MIPS16e2 */
 #define MIPS_ASE_MIPS16E2	0x00000400 /* MIPS16e2 */
+#define MIPS_ASE_LOONGSON_MMI	0x00000800 /* Loongson MultiMedia extensions Instructions */
+#define MIPS_ASE_LOONGSON_CAM	0x00001000 /* Loongson CAM */
+#define MIPS_ASE_LOONGSON_EXT	0x00002000 /* Loongson EXTensions */
+#define MIPS_ASE_LOONGSON_EXT2	0x00004000 /* Loongson EXTensions R2 */
 
 
 #endif /* _ASM_CPU_H */
 #endif /* _ASM_CPU_H */

+ 4 - 0
arch/mips/include/asm/mipsregs.h

@@ -688,6 +688,9 @@
 #define MIPS_CONF7_IAR		(_ULCAST_(1) << 10)
 #define MIPS_CONF7_IAR		(_ULCAST_(1) << 10)
 #define MIPS_CONF7_AR		(_ULCAST_(1) << 16)
 #define MIPS_CONF7_AR		(_ULCAST_(1) << 16)
 
 
+/* Ingenic Config7 bits */
+#define MIPS_CONF7_BTB_LOOP_EN	(_ULCAST_(1) << 4)
+
 /* Config7 Bits specific to MIPS Technologies. */
 /* Config7 Bits specific to MIPS Technologies. */
 
 
 /* Performance counters implemented Per TC */
 /* Performance counters implemented Per TC */
@@ -2774,6 +2777,7 @@ __BUILD_SET_C0(status)
 __BUILD_SET_C0(cause)
 __BUILD_SET_C0(cause)
 __BUILD_SET_C0(config)
 __BUILD_SET_C0(config)
 __BUILD_SET_C0(config5)
 __BUILD_SET_C0(config5)
+__BUILD_SET_C0(config7)
 __BUILD_SET_C0(intcontrol)
 __BUILD_SET_C0(intcontrol)
 __BUILD_SET_C0(intctl)
 __BUILD_SET_C0(intctl)
 __BUILD_SET_C0(srsmap)
 __BUILD_SET_C0(srsmap)

+ 13 - 0
arch/mips/kernel/cpu-probe.c

@@ -1489,6 +1489,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
 			__cpu_name[cpu] = "ICT Loongson-3";
 			__cpu_name[cpu] = "ICT Loongson-3";
 			set_elf_platform(cpu, "loongson3a");
 			set_elf_platform(cpu, "loongson3a");
 			set_isa(c, MIPS_CPU_ISA_M64R1);
 			set_isa(c, MIPS_CPU_ISA_M64R1);
+			c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
+				MIPS_ASE_LOONGSON_EXT);
 			break;
 			break;
 		case PRID_REV_LOONGSON3B_R1:
 		case PRID_REV_LOONGSON3B_R1:
 		case PRID_REV_LOONGSON3B_R2:
 		case PRID_REV_LOONGSON3B_R2:
@@ -1496,6 +1498,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
 			__cpu_name[cpu] = "ICT Loongson-3";
 			__cpu_name[cpu] = "ICT Loongson-3";
 			set_elf_platform(cpu, "loongson3b");
 			set_elf_platform(cpu, "loongson3b");
 			set_isa(c, MIPS_CPU_ISA_M64R1);
 			set_isa(c, MIPS_CPU_ISA_M64R1);
+			c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
+				MIPS_ASE_LOONGSON_EXT);
 			break;
 			break;
 		}
 		}
 
 
@@ -1861,6 +1865,8 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
 		decode_configs(c);
 		decode_configs(c);
 		c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE;
 		c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE;
 		c->writecombine = _CACHE_UNCACHED_ACCELERATED;
 		c->writecombine = _CACHE_UNCACHED_ACCELERATED;
+		c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
+			MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2);
 		break;
 		break;
 	default:
 	default:
 		panic("Unknown Loongson Processor ID!");
 		panic("Unknown Loongson Processor ID!");
@@ -1879,6 +1885,13 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
 		c->cputype = CPU_JZRISC;
 		c->cputype = CPU_JZRISC;
 		c->writecombine = _CACHE_UNCACHED_ACCELERATED;
 		c->writecombine = _CACHE_UNCACHED_ACCELERATED;
 		__cpu_name[cpu] = "Ingenic JZRISC";
 		__cpu_name[cpu] = "Ingenic JZRISC";
+		/*
+		 * The XBurst core by default attempts to avoid branch target
+		 * buffer lookups by detecting & special casing loops. This
+		 * feature will cause BogoMIPS and lpj calculate in error.
+		 * Set cp0 config7 bit 4 to disable this feature.
+		 */
+		set_c0_config7(MIPS_CONF7_BTB_LOOP_EN);
 		break;
 		break;
 	default:
 	default:
 		panic("Unknown Ingenic Processor ID!");
 		panic("Unknown Ingenic Processor ID!");

+ 4 - 0
arch/mips/kernel/proc.c

@@ -124,6 +124,10 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 	if (cpu_has_eva)	seq_printf(m, "%s", " eva");
 	if (cpu_has_eva)	seq_printf(m, "%s", " eva");
 	if (cpu_has_htw)	seq_printf(m, "%s", " htw");
 	if (cpu_has_htw)	seq_printf(m, "%s", " htw");
 	if (cpu_has_xpa)	seq_printf(m, "%s", " xpa");
 	if (cpu_has_xpa)	seq_printf(m, "%s", " xpa");
+	if (cpu_has_loongson_mmi)	seq_printf(m, "%s", " loongson-mmi");
+	if (cpu_has_loongson_cam)	seq_printf(m, "%s", " loongson-cam");
+	if (cpu_has_loongson_ext)	seq_printf(m, "%s", " loongson-ext");
+	if (cpu_has_loongson_ext2)	seq_printf(m, "%s", " loongson-ext2");
 	seq_printf(m, "\n");
 	seq_printf(m, "\n");
 
 
 	if (cpu_has_mmips) {
 	if (cpu_has_mmips) {

+ 12 - 2
arch/mips/mm/mmap.c

@@ -21,8 +21,9 @@ unsigned long shm_align_mask = PAGE_SIZE - 1;	/* Sane caches */
 EXPORT_SYMBOL(shm_align_mask);
 EXPORT_SYMBOL(shm_align_mask);
 
 
 /* gap between mmap and stack */
 /* gap between mmap and stack */
-#define MIN_GAP (128*1024*1024UL)
-#define MAX_GAP ((TASK_SIZE)/6*5)
+#define MIN_GAP		(128*1024*1024UL)
+#define MAX_GAP		((TASK_SIZE)/6*5)
+#define STACK_RND_MASK	(0x7ff >> (PAGE_SHIFT - 12))
 
 
 static int mmap_is_legacy(struct rlimit *rlim_stack)
 static int mmap_is_legacy(struct rlimit *rlim_stack)
 {
 {
@@ -38,6 +39,15 @@ static int mmap_is_legacy(struct rlimit *rlim_stack)
 static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
 static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
 {
 {
 	unsigned long gap = rlim_stack->rlim_cur;
 	unsigned long gap = rlim_stack->rlim_cur;
+	unsigned long pad = stack_guard_gap;
+
+	/* Account for stack randomization if necessary */
+	if (current->flags & PF_RANDOMIZE)
+		pad += (STACK_RND_MASK << PAGE_SHIFT);
+
+	/* Values close to RLIM_INFINITY can overflow. */
+	if (gap + pad > gap)
+		gap += pad;
 
 
 	if (gap < MIN_GAP)
 	if (gap < MIN_GAP)
 		gap = MIN_GAP;
 		gap = MIN_GAP;

+ 1 - 1
arch/mips/mm/tlbex.c

@@ -630,7 +630,7 @@ static __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
 		return;
 		return;
 	}
 	}
 
 
-	if (cpu_has_rixi && _PAGE_NO_EXEC) {
+	if (cpu_has_rixi && !!_PAGE_NO_EXEC) {
 		if (fill_includes_sw_bits) {
 		if (fill_includes_sw_bits) {
 			UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL));
 			UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL));
 		} else {
 		} else {

+ 2 - 2
arch/powerpc/include/asm/cputable.h

@@ -212,7 +212,7 @@ static inline void cpu_feature_keys_init(void) { }
 #define CPU_FTR_POWER9_DD2_1		LONG_ASM_CONST(0x0000080000000000)
 #define CPU_FTR_POWER9_DD2_1		LONG_ASM_CONST(0x0000080000000000)
 #define CPU_FTR_P9_TM_HV_ASSIST		LONG_ASM_CONST(0x0000100000000000)
 #define CPU_FTR_P9_TM_HV_ASSIST		LONG_ASM_CONST(0x0000100000000000)
 #define CPU_FTR_P9_TM_XER_SO_BUG	LONG_ASM_CONST(0x0000200000000000)
 #define CPU_FTR_P9_TM_XER_SO_BUG	LONG_ASM_CONST(0x0000200000000000)
-#define CPU_FTR_P9_TLBIE_BUG		LONG_ASM_CONST(0x0000400000000000)
+#define CPU_FTR_P9_TLBIE_STQ_BUG	LONG_ASM_CONST(0x0000400000000000)
 #define CPU_FTR_P9_TIDR			LONG_ASM_CONST(0x0000800000000000)
 #define CPU_FTR_P9_TIDR			LONG_ASM_CONST(0x0000800000000000)
 
 
 #ifndef __ASSEMBLY__
 #ifndef __ASSEMBLY__
@@ -460,7 +460,7 @@ static inline void cpu_feature_keys_init(void) { }
 	    CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
 	    CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
 	    CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
 	    CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
 	    CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_PKEY | \
 	    CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_PKEY | \
-	    CPU_FTR_P9_TLBIE_BUG | CPU_FTR_P9_TIDR)
+	    CPU_FTR_P9_TLBIE_STQ_BUG | CPU_FTR_P9_TIDR)
 #define CPU_FTRS_POWER9_DD2_0 CPU_FTRS_POWER9
 #define CPU_FTRS_POWER9_DD2_0 CPU_FTRS_POWER9
 #define CPU_FTRS_POWER9_DD2_1 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1)
 #define CPU_FTRS_POWER9_DD2_1 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1)
 #define CPU_FTRS_POWER9_DD2_2 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1 | \
 #define CPU_FTRS_POWER9_DD2_2 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1 | \

+ 1 - 2
arch/powerpc/include/asm/futex.h

@@ -59,8 +59,7 @@ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
 
 
 	pagefault_enable();
 	pagefault_enable();
 
 
-	if (!ret)
-		*oval = oldval;
+	*oval = oldval;
 
 
 	return ret;
 	return ret;
 }
 }

+ 1 - 1
arch/powerpc/include/asm/opal.h

@@ -275,7 +275,7 @@ int64_t opal_xive_get_vp_info(uint64_t vp,
 int64_t opal_xive_set_vp_info(uint64_t vp,
 int64_t opal_xive_set_vp_info(uint64_t vp,
 			      uint64_t flags,
 			      uint64_t flags,
 			      uint64_t report_cl_pair);
 			      uint64_t report_cl_pair);
-int64_t opal_xive_allocate_irq(uint32_t chip_id);
+int64_t opal_xive_allocate_irq_raw(uint32_t chip_id);
 int64_t opal_xive_free_irq(uint32_t girq);
 int64_t opal_xive_free_irq(uint32_t girq);
 int64_t opal_xive_sync(uint32_t type, uint32_t id);
 int64_t opal_xive_sync(uint32_t type, uint32_t id);
 int64_t opal_xive_dump(uint32_t type, uint32_t id);
 int64_t opal_xive_dump(uint32_t type, uint32_t id);

+ 1 - 0
arch/powerpc/include/asm/uaccess.h

@@ -306,6 +306,7 @@ extern unsigned long __copy_tofrom_user(void __user *to,
 static inline unsigned long
 static inline unsigned long
 raw_copy_in_user(void __user *to, const void __user *from, unsigned long n)
 raw_copy_in_user(void __user *to, const void __user *from, unsigned long n)
 {
 {
+	barrier_nospec();
 	return __copy_tofrom_user(to, from, n);
 	return __copy_tofrom_user(to, from, n);
 }
 }
 #endif /* __powerpc64__ */
 #endif /* __powerpc64__ */

+ 28 - 2
arch/powerpc/kernel/dt_cpu_ftrs.c

@@ -694,9 +694,35 @@ static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f)
 	return true;
 	return true;
 }
 }
 
 
+/*
+ * Handle POWER9 broadcast tlbie invalidation issue using
+ * cpu feature flag.
+ */
+static __init void update_tlbie_feature_flag(unsigned long pvr)
+{
+	if (PVR_VER(pvr) == PVR_POWER9) {
+		/*
+		 * Set the tlbie feature flag for anything below
+		 * Nimbus DD 2.3 and Cumulus DD 1.3
+		 */
+		if ((pvr & 0xe000) == 0) {
+			/* Nimbus */
+			if ((pvr & 0xfff) < 0x203)
+				cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_STQ_BUG;
+		} else if ((pvr & 0xc000) == 0) {
+			/* Cumulus */
+			if ((pvr & 0xfff) < 0x103)
+				cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_STQ_BUG;
+		} else {
+			WARN_ONCE(1, "Unknown PVR");
+			cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_STQ_BUG;
+		}
+	}
+}
+
 static __init void cpufeatures_cpu_quirks(void)
 static __init void cpufeatures_cpu_quirks(void)
 {
 {
-	int version = mfspr(SPRN_PVR);
+	unsigned long version = mfspr(SPRN_PVR);
 
 
 	/*
 	/*
 	 * Not all quirks can be derived from the cpufeatures device tree.
 	 * Not all quirks can be derived from the cpufeatures device tree.
@@ -715,10 +741,10 @@ static __init void cpufeatures_cpu_quirks(void)
 
 
 	if ((version & 0xffff0000) == 0x004e0000) {
 	if ((version & 0xffff0000) == 0x004e0000) {
 		cur_cpu_spec->cpu_features &= ~(CPU_FTR_DAWR);
 		cur_cpu_spec->cpu_features &= ~(CPU_FTR_DAWR);
-		cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_BUG;
 		cur_cpu_spec->cpu_features |= CPU_FTR_P9_TIDR;
 		cur_cpu_spec->cpu_features |= CPU_FTR_P9_TIDR;
 	}
 	}
 
 
+	update_tlbie_feature_flag(version);
 	/*
 	/*
 	 * PKEY was not in the initial base or feature node
 	 * PKEY was not in the initial base or feature node
 	 * specification, but it should become optional in the next
 	 * specification, but it should become optional in the next

+ 10 - 1
arch/powerpc/kernel/eeh_driver.c

@@ -811,6 +811,10 @@ void eeh_handle_normal_event(struct eeh_pe *pe)
 	pr_warn("EEH: This PCI device has failed %d times in the last hour and will be permanently disabled after %d failures.\n",
 	pr_warn("EEH: This PCI device has failed %d times in the last hour and will be permanently disabled after %d failures.\n",
 		pe->freeze_count, eeh_max_freezes);
 		pe->freeze_count, eeh_max_freezes);
 
 
+	eeh_for_each_pe(pe, tmp_pe)
+		eeh_pe_for_each_dev(tmp_pe, edev, tmp)
+			edev->mode &= ~EEH_DEV_NO_HANDLER;
+
 	/* Walk the various device drivers attached to this slot through
 	/* Walk the various device drivers attached to this slot through
 	 * a reset sequence, giving each an opportunity to do what it needs
 	 * a reset sequence, giving each an opportunity to do what it needs
 	 * to accomplish the reset.  Each child gets a report of the
 	 * to accomplish the reset.  Each child gets a report of the
@@ -1004,7 +1008,8 @@ final:
  */
  */
 void eeh_handle_special_event(void)
 void eeh_handle_special_event(void)
 {
 {
-	struct eeh_pe *pe, *phb_pe;
+	struct eeh_pe *pe, *phb_pe, *tmp_pe;
+	struct eeh_dev *edev, *tmp_edev;
 	struct pci_bus *bus;
 	struct pci_bus *bus;
 	struct pci_controller *hose;
 	struct pci_controller *hose;
 	unsigned long flags;
 	unsigned long flags;
@@ -1075,6 +1080,10 @@ void eeh_handle_special_event(void)
 				    (phb_pe->state & EEH_PE_RECOVERING))
 				    (phb_pe->state & EEH_PE_RECOVERING))
 					continue;
 					continue;
 
 
+				eeh_for_each_pe(pe, tmp_pe)
+					eeh_pe_for_each_dev(tmp_pe, edev, tmp_edev)
+						edev->mode &= ~EEH_DEV_NO_HANDLER;
+
 				/* Notify all devices to be down */
 				/* Notify all devices to be down */
 				eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
 				eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
 				eeh_set_channel_state(pe, pci_channel_io_perm_failure);
 				eeh_set_channel_state(pe, pci_channel_io_perm_failure);

+ 4 - 0
arch/powerpc/kernel/exceptions-64s.S

@@ -520,6 +520,10 @@ EXC_COMMON_BEGIN(machine_check_handle_early)
 	RFI_TO_USER_OR_KERNEL
 	RFI_TO_USER_OR_KERNEL
 9:
 9:
 	/* Deliver the machine check to host kernel in V mode. */
 	/* Deliver the machine check to host kernel in V mode. */
+BEGIN_FTR_SECTION
+	ld	r10,ORIG_GPR3(r1)
+	mtspr	SPRN_CFAR,r10
+END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
 	MACHINE_CHECK_HANDLER_WINDUP
 	MACHINE_CHECK_HANDLER_WINDUP
 	b	machine_check_pSeries
 	b	machine_check_pSeries
 
 

+ 10 - 1
arch/powerpc/kernel/mce.c

@@ -45,6 +45,7 @@ static DEFINE_PER_CPU(struct machine_check_event[MAX_MC_EVT],
 					mce_ue_event_queue);
 					mce_ue_event_queue);
 
 
 static void machine_check_process_queued_event(struct irq_work *work);
 static void machine_check_process_queued_event(struct irq_work *work);
+static void machine_check_ue_irq_work(struct irq_work *work);
 void machine_check_ue_event(struct machine_check_event *evt);
 void machine_check_ue_event(struct machine_check_event *evt);
 static void machine_process_ue_event(struct work_struct *work);
 static void machine_process_ue_event(struct work_struct *work);
 
 
@@ -52,6 +53,10 @@ static struct irq_work mce_event_process_work = {
         .func = machine_check_process_queued_event,
         .func = machine_check_process_queued_event,
 };
 };
 
 
+static struct irq_work mce_ue_event_irq_work = {
+	.func = machine_check_ue_irq_work,
+};
+
 DECLARE_WORK(mce_ue_event_work, machine_process_ue_event);
 DECLARE_WORK(mce_ue_event_work, machine_process_ue_event);
 
 
 static void mce_set_error_info(struct machine_check_event *mce,
 static void mce_set_error_info(struct machine_check_event *mce,
@@ -208,6 +213,10 @@ void release_mce_event(void)
 	get_mce_event(NULL, true);
 	get_mce_event(NULL, true);
 }
 }
 
 
+static void machine_check_ue_irq_work(struct irq_work *work)
+{
+	schedule_work(&mce_ue_event_work);
+}
 
 
 /*
 /*
  * Queue up the MCE event which then can be handled later.
  * Queue up the MCE event which then can be handled later.
@@ -225,7 +234,7 @@ void machine_check_ue_event(struct machine_check_event *evt)
 	memcpy(this_cpu_ptr(&mce_ue_event_queue[index]), evt, sizeof(*evt));
 	memcpy(this_cpu_ptr(&mce_ue_event_queue[index]), evt, sizeof(*evt));
 
 
 	/* Queue work to process this event later. */
 	/* Queue work to process this event later. */
-	schedule_work(&mce_ue_event_work);
+	irq_work_queue(&mce_ue_event_irq_work);
 }
 }
 
 
 /*
 /*

+ 13 - 6
arch/powerpc/kernel/mce_power.c

@@ -39,6 +39,7 @@
 static unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr)
 static unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr)
 {
 {
 	pte_t *ptep;
 	pte_t *ptep;
+	unsigned int shift;
 	unsigned long flags;
 	unsigned long flags;
 	struct mm_struct *mm;
 	struct mm_struct *mm;
 
 
@@ -48,13 +49,18 @@ static unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr)
 		mm = &init_mm;
 		mm = &init_mm;
 
 
 	local_irq_save(flags);
 	local_irq_save(flags);
-	if (mm == current->mm)
-		ptep = find_current_mm_pte(mm->pgd, addr, NULL, NULL);
-	else
-		ptep = find_init_mm_pte(addr, NULL);
+	ptep = __find_linux_pte(mm->pgd, addr, NULL, &shift);
 	local_irq_restore(flags);
 	local_irq_restore(flags);
+
 	if (!ptep || pte_special(*ptep))
 	if (!ptep || pte_special(*ptep))
 		return ULONG_MAX;
 		return ULONG_MAX;
+
+	if (shift > PAGE_SHIFT) {
+		unsigned long rpnmask = (1ul << shift) - PAGE_SIZE;
+
+		return pte_pfn(__pte(pte_val(*ptep) | (addr & rpnmask)));
+	}
+
 	return pte_pfn(*ptep);
 	return pte_pfn(*ptep);
 }
 }
 
 
@@ -339,7 +345,7 @@ static const struct mce_derror_table mce_p9_derror_table[] = {
   MCE_INITIATOR_CPU,   MCE_SEV_ERROR_SYNC, },
   MCE_INITIATOR_CPU,   MCE_SEV_ERROR_SYNC, },
 { 0, false, 0, 0, 0, 0 } };
 { 0, false, 0, 0, 0, 0 } };
 
 
-static int mce_find_instr_ea_and_pfn(struct pt_regs *regs, uint64_t *addr,
+static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr,
 					uint64_t *phys_addr)
 					uint64_t *phys_addr)
 {
 {
 	/*
 	/*
@@ -530,7 +536,8 @@ static int mce_handle_derror(struct pt_regs *regs,
 			 * kernel/exception-64s.h
 			 * kernel/exception-64s.h
 			 */
 			 */
 			if (get_paca()->in_mce < MAX_MCE_DEPTH)
 			if (get_paca()->in_mce < MAX_MCE_DEPTH)
-				mce_find_instr_ea_and_pfn(regs, addr, phys_addr);
+				mce_find_instr_ea_and_phys(regs, addr,
+							   phys_addr);
 		}
 		}
 		found = 1;
 		found = 1;
 	}
 	}

+ 8 - 3
arch/powerpc/kernel/rtas.c

@@ -875,15 +875,17 @@ static int rtas_cpu_state_change_mask(enum rtas_cpu_state state,
 		return 0;
 		return 0;
 
 
 	for_each_cpu(cpu, cpus) {
 	for_each_cpu(cpu, cpus) {
+		struct device *dev = get_cpu_device(cpu);
+
 		switch (state) {
 		switch (state) {
 		case DOWN:
 		case DOWN:
-			cpuret = cpu_down(cpu);
+			cpuret = device_offline(dev);
 			break;
 			break;
 		case UP:
 		case UP:
-			cpuret = cpu_up(cpu);
+			cpuret = device_online(dev);
 			break;
 			break;
 		}
 		}
-		if (cpuret) {
+		if (cpuret < 0) {
 			pr_debug("%s: cpu_%s for cpu#%d returned %d.\n",
 			pr_debug("%s: cpu_%s for cpu#%d returned %d.\n",
 					__func__,
 					__func__,
 					((state == UP) ? "up" : "down"),
 					((state == UP) ? "up" : "down"),
@@ -972,6 +974,8 @@ int rtas_ibm_suspend_me(u64 handle)
 	data.token = rtas_token("ibm,suspend-me");
 	data.token = rtas_token("ibm,suspend-me");
 	data.complete = &done;
 	data.complete = &done;
 
 
+	lock_device_hotplug();
+
 	/* All present CPUs must be online */
 	/* All present CPUs must be online */
 	cpumask_andnot(offline_mask, cpu_present_mask, cpu_online_mask);
 	cpumask_andnot(offline_mask, cpu_present_mask, cpu_online_mask);
 	cpuret = rtas_online_cpus_mask(offline_mask);
 	cpuret = rtas_online_cpus_mask(offline_mask);
@@ -1003,6 +1007,7 @@ int rtas_ibm_suspend_me(u64 handle)
 				__func__);
 				__func__);
 
 
 out:
 out:
+	unlock_device_hotplug();
 	free_cpumask_var(offline_mask);
 	free_cpumask_var(offline_mask);
 	return atomic_read(&data.error);
 	return atomic_read(&data.error);
 }
 }

+ 1 - 0
arch/powerpc/kernel/traps.c

@@ -399,6 +399,7 @@ void system_reset_exception(struct pt_regs *regs)
 	if (debugger(regs))
 	if (debugger(regs))
 		goto out;
 		goto out;
 
 
+	kmsg_dump(KMSG_DUMP_OOPS);
 	/*
 	/*
 	 * A system reset is a request to dump, so we always send
 	 * A system reset is a request to dump, so we always send
 	 * it through the crashdump code (if fadump or kdump are
 	 * it through the crashdump code (if fadump or kdump are

+ 18 - 6
arch/powerpc/kvm/book3s_hv.c

@@ -1407,7 +1407,14 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
 		*val = get_reg_val(id, vcpu->arch.pspb);
 		*val = get_reg_val(id, vcpu->arch.pspb);
 		break;
 		break;
 	case KVM_REG_PPC_DPDES:
 	case KVM_REG_PPC_DPDES:
-		*val = get_reg_val(id, vcpu->arch.vcore->dpdes);
+		/*
+		 * On POWER9, where we are emulating msgsndp etc.,
+		 * we return 1 bit for each vcpu, which can come from
+		 * either vcore->dpdes or doorbell_request.
+		 * On POWER8, doorbell_request is 0.
+		 */
+		*val = get_reg_val(id, vcpu->arch.vcore->dpdes |
+				   vcpu->arch.doorbell_request);
 		break;
 		break;
 	case KVM_REG_PPC_VTB:
 	case KVM_REG_PPC_VTB:
 		*val = get_reg_val(id, vcpu->arch.vcore->vtb);
 		*val = get_reg_val(id, vcpu->arch.vcore->vtb);
@@ -2550,7 +2557,7 @@ static void collect_piggybacks(struct core_info *cip, int target_threads)
 		if (!spin_trylock(&pvc->lock))
 		if (!spin_trylock(&pvc->lock))
 			continue;
 			continue;
 		prepare_threads(pvc);
 		prepare_threads(pvc);
-		if (!pvc->n_runnable) {
+		if (!pvc->n_runnable || !pvc->kvm->arch.mmu_ready) {
 			list_del_init(&pvc->preempt_list);
 			list_del_init(&pvc->preempt_list);
 			if (pvc->runner == NULL) {
 			if (pvc->runner == NULL) {
 				pvc->vcore_state = VCORE_INACTIVE;
 				pvc->vcore_state = VCORE_INACTIVE;
@@ -2571,15 +2578,20 @@ static void collect_piggybacks(struct core_info *cip, int target_threads)
 	spin_unlock(&lp->lock);
 	spin_unlock(&lp->lock);
 }
 }
 
 
-static bool recheck_signals(struct core_info *cip)
+static bool recheck_signals_and_mmu(struct core_info *cip)
 {
 {
 	int sub, i;
 	int sub, i;
 	struct kvm_vcpu *vcpu;
 	struct kvm_vcpu *vcpu;
+	struct kvmppc_vcore *vc;
 
 
-	for (sub = 0; sub < cip->n_subcores; ++sub)
-		for_each_runnable_thread(i, vcpu, cip->vc[sub])
+	for (sub = 0; sub < cip->n_subcores; ++sub) {
+		vc = cip->vc[sub];
+		if (!vc->kvm->arch.mmu_ready)
+			return true;
+		for_each_runnable_thread(i, vcpu, vc)
 			if (signal_pending(vcpu->arch.run_task))
 			if (signal_pending(vcpu->arch.run_task))
 				return true;
 				return true;
+	}
 	return false;
 	return false;
 }
 }
 
 
@@ -2800,7 +2812,7 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)
 	local_irq_disable();
 	local_irq_disable();
 	hard_irq_disable();
 	hard_irq_disable();
 	if (lazy_irq_pending() || need_resched() ||
 	if (lazy_irq_pending() || need_resched() ||
-	    recheck_signals(&core_info) || !vc->kvm->arch.mmu_ready) {
+	    recheck_signals_and_mmu(&core_info)) {
 		local_irq_enable();
 		local_irq_enable();
 		vc->vcore_state = VCORE_INACTIVE;
 		vc->vcore_state = VCORE_INACTIVE;
 		/* Unlock all except the primary vcore */
 		/* Unlock all except the primary vcore */

+ 1 - 1
arch/powerpc/kvm/book3s_hv_rm_mmu.c

@@ -452,7 +452,7 @@ static void do_tlbies(struct kvm *kvm, unsigned long *rbvalues,
 				     "r" (rbvalues[i]), "r" (kvm->arch.lpid));
 				     "r" (rbvalues[i]), "r" (kvm->arch.lpid));
 		}
 		}
 
 
-		if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG)) {
+		if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
 			/*
 			/*
 			 * Need the extra ptesync to make sure we don't
 			 * Need the extra ptesync to make sure we don't
 			 * re-order the tlbie
 			 * re-order the tlbie

+ 23 - 13
arch/powerpc/kvm/book3s_hv_rmhandlers.S

@@ -2903,29 +2903,39 @@ kvm_cede_prodded:
 kvm_cede_exit:
 kvm_cede_exit:
 	ld	r9, HSTATE_KVM_VCPU(r13)
 	ld	r9, HSTATE_KVM_VCPU(r13)
 #ifdef CONFIG_KVM_XICS
 #ifdef CONFIG_KVM_XICS
-	/* Abort if we still have a pending escalation */
+	/* are we using XIVE with single escalation? */
+	ld	r10, VCPU_XIVE_ESC_VADDR(r9)
+	cmpdi	r10, 0
+	beq	3f
+	li	r6, XIVE_ESB_SET_PQ_00
+	/*
+	 * If we still have a pending escalation, abort the cede,
+	 * and we must set PQ to 10 rather than 00 so that we don't
+	 * potentially end up with two entries for the escalation
+	 * interrupt in the XIVE interrupt queue.  In that case
+	 * we also don't want to set xive_esc_on to 1 here in
+	 * case we race with xive_esc_irq().
+	 */
 	lbz	r5, VCPU_XIVE_ESC_ON(r9)
 	lbz	r5, VCPU_XIVE_ESC_ON(r9)
 	cmpwi	r5, 0
 	cmpwi	r5, 0
-	beq	1f
+	beq	4f
 	li	r0, 0
 	li	r0, 0
 	stb	r0, VCPU_CEDED(r9)
 	stb	r0, VCPU_CEDED(r9)
-1:	/* Enable XIVE escalation */
-	li	r5, XIVE_ESB_SET_PQ_00
+	li	r6, XIVE_ESB_SET_PQ_10
+	b	5f
+4:	li	r0, 1
+	stb	r0, VCPU_XIVE_ESC_ON(r9)
+	/* make sure store to xive_esc_on is seen before xive_esc_irq runs */
+	sync
+5:	/* Enable XIVE escalation */
 	mfmsr	r0
 	mfmsr	r0
 	andi.	r0, r0, MSR_DR		/* in real mode? */
 	andi.	r0, r0, MSR_DR		/* in real mode? */
 	beq	1f
 	beq	1f
-	ld	r10, VCPU_XIVE_ESC_VADDR(r9)
-	cmpdi	r10, 0
-	beq	3f
-	ldx	r0, r10, r5
+	ldx	r0, r10, r6
 	b	2f
 	b	2f
 1:	ld	r10, VCPU_XIVE_ESC_RADDR(r9)
 1:	ld	r10, VCPU_XIVE_ESC_RADDR(r9)
-	cmpdi	r10, 0
-	beq	3f
-	ldcix	r0, r10, r5
+	ldcix	r0, r10, r6
 2:	sync
 2:	sync
-	li	r0, 1
-	stb	r0, VCPU_XIVE_ESC_ON(r9)
 #endif /* CONFIG_KVM_XICS */
 #endif /* CONFIG_KVM_XICS */
 3:	b	guest_exit_cont
 3:	b	guest_exit_cont
 
 

+ 10 - 8
arch/powerpc/kvm/book3s_xive.c

@@ -1037,20 +1037,22 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)
 	/* Mask the VP IPI */
 	/* Mask the VP IPI */
 	xive_vm_esb_load(&xc->vp_ipi_data, XIVE_ESB_SET_PQ_01);
 	xive_vm_esb_load(&xc->vp_ipi_data, XIVE_ESB_SET_PQ_01);
 
 
-	/* Disable the VP */
-	xive_native_disable_vp(xc->vp_id);
-
-	/* Free the queues & associated interrupts */
+	/* Free escalations */
 	for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
 	for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
-		struct xive_q *q = &xc->queues[i];
-
-		/* Free the escalation irq */
 		if (xc->esc_virq[i]) {
 		if (xc->esc_virq[i]) {
 			free_irq(xc->esc_virq[i], vcpu);
 			free_irq(xc->esc_virq[i], vcpu);
 			irq_dispose_mapping(xc->esc_virq[i]);
 			irq_dispose_mapping(xc->esc_virq[i]);
 			kfree(xc->esc_virq_names[i]);
 			kfree(xc->esc_virq_names[i]);
 		}
 		}
-		/* Free the queue */
+	}
+
+	/* Disable the VP */
+	xive_native_disable_vp(xc->vp_id);
+
+	/* Free the queues */
+	for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
+		struct xive_q *q = &xc->queues[i];
+
 		xive_native_disable_queue(xc->vp_id, q, i);
 		xive_native_disable_queue(xc->vp_id, q, i);
 		if (q->qpage) {
 		if (q->qpage) {
 			free_pages((unsigned long)q->qpage,
 			free_pages((unsigned long)q->qpage,

+ 1 - 1
arch/powerpc/mm/hash_native_64.c

@@ -203,7 +203,7 @@ static inline unsigned long  ___tlbie(unsigned long vpn, int psize,
 
 
 static inline void fixup_tlbie(unsigned long vpn, int psize, int apsize, int ssize)
 static inline void fixup_tlbie(unsigned long vpn, int psize, int apsize, int ssize)
 {
 {
-	if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG)) {
+	if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
 		/* Need the extra ptesync to ensure we don't reorder tlbie*/
 		/* Need the extra ptesync to ensure we don't reorder tlbie*/
 		asm volatile("ptesync": : :"memory");
 		asm volatile("ptesync": : :"memory");
 		___tlbie(vpn, psize, apsize, ssize);
 		___tlbie(vpn, psize, apsize, ssize);

+ 8 - 1
arch/powerpc/mm/hash_utils_64.c

@@ -37,6 +37,7 @@
 #include <linux/context_tracking.h>
 #include <linux/context_tracking.h>
 #include <linux/libfdt.h>
 #include <linux/libfdt.h>
 #include <linux/pkeys.h>
 #include <linux/pkeys.h>
+#include <linux/cpu.h>
 
 
 #include <asm/debugfs.h>
 #include <asm/debugfs.h>
 #include <asm/processor.h>
 #include <asm/processor.h>
@@ -1891,10 +1892,16 @@ static int hpt_order_get(void *data, u64 *val)
 
 
 static int hpt_order_set(void *data, u64 val)
 static int hpt_order_set(void *data, u64 val)
 {
 {
+	int ret;
+
 	if (!mmu_hash_ops.resize_hpt)
 	if (!mmu_hash_ops.resize_hpt)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	return mmu_hash_ops.resize_hpt(val);
+	cpus_read_lock();
+	ret = mmu_hash_ops.resize_hpt(val);
+	cpus_read_unlock();
+
+	return ret;
 }
 }
 
 
 DEFINE_SIMPLE_ATTRIBUTE(fops_hpt_order, hpt_order_get, hpt_order_set, "%llu\n");
 DEFINE_SIMPLE_ATTRIBUTE(fops_hpt_order, hpt_order_get, hpt_order_set, "%llu\n");

+ 7 - 9
arch/powerpc/mm/pgtable-radix.c

@@ -521,14 +521,6 @@ void __init radix__early_init_devtree(void)
 	mmu_psize_defs[MMU_PAGE_64K].shift = 16;
 	mmu_psize_defs[MMU_PAGE_64K].shift = 16;
 	mmu_psize_defs[MMU_PAGE_64K].ap = 0x5;
 	mmu_psize_defs[MMU_PAGE_64K].ap = 0x5;
 found:
 found:
-#ifdef CONFIG_SPARSEMEM_VMEMMAP
-	if (mmu_psize_defs[MMU_PAGE_2M].shift) {
-		/*
-		 * map vmemmap using 2M if available
-		 */
-		mmu_vmemmap_psize = MMU_PAGE_2M;
-	}
-#endif /* CONFIG_SPARSEMEM_VMEMMAP */
 	return;
 	return;
 }
 }
 
 
@@ -567,7 +559,13 @@ void __init radix__early_init_mmu(void)
 
 
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 	/* vmemmap mapping */
 	/* vmemmap mapping */
-	mmu_vmemmap_psize = mmu_virtual_psize;
+	if (mmu_psize_defs[MMU_PAGE_2M].shift) {
+		/*
+		 * map vmemmap using 2M if available
+		 */
+		mmu_vmemmap_psize = MMU_PAGE_2M;
+	} else
+		mmu_vmemmap_psize = mmu_virtual_psize;
 #endif
 #endif
 	/*
 	/*
 	 * initialize page table size
 	 * initialize page table size

+ 2 - 2
arch/powerpc/mm/tlb-radix.c

@@ -220,7 +220,7 @@ static inline void fixup_tlbie(void)
 	unsigned long pid = 0;
 	unsigned long pid = 0;
 	unsigned long va = ((1UL << 52) - 1);
 	unsigned long va = ((1UL << 52) - 1);
 
 
-	if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG)) {
+	if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
 		asm volatile("ptesync": : :"memory");
 		asm volatile("ptesync": : :"memory");
 		__tlbie_va(va, pid, mmu_get_ap(MMU_PAGE_64K), RIC_FLUSH_TLB);
 		__tlbie_va(va, pid, mmu_get_ap(MMU_PAGE_64K), RIC_FLUSH_TLB);
 	}
 	}
@@ -230,7 +230,7 @@ static inline void fixup_tlbie_lpid(unsigned long lpid)
 {
 {
 	unsigned long va = ((1UL << 52) - 1);
 	unsigned long va = ((1UL << 52) - 1);
 
 
-	if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG)) {
+	if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) {
 		asm volatile("ptesync": : :"memory");
 		asm volatile("ptesync": : :"memory");
 		__tlbie_lpid_va(va, lpid, mmu_get_ap(MMU_PAGE_64K), RIC_FLUSH_TLB);
 		__tlbie_lpid_va(va, lpid, mmu_get_ap(MMU_PAGE_64K), RIC_FLUSH_TLB);
 	}
 	}

+ 6 - 6
arch/powerpc/platforms/powernv/opal-imc.c

@@ -57,9 +57,9 @@ static void export_imc_mode_and_cmd(struct device_node *node,
 				    struct imc_pmu *pmu_ptr)
 				    struct imc_pmu *pmu_ptr)
 {
 {
 	static u64 loc, *imc_mode_addr, *imc_cmd_addr;
 	static u64 loc, *imc_mode_addr, *imc_cmd_addr;
-	int chip = 0, nid;
 	char mode[16], cmd[16];
 	char mode[16], cmd[16];
 	u32 cb_offset;
 	u32 cb_offset;
+	struct imc_mem_info *ptr = pmu_ptr->mem_info;
 
 
 	imc_debugfs_parent = debugfs_create_dir("imc", powerpc_debugfs_root);
 	imc_debugfs_parent = debugfs_create_dir("imc", powerpc_debugfs_root);
 
 
@@ -73,20 +73,20 @@ static void export_imc_mode_and_cmd(struct device_node *node,
 	if (of_property_read_u32(node, "cb_offset", &cb_offset))
 	if (of_property_read_u32(node, "cb_offset", &cb_offset))
 		cb_offset = IMC_CNTL_BLK_OFFSET;
 		cb_offset = IMC_CNTL_BLK_OFFSET;
 
 
-	for_each_node(nid) {
-		loc = (u64)(pmu_ptr->mem_info[chip].vbase) + cb_offset;
+	while (ptr->vbase != NULL) {
+		loc = (u64)(ptr->vbase) + cb_offset;
 		imc_mode_addr = (u64 *)(loc + IMC_CNTL_BLK_MODE_OFFSET);
 		imc_mode_addr = (u64 *)(loc + IMC_CNTL_BLK_MODE_OFFSET);
-		sprintf(mode, "imc_mode_%d", nid);
+		sprintf(mode, "imc_mode_%d", (u32)(ptr->id));
 		if (!imc_debugfs_create_x64(mode, 0600, imc_debugfs_parent,
 		if (!imc_debugfs_create_x64(mode, 0600, imc_debugfs_parent,
 					    imc_mode_addr))
 					    imc_mode_addr))
 			goto err;
 			goto err;
 
 
 		imc_cmd_addr = (u64 *)(loc + IMC_CNTL_BLK_CMD_OFFSET);
 		imc_cmd_addr = (u64 *)(loc + IMC_CNTL_BLK_CMD_OFFSET);
-		sprintf(cmd, "imc_cmd_%d", nid);
+		sprintf(cmd, "imc_cmd_%d", (u32)(ptr->id));
 		if (!imc_debugfs_create_x64(cmd, 0600, imc_debugfs_parent,
 		if (!imc_debugfs_create_x64(cmd, 0600, imc_debugfs_parent,
 					    imc_cmd_addr))
 					    imc_cmd_addr))
 			goto err;
 			goto err;
-		chip++;
+		ptr++;
 	}
 	}
 	return;
 	return;
 
 

+ 1 - 1
arch/powerpc/platforms/powernv/opal-wrappers.S

@@ -303,7 +303,7 @@ OPAL_CALL(opal_xive_set_queue_info,		OPAL_XIVE_SET_QUEUE_INFO);
 OPAL_CALL(opal_xive_donate_page,		OPAL_XIVE_DONATE_PAGE);
 OPAL_CALL(opal_xive_donate_page,		OPAL_XIVE_DONATE_PAGE);
 OPAL_CALL(opal_xive_alloc_vp_block,		OPAL_XIVE_ALLOCATE_VP_BLOCK);
 OPAL_CALL(opal_xive_alloc_vp_block,		OPAL_XIVE_ALLOCATE_VP_BLOCK);
 OPAL_CALL(opal_xive_free_vp_block,		OPAL_XIVE_FREE_VP_BLOCK);
 OPAL_CALL(opal_xive_free_vp_block,		OPAL_XIVE_FREE_VP_BLOCK);
-OPAL_CALL(opal_xive_allocate_irq,		OPAL_XIVE_ALLOCATE_IRQ);
+OPAL_CALL(opal_xive_allocate_irq_raw,		OPAL_XIVE_ALLOCATE_IRQ);
 OPAL_CALL(opal_xive_free_irq,			OPAL_XIVE_FREE_IRQ);
 OPAL_CALL(opal_xive_free_irq,			OPAL_XIVE_FREE_IRQ);
 OPAL_CALL(opal_xive_get_vp_info,		OPAL_XIVE_GET_VP_INFO);
 OPAL_CALL(opal_xive_get_vp_info,		OPAL_XIVE_GET_VP_INFO);
 OPAL_CALL(opal_xive_set_vp_info,		OPAL_XIVE_SET_VP_INFO);
 OPAL_CALL(opal_xive_set_vp_info,		OPAL_XIVE_SET_VP_INFO);

+ 7 - 4
arch/powerpc/platforms/powernv/opal.c

@@ -680,7 +680,10 @@ static ssize_t symbol_map_read(struct file *fp, struct kobject *kobj,
 				       bin_attr->size);
 				       bin_attr->size);
 }
 }
 
 
-static BIN_ATTR_RO(symbol_map, 0);
+static struct bin_attribute symbol_map_attr = {
+	.attr = {.name = "symbol_map", .mode = 0400},
+	.read = symbol_map_read
+};
 
 
 static void opal_export_symmap(void)
 static void opal_export_symmap(void)
 {
 {
@@ -697,10 +700,10 @@ static void opal_export_symmap(void)
 		return;
 		return;
 
 
 	/* Setup attributes */
 	/* Setup attributes */
-	bin_attr_symbol_map.private = __va(be64_to_cpu(syms[0]));
-	bin_attr_symbol_map.size = be64_to_cpu(syms[1]);
+	symbol_map_attr.private = __va(be64_to_cpu(syms[0]));
+	symbol_map_attr.size = be64_to_cpu(syms[1]);
 
 
-	rc = sysfs_create_bin_file(opal_kobj, &bin_attr_symbol_map);
+	rc = sysfs_create_bin_file(opal_kobj, &symbol_map_attr);
 	if (rc)
 	if (rc)
 		pr_warn("Error %d creating OPAL symbols file\n", rc);
 		pr_warn("Error %d creating OPAL symbols file\n", rc);
 }
 }

+ 23 - 15
arch/powerpc/platforms/powernv/pci-ioda-tce.c

@@ -36,7 +36,8 @@ static __be64 *pnv_alloc_tce_level(int nid, unsigned int shift)
 	struct page *tce_mem = NULL;
 	struct page *tce_mem = NULL;
 	__be64 *addr;
 	__be64 *addr;
 
 
-	tce_mem = alloc_pages_node(nid, GFP_KERNEL, shift - PAGE_SHIFT);
+	tce_mem = alloc_pages_node(nid, GFP_ATOMIC | __GFP_NOWARN,
+			shift - PAGE_SHIFT);
 	if (!tce_mem) {
 	if (!tce_mem) {
 		pr_err("Failed to allocate a TCE memory, level shift=%d\n",
 		pr_err("Failed to allocate a TCE memory, level shift=%d\n",
 				shift);
 				shift);
@@ -48,6 +49,9 @@ static __be64 *pnv_alloc_tce_level(int nid, unsigned int shift)
 	return addr;
 	return addr;
 }
 }
 
 
+static void pnv_pci_ioda2_table_do_free_pages(__be64 *addr,
+		unsigned long size, unsigned int levels);
+
 static __be64 *pnv_tce(struct iommu_table *tbl, bool user, long idx, bool alloc)
 static __be64 *pnv_tce(struct iommu_table *tbl, bool user, long idx, bool alloc)
 {
 {
 	__be64 *tmp = user ? tbl->it_userspace : (__be64 *) tbl->it_base;
 	__be64 *tmp = user ? tbl->it_userspace : (__be64 *) tbl->it_base;
@@ -57,9 +61,9 @@ static __be64 *pnv_tce(struct iommu_table *tbl, bool user, long idx, bool alloc)
 
 
 	while (level) {
 	while (level) {
 		int n = (idx & mask) >> (level * shift);
 		int n = (idx & mask) >> (level * shift);
-		unsigned long tce;
+		unsigned long oldtce, tce = be64_to_cpu(READ_ONCE(tmp[n]));
 
 
-		if (tmp[n] == 0) {
+		if (!tce) {
 			__be64 *tmp2;
 			__be64 *tmp2;
 
 
 			if (!alloc)
 			if (!alloc)
@@ -70,10 +74,15 @@ static __be64 *pnv_tce(struct iommu_table *tbl, bool user, long idx, bool alloc)
 			if (!tmp2)
 			if (!tmp2)
 				return NULL;
 				return NULL;
 
 
-			tmp[n] = cpu_to_be64(__pa(tmp2) |
-					TCE_PCI_READ | TCE_PCI_WRITE);
+			tce = __pa(tmp2) | TCE_PCI_READ | TCE_PCI_WRITE;
+			oldtce = be64_to_cpu(cmpxchg(&tmp[n], 0,
+					cpu_to_be64(tce)));
+			if (oldtce) {
+				pnv_pci_ioda2_table_do_free_pages(tmp2,
+					ilog2(tbl->it_level_size) + 3, 1);
+				tce = oldtce;
+			}
 		}
 		}
-		tce = be64_to_cpu(tmp[n]);
 
 
 		tmp = __va(tce & ~(TCE_PCI_READ | TCE_PCI_WRITE));
 		tmp = __va(tce & ~(TCE_PCI_READ | TCE_PCI_WRITE));
 		idx &= ~mask;
 		idx &= ~mask;
@@ -161,6 +170,9 @@ void pnv_tce_free(struct iommu_table *tbl, long index, long npages)
 
 
 		if (ptce)
 		if (ptce)
 			*ptce = cpu_to_be64(0);
 			*ptce = cpu_to_be64(0);
+		else
+			/* Skip the rest of the level */
+			i |= tbl->it_level_size - 1;
 	}
 	}
 }
 }
 
 
@@ -260,7 +272,6 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
 	unsigned int table_shift = max_t(unsigned int, entries_shift + 3,
 	unsigned int table_shift = max_t(unsigned int, entries_shift + 3,
 			PAGE_SHIFT);
 			PAGE_SHIFT);
 	const unsigned long tce_table_size = 1UL << table_shift;
 	const unsigned long tce_table_size = 1UL << table_shift;
-	unsigned int tmplevels = levels;
 
 
 	if (!levels || (levels > POWERNV_IOMMU_MAX_LEVELS))
 	if (!levels || (levels > POWERNV_IOMMU_MAX_LEVELS))
 		return -EINVAL;
 		return -EINVAL;
@@ -268,9 +279,6 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
 	if (!is_power_of_2(window_size))
 	if (!is_power_of_2(window_size))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (alloc_userspace_copy && (window_size > (1ULL << 32)))
-		tmplevels = 1;
-
 	/* Adjust direct table size from window_size and levels */
 	/* Adjust direct table size from window_size and levels */
 	entries_shift = (entries_shift + levels - 1) / levels;
 	entries_shift = (entries_shift + levels - 1) / levels;
 	level_shift = entries_shift + 3;
 	level_shift = entries_shift + 3;
@@ -281,7 +289,7 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
 
 
 	/* Allocate TCE table */
 	/* Allocate TCE table */
 	addr = pnv_pci_ioda2_table_do_alloc_pages(nid, level_shift,
 	addr = pnv_pci_ioda2_table_do_alloc_pages(nid, level_shift,
-			tmplevels, tce_table_size, &offset, &total_allocated);
+			1, tce_table_size, &offset, &total_allocated);
 
 
 	/* addr==NULL means that the first level allocation failed */
 	/* addr==NULL means that the first level allocation failed */
 	if (!addr)
 	if (!addr)
@@ -292,18 +300,18 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
 	 * we did not allocate as much as we wanted,
 	 * we did not allocate as much as we wanted,
 	 * release partially allocated table.
 	 * release partially allocated table.
 	 */
 	 */
-	if (tmplevels == levels && offset < tce_table_size)
+	if (levels == 1 && offset < tce_table_size)
 		goto free_tces_exit;
 		goto free_tces_exit;
 
 
 	/* Allocate userspace view of the TCE table */
 	/* Allocate userspace view of the TCE table */
 	if (alloc_userspace_copy) {
 	if (alloc_userspace_copy) {
 		offset = 0;
 		offset = 0;
 		uas = pnv_pci_ioda2_table_do_alloc_pages(nid, level_shift,
 		uas = pnv_pci_ioda2_table_do_alloc_pages(nid, level_shift,
-				tmplevels, tce_table_size, &offset,
+				1, tce_table_size, &offset,
 				&total_allocated_uas);
 				&total_allocated_uas);
 		if (!uas)
 		if (!uas)
 			goto free_tces_exit;
 			goto free_tces_exit;
-		if (tmplevels == levels && (offset < tce_table_size ||
+		if (levels == 1 && (offset < tce_table_size ||
 				total_allocated_uas != total_allocated))
 				total_allocated_uas != total_allocated))
 			goto free_uas_exit;
 			goto free_uas_exit;
 	}
 	}
@@ -318,7 +326,7 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
 
 
 	pr_debug("Created TCE table: ws=%08llx ts=%lx @%08llx base=%lx uas=%p levels=%d/%d\n",
 	pr_debug("Created TCE table: ws=%08llx ts=%lx @%08llx base=%lx uas=%p levels=%d/%d\n",
 			window_size, tce_table_size, bus_offset, tbl->it_base,
 			window_size, tce_table_size, bus_offset, tbl->it_base,
-			tbl->it_userspace, tmplevels, levels);
+			tbl->it_userspace, 1, levels);
 
 
 	return 0;
 	return 0;
 
 

+ 1 - 1
arch/powerpc/platforms/powernv/pci.h

@@ -243,7 +243,7 @@ extern void pnv_npu_release_ownership(struct pnv_ioda_pe *npe);
 extern int pnv_npu2_init(struct pnv_phb *phb);
 extern int pnv_npu2_init(struct pnv_phb *phb);
 
 
 /* pci-ioda-tce.c */
 /* pci-ioda-tce.c */
-#define POWERNV_IOMMU_DEFAULT_LEVELS	1
+#define POWERNV_IOMMU_DEFAULT_LEVELS	2
 #define POWERNV_IOMMU_MAX_LEVELS	5
 #define POWERNV_IOMMU_MAX_LEVELS	5
 
 
 extern int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
 extern int pnv_tce_build(struct iommu_table *tbl, long index, long npages,

+ 6 - 2
arch/powerpc/platforms/pseries/lpar.c

@@ -647,7 +647,10 @@ static int pseries_lpar_resize_hpt_commit(void *data)
 	return 0;
 	return 0;
 }
 }
 
 
-/* Must be called in user context */
+/*
+ * Must be called in process context. The caller must hold the
+ * cpus_lock.
+ */
 static int pseries_lpar_resize_hpt(unsigned long shift)
 static int pseries_lpar_resize_hpt(unsigned long shift)
 {
 {
 	struct hpt_resize_state state = {
 	struct hpt_resize_state state = {
@@ -699,7 +702,8 @@ static int pseries_lpar_resize_hpt(unsigned long shift)
 
 
 	t1 = ktime_get();
 	t1 = ktime_get();
 
 
-	rc = stop_machine(pseries_lpar_resize_hpt_commit, &state, NULL);
+	rc = stop_machine_cpuslocked(pseries_lpar_resize_hpt_commit,
+				     &state, NULL);
 
 
 	t2 = ktime_get();
 	t2 = ktime_get();
 
 

+ 9 - 0
arch/powerpc/platforms/pseries/mobility.c

@@ -12,6 +12,7 @@
 #include <linux/cpu.h>
 #include <linux/cpu.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/kobject.h>
 #include <linux/kobject.h>
+#include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/smp.h>
 #include <linux/stat.h>
 #include <linux/stat.h>
 #include <linux/completion.h>
 #include <linux/completion.h>
@@ -209,7 +210,11 @@ static int update_dt_node(__be32 phandle, s32 scope)
 
 
 				prop_data += vd;
 				prop_data += vd;
 			}
 			}
+
+			cond_resched();
 		}
 		}
+
+		cond_resched();
 	} while (rtas_rc == 1);
 	} while (rtas_rc == 1);
 
 
 	of_node_put(dn);
 	of_node_put(dn);
@@ -318,8 +323,12 @@ int pseries_devicetree_update(s32 scope)
 					add_dt_node(phandle, drc_index);
 					add_dt_node(phandle, drc_index);
 					break;
 					break;
 				}
 				}
+
+				cond_resched();
 			}
 			}
 		}
 		}
+
+		cond_resched();
 	} while (rc == 1);
 	} while (rc == 1);
 
 
 	kfree(rtas_buf);
 	kfree(rtas_buf);

+ 3 - 0
arch/powerpc/platforms/pseries/setup.c

@@ -325,6 +325,9 @@ static void pseries_lpar_idle(void)
 	 * low power mode by ceding processor to hypervisor
 	 * low power mode by ceding processor to hypervisor
 	 */
 	 */
 
 
+	if (!prep_irq_for_idle())
+		return;
+
 	/* Indicate to hypervisor that we are idle. */
 	/* Indicate to hypervisor that we are idle. */
 	get_lppaca()->idle = 1;
 	get_lppaca()->idle = 1;
 
 

+ 11 - 0
arch/powerpc/sysdev/xive/native.c

@@ -235,6 +235,17 @@ static bool xive_native_match(struct device_node *node)
 	return of_device_is_compatible(node, "ibm,opal-xive-vc");
 	return of_device_is_compatible(node, "ibm,opal-xive-vc");
 }
 }
 
 
+static s64 opal_xive_allocate_irq(u32 chip_id)
+{
+	s64 irq = opal_xive_allocate_irq_raw(chip_id);
+
+	/*
+	 * Old versions of skiboot can incorrectly return 0xffffffff to
+	 * indicate no space, fix it up here.
+	 */
+	return irq == 0xffffffff ? OPAL_RESOURCE : irq;
+}
+
 #ifdef CONFIG_SMP
 #ifdef CONFIG_SMP
 static int xive_native_get_ipi(unsigned int cpu, struct xive_cpu *xc)
 static int xive_native_get_ipi(unsigned int cpu, struct xive_cpu *xc)
 {
 {

+ 9 - 6
arch/powerpc/xmon/xmon.c

@@ -2497,13 +2497,16 @@ static void dump_pacas(void)
 static void dump_one_xive(int cpu)
 static void dump_one_xive(int cpu)
 {
 {
 	unsigned int hwid = get_hard_smp_processor_id(cpu);
 	unsigned int hwid = get_hard_smp_processor_id(cpu);
+	bool hv = cpu_has_feature(CPU_FTR_HVMODE);
 
 
-	opal_xive_dump(XIVE_DUMP_TM_HYP, hwid);
-	opal_xive_dump(XIVE_DUMP_TM_POOL, hwid);
-	opal_xive_dump(XIVE_DUMP_TM_OS, hwid);
-	opal_xive_dump(XIVE_DUMP_TM_USER, hwid);
-	opal_xive_dump(XIVE_DUMP_VP, hwid);
-	opal_xive_dump(XIVE_DUMP_EMU_STATE, hwid);
+	if (hv) {
+		opal_xive_dump(XIVE_DUMP_TM_HYP, hwid);
+		opal_xive_dump(XIVE_DUMP_TM_POOL, hwid);
+		opal_xive_dump(XIVE_DUMP_TM_OS, hwid);
+		opal_xive_dump(XIVE_DUMP_TM_USER, hwid);
+		opal_xive_dump(XIVE_DUMP_VP, hwid);
+		opal_xive_dump(XIVE_DUMP_EMU_STATE, hwid);
+	}
 
 
 	if (setjmp(bus_error_jmp) != 0) {
 	if (setjmp(bus_error_jmp) != 0) {
 		catch_memory_errors = 0;
 		catch_memory_errors = 0;

+ 5 - 1
arch/riscv/kernel/entry.S

@@ -171,9 +171,13 @@ ENTRY(handle_exception)
 	move a1, s4 /* scause */
 	move a1, s4 /* scause */
 	tail do_IRQ
 	tail do_IRQ
 1:
 1:
-	/* Exceptions run with interrupts enabled */
+	/* Exceptions run with interrupts enabled or disabled
+	   depending on the state of sstatus.SR_SPIE */
+	andi t0, s1, SR_SPIE
+	beqz t0, 1f
 	csrs sstatus, SR_SIE
 	csrs sstatus, SR_SIE
 
 
+1:
 	/* Handle syscalls */
 	/* Handle syscalls */
 	li t0, EXC_SYSCALL
 	li t0, EXC_SYSCALL
 	beq s4, t0, handle_syscall
 	beq s4, t0, handle_syscall

+ 6 - 0
arch/s390/crypto/aes_s390.c

@@ -585,6 +585,9 @@ static int xts_aes_encrypt(struct blkcipher_desc *desc,
 	struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm);
 	struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm);
 	struct blkcipher_walk walk;
 	struct blkcipher_walk walk;
 
 
+	if (!nbytes)
+		return -EINVAL;
+
 	if (unlikely(!xts_ctx->fc))
 	if (unlikely(!xts_ctx->fc))
 		return xts_fallback_encrypt(desc, dst, src, nbytes);
 		return xts_fallback_encrypt(desc, dst, src, nbytes);
 
 
@@ -599,6 +602,9 @@ static int xts_aes_decrypt(struct blkcipher_desc *desc,
 	struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm);
 	struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm);
 	struct blkcipher_walk walk;
 	struct blkcipher_walk walk;
 
 
+	if (!nbytes)
+		return -EINVAL;
+
 	if (unlikely(!xts_ctx->fc))
 	if (unlikely(!xts_ctx->fc))
 		return xts_fallback_decrypt(desc, dst, src, nbytes);
 		return xts_fallback_decrypt(desc, dst, src, nbytes);
 
 

+ 5 - 4
arch/s390/hypfs/inode.c

@@ -269,7 +269,7 @@ static int hypfs_show_options(struct seq_file *s, struct dentry *root)
 static int hypfs_fill_super(struct super_block *sb, void *data, int silent)
 static int hypfs_fill_super(struct super_block *sb, void *data, int silent)
 {
 {
 	struct inode *root_inode;
 	struct inode *root_inode;
-	struct dentry *root_dentry;
+	struct dentry *root_dentry, *update_file;
 	int rc = 0;
 	int rc = 0;
 	struct hypfs_sb_info *sbi;
 	struct hypfs_sb_info *sbi;
 
 
@@ -300,9 +300,10 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent)
 		rc = hypfs_diag_create_files(root_dentry);
 		rc = hypfs_diag_create_files(root_dentry);
 	if (rc)
 	if (rc)
 		return rc;
 		return rc;
-	sbi->update_file = hypfs_create_update_file(root_dentry);
-	if (IS_ERR(sbi->update_file))
-		return PTR_ERR(sbi->update_file);
+	update_file = hypfs_create_update_file(root_dentry);
+	if (IS_ERR(update_file))
+		return PTR_ERR(update_file);
+	sbi->update_file = update_file;
 	hypfs_update_update(sb);
 	hypfs_update_update(sb);
 	pr_info("Hypervisor filesystem mounted\n");
 	pr_info("Hypervisor filesystem mounted\n");
 	return 0;
 	return 0;

+ 16 - 6
arch/s390/kernel/process.c

@@ -183,20 +183,30 @@ unsigned long get_wchan(struct task_struct *p)
 
 
 	if (!p || p == current || p->state == TASK_RUNNING || !task_stack_page(p))
 	if (!p || p == current || p->state == TASK_RUNNING || !task_stack_page(p))
 		return 0;
 		return 0;
+
+	if (!try_get_task_stack(p))
+		return 0;
+
 	low = task_stack_page(p);
 	low = task_stack_page(p);
 	high = (struct stack_frame *) task_pt_regs(p);
 	high = (struct stack_frame *) task_pt_regs(p);
 	sf = (struct stack_frame *) p->thread.ksp;
 	sf = (struct stack_frame *) p->thread.ksp;
-	if (sf <= low || sf > high)
-		return 0;
+	if (sf <= low || sf > high) {
+		return_address = 0;
+		goto out;
+	}
 	for (count = 0; count < 16; count++) {
 	for (count = 0; count < 16; count++) {
 		sf = (struct stack_frame *) sf->back_chain;
 		sf = (struct stack_frame *) sf->back_chain;
-		if (sf <= low || sf > high)
-			return 0;
+		if (sf <= low || sf > high) {
+			return_address = 0;
+			goto out;
+		}
 		return_address = sf->gprs[8];
 		return_address = sf->gprs[8];
 		if (!in_sched_functions(return_address))
 		if (!in_sched_functions(return_address))
-			return return_address;
+			goto out;
 	}
 	}
-	return 0;
+out:
+	put_task_stack(p);
+	return return_address;
 }
 }
 
 
 unsigned long arch_align_stack(unsigned long sp)
 unsigned long arch_align_stack(unsigned long sp)

+ 2 - 1
arch/s390/kernel/topology.c

@@ -311,7 +311,8 @@ int arch_update_cpu_topology(void)
 	on_each_cpu(__arch_update_dedicated_flag, NULL, 0);
 	on_each_cpu(__arch_update_dedicated_flag, NULL, 0);
 	for_each_online_cpu(cpu) {
 	for_each_online_cpu(cpu) {
 		dev = get_cpu_device(cpu);
 		dev = get_cpu_device(cpu);
-		kobject_uevent(&dev->kobj, KOBJ_CHANGE);
+		if (dev)
+			kobject_uevent(&dev->kobj, KOBJ_CHANGE);
 	}
 	}
 	return rc;
 	return rc;
 }
 }

+ 10 - 0
arch/s390/kvm/interrupt.c

@@ -1879,6 +1879,16 @@ int s390int_to_s390irq(struct kvm_s390_interrupt *s390int,
 	case KVM_S390_MCHK:
 	case KVM_S390_MCHK:
 		irq->u.mchk.mcic = s390int->parm64;
 		irq->u.mchk.mcic = s390int->parm64;
 		break;
 		break;
+	case KVM_S390_INT_PFAULT_INIT:
+		irq->u.ext.ext_params = s390int->parm;
+		irq->u.ext.ext_params2 = s390int->parm64;
+		break;
+	case KVM_S390_RESTART:
+	case KVM_S390_INT_CLOCK_COMP:
+	case KVM_S390_INT_CPU_TIMER:
+		break;
+	default:
+		return -EINVAL;
 	}
 	}
 	return 0;
 	return 0;
 }
 }

+ 4 - 2
arch/s390/kvm/kvm-s390.c

@@ -928,6 +928,8 @@ static int kvm_s390_vm_start_migration(struct kvm *kvm)
 	/* mark all the pages in active slots as dirty */
 	/* mark all the pages in active slots as dirty */
 	for (slotnr = 0; slotnr < slots->used_slots; slotnr++) {
 	for (slotnr = 0; slotnr < slots->used_slots; slotnr++) {
 		ms = slots->memslots + slotnr;
 		ms = slots->memslots + slotnr;
+		if (!ms->dirty_bitmap)
+			return -EINVAL;
 		/*
 		/*
 		 * The second half of the bitmap is only used on x86,
 		 * The second half of the bitmap is only used on x86,
 		 * and would be wasted otherwise, so we put it to good
 		 * and would be wasted otherwise, so we put it to good
@@ -3888,7 +3890,7 @@ static long kvm_s390_guest_mem_op(struct kvm_vcpu *vcpu,
 	const u64 supported_flags = KVM_S390_MEMOP_F_INJECT_EXCEPTION
 	const u64 supported_flags = KVM_S390_MEMOP_F_INJECT_EXCEPTION
 				    | KVM_S390_MEMOP_F_CHECK_ONLY;
 				    | KVM_S390_MEMOP_F_CHECK_ONLY;
 
 
-	if (mop->flags & ~supported_flags)
+	if (mop->flags & ~supported_flags || mop->ar >= NUM_ACRS || !mop->size)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	if (mop->size > MEM_OP_MAX_SIZE)
 	if (mop->size > MEM_OP_MAX_SIZE)
@@ -3956,7 +3958,7 @@ long kvm_arch_vcpu_async_ioctl(struct file *filp,
 	}
 	}
 	case KVM_S390_INTERRUPT: {
 	case KVM_S390_INTERRUPT: {
 		struct kvm_s390_interrupt s390int;
 		struct kvm_s390_interrupt s390int;
-		struct kvm_s390_irq s390irq;
+		struct kvm_s390_irq s390irq = {};
 
 
 		if (copy_from_user(&s390int, argp, sizeof(s390int)))
 		if (copy_from_user(&s390int, argp, sizeof(s390int)))
 			return -EFAULT;
 			return -EFAULT;

+ 7 - 5
arch/s390/net/bpf_jit_comp.c

@@ -841,7 +841,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
 		break;
 		break;
 	case BPF_ALU64 | BPF_NEG: /* dst = -dst */
 	case BPF_ALU64 | BPF_NEG: /* dst = -dst */
 		/* lcgr %dst,%dst */
 		/* lcgr %dst,%dst */
-		EMIT4(0xb9130000, dst_reg, dst_reg);
+		EMIT4(0xb9030000, dst_reg, dst_reg);
 		break;
 		break;
 	/*
 	/*
 	 * BPF_FROM_BE/LE
 	 * BPF_FROM_BE/LE
@@ -1015,8 +1015,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
 		/* llgf %w1,map.max_entries(%b2) */
 		/* llgf %w1,map.max_entries(%b2) */
 		EMIT6_DISP_LH(0xe3000000, 0x0016, REG_W1, REG_0, BPF_REG_2,
 		EMIT6_DISP_LH(0xe3000000, 0x0016, REG_W1, REG_0, BPF_REG_2,
 			      offsetof(struct bpf_array, map.max_entries));
 			      offsetof(struct bpf_array, map.max_entries));
-		/* clgrj %b3,%w1,0xa,label0: if %b3 >= %w1 goto out */
-		EMIT6_PCREL_LABEL(0xec000000, 0x0065, BPF_REG_3,
+		/* clrj %b3,%w1,0xa,label0: if (u32)%b3 >= (u32)%w1 goto out */
+		EMIT6_PCREL_LABEL(0xec000000, 0x0077, BPF_REG_3,
 				  REG_W1, 0, 0xa);
 				  REG_W1, 0, 0xa);
 
 
 		/*
 		/*
@@ -1042,8 +1042,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
 		 *         goto out;
 		 *         goto out;
 		 */
 		 */
 
 
-		/* sllg %r1,%b3,3: %r1 = index * 8 */
-		EMIT6_DISP_LH(0xeb000000, 0x000d, REG_1, BPF_REG_3, REG_0, 3);
+		/* llgfr %r1,%b3: %r1 = (u32) index */
+		EMIT4(0xb9160000, REG_1, BPF_REG_3);
+		/* sllg %r1,%r1,3: %r1 *= 8 */
+		EMIT6_DISP_LH(0xeb000000, 0x000d, REG_1, REG_1, REG_0, 3);
 		/* lg %r1,prog(%b2,%r1) */
 		/* lg %r1,prog(%b2,%r1) */
 		EMIT6_DISP_LH(0xe3000000, 0x0004, REG_1, BPF_REG_2,
 		EMIT6_DISP_LH(0xe3000000, 0x0004, REG_1, BPF_REG_2,
 			      REG_1, offsetof(struct bpf_array, ptrs));
 			      REG_1, offsetof(struct bpf_array, ptrs));

+ 1 - 0
arch/x86/Makefile

@@ -38,6 +38,7 @@ REALMODE_CFLAGS	:= $(M16_CFLAGS) -g -Os -DDISABLE_BRANCH_PROFILING \
 
 
 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -ffreestanding)
 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -ffreestanding)
 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -fno-stack-protector)
 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -fno-stack-protector)
+REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -Wno-address-of-packed-member)
 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4))
 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4))
 export REALMODE_CFLAGS
 export REALMODE_CFLAGS
 
 

+ 10 - 3
arch/x86/events/amd/ibs.c

@@ -672,10 +672,17 @@ fail:
 
 
 	throttle = perf_event_overflow(event, &data, &regs);
 	throttle = perf_event_overflow(event, &data, &regs);
 out:
 out:
-	if (throttle)
+	if (throttle) {
 		perf_ibs_stop(event, 0);
 		perf_ibs_stop(event, 0);
-	else
-		perf_ibs_enable_event(perf_ibs, hwc, period >> 4);
+	} else {
+		period >>= 4;
+
+		if ((ibs_caps & IBS_CAPS_RDWROPCNT) &&
+		    (*config & IBS_OP_CNT_CTL))
+			period |= *config & IBS_OP_CUR_CNT_RAND;
+
+		perf_ibs_enable_event(perf_ibs, hwc, period);
+	}
 
 
 	perf_event_update_userpage(event);
 	perf_event_update_userpage(event);
 
 

+ 6 - 0
arch/x86/events/intel/core.c

@@ -3319,6 +3319,11 @@ static u64 bdw_limit_period(struct perf_event *event, u64 left)
 	return left;
 	return left;
 }
 }
 
 
+static u64 nhm_limit_period(struct perf_event *event, u64 left)
+{
+	return max(left, 32ULL);
+}
+
 PMU_FORMAT_ATTR(event,	"config:0-7"	);
 PMU_FORMAT_ATTR(event,	"config:0-7"	);
 PMU_FORMAT_ATTR(umask,	"config:8-15"	);
 PMU_FORMAT_ATTR(umask,	"config:8-15"	);
 PMU_FORMAT_ATTR(edge,	"config:18"	);
 PMU_FORMAT_ATTR(edge,	"config:18"	);
@@ -4115,6 +4120,7 @@ __init int intel_pmu_init(void)
 		x86_pmu.pebs_constraints = intel_nehalem_pebs_event_constraints;
 		x86_pmu.pebs_constraints = intel_nehalem_pebs_event_constraints;
 		x86_pmu.enable_all = intel_pmu_nhm_enable_all;
 		x86_pmu.enable_all = intel_pmu_nhm_enable_all;
 		x86_pmu.extra_regs = intel_nehalem_extra_regs;
 		x86_pmu.extra_regs = intel_nehalem_extra_regs;
+		x86_pmu.limit_period = nhm_limit_period;
 
 
 		x86_pmu.cpu_events = nhm_events_attrs;
 		x86_pmu.cpu_events = nhm_events_attrs;
 
 

+ 5 - 3
arch/x86/hyperv/mmu.c

@@ -37,12 +37,14 @@ static inline int fill_gva_list(u64 gva_list[], int offset,
 		 * Lower 12 bits encode the number of additional
 		 * Lower 12 bits encode the number of additional
 		 * pages to flush (in addition to the 'cur' page).
 		 * pages to flush (in addition to the 'cur' page).
 		 */
 		 */
-		if (diff >= HV_TLB_FLUSH_UNIT)
+		if (diff >= HV_TLB_FLUSH_UNIT) {
 			gva_list[gva_n] |= ~PAGE_MASK;
 			gva_list[gva_n] |= ~PAGE_MASK;
-		else if (diff)
+			cur += HV_TLB_FLUSH_UNIT;
+		}  else if (diff) {
 			gva_list[gva_n] |= (diff - 1) >> PAGE_SHIFT;
 			gva_list[gva_n] |= (diff - 1) >> PAGE_SHIFT;
+			cur = end;
+		}
 
 
-		cur += HV_TLB_FLUSH_UNIT;
 		gva_n++;
 		gva_n++;
 
 
 	} while (cur < end);
 	} while (cur < end);

+ 3 - 0
arch/x86/include/asm/intel-family.h

@@ -58,6 +58,9 @@
 #define INTEL_FAM6_ICELAKE_MOBILE	0x7E
 #define INTEL_FAM6_ICELAKE_MOBILE	0x7E
 #define INTEL_FAM6_ICELAKE_NNPI		0x9D
 #define INTEL_FAM6_ICELAKE_NNPI		0x9D
 
 
+#define INTEL_FAM6_TIGERLAKE_L		0x8C
+#define INTEL_FAM6_TIGERLAKE		0x8D
+
 /* "Small Core" Processors (Atom) */
 /* "Small Core" Processors (Atom) */
 
 
 #define INTEL_FAM6_ATOM_BONNELL		0x1C /* Diamondville, Pineview */
 #define INTEL_FAM6_ATOM_BONNELL		0x1C /* Diamondville, Pineview */

+ 8 - 4
arch/x86/include/asm/perf_event.h

@@ -209,16 +209,20 @@ struct x86_pmu_capability {
 #define IBSCTL_LVT_OFFSET_VALID		(1ULL<<8)
 #define IBSCTL_LVT_OFFSET_VALID		(1ULL<<8)
 #define IBSCTL_LVT_OFFSET_MASK		0x0F
 #define IBSCTL_LVT_OFFSET_MASK		0x0F
 
 
-/* ibs fetch bits/masks */
+/* IBS fetch bits/masks */
 #define IBS_FETCH_RAND_EN	(1ULL<<57)
 #define IBS_FETCH_RAND_EN	(1ULL<<57)
 #define IBS_FETCH_VAL		(1ULL<<49)
 #define IBS_FETCH_VAL		(1ULL<<49)
 #define IBS_FETCH_ENABLE	(1ULL<<48)
 #define IBS_FETCH_ENABLE	(1ULL<<48)
 #define IBS_FETCH_CNT		0xFFFF0000ULL
 #define IBS_FETCH_CNT		0xFFFF0000ULL
 #define IBS_FETCH_MAX_CNT	0x0000FFFFULL
 #define IBS_FETCH_MAX_CNT	0x0000FFFFULL
 
 
-/* ibs op bits/masks */
-/* lower 4 bits of the current count are ignored: */
-#define IBS_OP_CUR_CNT		(0xFFFF0ULL<<32)
+/*
+ * IBS op bits/masks
+ * The lower 7 bits of the current count are random bits
+ * preloaded by hardware and ignored in software
+ */
+#define IBS_OP_CUR_CNT		(0xFFF80ULL<<32)
+#define IBS_OP_CUR_CNT_RAND	(0x0007FULL<<32)
 #define IBS_OP_CNT_CTL		(1ULL<<19)
 #define IBS_OP_CNT_CTL		(1ULL<<19)
 #define IBS_OP_VAL		(1ULL<<18)
 #define IBS_OP_VAL		(1ULL<<18)
 #define IBS_OP_ENABLE		(1ULL<<17)
 #define IBS_OP_ENABLE		(1ULL<<17)

+ 3 - 1
arch/x86/include/asm/uaccess.h

@@ -451,8 +451,10 @@ do {									\
 ({									\
 ({									\
 	int __gu_err;							\
 	int __gu_err;							\
 	__inttype(*(ptr)) __gu_val;					\
 	__inttype(*(ptr)) __gu_val;					\
+	__typeof__(ptr) __gu_ptr = (ptr);				\
+	__typeof__(size) __gu_size = (size);				\
 	__uaccess_begin_nospec();					\
 	__uaccess_begin_nospec();					\
-	__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT);	\
+	__get_user_size(__gu_val, __gu_ptr, __gu_size, __gu_err, -EFAULT);	\
 	__uaccess_end();						\
 	__uaccess_end();						\
 	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
 	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
 	__builtin_expect(__gu_err, 0);					\
 	__builtin_expect(__gu_err, 0);					\

+ 71 - 44
arch/x86/kernel/apic/apic.c

@@ -1450,54 +1450,72 @@ static void lapic_setup_esr(void)
 			oldvalue, value);
 			oldvalue, value);
 }
 }
 
 
-static void apic_pending_intr_clear(void)
+#define APIC_IR_REGS		APIC_ISR_NR
+#define APIC_IR_BITS		(APIC_IR_REGS * 32)
+#define APIC_IR_MAPSIZE		(APIC_IR_BITS / BITS_PER_LONG)
+
+union apic_ir {
+	unsigned long	map[APIC_IR_MAPSIZE];
+	u32		regs[APIC_IR_REGS];
+};
+
+static bool apic_check_and_ack(union apic_ir *irr, union apic_ir *isr)
 {
 {
-	long long max_loops = cpu_khz ? cpu_khz : 1000000;
-	unsigned long long tsc = 0, ntsc;
-	unsigned int queued;
-	unsigned long value;
-	int i, j, acked = 0;
+	int i, bit;
+
+	/* Read the IRRs */
+	for (i = 0; i < APIC_IR_REGS; i++)
+		irr->regs[i] = apic_read(APIC_IRR + i * 0x10);
+
+	/* Read the ISRs */
+	for (i = 0; i < APIC_IR_REGS; i++)
+		isr->regs[i] = apic_read(APIC_ISR + i * 0x10);
 
 
-	if (boot_cpu_has(X86_FEATURE_TSC))
-		tsc = rdtsc();
 	/*
 	/*
-	 * After a crash, we no longer service the interrupts and a pending
-	 * interrupt from previous kernel might still have ISR bit set.
-	 *
-	 * Most probably by now CPU has serviced that pending interrupt and
-	 * it might not have done the ack_APIC_irq() because it thought,
-	 * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it
-	 * does not clear the ISR bit and cpu thinks it has already serivced
-	 * the interrupt. Hence a vector might get locked. It was noticed
-	 * for timer irq (vector 0x31). Issue an extra EOI to clear ISR.
+	 * If the ISR map is not empty. ACK the APIC and run another round
+	 * to verify whether a pending IRR has been unblocked and turned
+	 * into a ISR.
 	 */
 	 */
-	do {
-		queued = 0;
-		for (i = APIC_ISR_NR - 1; i >= 0; i--)
-			queued |= apic_read(APIC_IRR + i*0x10);
-
-		for (i = APIC_ISR_NR - 1; i >= 0; i--) {
-			value = apic_read(APIC_ISR + i*0x10);
-			for_each_set_bit(j, &value, 32) {
-				ack_APIC_irq();
-				acked++;
-			}
-		}
-		if (acked > 256) {
-			pr_err("LAPIC pending interrupts after %d EOI\n", acked);
-			break;
-		}
-		if (queued) {
-			if (boot_cpu_has(X86_FEATURE_TSC) && cpu_khz) {
-				ntsc = rdtsc();
-				max_loops = (long long)cpu_khz << 10;
-				max_loops -= ntsc - tsc;
-			} else {
-				max_loops--;
-			}
-		}
-	} while (queued && max_loops > 0);
-	WARN_ON(max_loops <= 0);
+	if (!bitmap_empty(isr->map, APIC_IR_BITS)) {
+		/*
+		 * There can be multiple ISR bits set when a high priority
+		 * interrupt preempted a lower priority one. Issue an ACK
+		 * per set bit.
+		 */
+		for_each_set_bit(bit, isr->map, APIC_IR_BITS)
+			ack_APIC_irq();
+		return true;
+	}
+
+	return !bitmap_empty(irr->map, APIC_IR_BITS);
+}
+
+/*
+ * After a crash, we no longer service the interrupts and a pending
+ * interrupt from previous kernel might still have ISR bit set.
+ *
+ * Most probably by now the CPU has serviced that pending interrupt and it
+ * might not have done the ack_APIC_irq() because it thought, interrupt
+ * came from i8259 as ExtInt. LAPIC did not get EOI so it does not clear
+ * the ISR bit and cpu thinks it has already serivced the interrupt. Hence
+ * a vector might get locked. It was noticed for timer irq (vector
+ * 0x31). Issue an extra EOI to clear ISR.
+ *
+ * If there are pending IRR bits they turn into ISR bits after a higher
+ * priority ISR bit has been acked.
+ */
+static void apic_pending_intr_clear(void)
+{
+	union apic_ir irr, isr;
+	unsigned int i;
+
+	/* 512 loops are way oversized and give the APIC a chance to obey. */
+	for (i = 0; i < 512; i++) {
+		if (!apic_check_and_ack(&irr, &isr))
+			return;
+	}
+	/* Dump the IRR/ISR content if that failed */
+	pr_warn("APIC: Stale IRR: %256pb ISR: %256pb\n", irr.map, isr.map);
 }
 }
 
 
 /**
 /**
@@ -1520,6 +1538,14 @@ static void setup_local_APIC(void)
 		return;
 		return;
 	}
 	}
 
 
+	/*
+	 * If this comes from kexec/kcrash the APIC might be enabled in
+	 * SPIV. Soft disable it before doing further initialization.
+	 */
+	value = apic_read(APIC_SPIV);
+	value &= ~APIC_SPIV_APIC_ENABLED;
+	apic_write(APIC_SPIV, value);
+
 #ifdef CONFIG_X86_32
 #ifdef CONFIG_X86_32
 	/* Pound the ESR really hard over the head with a big hammer - mbligh */
 	/* Pound the ESR really hard over the head with a big hammer - mbligh */
 	if (lapic_is_integrated() && apic->disable_esr) {
 	if (lapic_is_integrated() && apic->disable_esr) {
@@ -1565,6 +1591,7 @@ static void setup_local_APIC(void)
 	value &= ~APIC_TPRI_MASK;
 	value &= ~APIC_TPRI_MASK;
 	apic_write(APIC_TASKPRI, value);
 	apic_write(APIC_TASKPRI, value);
 
 
+	/* Clear eventually stale ISR/IRR bits */
 	apic_pending_intr_clear();
 	apic_pending_intr_clear();
 
 
 	/*
 	/*

+ 7 - 1
arch/x86/kernel/apic/io_apic.c

@@ -2432,7 +2432,13 @@ unsigned int arch_dynirq_lower_bound(unsigned int from)
 	 * dmar_alloc_hwirq() may be called before setup_IO_APIC(), so use
 	 * dmar_alloc_hwirq() may be called before setup_IO_APIC(), so use
 	 * gsi_top if ioapic_dynirq_base hasn't been initialized yet.
 	 * gsi_top if ioapic_dynirq_base hasn't been initialized yet.
 	 */
 	 */
-	return ioapic_initialized ? ioapic_dynirq_base : gsi_top;
+	if (!ioapic_initialized)
+		return gsi_top;
+	/*
+	 * For DT enabled machines ioapic_dynirq_base is irrelevant and not
+	 * updated. So simply return @from if ioapic_dynirq_base == 0.
+	 */
+	return ioapic_dynirq_base ? : from;
 }
 }
 
 
 #ifdef CONFIG_X86_32
 #ifdef CONFIG_X86_32

Some files were not shown because too many files changed in this diff