From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 11F072E2EE0; Thu, 3 Jul 2025 10:25:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538320; cv=none; b=EYgM6To5X4VFCcU42WFL3RQd0zvsaPYfKk9ts+KhWEZaiTtHTJWTIE3x/zJ2/GtWNe/qoohiFDY6oht3ryZufKRwosnsq8YzVi72BsQIyWuDcfRR2kvVqjgG5yAexAvRrfKt8704421DfuhZlwP2ZZdO0xR2TMmucWrZLon3Z3s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538320; c=relaxed/simple; bh=72YVYlZpx1c2GB+9yCrTowRw630f+mznM7Sb9bqRu6I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=M1G6hfNCzLG9QThtbODJEy3f88ywVrbdmDA3Ijt+ESOvRE4e1OjAACBDy1RIFugCiU3NBgVDedO4zeP2hGGPBTIq5JsW7+W6k+KHpas+wgy5maIdyqdPyOxzQuGqTw0xqqWkKadazqFjEdx0qRLLl78Bh2gI0A2lTo5bDoSTeV4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jtUwGCtK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jtUwGCtK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AF534C4CEF4; Thu, 3 Jul 2025 10:25:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538318; bh=72YVYlZpx1c2GB+9yCrTowRw630f+mznM7Sb9bqRu6I=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=jtUwGCtK2hm3bveJkKS2FeIF8HldLt+UKMfrSqvM7zMRymIqYmBub7Q/WyfDCoQHE V1mmPOwh4/W4oU3S8Ed85zzSAGByhWCSYPq42TS9sK0UpoeDRjfBO3/Mz7WY5B2tpL xpUiL/ailyzWpGwW7lBMeOX3cx6nKijQUL2wC1QukmVRsf2t/k4yDUssrqwwPiLPnK knDdTxV8/UCF0Y2/IYKvRIsS/pL6Blmi1i2QQAinfvqU2IKXHDiZ6eK9SXk5uAJk2u jq4Y3uc8K9lN5NP1In0xgr4dLmjmc7NsLgOM2rrKI7E8Qwi7UJOJK4U6mfgKpM4B7Y 7W1sK6a4I4aaA== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:24:51 +0200 Subject: [PATCH v7 01/31] dt-bindings: interrupt-controller: Add Arm GICv5 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-1-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e The GICv5 interrupt controller architecture is composed of: - one or more Interrupt Routing Service (IRS) - zero or more Interrupt Translation Service (ITS) - zero or more Interrupt Wire Bridge (IWB) Describe a GICv5 implementation by specifying a top level node corresponding to the GICv5 system component. IRS nodes are added as GICv5 system component children. An ITS is associated with an IRS so ITS nodes are described as IRS children - use the hierarchy explicitly in the device tree to define the association. IWB nodes are described as a separate schema. An IWB is connected to a single ITS, the connection is made explicit through the msi-parent property and therefore is not required to be explicit through a parent-child relationship in the device tree. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Rob Herring (Arm) Reviewed-by: Marc Zyngier Cc: Conor Dooley Cc: Rob Herring Cc: Krzysztof Kozlowski Cc: Marc Zyngier --- .../interrupt-controller/arm,gic-v5-iwb.yaml | 78 ++++++ .../bindings/interrupt-controller/arm,gic-v5.yaml | 267 +++++++++++++++++= ++++ MAINTAINERS | 7 + 3 files changed, 352 insertions(+) diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic= -v5-iwb.yaml b/Documentation/devicetree/bindings/interrupt-controller/arm,g= ic-v5-iwb.yaml new file mode 100644 index 000000000000..99a266a62385 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v5-iwb= .yaml @@ -0,0 +1,78 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interrupt-controller/arm,gic-v5-iwb.yam= l# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ARM Generic Interrupt Controller, version 5 Interrupt Wire Bridge (= IWB) + +maintainers: + - Lorenzo Pieralisi + - Marc Zyngier + +description: | + The GICv5 architecture defines the guidelines to implement GICv5 + compliant interrupt controllers for AArch64 systems. + + The GICv5 specification can be found at + https://developer.arm.com/documentation/aes0070 + + GICv5 has zero or more Interrupt Wire Bridges (IWB) that are responsible + for translating wire signals into interrupt messages to the GICv5 ITS. + +allOf: + - $ref: /schemas/interrupt-controller.yaml# + +properties: + compatible: + const: arm,gic-v5-iwb + + reg: + items: + - description: IWB control frame + + "#address-cells": + const: 0 + + "#interrupt-cells": + description: | + The 1st cell corresponds to the IWB wire. + + The 2nd cell is the flags, encoded as follows: + bits[3:0] trigger type and level flags. + + 1 =3D low-to-high edge triggered + 2 =3D high-to-low edge triggered + 4 =3D active high level-sensitive + 8 =3D active low level-sensitive + + const: 2 + + interrupt-controller: true + + msi-parent: + maxItems: 1 + +required: + - compatible + - reg + - "#interrupt-cells" + - interrupt-controller + - msi-parent + +additionalProperties: false + +examples: + - | + interrupt-controller@2f000000 { + compatible =3D "arm,gic-v5-iwb"; + reg =3D <0x2f000000 0x10000>; + + #address-cells =3D <0>; + + #interrupt-cells =3D <2>; + interrupt-controller; + + msi-parent =3D <&its0 64>; + }; +... diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic= -v5.yaml b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v= 5.yaml new file mode 100644 index 000000000000..86ca7f3ac281 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v5.yaml @@ -0,0 +1,267 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interrupt-controller/arm,gic-v5.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ARM Generic Interrupt Controller, version 5 + +maintainers: + - Lorenzo Pieralisi + - Marc Zyngier + +description: | + The GICv5 architecture defines the guidelines to implement GICv5 + compliant interrupt controllers for AArch64 systems. + + The GICv5 specification can be found at + https://developer.arm.com/documentation/aes0070 + + The GICv5 architecture is composed of multiple components: + - one or more IRS (Interrupt Routing Service) + - zero or more ITS (Interrupt Translation Service) + + The architecture defines: + - PE-Private Peripheral Interrupts (PPI) + - Shared Peripheral Interrupts (SPI) + - Logical Peripheral Interrupts (LPI) + +allOf: + - $ref: /schemas/interrupt-controller.yaml# + +properties: + compatible: + const: arm,gic-v5 + + "#address-cells": + enum: [ 1, 2 ] + + "#size-cells": + enum: [ 1, 2 ] + + ranges: true + + "#interrupt-cells": + description: | + The 1st cell corresponds to the INTID.Type field in the INTID; 1 for= PPI, + 3 for SPI. LPI interrupts must not be described in the bindings since + they are allocated dynamically by the software component managing th= em. + + The 2nd cell contains the interrupt INTID.ID field. + + The 3rd cell is the flags, encoded as follows: + bits[3:0] trigger type and level flags. + + 1 =3D low-to-high edge triggered + 2 =3D high-to-low edge triggered + 4 =3D active high level-sensitive + 8 =3D active low level-sensitive + + const: 3 + + interrupt-controller: true + + interrupts: + description: + The VGIC maintenance interrupt. + maxItems: 1 + +required: + - compatible + - "#address-cells" + - "#size-cells" + - ranges + - "#interrupt-cells" + - interrupt-controller + +patternProperties: + "^irs@[0-9a-f]+$": + type: object + description: + GICv5 has one or more Interrupt Routing Services (IRS) that are + responsible for handling IRQ state and routing. + + additionalProperties: false + + properties: + compatible: + const: arm,gic-v5-irs + + reg: + minItems: 1 + items: + - description: IRS config frames + - description: IRS setlpi frames + + reg-names: + description: + Describe config and setlpi frames that are present. + "ns-" stands for non-secure, "s-" for secure, "realm-" for realm + and "el3-" for EL3. + minItems: 1 + maxItems: 8 + items: + enum: [ ns-config, s-config, realm-config, el3-config, ns-setlpi, + s-setlpi, realm-setlpi, el3-setlpi ] + + "#address-cells": + enum: [ 1, 2 ] + + "#size-cells": + enum: [ 1, 2 ] + + ranges: true + + dma-noncoherent: + description: + Present if the GIC IRS permits programming shareability and + cacheability attributes but is connected to a non-coherent + downstream interconnect. + + cpus: + description: + CPUs managed by the IRS. + + arm,iaffids: + $ref: /schemas/types.yaml#/definitions/uint16-array + description: + Interrupt AFFinity ID (IAFFID) associated with the CPU whose + CPU node phandle is at the same index in the cpus array. + + patternProperties: + "^its@[0-9a-f]+$": + type: object + description: + GICv5 has zero or more Interrupt Translation Services (ITS) that= are + used to route Message Signalled Interrupts (MSI) to the CPUs. Ea= ch + ITS is connected to an IRS. + additionalProperties: false + + properties: + compatible: + const: arm,gic-v5-its + + reg: + items: + - description: ITS config frames + + reg-names: + description: + Describe config frames that are present. + "ns-" stands for non-secure, "s-" for secure, "realm-" for r= ealm + and "el3-" for EL3. + minItems: 1 + maxItems: 4 + items: + enum: [ ns-config, s-config, realm-config, el3-config ] + + "#address-cells": + enum: [ 1, 2 ] + + "#size-cells": + enum: [ 1, 2 ] + + ranges: true + + dma-noncoherent: + description: + Present if the GIC ITS permits programming shareability and + cacheability attributes but is connected to a non-coherent + downstream interconnect. + + patternProperties: + "^msi-controller@[0-9a-f]+$": + type: object + description: + GICv5 ITS has one or more translate register frames. + additionalProperties: false + + properties: + reg: + items: + - description: ITS translate frames + + reg-names: + description: + Describe translate frames that are present. + "ns-" stands for non-secure, "s-" for secure, "realm-" f= or realm + and "el3-" for EL3. + minItems: 1 + maxItems: 4 + items: + enum: [ ns-translate, s-translate, realm-translate, el3-= translate ] + + "#msi-cells": + description: + The single msi-cell is the DeviceID of the device which = will + generate the MSI. + const: 1 + + msi-controller: true + + required: + - reg + - reg-names + - "#msi-cells" + - msi-controller + + required: + - compatible + - reg + - reg-names + + required: + - compatible + - reg + - reg-names + - cpus + - arm,iaffids + +additionalProperties: false + +examples: + - | + interrupt-controller { + compatible =3D "arm,gic-v5"; + + #interrupt-cells =3D <3>; + interrupt-controller; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges; + + interrupts =3D <1 25 4>; + + irs@2f1a0000 { + compatible =3D "arm,gic-v5-irs"; + reg =3D <0x2f1a0000 0x10000>; // IRS_CONFIG_FRAME + reg-names =3D "ns-config"; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges; + + cpus =3D <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>, <&cpu4>, <&cpu5>, <&c= pu6>, <&cpu7>; + arm,iaffids =3D /bits/ 16 <0 1 2 3 4 5 6 7>; + + its@2f120000 { + compatible =3D "arm,gic-v5-its"; + reg =3D <0x2f120000 0x10000>; // ITS_CONFIG_FRAME + reg-names =3D "ns-config"; + + #address-cells =3D <1>; + #size-cells =3D <1>; + ranges; + + msi-controller@2f130000 { + reg =3D <0x2f130000 0x10000>; // ITS_TRANSLATE_FRAME + reg-names =3D "ns-translate"; + + #msi-cells =3D <1>; + msi-controller; + }; + }; + }; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index 0c1d245bf7b8..f02a768adecb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1965,6 +1965,13 @@ F: drivers/irqchip/irq-gic*.[ch] F: include/linux/irqchip/arm-gic*.h F: include/linux/irqchip/arm-vgic-info.h =20 +ARM GENERIC INTERRUPT CONTROLLER V5 DRIVERS +M: Lorenzo Pieralisi +M: Marc Zyngier +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: Documentation/devicetree/bindings/interrupt-controller/arm,gic-v5*.yaml + ARM HDLCD DRM DRIVER M: Liviu Dudau S: Supported --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 42BEB2E2F1F; Thu, 3 Jul 2025 10:25:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538324; cv=none; b=sWGDDoaYuQWAsCneXC8W1eCZY88DcOPdRQ5OqUDuRKw7YzdA9e0F5EPy+bTwCUMhpZVDhaX7eTPdAkvJRrm9JxUP2ESWipK2Oz/6lE1Qyy6S21qE51JqiPBNROVhtNlxRBXaY2kDGPuiAaVwoj4nW49wYFIoPoeI6r3HG3Y5sgU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538324; c=relaxed/simple; bh=DVrlQl7knEfTTRJf6B4kPW+doH90DFZNcs/PwxMLaDU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Q0E7GS52LunreiOxIe4Mk59C9pQN9/vNM1t3SyjioGu2BP3IVQQpGU41kq0tiCMbfaZxnhkoUe1ZneIYQm/hpnhBQnPvfWk8yrBkirhksdLygH7EX7HkjcG2Y+27FykzYJjVIPGRbO/DI2yqMgGVANkVKBwj0STE3ydh7wd6jNw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gTC92IJd; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gTC92IJd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 30097C4CEE3; Thu, 3 Jul 2025 10:25:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538324; bh=DVrlQl7knEfTTRJf6B4kPW+doH90DFZNcs/PwxMLaDU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=gTC92IJd8oeqpHpKuv9FODRFNo+kmATOj63So9/UbUd50BFsXN5UXWpnr4lt1h9K6 +IZgSRlOs+zcdPK7JapvprVqv8xBykup/74g1CX/YmYrPyDaJYXo0GQS5rumNBqq89 jgUs+9SbBAAXuBJkA82GfOYEspn6DUgPXmUZvg+lt9tkMz2oejNSCxpQ2WwtP3NycP 57n6LgYAUrmAoVGMPeWVKzXZ+39/dYvqNc5QRv721JR1PN7ODqMdqYv/QvEIeNF8p/ P3Tw1FUV5e4fXVMk82boBq6VgOuLG/IuHu3rvpzFu1in66s5FE/FFZ23YhnSX6aAwz Is8Ne/3ZhYLDQ== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:24:52 +0200 Subject: [PATCH v7 02/31] arm64/sysreg: Add GCIE field to ID_AA64PFR2_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-2-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Add field reporting the GCIE feature to ID_AA64PFR2_EL1 sysreg. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Jonathan Cameron Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/tools/sysreg | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 8a8cf6874298..fb5bddc700b3 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -1314,7 +1314,10 @@ UnsignedEnum 19:16 UINJ 0b0000 NI 0b0001 IMP EndEnum -Res0 15:12 +UnsignedEnum 15:12 GCIE + 0b0000 NI + 0b0001 IMP +EndEnum UnsignedEnum 11:8 MTEFAR 0b0000 NI 0b0001 IMP --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 776252E2EFA; Thu, 3 Jul 2025 10:25:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538330; cv=none; b=C8y25ur5+/PJDs0/eObRYk+q1krLwJYZmR0UEvI7iri2tO9d8Ke7o7NKWMIKNWdhJu24dOf+kL+CeXvAjJpP1t+4ooGhl0W7PSzNdxSctr+KwAV5aiWJd7PnQKkK7ukW9NbTC4wC0GB2yRQRegM6xIfbN9A4DTnkgu6cOon1BK4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538330; c=relaxed/simple; bh=SKwQSXmDop1+W5LuEcccPJhwjPfPQmCGH4HXtC2wDGE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=me7lVKijn6D2dxYCnrhZt5zDjAvkxIep0sNnMeO+BQgTPDZJ2098IoQYe1gEMTRTflo+dMmyw+/fTPrJP358GDalsl+RblPxV9ByzodSF+I8Ymqe0tFV6m/tNmPxz0C00WF3Mye5oH8l9W2sFw1jkdYtjpT18AB9FeqyLwsx7lc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bVJnBC4Z; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bVJnBC4Z" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A7948C4CEE3; Thu, 3 Jul 2025 10:25:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538330; bh=SKwQSXmDop1+W5LuEcccPJhwjPfPQmCGH4HXtC2wDGE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bVJnBC4Z24MWUObHgZI3t5dYYra2r4DCTLuB1whT8ohRvrN7V/Uao2veMzaDOQRZB d9mqSPG8Voj+kmZVdsr6HoJA3N3VzS70KO4TVweGFACAtNie9ZRuMXVvsJORhDT3nh 98Y18ET7L9BR94FNymoK/Kwv1OMW/e9ys60Oe0V47x2h/m3qyk6yxHqB/KDNck989i NxBN8NMMkre8S6IoUXTn+vvV6qA34iHnYt1YqEh4LfB1L4oY7yRyXA7PUFmYy5fLNM bC4pVSCkp3ogQQIVROwRievNWnfTUceSXYLzIxihQK6ZrwLrjwlNy6oHQplLfgd169 eKLbTzVnKqAuQ== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:24:53 +0200 Subject: [PATCH v7 03/31] arm64/sysreg: Add ICC_PPI_PRIORITY_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-3-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Add ICC_PPI_PRIORITY_EL1 sysreg description. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Jonathan Cameron Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/tools/sysreg | 83 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 83 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index fb5bddc700b3..fc17e19a738d 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -3024,6 +3024,89 @@ Sysreg PMIAR_EL1 3 0 9 14 7 Field 63:0 ADDRESS EndSysreg =20 +SysregFields ICC_PPI_PRIORITYRx_EL1 +Res0 63:61 +Field 60:56 Priority7 +Res0 55:53 +Field 52:48 Priority6 +Res0 47:45 +Field 44:40 Priority5 +Res0 39:37 +Field 36:32 Priority4 +Res0 31:29 +Field 28:24 Priority3 +Res0 23:21 +Field 20:16 Priority2 +Res0 15:13 +Field 12:8 Priority1 +Res0 7:5 +Field 4:0 Priority0 +EndSysregFields + +Sysreg ICC_PPI_PRIORITYR0_EL1 3 0 12 14 0 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR1_EL1 3 0 12 14 1 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR2_EL1 3 0 12 14 2 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR3_EL1 3 0 12 14 3 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR4_EL1 3 0 12 14 4 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR5_EL1 3 0 12 14 5 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR6_EL1 3 0 12 14 6 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR7_EL1 3 0 12 14 7 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR8_EL1 3 0 12 15 0 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR9_EL1 3 0 12 15 1 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR10_EL1 3 0 12 15 2 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR11_EL1 3 0 12 15 3 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR12_EL1 3 0 12 15 4 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR13_EL1 3 0 12 15 5 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR14_EL1 3 0 12 15 6 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + +Sysreg ICC_PPI_PRIORITYR15_EL1 3 0 12 15 7 +Fields ICC_PPI_PRIORITYRx_EL1 +EndSysreg + Sysreg PMSELR_EL0 3 3 9 12 5 Res0 63:5 Field 4:0 SEL --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA3C32E3B1C; Thu, 3 Jul 2025 10:25:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538335; cv=none; b=V7DbdyyTPhb7AHCpI3wv8NKs4DIW6CByHHXxuuN2PwJQRihAeH9P+1GnsSEdb0ooD+gtMNgDrjeW2XC6n64cJZPfRS2yzPC6zyN9A4UlurmUq2SNaWDM7uRBEIozIacZmnOJo7UDvws87cypflw5TbqvHnWnURWO9LAPwFbIRaI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538335; c=relaxed/simple; bh=DjvQOe0IuB9BWqh5JZMfWtGfm4m6xEiOL889DBftjMw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BqHUxsxZ3R40H8WbhKKIK2d8skzpG4wA1pVQJhbOvRbJzIXmiAJEPqWiTLKUm4sW6+36FgBZCrYprTnvq/wzsb92ggJw9mxZJ1/vuGPBlkeDJ+74OiCCiBUxc+CqgCNIWdS/o3x+Qu/MgDjMlcMqSFpi41A1WnnOfHTE30QPSng= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kXsvXERs; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kXsvXERs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 90AB7C4CEEB; Thu, 3 Jul 2025 10:25:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538335; bh=DjvQOe0IuB9BWqh5JZMfWtGfm4m6xEiOL889DBftjMw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=kXsvXERs35/+SYMmy3/J/jl+/PHj/jWG4yNUeiLDqLdcYA+zH5bCX6zsoA1AJGBlF C+7QmP6bf7taYVWQ35vBIliIB2eCLa9FX2q5gFmoMBcQtm19WxzzZZrqyha0xoP+hx DgU8zFqf8uiSEc6EBlwuenPAI5X5nYIeh24meT/NKAGJAa7b9TC/aT8qLR/5pmvAJC r3kO/2KX0n0uzbqqbk9FqgRW2NIzGVZcX9nYLzGPZ34rVpzcETqNMX5jIsRUxUGuQi AWEGN4oV3Kro1GDJbJiuZ+5l1Io3pvrkhkDgF4JOwxpq1sC9UCdj1EDjQ4D/xENofU Z7pQZz/EClcgQ== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:24:54 +0200 Subject: [PATCH v7 04/31] arm64/sysreg: Add ICC_ICSR_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-4-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Add ICC_ICSR_EL1 register sysreg description. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Jonathan Cameron Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/tools/sysreg | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index fc17e19a738d..81b32f567ce3 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -3024,6 +3024,20 @@ Sysreg PMIAR_EL1 3 0 9 14 7 Field 63:0 ADDRESS EndSysreg =20 +Sysreg ICC_ICSR_EL1 3 0 12 10 4 +Res0 63:48 +Field 47:32 IAFFID +Res0 31:16 +Field 15:11 Priority +Res0 10:6 +Field 5 HM +Field 4 Active +Field 3 IRM +Field 2 Pending +Field 1 Enabled +Field 0 F +EndSysreg + SysregFields ICC_PPI_PRIORITYRx_EL1 Res0 63:61 Field 60:56 Priority7 --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4A5EF2E2EEC; Thu, 3 Jul 2025 10:25:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538341; cv=none; b=TpZSPPI+hWvarzX5+I6uuQr5/gfcew0FN6mxdDWA49gp++FSdKhesHfLObQkYNZoew7cvOGvT00VMfR6atcnTWEivEDHkcT3XVyYR5HOmo15PDGBemSgEbEy4OhQVD9fpQOugLPabSNCvKTfluKsoa7CzXN4vnzdz+GXsWFLvoY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538341; c=relaxed/simple; bh=cHsJXMhOTfVZkuFAf0l6aQWEcs6MpJ4efXvwjlVJcKE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PjHOCyuotyVc7vvtVOLaPNLy5j/izQy/WwfQ3LuUHhcLg2nFJm8s/by6epb4/ykOd8xTFkEoRJx2b19MO+9b2LDVqPeGph91vgkRRLxh/NZPVWXHYDGMk8TxxIHb2zD6l1SUN/1cS/ytccfqZ1nGcPTkhq/S3DXG9wdDLxitPlY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=G0amZSU1; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="G0amZSU1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DFD56C4CEE3; Thu, 3 Jul 2025 10:25:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538340; bh=cHsJXMhOTfVZkuFAf0l6aQWEcs6MpJ4efXvwjlVJcKE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=G0amZSU1a8GM156F9LfGG6AaTBkba7mVaz29G51OO7jsNQhASyT0AsvU7daQzZBpd RyOF3P2EBD7mdgNQcgDHKSqjczJxkjUZTnkiNrOOW5hT1JXilIrIgQnfSGpVxeqzbT Gdwe6XNv8mj/YYYEkPN38UouE7RhxH2dJuOi6rGF1k0hJGNDnDYVKfRRHAhfr7WUEj Ry5OlupBmLccs0Wrj3mpO97VPobvmpDoLRDocmu7wYzy6E5ihNmZ9iiXIPNlEld8qw fvLFEwNcXSosyuznoY8bbe6tq2dE4XFGSvI6xBIGbGWqmIg4FRgSRwHr/PHuDZR+7m NCEXAevuoCdyg== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:24:55 +0200 Subject: [PATCH v7 05/31] arm64/sysreg: Add ICC_PPI_HMR_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-5-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Add ICC_PPI_HMR_EL1 registers sysreg description. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Jonathan Cameron Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/tools/sysreg | 75 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 75 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 81b32f567ce3..7f096efee4e7 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -3024,6 +3024,81 @@ Sysreg PMIAR_EL1 3 0 9 14 7 Field 63:0 ADDRESS EndSysreg =20 +SysregFields ICC_PPI_HMRx_EL1 +Field 63 HM63 +Field 62 HM62 +Field 61 HM61 +Field 60 HM60 +Field 59 HM59 +Field 58 HM58 +Field 57 HM57 +Field 56 HM56 +Field 55 HM55 +Field 54 HM54 +Field 53 HM53 +Field 52 HM52 +Field 51 HM51 +Field 50 HM50 +Field 49 HM49 +Field 48 HM48 +Field 47 HM47 +Field 46 HM46 +Field 45 HM45 +Field 44 HM44 +Field 43 HM43 +Field 42 HM42 +Field 41 HM41 +Field 40 HM40 +Field 39 HM39 +Field 38 HM38 +Field 37 HM37 +Field 36 HM36 +Field 35 HM35 +Field 34 HM34 +Field 33 HM33 +Field 32 HM32 +Field 31 HM31 +Field 30 HM30 +Field 29 HM29 +Field 28 HM28 +Field 27 HM27 +Field 26 HM26 +Field 25 HM25 +Field 24 HM24 +Field 23 HM23 +Field 22 HM22 +Field 21 HM21 +Field 20 HM20 +Field 19 HM19 +Field 18 HM18 +Field 17 HM17 +Field 16 HM16 +Field 15 HM15 +Field 14 HM14 +Field 13 HM13 +Field 12 HM12 +Field 11 HM11 +Field 10 HM10 +Field 9 HM9 +Field 8 HM8 +Field 7 HM7 +Field 6 HM6 +Field 5 HM5 +Field 4 HM4 +Field 3 HM3 +Field 2 HM2 +Field 1 HM1 +Field 0 HM0 +EndSysregFields + +Sysreg ICC_PPI_HMR0_EL1 3 0 12 10 0 +Fields ICC_PPI_HMRx_EL1 +EndSysreg + +Sysreg ICC_PPI_HMR1_EL1 3 0 12 10 1 +Fields ICC_PPI_HMRx_EL1 +EndSysreg + Sysreg ICC_ICSR_EL1 3 0 12 10 4 Res0 63:48 Field 47:32 IAFFID --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 359BE2E266F; Thu, 3 Jul 2025 10:25:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538346; cv=none; b=P/CcgsPUQopIcFcFxtKeCsIGfGuPF1Vfvq3XVoclO7HZJEXvcfQeDlWOQc60AFE2H5inDrKwBle411q7cXayfla7xgiRsfi1S/E4o9FUEohSC+UnurvmbjypPCSgkYMBuBqNGOZM3uelQEchKL/kHn3pJ1xZJzJqj3DxTdj6t9Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538346; c=relaxed/simple; bh=/5pTQlFDwkcDP+4q0vsmn4mNnCN/05UK6icxF1PfAdQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CbqXfoTidrQ6acF32lhr4MxU8elVuv1Y6KGTP5vhHy+zcjse3SQsiA8wVDSuMFjNs80vDdsM5lJecrJb2/uj1ttZJcUHkYZioxv2Y4xVvvYe8qlyaNTlCPEy36yHFMsgv81rZUMan8XT5MA0Ar1xVlDlcSJKviXL1f3sgEtof7A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=q/Y7t5A2; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="q/Y7t5A2" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 45F27C4CEF2; Thu, 3 Jul 2025 10:25:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538346; bh=/5pTQlFDwkcDP+4q0vsmn4mNnCN/05UK6icxF1PfAdQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=q/Y7t5A2jqca9IR4g0MdONVKeOFOcYIzo4u1kh/d7a+ExKr50tgeI4VPy4zh77fBc f9NCqDMBd2DHSsTBTSBdF7eTYPbf++zQf9L8+C3VNAg40XVjfiW1/qGPbRSWaZdzp1 HrnbWCBRqmE384Dan0Y4wsk4y/3rkzaO425KzHAqOvkjbjPP+5w0tlfovM7D5Pqtue dqk/AaSXMNvaTq5jAFUa3+QSsHOQEoWVKbse2io9U2oOIgMHZSbhrslp7csEf3AJ30 O5QlWv8io9A/kNYvxP5EgExXFXapZGWkWT4t+nIPgq9kvjzdA69Pri0JMeiZttImbO 2x2WFgjOJpWBA== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:24:56 +0200 Subject: [PATCH v7 06/31] arm64/sysreg: Add ICC_PPI_ENABLER_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-6-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Add ICC_PPI_ENABLER_EL1 registers sysreg description. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Jonathan Cameron Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/tools/sysreg | 75 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 75 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 7f096efee4e7..728223df482d 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -3113,6 +3113,81 @@ Field 1 Enabled Field 0 F EndSysreg =20 +SysregFields ICC_PPI_ENABLERx_EL1 +Field 63 EN63 +Field 62 EN62 +Field 61 EN61 +Field 60 EN60 +Field 59 EN59 +Field 58 EN58 +Field 57 EN57 +Field 56 EN56 +Field 55 EN55 +Field 54 EN54 +Field 53 EN53 +Field 52 EN52 +Field 51 EN51 +Field 50 EN50 +Field 49 EN49 +Field 48 EN48 +Field 47 EN47 +Field 46 EN46 +Field 45 EN45 +Field 44 EN44 +Field 43 EN43 +Field 42 EN42 +Field 41 EN41 +Field 40 EN40 +Field 39 EN39 +Field 38 EN38 +Field 37 EN37 +Field 36 EN36 +Field 35 EN35 +Field 34 EN34 +Field 33 EN33 +Field 32 EN32 +Field 31 EN31 +Field 30 EN30 +Field 29 EN29 +Field 28 EN28 +Field 27 EN27 +Field 26 EN26 +Field 25 EN25 +Field 24 EN24 +Field 23 EN23 +Field 22 EN22 +Field 21 EN21 +Field 20 EN20 +Field 19 EN19 +Field 18 EN18 +Field 17 EN17 +Field 16 EN16 +Field 15 EN15 +Field 14 EN14 +Field 13 EN13 +Field 12 EN12 +Field 11 EN11 +Field 10 EN10 +Field 9 EN9 +Field 8 EN8 +Field 7 EN7 +Field 6 EN6 +Field 5 EN5 +Field 4 EN4 +Field 3 EN3 +Field 2 EN2 +Field 1 EN1 +Field 0 EN0 +EndSysregFields + +Sysreg ICC_PPI_ENABLER0_EL1 3 0 12 10 6 +Fields ICC_PPI_ENABLERx_EL1 +EndSysreg + +Sysreg ICC_PPI_ENABLER1_EL1 3 0 12 10 7 +Fields ICC_PPI_ENABLERx_EL1 +EndSysreg + SysregFields ICC_PPI_PRIORITYRx_EL1 Res0 63:61 Field 60:56 Priority7 --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D3A102E337E; Thu, 3 Jul 2025 10:25:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538351; cv=none; b=iIsJaOm5jFbdRwI2CIKawCpW6Nr5Z82r5nHw5nv1KMD6TLlst2Hu0kOWofjjM3JLHrVXBb8hGtsimeBteInCXrWEaJgF+T6AmBX6ufsUjZzZYnPgzeDe3EfIFeCA7MIjIZGCmg/CTPUyatf6GOvYRCUDrR9Na3coaA/mbrkdC+4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538351; c=relaxed/simple; bh=chydQxXcGR8/rPWKQhdfhuVdKgKCKmATlQG6keW9CpI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dYIbE9UvSEOuLTRltyiXDlvHsD/pYw3HY5P8cVu6P8qgXohhid0vEGWXT92fUGgVrf2cLREk72ECZCI/0uCe/rUQfLIYs3sfzt2y7LZ6rkEAUsYxXrpV0HxGJb34ZnDuf8c3Xcme3mZgwpMe5Q6RpgPvESD28xKhetSHgtSvbIc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Zgs424TN; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Zgs424TN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 910FBC4CEE3; Thu, 3 Jul 2025 10:25:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538351; bh=chydQxXcGR8/rPWKQhdfhuVdKgKCKmATlQG6keW9CpI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Zgs424TNZImaYIXJxO59cIEt8frm3mtcn4jc3rus1qqT/r5E748rvuZJdO1Isxybs fByDxSeRWLeYBiZzQKssUqAtJIVCp2M4VbL6xEd0/NlBlV8phfQ/+o5jjAws5G81ct NH8Z+cVpDVsGexOwOkY7NX67+z5MkAuyTJHAPJph8GAo/aTrKVoWmAcPlmAI+w4YYT /gkZ2jGgx7vitU/aj8a+u61LEeWJa6EXIjm+Zq2erpQKczW7u+pPGFJnIqLowWb61i y54Z6Lp8Jfj8Nlmw7NSu4MGAEN+sznUprgLFGFjLi9JJ5KPx81otbhjDL1geLpSwMh FNiqyibHij9rg== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:24:57 +0200 Subject: [PATCH v7 07/31] arm64/sysreg: Add ICC_PPI_{C/S}ACTIVER_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-7-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Add ICC_PPI_{C/S}ACTIVER_EL1 registers description. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Jonathan Cameron Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/tools/sysreg | 83 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 83 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 728223df482d..f1650034e348 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -3188,6 +3188,89 @@ Sysreg ICC_PPI_ENABLER1_EL1 3 0 12 10 7 Fields ICC_PPI_ENABLERx_EL1 EndSysreg =20 +SysregFields ICC_PPI_ACTIVERx_EL1 +Field 63 Active63 +Field 62 Active62 +Field 61 Active61 +Field 60 Active60 +Field 59 Active59 +Field 58 Active58 +Field 57 Active57 +Field 56 Active56 +Field 55 Active55 +Field 54 Active54 +Field 53 Active53 +Field 52 Active52 +Field 51 Active51 +Field 50 Active50 +Field 49 Active49 +Field 48 Active48 +Field 47 Active47 +Field 46 Active46 +Field 45 Active45 +Field 44 Active44 +Field 43 Active43 +Field 42 Active42 +Field 41 Active41 +Field 40 Active40 +Field 39 Active39 +Field 38 Active38 +Field 37 Active37 +Field 36 Active36 +Field 35 Active35 +Field 34 Active34 +Field 33 Active33 +Field 32 Active32 +Field 31 Active31 +Field 30 Active30 +Field 29 Active29 +Field 28 Active28 +Field 27 Active27 +Field 26 Active26 +Field 25 Active25 +Field 24 Active24 +Field 23 Active23 +Field 22 Active22 +Field 21 Active21 +Field 20 Active20 +Field 19 Active19 +Field 18 Active18 +Field 17 Active17 +Field 16 Active16 +Field 15 Active15 +Field 14 Active14 +Field 13 Active13 +Field 12 Active12 +Field 11 Active11 +Field 10 Active10 +Field 9 Active9 +Field 8 Active8 +Field 7 Active7 +Field 6 Active6 +Field 5 Active5 +Field 4 Active4 +Field 3 Active3 +Field 2 Active2 +Field 1 Active1 +Field 0 Active0 +EndSysregFields + +Sysreg ICC_PPI_CACTIVER0_EL1 3 0 12 13 0 +Fields ICC_PPI_ACTIVERx_EL1 +EndSysreg + +Sysreg ICC_PPI_CACTIVER1_EL1 3 0 12 13 1 +Fields ICC_PPI_ACTIVERx_EL1 +EndSysreg + +Sysreg ICC_PPI_SACTIVER0_EL1 3 0 12 13 2 +Fields ICC_PPI_ACTIVERx_EL1 +EndSysreg + +Sysreg ICC_PPI_SACTIVER1_EL1 3 0 12 13 3 +Fields ICC_PPI_ACTIVERx_EL1 +EndSysreg + SysregFields ICC_PPI_PRIORITYRx_EL1 Res0 63:61 Field 60:56 Priority7 --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 145482E337E; Thu, 3 Jul 2025 10:25:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538357; cv=none; b=USqCcn8qwFYHwAjwQt/1nE/eVKvsyzH80RxI6eyP+ZmPfOBh5JVkTeib2RVGZ8LuAI0PbRbQCiK2g/UW3fZubXrRPbJlvfhQYrC+3r9Rn+CLrilyq7jxlTx6YzOo5GkH9oJel9+LEcieW+KL79zLzOl0pT5ZXNPV6QbSluKLft0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538357; c=relaxed/simple; bh=k0GoQ2NGfAMMIU1lVW2V4PQGiGiFH+CwZGL10BHe130=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KzGyvDzu4C5ag2WEgnM+E/008ovC85GI1lqPaSq6f9FE2YrS7fgvJpZUaeSxCx0HMEuHMY6WMRKeY+Sj/UuhrrW9XtFYBq4gs8o2JXh9gOj48BTm4hZKwJ+P/FhZK84HrNXG8FoGjmwd7l4iVFshkm0pjibov8WvreQ47vO2Uz0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UNbE5QLE; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UNbE5QLE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D9621C4CEEB; Thu, 3 Jul 2025 10:25:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538356; bh=k0GoQ2NGfAMMIU1lVW2V4PQGiGiFH+CwZGL10BHe130=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=UNbE5QLEtrXdP2sOxCP76deq2RD55Utw2zWU8Gl3ovbFNyPF2oynM5JUqVG56gu/Q t1wmxXLJH11lzCMPyKnD4AvpfW+VIZFOTbyO1cJ8uHVbV+Ia56Ehsz6v+KCcZRRE6i zBH0oiyku4ln7omP97MWBNLaz/8FcHf9oqoAHxfgUZO7uC0UVQlaepzyZe8mNIaCu7 Z+H6PUnQTlFsqUpbt+FLiYIRvwvWeeF3CIlh35Q/+xbG+CFeUHadcnUBSDBG9EdT2A gQwA9Fhf5YegptKwBOEmqs9U8EUaHnLZnnINOj3gJ2GbTDhyjo4Pnw2dnx2zvdubzX 3awxGow1Hj7ig== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:24:58 +0200 Subject: [PATCH v7 08/31] arm64/sysreg: Add ICC_PPI_{C/S}PENDR_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-8-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Add ICC_PPI_{C/S}PENDR_EL1 registers description. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Jonathan Cameron Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/tools/sysreg | 83 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 83 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index f1650034e348..78a51fbf3a99 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -3271,6 +3271,89 @@ Sysreg ICC_PPI_SACTIVER1_EL1 3 0 12 13 3 Fields ICC_PPI_ACTIVERx_EL1 EndSysreg =20 +SysregFields ICC_PPI_PENDRx_EL1 +Field 63 Pend63 +Field 62 Pend62 +Field 61 Pend61 +Field 60 Pend60 +Field 59 Pend59 +Field 58 Pend58 +Field 57 Pend57 +Field 56 Pend56 +Field 55 Pend55 +Field 54 Pend54 +Field 53 Pend53 +Field 52 Pend52 +Field 51 Pend51 +Field 50 Pend50 +Field 49 Pend49 +Field 48 Pend48 +Field 47 Pend47 +Field 46 Pend46 +Field 45 Pend45 +Field 44 Pend44 +Field 43 Pend43 +Field 42 Pend42 +Field 41 Pend41 +Field 40 Pend40 +Field 39 Pend39 +Field 38 Pend38 +Field 37 Pend37 +Field 36 Pend36 +Field 35 Pend35 +Field 34 Pend34 +Field 33 Pend33 +Field 32 Pend32 +Field 31 Pend31 +Field 30 Pend30 +Field 29 Pend29 +Field 28 Pend28 +Field 27 Pend27 +Field 26 Pend26 +Field 25 Pend25 +Field 24 Pend24 +Field 23 Pend23 +Field 22 Pend22 +Field 21 Pend21 +Field 20 Pend20 +Field 19 Pend19 +Field 18 Pend18 +Field 17 Pend17 +Field 16 Pend16 +Field 15 Pend15 +Field 14 Pend14 +Field 13 Pend13 +Field 12 Pend12 +Field 11 Pend11 +Field 10 Pend10 +Field 9 Pend9 +Field 8 Pend8 +Field 7 Pend7 +Field 6 Pend6 +Field 5 Pend5 +Field 4 Pend4 +Field 3 Pend3 +Field 2 Pend2 +Field 1 Pend1 +Field 0 Pend0 +EndSysregFields + +Sysreg ICC_PPI_CPENDR0_EL1 3 0 12 13 4 +Fields ICC_PPI_PENDRx_EL1 +EndSysreg + +Sysreg ICC_PPI_CPENDR1_EL1 3 0 12 13 5 +Fields ICC_PPI_PENDRx_EL1 +EndSysreg + +Sysreg ICC_PPI_SPENDR0_EL1 3 0 12 13 6 +Fields ICC_PPI_PENDRx_EL1 +EndSysreg + +Sysreg ICC_PPI_SPENDR1_EL1 3 0 12 13 7 +Fields ICC_PPI_PENDRx_EL1 +EndSysreg + SysregFields ICC_PPI_PRIORITYRx_EL1 Res0 63:61 Field 60:56 Priority7 --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CFEB92E3AE1; Thu, 3 Jul 2025 10:26:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538362; cv=none; b=NUXwIm7gN9SORmKUlOvcavahtX7WTrnC/RZAeUI4xUO9us/QH7zrkHbol40mp5/dPd2nWhrR9d+aepkaFQBd3Q9nblDV9aVW2PpYoP1qBhM+Zl3Sy9VJDydwG3bYy9txCwkIdq17vv9TnEfpduPp3xpUPcnegMVnNfdGjLL0B9c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538362; c=relaxed/simple; bh=snToJzWBwiqETy97af5AraNsbwKzWEb8CWlj1NZAE/Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=g/9aQM5MzfK+20hVki/wTuHuwy6JIpWoYOxIjJbUGpy/h1HkcFHC5vPO7kWDP0o7FFi0qBq+b/mutZ/Iwco8ZYpRFalZIGc9qZpaGY+6PnW1yLI01WDaLbu4qte0jXnHStY+Jl5+p7fTvT96w92QGB1QYB2CyHXIbmhvImQyIys= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CPSdufoo; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="CPSdufoo" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2B51BC4CEE3; Thu, 3 Jul 2025 10:25:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538362; bh=snToJzWBwiqETy97af5AraNsbwKzWEb8CWlj1NZAE/Q=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=CPSdufooijXPxj+sZpjO1Uil8oQYybqMJbePojr2rdcDe4QCrcNTQCtadUI8kw563 wCL7QxFtuV+1+YNbspnIrunssDUZcdFH4kfDd0srBLPoOTyjStaUzhwkqE5bzrc9GQ iHjc4jUuCk0C2zUClMqmtW5grZZE2I+T+6zh7s+F39CIEpaX59L59vu0DoxPAkyyUO 0pFEYMCzwDbAXTisLNTxwR/1a598AlaulURXrs7HTcg2QSFVJh4m0ietkgcVW7hmFe crSXB4XU4fUQhOw/mqVtbP9c/hTxADuIdwhwZCJXYiaCIqND/zdomjtlv30Wr5hE1W SMTi1JtGmBQ6g== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:24:59 +0200 Subject: [PATCH v7 09/31] arm64/sysreg: Add ICC_CR0_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-9-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Add ICC_CR0_EL1 register description. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Jonathan Cameron Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/tools/sysreg | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 78a51fbf3a99..ebbb22ed2301 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -3519,6 +3519,14 @@ Res0 14:12 Field 11:0 AFFINITY EndSysreg =20 +Sysreg ICC_CR0_EL1 3 1 12 0 1 +Res0 63:39 +Field 38 PID +Field 37:32 IPPT +Res0 31:1 +Field 0 EN +EndSysreg + Sysreg CSSELR_EL1 3 2 0 0 0 Res0 63:5 Field 4 TnD --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 929C82E2EF2; Thu, 3 Jul 2025 10:26:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538368; cv=none; b=mhM9Wt1reK06X5gk+ffreMOQE6CQq6N3b4F3q/D0blauIiV1F8X/s3FlVm2jtlGGtJJ19L5B4t4lc6RuFTO2a5yMKyGAQ2RVdTi/TSkyDy+aB0+lCW5FWSWuo7bi6jysFzoxoL09QzEbSAdEYo0thcDyAdmkSvcv5Bqei1Q2unI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538368; c=relaxed/simple; bh=CIcuhWndkg/N6GP+iqDrY1EvwebsVCnM40vCoSLVIvw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Bu5gSf1fG+cC8hoCbdcLH+XiWhllLxx8s+7MIAL38N95NQCuFoqA+gLjx8ovE7yZ7/ZZTct7hottpndseAgKFycOdInTGiHNpN0krDfKeiZSw0HrtIhkJuPDWxm5nIQK3bfbgVHXmUMUcB+N7r0/7sc2Y3NT36J315ibzZJhMdU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fXW/2FpV; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fXW/2FpV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3ECAAC4CEEB; Thu, 3 Jul 2025 10:26:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538368; bh=CIcuhWndkg/N6GP+iqDrY1EvwebsVCnM40vCoSLVIvw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=fXW/2FpVlzK1JWbOg2223uqHGL9joO0Qus9O8hSnu2GRmcbn7E/L13Qy9ly1MYKYh h/+9LZ0TXzcRWqyAp36U8Vg4E8QYNUIArqHqH/dtJ3kksmDjRenpl93TTaXTLieOZy gcGlZrVaypUOEDV3bGHZzrLYtl9lsXSHZNT5q3i96mJC1/IGHVkAGosPFaVQvSySXg UjFqTTUBAavH8EgpHZbZvXfy2JwfMOr/QvQisn7XkNEw71sYbFPo9kX0Z82hYeXADU Jvs75tYfbiUTn+EmjjVxmpql3Vxlr/6sCnHowqvzBQDyUtYNlEo51SoWgv2q1a+8AS cSpd2tz0MNNqw== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:00 +0200 Subject: [PATCH v7 10/31] arm64/sysreg: Add ICC_PCR_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-10-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Add ICC_PCR_EL1 register description. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Jonathan Cameron Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/tools/sysreg | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index ebbb22ed2301..5e15d69093d1 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -3527,6 +3527,11 @@ Res0 31:1 Field 0 EN EndSysreg =20 +Sysreg ICC_PCR_EL1 3 1 12 0 2 +Res0 63:5 +Field 4:0 PRIORITY +EndSysreg + Sysreg CSSELR_EL1 3 2 0 0 0 Res0 63:5 Field 4 TnD --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 174002E3B0F; Thu, 3 Jul 2025 10:26:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538374; cv=none; b=fImDLjouaCGBJTRQ6W21oGR6peNdEcCvOWAn7mTYkmiIhwQCqKsDq0bYxQQ68UpSTKF0CFUSEyd19+NGyW4R2DBBQxUJxnnydVsP+6UjopzgvfI5Mq29CBnRtkzYWzhs9eMfwEUhguQVnJaEd5Er5eXDNagHgTiVF7xdXdaN1jY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538374; c=relaxed/simple; bh=/82ivTsRA55xhUgW2LKCgvpDtOBuwYdW85vqedy3eUo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=aJEODxbPB1yJM4g4hIiUOKG9BSE0IWDiDEZLimuUl/1F/a3BCJUJrpsLPES84CFzUjbEAGLgJYhKbpRWT8y3XXBlULlGNU8c/mwW/6aF7T8pd1K5mxOZfGiUijlGgq0ndK9G15S66fSwJu3tnnRSYBdUeOQpvoJjV4/W/Ehrqpk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=X4ExUXSO; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="X4ExUXSO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A6A4CC4CEE3; Thu, 3 Jul 2025 10:26:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538373; bh=/82ivTsRA55xhUgW2LKCgvpDtOBuwYdW85vqedy3eUo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=X4ExUXSOh+wJgn/x9yOt3tbYw871EnnN6adcIoKUPieh2d3wLGy89D0HET70TrlfO H6NLmuAJl6KiMwsiVsvs1x16jE3WLrO4Pfl+ndom63AMPwYtPBtMk1k6r5gu6j+Ycv 3FOplmOFJRAWnAfCT6ksJsrIM5/02riBYVf0C0wkqfbiGo55dI+2KPqSPe2b8pflHH NNvxuh17EU6VCpaTy5f+ZM4l/hJ1Y6GbQl13m/pnYK79yhZ6e0JkFV9Y3E0tGXIACY s/vUzFBmlmqqFvrFnwf56z+os/QLL2Mf3a+Y9mkihhsAX1X8/P+K74fzZI2JR9V9DL lDNeZU0fpJKgA== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:01 +0200 Subject: [PATCH v7 11/31] arm64/sysreg: Add ICC_IDR0_EL1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-11-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Add ICC_IDR0_EL1 register description. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Jonathan Cameron Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/tools/sysreg | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 5e15d69093d1..8be5e4af4ad6 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -3099,6 +3099,22 @@ Sysreg ICC_PPI_HMR1_EL1 3 0 12 10 1 Fields ICC_PPI_HMRx_EL1 EndSysreg =20 +Sysreg ICC_IDR0_EL1 3 0 12 10 2 +Res0 63:12 +UnsignedEnum 11:8 GCIE_LEGACY + 0b0000 NI + 0b0001 IMP +EndEnum +UnsignedEnum 7:4 PRI_BITS + 0b0011 4BITS + 0b0100 5BITS +EndEnum +UnsignedEnum 3:0 ID_BITS + 0b0000 16BITS + 0b0001 24BITS +EndEnum +EndSysreg + Sysreg ICC_ICSR_EL1 3 0 12 10 4 Res0 63:48 Field 47:32 IAFFID --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 374BF2E3B12; Thu, 3 Jul 2025 10:26:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538380; cv=none; b=LDDX7sxY/5/gDHJRmkagBWSxXI0WbO9qWpP+/G6t0A5z7bzL/4YrH2bMd33vBxKhBmleHqs3m1PB9L3qKz/yeRb5Tdd3+I/LD7ILW4s6yWIYNoyeyfvX0KGp/TAHEckkeI1+ikQvX/eCJH/v5HoHXePTI/ot3Urws7XyucIp31E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538380; c=relaxed/simple; bh=5Ub3u81eGIQRAdBkAtaKfQGXjVbPb4ZZ4unaU8IL8fw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bU/ejPurvvqTPYknsDS9w/edh9a2vrnPNq+Vm/bAT5oQApJLmdy7W/3dU6G//PonUxIL8G2oaH7B0WrSBCycXOaneCTmu838dI9VyrIU6ZtAeyMbZFoj+8sRtYaTopq9BpFr83thUuYszo+jsgcM/j6NmMQbuoYog6drwtuobVQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XahIgNOI; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="XahIgNOI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1A11FC4CEF2; Thu, 3 Jul 2025 10:26:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538379; bh=5Ub3u81eGIQRAdBkAtaKfQGXjVbPb4ZZ4unaU8IL8fw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=XahIgNOIwGD4FfXM7oJH6nn3cZHPbtKUCwru4dXvSm0GketQOfmMenK/vKGQMo0u9 eYmtOGTXoCwzwcdFbMXDAnuc9gWD3QR8HZFkBkn38F7g2P0+/Xu2VzqGt+cj6pHCpY 9ryZA+GRJFSe7+dzEWDFHl4r3HTuf7dLdH4MZmcn6kjw8a6jq2Rcqha9xjs/EYYHCD 5DY5OfGiCifiYRG6k2Db4JAid8ylxHhnXGBc369EXgKxhRI6AiK66txjZMhDG+eExr I89qDSIGiIWvCZwRgwHHOKGt988eujXvL7hIo2Y0ces7NryjGPbCjf8DjIpWUD0zkJ zh/6gbPWB5vrA== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:02 +0200 Subject: [PATCH v7 12/31] arm64/sysreg: Add ICH_HFGRTR_EL2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-12-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Add ICH_HFGRTR_EL2 register description. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Jonathan Cameron Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/tools/sysreg | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 8be5e4af4ad6..0202b3bd3dda 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -4434,6 +4434,24 @@ Field 31:16 PhyPARTID29 Field 15:0 PhyPARTID28 EndSysreg =20 +Sysreg ICH_HFGRTR_EL2 3 4 12 9 4 +Res0 63:21 +Field 20 ICC_PPI_ACTIVERn_EL1 +Field 19 ICC_PPI_PRIORITYRn_EL1 +Field 18 ICC_PPI_PENDRn_EL1 +Field 17 ICC_PPI_ENABLERn_EL1 +Field 16 ICC_PPI_HMRn_EL1 +Res0 15:8 +Field 7 ICC_IAFFIDR_EL1 +Field 6 ICC_ICSR_EL1 +Field 5 ICC_PCR_EL1 +Field 4 ICC_HPPIR_EL1 +Field 3 ICC_HAPR_EL1 +Field 2 ICC_CR0_EL1 +Field 1 ICC_IDRn_EL1 +Field 0 ICC_APR_EL1 +EndSysreg + Sysreg ICH_HCR_EL2 3 4 12 11 0 Res0 63:32 Field 31:27 EOIcount --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B43612E424D; Thu, 3 Jul 2025 10:26:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538385; cv=none; b=AFgri/fRSbZYTKvA1vxmbjVW/J42JyOgPfMuGRJfSVfexbxgV+j5mL1DdnpMlyD6nUKfIVJQfdYZfov60xEwPDWBsbHdieofTRnyWYhD9uEgXWQP2cCu0N8dRu7pxHo7OxLcEAfsUl0am/faNPr8BzSap48QQyIvDfFJz8T1PIU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538385; c=relaxed/simple; bh=UE4nEEMoVD3v/SaKmpCCe4YLHuNFyOzbWblW9VqVH1s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=D8A2Ya+ScN4T1QHcbCYHXNWk9kwVZXkGPC459NmV2plJAxwymZ/Z9HTzp5/rioLy3s88GDo+07WRJWqzTeZ6eAI5Jy7GGDsp2oYdK3Zu2YVUq7gOMYttkHnnYI9ck0MK361yQUcWONEnDEzYjllapsydVxgH9QTa44GqfZ9tLiU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cp0aMRMn; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cp0aMRMn" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 24199C4CEE3; Thu, 3 Jul 2025 10:26:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538385; bh=UE4nEEMoVD3v/SaKmpCCe4YLHuNFyOzbWblW9VqVH1s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cp0aMRMn7sx5hbAcfZjcgwh8aowL56Zl/ckK1KlpLaLeel3CaE9dodywSVW+e3dMk usR0hpUzgMDAUNWpLOL/QD8AddrWE3eSMjifR1N9xZ5c6iDPQbU3V311ySDs+STz7j TCIi5w0379cGYHqO+SlxbUAYWuAwzKIb5cCVxrLXaZsC1UTCMvOgg6RPVOOFoL+8un EBOQBg2yVPNo4AXj23WgrnXT2+16yxfHg4YpVHqGtIKPpeC1XrCbg4CjhxJDA1L0Rr MU/NPacBBJwPlTQGAbKdD2tn/cYUOIqRjZXMd/PM+eeIH1Q6jQ22oLRC/caQK/tPmL WtQvNZLOm49gg== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:03 +0200 Subject: [PATCH v7 13/31] arm64/sysreg: Add ICH_HFGWTR_EL2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-13-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Add ICH_HFGWTR_EL2 register description to sysreg. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Jonathan Cameron Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/tools/sysreg | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 0202b3bd3dda..9def240582dc 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -4452,6 +4452,21 @@ Field 1 ICC_IDRn_EL1 Field 0 ICC_APR_EL1 EndSysreg =20 +Sysreg ICH_HFGWTR_EL2 3 4 12 9 6 +Res0 63:21 +Field 20 ICC_PPI_ACTIVERn_EL1 +Field 19 ICC_PPI_PRIORITYRn_EL1 +Field 18 ICC_PPI_PENDRn_EL1 +Field 17 ICC_PPI_ENABLERn_EL1 +Res0 16:7 +Field 6 ICC_ICSR_EL1 +Field 5 ICC_PCR_EL1 +Res0 4:3 +Field 2 ICC_CR0_EL1 +Res0 1 +Field 0 ICC_APR_EL1 +EndSysreg + Sysreg ICH_HCR_EL2 3 4 12 11 0 Res0 63:32 Field 31:27 EOIcount --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B981B2E3B19; Thu, 3 Jul 2025 10:26:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538390; cv=none; b=doG5sb2+bkv90VW06RWZ+6x3V3yCaB9mW1LaIpyZTkRRhiAsezTdw9GJshEZf0vJwCsWZzTKNx5GJ3TKEcSjSdUs+n8IFJG1tsudtTH9m1pPIlGySIFwb8rajZyDqSUTzVCnFez72qlXTfcqlbNy0ktsIgeZxwazMLcqGwWGfHA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538390; c=relaxed/simple; bh=Kee47be5SOaj8ZAKWq8kcIFL6lhOBtMxQS91FreJJG0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hJxs52wq94KrMeYxt41rY5AT2DShCH76GmLei6/7Nx45yKZDCPxJDx9GhySOzBAUqHrBQHoR+zqr1GaSBpiCR+HZkQDvlRHPdpEPmqn+KWa/53I2b+Vb8lLnqCusMgIZ5R8HEwGhMxxIuaMMmyk99uehDlyoEkvk9XdXqsPXtiE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cF9cDOAB; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cF9cDOAB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D3964C4CEEB; Thu, 3 Jul 2025 10:26:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538390; bh=Kee47be5SOaj8ZAKWq8kcIFL6lhOBtMxQS91FreJJG0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=cF9cDOABy4h48d3Cc+GsAZKBp/dxJIMNf042SMNGr2mVw6HyI6pkgZ1VYZBawIQt5 UGZyXvSGLAB2wyqASbijXv8NYemFoSej5keSTFdfCAJTYKcfP8eUeDHi4lEPZYzJV6 J8RQcX/z5/Olexkz8rW1zwP0Qk0eu0t6gYb3IfbM9DCp2tZaERhUT8iX+VuIxMdBcY XqrnsjX4HR9Ngn8U+Qrj87mMwb8lWEPSs6Jg/FeSsL+zEfVPDuPbVZcmHHW8aV/fPL XTw5fJ2MzPes4zPJZqZ/CFvNFw/myKThRASz0jtUUABSOiUfwC0ITVrsWFHeStgtkE E56e9pRQJvMQQ== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:04 +0200 Subject: [PATCH v7 14/31] arm64/sysreg: Add ICH_HFGITR_EL2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-14-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Add ICH_HFGITR_EL2 register description to sysreg. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Jonathan Cameron Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/tools/sysreg | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg index 9def240582dc..aab58bf4ed9c 100644 --- a/arch/arm64/tools/sysreg +++ b/arch/arm64/tools/sysreg @@ -4467,6 +4467,21 @@ Res0 1 Field 0 ICC_APR_EL1 EndSysreg =20 +Sysreg ICH_HFGITR_EL2 3 4 12 9 7 +Res0 63:11 +Field 10 GICRCDNMIA +Field 9 GICRCDIA +Field 8 GICCDDI +Field 7 GICCDEOI +Field 6 GICCDHM +Field 5 GICCDRCFG +Field 4 GICCDPEND +Field 3 GICCDAFF +Field 2 GICCDPRI +Field 1 GICCDDIS +Field 0 GICCDEN +EndSysreg + Sysreg ICH_HCR_EL2 3 4 12 11 0 Res0 63:32 Field 31:27 EOIcount --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5ADE92E425B; Thu, 3 Jul 2025 10:26:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538396; cv=none; b=COSfX1vX66IMZ+F3/K7Nn6ALwRQM21o2ecOLQgQypwMa2cTe12bPVu2IeZfh7yrAtMeZzrajqWXjEdcmed7LKinfG7OTL3fyX0kuoW9+P82T7M+O37oXuV1zfBunTTVMkhQcs1BOGYjNshiuSPJypKbSQT8t+cBxR+SO/DzK/KQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538396; c=relaxed/simple; bh=Y65mBpXFKRIuLxSiQ3O5ySwIbzcmgFcyV0yOBjwW2no=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=avXOaH9B3gki4RdKkx7rha/nKHk19t78FlYFmVnUVmQvOVnGYBFCWXAkqK0UA7cbd3qCJaOhuASxZ7jlNdFWPhL8UH2SKJZEZxpI5zY65+xvB5BNrPQRNdo7eCZhiQt/lmXSrhdGr7EDRMC2XInhf6xtSs/CnSHnrSzfGV9bkIE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pJYXo/gx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pJYXo/gx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 23B74C4CEF1; Thu, 3 Jul 2025 10:26:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538395; bh=Y65mBpXFKRIuLxSiQ3O5ySwIbzcmgFcyV0yOBjwW2no=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pJYXo/gxULIqpEH/981iAckpVHnjkIfWnFdqccNZE0jZ4KXtVw96F2tEQOrJv0D2D UlxEbqTe5Gr/tSiVUDo+kjcFwMgizxl1eDAG1YUkyf6LnNH/hXa+9yd1qX1w58lrWU fY50f+/b3o/iFBS3OuwCDydB2hF/yshS1B/utDwm9XKVeSR6dvm3gHJIXzM2yK9qic tsdUEtKSXtDcqiLuZNDqYbzJil0PUjrQlwffXDMv48gtaH39y9xf4oOPTG3v9qQezf OPpQ/qSfJ0lhH+nMvCFFkpCiYT8arUZtGUuyZp50Z4ZdzeUl2wdSah2QMk5L3G/Ke9 8kY94dgQMeZ2Q== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:05 +0200 Subject: [PATCH v7 15/31] arm64: Disable GICv5 read/write/instruction traps Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-15-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e GICv5 trap configuration registers value is UNKNOWN at reset. Initialize GICv5 EL2 trap configuration registers to prevent trapping GICv5 instruction/register access upon entering the kernel. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/include/asm/el2_setup.h | 45 ++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 45 insertions(+) diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el= 2_setup.h index ba5df0df02a4..54abcb13e51f 100644 --- a/arch/arm64/include/asm/el2_setup.h +++ b/arch/arm64/include/asm/el2_setup.h @@ -165,6 +165,50 @@ .Lskip_gicv3_\@: .endm =20 +/* GICv5 system register access */ +.macro __init_el2_gicv5 + mrs_s x0, SYS_ID_AA64PFR2_EL1 + ubfx x0, x0, #ID_AA64PFR2_EL1_GCIE_SHIFT, #4 + cbz x0, .Lskip_gicv5_\@ + + mov x0, #(ICH_HFGITR_EL2_GICRCDNMIA | \ + ICH_HFGITR_EL2_GICRCDIA | \ + ICH_HFGITR_EL2_GICCDDI | \ + ICH_HFGITR_EL2_GICCDEOI | \ + ICH_HFGITR_EL2_GICCDHM | \ + ICH_HFGITR_EL2_GICCDRCFG | \ + ICH_HFGITR_EL2_GICCDPEND | \ + ICH_HFGITR_EL2_GICCDAFF | \ + ICH_HFGITR_EL2_GICCDPRI | \ + ICH_HFGITR_EL2_GICCDDIS | \ + ICH_HFGITR_EL2_GICCDEN) + msr_s SYS_ICH_HFGITR_EL2, x0 // Disable instruction traps + mov_q x0, (ICH_HFGRTR_EL2_ICC_PPI_ACTIVERn_EL1 | \ + ICH_HFGRTR_EL2_ICC_PPI_PRIORITYRn_EL1 | \ + ICH_HFGRTR_EL2_ICC_PPI_PENDRn_EL1 | \ + ICH_HFGRTR_EL2_ICC_PPI_ENABLERn_EL1 | \ + ICH_HFGRTR_EL2_ICC_PPI_HMRn_EL1 | \ + ICH_HFGRTR_EL2_ICC_IAFFIDR_EL1 | \ + ICH_HFGRTR_EL2_ICC_ICSR_EL1 | \ + ICH_HFGRTR_EL2_ICC_PCR_EL1 | \ + ICH_HFGRTR_EL2_ICC_HPPIR_EL1 | \ + ICH_HFGRTR_EL2_ICC_HAPR_EL1 | \ + ICH_HFGRTR_EL2_ICC_CR0_EL1 | \ + ICH_HFGRTR_EL2_ICC_IDRn_EL1 | \ + ICH_HFGRTR_EL2_ICC_APR_EL1) + msr_s SYS_ICH_HFGRTR_EL2, x0 // Disable reg read traps + mov_q x0, (ICH_HFGWTR_EL2_ICC_PPI_ACTIVERn_EL1 | \ + ICH_HFGWTR_EL2_ICC_PPI_PRIORITYRn_EL1 | \ + ICH_HFGWTR_EL2_ICC_PPI_PENDRn_EL1 | \ + ICH_HFGWTR_EL2_ICC_PPI_ENABLERn_EL1 | \ + ICH_HFGWTR_EL2_ICC_ICSR_EL1 | \ + ICH_HFGWTR_EL2_ICC_PCR_EL1 | \ + ICH_HFGWTR_EL2_ICC_CR0_EL1 | \ + ICH_HFGWTR_EL2_ICC_APR_EL1) + msr_s SYS_ICH_HFGWTR_EL2, x0 // Disable reg write traps +.Lskip_gicv5_\@: +.endm + .macro __init_el2_hstr msr hstr_el2, xzr // Disable CP15 traps to EL2 .endm @@ -314,6 +358,7 @@ __init_el2_lor __init_el2_stage2 __init_el2_gicv3 + __init_el2_gicv5 __init_el2_hstr __init_el2_nvhe_idregs __init_el2_cptr --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 04C672E7627; Thu, 3 Jul 2025 10:26:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538402; cv=none; b=tQvkT0a1eRpqsgUMrbxIsVesk6TLqrIEuHTMxYGSAgQhFNDe6XaUvhn/im4ifV4p8gxpj1fh9C6Ub/4RcUcANmWThAa1MYXWejEc9US/hv/M8ranookP++7S9D9ggeDF9Cz/AVQJJVVZGwF+tUJnpH8c99fUr/f82XfvPimePY4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538402; c=relaxed/simple; bh=D1A2VCqeW16Gr2UxgYnNuc/Q40Vq2MeocinVOfXGjww=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tRSGTVgpoV30IQ0NMlAIOK2qaXnTacJu2W74+LFrsF7e5aOmHEnTafqWXgTbvErGlJdS6R8kWU7kFBbmWqGOhbcAlne2qeuwpUQIgBlfNI9+9Ueyw8cvwDfZV/EUQEM1qTuqn6eMvkO8Lcaf2NNFaFMQyH1dMkvtBb0GMVcPjk4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZvE2DrNq; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZvE2DrNq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 73500C4CEE3; Thu, 3 Jul 2025 10:26:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538401; bh=D1A2VCqeW16Gr2UxgYnNuc/Q40Vq2MeocinVOfXGjww=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ZvE2DrNqzzc6vAxbV4B1wR6IWPWw9dBOXLLgZNfm5Uq8ES2nTGdmDN/o75YkXe86r a8w3cX0rne91u+cVxSpAx8mjHBqlhRB+xC52+D7HAYR7kULWOQOaVO++mKvv2XjiVy gCqm+EQ5fxQN6gVMwl2T4UyCfqglXh9kHIWPswFfzAQQtEp8q0hsXXupMiE4n4/fED 6eGq5EoyOfdy2/rkQN7nWymWD8VmHiJTkI+g3Xh2EXwF3l+1WzweOJpR2/OSixyLBf sqlG03W+foJmLeSBlNje0XYKgQYp08gxh4U3tLLeZZJ//Rpvlm5TQD3Y1/nST7zDOv uxbbHjXVDqqgA== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:06 +0200 Subject: [PATCH v7 16/31] arm64: cpucaps: Rename GICv3 CPU interface capability Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-16-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e In preparation for adding a GICv5 CPU interface capability, rework the existing GICv3 CPUIF capability - change its name and description so that the subsequent GICv5 CPUIF capability can be added with a more consistent naming on top. Suggested-by: Mark Rutland Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/kernel/cpufeature.c | 10 +++++----- arch/arm64/tools/cpucaps | 2 +- drivers/irqchip/irq-gic.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index b34044e20128..42ba76b6c8cd 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -2296,11 +2296,11 @@ static bool can_use_gic_priorities(const struct arm= 64_cpu_capabilities *entry, int scope) { /* - * ARM64_HAS_GIC_CPUIF_SYSREGS has a lower index, and is a boot CPU + * ARM64_HAS_GICV3_CPUIF has a lower index, and is a boot CPU * feature, so will be detected earlier. */ - BUILD_BUG_ON(ARM64_HAS_GIC_PRIO_MASKING <=3D ARM64_HAS_GIC_CPUIF_SYSREGS); - if (!cpus_have_cap(ARM64_HAS_GIC_CPUIF_SYSREGS)) + BUILD_BUG_ON(ARM64_HAS_GIC_PRIO_MASKING <=3D ARM64_HAS_GICV3_CPUIF); + if (!cpus_have_cap(ARM64_HAS_GICV3_CPUIF)) return false; =20 return enable_pseudo_nmi; @@ -2496,8 +2496,8 @@ static const struct arm64_cpu_capabilities arm64_feat= ures[] =3D { .matches =3D has_always, }, { - .desc =3D "GIC system register CPU interface", - .capability =3D ARM64_HAS_GIC_CPUIF_SYSREGS, + .desc =3D "GICv3 CPU interface", + .capability =3D ARM64_HAS_GICV3_CPUIF, .type =3D ARM64_CPUCAP_STRICT_BOOT_CPU_FEATURE, .matches =3D has_useable_gicv3_cpuif, ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, GIC, IMP) diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index 10effd4cff6b..a7a4d9e6e12e 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -35,7 +35,7 @@ HAS_GENERIC_AUTH HAS_GENERIC_AUTH_ARCH_QARMA3 HAS_GENERIC_AUTH_ARCH_QARMA5 HAS_GENERIC_AUTH_IMP_DEF -HAS_GIC_CPUIF_SYSREGS +HAS_GICV3_CPUIF HAS_GIC_PRIO_MASKING HAS_GIC_PRIO_RELAXED_SYNC HAS_HCR_NV1 diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 6503573557fd..1269ab8eb726 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -54,7 +54,7 @@ =20 static void gic_check_cpu_features(void) { - WARN_TAINT_ONCE(this_cpu_has_cap(ARM64_HAS_GIC_CPUIF_SYSREGS), + WARN_TAINT_ONCE(this_cpu_has_cap(ARM64_HAS_GICV3_CPUIF), TAINT_CPU_OUT_OF_SPEC, "GICv3 system registers enabled, broken firmware!\n"); } --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5A7622E7BA8; Thu, 3 Jul 2025 10:26:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538407; cv=none; b=FSBbEAlkHFlUCeKqH+iWkrYw2of+65+GzTM5w1zIjjg8bmuOKAxh/IPusgJF8a1HE0NbAu1DWg1hQMvnUGq20MSkSzuarwcaM3q0eEOdIHjJPIi1wmq43CD1h6wovI/vGBOavuHXFSOJCiBi5oBXoNcBd82x/SzXVm2voAIP5rk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538407; c=relaxed/simple; bh=Z8Ojm3tu2K7fLVQhABMYAuAVcs0eLame5+RGMEmHY/A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DBswa485JuiA9+YyVbhvjJViRHH1+8LKFmtbs9Wq56KuyDCBDbJ6e38XxsjepETNfJOSyMEGCJsMCINAQqyQAYYboQyrtNdwe6kgLDoVjXHtv3m2enstqRk380/ebA9DYS64YPnwIKZImNhLMHItQXGaa+af/8C/BfKXT0zkdGI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MfnkMMKr; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MfnkMMKr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 28B09C4CEEB; Thu, 3 Jul 2025 10:26:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538407; bh=Z8Ojm3tu2K7fLVQhABMYAuAVcs0eLame5+RGMEmHY/A=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=MfnkMMKrenQurkIeFvn7yhMz17v3mJo2uhcTlhb48vr0QZ4vDkfH/WYcPYat2b5d7 1DD4OgEd9WIQf9NiVCuh6G2UROdmiJOwDj9SKk87THYksxXlssInNkAIlRQy9feIc9 zFfhvYc3poEtHswA+LscW2L3y/SEn0sZtkEOoyu+7KwDNIP635/mSYe+lgGtbjMino LcDU0OO4FIPDX2GA4nVYuLwRimWEwXPsocJaTZqYBqsXTQIJ2am5GjcNCYnlIZPeKv J9IzZvMVau27h6lOQYvyTpIWwO5vsc16U13/w/twAFxSWw5fqPqXQN827fbLKvByV5 47yl8SPH99P+Q== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:07 +0200 Subject: [PATCH v7 17/31] arm64: cpucaps: Add GICv5 CPU interface (GCIE) capability Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-17-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Implement the GCIE capability as a strict boot cpu capability to detect whether architectural GICv5 support is available in HW. Plug it in with a naming consistent with the existing GICv3 CPU interface capability. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/kernel/cpufeature.c | 7 +++++++ arch/arm64/tools/cpucaps | 1 + 2 files changed, 8 insertions(+) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 42ba76b6c8cd..2fa26129762c 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -3061,6 +3061,13 @@ static const struct arm64_cpu_capabilities arm64_fea= tures[] =3D { .matches =3D has_pmuv3, }, #endif + { + .desc =3D "GICv5 CPU interface", + .type =3D ARM64_CPUCAP_STRICT_BOOT_CPU_FEATURE, + .capability =3D ARM64_HAS_GICV5_CPUIF, + .matches =3D has_cpuid_feature, + ARM64_CPUID_FIELDS(ID_AA64PFR2_EL1, GCIE, IMP) + }, {}, }; =20 diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index a7a4d9e6e12e..8665e4cfbeab 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -36,6 +36,7 @@ HAS_GENERIC_AUTH_ARCH_QARMA3 HAS_GENERIC_AUTH_ARCH_QARMA5 HAS_GENERIC_AUTH_IMP_DEF HAS_GICV3_CPUIF +HAS_GICV5_CPUIF HAS_GIC_PRIO_MASKING HAS_GIC_PRIO_RELAXED_SYNC HAS_HCR_NV1 --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2B03A2E7F39; Thu, 3 Jul 2025 10:26:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538413; cv=none; b=XrraCuy9IOWLzt72b03i41dvqUggxdPGXMc7qzbmi83T4BGYNW1HwKoGUdx/sE2W+vTdG9Kw6gBMLPCNu74NtenydCcwbuTx/Z+2/WkixMAj7ra7G9V2QLU8VYSSBpW6u6ilxAHYfVp2Lk9uZrJeukNtyAFEHyN9LpQ4F70iDww= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538413; c=relaxed/simple; bh=jmKU/AVW3es/n6fJNXdjcwxCLiVu0aOx0X//TygUoKY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bdt3YTnr+cf+FsRDmJDrBWe6b3uxtbXR3adRDCXkyyGKcgi1okoalWILFKxRAdmBrMFPXv6IMGgsW4JljxCk0MnI0gTf3mFp4fi1z3Vk0+FAehIjkOLRytq7QCogti26jOWv5umGczBvuRAiie+mp9eJ1uOMG+HgV+lgX6Ht3Iw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NOYsieoq; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NOYsieoq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BC94BC4CEE3; Thu, 3 Jul 2025 10:26:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538413; bh=jmKU/AVW3es/n6fJNXdjcwxCLiVu0aOx0X//TygUoKY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=NOYsieoqhimaXGfMqzeu7sVAzUmU6v4n4Vo01k0gStM0MntuliWzZhoUvkULKWNYt jNU/qdqPeQlrULmVLWqD4CbDcZe9EJqim4FpD5yBHKraQ5nk/anarHjEED4un0e7r+ RVjdv29y7iw0KU4MEhfpA6fXXQOQg4ozvAFCgqXzpGSWPLheftCcbh+8zO+Sq78n2G z7ht2BngIZ9TZoWn7WmBAkr4SL9DkHT54wM+xf7eQZUsk0/f80sivkw0xdZXggYZQG UkY7T7fPmXvFXEt7On8uy8PqRV9LvE0R7AfpFlpZOyH4jd1L3Nhtw1tfn+HiGsx+dK HQxHUIfFxJqZg== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:08 +0200 Subject: [PATCH v7 18/31] arm64: smp: Support non-SGIs for IPIs Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-18-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e From: Marc Zyngier The arm64 arch has relied so far on GIC architectural software generated interrupt (SGIs) to handle IPIs. Those are per-cpu software generated interrupts. arm64 architecture code that allocates the IPIs virtual IRQs and IRQ descriptors was written accordingly. On GICv5 systems, IPIs are implemented using LPIs that are not per-cpu interrupts - they are just normal routable IRQs. Add arch code to set-up IPIs on systems where they are handled using normal routable IRQs. For those systems, force the IRQ affinity (and make it immutable) to the cpu a given IRQ was assigned to. Signed-off-by: Marc Zyngier [timothy.hayes@arm.com: fixed ipi/irq conversion, irq flags] Signed-off-by: Timothy Hayes [lpieralisi: changed affinity set-up, log] Signed-off-by: Lorenzo Pieralisi Cc: Will Deacon Cc: Catalin Marinas Acked-by: Catalin Marinas --- arch/arm64/include/asm/smp.h | 7 ++- arch/arm64/kernel/smp.c | 127 +++++++++++++++++++++++++++++++--------= ---- 2 files changed, 99 insertions(+), 35 deletions(-) diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index 2510eec026f7..d6fd6efb66a6 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -53,7 +53,12 @@ extern void smp_init_cpus(void); /* * Register IPI interrupts with the arch SMP code */ -extern void set_smp_ipi_range(int ipi_base, int nr_ipi); +extern void set_smp_ipi_range_percpu(int ipi_base, int nr_ipi, int ncpus); + +static inline void set_smp_ipi_range(int ipi_base, int n) +{ + set_smp_ipi_range_percpu(ipi_base, n, 0); +} =20 /* * Called from the secondary holding pen, this is the secondary CPU entry = point. diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 3b3f6b56e733..2c501e917d38 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -83,7 +83,16 @@ enum ipi_msg_type { =20 static int ipi_irq_base __ro_after_init; static int nr_ipi __ro_after_init =3D NR_IPI; -static struct irq_desc *ipi_desc[MAX_IPI] __ro_after_init; + +struct ipi_descs { + struct irq_desc *descs[MAX_IPI]; +}; + +static DEFINE_PER_CPU_READ_MOSTLY(struct ipi_descs, pcpu_ipi_desc); + +#define get_ipi_desc(__cpu, __ipi) (per_cpu_ptr(&pcpu_ipi_desc, __cpu)->de= scs[__ipi]) + +static bool percpu_ipi_descs __ro_after_init; =20 static bool crash_stop; =20 @@ -844,7 +853,7 @@ int arch_show_interrupts(struct seq_file *p, int prec) seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i, prec >=3D 4 ? " " : ""); for_each_online_cpu(cpu) - seq_printf(p, "%10u ", irq_desc_kstat_cpu(ipi_desc[i], cpu)); + seq_printf(p, "%10u ", irq_desc_kstat_cpu(get_ipi_desc(cpu, i), cpu)); seq_printf(p, " %s\n", ipi_types[i]); } =20 @@ -917,9 +926,20 @@ static void __noreturn ipi_cpu_crash_stop(unsigned int= cpu, struct pt_regs *regs #endif } =20 +static void arm64_send_ipi(const cpumask_t *mask, unsigned int nr) +{ + unsigned int cpu; + + if (!percpu_ipi_descs) + __ipi_send_mask(get_ipi_desc(0, nr), mask); + else + for_each_cpu(cpu, mask) + __ipi_send_single(get_ipi_desc(cpu, nr), cpu); +} + static void arm64_backtrace_ipi(cpumask_t *mask) { - __ipi_send_mask(ipi_desc[IPI_CPU_BACKTRACE], mask); + arm64_send_ipi(mask, IPI_CPU_BACKTRACE); } =20 void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu) @@ -944,7 +964,7 @@ void kgdb_roundup_cpus(void) if (cpu =3D=3D this_cpu) continue; =20 - __ipi_send_single(ipi_desc[IPI_KGDB_ROUNDUP], cpu); + __ipi_send_single(get_ipi_desc(cpu, IPI_KGDB_ROUNDUP), cpu); } } #endif @@ -1013,14 +1033,16 @@ static void do_handle_IPI(int ipinr) =20 static irqreturn_t ipi_handler(int irq, void *data) { - do_handle_IPI(irq - ipi_irq_base); + unsigned int ipi =3D (irq - ipi_irq_base) % nr_ipi; + + do_handle_IPI(ipi); return IRQ_HANDLED; } =20 static void smp_cross_call(const struct cpumask *target, unsigned int ipin= r) { trace_ipi_raise(target, ipi_types[ipinr]); - __ipi_send_mask(ipi_desc[ipinr], target); + arm64_send_ipi(target, ipinr); } =20 static bool ipi_should_be_nmi(enum ipi_msg_type ipi) @@ -1046,11 +1068,15 @@ static void ipi_setup(int cpu) return; =20 for (i =3D 0; i < nr_ipi; i++) { - if (ipi_should_be_nmi(i)) { - prepare_percpu_nmi(ipi_irq_base + i); - enable_percpu_nmi(ipi_irq_base + i, 0); + if (!percpu_ipi_descs) { + if (ipi_should_be_nmi(i)) { + prepare_percpu_nmi(ipi_irq_base + i); + enable_percpu_nmi(ipi_irq_base + i, 0); + } else { + enable_percpu_irq(ipi_irq_base + i, 0); + } } else { - enable_percpu_irq(ipi_irq_base + i, 0); + enable_irq(irq_desc_get_irq(get_ipi_desc(cpu, i))); } } } @@ -1064,44 +1090,77 @@ static void ipi_teardown(int cpu) return; =20 for (i =3D 0; i < nr_ipi; i++) { - if (ipi_should_be_nmi(i)) { - disable_percpu_nmi(ipi_irq_base + i); - teardown_percpu_nmi(ipi_irq_base + i); + if (!percpu_ipi_descs) { + if (ipi_should_be_nmi(i)) { + disable_percpu_nmi(ipi_irq_base + i); + teardown_percpu_nmi(ipi_irq_base + i); + } else { + disable_percpu_irq(ipi_irq_base + i); + } } else { - disable_percpu_irq(ipi_irq_base + i); + disable_irq(irq_desc_get_irq(get_ipi_desc(cpu, i))); } } } #endif =20 -void __init set_smp_ipi_range(int ipi_base, int n) +static void ipi_setup_sgi(int ipi) +{ + int err, irq, cpu; + + irq =3D ipi_irq_base + ipi; + + if (ipi_should_be_nmi(irq)) { + err =3D request_percpu_nmi(irq, ipi_handler, "IPI", &irq_stat); + WARN(err, "Could not request IRQ %d as NMI, err=3D%d\n", irq, err); + } else { + err =3D request_percpu_irq(irq, ipi_handler, "IPI", &irq_stat); + WARN(err, "Could not request IRQ %d as IRQ, err=3D%d\n", irq, err); + } + + for_each_possible_cpu(cpu) + get_ipi_desc(cpu, ipi) =3D irq_to_desc(irq); + + irq_set_status_flags(irq, IRQ_HIDDEN); +} + +static void ipi_setup_lpi(int ipi, int ncpus) +{ + for (int cpu =3D 0; cpu < ncpus; cpu++) { + int err, irq; + + irq =3D ipi_irq_base + (cpu * nr_ipi) + ipi; + + err =3D irq_force_affinity(irq, cpumask_of(cpu)); + WARN(err, "Could not force affinity IRQ %d, err=3D%d\n", irq, err); + + err =3D request_irq(irq, ipi_handler, IRQF_NO_AUTOEN, "IPI", + NULL); + WARN(err, "Could not request IRQ %d, err=3D%d\n", irq, err); + + irq_set_status_flags(irq, (IRQ_HIDDEN | IRQ_NO_BALANCING_MASK)); + + get_ipi_desc(cpu, ipi) =3D irq_to_desc(irq); + } +} + +void __init set_smp_ipi_range_percpu(int ipi_base, int n, int ncpus) { int i; =20 WARN_ON(n < MAX_IPI); nr_ipi =3D min(n, MAX_IPI); =20 - for (i =3D 0; i < nr_ipi; i++) { - int err; - - if (ipi_should_be_nmi(i)) { - err =3D request_percpu_nmi(ipi_base + i, ipi_handler, - "IPI", &irq_stat); - WARN(err, "Could not request IPI %d as NMI, err=3D%d\n", - i, err); - } else { - err =3D request_percpu_irq(ipi_base + i, ipi_handler, - "IPI", &irq_stat); - WARN(err, "Could not request IPI %d as IRQ, err=3D%d\n", - i, err); - } - - ipi_desc[i] =3D irq_to_desc(ipi_base + i); - irq_set_status_flags(ipi_base + i, IRQ_HIDDEN); - } - + percpu_ipi_descs =3D !!ncpus; ipi_irq_base =3D ipi_base; =20 + for (i =3D 0; i < nr_ipi; i++) { + if (!percpu_ipi_descs) + ipi_setup_sgi(i); + else + ipi_setup_lpi(i, ncpus); + } + /* Setup the boot CPU immediately */ ipi_setup(smp_processor_id()); } --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 836C52E2EEC; Thu, 3 Jul 2025 10:26:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538418; cv=none; b=NJu8nRlYv/RYfBp5yONKWs4Br7/g3QAebcyOfSi/JyUfyyCiA4M8x3ZzaCFC0nIE9oDVEu9kjM7Xftu+qLG3h23Kaf6UxpA3yRHW8H/2adpX20NL5SAONyWnJSDlhPJNWD3mkKLEFyRkFKw0JW3sKdSpHEic0qHIq3II2t24rhs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538418; c=relaxed/simple; bh=x0UjezfsoOH38t7iWo4VW4qdmeF50w/ZyH4r588go9U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GR1ACSn49mZ6vFN5onvbV2xkaItxaCImWL4B9F4YACYWnjKtuubflO1QNjAWqIQpRMuuau2Of3H2QxCu71UdxIY6WumMOhcb/MYBANwyJOwK3NYHc/12B3nM/6bGfkpUYSmibwKkNOcApRd+i2xl8/Uk7AuahGsZweFKqIUGVrc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GNdALS29; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GNdALS29" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 89DFBC4CEE3; Thu, 3 Jul 2025 10:26:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538418; bh=x0UjezfsoOH38t7iWo4VW4qdmeF50w/ZyH4r588go9U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=GNdALS296jUJIu7ceSIkUHb/w594jhgeYc7AbnXCo+C+DQvNoNATs/YyFkcl3KC7b BHR2qNYFWsrOR5tN28sL3TiLE/TXyYkUwL9DmJFiW47xLNd8rtXI9kRpz7XfxPHqK4 YyrxsL854AevKx+mUZs9v4ajI/rvf/dwHL5+wvoAbscLceuCkDWhbV7jAbIHDblfZn C7qjFUhbWYGFf6my6/Tws3YpUc/catrk/lMdnhBMwlpYV/s11mjGZD6tZwD1vV4Zjb X2VZ3RJ/TqKANflRZ3g11964g32jwdjG3IOo3YrzedG4mwYO0g41+7YtrTTggXtGoi B5tKUngUIXC8g== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:09 +0200 Subject: [PATCH v7 19/31] arm64: Add support for GICv5 GSB barriers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-19-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e The GICv5 architecture introduces two barriers instructions (GSB SYS, GSB ACK) that are used to manage interrupt effects. Rework macro used to emit the SB barrier instruction and implement the GSB barriers on top of it. Suggested-by: Marc Zyngier Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/include/asm/barrier.h | 3 +++ arch/arm64/include/asm/sysreg.h | 10 +++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barr= ier.h index 1ca947d5c939..f5801b0ba9e9 100644 --- a/arch/arm64/include/asm/barrier.h +++ b/arch/arm64/include/asm/barrier.h @@ -44,6 +44,9 @@ SB_BARRIER_INSN"nop\n", \ ARM64_HAS_SB)) =20 +#define gsb_ack() asm volatile(GSB_ACK_BARRIER_INSN : : : "memory") +#define gsb_sys() asm volatile(GSB_SYS_BARRIER_INSN : : : "memory") + #ifdef CONFIG_ARM64_PSEUDO_NMI #define pmr_sync() \ do { \ diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysre= g.h index f1bb0d10c39a..9b5fc6389715 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -113,10 +113,14 @@ /* Register-based PAN access, for save/restore purposes */ #define SYS_PSTATE_PAN sys_reg(3, 0, 4, 2, 3) =20 -#define __SYS_BARRIER_INSN(CRm, op2, Rt) \ - __emit_inst(0xd5000000 | sys_insn(0, 3, 3, (CRm), (op2)) | ((Rt) & 0x1f)) +#define __SYS_BARRIER_INSN(op0, op1, CRn, CRm, op2, Rt) \ + __emit_inst(0xd5000000 | \ + sys_insn((op0), (op1), (CRn), (CRm), (op2)) | \ + ((Rt) & 0x1f)) =20 -#define SB_BARRIER_INSN __SYS_BARRIER_INSN(0, 7, 31) +#define SB_BARRIER_INSN __SYS_BARRIER_INSN(0, 3, 3, 0, 7, 31) +#define GSB_SYS_BARRIER_INSN __SYS_BARRIER_INSN(1, 0, 12, 0, 0, 31) +#define GSB_ACK_BARRIER_INSN __SYS_BARRIER_INSN(1, 0, 12, 0, 1, 31) =20 /* Data cache zero operations */ #define SYS_DC_ISW sys_insn(1, 0, 7, 6, 2) --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 728322E3372; Thu, 3 Jul 2025 10:27:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538424; cv=none; b=YWN9ewZi6hULFhGtsrmmAzGsWRRDZIMEA5gEYJTgMHyQ4rIjHmz6gMiQ/SuJzfqh044L7C4zNLKKW3q/UOV+scIRIwyItyihOQZtYFQa5k9e4+p+HNrpS1AU5a2Kic3VdQs7OTaUgoEUvKortWekZd0zX3jPHStQJZ/7Cg9ZWBI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538424; c=relaxed/simple; bh=Ax+SoIbLlloOYsF4kGPHc9cyYRgERc2Qye8N42Rd+QM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VmEimms89Jsxp4kWKGemM1g9f0adI8U9VYqgYNYneF4iwe1XjHC6RBPyYzdh+uUX/NrUw3x5kcOR9bv8AUAxun/ipThMHVKVyrQK+KGAruezKVjMBNQJSfFu6ZuPPIHEd4GkWZWasmpouZNVITgYocsuI7Ulg//LV0ydNxeAI6Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=m3/usFBl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="m3/usFBl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E48E4C4CEEB; Thu, 3 Jul 2025 10:26:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538424; bh=Ax+SoIbLlloOYsF4kGPHc9cyYRgERc2Qye8N42Rd+QM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=m3/usFBl7w57ug7J9zh+Z85OSUVBn4LvvI+qcQ3lSBphr1Yw/9ayUfsuIGBTzKKHh PYj3bstPnyZW73w25PwEXWOeJFfddIPPiHAONmGdztsuBxUy0IQFNc6nPIQTmsESWx oVCmCrpt8W9nleQ+sxmylcHV77ME0+XZe1LyDUQG183YRN+wa29jzCgn9IsYPCYgHX F9qVzifbFaK6Pu1dJ5IV1bA5WJMex1uqdHnLg+A8hovcQsazBp/7aKDVKFLBhvMBVD mGUr7wMBR6GVwKgByTXPe8eDvVLsiV1UucaDo90wnuDsvcP0Hj1roVSty2s9TSsoqs N9LhNuYWe9A1g== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:10 +0200 Subject: [PATCH v7 20/31] irqchip/gic-v5: Add GICv5 PPI support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-20-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e The GICv5 CPU interface implements support for PE-Private Peripheral Interrupts (PPI), that are handled (enabled/prioritized/delivered) entirely within the CPU interface hardware. To enable PPI interrupts, implement the baseline GICv5 host kernel driver infrastructure required to handle interrupts on a GICv5 system. Add the exception handling code path and definitions for GICv5 instructions. Add GICv5 PPI handling code as a specific IRQ domain to: - Set-up PPI priority - Manage PPI configuration and state - Manage IRQ flow handler - IRQs allocation/free - Hook-up a PPI specific IRQchip to provide the relevant methods PPI IRQ priority is chosen as the minimum allowed priority by the system design (after probing the number of priority bits implemented by the CPU interface). Co-developed-by: Sascha Bischoff Signed-off-by: Sascha Bischoff Co-developed-by: Timothy Hayes Signed-off-by: Timothy Hayes Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Thomas Gleixner Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- MAINTAINERS | 2 + arch/arm64/include/asm/sysreg.h | 19 ++ drivers/irqchip/Kconfig | 5 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-gic-v5.c | 464 +++++++++++++++++++++++++++++++++= ++++ include/linux/irqchip/arm-gic-v5.h | 19 ++ 6 files changed, 510 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index f02a768adecb..222a668f3fb6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1971,6 +1971,8 @@ M: Marc Zyngier L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/interrupt-controller/arm,gic-v5*.yaml +F: drivers/irqchip/irq-gic-v5*.[ch] +F: include/linux/irqchip/arm-gic-v5.h =20 ARM HDLCD DRM DRIVER M: Liviu Dudau diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysre= g.h index 9b5fc6389715..36b82d74db37 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -1082,6 +1082,25 @@ =20 #define GCS_CAP(x) ((((unsigned long)x) & GCS_CAP_ADDR_MASK) | \ GCS_CAP_VALID_TOKEN) +/* + * Definitions for GICv5 instructions + */ +#define GICV5_OP_GIC_CDDI sys_insn(1, 0, 12, 2, 0) +#define GICV5_OP_GIC_CDEOI sys_insn(1, 0, 12, 1, 7) +#define GICV5_OP_GICR_CDIA sys_insn(1, 0, 12, 3, 0) + +/* Definitions for GIC CDDI */ +#define GICV5_GIC_CDDI_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDDI_ID_MASK GENMASK_ULL(23, 0) + +/* Definitions for GICR CDIA */ +#define GICV5_GIC_CDIA_VALID_MASK BIT_ULL(32) +#define GICV5_GICR_CDIA_VALID(r) FIELD_GET(GICV5_GIC_CDIA_VALID_MASK, r) +#define GICV5_GIC_CDIA_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDIA_ID_MASK GENMASK_ULL(23, 0) + +#define gicr_insn(insn) read_sysreg_s(GICV5_OP_GICR_##insn) +#define gic_insn(v, insn) write_sysreg_s(v, GICV5_OP_GIC_##insn) =20 #define ARM64_FEATURE_FIELD_BITS 4 =20 diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 0d196e447142..3e4fb08b7a4d 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -54,6 +54,11 @@ config ARM_GIC_V3_ITS_FSL_MC depends on FSL_MC_BUS default ARM_GIC_V3_ITS =20 +config ARM_GIC_V5 + bool + select IRQ_DOMAIN_HIERARCHY + select GENERIC_IRQ_EFFECTIVE_AFF_MASK + config ARM_NVIC bool select IRQ_DOMAIN_HIERARCHY diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 23ca4959e6ce..3d75659d99eb 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_ARM_GIC_V3) +=3D irq-gic-v3.o irq-gic-v3-mb= i.o irq-gic-common.o obj-$(CONFIG_ARM_GIC_V3_ITS) +=3D irq-gic-v3-its.o irq-gic-v4.o irq-gic-v= 3-its-msi-parent.o obj-$(CONFIG_ARM_GIC_V3_ITS_FSL_MC) +=3D irq-gic-v3-its-fsl-mc-msi.o obj-$(CONFIG_PARTITION_PERCPU) +=3D irq-partition-percpu.o +obj-$(CONFIG_ARM_GIC_V5) +=3D irq-gic-v5.o obj-$(CONFIG_HISILICON_IRQ_MBIGEN) +=3D irq-mbigen.o obj-$(CONFIG_ARM_NVIC) +=3D irq-nvic.o obj-$(CONFIG_ARM_VIC) +=3D irq-vic.o diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c new file mode 100644 index 000000000000..0bb940212e20 --- /dev/null +++ b/drivers/irqchip/irq-gic-v5.c @@ -0,0 +1,464 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024-2025 ARM Limited, All Rights Reserved. + */ + +#define pr_fmt(fmt) "GICv5: " fmt + +#include +#include + +#include +#include + +#include +#include + +static u8 pri_bits __ro_after_init =3D 5; + +#define GICV5_IRQ_PRI_MASK 0x1f +#define GICV5_IRQ_PRI_MI (GICV5_IRQ_PRI_MASK & GENMASK(4, 5 - pri_bits)) + +#define PPI_NR 128 + +static bool gicv5_cpuif_has_gcie(void) +{ + return this_cpu_has_cap(ARM64_HAS_GICV5_CPUIF); +} + +struct gicv5_chip_data { + struct fwnode_handle *fwnode; + struct irq_domain *ppi_domain; +}; + +static struct gicv5_chip_data gicv5_global_data __read_mostly; + +static void gicv5_ppi_priority_init(void) +{ + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR0_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR1_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR2_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR3_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR4_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR5_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR6_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR7_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR8_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR9_EL1); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR10_EL1= ); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR11_EL1= ); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR12_EL1= ); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR13_EL1= ); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR14_EL1= ); + write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR15_EL1= ); + + /* + * Context syncronization required to make sure system register writes + * effects are synchronised. + */ + isb(); +} + +static void gicv5_ppi_irq_mask(struct irq_data *d) +{ + u64 hwirq_id_bit =3D BIT_ULL(d->hwirq % 64); + + if (d->hwirq < 64) + sysreg_clear_set_s(SYS_ICC_PPI_ENABLER0_EL1, hwirq_id_bit, 0); + else + sysreg_clear_set_s(SYS_ICC_PPI_ENABLER1_EL1, hwirq_id_bit, 0); + + /* + * We must ensure that the disable takes effect immediately to + * guarantee that the lazy-disabled IRQ mechanism works. + * A context synchronization event is required to guarantee it. + * Reference: I_ZLTKB/R_YRGMH GICv5 specification - section 2.9.1. + */ + isb(); +} + +static void gicv5_ppi_irq_unmask(struct irq_data *d) +{ + u64 hwirq_id_bit =3D BIT_ULL(d->hwirq % 64); + + if (d->hwirq < 64) + sysreg_clear_set_s(SYS_ICC_PPI_ENABLER0_EL1, 0, hwirq_id_bit); + else + sysreg_clear_set_s(SYS_ICC_PPI_ENABLER1_EL1, 0, hwirq_id_bit); + /* + * We must ensure that the enable takes effect in finite time - a + * context synchronization event is required to guarantee it, we + * can not take for granted that would happen (eg a core going straight + * into idle after enabling a PPI). + * Reference: I_ZLTKB/R_YRGMH GICv5 specification - section 2.9.1. + */ + isb(); +} + +static void gicv5_hwirq_eoi(u32 hwirq_id, u8 hwirq_type) +{ + u64 cddi; + + cddi =3D FIELD_PREP(GICV5_GIC_CDDI_ID_MASK, hwirq_id) | + FIELD_PREP(GICV5_GIC_CDDI_TYPE_MASK, hwirq_type); + + gic_insn(cddi, CDDI); + + gic_insn(0, CDEOI); +} + +static void gicv5_ppi_irq_eoi(struct irq_data *d) +{ + gicv5_hwirq_eoi(d->hwirq, GICV5_HWIRQ_TYPE_PPI); +} + +enum ppi_reg { + PPI_PENDING, + PPI_ACTIVE, + PPI_HM +}; + +static __always_inline u64 read_ppi_sysreg_s(unsigned int irq, + const enum ppi_reg which) +{ + switch (which) { + case PPI_PENDING: + return irq < 64 ? read_sysreg_s(SYS_ICC_PPI_SPENDR0_EL1) : + read_sysreg_s(SYS_ICC_PPI_SPENDR1_EL1); + case PPI_ACTIVE: + return irq < 64 ? read_sysreg_s(SYS_ICC_PPI_SACTIVER0_EL1) : + read_sysreg_s(SYS_ICC_PPI_SACTIVER1_EL1); + case PPI_HM: + return irq < 64 ? read_sysreg_s(SYS_ICC_PPI_HMR0_EL1) : + read_sysreg_s(SYS_ICC_PPI_HMR1_EL1); + default: + BUILD_BUG_ON(1); + } +} + +static __always_inline void write_ppi_sysreg_s(unsigned int irq, bool set, + const enum ppi_reg which) +{ + u64 bit =3D BIT_ULL(irq % 64); + + switch (which) { + case PPI_PENDING: + if (set) { + if (irq < 64) + write_sysreg_s(bit, SYS_ICC_PPI_SPENDR0_EL1); + else + write_sysreg_s(bit, SYS_ICC_PPI_SPENDR1_EL1); + } else { + if (irq < 64) + write_sysreg_s(bit, SYS_ICC_PPI_CPENDR0_EL1); + else + write_sysreg_s(bit, SYS_ICC_PPI_CPENDR1_EL1); + } + return; + case PPI_ACTIVE: + if (set) { + if (irq < 64) + write_sysreg_s(bit, SYS_ICC_PPI_SACTIVER0_EL1); + else + write_sysreg_s(bit, SYS_ICC_PPI_SACTIVER1_EL1); + } else { + if (irq < 64) + write_sysreg_s(bit, SYS_ICC_PPI_CACTIVER0_EL1); + else + write_sysreg_s(bit, SYS_ICC_PPI_CACTIVER1_EL1); + } + return; + default: + BUILD_BUG_ON(1); + } +} + +static int gicv5_ppi_irq_get_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool *state) +{ + u64 hwirq_id_bit =3D BIT_ULL(d->hwirq % 64); + + switch (which) { + case IRQCHIP_STATE_PENDING: + *state =3D !!(read_ppi_sysreg_s(d->hwirq, PPI_PENDING) & hwirq_id_bit); + return 0; + case IRQCHIP_STATE_ACTIVE: + *state =3D !!(read_ppi_sysreg_s(d->hwirq, PPI_ACTIVE) & hwirq_id_bit); + return 0; + default: + pr_debug("Unexpected PPI irqchip state\n"); + return -EINVAL; + } +} + +static int gicv5_ppi_irq_set_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool state) +{ + switch (which) { + case IRQCHIP_STATE_PENDING: + write_ppi_sysreg_s(d->hwirq, state, PPI_PENDING); + return 0; + case IRQCHIP_STATE_ACTIVE: + write_ppi_sysreg_s(d->hwirq, state, PPI_ACTIVE); + return 0; + default: + pr_debug("Unexpected PPI irqchip state\n"); + return -EINVAL; + } +} + +static bool gicv5_ppi_irq_is_level(irq_hw_number_t hwirq) +{ + u64 bit =3D BIT_ULL(hwirq % 64); + + return !!(read_ppi_sysreg_s(hwirq, PPI_HM) & bit); +} + +static const struct irq_chip gicv5_ppi_irq_chip =3D { + .name =3D "GICv5-PPI", + .irq_mask =3D gicv5_ppi_irq_mask, + .irq_unmask =3D gicv5_ppi_irq_unmask, + .irq_eoi =3D gicv5_ppi_irq_eoi, + .irq_get_irqchip_state =3D gicv5_ppi_irq_get_irqchip_state, + .irq_set_irqchip_state =3D gicv5_ppi_irq_set_irqchip_state, + .flags =3D IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_MASK_ON_SUSPEND, +}; + +static int gicv5_irq_ppi_domain_translate(struct irq_domain *d, + struct irq_fwspec *fwspec, + irq_hw_number_t *hwirq, + unsigned int *type) +{ + if (!is_of_node(fwspec->fwnode)) + return -EINVAL; + + if (fwspec->param_count < 3) + return -EINVAL; + + if (fwspec->param[0] !=3D GICV5_HWIRQ_TYPE_PPI) + return -EINVAL; + + *hwirq =3D fwspec->param[1]; + + /* + * Handling mode is hardcoded for PPIs, set the type using + * HW reported value. + */ + *type =3D gicv5_ppi_irq_is_level(*hwirq) ? IRQ_TYPE_LEVEL_LOW : IRQ_TYPE_= EDGE_RISING; + + return 0; +} + +static int gicv5_irq_ppi_domain_alloc(struct irq_domain *domain, unsigned = int virq, + unsigned int nr_irqs, void *arg) +{ + unsigned int type =3D IRQ_TYPE_NONE; + struct irq_fwspec *fwspec =3D arg; + irq_hw_number_t hwirq; + int ret; + + if (WARN_ON_ONCE(nr_irqs !=3D 1)) + return -EINVAL; + + ret =3D gicv5_irq_ppi_domain_translate(domain, fwspec, &hwirq, &type); + if (ret) + return ret; + + if (type & IRQ_TYPE_LEVEL_MASK) + irq_set_status_flags(virq, IRQ_LEVEL); + + irq_set_percpu_devid(virq); + irq_domain_set_info(domain, virq, hwirq, &gicv5_ppi_irq_chip, NULL, + handle_percpu_devid_irq, NULL, NULL); + + return 0; +} + +static void gicv5_irq_domain_free(struct irq_domain *domain, unsigned int = virq, + unsigned int nr_irqs) +{ + struct irq_data *d; + + if (WARN_ON_ONCE(nr_irqs !=3D 1)) + return; + + d =3D irq_domain_get_irq_data(domain, virq); + + irq_set_handler(virq, NULL); + irq_domain_reset_irq_data(d); +} + +static int gicv5_irq_ppi_domain_select(struct irq_domain *d, struct irq_fw= spec *fwspec, + enum irq_domain_bus_token bus_token) +{ + if (fwspec->fwnode !=3D d->fwnode) + return 0; + + if (fwspec->param[0] !=3D GICV5_HWIRQ_TYPE_PPI) + return 0; + + return (d =3D=3D gicv5_global_data.ppi_domain); +} + +static const struct irq_domain_ops gicv5_irq_ppi_domain_ops =3D { + .translate =3D gicv5_irq_ppi_domain_translate, + .alloc =3D gicv5_irq_ppi_domain_alloc, + .free =3D gicv5_irq_domain_free, + .select =3D gicv5_irq_ppi_domain_select +}; + +static void handle_irq_per_domain(u32 hwirq) +{ + u8 hwirq_type =3D FIELD_GET(GICV5_HWIRQ_TYPE, hwirq); + u32 hwirq_id =3D FIELD_GET(GICV5_HWIRQ_ID, hwirq); + struct irq_domain *domain; + + switch (hwirq_type) { + case GICV5_HWIRQ_TYPE_PPI: + domain =3D gicv5_global_data.ppi_domain; + break; + default: + pr_err_once("Unknown IRQ type, bail out\n"); + return; + } + + if (generic_handle_domain_irq(domain, hwirq_id)) { + pr_err_once("Could not handle, hwirq =3D 0x%x", hwirq_id); + gicv5_hwirq_eoi(hwirq_id, hwirq_type); + } +} + +static void __exception_irq_entry gicv5_handle_irq(struct pt_regs *regs) +{ + bool valid; + u32 hwirq; + u64 ia; + + ia =3D gicr_insn(CDIA); + valid =3D GICV5_GICR_CDIA_VALID(ia); + + if (!valid) + return; + + /* + * Ensure that the CDIA instruction effects (ie IRQ activation) are + * completed before handling the interrupt. + */ + gsb_ack(); + + /* + * Ensure instruction ordering between an acknowledgment and subsequent + * instructions in the IRQ handler using an ISB. + */ + isb(); + + hwirq =3D FIELD_GET(GICV5_HWIRQ_INTID, ia); + + handle_irq_per_domain(hwirq); +} + +static void gicv5_cpu_disable_interrupts(void) +{ + u64 cr0; + + cr0 =3D FIELD_PREP(ICC_CR0_EL1_EN, 0); + write_sysreg_s(cr0, SYS_ICC_CR0_EL1); +} + +static void gicv5_cpu_enable_interrupts(void) +{ + u64 cr0, pcr; + + write_sysreg_s(0, SYS_ICC_PPI_ENABLER0_EL1); + write_sysreg_s(0, SYS_ICC_PPI_ENABLER1_EL1); + + gicv5_ppi_priority_init(); + + pcr =3D FIELD_PREP(ICC_PCR_EL1_PRIORITY, GICV5_IRQ_PRI_MI); + write_sysreg_s(pcr, SYS_ICC_PCR_EL1); + + cr0 =3D FIELD_PREP(ICC_CR0_EL1_EN, 1); + write_sysreg_s(cr0, SYS_ICC_CR0_EL1); +} + +static int gicv5_starting_cpu(unsigned int cpu) +{ + if (WARN(!gicv5_cpuif_has_gcie(), + "GICv5 system components present but CPU does not have FEAT_GCIE")) + return -ENODEV; + + gicv5_cpu_enable_interrupts(); + + return 0; +} + +static void __init gicv5_free_domains(void) +{ + if (gicv5_global_data.ppi_domain) + irq_domain_remove(gicv5_global_data.ppi_domain); + + gicv5_global_data.ppi_domain =3D NULL; +} + +static int __init gicv5_init_domains(struct fwnode_handle *handle) +{ + struct irq_domain *d; + + d =3D irq_domain_create_linear(handle, PPI_NR, &gicv5_irq_ppi_domain_ops,= NULL); + if (!d) + return -ENOMEM; + + irq_domain_update_bus_token(d, DOMAIN_BUS_WIRED); + gicv5_global_data.ppi_domain =3D d; + gicv5_global_data.fwnode =3D handle; + + return 0; +} + +static void gicv5_set_cpuif_pribits(void) +{ + u64 icc_idr0 =3D read_sysreg_s(SYS_ICC_IDR0_EL1); + + switch (FIELD_GET(ICC_IDR0_EL1_PRI_BITS, icc_idr0)) { + case ICC_IDR0_EL1_PRI_BITS_4BITS: + pri_bits =3D 4; + break; + case ICC_IDR0_EL1_PRI_BITS_5BITS: + pri_bits =3D 5; + break; + default: + pr_err("Unexpected ICC_IDR0_EL1_PRI_BITS value, default to 4"); + pri_bits =3D 4; + break; + } +} + +static int __init gicv5_of_init(struct device_node *node, struct device_no= de *parent) +{ + int ret =3D gicv5_init_domains(of_fwnode_handle(node)); + if (ret) + return ret; + + gicv5_set_cpuif_pribits(); + + ret =3D gicv5_starting_cpu(smp_processor_id()); + if (ret) + goto out_dom; + + ret =3D set_handle_irq(gicv5_handle_irq); + if (ret) + goto out_int; + + return 0; + +out_int: + gicv5_cpu_disable_interrupts(); +out_dom: + gicv5_free_domains(); + + return ret; +} +IRQCHIP_DECLARE(gic_v5, "arm,gic-v5", gicv5_of_init); diff --git a/include/linux/irqchip/arm-gic-v5.h b/include/linux/irqchip/arm= -gic-v5.h new file mode 100644 index 000000000000..b08ec0308a9b --- /dev/null +++ b/include/linux/irqchip/arm-gic-v5.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2025 ARM Limited, All Rights Reserved. + */ +#ifndef __LINUX_IRQCHIP_ARM_GIC_V5_H +#define __LINUX_IRQCHIP_ARM_GIC_V5_H + +#include + +/* + * INTID handling + */ +#define GICV5_HWIRQ_ID GENMASK(23, 0) +#define GICV5_HWIRQ_TYPE GENMASK(31, 29) +#define GICV5_HWIRQ_INTID GENMASK_ULL(31, 0) + +#define GICV5_HWIRQ_TYPE_PPI UL(0x1) + +#endif --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B48D52E3372; Thu, 3 Jul 2025 10:27:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538430; cv=none; b=lQfOMVvTjHpRMeRLOzjuNrPCoeXx4OzfFQB3B9l8CzUQzuorK70DiAJkxJ+iKWqvJ8OjbZKV2tWfWy7FZRsIDIhfOmYc5IeCB+2bribwZ1LrX3uPGIBjGXwUSGWnCjJVlsFCoY7rwB4rk1+75EnEvv26MJFw0vCnkWDUUyx3miU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538430; c=relaxed/simple; bh=vm0Dl1hyjJ3h2Mc9RhWqahNVc3sEEdjpQzCpGzJ+s4k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mGQlD2HBlW5wKAvI2CC90DDhQm5tLTgK4IslDtOQL8rwuXVDvVKe6uGFq49OSWrIZvMWMZe/tS401Dkj4pMj0iyGzplSnJG2SseK2WiYjIOz9a9yT0ahGzP0hlY06J3p4VU560+sVt70XpzbX3QJ1+0FAP/dFhUa9PYKZDy6b+8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rZvtfPl/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rZvtfPl/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C8FCEC4CEED; Thu, 3 Jul 2025 10:27:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538430; bh=vm0Dl1hyjJ3h2Mc9RhWqahNVc3sEEdjpQzCpGzJ+s4k=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=rZvtfPl/ykUkpy32AyULyifj998toOjgTPaTADBluNG3dZGW7bgo/e/0SEwrnFdQQ g/fRMh6yYXZXgjpDgGgF5BiRmzONMPD0FgvGkijrVPfZ0XHWb3tcdX17l550QZ0sSz pt2F65T7MsiQrkbhFXIjfOp8zeEoCHitswaD4YRmQUOjDTLwlBgTIU2lw5fvvtxAwv tOxtMVic4DM1GKys8SS/DqptEhz52Y3dXAUhJt/BqCJz0WZXx3Q7rmx+6WZ5f9vaKw aUXzMqIrYGr9mjzCpzbjcFzm79e6+59oPKyq6pwbJ54vvJOsSKMT1gLooH/dQPO9fQ xUU5ywcL/6ZMA== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:11 +0200 Subject: [PATCH v7 21/31] irqchip/gic-v5: Add GICv5 IRS/SPI support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-21-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e The GICv5 Interrupt Routing Service (IRS) component implements interrupt management and routing in the GICv5 architecture. A GICv5 system comprises one or more IRSes, that together handle the interrupt routing and state for the system. An IRS supports Shared Peripheral Interrupts (SPIs), that are interrupt sources directly connected to the IRS; they do not rely on memory for storage. The number of supported SPIs is fixed for a given implementation and can be probed through IRS IDR registers. SPI interrupt state and routing are managed through GICv5 instructions. Each core (PE in GICv5 terms) in a GICv5 system is identified with an Interrupt AFFinity ID (IAFFID). An IRS manages a set of cores that are connected to it. Firmware provides a topology description that the driver uses to detect to which IRS a CPU (ie an IAFFID) is associated with. Use probeable information and firmware description to initialize the IRSes and implement GICv5 IRS SPIs support through an SPI-specific IRQ domain. The GICv5 IRS driver: - Probes IRSes in the system to detect SPI ranges - Associates an IRS with a set of cores connected to it - Adds an IRQchip structure for SPI handling SPIs priority is set to a value corresponding to the lowest permissible priority in the system (taking into account the implemented priority bits of the IRS and CPU interface). Since all IRQs are set to the same priority value, the value itself does not matter as long as it is a valid one. Co-developed-by: Sascha Bischoff Signed-off-by: Sascha Bischoff Co-developed-by: Timothy Hayes Signed-off-by: Timothy Hayes Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Thomas Gleixner Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/include/asm/sysreg.h | 36 +++ drivers/irqchip/Makefile | 2 +- drivers/irqchip/irq-gic-v5-irs.c | 434 +++++++++++++++++++++++++++++++++= ++++ drivers/irqchip/irq-gic-v5.c | 347 +++++++++++++++++++++++++++-- include/linux/irqchip/arm-gic-v5.h | 140 ++++++++++++ 5 files changed, 937 insertions(+), 22 deletions(-) diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysre= g.h index 36b82d74db37..efd2e7a1fbe2 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -1085,14 +1085,50 @@ /* * Definitions for GICv5 instructions */ +#define GICV5_OP_GIC_CDAFF sys_insn(1, 0, 12, 1, 3) #define GICV5_OP_GIC_CDDI sys_insn(1, 0, 12, 2, 0) +#define GICV5_OP_GIC_CDDIS sys_insn(1, 0, 12, 1, 0) +#define GICV5_OP_GIC_CDEN sys_insn(1, 0, 12, 1, 1) #define GICV5_OP_GIC_CDEOI sys_insn(1, 0, 12, 1, 7) +#define GICV5_OP_GIC_CDPEND sys_insn(1, 0, 12, 1, 4) +#define GICV5_OP_GIC_CDPRI sys_insn(1, 0, 12, 1, 2) +#define GICV5_OP_GIC_CDRCFG sys_insn(1, 0, 12, 1, 5) #define GICV5_OP_GICR_CDIA sys_insn(1, 0, 12, 3, 0) =20 +/* Definitions for GIC CDAFF */ +#define GICV5_GIC_CDAFF_IAFFID_MASK GENMASK_ULL(47, 32) +#define GICV5_GIC_CDAFF_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDAFF_IRM_MASK BIT_ULL(28) +#define GICV5_GIC_CDAFF_ID_MASK GENMASK_ULL(23, 0) + /* Definitions for GIC CDDI */ #define GICV5_GIC_CDDI_TYPE_MASK GENMASK_ULL(31, 29) #define GICV5_GIC_CDDI_ID_MASK GENMASK_ULL(23, 0) =20 +/* Definitions for GIC CDDIS */ +#define GICV5_GIC_CDDIS_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDDIS_TYPE(r) FIELD_GET(GICV5_GIC_CDDIS_TYPE_MASK, r) +#define GICV5_GIC_CDDIS_ID_MASK GENMASK_ULL(23, 0) +#define GICV5_GIC_CDDIS_ID(r) FIELD_GET(GICV5_GIC_CDDIS_ID_MASK, r) + +/* Definitions for GIC CDEN */ +#define GICV5_GIC_CDEN_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDEN_ID_MASK GENMASK_ULL(23, 0) + +/* Definitions for GIC CDPEND */ +#define GICV5_GIC_CDPEND_PENDING_MASK BIT_ULL(32) +#define GICV5_GIC_CDPEND_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDPEND_ID_MASK GENMASK_ULL(23, 0) + +/* Definitions for GIC CDPRI */ +#define GICV5_GIC_CDPRI_PRIORITY_MASK GENMASK_ULL(39, 35) +#define GICV5_GIC_CDPRI_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDPRI_ID_MASK GENMASK_ULL(23, 0) + +/* Definitions for GIC CDRCFG */ +#define GICV5_GIC_CDRCFG_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDRCFG_ID_MASK GENMASK_ULL(23, 0) + /* Definitions for GICR CDIA */ #define GICV5_GIC_CDIA_VALID_MASK BIT_ULL(32) #define GICV5_GICR_CDIA_VALID(r) FIELD_GET(GICV5_GIC_CDIA_VALID_MASK, r) diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 3d75659d99eb..7a0e6cee09e1 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -36,7 +36,7 @@ obj-$(CONFIG_ARM_GIC_V3) +=3D irq-gic-v3.o irq-gic-v3-mb= i.o irq-gic-common.o obj-$(CONFIG_ARM_GIC_V3_ITS) +=3D irq-gic-v3-its.o irq-gic-v4.o irq-gic-v= 3-its-msi-parent.o obj-$(CONFIG_ARM_GIC_V3_ITS_FSL_MC) +=3D irq-gic-v3-its-fsl-mc-msi.o obj-$(CONFIG_PARTITION_PERCPU) +=3D irq-partition-percpu.o -obj-$(CONFIG_ARM_GIC_V5) +=3D irq-gic-v5.o +obj-$(CONFIG_ARM_GIC_V5) +=3D irq-gic-v5.o irq-gic-v5-irs.o obj-$(CONFIG_HISILICON_IRQ_MBIGEN) +=3D irq-mbigen.o obj-$(CONFIG_ARM_NVIC) +=3D irq-nvic.o obj-$(CONFIG_ARM_VIC) +=3D irq-vic.o diff --git a/drivers/irqchip/irq-gic-v5-irs.c b/drivers/irqchip/irq-gic-v5-= irs.c new file mode 100644 index 000000000000..fba8efceb26e --- /dev/null +++ b/drivers/irqchip/irq-gic-v5-irs.c @@ -0,0 +1,434 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024-2025 ARM Limited, All Rights Reserved. + */ + +#define pr_fmt(fmt) "GICv5 IRS: " fmt + +#include +#include + +#include +#include + +#define IRS_FLAGS_NON_COHERENT BIT(0) + +static DEFINE_PER_CPU_READ_MOSTLY(struct gicv5_irs_chip_data *, per_cpu_ir= s_data); +static LIST_HEAD(irs_nodes); + +static u32 irs_readl_relaxed(struct gicv5_irs_chip_data *irs_data, + const u32 reg_offset) +{ + return readl_relaxed(irs_data->irs_base + reg_offset); +} + +static void irs_writel_relaxed(struct gicv5_irs_chip_data *irs_data, + const u32 val, const u32 reg_offset) +{ + writel_relaxed(val, irs_data->irs_base + reg_offset); +} + +struct iaffid_entry { + u16 iaffid; + bool valid; +}; + +static DEFINE_PER_CPU(struct iaffid_entry, cpu_iaffid); + +int gicv5_irs_cpu_to_iaffid(int cpuid, u16 *iaffid) +{ + if (!per_cpu(cpu_iaffid, cpuid).valid) { + pr_err("IAFFID for CPU %d has not been initialised\n", cpuid); + return -ENODEV; + } + + *iaffid =3D per_cpu(cpu_iaffid, cpuid).iaffid; + + return 0; +} + +struct gicv5_irs_chip_data *gicv5_irs_lookup_by_spi_id(u32 spi_id) +{ + struct gicv5_irs_chip_data *irs_data; + u32 min, max; + + list_for_each_entry(irs_data, &irs_nodes, entry) { + if (!irs_data->spi_range) + continue; + + min =3D irs_data->spi_min; + max =3D irs_data->spi_min + irs_data->spi_range - 1; + if (spi_id >=3D min && spi_id <=3D max) + return irs_data; + } + + return NULL; +} + +static int gicv5_irs_wait_for_spi_op(struct gicv5_irs_chip_data *irs_data) +{ + u32 statusr; + int ret; + + ret =3D gicv5_wait_for_op_atomic(irs_data->irs_base, GICV5_IRS_SPI_STATUS= R, + GICV5_IRS_SPI_STATUSR_IDLE, &statusr); + if (ret) + return ret; + + return !!FIELD_GET(GICV5_IRS_SPI_STATUSR_V, statusr) ? 0 : -EIO; +} + +static int gicv5_irs_wait_for_irs_pe(struct gicv5_irs_chip_data *irs_data, + bool selr) +{ + bool valid =3D true; + u32 statusr; + int ret; + + ret =3D gicv5_wait_for_op_atomic(irs_data->irs_base, GICV5_IRS_PE_STATUSR, + GICV5_IRS_PE_STATUSR_IDLE, &statusr); + if (ret) + return ret; + + if (selr) + valid =3D !!FIELD_GET(GICV5_IRS_PE_STATUSR_V, statusr); + + return valid ? 0 : -EIO; +} + +static int gicv5_irs_wait_for_pe_selr(struct gicv5_irs_chip_data *irs_data) +{ + return gicv5_irs_wait_for_irs_pe(irs_data, true); +} + +static int gicv5_irs_wait_for_pe_cr0(struct gicv5_irs_chip_data *irs_data) +{ + return gicv5_irs_wait_for_irs_pe(irs_data, false); +} + +int gicv5_spi_irq_set_type(struct irq_data *d, unsigned int type) +{ + struct gicv5_irs_chip_data *irs_data =3D d->chip_data; + u32 selr, cfgr; + bool level; + int ret; + + /* + * There is no distinction between HIGH/LOW for level IRQs + * and RISING/FALLING for edge IRQs in the architecture, + * hence consider them equivalent. + */ + switch (type) { + case IRQ_TYPE_EDGE_RISING: + case IRQ_TYPE_EDGE_FALLING: + level =3D false; + break; + case IRQ_TYPE_LEVEL_HIGH: + case IRQ_TYPE_LEVEL_LOW: + level =3D true; + break; + default: + return -EINVAL; + } + + guard(raw_spinlock)(&irs_data->spi_config_lock); + + selr =3D FIELD_PREP(GICV5_IRS_SPI_SELR_ID, d->hwirq); + irs_writel_relaxed(irs_data, selr, GICV5_IRS_SPI_SELR); + ret =3D gicv5_irs_wait_for_spi_op(irs_data); + if (ret) + return ret; + + cfgr =3D FIELD_PREP(GICV5_IRS_SPI_CFGR_TM, level); + irs_writel_relaxed(irs_data, cfgr, GICV5_IRS_SPI_CFGR); + + return gicv5_irs_wait_for_spi_op(irs_data); +} + +static int gicv5_irs_wait_for_idle(struct gicv5_irs_chip_data *irs_data) +{ + return gicv5_wait_for_op_atomic(irs_data->irs_base, GICV5_IRS_CR0, + GICV5_IRS_CR0_IDLE, NULL); +} + +int gicv5_irs_register_cpu(int cpuid) +{ + struct gicv5_irs_chip_data *irs_data; + u32 selr, cr0; + u16 iaffid; + int ret; + + ret =3D gicv5_irs_cpu_to_iaffid(cpuid, &iaffid); + if (ret) { + pr_err("IAFFID for CPU %d has not been initialised\n", cpuid); + return ret; + } + + irs_data =3D per_cpu(per_cpu_irs_data, cpuid); + if (!irs_data) { + pr_err("No IRS associated with CPU %u\n", cpuid); + return -ENXIO; + } + + selr =3D FIELD_PREP(GICV5_IRS_PE_SELR_IAFFID, iaffid); + irs_writel_relaxed(irs_data, selr, GICV5_IRS_PE_SELR); + + ret =3D gicv5_irs_wait_for_pe_selr(irs_data); + if (ret) { + pr_err("IAFFID 0x%x used in IRS_PE_SELR is invalid\n", iaffid); + return -ENXIO; + } + + cr0 =3D FIELD_PREP(GICV5_IRS_PE_CR0_DPS, 0x1); + irs_writel_relaxed(irs_data, cr0, GICV5_IRS_PE_CR0); + + ret =3D gicv5_irs_wait_for_pe_cr0(irs_data); + if (ret) + return ret; + + pr_debug("CPU %d enabled PE IAFFID 0x%x\n", cpuid, iaffid); + + return 0; +} + +static void __init gicv5_irs_init_bases(struct gicv5_irs_chip_data *irs_da= ta, + void __iomem *irs_base, + struct fwnode_handle *handle) +{ + struct device_node *np =3D to_of_node(handle); + u32 cr0, cr1; + + irs_data->fwnode =3D handle; + irs_data->irs_base =3D irs_base; + + if (of_property_read_bool(np, "dma-noncoherent")) { + /* + * A non-coherent IRS implies that some cache levels cannot be + * used coherently by the cores and GIC. Our only option is to mark + * memory attributes for the GIC as non-cacheable; by default, + * non-cacheable memory attributes imply outer-shareable + * shareability, the value written into IRS_CR1_SH is ignored. + */ + cr1 =3D FIELD_PREP(GICV5_IRS_CR1_VPED_WA, GICV5_NO_WRITE_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VPED_RA, GICV5_NO_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VMD_WA, GICV5_NO_WRITE_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VMD_RA, GICV5_NO_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VPET_RA, GICV5_NO_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VMT_RA, GICV5_NO_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_IST_WA, GICV5_NO_WRITE_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_IST_RA, GICV5_NO_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_IC, GICV5_NON_CACHE) | + FIELD_PREP(GICV5_IRS_CR1_OC, GICV5_NON_CACHE); + irs_data->flags |=3D IRS_FLAGS_NON_COHERENT; + } else { + cr1 =3D FIELD_PREP(GICV5_IRS_CR1_VPED_WA, GICV5_WRITE_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VPED_RA, GICV5_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VMD_WA, GICV5_WRITE_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VMD_RA, GICV5_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VPET_RA, GICV5_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_VMT_RA, GICV5_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_IST_WA, GICV5_WRITE_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_IST_RA, GICV5_READ_ALLOC) | + FIELD_PREP(GICV5_IRS_CR1_IC, GICV5_WB_CACHE) | + FIELD_PREP(GICV5_IRS_CR1_OC, GICV5_WB_CACHE) | + FIELD_PREP(GICV5_IRS_CR1_SH, GICV5_INNER_SHARE); + } + + irs_writel_relaxed(irs_data, cr1, GICV5_IRS_CR1); + + cr0 =3D FIELD_PREP(GICV5_IRS_CR0_IRSEN, 0x1); + irs_writel_relaxed(irs_data, cr0, GICV5_IRS_CR0); + gicv5_irs_wait_for_idle(irs_data); +} + +static int __init gicv5_irs_of_init_affinity(struct device_node *node, + struct gicv5_irs_chip_data *irs_data, + u8 iaffid_bits) +{ + /* + * Detect IAFFID<->CPU mappings from the device tree and + * record IRS<->CPU topology information. + */ + u16 iaffid_mask =3D GENMASK(iaffid_bits - 1, 0); + int ret, i, ncpus, niaffids; + + ncpus =3D of_count_phandle_with_args(node, "cpus", NULL); + if (ncpus < 0) + return -EINVAL; + + niaffids =3D of_property_count_elems_of_size(node, "arm,iaffids", + sizeof(u16)); + if (niaffids !=3D ncpus) + return -EINVAL; + + u16 *iaffids __free(kfree) =3D kcalloc(niaffids, sizeof(*iaffids), GFP_KE= RNEL); + if (!iaffids) + return -ENOMEM; + + ret =3D of_property_read_u16_array(node, "arm,iaffids", iaffids, niaffids= ); + if (ret) + return ret; + + for (i =3D 0; i < ncpus; i++) { + struct device_node *cpu_node; + int cpu; + + cpu_node =3D of_parse_phandle(node, "cpus", i); + if (WARN_ON(!cpu_node)) + continue; + + cpu =3D of_cpu_node_to_id(cpu_node); + of_node_put(cpu_node); + if (WARN_ON(cpu < 0)) + continue; + + if (iaffids[i] & ~iaffid_mask) { + pr_warn("CPU %d iaffid 0x%x exceeds IRS iaffid bits\n", + cpu, iaffids[i]); + continue; + } + + per_cpu(cpu_iaffid, cpu).iaffid =3D iaffids[i]; + per_cpu(cpu_iaffid, cpu).valid =3D true; + + /* We also know that the CPU is connected to this IRS */ + per_cpu(per_cpu_irs_data, cpu) =3D irs_data; + } + + return ret; +} + +static void irs_setup_pri_bits(u32 idr1) +{ + switch (FIELD_GET(GICV5_IRS_IDR1_PRIORITY_BITS, idr1)) { + case GICV5_IRS_IDR1_PRIORITY_BITS_1BITS: + gicv5_global_data.irs_pri_bits =3D 1; + break; + case GICV5_IRS_IDR1_PRIORITY_BITS_2BITS: + gicv5_global_data.irs_pri_bits =3D 2; + break; + case GICV5_IRS_IDR1_PRIORITY_BITS_3BITS: + gicv5_global_data.irs_pri_bits =3D 3; + break; + case GICV5_IRS_IDR1_PRIORITY_BITS_4BITS: + gicv5_global_data.irs_pri_bits =3D 4; + break; + case GICV5_IRS_IDR1_PRIORITY_BITS_5BITS: + gicv5_global_data.irs_pri_bits =3D 5; + break; + default: + pr_warn("Detected wrong IDR priority bits value 0x%lx\n", + FIELD_GET(GICV5_IRS_IDR1_PRIORITY_BITS, idr1)); + gicv5_global_data.irs_pri_bits =3D 1; + break; + } +} + +static int __init gicv5_irs_init(struct device_node *node) +{ + struct gicv5_irs_chip_data *irs_data; + void __iomem *irs_base; + u32 idr, spi_count; + u8 iaffid_bits; + int ret; + + irs_data =3D kzalloc(sizeof(*irs_data), GFP_KERNEL); + if (!irs_data) + return -ENOMEM; + + raw_spin_lock_init(&irs_data->spi_config_lock); + + ret =3D of_property_match_string(node, "reg-names", "ns-config"); + if (ret < 0) { + pr_err("%pOF: ns-config reg-name not present\n", node); + goto out_err; + } + + irs_base =3D of_io_request_and_map(node, ret, of_node_full_name(node)); + if (IS_ERR(irs_base)) { + pr_err("%pOF: unable to map GICv5 IRS registers\n", node); + ret =3D PTR_ERR(irs_base); + goto out_err; + } + + gicv5_irs_init_bases(irs_data, irs_base, &node->fwnode); + + idr =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR1); + iaffid_bits =3D FIELD_GET(GICV5_IRS_IDR1_IAFFID_BITS, idr) + 1; + + ret =3D gicv5_irs_of_init_affinity(node, irs_data, iaffid_bits); + if (ret) { + pr_err("Failed to parse CPU IAFFIDs from the device tree!\n"); + goto out_iomem; + } + + idr =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR7); + irs_data->spi_min =3D FIELD_GET(GICV5_IRS_IDR7_SPI_BASE, idr); + + idr =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR6); + irs_data->spi_range =3D FIELD_GET(GICV5_IRS_IDR6_SPI_IRS_RANGE, idr); + + if (irs_data->spi_range) { + pr_info("%s detected SPI range [%u-%u]\n", + of_node_full_name(node), + irs_data->spi_min, + irs_data->spi_min + + irs_data->spi_range - 1); + } + + /* + * Do the global setting only on the first IRS. + * Global properties (iaffid_bits, global spi count) are guaranteed to + * be consistent across IRSes by the architecture. + */ + if (list_empty(&irs_nodes)) { + + idr =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR1); + irs_setup_pri_bits(idr); + + idr =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR5); + + spi_count =3D FIELD_GET(GICV5_IRS_IDR5_SPI_RANGE, idr); + gicv5_global_data.global_spi_count =3D spi_count; + + pr_debug("Detected %u SPIs globally\n", spi_count); + } + + list_add_tail(&irs_data->entry, &irs_nodes); + + return 0; + +out_iomem: + iounmap(irs_base); +out_err: + kfree(irs_data); + return ret; +} + +void __init gicv5_irs_remove(void) +{ + struct gicv5_irs_chip_data *irs_data, *tmp_data; + + list_for_each_entry_safe(irs_data, tmp_data, &irs_nodes, entry) { + iounmap(irs_data->irs_base); + list_del(&irs_data->entry); + kfree(irs_data); + } +} + +int __init gicv5_irs_of_probe(struct device_node *parent) +{ + struct device_node *np; + int ret; + + for_each_available_child_of_node(parent, np) { + if (!of_device_is_compatible(np, "arm,gic-v5-irs")) + continue; + + ret =3D gicv5_irs_init(np); + if (ret) + pr_err("Failed to init IRS %s\n", np->full_name); + } + + return list_empty(&irs_nodes) ? -ENODEV : 0; +} diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c index 0bb940212e20..9c55ddcfa0df 100644 --- a/drivers/irqchip/irq-gic-v5.c +++ b/drivers/irqchip/irq-gic-v5.c @@ -26,12 +26,7 @@ static bool gicv5_cpuif_has_gcie(void) return this_cpu_has_cap(ARM64_HAS_GICV5_CPUIF); } =20 -struct gicv5_chip_data { - struct fwnode_handle *fwnode; - struct irq_domain *ppi_domain; -}; - -static struct gicv5_chip_data gicv5_global_data __read_mostly; +struct gicv5_chip_data gicv5_global_data __read_mostly; =20 static void gicv5_ppi_priority_init(void) { @@ -59,6 +54,30 @@ static void gicv5_ppi_priority_init(void) isb(); } =20 +static void gicv5_hwirq_init(irq_hw_number_t hwirq, u8 priority, u8 hwirq_= type) +{ + u64 cdpri, cdaff; + u16 iaffid; + int ret; + + if (hwirq_type =3D=3D GICV5_HWIRQ_TYPE_SPI) { + cdpri =3D FIELD_PREP(GICV5_GIC_CDPRI_PRIORITY_MASK, priority) | + FIELD_PREP(GICV5_GIC_CDPRI_TYPE_MASK, hwirq_type) | + FIELD_PREP(GICV5_GIC_CDPRI_ID_MASK, hwirq); + gic_insn(cdpri, CDPRI); + + ret =3D gicv5_irs_cpu_to_iaffid(smp_processor_id(), &iaffid); + + if (WARN_ON_ONCE(ret)) + return; + + cdaff =3D FIELD_PREP(GICV5_GIC_CDAFF_IAFFID_MASK, iaffid) | + FIELD_PREP(GICV5_GIC_CDAFF_TYPE_MASK, hwirq_type) | + FIELD_PREP(GICV5_GIC_CDAFF_ID_MASK, hwirq); + gic_insn(cdaff, CDAFF); + } +} + static void gicv5_ppi_irq_mask(struct irq_data *d) { u64 hwirq_id_bit =3D BIT_ULL(d->hwirq % 64); @@ -77,6 +96,32 @@ static void gicv5_ppi_irq_mask(struct irq_data *d) isb(); } =20 +static void gicv5_iri_irq_mask(struct irq_data *d, u8 hwirq_type) +{ + u64 cddis; + + cddis =3D FIELD_PREP(GICV5_GIC_CDDIS_ID_MASK, d->hwirq) | + FIELD_PREP(GICV5_GIC_CDDIS_TYPE_MASK, hwirq_type); + + gic_insn(cddis, CDDIS); + /* + * We must make sure that GIC CDDIS write effects are propagated + * immediately to make sure the disable takes effect to guarantee + * that the lazy-disabled IRQ mechanism works. + * Rule R_XCLJC states that the effects of a GIC system instruction + * complete in finite time. + * The GSB ensures completion of the GIC instruction and prevents + * loads, stores and GIC instructions from executing part of their + * functionality before the GSB SYS. + */ + gsb_sys(); +} + +static void gicv5_spi_irq_mask(struct irq_data *d) +{ + gicv5_iri_irq_mask(d, GICV5_HWIRQ_TYPE_SPI); +} + static void gicv5_ppi_irq_unmask(struct irq_data *d) { u64 hwirq_id_bit =3D BIT_ULL(d->hwirq % 64); @@ -95,6 +140,25 @@ static void gicv5_ppi_irq_unmask(struct irq_data *d) isb(); } =20 +static void gicv5_iri_irq_unmask(struct irq_data *d, u8 hwirq_type) +{ + u64 cden; + + cden =3D FIELD_PREP(GICV5_GIC_CDEN_ID_MASK, d->hwirq) | + FIELD_PREP(GICV5_GIC_CDEN_TYPE_MASK, hwirq_type); + /* + * Rule R_XCLJC states that the effects of a GIC system instruction + * complete in finite time and that's the only requirement when + * unmasking an SPI IRQ. + */ + gic_insn(cden, CDEN); +} + +static void gicv5_spi_irq_unmask(struct irq_data *d) +{ + gicv5_iri_irq_unmask(d, GICV5_HWIRQ_TYPE_SPI); +} + static void gicv5_hwirq_eoi(u32 hwirq_id, u8 hwirq_type) { u64 cddi; @@ -112,6 +176,46 @@ static void gicv5_ppi_irq_eoi(struct irq_data *d) gicv5_hwirq_eoi(d->hwirq, GICV5_HWIRQ_TYPE_PPI); } =20 +static void gicv5_spi_irq_eoi(struct irq_data *d) +{ + gicv5_hwirq_eoi(d->hwirq, GICV5_HWIRQ_TYPE_SPI); +} + +static int gicv5_iri_irq_set_affinity(struct irq_data *d, + const struct cpumask *mask_val, + bool force, u8 hwirq_type) +{ + int ret, cpuid; + u16 iaffid; + u64 cdaff; + + if (force) + cpuid =3D cpumask_first(mask_val); + else + cpuid =3D cpumask_any_and(mask_val, cpu_online_mask); + + ret =3D gicv5_irs_cpu_to_iaffid(cpuid, &iaffid); + if (ret) + return ret; + + cdaff =3D FIELD_PREP(GICV5_GIC_CDAFF_IAFFID_MASK, iaffid) | + FIELD_PREP(GICV5_GIC_CDAFF_TYPE_MASK, hwirq_type) | + FIELD_PREP(GICV5_GIC_CDAFF_ID_MASK, d->hwirq); + gic_insn(cdaff, CDAFF); + + irq_data_update_effective_affinity(d, cpumask_of(cpuid)); + + return IRQ_SET_MASK_OK_DONE; +} + +static int gicv5_spi_irq_set_affinity(struct irq_data *d, + const struct cpumask *mask_val, + bool force) +{ + return gicv5_iri_irq_set_affinity(d, mask_val, force, + GICV5_HWIRQ_TYPE_SPI); +} + enum ppi_reg { PPI_PENDING, PPI_ACTIVE, @@ -192,6 +296,46 @@ static int gicv5_ppi_irq_get_irqchip_state(struct irq_= data *d, } } =20 +static int gicv5_iri_irq_get_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool *state, u8 hwirq_type) +{ + u64 icsr, cdrcfg; + + cdrcfg =3D d->hwirq | FIELD_PREP(GICV5_GIC_CDRCFG_TYPE_MASK, hwirq_type); + + gic_insn(cdrcfg, CDRCFG); + isb(); + icsr =3D read_sysreg_s(SYS_ICC_ICSR_EL1); + + if (FIELD_GET(ICC_ICSR_EL1_F, icsr)) { + pr_err("ICSR_EL1 is invalid\n"); + return -EINVAL; + } + + switch (which) { + case IRQCHIP_STATE_PENDING: + *state =3D !!(FIELD_GET(ICC_ICSR_EL1_Pending, icsr)); + return 0; + + case IRQCHIP_STATE_ACTIVE: + *state =3D !!(FIELD_GET(ICC_ICSR_EL1_Active, icsr)); + return 0; + + default: + pr_debug("Unexpected irqchip_irq_state\n"); + return -EINVAL; + } +} + +static int gicv5_spi_irq_get_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool *state) +{ + return gicv5_iri_irq_get_irqchip_state(d, which, state, + GICV5_HWIRQ_TYPE_SPI); +} + static int gicv5_ppi_irq_set_irqchip_state(struct irq_data *d, enum irqchip_irq_state which, bool state) @@ -209,6 +353,45 @@ static int gicv5_ppi_irq_set_irqchip_state(struct irq_= data *d, } } =20 +static void gicv5_iri_irq_write_pending_state(struct irq_data *d, bool sta= te, + u8 hwirq_type) +{ + u64 cdpend; + + cdpend =3D FIELD_PREP(GICV5_GIC_CDPEND_TYPE_MASK, hwirq_type) | + FIELD_PREP(GICV5_GIC_CDPEND_ID_MASK, d->hwirq) | + FIELD_PREP(GICV5_GIC_CDPEND_PENDING_MASK, state); + + gic_insn(cdpend, CDPEND); +} + +static void gicv5_spi_irq_write_pending_state(struct irq_data *d, bool sta= te) +{ + gicv5_iri_irq_write_pending_state(d, state, GICV5_HWIRQ_TYPE_SPI); +} + +static int gicv5_spi_irq_set_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool state) +{ + switch (which) { + case IRQCHIP_STATE_PENDING: + gicv5_spi_irq_write_pending_state(d, state); + break; + default: + pr_debug("Unexpected irqchip_irq_state\n"); + return -EINVAL; + } + + return 0; +} + +static int gicv5_spi_irq_retrigger(struct irq_data *data) +{ + return !gicv5_spi_irq_set_irqchip_state(data, IRQCHIP_STATE_PENDING, + true); +} + static bool gicv5_ppi_irq_is_level(irq_hw_number_t hwirq) { u64 bit =3D BIT_ULL(hwirq % 64); @@ -227,10 +410,26 @@ static const struct irq_chip gicv5_ppi_irq_chip =3D { IRQCHIP_MASK_ON_SUSPEND, }; =20 -static int gicv5_irq_ppi_domain_translate(struct irq_domain *d, - struct irq_fwspec *fwspec, - irq_hw_number_t *hwirq, - unsigned int *type) +static const struct irq_chip gicv5_spi_irq_chip =3D { + .name =3D "GICv5-SPI", + .irq_mask =3D gicv5_spi_irq_mask, + .irq_unmask =3D gicv5_spi_irq_unmask, + .irq_eoi =3D gicv5_spi_irq_eoi, + .irq_set_type =3D gicv5_spi_irq_set_type, + .irq_set_affinity =3D gicv5_spi_irq_set_affinity, + .irq_retrigger =3D gicv5_spi_irq_retrigger, + .irq_get_irqchip_state =3D gicv5_spi_irq_get_irqchip_state, + .irq_set_irqchip_state =3D gicv5_spi_irq_set_irqchip_state, + .flags =3D IRQCHIP_SET_TYPE_MASKED | + IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_MASK_ON_SUSPEND, +}; + +static __always_inline int gicv5_irq_domain_translate(struct irq_domain *d, + struct irq_fwspec *fwspec, + irq_hw_number_t *hwirq, + unsigned int *type, + const u8 hwirq_type) { if (!is_of_node(fwspec->fwnode)) return -EINVAL; @@ -238,20 +437,39 @@ static int gicv5_irq_ppi_domain_translate(struct irq_= domain *d, if (fwspec->param_count < 3) return -EINVAL; =20 - if (fwspec->param[0] !=3D GICV5_HWIRQ_TYPE_PPI) + if (fwspec->param[0] !=3D hwirq_type) return -EINVAL; =20 *hwirq =3D fwspec->param[1]; =20 - /* - * Handling mode is hardcoded for PPIs, set the type using - * HW reported value. - */ - *type =3D gicv5_ppi_irq_is_level(*hwirq) ? IRQ_TYPE_LEVEL_LOW : IRQ_TYPE_= EDGE_RISING; + switch (hwirq_type) { + case GICV5_HWIRQ_TYPE_PPI: + /* + * Handling mode is hardcoded for PPIs, set the type using + * HW reported value. + */ + *type =3D gicv5_ppi_irq_is_level(*hwirq) ? IRQ_TYPE_LEVEL_LOW : + IRQ_TYPE_EDGE_RISING; + break; + case GICV5_HWIRQ_TYPE_SPI: + *type =3D fwspec->param[2] & IRQ_TYPE_SENSE_MASK; + break; + default: + BUILD_BUG_ON(1); + } =20 return 0; } =20 +static int gicv5_irq_ppi_domain_translate(struct irq_domain *d, + struct irq_fwspec *fwspec, + irq_hw_number_t *hwirq, + unsigned int *type) +{ + return gicv5_irq_domain_translate(d, fwspec, hwirq, type, + GICV5_HWIRQ_TYPE_PPI); +} + static int gicv5_irq_ppi_domain_alloc(struct irq_domain *domain, unsigned = int virq, unsigned int nr_irqs, void *arg) { @@ -310,6 +528,63 @@ static const struct irq_domain_ops gicv5_irq_ppi_domai= n_ops =3D { .select =3D gicv5_irq_ppi_domain_select }; =20 +static int gicv5_irq_spi_domain_translate(struct irq_domain *d, + struct irq_fwspec *fwspec, + irq_hw_number_t *hwirq, + unsigned int *type) +{ + return gicv5_irq_domain_translate(d, fwspec, hwirq, type, + GICV5_HWIRQ_TYPE_SPI); +} + +static int gicv5_irq_spi_domain_alloc(struct irq_domain *domain, unsigned = int virq, + unsigned int nr_irqs, void *arg) +{ + struct gicv5_irs_chip_data *chip_data; + unsigned int type =3D IRQ_TYPE_NONE; + struct irq_fwspec *fwspec =3D arg; + struct irq_data *irqd; + irq_hw_number_t hwirq; + int ret; + + if (WARN_ON_ONCE(nr_irqs !=3D 1)) + return -EINVAL; + + ret =3D gicv5_irq_spi_domain_translate(domain, fwspec, &hwirq, &type); + if (ret) + return ret; + + irqd =3D irq_desc_get_irq_data(irq_to_desc(virq)); + chip_data =3D gicv5_irs_lookup_by_spi_id(hwirq); + + irq_domain_set_info(domain, virq, hwirq, &gicv5_spi_irq_chip, chip_data, + handle_fasteoi_irq, NULL, NULL); + irq_set_probe(virq); + irqd_set_single_target(irqd); + + gicv5_hwirq_init(hwirq, GICV5_IRQ_PRI_MI, GICV5_HWIRQ_TYPE_SPI); + + return 0; +} + +static int gicv5_irq_spi_domain_select(struct irq_domain *d, struct irq_fw= spec *fwspec, + enum irq_domain_bus_token bus_token) +{ + if (fwspec->fwnode !=3D d->fwnode) + return 0; + + if (fwspec->param[0] !=3D GICV5_HWIRQ_TYPE_SPI) + return 0; + + return (d =3D=3D gicv5_global_data.spi_domain); +} + +static const struct irq_domain_ops gicv5_irq_spi_domain_ops =3D { + .translate =3D gicv5_irq_spi_domain_translate, + .alloc =3D gicv5_irq_spi_domain_alloc, + .free =3D gicv5_irq_domain_free, + .select =3D gicv5_irq_spi_domain_select +}; static void handle_irq_per_domain(u32 hwirq) { u8 hwirq_type =3D FIELD_GET(GICV5_HWIRQ_TYPE, hwirq); @@ -320,6 +595,9 @@ static void handle_irq_per_domain(u32 hwirq) case GICV5_HWIRQ_TYPE_PPI: domain =3D gicv5_global_data.ppi_domain; break; + case GICV5_HWIRQ_TYPE_SPI: + domain =3D gicv5_global_data.spi_domain; + break; default: pr_err_once("Unknown IRQ type, bail out\n"); return; @@ -392,19 +670,23 @@ static int gicv5_starting_cpu(unsigned int cpu) =20 gicv5_cpu_enable_interrupts(); =20 - return 0; + return gicv5_irs_register_cpu(cpu); } =20 static void __init gicv5_free_domains(void) { if (gicv5_global_data.ppi_domain) irq_domain_remove(gicv5_global_data.ppi_domain); + if (gicv5_global_data.spi_domain) + irq_domain_remove(gicv5_global_data.spi_domain); =20 gicv5_global_data.ppi_domain =3D NULL; + gicv5_global_data.spi_domain =3D NULL; } =20 static int __init gicv5_init_domains(struct fwnode_handle *handle) { + u32 spi_count =3D gicv5_global_data.global_spi_count; struct irq_domain *d; =20 d =3D irq_domain_create_linear(handle, PPI_NR, &gicv5_irq_ppi_domain_ops,= NULL); @@ -413,6 +695,20 @@ static int __init gicv5_init_domains(struct fwnode_han= dle *handle) =20 irq_domain_update_bus_token(d, DOMAIN_BUS_WIRED); gicv5_global_data.ppi_domain =3D d; + + if (spi_count) { + d =3D irq_domain_create_linear(handle, spi_count, + &gicv5_irq_spi_domain_ops, NULL); + + if (!d) { + gicv5_free_domains(); + return -ENOMEM; + } + + gicv5_global_data.spi_domain =3D d; + irq_domain_update_bus_token(d, DOMAIN_BUS_WIRED); + } + gicv5_global_data.fwnode =3D handle; =20 return 0; @@ -424,26 +720,33 @@ static void gicv5_set_cpuif_pribits(void) =20 switch (FIELD_GET(ICC_IDR0_EL1_PRI_BITS, icc_idr0)) { case ICC_IDR0_EL1_PRI_BITS_4BITS: - pri_bits =3D 4; + gicv5_global_data.cpuif_pri_bits =3D 4; break; case ICC_IDR0_EL1_PRI_BITS_5BITS: - pri_bits =3D 5; + gicv5_global_data.cpuif_pri_bits =3D 5; break; default: pr_err("Unexpected ICC_IDR0_EL1_PRI_BITS value, default to 4"); - pri_bits =3D 4; + gicv5_global_data.cpuif_pri_bits =3D 4; break; } } =20 static int __init gicv5_of_init(struct device_node *node, struct device_no= de *parent) { - int ret =3D gicv5_init_domains(of_fwnode_handle(node)); + int ret =3D gicv5_irs_of_probe(node); if (ret) return ret; =20 + ret =3D gicv5_init_domains(of_fwnode_handle(node)); + if (ret) + goto out_irs; + gicv5_set_cpuif_pribits(); =20 + pri_bits =3D min_not_zero(gicv5_global_data.cpuif_pri_bits, + gicv5_global_data.irs_pri_bits); + ret =3D gicv5_starting_cpu(smp_processor_id()); if (ret) goto out_dom; @@ -458,6 +761,8 @@ static int __init gicv5_of_init(struct device_node *nod= e, struct device_node *pa gicv5_cpu_disable_interrupts(); out_dom: gicv5_free_domains(); +out_irs: + gicv5_irs_remove(); =20 return ret; } diff --git a/include/linux/irqchip/arm-gic-v5.h b/include/linux/irqchip/arm= -gic-v5.h index b08ec0308a9b..1064a69ab33f 100644 --- a/include/linux/irqchip/arm-gic-v5.h +++ b/include/linux/irqchip/arm-gic-v5.h @@ -5,6 +5,8 @@ #ifndef __LINUX_IRQCHIP_ARM_GIC_V5_H #define __LINUX_IRQCHIP_ARM_GIC_V5_H =20 +#include + #include =20 /* @@ -15,5 +17,143 @@ #define GICV5_HWIRQ_INTID GENMASK_ULL(31, 0) =20 #define GICV5_HWIRQ_TYPE_PPI UL(0x1) +#define GICV5_HWIRQ_TYPE_SPI UL(0x3) =20 +/* + * Tables attributes + */ +#define GICV5_NO_READ_ALLOC 0b0 +#define GICV5_READ_ALLOC 0b1 +#define GICV5_NO_WRITE_ALLOC 0b0 +#define GICV5_WRITE_ALLOC 0b1 + +#define GICV5_NON_CACHE 0b00 +#define GICV5_WB_CACHE 0b01 +#define GICV5_WT_CACHE 0b10 + +#define GICV5_NON_SHARE 0b00 +#define GICV5_OUTER_SHARE 0b10 +#define GICV5_INNER_SHARE 0b11 + +/* + * IRS registers + */ +#define GICV5_IRS_IDR1 0x0004 +#define GICV5_IRS_IDR2 0x0008 +#define GICV5_IRS_IDR5 0x0014 +#define GICV5_IRS_IDR6 0x0018 +#define GICV5_IRS_IDR7 0x001c +#define GICV5_IRS_CR0 0x0080 +#define GICV5_IRS_CR1 0x0084 +#define GICV5_IRS_SPI_SELR 0x0108 +#define GICV5_IRS_SPI_CFGR 0x0114 +#define GICV5_IRS_SPI_STATUSR 0x0118 +#define GICV5_IRS_PE_SELR 0x0140 +#define GICV5_IRS_PE_STATUSR 0x0144 +#define GICV5_IRS_PE_CR0 0x0148 + +#define GICV5_IRS_IDR1_PRIORITY_BITS GENMASK(22, 20) +#define GICV5_IRS_IDR1_IAFFID_BITS GENMASK(19, 16) + +#define GICV5_IRS_IDR1_PRIORITY_BITS_1BITS 0b000 +#define GICV5_IRS_IDR1_PRIORITY_BITS_2BITS 0b001 +#define GICV5_IRS_IDR1_PRIORITY_BITS_3BITS 0b010 +#define GICV5_IRS_IDR1_PRIORITY_BITS_4BITS 0b011 +#define GICV5_IRS_IDR1_PRIORITY_BITS_5BITS 0b100 + +#define GICV5_IRS_IDR2_ISTMD_SZ GENMASK(19, 15) +#define GICV5_IRS_IDR2_ISTMD BIT(14) +#define GICV5_IRS_IDR2_IST_L2SZ GENMASK(13, 11) +#define GICV5_IRS_IDR2_IST_LEVELS BIT(10) +#define GICV5_IRS_IDR2_MIN_LPI_ID_BITS GENMASK(9, 6) +#define GICV5_IRS_IDR2_LPI BIT(5) +#define GICV5_IRS_IDR2_ID_BITS GENMASK(4, 0) + +#define GICV5_IRS_IDR5_SPI_RANGE GENMASK(24, 0) +#define GICV5_IRS_IDR6_SPI_IRS_RANGE GENMASK(24, 0) +#define GICV5_IRS_IDR7_SPI_BASE GENMASK(23, 0) +#define GICV5_IRS_CR0_IDLE BIT(1) +#define GICV5_IRS_CR0_IRSEN BIT(0) + +#define GICV5_IRS_CR1_VPED_WA BIT(15) +#define GICV5_IRS_CR1_VPED_RA BIT(14) +#define GICV5_IRS_CR1_VMD_WA BIT(13) +#define GICV5_IRS_CR1_VMD_RA BIT(12) +#define GICV5_IRS_CR1_VPET_WA BIT(11) +#define GICV5_IRS_CR1_VPET_RA BIT(10) +#define GICV5_IRS_CR1_VMT_WA BIT(9) +#define GICV5_IRS_CR1_VMT_RA BIT(8) +#define GICV5_IRS_CR1_IST_WA BIT(7) +#define GICV5_IRS_CR1_IST_RA BIT(6) +#define GICV5_IRS_CR1_IC GENMASK(5, 4) +#define GICV5_IRS_CR1_OC GENMASK(3, 2) +#define GICV5_IRS_CR1_SH GENMASK(1, 0) + +#define GICV5_IRS_SPI_STATUSR_V BIT(1) +#define GICV5_IRS_SPI_STATUSR_IDLE BIT(0) + +#define GICV5_IRS_SPI_SELR_ID GENMASK(23, 0) + +#define GICV5_IRS_SPI_CFGR_TM BIT(0) + +#define GICV5_IRS_PE_SELR_IAFFID GENMASK(15, 0) + +#define GICV5_IRS_PE_STATUSR_V BIT(1) +#define GICV5_IRS_PE_STATUSR_IDLE BIT(0) + +#define GICV5_IRS_PE_CR0_DPS BIT(0) + +/* + * Global Data structures and functions + */ +struct gicv5_chip_data { + struct fwnode_handle *fwnode; + struct irq_domain *ppi_domain; + struct irq_domain *spi_domain; + u32 global_spi_count; + u8 cpuif_pri_bits; + u8 irs_pri_bits; +}; + +extern struct gicv5_chip_data gicv5_global_data __read_mostly; + +struct gicv5_irs_chip_data { + struct list_head entry; + struct fwnode_handle *fwnode; + void __iomem *irs_base; + u32 flags; + u32 spi_min; + u32 spi_range; + raw_spinlock_t spi_config_lock; +}; + +static inline int gicv5_wait_for_op_s_atomic(void __iomem *addr, u32 offse= t, + const char *reg_s, u32 mask, + u32 *val) +{ + void __iomem *reg =3D addr + offset; + u32 tmp; + int ret; + + ret =3D readl_poll_timeout_atomic(reg, tmp, tmp & mask, 1, 10 * USEC_PER_= MSEC); + if (unlikely(ret =3D=3D -ETIMEDOUT)) { + pr_err_ratelimited("%s timeout...\n", reg_s); + return ret; + } + + if (val) + *val =3D tmp; + + return 0; +} + +#define gicv5_wait_for_op_atomic(base, reg, mask, val) \ + gicv5_wait_for_op_s_atomic(base, reg, #reg, mask, val) + +int gicv5_irs_of_probe(struct device_node *parent); +void gicv5_irs_remove(void); +int gicv5_irs_register_cpu(int cpuid); +int gicv5_irs_cpu_to_iaffid(int cpu_id, u16 *iaffid); +struct gicv5_irs_chip_data *gicv5_irs_lookup_by_spi_id(u32 spi_id); +int gicv5_spi_irq_set_type(struct irq_data *d, unsigned int type); #endif --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 31D3B2E9EDB; Thu, 3 Jul 2025 10:27:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538438; cv=none; b=nOQfH53XM9LUzKU/WOiwigWsfepWcwaAVV/L0tYgtgI3aCWtz8TUmXtSSoVbqmB1YL6xzKf8h+lK7oe15iLqNmW13QkCtMzkrJsdq4hQz0iPtoxPEIjPlgJSyVgdGJLG/7XsrGl86cjdgT/52ZFkjD1AKGaEJnHqfhZZnfl2jdI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538438; c=relaxed/simple; bh=NUCCGK6hiUQUvqPaOoNklzaPM52Rkpd9zx9s+VBXJqE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ODatCIRm+p1C/TbT0+VLGj+gkYeEkoW9CYDDgaQADtjnQL/sgyNvg3dHeiZoLCkeCzqHKusQqyFeZzfEpwtpzDO2ADYodjhdJumE3yu2NENbvNjkI54/diYE2mTDS3XDXA9D/Ij5GBbiAloeMrx0uAMfKK7KdybjucnBJ3RbNho= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VsVJwb35; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VsVJwb35" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 217D2C4CEF4; Thu, 3 Jul 2025 10:27:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538436; bh=NUCCGK6hiUQUvqPaOoNklzaPM52Rkpd9zx9s+VBXJqE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VsVJwb35SFvqfT4ciD/dqNH4TM2gvqT9CJfi96ZR2eN9h0hyhZFsxS1hUGqu/aeIo NdeuIjc880MQAy2JZ5KWK1mbx7GUC9vsUshm7z1l5tqWnuJOD13fOWiJvuA1VG44NR vIE3dEtNC7aJx3KqtAuCZb63Upls1DLeyD6UaHY0JWeKfJy5WDf9DlqFcftbhoytYq 5szgB4eBIeHe+xO/f3W8vTbwSeIH5jaiFzBRC7kRpDdTuVLO4hIY6Z0Xe/1kUnWM9F kc4EgGEYV5klPaMxfGebGTE+ubUD/oJhMETjW1TWKwHDQN6tci2bHoxAhSfLN5mjHh TYUhsRetjlB1g== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:12 +0200 Subject: [PATCH v7 22/31] irqchip/gic-v5: Add GICv5 LPI/IPI support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-22-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e An IRS supports Logical Peripheral Interrupts (LPIs) and implement Linux IPIs on top of it. LPIs are used for interrupt signals that are translated by a GICv5 ITS (Interrupt Translation Service) but also for software generated IRQs - namely interrupts that are not driven by a HW signal, ie IPIs. LPIs rely on memory storage for interrupt routing and state. LPIs state and routing information is kept in the Interrupt State Table (IST). IRSes provide support for 1- or 2-level IST tables configured to support a maximum number of interrupts that depend on the OS configuration and the HW capabilities. On systems that provide 2-level IST support, always allow the maximum number of LPIs; On systems with only 1-level support, limit the number of LPIs to 2^12 to prevent wasting memory (presumably a system that supports a 1-level only IST is not expecting a large number of interrupts). On a 2-level IST system, L2 entries are allocated on demand. The IST table memory is allocated using the kmalloc() interface; the allocation required may be smaller than a page and must be made up of contiguous physical pages if larger than a page. On systems where the IRS is not cache-coherent with the CPUs, cache mainteinance operations are executed to clean and invalidate the allocated memory to the point of coherency making it visible to the IRS components. On GICv5 systems, IPIs are implemented using LPIs. Add an LPI IRQ domain and implement an IPI-specific IRQ domain created as a child/subdomain of the LPI domain to allocate the required number of LPIs needed to implement the IPIs. IPIs are backed by LPIs, add LPIs allocation/de-allocation functions. The LPI INTID namespace is managed using an IDA to alloc/free LPI INTIDs. Associate an IPI irqchip with IPI IRQ descriptors to provide core code with the irqchip.ipi_send_single() method required to raise an IPI. Co-developed-by: Sascha Bischoff Signed-off-by: Sascha Bischoff Co-developed-by: Timothy Hayes Signed-off-by: Timothy Hayes Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Thomas Gleixner Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/include/asm/smp.h | 17 ++ arch/arm64/include/asm/sysreg.h | 6 + arch/arm64/kernel/smp.c | 17 -- drivers/irqchip/irq-gic-v5-irs.c | 364 +++++++++++++++++++++++++++++++++= ++++ drivers/irqchip/irq-gic-v5.c | 299 +++++++++++++++++++++++++++++- include/linux/irqchip/arm-gic-v5.h | 63 ++++++- 6 files changed, 746 insertions(+), 20 deletions(-) diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index d6fd6efb66a6..d48ef6d5abcc 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -50,6 +50,23 @@ struct seq_file; */ extern void smp_init_cpus(void); =20 +enum ipi_msg_type { + IPI_RESCHEDULE, + IPI_CALL_FUNC, + IPI_CPU_STOP, + IPI_CPU_STOP_NMI, + IPI_TIMER, + IPI_IRQ_WORK, + NR_IPI, + /* + * Any enum >=3D NR_IPI and < MAX_IPI is special and not tracable + * with trace_ipi_* + */ + IPI_CPU_BACKTRACE =3D NR_IPI, + IPI_KGDB_ROUNDUP, + MAX_IPI +}; + /* * Register IPI interrupts with the arch SMP code */ diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysre= g.h index efd2e7a1fbe2..948007cd3684 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -1088,6 +1088,7 @@ #define GICV5_OP_GIC_CDAFF sys_insn(1, 0, 12, 1, 3) #define GICV5_OP_GIC_CDDI sys_insn(1, 0, 12, 2, 0) #define GICV5_OP_GIC_CDDIS sys_insn(1, 0, 12, 1, 0) +#define GICV5_OP_GIC_CDHM sys_insn(1, 0, 12, 2, 1) #define GICV5_OP_GIC_CDEN sys_insn(1, 0, 12, 1, 1) #define GICV5_OP_GIC_CDEOI sys_insn(1, 0, 12, 1, 7) #define GICV5_OP_GIC_CDPEND sys_insn(1, 0, 12, 1, 4) @@ -1115,6 +1116,11 @@ #define GICV5_GIC_CDEN_TYPE_MASK GENMASK_ULL(31, 29) #define GICV5_GIC_CDEN_ID_MASK GENMASK_ULL(23, 0) =20 +/* Definitions for GIC CDHM */ +#define GICV5_GIC_CDHM_HM_MASK BIT_ULL(32) +#define GICV5_GIC_CDHM_TYPE_MASK GENMASK_ULL(31, 29) +#define GICV5_GIC_CDHM_ID_MASK GENMASK_ULL(23, 0) + /* Definitions for GIC CDPEND */ #define GICV5_GIC_CDPEND_PENDING_MASK BIT_ULL(32) #define GICV5_GIC_CDPEND_TYPE_MASK GENMASK_ULL(31, 29) diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 2c501e917d38..4797e2c70014 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -64,23 +64,6 @@ struct secondary_data secondary_data; /* Number of CPUs which aren't online, but looping in kernel text. */ static int cpus_stuck_in_kernel; =20 -enum ipi_msg_type { - IPI_RESCHEDULE, - IPI_CALL_FUNC, - IPI_CPU_STOP, - IPI_CPU_STOP_NMI, - IPI_TIMER, - IPI_IRQ_WORK, - NR_IPI, - /* - * Any enum >=3D NR_IPI and < MAX_IPI is special and not tracable - * with trace_ipi_* - */ - IPI_CPU_BACKTRACE =3D NR_IPI, - IPI_KGDB_ROUNDUP, - MAX_IPI -}; - static int ipi_irq_base __ro_after_init; static int nr_ipi __ro_after_init =3D NR_IPI; =20 diff --git a/drivers/irqchip/irq-gic-v5-irs.c b/drivers/irqchip/irq-gic-v5-= irs.c index fba8efceb26e..f00a4a6fece7 100644 --- a/drivers/irqchip/irq-gic-v5-irs.c +++ b/drivers/irqchip/irq-gic-v5-irs.c @@ -5,12 +5,20 @@ =20 #define pr_fmt(fmt) "GICv5 IRS: " fmt =20 +#include #include #include =20 #include #include =20 +/* + * Hardcoded ID_BITS limit for systems supporting only a 1-level IST + * table. Systems supporting only a 1-level IST table aren't expected + * to require more than 2^12 LPIs. Tweak as required. + */ +#define LPI_ID_BITS_LINEAR 12 + #define IRS_FLAGS_NON_COHERENT BIT(0) =20 static DEFINE_PER_CPU_READ_MOSTLY(struct gicv5_irs_chip_data *, per_cpu_ir= s_data); @@ -28,6 +36,331 @@ static void irs_writel_relaxed(struct gicv5_irs_chip_da= ta *irs_data, writel_relaxed(val, irs_data->irs_base + reg_offset); } =20 +static u64 irs_readq_relaxed(struct gicv5_irs_chip_data *irs_data, + const u32 reg_offset) +{ + return readq_relaxed(irs_data->irs_base + reg_offset); +} + +static void irs_writeq_relaxed(struct gicv5_irs_chip_data *irs_data, + const u64 val, const u32 reg_offset) +{ + writeq_relaxed(val, irs_data->irs_base + reg_offset); +} + +/* + * The polling wait (in gicv5_wait_for_op_s_atomic()) on a GIC register + * provides the memory barriers (through MMIO accessors) + * required to synchronize CPU and GIC access to IST memory. + */ +static int gicv5_irs_ist_synchronise(struct gicv5_irs_chip_data *irs_data) +{ + return gicv5_wait_for_op_atomic(irs_data->irs_base, GICV5_IRS_IST_STATUSR, + GICV5_IRS_IST_STATUSR_IDLE, NULL); +} + +static int __init gicv5_irs_init_ist_linear(struct gicv5_irs_chip_data *ir= s_data, + unsigned int lpi_id_bits, + unsigned int istsz) +{ + size_t l2istsz; + u32 n, cfgr; + void *ist; + u64 baser; + int ret; + + /* Taken from GICv5 specifications 10.2.1.13 IRS_IST_BASER */ + n =3D max(5, lpi_id_bits + 1 + istsz); + + l2istsz =3D BIT(n + 1); + /* + * Check memory requirements. For a linear IST we cap the + * number of ID bits to a value that should never exceed + * kmalloc interface memory allocation limits, so this + * check is really belt and braces. + */ + if (l2istsz > KMALLOC_MAX_SIZE) { + u8 lpi_id_cap =3D ilog2(KMALLOC_MAX_SIZE) - 2 + istsz; + + pr_warn("Limiting LPI ID bits from %u to %u\n", + lpi_id_bits, lpi_id_cap); + lpi_id_bits =3D lpi_id_cap; + l2istsz =3D KMALLOC_MAX_SIZE; + } + + ist =3D kzalloc(l2istsz, GFP_KERNEL); + if (!ist) + return -ENOMEM; + + if (irs_data->flags & IRS_FLAGS_NON_COHERENT) + dcache_clean_inval_poc((unsigned long)ist, + (unsigned long)ist + l2istsz); + else + dsb(ishst); + + cfgr =3D FIELD_PREP(GICV5_IRS_IST_CFGR_STRUCTURE, + GICV5_IRS_IST_CFGR_STRUCTURE_LINEAR) | + FIELD_PREP(GICV5_IRS_IST_CFGR_ISTSZ, istsz) | + FIELD_PREP(GICV5_IRS_IST_CFGR_L2SZ, + GICV5_IRS_IST_CFGR_L2SZ_4K) | + FIELD_PREP(GICV5_IRS_IST_CFGR_LPI_ID_BITS, lpi_id_bits); + irs_writel_relaxed(irs_data, cfgr, GICV5_IRS_IST_CFGR); + + gicv5_global_data.ist.l2 =3D false; + + baser =3D (virt_to_phys(ist) & GICV5_IRS_IST_BASER_ADDR_MASK) | + FIELD_PREP(GICV5_IRS_IST_BASER_VALID, 0x1); + irs_writeq_relaxed(irs_data, baser, GICV5_IRS_IST_BASER); + + ret =3D gicv5_irs_ist_synchronise(irs_data); + if (ret) { + kfree(ist); + return ret; + } + + return 0; +} + +static int __init gicv5_irs_init_ist_two_level(struct gicv5_irs_chip_data = *irs_data, + unsigned int lpi_id_bits, + unsigned int istsz, + unsigned int l2sz) +{ + __le64 *l1ist; + u32 cfgr, n; + size_t l1sz; + u64 baser; + int ret; + + /* Taken from GICv5 specifications 10.2.1.13 IRS_IST_BASER */ + n =3D max(5, lpi_id_bits - ((10 - istsz) + (2 * l2sz)) + 2); + + l1sz =3D BIT(n + 1); + + l1ist =3D kzalloc(l1sz, GFP_KERNEL); + if (!l1ist) + return -ENOMEM; + + if (irs_data->flags & IRS_FLAGS_NON_COHERENT) + dcache_clean_inval_poc((unsigned long)l1ist, + (unsigned long)l1ist + l1sz); + else + dsb(ishst); + + cfgr =3D FIELD_PREP(GICV5_IRS_IST_CFGR_STRUCTURE, + GICV5_IRS_IST_CFGR_STRUCTURE_TWO_LEVEL) | + FIELD_PREP(GICV5_IRS_IST_CFGR_ISTSZ, istsz) | + FIELD_PREP(GICV5_IRS_IST_CFGR_L2SZ, l2sz) | + FIELD_PREP(GICV5_IRS_IST_CFGR_LPI_ID_BITS, lpi_id_bits); + irs_writel_relaxed(irs_data, cfgr, GICV5_IRS_IST_CFGR); + + /* + * The L2SZ determine bits required at L2 level. Number of bytes + * required by metadata is reported through istsz - the number of bits + * covered by L2 entries scales accordingly. + */ + gicv5_global_data.ist.l2_size =3D BIT(11 + (2 * l2sz) + 1); + gicv5_global_data.ist.l2_bits =3D (10 - istsz) + (2 * l2sz); + gicv5_global_data.ist.l1ist_addr =3D l1ist; + gicv5_global_data.ist.l2 =3D true; + + baser =3D (virt_to_phys(l1ist) & GICV5_IRS_IST_BASER_ADDR_MASK) | + FIELD_PREP(GICV5_IRS_IST_BASER_VALID, 0x1); + irs_writeq_relaxed(irs_data, baser, GICV5_IRS_IST_BASER); + + ret =3D gicv5_irs_ist_synchronise(irs_data); + if (ret) { + kfree(l1ist); + return ret; + } + + return 0; +} + +/* + * Alloc L2 IST entries on demand. + * + * Locking/serialization is guaranteed by irqdomain core code by + * taking the hierarchical domain struct irq_domain.root->mutex. + */ +int gicv5_irs_iste_alloc(const u32 lpi) +{ + struct gicv5_irs_chip_data *irs_data; + unsigned int index; + u32 l2istr, l2bits; + __le64 *l1ist; + size_t l2size; + void *l2ist; + int ret; + + if (!gicv5_global_data.ist.l2) + return 0; + + irs_data =3D per_cpu(per_cpu_irs_data, smp_processor_id()); + if (!irs_data) + return -ENOENT; + + l2size =3D gicv5_global_data.ist.l2_size; + l2bits =3D gicv5_global_data.ist.l2_bits; + l1ist =3D gicv5_global_data.ist.l1ist_addr; + index =3D lpi >> l2bits; + + if (FIELD_GET(GICV5_ISTL1E_VALID, le64_to_cpu(l1ist[index]))) + return 0; + + l2ist =3D kzalloc(l2size, GFP_KERNEL); + if (!l2ist) + return -ENOMEM; + + l1ist[index] =3D cpu_to_le64(virt_to_phys(l2ist) & GICV5_ISTL1E_L2_ADDR_M= ASK); + + if (irs_data->flags & IRS_FLAGS_NON_COHERENT) { + dcache_clean_inval_poc((unsigned long)l2ist, + (unsigned long)l2ist + l2size); + dcache_clean_poc((unsigned long)(l1ist + index), + (unsigned long)(l1ist + index) + sizeof(*l1ist)); + } else { + dsb(ishst); + } + + l2istr =3D FIELD_PREP(GICV5_IRS_MAP_L2_ISTR_ID, lpi); + irs_writel_relaxed(irs_data, l2istr, GICV5_IRS_MAP_L2_ISTR); + + ret =3D gicv5_irs_ist_synchronise(irs_data); + if (ret) { + l1ist[index] =3D 0; + kfree(l2ist); + return ret; + } + + /* + * Make sure we invalidate the cache line pulled before the IRS + * had a chance to update the L1 entry and mark it valid. + */ + if (irs_data->flags & IRS_FLAGS_NON_COHERENT) { + /* + * gicv5_irs_ist_synchronise() includes memory + * barriers (MMIO accessors) required to guarantee that the + * following dcache invalidation is not executed before the + * IST mapping operation has completed. + */ + dcache_inval_poc((unsigned long)(l1ist + index), + (unsigned long)(l1ist + index) + sizeof(*l1ist)); + } + + return 0; +} + +/* + * Try to match the L2 IST size to the pagesize, and if this is not possib= le + * pick the smallest supported L2 size in order to minimise the requiremen= t for + * physically contiguous blocks of memory as page-sized allocations are + * guaranteed to be physically contiguous, and are by definition the easie= st to + * find. + * + * Fall back to the smallest supported size (in the event that the pagesize + * itself is not supported) again serves to make it easier to find physica= lly + * contiguous blocks of memory. + */ +static unsigned int gicv5_irs_l2_sz(u32 idr2) +{ + switch (PAGE_SIZE) { + case SZ_64K: + if (GICV5_IRS_IST_L2SZ_SUPPORT_64KB(idr2)) + return GICV5_IRS_IST_CFGR_L2SZ_64K; + fallthrough; + case SZ_4K: + if (GICV5_IRS_IST_L2SZ_SUPPORT_4KB(idr2)) + return GICV5_IRS_IST_CFGR_L2SZ_4K; + fallthrough; + case SZ_16K: + if (GICV5_IRS_IST_L2SZ_SUPPORT_16KB(idr2)) + return GICV5_IRS_IST_CFGR_L2SZ_16K; + break; + } + + if (GICV5_IRS_IST_L2SZ_SUPPORT_4KB(idr2)) + return GICV5_IRS_IST_CFGR_L2SZ_4K; + + return GICV5_IRS_IST_CFGR_L2SZ_64K; +} + +static int __init gicv5_irs_init_ist(struct gicv5_irs_chip_data *irs_data) +{ + u32 lpi_id_bits, idr2_id_bits, idr2_min_lpi_id_bits, l2_iste_sz, l2sz; + u32 l2_iste_sz_split, idr2; + bool two_levels, istmd; + u64 baser; + int ret; + + baser =3D irs_readq_relaxed(irs_data, GICV5_IRS_IST_BASER); + if (FIELD_GET(GICV5_IRS_IST_BASER_VALID, baser)) { + pr_err("IST is marked as valid already; cannot allocate\n"); + return -EPERM; + } + + idr2 =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR2); + two_levels =3D !!FIELD_GET(GICV5_IRS_IDR2_IST_LEVELS, idr2); + + idr2_id_bits =3D FIELD_GET(GICV5_IRS_IDR2_ID_BITS, idr2); + idr2_min_lpi_id_bits =3D FIELD_GET(GICV5_IRS_IDR2_MIN_LPI_ID_BITS, idr2); + + /* + * For two level tables we are always supporting the maximum allowed + * number of IDs. + * + * For 1-level tables, we should support a number of bits that + * is >=3D min_lpi_id_bits but cap it to LPI_ID_BITS_LINEAR lest + * the level 1-table gets too large and its memory allocation + * may fail. + */ + if (two_levels) { + lpi_id_bits =3D idr2_id_bits; + } else { + lpi_id_bits =3D max(LPI_ID_BITS_LINEAR, idr2_min_lpi_id_bits); + lpi_id_bits =3D min(lpi_id_bits, idr2_id_bits); + } + + /* + * Cap the ID bits according to the CPUIF supported ID bits + */ + lpi_id_bits =3D min(lpi_id_bits, gicv5_global_data.cpuif_id_bits); + + if (two_levels) + l2sz =3D gicv5_irs_l2_sz(idr2); + + istmd =3D !!FIELD_GET(GICV5_IRS_IDR2_ISTMD, idr2); + + l2_iste_sz =3D GICV5_IRS_IST_CFGR_ISTSZ_4; + + if (istmd) { + l2_iste_sz_split =3D FIELD_GET(GICV5_IRS_IDR2_ISTMD_SZ, idr2); + + if (lpi_id_bits < l2_iste_sz_split) + l2_iste_sz =3D GICV5_IRS_IST_CFGR_ISTSZ_8; + else + l2_iste_sz =3D GICV5_IRS_IST_CFGR_ISTSZ_16; + } + + /* + * Follow GICv5 specification recommendation to opt in for two + * level tables (ref: 10.2.1.14 IRS_IST_CFGR). + */ + if (two_levels && (lpi_id_bits > ((10 - l2_iste_sz) + (2 * l2sz)))) { + ret =3D gicv5_irs_init_ist_two_level(irs_data, lpi_id_bits, + l2_iste_sz, l2sz); + } else { + ret =3D gicv5_irs_init_ist_linear(irs_data, lpi_id_bits, + l2_iste_sz); + } + if (ret) + return ret; + + gicv5_init_lpis(BIT(lpi_id_bits)); + + return 0; +} + struct iaffid_entry { u16 iaffid; bool valid; @@ -362,6 +695,13 @@ static int __init gicv5_irs_init(struct device_node *n= ode) goto out_iomem; } =20 + idr =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR2); + if (WARN(!FIELD_GET(GICV5_IRS_IDR2_LPI, idr), + "LPI support not available - no IPIs, can't proceed\n")) { + ret =3D -ENODEV; + goto out_iomem; + } + idr =3D irs_readl_relaxed(irs_data, GICV5_IRS_IDR7); irs_data->spi_min =3D FIELD_GET(GICV5_IRS_IDR7_SPI_BASE, idr); =20 @@ -391,6 +731,8 @@ static int __init gicv5_irs_init(struct device_node *no= de) spi_count =3D FIELD_GET(GICV5_IRS_IDR5_SPI_RANGE, idr); gicv5_global_data.global_spi_count =3D spi_count; =20 + gicv5_init_lpi_domain(); + pr_debug("Detected %u SPIs globally\n", spi_count); } =20 @@ -409,6 +751,9 @@ void __init gicv5_irs_remove(void) { struct gicv5_irs_chip_data *irs_data, *tmp_data; =20 + gicv5_free_lpi_domain(); + gicv5_deinit_lpis(); + list_for_each_entry_safe(irs_data, tmp_data, &irs_nodes, entry) { iounmap(irs_data->irs_base); list_del(&irs_data->entry); @@ -416,6 +761,25 @@ void __init gicv5_irs_remove(void) } } =20 +int __init gicv5_irs_enable(void) +{ + struct gicv5_irs_chip_data *irs_data; + int ret; + + irs_data =3D list_first_entry_or_null(&irs_nodes, + struct gicv5_irs_chip_data, entry); + if (!irs_data) + return -ENODEV; + + ret =3D gicv5_irs_init_ist(irs_data); + if (ret) { + pr_err("Failed to init IST\n"); + return ret; + } + + return 0; +} + int __init gicv5_irs_of_probe(struct device_node *parent) { struct device_node *np; diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c index 9c55ddcfa0df..84ed13c4f2b1 100644 --- a/drivers/irqchip/irq-gic-v5.c +++ b/drivers/irqchip/irq-gic-v5.c @@ -5,7 +5,9 @@ =20 #define pr_fmt(fmt) "GICv5: " fmt =20 +#include #include +#include #include =20 #include @@ -28,6 +30,42 @@ static bool gicv5_cpuif_has_gcie(void) =20 struct gicv5_chip_data gicv5_global_data __read_mostly; =20 +static DEFINE_IDA(lpi_ida); +static u32 num_lpis __ro_after_init; + +void __init gicv5_init_lpis(u32 lpis) +{ + num_lpis =3D lpis; +} + +void __init gicv5_deinit_lpis(void) +{ + num_lpis =3D 0; +} + +static int alloc_lpi(void) +{ + if (!num_lpis) + return -ENOSPC; + + return ida_alloc_max(&lpi_ida, num_lpis - 1, GFP_KERNEL); +} + +static void release_lpi(u32 lpi) +{ + ida_free(&lpi_ida, lpi); +} + +int gicv5_alloc_lpi(void) +{ + return alloc_lpi(); +} + +void gicv5_free_lpi(u32 lpi) +{ + release_lpi(lpi); +} + static void gicv5_ppi_priority_init(void) { write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_PRI_MI), SYS_ICC_PPI_PRIORITYR0_EL1); @@ -60,7 +98,7 @@ static void gicv5_hwirq_init(irq_hw_number_t hwirq, u8 pr= iority, u8 hwirq_type) u16 iaffid; int ret; =20 - if (hwirq_type =3D=3D GICV5_HWIRQ_TYPE_SPI) { + if (hwirq_type =3D=3D GICV5_HWIRQ_TYPE_LPI || hwirq_type =3D=3D GICV5_HWI= RQ_TYPE_SPI) { cdpri =3D FIELD_PREP(GICV5_GIC_CDPRI_PRIORITY_MASK, priority) | FIELD_PREP(GICV5_GIC_CDPRI_TYPE_MASK, hwirq_type) | FIELD_PREP(GICV5_GIC_CDPRI_ID_MASK, hwirq); @@ -122,6 +160,11 @@ static void gicv5_spi_irq_mask(struct irq_data *d) gicv5_iri_irq_mask(d, GICV5_HWIRQ_TYPE_SPI); } =20 +static void gicv5_lpi_irq_mask(struct irq_data *d) +{ + gicv5_iri_irq_mask(d, GICV5_HWIRQ_TYPE_LPI); +} + static void gicv5_ppi_irq_unmask(struct irq_data *d) { u64 hwirq_id_bit =3D BIT_ULL(d->hwirq % 64); @@ -149,7 +192,7 @@ static void gicv5_iri_irq_unmask(struct irq_data *d, u8= hwirq_type) /* * Rule R_XCLJC states that the effects of a GIC system instruction * complete in finite time and that's the only requirement when - * unmasking an SPI IRQ. + * unmasking an SPI/LPI IRQ. */ gic_insn(cden, CDEN); } @@ -159,6 +202,11 @@ static void gicv5_spi_irq_unmask(struct irq_data *d) gicv5_iri_irq_unmask(d, GICV5_HWIRQ_TYPE_SPI); } =20 +static void gicv5_lpi_irq_unmask(struct irq_data *d) +{ + gicv5_iri_irq_unmask(d, GICV5_HWIRQ_TYPE_LPI); +} + static void gicv5_hwirq_eoi(u32 hwirq_id, u8 hwirq_type) { u64 cddi; @@ -181,6 +229,11 @@ static void gicv5_spi_irq_eoi(struct irq_data *d) gicv5_hwirq_eoi(d->hwirq, GICV5_HWIRQ_TYPE_SPI); } =20 +static void gicv5_lpi_irq_eoi(struct irq_data *d) +{ + gicv5_hwirq_eoi(d->hwirq, GICV5_HWIRQ_TYPE_LPI); +} + static int gicv5_iri_irq_set_affinity(struct irq_data *d, const struct cpumask *mask_val, bool force, u8 hwirq_type) @@ -216,6 +269,14 @@ static int gicv5_spi_irq_set_affinity(struct irq_data = *d, GICV5_HWIRQ_TYPE_SPI); } =20 +static int gicv5_lpi_irq_set_affinity(struct irq_data *d, + const struct cpumask *mask_val, + bool force) +{ + return gicv5_iri_irq_set_affinity(d, mask_val, force, + GICV5_HWIRQ_TYPE_LPI); +} + enum ppi_reg { PPI_PENDING, PPI_ACTIVE, @@ -336,6 +397,14 @@ static int gicv5_spi_irq_get_irqchip_state(struct irq_= data *d, GICV5_HWIRQ_TYPE_SPI); } =20 +static int gicv5_lpi_irq_get_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool *state) +{ + return gicv5_iri_irq_get_irqchip_state(d, which, state, + GICV5_HWIRQ_TYPE_LPI); +} + static int gicv5_ppi_irq_set_irqchip_state(struct irq_data *d, enum irqchip_irq_state which, bool state) @@ -370,6 +439,11 @@ static void gicv5_spi_irq_write_pending_state(struct i= rq_data *d, bool state) gicv5_iri_irq_write_pending_state(d, state, GICV5_HWIRQ_TYPE_SPI); } =20 +static void gicv5_lpi_irq_write_pending_state(struct irq_data *d, bool sta= te) +{ + gicv5_iri_irq_write_pending_state(d, state, GICV5_HWIRQ_TYPE_LPI); +} + static int gicv5_spi_irq_set_irqchip_state(struct irq_data *d, enum irqchip_irq_state which, bool state) @@ -386,12 +460,41 @@ static int gicv5_spi_irq_set_irqchip_state(struct irq= _data *d, return 0; } =20 +static int gicv5_lpi_irq_set_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, + bool state) +{ + switch (which) { + case IRQCHIP_STATE_PENDING: + gicv5_lpi_irq_write_pending_state(d, state); + break; + + default: + pr_debug("Unexpected irqchip_irq_state\n"); + return -EINVAL; + } + + return 0; +} + static int gicv5_spi_irq_retrigger(struct irq_data *data) { return !gicv5_spi_irq_set_irqchip_state(data, IRQCHIP_STATE_PENDING, true); } =20 +static int gicv5_lpi_irq_retrigger(struct irq_data *data) +{ + return !gicv5_lpi_irq_set_irqchip_state(data, IRQCHIP_STATE_PENDING, + true); +} + +static void gicv5_ipi_send_single(struct irq_data *d, unsigned int cpu) +{ + /* Mark the LPI pending */ + irq_chip_retrigger_hierarchy(d); +} + static bool gicv5_ppi_irq_is_level(irq_hw_number_t hwirq) { u64 bit =3D BIT_ULL(hwirq % 64); @@ -425,6 +528,32 @@ static const struct irq_chip gicv5_spi_irq_chip =3D { IRQCHIP_MASK_ON_SUSPEND, }; =20 +static const struct irq_chip gicv5_lpi_irq_chip =3D { + .name =3D "GICv5-LPI", + .irq_mask =3D gicv5_lpi_irq_mask, + .irq_unmask =3D gicv5_lpi_irq_unmask, + .irq_eoi =3D gicv5_lpi_irq_eoi, + .irq_set_affinity =3D gicv5_lpi_irq_set_affinity, + .irq_retrigger =3D gicv5_lpi_irq_retrigger, + .irq_get_irqchip_state =3D gicv5_lpi_irq_get_irqchip_state, + .irq_set_irqchip_state =3D gicv5_lpi_irq_set_irqchip_state, + .flags =3D IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_MASK_ON_SUSPEND, +}; + +static const struct irq_chip gicv5_ipi_irq_chip =3D { + .name =3D "GICv5-IPI", + .irq_mask =3D irq_chip_mask_parent, + .irq_unmask =3D irq_chip_unmask_parent, + .irq_eoi =3D irq_chip_eoi_parent, + .irq_set_affinity =3D irq_chip_set_affinity_parent, + .irq_get_irqchip_state =3D irq_chip_get_parent_state, + .irq_set_irqchip_state =3D irq_chip_set_parent_state, + .ipi_send_single =3D gicv5_ipi_send_single, + .flags =3D IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_MASK_ON_SUSPEND, +}; + static __always_inline int gicv5_irq_domain_translate(struct irq_domain *d, struct irq_fwspec *fwspec, irq_hw_number_t *hwirq, @@ -585,6 +714,130 @@ static const struct irq_domain_ops gicv5_irq_spi_doma= in_ops =3D { .free =3D gicv5_irq_domain_free, .select =3D gicv5_irq_spi_domain_select }; + +static void gicv5_lpi_config_reset(struct irq_data *d) +{ + u64 cdhm; + + /* + * Reset LPIs handling mode to edge by default and clear pending + * state to make sure we start the LPI with a clean state from + * previous incarnations. + */ + cdhm =3D FIELD_PREP(GICV5_GIC_CDHM_HM_MASK, 0) | + FIELD_PREP(GICV5_GIC_CDHM_TYPE_MASK, GICV5_HWIRQ_TYPE_LPI) | + FIELD_PREP(GICV5_GIC_CDHM_ID_MASK, d->hwirq); + gic_insn(cdhm, CDHM); + + gicv5_lpi_irq_write_pending_state(d, false); +} + +static int gicv5_irq_lpi_domain_alloc(struct irq_domain *domain, unsigned = int virq, + unsigned int nr_irqs, void *arg) +{ + irq_hw_number_t hwirq; + struct irq_data *irqd; + u32 *lpi =3D arg; + int ret; + + if (WARN_ON_ONCE(nr_irqs !=3D 1)) + return -EINVAL; + + hwirq =3D *lpi; + + irqd =3D irq_domain_get_irq_data(domain, virq); + + irq_domain_set_info(domain, virq, hwirq, &gicv5_lpi_irq_chip, NULL, + handle_fasteoi_irq, NULL, NULL); + irqd_set_single_target(irqd); + + ret =3D gicv5_irs_iste_alloc(hwirq); + if (ret < 0) + return ret; + + gicv5_hwirq_init(hwirq, GICV5_IRQ_PRI_MI, GICV5_HWIRQ_TYPE_LPI); + gicv5_lpi_config_reset(irqd); + + return 0; +} + +static const struct irq_domain_ops gicv5_irq_lpi_domain_ops =3D { + .alloc =3D gicv5_irq_lpi_domain_alloc, + .free =3D gicv5_irq_domain_free, +}; + +void __init gicv5_init_lpi_domain(void) +{ + struct irq_domain *d; + + d =3D irq_domain_create_tree(NULL, &gicv5_irq_lpi_domain_ops, NULL); + gicv5_global_data.lpi_domain =3D d; +} + +void __init gicv5_free_lpi_domain(void) +{ + irq_domain_remove(gicv5_global_data.lpi_domain); + gicv5_global_data.lpi_domain =3D NULL; +} + +static int gicv5_irq_ipi_domain_alloc(struct irq_domain *domain, unsigned = int virq, + unsigned int nr_irqs, void *arg) +{ + struct irq_data *irqd; + int ret, i; + u32 lpi; + + for (i =3D 0; i < nr_irqs; i++) { + ret =3D gicv5_alloc_lpi(); + if (ret < 0) + return ret; + + lpi =3D ret; + + ret =3D irq_domain_alloc_irqs_parent(domain, virq + i, 1, &lpi); + if (ret) { + gicv5_free_lpi(lpi); + return ret; + } + + irqd =3D irq_domain_get_irq_data(domain, virq + i); + + irq_domain_set_hwirq_and_chip(domain, virq + i, i, + &gicv5_ipi_irq_chip, NULL); + + irqd_set_single_target(irqd); + + irq_set_handler(virq + i, handle_percpu_irq); + } + + return 0; +} + +static void gicv5_irq_ipi_domain_free(struct irq_domain *domain, unsigned = int virq, + unsigned int nr_irqs) +{ + struct irq_data *d; + unsigned int i; + + for (i =3D 0; i < nr_irqs; i++) { + d =3D irq_domain_get_irq_data(domain, virq + i); + + if (!d) + return; + + gicv5_free_lpi(d->parent_data->hwirq); + + irq_set_handler(virq + i, NULL); + irq_domain_reset_irq_data(d); + irq_domain_free_irqs_parent(domain, virq + i, 1); + } +} + +static const struct irq_domain_ops gicv5_irq_ipi_domain_ops =3D { + .alloc =3D gicv5_irq_ipi_domain_alloc, + .free =3D gicv5_irq_ipi_domain_free, +}; + static void handle_irq_per_domain(u32 hwirq) { u8 hwirq_type =3D FIELD_GET(GICV5_HWIRQ_TYPE, hwirq); @@ -598,6 +851,9 @@ static void handle_irq_per_domain(u32 hwirq) case GICV5_HWIRQ_TYPE_SPI: domain =3D gicv5_global_data.spi_domain; break; + case GICV5_HWIRQ_TYPE_LPI: + domain =3D gicv5_global_data.lpi_domain; + break; default: pr_err_once("Unknown IRQ type, bail out\n"); return; @@ -679,9 +935,12 @@ static void __init gicv5_free_domains(void) irq_domain_remove(gicv5_global_data.ppi_domain); if (gicv5_global_data.spi_domain) irq_domain_remove(gicv5_global_data.spi_domain); + if (gicv5_global_data.ipi_domain) + irq_domain_remove(gicv5_global_data.ipi_domain); =20 gicv5_global_data.ppi_domain =3D NULL; gicv5_global_data.spi_domain =3D NULL; + gicv5_global_data.ipi_domain =3D NULL; } =20 static int __init gicv5_init_domains(struct fwnode_handle *handle) @@ -709,6 +968,19 @@ static int __init gicv5_init_domains(struct fwnode_han= dle *handle) irq_domain_update_bus_token(d, DOMAIN_BUS_WIRED); } =20 + if (!WARN(!gicv5_global_data.lpi_domain, + "LPI domain uninitialized, can't set up IPIs")) { + d =3D irq_domain_create_hierarchy(gicv5_global_data.lpi_domain, + 0, GICV5_IPIS_PER_CPU * nr_cpu_ids, + NULL, &gicv5_irq_ipi_domain_ops, + NULL); + + if (!d) { + gicv5_free_domains(); + return -ENOMEM; + } + gicv5_global_data.ipi_domain =3D d; + } gicv5_global_data.fwnode =3D handle; =20 return 0; @@ -732,6 +1004,24 @@ static void gicv5_set_cpuif_pribits(void) } } =20 +static void gicv5_set_cpuif_idbits(void) +{ + u32 icc_idr0 =3D read_sysreg_s(SYS_ICC_IDR0_EL1); + + switch (FIELD_GET(ICC_IDR0_EL1_ID_BITS, icc_idr0)) { + case ICC_IDR0_EL1_ID_BITS_16BITS: + gicv5_global_data.cpuif_id_bits =3D 16; + break; + case ICC_IDR0_EL1_ID_BITS_24BITS: + gicv5_global_data.cpuif_id_bits =3D 24; + break; + default: + pr_err("Unexpected ICC_IDR0_EL1_ID_BITS value, default to 16"); + gicv5_global_data.cpuif_id_bits =3D 16; + break; + } +} + static int __init gicv5_of_init(struct device_node *node, struct device_no= de *parent) { int ret =3D gicv5_irs_of_probe(node); @@ -743,6 +1033,7 @@ static int __init gicv5_of_init(struct device_node *no= de, struct device_node *pa goto out_irs; =20 gicv5_set_cpuif_pribits(); + gicv5_set_cpuif_idbits(); =20 pri_bits =3D min_not_zero(gicv5_global_data.cpuif_pri_bits, gicv5_global_data.irs_pri_bits); @@ -755,6 +1046,10 @@ static int __init gicv5_of_init(struct device_node *n= ode, struct device_node *pa if (ret) goto out_int; =20 + ret =3D gicv5_irs_enable(); + if (ret) + goto out_int; + return 0; =20 out_int: diff --git a/include/linux/irqchip/arm-gic-v5.h b/include/linux/irqchip/arm= -gic-v5.h index 1064a69ab33f..680eed794a35 100644 --- a/include/linux/irqchip/arm-gic-v5.h +++ b/include/linux/irqchip/arm-gic-v5.h @@ -7,8 +7,12 @@ =20 #include =20 +#include +#include #include =20 +#define GICV5_IPIS_PER_CPU MAX_IPI + /* * INTID handling */ @@ -17,6 +21,7 @@ #define GICV5_HWIRQ_INTID GENMASK_ULL(31, 0) =20 #define GICV5_HWIRQ_TYPE_PPI UL(0x1) +#define GICV5_HWIRQ_TYPE_LPI UL(0x2) #define GICV5_HWIRQ_TYPE_SPI UL(0x3) =20 /* @@ -36,7 +41,7 @@ #define GICV5_INNER_SHARE 0b11 =20 /* - * IRS registers + * IRS registers and tables structures */ #define GICV5_IRS_IDR1 0x0004 #define GICV5_IRS_IDR2 0x0008 @@ -51,6 +56,10 @@ #define GICV5_IRS_PE_SELR 0x0140 #define GICV5_IRS_PE_STATUSR 0x0144 #define GICV5_IRS_PE_CR0 0x0148 +#define GICV5_IRS_IST_BASER 0x0180 +#define GICV5_IRS_IST_CFGR 0x0190 +#define GICV5_IRS_IST_STATUSR 0x0194 +#define GICV5_IRS_MAP_L2_ISTR 0x01c0 =20 #define GICV5_IRS_IDR1_PRIORITY_BITS GENMASK(22, 20) #define GICV5_IRS_IDR1_IAFFID_BITS GENMASK(19, 16) @@ -72,6 +81,11 @@ #define GICV5_IRS_IDR5_SPI_RANGE GENMASK(24, 0) #define GICV5_IRS_IDR6_SPI_IRS_RANGE GENMASK(24, 0) #define GICV5_IRS_IDR7_SPI_BASE GENMASK(23, 0) + +#define GICV5_IRS_IST_L2SZ_SUPPORT_4KB(r) FIELD_GET(BIT(11), (r)) +#define GICV5_IRS_IST_L2SZ_SUPPORT_16KB(r) FIELD_GET(BIT(12), (r)) +#define GICV5_IRS_IST_L2SZ_SUPPORT_64KB(r) FIELD_GET(BIT(13), (r)) + #define GICV5_IRS_CR0_IDLE BIT(1) #define GICV5_IRS_CR0_IRSEN BIT(0) =20 @@ -103,6 +117,33 @@ =20 #define GICV5_IRS_PE_CR0_DPS BIT(0) =20 +#define GICV5_IRS_IST_STATUSR_IDLE BIT(0) + +#define GICV5_IRS_IST_CFGR_STRUCTURE BIT(16) +#define GICV5_IRS_IST_CFGR_ISTSZ GENMASK(8, 7) +#define GICV5_IRS_IST_CFGR_L2SZ GENMASK(6, 5) +#define GICV5_IRS_IST_CFGR_LPI_ID_BITS GENMASK(4, 0) + +#define GICV5_IRS_IST_CFGR_STRUCTURE_LINEAR 0b0 +#define GICV5_IRS_IST_CFGR_STRUCTURE_TWO_LEVEL 0b1 + +#define GICV5_IRS_IST_CFGR_ISTSZ_4 0b00 +#define GICV5_IRS_IST_CFGR_ISTSZ_8 0b01 +#define GICV5_IRS_IST_CFGR_ISTSZ_16 0b10 + +#define GICV5_IRS_IST_CFGR_L2SZ_4K 0b00 +#define GICV5_IRS_IST_CFGR_L2SZ_16K 0b01 +#define GICV5_IRS_IST_CFGR_L2SZ_64K 0b10 + +#define GICV5_IRS_IST_BASER_ADDR_MASK GENMASK_ULL(55, 6) +#define GICV5_IRS_IST_BASER_VALID BIT_ULL(0) + +#define GICV5_IRS_MAP_L2_ISTR_ID GENMASK(23, 0) + +#define GICV5_ISTL1E_VALID BIT_ULL(0) + +#define GICV5_ISTL1E_L2_ADDR_MASK GENMASK_ULL(55, 12) + /* * Global Data structures and functions */ @@ -110,9 +151,18 @@ struct gicv5_chip_data { struct fwnode_handle *fwnode; struct irq_domain *ppi_domain; struct irq_domain *spi_domain; + struct irq_domain *lpi_domain; + struct irq_domain *ipi_domain; u32 global_spi_count; u8 cpuif_pri_bits; + u8 cpuif_id_bits; u8 irs_pri_bits; + struct { + __le64 *l1ist_addr; + u32 l2_size; + u8 l2_bits; + bool l2; + } ist; }; =20 extern struct gicv5_chip_data gicv5_global_data __read_mostly; @@ -150,10 +200,21 @@ static inline int gicv5_wait_for_op_s_atomic(void __i= omem *addr, u32 offset, #define gicv5_wait_for_op_atomic(base, reg, mask, val) \ gicv5_wait_for_op_s_atomic(base, reg, #reg, mask, val) =20 +void __init gicv5_init_lpi_domain(void); +void __init gicv5_free_lpi_domain(void); + int gicv5_irs_of_probe(struct device_node *parent); void gicv5_irs_remove(void); +int gicv5_irs_enable(void); int gicv5_irs_register_cpu(int cpuid); int gicv5_irs_cpu_to_iaffid(int cpu_id, u16 *iaffid); struct gicv5_irs_chip_data *gicv5_irs_lookup_by_spi_id(u32 spi_id); int gicv5_spi_irq_set_type(struct irq_data *d, unsigned int type); +int gicv5_irs_iste_alloc(u32 lpi); + +void gicv5_init_lpis(u32 max); +void gicv5_deinit_lpis(void); + +int gicv5_alloc_lpi(void); +void gicv5_free_lpi(u32 lpi); #endif --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 870222EA176; Thu, 3 Jul 2025 10:27:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538442; cv=none; b=dTeHH/2yvLfREC7VRG4AtY4EyO5PbAdTCEK/FUOj70k9UMJyZVQfmch93yby+En8fba+zQpSS8Dh48RK1wlLXDaffS699fhf/ixecyVlD7rBJDmogilke6G04YxxtoroGCUO19xm/lhcZzw4+cmR3viFGv96thbwGqY211nMpm8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538442; c=relaxed/simple; bh=xP1ZSDvdEMNzLFTksEUUUoXYt9M+SQ6BRBD+ihLwiLw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Mup/6CeKa8CkixC3/wXTlWb9R0xOUqcPENmU6g5OkAGCudsMRfueIf6r0RhUp5T5JeAKY+O0x6r5Hi/t2EPKUACXtW79TpP8LRZsfsw8oyTEKnErENhcjphYbgLK60MpeJuBBFAcoxT/rwtR5Tmzc0RHR2gJhZqSiQhgV22KRDw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=uxmPvPSp; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="uxmPvPSp" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3BADBC4CEFA; Thu, 3 Jul 2025 10:27:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538442; bh=xP1ZSDvdEMNzLFTksEUUUoXYt9M+SQ6BRBD+ihLwiLw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=uxmPvPSpq33kyeY4be5Z2tqaZ5bDx4d3LlGrIKmUr5634blz9o5VEZeSLXUrMS1nZ mhH11KUbpxOkDlCQlJs2yiKoECjGL8Pzm7npRb+rjy/A3SUxXXyp2oHqRLV74lKMMv g8fY+nOfY3FFnsfER/ALJ2DQtFemxK5Uzf+kITaq/WHIZ7oEsFRXkqrsAJi/fxBgua wEC9e/S5elECcAptXiOMht8j6MuwPWcF37gdyiv/b0JkyTJ1HEvjcryVM8pCgGxAUO JBPlUGzstqUI795XYxO5g1usxHGR5qmD5MoA488hPKCIt24HkB5C2hjZnrfPader6g T+2kfttwTkpIg== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:13 +0200 Subject: [PATCH v7 23/31] irqchip/gic-v5: Enable GICv5 SMP booting Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-23-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Set up IPIs by allocating IPI IRQs for all cpus and call into arm64 core code to initialise IPIs IRQ descriptors and request the related IRQ. Implement hotplug callback to enable interrupts on a cpu and register the cpu with an IRS. Co-developed-by: Sascha Bischoff Signed-off-by: Sascha Bischoff Co-developed-by: Timothy Hayes Signed-off-by: Timothy Hayes Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Thomas Gleixner Cc: Marc Zyngier --- drivers/irqchip/irq-gic-v5.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c index 84ed13c4f2b1..97ff935d79bd 100644 --- a/drivers/irqchip/irq-gic-v5.c +++ b/drivers/irqchip/irq-gic-v5.c @@ -5,6 +5,7 @@ =20 #define pr_fmt(fmt) "GICv5: " fmt =20 +#include #include #include #include @@ -918,6 +919,8 @@ static void gicv5_cpu_enable_interrupts(void) write_sysreg_s(cr0, SYS_ICC_CR0_EL1); } =20 +static int base_ipi_virq; + static int gicv5_starting_cpu(unsigned int cpu) { if (WARN(!gicv5_cpuif_has_gcie(), @@ -929,6 +932,22 @@ static int gicv5_starting_cpu(unsigned int cpu) return gicv5_irs_register_cpu(cpu); } =20 +static void __init gicv5_smp_init(void) +{ + unsigned int num_ipis =3D GICV5_IPIS_PER_CPU * nr_cpu_ids; + + cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_GIC_STARTING, + "irqchip/arm/gicv5:starting", + gicv5_starting_cpu, NULL); + + base_ipi_virq =3D irq_domain_alloc_irqs(gicv5_global_data.ipi_domain, + num_ipis, NUMA_NO_NODE, NULL); + if (WARN(base_ipi_virq <=3D 0, "IPI IRQ allocation was not successful")) + return; + + set_smp_ipi_range_percpu(base_ipi_virq, GICV5_IPIS_PER_CPU, nr_cpu_ids); +} + static void __init gicv5_free_domains(void) { if (gicv5_global_data.ppi_domain) @@ -1050,6 +1069,8 @@ static int __init gicv5_of_init(struct device_node *n= ode, struct device_node *pa if (ret) goto out_int; =20 + gicv5_smp_init(); + return 0; =20 out_int: --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A8A642E54A3; Thu, 3 Jul 2025 10:27:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538447; cv=none; b=ZbpMzcmynzOtPxLlrXNjTdHIZyt1R3Q+3xLPDwhAHhfn4M1jtGBhgyslBLcKngzMtc6nJ9zehQNhpWRImTL+j3cyjZ1VV+FpgRzGEFYLajs8KCHimgZDSl+f1UedI0fZ8Up1/b3dSVOpcgwLQYifY1UzNvHkNzs5gO2uOx+UVCs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538447; c=relaxed/simple; bh=DChQwWXvs3tE8B+jpm3p7q+cSXi9YVq9StAkRX8XLr8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FiD3jXqEod94sIqrudgDlgoC8WOV4w3MmbbglbGV6ILrI8Sc6HgOzFw2tKFre0v8NLKzx4PlbsmLfhlws3SgdF1srVbKoQjpOMMGng+vzU+6Y+54NmYxHdcAn/5MEGNpywp2hyw1KIPM1Xprkyd1ZAFlxeiHRekWGAPprjWeXEk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mJiSWJHb; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mJiSWJHb" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 85B21C4CEE3; Thu, 3 Jul 2025 10:27:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538447; bh=DChQwWXvs3tE8B+jpm3p7q+cSXi9YVq9StAkRX8XLr8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=mJiSWJHbV0OO0RGsSqGg8xwEU7oc30gH/MunHTuNLIT2ezbdIi4/y9UnFvOUpijKm 9XnhyhhdtUub0PitHfrLibSPJAQqKJVvsCZZXcmxtk5CZl2oIIAjKt1osi8dVHYpVf g9PRlwpO3+U8nD/3E2C8YpCzYZtO6h2o/mPwSr19idZynLNJXsnj9BZnLoiPVA2Oib YfH1rXbp0MsotBDTRJyBHkZI3Q+qwyOJPhmFOBdnWGWCPzbMbYj+aeNpHm9e3WyDG6 MlDt28xttTeY5I1sjEh+ArAweZgBJYl+AOZMQfNIFwLjobmVP89sKhVPbB8CudI6X3 meMA7p9anJBHg== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:14 +0200 Subject: [PATCH v7 24/31] of/irq: Add of_msi_xlate() helper function Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-24-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Add an of_msi_xlate() helper that maps a device ID and returns the device node of the MSI controller the device ID is mapped to. Required by core functions that need an MSI controller device node pointer at the same time as a mapped device ID, of_msi_map_id() is not sufficient for that purpose. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Rob Herring Cc: Marc Zyngier Reviewed-by: Rob Herring (Arm) --- drivers/of/irq.c | 22 +++++++++++++++++----- include/linux/of_irq.h | 5 +++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/of/irq.c b/drivers/of/irq.c index f8ad79b9b1c9..74aaea61de13 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -670,8 +670,20 @@ void __init of_irq_init(const struct of_device_id *mat= ches) } } =20 -static u32 __of_msi_map_id(struct device *dev, struct device_node **np, - u32 id_in) +/** + * of_msi_xlate - map a MSI ID and find relevant MSI controller node + * @dev: device for which the mapping is to be done. + * @msi_np: Pointer to store the MSI controller node + * @id_in: Device ID. + * + * Walk up the device hierarchy looking for devices with a "msi-map" + * property. If found, apply the mapping to @id_in. @msi_np pointed + * value must be NULL on entry, if an MSI controller is found @msi_np is + * initialized to the MSI controller node with a reference held. + * + * Returns: The mapped MSI id. + */ +u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u32 id_i= n) { struct device *parent_dev; u32 id_out =3D id_in; @@ -682,7 +694,7 @@ static u32 __of_msi_map_id(struct device *dev, struct d= evice_node **np, */ for (parent_dev =3D dev; parent_dev; parent_dev =3D parent_dev->parent) if (!of_map_id(parent_dev->of_node, id_in, "msi-map", - "msi-map-mask", np, &id_out)) + "msi-map-mask", msi_np, &id_out)) break; return id_out; } @@ -700,7 +712,7 @@ static u32 __of_msi_map_id(struct device *dev, struct d= evice_node **np, */ u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_i= n) { - return __of_msi_map_id(dev, &msi_np, id_in); + return of_msi_xlate(dev, &msi_np, id_in); } =20 /** @@ -719,7 +731,7 @@ struct irq_domain *of_msi_map_get_device_domain(struct = device *dev, u32 id, { struct device_node *np =3D NULL; =20 - __of_msi_map_id(dev, &np, id); + of_msi_xlate(dev, &np, id); return irq_find_matching_host(np, bus_token); } =20 diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index 6337ad4e5fe8..a480063c9cb1 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h @@ -54,6 +54,7 @@ extern struct irq_domain *of_msi_map_get_device_domain(st= ruct device *dev, u32 id, u32 bus_token); extern void of_msi_configure(struct device *dev, const struct device_node = *np); +extern u32 of_msi_xlate(struct device *dev, struct device_node **msi_np, u= 32 id_in); u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_i= n); #else static inline void of_irq_init(const struct of_device_id *matches) @@ -100,6 +101,10 @@ static inline struct irq_domain *of_msi_map_get_device= _domain(struct device *dev static inline void of_msi_configure(struct device *dev, struct device_node= *np) { } +static inline u32 of_msi_xlate(struct device *dev, struct device_node **ms= i_np, u32 id_in) +{ + return id_in; +} static inline u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in) { --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2248B2E3AE9; Thu, 3 Jul 2025 10:27:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538453; cv=none; b=l9Yc3lcfwwbUVxtsDNVmAN2lMo8OrrEseEwqzzY12uzgcBa6PvVK8bjUPCXYNqhrHCkM0+cRxqxlWQnTh0JB+oWt/JFM4p8peFQjQwnFV3FPW8gD05aM+LJjf9dkgpyB2Z5rUM562es3XVOAzCWXmbguZbHV5Xcd//J8opnD7R8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538453; c=relaxed/simple; bh=kcQzsER7QdASrb9daMHpXtsDHIwhK/zyXrrP1v57pPY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Kcd+alE8WDbyCZ9wVf+4U6vhkToNhrZor2C+YmMg0GY6kI5bkUOikvUDDMAv8a98KDZkOF0jhcMNj+PjwgZrOYfKNpR2UYhh86/VBNSxjTUS5GCTkOOnXD6M+p1rMzLQg7Vwkz4SsYUWjmzDQFK8/8a4VtsdEmj15ChQwtnKdG8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LDiIwa/A; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="LDiIwa/A" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D0268C4CEE3; Thu, 3 Jul 2025 10:27:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538452; bh=kcQzsER7QdASrb9daMHpXtsDHIwhK/zyXrrP1v57pPY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=LDiIwa/ApQJbdkfprm22n+4WcQLTw0PmULQUgVooIItke6uzDx6Ah/iZdwqiZ7nr1 Wjs7LgJ1ApCZT01xDU8lBh/DmFdM2BixPYAHNw31pDkBsX9C7ESIktnM7Po37jbZ4/ B+gEFmuepvcllGOF5Wuhjh96QGwWJsXeLj9sBvEWm1YqN9zIqy4+KBrLBSiHo3nBEC Q/oJauRvHzdIrWigLwPbIMRqiuoNSEdcBosNKfioan6MDwsFkerl2GVkSgIpFw9/r6 7S0xiV4sP/xT7t/p0dlEDUZr15MhQqwF5vfJPlgN6tb2ckGhNLpVoT06++MzI4Y2kV sdqBVjBZk26+w== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:15 +0200 Subject: [PATCH v7 25/31] PCI/MSI: Add pci_msi_map_rid_ctlr_node() helper function Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-25-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e IRQchip drivers need a PCI/MSI function to map a RID to a MSI controller deviceID namespace and at the same time retrieve the struct device_node pointer of the MSI controller the RID is mapped to. Add pci_msi_map_rid_ctlr_node() to achieve this purpose. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Thomas Gleixner Cc Bjorn Helgaas Cc: Marc Zyngier --- drivers/pci/msi/irqdomain.c | 20 ++++++++++++++++++++ include/linux/msi.h | 1 + 2 files changed, 21 insertions(+) diff --git a/drivers/pci/msi/irqdomain.c b/drivers/pci/msi/irqdomain.c index c05152733993..8a6e80d3963a 100644 --- a/drivers/pci/msi/irqdomain.c +++ b/drivers/pci/msi/irqdomain.c @@ -427,6 +427,26 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *doma= in, struct pci_dev *pdev) return rid; } =20 +/** + * pci_msi_map_rid_ctlr_node - Get the MSI controller node and MSI request= er id (RID) + * @pdev: The PCI device + * @node: Pointer to store the MSI controller device node + * + * Use the firmware data to find the MSI controller node for @pdev. + * If found map the RID and initialize @node with it. @node value must + * be set to NULL on entry. + * + * Returns: The RID. + */ +u32 pci_msi_map_rid_ctlr_node(struct pci_dev *pdev, struct device_node **n= ode) +{ + u32 rid =3D pci_dev_id(pdev); + + pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); + + return of_msi_xlate(&pdev->dev, node, rid); +} + /** * pci_msi_get_device_domain - Get the MSI domain for a given PCI device * @pdev: The PCI device diff --git a/include/linux/msi.h b/include/linux/msi.h index 6863540f4b71..a418e2695b05 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -705,6 +705,7 @@ struct irq_domain *pci_msi_create_irq_domain(struct fwn= ode_handle *fwnode, struct msi_domain_info *info, struct irq_domain *parent); u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *= pdev); +u32 pci_msi_map_rid_ctlr_node(struct pci_dev *pdev, struct device_node **n= ode); struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev); #else /* CONFIG_PCI_MSI */ static inline struct irq_domain *pci_msi_get_device_domain(struct pci_dev = *pdev) --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2966A2E54BF; Thu, 3 Jul 2025 10:27:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538458; cv=none; b=G+UbbO3cEySl+0YNBjEiiA70RydSfBfdzqk5B2MeoqJYME2xODwmETQ4XDmo+YR97h3IelqR8LFp8YzhkXrCWlk8wfqjimuU868bLv1ePKsaValS+ZQJ2zVw6p8dNzGYUd3IjpOU0/wf0p9M5eUiAHHW8qhpki/mg9UvZmQtxIE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538458; c=relaxed/simple; bh=tkMcRUIDNj0nEgyr++8PL3P4fcZsx1AILTo8bVztxoU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dFnh0PI283B1CvzRe4Bp/D9I8giVxAkzp5fNx8YnlbWbO9r870Dnr5aI0fIxZCweNR+UM9AKF80aTSt2rlsnV6kgtXSm0XAauY5DhFSCYzh9bZwPsbemH6u0RcEOgTkNoUCFS4RM8i8OXt05xtPRmVyYAlW6YIn1VIjyxS2gQ88= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FJY58TqS; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FJY58TqS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 38C40C4CEEB; Thu, 3 Jul 2025 10:27:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538458; bh=tkMcRUIDNj0nEgyr++8PL3P4fcZsx1AILTo8bVztxoU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=FJY58TqSjZ5RRmmELp8KPS8NJo5Eqo77tru+p+AiS+hrM0+iKUvlK+MB4VE5pGBfJ ORBd5DEVacHRzeHpGKiQlrNSvVbFpuReNJIV34jYwUmKR6ezzMs300HhRGNDXGoORK SJhi1a/tNGIBf02hSyE/4AebSCcmr5wqA3xxq3DGFpcJ0b/hNJHtIjkOVf5Cks/IuF 4zn6Rn9CjmwKgHjqKrNyj+ITl3FwyBx0EP8/OkOhvze5OS2LgScuYkIJupyNELjRXl T4mOekeBCtqcYYTD2X4/mniulBVbAoaiwQHLSwXEHt2bB2h+vbYBOWw13XUz8KjMv1 4MgkwH/z01EzA== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:16 +0200 Subject: [PATCH v7 26/31] irqchip/gic-v3: Rename GICv3 ITS MSI parent Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-26-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e The GICv5 ITS will reuse some GICv3 ITS MSI parent functions therefore it makes sense to keep the code functionality in a compilation unit shared by the two drivers. Rename the GICv3 ITS MSI parent file and update the related Kconfig/Makefile entries to pave the way for code sharing. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Thomas Gleixner Cc: Marc Zyngier --- drivers/irqchip/Kconfig | 4 ++++ drivers/irqchip/Makefile | 3 ++- drivers/irqchip/irq-gic-common.h | 2 -- .../{irq-gic-v3-its-msi-parent.c =3D> irq-gic-its-msi-parent.c} | 2 +- drivers/irqchip/irq-gic-its-msi-parent.h | 11 +++++++= ++++ drivers/irqchip/irq-gic-v3-its.c | 1 + 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 3e4fb08b7a4d..f9eae1a645c9 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -41,10 +41,14 @@ config ARM_GIC_V3 select HAVE_ARM_SMCCC_DISCOVERY select IRQ_MSI_IOMMU =20 +config ARM_GIC_ITS_PARENT + bool + config ARM_GIC_V3_ITS bool select GENERIC_MSI_IRQ select IRQ_MSI_LIB + select ARM_GIC_ITS_PARENT default ARM_GIC_V3 select IRQ_MSI_IOMMU =20 diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 7a0e6cee09e1..3ce6ea9a371b 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -33,7 +33,8 @@ obj-$(CONFIG_ARCH_REALVIEW) +=3D irq-gic-realview.o obj-$(CONFIG_IRQ_MSI_LIB) +=3D irq-msi-lib.o obj-$(CONFIG_ARM_GIC_V2M) +=3D irq-gic-v2m.o obj-$(CONFIG_ARM_GIC_V3) +=3D irq-gic-v3.o irq-gic-v3-mbi.o irq-gic-commo= n.o -obj-$(CONFIG_ARM_GIC_V3_ITS) +=3D irq-gic-v3-its.o irq-gic-v4.o irq-gic-v= 3-its-msi-parent.o +obj-$(CONFIG_ARM_GIC_ITS_PARENT) +=3D irq-gic-its-msi-parent.o +obj-$(CONFIG_ARM_GIC_V3_ITS) +=3D irq-gic-v3-its.o irq-gic-v4.o obj-$(CONFIG_ARM_GIC_V3_ITS_FSL_MC) +=3D irq-gic-v3-its-fsl-mc-msi.o obj-$(CONFIG_PARTITION_PERCPU) +=3D irq-partition-percpu.o obj-$(CONFIG_ARM_GIC_V5) +=3D irq-gic-v5.o irq-gic-v5-irs.o diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-com= mon.h index 020ecdf16901..710cab61d919 100644 --- a/drivers/irqchip/irq-gic-common.h +++ b/drivers/irqchip/irq-gic-common.h @@ -29,8 +29,6 @@ void gic_enable_quirks(u32 iidr, const struct gic_quirk *= quirks, void gic_enable_of_quirks(const struct device_node *np, const struct gic_quirk *quirks, void *data); =20 -extern const struct msi_parent_ops gic_v3_its_msi_parent_ops; - #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) #define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1) #define RDIST_FLAGS_FORCE_NON_SHAREABLE (1 << 2) diff --git a/drivers/irqchip/irq-gic-v3-its-msi-parent.c b/drivers/irqchip/= irq-gic-its-msi-parent.c similarity index 99% rename from drivers/irqchip/irq-gic-v3-its-msi-parent.c rename to drivers/irqchip/irq-gic-its-msi-parent.c index a5e110ffdd88..8beecfed2b84 100644 --- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c +++ b/drivers/irqchip/irq-gic-its-msi-parent.c @@ -7,7 +7,7 @@ #include #include =20 -#include "irq-gic-common.h" +#include "irq-gic-its-msi-parent.h" #include =20 #define ITS_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ diff --git a/drivers/irqchip/irq-gic-its-msi-parent.h b/drivers/irqchip/irq= -gic-its-msi-parent.h new file mode 100644 index 000000000000..75e223e673ce --- /dev/null +++ b/drivers/irqchip/irq-gic-its-msi-parent.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 ARM Limited, All Rights Reserved. + */ + +#ifndef _IRQ_GIC_ITS_MSI_PARENT_H +#define _IRQ_GIC_ITS_MSI_PARENT_H + +extern const struct msi_parent_ops gic_v3_its_msi_parent_ops; + +#endif /* _IRQ_GIC_ITS_MSI_PARENT_H */ diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-= its.c index d54fa0638dc4..467cb78435a9 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -41,6 +41,7 @@ #include =20 #include "irq-gic-common.h" +#include "irq-gic-its-msi-parent.h" #include =20 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1ULL << 0) --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 778E42E54CF; Thu, 3 Jul 2025 10:27:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538463; cv=none; b=tmIOvaxydzQ+i+4f9difBrkXdvJ8DMswKPmXTtrzyZa0DGNin+bhHT1Bnp8qgP//stwqY4I+CQ0i2QikogQia1s9Fr6MAe6LpbRaUKkLG18HRvHofGwaqX2GNeyMhpkLDt7OTO2LzD7f9IzB2LlkRmIcjkvXUTVGncru5pczajw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538463; c=relaxed/simple; bh=dzBAiGg88kZkWCQEw27NLp04lJrDytYM5jJuijOSK0E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eqi6NLoF9mnxgVpnanS+wOOmgVS/7kAH6IaoBdha/nazk8hFSTdkqhZ/GiMloY6iJtYWy8DfMWkMTLOuz6fkSZBk5JzaSUqBAyH38Hzf0zX6kbQzMCBA2V9bIeZYtZ8e9cv/en5MFRaBgdeqvZicg8boCt5ai5lBKyc8jSIpXus= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=uAM8WucZ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="uAM8WucZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 89FFDC4CEED; Thu, 3 Jul 2025 10:27:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538463; bh=dzBAiGg88kZkWCQEw27NLp04lJrDytYM5jJuijOSK0E=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=uAM8WucZveyfVAU+piOtw3vbIcZg3TeIe6BCw9rV/oy+pSiBv//M0Sjkgs3j+atsr mq+dGhaxv0YcfHGdUGKLDWqVuEPlNelzLDRBy8C+/lEn9sGQX+ngTuIDep4fF1LgtI 2HwzSOh+u5imF/+O6iXTBvAtnhhNvxgsdUerGgGtE6/EOr1D4vWjjVUsuaLsx4NI9G +LCZk4sfEUisaa2XEk7/qhPn30OSer4OBuWviTpanqgnP45f2hB5XOTaLrIAYCH4HT igfvstcsReqYUPx1ErPeUqk0OAeh/8jPVuYJxKf/L7pdcYn/IIzQfoK13k/Apn4W6/ 7SAW6TWs97fVQ== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:17 +0200 Subject: [PATCH v7 27/31] irqchip/msi-lib: Add IRQ_DOMAIN_FLAG_FWNODE_PARENT handling Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-27-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e In some irqchip implementations the fwnode representing the IRQdomain and the MSI controller fwnode do not match; in particular the IRQdomain fwnode is the MSI controller fwnode parent. To support selecting such IRQ domains, add a flag in core IRQ domain code that explicitly tells the MSI lib to use the parent fwnode while carrying out IRQ domain selection. Update the msi-lib select callback with the resulting logic. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Thomas Gleixner Cc: Marc Zyngier --- drivers/irqchip/irq-msi-lib.c | 5 ++++- include/linux/irqdomain.h | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-msi-lib.c b/drivers/irqchip/irq-msi-lib.c index 246c30205af4..454c7f16dd4d 100644 --- a/drivers/irqchip/irq-msi-lib.c +++ b/drivers/irqchip/irq-msi-lib.c @@ -133,11 +133,14 @@ int msi_lib_irq_domain_select(struct irq_domain *d, s= truct irq_fwspec *fwspec, { const struct msi_parent_ops *ops =3D d->msi_parent_ops; u32 busmask =3D BIT(bus_token); + struct fwnode_handle *fwh; =20 if (!ops) return 0; =20 - if (fwspec->fwnode !=3D d->fwnode || fwspec->param_count !=3D 0) + fwh =3D d->flags & IRQ_DOMAIN_FLAG_FWNODE_PARENT ? fwnode_get_parent(fwsp= ec->fwnode) + : fwspec->fwnode; + if (fwh !=3D d->fwnode || fwspec->param_count !=3D 0) return 0; =20 /* Handle pure domain searches */ diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 7387d183029b..25c7cbeed393 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -212,6 +212,9 @@ enum { /* Address and data pair is mutable when irq_set_affinity() */ IRQ_DOMAIN_FLAG_MSI_IMMUTABLE =3D (1 << 11), =20 + /* IRQ domain requires parent fwnode matching */ + IRQ_DOMAIN_FLAG_FWNODE_PARENT =3D (1 << 12), + /* * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved * for implementation specific purposes and ignored by the --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 84B5A2E6104; Thu, 3 Jul 2025 10:27:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538469; cv=none; b=Tny3nKfrDJJQZetDdvhWNn0E+gR1ND785ktIaG9cZb5tn6q/u4BwCfoaOun56XH1eJTWlGwXJKaIWCX96BJntmx1XjahKD1s4ZU2zppeGbbK0X3O77eU6hnq3PHJKbmKR3yFsrHVXcnGQ9LROHlcqMIaW1VauI9c3CG9tCn+jXU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538469; c=relaxed/simple; bh=WElIKt47i7jQqVafScwLuFSOdrFIO3AUdLpaJR+jrhg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=h/QYtxO1FEYpYPl6DFgWG3Sai2xxgGZ2mRPF5v1JwXK2U/+XlODSyVg4z5VdMAJIrFx9xhzRwjw3hyuBGI6khf7vKfCLyug7CLR/tvRf70tE0e8v2JVJ6y9tXJoqAIXiX7GvGGGr8jbWZ0Vu10SmuOKkVQ2hjeTdoEcxM27pI4E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pITKTOtv; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pITKTOtv" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D8614C4AF0B; Thu, 3 Jul 2025 10:27:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538469; bh=WElIKt47i7jQqVafScwLuFSOdrFIO3AUdLpaJR+jrhg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pITKTOtvn2oFfEEwcSYRg+uIlrdxclzW2DKvejL9evDgaU3+14w/qMA84SPrz86XI +PHaQCTdws2nlkjwHnuK5QJf/1WUsb+LLijJhWy0YHSF6yEaZSj6ImC2lryztwRDdb 5UsQCPBEIXO8w6ZPdvCqBmzbFX7EO+otvvLSI+u4nz4NuO/YI6PrQ+lBJK3BkWjhY5 8cny4XcYqvvxbbMEgRUzYjZvUsVkJvVCJD42R5vUjdKr32ZSWPrg19xacBclFSJp6u u542Dmk6qazOjuco9eybm5VlPm4eDMv2AndjpB9RSWJZ56jAPD4duzJfwJzf230VBb jHQbPOBMFQQbw== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:18 +0200 Subject: [PATCH v7 28/31] irqchip/gic-v5: Add GICv5 ITS support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-28-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e The GICv5 architecture implements Interrupt Translation Service (ITS) components in order to translate events coming from peripherals into interrupt events delivered to the connected IRSes. Events (ie MSI memory writes to ITS translate frame), are translated by the ITS using tables kept in memory. ITS translation tables for peripherals is kept in memory storage (device table [DT] and Interrupt Translation Table [ITT]) that is allocated by the driver on boot. Both tables can be 1- or 2-level; the structure is chosen by the driver after probing the ITS HW parameters and checking the allowed table splits and supported {device/event}_IDbits. DT table entries are allocated on demand (ie when a device is probed); the DT table is sized using the number of supported deviceID bits in that that's a system design decision (ie the number of deviceID bits implemented should reflect the number of devices expected in a system) therefore it makes sense to allocate a DT table that can cater for the maximum number of devices. DT and ITT tables are allocated using the kmalloc interface; the allocation size may be smaller than a page or larger, and must provide contiguous memory pages. LPIs INTIDs backing the device events are allocated one-by-one and only upon Linux IRQ allocation; this to avoid preallocating a large number of LPIs to cover the HW device MSI vector size whereas few MSI entries are actually enabled by a device. ITS cacheability/shareability attributes are programmed according to the provided firmware ITS description. The GICv5 partially reuses the GICv3 ITS MSI parent infrastructure and adds functions required to retrieve the ITS translate frame addresses out of msi-map and msi-parent properties to implement the GICv5 ITS MSI parent callbacks. Co-developed-by: Sascha Bischoff Signed-off-by: Sascha Bischoff Co-developed-by: Timothy Hayes Signed-off-by: Timothy Hayes Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Thomas Gleixner Cc: Marc Zyngier --- MAINTAINERS | 1 + drivers/irqchip/Kconfig | 3 + drivers/irqchip/Makefile | 2 +- drivers/irqchip/irq-gic-its-msi-parent.c | 166 ++++ drivers/irqchip/irq-gic-its-msi-parent.h | 1 + drivers/irqchip/irq-gic-v5-irs.c | 24 + drivers/irqchip/irq-gic-v5-its.c | 1206 ++++++++++++++++++++++++++= ++++ drivers/irqchip/irq-gic-v5.c | 2 + include/linux/irqchip/arm-gic-v5.h | 157 ++++ 9 files changed, 1561 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 222a668f3fb6..00afc5467e14 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1971,6 +1971,7 @@ M: Marc Zyngier L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/interrupt-controller/arm,gic-v5*.yaml +F: drivers/irqchip/irq-gic-its-msi-parent.[ch] F: drivers/irqchip/irq-gic-v5*.[ch] F: include/linux/irqchip/arm-gic-v5.h =20 diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index f9eae1a645c9..67d79d33407a 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -62,6 +62,9 @@ config ARM_GIC_V5 bool select IRQ_DOMAIN_HIERARCHY select GENERIC_IRQ_EFFECTIVE_AFF_MASK + select GENERIC_MSI_IRQ + select IRQ_MSI_LIB + select ARM_GIC_ITS_PARENT =20 config ARM_NVIC bool diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 3ce6ea9a371b..5459f66e597f 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -37,7 +37,7 @@ obj-$(CONFIG_ARM_GIC_ITS_PARENT) +=3D irq-gic-its-msi-par= ent.o obj-$(CONFIG_ARM_GIC_V3_ITS) +=3D irq-gic-v3-its.o irq-gic-v4.o obj-$(CONFIG_ARM_GIC_V3_ITS_FSL_MC) +=3D irq-gic-v3-its-fsl-mc-msi.o obj-$(CONFIG_PARTITION_PERCPU) +=3D irq-partition-percpu.o -obj-$(CONFIG_ARM_GIC_V5) +=3D irq-gic-v5.o irq-gic-v5-irs.o +obj-$(CONFIG_ARM_GIC_V5) +=3D irq-gic-v5.o irq-gic-v5-irs.o irq-gic-v5-it= s.o obj-$(CONFIG_HISILICON_IRQ_MBIGEN) +=3D irq-mbigen.o obj-$(CONFIG_ARM_NVIC) +=3D irq-nvic.o obj-$(CONFIG_ARM_VIC) +=3D irq-vic.o diff --git a/drivers/irqchip/irq-gic-its-msi-parent.c b/drivers/irqchip/irq= -gic-its-msi-parent.c index 8beecfed2b84..eb1473f1448a 100644 --- a/drivers/irqchip/irq-gic-its-msi-parent.c +++ b/drivers/irqchip/irq-gic-its-msi-parent.c @@ -5,6 +5,7 @@ // Copyright (C) 2022 Intel =20 #include +#include #include =20 #include "irq-gic-its-msi-parent.h" @@ -18,6 +19,23 @@ MSI_FLAG_PCI_MSIX | \ MSI_FLAG_MULTI_PCI_MSI) =20 +static int its_translate_frame_address(struct device_node *msi_node, phys_= addr_t *pa) +{ + struct resource res; + int ret; + + ret =3D of_property_match_string(msi_node, "reg-names", "ns-translate"); + if (ret < 0) + return ret; + + ret =3D of_address_to_resource(msi_node, ret, &res); + if (ret) + return ret; + + *pa =3D res.start; + return 0; +} + #ifdef CONFIG_PCI_MSI static int its_pci_msi_vec_count(struct pci_dev *pdev, void *data) { @@ -82,8 +100,46 @@ static int its_pci_msi_prepare(struct irq_domain *domai= n, struct device *dev, msi_info =3D msi_get_domain_info(domain->parent); return msi_info->ops->msi_prepare(domain->parent, dev, nvec, info); } + +static int its_v5_pci_msi_prepare(struct irq_domain *domain, struct device= *dev, + int nvec, msi_alloc_info_t *info) +{ + struct device_node *msi_node =3D NULL; + struct msi_domain_info *msi_info; + struct pci_dev *pdev; + phys_addr_t pa; + u32 rid; + int ret; + + if (!dev_is_pci(dev)) + return -EINVAL; + + pdev =3D to_pci_dev(dev); + + rid =3D pci_msi_map_rid_ctlr_node(pdev, &msi_node); + if (!msi_node) + return -ENODEV; + + ret =3D its_translate_frame_address(msi_node, &pa); + if (ret) + return -ENODEV; + + of_node_put(msi_node); + + /* ITS specific DeviceID */ + info->scratchpad[0].ul =3D rid; + /* ITS translate frame physical address */ + info->scratchpad[1].ul =3D pa; + + /* Always allocate power of two vectors */ + nvec =3D roundup_pow_of_two(nvec); + + msi_info =3D msi_get_domain_info(domain->parent); + return msi_info->ops->msi_prepare(domain->parent, dev, nvec, info); +} #else /* CONFIG_PCI_MSI */ #define its_pci_msi_prepare NULL +#define its_v5_pci_msi_prepare NULL #endif /* !CONFIG_PCI_MSI */ =20 static int of_pmsi_get_dev_id(struct irq_domain *domain, struct device *de= v, @@ -118,6 +174,53 @@ static int of_pmsi_get_dev_id(struct irq_domain *domai= n, struct device *dev, return ret; } =20 +static int of_v5_pmsi_get_msi_info(struct irq_domain *domain, struct devic= e *dev, + u32 *dev_id, phys_addr_t *pa) +{ + int ret, index =3D 0; + /* + * Retrieve the DeviceID and the ITS translate frame node pointer + * out of the msi-parent property. + */ + do { + struct of_phandle_args args; + + ret =3D of_parse_phandle_with_args(dev->of_node, + "msi-parent", "#msi-cells", + index, &args); + if (ret) + break; + /* + * The IRQ domain fwnode is the msi controller parent + * in GICv5 (where the msi controller nodes are the + * ITS translate frames). + */ + if (args.np->parent =3D=3D irq_domain_get_of_node(domain)) { + if (WARN_ON(args.args_count !=3D 1)) + return -EINVAL; + *dev_id =3D args.args[0]; + + ret =3D its_translate_frame_address(args.np, pa); + if (ret) + return -ENODEV; + break; + } + index++; + } while (!ret); + + if (ret) { + struct device_node *np =3D NULL; + + ret =3D of_map_id(dev->of_node, dev->id, "msi-map", "msi-map-mask", &np,= dev_id); + if (np) { + ret =3D its_translate_frame_address(np, pa); + of_node_put(np); + } + } + + return ret; +} + int __weak iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id) { return -1; @@ -148,6 +251,33 @@ static int its_pmsi_prepare(struct irq_domain *domain,= struct device *dev, dev, nvec, info); } =20 +static int its_v5_pmsi_prepare(struct irq_domain *domain, struct device *d= ev, + int nvec, msi_alloc_info_t *info) +{ + struct msi_domain_info *msi_info; + phys_addr_t pa; + u32 dev_id; + int ret; + + if (!dev->of_node) + return -ENODEV; + + ret =3D of_v5_pmsi_get_msi_info(domain->parent, dev, &dev_id, &pa); + if (ret) + return ret; + + /* ITS specific DeviceID */ + info->scratchpad[0].ul =3D dev_id; + /* ITS translate frame physical address */ + info->scratchpad[1].ul =3D pa; + + /* Allocate always as a power of 2 */ + nvec =3D roundup_pow_of_two(nvec); + + msi_info =3D msi_get_domain_info(domain->parent); + return msi_info->ops->msi_prepare(domain->parent, dev, nvec, info); +} + static void its_msi_teardown(struct irq_domain *domain, msi_alloc_info_t *= info) { struct msi_domain_info *msi_info; @@ -199,6 +329,32 @@ static bool its_init_dev_msi_info(struct device *dev, = struct irq_domain *domain, return true; } =20 +static bool its_v5_init_dev_msi_info(struct device *dev, struct irq_domain= *domain, + struct irq_domain *real_parent, struct msi_domain_info *info) +{ + if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info)) + return false; + + switch (info->bus_token) { + case DOMAIN_BUS_PCI_DEVICE_MSI: + case DOMAIN_BUS_PCI_DEVICE_MSIX: + info->ops->msi_prepare =3D its_v5_pci_msi_prepare; + info->ops->msi_teardown =3D its_msi_teardown; + break; + case DOMAIN_BUS_DEVICE_MSI: + case DOMAIN_BUS_WIRED_TO_MSI: + info->ops->msi_prepare =3D its_v5_pmsi_prepare; + info->ops->msi_teardown =3D its_msi_teardown; + break; + default: + /* Confused. How did the lib return true? */ + WARN_ON_ONCE(1); + return false; + } + + return true; +} + const struct msi_parent_ops gic_v3_its_msi_parent_ops =3D { .supported_flags =3D ITS_MSI_FLAGS_SUPPORTED, .required_flags =3D ITS_MSI_FLAGS_REQUIRED, @@ -208,3 +364,13 @@ const struct msi_parent_ops gic_v3_its_msi_parent_ops = =3D { .prefix =3D "ITS-", .init_dev_msi_info =3D its_init_dev_msi_info, }; + +const struct msi_parent_ops gic_v5_its_msi_parent_ops =3D { + .supported_flags =3D ITS_MSI_FLAGS_SUPPORTED, + .required_flags =3D ITS_MSI_FLAGS_REQUIRED, + .chip_flags =3D MSI_CHIP_FLAG_SET_EOI, + .bus_select_token =3D DOMAIN_BUS_NEXUS, + .bus_select_mask =3D MATCH_PCI_MSI | MATCH_PLATFORM_MSI, + .prefix =3D "ITS-v5-", + .init_dev_msi_info =3D its_v5_init_dev_msi_info, +}; diff --git a/drivers/irqchip/irq-gic-its-msi-parent.h b/drivers/irqchip/irq= -gic-its-msi-parent.h index 75e223e673ce..df016f347337 100644 --- a/drivers/irqchip/irq-gic-its-msi-parent.h +++ b/drivers/irqchip/irq-gic-its-msi-parent.h @@ -7,5 +7,6 @@ #define _IRQ_GIC_ITS_MSI_PARENT_H =20 extern const struct msi_parent_ops gic_v3_its_msi_parent_ops; +extern const struct msi_parent_ops gic_v5_its_msi_parent_ops; =20 #endif /* _IRQ_GIC_ITS_MSI_PARENT_H */ diff --git a/drivers/irqchip/irq-gic-v5-irs.c b/drivers/irqchip/irq-gic-v5-= irs.c index f00a4a6fece7..f845415f9143 100644 --- a/drivers/irqchip/irq-gic-v5-irs.c +++ b/drivers/irqchip/irq-gic-v5-irs.c @@ -484,6 +484,22 @@ static int gicv5_irs_wait_for_idle(struct gicv5_irs_ch= ip_data *irs_data) GICV5_IRS_CR0_IDLE, NULL); } =20 +void gicv5_irs_syncr(void) +{ + struct gicv5_irs_chip_data *irs_data; + u32 syncr; + + irs_data =3D list_first_entry_or_null(&irs_nodes, struct gicv5_irs_chip_d= ata, entry); + if (WARN_ON_ONCE(!irs_data)) + return; + + syncr =3D FIELD_PREP(GICV5_IRS_SYNCR_SYNC, 1); + irs_writel_relaxed(irs_data, syncr, GICV5_IRS_SYNCR); + + gicv5_wait_for_op(irs_data->irs_base, GICV5_IRS_SYNC_STATUSR, + GICV5_IRS_SYNC_STATUSR_IDLE); +} + int gicv5_irs_register_cpu(int cpuid) { struct gicv5_irs_chip_data *irs_data; @@ -780,6 +796,14 @@ int __init gicv5_irs_enable(void) return 0; } =20 +void __init gicv5_irs_its_probe(void) +{ + struct gicv5_irs_chip_data *irs_data; + + list_for_each_entry(irs_data, &irs_nodes, entry) + gicv5_its_of_probe(to_of_node(irs_data->fwnode)); +} + int __init gicv5_irs_of_probe(struct device_node *parent) { struct device_node *np; diff --git a/drivers/irqchip/irq-gic-v5-its.c b/drivers/irqchip/irq-gic-v5-= its.c new file mode 100644 index 000000000000..700df6d0687e --- /dev/null +++ b/drivers/irqchip/irq-gic-v5-its.c @@ -0,0 +1,1206 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024-2025 ARM Limited, All Rights Reserved. + */ + +#define pr_fmt(fmt) "GICv5 ITS: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "irq-gic-its-msi-parent.h" + +#define ITS_FLAGS_NON_COHERENT BIT(0) + +struct gicv5_its_chip_data { + struct xarray its_devices; + struct mutex dev_alloc_lock; + struct fwnode_handle *fwnode; + struct gicv5_its_devtab_cfg devtab_cfgr; + void __iomem *its_base; + u32 flags; + unsigned int msi_domain_flags; +}; + +struct gicv5_its_dev { + struct gicv5_its_chip_data *its_node; + struct gicv5_its_itt_cfg itt_cfg; + unsigned long *event_map; + u32 device_id; + u32 num_events; + phys_addr_t its_trans_phys_base; +}; + +static u32 its_readl_relaxed(struct gicv5_its_chip_data *its_node, const u= 32 reg_offset) +{ + return readl_relaxed(its_node->its_base + reg_offset); +} + +static void its_writel_relaxed(struct gicv5_its_chip_data *its_node, const= u32 val, + const u32 reg_offset) +{ + writel_relaxed(val, its_node->its_base + reg_offset); +} + +static void its_writeq_relaxed(struct gicv5_its_chip_data *its_node, const= u64 val, + const u32 reg_offset) +{ + writeq_relaxed(val, its_node->its_base + reg_offset); +} + +static void gicv5_its_dcache_clean(struct gicv5_its_chip_data *its, void *= start, + size_t sz) +{ + void *end =3D start + sz; + + if (its->flags & ITS_FLAGS_NON_COHERENT) + dcache_clean_inval_poc((unsigned long)start, (unsigned long)end); + else + dsb(ishst); +} + +static void its_write_table_entry(struct gicv5_its_chip_data *its, __le64 = *entry, + u64 val) +{ + WRITE_ONCE(*entry, cpu_to_le64(val)); + gicv5_its_dcache_clean(its, entry, sizeof(*entry)); +} + +#define devtab_cfgr_field(its, f) \ + FIELD_GET(GICV5_ITS_DT_CFGR_##f, (its)->devtab_cfgr.cfgr) + +static int gicv5_its_cache_sync(struct gicv5_its_chip_data *its) +{ + return gicv5_wait_for_op_atomic(its->its_base, GICV5_ITS_STATUSR, + GICV5_ITS_STATUSR_IDLE, NULL); +} + +static void gicv5_its_syncr(struct gicv5_its_chip_data *its, + struct gicv5_its_dev *its_dev) +{ + u64 syncr; + + syncr =3D FIELD_PREP(GICV5_ITS_SYNCR_SYNC, 1) | + FIELD_PREP(GICV5_ITS_SYNCR_DEVICEID, its_dev->device_id); + + its_writeq_relaxed(its, syncr, GICV5_ITS_SYNCR); + + gicv5_wait_for_op(its->its_base, GICV5_ITS_SYNC_STATUSR, GICV5_ITS_SYNC_S= TATUSR_IDLE); +} + +/* Number of bits required for each L2 {device/interrupt translation} tabl= e size */ +#define ITS_L2SZ_64K_L2_BITS 13 +#define ITS_L2SZ_16K_L2_BITS 11 +#define ITS_L2SZ_4K_L2_BITS 9 + +static unsigned int gicv5_its_l2sz_to_l2_bits(unsigned int sz) +{ + switch (sz) { + case GICV5_ITS_DT_ITT_CFGR_L2SZ_64k: + return ITS_L2SZ_64K_L2_BITS; + case GICV5_ITS_DT_ITT_CFGR_L2SZ_16k: + return ITS_L2SZ_16K_L2_BITS; + case GICV5_ITS_DT_ITT_CFGR_L2SZ_4k: + default: + return ITS_L2SZ_4K_L2_BITS; + } +} + +static int gicv5_its_itt_cache_inv(struct gicv5_its_chip_data *its, u32 de= vice_id, + u16 event_id) +{ + u32 eventr, eidr; + u64 didr; + + didr =3D FIELD_PREP(GICV5_ITS_DIDR_DEVICEID, device_id); + eidr =3D FIELD_PREP(GICV5_ITS_EIDR_EVENTID, event_id); + eventr =3D FIELD_PREP(GICV5_ITS_INV_EVENTR_I, 0x1); + + its_writeq_relaxed(its, didr, GICV5_ITS_DIDR); + its_writel_relaxed(its, eidr, GICV5_ITS_EIDR); + its_writel_relaxed(its, eventr, GICV5_ITS_INV_EVENTR); + + return gicv5_its_cache_sync(its); +} + +static void gicv5_its_free_itt_linear(struct gicv5_its_dev *its_dev) +{ + kfree(its_dev->itt_cfg.linear.itt); +} + +static void gicv5_its_free_itt_two_level(struct gicv5_its_dev *its_dev) +{ + unsigned int i, num_ents =3D its_dev->itt_cfg.l2.num_l1_ents; + + for (i =3D 0; i < num_ents; i++) + kfree(its_dev->itt_cfg.l2.l2ptrs[i]); + + kfree(its_dev->itt_cfg.l2.l2ptrs); + kfree(its_dev->itt_cfg.l2.l1itt); +} + +static void gicv5_its_free_itt(struct gicv5_its_dev *its_dev) +{ + if (!its_dev->itt_cfg.l2itt) + gicv5_its_free_itt_linear(its_dev); + else + gicv5_its_free_itt_two_level(its_dev); +} + +static int gicv5_its_create_itt_linear(struct gicv5_its_chip_data *its, + struct gicv5_its_dev *its_dev, + unsigned int event_id_bits) +{ + unsigned int num_ents =3D BIT(event_id_bits); + __le64 *itt; + + itt =3D kcalloc(num_ents, sizeof(*itt), GFP_KERNEL); + if (!itt) + return -ENOMEM; + + its_dev->itt_cfg.linear.itt =3D itt; + its_dev->itt_cfg.linear.num_ents =3D num_ents; + its_dev->itt_cfg.l2itt =3D false; + its_dev->itt_cfg.event_id_bits =3D event_id_bits; + + gicv5_its_dcache_clean(its, itt, num_ents * sizeof(*itt)); + + return 0; +} + +/* + * Allocate a two-level ITT. All ITT entries are allocated in one go, unli= ke + * with the device table. Span may be used to limit the second level table + * size, where possible. + */ +static int gicv5_its_create_itt_two_level(struct gicv5_its_chip_data *its, + struct gicv5_its_dev *its_dev, + unsigned int event_id_bits, + unsigned int itt_l2sz, + unsigned int num_events) +{ + unsigned int l1_bits, l2_bits, span, events_per_l2_table; + unsigned int i, complete_tables, final_span, num_ents; + __le64 *itt_l1, *itt_l2, **l2ptrs; + int ret; + u64 val; + + ret =3D gicv5_its_l2sz_to_l2_bits(itt_l2sz); + if (ret >=3D event_id_bits) { + pr_debug("Incorrect l2sz (0x%x) for %u EventID bits. Cannot allocate ITT= \n", + itt_l2sz, event_id_bits); + return -EINVAL; + } + + l2_bits =3D ret; + + l1_bits =3D event_id_bits - l2_bits; + + num_ents =3D BIT(l1_bits); + + itt_l1 =3D kcalloc(num_ents, sizeof(*itt_l1), GFP_KERNEL); + if (!itt_l1) + return -ENOMEM; + + l2ptrs =3D kcalloc(num_ents, sizeof(*l2ptrs), GFP_KERNEL); + if (!l2ptrs) { + kfree(itt_l1); + return -ENOMEM; + } + + its_dev->itt_cfg.l2.l2ptrs =3D l2ptrs; + + its_dev->itt_cfg.l2.l2sz =3D itt_l2sz; + its_dev->itt_cfg.l2.l1itt =3D itt_l1; + its_dev->itt_cfg.l2.num_l1_ents =3D num_ents; + its_dev->itt_cfg.l2itt =3D true; + its_dev->itt_cfg.event_id_bits =3D event_id_bits; + + /* + * Need to determine how many entries there are per L2 - this is based + * on the number of bits in the table. + */ + events_per_l2_table =3D BIT(l2_bits); + complete_tables =3D num_events / events_per_l2_table; + final_span =3D order_base_2(num_events % events_per_l2_table); + + for (i =3D 0; i < num_ents; i++) { + size_t l2sz; + + span =3D i =3D=3D complete_tables ? final_span : l2_bits; + + itt_l2 =3D kcalloc(BIT(span), sizeof(*itt_l2), GFP_KERNEL); + if (!itt_l2) { + ret =3D -ENOMEM; + goto out_free; + } + + its_dev->itt_cfg.l2.l2ptrs[i] =3D itt_l2; + + l2sz =3D BIT(span) * sizeof(*itt_l2); + + gicv5_its_dcache_clean(its, itt_l2, l2sz); + + val =3D (virt_to_phys(itt_l2) & GICV5_ITTL1E_L2_ADDR_MASK) | + FIELD_PREP(GICV5_ITTL1E_SPAN, span) | + FIELD_PREP(GICV5_ITTL1E_VALID, 0x1); + + WRITE_ONCE(itt_l1[i], cpu_to_le64(val)); + } + + gicv5_its_dcache_clean(its, itt_l1, num_ents * sizeof(*itt_l1)); + + return 0; + +out_free: + for (i =3D i - 1; i >=3D 0; i--) + kfree(its_dev->itt_cfg.l2.l2ptrs[i]); + + kfree(its_dev->itt_cfg.l2.l2ptrs); + kfree(itt_l1); + return ret; +} + +/* + * Function to check whether the device table or ITT table support + * a two-level table and if so depending on the number of id_bits + * requested, determine whether a two-level table is required. + * + * Return the 2-level size value if a two level table is deemed + * necessary. + */ +static bool gicv5_its_l2sz_two_level(bool devtab, u32 its_idr1, u8 id_bits= , u8 *sz) +{ + unsigned int l2_bits, l2_sz; + + if (devtab && !FIELD_GET(GICV5_ITS_IDR1_DT_LEVELS, its_idr1)) + return false; + + if (!devtab && !FIELD_GET(GICV5_ITS_IDR1_ITT_LEVELS, its_idr1)) + return false; + + /* + * Pick an L2 size that matches the pagesize; if a match + * is not found, go for the smallest supported l2 size granule. + * + * This ensures that we will always be able to allocate + * contiguous memory at L2. + */ + switch (PAGE_SIZE) { + case SZ_64K: + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_64KB(its_idr1)) { + l2_sz =3D GICV5_ITS_DT_ITT_CFGR_L2SZ_64k; + break; + } + fallthrough; + case SZ_4K: + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_4KB(its_idr1)) { + l2_sz =3D GICV5_ITS_DT_ITT_CFGR_L2SZ_4k; + break; + } + fallthrough; + case SZ_16K: + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_16KB(its_idr1)) { + l2_sz =3D GICV5_ITS_DT_ITT_CFGR_L2SZ_16k; + break; + } + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_4KB(its_idr1)) { + l2_sz =3D GICV5_ITS_DT_ITT_CFGR_L2SZ_4k; + break; + } + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_64KB(its_idr1)) { + l2_sz =3D GICV5_ITS_DT_ITT_CFGR_L2SZ_64k; + break; + } + + l2_sz =3D GICV5_ITS_DT_ITT_CFGR_L2SZ_4k; + break; + } + + l2_bits =3D gicv5_its_l2sz_to_l2_bits(l2_sz); + + if (l2_bits > id_bits) + return false; + + *sz =3D l2_sz; + + return true; +} + +static __le64 *gicv5_its_device_get_itte_ref(struct gicv5_its_dev *its_dev, + u16 event_id) +{ + unsigned int l1_idx, l2_idx, l2_bits; + __le64 *l2_itt; + + if (!its_dev->itt_cfg.l2itt) { + __le64 *itt =3D its_dev->itt_cfg.linear.itt; + + return &itt[event_id]; + } + + l2_bits =3D gicv5_its_l2sz_to_l2_bits(its_dev->itt_cfg.l2.l2sz); + l1_idx =3D event_id >> l2_bits; + l2_idx =3D event_id & GENMASK(l2_bits - 1, 0); + l2_itt =3D its_dev->itt_cfg.l2.l2ptrs[l1_idx]; + + return &l2_itt[l2_idx]; +} + +static int gicv5_its_device_cache_inv(struct gicv5_its_chip_data *its, + struct gicv5_its_dev *its_dev) +{ + u32 devicer; + u64 didr; + + didr =3D FIELD_PREP(GICV5_ITS_DIDR_DEVICEID, its_dev->device_id); + devicer =3D FIELD_PREP(GICV5_ITS_INV_DEVICER_I, 0x1) | + FIELD_PREP(GICV5_ITS_INV_DEVICER_EVENTID_BITS, + its_dev->itt_cfg.event_id_bits) | + FIELD_PREP(GICV5_ITS_INV_DEVICER_L1, 0x0); + its_writeq_relaxed(its, didr, GICV5_ITS_DIDR); + its_writel_relaxed(its, devicer, GICV5_ITS_INV_DEVICER); + + return gicv5_its_cache_sync(its); +} + +/* + * Allocate a level 2 device table entry, update L1 parent to reference it. + * Only used for 2-level device tables, and it is called on demand. + */ +static int gicv5_its_alloc_l2_devtab(struct gicv5_its_chip_data *its, + unsigned int l1_index) +{ + __le64 *l2devtab, *l1devtab =3D its->devtab_cfgr.l2.l1devtab; + u8 span, l2sz, l2_bits; + u64 l1dte; + + if (FIELD_GET(GICV5_DTL1E_VALID, le64_to_cpu(l1devtab[l1_index]))) + return 0; + + span =3D FIELD_GET(GICV5_DTL1E_SPAN, le64_to_cpu(l1devtab[l1_index])); + l2sz =3D devtab_cfgr_field(its, L2SZ); + + l2_bits =3D gicv5_its_l2sz_to_l2_bits(l2sz); + + /* + * Span allows us to create a smaller L2 device table. + * If it is too large, use the number of allowed L2 bits. + */ + if (span > l2_bits) + span =3D l2_bits; + + l2devtab =3D kcalloc(BIT(span), sizeof(*l2devtab), GFP_KERNEL); + if (!l2devtab) + return -ENOMEM; + + its->devtab_cfgr.l2.l2ptrs[l1_index] =3D l2devtab; + + l1dte =3D FIELD_PREP(GICV5_DTL1E_SPAN, span) | + (virt_to_phys(l2devtab) & GICV5_DTL1E_L2_ADDR_MASK) | + FIELD_PREP(GICV5_DTL1E_VALID, 0x1); + its_write_table_entry(its, &l1devtab[l1_index], l1dte); + + return 0; +} + +static __le64 *gicv5_its_devtab_get_dte_ref(struct gicv5_its_chip_data *it= s, + u32 device_id, bool alloc) +{ + u8 str =3D devtab_cfgr_field(its, STRUCTURE); + unsigned int l2sz, l2_bits, l1_idx, l2_idx; + __le64 *l2devtab; + int ret; + + if (str =3D=3D GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR) { + l2devtab =3D its->devtab_cfgr.linear.devtab; + return &l2devtab[device_id]; + } + + l2sz =3D devtab_cfgr_field(its, L2SZ); + l2_bits =3D gicv5_its_l2sz_to_l2_bits(l2sz); + l1_idx =3D device_id >> l2_bits; + l2_idx =3D device_id & GENMASK(l2_bits - 1, 0); + + if (alloc) { + /* + * Allocate a new L2 device table here before + * continuing. We make the assumption that the span in + * the L1 table has been set correctly, and blindly use + * that value. + */ + ret =3D gicv5_its_alloc_l2_devtab(its, l1_idx); + if (ret) + return NULL; + } + + l2devtab =3D its->devtab_cfgr.l2.l2ptrs[l1_idx]; + return &l2devtab[l2_idx]; +} + +/* + * Register a new device in the device table. Allocate an ITT and + * program the L2DTE entry according to the ITT structure that + * was chosen. + */ +static int gicv5_its_device_register(struct gicv5_its_chip_data *its, + struct gicv5_its_dev *its_dev) +{ + u8 event_id_bits, device_id_bits, itt_struct, itt_l2sz; + phys_addr_t itt_phys_base; + bool two_level_itt; + u32 idr1, idr2; + __le64 *dte; + u64 val; + int ret; + + device_id_bits =3D devtab_cfgr_field(its, DEVICEID_BITS); + + if (its_dev->device_id >=3D BIT(device_id_bits)) { + pr_err("Supplied DeviceID (%u) outside of Device Table range (%u)!", + its_dev->device_id, (u32)GENMASK(device_id_bits - 1, 0)); + return -EINVAL; + } + + dte =3D gicv5_its_devtab_get_dte_ref(its, its_dev->device_id, true); + if (!dte) + return -ENOMEM; + + if (FIELD_GET(GICV5_DTL2E_VALID, le64_to_cpu(*dte))) + return -EBUSY; + + /* + * Determine how many bits we need, validate those against the max. + * Based on these, determine if we should go for a 1- or 2-level ITT. + */ + event_id_bits =3D order_base_2(its_dev->num_events); + + idr2 =3D its_readl_relaxed(its, GICV5_ITS_IDR2); + + if (event_id_bits > FIELD_GET(GICV5_ITS_IDR2_EVENTID_BITS, idr2)) { + pr_err("Required EventID bits (%u) larger than supported bits (%u)!", + event_id_bits, + (u8)FIELD_GET(GICV5_ITS_IDR2_EVENTID_BITS, idr2)); + return -EINVAL; + } + + idr1 =3D its_readl_relaxed(its, GICV5_ITS_IDR1); + + /* + * L2 ITT size is programmed into the L2DTE regardless of + * whether a two-level or linear ITT is built, init it. + */ + itt_l2sz =3D 0; + + two_level_itt =3D gicv5_its_l2sz_two_level(false, idr1, event_id_bits, + &itt_l2sz); + if (two_level_itt) + ret =3D gicv5_its_create_itt_two_level(its, its_dev, event_id_bits, + itt_l2sz, + its_dev->num_events); + else + ret =3D gicv5_its_create_itt_linear(its, its_dev, event_id_bits); + if (ret) + return ret; + + itt_phys_base =3D two_level_itt ? virt_to_phys(its_dev->itt_cfg.l2.l1itt)= : + virt_to_phys(its_dev->itt_cfg.linear.itt); + + itt_struct =3D two_level_itt ? GICV5_ITS_DT_ITT_CFGR_STRUCTURE_TWO_LEVEL : + GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR; + + val =3D FIELD_PREP(GICV5_DTL2E_EVENT_ID_BITS, event_id_bits) | + FIELD_PREP(GICV5_DTL2E_ITT_STRUCTURE, itt_struct) | + (itt_phys_base & GICV5_DTL2E_ITT_ADDR_MASK) | + FIELD_PREP(GICV5_DTL2E_ITT_L2SZ, itt_l2sz) | + FIELD_PREP(GICV5_DTL2E_VALID, 0x1); + + its_write_table_entry(its, dte, val); + + ret =3D gicv5_its_device_cache_inv(its, its_dev); + if (ret) { + its_write_table_entry(its, dte, 0); + gicv5_its_free_itt(its_dev); + return ret; + } + + return 0; +} + +/* + * Unregister a device in the device table. Lookup the device by ID, free = the + * corresponding ITT, mark the device as invalid in the device table. + */ +static int gicv5_its_device_unregister(struct gicv5_its_chip_data *its, + struct gicv5_its_dev *its_dev) +{ + __le64 *dte; + + dte =3D gicv5_its_devtab_get_dte_ref(its, its_dev->device_id, false); + + if (!FIELD_GET(GICV5_DTL2E_VALID, le64_to_cpu(*dte))) { + pr_debug("Device table entry for DeviceID 0x%x is not valid. Nothing to = clean up!", + its_dev->device_id); + return -EINVAL; + } + + /* Zero everything - make it clear that this is an invalid entry */ + its_write_table_entry(its, dte, 0); + + gicv5_its_free_itt(its_dev); + + return gicv5_its_device_cache_inv(its, its_dev); +} + +/* + * Allocate a 1-level device table. All entries are allocated, but marked + * invalid. + */ +static int gicv5_its_alloc_devtab_linear(struct gicv5_its_chip_data *its, + u8 device_id_bits) +{ + __le64 *devtab; + size_t sz; + u64 baser; + u32 cfgr; + + /* + * We expect a GICv5 implementation requiring a large number of + * deviceID bits to support a 2-level device table. If that's not + * the case, cap the number of deviceIDs supported according to the + * kmalloc limits so that the system can chug along with a linear + * device table. + */ + sz =3D BIT_ULL(device_id_bits) * sizeof(*devtab); + if (sz > KMALLOC_MAX_SIZE) { + u8 device_id_cap =3D ilog2(KMALLOC_MAX_SIZE/sizeof(*devtab)); + + pr_warn("Limiting device ID bits from %u to %u\n", + device_id_bits, device_id_cap); + device_id_bits =3D device_id_cap; + } + + devtab =3D kcalloc(BIT(device_id_bits), sizeof(*devtab), GFP_KERNEL); + if (!devtab) + return -ENOMEM; + + gicv5_its_dcache_clean(its, devtab, sz); + + cfgr =3D FIELD_PREP(GICV5_ITS_DT_CFGR_STRUCTURE, + GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR) | + FIELD_PREP(GICV5_ITS_DT_CFGR_L2SZ, 0) | + FIELD_PREP(GICV5_ITS_DT_CFGR_DEVICEID_BITS, device_id_bits); + its_writel_relaxed(its, cfgr, GICV5_ITS_DT_CFGR); + + baser =3D virt_to_phys(devtab) & GICV5_ITS_DT_BASER_ADDR_MASK; + its_writeq_relaxed(its, baser, GICV5_ITS_DT_BASER); + + its->devtab_cfgr.cfgr =3D cfgr; + its->devtab_cfgr.linear.devtab =3D devtab; + + return 0; +} + +/* + * Allocate a 2-level device table. L2 entries are not allocated, + * they are allocated on-demand. + */ +static int gicv5_its_alloc_devtab_two_level(struct gicv5_its_chip_data *it= s, + u8 device_id_bits, + u8 devtab_l2sz) +{ + unsigned int l1_bits, l2_bits, i; + __le64 *l1devtab, **l2ptrs; + size_t l1_sz; + u64 baser; + u32 cfgr; + + l2_bits =3D gicv5_its_l2sz_to_l2_bits(devtab_l2sz); + + l1_bits =3D device_id_bits - l2_bits; + l1_sz =3D BIT(l1_bits) * sizeof(*l1devtab); + /* + * With 2-level device table support it is highly unlikely + * that we are not able to allocate the required amount of + * device table memory to cover deviceID space; cap the + * deviceID space if we encounter such set-up. + * If this ever becomes a problem we could revisit the policy + * behind level 2 size selection to reduce level-1 deviceID bits. + */ + if (l1_sz > KMALLOC_MAX_SIZE) { + l1_bits =3D ilog2(KMALLOC_MAX_SIZE/sizeof(*l1devtab)); + + pr_warn("Limiting device ID bits from %u to %u\n", + device_id_bits, l1_bits + l2_bits); + device_id_bits =3D l1_bits + l2_bits; + l1_sz =3D KMALLOC_MAX_SIZE; + } + + l1devtab =3D kcalloc(BIT(l1_bits), sizeof(*l1devtab), GFP_KERNEL); + if (!l1devtab) + return -ENOMEM; + + l2ptrs =3D kcalloc(BIT(l1_bits), sizeof(*l2ptrs), GFP_KERNEL); + if (!l2ptrs) { + kfree(l1devtab); + return -ENOMEM; + } + + for (i =3D 0; i < BIT(l1_bits); i++) + l1devtab[i] =3D cpu_to_le64(FIELD_PREP(GICV5_DTL1E_SPAN, l2_bits)); + + gicv5_its_dcache_clean(its, l1devtab, l1_sz); + + cfgr =3D FIELD_PREP(GICV5_ITS_DT_CFGR_STRUCTURE, + GICV5_ITS_DT_ITT_CFGR_STRUCTURE_TWO_LEVEL) | + FIELD_PREP(GICV5_ITS_DT_CFGR_L2SZ, devtab_l2sz) | + FIELD_PREP(GICV5_ITS_DT_CFGR_DEVICEID_BITS, device_id_bits); + its_writel_relaxed(its, cfgr, GICV5_ITS_DT_CFGR); + + baser =3D virt_to_phys(l1devtab) & GICV5_ITS_DT_BASER_ADDR_MASK; + its_writeq_relaxed(its, baser, GICV5_ITS_DT_BASER); + + its->devtab_cfgr.cfgr =3D cfgr; + its->devtab_cfgr.l2.l1devtab =3D l1devtab; + its->devtab_cfgr.l2.l2ptrs =3D l2ptrs; + + return 0; +} + +/* + * Initialise the device table as either 1- or 2-level depending on what is + * supported by the hardware. + */ +static int gicv5_its_init_devtab(struct gicv5_its_chip_data *its) +{ + u8 device_id_bits, devtab_l2sz; + bool two_level_devtab; + u32 idr1; + + idr1 =3D its_readl_relaxed(its, GICV5_ITS_IDR1); + + device_id_bits =3D FIELD_GET(GICV5_ITS_IDR1_DEVICEID_BITS, idr1); + two_level_devtab =3D gicv5_its_l2sz_two_level(true, idr1, device_id_bits, + &devtab_l2sz); + if (two_level_devtab) + return gicv5_its_alloc_devtab_two_level(its, device_id_bits, + devtab_l2sz); + else + return gicv5_its_alloc_devtab_linear(its, device_id_bits); +} + +static void gicv5_its_deinit_devtab(struct gicv5_its_chip_data *its) +{ + u8 str =3D devtab_cfgr_field(its, STRUCTURE); + + if (str =3D=3D GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR) { + kfree(its->devtab_cfgr.linear.devtab); + } else { + kfree(its->devtab_cfgr.l2.l1devtab); + kfree(its->devtab_cfgr.l2.l2ptrs); + } +} + +static void gicv5_its_compose_msi_msg(struct irq_data *d, struct msi_msg *= msg) +{ + struct gicv5_its_dev *its_dev =3D irq_data_get_irq_chip_data(d); + u64 addr =3D its_dev->its_trans_phys_base; + + msg->data =3D FIELD_GET(GICV5_ITS_HWIRQ_EVENT_ID, d->hwirq); + msi_msg_set_addr(irq_data_get_msi_desc(d), msg, addr); +} + +static const struct irq_chip gicv5_its_irq_chip =3D { + .name =3D "GICv5-ITS-MSI", + .irq_mask =3D irq_chip_mask_parent, + .irq_unmask =3D irq_chip_unmask_parent, + .irq_eoi =3D irq_chip_eoi_parent, + .irq_set_affinity =3D irq_chip_set_affinity_parent, + .irq_get_irqchip_state =3D irq_chip_get_parent_state, + .irq_set_irqchip_state =3D irq_chip_set_parent_state, + .irq_compose_msi_msg =3D gicv5_its_compose_msi_msg, +}; + +static struct gicv5_its_dev *gicv5_its_find_device(struct gicv5_its_chip_d= ata *its, + u32 device_id) +{ + struct gicv5_its_dev *dev =3D xa_load(&its->its_devices, device_id); + + return dev ? dev : ERR_PTR(-ENODEV); +} + +static struct gicv5_its_dev *gicv5_its_alloc_device(struct gicv5_its_chip_= data *its, int nvec, + u32 dev_id) +{ + struct gicv5_its_dev *its_dev; + void *entry; + int ret; + + its_dev =3D gicv5_its_find_device(its, dev_id); + if (!IS_ERR(its_dev)) { + pr_err("A device with this DeviceID (0x%x) has already been registered.\= n", + dev_id); + + return ERR_PTR(-EBUSY); + } + + its_dev =3D kzalloc(sizeof(*its_dev), GFP_KERNEL); + if (!its_dev) + return ERR_PTR(-ENOMEM); + + its_dev->device_id =3D dev_id; + its_dev->num_events =3D nvec; + + ret =3D gicv5_its_device_register(its, its_dev); + if (ret) { + pr_err("Failed to register the device\n"); + goto out_dev_free; + } + + gicv5_its_device_cache_inv(its, its_dev); + + its_dev->its_node =3D its; + + its_dev->event_map =3D (unsigned long *)bitmap_zalloc(its_dev->num_events= , GFP_KERNEL); + if (!its_dev->event_map) { + ret =3D -ENOMEM; + goto out_unregister; + } + + entry =3D xa_store(&its->its_devices, dev_id, its_dev, GFP_KERNEL); + if (xa_is_err(entry)) { + ret =3D xa_err(entry); + goto out_bitmap_free; + } + + return its_dev; + +out_bitmap_free: + bitmap_free(its_dev->event_map); +out_unregister: + gicv5_its_device_unregister(its, its_dev); +out_dev_free: + kfree(its_dev); + return ERR_PTR(ret); +} + +static int gicv5_its_msi_prepare(struct irq_domain *domain, struct device = *dev, + int nvec, msi_alloc_info_t *info) +{ + u32 dev_id =3D info->scratchpad[0].ul; + struct msi_domain_info *msi_info; + struct gicv5_its_chip_data *its; + struct gicv5_its_dev *its_dev; + + msi_info =3D msi_get_domain_info(domain); + its =3D msi_info->data; + + guard(mutex)(&its->dev_alloc_lock); + + its_dev =3D gicv5_its_alloc_device(its, nvec, dev_id); + if (IS_ERR(its_dev)) + return PTR_ERR(its_dev); + + its_dev->its_trans_phys_base =3D info->scratchpad[1].ul; + info->scratchpad[0].ptr =3D its_dev; + + return 0; +} + +static void gicv5_its_msi_teardown(struct irq_domain *domain, msi_alloc_in= fo_t *info) +{ + struct gicv5_its_dev *its_dev =3D info->scratchpad[0].ptr; + struct msi_domain_info *msi_info; + struct gicv5_its_chip_data *its; + + msi_info =3D msi_get_domain_info(domain); + its =3D msi_info->data; + + guard(mutex)(&its->dev_alloc_lock); + + if (WARN_ON_ONCE(!bitmap_empty(its_dev->event_map, its_dev->num_events))) + return; + + xa_erase(&its->its_devices, its_dev->device_id); + bitmap_free(its_dev->event_map); + gicv5_its_device_unregister(its, its_dev); + kfree(its_dev); +} + +static struct msi_domain_ops gicv5_its_msi_domain_ops =3D { + .msi_prepare =3D gicv5_its_msi_prepare, + .msi_teardown =3D gicv5_its_msi_teardown, +}; + +static int gicv5_its_map_event(struct gicv5_its_dev *its_dev, u16 event_id= , u32 lpi) +{ + struct gicv5_its_chip_data *its =3D its_dev->its_node; + u64 itt_entry; + __le64 *itte; + + itte =3D gicv5_its_device_get_itte_ref(its_dev, event_id); + + if (FIELD_GET(GICV5_ITTL2E_VALID, *itte)) + return -EEXIST; + + itt_entry =3D FIELD_PREP(GICV5_ITTL2E_LPI_ID, lpi) | + FIELD_PREP(GICV5_ITTL2E_VALID, 0x1); + + its_write_table_entry(its, itte, itt_entry); + + gicv5_its_itt_cache_inv(its, its_dev->device_id, event_id); + + return 0; +} + +static void gicv5_its_unmap_event(struct gicv5_its_dev *its_dev, u16 event= _id) +{ + struct gicv5_its_chip_data *its =3D its_dev->its_node; + u64 itte_val; + __le64 *itte; + + itte =3D gicv5_its_device_get_itte_ref(its_dev, event_id); + + itte_val =3D le64_to_cpu(*itte); + itte_val &=3D ~GICV5_ITTL2E_VALID; + + its_write_table_entry(its, itte, itte_val); + + gicv5_its_itt_cache_inv(its, its_dev->device_id, event_id); +} + +static int gicv5_its_alloc_eventid(struct gicv5_its_dev *its_dev, + unsigned int nr_irqs, u32 *eventid) +{ + int ret; + + ret =3D bitmap_find_free_region(its_dev->event_map, + its_dev->num_events, + get_count_order(nr_irqs)); + + if (ret < 0) + return ret; + + *eventid =3D ret; + + return 0; +} + +static void gicv5_its_free_eventid(struct gicv5_its_dev *its_dev, u32 even= t_id_base, + unsigned int nr_irqs) +{ + bitmap_release_region(its_dev->event_map, event_id_base, + get_count_order(nr_irqs)); +} + +static int gicv5_its_irq_domain_alloc(struct irq_domain *domain, unsigned = int virq, + unsigned int nr_irqs, void *arg) +{ + u32 device_id, event_id_base, lpi; + struct gicv5_its_dev *its_dev; + msi_alloc_info_t *info =3D arg; + irq_hw_number_t hwirq; + struct irq_data *irqd; + int ret, i; + + its_dev =3D info->scratchpad[0].ptr; + + ret =3D gicv5_its_alloc_eventid(its_dev, nr_irqs, &event_id_base); + if (ret) + return ret; + + ret =3D iommu_dma_prepare_msi(info->desc, its_dev->its_trans_phys_base); + if (ret) + goto out_eventid; + + device_id =3D its_dev->device_id; + + for (i =3D 0; i < nr_irqs; i++) { + lpi =3D gicv5_alloc_lpi(); + if (ret < 0) { + pr_debug("Failed to find free LPI!\n"); + goto out_eventid; + } + + ret =3D irq_domain_alloc_irqs_parent(domain, virq + i, 1, &lpi); + if (ret) + goto out_free_lpi; + + /* + * Store eventid and deviceid into the hwirq for later use. + * + * hwirq =3D event_id << 32 | device_id + */ + hwirq =3D FIELD_PREP(GICV5_ITS_HWIRQ_DEVICE_ID, device_id) | + FIELD_PREP(GICV5_ITS_HWIRQ_EVENT_ID, (u64)event_id_base + i); + irq_domain_set_info(domain, virq + i, hwirq, + &gicv5_its_irq_chip, its_dev, + handle_fasteoi_irq, NULL, NULL); + + irqd =3D irq_get_irq_data(virq + i); + irqd_set_single_target(irqd); + irqd_set_affinity_on_activate(irqd); + irqd_set_resend_when_in_progress(irqd); + } + + return 0; + +out_free_lpi: + gicv5_free_lpi(lpi); +out_eventid: + gicv5_its_free_eventid(its_dev, event_id_base, nr_irqs); + return ret; +} + +static void gicv5_its_irq_domain_free(struct irq_domain *domain, unsigned = int virq, + unsigned int nr_irqs) +{ + struct irq_data *d =3D irq_domain_get_irq_data(domain, virq); + struct gicv5_its_chip_data *its; + struct gicv5_its_dev *its_dev; + u16 event_id_base; + unsigned int i; + + its_dev =3D irq_data_get_irq_chip_data(d); + its =3D its_dev->its_node; + + event_id_base =3D FIELD_GET(GICV5_ITS_HWIRQ_EVENT_ID, d->hwirq); + + bitmap_release_region(its_dev->event_map, event_id_base, + get_count_order(nr_irqs)); + + /* Hierarchically free irq data */ + for (i =3D 0; i < nr_irqs; i++) { + d =3D irq_domain_get_irq_data(domain, virq + i); + + gicv5_free_lpi(d->parent_data->hwirq); + irq_domain_reset_irq_data(d); + irq_domain_free_irqs_parent(domain, virq + i, 1); + } + + gicv5_its_syncr(its, its_dev); + gicv5_irs_syncr(); +} + +static int gicv5_its_irq_domain_activate(struct irq_domain *domain, struct= irq_data *d, + bool reserve) +{ + struct gicv5_its_dev *its_dev =3D irq_data_get_irq_chip_data(d); + u16 event_id; + u32 lpi; + + event_id =3D FIELD_GET(GICV5_ITS_HWIRQ_EVENT_ID, d->hwirq); + lpi =3D d->parent_data->hwirq; + + return gicv5_its_map_event(its_dev, event_id, lpi); +} + +static void gicv5_its_irq_domain_deactivate(struct irq_domain *domain, + struct irq_data *d) +{ + struct gicv5_its_dev *its_dev =3D irq_data_get_irq_chip_data(d); + u16 event_id; + + event_id =3D FIELD_GET(GICV5_ITS_HWIRQ_EVENT_ID, d->hwirq); + + gicv5_its_unmap_event(its_dev, event_id); +} + +static const struct irq_domain_ops gicv5_its_irq_domain_ops =3D { + .alloc =3D gicv5_its_irq_domain_alloc, + .free =3D gicv5_its_irq_domain_free, + .activate =3D gicv5_its_irq_domain_activate, + .deactivate =3D gicv5_its_irq_domain_deactivate, + .select =3D msi_lib_irq_domain_select, +}; + +static int gicv5_its_write_cr0(struct gicv5_its_chip_data *its, bool enabl= e) +{ + u32 cr0 =3D FIELD_PREP(GICV5_ITS_CR0_ITSEN, enable); + + its_writel_relaxed(its, cr0, GICV5_ITS_CR0); + return gicv5_wait_for_op_atomic(its->its_base, GICV5_ITS_CR0, + GICV5_ITS_CR0_IDLE, NULL); +} + +static int gicv5_its_enable(struct gicv5_its_chip_data *its) +{ + return gicv5_its_write_cr0(its, true); +} + +static int gicv5_its_disable(struct gicv5_its_chip_data *its) +{ + return gicv5_its_write_cr0(its, false); +} + +static void gicv5_its_print_info(struct gicv5_its_chip_data *its_node) +{ + bool devtab_linear; + u8 device_id_bits; + u8 str; + + device_id_bits =3D devtab_cfgr_field(its_node, DEVICEID_BITS); + + str =3D devtab_cfgr_field(its_node, STRUCTURE); + devtab_linear =3D (str =3D=3D GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR); + + pr_info("ITS %s enabled using %s device table device_id_bits %u\n", + fwnode_get_name(its_node->fwnode), + devtab_linear ? "linear" : "2-level", + device_id_bits); +} + +static int gicv5_its_init_domain(struct gicv5_its_chip_data *its, struct i= rq_domain *parent) +{ + struct irq_domain_info dom_info =3D { + .fwnode =3D its->fwnode, + .ops =3D &gicv5_its_irq_domain_ops, + .domain_flags =3D its->msi_domain_flags, + .parent =3D parent, + }; + struct msi_domain_info *info; + + info =3D kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->ops =3D &gicv5_its_msi_domain_ops; + info->data =3D its; + dom_info.host_data =3D info; + + if (!msi_create_parent_irq_domain(&dom_info, &gic_v5_its_msi_parent_ops))= { + kfree(info); + return -ENOMEM; + } + + return 0; +} + +static int __init gicv5_its_init_bases(void __iomem *its_base, struct fwno= de_handle *handle, + struct irq_domain *parent_domain) +{ + struct device_node *np =3D to_of_node(handle); + struct gicv5_its_chip_data *its_node; + u32 cr0, cr1; + bool enabled; + int ret; + + its_node =3D kzalloc(sizeof(*its_node), GFP_KERNEL); + if (!its_node) + return -ENOMEM; + + mutex_init(&its_node->dev_alloc_lock); + xa_init(&its_node->its_devices); + its_node->fwnode =3D handle; + its_node->its_base =3D its_base; + its_node->msi_domain_flags =3D IRQ_DOMAIN_FLAG_ISOLATED_MSI | + IRQ_DOMAIN_FLAG_FWNODE_PARENT; + + cr0 =3D its_readl_relaxed(its_node, GICV5_ITS_CR0); + enabled =3D FIELD_GET(GICV5_ITS_CR0_ITSEN, cr0); + if (WARN(enabled, "ITS %s enabled, disabling it before proceeding\n", np-= >full_name)) { + ret =3D gicv5_its_disable(its_node); + if (ret) + goto out_free_node; + } + + if (of_property_read_bool(np, "dma-noncoherent")) { + /* + * A non-coherent ITS implies that some cache levels cannot be + * used coherently by the cores and GIC. Our only option is to mark + * memory attributes for the GIC as non-cacheable; by default, + * non-cacheable memory attributes imply outer-shareable + * shareability, the value written into ITS_CR1_SH is ignored. + */ + cr1 =3D FIELD_PREP(GICV5_ITS_CR1_ITT_RA, GICV5_NO_READ_ALLOC) | + FIELD_PREP(GICV5_ITS_CR1_DT_RA, GICV5_NO_READ_ALLOC) | + FIELD_PREP(GICV5_ITS_CR1_IC, GICV5_NON_CACHE) | + FIELD_PREP(GICV5_ITS_CR1_OC, GICV5_NON_CACHE); + its_node->flags |=3D ITS_FLAGS_NON_COHERENT; + } else { + cr1 =3D FIELD_PREP(GICV5_ITS_CR1_ITT_RA, GICV5_READ_ALLOC) | + FIELD_PREP(GICV5_ITS_CR1_DT_RA, GICV5_READ_ALLOC) | + FIELD_PREP(GICV5_ITS_CR1_IC, GICV5_WB_CACHE) | + FIELD_PREP(GICV5_ITS_CR1_OC, GICV5_WB_CACHE) | + FIELD_PREP(GICV5_ITS_CR1_SH, GICV5_INNER_SHARE); + } + + its_writel_relaxed(its_node, cr1, GICV5_ITS_CR1); + + ret =3D gicv5_its_init_devtab(its_node); + if (ret) + goto out_free_node; + + ret =3D gicv5_its_enable(its_node); + if (ret) + goto out_free_devtab; + + ret =3D gicv5_its_init_domain(its_node, parent_domain); + if (ret) + goto out_disable_its; + + gicv5_its_print_info(its_node); + + return 0; + +out_disable_its: + gicv5_its_disable(its_node); +out_free_devtab: + gicv5_its_deinit_devtab(its_node); +out_free_node: + kfree(its_node); + return ret; +} + +static int __init gicv5_its_init(struct device_node *node) +{ + void __iomem *its_base; + int ret, idx; + + idx =3D of_property_match_string(node, "reg-names", "ns-config"); + if (idx < 0) { + pr_err("%pOF: ns-config reg-name not present\n", node); + return -ENODEV; + } + + its_base =3D of_io_request_and_map(node, idx, of_node_full_name(node)); + if (IS_ERR(its_base)) { + pr_err("%pOF: unable to map GICv5 ITS_CONFIG_FRAME\n", node); + return PTR_ERR(its_base); + } + + ret =3D gicv5_its_init_bases(its_base, of_fwnode_handle(node), + gicv5_global_data.lpi_domain); + if (ret) + goto out_unmap; + + return 0; + +out_unmap: + iounmap(its_base); + return ret; +} + +void __init gicv5_its_of_probe(struct device_node *parent) +{ + struct device_node *np; + + for_each_available_child_of_node(parent, np) { + if (!of_device_is_compatible(np, "arm,gic-v5-its")) + continue; + + if (gicv5_its_init(np)) + pr_err("Failed to init ITS %s\n", np->full_name); + } +} diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c index 97ff935d79bd..a9e3e75adb96 100644 --- a/drivers/irqchip/irq-gic-v5.c +++ b/drivers/irqchip/irq-gic-v5.c @@ -1071,6 +1071,8 @@ static int __init gicv5_of_init(struct device_node *n= ode, struct device_node *pa =20 gicv5_smp_init(); =20 + gicv5_irs_its_probe(); + return 0; =20 out_int: diff --git a/include/linux/irqchip/arm-gic-v5.h b/include/linux/irqchip/arm= -gic-v5.h index 680eed794a35..07b952549bfa 100644 --- a/include/linux/irqchip/arm-gic-v5.h +++ b/include/linux/irqchip/arm-gic-v5.h @@ -50,6 +50,8 @@ #define GICV5_IRS_IDR7 0x001c #define GICV5_IRS_CR0 0x0080 #define GICV5_IRS_CR1 0x0084 +#define GICV5_IRS_SYNCR 0x00c0 +#define GICV5_IRS_SYNC_STATUSR 0x00c4 #define GICV5_IRS_SPI_SELR 0x0108 #define GICV5_IRS_SPI_CFGR 0x0114 #define GICV5_IRS_SPI_STATUSR 0x0118 @@ -103,6 +105,10 @@ #define GICV5_IRS_CR1_OC GENMASK(3, 2) #define GICV5_IRS_CR1_SH GENMASK(1, 0) =20 +#define GICV5_IRS_SYNCR_SYNC BIT(31) + +#define GICV5_IRS_SYNC_STATUSR_IDLE BIT(0) + #define GICV5_IRS_SPI_STATUSR_V BIT(1) #define GICV5_IRS_SPI_STATUSR_IDLE BIT(0) =20 @@ -144,6 +150,104 @@ =20 #define GICV5_ISTL1E_L2_ADDR_MASK GENMASK_ULL(55, 12) =20 +/* + * ITS registers and tables structures + */ +#define GICV5_ITS_IDR1 0x0004 +#define GICV5_ITS_IDR2 0x0008 +#define GICV5_ITS_CR0 0x0080 +#define GICV5_ITS_CR1 0x0084 +#define GICV5_ITS_DT_BASER 0x00c0 +#define GICV5_ITS_DT_CFGR 0x00d0 +#define GICV5_ITS_DIDR 0x0100 +#define GICV5_ITS_EIDR 0x0108 +#define GICV5_ITS_INV_EVENTR 0x010c +#define GICV5_ITS_INV_DEVICER 0x0110 +#define GICV5_ITS_STATUSR 0x0120 +#define GICV5_ITS_SYNCR 0x0140 +#define GICV5_ITS_SYNC_STATUSR 0x0148 + +#define GICV5_ITS_IDR1_L2SZ GENMASK(10, 8) +#define GICV5_ITS_IDR1_ITT_LEVELS BIT(7) +#define GICV5_ITS_IDR1_DT_LEVELS BIT(6) +#define GICV5_ITS_IDR1_DEVICEID_BITS GENMASK(5, 0) + +#define GICV5_ITS_IDR1_L2SZ_SUPPORT_4KB(r) FIELD_GET(BIT(8), (r)) +#define GICV5_ITS_IDR1_L2SZ_SUPPORT_16KB(r) FIELD_GET(BIT(9), (r)) +#define GICV5_ITS_IDR1_L2SZ_SUPPORT_64KB(r) FIELD_GET(BIT(10), (r)) + +#define GICV5_ITS_IDR2_XDMN_EVENTs GENMASK(6, 5) +#define GICV5_ITS_IDR2_EVENTID_BITS GENMASK(4, 0) + +#define GICV5_ITS_CR0_IDLE BIT(1) +#define GICV5_ITS_CR0_ITSEN BIT(0) + +#define GICV5_ITS_CR1_ITT_RA BIT(7) +#define GICV5_ITS_CR1_DT_RA BIT(6) +#define GICV5_ITS_CR1_IC GENMASK(5, 4) +#define GICV5_ITS_CR1_OC GENMASK(3, 2) +#define GICV5_ITS_CR1_SH GENMASK(1, 0) + +#define GICV5_ITS_DT_CFGR_STRUCTURE BIT(16) +#define GICV5_ITS_DT_CFGR_L2SZ GENMASK(7, 6) +#define GICV5_ITS_DT_CFGR_DEVICEID_BITS GENMASK(5, 0) + +#define GICV5_ITS_DT_BASER_ADDR_MASK GENMASK_ULL(55, 3) + +#define GICV5_ITS_INV_DEVICER_I BIT(31) +#define GICV5_ITS_INV_DEVICER_EVENTID_BITS GENMASK(5, 1) +#define GICV5_ITS_INV_DEVICER_L1 BIT(0) + +#define GICV5_ITS_DIDR_DEVICEID GENMASK_ULL(31, 0) + +#define GICV5_ITS_EIDR_EVENTID GENMASK(15, 0) + +#define GICV5_ITS_INV_EVENTR_I BIT(31) +#define GICV5_ITS_INV_EVENTR_ITT_L2SZ GENMASK(2, 1) +#define GICV5_ITS_INV_EVENTR_L1 BIT(0) + +#define GICV5_ITS_STATUSR_IDLE BIT(0) + +#define GICV5_ITS_SYNCR_SYNC BIT_ULL(63) +#define GICV5_ITS_SYNCR_SYNCALL BIT_ULL(32) +#define GICV5_ITS_SYNCR_DEVICEID GENMASK_ULL(31, 0) + +#define GICV5_ITS_SYNC_STATUSR_IDLE BIT(0) + +#define GICV5_DTL1E_VALID BIT_ULL(0) +/* Note that there is no shift for the address by design */ +#define GICV5_DTL1E_L2_ADDR_MASK GENMASK_ULL(55, 3) +#define GICV5_DTL1E_SPAN GENMASK_ULL(63, 60) + +#define GICV5_DTL2E_VALID BIT_ULL(0) +#define GICV5_DTL2E_ITT_L2SZ GENMASK_ULL(2, 1) +/* Note that there is no shift for the address by design */ +#define GICV5_DTL2E_ITT_ADDR_MASK GENMASK_ULL(55, 3) +#define GICV5_DTL2E_ITT_DSWE BIT_ULL(57) +#define GICV5_DTL2E_ITT_STRUCTURE BIT_ULL(58) +#define GICV5_DTL2E_EVENT_ID_BITS GENMASK_ULL(63, 59) + +#define GICV5_ITTL1E_VALID BIT_ULL(0) +/* Note that there is no shift for the address by design */ +#define GICV5_ITTL1E_L2_ADDR_MASK GENMASK_ULL(55, 3) +#define GICV5_ITTL1E_SPAN GENMASK_ULL(63, 60) + +#define GICV5_ITTL2E_LPI_ID GENMASK_ULL(23, 0) +#define GICV5_ITTL2E_DAC GENMASK_ULL(29, 28) +#define GICV5_ITTL2E_VIRTUAL BIT_ULL(30) +#define GICV5_ITTL2E_VALID BIT_ULL(31) +#define GICV5_ITTL2E_VM_ID GENMASK_ULL(47, 32) + +#define GICV5_ITS_DT_ITT_CFGR_L2SZ_4k 0b00 +#define GICV5_ITS_DT_ITT_CFGR_L2SZ_16k 0b01 +#define GICV5_ITS_DT_ITT_CFGR_L2SZ_64k 0b10 + +#define GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR 0 +#define GICV5_ITS_DT_ITT_CFGR_STRUCTURE_TWO_LEVEL 1 + +#define GICV5_ITS_HWIRQ_DEVICE_ID GENMASK_ULL(31, 0) +#define GICV5_ITS_HWIRQ_EVENT_ID GENMASK_ULL(63, 32) + /* * Global Data structures and functions */ @@ -197,24 +301,77 @@ static inline int gicv5_wait_for_op_s_atomic(void __i= omem *addr, u32 offset, return 0; } =20 +static inline int gicv5_wait_for_op_s(void __iomem *addr, u32 offset, + const char *reg_s, u32 mask) +{ + void __iomem *reg =3D addr + offset; + u32 val; + int ret; + + ret =3D readl_poll_timeout(reg, val, val & mask, 1, 10 * USEC_PER_MSEC); + if (unlikely(ret =3D=3D -ETIMEDOUT)) { + pr_err_ratelimited("%s timeout...\n", reg_s); + return ret; + } + + return 0; +} + #define gicv5_wait_for_op_atomic(base, reg, mask, val) \ gicv5_wait_for_op_s_atomic(base, reg, #reg, mask, val) =20 +#define gicv5_wait_for_op(base, reg, mask) \ + gicv5_wait_for_op_s(base, reg, #reg, mask) + void __init gicv5_init_lpi_domain(void); void __init gicv5_free_lpi_domain(void); =20 int gicv5_irs_of_probe(struct device_node *parent); void gicv5_irs_remove(void); int gicv5_irs_enable(void); +void gicv5_irs_its_probe(void); int gicv5_irs_register_cpu(int cpuid); int gicv5_irs_cpu_to_iaffid(int cpu_id, u16 *iaffid); struct gicv5_irs_chip_data *gicv5_irs_lookup_by_spi_id(u32 spi_id); int gicv5_spi_irq_set_type(struct irq_data *d, unsigned int type); int gicv5_irs_iste_alloc(u32 lpi); +void gicv5_irs_syncr(void); + +struct gicv5_its_devtab_cfg { + union { + struct { + __le64 *devtab; + } linear; + struct { + __le64 *l1devtab; + __le64 **l2ptrs; + } l2; + }; + u32 cfgr; +}; + +struct gicv5_its_itt_cfg { + union { + struct { + __le64 *itt; + unsigned int num_ents; + } linear; + struct { + __le64 *l1itt; + __le64 **l2ptrs; + unsigned int num_l1_ents; + u8 l2sz; + } l2; + }; + u8 event_id_bits; + bool l2itt; +}; =20 void gicv5_init_lpis(u32 max); void gicv5_deinit_lpis(void); =20 int gicv5_alloc_lpi(void); void gicv5_free_lpi(u32 lpi); + +void __init gicv5_its_of_probe(struct device_node *parent); #endif --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 46D032E3B01; Thu, 3 Jul 2025 10:27:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538475; cv=none; b=q3GAZViGf/nExqQjiLXl0MXbRlfoLY6g7f53I1QQzf0D609D5DlmQfhIEwFwvCBsmW7KaU7gSb0X3raZazkeTeuNAmz1m9YKZHY9xDpp49f25fiDmCf0fbuUXaau8xY5pU5z1rUdvFMqylqW66Ay0OebFGT27f6vk5ButZe9O1g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538475; c=relaxed/simple; bh=6xMnWOG8+UY1fkqV4BBV0oBxtt0IAo27S1yVhH1NjGY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ku05sP8bMVZ5tTRUxrSOK8bOREHnF9ifyJCdEt75HFz/dx50C+maxGcb49q+75mQxMXTeL8OJt33zvRonU+LBToRJJsywiPeF1sRMgK/XQdvn3GtKx6Gle2opBDTdd0FutMKl8jFvnHaIAOSgG1gH55rsoOEJOVGWPTUnSzXKjU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lulaPQY4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lulaPQY4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E3643C4CEED; Thu, 3 Jul 2025 10:27:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538474; bh=6xMnWOG8+UY1fkqV4BBV0oBxtt0IAo27S1yVhH1NjGY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=lulaPQY4gRzQ8Si1hTl/r3fN49UaWNsrlqLJl4MLrOgD3xunVb2sV9RK+OB2Fa6bt aFcMNYKWPBVsz+b0qHN4ZU6PVXC5nT1268MA6rUFA91oyO0DD2jonJPLgj1icuATpX 9LkoSaBQ7UhLdHw30Fvl5a6v9q6n+49WOZYeOOSW1wqmCsnUv19ciFqtrJ1zlrTUGr K0N09Brd+bQwee/XEaUTJSmCE14T4hWpnPt1w8McVwaQA6EPSSJXIhZGKe5gu2INbd CFiNZNeB26Wf0F16Vtoe2uVwAbHt5YP6FxyALuPxO4JcJR9LVzbYN7k/MMHpfIop/n 4pW7dNz5Czr4A== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:19 +0200 Subject: [PATCH v7 29/31] irqchip/gic-v5: Add GICv5 IWB support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-29-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e The GICv5 architecture implements the Interrupt Wire Bridge (IWB) in order to support wired interrupts that cannot be connected directly to an IRS and instead uses the ITS to translate a wire event into an IRQ signal. Add the wired-to-MSI IWB driver to manage IWB wired interrupts. An IWB is connected to an ITS and it has its own deviceID for all interrupt wires that it manages; the IWB input wire number must be exposed to the ITS as an eventID with a 1:1 mapping. This eventID is not programmable and therefore requires a new msi_alloc_info_t flag to make sure the ITS driver does not allocate an eventid for the wire but rather it uses the msi_alloc_info_t.hwirq number to gather the ITS eventID. Co-developed-by: Sascha Bischoff Signed-off-by: Sascha Bischoff Co-developed-by: Timothy Hayes Signed-off-by: Timothy Hayes Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Thomas Gleixner Cc: Marc Zyngier --- drivers/irqchip/Makefile | 3 +- drivers/irqchip/irq-gic-v5-its.c | 40 ++++-- drivers/irqchip/irq-gic-v5-iwb.c | 284 +++++++++++++++++++++++++++++++++= ++++ include/asm-generic/msi.h | 1 + include/linux/irqchip/arm-gic-v5.h | 17 +++ 5 files changed, 335 insertions(+), 10 deletions(-) diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 5459f66e597f..e83dad932ac0 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -37,7 +37,8 @@ obj-$(CONFIG_ARM_GIC_ITS_PARENT) +=3D irq-gic-its-msi-par= ent.o obj-$(CONFIG_ARM_GIC_V3_ITS) +=3D irq-gic-v3-its.o irq-gic-v4.o obj-$(CONFIG_ARM_GIC_V3_ITS_FSL_MC) +=3D irq-gic-v3-its-fsl-mc-msi.o obj-$(CONFIG_PARTITION_PERCPU) +=3D irq-partition-percpu.o -obj-$(CONFIG_ARM_GIC_V5) +=3D irq-gic-v5.o irq-gic-v5-irs.o irq-gic-v5-it= s.o +obj-$(CONFIG_ARM_GIC_V5) +=3D irq-gic-v5.o irq-gic-v5-irs.o irq-gic-v5-it= s.o \ + irq-gic-v5-iwb.o obj-$(CONFIG_HISILICON_IRQ_MBIGEN) +=3D irq-mbigen.o obj-$(CONFIG_ARM_NVIC) +=3D irq-nvic.o obj-$(CONFIG_ARM_VIC) +=3D irq-vic.o diff --git a/drivers/irqchip/irq-gic-v5-its.c b/drivers/irqchip/irq-gic-v5-= its.c index 700df6d0687e..340640fdbdf6 100644 --- a/drivers/irqchip/irq-gic-v5-its.c +++ b/drivers/irqchip/irq-gic-v5-its.c @@ -880,19 +880,41 @@ static void gicv5_its_unmap_event(struct gicv5_its_de= v *its_dev, u16 event_id) gicv5_its_itt_cache_inv(its, its_dev->device_id, event_id); } =20 -static int gicv5_its_alloc_eventid(struct gicv5_its_dev *its_dev, +static int gicv5_its_alloc_eventid(struct gicv5_its_dev *its_dev, msi_allo= c_info_t *info, unsigned int nr_irqs, u32 *eventid) { - int ret; + int event_id_base; =20 - ret =3D bitmap_find_free_region(its_dev->event_map, - its_dev->num_events, - get_count_order(nr_irqs)); + if (!(info->flags & MSI_ALLOC_FLAGS_FIXED_MSG_DATA)) { + event_id_base =3D bitmap_find_free_region(its_dev->event_map, + its_dev->num_events, + get_count_order(nr_irqs)); + if (event_id_base < 0) + return event_id_base; + } else { + /* + * We want to have a fixed EventID mapped for hardcoded + * message data allocations. + */ + if (WARN_ON_ONCE(nr_irqs !=3D 1)) + return -EINVAL; =20 - if (ret < 0) - return ret; + event_id_base =3D info->hwirq; =20 - *eventid =3D ret; + if (event_id_base >=3D its_dev->num_events) { + pr_err("EventID ouside of ITT range; cannot allocate an ITT entry!\n"); + + return -EINVAL; + } + + if (test_and_set_bit(event_id_base, its_dev->event_map)) { + pr_warn("Can't reserve event_id bitmap\n"); + return -EINVAL; + + } + } + + *eventid =3D event_id_base; =20 return 0; } @@ -916,7 +938,7 @@ static int gicv5_its_irq_domain_alloc(struct irq_domain= *domain, unsigned int vi =20 its_dev =3D info->scratchpad[0].ptr; =20 - ret =3D gicv5_its_alloc_eventid(its_dev, nr_irqs, &event_id_base); + ret =3D gicv5_its_alloc_eventid(its_dev, info, nr_irqs, &event_id_base); if (ret) return ret; =20 diff --git a/drivers/irqchip/irq-gic-v5-iwb.c b/drivers/irqchip/irq-gic-v5-= iwb.c new file mode 100644 index 000000000000..ed72fbdd4900 --- /dev/null +++ b/drivers/irqchip/irq-gic-v5-iwb.c @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024-2025 ARM Limited, All Rights Reserved. + */ +#define pr_fmt(fmt) "GICv5 IWB: " fmt + +#include +#include +#include +#include +#include +#include + +#include +#include + +struct gicv5_iwb_chip_data { + void __iomem *iwb_base; + u16 nr_regs; +}; + +static u32 iwb_readl_relaxed(struct gicv5_iwb_chip_data *iwb_node, const u= 32 reg_offset) +{ + return readl_relaxed(iwb_node->iwb_base + reg_offset); +} + +static void iwb_writel_relaxed(struct gicv5_iwb_chip_data *iwb_node, const= u32 val, + const u32 reg_offset) +{ + writel_relaxed(val, iwb_node->iwb_base + reg_offset); +} + +static int gicv5_iwb_wait_for_wenabler(struct gicv5_iwb_chip_data *iwb_nod= e) +{ + return gicv5_wait_for_op_atomic(iwb_node->iwb_base, GICV5_IWB_WENABLE_STA= TUSR, + GICV5_IWB_WENABLE_STATUSR_IDLE, NULL); +} + +static int __gicv5_iwb_set_wire_enable(struct gicv5_iwb_chip_data *iwb_nod= e, + u32 iwb_wire, bool enable) +{ + u32 n =3D iwb_wire / 32; + u8 i =3D iwb_wire % 32; + u32 val; + + if (n >=3D iwb_node->nr_regs) { + pr_err("IWB_WENABLER is invalid for n=3D%u\n", n); + return -EINVAL; + } + + /* + * Enable IWB wire/pin at this point + * Note: This is not the same as enabling the interrupt + */ + val =3D iwb_readl_relaxed(iwb_node, GICV5_IWB_WENABLER + (4 * n)); + if (enable) + val |=3D BIT(i); + else + val &=3D ~BIT(i); + iwb_writel_relaxed(iwb_node, val, GICV5_IWB_WENABLER + (4 * n)); + + return gicv5_iwb_wait_for_wenabler(iwb_node); +} + +static int gicv5_iwb_enable_wire(struct gicv5_iwb_chip_data *iwb_node, + u32 iwb_wire) +{ + return __gicv5_iwb_set_wire_enable(iwb_node, iwb_wire, true); +} + +static int gicv5_iwb_disable_wire(struct gicv5_iwb_chip_data *iwb_node, + u32 iwb_wire) +{ + return __gicv5_iwb_set_wire_enable(iwb_node, iwb_wire, false); +} + +static void gicv5_iwb_irq_disable(struct irq_data *d) +{ + struct gicv5_iwb_chip_data *iwb_node =3D irq_data_get_irq_chip_data(d); + + gicv5_iwb_disable_wire(iwb_node, d->hwirq); + irq_chip_disable_parent(d); +} + +static void gicv5_iwb_irq_enable(struct irq_data *d) +{ + struct gicv5_iwb_chip_data *iwb_node =3D irq_data_get_irq_chip_data(d); + + gicv5_iwb_enable_wire(iwb_node, d->hwirq); + irq_chip_enable_parent(d); +} + +static int gicv5_iwb_set_type(struct irq_data *d, unsigned int type) +{ + struct gicv5_iwb_chip_data *iwb_node =3D irq_data_get_irq_chip_data(d); + u32 iwb_wire, n, wtmr; + u8 i; + + iwb_wire =3D d->hwirq; + i =3D iwb_wire % 32; + n =3D iwb_wire / 32; + + if (n >=3D iwb_node->nr_regs) { + pr_err_once("reg %u out of range\n", n); + return -EINVAL; + } + + wtmr =3D iwb_readl_relaxed(iwb_node, GICV5_IWB_WTMR + (4 * n)); + + switch (type) { + case IRQ_TYPE_LEVEL_HIGH: + case IRQ_TYPE_LEVEL_LOW: + wtmr |=3D BIT(i); + break; + case IRQ_TYPE_EDGE_RISING: + case IRQ_TYPE_EDGE_FALLING: + wtmr &=3D ~BIT(i); + break; + default: + pr_debug("unexpected wire trigger mode"); + return -EINVAL; + } + + iwb_writel_relaxed(iwb_node, wtmr, GICV5_IWB_WTMR + (4 * n)); + + return 0; +} + +static void gicv5_iwb_domain_set_desc(msi_alloc_info_t *alloc_info, struct= msi_desc *desc) +{ + alloc_info->desc =3D desc; + alloc_info->hwirq =3D (u32)desc->data.icookie.value; +} + +static int gicv5_iwb_irq_domain_translate(struct irq_domain *d, struct irq= _fwspec *fwspec, + irq_hw_number_t *hwirq, + unsigned int *type) +{ + if (!is_of_node(fwspec->fwnode)) + return -EINVAL; + + if (fwspec->param_count < 2) + return -EINVAL; + + /* + * param[0] is be the wire + * param[1] is the interrupt type + */ + *hwirq =3D fwspec->param[0]; + *type =3D fwspec->param[1] & IRQ_TYPE_SENSE_MASK; + + return 0; +} + +static void gicv5_iwb_write_msi_msg(struct irq_data *d, struct msi_msg *ms= g) {} + +static const struct msi_domain_template iwb_msi_template =3D { + .chip =3D { + .name =3D "GICv5-IWB", + .irq_mask =3D irq_chip_mask_parent, + .irq_unmask =3D irq_chip_unmask_parent, + .irq_enable =3D gicv5_iwb_irq_enable, + .irq_disable =3D gicv5_iwb_irq_disable, + .irq_eoi =3D irq_chip_eoi_parent, + .irq_set_type =3D gicv5_iwb_set_type, + .irq_write_msi_msg =3D gicv5_iwb_write_msi_msg, + .irq_set_affinity =3D irq_chip_set_affinity_parent, + .irq_get_irqchip_state =3D irq_chip_get_parent_state, + .irq_set_irqchip_state =3D irq_chip_set_parent_state, + .flags =3D IRQCHIP_SET_TYPE_MASKED | + IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_MASK_ON_SUSPEND, + }, + + .ops =3D { + .set_desc =3D gicv5_iwb_domain_set_desc, + .msi_translate =3D gicv5_iwb_irq_domain_translate, + }, + + .info =3D { + .bus_token =3D DOMAIN_BUS_WIRED_TO_MSI, + .flags =3D MSI_FLAG_USE_DEV_FWNODE, + }, + + .alloc_info =3D { + .flags =3D MSI_ALLOC_FLAGS_FIXED_MSG_DATA, + }, +}; + +static bool gicv5_iwb_create_device_domain(struct device *dev, unsigned in= t size, + struct gicv5_iwb_chip_data *iwb_node) +{ + if (WARN_ON_ONCE(!dev->msi.domain)) + return false; + + return msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN, + &iwb_msi_template, size, + NULL, iwb_node); +} + +static struct gicv5_iwb_chip_data * +gicv5_iwb_init_bases(void __iomem *iwb_base, struct platform_device *pdev) +{ + u32 nr_wires, idr0, cr0; + unsigned int n; + int ret; + + struct gicv5_iwb_chip_data *iwb_node __free(kfree) =3D kzalloc(sizeof(*iw= b_node), + GFP_KERNEL); + if (!iwb_node) + return ERR_PTR(-ENOMEM); + + iwb_node->iwb_base =3D iwb_base; + + idr0 =3D iwb_readl_relaxed(iwb_node, GICV5_IWB_IDR0); + nr_wires =3D (FIELD_GET(GICV5_IWB_IDR0_IW_RANGE, idr0) + 1) * 32; + + cr0 =3D iwb_readl_relaxed(iwb_node, GICV5_IWB_CR0); + if (!FIELD_GET(GICV5_IWB_CR0_IWBEN, cr0)) { + dev_err(&pdev->dev, "IWB must be enabled in firmware\n"); + return ERR_PTR(-EINVAL); + } + + iwb_node->nr_regs =3D FIELD_GET(GICV5_IWB_IDR0_IW_RANGE, idr0) + 1; + + for (n =3D 0; n < iwb_node->nr_regs; n++) + iwb_writel_relaxed(iwb_node, 0, GICV5_IWB_WENABLER + (sizeof(u32) * n)); + + ret =3D gicv5_iwb_wait_for_wenabler(iwb_node); + if (ret) + return ERR_PTR(ret); + + if (!gicv5_iwb_create_device_domain(&pdev->dev, nr_wires, iwb_node)) + return ERR_PTR(-ENOMEM); + + return_ptr(iwb_node); +} + +static int gicv5_iwb_device_probe(struct platform_device *pdev) +{ + struct gicv5_iwb_chip_data *iwb_node; + void __iomem *iwb_base; + struct resource *res; + int ret; + + res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + iwb_base =3D devm_ioremap(&pdev->dev, res->start, resource_size(res)); + if (!iwb_base) { + dev_err(&pdev->dev, "failed to ioremap %pR\n", res); + return -ENOMEM; + } + + iwb_node =3D gicv5_iwb_init_bases(iwb_base, pdev); + if (IS_ERR(iwb_node)) { + ret =3D PTR_ERR(iwb_node); + goto out_unmap; + } + + return 0; + +out_unmap: + iounmap(iwb_base); + return ret; +} + +static const struct of_device_id gicv5_iwb_of_match[] =3D { + { .compatible =3D "arm,gic-v5-iwb" }, + { /* END */ } +}; +MODULE_DEVICE_TABLE(of, gicv5_iwb_of_match); + +static struct platform_driver gicv5_iwb_platform_driver =3D { + .driver =3D { + .name =3D "GICv5 IWB", + .of_match_table =3D gicv5_iwb_of_match, + .suppress_bind_attrs =3D true, + }, + .probe =3D gicv5_iwb_device_probe, +}; + +module_platform_driver(gicv5_iwb_platform_driver); diff --git a/include/asm-generic/msi.h b/include/asm-generic/msi.h index 124c734ca5d9..92cca4b23f13 100644 --- a/include/asm-generic/msi.h +++ b/include/asm-generic/msi.h @@ -33,6 +33,7 @@ typedef struct msi_alloc_info { =20 /* Device generating MSIs is proxying for another device */ #define MSI_ALLOC_FLAGS_PROXY_DEVICE (1UL << 0) +#define MSI_ALLOC_FLAGS_FIXED_MSG_DATA (1UL << 1) =20 #define GENERIC_MSI_DOMAIN_OPS 1 =20 diff --git a/include/linux/irqchip/arm-gic-v5.h b/include/linux/irqchip/arm= -gic-v5.h index 07b952549bfa..68ddcdb1cec5 100644 --- a/include/linux/irqchip/arm-gic-v5.h +++ b/include/linux/irqchip/arm-gic-v5.h @@ -248,6 +248,23 @@ #define GICV5_ITS_HWIRQ_DEVICE_ID GENMASK_ULL(31, 0) #define GICV5_ITS_HWIRQ_EVENT_ID GENMASK_ULL(63, 32) =20 +/* + * IWB registers + */ +#define GICV5_IWB_IDR0 0x0000 +#define GICV5_IWB_CR0 0x0080 +#define GICV5_IWB_WENABLE_STATUSR 0x00c0 +#define GICV5_IWB_WENABLER 0x2000 +#define GICV5_IWB_WTMR 0x4000 + +#define GICV5_IWB_IDR0_INT_DOMS GENMASK(14, 11) +#define GICV5_IWB_IDR0_IW_RANGE GENMASK(10, 0) + +#define GICV5_IWB_CR0_IDLE BIT(1) +#define GICV5_IWB_CR0_IWBEN BIT(0) + +#define GICV5_IWB_WENABLE_STATUSR_IDLE BIT(0) + /* * Global Data structures and functions */ --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C221D2ED15C; Thu, 3 Jul 2025 10:28:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538480; cv=none; b=dZ2OuZgIidn7XvZbzMbSNFO8Gj+mWxXsvX8tWWQdC1AYAS3P9YSGxko3LI+7xfcm4j5C5Z74LCLMz+B1AtZj9jxFvhaxbvtkw7JSr2yKnlbMlEXkL7CiBgLAmrYGxMYRvV3BGlcWAZ7FwJG7zCqJXL8QVXEYIx/fGHjS9WuKn9E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538480; c=relaxed/simple; bh=a9U6Azq4WkypWVG3l97xIWofH9Tf5doWeAgGMdKJXuc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Yzc8vC/bW1+jAlC63SkG4N7PgeZeTdCCPnKF9VOAJb32+O+rG3nHD7q+rkOJJH8NEsPdmxl/1VPAVyU/7le/1hHU244cVswLptNbI78BYADnQtk7KBMPotHcTKcDhmMF66qZYSl95tJpWJNBNviFmGmH3Anap+U6ZNOGM/EStfI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TFkpoiIN; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="TFkpoiIN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 53D42C4CEF1; Thu, 3 Jul 2025 10:27:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538480; bh=a9U6Azq4WkypWVG3l97xIWofH9Tf5doWeAgGMdKJXuc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=TFkpoiINC7Z5rFT3hlV8oq2Vhsf3HmazFCFhtdH4BoIagxTsqLmxUrw5M3Mn4MEEn 9kS+n6pTYH9dJxZA7+NohMiNnhVDt2IOYCkCIltc43n2RyIEBz1nwn5JLu/rjc0PhA DjYMqjKYRTyrXHgsuh0WDFcajeHwYWPEKxam8OHVsLDkYGpOuFxQeLV2VgbO7j9RvL q5/ZgTVYqbZ3p2loFCoWKep+L9qAvOjFbxrKUjqeNWW2uJff6wGPSl7Q52Z2iHYAGn LZ91Ik0HsmBh0OY8+ANQ6fRoo26VA9Oy+epkXAsT1Xfxkzlvz5/5HnQio3dlmYGH3u zpMD6zKUz+SUg== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:20 +0200 Subject: [PATCH v7 30/31] docs: arm64: gic-v5: Document booting requirements for GICv5 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-30-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Document the requirements for booting a kernel on a system implementing a GICv5 interrupt controller. Specifically, other than DT/ACPI providing the required firmware representation, define what traps must be disabled if the kernel is booted at EL1 on a system where EL2 is implemented. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- Documentation/arch/arm64/booting.rst | 41 ++++++++++++++++++++++++++++++++= ++++ 1 file changed, 41 insertions(+) diff --git a/Documentation/arch/arm64/booting.rst b/Documentation/arch/arm6= 4/booting.rst index dee7b6de864f..4b1d416c6016 100644 --- a/Documentation/arch/arm64/booting.rst +++ b/Documentation/arch/arm64/booting.rst @@ -223,6 +223,47 @@ Before jumping into the kernel, the following conditio= ns must be met: =20 - SCR_EL3.HCE (bit 8) must be initialised to 0b1. =20 + For systems with a GICv5 interrupt controller to be used in v5 mode: + + - If the kernel is entered at EL1 and EL2 is present: + + - ICH_HFGRTR_EL2.ICC_PPI_ACTIVERn_EL1 (bit 20) must be initialised t= o 0b1. + - ICH_HFGRTR_EL2.ICC_PPI_PRIORITYRn_EL1 (bit 19) must be initialised= to 0b1. + - ICH_HFGRTR_EL2.ICC_PPI_PENDRn_EL1 (bit 18) must be initialised to = 0b1. + - ICH_HFGRTR_EL2.ICC_PPI_ENABLERn_EL1 (bit 17) must be initialised t= o 0b1. + - ICH_HFGRTR_EL2.ICC_PPI_HMRn_EL1 (bit 16) must be initialised to 0b= 1. + - ICH_HFGRTR_EL2.ICC_IAFFIDR_EL1 (bit 7) must be initialised to 0b1. + - ICH_HFGRTR_EL2.ICC_ICSR_EL1 (bit 6) must be initialised to 0b1. + - ICH_HFGRTR_EL2.ICC_PCR_EL1 (bit 5) must be initialised to 0b1. + - ICH_HFGRTR_EL2.ICC_HPPIR_EL1 (bit 4) must be initialised to 0b1. + - ICH_HFGRTR_EL2.ICC_HAPR_EL1 (bit 3) must be initialised to 0b1. + - ICH_HFGRTR_EL2.ICC_CR0_EL1 (bit 2) must be initialised to 0b1. + - ICH_HFGRTR_EL2.ICC_IDRn_EL1 (bit 1) must be initialised to 0b1. + - ICH_HFGRTR_EL2.ICC_APR_EL1 (bit 0) must be initialised to 0b1. + + - ICH_HFGWTR_EL2.ICC_PPI_ACTIVERn_EL1 (bit 20) must be initialised t= o 0b1. + - ICH_HFGWTR_EL2.ICC_PPI_PRIORITYRn_EL1 (bit 19) must be initialised= to 0b1. + - ICH_HFGWTR_EL2.ICC_PPI_PENDRn_EL1 (bit 18) must be initialised to = 0b1. + - ICH_HFGWTR_EL2.ICC_PPI_ENABLERn_EL1 (bit 17) must be initialised t= o 0b1. + - ICH_HFGWTR_EL2.ICC_ICSR_EL1 (bit 6) must be initialised to 0b1. + - ICH_HFGWTR_EL2.ICC_PCR_EL1 (bit 5) must be initialised to 0b1. + - ICH_HFGWTR_EL2.ICC_CR0_EL1 (bit 2) must be initialised to 0b1. + - ICH_HFGWTR_EL2.ICC_APR_EL1 (bit 0) must be initialised to 0b1. + + - ICH_HFGITR_EL2.GICRCDNMIA (bit 10) must be initialised to 0b1. + - ICH_HFGITR_EL2.GICRCDIA (bit 9) must be initialised to 0b1. + - ICH_HFGITR_EL2.GICCDDI (bit 8) must be initialised to 0b1. + - ICH_HFGITR_EL2.GICCDEOI (bit 7) must be initialised to 0b1. + - ICH_HFGITR_EL2.GICCDHM (bit 6) must be initialised to 0b1. + - ICH_HFGITR_EL2.GICCDRCFG (bit 5) must be initialised to 0b1. + - ICH_HFGITR_EL2.GICCDPEND (bit 4) must be initialised to 0b1. + - ICH_HFGITR_EL2.GICCDAFF (bit 3) must be initialised to 0b1. + - ICH_HFGITR_EL2.GICCDPRI (bit 2) must be initialised to 0b1. + - ICH_HFGITR_EL2.GICCDDIS (bit 1) must be initialised to 0b1. + - ICH_HFGITR_EL2.GICCDEN (bit 0) must be initialised to 0b1. + + - The DT or ACPI tables must describe a GICv5 interrupt controller. + For systems with a GICv3 interrupt controller to be used in v3 mode: - If EL3 is present: =20 --=20 2.48.0 From nobody Wed Oct 8 01:59:35 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D82AA2ED85C; Thu, 3 Jul 2025 10:28:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538486; cv=none; b=LPqSgm2gEMaaH1ZaVRJGK1Vj9fOTMt93+B2Chd54yqVgHMVdpYeoKd8jd1YxbNUFLawQXLR3IH+PfL+DrYx4wuZT3VijnQl6EwSjC9UATQt44uLUNYx0eEA+zxi2MnpMgqPseb6wTS99AglB0g1cqrgbV+HSu/WyKTpeGKf1Uxo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751538486; c=relaxed/simple; bh=W/C4b3BY2gqbZVQ+W28M+ecYH4Ph9mXAsDV/aos0XlQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Hxq7PV+5Dpb3eH7USfuqlCqUeyQ7nt171xdmHsM9WTLEzMCbAiYGzl0byawlTkLWzcWR3aFLPuYdvX7B2E0ZrPuky9qIZzrepHqqK5Eok/TZfExOQMtHH5mJYszjCXulFZ44dx9mKq8svzuXjbkZ8gvpdoclhiucaOML2YwZ+z0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BYiDKkib; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BYiDKkib" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C7968C4CEF3; Thu, 3 Jul 2025 10:28:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1751538485; bh=W/C4b3BY2gqbZVQ+W28M+ecYH4Ph9mXAsDV/aos0XlQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=BYiDKkibLsr7oj7tfP/jdvaECF/8F81Uy/9i2B+qpAnJxPYXfnIsDLx4NqEIRwX7A IboCL3ZHok1OqAFcIh1nOQRCR00oAOAFyJsP4PzKxO6NcTp72Q1UYPH0lv55YnJSHc 7WnYXWeHvfQlLAjG4OVls66xxXjLpGAdH4RlotAfvyFbVxxck4UKPxn280Bjvx6ZR7 fdBYFzE+I62ByCsMK66f73g0ZPBF3PK3+sa9PoRI/p2yWSs+MLGUz18HBQOiQTBl77 zjz8QTE3VgxQwpX6FMpbx9euTFaWgXPPGqziLKUjrTWTgsEepktLdWg+3xwp0PzJrO cH9oLSjwlaFgA== From: Lorenzo Pieralisi Date: Thu, 03 Jul 2025 12:25:21 +0200 Subject: [PATCH v7 31/31] arm64: Kconfig: Enable GICv5 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250703-gicv5-host-v7-31-12e71f1b3528@kernel.org> References: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> In-Reply-To: <20250703-gicv5-host-v7-0-12e71f1b3528@kernel.org> To: Marc Zyngier , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Catalin Marinas , Will Deacon Cc: Arnd Bergmann , Sascha Bischoff , Jonathan Cameron , Timothy Hayes , Bjorn Helgaas , "Liam R. Howlett" , Peter Maydell , Mark Rutland , Jiri Slaby , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-pci@vger.kernel.org, Lorenzo Pieralisi X-Mailer: b4 0.15-dev-6f78e Enable GICv5 driver code for the ARM64 architecture. Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marc Zyngier Cc: Will Deacon Cc: Catalin Marinas Cc: Marc Zyngier Acked-by: Catalin Marinas --- arch/arm64/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 55fc331af337..5ff757cb7cd2 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -129,6 +129,7 @@ config ARM64 select ARM_GIC_V2M if PCI select ARM_GIC_V3 select ARM_GIC_V3_ITS if PCI + select ARM_GIC_V5 select ARM_PSCI_FW select BUILDTIME_TABLE_SORT select CLONE_BACKWARDS --=20 2.48.0