Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V4] scsi: hpsa: drop shutdown callback
From: Sinan Kaya @ 2018-06-01 13:46 UTC (permalink / raw)
  To: linux-arm-kernel

'Commit cc27b735ad3a ("PCI/portdrv: Turn off PCIe services during
shutdown")' has been added to kernel to shutdown pending PCIe port
service interrupts during reboot so that a newly started kexec kernel
wouldn't observe pending interrupts.

pcie_port_device_remove() is disabling the root port and switches by
calling pci_disable_device() after all PCIe service drivers are shutdown.

This has been found to cause crashes on HP DL360 Gen9 machines during
reboot due to hpsa driver not clearing the bus master bit during the
shutdown procedure by calling pci_disable_device().

Disable device as part of the shutdown sequence.

Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=199779
Fixes: cc27b735ad3a ("PCI/portdrv: Turn off PCIe services during shutdown")
Cc: stable at vger.kernel.org
Reported-by: Ryan Finnie <ryan@finnie.org>
---
 drivers/scsi/hpsa.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 3a9eca1..b92f86a 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -8869,7 +8869,7 @@ static void hpsa_disable_rld_caching(struct ctlr_info *h)
 	kfree(options);
 }
 
-static void hpsa_shutdown(struct pci_dev *pdev)
+static void __hpsa_shutdown(struct pci_dev *pdev)
 {
 	struct ctlr_info *h;
 
@@ -8884,6 +8884,12 @@ static void hpsa_shutdown(struct pci_dev *pdev)
 	hpsa_disable_interrupt_mode(h);		/* pci_init 2 */
 }
 
+static void hpsa_shutdown(struct pci_dev *pdev)
+{
+	__hpsa_shutdown(pdev);
+	pci_disable_device(pdev);
+}
+
 static void hpsa_free_device_info(struct ctlr_info *h)
 {
 	int i;
@@ -8927,7 +8933,7 @@ static void hpsa_remove_one(struct pci_dev *pdev)
 		scsi_remove_host(h->scsi_host);		/* init_one 8 */
 	/* includes hpsa_free_irqs - init_one 4 */
 	/* includes hpsa_disable_interrupt_mode - pci_init 2 */
-	hpsa_shutdown(pdev);
+	__hpsa_shutdown(pdev);
 
 	hpsa_free_device_info(h);		/* scan */
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH V3 2/2] scsi: hpsa: drop shutdown callback
From: Sinan Kaya @ 2018-06-01 13:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <3ebb873ea4658275e7fa89c01cd8bfe1@codeaurora.org>

On 5/30/2018 9:08 PM, okaya at codeaurora.org wrote:
> I have seen that shutdown() is also called from remove().
> 
> remove() is supposed to do a safe cleanup too. If it is leaving the hw in inconsistent state even though it is c lling shutdown , it is yet another bug.

Let's try to be constructive. I'll post a patch with the pci_disable added to shutdown
only as in my original proposal.

Somebody can deal with remove another day.

-- 
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply

* [PATCH] media: atmel-isi: move of_node_put() to cover success branch as well
From: Nicholas Mc Guire @ 2018-06-01 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

From: Nicholas Mc Guire <hofrat@osadl.org>

The of_node_put() was only covering the error branch but missed the 
success branch so the refcount for ep which 
of_graph_get_remote_port_parent() incremented on success would was
not being decremented.

Signed-off-by: Nicholas Mc Guire <hofrat@osadl.org>
---

This patch is on top of: "media: atmel-isi: drop unnecessary while loop"

Patch was compile tested with: x86_64_defconfig + CONFIG_MEDIA_SUPPORT=y
MEDIA_CAMERA_SUPPORT=y, CONFIG_MEDIA_CONTROLLER=y, V4L_PLATFORM_DRIVERS=y
OF=y, CONFIG_COMPILE_TEST=y, CONFIG_VIDEO_ATMEL_ISI=y

Compile testing atmel-isi.c shows some sparse warnings. Seems to be due to
sizeof operator being applied to a union (not related to the function being
changed though).

Patch is against 4.17-rc7 (localversion-next is next-20180531)

 drivers/media/platform/atmel/atmel-isi.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
index 85fc7b9..e8db4df 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -1111,10 +1111,9 @@ static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
 		return -EINVAL;
 
 	remote = of_graph_get_remote_port_parent(ep);
-	if (!remote) {
-		of_node_put(ep);
+	of_node_put(ep);
+	if (!remote)
 		return -EINVAL;
-	}
 
 	/* Remote node to connect */
 	isi->entity.node = remote;
-- 
2.1.4

^ permalink raw reply related

* [PATCH v9 01/15] ARM: Add Krait L2 register accessor functions
From: Sricharan R @ 2018-06-01 13:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <152775249799.144038.9269415086304305030@swboyd.mtv.corp.google.com>

Hi Stephen,

On 5/31/2018 1:11 PM, Stephen Boyd wrote:
> Quoting Sricharan R (2018-05-30 21:57:20)
>> Hi Stephen,
>>
>> On 5/30/2018 9:25 PM, Stephen Boyd wrote:
>>> Quoting Sricharan R (2018-05-24 22:40:11)
>>>> Hi Bjorn,
>>>>
>>>> On 5/24/2018 11:09 PM, Bjorn Andersson wrote:
>>>>> On Tue 06 Mar 06:38 PST 2018, Sricharan R wrote:
>>>>>
>>>>>> From: Stephen Boyd <sboyd@codeaurora.org>
>>>>>>
>>>>>> Krait CPUs have a handful of L2 cache controller registers that
>>>>>> live behind a cp15 based indirection register. First you program
>>>>>> the indirection register (l2cpselr) to point the L2 'window'
>>>>>> register (l2cpdr) at what you want to read/write.  Then you
>>>>>> read/write the 'window' register to do what you want. The
>>>>>> l2cpselr register is not banked per-cpu so we must lock around
>>>>>> accesses to it to prevent other CPUs from re-pointing l2cpdr
>>>>>> underneath us.
>>>>>>
>>>>>> Cc: Mark Rutland <mark.rutland@arm.com>
>>>>>> Cc: Russell King <linux@arm.linux.org.uk>
>>>>>> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
>>>>>
>>>>> This should have your signed-off-by here as well.
>>>>>
>>>>
>>>>  ok.
>>>>
>>>>> Apart from that:
>>>>>
>>>>> Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
>>>>>
>>>>
>>>
>>> Will these patches come around again? I'll do a quick sweep on them
>>> today but I expect them to be resent.
>>
>> Sure, i will have to resend them again, fixing couple of Bjorn's
>> minor comments. Will address your comments that you would give
>> as well along with that.
>>
> 
> Ok. One general comment is that it would be nice if the bindings for all
> the nodes that are introduced included 'clocks' properties and also
> maybe 'clock-names' properties for the clocks that are consumed by each
> node. Right now, we hide those details from DT and rely on the string
> names to hook the clk tree up for us. That sort of prevents us from
> moving away from string easily, so I would just throw the clocks into
> the binding right now and always have them there just in case we want to
> use the binding to figure out the hierarchy in the future.
> 

 ok, understand that mostly. So will try to revamp those patches with
 the 'clocks' property in the binding added, reading them in the driver
 from DT.

> I've been thinking we need to do something similar for the gcc and other
> nodes for any clks they use, but I haven't gotten around to it.
> 
> Otherwise the patches look mostly ok to me. Not sure I'll have any other
> comments.
> 

 Thanks, will respin.

Regards,
 Sricharan

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

^ permalink raw reply

* [RFC PATCH 8/8] dts: juno: Update coresight bindings for hw port
From: Suzuki K Poulose @ 2018-06-01 13:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527858967-16047-1-git-send-email-suzuki.poulose@arm.com>

Switch to updated coresight bindings for hw ports.

Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 arch/arm64/boot/dts/arm/juno-base.dtsi | 82 +++++++++++++++++++++++++---------
 arch/arm64/boot/dts/arm/juno.dts       |  5 ++-
 2 files changed, 63 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index eb749c5..33b41ba 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -122,15 +122,18 @@
 			port at 0 {
 				reg = <0>;
 				etf0_in_port: endpoint {
-					slave-mode;
+					direction = <0>;
 					remote-endpoint = <&main_funnel_out_port>;
+					coresight,hwid = <0>;
 				};
 			};
 
 			/* output port */
 			port at 1 {
-				reg = <0>;
+				reg = <1>;
 				etf0_out_port: endpoint {
+					coresight,hwid = <0>;
+					direction = <1>;
 				};
 			};
 		};
@@ -145,8 +148,9 @@
 		power-domains = <&scpi_devpd 0>;
 		port {
 			tpiu_in_port: endpoint {
-				slave-mode;
+				direction = <0>;
 				remote-endpoint = <&replicator_out_port0>;
+				coresight,hwid = <0>;
 			};
 		};
 	};
@@ -168,23 +172,27 @@
 				reg = <0>;
 				main_funnel_out_port: endpoint {
 					remote-endpoint = <&etf0_in_port>;
+					coresight,hwid = <0>;
+					direction = <1>;
 				};
 			};
 
 			/* input ports */
 			port at 1 {
-				reg = <0>;
+				reg = <1>;
 				main_funnel_in_port0: endpoint {
-					slave-mode;
+					direction = <0>;
 					remote-endpoint = <&cluster0_funnel_out_port>;
+					coresight,hwid = <0>;
 				};
 			};
 
 			port at 2 {
-				reg = <1>;
+				reg = <2>;
 				main_funnel_in_port1: endpoint {
-					slave-mode;
+					direction = <0>;
 					remote-endpoint = <&cluster1_funnel_out_port>;
+					coresight,hwid = <1>;
 				};
 			};
 		};
@@ -200,8 +208,9 @@
 		power-domains = <&scpi_devpd 0>;
 		port {
 			etr_in_port: endpoint {
-				slave-mode;
+				direction = <0>;
 				remote-endpoint = <&replicator_out_port1>;
+				coresight,hwid = <0>;
 			};
 		};
 	};
@@ -217,6 +226,8 @@
 		power-domains = <&scpi_devpd 0>;
 		port {
 			stm_out_port: endpoint {
+				coresight,hwid = <0>;
+				direction = <1>;
 			};
 		};
 	};
@@ -240,6 +251,8 @@
 		port {
 			cluster0_etm0_out_port: endpoint {
 				remote-endpoint = <&cluster0_funnel_in_port0>;
+				coresight,hwid = <0>;
+				direction = <1>;
 			};
 		};
 	};
@@ -259,22 +272,26 @@
 				reg = <0>;
 				cluster0_funnel_out_port: endpoint {
 					remote-endpoint = <&main_funnel_in_port0>;
+					coresight,hwid = <0>;
+					direction = <1>;
 				};
 			};
 
 			port at 1 {
-				reg = <0>;
+				reg = <1>;
 				cluster0_funnel_in_port0: endpoint {
-					slave-mode;
+					direction = <0>;
 					remote-endpoint = <&cluster0_etm0_out_port>;
+					coresight,hwid = <0>;
 				};
 			};
 
 			port at 2 {
-				reg = <1>;
+				reg = <2>;
 				cluster0_funnel_in_port1: endpoint {
-					slave-mode;
+					direction = <0>;
 					remote-endpoint = <&cluster0_etm1_out_port>;
+					coresight,hwid = <1>;
 				};
 			};
 		};
@@ -299,6 +316,8 @@
 		port {
 			cluster0_etm1_out_port: endpoint {
 				remote-endpoint = <&cluster0_funnel_in_port1>;
+				coresight,hwid = <0>;
+				direction = <1>;
 			};
 		};
 	};
@@ -322,6 +341,8 @@
 		port {
 			cluster1_etm0_out_port: endpoint {
 				remote-endpoint = <&cluster1_funnel_in_port0>;
+				coresight,hwid = <0>;
+				direction = <1>;
 			};
 		};
 	};
@@ -341,36 +362,42 @@
 				reg = <0>;
 				cluster1_funnel_out_port: endpoint {
 					remote-endpoint = <&main_funnel_in_port1>;
+					coresight,hwid = <0>;
+					direction = <1>;
 				};
 			};
 
 			port at 1 {
-				reg = <0>;
+				reg = <1>;
 				cluster1_funnel_in_port0: endpoint {
-					slave-mode;
+					direction = <0>;
 					remote-endpoint = <&cluster1_etm0_out_port>;
+					coresight,hwid = <0>;
 				};
 			};
 
 			port at 2 {
-				reg = <1>;
+				reg = <2>;
 				cluster1_funnel_in_port1: endpoint {
-					slave-mode;
+					direction = <0>;
 					remote-endpoint = <&cluster1_etm1_out_port>;
+					coresight,hwid = <1>;
 				};
 			};
 			port at 3 {
-				reg = <2>;
+				reg = <3>;
 				cluster1_funnel_in_port2: endpoint {
-					slave-mode;
+					direction = <0>;
 					remote-endpoint = <&cluster1_etm2_out_port>;
+					coresight,hwid = <2>;
 				};
 			};
 			port at 4 {
-				reg = <3>;
+				reg = <4>;
 				cluster1_funnel_in_port3: endpoint {
-					slave-mode;
+					direction = <0>;
 					remote-endpoint = <&cluster1_etm3_out_port>;
+					coresight,hwid = <3>;
 				};
 			};
 		};
@@ -395,6 +422,8 @@
 		port {
 			cluster1_etm1_out_port: endpoint {
 				remote-endpoint = <&cluster1_funnel_in_port1>;
+				coresight,hwid = <0>;
+				direction = <1>;
 			};
 		};
 	};
@@ -418,6 +447,8 @@
 		port {
 			cluster1_etm2_out_port: endpoint {
 				remote-endpoint = <&cluster1_funnel_in_port2>;
+				coresight,hwid = <0>;
+				direction = <1>;
 			};
 		};
 	};
@@ -441,6 +472,8 @@
 		port {
 			cluster1_etm3_out_port: endpoint {
 				remote-endpoint = <&cluster1_funnel_in_port3>;
+				coresight,hwid = <0>;
+				direction = <1>;
 			};
 		};
 	};
@@ -462,6 +495,8 @@
 				reg = <0>;
 				replicator_out_port0: endpoint {
 					remote-endpoint = <&tpiu_in_port>;
+					coresight,hwid = <0>;
+					direction = <1>;
 				};
 			};
 
@@ -469,14 +504,17 @@
 				reg = <1>;
 				replicator_out_port1: endpoint {
 					remote-endpoint = <&etr_in_port>;
+					coresight,hwid = <1>;
+					direction = <1>;
 				};
 			};
 
 			/* replicator input port */
 			port at 2 {
-				reg = <0>;
+				reg = <2>;
 				replicator_in_port0: endpoint {
-					slave-mode;
+					direction = <0>;
+					coresight,hwid = <0>;
 				};
 			};
 		};
diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts
index c9236c4..27b8036 100644
--- a/arch/arm64/boot/dts/arm/juno.dts
+++ b/arch/arm64/boot/dts/arm/juno.dts
@@ -260,10 +260,11 @@
 &main_funnel {
 	ports {
 		port at 3 {
-			reg = <2>;
+			reg = <3>;
 			main_funnel_in_port2: endpoint {
-				slave-mode;
+				direction = <0>;
 				remote-endpoint = <&stm_out_port>;
+				coresight,hwid = <2>;
 			};
 		};
 	};
-- 
2.7.4

^ permalink raw reply related

* [RFC PATCH 7/8] dts: coresight: Define new bindings for direction of data flow
From: Suzuki K Poulose @ 2018-06-01 13:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527858967-16047-1-git-send-email-suzuki.poulose@arm.com>

So far we have relied on an undocumented property "slave-mode",
to indicate if the given port is input or not. Since we are
redefining the coresight bindings, define new property for the
"direction" of data flow for a given connection endpoint in the
device.

Each endpoint must define the following property.

 - "direction" : 0 => Port is input
		 1 => Port is output

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 drivers/hwtracing/coresight/of_coresight.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
index 99d7a9c..63c1668 100644
--- a/drivers/hwtracing/coresight/of_coresight.c
+++ b/drivers/hwtracing/coresight/of_coresight.c
@@ -52,7 +52,19 @@ of_coresight_get_endpoint_device(struct device_node *endpoint)
 			       endpoint, of_dev_node_match);
 }
 
-static void of_coresight_get_ports(const struct device_node *node,
+static bool of_coresight_ep_is_input(struct device *dev, struct device_node *ep_node)
+{
+	u32 dir;
+
+	if (!of_property_read_u32(ep_node, "direction", &dir))
+		return dir == 0;
+
+	dev_warn_once(dev, "Missing mandatory \"direction\" property!\n");
+	return of_property_read_bool(ep_node, "slave-mode");
+}
+
+static void of_coresight_get_ports(struct device *dev,
+				   const struct device_node *node,
 				   int *nr_inport, int *nr_outport)
 {
 	struct device_node *ep = NULL;
@@ -63,7 +75,7 @@ static void of_coresight_get_ports(const struct device_node *node,
 		if (!ep)
 			break;
 
-		if (of_property_read_bool(ep, "slave-mode"))
+		if (of_coresight_ep_is_input(dev, ep))
 			in++;
 		else
 			out++;
@@ -149,7 +161,7 @@ of_get_coresight_platform_data(struct device *dev,
 	pdata->name = dev_name(dev);
 
 	/* Get the number of input and output port for this component */
-	of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport);
+	of_coresight_get_ports(dev, node, &pdata->nr_inport, &pdata->nr_outport);
 
 	if (pdata->nr_outport) {
 		ret = of_coresight_alloc_memory(dev, pdata);
@@ -168,7 +180,7 @@ of_get_coresight_platform_data(struct device *dev,
 			 * No need to deal with input ports, processing for as
 			 * processing for output ports will deal with them.
 			 */
-			if (of_find_property(ep, "slave-mode", NULL))
+			if (of_coresight_ep_is_input(dev, ep))
 				continue;
 
 			outport = of_graph_ep_coresight_get_port_id(dev, ep);
-- 
2.7.4

^ permalink raw reply related

* [RFC PATCH 6/8] dts: coresight: Clean up the device tree graph bindings
From: Suzuki K Poulose @ 2018-06-01 13:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527858967-16047-1-git-send-email-suzuki.poulose@arm.com>

The coresight drivers relied on default bindings for graph
in DT, while reusing the "reg" field of the "ports" to indicate
the actual hardware port number for the connections. However,
with the rules getting stricter w.r.t to the address mismatch
with the label, it is no longer possible to use the port address
field for the hardware port number. Hence, we add an explicit
property to denote the hardware port number, "coresight,hwid"
which must be specified for each "endpoint".

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Rob Herring <robh@kernel.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 .../devicetree/bindings/arm/coresight.txt          | 26 +++++++++---
 drivers/hwtracing/coresight/of_coresight.c         | 46 ++++++++++++++++------
 2 files changed, 54 insertions(+), 18 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
index bd36e40..385581a 100644
--- a/Documentation/devicetree/bindings/arm/coresight.txt
+++ b/Documentation/devicetree/bindings/arm/coresight.txt
@@ -104,7 +104,11 @@ properties to uniquely identify the connection details.
 	"slave-mode"
 
  * Hardware Port number at the component:
-     -  The hardware port number is assumed to be the address of the "port" component.
+   - (Obsolete) The hardware port number is assumed to be the address of the "port" component.
+   - Each "endpoint" must define the hardware port of the local end of the
+     connection using the following property:
+	"coresight,hwid" - 32bit integer, hardware port number at the local end.
+
 
 
 Example:
@@ -120,6 +124,7 @@ Example:
 			etb_in_port: endpoint at 0 {
 				slave-mode;
 				remote-endpoint = <&replicator_out_port0>;
+				coresight,hwid = <0>;
 			};
 		};
 	};
@@ -134,6 +139,7 @@ Example:
 			tpiu_in_port: endpoint at 0 {
 				slave-mode;
 				remote-endpoint = <&replicator_out_port1>;
+				coresight,hwid = <0>;
 			};
 		};
 	};
@@ -154,6 +160,7 @@ Example:
 				reg = <0>;
 				replicator_out_port0: endpoint {
 					remote-endpoint = <&etb_in_port>;
+					coresight,hwid = <0>;
 				};
 			};
 
