* [Bug 209869] Kernel 5.10-rc1 fails to boot on a PowerMac G4 3,6 at an early stage
From: bugzilla-daemon @ 2020-11-05 16:13 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-209869-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=209869
--- Comment #10 from Erhard F. (erhard_f@mailbox.org) ---
(In reply to Christophe Leroy from comment #9)
> Ok, what about 5.10-rc1 + KASAN without reverting the patch ?
Nope, does not boot. Same 5.10-rc1 .config + KASAN but without reverting the
patch.
--
You are receiving this mail because:
You are watching the assignee of the bug.
^ permalink raw reply
* [PATCH] powerpc: topology.h: fix build when CONFIG_NUMA=n
From: Scott Cheloha @ 2020-11-05 16:20 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nathan Lynch, Laurent Dufour, kernel test robot
Add a non-NUMA definition for of_drconf_to_nid_single() to topology.h
so we have one even if powerpc/mm/numa.c is not compiled. On a non-NUMA
kernel the appropriate node id is always first_online_node.
Signed-off-by: Scott Cheloha <cheloha@linux.ibm.com>
Reported-by: kernel test robot <lkp@intel.com>
Fixes: 72cdd117c449 ("pseries/hotplug-memory: hot-add: skip redundant LMB lookup")
---
arch/powerpc/include/asm/topology.h | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index 8728590f514a..90d2424418b5 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -61,6 +61,10 @@ static inline int early_cpu_to_node(int cpu)
*/
return (nid < 0) ? 0 : nid;
}
+
+struct drmem_lmb;
+extern int of_drconf_to_nid_single(struct drmem_lmb *lmb);
+
#else
static inline int early_cpu_to_node(int cpu) { return 0; }
@@ -84,10 +88,13 @@ static inline int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
return 0;
}
-#endif /* CONFIG_NUMA */
-
struct drmem_lmb;
-int of_drconf_to_nid_single(struct drmem_lmb *lmb);
+static inline int of_drconf_to_nid_single(struct drmem_lmb *lmb)
+{
+ return first_online_node;
+}
+
+#endif /* CONFIG_NUMA */
#if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR)
extern int find_and_online_cpu_nid(int cpu);
--
2.28.0
^ permalink raw reply related
* Re: [PATCH] powerpc: topology.h: fix build when CONFIG_NUMA=n
From: Christophe Leroy @ 2020-11-05 17:34 UTC (permalink / raw)
To: Scott Cheloha, linuxppc-dev
Cc: Nathan Lynch, Laurent Dufour, kernel test robot
In-Reply-To: <20201105162018.3559108-1-cheloha@linux.ibm.com>
Le 05/11/2020 à 17:20, Scott Cheloha a écrit :
> Add a non-NUMA definition for of_drconf_to_nid_single() to topology.h
> so we have one even if powerpc/mm/numa.c is not compiled. On a non-NUMA
> kernel the appropriate node id is always first_online_node.
>
> Signed-off-by: Scott Cheloha <cheloha@linux.ibm.com>
> Reported-by: kernel test robot <lkp@intel.com>
> Fixes: 72cdd117c449 ("pseries/hotplug-memory: hot-add: skip redundant LMB lookup")
> ---
> arch/powerpc/include/asm/topology.h | 13 ++++++++++---
> 1 file changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
> index 8728590f514a..90d2424418b5 100644
> --- a/arch/powerpc/include/asm/topology.h
> +++ b/arch/powerpc/include/asm/topology.h
> @@ -61,6 +61,10 @@ static inline int early_cpu_to_node(int cpu)
> */
> return (nid < 0) ? 0 : nid;
> }
> +
> +struct drmem_lmb;
Can you put that before the #ifdef CONFIG_NUMA in order to avoid duplicating it ?
> +extern int of_drconf_to_nid_single(struct drmem_lmb *lmb);
'extern' keywork is useless on a function prototype, don't add one, keep the prototype as before, ie:
int of_drconf_to_nid_single(struct drmem_lmb *lmb);
> +
> #else
>
> static inline int early_cpu_to_node(int cpu) { return 0; }
> @@ -84,10 +88,13 @@ static inline int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
> return 0;
> }
>
> -#endif /* CONFIG_NUMA */
> -
> struct drmem_lmb;
Can you put that before the #ifdef CONFIG_NUMA in order to avoid duplicating it ?
> -int of_drconf_to_nid_single(struct drmem_lmb *lmb);
> +static inline int of_drconf_to_nid_single(struct drmem_lmb *lmb)
> +{
> + return first_online_node;
> +}
> +
> +#endif /* CONFIG_NUMA */
>
> #if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR)
> extern int find_and_online_cpu_nid(int cpu);
>
Christophe
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: misc: convert fsl, dpaa2-console from txt to YAML
From: Rob Herring @ 2020-11-05 19:06 UTC (permalink / raw)
To: Laurentiu Tudor
Cc: devicetree, corbet, netdev, linux-doc, linux-kernel, leoyang.li,
robh+dt, ioana.ciornei, Ionut-robert Aron, kuba, linuxppc-dev,
davem, linux-arm-kernel
In-Reply-To: <20201105141114.18161-1-laurentiu.tudor@nxp.com>
On Thu, 05 Nov 2020 16:11:13 +0200, Laurentiu Tudor wrote:
> From: Ionut-robert Aron <ionut-robert.aron@nxp.com>
>
> Convert fsl,dpaa2-console to YAML in order to automate the
> verification process of dts files.
>
> Signed-off-by: Ionut-robert Aron <ionut-robert.aron@nxp.com>
> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> ---
> .../bindings/misc/fsl,dpaa2-console.txt | 11 ---------
> .../bindings/misc/fsl,dpaa2-console.yaml | 23 +++++++++++++++++++
> 2 files changed, 23 insertions(+), 11 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/misc/fsl,dpaa2-console.txt
> create mode 100644 Documentation/devicetree/bindings/misc/fsl,dpaa2-console.yaml
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/misc/fsl,dpaa2-console.yaml: 'additionalProperties' is a required property
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/misc/fsl,dpaa2-console.yaml: ignoring, error in schema:
warning: no schema found in file: ./Documentation/devicetree/bindings/misc/fsl,dpaa2-console.yaml
See https://patchwork.ozlabs.org/patch/1395015
The base for the patch is generally the last rc1. Any dependencies
should be noted.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit.
^ permalink raw reply
* Re: [PATCH 2/2] dt-bindings: misc: convert fsl,qoriq-mc from txt to YAML
From: Rob Herring @ 2020-11-05 19:07 UTC (permalink / raw)
To: Laurentiu Tudor
Cc: devicetree, linux-doc, netdev, corbet, linux-kernel, leoyang.li,
robh+dt, ioana.ciornei, Ionut-robert Aron, kuba, linuxppc-dev,
davem, linux-arm-kernel
In-Reply-To: <20201105141114.18161-2-laurentiu.tudor@nxp.com>
On Thu, 05 Nov 2020 16:11:14 +0200, Laurentiu Tudor wrote:
> From: Ionut-robert Aron <ionut-robert.aron@nxp.com>
>
> Convert fsl,qoriq-mc to YAML in order to automate the verification
> process of dts files. In addition, update MAINTAINERS accordingly
> and, while at it, add some missing files.
>
> Signed-off-by: Ionut-robert Aron <ionut-robert.aron@nxp.com>
> [laurentiu.tudor@nxp.com: update MINTAINERS, updates & fixes in schema]
> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> ---
> .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 196 ----------------
> .../bindings/misc/fsl,qoriq-mc.yaml | 218 ++++++++++++++++++
> .../ethernet/freescale/dpaa2/overview.rst | 5 +-
> MAINTAINERS | 4 +-
> 4 files changed, 225 insertions(+), 198 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
> create mode 100644 Documentation/devicetree/bindings/misc/fsl,qoriq-mc.yaml
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
./Documentation/devicetree/bindings/misc/fsl,qoriq-mc.yaml:128:9: [warning] wrong indentation: expected 10 but found 8 (indentation)
dtschema/dtc warnings/errors:
See https://patchwork.ozlabs.org/patch/1395017
The base for the patch is generally the last rc1. Any dependencies
should be noted.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit.
^ permalink raw reply
* Re: [PATCH 2/2] dt-bindings: misc: convert fsl,qoriq-mc from txt to YAML
From: Rob Herring @ 2020-11-05 19:17 UTC (permalink / raw)
To: Laurentiu Tudor
Cc: devicetree, corbet, netdev, linux-doc, linux-kernel, leoyang.li,
ioana.ciornei, Ionut-robert Aron, kuba, linuxppc-dev, davem,
linux-arm-kernel
In-Reply-To: <20201105141114.18161-2-laurentiu.tudor@nxp.com>
On Thu, Nov 05, 2020 at 04:11:14PM +0200, Laurentiu Tudor wrote:
> From: Ionut-robert Aron <ionut-robert.aron@nxp.com>
>
> Convert fsl,qoriq-mc to YAML in order to automate the verification
> process of dts files. In addition, update MAINTAINERS accordingly
> and, while at it, add some missing files.
>
> Signed-off-by: Ionut-robert Aron <ionut-robert.aron@nxp.com>
> [laurentiu.tudor@nxp.com: update MINTAINERS, updates & fixes in schema]
> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> ---
> .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 196 ----------------
> .../bindings/misc/fsl,qoriq-mc.yaml | 218 ++++++++++++++++++
> .../ethernet/freescale/dpaa2/overview.rst | 5 +-
> MAINTAINERS | 4 +-
> 4 files changed, 225 insertions(+), 198 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
> create mode 100644 Documentation/devicetree/bindings/misc/fsl,qoriq-mc.yaml
[...]
> diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.yaml b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.yaml
> new file mode 100644
> index 000000000000..9e89fd8eb635
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.yaml
> @@ -0,0 +1,218 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright 2020 NXP
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/misc/fsl,qoriq-mc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +maintainers:
> + - Laurentiu Tudor <laurentiu.tudor@nxp.com>
> +
> +title: Freescale Management Complex
> +
> +description: |
> + The Freescale Management Complex (fsl-mc) is a hardware resource
> + manager that manages specialized hardware objects used in
> + network-oriented packet processing applications. After the fsl-mc
> + block is enabled, pools of hardware resources are available, such as
> + queues, buffer pools, I/O interfaces. These resources are building
> + blocks that can be used to create functional hardware objects/devices
> + such as network interfaces, crypto accelerator instances, L2 switches,
> + etc.
> +
> + For an overview of the DPAA2 architecture and fsl-mc bus see:
> + Documentation/networking/device_drivers/freescale/dpaa2/overview.rst
> +
> + As described in the above overview, all DPAA2 objects in a DPRC share the
> + same hardware "isolation context" and a 10-bit value called an ICID
> + (isolation context id) is expressed by the hardware to identify
> + the requester.
> +
> + The generic 'iommus' property is insufficient to describe the relationship
> + between ICIDs and IOMMUs, so an iommu-map property is used to define
> + the set of possible ICIDs under a root DPRC and how they map to
> + an IOMMU.
> +
> + For generic IOMMU bindings, see:
> + Documentation/devicetree/bindings/iommu/iommu.txt.
> +
> + For arm-smmu binding, see:
> + Documentation/devicetree/bindings/iommu/arm,smmu.yaml.
> +
> + MC firmware binary images can be found here:
> + https://github.com/NXP/qoriq-mc-binary
> +
> +properties:
> + compatible:
> + const: "fsl,qoriq-mc"
Don't need quotes.
> + description: "Must be 'fsl,qoriq-mc'. A Freescale Management Complex
Drop ^^^^^^^^^^^^^^^^^^^^^^^^
The schema says that.
> + compatible with this binding must have Block Revision
> + Registers BRR1 and BRR2 at offset 0x0BF8 and 0x0BFC in
> + the MC control register region."
> +
> + reg:
> + description: "A standard property. Specifies one or two regions defining
Don't need quotes. You need '|' for a literal block to keep formatting.
But all this should be expressed as schema...
> + the MC's registers:
> +
> + - the first region is the command portal for the this machine
> + and must always be present
> +
> + - the second region is the MC control registers. This region
> + may not be present in some scenarios, such as in the device
> + tree presented to a virtual machine."
reg:
minItems: 1
items:
- description: the command portal for the this machine
- description: MC control registers. This region may not be present
in some scenarios, such as in the device tree presented to a
virtual machine.
> +
> + ranges:
> + description: "A standard property. Defines the mapping between the child
> + MC address space and the parent system address space.
> +
> + The MC address space is defined by 3 components:
> + <region type> <offset hi> <offset lo>
> +
> + Valid values for region type are:
> + 0x0 - MC portals
> + 0x1 - QBMAN portals"
> +
> + '#address-cells':
> + const: 3
> +
> + '#size-cells':
> + const: 1
> +
> + dpmacs:
> + type: object
> + description: "The fsl-mc node may optionally have dpmac sub-nodes that
> + describe the relationship between the Ethernet MACs which belong
> + to the MC and the Ethernet PHYs on the system board.
> +
> + The dpmac nodes must be under a node named 'dpmacs' which
> + contains the following properties:
> +
> + - '#address-cells'
> + const: 1
> + description: Must be present if dpmac sub-nodes are defined
> + and must have a value of 1.
> +
> + - '#size-cells'
> + const: 0
> + description: Must be present if dpmac sub-nodes are defined
> + and must have a value of 0."
Drop whatever description can be expressed in schemas.
> +
> + properties:
> + '#address-cells':
> + const: 1
> +
> + '#size-cells':
> + const: 0
> +
> + patternProperties:
> + "^dpmac@[0-9a-f]+$":
> + type: object
> +
> + description: "dpmac sub-node that describes the relationship between the
> + Ethernet MACs which belong to the MC and the Ethernet PHYs
> + on the system board."
> +
> + properties:
> + compatible:
> + const: "fsl,qoriq-mc-dpmac"
> +
> + reg:
> + description: Specifies the id of the dpmac
Constraints on the value?
> +
> + phy-handle:
> + $ref: /schemas/types.yaml#definitions/phandle
> + description: "Specifies the phandle to the PHY device node
> + associated with the this dpmac."
> +
> + required:
> + - compatible
> + - reg
> + - phy-handle
> +
> + iommu-map:
> + description: |
> + Maps an ICID to an IOMMU and associated iommu-specifier data.
> +
> + The property is an arbitrary number of tuples of
> + (icid-base, iommu, iommu-base, length).
> +
> + Any ICID i in the interval [icid-base, icid-base + length) is
> + associated with the listed IOMMU, with the iommu-specifier
> + (i - icid-base + iommu-base).
> +
> + msi-map:
> + description: |
> + Maps an ICID to a GIC ITS and associated msi-specifier data.
> +
> + The property is an arbitrary number of tuples of
> + (icid-base, gic-its, msi-base, length).
> +
> + Any ICID in the interval [icid-base, icid-base + length) is
> + associated with the listed GIC ITS, with the msi-specifier
> + (i - icid-base + msi-base).
> +
> + msi-parent:
> + deprecated: true
> + description: "Points to the MSI controller node handling message interrupts
> + for the MC."
> +
> +required:
> + - compatible
> + - reg
> + - iommu-map
> + - msi-map
> + - ranges
> + - '#address-cells'
> + - '#size-cells'
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + soc {
> + #address-cells = <2>;
> + #size-cells = <2>;
> +
> + smmu: iommu@5000000 {
> + compatible = "arm,mmu-500";
> + #global-interrupts = <1>;
> + #iommu-cells = <1>;
> + reg = <0 0x5000000 0 0x800000>;
> + stream-match-mask = <0x7c00>;
> + interrupts = <0 13 4>,
> + <0 146 4>, <0 147 4>,
> + <0 148 4>, <0 149 4>,
> + <0 150 4>, <0 151 4>,
> + <0 152 4>, <0 153 4>;
> + };
> +
> + fsl_mc: fsl-mc@80c000000 {
> + compatible = "fsl,qoriq-mc";
> + reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */
> + <0x00000000 0x08340000 0 0x40000>; /* MC control reg */
> + /* define map for ICIDs 23-64 */
> + iommu-map = <23 &smmu 23 41>;
> + /* define msi map for ICIDs 23-64 */
> + msi-map = <23 &its 23 41>;
> + #address-cells = <3>;
> + #size-cells = <1>;
> +
> + /*
> + * Region type 0x0 - MC portals
> + * Region type 0x1 - QBMAN portals
> + */
> + ranges = <0x0 0x0 0x0 0x8 0x0c000000 0x4000000
> + 0x1 0x0 0x0 0x8 0x18000000 0x8000000>;
> +
> + dpmacs {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + dpmac@1 {
> + compatible = "fsl,qoriq-mc-dpmac";
> + reg = <1>;
> + phy-handle = <&mdio0_phy0>;
> + };
> + };
> + };
> + };
> diff --git a/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/overview.rst b/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/overview.rst
> index d638b5a8aadd..b3261c5871cc 100644
> --- a/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/overview.rst
> +++ b/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/overview.rst
> @@ -28,6 +28,9 @@ interfaces, an L2 switch, or accelerator instances.
> The MC provides memory-mapped I/O command interfaces (MC portals)
> which DPAA2 software drivers use to operate on DPAA2 objects.
>
> +MC firmware binary images can be found here:
> +https://github.com/NXP/qoriq-mc-binary
> +
> The diagram below shows an overview of the DPAA2 resource management
> architecture::
>
> @@ -338,7 +341,7 @@ Key functions include:
> a bind of the root DPRC to the DPRC driver
>
> The binding for the MC-bus device-tree node can be consulted at
> -*Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt*.
> +*Documentation/devicetree/bindings/misc/fsl,qoriq-mc.yaml*.
> The sysfs bind/unbind interfaces for the MC-bus can be consulted at
> *Documentation/ABI/testing/sysfs-bus-fsl-mc*.
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index b43b59542d15..400a17c90edb 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14409,9 +14409,11 @@ M: Stuart Yoder <stuyoder@gmail.com>
> M: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> L: linux-kernel@vger.kernel.org
> S: Maintained
> -F: Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
> +F: Documentation/devicetree/bindings/misc/fsl,dpaa2-console.yaml
> +F: Documentation/devicetree/bindings/misc/fsl,qoriq-mc.yaml
> F: Documentation/networking/device_drivers/ethernet/freescale/dpaa2/overview.rst
> F: drivers/bus/fsl-mc/
> +F: include/linux/fsl/mc.h
>
> QT1010 MEDIA DRIVER
> M: Antti Palosaari <crope@iki.fi>
> --
> 2.17.1
>
^ permalink raw reply
* Re: [PATCH 2/2] dt-bindings: misc: convert fsl,qoriq-mc from txt to YAML
From: Laurentiu Tudor @ 2020-11-05 19:26 UTC (permalink / raw)
To: Rob Herring
Cc: devicetree, corbet, netdev, linux-doc, linux-kernel, leoyang.li,
ioana.ciornei, Ionut-robert Aron, kuba, linuxppc-dev, davem,
linux-arm-kernel
In-Reply-To: <20201105191745.GB1644330@bogus>
Hi Rob,
On 11/5/2020 9:17 PM, Rob Herring wrote:
> On Thu, Nov 05, 2020 at 04:11:14PM +0200, Laurentiu Tudor wrote:
>> From: Ionut-robert Aron <ionut-robert.aron@nxp.com>
>>
>> Convert fsl,qoriq-mc to YAML in order to automate the verification
>> process of dts files. In addition, update MAINTAINERS accordingly
>> and, while at it, add some missing files.
>>
>> Signed-off-by: Ionut-robert Aron <ionut-robert.aron@nxp.com>
>> [laurentiu.tudor@nxp.com: update MINTAINERS, updates & fixes in schema]
>> Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
>> ---
>> .../devicetree/bindings/misc/fsl,qoriq-mc.txt | 196 ----------------
>> .../bindings/misc/fsl,qoriq-mc.yaml | 218 ++++++++++++++++++
>> .../ethernet/freescale/dpaa2/overview.rst | 5 +-
>> MAINTAINERS | 4 +-
>> 4 files changed, 225 insertions(+), 198 deletions(-)
>> delete mode 100644 Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt
>> create mode 100644 Documentation/devicetree/bindings/misc/fsl,qoriq-mc.yaml
>
> [...]
>
>> diff --git a/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.yaml b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.yaml
>> new file mode 100644
>> index 000000000000..9e89fd8eb635
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/misc/fsl,qoriq-mc.yaml
>> @@ -0,0 +1,218 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +# Copyright 2020 NXP
>> +%YAML 1.2
>> +---
>> +$id: https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevicetree.org%2Fschemas%2Fmisc%2Ffsl%2Cqoriq-mc.yaml%23&data=04%7C01%7Claurentiu.tudor%40nxp.com%7C64a5aeb6fee5459041db08d881bf7bf2%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637402006701140599%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=fkXEIYUqXK1Dn6AqZtYLzro8nwJNCPJFI1Q9F9fRYxE%3D&reserved=0
>> +$schema: https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23&data=04%7C01%7Claurentiu.tudor%40nxp.com%7C64a5aeb6fee5459041db08d881bf7bf2%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637402006701140599%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=X7k0Sxh7uPo11GgkGCeaKKMzHdu0gtphKheyJeROZ9Q%3D&reserved=0
>> +
>> +maintainers:
>> + - Laurentiu Tudor <laurentiu.tudor@nxp.com>
>> +
>> +title: Freescale Management Complex
>> +
>> +description: |
>> + The Freescale Management Complex (fsl-mc) is a hardware resource
>> + manager that manages specialized hardware objects used in
>> + network-oriented packet processing applications. After the fsl-mc
>> + block is enabled, pools of hardware resources are available, such as
>> + queues, buffer pools, I/O interfaces. These resources are building
>> + blocks that can be used to create functional hardware objects/devices
>> + such as network interfaces, crypto accelerator instances, L2 switches,
>> + etc.
>> +
>> + For an overview of the DPAA2 architecture and fsl-mc bus see:
>> + Documentation/networking/device_drivers/freescale/dpaa2/overview.rst
>> +
>> + As described in the above overview, all DPAA2 objects in a DPRC share the
>> + same hardware "isolation context" and a 10-bit value called an ICID
>> + (isolation context id) is expressed by the hardware to identify
>> + the requester.
>> +
>> + The generic 'iommus' property is insufficient to describe the relationship
>> + between ICIDs and IOMMUs, so an iommu-map property is used to define
>> + the set of possible ICIDs under a root DPRC and how they map to
>> + an IOMMU.
>> +
>> + For generic IOMMU bindings, see:
>> + Documentation/devicetree/bindings/iommu/iommu.txt.
>> +
>> + For arm-smmu binding, see:
>> + Documentation/devicetree/bindings/iommu/arm,smmu.yaml.
>> +
>> + MC firmware binary images can be found here:
>> + https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FNXP%2Fqoriq-mc-binary&data=04%7C01%7Claurentiu.tudor%40nxp.com%7C64a5aeb6fee5459041db08d881bf7bf2%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637402006701140599%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=QKyEydXdS2AzqS7BlXVXDXpdjHfGL1%2BEdx95F1j5OHM%3D&reserved=0
>> +
>> +properties:
>> + compatible:
>> + const: "fsl,qoriq-mc"
>
> Don't need quotes.
>
>> + description: "Must be 'fsl,qoriq-mc'. A Freescale Management Complex
>
> Drop ^^^^^^^^^^^^^^^^^^^^^^^^
>
> The schema says that.
>
>> + compatible with this binding must have Block Revision
>> + Registers BRR1 and BRR2 at offset 0x0BF8 and 0x0BFC in
>> + the MC control register region."
>> +
>> + reg:
>> + description: "A standard property. Specifies one or two regions defining
>
> Don't need quotes. You need '|' for a literal block to keep formatting.
>
> But all this should be expressed as schema...
>
>> + the MC's registers:
>> +
>> + - the first region is the command portal for the this machine
>> + and must always be present
>> +
>> + - the second region is the MC control registers. This region
>> + may not be present in some scenarios, such as in the device
>> + tree presented to a virtual machine."
>
> reg:
> minItems: 1
> items:
> - description: the command portal for the this machine
> - description: MC control registers. This region may not be present
> in some scenarios, such as in the device tree presented to a
> virtual machine.
>
>> +
>> + ranges:
>> + description: "A standard property. Defines the mapping between the child
>> + MC address space and the parent system address space.
>> +
>> + The MC address space is defined by 3 components:
>> + <region type> <offset hi> <offset lo>
>> +
>> + Valid values for region type are:
>> + 0x0 - MC portals
>> + 0x1 - QBMAN portals"
>> +
>> + '#address-cells':
>> + const: 3
>> +
>> + '#size-cells':
>> + const: 1
>> +
>> + dpmacs:
>> + type: object
>> + description: "The fsl-mc node may optionally have dpmac sub-nodes that
>> + describe the relationship between the Ethernet MACs which belong
>> + to the MC and the Ethernet PHYs on the system board.
>> +
>> + The dpmac nodes must be under a node named 'dpmacs' which
>> + contains the following properties:
>> +
>> + - '#address-cells'
>> + const: 1
>> + description: Must be present if dpmac sub-nodes are defined
>> + and must have a value of 1.
>> +
>> + - '#size-cells'
>> + const: 0
>> + description: Must be present if dpmac sub-nodes are defined
>> + and must have a value of 0."
>
> Drop whatever description can be expressed in schemas.
>
>> +
>> + properties:
>> + '#address-cells':
>> + const: 1
>> +
>> + '#size-cells':
>> + const: 0
>> +
>> + patternProperties:
>> + "^dpmac@[0-9a-f]+$":
>> + type: object
>> +
>> + description: "dpmac sub-node that describes the relationship between the
>> + Ethernet MACs which belong to the MC and the Ethernet PHYs
>> + on the system board."
>> +
>> + properties:
>> + compatible:
>> + const: "fsl,qoriq-mc-dpmac"
>> +
>> + reg:
>> + description: Specifies the id of the dpmac
>
> Constraints on the value?
>
Thanks a lot for taking a look. Will take care in the next spin.
PS. Nice work on the validation tools. My ~1 month old version didn't
catch those errors.
---
Best Regards, Laurentiu
^ permalink raw reply
* Re: [PATCH 03/18] powerpc: bad_page_fault, do_break get registers from regs
From: kernel test robot @ 2020-11-05 20:43 UTC (permalink / raw)
To: Nicholas Piggin, linuxppc-dev; +Cc: kbuild-all, Nicholas Piggin
In-Reply-To: <20201105143431.1874789-4-npiggin@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3374 bytes --]
Hi Nicholas,
I love your patch! Yet something to improve:
[auto build test ERROR on powerpc/next]
[also build test ERROR on v5.10-rc2 next-20201105]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-interrupt-wrappers/20201105-231909
base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-allnoconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/4232a616cd2a8f7ef6b3f19cd656690dc5ec4c9e
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Nicholas-Piggin/powerpc-interrupt-wrappers/20201105-231909
git checkout 4232a616cd2a8f7ef6b3f19cd656690dc5ec4c9e
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
In file included from include/asm-generic/bug.h:5,
from arch/powerpc/include/asm/bug.h:109,
from include/linux/bug.h:5,
from include/linux/signal.h:5,
from arch/powerpc/mm/fault.c:14:
arch/powerpc/mm/fault.c: In function '__do_page_fault':
>> arch/powerpc/mm/fault.c:378:43: error: suggest parentheses around arithmetic in operand of '|' [-Werror=parentheses]
378 | #define page_fault_is_bad(__err) ((__err) & DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)
include/linux/compiler.h:78:42: note: in definition of macro 'unlikely'
78 | # define unlikely(x) __builtin_expect(!!(x), 0)
| ^
arch/powerpc/mm/fault.c:410:15: note: in expansion of macro 'page_fault_is_bad'
410 | if (unlikely(page_fault_is_bad(error_code))) {
| ^~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
vim +378 arch/powerpc/mm/fault.c
361
362 /*
363 * Define the correct "is_write" bit in error_code based
364 * on the processor family
365 */
366 #if (defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
367 #define page_fault_is_write(__err) ((__err) & ESR_DST)
368 #define page_fault_is_bad(__err) (0)
369 #else
370 #define page_fault_is_write(__err) ((__err) & DSISR_ISSTORE)
371 #if defined(CONFIG_PPC_8xx)
372 #define page_fault_is_bad(__err) ((__err) & DSISR_NOEXEC_OR_G)
373 #elif defined(CONFIG_PPC_BOOK3S_64)
374 #define page_fault_is_bad(__err) ((__err) & (DSISR_BAD_FAULT_64S | DSISR_DABRMATCH))
375 #elif defined(CONFIG_PPC_BOOK3E_64)
376 #define page_fault_is_bad(__err) ((__err) & DSISR_BAD_FAULT_64S)
377 #else
> 378 #define page_fault_is_bad(__err) ((__err) & DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)
379 #endif
380 #endif
381
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 6452 bytes --]
^ permalink raw reply
* [PATCH v2 00/16] PCI: dwc: Another round of clean-ups
From: Rob Herring @ 2020-11-05 21:11 UTC (permalink / raw)
To: Lorenzo Pieralisi
Cc: Kunihiko Hayashi, Neil Armstrong, linux-pci, Binghui Wang,
Bjorn Andersson, linux-tegra, Thierry Reding, linux-arm-kernel,
Thomas Petazzoni, Jonathan Chocron, Shawn Guo, Jonathan Hunter,
Fabio Estevam, Jerome Brunet, Jesper Nilsson, linux-samsung-soc,
Minghuan Lian, Kevin Hilman, Pratyush Anand, Krzysztof Kozlowski,
Kishon Vijay Abraham I, Kukjin Kim, Mingkai Hu, Xiaowei Song,
Marek Szyprowski, NXP Linux Team, Richard Zhu,
Martin Blumenstingl, linux-arm-msm, Sascha Hauer, Yue Wang,
Murali Karicheri, Bjorn Helgaas, linux-amlogic, linux-omap,
linux-arm-kernel, Roy Zang, Masahiro Yamada, Jingoo Han,
Andy Gross, Vidya Sagar, Stanimir Varbanov,
Pengutronix Kernel Team, Gustavo Pimentel, linuxppc-dev,
Lucas Stach
Here's another batch of DWC PCI host refactoring. This series primarily
moves more of the MSI, link up, and resource handling to the core
code. Beyond a couple of minor fixes, new in this version is runtime
detection of iATU regions instead of using DT properties.
No doubt I've probably broken something. Please test. I've run this thru
kernelci and checked boards with DWC PCI which currently is just
Layerscape boards (hint: add boards and/or enable PCI). A git branch is
here[1].
This is dependent on "PCI: dwc: Restore ATU memory resource setup to use
last entry" which will be in v5.10-rc3.
Rob
[1] git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git pci-more-dwc-cleanup
Rob Herring (16):
PCI: dwc: Support multiple ATU memory regions
PCI: dwc/intel-gw: Move ATU offset out of driver match data
PCI: dwc: Move "dbi", "dbi2", and "addr_space" resource setup into
common code
PCI: dwc/intel-gw: Remove some unneeded function wrappers
PCI: dwc: Ensure all outbound ATU windows are reset
PCI: dwc/dra7xx: Use the common MSI irq_chip
PCI: dwc: Drop the .set_num_vectors() host op
PCI: dwc: Move MSI interrupt setup into DWC common code
PCI: dwc: Rework MSI initialization
PCI: dwc: Move link handling into common code
PCI: dwc: Move dw_pcie_msi_init() into core
PCI: dwc: Move dw_pcie_setup_rc() to DWC common code
PCI: dwc: Remove unnecessary wrappers around dw_pcie_host_init()
Revert "PCI: dwc/keystone: Drop duplicated 'num-viewport'"
PCI: dwc: Move inbound and outbound windows to common struct
PCI: dwc: Detect number of iATU windows
drivers/pci/controller/dwc/pci-dra7xx.c | 141 +-----------------
drivers/pci/controller/dwc/pci-exynos.c | 50 ++-----
drivers/pci/controller/dwc/pci-imx6.c | 39 +----
drivers/pci/controller/dwc/pci-keystone.c | 79 ++--------
.../pci/controller/dwc/pci-layerscape-ep.c | 37 +----
drivers/pci/controller/dwc/pci-layerscape.c | 67 +--------
drivers/pci/controller/dwc/pci-meson.c | 53 ++-----
drivers/pci/controller/dwc/pcie-al.c | 29 +---
drivers/pci/controller/dwc/pcie-armada8k.c | 37 ++---
drivers/pci/controller/dwc/pcie-artpec6.c | 76 +---------
.../pci/controller/dwc/pcie-designware-ep.c | 58 +++----
.../pci/controller/dwc/pcie-designware-host.c | 139 ++++++++++-------
.../pci/controller/dwc/pcie-designware-plat.c | 70 +--------
drivers/pci/controller/dwc/pcie-designware.c | 93 +++++++++++-
drivers/pci/controller/dwc/pcie-designware.h | 24 +--
drivers/pci/controller/dwc/pcie-histb.c | 37 ++---
drivers/pci/controller/dwc/pcie-intel-gw.c | 67 ++-------
drivers/pci/controller/dwc/pcie-kirin.c | 62 +-------
drivers/pci/controller/dwc/pcie-qcom.c | 38 +----
drivers/pci/controller/dwc/pcie-spear13xx.c | 62 +++-----
drivers/pci/controller/dwc/pcie-tegra194.c | 41 +----
drivers/pci/controller/dwc/pcie-uniphier-ep.c | 38 +----
drivers/pci/controller/dwc/pcie-uniphier.c | 51 +------
23 files changed, 356 insertions(+), 1032 deletions(-)
--
2.25.1
^ permalink raw reply
* [PATCH v2 03/16] PCI: dwc: Move "dbi", "dbi2", and "addr_space" resource setup into common code
From: Rob Herring @ 2020-11-05 21:11 UTC (permalink / raw)
Cc: Kunihiko Hayashi, linux-pci, Binghui Wang, Bjorn Andersson,
Masahiro Yamada, Thierry Reding, Jonathan Chocron,
Kishon Vijay Abraham I, Jesper Nilsson, Lorenzo Pieralisi,
Pratyush Anand, linux-arm-kernel, Jonathan Hunter, Andy Gross,
linux-arm-kernel, Xiaowei Song, linux-tegra, linux-arm-msm,
Murali Karicheri, Bjorn Helgaas, linux-omap, Mingkai Hu, Roy Zang,
Minghuan Lian, Gustavo Pimentel, Stanimir Varbanov, Jingoo Han,
linuxppc-dev
In-Reply-To: <20201105211159.1814485-1-robh@kernel.org>
Most DWC drivers use the common register resource names "dbi", "dbi2", and
"addr_space", so let's move their setup into the DWC common code.
This means 'dbi_base' in particular is setup later, but it looks like no
drivers touch DBI registers before dw_pcie_host_init or dw_pcie_ep_init.
Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Murali Karicheri <m-karicheri2@ti.com>
Cc: Minghuan Lian <minghuan.Lian@nxp.com>
Cc: Mingkai Hu <mingkai.hu@nxp.com>
Cc: Roy Zang <roy.zang@nxp.com>
Cc: Jonathan Chocron <jonnyc@amazon.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Cc: Xiaowei Song <songxiaowei@hisilicon.com>
Cc: Binghui Wang <wangbinghui@hisilicon.com>
Cc: Andy Gross <agross@kernel.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Stanimir Varbanov <svarbanov@mm-sol.com>
Cc: Pratyush Anand <pratyush.anand@gmail.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: linux-omap@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-arm-kernel@axis.com
Cc: linux-arm-msm@vger.kernel.org
Cc: linux-tegra@vger.kernel.org
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
---
v2:
- Fix Layerscape EP build error
---
drivers/pci/controller/dwc/pci-dra7xx.c | 8 ----
drivers/pci/controller/dwc/pci-keystone.c | 29 +-----------
.../pci/controller/dwc/pci-layerscape-ep.c | 37 +--------------
drivers/pci/controller/dwc/pcie-al.c | 9 +---
drivers/pci/controller/dwc/pcie-artpec6.c | 43 ++----------------
.../pci/controller/dwc/pcie-designware-ep.c | 29 ++++++++++--
.../pci/controller/dwc/pcie-designware-host.c | 7 +++
.../pci/controller/dwc/pcie-designware-plat.c | 45 +------------------
drivers/pci/controller/dwc/pcie-intel-gw.c | 4 --
drivers/pci/controller/dwc/pcie-kirin.c | 5 ---
drivers/pci/controller/dwc/pcie-qcom.c | 8 ----
drivers/pci/controller/dwc/pcie-spear13xx.c | 11 +----
drivers/pci/controller/dwc/pcie-tegra194.c | 22 ---------
drivers/pci/controller/dwc/pcie-uniphier-ep.c | 38 +---------------
drivers/pci/controller/dwc/pcie-uniphier.c | 6 ---
15 files changed, 47 insertions(+), 254 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
index 6d012d2b1e90..a4aabc85dbb1 100644
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
@@ -578,7 +578,6 @@ static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
{
int ret;
struct dw_pcie_ep *ep;
- struct resource *res;
struct device *dev = &pdev->dev;
struct dw_pcie *pci = dra7xx->pci;
@@ -594,13 +593,6 @@ static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
if (IS_ERR(pci->dbi_base2))
return PTR_ERR(pci->dbi_base2);
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
- if (!res)
- return -EINVAL;
-
- ep->phys_base = res->start;
- ep->addr_size = resource_size(res);
-
ret = dw_pcie_ep_init(ep);
if (ret) {
dev_err(dev, "failed to initialize endpoint\n");
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index a222728238ca..9cf14f13798b 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -977,33 +977,6 @@ static const struct dw_pcie_ep_ops ks_pcie_am654_ep_ops = {
.get_features = &ks_pcie_am654_get_features,
};
-static int __init ks_pcie_add_pcie_ep(struct keystone_pcie *ks_pcie,
- struct platform_device *pdev)
-{
- int ret;
- struct dw_pcie_ep *ep;
- struct resource *res;
- struct device *dev = &pdev->dev;
- struct dw_pcie *pci = ks_pcie->pci;
-
- ep = &pci->ep;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
- if (!res)
- return -EINVAL;
-
- ep->phys_base = res->start;
- ep->addr_size = resource_size(res);
-
- ret = dw_pcie_ep_init(ep);
- if (ret) {
- dev_err(dev, "failed to initialize endpoint\n");
- return ret;
- }
-
- return 0;
-}
-
static void ks_pcie_disable_phy(struct keystone_pcie *ks_pcie)
{
int num_lanes = ks_pcie->num_lanes;
@@ -1313,7 +1286,7 @@ static int __init ks_pcie_probe(struct platform_device *pdev)
}
pci->ep.ops = ep_ops;
- ret = ks_pcie_add_pcie_ep(ks_pcie, pdev);
+ ret = dw_pcie_ep_init(&pci->ep);
if (ret < 0)
goto err_get_sync;
break;
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index 84206f265e54..4d12efdacd2f 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -18,8 +18,6 @@
#include "pcie-designware.h"
-#define PCIE_DBI2_OFFSET 0x1000 /* DBI2 base address*/
-
#define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
struct ls_pcie_ep_drvdata {
@@ -124,34 +122,6 @@ static const struct of_device_id ls_pcie_ep_of_match[] = {
{ },
};
-static int __init ls_add_pcie_ep(struct ls_pcie_ep *pcie,
- struct platform_device *pdev)
-{
- struct dw_pcie *pci = pcie->pci;
- struct device *dev = pci->dev;
- struct dw_pcie_ep *ep;
- struct resource *res;
- int ret;
-
- ep = &pci->ep;
- ep->ops = pcie->drvdata->ops;
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
- if (!res)
- return -EINVAL;
-
- ep->phys_base = res->start;
- ep->addr_size = resource_size(res);
-
- ret = dw_pcie_ep_init(ep);
- if (ret) {
- dev_err(dev, "failed to initialize endpoint\n");
- return ret;
- }
-
- return 0;
-}
-
static int __init ls_pcie_ep_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -159,7 +129,6 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
struct ls_pcie_ep *pcie;
struct pci_epc_features *ls_epc;
struct resource *dbi_base;
- int ret;
pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
if (!pcie)
@@ -188,13 +157,11 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
if (IS_ERR(pci->dbi_base))
return PTR_ERR(pci->dbi_base);
- pci->dbi_base2 = pci->dbi_base + PCIE_DBI2_OFFSET;
+ pci->ep.ops = &ls_pcie_ep_ops;
platform_set_drvdata(pdev, pcie);
- ret = ls_add_pcie_ep(pcie, pdev);
-
- return ret;
+ return dw_pcie_ep_init(&pci->ep);
}
static struct platform_driver ls_pcie_ep_driver = {
diff --git a/drivers/pci/controller/dwc/pcie-al.c b/drivers/pci/controller/dwc/pcie-al.c
index f973fbca90cf..d06866921187 100644
--- a/drivers/pci/controller/dwc/pcie-al.c
+++ b/drivers/pci/controller/dwc/pcie-al.c
@@ -347,7 +347,6 @@ static int al_pcie_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct resource *controller_res;
struct resource *ecam_res;
- struct resource *dbi_res;
struct al_pcie *al_pcie;
struct dw_pcie *pci;
@@ -365,11 +364,6 @@ static int al_pcie_probe(struct platform_device *pdev)
al_pcie->pci = pci;
al_pcie->dev = dev;
- dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
- pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_res);
- if (IS_ERR(pci->dbi_base))
- return PTR_ERR(pci->dbi_base);
-
ecam_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
if (!ecam_res) {
dev_err(dev, "couldn't find 'config' reg in DT\n");
@@ -386,8 +380,7 @@ static int al_pcie_probe(struct platform_device *pdev)
return PTR_ERR(al_pcie->controller_base);
}
- dev_dbg(dev, "From DT: dbi_base: %pR, controller_base: %pR\n",
- dbi_res, controller_res);
+ dev_dbg(dev, "From DT: controller_base: %pR\n", controller_res);
platform_set_drvdata(pdev, al_pcie);
diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c
index 929448e9e0bc..52ad7909cd0c 100644
--- a/drivers/pci/controller/dwc/pcie-artpec6.c
+++ b/drivers/pci/controller/dwc/pcie-artpec6.c
@@ -403,38 +403,6 @@ static const struct dw_pcie_ep_ops pcie_ep_ops = {
.raise_irq = artpec6_pcie_raise_irq,
};
-static int artpec6_add_pcie_ep(struct artpec6_pcie *artpec6_pcie,
- struct platform_device *pdev)
-{
- int ret;
- struct dw_pcie_ep *ep;
- struct resource *res;
- struct device *dev = &pdev->dev;
- struct dw_pcie *pci = artpec6_pcie->pci;
-
- ep = &pci->ep;
- ep->ops = &pcie_ep_ops;
-
- pci->dbi_base2 = devm_platform_ioremap_resource_byname(pdev, "dbi2");
- if (IS_ERR(pci->dbi_base2))
- return PTR_ERR(pci->dbi_base2);
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
- if (!res)
- return -EINVAL;
-
- ep->phys_base = res->start;
- ep->addr_size = resource_size(res);
-
- ret = dw_pcie_ep_init(ep);
- if (ret) {
- dev_err(dev, "failed to initialize endpoint\n");
- return ret;
- }
-
- return 0;
-}
-
static int artpec6_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -469,10 +437,6 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
artpec6_pcie->variant = variant;
artpec6_pcie->mode = mode;
- pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "dbi");
- if (IS_ERR(pci->dbi_base))
- return PTR_ERR(pci->dbi_base);
-
artpec6_pcie->phy_base =
devm_platform_ioremap_resource_byname(pdev, "phy");
if (IS_ERR(artpec6_pcie->phy_base))
@@ -504,9 +468,10 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
val &= ~PCIECFG_DEVICE_TYPE_MASK;
artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
- ret = artpec6_add_pcie_ep(artpec6_pcie, pdev);
- if (ret < 0)
- return ret;
+
+ pci->ep.ops = &pcie_ep_ops;
+
+ return dw_pcie_ep_init(&pci->ep);
break;
}
default:
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index ad7da4ea43a5..6fe176e1bdd2 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -7,6 +7,7 @@
*/
#include <linux/of.h>
+#include <linux/platform_device.h>
#include "pcie-designware.h"
#include <linux/pci-epc.h>
@@ -676,20 +677,42 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
int ret;
void *addr;
u8 func_no;
+ struct resource *res;
struct pci_epc *epc;
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
struct device *dev = pci->dev;
+ struct platform_device *pdev = to_platform_device(dev);
struct device_node *np = dev->of_node;
const struct pci_epc_features *epc_features;
struct dw_pcie_ep_func *ep_func;
INIT_LIST_HEAD(&ep->func_list);
- if (!pci->dbi_base || !pci->dbi_base2) {
- dev_err(dev, "dbi_base/dbi_base2 is not populated\n");
- return -EINVAL;
+ if (!pci->dbi_base) {
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+ pci->dbi_base = devm_pci_remap_cfg_resource(dev, res);
+ if (IS_ERR(pci->dbi_base))
+ return PTR_ERR(pci->dbi_base);
+ }
+
+ if (!pci->dbi_base2) {
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
+ if (!res)
+ pci->dbi_base2 = pci->dbi_base + SZ_4K;
+ else {
+ pci->dbi_base2 = devm_pci_remap_cfg_resource(dev, res);
+ if (IS_ERR(pci->dbi_base2))
+ return PTR_ERR(pci->dbi_base2);
+ }
}
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
+ if (!res)
+ return -EINVAL;
+
+ ep->phys_base = res->start;
+ ep->addr_size = resource_size(res);
+
ret = of_property_read_u32(np, "num-ib-windows", &ep->num_ib_windows);
if (ret < 0) {
dev_err(dev, "Unable to read *num-ib-windows* property\n");
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index a6ffab9b537e..cde45b2076ee 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -310,6 +310,13 @@ int dw_pcie_host_init(struct pcie_port *pp)
dev_err(dev, "Missing *config* reg space\n");
}
+ if (!pci->dbi_base) {
+ struct resource *dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+ pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_res);
+ if (IS_ERR(pci->dbi_base))
+ return PTR_ERR(pci->dbi_base);
+ }
+
bridge = devm_pci_alloc_host_bridge(dev, 0);
if (!bridge)
return -ENOMEM;
diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
index e3e300669ed5..562a05e07b1d 100644
--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
+++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
@@ -139,43 +139,11 @@ static int dw_plat_add_pcie_port(struct dw_plat_pcie *dw_plat_pcie,
return 0;
}
-static int dw_plat_add_pcie_ep(struct dw_plat_pcie *dw_plat_pcie,
- struct platform_device *pdev)
-{
- int ret;
- struct dw_pcie_ep *ep;
- struct resource *res;
- struct device *dev = &pdev->dev;
- struct dw_pcie *pci = dw_plat_pcie->pci;
-
- ep = &pci->ep;
- ep->ops = &pcie_ep_ops;
-
- pci->dbi_base2 = devm_platform_ioremap_resource_byname(pdev, "dbi2");
- if (IS_ERR(pci->dbi_base2))
- return PTR_ERR(pci->dbi_base2);
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
- if (!res)
- return -EINVAL;
-
- ep->phys_base = res->start;
- ep->addr_size = resource_size(res);
-
- ret = dw_pcie_ep_init(ep);
- if (ret) {
- dev_err(dev, "Failed to initialize endpoint\n");
- return ret;
- }
- return 0;
-}
-
static int dw_plat_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct dw_plat_pcie *dw_plat_pcie;
struct dw_pcie *pci;
- struct resource *res; /* Resource from DT */
int ret;
const struct of_device_id *match;
const struct dw_plat_pcie_of_data *data;
@@ -202,14 +170,6 @@ static int dw_plat_pcie_probe(struct platform_device *pdev)
dw_plat_pcie->pci = pci;
dw_plat_pcie->mode = mode;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
- if (!res)
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- pci->dbi_base = devm_ioremap_resource(dev, res);
- if (IS_ERR(pci->dbi_base))
- return PTR_ERR(pci->dbi_base);
-
platform_set_drvdata(pdev, dw_plat_pcie);
switch (dw_plat_pcie->mode) {
@@ -225,9 +185,8 @@ static int dw_plat_pcie_probe(struct platform_device *pdev)
if (!IS_ENABLED(CONFIG_PCIE_DW_PLAT_EP))
return -ENODEV;
- ret = dw_plat_add_pcie_ep(dw_plat_pcie, pdev);
- if (ret < 0)
- return ret;
+ pci->ep.ops = &pcie_ep_ops;
+ return dw_pcie_ep_init(&pci->ep);
break;
default:
dev_err(dev, "INVALID device type %d\n", dw_plat_pcie->mode);
diff --git a/drivers/pci/controller/dwc/pcie-intel-gw.c b/drivers/pci/controller/dwc/pcie-intel-gw.c
index 77ef88333115..88782653ed21 100644
--- a/drivers/pci/controller/dwc/pcie-intel-gw.c
+++ b/drivers/pci/controller/dwc/pcie-intel-gw.c
@@ -237,10 +237,6 @@ static int intel_pcie_get_resources(struct platform_device *pdev)
struct device *dev = pci->dev;
int ret;
- pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "dbi");
- if (IS_ERR(pci->dbi_base))
- return PTR_ERR(pci->dbi_base);
-
lpp->core_clk = devm_clk_get(dev, NULL);
if (IS_ERR(lpp->core_clk)) {
ret = PTR_ERR(lpp->core_clk);
diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c
index d0a6a2dee6f5..3042a23cf09a 100644
--- a/drivers/pci/controller/dwc/pcie-kirin.c
+++ b/drivers/pci/controller/dwc/pcie-kirin.c
@@ -157,11 +157,6 @@ static long kirin_pcie_get_resource(struct kirin_pcie *kirin_pcie,
if (IS_ERR(kirin_pcie->phy_base))
return PTR_ERR(kirin_pcie->phy_base);
- kirin_pcie->pci->dbi_base =
- devm_platform_ioremap_resource_byname(pdev, "dbi");
- if (IS_ERR(kirin_pcie->pci->dbi_base))
- return PTR_ERR(kirin_pcie->pci->dbi_base);
-
kirin_pcie->crgctrl =
syscon_regmap_lookup_by_compatible("hisilicon,hi3660-crgctrl");
if (IS_ERR(kirin_pcie->crgctrl))
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index b4761640ffd9..3b4f70b9f3f0 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1368,7 +1368,6 @@ static const struct dw_pcie_ops dw_pcie_ops = {
static int qcom_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct resource *res;
struct pcie_port *pp;
struct dw_pcie *pci;
struct qcom_pcie *pcie;
@@ -1407,13 +1406,6 @@ static int qcom_pcie_probe(struct platform_device *pdev)
goto err_pm_runtime_put;
}
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
- pci->dbi_base = devm_pci_remap_cfg_resource(dev, res);
- if (IS_ERR(pci->dbi_base)) {
- ret = PTR_ERR(pci->dbi_base);
- goto err_pm_runtime_put;
- }
-
pcie->elbi = devm_platform_ioremap_resource_byname(pdev, "elbi");
if (IS_ERR(pcie->elbi)) {
ret = PTR_ERR(pcie->elbi);
diff --git a/drivers/pci/controller/dwc/pcie-spear13xx.c b/drivers/pci/controller/dwc/pcie-spear13xx.c
index e348225f651f..1ed7e3501ff1 100644
--- a/drivers/pci/controller/dwc/pcie-spear13xx.c
+++ b/drivers/pci/controller/dwc/pcie-spear13xx.c
@@ -152,6 +152,8 @@ static int spear13xx_pcie_host_init(struct pcie_port *pp)
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pci);
+ spear13xx_pcie->app_base = pci->dbi_base + 0x2000;
+
spear13xx_pcie_establish_link(spear13xx_pcie);
spear13xx_pcie_enable_interrupts(spear13xx_pcie);
@@ -203,7 +205,6 @@ static int spear13xx_pcie_probe(struct platform_device *pdev)
struct dw_pcie *pci;
struct spear13xx_pcie *spear13xx_pcie;
struct device_node *np = dev->of_node;
- struct resource *dbi_base;
int ret;
spear13xx_pcie = devm_kzalloc(dev, sizeof(*spear13xx_pcie), GFP_KERNEL);
@@ -242,14 +243,6 @@ static int spear13xx_pcie_probe(struct platform_device *pdev)
return ret;
}
- dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
- pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base);
- if (IS_ERR(pci->dbi_base)) {
- ret = PTR_ERR(pci->dbi_base);
- goto fail_clk;
- }
- spear13xx_pcie->app_base = pci->dbi_base + 0x2000;
-
if (of_property_read_bool(np, "st,pcie-is-gen1"))
pci->link_gen = 1;
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index f920e7efe118..f8fca6794282 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -1907,19 +1907,12 @@ static int tegra_pcie_config_ep(struct tegra_pcie_dw *pcie,
struct dw_pcie *pci = &pcie->pci;
struct device *dev = pcie->dev;
struct dw_pcie_ep *ep;
- struct resource *res;
char *name;
int ret;
ep = &pci->ep;
ep->ops = &pcie_ep_ops;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
- if (!res)
- return -EINVAL;
-
- ep->phys_base = res->start;
- ep->addr_size = resource_size(res);
ep->page_size = SZ_64K;
ret = gpiod_set_debounce(pcie->pex_rst_gpiod, PERST_DEBOUNCE_TIME);
@@ -1982,7 +1975,6 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct resource *atu_dma_res;
struct tegra_pcie_dw *pcie;
- struct resource *dbi_res;
struct pcie_port *pp;
struct dw_pcie *pci;
struct phy **phys;
@@ -2091,20 +2083,6 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)
pcie->phys = phys;
- dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
- if (!dbi_res) {
- dev_err(dev, "Failed to find \"dbi\" region\n");
- return -ENODEV;
- }
- pcie->dbi_res = dbi_res;
-
- pci->dbi_base = devm_ioremap_resource(dev, dbi_res);
- if (IS_ERR(pci->dbi_base))
- return PTR_ERR(pci->dbi_base);
-
- /* Tegra HW locates DBI2 at a fixed offset from DBI */
- pci->dbi_base2 = pci->dbi_base + 0x1000;
-
atu_dma_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"atu_dma");
if (!atu_dma_res) {
diff --git a/drivers/pci/controller/dwc/pcie-uniphier-ep.c b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
index 148355960061..69810c6b0d58 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier-ep.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier-ep.c
@@ -218,35 +218,6 @@ static const struct dw_pcie_ep_ops uniphier_pcie_ep_ops = {
.get_features = uniphier_pcie_get_features,
};
-static int uniphier_add_pcie_ep(struct uniphier_pcie_ep_priv *priv,
- struct platform_device *pdev)
-{
- struct dw_pcie *pci = &priv->pci;
- struct dw_pcie_ep *ep = &pci->ep;
- struct device *dev = &pdev->dev;
- struct resource *res;
- int ret;
-
- ep->ops = &uniphier_pcie_ep_ops;
-
- pci->dbi_base2 = devm_platform_ioremap_resource_byname(pdev, "dbi2");
- if (IS_ERR(pci->dbi_base2))
- return PTR_ERR(pci->dbi_base2);
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
- if (!res)
- return -EINVAL;
-
- ep->phys_base = res->start;
- ep->addr_size = resource_size(res);
-
- ret = dw_pcie_ep_init(ep);
- if (ret)
- dev_err(dev, "Failed to initialize endpoint (%d)\n", ret);
-
- return ret;
-}
-
static int uniphier_pcie_ep_enable(struct uniphier_pcie_ep_priv *priv)
{
int ret;
@@ -300,7 +271,6 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct uniphier_pcie_ep_priv *priv;
- struct resource *res;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -314,11 +284,6 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)
priv->pci.dev = dev;
priv->pci.ops = &dw_pcie_ops;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
- priv->pci.dbi_base = devm_pci_remap_cfg_resource(dev, res);
- if (IS_ERR(priv->pci.dbi_base))
- return PTR_ERR(priv->pci.dbi_base);
-
priv->base = devm_platform_ioremap_resource_byname(pdev, "link");
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
@@ -352,7 +317,8 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)
if (ret)
return ret;
- return uniphier_add_pcie_ep(priv, pdev);
+ priv->pci.ep.ops = &uniphier_pcie_ep_ops;
+ return dw_pcie_ep_init(&priv->pci.ep);
}
static const struct pci_epc_features uniphier_pro5_data = {
diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
index 48176265c867..33130fb4af90 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier.c
@@ -400,7 +400,6 @@ static int uniphier_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct uniphier_pcie_priv *priv;
- struct resource *res;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -410,11 +409,6 @@ static int uniphier_pcie_probe(struct platform_device *pdev)
priv->pci.dev = dev;
priv->pci.ops = &dw_pcie_ops;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
- priv->pci.dbi_base = devm_pci_remap_cfg_resource(dev, res);
- if (IS_ERR(priv->pci.dbi_base))
- return PTR_ERR(priv->pci.dbi_base);
-
priv->base = devm_platform_ioremap_resource_byname(pdev, "link");
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
--
2.25.1
^ permalink raw reply related
* [PATCH v2 05/16] PCI: dwc: Ensure all outbound ATU windows are reset
From: Rob Herring @ 2020-11-05 21:11 UTC (permalink / raw)
Cc: Roy Zang, Lorenzo Pieralisi, linux-pci, Minghuan Lian,
linux-arm-kernel, Jingoo Han, Bjorn Helgaas, Gustavo Pimentel,
linuxppc-dev, Mingkai Hu
In-Reply-To: <20201105211159.1814485-1-robh@kernel.org>
The Layerscape driver clears the ATU registers which may have been
configured by the bootloader. Any driver could have the same issue
and doing it for all drivers doesn't hurt, so let's move it into the
common DWC code.
Cc: Minghuan Lian <minghuan.Lian@nxp.com>
Cc: Mingkai Hu <mingkai.hu@nxp.com>
Cc: Roy Zang <roy.zang@nxp.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Jingoo Han <jingoohan1@gmail.com>
Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Cc: linuxppc-dev@lists.ozlabs.org
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
---
drivers/pci/controller/dwc/pci-layerscape.c | 14 --------------
drivers/pci/controller/dwc/pcie-designware-host.c | 5 +++++
2 files changed, 5 insertions(+), 14 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c
index f24f79a70d9a..53e56d54c482 100644
--- a/drivers/pci/controller/dwc/pci-layerscape.c
+++ b/drivers/pci/controller/dwc/pci-layerscape.c
@@ -83,14 +83,6 @@ static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie)
iowrite32(val, pci->dbi_base + PCIE_STRFMR1);
}
-static void ls_pcie_disable_outbound_atus(struct ls_pcie *pcie)
-{
- int i;
-
- for (i = 0; i < PCIE_IATU_NUM; i++)
- dw_pcie_disable_atu(pcie->pci, i, DW_PCIE_REGION_OUTBOUND);
-}
-
static int ls1021_pcie_link_up(struct dw_pcie *pci)
{
u32 state;
@@ -136,12 +128,6 @@ static int ls_pcie_host_init(struct pcie_port *pp)
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct ls_pcie *pcie = to_ls_pcie(pci);
- /*
- * Disable outbound windows configured by the bootloader to avoid
- * one transaction hitting multiple outbound windows.
- * dw_pcie_setup_rc() will reconfigure the outbound windows.
- */
- ls_pcie_disable_outbound_atus(pcie);
ls_pcie_fix_error_response(pcie);
dw_pcie_dbi_ro_wr_en(pci);
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index cde45b2076ee..265a48f1a0ae 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -534,6 +534,7 @@ static struct pci_ops dw_pcie_ops = {
void dw_pcie_setup_rc(struct pcie_port *pp)
{
+ int i;
u32 val, ctrl, num_ctrls;
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -583,6 +584,10 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
+ /* Ensure all outbound windows are disabled so there are multiple matches */
+ for (i = 0; i < pci->num_viewport; i++)
+ dw_pcie_disable_atu(pci, i, DW_PCIE_REGION_OUTBOUND);
+
/*
* If the platform provides its own child bus config accesses, it means
* the platform uses its own address translation component rather than
--
2.25.1
^ permalink raw reply related
* [PATCH v2 09/16] PCI: dwc: Rework MSI initialization
From: Rob Herring @ 2020-11-05 21:11 UTC (permalink / raw)
Cc: Roy Zang, Lorenzo Pieralisi, Jingoo Han, linux-pci, Minghuan Lian,
Murali Karicheri, Mingkai Hu, Gustavo Pimentel, Bjorn Helgaas,
linuxppc-dev, linux-arm-kernel
In-Reply-To: <20201105211159.1814485-1-robh@kernel.org>
There are 3 possible MSI implementations for the DWC host. The first is
using the built-in DWC MSI controller. The 2nd is a custom MSI
controller as part of the PCI host (keystone only). The 3rd is an
external MSI controller (typically GICv3 ITS). Currently, the last 2
are distinguished with a .msi_host_init() hook with the 3rd option using
an empty function. However we can detect the 3rd case with the presence
of 'msi-parent' or 'msi-map' properties, so let's do that instead and
remove the empty functions.
Cc: Murali Karicheri <m-karicheri2@ti.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Minghuan Lian <minghuan.Lian@nxp.com>
Cc: Mingkai Hu <mingkai.hu@nxp.com>
Cc: Roy Zang <roy.zang@nxp.com>
Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Cc: linuxppc-dev@lists.ozlabs.org
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
---
drivers/pci/controller/dwc/pci-keystone.c | 9 -------
drivers/pci/controller/dwc/pci-layerscape.c | 25 -------------------
.../pci/controller/dwc/pcie-designware-host.c | 20 +++++++++------
drivers/pci/controller/dwc/pcie-designware.h | 1 +
drivers/pci/controller/dwc/pcie-intel-gw.c | 9 -------
5 files changed, 13 insertions(+), 51 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index 9cf14f13798b..784385ae6074 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -272,14 +272,6 @@ static void ks_pcie_handle_legacy_irq(struct keystone_pcie *ks_pcie,
ks_pcie_app_writel(ks_pcie, IRQ_EOI, offset);
}
-/*
- * Dummy function so that DW core doesn't configure MSI
- */
-static int ks_pcie_am654_msi_host_init(struct pcie_port *pp)
-{
- return 0;
-}
-
static void ks_pcie_enable_error_irq(struct keystone_pcie *ks_pcie)
{
ks_pcie_app_writel(ks_pcie, ERR_IRQ_ENABLE_SET, ERR_IRQ_ALL);
@@ -854,7 +846,6 @@ static const struct dw_pcie_host_ops ks_pcie_host_ops = {
static const struct dw_pcie_host_ops ks_pcie_am654_host_ops = {
.host_init = ks_pcie_host_init,
- .msi_host_init = ks_pcie_am654_msi_host_init,
};
static irqreturn_t ks_pcie_err_irq_handler(int irq, void *priv)
diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c
index 53e56d54c482..0d84986c4c16 100644
--- a/drivers/pci/controller/dwc/pci-layerscape.c
+++ b/drivers/pci/controller/dwc/pci-layerscape.c
@@ -168,37 +168,12 @@ static int ls1021_pcie_host_init(struct pcie_port *pp)
return ls_pcie_host_init(pp);
}
-static int ls_pcie_msi_host_init(struct pcie_port *pp)
-{
- struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
- struct device *dev = pci->dev;
- struct device_node *np = dev->of_node;
- struct device_node *msi_node;
-
- /*
- * The MSI domain is set by the generic of_msi_configure(). This
- * .msi_host_init() function keeps us from doing the default MSI
- * domain setup in dw_pcie_host_init() and also enforces the
- * requirement that "msi-parent" exists.
- */
- msi_node = of_parse_phandle(np, "msi-parent", 0);
- if (!msi_node) {
- dev_err(dev, "failed to find msi-parent\n");
- return -EINVAL;
- }
-
- of_node_put(msi_node);
- return 0;
-}
-
static const struct dw_pcie_host_ops ls1021_pcie_host_ops = {
.host_init = ls1021_pcie_host_init,
- .msi_host_init = ls_pcie_msi_host_init,
};
static const struct dw_pcie_host_ops ls_pcie_host_ops = {
.host_init = ls_pcie_host_init,
- .msi_host_init = ls_pcie_msi_host_init,
};
static const struct dw_pcie_ops dw_ls1021_pcie_ops = {
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 95deef0eaadf..9b952639d020 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -365,6 +365,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
pci->link_gen = of_pci_get_max_link_speed(np);
if (pci_msi_enabled()) {
+ pp->has_msi_ctrl = !(pp->ops->msi_host_init ||
+ of_property_read_bool(np, "msi-parent") ||
+ of_property_read_bool(np, "msi-map"));
+
if (!pp->num_vectors) {
pp->num_vectors = MSI_DEF_NUM_VECTORS;
} else if (pp->num_vectors > MAX_MSI_IRQS) {
@@ -372,7 +376,11 @@ int dw_pcie_host_init(struct pcie_port *pp)
return -EINVAL;
}
- if (!pp->ops->msi_host_init) {
+ if (pp->ops->msi_host_init) {
+ ret = pp->ops->msi_host_init(pp);
+ if (ret < 0)
+ return ret;
+ } else if (pp->has_msi_ctrl) {
if (!pp->msi_irq) {
pp->msi_irq = platform_get_irq_byname_optional(pdev, "msi");
if (pp->msi_irq < 0) {
@@ -402,10 +410,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
pp->msi_data = 0;
goto err_free_msi;
}
- } else {
- ret = pp->ops->msi_host_init(pp);
- if (ret < 0)
- return ret;
}
}
@@ -426,7 +430,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
return 0;
err_free_msi:
- if (pci_msi_enabled() && !pp->ops->msi_host_init)
+ if (pp->has_msi_ctrl)
dw_pcie_free_msi(pp);
return ret;
}
@@ -436,7 +440,7 @@ void dw_pcie_host_deinit(struct pcie_port *pp)
{
pci_stop_root_bus(pp->bridge->bus);
pci_remove_root_bus(pp->bridge->bus);
- if (pci_msi_enabled() && !pp->ops->msi_host_init)
+ if (pp->has_msi_ctrl)
dw_pcie_free_msi(pp);
}
EXPORT_SYMBOL_GPL(dw_pcie_host_deinit);
@@ -544,7 +548,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
dw_pcie_setup(pci);
- if (pci_msi_enabled() && !pp->ops->msi_host_init) {
+ if (pp->has_msi_ctrl) {
num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL;
/* Initialize IRQ Status array */
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 96382dcb2859..5d374bab10d1 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -175,6 +175,7 @@ struct dw_pcie_host_ops {
};
struct pcie_port {
+ bool has_msi_ctrl:1;
u64 cfg0_base;
void __iomem *va_cfg0_base;
u32 cfg0_size;
diff --git a/drivers/pci/controller/dwc/pcie-intel-gw.c b/drivers/pci/controller/dwc/pcie-intel-gw.c
index c562eb7454b1..292b9de86532 100644
--- a/drivers/pci/controller/dwc/pcie-intel-gw.c
+++ b/drivers/pci/controller/dwc/pcie-intel-gw.c
@@ -385,14 +385,6 @@ static int intel_pcie_rc_init(struct pcie_port *pp)
return intel_pcie_host_setup(lpp);
}
-/*
- * Dummy function so that DW core doesn't configure MSI
- */
-static int intel_pcie_msi_init(struct pcie_port *pp)
-{
- return 0;
-}
-
static u64 intel_pcie_cpu_addr(struct dw_pcie *pcie, u64 cpu_addr)
{
return cpu_addr + BUS_IATU_OFFSET;
@@ -404,7 +396,6 @@ static const struct dw_pcie_ops intel_pcie_ops = {
static const struct dw_pcie_host_ops intel_pcie_dw_ops = {
.host_init = intel_pcie_rc_init,
- .msi_host_init = intel_pcie_msi_init,
};
static const struct intel_pcie_soc pcie_data = {
--
2.25.1
^ permalink raw reply related
* [PATCH v2 12/16] PCI: dwc: Move dw_pcie_setup_rc() to DWC common code
From: Rob Herring @ 2020-11-05 21:11 UTC (permalink / raw)
Cc: Kunihiko Hayashi, Neil Armstrong, linux-pci, Binghui Wang,
Bjorn Andersson, Minghuan Lian, linux-arm-kernel,
Thomas Petazzoni, Fabio Estevam, Jerome Brunet, Jesper Nilsson,
Lorenzo Pieralisi, Kevin Hilman, Pratyush Anand,
Krzysztof Kozlowski, Kishon Vijay Abraham I, Murali Karicheri,
NXP Linux Team, Xiaowei Song, Richard Zhu, Martin Blumenstingl,
linux-arm-msm, Sascha Hauer, linuxppc-dev, Yue Wang,
linux-samsung-soc, Bjorn Helgaas, linux-amlogic, linux-omap,
Mingkai Hu, linux-arm-kernel, Roy Zang, Masahiro Yamada,
Gustavo Pimentel, Andy Gross, Stanimir Varbanov, Kukjin Kim,
Pengutronix Kernel Team, Jingoo Han, Shawn Guo, Lucas Stach
In-Reply-To: <20201105211159.1814485-1-robh@kernel.org>
All RC complex drivers must call dw_pcie_setup_rc(). The ordering of the
call shouldn't be too important other than being after any RC resets.
There's a few calls of dw_pcie_setup_rc() left as drivers implementing
suspend/resume need it.
Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Kukjin Kim <kgene@kernel.org>
Cc: Krzysztof Kozlowski <krzk@kernel.org>
Cc: Richard Zhu <hongxing.zhu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: Murali Karicheri <m-karicheri2@ti.com>
Cc: Minghuan Lian <minghuan.Lian@nxp.com>
Cc: Mingkai Hu <mingkai.hu@nxp.com>
Cc: Roy Zang <roy.zang@nxp.com>
Cc: Yue Wang <yue.wang@Amlogic.com>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Cc: Xiaowei Song <songxiaowei@hisilicon.com>
Cc: Binghui Wang <wangbinghui@hisilicon.com>
Cc: Andy Gross <agross@kernel.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Stanimir Varbanov <svarbanov@mm-sol.com>
Cc: Pratyush Anand <pratyush.anand@gmail.com>
Cc: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: linux-omap@vger.kernel.org
Cc: linux-samsung-soc@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-amlogic@lists.infradead.org
Cc: linux-arm-kernel@axis.com
Cc: linux-arm-msm@vger.kernel.org
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
---
drivers/pci/controller/dwc/pci-dra7xx.c | 1 -
drivers/pci/controller/dwc/pci-exynos.c | 1 -
drivers/pci/controller/dwc/pci-imx6.c | 1 -
drivers/pci/controller/dwc/pci-keystone.c | 2 --
drivers/pci/controller/dwc/pci-layerscape.c | 2 --
drivers/pci/controller/dwc/pci-meson.c | 2 --
drivers/pci/controller/dwc/pcie-armada8k.c | 2 --
drivers/pci/controller/dwc/pcie-artpec6.c | 1 -
drivers/pci/controller/dwc/pcie-designware-host.c | 1 +
drivers/pci/controller/dwc/pcie-designware-plat.c | 8 --------
drivers/pci/controller/dwc/pcie-histb.c | 3 ---
drivers/pci/controller/dwc/pcie-kirin.c | 2 --
drivers/pci/controller/dwc/pcie-qcom.c | 1 -
drivers/pci/controller/dwc/pcie-spear13xx.c | 2 --
drivers/pci/controller/dwc/pcie-uniphier.c | 2 --
15 files changed, 1 insertion(+), 30 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
index 72a5a2bf933b..b105af63854a 100644
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
@@ -181,7 +181,6 @@ static int dra7xx_pcie_host_init(struct pcie_port *pp)
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
- dw_pcie_setup_rc(pp);
dra7xx_pcie_enable_interrupts(dra7xx);
return 0;
diff --git a/drivers/pci/controller/dwc/pci-exynos.c b/drivers/pci/controller/dwc/pci-exynos.c
index 3939fe22e8a2..5c10a5432896 100644
--- a/drivers/pci/controller/dwc/pci-exynos.c
+++ b/drivers/pci/controller/dwc/pci-exynos.c
@@ -372,7 +372,6 @@ static int exynos_pcie_host_init(struct pcie_port *pp)
phy_init(ep->phy);
exynos_pcie_deassert_core_reset(ep);
- dw_pcie_setup_rc(pp);
exynos_pcie_assert_reset(ep);
exynos_pcie_enable_interrupts(ep);
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 9e30fbf4efbe..f9547bb2cf1b 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -834,7 +834,6 @@ static int imx6_pcie_host_init(struct pcie_port *pp)
imx6_pcie_init_phy(imx6_pcie);
imx6_pcie_deassert_core_reset(imx6_pcie);
imx6_setup_phy_mpll(imx6_pcie);
- dw_pcie_setup_rc(pp);
return 0;
}
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index 90b222b020a3..5a4bcc2b1ddb 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -807,8 +807,6 @@ static int __init ks_pcie_host_init(struct pcie_port *pp)
if (ret)
return ret;
- dw_pcie_setup_rc(pp);
-
ks_pcie_stop_link(pci);
ks_pcie_setup_rc_app_regs(ks_pcie);
writew(PCI_IO_RANGE_TYPE_32 | (PCI_IO_RANGE_TYPE_32 << 8),
diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c
index 0d84986c4c16..400ebbebd00f 100644
--- a/drivers/pci/controller/dwc/pci-layerscape.c
+++ b/drivers/pci/controller/dwc/pci-layerscape.c
@@ -136,8 +136,6 @@ static int ls_pcie_host_init(struct pcie_port *pp)
ls_pcie_drop_msg_tlp(pcie);
- dw_pcie_setup_rc(pp);
-
return 0;
}
diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c
index 2df0adcf0bf2..04589f0decb2 100644
--- a/drivers/pci/controller/dwc/pci-meson.c
+++ b/drivers/pci/controller/dwc/pci-meson.c
@@ -380,8 +380,6 @@ static int meson_pcie_host_init(struct pcie_port *pp)
meson_set_max_payload(mp, MAX_PAYLOAD_SIZE);
meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);
- dw_pcie_setup_rc(pp);
-
return 0;
}
diff --git a/drivers/pci/controller/dwc/pcie-armada8k.c b/drivers/pci/controller/dwc/pcie-armada8k.c
index dd2926bbb901..4e2552dcf982 100644
--- a/drivers/pci/controller/dwc/pcie-armada8k.c
+++ b/drivers/pci/controller/dwc/pcie-armada8k.c
@@ -171,8 +171,6 @@ static int armada8k_pcie_host_init(struct pcie_port *pp)
u32 reg;
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
- dw_pcie_setup_rc(pp);
-
if (!dw_pcie_link_up(pci)) {
/* Disable LTSSM state machine to enable configuration */
reg = dw_pcie_readl_dbi(pci, PCIE_GLOBAL_CONTROL_REG);
diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c
index 7ee8f3c83f8f..fcba9915a606 100644
--- a/drivers/pci/controller/dwc/pcie-artpec6.c
+++ b/drivers/pci/controller/dwc/pcie-artpec6.c
@@ -328,7 +328,6 @@ static int artpec6_pcie_host_init(struct pcie_port *pp)
artpec6_pcie_init_phy(artpec6_pcie);
artpec6_pcie_deassert_core_reset(artpec6_pcie);
artpec6_pcie_wait_for_phy(artpec6_pcie);
- dw_pcie_setup_rc(pp);
return 0;
}
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index ebea2c814448..f2b0a15ad72b 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -422,6 +422,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
goto err_free_msi;
}
+ dw_pcie_setup_rc(pp);
dw_pcie_msi_init(pp);
if (!dw_pcie_link_up(pci) && pci->ops->start_link) {
diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
index dec24e595c3e..9b397c807261 100644
--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
+++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
@@ -33,15 +33,7 @@ struct dw_plat_pcie_of_data {
static const struct of_device_id dw_plat_pcie_of_match[];
-static int dw_plat_pcie_host_init(struct pcie_port *pp)
-{
- dw_pcie_setup_rc(pp);
-
- return 0;
-}
-
static const struct dw_pcie_host_ops dw_plat_pcie_host_ops = {
- .host_init = dw_plat_pcie_host_init,
};
static int dw_plat_pcie_establish_link(struct dw_pcie *pci)
diff --git a/drivers/pci/controller/dwc/pcie-histb.c b/drivers/pci/controller/dwc/pcie-histb.c
index 210777c793ea..86f9d16c50d7 100644
--- a/drivers/pci/controller/dwc/pcie-histb.c
+++ b/drivers/pci/controller/dwc/pcie-histb.c
@@ -196,9 +196,6 @@ static int histb_pcie_host_init(struct pcie_port *pp)
regval |= PCIE_WM_RC;
histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, regval);
- /* setup root complex */
- dw_pcie_setup_rc(pp);
-
return 0;
}
diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c
index f84ac1b36b2c..ac4bbdaf5324 100644
--- a/drivers/pci/controller/dwc/pcie-kirin.c
+++ b/drivers/pci/controller/dwc/pcie-kirin.c
@@ -405,8 +405,6 @@ static int kirin_pcie_host_init(struct pcie_port *pp)
{
pp->bridge->ops = &kirin_pci_ops;
- dw_pcie_setup_rc(pp);
-
return 0;
}
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index eb107179d544..e49791c4f846 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1280,7 +1280,6 @@ static int qcom_pcie_host_init(struct pcie_port *pp)
goto err_disable_phy;
}
- dw_pcie_setup_rc(pp);
qcom_ep_reset_deassert(pcie);
return 0;
diff --git a/drivers/pci/controller/dwc/pcie-spear13xx.c b/drivers/pci/controller/dwc/pcie-spear13xx.c
index 31475e4493a7..1a9e353bef55 100644
--- a/drivers/pci/controller/dwc/pcie-spear13xx.c
+++ b/drivers/pci/controller/dwc/pcie-spear13xx.c
@@ -130,8 +130,6 @@ static int spear13xx_pcie_host_init(struct pcie_port *pp)
spear13xx_pcie->app_base = pci->dbi_base + 0x2000;
- dw_pcie_setup_rc(pp);
-
/*
* this controller support only 128 bytes read size, however its
* default value in capability register is 512 bytes. So force
diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
index e6616408a29c..2457e9dd098d 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier.c
@@ -314,8 +314,6 @@ static int uniphier_pcie_host_init(struct pcie_port *pp)
uniphier_pcie_irq_enable(priv);
- dw_pcie_setup_rc(pp);
-
return 0;
}
--
2.25.1
^ permalink raw reply related
* [PATCH v2 13/16] PCI: dwc: Remove unnecessary wrappers around dw_pcie_host_init()
From: Rob Herring @ 2020-11-05 21:11 UTC (permalink / raw)
Cc: Kunihiko Hayashi, Neil Armstrong, linux-pci, Binghui Wang,
Minghuan Lian, Jonathan Chocron, Fabio Estevam, Jerome Brunet,
Jesper Nilsson, Lorenzo Pieralisi, Kevin Hilman, linux-arm-kernel,
Murali Karicheri, NXP Linux Team, Xiaowei Song, Richard Zhu,
Martin Blumenstingl, Sascha Hauer, Yue Wang, Bjorn Helgaas,
linux-amlogic, Mingkai Hu, linux-arm-kernel, Roy Zang,
Masahiro Yamada, linuxppc-dev, Pengutronix Kernel Team, Shawn Guo,
Lucas Stach
In-Reply-To: <20201105211159.1814485-1-robh@kernel.org>
Many calls to dw_pcie_host_init() are in a wrapper function with
nothing else now. Let's remove the pointless extra layer.
Cc: Richard Zhu <hongxing.zhu@nxp.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: Murali Karicheri <m-karicheri2@ti.com>
Cc: Minghuan Lian <minghuan.Lian@nxp.com>
Cc: Mingkai Hu <mingkai.hu@nxp.com>
Cc: Roy Zang <roy.zang@nxp.com>
Cc: Yue Wang <yue.wang@Amlogic.com>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Cc: Jonathan Chocron <jonnyc@amazon.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Xiaowei Song <songxiaowei@hisilicon.com>
Cc: Binghui Wang <wangbinghui@hisilicon.com>
Cc: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-amlogic@lists.infradead.org
Cc: linux-arm-kernel@axis.com
Signed-off-by: Rob Herring <robh@kernel.org>
---
drivers/pci/controller/dwc/pci-imx6.c | 22 ++---------------
drivers/pci/controller/dwc/pci-keystone.c | 19 +--------------
drivers/pci/controller/dwc/pci-layerscape.c | 26 ++-------------------
drivers/pci/controller/dwc/pci-meson.c | 22 ++---------------
drivers/pci/controller/dwc/pcie-al.c | 20 ++--------------
drivers/pci/controller/dwc/pcie-artpec6.c | 23 +++---------------
drivers/pci/controller/dwc/pcie-kirin.c | 11 ++-------
drivers/pci/controller/dwc/pcie-uniphier.c | 23 +++---------------
8 files changed, 17 insertions(+), 149 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index f9547bb2cf1b..0cf1333c0440 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -842,25 +842,6 @@ static const struct dw_pcie_host_ops imx6_pcie_host_ops = {
.host_init = imx6_pcie_host_init,
};
-static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
- struct platform_device *pdev)
-{
- struct dw_pcie *pci = imx6_pcie->pci;
- struct pcie_port *pp = &pci->pp;
- struct device *dev = &pdev->dev;
- int ret;
-
- pp->ops = &imx6_pcie_host_ops;
-
- ret = dw_pcie_host_init(pp);
- if (ret) {
- dev_err(dev, "failed to initialize host\n");
- return ret;
- }
-
- return 0;
-}
-
static const struct dw_pcie_ops dw_pcie_ops = {
.start_link = imx6_pcie_start_link,
};
@@ -1005,6 +986,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
pci->dev = dev;
pci->ops = &dw_pcie_ops;
+ pci->pp.ops = &imx6_pcie_host_ops;
imx6_pcie->pci = pci;
imx6_pcie->drvdata = of_device_get_match_data(dev);
@@ -1154,7 +1136,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
if (ret)
return ret;
- ret = imx6_add_pcie_port(imx6_pcie, pdev);
+ ret = dw_pcie_host_init(&pci->pp);
if (ret < 0)
return ret;
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index 5a4bcc2b1ddb..719756160821 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -844,23 +844,6 @@ static irqreturn_t ks_pcie_err_irq_handler(int irq, void *priv)
return ks_pcie_handle_error_irq(ks_pcie);
}
-static int __init ks_pcie_add_pcie_port(struct keystone_pcie *ks_pcie,
- struct platform_device *pdev)
-{
- struct dw_pcie *pci = ks_pcie->pci;
- struct pcie_port *pp = &pci->pp;
- struct device *dev = &pdev->dev;
- int ret;
-
- ret = dw_pcie_host_init(pp);
- if (ret) {
- dev_err(dev, "failed to initialize host\n");
- return ret;
- }
-
- return 0;
-}
-
static void ks_pcie_am654_write_dbi2(struct dw_pcie *pci, void __iomem *base,
u32 reg, size_t size, u32 val)
{
@@ -1255,7 +1238,7 @@ static int __init ks_pcie_probe(struct platform_device *pdev)
}
pci->pp.ops = host_ops;
- ret = ks_pcie_add_pcie_port(ks_pcie, pdev);
+ ret = dw_pcie_host_init(&pci->pp);
if (ret < 0)
goto err_get_sync;
break;
diff --git a/drivers/pci/controller/dwc/pci-layerscape.c b/drivers/pci/controller/dwc/pci-layerscape.c
index 400ebbebd00f..44ad34cdc3bc 100644
--- a/drivers/pci/controller/dwc/pci-layerscape.c
+++ b/drivers/pci/controller/dwc/pci-layerscape.c
@@ -232,31 +232,12 @@ static const struct of_device_id ls_pcie_of_match[] = {
{ },
};
-static int __init ls_add_pcie_port(struct ls_pcie *pcie)
-{
- struct dw_pcie *pci = pcie->pci;
- struct pcie_port *pp = &pci->pp;
- struct device *dev = pci->dev;
- int ret;
-
- pp->ops = pcie->drvdata->ops;
-
- ret = dw_pcie_host_init(pp);
- if (ret) {
- dev_err(dev, "failed to initialize host\n");
- return ret;
- }
-
- return 0;
-}
-
static int __init ls_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct dw_pcie *pci;
struct ls_pcie *pcie;
struct resource *dbi_base;
- int ret;
pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
if (!pcie)
@@ -270,6 +251,7 @@ static int __init ls_pcie_probe(struct platform_device *pdev)
pci->dev = dev;
pci->ops = pcie->drvdata->dw_pcie_ops;
+ pci->pp.ops = pcie->drvdata->ops;
pcie->pci = pci;
@@ -285,11 +267,7 @@ static int __init ls_pcie_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pcie);
- ret = ls_add_pcie_port(pcie);
- if (ret < 0)
- return ret;
-
- return 0;
+ return dw_pcie_host_init(&pci->pp);
}
static struct platform_driver ls_pcie_driver = {
diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c
index 04589f0decb2..686ded034f22 100644
--- a/drivers/pci/controller/dwc/pci-meson.c
+++ b/drivers/pci/controller/dwc/pci-meson.c
@@ -387,25 +387,6 @@ static const struct dw_pcie_host_ops meson_pcie_host_ops = {
.host_init = meson_pcie_host_init,
};
-static int meson_add_pcie_port(struct meson_pcie *mp,
- struct platform_device *pdev)
-{
- struct dw_pcie *pci = &mp->pci;
- struct pcie_port *pp = &pci->pp;
- struct device *dev = &pdev->dev;
- int ret;
-
- pp->ops = &meson_pcie_host_ops;
-
- ret = dw_pcie_host_init(pp);
- if (ret) {
- dev_err(dev, "failed to initialize host\n");
- return ret;
- }
-
- return 0;
-}
-
static const struct dw_pcie_ops dw_pcie_ops = {
.link_up = meson_pcie_link_up,
.start_link = meson_pcie_start_link,
@@ -425,6 +406,7 @@ static int meson_pcie_probe(struct platform_device *pdev)
pci = &mp->pci;
pci->dev = dev;
pci->ops = &dw_pcie_ops;
+ pci->pp.ops = &meson_pcie_host_ops;
pci->num_lanes = 1;
mp->phy = devm_phy_get(dev, "pcie");
@@ -471,7 +453,7 @@ static int meson_pcie_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mp);
- ret = meson_add_pcie_port(mp, pdev);
+ ret = dw_pcie_host_init(&pci->pp);
if (ret < 0) {
dev_err(dev, "Add PCIe port failed, %d\n", ret);
goto err_phy;
diff --git a/drivers/pci/controller/dwc/pcie-al.c b/drivers/pci/controller/dwc/pcie-al.c
index d06866921187..7ac8a37d9ce0 100644
--- a/drivers/pci/controller/dwc/pcie-al.c
+++ b/drivers/pci/controller/dwc/pcie-al.c
@@ -322,23 +322,6 @@ static const struct dw_pcie_host_ops al_pcie_host_ops = {
.host_init = al_pcie_host_init,
};
-static int al_add_pcie_port(struct pcie_port *pp,
- struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- int ret;
-
- pp->ops = &al_pcie_host_ops;
-
- ret = dw_pcie_host_init(pp);
- if (ret) {
- dev_err(dev, "failed to initialize host\n");
- return ret;
- }
-
- return 0;
-}
-
static const struct dw_pcie_ops dw_pcie_ops = {
};
@@ -360,6 +343,7 @@ static int al_pcie_probe(struct platform_device *pdev)
pci->dev = dev;
pci->ops = &dw_pcie_ops;
+ pci->pp.ops = &al_pcie_host_ops;
al_pcie->pci = pci;
al_pcie->dev = dev;
@@ -384,7 +368,7 @@ static int al_pcie_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, al_pcie);
- return al_add_pcie_port(&pci->pp, pdev);
+ return dw_pcie_host_init(&pci->pp);
}
static const struct of_device_id al_pcie_of_match[] = {
diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c
index fcba9915a606..597c282f586c 100644
--- a/drivers/pci/controller/dwc/pcie-artpec6.c
+++ b/drivers/pci/controller/dwc/pcie-artpec6.c
@@ -336,25 +336,6 @@ static const struct dw_pcie_host_ops artpec6_pcie_host_ops = {
.host_init = artpec6_pcie_host_init,
};
-static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie,
- struct platform_device *pdev)
-{
- struct dw_pcie *pci = artpec6_pcie->pci;
- struct pcie_port *pp = &pci->pp;
- struct device *dev = pci->dev;
- int ret;
-
- pp->ops = &artpec6_pcie_host_ops;
-
- ret = dw_pcie_host_init(pp);
- if (ret) {
- dev_err(dev, "failed to initialize host\n");
- return ret;
- }
-
- return 0;
-}
-
static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
{
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -445,7 +426,9 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_HOST))
return -ENODEV;
- ret = artpec6_add_pcie_port(artpec6_pcie, pdev);
+ pci->pp.ops = &artpec6_pcie_host_ops;
+
+ ret = dw_pcie_host_init(&pci->pp);
if (ret < 0)
return ret;
break;
diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c
index ac4bbdaf5324..026fd1e42a55 100644
--- a/drivers/pci/controller/dwc/pcie-kirin.c
+++ b/drivers/pci/controller/dwc/pcie-kirin.c
@@ -419,14 +419,6 @@ static const struct dw_pcie_host_ops kirin_pcie_host_ops = {
.host_init = kirin_pcie_host_init,
};
-static int kirin_add_pcie_port(struct dw_pcie *pci,
- struct platform_device *pdev)
-{
- pci->pp.ops = &kirin_pcie_host_ops;
-
- return dw_pcie_host_init(&pci->pp);
-}
-
static int kirin_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -449,6 +441,7 @@ static int kirin_pcie_probe(struct platform_device *pdev)
pci->dev = dev;
pci->ops = &kirin_dw_pcie_ops;
+ pci->pp.ops = &kirin_pcie_host_ops;
kirin_pcie->pci = pci;
ret = kirin_pcie_get_clk(kirin_pcie, pdev);
@@ -474,7 +467,7 @@ static int kirin_pcie_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, kirin_pcie);
- return kirin_add_pcie_port(pci, pdev);
+ return dw_pcie_host_init(&pci->pp);
}
static const struct of_device_id kirin_pcie_match[] = {
diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
index 2457e9dd098d..7e8bad326770 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier.c
@@ -321,25 +321,6 @@ static const struct dw_pcie_host_ops uniphier_pcie_host_ops = {
.host_init = uniphier_pcie_host_init,
};
-static int uniphier_add_pcie_port(struct uniphier_pcie_priv *priv,
- struct platform_device *pdev)
-{
- struct dw_pcie *pci = &priv->pci;
- struct pcie_port *pp = &pci->pp;
- struct device *dev = &pdev->dev;
- int ret;
-
- pp->ops = &uniphier_pcie_host_ops;
-
- ret = dw_pcie_host_init(pp);
- if (ret) {
- dev_err(dev, "Failed to initialize host (%d)\n", ret);
- return ret;
- }
-
- return 0;
-}
-
static int uniphier_pcie_host_enable(struct uniphier_pcie_priv *priv)
{
int ret;
@@ -415,7 +396,9 @@ static int uniphier_pcie_probe(struct platform_device *pdev)
if (ret)
return ret;
- return uniphier_add_pcie_port(priv, pdev);
+ priv->pci.pp.ops = &uniphier_pcie_host_ops;
+
+ return dw_pcie_host_init(&priv->pci.pp);
}
static const struct of_device_id uniphier_pcie_match[] = {
--
2.25.1
^ permalink raw reply related
* Re: [PATCH 01/18] powerpc/64s: move the last of the page fault handling logic to C
From: kernel test robot @ 2020-11-05 21:54 UTC (permalink / raw)
To: Nicholas Piggin, linuxppc-dev; +Cc: kbuild-all, Nicholas Piggin
In-Reply-To: <20201105143431.1874789-2-npiggin@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4810 bytes --]
Hi Nicholas,
I love your patch! Perhaps something to improve:
[auto build test WARNING on powerpc/next]
[also build test WARNING on v5.10-rc2 next-20201105]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-interrupt-wrappers/20201105-231909
base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-allyesconfig (attached as .config)
compiler: powerpc64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/7c4e3c4d325c8c43a43b8031b5327cb91b56db19
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Nicholas-Piggin/powerpc-interrupt-wrappers/20201105-231909
git checkout 7c4e3c4d325c8c43a43b8031b5327cb91b56db19
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
>> arch/powerpc/mm/book3s64/hash_utils.c:1513:5: warning: no previous prototype for 'do_hash_fault' [-Wmissing-prototypes]
1513 | int do_hash_fault(struct pt_regs *regs, unsigned long ea, unsigned long dsisr)
| ^~~~~~~~~~~~~
arch/powerpc/mm/book3s64/hash_utils.c:1886:6: warning: no previous prototype for 'hpte_insert_repeating' [-Wmissing-prototypes]
1886 | long hpte_insert_repeating(unsigned long hash, unsigned long vpn,
| ^~~~~~~~~~~~~~~~~~~~~
vim +/do_hash_fault +1513 arch/powerpc/mm/book3s64/hash_utils.c
1512
> 1513 int do_hash_fault(struct pt_regs *regs, unsigned long ea, unsigned long dsisr)
1514 {
1515 unsigned long access = _PAGE_PRESENT | _PAGE_READ;
1516 unsigned long flags = 0;
1517 struct mm_struct *mm;
1518 unsigned int region_id;
1519 int err;
1520
1521 if (unlikely(dsisr & (DSISR_BAD_FAULT_64S | DSISR_DABRMATCH | DSISR_KEYFAULT)))
1522 goto _do_page_fault;
1523
1524 /*
1525 * If we are in an "NMI" (e.g., an interrupt when soft-disabled), then
1526 * don't call hash_page, just fail the fault. This is required to
1527 * prevent re-entrancy problems in the hash code, namely perf
1528 * interrupts hitting while something holds H_PAGE_BUSY, and taking a
1529 * hash fault. See the comment in hash_preload().
1530 *
1531 * We come here as a result of a DSI at a point where we don't want
1532 * to call hash_page, such as when we are accessing memory (possibly
1533 * user memory) inside a PMU interrupt that occurred while interrupts
1534 * were soft-disabled. We want to invoke the exception handler for
1535 * the access, or panic if there isn't a handler.
1536 */
1537 if (unlikely(in_nmi())) {
1538 bad_page_fault(regs, ea, SIGSEGV);
1539 return 0;
1540 }
1541
1542 region_id = get_region_id(ea);
1543 if ((region_id == VMALLOC_REGION_ID) || (region_id == IO_REGION_ID))
1544 mm = &init_mm;
1545 else
1546 mm = current->mm;
1547
1548 if (dsisr & DSISR_NOHPTE)
1549 flags |= HPTE_NOHPTE_UPDATE;
1550
1551 if (dsisr & DSISR_ISSTORE)
1552 access |= _PAGE_WRITE;
1553 /*
1554 * We set _PAGE_PRIVILEGED only when
1555 * kernel mode access kernel space.
1556 *
1557 * _PAGE_PRIVILEGED is NOT set
1558 * 1) when kernel mode access user space
1559 * 2) user space access kernel space.
1560 */
1561 access |= _PAGE_PRIVILEGED;
1562 if (user_mode(regs) || (region_id == USER_REGION_ID))
1563 access &= ~_PAGE_PRIVILEGED;
1564
1565 if (regs->trap == 0x400)
1566 access |= _PAGE_EXEC;
1567
1568 err = hash_page_mm(mm, ea, access, regs->trap, flags);
1569 if (unlikely(err < 0)) {
1570 // failed to instert a hash PTE due to an hypervisor error
1571 if (user_mode(regs)) {
1572 if (IS_ENABLED(CONFIG_PPC_SUBPAGE_PROT) && err == -2)
1573 _exception(SIGSEGV, regs, SEGV_ACCERR, ea);
1574 else
1575 _exception(SIGBUS, regs, BUS_ADRERR, ea);
1576 } else {
1577 bad_page_fault(regs, ea, SIGBUS);
1578 }
1579 err = 0;
1580
1581 } else if (err) {
1582 _do_page_fault:
1583 err = hash__do_page_fault(regs, ea, dsisr);
1584 }
1585
1586 return err;
1587 }
1588
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 71468 bytes --]
^ permalink raw reply
* Re: [PATCH] KVM: PPC: Book3S HV: XIVE: Fix possible oops when accessing ESB page
From: Greg Kurz @ 2020-11-05 17:41 UTC (permalink / raw)
To: Cédric Le Goater
Cc: kvm, Gustavo Romero, kvm-ppc, Paul Mackerras, linuxppc-dev,
David Gibson
In-Reply-To: <20201105134713.656160-1-clg@kaod.org>
On Thu, 5 Nov 2020 14:47:13 +0100
Cédric Le Goater <clg@kaod.org> wrote:
> When accessing the ESB page of a source interrupt, the fault handler
> will retrieve the page address from the XIVE interrupt 'xive_irq_data'
> structure. If the associated KVM XIVE interrupt is not valid, that is
> not allocated at the HW level for some reason, the fault handler will
> dereference a NULL pointer leading to the oops below :
>
> WARNING: CPU: 40 PID: 59101 at arch/powerpc/kvm/book3s_xive_native.c:259 xive_native_esb_fault+0xe4/0x240 [kvm]
> CPU: 40 PID: 59101 Comm: qemu-system-ppc Kdump: loaded Tainted: G W --------- - - 4.18.0-240.el8.ppc64le #1
> NIP: c00800000e949fac LR: c00000000044b164 CTR: c00800000e949ec8
> REGS: c000001f69617840 TRAP: 0700 Tainted: G W --------- - - (4.18.0-240.el8.ppc64le)
> MSR: 9000000000029033 <SF,HV,EE,ME,IR,DR,RI,LE> CR: 44044282 XER: 00000000
> CFAR: c00000000044b160 IRQMASK: 0
> GPR00: c00000000044b164 c000001f69617ac0 c00800000e96e000 c000001f69617c10
> GPR04: 05faa2b21e000080 0000000000000000 0000000000000005 ffffffffffffffff
> GPR08: 0000000000000000 0000000000000001 0000000000000000 0000000000000001
> GPR12: c00800000e949ec8 c000001ffffd3400 0000000000000000 0000000000000000
> GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> GPR20: 0000000000000000 0000000000000000 c000001f5c065160 c000000001c76f90
> GPR24: c000001f06f20000 c000001f5c065100 0000000000000008 c000001f0eb98c78
> GPR28: c000001dcab40000 c000001dcab403d8 c000001f69617c10 0000000000000011
> NIP [c00800000e949fac] xive_native_esb_fault+0xe4/0x240 [kvm]
> LR [c00000000044b164] __do_fault+0x64/0x220
> Call Trace:
> [c000001f69617ac0] [0000000137a5dc20] 0x137a5dc20 (unreliable)
> [c000001f69617b50] [c00000000044b164] __do_fault+0x64/0x220
> [c000001f69617b90] [c000000000453838] do_fault+0x218/0x930
> [c000001f69617bf0] [c000000000456f50] __handle_mm_fault+0x350/0xdf0
> [c000001f69617cd0] [c000000000457b1c] handle_mm_fault+0x12c/0x310
> [c000001f69617d10] [c00000000007ef44] __do_page_fault+0x264/0xbb0
> [c000001f69617df0] [c00000000007f8c8] do_page_fault+0x38/0xd0
> [c000001f69617e30] [c00000000000a714] handle_page_fault+0x18/0x38
> Instruction dump:
> 40c2fff0 7c2004ac 2fa90000 409e0118 73e90001 41820080 e8bd0008 7c2004ac
> 7ca90074 39400000 915c0000 7929d182 <0b090000> 2fa50000 419e0080 e89e0018
> ---[ end trace 66c6ff034c53f64f ]---
> xive-kvm: xive_native_esb_fault: accessing invalid ESB page for source 8 !
>
> Fix that by checking the validity of the KVM XIVE interrupt structure.
>
> Reported-by: Greg Kurz <groug@kaod.org>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
Looks sane to me. QEMU still crashes on SIGBUS but no more oops at least.
Tested-by: Greg Kurz <groug@kaod.org>
> arch/powerpc/kvm/book3s_xive_native.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c
> index d0c2db0e07fa..a59a94f02733 100644
> --- a/arch/powerpc/kvm/book3s_xive_native.c
> +++ b/arch/powerpc/kvm/book3s_xive_native.c
> @@ -251,6 +251,13 @@ static vm_fault_t xive_native_esb_fault(struct vm_fault *vmf)
> }
>
> state = &sb->irq_state[src];
> +
> + /* Some sanity checking */
> + if (!state->valid) {
> + pr_devel("%s: source %lx invalid !\n", __func__, irq);
> + return VM_FAULT_SIGBUS;
> + }
> +
> kvmppc_xive_select_irq(state, &hw_num, &xd);
>
> arch_spin_lock(&sb->lock);
^ permalink raw reply
* Re: Kernel panic from malloc() on SUSE 15.1?
From: Carl Jacobsen @ 2020-11-05 19:44 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev
In-Reply-To: <87lffgt8b9.fsf@mpe.ellerman.id.au>
[-- Attachment #1: Type: text/plain, Size: 14126 bytes --]
On Thu, Nov 5, 2020 at 2:19 AM Michael Ellerman <mpe@ellerman.id.au> wrote:
> Carl Jacobsen <cjacobsen@storix.com> writes:
> > The panic (on a call to malloc from static linked libcrypto) looks like
> > this:
>
> What hardware is this on?
>
Thank you for looking into this.
The system that's panicking identifies like this:
# uname -a
Linux sl151pwr8 4.12.14-197.18-default #1 SMP Tue Sep 17 14:26:49 UTC
2019
(d75059b) ppc64le ppc64le ppc64le GNU/Linux
#
# cat /etc/os-release
NAME="SLES"
VERSION="15-SP1"
VERSION_ID="15.1"
PRETTY_NAME="SUSE Linux Enterprise Server 15 SP1"
ID="sles"
ID_LIKE="suse"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:suse:sles:15:sp1"
The system is an LPAR running under PowerVM vios version 2.2.3.4.
The underlying hardware is machine type-model 8284-22A.
> Can you try booting with ppc_tm=off on the kernel command line, and see
> if that changes anything?
>
Yes. Output is down below. Doesn't appear to change much, but I don't have
the background to interpret the registers.
> Can you put your compiled test program up somewhere we can download it
> and look at? Or post the disassembly?
>
Here's the source file:
https://www.storix.com/download/support/misc/rand_test.c
Here's the resulting executable:
https://www.storix.com/download/support/misc/rand_test
Executable is linked to libcrypto from openssl-1.1.1g, configured with:
./config no-shared no-dso no-threads -fPIC -ggdb3 -debug -static
Executable is built (on SUSE 12) with:
gcc -ggdb3 -o rand_test rand_test.c libcrypto.a
And running the executable (on SUSE 15.1) through gdb goes like this:
# gdb --args ./rand_test
GNU gdb (GDB; SUSE Linux Enterprise 15) 8.3.1
<< snip intro text >>
Reading symbols from ./rand_test...
(gdb) b main
Breakpoint 1 at 0x1000288c: file rand_test.c, line 6.
(gdb) r
Starting program: /tmp/ossl/rand_test
Breakpoint 1, main (argc=1, argv=0x7ffffffff798) at rand_test.c:6
6 int has_enough_data = RAND_status();
(gdb) s
RAND_status () at crypto/rand/rand_lib.c:958
958 const RAND_METHOD *meth = RAND_get_rand_method();
(gdb)
RAND_get_rand_method () at crypto/rand/rand_lib.c:844
844 const RAND_METHOD *tmp_meth = NULL;
(gdb)
846 if (!RUN_ONCE(&rand_init, do_rand_init))
(gdb)
CRYPTO_THREAD_run_once (once=0x102a7d88 <rand_init>,
init=0x10002f30 <do_rand_init_ossl_>) at crypto/threads_none.c:67
67 if (*once != 0)
(gdb)
70 init();
(gdb)
do_rand_init_ossl_ () at crypto/rand/rand_lib.c:306
306 DEFINE_RUN_ONCE_STATIC(do_rand_init)
(gdb)
do_rand_init () at crypto/rand/rand_lib.c:309
309 rand_engine_lock = CRYPTO_THREAD_lock_new();
(gdb)
CRYPTO_THREAD_lock_new () at crypto/threads_none.c:24
24 if ((lock = OPENSSL_zalloc(sizeof(unsigned int))) == NULL) {
(gdb)
CRYPTO_zalloc (num=4, file=0x1023a500 "crypto/threads_none.c", line=24)
at crypto/mem.c:230
230 void *ret = CRYPTO_malloc(num, file, line);
(gdb)
CRYPTO_malloc (num=4, file=0x1023a500 "crypto/threads_none.c", line=24)
at crypto/mem.c:194
194 void *ret = NULL;
(gdb)
197 if (malloc_impl != NULL && malloc_impl != CRYPTO_malloc)
(gdb)
200 if (num == 0)
(gdb)
204 if (allow_customize) {
(gdb)
210 allow_customize = 0;
(gdb)
222 ret = malloc(num);
(gdb)
Bad kernel stack pointer 7fffffffef20 at 700
Oops: Bad kernel stack pointer, sig: 6 [#1]
SMP NR_CPUS=2048
NUMA
pSeries
Modules linked in: scsi_transport_iscsi af_packet xt_tcpudp
ip6t_rpfilter ip6t_REJECT ipt_REJECT xt_conntrack ip_set nfnetlink
ebtable_nat ebtable_broute br_netfilter bridge stp llc ip6table_nat
nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_raw
ip6table_security iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4
nf_nat nf_conntrack libcrc32c iptable_mangle iptable_raw iptable_security
ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter ip_tables
x_tables ibmveth(X) vmx_crypto gf128mul crct10dif_vpmsum rtc_generic btrfs
xor zstd_decompress zstd_compress xxhash raid6_pq sr_mod cdrom sd_mod
ibmvscsi(X) scsi_transport_srp crc32c_vpmsum sg dm_multipath dm_mod
scsi_dh_rdac scsi_dh_emc scsi_dh_alua scsi_mod autofs4
Supported: Yes, External
CPU: 4 PID: 3082 Comm: rand_test Tainted: G
4.12.14-197.18-default #1 SLE15-SP1
task: c00000002e226100 task.stack: c0000000387c8000
NIP: 0000000000000700 LR: 0000000010004acc CTR: 0000000000000000
REGS: c00000001ebffd40 TRAP: 0300 Tainted: G
(4.12.14-197.18-default)
MSR: 8000000000001000 <SF,ME>
CR: 44000844 XER: 20000000
CFAR: 00000000000010f0 DAR: ffffffffffffb27a DSISR: 40000000 SOFTE: 0
GPR00: 0000000020000000 00007fffffffef20 00000000102af788
fffffffffffffffd
GPR04: 0000000000000020 0000000000000030 00000000102b0760
0000000000000001
GPR08: 0000000000000000 00007fffb7dacc00 00000000102b0730
800000010280f033
GPR12: 0000000000004000 00007fffb7ffa100 0000000000000000
0000000000000000
GPR16: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
GPR20: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
GPR24: 0000000000000000 0000000000000000 0000000000000000
00007fffb7fef4b8
GPR28: 00007fffb7ff0000 0000000000000000 0000000000000000
00007fffffffef20
NIP [0000000000000700] 0x700
LR [0000000010004acc] 0x10004acc
Call Trace:
Instruction dump:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 7db243a6 7db142a6 f92d0080 7d20e2a6
---[ end trace 167d5d3b2e8a06e9 ]---
Sending IPI to other CPUs
IPI complete
kexec: Starting switchover sequence.
I'm in purgatory
-> smp_release_cpus()
spinning_secondaries = 0
<- smp_release_cpus()
Kernel panic - not syncing: Out of memory and no killable processes...
CPU: 4 PID: 1 Comm: swapper/4 Not tainted 4.12.14-197.18-default #1
SLE15-SP1
Call Trace:
[c000000012457210] [c000000008a20140] dump_stack+0xb0/0xf0 (unreliable)
[c000000012457250] [c000000008a1ccd4] panic+0x144/0x31c
[c0000000124572e0] [c0000000082efcc0] out_of_memory+0x3f0/0x700
[c000000012457380] [c0000000082f7ed4]
__alloc_pages_nodemask+0x1004/0x10b0
[c000000012457570] [c00000000837f4d8] alloc_page_interleave+0x58/0x110
[c0000000124575b0] [c0000000083800bc] alloc_pages_current+0x16c/0x1d0
[c000000012457610] [c0000000082e8398] __page_cache_alloc+0xd8/0x150
[c000000012457650] [c0000000082e8574] pagecache_get_page+0x164/0x440
[c0000000124576b0] [c0000000082e8884]
grab_cache_page_write_begin+0x34/0x70
[c0000000124576e0] [c00000000840ede8] simple_write_begin+0x48/0x190
[c000000012457720] [c0000000082e7c7c] generic_perform_write+0xec/0x270
[c0000000124577b0] [c0000000082ea2e0]
__generic_file_write_iter+0x250/0x2a0
[c000000012457810] [c0000000082ea53c]
generic_file_write_iter+0x20c/0x2e0
[c000000012457850] [c0000000083cc0e0] __vfs_write+0x120/0x1e0
[c0000000124578e0] [c0000000083cdfc8] vfs_write+0xd8/0x220
[c000000012457930] [c0000000083cfeec] SyS_write+0x6c/0x110
[c000000012457980] [c000000008d154c4] xwrite+0x54/0xb8
[c0000000124579c0] [c000000008d15574] do_copy+0x4c/0x17c
[c0000000124579f0] [c000000008d15140] write_buffer+0x64/0x90
[c000000012457a20] [c000000008d151d4] flush_buffer+0x68/0xf4
[c000000012457a70] [c000000008d62268] unxz+0x210/0x398
[c000000012457b10] [c000000008d15efc] unpack_to_rootfs+0x1f0/0x360
[c000000012457bc0] [c000000008d16108] populate_rootfs+0x9c/0x188
[c000000012457c40] [c00000000800f5d4] do_one_initcall+0x64/0x1d0
[c000000012457d00] [c000000008d14474] kernel_init_freeable+0x294/0x388
[c000000012457dc0] [c00000000801026c] kernel_init+0x2c/0x160
[c000000012457e30] [c00000000800b560] ret_from_kernel_thread+0x5c/0x7c
------------[ cut here ]------------
Doing the same thing but with ppc_tm=off...
# cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinux-4.12.14-197.18-default
root=UUID=0e795e37-3692-465a-a037-c2935a9fde7a mitigations=auto quiet
crashkernel=197M ppc_tm=off
Results in a panic at the same point, with a few registers changed:
<< snip down to panic at malloc >>
(gdb)
Bad kernel stack pointer 7fffffffef20 at 700
Oops: Bad kernel stack pointer, sig: 6 [#1]
SMP NR_CPUS=2048
NUMA
pSeries
Modules linked in: scsi_transport_iscsi af_packet xt_tcpudp
ip6t_rpfilter ip6t_REJECT ipt_REJECT xt_conntrack ip_set nfnetlink
ebtable_nat ebtable_broute br_netfilter bridge stp llc ip6table_nat
nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_raw
ip6table_security iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4
nf_nat nf_conntrack libcrc32c iptable_mangle iptable_raw iptable_security
ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter ip_tables
x_tables ibmveth(X) vmx_crypto gf128mul crct10dif_vpmsum rtc_generic btrfs
xor zstd_decompress zstd_compress xxhash raid6_pq sr_mod cdrom sd_mod
ibmvscsi(X) scsi_transport_srp crc32c_vpmsum sg dm_multipath dm_mod
scsi_dh_rdac scsi_dh_emc scsi_dh_alua scsi_mod autofs4
Supported: Yes, External
CPU: 2 PID: 3079 Comm: rand_test Tainted: G
4.12.14-197.18-default #1 SLE15-SP1
task: c00000002f6bcc00 task.stack: c0000000321fc000
NIP: 0000000000000700 LR: 0000000010004acc CTR: 0000000000000000
REGS: c00000001ec17d40 TRAP: 0300 Tainted: G
(4.12.14-197.18-default)
MSR: 8000000000001000 <SF,ME>
CR: 44000844 XER: 20000000
CFAR: 00000000000010f0 DAR: ffffffffffffb27a DSISR: 40000000 SOFTE: 0
GPR00: 0000000020000000 00007fffffffef20 00000000102af788
fffffffffffffffd
GPR04: 0000000000000020 0000000000000030 00000000102b0760
0000000000000001
GPR08: 0000000000000000 00007fffb7dacc00 00000000102b0730
800000000280f033
GPR12: 0000000000004000 00007fffb7ffa100 0000000000000000
0000000000000000
GPR16: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
GPR20: 0000000000000000 0000000000000000 0000000000000000
0000000000000000
GPR24: 0000000000000000 0000000000000000 0000000000000000
00007fffb7fef4b8
GPR28: 00007fffb7ff0000 0000000000000000 0000000000000000
00007fffffffef20
NIP [0000000000000700] 0x700
LR [0000000010004acc] 0x10004acc
Call Trace:
Instruction dump:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 7db243a6 7db142a6 f92d0080 7d20e2a6
---[ end trace 436f626dd098548c ]---
Sending IPI to other CPUs
IPI complete
kexec: Starting switchover sequence.
I'm in purgatory
-> smp_release_cpus()
spinning_secondaries = 0
<- smp_release_cpus()
Kernel panic - not syncing: Out of memory and no killable processes...
CPU: 2 PID: 1 Comm: swapper/2 Not tainted 4.12.14-197.18-default #1
SLE15-SP1
Call Trace:
[c000000012457210] [c000000008a20140] dump_stack+0xb0/0xf0 (unreliable)
[c000000012457250] [c000000008a1ccd4] panic+0x144/0x31c
[c0000000124572e0] [c0000000082efcc0] out_of_memory+0x3f0/0x700
[c000000012457380] [c0000000082f7ed4]
__alloc_pages_nodemask+0x1004/0x10b0
[c000000012457570] [c00000000837f4d8] alloc_page_interleave+0x58/0x110
[c0000000124575b0] [c0000000083800bc] alloc_pages_current+0x16c/0x1d0
[c000000012457610] [c0000000082e8398] __page_cache_alloc+0xd8/0x150
[c000000012457650] [c0000000082e8574] pagecache_get_page+0x164/0x440
[c0000000124576b0] [c0000000082e8884]
grab_cache_page_write_begin+0x34/0x70
[c0000000124576e0] [c00000000840ede8] simple_write_begin+0x48/0x190
[c000000012457720] [c0000000082e7c7c] generic_perform_write+0xec/0x270
[c0000000124577b0] [c0000000082ea2e0]
__generic_file_write_iter+0x250/0x2a0
[c000000012457810] [c0000000082ea53c]
generic_file_write_iter+0x20c/0x2e0
[c000000012457850] [c0000000083cc0e0] __vfs_write+0x120/0x1e0
[c0000000124578e0] [c0000000083cdfc8] vfs_write+0xd8/0x220
[c000000012457930] [c0000000083cfeec] SyS_write+0x6c/0x110
[c000000012457980] [c000000008d154c4] xwrite+0x54/0xb8
[c0000000124579c0] [c000000008d15574] do_copy+0x4c/0x17c
[c0000000124579f0] [c000000008d15140] write_buffer+0x64/0x90
[c000000012457a20] [c000000008d151d4] flush_buffer+0x68/0xf4
[c000000012457a70] [c000000008d62268] unxz+0x210/0x398
[c000000012457b10] [c000000008d15efc] unpack_to_rootfs+0x1f0/0x360
[c000000012457bc0] [c000000008d16108] populate_rootfs+0x9c/0x188
[c000000012457c40] [c00000000800f5d4] do_one_initcall+0x64/0x1d0
[c000000012457d00] [c000000008d14474] kernel_init_freeable+0x294/0x388
[c000000012457dc0] [c00000000801026c] kernel_init+0x2c/0x160
[c000000012457e30] [c00000000800b560] ret_from_kernel_thread+0x5c/0x7c
------------[ cut here ]------------
Diffing the panic output looks like this (highlighting register changes?):
74,75c79,80
< CPU: 4 PID: 3082 Comm: rand_test Tainted: G
4.12.14-197.18-default #1 SLE15-SP1
< task: c00000002e226100 task.stack: c0000000387c8000
---
> CPU: 2 PID: 3079 Comm: rand_test Tainted: G
4.12.14-197.18-default #1 SLE15-SP1
> task: c00000002f6bcc00 task.stack: c0000000321fc000
77c82
< REGS: c00000001ebffd40 TRAP: 0300 Tainted: G
(4.12.14-197.18-default)
---
> REGS: c00000001ec17d40 TRAP: 0300 Tainted: G
(4.12.14-197.18-default)
83c88
< GPR08: 0000000000000000 00007fffb7dacc00 00000000102b0730
800000010280f033
---
> GPR08: 0000000000000000 00007fffb7dacc00 00000000102b0730
800000000280f033
95c100
< ---[ end trace 167d5d3b2e8a06e9 ]---
---
> ---[ end trace 436f626dd098548c ]---
106c111
< CPU: 4 PID: 1 Comm: swapper/4 Not tainted 4.12.14-197.18-default #1
SLE15-SP1
---
> CPU: 2 PID: 1 Comm: swapper/2 Not tainted 4.12.14-197.18-default #1
SLE15-SP1
--
Carl Jacobsen
Storix, Inc.
[-- Attachment #2: Type: text/html, Size: 16954 bytes --]
^ permalink raw reply
* [PATCH v2] powerpc: topology.h: fix build when CONFIG_NUMA=n
From: Scott Cheloha @ 2020-11-05 22:30 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nathan Lynch, Laurent Dufour, kernel test robot
Add a non-NUMA definition for of_drconf_to_nid_single() to topology.h
so we have one even if powerpc/mm/numa.c is not compiled. On a non-NUMA
kernel the appropriate node id is always first_online_node.
Signed-off-by: Scott Cheloha <cheloha@linux.ibm.com>
Reported-by: kernel test robot <lkp@intel.com>
Fixes: 72cdd117c449 ("pseries/hotplug-memory: hot-add: skip redundant LMB lookup")
---
v1: Initial patch.
v2: Incorporate suggested cleanups from Christophe Leroy.
arch/powerpc/include/asm/topology.h | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index 8728590f514a..3beeb030cd78 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -6,6 +6,7 @@
struct device;
struct device_node;
+struct drmem_lmb;
#ifdef CONFIG_NUMA
@@ -61,6 +62,9 @@ static inline int early_cpu_to_node(int cpu)
*/
return (nid < 0) ? 0 : nid;
}
+
+int of_drconf_to_nid_single(struct drmem_lmb *lmb);
+
#else
static inline int early_cpu_to_node(int cpu) { return 0; }
@@ -84,10 +88,12 @@ static inline int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
return 0;
}
-#endif /* CONFIG_NUMA */
+static inline int of_drconf_to_nid_single(struct drmem_lmb *lmb)
+{
+ return first_online_node;
+}
-struct drmem_lmb;
-int of_drconf_to_nid_single(struct drmem_lmb *lmb);
+#endif /* CONFIG_NUMA */
#if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR)
extern int find_and_online_cpu_nid(int cpu);
--
2.28.0
^ permalink raw reply related
* [PATCH v2] kernel/watchdog: Fix watchdog_allowed_mask not used warning
From: Santosh Sivaraj @ 2020-11-06 1:50 UTC (permalink / raw)
To: Linux Kernel, linuxppc-dev
Cc: Andrew Morton, Petr Mladek, Santosh Sivaraj, Thomas Gleixner
Define watchdog_allowed_mask only when SOFTLOCKUP_DETECTOR is enabled.
Fixes: 7feeb9cd4f5b ("watchdog/sysctl: Clean up sysctl variable name space")
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Santosh Sivaraj <santosh@fossix.org>
---
v2:
Added Petr's reviewed-by from [1] and add fixes tag as suggested by Christophe.
[1]: https://lkml.org/lkml/2020/8/20/1030
kernel/watchdog.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 5abb5b22ad13..71109065bd8e 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -44,8 +44,6 @@ int __read_mostly soft_watchdog_user_enabled = 1;
int __read_mostly watchdog_thresh = 10;
static int __read_mostly nmi_watchdog_available;
-static struct cpumask watchdog_allowed_mask __read_mostly;
-
struct cpumask watchdog_cpumask __read_mostly;
unsigned long *watchdog_cpumask_bits = cpumask_bits(&watchdog_cpumask);
@@ -162,6 +160,8 @@ static void lockup_detector_update_enable(void)
int __read_mostly sysctl_softlockup_all_cpu_backtrace;
#endif
+static struct cpumask watchdog_allowed_mask __read_mostly;
+
/* Global variables, exported for sysctl */
unsigned int __read_mostly softlockup_panic =
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE;
--
2.26.2
^ permalink raw reply related
* [PATCH 05/11 v3] kprobes/ftrace: Add recursion protection to the ftrace callback
From: Steven Rostedt @ 2020-11-06 2:32 UTC (permalink / raw)
To: linux-kernel
Cc: Peter Zijlstra, James E.J. Bottomley, Guo Ren, linux-csky,
H. Peter Anvin, Miroslav Benes, Ingo Molnar, linux-s390,
Helge Deller, x86, Anil S Keshavamurthy, Christian Borntraeger,
Naveen N. Rao, Petr Mladek, Vasily Gorbik, Heiko Carstens,
Jiri Kosina, Borislav Petkov, Josh Poimboeuf, Thomas Gleixner,
linux-parisc, Masami Hiramatsu, Paul Mackerras, Andrew Morton,
linuxppc-dev, David S. Miller
In-Reply-To: <20201106023235.367190737@goodmis.org>
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
If a ftrace callback does not supply its own recursion protection and
does not set the RECURSION_SAFE flag in its ftrace_ops, then ftrace will
make a helper trampoline to do so before calling the callback instead of
just calling the callback directly.
The default for ftrace_ops is going to change. It will expect that handlers
provide their own recursion protection, unless its ftrace_ops states
otherwise.
Link: https://lkml.kernel.org/r/20201028115613.140212174@goodmis.org
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Guo Ren <guoren@kernel.org>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Helge Deller <deller@gmx.de>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Borislav Petkov <bp@alien8.de>
Cc: x86@kernel.org
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: "Naveen N. Rao" <naveen.n.rao@linux.ibm.com>
Cc: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: linux-csky@vger.kernel.org
Cc: linux-parisc@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s390@vger.kernel.org
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
Changes since v2:
- Move get_kprobe() into preempt disabled sections for various archs
arch/csky/kernel/probes/ftrace.c | 12 ++++++++++--
arch/parisc/kernel/ftrace.c | 16 +++++++++++++---
arch/powerpc/kernel/kprobes-ftrace.c | 11 ++++++++++-
arch/s390/kernel/ftrace.c | 16 +++++++++++++---
arch/x86/kernel/kprobes/ftrace.c | 12 ++++++++++--
5 files changed, 56 insertions(+), 11 deletions(-)
diff --git a/arch/csky/kernel/probes/ftrace.c b/arch/csky/kernel/probes/ftrace.c
index 5264763d05be..5eb2604fdf71 100644
--- a/arch/csky/kernel/probes/ftrace.c
+++ b/arch/csky/kernel/probes/ftrace.c
@@ -13,16 +13,21 @@ int arch_check_ftrace_location(struct kprobe *p)
void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *ops, struct pt_regs *regs)
{
+ int bit;
bool lr_saver = false;
struct kprobe *p;
struct kprobe_ctlblk *kcb;
- /* Preempt is disabled by ftrace */
+ bit = ftrace_test_recursion_trylock();
+ if (bit < 0)
+ return;
+
+ preempt_disable_notrace();
p = get_kprobe((kprobe_opcode_t *)ip);
if (!p) {
p = get_kprobe((kprobe_opcode_t *)(ip - MCOUNT_INSN_SIZE));
if (unlikely(!p) || kprobe_disabled(p))
- return;
+ goto out;
lr_saver = true;
}
@@ -56,6 +61,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
*/
__this_cpu_write(current_kprobe, NULL);
}
+out:
+ preempt_enable_notrace();
+ ftrace_test_recursion_unlock(bit);
}
NOKPROBE_SYMBOL(kprobe_ftrace_handler);
diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
index 63e3ecb9da81..13d85042810a 100644
--- a/arch/parisc/kernel/ftrace.c
+++ b/arch/parisc/kernel/ftrace.c
@@ -207,14 +207,21 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *ops, struct pt_regs *regs)
{
struct kprobe_ctlblk *kcb;
- struct kprobe *p = get_kprobe((kprobe_opcode_t *)ip);
+ struct kprobe *p;
+ int bit;
- if (unlikely(!p) || kprobe_disabled(p))
+ bit = ftrace_test_recursion_trylock();
+ if (bit < 0)
return;
+ preempt_disable_notrace();
+ p = get_kprobe((kprobe_opcode_t *)ip);
+ if (unlikely(!p) || kprobe_disabled(p))
+ goto out;
+
if (kprobe_running()) {
kprobes_inc_nmissed_count(p);
- return;
+ goto out;
}
__this_cpu_write(current_kprobe, p);
@@ -235,6 +242,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
}
}
__this_cpu_write(current_kprobe, NULL);
+out:
+ preempt_enable_notrace();
+ ftrace_test_recursion_unlock(bit);
}
NOKPROBE_SYMBOL(kprobe_ftrace_handler);
diff --git a/arch/powerpc/kernel/kprobes-ftrace.c b/arch/powerpc/kernel/kprobes-ftrace.c
index 972cb28174b2..5df8d50c65ae 100644
--- a/arch/powerpc/kernel/kprobes-ftrace.c
+++ b/arch/powerpc/kernel/kprobes-ftrace.c
@@ -18,10 +18,16 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
{
struct kprobe *p;
struct kprobe_ctlblk *kcb;
+ int bit;
+ bit = ftrace_test_recursion_trylock();
+ if (bit < 0)
+ return;
+
+ preempt_disable_notrace();
p = get_kprobe((kprobe_opcode_t *)nip);
if (unlikely(!p) || kprobe_disabled(p))
- return;
+ goto out;
kcb = get_kprobe_ctlblk();
if (kprobe_running()) {
@@ -52,6 +58,9 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
*/
__this_cpu_write(current_kprobe, NULL);
}
+out:
+ preempt_enable_notrace();
+ ftrace_test_recursion_unlock(bit);
}
NOKPROBE_SYMBOL(kprobe_ftrace_handler);
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index b388e87a08bf..8f31c726537a 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -201,14 +201,21 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *ops, struct pt_regs *regs)
{
struct kprobe_ctlblk *kcb;
- struct kprobe *p = get_kprobe((kprobe_opcode_t *)ip);
+ struct kprobe *p;
+ int bit;
- if (unlikely(!p) || kprobe_disabled(p))
+ bit = ftrace_test_recursion_trylock();
+ if (bit < 0)
return;
+ preempt_disable_notrace();
+ p = get_kprobe((kprobe_opcode_t *)ip);
+ if (unlikely(!p) || kprobe_disabled(p))
+ goto out;
+
if (kprobe_running()) {
kprobes_inc_nmissed_count(p);
- return;
+ goto out;
}
__this_cpu_write(current_kprobe, p);
@@ -228,6 +235,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
}
}
__this_cpu_write(current_kprobe, NULL);
+out:
+ preempt_enable_notrace();
+ ftrace_test_recursion_unlock(bit);
}
NOKPROBE_SYMBOL(kprobe_ftrace_handler);
diff --git a/arch/x86/kernel/kprobes/ftrace.c b/arch/x86/kernel/kprobes/ftrace.c
index 681a4b36e9bb..a40a6cdfcca3 100644
--- a/arch/x86/kernel/kprobes/ftrace.c
+++ b/arch/x86/kernel/kprobes/ftrace.c
@@ -18,11 +18,16 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
{
struct kprobe *p;
struct kprobe_ctlblk *kcb;
+ int bit;
- /* Preempt is disabled by ftrace */
+ bit = ftrace_test_recursion_trylock();
+ if (bit < 0)
+ return;
+
+ preempt_disable_notrace();
p = get_kprobe((kprobe_opcode_t *)ip);
if (unlikely(!p) || kprobe_disabled(p))
- return;
+ goto out;
kcb = get_kprobe_ctlblk();
if (kprobe_running()) {
@@ -52,6 +57,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
*/
__this_cpu_write(current_kprobe, NULL);
}
+out:
+ preempt_enable_notrace();
+ ftrace_test_recursion_unlock(bit);
}
NOKPROBE_SYMBOL(kprobe_ftrace_handler);
--
2.28.0
^ permalink raw reply related
* [PATCH 11/11 v3] ftrace: Add recording of functions that caused recursion
From: Steven Rostedt @ 2020-11-06 2:32 UTC (permalink / raw)
To: linux-kernel
Cc: Anton Vorontsov, linux-doc, Peter Zijlstra,
Sebastian Andrzej Siewior, Kamalesh Babulal, James E.J. Bottomley,
Guo Ren, H. Peter Anvin, live-patching, Miroslav Benes,
Ingo Molnar, linux-s390, Joe Lawrence, Jonathan Corbet,
Mauro Carvalho Chehab, Helge Deller, x86, linux-csky,
Christian Borntraeger, Petr Mladek, Kees Cook, Vasily Gorbik,
Heiko Carstens, Jiri Kosina, Borislav Petkov, Josh Poimboeuf,
Thomas Gleixner, Tony Luck, linux-parisc, Masami Hiramatsu,
Colin Cross, Paul Mackerras, Andrew Morton, linuxppc-dev
In-Reply-To: <20201106023235.367190737@goodmis.org>
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
This adds CONFIG_FTRACE_RECORD_RECURSION that will record to a file
"recursed_functions" all the functions that caused recursion while a
callback to the function tracer was running.
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Guo Ren <guoren@kernel.org>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Helge Deller <deller@gmx.de>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Borislav Petkov <bp@alien8.de>
Cc: x86@kernel.org
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Anton Vorontsov <anton@enomsg.org>
Cc: Colin Cross <ccross@android.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Jiri Kosina <jikos@kernel.org>
Cc: Miroslav Benes <mbenes@suse.cz>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Joe Lawrence <joe.lawrence@redhat.com>
Cc: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
Cc: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-csky@vger.kernel.org
Cc: linux-parisc@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s390@vger.kernel.org
Cc: live-patching@vger.kernel.org
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
Changes since v2:
- Use trace_recursion flags in current for protecting recursion of recursion recording
- Make the recursion logic a little cleaner
- Export GPL the recursion recording
Documentation/trace/ftrace-uses.rst | 6 +-
arch/csky/kernel/probes/ftrace.c | 2 +-
arch/parisc/kernel/ftrace.c | 2 +-
arch/powerpc/kernel/kprobes-ftrace.c | 2 +-
arch/s390/kernel/ftrace.c | 2 +-
arch/x86/kernel/kprobes/ftrace.c | 2 +-
fs/pstore/ftrace.c | 2 +-
include/linux/trace_recursion.h | 29 +++-
kernel/livepatch/patch.c | 2 +-
kernel/trace/Kconfig | 25 +++
kernel/trace/Makefile | 1 +
kernel/trace/ftrace.c | 4 +-
kernel/trace/trace_event_perf.c | 2 +-
kernel/trace/trace_functions.c | 2 +-
kernel/trace/trace_output.c | 6 +-
kernel/trace/trace_output.h | 1 +
kernel/trace/trace_recursion_record.c | 236 ++++++++++++++++++++++++++
17 files changed, 306 insertions(+), 20 deletions(-)
create mode 100644 kernel/trace/trace_recursion_record.c
diff --git a/Documentation/trace/ftrace-uses.rst b/Documentation/trace/ftrace-uses.rst
index 86cd14b8e126..5981d5691745 100644
--- a/Documentation/trace/ftrace-uses.rst
+++ b/Documentation/trace/ftrace-uses.rst
@@ -118,7 +118,7 @@ can help in this regard. If you start your code with:
int bit;
- bit = ftrace_test_recursion_trylock();
+ bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (bit < 0)
return;
@@ -130,7 +130,9 @@ The code in between will be safe to use, even if it ends up calling a
function that the callback is tracing. Note, on success,
ftrace_test_recursion_trylock() will disable preemption, and the
ftrace_test_recursion_unlock() will enable it again (if it was previously
-enabled).
+enabled). The instruction pointer (ip) and its parent (parent_ip) is passed to
+ftrace_test_recursion_trylock() to record where the recursion happened
+(if CONFIG_FTRACE_RECORD_RECURSION is set).
Alternatively, if the FTRACE_OPS_FL_RECURSION flag is set on the ftrace_ops
(as explained below), then a helper trampoline will be used to test
diff --git a/arch/csky/kernel/probes/ftrace.c b/arch/csky/kernel/probes/ftrace.c
index 5eb2604fdf71..f30b179924ef 100644
--- a/arch/csky/kernel/probes/ftrace.c
+++ b/arch/csky/kernel/probes/ftrace.c
@@ -18,7 +18,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct kprobe *p;
struct kprobe_ctlblk *kcb;
- bit = ftrace_test_recursion_trylock();
+ bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (bit < 0)
return;
diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
index 13d85042810a..1c5d3732bda2 100644
--- a/arch/parisc/kernel/ftrace.c
+++ b/arch/parisc/kernel/ftrace.c
@@ -210,7 +210,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct kprobe *p;
int bit;
- bit = ftrace_test_recursion_trylock();
+ bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (bit < 0)
return;
diff --git a/arch/powerpc/kernel/kprobes-ftrace.c b/arch/powerpc/kernel/kprobes-ftrace.c
index 5df8d50c65ae..fdfee39938ea 100644
--- a/arch/powerpc/kernel/kprobes-ftrace.c
+++ b/arch/powerpc/kernel/kprobes-ftrace.c
@@ -20,7 +20,7 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
struct kprobe_ctlblk *kcb;
int bit;
- bit = ftrace_test_recursion_trylock();
+ bit = ftrace_test_recursion_trylock(nip, parent_nip);
if (bit < 0)
return;
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index 8f31c726537a..657c1ab45408 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -204,7 +204,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct kprobe *p;
int bit;
- bit = ftrace_test_recursion_trylock();
+ bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (bit < 0)
return;
diff --git a/arch/x86/kernel/kprobes/ftrace.c b/arch/x86/kernel/kprobes/ftrace.c
index a40a6cdfcca3..954d930a7127 100644
--- a/arch/x86/kernel/kprobes/ftrace.c
+++ b/arch/x86/kernel/kprobes/ftrace.c
@@ -20,7 +20,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
struct kprobe_ctlblk *kcb;
int bit;
- bit = ftrace_test_recursion_trylock();
+ bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (bit < 0)
return;
diff --git a/fs/pstore/ftrace.c b/fs/pstore/ftrace.c
index 816210fc5d3a..adb0935eb062 100644
--- a/fs/pstore/ftrace.c
+++ b/fs/pstore/ftrace.c
@@ -41,7 +41,7 @@ static void notrace pstore_ftrace_call(unsigned long ip,
if (unlikely(oops_in_progress))
return;
- bit = ftrace_test_recursion_trylock();
+ bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (bit < 0)
return;
diff --git a/include/linux/trace_recursion.h b/include/linux/trace_recursion.h
index ac3d73484cb2..228cc56ed66e 100644
--- a/include/linux/trace_recursion.h
+++ b/include/linux/trace_recursion.h
@@ -91,6 +91,9 @@ enum {
* not be correct. Allow for a single recursion to cover this case.
*/
TRACE_TRANSITION_BIT,
+
+ /* Used to prevent recursion recording from recursing. */
+ TRACE_RECORD_RECURSION_BIT,
};
#define trace_recursion_set(bit) do { (current)->trace_recursion |= (1<<(bit)); } while (0)
@@ -142,7 +145,22 @@ static __always_inline int trace_get_context_bit(void)
pc & HARDIRQ_MASK ? TRACE_CTX_IRQ : TRACE_CTX_SOFTIRQ;
}
-static __always_inline int trace_test_and_set_recursion(int start, int max)
+#ifdef CONFIG_FTRACE_RECORD_RECURSION
+extern void ftrace_record_recursion(unsigned long ip, unsigned long parent_ip);
+# define do_ftrace_record_recursion(ip, pip) \
+ do { \
+ if (!trace_recursion_test(TRACE_RECORD_RECURSION_BIT)) { \
+ trace_recursion_set(TRACE_RECORD_RECURSION_BIT); \
+ ftrace_record_recursion(ip, pip); \
+ trace_recursion_clear(TRACE_RECORD_RECURSION_BIT); \
+ } \
+ } while (0)
+#else
+# define do_ftrace_record_recursion(ip, pip) do { } while (0)
+#endif
+
+static __always_inline int trace_test_and_set_recursion(unsigned long ip, unsigned long pip,
+ int start, int max)
{
unsigned int val = current->trace_recursion;
int bit;
@@ -158,8 +176,10 @@ static __always_inline int trace_test_and_set_recursion(int start, int max)
* a switch between contexts. Allow for a single recursion.
*/
bit = TRACE_TRANSITION_BIT;
- if (trace_recursion_test(bit))
+ if (trace_recursion_test(bit)) {
+ do_ftrace_record_recursion(ip, pip);
return -1;
+ }
trace_recursion_set(bit);
barrier();
return bit + 1;
@@ -199,9 +219,10 @@ static __always_inline void trace_clear_recursion(int bit)
* Returns: -1 if a recursion happened.
* >= 0 if no recursion
*/
-static __always_inline int ftrace_test_recursion_trylock(void)
+static __always_inline int ftrace_test_recursion_trylock(unsigned long ip,
+ unsigned long parent_ip)
{
- return trace_test_and_set_recursion(TRACE_FTRACE_START, TRACE_FTRACE_MAX);
+ return trace_test_and_set_recursion(ip, parent_ip, TRACE_FTRACE_START, TRACE_FTRACE_MAX);
}
/**
diff --git a/kernel/livepatch/patch.c b/kernel/livepatch/patch.c
index 15480bf3ce88..875c5dbbdd33 100644
--- a/kernel/livepatch/patch.c
+++ b/kernel/livepatch/patch.c
@@ -49,7 +49,7 @@ static void notrace klp_ftrace_handler(unsigned long ip,
ops = container_of(fops, struct klp_ops, fops);
- bit = ftrace_test_recursion_trylock();
+ bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (WARN_ON_ONCE(bit < 0))
return;
/*
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index a4020c0b4508..9b11c096d139 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -727,6 +727,31 @@ config TRACE_EVAL_MAP_FILE
If unsure, say N.
+config FTRACE_RECORD_RECURSION
+ bool "Record functions that recurse in function tracing"
+ depends on FUNCTION_TRACER
+ help
+ All callbacks that attach to the function tracing have some sort
+ of protection against recursion. Even though the protection exists,
+ it adds overhead. This option will create a file in the tracefs
+ file system called "recursed_functions" that will list the functions
+ that triggered a recursion.
+
+ This will add more overhead to cases that have recursion.
+
+ If unsure, say N
+
+config FTRACE_RECORD_RECURSION_SIZE
+ int "Max number of recursed functions to record"
+ default 128
+ depends on FTRACE_RECORD_RECURSION
+ help
+ This defines the limit of number of functions that can be
+ listed in the "recursed_functions" file, that lists all
+ the functions that caused a recursion to happen.
+ This file can be reset, but the limit can not change in
+ size at runtime.
+
config GCOV_PROFILE_FTRACE
bool "Enable GCOV profiling on ftrace subsystem"
depends on GCOV_KERNEL
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index e153be351548..7e44cea89fdc 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -92,6 +92,7 @@ obj-$(CONFIG_DYNAMIC_EVENTS) += trace_dynevent.o
obj-$(CONFIG_PROBE_EVENTS) += trace_probe.o
obj-$(CONFIG_UPROBE_EVENTS) += trace_uprobe.o
obj-$(CONFIG_BOOTTIME_TRACING) += trace_boot.o
+obj-$(CONFIG_FTRACE_RECORD_RECURSION) += trace_recursion_record.o
obj-$(CONFIG_TRACEPOINT_BENCHMARK) += trace_benchmark.o
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 39f2bba89b76..03aad2b5cd5e 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -6918,7 +6918,7 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *op;
int bit;
- bit = trace_test_and_set_recursion(TRACE_LIST_START, TRACE_LIST_MAX);
+ bit = trace_test_and_set_recursion(ip, parent_ip, TRACE_LIST_START, TRACE_LIST_MAX);
if (bit < 0)
return;
@@ -6993,7 +6993,7 @@ static void ftrace_ops_assist_func(unsigned long ip, unsigned long parent_ip,
{
int bit;
- bit = trace_test_and_set_recursion(TRACE_LIST_START, TRACE_LIST_MAX);
+ bit = trace_test_and_set_recursion(ip, parent_ip, TRACE_LIST_START, TRACE_LIST_MAX);
if (bit < 0)
return;
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c
index a2b9fddb8148..1b202e28dfaa 100644
--- a/kernel/trace/trace_event_perf.c
+++ b/kernel/trace/trace_event_perf.c
@@ -447,7 +447,7 @@ perf_ftrace_function_call(unsigned long ip, unsigned long parent_ip,
if ((unsigned long)ops->private != smp_processor_id())
return;
- bit = ftrace_test_recursion_trylock();
+ bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (bit < 0)
return;
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 89c414ce1388..646eda6c44a5 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -141,7 +141,7 @@ function_trace_call(unsigned long ip, unsigned long parent_ip,
if (unlikely(!tr->function_enabled))
return;
- bit = ftrace_test_recursion_trylock();
+ bit = ftrace_test_recursion_trylock(ip, parent_ip);
if (bit < 0)
return;
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index 000e9dc224c6..92b1575ae0ca 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -353,8 +353,8 @@ static inline const char *kretprobed(const char *name)
}
#endif /* CONFIG_KRETPROBES */
-static void
-seq_print_sym(struct trace_seq *s, unsigned long address, bool offset)
+void
+trace_seq_print_sym(struct trace_seq *s, unsigned long address, bool offset)
{
#ifdef CONFIG_KALLSYMS
char str[KSYM_SYMBOL_LEN];
@@ -420,7 +420,7 @@ seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
goto out;
}
- seq_print_sym(s, ip, sym_flags & TRACE_ITER_SYM_OFFSET);
+ trace_seq_print_sym(s, ip, sym_flags & TRACE_ITER_SYM_OFFSET);
if (sym_flags & TRACE_ITER_SYM_ADDR)
trace_seq_printf(s, " <" IP_FMT ">", ip);
diff --git a/kernel/trace/trace_output.h b/kernel/trace/trace_output.h
index 2f742b74e7e6..4c954636caf0 100644
--- a/kernel/trace/trace_output.h
+++ b/kernel/trace/trace_output.h
@@ -16,6 +16,7 @@ extern int
seq_print_ip_sym(struct trace_seq *s, unsigned long ip,
unsigned long sym_flags);
+extern void trace_seq_print_sym(struct trace_seq *s, unsigned long address, bool offset);
extern int trace_print_context(struct trace_iterator *iter);
extern int trace_print_lat_context(struct trace_iterator *iter);
diff --git a/kernel/trace/trace_recursion_record.c b/kernel/trace/trace_recursion_record.c
new file mode 100644
index 000000000000..b2edac1fe156
--- /dev/null
+++ b/kernel/trace/trace_recursion_record.c
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/seq_file.h>
+#include <linux/kallsyms.h>
+#include <linux/module.h>
+#include <linux/ftrace.h>
+#include <linux/fs.h>
+
+#include "trace_output.h"
+
+struct recursed_functions {
+ unsigned long ip;
+ unsigned long parent_ip;
+};
+
+static struct recursed_functions recursed_functions[CONFIG_FTRACE_RECORD_RECURSION_SIZE];
+static atomic_t nr_records;
+
+/*
+ * Cache the last found function. Yes, updates to this is racey, but
+ * so is memory cache ;-)
+ */
+static unsigned long cached_function;
+
+void ftrace_record_recursion(unsigned long ip, unsigned long parent_ip)
+{
+ int index = 0;
+ int i;
+ unsigned long old;
+
+ again:
+ /* First check the last one recorded */
+ if (ip == cached_function)
+ return;
+
+ i = atomic_read(&nr_records);
+ /* nr_records is -1 when clearing records */
+ smp_mb__after_atomic();
+ if (i < 0)
+ return;
+
+ /*
+ * If there's two writers and this writer comes in second,
+ * the cmpxchg() below to update the ip will fail. Then this
+ * writer will try again. It is possible that index will now
+ * be greater than nr_records. This is because the writer
+ * that succeeded has not updated the nr_records yet.
+ * This writer could keep trying again until the other writer
+ * updates nr_records. But if the other writer takes an
+ * interrupt, and that interrupt locks up that CPU, we do
+ * not want this CPU to lock up due to the recursion protection,
+ * and have a bug report showing this CPU as the cause of
+ * locking up the computer. To not lose this record, this
+ * writer will simply use the next position to update the
+ * recursed_functions, and it will update the nr_records
+ * accordingly.
+ */
+ if (index < i)
+ index = i;
+ if (index >= CONFIG_FTRACE_RECORD_RECURSION_SIZE)
+ return;
+
+ for (i = index - 1; i >= 0; i--) {
+ if (recursed_functions[i].ip == ip) {
+ cached_function = ip;
+ return;
+ }
+ }
+
+ cached_function = ip;
+
+ /*
+ * We only want to add a function if it hasn't been added before.
+ * Add to the current location before incrementing the count.
+ * If it fails to add, then increment the index (save in i)
+ * and try again.
+ */
+ old = cmpxchg(&recursed_functions[index].ip, 0, ip);
+ if (old != 0) {
+ /* Did something else already added this for us? */
+ if (old == ip)
+ return;
+ /* Try the next location (use i for the next index) */
+ index++;
+ goto again;
+ }
+
+ recursed_functions[index].parent_ip = parent_ip;
+
+ /*
+ * It's still possible that we could race with the clearing
+ * CPU0 CPU1
+ * ---- ----
+ * ip = func
+ * nr_records = -1;
+ * recursed_functions[0] = 0;
+ * i = -1
+ * if (i < 0)
+ * nr_records = 0;
+ * (new recursion detected)
+ * recursed_functions[0] = func
+ * cmpxchg(recursed_functions[0],
+ * func, 0)
+ *
+ * But the worse that could happen is that we get a zero in
+ * the recursed_functions array, and it's likely that "func" will
+ * be recorded again.
+ */
+ i = atomic_read(&nr_records);
+ smp_mb__after_atomic();
+ if (i < 0)
+ cmpxchg(&recursed_functions[index].ip, ip, 0);
+ else if (i <= index)
+ atomic_cmpxchg(&nr_records, i, index + 1);
+}
+EXPORT_SYMBOL_GPL(ftrace_record_recursion);
+
+static DEFINE_MUTEX(recursed_function_lock);
+static struct trace_seq *tseq;
+
+static void *recursed_function_seq_start(struct seq_file *m, loff_t *pos)
+{
+ void *ret = NULL;
+ int index;
+
+ mutex_lock(&recursed_function_lock);
+ index = atomic_read(&nr_records);
+ if (*pos < index) {
+ ret = &recursed_functions[*pos];
+ }
+
+ tseq = kzalloc(sizeof(*tseq), GFP_KERNEL);
+ if (!tseq)
+ return ERR_PTR(-ENOMEM);
+
+ trace_seq_init(tseq);
+
+ return ret;
+}
+
+static void *recursed_function_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ int index;
+ int p;
+
+ index = atomic_read(&nr_records);
+ p = ++(*pos);
+
+ return p < index ? &recursed_functions[p] : NULL;
+}
+
+static void recursed_function_seq_stop(struct seq_file *m, void *v)
+{
+ kfree(tseq);
+ mutex_unlock(&recursed_function_lock);
+}
+
+static int recursed_function_seq_show(struct seq_file *m, void *v)
+{
+ struct recursed_functions *record = v;
+ int ret = 0;
+
+ if (record) {
+ trace_seq_print_sym(tseq, record->parent_ip, true);
+ trace_seq_puts(tseq, ":\t");
+ trace_seq_print_sym(tseq, record->ip, true);
+ trace_seq_putc(tseq, '\n');
+ ret = trace_print_seq(m, tseq);
+ }
+
+ return ret;
+}
+
+static const struct seq_operations recursed_function_seq_ops = {
+ .start = recursed_function_seq_start,
+ .next = recursed_function_seq_next,
+ .stop = recursed_function_seq_stop,
+ .show = recursed_function_seq_show
+};
+
+static int recursed_function_open(struct inode *inode, struct file *file)
+{
+ int ret = 0;
+
+ mutex_lock(&recursed_function_lock);
+ /* If this file was opened for write, then erase contents */
+ if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
+ /* disable updating records */
+ atomic_set(&nr_records, -1);
+ smp_mb__after_atomic();
+ memset(recursed_functions, 0, sizeof(recursed_functions));
+ smp_wmb();
+ /* enable them again */
+ atomic_set(&nr_records, 0);
+ }
+ if (file->f_mode & FMODE_READ)
+ ret = seq_open(file, &recursed_function_seq_ops);
+ mutex_unlock(&recursed_function_lock);
+
+ return ret;
+}
+
+static ssize_t recursed_function_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ return count;
+}
+
+static int recursed_function_release(struct inode *inode, struct file *file)
+{
+ if (file->f_mode & FMODE_READ)
+ seq_release(inode, file);
+ return 0;
+}
+
+static const struct file_operations recursed_functions_fops = {
+ .open = recursed_function_open,
+ .write = recursed_function_write,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = recursed_function_release,
+};
+
+__init static int create_recursed_functions(void)
+{
+ struct dentry *dentry;
+
+ dentry = trace_create_file("recursed_functions", 0644, NULL, NULL,
+ &recursed_functions_fops);
+ if (!dentry)
+ pr_warn("WARNING: Failed to create recursed_functions\n");
+ return 0;
+}
+
+fs_initcall(create_recursed_functions);
--
2.28.0
^ permalink raw reply related
* Re: [PATCH v3 2/2] ASoC: fsl_aud2htx: Add aud2htx module driver
From: Shengjiu Wang @ 2020-11-06 2:51 UTC (permalink / raw)
To: Nicolin Chen
Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
alsa-devel, Timur Tabi, Xiubo Li, Fabio Estevam, Shengjiu Wang,
Liam Girdwood, Takashi Iwai, Rob Herring, Mark Brown,
linuxppc-dev, linux-kernel
In-Reply-To: <20201105013539.GA16459@Asurada-Nvidia>
On Thu, Nov 5, 2020 at 9:48 AM Nicolin Chen <nicoleotsuka@gmail.com> wrote:
>
> On Mon, Nov 02, 2020 at 09:52:27AM +0800, Shengjiu Wang wrote:
> > The AUD2HTX is a digital module that provides a bridge between
> > the Audio Subsystem and the HDMI RTX Subsystem. This module
> > includes intermediate storage to queue SDMA transactions prior
> > to being synchronized and passed to the HDMI RTX Subsystem over
> > the Audio Link.
> >
> > The AUD2HTX contains a DMA request routed to the SDMA module.
> > This DMA request is controlled based on the watermark level in
> > the 32-entry sample buffer.
> >
> > Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
>
> Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
>
> Despite some small comments inline.
>
> > +static int fsl_aud2htx_dai_probe(struct snd_soc_dai *cpu_dai)
> > +{
> > + struct fsl_aud2htx *aud2htx = dev_get_drvdata(cpu_dai->dev);
> > +
> > + /* DMA request when number of entries < WTMK_LOW */
> > + regmap_update_bits(aud2htx->regmap, AUD2HTX_CTRL_EXT,
> > + AUD2HTX_CTRE_DT_MASK, 0);
> > +
> > + /* Disable interrupts*/
> > + regmap_update_bits(aud2htx->regmap, AUD2HTX_IRQ_MASK,
> > + AUD2HTX_WM_HIGH_IRQ_MASK |
> > + AUD2HTX_WM_LOW_IRQ_MASK |
> > + AUD2HTX_OVF_MASK,
> > + AUD2HTX_WM_HIGH_IRQ_MASK |
> > + AUD2HTX_WM_LOW_IRQ_MASK |
> > + AUD2HTX_OVF_MASK);
> > +
> > + /* Configure watermark */
> > + regmap_update_bits(aud2htx->regmap, AUD2HTX_CTRL_EXT,
> > + AUD2HTX_CTRE_WL_MASK,
> > + AUD2HTX_WTMK_LOW << AUD2HTX_CTRE_WL_SHIFT);
> > + regmap_update_bits(aud2htx->regmap, AUD2HTX_CTRL_EXT,
> > + AUD2HTX_CTRE_WH_MASK,
> > + AUD2HTX_WTMK_HIGH << AUD2HTX_CTRE_WH_SHIFT);
>
> If there isn't a hard requirement from hardware, feels better to
> combine all the writes to AUD2HTX_CTRL_EXT into one single MMIO.
ok, will update it.
>
> > +static irqreturn_t fsl_aud2htx_isr(int irq, void *dev_id)
> > +{
> > + return IRQ_HANDLED;
>
> Empty isr? Perhaps can drop the request_irq() at all?
I'd like to keep this for future enhancement, what do you think?
>
> > +static int fsl_aud2htx_probe(struct platform_device *pdev)
> > +{
> > + struct fsl_aud2htx *aud2htx;
> > + struct resource *res;
> > + void __iomem *regs;
> > + int ret, irq;
> > +
> > + aud2htx = devm_kzalloc(&pdev->dev, sizeof(*aud2htx), GFP_KERNEL);
> > + if (!aud2htx)
> > + return -ENOMEM;
> > +
> > + aud2htx->pdev = pdev;
> > +
> > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > + regs = devm_ioremap_resource(&pdev->dev, res);
> > + if (IS_ERR(regs)) {
> > + dev_err(&pdev->dev, "failed ioremap\n");
> > + return PTR_ERR(regs);
> > + }
> > +
> > + aud2htx->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
> > + &fsl_aud2htx_regmap_config);
> > + if (IS_ERR(aud2htx->regmap)) {
> > + dev_err(&pdev->dev, "failed to init regmap");
> > + return PTR_ERR(aud2htx->regmap);
> > + }
> > +
> > + irq = platform_get_irq(pdev, 0);
> > + if (irq < 0) {
> > + dev_err(&pdev->dev, "no irq for node %s\n",
> > + dev_name(&pdev->dev));
>
> dev_err() already prints dev_name, so not necessary to print again.
ok, will update it
best regards
wang shengjiu
^ permalink raw reply
* Re: [PATCH kernel v2] irq: Add reference counting to IRQ mappings
From: Alexey Kardashevskiy @ 2020-11-06 3:06 UTC (permalink / raw)
To: linuxppc-dev
Cc: Rob Herring, Marc Zyngier, linux-kernel, Qian Cai,
Cédric Le Goater, Frederic Barrat, Thomas Gleixner,
Michal Suchánek, David Gibson
In-Reply-To: <20201029110141.94304-1-aik@ozlabs.ru>
Hi,
This one seems to be broken in the domain associating part so please
ignore it, I'll post v3 soon. Thanks,
On 29/10/2020 22:01, Alexey Kardashevskiy wrote:
> PCI devices share 4 legacy INTx interrupts from the same PCI host bridge.
> Device drivers map/unmap hardware interrupts via irq_create_mapping()/
> irq_dispose_mapping(). The problem with that these interrupts are
> shared and when performing hot unplug, we need to unmap the interrupt
> only when the last device is released.
>
> This reuses already existing irq_desc::kobj for this purpose.
> The refcounter is naturally 1 when the descriptor is allocated already;
> this adds kobject_get() in places where already existing mapped virq
> is returned.
>
> This reorganizes irq_dispose_mapping() to release the kobj and let
> the release callback do the cleanup.
>
> Quick grep shows no sign of irq reference counting in drivers. Drivers
> typically request mapping when probing and dispose it when removing;
> platforms tend to dispose only if setup failed and the rest seems
> calling one dispose per one mapping. Except (at least) PPC/pseries
> which needs https://lkml.org/lkml/2020/10/27/259
>
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
>
> What is the easiest way to get irq-hierarchical hardware?
> I have a bunch of powerpc boxes (no good) but also a raspberry pi,
> a bunch of 32/64bit orange pi's, an "armada" arm box,
> thinkpads - is any of this good for the task?
>
>
> ---
> Changes:
> v2:
> * added more get/put, including irq_domain_associate/irq_domain_disassociate
> ---
> kernel/irq/irqdesc.c | 36 ++++++++++++++++++++-----------
> kernel/irq/irqdomain.c | 49 +++++++++++++++++++++++++++++-------------
> 2 files changed, 58 insertions(+), 27 deletions(-)
>
> diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
> index 1a7723604399..bc8f62157ffa 100644
> --- a/kernel/irq/irqdesc.c
> +++ b/kernel/irq/irqdesc.c
> @@ -419,20 +419,40 @@ static struct irq_desc *alloc_desc(int irq, int node, unsigned int flags,
> return NULL;
> }
>
> +static void delayed_free_desc(struct rcu_head *rhp);
> static void irq_kobj_release(struct kobject *kobj)
> {
> struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
> +#ifdef CONFIG_IRQ_DOMAIN
> + struct irq_domain *domain;
> + unsigned int virq = desc->irq_data.irq;
>
> - free_masks(desc);
> - free_percpu(desc->kstat_irqs);
> - kfree(desc);
> + domain = desc->irq_data.domain;
> + if (domain) {
> + if (irq_domain_is_hierarchy(domain)) {
> + irq_domain_free_irqs(virq, 1);
> + } else {
> + irq_domain_disassociate(domain, virq);
> + irq_free_desc(virq);
> + }
> + }
> +#endif
> + /*
> + * We free the descriptor, masks and stat fields via RCU. That
> + * allows demultiplex interrupts to do rcu based management of
> + * the child interrupts.
> + * This also allows us to use rcu in kstat_irqs_usr().
> + */
> + call_rcu(&desc->rcu, delayed_free_desc);
> }
>
> static void delayed_free_desc(struct rcu_head *rhp)
> {
> struct irq_desc *desc = container_of(rhp, struct irq_desc, rcu);
>
> - kobject_put(&desc->kobj);
> + free_masks(desc);
> + free_percpu(desc->kstat_irqs);
> + kfree(desc);
> }
>
> static void free_desc(unsigned int irq)
> @@ -453,14 +473,6 @@ static void free_desc(unsigned int irq)
> */
> irq_sysfs_del(desc);
> delete_irq_desc(irq);
> -
> - /*
> - * We free the descriptor, masks and stat fields via RCU. That
> - * allows demultiplex interrupts to do rcu based management of
> - * the child interrupts.
> - * This also allows us to use rcu in kstat_irqs_usr().
> - */
> - call_rcu(&desc->rcu, delayed_free_desc);
> }
>
> static int alloc_descs(unsigned int start, unsigned int cnt, int node,
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index cf8b374b892d..5fb060e077e3 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -487,6 +487,7 @@ static void irq_domain_set_mapping(struct irq_domain *domain,
>
> void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq)
> {
> + struct irq_desc *desc = irq_to_desc(irq);
> struct irq_data *irq_data = irq_get_irq_data(irq);
> irq_hw_number_t hwirq;
>
> @@ -514,11 +515,14 @@ void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq)
>
> /* Clear reverse map for this hwirq */
> irq_domain_clear_mapping(domain, hwirq);
> +
> + kobject_put(&desc->kobj);
> }
>
> int irq_domain_associate(struct irq_domain *domain, unsigned int virq,
> irq_hw_number_t hwirq)
> {
> + struct irq_desc *desc = irq_to_desc(virq);
> struct irq_data *irq_data = irq_get_irq_data(virq);
> int ret;
>
> @@ -530,6 +534,8 @@ int irq_domain_associate(struct irq_domain *domain, unsigned int virq,
> if (WARN(irq_data->domain, "error: virq%i is already associated", virq))
> return -EINVAL;
>
> + kobject_get(&desc->kobj);
> +
> mutex_lock(&irq_domain_mutex);
> irq_data->hwirq = hwirq;
> irq_data->domain = domain;
> @@ -548,6 +554,7 @@ int irq_domain_associate(struct irq_domain *domain, unsigned int virq,
> irq_data->domain = NULL;
> irq_data->hwirq = 0;
> mutex_unlock(&irq_domain_mutex);
> + kobject_put(&desc->kobj);
> return ret;
> }
>
> @@ -638,6 +645,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
> {
> struct device_node *of_node;
> int virq;
> + struct irq_desc *desc;
>
> pr_debug("irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq);
>
> @@ -655,7 +663,9 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
> /* Check if mapping already exists */
> virq = irq_find_mapping(domain, hwirq);
> if (virq) {
> + desc = irq_to_desc(virq);
> pr_debug("-> existing mapping on virq %d\n", virq);
> + kobject_get(&desc->kobj);
> return virq;
> }
>
> @@ -674,6 +684,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
> pr_debug("irq %lu on domain %s mapped to virtual irq %u\n",
> hwirq, of_node_full_name(of_node), virq);
>
> + desc = irq_to_desc(virq);
> return virq;
> }
> EXPORT_SYMBOL_GPL(irq_create_mapping);
> @@ -751,6 +762,7 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
> irq_hw_number_t hwirq;
> unsigned int type = IRQ_TYPE_NONE;
> int virq;
> + struct irq_desc *desc;
>
> if (fwspec->fwnode) {
> domain = irq_find_matching_fwspec(fwspec, DOMAIN_BUS_WIRED);
> @@ -787,8 +799,15 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
> * current trigger type then we are done so return the
> * interrupt number.
> */
> - if (type == IRQ_TYPE_NONE || type == irq_get_trigger_type(virq))
> + if (type == IRQ_TYPE_NONE || type == irq_get_trigger_type(virq)) {
> + desc = irq_to_desc(virq);
> + kobject_get(&desc->kobj);
> +
> + pr_err("___K___ (%u) %s %u: virq %d counter %d\n",
> + smp_processor_id(),
> + __func__, __LINE__, virq, kref_read(&desc->kobj.kref));
> return virq;
> + }
>
> /*
> * If the trigger type has not been set yet, then set
> @@ -800,6 +819,8 @@ unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
> return 0;
>
> irqd_set_trigger_type(irq_data, type);
> + desc = irq_to_desc(virq);
> + kobject_get(&desc->kobj);
> return virq;
> }
>
> @@ -852,22 +873,12 @@ EXPORT_SYMBOL_GPL(irq_create_of_mapping);
> */
> void irq_dispose_mapping(unsigned int virq)
> {
> - struct irq_data *irq_data = irq_get_irq_data(virq);
> - struct irq_domain *domain;
> + struct irq_desc *desc = irq_to_desc(virq);
>
> - if (!virq || !irq_data)
> + if (!virq || !desc)
> return;
>
> - domain = irq_data->domain;
> - if (WARN_ON(domain == NULL))
> - return;
> -
> - if (irq_domain_is_hierarchy(domain)) {
> - irq_domain_free_irqs(virq, 1);
> - } else {
> - irq_domain_disassociate(domain, virq);
> - irq_free_desc(virq);
> - }
> + kobject_put(&desc->kobj);
> }
> EXPORT_SYMBOL_GPL(irq_dispose_mapping);
>
> @@ -1413,6 +1424,7 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
> bool realloc, const struct irq_affinity_desc *affinity)
> {
> int i, ret, virq;
> + bool get_ref = false;
>
> if (domain == NULL) {
> domain = irq_default_domain;
> @@ -1422,6 +1434,7 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
>
> if (realloc && irq_base >= 0) {
> virq = irq_base;
> + get_ref = true;
> } else {
> virq = irq_domain_alloc_descs(irq_base, nr_irqs, 0, node,
> affinity);
> @@ -1453,8 +1466,14 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
> }
> }
>
> - for (i = 0; i < nr_irqs; i++)
> + for (i = 0; i < nr_irqs; i++) {
> irq_domain_insert_irq(virq + i);
> + if (get_ref) {
> + struct irq_desc *desc = irq_to_desc(virq + i);
> +
> + kobject_get(&desc->kobj);
> + }
> + }
> mutex_unlock(&irq_domain_mutex);
>
> return virq;
>
--
Alexey
^ permalink raw reply
* Re: [PATCH] KVM: PPC: Book3S HV: XIVE: Fix possible oops when accessing ESB page
From: Michael Ellerman @ 2020-11-06 3:19 UTC (permalink / raw)
To: Cédric Le Goater, Paul Mackerras
Cc: kvm, Gustavo Romero, Greg Kurz, kvm-ppc, Cédric Le Goater,
linuxppc-dev, David Gibson
In-Reply-To: <20201105134713.656160-1-clg@kaod.org>
Cédric Le Goater <clg@kaod.org> writes:
> When accessing the ESB page of a source interrupt, the fault handler
> will retrieve the page address from the XIVE interrupt 'xive_irq_data'
> structure. If the associated KVM XIVE interrupt is not valid, that is
> not allocated at the HW level for some reason, the fault handler will
> dereference a NULL pointer leading to the oops below :
>
> WARNING: CPU: 40 PID: 59101 at arch/powerpc/kvm/book3s_xive_native.c:259 xive_native_esb_fault+0xe4/0x240 [kvm]
> CPU: 40 PID: 59101 Comm: qemu-system-ppc Kdump: loaded Tainted: G W --------- - - 4.18.0-240.el8.ppc64le #1
> NIP: c00800000e949fac LR: c00000000044b164 CTR: c00800000e949ec8
> REGS: c000001f69617840 TRAP: 0700 Tainted: G W --------- - - (4.18.0-240.el8.ppc64le)
> MSR: 9000000000029033 <SF,HV,EE,ME,IR,DR,RI,LE> CR: 44044282 XER: 00000000
> CFAR: c00000000044b160 IRQMASK: 0
> GPR00: c00000000044b164 c000001f69617ac0 c00800000e96e000 c000001f69617c10
> GPR04: 05faa2b21e000080 0000000000000000 0000000000000005 ffffffffffffffff
> GPR08: 0000000000000000 0000000000000001 0000000000000000 0000000000000001
> GPR12: c00800000e949ec8 c000001ffffd3400 0000000000000000 0000000000000000
> GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
> GPR20: 0000000000000000 0000000000000000 c000001f5c065160 c000000001c76f90
> GPR24: c000001f06f20000 c000001f5c065100 0000000000000008 c000001f0eb98c78
> GPR28: c000001dcab40000 c000001dcab403d8 c000001f69617c10 0000000000000011
> NIP [c00800000e949fac] xive_native_esb_fault+0xe4/0x240 [kvm]
> LR [c00000000044b164] __do_fault+0x64/0x220
> Call Trace:
> [c000001f69617ac0] [0000000137a5dc20] 0x137a5dc20 (unreliable)
> [c000001f69617b50] [c00000000044b164] __do_fault+0x64/0x220
> [c000001f69617b90] [c000000000453838] do_fault+0x218/0x930
> [c000001f69617bf0] [c000000000456f50] __handle_mm_fault+0x350/0xdf0
> [c000001f69617cd0] [c000000000457b1c] handle_mm_fault+0x12c/0x310
> [c000001f69617d10] [c00000000007ef44] __do_page_fault+0x264/0xbb0
> [c000001f69617df0] [c00000000007f8c8] do_page_fault+0x38/0xd0
> [c000001f69617e30] [c00000000000a714] handle_page_fault+0x18/0x38
> Instruction dump:
> 40c2fff0 7c2004ac 2fa90000 409e0118 73e90001 41820080 e8bd0008 7c2004ac
> 7ca90074 39400000 915c0000 7929d182 <0b090000> 2fa50000 419e0080 e89e0018
> ---[ end trace 66c6ff034c53f64f ]---
> xive-kvm: xive_native_esb_fault: accessing invalid ESB page for source 8 !
>
> Fix that by checking the validity of the KVM XIVE interrupt structure.
>
> Reported-by: Greg Kurz <groug@kaod.org>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
Fixes ?
cheers
^ permalink raw reply
* [PATCH] powerpc/64s: Remove MSR[ISF] bit
From: Nicholas Piggin @ 2020-11-06 4:53 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nicholas Piggin
No supported processor implements this mode. Setting the bit in
MSR values can be a bit confusing (and would prevent the bit from
ever being reused). Remove it.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/include/asm/reg.h | 5 +----
arch/powerpc/kernel/entry_64.S | 2 +-
arch/powerpc/kernel/head_64.S | 3 +--
arch/powerpc/kvm/book3s_pr.c | 2 +-
4 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index f877a576b338..8885fbf4285b 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -29,7 +29,6 @@
#include <asm/reg_8xx.h>
#define MSR_SF_LG 63 /* Enable 64 bit mode */
-#define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */
#define MSR_HV_LG 60 /* Hypervisor state */
#define MSR_TS_T_LG 34 /* Trans Mem state: Transactional */
#define MSR_TS_S_LG 33 /* Trans Mem state: Suspended */
@@ -69,13 +68,11 @@
#ifdef CONFIG_PPC64
#define MSR_SF __MASK(MSR_SF_LG) /* Enable 64 bit mode */
-#define MSR_ISF __MASK(MSR_ISF_LG) /* Interrupt 64b mode valid on 630 */
#define MSR_HV __MASK(MSR_HV_LG) /* Hypervisor state */
#define MSR_S __MASK(MSR_S_LG) /* Secure state */
#else
/* so tests for these bits fail on 32-bit */
#define MSR_SF 0
-#define MSR_ISF 0
#define MSR_HV 0
#define MSR_S 0
#endif
@@ -134,7 +131,7 @@
#define MSR_64BIT MSR_SF
/* Server variant */
-#define __MSR (MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF |MSR_HV)
+#define __MSR (MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_HV)
#ifdef __BIG_ENDIAN__
#define MSR_ __MSR
#define MSR_IDLE (MSR_ME | MSR_SF | MSR_HV)
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2f3846192ec7..479fb58844fa 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -967,7 +967,7 @@ _GLOBAL(enter_prom)
mtsrr1 r11
rfi
#else /* CONFIG_PPC_BOOK3E */
- LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE)
+ LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_LE)
andc r11,r11,r12
mtsrr1 r11
RFI_TO_KERNEL
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 1510b2a56669..4e2591cb4bd1 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -865,8 +865,7 @@ enable_64b_mode:
oris r11,r11,0x8000 /* CM bit set, we'll set ICM later */
mtmsr r11
#else /* CONFIG_PPC_BOOK3E */
- li r12,(MSR_64BIT | MSR_ISF)@highest
- sldi r12,r12,48
+ LOAD_REG_IMMEDIATE(r12, MSR_64BIT)
or r11,r11,r12
mtmsrd r11
isync
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index b1fefa63e125..913944dc3620 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -239,7 +239,7 @@ static void kvmppc_recalc_shadow_msr(struct kvm_vcpu *vcpu)
smsr |= (guest_msr & vcpu->arch.guest_owned_ext);
/* 64-bit Process MSR values */
#ifdef CONFIG_PPC_BOOK3S_64
- smsr |= MSR_ISF | MSR_HV;
+ smsr |= MSR_HV;
#endif
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
/*
--
2.23.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox