* Re: [PATCH] firmware: imx: sm-misc: Add NULL check for kmalloc in syslog_show
From: Frank.Li @ 2026-06-29 20:41 UTC (permalink / raw)
To: s.hauer, imx, linux-kernel, kernel, festevam, peng.fan, shawnguo,
krzysztof.kozlowski, linux-arm-kernel, Li Jun
Cc: Frank Li
In-Reply-To: <20260610003814.75493-1-lijun01@kylinos.cn>
From: Frank Li <Frank.Li@nxp.com>
On Wed, 10 Jun 2026 08:38:14 +0800, Li Jun wrote:
> Add a proper NULL check for the kmalloc() return value in syslog_show().
> If memory allocation fails, syslog would be NULL and passing it to
> misc_syslog() could lead to a NULL pointer dereference.
Applied, thanks!
[1/1] firmware: imx: sm-misc: Add NULL check for kmalloc in syslog_show
commit: 4cf26bc2e7e099c86127d63ed7272753da45737e
Best regards,
--
Frank Li <Frank.Li@nxp.com>
^ permalink raw reply
* [PATCH_v2 0/3] clock-wizard fixups
From: Colin Foster @ 2026-06-29 20:53 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, linux-clk
Cc: Shubhrajyoti Datta, Michal Simek, Brian Masney, Stephen Boyd,
Michael Turquette
The clock-wizard driver had a hard-coded 20KHz minimum accuracy. This
led to out-of-tree drivers silently failing to set clock rates instead
of dealing with the best-effort.
Remove this 20KHz restriction to match the Versal clock wizard driver.
There also was a bug in the difference calculation that is addressed in
the first patch.
The second patch optimizes the search if an exact match is found.
The third removes the restriction.
v2:
* Rebase to apply cleanly
* Add signoffs
Colin Foster (3):
clk: clocking-wizard: fix clock difference detection
clk: clocking-wizard: optimize clock search
clk: clocking-wizard: remove 20kHz restriction
drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
--
2.43.0
^ permalink raw reply
* [PATCH_v2 1/3] clk: clocking-wizard: fix clock difference detection
From: Colin Foster @ 2026-06-29 20:53 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, linux-clk
Cc: Shubhrajyoti Datta, Michal Simek, Brian Masney, Stephen Boyd,
Michael Turquette
In-Reply-To: <20260629205346.3228886-1-colin.foster@in-advantage.com>
The diff calculation didn't take into account rollover. As such, a
target clock frequency below the requested rate would not be considered.
Before this change, bogus diffs would be used to determine the closest
possible clock:
8<--------
clk-wizard-test: requesting 133312500 Hz on output 0 (clock NOT enabled)
*** Clock wizard - Matching for rate 133312500 parent rate 99999000
m = 33, d = 1, o = 25, freq = 131998680, diff = 18446744073708237796
m = 34, d = 1, o = 26, freq = 130767923, diff = 18446744073707007039
m = 35, d = 1, o = 26, freq = 134614038, diff = 1301538
m = 36, d = 1, o = 27, freq = 133332000, diff = 19500
8<--------
After this change:
8<--------
clk-wizard-test: requesting 133312500 Hz on output 0 (clock NOT enabled)
*** Clock wizard - Matching for rate 133312500 parent rate 99999000
m = 33, d = 1, o = 25, freq = 131998680, diff = 1313820
m = 35, d = 1, o = 26, freq = 134614038, diff = 1301538
m = 36, d = 1, o = 27, freq = 133332000, diff = 19500
8<--------
Reviewed-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
---
drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
index 4a0136349f71a..77c9d025ca8cf 100644
--- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
@@ -406,7 +406,7 @@ static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate,
if (o < omin || o > omax)
continue;
freq = DIV_ROUND_CLOSEST_ULL(vco_freq, o);
- diff = freq - rate;
+ diff = abs(freq - rate);
if (diff < best_diff) {
best_diff = diff;
divider->m = m >> 3;
--
2.43.0
^ permalink raw reply related
* [PATCH_v2 3/3] clk: clocking-wizard: remove 20kHz restriction
From: Colin Foster @ 2026-06-29 20:53 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, linux-clk
Cc: Shubhrajyoti Datta, Michal Simek, Brian Masney, Stephen Boyd,
Michael Turquette
In-Reply-To: <20260629205346.3228886-1-colin.foster@in-advantage.com>
There is a 20KHz minimum target for clock difference that was baked into
the driver. This is unnecessary, and causes target clock frequencies to
be rejected that should otherwise succeed.
The discrepancy existed in versal drivers as well, but was removed as
part of 'commit e0a94c6bb5b4 ("clk: xilinx: Optimize divisor search in
clk_wzrd_get_divisors_ver()")'
Apply the change to allow differences >= 20kHz.
Before the change:
8<--------
clk-wizard-test: requesting 133312000 Hz on output 0 (clock NOT enabled)
*** Clock wizard - Matching for rate 133312000 parent rate 99999000
m = 33, d = 1, o = 25, freq = 131998680, diff = 1313320
m = 35, d = 1, o = 26, freq = 134614038, diff = 1302038
m = 36, d = 1, o = 27, freq = 133332000, diff = 20000
*** Clock wizard - Matching for rate 133312000 parent rate 99999000
m = 33, d = 1, o = 25, freq = 131998680, diff = 1313320
m = 35, d = 1, o = 26, freq = 134614038, diff = 1302038
m = 36, d = 1, o = 27, freq = 133332000, diff = 20000
clk-wizard-test: clk_set_rate(133312000) failed: -22
8<--------
After the change:
8<--------
clk-wizard-test: requesting 133312000 Hz on output 0 (clock NOT enabled)
*** Clock wizard - Matching for rate 133312000 parent rate 99999000
m = 33, d = 1, o = 25, freq = 131998680, diff = 1313320
m = 35, d = 1, o = 26, freq = 134614038, diff = 1302038
m = 36, d = 1, o = 27, freq = 133332000, diff = 20000
*** Clock wizard - Matching for rate 133312000 parent rate 99999000
m = 33, d = 1, o = 25, freq = 131998680, diff = 1313320
m = 35, d = 1, o = 26, freq = 134614038, diff = 1302038
m = 36, d = 1, o = 27, freq = 133332000, diff = 20000
*** Clock wizard - Matching for rate 133332000 parent rate 99999000
m = 33, d = 1, o = 25, freq = 131998680, diff = 1333320
m = 35, d = 1, o = 26, freq = 134614038, diff = 1282038
m = 36, d = 1, o = 27, freq = 133332000, diff = 0
clk-wizard-test: success -- actual rate: 133332000 Hz (requested 133312000 Hz, error 20000 Hz)
8<--------
Reviewed-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
---
drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
index c7e8010afae52..a8decb3ec40f4 100644
--- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
@@ -105,7 +105,6 @@
#define VER_WZRD_VCO_MAX 4320000000ULL
#define VER_WZRD_O_MIN 2
#define VER_WZRD_O_MAX 511
-#define WZRD_MIN_ERR 20000
#define WZRD_FRAC_POINTS 1000
/* Get the mask from width */
@@ -420,7 +419,7 @@ static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate,
}
}
}
- return best_diff < WZRD_MIN_ERR ? 0 : -EBUSY;
+ return best_diff != -1ULL ? 0 : -EBUSY;
}
static int clk_wzrd_reconfig(struct clk_wzrd_divider *divider, void __iomem *div_addr)
--
2.43.0
^ permalink raw reply related
* [PATCH_v2 2/3] clk: clocking-wizard: optimize clock search
From: Colin Foster @ 2026-06-29 20:53 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, linux-clk
Cc: Shubhrajyoti Datta, Michal Simek, Brian Masney, Stephen Boyd,
Michael Turquette
In-Reply-To: <20260629205346.3228886-1-colin.foster@in-advantage.com>
When an exact clock match is found, there is no need to continue
searching. This process was optimized for versal as part of
'commit e0a94c6bb5b4 ("clk: xilinx: Optimize divisor search in
clk_wzrd_get_divisors_ver()")' but that logic wasn't applied to
the non-versal driver.
Apply this fast-exit logic to the non-versal driver.
Reviewed-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Colin Foster <colin.foster@in-advantage.com>
---
drivers/clk/xilinx/clk-xlnx-clock-wizard.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
index 77c9d025ca8cf..c7e8010afae52 100644
--- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c
@@ -414,6 +414,9 @@ static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate,
divider->d = d;
divider->o = o >> 3;
divider->o_frac = (o - (divider->o << 3)) * 125;
+
+ if (!diff)
+ return 0;
}
}
}
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v1 1/3] clk: clocking-wizard: fix clock difference detection
From: Colin Foster @ 2026-06-29 20:56 UTC (permalink / raw)
To: Brian Masney
Cc: linux-kernel, linux-arm-kernel, linux-clk, Shubhrajyoti Datta,
Michal Simek, Stephen Boyd, Michael Turquette
In-Reply-To: <akLRwsEQEd3JGcvz@redhat.com>
On Mon, Jun 29, 2026 at 04:12:50PM -0400, Brian Masney wrote:
> Hi Colin,
>
>
> Stephen didn't pick this up last development cycle and I'm assembling a
> pull for him. This doesn't apply to upstream. Please post a new
> version that applies cleanly.
Hi Brian,
V2 sent that should apply cleanly. Thanks!
Colin Foster
^ permalink raw reply
* Re: [PATCH v11 2/3] dt-bindings: clock: imx95-blk-ctl: Define formatter child node schema
From: Frank Li @ 2026-06-29 20:59 UTC (permalink / raw)
To: guoniu.zhou
Cc: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Laurent Pinchart, Frank Li, Abel Vesa, Peng Fan,
Michael Turquette, Stephen Boyd, imx, linux-media, devicetree,
linux-arm-kernel, linux-kernel, linux-clk, Guoniu Zhou
In-Reply-To: <20260623-csi_formatter-v11-2-a792fe9c1502@oss.nxp.com>
On Tue, Jun 23, 2026 at 11:56:32AM +0800, guoniu.zhou@oss.nxp.com wrote:
> From: Guoniu Zhou <guoniu.zhou@nxp.com>
>
> The Camera CSR contains control registers for multiple CSI formatter IPs
> at different register offsets. Each formatter is an independent hardware
> block with its own clock input and media pipeline connection.
>
> Define schema to allow formatter child nodes under nxp,imx95-camera-csr,
> with 'reg' property specifying the formatter's register offset within the
> CSR address space.
>
> Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Changes in v11:
> - Move properties to top-level and use if:then:else (Krzysztof/Frank)
>
> Changes in v10:
> - Use single quotes for regex pattern to be consistent (Krzysztof Kozlowski)
> - Add formatter subnode binding and camera-csr syscon example
> - Update commit title and message
>
> Changes in v9:
> - New patch to address the issue of formatter acting as a child node of syscon
> ---
> .../bindings/clock/nxp,imx95-blk-ctl.yaml | 71 ++++++++++++++++++++++
> 1 file changed, 71 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> index 27403b4c52d6..fbbf1b3f1790 100644
> --- a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> +++ b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> @@ -39,6 +39,18 @@ properties:
> ID in its "clocks" phandle cell. See
> include/dt-bindings/clock/nxp,imx95-clock.h
>
> + '#address-cells':
> + const: 1
> +
> + '#size-cells':
> + const: 1
> +
> +patternProperties:
> + '^formatter@[0-9a-f]+$':
> + type: object
> + $ref: /schemas/media/fsl,imx95-csi-formatter.yaml#
> + unevaluatedProperties: false
> +
> required:
> - compatible
> - reg
> @@ -46,6 +58,23 @@ required:
> - power-domains
> - clocks
>
> +allOf:
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: nxp,imx95-camera-csr
> + then:
> + required:
> + - '#address-cells'
> + - '#size-cells'
> + else:
> + properties:
> + '#address-cells': false
> + '#size-cells': false
> + patternProperties:
> + '^formatter@[0-9a-f]+$': false
> +
> additionalProperties: false
>
> examples:
> @@ -57,4 +86,46 @@ examples:
> clocks = <&scmi_clk 114>;
> power-domains = <&scmi_devpd 21>;
> };
> +
> + - |
> + #include <dt-bindings/clock/nxp,imx95-clock.h>
> +
> + syscon@4ac10000 {
> + compatible = "nxp,imx95-camera-csr", "syscon";
> + reg = <0x4ac10000 0x10000>;
> + #address-cells = <1>;
> + #size-cells = <1>;
> + #clock-cells = <1>;
> + clocks = <&scmi_clk 62>;
> + power-domains = <&scmi_devpd 3>;
> +
> + formatter@20 {
> + compatible = "fsl,imx95-csi-formatter";
> + reg = <0x20 0x100>;
> + clocks = <&cameramix_csr IMX95_CLK_CAMBLK_CSI2_FOR0>;
> + power-domains = <&scmi_devpd 3>;
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + reg = <0>;
> +
> + endpoint {
> + remote-endpoint = <&mipi_csi_0_out>;
> + };
> +
> + };
> +
> + port@1 {
> + reg = <1>;
> +
> + endpoint {
> + remote-endpoint = <&isi_in_2>;
> + };
> + };
> + };
> + };
> + };
> ...
>
> --
> 2.34.1
>
^ permalink raw reply
* Re: [PATCH] arm64: dts: imx93-kontron: Fix memory node
From: Frank.Li @ 2026-06-29 21:08 UTC (permalink / raw)
To: Conor Dooley, devicetree, Frieder Schrempf, imx,
Krzysztof Kozlowski, linux-arm-kernel, linux-kernel, Rob Herring,
Sascha Hauer, Shawn Guo, Frieder Schrempf
Cc: Frank Li, Fabio Estevam, Pengutronix Kernel Team
In-Reply-To: <20260616104311.633297-1-frieder@fris.de>
From: Frank Li <Frank.Li@nxp.com>
On Tue, 16 Jun 2026 12:43:09 +0200, Frieder Schrempf wrote:
> The start address of the DRAM area is 0x80000000. The minimal
> size of the DDR on the SoM is 1 GiB. Fix this.
Applied, thanks!
[1/1] arm64: dts: imx93-kontron: Fix memory node
Rephrase commit message
Best regards,
--
Frank Li <Frank.Li@nxp.com>
^ permalink raw reply
* Re: [PATCH v1] arm64: dts: freescale: imx95-toradex-smarc: add alias for lpuart5
From: Frank.Li @ 2026-06-29 21:10 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Francesco Dolcini
Cc: Frank Li, Francesco Dolcini, devicetree, imx, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260622093507.44132-1-francesco@dolcini.it>
From: Frank Li <Frank.Li@nxp.com>
On Mon, 22 Jun 2026 11:35:06 +0200, Francesco Dolcini wrote:
> Add alias for lpuart5 so the UART gets a stable line number.
> Without this alias, the lpuart driver fails:
>
> fsl-lpuart 42590000.serial: failed to get alias id, errno -19
>
> This prevents the Bluetooth controller connected to this UART from
> working.
>
> [...]
Applied, thanks!
[1/1] arm64: dts: freescale: imx95-toradex-smarc: add alias for lpuart5
commit: 3385e2f77182469940c136b9eeedf01f27b7441f
Best regards,
--
Frank Li <Frank.Li@nxp.com>
^ permalink raw reply
* Re: [PATCH] ARM: imx: Drop obsolte stuff from common.h
From: Frank.Li @ 2026-06-29 21:12 UTC (permalink / raw)
To: Sascha Hauer, Uwe Kleine-König (The Capable Hub)
Cc: Frank Li, Pengutronix Kernel Team, Fabio Estevam,
linux-arm-kernel, imx
In-Reply-To: <20260623104557.1801727-2-u.kleine-koenig@baylibre.com>
From: Frank Li <Frank.Li@nxp.com>
On Tue, 23 Jun 2026 12:45:57 +0200, Uwe Kleine-König (The Capable Hub) wrote:
> i.MX21 (and thus imx21_init_early()) is gone since v5.10-rc1 (commit
> 4b563a066611 ("ARM: imx: Remove imx21 support")).
>
> The init_irq() functions are gone since v5.12-rc5 (commit e2c1b0ff38c9
> ("ARM: imx: avic: Convert to using IRQCHIP_DECLARE")).
>
> And mxc_device_init() was removed for v5.10-rc1 (in commit 8485adf17a15
> ("ARM: imx: Remove imx device directory")).
>
> [...]
Applied, thanks!
[1/1] ARM: imx: Drop obsolte stuff from common.h
commit: c195d4d1eeab9391f6ee16519c8ccf017adb1d98
Best regards,
--
Frank Li <Frank.Li@nxp.com>
^ permalink raw reply
* Re: [PATCH v5 5/5] PCI: qcom: Add D3cold support
From: Steev Klimaszewski @ 2026-06-29 21:16 UTC (permalink / raw)
To: krishna.chundru
Cc: bhelgaas, bjorn.andersson, jingoohan1, jonathanh, kwilczynski,
linux-arm-kernel, linux-arm-msm, linux-kernel, linux-pci,
lpieralisi, mani, robh, will
In-Reply-To: <20260429-d3cold-v5-5-89e9735b9df6@oss.qualcomm.com>
Hi Krishna, and Mani,
Turns out, this patchset causes issues but only on some machines. On a WDK2023
(Volterra), this breaks suspend, and on *my* X13s, it also seems to when using
the command `sudo rtcwake -m freeze -s 300` when resuming it crashes the
machine. Interestingly, it does not crash on another user's X13s.
Included is the info from Volterra's lspci -vvv and further down will be my
lspci -vvv - my X13s has a WD_BLACK 2TB SN770M in it which is not what it came
with from Lenovo.
WDK2023:
[alex@volterra d3-bug]$ cat volterra-info.txt
Linux volterra 7.0.14-gefea59a29f1a #17 SMP PREEMPT Mon Jun 29 14:47:59 CDT 2026 aarch64 GNU/Linux
Windows Dev Kit 2023BOOT_IMAGE=/@/boot/vmlinuz-linux root=UUID=a8f7fb76-9ae0-49af-a830-09025b783224 rw rootflags=subvol=@ loglevel=3 efi=noruntime clk_ignore_unused pd_ignore_unused regulator_ignore_unused arm64.nopauth
[alex@volterra d3-bug]$ cat volterra-lspci-vvv.txt
0002:00:00.0 PCI bridge: Qualcomm Technologies, Inc SC8280XP PCI Express Root Port (prog-if 00 [Normal decode])
Device tree node: /sys/firmware/devicetree/base/soc@0/pcie@1c20000/pcie@0
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupts: pin B disabled, MSI(X) routed to IRQ 182
Region 0: Memory at 3c700000 (32-bit, non-prefetchable) [size=4K]
Bus: primary=00, secondary=01, subordinate=ff, sec-latency=0
I/O behind bridge: 100000-100fff [size=4K] [16-bit]
Memory behind bridge: 3c300000-3c4fffff [size=2M] [32-bit]
Prefetchable memory behind bridge: 3c500000-3c6fffff [size=2M] [32-bit]
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
BridgeCtl: Parity- SERR+ NoISA- VGA- VGA16- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] MSI: Enable+ Count=1/32 Maskable+ 64bit+
Address: 0000000017a50040 Data: 0000
Masking: fffffffe Pending: 00000000
Capabilities: [70] Express (v2) Root Port (Slot+), IntMsgNum 0
DevCap: MaxPayload 256 bytes, PhantFunc 0
ExtTag- RBE+ TEE-IO-
DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
LnkCap: Port #0, Speed 8GT/s, Width x4, ASPM L1, Exit Latency L1 <64us
ClockPM- Surprise- LLActRep+ BwNot- ASPMOptComp+
LnkCtl: ASPM L1 Enabled; RCB 128 bytes, LnkDisable- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- FltModeDis-
LnkSta: Speed 8GT/s, Width x4
TrErr- Train- SlotClk+ DLActive+ BWMgmt- ABWMgmt-
SltCap: AttnBtn+ PwrCtrl+ MRL+ AttnInd+ PwrInd+ HotPlug+ Surprise+
Slot #0, PowerLimit 0W; Interlock+ NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
Control: AttnInd Off, PwrInd Off, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet- Interlock-
Changed: MRL- PresDet- LinkState-
RootCap: CRSVisible-
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+ NROPrPrP+ LTR+
10BitTagComp- 10BitTagReq- OBFF Not Supported, ExtFmt- EETLPPrefix-
EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
FRS- LN System CLS Not Supported, TPHComp+ ExtTPHComp- ARIFwd-
AtomicOpsCap: Routing- 32bit- 64bit- 128bitCAS-
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- ARIFwd-
AtomicOpsCtl: ReqEn- EgressBlck-
IDOReq- IDOCompl- LTR+ EmergencyPowerReductionReq-
10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
LnkCap2: Supported Link Speeds: 2.5-8GT/s, Crosslink- Retimer- 2Retimers- DRS-
LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-
Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete+ EqualizationPhase1+
EqualizationPhase2+ EqualizationPhase3+ LinkEqualizationRequest-
Retimer- 2Retimers- CrosslinkRes: unsupported, FltMode-
Capabilities: [100 v2] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr+ HeaderOF+
AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
MultHdrRecCap+ MultHdrRecEn- TLPPfxPres- HdrLogCap-
HeaderLog: 00000000 00000000 00000000 00000000
RootCmd: CERptEn+ NFERptEn+ FERptEn+
RootSta: CERcvd- MultCERcvd- UERcvd- MultUERcvd-
FirstFatal- NonFatalMsg- FatalMsg- IntMsgNum 0
ErrorSrc: ERR_COR: 0000 ERR_FATAL/NONFATAL: 0000
Capabilities: [148 v1] Secondary PCI Express
LnkCtl3: LnkEquIntrruptEn- PerformEqu-
LaneErrStat: 0
Capabilities: [168 v1] Transaction Processing Hints
No steering table available
Capabilities: [1fc v1] L1 PM Substates
L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ L1_PM_Substates+
PortCommonModeRestoreTime=70us PortTPowerOnTime=0us
L1SubCtl1: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+
T_CommonMode=70us LTR1.2_Threshold=136192ns
L1SubCtl2: T_PwrOn=60us
Capabilities: [20c v1] Vendor Specific Information: ID=0002 Rev=4 Len=100 <?>
Capabilities: [30c v1] Vendor Specific Information: ID=0001 Rev=1 Len=038 <?>
Capabilities: [344 v1] Vendor Specific Information: ID=0006 Rev=0 Len=018 <?>
Kernel driver in use: pcieport
0002:01:00.0 Non-Volatile memory controller: Silicon Motion, Inc. SM2269XT (DRAM-less) NVMe SSD Controller (rev 03) (prog-if 02 [NVM Express])
Subsystem: Silicon Motion, Inc. SM2269XT (DRAM-less) NVMe SSD Controller
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupts: pin B disabled, MSI(X) routed to IRQ 183-191
Region 0: Memory at 3c300000 (64-bit, non-prefetchable) [size=16K]
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] MSI: Enable- Count=1/16 Maskable+ 64bit+
Address: 0000000000000000 Data: 0000
Masking: 00000000 Pending: 00000000
Capabilities: [70] Express (v2) Endpoint, IntMsgNum 0
DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset+ SlotPowerLimit 0W TEE-IO-
DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop- FLReset-
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr- TransPend-
LnkCap: Port #0, Speed 16GT/s, Width x4, ASPM L1, Exit Latency L1 <64us
ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp+
LnkCtl: ASPM L1 Enabled; RCB 128 bytes, LnkDisable- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt- FltModeDis-
LnkSta: Speed 8GT/s (downgraded), Width x4
TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+ NROPrPrP- LTR+
10BitTagComp+ 10BitTagReq- OBFF Not Supported, ExtFmt- EETLPPrefix-
EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
FRS+ TPHComp- ExtTPHComp-
AtomicOpsCap: 32bit- 64bit- 128bitCAS-
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
AtomicOpsCtl: ReqEn-
IDOReq- IDOCompl- LTR+ EmergencyPowerReductionReq-
10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
LnkCap2: Supported Link Speeds: 2.5-16GT/s, Crosslink- Retimer+ 2Retimers+ DRS+
LnkCtl2: Target Link Speed: 16GT/s, EnterCompliance- SpeedDis-
Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete+ EqualizationPhase1+
EqualizationPhase2+ EqualizationPhase3+ LinkEqualizationRequest-
Retimer- 2Retimers- CrosslinkRes: Upstream Port, FltMode-
Capabilities: [b0] MSI-X: Enable+ Count=17 Masked-
Vector table: BAR=0 offset=00002000
PBA: BAR=0 offset=00003000
Capabilities: [100 v2] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr+ HeaderOF+
AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
HeaderLog: 00000000 00000000 00000000 00000000
Capabilities: [148 v1] Power Budgeting <?>
Capabilities: [158 v1] Alternative Routing-ID Interpretation (ARI)
ARICap: MFVC- ACS-, Next Function: 0
ARICtl: MFVC- ACS-, Function Group: 0
Capabilities: [168 v1] Secondary PCI Express
LnkCtl3: LnkEquIntrruptEn- PerformEqu-
LaneErrStat: 0
Capabilities: [188 v1] Physical Layer 16.0 GT/s
Phy16Sta: EquComplete- EquPhase1- EquPhase2- EquPhase3- LinkEquRequest-
Capabilities: [1ac v1] Lane Margining at the Receiver
PortCap: Uses Driver-
PortSta: MargReady- MargSoftReady-
Capabilities: [204 v1] Latency Tolerance Reporting
Max snoop latency: 0ns
Max no snoop latency: 0ns
Capabilities: [20c v1] L1 PM Substates
L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ L1_PM_Substates+
PortCommonModeRestoreTime=10us PortTPowerOnTime=60us
L1SubCtl1: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+
T_CommonMode=0us LTR1.2_Threshold=136192ns
L1SubCtl2: T_PwrOn=60us
Capabilities: [390 v1] Data Link Feature <?>
Kernel driver in use: nvme
Kernel modules: nvme
0006:00:00.0 PCI bridge: Qualcomm Technologies, Inc SC8280XP PCI Express Root Port (prog-if 00 [Normal decode])
Device tree node: /sys/firmware/devicetree/base/soc@0/pcie@1c00000/pcie@0
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupts: pin B disabled, MSI(X) routed to IRQ 237
Region 0: Memory at 30300000 (32-bit, non-prefetchable) [size=4K]
Bus: primary=00, secondary=01, subordinate=ff, sec-latency=0
I/O behind bridge: 1000-1fff [size=4K] [16-bit]
Memory behind bridge: 30400000-305fffff [size=2M] [32-bit]
Prefetchable memory behind bridge: 30600000-307fffff [size=2M] [32-bit]
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
BridgeCtl: Parity- SERR+ NoISA- VGA- VGA16- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] MSI: Enable+ Count=1/32 Maskable+ 64bit+
Address: 0000000017a50040 Data: 0000
Masking: fffffffe Pending: 00000000
Capabilities: [70] Express (v2) Root Port (Slot+), IntMsgNum 0
DevCap: MaxPayload 128 bytes, PhantFunc 0
ExtTag- RBE+ TEE-IO-
DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
LnkCap: Port #0, Speed 5GT/s, Width x1, ASPM L1, Exit Latency L1 <64us
ClockPM- Surprise+ LLActRep+ BwNot+ ASPMOptComp+
LnkCtl: ASPM L1 Enabled; RCB 128 bytes, LnkDisable- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt+ AutBWInt+ FltModeDis-
LnkSta: Speed 5GT/s, Width x1
TrErr- Train- SlotClk+ DLActive+ BWMgmt- ABWMgmt-
SltCap: AttnBtn+ PwrCtrl+ MRL+ AttnInd+ PwrInd+ HotPlug+ Surprise+
Slot #0, PowerLimit 0W; Interlock+ NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
Control: AttnInd Off, PwrInd Off, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet- Interlock-
Changed: MRL- PresDet- LinkState-
RootCap: CRSVisible+
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible+
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+ NROPrPrP+ LTR+
10BitTagComp- 10BitTagReq- OBFF Not Supported, ExtFmt- EETLPPrefix-
EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
FRS- LN System CLS Not Supported, TPHComp+ ExtTPHComp- ARIFwd-
AtomicOpsCap: Routing- 32bit- 64bit- 128bitCAS-
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- ARIFwd-
AtomicOpsCtl: ReqEn- EgressBlck-
IDOReq- IDOCompl- LTR+ EmergencyPowerReductionReq-
10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
LnkCap2: Supported Link Speeds: 2.5-5GT/s, Crosslink- Retimer- 2Retimers- DRS-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-
Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete- EqualizationPhase1-
EqualizationPhase2- EqualizationPhase3- LinkEqualizationRequest-
Retimer- 2Retimers- CrosslinkRes: unsupported, FltMode-
Capabilities: [100 v2] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr+ HeaderOF+
AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
MultHdrRecCap+ MultHdrRecEn- TLPPfxPres- HdrLogCap-
HeaderLog: 00000000 00000000 00000000 00000000
RootCmd: CERptEn+ NFERptEn+ FERptEn+
RootSta: CERcvd- MultCERcvd- UERcvd- MultUERcvd-
FirstFatal- NonFatalMsg- FatalMsg- IntMsgNum 0
ErrorSrc: ERR_COR: 0000 ERR_FATAL/NONFATAL: 0000
Capabilities: [148 v1] Secondary PCI Express
LnkCtl3: LnkEquIntrruptEn- PerformEqu-
LaneErrStat: 0
Capabilities: [158 v1] Transaction Processing Hints
No steering table available
Capabilities: [1ec v1] L1 PM Substates
L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ L1_PM_Substates+
PortCommonModeRestoreTime=70us PortTPowerOnTime=0us
L1SubCtl1: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+
T_CommonMode=70us LTR1.2_Threshold=76800ns
L1SubCtl2: T_PwrOn=0us
Capabilities: [1fc v1] Vendor Specific Information: ID=0002 Rev=4 Len=100 <?>
Capabilities: [2fc v1] Vendor Specific Information: ID=0001 Rev=1 Len=038 <?>
Kernel driver in use: pcieport
0006:01:00.0 Network controller: Qualcomm Technologies, Inc QCNFA765 Wireless Network Adapter (rev 01)
Subsystem: Qualcomm Technologies, Inc Device 0108
Device tree node: /sys/firmware/devicetree/base/soc@0/pcie@1c00000/pcie@0/wifi@0
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupts: MSI(X) routed to IRQ 245-276
Region 0: Memory at 30400000 (64-bit, non-prefetchable) [size=2M]
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] MSI: Enable+ Count=32/32 Maskable+ 64bit-
Address: 17a50040 Data: 0000
Masking: fe023c00 Pending: 00000000
Capabilities: [70] Express (v2) Endpoint, IntMsgNum 0
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 0W TEE-IO-
DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
LnkCap: Port #0, Speed 8GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <1us, L1 <64us
ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp+
LnkCtl: ASPM L1 Enabled; RCB 128 bytes, LnkDisable- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- FltModeDis-
LnkSta: Speed 5GT/s (downgraded), Width x1
TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+ NROPrPrP- LTR+
10BitTagComp- 10BitTagReq- OBFF Not Supported, ExtFmt- EETLPPrefix-
EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
FRS- TPHComp+ ExtTPHComp-
AtomicOpsCap: 32bit- 64bit- 128bitCAS-
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
AtomicOpsCtl: ReqEn-
IDOReq- IDOCompl- LTR+ EmergencyPowerReductionReq-
10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
LnkCap2: Supported Link Speeds: 2.5-8GT/s, Crosslink- Retimer- 2Retimers- DRS-
LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-
Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete- EqualizationPhase1-
EqualizationPhase2- EqualizationPhase3- LinkEqualizationRequest-
Retimer- 2Retimers- CrosslinkRes: unsupported, FltMode-
Capabilities: [100 v2] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr+ HeaderOF+
AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
HeaderLog: 00000000 00000000 00000000 00000000
Capabilities: [148 v1] Secondary PCI Express
LnkCtl3: LnkEquIntrruptEn- PerformEqu-
LaneErrStat: 0
Capabilities: [158 v1] Transaction Processing Hints
No steering table available
Capabilities: [1e4 v1] Latency Tolerance Reporting
Max snoop latency: 0ns
Max no snoop latency: 0ns
Capabilities: [1ec v1] L1 PM Substates
L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ L1_PM_Substates+
PortCommonModeRestoreTime=70us PortTPowerOnTime=0us
L1SubCtl1: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+
T_CommonMode=0us LTR1.2_Threshold=76800ns
L1SubCtl2: T_PwrOn=0us
Kernel driver in use: ath11k_pci
Kernel modules: ath11k_pci
X13s:
cmdline.txt: BOOT_IMAGE=/boot/vmlinuz-7.0.14 root=UUID=dc44a82f-6d97-490e-a4be-4c3bceacc658 ro arm64.nopauth ipv6.disable=1 clk_ignore_unused mitigations=off cfg80211.ieee80211_regdom=US efi=noruntime printk.always_kmsg_dump=Y efi_pstore.pstore_disable=N quiet splash
lspci -vvv:
steev@finn:~$ sudo lspci -vvv
[sudo] password for steev:
0002:00:00.0 PCI bridge: Qualcomm Technologies, Inc SC8280XP PCI Express Root Port (prog-if 00 [Normal decode])
Device tree node: /sys/firmware/devicetree/base/soc@0/pcie@1c20000/pcie@0
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupts: pin B disabled, MSI(X) routed to IRQ 215
IOMMU group: 14
Region 0: Memory at 3c700000 (32-bit, non-prefetchable) [size=4K]
Bus: primary=00, secondary=01, subordinate=ff, sec-latency=0
I/O behind bridge: 200000-200fff [size=4K] [16-bit]
Memory behind bridge: 3c300000-3c4fffff [size=2M] [32-bit]
Prefetchable memory behind bridge: 3c500000-3c6fffff [size=2M] [32-bit]
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
BridgeCtl: Parity- SERR+ NoISA- VGA- VGA16- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] MSI: Enable+ Count=1/32 Maskable+ 64bit+
Address: 00000000fffff040 Data: 0000
Masking: fffffffe Pending: 00000000
Capabilities: [70] Express (v2) Root Port (Slot+), IntMsgNum 0
DevCap: MaxPayload 256 bytes, PhantFunc 0
ExtTag- RBE+ TEE-IO-
DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
LnkCap: Port #0, Speed 8GT/s, Width x4, ASPM L1, Exit Latency L1 <64us
ClockPM- Surprise- LLActRep+ BwNot- ASPMOptComp+
LnkCtl: ASPM L1 Enabled; RCB 128 bytes, LnkDisable- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- FltModeDis-
LnkSta: Speed 8GT/s, Width x4
TrErr- Train- SlotClk+ DLActive+ BWMgmt- ABWMgmt-
SltCap: AttnBtn+ PwrCtrl+ MRL+ AttnInd+ PwrInd+ HotPlug+ Surprise+
Slot #0, PowerLimit 0W; Interlock+ NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
Control: AttnInd Off, PwrInd Off, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet- Interlock-
Changed: MRL- PresDet- LinkState-
RootCap: CRSVisible-
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+ NROPrPrP+ LTR+
10BitTagComp- 10BitTagReq- OBFF Not Supported, ExtFmt- EETLPPrefix-
EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
FRS- LN System CLS Not Supported, TPHComp+ ExtTPHComp- ARIFwd-
AtomicOpsCap: Routing- 32bit- 64bit- 128bitCAS-
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- ARIFwd-
AtomicOpsCtl: ReqEn- EgressBlck-
IDOReq- IDOCompl- LTR+ EmergencyPowerReductionReq-
10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
LnkCap2: Supported Link Speeds: 2.5-8GT/s, Crosslink- Retimer- 2Retimers- DRS-
LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-
Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete+ EqualizationPhase1+
EqualizationPhase2+ EqualizationPhase3+ LinkEqualizationRequest-
Retimer- 2Retimers- CrosslinkRes: unsupported, FltMode-
Capabilities: [100 v2] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr+ HeaderOF+
AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
MultHdrRecCap+ MultHdrRecEn- TLPPfxPres- HdrLogCap-
HeaderLog: 00000000 00000000 00000000 00000000
RootCmd: CERptEn+ NFERptEn+ FERptEn+
RootSta: CERcvd- MultCERcvd- UERcvd- MultUERcvd-
FirstFatal- NonFatalMsg- FatalMsg- IntMsgNum 0
ErrorSrc: ERR_COR: 0000 ERR_FATAL/NONFATAL: 0000
Capabilities: [148 v1] Secondary PCI Express
LnkCtl3: LnkEquIntrruptEn- PerformEqu-
LaneErrStat: 0
Capabilities: [168 v1] Transaction Processing Hints
No steering table available
Capabilities: [1fc v1] L1 PM Substates
L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ L1_PM_Substates+
PortCommonModeRestoreTime=70us PortTPowerOnTime=0us
L1SubCtl1: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1-
T_CommonMode=70us LTR1.2_Threshold=86016ns
L1SubCtl2: T_PwrOn=10us
Capabilities: [20c v1] Vendor Specific Information: ID=0002 Rev=4 Len=100 <?>
Capabilities: [30c v1] Vendor Specific Information: ID=0001 Rev=1 Len=038 <?>
Capabilities: [344 v1] Vendor Specific Information: ID=0006 Rev=0 Len=018 <?>
Kernel driver in use: pcieport
0002:01:00.0 Non-Volatile memory controller: Sandisk Corp WD Black SN770M NVMe SSD (DRAM-less) (rev 01) (prog-if 02 [NVM Express])
Subsystem: Sandisk Corp WD Black SN770M NVMe SSD (DRAM-less)
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupts: pin B disabled, MSI(X) routed to IRQ 253-261
IOMMU group: 14
Region 0: Memory at 3c300000 (64-bit, non-prefetchable) [size=16K]
Capabilities: [80] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [90] MSI: Enable- Count=1/32 Maskable- 64bit+
Address: 0000000000000000 Data: 0000
Capabilities: [b0] MSI-X: Enable+ Count=65 Masked-
Vector table: BAR=0 offset=00003000
PBA: BAR=0 offset=00002000
Capabilities: [c0] Express (v2) Endpoint, IntMsgNum 0
DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s <1us, L1 unlimited
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset+ SlotPowerLimit 0W TEE-IO-
DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+ FLReset-
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr- TransPend-
LnkCap: Port #0, Speed 16GT/s, Width x4, ASPM L1, Exit Latency L1 <8us
ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp+
LnkCtl: ASPM L1 Enabled; RCB 128 bytes, LnkDisable- CommClk+
ExtSynch+ ClockPM- AutWidDis- BWInt- AutBWInt- FltModeDis-
LnkSta: Speed 8GT/s (downgraded), Width x4
TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
DevCap2: Completion Timeout: Range B, TimeoutDis+ NROPrPrP- LTR+
10BitTagComp+ 10BitTagReq- OBFF Not Supported, ExtFmt+ EETLPPrefix-
EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
FRS- TPHComp- ExtTPHComp-
AtomicOpsCap: 32bit- 64bit- 128bitCAS-
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
AtomicOpsCtl: ReqEn-
IDOReq- IDOCompl- LTR+ EmergencyPowerReductionReq-
10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
LnkCap2: Supported Link Speeds: 2.5-16GT/s, Crosslink- Retimer+ 2Retimers+ DRS-
LnkCtl2: Target Link Speed: 16GT/s, EnterCompliance- SpeedDis-
Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete+ EqualizationPhase1+
EqualizationPhase2+ EqualizationPhase3+ LinkEqualizationRequest-
Retimer- 2Retimers- CrosslinkRes: unsupported, FltMode-
Capabilities: [100 v2] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr+ HeaderOF+
AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
HeaderLog: 00000000 00000000 00000000 00000000
Capabilities: [1b8 v1] Latency Tolerance Reporting
Max snoop latency: 0ns
Max no snoop latency: 0ns
Capabilities: [300 v1] Secondary PCI Express
LnkCtl3: LnkEquIntrruptEn- PerformEqu-
LaneErrStat: 0
Capabilities: [900 v1] L1 PM Substates
L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1- L1_PM_Substates+
PortCommonModeRestoreTime=32us PortTPowerOnTime=10us
L1SubCtl1: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1-
T_CommonMode=0us LTR1.2_Threshold=86016ns
L1SubCtl2: T_PwrOn=10us
Capabilities: [910 v1] Data Link Feature <?>
Capabilities: [920 v1] Lane Margining at the Receiver
PortCap: Uses Driver+
PortSta: MargReady- MargSoftReady+
Capabilities: [9c0 v1] Physical Layer 16.0 GT/s
Phy16Sta: EquComplete- EquPhase1- EquPhase2- EquPhase3- LinkEquRequest-
Kernel driver in use: nvme
Kernel modules: nvme
0004:00:00.0 PCI bridge: Qualcomm Technologies, Inc SC8280XP PCI Express Root Port (prog-if 00 [Normal decode])
Device tree node: /sys/firmware/devicetree/base/soc@0/pcie@1c10000/pcie@0
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupts: MSI(X) routed to IRQ 217
IOMMU group: 15
Region 0: Memory at 34700000 (32-bit, non-prefetchable) [size=4K]
Bus: primary=00, secondary=01, subordinate=ff, sec-latency=0
I/O behind bridge: 1000-1fff [size=4K] [16-bit]
Memory behind bridge: 34300000-344fffff [size=2M] [32-bit]
Prefetchable memory behind bridge: 34500000-346fffff [size=2M] [32-bit]
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
BridgeCtl: Parity- SERR+ NoISA- VGA- VGA16- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] MSI: Enable+ Count=1/32 Maskable+ 64bit+
Address: 00000000fffff040 Data: 0000
Masking: fffffffe Pending: 00000000
Capabilities: [70] Express (v2) Root Port (Slot+), IntMsgNum 0
DevCap: MaxPayload 256 bytes, PhantFunc 0
ExtTag- RBE+ TEE-IO-
DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
LnkCap: Port #0, Speed 8GT/s, Width x4, ASPM L1, Exit Latency L1 <16us
ClockPM- Surprise+ LLActRep+ BwNot+ ASPMOptComp+
LnkCtl: ASPM Disabled; RCB 128 bytes, LnkDisable- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt+ AutBWInt+ FltModeDis-
LnkSta: Speed 2.5GT/s, Width x1
TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
SltCap: AttnBtn+ PwrCtrl+ MRL+ AttnInd+ PwrInd+ HotPlug+ Surprise+
Slot #0, PowerLimit 0W; Interlock+ NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
Control: AttnInd Off, PwrInd Off, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet- Interlock-
Changed: MRL- PresDet- LinkState-
RootCap: CRSVisible+
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible+
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+ NROPrPrP+ LTR+
10BitTagComp- 10BitTagReq- OBFF Not Supported, ExtFmt- EETLPPrefix-
EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
FRS- LN System CLS Not Supported, TPHComp+ ExtTPHComp- ARIFwd-
AtomicOpsCap: Routing- 32bit- 64bit- 128bitCAS-
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- ARIFwd-
AtomicOpsCtl: ReqEn- EgressBlck-
IDOReq- IDOCompl- LTR- EmergencyPowerReductionReq-
10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
LnkCap2: Supported Link Speeds: 2.5-8GT/s, Crosslink- Retimer- 2Retimers- DRS-
LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-
Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete- EqualizationPhase1-
EqualizationPhase2- EqualizationPhase3- LinkEqualizationRequest-
Retimer- 2Retimers- CrosslinkRes: unsupported, FltMode-
Capabilities: [100 v2] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr+ HeaderOF+
AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
MultHdrRecCap+ MultHdrRecEn- TLPPfxPres- HdrLogCap-
HeaderLog: 00000000 00000000 00000000 00000000
RootCmd: CERptEn+ NFERptEn+ FERptEn+
RootSta: CERcvd- MultCERcvd- UERcvd- MultUERcvd-
FirstFatal- NonFatalMsg- FatalMsg- IntMsgNum 0
ErrorSrc: ERR_COR: 0000 ERR_FATAL/NONFATAL: 0000
Capabilities: [148 v1] Secondary PCI Express
LnkCtl3: LnkEquIntrruptEn- PerformEqu-
LaneErrStat: 0
Capabilities: [168 v1] Transaction Processing Hints
No steering table available
Capabilities: [1fc v1] L1 PM Substates
L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ L1_PM_Substates+
PortCommonModeRestoreTime=70us PortTPowerOnTime=0us
L1SubCtl1: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2- ASPM_L1.1-
T_CommonMode=70us LTR1.2_Threshold=0ns
L1SubCtl2: T_PwrOn=10us
Capabilities: [20c v1] Vendor Specific Information: ID=0002 Rev=4 Len=100 <?>
Capabilities: [30c v1] Vendor Specific Information: ID=0001 Rev=1 Len=038 <?>
Capabilities: [344 v1] Vendor Specific Information: ID=0006 Rev=0 Len=018 <?>
Kernel driver in use: pcieport
0006:00:00.0 PCI bridge: Qualcomm Technologies, Inc SC8280XP PCI Express Root Port (prog-if 00 [Normal decode])
Device tree node: /sys/firmware/devicetree/base/soc@0/pcie@1c00000/pcie@0
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupts: pin B disabled, MSI(X) routed to IRQ 267
IOMMU group: 35
Region 0: Memory at 30300000 (32-bit, non-prefetchable) [size=4K]
Bus: primary=00, secondary=01, subordinate=ff, sec-latency=0
I/O behind bridge: 100000-100fff [size=4K] [16-bit]
Memory behind bridge: 30400000-305fffff [size=2M] [32-bit]
Prefetchable memory behind bridge: 30600000-307fffff [size=2M] [32-bit]
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
BridgeCtl: Parity- SERR+ NoISA- VGA- VGA16- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] MSI: Enable+ Count=1/32 Maskable+ 64bit+
Address: 00000000fffff040 Data: 0000
Masking: fffffffe Pending: 00000000
Capabilities: [70] Express (v2) Root Port (Slot+), IntMsgNum 0
DevCap: MaxPayload 128 bytes, PhantFunc 0
ExtTag- RBE+ TEE-IO-
DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
LnkCap: Port #0, Speed 5GT/s, Width x1, ASPM L1, Exit Latency L1 <64us
ClockPM- Surprise+ LLActRep+ BwNot+ ASPMOptComp+
LnkCtl: ASPM L1 Enabled; RCB 128 bytes, LnkDisable- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt+ AutBWInt+ FltModeDis-
LnkSta: Speed 5GT/s, Width x1
TrErr- Train- SlotClk+ DLActive+ BWMgmt- ABWMgmt-
SltCap: AttnBtn+ PwrCtrl+ MRL+ AttnInd+ PwrInd+ HotPlug+ Surprise+
Slot #0, PowerLimit 0W; Interlock+ NoCompl+
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
Control: AttnInd Off, PwrInd Off, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet- Interlock-
Changed: MRL- PresDet- LinkState-
RootCap: CRSVisible+
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible+
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+ NROPrPrP+ LTR+
10BitTagComp- 10BitTagReq- OBFF Not Supported, ExtFmt- EETLPPrefix-
EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
FRS- LN System CLS Not Supported, TPHComp+ ExtTPHComp- ARIFwd-
AtomicOpsCap: Routing- 32bit- 64bit- 128bitCAS-
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- ARIFwd-
AtomicOpsCtl: ReqEn- EgressBlck-
IDOReq- IDOCompl- LTR+ EmergencyPowerReductionReq-
10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
LnkCap2: Supported Link Speeds: 2.5-5GT/s, Crosslink- Retimer- 2Retimers- DRS-
LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-
Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete- EqualizationPhase1-
EqualizationPhase2- EqualizationPhase3- LinkEqualizationRequest-
Retimer- 2Retimers- CrosslinkRes: unsupported, FltMode-
Capabilities: [100 v2] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr+ HeaderOF+
AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
MultHdrRecCap+ MultHdrRecEn- TLPPfxPres- HdrLogCap-
HeaderLog: 00000000 00000000 00000000 00000000
RootCmd: CERptEn+ NFERptEn+ FERptEn+
RootSta: CERcvd- MultCERcvd- UERcvd- MultUERcvd-
FirstFatal- NonFatalMsg- FatalMsg- IntMsgNum 0
ErrorSrc: ERR_COR: 0000 ERR_FATAL/NONFATAL: 0000
Capabilities: [148 v1] Secondary PCI Express
LnkCtl3: LnkEquIntrruptEn- PerformEqu-
LaneErrStat: 0
Capabilities: [158 v1] Transaction Processing Hints
No steering table available
Capabilities: [1ec v1] L1 PM Substates
L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ L1_PM_Substates+
PortCommonModeRestoreTime=70us PortTPowerOnTime=0us
L1SubCtl1: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+
T_CommonMode=70us LTR1.2_Threshold=76800ns
L1SubCtl2: T_PwrOn=0us
Capabilities: [1fc v1] Vendor Specific Information: ID=0002 Rev=4 Len=100 <?>
Capabilities: [2fc v1] Vendor Specific Information: ID=0001 Rev=1 Len=038 <?>
Kernel driver in use: pcieport
0006:01:00.0 Network controller: Qualcomm Technologies, Inc QCNFA765 Wireless Network Adapter (rev 01)
Subsystem: Qualcomm Technologies, Inc Device 0108
Device tree node: /sys/firmware/devicetree/base/soc@0/pcie@1c00000/pcie@0/wifi@0
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupts: MSI(X) routed to IRQ 288-319
IOMMU group: 35
Region 0: Memory at 30400000 (64-bit, non-prefetchable) [size=2M]
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] MSI: Enable+ Count=32/32 Maskable+ 64bit-
Address: fffff040 Data: 0000
Masking: fe023c00 Pending: 00000000
Capabilities: [70] Express (v2) Endpoint, IntMsgNum 0
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 0W TEE-IO-
DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend+
LnkCap: Port #0, Speed 8GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <1us, L1 <64us
ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp+
LnkCtl: ASPM L1 Enabled; RCB 128 bytes, LnkDisable- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- FltModeDis-
LnkSta: Speed 5GT/s (downgraded), Width x1
TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+ NROPrPrP- LTR+
10BitTagComp- 10BitTagReq- OBFF Not Supported, ExtFmt- EETLPPrefix-
EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
FRS- TPHComp+ ExtTPHComp-
AtomicOpsCap: 32bit- 64bit- 128bitCAS-
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-
AtomicOpsCtl: ReqEn-
IDOReq- IDOCompl- LTR+ EmergencyPowerReductionReq-
10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
LnkCap2: Supported Link Speeds: 2.5-8GT/s, Crosslink- Retimer- 2Retimers- DRS-
LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-
Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete- EqualizationPhase1-
EqualizationPhase2- EqualizationPhase3- LinkEqualizationRequest-
Retimer- 2Retimers- CrosslinkRes: unsupported, FltMode-
Capabilities: [100 v2] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr+ HeaderOF+
AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
HeaderLog: 00000000 00000000 00000000 00000000
Capabilities: [148 v1] Secondary PCI Express
LnkCtl3: LnkEquIntrruptEn- PerformEqu-
LaneErrStat: 0
Capabilities: [158 v1] Transaction Processing Hints
No steering table available
Capabilities: [1e4 v1] Latency Tolerance Reporting
Max snoop latency: 0ns
Max no snoop latency: 0ns
Capabilities: [1ec v1] L1 PM Substates
L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ L1_PM_Substates+
PortCommonModeRestoreTime=70us PortTPowerOnTime=0us
L1SubCtl1: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+
T_CommonMode=0us LTR1.2_Threshold=76800ns
L1SubCtl2: T_PwrOn=0us
Kernel driver in use: ath11k_pci
Kernel modules: ath11k_pci
Sorry for taking so long to reply about this, Konrad suggested we provide the
info now, as I have been applying the patchset to a 7.0 kernel, but I know the
patchset is already in -next (maybe 7.1?)
-- steev
^ permalink raw reply
* [PATCH v1 0/5] iommufd: Iterate the cache invalidation array in the core
From: Nicolin Chen @ 2026-06-29 21:15 UTC (permalink / raw)
To: Will Deacon, Jason Gunthorpe, Kevin Tian, Lu Baolu
Cc: Robin Murphy, joro, David Woodhouse, linux-arm-kernel, iommu,
linux-kernel
The vIOMMU cache_invalidate() and the nested-HWPT cache_invalidate_user()
ops are each handed the full user invalidation array and must report, via
array->entry_num, how many of its entries they handled. That makes every
driver open-code the same array walk, with real downsides:
- each driver carries its own loop and sub-array bookkeeping;
- the ARM SMMUv3 driver allocates a buffer sized to the whole array just
to iterate over it;
- hand-rolling the loop left the ARM SMMUv3 driver with two long-standing
bugs:
1) on a conversion failure it counts commands that it converted but
never issued, so user space skips invalidations that never reached
the cmdq;
2) it rejects a zero-length array, which the uAPI documents as a valid
request that only probes the data type.
The walk is identical for every driver, so move it into the iommufd core.
The core now drives the iteration:
- it invokes the op on a sub-array starting at the first not-yet-handled
entry;
- the op handles one chunk from the front of that sub-array and reports
the count via array->entry_num;
- the core advances and re-invokes until the whole array is consumed or
the op returns an error.
A driver then only has to handle one bounded chunk per call, e.g. the ARM
SMMUv3 op copies a single cmdq batch into a fixed on-stack buffer and drops
its whole-array allocation. An op still handling the entire array in one
call keeps working, so each driver converts independently.
These are long-standing corner cases, so this targets for-next, not for-rc.
This is on Github:
https://github.com/nicolinc/iommufd/commits/iommufd_invalidation_loop-v1
[Note to Jason and Will]
This has some conflicts with Ashish's ARM_SMMU_OPT_REPEAT_TLBI_CFGI series:
https://lore.kernel.org/all/20260609073204.1760077-1-amhetre@nvidia.com/
Nicolin Chen (5):
iommu/arm-smmu-v3-iommufd: Reject unsupported bits in invalidation
commands
iommufd: Iterate the cache invalidation array in the core
iommufd/selftest: Convert cache invalidation mocks to the core array
loop
iommu/arm-smmu-v3-iommufd: Convert cache invalidation to the core
array loop
iommu/vt-d: Convert nested cache invalidation to the core array loop
include/linux/iommu.h | 6 +-
include/linux/iommufd.h | 2 +
.../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 131 ++++++++++++----
drivers/iommu/intel/nested.c | 54 ++++---
drivers/iommu/iommufd/hw_pagetable.c | 22 ++-
drivers/iommu/iommufd/selftest.c | 147 +++++++++---------
6 files changed, 222 insertions(+), 140 deletions(-)
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
--
2.43.0
^ permalink raw reply
* [PATCH v1 2/5] iommufd: Iterate the cache invalidation array in the core
From: Nicolin Chen @ 2026-06-29 21:15 UTC (permalink / raw)
To: Will Deacon, Jason Gunthorpe, Kevin Tian, Lu Baolu
Cc: Robin Murphy, joro, David Woodhouse, linux-arm-kernel, iommu,
linux-kernel
In-Reply-To: <cover.1782767398.git.nicolinc@nvidia.com>
The cache invalidation ops, cache_invalidate_user() for a nested HWPT and
the cache_invalidate() for a vIOMMU, are each handed the full user request
array and report how many of the array entries they handled by setting the
array->entry_num. Every driver therefore implements its own loop over the
array, and a driver wanting to process that array in fixed-size chunks
(e.g. to issue commands out of a fixed-size on-stack buffer) has to carry
the loop and its sub-array bookkeeping all on its own.
Move the iteration into the iommufd core instead. Invoke the op with a
sub-array that starts at the first not-yet-handled entry, let it handle a
prefix of that sub-array and report the count via array->entry_num, then
advance the base pointer and re-invoke the op until the entire array has
been consumed or until the op returns an error along the way.
A driver that handles the entire window in one single call, as all of the
current drivers happen to do, finishes the loop in just one pass, so this
does not change any of the existing behavior. It instead lets each of the
drivers convert to bounded chunk processing on its own, done by each of the
following changes.
Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
include/linux/iommu.h | 6 ++++--
include/linux/iommufd.h | 2 ++
drivers/iommu/iommufd/hw_pagetable.c | 22 +++++++++++++++++-----
3 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index d20aa6f6863ab..969758f87e445 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -773,8 +773,10 @@ struct iommu_ops {
* passes in the cache invalidation requests, in form
* of a driver data structure. The driver must update
* array->entry_num to report the number of handled
- * invalidation requests. The driver data structure
- * must be defined in include/uapi/linux/iommufd.h
+ * invalidation requests. A driver may handle fewer than
+ * the requested, in which case the core re-invokes the
+ * op for the remainder. The driver data structure must
+ * be defined in include/uapi/linux/iommufd.h
* @iova_to_phys: translate iova to physical address
* @enforce_cache_coherency: Prevent any kind of DMA from bypassing IOMMU_CACHE,
* including no-snoop TLPs on PCIe or other platform
diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index 6e7efe83bc5d8..3087f5b2def84 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -154,6 +154,8 @@ struct iommufd_hw_queue {
* The @array passes in the cache invalidation requests, in
* form of a driver data structure. A driver must update the
* array->entry_num to report the number of handled requests.
+ * A driver may handle fewer than the requested entry_num, in
+ * which case the core re-invokes the op for the remainder.
* The data structure of the array entry must be defined in
* include/uapi/linux/iommufd.h
* @vdevice_size: Size of the driver-defined vDEVICE structure per this vIOMMU
diff --git a/drivers/iommu/iommufd/hw_pagetable.c b/drivers/iommu/iommufd/hw_pagetable.c
index 623cc608ca0cd..409ba2216f8bd 100644
--- a/drivers/iommu/iommufd/hw_pagetable.c
+++ b/drivers/iommu/iommufd/hw_pagetable.c
@@ -535,8 +535,15 @@ int iommufd_hwpt_invalidate(struct iommufd_ucmd *ucmd)
rc = -EOPNOTSUPP;
goto out_put_pt;
}
- rc = hwpt->domain->ops->cache_invalidate_user(hwpt->domain,
- &data_array);
+ do {
+ rc = hwpt->domain->ops->cache_invalidate_user(
+ hwpt->domain, &data_array);
+
+ done_num += data_array.entry_num;
+ data_array.uptr +=
+ data_array.entry_num * cmd->entry_len;
+ data_array.entry_num = cmd->entry_num - done_num;
+ } while (!rc && done_num != cmd->entry_num);
} else if (pt_obj->type == IOMMUFD_OBJ_VIOMMU) {
struct iommufd_viommu *viommu =
container_of(pt_obj, struct iommufd_viommu, obj);
@@ -545,14 +552,19 @@ int iommufd_hwpt_invalidate(struct iommufd_ucmd *ucmd)
rc = -EOPNOTSUPP;
goto out_put_pt;
}
- rc = viommu->ops->cache_invalidate(viommu, &data_array);
+ do {
+ rc = viommu->ops->cache_invalidate(viommu, &data_array);
+
+ done_num += data_array.entry_num;
+ data_array.uptr +=
+ data_array.entry_num * cmd->entry_len;
+ data_array.entry_num = cmd->entry_num - done_num;
+ } while (!rc && done_num != cmd->entry_num);
} else {
rc = -EINVAL;
goto out_put_pt;
}
- done_num = data_array.entry_num;
-
out_put_pt:
iommufd_put_object(ucmd->ictx, pt_obj);
out:
--
2.43.0
^ permalink raw reply related
* [PATCH v1 3/5] iommufd/selftest: Convert cache invalidation mocks to the core array loop
From: Nicolin Chen @ 2026-06-29 21:15 UTC (permalink / raw)
To: Will Deacon, Jason Gunthorpe, Kevin Tian, Lu Baolu
Cc: Robin Murphy, joro, David Woodhouse, linux-arm-kernel, iommu,
linux-kernel
In-Reply-To: <cover.1782767398.git.nicolinc@nvidia.com>
The vIOMMU and the nested-domain selftest invalidation mocks each used to
walk the whole request array on their own, with the vIOMMU mock even
allocating a buffer sized to the entire array in order to do so first.
The iommufd core now iterates the request array itself and re-invokes the
op with the not-yet-handled sub-array, so handle just a single request per
call out of the front of that sub-array and report one handled entry via
the array->entry_num. Drop both of the loops and the kzalloc_objs() in the
viommu callback function, and keep returning a success for an empty array
as a probe of the selftest data type.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommufd/selftest.c | 147 +++++++++++++++----------------
1 file changed, 72 insertions(+), 75 deletions(-)
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index af07c642a5260..51da687e432ef 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -631,70 +631,63 @@ mock_viommu_alloc_domain_nested(struct iommufd_viommu *viommu, u32 flags,
static int mock_viommu_cache_invalidate(struct iommufd_viommu *viommu,
struct iommu_user_data_array *array)
{
- struct iommu_viommu_invalidate_selftest *cmds;
- struct iommu_viommu_invalidate_selftest *cur;
- struct iommu_viommu_invalidate_selftest *end;
- int rc;
+ struct iommu_viommu_invalidate_selftest cmd;
+ struct mock_dev *mdev;
+ struct device *dev;
+ u32 processed = 0;
+ int rc = 0;
+ int i;
- /* A zero-length array is allowed to validate the array type */
- if (array->entry_num == 0 &&
- array->type == IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST) {
- array->entry_num = 0;
- return 0;
+ if (array->type != IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST) {
+ rc = -EINVAL;
+ goto out;
}
- cmds = kzalloc_objs(*cmds, array->entry_num);
- if (!cmds)
- return -ENOMEM;
- cur = cmds;
- end = cmds + array->entry_num;
+ /*
+ * The core re-invokes this op for the remaining requests, so handle one
+ * request per call. A zero-length array only probes the type, validated
+ * above.
+ */
+ if (!array->entry_num)
+ goto out;
- static_assert(sizeof(*cmds) == 3 * sizeof(u32));
- rc = iommu_copy_struct_from_full_user_array(
- cmds, sizeof(*cmds), array,
- IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST);
+ rc = iommu_copy_struct_from_user_array(
+ &cmd, array, IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST, 0,
+ cache_id);
if (rc)
goto out;
- while (cur != end) {
- struct mock_dev *mdev;
- struct device *dev;
- int i;
-
- if (cur->flags & ~IOMMU_TEST_INVALIDATE_FLAG_ALL) {
- rc = -EOPNOTSUPP;
- goto out;
- }
-
- if (cur->cache_id > MOCK_DEV_CACHE_ID_MAX) {
- rc = -EINVAL;
- goto out;
- }
+ if (cmd.flags & ~IOMMU_TEST_INVALIDATE_FLAG_ALL) {
+ rc = -EOPNOTSUPP;
+ goto out;
+ }
- xa_lock(&viommu->vdevs);
- dev = iommufd_viommu_find_dev(viommu,
- (unsigned long)cur->vdev_id);
- if (!dev) {
- xa_unlock(&viommu->vdevs);
- rc = -EINVAL;
- goto out;
- }
- mdev = container_of(dev, struct mock_dev, dev);
+ if (cmd.cache_id > MOCK_DEV_CACHE_ID_MAX) {
+ rc = -EINVAL;
+ goto out;
+ }
- if (cur->flags & IOMMU_TEST_INVALIDATE_FLAG_ALL) {
- /* Invalidate all cache entries and ignore cache_id */
- for (i = 0; i < MOCK_DEV_CACHE_NUM; i++)
- mdev->cache[i] = 0;
- } else {
- mdev->cache[cur->cache_id] = 0;
- }
+ xa_lock(&viommu->vdevs);
+ dev = iommufd_viommu_find_dev(viommu, (unsigned long)cmd.vdev_id);
+ if (!dev) {
xa_unlock(&viommu->vdevs);
-
- cur++;
+ rc = -EINVAL;
+ goto out;
+ }
+ mdev = container_of(dev, struct mock_dev, dev);
+
+ if (cmd.flags & IOMMU_TEST_INVALIDATE_FLAG_ALL) {
+ /* Invalidate all cache entries and ignore cache_id */
+ for (i = 0; i < MOCK_DEV_CACHE_NUM; i++)
+ mdev->cache[i] = 0;
+ } else {
+ mdev->cache[cmd.cache_id] = 0;
}
+ xa_unlock(&viommu->vdevs);
+
+ processed = 1;
out:
- array->entry_num = cur - cmds;
- kfree(cmds);
+ array->entry_num = processed;
return rc;
}
@@ -875,42 +868,46 @@ mock_domain_cache_invalidate_user(struct iommu_domain *domain,
struct mock_iommu_domain_nested *mock_nested = to_mock_nested(domain);
struct iommu_hwpt_invalidate_selftest inv;
u32 processed = 0;
- int i = 0, j;
int rc = 0;
+ int i;
if (array->type != IOMMU_HWPT_INVALIDATE_DATA_SELFTEST) {
rc = -EINVAL;
goto out;
}
- for ( ; i < array->entry_num; i++) {
- rc = iommu_copy_struct_from_user_array(&inv, array,
- IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
- i, iotlb_id);
- if (rc)
- break;
+ /*
+ * The core re-invokes this op for the remaining requests, so handle one
+ * request per call. A zero-length array only probes the type, validated
+ * above.
+ */
+ if (!array->entry_num)
+ goto out;
- if (inv.flags & ~IOMMU_TEST_INVALIDATE_FLAG_ALL) {
- rc = -EOPNOTSUPP;
- break;
- }
+ rc = iommu_copy_struct_from_user_array(
+ &inv, array, IOMMU_HWPT_INVALIDATE_DATA_SELFTEST, 0, iotlb_id);
+ if (rc)
+ goto out;
- if (inv.iotlb_id > MOCK_NESTED_DOMAIN_IOTLB_ID_MAX) {
- rc = -EINVAL;
- break;
- }
+ if (inv.flags & ~IOMMU_TEST_INVALIDATE_FLAG_ALL) {
+ rc = -EOPNOTSUPP;
+ goto out;
+ }
- if (inv.flags & IOMMU_TEST_INVALIDATE_FLAG_ALL) {
- /* Invalidate all mock iotlb entries and ignore iotlb_id */
- for (j = 0; j < MOCK_NESTED_DOMAIN_IOTLB_NUM; j++)
- mock_nested->iotlb[j] = 0;
- } else {
- mock_nested->iotlb[inv.iotlb_id] = 0;
- }
+ if (inv.iotlb_id > MOCK_NESTED_DOMAIN_IOTLB_ID_MAX) {
+ rc = -EINVAL;
+ goto out;
+ }
- processed++;
+ if (inv.flags & IOMMU_TEST_INVALIDATE_FLAG_ALL) {
+ /* Invalidate all mock iotlb entries and ignore iotlb_id */
+ for (i = 0; i < MOCK_NESTED_DOMAIN_IOTLB_NUM; i++)
+ mock_nested->iotlb[i] = 0;
+ } else {
+ mock_nested->iotlb[inv.iotlb_id] = 0;
}
+ processed = 1;
out:
array->entry_num = processed;
return rc;
--
2.43.0
^ permalink raw reply related
* [PATCH v1 4/5] iommu/arm-smmu-v3-iommufd: Convert cache invalidation to the core array loop
From: Nicolin Chen @ 2026-06-29 21:15 UTC (permalink / raw)
To: Will Deacon, Jason Gunthorpe, Kevin Tian, Lu Baolu
Cc: Robin Murphy, joro, David Woodhouse, linux-arm-kernel, iommu,
linux-kernel
In-Reply-To: <cover.1782767398.git.nicolinc@nvidia.com>
arm_vsmmu_cache_invalidate() allocated a buffer for the entire user request
array, walked the array converting each of the commands, and issued those
converted commands to the cmdq in CMDQ_BATCH_ENTRIES sized chunks, carrying
the sub-array bookkeeping all on its own.
The iommufd core now iterates the invalidation array and re-invokes the op
with the not-yet-handled sub-array, so the driver only has to proceed with
a single chunk per call.
Instead of a per-array allocation, use a fixed on-stack batch to copy from
the userspace array. If the copy fails due to nonzero padding (VMM violates
the ABI), fail the entire batch.
Convert the whole batch before issuing any of it: a malformed command is a
userspace bug, so the first illegal command fails the batch as a unit,
issuing nothing and leaving array->entry_num at zero, the same way the copy
above bails on nonzero padding. A batch that converts cleanly is issued in
full, so the op returns either a handled count with no error or zero with
an error.
A zero-length array now returns success once the data type gets validated,
matching the documented probe behavior, rather than the -EINVAL that the
full-array copy helper would previously return.
This also fixes two long-standing bugs:
1) On a conversion failure the old code reported commands that it had
converted but not yet issued, so user space advanced its consumer
index past invalidations that never reached the cmdq.
2) A zero-length array was rejected with -EINVAL, although the uAPI
documents it as a valid request that only probes the data type.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
.../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 73 ++++++++++---------
1 file changed, 39 insertions(+), 34 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
index 393d69783225c..aee58c0be4597 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -412,49 +412,54 @@ int arm_vsmmu_cache_invalidate(struct iommufd_viommu *viommu,
struct iommu_user_data_array *array)
{
struct arm_vsmmu *vsmmu = container_of(viommu, struct arm_vsmmu, core);
+ struct arm_vsmmu_invalidation_cmd cmds[CMDQ_BATCH_ENTRIES - 1];
struct arm_smmu_device *smmu = vsmmu->smmu;
- struct arm_vsmmu_invalidation_cmd *last;
- struct arm_vsmmu_invalidation_cmd *cmds;
- struct arm_vsmmu_invalidation_cmd *cur;
- struct arm_vsmmu_invalidation_cmd *end;
+ struct iommu_user_data_array batch = {
+ .type = array->type,
+ .uptr = array->uptr,
+ .entry_len = array->entry_len,
+ };
int ret;
-
- cmds = kzalloc_objs(*cmds, array->entry_num);
- if (!cmds)
- return -ENOMEM;
- cur = cmds;
- end = cmds + array->entry_num;
+ u32 i;
static_assert(sizeof(*cmds) == 2 * sizeof(u64));
+
+ if (array->type != IOMMU_VIOMMU_INVALIDATE_DATA_ARM_SMMUV3) {
+ array->entry_num = 0;
+ return -EINVAL;
+ }
+
+ /* A zero-length array only probes the type, validated above */
+ if (!array->entry_num)
+ return 0;
+
+ /*
+ * The core re-invokes this op for the remaining requests, so copy one
+ * cmdq batch worth of commands into a fixed on-stack buffer rather than
+ * allocating for the whole array.
+ */
+ batch.entry_num = min_t(u32, array->entry_num, ARRAY_SIZE(cmds));
ret = iommu_copy_struct_from_full_user_array(
- cmds, sizeof(*cmds), array,
+ cmds, sizeof(*cmds), &batch,
IOMMU_VIOMMU_INVALIDATE_DATA_ARM_SMMUV3);
- if (ret)
- goto out;
-
- last = cmds;
- while (cur != end) {
- ret = arm_vsmmu_convert_user_cmd(vsmmu, cur);
- if (ret)
- goto out;
-
- /* FIXME work in blocks of CMDQ_BATCH_ENTRIES and copy each block? */
- cur++;
- if (cur != end && (cur - last) != CMDQ_BATCH_ENTRIES - 1)
- continue;
-
- /* FIXME always uses the main cmdq rather than trying to group by type */
- ret = arm_smmu_cmdq_issue_cmdlist(smmu, &smmu->cmdq, &last->cmd,
- cur - last, true);
+ if (ret) {
+ array->entry_num = 0;
+ return ret;
+ }
+
+ /* Convert the whole batch; a single illegal command fails it all */
+ for (i = 0; i < batch.entry_num; i++) {
+ ret = arm_vsmmu_convert_user_cmd(vsmmu, &cmds[i]);
if (ret) {
- cur--;
- goto out;
+ array->entry_num = 0;
+ return ret;
}
- last = cur;
}
-out:
- array->entry_num = cur - cmds;
- kfree(cmds);
+
+ /* FIXME always uses the main cmdq rather than trying to group by type */
+ ret = arm_smmu_cmdq_issue_cmdlist(smmu, &smmu->cmdq, &cmds->cmd,
+ batch.entry_num, true);
+ array->entry_num = ret ? 0 : batch.entry_num;
return ret;
}
--
2.43.0
^ permalink raw reply related
* [PATCH v1 1/5] iommu/arm-smmu-v3-iommufd: Reject unsupported bits in invalidation commands
From: Nicolin Chen @ 2026-06-29 21:15 UTC (permalink / raw)
To: Will Deacon, Jason Gunthorpe, Kevin Tian, Lu Baolu
Cc: Robin Murphy, joro, David Woodhouse, linux-arm-kernel, iommu,
linux-kernel
In-Reply-To: <cover.1782767398.git.nicolinc@nvidia.com>
The arm_vsmmu_cache_invalidate() op hands a guest's invalidation commands
to the trusted main command queue after enforcing only the VMID or the SID,
and passes the rest of the command through to the queue unchanged.
That lets a guest set bits the host never meant to forward, in two ways. A
bit can take the command out of the guest's own scope: the ATC_INV Global
bit, for one, makes the SMMU ignore the SID and invalidate the ATC of every
device, not just the guest's. A reserved or undefined bit instead makes the
command malformed; per the Arm SMMUv3 specification, in its section 4.1.3
"Command errors", a CERROR_ILL is raised, among other cases, when:
A valid command opcode is used and a Reserved or undefined field is
optionally detected as non-zero, which results in the command being
treated as malformed.
Restrict each opcode to the fields that the driver supports and reject the
command with -EIO if it sets any other bit, before the command reaches the
queue. This keeps a guest scoped to its own devices and stops the host from
forwarding any bit whose meaning it does not control.
Some fields and whole opcodes are legal only on an SMMU that implements the
matching feature, so accept them conditionally. The NUM, SCALE and TG range
fields need FEAT_RANGE_INV. The ATC_INV opcode needs FEAT_ATS. Per the same
specification's section 4.5 "ATS and PRI", CMD_ATC_INV is ILLEGAL when:
SMMU_IDR0.ATS == 0 and this command is issued on a Non-secure or Secure
Command queue.
The SSV and SSID substream fields require a non-zero ssid_bits, so without
substream support setting them is not illegal but CONSTRAINED UNPREDICTABLE,
which a guest should not be able to provoke.
Fixes: d68beb276ba2 ("iommu/arm-smmu-v3: Support IOMMU_HWPT_INVALIDATE using a VIOMMU object")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
.../arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 58 +++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
index 1e9f7d2de3441..393d69783225c 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -315,10 +315,64 @@ struct arm_vsmmu_invalidation_cmd {
static int arm_vsmmu_convert_user_cmd(struct arm_vsmmu *vsmmu,
struct arm_vsmmu_invalidation_cmd *cmd)
{
+ u64 allowed[2] = { CMDQ_0_OP };
+
/* Commands are le64 stored in u64 */
cmd->cmd.data[0] = le64_to_cpu(cmd->ucmd.cmd[0]);
cmd->cmd.data[1] = le64_to_cpu(cmd->ucmd.cmd[1]);
+ /* Collect the fields userspace is allowed to set for each opcode */
+ switch (cmd->cmd.data[0] & CMDQ_0_OP) {
+ case CMDQ_OP_TLBI_NH_VA:
+ allowed[0] |= CMDQ_TLBI_0_ASID;
+ fallthrough;
+ case CMDQ_OP_TLBI_NH_VAA:
+ allowed[0] |= CMDQ_TLBI_0_VMID;
+ allowed[1] |= CMDQ_TLBI_1_LEAF | CMDQ_TLBI_1_TTL |
+ CMDQ_TLBI_1_VA_MASK;
+ /* NUM/SCALE/TG are range fields gated on FEAT_RANGE_INV */
+ if (vsmmu->smmu->features & ARM_SMMU_FEAT_RANGE_INV) {
+ allowed[0] |= CMDQ_TLBI_0_NUM | CMDQ_TLBI_0_SCALE;
+ allowed[1] |= CMDQ_TLBI_1_TG;
+ }
+ break;
+ case CMDQ_OP_TLBI_NH_ASID:
+ allowed[0] |= CMDQ_TLBI_0_ASID;
+ fallthrough;
+ case CMDQ_OP_TLBI_NH_ALL:
+ allowed[0] |= CMDQ_TLBI_0_VMID;
+ break;
+ case CMDQ_OP_ATC_INV:
+ /*
+ * Exclude the Global bit: it makes the SMMU ignore the SID and
+ * invalidate the ATC of every device, not just the guest's.
+ */
+ allowed[0] |= CMDQ_ATC_0_SID;
+ allowed[1] |= CMDQ_ATC_1_SIZE | CMDQ_ATC_1_ADDR_MASK;
+ /* SSV/SSID require substream support */
+ if (vsmmu->smmu->ssid_bits)
+ allowed[0] |= CMDQ_0_SSV | CMDQ_ATC_0_SSID;
+ break;
+ case CMDQ_OP_CFGI_CD:
+ allowed[1] |= CMDQ_CFGI_1_LEAF;
+ /* No SSV for CFGI_CD; SSID requires substream support */
+ if (vsmmu->smmu->ssid_bits)
+ allowed[0] |= CMDQ_CFGI_0_SSID;
+ fallthrough;
+ case CMDQ_OP_CFGI_CD_ALL:
+ allowed[0] |= CMDQ_CFGI_0_SID;
+ break;
+ }
+
+ /*
+ * Reject any other bit, e.g. a RES0 bit or a Secure bit, before the
+ * command reaches the trusted main cmdq, so a guest cannot wedge the
+ * shared queue for every device with a CERROR_ILL.
+ */
+ if ((cmd->cmd.data[0] & ~allowed[0]) ||
+ (cmd->cmd.data[1] & ~allowed[1]))
+ return -EIO;
+
switch (cmd->cmd.data[0] & CMDQ_0_OP) {
case CMDQ_OP_TLBI_NSNH_ALL:
/* Convert to NH_ALL */
@@ -334,6 +388,10 @@ static int arm_vsmmu_convert_user_cmd(struct arm_vsmmu *vsmmu,
cmd->cmd.data[0] |= FIELD_PREP(CMDQ_TLBI_0_VMID, vsmmu->vmid);
break;
case CMDQ_OP_ATC_INV:
+ /* ATC_INV is illegal unless the SMMU implements ATS */
+ if (!(vsmmu->smmu->features & ARM_SMMU_FEAT_ATS))
+ return -EIO;
+ fallthrough;
case CMDQ_OP_CFGI_CD:
case CMDQ_OP_CFGI_CD_ALL: {
u32 sid, vsid = FIELD_GET(CMDQ_CFGI_0_SID, cmd->cmd.data[0]);
--
2.43.0
^ permalink raw reply related
* [PATCH v1 5/5] iommu/vt-d: Convert nested cache invalidation to the core array loop
From: Nicolin Chen @ 2026-06-29 21:15 UTC (permalink / raw)
To: Will Deacon, Jason Gunthorpe, Kevin Tian, Lu Baolu
Cc: Robin Murphy, joro, David Woodhouse, linux-arm-kernel, iommu,
linux-kernel
In-Reply-To: <cover.1782767398.git.nicolinc@nvidia.com>
intel_nested_cache_invalidate_user() used to walk the whole request array
on its own, copying and then flushing one single entry at a time.
The iommufd core now iterates the request array itself and re-invokes the
op with the not-yet-handled sub-array, so handle just a single request per
call out of the front of that sub-array and report one handled entry via
the array->entry_num. An empty array keeps returning a success, used as a
probe of IOMMU_HWPT_INVALIDATE_DATA_VTD_S1 support.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/intel/nested.c | 54 ++++++++++++++++++++----------------
1 file changed, 30 insertions(+), 24 deletions(-)
diff --git a/drivers/iommu/intel/nested.c b/drivers/iommu/intel/nested.c
index 2b979bec56cef..cad5c1573196e 100644
--- a/drivers/iommu/intel/nested.c
+++ b/drivers/iommu/intel/nested.c
@@ -93,7 +93,7 @@ static int intel_nested_cache_invalidate_user(struct iommu_domain *domain,
{
struct dmar_domain *dmar_domain = to_dmar_domain(domain);
struct iommu_hwpt_vtd_s1_invalidate inv_entry;
- u32 index, processed = 0;
+ u32 processed = 0;
int ret = 0;
if (array->type != IOMMU_HWPT_INVALIDATE_DATA_VTD_S1) {
@@ -101,31 +101,37 @@ static int intel_nested_cache_invalidate_user(struct iommu_domain *domain,
goto out;
}
- for (index = 0; index < array->entry_num; index++) {
- ret = iommu_copy_struct_from_user_array(&inv_entry, array,
- IOMMU_HWPT_INVALIDATE_DATA_VTD_S1,
- index, __reserved);
- if (ret)
- break;
-
- if ((inv_entry.flags & ~IOMMU_VTD_INV_FLAGS_LEAF) ||
- inv_entry.__reserved) {
- ret = -EOPNOTSUPP;
- break;
- }
-
- if (!IS_ALIGNED(inv_entry.addr, VTD_PAGE_SIZE) ||
- ((inv_entry.npages == U64_MAX) && inv_entry.addr)) {
- ret = -EINVAL;
- break;
- }
-
- cache_tag_flush_range(dmar_domain, inv_entry.addr,
- inv_entry.addr + nrpages_to_size(inv_entry.npages) - 1,
- inv_entry.flags & IOMMU_VTD_INV_FLAGS_LEAF);
- processed++;
+ /*
+ * The core re-invokes this op for the remaining requests, so handle one
+ * request per call. A zero-length array only probes the type, validated
+ * above.
+ */
+ if (!array->entry_num)
+ goto out;
+
+ ret = iommu_copy_struct_from_user_array(
+ &inv_entry, array, IOMMU_HWPT_INVALIDATE_DATA_VTD_S1, 0,
+ __reserved);
+ if (ret)
+ goto out;
+
+ if ((inv_entry.flags & ~IOMMU_VTD_INV_FLAGS_LEAF) ||
+ inv_entry.__reserved) {
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (!IS_ALIGNED(inv_entry.addr, VTD_PAGE_SIZE) ||
+ (inv_entry.npages == U64_MAX && inv_entry.addr)) {
+ ret = -EINVAL;
+ goto out;
}
+ cache_tag_flush_range(dmar_domain, inv_entry.addr,
+ inv_entry.addr +
+ nrpages_to_size(inv_entry.npages) - 1,
+ inv_entry.flags & IOMMU_VTD_INV_FLAGS_LEAF);
+ processed = 1;
out:
array->entry_num = processed;
return ret;
--
2.43.0
^ permalink raw reply related
* [PATCH v1 2/3] iommufd/viommu: Publish a vDEVICE only after vdevice_init() succeeds
From: Nicolin Chen @ 2026-06-29 21:16 UTC (permalink / raw)
To: Jason Gunthorpe, Kevin Tian
Cc: Will Deacon, Robin Murphy, joro, linux-arm-kernel, iommu,
linux-kernel
In-Reply-To: <cover.1782767110.git.nicolinc@nvidia.com>
iommufd_vdevice_alloc_ioctl() adds the vDEVICE to the viommu->vdevs xarray
with xa_cmpxchg() before the driver's vdevice_init() op runs. That op is
where a driver validates the device and may reject it, but the xarray entry
is already live by then: a concurrent IOMMU_HWPT_INVALIDATE can look it up
with iommufd_viommu_find_dev() and run the driver invalidation path against
a device that vdevice_init() would have refused.
Reserve the index with xa_insert(): it stores a zero entry that reads back
as NULL, and returns -EBUSY on a duplicate virt_id. Run vdevice_init() and
store the vDEVICE pointer only once it succeeds. A failed vdevice_init()
releases the reservation, so lookups observe the vDEVICE only after it is
fully initialized and accepted.
Fixes: ed42eee797ff3 ("iommufd/viommu: Add driver-defined vDEVICE support")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommufd/viommu.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/iommufd/viommu.c b/drivers/iommu/iommufd/viommu.c
index 0c12c7e352a14..5b40e924f0782 100644
--- a/drivers/iommu/iommufd/viommu.c
+++ b/drivers/iommu/iommufd/viommu.c
@@ -143,7 +143,7 @@ void iommufd_vdevice_destroy(struct iommufd_object *obj)
int iommufd_vdevice_alloc_ioctl(struct iommufd_ucmd *ucmd)
{
struct iommu_vdevice_alloc *cmd = ucmd->cmd;
- struct iommufd_vdevice *vdev, *curr;
+ struct iommufd_vdevice *vdev;
size_t vdev_size = sizeof(*vdev);
struct iommufd_viommu *viommu;
struct iommufd_device *idev;
@@ -218,18 +218,21 @@ int iommufd_vdevice_alloc_ioctl(struct iommufd_ucmd *ucmd)
*/
idev->vdev = vdev;
- curr = xa_cmpxchg(&viommu->vdevs, virt_id, NULL, vdev, GFP_KERNEL);
- if (curr) {
- rc = xa_err(curr) ?: -EEXIST;
+ rc = xa_insert(&viommu->vdevs, virt_id, NULL, GFP_KERNEL);
+ if (rc) {
+ if (rc == -EBUSY)
+ rc = -EEXIST;
goto out_abort;
}
if (viommu->ops && viommu->ops->vdevice_init) {
rc = viommu->ops->vdevice_init(vdev);
if (rc)
- goto out_abort;
+ goto out_release;
}
+ xa_store(&viommu->vdevs, virt_id, vdev, GFP_KERNEL);
+
cmd->out_vdevice_id = vdev->obj.id;
rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
if (rc)
@@ -237,6 +240,8 @@ int iommufd_vdevice_alloc_ioctl(struct iommufd_ucmd *ucmd)
iommufd_object_finalize(ucmd->ictx, &vdev->obj);
goto out_unlock_igroup;
+out_release:
+ xa_release(&viommu->vdevs, virt_id);
out_abort:
iommufd_object_abort_and_destroy(ucmd->ictx, &vdev->obj);
out_unlock_igroup:
--
2.43.0
^ permalink raw reply related
* [PATCH v1 0/3] iommufd: Fix vDEVICE allocation lifecycle bugs
From: Nicolin Chen @ 2026-06-29 21:16 UTC (permalink / raw)
To: Jason Gunthorpe, Kevin Tian
Cc: Will Deacon, Robin Murphy, joro, linux-arm-kernel, iommu,
linux-kernel
Sashiko flagged a few bugs in how IOMMU_VDEVICE_ALLOC creates and validates
a vDEVICE on a vIOMMU:
- the core publishes a vDEVICE into the vIOMMU xarray before the driver's
vdevice_init() runs, so a concurrent invalidation can reach one it has
not yet accepted;
- the undersized-vdevice_size guard returns holding the igroup mutex,
deadlocking later vDEVICE operations on that group;
- the Arm SMMUv3 vIOMMU accepts a device without exactly one Stream ID:
an out-of-bounds streams[] read for none, stale ATC/IOTLB for several.
Fix each of them properly.
This is on Github:
https://github.com/nicolinc/iommufd/commits/fix_vdevice_sashiko-v1
Nicolin Chen (3):
iommufd/viommu: Release the igroup lock on the vdevice_size error path
iommufd/viommu: Publish a vDEVICE only after vdevice_init() succeeds
iommu/arm-smmu-v3-iommufd: Require exactly one Stream ID for a vDEVICE
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 15 +++++++++++++++
drivers/iommu/iommufd/viommu.c | 17 +++++++++++------
2 files changed, 26 insertions(+), 6 deletions(-)
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
--
2.43.0
^ permalink raw reply
* [PATCH v1 1/3] iommufd/viommu: Release the igroup lock on the vdevice_size error path
From: Nicolin Chen @ 2026-06-29 21:16 UTC (permalink / raw)
To: Jason Gunthorpe, Kevin Tian
Cc: Will Deacon, Robin Murphy, joro, linux-arm-kernel, iommu,
linux-kernel
In-Reply-To: <cover.1782767110.git.nicolinc@nvidia.com>
iommufd_vdevice_alloc_ioctl() takes idev->igroup->lock, then validates the
driver's vdevice_size against the core structure size with a WARN_ON_ONCE.
On failure that guard jumps to out_put_idev, below out_unlock_igroup, so it
skips the mutex_unlock(), leaving the igroup lock held and deadlocking the
next vDEVICE operation on that group.
Jump to out_unlock_igroup instead.
Fixes: ed42eee797ff3 ("iommufd/viommu: Add driver-defined vDEVICE support")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommufd/viommu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iommu/iommufd/viommu.c b/drivers/iommu/iommufd/viommu.c
index 4081deda9b33d..0c12c7e352a14 100644
--- a/drivers/iommu/iommufd/viommu.c
+++ b/drivers/iommu/iommufd/viommu.c
@@ -189,7 +189,7 @@ int iommufd_vdevice_alloc_ioctl(struct iommufd_ucmd *ucmd)
if (WARN_ON_ONCE(viommu->ops->vdevice_size < vdev_size ||
!viommu->ops->vdevice_init)) {
rc = -EOPNOTSUPP;
- goto out_put_idev;
+ goto out_unlock_igroup;
}
vdev_size = viommu->ops->vdevice_size;
}
--
2.43.0
^ permalink raw reply related
* [PATCH v1 3/3] iommu/arm-smmu-v3-iommufd: Require exactly one Stream ID for a vDEVICE
From: Nicolin Chen @ 2026-06-29 21:16 UTC (permalink / raw)
To: Jason Gunthorpe, Kevin Tian
Cc: Will Deacon, Robin Murphy, joro, linux-arm-kernel, iommu,
linux-kernel
In-Reply-To: <cover.1782767110.git.nicolinc@nvidia.com>
arm_vsmmu_vsid_to_sid() maps a guest's vSID to a single physical Stream ID
taken from master->streams[0], assuming a device has exactly one stream. A
device with several streams gets only its first one mapped, so a guest vSID
invalidation cannot reach the others' ATC and IOTLB entries; a device with
none makes master->streams a ZERO_SIZE_PTR, read out of bounds.
Add an arm_vsmmu_vdevice_init() op to reject the vDEVICE with -EINVAL when
master->num_streams is not one, rather than mapping it silently.
Fixes: d68beb276ba26 ("iommu/arm-smmu-v3: Support IOMMU_HWPT_INVALIDATE using a VIOMMU object")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
index 1e9f7d2de3441..2ba08df75af8b 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c
@@ -297,6 +297,20 @@ static int arm_vsmmu_vsid_to_sid(struct arm_vsmmu *vsmmu, u32 vsid, u32 *sid)
return ret;
}
+static int arm_vsmmu_vdevice_init(struct iommufd_vdevice *vdev)
+{
+ struct device *dev = iommufd_vdevice_to_device(vdev);
+ struct arm_smmu_master *master = dev_iommu_priv_get(dev);
+
+ /*
+ * arm_vsmmu_vsid_to_sid() maps a vSID to master->streams[0] alone, so
+ * more streams would leave the rest stale and none reads out of bounds.
+ */
+ if (master->num_streams != 1)
+ return -EINVAL;
+ return 0;
+}
+
/* This is basically iommu_viommu_arm_smmuv3_invalidate in u64 for conversion */
struct arm_vsmmu_invalidation_cmd {
union {
@@ -403,6 +417,7 @@ int arm_vsmmu_cache_invalidate(struct iommufd_viommu *viommu,
static const struct iommufd_viommu_ops arm_vsmmu_ops = {
.alloc_domain_nested = arm_vsmmu_alloc_domain_nested,
.cache_invalidate = arm_vsmmu_cache_invalidate,
+ .vdevice_init = arm_vsmmu_vdevice_init,
};
size_t arm_smmu_get_viommu_size(struct device *dev,
--
2.43.0
^ permalink raw reply related
* Re: [PATCH] arm64: dts: imx8mp-ab2: Enable MU2 for DSP communication
From: Frank.Li @ 2026-06-29 21:18 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, s.hauer, kernel, festevam, devicetree,
imx, linux-arm-kernel, linux-kernel, shengjiu.wang
Cc: Frank Li
In-Reply-To: <20260625054709.301209-1-shengjiu.wang@oss.nxp.com>
From: Frank Li <Frank.Li@nxp.com>
On Thu, 25 Jun 2026 13:47:09 +0800, shengjiu.wang@oss.nxp.com wrote:
> Enable the MU2 (Message Unit 2) node on the i.MX8MP Audio Board v2.
> MU2 is required for inter-processor communication between the
> application CPU and the HiFi4 DSP, allowing DSP firmware to exchange
> control and status messages with the Linux host.
>
> Without this change, the DSP driver cannot establish the message
> channel and DSP audio processing is non-functional.
>
> [...]
Applied, thanks!
[1/1] arm64: dts: imx8mp-ab2: Enable MU2 for DSP communication
commit: b1b6c1c4d3c63d8097c933009bdb618d1be18305
Best regards,
--
Frank Li <Frank.Li@nxp.com>
^ permalink raw reply
* Re: [PATCH v11 2/3] dt-bindings: clock: imx95-blk-ctl: Define formatter child node schema
From: Frank Li @ 2026-06-29 21:23 UTC (permalink / raw)
To: guoniu.zhou
Cc: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Laurent Pinchart, Frank Li, Abel Vesa, Peng Fan,
Michael Turquette, Stephen Boyd, imx, linux-media, devicetree,
linux-arm-kernel, linux-kernel, linux-clk, Guoniu Zhou
In-Reply-To: <20260623-csi_formatter-v11-2-a792fe9c1502@oss.nxp.com>
On Tue, Jun 23, 2026 at 11:56:32AM +0800, guoniu.zhou@oss.nxp.com wrote:
> From: Guoniu Zhou <guoniu.zhou@nxp.com>
>
> The Camera CSR contains control registers for multiple CSI formatter IPs
> at different register offsets. Each formatter is an independent hardware
> block with its own clock input and media pipeline connection.
>
> Define schema to allow formatter child nodes under nxp,imx95-camera-csr,
> with 'reg' property specifying the formatter's register offset within the
> CSR address space.
>
> Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
> ---
Abel Vesa:
There are week dependence with media driver/binding, Can I pick
this with media driver together? If this go through clock tree,
"fsl,imx95-csi-formatter" cause dt_binding_check failure.
Frank
> Changes in v11:
> - Move properties to top-level and use if:then:else (Krzysztof/Frank)
>
> Changes in v10:
> - Use single quotes for regex pattern to be consistent (Krzysztof Kozlowski)
> - Add formatter subnode binding and camera-csr syscon example
> - Update commit title and message
>
> Changes in v9:
> - New patch to address the issue of formatter acting as a child node of syscon
> ---
> .../bindings/clock/nxp,imx95-blk-ctl.yaml | 71 ++++++++++++++++++++++
> 1 file changed, 71 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> index 27403b4c52d6..fbbf1b3f1790 100644
> --- a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> +++ b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
> @@ -39,6 +39,18 @@ properties:
> ID in its "clocks" phandle cell. See
> include/dt-bindings/clock/nxp,imx95-clock.h
>
> + '#address-cells':
> + const: 1
> +
> + '#size-cells':
> + const: 1
> +
> +patternProperties:
> + '^formatter@[0-9a-f]+$':
> + type: object
> + $ref: /schemas/media/fsl,imx95-csi-formatter.yaml#
> + unevaluatedProperties: false
> +
> required:
> - compatible
> - reg
> @@ -46,6 +58,23 @@ required:
> - power-domains
> - clocks
>
> +allOf:
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: nxp,imx95-camera-csr
> + then:
> + required:
> + - '#address-cells'
> + - '#size-cells'
> + else:
> + properties:
> + '#address-cells': false
> + '#size-cells': false
> + patternProperties:
> + '^formatter@[0-9a-f]+$': false
> +
> additionalProperties: false
>
> examples:
> @@ -57,4 +86,46 @@ examples:
> clocks = <&scmi_clk 114>;
> power-domains = <&scmi_devpd 21>;
> };
> +
> + - |
> + #include <dt-bindings/clock/nxp,imx95-clock.h>
> +
> + syscon@4ac10000 {
> + compatible = "nxp,imx95-camera-csr", "syscon";
> + reg = <0x4ac10000 0x10000>;
> + #address-cells = <1>;
> + #size-cells = <1>;
> + #clock-cells = <1>;
> + clocks = <&scmi_clk 62>;
> + power-domains = <&scmi_devpd 3>;
> +
> + formatter@20 {
> + compatible = "fsl,imx95-csi-formatter";
> + reg = <0x20 0x100>;
> + clocks = <&cameramix_csr IMX95_CLK_CAMBLK_CSI2_FOR0>;
> + power-domains = <&scmi_devpd 3>;
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + reg = <0>;
> +
> + endpoint {
> + remote-endpoint = <&mipi_csi_0_out>;
> + };
> +
> + };
> +
> + port@1 {
> + reg = <1>;
> +
> + endpoint {
> + remote-endpoint = <&isi_in_2>;
> + };
> + };
> + };
> + };
> + };
> ...
>
> --
> 2.34.1
>
>
^ permalink raw reply
* Re: [PATCH] ARM: imx: Drop obsolte stuff from common.h
From: Uwe Kleine-König (The Capable Hub) @ 2026-06-29 21:39 UTC (permalink / raw)
To: Frank.Li
Cc: Sascha Hauer, Frank Li, Pengutronix Kernel Team, Fabio Estevam,
linux-arm-kernel, imx
In-Reply-To: <178276752372.2498119.8965955961315145259.b4-ty@b4>
[-- Attachment #1: Type: text/plain, Size: 897 bytes --]
Hello Frank,
On Mon, Jun 29, 2026 at 05:12:07PM -0400, Frank.Li@oss.nxp.com wrote:
> From: Frank Li <Frank.Li@nxp.com>
>
> On Tue, 23 Jun 2026 12:45:57 +0200, Uwe Kleine-König (The Capable Hub) wrote:
> > i.MX21 (and thus imx21_init_early()) is gone since v5.10-rc1 (commit
> > 4b563a066611 ("ARM: imx: Remove imx21 support")).
> >
> > The init_irq() functions are gone since v5.12-rc5 (commit e2c1b0ff38c9
> > ("ARM: imx: avic: Convert to using IRQCHIP_DECLARE")).
> >
> > And mxc_device_init() was removed for v5.10-rc1 (in commit 8485adf17a15
> > ("ARM: imx: Remove imx device directory")).
> >
> > [...]
>
> Applied, thanks!
>
> [1/1] ARM: imx: Drop obsolte stuff from common.h
^
There is an 'e' missing ---' (i.e. s/obsolte/obsolete/).
If you want to fix-up that's great, if not, I can live with the shame
:-)
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH] ARM: imx: Drop obsolte stuff from common.h
From: Frank Li @ 2026-06-29 22:23 UTC (permalink / raw)
To: Uwe Kleine-König (The Capable Hub)
Cc: Sascha Hauer, Frank Li, Pengutronix Kernel Team, Fabio Estevam,
linux-arm-kernel, imx
In-Reply-To: <akLlvHMcVpXDsS9l@monoceros>
On Mon, Jun 29, 2026 at 11:39:39PM +0200, Uwe Kleine-König (The Capable Hub) wrote:
> Hello Frank,
>
> On Mon, Jun 29, 2026 at 05:12:07PM -0400, Frank.Li@oss.nxp.com wrote:
> > From: Frank Li <Frank.Li@nxp.com>
> >
> > On Tue, 23 Jun 2026 12:45:57 +0200, Uwe Kleine-König (The Capable Hub) wrote:
> > > i.MX21 (and thus imx21_init_early()) is gone since v5.10-rc1 (commit
> > > 4b563a066611 ("ARM: imx: Remove imx21 support")).
> > >
> > > The init_irq() functions are gone since v5.12-rc5 (commit e2c1b0ff38c9
> > > ("ARM: imx: avic: Convert to using IRQCHIP_DECLARE")).
> > >
> > > And mxc_device_init() was removed for v5.10-rc1 (in commit 8485adf17a15
> > > ("ARM: imx: Remove imx device directory")).
> > >
> > > [...]
> >
> > Applied, thanks!
> >
> > [1/1] ARM: imx: Drop obsolte stuff from common.h
> ^
> There is an 'e' missing ---' (i.e. s/obsolte/obsolete/).
>
> If you want to fix-up that's great, if not, I can live with the shame
> :-)
Fixed it.
Frank
>
> Best regards
> Uwe
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox