* [PATCH v4 4/8] dt-bindings: can: fsl,flexcan: add NXP S32N79 SoC support
From: Ciprian Costea @ 2026-03-26 13:58 UTC (permalink / raw)
To: Marc Kleine-Budde, Vincent Mailhol, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
Fabio Estevam
Cc: Pengutronix Kernel Team, linux-can, devicetree, linux-kernel, imx,
linux-arm-kernel, NXP S32 Linux Team, Christophe Lizzi,
Alberto Ruiz, Enric Balletbo, Eric Chanudet,
Ciprian Marian Costea, Andra-Teodora Ilie, Larisa Grigore,
Conor Dooley
In-Reply-To: <20260326135825.3428856-1-ciprianmarian.costea@oss.nxp.com>
From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
Add NXP S32N79 SoC compatible string and interrupt properties.
On S32N79, FlexCAN IP is integrated with two interrupt lines:
one for the mailbox interrupts (0-127) and one for signaling
bus errors and device state changes.
Co-developed-by: Andra-Teodora Ilie <andra.ilie@nxp.com>
Signed-off-by: Andra-Teodora Ilie <andra.ilie@nxp.com>
Co-developed-by: Larisa Grigore <larisa.grigore@nxp.com>
Signed-off-by: Larisa Grigore <larisa.grigore@nxp.com>
Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
---
.../bindings/net/can/fsl,flexcan.yaml | 30 ++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml b/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml
index f81d56f7c12a..d098a44c2b9c 100644
--- a/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml
+++ b/Documentation/devicetree/bindings/net/can/fsl,flexcan.yaml
@@ -26,6 +26,7 @@ properties:
- fsl,ls1021ar2-flexcan
- fsl,lx2160ar1-flexcan
- nxp,s32g2-flexcan
+ - nxp,s32n79-flexcan
- items:
- enum:
- fsl,imx53-flexcan
@@ -173,11 +174,38 @@ allOf:
- const: mb-1
required:
- interrupt-names
- else:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: nxp,s32n79-flexcan
+ then:
+ properties:
+ interrupts:
+ items:
+ - description: Message Buffer interrupt for mailboxes 0-127
+ - description: Bus Error and Device state change interrupt
+ interrupt-names:
+ items:
+ - const: mb-0
+ - const: berr
+ required:
+ - interrupt-names
+
+ - if:
+ not:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - nxp,s32g2-flexcan
+ - nxp,s32n79-flexcan
+ then:
properties:
interrupts:
maxItems: 1
interrupt-names: false
+
- if:
required:
- xceiver-supply
--
2.43.0
^ permalink raw reply related
* [PATCH v4 5/8] can: flexcan: add FLEXCAN_QUIRK_IRQ_BERR quirk
From: Ciprian Costea @ 2026-03-26 13:58 UTC (permalink / raw)
To: Marc Kleine-Budde, Vincent Mailhol, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
Fabio Estevam
Cc: Pengutronix Kernel Team, linux-can, devicetree, linux-kernel, imx,
linux-arm-kernel, NXP S32 Linux Team, Christophe Lizzi,
Alberto Ruiz, Enric Balletbo, Eric Chanudet,
Ciprian Marian Costea, Larisa Grigore
In-Reply-To: <20260326135825.3428856-1-ciprianmarian.costea@oss.nxp.com>
From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
Introduce FLEXCAN_QUIRK_IRQ_BERR quirk to handle hardware integration
where the FlexCAN module has a dedicated interrupt line for signaling
bus errors and device state changes.
This adds the flexcan_irq_esr() handler which composes
flexcan_do_state() and flexcan_do_berr() to handle platforms where
these events share a single IRQ line.
Also extend flexcan_chip_interrupts_enable() to disable/enable the
new IRQ line during IMASK register writes.
This is required for NXP S32N79 SoC support.
Co-developed-by: Larisa Grigore <larisa.grigore@nxp.com>
Signed-off-by: Larisa Grigore <larisa.grigore@nxp.com>
Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
---
drivers/net/can/flexcan/flexcan-core.c | 54 +++++++++++++++++++++-----
drivers/net/can/flexcan/flexcan.h | 2 +
2 files changed, 47 insertions(+), 9 deletions(-)
diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
index 32e4d4da00a1..23ddf7910641 100644
--- a/drivers/net/can/flexcan/flexcan-core.c
+++ b/drivers/net/can/flexcan/flexcan-core.c
@@ -1293,6 +1293,22 @@ static irqreturn_t flexcan_irq_boff(int irq, void *dev_id)
return handled;
}
+/* Combined bus error and state change IRQ handler */
+static irqreturn_t flexcan_irq_esr(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct flexcan_priv *priv = netdev_priv(dev);
+ irqreturn_t handled;
+
+ handled = flexcan_do_state(dev);
+ handled |= flexcan_do_berr(dev);
+
+ if (handled)
+ can_rx_offload_irq_finish(&priv->offload);
+
+ return handled;
+}
+
static void flexcan_set_bittiming_ctrl(const struct net_device *dev)
{
const struct flexcan_priv *priv = netdev_priv(dev);
@@ -1549,10 +1565,10 @@ static void flexcan_chip_interrupts_enable(const struct net_device *dev)
u64 reg_imask;
disable_irq(dev->irq);
- if (quirks & FLEXCAN_QUIRK_NR_IRQ_3) {
+ if (quirks & FLEXCAN_QUIRK_NR_IRQ_3)
disable_irq(priv->irq_boff);
+ if (quirks & (FLEXCAN_QUIRK_NR_IRQ_3 | FLEXCAN_QUIRK_IRQ_BERR))
disable_irq(priv->irq_err);
- }
if (quirks & FLEXCAN_QUIRK_SECONDARY_MB_IRQ)
disable_irq(priv->irq_secondary_mb);
@@ -1564,10 +1580,10 @@ static void flexcan_chip_interrupts_enable(const struct net_device *dev)
enable_irq(dev->irq);
if (quirks & FLEXCAN_QUIRK_SECONDARY_MB_IRQ)
enable_irq(priv->irq_secondary_mb);
- if (quirks & FLEXCAN_QUIRK_NR_IRQ_3) {
- enable_irq(priv->irq_boff);
+ if (quirks & (FLEXCAN_QUIRK_NR_IRQ_3 | FLEXCAN_QUIRK_IRQ_BERR))
enable_irq(priv->irq_err);
- }
+ if (quirks & FLEXCAN_QUIRK_NR_IRQ_3)
+ enable_irq(priv->irq_boff);
}
static void flexcan_chip_interrupts_disable(const struct net_device *dev)
@@ -1891,7 +1907,8 @@ static int flexcan_open(struct net_device *dev)
can_rx_offload_enable(&priv->offload);
- if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3)
+ if (priv->devtype_data.quirks &
+ (FLEXCAN_QUIRK_NR_IRQ_3 | FLEXCAN_QUIRK_IRQ_BERR))
err = request_irq(dev->irq, flexcan_irq_mb,
IRQF_SHARED, dev->name, dev);
else
@@ -1912,6 +1929,13 @@ static int flexcan_open(struct net_device *dev)
goto out_free_irq_boff;
}
+ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_IRQ_BERR) {
+ err = request_irq(priv->irq_err,
+ flexcan_irq_esr, IRQF_SHARED, dev->name, dev);
+ if (err)
+ goto out_free_irq_boff;
+ }
+
if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SECONDARY_MB_IRQ) {
err = request_irq(priv->irq_secondary_mb,
flexcan_irq_mb, IRQF_SHARED, dev->name, dev);
@@ -1926,7 +1950,8 @@ static int flexcan_open(struct net_device *dev)
return 0;
out_free_irq_err:
- if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3)
+ if (priv->devtype_data.quirks &
+ (FLEXCAN_QUIRK_IRQ_BERR | FLEXCAN_QUIRK_NR_IRQ_3))
free_irq(priv->irq_err, dev);
out_free_irq_boff:
if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3)
@@ -1958,10 +1983,12 @@ static int flexcan_close(struct net_device *dev)
if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SECONDARY_MB_IRQ)
free_irq(priv->irq_secondary_mb, dev);
- if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3) {
+ if (priv->devtype_data.quirks &
+ (FLEXCAN_QUIRK_IRQ_BERR | FLEXCAN_QUIRK_NR_IRQ_3))
free_irq(priv->irq_err, dev);
+
+ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3)
free_irq(priv->irq_boff, dev);
- }
free_irq(dev->irq, dev);
can_rx_offload_disable(&priv->offload);
@@ -2348,12 +2375,21 @@ static int flexcan_probe(struct platform_device *pdev)
if (transceiver)
priv->can.bitrate_max = transceiver->attrs.max_link_rate;
+ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_IRQ_BERR) {
+ priv->irq_err = platform_get_irq_byname(pdev, "berr");
+ if (priv->irq_err < 0) {
+ err = priv->irq_err;
+ goto failed_platform_get_irq;
+ }
+ }
+
if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3) {
priv->irq_boff = platform_get_irq(pdev, 1);
if (priv->irq_boff < 0) {
err = priv->irq_boff;
goto failed_platform_get_irq;
}
+
priv->irq_err = platform_get_irq(pdev, 2);
if (priv->irq_err < 0) {
err = priv->irq_err;
diff --git a/drivers/net/can/flexcan/flexcan.h b/drivers/net/can/flexcan/flexcan.h
index 22aa097ec3c0..43d4e0da3779 100644
--- a/drivers/net/can/flexcan/flexcan.h
+++ b/drivers/net/can/flexcan/flexcan.h
@@ -74,6 +74,8 @@
* both need to have an interrupt handler registered.
*/
#define FLEXCAN_QUIRK_SECONDARY_MB_IRQ BIT(18)
+/* Setup dedicated bus error and state change IRQ */
+#define FLEXCAN_QUIRK_IRQ_BERR BIT(19)
#define FLEXCAN_NR_MB_IRQS 2
--
2.43.0
^ permalink raw reply related
* [PATCH v4 6/8] can: flexcan: add NXP S32N79 SoC support
From: Ciprian Costea @ 2026-03-26 13:58 UTC (permalink / raw)
To: Marc Kleine-Budde, Vincent Mailhol, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
Fabio Estevam
Cc: Pengutronix Kernel Team, linux-can, devicetree, linux-kernel, imx,
linux-arm-kernel, NXP S32 Linux Team, Christophe Lizzi,
Alberto Ruiz, Enric Balletbo, Eric Chanudet,
Ciprian Marian Costea, Andra-Teodora Ilie, Larisa Grigore
In-Reply-To: <20260326135825.3428856-1-ciprianmarian.costea@oss.nxp.com>
From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
Add device data and compatible string for NXP S32N79 SoC.
FlexCAN IP integration on S32N79 SoC uses two interrupts:
- one for mailboxes 0-127
- one for signaling bus errors and device state changes
Co-developed-by: Andra-Teodora Ilie <andra.ilie@nxp.com>
Signed-off-by: Andra-Teodora Ilie <andra.ilie@nxp.com>
Co-developed-by: Larisa Grigore <larisa.grigore@nxp.com>
Signed-off-by: Larisa Grigore <larisa.grigore@nxp.com>
Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
---
drivers/net/can/flexcan/flexcan-core.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
index 23ddf7910641..9ae0d9eb4ccc 100644
--- a/drivers/net/can/flexcan/flexcan-core.c
+++ b/drivers/net/can/flexcan/flexcan-core.c
@@ -397,6 +397,15 @@ static const struct flexcan_devtype_data nxp_s32g2_devtype_data = {
FLEXCAN_QUIRK_SECONDARY_MB_IRQ,
};
+static const struct flexcan_devtype_data nxp_s32n_devtype_data = {
+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
+ FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_RX_MAILBOX |
+ FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SUPPORT_FD |
+ FLEXCAN_QUIRK_SUPPORT_ECC | FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX |
+ FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR |
+ FLEXCAN_QUIRK_IRQ_BERR,
+};
+
static const struct can_bittiming_const flexcan_bittiming_const = {
.name = DRV_NAME,
.tseg1_min = 4,
@@ -2232,6 +2241,7 @@ static const struct of_device_id flexcan_of_match[] = {
{ .compatible = "fsl,ls1021ar2-flexcan", .data = &fsl_ls1021a_r2_devtype_data, },
{ .compatible = "fsl,lx2160ar1-flexcan", .data = &fsl_lx2160a_r1_devtype_data, },
{ .compatible = "nxp,s32g2-flexcan", .data = &nxp_s32g2_devtype_data, },
+ { .compatible = "nxp,s32n79-flexcan", .data = &nxp_s32n_devtype_data, },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, flexcan_of_match);
--
2.43.0
^ permalink raw reply related
* [PATCH v4 7/8] arm64: dts: s32n79: add FlexCAN nodes
From: Ciprian Costea @ 2026-03-26 13:58 UTC (permalink / raw)
To: Marc Kleine-Budde, Vincent Mailhol, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
Fabio Estevam
Cc: Pengutronix Kernel Team, linux-can, devicetree, linux-kernel, imx,
linux-arm-kernel, NXP S32 Linux Team, Christophe Lizzi,
Alberto Ruiz, Enric Balletbo, Eric Chanudet,
Ciprian Marian Costea, Andra-Teodora Ilie
In-Reply-To: <20260326135825.3428856-1-ciprianmarian.costea@oss.nxp.com>
From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
The S32N79 integrates multiple FlexCAN instances connected through the RCU
irqsteer interrupt controller.
Co-developed-by: Andra-Teodora Ilie <andra.ilie@nxp.com>
Signed-off-by: Andra-Teodora Ilie <andra.ilie@nxp.com>
Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
---
arch/arm64/boot/dts/freescale/s32n79.dtsi | 50 +++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/s32n79.dtsi b/arch/arm64/boot/dts/freescale/s32n79.dtsi
index 94ab58783fdc..c1a4fdead91d 100644
--- a/arch/arm64/boot/dts/freescale/s32n79.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32n79.dtsi
@@ -352,6 +352,56 @@ pmu: pmu {
interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
};
+ rcu-bus {
+ compatible = "simple-bus";
+ ranges = <0x54000000 0x0 0x54000000 0x4000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ irqsteer_rcu: interrupt-controller@55101000 {
+ compatible = "nxp,s32n79-irqsteer";
+ reg = <0x55101000 0x1000>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks 0xf9>;
+ clock-names = "ipg";
+ fsl,channel = <0>;
+ fsl,num-irqs = <512>;
+ status = "disabled";
+ };
+
+ can0: can@55b60000 {
+ compatible = "nxp,s32n79-flexcan";
+ reg = <0x55b60000 0x4000>;
+ interrupt-parent = <&irqsteer_rcu>;
+ interrupts = <0>, <64>;
+ interrupt-names = "mb-0", "berr";
+ clocks = <&clks 0xf9>, <&clks 0xfc>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ can1: can@55b70000 {
+ compatible = "nxp,s32n79-flexcan";
+ reg = <0x55b70000 0x4000>;
+ interrupt-parent = <&irqsteer_rcu>;
+ interrupts = <1>, <65>;
+ interrupt-names = "mb-0", "berr";
+ clocks = <&clks 0xf9>, <&clks 0xfc>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+ };
+
timer: timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
--
2.43.0
^ permalink raw reply related
* [PATCH v4 8/8] arm64: dts: s32n79: enable FlexCAN devices
From: Ciprian Costea @ 2026-03-26 13:58 UTC (permalink / raw)
To: Marc Kleine-Budde, Vincent Mailhol, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
Fabio Estevam
Cc: Pengutronix Kernel Team, linux-can, devicetree, linux-kernel, imx,
linux-arm-kernel, NXP S32 Linux Team, Christophe Lizzi,
Alberto Ruiz, Enric Balletbo, Eric Chanudet,
Ciprian Marian Costea
In-Reply-To: <20260326135825.3428856-1-ciprianmarian.costea@oss.nxp.com>
From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
Enable FlexCAN controller instances (can0 and can1) and the required RCU
irqsteer interrupt controller on S32N79-RDB board.
Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
---
arch/arm64/boot/dts/freescale/s32n79-rdb.dts | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/s32n79-rdb.dts b/arch/arm64/boot/dts/freescale/s32n79-rdb.dts
index 1feccd61258e..65a595d7535f 100644
--- a/arch/arm64/boot/dts/freescale/s32n79-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/s32n79-rdb.dts
@@ -43,10 +43,22 @@ memory@80000000 {
};
};
+&can0 {
+ status = "okay";
+};
+
+&can1 {
+ status = "okay";
+};
+
&irqsteer_coss {
status = "okay";
};
+&irqsteer_rcu {
+ status = "okay";
+};
+
&uart0 {
status = "okay";
};
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v5 8/9] dt-bindings: net: wireless: brcm: Add compatible for bcm43752
From: Ronald Claveau @ 2026-03-26 14:03 UTC (permalink / raw)
To: Neil Armstrong
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
linux-mmc, linux-wireless, Conor Dooley, Kevin Hilman,
Jerome Brunet, Martin Blumenstingl, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Ulf Hansson, Johannes Berg,
van Spriel
In-Reply-To: <9bc23f1e-1cf3-43d1-935a-c4738d576c29@linaro.org>
On 3/26/26 1:55 PM, Neil Armstrong wrote:
> On 3/26/26 10:59, Ronald Claveau wrote:
>> Add bcm43752 compatible with its bcm4329 compatible fallback.
>>
>> Acked-by: Conor Dooley <conor.dooley@microchip.com>
>> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
>> ---
>> Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-
>> fmac.yaml | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/Documentation/devicetree/bindings/net/wireless/
>> brcm,bcm4329-fmac.yaml b/Documentation/devicetree/bindings/net/
>> wireless/brcm,bcm4329-fmac.yaml
>> index 3be7576787644..81fd3e37452a6 100644
>> --- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-
>> fmac.yaml
>> +++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-
>> fmac.yaml
>> @@ -42,6 +42,7 @@ properties:
>> - brcm,bcm4356-fmac
>> - brcm,bcm4359-fmac
>> - brcm,bcm4366-fmac
>> + - brcm,bcm43752-fmac
>> - cypress,cyw4373-fmac
>> - cypress,cyw43012-fmac
>> - infineon,cyw43439-fmac
>>
>
> I'll apply all the other DT patches, please send this one alone with the
> [PATCH net-next] prefix so it gets picked by the wireless/net people.
>
> Thanks,
> Neil
I'm on it, thank you.
--
Best regards,
Ronald
^ permalink raw reply
* [PATCH v3 0/3] KVM: arm64: Fix SPE and TRBE nVHE world switch
From: Will Deacon @ 2026-03-26 14:12 UTC (permalink / raw)
To: kvmarm
Cc: mark.rutland, linux-arm-kernel, Will Deacon, Marc Zyngier,
Oliver Upton, James Clark, Leo Yan, Suzuki K Poulose, Fuad Tabba,
Alexandru Elisei, Yabin Cui
Hi all,
Here is version three of the SPE/TRBE fixes I previously posted here:
v1: https://lore.kernel.org/r/20260216130959.19317-1-will@kernel.org
v2: https://lore.kernel.org/r/20260227212136.7660-1-will@kernel.org
Changes since v2 include:
* Simplified the TRBE drain check logic
* Added R-b / T-b tags
* Rebased onto -rc4
Cheers,
Will
Cc: Marc Zyngier <maz@kernel.org>
Cc: Oliver Upton <oupton@kernel.org>
Cc: James Clark <james.clark@linaro.org>
Cc: Leo Yan <leo.yan@arm.com>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Fuad Tabba <tabba@google.com>
Cc: Alexandru Elisei <alexandru.elisei@arm.com>
Cc: Yabin Cui <yabinc@google.com>
--->8
Will Deacon (3):
KVM: arm64: Disable TRBE Trace Buffer Unit when running in guest
context
KVM: arm64: Disable SPE Profiling Buffer when running in guest context
KVM: arm64: Don't pass host_debug_state to BRBE world-switch routines
arch/arm64/include/asm/kvm_host.h | 2 +
arch/arm64/kvm/hyp/nvhe/debug-sr.c | 116 ++++++++++++++++++++++-------
arch/arm64/kvm/hyp/nvhe/switch.c | 2 +-
3 files changed, 94 insertions(+), 26 deletions(-)
--
2.53.0.1018.g2bb0e51243-goog
^ permalink raw reply
* [PATCH v3 1/3] KVM: arm64: Disable TRBE Trace Buffer Unit when running in guest context
From: Will Deacon @ 2026-03-26 14:12 UTC (permalink / raw)
To: kvmarm
Cc: mark.rutland, linux-arm-kernel, Will Deacon, Marc Zyngier,
Oliver Upton, James Clark, Leo Yan, Suzuki K Poulose, Fuad Tabba,
Alexandru Elisei, Yabin Cui
In-Reply-To: <20260326141214.18990-1-will@kernel.org>
The nVHE world-switch code relies on zeroing TRFCR_EL1 to disable trace
generation in guest context when self-hosted TRBE is in use by the host.
Per D3.2.1 ("Controls to prohibit trace at Exception levels"), clearing
TRFCR_EL1 means that trace generation is prohibited at EL1 and EL0 but
per R_YCHKJ the Trace Buffer Unit will still be enabled if
TRBLIMITR_EL1.E is set. R_SJFRQ goes on to state that, when enabled, the
Trace Buffer Unit can perform address translation for the "owning
exception level" even when it is out of context.
Consequently, we can end up in a state where TRBE performs speculative
page-table walks for a host VA/IPA in guest/hypervisor context depending
on the value of MDCR_EL2.E2TB, which changes over world-switch. The
potential result appears to be a heady mixture of SErrors, data
corruption and hardware lockups.
Extend the TRBE world-switch code to clear TRBLIMITR_EL1.E after
draining the buffer, restoring the register on return to the host. This
unfortunately means we need to tackle CPU errata #2064142 and #2038923
which add additional synchronisation requirements around manipulations
of the limit register. Hopefully this doesn't need to be fast.
Cc: Marc Zyngier <maz@kernel.org>
Cc: Oliver Upton <oupton@kernel.org>
Cc: James Clark <james.clark@linaro.org>
Cc: Leo Yan <leo.yan@arm.com>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Fuad Tabba <tabba@google.com>
Cc: Alexandru Elisei <alexandru.elisei@arm.com>
Tested-by: Leo Yan <leo.yan@arm.com>
Tested-by: Fuad Tabba <tabba@google.com>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Reviewed-by: Fuad Tabba <tabba@google.com>
Fixes: a1319260bf62 ("arm64: KVM: Enable access to TRBE support for host")
Signed-off-by: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kvm/hyp/nvhe/debug-sr.c | 71 ++++++++++++++++++++++++++----
arch/arm64/kvm/hyp/nvhe/switch.c | 2 +-
3 files changed, 64 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 70cb9cfd760a..b1335c55dbef 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -770,6 +770,7 @@ struct kvm_host_data {
u64 pmscr_el1;
/* Self-hosted trace */
u64 trfcr_el1;
+ u64 trblimitr_el1;
/* Values of trap registers for the host before guest entry. */
u64 mdcr_el2;
u64 brbcr_el1;
diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
index 2a1c0f49792b..0955af771ad1 100644
--- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -57,12 +57,54 @@ static void __trace_do_switch(u64 *saved_trfcr, u64 new_trfcr)
write_sysreg_el1(new_trfcr, SYS_TRFCR);
}
-static bool __trace_needs_drain(void)
+static void __trace_drain_and_disable(void)
{
- if (is_protected_kvm_enabled() && host_data_test_flag(HAS_TRBE))
- return read_sysreg_s(SYS_TRBLIMITR_EL1) & TRBLIMITR_EL1_E;
+ u64 *trblimitr_el1 = host_data_ptr(host_debug_state.trblimitr_el1);
+ bool needs_drain = is_protected_kvm_enabled() ?
+ host_data_test_flag(HAS_TRBE) :
+ host_data_test_flag(TRBE_ENABLED);
- return host_data_test_flag(TRBE_ENABLED);
+ if (!needs_drain) {
+ *trblimitr_el1 = 0;
+ return;
+ }
+
+ *trblimitr_el1 = read_sysreg_s(SYS_TRBLIMITR_EL1);
+ if (*trblimitr_el1 & TRBLIMITR_EL1_E) {
+ /*
+ * The host has enabled the Trace Buffer Unit so we have
+ * to beat the CPU with a stick until it stops accessing
+ * memory.
+ */
+
+ /* First, ensure that our prior write to TRFCR has stuck. */
+ isb();
+
+ /* Now synchronise with the trace and drain the buffer. */
+ tsb_csync();
+ dsb(nsh);
+
+ /*
+ * With no more trace being generated, we can disable the
+ * Trace Buffer Unit.
+ */
+ write_sysreg_s(0, SYS_TRBLIMITR_EL1);
+ if (cpus_have_final_cap(ARM64_WORKAROUND_2064142)) {
+ /*
+ * Some CPUs are so good, we have to drain 'em
+ * twice.
+ */
+ tsb_csync();
+ dsb(nsh);
+ }
+
+ /*
+ * Ensure that the Trace Buffer Unit is disabled before
+ * we start mucking with the stage-2 and trap
+ * configuration.
+ */
+ isb();
+ }
}
static bool __trace_needs_switch(void)
@@ -79,15 +121,26 @@ static void __trace_switch_to_guest(void)
__trace_do_switch(host_data_ptr(host_debug_state.trfcr_el1),
*host_data_ptr(trfcr_while_in_guest));
-
- if (__trace_needs_drain()) {
- isb();
- tsb_csync();
- }
+ __trace_drain_and_disable();
}
static void __trace_switch_to_host(void)
{
+ u64 trblimitr_el1 = *host_data_ptr(host_debug_state.trblimitr_el1);
+
+ if (trblimitr_el1 & TRBLIMITR_EL1_E) {
+ /* Re-enable the Trace Buffer Unit for the host. */
+ write_sysreg_s(trblimitr_el1, SYS_TRBLIMITR_EL1);
+ isb();
+ if (cpus_have_final_cap(ARM64_WORKAROUND_2038923)) {
+ /*
+ * Make sure the unit is re-enabled before we
+ * poke TRFCR.
+ */
+ isb();
+ }
+ }
+
__trace_do_switch(host_data_ptr(trfcr_while_in_guest),
*host_data_ptr(host_debug_state.trfcr_el1));
}
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 779089e42681..f00688e69d88 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -278,7 +278,7 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
* We're about to restore some new MMU state. Make sure
* ongoing page-table walks that have started before we
* trapped to EL2 have completed. This also synchronises the
- * above disabling of BRBE, SPE and TRBE.
+ * above disabling of BRBE and SPE.
*
* See DDI0487I.a D8.1.5 "Out-of-context translation regimes",
* rule R_LFHQG and subsequent information statements.
--
2.53.0.1018.g2bb0e51243-goog
^ permalink raw reply related
* [PATCH v3 2/3] KVM: arm64: Disable SPE Profiling Buffer when running in guest context
From: Will Deacon @ 2026-03-26 14:12 UTC (permalink / raw)
To: kvmarm
Cc: mark.rutland, linux-arm-kernel, Will Deacon, Marc Zyngier,
Oliver Upton, James Clark, Leo Yan, Suzuki K Poulose, Fuad Tabba,
Alexandru Elisei, Yabin Cui
In-Reply-To: <20260326141214.18990-1-will@kernel.org>
The nVHE world-switch code relies on zeroing PMSCR_EL1 to disable
profiling data generation in guest context when SPE is in use by the
host.
Unfortunately, this may leave PMBLIMITR_EL1.E set and consequently we
can end up running in guest/hypervisor context with the Profiling Buffer
enabled. The current "known issues" document for Rev M.a of the Arm ARM
states that this can lead to speculative, out-of-context translations:
| 2.18 D23136:
|
| When the Profiling Buffer is enabled, profiling is not stopped, and
| Discard mode is not enabled, the Statistical Profiling Unit might
| cause speculative translations for the owning translation regime,
| including when the owning translation regime is out-of-context.
In a similar fashion to TRBE, ensure that the Profiling Buffer is
disabled during the nVHE world switch before we start messing with the
stage-2 MMU and trap configuration.
Cc: Marc Zyngier <maz@kernel.org>
Cc: Oliver Upton <oupton@kernel.org>
Cc: James Clark <james.clark@linaro.org>
Cc: Leo Yan <leo.yan@arm.com>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Fuad Tabba <tabba@google.com>
Cc: Alexandru Elisei <alexandru.elisei@arm.com>
Reviewed-by: Alexandru Elisei <alexandru.elisei@arm.com>
Reviewed-by: Fuad Tabba <tabba@google.com>
Tested-by: Alexandru Elisei <alexandru.elisei@arm.com>
Tested-by: Fuad Tabba <tabba@google.com>
Fixes: f85279b4bd48 ("arm64: KVM: Save/restore the host SPE state when entering/leaving a VM")
Signed-off-by: Will Deacon <will@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kvm/hyp/nvhe/debug-sr.c | 33 ++++++++++++++++++++----------
arch/arm64/kvm/hyp/nvhe/switch.c | 2 +-
3 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index b1335c55dbef..fe588760fe62 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -768,6 +768,7 @@ struct kvm_host_data {
struct kvm_guest_debug_arch regs;
/* Statistical profiling extension */
u64 pmscr_el1;
+ u64 pmblimitr_el1;
/* Self-hosted trace */
u64 trfcr_el1;
u64 trblimitr_el1;
diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
index 0955af771ad1..84bc80f4e36b 100644
--- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -14,20 +14,20 @@
#include <asm/kvm_hyp.h>
#include <asm/kvm_mmu.h>
-static void __debug_save_spe(u64 *pmscr_el1)
+static void __debug_save_spe(void)
{
- u64 reg;
+ u64 *pmscr_el1, *pmblimitr_el1;
- /* Clear pmscr in case of early return */
- *pmscr_el1 = 0;
+ pmscr_el1 = host_data_ptr(host_debug_state.pmscr_el1);
+ pmblimitr_el1 = host_data_ptr(host_debug_state.pmblimitr_el1);
/*
* At this point, we know that this CPU implements
* SPE and is available to the host.
* Check if the host is actually using it ?
*/
- reg = read_sysreg_s(SYS_PMBLIMITR_EL1);
- if (!(reg & BIT(PMBLIMITR_EL1_E_SHIFT)))
+ *pmblimitr_el1 = read_sysreg_s(SYS_PMBLIMITR_EL1);
+ if (!(*pmblimitr_el1 & BIT(PMBLIMITR_EL1_E_SHIFT)))
return;
/* Yes; save the control register and disable data generation */
@@ -37,18 +37,29 @@ static void __debug_save_spe(u64 *pmscr_el1)
/* Now drain all buffered data to memory */
psb_csync();
+ dsb(nsh);
+
+ /* And disable the profiling buffer */
+ write_sysreg_s(0, SYS_PMBLIMITR_EL1);
+ isb();
}
-static void __debug_restore_spe(u64 pmscr_el1)
+static void __debug_restore_spe(void)
{
- if (!pmscr_el1)
+ u64 pmblimitr_el1 = *host_data_ptr(host_debug_state.pmblimitr_el1);
+
+ if (!(pmblimitr_el1 & BIT(PMBLIMITR_EL1_E_SHIFT)))
return;
/* The host page table is installed, but not yet synchronised */
isb();
+ /* Re-enable the profiling buffer. */
+ write_sysreg_s(pmblimitr_el1, SYS_PMBLIMITR_EL1);
+ isb();
+
/* Re-enable data generation */
- write_sysreg_el1(pmscr_el1, SYS_PMSCR);
+ write_sysreg_el1(*host_data_ptr(host_debug_state.pmscr_el1), SYS_PMSCR);
}
static void __trace_do_switch(u64 *saved_trfcr, u64 new_trfcr)
@@ -175,7 +186,7 @@ void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu)
{
/* Disable and flush SPE data generation */
if (host_data_test_flag(HAS_SPE))
- __debug_save_spe(host_data_ptr(host_debug_state.pmscr_el1));
+ __debug_save_spe();
/* Disable BRBE branch records */
if (host_data_test_flag(HAS_BRBE))
@@ -193,7 +204,7 @@ void __debug_switch_to_guest(struct kvm_vcpu *vcpu)
void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu)
{
if (host_data_test_flag(HAS_SPE))
- __debug_restore_spe(*host_data_ptr(host_debug_state.pmscr_el1));
+ __debug_restore_spe();
if (host_data_test_flag(HAS_BRBE))
__debug_restore_brbe(*host_data_ptr(host_debug_state.brbcr_el1));
if (__trace_needs_switch())
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index f00688e69d88..9b6e87dac3b9 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -278,7 +278,7 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
* We're about to restore some new MMU state. Make sure
* ongoing page-table walks that have started before we
* trapped to EL2 have completed. This also synchronises the
- * above disabling of BRBE and SPE.
+ * above disabling of BRBE.
*
* See DDI0487I.a D8.1.5 "Out-of-context translation regimes",
* rule R_LFHQG and subsequent information statements.
--
2.53.0.1018.g2bb0e51243-goog
^ permalink raw reply related
* [PATCH v3 3/3] KVM: arm64: Don't pass host_debug_state to BRBE world-switch routines
From: Will Deacon @ 2026-03-26 14:12 UTC (permalink / raw)
To: kvmarm
Cc: mark.rutland, linux-arm-kernel, Will Deacon, Marc Zyngier,
Oliver Upton, James Clark, Leo Yan, Suzuki K Poulose, Fuad Tabba,
Alexandru Elisei, Yabin Cui
In-Reply-To: <20260326141214.18990-1-will@kernel.org>
Now that the SPE and BRBE nVHE world-switch routines operate on the
host_debug_state directly, tweak the BRBE code to do the same for
consistency.
This is purely cosmetic.
Cc: Marc Zyngier <maz@kernel.org>
Cc: Oliver Upton <oupton@kernel.org>
Cc: James Clark <james.clark@linaro.org>
Cc: Leo Yan <leo.yan@arm.com>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Fuad Tabba <tabba@google.com>
Cc: Alexandru Elisei <alexandru.elisei@arm.com>
Tested-by: Fuad Tabba <tabba@google.com>
Reviewed-by: Fuad Tabba <tabba@google.com>
Signed-off-by: Will Deacon <will@kernel.org>
---
arch/arm64/kvm/hyp/nvhe/debug-sr.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
index 84bc80f4e36b..50413171bd1a 100644
--- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -156,9 +156,9 @@ static void __trace_switch_to_host(void)
*host_data_ptr(host_debug_state.trfcr_el1));
}
-static void __debug_save_brbe(u64 *brbcr_el1)
+static void __debug_save_brbe(void)
{
- *brbcr_el1 = 0;
+ u64 *brbcr_el1 = host_data_ptr(host_debug_state.brbcr_el1);
/* Check if the BRBE is enabled */
if (!(read_sysreg_el1(SYS_BRBCR) & (BRBCR_ELx_E0BRE | BRBCR_ELx_ExBRE)))
@@ -173,8 +173,10 @@ static void __debug_save_brbe(u64 *brbcr_el1)
write_sysreg_el1(0, SYS_BRBCR);
}
-static void __debug_restore_brbe(u64 brbcr_el1)
+static void __debug_restore_brbe(void)
{
+ u64 brbcr_el1 = *host_data_ptr(host_debug_state.brbcr_el1);
+
if (!brbcr_el1)
return;
@@ -190,7 +192,7 @@ void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu)
/* Disable BRBE branch records */
if (host_data_test_flag(HAS_BRBE))
- __debug_save_brbe(host_data_ptr(host_debug_state.brbcr_el1));
+ __debug_save_brbe();
if (__trace_needs_switch())
__trace_switch_to_guest();
@@ -206,7 +208,7 @@ void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu)
if (host_data_test_flag(HAS_SPE))
__debug_restore_spe();
if (host_data_test_flag(HAS_BRBE))
- __debug_restore_brbe(*host_data_ptr(host_debug_state.brbcr_el1));
+ __debug_restore_brbe();
if (__trace_needs_switch())
__trace_switch_to_host();
}
--
2.53.0.1018.g2bb0e51243-goog
^ permalink raw reply related
* Re: [PATCH v6 00/10] arm64: dts: lx2160a: fix pinmux issues, update SolidRun boards
From: Frank Li @ 2026-03-26 14:20 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Carlos Song, Josua Mayer
Cc: Frank Li, Mikhail Anikin, Yazan Shhady, Rabeeh Khoury, Frank Li,
linux-arm-kernel, devicetree, linux-kernel, stable
In-Reply-To: <20260324-lx2160-sd-cd-v6-0-8bf207711848@solid-run.com>
On Tue, 24 Mar 2026 13:40:54 +0100, Josua Mayer wrote:
> Fix a bug with microsd card-detect & gpios pinmux on SolidRun
> LX2160A Clearfog-CX & Honeycomb, and LX2162A Clearfog.
>
> Then make small additions to SolidRun board descriptions.
>
>
Applied, thanks!
[01/10] arm64: dts: lx2160a-cex7/lx2162a-sr-som: fix usd-cd & gpio pinmux
commit: 6bdd023311d9cc754126418875b5265dc5705230
[02/10] arm64: dts: lx2160a: change i2c0 (iic1) pinmux mask to one bit
commit: 0973d9d880d26c85a9466f7b51163309c0d3177b
Remove words "This change" and rephrash last sentence to
Align with documentation by avoiding writes to reserved bits. No functional
change, as writing the extra two reserved bits is not known to cause
issues.
[03/10] arm64: dts: lx2160a: remove duplicate pinmux nodes
commit: 385c7dca29e416800f57fbaf96788257d455046e
[04/10] arm64: dts: lx2160a: rename pinmux nodes for readability
commit: bb9407c855bbf62c404a3bc5119033198c5ae8a4
[05/10] arm64: dts: lx2160a: add sda gpio references for i2c bus recovery
commit: fbf66a01af34364cb6b49fcf1d77deaf09afb9ab
[06/10] arm64: dts: lx2160a: change zeros to hexadecimal in pinmux nodes
commit: ac26aca831c037a57286a63a6d924c5b956b7b42
[07/10] arm64: dts: lx2160a: complete pinmux for rcwsr12 configuration word
commit: 92479a6b97a54a829a28ec57221f5b74e7ee53b2
[08/10] arm64: dts: lx2160a-cex7: add rtc alias
commit: 7593c15e9512022f8bb57bb24995955d8dcd137e
[09/10] arm64: dts: lx2162a-sr-som: add crypto & rtc aliases, model
commit: 112d3b46d3e00db17f0a309e479fe4678906b6f9
[10/10] arm64: dts: lx2162a-clearfog: set sfp connector leds function and source
commit: 7a387b0b0bc2f2c703d8d64250a056f43eb2c800
Best regards,
--
Frank Li <Frank.Li@nxp.com>
^ permalink raw reply
* Re: [PATCH v5] nvme: Skip trace complete_rq on host path error
From: hch @ 2026-03-26 14:20 UTC (permalink / raw)
To: 전민식
Cc: hch@lst.de, Keith Busch, Justin Tee, axboe@kernel.dk,
sven@kernel.org, j@jannau.net, neal@gompa.dev, sagi@grimberg.me,
justin.tee@broadcom.com, nareshgottumukkala83@gmail.com,
paul.ely@broadcom.com, James Smart, kch@nvidia.com,
linux-arm-kernel@lists.infradead.org,
linux-nvme@lists.infradead.org, asahi@lists.linux.dev,
linux-kernel@vger.kernel.org, 이은수,
칸찬
In-Reply-To: <20260326065152epcms2p51a18d3bbecb6eb6dc2ddba09651e5152@epcms2p5>
On Thu, Mar 26, 2026 at 03:51:52PM +0900, 전민식 wrote:
> Hi hch,
>
> I added a comment about why I do trace skip if it's host path error.
The patch looks good:
Reviewed-by: Christoph Hellwig <hch@lst.de>
But such note go below the '--' so that don't end up in git history.
^ permalink raw reply
* Re: [PATCH v9 02/11] drm/fourcc: Add DRM_FORMAT_XV20
From: Simon Ser @ 2026-03-26 14:26 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Michal Simek, dri-devel, linux-kernel, linux-arm-kernel,
Geert Uytterhoeven, Dmitry Baryshkov, Pekka Paalanen,
Dmitry Baryshkov
In-Reply-To: <20260325-xilinx-formats-v9-2-d03b7e3752e4@ideasonboard.com>
On Wednesday, March 25th, 2026 at 15:02, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> wrote:
> XV20 is 2 plane 10 bit per component YCbCr 2x1 subsampled format. XV20
> is similar to the already existing P030 format, which is 2x2 subsampled.
I don't know for sure the multi-planar YCbCr format name scheme we're
using, but here are my observations looking at P, Q and S formats:
- The first digit indicates sub-sampling. 0 for 2x2, 2 for 2x1, 4 for none.
- The two other digits indicate bits for the Y channel, one of 10, 12, 16.
One exception: Q401 indicates reverse order for Cb and Cr planes when compared
to Q410.
P030 is a bit of an outlier here since it's the only one with multiple
Y samples. NV formats are also multi-planar but seem to use a completely
separate scheme.
Given the above I'd say what would make most sense to me is to use P230:
keep the last two digits and change the first one to indicate that the
only difference is the sub-sampling. Does that make sense to you?
Simon
^ permalink raw reply
* Re: [PATCH 1/3] KVM: arm64: selftests: Add library functions for NV
From: Wei-Lin Chang @ 2026-03-26 14:28 UTC (permalink / raw)
To: Marc Zyngier
Cc: kvm, linux-kselftest, linux-arm-kernel, kvmarm, linux-kernel,
Paolo Bonzini, Shuah Khan, Oliver Upton, Joey Gouly,
Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon
In-Reply-To: <86o6kc46x8.wl-maz@kernel.org>
On Wed, Mar 25, 2026 at 09:03:47AM +0000, Marc Zyngier wrote:
> On Wed, 25 Mar 2026 00:36:18 +0000,
> Wei-Lin Chang <weilin.chang@arm.com> wrote:
> >
> > The API is designed for userspace to first call prepare_{l2_stack,
> > hyp_state, eret_destination, nested_sync_handler}, with a function
> > supplied to prepare_eret_destination() to be run in L2. Then run_l2()
> > can be called in L1 to run the given function in L2.
> >
> > Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
> > ---
> > tools/testing/selftests/kvm/Makefile.kvm | 2 +
> > .../selftests/kvm/include/arm64/nested.h | 18 ++++++
> > .../testing/selftests/kvm/lib/arm64/nested.c | 61 +++++++++++++++++++
> > .../selftests/kvm/lib/arm64/nested_asm.S | 35 +++++++++++
> > 4 files changed, 116 insertions(+)
> > create mode 100644 tools/testing/selftests/kvm/include/arm64/nested.h
> > create mode 100644 tools/testing/selftests/kvm/lib/arm64/nested.c
> > create mode 100644 tools/testing/selftests/kvm/lib/arm64/nested_asm.S
> >
> > diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
> > index 98da9fa4b8b7..5e681e8e0cd7 100644
> > --- a/tools/testing/selftests/kvm/Makefile.kvm
> > +++ b/tools/testing/selftests/kvm/Makefile.kvm
> > @@ -34,6 +34,8 @@ LIBKVM_arm64 += lib/arm64/gic.c
> > LIBKVM_arm64 += lib/arm64/gic_v3.c
> > LIBKVM_arm64 += lib/arm64/gic_v3_its.c
> > LIBKVM_arm64 += lib/arm64/handlers.S
> > +LIBKVM_arm64 += lib/arm64/nested.c
> > +LIBKVM_arm64 += lib/arm64/nested_asm.S
> > LIBKVM_arm64 += lib/arm64/processor.c
> > LIBKVM_arm64 += lib/arm64/spinlock.c
> > LIBKVM_arm64 += lib/arm64/ucall.c
> > diff --git a/tools/testing/selftests/kvm/include/arm64/nested.h b/tools/testing/selftests/kvm/include/arm64/nested.h
> > new file mode 100644
> > index 000000000000..739ff2ee0161
> > --- /dev/null
> > +++ b/tools/testing/selftests/kvm/include/arm64/nested.h
> > @@ -0,0 +1,18 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * ARM64 Nested virtualization defines
> > + */
> > +
> > +#ifndef SELFTEST_KVM_NESTED_H
> > +#define SELFTEST_KVM_NESTED_H
> > +
> > +void prepare_l2_stack(struct kvm_vm *vm, struct kvm_vcpu *vcpu);
> > +void prepare_hyp_state(struct kvm_vm *vm, struct kvm_vcpu *vcpu);
> > +void prepare_eret_destination(struct kvm_vm *vm, struct kvm_vcpu *vcpu, void *l2_pc);
> > +void prepare_nested_sync_handler(struct kvm_vm *vm, struct kvm_vcpu *vcpu);
> > +
> > +void run_l2(void);
> > +void after_hvc(void);
> > +void do_hvc(void);
> > +
> > +#endif /* SELFTEST_KVM_NESTED_H */
> > diff --git a/tools/testing/selftests/kvm/lib/arm64/nested.c b/tools/testing/selftests/kvm/lib/arm64/nested.c
> > new file mode 100644
> > index 000000000000..111d02f44cfe
> > --- /dev/null
> > +++ b/tools/testing/selftests/kvm/lib/arm64/nested.c
> > @@ -0,0 +1,61 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * ARM64 Nested virtualization helpers
> > + */
> > +
> > +#include "kvm_util.h"
> > +#include "nested.h"
> > +#include "processor.h"
> > +#include "test_util.h"
> > +
> > +#include <asm/sysreg.h>
> > +
> > +static void hvc_handler(struct ex_regs *regs)
> > +{
> > + GUEST_ASSERT_EQ(get_current_el(), 2);
> > + GUEST_PRINTF("hvc handler\n");
> > + regs->pstate = PSR_MODE_EL2h | PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT;
> > + regs->pc = (u64)after_hvc;
> > +}
> > +
> > +void prepare_l2_stack(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
> > +{
> > + size_t l2_stack_size;
> > + uint64_t l2_stack_paddr;
> > +
> > + l2_stack_size = vm->page_size == 4096 ? DEFAULT_STACK_PGS * vm->page_size :
> > + vm->page_size;
>
> Please use symbolic constants. Also, this looks wrong if the default
> stack size is 32k and the page size is 16k. You probably want to
> express a stack size directly, rather than a number of pages.
Makes sense, will fix the size of the stack.
>
> > + l2_stack_paddr = __vm_phy_pages_alloc(vm, l2_stack_size / vm->page_size,
> > + 0, 0, false);
> > + vcpu_set_reg(vcpu, ARM64_CORE_REG(sp_el1), l2_stack_paddr + l2_stack_size);
> > +}
> > +
> > +void prepare_hyp_state(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
> > +{
> > + vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_HCR_EL2), HCR_EL2_RW);
>
> Surely the E2H value matters. Or are you planning to only run this on
> configuration that hardcode E2H==0? That'd be pretty limiting.
Yes it does matter, I was tunnel-visioned in trying to make L1 <-> L2
transition work with the bare minimum, and missed what we will want in
the future.
>
> > +}
> > +
> > +void prepare_eret_destination(struct kvm_vm *vm, struct kvm_vcpu *vcpu, void *l2_pc)
> > +{
> > + vm_paddr_t do_hvc_paddr = addr_gva2gpa(vm, (vm_vaddr_t)do_hvc);
> > + vm_paddr_t l2_pc_paddr = addr_gva2gpa(vm, (vm_vaddr_t)l2_pc);
> > +
> > + vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_SPSR_EL2), PSR_MODE_EL1h |
> > + PSR_D_BIT |
> > + PSR_A_BIT |
> > + PSR_I_BIT |
> > + PSR_F_BIT);
> > + vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ELR_EL2), l2_pc_paddr);
> > + /* HACK: use TPIDR_EL2 to pass address, see run_l2() in nested_asm.S */
> > + vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TPIDR_EL2), do_hvc_paddr);
> > +}
> > +
> > +void prepare_nested_sync_handler(struct kvm_vm *vm, struct kvm_vcpu *vcpu)
> > +{
> > + if (!vm->handlers) {
> > + vm_init_descriptor_tables(vm);
> > + vcpu_init_descriptor_tables(vcpu);
> > + }
> > + vm_install_sync_handler(vm, VECTOR_SYNC_LOWER_64,
> > + ESR_ELx_EC_HVC64, hvc_handler);
> > +}
> > diff --git a/tools/testing/selftests/kvm/lib/arm64/nested_asm.S b/tools/testing/selftests/kvm/lib/arm64/nested_asm.S
> > new file mode 100644
> > index 000000000000..4ecf2d510a6f
> > --- /dev/null
> > +++ b/tools/testing/selftests/kvm/lib/arm64/nested_asm.S
> > @@ -0,0 +1,35 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * ARM64 Nested virtualization assembly helpers
> > + */
> > +
> > +.globl run_l2
> > +.globl after_hvc
> > +.globl do_hvc
> > +run_l2:
> > + /*
> > + * At this point TPIDR_EL2 will contain the gpa of do_hvc from
> > + * prepare_eret_destination(). gpa of do_hvc have to be passed in
> > + * because we want L2 to issue an hvc after it returns from the user
> > + * passed function. In order for that to happen the lr must be
> > + * controlled, which at this point holds the value of the address of
> > + * the next instruction after this run_l2() call, which is not useful
> > + * for L2. Additionally, L1 can't translate gva into gpa, so we can't
> > + * calculate it here.
> > + *
> > + * So first save lr, then move TPIDR_EL2 to lr so when the user supplied
> > + * L2 function returns, L2 jumps to do_hvc and let the L1 hvc handler
> > + * take control. This implies we expect the L2 code to preserve lr and
> > + * calls a regular ret in the end, which is true for normal C functions.
> > + * The hvc handler will jump back to after_hvc when finished, and lr
> > + * will be restored and we can return run_l2().
> > + */
> > + stp x29, lr, [sp, #-16]!
> > + mrs x0, tpidr_el2
> > + mov lr, x0
> > + eret
> > +after_hvc:
> > + ldp x29, lr, [sp], #16
> > + ret
> > +do_hvc:
> > + hvc #0
>
> This probably works for a single instruction L2 guest, but not having
> any save/restore of the L2 context makes it hard to build anything on
> top of this.
Agreed, we need L2 save/restore to meaningfully test NV.
Thanks,
Wei-Lin Chang
>
> Thanks,
>
> M.
>
> --
> Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH v2 1/2] arm64: dts: imx8qm-mek: switch Type-C connector power-role to dual
From: Frank Li @ 2026-03-26 14:28 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, s.hauer, kernel, festevam, Xu Yang
Cc: Frank Li, devicetree, imx, linux-arm-kernel, linux-kernel, jun.li
In-Reply-To: <20260324110459.2838767-1-xu.yang_2@nxp.com>
On Tue, 24 Mar 2026 19:04:58 +0800, Xu Yang wrote:
> When attach to PC Type-A port, the USB device controller does not function
> at all. Because it is configured as source-only and a Type-A port doesn't
> support PD capability, a data role swap is impossible.
>
> Actually, PTN5110THQ is configured for Source role only at POR, but after
> POR it can operate as a DRP (Dual-Role Power). By switching the power-role
> to dual, the port can operate as a sink and enter device mode when attach
> to Type-A port.
>
> [...]
Applied, thanks!
[1/2] arm64: dts: imx8qm-mek: switch Type-C connector power-role to dual
commit: 755d74cc06950d0f0449794dd23f42669811f6c4
[2/2] arm64: dts: imx8qxp-mek: switch Type-C connector power-role to dual
commit: 8c5dbb306887fc81737e0077b9d821909f64a5fb
Add fixes tags for both patches
Best regards,
--
Frank Li <Frank.Li@nxp.com>
^ permalink raw reply
* Re: [PATCH v5] nvme: Skip trace complete_rq on host path error
From: Keith Busch @ 2026-03-26 14:28 UTC (permalink / raw)
To: 전민식
Cc: hch@lst.de, Justin Tee, axboe@kernel.dk, sven@kernel.org,
j@jannau.net, neal@gompa.dev, sagi@grimberg.me,
justin.tee@broadcom.com, nareshgottumukkala83@gmail.com,
paul.ely@broadcom.com, James Smart, kch@nvidia.com,
linux-arm-kernel@lists.infradead.org,
linux-nvme@lists.infradead.org, asahi@lists.linux.dev,
linux-kernel@vger.kernel.org, 이은수,
칸찬
In-Reply-To: <20260326065152epcms2p51a18d3bbecb6eb6dc2ddba09651e5152@epcms2p5>
On Thu, Mar 26, 2026 at 03:51:52PM +0900, 전민식 wrote:
> {
> struct nvme_ctrl *ctrl = nvme_req(req)->ctrl;
>
> - trace_nvme_complete_rq(req);
> + /*
> + * The idea for these trace events was to match up commands
> + * dispatched to hardware with the hardware's posted response.
> + * So skip tracing for undispatched commands.
> + */
> + if (nvme_req(req)->status != NVME_SC_HOST_PATH_ERROR)
> + trace_nvme_complete_rq(req);
> +
Well, how do we know a controller doesnn't actually return that status
code? I was just suggesting to skip the trace for the condition we never
dispatched the command. An added bonus is we don't need a mostly
unnecessary 'if' check on every IO.
---
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index f5ebcaa2f859c..0dcccdca2965e 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -454,11 +454,10 @@ void nvme_end_req(struct request *req)
blk_mq_end_request(req, status);
}
-void nvme_complete_rq(struct request *req)
+static void __nvme_complete_rq(struct request *req)
{
struct nvme_ctrl *ctrl = nvme_req(req)->ctrl;
- trace_nvme_complete_rq(req);
nvme_cleanup_cmd(req);
/*
@@ -493,6 +492,12 @@ void nvme_complete_rq(struct request *req)
return;
}
}
+
+void nvme_complete_rq(struct request *req)
+{
+ trace_nvme_complete_rq(req);
+ __nvme_complete_rq(req);
+}
EXPORT_SYMBOL_GPL(nvme_complete_rq);
void nvme_complete_batch_req(struct request *req)
@@ -513,7 +518,7 @@ blk_status_t nvme_host_path_error(struct request *req)
{
nvme_req(req)->status = NVME_SC_HOST_PATH_ERROR;
blk_mq_set_request_complete(req);
- nvme_complete_rq(req);
+ __nvme_complete_rq(req);
return BLK_STS_OK;
}
EXPORT_SYMBOL_GPL(nvme_host_path_error);
--
^ permalink raw reply related
* Re: [PATCH v5] nvme: Skip trace complete_rq on host path error
From: hch @ 2026-03-26 14:31 UTC (permalink / raw)
To: Keith Busch
Cc: 전민식, hch@lst.de, Justin Tee, axboe@kernel.dk,
sven@kernel.org, j@jannau.net, neal@gompa.dev, sagi@grimberg.me,
justin.tee@broadcom.com, nareshgottumukkala83@gmail.com,
paul.ely@broadcom.com, James Smart, kch@nvidia.com,
linux-arm-kernel@lists.infradead.org,
linux-nvme@lists.infradead.org, asahi@lists.linux.dev,
linux-kernel@vger.kernel.org, 이은수,
칸찬
In-Reply-To: <acVCnozG1WKPkq1L@kbusch-mbp>
On Thu, Mar 26, 2026 at 08:28:46AM -0600, Keith Busch wrote:
> On Thu, Mar 26, 2026 at 03:51:52PM +0900, 전민식 wrote:
> > {
> > struct nvme_ctrl *ctrl = nvme_req(req)->ctrl;
> >
> > - trace_nvme_complete_rq(req);
> > + /*
> > + * The idea for these trace events was to match up commands
> > + * dispatched to hardware with the hardware's posted response.
> > + * So skip tracing for undispatched commands.
> > + */
> > + if (nvme_req(req)->status != NVME_SC_HOST_PATH_ERROR)
> > + trace_nvme_complete_rq(req);
> > +
>
> Well, how do we know a controller doesnn't actually return that status
> code? I was just suggesting to skip the trace for the condition we never
> dispatched the command. An added bonus is we don't need a mostly
> unnecessary 'if' check on every IO.
The 7?h error values were added for host use. The description of
the section in the spec suggests this, but isn't actually as clear
as I would like it. I wonder if we need to verify that controller
don't incorrectly return it, as that could cause some problems?
Independent of that your patch below looks sane to me.
^ permalink raw reply
* Re: [PATCH v2 0/3] Inline helpers into Rust without full LTO
From: Christian Schrefl @ 2026-03-26 14:31 UTC (permalink / raw)
To: Miguel Ojeda, Alice Ryhl, Ard Biesheuvel, Jamie Cunliffe,
Will Deacon, Catalin Marinas
Cc: Russell King (Oracle), Miguel Ojeda, a.hindborg, acourbot, akpm,
anton.ivanov, bjorn3_gh, boqun.feng, dakr, david, gary, johannes,
justinstitt, linux-arm-kernel, linux-kbuild, linux-kernel,
linux-mm, linux-um, llvm, lossin, mark.rutland, mmaurer, morbo,
nathan, nick.desaulniers+lkml, nicolas.schier, nsc, peterz,
richard, rust-for-linux, tmgross, urezki
In-Reply-To: <CANiq72mzPpkELXis1CiSbKUmBXNQYMiMmjj-7-sYiLh4T_JSOQ@mail.gmail.com>
Hi Miguel,
On 3/26/26 2:47 PM, Miguel Ojeda wrote:
> On Thu, Mar 26, 2026 at 11:10 AM Alice Ryhl <aliceryhl@google.com> wrote:
>>
>> I noticed that the Makefile currently uses the arm-unknown-linux-gnueabi
>> target. It should probably not be -linux target to avoid this? Probably
>> it should just be armv7a-none-eabi, right? We gate HAVE_RUST on
>> CPU_32v7, so we should not need to consider the other variants.
>
> I think Christian tried several targets back then and eventually
> picked that one.
>
> Christian: what was the reason to pick the `-linux-` one? e.g. was
> there something you wanted to rely on that target spec that you
> couldn't enable or disable via `rustc` flags or similar?
It should probably be fine to use armv7a-none-eabi. I've mostly used
arm-unknown-linux-gnueabi since I though it needed to match the
bindgen-target (which is -linux-gnu for all architectures) and
because from what I understand clang also uses arm-linux-gnueabi [1].
Also when I selected the target I thought that we would also support
armv6, but since I had no v6 hardware to test on I disabled it.
[1]: https://github.com/Rust-for-Linux/linux/blob/rust-next/scripts/Makefile.clang#L4
Cheers,
Christian
^ permalink raw reply
* Re: [PATCH v3 4/5] KVM: arm64: Enable HDBSS support and handle HDBSSF events
From: Leonardo Bras @ 2026-03-26 14:31 UTC (permalink / raw)
To: Tian Zheng
Cc: Leonardo Bras, maz, oupton, catalin.marinas, corbet, pbonzini,
will, yuzenghui, wangzhou1, liuyonglong, Jonathan.Cameron,
yezhenyu2, linuxarm, joey.gouly, kvmarm, kvm, linux-arm-kernel,
linux-doc, linux-kernel, skhan, suzuki.poulose
In-Reply-To: <acQj5grOdZT8LUGp@devkitleo>
On Wed, Mar 25, 2026 at 06:05:26PM +0000, Leonardo Bras wrote:
> Hello Tian,
>
> I am currently working on HACDBS enablement(which will be rebased on top of
> this patchset) and due to the fact HACDBS and HDBSS are kind of
> complementary I will sometimes come with some questions for issues I have
> faced myself on that part. :)
>
> (see below)
>
> On Wed, Feb 25, 2026 at 12:04:20PM +0800, Tian Zheng wrote:
> > From: eillon <yezhenyu2@huawei.com>
> >
> > HDBSS is enabled via an ioctl from userspace (e.g. QEMU) at the start of
> > migration. This feature is only supported in VHE mode.
> >
> > Initially, S2 PTEs doesn't contain the DBM attribute. During migration,
> > write faults are handled by user_mem_abort, which relaxes permissions
> > and adds the DBM bit when HDBSS is active. Once DBM is set, subsequent
> > writes no longer trap, as the hardware automatically transitions the page
> > from writable-clean to writable-dirty.
> >
> > KVM does not scan S2 page tables to consume DBM. Instead, when HDBSS is
> > enabled, the hardware observes the clean->dirty transition and records
> > the corresponding page into the HDBSS buffer.
> >
> > During sync_dirty_log, KVM kicks all vCPUs to force VM-Exit, ensuring
> > that check_vcpu_requests flushes the HDBSS buffer and propagates the
> > accumulated dirty information into the userspace-visible dirty bitmap.
> >
> > Add fault handling for HDBSS including buffer full, external abort, and
> > general protection fault (GPF).
> >
> > Signed-off-by: eillon <yezhenyu2@huawei.com>
> > Signed-off-by: Tian Zheng <zhengtian10@huawei.com>
> > ---
> > arch/arm64/include/asm/esr.h | 5 ++
> > arch/arm64/include/asm/kvm_host.h | 17 +++++
> > arch/arm64/include/asm/kvm_mmu.h | 1 +
> > arch/arm64/include/asm/sysreg.h | 11 ++++
> > arch/arm64/kvm/arm.c | 102 ++++++++++++++++++++++++++++++
> > arch/arm64/kvm/hyp/vhe/switch.c | 19 ++++++
> > arch/arm64/kvm/mmu.c | 70 ++++++++++++++++++++
> > arch/arm64/kvm/reset.c | 3 +
> > 8 files changed, 228 insertions(+)
> >
> > diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> > index 81c17320a588..2e6b679b5908 100644
> > --- a/arch/arm64/include/asm/esr.h
> > +++ b/arch/arm64/include/asm/esr.h
> > @@ -437,6 +437,11 @@
> > #ifndef __ASSEMBLER__
> > #include <asm/types.h>
> >
> > +static inline bool esr_iss2_is_hdbssf(unsigned long esr)
> > +{
> > + return ESR_ELx_ISS2(esr) & ESR_ELx_HDBSSF;
> > +}
> > +
> > static inline unsigned long esr_brk_comment(unsigned long esr)
> > {
> > return esr & ESR_ELx_BRK64_ISS_COMMENT_MASK;
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index 5d5a3bbdb95e..57ee6b53e061 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -55,12 +55,17 @@
> > #define KVM_REQ_GUEST_HYP_IRQ_PENDING KVM_ARCH_REQ(9)
> > #define KVM_REQ_MAP_L1_VNCR_EL2 KVM_ARCH_REQ(10)
> > #define KVM_REQ_VGIC_PROCESS_UPDATE KVM_ARCH_REQ(11)
> > +#define KVM_REQ_FLUSH_HDBSS KVM_ARCH_REQ(12)
> >
> > #define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
> > KVM_DIRTY_LOG_INITIALLY_SET)
> >
> > #define KVM_HAVE_MMU_RWLOCK
> >
> > +/* HDBSS entry field definitions */
> > +#define HDBSS_ENTRY_VALID BIT(0)
> > +#define HDBSS_ENTRY_IPA GENMASK_ULL(55, 12)
> > +
> > /*
> > * Mode of operation configurable with kvm-arm.mode early param.
> > * See Documentation/admin-guide/kernel-parameters.txt for more information.
> > @@ -84,6 +89,7 @@ int __init kvm_arm_init_sve(void);
> > u32 __attribute_const__ kvm_target_cpu(void);
> > void kvm_reset_vcpu(struct kvm_vcpu *vcpu);
> > void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu);
> > +void kvm_arm_vcpu_free_hdbss(struct kvm_vcpu *vcpu);
> >
> > struct kvm_hyp_memcache {
> > phys_addr_t head;
> > @@ -405,6 +411,8 @@ struct kvm_arch {
> > * the associated pKVM instance in the hypervisor.
> > */
> > struct kvm_protected_vm pkvm;
> > +
> > + bool enable_hdbss;
> > };
> >
> > struct kvm_vcpu_fault_info {
> > @@ -816,6 +824,12 @@ struct vcpu_reset_state {
> > bool reset;
> > };
> >
> > +struct vcpu_hdbss_state {
> > + phys_addr_t base_phys;
> > + u32 size;
> > + u32 next_index;
> > +};
> > +
> > struct vncr_tlb;
> >
> > struct kvm_vcpu_arch {
> > @@ -920,6 +934,9 @@ struct kvm_vcpu_arch {
> >
> > /* Per-vcpu TLB for VNCR_EL2 -- NULL when !NV */
> > struct vncr_tlb *vncr_tlb;
> > +
> > + /* HDBSS registers info */
> > + struct vcpu_hdbss_state hdbss;
> > };
> >
> > /*
> > diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> > index d968aca0461a..3fea8cfe8869 100644
> > --- a/arch/arm64/include/asm/kvm_mmu.h
> > +++ b/arch/arm64/include/asm/kvm_mmu.h
> > @@ -183,6 +183,7 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
> >
> > int kvm_handle_guest_sea(struct kvm_vcpu *vcpu);
> > int kvm_handle_guest_abort(struct kvm_vcpu *vcpu);
> > +void kvm_flush_hdbss_buffer(struct kvm_vcpu *vcpu);
> >
> > phys_addr_t kvm_mmu_get_httbr(void);
> > phys_addr_t kvm_get_idmap_vector(void);
> > diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> > index f4436ecc630c..d11f4d0dd4e7 100644
> > --- a/arch/arm64/include/asm/sysreg.h
> > +++ b/arch/arm64/include/asm/sysreg.h
> > @@ -1039,6 +1039,17 @@
> >
> > #define GCS_CAP(x) ((((unsigned long)x) & GCS_CAP_ADDR_MASK) | \
> > GCS_CAP_VALID_TOKEN)
> > +
> > +/*
> > + * Definitions for the HDBSS feature
> > + */
> > +#define HDBSS_MAX_SIZE HDBSSBR_EL2_SZ_2MB
> > +
> > +#define HDBSSBR_EL2(baddr, sz) (((baddr) & GENMASK(55, 12 + sz)) | \
> > + FIELD_PREP(HDBSSBR_EL2_SZ_MASK, sz))
> > +
> > +#define HDBSSPROD_IDX(prod) FIELD_GET(HDBSSPROD_EL2_INDEX_MASK, prod)
> > +
> > /*
> > * Definitions for GICv5 instructions]
> > */
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index 29f0326f7e00..d64da05e25c4 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -125,6 +125,87 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
> > return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
> > }
> >
> > +void kvm_arm_vcpu_free_hdbss(struct kvm_vcpu *vcpu)
> > +{
> > + struct page *hdbss_pg;
> > +
> > + hdbss_pg = phys_to_page(vcpu->arch.hdbss.base_phys);
> > + if (hdbss_pg)
> > + __free_pages(hdbss_pg, vcpu->arch.hdbss.size);
> > +
> > + vcpu->arch.hdbss.size = 0;
> > +}
> > +
> > +static int kvm_cap_arm_enable_hdbss(struct kvm *kvm,
> > + struct kvm_enable_cap *cap)
> > +{
> > + unsigned long i;
> > + struct kvm_vcpu *vcpu;
> > + struct page *hdbss_pg = NULL;
> > + __u64 size = cap->args[0];
> > + bool enable = cap->args[1] ? true : false;
> > +
> > + if (!system_supports_hdbss())
> > + return -EINVAL;
> > +
> > + if (size > HDBSS_MAX_SIZE)
> > + return -EINVAL;
> > +
> > + if (!enable && !kvm->arch.enable_hdbss) /* Already Off */
> > + return 0;
> > +
> > + if (enable && kvm->arch.enable_hdbss) /* Already On, can't set size */
> > + return -EINVAL;
> > +
> > + if (!enable) { /* Turn it off */
> > + kvm->arch.mmu.vtcr &= ~(VTCR_EL2_HD | VTCR_EL2_HDBSS | VTCR_EL2_HA);
> > +
> > + kvm_for_each_vcpu(i, vcpu, kvm) {
> > + /* Kick vcpus to flush hdbss buffer. */
> > + kvm_vcpu_kick(vcpu);
> > +
> > + kvm_arm_vcpu_free_hdbss(vcpu);
> > + }
> > +
> > + kvm->arch.enable_hdbss = false;
> > +
> > + return 0;
> > + }
> > +
> > + /* Turn it on */
> > + kvm_for_each_vcpu(i, vcpu, kvm) {
> > + hdbss_pg = alloc_pages(GFP_KERNEL_ACCOUNT, size);
> > + if (!hdbss_pg)
> > + goto error_alloc;
> > +
> > + vcpu->arch.hdbss = (struct vcpu_hdbss_state) {
> > + .base_phys = page_to_phys(hdbss_pg),
> > + .size = size,
> > + .next_index = 0,
> > + };
> > + }
> > +
> > + kvm->arch.enable_hdbss = true;
> > + kvm->arch.mmu.vtcr |= VTCR_EL2_HD | VTCR_EL2_HDBSS | VTCR_EL2_HA;
> > +
> > + /*
> > + * We should kick vcpus out of guest mode here to load new
> > + * vtcr value to vtcr_el2 register when re-enter guest mode.
> > + */
> > + kvm_for_each_vcpu(i, vcpu, kvm)
> > + kvm_vcpu_kick(vcpu);
> > +
> > + return 0;
> > +
> > +error_alloc:
> > + kvm_for_each_vcpu(i, vcpu, kvm) {
> > + if (vcpu->arch.hdbss.base_phys)
> > + kvm_arm_vcpu_free_hdbss(vcpu);
> > + }
> > +
> > + return -ENOMEM;
> > +}
> > +
> > int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
> > struct kvm_enable_cap *cap)
> > {
> > @@ -182,6 +263,11 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
> > r = 0;
> > set_bit(KVM_ARCH_FLAG_EXIT_SEA, &kvm->arch.flags);
> > break;
> > + case KVM_CAP_ARM_HW_DIRTY_STATE_TRACK:
> > + mutex_lock(&kvm->lock);
> > + r = kvm_cap_arm_enable_hdbss(kvm, cap);
> > + mutex_unlock(&kvm->lock);
> > + break;
> > default:
> > break;
> > }
> > @@ -471,6 +557,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
> > r = kvm_supports_cacheable_pfnmap();
> > break;
> >
> > + case KVM_CAP_ARM_HW_DIRTY_STATE_TRACK:
> > + r = system_supports_hdbss();
> > + break;
> > default:
> > r = 0;
> > }
> > @@ -1120,6 +1209,9 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu)
> > if (kvm_dirty_ring_check_request(vcpu))
> > return 0;
> >
> > + if (kvm_check_request(KVM_REQ_FLUSH_HDBSS, vcpu))
> > + kvm_flush_hdbss_buffer(vcpu);
> > +
> > check_nested_vcpu_requests(vcpu);
> > }
> >
> > @@ -1898,7 +1990,17 @@ long kvm_arch_vcpu_unlocked_ioctl(struct file *filp, unsigned int ioctl,
> >
> > void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot)
> > {
> > + /*
> > + * Flush all CPUs' dirty log buffers to the dirty_bitmap. Called
> > + * before reporting dirty_bitmap to userspace. Send a request with
> > + * KVM_REQUEST_WAIT to flush buffer synchronously.
> > + */
> > + struct kvm_vcpu *vcpu;
> > +
> > + if (!kvm->arch.enable_hdbss)
> > + return;
> >
> > + kvm_make_all_cpus_request(kvm, KVM_REQ_FLUSH_HDBSS);
> > }
> >
> > static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
> > diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
> > index 9db3f11a4754..600cbc4f8ae9 100644
> > --- a/arch/arm64/kvm/hyp/vhe/switch.c
> > +++ b/arch/arm64/kvm/hyp/vhe/switch.c
> > @@ -213,6 +213,23 @@ static void __vcpu_put_deactivate_traps(struct kvm_vcpu *vcpu)
> > local_irq_restore(flags);
> > }
> >
> > +static void __load_hdbss(struct kvm_vcpu *vcpu)
> > +{
> > + struct kvm *kvm = vcpu->kvm;
> > + u64 br_el2, prod_el2;
> > +
> > + if (!kvm->arch.enable_hdbss)
> > + return;
> > +
> > + br_el2 = HDBSSBR_EL2(vcpu->arch.hdbss.base_phys, vcpu->arch.hdbss.size);
> > + prod_el2 = vcpu->arch.hdbss.next_index;
> > +
> > + write_sysreg_s(br_el2, SYS_HDBSSBR_EL2);
> > + write_sysreg_s(prod_el2, SYS_HDBSSPROD_EL2);
> > +
> > + isb();
> > +}
> > +
>
> I see in the code below you trust that the tracking will happen with
> PAGE_SIZE granularity (you track with PAGE_SHIFT).
Oh, that was misleading :\
The mentioned routine is not wrong AFAICS, but without the patch I sent, if
the VMM does not manually set eager splitting, and is using some sort of
hugepages (even transparent, without noticing) it could end up sending just
PAGE_SIZE instead of the whole hugepage size, which breaks migration.
Does that make sense?
Thanks!
Leo
>
> That may be a problem when we have guest memory backed by hugepages or
> transparent huge pages.
>
> When we are using HDBSS, there is no fault happening, so we have no way of
> doing on-demand block splitting, so we need to make use of eager block
> splitting, _before_ we start to track anything, or else we may have
> different-sized pages in the HDBSS buffer, which is harder to deal with.
>
> Suggestion: do the eager splitting before we enable HDBSS.
>
> For this to happen, we have to enable the EAGER_SPLIT_CHUNK_SIZE
> capability, which can only be enabled when all memslots are empty.
>
> I suggest doing that at kvm_init_stage2_mmu(), and checking if HDBSS is
> in which case we set mmu->split_page_chunk_size to PAGESIZE.
>
> I will send a patch you can put before this one to make sure it works :)
>
> Thanks!
> Leo
>
>
> > void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu)
> > {
> > host_data_ptr(host_ctxt)->__hyp_running_vcpu = vcpu;
> > @@ -220,10 +237,12 @@ void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu)
> > __vcpu_load_switch_sysregs(vcpu);
> > __vcpu_load_activate_traps(vcpu);
> > __load_stage2(vcpu->arch.hw_mmu, vcpu->arch.hw_mmu->arch);
> > + __load_hdbss(vcpu);
> > }
> >
> > void kvm_vcpu_put_vhe(struct kvm_vcpu *vcpu)
> > {
> > + kvm_flush_hdbss_buffer(vcpu);
> > __vcpu_put_deactivate_traps(vcpu);
> > __vcpu_put_switch_sysregs(vcpu);
> >
> > diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> > index 070a01e53fcb..42b0710a16ce 100644
> > --- a/arch/arm64/kvm/mmu.c
> > +++ b/arch/arm64/kvm/mmu.c
> > @@ -1896,6 +1896,9 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> > if (writable)
> > prot |= KVM_PGTABLE_PROT_W;
> >
> > + if (writable && kvm->arch.enable_hdbss && logging_active)
> > + prot |= KVM_PGTABLE_PROT_DBM;
> > +
> > if (exec_fault)
> > prot |= KVM_PGTABLE_PROT_X;
> >
> > @@ -2033,6 +2036,70 @@ int kvm_handle_guest_sea(struct kvm_vcpu *vcpu)
> > return 0;
> > }
> >
> > +void kvm_flush_hdbss_buffer(struct kvm_vcpu *vcpu)
> > +{
> > + int idx, curr_idx;
> > + u64 br_el2;
> > + u64 *hdbss_buf;
> > + struct kvm *kvm = vcpu->kvm;
> > +
> > + if (!kvm->arch.enable_hdbss)
> > + return;
> > +
> > + curr_idx = HDBSSPROD_IDX(read_sysreg_s(SYS_HDBSSPROD_EL2));
> > + br_el2 = HDBSSBR_EL2(vcpu->arch.hdbss.base_phys, vcpu->arch.hdbss.size);
> > +
> > + /* Do nothing if HDBSS buffer is empty or br_el2 is NULL */
> > + if (curr_idx == 0 || br_el2 == 0)
> > + return;
> > +
> > + hdbss_buf = page_address(phys_to_page(vcpu->arch.hdbss.base_phys));
> > + if (!hdbss_buf)
> > + return;
> > +
> > + guard(write_lock_irqsave)(&vcpu->kvm->mmu_lock);
> > + for (idx = 0; idx < curr_idx; idx++) {
> > + u64 gpa;
> > +
> > + gpa = hdbss_buf[idx];
> > + if (!(gpa & HDBSS_ENTRY_VALID))
> > + continue;
> > +
> > + gpa &= HDBSS_ENTRY_IPA;
> > + kvm_vcpu_mark_page_dirty(vcpu, gpa >> PAGE_SHIFT);
> > + }
>
> Here ^
>
> > +
> > + /* reset HDBSS index */
> > + write_sysreg_s(0, SYS_HDBSSPROD_EL2);
> > + vcpu->arch.hdbss.next_index = 0;
> > + isb();
> > +}
> > +
> > +static int kvm_handle_hdbss_fault(struct kvm_vcpu *vcpu)
> > +{
> > + u64 prod;
> > + u64 fsc;
> > +
> > + prod = read_sysreg_s(SYS_HDBSSPROD_EL2);
> > + fsc = FIELD_GET(HDBSSPROD_EL2_FSC_MASK, prod);
> > +
> > + switch (fsc) {
> > + case HDBSSPROD_EL2_FSC_OK:
> > + /* Buffer full, which is reported as permission fault. */
> > + kvm_flush_hdbss_buffer(vcpu);
> > + return 1;
> > + case HDBSSPROD_EL2_FSC_ExternalAbort:
> > + case HDBSSPROD_EL2_FSC_GPF:
> > + return -EFAULT;
> > + default:
> > + /* Unknown fault. */
> > + WARN_ONCE(1,
> > + "Unexpected HDBSS fault type, FSC: 0x%llx (prod=0x%llx, vcpu=%d)\n",
> > + fsc, prod, vcpu->vcpu_id);
> > + return -EFAULT;
> > + }
> > +}
> > +
> > /**
> > * kvm_handle_guest_abort - handles all 2nd stage aborts
> > * @vcpu: the VCPU pointer
> > @@ -2071,6 +2138,9 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
> >
> > is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
> >
> > + if (esr_iss2_is_hdbssf(esr))
> > + return kvm_handle_hdbss_fault(vcpu);
> > +
> > if (esr_fsc_is_translation_fault(esr)) {
> > /* Beyond sanitised PARange (which is the IPA limit) */
> > if (fault_ipa >= BIT_ULL(get_kvm_ipa_limit())) {
> > diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> > index 959532422d3a..c03a4b310b53 100644
> > --- a/arch/arm64/kvm/reset.c
> > +++ b/arch/arm64/kvm/reset.c
> > @@ -161,6 +161,9 @@ void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu)
> > free_page((unsigned long)vcpu->arch.ctxt.vncr_array);
> > kfree(vcpu->arch.vncr_tlb);
> > kfree(vcpu->arch.ccsidr);
> > +
> > + if (vcpu->kvm->arch.enable_hdbss)
> > + kvm_arm_vcpu_free_hdbss(vcpu);
> > }
> >
> > static void kvm_vcpu_reset_sve(struct kvm_vcpu *vcpu)
> > --
> > 2.33.0
> >
^ permalink raw reply
* [PATCH v2 0/3] arm64: dts: freescale: imx95-toradex-smarc: Add Bluetooth and SER2
From: Franz Schnyder @ 2026-03-26 14:37 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Franz Schnyder, devicetree, imx, linux-arm-kernel, linux-kernel,
Francesco Dolcini
From: Franz Schnyder <franz.schnyder@toradex.com>
This patch series adds support for missing interfaces on the Toradex
SMARC i.MX95 SoM.
It adds:
- SER2 interface
- UART interface for Bluetooth
- WIFI_UART_EN as a gpio-hog to select the UART function by default,
as the MAYA-W260 UART signals are shared with the JTAG.
Signed-off-by: Franz Schnyder <franz.schnyder@toradex.com>
---
v2: Remove unused label for wifi-uart-en-hog node
Add explanation to clarify the safe usage of the GPIO hog
---
Franz Schnyder (3):
arm64: dts: freescale: imx95-toradex-smarc: Add SER2 interface
arm64: dts: freescale: imx95-toradex-smarc: Enable bluetooth on
lpuart5
arm64: dts: freescale: imx95-toradex-smarc: Use gpio-hog for
WIFI_UART_EN
.../dts/freescale/imx95-toradex-smarc-dev.dts | 5 +++
.../dts/freescale/imx95-toradex-smarc.dtsi | 44 +++++++++++++++++++
2 files changed, 49 insertions(+)
--
2.43.0
^ permalink raw reply
* [PATCH v2 1/3] arm64: dts: freescale: imx95-toradex-smarc: Add SER2 interface
From: Franz Schnyder @ 2026-03-26 14:37 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Franz Schnyder, devicetree, imx, linux-arm-kernel, linux-kernel,
Francesco Dolcini
In-Reply-To: <20260326143711.143462-1-fra.schnyder@gmail.com>
From: Franz Schnyder <franz.schnyder@toradex.com>
The Toradex SMARC iMX95 has four exposed serial interfaces, one of these
is SER2, which supports RTS/CTS.
Add UART support for SMARC SER2.
Signed-off-by: Franz Schnyder <franz.schnyder@toradex.com>
---
v2: no changes
---
.../dts/freescale/imx95-toradex-smarc-dev.dts | 5 +++++
.../boot/dts/freescale/imx95-toradex-smarc.dtsi | 16 ++++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx95-toradex-smarc-dev.dts b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc-dev.dts
index 5b05f256fd52..7437e523ff63 100644
--- a/arch/arm64/boot/dts/freescale/imx95-toradex-smarc-dev.dts
+++ b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc-dev.dts
@@ -210,6 +210,11 @@ &lpuart3 {
status = "okay";
};
+/* SMARC SER2 */
+&lpuart6 {
+ status = "okay";
+};
+
/* SMARC MDIO, shared between all ethernet ports */
&netc_emdio {
status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi
index 7a73958f6eec..1d369983cf7d 100644
--- a/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi
@@ -22,6 +22,7 @@ aliases {
rtc1 = &scmi_bbm;
serial0 = &lpuart2;
serial1 = &lpuart1;
+ serial2 = &lpuart6;
serial3 = &lpuart3;
};
@@ -615,6 +616,13 @@ &lpuart3 {
pinctrl-0 = <&pinctrl_uart3>;
};
+/* SMARC SER2 */
+&lpuart6 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart6>;
+ uart-has-rtscts;
+};
+
&mu7 {
status = "okay";
};
@@ -1105,6 +1113,14 @@ pinctrl_uart3: uart3grp {
<IMX95_PAD_GPIO_IO15__LPUART3_RX 0x31e>; /* SMARC P141 - SER3_RX */
};
+ /* SMARC SER2 */
+ pinctrl_uart6: uart6grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO34__LPUART6_CTS_B 0x31e>, /* SMARC P139 - SER2_CTS# */
+ <IMX95_PAD_GPIO_IO07__LPUART6_RTS_B 0x31e>, /* SMARC P138 - SER2_RTS# */
+ <IMX95_PAD_GPIO_IO05__LPUART6_RX 0x31e>, /* SMARC P137 - SER2_RX */
+ <IMX95_PAD_GPIO_IO04__LPUART6_TX 0x31e>; /* SMARC P136 - SER2_TX */
+ };
+
/* On-module eMMC */
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <IMX95_PAD_SD1_CLK__USDHC1_CLK 0x158e>, /* SD1_CLK */
--
2.43.0
^ permalink raw reply related
* [PATCH v2 2/3] arm64: dts: freescale: imx95-toradex-smarc: Enable bluetooth on lpuart5
From: Franz Schnyder @ 2026-03-26 14:37 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Franz Schnyder, devicetree, imx, linux-arm-kernel, linux-kernel,
Francesco Dolcini
In-Reply-To: <20260326143711.143462-1-fra.schnyder@gmail.com>
From: Franz Schnyder <franz.schnyder@toradex.com>
The Toradex SMARC iMX95 uses the MAYA-W260 WiFi/Bluetooth module, which
uses the UART interface for Bluetooth.
Add UART support to enable bluetooth functionality on the MAYA-W260.
Signed-off-by: Franz Schnyder <franz.schnyder@toradex.com>
---
Although Documentation/devicetree/bindings/dts-coding-style.rst
recommends an empty line between status and latest property, leave it
unchanged for consistency with the rest of the file.
v2: no changes
---
.../dts/freescale/imx95-toradex-smarc.dtsi | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi
index 1d369983cf7d..a90edefc5197 100644
--- a/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi
@@ -616,6 +616,19 @@ &lpuart3 {
pinctrl-0 = <&pinctrl_uart3>;
};
+/* On-module Bluetooth */
+&lpuart5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_bt_uart>;
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "nxp,88w8987-bt";
+ fw-init-baudrate = <3000000>;
+ };
+};
+
/* SMARC SER2 */
&lpuart6 {
pinctrl-names = "default";
@@ -830,6 +843,14 @@ &wdog3 {
};
&scmi_iomuxc {
+ /* On-module Bluetooth, UART pins shared with JTAG */
+ pinctrl_bt_uart: btuartgrp {
+ fsl,pins = <IMX95_PAD_DAP_TDO_TRACESWO__LPUART5_TX 0x31e>, /* WiFI_UART_RXD */
+ <IMX95_PAD_DAP_TDI__LPUART5_RX 0x31e>, /* WiFI_UART_TXD */
+ <IMX95_PAD_DAP_TCLK_SWCLK__LPUART5_CTS_B 0x31e>, /* WiFI_UART_RTS# */
+ <IMX95_PAD_DAP_TMS_SWDIO__LPUART5_RTS_B 0x31e>; /* WiFI_UART_CTS# */
+ };
+
/* SMARC CAM_MCK */
pinctrl_cam_mck: cammckgrp {
fsl,pins = <IMX95_PAD_CCM_CLKO1__CCMSRCGPCMIX_TOP_CLKO_1 0x51e>; /* SMARC S6 - CAM_MCK */
--
2.43.0
^ permalink raw reply related
* [PATCH v2 3/3] arm64: dts: freescale: imx95-toradex-smarc: Use gpio-hog for WIFI_UART_EN
From: Franz Schnyder @ 2026-03-26 14:37 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Franz Schnyder, devicetree, imx, linux-arm-kernel, linux-kernel,
Francesco Dolcini
In-Reply-To: <20260326143711.143462-1-fra.schnyder@gmail.com>
From: Franz Schnyder <franz.schnyder@toradex.com>
On the Toradex SMARC iMX95, the WiFi UART signals are shared with the
JTAG. The WIFI_UART_EN signal is used to select between these
two functions. A GPIO hog is used to select the UART function by
default. This DT file is going to be used by both Linux and the boot
firmware, and the boot firmware will configure the GPIO hog way before
the Linux kernel is booted, therefore there is no actual race condition
between the Linux kernel BT UART driver and GPIO hog probe.
Configure WIFI_UART_EN as a gpio-hog driven high.
Signed-off-by: Franz Schnyder <franz.schnyder@toradex.com>
---
v2: Remove unused label for wifi-uart-en-hog node
Add explanation to clarify the safe usage of the GPIO hog
---
arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi
index a90edefc5197..8eef26eb0f87 100644
--- a/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi
@@ -451,6 +451,13 @@ som_gpio_expander_1: gpio@21 {
"",
"",
"SMARC_SDIO_WP";
+
+ wifi-uart-en-hog {
+ gpio-hog;
+ gpios = <12 GPIO_ACTIVE_HIGH>;
+ line-name = "WIFI_UART_EN";
+ output-high;
+ };
};
embedded-controller@28 {
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v2] irqchip/gic-v3: Print a warning for out-of-range interrupt numbers
From: Thomas Gleixner @ 2026-03-26 14:43 UTC (permalink / raw)
To: Geert Uytterhoeven, Marc Zyngier
Cc: linux-arm-kernel, linux-renesas-soc, linux-kernel,
Geert Uytterhoeven
In-Reply-To: <ce695ea46decc816974179314a86f2b9b5cad6a9.1772799134.git.geert+renesas@glider.be>
On Fri, Mar 06 2026 at 13:13, Geert Uytterhoeven wrote:
> gic_irq_domain_translate() does not check if an interrupt number lies
> within the valid range of the specified interrupt type. Add these
> checks, and print a warning if the interrupt number is out of range.
>
> This can help flagging incorrectly described Extended SPI and PPI
> interrupts in DT.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Marc, any objections or comments?
^ permalink raw reply
* Re: [PATCH v9 05/11] drm/fourcc: Add DRM_FORMAT_X403
From: Simon Ser @ 2026-03-26 14:43 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Vishal Sagar, Anatoliy Klymenko, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Laurent Pinchart,
Michal Simek, dri-devel, linux-kernel, linux-arm-kernel,
Geert Uytterhoeven, Dmitry Baryshkov, Pekka Paalanen
In-Reply-To: <20260325-xilinx-formats-v9-5-d03b7e3752e4@ideasonboard.com>
On Wednesday, March 25th, 2026 at 15:02, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> wrote:
> +/*
> + * 3 plane non-subsampled (444) YCbCr
> + * 10 bpc, 30 bits per sample image data in a single contiguous buffer.
> + * index 0: Y plane, [31:0] x:Y2:Y1:Y0 [2:10:10:10] little endian
> + * index 1: Cb plane, [31:0] x:Cb2:Cb1:Cb0 [2:10:10:10] little endian
> + * index 2: Cr plane, [31:0] x:Cr2:Cr1:Cr0 [2:10:10:10] little endian
> + */
> +#define DRM_FORMAT_X403 fourcc_code('X', '4', '0', '3')
So, this one is different from the Q family, because Q has padding in
LSB rather than MSB. Speaking of, maybe we should add "LSB aligned" to
the doc comment to make that clear?
Re-reading the sibling thread about DRM_FORMAT_XV20, sounds like the
first digit matches my expectations for sub-sampling. How did you pick
the last two digits? I think I would've expected "30" here rather than
"03", since the last two planes are Cb Cr rather than Cr Cb.
Has the first "X" letter been picked arbitrarily? It's already used to
denote padding in other formats so I wonder if we should pick that
instead of, say, "T".
Simon
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox