* Re: [PATCH v3 3/3] arm64: dts: imx93-11x11-evk: Add DY1212W-4856 LVDS panel
From: Marco Felsch @ 2026-06-16 10:05 UTC (permalink / raw)
To: Liu Ying
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Peng Fan,
devicetree, imx, linux-arm-kernel, linux-kernel
In-Reply-To: <20260610-imx93-ldb-v3-3-c9b65d742753@nxp.com>
On 26-06-10, Liu Ying wrote:
> DY1212W-4856 [1] is a 12.1" (WXGA) TFT LCD panel with LVDS interface.
> The panel's 40-pin connector allows it to be directly connected to
> i.MX93 11x11 EVK board.
>
> Link: https://www.nxp.com/design/design-center/development-boards-and-designs/dy1212w-4856-tft-lcd-panel-with-lvds-interface:DY1212W-4856 [1]
> Signed-off-by: Liu Ying <victor.liu@nxp.com>
> ---
> arch/arm64/boot/dts/freescale/Makefile | 4 ++
> .../freescale/imx93-11x11-evk-dy1212w-4856.dtso | 81 ++++++++++++++++++++++
> 2 files changed, 85 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
> index 8ddaab127ab9..dbe27d757c86 100644
> --- a/arch/arm64/boot/dts/freescale/Makefile
> +++ b/arch/arm64/boot/dts/freescale/Makefile
> @@ -588,6 +588,10 @@ dtb-$(CONFIG_ARCH_MXC) += imx93-9x9-qsb-ontat-kd50g21-40nt-a1.dtb
> dtb-$(CONFIG_ARCH_MXC) += imx93-9x9-qsb-tianma-tm050rdh03.dtb
>
> dtb-$(CONFIG_ARCH_MXC) += imx93-11x11-evk.dtb
> +
> +imx93-11x11-evk-dy1212w-4856-dtbs += imx93-11x11-evk.dtb imx93-11x11-evk-dy1212w-4856.dtbo
> +dtb-$(CONFIG_ARCH_MXC) += imx93-11x11-evk-dy1212w-4856.dtb
> +
> dtb-$(CONFIG_ARCH_MXC) += imx93-11x11-frdm.dtb
>
> imx93-11x11-frdm-pixpaper-dtbs += imx93-11x11-frdm.dtb imx93-11x11-frdm-pixpaper.dtbo
> diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk-dy1212w-4856.dtso b/arch/arm64/boot/dts/freescale/imx93-11x11-evk-dy1212w-4856.dtso
> new file mode 100644
> index 000000000000..35f7c5699e3a
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk-dy1212w-4856.dtso
> @@ -0,0 +1,81 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright 2026 NXP
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +#include <dt-bindings/clock/imx93-clock.h>
> +
> +&{/} {
> + panel-lvds {
> + compatible = "boe,ev121wxm-n10-1850";
> + backlight = <&backlight_lvds>;
> + power-supply = <&buck4>;
> +
> + panel-timing {
> + /*
> + * Set clock frequency to 71142858Hz to accommodate
> + * IMX93_CLK_VIDEO_PLL rate at 498000000Hz in a rate
> + * table.
> + */
> + clock-frequency = <71142858>;
> + hactive = <1280>;
> + vactive = <800>;
> + hfront-porch = <48>;
> + hback-porch = <80>;
> + hsync-len = <32>;
> + vfront-porch = <3>;
> + vback-porch = <14>;
> + vsync-len = <6>;
> + };
> +
> + port {
> + panel_lvds_in: endpoint {
> + remote-endpoint = <&ldb_lvds_ch0>;
> + };
> + };
> + };
> +};
> +
> +&backlight_lvds {
> + status = "okay";
> +};
> +
> +&lcdif {
> + status = "okay";
> +};
> +
> +&lvds_bridge {
> + status = "okay";
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@1 {
> + reg = <1>;
> +
> + ldb_lvds_ch0: endpoint {
> + remote-endpoint = <&panel_lvds_in>;
> + };
> + };
> + };
You could just make use of the ldb_lvds_ch0 phandle you added previously
and drop the complete override.
Regards,
Marco
> +};
> +
> +&media_blk_ctrl {
> + assigned-clocks = <&clk IMX93_CLK_MEDIA_AXI>,
> + <&clk IMX93_CLK_MEDIA_APB>,
> + <&clk IMX93_CLK_MEDIA_DISP_PIX>,
> + <&clk IMX93_CLK_VIDEO_PLL>;
> + assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1>,
> + <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>,
> + <&clk IMX93_CLK_VIDEO_PLL>;
> + /*
> + * Set IMX93_CLK_MEDIA_DISP_PIX rate to 71142858Hz to accommodate
> + * IMX93_CLK_VIDEO_PLL rate at 498000000Hz in a rate table.
> + */
> + assigned-clock-rates = <400000000>, <133333333>, <71142858>, <498000000>;
> + status = "okay";
> +};
>
> --
> 2.43.0
>
>
--
#gernperDu
#CallMeByMyFirstName
Pengutronix e.K. | |
Steuerwalder Str. 21 | https://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
^ permalink raw reply
* [PATCH] net: airoha: fix foe_check_time allocation size
From: Wayen Yan @ 2026-06-16 9:49 UTC (permalink / raw)
To: netdev
Cc: lorenzo, horms, pabeni, kuba, edumazet, andrew+netdev,
angelogioacchino.delregno, matthias.bgg, linux-arm-kernel,
linux-mediatek
foe_check_time is declared as u16 pointer but was allocated with
only ppe_num_entries bytes instead of ppe_num_entries * sizeof(u16).
When airoha_ppe_foe_verify_entry() is called with hash >= ppe_num_entries/2,
it writes beyond the allocated buffer, causing heap buffer overflow and
potential kernel crash.
Signed-off-by: Wayen Yan <win847@gmail.com>
---
drivers/net/ethernet/airoha/airoha_ppe.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 5c9dff6bcc..8fb8ecf909 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -1578,7 +1578,8 @@ int airoha_ppe_init(struct airoha_eth *eth)
return -ENOMEM;
}
- ppe->foe_check_time = devm_kzalloc(eth->dev, ppe_num_entries,
+ ppe->foe_check_time = devm_kzalloc(eth->dev,
+ ppe_num_entries * sizeof(*ppe->foe_check_time),
GFP_KERNEL);
if (!ppe->foe_check_time)
return -ENOMEM;
--
2.51.0
^ permalink raw reply related
* [PATCH] arm64: dts: imx93-kontron: Fix memory node
From: Frieder Schrempf @ 2026-06-16 10:43 UTC (permalink / raw)
To: Conor Dooley, devicetree, Frank Li, Frieder Schrempf, imx,
Krzysztof Kozlowski, linux-arm-kernel, linux-kernel, Rob Herring,
Sascha Hauer, Shawn Guo
Cc: Fabio Estevam, Pengutronix Kernel Team
From: Frieder Schrempf <frieder.schrempf@kontron.de>
The start address of the DRAM area is 0x80000000. The minimal
size of the DDR on the SoM is 1 GiB. Fix this.
Fixes: 2b52fd6035b7 ("arm64: dts: Add support for Kontron i.MX93 OSM-S SoM and BL carrier board")
Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
---
arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi b/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi
index c79b1df339db..f881912cde46 100644
--- a/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi
@@ -15,9 +15,9 @@ aliases {
rtc1 = &bbnsm_rtc;
};
- memory@40000000 {
+ memory@80000000 {
device_type = "memory";
- reg = <0x0 0x40000000 0 0x80000000>;
+ reg = <0x0 0x80000000 0 0x40000000>;
};
chosen {
--
2.54.0
^ permalink raw reply related
* [PATCH V1] arm64: dts: imx8mq-evk: add uart3 and bluetooth node
From: Sherry Sun (OSS) @ 2026-06-16 10:52 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam
Cc: imx, devicetree, linux-arm-kernel, linux-kernel, sherry.sun
From: Sherry Sun <sherry.sun@nxp.com>
Add uart3 and bluetooth node.
Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
arch/arm64/boot/dts/freescale/imx8mq-evk.dts | 22 ++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
index e7d87ea81b69..b9b03416aa39 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
@@ -498,6 +498,19 @@ &uart1 {
status = "okay";
};
+&uart3 { /* BT */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ assigned-clocks = <&clk IMX8MQ_CLK_UART3>;
+ assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>;
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "nxp,88w8987-bt";
+ };
+};
+
&usb3_phy1 {
status = "okay";
};
@@ -657,6 +670,15 @@ MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX 0x49
>;
};
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX8MQ_IOMUXC_UART3_TXD_UART3_DCE_TX 0x49
+ MX8MQ_IOMUXC_UART3_RXD_UART3_DCE_RX 0x49
+ MX8MQ_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B 0x49
+ MX8MQ_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B 0x49
+ >;
+ };
+
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x83
base-commit: 8d6dbbbe3ba62de0a63e962ee004afb848c8e3ac
--
2.50.1
^ permalink raw reply related
* [PATCH] net: airoha: Fix QoS counter configuration for Tx-fwd channels
From: Wayen Yan @ 2026-06-16 10:50 UTC (permalink / raw)
To: netdev
Cc: lorenzo, horms, pabeni, kuba, edumazet, andrew+netdev,
angelogioacchino.delregno, matthias.bgg, linux-arm-kernel,
linux-mediatek
In airoha_qdma_init_qos_stats(), the Tx-fwd counter was incorrectly
using register index (i << 1) instead of ((i << 1) + 1). This caused
the Tx-fwd configuration to overwrite the Tx-cpu configuration for
each QoS channel, resulting in incorrect QoS statistics.
Fix by using the correct register index ((i << 1) + 1) for Tx-fwd
counter configuration.
Fixes: 20bf7d07c956 ("net: airoha: add QDMA support for Airoha EN7581 Ethernet")
Signed-off-by: Wayen Yan <win847@gmail.com>
---
drivers/net/ethernet/airoha/airoha_eth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 31cdb11cd7..329988a840 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1256,7 +1256,7 @@ static void airoha_qdma_init_qos_stats(struct airoha_qdma *qdma)
FIELD_PREP(CNTR_CHAN_MASK, i));
/* Tx-fwd transferred count */
airoha_qdma_wr(qdma, REG_CNTR_VAL((i << 1) + 1), 0);
- airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1),
+ airoha_qdma_wr(qdma, REG_CNTR_CFG((i << 1) + 1),
CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK |
CNTR_ALL_DSCP_RING_EN_MASK |
FIELD_PREP(CNTR_SRC_MASK, 1) |
--
2.51.0
^ permalink raw reply related
* [PATCH v3 0/7] KVM: arm64: Forward FFA_NOTIFICATION* calls to TrustZone
From: Sebastian Ene @ 2026-06-16 10:54 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
Remove the FFA_NOTIFICATION* calls from the blocklist used by the pKVM
FF-A proxy. This restriction was preventing the use of asynchronous
signaling mechanisms defined by the Arm FF-A specification to
communicate with the secure services.
While these calls are markes as optional, there is no reason why the
hypervisor proxy would block them because:
1. Host is the Sole Non-Secure Endpoint: The Host operates as the
only Non-Secure VM ID (VM ID 0) recognized by the Secure World.
Because all forwarded notifications are inherently attributed to
the Host by the SPMC, there is no risk of VM ID spoofing
originating from the Normal World.
2. No Memory Pointers or Addresses: The FFA_NOTIFICATION_* ABIs
operate strictly via register-based parameters, passing only
VM IDs, VCPU IDs, flags, and bitmaps. Because these calls do
not contain memory addresses, offsets, or pointers, forwarding
them doesn't pose a risk of memory-based confused deputy attack
(e.g., tricking the SPMC into overwriting protected memory).
While the pKVM proxy behaves as a relayer, it doesn't currently have its
own FF-A ID(only the host has the ID 0). The behavior of the setup
flow is covered by the spec in the: '10.9 Notification support without
a Hypervisor'.
---
Changes in v3:
- applied Will's suggestion to use the introduced method
ffa_check_unused_args_sbz for existing calls and added a new
patch in the beggining of the series to do this.
- merged the handling of
FFA_NOTIFICATION_BITMAP_CREATE/FFA_NOTIFICATION_BITMAP_DESTROY into
one patch as Vincent suggested and create one handler for both.
Changes in v2:
- enforce the MBZ/SBZ fields
- split the calls into separate patches
- rebase on 7.1-rc7
Link to v2:
https://lore.kernel.org/all/20260608165549.1479409-1-sebastianene@google.com/
Link to v1:
https://lore.kernel.org/all/20260501114447.2389222-2-sebastianene@google.com/
Sebastian Ene (7):
KVM: arm64: Enforce strict SBZ checks in the FF-A proxy
KVM: arm64: Forward FFA_NOTIFICATION_BITMAP calls to Trustzone
KVM: arm64: Support FFA_NOTIFICATION_BIND in host handler
KVM: arm64: Support FFA_NOTIFICATION_UNBIND in host handler
KVM: arm64: Support FFA_NOTIFICATION_SET in host handler
KVM: arm64: Support FFA_NOTIFICATION_GET in host handler
KVM: arm64: Support FFA_NOTIFICATION_INFO_GET in host handler
arch/arm64/kvm/hyp/nvhe/ffa.c | 205 ++++++++++++++++++++++++++++++++--
1 file changed, 197 insertions(+), 8 deletions(-)
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply
* [PATCH v3 1/7] KVM: arm64: Enforce strict SBZ checks in the FF-A proxy
From: Sebastian Ene @ 2026-06-16 10:54 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
In-Reply-To: <20260616105417.2578670-1-sebastianene@google.com>
Introduce a helper method ffa_check_unused_args_sbz to enforce strict
arguments checking when the hypervisor acts as a relayer between the
host and Trustzone.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 47 +++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 1af722771178..c723a21006aa 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -71,6 +71,18 @@ static u32 hyp_ffa_version;
static bool has_version_negotiated;
static hyp_spinlock_t version_lock;
+static bool ffa_check_unused_args_sbz(struct kvm_cpu_context *ctxt, int first_reg)
+{
+ int reg;
+
+ for (reg = first_reg; reg < 17; reg++) {
+ if (cpu_reg(ctxt, reg))
+ return true;
+ }
+
+ return false;
+}
+
static void ffa_to_smccc_error(struct arm_smccc_1_2_regs *res, u64 ffa_errno)
{
*res = (struct arm_smccc_1_2_regs) {
@@ -239,6 +251,11 @@ static void do_ffa_rxtx_map(struct arm_smccc_1_2_regs *res,
int ret = 0;
void *rx_virt, *tx_virt;
+ if (ffa_check_unused_args_sbz(ctxt, 4)) {
+ ret = FFA_RET_INVALID_PARAMETERS;
+ goto out;
+ }
+
if (npages != (KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) / FFA_PAGE_SIZE) {
ret = FFA_RET_INVALID_PARAMETERS;
goto out;
@@ -315,6 +332,11 @@ static void do_ffa_rxtx_unmap(struct arm_smccc_1_2_regs *res,
DECLARE_REG(u32, id, ctxt, 1);
int ret = 0;
+ if (ffa_check_unused_args_sbz(ctxt, 2)) {
+ ret = FFA_RET_INVALID_PARAMETERS;
+ goto out;
+ }
+
if (id != HOST_FFA_ID) {
ret = FFA_RET_INVALID_PARAMETERS;
goto out;
@@ -421,6 +443,11 @@ static void do_ffa_mem_frag_tx(struct arm_smccc_1_2_regs *res,
int ret = FFA_RET_INVALID_PARAMETERS;
u32 nr_ranges;
+ if (ffa_check_unused_args_sbz(ctxt, 5)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
if (fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE)
goto out;
@@ -482,6 +509,11 @@ static void __do_ffa_mem_xfer(const u64 func_id,
u32 offset, nr_ranges, checked_offset;
int ret = 0;
+ if (ffa_check_unused_args_sbz(ctxt, 5)) {
+ ret = FFA_RET_INVALID_PARAMETERS;
+ goto out;
+ }
+
if (addr_mbz || npages_mbz || fraglen > len ||
fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) {
ret = FFA_RET_INVALID_PARAMETERS;
@@ -581,6 +613,11 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res,
int ret = 0;
u64 handle;
+ if (ffa_check_unused_args_sbz(ctxt, 4)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
handle = PACK_HANDLE(handle_lo, handle_hi);
hyp_spin_lock(&host_buffers.lock);
@@ -769,6 +806,11 @@ static void do_ffa_version(struct arm_smccc_1_2_regs *res,
{
DECLARE_REG(u32, ffa_req_version, ctxt, 1);
+ if (ffa_check_unused_args_sbz(ctxt, 2)) {
+ res->a0 = FFA_RET_NOT_SUPPORTED;
+ return;
+ }
+
if (FFA_MAJOR_VERSION(ffa_req_version) != 1) {
res->a0 = FFA_RET_NOT_SUPPORTED;
return;
@@ -818,6 +860,11 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *res,
DECLARE_REG(u32, flags, ctxt, 5);
u32 count, partition_sz, copy_sz;
+ if (ffa_check_unused_args_sbz(ctxt, 6)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
hyp_spin_lock(&host_buffers.lock);
if (!host_buffers.rx) {
ffa_to_smccc_res(res, FFA_RET_BUSY);
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* [PATCH v3 2/7] KVM: arm64: Support FFA_NOTIFICATION_BITMAP_DESTROY in host handler
From: Sebastian Ene @ 2026-06-16 10:54 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
In-Reply-To: <20260616105417.2578670-1-sebastianene@google.com>
Allow FF-A notification bitmap destruction messages to be forwarded to
Trustzone from the host.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index b1e5f9ee86ef..49a43c38a931 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -688,7 +688,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_MEM_DONATE:
case FFA_MEM_RETRIEVE_REQ:
/* Optional notification interfaces added in FF-A 1.1 */
- case FFA_NOTIFICATION_BITMAP_DESTROY:
case FFA_NOTIFICATION_BIND:
case FFA_NOTIFICATION_UNBIND:
case FFA_NOTIFICATION_SET:
@@ -876,10 +875,12 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *res,
static void do_ffa_notif_bitmap(struct arm_smccc_1_2_regs *res,
struct kvm_cpu_context *ctxt)
{
+ DECLARE_REG(u32, func_id, ctxt, 0);
DECLARE_REG(u32, vmid, ctxt, 1);
struct arm_smccc_1_2_regs *args;
+ u32 idx_unused_args = func_id == FFA_NOTIFICATION_BITMAP_CREATE ? 3 : 2;
- if (ffa_check_unused_args_sbz(ctxt, 3)) {
+ if (ffa_check_unused_args_sbz(ctxt, idx_unused_args)) {
ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
return;
}
@@ -952,6 +953,7 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
do_ffa_part_get(&res, host_ctxt);
goto out_handled;
case FFA_NOTIFICATION_BITMAP_CREATE:
+ case FFA_NOTIFICATION_BITMAP_DESTROY:
do_ffa_notif_bitmap(&res, host_ctxt);
goto out_handled;
}
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v3 1/7] KVM: arm64: Support FFA_NOTIFICATION_BITMAP_CREATE in host handler
From: Sebastian Ene @ 2026-06-16 10:54 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
In-Reply-To: <20260616105417.2578670-1-sebastianene@google.com>
Allow FF-A notification bitmap creation messages to be forwarded to
Trustzone from the host and introduce a helper to check for SBZ
register fields.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 36 ++++++++++++++++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 1af722771178..b1e5f9ee86ef 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -71,6 +71,18 @@ static u32 hyp_ffa_version;
static bool has_version_negotiated;
static hyp_spinlock_t version_lock;
+static bool ffa_check_unused_args_sbz(struct kvm_cpu_context *ctxt, int first_reg)
+{
+ int reg;
+
+ for (reg = first_reg; reg < 17; reg++) {
+ if (cpu_reg(ctxt, reg))
+ return true;
+ }
+
+ return false;
+}
+
static void ffa_to_smccc_error(struct arm_smccc_1_2_regs *res, u64 ffa_errno)
{
*res = (struct arm_smccc_1_2_regs) {
@@ -676,7 +688,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_MEM_DONATE:
case FFA_MEM_RETRIEVE_REQ:
/* Optional notification interfaces added in FF-A 1.1 */
- case FFA_NOTIFICATION_BITMAP_CREATE:
case FFA_NOTIFICATION_BITMAP_DESTROY:
case FFA_NOTIFICATION_BIND:
case FFA_NOTIFICATION_UNBIND:
@@ -862,6 +873,26 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *res,
hyp_spin_unlock(&host_buffers.lock);
}
+static void do_ffa_notif_bitmap(struct arm_smccc_1_2_regs *res,
+ struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, vmid, ctxt, 1);
+ struct arm_smccc_1_2_regs *args;
+
+ if (ffa_check_unused_args_sbz(ctxt, 3)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ if (vmid != HOST_FFA_ID) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ args = (void *)&ctxt->regs.regs[0];
+ hyp_smccc_1_2_smc(args, res);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_1_2_regs res;
@@ -920,6 +951,9 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_PARTITION_INFO_GET:
do_ffa_part_get(&res, host_ctxt);
goto out_handled;
+ case FFA_NOTIFICATION_BITMAP_CREATE:
+ do_ffa_notif_bitmap(&res, host_ctxt);
+ goto out_handled;
}
if (ffa_call_supported(func_id))
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v3 2/7] KVM: arm64: Forward FFA_NOTIFICATION_BITMAP calls to Trustzone
From: Sebastian Ene @ 2026-06-16 10:54 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
In-Reply-To: <20260616105417.2578670-1-sebastianene@google.com>
Allow FF-A notification bitmap messages to be forwarded to
Trustzone from the host kernel driver enforce checking for
SBZ fields.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index c723a21006aa..dc7496ec295f 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -713,8 +713,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_MEM_DONATE:
case FFA_MEM_RETRIEVE_REQ:
/* Optional notification interfaces added in FF-A 1.1 */
- case FFA_NOTIFICATION_BITMAP_CREATE:
- case FFA_NOTIFICATION_BITMAP_DESTROY:
case FFA_NOTIFICATION_BIND:
case FFA_NOTIFICATION_UNBIND:
case FFA_NOTIFICATION_SET:
@@ -909,6 +907,28 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *res,
hyp_spin_unlock(&host_buffers.lock);
}
+static void do_ffa_notif_bitmap(struct arm_smccc_1_2_regs *res,
+ struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, func_id, ctxt, 0);
+ DECLARE_REG(u32, vmid, ctxt, 1);
+ struct arm_smccc_1_2_regs *args;
+ u32 idx_unused_args = func_id == FFA_NOTIFICATION_BITMAP_CREATE ? 3 : 2;
+
+ if (ffa_check_unused_args_sbz(ctxt, idx_unused_args)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ if (vmid != HOST_FFA_ID) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ args = (void *)&ctxt->regs.regs[0];
+ hyp_smccc_1_2_smc(args, res);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_1_2_regs res;
@@ -967,6 +987,10 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_PARTITION_INFO_GET:
do_ffa_part_get(&res, host_ctxt);
goto out_handled;
+ case FFA_NOTIFICATION_BITMAP_CREATE:
+ case FFA_NOTIFICATION_BITMAP_DESTROY:
+ do_ffa_notif_bitmap(&res, host_ctxt);
+ goto out_handled;
}
if (ffa_call_supported(func_id))
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* [PATCH v3 3/7] KVM: arm64: Support FFA_NOTIFICATION_BIND in host handler
From: Sebastian Ene @ 2026-06-16 10:54 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
In-Reply-To: <20260616105417.2578670-1-sebastianene@google.com>
Verify the arguments of the FF-A notification bind call and forward the
message to Trustzone.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 32 +++++++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index dc7496ec295f..3d8ed829f558 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -42,6 +42,8 @@
*/
#define HOST_FFA_ID 0
+#define FFA_NOTIF_SENDER_ENDP_MASK GENMASK(31, 16)
+
/*
* A buffer to hold the maximum descriptor size we can see from the host,
* which is required when the SPMD returns a fragmented FFA_MEM_RETRIEVE_RESP
@@ -713,7 +715,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_MEM_DONATE:
case FFA_MEM_RETRIEVE_REQ:
/* Optional notification interfaces added in FF-A 1.1 */
- case FFA_NOTIFICATION_BIND:
case FFA_NOTIFICATION_UNBIND:
case FFA_NOTIFICATION_SET:
case FFA_NOTIFICATION_GET:
@@ -929,6 +930,32 @@ static void do_ffa_notif_bitmap(struct arm_smccc_1_2_regs *res,
hyp_smccc_1_2_smc(args, res);
}
+static void do_ffa_notif_bind(struct arm_smccc_1_2_regs *res,
+ struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, endp_id, ctxt, 1);
+ DECLARE_REG(u32, flags, ctxt, 2);
+ struct arm_smccc_1_2_regs *args;
+
+ if (ffa_check_unused_args_sbz(ctxt, 5)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ if (FIELD_GET(FFA_NOTIF_SENDER_ENDP_MASK, endp_id) != HOST_FFA_ID) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ if (flags > 1) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ args = (void *)&ctxt->regs.regs[0];
+ hyp_smccc_1_2_smc(args, res);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_1_2_regs res;
@@ -991,6 +1018,9 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_NOTIFICATION_BITMAP_DESTROY:
do_ffa_notif_bitmap(&res, host_ctxt);
goto out_handled;
+ case FFA_NOTIFICATION_BIND:
+ do_ffa_notif_bind(&res, host_ctxt);
+ goto out_handled;
}
if (ffa_call_supported(func_id))
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* [PATCH v3 4/7] KVM: arm64: Support FFA_NOTIFICATION_UNBIND in host handler
From: Sebastian Ene @ 2026-06-16 10:54 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
In-Reply-To: <20260616105417.2578670-1-sebastianene@google.com>
Verify the arguments of the FF-A notification unbind call and forward
the message to Trustzone.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 3d8ed829f558..9ec9bc9a8622 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -715,7 +715,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_MEM_DONATE:
case FFA_MEM_RETRIEVE_REQ:
/* Optional notification interfaces added in FF-A 1.1 */
- case FFA_NOTIFICATION_UNBIND:
case FFA_NOTIFICATION_SET:
case FFA_NOTIFICATION_GET:
case FFA_NOTIFICATION_INFO_GET:
@@ -956,6 +955,27 @@ static void do_ffa_notif_bind(struct arm_smccc_1_2_regs *res,
hyp_smccc_1_2_smc(args, res);
}
+static void do_ffa_notif_unbind(struct arm_smccc_1_2_regs *res,
+ struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, endp_id, ctxt, 1);
+ DECLARE_REG(u32, reserved, ctxt, 2);
+ struct arm_smccc_1_2_regs *args;
+
+ if (ffa_check_unused_args_sbz(ctxt, 5) || reserved) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ if (FIELD_GET(FFA_NOTIF_SENDER_ENDP_MASK, endp_id) != HOST_FFA_ID) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ args = (void *)&ctxt->regs.regs[0];
+ arm_smccc_1_2_smc(args, res);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_1_2_regs res;
@@ -1021,6 +1041,9 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_NOTIFICATION_BIND:
do_ffa_notif_bind(&res, host_ctxt);
goto out_handled;
+ case FFA_NOTIFICATION_UNBIND:
+ do_ffa_notif_unbind(&res, host_ctxt);
+ goto out_handled;
}
if (ffa_call_supported(func_id))
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* [PATCH v3 5/7] KVM: arm64: Support FFA_NOTIFICATION_SET in host handler
From: Sebastian Ene @ 2026-06-16 10:54 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
In-Reply-To: <20260616105417.2578670-1-sebastianene@google.com>
Allow FF-A notification SET messages to be proxied from the pKVM
hypervisor to Trustzone and enforce MBZ/SBZ fields.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 9ec9bc9a8622..fcfaa441770d 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -715,7 +715,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_MEM_DONATE:
case FFA_MEM_RETRIEVE_REQ:
/* Optional notification interfaces added in FF-A 1.1 */
- case FFA_NOTIFICATION_SET:
case FFA_NOTIFICATION_GET:
case FFA_NOTIFICATION_INFO_GET:
/* Optional interfaces added in FF-A 1.2 */
@@ -976,6 +975,32 @@ static void do_ffa_notif_unbind(struct arm_smccc_1_2_regs *res,
arm_smccc_1_2_smc(args, res);
}
+static void do_ffa_notif_set(struct arm_smccc_1_2_regs *res,
+ struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, endp_id, ctxt, 1);
+ DECLARE_REG(u32, flags, ctxt, 2);
+ struct arm_smccc_1_2_regs *args;
+
+ if (FIELD_GET(FFA_NOTIF_SENDER_ENDP_MASK, endp_id) != HOST_FFA_ID) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ if (ffa_check_unused_args_sbz(ctxt, 5)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ if (flags & GENMASK(15, 2)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ args = (void *)&ctxt->regs.regs[0];
+ arm_smccc_1_2_smc(args, res);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_1_2_regs res;
@@ -1044,6 +1069,9 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_NOTIFICATION_UNBIND:
do_ffa_notif_unbind(&res, host_ctxt);
goto out_handled;
+ case FFA_NOTIFICATION_SET:
+ do_ffa_notif_set(&res, host_ctxt);
+ goto out_handled;
}
if (ffa_call_supported(func_id))
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* [PATCH v3 6/7] KVM: arm64: Support FFA_NOTIFICATION_GET in host handler
From: Sebastian Ene @ 2026-06-16 10:54 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
In-Reply-To: <20260616105417.2578670-1-sebastianene@google.com>
Allow FF-A notification GET messages to be proxied from the pKVM
hypervisor to Trustzone and enforce MBZ/SBZ fields.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index fcfaa441770d..549250ff8f82 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -715,7 +715,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_MEM_DONATE:
case FFA_MEM_RETRIEVE_REQ:
/* Optional notification interfaces added in FF-A 1.1 */
- case FFA_NOTIFICATION_GET:
case FFA_NOTIFICATION_INFO_GET:
/* Optional interfaces added in FF-A 1.2 */
case FFA_MSG_SEND_DIRECT_REQ2: /* Optional per 7.5.1 */
@@ -1001,6 +1000,26 @@ static void do_ffa_notif_set(struct arm_smccc_1_2_regs *res,
arm_smccc_1_2_smc(args, res);
}
+static void do_ffa_notif_get(struct arm_smccc_1_2_regs *res,
+ struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, flags, ctxt, 2);
+ struct arm_smccc_1_2_regs *args;
+
+ if (ffa_check_unused_args_sbz(ctxt, 3)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ if (flags & GENMASK(31, 4)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ args = (void *)&ctxt->regs.regs[0];
+ arm_smccc_1_2_smc(args, res);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_1_2_regs res;
@@ -1072,6 +1091,9 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_NOTIFICATION_SET:
do_ffa_notif_set(&res, host_ctxt);
goto out_handled;
+ case FFA_NOTIFICATION_GET:
+ do_ffa_notif_get(&res, host_ctxt);
+ goto out_handled;
}
if (ffa_call_supported(func_id))
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* [PATCH v3 7/7] KVM: arm64: Support FFA_NOTIFICATION_INFO_GET in host handler
From: Sebastian Ene @ 2026-06-16 10:54 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
In-Reply-To: <20260616105417.2578670-1-sebastianene@google.com>
Allow the host to query the FF-A notifiction status and proxy the info
get message to Trustzone. Make sure that the SBZ fields are enforced.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 549250ff8f82..dac30a5fcf5a 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -714,8 +714,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_RXTX_MAP:
case FFA_MEM_DONATE:
case FFA_MEM_RETRIEVE_REQ:
- /* Optional notification interfaces added in FF-A 1.1 */
- case FFA_NOTIFICATION_INFO_GET:
/* Optional interfaces added in FF-A 1.2 */
case FFA_MSG_SEND_DIRECT_REQ2: /* Optional per 7.5.1 */
case FFA_MSG_SEND_DIRECT_RESP2: /* Optional per 7.5.1 */
@@ -1020,6 +1018,20 @@ static void do_ffa_notif_get(struct arm_smccc_1_2_regs *res,
arm_smccc_1_2_smc(args, res);
}
+static void do_ffa_notif_info_get(struct arm_smccc_1_2_regs *res,
+ struct kvm_cpu_context *ctxt)
+{
+ struct arm_smccc_1_2_regs *args;
+
+ if (ffa_check_unused_args_sbz(ctxt, 1)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ args = (void *)&ctxt->regs.regs[0];
+ arm_smccc_1_2_smc(args, res);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_1_2_regs res;
@@ -1094,6 +1106,9 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_NOTIFICATION_GET:
do_ffa_notif_get(&res, host_ctxt);
goto out_handled;
+ case FFA_NOTIFICATION_INFO_GET:
+ do_ffa_notif_info_get(&res, host_ctxt);
+ goto out_handled;
}
if (ffa_call_supported(func_id))
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* [PATCH] net: airoha: Stop TX queues on error path in airoha_dev_open
From: Wayen Yan @ 2026-06-16 10:50 UTC (permalink / raw)
To: netdev
Cc: lorenzo, horms, pabeni, kuba, edumazet, andrew+netdev,
angelogioacchino.delregno, matthias.bgg, linux-arm-kernel,
linux-mediatek
In airoha_dev_open(), if airoha_set_vip_for_gdm_port() fails after
netif_tx_start_all_queues() has been called, the TX queues remain
started while the device configuration is incomplete. This leaves
the device in an inconsistent state where packets could be
transmitted before the VIP/IFC port configuration is complete.
Add netif_tx_stop_all_queues() call on the error path to properly
roll back the TX queue state.
Fixes: 20bf7d07c956 ("net: airoha: add QDMA support for Airoha EN7581 Ethernet")
Signed-off-by: Wayen Yan <win847@gmail.com>
---
drivers/net/ethernet/airoha/airoha_eth.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 31cdb11cd7..cf9c366907 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1715,8 +1715,10 @@ static int airoha_dev_open(struct net_device *dev)
netif_tx_start_all_queues(dev);
err = airoha_set_vip_for_gdm_port(port, true);
- if (err)
+ if (err) {
+ netif_tx_stop_all_queues(dev);
return err;
+ }
if (netdev_uses_dsa(dev))
airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
--
2.51.0
^ permalink raw reply related
* [PATCH] net: airoha: Clean up RX queues in airoha_dev_stop
From: Wayen Yan @ 2026-06-16 10:50 UTC (permalink / raw)
To: netdev
Cc: lorenzo, horms, pabeni, kuba, edumazet, andrew+netdev,
angelogioacchino.delregno, matthias.bgg, linux-arm-kernel,
linux-mediatek
When the last port is stopped, airoha_dev_stop() clears TX queues
but neglects to clean up RX queues. This can lead to:
- RX ring buffer descriptors remaining valid after device close
- Potential DMA synchronization issues on device reopen
- Risk of use-after-free if pages are freed while DMA is still active
Add cleanup loop for RX queues to mirror the TX queue cleanup,
ensuring symmetric resource management.
Fixes: 20bf7d07c956 ("net: airoha: add QDMA support for Airoha EN7581 Ethernet")
Signed-off-by: Wayen Yan <win847@gmail.com>
---
drivers/net/ethernet/airoha/airoha_eth.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 31cdb11cd7..9ca5bbf64d 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1771,6 +1771,13 @@ static int airoha_dev_stop(struct net_device *dev)
airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]);
}
+
+ for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
+ if (!qdma->q_rx[i].ndesc)
+ continue;
+
+ airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]);
+ }
}
return 0;
--
2.51.0
^ permalink raw reply related
* Re: [PATCH net 4/4] net: ti: icssg: Fix XSK zero copy TX during application wakeup
From: Meghana Malladi @ 2026-06-16 11:11 UTC (permalink / raw)
To: Jakub Kicinski
Cc: diogo.ivo, haokexin, vadim.fedorenko, devnexen, horms,
jacob.e.keller, sdf, john.fastabend, hawk, daniel, ast, pabeni,
edumazet, davem, andrew+netdev, bpf, linux-kernel, netdev,
linux-arm-kernel, srk, Vignesh Raghavendra, Roger Quadros,
danishanwar
In-Reply-To: <20260615162157.3748bcda@kernel.org>
Hi Jakub,
On 6/16/26 04:51, Jakub Kicinski wrote:
> On Fri, 12 Jun 2026 00:27:44 +0530 Meghana Malladi wrote:
>> @@ -169,9 +169,6 @@ static int emac_xsk_xmit_zc(struct prueth_emac *emac,
>>
>> num_tx++;
>> }
>> -
>> - xsk_tx_release(tx_chn->xsk_pool);
>> - return num_tx;
>
> Why are you deleting this?
>
xsk_sendmsg() also calls this without an rcu-lock when transmitting the
packets if the xmit was successful, so I was assuming it is not required
and I removed this.
>> }
>>
>> void prueth_xmit_free(struct prueth_tx_chn *tx_chn,
>> @@ -279,9 +276,6 @@ int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
>> num_tx++;
>> }
>>
>> - if (!num_tx)
>> - return 0;
>
> Does something prevent us from running all this code if budget is 0?
> If budget is 0 we can complete normal Tx with skbs but we must
> not touch any AF-XDP related state.
>
Can you elaborate more, I couldn't interpret your comment here
>> netif_txq = netdev_get_tx_queue(ndev, chn);
>> netdev_tx_completed_queue(netif_txq, num_tx, total_bytes);
>>
>> @@ -306,7 +300,9 @@ int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
>>
>> netif_txq = netdev_get_tx_queue(ndev, chn);
>> txq_trans_cond_update(netif_txq);
>
> This looks misplaced, now we will hit it even if we didn't complete
> or submit any Tx.
>
This code needs to be hit for packet transmission in zero copy mode.
emac_xsk_xmit_zc() submits the packets to the DMA in NAPI context,
when application wakes up the driver and triggers NAPI. Once DMA
transfer is done, irq gets triggered NAPI gets called which will handle
the tx packet completion + submit next Tx batch packets to the DMA.
if (tx_chn->xsk_pool) -> check ensure this hits and runs for zero copy
only. Also above check (!num_tx) returns early during the application
wakeup (where budget is zero), hence it is removed.
>> + __netif_tx_lock(netif_txq, smp_processor_id());
>> emac_xsk_xmit_zc(emac, chn);
>> + __netif_tx_unlock(netif_txq);
>> }
^ permalink raw reply
* [PATCH v2 0/3] Bluetooth: btmtksdio: teardown fixes
From: Sergey Senozhatsky @ 2026-06-16 11:12 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz, Mark-yw Chen, Sean Wang
Cc: Tomasz Figa, linux-bluetooth, linux-kernel, linux-arm-kernel,
linux-mediatek, Sergey Senozhatsky
This is v2 of teardown fixes.
We noticed a number of cases when btmtk close/teardown would hung:
INFO: task kworker/u17:0:189 blocked for more than 122 seconds.
__cancel_work_timer+0x3f4/0x460
cancel_work_sync+0x1c/0x2c
btmtksdio_flush+0x2c/0x40
hci_dev_open_sync+0x10c4/0x2190
[..]
There are several issues with the teardown (close/reset) code
in the driver. First, the btmtksdio_txrx_work() potentially
can spin forever (infinite loop). Second, close/flush can
deadlock when run concurrently with btmtksdio_txrx_work().
v1 -> v2:
- added two more patches (deadlock fix, interrupts re-enabling
enhancement)
Sergey Senozhatsky (3):
Bluetooth: btmtksdio: correct btmtksdio_txrx_work() loop timeout check
Bluetooth: btmtksdio: test for bug IO errors in btmtksdio_txrx_work()
Bluetooth: btmtksdio: call cancel_work_sync() outside of host lock
scope
drivers/bluetooth/btmtksdio.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply
* [PATCH v2 1/3] Bluetooth: btmtksdio: correct btmtksdio_txrx_work() loop timeout check
From: Sergey Senozhatsky @ 2026-06-16 11:12 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz, Mark-yw Chen, Sean Wang
Cc: Tomasz Figa, linux-bluetooth, linux-kernel, linux-arm-kernel,
linux-mediatek, Sergey Senozhatsky, stable
In-Reply-To: <20260616111224.152140-1-senozhatsky@chromium.org>
The btmtksdio_txrx_work() loop is expected to be terminated if running
for longer than 5*HZ. However the timeout check is reversed:
time_is_before_jiffies(old_jiffies + 5*HZ) evaluates to true when
old_jiffies + 5*HZ is in the past i.e. when a timeout has occurred.
Using OR with time_is_before_jiffies(txrx_timeout) means that:
- before the 5-second timeout: the condition is `int_status || false`,
so it loops as long as there are pending interrupts.
- after the 5-second timeout: the condition becomes `int_status || true`,
which is always true.
Fix loop termination condition to actually enforce a 5*HZ timeout.
Fixes: 26270bc189ea4 ("Bluetooth: btmtksdio: move interrupt service to work")
Cc: stable@vger.kernel.org
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/bluetooth/btmtksdio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index 5b0fab7b89b5..c6f80c419e90 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -620,7 +620,7 @@ static void btmtksdio_txrx_work(struct work_struct *work)
if (btmtksdio_rx_packet(bdev, rx_size) < 0)
bdev->hdev->stat.err_rx++;
}
- } while (int_status || time_is_before_jiffies(txrx_timeout));
+ } while (int_status && time_is_after_jiffies(txrx_timeout));
/* Enable interrupt */
if (bdev->func->irq_handler)
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* [PATCH v2 3/3] Bluetooth: btmtksdio: call cancel_work_sync() outside of host lock scope
From: Sergey Senozhatsky @ 2026-06-16 11:12 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz, Mark-yw Chen, Sean Wang
Cc: Tomasz Figa, linux-bluetooth, linux-kernel, linux-arm-kernel,
linux-mediatek, Sergey Senozhatsky, stable
In-Reply-To: <20260616111224.152140-1-senozhatsky@chromium.org>
cancel_work_sync() should be called outside of host lock scope
in order to avoid circular locking scenario:
CPU0 CPU1
close()/reset()
sdio_claim_host()
txrx_work
sdio_claim_host() // sleeps
cancel_work_sync() // sleeps
In addition, when txrx_work() runs concurrently with close()/reset()
it better not to re-enable interrupts by testing for BTMTKSDIO_FUNC_ENABLED
and not BTMTKSDIO_HW_RESET_ACTIVE before C_INT_EN_SET write. However,
btmtksdio_close() clears the BTMTKSDIO_FUNC_ENABLED too late (after
cancel_work_sync() call). Move BTMTKSDIO_FUNC_ENABLED bit-clear earlier
so that txrx_work can see concurrent close().
Fixes: 26270bc189ea4 ("Bluetooth: btmtksdio: move interrupt service to work")
Cc: stable@vger.kernel.org
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/bluetooth/btmtksdio.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index d8c8d2857527..207d04cc2282 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -625,7 +625,9 @@ static void btmtksdio_txrx_work(struct work_struct *work)
} while (int_status && time_is_after_jiffies(txrx_timeout));
/* Enable interrupt */
- if (bdev->func->irq_handler)
+ if (bdev->func->irq_handler &&
+ test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state) &&
+ !test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, NULL);
sdio_release_host(bdev->func);
@@ -741,6 +743,8 @@ static int btmtksdio_close(struct hci_dev *hdev)
if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state))
return 0;
+ clear_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state);
+
sdio_claim_host(bdev->func);
/* Disable interrupt */
@@ -748,11 +752,12 @@ static int btmtksdio_close(struct hci_dev *hdev)
sdio_release_irq(bdev->func);
+ sdio_release_host(bdev->func);
cancel_work_sync(&bdev->txrx_work);
+ sdio_claim_host(bdev->func);
btmtksdio_fw_pmctrl(bdev);
- clear_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state);
sdio_disable_func(bdev->func);
sdio_release_host(bdev->func);
@@ -1295,7 +1300,10 @@ static void btmtksdio_reset(struct hci_dev *hdev)
sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
skb_queue_purge(&bdev->txq);
+
+ sdio_release_host(bdev->func);
cancel_work_sync(&bdev->txrx_work);
+ sdio_claim_host(bdev->func);
gpiod_set_value_cansleep(bdev->reset, 1);
msleep(100);
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* [PATCH v2 2/3] Bluetooth: btmtksdio: test for bug IO errors in btmtksdio_txrx_work()
From: Sergey Senozhatsky @ 2026-06-16 11:12 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz, Mark-yw Chen, Sean Wang
Cc: Tomasz Figa, linux-bluetooth, linux-kernel, linux-arm-kernel,
linux-mediatek, Sergey Senozhatsky, stable
In-Reply-To: <20260616111224.152140-1-senozhatsky@chromium.org>
btmtksdio_txrx_work() loop termination condition checks for
int_status being non-zero, however, this evaluates to true
even when sdio_readl() encounters BUS I/O error (in which
case int_status is 0xffffffff). Break out of the loop if
sdio_readl() errors out.
Fixes: 26270bc189ea4 ("Bluetooth: btmtksdio: move interrupt service to work")
Cc: stable@vger.kernel.org
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
drivers/bluetooth/btmtksdio.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index c6f80c419e90..d8c8d2857527 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -574,7 +574,9 @@ static void btmtksdio_txrx_work(struct work_struct *work)
txrx_timeout = jiffies + 5 * HZ;
do {
- int_status = sdio_readl(bdev->func, MTK_REG_CHISR, NULL);
+ int_status = sdio_readl(bdev->func, MTK_REG_CHISR, &err);
+ if (err < 0 || int_status == 0xffffffff)
+ break;
/* Ack an interrupt as soon as possible before any operation on
* hardware.
--
2.54.0.1136.gdb2ca164c4-goog
^ permalink raw reply related
* [PATCH v10 1/2] dt-bindings: ufs: Document static TX Equalization settings properties
From: Can Guo @ 2026-06-16 11:33 UTC (permalink / raw)
To: krzk, bvanassche, beanhuo, peter.wang, martin.petersen, mani
Cc: linux-scsi, Can Guo, Krzysztof Kozlowski, Alim Akhtar,
Avri Altman, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Ram Kumar Dwivedi,
Zhaoming Luo,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list,
moderated list:ARM/Mediatek SoC support:Keyword:mediatek,
moderated list:ARM/Mediatek SoC support:Keyword:mediatek
In-Reply-To: <20260616113348.1168248-1-can.guo@oss.qualcomm.com>
UFS v5.0/UFSHCI v5.0 adds HS-G6 support (46.6 Gbps/lane) via UniPro
v3.0 and M-PHY v6.0. These specs define TX Equalization for all
High-Speed Gears (not only HS-G6) to compensate channel loss and
improve signal integrity at high speed.
For HS-G6, M-PHY uses PAM4 1b1b line coding. Pre-Coding may also be
required depending on channel characteristics.
Document vendor-neutral properties in ufs-common.yaml:
- txeq-preshoot-g[1-6]
- txeq-deemphasis-g[1-6]
- tx-precode-enable-g6
Values are per-lane Host/Device tuples (2 values for x1, 4 values for
x2). PreShoot/DeEmphasis range from 0..7, and Precode is 0/1.
These are board-specific signal-integrity tuning values. They depend on
channel SI/PHY characterization and validation (host PHY, device PHY,
package, and board routing), and are determined by HW/PHY designers.
Although UFSHCI v5.0 supports TX Equalization Training via UniPro v3.0,
which allows host software to determine optimal TX Equalization at
runtime, static board-specific TX Equalization settings in the Device
Tree are still necessary because:
- TX Equalization Training is not supported for HS-G3 and below
- TX Equalization Training is disabled on some platforms
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Can Guo <can.guo@oss.qualcomm.com>
---
.../devicetree/bindings/ufs/ufs-common.yaml | 58 +++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/Documentation/devicetree/bindings/ufs/ufs-common.yaml b/Documentation/devicetree/bindings/ufs/ufs-common.yaml
index ed97f5682509..cc32e1189d50 100644
--- a/Documentation/devicetree/bindings/ufs/ufs-common.yaml
+++ b/Documentation/devicetree/bindings/ufs/ufs-common.yaml
@@ -105,6 +105,64 @@ properties:
Restricts the UFS controller to rate-a or rate-b for both TX and
RX directions.
+ tx-precode-enable-g6:
+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
+ minItems: 1
+ items:
+ - items:
+ - description: Host_Lane0 precode
+ enum: [0, 1]
+ - description: Device_Lane0 precode
+ enum: [0, 1]
+ - items:
+ - description: Host_Lane1 precode
+ enum: [0, 1]
+ - description: Device_Lane1 precode
+ enum: [0, 1]
+ description:
+ Static TX Precode enable values for HS-G6 only.
+
+patternProperties:
+ "^txeq-preshoot-g[1-6]$":
+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
+ minItems: 1
+ items:
+ - items:
+ - description: Host_Lane0 Preshoot value
+ enum: [0, 1, 2, 3, 4, 5, 6, 7]
+ - description: Device_Lane0 Preshoot value
+ enum: [0, 1, 2, 3, 4, 5, 6, 7]
+ - items:
+ - description: Host_Lane1 Preshoot value
+ enum: [0, 1, 2, 3, 4, 5, 6, 7]
+ - description: Device_Lane1 Preshoot value
+ enum: [0, 1, 2, 3, 4, 5, 6, 7]
+ description: |
+ Static TX Equalization PreShoot settings for High Speed Gears. These
+ values are programmed to the corresponding UniPro PA layer attribute
+ PA_TxEQG[1-6]Setting. Each value selects a Pre-Shoot level as defined
+ by the MIPI M-PHY specification (TX_HS_PreShoot_Setting).
+
+ "^txeq-deemphasis-g[1-6]$":
+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
+ minItems: 1
+ items:
+ - items:
+ - description: Host_Lane0 DeEmphasis value
+ enum: [0, 1, 2, 3, 4, 5, 6, 7]
+ - description: Device_Lane0 DeEmphasis value
+ enum: [0, 1, 2, 3, 4, 5, 6, 7]
+ - items:
+ - description: Host_Lane1 DeEmphasis value
+ enum: [0, 1, 2, 3, 4, 5, 6, 7]
+ - description: Device_Lane1 DeEmphasis value
+ enum: [0, 1, 2, 3, 4, 5, 6, 7]
+ description: |
+ Static TX Equalization DeEmphasis settings for High Speed Gears. These
+ values are programmed to the corresponding UniPro PA layer attribute
+ PA_TxEQG[1-6]Setting. Each value selects a De-Emphasis level as defined
+ by the MIPI M-PHY specification (TX_HS_DeEmphasis_Setting).
+
dependencies:
freq-table-hz: [ clocks ]
operating-points-v2: [ clocks, clock-names ]
--
2.34.1
^ permalink raw reply related
* [PATCH v10 2/2] scsi: ufs: core: Add support for static TX Equalization settings
From: Can Guo @ 2026-06-16 11:33 UTC (permalink / raw)
To: krzk, bvanassche, beanhuo, peter.wang, martin.petersen, mani
Cc: linux-scsi, Can Guo, Alim Akhtar, Avri Altman,
James E.J. Bottomley, Matthias Brugger,
AngeloGioacchino Del Regno, Nitin Rawat, Ram Kumar Dwivedi,
open list,
moderated list:ARM/Mediatek SoC support:Keyword:mediatek,
moderated list:ARM/Mediatek SoC support:Keyword:mediatek
In-Reply-To: <20260616113348.1168248-1-can.guo@oss.qualcomm.com>
Parse board-specific static TX Equalization settings from Device Tree for
each HS gear and store them in hba->tx_eq_params.
Parse txeq-preshoot-g[1-6] and txeq-deemphasis-g[1-6] as per-lane tuples:
<Host_Lane0 Device_Lane0>, [<Host_Lane1 Device_Lane1>].
For HS-G6, parse optional tx-precode-enable-g6 using the same per-lane
Host/Device tuple format. If provided, it must contain values for all
active lanes, and each value must be 0 or 1.
Introduce from_dt in struct ufshcd_tx_eq_params to track whether TX EQ
values came from static Device Tree data.
When adaptive TX Equalization is used, these static settings are not final:
- If valid settings are retrieved from qTxEQGnSettings/wTxEQGnSettingsExt,
those retrieved settings override static Device Tree settings.
- If retrieval is not available/valid, TX EQTR runs and trained settings
override static Device Tree settings.
So static Device Tree settings are a fallback for cases where adaptive TX
Equalization is not enabled or not used. Adaptive TX Equalization remains
the primary path when enabled.
No behavior changes for platforms that do not provide these properties.
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Can Guo <can.guo@oss.qualcomm.com>
---
drivers/ufs/core/ufs-txeq.c | 15 ++-
drivers/ufs/host/ufshcd-pltfrm.c | 154 +++++++++++++++++++++++++++++++
include/ufs/ufshcd.h | 2 +
3 files changed, 170 insertions(+), 1 deletion(-)
diff --git a/drivers/ufs/core/ufs-txeq.c b/drivers/ufs/core/ufs-txeq.c
index 3a2fb5329d27..3c94b94dd7b7 100644
--- a/drivers/ufs/core/ufs-txeq.c
+++ b/drivers/ufs/core/ufs-txeq.c
@@ -1297,7 +1297,13 @@ int ufshcd_config_tx_eq_settings(struct ufs_hba *hba,
}
params = &hba->tx_eq_params[gear - 1];
- if (!params->is_valid || force_tx_eqtr) {
+ /*
+ * TX EQTR must run for the following cases:
+ * 1. TX EQ settings are invalid.
+ * 2. TX EQ settings are from Device Tree.
+ * 3. TX EQTR procedure is forced.
+ */
+ if (!params->is_valid || params->from_dt || force_tx_eqtr) {
int ret;
ret = ufshcd_tx_eqtr(hba, params, pwr_mode);
@@ -1310,6 +1316,8 @@ int ufshcd_config_tx_eq_settings(struct ufs_hba *hba,
/* Mark TX Equalization settings as valid */
params->is_valid = true;
params->is_trained = true;
+ /* TX EQTR succeeds, clear from_dt flag */
+ params->from_dt = false;
params->is_applied = false;
}
@@ -1495,6 +1503,11 @@ static void ufshcd_extract_tx_eq_settings_attrs(struct ufs_hba *hba, u8 gear)
}
params->is_valid = true;
+ /*
+ * Optimal TX EQ settings are retrieved from UFS device attributes,
+ * clear from_dt flag to avoid TX EQTR procedure.
+ */
+ params->from_dt = false;
}
void ufshcd_retrieve_tx_eq_settings(struct ufs_hba *hba)
diff --git a/drivers/ufs/host/ufshcd-pltfrm.c b/drivers/ufs/host/ufshcd-pltfrm.c
index c2dafb583cf5..5ac7afe75934 100644
--- a/drivers/ufs/host/ufshcd-pltfrm.c
+++ b/drivers/ufs/host/ufshcd-pltfrm.c
@@ -210,6 +210,158 @@ static void ufshcd_init_lanes_per_dir(struct ufs_hba *hba)
}
}
+static int ufshcd_parse_tx_precode_enable(struct ufs_hba *hba,
+ bool host_precode_en[UFS_MAX_LANES],
+ bool device_precode_en[UFS_MAX_LANES])
+{
+ const char *prop_name = "tx-precode-enable-g6";
+ u32 num_elems = 2 * hba->lanes_per_direction;
+ const u32 lpd = hba->lanes_per_direction;
+ u32 precode[UFS_MAX_LANES * 2];
+ struct device *dev = hba->dev;
+ int count, err, i;
+
+ count = of_property_count_u32_elems(dev->of_node, prop_name);
+ if (count == -EINVAL || count == -ENODATA)
+ return 0;
+
+ if (count < 0)
+ return count;
+
+ if (count != num_elems) {
+ dev_err(dev, "Property %s has invalid count (%d), expecting %u\n",
+ prop_name, count, num_elems);
+ return -EINVAL;
+ }
+
+ err = of_property_read_u32_array(dev->of_node, prop_name, precode, num_elems);
+ if (err) {
+ dev_err(dev, "Failed to read %s property, %d\n", prop_name, err);
+ return err;
+ }
+
+ for (i = 0; i < num_elems; i++) {
+ if (precode[i] > 1) {
+ dev_err(dev, "Invalid TX precode value (%u) in %s property\n",
+ precode[i], prop_name);
+ return -EINVAL;
+ }
+ }
+
+ for (i = 0; i < lpd; i++) {
+ host_precode_en[i] = precode[i * 2];
+ device_precode_en[i] = precode[i * 2 + 1];
+ }
+
+ return 0;
+}
+
+static int ufshcd_parse_tx_eq_value_array(struct ufs_hba *hba,
+ const char *prop_name,
+ const u32 max_value,
+ u32 values[UFS_MAX_LANES * 2])
+{
+ u32 num_elems = 2 * hba->lanes_per_direction;
+ struct device *dev = hba->dev;
+ int count, err, i;
+
+ count = of_property_count_u32_elems(dev->of_node, prop_name);
+ if (count < 0)
+ return count;
+
+ if (count != num_elems) {
+ dev_err(dev, "Property %s has invalid count (%d), expecting %u\n",
+ prop_name, count, num_elems);
+ return -EINVAL;
+ }
+
+ err = of_property_read_u32_array(dev->of_node, prop_name, values, num_elems);
+ if (err) {
+ dev_err(dev, "Failed to read %s property, %d\n", prop_name, err);
+ return err;
+ }
+
+ for (i = 0; i < num_elems; i++) {
+ if (values[i] >= max_value) {
+ dev_err(dev, "Invalid TX EQ value (%u) in %s property\n",
+ values[i], prop_name);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * ufshcd_parse_tx_eq_settings_for_gear - Parse static TX EQ DT settings for one gear
+ * @hba: per adapter instance
+ * @gear: target HS gear
+ *
+ * Reads the txeq-preshoot-gN, txeq-deemphasis-gN, and (for G6)
+ * tx-precode-enable-g6 device-tree properties.
+ * If all present values are valid, stores them as static TX Equalization
+ * settings for the given gear.
+ */
+static void ufshcd_parse_tx_eq_settings_for_gear(struct ufs_hba *hba, int gear)
+{
+ bool device_precode_en[UFS_MAX_LANES] = { false };
+ bool host_precode_en[UFS_MAX_LANES] = { false };
+ const u32 lpd = hba->lanes_per_direction;
+ struct ufshcd_tx_eq_params *params;
+ u32 deemphasis[UFS_MAX_LANES * 2];
+ u32 preshoot[UFS_MAX_LANES * 2];
+ char prop_name[MAX_PROP_SIZE];
+ int err, lane;
+
+ snprintf(prop_name, MAX_PROP_SIZE, "txeq-preshoot-g%d", gear);
+ err = ufshcd_parse_tx_eq_value_array(hba, prop_name, TX_HS_NUM_PRESHOOT, preshoot);
+ if (err)
+ return;
+
+ snprintf(prop_name, MAX_PROP_SIZE, "txeq-deemphasis-g%d", gear);
+ err = ufshcd_parse_tx_eq_value_array(hba, prop_name, TX_HS_NUM_DEEMPHASIS, deemphasis);
+ if (err)
+ return;
+
+ if (gear == UFS_HS_G6) {
+ err = ufshcd_parse_tx_precode_enable(hba, host_precode_en, device_precode_en);
+ if (err)
+ return;
+ }
+
+ params = &hba->tx_eq_params[gear - 1];
+ for (lane = 0; lane < lpd; lane++) {
+ params->host[lane].preshoot = preshoot[lane * 2];
+ params->host[lane].deemphasis = deemphasis[lane * 2];
+ params->host[lane].precode_en = host_precode_en[lane];
+
+ params->device[lane].preshoot = preshoot[lane * 2 + 1];
+ params->device[lane].deemphasis = deemphasis[lane * 2 + 1];
+ params->device[lane].precode_en = device_precode_en[lane];
+ }
+
+ params->is_valid = true;
+ params->from_dt = true;
+}
+
+static void ufshcd_parse_static_tx_eq_settings(struct ufs_hba *hba)
+{
+ const u32 lpd = hba->lanes_per_direction;
+ int gear;
+
+ if (!lpd)
+ return;
+
+ if (lpd > UFS_MAX_LANES) {
+ dev_warn(hba->dev, "lanes_per_direction (%u) exceeds UFS_MAX_LANES (%u)\n",
+ lpd, UFS_MAX_LANES);
+ return;
+ }
+
+ for (gear = UFS_HS_G1; gear <= UFS_HS_GEAR_MAX; gear++)
+ ufshcd_parse_tx_eq_settings_for_gear(hba, gear);
+}
+
/**
* ufshcd_parse_clock_min_max_freq - Parse MIN and MAX clocks freq
* @hba: per adapter instance
@@ -528,6 +680,8 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
ufshcd_init_lanes_per_dir(hba);
+ ufshcd_parse_static_tx_eq_settings(hba);
+
err = ufshcd_parse_operating_points(hba);
if (err) {
dev_err(dev, "%s: OPP parse failed %d\n", __func__, err);
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index f48d6416e299..0f87b081b2ff 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -359,6 +359,7 @@ struct ufshcd_tx_eqtr_record {
* @is_valid: True if parameter contains valid TX Equalization settings
* @is_applied: True if settings have been applied to UniPro of both sides
* @is_trained: True if parameters obtained from TX EQTR procedure
+ * @from_dt: True if settings are from Device Tree
*/
struct ufshcd_tx_eq_params {
struct ufshcd_tx_eq_settings host[UFS_MAX_LANES];
@@ -367,6 +368,7 @@ struct ufshcd_tx_eq_params {
bool is_valid;
bool is_applied;
bool is_trained;
+ bool from_dt;
};
/**
--
2.34.1
^ permalink raw reply related
* [PATCH] KVM: arm64: nv: Translate vEL2 PSTATE to EL1 in kvm_hyp_handle_mops()
From: Weiming Shi @ 2026-06-16 11:49 UTC (permalink / raw)
To: Marc Zyngier, Oliver Upton, Catalin Marinas, Will Deacon
Cc: Joey Gouly, Steffen Eiden, Suzuki K Poulose, Zenghui Yu,
Andrew Morton, Jakub Kicinski, Bjorn Andersson, Mark Rutland,
Kristina Martsenko, linux-arm-kernel, kvmarm, Zhong Wang,
Xuanqing Shi, Weiming Shi
When a nested virtualisation guest is running its virtual EL2 (vEL2),
fixup_guest_exit() rewrites vcpu_cpsr() to the guest's virtual exception
level: a hardware PSTATE.M of EL1{t,h} is presented as EL2{t,h}. The
hardware, however, executes vEL2 at EL1.
kvm_hyp_handle_mops() runs on the fast guest re-entry path, where it
clears the single-step bit and restores SPSR_EL2 directly from
vcpu_cpsr():
*vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;
write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
For a guest hypervisor this writes the vEL2 view (PSTATE.M == EL2h) into
the hardware SPSR_EL2 without translating it back. The fast path re-enters
the guest via __guest_enter()/ERET without going through
__sysreg_restore_el2_return_state(), so neither to_hw_pstate() nor the
"return to a less privileged mode" safety check there (which would set
PSR_IL_BIT) is applied. The ERET therefore restores PSTATE.M = EL2h and
re-enters the guest at the real EL2 with a guest-controlled ELR, escaping
stage-2 and the guest/host boundary.
This is reachable on a kernel with FEAT_MOPS running a KVM nested guest
(kvm-arm.mode=nested): KVM sets HCRX_EL2.MCE2, which the guest hypervisor
cannot clear for its own context (is_nested_ctxt() is false), so a vEL2
MOPS exception is taken to the host and dispatched to kvm_hyp_handle_mops()
with VCPU_IN_HYP_CONTEXT set.
Translate EL2{t,h} back to EL1{t,h} before writing SPSR_EL2, mirroring
kvm_hyp_handle_eret(). For non-nested guests vcpu_cpsr() never holds an
EL2 mode, so the translation is a no-op and behaviour is unchanged.
Fixes: 2de451a329cf ("KVM: arm64: Add handler for MOPS exceptions")
Assisted-by: Claude:claude-opus-4-8
Reported-by: Zhong Wang <wangzhong.c0ss4ck@bytedance.com>
Reported-by: Xuanqing Shi <shixuanqing.11@bytedance.com>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
arch/arm64/kvm/hyp/include/hyp/switch.h | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index e9b36a3b27bbc..a6b7963ddbf0b 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -448,6 +448,8 @@ static inline bool __populate_fault_info(struct kvm_vcpu *vcpu)
static inline bool kvm_hyp_handle_mops(struct kvm_vcpu *vcpu, u64 *exit_code)
{
+ u64 spsr, mode;
+
*vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
arm64_mops_reset_regs(vcpu_gp_regs(vcpu), vcpu->arch.fault.esr_el2);
write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
@@ -457,7 +459,26 @@ static inline bool kvm_hyp_handle_mops(struct kvm_vcpu *vcpu, u64 *exit_code)
* instruction.
*/
*vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;
- write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
+
+ /*
+ * For a guest hypervisor, vcpu_cpsr() holds the vEL2 view
+ * (PSTATE.M == EL2h) installed by fixup_guest_exit(), but vEL2
+ * runs at EL1. Translate it back before restoring SPSR_EL2, as in
+ * kvm_hyp_handle_eret().
+ */
+ spsr = *vcpu_cpsr(vcpu);
+ mode = spsr & (PSR_MODE_MASK | PSR_MODE32_BIT);
+ switch (mode) {
+ case PSR_MODE_EL2t:
+ mode = PSR_MODE_EL1t;
+ break;
+ case PSR_MODE_EL2h:
+ mode = PSR_MODE_EL1h;
+ break;
+ }
+ spsr = (spsr & ~(PSR_MODE_MASK | PSR_MODE32_BIT)) | mode;
+
+ write_sysreg_el2(spsr, SYS_SPSR);
return true;
}
--
2.43.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox