Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
From: Linus Torvalds @ 2026-04-23 21:28 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Mathias Stearn, Peter Zijlstra, Mathieu Desnoyers,
	Catalin Marinas, Will Deacon, Boqun Feng, Paul E. McKenney,
	Chris Kennelly, Dmitry Vyukov, regressions, linux-kernel,
	linux-arm-kernel, Ingo Molnar, Mark Rutland, Jinjie Ruan,
	Blake Oler
In-Reply-To: <874il11jac.ffs@tglx>

On Thu, 23 Apr 2026 at 14:03, Thomas Gleixner <tglx@kernel.org> wrote:
>
>      Feel free to enforce it, but be aware that you thereby set a
>      precedence that a single abuser can then rightfully own a general
>      shared interface of the kernel forever and force everybody else to
>      give up.

That's not a new precedent. That is *literally* the rule we have always had.

This is why system calls and ABI's need to have hard rules that they
actually check, because if they don't, they are stuck with the
semantics that people assume.

And no, "documented behavior" is BS. It has absolutely no relevance.
All that matters is hard harsh reality.

Yes, this has led to issues before.

Most new system calls have learnt their lesson, and they check for
unused bits in flags etc, and error out on bits that the lernel
doesn't really care about being randomly set - so that one day we
*can* extend on things and start caring about them.

But they do it because we've been burnt so many times before because
we haven't checked those bits, and then we were forced to just live
with the fact that people passed in random values.

>     // Note: this makes __rseq_abi.cpu_id_start unusable for its original purpose.
>
>     Do you seriously want to proliferate that?

Absolutely.

That's how clever hacks work - they take advantage of things past
their design parameters. "If it works, it's not stupid".

We don't then turn around and say "you were clever, and we did
something stupid, so now we'll hurt you".

This is all 100% on the RSEQ kernel code, not on users who took advantage of it.

                Linus


^ permalink raw reply

* [PATCH 5/5] ARM: dts: exynos: Add display support for exynos5250-manta
From: Lukas Timmermann @ 2026-04-23 21:14 UTC (permalink / raw)
  To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Thierry Reding, Sam Ravnborg,
	Douglas Anderson, Krzysztof Kozlowski, Sylwester Nawrocki,
	Chanwoo Choi, Alim Akhtar, Michael Turquette, Stephen Boyd
  Cc: dri-devel, devicetree, linux-kernel, linux-samsung-soc, linux-clk,
	linux-arm-kernel, Lukas Timmermann, Alexandre Marquet
In-Reply-To: <20260423-manta-display-v1-0-196f80c5673a@timmermann.space>

Adds the necessary entries for panel and backlight as
well as the fimd controller.

Signed-off-by: Alexandre Marquet <tb@a-marquet.fr>
Signed-off-by: Lukas Timmermann <linux@timmermann.space>
---
 arch/arm/boot/dts/samsung/exynos5250-manta.dts | 99 ++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/arch/arm/boot/dts/samsung/exynos5250-manta.dts b/arch/arm/boot/dts/samsung/exynos5250-manta.dts
index 76d3657eb22f..eb97a28ff4e3 100644
--- a/arch/arm/boot/dts/samsung/exynos5250-manta.dts
+++ b/arch/arm/boot/dts/samsung/exynos5250-manta.dts
@@ -25,6 +25,29 @@ aliases {
 		mmc1 = &mmc_1; /* WiFi */
 	};
 
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm 0 1000000 0>;
+
+		brightness-levels = <2 255>; /* TODO */
+		num-interpolated-steps = <254>; /* TODO */
+		default-brightness-level = <102>; /* TODO */
+		post-pwm-on-delay-ms = <97>; /* TODO */
+
+		power-supply = <&backlight_reg>;
+		enable-gpios = <&gpg0 5 GPIO_ACTIVE_HIGH>;
+
+		pinctrl-0 = <&led_bl_reset &pwm0_out>;
+		pinctrl-names = "default";
+	};
+
+	backlight_reg: regulator-backlight {
+		compatible = "regulator-fixed";
+		regulator-name = "APS_EN_18V";
+		pinctrl-0 = <&aps_en_18v>;
+		pinctrl-names = "default";
+	};
+
 	/* Voltage source unknown */
 	bmp180_vdda_reg: regulator-bmp180-vdda {
 		compatible = "regulator-fixed";
@@ -105,6 +128,28 @@ multi-led {
 		leds = <&status_red>, <&status_green>, <&status_blue>, <&status_white>;
 	};
 
+	panel {
+		compatible = "samsung,ltl101dl02-002";
+
+		backlight = <&backlight>;
+		power-supply = <&panel_reg>;
+		enable-gpios = <&gph1 7 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&lcd_en>;
+		pinctrl-names = "default";
+		no-hpd;
+
+		port {
+			panel: endpoint {
+				remote-endpoint = <&dp_out>;
+			};
+		};
+	};
+
+	panel_reg: regulator-panel {
+		compatible = "regulator-fixed";
+		regulator-name = "LCD_EN";
+	};
+
 	pwrseq: mmc1-pwrseq {
 		compatible = "mmc-pwrseq-simple";
 
@@ -146,10 +191,36 @@ &cpu1 {
 	cpu-supply = <&buck2_reg>;
 };
 
+&dp {
+	status = "okay";
+
+	samsung,color-space = <0>;
+	samsung,color-depth = <1>;
+	samsung,link-rate = <0x0a>;
+	samsung,lane-count = <4>;
+	samsung,dynamic-range = <0>;
+	samsung,ycbcr-coeff = <0>;
+
+	ports {
+		port {
+			dp_out: endpoint {
+				remote-endpoint = <&panel>;
+			};
+		};
+	};
+};
+
 &ehci {
 	status = "disabled";
 };
 
+&fimd {
+	status = "okay";
+
+	assigned-clocks = <&clock CLK_MOUT_FIMD1>, <&clock CLK_MOUT_VPLL>;
+	assigned-clock-parents = <&clock CLK_MOUT_VPLL>;
+};
+
 &i2c_1 {
 	status = "okay";
 
@@ -396,6 +467,12 @@ ldo25_reg: LDO25 {
 	};
 };
 
+&mali {
+	status = "okay";
+
+	mali-supply = <&buck4_reg>;
+};
+
 &mixer {
 	status = "okay";
 };
@@ -489,6 +566,14 @@ wlan_irq: wlan-irq-pins {
 };
 
 &pinctrl_1 {
+	aps_en_18v: aps-en-18v-pins {
+		samsung,pins = "gph1-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; /* TODO */
+		samsung,pin-con-pdn = <EXYNOS_PIN_PDN_INPUT>; /* TODO */
+		samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_UP>; /* TODO */
+		samsung,pin-val = <0>; /* TODO */
+	};
+
 	bh1721fvc_reset: bh1721fvc-reset-pins {
 		samsung,pins = "gph1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
@@ -509,6 +594,20 @@ bt_wake: bt-wake-pins {
 		samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
 	};
 
+	lcd_en: lcd-en-pins {
+		samsung,pins = "gph1-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; /* TODO */
+		samsung,pin-val = <0>;
+	};
+
+	led_bl_reset: led-bl-rst-pins {
+		samsung,pins = "gpg0-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>; /* TODO */
+		samsung,pin-con-pdn = <EXYNOS_PIN_PDN_PREV>; /* TODO */
+		samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>; /* TODO */
+		samsung,pin-val = <0>; /* TODO */
+	};
+
 	msense_reset: msense-reset-pins {
 		samsung,pins = "gpg2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;

-- 
2.53.0



^ permalink raw reply related

* [PATCH 4/5] clk: samsung: exynos5250: Define more clocks
From: Lukas Timmermann @ 2026-04-23 21:14 UTC (permalink / raw)
  To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Thierry Reding, Sam Ravnborg,
	Douglas Anderson, Krzysztof Kozlowski, Sylwester Nawrocki,
	Chanwoo Choi, Alim Akhtar, Michael Turquette, Stephen Boyd
  Cc: dri-devel, devicetree, linux-kernel, linux-samsung-soc, linux-clk,
	linux-arm-kernel, Lukas Timmermann, Alexandre Marquet
In-Reply-To: <20260423-manta-display-v1-0-196f80c5673a@timmermann.space>

Add defines for mout_fimd1 and mout_vpll to enable display support for
exynos5250-manta boards.

Signed-off-by: Alexandre Marquet <tb@a-marquet.fr>
Signed-off-by: Lukas Timmermann <linux@timmermann.space>
---
 drivers/clk/samsung/clk-exynos5250.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index e90d3a0848cb..a43d05d3014f 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -102,7 +102,7 @@
 #define PWR_CTRL2_CORE1_UP_RATIO		(1 << 0)
 
 /* NOTE: Must be equal to the last clock ID increased by one */
-#define CLKS_NR					(CLK_MOUT_VPLLSRC + 1)
+#define CLKS_NR					(CLK_MOUT_VPLL + 1)
 
 /* list of PLLs to be registered */
 enum exynos5250_plls {
@@ -283,7 +283,7 @@ static const struct samsung_mux_clock exynos5250_mux_clks[] __initconst = {
 
 	MUX(0, "mout_cpll", mout_cpll_p, SRC_TOP2, 8, 1),
 	MUX(0, "mout_epll", mout_epll_p, SRC_TOP2, 12, 1),
-	MUX(0, "mout_vpll", mout_vpll_p, SRC_TOP2, 16, 1),
+	MUX(CLK_MOUT_VPLL, "mout_vpll", mout_vpll_p, SRC_TOP2, 16, 1),
 	MUX(0, "mout_mpll_user", mout_mpll_user_p, SRC_TOP2, 20, 1),
 	MUX(0, "mout_bpll_user", mout_bpll_user_p, SRC_TOP2, 24, 1),
 	MUX(CLK_MOUT_GPLL, "mout_gpll", mout_gpll_p, SRC_TOP2, 28, 1),
@@ -304,7 +304,7 @@ static const struct samsung_mux_clock exynos5250_mux_clks[] __initconst = {
 	MUX(0, "mout_gscl_wa", mout_group1_p, SRC_GSCL, 24, 4),
 	MUX(0, "mout_gscl_wb", mout_group1_p, SRC_GSCL, 28, 4),
 
-	MUX(0, "mout_fimd1", mout_group1_p, SRC_DISP1_0, 0, 4),
+	MUX(CLK_MOUT_FIMD1, "mout_fimd1", mout_group1_p, SRC_DISP1_0, 0, 4),
 	MUX(0, "mout_mipi1", mout_group1_p, SRC_DISP1_0, 12, 4),
 	MUX(0, "mout_dp", mout_group1_p, SRC_DISP1_0, 16, 4),
 	MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_DISP1_0, 20, 1),

-- 
2.53.0



^ permalink raw reply related

* [PATCH 3/5] dt-bindings: clock: samsung: Add fimd1 and vpll muxes
From: Lukas Timmermann @ 2026-04-23 21:14 UTC (permalink / raw)
  To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Thierry Reding, Sam Ravnborg,
	Douglas Anderson, Krzysztof Kozlowski, Sylwester Nawrocki,
	Chanwoo Choi, Alim Akhtar, Michael Turquette, Stephen Boyd
  Cc: dri-devel, devicetree, linux-kernel, linux-samsung-soc, linux-clk,
	linux-arm-kernel, Lukas Timmermann
In-Reply-To: <20260423-manta-display-v1-0-196f80c5673a@timmermann.space>

Add two clocks necessary for the google-manta board
display.

Signed-off-by: Lukas Timmermann <linux@timmermann.space>
---
 include/dt-bindings/clock/exynos5250.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/dt-bindings/clock/exynos5250.h b/include/dt-bindings/clock/exynos5250.h
index 2337c028bbe1..93122823c04d 100644
--- a/include/dt-bindings/clock/exynos5250.h
+++ b/include/dt-bindings/clock/exynos5250.h
@@ -176,5 +176,7 @@
 #define CLK_MOUT_APLL		1028
 #define CLK_MOUT_MPLL		1029
 #define CLK_MOUT_VPLLSRC	1030
+#define CLK_MOUT_FIMD1		1031
+#define CLK_MOUT_VPLL		1032
 
 #endif /* _DT_BINDINGS_CLOCK_EXYNOS_5250_H */

-- 
2.53.0



^ permalink raw reply related

* [PATCH 2/5] drm/panel-edp: Add support for Samsung LTL101DL02-002 panel
From: Lukas Timmermann @ 2026-04-23 21:14 UTC (permalink / raw)
  To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Thierry Reding, Sam Ravnborg,
	Douglas Anderson, Krzysztof Kozlowski, Sylwester Nawrocki,
	Chanwoo Choi, Alim Akhtar, Michael Turquette, Stephen Boyd
  Cc: dri-devel, devicetree, linux-kernel, linux-samsung-soc, linux-clk,
	linux-arm-kernel, Lukas Timmermann, Alexandre Marquet
In-Reply-To: <20260423-manta-display-v1-0-196f80c5673a@timmermann.space>

From: Alexandre Marquet <tb@a-marquet.fr>

Add a panel entry for the Samsung LTL101DL02-002 panel, as found in
Samsung Manta (Google Nexus 10).

Signed-off-by: Alexandre Marquet <tb@a-marquet.fr>
Signed-off-by: Lukas Timmermann <linux@timmermann.space>
---
 drivers/gpu/drm/panel/panel-edp.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c
index 415b894890ad..2004699db41b 100644
--- a/drivers/gpu/drm/panel/panel-edp.c
+++ b/drivers/gpu/drm/panel/panel-edp.c
@@ -1542,6 +1542,34 @@ static const struct panel_desc samsung_lsn122dl01_c01 = {
 	},
 };
 
+static const struct drm_display_mode samsung_ltl101dl02_002_mode = {
+	.clock = 268627,
+	.hdisplay = 2560,
+	.hsync_start = 2560 + 48,
+	.hsync_end = 2560 + 48 + 32,
+	.htotal = 2560 + 48 + 32 + 80,
+	.vdisplay = 1600,
+	.vsync_start = 1600 + 3,
+	.vsync_end = 1600 + 3 + 6,
+	.vtotal = 1600 + 3 + 6 + 37,
+	.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
+};
+
+static const struct panel_desc samsung_ltl101dl02_002 = {
+	.modes = &samsung_ltl101dl02_002_mode,
+	.num_modes = 1,
+	.bpc = 6,
+	.size = {
+		.width = 218,
+		.height = 136,
+	},
+	.delay = {
+		.hpd_absent = 200,
+		.unprepare = 500,
+	},
+
+};
+
 static const struct drm_display_mode samsung_ltn140at29_301_mode = {
 	.clock = 76300,
 	.hdisplay = 1366,
@@ -1696,6 +1724,9 @@ static const struct of_device_id platform_of_match[] = {
 	}, {
 		.compatible = "samsung,lsn122dl01-c01",
 		.data = &samsung_lsn122dl01_c01,
+	}, {
+		.compatible = "samsung,ltl101dl02-002",
+		.data = &samsung_ltl101dl02_002,
 	}, {
 		.compatible = "samsung,ltn140at29-301",
 		.data = &samsung_ltn140at29_301,

-- 
2.53.0



^ permalink raw reply related

* [PATCH 1/5] dt-bindings: display: panel: Document Samsung LTL101DL02-002 panel
From: Lukas Timmermann @ 2026-04-23 21:14 UTC (permalink / raw)
  To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Thierry Reding, Sam Ravnborg,
	Douglas Anderson, Krzysztof Kozlowski, Sylwester Nawrocki,
	Chanwoo Choi, Alim Akhtar, Michael Turquette, Stephen Boyd
  Cc: dri-devel, devicetree, linux-kernel, linux-samsung-soc, linux-clk,
	linux-arm-kernel, Lukas Timmermann, Alexandre Marquet
In-Reply-To: <20260423-manta-display-v1-0-196f80c5673a@timmermann.space>

From: Alexandre Marquet <tb@a-marquet.fr>

Add the dt-bindings for the LTL101DL02-002 panel.

Signed-off-by: Alexandre Marquet <tb@a-marquet.fr>
Signed-off-by: Lukas Timmermann	<linux@timmermann.space>
---
 Documentation/devicetree/bindings/display/panel/panel-simple.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
index 24e277b19094..2de0a3a6d1fe 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -283,6 +283,8 @@ properties:
         # Samsung Electronics 10.6" FWXGA (1366x768) TFT LCD panel
       - samsung,ltl106al01
         # Samsung Electronics 10.1" WSVGA TFT LCD panel
+      - samsung,ltl101dl02-002
+        # Samsung Electronics 10.1" WQXGA (2560x1600) TFT LCD panel
       - samsung,ltn101nt05
         # Satoz SAT050AT40H12R2 5.0" WVGA TFT LCD panel
       - satoz,sat050at40h12r2

-- 
2.53.0



^ permalink raw reply related

* [PATCH 0/5] Google Nexus 10 display support
From: Lukas Timmermann @ 2026-04-23 21:14 UTC (permalink / raw)
  To: Neil Armstrong, Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Thierry Reding, Sam Ravnborg,
	Douglas Anderson, Krzysztof Kozlowski, Sylwester Nawrocki,
	Chanwoo Choi, Alim Akhtar, Michael Turquette, Stephen Boyd
  Cc: dri-devel, devicetree, linux-kernel, linux-samsung-soc, linux-clk,
	linux-arm-kernel, Lukas Timmermann, Alexandre Marquet

This patch series adds display support to the
Nexus 10 (google-manta) tablet. 

The panel can be used with the panel-edp 
driver and just had to be added.

Also needed for display output were two clocks which had to be defined.

This patch series depends on previous patches which are
currently only found in linux-next.
See: https://lore.kernel.org/all/177214038655.341086.4114348823043257597.b4-ty@kernel.org/

Signed-off-by: Lukas Timmermann <linux@timmermann.space>
---
Alexandre Marquet (2):
      dt-bindings: display: panel: Document Samsung LTL101DL02-002 panel
      drm/panel-edp: Add support for Samsung LTL101DL02-002 panel

Lukas Timmermann (3):
      dt-bindings: clock: samsung: Add fimd1 and vpll muxes
      clk: samsung: exynos5250: Define more clocks
      ARM: dts: exynos: Add display support for exynos5250-manta

 .../bindings/display/panel/panel-simple.yaml       |  2 +
 arch/arm/boot/dts/samsung/exynos5250-manta.dts     | 99 ++++++++++++++++++++++
 drivers/clk/samsung/clk-exynos5250.c               |  6 +-
 drivers/gpu/drm/panel/panel-edp.c                  | 31 +++++++
 include/dt-bindings/clock/exynos5250.h             |  2 +
 5 files changed, 137 insertions(+), 3 deletions(-)
---
base-commit: 6d130a71abb393ce99b081e78783581bd3b5985b
change-id: 20260423-manta-display-55781039fb0d

Best regards,
--  
Lukas Timmermann <linux@timmermann.space>



^ permalink raw reply

* Re: [REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
From: Thomas Gleixner @ 2026-04-23 21:03 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Mathias Stearn, Peter Zijlstra, Mathieu Desnoyers,
	Catalin Marinas, Will Deacon, Boqun Feng, Paul E. McKenney,
	Chris Kennelly, Dmitry Vyukov, regressions, linux-kernel,
	linux-arm-kernel, Ingo Molnar, Mark Rutland, Jinjie Ruan,
	Blake Oler
In-Reply-To: <CAHk-=wjsEqWJxXArS-P5+ksSY2Apaox8u6FtUrtyWSBEOL4Q2Q@mail.gmail.com>

On Thu, Apr 23 2026 at 10:41, Linus Torvalds wrote:
> If that rule was actually an important part of the ABI, it shouldn't
> have been a debug thing.

It's a debug thing because it's too expensive to be enabled by
default. And it's actually valuable for validating RSEQ critical section
ABI correctness as they can't be single stepped with a debugger as the
break point interruption would immediately canceled.

> So:
>
>  (a) the debug code in question needs to just be removed, since it's
> now actively detrimental, and means that any kernel developer who
> *does* enable it can't actually test this case any more. It's checking
> for something that has been shown to not be true.
>
>  (b) we need to fix this (revert if it can't be fixed otherwise)
>
> I see some patches flying around, but am not clear on whether there
> was an actual patch that make this work again?

There are two issues:

  1) ARM64

     On ARM64 RSEQ got broken completely with the partial move to the
     generic entry code. There are patches flying around which "fix" it
     and Mark is working on a more complete solution as there are other
     subtle issues with that aside of the obvious RSEQ wreckage. The
     latter could have been detected with the existing RSEQ selftests if
     any CI would actually run them on -next.

     That's uninteresting and unrelated to the tcmalloc issue. It's just
     a boring bug which will be fixed in the next couple of days.


  2) The tcmalloc problem

     That's a known problem for at least 6 years. tcmalloc assumes that
     it "owns" rseq and can do whatever it wants with it.

     In 2022 the glibc people requested that tcmalloc becomes
     interoperable with the reasonable expection of glibc to utilize
     rseq as well:

          https://github.com/google/tcmalloc/issues/144

     Status unresolved.

     That means that using tcmalloc requires to tell glibc to _NOT_ use
     rseq and at the same time precludes any other library which wants
     to use it for the documented purposes. So this code sequence blows
     up in your face:

        x = tcmalloc();
        dostuff(x)
          evaluate(rseq::cpu_id_start, rseq::cpu_id)

     because tcmalloc overwrites rseq::cpu_id_start and thereby breaks
     the ABI which evaluate() is rightfully depending on.

     That has absolutely nothing to do with the kernel as there is no
     kernel interaction between tcmalloc's abuse and the subsequent
     evaluation of rseq::cpu_id_start. The kernel has no way to fix that
     problem at all.

     Now back to your generally correct and agreed on "observed
     behaviour" rule.

     Feel free to enforce it, but be aware that you thereby set a
     precedence that a single abuser can then rightfully own a general
     shared interface of the kernel forever and force everybody else to
     give up.

     The tcmalloc developers actually documented that they own the
     world:

     // Note: this makes __rseq_abi.cpu_id_start unusable for its original purpose.

     Do you seriously want to proliferate that?

Thanks,

        tglx





^ permalink raw reply

* Re: [PATCH] cpu/hotplug: Fix NULL kobject warning in cpuhp_smt_enable()
From: Catalin Marinas @ 2026-04-23 20:11 UTC (permalink / raw)
  To: Jinjie Ruan
  Cc: Thomas Gleixner, peterz, sudeep.holla, yangyicong,
	dietmar.eggemann, Jonathan.Cameron, linux-kernel, James Morse,
	linux-arm-kernel
In-Reply-To: <78515da3-03a1-4fdb-a606-3fea9f4cd20b@huawei.com>

On Thu, Apr 23, 2026 at 08:32:34PM +0800, Jinjie Ruan wrote:
> On 4/23/2026 6:08 PM, Thomas Gleixner wrote:
> > On Sat, Apr 18 2026 at 12:55, Catalin Marinas wrote:
> >> Another option would have been to avoid marking such CPUs present but I
> >> think this will break other things. Yet another option is to register
> >> all CPU devices even if they never come up (like maxcpus greater than
> >> actual CPUs).
> >>
> >> Opinions? It might be an arm64+ACPI-only thing.
> > 
> > I think so. The proper thing to do is to apply sane limits:
> > 
> >  1) The possible CPUs enumerated by firmware N_POSSIBLE_FW
> > 
> >  2) The maxcpus limit on the command line N_MAXCPUS_CL
> > 
> > So the actual possible CPUs evaluates to:
> > 
> >    num_possible = min(N_POSSIBLE_FW, N_MAXCPUS_CL, CONFIG_NR_CPUS);
> > 
> > The evaluation of the firmware should not mark CPUs present which are
> > actually not. ACPI gives you that information. See:
> > 
> >          5.2.12.14 GIC CPU Interface (GICC) Structure
> > 
> > in the ACPI spec. That has two related bits:
> > 
> > Enabled:
> > 
> >    If this bit is set, the processor is ready for use. If this bit is
> >    clear and the Online Capable bit is set, the system supports enabling
> >    this processor during OS runtime. If this bit is clear and the Online
> >    Capable bit is also clear, this processor is un- usable, and the
> >    operating system support will not attempt to use it.
> > 
> > Online Capable:
> > 
> >    The information conveyed by this bit depends on the value of the
> >    Enabled bit. If the Enabled bit is set, this bit is reserved and must
> >    be zero. Otherwise, if this bit is set, the system supports enabling
> >    this processor later during OS runtime
> > 
> > So the combination of those gives you the right answer:
> > 
> >    Enabled	Online
> >    	        Capable
> >    0            0        Not present, not possible
> >    0            1        Not present, but possible to "hotplug" layter
> >    1            0        Present
> >    1            1        Invalid
> 
> On x86, it seems that all CPUs with the ACPI_MADT_ENABLED bit set will
> be marked as present.
> 
> acpi_parse_x2apic()
>   -> enabled = processor->lapic_flags & ACPI_MADT_ENABLED
>   -> topology_register_apic(enabled)
>      -> topo_register_apic(enabled)
>         -> set_cpu_present(cpu, true)

Yes but arm64 marks all CPUs present even if !ACPI_MADT_ENABLED as we
don't have the notion of hardware CPU hotplug.

I need to dig some more into the original vCPU hotplug support and why
we ended up with all CPUs marked as present even if not calling
register_cpu():

https://lore.kernel.org/linux-arm-kernel/20240529133446.28446-1-Jonathan.Cameron@huawei.com/

What's the MADT GICC provided by qemu with "-smp cpus=4,maxcpus=8"? If
it says Enabled for the first 4 and Online Capable for the rest, maybe
we can try something like below:

----------------------8<-----------------
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index 5891f92c2035..681aa2bbc399 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -448,12 +448,14 @@ int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 apci_id,
 		return *pcpu;
 	}
 
+	set_cpu_present(*pcpu, true);
 	return 0;
 }
 EXPORT_SYMBOL(acpi_map_cpu);
 
 int acpi_unmap_cpu(int cpu)
 {
+	set_cpu_present(cpu, false);
 	return 0;
 }
 EXPORT_SYMBOL(acpi_unmap_cpu);
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 1aa324104afb..6421027669fc 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -566,6 +566,11 @@ struct acpi_madt_generic_interrupt *acpi_cpu_get_madt_gicc(int cpu)
 }
 EXPORT_SYMBOL_GPL(acpi_cpu_get_madt_gicc);
 
+static bool acpi_cpu_is_present(int cpu)
+{
+	return acpi_cpu_get_madt_gicc(cpu)->flags & ACPI_MADT_ENABLED;
+}
+
 /*
  * acpi_map_gic_cpu_interface - parse processor MADT entry
  *
@@ -670,6 +675,11 @@ static void __init acpi_parse_and_init_cpus(void)
 		early_map_cpu_to_node(i, acpi_numa_get_nid(i));
 }
 #else
+static bool acpi_cpu_is_present(int cpu)
+{
+	return false;
+}
+
 #define acpi_parse_and_init_cpus(...)	do { } while (0)
 #endif
 
@@ -808,7 +818,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 		if (err)
 			continue;
 
-		set_cpu_present(cpu, true);
+		if (acpi_disabled || acpi_cpu_is_present(cpu))
+			set_cpu_present(cpu, true);
 		numa_store_cpu_info(cpu);
 	}
 }


^ permalink raw reply related

* [PATCH v3 2/3] drm/exynos: remove bridge when component_add fails
From: Osama Abdelkader @ 2026-04-23 20:06 UTC (permalink / raw)
  To: luca.ceresoli, Inki Dae, Seung-Woo Kim, Kyungmin Park,
	David Airlie, Simona Vetter, Krzysztof Kozlowski, Alim Akhtar,
	Andrzej Hajda, Hoegeun Kwon, dri-devel, linux-arm-kernel,
	linux-samsung-soc, linux-kernel
  Cc: Osama Abdelkader, stable
In-Reply-To: <20260423200622.325076-1-osama.abdelkader@gmail.com>

Use devm_drm_bridge_add() so the bridge is released if probe fails after
registration, and drop the manual drm_bridge_remove() in remove().

Check the return value of devm_drm_bridge_add().

Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com>
Fixes: 576d72fbfb45 ("drm/exynos: mic: add a bridge at probe")
Cc: stable@vger.kernel.org
---
v3: add Fixes and Cc tags
v2: devm_drm_bridge_add instead of drm_bridge_add + goto remove_bridge
---
 drivers/gpu/drm/exynos/exynos_drm_mic.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c
index 29a8366513fa..e68c954ec3e6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_mic.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
@@ -423,7 +423,9 @@ static int exynos_mic_probe(struct platform_device *pdev)
 
 	mic->bridge.of_node = dev->of_node;
 
-	drm_bridge_add(&mic->bridge);
+	ret = devm_drm_bridge_add(dev, &mic->bridge);
+	if (ret)
+		goto err;
 
 	pm_runtime_enable(dev);
 
@@ -443,12 +445,8 @@ static int exynos_mic_probe(struct platform_device *pdev)
 
 static void exynos_mic_remove(struct platform_device *pdev)
 {
-	struct exynos_mic *mic = platform_get_drvdata(pdev);
-
 	component_del(&pdev->dev, &exynos_mic_component_ops);
 	pm_runtime_disable(&pdev->dev);
-
-	drm_bridge_remove(&mic->bridge);
 }
 
 static const struct of_device_id exynos_mic_of_match[] = {
-- 
2.43.0



^ permalink raw reply related

* Re: [PATCH rc v2 0/5] iommu/arm-smmu-v3: Fix device crash on kdump kernel
From: Nicolin Chen @ 2026-04-23 20:02 UTC (permalink / raw)
  To: will, robin.murphy, jgg, kevin.tian
  Cc: joro, praan, baolu.lu, miko.lenczewski, smostafa,
	linux-arm-kernel, iommu, linux-kernel, stable, jamien
In-Reply-To: <cover.1776286352.git.nicolinc@nvidia.com>

On Wed, Apr 15, 2026 at 02:17:35PM -0700, Nicolin Chen wrote:
> This is on Github:
> https://github.com/nicolinc/iommufd/commits/smmuv3_kdump-v2
> 
> Changelog
> v2
>  * Add warning in non-coherent SMMU cases
>  * Keep eventq/priq disabled v.s. enabling-and-disabling-later
>  * Check KDUMP option in the beginning of arm_smmu_device_reset()
>  * Validate STRTAB format matches HW capability instead of forcing flags

https://sashiko.dev/#/patchset/cover.1776286352.git.nicolinc%40nvidia.com

Sashiko posted a few comments, mostly valid.

I am fixing them with a v3.

Thanks
Nicolin


^ permalink raw reply

* [PATCH v4 30/58] perf flamegraph: Port flamegraph to use python module
From: Ian Rogers @ 2026-04-23 19:43 UTC (permalink / raw)
  To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
  Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
	linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260423194428.1846255-1-irogers@google.com>

Add a port of the flamegraph script that uses the perf python module
directly. This approach is significantly faster than using perf script
callbacks as it avoids creating intermediate dictionaries for all
event fields.

Assisted-by: Gemini:gemini-3.1-pro-preview
Signed-off-by: Ian Rogers <irogers@google.com>
---
v2:

1. Performance Optimization: Changed Node.children from a list to a
   dictionary, reducing the lookup time in find_or_create_node from
   O(N) to O(1) and avoiding performance bottlenecks on wide call
   graphs.

2. Callchain Fallback: Added a fallback to use the sample's top-level
   symbol or instruction pointer if no callchain is present, ensuring
   the script still generates meaningful output rather than just
   process names.

3. Template Downloading Fix: Corrected the logic handling the
   --allow-download flag and custom HTTP URLs. It no longer warns
   about missing local files when a URL is provided, and won't
   silently overwrite custom URLs with the default one.

4. Output Stream Separation: Moved informational warnings to
   sys.stderr to prevent them from corrupting the resulting HTML/JSON
   file when the user streams the output to stdout (e.g., using -o -
   ).

5. XSS Protection: Added basic HTML entity escaping for < , > , and &
   within the embedded JSON data blocks. This mitigates the risk of
   cross-site scripting if trace data contains maliciously formed
   process or symbol names.
---
 tools/perf/python/flamegraph.py | 250 ++++++++++++++++++++++++++++++++
 1 file changed, 250 insertions(+)
 create mode 100755 tools/perf/python/flamegraph.py

diff --git a/tools/perf/python/flamegraph.py b/tools/perf/python/flamegraph.py
new file mode 100755
index 000000000000..f3f69e5a88c2
--- /dev/null
+++ b/tools/perf/python/flamegraph.py
@@ -0,0 +1,250 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+"""
+flamegraph.py - create flame graphs from perf samples using perf python module
+"""
+
+import argparse
+import hashlib
+import json
+import os
+import subprocess
+import sys
+import urllib.request
+from typing import Dict, Optional, Union
+import perf
+
+MINIMAL_HTML = """<head>
+  <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/d3-flame-graph@4.1.3/dist/d3-flamegraph.css">
+</head>
+<body>
+  <div id="chart"></div>
+  <script type="text/javascript" src="https://d3js.org/d3.v7.js"></script>
+  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/d3-flame-graph@4.1.3/dist/d3-flamegraph.min.js"></script>
+  <script type="text/javascript">
+  const stacks = [/** @flamegraph_json **/];
+  // Note, options is unused.
+  const options = [/** @options_json **/];
+
+  var chart = flamegraph();
+  d3.select("#chart")
+        .datum(stacks[0])
+        .call(chart);
+  </script>
+</body>
+"""
+
+class Node:
+    """A node in the flame graph tree."""
+    def __init__(self, name: str, libtype: str):
+        self.name = name
+        self.libtype = libtype
+        self.value: int = 0
+        self.children: dict[str, Node] = {}
+
+    def to_json(self) -> Dict[str, Union[str, int, list[Dict]]]:
+        """Convert the node to a JSON-serializable dictionary."""
+        return {
+            "n": self.name,
+            "l": self.libtype,
+            "v": self.value,
+            "c": [x.to_json() for x in self.children.values()]
+        }
+
+
+class FlameGraphCLI:
+    """Command-line interface for generating flame graphs."""
+    def __init__(self, args):
+        self.args = args
+        self.stack = Node("all", "root")
+        self.session = None
+
+    @staticmethod
+    def get_libtype_from_dso(dso: Optional[str]) -> str:
+        """Determine the library type from the DSO name."""
+        if dso and (dso == "[kernel.kallsyms]" or dso.endswith("/vmlinux") or dso == "[kernel]"):
+            return "kernel"
+        return ""
+
+    @staticmethod
+    def find_or_create_node(node: Node, name: str, libtype: str) -> Node:
+        """Find a child node with the given name or create a new one."""
+        if name in node.children:
+            return node.children[name]
+        child = Node(name, libtype)
+        node.children[name] = child
+        return child
+
+    def process_event(self, sample) -> None:
+        """Process a single perf sample event."""
+        if self.args.event_name and str(sample.evsel) != self.args.event_name:
+            return
+
+        pid = sample.sample_pid
+        dso_type = ""
+        try:
+            thread = self.session.process(sample.sample_tid)
+            comm = thread.comm()
+        except Exception:
+            comm = "[unknown]"
+
+        if pid == 0:
+            comm = "swapper"
+            dso_type = "kernel"
+        else:
+            comm = f"{comm} ({pid})"
+
+        node = self.find_or_create_node(self.stack, comm, dso_type)
+
+        callchain = sample.callchain
+        if callchain:
+            # We want to traverse from root to leaf.
+            # perf callchain iterator gives leaf to root.
+            # We collect them and reverse.
+            frames = list(callchain)
+            for entry in reversed(frames):
+                name = entry.symbol or "[unknown]"
+                libtype = self.get_libtype_from_dso(entry.dso)
+                node = self.find_or_create_node(node, name, libtype)
+        else:
+            # Fallback if no callchain
+            name = getattr(sample, "symbol", "[unknown]")
+            libtype = self.get_libtype_from_dso(getattr(sample, "dso", "[unknown]"))
+            node = self.find_or_create_node(node, name, libtype)
+
+        node.value += 1
+
+    def get_report_header(self) -> str:
+        """Get the header from the perf report."""
+        try:
+            input_file = self.args.input or "perf.data"
+            output = subprocess.check_output(["perf", "report", "--header-only", "-i", input_file])
+            result = output.decode("utf-8")
+            if self.args.event_name:
+                result += "\nFocused event: " + self.args.event_name
+            return result
+        except Exception:
+            return ""
+
+    def run(self) -> None:
+        """Run the flame graph generation."""
+        input_file = self.args.input or "perf.data"
+        if not os.path.exists(input_file):
+            print(f"Error: {input_file} not found. (try 'perf record' first)", file=sys.stderr)
+            sys.exit(1)
+
+        try:
+            self.session = perf.session(perf.data(input_file),
+                                        sample=self.process_event)
+        except Exception as e:
+            print(f"Error opening session: {e}", file=sys.stderr)
+            sys.exit(1)
+
+        self.session.process_events()
+
+        stacks_json = json.dumps(self.stack, default=lambda x: x.to_json())
+        # Escape HTML special characters to prevent XSS
+        stacks_json = stacks_json.replace("<", "\\u003c") \
+            .replace(">", "\\u003e").replace("&", "\\u0026")
+
+        if self.args.format == "html":
+            report_header = self.get_report_header()
+            options = {
+                "colorscheme": self.args.colorscheme,
+                "context": report_header
+            }
+            options_json = json.dumps(options)
+            options_json = options_json.replace("<", "\\u003c") \
+                .replace(">", "\\u003e").replace("&", "\\u0026")
+
+            template = self.args.template
+            template_md5sum = None
+            output_str = None
+
+            if not os.path.isfile(template):
+                if template.startswith("http://") or template.startswith("https://"):
+                    if not self.args.allow_download:
+                        print("Warning: Downloading templates is disabled. "
+                              "Use --allow-download.", file=sys.stderr)
+                        template = None
+                else:
+                    print(f"Warning: Template file '{template}' not found.", file=sys.stderr)
+                    if self.args.allow_download:
+                        print("Using default CDN template.", file=sys.stderr)
+                        template = (
+                            "https://cdn.jsdelivr.net/npm/d3-flame-graph@4.1.3/dist/templates/"
+                            "d3-flamegraph-base.html"
+                        )
+                        template_md5sum = "143e0d06ba69b8370b9848dcd6ae3f36"
+                    else:
+                        template = None
+
+            use_minimal = False
+            try:
+                if not template:
+                    use_minimal = True
+                elif template.startswith("http"):
+                    with urllib.request.urlopen(template) as url_template:
+                        output_str = "".join([l.decode("utf-8") for l in url_template.readlines()])
+                else:
+                    with open(template, "r", encoding="utf-8") as f:
+                        output_str = f.read()
+            except Exception as err:
+                print(f"Error reading template {template}: {err}\n", file=sys.stderr)
+                use_minimal = True
+
+            if use_minimal:
+                print("Using internal minimal HTML that refers to d3's web site. JavaScript " +
+                      "loaded this way from a local file may be blocked unless your " +
+                      "browser has relaxed permissions. Run with '--allow-download' to fetch" +
+                      "the full D3 HTML template.", file=sys.stderr)
+                output_str = MINIMAL_HTML
+
+            elif template_md5sum:
+                assert output_str is not None
+                download_md5sum = hashlib.md5(output_str.encode("utf-8")).hexdigest()
+                if download_md5sum != template_md5sum:
+                    s = None
+                    while s not in ["y", "n"]:
+                        s = input(f"""Unexpected template md5sum.
+{download_md5sum} != {template_md5sum}, for:
+{output_str}
+continue?[yn] """).lower()
+                    if s == "n":
+                        sys.exit(1)
+
+            assert output_str is not None
+            output_str = output_str.replace("/** @options_json **/", options_json)
+            output_str = output_str.replace("/** @flamegraph_json **/", stacks_json)
+            output_fn = self.args.output or "flamegraph.html"
+        else:
+            output_str = stacks_json
+            output_fn = self.args.output or "stacks.json"
+
+        if output_fn == "-":
+            sys.stdout.write(output_str)
+        else:
+            print(f"dumping data to {output_fn}")
+            with open(output_fn, "w", encoding="utf-8") as out:
+                out.write(output_str)
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description="Create flame graphs using perf python module.")
+    parser.add_argument("-f", "--format", default="html", choices=["json", "html"],
+                        help="output file format")
+    parser.add_argument("-o", "--output", help="output file name")
+    parser.add_argument("--template",
+                        default="/usr/share/d3-flame-graph/d3-flamegraph-base.html",
+                        help="path to flame graph HTML template")
+    parser.add_argument("--colorscheme", default="blue-green",
+                        help="flame graph color scheme", choices=["blue-green", "orange"])
+    parser.add_argument("-i", "--input", help="input perf.data file")
+    parser.add_argument("--allow-download", default=False, action="store_true",
+                        help="allow unprompted downloading of HTML template")
+    parser.add_argument("-e", "--event", default="", dest="event_name", type=str,
+                        help="specify the event to generate flamegraph for")
+
+    cli_args = parser.parse_args()
+    cli = FlameGraphCLI(cli_args)
+    cli.run()
-- 
2.54.0.rc2.533.g4f5dca5207-goog



^ permalink raw reply related

* [PATCH v4 29/58] perf futex-contention: Port futex-contention to use python module
From: Ian Rogers @ 2026-04-23 19:43 UTC (permalink / raw)
  To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
  Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
	linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260423194428.1846255-1-irogers@google.com>

Rewrite tools/perf/scripts/python/futex-contention.py to use the
python module and various style changes. By avoiding the overheads in
the `perf script` execution the performance improves by more than 3.2x
as shown in the following (with PYTHON_PATH and PERF_EXEC_PATH set as
necessary):

```
$ perf record -e syscalls:sys_*_futex -a sleep 1
...
$ time perf script tools/perf/scripts/python/futex-contention.py
Install the python-audit package to get syscall names.
For example:
  # apt-get install python3-audit (Ubuntu)
  # yum install python3-audit (Fedora)
  etc.

Press control+C to stop and show the summary
aaa/4[2435653] lock 7f76b380c878 contended 1 times, 1099 avg ns [max: 1099 ns, min 1099 ns]
...
real    0m1.007s
user    0m0.935s
sys     0m0.072s
$ time python3 tools/perf/python/futex-contention.py
...
real    0m0.314s
user    0m0.259s
sys     0m0.056s
```

Assisted-by: Gemini:gemini-3.1-pro-preview
Signed-off-by: Ian Rogers <irogers@google.com>
---
v2:

1. Fixed Module Import Failure: Corrected the type annotations from
   [int, int] to Tuple[int, int] .  The previous code would raise a
   TypeError at module import time because lists cannot be used as
   types in dictionary annotations.

2. Prevented Out-Of-Memory Crashes: Replaced the approach of storing
   every single duration in a list with a LockStats class that
   maintains running aggregates (count, total time, min, max). This
   ensures O(1) memory usage per lock/thread pair rather than
   unbounded memory growth.

3. Support for Custom Input Files: Added a -i / --input command-line
   argument to support processing arbitrarily named trace files,
   removing the hardcoded "perf.data" restriction.

4. Robust Process Lookup: Added a check to ensure session is
   initialized before calling session.  process() , preventing
   potential NoneType attribute errors if events are processed during
   initialization.
---
 tools/perf/python/futex-contention.py | 87 +++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)
 create mode 100755 tools/perf/python/futex-contention.py

diff --git a/tools/perf/python/futex-contention.py b/tools/perf/python/futex-contention.py
new file mode 100755
index 000000000000..7c5c3d0ca60a
--- /dev/null
+++ b/tools/perf/python/futex-contention.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+"""Measures futex contention."""
+
+import argparse
+from collections import defaultdict
+from typing import Dict, Tuple
+import perf
+
+class LockStats:
+    """Aggregate lock contention information."""
+    def __init__(self) -> None:
+        self.count = 0
+        self.total_time = 0
+        self.min_time = 0
+        self.max_time = 0
+
+    def add(self, duration: int) -> None:
+        """Add a new duration measurement."""
+        self.count += 1
+        self.total_time += duration
+        if self.count == 1:
+            self.min_time = duration
+            self.max_time = duration
+        else:
+            self.min_time = min(self.min_time, duration)
+            self.max_time = max(self.max_time, duration)
+
+    def avg(self) -> float:
+        """Return average duration."""
+        return self.total_time / self.count if self.count > 0 else 0.0
+
+process_names: Dict[int, str] = {}
+start_times: Dict[int, Tuple[int, int]] = {}
+session = None
+durations: Dict[Tuple[int, int], LockStats] = defaultdict(LockStats)
+
+FUTEX_WAIT = 0
+FUTEX_WAKE = 1
+FUTEX_PRIVATE_FLAG = 128
+FUTEX_CLOCK_REALTIME = 256
+FUTEX_CMD_MASK = ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)
+
+
+def process_event(sample: perf.sample_event) -> None:
+    """Process a single sample event."""
+    def handle_start(tid: int, uaddr: int, op: int, start_time: int) -> None:
+        if (op & FUTEX_CMD_MASK) != FUTEX_WAIT:
+            return
+        if tid not in process_names:
+            try:
+                if session:
+                    process = session.process(tid)
+                    if process:
+                        process_names[tid] = process.comm()
+            except (TypeError, AttributeError):
+                return
+        start_times[tid] = (uaddr, start_time)
+
+    def handle_end(tid: int, end_time: int) -> None:
+        if tid not in start_times:
+            return
+        (uaddr, start_time) = start_times[tid]
+        del start_times[tid]
+        durations[(tid, uaddr)].add(end_time - start_time)
+
+    event_name = str(sample.evsel)
+    if event_name == "evsel(syscalls:sys_enter_futex)":
+        uaddr = getattr(sample, "uaddr", 0)
+        op = getattr(sample, "op", 0)
+        handle_start(sample.sample_tid, uaddr, op, sample.sample_time)
+    elif event_name == "evsel(syscalls:sys_exit_futex)":
+        handle_end(sample.sample_tid, sample.sample_time)
+
+
+if __name__ == "__main__":
+    ap = argparse.ArgumentParser(description="Measure futex contention")
+    ap.add_argument("-i", "--input", default="perf.data", help="Input file name")
+    args = ap.parse_args()
+
+    session = perf.session(perf.data(args.input), sample=process_event)
+    session.process_events()
+
+    for ((t, u), stats) in sorted(durations.items()):
+        avg_ns = stats.avg()
+        print(f"{process_names.get(t, 'unknown')}[{t}] lock {u:x} contended {stats.count} times, "
+              f"{avg_ns:.0f} avg ns [max: {stats.max_time} ns, min {stats.min_time} ns]")
-- 
2.54.0.rc2.533.g4f5dca5207-goog



^ permalink raw reply related

* [PATCH v4 28/58] perf syscall-counts-by-pid: Port syscall-counts-by-pid to use python module
From: Ian Rogers @ 2026-04-23 19:43 UTC (permalink / raw)
  To: acme, adrian.hunter, james.clark, leo.yan, namhyung, tmricht
  Cc: alice.mei.rogers, dapeng1.mi, linux-arm-kernel, linux-kernel,
	linux-perf-users, mingo, peterz, Ian Rogers
In-Reply-To: <20260423161006.1762700-1-irogers@google.com>

Rewrite tools/perf/scripts/python/syscall-counts-by-pid.py to use the
python module and various style changes. By avoiding the overheads in
the `perf script` execution the performance improves by more than 3.8x
as shown in the following (with PYTHON_PATH and PERF_EXEC_PATH set as
necessary):

```
$ perf record -e raw_syscalls:sys_enter -a sleep 1
...
$ time perf script tools/perf/scripts/python/syscall-counts-by-pid.py perf
Install the python-audit package to get syscall names.
For example:
  # apt-get install python3-audit (Ubuntu)
  # yum install python3-audit (Fedora)
  etc.

Press control+C to stop and show the summary
Warning:
1 out of order events recorded.

syscall events for perf:

comm [pid]/syscalls                            count
 ---------------------------------------  ----------

perf [3886080]
  1                                           538989
  16                                              32
  203                                             17
  3                                                2
  257                                              1
  204                                              1
  15                                               1
  0                                                1

perf [3886082]
  7                                                1

real    0m3.852s
user    0m3.512s
sys     0m0.336s
$ time python3 tools/perf/python/syscall-counts-by-pid.py perf
Warning:
1 out of order events recorded.

syscall events for perf:

comm [pid]/syscalls                           count
 --------------------------------------- -----------

perf [3886080]
  write                                      538989
  ioctl                                          32
  sched_setaffinity                              17
  close                                           2
  openat                                          1
  sched_getaffinity                               1
  rt_sigreturn                                    1
  read                                            1

perf [3886082]
  poll                                            1

real    0m1.011s
user    0m0.963s
sys     0m0.048s
```

Assisted-by: Gemini:gemini-3.1-pro-preview
Signed-off-by: Ian Rogers <irogers@google.com>
---
v2:

1. Removed Unused Variable: Removed id_keys which was assigned but
   never read.

2. Fallback for Unknown Syscalls: If perf.syscall_name() returns None
   for an unmapped ID, it now falls back to the numeric ID string to
   prevent TypeError crashes during string formatting.

3. Fallback for Syscall Number Attribute: It now checks for
   __syscall_nr first, and if missing, falls back to checking for nr .

4. Robust Process Resolution: Added a try-except block around
   session.process(sample.pid).comm() to handle untracked PIDs
   gracefully instead of crashing on a TypeError .

5. Restored PID Filtering: The script now attempts to parse the
   positional argument as an integer to filter by Process ID. If that
   fails, it treats it as a command name (COMM) string to filter by,
   restoring behavior from the original legacy script.

6. Support for Custom Input Files: Added a -i / --input command-line
   argument to support arbitrarily named trace files, removing the
   hardcoded "perf.data" restriction.
---
 tools/perf/python/syscall-counts-by-pid.py | 88 ++++++++++++++++++++++
 1 file changed, 88 insertions(+)
 create mode 100755 tools/perf/python/syscall-counts-by-pid.py

diff --git a/tools/perf/python/syscall-counts-by-pid.py b/tools/perf/python/syscall-counts-by-pid.py
new file mode 100755
index 000000000000..45a98e6e8e01
--- /dev/null
+++ b/tools/perf/python/syscall-counts-by-pid.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+"""
+Displays system-wide system call totals, broken down by syscall.
+If a [comm] arg is specified, only syscalls called by [comm] are displayed.
+"""
+
+import argparse
+from collections import defaultdict
+import perf
+
+syscalls: dict[tuple[str, int, int], int] = defaultdict(int)
+for_comm = None
+for_pid = None
+session = None
+
+
+def print_syscall_totals():
+    """Print aggregated statistics."""
+    if for_comm is not None:
+        print(f"\nsyscall events for {for_comm}:\n")
+    elif for_pid is not None:
+        print(f"\nsyscall events for PID {for_pid}:\n")
+    else:
+        print("\nsyscall events:\n")
+
+    print(f"{'comm [pid]/syscalls':<40} {'count':>10}")
+    print("---------------------------------------- -----------")
+
+    sorted_keys = sorted(syscalls.keys(), key=lambda k: (k[0], k[1], k[2]))
+    current_comm_pid = None
+    for comm, pid, sc_id in sorted_keys:
+        if current_comm_pid != (comm, pid):
+            print(f"\n{comm} [{pid}]")
+            current_comm_pid = (comm, pid)
+        name = perf.syscall_name(sc_id) or str(sc_id)
+        print(f"  {name:<38} {syscalls[(comm, pid, sc_id)]:>10}")
+
+
+def process_event(sample):
+    """Process a single sample event."""
+    event_name = str(sample.evsel)
+    if event_name == "evsel(raw_syscalls:sys_enter)":
+        sc_id = getattr(sample, "id", -1)
+    elif event_name.startswith("evsel(syscalls:sys_enter_"):
+        sc_id = getattr(sample, "__syscall_nr", None)
+        if sc_id is None:
+            sc_id = getattr(sample, "nr", -1)
+    else:
+        return
+
+    if sc_id == -1:
+        return
+
+    pid = sample.sample_pid
+
+    if for_pid and pid != for_pid:
+        return
+
+    comm = "unknown"
+    try:
+        if session:
+            proc = session.process(pid)
+            if proc:
+                comm = proc.comm()
+    except (TypeError, AttributeError):
+        pass
+
+    if for_comm and comm != for_comm:
+        return
+    syscalls[(comm, pid, sc_id)] += 1
+
+
+if __name__ == "__main__":
+    ap = argparse.ArgumentParser()
+    ap.add_argument("filter", nargs="?", help="COMM or PID to filter by")
+    ap.add_argument("-i", "--input", default="perf.data", help="Input file name")
+    args = ap.parse_args()
+
+    if args.filter:
+        try:
+            for_pid = int(args.filter)
+        except ValueError:
+            for_comm = args.filter
+
+    session = perf.session(perf.data(args.input), sample=process_event)
+    session.process_events()
+    print_syscall_totals()
-- 
2.54.0.rc2.533.g4f5dca5207-goog



^ permalink raw reply related

* Re: [REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
From: Thomas Gleixner @ 2026-04-23 19:39 UTC (permalink / raw)
  To: Chris Kennelly
  Cc: Mathias Stearn, Peter Zijlstra, Mathieu Desnoyers,
	Catalin Marinas, Will Deacon, Boqun Feng, Paul E. McKenney,
	Dmitry Vyukov, regressions, linux-kernel, linux-arm-kernel,
	Ingo Molnar, Mark Rutland, Jinjie Ruan, Blake Oler,
	Linus Torvalds
In-Reply-To: <CAEE+yb=rZFxxOhCw+6wsUt5PE6=ebbKjEggQ_j_G3qSkMQZsfg@mail.gmail.com>

On Thu, Apr 23 2026 at 13:38, Chris Kennelly wrote:
> On Thu, Apr 23, 2026 at 1:19 PM Thomas Gleixner <tglx@kernel.org> wrote:
>>   3) The RO for userspace property has been enforced by RSEQ debugging
>>      mode since day one. If such a debug enabled kernel detects user
>>      space changing the field it kills the task/application.
>
> The optimization in TCMalloc that you're describing has been available
> since September 2023:
> https://github.com/google/tcmalloc/commit/aaa4fbf6fcdce1b7f86fcadd659874645c75ddb9

And the github issue which requested glibc compatibility was opened in
Sept. 2022:

      https://github.com/google/tcmalloc/issues/144

> I thought the RSEQ debug checks were added in December 2024:
> https://github.com/torvalds/linux/commit/7d5265ffcd8b41da5e09066360540d6e0716e9cd,
> but perhaps I misidentified the ones in question.

I might have misread the git log. But that still does not justify the
violation of a documented ABI for the price that nobody else can use it
once tcmalloc is in play:

   x = tcmalloc();
   dostuff(x)
     evaluate(rseq::cpu_id_start, rseq::cpu_id) <- FAIL

>>   7) tcmalloc violates the ABI from day one and has since refused to
>>      address the problem despite being offered a kernel side rseq
>>      extension to solve it many years ago.
>
> I know there was some discussion around a preemption notification
> scheme, rseq_sched_state; but I thought the discussion moved in favor
> of the timeslice extension interface that recently landed. Timeslice
> extension solves some use cases, but I'm not sure it addresses this
> one.

No it does not. That's an orthogonal optimization.

Thanks,

        tglx


^ permalink raw reply

* Re: [REGRESSION] rseq: refactoring in v6.19 broke everyone on arm64 and tcmalloc everywhere
From: Thomas Gleixner @ 2026-04-23 19:31 UTC (permalink / raw)
  To: Mathias Stearn
  Cc: Dmitry Vyukov, Jinjie Ruan, linux-man, Mark Rutland,
	Mathieu Desnoyers, Catalin Marinas, Will Deacon, Boqun Feng,
	Paul E. McKenney, Chris Kennelly, regressions, linux-kernel,
	linux-arm-kernel, Peter Zijlstra, Ingo Molnar, Blake Oler
In-Reply-To: <CAHnCjA0UBNXfjHw=Y34OrAyGRNUtVF+zWd3ugyX6pd_mCk8K9w@mail.gmail.com>

On Thu, Apr 23 2026 at 12:51, Mathias Stearn wrote:
> On Thu, Apr 23, 2026 at 12:39 PM Thomas Gleixner <tglx@linutronix.de> wrote:
>> The kernel clears rseq_cs reliably when user space was interrupted and:
>>
>>     the task was preempted
>> or
>>     the return from interrupt delivers a signal
>>
>> If the task invoked a syscall then there is absolutely no reason to do
>> either of this because syscalls from within a critical section are a
>> bug and catched when enabling rseq debugging.
>>
>> The original code did this along with unconditionally updating CPU/MMCID
>> which resulted in ~15% performance regression on a syscall heavy
>> database benchmark once glibc started to register rseq.
>
> Just to be clear TCMalloc does not need either rseq_cs to be cleared
> or cpu_id_start to be written to on syscalls because it doesn't do
> syscalls from critical sections. It will actually benefit (slightly)
> from not updating cpu_id_start on syscalls.

I know that it does not do syscalls from within critical sections, but
it relies on cpu_id_start being unconditionally updated in one way or
the other.

> It is specifically in the cases where an rseq would need to be aborted
> (preemption, signals, migration, and membarrier IPI with the rseq
> flag) that TCMalloc relies on cpu_id_start being written. It does rely
> on that write even when not inside the critical section, because it
> effectively uses that to detect if there were any would-cause-abort
> events in between two critical sections. But since it leaves the
> rseq_cs pointer non-null between critical sections, so you dont need
> to add _any_ overhead for programs that never make use of rseq after
> registration, or add any overhead to syscalls even for those who do.

Well. According to the comment in the tcmalloc code:

// Calculation of the address of the current CPU slabs region is needed for
// allocation/deallocation fast paths, but is quite expensive. Due to variable
// shift and experimental support for "virtual CPUs", the calculation involves
// several additional loads and dependent calculations. Pseudo-code for the
// address calculation is as follows:
//
//   cpu_offset = TcmallocSlab.virtual_cpu_id_offset_;
//   cpu = *(&__rseq_abi + virtual_cpu_id_offset_);
//   slabs_and_shift = TcmallocSlab.slabs_and_shift_;
//   shift = slabs_and_shift & kShiftMask;
//   shifted_cpu = cpu << shift;
//   slabs = slabs_and_shift & kSlabsMask;
//   slabs += shifted_cpu;
//
// To remove this calculation from fast paths, we cache the slabs address
// for the current CPU in thread local storage. However, when a thread is
// rescheduled to another CPU, we somehow need to understand that the cached

                  ^^^^^^^^^^^

// address is not valid anymore. To achieve this, we overlap the top 4 bytes
// of the cached address with __rseq_abi.cpu_id_start. When a thread is
// rescheduled the kernel overwrites cpu_id_start with the current CPU number,
// which gives us the signal that the cached address is not valid anymore.

The kernel still as of today (the arm64 bug aside) updates the
cpu_id_start and cpu_id fields in rseq when a task is rescheduled to
another CPU.

So if the code only requires to know when it got rescheduled to another
CPU then it still should work, no?

But it does not, which makes it clear that it relies on this
undocumented behaviour of the kernel to rewrite rseq::cpu_id_start
unconditionally. I'm not yet convinced that it relies on it only when
interrupted between two subsequent critical sections. We'll see.

....

Now we come to the best part of this comment:

// Note: this makes __rseq_abi.cpu_id_start unusable for its original purpose.

So any code sequence which ends up in:

   x = tcmalloc();
   dostuff(x)
     evaluate(rseq::cpu_id_start, rseq::cpu_id)

is doomed. This might be acceptable for Google internal usage where they
control the full stack and can prevent anyone else to utilize rseq, but
in an open ecosystem that's obviously a non-starter.

And they definitely forgot to add this to the comment:

// Never enable CONFIG_RSEQ_DEBUG in the kernel when you use tcmalloc as
// it will expose the blatant ABI abuse and therefore will kill your
// application.

If your assumption that the rewrite is only required when rseq::rseq_cs
is non NULL and user space was interrupted is correct, then the obvious
no-brainer would have been to add:

        __u64	rseq_usr_data;

to struct rseq and clear that unconditionally when rseq::rseq_cs is
cleared.

But that would have been too simple, would work independent of endianess
and not in the way of anybody else.

But I know that's incompatible with the features first, correctness
later and we own the world anyway mindset.

Just for giggles I asked Google Gemini about the implications of
tmalloc's rseq abuse. The answer is pretty clear:

   "In short, TCMalloc treats RSEQ as a private optimization rather than
    a shared system resource, which compromises the stability and
    extensibility of any application that needs RSEQ for anything other
    than memory allocation."

It's also very clear about the wilful ignorance of the tcmalloc people:

   "In summary, the developers have known for at least 6 years that the
    implementation was non-standard and conflicting with other rseq
    usage. The github issue which requested glibc compatibility was
    opened in 2022 and has been unresolved since then."

Thanks,

        tglx


^ permalink raw reply

* Re: [PATCH v11 00/14] barrier: Add smp_cond_load_{relaxed,acquire}_timeout()
From: Ankur Arora @ 2026-04-23 19:29 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ankur Arora, linux-kernel, linux-arch, linux-arm-kernel, linux-pm,
	bpf, arnd, catalin.marinas, will, peterz, mark.rutland, harisokn,
	cl, ast, rafael, daniel.lezcano, memxor, zhenglifeng1, xueshuai,
	rdunlap, david.laight.linux, joao.m.martins, boris.ostrovsky,
	konrad.wilk, ashok.bhat
In-Reply-To: <20260423101631.84f26592d629eee46fbde6f8@linux-foundation.org>


Andrew Morton <akpm@linux-foundation.org> writes:

> On Wed,  8 Apr 2026 17:55:24 +0530 Ankur Arora <ankur.a.arora@oracle.com> wrote:
>
>> The core kernel often uses smp_cond_load_{relaxed,acquire}() to spin
>> on condition variables with architectural primitives used to avoid
>> hammering the relevant cachelines.
>>
>> ...
>>
>> Accordingly add two interfaces (with their generic and arm64 specific
>> implementations):
>>
>>    smp_cond_load_relaxed_timeout(ptr, cond_expr, time_expr, timeout)
>>    smp_cond_load_acquire_timeout(ptr, cond_expr, time_expr, timeout)
>>
>> Also add tif_need_resched_relaxed_wait() which wraps the polling
>> pattern and its scheduler specific details in poll_idle().
>> In addition add atomic_cond_read_*_timeout(),
>
> Thanks, I'll add this to mm.git's mm-new branch today.

Great. Thanks!

> This isn't am MM patchset, but mm-new isn't included in linux-next, and
> linux-next isn't presently open for 7.1 material.
>
> After -rc1 I'll move the series into mm.git's mm-nonmm-unstable branch,
> where it will get linux-next exposure.

Ack that.

> I see that further review/comment has been requested - hopefully this
> will happen over the next couple of months, but please do continue to
> chase this down if you feel the need.

Will do.

>> Haris Okanovic also saw improvement in real workloads due to the
>> cpuidle changes: "observed 4-6% improvements in memcahed, cassandra,
>> mysql, and postgresql under certain loads. Other applications likely
>> benefit too." [12]
>
> Those are significant improvements.   Three years :(

Part of the reason was that the barrier interface was part of a series
focused on virtualization via cpuidle-haltpoll. As that was reviewed,
the tale changed in the telling, and it made more sense to separate
the two.

Will send out the cpuidle changes for review which Haris is running
with.

--
ankur


^ permalink raw reply

* [PATCH V1 3/3] iommu/arm-smmu-v3: Honor IORT Root Complex PASID descriptors
From: Vidya Sagar @ 2026-04-23 19:14 UTC (permalink / raw)
  To: rafael, lenb, saket.dumbre, lpieralisi, guohanjun, sudeep.holla,
	will, catalin.marinas, joro, robin.murphy, jgg, nicolinc, praan
  Cc: vsethi, sdonthineni, kthota, sagar.tv, linux-acpi,
	linux-arm-kernel, acpica-devel, iommu, linux-kernel, Vidya Sagar
In-Reply-To: <20260423191417.2031652-1-vidyas@nvidia.com>

The SMMUv3 driver currently calls pci_enable_pasid() for any PCI
master that exposes a PASID capability, regardless of whether the
upstream Root Complex actually supports PASID and regardless of the
RC's declared Max PASID Width. With IORT spec E.c (RC node revision
>= 4) firmware reports both, so we can do better:

  - If the IORT Root Complex node says PASID is not supported
    (Flags bit 0 == 0 at byte offset 36), enabling PASID on the
    endpoint is futile - the RC will not forward the PASID prefix to
    the SMMU - so skip pci_enable_pasid() silently.

  - If the IORT Root Complex node reports a Max PASID Width (bits[4:0]
    of PASID Capabilities at offset 33), clamp the endpoint's
    pci_max_pasids() result by 1 << width before computing the SMMU
    SSID width. This prevents master->ssid_bits from exceeding what
    the RC can actually carry.

Both behaviours are gated on iort_pci_rc_pasid_max_width_known(), i.e.
RC node revision >= 4, so platforms with older IORT firmware see no
behavioural change and continue to enable PASID purely on the basis
of the endpoint capability.

Use the new IOMMU_FWSPEC_PCI_RC_PASID fwspec flag (set by IORT) for
the support check, and call iort_pci_rc_pasid_max_width_for_dev() for
the width clamp; both pieces are wired up in
iort_iommu_configure_id() by the previous patch.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 26 ++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index e8d7dbe495f0..2b269307fd33 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3071,16 +3071,28 @@ static void arm_smmu_enable_ats(struct arm_smmu_master *master)
 
 static int arm_smmu_enable_pasid(struct arm_smmu_master *master)
 {
-	int ret;
-	int features;
-	int num_pasids;
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(master->dev);
 	struct pci_dev *pdev;
+	int features, num_pasids, ret, rc_width;
 
 	if (!dev_is_pci(master->dev))
 		return -ENODEV;
 
 	pdev = to_pci_dev(master->dev);
 
+	/*
+	 * IORT E.c (RC node revision >= 4) reports whether the root
+	 * complex actually supports PASID. If it does not, enabling
+	 * PASID on the endpoint is futile - the RC will not forward
+	 * the PASID prefix - so skip silently. Older firmware is
+	 * treated as "unknown / assume supported" to preserve the
+	 * pre-E.c behaviour.
+	 */
+	if (fwspec &&
+	    !(fwspec->flags & IOMMU_FWSPEC_PCI_RC_PASID) &&
+	    iort_pci_rc_pasid_max_width_known(master->dev))
+		return 0;
+
 	features = pci_pasid_features(pdev);
 	if (features < 0)
 		return features;
@@ -3089,6 +3101,14 @@ static int arm_smmu_enable_pasid(struct arm_smmu_master *master)
 	if (num_pasids <= 0)
 		return num_pasids;
 
+	/* Clamp by what the root complex can carry, when known. */
+	rc_width = iort_pci_rc_pasid_max_width_for_dev(master->dev);
+	if (rc_width >= 0)
+		num_pasids = min_t(int, num_pasids, 1 << rc_width);
+
+	if (num_pasids <= 1)
+		return 0;
+
 	ret = pci_enable_pasid(pdev, features);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to enable PASID\n");
-- 
2.25.1



^ permalink raw reply related

* [PATCH V1 2/3] ACPI/IORT: Plumb Root Complex PASID descriptors into iommu_fwspec
From: Vidya Sagar @ 2026-04-23 19:14 UTC (permalink / raw)
  To: rafael, lenb, saket.dumbre, lpieralisi, guohanjun, sudeep.holla,
	will, catalin.marinas, joro, robin.murphy, jgg, nicolinc, praan
  Cc: vsethi, sdonthineni, kthota, sagar.tv, linux-acpi,
	linux-arm-kernel, acpica-devel, iommu, linux-kernel, Vidya Sagar
In-Reply-To: <20260423191417.2031652-1-vidyas@nvidia.com>

The IORT spec, Issue E.c (ARM DEN 0049E.c, January 2022), gives
software two ways to learn about Root Complex PASID capability:

  - the Flags field at byte offset 36 (RC node revision >= 4), bit 0
    of which says whether the Root Complex itself supports PASID, and
  - bit 2 of the long-standing ATS Attribute field at offset 24, which
    says whether the Root Complex forwards PASID information on
    translated transactions to the SMMU.

Neither is consumed by Linux today. Modeled after the CANWBS support
in commit 807404d66fcf ("ACPI/IORT: Support CANWBS memory access
flag"), expose both bits via the existing iommu_fwspec mechanism so
IOMMU drivers can consult them at device probe time:

  - IOMMU_FWSPEC_PCI_RC_PASID      (bit 2): RC declares PASID support
  - IOMMU_FWSPEC_PCI_RC_PASID_FWD  (bit 3): RC forwards PASID

Add three new static helpers in iort.c that read the corresponding
fields, with iort_pci_rc_supports_pasid() and the new
iort_pci_rc_pasid_max_width() helper guarded by node->revision >= 4
because their backing storage was only added in E.c. The PASID
forwarding bit lives in the older ats_attribute field and needs no
guard. Set the new fwspec flags from iort_iommu_configure_id().

In addition, expose two device-facing wrappers,
iort_pci_rc_pasid_max_width_known() and _for_dev(), so IOMMU drivers
can clamp endpoint PASID widths by what the Root Complex can actually
carry without having to walk the IORT themselves. Provide stubs in
include/linux/acpi_iort.h for !CONFIG_ACPI_IORT.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
 drivers/acpi/arm64/iort.c | 80 +++++++++++++++++++++++++++++++++++++++
 include/linux/acpi_iort.h |  6 +++
 include/linux/iommu.h     |  4 ++
 3 files changed, 90 insertions(+)

diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index af7a9b2fd5bc..40486de6bd79 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1352,6 +1352,36 @@ static bool iort_pci_rc_supports_canwbs(struct acpi_iort_node *node)
 	return memory_access->memory_flags & ACPI_IORT_MF_CANWBS;
 }
 
+static bool iort_pci_rc_supports_pasid(struct acpi_iort_node *node)
+{
+	struct acpi_iort_root_complex *pci_rc;
+
+	if (node->revision < 4)
+		return false;
+
+	pci_rc = (struct acpi_iort_root_complex *)node->node_data;
+	return pci_rc->flags & ACPI_IORT_RC_PASID_SUPPORTED;
+}
+
+static bool iort_pci_rc_supports_pasid_fwd(struct acpi_iort_node *node)
+{
+	struct acpi_iort_root_complex *pci_rc;
+
+	pci_rc = (struct acpi_iort_root_complex *)node->node_data;
+	return pci_rc->ats_attribute & ACPI_IORT_PASID_FWD_SUPPORTED;
+}
+
+static int iort_pci_rc_pasid_max_width(struct acpi_iort_node *node)
+{
+	struct acpi_iort_root_complex *pci_rc;
+
+	if (node->revision < 4)
+		return -ENODEV;
+
+	pci_rc = (struct acpi_iort_root_complex *)node->node_data;
+	return FIELD_GET(ACPI_IORT_PASID_MAX_WIDTH, pci_rc->pasid_capabilities);
+}
+
 static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
 			    u32 streamid)
 {
@@ -1471,6 +1501,10 @@ int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
 		if (fwspec && iort_pci_rc_supports_canwbs(node))
 			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_CANWBS;
+		if (fwspec && iort_pci_rc_supports_pasid(node))
+			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_PASID;
+		if (fwspec && iort_pci_rc_supports_pasid_fwd(node))
+			fwspec->flags |= IOMMU_FWSPEC_PCI_RC_PASID_FWD;
 	} else {
 		node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
 				      iort_match_node_callback, dev);
@@ -1556,6 +1590,52 @@ int iort_dma_get_ranges(struct device *dev, u64 *limit)
 		return nc_dma_get_range(dev, limit);
 }
 
+static struct acpi_iort_node *iort_pci_rc_node_for_dev(struct device *dev)
+{
+	struct pci_bus *pbus;
+
+	if (!dev_is_pci(dev))
+		return NULL;
+
+	pbus = to_pci_dev(dev)->bus;
+	return iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
+			      iort_match_node_callback, &pbus->dev);
+}
+
+/**
+ * iort_pci_rc_pasid_max_width_known() - Whether IORT firmware describes the
+ * Root Complex PASID width for the given PCI device.
+ * @dev: PCI device to lookup
+ *
+ * Returns true iff a matching IORT Root Complex node exists and has revision
+ * >= 4 (IORT spec E.c), i.e. the PASID Capabilities descriptor is present.
+ */
+bool iort_pci_rc_pasid_max_width_known(struct device *dev)
+{
+	struct acpi_iort_node *node = iort_pci_rc_node_for_dev(dev);
+
+	return node && node->revision >= 4;
+}
+
+/**
+ * iort_pci_rc_pasid_max_width_for_dev() - Look up the Root Complex Max PASID
+ * Width for the given PCI device.
+ * @dev: PCI device to lookup
+ *
+ * Returns the Max PASID Width (bits[4:0] of PASID Capabilities) declared by
+ * the Root Complex node in IORT firmware, or a negative errno when the field
+ * is not present (RC node revision < 4) or the device is not PCI.
+ */
+int iort_pci_rc_pasid_max_width_for_dev(struct device *dev)
+{
+	struct acpi_iort_node *node = iort_pci_rc_node_for_dev(dev);
+
+	if (!node)
+		return -ENODEV;
+
+	return iort_pci_rc_pasid_max_width(node);
+}
+
 static void __init acpi_iort_register_irq(int hwirq, const char *name,
 					  int trigger,
 					  struct resource *res)
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
index 17bb3374f4ca..befe19d87c2c 100644
--- a/include/linux/acpi_iort.h
+++ b/include/linux/acpi_iort.h
@@ -45,6 +45,8 @@ void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
 int iort_dma_get_ranges(struct device *dev, u64 *limit);
 int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
 void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
+bool iort_pci_rc_pasid_max_width_known(struct device *dev);
+int iort_pci_rc_pasid_max_width_for_dev(struct device *dev);
 phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
 #else
 static inline u32 iort_msi_map_id(struct device *dev, u32 id)
@@ -71,6 +73,10 @@ static inline int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
 static inline
 void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head)
 { }
+static inline bool iort_pci_rc_pasid_max_width_known(struct device *dev)
+{ return false; }
+static inline int iort_pci_rc_pasid_max_width_for_dev(struct device *dev)
+{ return -ENODEV; }
 
 static inline phys_addr_t acpi_iort_dma_get_max_cpu_address(void)
 { return PHYS_ADDR_MAX; }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index e587d4ac4d33..e78d7f56d603 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -1118,6 +1118,10 @@ struct iommu_fwspec {
 #define IOMMU_FWSPEC_PCI_RC_ATS			(1 << 0)
 /* CANWBS is supported */
 #define IOMMU_FWSPEC_PCI_RC_CANWBS		(1 << 1)
+/* Root complex declares PASID support (IORT E.c Flags bit 0) */
+#define IOMMU_FWSPEC_PCI_RC_PASID		(1 << 2)
+/* Root complex forwards PASID on translated transactions (IORT ATS bit 2) */
+#define IOMMU_FWSPEC_PCI_RC_PASID_FWD		(1 << 3)
 
 /*
  * An iommu attach handle represents a relationship between an iommu domain
-- 
2.25.1



^ permalink raw reply related

* [PATCH V1 1/3] ACPICA: IORT: Add Root Complex PASID Flags field
From: Vidya Sagar @ 2026-04-23 19:14 UTC (permalink / raw)
  To: rafael, lenb, saket.dumbre, lpieralisi, guohanjun, sudeep.holla,
	will, catalin.marinas, joro, robin.murphy, jgg, nicolinc, praan
  Cc: vsethi, sdonthineni, kthota, sagar.tv, linux-acpi,
	linux-arm-kernel, acpica-devel, iommu, linux-kernel, Vidya Sagar
In-Reply-To: <20260423191417.2031652-1-vidyas@nvidia.com>

The IORT spec, Issue E.c (ARM DEN 0049E.c, January 2022), bumps the
Root Complex Node to revision 4 and adds two PASID descriptors:

  - PASID Capabilities at byte offset 33 (2 bytes), bits[4:0] of which
    report the Max PASID Width supported by the Root Complex.
  - Flags at byte offset 36 (4 bytes), bit 0 of which reports whether
    the Root Complex itself supports PASID. This is distinct from the
    existing ATS Attribute bit 2 (at offset 24) that only reports
    whether the RC forwards PASID information on translated
    transactions.

The ACPICA struct in include/acpi/actbl2.h was updated for the E.c
PASID Capabilities descriptor (offset 33) but stops short with a
trailing 'u8 reserved[]' flexible array, so the new Flags field at
offset 36 is unreachable and the existing ACPI_IORT_PASID_*
definitions have no consumer.

Replace the trailing flexible array with a fixed 'u8 reserved[1]'
followed by 'u32 flags' so the struct fully covers RC node revision 4,
and add the ACPI_IORT_RC_PASID_SUPPORTED mask for bit 0 of the new
field. With #pragma pack(1) in effect for actbl2.h, this lands the new
field at the spec-mandated absolute offset 36.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
 include/acpi/actbl2.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index 5c0b55e7b3e4..5a4450e66358 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -748,7 +748,8 @@ struct acpi_iort_root_complex {
 	u32 pci_segment_number;
 	u8 memory_address_limit;	/* Memory address size limit */
 	u16 pasid_capabilities;	/* PASID Capabilities */
-	u8 reserved[];		/* Reserved, must be zero */
+	u8 reserved[1];		/* Reserved, must be zero */
+	u32 flags;		/* Flags (IORT E.c, RC node revision >= 4) */
 };
 
 /* Masks for ats_attribute field above */
@@ -760,6 +761,9 @@ struct acpi_iort_root_complex {
 /* Masks for pasid_capabilities field above */
 #define ACPI_IORT_PASID_MAX_WIDTH       (0x1F)	/* Bits 0-4 */
 
+/* Masks for flags field above */
+#define ACPI_IORT_RC_PASID_SUPPORTED    (1)	/* The root complex PASID support */
+
 struct acpi_iort_smmu {
 	u64 base_address;	/* SMMU base address */
 	u64 span;		/* Length of memory range */
-- 
2.25.1



^ permalink raw reply related

* [PATCH V1 0/3] ACPI/IORT: Honor Root Complex PASID descriptors on SMMUv3
From: Vidya Sagar @ 2026-04-23 19:14 UTC (permalink / raw)
  To: rafael, lenb, saket.dumbre, lpieralisi, guohanjun, sudeep.holla,
	will, catalin.marinas, joro, robin.murphy, jgg, nicolinc, praan
  Cc: vsethi, sdonthineni, kthota, sagar.tv, linux-acpi,
	linux-arm-kernel, acpica-devel, iommu, linux-kernel, Vidya Sagar

Hi,
This series enhances Linux to read and honor the Root Complex (RC) PASID
descriptors introduced by IORT Issue E.c (ARM DEN 0049E.c, January 2022,
RC node revision 4):

  - PASID Capabilities at byte offset 33, bits[4:0] = Max PASID Width.
  - Flags at byte offset 36, bit 0 = "Root Complex supports PASID".

Both fields have been spec'd for over four years but are not consumed
anywhere in the tree. Worse, include/acpi/actbl2.h only covers the
PASID Capabilities field - the trailing "u8 reserved[]" flexible array
stops just before the Flags field at offset 36, so even firmware that
populates it cannot be read today. The existing ACPI_IORT_PRI_SUPPORTED,
ACPI_IORT_PASID_FWD_SUPPORTED and ACPI_IORT_PASID_MAX_WIDTH macros are
dead code, and ACPICA upstream has the same gap.

Today arm_smmu_enable_pasid() calls pci_enable_pasid() for any PCI
master with a PASID capability, regardless of whether the upstream RC
actually supports PASID and regardless of the RC's declared Max PASID
Width. On a platform whose RC cannot forward PASID to the SMMU, this
enables the PCIe PASID capability unnecessarily on the endpoint (the
traffic then gets dropped upstream) and sets a non-zero master->ssid_bits,
which complicates teardown ordering with ATS (see the comment block in
arm_smmu_probe_device() for that ordering constraint).

The series fixes this in three bite-sized patches, modeled on the
CANWBS support from commit 807404d66fcf ("ACPI/IORT: Support CANWBS
memory access flag"):

  Patch 1 (ACPICA): extend struct acpi_iort_root_complex to cover the
    offset-36 Flags field and add the ACPI_IORT_RC_PASID_SUPPORTED
    mask. With #pragma pack(1) already in effect for actbl2.h, this
    lands the new field at the spec-mandated absolute offset 36.

  Patch 2 (ACPI/IORT): add three static helpers that read the new RC
    PASID fields (guarded by node->revision >= 4 where appropriate),
    set two new iommu_fwspec flags from iort_iommu_configure_id(), and
    expose two device-facing wrappers so IOMMU drivers can clamp
    endpoint PASID widths without walking the IORT themselves. Stubs
    for !CONFIG_ACPI_IORT live in include/linux/acpi_iort.h.
      IOMMU_FWSPEC_PCI_RC_PASID      (bit 2): RC declares PASID support
      IOMMU_FWSPEC_PCI_RC_PASID_FWD  (bit 3): RC forwards PASID on
                                              translated transactions
  Patch 3 (arm-smmu-v3): consume the new fwspec flag and the new
    max-width helper in arm_smmu_enable_pasid(). If the RC explicitly
    declares no PASID support, skip pci_enable_pasid() silently.
    Otherwise clamp num_pasids by min(endpoint cap, 1 << RC width) and
    only proceed when the effective count is > 1.
    
Policy: all new gating is conditional on
iort_pci_rc_pasid_max_width_known(), i.e. the presence of an IORT RC
node at revision >= 4. Platforms booting with older IORT firmware (RC
node revision 0..3) see no behavioural change and continue to enable
PASID purely on the basis of the endpoint capability. This keeps the
series safe for platforms that ship pre-E.c tables.

Out of scope intentionally:
  - Wiring the new fwspec flags into Intel/AMD IOMMU drivers - IORT
    is ARM-only.
  - Consuming IOMMU_FWSPEC_PCI_RC_PASID_FWD in arm-smmu-v3 beyond the
    existing CD/STE programming. The fwspec flag is plumbed now so
    future work (e.g. gating PASID forwarding hints in STE.S1DSS) has
    the information available.
  - Exposing a "pasid-num-bits" software node property for PCI devices,
    parallel to what iort_named_component_init() already does for named
    components. The direct helper is simpler and avoids creating a
    software node per RC.

Thanks,
Vidya Sagar

Vidya Sagar (3):
  ACPICA: IORT: Add Root Complex PASID Flags field
  ACPI/IORT: Plumb Root Complex PASID descriptors into iommu_fwspec
  iommu/arm-smmu-v3: Honor IORT Root Complex PASID descriptors

 drivers/acpi/arm64/iort.c                   | 80 +++++++++++++++++++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 26 ++++++-
 include/acpi/actbl2.h                       |  6 +-
 include/linux/acpi_iort.h                   |  6 ++
 include/linux/iommu.h                       |  4 ++
 5 files changed, 118 insertions(+), 4 deletions(-)

-- 
2.25.1



^ permalink raw reply

* Re: [PATCH v13 0/4] Enable Remote GPIO over RPMSG on i.MX Platform
From: Shenwei Wang @ 2026-04-23 19:11 UTC (permalink / raw)
  To: Andrew Lunn, Mathieu Poirier
  Cc: Linus Walleij, Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Frank Li,
	Sascha Hauer, Shuah Khan, linux-gpio@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	Pengutronix Kernel Team, Fabio Estevam, Peng Fan,
	devicetree@vger.kernel.org, linux-remoteproc@vger.kernel.org,
	imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	dl-linux-imx
In-Reply-To: <cb6b8ec9-296e-40fe-848d-ae87463ff1db@lunn.ch>



> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Thursday, April 23, 2026 8:54 AM
> To: Mathieu Poirier <mathieu.poirier@linaro.org>
> Cc: Shenwei Wang <shenwei.wang@nxp.com>; Linus Walleij
> <linusw@kernel.org>; Bartosz Golaszewski <brgl@kernel.org>; Jonathan Corbet
> <corbet@lwn.net>; Rob Herring <robh@kernel.org>; Krzysztof Kozlowski
> <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Bjorn Andersson
> <andersson@kernel.org>; Frank Li <frank.li@nxp.com>; Sascha Hauer
> <s.hauer@pengutronix.de>; Shuah Khan <skhan@linuxfoundation.org>; linux-
> gpio@vger.kernel.org; linux-doc@vger.kernel.org; linux-kernel@vger.kernel.org;
> Pengutronix Kernel Team <kernel@pengutronix.de>; Fabio Estevam
> <festevam@gmail.com>; Peng Fan <peng.fan@nxp.com>;
> devicetree@vger.kernel.org; linux-remoteproc@vger.kernel.org;
> imx@lists.linux.dev; linux-arm-kernel@lists.infradead.org; dl-linux-imx <linux-
> imx@nxp.com>
> Subject: [EXT] Re: [PATCH v13 0/4] Enable Remote GPIO over RPMSG on i.MX
> Platform
> 
> Caution: This is an external email. Please take care when clicking links or opening
> attachments. When in doubt, report the message using the 'Report this email'
> button
> 
> 
> On Thu, Apr 23, 2026 at 06:53:12AM -0600, Mathieu Poirier wrote:
> > Once again Andrew Lunn was left out.
> >
> > On Wed, 22 Apr 2026 at 15:29, Shenwei Wang <shenwei.wang@nxp.com>
> wrote:
> > >
> > > Support the remote devices on the remote processor via the RPMSG bus
> > > on i.MX platform.
> > >
> > > Changes in v13:
> > >  - drop the support for legacy NXP firmware.
> > >  - remove the fixed_up hooks from the rpmsg gpio driver.
> > >  - code cleanup.
> 
> That looks like a step forward. Now we don't care about legacy NXP firmware, it
> makes it easier to make bigger changes, like use the messages format from gpio-
> virtio.
> 

The implementation adopts the gpio‑virtio design, including its commands, parameters, and error codes.

Shenwei

>          Andrew

^ permalink raw reply

* [PATCH v14 20/28] drm/rockchip: dw_hdmi_qp: Implement "color format" DRM property
From: Nicolas Frattaroli @ 2026-04-23 19:03 UTC (permalink / raw)
  To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
	Christian König, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
	Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
	Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring,
	Jonathan Corbet, Shuah Khan
  Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
	linux-rockchip, intel-gfx, intel-xe, linux-doc, wayland-devel,
	Nicolas Frattaroli, Cristian Ciocaltea
In-Reply-To: <20260423-color-format-v14-0-449a419ccbd4@collabora.com>

Switch between requested color formats by setting the right bus formats,
configuring the VO GRF registers, and setting the right output mode.

To do this, the encoder's atomic_check queries the bus format of the
first bridge, which was determined by the bridge chain recursive format
selection. Pick the input format if it's !FIXED, otherwise, pick the
output format.

The previously unused GRF register color format defines are redone as
well. Both RK3588 and RK3576 use the same defines; it didn't look like
this as there was a typo in the previously (unused) definition.

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 107 ++++++++++++++++++++++---
 1 file changed, 98 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index c78db7f8ab6c..9bf727c1dd7d 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -11,6 +11,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/hw_bitfield.h>
 #include <linux/mfd/syscon.h>
+#include <linux/media-bus-format.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/phy/phy.h>
@@ -44,10 +45,6 @@
 #define RK3576_8BPC			0x0
 #define RK3576_10BPC			0x6
 #define RK3576_COLOR_FORMAT_MASK	GENMASK(7, 4)
-#define RK3576_RGB			0x9
-#define RK3576_YUV422			0x1
-#define RK3576_YUV444			0x2
-#define RK3576_YUV420			0x3
 #define RK3576_CECIN_MASK		BIT(3)
 
 #define RK3576_VO0_GRF_SOC_CON14	0x0038
@@ -75,8 +72,6 @@
 #define RK3588_8BPC			0x0
 #define RK3588_10BPC			0x6
 #define RK3588_COLOR_FORMAT_MASK	GENMASK(3, 0)
-#define RK3588_RGB			0x0
-#define RK3588_YUV420			0x3
 #define RK3588_SCLIN_MASK		BIT(9)
 #define RK3588_SDAIN_MASK		BIT(10)
 #define RK3588_MODE_MASK		BIT(11)
@@ -88,6 +83,11 @@
 #define HOTPLUG_DEBOUNCE_MS		150
 #define MAX_HDMI_PORT_NUM		2
 
+#define RK_COLOR_FMT_RGB		0x0
+#define RK_COLOR_FMT_YUV422		0x1
+#define RK_COLOR_FMT_YUV444		0x2
+#define RK_COLOR_FMT_YUV420		0x3
+
 struct rockchip_hdmi_qp {
 	struct device *dev;
 	struct regmap *regmap;
@@ -116,6 +116,33 @@ static struct rockchip_hdmi_qp *to_rockchip_hdmi_qp(struct drm_encoder *encoder)
 	return container_of(rkencoder, struct rockchip_hdmi_qp, encoder);
 }
 
+/**
+ * dw_hdmi_qp_rockchip_bus_fmt_to_reg - converts a bus format to a GRF reg value
+ * @bus_fmt: One of the MEDIA_BUS_FMT_s allowed by this driver's atomic_check
+ *
+ * Returns: an unshifted value to be written to the COLOR_FORMAT GRF register
+ * on success, or %-EINVAL if the bus format is not supported.
+ */
+static int __pure dw_hdmi_qp_rockchip_bus_fmt_to_reg(u32 bus_fmt)
+{
+	switch (bus_fmt) {
+	case MEDIA_BUS_FMT_RGB888_1X24:
+	case MEDIA_BUS_FMT_RGB101010_1X30:
+		return RK_COLOR_FMT_RGB;
+	case MEDIA_BUS_FMT_UYVY8_1X16:
+	case MEDIA_BUS_FMT_UYVY10_1X20:
+		return RK_COLOR_FMT_YUV422;
+	case MEDIA_BUS_FMT_YUV8_1X24:
+	case MEDIA_BUS_FMT_YUV10_1X30:
+		return RK_COLOR_FMT_YUV444;
+	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
+	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+		return RK_COLOR_FMT_YUV420;
+	}
+
+	return -EINVAL;
+}
+
 static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder)
 {
 	struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder);
@@ -131,29 +158,83 @@ static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder)
 		hdmi->ctrl_ops->enc_init(hdmi, to_rockchip_crtc_state(crtc->state));
 }
 
+/**
+ * dw_hdmi_qp_rockchip_get_vop_format - get the bus format VOP should output
+ * @encoder: pointer to a &struct drm_encoder
+ * @conn_state: pointer to the current atomic &struct drm_connector_state
+ *
+ * Determines which bus format the Rockchip video processor should output as
+ * to feed into the bridge chain.
+ *
+ * Returns a MEDIA_BUS_FMT_* on success, or %0 on error.
+ */
+static u32 dw_hdmi_qp_rockchip_get_vop_format(struct drm_encoder *encoder,
+					      struct drm_connector_state *conn_state)
+{
+	struct drm_bridge *bridge __free(drm_bridge_put) = NULL;
+	struct drm_bridge_state *bstate;
+
+	bridge = drm_bridge_chain_get_first_bridge(encoder);
+	if (!bridge)
+		return 0;
+
+	bstate = drm_atomic_get_bridge_state(conn_state->state, bridge);
+	if (!bstate)
+		return 0;
+
+	if (bstate->input_bus_cfg.format != MEDIA_BUS_FMT_FIXED)
+		return bstate->input_bus_cfg.format;
+
+	return bstate->output_bus_cfg.format;
+}
+
 static int
 dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
 					 struct drm_crtc_state *crtc_state,
 					 struct drm_connector_state *conn_state)
 {
-	struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder);
 	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+	struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder);
 	union phy_configure_opts phy_cfg = {};
+	u32 ingest_fmt;
 	int ret;
 
+	ingest_fmt = dw_hdmi_qp_rockchip_get_vop_format(encoder, conn_state);
+	if (!ingest_fmt)
+		return -EINVAL;
+
 	if (hdmi->tmds_char_rate == conn_state->hdmi.tmds_char_rate &&
-	    s->output_bpc == conn_state->hdmi.output_bpc)
+	    s->output_bpc == conn_state->hdmi.output_bpc &&
+	    s->bus_format == ingest_fmt)
 		return 0;
 
+	switch (ingest_fmt) {
+	case MEDIA_BUS_FMT_RGB888_1X24:
+	case MEDIA_BUS_FMT_RGB101010_1X30:
+	case MEDIA_BUS_FMT_YUV8_1X24:
+	case MEDIA_BUS_FMT_YUV10_1X30:
+		s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
+		break;
+	case MEDIA_BUS_FMT_UYVY8_1X16:
+		s->output_mode = ROCKCHIP_OUT_MODE_YUV422;
+		break;
+	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
+	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+		s->output_mode = ROCKCHIP_OUT_MODE_YUV420;
+		break;
+	default:
+		return -EINVAL;
+	}
+
 	phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate;
 	phy_cfg.hdmi.bpc = conn_state->hdmi.output_bpc;
 
 	ret = phy_configure(hdmi->phy, &phy_cfg);
 	if (!ret) {
 		hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate;
-		s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
 		s->output_type = DRM_MODE_CONNECTOR_HDMIA;
 		s->output_bpc = conn_state->hdmi.output_bpc;
+		s->bus_format = ingest_fmt;
 	} else {
 		dev_err(hdmi->dev, "Failed to configure phy: %d\n", ret);
 	}
@@ -383,6 +464,7 @@ static void dw_hdmi_qp_rk3588_io_init(struct rockchip_hdmi_qp *hdmi)
 static void dw_hdmi_qp_rk3576_enc_init(struct rockchip_hdmi_qp *hdmi,
 				       struct rockchip_crtc_state *state)
 {
+	int color = dw_hdmi_qp_rockchip_bus_fmt_to_reg(state->bus_format);
 	u32 val;
 
 	if (state->output_bpc == 10)
@@ -390,12 +472,16 @@ static void dw_hdmi_qp_rk3576_enc_init(struct rockchip_hdmi_qp *hdmi,
 	else
 		val = FIELD_PREP_WM16(RK3576_COLOR_DEPTH_MASK, RK3576_8BPC);
 
+	if (likely(color >= 0))
+		val |= FIELD_PREP_WM16(RK3576_COLOR_FORMAT_MASK, color);
+
 	regmap_write(hdmi->vo_regmap, RK3576_VO0_GRF_SOC_CON8, val);
 }
 
 static void dw_hdmi_qp_rk3588_enc_init(struct rockchip_hdmi_qp *hdmi,
 				       struct rockchip_crtc_state *state)
 {
+	int color = dw_hdmi_qp_rockchip_bus_fmt_to_reg(state->bus_format);
 	u32 val;
 
 	if (state->output_bpc == 10)
@@ -403,6 +489,9 @@ static void dw_hdmi_qp_rk3588_enc_init(struct rockchip_hdmi_qp *hdmi,
 	else
 		val = FIELD_PREP_WM16(RK3588_COLOR_DEPTH_MASK, RK3588_8BPC);
 
+	if (likely(color >= 0))
+		val |= FIELD_PREP_WM16(RK3588_COLOR_FORMAT_MASK, color);
+
 	regmap_write(hdmi->vo_regmap,
 		     hdmi->port_id ? RK3588_GRF_VO1_CON6 : RK3588_GRF_VO1_CON3,
 		     val);

-- 
2.53.0



^ permalink raw reply related

* Re: [PATCH v13 0/4] Enable Remote GPIO over RPMSG on i.MX Platform
From: Shenwei Wang @ 2026-04-23 19:08 UTC (permalink / raw)
  To: Mathieu Poirier, Andrew Lunn
  Cc: Linus Walleij, Bartosz Golaszewski, Jonathan Corbet, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Frank Li,
	Sascha Hauer, Shuah Khan, linux-gpio@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	Pengutronix Kernel Team, Fabio Estevam, Peng Fan,
	devicetree@vger.kernel.org, linux-remoteproc@vger.kernel.org,
	imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	dl-linux-imx
In-Reply-To: <CANLsYkypRaFTTP7MLLLR+=AB5JnRTA4i130qvWzB1qoAuM9FWQ@mail.gmail.com>



> -----Original Message-----
> From: Mathieu Poirier <mathieu.poirier@linaro.org>
> Sent: Thursday, April 23, 2026 7:53 AM
> To: Shenwei Wang <shenwei.wang@nxp.com>; Andrew Lunn <andrew@lunn.ch>
> Cc: Linus Walleij <linusw@kernel.org>; Bartosz Golaszewski <brgl@kernel.org>;
> Jonathan Corbet <corbet@lwn.net>; Rob Herring <robh@kernel.org>; Krzysztof
> Kozlowski <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; Bjorn
> Andersson <andersson@kernel.org>; Frank Li <frank.li@nxp.com>; Sascha Hauer
> <s.hauer@pengutronix.de>; Shuah Khan <skhan@linuxfoundation.org>; linux-
> 
> Once again Andrew Lunn was left out.
> 

Seems an issue of get_maintainer.pl, but he is included in the thread for the gpio‑rpmsg driver patch..
Cc: Andrew Lunn <andrew@lunn.ch>

> On Wed, 22 Apr 2026 at 15:29, Shenwei Wang <shenwei.wang@nxp.com>
> wrote:
> >
> > Support the remote devices on the remote processor via the RPMSG bus
> > on i.MX platform.
> >
> > Changes in v13:
> >  - drop the support for legacy NXP firmware.
> >  - remove the fixed_up hooks from the rpmsg gpio driver.
> >  - code cleanup.
> >
> > Changes in v12:
> >  - Fixed the "underline" warning reported by Randy.
> >
> > Changes in v11:
> >  - Expand RPMSG for the first time per Shuah's review comment.
> >
> > Changes in v10:
> >  - Update gpio-rpmsg.rst according to Daniel Baluta's review comments.
> >  - Add a kernel CONFIG for fixed up handlers and only enable it on
> >    i.MX products.
> >  - Fixed bugs reported by kernel test robot.
> >
> > Changes in v9:
> >  - Reuse the gpio-virtio design for command and IRQ type definitions.
> >  - Remove msg_id, version, and vendor fields from the generic protocol.
> >  - Add fixed-up handlers to support legacy firmware.
> >
> > Changes in v8:
> >  - Add "depends on REMOTEPROC" in Kconfig to fix the build error reported
> >    by the kernel test robot.
> >  - Move the .rst patch before the .yaml patch.
> >  - Handle the "ngpios" DT property based on Andrew's feedback.
> >
> > Changes in v7:
> >  - Reworked the driver to use the rpmsg_driver framework instead of
> >    platform_driver, based on feedback from Bjorn and Arnaud.
> >  - Updated gpio-rpmsg.yaml and imx_rproc.yaml according to comments from
> >    Rob and Arnaud.
> >  - Further refinements to gpio-rpmsg.yaml per Arnaud's feedback.
> >
> > Changes in v6:
> >  - make the driver more generic with the actions below:
> >      rename the driver file to gpio-rpmsg.c
> >      remove the imx related info in the function and variable names
> >      rename the imx_rpmsg.h to rpdev_info.h
> >      create a gpio-rpmsg.yaml and refer it in imx_rproc.yaml
> >  - update the gpio-rpmsg.rst according to the feedback from Andrew and
> >    move the source file to driver-api/gpio
> >  - fix the bug reported by Zhongqiu Han
> >  - remove the I2C related info
> >
> > Changes in v5:
> >  - move the gpio-rpmsg.rst from admin-guide to staging directory after
> >    discussion with Randy Dunlap.
> >  - add include files with some code improvements per Bartosz's comments.
> >
> > Changes in v4:
> >  - add a documentation to describe the transport protocol per Andrew's
> >    comments.
> >  - add a new handler to get the gpio direction.
> >
> > Changes in v3:
> >  - fix various format issue and return value check per Peng 's review
> >    comments.
> >  - add the logic to also populate the subnodes which are not in the
> >    device map per Arnaud's request. (in imx_rproc.c)
> >  - update the yaml per Frank's review comments.
> >
> > Changes in v2:
> >  - re-implemented the gpio driver per Linus Walleij's feedback by using
> >    GPIOLIB_IRQCHIP helper library.
> >  - fix various format issue per Mathieu/Peng 's review comments.
> >  - update the yaml doc per Rob's feedback
> >
> > Shenwei Wang (4):
> >   docs: driver-api: gpio: rpmsg gpio driver over rpmsg bus
> >   dt-bindings: remoteproc: imx_rproc: Add "rpmsg" subnode support
> >   gpio: rpmsg: add generic rpmsg GPIO driver
> >   arm64: dts: imx8ulp: Add rpmsg node under imx_rproc
> >
> >  .../devicetree/bindings/gpio/gpio-rpmsg.yaml  |  55 ++
> >  .../bindings/remoteproc/fsl,imx-rproc.yaml    |  53 ++
> >  Documentation/driver-api/gpio/gpio-rpmsg.rst  | 266 ++++++++
> >  Documentation/driver-api/gpio/index.rst       |   1 +
> >  arch/arm64/boot/dts/freescale/imx8ulp.dtsi    |  25 +
> >  drivers/gpio/Kconfig                          |  17 +
> >  drivers/gpio/Makefile                         |   1 +
> >  drivers/gpio/gpio-rpmsg.c                     | 573 ++++++++++++++++++
> >  8 files changed, 991 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/gpio/gpio-rpmsg.yaml
> >  create mode 100644 Documentation/driver-api/gpio/gpio-rpmsg.rst
> >  create mode 100644 drivers/gpio/gpio-rpmsg.c
> >
> > --
> > 2.43.0
> >

^ permalink raw reply

* [PATCH v14 21/28] drm/rockchip: dw_hdmi_qp: Set supported_formats platdata
From: Nicolas Frattaroli @ 2026-04-23 19:03 UTC (permalink / raw)
  To: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
	Christian König, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Sandy Huang, Heiko Stübner,
	Andy Yan, Jani Nikula, Rodrigo Vivi, Joonas Lahtinen,
	Tvrtko Ursulin, Dmitry Baryshkov, Sascha Hauer, Rob Herring,
	Jonathan Corbet, Shuah Khan
  Cc: kernel, amd-gfx, dri-devel, linux-kernel, linux-arm-kernel,
	linux-rockchip, intel-gfx, intel-xe, linux-doc, wayland-devel,
	Nicolas Frattaroli, Cristian Ciocaltea
In-Reply-To: <20260423-color-format-v14-0-449a419ccbd4@collabora.com>

With the introduction of the supported_formats member in the
dw-hdmi-qp platform data struct, drivers that have access to this
information should now set it.

Set it in the rockchip dw_hdmi_qp glue driver.

This allows this information to be passed down to the dw-hdmi-qp core,
which sets it in the bridge it creates, and consequently will allow the
common HDMI bridge code to act on it.

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index 9bf727c1dd7d..a7a8bdb76ce6 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -602,6 +602,10 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
 	plat_data.phy_data = hdmi;
 	plat_data.max_bpc = 10;
 
+	plat_data.supported_formats = BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
+				      BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444) |
+				      BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422);
+
 	encoder = &hdmi->encoder.encoder;
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
 

-- 
2.53.0



^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox