LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] powerpc/85xx: Add P1024rdb dts support
From: b29983 @ 2012-01-09  8:37 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Tang Yuantian, Jin Qing, Tang Yuantian

From: Tang Yuantian <B29983@freescale.com>

Signed-off-by: Jin Qing <b24347@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
---
 arch/powerpc/boot/dts/fsl/p1024si-pre.dtsi    |   68 ++++++++
 arch/powerpc/boot/dts/p1024rdb.dts            |   87 ++++++++++
 arch/powerpc/boot/dts/p1024rdb.dtsi           |  228 +++++++++++++++++++++++++
 arch/powerpc/boot/dts/p1024rdb_36b.dts        |   87 ++++++++++
 arch/powerpc/boot/dts/p1024rdb_camp_core0.dts |  106 ++++++++++++
 arch/powerpc/boot/dts/p1024rdb_camp_core1.dts |  161 +++++++++++++++++
 6 files changed, 737 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/boot/dts/fsl/p1024si-pre.dtsi
 create mode 100644 arch/powerpc/boot/dts/p1024rdb.dts
 create mode 100644 arch/powerpc/boot/dts/p1024rdb.dtsi
 create mode 100644 arch/powerpc/boot/dts/p1024rdb_36b.dts
 create mode 100644 arch/powerpc/boot/dts/p1024rdb_camp_core0.dts
 create mode 100644 arch/powerpc/boot/dts/p1024rdb_camp_core1.dts

diff --git a/arch/powerpc/boot/dts/fsl/p1024si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p1024si-pre.dtsi
new file mode 100644
index 0000000..4a0406b
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/p1024si-pre.dtsi
@@ -0,0 +1,68 @@
+/*
+ * P1024 Silicon/SoC Device Tree Source (pre include)
+ *
+ * Copyright 2011 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.
+ */
+
+/dts-v1/;
+/ {
+	compatible = "fsl,P1024";
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&mpic>;
+
+	aliases {
+		serial0 = &serial0;
+		serial1 = &serial1;
+		ethernet0 = &enet0;
+		ethernet1 = &enet1;
+		ethernet2 = &enet2;
+		pci0 = &pci0;
+		pci1 = &pci1;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,P1024@0 {
+			device_type = "cpu";
+			reg = <0x0>;
+			next-level-cache = <&L2>;
+		};
+
+		PowerPC,P1024@1 {
+			device_type = "cpu";
+			reg = <0x1>;
+			next-level-cache = <&L2>;
+		};
+	};
+};
diff --git a/arch/powerpc/boot/dts/p1024rdb.dts b/arch/powerpc/boot/dts/p1024rdb.dts
new file mode 100644
index 0000000..1a89f9c
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1024rdb.dts
@@ -0,0 +1,87 @@
+/*
+ * P1024 RDB 32Bit Physical Address Map Device Tree Source
+ *
+ * Copyright 2011 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/p1024si-pre.dtsi"
+/ {
+	model = "fsl,P1024RDB";
+	compatible = "fsl,P1024RDB";
+
+	memory {
+		device_type = "memory";
+	};
+
+	lbc: localbus@ffe05000 {
+		reg = <0x0 0xffe05000 0 0x1000>;
+		ranges = <0x0 0x0 0x0 0xef000000 0x01000000
+			  0x1 0x0 0x0 0xff800000 0x00040000>;
+	};
+
+	soc: soc@ffe00000 {
+		ranges = <0x0 0x0 0xffe00000 0x100000>;
+	};
+
+	pci0: pcie@ffe09000 {
+		reg = <0x0 0xffe09000 0 0x1000>;
+		ranges = <0x2000000 0x0 0xe0000000 0x0 0xa0000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0x0 0xffc10000 0x0 0x10000>;
+		pcie@0 {
+			ranges = <0x2000000 0x0 0xe0000000
+				  0x2000000 0x0 0xe0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+
+	pci1: pcie@ffe0a000 {
+		reg = <0xf 0xffe0a000 0 0x1000>;
+		ranges = <0x2000000 0x0 0xe0000000 0x0 0x80000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0x0 0xffc00000 0x0 0x10000>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			ranges = <0x2000000 0x0 0xe0000000
+				  0x2000000 0x0 0xe0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+};
+
+/include/ "p1024rdb.dtsi"
+/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1024rdb.dtsi b/arch/powerpc/boot/dts/p1024rdb.dtsi
new file mode 100644
index 0000000..eb3141d
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1024rdb.dtsi
@@ -0,0 +1,228 @@
+/*
+ * P1024 RDB Device Tree Source stub (no addresses or top-level ranges)
+ *
+ * Copyright 2011 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.
+ */
+
+&lbc {
+	nor@0,0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "cfi-flash";
+		reg = <0x0 0x0 0x1000000>;
+		bank-width = <2>;
+		device-width = <1>;
+
+		partition@0 {
+			/* This location must not be altered  */
+			/* 256KB for Vitesse 7385 Switch firmware */
+			reg = <0x0 0x00040000>;
+			label = "NOR Vitesse-7385 Firmware";
+			read-only;
+		};
+
+		partition@40000 {
+			/* 256KB for DTB Image */
+			reg = <0x00040000 0x00040000>;
+			label = "NOR DTB Image";
+		};
+
+		partition@80000 {
+			/* 3.5 MB for Linux Kernel Image */
+			reg = <0x00080000 0x00380000>;
+			label = "NOR Linux Kernel Image";
+		};
+
+		partition@400000 {
+			/* 11MB for JFFS2 based Root file System */
+			reg = <0x00400000 0x00b00000>;
+			label = "NOR JFFS2 Root File System";
+		};
+
+		partition@f00000 {
+			/* This location must not be altered  */
+			/* 512KB for u-boot Bootloader Image */
+			/* 512KB for u-boot Environment Variables */
+			reg = <0x00f00000 0x00100000>;
+			label = "NOR U-Boot Image";
+			read-only;
+		};
+	};
+
+	nand@1,0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "fsl,p1020-fcm-nand",
+				 "fsl,elbc-fcm-nand";
+		reg = <0x1 0x0 0x40000>;
+
+		partition@0 {
+			/* This location must not be altered  */
+			/* 1MB for u-boot Bootloader Image */
+			reg = <0x0 0x00100000>;
+			label = "NAND U-Boot Image";
+			read-only;
+		};
+
+		partition@100000 {
+			/* 1MB for DTB Image */
+			reg = <0x00100000 0x00100000>;
+			label = "NAND DTB Image";
+		};
+
+		partition@200000 {
+			/* 4MB for Linux Kernel Image */
+			reg = <0x00200000 0x00400000>;
+			label = "NAND Linux Kernel Image";
+		};
+
+		partition@600000 {
+			/* 4MB for Compressed Root file System Image */
+			reg = <0x00600000 0x00400000>;
+			label = "NAND Compressed RFS Image";
+		};
+
+		partition@a00000 {
+			/* 15MB for JFFS2 based Root file System */
+			reg = <0x00a00000 0x00f00000>;
+			label = "NAND JFFS2 Root File System";
+		};
+
+		partition@1900000 {
+			/* 7MB for User Writable Area */
+			reg = <0x01900000 0x00700000>;
+			label = "NAND Writable User area";
+		};
+	};
+};
+
+&soc {
+	spi@7000 {
+		flash@0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "spansion,m25p80";
+			reg = <0>;
+			spi-max-frequency = <40000000>;
+
+			partition@0 {
+				/* 512KB for u-boot Bootloader Image */
+				reg = <0x0 0x00080000>;
+				label = "SPI U-Boot Image";
+				read-only;
+			};
+
+			partition@80000 {
+				/* 512KB for DTB Image */
+				reg = <0x00080000 0x00080000>;
+				label = "SPI DTB Image";
+			};
+
+			partition@100000 {
+				/* 4MB for Linux Kernel Image */
+				reg = <0x00100000 0x00400000>;
+				label = "SPI Linux Kernel Image";
+			};
+
+			partition@500000 {
+				/* 4MB for Compressed RFS Image */
+				reg = <0x00500000 0x00400000>;
+				label = "SPI Compressed RFS Image";
+			};
+
+			partition@900000 {
+				/* 7MB for JFFS2 based RFS */
+				reg = <0x00900000 0x00700000>;
+				label = "SPI JFFS2 RFS";
+			};
+		};
+	};
+
+	i2c@3000 {
+		rtc@68 {
+			compatible = "dallas,ds1339";
+			reg = <0x68>;
+		};
+	};
+
+	usb@22000 {
+		phy_type = "ulpi";
+	};
+
+	usb@23000 {
+		status = "disabled";
+	};
+
+	mdio@24000 {
+		phy0: ethernet-phy@0 {
+			interrupts = <3 1 0 0>;
+			reg = <0x0>;
+		};
+		phy1: ethernet-phy@1 {
+			interrupts = <2 1 0 0>;
+			reg = <0x1>;
+		};
+		phy2: ethernet-phy@2 {
+			interrupts = <1 1 0 0>;
+			reg = <0x2>;
+		};
+	};
+
+	mdio@25000 {
+		tbi0: tbi-phy@11 {
+			reg = <0x11>;
+			device_type = "tbi-phy";
+		};
+	};
+
+	mdio@26000 {
+		tbi1: tbi-phy@11 {
+			reg = <0x11>;
+			device_type = "tbi-phy";
+		};
+	};
+
+	ethernet@b0000 {
+		phy-handle = <&phy2>;
+		phy-connection-type = "rgmii-id";
+	};
+
+	ethernet@b1000 {
+		phy-handle = <&phy0>;
+		tbi-handle = <&tbi0>;
+		phy-connection-type = "sgmii";
+	};
+
+	ethernet@b2000 {
+		phy-handle = <&phy1>;
+		phy-connection-type = "rgmii-id";
+	};
+};
diff --git a/arch/powerpc/boot/dts/p1024rdb_36b.dts b/arch/powerpc/boot/dts/p1024rdb_36b.dts
new file mode 100644
index 0000000..abfa328
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1024rdb_36b.dts
@@ -0,0 +1,87 @@
+/*
+ * P1024 RDB 36Bit Physical Address Map Device Tree Source
+ *
+ * Copyright 2011 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/p1024si-pre.dtsi"
+/ {
+	model = "fsl,P1024RDB";
+	compatible = "fsl,P1024RDB";
+
+	memory {
+		device_type = "memory";
+	};
+
+	lbc: localbus@fffe05000 {
+		reg = <0xf 0xffe05000 0 0x1000>;
+		ranges = <0x0 0x0 0xf 0xef000000 0x01000000
+			  0x1 0x0 0xf 0xff800000 0x00040000>;
+	};
+
+	soc: soc@fffe00000 {
+		ranges = <0x0 0xf 0xffe00000 0x100000>;
+	};
+
+	pci0: pcie@fffe09000 {
+		reg = <0xf 0xffe09000 0 0x1000>;
+		ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
+		pcie@0 {
+			ranges = <0x2000000 0x0 0xe0000000
+				  0x2000000 0x0 0xe0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+
+	pci1: pcie@fffe0a000 {
+		reg = <0xf 0xffe0a000 0 0x1000>;
+		ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			ranges = <0x2000000 0x0 0xe0000000
+				  0x2000000 0x0 0xe0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+};
+
+/include/ "p1024rdb.dtsi"
+/include/ "fsl/p1020si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/p1024rdb_camp_core0.dts b/arch/powerpc/boot/dts/p1024rdb_camp_core0.dts
new file mode 100644
index 0000000..abab1b0
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1024rdb_camp_core0.dts
@@ -0,0 +1,106 @@
+/*
+ * P1024 RDB Core0 Device Tree Source in CAMP mode.
+ *
+ * Copyright 2011 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.
+ *
+ *
+ * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
+ * can be shared, all the other devices must be assigned to one core only.
+ * This dts file allows core0 to have all the devices except that USB, SDHCI
+ * enet0.
+ *
+ * Please note to add "-b 0" for core0's dts compiling.
+ */
+
+/include/ "p1024rdb.dts"
+
+/ {
+	model = "fsl,P1024RDB";
+	compatible = "fsl,P1024RDB", "fsl,MPC85XXRDB-CAMP";
+
+	aliases {
+		ethernet1 = &enet1;
+		ethernet2 = &enet2;
+		serial0 = &serial0;
+		pci0 = &pci0;
+		pci1 = &pci1;
+	};
+
+	cpus {
+		PowerPC,P1024@1 {
+			status = "disabled";
+		};
+	};
+
+	localbus@ffe05000 {
+		status = "disabled";
+	};
+
+	soc@ffe00000 {
+		serial1: serial@4600 {
+			status = "disabled";
+		};
+
+		mdio@24000 {
+			phy2: ethernet-phy@2 {
+				status = "disabled";
+			};
+		};
+
+		enet0: ethernet@b0000 {
+			status = "disabled";
+		};
+
+		sdhci@2e000 {
+			status = "disabled";
+		};
+
+		usb@22000 {
+			status = "disabled";
+		};
+
+		mpic: pic@40000 {
+			protected-sources = <
+			42 29 30 34	/* serial1, enet0-queue-group0 */
+			17 18 24 45	/* enet0-queue-group1, crypto */
+			1 28 46 72	/* phy2 usb sdhc */
+			>;
+		};
+	};
+
+	pci0: pcie@ffe09000 {
+		status = "disabled";
+	};
+
+	pci1: pcie@ffe0a000 {
+		status = "disabled";
+	};
+};
diff --git a/arch/powerpc/boot/dts/p1024rdb_camp_core1.dts b/arch/powerpc/boot/dts/p1024rdb_camp_core1.dts
new file mode 100644
index 0000000..461af60
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1024rdb_camp_core1.dts
@@ -0,0 +1,161 @@
+/*
+ * P1024 RDB Core1 Device Tree Source in CAMP mode.
+ *
+ * Copyright 2011 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.
+ *
+ *
+ * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
+ * can be shared, all the other devices must be assigned to one core only.
+ * This dts file allows core0 to have USB, SDHCI and enet0.
+ *
+ * Please note to add "-b 1" for core1's dts compiling.
+ */
+
+/include/ "p1024rdb.dts"
+
+/ {
+	model = "fsl,P1024RDB";
+	compatible = "fsl,P1024RDB", "fsl,MPC85XXRDB-CAMP";
+
+	aliases {
+		ethernet0 = &enet0;
+		serial0 = &serial1;
+	};
+
+	cpus {
+		PowerPC,P1024@0 {
+			status = "disabled";
+		};
+	};
+
+	localbus@ffe05000 {
+		status = "disabled";
+	};
+
+	soc@ffe00000 {
+		ecm-law@0 {
+			status = "disabled";
+		};
+
+		ecm@1000 {
+			status = "disabled";
+		};
+
+		memory-controller@2000 {
+			status = "disabled";
+		};
+
+		i2c@3000 {
+			status = "disabled";
+		};
+
+		i2c@3100 {
+			status = "disabled";
+		};
+
+		serial0: serial@4500 {
+			status = "disabled";
+		};
+
+		spi@7000 {
+			status = "disabled";
+		};
+
+		gpio: gpio-controller@f000 {
+			status = "disabled";
+		};
+
+		dma@c300 {
+			status = "disabled";
+		};
+
+		dma@21300 {
+			status = "disabled";
+		};
+
+		mdio@24000 {
+			phy0: ethernet-phy@0 {
+				status = "disabled";
+			};
+			phy1: ethernet-phy@1 {
+				status = "disabled";
+			};
+		};
+
+		mdio@25000 {
+			status = "disabled";
+		};
+
+		enet1: ethernet@b1000 {
+			status = "disabled";
+		};
+
+		enet2: ethernet@b2000 {
+			status = "disabled";
+		};
+
+		mpic: pic@40000 {
+			protected-sources = <
+			16 		/* ecm, mem, L2, pci0, pci1 */
+			43 42 59	/* i2c, serial0, spi */
+			47 63 62 	/* gpio, tdm */
+			20 21 22 23	/* dma */
+			03 02 58	/* mdio crypto */
+			35 36 40	/* enet1-queue-group0 */
+			51 52 67	/* enet1-queue-group1 */
+			31 32 33	/* enet2-queue-group0 */
+			25 26 27	/* enet2-queue-group1 */
+			0xb0 0xb1 0xb2	/* message */
+			0xb3 0xb4 0xb5
+			0xb6 0xb7
+			0xe0 0xe1 0xe2	/* msi */
+			0xe3 0xe4 0xe5
+			0xe6 0xe7
+			>;
+		};
+
+		msi@41600 {
+			status = "disabled";
+		};
+
+		global-utilities@e0000 {	//global utilities block
+			status = "disabled";
+		};
+	};
+
+	pci0: pcie@ffe09000 {
+		status = "disabled";
+	};
+
+	pci1: pcie@ffe0a000 {
+		status = "disabled";
+	};
+};
-- 
1.6.4

^ permalink raw reply related

* [PATCH 1/2][v2] mtd/nand:Fix wrong address read in is_blank()
From: Prabhakar Kushwaha @ 2012-01-09 12:24 UTC (permalink / raw)
  To: linuxppc-dev, linux-mtd; +Cc: scottwood, Poonam Aggrwal, Prabhakar Kushwaha

IFC NAND Machine calculates ECC on 512byte sector. Same is taken care in
fsl_ifc_run_command() while ECC status verification. Here buffer number is
calculated assuming 512byte sector and same is passed to is_blank.
However in is_blank() buffer address is calculated using mdt->writesize which is
wrong. It should be calculated on basis of ecc sector size.

Also, in fsl_ifc_run_command() bufferpage is calculated on the basis of ecc sector
size instead of hard coded value.

Signed-off-by: Poonam Aggrwal <poonam.aggrwal@freescale.com>
Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com>
---
  git://git.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git (branch next)

 This patch is created on top of IFC driver patch (already floated in mailing
 list). Please find their link:
 http://patchwork.ozlabs.org/patch/133315/
 http://patchwork.ozlabs.org/patch/133316/

 Tested on P1010RDB

 Changes for v2: Incorporated Scott's comments
 	- Updated copyright
	- is_blank - works on ecc buffer block 
	- check_read_ecc() - Calculate actual ecc buffer number

 drivers/mtd/nand/fsl_ifc_nand.c |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 8475b88..c0529ea 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -1,7 +1,7 @@
 /*
  * Freescale Integrated Flash Controller NAND driver
  *
- * Copyright 2011 Freescale Semiconductor, Inc
+ * Copyright 2011,2012 Freescale Semiconductor, Inc
  *
  * Author: Dipen Dudhat <Dipen.Dudhat@freescale.com>
  *
@@ -191,12 +191,12 @@ static int is_blank(struct mtd_info *mtd, unsigned int bufnum)
 {
 	struct nand_chip *chip = mtd->priv;
 	struct fsl_ifc_mtd *priv = chip->priv;
-	u8 __iomem *addr = priv->vbase + bufnum * (mtd->writesize * 2);
+	u8 __iomem *addr = priv->vbase + bufnum * chip->ecc.size;
 	u32 __iomem *mainarea = (u32 *)addr;
 	u8 __iomem *oob = addr + mtd->writesize;
 	int i;
 
-	for (i = 0; i < mtd->writesize / 4; i++) {
+	for (i = 0; i < chip->ecc.size / 4; i++) {
 		if (__raw_readl(&mainarea[i]) != 0xffffffff)
 			return 0;
 	}
@@ -215,12 +215,15 @@ static int is_blank(struct mtd_info *mtd, unsigned int bufnum)
 static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl,
 			  u32 *eccstat, unsigned int bufnum)
 {
+	struct nand_chip *chip = mtd->priv;
+	int bufperpage = mtd->writesize / chip->ecc.size;
+	int eccbuf_num = bufnum + (bufnum / bufperpage) * bufperpage;
 	u32 reg = eccstat[bufnum / 4];
 	int errors = (reg >> ((3 - bufnum % 4) * 8)) & 15;
 
 	if (errors == 15) { /* uncorrectable */
 		/* Blank pages fail hw ECC checks */
-		if (is_blank(mtd, bufnum))
+		if (is_blank(mtd, eccbuf_num))
 			return 1;
 
 		/*
@@ -273,7 +276,7 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
 		dev_err(priv->dev, "NAND Flash Write Protect Error\n");
 
 	if (nctrl->eccread) {
-		int bufperpage = mtd->writesize / 512;
+		int bufperpage = mtd->writesize / chip->ecc.size;
 		int bufnum = (nctrl->page & priv->bufnum_mask) * bufperpage;
 		int bufnum_end = bufnum + bufperpage - 1;
 
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 2/2][v2] mtd/nand: Fix IFC driver to support 2K NAND page
From: Prabhakar Kushwaha @ 2012-01-09 12:24 UTC (permalink / raw)
  To: linuxppc-dev, linux-mtd; +Cc: scottwood, Poonam Aggrwal, Prabhakar Kushwaha

1) OOB area should be updated irrespective of NAND page size. Earlier it was
updated only for 512byte NAND page.

2) During OOB update fbcr should be equal to OOB size.

Signed-off-by: Poonam Aggrwal <poonam.aggrwal@freescale.com>
Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com>
---
 git://git.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git (branch next)

 This patch is created on top of IFC driver patch (already floated in mailing
 list). Please find their link:
 http://patchwork.ozlabs.org/patch/133315/
 http://patchwork.ozlabs.org/patch/133316/

 Tested on P1010RDB

  Changes for v2: Incorporated Scott's comments
 	- Added missed NAND_CMD_READOOB
	- Updated function as per Scott's advice

 drivers/mtd/nand/fsl_ifc_nand.c |   21 +++++++++------------
 1 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index c0529ea..52bd706d 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -440,22 +440,19 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 			out_be32(&ifc->ifc_nand.nand_fir1,
 				 (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT));
 
-			if (column >= mtd->writesize) {
-				/* OOB area --> READOOB */
-				column -= mtd->writesize;
-				nand_fcr0 |= NAND_CMD_READOOB <<
-						IFC_NAND_FCR0_CMD0_SHIFT;
-				ifc_nand_ctrl->oob = 1;
-			} else if (column < 256)
-				/* First 256 bytes --> READ0 */
+			if (column >= mtd->writesize)
 				nand_fcr0 |=
-				NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT;
+				NAND_CMD_READOOB << IFC_NAND_FCR0_CMD0_SHIFT;
 			else
-				/* Second 256 bytes --> READ1 */
 				nand_fcr0 |=
-				NAND_CMD_READ1 << IFC_NAND_FCR0_CMD0_SHIFT;
+				NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT;
 		}
 
+		if (column >= mtd->writesize) {
+			/* OOB area --> READOOB */
+			column -= mtd->writesize;
+			ifc_nand_ctrl->oob = 1;
+		}
 		out_be32(&ifc->ifc_nand.nand_fcr0, nand_fcr0);
 		set_addr(mtd, column, page_addr, ifc_nand_ctrl->oob);
 		return;
@@ -466,7 +463,7 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 		int full_page;
 		if (ifc_nand_ctrl->oob) {
 			out_be32(&ifc->ifc_nand.nand_fbcr,
-					ifc_nand_ctrl->index);
+				ifc_nand_ctrl->index - ifc_nand_ctrl->column);
 			full_page = 0;
 		} else {
 			out_be32(&ifc->ifc_nand.nand_fbcr, 0);
-- 
1.7.5.4

^ permalink raw reply related

* Re: Driver(s) for Synopsys' DesignWare USB OTG
From: Nikolai Zhubr @ 2012-01-09 12:41 UTC (permalink / raw)
  To: Peter Chen; +Cc: support, linux-usb, linuxppc-dev, openwrt-devel, Peter Chen
In-Reply-To: <20120109021220.GA10198@nchen-desktop>

Hello Peter,

09.01.2012 6:12, Peter Chen:
>>> I am not sure we can combine all Synopsys USB drivers to single file, but we
>>
>> Synopsys driver which I examine consists of 16 files (each of 2
>> versions), 200k lines total. I've already perpared some few smaller
>> files for version merging. So probably it is doable, but quite a lot
>> of work, therefore I wouldn't like it to be wasted.
> I mean one file is just a common udc driver for all Synopsys, not all usb file.
> For ehci, I think it will be easier to use single file as well as
> some specific SoC's quirks if needed.
> For udc, as there is no standard spec for how usb device should be designed,
> maybe different Synopsys IPs have a little different for work flow.
> For otg, it  should be not difficult after we split PHY's operation
> from the otg, as common otg operation is the same.
>>
>>> can try combine similar IP versions to one file, this work may need all Synopsys
>>> USB IP driver maintainer work together.
>>
>> Exactly. This is why I'm now trying to find all relevant people to
>> begin with.
> I know someone(@Pengutronix and @linux.intel.com) is doing that. I think first
> we should find which driver file at current code base is most capable and
> compatible. I would like to help it, and verify it at Freescale i.MX SoCs.

Ok. Because my resources are limited (and my knowledge is actually 
limited too) I'll list what exactly I'm able (and willing) to do:

- split formatting/naming/uninteresting changes from algorythmical 
changes, prepare clean diffs as necessary (boring work, but anyway);
- bisect changes which make the driver stop working on my tablet;
- try whichever driver parameters and see what happens to my tablet;
- connect the tablet to a regular linux PC with USB cable, do some 
tests, capture traffic dumps as necessary;
- connect some devices to the tablet, do tests, report results;

and with some luck:
- prepare bufixes (depending very much on how simple is the bug).

So basically my effort would probably only be usefull in cooperation 
with someone with more knowledge and understanding of the situation in 
whole. Otherwise it would be more wasting of time.

If usb issues were solved, it might make some sense to try to create 
e.g. a generic openwrt target for 8726m-based tablet. (Of course it 
wouldn't allow to use the device for its intended purpose yet, but still 
might be interesting as kind of devel/testing reference option)


Thank you.
Nikolai.


>>
>> Thank you.
>> Nikolai.
>>
>> Please CC me, I'm not subscribed to the lists.
>>
>>
>>>
>>>
>>>> Thank you.
>>>> Nikolai.
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>>
>>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>

^ permalink raw reply

* Re: Driver(s) for Synopsys' DesignWare USB OTG
From: Nikolai Zhubr @ 2012-01-09 12:44 UTC (permalink / raw)
  To: Leo Li; +Cc: support, linux-usb, linuxppc-dev, openwrt-devel, Peter Chen
In-Reply-To: <CADRPPNRLKhDEU=mVDjbxaNtOD+665hQodhQzpVBc11120GpuJQ@mail.gmail.com>

Hello Leo,

09.01.2012 9:17, Leo Li:
> On Sun, Jan 8, 2012 at 8:56 PM, Nikolai Zhubr<n-a-zhubr@yandex.ru>  wrote:
>>> 2012/1/8 Nikolai Zhubr<n-a-zhubr@yandex.ru>:
>>>>
>>>> Hello developers,
>>>>
>>>> I'm trying to find/combine/fix a driver for Synopsys' DesignWare USB
>>>> controller. This thing is USB 2.0 host/slave/otg capable and is used in
>>>> various SoCs including Amlogic 8726M, Ralink RT305x, and probably more.
>>>>
[...trim...]
>
> I think the challenge of cooperation in situation like this is that
> most companies don't like to advertise the source of the licensed IP
> block.  Even the owner of the IP block doesn't list all users of the
> block(maybe business requirement). It was really hard to find out if
> the same IP has been used by anyone else.  Also the owner of this USB
> IP block has been changed for several times(ARC, TDI, ChipIdea, and
> Synopsys) which made it even more difficult to tell.

Ah, I see. It explains.
But communicating in private and keeping some public repository up to 
date would still be allowed I suppose?

>
>>
>>
>>> I am not sure we can combine all Synopsys USB drivers to single file, but
>>> we
>>
>>
>> Synopsys driver which I examine consists of 16 files (each of 2 versions),
>> 200k lines total. I've already perpared some few smaller files for version
>> merging. So probably it is doable, but quite a lot of work, therefore I
>> wouldn't like it to be wasted.
>
> I didn't examine the Synopsys driver myself.  But if it is so complex
> as you described, it might be better to start with the in-tree drivers
> IMO.

Unfortunately its far beyond my capabilities at the moment. Besides, it 
looks like huge effort has already been invested into the existing 
driver, so to me it seems fixing it rather than starting from scratch 
would be more realistic anyway (unless a company with unlimited 
resources step in...)


Thank you.
Nikolai.

>
> - Leo
>
>

^ permalink raw reply

* Re: [PATCH 1/3] KVM: PPC: epapr: Factor out the epapr init
From: Alexander Graf @ 2012-01-09 13:50 UTC (permalink / raw)
  To: Liu Yu; +Cc: kvm, kvm-ppc, linuxppc-dev, scottwood, timur
In-Reply-To: <1325754412-29963-1-git-send-email-yu.liu@freescale.com>


On 05.01.2012, at 10:06, Liu Yu wrote:

> from the kvm guest paravirt init code.

Your patch description could be slightly more ... verbose :)

>=20
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> ---
> arch/powerpc/include/asm/epapr_hcalls.h |    8 +++++
> arch/powerpc/kernel/Makefile            |    1 +
> arch/powerpc/kernel/epapr_para.c        |   45 =
+++++++++++++++++++++++++++++++
> arch/powerpc/kernel/kvm.c               |    9 +++++-
> 4 files changed, 62 insertions(+), 1 deletions(-)
> create mode 100644 arch/powerpc/kernel/epapr_para.c
>=20
> diff --git a/arch/powerpc/include/asm/epapr_hcalls.h =
b/arch/powerpc/include/asm/epapr_hcalls.h
> index f3b0c2c..c4b86e4 100644
> --- a/arch/powerpc/include/asm/epapr_hcalls.h
> +++ b/arch/powerpc/include/asm/epapr_hcalls.h
> @@ -148,6 +148,14 @@
> #define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5"
> #define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4"
>=20
> +extern u32 *epapr_hcall_insts;
> +extern int epapr_hcall_insts_len;
> +
> +static inline void epapr_get_hcall_insts(u32 **instp, int *lenp)
> +{
> +	*instp =3D epapr_hcall_insts;
> +	*lenp =3D epapr_hcall_insts_len;

Why do we need this? Can't we just directly access the variables?

> +}
>=20
> /*
>  * We use "uintptr_t" to define a register because it's guaranteed to =
be a
> diff --git a/arch/powerpc/kernel/Makefile =
b/arch/powerpc/kernel/Makefile
> index ce4f7f1..1052bbc 100644
> --- a/arch/powerpc/kernel/Makefile
> +++ b/arch/powerpc/kernel/Makefile
> @@ -134,6 +134,7 @@ ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC),)
> obj-y				+=3D ppc_save_regs.o
> endif
>=20
> +obj-$(CONFIG_BOOKE)		+=3D epapr_para.o
> obj-$(CONFIG_KVM_GUEST)		+=3D kvm.o kvm_emul.o
>=20
> # Disable GCOV in odd or sensitive code
> diff --git a/arch/powerpc/kernel/epapr_para.c =
b/arch/powerpc/kernel/epapr_para.c
> new file mode 100644
> index 0000000..714dcb3
> --- /dev/null
> +++ b/arch/powerpc/kernel/epapr_para.c
> @@ -0,0 +1,45 @@
> +/*
> + * ePAPR para-virtualization support.
> + *
> + * This program is free software; you can redistribute it and/or =
modify
> + * it under the terms of the GNU General Public License, version 2, =
as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  =
02110-1301, USA.
> + *
> + * Copyright (C) 2012 Freescale Semiconductor, Inc.
> + */
> +
> +#include <linux/of.h>
> +#include <asm/epapr_hcalls.h>
> +
> +u32 *epapr_hcall_insts;
> +int epapr_hcall_insts_len;
> +
> +static int __init epapr_para_init(void)
> +{
> +	struct device_node *hyper_node;
> +	u32 *insts;
> +	int len;
> +
> +	hyper_node =3D of_find_node_by_path("/hypervisor");
> +	if (!hyper_node)
> +		return -ENODEV;
> +
> +	insts =3D (u32*)of_get_property(hyper_node, =
"hcall-instructions", &len);
> +	if (!(len % 4) && (len >=3D (4 * 4))) {
> +		epapr_hcall_insts =3D insts;
> +		epapr_hcall_insts_len =3D len;
> +	}

else error()?

> +
> +	return 0;
> +}
> +
> +early_initcall(epapr_para_init);
> diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
> index b06bdae..82a9137 100644
> --- a/arch/powerpc/kernel/kvm.c
> +++ b/arch/powerpc/kernel/kvm.c
> @@ -28,6 +28,7 @@
> #include <asm/sections.h>
> #include <asm/cacheflush.h>
> #include <asm/disassemble.h>
> +#include <asm/epapr_hcalls.h>
>=20
> #define KVM_MAGIC_PAGE		(-4096L)
> #define magic_var(x) KVM_MAGIC_PAGE + offsetof(struct =
kvm_vcpu_arch_shared, x)
> @@ -535,9 +536,10 @@ EXPORT_SYMBOL_GPL(kvm_hypercall);
> static int kvm_para_setup(void)
> {
> 	extern u32 kvm_hypercall_start;
> -	struct device_node *hyper_node;
> 	u32 *insts;
> 	int len, i;
> +#ifndef CONFIG_BOOKE

Ugh - now you're duplicating even more code. Why not completely unify it =
and always call epapr_get_hcall_insts() on all ppc platforms?


> +	struct device_node *hyper_node;
>=20
> 	hyper_node =3D of_find_node_by_path("/hypervisor");
> 	if (!hyper_node)
> @@ -548,6 +550,11 @@ static int kvm_para_setup(void)
> 		return -1;
> 	if (len > (4 * 4))
> 		return -1;
> +#else
> +	epapr_get_hcall_insts(&insts, &len);
> +	if (insts =3D=3D NULL)
> +		return -1;
> +#endif	/* !BOOKE */
>=20
> 	for (i =3D 0; i < (len / 4); i++)
> 		kvm_patch_ins(&(&kvm_hypercall_start)[i], insts[i]);
> --=20
> 1.6.4
>=20
>=20
> --
> To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Mac address in the DT
From: smitha.vanga @ 2012-01-09 13:54 UTC (permalink / raw)
  To: wd; +Cc: scottwood, linuxppc-dev
In-Reply-To: <20111230182806.21CF61931810@gemini.denx.de>

 
Hi Wolfgang,

I need to automate a sequence of commands. To do that I am setting a environ=
ment variable with the sequence of commands.
And using run command run the environment variable.

But one of the command uses " in the command. So how do I save the command w=
ith quotes.

Below is the command which I want to set in the environment variable.

setenv set_mac ""cp 0xffec0000 0x100000 1024;fdt addr 0x100000 8192;fdt set=
 /soc8272@f0000000/ethernet@24000 mac-address "[00 22 00 33 00 55]""

But when I saveenv the command doesnot get save as fdt set /soc8272@f0000000=
/ethernet@24000 mac-address "[00 22 00 33 00 55]"

Thanks & Regards,
Smitha


Please do not print this email unless it is absolutely necessary. =0A=
=0A=
The information contained in this electronic message and any attachments to=
 this message are intended for the exclusive use of the addressee(s) and may=
 contain proprietary, confidential or privileged information. If you are not=
 the intended recipient, you should not disseminate, distribute or copy this=
 e-mail. Please notify the sender immediately and destroy all copies of this=
 message and any attachments. =0A=
=0A=
WARNING: Computer viruses can be transmitted via email. The recipient should=
 check this email and any attachments for the presence of viruses. The compa=
ny accepts no liability for any damage caused by any virus transmitted by th=
is email. =0A=
=0A=
www.wipro.com

^ permalink raw reply

* Re: [PATCH v2 3/3] KVM: PPC: epapr: install ev_idle hcall for e500 guest
From: Alexander Graf @ 2012-01-09 14:05 UTC (permalink / raw)
  To: Liu Yu; +Cc: kvm, kvm-ppc, linuxppc-dev, scottwood, timur
In-Reply-To: <1325754412-29963-2-git-send-email-yu.liu@freescale.com>


On 05.01.2012, at 10:06, Liu Yu wrote:

> If the guest hypervisor node contains "has-idle" property.
>=20
> Signed-off-by: Liu Yu <yu.liu@freescale.com>
> ---
> v2:
> 1. move the idle code into assembly.
> 2. move the part that check "has-idle" into epapr code.
>=20
> arch/powerpc/include/asm/epapr_hcalls.h |    1 +
> arch/powerpc/include/asm/machdep.h      |    5 +++++
> arch/powerpc/kernel/epapr_para.c        |    4 ++++
> arch/powerpc/kernel/idle_e500.S         |   17 +++++++++++++++++
> arch/powerpc/kernel/kvm.c               |   24 =
++++++++++++++++++++++++
> 5 files changed, 51 insertions(+), 0 deletions(-)
>=20
> diff --git a/arch/powerpc/include/asm/epapr_hcalls.h =
b/arch/powerpc/include/asm/epapr_hcalls.h
> index c4b86e4..566805e 100644
> --- a/arch/powerpc/include/asm/epapr_hcalls.h
> +++ b/arch/powerpc/include/asm/epapr_hcalls.h
> @@ -150,6 +150,7 @@
>=20
> extern u32 *epapr_hcall_insts;
> extern int epapr_hcall_insts_len;
> +extern bool epapr_hcall_has_idle;
>=20
> static inline void epapr_get_hcall_insts(u32 **instp, int *lenp)
> {
> diff --git a/arch/powerpc/include/asm/machdep.h =
b/arch/powerpc/include/asm/machdep.h
> index 47cacdd..7e56abf 100644
> --- a/arch/powerpc/include/asm/machdep.h
> +++ b/arch/powerpc/include/asm/machdep.h
> @@ -255,6 +255,11 @@ extern void power4_idle(void);
> extern void power7_idle(void);
> extern void ppc6xx_idle(void);
> extern void book3e_idle(void);
> +#ifdef CONFIG_KVM_GUEST
> +extern void e500_ev_idle(unsigned long *, unsigned long *, unsigned =
long,
> +                         unsigned long (*)(unsigned long *, unsigned =
long *,
> +                                          unsigned long));
> +#endif
>=20
> /*
>  * ppc_md contains a copy of the machine description structure for the
> diff --git a/arch/powerpc/kernel/epapr_para.c =
b/arch/powerpc/kernel/epapr_para.c
> index 714dcb3..1f37ddf 100644
> --- a/arch/powerpc/kernel/epapr_para.c
> +++ b/arch/powerpc/kernel/epapr_para.c
> @@ -22,6 +22,7 @@
>=20
> u32 *epapr_hcall_insts;
> int epapr_hcall_insts_len;
> +bool epapr_hcall_has_idle;
>=20
> static int __init epapr_para_init(void)
> {
> @@ -39,6 +40,9 @@ static int __init epapr_para_init(void)
> 		epapr_hcall_insts_len =3D len;
> 	}
>=20
> +	if (of_get_property(hyper_node, "has-idle", NULL))
> +		epapr_hcall_has_idle =3D true;
> +
> 	return 0;
> }
>=20
> diff --git a/arch/powerpc/kernel/idle_e500.S =
b/arch/powerpc/kernel/idle_e500.S
> index 3e2b95c..6ea95f0 100644
> --- a/arch/powerpc/kernel/idle_e500.S
> +++ b/arch/powerpc/kernel/idle_e500.S
> @@ -85,6 +85,23 @@ =
END_FTR_SECTION_IFSET(CPU_FTR_L2CSR|CPU_FTR_CAN_NAP)
> 2:	b	2b
> #endif /* !E500MC */
>=20
> +#ifdef CONFIG_KVM_GUEST
> +/*
> + * r3 contains the pointer to in[8]
> + * r4 contains the pointer to out[8]
> + * r5 contains the hcall vendor and nr
> + * r6 contains the handler which send hcall
> + */
> +_GLOBAL(e500_ev_idle)

How is that specific to e500? Isn't it just the generic epapr =
implementation?

> +	rlwinm	r7,r1,0,0,31-THREAD_SHIFT	/* current thread_info =
*/
> +	lwz	r8,TI_LOCAL_FLAGS(r7)	/* set napping bit */
> +	ori	r8,r8,_TLF_NAPPING	/* so when we take an exception =
*/
> +	stw	r8,TI_LOCAL_FLAGS(r7)	/* it will return to our caller =
*/
> +	wrteei	1

Except for this part of course :). But I'm sure we can generalize this.

> +	mtctr	r6
> +	bctr
> +#endif /* KVM_GUEST */
> +
> /*
>  * Return from NAP/DOZE mode, restore some CPU specific registers,
>  * r2 containing physical address of current.
> diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
> index 82a9137..8952e12 100644
> --- a/arch/powerpc/kernel/kvm.c
> +++ b/arch/powerpc/kernel/kvm.c
> @@ -29,6 +29,7 @@
> #include <asm/cacheflush.h>
> #include <asm/disassemble.h>
> #include <asm/epapr_hcalls.h>
> +#include <asm/machdep.h>
>=20
> #define KVM_MAGIC_PAGE		(-4096L)
> #define magic_var(x) KVM_MAGIC_PAGE + offsetof(struct =
kvm_vcpu_arch_shared, x)
> @@ -578,6 +579,25 @@ static __init void kvm_free_tmp(void)
> 	}
> }
>=20
> +static void kvm_hcall_idle(void)
> +{
> +#ifdef CONFIG_KVM_E500
> +	ulong in[8];
> +	ulong out[8];
> +
> +	e500_ev_idle(in, out, HC_VENDOR_EPAPR | HC_EV_IDLE, =
kvm_hypercall);
> +#endif

... because then the ifdef goes away here too

> +}
> +
> +static bool kvm_para_has_idle(void)
> +{
> +#ifdef CONFIG_BOOKE
> +	return epapr_hcall_has_idle;
> +#else
> +	return false;
> +#endif

... this also shouldn't be an ifdef

> +}
> +
> static int __init kvm_guest_init(void)
> {
> 	if (!kvm_para_available())
> @@ -594,6 +614,10 @@ static int __init kvm_guest_init(void)
> 	powersave_nap =3D 1;
> #endif
>=20
> +	/* Install hcall based power_save for guest kernel */
> +	if (kvm_para_has_idle())
> +		ppc_md.power_save =3D kvm_hcall_idle;

The way it's now it would break kernels with this patch if we ever =
choose to implement hcall_idle for non-e500. Please make the code =
generic :)


Alex

^ permalink raw reply

* Re: Mac address in the DT
From: Joakim Tjernlund @ 2012-01-09 14:20 UTC (permalink / raw)
  To: smitha.vanga; +Cc: scottwood, linuxppc-dev, wd
In-Reply-To: <40631E9A2581F14BA60888C87A76A1FE01D34F@HYD-MKD-MBX4.wipro.com>

>
> Hi Wolfgang,
>
> I need to automate a sequence of commands. To do that I am setting a environment variable with the sequence of commands.
> And using run command run the environment variable.
>
> But one of the command uses " in the command. So how do I save the command with quotes.
>
> Below is the command which I want to set in the environment variable.
>
> setenv set_mac ""cp 0xffec0000 0x100000 1024;fdt addr 0x100000 8192;fdt set /soc8272@f0000000/ethernet@24000 mac-address "[00 22 00 33 00 55]""
>
> But when I saveenv the command doesnot get save as fdt set /soc8272@f0000000/ethernet@24000 mac-address "[00 22 00 33 00 55]"
>
> Thanks & Regards,
> Smitha

Have you tried ...\"[00 22 00 33 00 55]\"" ?

 Jocke

^ permalink raw reply

* RE: Mac address in the DT
From: smitha.vanga @ 2012-01-09 14:28 UTC (permalink / raw)
  To: joakim.tjernlund; +Cc: scottwood, linuxppc-dev, wd
In-Reply-To: <OF5FE90C20.B5971F88-ONC1257980.004EAA90-C1257980.004EC4DA@transmode.se>

 
Hi Joakim,

I have tried it but it doesn't work.

Just now found that with single ' quotes the entire sequence it works.
>Setenv set_mac 'cp 0xffec0000 0x100000 1024;fdt addr 0xc00000 8192;fdt set=
 /soc8272@f0000000/ethernet@24000 mac-address "[00 44 00 55 00 66]";erase 0x=
ffec0000 0xffec4000;cp 0xc00000 0xffec0000 1024;bootm 0xfe060000 - 0xffec000=
0'

> run set_mac

For the above command I want to replace the mac address with the ethaddr> Ho=
w do I do that. I tried $ethaddr but I get extra : characters.

>Setenv set_mac 'cp 0xffec0000 0x100000 1024;fdt addr 0xc00000 8192;fdt set=
 /soc8272@f0000000/ethernet@24000 mac-address $ethaddr;erase 0xffec0000 0xff=
ec4000;cp 0xc00000 0xffec0000 1024;bootm 0xfe060000 - 0xffec0000'

Regards,
Smitha
Please do not print this email unless it is absolutely necessary. =0A=
=0A=
The information contained in this electronic message and any attachments to=
 this message are intended for the exclusive use of the addressee(s) and may=
 contain proprietary, confidential or privileged information. If you are not=
 the intended recipient, you should not disseminate, distribute or copy this=
 e-mail. Please notify the sender immediately and destroy all copies of this=
 message and any attachments. =0A=
=0A=
WARNING: Computer viruses can be transmitted via email. The recipient should=
 check this email and any attachments for the presence of viruses. The compa=
ny accepts no liability for any damage caused by any virus transmitted by th=
is email. =0A=
=0A=
www.wipro.com

^ permalink raw reply

* RE: Mac address in the DT
From: Joakim Tjernlund @ 2012-01-09 14:59 UTC (permalink / raw)
  To: smitha.vanga; +Cc: scottwood, linuxppc-dev, wd
In-Reply-To: <40631E9A2581F14BA60888C87A76A1FE01D360@HYD-MKD-MBX4.wipro.com>

<smitha.vanga@wipro.com> wrote on 2012/01/09 15:28:54:
>
>
> Hi Joakim,
>
> I have tried it but it doesn't work.
>
> Just now found that with single ' quotes the entire sequence it works.
> >Setenv set_mac 'cp 0xffec0000 0x100000 1024;fdt addr 0xc00000 8192;fdt set /soc8272@f0000000/ethernet@24000 mac-address "[00 44 00 55 00 66]";erase 0xffec0000 0xffec4000;cp 0xc00000 0xffec0000 1024;bootm 0xfe060000 - 0xffec0000'
>
> > run set_mac
>
> For the above command I want to replace the mac address with the ethaddr> How do I do that. I tried $ethaddr but I get extra : characters.
>
> >Setenv set_mac 'cp 0xffec0000 0x100000 1024;fdt addr 0xc00000 8192;fdt set /soc8272@f0000000/ethernet@24000 mac-address $ethaddr;erase 0xffec0000 0xffec4000;cp 0xc00000 0xffec0000 1024;bootm 0xfe060000 - 0xffec0000'

Of course you do, ethaddr has a different syntax and contains :

Anyway you should not have to set mac address manually like you do, u-boot will do it for you if you
have configured u-boot correctly and have a proper dtb tree. Check the u-boot code and the many dts files in linux
under arch/powerpc/boot/dts

^ permalink raw reply

* Re: [RFC PATCH 01/16] powerpc/booke: Set CPU_FTR_DEBUG_LVL_EXC on 32-bit
From: Alexander Graf @ 2012-01-09 15:21 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <20111221013412.GA8378@schlenkerla.am.freescale.net>


On 21.12.2011, at 02:34, Scott Wood wrote:

> Currently 32-bit only cares about this for choice of exception
> vector, which is done in core-specific code.  However, KVM will
> want to distinguish as well.
>=20
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> arch/powerpc/include/asm/cputable.h |    5 +++--
> 1 files changed, 3 insertions(+), 2 deletions(-)
>=20
> diff --git a/arch/powerpc/include/asm/cputable.h =
b/arch/powerpc/include/asm/cputable.h
> index e30442c..033ad30 100644
> --- a/arch/powerpc/include/asm/cputable.h
> +++ b/arch/powerpc/include/asm/cputable.h
> @@ -375,7 +375,8 @@ extern const char *powerpc_base_platform;
> #define CPU_FTRS_47X	(CPU_FTRS_440x6)
> #define CPU_FTRS_E200	(CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \
> 	    CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \
> -	    CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE)
> +	    CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE | \
> +	    CPU_FTR_DEBUG_LVL_EXC)

KVM on E200?


Alex

^ permalink raw reply

* Re: [RFC PATCH 04/16] KVM: PPC: factor out lpid allocator from book3s_64_mmu_hv
From: Alexander Graf @ 2012-01-09 15:35 UTC (permalink / raw)
  To: Scott Wood; +Cc: Paul Mackerras, linuxppc-dev, KVM mailing list, kvm-ppc
In-Reply-To: <20111221013420.GD8378@schlenkerla.am.freescale.net>


On 21.12.2011, at 02:34, Scott Wood wrote:

> We'll use it on e500mc as well.
>=20
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> arch/powerpc/include/asm/kvm_book3s.h |    3 ++
> arch/powerpc/include/asm/kvm_booke.h  |    3 ++
> arch/powerpc/include/asm/kvm_ppc.h    |    5 ++++
> arch/powerpc/kvm/book3s_64_mmu_hv.c   |   26 +++++++++---------------
> arch/powerpc/kvm/powerpc.c            |   34 =
+++++++++++++++++++++++++++++++++
> 5 files changed, 55 insertions(+), 16 deletions(-)
>=20
> diff --git a/arch/powerpc/include/asm/kvm_book3s.h =
b/arch/powerpc/include/asm/kvm_book3s.h
> index 60e069e..58c8bec 100644
> --- a/arch/powerpc/include/asm/kvm_book3s.h
> +++ b/arch/powerpc/include/asm/kvm_book3s.h
> @@ -448,4 +448,7 @@ static inline bool kvmppc_critical_section(struct =
kvm_vcpu *vcpu)
>=20
> #define INS_DCBZ			0x7c0007ec
>=20
> +/* LPIDs we support with this build -- runtime limit may be lower */
> +#define KVMPPC_NR_LPIDS			(LPID_RSVD + 1)
> +
> #endif /* __ASM_KVM_BOOK3S_H__ */
> diff --git a/arch/powerpc/include/asm/kvm_booke.h =
b/arch/powerpc/include/asm/kvm_booke.h
> index e20c162..138118e 100644
> --- a/arch/powerpc/include/asm/kvm_booke.h
> +++ b/arch/powerpc/include/asm/kvm_booke.h
> @@ -23,6 +23,9 @@
> #include <linux/types.h>
> #include <linux/kvm_host.h>
>=20
> +/* LPIDs we support with this build -- runtime limit may be lower */
> +#define KVMPPC_NR_LPIDS                        64
> +
> static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, =
ulong val)
> {
> 	vcpu->arch.regs.gpr[num] =3D val;
> diff --git a/arch/powerpc/include/asm/kvm_ppc.h =
b/arch/powerpc/include/asm/kvm_ppc.h
> index a61b5b5..5524f88 100644
> --- a/arch/powerpc/include/asm/kvm_ppc.h
> +++ b/arch/powerpc/include/asm/kvm_ppc.h
> @@ -202,4 +202,9 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu =
*vcpu,
> int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu,
> 			     struct kvm_dirty_tlb *cfg);
>=20
> +long kvmppc_alloc_lpid(void);
> +void kvmppc_claim_lpid(long lpid);
> +void kvmppc_free_lpid(long lpid);
> +void kvmppc_init_lpid(unsigned long nr_lpids);
> +
> #endif /* __POWERPC_KVM_PPC_H__ */
> diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c =
b/arch/powerpc/kvm/book3s_64_mmu_hv.c
> index 66d6452..45b6f0e 100644
> --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
> @@ -36,13 +36,11 @@
>=20
> /* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */
> #define MAX_LPID_970	63
> -#define NR_LPIDS	(LPID_RSVD + 1)
> -unsigned long lpid_inuse[BITS_TO_LONGS(NR_LPIDS)];
>=20
> long kvmppc_alloc_hpt(struct kvm *kvm)
> {
> 	unsigned long hpt;
> -	unsigned long lpid;
> +	long lpid;
> 	struct revmap_entry *rev;
>=20
> 	/* Allocate guest's hashed page table */
> @@ -62,14 +60,9 @@ long kvmppc_alloc_hpt(struct kvm *kvm)
> 	}
> 	kvm->arch.revmap =3D rev;
>=20
> -	/* Allocate the guest's logical partition ID */
> -	do {
> -		lpid =3D find_first_zero_bit(lpid_inuse, NR_LPIDS);
> -		if (lpid >=3D NR_LPIDS) {
> -			pr_err("kvm_alloc_hpt: No LPIDs free\n");
> -			goto out_freeboth;
> -		}
> -	} while (test_and_set_bit(lpid, lpid_inuse));
> +	lpid =3D kvmppc_alloc_lpid();
> +	if (lpid < 0)
> +		goto out_freeboth;
>=20
> 	kvm->arch.sdr1 =3D __pa(hpt) | (HPT_ORDER - 18);
> 	kvm->arch.lpid =3D lpid;
> @@ -86,7 +79,7 @@ long kvmppc_alloc_hpt(struct kvm *kvm)
>=20
> void kvmppc_free_hpt(struct kvm *kvm)
> {
> -	clear_bit(kvm->arch.lpid, lpid_inuse);
> +	kvmppc_free_lpid(kvm->arch.lpid);
> 	vfree(kvm->arch.revmap);
> 	free_pages(kvm->arch.hpt_virt, HPT_ORDER - PAGE_SHIFT);
> }
> @@ -158,8 +151,7 @@ int kvmppc_mmu_hv_init(void)
> 	if (!cpu_has_feature(CPU_FTR_HVMODE))
> 		return -EINVAL;
>=20
> -	memset(lpid_inuse, 0, sizeof(lpid_inuse));
> -
> +	/* POWER7 has 10-bit LPIDs, PPC970 and e500mc have 6-bit LPIDs =
*/
> 	if (cpu_has_feature(CPU_FTR_ARCH_206)) {
> 		host_lpid =3D mfspr(SPRN_LPID);	/* POWER7 */
> 		rsvd_lpid =3D LPID_RSVD;
> @@ -168,9 +160,11 @@ int kvmppc_mmu_hv_init(void)
> 		rsvd_lpid =3D MAX_LPID_970;
> 	}
>=20
> -	set_bit(host_lpid, lpid_inuse);
> +	kvmppc_init_lpid(rsvd_lpid + 1);
> +
> +	kvmppc_claim_lpid(host_lpid);
> 	/* rsvd_lpid is reserved for use in partition switching */
> -	set_bit(rsvd_lpid, lpid_inuse);
> +	kvmppc_claim_lpid(rsvd_lpid);
>=20
> 	return 0;
> }
> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> index 64c738dc..42701e5 100644
> --- a/arch/powerpc/kvm/powerpc.c
> +++ b/arch/powerpc/kvm/powerpc.c

Paul, does this work for you? IIRC you need this code to be available =
from real mode, which powerpc.c isn't in, right?


Alex

> @@ -800,6 +800,40 @@ out:
> 	return r;
> }
>=20
> +static unsigned long lpid_inuse[BITS_TO_LONGS(KVMPPC_NR_LPIDS)];
> +static unsigned long nr_lpids;
> +
> +long kvmppc_alloc_lpid(void)
> +{
> +	long lpid;
> +
> +	do {
> +		lpid =3D find_first_zero_bit(lpid_inuse, =
KVMPPC_NR_LPIDS);
> +		if (lpid >=3D nr_lpids) {
> +			pr_err("%s: No LPIDs free\n", __func__);
> +			return -ENOMEM;
> +		}
> +	} while (test_and_set_bit(lpid, lpid_inuse));
> +
> +	return lpid;
> +}
> +
> +void kvmppc_claim_lpid(long lpid)
> +{
> +	set_bit(lpid, lpid_inuse);
> +}
> +
> +void kvmppc_free_lpid(long lpid)
> +{
> +	clear_bit(lpid, lpid_inuse);
> +}
> +
> +void kvmppc_init_lpid(unsigned long nr_lpids_param)
> +{
> +	nr_lpids =3D min_t(unsigned long, KVMPPC_NR_LPIDS, =
nr_lpids_param);
> +	memset(lpid_inuse, 0, sizeof(lpid_inuse));
> +}
> +
> int kvm_arch_init(void *opaque)
> {
> 	return 0;
> --=20
> 1.7.7.rc3.4.g8d714
>=20
>=20

^ permalink raw reply

* Re: [RFC PATCH 12/16] KVM: PPC: e500: emulate tlbilx
From: Alexander Graf @ 2012-01-09 16:23 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <20111221013438.GL8378@schlenkerla.am.freescale.net>


On 21.12.2011, at 02:34, Scott Wood wrote:

> tlbilx is the new, preferred invalidation instruction.  It is not
> found on e500 prior to e500mc, but there should be no harm in
> supporting it on all e500.
>=20
> Based on code from Ashish Kalra <Ashish.Kalra@freescale.com>.
>=20
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> arch/powerpc/kvm/e500.h         |    1 +
> arch/powerpc/kvm/e500_emulate.c |    9 ++++++
> arch/powerpc/kvm/e500_tlb.c     |   52 =
+++++++++++++++++++++++++++++++++++++++
> 3 files changed, 62 insertions(+), 0 deletions(-)
>=20
> diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
> index f4dee55..ce3f163 100644
> --- a/arch/powerpc/kvm/e500.h
> +++ b/arch/powerpc/kvm/e500.h
> @@ -124,6 +124,7 @@ int kvmppc_e500_emul_mt_mmucsr0(struct =
kvmppc_vcpu_e500 *vcpu_e500,
> int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu);
> int kvmppc_e500_emul_tlbre(struct kvm_vcpu *vcpu);
> int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, int ra, int rb);
> +int kvmppc_e500_emul_tlbilx(struct kvm_vcpu *vcpu, int rt, int ra, =
int rb);
> int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, int rb);
> int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500);
> void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500);
> diff --git a/arch/powerpc/kvm/e500_emulate.c =
b/arch/powerpc/kvm/e500_emulate.c
> index c80794d..af02c18 100644
> --- a/arch/powerpc/kvm/e500_emulate.c
> +++ b/arch/powerpc/kvm/e500_emulate.c
> @@ -22,6 +22,7 @@
> #define XOP_TLBSX   914
> #define XOP_TLBRE   946
> #define XOP_TLBWE   978
> +#define XOP_TLBILX  18
>=20
> int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
>                            unsigned int inst, int *advance)
> @@ -29,6 +30,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, =
struct kvm_vcpu *vcpu,
> 	int emulated =3D EMULATE_DONE;
> 	int ra;
> 	int rb;
> +	int rt;
>=20
> 	switch (get_op(inst)) {
> 	case 31:
> @@ -47,6 +49,13 @@ int kvmppc_core_emulate_op(struct kvm_run *run, =
struct kvm_vcpu *vcpu,
> 			emulated =3D kvmppc_e500_emul_tlbsx(vcpu,rb);
> 			break;
>=20
> +		case XOP_TLBILX:
> +			ra =3D get_ra(inst);
> +			rb =3D get_rb(inst);
> +			rt =3D get_rt(inst);
> +			emulated =3D kvmppc_e500_emul_tlbilx(vcpu, rt, =
ra, rb);
> +			break;
> +
> 		case XOP_TLBIVAX:
> 			ra =3D get_ra(inst);
> 			rb =3D get_rb(inst);
> diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
> index 031fd5b..121cd68 100644
> --- a/arch/powerpc/kvm/e500_tlb.c
> +++ b/arch/powerpc/kvm/e500_tlb.c
> @@ -631,6 +631,58 @@ int kvmppc_e500_emul_tlbivax(struct kvm_vcpu =
*vcpu, int ra, int rb)
> 	return EMULATE_DONE;
> }
>=20
> +static void tlbilx_all(struct kvmppc_vcpu_e500 *vcpu_e500, int =
tlbsel,
> +		       int pid, int rt)
> +{
> +	struct kvm_book3e_206_tlb_entry *tlbe;
> +	int tid, esel;
> +
> +	/* invalidate all entries */
> +	for (esel =3D 0; esel < vcpu_e500->gtlb_params[tlbsel].entries; =
esel++) {

By dereferencing the struct inside the loop you're creating a new load =
on every iteration. Please use a variable for entries.

> +		tlbe =3D get_entry(vcpu_e500, tlbsel, esel);
> +		tid =3D get_tlb_tid(tlbe);
> +		if (rt =3D=3D 0 || tid =3D=3D pid) {
> +			inval_gtlbe_on_host(vcpu_e500, tlbsel, esel);
> +			kvmppc_e500_gtlbe_invalidate(vcpu_e500, tlbsel, =
esel);
> +		}
> +	}
> +}
> +
> +static void tlbilx_one(struct kvmppc_vcpu_e500 *vcpu_e500, int pid,
> +		       int ra, int rb)
> +{
> +	int tlbsel, esel;
> +	gva_t ea;
> +
> +	ea =3D kvmppc_get_gpr(&vcpu_e500->vcpu, rb);
> +	if (ra)
> +		ea +=3D kvmppc_get_gpr(&vcpu_e500->vcpu, ra);
> +
> +	for (tlbsel =3D 0; tlbsel < 2; tlbsel++) {
> +		esel =3D kvmppc_e500_tlb_index(vcpu_e500, ea, tlbsel, =
pid, -1);
> +		if (esel >=3D 0) {
> +			inval_gtlbe_on_host(vcpu_e500, tlbsel, esel);
> +			kvmppc_e500_gtlbe_invalidate(vcpu_e500, tlbsel, =
esel);
> +			break;
> +		}
> +	}
> +}
> +
> +int kvmppc_e500_emul_tlbilx(struct kvm_vcpu *vcpu, int rt, int ra, =
int rb)
> +{
> +	struct kvmppc_vcpu_e500 *vcpu_e500 =3D to_e500(vcpu);
> +	int pid =3D get_cur_spid(vcpu);
> +
> +	if (rt =3D=3D 0 || rt =3D=3D 1) {
> +		tlbilx_all(vcpu_e500, 0, pid, rt);
> +		tlbilx_all(vcpu_e500, 1, pid, rt);
> +	} else if (rt =3D=3D 3) {

too many magic constants :)


Alex

^ permalink raw reply

* Re: [RFC PATCH 16/16] KVM: PPC: e500mc support
From: Avi Kivity @ 2012-01-09 16:33 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, agraf, kvm-ppc, kvm
In-Reply-To: <20111221013447.GP8378@schlenkerla.am.freescale.net>

On 12/21/2011 03:34 AM, Scott Wood wrote:
> Add processor support for e500mc, using hardware virtualization support
> (GS-mode).
>
> Current issues include:
>  - No support for external proxy (coreint) interrupt mode in the guest.
>
> Includes work by Ashish Kalra <Ashish.Kalra@freescale.com>,
> Varun Sethi <Varun.Sethi@freescale.com>, and
> Liu Yu <yu.liu@freescale.com>.
>

Best to include their signoffs, if possible.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply

* Re: [RFC PATCH 14/16] KVM: PPC: booke: category E.HV (GS-mode) support
From: Alexander Graf @ 2012-01-09 17:46 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <20111221013443.GN8378@schlenkerla.am.freescale.net>


On 21.12.2011, at 02:34, Scott Wood wrote:

> Chips such as e500mc that implement category E.HV in Power ISA 2.06
> provide hardware virtualization features, including a new MSR mode for
> guest state.  The guest OS can perform many operations without =
trapping
> into the hypervisor, including transitions to and from guest =
userspace.
>=20
> Since we can use SRR1[GS] to reliably tell whether an exception came =
from
> guest state, instead of messing around with IVPR, we use DO_KVM =
similarly
> to book3s.

Is there any benefit of using DO_KVM? I would assume that messing with =
IVPR is faster.

>=20
> Current issues include:
> - Machine checks from guest state are not routed to the host handler.
> - The guest can cause a host oops by executing an emulated instruction
>   in a page that lacks read permission.  Existing e500/4xx support has
>   the same problem.

We solve that in book3s pr by doing

  LAST_INST =3D <known bad value>;
  PACA->kvm_mode =3D <recover at next inst>;
  lwz(guest pc);
  do_more_stuff();

That way when an exception occurs at lwz() the DO_KVM handler checks =
that we're in kvm mode "recover" which does basically srr0+=3D4; rfi;.

>=20
> Includes work by Ashish Kalra <Ashish.Kalra@freescale.com>,
> Varun Sethi <Varun.Sethi@freescale.com>, and
> Liu Yu <yu.liu@freescale.com>.
>=20
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> arch/powerpc/include/asm/dbell.h            |    1 +
> arch/powerpc/include/asm/kvm_asm.h          |    8 +
> arch/powerpc/include/asm/kvm_booke_hv_asm.h |   49 +++
> arch/powerpc/include/asm/kvm_host.h         |   19 +-
> arch/powerpc/include/asm/kvm_ppc.h          |    3 +
> arch/powerpc/include/asm/mmu-book3e.h       |    6 +
> arch/powerpc/include/asm/processor.h        |    3 +
> arch/powerpc/include/asm/reg.h              |    2 +
> arch/powerpc/include/asm/reg_booke.h        |   34 ++
> arch/powerpc/kernel/asm-offsets.c           |   15 +-
> arch/powerpc/kernel/head_booke.h            |   28 ++-
> arch/powerpc/kvm/Kconfig                    |    3 +
> arch/powerpc/kvm/booke.c                    |  398 ++++++++++++++-----
> arch/powerpc/kvm/booke.h                    |   24 +-
> arch/powerpc/kvm/booke_emulate.c            |   23 +-
> arch/powerpc/kvm/bookehv_interrupts.S       |  587 =
+++++++++++++++++++++++++++
> arch/powerpc/kvm/powerpc.c                  |    5 +
> arch/powerpc/kvm/timing.h                   |    6 +
> 18 files changed, 1107 insertions(+), 107 deletions(-)
> create mode 100644 arch/powerpc/include/asm/kvm_booke_hv_asm.h
> create mode 100644 arch/powerpc/kvm/bookehv_interrupts.S
>=20
> diff --git a/arch/powerpc/include/asm/dbell.h =
b/arch/powerpc/include/asm/dbell.h
> index efa74ac..d7365b0 100644
> --- a/arch/powerpc/include/asm/dbell.h
> +++ b/arch/powerpc/include/asm/dbell.h
> @@ -19,6 +19,7 @@
>=20
> #define PPC_DBELL_MSG_BRDCAST	(0x04000000)
> #define PPC_DBELL_TYPE(x)	(((x) & 0xf) << (63-36))
> +#define PPC_DBELL_LPID(x)	((x) << (63 - 49))
> enum ppc_dbell {
> 	PPC_DBELL =3D 0,		/* doorbell */
> 	PPC_DBELL_CRIT =3D 1,	/* critical doorbell */
> diff --git a/arch/powerpc/include/asm/kvm_asm.h =
b/arch/powerpc/include/asm/kvm_asm.h
> index 7b1f0e0..0978152 100644
> --- a/arch/powerpc/include/asm/kvm_asm.h
> +++ b/arch/powerpc/include/asm/kvm_asm.h
> @@ -48,6 +48,14 @@
> #define BOOKE_INTERRUPT_SPE_FP_DATA 33
> #define BOOKE_INTERRUPT_SPE_FP_ROUND 34
> #define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35
> +#define BOOKE_INTERRUPT_DOORBELL 36
> +#define BOOKE_INTERRUPT_DOORBELL_CRITICAL 37
> +
> +/* booke_hv */
> +#define BOOKE_INTERRUPT_GUEST_DBELL 38
> +#define BOOKE_INTERRUPT_GUEST_DBELL_CRIT 39
> +#define BOOKE_INTERRUPT_HV_SYSCALL 40
> +#define BOOKE_INTERRUPT_HV_PRIV 41
>=20
> /* book3s */
>=20
> diff --git a/arch/powerpc/include/asm/kvm_booke_hv_asm.h =
b/arch/powerpc/include/asm/kvm_booke_hv_asm.h
> new file mode 100644
> index 0000000..30a600f
> --- /dev/null
> +++ b/arch/powerpc/include/asm/kvm_booke_hv_asm.h
> @@ -0,0 +1,49 @@
> +/*
> + * Copyright 2010-2011 Freescale Semiconductor, Inc.
> + *
> + * This program is free software; you can redistribute it and/or =
modify
> + * it under the terms of the GNU General Public License, version 2, =
as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef ASM_KVM_BOOKE_HV_ASM_H
> +#define ASM_KVM_BOOKE_HV_ASM_H
> +
> +#ifdef __ASSEMBLY__
> +
> +/*
> + * All exceptions from guest state must go through KVM
> + * (except for those which are delivered directly to the guest) --
> + * there are no exceptions for which we fall through directly to
> + * the normal host handler.
> + *
> + * Expected inputs (normal exceptions):
> + *   SCRATCH0 =3D saved r10
> + *   r10 =3D thread struct
> + *   r11 =3D appropriate SRR1 variant (currently used as scratch)
> + *   r13 =3D saved CR
> + *   *(r10 + THREAD_NORMSAVE(0)) =3D saved r11
> + *   *(r10 + THREAD_NORMSAVE(2)) =3D saved r13
> + *
> + * Expected inputs (crit/mcheck/debug exceptions):
> + *   appropriate SCRATCH =3D saved r8
> + *   r8 =3D exception level stack frame
> + *   r9 =3D *(r8 + _CCR) =3D saved CR
> + *   r11 =3D appropriate SRR1 variant (currently used as scratch)
> + *   *(r8 + GPR9) =3D saved r9
> + *   *(r8 + GPR10) =3D saved r10 (r10 not yet clobbered)
> + *   *(r8 + GPR11) =3D saved r11
> + */
> +.macro DO_KVM intno srr1
> +#ifdef CONFIG_KVM_BOOKE_HV
> +BEGIN_FTR_SECTION
> +	mtocrf	0x80, r11	/* check MSR[GS] without clobbering reg =
*/
> +	bf	3, kvmppc_resume_\intno\()_\srr1
> +	b	kvmppc_handler_\intno\()_\srr1
> +kvmppc_resume_\intno\()_\srr1:
> +END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
> +#endif
> +.endm
> +
> +#endif /*__ASSEMBLY__ */
> +#endif /* ASM_KVM_BOOKE_HV_ASM_H */
> diff --git a/arch/powerpc/include/asm/kvm_host.h =
b/arch/powerpc/include/asm/kvm_host.h
> index ad4d671..d603513 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -107,6 +107,8 @@ struct kvm_vcpu_stat {
> 	u32 dec_exits;
> 	u32 ext_intr_exits;
> 	u32 halt_wakeup;
> +	u32 dbell_exits;
> +	u32 gdbell_exits;
> #ifdef CONFIG_PPC_BOOK3S
> 	u32 pf_storage;
> 	u32 pf_instruc;
> @@ -141,6 +143,7 @@ enum kvm_exit_types {
> 	EMULATED_TLBSX_EXITS,
> 	EMULATED_TLBWE_EXITS,
> 	EMULATED_RFI_EXITS,
> +	EMULATED_RFCI_EXITS,
> 	DEC_EXITS,
> 	EXT_INTR_EXITS,
> 	HALT_WAKEUP,
> @@ -148,6 +151,8 @@ enum kvm_exit_types {
> 	FP_UNAVAIL,
> 	DEBUG_EXITS,
> 	TIMEINGUEST,
> +	DBELL_EXITS,
> +	GDBELL_EXITS,
> 	__NUMBER_OF_KVM_EXIT_TYPES
> };
>=20
> @@ -213,10 +218,10 @@ struct revmap_entry {
> #define KVMPPC_GOT_PAGE		0x80
>=20
> struct kvm_arch {
> +	unsigned int lpid;
> #ifdef CONFIG_KVM_BOOK3S_64_HV
> 	unsigned long hpt_virt;
> 	struct revmap_entry *revmap;
> -	unsigned int lpid;
> 	unsigned int host_lpid;
> 	unsigned long host_lpcr;
> 	unsigned long sdr1;
> @@ -346,6 +351,17 @@ struct kvm_vcpu_arch {
> 	u32 qpr[32];
> #endif
>=20
> +#ifdef CONFIG_KVM_BOOKE_HV
> +	u32 host_mas4;
> +	u32 host_mas6;
> +	u32 shadow_epcr;
> +	u32 epcr;
> +	u32 shadow_msrp;
> +	u32 eplc;
> +	u32 epsc;
> +	u32 oldpir;
> +#endif
> +
> #ifdef CONFIG_PPC_BOOK3S
> 	ulong hflags;
> 	ulong guest_owned_ext;
> @@ -417,6 +433,7 @@ struct kvm_vcpu_arch {
> 	ulong queued_esr;
> 	u32 tlbcfg[4];
> 	u32 mmucfg;
> +	u32 epr;
> #endif
> 	gpa_t paddr_accessed;
>=20
> diff --git a/arch/powerpc/include/asm/kvm_ppc.h =
b/arch/powerpc/include/asm/kvm_ppc.h
> index 5524f88..247b920 100644
> --- a/arch/powerpc/include/asm/kvm_ppc.h
> +++ b/arch/powerpc/include/asm/kvm_ppc.h
> @@ -137,6 +137,9 @@ extern int =
kvmppc_core_prepare_memory_region(struct kvm *kvm,
> extern void kvmppc_core_commit_memory_region(struct kvm *kvm,
> 				struct kvm_userspace_memory_region =
*mem);
>=20
> +extern int kvmppc_bookehv_init(void);
> +extern void kvmppc_bookehv_exit(void);
> +
> /*
>  * Cuts out inst bits with ordering according to spec.
>  * That means the leftmost bit is zero. All given bits are included.
> diff --git a/arch/powerpc/include/asm/mmu-book3e.h =
b/arch/powerpc/include/asm/mmu-book3e.h
> index 36a6eaa..b8e303c 100644
> --- a/arch/powerpc/include/asm/mmu-book3e.h
> +++ b/arch/powerpc/include/asm/mmu-book3e.h
> @@ -104,6 +104,8 @@
> #define MAS4_TSIZED_MASK	0x00000f80	/* Default TSIZE */
> #define MAS4_TSIZED_SHIFT	7
>=20
> +#define MAS5_SGS		0x80000000
> +
> #define MAS6_SPID0		0x3FFF0000
> #define MAS6_SPID1		0x00007FFE
> #define MAS6_ISIZE(x)		MAS1_TSIZE(x)
> @@ -118,6 +120,10 @@
>=20
> #define MAS7_RPN		0xFFFFFFFF
>=20
> +#define MAS8_TGS		0x80000000 /* Guest space */
> +#define MAS8_VF			0x40000000 /* Virtualization =
Fault */
> +#define MAS8_TLPID		0x000000ff
> +
> /* Bit definitions for MMUCFG */
> #define MMUCFG_MAVN	0x00000003	/* MMU Architecture Version =
Number */
> #define MMUCFG_MAVN_V1	0x00000000	/* v1.0 */
> diff --git a/arch/powerpc/include/asm/processor.h =
b/arch/powerpc/include/asm/processor.h
> index eb11a44..032a984 100644
> --- a/arch/powerpc/include/asm/processor.h
> +++ b/arch/powerpc/include/asm/processor.h
> @@ -243,6 +243,9 @@ struct thread_struct {
> #ifdef CONFIG_KVM_BOOK3S_32_HANDLER
> 	void*		kvm_shadow_vcpu; /* KVM internal data */
> #endif /* CONFIG_KVM_BOOK3S_32_HANDLER */
> +#if defined(CONFIG_KVM) && defined(CONFIG_BOOKE)
> +	struct kvm_vcpu	*kvm_vcpu;
> +#endif
> #ifdef CONFIG_PPC64
> 	unsigned long	dscr;
> 	int		dscr_inherit;
> diff --git a/arch/powerpc/include/asm/reg.h =
b/arch/powerpc/include/asm/reg.h
> index 209dc74..5993770 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -257,7 +257,9 @@
> #define   LPCR_LPES_SH	2
> #define   LPCR_RMI     0x00000002      /* real mode is cache inhibit =
*/
> #define   LPCR_HDICE   0x00000001      /* Hyp Decr enable (HV,PR,EE) =
*/
> +#ifndef SPRN_LPID
> #define SPRN_LPID	0x13F	/* Logical Partition Identifier */
> +#endif
> #define   LPID_RSVD	0x3ff		/* Reserved LPID for partn =
switching */
> #define	SPRN_HMER	0x150	/* Hardware m? error recovery */
> #define	SPRN_HMEER	0x151	/* Hardware m? enable error =
recovery */
> diff --git a/arch/powerpc/include/asm/reg_booke.h =
b/arch/powerpc/include/asm/reg_booke.h
> index 03c48e8..bd80b8d 100644
> --- a/arch/powerpc/include/asm/reg_booke.h
> +++ b/arch/powerpc/include/asm/reg_booke.h
> @@ -56,17 +56,29 @@
> #define SPRN_SPRG7W	0x117	/* Special Purpose Register General 7 =
Write */
> #define SPRN_EPCR	0x133	/* Embedded Processor Control Register =
*/
> #define SPRN_DBCR2	0x136	/* Debug Control Register 2 */
> +#define SPRN_MSRP	0x137	/* MSR Protect Register */
> #define SPRN_IAC3	0x13A	/* Instruction Address Compare 3 */
> #define SPRN_IAC4	0x13B	/* Instruction Address Compare 4 */
> #define SPRN_DVC1	0x13E	/* Data Value Compare Register 1 */
> #define SPRN_DVC2	0x13F	/* Data Value Compare Register 2 */
> +#define SPRN_LPID	0x152	/* Logical Partition ID */
> #define SPRN_MAS8	0x155	/* MMU Assist Register 8 */
> #define SPRN_TLB0PS	0x158	/* TLB 0 Page Size Register */
> #define SPRN_MAS5_MAS6	0x15c	/* MMU Assist Register 5 || 6 */
> #define SPRN_MAS8_MAS1	0x15d	/* MMU Assist Register 8 || 1 */
> #define SPRN_EPTCFG	0x15e	/* Embedded Page Table Config */
> +#define SPRN_GSPRG0	0x170	/* Guest SPRG0 */
> +#define SPRN_GSPRG1	0x171	/* Guest SPRG1 */
> +#define SPRN_GSPRG2	0x172	/* Guest SPRG2 */
> +#define SPRN_GSPRG3	0x173	/* Guest SPRG3 */
> #define SPRN_MAS7_MAS3	0x174	/* MMU Assist Register 7 || 3 */
> #define SPRN_MAS0_MAS1	0x175	/* MMU Assist Register 0 || 1 */
> +#define SPRN_GSRR0	0x17A	/* Guest SRR0 */
> +#define SPRN_GSRR1	0x17B	/* Guest SRR1 */
> +#define SPRN_GEPR	0x17C	/* Guest EPR */
> +#define SPRN_GDEAR	0x17D	/* Guest DEAR */
> +#define SPRN_GPIR	0x17E	/* Guest PIR */
> +#define SPRN_GESR	0x17F	/* Guest Exception Syndrome Register */
> #define SPRN_IVOR0	0x190	/* Interrupt Vector Offset Register 0 */
> #define SPRN_IVOR1	0x191	/* Interrupt Vector Offset Register 1 */
> #define SPRN_IVOR2	0x192	/* Interrupt Vector Offset Register 2 */
> @@ -87,6 +99,13 @@
> #define SPRN_IVOR39	0x1B1	/* Interrupt Vector Offset Register 39 =
*/
> #define SPRN_IVOR40	0x1B2	/* Interrupt Vector Offset Register 40 =
*/
> #define SPRN_IVOR41	0x1B3	/* Interrupt Vector Offset Register 41 =
*/
> +#define SPRN_GIVOR2	0x1B8	/* Guest IVOR2 */
> +#define SPRN_GIVOR3	0x1B9	/* Guest IVOR3 */
> +#define SPRN_GIVOR4	0x1BA	/* Guest IVOR4 */
> +#define SPRN_GIVOR8	0x1BB	/* Guest IVOR8 */
> +#define SPRN_GIVOR13	0x1BC	/* Guest IVOR13 */
> +#define SPRN_GIVOR14	0x1BD	/* Guest IVOR14 */
> +#define SPRN_GIVPR	0x1BF	/* Guest IVPR */
> #define SPRN_SPEFSCR	0x200	/* SPE & Embedded FP Status & Control */
> #define SPRN_BBEAR	0x201	/* Branch Buffer Entry Address Register =
*/
> #define SPRN_BBTAR	0x202	/* Branch Buffer Target Address Register =
*/
> @@ -235,6 +254,10 @@
> #define MCSR_LDG	0x00002000UL /* Guarded Load */
> #define MCSR_TLBSYNC	0x00000002UL /* Multiple tlbsyncs detected */
> #define MCSR_BSL2_ERR	0x00000001UL /* Backside L2 cache error */
> +
> +#define MSRP_UCLEP	0x04000000 /* Protect MSR[UCLE] */
> +#define MSRP_DEP	0x00000200 /* Protect MSR[DE] */
> +#define MSRP_PMMP	0x00000004 /* Protect MSR[PMM] */
> #endif
>=20
> #ifdef CONFIG_E200
> @@ -589,6 +612,17 @@
> #define SPRN_EPCR_DMIUH		0x00400000	/* Disable MAS =
Interrupt updates
> 						 * for hypervisor */
>=20
> +/* Bit definitions for EPLC/EPSC */
> +#define EPC_EPR		0x80000000 /* 1 =3D user, 0 =3D kernel =
*/
> +#define EPC_EPR_SHIFT	31
> +#define EPC_EAS		0x40000000 /* Address Space */
> +#define EPC_EAS_SHIFT	30
> +#define EPC_EGS		0x20000000 /* 1 =3D guest, 0 =3D =
hypervisor */
> +#define EPC_EGS_SHIFT	29
> +#define EPC_ELPID	0x00ff0000
> +#define EPC_ELPID_SHIFT	16
> +#define EPC_EPID	0x00003fff
> +#define EPC_EPID_SHIFT	0
>=20
> /*
>  * The IBM-403 is an even more odd special case, as it is much
> diff --git a/arch/powerpc/kernel/asm-offsets.c =
b/arch/powerpc/kernel/asm-offsets.c
> index c80bdd1..e179f09 100644
> --- a/arch/powerpc/kernel/asm-offsets.c
> +++ b/arch/powerpc/kernel/asm-offsets.c
> @@ -119,6 +119,9 @@ int main(void)
> #ifdef CONFIG_KVM_BOOK3S_32_HANDLER
> 	DEFINE(THREAD_KVM_SVCPU, offsetof(struct thread_struct, =
kvm_shadow_vcpu));
> #endif
> +#ifdef CONFIG_KVM_BOOKE_HV
> +	DEFINE(THREAD_KVM_VCPU, offsetof(struct thread_struct, =
kvm_vcpu));
> +#endif
>=20
> 	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
> 	DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, =
local_flags));
> @@ -400,6 +403,7 @@ int main(void)
> #ifdef CONFIG_KVM
> 	DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, =
arch.host_stack));
> 	DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
> +	DEFINE(VCPU_GUEST_PID, offsetof(struct kvm_vcpu, arch.pid));
> 	DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.regs.gpr));
> 	DEFINE(VCPU_VRSAVE, offsetof(struct kvm_vcpu, arch.vrsave));
> 	DEFINE(VCPU_FPRS, offsetof(struct kvm_vcpu, arch.fpr));
> @@ -442,9 +446,11 @@ int main(void)
> 	DEFINE(VCPU_SHARED_MAS4, offsetof(struct kvm_vcpu_arch_shared, =
mas4));
> 	DEFINE(VCPU_SHARED_MAS6, offsetof(struct kvm_vcpu_arch_shared, =
mas6));
>=20
> +	DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm));
> +	DEFINE(KVM_LPID, offsetof(struct kvm, arch.lpid));
> +
> 	/* book3s */
> #ifdef CONFIG_KVM_BOOK3S_64_HV
> -	DEFINE(KVM_LPID, offsetof(struct kvm, arch.lpid));
> 	DEFINE(KVM_SDR1, offsetof(struct kvm, arch.sdr1));
> 	DEFINE(KVM_HOST_LPID, offsetof(struct kvm, arch.host_lpid));
> 	DEFINE(KVM_HOST_LPCR, offsetof(struct kvm, arch.host_lpcr));
> @@ -459,7 +465,6 @@ int main(void)
> 	DEFINE(VCPU_DAR, offsetof(struct kvm_vcpu, arch.shregs.dar));
> #endif
> #ifdef CONFIG_PPC_BOOK3S
> -	DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm));
> 	DEFINE(VCPU_VCPUID, offsetof(struct kvm_vcpu, vcpu_id));
> 	DEFINE(VCPU_PURR, offsetof(struct kvm_vcpu, arch.purr));
> 	DEFINE(VCPU_SPURR, offsetof(struct kvm_vcpu, arch.spurr));
> @@ -605,6 +610,12 @@ int main(void)
> 	DEFINE(VCPU_HOST_SPEFSCR, offsetof(struct kvm_vcpu, =
arch.host_spefscr));
> #endif
>=20
> +#ifdef CONFIG_KVM_BOOKE_HV
> +	DEFINE(VCPU_HOST_MAS4, offsetof(struct kvm_vcpu, =
arch.host_mas4));
> +	DEFINE(VCPU_HOST_MAS6, offsetof(struct kvm_vcpu, =
arch.host_mas6));
> +	DEFINE(VCPU_EPLC, offsetof(struct kvm_vcpu, arch.eplc));
> +#endif
> +
> #ifdef CONFIG_KVM_EXIT_TIMING
> 	DEFINE(VCPU_TIMING_EXIT_TBU, offsetof(struct kvm_vcpu,
> 						=
arch.timing_exit.tv32.tbu));
> diff --git a/arch/powerpc/kernel/head_booke.h =
b/arch/powerpc/kernel/head_booke.h
> index 06ab353..b87c335 100644
> --- a/arch/powerpc/kernel/head_booke.h
> +++ b/arch/powerpc/kernel/head_booke.h
> @@ -3,6 +3,7 @@
>=20
> #include <asm/ptrace.h>	/* for STACK_FRAME_REGS_MARKER */
> #include <asm/kvm_asm.h>
> +#include <asm/kvm_booke_hv_asm.h>
>=20
> /*
>  * Macros used for common Book-e exception handling
> @@ -36,8 +37,9 @@
> 	stw	r11, THREAD_NORMSAVE(0)(r10);				 =
    \
> 	stw	r13, THREAD_NORMSAVE(2)(r10);				 =
    \
> 	mfcr	r13;			/* save CR in r13 for now	 =
  */\
> -	mfspr	r11,SPRN_SRR1;		/* check whether user or kernel  =
  */\
> -	andi.	r11,r11,MSR_PR;						 =
    \
> +	mfspr	r11, SPRN_SRR1;		                                 =
    \
> +	DO_KVM	BOOKE_INTERRUPT_##intno SPRN_SRR1;			 =
    \
> +	andi.	r11, r11, MSR_PR;	/* check whether user or kernel  =
  */\
> 	mr	r11, r1;						 =
    \
> 	beq	1f;							 =
    \
> 	/* if from user, start at top of this thread's kernel stack */   =
    \
> @@ -123,8 +125,9 @@
> 	stw	r10,GPR10(r8);						 =
    \
> 	stw	r11,GPR11(r8);						 =
    \
> 	stw	r9,_CCR(r8);		/* save CR on stack		 =
  */\
> -	mfspr	r10,exc_level_srr1;	/* check whether user or kernel  =
  */\
> -	andi.	r10,r10,MSR_PR;						 =
    \
> +	mfspr	r11,exc_level_srr1;	/* check whether user or kernel  =
  */\
> +	DO_KVM	BOOKE_INTERRUPT_##intno exc_level_srr1;		         =
    \
> +	andi.	r11,r11,MSR_PR;						 =
    \
> 	mfspr	r11,SPRN_SPRG_THREAD;	/* if from user, start at top of =
  */\
> 	lwz	r11,THREAD_INFO-THREAD(r11); /* this thread's kernel =
stack */\
> 	addi	r11,r11,EXC_LVL_FRAME_OVERHEAD;	/* allocate stack frame  =
  */\
> @@ -173,6 +176,23 @@
> 			SPRN_MCSRR0, SPRN_MCSRR1)
>=20
> /*
> + * Guest Doorbell -- this is a bit odd in that uses GSRR0/1 despite
> + * being delivered to the host.  This exception can only happen
> + * inside a KVM guest -- so we just handle up to the DO_KVM rather
> + * than try to fit this into one of the existing prolog macros.
> + */
> +#define GUEST_DOORBELL_EXCEPTION \
> +	START_EXCEPTION(GuestDoorbell);					 =
    \
> +	mtspr	SPRN_SPRG_WSCRATCH0, r10;	/* save one register */	 =
    \
> +	mfspr	r10, SPRN_SPRG_THREAD;					 =
    \
> +	stw	r11, THREAD_NORMSAVE(0)(r10);				 =
    \
> +	mfspr	r11, SPRN_SRR1;		                                 =
    \
> +	stw	r13, THREAD_NORMSAVE(2)(r10);				 =
    \
> +	mfcr	r13;			/* save CR in r13 for now	 =
  */\
> +	DO_KVM	BOOKE_INTERRUPT_GUEST_DBELL SPRN_GSRR1;			 =
    \
> +	trap
> +
> +/*
>  * Exception vectors.
>  */
> #define	START_EXCEPTION(label)						=
     \
> diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
> index 8f64709..2c33cd3 100644
> --- a/arch/powerpc/kvm/Kconfig
> +++ b/arch/powerpc/kvm/Kconfig
> @@ -90,6 +90,9 @@ config KVM_BOOK3S_64_PR
> 	depends on KVM_BOOK3S_64 && !KVM_BOOK3S_64_HV
> 	select KVM_BOOK3S_PR
>=20
> +config KVM_BOOKE_HV
> +	bool
> +
> config KVM_440
> 	bool "KVM support for PowerPC 440 processors"
> 	depends on EXPERIMENTAL && 44x
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index f66e741..cf63b93 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -17,6 +17,8 @@
>  *
>  * Authors: Hollis Blanchard <hollisb@us.ibm.com>
>  *          Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
> + *          Scott Wood <scottwood@freescale.com>
> + *          Varun Sethi <varun.sethi@freescale.com>
>  */
>=20
> #include <linux/errno.h>
> @@ -30,9 +32,12 @@
> #include <asm/cputable.h>
> #include <asm/uaccess.h>
> #include <asm/kvm_ppc.h>
> -#include "timing.h"
> #include <asm/cacheflush.h>
> +#include <asm/dbell.h>
> +#include <asm/hw_irq.h>
> +#include <asm/irq.h>
>=20
> +#include "timing.h"
> #include "booke.h"
>=20
> unsigned long kvmppc_booke_handlers;
> @@ -55,6 +60,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] =3D =
{
> 	{ "dec",        VCPU_STAT(dec_exits) },
> 	{ "ext_intr",   VCPU_STAT(ext_intr_exits) },
> 	{ "halt_wakeup", VCPU_STAT(halt_wakeup) },
> +	{ "doorbell", VCPU_STAT(dbell_exits) },
> +	{ "guest doorbell", VCPU_STAT(gdbell_exits) },
> 	{ NULL }
> };
>=20
> @@ -123,6 +130,10 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 =
new_msr)
> {
> 	u32 old_msr =3D vcpu->arch.shared->msr;
>=20
> +#ifdef CONFIG_KVM_BOOKE_HV
> +	new_msr |=3D MSR_GS;
> +#endif
> +
> 	vcpu->arch.shared->msr =3D new_msr;
>=20
> 	kvmppc_mmu_msr_notify(vcpu, old_msr);
> @@ -197,6 +208,75 @@ void kvmppc_core_dequeue_external(struct kvm_vcpu =
*vcpu,
> 	clear_bit(BOOKE_IRQPRIO_EXTERNAL_LEVEL, =
&vcpu->arch.pending_exceptions);
> }
>=20
> +static void set_guest_srr(struct kvm_vcpu *vcpu, unsigned long srr0, =
u32 srr1)
> +{
> +#ifdef CONFIG_KVM_BOOKE_HV
> +	mtspr(SPRN_GSRR0, srr0);
> +	mtspr(SPRN_GSRR1, srr1);
> +#else
> +	vcpu->arch.shared->srr0 =3D srr0;
> +	vcpu->arch.shared->srr1 =3D srr1;
> +#endif
> +}
> +
> +static void set_guest_csrr(struct kvm_vcpu *vcpu, unsigned long srr0, =
u32 srr1)
> +{
> +	vcpu->arch.csrr0 =3D srr0;
> +	vcpu->arch.csrr1 =3D srr1;
> +}
> +
> +static void set_guest_dsrr(struct kvm_vcpu *vcpu, unsigned long srr0, =
u32 srr1)
> +{
> +	if (cpu_has_feature(CPU_FTR_DEBUG_LVL_EXC)) {
> +		vcpu->arch.dsrr0 =3D srr0;
> +		vcpu->arch.dsrr1 =3D srr1;
> +	} else {
> +		set_guest_csrr(vcpu, srr0, srr1);
> +	}
> +}
> +
> +static void set_guest_mcsrr(struct kvm_vcpu *vcpu, unsigned long =
srr0, u32 srr1)
> +{
> +	vcpu->arch.mcsrr0 =3D srr0;
> +	vcpu->arch.mcsrr1 =3D srr1;
> +}
> +
> +static unsigned long get_guest_dear(struct kvm_vcpu *vcpu)
> +{
> +#ifdef CONFIG_KVM_BOOKE_HV
> +	return mfspr(SPRN_GDEAR);
> +#else
> +	return vcpu->arch.shared->dar;
> +#endif
> +}
> +
> +static void set_guest_dear(struct kvm_vcpu *vcpu, unsigned long dear)
> +{
> +#ifdef CONFIG_KVM_BOOKE_HV
> +	mtspr(SPRN_GDEAR, dear);
> +#else
> +	vcpu->arch.shared->dar =3D dear;
> +#endif
> +}
> +
> +static unsigned long get_guest_esr(struct kvm_vcpu *vcpu)
> +{
> +#ifdef CONFIG_KVM_BOOKE_HV
> +	return mfspr(SPRN_ESR);
> +#else
> +	return vcpu->arch.shared->esr;
> +#endif
> +}
> +
> +static void set_guest_esr(struct kvm_vcpu *vcpu, u32 esr)
> +{
> +#ifdef CONFIG_KVM_BOOKE_HV
> +	mtspr(SPRN_GESR, esr);
> +#else
> +	vcpu->arch.shared->esr =3D esr;
> +#endif
> +}
> +
> /* Deliver the interrupt of the corresponding priority, if possible. =
*/
> static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
>                                         unsigned int priority)
> @@ -208,6 +288,7 @@ static int kvmppc_booke_irqprio_deliver(struct =
kvm_vcpu *vcpu,
> 	ulong crit_r1 =3D kvmppc_get_gpr(vcpu, 1);
> 	bool crit;
> 	bool keep_irq =3D false;
> +	enum int_class int_class;
>=20
> 	/* Truncate crit indicators in 32 bit mode */
> 	if (!(vcpu->arch.shared->msr & MSR_SF)) {
> @@ -243,16 +324,20 @@ static int kvmppc_booke_irqprio_deliver(struct =
kvm_vcpu *vcpu,
> 	case BOOKE_IRQPRIO_AP_UNAVAIL:
> 	case BOOKE_IRQPRIO_ALIGNMENT:
> 		allowed =3D 1;
> -		msr_mask =3D MSR_CE|MSR_ME|MSR_DE;
> +		msr_mask =3D MSR_GS | MSR_CE | MSR_ME | MSR_DE;

No need to do this. You already force MSR_GS in set_msr();

> +		int_class =3D INT_CLASS_NONCRIT;
> 		break;
> 	case BOOKE_IRQPRIO_CRITICAL:
> -	case BOOKE_IRQPRIO_WATCHDOG:
> 		allowed =3D vcpu->arch.shared->msr & MSR_CE;
> -		msr_mask =3D MSR_ME;
> +		allowed =3D allowed && !crit;
> +		msr_mask =3D MSR_GS | MSR_ME;
> +		int_class =3D INT_CLASS_CRIT;
> 		break;
> 	case BOOKE_IRQPRIO_MACHINE_CHECK:
> 		allowed =3D vcpu->arch.shared->msr & MSR_ME;
> -		msr_mask =3D 0;
> +		allowed =3D allowed && !crit;
> +		msr_mask =3D MSR_GS;
> +		int_class =3D INT_CLASS_MC;
> 		break;
> 	case BOOKE_IRQPRIO_DECREMENTER:
> 	case BOOKE_IRQPRIO_FIT:
> @@ -261,29 +346,63 @@ static int kvmppc_booke_irqprio_deliver(struct =
kvm_vcpu *vcpu,
> 	case BOOKE_IRQPRIO_EXTERNAL:
> 		allowed =3D vcpu->arch.shared->msr & MSR_EE;
> 		allowed =3D allowed && !crit;
> -		msr_mask =3D MSR_CE|MSR_ME|MSR_DE;
> +		msr_mask =3D MSR_GS | MSR_CE | MSR_ME | MSR_DE;
> +		int_class =3D INT_CLASS_NONCRIT;
> 		break;
> 	case BOOKE_IRQPRIO_DEBUG:
> 		allowed =3D vcpu->arch.shared->msr & MSR_DE;
> -		msr_mask =3D MSR_ME;
> +		allowed =3D allowed && !crit;
> +		msr_mask =3D MSR_GS | MSR_ME;
> +		int_class =3D INT_CLASS_CRIT;
> 		break;
> 	}
>=20
> 	if (allowed) {
> -		vcpu->arch.shared->srr0 =3D vcpu->arch.regs.nip;
> -		vcpu->arch.shared->srr1 =3D vcpu->arch.shared->msr;
> +		switch (int_class) {
> +		case INT_CLASS_NONCRIT:
> +			set_guest_srr(vcpu, vcpu->arch.regs.nip,
> +				      vcpu->arch.shared->msr);
> +			break;
> +		case INT_CLASS_CRIT:
> +			set_guest_csrr(vcpu, vcpu->arch.regs.nip,
> +				       vcpu->arch.shared->msr);
> +			break;
> +		case INT_CLASS_DBG:
> +			set_guest_dsrr(vcpu, vcpu->arch.regs.nip,
> +				       vcpu->arch.shared->msr);
> +			break;
> +		case INT_CLASS_MC:
> +			set_guest_mcsrr(vcpu, vcpu->arch.regs.nip,
> +					vcpu->arch.shared->msr);
> +			break;
> +		}
> +
> 		vcpu->arch.regs.nip =3D vcpu->arch.ivpr |
> 				      vcpu->arch.ivor[priority];
> 		if (update_esr =3D=3D true)
> -			vcpu->arch.shared->esr =3D =
vcpu->arch.queued_esr;
> +			set_guest_esr(vcpu, vcpu->arch.queued_esr);
> 		if (update_dear =3D=3D true)
> -			vcpu->arch.shared->dar =3D =
vcpu->arch.queued_dear;
> +			set_guest_dear(vcpu, vcpu->arch.queued_dear);
> 		kvmppc_set_msr(vcpu, vcpu->arch.shared->msr & msr_mask);
>=20
> 		if (!keep_irq)
> 			clear_bit(priority, =
&vcpu->arch.pending_exceptions);
> 	}
>=20
> +#ifdef CONFIG_KVM_BOOKE_HV
> +	/*
> +	 * If an interrupt is pending but masked, raise a guest doorbell
> +	 * so that we are notified when the guest enables the relevant
> +	 * MSR bit.
> +	 */
> +	if (vcpu->arch.pending_exceptions & BOOKE_IRQMASK_EE)
> +		kvmppc_set_pending_interrupt(vcpu, INT_CLASS_NONCRIT);
> +	if (vcpu->arch.pending_exceptions & BOOKE_IRQMASK_CE)
> +		kvmppc_set_pending_interrupt(vcpu, INT_CLASS_CRIT);
> +	if (vcpu->arch.pending_exceptions & BOOKE_IRQPRIO_MACHINE_CHECK)
> +		kvmppc_set_pending_interrupt(vcpu, INT_CLASS_MC);
> +#endif
> +
> 	return allowed;
> }
>=20
> @@ -347,6 +466,11 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, =
struct kvm_vcpu *vcpu)
> 		return -EINVAL;
> 	}
>=20
> +	if (!current->thread.kvm_vcpu) {
> +		WARN(1, "no vcpu\n");
> +		return -EPERM;
> +	}

Huh?

> +
> 	local_irq_disable();
>=20
> 	kvmppc_core_prepare_to_enter(vcpu);
> @@ -366,6 +490,38 @@ out:
> 	return ret;
> }
>=20
> +static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
> +{
> +	enum emulation_result er;
> +
> +	er =3D kvmppc_emulate_instruction(run, vcpu);
> +	switch (er) {
> +	case EMULATE_DONE:
> +		/* don't overwrite subtypes, just account kvm_stats */
> +		kvmppc_account_exit_stat(vcpu, EMULATED_INST_EXITS);
> +		/* Future optimization: only reload non-volatiles if
> +		 * they were actually modified by emulation. */
> +		return RESUME_GUEST_NV;
> +
> +	case EMULATE_DO_DCR:
> +		run->exit_reason =3D KVM_EXIT_DCR;
> +		return RESUME_HOST;
> +
> +	case EMULATE_FAIL:
> +		/* XXX Deliver Program interrupt to guest. */
> +		printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
> +		       __func__, vcpu->arch.regs.nip, =
vcpu->arch.last_inst);

This should be throttled, otherwise the guest can spam our logs.

> +		/* For debugging, encode the failing instruction and
> +		 * report it to userspace. */
> +		run->hw.hardware_exit_reason =3D ~0ULL << 32;
> +		run->hw.hardware_exit_reason |=3D vcpu->arch.last_inst;


I'm fairly sure you want to fix this :)

> +		return RESUME_HOST;
> +
> +	default:
> +		BUG();
> +	}
> +}
> +
> /**
>  * kvmppc_handle_exit
>  *
> @@ -374,12 +530,39 @@ out:
> int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
>                        unsigned int exit_nr)
> {
> -	enum emulation_result er;
> 	int r =3D RESUME_HOST;
>=20
> 	/* update before a new last_exit_type is rewritten */
> 	kvmppc_update_timing_stats(vcpu);
>=20
> +	/*
> +	 * If we actually care, we could copy MSR, DEAR, and ESR to =
regs,
> +	 * insert an appropriate trap number, etc.
> +	 *
> +	 * Seems like a waste of cycles for something that should only =
matter
> +	 * to someone using sysrq-t/p or similar host kernel debug =
facility.
> +	 * We have other debug facilities to get that information from a
> +	 * guest through userspace.
> +	 */
> +	switch (exit_nr) {
> +	case BOOKE_INTERRUPT_EXTERNAL:
> +		do_IRQ(&vcpu->arch.regs);

Ah, so that's what you want to use regs for. So is having a pt_regs =
struct that only contains useful register values in half its fields any =
useful here? Or could we keep control of the registers ourselves, =
enabling us to maybe one day optimize things more.

> +		break;
> +
> +	case BOOKE_INTERRUPT_DECREMENTER:
> +		timer_interrupt(&vcpu->arch.regs);
> +		break;
> +
> +#if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_BOOK3E_64)
> +	case BOOKE_INTERRUPT_DOORBELL:
> +		doorbell_exception(&vcpu->arch.regs);
> +		break;
> +#endif
> +	case BOOKE_INTERRUPT_MACHINE_CHECK:
> +		/* FIXME */
> +		break;
> +	}
> +
> 	local_irq_enable();
>=20
> 	run->exit_reason =3D KVM_EXIT_UNKNOWN;
> @@ -387,30 +570,56 @@ int kvmppc_handle_exit(struct kvm_run *run, =
struct kvm_vcpu *vcpu,
>=20
> 	switch (exit_nr) {
> 	case BOOKE_INTERRUPT_MACHINE_CHECK:
> -		printk("MACHINE CHECK: %lx\n", mfspr(SPRN_MCSR));
> -		kvmppc_dump_vcpu(vcpu);
> -		r =3D RESUME_HOST;
> +		kvm_resched(vcpu);
> +		r =3D RESUME_GUEST;

huh?

> 		break;
>=20
> 	case BOOKE_INTERRUPT_EXTERNAL:
> 		kvmppc_account_exit(vcpu, EXT_INTR_EXITS);
> -		if (need_resched())
> -			cond_resched();
> +		kvm_resched(vcpu);

Why are we explicit about the resched? On book3s I just call =
kvm_resched(vcpu) before the switch().

> 		r =3D RESUME_GUEST;
> 		break;
>=20
> 	case BOOKE_INTERRUPT_DECREMENTER:
> -		/* Since we switched IVPR back to the host's value, the =
host
> -		 * handled this interrupt the moment we enabled =
interrupts.
> -		 * Now we just offer it a chance to reschedule the =
guest. */
> 		kvmppc_account_exit(vcpu, DEC_EXITS);
> -		if (need_resched())
> -			cond_resched();
> +		kvm_resched(vcpu);
> +		r =3D RESUME_GUEST;
> +		break;
> +
> +	case BOOKE_INTERRUPT_DOORBELL:
> +		kvmppc_account_exit(vcpu, DBELL_EXITS);
> +		kvm_resched(vcpu);
> +		r =3D RESUME_GUEST;
> +		break;
> +
> +	case BOOKE_INTERRUPT_GUEST_DBELL_CRIT:
> +		kvmppc_account_exit(vcpu, GDBELL_EXITS);
> +
> +		/*
> +		 * We are here because there is a pending guest =
interrupt
> +		 * which could not be delivered as MSR_CE or MSR_ME was =
not
> +		 * set.  Once we break from here we will retry delivery.
> +		 */
> 		r =3D RESUME_GUEST;
> 		break;
>=20
> +	case BOOKE_INTERRUPT_GUEST_DBELL:
> +		kvmppc_account_exit(vcpu, GDBELL_EXITS);
> +
> +		/*
> +		 * We are here because there is a pending guest =
interrupt
> +		 * which could not be delivered as MSR_EE was not set.  =
Once
> +		 * we break from here we will retry delivery.
> +		 */
> +		r =3D RESUME_GUEST;
> +		break;
> +
> +	case BOOKE_INTERRUPT_HV_PRIV:
> +		r =3D emulation_exit(run, vcpu);
> +		break;
> +
> 	case BOOKE_INTERRUPT_PROGRAM:
> -		if (vcpu->arch.shared->msr & MSR_PR) {
> +		if (vcpu->arch.shared->msr & (MSR_PR | MSR_GS)) {
> 			/* Program traps generated by user-level =
software must be handled
> 			 * by the guest kernel. */
> 			kvmppc_core_queue_program(vcpu, =
vcpu->arch.fault_esr);
> @@ -419,33 +628,7 @@ int kvmppc_handle_exit(struct kvm_run *run, =
struct kvm_vcpu *vcpu,
> 			break;
> 		}
>=20
> -		er =3D kvmppc_emulate_instruction(run, vcpu);
> -		switch (er) {
> -		case EMULATE_DONE:
> -			/* don't overwrite subtypes, just account =
kvm_stats */
> -			kvmppc_account_exit_stat(vcpu, =
EMULATED_INST_EXITS);
> -			/* Future optimization: only reload =
non-volatiles if
> -			 * they were actually modified by emulation. */
> -			r =3D RESUME_GUEST_NV;
> -			break;
> -		case EMULATE_DO_DCR:
> -			run->exit_reason =3D KVM_EXIT_DCR;
> -			r =3D RESUME_HOST;
> -			break;
> -		case EMULATE_FAIL:
> -			/* XXX Deliver Program interrupt to guest. */
> -			printk(KERN_CRIT "%s: emulation at %lx failed =
(%08x)\n",
> -			       __func__, vcpu->arch.regs.nip,
> -			       vcpu->arch.last_inst);
> -			/* For debugging, encode the failing instruction =
and
> -			 * report it to userspace. */
> -			run->hw.hardware_exit_reason =3D ~0ULL << 32;
> -			run->hw.hardware_exit_reason |=3D =
vcpu->arch.last_inst;
> -			r =3D RESUME_HOST;
> -			break;
> -		default:
> -			BUG();
> -		}
> +		r =3D emulation_exit(run, vcpu);
> 		break;
>=20
> 	case BOOKE_INTERRUPT_FP_UNAVAIL:
> @@ -510,6 +693,21 @@ int kvmppc_handle_exit(struct kvm_run *run, =
struct kvm_vcpu *vcpu,
> 		r =3D RESUME_GUEST;
> 		break;
>=20
> +#ifdef CONFIG_KVM_BOOKE_HV
> +	case BOOKE_INTERRUPT_HV_SYSCALL:
> +		if (!(vcpu->arch.shared->msr & MSR_PR)) {
> +			kvmppc_set_gpr(vcpu, 3, kvmppc_kvm_pv(vcpu));
> +		} else {
> +			/*
> +			 * hcall from guest userspace -- send privileged
> +			 * instruction program check.
> +			 */
> +			kvmppc_core_queue_program(vcpu, ESR_PPR);
> +		}
> +
> +		r =3D RESUME_GUEST;
> +		break;
> +#else
> 	case BOOKE_INTERRUPT_SYSCALL:
> 		if (!(vcpu->arch.shared->msr & MSR_PR) &&
> 		    (((u32)kvmppc_get_gpr(vcpu, 0)) =3D=3D =
KVM_SC_MAGIC_R0)) {
> @@ -523,6 +721,47 @@ int kvmppc_handle_exit(struct kvm_run *run, =
struct kvm_vcpu *vcpu,
> 		kvmppc_account_exit(vcpu, SYSCALL_EXITS);
> 		r =3D RESUME_GUEST;
> 		break;
> +#endif
> +
> +	case BOOKE_INTERRUPT_ITLB_MISS: {
> +		unsigned long eaddr =3D vcpu->arch.regs.nip;
> +		gpa_t gpaddr;
> +		gfn_t gfn;
> +		int gtlb_index;
> +
> +		r =3D RESUME_GUEST;
> +
> +		/* Check the guest TLB. */
> +		gtlb_index =3D kvmppc_mmu_itlb_index(vcpu, eaddr);
> +		if (gtlb_index < 0) {
> +			/* The guest didn't have a mapping for it. */
> +			kvmppc_booke_queue_irqprio(vcpu,
> +						   =
BOOKE_IRQPRIO_ITLB_MISS);
> +			kvmppc_mmu_itlb_miss(vcpu);
> +			kvmppc_account_exit(vcpu, ITLB_REAL_MISS_EXITS);
> +			break;
> +		}
> +
> +		kvmppc_account_exit(vcpu, ITLB_VIRT_MISS_EXITS);
> +
> +		gpaddr =3D kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr);
> +		gfn =3D gpaddr >> PAGE_SHIFT;
> +
> +		if (kvm_is_visible_gfn(vcpu->kvm, gfn)) {
> +			/* The guest TLB had a mapping, but the shadow =
TLB
> +			 * didn't. This could be because:
> +			 * a) the entry is mapping the host kernel, or
> +			 * b) the guest used a large mapping which we're =
faking
> +			 * Either way, we need to satisfy the fault =
without
> +			 * invoking the guest. */
> +			kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index);
> +		} else {
> +			/* Guest mapped and leaped at non-RAM! */
> +			kvmppc_booke_queue_irqprio(vcpu,
> +						   =
BOOKE_IRQPRIO_MACHINE_CHECK);

Are you sure? Couldn't this also be MMIO? That doesn't really improve =
the situation as executing from MMIO is tricky with the KVM model, but =
it's not necessarily bad. Oh well, I guess we'll have to do something =
and throwing an #MC isn't all that ugly.

> +		}
> +		break;
> +	}
>=20
> 	case BOOKE_INTERRUPT_DTLB_MISS: {
> 		unsigned long eaddr =3D vcpu->arch.fault_dear;
> @@ -578,45 +817,6 @@ int kvmppc_handle_exit(struct kvm_run *run, =
struct kvm_vcpu *vcpu,
> 		break;
> 	}
>=20
> -	case BOOKE_INTERRUPT_ITLB_MISS: {
> -		unsigned long eaddr =3D vcpu->arch.regs.nip;
> -		gpa_t gpaddr;
> -		gfn_t gfn;
> -		int gtlb_index;
> -
> -		r =3D RESUME_GUEST;
> -
> -		/* Check the guest TLB. */
> -		gtlb_index =3D kvmppc_mmu_itlb_index(vcpu, eaddr);
> -		if (gtlb_index < 0) {
> -			/* The guest didn't have a mapping for it. */
> -			kvmppc_booke_queue_irqprio(vcpu, =
BOOKE_IRQPRIO_ITLB_MISS);
> -			kvmppc_mmu_itlb_miss(vcpu);
> -			kvmppc_account_exit(vcpu, ITLB_REAL_MISS_EXITS);
> -			break;
> -		}
> -
> -		kvmppc_account_exit(vcpu, ITLB_VIRT_MISS_EXITS);
> -
> -		gpaddr =3D kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr);
> -		gfn =3D gpaddr >> PAGE_SHIFT;
> -
> -		if (kvm_is_visible_gfn(vcpu->kvm, gfn)) {
> -			/* The guest TLB had a mapping, but the shadow =
TLB
> -			 * didn't. This could be because:
> -			 * a) the entry is mapping the host kernel, or
> -			 * b) the guest used a large mapping which we're =
faking
> -			 * Either way, we need to satisfy the fault =
without
> -			 * invoking the guest. */
> -			kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index);
> -		} else {
> -			/* Guest mapped and leaped at non-RAM! */
> -			kvmppc_booke_queue_irqprio(vcpu, =
BOOKE_IRQPRIO_MACHINE_CHECK);

Ah, you just shoved the code around :)

> -		}
> -
> -		break;
> -	}
> -
> 	case BOOKE_INTERRUPT_DEBUG: {
> 		u32 dbsr;
>=20
> @@ -663,12 +863,15 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
> 	int r;
>=20
> 	vcpu->arch.regs.nip =3D 0;
> -	vcpu->arch.shared->msr =3D 0;
> -	vcpu->arch.shadow_msr =3D MSR_USER | MSR_DE | MSR_IS | MSR_DS;
> 	vcpu->arch.shared->pir =3D vcpu->vcpu_id;
> 	kvmppc_set_gpr(vcpu, 1, (16<<20) - 8); /* -8 for the callee-save =
LR slot */
> +	kvmppc_set_msr(vcpu, 0);
>=20
> +#ifndef CONFIG_KVM_BOOKE_HV
> +	vcpu->arch.shadow_msr =3D MSR_USER | MSR_DE | MSR_IS | MSR_DS;
> 	vcpu->arch.shadow_pid =3D 1;
> +	vcpu->arch.shared->msr =3D 0;
> +#endif
>=20
> 	/* Eye-catching numbers so we know if the guest takes an =
interrupt
> 	 * before it's programmed its own IVPR/IVORs. */
> @@ -749,8 +952,8 @@ static void get_sregs_base(struct kvm_vcpu *vcpu,
> 	sregs->u.e.csrr0 =3D vcpu->arch.csrr0;
> 	sregs->u.e.csrr1 =3D vcpu->arch.csrr1;
> 	sregs->u.e.mcsr =3D vcpu->arch.mcsr;
> -	sregs->u.e.esr =3D vcpu->arch.shared->esr;
> -	sregs->u.e.dear =3D vcpu->arch.shared->dar;
> +	sregs->u.e.esr =3D get_guest_esr(vcpu);
> +	sregs->u.e.dear =3D get_guest_dear(vcpu);
> 	sregs->u.e.tsr =3D vcpu->arch.tsr;
> 	sregs->u.e.tcr =3D vcpu->arch.tcr;
> 	sregs->u.e.dec =3D kvmppc_get_dec(vcpu, tb);
> @@ -767,8 +970,8 @@ static int set_sregs_base(struct kvm_vcpu *vcpu,
> 	vcpu->arch.csrr0 =3D sregs->u.e.csrr0;
> 	vcpu->arch.csrr1 =3D sregs->u.e.csrr1;
> 	vcpu->arch.mcsr =3D sregs->u.e.mcsr;
> -	vcpu->arch.shared->esr =3D sregs->u.e.esr;
> -	vcpu->arch.shared->dar =3D sregs->u.e.dear;
> +	set_guest_esr(vcpu, sregs->u.e.esr);
> +	set_guest_dear(vcpu, sregs->u.e.dear);
> 	vcpu->arch.vrsave =3D sregs->u.e.vrsave;
> 	kvmppc_set_tcr(vcpu, sregs->u.e.tcr);
>=20
> @@ -965,14 +1168,17 @@ void kvmppc_decrementer_func(unsigned long =
data)
>=20
> void kvmppc_booke_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
> {
> +	current->thread.kvm_vcpu =3D vcpu;
> }
>=20
> void kvmppc_booke_vcpu_put(struct kvm_vcpu *vcpu)
> {
> +	current->thread.kvm_vcpu =3D NULL;
> }
>=20
> int __init kvmppc_booke_init(void)
> {
> +#ifndef CONFIG_KVM_BOOKE_HV
> 	unsigned long ivor[16];
> 	unsigned long max_ivor =3D 0;
> 	int i;
> @@ -1015,7 +1221,7 @@ int __init kvmppc_booke_init(void)
> 	}
> 	flush_icache_range(kvmppc_booke_handlers,
> 	                   kvmppc_booke_handlers + max_ivor + =
kvmppc_handler_len);
> -
> +#endif /* !BOOKE_HV */
> 	return 0;
> }
>=20
> diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
> index 05d1d99..d53bcf2 100644
> --- a/arch/powerpc/kvm/booke.h
> +++ b/arch/powerpc/kvm/booke.h
> @@ -48,7 +48,20 @@
> #define BOOKE_IRQPRIO_PERFORMANCE_MONITOR 19
> /* Internal pseudo-irqprio for level triggered externals */
> #define BOOKE_IRQPRIO_EXTERNAL_LEVEL 20
> -#define BOOKE_IRQPRIO_MAX 20
> +#define BOOKE_IRQPRIO_DBELL 21
> +#define BOOKE_IRQPRIO_DBELL_CRIT 22
> +#define BOOKE_IRQPRIO_MAX 23

So was MAX wrong before or is it too big now?

> +
> +#define BOOKE_IRQMASK_EE ((1 << BOOKE_IRQPRIO_EXTERNAL_LEVEL) | \
> +			  (1 << BOOKE_IRQPRIO_PERFORMANCE_MONITOR) | \
> +			  (1 << BOOKE_IRQPRIO_DBELL) | \
> +			  (1 << BOOKE_IRQPRIO_DECREMENTER) | \
> +			  (1 << BOOKE_IRQPRIO_FIT) | \
> +			  (1 << BOOKE_IRQPRIO_EXTERNAL))
> +
> +#define BOOKE_IRQMASK_CE ((1 << BOOKE_IRQPRIO_DBELL_CRIT) | \
> +			  (1 << BOOKE_IRQPRIO_WATCHDOG) | \
> +			  (1 << BOOKE_IRQPRIO_CRITICAL))
>=20
> extern unsigned long kvmppc_booke_handlers;
>=20
> @@ -74,4 +87,13 @@ void kvmppc_vcpu_disable_spe(struct kvm_vcpu =
*vcpu);
> void kvmppc_booke_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
> void kvmppc_booke_vcpu_put(struct kvm_vcpu *vcpu);
>=20
> +enum int_class {
> +	INT_CLASS_NONCRIT,
> +	INT_CLASS_CRIT,
> +	INT_CLASS_MC,
> +	INT_CLASS_DBG,
> +};
> +
> +void kvmppc_set_pending_interrupt(struct kvm_vcpu *vcpu, enum =
int_class type);
> +
> #endif /* __KVM_BOOKE_H__ */
> diff --git a/arch/powerpc/kvm/booke_emulate.c =
b/arch/powerpc/kvm/booke_emulate.c
> index a4af03b..3eb7fc6 100644
> --- a/arch/powerpc/kvm/booke_emulate.c
> +++ b/arch/powerpc/kvm/booke_emulate.c
> @@ -99,6 +99,12 @@ int kvmppc_booke_emulate_op(struct kvm_run *run, =
struct kvm_vcpu *vcpu,
> 	return emulated;
> }
>=20
> +/*
> + * NOTE: some of these registers are not emulated on BOOKE_HV =
(GS-mode).
> + * Their backing store is in real registers, and these functions
> + * will return the wrong result if called for them in another context
> + * (such as debugging).
> + */
> int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int =
rs)
> {
> 	int emulated =3D EMULATE_DONE;
> @@ -122,9 +128,11 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu =
*vcpu, int sprn, int rs)
> 		kvmppc_set_tcr(vcpu, spr_val);
> 		break;
>=20
> -	/* Note: SPRG4-7 are user-readable. These values are
> -	 * loaded into the real SPRGs when resuming the
> -	 * guest. */
> +	/*
> +	 * Note: SPRG4-7 are user-readable.
> +	 * These values are loaded into the real SPRGs when resuming the
> +	 * guest (PR-mode only).
> +	 */
> 	case SPRN_SPRG4:
> 		vcpu->arch.shared->sprg4 =3D spr_val; break;
> 	case SPRN_SPRG5:
> @@ -136,6 +144,9 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu =
*vcpu, int sprn, int rs)
>=20
> 	case SPRN_IVPR:
> 		vcpu->arch.ivpr =3D spr_val;
> +#ifdef CONFIG_KVM_BOOKE_HV
> +		mtspr(SPRN_GIVPR, spr_val);
> +#endif
> 		break;
> 	case SPRN_IVOR0:
> 		vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] =3D spr_val;
> @@ -145,6 +156,9 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu =
*vcpu, int sprn, int rs)
> 		break;
> 	case SPRN_IVOR2:
> 		vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] =3D spr_val;
> +#ifdef CONFIG_KVM_BOOKE_HV
> +		mtspr(SPRN_GIVOR2, spr_val);
> +#endif
> 		break;
> 	case SPRN_IVOR3:
> 		vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] =3D spr_val;
> @@ -163,6 +177,9 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu =
*vcpu, int sprn, int rs)
> 		break;
> 	case SPRN_IVOR8:
> 		vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] =3D spr_val;
> +#ifdef CONFIG_KVM_BOOKE_HV
> +		mtspr(SPRN_GIVOR8, spr_val);
> +#endif
> 		break;
> 	case SPRN_IVOR9:
> 		vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] =3D spr_val;
> diff --git a/arch/powerpc/kvm/bookehv_interrupts.S =
b/arch/powerpc/kvm/bookehv_interrupts.S
> new file mode 100644
> index 0000000..9eaeebd
> --- /dev/null
> +++ b/arch/powerpc/kvm/bookehv_interrupts.S
> @@ -0,0 +1,587 @@
> +/*
> + * This program is free software; you can redistribute it and/or =
modify
> + * it under the terms of the GNU General Public License, version 2, =
as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  =
02110-1301, USA.
> + *
> + * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
> + *
> + * Author: Varun Sethi <varun.sethi@freescale.com>
> + * Author: Scott Wood <scotwood@freescale.com>
> + *
> + * This file is derived from arch/powerpc/kvm/booke_interrupts.S
> + */
> +
> +#include <asm/ppc_asm.h>
> +#include <asm/kvm_asm.h>
> +#include <asm/reg.h>
> +#include <asm/mmu-44x.h>
> +#include <asm/page.h>
> +#include <asm/asm-compat.h>
> +#include <asm/asm-offsets.h>
> +#include <asm/bitsperlong.h>
> +
> +#include "../kernel/head_booke.h" /* for THREAD_NORMSAVE() */
> +
> +#define GET_VCPU(vcpu, thread)	\
> +	PPC_LL	vcpu, THREAD_KVM_VCPU(thread)
> +
> +#define SET_VCPU(vcpu)		\
> +        PPC_STL	vcpu, (THREAD + THREAD_KVM_VCPU)(r2)
> +
> +#define LONGBYTES		(BITS_PER_LONG / 8)
> +
> +#define VCPU_GPR(n)     	(VCPU_GPRS + (n * LONGBYTES))
> +#define VCPU_GUEST_SPRG(n)	(VCPU_GUEST_SPRGS + (n * LONGBYTES))
> +
> +/* The host stack layout: */
> +#define HOST_R1         (0 * LONGBYTES) /* Implied by stwu. */
> +#define HOST_CALLEE_LR  (1 * LONGBYTES)
> +#define HOST_RUN        (2 * LONGBYTES) /* struct kvm_run */
> +/*
> + * r2 is special: it holds 'current', and it made nonvolatile in the
> + * kernel with the -ffixed-r2 gcc option.
> + */
> +#define HOST_R2         (3 * LONGBYTES)
> +#define HOST_NV_GPRS    (4 * LONGBYTES)
> +#define HOST_NV_GPR(n)  (HOST_NV_GPRS + ((n - 14) * LONGBYTES))
> +#define HOST_MIN_STACK_SIZE (HOST_NV_GPR(31) + LONGBYTES)
> +#define HOST_STACK_SIZE ((HOST_MIN_STACK_SIZE + 15) & ~15) /* Align. =
*/
> +#define HOST_STACK_LR   (HOST_STACK_SIZE + LONGBYTES) /* In caller =
stack frame. */
> +
> +#define NEED_EMU		0x00000001 /* emulation -- save nv regs =
*/
> +#define NEED_DEAR		0x00000002 /* save faulting DEAR */
> +#define NEED_ESR		0x00000004 /* save faulting ESR */
> +
> +/*
> + * On entry:
> + * r4 =3D vcpu, r5 =3D srr0, r6 =3D srr1
> + * saved in vcpu: cr, ctr, r3-r13
> + */
> +.macro kvm_handler_common intno, srr0, flags
> +	mfspr	r10, SPRN_PID
> +	lwz	r8, VCPU_HOST_PID(r4)
> +	PPC_LL	r11, VCPU_SHARED(r4)
> +	PPC_STL	r14, VCPU_GPR(r14)(r4) /* We need a non-volatile GPR. */
> +	li	r14, \intno
> +
> +	stw	r10, VCPU_GUEST_PID(r4)
> +	mtspr	SPRN_PID, r8
> +
> +	.if	\flags & NEED_EMU
> +	lwz	r9, VCPU_KVM(r4)

writing r9

> +	.endif
> +
> +#ifdef CONFIG_KVM_EXIT_TIMING
> +	/* save exit time */
> +1:	mfspr	r7, SPRN_TBRU
> +	mfspr	r8, SPRN_TBRL
> +	mfspr	r9, SPRN_TBRU

overwriting r9 again?

> +	cmpw	r9, r7
> +	PPC_STL	r8, VCPU_TIMING_EXIT_TBL(r4)
> +	bne-	1b
> +	PPC_STL	r9, VCPU_TIMING_EXIT_TBU(r4)
> +#endif
> +
> +	oris	r8, r6, MSR_CE@h
> +#ifndef CONFIG_64BIT

Double negation is always hard to read. Please reverse the ifdef :)

> +	stw	r6, (VCPU_SHARED_MSR + 4)(r11)
> +#else
> +	std	r6, (VCPU_SHARED_MSR)(r11)
> +#endif
> +	ori	r8, r8, MSR_ME | MSR_RI
> +	PPC_STL	r5, VCPU_PC(r4)
> +
> +	/*
> +	 * Make sure CE/ME/RI are set (if appropriate for exception =
type)
> +	 * whether or not the guest had it set.  Since mfmsr/mtmsr are
> +	 * somewhat expensive, skip in the common case where the guest
> +	 * had all these bits set (and thus they're still set if
> +	 * appropriate for the exception type).
> +	 */
> +	cmpw	r6, r8
> +	.if	\flags & NEED_EMU
> +	lwz	r9, KVM_LPID(r9)

And here r9 is already clobbered

> +	.endif
> +	beq	1f
> +	mfmsr	r7
> +	.if	\srr0 !=3D SPRN_MCSRR0 && \srr0 !=3D SPRN_CSRR0
> +	oris	r7, r7, MSR_CE@h
> +	.endif
> +	.if	\srr0 !=3D SPRN_MCSRR0
> +	ori	r7, r7, MSR_ME | MSR_RI
> +	.endif
> +	mtmsr	r7
> +1:
> +
> +	.if	\flags & NEED_EMU
> +	/*
> +	 * This assumes you have external PID support.
> +	 * To support a bookehv CPU without external PID, you'll
> +	 * need to look up the TLB entry and create a temporary mapping.
> +	 *
> +	 * FIXME: we don't currently handle if the lwepx faults.  =
PR-mode
> +	 * booke doesn't handle it either.  Since Linux doesn't use
> +	 * broadcast tlbivax anymore, the only way this should happen is
> +	 * if the guest maps its memory execute-but-not-read, or if we
> +	 * somehow take a TLB miss in the middle of this entry code and
> +	 * evict the relevant entry.  On e500mc, all kernel lowmem is
> +	 * bolted into TLB1 large page mappings, and we don't use
> +	 * broadcast invalidates, so we should not take a TLB miss here.
> +	 *
> +	 * Later we'll need to deal with faults here.  Disallowing guest
> +	 * mappings that are execute-but-not-read could be an option on
> +	 * e500mc, but not on chips with an LRAT if it is used.
> +	 */
> +
> +	mfspr	r3, SPRN_EPLC	/* will already have correct ELPID and =
EGS */
> +	PPC_STL	r15, VCPU_GPR(r15)(r4)
> +	PPC_STL	r16, VCPU_GPR(r16)(r4)
> +	PPC_STL	r17, VCPU_GPR(r17)(r4)
> +	PPC_STL	r18, VCPU_GPR(r18)(r4)
> +	PPC_STL	r19, VCPU_GPR(r19)(r4)
> +	mr	r8, r3
> +	PPC_STL	r20, VCPU_GPR(r20)(r4)
> +	rlwimi	r8, r6, EPC_EAS_SHIFT - MSR_IR_LG, EPC_EAS
> +	PPC_STL	r21, VCPU_GPR(r21)(r4)
> +	rlwimi	r8, r6, EPC_EPR_SHIFT - MSR_PR_LG, EPC_EPR
> +	PPC_STL	r22, VCPU_GPR(r22)(r4)
> +	rlwimi	r8, r10, EPC_EPID_SHIFT, EPC_EPID
> +	PPC_STL	r23, VCPU_GPR(r23)(r4)
> +	PPC_STL	r24, VCPU_GPR(r24)(r4)
> +	PPC_STL	r25, VCPU_GPR(r25)(r4)
> +	PPC_STL	r26, VCPU_GPR(r26)(r4)
> +	PPC_STL	r27, VCPU_GPR(r27)(r4)
> +	PPC_STL	r28, VCPU_GPR(r28)(r4)
> +	PPC_STL	r29, VCPU_GPR(r29)(r4)
> +	PPC_STL	r30, VCPU_GPR(r30)(r4)
> +	PPC_STL	r31, VCPU_GPR(r31)(r4)
> +	mtspr	SPRN_EPLC, r8
> +	isync
> +	lwepx	r9, 0, r5
> +	mtspr	SPRN_EPLC, r3
> +	stw	r9, VCPU_LAST_INST(r4)
> +	.endif
> +
> +	.if	\flags & NEED_ESR
> +	mfspr	r8, SPRN_ESR
> +	PPC_STL	r8, VCPU_FAULT_ESR(r4)
> +	.endif
> +
> +	.if	\flags & NEED_DEAR
> +	mfspr	r9, SPRN_DEAR
> +	PPC_STL	r9, VCPU_FAULT_DEAR(r4)
> +	.endif
> +
> +	b	kvmppc_resume_host
> +.endm
> +
> +/*
> + * For input register values, see =
arch/powerpc/include/asm/kvm_booke_hv_asm.h
> + */
> +.macro kvm_handler intno srr0, srr1, flags
> +_GLOBAL(kvmppc_handler_\intno\()_\srr1)
> +	GET_VCPU(r11, r10)
> +	PPC_STL r3, VCPU_GPR(r3)(r11)
> +	mfspr	r3, SPRN_SPRG_RSCRATCH0
> +	PPC_STL	r4, VCPU_GPR(r4)(r11)
> +	PPC_LL	r4, THREAD_NORMSAVE(0)(r10)
> +	PPC_STL	r5, VCPU_GPR(r5)(r11)
> +	PPC_STL	r13, VCPU_CR(r11)
> +	mfspr	r5, \srr0
> +	PPC_STL	r3, VCPU_GPR(r10)(r11)
> +	PPC_LL	r3, THREAD_NORMSAVE(2)(r10)
> +	PPC_STL	r6, VCPU_GPR(r6)(r11)
> +	PPC_STL	r4, VCPU_GPR(r11)(r11)
> +	mfspr	r6, \srr1
> +	PPC_STL	r7, VCPU_GPR(r7)(r11)
> +	PPC_STL	r8, VCPU_GPR(r8)(r11)
> +	PPC_STL	r9, VCPU_GPR(r9)(r11)
> +	PPC_STL r3, VCPU_GPR(r13)(r11)
> +	mfctr	r7
> +	PPC_STL	r12, VCPU_GPR(r12)(r11)
> +	PPC_STL	r7, VCPU_CTR(r11)
> +	mr	r4, r11
> +	kvm_handler_common \intno, \srr0, \flags
> +.endm
> +
> +.macro kvm_lvl_handler intno scratch srr0, srr1, flags
> +_GLOBAL(kvmppc_handler_\intno\()_\srr1)
> +	mfspr	r10, SPRN_SPRG_THREAD
> +	GET_VCPU(r11, r10)
> +	PPC_STL r3, VCPU_GPR(r3)(r11)
> +	mfspr	r3, \scratch
> +	PPC_STL	r4, VCPU_GPR(r4)(r11)
> +	PPC_LL	r4, GPR9(r8)
> +	PPC_STL	r5, VCPU_GPR(r5)(r11)
> +	PPC_STL	r9, VCPU_CR(r11)
> +	mfspr	r5, \srr0
> +	PPC_STL	r3, VCPU_GPR(r8)(r11)
> +	PPC_LL	r3, GPR10(r8)
> +	PPC_STL	r6, VCPU_GPR(r6)(r11)
> +	PPC_STL	r4, VCPU_GPR(r9)(r11)
> +	mfspr	r6, \srr1
> +	PPC_LL	r4, GPR11(r8)
> +	PPC_STL	r7, VCPU_GPR(r7)(r11)
> +	PPC_STL	r8, VCPU_GPR(r8)(r11)
> +	PPC_STL r3, VCPU_GPR(r10)(r11)
> +	mfctr	r7
> +	PPC_STL	r12, VCPU_GPR(r12)(r11)
> +	PPC_STL	r4, VCPU_GPR(r11)(r11)
> +	PPC_STL	r7, VCPU_CTR(r11)
> +	mr	r4, r11
> +	kvm_handler_common \intno, \srr0, \flags
> +.endm
> +
> +kvm_lvl_handler BOOKE_INTERRUPT_CRITICAL, \
> +	SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
> +kvm_lvl_handler BOOKE_INTERRUPT_MACHINE_CHECK, \
> +	SPRN_SPRG_RSCRATCH_MC, SPRN_MCSRR0, SPRN_MCSRR1, 0
> +kvm_handler BOOKE_INTERRUPT_DATA_STORAGE, \
> +	SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR)
> +kvm_handler BOOKE_INTERRUPT_INST_STORAGE, SPRN_SRR0, SPRN_SRR1, =
NEED_ESR
> +kvm_handler BOOKE_INTERRUPT_EXTERNAL, SPRN_SRR0, SPRN_SRR1, 0
> +kvm_handler BOOKE_INTERRUPT_ALIGNMENT, \
> +	SPRN_SRR0, SPRN_SRR1, (NEED_DEAR | NEED_ESR)
> +kvm_handler BOOKE_INTERRUPT_PROGRAM, SPRN_SRR0, SPRN_SRR1, NEED_ESR
> +kvm_handler BOOKE_INTERRUPT_FP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0
> +kvm_handler BOOKE_INTERRUPT_SYSCALL, SPRN_SRR0, SPRN_SRR1, 0
> +kvm_handler BOOKE_INTERRUPT_AP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0
> +kvm_handler BOOKE_INTERRUPT_DECREMENTER, SPRN_SRR0, SPRN_SRR1, 0
> +kvm_handler BOOKE_INTERRUPT_FIT, SPRN_SRR0, SPRN_SRR1, 0
> +kvm_lvl_handler BOOKE_INTERRUPT_WATCHDOG, \
> +	SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
> +kvm_handler BOOKE_INTERRUPT_DTLB_MISS, \
> +	SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR)
> +kvm_handler BOOKE_INTERRUPT_ITLB_MISS, SPRN_SRR0, SPRN_SRR1, 0
> +kvm_handler BOOKE_INTERRUPT_SPE_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0
> +kvm_handler BOOKE_INTERRUPT_SPE_FP_DATA, SPRN_SRR0, SPRN_SRR1, 0
> +kvm_handler BOOKE_INTERRUPT_SPE_FP_ROUND, SPRN_SRR0, SPRN_SRR1, 0
> +kvm_handler BOOKE_INTERRUPT_PERFORMANCE_MONITOR, SPRN_SRR0, =
SPRN_SRR1, 0
> +kvm_handler BOOKE_INTERRUPT_DOORBELL, SPRN_SRR0, SPRN_SRR1, 0
> +kvm_lvl_handler BOOKE_INTERRUPT_DOORBELL_CRITICAL, \
> +	SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
> +kvm_handler BOOKE_INTERRUPT_HV_PRIV, SPRN_SRR0, SPRN_SRR1, NEED_EMU
> +kvm_handler BOOKE_INTERRUPT_HV_SYSCALL, SPRN_SRR0, SPRN_SRR1, 0
> +kvm_handler BOOKE_INTERRUPT_GUEST_DBELL, SPRN_GSRR0, SPRN_GSRR1, 0
> +kvm_lvl_handler BOOKE_INTERRUPT_GUEST_DBELL_CRIT, \
> +	SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
> +kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \
> +	SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
> +kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \
> +	SPRN_SPRG_RSCRATCH_DBG, SPRN_DSRR0, SPRN_DSRR1, 0
> +
> +
> +/* Registers:
> + *  SPRG_SCRATCH0: guest r10
> + *  r4: vcpu pointer
> + *  r11: vcpu->arch.shared
> + *  r14: KVM exit number
> + */
> +_GLOBAL(kvmppc_resume_host)
> +	/* Save remaining volatile guest register state to vcpu. */
> +	mfspr	r3, SPRN_VRSAVE
> +	PPC_STL	r0, VCPU_GPR(r0)(r4)
> +	PPC_STL	r1, VCPU_GPR(r1)(r4)
> +	mflr	r5
> +	mfspr	r6, SPRN_SPRG4
> +	PPC_STL	r2, VCPU_GPR(r2)(r4)
> +	PPC_STL	r5, VCPU_LR(r4)
> +	mfspr	r7, SPRN_SPRG5
> +	PPC_STL	r3, VCPU_VRSAVE(r4)
> +	PPC_STL	r6, VCPU_SHARED_SPRG4(r11)
> +	mfspr	r8, SPRN_SPRG6
> +	PPC_STL	r7, VCPU_SHARED_SPRG5(r11)
> +	mfspr	r9, SPRN_SPRG7
> +	PPC_STL	r8, VCPU_SHARED_SPRG6(r11)
> +	mfxer	r3
> +	PPC_STL	r9, VCPU_SHARED_SPRG7(r11)
> +
> +	/* save guest MAS registers and restore host mas4 & mas6 */
> +	mfspr	r5, SPRN_MAS0
> +	PPC_STL	r3, VCPU_XER(r4)
> +	mfspr	r6, SPRN_MAS1
> +	stw	r5, VCPU_SHARED_MAS0(r11)
> +	mfspr	r7, SPRN_MAS2
> +	stw	r6, VCPU_SHARED_MAS1(r11)
> +#ifndef CONFIG_64BIT

see above

> +	stw	r7, (VCPU_SHARED_MAS2 + 4)(r11)
> +#else
> +	std	r7, (VCPU_SHARED_MAS2)(r11)
> +#endif
> +	mfspr	r5, SPRN_MAS3
> +	mfspr	r6, SPRN_MAS4
> +	stw	r5, VCPU_SHARED_MAS7_3+4(r11)
> +	mfspr	r7, SPRN_MAS6
> +	stw	r6, VCPU_SHARED_MAS4(r11)
> +	mfspr	r5, SPRN_MAS7
> +	lwz	r6, VCPU_HOST_MAS4(r4)
> +	stw	r7, VCPU_SHARED_MAS6(r11)
> +	lwz	r8, VCPU_HOST_MAS6(r4)
> +	mtspr	SPRN_MAS4, r6
> +	stw	r5, VCPU_SHARED_MAS7_3+0(r11)
> +	mtspr	SPRN_MAS6, r8
> +	mfspr	r3, SPRN_EPCR
> +	rlwinm	r3, r3, 0, ~SPRN_EPCR_DMIUH
> +	mtspr	SPRN_EPCR, r3
> +	isync
> +
> +	/* Restore host stack pointer */
> +	PPC_LL	r1, VCPU_HOST_STACK(r4)
> +	PPC_LL	r2, HOST_R2(r1)
> +
> +	/* Switch to kernel stack and jump to handler. */
> +	PPC_LL	r3, HOST_RUN(r1)
> +	mr	r5, r14 /* intno */
> +	mr	r14, r4 /* Save vcpu pointer. */
> +	bl	kvmppc_handle_exit
> +
> +	/* Restore vcpu pointer and the nonvolatiles we used. */
> +	mr	r4, r14
> +	PPC_LL	r14, VCPU_GPR(r14)(r4)
> +
> +	andi.	r5, r3, RESUME_FLAG_NV
> +	beq	skip_nv_load
> +	PPC_LL	r15, VCPU_GPR(r15)(r4)
> +	PPC_LL	r16, VCPU_GPR(r16)(r4)
> +	PPC_LL	r17, VCPU_GPR(r17)(r4)
> +	PPC_LL	r18, VCPU_GPR(r18)(r4)
> +	PPC_LL	r19, VCPU_GPR(r19)(r4)
> +	PPC_LL	r20, VCPU_GPR(r20)(r4)
> +	PPC_LL	r21, VCPU_GPR(r21)(r4)
> +	PPC_LL	r22, VCPU_GPR(r22)(r4)
> +	PPC_LL	r23, VCPU_GPR(r23)(r4)
> +	PPC_LL	r24, VCPU_GPR(r24)(r4)
> +	PPC_LL	r25, VCPU_GPR(r25)(r4)
> +	PPC_LL	r26, VCPU_GPR(r26)(r4)
> +	PPC_LL	r27, VCPU_GPR(r27)(r4)
> +	PPC_LL	r28, VCPU_GPR(r28)(r4)
> +	PPC_LL	r29, VCPU_GPR(r29)(r4)
> +	PPC_LL	r30, VCPU_GPR(r30)(r4)
> +	PPC_LL	r31, VCPU_GPR(r31)(r4)
> +skip_nv_load:
> +	/* Should we return to the guest? */
> +	andi.	r5, r3, RESUME_FLAG_HOST
> +	beq	lightweight_exit
> +
> +	srawi	r3, r3, 2 /* Shift -ERR back down. */
> +
> +heavyweight_exit:
> +	/* Not returning to guest. */
> +	PPC_LL	r5, HOST_STACK_LR(r1)
> +
> +	/*
> +	 * We already saved guest volatile register state; now save the
> +	 * non-volatiles.
> +	 */
> +
> +	PPC_STL	r15, VCPU_GPR(r15)(r4)
> +	PPC_STL	r16, VCPU_GPR(r16)(r4)
> +	PPC_STL	r17, VCPU_GPR(r17)(r4)
> +	PPC_STL	r18, VCPU_GPR(r18)(r4)
> +	PPC_STL	r19, VCPU_GPR(r19)(r4)
> +	PPC_STL	r20, VCPU_GPR(r20)(r4)
> +	PPC_STL	r21, VCPU_GPR(r21)(r4)
> +	PPC_STL	r22, VCPU_GPR(r22)(r4)
> +	PPC_STL	r23, VCPU_GPR(r23)(r4)
> +	PPC_STL	r24, VCPU_GPR(r24)(r4)
> +	PPC_STL	r25, VCPU_GPR(r25)(r4)
> +	PPC_STL	r26, VCPU_GPR(r26)(r4)
> +	PPC_STL	r27, VCPU_GPR(r27)(r4)
> +	PPC_STL	r28, VCPU_GPR(r28)(r4)
> +	PPC_STL	r29, VCPU_GPR(r29)(r4)
> +	PPC_STL	r30, VCPU_GPR(r30)(r4)
> +	PPC_STL	r31, VCPU_GPR(r31)(r4)
> +
> +	/* Load host non-volatile register state from host stack. */
> +	PPC_LL	r14, HOST_NV_GPR(r14)(r1)
> +	PPC_LL	r15, HOST_NV_GPR(r15)(r1)
> +	PPC_LL	r16, HOST_NV_GPR(r16)(r1)
> +	PPC_LL	r17, HOST_NV_GPR(r17)(r1)
> +	PPC_LL	r18, HOST_NV_GPR(r18)(r1)
> +	PPC_LL	r19, HOST_NV_GPR(r19)(r1)
> +	PPC_LL	r20, HOST_NV_GPR(r20)(r1)
> +	PPC_LL	r21, HOST_NV_GPR(r21)(r1)
> +	PPC_LL	r22, HOST_NV_GPR(r22)(r1)
> +	PPC_LL	r23, HOST_NV_GPR(r23)(r1)
> +	PPC_LL	r24, HOST_NV_GPR(r24)(r1)
> +	PPC_LL	r25, HOST_NV_GPR(r25)(r1)
> +	PPC_LL	r26, HOST_NV_GPR(r26)(r1)
> +	PPC_LL	r27, HOST_NV_GPR(r27)(r1)
> +	PPC_LL	r28, HOST_NV_GPR(r28)(r1)
> +	PPC_LL	r29, HOST_NV_GPR(r29)(r1)
> +	PPC_LL	r30, HOST_NV_GPR(r30)(r1)
> +	PPC_LL	r31, HOST_NV_GPR(r31)(r1)
> +
> +	/* Return to kvm_vcpu_run(). */
> +	mtlr	r5
> +	addi	r1, r1, HOST_STACK_SIZE
> +	/* r3 still contains the return code from kvmppc_handle_exit(). =
*/
> +	blr
> +
> +/* Registers:
> + *  r3: kvm_run pointer
> + *  r4: vcpu pointer
> + */
> +_GLOBAL(__kvmppc_vcpu_run)
> +	stwu	r1, -HOST_STACK_SIZE(r1)
> +	PPC_STL	r1, VCPU_HOST_STACK(r4)	/* Save stack pointer to vcpu. =
*/
> +
> +	/* Save host state to stack. */
> +	PPC_STL	r3, HOST_RUN(r1)
> +	mflr	r3
> +	PPC_STL	r3, HOST_STACK_LR(r1)
> +
> +	/* Save host non-volatile register state to stack. */
> +	PPC_STL	r14, HOST_NV_GPR(r14)(r1)
> +	PPC_STL	r15, HOST_NV_GPR(r15)(r1)
> +	PPC_STL	r16, HOST_NV_GPR(r16)(r1)
> +	PPC_STL	r17, HOST_NV_GPR(r17)(r1)
> +	PPC_STL	r18, HOST_NV_GPR(r18)(r1)
> +	PPC_STL	r19, HOST_NV_GPR(r19)(r1)
> +	PPC_STL	r20, HOST_NV_GPR(r20)(r1)
> +	PPC_STL	r21, HOST_NV_GPR(r21)(r1)
> +	PPC_STL	r22, HOST_NV_GPR(r22)(r1)
> +	PPC_STL	r23, HOST_NV_GPR(r23)(r1)
> +	PPC_STL	r24, HOST_NV_GPR(r24)(r1)
> +	PPC_STL	r25, HOST_NV_GPR(r25)(r1)
> +	PPC_STL	r26, HOST_NV_GPR(r26)(r1)
> +	PPC_STL	r27, HOST_NV_GPR(r27)(r1)
> +	PPC_STL	r28, HOST_NV_GPR(r28)(r1)
> +	PPC_STL	r29, HOST_NV_GPR(r29)(r1)
> +	PPC_STL	r30, HOST_NV_GPR(r30)(r1)
> +	PPC_STL	r31, HOST_NV_GPR(r31)(r1)
> +
> +	/* Load guest non-volatiles. */
> +	PPC_LL	r14, VCPU_GPR(r14)(r4)
> +	PPC_LL	r15, VCPU_GPR(r15)(r4)
> +	PPC_LL	r16, VCPU_GPR(r16)(r4)
> +	PPC_LL	r17, VCPU_GPR(r17)(r4)
> +	PPC_LL	r18, VCPU_GPR(r18)(r4)
> +	PPC_LL	r19, VCPU_GPR(r19)(r4)
> +	PPC_LL	r20, VCPU_GPR(r20)(r4)
> +	PPC_LL	r21, VCPU_GPR(r21)(r4)
> +	PPC_LL	r22, VCPU_GPR(r22)(r4)
> +	PPC_LL	r23, VCPU_GPR(r23)(r4)
> +	PPC_LL	r24, VCPU_GPR(r24)(r4)
> +	PPC_LL	r25, VCPU_GPR(r25)(r4)
> +	PPC_LL	r26, VCPU_GPR(r26)(r4)
> +	PPC_LL	r27, VCPU_GPR(r27)(r4)
> +	PPC_LL	r28, VCPU_GPR(r28)(r4)
> +	PPC_LL	r29, VCPU_GPR(r29)(r4)
> +	PPC_LL	r30, VCPU_GPR(r30)(r4)
> +	PPC_LL	r31, VCPU_GPR(r31)(r4)
> +
> +
> +lightweight_exit:
> +	PPC_STL	r2, HOST_R2(r1)
> +
> +	mfspr	r3, SPRN_PID
> +	stw	r3, VCPU_HOST_PID(r4)
> +	lwz	r3, VCPU_GUEST_PID(r4)
> +	mtspr	SPRN_PID, r3
> +
> +	/* Save vcpu pointer for the exception handlers
> +	 * must be done before loading guest r2.
> +	 */
> +//	SET_VCPU(r4)

hm?

> +
> +	PPC_LL	r11, VCPU_SHARED(r4)
> +	/* Save host mas4 and mas6 and load guest MAS registers */
> +	mfspr	r3, SPRN_MAS4
> +	stw	r3, VCPU_HOST_MAS4(r4)
> +	mfspr	r3, SPRN_MAS6
> +	stw	r3, VCPU_HOST_MAS6(r4)
> +	lwz	r3, VCPU_SHARED_MAS0(r11)
> +	lwz	r5, VCPU_SHARED_MAS1(r11)
> +#ifndef CONFIG_64BIT

see above

> +	lwz	r6, (VCPU_SHARED_MAS2 + 4)(r11)
> +#else
> +	ld	r6, (VCPU_SHARED_MAS2)(r11)
> +#endif
> +	lwz	r7, VCPU_SHARED_MAS7_3+4(r11)
> +	lwz	r8, VCPU_SHARED_MAS4(r11)
> +	mtspr	SPRN_MAS0, r3
> +	mtspr	SPRN_MAS1, r5
> +	mtspr	SPRN_MAS2, r6
> +	mtspr	SPRN_MAS3, r7
> +	mtspr	SPRN_MAS4, r8
> +	lwz	r3, VCPU_SHARED_MAS6(r11)
> +	lwz	r5, VCPU_SHARED_MAS7_3+0(r11)
> +	mtspr	SPRN_MAS6, r3
> +	mtspr	SPRN_MAS7, r5
> +	/* Disable MAS register updates via exception */
> +	mfspr	r3, SPRN_EPCR
> +	oris	r3, r3, SPRN_EPCR_DMIUH@h
> +	mtspr	SPRN_EPCR, r3

Shouldn't this happen before you set the MAS registers? :)

> +
> +	/*
> +	 * Host interrupt handlers may have clobbered these =
guest-readable
> +	 * SPRGs, so we need to reload them here with the guest's =
values.
> +	 */
> +	lwz	r3, VCPU_VRSAVE(r4)
> +	lwz	r5, VCPU_SHARED_SPRG4(r11)
> +	mtspr	SPRN_VRSAVE, r3
> +	lwz	r6, VCPU_SHARED_SPRG5(r11)
> +	mtspr	SPRN_SPRG4W, r5
> +	lwz	r7, VCPU_SHARED_SPRG6(r11)
> +	mtspr	SPRN_SPRG5W, r6
> +	lwz	r8, VCPU_SHARED_SPRG7(r11)
> +	mtspr	SPRN_SPRG6W, r7
> +	mtspr	SPRN_SPRG7W, r8
> +
> +	/* Load some guest volatiles. */
> +	PPC_LL	r3, VCPU_LR(r4)
> +	PPC_LL	r5, VCPU_XER(r4)
> +	PPC_LL	r6, VCPU_CTR(r4)
> +	PPC_LL	r7, VCPU_CR(r4)
> +	PPC_LL	r8, VCPU_PC(r4)
> +#ifndef CONFIG_64BIT
> +	lwz	r9, (VCPU_SHARED_MSR + 4)(r11)
> +#else
> +	ld	r9, (VCPU_SHARED_MSR)(r11)
> +#endif
> +	PPC_LL	r0, VCPU_GPR(r0)(r4)
> +	PPC_LL	r1, VCPU_GPR(r1)(r4)
> +	PPC_LL	r2, VCPU_GPR(r2)(r4)
> +	PPC_LL	r10, VCPU_GPR(r10)(r4)
> +	PPC_LL	r11, VCPU_GPR(r11)(r4)
> +	PPC_LL	r12, VCPU_GPR(r12)(r4)
> +	PPC_LL	r13, VCPU_GPR(r13)(r4)
> +	mtlr	r3
> +	mtxer	r5
> +	mtctr	r6
> +	mtcr	r7
> +	mtsrr0	r8
> +	mtsrr1	r9

Are you sure this should be shared->msr, not shadow_msr?

> +
> +#ifdef CONFIG_KVM_EXIT_TIMING
> +	/* save enter time */
> +1:
> +	mfspr	r6, SPRN_TBRU
> +	mfspr	r7, SPRN_TBRL
> +	mfspr	r8, SPRN_TBRU
> +	cmpw	r8, r6
> +	PPC_STL	r7, VCPU_TIMING_LAST_ENTER_TBL(r4)
> +	bne	1b
> +	PPC_STL	r8, VCPU_TIMING_LAST_ENTER_TBU(r4)
> +#endif
> +
> +	/* Finish loading guest volatiles and jump to guest. */
> +	PPC_LL	r5, VCPU_GPR(r5)(r4)
> +	PPC_LL	r6, VCPU_GPR(r6)(r4)
> +	PPC_LL	r7, VCPU_GPR(r7)(r4)
> +	PPC_LL	r8, VCPU_GPR(r8)(r4)
> +	PPC_LL	r9, VCPU_GPR(r9)(r4)
> +
> +	PPC_LL	r3, VCPU_GPR(r3)(r4)
> +	PPC_LL	r4, VCPU_GPR(r4)(r4)
> +	rfi
> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> index 42701e5..f9c62dd 100644
> --- a/arch/powerpc/kvm/powerpc.c
> +++ b/arch/powerpc/kvm/powerpc.c
> @@ -109,6 +109,11 @@ int kvmppc_sanity_check(struct kvm_vcpu *vcpu)
> 		goto out;
> #endif
>=20
> +#ifdef CONFIG_KVM_BOOKE_HV
> +	if (!cpu_has_feature(CPU_FTR_EMB_HV))
> +		goto out;
> +#endif
> +
> 	r =3D true;
>=20
> out:
> diff --git a/arch/powerpc/kvm/timing.h b/arch/powerpc/kvm/timing.h
> index 8167d42..bf191e7 100644
> --- a/arch/powerpc/kvm/timing.h
> +++ b/arch/powerpc/kvm/timing.h
> @@ -93,6 +93,12 @@ static inline void kvmppc_account_exit_stat(struct =
kvm_vcpu *vcpu, int type)
> 	case SIGNAL_EXITS:
> 		vcpu->stat.signal_exits++;
> 		break;
> +	case DBELL_EXITS:
> +		vcpu->stat.dbell_exits++;
> +		break;
> +	case GDBELL_EXITS:
> +		vcpu->stat.gdbell_exits++;
> +		break;
> 	}
> }
>=20
> --=20
> 1.7.7.rc3.4.g8d714
>=20
>=20

^ permalink raw reply

* Re: [RFC PATCH 15/16] KVM: PPC: booke: standard PPC floating point support
From: Alexander Graf @ 2012-01-09 17:48 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <20111221013445.GO8378@schlenkerla.am.freescale.net>


On 21.12.2011, at 02:34, Scott Wood wrote:

> e500mc has a normal PPC FPU, rather than SPE which is found
> on e500v1/v2.
>=20
> Based on code from Liu Yu <yu.liu@freescale.com>.
>=20
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> arch/powerpc/include/asm/system.h |    1 +
> arch/powerpc/kvm/booke.c          |   44 =
+++++++++++++++++++++++++++++++++++++
> arch/powerpc/kvm/booke.h          |   30 +++++++++++++++++++++++++
> 3 files changed, 75 insertions(+), 0 deletions(-)
>=20
> diff --git a/arch/powerpc/include/asm/system.h =
b/arch/powerpc/include/asm/system.h
> index e30a13d..0561356 100644
> --- a/arch/powerpc/include/asm/system.h
> +++ b/arch/powerpc/include/asm/system.h
> @@ -140,6 +140,7 @@ extern void via_cuda_init(void);
> extern void read_rtc_time(void);
> extern void pmac_find_display(void);
> extern void giveup_fpu(struct task_struct *);
> +extern void load_up_fpu(void);
> extern void disable_kernel_fp(void);
> extern void enable_kernel_fp(void);
> extern void flush_fp_to_thread(struct task_struct *);
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index cf63b93..4bf43f9 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -460,6 +460,11 @@ void kvmppc_core_prepare_to_enter(struct kvm_vcpu =
*vcpu)
> int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
> {
> 	int ret;
> +#ifdef CONFIG_PPC_FPU
> +	unsigned int fpscr;
> +	int fpexc_mode;
> +	u64 fpr[32];
> +#endif
>=20
> 	if (!vcpu->arch.sane) {
> 		kvm_run->exit_reason =3D KVM_EXIT_INTERNAL_ERROR;
> @@ -482,7 +487,46 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, =
struct kvm_vcpu *vcpu)
> 	}
>=20
> 	kvm_guest_enter();
> +
> +#ifdef CONFIG_PPC_FPU
> +	/* Save userspace FPU state in stack */
> +	enable_kernel_fp();
> +	memcpy(fpr, current->thread.fpr, sizeof(current->thread.fpr));
> +	fpscr =3D current->thread.fpscr.val;
> +	fpexc_mode =3D current->thread.fpexc_mode;
> +
> +	/* Restore guest FPU state to thread */
> +	memcpy(current->thread.fpr, vcpu->arch.fpr, =
sizeof(vcpu->arch.fpr));
> +	current->thread.fpscr.val =3D vcpu->arch.fpscr;
> +
> +	/*
> +	 * Since we can't trap on MSR_FP in GS-mode, we consider the =
guest
> +	 * as always using the FPU.  Kernel usage of FP (via
> +	 * enable_kernel_fp()) in this thread must not occur while
> +	 * vcpu->fpu_active is set.
> +	 */
> +	vcpu->fpu_active =3D 1;
> +
> +	kvmppc_load_guest_fp(vcpu);
> +#endif

Do you think it's possible to combine this with the book3s_pr code, so =
we don't duplicate too much here?

> +
> 	ret =3D __kvmppc_vcpu_run(kvm_run, vcpu);
> +
> +#ifdef CONFIG_PPC_FPU
> +	kvmppc_save_guest_fp(vcpu);
> +
> +	vcpu->fpu_active =3D 0;
> +
> +	/* Save guest FPU state from thread */
> +	memcpy(vcpu->arch.fpr, current->thread.fpr, =
sizeof(vcpu->arch.fpr));
> +	vcpu->arch.fpscr =3D current->thread.fpscr.val;
> +
> +	/* Restore userspace FPU state from stack */
> +	memcpy(current->thread.fpr, fpr, sizeof(current->thread.fpr));
> +	current->thread.fpscr.val =3D fpscr;
> +	current->thread.fpexc_mode =3D fpexc_mode;
> +#endif
> +
> 	kvm_guest_exit();
>=20
> out:
> diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
> index d53bcf2..3bf5eda 100644
> --- a/arch/powerpc/kvm/booke.h
> +++ b/arch/powerpc/kvm/booke.h
> @@ -96,4 +96,34 @@ enum int_class {
>=20
> void kvmppc_set_pending_interrupt(struct kvm_vcpu *vcpu, enum =
int_class type);
>=20
> +/*
> + * Load up guest vcpu FP state if it's needed.
> + * It also set the MSR_FP in thread so that host know
> + * we're holding FPU, and then host can help to save
> + * guest vcpu FP state if other threads require to use FPU.
> + * This simulates an FP unavailable fault.
> + *
> + * It requires to be called with preemption disabled.
> + */
> +static inline void kvmppc_load_guest_fp(struct kvm_vcpu *vcpu)
> +{
> +#ifdef CONFIG_PPC_FPU
> +	if (vcpu->fpu_active && !(current->thread.regs->msr & MSR_FP)) {
> +		load_up_fpu();
> +		current->thread.regs->msr |=3D MSR_FP;

I'm having a hard time to grasp when shared->msr, shadow_msr and =
regs->msr is used in your code :).


Alex

^ permalink raw reply

* [PATCH 1/2] dtc: Implement -d option to write out a dependency file
From: Stephen Warren @ 2012-01-09 18:38 UTC (permalink / raw)
  To: Michal Marek, Jon Loeliger, David Gibson
  Cc: Jonas Bonn, Michal Simek, Russell King, linux-c6x-dev,
	Arnd Bergmann, Aurelien Jacquiot, Devicetree Discuss,
	microblaze-uclinux, linux-kbuild, linux-kernel, Rob Herring,
	Paul Mackerras, Mark Salter, Stephen Warren, linuxppc-dev, linux,
	linux-arm-kernel

This will allow callers to rebuild .dtb files when any of the /include/d
.dtsi files are modified, not just the top-level .dts file.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
This patch is against the Linux kernel's copy of dtc, but it applies to
upstream dtc with a couple of trivial conflicts. I can post a version for
upstream dtc as well if desired.

I have only tested this series for ARM.

 scripts/dtc/dtc.c    |   22 +++++++++++++++++++++-
 scripts/dtc/srcpos.c |    6 ++++++
 scripts/dtc/srcpos.h |    1 +
 3 files changed, 28 insertions(+), 1 deletions(-)

diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index cbc0193..27ecf06 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -71,6 +71,7 @@ static void  __attribute__ ((noreturn)) usage(void)
 	fprintf(stderr, "\t\t\tasm - assembler source\n");
 	fprintf(stderr, "\t-V <output version>\n");
 	fprintf(stderr, "\t\tBlob version to produce, defaults to %d (relevant for dtb\n\t\tand asm output only)\n", DEFAULT_FDT_VERSION);
+	fprintf(stderr, "\t-d <output dependency file>\n");
 	fprintf(stderr, "\t-R <number>\n");
 	fprintf(stderr, "\t\tMake space for <number> reserve map entries (relevant for \n\t\tdtb and asm output only)\n");
 	fprintf(stderr, "\t-S <bytes>\n");
@@ -99,6 +100,7 @@ int main(int argc, char *argv[])
 	const char *inform = "dts";
 	const char *outform = "dts";
 	const char *outname = "-";
+	const char *depname = NULL;
 	int force = 0, check = 0, sort = 0;
 	const char *arg;
 	int opt;
@@ -111,7 +113,8 @@ int main(int argc, char *argv[])
 	minsize    = 0;
 	padsize    = 0;
 
-	while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:vH:s")) != EOF) {
+	while ((opt = getopt(argc, argv, "hI:O:o:V:d:R:S:p:fcqb:vH:s"))
+			!= EOF) {
 		switch (opt) {
 		case 'I':
 			inform = optarg;
@@ -125,6 +128,9 @@ int main(int argc, char *argv[])
 		case 'V':
 			outversion = strtol(optarg, NULL, 0);
 			break;
+		case 'd':
+			depname = optarg;
+			break;
 		case 'R':
 			reservenum = strtol(optarg, NULL, 0);
 			break;
@@ -188,6 +194,15 @@ int main(int argc, char *argv[])
 	fprintf(stderr, "DTC: %s->%s  on file \"%s\"\n",
 		inform, outform, arg);
 
+	if (depname) {
+		depfile = fopen(depname, "w");
+		if (!depfile)
+			die("Couldn't open dependency file %s: %s\n", depname,
+			    strerror(errno));
+		fputs(outname, depfile);
+		fputc(':', depfile);
+	}
+
 	if (streq(inform, "dts"))
 		bi = dt_from_source(arg);
 	else if (streq(inform, "fs"))
@@ -197,6 +212,11 @@ int main(int argc, char *argv[])
 	else
 		die("Unknown input format \"%s\"\n", inform);
 
+	if (depfile) {
+		fputc('\n', depfile);
+		fclose(depfile);
+	}
+
 	if (cmdline_boot_cpuid != -1)
 		bi->boot_cpuid_phys = cmdline_boot_cpuid;
 
diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c
index 2dbc874..93b3533 100644
--- a/scripts/dtc/srcpos.c
+++ b/scripts/dtc/srcpos.c
@@ -40,6 +40,7 @@ static char *dirname(const char *path)
 	return NULL;
 }
 
+FILE *depfile; /* = NULL */
 struct srcfile_state *current_srcfile; /* = NULL */
 
 /* Detect infinite include recursion. */
@@ -67,6 +68,11 @@ FILE *srcfile_relative_open(const char *fname, char **fullnamep)
 			    strerror(errno));
 	}
 
+	if (depfile) {
+		fputc(' ', depfile);
+		fputs(fullname, depfile);
+	}
+
 	if (fullnamep)
 		*fullnamep = fullname;
 	else
diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h
index bd7966e..ce980ca 100644
--- a/scripts/dtc/srcpos.h
+++ b/scripts/dtc/srcpos.h
@@ -30,6 +30,7 @@ struct srcfile_state {
 	struct srcfile_state *prev;
 };
 
+extern FILE *depfile; /* = NULL */
 extern struct srcfile_state *current_srcfile; /* = NULL */
 
 FILE *srcfile_relative_open(const char *fname, char **fullnamep);
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH 2/2] Kbuild: Use dtc's -d (dependency) option
From: Stephen Warren @ 2012-01-09 18:38 UTC (permalink / raw)
  To: Michal Marek, Jon Loeliger, David Gibson
  Cc: Jonas Bonn, Michal Simek, Russell King, linux-c6x-dev,
	Arnd Bergmann, Aurelien Jacquiot, Devicetree Discuss,
	microblaze-uclinux, linux-kbuild, linux-kernel, Rob Herring,
	Paul Mackerras, Mark Salter, Stephen Warren, linuxppc-dev, linux,
	linux-arm-kernel
In-Reply-To: <1326134295-15547-1-git-send-email-swarren@nvidia.com>

This hooks dtc into Kbuild's dependency system.

Thus, for example, "make dtbs" will rebuild tegra-harmony.dtb if only
tegra20.dtsi has changed yet tegra-harmony.dts has not. The previous
lack of this feature recently caused me to have very confusing "git
bisect" results.

For ARM, it's obvious what to add to $(targets). I'm not familiar enough
with other architectures to know what to add there. Powerpc appears to
already add various .dtb files into $(targets), but the other archs may
need something added to $(targets) to work.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
I have only tested this series for ARM.

 arch/arm/boot/Makefile        |    6 ++++--
 arch/c6x/boot/Makefile        |    2 +-
 arch/microblaze/boot/Makefile |    2 +-
 arch/openrisc/boot/Makefile   |    4 ++--
 arch/powerpc/boot/Makefile    |    4 ++--
 scripts/Makefile.lib          |    2 +-
 6 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index 1338cf0..c72730d 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -62,9 +62,11 @@ $(obj)/zImage-dtb.%:	$(obj)/%.dtb $(obj)/zImage
 
 endif
 
+targets += $(dtb-y)
+
 # Rule to build device tree blobs
-$(obj)/%.dtb: $(src)/dts/%.dts
-	$(call cmd,dtc)
+$(obj)/%.dtb: $(src)/dts/%.dts FORCE
+	$(call if_changed_dep,dtc)
 
 $(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y))
 
diff --git a/arch/c6x/boot/Makefile b/arch/c6x/boot/Makefile
index ecca820..6891257 100644
--- a/arch/c6x/boot/Makefile
+++ b/arch/c6x/boot/Makefile
@@ -13,7 +13,7 @@ obj-y += linked_dtb.o
 endif
 
 $(obj)/%.dtb: $(src)/dts/%.dts FORCE
-	$(call cmd,dtc)
+	$(call if_changed_dep,dtc)
 
 quiet_cmd_cp = CP      $< $@$2
 	cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false)
diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile
index 4c4e58e..0c796cf 100644
--- a/arch/microblaze/boot/Makefile
+++ b/arch/microblaze/boot/Makefile
@@ -53,6 +53,6 @@ $(obj)/simpleImage.%: vmlinux FORCE
 DTC_FLAGS := -p 1024
 
 $(obj)/%.dtb: $(src)/dts/%.dts FORCE
-	$(call cmd,dtc)
+	$(call if_changed_dep,dtc)
 
 clean-files += *.dtb simpleImage.*.unstrip linux.bin.ub
diff --git a/arch/openrisc/boot/Makefile b/arch/openrisc/boot/Makefile
index 98ca185..0995835 100644
--- a/arch/openrisc/boot/Makefile
+++ b/arch/openrisc/boot/Makefile
@@ -11,5 +11,5 @@ clean-files := *.dtb.S
 
 #DTC_FLAGS ?= -p 1024
 
-$(obj)/%.dtb: $(src)/dts/%.dts
-	$(call cmd,dtc)
+$(obj)/%.dtb: $(src)/dts/%.dts FORCE
+	$(call if_changed_dep,dtc)
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 15986e7..8844a17 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -345,8 +345,8 @@ $(obj)/treeImage.%: vmlinux $(obj)/%.dtb $(wrapperbits)
 	$(call if_changed,wrap,treeboot-$*,,$(obj)/$*.dtb)
 
 # Rule to build device tree blobs
-$(obj)/%.dtb: $(src)/dts/%.dts
-	$(call cmd,dtc)
+$(obj)/%.dtb: $(src)/dts/%.dts FORCE
+	$(call if_changed_dep,dtc)
 
 # If there isn't a platform selected then just strip the vmlinux.
 ifeq (,$(image-y))
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 5d986d9..7bae316 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -264,7 +264,7 @@ $(obj)/%.dtb.S: $(obj)/%.dtb
 	$(call cmd,dt_S_dtb)
 
 quiet_cmd_dtc = DTC     $@
-cmd_dtc = $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) $<
+cmd_dtc = $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) -d $(depfile) $<
 
 # Bzip2
 # ---------------------------------------------------------------------------
-- 
1.7.0.4

^ permalink raw reply related

* Re: [RFC PATCH 01/16] powerpc/booke: Set CPU_FTR_DEBUG_LVL_EXC on 32-bit
From: Scott Wood @ 2012-01-09 19:14 UTC (permalink / raw)
  To: Alexander Graf; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <C57ECE6B-1040-40BC-B7C7-5107533A2DC2@suse.de>

On 01/09/2012 09:21 AM, Alexander Graf wrote:
> 
> On 21.12.2011, at 02:34, Scott Wood wrote:
> 
>> Currently 32-bit only cares about this for choice of exception
>> vector, which is done in core-specific code.  However, KVM will
>> want to distinguish as well.
>>
>> Signed-off-by: Scott Wood <scottwood@freescale.com>
>> ---
>> arch/powerpc/include/asm/cputable.h |    5 +++--
>> 1 files changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
>> index e30442c..033ad30 100644
>> --- a/arch/powerpc/include/asm/cputable.h
>> +++ b/arch/powerpc/include/asm/cputable.h
>> @@ -375,7 +375,8 @@ extern const char *powerpc_base_platform;
>> #define CPU_FTRS_47X	(CPU_FTRS_440x6)
>> #define CPU_FTRS_E200	(CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \
>> 	    CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \
>> -	    CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE)
>> +	    CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE | \
>> +	    CPU_FTR_DEBUG_LVL_EXC)
> 
> KVM on E200?

This isn't a KVM patch, it's a patch to make CPU_FTR_DEBUG_LVL_EXC be
set properly on 32-bit chips.  e200 has this CPU feature.

-Scott

^ permalink raw reply

* Re: [RFC PATCH 16/16] KVM: PPC: e500mc support
From: Scott Wood @ 2012-01-09 19:29 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Liu Yu, kvm, agraf, kvm-ppc, Varun Sethi, linuxppc-dev
In-Reply-To: <4F0B16D7.2000709@redhat.com>

On 01/09/2012 10:33 AM, Avi Kivity wrote:
> On 12/21/2011 03:34 AM, Scott Wood wrote:
>> Add processor support for e500mc, using hardware virtualization support
>> (GS-mode).
>>
>> Current issues include:
>>  - No support for external proxy (coreint) interrupt mode in the guest.
>>
>> Includes work by Ashish Kalra <Ashish.Kalra@freescale.com>,
>> Varun Sethi <Varun.Sethi@freescale.com>, and
>> Liu Yu <yu.liu@freescale.com>.
>>
> 
> Best to include their signoffs, if possible.

These patches are based in part on a bunch of different patches from
these people (for which I did receive signoffs).  I was reluctant to put
their signoff directly on the new patches, since I didn't want to make
it look like they had submitted the patch in anything resembling its
current form.  I wanted to give them credit for what they did, but not
blame for what I did with their code.

I've CCed Varun and Liu so they can sign off these versions of the
patches if they wish.  Ashish no longer works at Freescale, so I don't
have a currently valid e-mail address for him.

-Scott

^ permalink raw reply

* Re: [PATCH 1/2] dtc: Implement -d option to write out a dependency file
From: Jon Loeliger @ 2012-01-09 18:58 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Michal Marek, Jonas Bonn, Michal Simek, Russell King,
	linux-c6x-dev, Arnd Bergmann, Aurelien Jacquiot,
	Devicetree Discuss, linux-kbuild, linux-kernel, Rob Herring,
	Paul Mackerras, Mark Salter, microblaze-uclinux, linuxppc-dev,
	linux, linux-arm-kernel, David Gibson
In-Reply-To: <1326134295-15547-1-git-send-email-swarren@nvidia.com>

> This will allow callers to rebuild .dtb files when any of the /include/d
> .dtsi files are modified, not just the top-level .dts file.
> 
> Signed-off-by: Stephen Warren <swarren@nvidia.com>
> ---
> This patch is against the Linux kernel's copy of dtc, but it applies to
> upstream dtc with a couple of trivial conflicts. I can post a version for
> upstream dtc as well if desired.

If it does go upstream into Linux proper, we should
definitely have it in the main DTC repository.
So if you would, please send me a path that applies there.

Thanks,
jdl

^ permalink raw reply

* Re: [SDK v1.2][PATCH 1/2 v3] powerpc/85xx: Add dts for P1021RDB-PC board
From: Scott Wood @ 2012-01-09 20:54 UTC (permalink / raw)
  To: Xu Jiucheng; +Cc: Matthew McClintock, linuxppc-dev
In-Reply-To: <1326092022-10085-1-git-send-email-B37781@freescale.com>

On 01/09/2012 12:53 AM, Xu Jiucheng wrote:
> +	nand@1,0 {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "fsl,p1020-fcm-nand",
> +			     "fsl,elbc-fcm-nand";

s/p1020/p1021/

-Scott

^ permalink raw reply

* Re: [PATCH] powerpc/85xx: Add P1024rdb dts support
From: Scott Wood @ 2012-01-09 21:03 UTC (permalink / raw)
  To: b29983; +Cc: Tang Yuantian, linuxppc-dev
In-Reply-To: <1326098258-32097-1-git-send-email-b29983@freescale.com>

On 01/09/2012 02:37 AM, b29983@freescale.com wrote:
> +/include/ "p1024rdb.dtsi"
> +/include/ "fsl/p1020si-post.dtsi"

Is p1024 100% software-compatible with p1020?

They have different manuals...

-Scott

^ permalink raw reply

* Re: [PATCH v2 3/3] KVM: PPC: epapr: install ev_idle hcall for e500 guest
From: Scott Wood @ 2012-01-09 21:15 UTC (permalink / raw)
  To: Liu Yu; +Cc: kvm, kvm-ppc, agraf, linuxppc-dev, timur
In-Reply-To: <1325754412-29963-2-git-send-email-yu.liu@freescale.com>

On 01/05/2012 03:06 AM, Liu Yu wrote:
> diff --git a/arch/powerpc/kernel/idle_e500.S b/arch/powerpc/kernel/idle_e500.S
> index 3e2b95c..6ea95f0 100644
> --- a/arch/powerpc/kernel/idle_e500.S
> +++ b/arch/powerpc/kernel/idle_e500.S
> @@ -85,6 +85,23 @@ END_FTR_SECTION_IFSET(CPU_FTR_L2CSR|CPU_FTR_CAN_NAP)
>  2:	b	2b
>  #endif /* !E500MC */
>  
> +#ifdef CONFIG_KVM_GUEST
> +/*
> + * r3 contains the pointer to in[8]
> + * r4 contains the pointer to out[8]
> + * r5 contains the hcall vendor and nr
> + * r6 contains the handler which send hcall
> + */
> +_GLOBAL(e500_ev_idle)
> +	rlwinm	r7,r1,0,0,31-THREAD_SHIFT	/* current thread_info */
> +	lwz	r8,TI_LOCAL_FLAGS(r7)	/* set napping bit */
> +	ori	r8,r8,_TLF_NAPPING	/* so when we take an exception */
> +	stw	r8,TI_LOCAL_FLAGS(r7)	/* it will return to our caller */
> +	wrteei	1
> +	mtctr	r6
> +	bctr
> +#endif /* KVM_GUEST */

You'll need to branch back to the hcall invocation in an infinite loop
-- the only way we should leave is via an interrupt.

> +static void kvm_hcall_idle(void)
> +{
> +#ifdef CONFIG_KVM_E500
> +	ulong in[8];
> +	ulong out[8];
> +
> +	e500_ev_idle(in, out, HC_VENDOR_EPAPR | HC_EV_IDLE, kvm_hypercall);
> +#endif
> +}

kvm_hypercall is C code.  As stated before, you cannot use C code while
_TLF_NAPPING is set.

> +static bool kvm_para_has_idle(void)
> +{
> +#ifdef CONFIG_BOOKE
> +	return epapr_hcall_has_idle;
> +#else
> +	return false;
> +#endif
> +}
> +
>  static int __init kvm_guest_init(void)
>  {
>  	if (!kvm_para_available())
> @@ -594,6 +614,10 @@ static int __init kvm_guest_init(void)
>  	powersave_nap = 1;
>  #endif
>  
> +	/* Install hcall based power_save for guest kernel */
> +	if (kvm_para_has_idle())
> +		ppc_md.power_save = kvm_hcall_idle;

Why did you only move it halfway out of KVM code?  ePAPR features such
as idle hcall should work on any ePAPR hypervisor, even with all KVM
code disabled.

Plus everything Alex said. :-)

-Scott

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox