diff options
Diffstat (limited to 'arch/powerpc')
171 files changed, 3101 insertions, 1897 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 5ef27113b898..9a7057ec2154 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -82,6 +82,9 @@ config GENERIC_HWEIGHT  	bool  	default y +config ARCH_HAS_DMA_SET_COHERENT_MASK +        bool +  config PPC  	bool  	default y @@ -155,6 +158,8 @@ config PPC  	select HAVE_PERF_EVENTS_NMI if PPC64  	select EDAC_SUPPORT  	select EDAC_ATOMIC_SCRUB +	select ARCH_HAS_DMA_SET_COHERENT_MASK +	select HAVE_ARCH_SECCOMP_FILTER  config GENERIC_CSUM  	def_bool CPU_LITTLE_ENDIAN @@ -415,6 +420,7 @@ config PPC64_SUPPORTS_MEMORY_FAILURE  config KEXEC  	bool "kexec system call"  	depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP)) +	select KEXEC_CORE  	help  	  kexec is a system call that implements the ability to shutdown your  	  current kernel, and to start another kernel.  It is like a reboot @@ -514,11 +520,6 @@ config NODES_SPAN_OTHER_NODES  	def_bool y  	depends on NEED_MULTIPLE_NODES -config PPC_HAS_HASH_64K -	bool -	depends on PPC64 -	default n -  config STDBINUTILS  	bool "Using standard binutils settings"  	depends on 44x @@ -560,16 +561,16 @@ config PPC_4K_PAGES  	bool "4k page size"  config PPC_16K_PAGES -	bool "16k page size" if 44x || PPC_8xx +	bool "16k page size" +	depends on 44x || PPC_8xx  config PPC_64K_PAGES -	bool "64k page size" if 44x || PPC_STD_MMU_64 || PPC_BOOK3E_64 -	depends on !PPC_FSL_BOOK3E -	select PPC_HAS_HASH_64K if PPC_STD_MMU_64 +	bool "64k page size" +	depends on !PPC_FSL_BOOK3E && (44x || PPC_STD_MMU_64 || PPC_BOOK3E_64)  config PPC_256K_PAGES -	bool "256k page size" if 44x -	depends on !STDBINUTILS +	bool "256k page size" +	depends on 44x && !STDBINUTILS  	help  	  Make the page size 256k. diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 05f464eb6952..b9b4af2af9a5 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -67,7 +67,7 @@ UTS_MACHINE := $(OLDARCH)  ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y)  override CC	+= -mlittle-endian -ifneq ($(COMPILER),clang) +ifneq ($(cc-name),clang)  override CC	+= -mno-strict-align  endif  override AS	+= -mlittle-endian @@ -288,6 +288,26 @@ PHONY += pseries_le_defconfig  pseries_le_defconfig:  	$(call merge_into_defconfig,pseries_defconfig,le) +PHONY += mpc85xx_defconfig +mpc85xx_defconfig: +	$(call merge_into_defconfig,mpc85xx_basic_defconfig,\ +		85xx-32bit 85xx-hw fsl-emb-nonhw) + +PHONY += mpc85xx_smp_defconfig +mpc85xx_smp_defconfig: +	$(call merge_into_defconfig,mpc85xx_basic_defconfig,\ +		85xx-32bit 85xx-smp 85xx-hw fsl-emb-nonhw) + +PHONY += corenet32_smp_defconfig +corenet32_smp_defconfig: +	$(call merge_into_defconfig,corenet_basic_defconfig,\ +		85xx-32bit 85xx-smp 85xx-hw fsl-emb-nonhw) + +PHONY += corenet64_smp_defconfig +corenet64_smp_defconfig: +	$(call merge_into_defconfig,corenet_basic_defconfig,\ +		85xx-64bit 85xx-smp altivec 85xx-hw fsl-emb-nonhw) +  define archhelp    @echo '* zImage          - Build default images selected by kernel config'    @echo '  zImage.*        - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)' @@ -333,7 +353,7 @@ TOUT	:= .tmp_gas_check  # - Require gcc 4.0 or above on 64-bit  # - gcc-4.2.0 has issues compiling modules on 64-bit  checkbin: -	@if test "${COMPILER}" != "clang" \ +	@if test "$(cc-name)" != "clang" \  	    && test "$(cc-version)" = "0304" ; then \  		if ! /bin/echo mftb 5 | $(AS) -v -mppc -many -o $(TOUT) >/dev/null 2>&1 ; then \  			echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build '; \ @@ -342,14 +362,14 @@ checkbin:  			false; \  		fi ; \  	fi -	@if test "${COMPILER}" != "clang" \ +	@if test "$(cc-name)" != "clang" \  	    && test "$(cc-version)" -lt "0400" \  	    && test "x${CONFIG_PPC64}" = "xy" ; then \                  echo -n "Sorry, GCC v4.0 or above is required to build " ; \                  echo "the 64-bit powerpc kernel." ; \                  false ; \          fi -	@if test "${COMPILER}" != "clang" \ +	@if test "$(cc-name)" != "clang" \  	    && test "$(cc-fullversion)" = "040200" \  	    && test "x${CONFIG_MODULES}${CONFIG_PPC64}" = "xyy" ; then \  		echo -n '*** GCC-4.2.0 cannot compile the 64-bit powerpc ' ; \ diff --git a/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi index ebf202234549..426bf4103b9e 100644 --- a/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1022si-post.dtsi @@ -175,7 +175,7 @@  /include/ "pq3-gpio-0.dtsi" -	display@10000 { +	display: display@10000 {  		compatible = "fsl,diu", "fsl,p1022-diu";  		reg = <0x10000 1000>;  		interrupts = <64 2 0 0>; diff --git a/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi index 1956dea040cc..de76ae8992c6 100644 --- a/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi @@ -50,6 +50,8 @@  		pci0 = &pci0;  		pci1 = &pci1;  		pci2 = &pci2; +		vga = &display; +		display = &display;  	};  	cpus { diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi index 9e9f7e201d43..9770d0278493 100644 --- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi @@ -484,6 +484,11 @@  		reg	   = <0xea000 0x4000>;  	}; +	scfg: global-utilities@fc000 { +		compatible = "fsl,t1040-scfg"; +		reg = <0xfc000 0x1000>; +	}; +  /include/ "elo3-dma-0.dtsi"  /include/ "elo3-dma-1.dtsi"  /include/ "qoriq-espi-0.dtsi" diff --git a/arch/powerpc/boot/dts/t1023rdb.dts b/arch/powerpc/boot/dts/t1023rdb.dts index 06b090aba066..d3fa8294cd49 100644 --- a/arch/powerpc/boot/dts/t1023rdb.dts +++ b/arch/powerpc/boot/dts/t1023rdb.dts @@ -60,7 +60,7 @@  			#address-cells = <1>;  			#size-cells = <1>;  			compatible = "fsl,ifc-nand"; -			reg = <0x2 0x0 0x10000>; +			reg = <0x1 0x0 0x10000>;  		};  	}; @@ -99,6 +99,17 @@  		};  		i2c@118100 { +			current-sensor@40 { +				compatible = "ti,ina220"; +				reg = <0x40>; +				shunt-resistor = <1000>; +			}; + +			current-sensor@41 { +				compatible = "ti,ina220"; +				reg = <0x41>; +				shunt-resistor = <1000>; +			};  		};  	}; diff --git a/arch/powerpc/boot/dts/t1024rdb.dts b/arch/powerpc/boot/dts/t1024rdb.dts index 733e723ffed6..bf05e324fda2 100644 --- a/arch/powerpc/boot/dts/t1024rdb.dts +++ b/arch/powerpc/boot/dts/t1024rdb.dts @@ -114,6 +114,12 @@  				reg = <0x4c>;  			}; +			current-sensor@40 { +				compatible = "ti,ina220"; +				reg = <0x40>; +				shunt-resistor = <1000>; +			}; +  			eeprom@50 {  				compatible = "atmel,24c256";  				reg = <0x50>; diff --git a/arch/powerpc/boot/dts/t1040d4rdb.dts b/arch/powerpc/boot/dts/t1040d4rdb.dts new file mode 100644 index 000000000000..2d1315a1670e --- /dev/null +++ b/arch/powerpc/boot/dts/t1040d4rdb.dts @@ -0,0 +1,46 @@ +/* + * T1040D4RDB Device Tree Source + * + * Copyright 2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + *     * Redistributions of source code must retain the above copyright + *	 notice, this list of conditions and the following disclaimer. + *     * Redistributions in binary form must reproduce the above copyright + *	 notice, this list of conditions and the following disclaimer in the + *	 documentation and/or other materials provided with the distribution. + *     * Neither the name of Freescale Semiconductor nor the + *	 names of its contributors may be used to endorse or promote products + *	 derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/include/ "fsl/t104xsi-pre.dtsi" +/include/ "t104xd4rdb.dtsi" + +/ { +	model = "fsl,T1040D4RDB"; +	compatible = "fsl,T1040D4RDB"; +	#address-cells = <2>; +	#size-cells = <2>; +	interrupt-parent = <&mpic>; +}; + +/include/ "fsl/t1040si-post.dtsi" diff --git a/arch/powerpc/boot/dts/t1042d4rdb.dts b/arch/powerpc/boot/dts/t1042d4rdb.dts new file mode 100644 index 000000000000..846f8c87e85a --- /dev/null +++ b/arch/powerpc/boot/dts/t1042d4rdb.dts @@ -0,0 +1,53 @@ +/* + * T1042D4RDB Device Tree Source + * + * Copyright 2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + *     * Redistributions of source code must retain the above copyright + *	 notice, this list of conditions and the following disclaimer. + *     * Redistributions in binary form must reproduce the above copyright + *	 notice, this list of conditions and the following disclaimer in the + *	 documentation and/or other materials provided with the distribution. + *     * Neither the name of Freescale Semiconductor nor the + *	 names of its contributors may be used to endorse or promote products + *	 derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/include/ "fsl/t104xsi-pre.dtsi" +/include/ "t104xd4rdb.dtsi" + +/ { +	model = "fsl,T1042D4RDB"; +	compatible = "fsl,T1042D4RDB"; +	#address-cells = <2>; +	#size-cells = <2>; +	interrupt-parent = <&mpic>; + +	ifc: localbus@ffe124000 { +		cpld@3,0 { +			compatible = "fsl,t1040d4rdb-cpld", +					"fsl,deepsleep-cpld"; +		}; +	}; +}; + +/include/ "fsl/t1040si-post.dtsi" diff --git a/arch/powerpc/boot/dts/t104xd4rdb.dtsi b/arch/powerpc/boot/dts/t104xd4rdb.dtsi new file mode 100644 index 000000000000..491367bd3883 --- /dev/null +++ b/arch/powerpc/boot/dts/t104xd4rdb.dtsi @@ -0,0 +1,205 @@ +/* + * T1040D4RDB/T1042D4RDB Device Tree Source + * + * Copyright 2015 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + *     * Redistributions of source code must retain the above copyright + *	 notice, this list of conditions and the following disclaimer. + *     * Redistributions in binary form must reproduce the above copyright + *	 notice, this list of conditions and the following disclaimer in the + *	 documentation and/or other materials provided with the distribution. + *     * Neither the name of Freescale Semiconductor nor the + *	 names of its contributors may be used to endorse or promote products + *	 derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/ { +	reserved-memory { +		#address-cells = <2>; +		#size-cells = <2>; +		ranges; + +		bman_fbpr: bman-fbpr { +			size = <0 0x1000000>; +			alignment = <0 0x1000000>; +		}; +		qman_fqd: qman-fqd { +			size = <0 0x400000>; +			alignment = <0 0x400000>; +		}; +		qman_pfdr: qman-pfdr { +			size = <0 0x2000000>; +			alignment = <0 0x2000000>; +		}; +	}; + +	ifc: localbus@ffe124000 { +		reg = <0xf 0xfe124000 0 0x2000>; +		ranges = <0 0 0xf 0xe8000000 0x08000000 +			  2 0 0xf 0xff800000 0x00010000 +			  3 0 0xf 0xffdf0000 0x00008000>; + +		nor@0,0 { +			#address-cells = <1>; +			#size-cells = <1>; +			compatible = "cfi-flash"; +			reg = <0x0 0x0 0x8000000>; +			bank-width = <2>; +			device-width = <1>; +		}; + +		nand@2,0 { +			#address-cells = <1>; +			#size-cells = <1>; +			compatible = "fsl,ifc-nand"; +			reg = <0x2 0x0 0x10000>; +		}; + +		cpld@3,0 { +			compatible = "fsl,t1040d4rdb-cpld"; +			reg = <3 0 0x300>; +		}; +	}; + +	memory { +		device_type = "memory"; +	}; + +	dcsr: dcsr@f00000000 { +		ranges = <0x00000000 0xf 0x00000000 0x01072000>; +	}; + +	bportals: bman-portals@ff4000000 { +		ranges = <0x0 0xf 0xf4000000 0x2000000>; +	}; + +	qportals: qman-portals@ff6000000 { +		ranges = <0x0 0xf 0xf6000000 0x2000000>; +	}; + +	soc: soc@ffe000000 { +		ranges = <0x00000000 0xf 0xfe000000 0x1000000>; +		reg = <0xf 0xfe000000 0 0x00001000>; + +		spi@110000 { +			flash@0 { +				#address-cells = <1>; +				#size-cells = <1>; +				compatible = "micron,n25q512ax3"; +				reg = <0>; +				/* input clock */ +				spi-max-frequency = <10000000>; +			}; +		}; +		i2c@118000 { +			hwmon@4c { +				compatible = "adi,adt7461"; +				reg = <0x4c>; +			}; + +			rtc@68 { +				compatible = "dallas,ds1337"; +				reg = <0x68>; +				interrupts = <0x2 0x1 0 0>; +			}; +		}; + +		i2c@118100 { +			mux@77 { +				/* +				 * Child nodes of mux depend on which i2c +				 * devices are connected via the mini PCI +				 * connector slot1, the mini PCI connector +				 * slot2, the HDMI connector, and the PEX +				 * slot. Systems with such devices attached +				 * should provide a wrapper .dts file that +				 * includes this one, and adds those nodes +				 */ +				compatible = "nxp,pca9546"; +				reg = <0x77>; +				#address-cells = <1>; +				#size-cells = <0>; +			}; +		}; + +	}; + +	pci0: pcie@ffe240000 { +		reg = <0xf 0xfe240000 0 0x10000>; +		ranges = <0x02000000 0 0xe0000000 0xc 0x0 0x0 0x10000000 +			  0x01000000 0 0x0 0xf 0xf8000000 0x0 0x00010000>; +		pcie@0 { +			ranges = <0x02000000 0 0xe0000000 +				  0x02000000 0 0xe0000000 +				  0 0x10000000 + +				  0x01000000 0 0x00000000 +				  0x01000000 0 0x00000000 +				  0 0x00010000>; +		}; +	}; + +	pci1: pcie@ffe250000 { +		reg = <0xf 0xfe250000 0 0x10000>; +		ranges = <0x02000000 0 0xe0000000 0xc 0x10000000 0 0x10000000 +			  0x01000000 0 0 0xf 0xf8010000 0 0x00010000>; +		pcie@0 { +			ranges = <0x02000000 0 0xe0000000 +				  0x02000000 0 0xe0000000 +				  0 0x10000000 + +				  0x01000000 0 0x00000000 +				  0x01000000 0 0x00000000 +				  0 0x00010000>; +		}; +	}; + +	pci2: pcie@ffe260000 { +		reg = <0xf 0xfe260000 0 0x10000>; +		ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x10000000 +			  0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>; +		pcie@0 { +			ranges = <0x02000000 0 0xe0000000 +				  0x02000000 0 0xe0000000 +				  0 0x10000000 + +				  0x01000000 0 0x00000000 +				  0x01000000 0 0x00000000 +				  0 0x00010000>; +		}; +	}; + +	pci3: pcie@ffe270000 { +		reg = <0xf 0xfe270000 0 0x10000>; +		ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000 +			  0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>; +		pcie@0 { +			ranges = <0x02000000 0 0xe0000000 +				  0x02000000 0 0xe0000000 +				  0 0x10000000 + +				  0x01000000 0 0x00000000 +				  0x01000000 0 0x00000000 +				  0 0x00010000>; +		}; +	}; +}; diff --git a/arch/powerpc/configs/85xx-32bit.config b/arch/powerpc/configs/85xx-32bit.config new file mode 100644 index 000000000000..6b8894d727a2 --- /dev/null +++ b/arch/powerpc/configs/85xx-32bit.config @@ -0,0 +1,5 @@ +CONFIG_HIGHMEM=y +CONFIG_KEXEC=y +CONFIG_PPC_85xx=y +CONFIG_PROC_KCORE=y +CONFIG_PHYS_64BIT=y diff --git a/arch/powerpc/configs/85xx-64bit.config b/arch/powerpc/configs/85xx-64bit.config new file mode 100644 index 000000000000..4aba81222885 --- /dev/null +++ b/arch/powerpc/configs/85xx-64bit.config @@ -0,0 +1,4 @@ +CONFIG_MATH_EMULATION=y +CONFIG_MATH_EMULATION_HW_UNIMPLEMENTED=y +CONFIG_PPC64=y +CONFIG_PPC_BOOK3E_64=y diff --git a/arch/powerpc/configs/85xx-hw.config b/arch/powerpc/configs/85xx-hw.config new file mode 100644 index 000000000000..528ff0e714e6 --- /dev/null +++ b/arch/powerpc/configs/85xx-hw.config @@ -0,0 +1,142 @@ +CONFIG_AQUANTIA_PHY=y +CONFIG_AT803X_PHY=y +CONFIG_ATA=y +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_BLK_DEV_SR=y +CONFIG_BROADCOM_PHY=y +CONFIG_C293_PCIE=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_ST=y +CONFIG_CICADA_PHY=y +CONFIG_CLK_QORIQ=y +CONFIG_CRYPTO_DEV_FSL_CAAM=y +CONFIG_CRYPTO_DEV_TALITOS=y +CONFIG_DAVICOM_PHY=y +CONFIG_DMADEVICES=y +CONFIG_E1000E=y +CONFIG_E1000=y +CONFIG_EDAC_MM_EDAC=y +CONFIG_EDAC_MPC85XX=y +CONFIG_EDAC=y +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_LEGACY=y +CONFIG_FB_FSL_DIU=y +CONFIG_FS_ENET=y +CONFIG_FSL_CORENET_CF=y +CONFIG_FSL_DMA=y +CONFIG_FSL_HV_MANAGER=y +CONFIG_FSL_PQ_MDIO=y +CONFIG_FSL_RIO=y +CONFIG_FSL_XGMAC_MDIO=y +CONFIG_GIANFAR=y +CONFIG_GPIO_MPC8XXX=y +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_EZKEY=y +CONFIG_HID_GYRATION=y +CONFIG_HID_LOGITECH=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_PANTHERLORD=y +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SUNPLUS=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_CPM=m +CONFIG_I2C_MPC=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_MUX=y +CONFIG_I2C=y +CONFIG_IGB=y +CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_MARVELL_PHY=y +CONFIG_MDIO_BUS_MUX_GPIO=y +CONFIG_MDIO_BUS_MUX_MMIOREG=y +CONFIG_MMC_SDHCI_OF_ESDHC=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_M25P80=y +CONFIG_MTD_NAND_FSL_ELBC=y +CONFIG_MTD_NAND_FSL_IFC=y +CONFIG_MTD_NAND=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PLATRAM=y +CONFIG_MTD_SPI_NOR=y +CONFIG_NETDEVICES=y +CONFIG_NVRAM=y +CONFIG_PATA_ALI=y +CONFIG_PATA_SIL680=y +CONFIG_PATA_VIA=y +# CONFIG_PCIEASPM is not set +CONFIG_PCIEPORTBUS=y +CONFIG_PCI_MSI=y +CONFIG_PCI=y +CONFIG_PPC_EPAPR_HV_BYTECHAN=y +# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set +CONFIG_QE_GPIO=y +CONFIG_QUICC_ENGINE=y +CONFIG_RAPIDIO=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_CMOS=y +CONFIG_RTC_DRV_DS1307=y +CONFIG_RTC_DRV_DS1374=y +CONFIG_RTC_DRV_DS3232=y +CONFIG_SATA_AHCI=y +CONFIG_SATA_FSL=y +CONFIG_SATA_SIL24=y +CONFIG_SATA_SIL=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SENSORS_INA2XX=y +CONFIG_SENSORS_LM90=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_NR_UARTS=6 +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=6 +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_QE=m +CONFIG_SERIO_LIBPS2=y +# CONFIG_SND_DRIVERS is not set +CONFIG_SND_INTEL8X0=y +CONFIG_SND_POWERPC_SOC=y +# CONFIG_SND_PPC is not set +CONFIG_SND_SOC=y +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_USB is not set +CONFIG_SND=y +CONFIG_SOUND=y +CONFIG_SPI_FSL_ESPI=y +CONFIG_SPI_FSL_SPI=y +CONFIG_SPI_GPIO=y +CONFIG_SPI=y +CONFIG_TERANETICS_PHY=y +CONFIG_UCC_GETH=y +CONFIG_USB_EHCI_FSL=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_HID=m +CONFIG_USB_MON=y +CONFIG_USB_OHCI_HCD_PPC_OF_BE=y +CONFIG_USB_OHCI_HCD_PPC_OF_LE=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB=y +# CONFIG_VGA_CONSOLE is not set +CONFIG_VIRT_DRIVERS=y +CONFIG_VITESSE_PHY=y diff --git a/arch/powerpc/configs/85xx-smp.config b/arch/powerpc/configs/85xx-smp.config new file mode 100644 index 000000000000..3b4d1e54636d --- /dev/null +++ b/arch/powerpc/configs/85xx-smp.config @@ -0,0 +1,2 @@ +CONFIG_NR_CPUS=24 +CONFIG_SMP=y diff --git a/arch/powerpc/configs/altivec.config b/arch/powerpc/configs/altivec.config new file mode 100644 index 000000000000..58a697cb5a62 --- /dev/null +++ b/arch/powerpc/configs/altivec.config @@ -0,0 +1 @@ +CONFIG_ALTIVEC=y diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig deleted file mode 100644 index 37659937bd12..000000000000 --- a/arch/powerpc/configs/corenet32_smp_defconfig +++ /dev/null @@ -1,185 +0,0 @@ -CONFIG_PPC_85xx=y -CONFIG_SMP=y -CONFIG_NR_CPUS=8 -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_AUDIT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_KALLSYMS_ALL=y -CONFIG_EMBEDDED=y -CONFIG_PERF_EVENTS=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_MODVERSIONS=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_PARTITION_ADVANCED=y -CONFIG_MAC_PARTITION=y -CONFIG_CORENET_GENERIC=y -CONFIG_HIGHMEM=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_BINFMT_MISC=m -CONFIG_KEXEC=y -CONFIG_FORCE_MAX_ZONEORDER=13 -CONFIG_PCI=y -CONFIG_PCIEPORTBUS=y -# CONFIG_PCIEASPM is not set -CONFIG_PCI_MSI=y -CONFIG_RAPIDIO=y -CONFIG_FSL_RIO=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_XFRM_SUB_POLICY=y -CONFIG_XFRM_STATISTICS=y -CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set -CONFIG_IPV6=y -CONFIG_IP_SCTP=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP_OF=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_FSL_ELBC=y -CONFIG_MTD_NAND_FSL_IFC=y -CONFIG_MTD_SPI_NOR=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -CONFIG_BLK_DEV_SR=y -CONFIG_CHR_DEV_SG=y -CONFIG_SCSI_LOGGING=y -CONFIG_SCSI_SYM53C8XX_2=y -CONFIG_ATA=y -CONFIG_SATA_AHCI=y -CONFIG_SATA_FSL=y -CONFIG_SATA_SIL24=y -CONFIG_SATA_SIL=y -CONFIG_PATA_SIL680=y -CONFIG_NETDEVICES=y -CONFIG_FSL_PQ_MDIO=y -CONFIG_FSL_XGMAC_MDIO=y -CONFIG_E1000=y -CONFIG_E1000E=y -CONFIG_AT803X_PHY=y -CONFIG_VITESSE_PHY=y -CONFIG_FIXED_PHY=y -CONFIG_MDIO_BUS_MUX_GPIO=y -CONFIG_MDIO_BUS_MUX_MMIOREG=y -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_LEGACY_PTYS is not set -CONFIG_PPC_EPAPR_HV_BYTECHAN=y -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y -CONFIG_NVRAM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MPC=y -CONFIG_I2C_MUX=y -CONFIG_I2C_MUX_PCA954x=y -CONFIG_SPI=y -CONFIG_SPI_GPIO=y -CONFIG_SPI_FSL_SPI=y -CONFIG_SPI_FSL_ESPI=y -CONFIG_SENSORS_LM90=y -CONFIG_SENSORS_INA2XX=y -CONFIG_USB_HID=m -CONFIG_USB=y -CONFIG_USB_MON=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_FSL=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_HCD_PPC_OF_BE=y -CONFIG_USB_OHCI_HCD_PPC_OF_LE=y -CONFIG_USB_STORAGE=y -CONFIG_MMC=y -CONFIG_MMC_SDHCI=y -CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=y -CONFIG_EDAC_MPC85XX=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_DS1307=y -CONFIG_RTC_DRV_DS1374=y -CONFIG_RTC_DRV_DS3232=y -CONFIG_UIO=y -CONFIG_VIRT_DRIVERS=y -CONFIG_FSL_HV_MANAGER=y -CONFIG_STAGING=y -CONFIG_FSL_CORENET_CF=y -CONFIG_CLK_QORIQ=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=y -CONFIG_NTFS_FS=y -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_HUGETLBFS=y -CONFIG_JFFS2_FS=y -CONFIG_CRAMFS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=m -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_UTF8=m -CONFIG_DEBUG_INFO=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_SHIRQ=y -CONFIG_DETECT_HUNG_TASK=y -CONFIG_RCU_TRACE=y -CONFIG_CRYPTO_NULL=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_DEV_FSL_CAAM=y diff --git a/arch/powerpc/configs/corenet_basic_defconfig b/arch/powerpc/configs/corenet_basic_defconfig new file mode 100644 index 000000000000..b568d465e59e --- /dev/null +++ b/arch/powerpc/configs/corenet_basic_defconfig @@ -0,0 +1 @@ +CONFIG_CORENET_GENERIC=y diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/fsl-emb-nonhw.config index 33cd1df818ad..41e4d359524d 100644 --- a/arch/powerpc/configs/corenet64_smp_defconfig +++ b/arch/powerpc/configs/fsl-emb-nonhw.config @@ -1,176 +1,126 @@ -CONFIG_PPC64=y -CONFIG_PPC_BOOK3E_64=y -CONFIG_ALTIVEC=y -CONFIG_SMP=y -CONFIG_NR_CPUS=24 -CONFIG_SYSVIPC=y -CONFIG_FHANDLE=y -CONFIG_IRQ_DOMAIN_DEBUG=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y +CONFIG_ADFS_FS=m +CONFIG_AFFS_FS=m +CONFIG_AUDIT=y +CONFIG_BEFS_FS=m +CONFIG_BFS_FS=m +CONFIG_BINFMT_MISC=m +# CONFIG_BLK_DEV_BSG is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=y +CONFIG_BLK_DEV_RAM_SIZE=131072 +CONFIG_BLK_DEV_RAM=y  CONFIG_BSD_PROCESS_ACCT=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_CGROUPS=y -CONFIG_CPUSETS=y  CONFIG_CGROUP_CPUACCT=y  CONFIG_CGROUP_SCHED=y -CONFIG_BLK_DEV_INITRD=y +CONFIG_CGROUPS=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_CRC_T10DIF=y +CONFIG_CPUSETS=y +CONFIG_CRAMFS=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_SHIRQ=y +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DEVTMPFS=y +CONFIG_DUMMY=y +CONFIG_EFS_FS=m  CONFIG_EXPERT=y -CONFIG_KALLSYMS_ALL=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_MODVERSIONS=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_PARTITION_ADVANCED=y -CONFIG_MAC_PARTITION=y -CONFIG_CORENET_GENERIC=y -# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set -CONFIG_BINFMT_MISC=m -CONFIG_MATH_EMULATION=y -CONFIG_MATH_EMULATION_HW_UNIMPLEMENTED=y -CONFIG_PCIEPORTBUS=y -CONFIG_PCI_MSI=y -CONFIG_RAPIDIO=y -CONFIG_FSL_RIO=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=y +CONFIG_EXT2_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS=y +CONFIG_FB=y +CONFIG_FHANDLE=y +CONFIG_FIXED_PHY=y +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FONTS=y +CONFIG_FORCE_MAX_ZONEORDER=13 +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAME_WARN=1024 +CONFIG_FTL=y +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_HIGH_RES_TIMERS=y +CONFIG_HPFS_FS=m +CONFIG_HUGETLBFS=y +CONFIG_IKCONFIG_PROC=y +CONFIG_IKCONFIG=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +# CONFIG_INET_LRO is not set +# CONFIG_INET_XFRM_MODE_BEET is not set  CONFIG_INET=y -CONFIG_IP_MULTICAST=y  CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=y  CONFIG_IP_MROUTE=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y  CONFIG_IP_PIMSM_V1=y  CONFIG_IP_PIMSM_V2=y -CONFIG_INET_ESP=y -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -CONFIG_IPV6=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_RARP=y +CONFIG_IP_PNP=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y  CONFIG_IP_SCTP=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_FTL=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP_OF=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_FSL_ELBC=y -CONFIG_MTD_NAND_FSL_IFC=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_EEPROM_LEGACY=y -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_CHR_DEV_SG=y -CONFIG_ATA=y -CONFIG_SATA_FSL=y -CONFIG_SATA_SIL24=y -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -CONFIG_FSL_PQ_MDIO=y -CONFIG_FSL_XGMAC_MDIO=y -CONFIG_E1000E=y -CONFIG_VITESSE_PHY=y -CONFIG_FIXED_PHY=y -CONFIG_MDIO_BUS_MUX_GPIO=y -CONFIG_MDIO_BUS_MUX_MMIOREG=y -CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_SERIO_LIBPS2=y -CONFIG_PPC_EPAPR_HV_BYTECHAN=y -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MPC=y -CONFIG_I2C_MUX=y -CONFIG_I2C_MUX_PCA954x=y -CONFIG_SPI=y -CONFIG_SPI_GPIO=y -CONFIG_SPI_FSL_SPI=y -CONFIG_SPI_FSL_ESPI=y -CONFIG_SENSORS_LM90=y -CONFIG_SENSORS_INA2XX=y -CONFIG_USB_HID=m -CONFIG_USB=y -CONFIG_USB_MON=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_FSL=y -CONFIG_USB_STORAGE=y -CONFIG_MMC=y -CONFIG_MMC_SDHCI=y -CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_DS1307=y -CONFIG_RTC_DRV_DS1374=y -CONFIG_RTC_DRV_DS3232=y -CONFIG_DMADEVICES=y -CONFIG_FSL_DMA=y -CONFIG_VIRT_DRIVERS=y -CONFIG_FSL_HV_MANAGER=y -CONFIG_CLK_QORIQ=y -CONFIG_FSL_CORENET_CF=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y +CONFIG_IPV6=y +CONFIG_IRQ_DOMAIN_DEBUG=y  CONFIG_ISO9660_FS=m +CONFIG_JFFS2_FS_DEBUG=1 +CONFIG_JFFS2_FS=y  CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=m +CONFIG_KALLSYMS_ALL=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_MAC_PARTITION=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y  CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=y -CONFIG_NTFS_FS=y -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_HUGETLBFS=y -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=1 -CONFIG_UBIFS_FS=y +CONFIG_MTD_UBI=y +CONFIG_MTD=y +CONFIG_NET_IPIP=y +CONFIG_NET_KEY_MIGRATE=y +CONFIG_NET_KEY=y +CONFIG_NET=y +CONFIG_NFSD=y  CONFIG_NFS_FS=y  CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=m  CONFIG_NLS_CODEPAGE_437=y  CONFIG_NLS_CODEPAGE_850=y  CONFIG_NLS_ISO8859_1=y  CONFIG_NLS_UTF8=m -CONFIG_CRC_T10DIF=y -CONFIG_DEBUG_INFO=y -CONFIG_FRAME_WARN=1024 -CONFIG_DEBUG_FS=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_SHIRQ=y -CONFIG_DETECT_HUNG_TASK=y -CONFIG_CRYPTO_NULL=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_DEV_FSL_CAAM=y +CONFIG_NO_HZ=y +CONFIG_NTFS_FS=y +CONFIG_PACKET=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_PERF_EVENTS=y +CONFIG_POSIX_MQUEUE=y +CONFIG_QNX4FS_FS=m +CONFIG_RCU_TRACE=y +CONFIG_ROOT_NFS=y +CONFIG_SYSV_FS=m +CONFIG_SYSVIPC=y +CONFIG_TMPFS=y +CONFIG_UBIFS_FS=y +CONFIG_UDF_FS=m +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_UFS_FS=m +CONFIG_UIO=y +CONFIG_UNIX=y +CONFIG_VFAT_FS=y +CONFIG_VXFS_FS=m +CONFIG_XFRM_STATISTICS=y +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_USER=y +CONFIG_ZISOFS=y diff --git a/arch/powerpc/configs/mpc85xx_basic_defconfig b/arch/powerpc/configs/mpc85xx_basic_defconfig new file mode 100644 index 000000000000..850bd195d0e8 --- /dev/null +++ b/arch/powerpc/configs/mpc85xx_basic_defconfig @@ -0,0 +1,23 @@ +CONFIG_MATH_EMULATION=y +CONFIG_MPC8536_DS=y +CONFIG_MPC8540_ADS=y +CONFIG_MPC8560_ADS=y +CONFIG_MPC85xx_CDS=y +CONFIG_MPC85xx_DS=y +CONFIG_MPC85xx_MDS=y +CONFIG_MPC85xx_RDB=y +CONFIG_KSI8560=y +CONFIG_MVME2500=y +CONFIG_P1010_RDB=y +CONFIG_P1022_DS=y +CONFIG_P1022_RDK=y +CONFIG_P1023_RDB=y +CONFIG_SBC8548=y +CONFIG_SOCRATES=y +CONFIG_STX_GP3=y +CONFIG_TQM8540=y +CONFIG_TQM8541=y +CONFIG_TQM8548=y +CONFIG_TQM8555=y +CONFIG_TQM8560=y +CONFIG_XES_MPC85xx=y diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig deleted file mode 100644 index 6ecf7bdbc2f9..000000000000 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ /dev/null @@ -1,252 +0,0 @@ -CONFIG_PPC_85xx=y -CONFIG_PHYS_64BIT=y -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_AUDIT=y -CONFIG_IRQ_DOMAIN_DEBUG=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_EXPERT=y -CONFIG_KALLSYMS_ALL=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_MODVERSIONS=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_PARTITION_ADVANCED=y -CONFIG_MAC_PARTITION=y -CONFIG_C293_PCIE=y -CONFIG_MPC8540_ADS=y -CONFIG_MPC8560_ADS=y -CONFIG_MPC85xx_CDS=y -CONFIG_MPC85xx_MDS=y -CONFIG_MPC8536_DS=y -CONFIG_MPC85xx_DS=y -CONFIG_MPC85xx_RDB=y -CONFIG_P1010_RDB=y -CONFIG_P1022_DS=y -CONFIG_P1022_RDK=y -CONFIG_P1023_RDB=y -CONFIG_SOCRATES=y -CONFIG_KSI8560=y -CONFIG_XES_MPC85xx=y -CONFIG_STX_GP3=y -CONFIG_TQM8540=y -CONFIG_TQM8541=y -CONFIG_TQM8548=y -CONFIG_TQM8555=y -CONFIG_TQM8560=y -CONFIG_SBC8548=y -CONFIG_MVME2500=y -CONFIG_QUICC_ENGINE=y -CONFIG_QE_GPIO=y -CONFIG_HIGHMEM=y -CONFIG_BINFMT_MISC=m -CONFIG_MATH_EMULATION=y -CONFIG_FORCE_MAX_ZONEORDER=12 -CONFIG_PCI=y -CONFIG_PCIEPORTBUS=y -# CONFIG_PCIEASPM is not set -CONFIG_PCI_MSI=y -CONFIG_RAPIDIO=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_INET_ESP=y -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -CONFIG_IPV6=y -CONFIG_IP_SCTP=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_FTL=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_OF=y -CONFIG_MTD_PLATRAM=y -CONFIG_MTD_M25P80=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_FSL_ELBC=y -CONFIG_MTD_NAND_FSL_IFC=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_NBD=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_EEPROM_AT24=y -CONFIG_EEPROM_LEGACY=y -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -CONFIG_BLK_DEV_SR=y -CONFIG_CHR_DEV_SG=y -CONFIG_SCSI_LOGGING=y -CONFIG_ATA=y -CONFIG_SATA_AHCI=y -CONFIG_SATA_FSL=y -CONFIG_SATA_SIL24=y -CONFIG_PATA_ALI=y -CONFIG_PATA_VIA=y -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -CONFIG_FS_ENET=y -CONFIG_UCC_GETH=y -CONFIG_GIANFAR=y -CONFIG_E1000=y -CONFIG_E1000E=y -CONFIG_IGB=y -CONFIG_AT803X_PHY=y -CONFIG_MARVELL_PHY=y -CONFIG_DAVICOM_PHY=y -CONFIG_CICADA_PHY=y -CONFIG_VITESSE_PHY=y -CONFIG_BROADCOM_PHY=y -CONFIG_FIXED_PHY=y -CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_SERIO_LIBPS2=y -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=6 -CONFIG_SERIAL_8250_RUNTIME_UARTS=6 -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y -CONFIG_SERIAL_QE=m -CONFIG_NVRAM=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_CPM=m -CONFIG_I2C_MPC=y -CONFIG_SPI=y -CONFIG_SPI_FSL_SPI=y -CONFIG_SPI_FSL_ESPI=y -CONFIG_GPIO_MPC8XXX=y -CONFIG_SENSORS_LM90=y -CONFIG_FB=y -CONFIG_FB_FSL_DIU=y -# CONFIG_VGA_CONSOLE is not set -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_SOUND=y -CONFIG_SND=y -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_DRIVERS is not set -CONFIG_SND_INTEL8X0=y -# CONFIG_SND_PPC is not set -# CONFIG_SND_USB is not set -CONFIG_SND_SOC=y -CONFIG_SND_POWERPC_SOC=y -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_EZKEY=y -CONFIG_HID_GYRATION=y -CONFIG_HID_LOGITECH=y -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y -CONFIG_HID_PANTHERLORD=y -CONFIG_HID_PETALYNX=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SUNPLUS=y -CONFIG_USB=y -CONFIG_USB_MON=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_FSL=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_HCD_PPC_OF_BE=y -CONFIG_USB_OHCI_HCD_PPC_OF_LE=y -CONFIG_USB_STORAGE=y -CONFIG_MMC=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MMC_SDHCI_OF_ESDHC=y -CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=y -CONFIG_EDAC_MPC85XX=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_DS1307=y -CONFIG_RTC_DRV_DS1374=y -CONFIG_RTC_DRV_DS3232=y -CONFIG_RTC_DRV_CMOS=y -CONFIG_DMADEVICES=y -CONFIG_FSL_DMA=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=y -CONFIG_NTFS_FS=y -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_HUGETLBFS=y -CONFIG_ADFS_FS=m -CONFIG_AFFS_FS=m -CONFIG_HFS_FS=m -CONFIG_HFSPLUS_FS=m -CONFIG_BEFS_FS=m -CONFIG_BFS_FS=m -CONFIG_EFS_FS=m -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=1 -CONFIG_UBIFS_FS=y -CONFIG_CRAMFS=y -CONFIG_VXFS_FS=m -CONFIG_HPFS_FS=m -CONFIG_QNX4FS_FS=m -CONFIG_SYSV_FS=m -CONFIG_UFS_FS=m -CONFIG_NFS_FS=y -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_CRC_T10DIF=y -CONFIG_FONTS=y -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y -CONFIG_DETECT_HUNG_TASK=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_DEV_FSL_CAAM=y -CONFIG_CRYPTO_DEV_TALITOS=y diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig deleted file mode 100644 index b6c7111ea913..000000000000 --- a/arch/powerpc/configs/mpc85xx_smp_defconfig +++ /dev/null @@ -1,244 +0,0 @@ -CONFIG_PPC_85xx=y -CONFIG_PHYS_64BIT=y -CONFIG_SMP=y -CONFIG_NR_CPUS=8 -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_AUDIT=y -CONFIG_IRQ_DOMAIN_DEBUG=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_EXPERT=y -CONFIG_KALLSYMS_ALL=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_MODVERSIONS=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_PARTITION_ADVANCED=y -CONFIG_MAC_PARTITION=y -CONFIG_C293_PCIE=y -CONFIG_MPC8540_ADS=y -CONFIG_MPC8560_ADS=y -CONFIG_MPC85xx_CDS=y -CONFIG_MPC85xx_MDS=y -CONFIG_MPC8536_DS=y -CONFIG_MPC85xx_DS=y -CONFIG_MPC85xx_RDB=y -CONFIG_P1010_RDB=y -CONFIG_P1022_DS=y -CONFIG_P1022_RDK=y -CONFIG_P1023_RDB=y -CONFIG_SOCRATES=y -CONFIG_KSI8560=y -CONFIG_XES_MPC85xx=y -CONFIG_STX_GP3=y -CONFIG_TQM8540=y -CONFIG_TQM8541=y -CONFIG_TQM8548=y -CONFIG_TQM8555=y -CONFIG_TQM8560=y -CONFIG_SBC8548=y -CONFIG_QUICC_ENGINE=y -CONFIG_QE_GPIO=y -CONFIG_HIGHMEM=y -CONFIG_BINFMT_MISC=m -CONFIG_MATH_EMULATION=y -CONFIG_FORCE_MAX_ZONEORDER=12 -CONFIG_PCI=y -CONFIG_PCI_MSI=y -CONFIG_RAPIDIO=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_INET_ESP=y -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -CONFIG_IPV6=y -CONFIG_IP_SCTP=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_FTL=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP_OF=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_FSL_ELBC=y -CONFIG_MTD_NAND_FSL_IFC=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_NBD=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_EEPROM_AT24=y -CONFIG_EEPROM_LEGACY=y -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -CONFIG_BLK_DEV_SR=y -CONFIG_CHR_DEV_SG=y -CONFIG_SCSI_LOGGING=y -CONFIG_ATA=y -CONFIG_SATA_AHCI=y -CONFIG_SATA_FSL=y -CONFIG_SATA_SIL24=y -CONFIG_PATA_ALI=y -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -CONFIG_FS_ENET=y -CONFIG_UCC_GETH=y -CONFIG_GIANFAR=y -CONFIG_E1000E=y -CONFIG_AT803X_PHY=y -CONFIG_MARVELL_PHY=y -CONFIG_DAVICOM_PHY=y -CONFIG_CICADA_PHY=y -CONFIG_VITESSE_PHY=y -CONFIG_FIXED_PHY=y -CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_SERIO_LIBPS2=y -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y -CONFIG_SERIAL_QE=m -CONFIG_NVRAM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_CPM=m -CONFIG_I2C_MPC=y -CONFIG_SPI=y -CONFIG_SPI_FSL_SPI=y -CONFIG_SPI_FSL_ESPI=y -CONFIG_GPIO_MPC8XXX=y -CONFIG_SENSORS_LM90=y -CONFIG_FB=y -CONFIG_FB_FSL_DIU=y -# CONFIG_VGA_CONSOLE is not set -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_SOUND=y -CONFIG_SND=y -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_DRIVERS is not set -CONFIG_SND_INTEL8X0=y -# CONFIG_SND_PPC is not set -# CONFIG_SND_USB is not set -CONFIG_SND_SOC=y -CONFIG_SND_POWERPC_SOC=y -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_EZKEY=y -CONFIG_HID_GYRATION=y -CONFIG_HID_LOGITECH=y -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y -CONFIG_HID_PANTHERLORD=y -CONFIG_HID_PETALYNX=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SUNPLUS=y -CONFIG_USB=y -CONFIG_USB_MON=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_FSL=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_HCD_PPC_OF_BE=y -CONFIG_USB_OHCI_HCD_PPC_OF_LE=y -CONFIG_USB_STORAGE=y -CONFIG_MMC=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MMC_SDHCI_OF_ESDHC=y -CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_DS1307=y -CONFIG_RTC_DRV_DS1374=y -CONFIG_RTC_DRV_DS3232=y -CONFIG_RTC_DRV_CMOS=y -CONFIG_DMADEVICES=y -CONFIG_FSL_DMA=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=y -CONFIG_NTFS_FS=y -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_HUGETLBFS=y -CONFIG_ADFS_FS=m -CONFIG_AFFS_FS=m -CONFIG_HFS_FS=m -CONFIG_HFSPLUS_FS=m -CONFIG_BEFS_FS=m -CONFIG_BFS_FS=m -CONFIG_EFS_FS=m -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=1 -CONFIG_UBIFS_FS=y -CONFIG_CRAMFS=y -CONFIG_VXFS_FS=m -CONFIG_HPFS_FS=m -CONFIG_QNX4FS_FS=m -CONFIG_SYSV_FS=m -CONFIG_UFS_FS=m -CONFIG_NFS_FS=y -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_CRC_T10DIF=y -CONFIG_FONTS=y -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y -CONFIG_DETECT_HUNG_TASK=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_DEV_FSL_CAAM=y -CONFIG_CRYPTO_DEV_TALITOS=y diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index a97efc2146fd..6bc0ee4b1070 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -355,3 +355,6 @@ CONFIG_CRYPTO_DEV_NX_ENCRYPT=m  CONFIG_VIRTUALIZATION=y  CONFIG_KVM_BOOK3S_64=m  CONFIG_KVM_BOOK3S_64_HV=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_POWERNV=m diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 0d9efcedaf34..7991f37e5fe2 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -190,7 +190,8 @@ CONFIG_HVC_RTAS=y  CONFIG_HVCS=m  CONFIG_VIRTIO_CONSOLE=m  CONFIG_IBM_BSR=m -CONFIG_GEN_RTC=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GENERIC=y  CONFIG_RAW_DRIVER=y  CONFIG_MAX_RAW_DEVS=1024  CONFIG_FB=y @@ -319,3 +320,6 @@ CONFIG_CRYPTO_DEV_NX_ENCRYPT=m  CONFIG_VIRTUALIZATION=y  CONFIG_KVM_BOOK3S_64=m  CONFIG_KVM_BOOK3S_64_HV=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_POWERNV=m diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild index 050712e1ce41..ab9f4e0ed4cf 100644 --- a/arch/powerpc/include/asm/Kbuild +++ b/arch/powerpc/include/asm/Kbuild @@ -6,5 +6,4 @@ generic-y += local64.h  generic-y += mcs_spinlock.h  generic-y += preempt.h  generic-y += rwsem.h -generic-y += trace_clock.h  generic-y += vtime.h diff --git a/arch/powerpc/include/asm/archrandom.h b/arch/powerpc/include/asm/archrandom.h index 0cc6eedc4780..85e88f7a59c0 100644 --- a/arch/powerpc/include/asm/archrandom.h +++ b/arch/powerpc/include/asm/archrandom.h @@ -7,14 +7,23 @@  static inline int arch_get_random_long(unsigned long *v)  { -	if (ppc_md.get_random_long) -		return ppc_md.get_random_long(v); -  	return 0;  }  static inline int arch_get_random_int(unsigned int *v)  { +	return 0; +} + +static inline int arch_get_random_seed_long(unsigned long *v) +{ +	if (ppc_md.get_random_seed) +		return ppc_md.get_random_seed(v); + +	return 0; +} +static inline int arch_get_random_seed_int(unsigned int *v) +{  	unsigned long val;  	int rc; @@ -27,22 +36,13 @@ static inline int arch_get_random_int(unsigned int *v)  static inline int arch_has_random(void)  { -	return !!ppc_md.get_random_long; -} - -static inline int arch_get_random_seed_long(unsigned long *v) -{ -	return 0; -} -static inline int arch_get_random_seed_int(unsigned int *v) -{  	return 0;  } +  static inline int arch_has_random_seed(void)  { -	return 0; +	return !!ppc_md.get_random_seed;  } -  #endif /* CONFIG_ARCH_RANDOM */  #ifdef CONFIG_PPC_POWERNV diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h index 512d2782b043..55f106ed12bf 100644 --- a/arch/powerpc/include/asm/atomic.h +++ b/arch/powerpc/include/asm/atomic.h @@ -67,6 +67,10 @@ static __inline__ int atomic_##op##_return(int a, atomic_t *v)		\  ATOMIC_OPS(add, add)  ATOMIC_OPS(sub, subf) +ATOMIC_OP(and, and) +ATOMIC_OP(or, or) +ATOMIC_OP(xor, xor) +  #undef ATOMIC_OPS  #undef ATOMIC_OP_RETURN  #undef ATOMIC_OP @@ -304,6 +308,9 @@ static __inline__ long atomic64_##op##_return(long a, atomic64_t *v)	\  ATOMIC64_OPS(add, add)  ATOMIC64_OPS(sub, subf) +ATOMIC64_OP(and, and) +ATOMIC64_OP(or, or) +ATOMIC64_OP(xor, xor)  #undef ATOMIC64_OPS  #undef ATOMIC64_OP_RETURN diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h index 51ccc7232042..0eca6efc0631 100644 --- a/arch/powerpc/include/asm/barrier.h +++ b/arch/powerpc/include/asm/barrier.h @@ -76,12 +76,12 @@  do {									\  	compiletime_assert_atomic_type(*p);				\  	smp_lwsync();							\ -	ACCESS_ONCE(*p) = (v);						\ +	WRITE_ONCE(*p, v);						\  } while (0)  #define smp_load_acquire(p)						\  ({									\ -	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\ +	typeof(*p) ___p1 = READ_ONCE(*p);				\  	compiletime_assert_atomic_type(*p);				\  	smp_lwsync();							\  	___p1;								\ diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 30b35fff2dea..6229e6b6037b 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -40,7 +40,12 @@ extern void __flush_dcache_icache(void *page_va);  extern void flush_dcache_icache_page(struct page *page);  #if defined(CONFIG_PPC32) && !defined(CONFIG_BOOKE)  extern void __flush_dcache_icache_phys(unsigned long physaddr); -#endif /* CONFIG_PPC32 && !CONFIG_BOOKE */ +#else +static inline void __flush_dcache_icache_phys(unsigned long physaddr) +{ +	BUG(); +} +#endif  extern void flush_dcache_range(unsigned long start, unsigned long stop);  #ifdef CONFIG_PPC32 diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h index 8251a3ba870f..e8d9ef4755a4 100644 --- a/arch/powerpc/include/asm/checksum.h +++ b/arch/powerpc/include/asm/checksum.h @@ -20,15 +20,6 @@  extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);  /* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -extern __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, -					unsigned short len, -					unsigned short proto, -					__wsum sum); - -/*   * computes the checksum of a memory block at buff, length len,   * and adds in "sum" (32-bit)   * @@ -127,6 +118,34 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,  #endif  } +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, +					unsigned short len, +					unsigned short proto, +					__wsum sum) +{ +	return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); +} + +#define HAVE_ARCH_CSUM_ADD +static inline __wsum csum_add(__wsum csum, __wsum addend) +{ +#ifdef __powerpc64__ +	u64 res = (__force u64)csum; + +	res += (__force u64)addend; +	return (__force __wsum)((u32)res + (res >> 32)); +#else +	asm("addc %0,%0,%1;" +	    "addze %0,%0;" +	    : "+r" (csum) : "r" (addend)); +	return csum; +#endif +} +  #endif  #endif /* __KERNEL__ */  #endif diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h index b142b8e0ed9e..4f2df589ec1d 100644 --- a/arch/powerpc/include/asm/compat.h +++ b/arch/powerpc/include/asm/compat.h @@ -174,6 +174,13 @@ typedef struct compat_siginfo {  			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */  			int _fd;  		} _sigpoll; + +		/* SIGSYS */ +		struct { +			unsigned int _call_addr; /* calling insn */ +			int _syscall;		 /* triggering system call number */ +			unsigned int _arch;	 /* AUDIT_ARCH_* of syscall */ +		} _sigsys;  	} _sifields;  } compat_siginfo_t; diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index e9bdda88f1fb..406c2b1ff82d 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -10,6 +10,7 @@ struct dma_map_ops;  struct device_node;  #ifdef CONFIG_PPC64  struct pci_dn; +struct iommu_table;  #endif  /* @@ -23,13 +24,15 @@ struct dev_archdata {  	struct dma_map_ops	*dma_ops;  	/* -	 * When an iommu is in use, dma_data is used as a ptr to the base of the -	 * iommu_table.  Otherwise, it is a simple numerical offset. +	 * These two used to be a union. However, with the hybrid ops we need +	 * both so here we store both a DMA offset for direct mappings and +	 * an iommu_table for remapped DMA.  	 */ -	union { -		dma_addr_t	dma_offset; -		void		*iommu_table_base; -	} dma_data; +	dma_addr_t		dma_offset; + +#ifdef CONFIG_PPC64 +	struct iommu_table	*iommu_table_base; +#endif  #ifdef CONFIG_IOMMU_API  	void			*iommu_domain; diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index 9103687b0436..7f522c021dc3 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -18,15 +18,17 @@  #include <asm/io.h>  #include <asm/swiotlb.h> +#ifdef CONFIG_PPC64  #define DMA_ERROR_CODE		(~(dma_addr_t)0x0) +#endif  /* Some dma direct funcs must be visible for use in other dma_ops */ -extern void *dma_direct_alloc_coherent(struct device *dev, size_t size, -				       dma_addr_t *dma_handle, gfp_t flag, +extern void *__dma_direct_alloc_coherent(struct device *dev, size_t size, +					 dma_addr_t *dma_handle, gfp_t flag, +					 struct dma_attrs *attrs); +extern void __dma_direct_free_coherent(struct device *dev, size_t size, +				       void *vaddr, dma_addr_t dma_handle,  				       struct dma_attrs *attrs); -extern void dma_direct_free_coherent(struct device *dev, size_t size, -				     void *vaddr, dma_addr_t dma_handle, -				     struct dma_attrs *attrs);  extern int dma_direct_mmap_coherent(struct device *dev,  				    struct vm_area_struct *vma,  				    void *cpu_addr, dma_addr_t handle, @@ -106,7 +108,7 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)  static inline dma_addr_t get_dma_offset(struct device *dev)  {  	if (dev) -		return dev->archdata.dma_data.dma_offset; +		return dev->archdata.dma_offset;  	return PCI_DRAM_OFFSET;  } @@ -114,77 +116,20 @@ static inline dma_addr_t get_dma_offset(struct device *dev)  static inline void set_dma_offset(struct device *dev, dma_addr_t off)  {  	if (dev) -		dev->archdata.dma_data.dma_offset = off; +		dev->archdata.dma_offset = off;  }  /* this will be removed soon */  #define flush_write_buffers() -#include <asm-generic/dma-mapping-common.h> - -static inline int dma_supported(struct device *dev, u64 mask) -{ -	struct dma_map_ops *dma_ops = get_dma_ops(dev); +#define HAVE_ARCH_DMA_SET_MASK 1 +extern int dma_set_mask(struct device *dev, u64 dma_mask); -	if (unlikely(dma_ops == NULL)) -		return 0; -	if (dma_ops->dma_supported == NULL) -		return 1; -	return dma_ops->dma_supported(dev, mask); -} +#include <asm-generic/dma-mapping-common.h> -extern int dma_set_mask(struct device *dev, u64 dma_mask);  extern int __dma_set_mask(struct device *dev, u64 dma_mask);  extern u64 __dma_get_required_mask(struct device *dev); -#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL) - -static inline void *dma_alloc_attrs(struct device *dev, size_t size, -				    dma_addr_t *dma_handle, gfp_t flag, -				    struct dma_attrs *attrs) -{ -	struct dma_map_ops *dma_ops = get_dma_ops(dev); -	void *cpu_addr; - -	BUG_ON(!dma_ops); - -	cpu_addr = dma_ops->alloc(dev, size, dma_handle, flag, attrs); - -	debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); - -	return cpu_addr; -} - -#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) - -static inline void dma_free_attrs(struct device *dev, size_t size, -				  void *cpu_addr, dma_addr_t dma_handle, -				  struct dma_attrs *attrs) -{ -	struct dma_map_ops *dma_ops = get_dma_ops(dev); - -	BUG_ON(!dma_ops); - -	debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); - -	dma_ops->free(dev, size, cpu_addr, dma_handle, attrs); -} - -static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) -{ -	struct dma_map_ops *dma_ops = get_dma_ops(dev); - -	debug_dma_mapping_error(dev, dma_addr); -	if (dma_ops->mapping_error) -		return dma_ops->mapping_error(dev, dma_addr); - -#ifdef CONFIG_PPC64 -	return (dma_addr == DMA_ERROR_CODE); -#else -	return 0; -#endif -} -  static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)  {  #ifdef CONFIG_SWIOTLB @@ -210,9 +155,6 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)  	return daddr - get_dma_offset(dev);  } -#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) -#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -  #define ARCH_HAS_DMA_MMAP_COHERENT  static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h index e3661872fbea..ef89b1465573 100644 --- a/arch/powerpc/include/asm/ftrace.h +++ b/arch/powerpc/include/asm/ftrace.h @@ -2,7 +2,7 @@  #define _ASM_POWERPC_FTRACE  #ifdef CONFIG_FUNCTION_TRACER -#define MCOUNT_ADDR		((long)(_mcount)) +#define MCOUNT_ADDR		((unsigned long)(_mcount))  #define MCOUNT_INSN_SIZE	4 /* sizeof mcount call */  #ifdef __ASSEMBLY__ diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index a8d2ef30d473..5879fde56f3c 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -721,6 +721,7 @@ extern void __iomem *ioremap_prot(phys_addr_t address, unsigned long size,  				  unsigned long flags);  extern void __iomem *ioremap_wc(phys_addr_t address, unsigned long size);  #define ioremap_nocache(addr, size)	ioremap((addr), (size)) +#define ioremap_uc(addr, size)		ioremap((addr), (size))  extern void iounmap(volatile void __iomem *addr); diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index ca18cff90900..7b87bab09564 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h @@ -2,17 +2,17 @@   * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation   * Rewrite, cleanup:   * Copyright (C) 2004 Olof Johansson <[email protected]>, IBM Corporation - *  + *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by   * the Free Software Foundation; either version 2 of the License, or   * (at your option) any later version. - *  + *   * This program is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * GNU General Public License for more details. - *  + *   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA @@ -131,16 +131,21 @@ int get_iommu_order(unsigned long size, struct iommu_table *tbl)  struct scatterlist; -static inline void set_iommu_table_base(struct device *dev, void *base) +#ifdef CONFIG_PPC64 + +static inline void set_iommu_table_base(struct device *dev, +					struct iommu_table *base)  { -	dev->archdata.dma_data.iommu_table_base = base; +	dev->archdata.iommu_table_base = base;  }  static inline void *get_iommu_table_base(struct device *dev)  { -	return dev->archdata.dma_data.iommu_table_base; +	return dev->archdata.iommu_table_base;  } +extern int dma_iommu_dma_supported(struct device *dev, u64 mask); +  /* Frees table for an individual device node */  extern void iommu_free_table(struct iommu_table *tbl, const char *node_name); @@ -225,6 +230,20 @@ static inline int __init tce_iommu_bus_notifier_init(void)  }  #endif /* !CONFIG_IOMMU_API */ +#else + +static inline void *get_iommu_table_base(struct device *dev) +{ +	return NULL; +} + +static inline int dma_iommu_dma_supported(struct device *dev, u64 mask) +{ +	return 0; +} + +#endif /* CONFIG_PPC64 */ +  extern int ppc_iommu_map_sg(struct device *dev, struct iommu_table *tbl,  			    struct scatterlist *sglist, int nelems,  			    unsigned long mask, diff --git a/arch/powerpc/include/asm/jump_label.h b/arch/powerpc/include/asm/jump_label.h index efbf9a322a23..47e155f15433 100644 --- a/arch/powerpc/include/asm/jump_label.h +++ b/arch/powerpc/include/asm/jump_label.h @@ -18,14 +18,29 @@  #define JUMP_ENTRY_TYPE		stringify_in_c(FTR_ENTRY_LONG)  #define JUMP_LABEL_NOP_SIZE	4 -static __always_inline bool arch_static_branch(struct static_key *key) +static __always_inline bool arch_static_branch(struct static_key *key, bool branch)  {  	asm_volatile_goto("1:\n\t"  		 "nop\n\t"  		 ".pushsection __jump_table,  \"aw\"\n\t"  		 JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t"  		 ".popsection \n\t" -		 : :  "i" (key) : : l_yes); +		 : :  "i" (&((char *)key)[branch]) : : l_yes); + +	return false; +l_yes: +	return true; +} + +static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) +{ +	asm_volatile_goto("1:\n\t" +		 "b %l[l_yes]\n\t" +		 ".pushsection __jump_table,  \"aw\"\n\t" +		 JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t" +		 ".popsection \n\t" +		 : :  "i" (&((char *)key)[branch]) : : l_yes); +  	return false;  l_yes:  	return true; diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index b91e74a817d8..9fac01cb89c1 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -158,6 +158,7 @@ extern pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa, bool writing,  			bool *writable);  extern void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev,  			unsigned long *rmap, long pte_index, int realmode); +extern void kvmppc_update_rmap_change(unsigned long *rmap, unsigned long psize);  extern void kvmppc_invalidate_hpte(struct kvm *kvm, __be64 *hptep,  			unsigned long pte_index);  void kvmppc_clear_ref_hpte(struct kvm *kvm, __be64 *hptep, @@ -225,12 +226,12 @@ static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu)  	return vcpu->arch.cr;  } -static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val) +static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, ulong val)  {  	vcpu->arch.xer = val;  } -static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu) +static inline ulong kvmppc_get_xer(struct kvm_vcpu *vcpu)  {  	return vcpu->arch.xer;  } diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h index 5bdfb5dd3400..72b6225aca73 100644 --- a/arch/powerpc/include/asm/kvm_book3s_asm.h +++ b/arch/powerpc/include/asm/kvm_book3s_asm.h @@ -25,6 +25,12 @@  #define XICS_MFRR		0xc  #define XICS_IPI		2	/* interrupt source # for IPIs */ +/* Maximum number of threads per physical core */ +#define MAX_SMT_THREADS		8 + +/* Maximum number of subcores per physical core */ +#define MAX_SUBCORES		4 +  #ifdef __ASSEMBLY__  #ifdef CONFIG_KVM_BOOK3S_HANDLER @@ -65,6 +71,19 @@ kvmppc_resume_\intno:  #else  /*__ASSEMBLY__ */ +struct kvmppc_vcore; + +/* Struct used for coordinating micro-threading (split-core) mode changes */ +struct kvm_split_mode { +	unsigned long	rpr; +	unsigned long	pmmar; +	unsigned long	ldbar; +	u8		subcore_size; +	u8		do_nap; +	u8		napped[MAX_SMT_THREADS]; +	struct kvmppc_vcore *master_vcs[MAX_SUBCORES]; +}; +  /*   * This struct goes in the PACA on 64-bit processors.  It is used   * to store host state that needs to be saved when we enter a guest @@ -100,6 +119,7 @@ struct kvmppc_host_state {  	u64 host_spurr;  	u64 host_dscr;  	u64 dec_expires; +	struct kvm_split_mode *kvm_split_mode;  #endif  #ifdef CONFIG_PPC_BOOK3S_64  	u64 cfar; @@ -112,7 +132,7 @@ struct kvmppc_book3s_shadow_vcpu {  	bool in_use;  	ulong gpr[14];  	u32 cr; -	u32 xer; +	ulong xer;  	ulong ctr;  	ulong lr;  	ulong pc; diff --git a/arch/powerpc/include/asm/kvm_booke.h b/arch/powerpc/include/asm/kvm_booke.h index 3286f0d6a86c..bc6e29e4dfd4 100644 --- a/arch/powerpc/include/asm/kvm_booke.h +++ b/arch/powerpc/include/asm/kvm_booke.h @@ -54,12 +54,12 @@ static inline u32 kvmppc_get_cr(struct kvm_vcpu *vcpu)  	return vcpu->arch.cr;  } -static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, u32 val) +static inline void kvmppc_set_xer(struct kvm_vcpu *vcpu, ulong val)  {  	vcpu->arch.xer = val;  } -static inline u32 kvmppc_get_xer(struct kvm_vcpu *vcpu) +static inline ulong kvmppc_get_xer(struct kvm_vcpu *vcpu)  {  	return vcpu->arch.xer;  } diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index d91f65b28e32..98eebbf66340 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -205,8 +205,10 @@ struct revmap_entry {   */  #define KVMPPC_RMAP_LOCK_BIT	63  #define KVMPPC_RMAP_RC_SHIFT	32 +#define KVMPPC_RMAP_CHG_SHIFT	48  #define KVMPPC_RMAP_REFERENCED	(HPTE_R_R << KVMPPC_RMAP_RC_SHIFT)  #define KVMPPC_RMAP_CHANGED	(HPTE_R_C << KVMPPC_RMAP_RC_SHIFT) +#define KVMPPC_RMAP_CHG_ORDER	(0x3ful << KVMPPC_RMAP_CHG_SHIFT)  #define KVMPPC_RMAP_PRESENT	0x100000000ul  #define KVMPPC_RMAP_INDEX	0xfffffffful @@ -278,7 +280,9 @@ struct kvmppc_vcore {  	u16 last_cpu;  	u8 vcore_state;  	u8 in_guest; +	struct kvmppc_vcore *master_vcore;  	struct list_head runnable_threads; +	struct list_head preempt_list;  	spinlock_t lock;  	wait_queue_head_t wq;  	spinlock_t stoltb_lock;	/* protects stolen_tb and preempt_tb */ @@ -300,12 +304,21 @@ struct kvmppc_vcore {  #define VCORE_EXIT_MAP(vc)	((vc)->entry_exit_map >> 8)  #define VCORE_IS_EXITING(vc)	(VCORE_EXIT_MAP(vc) != 0) -/* Values for vcore_state */ +/* This bit is used when a vcore exit is triggered from outside the vcore */ +#define VCORE_EXIT_REQ		0x10000 + +/* + * Values for vcore_state. + * Note that these are arranged such that lower values + * (< VCORE_SLEEPING) don't require stolen time accounting + * on load/unload, and higher values do. + */  #define VCORE_INACTIVE	0 -#define VCORE_SLEEPING	1 -#define VCORE_PREEMPT	2 -#define VCORE_RUNNING	3 -#define VCORE_EXITING	4 +#define VCORE_PREEMPT	1 +#define VCORE_PIGGYBACK	2 +#define VCORE_SLEEPING	3 +#define VCORE_RUNNING	4 +#define VCORE_EXITING	5  /*   * Struct used to manage memory for a virtual processor area @@ -473,7 +486,7 @@ struct kvm_vcpu_arch {  	ulong ciabr;  	ulong cfar;  	ulong ppr; -	ulong pspb; +	u32 pspb;  	ulong fscr;  	ulong shadow_fscr;  	ulong ebbhr; @@ -619,6 +632,7 @@ struct kvm_vcpu_arch {  	int trap;  	int state;  	int ptid; +	int thread_cpu;  	bool timer_running;  	wait_queue_head_t cpu_run; diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 952579f5e79a..cab6753f1be5 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -249,7 +249,7 @@ struct machdep_calls {  #endif  #ifdef CONFIG_ARCH_RANDOM -	int (*get_random_long)(unsigned long *v); +	int (*get_random_seed)(unsigned long *v);  #endif  }; diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h b/arch/powerpc/include/asm/mpc52xx_psc.h index d0ece257d310..04c7e8fc24c2 100644 --- a/arch/powerpc/include/asm/mpc52xx_psc.h +++ b/arch/powerpc/include/asm/mpc52xx_psc.h @@ -150,7 +150,10 @@  /* Structure of the hardware registers */  struct mpc52xx_psc { -	u8		mode;		/* PSC + 0x00 */ +	union { +		u8	mode;		/* PSC + 0x00 */ +		u8	mr2; +	};  	u8		reserved0[3];  	union {				/* PSC + 0x04 */  		u16	status; diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index e9e4c52f3685..8374afed9d0a 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -154,7 +154,10 @@  #define OPAL_FLASH_WRITE			111  #define OPAL_FLASH_ERASE			112  #define OPAL_PRD_MSG				113 -#define OPAL_LAST				113 +#define OPAL_LEDS_GET_INDICATOR			114 +#define OPAL_LEDS_SET_INDICATOR			115 +#define OPAL_CEC_REBOOT2			116 +#define OPAL_LAST				116  /* Device tree flags */ @@ -340,6 +343,18 @@ enum OpalPciResetState {  	OPAL_ASSERT_RESET   = 1  }; +enum OpalSlotLedType { +	OPAL_SLOT_LED_TYPE_ID = 0,	/* IDENTIFY LED */ +	OPAL_SLOT_LED_TYPE_FAULT = 1,	/* FAULT LED */ +	OPAL_SLOT_LED_TYPE_ATTN = 2,	/* System Attention LED */ +	OPAL_SLOT_LED_TYPE_MAX = 3 +}; + +enum OpalSlotLedState { +	OPAL_SLOT_LED_STATE_OFF = 0,	/* LED is OFF */ +	OPAL_SLOT_LED_STATE_ON = 1	/* LED is ON */ +}; +  /*   * Address cycle types for LPC accesses. These also correspond   * to the content of the first cell of the "reg" property for @@ -361,6 +376,7 @@ enum opal_msg_type {  	OPAL_MSG_HMI_EVT,  	OPAL_MSG_DPO,  	OPAL_MSG_PRD, +	OPAL_MSG_OCC,  	OPAL_MSG_TYPE_MAX,  }; @@ -437,6 +453,7 @@ struct OpalMemoryErrorData {  /* HMI interrupt event */  enum OpalHMI_Version {  	OpalHMIEvt_V1 = 1, +	OpalHMIEvt_V2 = 2,  };  enum OpalHMI_Severity { @@ -467,6 +484,49 @@ enum OpalHMI_ErrType {  	OpalHMI_ERROR_CAPP_RECOVERY,  }; +enum OpalHMI_XstopType { +	CHECKSTOP_TYPE_UNKNOWN	=	0, +	CHECKSTOP_TYPE_CORE	=	1, +	CHECKSTOP_TYPE_NX	=	2, +}; + +enum OpalHMI_CoreXstopReason { +	CORE_CHECKSTOP_IFU_REGFILE		= 0x00000001, +	CORE_CHECKSTOP_IFU_LOGIC		= 0x00000002, +	CORE_CHECKSTOP_PC_DURING_RECOV		= 0x00000004, +	CORE_CHECKSTOP_ISU_REGFILE		= 0x00000008, +	CORE_CHECKSTOP_ISU_LOGIC		= 0x00000010, +	CORE_CHECKSTOP_FXU_LOGIC		= 0x00000020, +	CORE_CHECKSTOP_VSU_LOGIC		= 0x00000040, +	CORE_CHECKSTOP_PC_RECOV_IN_MAINT_MODE	= 0x00000080, +	CORE_CHECKSTOP_LSU_REGFILE		= 0x00000100, +	CORE_CHECKSTOP_PC_FWD_PROGRESS		= 0x00000200, +	CORE_CHECKSTOP_LSU_LOGIC		= 0x00000400, +	CORE_CHECKSTOP_PC_LOGIC			= 0x00000800, +	CORE_CHECKSTOP_PC_HYP_RESOURCE		= 0x00001000, +	CORE_CHECKSTOP_PC_HANG_RECOV_FAILED	= 0x00002000, +	CORE_CHECKSTOP_PC_AMBI_HANG_DETECTED	= 0x00004000, +	CORE_CHECKSTOP_PC_DEBUG_TRIG_ERR_INJ	= 0x00008000, +	CORE_CHECKSTOP_PC_SPRD_HYP_ERR_INJ	= 0x00010000, +}; + +enum OpalHMI_NestAccelXstopReason { +	NX_CHECKSTOP_SHM_INVAL_STATE_ERR	= 0x00000001, +	NX_CHECKSTOP_DMA_INVAL_STATE_ERR_1	= 0x00000002, +	NX_CHECKSTOP_DMA_INVAL_STATE_ERR_2	= 0x00000004, +	NX_CHECKSTOP_DMA_CH0_INVAL_STATE_ERR	= 0x00000008, +	NX_CHECKSTOP_DMA_CH1_INVAL_STATE_ERR	= 0x00000010, +	NX_CHECKSTOP_DMA_CH2_INVAL_STATE_ERR	= 0x00000020, +	NX_CHECKSTOP_DMA_CH3_INVAL_STATE_ERR	= 0x00000040, +	NX_CHECKSTOP_DMA_CH4_INVAL_STATE_ERR	= 0x00000080, +	NX_CHECKSTOP_DMA_CH5_INVAL_STATE_ERR	= 0x00000100, +	NX_CHECKSTOP_DMA_CH6_INVAL_STATE_ERR	= 0x00000200, +	NX_CHECKSTOP_DMA_CH7_INVAL_STATE_ERR	= 0x00000400, +	NX_CHECKSTOP_DMA_CRB_UE			= 0x00000800, +	NX_CHECKSTOP_DMA_CRB_SUE		= 0x00001000, +	NX_CHECKSTOP_PBI_ISN_UE			= 0x00002000, +}; +  struct OpalHMIEvent {  	uint8_t		version;	/* 0x00 */  	uint8_t		severity;	/* 0x01 */ @@ -477,6 +537,23 @@ struct OpalHMIEvent {  	__be64		hmer;  	/* TFMR register. Valid only for TFAC and TFMR_PARITY error type. */  	__be64		tfmr; + +	/* version 2 and later */ +	union { +		/* +		 * checkstop info (Core/NX). +		 * Valid for OpalHMI_ERROR_MALFUNC_ALERT. +		 */ +		struct { +			uint8_t	xstop_type;	/* enum OpalHMI_XstopType */ +			uint8_t reserved_1[3]; +			__be32  xstop_reason; +			union { +				__be32 pir;	/* for CHECKSTOP_TYPE_CORE */ +				__be32 chip_id;	/* for CHECKSTOP_TYPE_NX */ +			} u; +		} xstop_error; +	} u;  };  enum { @@ -700,6 +777,17 @@ struct opal_prd_msg_header {  struct opal_prd_msg; +#define OCC_RESET                       0 +#define OCC_LOAD                        1 +#define OCC_THROTTLE                    2 +#define OCC_MAX_THROTTLE_STATUS         5 + +struct opal_occ_msg { +	__be64 type; +	__be64 chip; +	__be64 throttle_status; +}; +  /*   * SG entries   * @@ -756,6 +844,52 @@ struct opal_i2c_request {  	__be64 buffer_ra;		/* Buffer real address */  }; +/* + * EPOW status sharing (OPAL and the host) + * + * The host will pass on OPAL, a buffer of length OPAL_SYSEPOW_MAX + * with individual elements being 16 bits wide to fetch the system + * wide EPOW status. Each element in the buffer will contain the + * EPOW status in it's bit representation for a particular EPOW sub + * class as defiend here. So multiple detailed EPOW status bits + * specific for any sub class can be represented in a single buffer + * element as it's bit representation. + */ + +/* System EPOW type */ +enum OpalSysEpow { +	OPAL_SYSEPOW_POWER	= 0,	/* Power EPOW */ +	OPAL_SYSEPOW_TEMP	= 1,	/* Temperature EPOW */ +	OPAL_SYSEPOW_COOLING	= 2,	/* Cooling EPOW */ +	OPAL_SYSEPOW_MAX	= 3,	/* Max EPOW categories */ +}; + +/* Power EPOW */ +enum OpalSysPower { +	OPAL_SYSPOWER_UPS	= 0x0001, /* System on UPS power */ +	OPAL_SYSPOWER_CHNG	= 0x0002, /* System power config change */ +	OPAL_SYSPOWER_FAIL	= 0x0004, /* System impending power failure */ +	OPAL_SYSPOWER_INCL	= 0x0008, /* System incomplete power */ +}; + +/* Temperature EPOW */ +enum OpalSysTemp { +	OPAL_SYSTEMP_AMB	= 0x0001, /* System over ambient temperature */ +	OPAL_SYSTEMP_INT	= 0x0002, /* System over internal temperature */ +	OPAL_SYSTEMP_HMD	= 0x0004, /* System over ambient humidity */ +}; + +/* Cooling EPOW */ +enum OpalSysCooling { +	OPAL_SYSCOOL_INSF	= 0x0001, /* System insufficient cooling */ +}; + +/* Argument to OPAL_CEC_REBOOT2() */ +enum { +	OPAL_REBOOT_NORMAL		= 0, +	OPAL_REBOOT_PLATFORM_ERROR	= 1, +}; +  #endif /* __ASSEMBLY__ */  #endif /* __OPAL_API_H */ diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 958e941c0cda..800115910e43 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -44,6 +44,7 @@ int64_t opal_tpo_write(uint64_t token, uint32_t year_mon_day,  		       uint32_t hour_min);  int64_t opal_cec_power_down(uint64_t request);  int64_t opal_cec_reboot(void); +int64_t opal_cec_reboot2(uint32_t reboot_type, char *diag);  int64_t opal_read_nvram(uint64_t buffer, uint64_t size, uint64_t offset);  int64_t opal_write_nvram(uint64_t buffer, uint64_t size, uint64_t offset);  int64_t opal_handle_interrupt(uint64_t isn, __be64 *outstanding_event_mask); @@ -141,7 +142,8 @@ int64_t opal_pci_fence_phb(uint64_t phb_id);  int64_t opal_pci_reinit(uint64_t phb_id, uint64_t reinit_scope, uint64_t data);  int64_t opal_pci_mask_pe_error(uint64_t phb_id, uint16_t pe_number, uint8_t error_type, uint8_t mask_action);  int64_t opal_set_slot_led_status(uint64_t phb_id, uint64_t slot_id, uint8_t led_type, uint8_t led_action); -int64_t opal_get_epow_status(__be64 *status); +int64_t opal_get_epow_status(__be16 *epow_status, __be16 *num_epow_classes); +int64_t opal_get_dpo_status(__be64 *dpo_timeout);  int64_t opal_set_system_attention_led(uint8_t led_action);  int64_t opal_pci_next_error(uint64_t phb_id, __be64 *first_frozen_pe,  			    __be16 *pci_error_type, __be16 *severity); @@ -195,6 +197,10 @@ int64_t opal_ipmi_recv(uint64_t interface, struct opal_ipmi_msg *msg,  int64_t opal_i2c_request(uint64_t async_token, uint32_t bus_id,  			 struct opal_i2c_request *oreq);  int64_t opal_prd_msg(struct opal_prd_msg *msg); +int64_t opal_leds_get_ind(char *loc_code, __be64 *led_mask, +			  __be64 *led_value, __be64 *max_led_type); +int64_t opal_leds_set_ind(uint64_t token, char *loc_code, const u64 led_mask, +			  const u64 led_value, __be64 *max_led_type);  int64_t opal_flash_read(uint64_t id, uint64_t offset, uint64_t buf,  		uint64_t size, uint64_t token); diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 712add590445..37fc53587bb4 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -42,6 +42,7 @@ struct pci_controller_ops {  #endif  	int             (*dma_set_mask)(struct pci_dev *dev, u64 dma_mask); +	u64		(*dma_get_required_mask)(struct pci_dev *dev);  	void		(*shutdown)(struct pci_controller *);  }; diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h index 3bb7488bd24b..fa1dfb7f7b48 100644 --- a/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/arch/powerpc/include/asm/pgtable-ppc64.h @@ -134,11 +134,11 @@  #define pte_iterate_hashed_end() } while(0) -#ifdef CONFIG_PPC_HAS_HASH_64K -#define pte_pagesize_index(mm, addr, pte)	get_slice_psize(mm, addr) -#else +/* + * We expect this to be called only for user addresses or kernel virtual + * addresses other than the linear mapping. + */  #define pte_pagesize_index(mm, addr, pte)	MMU_PAGE_4K -#endif  #endif /* __real_pte */ diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index 11a38635dd65..0717693c8428 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h @@ -169,6 +169,17 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,  	 * cases, and 32-bit non-hash with 32-bit PTEs.  	 */  	*ptep = pte; + +#ifdef CONFIG_PPC_BOOK3E_64 +	/* +	 * With hardware tablewalk, a sync is needed to ensure that +	 * subsequent accesses see the PTE we just wrote.  Unlike userspace +	 * mappings, we can't tolerate spurious faults, so make sure +	 * the new PTE will be seen the first time. +	 */ +	if (is_kernel_addr(addr)) +		mb(); +#endif  #endif  } diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index 8452335661a5..790f5d1d9a46 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -287,7 +287,7 @@  /* POWER8 Micro Partition Prefetch (MPP) parameters */  /* Address mask is common for LOGMPP instruction and MPPR SPR */ -#define PPC_MPPE_ADDRESS_MASK 0xffffffffc000 +#define PPC_MPPE_ADDRESS_MASK 0xffffffffc000ULL  /* Bits 60 and 61 of MPP SPR should be set to one of the following */  /* Aborting the fetch is indeed setting 00 in the table size bits */ diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h index 4122a86d6858..ca0c5bff7849 100644 --- a/arch/powerpc/include/asm/ppc-pci.h +++ b/arch/powerpc/include/asm/ppc-pci.h @@ -61,6 +61,7 @@ int rtas_write_config(struct pci_dn *, int where, int size, u32 val);  int rtas_read_config(struct pci_dn *, int where, int size, u32 *val);  void eeh_pe_state_mark(struct eeh_pe *pe, int state);  void eeh_pe_state_clear(struct eeh_pe *pe, int state); +void eeh_pe_state_mark_with_cfg(struct eeh_pe *pe, int state);  void eeh_pe_dev_mode_mark(struct eeh_pe *pe, int mode);  void eeh_sysfs_add_device(struct pci_dev *pdev); diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 28ded5d9b579..5afea361beaa 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -264,7 +264,6 @@ struct thread_struct {  	u64		tm_tfhar;	/* Transaction fail handler addr */  	u64		tm_texasr;	/* Transaction exception & summary */  	u64		tm_tfiar;	/* Transaction fail instr address reg */ -	unsigned long	tm_orig_msr;	/* Thread's MSR on ctx switch */  	struct pt_regs	ckpt_regs;	/* Checkpointed registers */  	unsigned long	tm_tar; diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h index b7c8d079c121..71537a319fc8 100644 --- a/arch/powerpc/include/asm/pte-common.h +++ b/arch/powerpc/include/asm/pte-common.h @@ -109,7 +109,8 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);   * the processor might need it for DMA coherency.   */  #define _PAGE_BASE_NC	(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_PSIZE) -#if defined(CONFIG_SMP) || defined(CONFIG_PPC_STD_MMU) +#if defined(CONFIG_SMP) || defined(CONFIG_PPC_STD_MMU) || \ +	defined(CONFIG_PPC_E500MC)  #define _PAGE_BASE	(_PAGE_BASE_NC | _PAGE_COHERENT)  #else  #define _PAGE_BASE	(_PAGE_BASE_NC) diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index af56b5c6c81a..aa1cc5f015ee 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1193,8 +1193,7 @@  #ifdef CONFIG_PPC_BOOK3S_64  #define __mtmsrd(v, l)	asm volatile("mtmsrd %0," __stringify(l) \  				     : : "r" (v) : "memory") -#define mtmsrd(v)	__mtmsrd((v), 0) -#define mtmsr(v)	mtmsrd(v) +#define mtmsr(v)	__mtmsrd((v), 0)  #else  #define mtmsr(v)	asm volatile("mtmsr %0" : \  				     : "r" ((unsigned long)(v)) \ @@ -1281,6 +1280,15 @@ struct pt_regs;  extern void ppc_save_regs(struct pt_regs *regs); +static inline void update_power8_hid0(unsigned long hid0) +{ +	/* +	 *  The HID0 update on Power8 should at the very least be +	 *  preceded by a a SYNC instruction followed by an ISYNC +	 *  instruction +	 */ +	asm volatile("sync; mtspr %0,%1; isync":: "i"(SPRN_HID0), "r"(hid0)); +}  #endif /* __ASSEMBLY__ */  #endif /* __KERNEL__ */  #endif /* _ASM_POWERPC_REG_H */ diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index 7a4ede16b283..b77ef369c0f0 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h @@ -343,6 +343,7 @@ extern void rtas_power_off(void);  extern void rtas_halt(void);  extern void rtas_os_term(char *str);  extern int rtas_get_sensor(int sensor, int index, int *state); +extern int rtas_get_sensor_fast(int sensor, int index, int *state);  extern int rtas_get_power_level(int powerdomain, int *level);  extern int rtas_set_power_level(int powerdomain, int level, int *setlevel);  extern bool rtas_indicator_present(int token, int *maxindex); diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h index 4dbe072eecbe..523673d7583c 100644 --- a/arch/powerpc/include/asm/spinlock.h +++ b/arch/powerpc/include/asm/spinlock.h @@ -28,8 +28,6 @@  #include <asm/synch.h>  #include <asm/ppc-opcode.h> -#define smp_mb__after_unlock_lock()	smp_mb()  /* Full ordering for lock. */ -  #ifdef CONFIG_PPC64  /* use 0x800000yy when locked, where yy == CPU number */  #ifdef __BIG_ENDIAN__ diff --git a/arch/powerpc/include/asm/spu_csa.h b/arch/powerpc/include/asm/spu_csa.h index a40fd491250c..51f80b41cda3 100644 --- a/arch/powerpc/include/asm/spu_csa.h +++ b/arch/powerpc/include/asm/spu_csa.h @@ -241,12 +241,6 @@ struct spu_priv2_collapsed {   */  struct spu_state {  	struct spu_lscsa *lscsa; -#ifdef CONFIG_SPU_FS_64K_LS -	int		use_big_pages; -	/* One struct page per 64k page */ -#define SPU_LSCSA_NUM_BIG_PAGES	(sizeof(struct spu_lscsa) / 0x10000) -	struct page	*lscsa_pages[SPU_LSCSA_NUM_BIG_PAGES]; -#endif  	struct spu_problem_collapsed prob;  	struct spu_priv1_collapsed priv1;  	struct spu_priv2_collapsed priv2; diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 58abeda64cb7..15cca17cba4b 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -29,6 +29,7 @@ static inline void save_early_sprs(struct thread_struct *prev) {}  extern void enable_kernel_fp(void);  extern void enable_kernel_altivec(void); +extern void enable_kernel_vsx(void);  extern int emulate_altivec(struct pt_regs *);  extern void __giveup_vsx(struct task_struct *);  extern void giveup_vsx(struct task_struct *); diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h index ff21b7a2f0cc..ab9f3f0a8637 100644 --- a/arch/powerpc/include/asm/syscall.h +++ b/arch/powerpc/include/asm/syscall.h @@ -22,10 +22,15 @@  extern const unsigned long sys_call_table[];  #endif /* CONFIG_FTRACE_SYSCALLS */ -static inline long syscall_get_nr(struct task_struct *task, -				  struct pt_regs *regs) +static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)  { -	return TRAP(regs) == 0xc00 ? regs->gpr[0] : -1L; +	/* +	 * Note that we are returning an int here. That means 0xffffffff, ie. +	 * 32-bit negative 1, will be interpreted as -1 on a 64-bit kernel. +	 * This is important for seccomp so that compat tasks can set r0 = -1 +	 * to reject the syscall. +	 */ +	return TRAP(regs) == 0xc00 ? regs->gpr[0] : -1;  }  static inline void syscall_rollback(struct task_struct *task, @@ -34,12 +39,6 @@ static inline void syscall_rollback(struct task_struct *task,  	regs->gpr[3] = regs->orig_gpr3;  } -static inline long syscall_get_error(struct task_struct *task, -				     struct pt_regs *regs) -{ -	return (regs->ccr & 0x10000000) ? -regs->gpr[3] : 0; -} -  static inline long syscall_get_return_value(struct task_struct *task,  					    struct pt_regs *regs)  { @@ -50,9 +49,15 @@ static inline void syscall_set_return_value(struct task_struct *task,  					    struct pt_regs *regs,  					    int error, long val)  { +	/* +	 * In the general case it's not obvious that we must deal with CCR +	 * here, as the syscall exit path will also do that for us. However +	 * there are some places, eg. the signal code, which check ccr to +	 * decide if the value in r3 is actually an error. +	 */  	if (error) {  		regs->ccr |= 0x10000000L; -		regs->gpr[3] = -error; +		regs->gpr[3] = error;  	} else {  		regs->ccr &= ~0x10000000L;  		regs->gpr[3] = val; @@ -64,19 +69,22 @@ static inline void syscall_get_arguments(struct task_struct *task,  					 unsigned int i, unsigned int n,  					 unsigned long *args)  { +	unsigned long val, mask = -1UL; +  	BUG_ON(i + n > 6); -#ifdef CONFIG_PPC64 -	if (test_tsk_thread_flag(task, TIF_32BIT)) { -		/* -		 * Zero-extend 32-bit argument values.  The high bits are -		 * garbage ignored by the actual syscall dispatch. -		 */ -		while (n-- > 0) -			args[n] = (u32) regs->gpr[3 + i + n]; -		return; -	} + +#ifdef CONFIG_COMPAT +	if (test_tsk_thread_flag(task, TIF_32BIT)) +		mask = 0xffffffff;  #endif -	memcpy(args, ®s->gpr[3 + i], n * sizeof(args[0])); +	while (n--) { +		if (n == 0 && i == 0) +			val = regs->orig_gpr3; +		else +			val = regs->gpr[3 + i + n]; + +		args[n] = val & mask; +	}  }  static inline void syscall_set_arguments(struct task_struct *task, @@ -86,6 +94,10 @@ static inline void syscall_set_arguments(struct task_struct *task,  {  	BUG_ON(i + n > 6);  	memcpy(®s->gpr[3 + i], args, n * sizeof(args[0])); + +	/* Also copy the first argument into orig_gpr3 */ +	if (i == 0 && n > 0) +		regs->orig_gpr3 = args[0];  }  static inline int syscall_get_arch(void) diff --git a/arch/powerpc/include/asm/trace_clock.h b/arch/powerpc/include/asm/trace_clock.h new file mode 100644 index 000000000000..cf1ee75ca069 --- /dev/null +++ b/arch/powerpc/include/asm/trace_clock.h @@ -0,0 +1,19 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * Copyright (C) 2015 Naveen N. Rao, IBM Corporation + */ + +#ifndef _ASM_PPC_TRACE_CLOCK_H +#define _ASM_PPC_TRACE_CLOCK_H + +#include <linux/compiler.h> +#include <linux/types.h> + +extern u64 notrace trace_clock_ppc_tb(void); + +#define ARCH_TRACE_CLOCKS { trace_clock_ppc_tb, "ppc-tb", 0 }, + +#endif  /* _ASM_PPC_TRACE_CLOCK_H */ diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild index f44a027818af..dab3717e3ea0 100644 --- a/arch/powerpc/include/uapi/asm/Kbuild +++ b/arch/powerpc/include/uapi/asm/Kbuild @@ -6,6 +6,7 @@ header-y += bitsperlong.h  header-y += bootx.h  header-y += byteorder.h  header-y += cputable.h +header-y += eeh.h  header-y += elf.h  header-y += epapr_hcalls.h  header-y += errno.h diff --git a/arch/powerpc/include/uapi/asm/errno.h b/arch/powerpc/include/uapi/asm/errno.h index 8c145fd17d86..e8b6b5f7de7c 100644 --- a/arch/powerpc/include/uapi/asm/errno.h +++ b/arch/powerpc/include/uapi/asm/errno.h @@ -6,6 +6,4 @@  #undef	EDEADLOCK  #define	EDEADLOCK	58	/* File locking deadlock error */ -#define _LAST_ERRNO	516 -  #endif	/* _ASM_POWERPC_ERRNO_H */ diff --git a/arch/powerpc/include/uapi/asm/sigcontext.h b/arch/powerpc/include/uapi/asm/sigcontext.h index 9c1f24fd5d11..3ad0c7f001a9 100644 --- a/arch/powerpc/include/uapi/asm/sigcontext.h +++ b/arch/powerpc/include/uapi/asm/sigcontext.h @@ -28,7 +28,7 @@ struct sigcontext {  /*   * To maintain compatibility with current implementations the sigcontext is   * extended by appending a pointer (v_regs) to a quadword type (elf_vrreg_t) - * followed by an unstructured (vmx_reserve) field of 69 doublewords.  This + * followed by an unstructured (vmx_reserve) field of 101 doublewords. This   * allows the array of vector registers to be quadword aligned independent of   * the alignment of the containing sigcontext or ucontext. It is the   * responsibility of the code setting the sigcontext to set this pointer to @@ -80,7 +80,7 @@ struct sigcontext {   * registers and vscr/vrsave.   */  	elf_vrreg_t	__user *v_regs; -	long		vmx_reserve[ELF_NVRREG+ELF_NVRREG+32+1]; +	long		vmx_reserve[ELF_NVRREG + ELF_NVRREG + 1 + 32];  #endif  }; diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 12868b1c4e05..ba336930d448 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -118,6 +118,7 @@ obj-$(CONFIG_PPC_IO_WORKAROUNDS)	+= io-workarounds.o  obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o  obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o  obj-$(CONFIG_FTRACE_SYSCALLS)	+= ftrace.o +obj-$(CONFIG_TRACING)		+= trace_clock.o  ifneq ($(CONFIG_PPC_INDIRECT_PIO),y)  obj-y				+= iomap.o diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 98230579d99c..221d584d089f 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -213,7 +213,6 @@ int main(void)  		offsetof(struct tlb_core_data, esel_max));  	DEFINE(TCD_ESEL_FIRST,  		offsetof(struct tlb_core_data, esel_first)); -	DEFINE(TCD_LOCK, offsetof(struct tlb_core_data, lock));  #endif /* CONFIG_PPC_BOOK3E */  #ifdef CONFIG_PPC_STD_MMU_64 @@ -512,6 +511,8 @@ int main(void)  	DEFINE(VCPU_VPA, offsetof(struct kvm_vcpu, arch.vpa.pinned_addr));  	DEFINE(VCPU_VPA_DIRTY, offsetof(struct kvm_vcpu, arch.vpa.dirty));  	DEFINE(VCPU_HEIR, offsetof(struct kvm_vcpu, arch.emul_inst)); +	DEFINE(VCPU_CPU, offsetof(struct kvm_vcpu, cpu)); +	DEFINE(VCPU_THREAD_CPU, offsetof(struct kvm_vcpu, arch.thread_cpu));  #endif  #ifdef CONFIG_PPC_BOOK3S  	DEFINE(VCPU_VCPUID, offsetof(struct kvm_vcpu, vcpu_id)); @@ -674,7 +675,14 @@ int main(void)  	HSTATE_FIELD(HSTATE_DSCR, host_dscr);  	HSTATE_FIELD(HSTATE_DABR, dabr);  	HSTATE_FIELD(HSTATE_DECEXP, dec_expires); +	HSTATE_FIELD(HSTATE_SPLIT_MODE, kvm_split_mode);  	DEFINE(IPI_PRIORITY, IPI_PRIORITY); +	DEFINE(KVM_SPLIT_RPR, offsetof(struct kvm_split_mode, rpr)); +	DEFINE(KVM_SPLIT_PMMAR, offsetof(struct kvm_split_mode, pmmar)); +	DEFINE(KVM_SPLIT_LDBAR, offsetof(struct kvm_split_mode, ldbar)); +	DEFINE(KVM_SPLIT_SIZE, offsetof(struct kvm_split_mode, subcore_size)); +	DEFINE(KVM_SPLIT_DO_NAP, offsetof(struct kvm_split_mode, do_nap)); +	DEFINE(KVM_SPLIT_NAPPED, offsetof(struct kvm_split_mode, napped));  #endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */  #ifdef CONFIG_PPC_BOOK3S_64 diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 4c68bfe4108a..41a7d9d49a5a 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -73,7 +73,7 @@ static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist,  }  /* We support DMA to/from any memory page via the iommu */ -static int dma_iommu_dma_supported(struct device *dev, u64 mask) +int dma_iommu_dma_supported(struct device *dev, u64 mask)  {  	struct iommu_table *tbl = get_iommu_table_base(dev); diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c index 6e8d764ce47b..c6689f658b50 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c @@ -47,8 +47,8 @@ static u64 swiotlb_powerpc_get_required(struct device *dev)   * for everything else.   */  struct dma_map_ops swiotlb_dma_ops = { -	.alloc = dma_direct_alloc_coherent, -	.free = dma_direct_free_coherent, +	.alloc = __dma_direct_alloc_coherent, +	.free = __dma_direct_free_coherent,  	.mmap = dma_direct_mmap_coherent,  	.map_sg = swiotlb_map_sg_attrs,  	.unmap_sg = swiotlb_unmap_sg_attrs, diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c index 35e4dcc5dce3..59503ed98e5f 100644 --- a/arch/powerpc/kernel/dma.c +++ b/arch/powerpc/kernel/dma.c @@ -16,6 +16,7 @@  #include <asm/bug.h>  #include <asm/machdep.h>  #include <asm/swiotlb.h> +#include <asm/iommu.h>  /*   * Generic direct DMA implementation @@ -39,9 +40,31 @@ static u64 __maybe_unused get_pfn_limit(struct device *dev)  	return pfn;  } -void *dma_direct_alloc_coherent(struct device *dev, size_t size, -				dma_addr_t *dma_handle, gfp_t flag, -				struct dma_attrs *attrs) +static int dma_direct_dma_supported(struct device *dev, u64 mask) +{ +#ifdef CONFIG_PPC64 +	u64 limit = get_dma_offset(dev) + (memblock_end_of_DRAM() - 1); + +	/* Limit fits in the mask, we are good */ +	if (mask >= limit) +		return 1; + +#ifdef CONFIG_FSL_SOC +	/* Freescale gets another chance via ZONE_DMA/ZONE_DMA32, however +	 * that will have to be refined if/when they support iommus +	 */ +	return 1; +#endif +	/* Sorry ... */ +	return 0; +#else +	return 1; +#endif +} + +void *__dma_direct_alloc_coherent(struct device *dev, size_t size, +				  dma_addr_t *dma_handle, gfp_t flag, +				  struct dma_attrs *attrs)  {  	void *ret;  #ifdef CONFIG_NOT_COHERENT_CACHE @@ -96,9 +119,9 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size,  #endif  } -void dma_direct_free_coherent(struct device *dev, size_t size, -			      void *vaddr, dma_addr_t dma_handle, -			      struct dma_attrs *attrs) +void __dma_direct_free_coherent(struct device *dev, size_t size, +				void *vaddr, dma_addr_t dma_handle, +				struct dma_attrs *attrs)  {  #ifdef CONFIG_NOT_COHERENT_CACHE  	__dma_free_coherent(size, vaddr); @@ -107,6 +130,51 @@ void dma_direct_free_coherent(struct device *dev, size_t size,  #endif  } +static void *dma_direct_alloc_coherent(struct device *dev, size_t size, +				       dma_addr_t *dma_handle, gfp_t flag, +				       struct dma_attrs *attrs) +{ +	struct iommu_table *iommu; + +	/* The coherent mask may be smaller than the real mask, check if +	 * we can really use the direct ops +	 */ +	if (dma_direct_dma_supported(dev, dev->coherent_dma_mask)) +		return __dma_direct_alloc_coherent(dev, size, dma_handle, +						   flag, attrs); + +	/* Ok we can't ... do we have an iommu ? If not, fail */ +	iommu = get_iommu_table_base(dev); +	if (!iommu) +		return NULL; + +	/* Try to use the iommu */ +	return iommu_alloc_coherent(dev, iommu, size, dma_handle, +				    dev->coherent_dma_mask, flag, +				    dev_to_node(dev)); +} + +static void dma_direct_free_coherent(struct device *dev, size_t size, +				     void *vaddr, dma_addr_t dma_handle, +				     struct dma_attrs *attrs) +{ +	struct iommu_table *iommu; + +	/* See comments in dma_direct_alloc_coherent() */ +	if (dma_direct_dma_supported(dev, dev->coherent_dma_mask)) +		return __dma_direct_free_coherent(dev, size, vaddr, dma_handle, +						  attrs); +	/* Maybe we used an iommu ... */ +	iommu = get_iommu_table_base(dev); + +	/* If we hit that we should have never allocated in the first +	 * place so how come we are freeing ? +	 */ +	if (WARN_ON(!iommu)) +		return; +	iommu_free_coherent(iommu, size, vaddr, dma_handle); +} +  int dma_direct_mmap_coherent(struct device *dev, struct vm_area_struct *vma,  			     void *cpu_addr, dma_addr_t handle, size_t size,  			     struct dma_attrs *attrs) @@ -147,18 +215,6 @@ static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,  {  } -static int dma_direct_dma_supported(struct device *dev, u64 mask) -{ -#ifdef CONFIG_PPC64 -	/* Could be improved so platforms can set the limit in case -	 * they have limited DMA windows -	 */ -	return mask >= get_dma_offset(dev) + (memblock_end_of_DRAM() - 1); -#else -	return 1; -#endif -} -  static u64 dma_direct_get_required_mask(struct device *dev)  {  	u64 end, mask; @@ -230,6 +286,25 @@ struct dma_map_ops dma_direct_ops = {  };  EXPORT_SYMBOL(dma_direct_ops); +int dma_set_coherent_mask(struct device *dev, u64 mask) +{ +	if (!dma_supported(dev, mask)) { +		/* +		 * We need to special case the direct DMA ops which can +		 * support a fallback for coherent allocations. There +		 * is no dma_op->set_coherent_mask() so we have to do +		 * things the hard way: +		 */ +		if (get_dma_ops(dev) != &dma_direct_ops || +		    get_iommu_table_base(dev) == NULL || +		    !dma_iommu_dma_supported(dev, mask)) +			return -EIO; +	} +	dev->coherent_dma_mask = mask; +	return 0; +} +EXPORT_SYMBOL_GPL(dma_set_coherent_mask); +  #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)  int __dma_set_mask(struct device *dev, u64 dma_mask) @@ -278,6 +353,13 @@ u64 dma_get_required_mask(struct device *dev)  	if (ppc_md.dma_get_required_mask)  		return ppc_md.dma_get_required_mask(dev); +	if (dev_is_pci(dev)) { +		struct pci_dev *pdev = to_pci_dev(dev); +		struct pci_controller *phb = pci_bus_to_host(pdev->bus); +		if (phb->controller_ops.dma_get_required_mask) +			return phb->controller_ops.dma_get_required_mask(pdev); +	} +  	return __dma_get_required_mask(dev);  }  EXPORT_SYMBOL_GPL(dma_get_required_mask); diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index af9b597b10af..e968533e3e05 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -308,11 +308,26 @@ void eeh_slot_error_detail(struct eeh_pe *pe, int severity)  	if (!(pe->type & EEH_PE_PHB)) {  		if (eeh_has_flag(EEH_ENABLE_IO_FOR_LOG))  			eeh_pci_enable(pe, EEH_OPT_THAW_MMIO); + +		/* +		 * The config space of some PCI devices can't be accessed +		 * when their PEs are in frozen state. Otherwise, fenced +		 * PHB might be seen. Those PEs are identified with flag +		 * EEH_PE_CFG_RESTRICTED, indicating EEH_PE_CFG_BLOCKED +		 * is set automatically when the PE is put to EEH_PE_ISOLATED. +		 * +		 * Restoring BARs possibly triggers PCI config access in +		 * (OPAL) firmware and then causes fenced PHB. If the +		 * PCI config is blocked with flag EEH_PE_CFG_BLOCKED, it's +		 * pointless to restore BARs and dump config space. +		 */  		eeh_ops->configure_bridge(pe); -		eeh_pe_restore_bars(pe); +		if (!(pe->state & EEH_PE_CFG_BLOCKED)) { +			eeh_pe_restore_bars(pe); -		pci_regs_buf[0] = 0; -		eeh_pe_traverse(pe, eeh_dump_pe_log, &loglen); +			pci_regs_buf[0] = 0; +			eeh_pe_traverse(pe, eeh_dump_pe_log, &loglen); +		}  	}  	eeh_ops->get_log(pe, severity, pci_regs_buf, loglen); @@ -750,14 +765,14 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat  		eeh_pe_state_clear(pe, EEH_PE_ISOLATED);  		break;  	case pcie_hot_reset: -		eeh_pe_state_mark(pe, EEH_PE_ISOLATED); +		eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED);  		eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE);  		eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev);  		eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED);  		eeh_ops->reset(pe, EEH_RESET_HOT);  		break;  	case pcie_warm_reset: -		eeh_pe_state_mark(pe, EEH_PE_ISOLATED); +		eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED);  		eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE);  		eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev);  		eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED); @@ -1116,9 +1131,6 @@ void eeh_add_device_late(struct pci_dev *dev)  		return;  	} -	if (eeh_has_flag(EEH_PROBE_MODE_DEV)) -		eeh_ops->probe(pdn, NULL); -  	/*  	 * The EEH cache might not be removed correctly because of  	 * unbalanced kref to the device during unplug time, which @@ -1142,6 +1154,9 @@ void eeh_add_device_late(struct pci_dev *dev)  		dev->dev.archdata.edev = NULL;  	} +	if (eeh_has_flag(EEH_PROBE_MODE_DEV)) +		eeh_ops->probe(pdn, NULL); +  	edev->pdev = dev;  	dev->dev.archdata.edev = edev; diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index 35f0b62259bb..8654cb166c19 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c @@ -657,6 +657,28 @@ void eeh_pe_state_clear(struct eeh_pe *pe, int state)  	eeh_pe_traverse(pe, __eeh_pe_state_clear, &state);  } +/** + * eeh_pe_state_mark_with_cfg - Mark PE state with unblocked config space + * @pe: PE + * @state: PE state to be set + * + * Set specified flag to PE and its child PEs. The PCI config space + * of some PEs is blocked automatically when EEH_PE_ISOLATED is set, + * which isn't needed in some situations. The function allows to set + * the specified flag to indicated PEs without blocking their PCI + * config space. + */ +void eeh_pe_state_mark_with_cfg(struct eeh_pe *pe, int state) +{ +	eeh_pe_traverse(pe, __eeh_pe_state_mark, &state); +	if (!(state & EEH_PE_ISOLATED)) +		return; + +	/* Clear EEH_PE_CFG_BLOCKED, which might be set just now */ +	state = EEH_PE_CFG_BLOCKED; +	eeh_pe_traverse(pe, __eeh_pe_state_clear, &state); +} +  /*   * Some PCI bridges (e.g. PLX bridges) have primary/secondary   * buses assigned explicitly by firmware, and we probably have diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 46fc0f4d8982..2405631e91a2 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -20,6 +20,7 @@   */  #include <linux/errno.h> +#include <linux/err.h>  #include <linux/sys.h>  #include <linux/threads.h>  #include <asm/reg.h> @@ -354,7 +355,7 @@ ret_from_syscall:  	SYNC  	MTMSRD(r10)  	lwz	r9,TI_FLAGS(r12) -	li	r8,-_LAST_ERRNO +	li	r8,-MAX_ERRNO  	andi.	r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)  	bne-	syscall_exit_work  	cmplw	0,r3,r8 @@ -457,6 +458,10 @@ syscall_dotrace:  	lwz	r7,GPR7(r1)  	lwz	r8,GPR8(r1)  	REST_NVGPRS(r1) + +	cmplwi	r0,NR_syscalls +	/* Return code is already in r3 thanks to do_syscall_trace_enter() */ +	bge-	ret_from_syscall  	b	syscall_dotrace_cont  syscall_exit_work: diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 579e0f9a2d57..a94f155db78e 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -19,6 +19,7 @@   */  #include <linux/errno.h> +#include <linux/err.h>  #include <asm/unistd.h>  #include <asm/processor.h>  #include <asm/page.h> @@ -150,8 +151,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)  	CURRENT_THREAD_INFO(r11, r1)  	ld	r10,TI_FLAGS(r11)  	andi.	r11,r10,_TIF_SYSCALL_DOTRACE -	bne	syscall_dotrace -.Lsyscall_dotrace_cont: +	bne	syscall_dotrace		/* does not return */  	cmpldi	0,r0,NR_syscalls  	bge-	syscall_enosys @@ -207,7 +207,7 @@ system_call:			/* label this so stack traces look sane */  #endif /* CONFIG_PPC_BOOK3E */  	ld	r9,TI_FLAGS(r12) -	li	r11,-_LAST_ERRNO +	li	r11,-MAX_ERRNO  	andi.	r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)  	bne-	syscall_exit_work  	cmpld	r3,r11 @@ -245,22 +245,34 @@ syscall_dotrace:  	bl	save_nvgprs  	addi	r3,r1,STACK_FRAME_OVERHEAD  	bl	do_syscall_trace_enter +  	/* -	 * Restore argument registers possibly just changed. -	 * We use the return value of do_syscall_trace_enter -	 * for the call number to look up in the table (r0). +	 * We use the return value of do_syscall_trace_enter() as the syscall +	 * number. If the syscall was rejected for any reason do_syscall_trace_enter() +	 * returns an invalid syscall number and the test below against +	 * NR_syscalls will fail.  	 */  	mr	r0,r3 + +	/* Restore argument registers just clobbered and/or possibly changed. */  	ld	r3,GPR3(r1)  	ld	r4,GPR4(r1)  	ld	r5,GPR5(r1)  	ld	r6,GPR6(r1)  	ld	r7,GPR7(r1)  	ld	r8,GPR8(r1) + +	/* Repopulate r9 and r10 for the system_call path */  	addi	r9,r1,STACK_FRAME_OVERHEAD  	CURRENT_THREAD_INFO(r10, r1)  	ld	r10,TI_FLAGS(r10) -	b	.Lsyscall_dotrace_cont + +	cmpldi	r0,NR_syscalls +	blt+	system_call + +	/* Return code is already in r3 thanks to do_syscall_trace_enter() */ +	b	.Lsyscall_exit +  syscall_enosys:  	li	r3,-ENOSYS @@ -277,7 +289,7 @@ syscall_exit_work:  	beq+	0f  	REST_NVGPRS(r1)  	b	2f -0:	cmpld	r3,r11		/* r10 is -LAST_ERRNO */ +0:	cmpld	r3,r11		/* r11 is -MAX_ERRNO */  	blt+	1f  	andi.	r0,r9,_TIF_NOERROR  	bne-	1f diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index 3e68d1c69718..f3bd5e747ed8 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S @@ -1313,11 +1313,14 @@ skpinv:	addi	r6,r6,1				/* Increment */  	sync  	isync -/* The mapping only needs to be cache-coherent on SMP */ -#ifdef CONFIG_SMP -#define M_IF_SMP	MAS2_M +/* + * The mapping only needs to be cache-coherent on SMP, except on + * Freescale e500mc derivatives where it's also needed for coherent DMA. + */ +#if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC) +#define M_IF_NEEDED	MAS2_M  #else -#define M_IF_SMP	0 +#define M_IF_NEEDED	0  #endif  /* 6. Setup KERNELBASE mapping in TLB[0] @@ -1332,7 +1335,7 @@ skpinv:	addi	r6,r6,1				/* Increment */  	ori	r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_1GB))@l  	mtspr	SPRN_MAS1,r6 -	LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET | M_IF_SMP) +	LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET | M_IF_NEEDED)  	mtspr	SPRN_MAS2,r6  	rlwinm	r5,r5,0,0,25 diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S b/arch/powerpc/kernel/fsl_booke_entry_mapping.S index f22e7e44fbf3..83dd0f6776b3 100644 --- a/arch/powerpc/kernel/fsl_booke_entry_mapping.S +++ b/arch/powerpc/kernel/fsl_booke_entry_mapping.S @@ -152,11 +152,14 @@ skpinv:	addi	r6,r6,1				/* Increment */  	tlbivax 0,r9  	TLBSYNC -/* The mapping only needs to be cache-coherent on SMP */ -#ifdef CONFIG_SMP -#define M_IF_SMP	MAS2_M +/* + * The mapping only needs to be cache-coherent on SMP, except on + * Freescale e500mc derivatives where it's also needed for coherent DMA. + */ +#if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC) +#define M_IF_NEEDED	MAS2_M  #else -#define M_IF_SMP	0 +#define M_IF_NEEDED	0  #endif  #if defined(ENTRY_MAPPING_BOOT_SETUP) @@ -167,8 +170,8 @@ skpinv:	addi	r6,r6,1				/* Increment */  	lis	r6,(MAS1_VALID|MAS1_IPROT)@h  	ori	r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l  	mtspr	SPRN_MAS1,r6 -	lis	r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h -	ori	r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l +	lis	r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_NEEDED)@h +	ori	r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_NEEDED)@l  	mtspr	SPRN_MAS2,r6  	mtspr	SPRN_MAS3,r8  	tlbwe diff --git a/arch/powerpc/kernel/jump_label.c b/arch/powerpc/kernel/jump_label.c index a1ed8a8c7cb4..6472472093d0 100644 --- a/arch/powerpc/kernel/jump_label.c +++ b/arch/powerpc/kernel/jump_label.c @@ -17,7 +17,7 @@ void arch_jump_label_transform(struct jump_entry *entry,  {  	u32 *addr = (u32 *)(unsigned long)entry->code; -	if (type == JUMP_LABEL_ENABLE) +	if (type == JUMP_LABEL_JMP)  		patch_branch(addr, entry->target, 0);  	else  		patch_instruction(addr, PPC_INST_NOP); diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c index 33aa4ddf597d..9ad37f827a97 100644 --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c @@ -649,7 +649,6 @@ static void kvm_check_ins(u32 *inst, u32 features)  			kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);  		}  		break; -		break;  #endif  	} diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 7c6bb4b17b49..ed3ab509faca 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -596,25 +596,6 @@ _GLOBAL(copy_page)  	b	2b  /* - * void atomic_clear_mask(atomic_t mask, atomic_t *addr) - * void atomic_set_mask(atomic_t mask, atomic_t *addr); - */ -_GLOBAL(atomic_clear_mask) -10:	lwarx	r5,0,r4 -	andc	r5,r5,r3 -	PPC405_ERR77(0,r4) -	stwcx.	r5,0,r4 -	bne-	10b -	blr -_GLOBAL(atomic_set_mask) -10:	lwarx	r5,0,r4 -	or	r5,r5,r3 -	PPC405_ERR77(0,r4) -	stwcx.	r5,0,r4 -	bne-	10b -	blr - -/*   * Extended precision shifts.   *   * Updated to be valid for shift counts from 0 to 63 inclusive. diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 4e314b90c75d..6e4168cf4698 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -475,9 +475,18 @@ _GLOBAL(kexec_wait)  #ifdef CONFIG_KEXEC		/* use no memory without kexec */  	lwz	r4,0(r5)  	cmpwi	0,r4,0 -	bnea	0x60 +	beq	99b +#ifdef CONFIG_PPC_BOOK3S_64 +	li	r10,0x60 +	mfmsr	r11 +	clrrdi	r11,r11,1	/* Clear MSR_LE */ +	mtsrr0	r10 +	mtsrr1	r11 +	rfid +#else +	ba	0x60 +#endif  #endif -	b	99b  /* this can be in text because we won't change it until we are   * running in real anyways diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index 1e703f8ebad4..98ba106a59ef 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -541,10 +541,9 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,  			time->tv_sec = be64_to_cpu(oops_hdr->timestamp);  			time->tv_nsec = 0;  		} -		*buf = kmalloc(length, GFP_KERNEL); +		*buf = kmemdup(buff + hdr_size, length, GFP_KERNEL);  		if (*buf == NULL)  			return -ENOMEM; -		memcpy(*buf, buff + hdr_size, length);  		kfree(buff);  		if (err_type == ERR_TYPE_KERNEL_PANIC_GZ) @@ -582,9 +581,10 @@ static int nvram_pstore_init(void)  	spin_lock_init(&nvram_pstore_info.buf_lock);  	rc = pstore_register(&nvram_pstore_info); -	if (rc != 0) -		pr_err("nvram: pstore_register() failed, defaults to " -				"kmsg_dump; returned %d\n", rc); +	if (rc && (rc != -EPERM)) +		/* Print error only when pstore.backend == nvram */ +		pr_err("nvram: pstore_register() failed, returned %d. " +				"Defaults to kmsg_dump\n", rc);  	return rc;  } diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index b9de34d44fcb..a1d0632d97c6 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -823,23 +823,15 @@ static void pcibios_fixup_resources(struct pci_dev *dev)  		    (reg.start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) {  			/* Only print message if not re-assigning */  			if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC)) -				pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] " -					 "is unassigned\n", -					 pci_name(dev), i, -					 (unsigned long long)res->start, -					 (unsigned long long)res->end, -					 (unsigned int)res->flags); +				pr_debug("PCI:%s Resource %d %pR is unassigned\n", +					 pci_name(dev), i, res);  			res->end -= res->start;  			res->start = 0;  			res->flags |= IORESOURCE_UNSET;  			continue;  		} -		pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]\n", -			 pci_name(dev), i, -			 (unsigned long long)res->start,\ -			 (unsigned long long)res->end, -			 (unsigned int)res->flags); +		pr_debug("PCI:%s Resource %d %pR\n", pci_name(dev), i, res);  	}  	/* Call machine specific resource fixup */ @@ -943,11 +935,7 @@ static void pcibios_fixup_bridge(struct pci_bus *bus)  			continue;  		} -		pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x]\n", -			 pci_name(dev), i, -			 (unsigned long long)res->start,\ -			 (unsigned long long)res->end, -			 (unsigned int)res->flags); +		pr_debug("PCI:%s Bus rsrc %d %pR\n", pci_name(dev), i, res);  		/* Try to detect uninitialized P2P bridge resources,  		 * and clear them out so they get re-assigned later @@ -1044,13 +1032,7 @@ void pcibios_set_master(struct pci_dev *dev)  void pcibios_fixup_bus(struct pci_bus *bus)  { -	/* When called from the generic PCI probe, read PCI<->PCI bridge -	 * bases. This is -not- called when generating the PCI tree from -	 * the OF device-tree. -	 */ -	pci_read_bridge_bases(bus); - -	/* Now fixup the bus bus */ +	/* Fixup the bus */  	pcibios_setup_bus_self(bus);  	/* Now fixup devices on that bus */ @@ -1132,10 +1114,8 @@ static int reparent_resources(struct resource *parent,  	*pp = NULL;  	for (p = res->child; p != NULL; p = p->sibling) {  		p->parent = res; -		pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n", -			 p->name, -			 (unsigned long long)p->start, -			 (unsigned long long)p->end, res->name); +		pr_debug("PCI: Reparented %s %pR under %s\n", +			 p->name, p, res->name);  	}  	return 0;  } @@ -1204,14 +1184,9 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)  			}  		} -		pr_debug("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx " -			 "[0x%x], parent %p (%s)\n", -			 bus->self ? pci_name(bus->self) : "PHB", -			 bus->number, i, -			 (unsigned long long)res->start, -			 (unsigned long long)res->end, -			 (unsigned int)res->flags, -			 pr, (pr && pr->name) ? pr->name : "nil"); +		pr_debug("PCI: %s (bus %d) bridge rsrc %d: %pR, parent %p (%s)\n", +			 bus->self ? pci_name(bus->self) : "PHB", bus->number, +			 i, res, pr, (pr && pr->name) ? pr->name : "nil");  		if (pr && !(pr->flags & IORESOURCE_UNSET)) {  			struct pci_dev *dev = bus->self; @@ -1253,11 +1228,8 @@ static inline void alloc_resource(struct pci_dev *dev, int idx)  {  	struct resource *pr, *r = &dev->resource[idx]; -	pr_debug("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n", -		 pci_name(dev), idx, -		 (unsigned long long)r->start, -		 (unsigned long long)r->end, -		 (unsigned int)r->flags); +	pr_debug("PCI: Allocating %s: Resource %d: %pR\n", +		 pci_name(dev), idx, r);  	pr = pci_find_parent_resource(dev, r);  	if (!pr || (pr->flags & IORESOURCE_UNSET) || @@ -1265,11 +1237,7 @@ static inline void alloc_resource(struct pci_dev *dev, int idx)  		printk(KERN_WARNING "PCI: Cannot allocate resource region %d"  		       " of device %s, will remap\n", idx, pci_name(dev));  		if (pr) -			pr_debug("PCI:  parent is %p: %016llx-%016llx [%x]\n", -				 pr, -				 (unsigned long long)pr->start, -				 (unsigned long long)pr->end, -				 (unsigned int)pr->flags); +			pr_debug("PCI:  parent is %p: %pR\n", pr, pr);  		/* We'll assign a new address later */  		r->flags |= IORESOURCE_UNSET;  		r->end -= r->start; @@ -1431,12 +1399,8 @@ void pcibios_claim_one_bus(struct pci_bus *bus)  			if (r->parent || !r->start || !r->flags)  				continue; -			pr_debug("PCI: Claiming %s: " -				 "Resource %d: %016llx..%016llx [%x]\n", -				 pci_name(dev), i, -				 (unsigned long long)r->start, -				 (unsigned long long)r->end, -				 (unsigned int)r->flags); +			pr_debug("PCI: Claiming %s: Resource %d: %pR\n", +				 pci_name(dev), i, r);  			if (pci_claim_resource(dev, i) == 0)  				continue; @@ -1520,11 +1484,8 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose,  	} else {  		offset = pcibios_io_space_offset(hose); -		pr_debug("PCI: PHB IO resource    = %08llx-%08llx [%lx] off 0x%08llx\n", -			 (unsigned long long)res->start, -			 (unsigned long long)res->end, -			 (unsigned long)res->flags, -			 (unsigned long long)offset); +		pr_debug("PCI: PHB IO resource    = %pR off 0x%08llx\n", +			 res, (unsigned long long)offset);  		pci_add_resource_offset(resources, res, offset);  	} @@ -1541,11 +1502,8 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose,  		offset = hose->mem_offset[i]; -		pr_debug("PCI: PHB MEM resource %d = %08llx-%08llx [%lx] off 0x%08llx\n", i, -			 (unsigned long long)res->start, -			 (unsigned long long)res->end, -			 (unsigned long)res->flags, -			 (unsigned long long)offset); +		pr_debug("PCI: PHB MEM resource %d = %pR off 0x%08llx\n", i, +			 res, (unsigned long long)offset);  		pci_add_resource_offset(resources, res, offset);  	} diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 42e02a2d570b..2e710c15893f 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -102,7 +102,7 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev)  			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];  		} else if (i == dev->rom_base_reg) {  			res = &dev->resource[PCI_ROM_RESOURCE]; -			flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE; +			flags |= IORESOURCE_READONLY;  		} else {  			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);  			continue; @@ -126,7 +126,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,  {  	struct pci_dev *dev;  	const char *type; -	struct pci_slot *slot;  	dev = pci_alloc_dev(bus);  	if (!dev) @@ -145,10 +144,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,  	dev->needs_freset = 0;		/* pcie fundamental reset required */  	set_pcie_port_type(dev); -	list_for_each_entry(slot, &dev->bus->slots, list) -		if (PCI_SLOT(dev->devfn) == slot->number) -			dev->slot = slot; - +	pci_dev_assign_slot(dev);  	dev->vendor = get_int_prop(node, "vendor-id", 0xffff);  	dev->device = get_int_prop(node, "device-id", 0xffff);  	dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0); @@ -191,6 +187,9 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,  	pci_device_add(dev, bus); +	/* Setup MSI caps & disable MSI/MSI-X interrupts */ +	pci_msi_setup_pci_dev(dev); +  	return dev;  }  EXPORT_SYMBOL(of_create_pci_dev); diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 8005e18d1b40..75b6676c1a0b 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -86,7 +86,7 @@ void giveup_fpu_maybe_transactional(struct task_struct *tsk)  	if (tsk == current && tsk->thread.regs &&  	    MSR_TM_ACTIVE(tsk->thread.regs->msr) &&  	    !test_thread_flag(TIF_RESTORE_TM)) { -		tsk->thread.tm_orig_msr = tsk->thread.regs->msr; +		tsk->thread.ckpt_regs.msr = tsk->thread.regs->msr;  		set_thread_flag(TIF_RESTORE_TM);  	} @@ -104,7 +104,7 @@ void giveup_altivec_maybe_transactional(struct task_struct *tsk)  	if (tsk == current && tsk->thread.regs &&  	    MSR_TM_ACTIVE(tsk->thread.regs->msr) &&  	    !test_thread_flag(TIF_RESTORE_TM)) { -		tsk->thread.tm_orig_msr = tsk->thread.regs->msr; +		tsk->thread.ckpt_regs.msr = tsk->thread.regs->msr;  		set_thread_flag(TIF_RESTORE_TM);  	} @@ -204,8 +204,6 @@ EXPORT_SYMBOL_GPL(flush_altivec_to_thread);  #endif /* CONFIG_ALTIVEC */  #ifdef CONFIG_VSX -#if 0 -/* not currently used, but some crazy RAID module might want to later */  void enable_kernel_vsx(void)  {  	WARN_ON(preemptible()); @@ -220,7 +218,6 @@ void enable_kernel_vsx(void)  #endif /* CONFIG_SMP */  }  EXPORT_SYMBOL(enable_kernel_vsx); -#endif  void giveup_vsx(struct task_struct *tsk)  { @@ -543,7 +540,7 @@ static void tm_reclaim_thread(struct thread_struct *thr,  	 * the thread will no longer be transactional.  	 */  	if (test_ti_thread_flag(ti, TIF_RESTORE_TM)) { -		msr_diff = thr->tm_orig_msr & ~thr->regs->msr; +		msr_diff = thr->ckpt_regs.msr & ~thr->regs->msr;  		if (msr_diff & MSR_FP)  			memcpy(&thr->transact_fp, &thr->fp_state,  			       sizeof(struct thread_fp_state)); @@ -594,10 +591,10 @@ static inline void tm_reclaim_task(struct task_struct *tsk)  	/* Stash the original thread MSR, as giveup_fpu et al will  	 * modify it.  We hold onto it to see whether the task used  	 * FP & vector regs.  If the TIF_RESTORE_TM flag is set, -	 * tm_orig_msr is already set. +	 * ckpt_regs.msr is already set.  	 */  	if (!test_ti_thread_flag(task_thread_info(tsk), TIF_RESTORE_TM)) -		thr->tm_orig_msr = thr->regs->msr; +		thr->ckpt_regs.msr = thr->regs->msr;  	TM_DEBUG("--- tm_reclaim on pid %d (NIP=%lx, "  		 "ccr=%lx, msr=%lx, trap=%lx)\n", @@ -666,7 +663,7 @@ static inline void tm_recheckpoint_new_task(struct task_struct *new)  		tm_restore_sprs(&new->thread);  		return;  	} -	msr = new->thread.tm_orig_msr; +	msr = new->thread.ckpt_regs.msr;  	/* Recheckpoint to restore original checkpointed register state. */  	TM_DEBUG("*** tm_recheckpoint of pid %d "  		 "(new->msr 0x%lx, new->origmsr 0x%lx)\n", @@ -726,7 +723,7 @@ void restore_tm_state(struct pt_regs *regs)  	if (!MSR_TM_ACTIVE(regs->msr))  		return; -	msr_diff = current->thread.tm_orig_msr & ~regs->msr; +	msr_diff = current->thread.ckpt_regs.msr & ~regs->msr;  	msr_diff &= MSR_FP | MSR_VEC | MSR_VSX;  	if (msr_diff & MSR_FP) {  		fp_enable(); diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 8b888b12a475..bef76c5033e4 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -218,22 +218,18 @@ static void __init check_cpu_pa_features(unsigned long node)  }  #ifdef CONFIG_PPC_STD_MMU_64 -static void __init check_cpu_slb_size(unsigned long node) +static void __init init_mmu_slb_size(unsigned long node)  {  	const __be32 *slb_size_ptr; -	slb_size_ptr = of_get_flat_dt_prop(node, "slb-size", NULL); -	if (slb_size_ptr != NULL) { -		mmu_slb_size = be32_to_cpup(slb_size_ptr); -		return; -	} -	slb_size_ptr = of_get_flat_dt_prop(node, "ibm,slb-size", NULL); -	if (slb_size_ptr != NULL) { +	slb_size_ptr = of_get_flat_dt_prop(node, "slb-size", NULL) ? : +			of_get_flat_dt_prop(node, "ibm,slb-size", NULL); + +	if (slb_size_ptr)  		mmu_slb_size = be32_to_cpup(slb_size_ptr); -	}  }  #else -#define check_cpu_slb_size(node) do { } while(0) +#define init_mmu_slb_size(node) do { } while(0)  #endif  static struct feature_property { @@ -380,7 +376,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,  	check_cpu_feature_properties(node);  	check_cpu_pa_features(node); -	check_cpu_slb_size(node); +	init_mmu_slb_size(node);  #ifdef CONFIG_PPC64  	if (nthreads > 1) @@ -476,9 +472,10 @@ static int __init early_init_dt_scan_drconf_memory(unsigned long node)  		flags = of_read_number(&dm[3], 1);  		/* skip DRC index, pad, assoc. list index, flags */  		dm += 4; -		/* skip this block if the reserved bit is set in flags (0x80) -		   or if the block is not assigned to this partition (0x8) */ -		if ((flags & 0x80) || !(flags & 0x8)) +		/* skip this block if the reserved bit is set in flags +		   or if the block is not assigned to this partition */ +		if ((flags & DRCONF_MEM_RESERVED) || +				!(flags & DRCONF_MEM_ASSIGNED))  			continue;  		size = memblock_size;  		rngs = 1; diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index fcca8077e6a2..15099c41622e 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -641,6 +641,15 @@ static void __init early_cmdline_parse(void)  #define W(x)	((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \  		((x) >> 8) & 0xff, (x) & 0xff +/* Firmware expects the value to be n - 1, where n is the # of vectors */ +#define NUM_VECTORS(n)		((n) - 1) + +/* + * Firmware expects 1 + n - 2, where n is the length of the option vector in + * bytes. The 1 accounts for the length byte itself, the - 2 .. ? + */ +#define VECTOR_LENGTH(n)	(1 + (n) - 2) +  unsigned char ibm_architecture_vec[] = {  	W(0xfffe0000), W(0x003a0000),	/* POWER5/POWER5+ */  	W(0xffff0000), W(0x003e0000),	/* POWER6 */ @@ -651,16 +660,16 @@ unsigned char ibm_architecture_vec[] = {  	W(0xffffffff), W(0x0f000003),	/* all 2.06-compliant */  	W(0xffffffff), W(0x0f000002),	/* all 2.05-compliant */  	W(0xfffffffe), W(0x0f000001),	/* all 2.04-compliant and earlier */ -	6 - 1,				/* 6 option vectors */ +	NUM_VECTORS(6),			/* 6 option vectors */  	/* option vector 1: processor architectures supported */ -	3 - 2,				/* length */ +	VECTOR_LENGTH(2),		/* length */  	0,				/* don't ignore, don't halt */  	OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |  	OV1_PPC_2_04 | OV1_PPC_2_05 | OV1_PPC_2_06 | OV1_PPC_2_07,  	/* option vector 2: Open Firmware options supported */ -	34 - 2,				/* length */ +	VECTOR_LENGTH(33),		/* length */  	OV2_REAL_MODE,  	0, 0,  	W(0xffffffff),			/* real_base */ @@ -674,17 +683,17 @@ unsigned char ibm_architecture_vec[] = {  	48,				/* max log_2(hash table size) */  	/* option vector 3: processor options supported */ -	3 - 2,				/* length */ +	VECTOR_LENGTH(2),		/* length */  	0,				/* don't ignore, don't halt */  	OV3_FP | OV3_VMX | OV3_DFP,  	/* option vector 4: IBM PAPR implementation */ -	3 - 2,				/* length */ +	VECTOR_LENGTH(2),		/* length */  	0,				/* don't halt */  	OV4_MIN_ENT_CAP,		/* minimum VP entitled capacity */  	/* option vector 5: PAPR/OF options */ -	19 - 2,				/* length */ +	VECTOR_LENGTH(18),		/* length */  	0,				/* don't ignore, don't halt */  	OV5_FEAT(OV5_LPAR) | OV5_FEAT(OV5_SPLPAR) | OV5_FEAT(OV5_LARGE_PAGES) |  	OV5_FEAT(OV5_DRCONF_MEMORY) | OV5_FEAT(OV5_DONATE_DEDICATE_CPU) | @@ -717,12 +726,12 @@ unsigned char ibm_architecture_vec[] = {  	OV5_FEAT(OV5_PFO_HW_RNG) | OV5_FEAT(OV5_PFO_HW_ENCR) |  	OV5_FEAT(OV5_PFO_HW_842),  	OV5_FEAT(OV5_SUB_PROCESSORS), +  	/* option vector 6: IBM PAPR hints */ -	4 - 2,				/* length */ +	VECTOR_LENGTH(3),		/* length */  	0,  	0,  	OV6_LINUX, -  };  /* Old method - ELF header with PT_NOTE sections only works on BE */ diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index f21897b42057..737c0d0b53ac 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -1762,26 +1762,81 @@ long arch_ptrace(struct task_struct *child, long request,  	return ret;  } -/* - * We must return the syscall number to actually look up in the table. - * This can be -1L to skip running any syscall at all. +#ifdef CONFIG_SECCOMP +static int do_seccomp(struct pt_regs *regs) +{ +	if (!test_thread_flag(TIF_SECCOMP)) +		return 0; + +	/* +	 * The ABI we present to seccomp tracers is that r3 contains +	 * the syscall return value and orig_gpr3 contains the first +	 * syscall parameter. This is different to the ptrace ABI where +	 * both r3 and orig_gpr3 contain the first syscall parameter. +	 */ +	regs->gpr[3] = -ENOSYS; + +	/* +	 * We use the __ version here because we have already checked +	 * TIF_SECCOMP. If this fails, there is nothing left to do, we +	 * have already loaded -ENOSYS into r3, or seccomp has put +	 * something else in r3 (via SECCOMP_RET_ERRNO/TRACE). +	 */ +	if (__secure_computing()) +		return -1; + +	/* +	 * The syscall was allowed by seccomp, restore the register +	 * state to what ptrace and audit expect. +	 * Note that we use orig_gpr3, which means a seccomp tracer can +	 * modify the first syscall parameter (in orig_gpr3) and also +	 * allow the syscall to proceed. +	 */ +	regs->gpr[3] = regs->orig_gpr3; + +	return 0; +} +#else +static inline int do_seccomp(struct pt_regs *regs) { return 0; } +#endif /* CONFIG_SECCOMP */ + +/** + * do_syscall_trace_enter() - Do syscall tracing on kernel entry. + * @regs: the pt_regs of the task to trace (current) + * + * Performs various types of tracing on syscall entry. This includes seccomp, + * ptrace, syscall tracepoints and audit. + * + * The pt_regs are potentially visible to userspace via ptrace, so their + * contents is ABI. + * + * One or more of the tracers may modify the contents of pt_regs, in particular + * to modify arguments or even the syscall number itself. + * + * It's also possible that a tracer can choose to reject the system call. In + * that case this function will return an illegal syscall number, and will put + * an appropriate return value in regs->r3. + * + * Return: the (possibly changed) syscall number.   */  long do_syscall_trace_enter(struct pt_regs *regs)  { -	long ret = 0; +	bool abort = false;  	user_exit(); -	secure_computing_strict(regs->gpr[0]); +	if (do_seccomp(regs)) +		return -1; -	if (test_thread_flag(TIF_SYSCALL_TRACE) && -	    tracehook_report_syscall_entry(regs)) +	if (test_thread_flag(TIF_SYSCALL_TRACE)) {  		/* -		 * Tracing decided this syscall should not happen. -		 * We'll return a bogus call number to get an ENOSYS -		 * error, but leave the original number in regs->gpr[0]. +		 * The tracer may decide to abort the syscall, if so tracehook +		 * will return !0. Note that the tracer may also just change +		 * regs->gpr[0] to an invalid syscall number, that is handled +		 * below on the exit path.  		 */ -		ret = -1L; +		abort = tracehook_report_syscall_entry(regs) != 0; +	}  	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))  		trace_sys_enter(regs, regs->gpr[0]); @@ -1798,7 +1853,17 @@ long do_syscall_trace_enter(struct pt_regs *regs)  				    regs->gpr[5] & 0xffffffff,  				    regs->gpr[6] & 0xffffffff); -	return ret ?: regs->gpr[0]; +	if (abort || regs->gpr[0] >= NR_syscalls) { +		/* +		 * If we are aborting explicitly, or if the syscall number is +		 * now invalid, set the return value to -ENOSYS. +		 */ +		regs->gpr[3] = -ENOSYS; +		return -1; +	} + +	/* Return the possibly modified but valid syscall number */ +	return regs->gpr[0];  }  void do_syscall_trace_leave(struct pt_regs *regs) diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 7a488c108410..84bf934cf748 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -478,8 +478,9 @@ unsigned int rtas_busy_delay_time(int status)  	if (status == RTAS_BUSY) {  		ms = 1; -	} else if (status >= 9900 && status <= 9905) { -		order = status - 9900; +	} else if (status >= RTAS_EXTENDED_DELAY_MIN && +		   status <= RTAS_EXTENDED_DELAY_MAX) { +		order = status - RTAS_EXTENDED_DELAY_MIN;  		for (ms = 1; order > 0; order--)  			ms *= 10;  	} @@ -584,6 +585,23 @@ int rtas_get_sensor(int sensor, int index, int *state)  }  EXPORT_SYMBOL(rtas_get_sensor); +int rtas_get_sensor_fast(int sensor, int index, int *state) +{ +	int token = rtas_token("get-sensor-state"); +	int rc; + +	if (token == RTAS_UNKNOWN_SERVICE) +		return -ENOENT; + +	rc = rtas_call(token, 2, 2, state, sensor, index); +	WARN_ON(rc == RTAS_BUSY || (rc >= RTAS_EXTENDED_DELAY_MIN && +				    rc <= RTAS_EXTENDED_DELAY_MAX)); + +	if (rc < 0) +		return rtas_error_rc(rc); +	return rc; +} +  bool rtas_indicator_present(int token, int *maxindex)  {  	int proplen, count, i; @@ -641,7 +659,8 @@ int rtas_set_indicator_fast(int indicator, int index, int new_value)  	rc = rtas_call(token, 3, 1, NULL, indicator, index, new_value); -	WARN_ON(rc == -2 || (rc >= 9900 && rc <= 9905)); +	WARN_ON(rc == RTAS_BUSY || (rc >= RTAS_EXTENDED_DELAY_MIN && +				    rc <= RTAS_EXTENDED_DELAY_MAX));  	if (rc < 0)  		return rtas_error_rc(rc); diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index d3a831ac0f92..0dbee465af7a 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -949,6 +949,11 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *d, const siginfo_t *s)  		err |= __put_user(s->si_overrun, &d->si_overrun);  		err |= __put_user(s->si_int, &d->si_int);  		break; +	case __SI_SYS >> 16: +		err |= __put_user(ptr_to_compat(s->si_call_addr), &d->si_call_addr); +		err |= __put_user(s->si_syscall, &d->si_syscall); +		err |= __put_user(s->si_arch, &d->si_arch); +		break;  	case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */  	case __SI_MESGQ >> 16:  		err |= __put_user(s->si_int, &d->si_int); @@ -966,8 +971,6 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *d, const siginfo_t *s)  int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)  { -	memset(to, 0, sizeof *to); -  	if (copy_from_user(to, from, 3*sizeof(int)) ||  	    copy_from_user(to->_sifields._pad,  			   from->_sifields._pad, SI_PAD_SIZE32)) diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index c7c24d2e2bdb..20756dfb9f34 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -74,6 +74,19 @@ static const char fmt64[] = KERN_INFO \  	"%s[%d]: bad frame in %s: %016lx nip %016lx lr %016lx\n";  /* + * This computes a quad word aligned pointer inside the vmx_reserve array + * element. For historical reasons sigcontext might not be quad word aligned, + * but the location we write the VMX regs to must be. See the comment in + * sigcontext for more detail. + */ +#ifdef CONFIG_ALTIVEC +static elf_vrreg_t __user *sigcontext_vmx_regs(struct sigcontext __user *sc) +{ +	return (elf_vrreg_t __user *) (((unsigned long)sc->vmx_reserve + 15) & ~0xful); +} +#endif + +/*   * Set up the sigcontext for the signal frame.   */ @@ -90,7 +103,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,  	 * v_regs pointer or not  	 */  #ifdef CONFIG_ALTIVEC -	elf_vrreg_t __user *v_regs = (elf_vrreg_t __user *)(((unsigned long)sc->vmx_reserve + 15) & ~0xful); +	elf_vrreg_t __user *v_regs = sigcontext_vmx_regs(sc);  #endif  	unsigned long msr = regs->msr;  	long err = 0; @@ -181,10 +194,8 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc,  	 * v_regs pointer or not.  	 */  #ifdef CONFIG_ALTIVEC -	elf_vrreg_t __user *v_regs = (elf_vrreg_t __user *) -		(((unsigned long)sc->vmx_reserve + 15) & ~0xful); -	elf_vrreg_t __user *tm_v_regs = (elf_vrreg_t __user *) -		(((unsigned long)tm_sc->vmx_reserve + 15) & ~0xful); +	elf_vrreg_t __user *v_regs = sigcontext_vmx_regs(sc); +	elf_vrreg_t __user *tm_v_regs = sigcontext_vmx_regs(tm_sc);  #endif  	unsigned long msr = regs->msr;  	long err = 0; diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 43922509a483..1be1092c7204 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -99,16 +99,17 @@ static struct clocksource clocksource_timebase = {  static int decrementer_set_next_event(unsigned long evt,  				      struct clock_event_device *dev); -static void decrementer_set_mode(enum clock_event_mode mode, -				 struct clock_event_device *dev); +static int decrementer_shutdown(struct clock_event_device *evt);  struct clock_event_device decrementer_clockevent = { -	.name           = "decrementer", -	.rating         = 200, -	.irq            = 0, -	.set_next_event = decrementer_set_next_event, -	.set_mode       = decrementer_set_mode, -	.features       = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP, +	.name			= "decrementer", +	.rating			= 200, +	.irq			= 0, +	.set_next_event		= decrementer_set_next_event, +	.set_state_shutdown	= decrementer_shutdown, +	.tick_resume		= decrementer_shutdown, +	.features		= CLOCK_EVT_FEAT_ONESHOT | +				  CLOCK_EVT_FEAT_C3STOP,  };  EXPORT_SYMBOL(decrementer_clockevent); @@ -862,11 +863,10 @@ static int decrementer_set_next_event(unsigned long evt,  	return 0;  } -static void decrementer_set_mode(enum clock_event_mode mode, -				 struct clock_event_device *dev) +static int decrementer_shutdown(struct clock_event_device *dev)  { -	if (mode != CLOCK_EVT_MODE_ONESHOT) -		decrementer_set_next_event(DECREMENTER_MAX, dev); +	decrementer_set_next_event(DECREMENTER_MAX, dev); +	return 0;  }  /* Interrupt handler for the timer broadcast IPI */ diff --git a/arch/powerpc/kernel/trace_clock.c b/arch/powerpc/kernel/trace_clock.c new file mode 100644 index 000000000000..49170690946d --- /dev/null +++ b/arch/powerpc/kernel/trace_clock.c @@ -0,0 +1,15 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * Copyright (C) 2015 Naveen N. Rao, IBM Corporation + */ + +#include <asm/trace_clock.h> +#include <asm/time.h> + +u64 notrace trace_clock_ppc_tb(void) +{ +	return get_tb(); +} diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 3caec2c42105..c2024ac9d4e8 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -74,14 +74,14 @@ config KVM_BOOK3S_64  	  If unsure, say N.  config KVM_BOOK3S_64_HV -	tristate "KVM support for POWER7 and PPC970 using hypervisor mode in host" +	tristate "KVM for POWER7 and later using hypervisor mode in host"  	depends on KVM_BOOK3S_64 && PPC_POWERNV  	select KVM_BOOK3S_HV_POSSIBLE  	select MMU_NOTIFIER  	select CMA  	---help---  	  Support running unmodified book3s_64 guest kernels in -	  virtual machines on POWER7 and PPC970 processors that have +	  virtual machines on POWER7 and newer processors that have  	  hypervisor mode available to the host.  	  If you say Y here, KVM will use the hardware virtualization @@ -89,8 +89,8 @@ config KVM_BOOK3S_64_HV  	  guest operating systems will run at full hardware speed  	  using supervisor and user modes.  However, this also means  	  that KVM is not usable under PowerVM (pHyp), is only usable -	  on POWER7 (or later) processors and PPC970-family processors, -	  and cannot emulate a different processor from the host processor. +	  on POWER7 or later processors, and cannot emulate a +	  different processor from the host processor.  	  If unsure, say N. diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 05ea8fc7f829..d75bf325f54a 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -240,7 +240,8 @@ void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, ulong flags)  	kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_INST_STORAGE);  } -int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) +static int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, +					 unsigned int priority)  {  	int deliver = 1;  	int vec = 0; @@ -902,7 +903,7 @@ int kvmppc_core_check_processor_compat(void)  {  	/*  	 * We always return 0 for book3s. We check -	 * for compatability while loading the HV +	 * for compatibility while loading the HV  	 * or PR module  	 */  	return 0; diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c index 2035d16a9262..d5c9bfeb0c9c 100644 --- a/arch/powerpc/kvm/book3s_32_mmu_host.c +++ b/arch/powerpc/kvm/book3s_32_mmu_host.c @@ -26,6 +26,7 @@  #include <asm/machdep.h>  #include <asm/mmu_context.h>  #include <asm/hw_irq.h> +#include "book3s.h"  /* #define DEBUG_MMU */  /* #define DEBUG_SR */ diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index b982d925c710..79ad35abd196 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -28,6 +28,7 @@  #include <asm/mmu_context.h>  #include <asm/hw_irq.h>  #include "trace_pr.h" +#include "book3s.h"  #define PTE_SIZE 12 diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index dab68b7af3f2..1f9c0a17f445 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -761,6 +761,8 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,  			/* Harvest R and C */  			rcbits = be64_to_cpu(hptep[1]) & (HPTE_R_R | HPTE_R_C);  			*rmapp |= rcbits << KVMPPC_RMAP_RC_SHIFT; +			if (rcbits & HPTE_R_C) +				kvmppc_update_rmap_change(rmapp, psize);  			if (rcbits & ~rev[i].guest_rpte) {  				rev[i].guest_rpte = ptel | rcbits;  				note_hpte_modification(kvm, &rev[i]); @@ -927,8 +929,12 @@ static int kvm_test_clear_dirty_npages(struct kvm *kvm, unsigned long *rmapp)   retry:  	lock_rmap(rmapp);  	if (*rmapp & KVMPPC_RMAP_CHANGED) { -		*rmapp &= ~KVMPPC_RMAP_CHANGED; +		long change_order = (*rmapp & KVMPPC_RMAP_CHG_ORDER) +			>> KVMPPC_RMAP_CHG_SHIFT; +		*rmapp &= ~(KVMPPC_RMAP_CHANGED | KVMPPC_RMAP_CHG_ORDER);  		npages_dirty = 1; +		if (change_order > PAGE_SHIFT) +			npages_dirty = 1ul << (change_order - PAGE_SHIFT);  	}  	if (!(*rmapp & KVMPPC_RMAP_PRESENT)) {  		unlock_rmap(rmapp); diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 5a2bc4b0dfe5..2afdb9c0937d 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -23,6 +23,7 @@  #include <asm/reg.h>  #include <asm/switch_to.h>  #include <asm/time.h> +#include "book3s.h"  #define OP_19_XOP_RFID		18  #define OP_19_XOP_RFI		50 diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 68d067ad4222..9754e6815e52 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -81,6 +81,12 @@ static DECLARE_BITMAP(default_enabled_hcalls, MAX_HCALL_OPCODE/4 + 1);  #define MPP_BUFFER_ORDER	3  #endif +static int dynamic_mt_modes = 6; +module_param(dynamic_mt_modes, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(dynamic_mt_modes, "Set of allowed dynamic micro-threading modes: 0 (= none), 2, 4, or 6 (= 2 or 4)"); +static int target_smt_mode; +module_param(target_smt_mode, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(target_smt_mode, "Target threads per core (0 = max)");  static void kvmppc_end_cede(struct kvm_vcpu *vcpu);  static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); @@ -114,7 +120,7 @@ static bool kvmppc_ipi_thread(int cpu)  static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)  { -	int cpu = vcpu->cpu; +	int cpu;  	wait_queue_head_t *wqp;  	wqp = kvm_arch_vcpu_wq(vcpu); @@ -123,10 +129,11 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)  		++vcpu->stat.halt_wakeup;  	} -	if (kvmppc_ipi_thread(cpu + vcpu->arch.ptid)) +	if (kvmppc_ipi_thread(vcpu->arch.thread_cpu))  		return;  	/* CPU points to the first thread of the core */ +	cpu = vcpu->cpu;  	if (cpu >= 0 && cpu < nr_cpu_ids && cpu_online(cpu))  		smp_send_reschedule(cpu);  } @@ -164,6 +171,27 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu)   * they should never fail.)   */ +static void kvmppc_core_start_stolen(struct kvmppc_vcore *vc) +{ +	unsigned long flags; + +	spin_lock_irqsave(&vc->stoltb_lock, flags); +	vc->preempt_tb = mftb(); +	spin_unlock_irqrestore(&vc->stoltb_lock, flags); +} + +static void kvmppc_core_end_stolen(struct kvmppc_vcore *vc) +{ +	unsigned long flags; + +	spin_lock_irqsave(&vc->stoltb_lock, flags); +	if (vc->preempt_tb != TB_NIL) { +		vc->stolen_tb += mftb() - vc->preempt_tb; +		vc->preempt_tb = TB_NIL; +	} +	spin_unlock_irqrestore(&vc->stoltb_lock, flags); +} +  static void kvmppc_core_vcpu_load_hv(struct kvm_vcpu *vcpu, int cpu)  {  	struct kvmppc_vcore *vc = vcpu->arch.vcore; @@ -175,14 +203,9 @@ static void kvmppc_core_vcpu_load_hv(struct kvm_vcpu *vcpu, int cpu)  	 * vcpu, and once it is set to this vcpu, only this task  	 * ever sets it to NULL.  	 */ -	if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE) { -		spin_lock_irqsave(&vc->stoltb_lock, flags); -		if (vc->preempt_tb != TB_NIL) { -			vc->stolen_tb += mftb() - vc->preempt_tb; -			vc->preempt_tb = TB_NIL; -		} -		spin_unlock_irqrestore(&vc->stoltb_lock, flags); -	} +	if (vc->runner == vcpu && vc->vcore_state >= VCORE_SLEEPING) +		kvmppc_core_end_stolen(vc); +  	spin_lock_irqsave(&vcpu->arch.tbacct_lock, flags);  	if (vcpu->arch.state == KVMPPC_VCPU_BUSY_IN_HOST &&  	    vcpu->arch.busy_preempt != TB_NIL) { @@ -197,11 +220,9 @@ static void kvmppc_core_vcpu_put_hv(struct kvm_vcpu *vcpu)  	struct kvmppc_vcore *vc = vcpu->arch.vcore;  	unsigned long flags; -	if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE) { -		spin_lock_irqsave(&vc->stoltb_lock, flags); -		vc->preempt_tb = mftb(); -		spin_unlock_irqrestore(&vc->stoltb_lock, flags); -	} +	if (vc->runner == vcpu && vc->vcore_state >= VCORE_SLEEPING) +		kvmppc_core_start_stolen(vc); +  	spin_lock_irqsave(&vcpu->arch.tbacct_lock, flags);  	if (vcpu->arch.state == KVMPPC_VCPU_BUSY_IN_HOST)  		vcpu->arch.busy_preempt = mftb(); @@ -214,12 +235,12 @@ static void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr)  	kvmppc_end_cede(vcpu);  } -void kvmppc_set_pvr_hv(struct kvm_vcpu *vcpu, u32 pvr) +static void kvmppc_set_pvr_hv(struct kvm_vcpu *vcpu, u32 pvr)  {  	vcpu->arch.pvr = pvr;  } -int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat) +static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)  {  	unsigned long pcr = 0;  	struct kvmppc_vcore *vc = vcpu->arch.vcore; @@ -259,7 +280,7 @@ int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)  	return 0;  } -void kvmppc_dump_regs(struct kvm_vcpu *vcpu) +static void kvmppc_dump_regs(struct kvm_vcpu *vcpu)  {  	int r; @@ -292,7 +313,7 @@ void kvmppc_dump_regs(struct kvm_vcpu *vcpu)  	       vcpu->arch.last_inst);  } -struct kvm_vcpu *kvmppc_find_vcpu(struct kvm *kvm, int id) +static struct kvm_vcpu *kvmppc_find_vcpu(struct kvm *kvm, int id)  {  	int r;  	struct kvm_vcpu *v, *ret = NULL; @@ -641,7 +662,8 @@ static int kvm_arch_vcpu_yield_to(struct kvm_vcpu *target)  	spin_lock(&vcore->lock);  	if (target->arch.state == KVMPPC_VCPU_RUNNABLE && -	    vcore->vcore_state != VCORE_INACTIVE) +	    vcore->vcore_state != VCORE_INACTIVE && +	    vcore->runner)  		target = vcore->runner;  	spin_unlock(&vcore->lock); @@ -1431,6 +1453,7 @@ static struct kvmppc_vcore *kvmppc_vcore_create(struct kvm *kvm, int core)  	vcore->lpcr = kvm->arch.lpcr;  	vcore->first_vcpuid = core * threads_per_subcore;  	vcore->kvm = kvm; +	INIT_LIST_HEAD(&vcore->preempt_list);  	vcore->mpp_buffer_is_valid = false; @@ -1655,6 +1678,7 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm,  	spin_unlock(&vcore->lock);  	vcpu->arch.vcore = vcore;  	vcpu->arch.ptid = vcpu->vcpu_id - vcore->first_vcpuid; +	vcpu->arch.thread_cpu = -1;  	vcpu->arch.cpu_type = KVM_CPU_3S_64;  	kvmppc_sanity_check(vcpu); @@ -1749,6 +1773,7 @@ static int kvmppc_grab_hwthread(int cpu)  	/* Ensure the thread won't go into the kernel if it wakes */  	tpaca->kvm_hstate.kvm_vcpu = NULL; +	tpaca->kvm_hstate.kvm_vcore = NULL;  	tpaca->kvm_hstate.napping = 0;  	smp_wmb();  	tpaca->kvm_hstate.hwthread_req = 1; @@ -1780,26 +1805,32 @@ static void kvmppc_release_hwthread(int cpu)  	tpaca = &paca[cpu];  	tpaca->kvm_hstate.hwthread_req = 0;  	tpaca->kvm_hstate.kvm_vcpu = NULL; +	tpaca->kvm_hstate.kvm_vcore = NULL; +	tpaca->kvm_hstate.kvm_split_mode = NULL;  } -static void kvmppc_start_thread(struct kvm_vcpu *vcpu) +static void kvmppc_start_thread(struct kvm_vcpu *vcpu, struct kvmppc_vcore *vc)  {  	int cpu;  	struct paca_struct *tpaca; -	struct kvmppc_vcore *vc = vcpu->arch.vcore; +	struct kvmppc_vcore *mvc = vc->master_vcore; -	if (vcpu->arch.timer_running) { -		hrtimer_try_to_cancel(&vcpu->arch.dec_timer); -		vcpu->arch.timer_running = 0; +	cpu = vc->pcpu; +	if (vcpu) { +		if (vcpu->arch.timer_running) { +			hrtimer_try_to_cancel(&vcpu->arch.dec_timer); +			vcpu->arch.timer_running = 0; +		} +		cpu += vcpu->arch.ptid; +		vcpu->cpu = mvc->pcpu; +		vcpu->arch.thread_cpu = cpu;  	} -	cpu = vc->pcpu + vcpu->arch.ptid;  	tpaca = &paca[cpu]; -	tpaca->kvm_hstate.kvm_vcore = vc; -	tpaca->kvm_hstate.ptid = vcpu->arch.ptid; -	vcpu->cpu = vc->pcpu; -	/* Order stores to hstate.kvm_vcore etc. before store to kvm_vcpu */ -	smp_wmb();  	tpaca->kvm_hstate.kvm_vcpu = vcpu; +	tpaca->kvm_hstate.ptid = cpu - mvc->pcpu; +	/* Order stores to hstate.kvm_vcpu etc. before store to kvm_vcore */ +	smp_wmb(); +	tpaca->kvm_hstate.kvm_vcore = mvc;  	if (cpu != smp_processor_id())  		kvmppc_ipi_thread(cpu);  } @@ -1812,12 +1843,12 @@ static void kvmppc_wait_for_nap(void)  	for (loops = 0; loops < 1000000; ++loops) {  		/*  		 * Check if all threads are finished. -		 * We set the vcpu pointer when starting a thread +		 * We set the vcore pointer when starting a thread  		 * and the thread clears it when finished, so we look -		 * for any threads that still have a non-NULL vcpu ptr. +		 * for any threads that still have a non-NULL vcore ptr.  		 */  		for (i = 1; i < threads_per_subcore; ++i) -			if (paca[cpu + i].kvm_hstate.kvm_vcpu) +			if (paca[cpu + i].kvm_hstate.kvm_vcore)  				break;  		if (i == threads_per_subcore) {  			HMT_medium(); @@ -1827,7 +1858,7 @@ static void kvmppc_wait_for_nap(void)  	}  	HMT_medium();  	for (i = 1; i < threads_per_subcore; ++i) -		if (paca[cpu + i].kvm_hstate.kvm_vcpu) +		if (paca[cpu + i].kvm_hstate.kvm_vcore)  			pr_err("KVM: CPU %d seems to be stuck\n", cpu + i);  } @@ -1890,6 +1921,278 @@ static void kvmppc_start_restoring_l2_cache(const struct kvmppc_vcore *vc)  	mtspr(SPRN_MPPR, mpp_addr | PPC_MPPR_FETCH_WHOLE_TABLE);  } +/* + * A list of virtual cores for each physical CPU. + * These are vcores that could run but their runner VCPU tasks are + * (or may be) preempted. + */ +struct preempted_vcore_list { +	struct list_head	list; +	spinlock_t		lock; +}; + +static DEFINE_PER_CPU(struct preempted_vcore_list, preempted_vcores); + +static void init_vcore_lists(void) +{ +	int cpu; + +	for_each_possible_cpu(cpu) { +		struct preempted_vcore_list *lp = &per_cpu(preempted_vcores, cpu); +		spin_lock_init(&lp->lock); +		INIT_LIST_HEAD(&lp->list); +	} +} + +static void kvmppc_vcore_preempt(struct kvmppc_vcore *vc) +{ +	struct preempted_vcore_list *lp = this_cpu_ptr(&preempted_vcores); + +	vc->vcore_state = VCORE_PREEMPT; +	vc->pcpu = smp_processor_id(); +	if (vc->num_threads < threads_per_subcore) { +		spin_lock(&lp->lock); +		list_add_tail(&vc->preempt_list, &lp->list); +		spin_unlock(&lp->lock); +	} + +	/* Start accumulating stolen time */ +	kvmppc_core_start_stolen(vc); +} + +static void kvmppc_vcore_end_preempt(struct kvmppc_vcore *vc) +{ +	struct preempted_vcore_list *lp; + +	kvmppc_core_end_stolen(vc); +	if (!list_empty(&vc->preempt_list)) { +		lp = &per_cpu(preempted_vcores, vc->pcpu); +		spin_lock(&lp->lock); +		list_del_init(&vc->preempt_list); +		spin_unlock(&lp->lock); +	} +	vc->vcore_state = VCORE_INACTIVE; +} + +/* + * This stores information about the virtual cores currently + * assigned to a physical core. + */ +struct core_info { +	int		n_subcores; +	int		max_subcore_threads; +	int		total_threads; +	int		subcore_threads[MAX_SUBCORES]; +	struct kvm	*subcore_vm[MAX_SUBCORES]; +	struct list_head vcs[MAX_SUBCORES]; +}; + +/* + * This mapping means subcores 0 and 1 can use threads 0-3 and 4-7 + * respectively in 2-way micro-threading (split-core) mode. + */ +static int subcore_thread_map[MAX_SUBCORES] = { 0, 4, 2, 6 }; + +static void init_core_info(struct core_info *cip, struct kvmppc_vcore *vc) +{ +	int sub; + +	memset(cip, 0, sizeof(*cip)); +	cip->n_subcores = 1; +	cip->max_subcore_threads = vc->num_threads; +	cip->total_threads = vc->num_threads; +	cip->subcore_threads[0] = vc->num_threads; +	cip->subcore_vm[0] = vc->kvm; +	for (sub = 0; sub < MAX_SUBCORES; ++sub) +		INIT_LIST_HEAD(&cip->vcs[sub]); +	list_add_tail(&vc->preempt_list, &cip->vcs[0]); +} + +static bool subcore_config_ok(int n_subcores, int n_threads) +{ +	/* Can only dynamically split if unsplit to begin with */ +	if (n_subcores > 1 && threads_per_subcore < MAX_SMT_THREADS) +		return false; +	if (n_subcores > MAX_SUBCORES) +		return false; +	if (n_subcores > 1) { +		if (!(dynamic_mt_modes & 2)) +			n_subcores = 4; +		if (n_subcores > 2 && !(dynamic_mt_modes & 4)) +			return false; +	} + +	return n_subcores * roundup_pow_of_two(n_threads) <= MAX_SMT_THREADS; +} + +static void init_master_vcore(struct kvmppc_vcore *vc) +{ +	vc->master_vcore = vc; +	vc->entry_exit_map = 0; +	vc->in_guest = 0; +	vc->napping_threads = 0; +	vc->conferring_threads = 0; +} + +/* + * See if the existing subcores can be split into 3 (or fewer) subcores + * of at most two threads each, so we can fit in another vcore.  This + * assumes there are at most two subcores and at most 6 threads in total. + */ +static bool can_split_piggybacked_subcores(struct core_info *cip) +{ +	int sub, new_sub; +	int large_sub = -1; +	int thr; +	int n_subcores = cip->n_subcores; +	struct kvmppc_vcore *vc, *vcnext; +	struct kvmppc_vcore *master_vc = NULL; + +	for (sub = 0; sub < cip->n_subcores; ++sub) { +		if (cip->subcore_threads[sub] <= 2) +			continue; +		if (large_sub >= 0) +			return false; +		large_sub = sub; +		vc = list_first_entry(&cip->vcs[sub], struct kvmppc_vcore, +				      preempt_list); +		if (vc->num_threads > 2) +			return false; +		n_subcores += (cip->subcore_threads[sub] - 1) >> 1; +	} +	if (n_subcores > 3 || large_sub < 0) +		return false; + +	/* +	 * Seems feasible, so go through and move vcores to new subcores. +	 * Note that when we have two or more vcores in one subcore, +	 * all those vcores must have only one thread each. +	 */ +	new_sub = cip->n_subcores; +	thr = 0; +	sub = large_sub; +	list_for_each_entry_safe(vc, vcnext, &cip->vcs[sub], preempt_list) { +		if (thr >= 2) { +			list_del(&vc->preempt_list); +			list_add_tail(&vc->preempt_list, &cip->vcs[new_sub]); +			/* vc->num_threads must be 1 */ +			if (++cip->subcore_threads[new_sub] == 1) { +				cip->subcore_vm[new_sub] = vc->kvm; +				init_master_vcore(vc); +				master_vc = vc; +				++cip->n_subcores; +			} else { +				vc->master_vcore = master_vc; +				++new_sub; +			} +		} +		thr += vc->num_threads; +	} +	cip->subcore_threads[large_sub] = 2; +	cip->max_subcore_threads = 2; + +	return true; +} + +static bool can_dynamic_split(struct kvmppc_vcore *vc, struct core_info *cip) +{ +	int n_threads = vc->num_threads; +	int sub; + +	if (!cpu_has_feature(CPU_FTR_ARCH_207S)) +		return false; + +	if (n_threads < cip->max_subcore_threads) +		n_threads = cip->max_subcore_threads; +	if (subcore_config_ok(cip->n_subcores + 1, n_threads)) { +		cip->max_subcore_threads = n_threads; +	} else if (cip->n_subcores <= 2 && cip->total_threads <= 6 && +		   vc->num_threads <= 2) { +		/* +		 * We may be able to fit another subcore in by +		 * splitting an existing subcore with 3 or 4 +		 * threads into two 2-thread subcores, or one +		 * with 5 or 6 threads into three subcores. +		 * We can only do this if those subcores have +		 * piggybacked virtual cores. +		 */ +		if (!can_split_piggybacked_subcores(cip)) +			return false; +	} else { +		return false; +	} + +	sub = cip->n_subcores; +	++cip->n_subcores; +	cip->total_threads += vc->num_threads; +	cip->subcore_threads[sub] = vc->num_threads; +	cip->subcore_vm[sub] = vc->kvm; +	init_master_vcore(vc); +	list_del(&vc->preempt_list); +	list_add_tail(&vc->preempt_list, &cip->vcs[sub]); + +	return true; +} + +static bool can_piggyback_subcore(struct kvmppc_vcore *pvc, +				  struct core_info *cip, int sub) +{ +	struct kvmppc_vcore *vc; +	int n_thr; + +	vc = list_first_entry(&cip->vcs[sub], struct kvmppc_vcore, +			      preempt_list); + +	/* require same VM and same per-core reg values */ +	if (pvc->kvm != vc->kvm || +	    pvc->tb_offset != vc->tb_offset || +	    pvc->pcr != vc->pcr || +	    pvc->lpcr != vc->lpcr) +		return false; + +	/* P8 guest with > 1 thread per core would see wrong TIR value */ +	if (cpu_has_feature(CPU_FTR_ARCH_207S) && +	    (vc->num_threads > 1 || pvc->num_threads > 1)) +		return false; + +	n_thr = cip->subcore_threads[sub] + pvc->num_threads; +	if (n_thr > cip->max_subcore_threads) { +		if (!subcore_config_ok(cip->n_subcores, n_thr)) +			return false; +		cip->max_subcore_threads = n_thr; +	} + +	cip->total_threads += pvc->num_threads; +	cip->subcore_threads[sub] = n_thr; +	pvc->master_vcore = vc; +	list_del(&pvc->preempt_list); +	list_add_tail(&pvc->preempt_list, &cip->vcs[sub]); + +	return true; +} + +/* + * Work out whether it is possible to piggyback the execution of + * vcore *pvc onto the execution of the other vcores described in *cip. + */ +static bool can_piggyback(struct kvmppc_vcore *pvc, struct core_info *cip, +			  int target_threads) +{ +	int sub; + +	if (cip->total_threads + pvc->num_threads > target_threads) +		return false; +	for (sub = 0; sub < cip->n_subcores; ++sub) +		if (cip->subcore_threads[sub] && +		    can_piggyback_subcore(pvc, cip, sub)) +			return true; + +	if (can_dynamic_split(pvc, cip)) +		return true; + +	return false; +} +  static void prepare_threads(struct kvmppc_vcore *vc)  {  	struct kvm_vcpu *vcpu, *vnext; @@ -1909,12 +2212,45 @@ static void prepare_threads(struct kvmppc_vcore *vc)  	}  } -static void post_guest_process(struct kvmppc_vcore *vc) +static void collect_piggybacks(struct core_info *cip, int target_threads) +{ +	struct preempted_vcore_list *lp = this_cpu_ptr(&preempted_vcores); +	struct kvmppc_vcore *pvc, *vcnext; + +	spin_lock(&lp->lock); +	list_for_each_entry_safe(pvc, vcnext, &lp->list, preempt_list) { +		if (!spin_trylock(&pvc->lock)) +			continue; +		prepare_threads(pvc); +		if (!pvc->n_runnable) { +			list_del_init(&pvc->preempt_list); +			if (pvc->runner == NULL) { +				pvc->vcore_state = VCORE_INACTIVE; +				kvmppc_core_end_stolen(pvc); +			} +			spin_unlock(&pvc->lock); +			continue; +		} +		if (!can_piggyback(pvc, cip, target_threads)) { +			spin_unlock(&pvc->lock); +			continue; +		} +		kvmppc_core_end_stolen(pvc); +		pvc->vcore_state = VCORE_PIGGYBACK; +		if (cip->total_threads >= target_threads) +			break; +	} +	spin_unlock(&lp->lock); +} + +static void post_guest_process(struct kvmppc_vcore *vc, bool is_master)  { +	int still_running = 0;  	u64 now;  	long ret;  	struct kvm_vcpu *vcpu, *vnext; +	spin_lock(&vc->lock);  	now = get_tb();  	list_for_each_entry_safe(vcpu, vnext, &vc->runnable_threads,  				 arch.run_list) { @@ -1933,17 +2269,36 @@ static void post_guest_process(struct kvmppc_vcore *vc)  		vcpu->arch.ret = ret;  		vcpu->arch.trap = 0; -		if (vcpu->arch.ceded) { -			if (!is_kvmppc_resume_guest(ret)) -				kvmppc_end_cede(vcpu); -			else +		if (is_kvmppc_resume_guest(vcpu->arch.ret)) { +			if (vcpu->arch.pending_exceptions) +				kvmppc_core_prepare_to_enter(vcpu); +			if (vcpu->arch.ceded)  				kvmppc_set_timer(vcpu); -		} -		if (!is_kvmppc_resume_guest(vcpu->arch.ret)) { +			else +				++still_running; +		} else {  			kvmppc_remove_runnable(vc, vcpu);  			wake_up(&vcpu->arch.cpu_run);  		}  	} +	list_del_init(&vc->preempt_list); +	if (!is_master) { +		if (still_running > 0) { +			kvmppc_vcore_preempt(vc); +		} else if (vc->runner) { +			vc->vcore_state = VCORE_PREEMPT; +			kvmppc_core_start_stolen(vc); +		} else { +			vc->vcore_state = VCORE_INACTIVE; +		} +		if (vc->n_runnable > 0 && vc->runner == NULL) { +			/* make sure there's a candidate runner awake */ +			vcpu = list_first_entry(&vc->runnable_threads, +						struct kvm_vcpu, arch.run_list); +			wake_up(&vcpu->arch.cpu_run); +		} +	} +	spin_unlock(&vc->lock);  }  /* @@ -1955,6 +2310,15 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)  	struct kvm_vcpu *vcpu, *vnext;  	int i;  	int srcu_idx; +	struct core_info core_info; +	struct kvmppc_vcore *pvc, *vcnext; +	struct kvm_split_mode split_info, *sip; +	int split, subcore_size, active; +	int sub; +	bool thr0_done; +	unsigned long cmd_bit, stat_bit; +	int pcpu, thr; +	int target_threads;  	/*  	 * Remove from the list any threads that have a signal pending @@ -1969,11 +2333,8 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)  	/*  	 * Initialize *vc.  	 */ -	vc->entry_exit_map = 0; +	init_master_vcore(vc);  	vc->preempt_tb = TB_NIL; -	vc->in_guest = 0; -	vc->napping_threads = 0; -	vc->conferring_threads = 0;  	/*  	 * Make sure we are running on primary threads, and that secondary @@ -1991,24 +2352,120 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)  		goto out;  	} +	/* +	 * See if we could run any other vcores on the physical core +	 * along with this one. +	 */ +	init_core_info(&core_info, vc); +	pcpu = smp_processor_id(); +	target_threads = threads_per_subcore; +	if (target_smt_mode && target_smt_mode < target_threads) +		target_threads = target_smt_mode; +	if (vc->num_threads < target_threads) +		collect_piggybacks(&core_info, target_threads); + +	/* Decide on micro-threading (split-core) mode */ +	subcore_size = threads_per_subcore; +	cmd_bit = stat_bit = 0; +	split = core_info.n_subcores; +	sip = NULL; +	if (split > 1) { +		/* threads_per_subcore must be MAX_SMT_THREADS (8) here */ +		if (split == 2 && (dynamic_mt_modes & 2)) { +			cmd_bit = HID0_POWER8_1TO2LPAR; +			stat_bit = HID0_POWER8_2LPARMODE; +		} else { +			split = 4; +			cmd_bit = HID0_POWER8_1TO4LPAR; +			stat_bit = HID0_POWER8_4LPARMODE; +		} +		subcore_size = MAX_SMT_THREADS / split; +		sip = &split_info; +		memset(&split_info, 0, sizeof(split_info)); +		split_info.rpr = mfspr(SPRN_RPR); +		split_info.pmmar = mfspr(SPRN_PMMAR); +		split_info.ldbar = mfspr(SPRN_LDBAR); +		split_info.subcore_size = subcore_size; +		for (sub = 0; sub < core_info.n_subcores; ++sub) +			split_info.master_vcs[sub] = +				list_first_entry(&core_info.vcs[sub], +					struct kvmppc_vcore, preempt_list); +		/* order writes to split_info before kvm_split_mode pointer */ +		smp_wmb(); +	} +	pcpu = smp_processor_id(); +	for (thr = 0; thr < threads_per_subcore; ++thr) +		paca[pcpu + thr].kvm_hstate.kvm_split_mode = sip; + +	/* Initiate micro-threading (split-core) if required */ +	if (cmd_bit) { +		unsigned long hid0 = mfspr(SPRN_HID0); + +		hid0 |= cmd_bit | HID0_POWER8_DYNLPARDIS; +		mb(); +		mtspr(SPRN_HID0, hid0); +		isync(); +		for (;;) { +			hid0 = mfspr(SPRN_HID0); +			if (hid0 & stat_bit) +				break; +			cpu_relax(); +		} +	} -	vc->pcpu = smp_processor_id(); -	list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) { -		kvmppc_start_thread(vcpu); -		kvmppc_create_dtl_entry(vcpu, vc); -		trace_kvm_guest_enter(vcpu); +	/* Start all the threads */ +	active = 0; +	for (sub = 0; sub < core_info.n_subcores; ++sub) { +		thr = subcore_thread_map[sub]; +		thr0_done = false; +		active |= 1 << thr; +		list_for_each_entry(pvc, &core_info.vcs[sub], preempt_list) { +			pvc->pcpu = pcpu + thr; +			list_for_each_entry(vcpu, &pvc->runnable_threads, +					    arch.run_list) { +				kvmppc_start_thread(vcpu, pvc); +				kvmppc_create_dtl_entry(vcpu, pvc); +				trace_kvm_guest_enter(vcpu); +				if (!vcpu->arch.ptid) +					thr0_done = true; +				active |= 1 << (thr + vcpu->arch.ptid); +			} +			/* +			 * We need to start the first thread of each subcore +			 * even if it doesn't have a vcpu. +			 */ +			if (pvc->master_vcore == pvc && !thr0_done) +				kvmppc_start_thread(NULL, pvc); +			thr += pvc->num_threads; +		}  	} -	/* Set this explicitly in case thread 0 doesn't have a vcpu */ -	get_paca()->kvm_hstate.kvm_vcore = vc; -	get_paca()->kvm_hstate.ptid = 0; +	/* +	 * Ensure that split_info.do_nap is set after setting +	 * the vcore pointer in the PACA of the secondaries. +	 */ +	smp_mb(); +	if (cmd_bit) +		split_info.do_nap = 1;	/* ask secondaries to nap when done */ + +	/* +	 * When doing micro-threading, poke the inactive threads as well. +	 * This gets them to the nap instruction after kvm_do_nap, +	 * which reduces the time taken to unsplit later. +	 */ +	if (split > 1) +		for (thr = 1; thr < threads_per_subcore; ++thr) +			if (!(active & (1 << thr))) +				kvmppc_ipi_thread(pcpu + thr);  	vc->vcore_state = VCORE_RUNNING;  	preempt_disable();  	trace_kvmppc_run_core(vc, 0); -	spin_unlock(&vc->lock); +	for (sub = 0; sub < core_info.n_subcores; ++sub) +		list_for_each_entry(pvc, &core_info.vcs[sub], preempt_list) +			spin_unlock(&pvc->lock);  	kvm_guest_enter(); @@ -2019,32 +2476,58 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)  	__kvmppc_vcore_entry(); -	spin_lock(&vc->lock); -  	if (vc->mpp_buffer)  		kvmppc_start_saving_l2_cache(vc); -	/* disable sending of IPIs on virtual external irqs */ -	list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) -		vcpu->cpu = -1; -	/* wait for secondary threads to finish writing their state to memory */ -	kvmppc_wait_for_nap(); -	for (i = 0; i < threads_per_subcore; ++i) -		kvmppc_release_hwthread(vc->pcpu + i); +	srcu_read_unlock(&vc->kvm->srcu, srcu_idx); + +	spin_lock(&vc->lock);  	/* prevent other vcpu threads from doing kvmppc_start_thread() now */  	vc->vcore_state = VCORE_EXITING; -	spin_unlock(&vc->lock); -	srcu_read_unlock(&vc->kvm->srcu, srcu_idx); +	/* wait for secondary threads to finish writing their state to memory */ +	kvmppc_wait_for_nap(); + +	/* Return to whole-core mode if we split the core earlier */ +	if (split > 1) { +		unsigned long hid0 = mfspr(SPRN_HID0); +		unsigned long loops = 0; + +		hid0 &= ~HID0_POWER8_DYNLPARDIS; +		stat_bit = HID0_POWER8_2LPARMODE | HID0_POWER8_4LPARMODE; +		mb(); +		mtspr(SPRN_HID0, hid0); +		isync(); +		for (;;) { +			hid0 = mfspr(SPRN_HID0); +			if (!(hid0 & stat_bit)) +				break; +			cpu_relax(); +			++loops; +		} +		split_info.do_nap = 0; +	} + +	/* Let secondaries go back to the offline loop */ +	for (i = 0; i < threads_per_subcore; ++i) { +		kvmppc_release_hwthread(pcpu + i); +		if (sip && sip->napped[i]) +			kvmppc_ipi_thread(pcpu + i); +	} + +	spin_unlock(&vc->lock);  	/* make sure updates to secondary vcpu structs are visible now */  	smp_mb();  	kvm_guest_exit(); -	preempt_enable(); +	for (sub = 0; sub < core_info.n_subcores; ++sub) +		list_for_each_entry_safe(pvc, vcnext, &core_info.vcs[sub], +					 preempt_list) +			post_guest_process(pvc, pvc == vc);  	spin_lock(&vc->lock); -	post_guest_process(vc); +	preempt_enable();   out:  	vc->vcore_state = VCORE_INACTIVE; @@ -2055,13 +2538,17 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc)   * Wait for some other vcpu thread to execute us, and   * wake us up when we need to handle something in the host.   */ -static void kvmppc_wait_for_exec(struct kvm_vcpu *vcpu, int wait_state) +static void kvmppc_wait_for_exec(struct kvmppc_vcore *vc, +				 struct kvm_vcpu *vcpu, int wait_state)  {  	DEFINE_WAIT(wait);  	prepare_to_wait(&vcpu->arch.cpu_run, &wait, wait_state); -	if (vcpu->arch.state == KVMPPC_VCPU_RUNNABLE) +	if (vcpu->arch.state == KVMPPC_VCPU_RUNNABLE) { +		spin_unlock(&vc->lock);  		schedule(); +		spin_lock(&vc->lock); +	}  	finish_wait(&vcpu->arch.cpu_run, &wait);  } @@ -2137,9 +2624,21 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)  	 * this thread straight away and have it join in.  	 */  	if (!signal_pending(current)) { -		if (vc->vcore_state == VCORE_RUNNING && !VCORE_IS_EXITING(vc)) { +		if (vc->vcore_state == VCORE_PIGGYBACK) { +			struct kvmppc_vcore *mvc = vc->master_vcore; +			if (spin_trylock(&mvc->lock)) { +				if (mvc->vcore_state == VCORE_RUNNING && +				    !VCORE_IS_EXITING(mvc)) { +					kvmppc_create_dtl_entry(vcpu, vc); +					kvmppc_start_thread(vcpu, vc); +					trace_kvm_guest_enter(vcpu); +				} +				spin_unlock(&mvc->lock); +			} +		} else if (vc->vcore_state == VCORE_RUNNING && +			   !VCORE_IS_EXITING(vc)) {  			kvmppc_create_dtl_entry(vcpu, vc); -			kvmppc_start_thread(vcpu); +			kvmppc_start_thread(vcpu, vc);  			trace_kvm_guest_enter(vcpu);  		} else if (vc->vcore_state == VCORE_SLEEPING) {  			wake_up(&vc->wq); @@ -2149,10 +2648,11 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)  	while (vcpu->arch.state == KVMPPC_VCPU_RUNNABLE &&  	       !signal_pending(current)) { +		if (vc->vcore_state == VCORE_PREEMPT && vc->runner == NULL) +			kvmppc_vcore_end_preempt(vc); +  		if (vc->vcore_state != VCORE_INACTIVE) { -			spin_unlock(&vc->lock); -			kvmppc_wait_for_exec(vcpu, TASK_INTERRUPTIBLE); -			spin_lock(&vc->lock); +			kvmppc_wait_for_exec(vc, vcpu, TASK_INTERRUPTIBLE);  			continue;  		}  		list_for_each_entry_safe(v, vn, &vc->runnable_threads, @@ -2178,11 +2678,12 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)  		vc->runner = vcpu;  		if (n_ceded == vc->n_runnable) {  			kvmppc_vcore_blocked(vc); -		} else if (should_resched()) { -			vc->vcore_state = VCORE_PREEMPT; +		} else if (need_resched()) { +			kvmppc_vcore_preempt(vc);  			/* Let something else run */  			cond_resched_lock(&vc->lock); -			vc->vcore_state = VCORE_INACTIVE; +			if (vc->vcore_state == VCORE_PREEMPT) +				kvmppc_vcore_end_preempt(vc);  		} else {  			kvmppc_run_core(vc);  		} @@ -2191,11 +2692,8 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)  	while (vcpu->arch.state == KVMPPC_VCPU_RUNNABLE &&  	       (vc->vcore_state == VCORE_RUNNING || -		vc->vcore_state == VCORE_EXITING)) { -		spin_unlock(&vc->lock); -		kvmppc_wait_for_exec(vcpu, TASK_UNINTERRUPTIBLE); -		spin_lock(&vc->lock); -	} +		vc->vcore_state == VCORE_EXITING)) +		kvmppc_wait_for_exec(vc, vcpu, TASK_UNINTERRUPTIBLE);  	if (vcpu->arch.state == KVMPPC_VCPU_RUNNABLE) {  		kvmppc_remove_runnable(vc, vcpu); @@ -2755,6 +3253,8 @@ static int kvmppc_book3s_init_hv(void)  	init_default_hcalls(); +	init_vcore_lists(); +  	r = kvmppc_mmu_hv_init();  	return r;  } diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index ed2589d4593f..fd7006bf6b1a 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -110,14 +110,15 @@ void __init kvm_cma_reserve(void)  long int kvmppc_rm_h_confer(struct kvm_vcpu *vcpu, int target,  			    unsigned int yield_count)  { -	struct kvmppc_vcore *vc = vcpu->arch.vcore; +	struct kvmppc_vcore *vc = local_paca->kvm_hstate.kvm_vcore; +	int ptid = local_paca->kvm_hstate.ptid;  	int threads_running;  	int threads_ceded;  	int threads_conferring;  	u64 stop = get_tb() + 10 * tb_ticks_per_usec;  	int rv = H_SUCCESS; /* => don't yield */ -	set_bit(vcpu->arch.ptid, &vc->conferring_threads); +	set_bit(ptid, &vc->conferring_threads);  	while ((get_tb() < stop) && !VCORE_IS_EXITING(vc)) {  		threads_running = VCORE_ENTRY_MAP(vc);  		threads_ceded = vc->napping_threads; @@ -127,7 +128,7 @@ long int kvmppc_rm_h_confer(struct kvm_vcpu *vcpu, int target,  			break;  		}  	} -	clear_bit(vcpu->arch.ptid, &vc->conferring_threads); +	clear_bit(ptid, &vc->conferring_threads);  	return rv;  } @@ -238,7 +239,8 @@ void kvmhv_commence_exit(int trap)  {  	struct kvmppc_vcore *vc = local_paca->kvm_hstate.kvm_vcore;  	int ptid = local_paca->kvm_hstate.ptid; -	int me, ee; +	struct kvm_split_mode *sip = local_paca->kvm_hstate.kvm_split_mode; +	int me, ee, i;  	/* Set our bit in the threads-exiting-guest map in the 0xff00  	   bits of vcore->entry_exit_map */ @@ -258,4 +260,26 @@ void kvmhv_commence_exit(int trap)  	 */  	if (trap != BOOK3S_INTERRUPT_HV_DECREMENTER)  		kvmhv_interrupt_vcore(vc, ee & ~(1 << ptid)); + +	/* +	 * If we are doing dynamic micro-threading, interrupt the other +	 * subcores to pull them out of their guests too. +	 */ +	if (!sip) +		return; + +	for (i = 0; i < MAX_SUBCORES; ++i) { +		vc = sip->master_vcs[i]; +		if (!vc) +			break; +		do { +			ee = vc->entry_exit_map; +			/* Already asked to exit? */ +			if ((ee >> 8) != 0) +				break; +		} while (cmpxchg(&vc->entry_exit_map, ee, +				 ee | VCORE_EXIT_REQ) != ee); +		if ((ee >> 8) == 0) +			kvmhv_interrupt_vcore(vc, ee); +	}  } diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index b027a89737b6..c1df9bb1e413 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c @@ -12,6 +12,7 @@  #include <linux/kvm_host.h>  #include <linux/hugetlb.h>  #include <linux/module.h> +#include <linux/log2.h>  #include <asm/tlbflush.h>  #include <asm/kvm_ppc.h> @@ -97,25 +98,52 @@ void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev,  }  EXPORT_SYMBOL_GPL(kvmppc_add_revmap_chain); +/* Update the changed page order field of an rmap entry */ +void kvmppc_update_rmap_change(unsigned long *rmap, unsigned long psize) +{ +	unsigned long order; + +	if (!psize) +		return; +	order = ilog2(psize); +	order <<= KVMPPC_RMAP_CHG_SHIFT; +	if (order > (*rmap & KVMPPC_RMAP_CHG_ORDER)) +		*rmap = (*rmap & ~KVMPPC_RMAP_CHG_ORDER) | order; +} +EXPORT_SYMBOL_GPL(kvmppc_update_rmap_change); + +/* Returns a pointer to the revmap entry for the page mapped by a HPTE */ +static unsigned long *revmap_for_hpte(struct kvm *kvm, unsigned long hpte_v, +				      unsigned long hpte_gr) +{ +	struct kvm_memory_slot *memslot; +	unsigned long *rmap; +	unsigned long gfn; + +	gfn = hpte_rpn(hpte_gr, hpte_page_size(hpte_v, hpte_gr)); +	memslot = __gfn_to_memslot(kvm_memslots_raw(kvm), gfn); +	if (!memslot) +		return NULL; + +	rmap = real_vmalloc_addr(&memslot->arch.rmap[gfn - memslot->base_gfn]); +	return rmap; +} +  /* Remove this HPTE from the chain for a real page */  static void remove_revmap_chain(struct kvm *kvm, long pte_index,  				struct revmap_entry *rev,  				unsigned long hpte_v, unsigned long hpte_r)  {  	struct revmap_entry *next, *prev; -	unsigned long gfn, ptel, head; -	struct kvm_memory_slot *memslot; +	unsigned long ptel, head;  	unsigned long *rmap;  	unsigned long rcbits;  	rcbits = hpte_r & (HPTE_R_R | HPTE_R_C);  	ptel = rev->guest_rpte |= rcbits; -	gfn = hpte_rpn(ptel, hpte_page_size(hpte_v, ptel)); -	memslot = __gfn_to_memslot(kvm_memslots_raw(kvm), gfn); -	if (!memslot) +	rmap = revmap_for_hpte(kvm, hpte_v, ptel); +	if (!rmap)  		return; - -	rmap = real_vmalloc_addr(&memslot->arch.rmap[gfn - memslot->base_gfn]);  	lock_rmap(rmap);  	head = *rmap & KVMPPC_RMAP_INDEX; @@ -131,6 +159,8 @@ static void remove_revmap_chain(struct kvm *kvm, long pte_index,  			*rmap = (*rmap & ~KVMPPC_RMAP_INDEX) | head;  	}  	*rmap |= rcbits << KVMPPC_RMAP_RC_SHIFT; +	if (rcbits & HPTE_R_C) +		kvmppc_update_rmap_change(rmap, hpte_page_size(hpte_v, hpte_r));  	unlock_rmap(rmap);  } @@ -421,14 +451,20 @@ long kvmppc_do_h_remove(struct kvm *kvm, unsigned long flags,  	rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]);  	v = pte & ~HPTE_V_HVLOCK;  	if (v & HPTE_V_VALID) { -		u64 pte1; - -		pte1 = be64_to_cpu(hpte[1]);  		hpte[0] &= ~cpu_to_be64(HPTE_V_VALID); -		rb = compute_tlbie_rb(v, pte1, pte_index); +		rb = compute_tlbie_rb(v, be64_to_cpu(hpte[1]), pte_index);  		do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags), true); -		/* Read PTE low word after tlbie to get final R/C values */ -		remove_revmap_chain(kvm, pte_index, rev, v, pte1); +		/* +		 * The reference (R) and change (C) bits in a HPT +		 * entry can be set by hardware at any time up until +		 * the HPTE is invalidated and the TLB invalidation +		 * sequence has completed.  This means that when +		 * removing a HPTE, we need to re-read the HPTE after +		 * the invalidation sequence has completed in order to +		 * obtain reliable values of R and C. +		 */ +		remove_revmap_chain(kvm, pte_index, rev, v, +				    be64_to_cpu(hpte[1]));  	}  	r = rev->guest_rpte & ~HPTE_GR_RESERVED;  	note_hpte_modification(kvm, rev); @@ -655,6 +691,105 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags,  	return H_SUCCESS;  } +long kvmppc_h_clear_ref(struct kvm_vcpu *vcpu, unsigned long flags, +			unsigned long pte_index) +{ +	struct kvm *kvm = vcpu->kvm; +	__be64 *hpte; +	unsigned long v, r, gr; +	struct revmap_entry *rev; +	unsigned long *rmap; +	long ret = H_NOT_FOUND; + +	if (pte_index >= kvm->arch.hpt_npte) +		return H_PARAMETER; + +	rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); +	hpte = (__be64 *)(kvm->arch.hpt_virt + (pte_index << 4)); +	while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) +		cpu_relax(); +	v = be64_to_cpu(hpte[0]); +	r = be64_to_cpu(hpte[1]); +	if (!(v & (HPTE_V_VALID | HPTE_V_ABSENT))) +		goto out; + +	gr = rev->guest_rpte; +	if (rev->guest_rpte & HPTE_R_R) { +		rev->guest_rpte &= ~HPTE_R_R; +		note_hpte_modification(kvm, rev); +	} +	if (v & HPTE_V_VALID) { +		gr |= r & (HPTE_R_R | HPTE_R_C); +		if (r & HPTE_R_R) { +			kvmppc_clear_ref_hpte(kvm, hpte, pte_index); +			rmap = revmap_for_hpte(kvm, v, gr); +			if (rmap) { +				lock_rmap(rmap); +				*rmap |= KVMPPC_RMAP_REFERENCED; +				unlock_rmap(rmap); +			} +		} +	} +	vcpu->arch.gpr[4] = gr; +	ret = H_SUCCESS; + out: +	unlock_hpte(hpte, v & ~HPTE_V_HVLOCK); +	return ret; +} + +long kvmppc_h_clear_mod(struct kvm_vcpu *vcpu, unsigned long flags, +			unsigned long pte_index) +{ +	struct kvm *kvm = vcpu->kvm; +	__be64 *hpte; +	unsigned long v, r, gr; +	struct revmap_entry *rev; +	unsigned long *rmap; +	long ret = H_NOT_FOUND; + +	if (pte_index >= kvm->arch.hpt_npte) +		return H_PARAMETER; + +	rev = real_vmalloc_addr(&kvm->arch.revmap[pte_index]); +	hpte = (__be64 *)(kvm->arch.hpt_virt + (pte_index << 4)); +	while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) +		cpu_relax(); +	v = be64_to_cpu(hpte[0]); +	r = be64_to_cpu(hpte[1]); +	if (!(v & (HPTE_V_VALID | HPTE_V_ABSENT))) +		goto out; + +	gr = rev->guest_rpte; +	if (gr & HPTE_R_C) { +		rev->guest_rpte &= ~HPTE_R_C; +		note_hpte_modification(kvm, rev); +	} +	if (v & HPTE_V_VALID) { +		/* need to make it temporarily absent so C is stable */ +		hpte[0] |= cpu_to_be64(HPTE_V_ABSENT); +		kvmppc_invalidate_hpte(kvm, hpte, pte_index); +		r = be64_to_cpu(hpte[1]); +		gr |= r & (HPTE_R_R | HPTE_R_C); +		if (r & HPTE_R_C) { +			unsigned long psize = hpte_page_size(v, r); +			hpte[1] = cpu_to_be64(r & ~HPTE_R_C); +			eieio(); +			rmap = revmap_for_hpte(kvm, v, gr); +			if (rmap) { +				lock_rmap(rmap); +				*rmap |= KVMPPC_RMAP_CHANGED; +				kvmppc_update_rmap_change(rmap, psize); +				unlock_rmap(rmap); +			} +		} +	} +	vcpu->arch.gpr[4] = gr; +	ret = H_SUCCESS; + out: +	unlock_hpte(hpte, v & ~HPTE_V_HVLOCK); +	return ret; +} +  void kvmppc_invalidate_hpte(struct kvm *kvm, __be64 *hptep,  			unsigned long pte_index)  { diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c index 00e45b6d4f24..24f58076d49e 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_xics.c +++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c @@ -67,14 +67,12 @@ static void icp_rm_set_vcpu_irq(struct kvm_vcpu *vcpu,  	}  	/* Check if the core is loaded, if not, too hard */ -	cpu = vcpu->cpu; +	cpu = vcpu->arch.thread_cpu;  	if (cpu < 0 || cpu >= nr_cpu_ids) {  		this_icp->rm_action |= XICS_RM_KICK_VCPU;  		this_icp->rm_kick_target = vcpu;  		return;  	} -	/* In SMT cpu will always point to thread 0, we adjust it */ -	cpu += vcpu->arch.ptid;  	smp_mb();  	kvmhv_rm_send_ipi(cpu); diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index faa86e9c0551..2273dcacef39 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -128,6 +128,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)  	subf	r4, r4, r3  	mtspr	SPRN_DEC, r4 +	/* hwthread_req may have got set by cede or no vcpu, so clear it */ +	li	r0, 0 +	stb	r0, HSTATE_HWTHREAD_REQ(r13) +  	/*  	 * For external and machine check interrupts, we need  	 * to call the Linux handler to process the interrupt. @@ -215,7 +219,6 @@ kvm_novcpu_wakeup:  	ld	r5, HSTATE_KVM_VCORE(r13)  	li	r0, 0  	stb	r0, HSTATE_NAPPING(r13) -	stb	r0, HSTATE_HWTHREAD_REQ(r13)  	/* check the wake reason */  	bl	kvmppc_check_wake_reason @@ -315,10 +318,10 @@ kvm_start_guest:  	cmpdi	r3, 0  	bge	kvm_no_guest -	/* get vcpu pointer, NULL if we have no vcpu to run */ -	ld	r4,HSTATE_KVM_VCPU(r13) -	cmpdi	r4,0 -	/* if we have no vcpu to run, go back to sleep */ +	/* get vcore pointer, NULL if we have nothing to run */ +	ld	r5,HSTATE_KVM_VCORE(r13) +	cmpdi	r5,0 +	/* if we have no vcore to run, go back to sleep */  	beq	kvm_no_guest  kvm_secondary_got_guest: @@ -327,21 +330,42 @@ kvm_secondary_got_guest:  	ld	r6, PACA_DSCR_DEFAULT(r13)  	std	r6, HSTATE_DSCR(r13) -	/* Order load of vcore, ptid etc. after load of vcpu */ +	/* On thread 0 of a subcore, set HDEC to max */ +	lbz	r4, HSTATE_PTID(r13) +	cmpwi	r4, 0 +	bne	63f +	lis	r6, 0x7fff +	ori	r6, r6, 0xffff +	mtspr	SPRN_HDEC, r6 +	/* and set per-LPAR registers, if doing dynamic micro-threading */ +	ld	r6, HSTATE_SPLIT_MODE(r13) +	cmpdi	r6, 0 +	beq	63f +	ld	r0, KVM_SPLIT_RPR(r6) +	mtspr	SPRN_RPR, r0 +	ld	r0, KVM_SPLIT_PMMAR(r6) +	mtspr	SPRN_PMMAR, r0 +	ld	r0, KVM_SPLIT_LDBAR(r6) +	mtspr	SPRN_LDBAR, r0 +	isync +63: +	/* Order load of vcpu after load of vcore */  	lwsync +	ld	r4, HSTATE_KVM_VCPU(r13)  	bl	kvmppc_hv_entry  	/* Back from the guest, go back to nap */ -	/* Clear our vcpu pointer so we don't come back in early */ +	/* Clear our vcpu and vcore pointers so we don't come back in early */  	li	r0, 0 +	std	r0, HSTATE_KVM_VCPU(r13)  	/* -	 * Once we clear HSTATE_KVM_VCPU(r13), the code in +	 * Once we clear HSTATE_KVM_VCORE(r13), the code in  	 * kvmppc_run_core() is going to assume that all our vcpu  	 * state is visible in memory.  This lwsync makes sure  	 * that that is true.  	 */  	lwsync -	std	r0, HSTATE_KVM_VCPU(r13) +	std	r0, HSTATE_KVM_VCORE(r13)  /*   * At this point we have finished executing in the guest. @@ -374,16 +398,71 @@ kvm_no_guest:  	b	power7_wakeup_loss  53:	HMT_LOW -	ld	r4, HSTATE_KVM_VCPU(r13) -	cmpdi	r4, 0 +	ld	r5, HSTATE_KVM_VCORE(r13) +	cmpdi	r5, 0 +	bne	60f +	ld	r3, HSTATE_SPLIT_MODE(r13) +	cmpdi	r3, 0 +	beq	kvm_no_guest +	lbz	r0, KVM_SPLIT_DO_NAP(r3) +	cmpwi	r0, 0  	beq	kvm_no_guest  	HMT_MEDIUM +	b	kvm_unsplit_nap +60:	HMT_MEDIUM  	b	kvm_secondary_got_guest  54:	li	r0, KVM_HWTHREAD_IN_KVM  	stb	r0, HSTATE_HWTHREAD_STATE(r13)  	b	kvm_no_guest +/* + * Here the primary thread is trying to return the core to + * whole-core mode, so we need to nap. + */ +kvm_unsplit_nap: +	/* +	 * Ensure that secondary doesn't nap when it has +	 * its vcore pointer set. +	 */ +	sync		/* matches smp_mb() before setting split_info.do_nap */ +	ld	r0, HSTATE_KVM_VCORE(r13) +	cmpdi	r0, 0 +	bne	kvm_no_guest +	/* clear any pending message */ +BEGIN_FTR_SECTION +	lis	r6, (PPC_DBELL_SERVER << (63-36))@h +	PPC_MSGCLR(6) +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) +	/* Set kvm_split_mode.napped[tid] = 1 */ +	ld	r3, HSTATE_SPLIT_MODE(r13) +	li	r0, 1 +	lhz	r4, PACAPACAINDEX(r13) +	clrldi	r4, r4, 61	/* micro-threading => P8 => 8 threads/core */ +	addi	r4, r4, KVM_SPLIT_NAPPED +	stbx	r0, r3, r4 +	/* Check the do_nap flag again after setting napped[] */ +	sync +	lbz	r0, KVM_SPLIT_DO_NAP(r3) +	cmpwi	r0, 0 +	beq	57f +	li	r3, (LPCR_PECEDH | LPCR_PECE0) >> 4 +	mfspr	r4, SPRN_LPCR +	rlwimi	r4, r3, 4, (LPCR_PECEDP | LPCR_PECEDH | LPCR_PECE0 | LPCR_PECE1) +	mtspr	SPRN_LPCR, r4 +	isync +	std	r0, HSTATE_SCRATCH0(r13) +	ptesync +	ld	r0, HSTATE_SCRATCH0(r13) +1:	cmpd	r0, r0 +	bne	1b +	nap +	b	. + +57:	li	r0, 0 +	stbx	r0, r3, r4 +	b	kvm_no_guest +  /******************************************************************************   *                                                                            *   *                               Entry code                                   * @@ -854,7 +933,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)  	cmpwi	r0, 0  	bne	21f  	HMT_LOW -20:	lbz	r0, VCORE_IN_GUEST(r5) +20:	lwz	r3, VCORE_ENTRY_EXIT(r5) +	cmpwi	r3, 0x100 +	bge	no_switch_exit +	lbz	r0, VCORE_IN_GUEST(r5)  	cmpwi	r0, 0  	beq	20b  	HMT_MEDIUM @@ -870,7 +952,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)  	blt	hdec_soon  	ld	r6, VCPU_CTR(r4) -	lwz	r7, VCPU_XER(r4) +	ld	r7, VCPU_XER(r4)  	mtctr	r6  	mtxer	r7 @@ -985,9 +1067,13 @@ secondary_too_late:  #endif  11:	b	kvmhv_switch_to_host +no_switch_exit: +	HMT_MEDIUM +	li	r12, 0 +	b	12f  hdec_soon:  	li	r12, BOOK3S_INTERRUPT_HV_DECREMENTER -	stw	r12, VCPU_TRAP(r4) +12:	stw	r12, VCPU_TRAP(r4)  	mr	r9, r4  #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING  	addi	r3, r4, VCPU_TB_RMEXIT @@ -1103,7 +1189,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)  	mfctr	r3  	mfxer	r4  	std	r3, VCPU_CTR(r9) -	stw	r4, VCPU_XER(r9) +	std	r4, VCPU_XER(r9)  	/* If this is a page table miss then see if it's theirs or ours */  	cmpwi	r12, BOOK3S_INTERRUPT_H_DATA_STORAGE @@ -1127,6 +1213,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)  	cmpwi	r12, BOOK3S_INTERRUPT_H_DOORBELL  	bne	3f  	lbz	r0, HSTATE_HOST_IPI(r13) +	cmpwi	r0, 0  	beq	4f  	b	guest_exit_cont  3: @@ -1176,6 +1263,11 @@ mc_cont:  	ld	r9, HSTATE_KVM_VCPU(r13)  	lwz	r12, VCPU_TRAP(r9) +	/* Stop others sending VCPU interrupts to this physical CPU */ +	li	r0, -1 +	stw	r0, VCPU_CPU(r9) +	stw	r0, VCPU_THREAD_CPU(r9) +  	/* Save guest CTRL register, set runlatch to 1 */  	mfspr	r6,SPRN_CTRLF  	stw	r6,VCPU_CTRL(r9) @@ -1540,12 +1632,17 @@ kvmhv_switch_to_host:  	/* Primary thread waits for all the secondaries to exit guest */  15:	lwz	r3,VCORE_ENTRY_EXIT(r5) -	srwi	r0,r3,8 +	rlwinm	r0,r3,32-8,0xff  	clrldi	r3,r3,56  	cmpw	r3,r0  	bne	15b  	isync +	/* Did we actually switch to the guest at all? */ +	lbz	r6, VCORE_IN_GUEST(r5) +	cmpwi	r6, 0 +	beq	19f +  	/* Primary thread switches back to host partition */  	ld	r6,KVM_HOST_SDR1(r4)  	lwz	r7,KVM_HOST_LPID(r4) @@ -1589,7 +1686,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)  18:  	/* Signal secondary CPUs to continue */  	stb	r0,VCORE_IN_GUEST(r5) -	lis	r8,0x7fff		/* MAX_INT@h */ +19:	lis	r8,0x7fff		/* MAX_INT@h */  	mtspr	SPRN_HDEC,r8  16:	ld	r8,KVM_HOST_LPCR(r4) @@ -1675,7 +1772,7 @@ kvmppc_hdsi:  	bl	kvmppc_msr_interrupt  fast_interrupt_c_return:  6:	ld	r7, VCPU_CTR(r9) -	lwz	r8, VCPU_XER(r9) +	ld	r8, VCPU_XER(r9)  	mtctr	r7  	mtxer	r8  	mr	r4, r9 @@ -1816,8 +1913,8 @@ hcall_real_table:  	.long	DOTSYM(kvmppc_h_remove) - hcall_real_table  	.long	DOTSYM(kvmppc_h_enter) - hcall_real_table  	.long	DOTSYM(kvmppc_h_read) - hcall_real_table -	.long	0		/* 0x10 - H_CLEAR_MOD */ -	.long	0		/* 0x14 - H_CLEAR_REF */ +	.long	DOTSYM(kvmppc_h_clear_mod) - hcall_real_table +	.long	DOTSYM(kvmppc_h_clear_ref) - hcall_real_table  	.long	DOTSYM(kvmppc_h_protect) - hcall_real_table  	.long	DOTSYM(kvmppc_h_get_tce) - hcall_real_table  	.long	DOTSYM(kvmppc_h_put_tce) - hcall_real_table diff --git a/arch/powerpc/kvm/book3s_paired_singles.c b/arch/powerpc/kvm/book3s_paired_singles.c index bd6ab1672ae6..a759d9adb0b6 100644 --- a/arch/powerpc/kvm/book3s_paired_singles.c +++ b/arch/powerpc/kvm/book3s_paired_singles.c @@ -352,7 +352,7 @@ static inline u32 inst_get_field(u32 inst, int msb, int lsb)  	return kvmppc_get_field(inst, msb + 32, lsb + 32);  } -bool kvmppc_inst_is_paired_single(struct kvm_vcpu *vcpu, u32 inst) +static bool kvmppc_inst_is_paired_single(struct kvm_vcpu *vcpu, u32 inst)  {  	if (!(vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE))  		return false; diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S index acee37cde840..ca8f174289bb 100644 --- a/arch/powerpc/kvm/book3s_segment.S +++ b/arch/powerpc/kvm/book3s_segment.S @@ -123,7 +123,7 @@ no_dcbz32_on:  	PPC_LL	r8, SVCPU_CTR(r3)  	PPC_LL	r9, SVCPU_LR(r3)  	lwz	r10, SVCPU_CR(r3) -	lwz	r11, SVCPU_XER(r3) +	PPC_LL	r11, SVCPU_XER(r3)  	mtctr	r8  	mtlr	r9 @@ -237,7 +237,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)  	mfctr	r8  	mflr	r9 -	stw	r5, SVCPU_XER(r13) +	PPC_STL	r5, SVCPU_XER(r13)  	PPC_STL	r6, SVCPU_FAULT_DAR(r13)  	stw	r7, SVCPU_FAULT_DSISR(r13)  	PPC_STL	r8, SVCPU_CTR(r13) diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index c6ca7db64673..905e94a1370f 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c @@ -41,7 +41,7 @@   * =======   *   * Each ICS has a spin lock protecting the information about the IRQ - * sources and avoiding simultaneous deliveries if the same interrupt. + * sources and avoiding simultaneous deliveries of the same interrupt.   *   * ICP operations are done via a single compare & swap transaction   * (most ICP state fits in the union kvmppc_icp_state) diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index cc5842657161..ae458f0fd061 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -933,6 +933,7 @@ static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu,  #endif  		break;  	case BOOKE_INTERRUPT_CRITICAL: +		kvmppc_fill_pt_regs(®s);  		unknown_exception(®s);  		break;  	case BOOKE_INTERRUPT_DEBUG: diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c index 50860e919cb8..29911a07bcdb 100644 --- a/arch/powerpc/kvm/e500_mmu.c +++ b/arch/powerpc/kvm/e500_mmu.c @@ -377,7 +377,7 @@ int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, gva_t ea)  			| MAS0_NV(vcpu_e500->gtlb_nv[tlbsel]);  		vcpu->arch.shared->mas1 =  			  (vcpu->arch.shared->mas6 & MAS6_SPID0) -			| (vcpu->arch.shared->mas6 & (MAS6_SAS ? MAS1_TS : 0)) +			| ((vcpu->arch.shared->mas6 & MAS6_SAS) ? MAS1_TS : 0)  			| (vcpu->arch.shared->mas4 & MAS4_TSIZED(~0));  		vcpu->arch.shared->mas2 &= MAS2_EPN;  		vcpu->arch.shared->mas2 |= vcpu->arch.shared->mas4 & diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index e5dde32fe71f..2e51289610e4 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -660,7 +660,7 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)  	return kvmppc_core_pending_dec(vcpu);  } -enum hrtimer_restart kvmppc_decrementer_wakeup(struct hrtimer *timer) +static enum hrtimer_restart kvmppc_decrementer_wakeup(struct hrtimer *timer)  {  	struct kvm_vcpu *vcpu; diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S index 7874e8a80455..6d67e057f15e 100644 --- a/arch/powerpc/lib/checksum_32.S +++ b/arch/powerpc/lib/checksum_32.S @@ -41,22 +41,6 @@ _GLOBAL(ip_fast_csum)  	blr  /* - * Compute checksum of TCP or UDP pseudo-header: - *   csum_tcpudp_magic(saddr, daddr, len, proto, sum) - */	 -_GLOBAL(csum_tcpudp_magic) -	rlwimi	r5,r6,16,0,15	/* put proto in upper half of len */ -	addc	r0,r3,r4	/* add 4 32-bit words together */ -	adde	r0,r0,r5 -	adde	r0,r0,r7 -	addze	r0,r0		/* add in final carry */ -	rlwinm	r3,r0,16,0,31	/* fold two halves together */ -	add	r3,r0,r3 -	not	r3,r3 -	srwi	r3,r3,16 -	blr - -/*   * computes the checksum of a memory block at buff, length len,   * and adds in "sum" (32-bit)   * diff --git a/arch/powerpc/lib/checksum_64.S b/arch/powerpc/lib/checksum_64.S index 57a072065057..f3ef35436612 100644 --- a/arch/powerpc/lib/checksum_64.S +++ b/arch/powerpc/lib/checksum_64.S @@ -45,27 +45,6 @@ _GLOBAL(ip_fast_csum)  	blr  /* - * Compute checksum of TCP or UDP pseudo-header: - *   csum_tcpudp_magic(r3=saddr, r4=daddr, r5=len, r6=proto, r7=sum) - * No real gain trying to do this specially for 64 bit, but - * the 32 bit addition may spill into the upper bits of - * the doubleword so we still must fold it down from 64. - */	 -_GLOBAL(csum_tcpudp_magic) -	rlwimi	r5,r6,16,0,15	/* put proto in upper half of len */ -	addc	r0,r3,r4	/* add 4 32-bit words together */ -	adde	r0,r0,r5 -	adde	r0,r0,r7 -        rldicl  r4,r0,32,0      /* fold 64 bit value */ -        add     r0,r4,r0 -        srdi    r0,r0,32 -	rlwinm	r3,r0,16,0,31	/* fold two halves together */ -	add	r3,r0,r3 -	not	r3,r3 -	srwi	r3,r3,16 -	blr - -/*   * Computes the checksum of a memory block at buff, length len,   * and adds in "sum" (32-bit).   * diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S index 6813f80d1eec..2ef50c629470 100644 --- a/arch/powerpc/lib/copy_32.S +++ b/arch/powerpc/lib/copy_32.S @@ -69,9 +69,15 @@ CACHELINE_BYTES = L1_CACHE_BYTES  LG_CACHELINE_BYTES = L1_CACHE_SHIFT  CACHELINE_MASK = (L1_CACHE_BYTES-1) +/* + * Use dcbz on the complete cache lines in the destination + * to set them to zero.  This requires that the destination + * area is cacheable.  -- paulus + */  _GLOBAL(memset)  	rlwimi	r4,r4,8,16,23  	rlwimi	r4,r4,16,0,15 +  	addi	r6,r3,-4  	cmplwi	0,r5,4  	blt	7f @@ -80,7 +86,29 @@ _GLOBAL(memset)  	andi.	r0,r6,3  	add	r5,r0,r5  	subf	r6,r0,r6 -	srwi	r0,r5,2 +	cmplwi	0,r4,0 +	bne	2f	/* Use normal procedure if r4 is not zero */ + +	clrlwi	r7,r6,32-LG_CACHELINE_BYTES +	add	r8,r7,r5 +	srwi	r9,r8,LG_CACHELINE_BYTES +	addic.	r9,r9,-1	/* total number of complete cachelines */ +	ble	2f +	xori	r0,r7,CACHELINE_MASK & ~3 +	srwi.	r0,r0,2 +	beq	3f +	mtctr	r0 +4:	stwu	r4,4(r6) +	bdnz	4b +3:	mtctr	r9 +	li	r7,4 +10:	dcbz	r7,r6 +	addi	r6,r6,CACHELINE_BYTES +	bdnz	10b +	clrlwi	r5,r8,32-LG_CACHELINE_BYTES +	addi	r5,r5,4 + +2:	srwi	r0,r5,2  	mtctr	r0  	bdz	6f  1:	stwu	r4,4(r6) @@ -94,12 +122,91 @@ _GLOBAL(memset)  	bdnz	8b  	blr +/* + * This version uses dcbz on the complete cache lines in the + * destination area to reduce memory traffic.  This requires that + * the destination area is cacheable. + * We only use this version if the source and dest don't overlap. + * -- paulus. + */  _GLOBAL(memmove)  	cmplw	0,r3,r4  	bgt	backwards_memcpy  	/* fall through */  _GLOBAL(memcpy) +	add	r7,r3,r5		/* test if the src & dst overlap */ +	add	r8,r4,r5 +	cmplw	0,r4,r7 +	cmplw	1,r3,r8 +	crand	0,0,4			/* cr0.lt &= cr1.lt */ +	blt	generic_memcpy		/* if regions overlap */ + +	addi	r4,r4,-4 +	addi	r6,r3,-4 +	neg	r0,r3 +	andi.	r0,r0,CACHELINE_MASK	/* # bytes to start of cache line */ +	beq	58f + +	cmplw	0,r5,r0			/* is this more than total to do? */ +	blt	63f			/* if not much to do */ +	andi.	r8,r0,3			/* get it word-aligned first */ +	subf	r5,r0,r5 +	mtctr	r8 +	beq+	61f +70:	lbz	r9,4(r4)		/* do some bytes */ +	addi	r4,r4,1 +	addi	r6,r6,1 +	stb	r9,3(r6) +	bdnz	70b +61:	srwi.	r0,r0,2 +	mtctr	r0 +	beq	58f +72:	lwzu	r9,4(r4)		/* do some words */ +	stwu	r9,4(r6) +	bdnz	72b + +58:	srwi.	r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */ +	clrlwi	r5,r5,32-LG_CACHELINE_BYTES +	li	r11,4 +	mtctr	r0 +	beq	63f +53: +	dcbz	r11,r6 +	COPY_16_BYTES +#if L1_CACHE_BYTES >= 32 +	COPY_16_BYTES +#if L1_CACHE_BYTES >= 64 +	COPY_16_BYTES +	COPY_16_BYTES +#if L1_CACHE_BYTES >= 128 +	COPY_16_BYTES +	COPY_16_BYTES +	COPY_16_BYTES +	COPY_16_BYTES +#endif +#endif +#endif +	bdnz	53b + +63:	srwi.	r0,r5,2 +	mtctr	r0 +	beq	64f +30:	lwzu	r0,4(r4) +	stwu	r0,4(r6) +	bdnz	30b + +64:	andi.	r0,r5,3 +	mtctr	r0 +	beq+	65f +	addi	r4,r4,3 +	addi	r6,r6,3 +40:	lbzu	r0,1(r4) +	stbu	r0,1(r6) +	bdnz	40b +65:	blr + +_GLOBAL(generic_memcpy)  	srwi.	r7,r5,3  	addi	r6,r3,-4  	addi	r4,r4,-4 diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index 9c90e66cffb6..354ba3c09ef3 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -112,7 +112,7 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,  	tsize = __ilog2(size) - 10; -#ifdef CONFIG_SMP +#if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC)  	if ((flags & _PAGE_NO_CACHE) == 0)  		flags |= _PAGE_COHERENT;  #endif diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S index 463174a4a647..3b49e3295901 100644 --- a/arch/powerpc/mm/hash_low_64.S +++ b/arch/powerpc/mm/hash_low_64.S @@ -701,7 +701,7 @@ htab_pte_insert_failure:  #endif /* CONFIG_PPC_64K_PAGES */ -#ifdef CONFIG_PPC_HAS_HASH_64K +#ifdef CONFIG_PPC_64K_PAGES  /*****************************************************************************   *                                                                           * @@ -993,7 +993,7 @@ ht64_pte_insert_failure:  	b	ht64_bail -#endif /* CONFIG_PPC_HAS_HASH_64K */ +#endif /* CONFIG_PPC_64K_PAGES */  /***************************************************************************** diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 5ec987f65b2c..aee70171355b 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -640,7 +640,7 @@ extern u32 ht64_call_hpte_updatepp[];  static void __init htab_finish_init(void)  { -#ifdef CONFIG_PPC_HAS_HASH_64K +#ifdef CONFIG_PPC_64K_PAGES  	patch_branch(ht64_call_hpte_insert1,  		ppc_function_entry(ppc_md.hpte_insert),  		BRANCH_SET_LINK); @@ -653,7 +653,7 @@ static void __init htab_finish_init(void)  	patch_branch(ht64_call_hpte_updatepp,  		ppc_function_entry(ppc_md.hpte_updatepp),  		BRANCH_SET_LINK); -#endif /* CONFIG_PPC_HAS_HASH_64K */ +#endif /* CONFIG_PPC_64K_PAGES */  	patch_branch(htab_call_hpte_insert1,  		ppc_function_entry(ppc_md.hpte_insert), @@ -1151,12 +1151,12 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea,  		check_paca_psize(ea, mm, psize, user_region);  #endif /* CONFIG_PPC_64K_PAGES */ -#ifdef CONFIG_PPC_HAS_HASH_64K +#ifdef CONFIG_PPC_64K_PAGES  	if (psize == MMU_PAGE_64K)  		rc = __hash_page_64K(ea, access, vsid, ptep, trap,  				     flags, ssize);  	else -#endif /* CONFIG_PPC_HAS_HASH_64K */ +#endif /* CONFIG_PPC_64K_PAGES */  	{  		int spp = subpage_protection(mm, ea);  		if (access & spp) @@ -1264,12 +1264,12 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,  		update_flags |= HPTE_LOCAL_UPDATE;  	/* Hash it in */ -#ifdef CONFIG_PPC_HAS_HASH_64K +#ifdef CONFIG_PPC_64K_PAGES  	if (mm->context.user_psize == MMU_PAGE_64K)  		rc = __hash_page_64K(ea, access, vsid, ptep, trap,  				     update_flags, ssize);  	else -#endif /* CONFIG_PPC_HAS_HASH_64K */ +#endif /* CONFIG_PPC_64K_PAGES */  		rc = __hash_page_4K(ea, access, vsid, ptep, trap, update_flags,  				    ssize, subpage_protection(mm, ea)); diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index bb0bd7025cb8..06c14523b787 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -808,14 +808,6 @@ static int __init add_huge_page_size(unsigned long long size)  	if ((mmu_psize = shift_to_mmu_psize(shift)) < 0)  		return -EINVAL; -#ifdef CONFIG_SPU_FS_64K_LS -	/* Disable support for 64K huge pages when 64K SPU local store -	 * support is enabled as the current implementation conflicts. -	 */ -	if (shift == PAGE_SHIFT_64K) -		return -EINVAL; -#endif /* CONFIG_SPU_FS_64K_LS */ -  	BUG_ON(mmu_psize_defs[mmu_psize].shift != shift);  	/* Return if huge page size has already been setup */ diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 0f11819d8f1d..22d94c3e6fc4 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -113,7 +113,7 @@ int memory_add_physaddr_to_nid(u64 start)  }  #endif -int arch_add_memory(int nid, u64 start, u64 size) +int arch_add_memory(int nid, u64 start, u64 size, bool for_device)  {  	struct pglist_data *pgdata;  	struct zone *zone; @@ -128,7 +128,7 @@ int arch_add_memory(int nid, u64 start, u64 size)  	/* this should work for most non-highmem platforms */  	zone = pgdata->node_zones + -		zone_for_memory(nid, start, size, 0); +		zone_for_memory(nid, start, size, 0, for_device);  	return __add_pages(nid, zone, start_pfn, nr_pages);  } @@ -414,17 +414,17 @@ void flush_dcache_icache_page(struct page *page)  		return;  	}  #endif -#ifdef CONFIG_BOOKE -	{ +#if defined(CONFIG_8xx) || defined(CONFIG_PPC64) +	/* On 8xx there is no need to kmap since highmem is not supported */ +	__flush_dcache_icache(page_address(page)); +#else +	if (IS_ENABLED(CONFIG_BOOKE) || sizeof(phys_addr_t) > sizeof(void *)) {  		void *start = kmap_atomic(page);  		__flush_dcache_icache(start);  		kunmap_atomic(start); +	} else { +		__flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT);  	} -#elif defined(CONFIG_8xx) || defined(CONFIG_PPC64) -	/* On 8xx there is no need to kmap since highmem is not supported */ -	__flush_dcache_icache(page_address(page));  -#else -	__flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT);  #endif  }  EXPORT_SYMBOL(flush_dcache_icache_page); diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 5e80621d9324..8b9502adaf79 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -225,7 +225,7 @@ static void initialize_distance_lookup_table(int nid,  	for (i = 0; i < distance_ref_points_depth; i++) {  		const __be32 *entry; -		entry = &associativity[be32_to_cpu(distance_ref_points[i])]; +		entry = &associativity[be32_to_cpu(distance_ref_points[i]) - 1];  		distance_lookup_table[nid][i] = of_read_number(entry, 1);  	}  } @@ -248,8 +248,12 @@ static int associativity_to_nid(const __be32 *associativity)  		nid = -1;  	if (nid > 0 && -	    of_read_number(associativity, 1) >= distance_ref_points_depth) -		initialize_distance_lookup_table(nid, associativity); +		of_read_number(associativity, 1) >= distance_ref_points_depth) { +		/* +		 * Skip the length field and send start of associativity array +		 */ +		initialize_distance_lookup_table(nid, associativity + 1); +	}  out:  	return nid; @@ -507,6 +511,12 @@ static int of_drconf_to_nid_single(struct of_drconf_cell *drmem,  		if (nid == 0xffff || nid >= MAX_NUMNODES)  			nid = default_nid; + +		if (nid > 0) { +			index = drmem->aa_index * aa->array_sz; +			initialize_distance_lookup_table(nid, +							&aa->arrays[index]); +		}  	}  	return nid; diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 876232d64126..e92cb2146b18 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -149,17 +149,7 @@ int map_kernel_page(unsigned long ea, unsigned long pa, int flags)  #endif /* !CONFIG_PPC_MMU_NOHASH */  	} -#ifdef CONFIG_PPC_BOOK3E_64 -	/* -	 * With hardware tablewalk, a sync is needed to ensure that -	 * subsequent accesses see the PTE we just wrote.  Unlike userspace -	 * mappings, we can't tolerate spurious faults, so make sure -	 * the new PTE will be seen the first time. -	 */ -	mb(); -#else  	smp_wmb(); -#endif  	return 0;  } diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index 6e450ca66526..8a32a2be3c53 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c @@ -41,9 +41,9 @@ static void slb_allocate(unsigned long ea)  	(((ssize) == MMU_SEGSIZE_256M)? ESID_MASK: ESID_MASK_1T)  static inline unsigned long mk_esid_data(unsigned long ea, int ssize, -					 unsigned long slot) +					 unsigned long entry)  { -	return (ea & slb_esid_mask(ssize)) | SLB_ESID_V | slot; +	return (ea & slb_esid_mask(ssize)) | SLB_ESID_V | entry;  }  static inline unsigned long mk_vsid_data(unsigned long ea, int ssize, @@ -249,11 +249,24 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)  static inline void patch_slb_encoding(unsigned int *insn_addr,  				      unsigned int immed)  { -	int insn = (*insn_addr & 0xffff0000) | immed; + +	/* +	 * This function patches either an li or a cmpldi instruction with +	 * a new immediate value. This relies on the fact that both li +	 * (which is actually addi) and cmpldi both take a 16-bit immediate +	 * value, and it is situated in the same location in the instruction, +	 * ie. bits 16-31 (Big endian bit order) or the lower 16 bits. +	 * The signedness of the immediate operand differs between the two +	 * instructions however this code is only ever patching a small value, +	 * much less than 1 << 15, so we can get away with it. +	 * To patch the value we read the existing instruction, clear the +	 * immediate value, and or in our new value, then write the instruction +	 * back. +	 */ +	unsigned int insn = (*insn_addr & 0xffff0000) | immed;  	patch_instruction(insn_addr, insn);  } -extern u32 slb_compare_rr_to_size[];  extern u32 slb_miss_kernel_load_linear[];  extern u32 slb_miss_kernel_load_io[];  extern u32 slb_compare_rr_to_size[]; @@ -309,12 +322,11 @@ void slb_initialize(void)  	lflags = SLB_VSID_KERNEL | linear_llp;  	vflags = SLB_VSID_KERNEL | vmalloc_llp; -	/* Invalidate the entire SLB (even slot 0) & all the ERATS */ +	/* Invalidate the entire SLB (even entry 0) & all the ERATS */  	asm volatile("isync":::"memory");  	asm volatile("slbmte  %0,%0"::"r" (0) : "memory");  	asm volatile("isync; slbia; isync":::"memory");  	create_shadowed_slbe(PAGE_OFFSET, mmu_kernel_ssize, lflags, 0); -  	create_shadowed_slbe(VMALLOC_START, mmu_kernel_ssize, vflags, 1);  	/* For the boot cpu, we're running on the stack in init_thread_union, diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S index 765b419883f2..e4185581c5a7 100644 --- a/arch/powerpc/mm/tlb_low_64e.S +++ b/arch/powerpc/mm/tlb_low_64e.S @@ -308,11 +308,11 @@ BEGIN_FTR_SECTION		/* CPU_FTR_SMT */  	 *  	 * MAS6:IND should be already set based on MAS4  	 */ -1:	lbarx	r15,0,r11  	lhz	r10,PACAPACAINDEX(r13) -	cmpdi	r15,0 -	cmpdi	cr1,r15,1	/* set cr1.eq = 0 for non-recursive */  	addi	r10,r10,1 +	crclr	cr1*4+eq	/* set cr1.eq = 0 for non-recursive */ +1:	lbarx	r15,0,r11 +	cmpdi	r15,0  	bne	2f  	stbcx.	r10,0,r11  	bne	1b @@ -320,9 +320,9 @@ BEGIN_FTR_SECTION		/* CPU_FTR_SMT */  	.subsection 1  2:	cmpd	cr1,r15,r10	/* recursive lock due to mcheck/crit/etc? */  	beq	cr1,3b		/* unlock will happen if cr1.eq = 0 */ -	lbz	r15,0(r11) +10:	lbz	r15,0(r11)  	cmpdi	r15,0 -	bne	2b +	bne	10b  	b	1b  	.previous diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c index 962fe7b3e3fb..4b32e9404bbe 100644 --- a/arch/powerpc/oprofile/op_model_power4.c +++ b/arch/powerpc/oprofile/op_model_power4.c @@ -207,7 +207,7 @@ static int power4_start(struct op_counter_config *ctr)  	unsigned int mmcr0;  	/* set the PMM bit (see comment below) */ -	mtmsrd(mfmsr() | MSR_PMM); +	mtmsr(mfmsr() | MSR_PMM);  	for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {  		if (ctr[i].enabled) { @@ -377,7 +377,7 @@ static void power4_handle_interrupt(struct pt_regs *regs,  	is_kernel = get_kernel(pc, mmcra);  	/* set the PMM bit (see comment below) */ -	mtmsrd(mfmsr() | MSR_PMM); +	mtmsr(mfmsr() | MSR_PMM);  	/* Check that the SIAR  valid bit in MMCRA is set to 1. */  	if ((mmcra & MMCRA_SIAR_VALID_MASK) == MMCRA_SIAR_VALID_MASK) diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index d90893b76e7c..b0382f3f1095 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -53,7 +53,7 @@ struct cpu_hw_events {  	/* BHRB bits */  	u64				bhrb_filter;	/* BHRB HW branch filter */ -	int				bhrb_users; +	unsigned int			bhrb_users;  	void				*bhrb_context;  	struct	perf_branch_stack	bhrb_stack;  	struct	perf_branch_entry	bhrb_entries[BHRB_MAX_ENTRIES]; @@ -369,8 +369,8 @@ static void power_pmu_bhrb_disable(struct perf_event *event)  	if (!ppmu->bhrb_nr)  		return; +	WARN_ON_ONCE(!cpuhw->bhrb_users);  	cpuhw->bhrb_users--; -	WARN_ON_ONCE(cpuhw->bhrb_users < 0);  	perf_sched_cb_dec(event->ctx->pmu);  	if (!cpuhw->disabled && !cpuhw->bhrb_users) { diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index df956295c2a7..527c8b98e97e 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -416,7 +416,7 @@ out_val:  }  static struct attribute *event_to_desc_attr(struct hv_24x7_event_data *event, -				int nonce) +					    int nonce)  {  	int nl, dl;  	char *name = event_name(event, &nl); @@ -444,7 +444,7 @@ event_to_long_desc_attr(struct hv_24x7_event_data *event, int nonce)  }  static ssize_t event_data_to_attrs(unsigned ix, struct attribute **attrs, -		struct hv_24x7_event_data *event, int nonce) +				   struct hv_24x7_event_data *event, int nonce)  {  	unsigned i; @@ -512,7 +512,7 @@ static int memord(const void *d1, size_t s1, const void *d2, size_t s2)  }  static int ev_uniq_ord(const void *v1, size_t s1, unsigned d1, const void *v2, -					size_t s2, unsigned d2) +		       size_t s2, unsigned d2)  {  	int r = memord(v1, s1, v2, s2); @@ -526,7 +526,7 @@ static int ev_uniq_ord(const void *v1, size_t s1, unsigned d1, const void *v2,  }  static int event_uniq_add(struct rb_root *root, const char *name, int nl, -				unsigned domain) +			  unsigned domain)  {  	struct rb_node **new = &(root->rb_node), *parent = NULL;  	struct event_uniq *data; @@ -650,8 +650,8 @@ static ssize_t catalog_event_len_validate(struct hv_24x7_event_data *event,  #define MAX_4K (SIZE_MAX / 4096)  static int create_events_from_catalog(struct attribute ***events_, -		struct attribute ***event_descs_, -		struct attribute ***event_long_descs_) +				      struct attribute ***event_descs_, +				      struct attribute ***event_long_descs_)  {  	unsigned long hret;  	size_t catalog_len, catalog_page_len, event_entry_count, @@ -1008,8 +1008,8 @@ static const struct attribute_group *attr_groups[] = {  };  static void log_24x7_hcall(struct hv_24x7_request_buffer *request_buffer, -			struct hv_24x7_data_result_buffer *result_buffer, -			unsigned long ret) +			   struct hv_24x7_data_result_buffer *result_buffer, +			   unsigned long ret)  {  	struct hv_24x7_request *req; @@ -1026,7 +1026,7 @@ static void log_24x7_hcall(struct hv_24x7_request_buffer *request_buffer,   * Start the process for a new H_GET_24x7_DATA hcall.   */  static void init_24x7_request(struct hv_24x7_request_buffer *request_buffer, -			struct hv_24x7_data_result_buffer *result_buffer) +			      struct hv_24x7_data_result_buffer *result_buffer)  {  	memset(request_buffer, 0, 4096); @@ -1041,7 +1041,7 @@ static void init_24x7_request(struct hv_24x7_request_buffer *request_buffer,   * by 'init_24x7_request()' and 'add_event_to_24x7_request()'.   */  static int make_24x7_request(struct hv_24x7_request_buffer *request_buffer, -			struct hv_24x7_data_result_buffer *result_buffer) +			     struct hv_24x7_data_result_buffer *result_buffer)  {  	unsigned long ret; @@ -1104,7 +1104,6 @@ static unsigned long single_24x7_request(struct perf_event *event, u64 *count)  	unsigned long ret;  	struct hv_24x7_request_buffer *request_buffer;  	struct hv_24x7_data_result_buffer *result_buffer; -	struct hv_24x7_result *resb;  	BUILD_BUG_ON(sizeof(*request_buffer) > 4096);  	BUILD_BUG_ON(sizeof(*result_buffer) > 4096); @@ -1125,8 +1124,7 @@ static unsigned long single_24x7_request(struct perf_event *event, u64 *count)  	}  	/* process result from hcall */ -	resb = &result_buffer->results[0]; -	*count = be64_to_cpu(resb->elements[0].element_data[0]); +	*count = be64_to_cpu(result_buffer->results[0].elements[0].element_data[0]);  out:  	put_cpu_var(hv_24x7_reqb); diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index 5aa3f4b5332c..48bf38d0de35 100644 --- a/arch/powerpc/platforms/512x/Kconfig +++ b/arch/powerpc/platforms/512x/Kconfig @@ -7,8 +7,8 @@ config PPC_MPC512x  	select PPC_PCI_CHOICE  	select FSL_PCI if PCI  	select ARCH_WANT_OPTIONAL_GPIOLIB -	select USB_EHCI_BIG_ENDIAN_MMIO -	select USB_EHCI_BIG_ENDIAN_DESC +	select USB_EHCI_BIG_ENDIAN_MMIO if USB_EHCI_HCD +	select USB_EHCI_BIG_ENDIAN_DESC if USB_EHCI_HCD  config MPC5121_ADS  	bool "Freescale MPC5121E ADS" diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c index f691bcabd710..c50ea76ba66c 100644 --- a/arch/powerpc/platforms/512x/clock-commonclk.c +++ b/arch/powerpc/platforms/512x/clock-commonclk.c @@ -12,6 +12,7 @@   */  #include <linux/bitops.h> +#include <linux/clk.h>  #include <linux/clk-provider.h>  #include <linux/clkdev.h>  #include <linux/device.h> diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c index ca3a062ed1b9..11090ab4bf59 100644 --- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c +++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c @@ -123,7 +123,8 @@ cpld_pic_cascade(unsigned int irq, struct irq_desc *desc)  }  static int -cpld_pic_host_match(struct irq_domain *h, struct device_node *node) +cpld_pic_host_match(struct irq_domain *h, struct device_node *node, +		    enum irq_domain_bus_token bus_token)  {  	return cpld_pic_node == node;  } diff --git a/arch/powerpc/platforms/85xx/c293pcie.c b/arch/powerpc/platforms/85xx/c293pcie.c index 84476b646005..61bc851e9a8e 100644 --- a/arch/powerpc/platforms/85xx/c293pcie.c +++ b/arch/powerpc/platforms/85xx/c293pcie.c @@ -66,10 +66,6 @@ define_machine(c293_pcie) {  	.probe			= c293_pcie_probe,  	.setup_arch		= c293_pcie_setup_arch,  	.init_IRQ		= c293_pcie_pic_init, -#ifdef CONFIG_PCI -	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus, -	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb, -#endif  	.get_irq		= mpic_get_irq,  	.restart		= fsl_rstcr_restart,  	.calibrate_decr		= generic_calibrate_decr, diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c index bd839dc287fe..b39557120cbb 100644 --- a/arch/powerpc/platforms/85xx/corenet_generic.c +++ b/arch/powerpc/platforms/85xx/corenet_generic.c @@ -153,6 +153,8 @@ static const char * const boards[] __initconst = {  	"fsl,T1023RDB",  	"fsl,T1024QDS",  	"fsl,T1024RDB", +	"fsl,T1040D4RDB", +	"fsl,T1042D4RDB",  	"fsl,T1040QDS",  	"fsl,T1042QDS",  	"fsl,T1040RDB", diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index 2f23133ab3d1..b0ac1773cea6 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig @@ -57,21 +57,6 @@ config SPU_FS  	  Units on machines implementing the Broadband Processor  	  Architecture. -config SPU_FS_64K_LS -	bool "Use 64K pages to map SPE local  store" -	# we depend on PPC_MM_SLICES for now rather than selecting -	# it because we depend on hugetlbfs hooks being present. We -	# will fix that when the generic code has been improved to -	# not require hijacking hugetlbfs hooks. -	depends on SPU_FS && PPC_MM_SLICES && !PPC_64K_PAGES -	default y -	select PPC_HAS_HASH_64K -	help -	  This option causes SPE local stores to be mapped in process -	  address spaces using 64K pages while the rest of the kernel -	  uses 4K pages. This can improve performances of applications -	  using multiple SPEs by lowering the TLB pressure on them. -  config SPU_BASE  	bool  	default n diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index fe51de4fcf13..306888acb737 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -213,7 +213,7 @@ static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)  		return -ENODEV;  	} -	entry = list_first_entry(&dev->msi_list, struct msi_desc, list); +	entry = first_pci_msi_entry(dev);  	for (; dn; dn = of_get_next_parent(dn)) {  		if (entry->msi_attrib.is_64) { @@ -269,7 +269,7 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)  	if (rc)  		return rc; -	list_for_each_entry(entry, &dev->msi_list, list) { +	for_each_pci_msi_entry(entry, dev) {  		virq = irq_create_direct_mapping(msic->irq_domain);  		if (virq == NO_IRQ) {  			dev_warn(&dev->dev, @@ -292,7 +292,7 @@ static void axon_msi_teardown_msi_irqs(struct pci_dev *dev)  	dev_dbg(&dev->dev, "axon_msi: tearing down msi irqs\n"); -	list_for_each_entry(entry, &dev->msi_list, list) { +	for_each_pci_msi_entry(entry, dev) {  		if (entry->irq == NO_IRQ)  			continue; diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 3af8324c122e..a15f1efc295f 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -222,7 +222,8 @@ void iic_request_IPIs(void)  #endif /* CONFIG_SMP */ -static int iic_host_match(struct irq_domain *h, struct device_node *node) +static int iic_host_match(struct irq_domain *h, struct device_node *node, +			  enum irq_domain_bus_token bus_token)  {  	return of_device_is_compatible(node,  				    "IBM,CBEA-Internal-Interrupt-Controller"); diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index e865d748179b..2d4f60c0119a 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c @@ -123,7 +123,7 @@ static int __init cbe_ptcal_enable_on_node(int nid, int order)  	area->nid = nid;  	area->order = order; -	area->pages = alloc_pages_exact_node(area->nid, +	area->pages = __alloc_pages_node(area->nid,  						GFP_KERNEL|__GFP_THISNODE,  						area->order); diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index d966bbe58b8f..5038fd578e65 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -239,23 +239,6 @@ spufs_mem_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)  	unsigned long address = (unsigned long)vmf->virtual_address;  	unsigned long pfn, offset; -#ifdef CONFIG_SPU_FS_64K_LS -	struct spu_state *csa = &ctx->csa; -	int psize; - -	/* Check what page size we are using */ -	psize = get_slice_psize(vma->vm_mm, address); - -	/* Some sanity checking */ -	BUG_ON(csa->use_big_pages != (psize == MMU_PAGE_64K)); - -	/* Wow, 64K, cool, we need to align the address though */ -	if (csa->use_big_pages) { -		BUG_ON(vma->vm_start & 0xffff); -		address &= ~0xfffful; -	} -#endif /* CONFIG_SPU_FS_64K_LS */ -  	offset = vmf->pgoff << PAGE_SHIFT;  	if (offset >= LS_SIZE)  		return VM_FAULT_SIGBUS; @@ -310,22 +293,6 @@ static const struct vm_operations_struct spufs_mem_mmap_vmops = {  static int spufs_mem_mmap(struct file *file, struct vm_area_struct *vma)  { -#ifdef CONFIG_SPU_FS_64K_LS -	struct spu_context	*ctx = file->private_data; -	struct spu_state	*csa = &ctx->csa; - -	/* Sanity check VMA alignment */ -	if (csa->use_big_pages) { -		pr_debug("spufs_mem_mmap 64K, start=0x%lx, end=0x%lx," -			 " pgoff=0x%lx\n", vma->vm_start, vma->vm_end, -			 vma->vm_pgoff); -		if (vma->vm_start & 0xffff) -			return -EINVAL; -		if (vma->vm_pgoff & 0xf) -			return -EINVAL; -	} -#endif /* CONFIG_SPU_FS_64K_LS */ -  	if (!(vma->vm_flags & VM_SHARED))  		return -EINVAL; @@ -336,25 +303,6 @@ static int spufs_mem_mmap(struct file *file, struct vm_area_struct *vma)  	return 0;  } -#ifdef CONFIG_SPU_FS_64K_LS -static unsigned long spufs_get_unmapped_area(struct file *file, -		unsigned long addr, unsigned long len, unsigned long pgoff, -		unsigned long flags) -{ -	struct spu_context	*ctx = file->private_data; -	struct spu_state	*csa = &ctx->csa; - -	/* If not using big pages, fallback to normal MM g_u_a */ -	if (!csa->use_big_pages) -		return current->mm->get_unmapped_area(file, addr, len, -						      pgoff, flags); - -	/* Else, try to obtain a 64K pages slice */ -	return slice_get_unmapped_area(addr, len, flags, -				       MMU_PAGE_64K, 1); -} -#endif /* CONFIG_SPU_FS_64K_LS */ -  static const struct file_operations spufs_mem_fops = {  	.open			= spufs_mem_open,  	.release		= spufs_mem_release, @@ -362,9 +310,6 @@ static const struct file_operations spufs_mem_fops = {  	.write			= spufs_mem_write,  	.llseek			= generic_file_llseek,  	.mmap			= spufs_mem_mmap, -#ifdef CONFIG_SPU_FS_64K_LS -	.get_unmapped_area	= spufs_get_unmapped_area, -#endif  };  static int spufs_ps_fault(struct vm_area_struct *vma, diff --git a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c index 147069938cfe..b847e9403566 100644 --- a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c +++ b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c @@ -31,7 +31,7 @@  #include "spufs.h" -static int spu_alloc_lscsa_std(struct spu_state *csa) +int spu_alloc_lscsa(struct spu_state *csa)  {  	struct spu_lscsa *lscsa;  	unsigned char *p; @@ -48,7 +48,7 @@ static int spu_alloc_lscsa_std(struct spu_state *csa)  	return 0;  } -static void spu_free_lscsa_std(struct spu_state *csa) +void spu_free_lscsa(struct spu_state *csa)  {  	/* Clear reserved bit before vfree. */  	unsigned char *p; @@ -61,123 +61,3 @@ static void spu_free_lscsa_std(struct spu_state *csa)  	vfree(csa->lscsa);  } - -#ifdef CONFIG_SPU_FS_64K_LS - -#define SPU_64K_PAGE_SHIFT	16 -#define SPU_64K_PAGE_ORDER	(SPU_64K_PAGE_SHIFT - PAGE_SHIFT) -#define SPU_64K_PAGE_COUNT	(1ul << SPU_64K_PAGE_ORDER) - -int spu_alloc_lscsa(struct spu_state *csa) -{ -	struct page	**pgarray; -	unsigned char	*p; -	int		i, j, n_4k; - -	/* Check availability of 64K pages */ -	if (!spu_64k_pages_available()) -		goto fail; - -	csa->use_big_pages = 1; - -	pr_debug("spu_alloc_lscsa(csa=0x%p), trying to allocate 64K pages\n", -		 csa); - -	/* First try to allocate our 64K pages. We need 5 of them -	 * with the current implementation. In the future, we should try -	 * to separate the lscsa with the actual local store image, thus -	 * allowing us to require only 4 64K pages per context -	 */ -	for (i = 0; i < SPU_LSCSA_NUM_BIG_PAGES; i++) { -		/* XXX This is likely to fail, we should use a special pool -		 *     similar to what hugetlbfs does. -		 */ -		csa->lscsa_pages[i] = alloc_pages(GFP_KERNEL, -						  SPU_64K_PAGE_ORDER); -		if (csa->lscsa_pages[i] == NULL) -			goto fail; -	} - -	pr_debug(" success ! creating vmap...\n"); - -	/* Now we need to create a vmalloc mapping of these for the kernel -	 * and SPU context switch code to use. Currently, we stick to a -	 * normal kernel vmalloc mapping, which in our case will be 4K -	 */ -	n_4k = SPU_64K_PAGE_COUNT * SPU_LSCSA_NUM_BIG_PAGES; -	pgarray = kmalloc(sizeof(struct page *) * n_4k, GFP_KERNEL); -	if (pgarray == NULL) -		goto fail; -	for (i = 0; i < SPU_LSCSA_NUM_BIG_PAGES; i++) -		for (j = 0; j < SPU_64K_PAGE_COUNT; j++) -			/* We assume all the struct page's are contiguous -			 * which should be hopefully the case for an order 4 -			 * allocation.. -			 */ -			pgarray[i * SPU_64K_PAGE_COUNT + j] = -				csa->lscsa_pages[i] + j; -	csa->lscsa = vmap(pgarray, n_4k, VM_USERMAP, PAGE_KERNEL); -	kfree(pgarray); -	if (csa->lscsa == NULL) -		goto fail; - -	memset(csa->lscsa, 0, sizeof(struct spu_lscsa)); - -	/* Set LS pages reserved to allow for user-space mapping. -	 * -	 * XXX isn't that a bit obsolete ? I think we should just -	 * make sure the page count is high enough. Anyway, won't harm -	 * for now -	 */ -	for (p = csa->lscsa->ls; p < csa->lscsa->ls + LS_SIZE; p += PAGE_SIZE) -		SetPageReserved(vmalloc_to_page(p)); - -	pr_debug(" all good !\n"); - -	return 0; -fail: -	pr_debug("spufs: failed to allocate lscsa 64K pages, falling back\n"); -	spu_free_lscsa(csa); -	return spu_alloc_lscsa_std(csa); -} - -void spu_free_lscsa(struct spu_state *csa) -{ -	unsigned char *p; -	int i; - -	if (!csa->use_big_pages) { -		spu_free_lscsa_std(csa); -		return; -	} -	csa->use_big_pages = 0; - -	if (csa->lscsa == NULL) -		goto free_pages; - -	for (p = csa->lscsa->ls; p < csa->lscsa->ls + LS_SIZE; p += PAGE_SIZE) -		ClearPageReserved(vmalloc_to_page(p)); - -	vunmap(csa->lscsa); -	csa->lscsa = NULL; - - free_pages: - -	for (i = 0; i < SPU_LSCSA_NUM_BIG_PAGES; i++) -		if (csa->lscsa_pages[i]) -			__free_pages(csa->lscsa_pages[i], SPU_64K_PAGE_ORDER); -} - -#else /* CONFIG_SPU_FS_64K_LS */ - -int spu_alloc_lscsa(struct spu_state *csa) -{ -	return spu_alloc_lscsa_std(csa); -} - -void spu_free_lscsa(struct spu_state *csa) -{ -	spu_free_lscsa_std(csa); -} - -#endif /* !defined(CONFIG_SPU_FS_64K_LS) */ diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c index 4cde8e7da4b8..b7866e01483d 100644 --- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c +++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c @@ -108,7 +108,8 @@ static int flipper_pic_map(struct irq_domain *h, unsigned int virq,  	return 0;  } -static int flipper_pic_match(struct irq_domain *h, struct device_node *np) +static int flipper_pic_match(struct irq_domain *h, struct device_node *np, +			     enum irq_domain_bus_token bus_token)  {  	return 1;  } diff --git a/arch/powerpc/platforms/pasemi/msi.c b/arch/powerpc/platforms/pasemi/msi.c index 27f2b187a91b..e66ef1943338 100644 --- a/arch/powerpc/platforms/pasemi/msi.c +++ b/arch/powerpc/platforms/pasemi/msi.c @@ -66,7 +66,7 @@ static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev)  	pr_debug("pasemi_msi_teardown_msi_irqs, pdev %p\n", pdev); -	list_for_each_entry(entry, &pdev->msi_list, list) { +	for_each_pci_msi_entry(entry, pdev) {  		if (entry->irq == NO_IRQ)  			continue; @@ -94,7 +94,7 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)  	msg.address_hi = 0;  	msg.address_lo = PASEMI_MSI_ADDR; -	list_for_each_entry(entry, &pdev->msi_list, list) { +	for_each_pci_msi_entry(entry, pdev) {  		/* Allocate 16 interrupts for now, since that's the grouping for  		 * affinity. This can be changed later if it turns out 32 is too  		 * few MSIs for someone, but restrictions will apply to how the diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 59cfc9d63c2d..6f4f8b060def 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -268,7 +268,8 @@ static struct irqaction gatwick_cascade_action = {  	.name		= "cascade",  }; -static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node) +static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node, +			       enum irq_domain_bus_token bus_token)  {  	/* We match all, we don't always have a node anyway */  	return 1; diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 5cf5e6ea213b..3bb6acb76339 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -1394,11 +1394,19 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)  			 */  			if (pnv_eeh_get_pe(hose,  				be64_to_cpu(frozen_pe_no), pe)) { -				/* Try best to clear it */  				pr_info("EEH: Clear non-existing PHB#%x-PE#%llx\n", -					hose->global_number, frozen_pe_no); +					hose->global_number, be64_to_cpu(frozen_pe_no));  				pr_info("EEH: PHB location: %s\n",  					eeh_pe_loc_get(phb_pe)); + +				/* Dump PHB diag-data */ +				rc = opal_pci_get_phb_diag_data2(phb->opal_id, +					phb->diag.blob, PNV_PCI_DIAG_BUF_SIZE); +				if (rc == OPAL_SUCCESS) +					pnv_pci_dump_phb_diag_data(hose, +							phb->diag.blob); + +				/* Try best to clear it */  				opal_pci_eeh_freeze_clear(phb->opal_id,  					frozen_pe_no,  					OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); @@ -1478,7 +1486,7 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)  	}  	/* Unmask the event */ -	if (eeh_enabled()) +	if (ret == EEH_NEXT_ERR_NONE && eeh_enabled())  		enable_irq(eeh_event_irq);  	return ret; diff --git a/arch/powerpc/platforms/powernv/opal-hmi.c b/arch/powerpc/platforms/powernv/opal-hmi.c index a8f49d380449..d000f4e21981 100644 --- a/arch/powerpc/platforms/powernv/opal-hmi.c +++ b/arch/powerpc/platforms/powernv/opal-hmi.c @@ -35,9 +35,134 @@ struct OpalHmiEvtNode {  	struct list_head list;  	struct OpalHMIEvent hmi_evt;  }; + +struct xstop_reason { +	uint32_t xstop_reason; +	const char *unit_failed; +	const char *description; +}; +  static LIST_HEAD(opal_hmi_evt_list);  static DEFINE_SPINLOCK(opal_hmi_evt_lock); +static void print_core_checkstop_reason(const char *level, +					struct OpalHMIEvent *hmi_evt) +{ +	int i; +	static const struct xstop_reason xstop_reason[] = { +		{ CORE_CHECKSTOP_IFU_REGFILE, "IFU", +				"RegFile core check stop" }, +		{ CORE_CHECKSTOP_IFU_LOGIC, "IFU", "Logic core check stop" }, +		{ CORE_CHECKSTOP_PC_DURING_RECOV, "PC", +				"Core checkstop during recovery" }, +		{ CORE_CHECKSTOP_ISU_REGFILE, "ISU", +				"RegFile core check stop (mapper error)" }, +		{ CORE_CHECKSTOP_ISU_LOGIC, "ISU", "Logic core check stop" }, +		{ CORE_CHECKSTOP_FXU_LOGIC, "FXU", "Logic core check stop" }, +		{ CORE_CHECKSTOP_VSU_LOGIC, "VSU", "Logic core check stop" }, +		{ CORE_CHECKSTOP_PC_RECOV_IN_MAINT_MODE, "PC", +				"Recovery in maintenance mode" }, +		{ CORE_CHECKSTOP_LSU_REGFILE, "LSU", +				"RegFile core check stop" }, +		{ CORE_CHECKSTOP_PC_FWD_PROGRESS, "PC", +				"Forward Progress Error" }, +		{ CORE_CHECKSTOP_LSU_LOGIC, "LSU", "Logic core check stop" }, +		{ CORE_CHECKSTOP_PC_LOGIC, "PC", "Logic core check stop" }, +		{ CORE_CHECKSTOP_PC_HYP_RESOURCE, "PC", +				"Hypervisor Resource error - core check stop" }, +		{ CORE_CHECKSTOP_PC_HANG_RECOV_FAILED, "PC", +				"Hang Recovery Failed (core check stop)" }, +		{ CORE_CHECKSTOP_PC_AMBI_HANG_DETECTED, "PC", +				"Ambiguous Hang Detected (unknown source)" }, +		{ CORE_CHECKSTOP_PC_DEBUG_TRIG_ERR_INJ, "PC", +				"Debug Trigger Error inject" }, +		{ CORE_CHECKSTOP_PC_SPRD_HYP_ERR_INJ, "PC", +				"Hypervisor check stop via SPRC/SPRD" }, +	}; + +	/* Validity check */ +	if (!hmi_evt->u.xstop_error.xstop_reason) { +		printk("%s	Unknown Core check stop.\n", level); +		return; +	} + +	printk("%s	CPU PIR: %08x\n", level, +			be32_to_cpu(hmi_evt->u.xstop_error.u.pir)); +	for (i = 0; i < ARRAY_SIZE(xstop_reason); i++) +		if (be32_to_cpu(hmi_evt->u.xstop_error.xstop_reason) & +					xstop_reason[i].xstop_reason) +			printk("%s	[Unit: %-3s] %s\n", level, +					xstop_reason[i].unit_failed, +					xstop_reason[i].description); +} + +static void print_nx_checkstop_reason(const char *level, +					struct OpalHMIEvent *hmi_evt) +{ +	int i; +	static const struct xstop_reason xstop_reason[] = { +		{ NX_CHECKSTOP_SHM_INVAL_STATE_ERR, "DMA & Engine", +					"SHM invalid state error" }, +		{ NX_CHECKSTOP_DMA_INVAL_STATE_ERR_1, "DMA & Engine", +					"DMA invalid state error bit 15" }, +		{ NX_CHECKSTOP_DMA_INVAL_STATE_ERR_2, "DMA & Engine", +					"DMA invalid state error bit 16" }, +		{ NX_CHECKSTOP_DMA_CH0_INVAL_STATE_ERR, "DMA & Engine", +					"Channel 0 invalid state error" }, +		{ NX_CHECKSTOP_DMA_CH1_INVAL_STATE_ERR, "DMA & Engine", +					"Channel 1 invalid state error" }, +		{ NX_CHECKSTOP_DMA_CH2_INVAL_STATE_ERR, "DMA & Engine", +					"Channel 2 invalid state error" }, +		{ NX_CHECKSTOP_DMA_CH3_INVAL_STATE_ERR, "DMA & Engine", +					"Channel 3 invalid state error" }, +		{ NX_CHECKSTOP_DMA_CH4_INVAL_STATE_ERR, "DMA & Engine", +					"Channel 4 invalid state error" }, +		{ NX_CHECKSTOP_DMA_CH5_INVAL_STATE_ERR, "DMA & Engine", +					"Channel 5 invalid state error" }, +		{ NX_CHECKSTOP_DMA_CH6_INVAL_STATE_ERR, "DMA & Engine", +					"Channel 6 invalid state error" }, +		{ NX_CHECKSTOP_DMA_CH7_INVAL_STATE_ERR, "DMA & Engine", +					"Channel 7 invalid state error" }, +		{ NX_CHECKSTOP_DMA_CRB_UE, "DMA & Engine", +					"UE error on CRB(CSB address, CCB)" }, +		{ NX_CHECKSTOP_DMA_CRB_SUE, "DMA & Engine", +					"SUE error on CRB(CSB address, CCB)" }, +		{ NX_CHECKSTOP_PBI_ISN_UE, "PowerBus Interface", +		"CRB Kill ISN received while holding ISN with UE error" }, +	}; + +	/* Validity check */ +	if (!hmi_evt->u.xstop_error.xstop_reason) { +		printk("%s	Unknown NX check stop.\n", level); +		return; +	} + +	printk("%s	NX checkstop on CHIP ID: %x\n", level, +			be32_to_cpu(hmi_evt->u.xstop_error.u.chip_id)); +	for (i = 0; i < ARRAY_SIZE(xstop_reason); i++) +		if (be32_to_cpu(hmi_evt->u.xstop_error.xstop_reason) & +					xstop_reason[i].xstop_reason) +			printk("%s	[Unit: %-3s] %s\n", level, +					xstop_reason[i].unit_failed, +					xstop_reason[i].description); +} + +static void print_checkstop_reason(const char *level, +					struct OpalHMIEvent *hmi_evt) +{ +	switch (hmi_evt->u.xstop_error.xstop_type) { +	case CHECKSTOP_TYPE_CORE: +		print_core_checkstop_reason(level, hmi_evt); +		break; +	case CHECKSTOP_TYPE_NX: +		print_nx_checkstop_reason(level, hmi_evt); +		break; +	case CHECKSTOP_TYPE_UNKNOWN: +		printk("%s	Unknown Malfunction Alert.\n", level); +		break; +	} +} +  static void print_hmi_event_info(struct OpalHMIEvent *hmi_evt)  {  	const char *level, *sevstr, *error_info; @@ -95,6 +220,13 @@ static void print_hmi_event_info(struct OpalHMIEvent *hmi_evt)  		(hmi_evt->type == OpalHMI_ERROR_TFMR_PARITY))  		printk("%s	TFMR: %016llx\n", level,  						be64_to_cpu(hmi_evt->tfmr)); + +	if (hmi_evt->version < OpalHMIEvt_V2) +		return; + +	/* OpalHMIEvt_V2 and above provides reason for malfunction alert. */ +	if (hmi_evt->type == OpalHMI_ERROR_MALFUNC_ALERT) +		print_checkstop_reason(level, hmi_evt);  }  static void hmi_event_handler(struct work_struct *work) @@ -103,6 +235,8 @@ static void hmi_event_handler(struct work_struct *work)  	struct OpalHMIEvent *hmi_evt;  	struct OpalHmiEvtNode *msg_node;  	uint8_t disposition; +	struct opal_msg msg; +	int unrecoverable = 0;  	spin_lock_irqsave(&opal_hmi_evt_lock, flags);  	while (!list_empty(&opal_hmi_evt_list)) { @@ -118,14 +252,53 @@ static void hmi_event_handler(struct work_struct *work)  		/*  		 * Check if HMI event has been recovered or not. If not -		 * then we can't continue, invoke panic. +		 * then kernel can't continue, we need to panic. +		 * But before we do that, display all the HMI event +		 * available on the list and set unrecoverable flag to 1.  		 */  		if (disposition != OpalHMI_DISPOSITION_RECOVERED) -			panic("Unrecoverable HMI exception"); +			unrecoverable = 1;  		spin_lock_irqsave(&opal_hmi_evt_lock, flags);  	}  	spin_unlock_irqrestore(&opal_hmi_evt_lock, flags); + +	if (unrecoverable) { +		int ret; + +		/* Pull all HMI events from OPAL before we panic. */ +		while (opal_get_msg(__pa(&msg), sizeof(msg)) == OPAL_SUCCESS) { +			u32 type; + +			type = be32_to_cpu(msg.msg_type); + +			/* skip if not HMI event */ +			if (type != OPAL_MSG_HMI_EVT) +				continue; + +			/* HMI event info starts from param[0] */ +			hmi_evt = (struct OpalHMIEvent *)&msg.params[0]; +			print_hmi_event_info(hmi_evt); +		} + +		/* +		 * Unrecoverable HMI exception. We need to inform BMC/OCC +		 * about this error so that it can collect relevant data +		 * for error analysis before rebooting. +		 */ +		ret = opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR, +			"Unrecoverable HMI exception"); +		if (ret == OPAL_UNSUPPORTED) { +			pr_emerg("Reboot type %d not supported\n", +						OPAL_REBOOT_PLATFORM_ERROR); +		} + +		/* +		 * Fall through and panic if opal_cec_reboot2() returns +		 * OPAL_UNSUPPORTED. +		 */ +		panic("Unrecoverable HMI exception"); +	}  }  static DECLARE_WORK(hmi_event_work, hmi_event_handler); diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c b/arch/powerpc/platforms/powernv/opal-irqchip.c index e2e7d75f52f3..2c91ee7800b9 100644 --- a/arch/powerpc/platforms/powernv/opal-irqchip.c +++ b/arch/powerpc/platforms/powernv/opal-irqchip.c @@ -134,7 +134,8 @@ static void opal_handle_irq_work(struct irq_work *work)  	opal_handle_events(be64_to_cpu(last_outstanding_events));  } -static int opal_event_match(struct irq_domain *h, struct device_node *node) +static int opal_event_match(struct irq_domain *h, struct device_node *node, +			    enum irq_domain_bus_token bus_token)  {  	return h->of_node == node;  } diff --git a/arch/powerpc/platforms/powernv/opal-power.c b/arch/powerpc/platforms/powernv/opal-power.c index ac46c2c24f99..58dc3308237f 100644 --- a/arch/powerpc/platforms/powernv/opal-power.c +++ b/arch/powerpc/platforms/powernv/opal-power.c @@ -9,9 +9,12 @@   * 2 of the License, or (at your option) any later version.   */ +#define pr_fmt(fmt)	"opal-power: "	fmt +  #include <linux/kernel.h>  #include <linux/reboot.h>  #include <linux/notifier.h> +#include <linux/of.h>  #include <asm/opal.h>  #include <asm/machdep.h> @@ -19,30 +22,116 @@  #define SOFT_OFF 0x00  #define SOFT_REBOOT 0x01 +/* Detect EPOW event */ +static bool detect_epow(void) +{ +	u16 epow; +	int i, rc; +	__be16 epow_classes; +	__be16 opal_epow_status[OPAL_SYSEPOW_MAX] = {0}; + +	/* +	* Check for EPOW event. Kernel sends supported EPOW classes info +	* to OPAL. OPAL returns EPOW info along with classes present. +	*/ +	epow_classes = cpu_to_be16(OPAL_SYSEPOW_MAX); +	rc = opal_get_epow_status(opal_epow_status, &epow_classes); +	if (rc != OPAL_SUCCESS) { +		pr_err("Failed to get EPOW event information\n"); +		return false; +	} + +	/* Look for EPOW events present */ +	for (i = 0; i < be16_to_cpu(epow_classes); i++) { +		epow = be16_to_cpu(opal_epow_status[i]); + +		/* Filter events which do not need shutdown. */ +		if (i == OPAL_SYSEPOW_POWER) +			epow &= ~(OPAL_SYSPOWER_CHNG | OPAL_SYSPOWER_FAIL | +					OPAL_SYSPOWER_INCL); +		if (epow) +			return true; +	} + +	return false; +} + +/* Check for existing EPOW, DPO events */ +static bool poweroff_pending(void) +{ +	int rc; +	__be64 opal_dpo_timeout; + +	/* Check for DPO event */ +	rc = opal_get_dpo_status(&opal_dpo_timeout); +	if (rc == OPAL_SUCCESS) { +		pr_info("Existing DPO event detected.\n"); +		return true; +	} + +	/* Check for EPOW event */ +	if (detect_epow()) { +		pr_info("Existing EPOW event detected.\n"); +		return true; +	} + +	return false; +} + +/* OPAL power-control events notifier */  static int opal_power_control_event(struct notifier_block *nb, -				    unsigned long msg_type, void *msg) +					unsigned long msg_type, void *msg)  { -	struct opal_msg *power_msg = msg;  	uint64_t type; -	type = be64_to_cpu(power_msg->params[0]); - -	switch (type) { -	case SOFT_REBOOT: -		pr_info("OPAL: reboot requested\n"); -		orderly_reboot(); +	switch (msg_type) { +	case OPAL_MSG_EPOW: +		if (detect_epow()) { +			pr_info("EPOW msg received. Powering off system\n"); +			orderly_poweroff(true); +		}  		break; -	case SOFT_OFF: -		pr_info("OPAL: poweroff requested\n"); +	case OPAL_MSG_DPO: +		pr_info("DPO msg received. Powering off system\n");  		orderly_poweroff(true);  		break; +	case OPAL_MSG_SHUTDOWN: +		type = be64_to_cpu(((struct opal_msg *)msg)->params[0]); +		switch (type) { +		case SOFT_REBOOT: +			pr_info("Reboot requested\n"); +			orderly_reboot(); +			break; +		case SOFT_OFF: +			pr_info("Poweroff requested\n"); +			orderly_poweroff(true); +			break; +		default: +			pr_err("Unknown power-control type %llu\n", type); +		} +		break;  	default: -		pr_err("OPAL: power control type unexpected %016llx\n", type); +		pr_err("Unknown OPAL message type %lu\n", msg_type);  	}  	return 0;  } +/* OPAL EPOW event notifier block */ +static struct notifier_block opal_epow_nb = { +	.notifier_call	= opal_power_control_event, +	.next		= NULL, +	.priority	= 0, +}; + +/* OPAL DPO event notifier block */ +static struct notifier_block opal_dpo_nb = { +	.notifier_call	= opal_power_control_event, +	.next		= NULL, +	.priority	= 0, +}; + +/* OPAL power-control event notifier block */  static struct notifier_block opal_power_control_nb = {  	.notifier_call	= opal_power_control_event,  	.next		= NULL, @@ -51,16 +140,40 @@ static struct notifier_block opal_power_control_nb = {  static int __init opal_power_control_init(void)  { -	int ret; +	int ret, supported = 0; +	struct device_node *np; +	/* Register OPAL power-control events notifier */  	ret = opal_message_notifier_register(OPAL_MSG_SHUTDOWN, -					     &opal_power_control_nb); -	if (ret) { -		pr_err("%s: Can't register OPAL event notifier (%d)\n", -				__func__, ret); -		return ret; +						&opal_power_control_nb); +	if (ret) +		pr_err("Failed to register SHUTDOWN notifier, ret = %d\n", ret); + +	/* Determine OPAL EPOW, DPO support */ +	np = of_find_node_by_path("/ibm,opal/epow"); +	if (np) { +		supported = of_device_is_compatible(np, "ibm,opal-v3-epow"); +		of_node_put(np);  	} +	if (!supported) +		return 0; +	pr_info("OPAL EPOW, DPO support detected.\n"); + +	/* Register EPOW event notifier */ +	ret = opal_message_notifier_register(OPAL_MSG_EPOW, &opal_epow_nb); +	if (ret) +		pr_err("Failed to register EPOW notifier, ret = %d\n", ret); + +	/* Register DPO event notifier */ +	ret = opal_message_notifier_register(OPAL_MSG_DPO, &opal_dpo_nb); +	if (ret) +		pr_err("Failed to register DPO notifier, ret = %d\n", ret); + +	/* Check for any pending EPOW or DPO events. */ +	if (poweroff_pending()) +		orderly_poweroff(true); +  	return 0;  }  machine_subsys_initcall(powernv, opal_power_control_init); diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index d6a7b8252e4d..b7a464fef7a7 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -202,6 +202,7 @@ OPAL_CALL(opal_rtc_read,			OPAL_RTC_READ);  OPAL_CALL(opal_rtc_write,			OPAL_RTC_WRITE);  OPAL_CALL(opal_cec_power_down,			OPAL_CEC_POWER_DOWN);  OPAL_CALL(opal_cec_reboot,			OPAL_CEC_REBOOT); +OPAL_CALL(opal_cec_reboot2,			OPAL_CEC_REBOOT2);  OPAL_CALL(opal_read_nvram,			OPAL_READ_NVRAM);  OPAL_CALL(opal_write_nvram,			OPAL_WRITE_NVRAM);  OPAL_CALL(opal_handle_interrupt,		OPAL_HANDLE_INTERRUPT); @@ -249,6 +250,7 @@ OPAL_CALL(opal_pci_reinit,			OPAL_PCI_REINIT);  OPAL_CALL(opal_pci_mask_pe_error,		OPAL_PCI_MASK_PE_ERROR);  OPAL_CALL(opal_set_slot_led_status,		OPAL_SET_SLOT_LED_STATUS);  OPAL_CALL(opal_get_epow_status,			OPAL_GET_EPOW_STATUS); +OPAL_CALL(opal_get_dpo_status,			OPAL_GET_DPO_STATUS);  OPAL_CALL(opal_set_system_attention_led,	OPAL_SET_SYSTEM_ATTENTION_LED);  OPAL_CALL(opal_pci_next_error,			OPAL_PCI_NEXT_ERROR);  OPAL_CALL(opal_pci_poll,			OPAL_PCI_POLL); @@ -297,3 +299,5 @@ OPAL_CALL(opal_flash_read,			OPAL_FLASH_READ);  OPAL_CALL(opal_flash_write,			OPAL_FLASH_WRITE);  OPAL_CALL(opal_flash_erase,			OPAL_FLASH_ERASE);  OPAL_CALL(opal_prd_msg,				OPAL_PRD_MSG); +OPAL_CALL(opal_leds_get_ind,			OPAL_LEDS_GET_INDICATOR); +OPAL_CALL(opal_leds_set_ind,			OPAL_LEDS_SET_INDICATOR); diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index f084afa0e3ba..230f3a7cdea4 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -441,6 +441,7 @@ static int opal_recover_mce(struct pt_regs *regs,  int opal_machine_check(struct pt_regs *regs)  {  	struct machine_check_event evt; +	int ret;  	if (!get_mce_event(&evt, MCE_EVENT_RELEASE))  		return 0; @@ -455,6 +456,40 @@ int opal_machine_check(struct pt_regs *regs)  	if (opal_recover_mce(regs, &evt))  		return 1; + +	/* +	 * Unrecovered machine check, we are heading to panic path. +	 * +	 * We may have hit this MCE in very early stage of kernel +	 * initialization even before opal-prd has started running. If +	 * this is the case then this MCE error may go un-noticed or +	 * un-analyzed if we go down panic path. We need to inform +	 * BMC/OCC about this error so that they can collect relevant +	 * data for error analysis before rebooting. +	 * Use opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR) to do so. +	 * This function may not return on BMC based system. +	 */ +	ret = opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR, +			"Unrecoverable Machine Check exception"); +	if (ret == OPAL_UNSUPPORTED) { +		pr_emerg("Reboot type %d not supported\n", +					OPAL_REBOOT_PLATFORM_ERROR); +	} + +	/* +	 * We reached here. There can be three possibilities: +	 * 1. We are running on a firmware level that do not support +	 *    opal_cec_reboot2() +	 * 2. We are running on a firmware level that do not support +	 *    OPAL_REBOOT_PLATFORM_ERROR reboot type. +	 * 3. We are running on FSP based system that does not need opal +	 *    to trigger checkstop explicitly for error analysis. The FSP +	 *    PRD component would have already got notified about this +	 *    error through other channels. +	 * +	 * In any case, let us just fall through. We anyway heading +	 * down to panic path. +	 */  	return 0;  } @@ -648,7 +683,7 @@ static void opal_init_heartbeat(void)  static int __init opal_init(void)  { -	struct device_node *np, *consoles; +	struct device_node *np, *consoles, *leds;  	int rc;  	opal_node = of_find_node_by_path("/ibm,opal"); @@ -689,6 +724,13 @@ static int __init opal_init(void)  	/* Setup a heatbeat thread if requested by OPAL */  	opal_init_heartbeat(); +	/* Create leds platform devices */ +	leds = of_find_node_by_path("/ibm,opal/leds"); +	if (leds) { +		of_platform_device_create(leds, "opal_leds", NULL); +		of_node_put(leds); +	} +  	/* Create "opal" kobject under /sys/firmware */  	rc = opal_sysfs_init();  	if (rc == 0) { @@ -841,3 +883,6 @@ EXPORT_SYMBOL_GPL(opal_rtc_write);  EXPORT_SYMBOL_GPL(opal_tpo_read);  EXPORT_SYMBOL_GPL(opal_tpo_write);  EXPORT_SYMBOL_GPL(opal_i2c_request); +/* Export these symbols for PowerNV LED class driver */ +EXPORT_SYMBOL_GPL(opal_leds_get_ind); +EXPORT_SYMBOL_GPL(opal_leds_set_ind); diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 5738d315248b..2927cd5c8303 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -140,11 +140,9 @@ static void pnv_ioda_reserve_pe(struct pnv_phb *phb, int pe_no)  		return;  	} -	if (test_and_set_bit(pe_no, phb->ioda.pe_alloc)) { -		pr_warn("%s: PE %d was assigned on PHB#%x\n", -			__func__, pe_no, phb->hose->global_number); -		return; -	} +	if (test_and_set_bit(pe_no, phb->ioda.pe_alloc)) +		pr_debug("%s: PE %d was reserved on PHB#%x\n", +			 __func__, pe_no, phb->hose->global_number);  	phb->ioda.pe_array[pe_no].phb = phb;  	phb->ioda.pe_array[pe_no].pe_number = pe_no; @@ -231,61 +229,60 @@ fail:  	return -EIO;  } -static void pnv_ioda2_reserve_m64_pe(struct pnv_phb *phb) +static void pnv_ioda2_reserve_dev_m64_pe(struct pci_dev *pdev, +					 unsigned long *pe_bitmap)  { -	resource_size_t sgsz = phb->ioda.m64_segsize; -	struct pci_dev *pdev; +	struct pci_controller *hose = pci_bus_to_host(pdev->bus); +	struct pnv_phb *phb = hose->private_data;  	struct resource *r; -	int base, step, i; - -	/* -	 * Root bus always has full M64 range and root port has -	 * M64 range used in reality. So we're checking root port -	 * instead of root bus. -	 */ -	list_for_each_entry(pdev, &phb->hose->bus->devices, bus_list) { -		for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) { -			r = &pdev->resource[PCI_BRIDGE_RESOURCES + i]; -			if (!r->parent || -			    !pnv_pci_is_mem_pref_64(r->flags)) -				continue; +	resource_size_t base, sgsz, start, end; +	int segno, i; + +	base = phb->ioda.m64_base; +	sgsz = phb->ioda.m64_segsize; +	for (i = 0; i <= PCI_ROM_RESOURCE; i++) { +		r = &pdev->resource[i]; +		if (!r->parent || !pnv_pci_is_mem_pref_64(r->flags)) +			continue; -			base = (r->start - phb->ioda.m64_base) / sgsz; -			for (step = 0; step < resource_size(r) / sgsz; step++) -				pnv_ioda_reserve_pe(phb, base + step); +		start = _ALIGN_DOWN(r->start - base, sgsz); +		end = _ALIGN_UP(r->end - base, sgsz); +		for (segno = start / sgsz; segno < end / sgsz; segno++) { +			if (pe_bitmap) +				set_bit(segno, pe_bitmap); +			else +				pnv_ioda_reserve_pe(phb, segno);  		}  	}  } -static int pnv_ioda2_pick_m64_pe(struct pnv_phb *phb, -				 struct pci_bus *bus, int all) +static void pnv_ioda2_reserve_m64_pe(struct pci_bus *bus, +				     unsigned long *pe_bitmap, +				     bool all)  { -	resource_size_t segsz = phb->ioda.m64_segsize;  	struct pci_dev *pdev; -	struct resource *r; + +	list_for_each_entry(pdev, &bus->devices, bus_list) { +		pnv_ioda2_reserve_dev_m64_pe(pdev, pe_bitmap); + +		if (all && pdev->subordinate) +			pnv_ioda2_reserve_m64_pe(pdev->subordinate, +						 pe_bitmap, all); +	} +} + +static int pnv_ioda2_pick_m64_pe(struct pci_bus *bus, bool all) +{ +	struct pci_controller *hose = pci_bus_to_host(bus); +	struct pnv_phb *phb = hose->private_data;  	struct pnv_ioda_pe *master_pe, *pe;  	unsigned long size, *pe_alloc; -	bool found; -	int start, i, j; +	int i;  	/* Root bus shouldn't use M64 */  	if (pci_is_root_bus(bus))  		return IODA_INVALID_PE; -	/* We support only one M64 window on each bus */ -	found = false; -	pci_bus_for_each_resource(bus, r, i) { -		if (r && r->parent && -		    pnv_pci_is_mem_pref_64(r->flags)) { -			found = true; -			break; -		} -	} - -	/* No M64 window found ? */ -	if (!found) -		return IODA_INVALID_PE; -  	/* Allocate bitmap */  	size = _ALIGN_UP(phb->ioda.total_pe / 8, sizeof(unsigned long));  	pe_alloc = kzalloc(size, GFP_KERNEL); @@ -295,35 +292,8 @@ static int pnv_ioda2_pick_m64_pe(struct pnv_phb *phb,  		return IODA_INVALID_PE;  	} -	/* -	 * Figure out reserved PE numbers by the PE -	 * the its child PEs. -	 */ -	start = (r->start - phb->ioda.m64_base) / segsz; -	for (i = 0; i < resource_size(r) / segsz; i++) -		set_bit(start + i, pe_alloc); - -	if (all) -		goto done; - -	/* -	 * If the PE doesn't cover all subordinate buses, -	 * we need subtract from reserved PEs for children. -	 */ -	list_for_each_entry(pdev, &bus->devices, bus_list) { -		if (!pdev->subordinate) -			continue; - -		pci_bus_for_each_resource(pdev->subordinate, r, i) { -			if (!r || !r->parent || -			    !pnv_pci_is_mem_pref_64(r->flags)) -				continue; - -			start = (r->start - phb->ioda.m64_base) / segsz; -			for (j = 0; j < resource_size(r) / segsz ; j++) -				clear_bit(start + j, pe_alloc); -                } -        } +	/* Figure out reserved PE numbers by the PE */ +	pnv_ioda2_reserve_m64_pe(bus, pe_alloc, all);  	/*  	 * the current bus might not own M64 window and that's all @@ -339,7 +309,6 @@ static int pnv_ioda2_pick_m64_pe(struct pnv_phb *phb,  	 * Figure out the master PE and put all slave PEs to master  	 * PE's list to form compound PE.  	 */ -done:  	master_pe = NULL;  	i = -1;  	while ((i = find_next_bit(pe_alloc, phb->ioda.total_pe, i + 1)) < @@ -653,7 +622,7 @@ static int pnv_ioda_set_peltv(struct pnv_phb *phb,  		pdev = pe->pdev->bus->self;  #ifdef CONFIG_PCI_IOV  	else if (pe->flags & PNV_IODA_PE_VF) -		pdev = pe->parent_dev->bus->self; +		pdev = pe->parent_dev;  #endif /* CONFIG_PCI_IOV */  	while (pdev) {  		struct pci_dn *pdn = pci_get_pdn(pdev); @@ -732,7 +701,7 @@ static int pnv_ioda_deconfigure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe)  		parent = parent->bus->self;  	} -	opal_pci_eeh_freeze_set(phb->opal_id, pe->pe_number, +	opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number,  				  OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);  	/* Disassociate PE in PELT */ @@ -946,8 +915,9 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset)  		res2 = *res;  		res->start += size * offset; -		dev_info(&dev->dev, "VF BAR%d: %pR shifted to %pR (enabling %d VFs shifted by %d)\n", -			 i, &res2, res, num_vfs, offset); +		dev_info(&dev->dev, "VF BAR%d: %pR shifted to %pR (%sabling %d VFs shifted by %d)\n", +			 i, &res2, res, (offset > 0) ? "En" : "Dis", +			 num_vfs, offset);  		pci_update_resource(dev, i + PCI_IOV_RESOURCES);  	}  	return 0; @@ -1050,7 +1020,7 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe)   * subordinate PCI devices and buses. The second type of PE is normally   * orgiriated by PCIe-to-PCI bridge or PLX switch downstream ports.   */ -static void pnv_ioda_setup_bus_PE(struct pci_bus *bus, int all) +static void pnv_ioda_setup_bus_PE(struct pci_bus *bus, bool all)  {  	struct pci_controller *hose = pci_bus_to_host(bus);  	struct pnv_phb *phb = hose->private_data; @@ -1059,7 +1029,7 @@ static void pnv_ioda_setup_bus_PE(struct pci_bus *bus, int all)  	/* Check if PE is determined by M64 */  	if (phb->pick_m64_pe) -		pe_num = phb->pick_m64_pe(phb, bus, all); +		pe_num = phb->pick_m64_pe(bus, all);  	/* The PE number isn't pinned by M64 */  	if (pe_num == IODA_INVALID_PE) @@ -1117,12 +1087,12 @@ static void pnv_ioda_setup_PEs(struct pci_bus *bus)  {  	struct pci_dev *dev; -	pnv_ioda_setup_bus_PE(bus, 0); +	pnv_ioda_setup_bus_PE(bus, false);  	list_for_each_entry(dev, &bus->devices, bus_list) {  		if (dev->subordinate) {  			if (pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE) -				pnv_ioda_setup_bus_PE(dev->subordinate, 1); +				pnv_ioda_setup_bus_PE(dev->subordinate, true);  			else  				pnv_ioda_setup_PEs(dev->subordinate);  		} @@ -1147,7 +1117,7 @@ static void pnv_pci_ioda_setup_PEs(void)  		/* M64 layout might affect PE allocation */  		if (phb->reserve_m64_pe) -			phb->reserve_m64_pe(phb); +			phb->reserve_m64_pe(hose->bus, NULL, true);  		pnv_ioda_setup_PEs(hose->bus);  	} @@ -1590,6 +1560,7 @@ static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev  	pe = &phb->ioda.pe_array[pdn->pe_number];  	WARN_ON(get_dma_ops(&pdev->dev) != &dma_iommu_ops); +	set_dma_offset(&pdev->dev, pe->tce_bypass_base);  	set_iommu_table_base(&pdev->dev, pe->table_group.tables[0]);  	/*  	 * Note: iommu_add_device() will fail here as @@ -1620,19 +1591,18 @@ static int pnv_pci_ioda_dma_set_mask(struct pci_dev *pdev, u64 dma_mask)  	if (bypass) {  		dev_info(&pdev->dev, "Using 64-bit DMA iommu bypass\n");  		set_dma_ops(&pdev->dev, &dma_direct_ops); -		set_dma_offset(&pdev->dev, pe->tce_bypass_base);  	} else {  		dev_info(&pdev->dev, "Using 32-bit DMA via iommu\n");  		set_dma_ops(&pdev->dev, &dma_iommu_ops); -		set_iommu_table_base(&pdev->dev, pe->table_group.tables[0]);  	}  	*pdev->dev.dma_mask = dma_mask;  	return 0;  } -static u64 pnv_pci_ioda_dma_get_required_mask(struct pnv_phb *phb, -					      struct pci_dev *pdev) +static u64 pnv_pci_ioda_dma_get_required_mask(struct pci_dev *pdev)  { +	struct pci_controller *hose = pci_bus_to_host(pdev->bus); +	struct pnv_phb *phb = hose->private_data;  	struct pci_dn *pdn = pci_get_pdn(pdev);  	struct pnv_ioda_pe *pe;  	u64 end, mask; @@ -1659,6 +1629,7 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe,  	list_for_each_entry(dev, &bus->devices, bus_list) {  		set_iommu_table_base(&dev->dev, pe->table_group.tables[0]); +		set_dma_offset(&dev->dev, pe->tce_bypass_base);  		iommu_add_device(&dev->dev);  		if ((pe->flags & PNV_IODA_PE_BUS_ALL) && dev->subordinate) @@ -2220,7 +2191,7 @@ static void pnv_pci_ioda_setup_opal_tce_kill(struct pnv_phb *phb)  static __be64 *pnv_pci_ioda2_table_do_alloc_pages(int nid, unsigned shift,  		unsigned levels, unsigned long limit, -		unsigned long *current_offset) +		unsigned long *current_offset, unsigned long *total_allocated)  {  	struct page *tce_mem = NULL;  	__be64 *addr, *tmp; @@ -2236,6 +2207,7 @@ static __be64 *pnv_pci_ioda2_table_do_alloc_pages(int nid, unsigned shift,  	}  	addr = page_address(tce_mem);  	memset(addr, 0, allocated); +	*total_allocated += allocated;  	--levels;  	if (!levels) { @@ -2245,7 +2217,7 @@ static __be64 *pnv_pci_ioda2_table_do_alloc_pages(int nid, unsigned shift,  	for (i = 0; i < entries; ++i) {  		tmp = pnv_pci_ioda2_table_do_alloc_pages(nid, shift, -				levels, limit, current_offset); +				levels, limit, current_offset, total_allocated);  		if (!tmp)  			break; @@ -2267,7 +2239,7 @@ static long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,  		struct iommu_table *tbl)  {  	void *addr; -	unsigned long offset = 0, level_shift; +	unsigned long offset = 0, level_shift, total_allocated = 0;  	const unsigned window_shift = ilog2(window_size);  	unsigned entries_shift = window_shift - page_shift;  	unsigned table_shift = max_t(unsigned, entries_shift + 3, PAGE_SHIFT); @@ -2286,7 +2258,7 @@ static long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,  	/* Allocate TCE table */  	addr = pnv_pci_ioda2_table_do_alloc_pages(nid, level_shift, -			levels, tce_table_size, &offset); +			levels, tce_table_size, &offset, &total_allocated);  	/* addr==NULL means that the first level allocation failed */  	if (!addr) @@ -2308,7 +2280,7 @@ static long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,  			page_shift);  	tbl->it_level_size = 1ULL << (level_shift - 3);  	tbl->it_indirect_levels = levels - 1; -	tbl->it_allocated_size = offset; +	tbl->it_allocated_size = total_allocated;  	pr_devel("Created TCE table: ws=%08llx ts=%lx @%08llx\n",  			window_size, tce_table_size, bus_offset); @@ -3056,6 +3028,7 @@ static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {         .window_alignment = pnv_pci_window_alignment,         .reset_secondary_bus = pnv_pci_reset_secondary_bus,         .dma_set_mask = pnv_pci_ioda_dma_set_mask, +       .dma_get_required_mask = pnv_pci_ioda_dma_get_required_mask,         .shutdown = pnv_pci_ioda_shutdown,  }; @@ -3202,7 +3175,6 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,  	/* Setup TCEs */  	phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup; -	phb->dma_get_required_mask = pnv_pci_ioda_dma_get_required_mask;  	/* Setup MSI support */  	pnv_pci_init_ioda_msis(phb); diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 765d8ed558d0..9b2480b265c0 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -61,7 +61,7 @@ int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)  	if (pdev->no_64bit_msi && !phb->msi32_support)  		return -ENODEV; -	list_for_each_entry(entry, &pdev->msi_list, list) { +	for_each_pci_msi_entry(entry, pdev) {  		if (!entry->msi_attrib.is_64 && !phb->msi32_support) {  			pr_warn("%s: Supports only 64-bit MSIs\n",  				pci_name(pdev)); @@ -103,7 +103,7 @@ void pnv_teardown_msi_irqs(struct pci_dev *pdev)  	if (WARN_ON(!phb))  		return; -	list_for_each_entry(entry, &pdev->msi_list, list) { +	for_each_pci_msi_entry(entry, pdev) {  		if (entry->irq == NO_IRQ)  			continue;  		irq_set_msi_desc(entry->irq, NULL); @@ -761,17 +761,6 @@ void pnv_pci_dma_dev_setup(struct pci_dev *pdev)  		phb->dma_dev_setup(phb, pdev);  } -u64 pnv_pci_dma_get_required_mask(struct pci_dev *pdev) -{ -	struct pci_controller *hose = pci_bus_to_host(pdev->bus); -	struct pnv_phb *phb = hose->private_data; - -	if (phb && phb->dma_get_required_mask) -		return phb->dma_get_required_mask(phb, pdev); - -	return __dma_get_required_mask(&pdev->dev); -} -  void pnv_pci_shutdown(void)  {  	struct pci_controller *hose; diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 8ef2d28aded0..c8ff50e90766 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -105,13 +105,12 @@ struct pnv_phb {  			 unsigned int hwirq, unsigned int virq,  			 unsigned int is_64, struct msi_msg *msg);  	void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev); -	u64 (*dma_get_required_mask)(struct pnv_phb *phb, -				     struct pci_dev *pdev);  	void (*fixup_phb)(struct pci_controller *hose);  	u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn);  	int (*init_m64)(struct pnv_phb *phb); -	void (*reserve_m64_pe)(struct pnv_phb *phb); -	int (*pick_m64_pe)(struct pnv_phb *phb, struct pci_bus *bus, int all); +	void (*reserve_m64_pe)(struct pci_bus *bus, +			       unsigned long *pe_bitmap, bool all); +	int (*pick_m64_pe)(struct pci_bus *bus, bool all);  	int (*get_pe_state)(struct pnv_phb *phb, int pe_no);  	void (*freeze_pe)(struct pnv_phb *phb, int pe_no);  	int (*unfreeze_pe)(struct pnv_phb *phb, int pe_no, int opt); diff --git a/arch/powerpc/platforms/powernv/powernv.h b/arch/powerpc/platforms/powernv/powernv.h index 9269e30e4ca0..6dbc0a1da1f6 100644 --- a/arch/powerpc/platforms/powernv/powernv.h +++ b/arch/powerpc/platforms/powernv/powernv.h @@ -12,15 +12,9 @@ struct pci_dev;  #ifdef CONFIG_PCI  extern void pnv_pci_init(void);  extern void pnv_pci_shutdown(void); -extern u64 pnv_pci_dma_get_required_mask(struct pci_dev *pdev);  #else  static inline void pnv_pci_init(void) { }  static inline void pnv_pci_shutdown(void) { } - -static inline u64 pnv_pci_dma_get_required_mask(struct pci_dev *pdev) -{ -	return 0; -}  #endif  extern u32 pnv_get_supported_cpuidle_states(void); diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c index 6eb808ff637e..5dcbdea1afac 100644 --- a/arch/powerpc/platforms/powernv/rng.c +++ b/arch/powerpc/platforms/powernv/rng.c @@ -128,7 +128,7 @@ static __init int rng_create(struct device_node *dn)  	pr_info_once("Registering arch random hook.\n"); -	ppc_md.get_random_long = powernv_get_random_long; +	ppc_md.get_random_seed = powernv_get_random_long;  	return 0;  } diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 53737e019ae3..685b3cbe1362 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -165,14 +165,6 @@ static void pnv_progress(char *s, unsigned short hex)  {  } -static u64 pnv_dma_get_required_mask(struct device *dev) -{ -	if (dev_is_pci(dev)) -		return pnv_pci_dma_get_required_mask(to_pci_dev(dev)); - -	return __dma_get_required_mask(dev); -} -  static void pnv_shutdown(void)  {  	/* Let the PCI code clear up IODA tables */ @@ -243,6 +235,13 @@ static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)  	} else {  		/* Primary waits for the secondaries to have reached OPAL */  		pnv_kexec_wait_secondaries_down(); + +		/* +		 * We might be running as little-endian - now that interrupts +		 * are disabled, reset the HILE bit to big-endian so we don't +		 * take interrupts in the wrong endian later +		 */ +		opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_BE);  	}  }  #endif /* CONFIG_KEXEC */ @@ -314,7 +313,6 @@ define_machine(powernv) {  	.machine_shutdown	= pnv_shutdown,  	.power_save             = power7_idle,  	.calibrate_decr		= generic_calibrate_decr, -	.dma_get_required_mask	= pnv_dma_get_required_mask,  #ifdef CONFIG_KEXEC  	.kexec_cpu_down		= pnv_kexec_cpu_down,  #endif diff --git a/arch/powerpc/platforms/powernv/subcore.c b/arch/powerpc/platforms/powernv/subcore.c index f60f80ada903..503a73f59359 100644 --- a/arch/powerpc/platforms/powernv/subcore.c +++ b/arch/powerpc/platforms/powernv/subcore.c @@ -190,7 +190,7 @@ static void unsplit_core(void)  	hid0 = mfspr(SPRN_HID0);  	hid0 &= ~HID0_POWER8_DYNLPARDIS; -	mtspr(SPRN_HID0, hid0); +	update_power8_hid0(hid0);  	update_hid_in_slw(hid0);  	while (mfspr(SPRN_HID0) & mask) @@ -227,7 +227,7 @@ static void split_core(int new_mode)  	/* Write new mode */  	hid0  = mfspr(SPRN_HID0);  	hid0 |= HID0_POWER8_DYNLPARDIS | split_parms[i].value; -	mtspr(SPRN_HID0, hid0); +	update_power8_hid0(hid0);  	update_hid_in_slw(hid0);  	/* Wait for it to happen */ diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index a6c42f34303a..638c4060938e 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c @@ -678,7 +678,8 @@ static int ps3_host_map(struct irq_domain *h, unsigned int virq,  	return 0;  } -static int ps3_host_match(struct irq_domain *h, struct device_node *np) +static int ps3_host_match(struct irq_domain *h, struct device_node *np, +			  enum irq_domain_bus_token bus_token)  {  	/* Match all */  	return 1; diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 0ced387e1463..e9ff44cd5d86 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -92,13 +92,12 @@ static struct property *dlpar_clone_drconf_property(struct device_node *dn)  		return NULL;  	new_prop->name = kstrdup(prop->name, GFP_KERNEL); -	new_prop->value = kmalloc(prop->length, GFP_KERNEL); +	new_prop->value = kmemdup(prop->value, prop->length, GFP_KERNEL);  	if (!new_prop->name || !new_prop->value) {  		dlpar_free_drconf_property(new_prop);  		return NULL;  	} -	memcpy(new_prop->value, prop->value, prop->length);  	new_prop->length = prop->length;  	/* Convert the property to cpu endian-ness */ diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 10510dea16b3..0946b98d75d4 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -1253,11 +1253,10 @@ static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask)  		}  	} -	/* fall back on iommu ops, restore table pointer with ops */ +	/* fall back on iommu ops */  	if (!ddw_enabled && get_dma_ops(dev) != &dma_iommu_ops) {  		dev_info(dev, "Restoring 32-bit DMA via iommu\n");  		set_dma_ops(dev, &dma_iommu_ops); -		pci_dma_dev_setup_pSeriesLP(pdev);  	}  check_mask: diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index c22bb647cce6..272e9ec1ab54 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -118,7 +118,7 @@ static void rtas_teardown_msi_irqs(struct pci_dev *pdev)  {  	struct msi_desc *entry; -	list_for_each_entry(entry, &pdev->msi_list, list) { +	for_each_pci_msi_entry(entry, pdev) {  		if (entry->irq == NO_IRQ)  			continue; @@ -350,7 +350,7 @@ static int check_msix_entries(struct pci_dev *pdev)  	 * So we must reject such requests. */  	expected = 0; -	list_for_each_entry(entry, &pdev->msi_list, list) { +	for_each_pci_msi_entry(entry, pdev) {  		if (entry->msi_attrib.entry_nr != expected) {  			pr_debug("rtas_msi: bad MSI-X entries.\n");  			return -EINVAL; @@ -462,7 +462,7 @@ again:  	}  	i = 0; -	list_for_each_entry(entry, &pdev->msi_list, list) { +	for_each_pci_msi_entry(entry, pdev) {  		hwirq = rtas_query_irq_number(pdn, i++);  		if (hwirq < 0) {  			pr_debug("rtas_msi: error (%d) getting hwirq\n", rc); diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index 02e4a1745516..3b6647e574b6 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -189,7 +189,8 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id)  	int state;  	int critical; -	status = rtas_get_sensor(EPOW_SENSOR_TOKEN, EPOW_SENSOR_INDEX, &state); +	status = rtas_get_sensor_fast(EPOW_SENSOR_TOKEN, EPOW_SENSOR_INDEX, +				      &state);  	if (state > 3)  		critical = 1;		/* Time Critical */ diff --git a/arch/powerpc/platforms/pseries/rng.c b/arch/powerpc/platforms/pseries/rng.c index e09608770909..31ca557af60b 100644 --- a/arch/powerpc/platforms/pseries/rng.c +++ b/arch/powerpc/platforms/pseries/rng.c @@ -38,7 +38,7 @@ static __init int rng_init(void)  	pr_info("Registering arch random hook.\n"); -	ppc_md.get_random_long = pseries_get_random_long; +	ppc_md.get_random_seed = pseries_get_random_long;  	return 0;  } diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index df6a7041922b..39a74fad3e04 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -254,19 +254,26 @@ static void __init pseries_discover_pic(void)  static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *data)  {  	struct of_reconfig_data *rd = data; -	struct device_node *np = rd->dn; -	struct pci_dn *pci = NULL; +	struct device_node *parent, *np = rd->dn; +	struct pci_dn *pdn;  	int err = NOTIFY_OK;  	switch (action) {  	case OF_RECONFIG_ATTACH_NODE: -		pci = np->parent->data; -		if (pci) { -			update_dn_pci_info(np, pci->phb); - -			/* Create EEH device for the OF node */ -			eeh_dev_init(PCI_DN(np), pci->phb); +		parent = of_get_parent(np); +		pdn = parent ? PCI_DN(parent) : NULL; +		if (pdn) { +			/* Create pdn and EEH device */ +			update_dn_pci_info(np, pdn->phb); +			eeh_dev_init(PCI_DN(np), pdn->phb);  		} + +		of_node_put(parent); +		break; +	case OF_RECONFIG_DETACH_NODE: +		pdn = PCI_DN(np); +		if (pdn) +			list_del(&pdn->list);  		break;  	default:  		err = NOTIFY_DONE; diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index ee90db17b097..d2b79bc336c1 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -132,7 +132,7 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)  		phys_mem += vec.bv_len;  		transfered += vec.bv_len;  	} -	bio_endio(bio, 0); +	bio_endio(bio);  }  /** @@ -141,13 +141,14 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)   */  static long  axon_ram_direct_access(struct block_device *device, sector_t sector, -		       void **kaddr, unsigned long *pfn, long size) +		       void __pmem **kaddr, unsigned long *pfn)  {  	struct axon_ram_bank *bank = device->bd_disk->private_data;  	loff_t offset = (loff_t)sector << AXON_RAM_SECTOR_SHIFT; +	void *addr = (void *)(bank->ph_addr + offset); -	*kaddr = (void *)(bank->ph_addr + offset); -	*pfn = virt_to_phys(*kaddr) >> PAGE_SHIFT; +	*kaddr = (void __pmem *)addr; +	*pfn = virt_to_phys(addr) >> PAGE_SHIFT;  	return bank->size - offset;  } diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 4f7869571290..e2ea51961979 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c @@ -147,7 +147,7 @@ unsigned long cpm_muram_alloc(unsigned long size, unsigned long align)  	spin_lock_irqsave(&cpm_muram_lock, flags);  	cpm_muram_info.alignment = align;  	start = rh_alloc(&cpm_muram_info, size, "commproc"); -	memset(cpm_muram_addr(start), 0, size); +	memset_io(cpm_muram_addr(start), 0, size);  	spin_unlock_irqrestore(&cpm_muram_lock, flags);  	return start; diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 90bcdfeedf48..b7348637eae0 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -313,20 +313,11 @@ static void iommu_table_dart_setup(void)  	set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map);  } -static void dma_dev_setup_dart(struct device *dev) -{ -	/* We only have one iommu table on the mac for now, which makes -	 * things simple. Setup all PCI devices to point to this table -	 */ -	if (get_dma_ops(dev) == &dma_direct_ops) -		set_dma_offset(dev, DART_U4_BYPASS_BASE); -	else -		set_iommu_table_base(dev, &iommu_table_dart); -} -  static void pci_dma_dev_setup_dart(struct pci_dev *dev)  { -	dma_dev_setup_dart(&dev->dev); +	if (dart_is_u4) +		set_dma_offset(&dev->dev, DART_U4_BYPASS_BASE); +	set_iommu_table_base(&dev->dev, &iommu_table_dart);  }  static void pci_dma_bus_setup_dart(struct pci_bus *bus) @@ -370,7 +361,6 @@ static int dart_dma_set_mask(struct device *dev, u64 dma_mask)  		dev_info(dev, "Using 32-bit DMA via iommu\n");  		set_dma_ops(dev, &dma_iommu_ops);  	} -	dma_dev_setup_dart(dev);  	*dev->dma_mask = dma_mask;  	return 0; diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c index 2d20f10a4203..eca0b00794fa 100644 --- a/arch/powerpc/sysdev/ehv_pic.c +++ b/arch/powerpc/sysdev/ehv_pic.c @@ -177,7 +177,8 @@ unsigned int ehv_pic_get_irq(void)  	return irq_linear_revmap(global_ehv_pic->irqhost, irq);  } -static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node) +static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node, +			      enum irq_domain_bus_token bus_token)  {  	/* Exact match, unless ehv_pic node is NULL */  	return h->of_node == NULL || h->of_node == node; diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 5236e5427c38..5916da1856a7 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -129,7 +129,7 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev)  	struct msi_desc *entry;  	struct fsl_msi *msi_data; -	list_for_each_entry(entry, &pdev->msi_list, list) { +	for_each_pci_msi_entry(entry, pdev) {  		if (entry->irq == NO_IRQ)  			continue;  		msi_data = irq_get_chip_data(entry->irq); @@ -219,7 +219,7 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)  		}  	} -	list_for_each_entry(entry, &pdev->msi_list, list) { +	for_each_pci_msi_entry(entry, pdev) {  		/*  		 * Loop over all the MSI devices until we find one that has an  		 * available interrupt. diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 9a8fcf0d79d7..ebc1f412cf49 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -1113,7 +1113,7 @@ static int fsl_pci_pme_probe(struct pci_controller *hose)  			IRQF_SHARED,  			"[PCI] PME", hose);  	if (res < 0) { -		dev_err(&dev->dev, "Unable to requiest irq %d for PME\n", pme_irq); +		dev_err(&dev->dev, "Unable to request irq %d for PME\n", pme_irq);  		irq_dispose_mapping(pme_irq);  		return -ENODEV; diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c index 31c33475c7b7..e1a9c2c2d5d3 100644 --- a/arch/powerpc/sysdev/i8259.c +++ b/arch/powerpc/sysdev/i8259.c @@ -162,7 +162,8 @@ static struct resource pic_edgectrl_iores = {  	.flags = IORESOURCE_BUSY,  }; -static int i8259_host_match(struct irq_domain *h, struct device_node *node) +static int i8259_host_match(struct irq_domain *h, struct device_node *node, +			    enum irq_domain_bus_token bus_token)  {  	return h->of_node == NULL || h->of_node == node;  } diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index d78f1364b639..6b2b68914810 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -671,7 +671,8 @@ static struct irq_chip ipic_edge_irq_chip = {  	.irq_set_type	= ipic_set_irq_type,  }; -static int ipic_host_match(struct irq_domain *h, struct device_node *node) +static int ipic_host_match(struct irq_domain *h, struct device_node *node, +			   enum irq_domain_bus_token bus_token)  {  	/* Exact match, unless ipic node is NULL */  	return h->of_node == NULL || h->of_node == node; diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index c8e73332eaad..97a8ae8f94dd 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1007,7 +1007,8 @@ static struct irq_chip mpic_irq_ht_chip = {  #endif /* CONFIG_MPIC_U3_HT_IRQS */ -static int mpic_host_match(struct irq_domain *h, struct device_node *node) +static int mpic_host_match(struct irq_domain *h, struct device_node *node, +			   enum irq_domain_bus_token bus_token)  {  	/* Exact match, unless mpic node is NULL */  	return h->of_node == NULL || h->of_node == node; diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c index fc46ef3b816e..70fbd5694a8b 100644 --- a/arch/powerpc/sysdev/mpic_u3msi.c +++ b/arch/powerpc/sysdev/mpic_u3msi.c @@ -108,7 +108,7 @@ static void u3msi_teardown_msi_irqs(struct pci_dev *pdev)  {  	struct msi_desc *entry; -        list_for_each_entry(entry, &pdev->msi_list, list) { +	for_each_pci_msi_entry(entry, pdev) {  		if (entry->irq == NO_IRQ)  			continue; @@ -140,7 +140,7 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)  		return -ENXIO;  	} -	list_for_each_entry(entry, &pdev->msi_list, list) { +	for_each_pci_msi_entry(entry, pdev) {  		hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1);  		if (hwirq < 0) {  			pr_debug("u3msi: failed allocating hwirq\n"); diff --git a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c index 87f9623ca805..52a93dcae262 100644 --- a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c +++ b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c @@ -51,7 +51,7 @@ static int hsta_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)  		return -EINVAL;  	} -	list_for_each_entry(entry, &dev->msi_list, list) { +	for_each_pci_msi_entry(entry, dev) {  		irq = msi_bitmap_alloc_hwirqs(&ppc4xx_hsta_msi.bmp, 1);  		if (irq < 0) {  			pr_debug("%s: Failed to allocate msi interrupt\n", @@ -109,7 +109,7 @@ static void hsta_teardown_msi_irqs(struct pci_dev *dev)  	struct msi_desc *entry;  	int irq; -	list_for_each_entry(entry, &dev->msi_list, list) { +	for_each_pci_msi_entry(entry, dev) {  		if (entry->irq == NO_IRQ)  			continue; @@ -132,7 +132,7 @@ static int hsta_msi_probe(struct platform_device *pdev)  	struct pci_controller *phb;  	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (IS_ERR(mem)) { +	if (!mem) {  		dev_err(dev, "Unable to get mmio space\n");  		return -EINVAL;  	} @@ -157,7 +157,7 @@ static int hsta_msi_probe(struct platform_device *pdev)  		goto out;  	ppc4xx_hsta_msi.irq_map = kmalloc(sizeof(int) * irq_count, GFP_KERNEL); -	if (IS_ERR(ppc4xx_hsta_msi.irq_map)) { +	if (!ppc4xx_hsta_msi.irq_map) {  		ret = -ENOMEM;  		goto out1;  	} diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_msi.c index 6eb21f2ea585..24d0470c1698 100644 --- a/arch/powerpc/sysdev/ppc4xx_msi.c +++ b/arch/powerpc/sysdev/ppc4xx_msi.c @@ -93,7 +93,7 @@ static int ppc4xx_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)  	if (!msi_data->msi_virqs)  		return -ENOMEM; -	list_for_each_entry(entry, &dev->msi_list, list) { +	for_each_pci_msi_entry(entry, dev) {  		int_no = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1);  		if (int_no >= 0)  			break; @@ -127,7 +127,7 @@ void ppc4xx_teardown_msi_irqs(struct pci_dev *dev)  	dev_dbg(&dev->dev, "PCIE-MSI: tearing down msi irqs\n"); -	list_for_each_entry(entry, &dev->msi_list, list) { +	for_each_pci_msi_entry(entry, dev) {  		if (entry->irq == NO_IRQ)  			continue;  		irq_set_msi_desc(entry->irq, NULL); diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c index 6512cd8caa51..47b352e4bc74 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c @@ -244,7 +244,8 @@ static struct irq_chip qe_ic_irq_chip = {  	.irq_mask_ack = qe_ic_mask_irq,  }; -static int qe_ic_host_match(struct irq_domain *h, struct device_node *node) +static int qe_ic_host_match(struct irq_domain *h, struct device_node *node, +			    enum irq_domain_bus_token bus_token)  {  	/* Exact match, unless qe_ic node is NULL */  	return h->of_node == NULL || h->of_node == node; diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c index 68c7e5cc98e0..11ac964d5175 100644 --- a/arch/powerpc/sysdev/xics/ics-opal.c +++ b/arch/powerpc/sysdev/xics/ics-opal.c @@ -72,7 +72,7 @@ static unsigned int ics_opal_startup(struct irq_data *d)  	 * card, using the MSI mask bits. Firmware doesn't appear to unmask  	 * at that level, so we do it here by hand.  	 */ -	if (d->msi_desc) +	if (irq_data_get_msi_desc(d))  		pci_msi_unmask_irq(d);  #endif diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c index 0af97deb83f3..d1c625c4cc5a 100644 --- a/arch/powerpc/sysdev/xics/ics-rtas.c +++ b/arch/powerpc/sysdev/xics/ics-rtas.c @@ -75,7 +75,7 @@ static unsigned int ics_rtas_startup(struct irq_data *d)  	 * card, using the MSI mask bits. Firmware doesn't appear to unmask  	 * at that level, so we do it here by hand.  	 */ -	if (d->msi_desc) +	if (irq_data_get_msi_desc(d))  		pci_msi_unmask_irq(d);  #endif  	/* unmask it */ diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index 08c248eb491b..47e43b7b076b 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c @@ -298,7 +298,8 @@ int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,  }  #endif /* CONFIG_SMP */ -static int xics_host_match(struct irq_domain *h, struct device_node *node) +static int xics_host_match(struct irq_domain *h, struct device_node *node, +			   enum irq_domain_bus_token bus_token)  {  	struct ics *ics; diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index e599259d84fc..6ef1231c6e9c 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -1987,7 +1987,6 @@ memex(void)  			case '^':  				adrs -= size;  				break; -				break;  			case '/':  				if (nslash > 0)  					adrs -= 1 << nslash; @@ -2731,7 +2730,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid,  void dump_segments(void)  {  	int i; -	unsigned long esid,vsid,valid; +	unsigned long esid,vsid;  	unsigned long llp;  	printf("SLB contents of cpu 0x%x\n", smp_processor_id()); @@ -2739,10 +2738,9 @@ void dump_segments(void)  	for (i = 0; i < mmu_slb_size; i++) {  		asm volatile("slbmfee  %0,%1" : "=r" (esid) : "r" (i));  		asm volatile("slbmfev  %0,%1" : "=r" (vsid) : "r" (i)); -		valid = (esid & SLB_ESID_V); -		if (valid | esid | vsid) { +		if (esid || vsid) {  			printf("%02d %016lx %016lx", i, esid, vsid); -			if (valid) { +			if (esid & SLB_ESID_V) {  				llp = vsid & SLB_VSID_LLP;  				if (vsid & SLB_VSID_B_1T) {  					printf("  1T  ESID=%9lx  VSID=%13lx LLP:%3lx \n",  |