@@ -161,15 +168,17 @@ Example:
 				reg = <1>;
 				replicator_out_port1: endpoint {
 					remote-endpoint = <&tpiu_in_port>;
+					coresight,hwid = <1>;
 				};
 			};
 
 			/* replicator input port */
 			port at 2 {
-				reg = <0>;
+				reg = <1>;
 				replicator_in_port0: endpoint {
 					slave-mode;
 					remote-endpoint = <&funnel_out_port0>;
+					coresight,hwid = <0>;
 				};
 			};
 		};
@@ -191,31 +200,35 @@ Example:
 				funnel_out_port0: endpoint {
 					remote-endpoint =
 							<&replicator_in_port0>;
+					coresight,hwid = <0>;
 				};
 			};
 
 			/* funnel input ports */
 			port at 1 {
-				reg = <0>;
+				reg = <1>;
 				funnel_in_port0: endpoint {
 					slave-mode;
 					remote-endpoint = <&ptm0_out_port>;
+					coresight,hwid = <0>;
 				};
 			};
 
 			port at 2 {
-				reg = <1>;
+				reg = <2>;
 				funnel_in_port1: endpoint {
 					slave-mode;
 					remote-endpoint = <&ptm1_out_port>;
+					coresight,hwid = <1>;
 				};
 			};
 
 			port at 3 {
-				reg = <2>;
+				reg = <3>;
 				funnel_in_port2: endpoint {
 					slave-mode;
 					remote-endpoint = <&etm0_out_port>;
+					coresight,hwid = <2>;
 				};
 			};
 
@@ -233,6 +246,7 @@ Example:
 		port {
 			ptm0_out_port: endpoint {
 				remote-endpoint = <&funnel_in_port0>;
+				coresight,hwid = <0>;
 			};
 		};
 	};
@@ -247,6 +261,7 @@ Example:
 		port {
 			ptm1_out_port: endpoint {
 				remote-endpoint = <&funnel_in_port1>;
+				coresight,hwid = <0>;
 			};
 		};
 	};
@@ -263,6 +278,7 @@ Example:
 		port {
 			stm_out_port: endpoint {
 				remote-endpoint = <&main_funnel_in_port2>;
+				coresight,hwid = <0>;
 			};
 		};
 	};
diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
index a3f3416..99d7a9c 100644
--- a/drivers/hwtracing/coresight/of_coresight.c
+++ b/drivers/hwtracing/coresight/of_coresight.c
@@ -105,14 +105,37 @@ int of_coresight_get_cpu(const struct device_node *node)
 }
 EXPORT_SYMBOL_GPL(of_coresight_get_cpu);
 
+/*
+ * of_graph_ep_coresight_get_port_id : Get the hardware port number for the
+ * given endpoint device node. Prefer the explicit "coresight,hwid" property
+ * over the endpoint register id (obsolete bindings).
+ */
+static int of_graph_ep_coresight_get_port_id(struct device *dev,
+					     struct device_node *ep_node)
+{
+	struct of_endpoint ep;
+	int rc, port_id;
+
+
+	if (!of_property_read_u32(ep_node, "coresight,hwid", &port_id))
+		return port_id;
+
+	rc = of_graph_parse_endpoint(ep_node, &ep);
+	if (rc)
+		return rc;
+	dev_warn_once(dev,
+		      "ep%d: Mandatory \"coresight,hwid\" property missing."
+		      " DT uses obsolete coresight bindings\n", ep.port);
+	return ep.port;
+}
+
 struct coresight_platform_data *
 of_get_coresight_platform_data(struct device *dev,
 			       const struct device_node *node)
 {
-	int ret = 0;
+	int ret = 0, outport, inport;
 	struct coresight_platform_data *pdata;
 	struct coresight_connection *conn;
-	struct of_endpoint endpoint, rendpoint;
 	struct device *rdev;
 	struct device_node *ep = NULL;
 	struct device_node *rparent = NULL;
@@ -148,14 +171,10 @@ of_get_coresight_platform_data(struct device *dev,
 			if (of_find_property(ep, "slave-mode", NULL))
 				continue;
 
-			/* Get a handle on the local endpoint */
-			ret = of_graph_parse_endpoint(ep, &endpoint);
-
-			if (ret)
+			outport = of_graph_ep_coresight_get_port_id(dev, ep);
+			if (outport < 0)
 				continue;
-
-			/* The local out port number */
-			conn->outport = endpoint.port;
+			conn->outport = outport;
 
 			/*
 			 * Get a handle on the remote endpoint and the device
@@ -168,15 +187,16 @@ of_get_coresight_platform_data(struct device *dev,
 			if (!rparent)
 				continue;
 
-			if (of_graph_parse_endpoint(rep, &rendpoint))
-				continue;
-
 			rdev = of_coresight_get_endpoint_device(rparent);
 			if (!rdev)
 				return ERR_PTR(-EPROBE_DEFER);
 
+			inport = of_graph_ep_coresight_get_port_id(rdev, rep);
+			if (inport < 0)
+				continue;
+
 			conn->child_name = dev_name(rdev);
-			conn->child_port = rendpoint.port;
+			conn->child_port = inport;
 			conn++;
 		} while (ep);
 	}
-- 
2.7.4

^ permalink raw reply related

* [RFC PATCH 5/8] coresight: Handle errors in finding input/output ports
From: Suzuki K Poulose @ 2018-06-01 13:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527858967-16047-1-git-send-email-suzuki.poulose@arm.com>

If we fail to find the input / output port for a LINK component
while enabling a path, we should fail gracefully rather than
assuming port "0".

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 drivers/hwtracing/coresight/coresight.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index 3b3756e..4dcea6e 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -115,7 +115,7 @@ static int coresight_find_link_inport(struct coresight_device *csdev,
 	dev_err(&csdev->dev, "couldn't find inport, parent: %s, child: %s\n",
 		dev_name(&parent->dev), dev_name(&csdev->dev));
 
-	return 0;
+	return -ENODEV;
 }
 
 static int coresight_find_link_outport(struct coresight_device *csdev,
@@ -133,7 +133,7 @@ static int coresight_find_link_outport(struct coresight_device *csdev,
 	dev_err(&csdev->dev, "couldn't find outport, parent: %s, child: %s\n",
 		dev_name(&csdev->dev), dev_name(&child->dev));
 
-	return 0;
+	return -ENODEV;
 }
 
 static int coresight_enable_sink(struct coresight_device *csdev, u32 mode)
@@ -186,6 +186,9 @@ static int coresight_enable_link(struct coresight_device *csdev,
 	else
 		refport = 0;
 
+	if (refport < 0)
+		return refport;
+
 	if (atomic_inc_return(&csdev->refcnt[refport]) == 1) {
 		if (link_ops(csdev)->enable) {
 			ret = link_ops(csdev)->enable(csdev, inport, outport);
-- 
2.7.4

^ permalink raw reply related

* [RFC PATCH 4/8] coresight: platform: Cleanup coresight connection handling
From: Suzuki K Poulose @ 2018-06-01 13:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527858967-16047-1-git-send-email-suzuki.poulose@arm.com>

The platform code parses the component connections and populates
a platform-description of the output connections in arrays of fields
(which is never freed). This is later copied in the coresight_register
to a newly allocated area, represented by coresight_connection(s).

This patch cleans up the code dealing with connections by making
use of the "coresight_connection" structure right at the platform
code and lets the generic driver simply re-use information provided
by the platform.

Thus making it reader friendly as well as avoiding the wastage of
unused memory.

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 drivers/hwtracing/coresight/coresight.c    | 21 +---------------
 drivers/hwtracing/coresight/of_coresight.c | 40 +++++++++++-------------------
 include/linux/coresight.h                  |  9 ++-----
 3 files changed, 17 insertions(+), 53 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index 389c4ba..3b3756e 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -961,13 +961,11 @@ postcore_initcall(coresight_init);
 
 struct coresight_device *coresight_register(struct coresight_desc *desc)
 {
-	int i;
 	int ret;
 	int link_subtype;
 	int nr_refcnts = 1;
 	atomic_t *refcnts = NULL;
 	struct coresight_device *csdev;
-	struct coresight_connection *conns = NULL;
 
 	csdev = kzalloc(sizeof(*csdev), GFP_KERNEL);
 	if (!csdev) {
@@ -996,22 +994,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
 	csdev->nr_inport = desc->pdata->nr_inport;
 	csdev->nr_outport = desc->pdata->nr_outport;
 
-	/* Initialise connections if there is at least one outport */
-	if (csdev->nr_outport) {
-		conns = kcalloc(csdev->nr_outport, sizeof(*conns), GFP_KERNEL);
-		if (!conns) {
-			ret = -ENOMEM;
-			goto err_kzalloc_conns;
-		}
-
-		for (i = 0; i < csdev->nr_outport; i++) {
-			conns[i].outport = desc->pdata->outports[i];
-			conns[i].child_name = desc->pdata->child_names[i];
-			conns[i].child_port = desc->pdata->child_ports[i];
-		}
-	}
-
-	csdev->conns = conns;
+	csdev->conns = desc->pdata->conns;
 
 	csdev->type = desc->type;
 	csdev->subtype = desc->subtype;
@@ -1039,8 +1022,6 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
 	return csdev;
 
 err_device_register:
-	kfree(conns);
-err_kzalloc_conns:
 	kfree(refcnts);
 err_kzalloc_refcnts:
 	kfree(csdev);
diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
index e0deab0..a3f3416 100644
--- a/drivers/hwtracing/coresight/of_coresight.c
+++ b/drivers/hwtracing/coresight/of_coresight.c
@@ -77,26 +77,13 @@ static void of_coresight_get_ports(const struct device_node *node,
 static int of_coresight_alloc_memory(struct device *dev,
 			struct coresight_platform_data *pdata)
 {
-	/* List of output port on this component */
-	pdata->outports = devm_kzalloc(dev, pdata->nr_outport *
-				       sizeof(*pdata->outports),
-				       GFP_KERNEL);
-	if (!pdata->outports)
-		return -ENOMEM;
-
-	/* Children connected to this component via @outports */
-	pdata->child_names = devm_kzalloc(dev, pdata->nr_outport *
-					  sizeof(*pdata->child_names),
-					  GFP_KERNEL);
-	if (!pdata->child_names)
-		return -ENOMEM;
-
-	/* Port number on the child this component is connected to */
-	pdata->child_ports = devm_kzalloc(dev, pdata->nr_outport *
-					  sizeof(*pdata->child_ports),
-					  GFP_KERNEL);
-	if (!pdata->child_ports)
-		return -ENOMEM;
+	if (pdata->nr_outport) {
+		pdata->conns = devm_kzalloc(dev, pdata->nr_outport *
+					    sizeof(*pdata->conns),
+					    GFP_KERNEL);
+		if (!pdata->conns)
+			return -ENOMEM;
+	}
 
 	return 0;
 }
@@ -122,8 +109,9 @@ struct coresight_platform_data *
 of_get_coresight_platform_data(struct device *dev,
 			       const struct device_node *node)
 {
-	int i = 0, ret = 0;
+	int ret = 0;
 	struct coresight_platform_data *pdata;
+	struct coresight_connection *conn;
 	struct of_endpoint endpoint, rendpoint;
 	struct device *rdev;
 	struct device_node *ep = NULL;
@@ -145,6 +133,7 @@ of_get_coresight_platform_data(struct device *dev,
 		if (ret)
 			return ERR_PTR(ret);
 
+		conn = pdata->conns;
 		/* Iterate through each port to discover topology */
 		do {
 			/* Get a handle on a port */
@@ -166,7 +155,7 @@ of_get_coresight_platform_data(struct device *dev,
 				continue;
 
 			/* The local out port number */
-			pdata->outports[i] = endpoint.port;
+			conn->outport = endpoint.port;
 
 			/*
 			 * Get a handle on the remote endpoint and the device
@@ -186,10 +175,9 @@ of_get_coresight_platform_data(struct device *dev,
 			if (!rdev)
 				return ERR_PTR(-EPROBE_DEFER);
 
-			pdata->child_names[i] = dev_name(rdev);
-			pdata->child_ports[i] = rendpoint.port;
-
-			i++;
+			conn->child_name = dev_name(rdev);
+			conn->child_port = rendpoint.port;
+			conn++;
 		} while (ep);
 	}
 
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 32aaa1c..c2363bb 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -89,20 +89,15 @@ struct coresight_dev_subtype {
  * @cpu:	the CPU a source belongs to. Only applicable for ETM/PTMs.
  * @name:	name of the component as shown under sysfs.
  * @nr_inport:	number of input ports for this component.
- * @outports:	list of remote endpoint port number.
- * @child_names:name of all child components connected to this device.
- * @child_ports:child component port number the current component is
-		connected  to.
  * @nr_outport:	number of output ports for this component.
+ * @conns:	Array of nr_outport connections from this component
  */
 struct coresight_platform_data {
 	int cpu;
 	const char *name;
 	int nr_inport;
-	int *outports;
-	const char **child_names;
-	int *child_ports;
 	int nr_outport;
+	struct coresight_connection *conns;
 };
 
 /**
-- 
2.7.4

^ permalink raw reply related

* [RFC PATCH 3/8] coresight: Cleanup platform description data
From: Suzuki K Poulose @ 2018-06-01 13:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527858967-16047-1-git-send-email-suzuki.poulose@arm.com>

Nobody uses the "clk" field in struct coresight_platform_data.
Remove it.

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 include/linux/coresight.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index d950dad..32aaa1c 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -94,7 +94,6 @@ struct coresight_dev_subtype {
  * @child_ports:child component port number the current component is
 		connected  to.
  * @nr_outport:	number of output ports for this component.
- * @clk:	The clock this component is associated to.
  */
 struct coresight_platform_data {
 	int cpu;
@@ -104,7 +103,6 @@ struct coresight_platform_data {
 	const char **child_names;
 	int *child_ports;
 	int nr_outport;
-	struct clk *clk;
 };
 
 /**
-- 
2.7.4

^ permalink raw reply related

* [RFC PATCH 2/8] coresight: Fix remote endpoint parsing
From: Suzuki K Poulose @ 2018-06-01 13:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527858967-16047-1-git-send-email-suzuki.poulose@arm.com>

When parsing the remote endpoint of an output port, we do :
     rport = of_graph_get_remote_port(ep);
     rparent = of_graph_get_remote_port_parent(ep);

and then parse the "remote_port" as if it was the remote endpoint,
which is wrong. The code worked fine because we used endpoint number
as the port number. Let us fix it and optimise a bit as:

     remote_ep = of_graph_get_remote_endpoint(ep);
     if (remote_ep)
        remote_parent = of_graph_get_port_parent(remote_ep);

and then, parse the remote_ep for the port/endpoint details.

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 drivers/hwtracing/coresight/of_coresight.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
index 7c37544..e0deab0 100644
--- a/drivers/hwtracing/coresight/of_coresight.c
+++ b/drivers/hwtracing/coresight/of_coresight.c
@@ -128,7 +128,7 @@ of_get_coresight_platform_data(struct device *dev,
 	struct device *rdev;
 	struct device_node *ep = NULL;
 	struct device_node *rparent = NULL;
-	struct device_node *rport = NULL;
+	struct device_node *rep = NULL;
 
 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
@@ -169,16 +169,17 @@ of_get_coresight_platform_data(struct device *dev,
 			pdata->outports[i] = endpoint.port;
 
 			/*
-			 * Get a handle on the remote port and parent
-			 * attached to it.
+			 * Get a handle on the remote endpoint and the device
+			 * it is attached to.
 			 */
-			rparent = of_graph_get_remote_port_parent(ep);
-			rport = of_graph_get_remote_port(ep);
-
-			if (!rparent || !rport)
+			rep = of_graph_get_remote_endpoint(ep);
+			if (!rep)
+				continue;
+			rparent = of_graph_get_port_parent(rep);
+			if (!rparent)
 				continue;
 
-			if (of_graph_parse_endpoint(rport, &rendpoint))
+			if (of_graph_parse_endpoint(rep, &rendpoint))
 				continue;
 
 			rdev = of_coresight_get_endpoint_device(rparent);
@@ -186,7 +187,7 @@ of_get_coresight_platform_data(struct device *dev,
 				return ERR_PTR(-EPROBE_DEFER);
 
 			pdata->child_names[i] = dev_name(rdev);
-			pdata->child_ports[i] = rendpoint.id;
+			pdata->child_ports[i] = rendpoint.port;
 
 			i++;
 		} while (ep);
-- 
2.7.4

^ permalink raw reply related

* [RFC PATCH 1/8] dts: binding: coresight: Document graph bindings
From: Suzuki K Poulose @ 2018-06-01 13:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527858967-16047-1-git-send-email-suzuki.poulose@arm.com>

Before we updat the bindings, document the current graph bindings
and usage of additional properties.

Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
---
 .../devicetree/bindings/arm/coresight.txt          | 28 ++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
index 15ac8e8..bd36e40 100644
--- a/Documentation/devicetree/bindings/arm/coresight.txt
+++ b/Documentation/devicetree/bindings/arm/coresight.txt
@@ -52,9 +52,7 @@ its hardware characteristcs.
 	  clocks the core of that coresight component. The latter clock
 	  is optional.
 
-	* port or ports: The representation of the component's port
-	  layout using the generic DT graph presentation found in
-	  "bindings/graph.txt".
+	* port or ports: see "Graph bindings for Coresight" below
 
 * Additional required properties for System Trace Macrocells (STM):
 	* reg: along with the physical base address and length of the register
@@ -71,7 +69,7 @@ its hardware characteristcs.
 	  AMBA markee):
 		- "arm,coresight-replicator"
 
-	* port or ports: same as above.
+	* port or ports: see "Graph bindings for Coresight" below.
 
 * Optional properties for ETM/PTMs:
 
@@ -86,6 +84,28 @@ its hardware characteristcs.
 	* arm,buffer-size: size of contiguous buffer space for TMC ETR
 	 (embedded trace router)
 
+Graph bindings for Coresight
+-------------------------------
+
+Coresight components are interconnected to create a data path for the flow of
+trace data generated from the "sources" to their collection points "sink". Each
+coresight component must describe the "input" and "output" connections.
+The connections must be described via generic DT graph bindings as described
+by the "bindings/graph.txt", where each "port" along with an "endpoint" component
+represents a hardware port and the connection.
+
+Since it is possible to have multiple connections for any coresight component with
+a specific direction of data flow, each connection must define the following
+properties to uniquely identify the connection details.
+
+ * Direction of the data flow w.r.t the component :
+   Each input port must have the following property defined at the "endpoint"
+   for the port.
+	"slave-mode"
+
+ * Hardware Port number at the component:
+     -  The hardware port number is assumed to be the address of the "port" component.
+
 
 Example:
 
-- 
2.7.4

^ permalink raw reply related

* [RFC PATCH 0/8] coresight: Update device tree bindings
From: Suzuki K Poulose @ 2018-06-01 13:15 UTC (permalink / raw)
  To: linux-arm-kernel

Coresight uses DT graph bindings to describe the connections of the
components. However we have some undocumented usage of the bindings
to describe some of the properties of the connections.

The coresight driver needs to know the hardware ports invovled
in the connection and the direction of data flow to effectively
manage the trace sessions. So far we have relied on the "port"
address (as described by the generic graph bindings) to represent
the hardware port of the component for a connection.

The hardware uses separate numbering scheme for input and output
ports, which implies, we could have two different (input and output)
ports with the same port number. This could create problems in the
graph bindings where the label of the port wouldn't match the address.

e.g, with the existing bindings we get :

	port at 0{				// Output port 0
		reg = <0>;
		...
	};

	port at 1{
		reg = <0>;		// Input port 0
		endpoint {
			slave-mode;
			...
		};
	};

With the new enforcement in the DT rules, mismatches in label and address
are not allowed (as see in the case for port at 1). So, we need a new mechanism
to describe the hardware port number reliably.

Also, we relied on an undocumented "slave-mode" property (see the above
example) to indicate if the port is an input port. Let us formalise and
switch to a new property to describe the direction of data flow.

There were three options considered for the hardware port number scheme:

 1) Use natural ordering in the DT to infer the hardware port number.
  i.e, Mandate that the all ports are listed in the DT and in the ascending
  order for each class (input and output respectively).
   Pros :
      - We don't need new properties and if the existing DTS list them in
        order (which most of them do), they work out of the box.
   Cons :
      - We must list all the ports even if the system cannot/shouldn't use
        it.
      - It is prone to human errors (if the order is not kept).

 2) Use an explicit property to list both the direction and the hw port
    number and direction. Define "coresight,hwid" as 2 member array of u32,
    where the members are port number and the direction respectively.
	e.g

	port at 0{
		reg = <0>;
		endpoint {
			coresight,hwid = <0 1>;	// Port # 0, Output
		}
	};

	port at 1{
		reg = <1>;
		endpoint {
			coresight,hwid = <0 0>;	// Port # 0, Input
		};
	};

	Pros:
	  - The bindings are formal but not so reader friendly and could potentially
	    lead to human errors.
	Cons:
	  - Backward compatiblity is lost.
 3) Use explicit properties (implemented in the series) for the hardware
    port id and direction. We define a new property "coresight,hwid" for
    each endpoint in coresight devices to specify the hardware port number
    explicitly. Also use a separate property "direction" to specify the
    direction of the data flow.

	e.g,

	port at 0{
		reg = <0>;
		endpoint {
			direction = <1>;	// Output
			coresight,hwid = <0>;	// Port # 0
		}
	};

	port at 1{
		reg = <1>;
		endpoint {
			direction = <0>;	// Input
			coresight,hwid = <0>;	// Port # 0
		};
	};

    Pros:
       - The bindings are formal and reader friendly, and less prone to errors.
    Cons:
       - Backward compatibility is lost.


This series achieves implements Option (3) listed above while still retaining
the backward compatibility. The driver now issues a warning (once) when it
encounters the old bindings.
It also cleans up the platform parsing code to reduce the memory usage by
reusing the platform description. The series also includes the
changes for Juno platform as an example. If there are no objections
to the approach, I could post the series, converting all the
in-kernel DTS to the new binding.

Suzuki K Poulose (8):
  dts: binding: coresight: Document graph bindings
  coresight: Fix remote endpoint parsing
  coresight: Cleanup platform description data
  coresight: platform: Cleanup coresight connection handling
  coresight: Handle errors in finding input/output ports
  dts: coresight: Clean up the device tree graph bindings
  dts: coresight: Define new bindings for direction of data flow
  dts: juno: Update coresight bindings for hw port

 .../devicetree/bindings/arm/coresight.txt          |  52 ++++++++--
 arch/arm64/boot/dts/arm/juno-base.dtsi             |  82 +++++++++++----
 arch/arm64/boot/dts/arm/juno.dts                   |   5 +-
 drivers/hwtracing/coresight/coresight.c            |  28 ++----
 drivers/hwtracing/coresight/of_coresight.c         | 111 ++++++++++++---------
 include/linux/coresight.h                          |  11 +-
 6 files changed, 181 insertions(+), 108 deletions(-)

-- 
2.7.4

^ permalink raw reply

* [PATCH v2]irqchip/irq-gic-v3:Avoid a waste of LPI resource
From: Marc Zyngier @ 2018-06-01 12:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <8898674D84E3B24BA3A2D289B872026A69F3004A@G01JPEXMBKW03>

Hi Lei,

On 01/06/18 13:44, Zhang, Lei wrote:
> Hi Marc
> 
> I have reviewed your patch.	 
> I think the approach is same between your patch and mine.
> Your patch is simpler and more beautiful, and match our bus's requirement.
> 
> I have only one question.
> According your patch, if there are no enough lpis, amount of lpis required
> will be divide by 2. it means someone want 16 lpis, maybe they can only get 8?
> I don?t' understand why we need it.

That's the way the MSI allocation works in the kernel.

A driver asks a number of MSIs (let's imagine, for example, one MSI per
CPU in the system), but the underlying HW can only provide a smaller number.

Instead of failing and just returning an error, we reduce the allocation
in order to provide the driver with something. If that's not enough,
well, the driver itself will have the opportunity to give up.

See pci_alloc_irq_vectors_affinity(), which takes a min and a max number
of vectors, for example.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [PATCH] media: atmel-isi: drop unnecessary while loop
From: Nicholas Mc Guire @ 2018-06-01 12:46 UTC (permalink / raw)
  To: linux-arm-kernel

From: Nicholas Mc Guire <hofrat@osadl.org>

As there is no way this can loop it actually makes no sense to have
a while(1){} around the body - all three possible paths end in a return
statement. 

Signed-off-by: Nicholas Mc Guire <hofrat@osadl.org>
Fixes: commit c1d82b895380 "[media] atmel-isi: move out of soc_camera to atmel"
---

The diff output is unfortunately not that readable - essentially only
the outer while(1){ } was removed. 

Patch was compile tested with: x86_64_defconfig + CONFIG_MEDIA_SUPPORT=y
MEDIA_CAMERA_SUPPORT=y, CONFIG_MEDIA_CONTROLLER=y, V4L_PLATFORM_DRIVERS=y
OF=y, CONFIG_COMPILE_TEST=y, CONFIG_VIDEO_ATMEL_ISI=y

Compile testing atmel-isi.c shows some sparse warnings. Seems to be due to
sizeof operator being applied to a union (not related to the function being
changed though).

Patch is against 4.17-rc7 (localversion-next is next-20180531)

 drivers/media/platform/atmel/atmel-isi.c | 28 +++++++++++++---------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
index e5be21a..85fc7b9 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -1106,23 +1106,21 @@ static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
 	struct device_node *ep = NULL;
 	struct device_node *remote;
 
-	while (1) {
-		ep = of_graph_get_next_endpoint(node, ep);
-		if (!ep)
-			return -EINVAL;
-
-		remote = of_graph_get_remote_port_parent(ep);
-		if (!remote) {
-			of_node_put(ep);
-			return -EINVAL;
-		}
+	ep = of_graph_get_next_endpoint(node, ep);
+	if (!ep)
+		return -EINVAL;
 
-		/* Remote node to connect */
-		isi->entity.node = remote;
-		isi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-		isi->entity.asd.match.fwnode = of_fwnode_handle(remote);
-		return 0;
+	remote = of_graph_get_remote_port_parent(ep);
+	if (!remote) {
+		of_node_put(ep);
+		return -EINVAL;
 	}
+
+	/* Remote node to connect */
+	isi->entity.node = remote;
+	isi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
+	isi->entity.asd.match.fwnode = of_fwnode_handle(remote);
+	return 0;
 }
 
 static int isi_graph_init(struct atmel_isi *isi)
-- 
2.1.4

^ permalink raw reply related

* [PATCH v2]irqchip/irq-gic-v3:Avoid a waste of LPI resource
From: Zhang, Lei @ 2018-06-01 12:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <86d0xhaucm.wl-marc.zyngier@arm.com>

Hi Marc

I have reviewed your patch.	 
I think the approach is same between your patch and mine.
Your patch is simpler and more beautiful, and match our bus's requirement.

I have only one question.
According your patch, if there are no enough lpis, amount of lpis required
will be divide by 2. it means someone want 16 lpis, maybe they can only get 8?
I don?t' understand why we need it.

 static unsigned long *its_lpi_alloc(int nr_irqs, u32 *base, int *nr_ids)
 {
         unsigned long *bitmap = NULL;
         int err = 0;

         do {
                 err = alloc_lpi_range(nr_irqs, base);
                 if (!err)
                         break;

                 nr_irqs /= 2;
         } while (nr_irqs > 0);


Best Regards,
Lei Zhang zhang.lei at jp.fujitsu.com
FUJITSU LIMITED

> -----Original Message-----
> From: linux-arm-kernel
> [mailto:linux-arm-kernel-bounces at lists.infradead.org] On Behalf Of
> Marc Zyngier
> Sent: Monday, May 28, 2018 2:20 AM
> To: Zhang, Lei/? ?
> Cc: 'linux-arm-kernel at lists.infradead.org'
> Subject: Re: [PATCH v2]irqchip/irq-gic-v3:Avoid a waste of LPI resource
> 
> On Fri, 25 May 2018 13:45:24 +0100,
> Zhang, Lei wrote:
> 
 
> I've just prototyped what I had in mind for this at [1] (see the first
> patch for the allocator itself). As you can see, the allocator is a
> lot simpler, yet it has all the flexibility you would need, The
> drawback is of course that freeing LPIs is quite expensive, but that
> almost never happens. And if it does, we can switch to a tree or some
> more efficient data structure.
> 
> Thanks,
> 
> 	M.
> 
> [1]
> https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.gi
> t/log/?h=irq/lpi-allocator
> 

^ permalink raw reply

* [PATCH v12 5/5] arm64: Allow huge io mappings again
From: Chintan Pandya @ 2018-06-01 12:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527856758-27169-1-git-send-email-cpandya@codeaurora.org>

Huge mappings have had stability issues due to stale
TLB entry and memory leak issues. Since, those are
addressed in this series of patches, it is now safe
to allow huge mappings.

Signed-off-by: Chintan Pandya <cpandya@codeaurora.org>
---
 arch/arm64/mm/mmu.c | 18 ++----------------
 1 file changed, 2 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 6e7e16c..c65abc4 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -934,15 +934,8 @@ int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot)
 {
 	pgprot_t sect_prot = __pgprot(PUD_TYPE_SECT |
 					pgprot_val(mk_sect_prot(prot)));
-	pud_t new_pud = pfn_pud(__phys_to_pfn(phys), sect_prot);
-
-	/* Only allow permission changes for now */
-	if (!pgattr_change_is_safe(READ_ONCE(pud_val(*pudp)),
-				   pud_val(new_pud)))
-		return 0;
-
 	BUG_ON(phys & ~PUD_MASK);
-	set_pud(pudp, new_pud);
+	set_pud(pudp, pfn_pud(__phys_to_pfn(phys), sect_prot));
 	return 1;
 }
 
@@ -950,15 +943,8 @@ int pmd_set_huge(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot)
 {
 	pgprot_t sect_prot = __pgprot(PMD_TYPE_SECT |
 					pgprot_val(mk_sect_prot(prot)));
-	pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), sect_prot);
-
-	/* Only allow permission changes for now */
-	if (!pgattr_change_is_safe(READ_ONCE(pmd_val(*pmdp)),
-				   pmd_val(new_pmd)))
-		return 0;
-
 	BUG_ON(phys & ~PMD_MASK);
-	set_pmd(pmdp, new_pmd);
+	set_pmd(pmdp, pfn_pmd(__phys_to_pfn(phys), sect_prot));
 	return 1;
 }
 
-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation
Center, Inc., is a member of Code Aurora Forum, a Linux Foundation
Collaborative Project

^ permalink raw reply related

* [PATCH v12 4/5] arm64: Implement page table free interfaces
From: Chintan Pandya @ 2018-06-01 12:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527856758-27169-1-git-send-email-cpandya@codeaurora.org>

Implement pud_free_pmd_page() and pmd_free_pte_page().

Implementation requires,
 1) Clearing off the current pud/pmd entry
 2) Invalidate TLB which could have previously
    valid but not stale entry
 3) Freeing of the un-used next level page tables

Signed-off-by: Chintan Pandya <cpandya@codeaurora.org>
---
 arch/arm64/mm/mmu.c | 38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 8ae5d7a..6e7e16c 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -45,6 +45,7 @@
 #include <asm/memblock.h>
 #include <asm/mmu_context.h>
 #include <asm/ptdump.h>
+#include <asm/tlbflush.h>
 
 #define NO_BLOCK_MAPPINGS	BIT(0)
 #define NO_CONT_MAPPINGS	BIT(1)
@@ -977,12 +978,41 @@ int pmd_clear_huge(pmd_t *pmdp)
 	return 1;
 }
 
-int pud_free_pmd_page(pud_t *pud, unsigned long addr)
+int pmd_free_pte_page(pmd_t *pmdp, unsigned long addr)
 {
-	return pud_none(*pud);
+	pte_t *table;
+	pmd_t pmd;
+
+	pmd = READ_ONCE(*pmdp);
+	if (pmd_present(pmd)) {
+		table = pmd_page_vaddr(pmd);
+		pmd_clear(pmdp);
+		__flush_tlb_kernel_pgtable(addr);
+		pte_free_kernel(NULL, table);
+	}
+	return 1;
 }
 
-int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
+int pud_free_pmd_page(pud_t *pudp, unsigned long addr)
 {
-	return pmd_none(*pmd);
+	pmd_t *table;
+	pmd_t *entry;
+	pud_t pud;
+	unsigned long next, end;
+
+	pud = READ_ONCE(*pudp);
+	if (pud_present(pud)) {
+		table = pud_page_vaddr(pud);
+		entry = table;
+		next = addr;
+		end = addr + PUD_SIZE;
+		do {
+			pmd_free_pte_page(entry, next);
+		} while (entry++, next += PMD_SIZE, next != end);
+
+		pud_clear(pudp);
+		__flush_tlb_kernel_pgtable(addr);
+		pmd_free(NULL, table);
+	}
+	return 1;
 }
-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation
Center, Inc., is a member of Code Aurora Forum, a Linux Foundation
Collaborative Project

^ permalink raw reply related

* [PATCH v12 3/5] arm64: pgtable: Add p*d_page_vaddr helper macros
From: Chintan Pandya @ 2018-06-01 12:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527856758-27169-1-git-send-email-cpandya@codeaurora.org>

Add helper macros to give virtual references to page
tables. These will be used while freeing dangling
page tables.

Signed-off-by: Chintan Pandya <cpandya@codeaurora.org>
---
 arch/arm64/include/asm/pgtable.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 7c4c8f3..ef4047f 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -580,6 +580,9 @@ static inline phys_addr_t pgd_page_paddr(pgd_t pgd)
 
 #endif  /* CONFIG_PGTABLE_LEVELS > 3 */
 
+#define pmd_page_vaddr(pmd) __va(pmd_page_paddr(pmd))
+#define pud_page_vaddr(pud) __va(pud_page_paddr(pud))
+
 #define pgd_ERROR(pgd)		__pgd_error(__FILE__, __LINE__, pgd_val(pgd))
 
 /* to find an entry in a page-table-directory */
-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation
Center, Inc., is a member of Code Aurora Forum, a Linux Foundation
Collaborative Project

^ permalink raw reply related

* [PATCH v12 2/5] arm64: tlbflush: Introduce __flush_tlb_kernel_pgtable
From: Chintan Pandya @ 2018-06-01 12:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527856758-27169-1-git-send-email-cpandya@codeaurora.org>

Add an interface to invalidate intermediate page tables
from TLB for kernel.

Signed-off-by: Chintan Pandya <cpandya@codeaurora.org>
---
 arch/arm64/include/asm/tlbflush.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index dfc61d7..a4a1901 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -218,6 +218,13 @@ static inline void __flush_tlb_pgtable(struct mm_struct *mm,
 	dsb(ish);
 }
 
+static inline void __flush_tlb_kernel_pgtable(unsigned long kaddr)
+{
+	unsigned long addr = __TLBI_VADDR(kaddr, 0);
+
+	__tlbi(vaae1is, addr);
+	dsb(ish);
+}
 #endif
 
 #endif
-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation
Center, Inc., is a member of Code Aurora Forum, a Linux Foundation
Collaborative Project

^ permalink raw reply related

* [PATCH v12 1/5] ioremap: Update pgtable free interfaces with addr
From: Chintan Pandya @ 2018-06-01 12:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527856758-27169-1-git-send-email-cpandya@codeaurora.org>

From: Chintan Pandya <cpandya@codeaurora.org>

The following kernel panic was observed on ARM64 platform due to a stale
TLB entry.

 1. ioremap with 4K size, a valid pte page table is set.
 2. iounmap it, its pte entry is set to 0.
 3. ioremap the same address with 2M size, update its pmd entry with
    a new value.
 4. CPU may hit an exception because the old pmd entry is still in TLB,
    which leads to a kernel panic.

Commit b6bdb7517c3d ("mm/vmalloc: add interfaces to free unmapped page
table") has addressed this panic by falling to pte mappings in the above
case on ARM64.

To support pmd mappings in all cases, TLB purge needs to be performed
in this case on ARM64.

Add a new arg, 'addr', to pud_free_pmd_page() and pmd_free_pte_page()
so that TLB purge can be added later in seprate patches.

[toshi at hpe.com: merge changes, rewrite patch description]
Fixes: 28ee90fe6048 ("x86/mm: implement free pmd/pte page interfaces")
Signed-off-by: Chintan Pandya <cpandya@codeaurora.org>
Signed-off-by: Toshi Kani <toshi.kani@hpe.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: <stable@vger.kernel.org>

---
 arch/arm64/mm/mmu.c           | 4 ++--
 arch/x86/mm/pgtable.c         | 8 +++++---
 include/asm-generic/pgtable.h | 8 ++++----
 lib/ioremap.c                 | 4 ++--
 4 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 493ff75..8ae5d7a 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -977,12 +977,12 @@ int pmd_clear_huge(pmd_t *pmdp)
 	return 1;
 }
 
-int pud_free_pmd_page(pud_t *pud)
+int pud_free_pmd_page(pud_t *pud, unsigned long addr)
 {
 	return pud_none(*pud);
 }
 
-int pmd_free_pte_page(pmd_t *pmd)
+int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
 {
 	return pmd_none(*pmd);
 }
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index ffc8c13..37e3cba 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -718,11 +718,12 @@ int pmd_clear_huge(pmd_t *pmd)
 /**
  * pud_free_pmd_page - Clear pud entry and free pmd page.
  * @pud: Pointer to a PUD.
+ * @addr: Virtual address associated with pud.
  *
  * Context: The pud range has been unmaped and TLB purged.
  * Return: 1 if clearing the entry succeeded. 0 otherwise.
  */
-int pud_free_pmd_page(pud_t *pud)
+int pud_free_pmd_page(pud_t *pud, unsigned long addr)
 {
 	pmd_t *pmd;
 	int i;
@@ -733,7 +734,7 @@ int pud_free_pmd_page(pud_t *pud)
 	pmd = (pmd_t *)pud_page_vaddr(*pud);
 
 	for (i = 0; i < PTRS_PER_PMD; i++)
-		if (!pmd_free_pte_page(&pmd[i]))
+		if (!pmd_free_pte_page(&pmd[i], addr + (i * PMD_SIZE)))
 			return 0;
 
 	pud_clear(pud);
@@ -745,11 +746,12 @@ int pud_free_pmd_page(pud_t *pud)
 /**
  * pmd_free_pte_page - Clear pmd entry and free pte page.
  * @pmd: Pointer to a PMD.
+ * @addr: Virtual address associated with pmd.
  *
  * Context: The pmd range has been unmaped and TLB purged.
  * Return: 1 if clearing the entry succeeded. 0 otherwise.
  */
-int pmd_free_pte_page(pmd_t *pmd)
+int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
 {
 	pte_t *pte;
 
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index f59639a..b081794 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -1019,8 +1019,8 @@ static inline int p4d_clear_huge(p4d_t *p4d)
 int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot);
 int pud_clear_huge(pud_t *pud);
 int pmd_clear_huge(pmd_t *pmd);
-int pud_free_pmd_page(pud_t *pud);
-int pmd_free_pte_page(pmd_t *pmd);
+int pud_free_pmd_page(pud_t *pud, unsigned long addr);
+int pmd_free_pte_page(pmd_t *pmd, unsigned long addr);
 #else	/* !CONFIG_HAVE_ARCH_HUGE_VMAP */
 static inline int p4d_set_huge(p4d_t *p4d, phys_addr_t addr, pgprot_t prot)
 {
@@ -1046,11 +1046,11 @@ static inline int pmd_clear_huge(pmd_t *pmd)
 {
 	return 0;
 }
-static inline int pud_free_pmd_page(pud_t *pud)
+static inline int pud_free_pmd_page(pud_t *pud, unsigned long addr)
 {
 	return 0;
 }
-static inline int pmd_free_pte_page(pmd_t *pmd)
+static inline int pmd_free_pte_page(pmd_t *pmd, unsigned long addr)
 {
 	return 0;
 }
diff --git a/lib/ioremap.c b/lib/ioremap.c
index 54e5bba..517f585 100644
--- a/lib/ioremap.c
+++ b/lib/ioremap.c
@@ -92,7 +92,7 @@ static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr,
 		if (ioremap_pmd_enabled() &&
 		    ((next - addr) == PMD_SIZE) &&
 		    IS_ALIGNED(phys_addr + addr, PMD_SIZE) &&
-		    pmd_free_pte_page(pmd)) {
+		    pmd_free_pte_page(pmd, addr)) {
 			if (pmd_set_huge(pmd, phys_addr + addr, prot))
 				continue;
 		}
@@ -119,7 +119,7 @@ static inline int ioremap_pud_range(p4d_t *p4d, unsigned long addr,
 		if (ioremap_pud_enabled() &&
 		    ((next - addr) == PUD_SIZE) &&
 		    IS_ALIGNED(phys_addr + addr, PUD_SIZE) &&
-		    pud_free_pmd_page(pud)) {
+		    pud_free_pmd_page(pud, addr)) {
 			if (pud_set_huge(pud, phys_addr + addr, prot))
 				continue;
 		}
-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation
Center, Inc., is a member of Code Aurora Forum, a Linux Foundation
Collaborative Project

^ permalink raw reply related

* [PATCH v12 0/5] Fix issues with huge mapping in ioremap for ARM64
From: Chintan Pandya @ 2018-06-01 12:39 UTC (permalink / raw)
  To: linux-arm-kernel

This series of patches re-bring huge vmap back for arm64.

Patch 1/4 has been taken by Toshi in his series of patches
by name "[PATCH v3 0/3] fix free pmd/pte page handlings on x86"
to avoid merge conflict with this series.

These patches are tested on 4.16 kernel with Cortex-A75 based SoC.

The test used for verifying these patches is a stress test on
ioremap/unmap which tries to re-use same io-address but changes
size of mapping randomly i.e. 4K to 2M to 1G etc. The same test
used to reproduce 3rd level translation fault without these fixes
(and also of course with Revert "arm64: Enforce BBM for huge IO/VMAP
mappings" being part of the tree).

These patches can also go into '-stable' branch (if accepted)
for 4.6 onwards.

>From V11->V12:
 - Introduced p*d_page_vaddr helper macros and using them
 - Rebased over current tip

>From V10->V11:
 - Updated pud_free_pmd_page & pmd_free_pte_page to use consistent
   conding style
 - Fixed few bugs by using pmd_page_paddr & pud_page_paddr

>From V9->V10:
 - Updated commit log for patch 1/4 by Toshi
 - Addressed review comments by Will on patch 3/4

>From V8->V9:
 - Used __TLBI_VADDR macros in new TLB flush API

>From V7->V8:
 - Properly fixed compilation issue in x86 file

>From V6->V7:
 - Fixed compilation issue in x86 case
 - V6 patches were not properly enumarated

>From V5->V6:
 - Use __flush_tlb_kernel_pgtable() for both PUD and PMD. Remove
   "bool tlb_inv" based variance as it is not need now
 - Re-naming for consistency

>From V4->V5:
 - Add new API __flush_tlb_kernel_pgtable(unsigned long addr)
   for kernel addresses

>From V3->V4:
 - Add header for 'addr' in x86 implementation
 - Re-order pmd/pud clear and table free
 - Avoid redundant TLB invalidatation in one perticular case

>From V2->V3:
 - Use the exisiting page table free interface to do arm64
   specific things

>From V1->V2:
 - Rebased my patches on top of "[PATCH v2 1/2] mm/vmalloc:
   Add interfaces to free unmapped page table"
 - Honored BBM for ARM64

Chintan Pandya (5):
  ioremap: Update pgtable free interfaces with addr
  arm64: tlbflush: Introduce __flush_tlb_kernel_pgtable
  arm64: pgtable: Add p*d_page_vaddr helper macros
  arm64: Implement page table free interfaces
  arm64: Re-enable huge io mappings

 arch/arm64/include/asm/pgtable.h  |  3 +++
 arch/arm64/include/asm/tlbflush.h |  7 +++++
 arch/arm64/mm/mmu.c               | 56 +++++++++++++++++++++++++--------------
 arch/x86/mm/pgtable.c             |  8 +++---
 include/asm-generic/pgtable.h     |  8 +++---
 lib/ioremap.c                     |  4 +--
 6 files changed, 57 insertions(+), 29 deletions(-)

-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation
Center, Inc., is a member of Code Aurora Forum, a Linux Foundation
Collaborative Project

^ permalink raw reply

* [PATCH 1/4] arm64/mm: pass swapper_pg_dir as an argument to __enable_mmu()
From: James Morse @ 2018-06-01 12:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180601080833.11762-1-yaojun8558363@gmail.com>

Hi Jun Yao,

On 01/06/18 09:08, Jun Yao wrote:
> Introduce __pa_swapper_pg_dir to save physical address of
> swapper_pg_dir. And pass it as an argument to __enable_mmu().


> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index b0853069702f..e3bb44b4b6c6 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -706,6 +706,8 @@ secondary_startup:
>  	 * Common entry point for secondary CPUs.
>  	 */
>  	bl	__cpu_setup			// initialise processor
> +	adrp    x25, idmap_pg_dir
> +	ldr_l   x26, __pa_swapper_pg_dir
>  	bl	__enable_mmu
>  	ldr	x8, =__secondary_switched
>  	br	x8

'__pa_swapper_pg_dir' here is read with the MMU off, but you write it with the
MMU on. To make this safe, you need to clean this value to the 'PoC' each time
you write it, so that secondaries here will read the new value.

Please put __pa_swapper_pg_dir in the mmuoff.data.read section, this ensures
hibernate will re-clean this value to the PoC once it has restored the memory.


> @@ -761,10 +763,8 @@ ENTRY(__enable_mmu)
>  	cmp	x2, #ID_AA64MMFR0_TGRAN_SUPPORTED
>  	b.ne	__no_granule_support
>  	update_early_cpu_boot_status 0, x1, x2
> -	adrp	x1, idmap_pg_dir
> -	adrp	x2, swapper_pg_dir
> -	phys_to_ttbr x3, x1
> -	phys_to_ttbr x4, x2
> +	phys_to_ttbr x3, x25
> +	phys_to_ttbr x4, x26
>  	msr	ttbr0_el1, x3			// load TTBR0
>  	msr	ttbr1_el1, x4			// load TTBR1
>  	isb

__enable_mmu() is now taking arguments in x25 and x26. Please update the comment
above it that describes the 'x0' argument.

Why do you pass the idmap ttbr value in too? Its always the same.


> @@ -823,6 +823,8 @@ __primary_switch:
>  	mrs	x20, sctlr_el1			// preserve old SCTLR_EL1 value
>  #endif
>  
> +	adrp    x25, idmap_pg_dir
> +	adrp    x26, swapper_pg_dir
>  	bl	__enable_mmu
>  #ifdef CONFIG_RELOCATABLE
>  	bl	__relocate_kernel

> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 2dbb2c9f1ec1..41eee333f91a 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -55,6 +55,8 @@ u64 idmap_ptrs_per_pgd = PTRS_PER_PGD;
>  u64 kimage_voffset __ro_after_init;
>  EXPORT_SYMBOL(kimage_voffset);
>  
> +phys_addr_t __pa_swapper_pg_dir;

See the definition of 'secondary_holding_pen_release' for an example of how to
put this in the mmuoff.data.read section.


> +
>  /*
>   * Empty_zero_page is a special page that is used for zero-initialized data
>   * and COW.
> @@ -631,6 +633,8 @@ void __init paging_init(void)
>  	phys_addr_t pgd_phys = early_pgtable_alloc();
>  	pgd_t *pgdp = pgd_set_fixmap(pgd_phys);
>  
> +	__pa_swapper_pg_dir = __pa_symbol(swapper_pg_dir);

This write needs to be cleaned to the PoC, see write_pen_release() for an example.


>  	map_kernel(pgdp);
>  	map_mem(pgdp);
>  


Thanks,

James

^ permalink raw reply

* [PATCH 0/4] lib/vsprintf: Remove atomic-unsafe support for printk format %pCr
From: Petr Mladek @ 2018-06-01 11:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CA+55aFxHHSRnDbbNGq6SwNAwEt0EhX15n_pNqon3MzGYJgMJmA@mail.gmail.com>

On Fri 2018-06-01 06:00:47, Linus Torvalds wrote:
> On Fri, Jun 1, 2018 at 4:29 AM Geert Uytterhoeven
> <geert+renesas@glider.be> wrote:
> >
> > This patch series:
> >   - Changes all existing users of "%pCr" to print the result of
> >     clk_get_rate() directly, which is safe as they all do this in task
> >     context only,
> >   - Removes support for the "%pCr" printk format.
> 
> Looks good to me.
> 
> What tree will this go through? The normal printk one? Just checking
> that this doesn't end up falling through the cracks because nobody
> knows who would take it...

I will take it via printk.git. There already is bunch of vsprintf
changes for-4.18.

Best Regards,
Petr

^ permalink raw reply

* [PATCHv2 19/19] arm64: implement syscall wrappers
From: Mark Rutland @ 2018-06-01 11:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180601112441.37810-1-mark.rutland@arm.com>

To minimize the risk of userspace-controlled values being used under
speculation, this patch adds pt_regs based syscall wrappers for arm64,
which pass the minimum set of required userspace values to syscall
implementations. For each syscall, a wrapper which takes a pt_regs
argument is automatically generated, and this extracts the arguments
before calling the "real" syscall implementation.

Each syscall has three functions generated:

* __do_<compat_>sys_<name> is the "real" syscall implementation, with
  the expected prototype.

* __se_<compat_>sys_<name> is the sign-extension/narrowing wrapper,
  inherited from common code. This takes a series of long parameters,
  casting each to the requisite types required by the "real" syscall
  implementation in __do_<compat_>sys_<name>.

  This wrapper *may* not be necessary on arm64 given the AAPCS rules on
  unused register bits, but it seemed safer to keep the wrapper for now.

* __arm64_<compat_>_sys_<name> takes a struct pt_regs pointer, and
  extracts *only* the relevant register values, passing these on to the
  __se_<compat_>sys_<name> wrapper.

The syscall invocation code is updated to handle the calling convention
required by __arm64_<compat_>_sys_<name>, and passes a single struct
pt_regs pointer.

The compiler can fold the syscall implementation and its wrappers, such
that the overhead of this approach is minimized.

Note that we play games with sys_ni_syscall(). It can't be defined with
SYSCALL_DEFINE0() because we must avoid the possibility of error
injection. Additionally, there are a couple of locations where we need
to call it from C code, and we don't (currently) have a
ksys_ni_syscall().  While it has no wrapper, passing in a redundant
pt_regs pointer is benign per the AAPCS.

When ARCH_HAS_SYSCALL_WRAPPER is selected, no prototype is define for
sys_ni_syscall(). Since we need to treat it differently for in-kernel
calls and the syscall tables, the prototype is defined as-required.

The wrappers are largely the same as their x86 counterparts, but
simplified as we don't have a variety of compat calling conventions that
require separate stubs. Unlike x86, we have some zero-argument compat
syscalls, and must define COMPAT_SYSCALL_DEFINE0() to ensure that these
are also given an __arm64_compat_sys_ prefix.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/Kconfig                       |  1 +
 arch/arm64/include/asm/syscall_wrapper.h | 80 ++++++++++++++++++++++++++++++++
 arch/arm64/kernel/sys.c                  | 10 +++-
 arch/arm64/kernel/sys32.c                |  9 +++-
 arch/arm64/kernel/syscall.c              |  8 +---
 arch/arm64/kernel/traps.c                |  2 +
 6 files changed, 101 insertions(+), 9 deletions(-)
 create mode 100644 arch/arm64/include/asm/syscall_wrapper.h

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 0b98a6c42454..4c18c6b3c915 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -23,6 +23,7 @@ config ARM64
 	select ARCH_HAS_SG_CHAIN
 	select ARCH_HAS_STRICT_KERNEL_RWX
 	select ARCH_HAS_STRICT_MODULE_RWX
+	select ARCH_HAS_SYSCALL_WRAPPER
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select ARCH_INLINE_READ_LOCK if !PREEMPT
diff --git a/arch/arm64/include/asm/syscall_wrapper.h b/arch/arm64/include/asm/syscall_wrapper.h
new file mode 100644
index 000000000000..a4477e515b79
--- /dev/null
+++ b/arch/arm64/include/asm/syscall_wrapper.h
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * syscall_wrapper.h - arm64 specific wrappers to syscall definitions
+ *
+ * Based on arch/x86/include/asm_syscall_wrapper.h
+ */
+
+#ifndef __ASM_SYSCALL_WRAPPER_H
+#define __ASM_SYSCALL_WRAPPER_H
+
+#define SC_ARM64_REGS_TO_ARGS(x, ...)				\
+	__MAP(x,__SC_ARGS					\
+	      ,,regs->regs[0],,regs->regs[1],,regs->regs[2]	\
+	      ,,regs->regs[3],,regs->regs[4],,regs->regs[5])
+
+#ifdef CONFIG_COMPAT
+
+#define COMPAT_SYSCALL_DEFINEx(x, name, ...)						\
+	asmlinkage long __arm64_compat_sys##name(const struct pt_regs *regs);		\
+	ALLOW_ERROR_INJECTION(__arm64_compat_sys##name, ERRNO);				\
+	static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__));		\
+	static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));	\
+	asmlinkage long __arm64_compat_sys##name(const struct pt_regs *regs)		\
+	{										\
+		return __se_compat_sys##name(SC_ARM64_REGS_TO_ARGS(x,__VA_ARGS__));	\
+	}										\
+	static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))		\
+	{										\
+		return __do_compat_sys##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__));	\
+	}										\
+	static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
+
+#define COMPAT_SYSCALL_DEFINE0(sname)					\
+	asmlinkage long __arm64_compat_sys_##sname(void);		\
+	ALLOW_ERROR_INJECTION(__arm64_compat_sys_##sname, ERRNO);	\
+	asmlinkage long __arm64_compat_sys_##sname(void)
+
+#define COND_SYSCALL_COMPAT(name) \
+	cond_syscall(__arm64_compat_sys_##name);
+
+#define COMPAT_SYS_NI(name) \
+	SYSCALL_ALIAS(__arm64_compat_sys_##name, sys_ni_posix_timers);
+
+#endif /* CONFIG_COMPAT */
+
+#define __SYSCALL_DEFINEx(x, name, ...)						\
+	asmlinkage long __arm64_sys##name(const struct pt_regs *regs);		\
+	ALLOW_ERROR_INJECTION(__arm64_sys##name, ERRNO);			\
+	static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__));		\
+	static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));	\
+	asmlinkage long __arm64_sys##name(const struct pt_regs *regs)		\
+	{									\
+		return __se_sys##name(SC_ARM64_REGS_TO_ARGS(x,__VA_ARGS__));	\
+	}									\
+	static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))		\
+	{									\
+		long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));	\
+		__MAP(x,__SC_TEST,__VA_ARGS__);					\
+		__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__));		\
+		return ret;							\
+	}									\
+	static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
+
+#ifndef SYSCALL_DEFINE0
+#define SYSCALL_DEFINE0(sname)					\
+	SYSCALL_METADATA(_##sname, 0);				\
+	asmlinkage long __arm64_sys_##sname(void);		\
+	ALLOW_ERROR_INJECTION(__arm64_sys_##sname, ERRNO);	\
+	asmlinkage long __arm64_sys_##sname(void)
+#endif
+
+#ifndef COND_SYSCALL
+#define COND_SYSCALL(name) cond_syscall(__arm64_sys_##name)
+#endif
+
+#ifndef SYS_NI
+#define SYS_NI(name) SYSCALL_ALIAS(__arm64_sys_##name, sys_ni_posix_timers);
+#endif
+
+#endif /* __ASM_SYSCALL_WRAPPER_H */
diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
index 2ad1497a184e..ee93bf789f0a 100644
--- a/arch/arm64/kernel/sys.c
+++ b/arch/arm64/kernel/sys.c
@@ -48,11 +48,17 @@ SYSCALL_DEFINE1(arm64_personality, unsigned int, personality)
 /*
  * Wrappers to pass the pt_regs argument.
  */
-asmlinkage long sys_rt_sigreturn(void);
 #define sys_personality		sys_arm64_personality
 
+asmlinkage long sys_ni_syscall(const struct pt_regs *);
+#define __arm64_sys_ni_syscall	sys_ni_syscall
+
+#undef __SYSCALL
+#define __SYSCALL(nr, sym)	asmlinkage long __arm64_##sym(const struct pt_regs *);
+#include <asm/unistd.h>
+
 #undef __SYSCALL
-#define __SYSCALL(nr, sym)	[nr] = sym,
+#define __SYSCALL(nr, sym)	[nr] = __arm64_##sym,
 
 /*
  * The sys_call_table array must be 4K aligned to be accessible from
diff --git a/arch/arm64/kernel/sys32.c b/arch/arm64/kernel/sys32.c
index 793bd0952ee0..533c97c5c232 100644
--- a/arch/arm64/kernel/sys32.c
+++ b/arch/arm64/kernel/sys32.c
@@ -131,8 +131,15 @@ COMPAT_SYSCALL_DEFINE6(aarch32_fallocate, int, fd, int, mode,
 	return ksys_fallocate(fd, mode, arg_u64(offset), arg_u64(len));
 }
 
+asmlinkage long sys_ni_syscall(const struct pt_regs *);
+#define __arm64_sys_ni_syscall	sys_ni_syscall
+
+#undef __SYSCALL
+#define __SYSCALL(nr, sym)	asmlinkage long __arm64_##sym(const struct pt_regs *);
+#include <asm/unistd32.h>
+
 #undef __SYSCALL
-#define __SYSCALL(nr, sym)	[nr] = sym,
+#define __SYSCALL(nr, sym)	[nr] = __arm64_##sym,
 
 /*
  * The sys_call_table array must be 4K aligned to be accessible from
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 6a31bb2a382b..e5985924f57e 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -12,15 +12,11 @@
 
 long do_ni_syscall(struct pt_regs *regs);
 
-typedef long (*syscall_fn_t)(unsigned long, unsigned long,
-			     unsigned long, unsigned long,
-			     unsigned long, unsigned long);
+typedef long (*syscall_fn_t)(struct pt_regs *regs);
 
 static void __invoke_syscall(struct pt_regs *regs, syscall_fn_t syscall_fn)
 {
-	regs->regs[0] = syscall_fn(regs->regs[0], regs->regs[1],
-				   regs->regs[2], regs->regs[3],
-				   regs->regs[4], regs->regs[5]);
+	regs->regs[0] = syscall_fn(regs);
 }
 
 static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index b8d3e0d8c616..8bfcc37cbc65 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -549,6 +549,8 @@ asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs)
 
 long compat_arm_syscall(struct pt_regs *regs);
 
+long sys_ni_syscall(void);
+
 asmlinkage long do_ni_syscall(struct pt_regs *regs)
 {
 #ifdef CONFIG_COMPAT
-- 
2.11.0

^ permalink raw reply related


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