* [PATCH v4 8/8] usb: typec: ucsi: huawei-gaokun: pass down HPD_IRQ events
From: Dmitry Baryshkov @ 2026-06-07 21:33 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tomi Valkeinen,
Bjorn Andersson, Konrad Dybcio, Pengyu Luo, Nikita Travkin,
Yongxing Mou, Luca Ceresoli, Francesco Dolcini
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno
In-Reply-To: <20260608-hpd-irq-events-v4-0-30b62b335487@oss.qualcomm.com>
The DisplayPort standard defines a special kind of HPD events called
IRQ_HPD. These events are used to notify DP Source about the events on
the Sink side.
Pass IRQ_HPD events from the EC to the HPD bridge, letting those
to be delivered to the DisplayPort driver.
Reviewed-by: Pengyu Luo <mitltlatltl@gmail.com>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c b/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c
index ca749fde49bd..5e3f887ecbd8 100644
--- a/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c
+++ b/drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c
@@ -299,10 +299,13 @@ static void gaokun_ucsi_handle_altmode(struct gaokun_ucsi_port *port)
/* UCSI callback .connector_status() have set orientation */
if (port->bridge)
- drm_aux_hpd_bridge_notify(&port->bridge->dev,
- port->hpd_state ?
- connector_status_connected :
- connector_status_disconnected);
+ drm_aux_hpd_bridge_notify_extra(&port->bridge->dev,
+ port->hpd_state ?
+ connector_status_connected :
+ connector_status_disconnected,
+ port->hpd_irq ?
+ DRM_CONNECTOR_DP_IRQ_HPD :
+ DRM_CONNECTOR_NO_EXTRA_STATUS);
gaokun_ec_ucsi_pan_ack(uec->ec, port->idx);
}
--
2.47.3
^ permalink raw reply related
* [PATCH v4 7/8] soc: qcom: pmic-glink-altmode: pass down HPD_IRQ events
From: Dmitry Baryshkov @ 2026-06-07 21:33 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tomi Valkeinen,
Bjorn Andersson, Konrad Dybcio, Pengyu Luo, Nikita Travkin,
Yongxing Mou, Luca Ceresoli, Francesco Dolcini
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno,
Konrad Dybcio
In-Reply-To: <20260608-hpd-irq-events-v4-0-30b62b335487@oss.qualcomm.com>
The DisplayPort standard defines a special kind of HPD events called
IRQ_HPD. These events are used to notify DP Source about the events on
the Sink side.
Pass IRQ_HPD events from the firmware to the HPD bridge, letting those
to be delivered to the DisplayPort driver.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Acked-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/soc/qcom/pmic_glink_altmode.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c
index 619bad2c27ee..946eb20b8f83 100644
--- a/drivers/soc/qcom/pmic_glink_altmode.c
+++ b/drivers/soc/qcom/pmic_glink_altmode.c
@@ -373,7 +373,11 @@ static void pmic_glink_altmode_worker(struct work_struct *work)
else
conn_status = connector_status_disconnected;
- drm_aux_hpd_bridge_notify(&alt_port->bridge->dev, conn_status);
+ drm_aux_hpd_bridge_notify_extra(&alt_port->bridge->dev,
+ conn_status,
+ alt_port->hpd_irq ?
+ DRM_CONNECTOR_DP_IRQ_HPD :
+ DRM_CONNECTOR_NO_EXTRA_STATUS);
} else if (alt_port->mux_ctrl == MUX_CTRL_STATE_TUNNELING) {
if (alt_port->svid == USB_TYPEC_TBT_SID)
pmic_glink_altmode_enable_tbt(altmode, alt_port);
--
2.47.3
^ permalink raw reply related
* [PATCH v4 6/8] drm/msm: dp: handle the IRQ_HPD events reported by USB-C
From: Dmitry Baryshkov @ 2026-06-07 21:33 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tomi Valkeinen,
Bjorn Andersson, Konrad Dybcio, Pengyu Luo, Nikita Travkin,
Yongxing Mou, Luca Ceresoli, Francesco Dolcini
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno
In-Reply-To: <20260608-hpd-irq-events-v4-0-30b62b335487@oss.qualcomm.com>
The DisplayPort standard defines a special kind of HPD events called
IRQ_HPD. These events are used to notify DP Source about the events on
the Sink side, for example DP MST events.
Let the MSM DisplayPort driver properly track and handle IRQ_HPD
delivered over the OOB events (e.g. from the USB-C AltMode handler).
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/msm/dp/dp_display.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index c0f6a8ff9b99..743d8fa40dc6 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1533,11 +1533,12 @@ void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
msm_dp_display->connector_type, hpd_link_status, status);
if (status == connector_status_connected) {
- if (hpd_link_status == ISR_HPD_REPLUG_COUNT) {
+ if (hpd_link_status == ISR_IRQ_HPD_PULSE_COUNT ||
+ extra_status == DRM_CONNECTOR_DP_IRQ_HPD) {
+ msm_dp_irq_hpd_handle(dp);
+ } else if (hpd_link_status == ISR_HPD_REPLUG_COUNT) {
msm_dp_hpd_unplug_handle(dp);
msm_dp_hpd_plug_handle(dp);
- } else if (hpd_link_status == ISR_IRQ_HPD_PULSE_COUNT) {
- msm_dp_irq_hpd_handle(dp);
} else {
msm_dp_hpd_plug_handle(dp);
}
--
2.47.3
^ permalink raw reply related
* [PATCH v4 5/8] drm/bridge: pass down IRQ_HPD to the drivers
From: Dmitry Baryshkov @ 2026-06-07 21:33 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tomi Valkeinen,
Bjorn Andersson, Konrad Dybcio, Pengyu Luo, Nikita Travkin,
Yongxing Mou, Luca Ceresoli, Francesco Dolcini
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno
In-Reply-To: <20260608-hpd-irq-events-v4-0-30b62b335487@oss.qualcomm.com>
The DisplayPort standard defines a special kind of HPD events called
IRQ_HPD. These events are used to notify DP Source about the events on
the Sink side. Pass down the extra status to the bridge drivers via the
hpd_notify() callback, letting DP bridges to act accordingly.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 3 ++-
drivers/gpu/drm/display/drm_bridge_connector.c | 2 +-
drivers/gpu/drm/meson/meson_encoder_hdmi.c | 3 ++-
drivers/gpu/drm/msm/dp/dp_display.c | 3 ++-
drivers/gpu/drm/msm/dp/dp_drm.h | 3 ++-
drivers/gpu/drm/omapdrm/dss/hdmi4.c | 3 ++-
include/drm/drm_bridge.h | 3 ++-
7 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
index 9427cc2358ae..8cb17bd0e238 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
@@ -429,7 +429,8 @@ static const struct drm_edid *lt9611uxc_bridge_edid_read(struct drm_bridge *brid
static void lt9611uxc_bridge_hpd_notify(struct drm_bridge *bridge,
struct drm_connector *connector,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ enum drm_connector_status_extra extra_status)
{
const struct drm_edid *drm_edid;
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index a34643d3ddef..8f7075fd2aa5 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -150,7 +150,7 @@ static void drm_bridge_connector_hpd_notify(struct drm_connector *connector,
/* Notify all bridges in the pipeline of hotplug events. */
drm_for_each_bridge_in_chain_scoped(bridge_connector->encoder, bridge) {
if (bridge->funcs->hpd_notify)
- bridge->funcs->hpd_notify(bridge, connector, status);
+ bridge->funcs->hpd_notify(bridge, connector, status, extra_status);
}
}
diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
index 55c0601df3c6..4aecf0ffcf75 100644
--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
@@ -323,7 +323,8 @@ static int meson_encoder_hdmi_atomic_check(struct drm_bridge *bridge,
static void meson_encoder_hdmi_hpd_notify(struct drm_bridge *bridge,
struct drm_connector *connector,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ enum drm_connector_status_extra extra_status)
{
struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index dc6f33809ca5..c0f6a8ff9b99 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1514,7 +1514,8 @@ void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge)
void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
struct drm_connector *connector,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ enum drm_connector_status_extra extra_status)
{
struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(bridge);
struct msm_dp *msm_dp_display = msm_dp_bridge->msm_dp_display;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h
index 041aa026ae2e..4d98e04bb511 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.h
+++ b/drivers/gpu/drm/msm/dp/dp_drm.h
@@ -43,6 +43,7 @@ void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge);
void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge);
void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
struct drm_connector *connector,
- enum drm_connector_status status);
+ enum drm_connector_status status,
+ enum drm_connector_status_extra extra_status);
#endif /* _DP_DRM_H_ */
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index e306247ed8a0..d02d432abde4 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -429,7 +429,8 @@ static void hdmi4_bridge_disable(struct drm_bridge *bridge,
static void hdmi4_bridge_hpd_notify(struct drm_bridge *bridge,
struct drm_connector *connector,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ enum drm_connector_status_extra extra_status)
{
struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 6a5edfda2ddd..9c4c88024cc5 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -615,7 +615,8 @@ struct drm_bridge_funcs {
*/
void (*hpd_notify)(struct drm_bridge *bridge,
struct drm_connector *connector,
- enum drm_connector_status status);
+ enum drm_connector_status status,
+ enum drm_connector_status_extra extra_status);
/**
* @hpd_enable:
--
2.47.3
^ permalink raw reply related
* [PATCH v4 0/8] drm: handle IRQ_HPD events correctly
From: Dmitry Baryshkov @ 2026-06-07 21:33 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tomi Valkeinen,
Bjorn Andersson, Konrad Dybcio, Pengyu Luo, Nikita Travkin,
Yongxing Mou, Luca Ceresoli, Francesco Dolcini
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno,
Konrad Dybcio
Both DisplayPort and HDMI standards define a way for the Sink / display
to notify the Source / host about some kinds of events. In case of HDMI
it's as simple as singnalling changes to the EDID. In case of
DisplayPort it's more complicated and requires actual checking of the
DPCD registers.
Currently USB-C drivers don't have a way to deliver the IRQ_HPD
notifications, leading to missing MST notifications. Provide necessary
plumbing to let IRQ_HPD events be passed to the DisplayPort drivers.
Note: the Yoga C630 UCSI driver and Acer Aspire1 EC driver are not yet
enabled to send the IRQ_HPD events. Both of them would need some more
reverse engineering to find out how the event is being reported by the
EC.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
Changes in v4:
- Renamed drm_connector_oob_hotplug_event() to
drm_connector_dp_oob_status() (Maxime)
- Reworked commit messages, explaining what it is about (Bjorn)
- Rearranged commits, making them a bit more logical.
- Link to v3: https://patch.msgid.link/20260421-hpd-irq-events-v3-0-44d2bf40dfc2@oss.qualcomm.com
Changes in v3:
- Fixed build error if aux bridges are disabled (Intel GFX CI)
- Link to v2: https://patch.msgid.link/20260420-hpd-irq-events-v2-0-402ffe27e9e9@oss.qualcomm.com
Changes in v2:
- Change irq_hpd arg to be an enum, possibly desribing other uses (Toni)
- Account for that, chaning the API accordingly (with_irq -> extra,
etc.)
- Wire up AUX bridge notifications
- Link to v1: https://patch.msgid.link/20260416-hpd-irq-events-v1-0-1ab1f1cfb2b2@oss.qualcomm.com
To: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
To: Maxime Ripard <mripard@kernel.org>
To: Thomas Zimmermann <tzimmermann@suse.de>
To: David Airlie <airlied@gmail.com>
To: Simona Vetter <simona@ffwll.ch>
To: Heikki Krogerus <heikki.krogerus@linux.intel.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: Andrzej Hajda <andrzej.hajda@intel.com>
To: Neil Armstrong <neil.armstrong@linaro.org>
To: Robert Foss <rfoss@kernel.org>
To: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
To: Jonas Karlman <jonas@kwiboo.se>
To: Jernej Skrabec <jernej.skrabec@gmail.com>
To: Luca Ceresoli <luca.ceresoli@bootlin.com>
To: Jani Nikula <jani.nikula@linux.intel.com>
To: Rodrigo Vivi <rodrigo.vivi@intel.com>
To: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
To: Tvrtko Ursulin <tursulin@ursulin.net>
To: Francesco Dolcini <francesco@dolcini.it>
To: Kevin Hilman <khilman@baylibre.com>
To: Jerome Brunet <jbrunet@baylibre.com>
To: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
To: Rob Clark <robin.clark@oss.qualcomm.com>
To: Dmitry Baryshkov <lumag@kernel.org>
To: Abhinav Kumar <abhinav.kumar@linux.dev>
To: Jessica Zhang <jesszhan0024@gmail.com>
To: Sean Paul <sean@poorly.run>
To: Marijn Suijten <marijn.suijten@somainline.org>
To: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
To: Bjorn Andersson <andersson@kernel.org>
To: Konrad Dybcio <konradybcio@kernel.org>
To: Pengyu Luo <mitltlatltl@gmail.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-usb@vger.kernel.org
Cc: intel-gfx@lists.freedesktop.org
Cc: intel-xe@lists.freedesktop.org
Cc: linux-amlogic@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-arm-msm@vger.kernel.org
Cc: freedreno@lists.freedesktop.org
---
Dmitry Baryshkov (8):
drm/connector: report out-of-band IRQ_HPD events
drm/connector: pass down IRQ_HPD to the drivers
drm/bridge: aux-hpd: let drivers pass IRQ_HPD events
drm/bridge: pass extra events to the HPD callback
drm/bridge: pass down IRQ_HPD to the drivers
drm/msm: dp: handle the IRQ_HPD events reported by USB-C
soc: qcom: pmic-glink-altmode: pass down HPD_IRQ events
usb: typec: ucsi: huawei-gaokun: pass down HPD_IRQ events
drivers/gpu/drm/bridge/aux-hpd-bridge.c | 11 +++++----
drivers/gpu/drm/bridge/chrontel-ch7033.c | 3 ++-
drivers/gpu/drm/bridge/lontium-lt8912b.c | 3 ++-
drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 3 ++-
drivers/gpu/drm/bridge/ti-tfp410.c | 3 ++-
drivers/gpu/drm/display/drm_bridge_connector.c | 22 ++++++++++--------
drivers/gpu/drm/drm_bridge.c | 20 ++++++++++-------
drivers/gpu/drm/drm_connector.c | 22 ++++++++++--------
drivers/gpu/drm/i915/display/intel_dp.c | 3 ++-
drivers/gpu/drm/meson/meson_encoder_hdmi.c | 3 ++-
drivers/gpu/drm/msm/dp/dp_display.c | 10 +++++----
drivers/gpu/drm/msm/dp/dp_drm.h | 3 ++-
drivers/gpu/drm/omapdrm/dss/hdmi4.c | 3 ++-
drivers/soc/qcom/pmic_glink_altmode.c | 6 ++++-
drivers/usb/typec/altmodes/displayport.c | 23 ++++++++++++-------
drivers/usb/typec/ucsi/ucsi_huawei_gaokun.c | 11 +++++----
include/drm/bridge/aux-bridge.h | 13 +++++++++--
include/drm/drm_bridge.h | 31 +++++++++++++++++++++-----
include/drm/drm_connector.h | 24 +++++++++++++++++---
19 files changed, 152 insertions(+), 65 deletions(-)
---
base-commit: 6e845bcb78c95af935094040bd4edc3c2b6dd784
change-id: 20260414-hpd-irq-events-e72bc076a5f1
Best regards,
--
With best wishes
Dmitry
^ permalink raw reply
* [PATCH v4 2/8] drm/connector: pass down IRQ_HPD to the drivers
From: Dmitry Baryshkov @ 2026-06-07 21:33 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Heikki Krogerus, Greg Kroah-Hartman, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Adrien Grassein, Jani Nikula, Rodrigo Vivi,
Joonas Lahtinen, Tvrtko Ursulin, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Tomi Valkeinen,
Bjorn Andersson, Konrad Dybcio, Pengyu Luo, Nikita Travkin,
Yongxing Mou, Luca Ceresoli, Francesco Dolcini
Cc: dri-devel, linux-kernel, linux-usb, intel-gfx, intel-xe,
linux-amlogic, linux-arm-kernel, linux-arm-msm, freedreno
In-Reply-To: <20260608-hpd-irq-events-v4-0-30b62b335487@oss.qualcomm.com>
The DisplayPort standard defines a special kind of HPD events called
IRQ_HPD. These events are used to notify DP Source about the events on
the Sink side.
Extend drm_connector_funcs::oob_hotplug_event() to pass the
notifications about the IRQ_HPD events down to the individual drivers,
letting them handle those as required.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/display/drm_bridge_connector.c | 17 ++++++++++-------
drivers/gpu/drm/drm_connector.c | 2 +-
drivers/gpu/drm/i915/display/intel_dp.c | 3 ++-
include/drm/drm_connector.h | 3 ++-
4 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 649969fca141..046efd913064 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -141,7 +141,8 @@ struct drm_bridge_connector {
*/
static void drm_bridge_connector_hpd_notify(struct drm_connector *connector,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ enum drm_connector_status_extra extra_status)
{
struct drm_bridge_connector *bridge_connector =
to_drm_bridge_connector(connector);
@@ -154,7 +155,8 @@ static void drm_bridge_connector_hpd_notify(struct drm_connector *connector,
}
static void drm_bridge_connector_handle_hpd(struct drm_bridge_connector *drm_bridge_connector,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ enum drm_connector_status_extra extra_status)
{
struct drm_connector *connector = &drm_bridge_connector->base;
struct drm_device *dev = connector->dev;
@@ -163,7 +165,7 @@ static void drm_bridge_connector_handle_hpd(struct drm_bridge_connector *drm_bri
connector->status = status;
mutex_unlock(&dev->mode_config.mutex);
- drm_bridge_connector_hpd_notify(connector, status);
+ drm_bridge_connector_hpd_notify(connector, status, extra_status);
drm_kms_helper_connector_hotplug_event(connector);
}
@@ -171,16 +173,17 @@ static void drm_bridge_connector_handle_hpd(struct drm_bridge_connector *drm_bri
static void drm_bridge_connector_hpd_cb(void *cb_data,
enum drm_connector_status status)
{
- drm_bridge_connector_handle_hpd(cb_data, status);
+ drm_bridge_connector_handle_hpd(cb_data, status, DRM_CONNECTOR_NO_EXTRA_STATUS);
}
static void drm_bridge_connector_oob_hotplug_event(struct drm_connector *connector,
- enum drm_connector_status status)
+ enum drm_connector_status status,
+ enum drm_connector_status_extra extra_status)
{
struct drm_bridge_connector *bridge_connector =
to_drm_bridge_connector(connector);
- drm_bridge_connector_handle_hpd(bridge_connector, status);
+ drm_bridge_connector_handle_hpd(bridge_connector, status, extra_status);
}
static void drm_bridge_connector_enable_hpd(struct drm_connector *connector)
@@ -223,7 +226,7 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force)
if (hdmi)
drm_atomic_helper_connector_hdmi_hotplug(connector, status);
- drm_bridge_connector_hpd_notify(connector, status);
+ drm_bridge_connector_hpd_notify(connector, status, DRM_CONNECTOR_NO_EXTRA_STATUS);
} else {
switch (connector->connector_type) {
case DRM_MODE_CONNECTOR_DPI:
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index bb128dd0263a..d99019fdea9c 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -3528,7 +3528,7 @@ void drm_connector_dp_oob_status(struct fwnode_handle *connector_fwnode,
return;
if (connector->funcs->oob_hotplug_event)
- connector->funcs->oob_hotplug_event(connector, status);
+ connector->funcs->oob_hotplug_event(connector, status, extra_status);
drm_connector_put(connector);
}
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 85d3aa3b9894..31acb3129723 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -6990,7 +6990,8 @@ static int intel_dp_connector_atomic_check(struct drm_connector *_connector,
}
static void intel_dp_oob_hotplug_event(struct drm_connector *_connector,
- enum drm_connector_status hpd_state)
+ enum drm_connector_status hpd_state,
+ enum drm_connector_status_extra extra_status)
{
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 105da7c94910..5784bb9c4021 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1720,7 +1720,8 @@ struct drm_connector_funcs {
* has been received from a source outside the display driver / device.
*/
void (*oob_hotplug_event)(struct drm_connector *connector,
- enum drm_connector_status status);
+ enum drm_connector_status status,
+ enum drm_connector_status_extra extra_status);
/**
* @debugfs_init:
--
2.47.3
^ permalink raw reply related
* Re: [RFC PATCH v3 6/9] iommu/rockchip: Clear AUTO_GATING bit 1 on the RK356x v1 IOMMU
From: Midgy Balon @ 2026-06-07 21:05 UTC (permalink / raw)
To: Chaoyi Chen
Cc: Simon Xue, tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, joro,
will, robin.murphy, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, iommu, linux-kernel
In-Reply-To: <e44b506e-e9d2-48e3-acea-ab28b7be9b37@rock-chips.com>
Hi Chaoyi,
> As I said, it is v2. Could you please try using the code below instead and
> see if it works?
> [ auto_gate = read(RK_MMU_AUTO_GATING); auto_gate |= BIT(31); write(...) ]
Thanks -- that's clearly the right shape (read-modify-write, before paging is
enabled, keeping the reset value instead of my clobbering 0x2).
I rebuilt v7.1-rc6 (with the rocket RK3568 series + your per-device-ops work)
using your bit-31 version and tested it on a ROCK 3B: the NPU IOMMU comes up and
services the NPU's DMA cleanly -- the NPU probes, attaches its domain, and runs
repeated conv submissions with no DMA_READ_ERROR and no page-walk stall. No
regression from the write.
To be precise about what I can and can't show: I tested both ways on v7.1-rc6 --
with your bit-31 write, and on the reset value (0x3) -- and the NPU
IOMMU services
the NPU's reads with zero faults in both cases (no DMA_READ_ERROR, no page-walk
stall). So I don't have a failing baseline here that bit-31 visibly
fixes. Is the
AUTO_GATING write needed on current mainline, or only under conditions I'm not
reproducing (a particular traffic pattern / silicon rev)? I'll keep the patch in
your form unless you'd prefer to drop it.
One question so I document it correctly: what does bit 31 of RK_MMU_AUTO_GATING
control on the v2 block -- is it a master "disable internal auto clock-gating"
for the page-table walker (i.e. so a TLB-miss walk's AXI master keeps its clock
to completion)? The RK3568 TRM I have doesn't cover the IOMMU registers, so a
one-line description would let me write an accurate comment.
Kind regards,
Midgy
Le ven. 5 juin 2026 à 03:59, Chaoyi Chen <chaoyi.chen@rock-chips.com> a écrit :
>
> Hello Midgy,
>
> On 6/4/2026 9:52 PM, Midgy BALON wrote:
> > On the RK356x v1 IOMMU, RK_MMU_AUTO_GATING resets to 0x3. Bit 1 enables
> > auto clock-gating of the page-table walker, so the walker's AXI master
> > loses its clock between transactions; a TLB-miss page walk then never
> > completes and the IOMMU is left stuck (PAGING_ENABLED, never IDLE).
> >
> > Clear bit 1 (keeping bit 0, the slave-port gate) once paging is enabled
> > so the walker keeps its clock. This is required for the RK3568 NPU MMU.
> >
> > Signed-off-by: Midgy BALON <midgy971@gmail.com>
> > ---
> > drivers/iommu/rockchip-iommu.c | 12 ++++++++++++
> > 1 file changed, 12 insertions(+)
> >
> > diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
> > index 4da80136933c4..e3d8b6e9ca12b 100644
> > --- a/drivers/iommu/rockchip-iommu.c
> > +++ b/drivers/iommu/rockchip-iommu.c
> > @@ -953,6 +953,18 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
> >
> > ret = rk_iommu_enable_paging(iommu);
> >
> > + if (!ret) {
> > + /*
> > + * RK356x v1 IOMMU: RK_MMU_AUTO_GATING bit 1 enables page-walker
> > + * auto clock-gating; the walker's AXI master then loses its clock
> > + * between transactions and a TLB-miss page walk never completes,
> > + * leaving the IOMMU stuck (PAGING_ENABLED, never IDLE). Clear
> > + * bit 1 (keep bit 0, the slave-port gate) once paging is enabled.
> > + */
> > + for (i = 0; i < iommu->num_mmu; i++)
> > + rk_iommu_write(iommu->bases[i], RK_MMU_AUTO_GATING, 0x2);
> > + }
> > +
> > out_disable_stall:
> > rk_iommu_disable_stall(iommu);
> > out_disable_clocks:
>
> As I said, it is v2. Could you please try using the code below
> instead and see if it works? Thank you.
>
> diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
> index 0013cf196c57..89e3a83a0251 100644
> --- a/drivers/iommu/rockchip-iommu.c
> +++ b/drivers/iommu/rockchip-iommu.c
> @@ -930,6 +930,7 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
> struct iommu_domain *domain = iommu->domain;
> struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
> int ret, i;
> + u32 auto_gate;
>
> ret = clk_bulk_enable(iommu->num_clocks, iommu->clocks);
> if (ret)
> @@ -948,6 +949,10 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
> rk_ops->mk_dtentries(rk_domain->dt_dma));
> rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
> rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK);
> +
> + auto_gate = rk_iommu_read(iommu->bases[i], RK_MMU_AUTO_GATING);
> + auto_gate |= BIT(31);
> + rk_iommu_write(iommu->bases[i], RK_MMU_AUTO_GATING, auto_gate);
> }
>
> ret = rk_iommu_enable_paging(iommu);
>
> --
> Best,
> Chaoyi
^ permalink raw reply
* Re: [RFC PATCH v3 0/9] accel: rocket: Add RK3568 NPU support
From: Midgy Balon @ 2026-06-07 21:03 UTC (permalink / raw)
To: Chaoyi Chen
Cc: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, joro, will,
robin.murphy, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, iommu, linux-kernel
In-Reply-To: <3d99569e-9c3a-49d1-93fb-1335382523e9@rock-chips.com>
Hi Chaoyi,
Thanks a lot for looking at this -- input from Rockchip is exactly what this
series needs.
> Hmmm. If I understand correctly, the NPU IOMMU should be v2 rather than v1,
> implying it should support 40-bit PAs. Nevertheless, please note that the
> upper limit for DTE is 32 bits.
Understood, and that 32-bit-DTE note is the crux of the trouble I had, so let
me lay out what I see and ask how you'd prefer to solve it.
The mainline node is already v2 (rockchip,rk3568-iommu in rk356x-base.dtsi).
The problem on this 8 GiB board: with the v2 ops the page-table allocations
(gfp_flags == 0) can land above 4 GiB, so the DTE ends up > 32 bits and the
NPU's first translation faults with DMA_READ_ERROR. To work around that I had
switched the NPU MMU to the v1 compatible (rockchip,iommu), whose ops set
GFP_DMA32 and keep the DTE sub-4 GiB. That works in isolation, but because the
driver keeps a single global rk_ops, a v1 NPU MMU then trips
WARN_ON(rk_ops != ops) against the SoC's v2 instances (VOP/VDEC), which is why
I based the series on Simon's per-device-ops work.
So my question: with per-device ops in place, what's the intended way to keep
the NPU MMU on v2 *and* cap its DTE at 32 bits on boards with >4 GiB of RAM?
A v2 ops variant carrying GFP_DMA32 for this device, or is there a register/
config bit that constrains the DTE address? I'd rather follow the Rockchip
intent here than carry the v1 workaround. (Simon, cc'd -- this is right next to
your per-device-ops series.)
> Can these operations not be completed via the pmdomain driver?
> If some operations are controlled by TF-A, are you using open source TF-A?
Most of it is in pmdomain already. Power-on and NoC de-idle are done by the
RK3568 NPU power domain (genpd) at power-on -- the driver no longer pokes the
PMU directly. Two things remain outside it:
- vdd_npu: I mark it regulator-always-on in DT rather than wiring it as the
domain's domain-supply, because as a domain-supply it created a device-link
to the I2C PMIC (rk809) and genpd's power-off QoS-save path then hung
reading the NPU QoS registers behind the (gated) NoC. If there's a clean way
to let genpd own vdd_npu without that I2C ordering deadlock I'd much prefer
that -- pointers welcome.
- the NPU compute clock (PVTPLL): set from the driver via SCMI, and only
needed for actual compute, not for bring-up.
One more pmdomain observation from testing, possibly relevant to how the NPU
domain should be modelled: the domain's power-off/on cycle doesn't reliably
re-de-idle the NoC. If the NPU is probed after genpd has already powered the
(unused) domain off, the power-on de-idle fails ("failed to set idle on domain
'npu'") and the NPU IOMMU then takes an external abort on its first MMIO access.
Probing the NPU before the unused-domain power-off, or marking the domain
always-on, both avoid it. Is the NoC de-idle expected to work on a genpd
re-power here, or should this domain effectively stay on?
On TF-A: yes -- bl31 is built from upstream arm-trusted-firmware
(github.com/ARM-software/arm-trusted-firmware, RK3568 platform), providing PSCI
and the SCMI clock service. The only closed blob in the boot chain is Rockchip's
DDR init (rkbin), which is the standard situation for mainline RK356x.
Kind regards,
Midgy
Le ven. 5 juin 2026 à 03:36, Chaoyi Chen <chaoyi.chen@rock-chips.com> a écrit :
>
> Hello Midgy,
>
> On 6/4/2026 9:52 PM, Midgy BALON wrote:
> > RFC, not for merge. End-to-end inference does not produce correct output
> > yet (see Status), so per the v2 discussion this is a request for design
> > feedback. It now probes, attaches, and submits cleanly on a stock
> > v7.1-rc6 tree; what remains is one hardware-internal issue.
> >
> > The RK3568 has a single NVDLA-derived NPU core, the same IP family as the
> > RK3588 NPU the driver already supports; the register layout matches. The
> > RK3568 differences are a 32-bit NPU AXI/IOMMU (vs 40-bit) and explicit
> > PVTPLL/PMU bring-up to power and de-idle the NPU before it is reachable.
> >
> > Patches:
> > 1-2 rocket: per-SoC data struct, then derive DMA width and core count
> > from match data (refactors, no functional change).
> > 3 rocket: RK3568 SoC data + PVTPLL/PMU/NOC bring-up.
> > 4 rocket: reset the NPU before detaching the IOMMU on a job timeout
> > (the detach otherwise stalls a wedged AXI master and WARNs).
> > 5 rocket: keep the IOMMU domain attached across jobs instead of
> > re-attaching per job (the per-job rk_iommu handshake on the idle
> > NPU MMU is slow and noisy).
> > 6 iommu/rockchip: clear AUTO_GATING bit 1 on the RK356x v1 IOMMU so
> > the page-walker keeps its clock (else a TLB-miss walk never
> > completes).
> > 7 dt-bindings: add the RK3568 NPU compatible.
> > 8-9 arm64 dts: add the NPU and its IOMMU, and enable them on ROCK 3B.
> >
> > Dependency. The NPU MMU is rockchip-iommu v1 (32-bit) while the rest of
> > the RK3568 uses v2 (40-bit). They cannot coexist until the driver carries
> > per-device ops; this series is developed on top of Simon Xue's
> > "iommu/rockchip: Drop global rk_ops in favor of per-device ops" [1].
> > Without it the NPU IOMMU fails to probe on a full RK3568 boot.
> >
>
> Hmmm. If I understand correctly, the NPU IOMMU should be v2 rather than
> v1, implying it should support 40-bit PAs. Nevertheless, please note that
> the upper limit for DTE is 32 bits.
>
> > Power bring-up. The NPU is brought up through the power-domain layer (no
> > driver hack): the NPU power-domain keeps its clocks but drops the pm_qos
> > phandle (qos_npu sits behind the gated NPU NoC, so genpd's power-off QoS
> > save faults reading it), and vdd_npu is marked always-on so the rail is
> > up before genpd de-idles the NoC at power-on. The PMU de-idle then ACKs
> > without PVTPLL running; PVTPLL is only needed for compute.
> >
>
> Can these operations not be completed via the pmdomain driver?
> If some operations are controlled by TF-A, are you using open
> source TF-A? Thank you.
>
> > Status. On v7.1-rc6 the driver probes, creates /dev/accel/accel0,
> > attaches an IOMMU domain, and submits jobs; the program controller
> > fetches and broadcasts the command list. Inference output is still wrong,
> > and the cause is split across three layers:
> > - kernel (this series): the RK3568 differences appear handled;
> > - mesa/Teflon userspace: still emits RK3588-tuned config, wrong for
> > RK3568 (to be filed separately on mesa-dev);
> > - hardware: with corrected config the NPU's DMA reads the full input
> > and weight tensors (confirmed via its DMA bandwidth counters), but
> > the MAC/output stage never completes, the job times out, and the
> > output stays at the buffer's zero-point. I have not found the missing
> > step; it is not in the command list (replaying the vendor's
> > byte-exact command list behaves the same). Pointers welcome,
> > especially from anyone with RK3568 NPU experience.
> >
> > Known residual. On the first IOMMU attach the NPU MMU is idle with paging
> > already enabled; the rk_iommu stall/reset handshake does not complete in
> > that state and logs one burst of timeouts before the (kept) domain
> > settles. It is harmless here because the job times out regardless, but it
> > points at an idle-MMU reconfiguration corner the rk_iommu code does not
> > handle on this block.
> >
> > [1] https://lore.kernel.org/linux-rockchip/20260310105303.128859-1-xxm@rock-chips.com/
> >
> > Changes since v2:
> > - Tagged RFC; now tested on a stock v7.1-rc6 tree.
> > - Bring-up moved into the power-domain/DT layer (no initcall hack).
> > - Added the IOMMU detach-on-timeout and attach-once driver fixes.
> > - Split the driver patch (Heiko): soc_data / match-data / RK3568.
> > - Derive DMA width and core count from match data; drop the DT rescans.
> > - Binding describes the hardware; added the missing $ref on rockchip,pmu.
> > - Disclosed the per-device-ops IOMMU dependency.
> >
> > Midgy BALON (9):
> > accel: rocket: Introduce per-SoC rocket_soc_data
> > accel: rocket: Derive DMA width and core count from match data
> > accel: rocket: Add RK3568 SoC support
> > accel: rocket: Reset the NPU before detaching the IOMMU on timeout
> > accel: rocket: Keep the IOMMU domain attached across jobs
> > iommu/rockchip: Clear AUTO_GATING bit 1 on the RK356x v1 IOMMU
> > dt-bindings: npu: rockchip,rk3588-rknn-core: Add RK3568
> > arm64: dts: rockchip: rk356x: Add the NPU and its IOMMU
> > arm64: dts: rockchip: rk3568-rock-3b: Enable the NPU
> >
> > .../npu/rockchip,rk3588-rknn-core.yaml | 18 ++++-
> > .../boot/dts/rockchip/rk3568-rock-3b.dts | 14 +++-
> > arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 38 +++++++++++
> > drivers/accel/rocket/rocket_core.c | 22 ++++++-
> > drivers/accel/rocket/rocket_core.h | 19 ++++++
> > drivers/accel/rocket/rocket_device.c | 15 ++---
> > drivers/accel/rocket/rocket_device.h | 3 +-
> > drivers/accel/rocket/rocket_drv.c | 66 ++++++++++++++++++-
> > drivers/accel/rocket/rocket_job.c | 35 ++++++++--
> > drivers/iommu/rockchip-iommu.c | 12 ++++
> > 10 files changed, 219 insertions(+), 23 deletions(-)
> >
> >
> > base-commit: 52c800fdcf11888ebeb50c3d707f782cc15b66eb
>
> --
> Best,
> Chaoyi
^ permalink raw reply
* [PATCH v4 1/1] crypto: atmel-ecc - fix multi-device use-after-free and registration races
From: Lothar Rubusch @ 2026-06-07 20:02 UTC (permalink / raw)
To: thorsten.blum, herbert, davem, nicolas.ferre, alexandre.belloni,
claudiu.beznea, tudor.ambarus, krzk+dt
Cc: linux-crypto, linux-arm-kernel, linux-kernel, l.rubusch
During parallel driver initialization or driver teardown sequences
in setups with multiple atmel-ecc instances, a race condition exists
between atmel_ecc_i2c_client_alloc() and the probe/remove paths.
A concurrent transformation request can fetch an i2c_client instance
from the global i2c_client_list before the kpp is fully registered, or
while it is actively being unbound, resulting in a use-after-free (UAF)
risk.
1. The initialization problem in probe(): Adding first an i2c client to the
i2c_client_list, and then registering the kpp algorim may result in a race,
when this happens for a second (or further) probed device. In this case the
algorithm is already registered, so a TFM may arrive, while the latest
probing device is added to the list, but not kpp registered. In case this
fails and this last device is going to be removed again from the list, this
leaves a window where the TFM might obtain a pointer to the - now deleted -
i2c client, which opens a UAF risk. Furthermore, there will happen atempts
to multiple registering the same driver to the same type of algorithm.
Note, a simple reverting of the order: first register kpp, second add the
i2c client to the i2c_client_list - is not possible here, since the kpp
registration immediately triggers the self tests, which then will allocate
and require an i2c client.
2. The critical race condition problem: It exists when an Atmel device
instance is rapidly removed and immediately re-probed, before the global
resources are fully cleaned up. In this scenario, the asynchronous
unregistration sequence in the remove() lags behind the incoming probe()
function. Because of the global algorithm structure being not yet
completely cleaned up, the newly re-probed device incorrectly intercepts
the static, partially-dismantled global context. It then overwrites active
pointers and re-acquires the global instance prematurely. In this way, when
the deregistration sequence finally completes its execution, under the
newly initialized device, it may lose the tracking references, leaking the
older driver memory blocks, and introducing an immediate UAF risk.
3. The removal race problem, when a call to remove() starts removing the
device, but another thread executing a TFM, a severe Time-of-Check to
Time-of-Use (TOCTOU) race condition exists in the teardown path between the
asynchronous remove() sequence and completing TFMs. When the device is
unbound, the remove() function evaluates the active tfm_count and decides
whether to wait or proceed with resource deallocation. However, if the
final active TFM finishes its crypto operation and invokes the client free
function immediately after remove() performs its reference check but before
it can sleep, the completion signal is fired into a clearing state. The
unbind thread then misinterprets the zeroed counter, skips the
synchronization barrier entirely, and instantly deallocates the per-device
private structures. This leaves the final TFM worker thread executing code
inside a completely freed memory area, triggering an immediate UAF kernel
panic. Note, simply calling the kpp unregister here won't clean up the
situation in the context of having a setup with external hardware on a slow
bus.
Address this by implementing an independent subsystem reference counter
kpp refcnt protected by a dedicated mutex to ensure the static global kpp
algorithm structure is registered exactly once by the first probing device
instance. In multi-device scenarios, or when extending the resource
management support of the i2c_client_list to all atmel-i2c based device
drivers, such scenarios can become realistic. The particular algorithm is
registered only once. Each i2c client (i.e. each probing device driver) is
added as client to the i2c_client_list. This guarantee that only the first
probe will register the algorithm. The list is populated for further calls
to probe, and subsequent calls to the client alloc function.
Concurrently, decouple list mutations from registration by moving the
global list eviction to the absolute top of the remove lifecycle. This
keeps the quick execution of the list allocation loop intact, ensures that
unbinding hardware is instantly blind to the rest of the system, and
completely bypasses the recursive deadlock condition previously triggered
by synchronous crypto API self-tests.
Fixes: 11105693fa05 ("crypto: atmel-ecc - introduce Microchip / Atmel ECC driver")
Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
drivers/crypto/atmel-ecc.c | 130 +++++++++++++++++++++++++++++--------
drivers/crypto/atmel-i2c.h | 3 +
2 files changed, 106 insertions(+), 27 deletions(-)
diff --git a/drivers/crypto/atmel-ecc.c b/drivers/crypto/atmel-ecc.c
index 0ca02995a1de..7336c3661e52 100644
--- a/drivers/crypto/atmel-ecc.c
+++ b/drivers/crypto/atmel-ecc.c
@@ -23,6 +23,11 @@
#include <crypto/kpp.h>
#include "atmel-i2c.h"
+static DEFINE_MUTEX(atmel_ecc_kpp_lock);
+static int atmel_ecc_kpp_refcnt;
+DECLARE_COMPLETION(atmel_ecc_unreg_done);
+static bool atmel_ecc_unreg_active;
+
static struct atmel_ecc_driver_data driver_data;
/**
@@ -241,7 +246,10 @@ static void atmel_ecc_i2c_client_free(struct i2c_client *client)
{
struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client);
- atomic_dec(&i2c_priv->tfm_count);
+ spin_lock(&driver_data.i2c_list_lock);
+ if (atomic_dec_and_test(&i2c_priv->tfm_count) && i2c_priv->unbinding)
+ complete(&i2c_priv->remove_done);
+ spin_unlock(&driver_data.i2c_list_lock);
}
static int atmel_ecdh_init_tfm(struct crypto_kpp *tfm)
@@ -276,7 +284,8 @@ static void atmel_ecdh_exit_tfm(struct crypto_kpp *tfm)
struct atmel_ecdh_ctx *ctx = kpp_tfm_ctx(tfm);
kfree(ctx->public_key);
- crypto_free_kpp(ctx->fallback);
+ if (ctx->fallback)
+ crypto_free_kpp(ctx->fallback);
atmel_ecc_i2c_client_free(ctx->client);
}
@@ -295,6 +304,28 @@ static unsigned int atmel_ecdh_max_size(struct crypto_kpp *tfm)
return ATMEL_ECC_PUBKEY_SIZE;
}
+static int atmel_ecc_wait_for_tfms(struct atmel_i2c_client_priv *i2c_priv)
+{
+ unsigned long timeout;
+
+ spin_lock(&driver_data.i2c_list_lock);
+ list_del(&i2c_priv->i2c_client_list_node);
+ i2c_priv->unbinding = true;
+ reinit_completion(&i2c_priv->remove_done);
+ if (!atomic_read(&i2c_priv->tfm_count)) {
+ spin_unlock(&driver_data.i2c_list_lock);
+ return 0;
+ }
+ spin_unlock(&driver_data.i2c_list_lock);
+
+ timeout = wait_for_completion_timeout(&i2c_priv->remove_done,
+ msecs_to_jiffies(2000));
+ if (!timeout)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
static struct kpp_alg atmel_ecdh_nist_p256 = {
.set_secret = atmel_ecdh_set_secret,
.generate_public_key = atmel_ecdh_generate_public_key,
@@ -315,6 +346,7 @@ static struct kpp_alg atmel_ecdh_nist_p256 = {
static int atmel_ecc_probe(struct i2c_client *client)
{
struct atmel_i2c_client_priv *i2c_priv;
+ unsigned long timeout;
int ret;
ret = atmel_i2c_probe(client);
@@ -323,49 +355,93 @@ static int atmel_ecc_probe(struct i2c_client *client)
i2c_priv = i2c_get_clientdata(client);
+ init_completion(&i2c_priv->remove_done);
+ i2c_priv->unbinding = false;
+
spin_lock(&driver_data.i2c_list_lock);
list_add_tail(&i2c_priv->i2c_client_list_node,
&driver_data.i2c_client_list);
spin_unlock(&driver_data.i2c_list_lock);
- ret = crypto_register_kpp(&atmel_ecdh_nist_p256);
- if (ret) {
- spin_lock(&driver_data.i2c_list_lock);
- list_del(&i2c_priv->i2c_client_list_node);
- spin_unlock(&driver_data.i2c_list_lock);
+ mutex_lock(&atmel_ecc_kpp_lock);
+ /*
+ * For cases where the same/last such device is still in unregistering,
+ * and now re-registering (refcnt is 0, but completion still exists).
+ * Safely capture the pointer, drop the lock and sleep until it
+ * terminates upon completion or retry limit reached.
+ */
+ while (atmel_ecc_unreg_active) {
+ mutex_unlock(&atmel_ecc_kpp_lock);
+ timeout = wait_for_completion_timeout(&atmel_ecc_unreg_done,
+ msecs_to_jiffies(2000));
+ mutex_lock(&atmel_ecc_kpp_lock);
+ if (timeout == 0) {
+ mutex_unlock(&atmel_ecc_kpp_lock);
+
+ ret = atmel_ecc_wait_for_tfms(i2c_priv);
+ if (ret)
+ dev_err(&client->dev,
+ "probe timed out, former instance active\n");
+ return -ETIMEDOUT;
+ }
+ }
+ if (atmel_ecc_kpp_refcnt == 0) {
+ ret = crypto_register_kpp(&atmel_ecdh_nist_p256);
+ if (ret) {
+ mutex_unlock(&atmel_ecc_kpp_lock);
- dev_err(&client->dev, "%s alg registration failed\n",
- atmel_ecdh_nist_p256.base.cra_driver_name);
- } else {
- dev_info(&client->dev, "atmel ecc algorithms registered in /proc/crypto\n");
+ atmel_ecc_wait_for_tfms(i2c_priv);
+ dev_err(&client->dev,
+ "%s alg registration failed\n",
+ atmel_ecdh_nist_p256.base.cra_driver_name);
+
+ return ret;
+ }
}
+ atmel_ecc_kpp_refcnt++;
+ mutex_unlock(&atmel_ecc_kpp_lock);
+ dev_info(&client->dev, "atmel ecc algorithms registered in /proc/crypto\n");
return ret;
}
static void atmel_ecc_remove(struct i2c_client *client)
{
struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client);
-
- /* Return EBUSY if i2c client already allocated. */
- if (atomic_read(&i2c_priv->tfm_count)) {
- /*
- * After we return here, the memory backing the device is freed.
- * That happens no matter what the return value of this function
- * is because in the Linux device model there is no error
- * handling for unbinding a driver.
- * If there is still some action pending, it probably involves
- * accessing the freed memory.
- */
- dev_emerg(&client->dev, "Device is busy, expect memory corruption.\n");
- return;
- }
-
- crypto_unregister_kpp(&atmel_ecdh_nist_p256);
+ bool trigger_unreg = false;
+ bool wait_needed = false;
+ unsigned long timeout;
spin_lock(&driver_data.i2c_list_lock);
list_del(&i2c_priv->i2c_client_list_node);
+ i2c_priv->unbinding = true;
+ reinit_completion(&i2c_priv->remove_done);
+ if (atomic_read(&i2c_priv->tfm_count) > 0)
+ wait_needed = true;
spin_unlock(&driver_data.i2c_list_lock);
+ if (wait_needed) {
+ timeout = wait_for_completion_timeout(&i2c_priv->remove_done,
+ msecs_to_jiffies(5000));
+ if (timeout == 0)
+ dev_emerg(&client->dev, "Teardown timed out! Active TFMs leaked, memory corruption imminent.\n");
+ }
+
+ mutex_lock(&atmel_ecc_kpp_lock);
+ atmel_ecc_kpp_refcnt--;
+ if (atmel_ecc_kpp_refcnt == 0) {
+ trigger_unreg = true;
+ atmel_ecc_unreg_active = true;
+ reinit_completion(&atmel_ecc_unreg_done);
+ }
+ mutex_unlock(&atmel_ecc_kpp_lock);
+
+ if (trigger_unreg) {
+ crypto_unregister_kpp(&atmel_ecdh_nist_p256);
+ mutex_lock(&atmel_ecc_kpp_lock);
+ atmel_ecc_unreg_active = false;
+ complete_all(&atmel_ecc_unreg_done);
+ mutex_unlock(&atmel_ecc_kpp_lock);
+ }
}
static const struct of_device_id atmel_ecc_dt_ids[] = {
diff --git a/drivers/crypto/atmel-i2c.h b/drivers/crypto/atmel-i2c.h
index 72f04c15682f..8e6617422191 100644
--- a/drivers/crypto/atmel-i2c.h
+++ b/drivers/crypto/atmel-i2c.h
@@ -129,6 +129,7 @@ struct atmel_ecc_driver_data {
* @wake_token_sz : size in bytes of the wake_token
* @tfm_count : number of active crypto transformations on i2c client
* @hwrng : hold the hardware generated rng
+ * @unbinding : unbinding handshake
*
* Reads and writes from/to the i2c client are sequential. The first byte
* transmitted to the device is treated as the byte size. Any attempt to send
@@ -145,6 +146,8 @@ struct atmel_i2c_client_priv {
size_t wake_token_sz;
atomic_t tfm_count ____cacheline_aligned;
struct hwrng hwrng;
+ struct completion remove_done;
+ bool unbinding;
};
/**
base-commit: 79bbe453e5bfa6e1c6aa2e8329bfc8f152b81c9b
--
2.53.0
^ permalink raw reply related
* Re: [PATCH bpf-next] arm64: mm: Complete the PTE store in ptep_try_set()
From: Catalin Marinas @ 2026-06-07 20:31 UTC (permalink / raw)
To: Tejun Heo
Cc: bot+bpf-ci, Will Deacon, Alexei Starovoitov, david, arighi,
memxor, akpm, rppt, andrii, daniel, martin.lau, martin.lau,
eddyz87, yonghong.song, emil, void, changwoo, clm, ihor.solodrai,
linux-arm-kernel, linux-mm, bpf, linux-kernel
In-Reply-To: <1780862659.ccb18e27e916dc4b@kernel.org>
On Sun, Jun 07, 2026 at 10:04:19AM -1000, Tejun Heo wrote:
> > Can this path actually loop, or is the deferred barrier guaranteed to be
> > flushed before the faulting instruction is retried?
>
> I don't know the arm64 paths well enough to say. What I can see is that
> ptep_try_set() only runs as an apply_to_page_range() callback, and
> apply_to_pte_range() brackets it with lazy_mmu_mode_enable()/disable(), with
> the disable() flushing TIF_LAZY_MMU_PENDING before returning. The barriers
> would land before the access is retried. It also looks like the same
> queue_pte_barriers() path __set_pte() already uses. I'd defer to Catalin and
> the arm64 folks on whether that actually closes the case.
I don't fully understand the BPF parts but I think the bots have a
point. If a BPF kprobe fires while we are in lazy mmu mode,
__set_pte_complete() will defer issuing the barriers.
I think better to just call emit_pte_barriers() directly. If
ptep_try_set() is always called with valid kernel ptes, we can skip the
if (pte_valid_not_user()) check as well (which was just an optimisation
anyway).
--
Catalin
^ permalink raw reply
* Re: [PATCH v7 10/11] iommu/arm-smmu-v3: Invoke pm_runtime before hw access
From: Daniel Mentz @ 2026-06-07 20:17 UTC (permalink / raw)
To: Pranjal Shrivastava
Cc: Nicolin Chen, iommu, Will Deacon, Joerg Roedel, Robin Murphy,
Jason Gunthorpe, Mostafa Saleh, Ashish Mhetre, linux-arm-kernel
In-Reply-To: <aiEm0yuNtG3PGJ4D@google.com>
On Thu, Jun 4, 2026 at 12:18 AM Pranjal Shrivastava <praan@google.com> wrote:
>
> On Wed, Jun 03, 2026 at 03:18:32PM -0700, Daniel Mentz wrote:
> > On Thu, May 28, 2026 at 2:46 PM Pranjal Shrivastava <praan@google.com> wrote:
> > >
> > > On Thu, May 28, 2026 at 01:28:15PM -0700, Nicolin Chen wrote:
> > > > On Wed, May 27, 2026 at 10:14:06PM +0000, Pranjal Shrivastava wrote:
> > > > > TLB and CFG invalidations are
> > > > > elided if the SMMU is suspended by observing the CMDQ_PROD_STOP_FLAG via
> > > > > the arm_smmu_can_elide() helper.
> > > >
> > > > All the arm_smmu_can_elide() call sites here would eventually elide
> > > > the commands in arm_smmu_cmdq_issue_cmdlist() that is already gated
> > > > by CMDQ_PROD_STOP_FLAG? It doesn't seem necessary to gate again?
> > >
> > > While issue_cmdlist() would eventually elide these commands, the
> > > can_elide() check is necessary to return early during suspension.
> > >
> > > This avoids unnecessary stack allocation, cmd building, and spinlock
> > > contention on the cmdq->lock for threads that are anyway about to be
> > > elided.
> > >
> > > By dropping these requests immediately, we significantly reduce cacheline
> > > bouncing and contention during unmap storms. Furthermore, the early check
> > > also allows us to specifically trigger the WARN_ON_ONCE() for broken
> > > devlinks.
> >
> > Hi Pranjal,
> >
> > Have you observed unmap storms in a real-world use case, or is this a
> > preemptive optimization? I would not expect a high rate of map/unmap
> > operations while the SMMU is suspended. If a client device calls
> > iommu_map/iommu_unmap (directly or indirectly), it suggests the client
> > device is RPM_ACTIVE, meaning the SMMU should be active as well.
> >
> > I am in favor of removing arm_smmu_can_elide().
>
> I saw some with DMA_FQ (fq_timer does batched async invalidations) but
> the early ellision doesn't really help with perf which I agreed to in my
> reply to Nicolin as well.
>
> The early checks were dropped in v8 (except for invs_array and for the
> WARN_ON in inv_master).
Hi Pranjal,
Please correct me if I'm wrong, but in v8, I can see a call to
arm_smmu_cmdq_can_elide() at the very beginning of
arm_smmu_domain_inv_range(). Isn't this the path every iommu_unmap
goes through?
^ permalink raw reply
* Re: [PATCH bpf-next] arm64: mm: Complete the PTE store in ptep_try_set()
From: Tejun Heo @ 2026-06-07 20:04 UTC (permalink / raw)
To: bot+bpf-ci, Catalin Marinas, Will Deacon, Alexei Starovoitov
Cc: david, arighi, memxor, akpm, rppt, andrii, daniel, martin.lau,
martin.lau, eddyz87, yonghong.song, emil, void, changwoo, clm,
ihor.solodrai, linux-arm-kernel, linux-mm, bpf, linux-kernel
In-Reply-To: <5f68f44310d4878185fd5ebc52d66530b99f174c6d04ab1170dc53cefaa54568@mail.kernel.org>
> Can this path actually loop, or is the deferred barrier guaranteed to be
> flushed before the faulting instruction is retried?
I don't know the arm64 paths well enough to say. What I can see is that
ptep_try_set() only runs as an apply_to_page_range() callback, and
apply_to_pte_range() brackets it with lazy_mmu_mode_enable()/disable(), with
the disable() flushing TIF_LAZY_MMU_PENDING before returning. The barriers
would land before the access is retried. It also looks like the same
queue_pte_barriers() path __set_pte() already uses. I'd defer to Catalin and
the arm64 folks on whether that actually closes the case.
Thanks.
--
tejun
^ permalink raw reply
* Re: [PATCH net-next v2] net: airoha: add ethtool priv_flags support for LAN/WAN and GDM2 loopback
From: Andrew Lunn @ 2026-06-07 18:48 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, linux-arm-kernel, linux-mediatek, netdev,
Madhur Agrawal
In-Reply-To: <aiWzaV1f1Fpc2rhJ@lore-desk>
On Sun, Jun 07, 2026 at 08:07:37PM +0200, Lorenzo Bianconi wrote:
> > > When a GDM3/GDM4 port is set to WAN mode, enable GDM2 loopback to
> > > support hardware QoS. Conversely, when switching back to LAN mode,
> > > disable the GDM2 loopback and restore the default forwarding
> > > configuration.
> >
> > Why not just use the presence of an off loadable qdisc as the
> > indicator to change mode?
>
> Hi Andrew,
>
> Interesting, can you please provide more details about you mean?
You say you need it to be in loopback mode in order to support
hardware QoS. You configure QoS by using a qdisc, and something like
mqprio, tcf etc. So when the user configures QoS, you can see if the
hardware supports the request QoS. If so, swap to loopback mode and
offload the QoS function to the hardware. If the hardware does not
support the requested QoS, leave it in software and keep with LAN
mode.
Andrew
^ permalink raw reply
* Re: [PATCH] dmaengine: qcom: hidma: use sysfs_emit() in sysfs show callbacks
From: Dmitry Baryshkov @ 2026-06-07 18:30 UTC (permalink / raw)
To: Hungyu Lin
Cc: okaya, vkoul, Frank.Li, linux-arm-kernel, linux-arm-msm,
dmaengine, linux-kernel
In-Reply-To: <20260607163119.78717-1-dennylin0707@gmail.com>
On Sun, Jun 07, 2026 at 04:31:19PM +0000, Hungyu Lin wrote:
> Replace sprintf() and strlen() patterns in sysfs show callbacks
> with sysfs_emit().
>
> sysfs_emit() is the preferred helper for formatting sysfs output
> and simplifies the implementation.
>
> Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
> ---
> drivers/dma/qcom/hidma.c | 6 ++----
> drivers/dma/qcom/hidma_mgmt_sys.c | 19 ++++++++-----------
> 2 files changed, 10 insertions(+), 15 deletions(-)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH net-next v2] net: airoha: add ethtool priv_flags support for LAN/WAN and GDM2 loopback
From: Lorenzo Bianconi @ 2026-06-07 18:07 UTC (permalink / raw)
To: Andrew Lunn
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, linux-arm-kernel, linux-mediatek, netdev,
Madhur Agrawal
In-Reply-To: <33c3a87d-ad97-4f6a-8f76-ebab80c496ac@lunn.ch>
[-- Attachment #1: Type: text/plain, Size: 449 bytes --]
> > When a GDM3/GDM4 port is set to WAN mode, enable GDM2 loopback to
> > support hardware QoS. Conversely, when switching back to LAN mode,
> > disable the GDM2 loopback and restore the default forwarding
> > configuration.
>
> Why not just use the presence of an off loadable qdisc as the
> indicator to change mode?
Hi Andrew,
Interesting, can you please provide more details about you mean?
Regards,
Lorenzo
>
> Andrew
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH net-next v2] net: airoha: add ethtool priv_flags support for LAN/WAN and GDM2 loopback
From: Andrew Lunn @ 2026-06-07 17:59 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, linux-arm-kernel, linux-mediatek, netdev,
Madhur Agrawal
In-Reply-To: <20260607-airoha-ethtool-priv_flags-v2-1-742c7aa1e182@kernel.org>
> When a GDM3/GDM4 port is set to WAN mode, enable GDM2 loopback to
> support hardware QoS. Conversely, when switching back to LAN mode,
> disable the GDM2 loopback and restore the default forwarding
> configuration.
Why not just use the presence of an off loadable qdisc as the
indicator to change mode?
Andrew
^ permalink raw reply
* Re: [PATCH] KVM: arm64: nv: Skip vCPUs without a pseudo-TLB in invalidate_vncr_va()
From: Marc Zyngier @ 2026-06-07 18:00 UTC (permalink / raw)
To: Hyunwoo Kim
Cc: oupton, joey.gouly, seiden, suzuki.poulose, yuzenghui,
catalin.marinas, will, linux-arm-kernel, kvmarm
In-Reply-To: <aiVz7O_FIpY2k2bV@v4bel>
On Sun, 07 Jun 2026 14:36:44 +0100,
Hyunwoo Kim <imv4bel@gmail.com> wrote:
>
> On Sun, Jun 07, 2026 at 02:05:02PM +0100, Marc Zyngier wrote:
> > On Sun, 07 Jun 2026 09:43:53 +0100,
> > Hyunwoo Kim <imv4bel@gmail.com> wrote:
> > >
> > > vncr_tlb is not allocated before a vCPU runs for the first time, so
> > > vcpu->arch.vncr_tlb is NULL for a vCPU that has been created but not yet
> > > run. Code that iterates over every vCPU's pseudo-TLB must skip those.
> > >
> > > invalidate_vncr_va() iterates over the vCPUs with kvm_for_each_vcpu() and
> > > dereferences vt->valid without checking whether vncr_tlb is NULL.
> > >
> > > While iterating, skip vCPUs whose pseudo-TLB has not been allocated.
> > >
> > > Fixes: 4ffa72ad8f37 ("KVM: arm64: nv: Add S1 TLB invalidation primitive for VNCR_EL2")
> > > Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
> > > ---
> > > arch/arm64/kvm/nested.c | 4 ++++
> > > 1 file changed, 4 insertions(+)
> > >
> > > diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> > > index 6f7bc9a9992e..063e079d1d1a 100644
> > > --- a/arch/arm64/kvm/nested.c
> > > +++ b/arch/arm64/kvm/nested.c
> > > @@ -969,6 +969,10 @@ static void invalidate_vncr_va(struct kvm *kvm,
> > > struct vncr_tlb *vt = vcpu->arch.vncr_tlb;
> > > u64 va_start, va_end, va_size;
> > >
> > > + /* Skip vCPUs whose pseudo-TLB hasn't been allocated yet */
> > > + if (!vt)
> > > + continue;
> > > +
> > > if (!vt->valid)
> > > continue;
> > >
> >
> > This looks correct and matches what we already have for
> > invalidate_vncr_ipa().
> >
> > But I think this misses the opportunity to squash a whole class of
> > similar bugs, should we ever have the need for another function that
> > iterates over all *valid* VNCR pseudo-TLBs.
> >
> > Since I'm on a train and have nothing better to do, I've written the
> > following hack.
> >
> > Thoughts?
>
> Looks like a good direction to me. I confirmed it fixes the issue (as
> expected).
>
> How about you submit this patch yourself?
Sure, can do. I'll sent that in a minute.
> > +#define kvm_for_each_vncr_tlb(idx, vcpup, tlbp, kvm) \
> > + kvm_for_each_vcpu(idx, vcpu, kvm) \
>
> Maybe vcpu -> vcpup?
Duh. Yes. Thanks.
M.
--
Jazz isn't dead. It just smells funny.
^ permalink raw reply
* Re: [PATCH v2] drm/rockchip: dsi: Open-code drm_simple_encoder_init()
From: Jonas Karlman @ 2026-06-07 17:01 UTC (permalink / raw)
To: Diogo Silva, heiko
Cc: airlied, andy.yan, dri-devel, hjc, linux-arm-kernel, linux-kernel,
linux-rockchip, maarten.lankhorst, mripard, simona, tzimmermann
In-Reply-To: <20260607123739.393974-2-diogompaissilva@gmail.com>
Hi Diogo,
On 6/7/2026 2:37 PM, Diogo Silva wrote:
> Simple KMS helper are deprecated since they only add an intermediate
> layer between drivers and the atomic modesetting.
> This patch removes the dependency on drm_simple_encoder_init from rockchip
> DRM drivers by inlining this helper.
>
> Signed-off-by: Diogo Silva <diogompaissilva@gmail.com>
> ---
> drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 9 ++++++---
> drivers/gpu/drm/rockchip/cdn-dp-core.c | 9 ++++++---
> drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 9 +++++++--
> drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c | 8 ++++++--
> drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 8 ++++++--
> drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 8 ++++++--
> drivers/gpu/drm/rockchip/rk3066_hdmi.c | 8 ++++++--
> drivers/gpu/drm/rockchip/rockchip_lvds.c | 9 +++++++--
> drivers/gpu/drm/rockchip/rockchip_rgb.c | 8 ++++++--
> 9 files changed, 56 insertions(+), 20 deletions(-)
[snip]
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> index 0dc1eb5d2ae3..906264d65db3 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> @@ -16,7 +16,6 @@
> #include <drm/drm_edid.h>
> #include <drm/drm_of.h>
> #include <drm/drm_probe_helper.h>
> -#include <drm/drm_simple_kms_helper.h>
>
> #include "rockchip_drm_drv.h"
>
> @@ -322,6 +321,10 @@ dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
> return 0;
> }
>
> +static const struct drm_encoder_funcs dw_hdmi_rockchip_encoder_funcs = {
> + .destroy = drm_encoder_cleanup,
> +};
> +
> static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
> .mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
> .mode_set = dw_hdmi_rockchip_encoder_mode_set,
> @@ -604,7 +607,8 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
> }
>
> drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs);
> - drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
> + drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs,
> + DRM_MODE_ENCODER_TMDS, NULL);
Please base your work on latest drm-misc tree, this has already been
addressed in commit 3de723684be5 ("drm/rockchip: dw_hdmi: Use drmres
helpers for encoder resources") [1].
Also instead of open-code, maybe a change to use drmm_encoder_init() is
more appropriate for some of the other drivers?
[1] https://cgit.freedesktop.org/drm/drm-misc/commit/?id=3de723684be5c13517dea3dba287d06e12678c86
Regards,
Jonas
>
> platform_set_drvdata(pdev, hdmi);
>
[snip]
^ permalink raw reply
* [PATCH] KVM: arm64: Add kvm_for_each_vncr_tlb() helper
From: Marc Zyngier @ 2026-06-07 17:57 UTC (permalink / raw)
To: kvmarm, kvm, linux-arm-kernel
Cc: Steffen Eiden, Joey Gouly, Suzuki K Poulose, Oliver Upton,
Zenghui Yu, Hyunwoo Kim, stable
VNCR TLB invalidation occurs from MMU notifiers or TLBI instructions,
and either can race against a vcpu not being onlined yet (no pseudo-TLB
allocated). Similarly, the TLB might be invalid, and the invalidation
should be skipped in this case.
Both kvm_invalidate_vncr_ipa() and kvm_invalidate_vncr_va() are
expected to perform the same checks, except that the latter doesn't
check for the allocation and blindly dereferences the pointer.
Solve this by introducing a new iterator built on top of the usual
kvm_for_each_vcpu() that checks for both of the above conditions,
and convert the two users to it.
Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/aiUvSbrWndQeUPc8@v4bel
Fixes: 4ffa72ad8f37 ("KVM: arm64: nv: Add S1 TLB invalidation primitive for VNCR_EL2")
Cc: stable@vger.kernel.org
---
arch/arm64/kvm/nested.c | 36 +++++++++++++++---------------------
1 file changed, 15 insertions(+), 21 deletions(-)
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index f8d3f3a723282..690b8e8564166 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -908,9 +908,21 @@ static void invalidate_vncr(struct vncr_tlb *vt)
clear_fixmap(vncr_fixmap(vt->cpu));
}
+/*
+ * VNCR TLB invalidation occurs from MMU notifiers or TLBI instructions, and
+ * either can race against a vcpu not being onlined yet (no pseudo-TLB
+ * allocated). Similarly, the TLB might be invalid. Skip those, as they
+ * obviously don't participate in the invalidation at this stage.
+ */
+#define kvm_for_each_vncr_tlb(idx, vcpup, tlbp, kvm) \
+ kvm_for_each_vcpu(idx, vcpup, kvm) \
+ if (((tlbp) = vcpup->arch.vncr_tlb) && \
+ (tlbp)->valid)
+
static void kvm_invalidate_vncr_ipa(struct kvm *kvm, u64 start, u64 end)
{
struct kvm_vcpu *vcpu;
+ struct vncr_tlb *vt;
unsigned long i;
lockdep_assert_held_write(&kvm->mmu_lock);
@@ -918,24 +930,9 @@ static void kvm_invalidate_vncr_ipa(struct kvm *kvm, u64 start, u64 end)
if (!kvm_has_feat(kvm, ID_AA64MMFR4_EL1, NV_frac, NV2_ONLY))
return;
- kvm_for_each_vcpu(i, vcpu, kvm) {
- struct vncr_tlb *vt = vcpu->arch.vncr_tlb;
+ kvm_for_each_vncr_tlb(i, vcpu, vt, kvm) {
u64 ipa_start, ipa_end, ipa_size;
- /*
- * Careful here: We end-up here from an MMU notifier,
- * and this can race against a vcpu not being onlined
- * yet, without the pseudo-TLB being allocated.
- *
- * Skip those, as they obviously don't participate in
- * the invalidation at this stage.
- */
- if (!vt)
- continue;
-
- if (!vt->valid)
- continue;
-
ipa_size = ttl_to_size(pgshift_level_to_ttl(vt->wi.pgshift,
vt->wr.level));
ipa_start = vt->wr.pa & ~(ipa_size - 1);
@@ -965,17 +962,14 @@ static void invalidate_vncr_va(struct kvm *kvm,
struct s1e2_tlbi_scope *scope)
{
struct kvm_vcpu *vcpu;
+ struct vncr_tlb *vt;
unsigned long i;
lockdep_assert_held_write(&kvm->mmu_lock);
- kvm_for_each_vcpu(i, vcpu, kvm) {
- struct vncr_tlb *vt = vcpu->arch.vncr_tlb;
+ kvm_for_each_vncr_tlb(i, vcpu, vt, kvm) {
u64 va_start, va_end, va_size;
- if (!vt->valid)
- continue;
-
va_size = ttl_to_size(pgshift_level_to_ttl(vt->wi.pgshift,
vt->wr.level));
va_start = vt->gva & ~(va_size - 1);
--
2.47.3
^ permalink raw reply related
* Re: [PATCH net-next v2 05/14] net: pcs: pcs-xpcs: select operating mode for 10G-baseR capable PCS
From: Andrew Lunn @ 2026-06-07 17:52 UTC (permalink / raw)
To: Alex Elder
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, maxime.chevallier,
rmk+kernel, andersson, konradybcio, robh, krzk+dt, conor+dt,
linusw, brgl, arnd, gregkh, Daniel Thompson, mohd.anwar,
a0987203069, alexandre.torgue, ast, boon.khai.ng, chenchuangyu,
chenhuacai, daniel, hawk, hkallweit1, inochiama, john.fastabend,
julianbraha, livelycarpet87, mcoquelin.stm32, me,
prabhakar.mahadev-lad.rj, richardcochran, rohan.g.thomas, sdf,
siyanteng, weishangjuan, wens, netdev, bpf, linux-arm-msm,
devicetree, linux-gpio, linux-stm32, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260605010022.968612-6-elder@riscstar.com>
> Rather than introduce another quirk for TC956x let's attempt so solve
> this generically by setting SR_XS_PCS_CTRL2:PCS_TYPE_SEL to a reserved
> value when we detect the right we detect the right combination of phy
> interface and XPCS feature support.
This sentence is broken.
Andrew
^ permalink raw reply
* Re: [PATCH net-next v2 03/14] net: pcs: pcs-xpcs-regmap: support XPCS memory-mapped MDIO bus via regmap
From: Andrew Lunn @ 2026-06-07 17:47 UTC (permalink / raw)
To: Alex Elder
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, maxime.chevallier,
rmk+kernel, andersson, konradybcio, robh, krzk+dt, conor+dt,
linusw, brgl, arnd, gregkh, Daniel Thompson, mohd.anwar,
a0987203069, alexandre.torgue, ast, boon.khai.ng, chenchuangyu,
chenhuacai, daniel, hawk, hkallweit1, inochiama, john.fastabend,
julianbraha, livelycarpet87, mcoquelin.stm32, me,
prabhakar.mahadev-lad.rj, richardcochran, rohan.g.thomas, sdf,
siyanteng, weishangjuan, wens, netdev, bpf, linux-arm-msm,
devicetree, linux-gpio, linux-stm32, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260605010022.968612-4-elder@riscstar.com>
> +struct dw_xpcs *devm_xpcs_regmap_register(struct device *dev,
> + const struct xpcs_regmap_config *config)
> +{
> + static atomic_t id = ATOMIC_INIT(-1);
...
> + snprintf(pxpcs->bus->id, MII_BUS_ID_SIZE,
> + "dwxpcs-%x", atomic_inc_return(&id));
dev_name(dev) should be unique, and it also makes it easier to
associate the PCS to the MAC when looking in /sys.
Andrew
^ permalink raw reply
* [PATCH net-next v2] net: airoha: add ethtool priv_flags support for LAN/WAN and GDM2 loopback
From: Lorenzo Bianconi @ 2026-06-07 17:19 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Lorenzo Bianconi
Cc: linux-arm-kernel, linux-mediatek, netdev, Madhur Agrawal
Introduce ethtool private flags infrastructure for the airoha ethernet
driver, allowing userspace to configure per-device behavior via ethtool.
Implement the "wan" private flag to let the user select whether a GDM
port is used as a hardware LAN or WAN interface. GDM2 is fixed as WAN
only, GDM1 is fixed as LAN only, while GDM3 and GDM4 can be switched
between LAN and WAN at runtime (when the interface is not running).
When a GDM3/GDM4 port is set to WAN mode, enable GDM2 loopback to
support hardware QoS. Conversely, when switching back to LAN mode,
disable the GDM2 loopback and restore the default forwarding
configuration.
Add airoha_disable_gdm2_loopback() as the counterpart of the existing
airoha_enable_gdm2_loopback(), and define FC_MAP6_DEF_VALUE for use
during loopback teardown.
Example usage to configure eth1 (GDM3/GDM4) as WAN:
$ ethtool --show-priv-flags eth1
Private flags for eth1:
wan: off
$ ethtool --set-priv-flags eth1 wan on
$ ethtool --show-priv-flags eth1
Private flags for eth1:
wan: on
To revert back to LAN mode:
$ ethtool --set-priv-flags eth1 wan off
Tested-by: Madhur Agrawal <madhur.agrawal@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
Changes in v2:
- Rework airoha_dev_set_wan_flag routine
- Enable GDM_STRIP_CRC_MASK in airoha_disable_gdm2_loopback()
- Do not always reset REG_SRC_PORT_FC_MAP6 in
airoha_disable_gdm2_loopback() but use the same condition used in
airoha_enable_gdm2_loopback().
- Link to v1: https://lore.kernel.org/r/20260606-airoha-ethtool-priv_flags-v1-1-401b2c9fe9f1@kernel.org
---
drivers/net/ethernet/airoha/airoha_eth.c | 173 ++++++++++++++++++++++++++++++
drivers/net/ethernet/airoha/airoha_regs.h | 1 +
2 files changed, 174 insertions(+)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 5a8e84fa9918..5dd160dbbbc1 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1960,6 +1960,49 @@ static int airoha_enable_gdm2_loopback(struct airoha_gdm_dev *dev)
return 0;
}
+static int airoha_disable_gdm2_loopback(struct airoha_gdm_dev *dev)
+{
+ struct airoha_gdm_port *port = dev->port;
+ struct airoha_eth *eth = dev->eth;
+ int i, src_port;
+ u32 pse_port;
+
+ src_port = eth->soc->ops.get_sport(dev->port, dev->nbq);
+ if (src_port < 0)
+ return src_port;
+
+ airoha_fe_clear(eth,
+ REG_SP_DFT_CPORT(src_port >> fls(SP_CPORT_DFT_MASK)),
+ SP_CPORT_MASK(src_port & SP_CPORT_DFT_MASK));
+
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
+ GDM_STRIP_CRC_MASK);
+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
+ FE_PSE_PORT_DROP);
+ airoha_fe_clear(eth, REG_GDM_LPBK_CFG(AIROHA_GDM2_IDX),
+ LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK);
+ pse_port = airoha_ppe_is_enabled(eth, 1) ? FE_PSE_PORT_PPE2
+ : FE_PSE_PORT_PPE1;
+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
+ pse_port);
+
+ airoha_fe_rmw(eth, REG_FE_WAN_PORT, WAN0_MASK,
+ FIELD_PREP(WAN0_MASK, AIROHA_GDM2_IDX));
+
+ for (i = 0; i < eth->soc->num_ppe; i++)
+ airoha_fe_clear(eth, REG_PPE_DFT_CPORT(i, AIROHA_GDM2_IDX),
+ DFT_CPORT_MASK(AIROHA_GDM2_IDX));
+
+ /* Enable VIP and IFC for GDM2 */
+ airoha_fe_set(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX));
+ airoha_fe_set(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX));
+
+ if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth))
+ airoha_fe_wr(eth, REG_SRC_PORT_FC_MAP6, FC_MAP6_DEF_VALUE);
+
+ return 0;
+}
+
static struct airoha_gdm_dev *
airoha_get_wan_gdm_dev(struct airoha_eth *eth)
{
@@ -2296,6 +2339,77 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;
}
+struct airoha_ethool_priv_flags {
+ char name[ETH_GSTRING_LEN];
+ int (*handler)(struct net_device *netdev, u32 flags);
+};
+
+static int airoha_dev_set_wan_flag(struct net_device *netdev, u32 flags)
+{
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
+ struct airoha_eth *eth = dev->eth;
+ int err;
+
+ if (port->id != AIROHA_GDM3_IDX &&
+ port->id != AIROHA_GDM4_IDX) {
+ /* GDM1 can be used just as LAN while GDM2 can be configured
+ * only as WAN
+ */
+ return -EOPNOTSUPP;
+ }
+
+ if (netif_running(netdev))
+ return -EBUSY;
+
+ if (flags & AIROHA_PRIV_F_WAN) {
+ struct airoha_gdm_dev *wan_dev;
+
+ /* Verify the WAN device is not already configured */
+ wan_dev = airoha_get_wan_gdm_dev(eth);
+ if (wan_dev && wan_dev != dev)
+ return -EBUSY;
+
+ dev->flags |= AIROHA_PRIV_F_WAN;
+ airoha_dev_set_qdma(dev);
+ err = airoha_enable_gdm2_loopback(dev);
+ if (err)
+ goto error;
+ } else {
+ err = airoha_disable_gdm2_loopback(dev);
+ if (err)
+ return err;
+
+ dev->flags &= ~AIROHA_PRIV_F_WAN;
+ airoha_dev_set_qdma(dev);
+ }
+
+ err = airoha_set_macaddr(dev, netdev->dev_addr);
+ if (err)
+ goto error;
+
+ return 0;
+error:
+ /* Restore previous LAN or WAN configuration */
+ if (flags & AIROHA_PRIV_F_WAN) {
+ airoha_disable_gdm2_loopback(dev);
+ dev->flags &= ~AIROHA_PRIV_F_WAN;
+ airoha_dev_set_qdma(dev);
+ } else {
+ dev->flags |= AIROHA_PRIV_F_WAN;
+ airoha_dev_set_qdma(dev);
+ airoha_enable_gdm2_loopback(dev);
+ }
+
+ return err;
+}
+
+static const struct airoha_ethool_priv_flags airoha_eth_priv_flags[] = {
+ { "wan", airoha_dev_set_wan_flag },
+};
+
+#define AIROHA_PRIV_FLAGS_STR_LEN ARRAY_SIZE(airoha_eth_priv_flags)
+
static void airoha_ethtool_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *info)
{
@@ -2304,6 +2418,7 @@ static void airoha_ethtool_get_drvinfo(struct net_device *netdev,
strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
+ info->n_priv_flags = AIROHA_PRIV_FLAGS_STR_LEN;
}
static void airoha_ethtool_get_mac_stats(struct net_device *netdev,
@@ -2368,6 +2483,60 @@ airoha_ethtool_get_rmon_stats(struct net_device *netdev,
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
}
+static int airoha_ethtool_set_priv_flags(struct net_device *netdev, u32 flags)
+{
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ int i;
+
+ for (i = 0; i < AIROHA_PRIV_FLAGS_STR_LEN; i++) {
+ int err;
+
+ if (!((dev->flags ^ flags) & BIT(i)))
+ continue;
+
+ if (!airoha_eth_priv_flags[i].handler)
+ continue;
+
+ err = airoha_eth_priv_flags[i].handler(netdev, flags);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static u32 airoha_ethtool_get_priv_flags(struct net_device *netdev)
+{
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+
+ return dev->flags;
+}
+
+static int airoha_ethtool_get_sset_count(struct net_device *netdev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_PRIV_FLAGS:
+ return AIROHA_PRIV_FLAGS_STR_LEN;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static void airoha_ethtool_get_strings(struct net_device *netdev,
+ u32 stringset, u8 *data)
+{
+ int i;
+
+ switch (stringset) {
+ case ETH_SS_PRIV_FLAGS:
+ for (i = 0; i < AIROHA_PRIV_FLAGS_STR_LEN; i++)
+ ethtool_puts(&data, airoha_eth_priv_flags[i].name);
+ break;
+ default:
+ break;
+ }
+}
+
static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
int channel, enum tx_sched_mode mode,
const u16 *weights, u8 n_weights)
@@ -3094,6 +3263,10 @@ static const struct ethtool_ops airoha_ethtool_ops = {
.get_rmon_stats = airoha_ethtool_get_rmon_stats,
.get_link_ksettings = phy_ethtool_get_link_ksettings,
.get_link = ethtool_op_get_link,
+ .set_priv_flags = airoha_ethtool_set_priv_flags,
+ .get_priv_flags = airoha_ethtool_get_priv_flags,
+ .get_sset_count = airoha_ethtool_get_sset_count,
+ .get_strings = airoha_ethtool_get_strings,
};
static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port)
diff --git a/drivers/net/ethernet/airoha/airoha_regs.h b/drivers/net/ethernet/airoha/airoha_regs.h
index 436f3c8779c1..4e17dfbcf2b8 100644
--- a/drivers/net/ethernet/airoha/airoha_regs.h
+++ b/drivers/net/ethernet/airoha/airoha_regs.h
@@ -376,6 +376,7 @@
#define REG_SRC_PORT_FC_MAP6 0x2298
#define FC_ID_OF_SRC_PORT_MASK(_n) GENMASK(4 + ((_n) << 3), ((_n) << 3))
+#define FC_MAP6_DEF_VALUE 0x1b1a1918
#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4
---
base-commit: 903db046d5579bef0ea699eae4b279dd6455fc9f
change-id: 20260606-airoha-ethtool-priv_flags-b6aa70caa780
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply related
* Re: [PATCH 6.18 000/315] 6.18.35-rc1 review
From: Miguel Ojeda @ 2026-06-07 17:04 UTC (permalink / raw)
To: gregkh
Cc: achill, akpm, broonie, conor, f.fainelli, hargar, jonathanh,
linux-kernel, linux, lkft-triage, patches, patches, pavel,
rwarsow, shuah, sr, stable, sudipm.mukherjee, torvalds,
Miguel Ojeda, Marc Zyngier, Joey Gouly, Suzuki K Poulose,
Oliver Upton, Zenghui Yu, Fuad Tabba, Will Deacon,
Catalin Marinas, Steffen Eiden, Mark Rutland, kvmarm,
linux-arm-kernel, kvm
In-Reply-To: <20260607095727.528828913@linuxfoundation.org>
On Sun, 07 Jun 2026 11:56:27 +0200 Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote:
>
> This is the start of the stable review cycle for the 6.18.35 release.
> There are 315 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Tue, 09 Jun 2026 09:56:45 +0000.
> Anything received after that time might be too late.
Boot-tested under QEMU for Rust x86_64, arm64 and riscv64; built-tested
for loongarch64:
Tested-by: Miguel Ojeda <ojeda@kernel.org>
arm32 builds fine too.
However, on arm64 I am seeing:
arch/arm64/kvm/nested.c:1776:2: error: use of undeclared identifier 'resx'
1776 | resx.res0 = ZCR_ELx_RES0 | GENMASK_ULL(8, 4);
| ^
arch/arm64/kvm/nested.c:1777:2: error: use of undeclared identifier 'resx'
1777 | resx.res1 = ZCR_ELx_RES1;
| ^
arch/arm64/kvm/nested.c:1778:33: error: use of undeclared identifier 'resx'
1778 | set_sysreg_masks(kvm, ZCR_EL2, resx);
| ^
Due to commit 10206eaad1b9 ("KVM: arm64: Correctly cap ZCR_EL2 provided
by a guest hypervisor") here.
`resx` indeed doesn't exist, and it seems like it was added by commits
0879478913dd ("KVM: arm64: Introduce data structure tracking both RES0
and RES1 bits") etc., which are in 7.0, from this series:
https://lore.kernel.org/all/20260202184329.2724080-1-maz@kernel.org/
So either we make a targeted backport or backport some commits, no?
I hope that help!
Cc: Mark Brown <broonie@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Joey Gouly <joey.gouly@arm.com>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Oliver Upton <oupton@kernel.org>
Cc: Zenghui Yu <yuzenghui@huawei.com>
Cc: Fuad Tabba <tabba@google.com>
Cc: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Steffen Eiden <seiden@linux.ibm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: kvmarm@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
Cc: kvm@vger.kernel.org
Cheers,
Miguel
^ permalink raw reply
* [PATCH] dmaengine: qcom: hidma: use sysfs_emit() in sysfs show callbacks
From: Hungyu Lin @ 2026-06-07 16:31 UTC (permalink / raw)
To: okaya, vkoul
Cc: Frank.Li, linux-arm-kernel, linux-arm-msm, dmaengine,
linux-kernel, Hungyu Lin
Replace sprintf() and strlen() patterns in sysfs show callbacks
with sysfs_emit().
sysfs_emit() is the preferred helper for formatting sysfs output
and simplifies the implementation.
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
---
drivers/dma/qcom/hidma.c | 6 ++----
drivers/dma/qcom/hidma_mgmt_sys.c | 19 ++++++++-----------
2 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c
index 5a8dca8db5ce..7a7f302a9699 100644
--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -624,12 +624,10 @@ static ssize_t hidma_show_values(struct device *dev,
{
struct hidma_dev *mdev = dev_get_drvdata(dev);
- buf[0] = 0;
-
if (strcmp(attr->attr.name, "chid") == 0)
- sprintf(buf, "%d\n", mdev->chidx);
+ return sysfs_emit(buf, "%d\n", mdev->chidx);
- return strlen(buf);
+ return 0;
}
static inline void hidma_sysfs_uninit(struct hidma_dev *dev)
diff --git a/drivers/dma/qcom/hidma_mgmt_sys.c b/drivers/dma/qcom/hidma_mgmt_sys.c
index 930eae0a6257..9672ef9ee8fc 100644
--- a/drivers/dma/qcom/hidma_mgmt_sys.c
+++ b/drivers/dma/qcom/hidma_mgmt_sys.c
@@ -102,15 +102,12 @@ static ssize_t show_values(struct device *dev, struct device_attribute *attr,
struct hidma_mgmt_dev *mdev = dev_get_drvdata(dev);
unsigned int i;
- buf[0] = 0;
-
for (i = 0; i < ARRAY_SIZE(hidma_mgmt_files); i++) {
- if (strcmp(attr->attr.name, hidma_mgmt_files[i].name) == 0) {
- sprintf(buf, "%d\n", hidma_mgmt_files[i].get(mdev));
- break;
- }
+ if (strcmp(attr->attr.name, hidma_mgmt_files[i].name) == 0)
+ return sysfs_emit(buf, "%d\n",
+ hidma_mgmt_files[i].get(mdev));
}
- return strlen(buf);
+ return 0;
}
static ssize_t set_values(struct device *dev, struct device_attribute *attr,
@@ -143,15 +140,15 @@ static ssize_t show_values_channel(struct kobject *kobj,
struct hidma_chan_attr *chattr;
struct hidma_mgmt_dev *mdev;
- buf[0] = 0;
chattr = container_of(attr, struct hidma_chan_attr, attr);
mdev = chattr->mdev;
+
if (strcmp(attr->attr.name, "priority") == 0)
- sprintf(buf, "%d\n", mdev->priority[chattr->index]);
+ return sysfs_emit(buf, "%d\n", mdev->priority[chattr->index]);
else if (strcmp(attr->attr.name, "weight") == 0)
- sprintf(buf, "%d\n", mdev->weight[chattr->index]);
+ return sysfs_emit(buf, "%d\n", mdev->weight[chattr->index]);
- return strlen(buf);
+ return 0;
}
static ssize_t set_values_channel(struct kobject *kobj,
--
2.34.1
^ permalink raw reply related
* [PATCH] mailbox: bcm2835: Add ACPI support for UEFI-booted Raspberry Pi 4
From: Steve Crawford @ 2026-06-07 15:43 UTC (permalink / raw)
To: jassisinghbrar
Cc: linux-kernel, linux-arm-kernel, kernel-list, Steve Crawford
On Raspberry Pi 4 booted via UEFI (e.g. using the pftf/RPi4 firmware),
the kernel enumerates devices via ACPI rather than the device tree. The
RPIQ mailbox device is already correctly described in the edk2-platforms
GpuDevs.asl with HID BCM2849, complete with MMIO and interrupt resources,
but the driver has no ACPI match table and therefore never binds.
Add an ACPI device ID table matching BCM2849, and replace the
DT-only irq_of_parse_and_map() call with platform_get_irq(), which
handles both DT and ACPI resource lookup transparently.
The existing DT path (brcm,bcm2835-mbox) is unchanged; this is a
purely additive change that has no effect on any boot path other than
UEFI+ACPI on RPi4.
Testing
-------
On Fedora CoreOS 44 (kernel 7.0.8-200.fc44.aarch64) booted via pftf/RPi4
UEFI v1.42, BCM2849:00 (the RPIQ mailbox device) is visible in ACPI but
unbound. Using driver_override to force-bind the unpatched driver
reproduces the exact failure this patch fixes:
# echo bcm2835-mbox > /sys/bus/platform/devices/BCM2849:00/driver_override
# echo BCM2849:00 > /sys/bus/platform/drivers/bcm2835-mbox/bind
bcm2835-mbox BCM2849:00: error -EINVAL: request_irq(0) bcm2835_mbox_irq 0x0 BCM2849:00
bcm2835-mbox BCM2849:00: Failed to register a mailbox IRQ handler: -22
irq_of_parse_and_map() returns 0 when dev->of_node is NULL (ACPI case).
platform_get_irq() correctly reads the interrupt from the ACPI _CRS
resources instead.
Signed-off-by: Steve Crawford <steve@crawford.dev>
---
bcm2835-mailbox.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/bcm2835-mailbox.c b/bcm2835-mailbox.c
index ea12fb8..d450f3b 100644
--- a/bcm2835-mailbox.c
+++ b/bcm2835-mailbox.c
@@ -15,6 +15,7 @@
* https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
*/
+#include <linux/acpi.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
@@ -24,7 +25,6 @@
#include <linux/mailbox_controller.h>
#include <linux/module.h>
#include <linux/of_address.h>
-#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
@@ -144,7 +144,7 @@ static int bcm2835_mbox_probe(struct platform_device *pdev)
return -ENOMEM;
spin_lock_init(&mbox->lock);
- ret = devm_request_irq(dev, irq_of_parse_and_map(dev->of_node, 0),
+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
bcm2835_mbox_irq, IRQF_NO_SUSPEND, dev_name(dev),
mbox);
if (ret) {
@@ -186,10 +186,24 @@ static const struct of_device_id bcm2835_mbox_of_match[] = {
};
MODULE_DEVICE_TABLE(of, bcm2835_mbox_of_match);
+static const struct acpi_device_id bcm2835_mbox_acpi_match[] = {
+ /*
+ * BCM2849 is the ACPI HID for the RPi4 UEFI firmware's RPIQ mailbox
+ * device (defined in GpuDevs.asl of the tianocore/edk2-platforms RPi4
+ * platform). On UEFI-booted systems this device carries the correct
+ * MMIO and interrupt resources, allowing the driver to bind via ACPI
+ * rather than the device tree.
+ */
+ { "BCM2849", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, bcm2835_mbox_acpi_match);
+
static struct platform_driver bcm2835_mbox_driver = {
.driver = {
.name = "bcm2835-mbox",
.of_match_table = bcm2835_mbox_of_match,
+ .acpi_match_table = bcm2835_mbox_acpi_match,
},
.probe = bcm2835_mbox_probe,
};
--
2.54.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