* Re: [PATCH v4 7/9] regulator: Add MediaTek MT6392 regulator
From: kernel test robot @ 2026-04-01 1:21 UTC (permalink / raw)
To: Luca Leonardo Scorcia, linux-mediatek
Cc: llvm, oe-kbuild-all, Fabien Parent, Val Packett,
Luca Leonardo Scorcia, AngeloGioacchino Del Regno,
Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Sen Chu, Sean Wang, Macpaul Lin, Lee Jones, Matthias Brugger,
Linus Walleij, Liam Girdwood, Mark Brown, Julien Massot,
Louis-Alexis Eyraud, Gary Bisson, Chen Zhong, linux-input,
devicetree, linux-kernel, linux-pm, linux-arm-kernel, linux-gpio
In-Reply-To: <20260330083429.359819-8-l.scorcia@gmail.com>
Hi Luca,
kernel test robot noticed the following build warnings:
[auto build test WARNING on lee-mfd/for-mfd-next]
[also build test WARNING on broonie-regulator/for-next linusw-pinctrl/devel linusw-pinctrl/for-next lee-mfd/for-mfd-fixes linus/master v7.0-rc6 next-20260330]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Luca-Leonardo-Scorcia/dt-bindings-mfd-mt6397-Add-MT6392-PMIC/20260331-081127
base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
patch link: https://lore.kernel.org/r/20260330083429.359819-8-l.scorcia%40gmail.com
patch subject: [PATCH v4 7/9] regulator: Add MediaTek MT6392 regulator
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20260401/202604010924.UuETwSKZ-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260401/202604010924.UuETwSKZ-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604010924.UuETwSKZ-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/regulator/mt6392-regulator.c:181:18: warning: unused variable 'ldo_volt_table1b' [-Wunused-const-variable]
181 | static const u32 ldo_volt_table1b[] = {
| ^~~~~~~~~~~~~~~~
1 warning generated.
vim +/ldo_volt_table1b +181 drivers/regulator/mt6392-regulator.c
180
> 181 static const u32 ldo_volt_table1b[] = {
182 1500000, 1800000, 2500000, 2800000,
183 };
184
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* RE: [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector
From: Peng Fan @ 2026-04-01 1:31 UTC (permalink / raw)
To: Peng Fan (OSS), Bjorn Andersson, Mathieu Poirier, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Daniel Baluta
Cc: linux-remoteproc@vger.kernel.org, devicetree@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20260327-imx943-rproc-v2-2-a547a3588730@nxp.com>
Hi Mathieu,
> Subject: [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM
> CPU/LMM reset vector
I had an follow-up patch to update reset-vector-mask for i.MX95-CM7
to make it could boot from non-TCM area, not included in this pachset
to avoid unnecessary churn for i.MX94 support, but I realize that
that patch should be squashed into this patch 2/3 to avoid breaking
i.MX95 M7 TCM booting.
Although in my test, cm7 luckily boots up without crash[1], but in theory,
below change should be included in patch 2/3. I will include below change
in v3 after we clear the reset-vector-mask question.
Daniel, please see whether this is ok for you, since you reviewed this
patch.
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 525a92e03e8ab..930dd9eca6fb5 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -1541,6 +1541,7 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx95_m7 = {
/* Must align with System Manager Firmware */
.cpuid = 1, /* Use 1 as cpu id for M7 core */
.lmid = 1, /* Use 1 as Logical Machine ID where M7 resides */
+ .reset_vector_mask = GENMASK_U32(31, 16),
};
static const struct of_device_id imx_rproc_of_match[] = {
[1]
[ 135.738523] remoteproc remoteproc0: powering up imx-rproc
[ 135.748464] remoteproc remoteproc0: Booting fw image imx95-19x19-evk_m7_TCM_rpmsg_lite_str_echo_rtos.elf, size 98996
[ 135.759229] imx-rproc imx95-cm7: lmm(1) powered on by Linux
[ 135.764900] ============== entry 0x91d
[ 135.772597] xxxxxxxxxxxx bootaddr 0x91d
[ 135.775818] rproc-virtio rproc-virtio.2.auto: assigned reserved memory node vdevbuffer@88020000
[ 135.780278] /soc/bus@42000000/i2c@426d0000/tcpc@50/connector: Fixed dependency cycle(s) with /soc/usb@4c010010/usb@4c100000
[ 135.795970] /soc/usb@4c010010/usb@4c100000: Fixed dependency cycle(s) with /soc/bus@42000000/i2c@426d0000/tcpc@50/connector
[ 135.807727] virtio_rpmsg_bus virtio0: rpmsg host is online
[ 135.811546] virtio_rpmsg_bus virtio0: creating channel rpmsg-i2c-channel addr 0x1
Thanks,
Peng.
>
> From: Peng Fan <peng.fan@nxp.com>
>
> Cortex-M[7,33] processors use a fixed reset vector table format:
>
> 0x00 Initial SP value
> 0x04 Reset vector
> 0x08 NMI
> 0x0C ...
> ...
> IRQ[n]
>
> In ELF images, the corresponding layout is:
>
> reset_vectors: --> hardware reset address
> .word __stack_end__
> .word Reset_Handler
> .word NMI_Handler
> .word HardFault_Handler
> ...
> .word UART_IRQHandler
> .word SPI_IRQHandler
> ...
>
> Reset_Handler: --> ELF entry point address
> ...
>
> The hardware fetches the first two words from reset_vectors and
> populates SP with __stack_end__ and PC with Reset_Handler.
> Execution proceeds from Reset_Handler.
>
> However, the ELF entry point does not always match the hardware
> reset address. For example, on i.MX94 CM33S:
>
> ELF entry point: 0x0ffc211d
> hardware reset base: 0x0ffc0000 (default reset value, sw
> programmable)
>
> To derive the correct hardware reset address, the unused lower bits
> must be masked off. The boot code should apply a SoC-specific mask
> before programming the reset address registers, e.g.:
>
> reset_address = entry & reset_vector_mask
>
> Current driver always programs the reset vector as 0. But i.MX94
> CM33S's default reset base is 0x0ffc0000, so the correct reset vector
> must be passed to the SM API; otherwise the M33 Sync core cannot
> boot successfully.
>
> rproc_elf_get_boot_addr() returns the ELF entry point, which is not the
> hardware reset vector address. To derive the proper reset vector, this
> patch introduces imx_rproc_get_boot_addr(), which masks the ELF
> entry point using the SoC‑specific 'reset_vector_mask'. The resulting
> reset vector address is then passed to the SM CPU/LMM reset vector
> API calls.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
> drivers/remoteproc/imx_rproc.c | 17 ++++++++++++++---
> drivers/remoteproc/imx_rproc.h | 2 ++
> 2 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/remoteproc/imx_rproc.c
> b/drivers/remoteproc/imx_rproc.c index
> 0dd80e688b0ea3df4c66e5726884dc86c8a5a881..d8ead42640881bd5
> 23d605fa7002935ef6e98077 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -345,7 +345,7 @@ static int imx_rproc_sm_cpu_start(struct rproc
> *rproc)
> const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> int ret;
>
> - ret = scmi_imx_cpu_reset_vector_set(dcfg->cpuid, 0, true, false,
> false);
> + ret = scmi_imx_cpu_reset_vector_set(dcfg->cpuid, rproc-
> >bootaddr,
> +true, false, false);
> if (ret) {
> dev_err(priv->dev, "Failed to set reset vector
> cpuid(%u): %d\n", dcfg->cpuid, ret);
> return ret;
> @@ -365,7 +365,7 @@ static int imx_rproc_sm_lmm_start(struct
> rproc *rproc)
> * If the remoteproc core can't start the M7, it will already be
> * handled in imx_rproc_sm_lmm_prepare().
> */
> - ret = scmi_imx_lmm_reset_vector_set(dcfg->lmid, dcfg->cpuid,
> 0, 0);
> + ret = scmi_imx_lmm_reset_vector_set(dcfg->lmid, dcfg->cpuid,
> 0,
> +rproc->bootaddr);
> if (ret) {
> dev_err(dev, "Failed to set reset vector lmid(%u),
> cpuid(%u): %d\n",
> dcfg->lmid, dcfg->cpuid, ret);
> @@ -739,6 +739,17 @@ imx_rproc_elf_find_loaded_rsc_table(struct
> rproc *rproc, const struct firmware *
> return rproc_elf_find_loaded_rsc_table(rproc, fw); }
>
> +static u64 imx_rproc_get_boot_addr(struct rproc *rproc, const struct
> +firmware *fw) {
> + struct imx_rproc *priv = rproc->priv;
> + u32 reset_vector_mask = GENMASK_U32(31, 0);
> +
> + if (priv->dcfg->reset_vector_mask)
> + reset_vector_mask = priv->dcfg->reset_vector_mask;
> +
> + return rproc_elf_get_boot_addr(rproc, fw) &
> reset_vector_mask; }
> +
> static const struct rproc_ops imx_rproc_ops = {
> .prepare = imx_rproc_prepare,
> .attach = imx_rproc_attach,
> @@ -752,7 +763,7 @@ static const struct rproc_ops imx_rproc_ops = {
> .find_loaded_rsc_table = imx_rproc_elf_find_loaded_rsc_table,
> .get_loaded_rsc_table = imx_rproc_get_loaded_rsc_table,
> .sanity_check = rproc_elf_sanity_check,
> - .get_boot_addr = rproc_elf_get_boot_addr,
> + .get_boot_addr = imx_rproc_get_boot_addr,
> };
>
> static int imx_rproc_addr_init(struct imx_rproc *priv, diff --git
> a/drivers/remoteproc/imx_rproc.h b/drivers/remoteproc/imx_rproc.h
> index
> d37e6f90548cec727b4aeb874680b42af85bdbb4..0d7d48352a1091ad
> 24e8e083172ce6da6d26ae10 100644
> --- a/drivers/remoteproc/imx_rproc.h
> +++ b/drivers/remoteproc/imx_rproc.h
> @@ -41,6 +41,8 @@ struct imx_rproc_dcfg {
> /* For System Manager(SM) based SoCs */
> u32 cpuid; /* ID of the remote
> core */
> u32 lmid; /* ID of the Logcial
> Machine */
> + /* reset_vector = elf_entry_addr & reset_vector_mask */
> + u32 reset_vector_mask;
> };
>
> #endif /* _IMX_RPROC_H */
>
> --
> 2.37.1
^ permalink raw reply related
* [PATCH 1/2] Revert "arm64: dts: imx8mm-kontron: Add support for reading SD_VSEL signal"
From: Peng Fan (OSS) @ 2026-04-01 2:05 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Frieder Schrempf
Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260401-imx8m-ldo5-v1-0-1b1c1381babd@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
This reverts commit 8472751c4d96b558d60d0f6aede6b24b64bcb3c9.
The board uses SDHC VSELECT to automatically switch between 1.8v and
3.3v. It does not use GPIO to control the PMIC SD_VSEL signal.
The original commit intends to read back SD_VSEL value from GPIO,
but it is wrong. When MUX is configured as SDHC VSELECT, it is
impossible to read back the value from GPIO controller. Setting SION
could only enable the input path for the mux function. It could not
redirect the input to GPIO.
And value "0x40000d0" is wrong, SION is BIT30, not BIT26.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts | 10 +++-------
arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi | 7 +++----
2 files changed, 6 insertions(+), 11 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
index e756fe5db56b6a19c309fcbb94475629e5f2b2a0..dd59af0ebaae55ede743d4187b1165041d655cf2 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
@@ -254,10 +254,6 @@ &pwm2 {
status = "okay";
};
-®_nvcc_sd {
- sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
-};
-
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
@@ -466,7 +462,7 @@ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0
MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0
MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0
MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19
- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x40000d0
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0
>;
};
@@ -479,7 +475,7 @@ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4
MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4
MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4
MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19
- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x40000d0
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0
>;
};
@@ -492,7 +488,7 @@ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6
MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6
MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6
MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19
- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x40000d0
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0
>;
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
index 96987910609f1b0083f5ae0c957f0baf10bfa826..4fb13d8ecfd45a8587e169b7d0a08e811745b5a9 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
@@ -342,7 +342,6 @@ reg_nvcc_sd: LDO5 {
regulator-name = "NVCC_SD (LDO5)";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
- sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
};
};
};
@@ -795,7 +794,7 @@ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0 /* SDIO_A_D1 */
MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0 /* SDIO_A_D2 */
MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0 /* SDIO_A_D3 */
MX8MM_IOMUXC_SD2_WP_USDHC2_WP 0x400000d6 /* SDIO_A_WP */
- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x40000090
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x90
>;
};
@@ -808,7 +807,7 @@ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4 /* SDIO_A_D1 */
MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4 /* SDIO_A_D2 */
MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4 /* SDIO_A_D3 */
MX8MM_IOMUXC_SD2_WP_USDHC2_WP 0x400000d6 /* SDIO_A_WP */
- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x40000090
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x90
>;
};
@@ -821,7 +820,7 @@ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6 /* SDIO_A_D1 */
MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6 /* SDIO_A_D2 */
MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6 /* SDIO_A_D3 */
MX8MM_IOMUXC_SD2_WP_USDHC2_WP 0x400000d6 /* SDIO_A_WP */
- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x40000090
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x90
>;
};
--
2.37.1
^ permalink raw reply related
* [PATCH 2/2] Revert "arm64: dts: imx8mp-kontron: Add support for reading SD_VSEL signal"
From: Peng Fan (OSS) @ 2026-04-01 2:05 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Frieder Schrempf
Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260401-imx8m-ldo5-v1-0-1b1c1381babd@nxp.com>
From: Peng Fan <peng.fan@nxp.com>
This reverts commit 39e4189d9d63a0b6fc15458ce0136e99ecdfb1b8.
The board uses SDHC VSELECT to automatically switch between 1.8v and
3.3v. It does not use GPIO to control the PMIC SD_VSEL signal.
The original commit intends to read back SD_VSEL value from GPIO,
but it is wrong. When MUX is configured as SDHC VSELECT, it is
impossible to read back the value from GPIO controller. Setting SION
could only enable the input path for the mux function. It could not
redirect the input to GPIO.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
arch/arm64/boot/dts/freescale/imx8mp-kontron-osm-s.dtsi | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-kontron-osm-s.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-kontron-osm-s.dtsi
index bc1a261bb000ed0e8071d214111c12689bc394d0..ea69c639b30b8f7e05bb103074c6481d88560c53 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-kontron-osm-s.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-kontron-osm-s.dtsi
@@ -311,7 +311,6 @@ reg_nvcc_sd: LDO5 {
regulator-name = "NVCC_SD (LDO5)";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
- sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
};
};
};
@@ -815,7 +814,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d0 /* SDIO_A_D0 */
MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d0 /* SDIO_A_D1 */
MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d0 /* SDIO_A_D2 */
MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d0 /* SDIO_A_D3 */
- MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0x400001d0
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0x1d0
>;
};
@@ -827,7 +826,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d4 /* SDIO_A_D0 */
MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d4 /* SDIO_A_D1 */
MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d4 /* SDIO_A_D2 */
MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d4 /* SDIO_A_D3 */
- MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0x400001d0
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0x1d0
>;
};
@@ -839,7 +838,7 @@ MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0 0x1d6 /* SDIO_A_D0 */
MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d6 /* SDIO_A_D1 */
MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d6 /* SDIO_A_D2 */
MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d6 /* SDIO_A_D3 */
- MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0x400001d0
+ MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0x1d0
>;
};
--
2.37.1
^ permalink raw reply related
* Re: [RFC PATCH 1/7] media: v4l2-ctrls: Add V4L2_CID_MEMORY_USAGE control
From: Ming Qian(OSS) @ 2026-04-01 2:07 UTC (permalink / raw)
To: Frank Li
Cc: linux-media, mchehab, hverkuil-cisco, nicolas, sebastian.fricke,
shawnguo, s.hauer, kernel, festevam, linux-imx, xiahong.bao,
eagle.zhou, imx, linux-kernel, linux-arm-kernel
In-Reply-To: <acvbOo17tU-s20BS@lizhi-Precision-Tower-5810>
Hi Frank,
On 3/31/2026 10:33 PM, Frank Li wrote:
> On Tue, Mar 31, 2026 at 03:23:11PM +0800, ming.qian@oss.nxp.com wrote:
>> From: Ming Qian <ming.qian@oss.nxp.com>
>>
>> Add a new read-only control V4L2_CID_MEMORY_USAGE that allows
>> applications to query the total amount of memory currently used
>> by a device instance.
>>
>> This control reports the memory consumption in bytes, including
>> internal buffers, intermediate processing data, and other
>> driver-managed allocations. Applications can use this information
>> for debugging, resource monitoring, or making informed decisions
>> about buffer allocation strategies.
>>
>> Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
>> ---
>
> Not sure why not export these information by debugfs, or any benefit vs
> debugfs?
>
> Generanlly document should be first patch, then driver change.
>
> Frank
Thanks for the comments.
The key reason for adding a V4L2 ctrl is that the original requirement
(from Android) is to query the memory usage per VPU instance in a simple
and stable way. A ctrl naturally fits this use case, as userspace
already has the instance fd and does not need to locate or map any
external paths. In contrast, relying only on debugfs would require
userspace to figure out the relationship between an instance and a
debugfs node, which is neither stable nor friendly for production
systems where debugfs may not even be available.
Debugfs is added only to expose the full hierarchical memory‑tracking
structure (device → instance → queue) for debugging and analysis. It
complements the ctrl, but cannot replace it for the original functional
requirement.
I will reorder the documentation patch to come first in the next
revision.
Regards,
Ming
>
>> drivers/media/v4l2-core/v4l2-ctrls-defs.c | 8 ++++++++
>> include/uapi/linux/v4l2-controls.h | 4 +++-
>> 2 files changed, 11 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
>> index 551426c4cd01..053db78ff661 100644
>> --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
>> +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
>> @@ -831,6 +831,7 @@ const char *v4l2_ctrl_get_name(u32 id)
>> case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component";
>> case V4L2_CID_COLORFX_CBCR: return "Color Effects, CbCr";
>> case V4L2_CID_COLORFX_RGB: return "Color Effects, RGB";
>> + case V4L2_CID_MEMORY_USAGE: return "Memory Usage";
>>
>> /*
>> * Codec controls
>> @@ -1476,6 +1477,13 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
>> *min = 0;
>> *max = 0xffff;
>> break;
>> + case V4L2_CID_MEMORY_USAGE:
>> + *type = V4L2_CTRL_TYPE_INTEGER64;
>> + *flags |= V4L2_CTRL_FLAG_READ_ONLY;
>> + *min = 0;
>> + *max = S64_MAX;
>> + *step = 1;
>> + break;
>> case V4L2_CID_FLASH_FAULT:
>> case V4L2_CID_JPEG_ACTIVE_MARKER:
>> case V4L2_CID_3A_LOCK:
>> diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
>> index 68dd0c4e47b2..02c6f960d38e 100644
>> --- a/include/uapi/linux/v4l2-controls.h
>> +++ b/include/uapi/linux/v4l2-controls.h
>> @@ -110,8 +110,10 @@ enum v4l2_colorfx {
>> #define V4L2_CID_COLORFX_CBCR (V4L2_CID_BASE+42)
>> #define V4L2_CID_COLORFX_RGB (V4L2_CID_BASE+43)
>>
>> +#define V4L2_CID_MEMORY_USAGE (V4L2_CID_BASE+44)
>> +
>> /* last CID + 1 */
>> -#define V4L2_CID_LASTP1 (V4L2_CID_BASE+44)
>> +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+45)
>>
>> /* USER-class private control IDs */
>>
>> --
>> 2.53.0
>>
^ permalink raw reply
* Re: [PATCH 1/1] net: ipv6: flowlabel: defer exclusive option free until RCU teardown
From: patchwork-bot+netdevbpf @ 2026-04-01 2:10 UTC (permalink / raw)
To: Yang Yang
Cc: security, davem, dsahern, edumazet, kuba, pabeni, horms, afaerber,
mani, yoshfuji, yifanwucs, tomapufckgml, yuantan098, bird,
enjou1224z, zcliangcn, netdev, linux-arm-kernel, linux-actions,
linux-kernel
In-Reply-To: <07351f0ec47bcee289576f39f9354f4a64add6e4.1774855883.git.zcliangcn@gmail.com>
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 30 Mar 2026 16:46:24 +0800 you wrote:
> From: Zhengchuan Liang <zcliangcn@gmail.com>
>
> `ip6fl_seq_show()` walks the global flowlabel hash under the seq-file
> RCU read-side lock and prints `fl->opt->opt_nflen` when an option block
> is present.
>
> Exclusive flowlabels currently free `fl->opt` as soon as `fl->users`
> drops to zero in `fl_release()`. However, the surrounding
> `struct ip6_flowlabel` remains visible in the global hash table until
> later garbage collection removes it and `fl_free_rcu()` finally tears it
> down.
>
> [...]
Here is the summary with links:
- [1/1] net: ipv6: flowlabel: defer exclusive option free until RCU teardown
https://git.kernel.org/netdev/net/c/9ca562bb8e66
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* [PATCH 0/2] arm64: dts: imx8m-kontron: Revert reading SD_VSEL signal
From: Peng Fan (OSS) @ 2026-04-01 2:05 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Frieder Schrempf
Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
When MUX is configured as SDHC VSELECT, enabling SION is not able
to read back the SD_VSEL value. SION is used for force input path,
not to redirect the PAD value to GPIO(the other mux).
This has been confirmed by reading i.MX8MP RTL. we have not check
i.MX8MM RTL, but it should be same.
Not sure whether need to add Fixes commit for the patches, just revert
patches.
For the U-Boot support, either drop vqmmc-supply or switch to use gpio
control to replace vselect control.
And below patch should also be revisited.
commit 3ce6f4f943ddd9edc03e450a2a0d89cb025b165b
Author: Frieder Schrempf <frieder.schrempf@kontron.de>
Date: Wed Dec 18 16:27:27 2024 +0100
regulator: pca9450: Fix control register for LDO5
To supporting read back signal, need the MUX set as GPIO and support
in/out, not set mux as VSELECT.
TBH: I have not test setting MUX as GPIO, anyway we need to fix DT.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Peng Fan (2):
Revert "arm64: dts: imx8mm-kontron: Add support for reading SD_VSEL signal"
Revert "arm64: dts: imx8mp-kontron: Add support for reading SD_VSEL signal"
arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts | 10 +++-------
arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi | 7 +++----
arch/arm64/boot/dts/freescale/imx8mp-kontron-osm-s.dtsi | 7 +++----
3 files changed, 9 insertions(+), 15 deletions(-)
---
base-commit: 3b058d1aeeeff27a7289529c4944291613b364e9
change-id: 20260329-imx8m-ldo5-90e369066213
Best regards,
--
Peng Fan <peng.fan@nxp.com>
^ permalink raw reply
* Re: [PATCH v2 12/30] KVM: arm64: Hoist MTE validation check out of MMU lock path
From: Anshuman Khandual @ 2026-04-01 2:18 UTC (permalink / raw)
To: Marc Zyngier
Cc: kvmarm, linux-arm-kernel, kvm, Joey Gouly, Suzuki K Poulose,
Oliver Upton, Zenghui Yu, Fuad Tabba, Will Deacon, Quentin Perret
In-Reply-To: <865x6b4zwh.wl-maz@kernel.org>
On 31/03/26 11:58 PM, Marc Zyngier wrote:
> On Tue, 31 Mar 2026 07:57:48 +0100,
> Anshuman Khandual <anshuman.khandual@arm.com> wrote:
>>
>> On 27/03/26 5:06 PM, Marc Zyngier wrote:
>>> From: Fuad Tabba <tabba@google.com>
>>>
>>> Simplify the non-cacheable attributes assignment by using a ternary
>>> operator. Additionally, hoist the MTE validation check (mte_allowed) out
>>> of kvm_s2_fault_map() and into kvm_s2_fault_compute_prot(). This allows
>>> us to fail faster and avoid acquiring the KVM MMU lock unnecessarily
>>> when the VMM introduces a disallowed VMA for an MTE-enabled guest.
>>>
>>> Signed-off-by: Fuad Tabba <tabba@google.com>
>>> Signed-off-by: Marc Zyngier <maz@kernel.org>
>>> ---
>>> arch/arm64/kvm/mmu.c | 28 ++++++++++++----------------
>>> 1 file changed, 12 insertions(+), 16 deletions(-)
>>>
>>> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
>>> index 0c71e3a9af8b0..ee2a548999b1b 100644
>>> --- a/arch/arm64/kvm/mmu.c
>>> +++ b/arch/arm64/kvm/mmu.c
>>> @@ -1870,18 +1870,21 @@ static int kvm_s2_fault_compute_prot(struct kvm_s2_fault *fault)
>>> if (fault->exec_fault)
>>> fault->prot |= KVM_PGTABLE_PROT_X;
>>>
>>> - if (fault->s2_force_noncacheable) {
>>> - if (fault->vm_flags & VM_ALLOW_ANY_UNCACHED)
>>> - fault->prot |= KVM_PGTABLE_PROT_NORMAL_NC;
>>> - else
>>> - fault->prot |= KVM_PGTABLE_PROT_DEVICE;
>>> - } else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC)) {
>>> + if (fault->s2_force_noncacheable)
>>> + fault->prot |= (fault->vm_flags & VM_ALLOW_ANY_UNCACHED) ?
>>> + KVM_PGTABLE_PROT_NORMAL_NC : KVM_PGTABLE_PROT_DEVICE;
>>> + else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC))
>>> fault->prot |= KVM_PGTABLE_PROT_X;
>>> - }
>>
>> Is not the existing code block bit more cleaner though ?
>
> What is wrong with this? Are you stating a matter of personal taste ?
> > Ternary operators are great at making things more readable by reducing
> the amount of nesting, and I'm all in favour of anything that makes
> this $%^&*( code easier to parse.
>
> Or are you pointing out a technical issue?
There is no technical issue here. Just that the existing code block
appeared bit easier to read but as you mentioned earlier that is
probably subjective. Never mind and please feel free to ignore this
comment.
^ permalink raw reply
* Re: [RFC PATCH 1/7] media: v4l2-ctrls: Add V4L2_CID_MEMORY_USAGE control
From: Ming Qian(OSS) @ 2026-04-01 2:23 UTC (permalink / raw)
To: Nicolas Dufresne, Frank Li
Cc: linux-media, mchehab, hverkuil-cisco, sebastian.fricke, shawnguo,
s.hauer, kernel, festevam, linux-imx, xiahong.bao, eagle.zhou,
imx, linux-kernel, linux-arm-kernel
In-Reply-To: <079b1630abe5dd22e032797fc12925c9c79ea305.camel@ndufresne.ca>
Hi Nicolas,
On 3/31/2026 10:54 PM, Nicolas Dufresne wrote:
> Le mardi 31 mars 2026 à 10:33 -0400, Frank Li a écrit :
>> On Tue, Mar 31, 2026 at 03:23:11PM +0800, ming.qian@oss.nxp.com wrote:
>>> From: Ming Qian <ming.qian@oss.nxp.com>
>>>
>>> Add a new read-only control V4L2_CID_MEMORY_USAGE that allows
>>> applications to query the total amount of memory currently used
>>> by a device instance.
>>>
>>> This control reports the memory consumption in bytes, including
>>> internal buffers, intermediate processing data, and other
>>> driver-managed allocations. Applications can use this information
>>> for debugging, resource monitoring, or making informed decisions
>>> about buffer allocation strategies.
>>>
>>> Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
>>> ---
>>
>> Not sure why not export these information by debugfs, or any benefit vs
>> debugfs?
>
> There is also a on-going proposal that uses fdinfo.
>
> Nicolas
>
Thanks for the reminder about the ongoing fdinfo proposal.
Just to confirm, you are referring to Detlev’s ongoing fdinfo proposal,
specifically this series:
https://lore.kernel.org/lkml/20260212162328.192217-1-detlev.casanova@collabora.com/
I will align my work with it and switch to using fdinfo.
Once the show_fdinfo support from that series is merged, I will prepare
the next revision of my patch accordingly.
Regards,
Ming
>>
>> Generanlly document should be first patch, then driver change.
>>
>> Frank
>>
>>> drivers/media/v4l2-core/v4l2-ctrls-defs.c | 8 ++++++++
>>> include/uapi/linux/v4l2-controls.h | 4 +++-
>>> 2 files changed, 11 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
>>> index 551426c4cd01..053db78ff661 100644
>>> --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
>>> +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
>>> @@ -831,6 +831,7 @@ const char *v4l2_ctrl_get_name(u32 id)
>>> case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component";
>>> case V4L2_CID_COLORFX_CBCR: return "Color Effects, CbCr";
>>> case V4L2_CID_COLORFX_RGB: return "Color Effects, RGB";
>>> + case V4L2_CID_MEMORY_USAGE: return "Memory Usage";
>>>
>>> /*
>>> * Codec controls
>>> @@ -1476,6 +1477,13 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
>>> *min = 0;
>>> *max = 0xffff;
>>> break;
>>> + case V4L2_CID_MEMORY_USAGE:
>>> + *type = V4L2_CTRL_TYPE_INTEGER64;
>>> + *flags |= V4L2_CTRL_FLAG_READ_ONLY;
>>> + *min = 0;
>>> + *max = S64_MAX;
>>> + *step = 1;
>>> + break;
>>> case V4L2_CID_FLASH_FAULT:
>>> case V4L2_CID_JPEG_ACTIVE_MARKER:
>>> case V4L2_CID_3A_LOCK:
>>> diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
>>> index 68dd0c4e47b2..02c6f960d38e 100644
>>> --- a/include/uapi/linux/v4l2-controls.h
>>> +++ b/include/uapi/linux/v4l2-controls.h
>>> @@ -110,8 +110,10 @@ enum v4l2_colorfx {
>>> #define V4L2_CID_COLORFX_CBCR (V4L2_CID_BASE+42)
>>> #define V4L2_CID_COLORFX_RGB (V4L2_CID_BASE+43)
>>>
>>> +#define V4L2_CID_MEMORY_USAGE (V4L2_CID_BASE+44)
>>> +
>>> /* last CID + 1 */
>>> -#define V4L2_CID_LASTP1 (V4L2_CID_BASE+44)
>>> +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+45)
>>>
>>> /* USER-class private control IDs */
>>>
>>> --
>>> 2.53.0
>>>
^ permalink raw reply
* Re: [PATCH v2 12/30] KVM: arm64: Hoist MTE validation check out of MMU lock path
From: Anshuman Khandual @ 2026-04-01 2:23 UTC (permalink / raw)
To: Marc Zyngier, kvmarm, linux-arm-kernel, kvm
Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
Fuad Tabba, Will Deacon, Quentin Perret
In-Reply-To: <20260327113618.4051534-13-maz@kernel.org>
On 27/03/26 5:06 PM, Marc Zyngier wrote:
> From: Fuad Tabba <tabba@google.com>
>
> Simplify the non-cacheable attributes assignment by using a ternary
> operator. Additionally, hoist the MTE validation check (mte_allowed) out
> of kvm_s2_fault_map() and into kvm_s2_fault_compute_prot(). This allows
> us to fail faster and avoid acquiring the KVM MMU lock unnecessarily
> when the VMM introduces a disallowed VMA for an MTE-enabled guest.
>
> Signed-off-by: Fuad Tabba <tabba@google.com>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> arch/arm64/kvm/mmu.c | 28 ++++++++++++----------------
> 1 file changed, 12 insertions(+), 16 deletions(-)
>
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 0c71e3a9af8b0..ee2a548999b1b 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1870,18 +1870,21 @@ static int kvm_s2_fault_compute_prot(struct kvm_s2_fault *fault)
> if (fault->exec_fault)
> fault->prot |= KVM_PGTABLE_PROT_X;
>
> - if (fault->s2_force_noncacheable) {
> - if (fault->vm_flags & VM_ALLOW_ANY_UNCACHED)
> - fault->prot |= KVM_PGTABLE_PROT_NORMAL_NC;
> - else
> - fault->prot |= KVM_PGTABLE_PROT_DEVICE;
> - } else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC)) {
> + if (fault->s2_force_noncacheable)
> + fault->prot |= (fault->vm_flags & VM_ALLOW_ANY_UNCACHED) ?
> + KVM_PGTABLE_PROT_NORMAL_NC : KVM_PGTABLE_PROT_DEVICE;
> + else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC))
> fault->prot |= KVM_PGTABLE_PROT_X;
> - }
>
> if (fault->nested)
> adjust_nested_exec_perms(kvm, fault->nested, &fault->prot);
>
> + if (!fault->fault_is_perm && !fault->s2_force_noncacheable && kvm_has_mte(kvm)) {
> + /* Check the VMM hasn't introduced a new disallowed VMA */
> + if (!fault->mte_allowed)
> + return -EFAULT;
> + }
> +
> return 0;
> }
>
> @@ -1918,15 +1921,8 @@ static int kvm_s2_fault_map(struct kvm_s2_fault *fault, void *memcache)
> }
> }
>
> - if (!fault->fault_is_perm && !fault->s2_force_noncacheable && kvm_has_mte(kvm)) {
> - /* Check the VMM hasn't introduced a new disallowed VMA */
> - if (fault->mte_allowed) {
> - sanitise_mte_tags(kvm, fault->pfn, fault->vma_pagesize);
> - } else {
> - ret = -EFAULT;
> - goto out_unlock;
> - }
> - }
> + if (!fault->fault_is_perm && !fault->s2_force_noncacheable && kvm_has_mte(kvm))
> + sanitise_mte_tags(kvm, fault->pfn, fault->vma_pagesize);
>
> /*
> * Under the premise of getting a FSC_PERM fault, we just need to relax
^ permalink raw reply
* [PATCH v2] ACPI: AGDI: fix missing newline in error message
From: Haoyu Lu @ 2026-04-01 2:29 UTC (permalink / raw)
To: Rafael J . Wysocki, Lorenzo Pieralisi, Hanjun Guo, Sudeep Holla,
Catalin Marinas, Will Deacon
Cc: Len Brown, Ilkka Koskinen, Russell King, linux-acpi,
linux-arm-kernel, linux-kernel, Haoyu Lu
Add the missing trailing newline to the dev_err() message
printed when SDEI event registration fails.
This keeps the error output as a properly terminated log line.
Changes in v2:
- Change subject prefix from "acpi: arm64: agdi:" to "ACPI: AGDI:"
Fixes: a2a591fb76e6f5461dfd04715b69c317e50c43a5 ("ACPI: AGDI: Add driver for Arm Generic Diagnostic Dump and Reset device")
Reviewed-by: Ilkka Koskinen <ilkka@os.amperecomputing.com>
Signed-off-by: Haoyu Lu <hechushiguitu666@gmail.com>
---
drivers/acpi/arm64/agdi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c
index feb4b2cb4618..0c2d9d6c160b 100644
--- a/drivers/acpi/arm64/agdi.c
+++ b/drivers/acpi/arm64/agdi.c
@@ -36,7 +36,7 @@ static int agdi_sdei_probe(struct platform_device *pdev,
err = sdei_event_register(adata->sdei_event, agdi_sdei_handler, pdev);
if (err) {
- dev_err(&pdev->dev, "Failed to register for SDEI event %d",
+ dev_err(&pdev->dev, "Failed to register for SDEI event %d\n",
adata->sdei_event);
return err;
}
--
2.17.1
^ permalink raw reply related
* Re: [PATCH net-next] net: airoha: Fix typo in airoha_set_gdm2_loopback routine name
From: patchwork-bot+netdevbpf @ 2026-04-01 2:40 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, linux-arm-kernel,
linux-mediatek, netdev
In-Reply-To: <20260330-airoha_set_gdm2_loopback-fix-typo-v1-1-a1320ff6b6cc@kernel.org>
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 30 Mar 2026 00:03:49 +0200 you wrote:
> Rename airhoha_set_gdm2_loopback() in airoha_set_gdm2_loopback()
>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
> drivers/net/ethernet/airoha/airoha_eth.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> [...]
Here is the summary with links:
- [net-next] net: airoha: Fix typo in airoha_set_gdm2_loopback routine name
https://git.kernel.org/netdev/net-next/c/a94ddc191f19
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH v2 15/30] KVM: arm64: Make fault_ipa immutable
From: Anshuman Khandual @ 2026-04-01 2:44 UTC (permalink / raw)
To: Marc Zyngier, kvmarm, linux-arm-kernel, kvm
Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
Fuad Tabba, Will Deacon, Quentin Perret
In-Reply-To: <20260327113618.4051534-16-maz@kernel.org>
On 27/03/26 5:06 PM, Marc Zyngier wrote:
> Updating fault_ipa is conceptually annoying, as it changes something
> that is a property of the fault itself.
>
> Stop doing so and instead use fault->gfn as the sole piece of state
> that can be used to represent the faulting IPA.
>
> At the same time, introduce get_canonical_gfn() for the couple of case
> we're we are concerned with the memslot-related IPA and not the faulting
> one.
>
> Tested-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
> arch/arm64/kvm/mmu.c | 38 ++++++++++++++++++++++++++------------
> 1 file changed, 26 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 67e5e867e01dc..496bf5903ed3d 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1400,10 +1400,10 @@ static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot,
> */
> static long
> transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,
> - unsigned long hva, kvm_pfn_t *pfnp,
> - phys_addr_t *ipap)
> + unsigned long hva, kvm_pfn_t *pfnp, gfn_t *gfnp)
> {
> kvm_pfn_t pfn = *pfnp;
> + gfn_t gfn = *gfnp;
>
> /*
> * Make sure the adjustment is done only for THP pages. Also make
> @@ -1419,7 +1419,8 @@ transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,
> if (sz < PMD_SIZE)
> return PAGE_SIZE;
>
> - *ipap &= PMD_MASK;
> + gfn &= ~(PTRS_PER_PMD - 1);
> + *gfnp = gfn;
> pfn &= ~(PTRS_PER_PMD - 1);
> *pfnp = pfn;
>
> @@ -1735,7 +1736,6 @@ static int kvm_s2_fault_get_vma_info(struct kvm_s2_fault *fault)
> {
> struct vm_area_struct *vma;
> struct kvm *kvm = fault->vcpu->kvm;
> - phys_addr_t ipa;
>
> mmap_read_lock(current->mm);
> vma = vma_lookup(current->mm, fault->hva);
> @@ -1753,9 +1753,7 @@ static int kvm_s2_fault_get_vma_info(struct kvm_s2_fault *fault)
> * mapping size to ensure we find the right PFN and lay down the
> * mapping in the right place.
> */
> - fault->fault_ipa = ALIGN_DOWN(fault->fault_ipa, fault->vma_pagesize);
> - ipa = fault->nested ? kvm_s2_trans_output(fault->nested) : fault->fault_ipa;
> - fault->gfn = ALIGN_DOWN(ipa, fault->vma_pagesize) >> PAGE_SHIFT;
> + fault->gfn = ALIGN_DOWN(fault->fault_ipa, fault->vma_pagesize) >> PAGE_SHIFT;
>
> fault->mte_allowed = kvm_vma_mte_allowed(vma);
>
> @@ -1777,6 +1775,17 @@ static int kvm_s2_fault_get_vma_info(struct kvm_s2_fault *fault)
> return 0;
> }
>
> +static gfn_t get_canonical_gfn(struct kvm_s2_fault *fault)
> +{
> + phys_addr_t ipa;
> +
> + if (!fault->nested)
> + return fault->gfn;
> +
> + ipa = kvm_s2_trans_output(fault->nested);
> + return ALIGN_DOWN(ipa, fault->vma_pagesize) >> PAGE_SHIFT;
> +}
> +
> static int kvm_s2_fault_pin_pfn(struct kvm_s2_fault *fault)
> {
> int ret;
> @@ -1785,7 +1794,7 @@ static int kvm_s2_fault_pin_pfn(struct kvm_s2_fault *fault)
> if (ret)
> return ret;
>
> - fault->pfn = __kvm_faultin_pfn(fault->memslot, fault->gfn,
> + fault->pfn = __kvm_faultin_pfn(fault->memslot, get_canonical_gfn(fault),
> fault->write_fault ? FOLL_WRITE : 0,
> &fault->writable, &fault->page);
> if (unlikely(is_error_noslot_pfn(fault->pfn))) {
> @@ -1885,6 +1894,11 @@ static int kvm_s2_fault_compute_prot(struct kvm_s2_fault *fault)
> return 0;
> }
>
> +static phys_addr_t get_ipa(const struct kvm_s2_fault *fault)
> +{
> + return gfn_to_gpa(fault->gfn);
> +}
> +
> static int kvm_s2_fault_map(struct kvm_s2_fault *fault, void *memcache)
> {
> struct kvm *kvm = fault->vcpu->kvm;
> @@ -1909,7 +1923,7 @@ static int kvm_s2_fault_map(struct kvm_s2_fault *fault, void *memcache)
> } else {
> fault->vma_pagesize = transparent_hugepage_adjust(kvm, fault->memslot,
> fault->hva, &fault->pfn,
> - &fault->fault_ipa);
> + &fault->gfn);
>
> if (fault->vma_pagesize < 0) {
> ret = fault->vma_pagesize;
> @@ -1932,10 +1946,10 @@ static int kvm_s2_fault_map(struct kvm_s2_fault *fault, void *memcache)
> * PTE, which will be preserved.
> */
> fault->prot &= ~KVM_NV_GUEST_MAP_SZ;
> - ret = KVM_PGT_FN(kvm_pgtable_stage2_relax_perms)(pgt, fault->fault_ipa,
> + ret = KVM_PGT_FN(kvm_pgtable_stage2_relax_perms)(pgt, get_ipa(fault),
> fault->prot, flags);
> } else {
> - ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, fault->fault_ipa, fault->vma_pagesize,
> + ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, get_ipa(fault), fault->vma_pagesize,
> __pfn_to_phys(fault->pfn), fault->prot,
> memcache, flags);
> }
> @@ -1946,7 +1960,7 @@ static int kvm_s2_fault_map(struct kvm_s2_fault *fault, void *memcache)
>
> /* Mark the page dirty only if the fault is handled successfully */
> if (fault->writable && !ret)
> - mark_page_dirty_in_slot(kvm, fault->memslot, fault->gfn);
> + mark_page_dirty_in_slot(kvm, fault->memslot, get_canonical_gfn(fault));
>
> if (ret != -EAGAIN)
> return ret;
^ permalink raw reply
* Re: [PATCH v2 16/30] KVM: arm64: Move fault context to const structure
From: Anshuman Khandual @ 2026-04-01 2:53 UTC (permalink / raw)
To: Marc Zyngier, kvmarm, linux-arm-kernel, kvm
Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
Fuad Tabba, Will Deacon, Quentin Perret
In-Reply-To: <20260327113618.4051534-17-maz@kernel.org>
On 27/03/26 5:06 PM, Marc Zyngier wrote:
> In order to make it clearer what gets updated or not during fault
> handling, move a set of information that losely represents the
> fault context.
>
> This gets populated early, from handle_mem_abort(), and gets passed
> along as a const pointer. user_mem_abort()'s signature is majorly
> improved in doing so, and kvm_s2_fault loses a bunch of fields.
>
> gmem_abort() will get a similar treatment down the line.
>
> Tested-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> arch/arm64/kvm/mmu.c | 133 ++++++++++++++++++++++---------------------
> 1 file changed, 69 insertions(+), 64 deletions(-)
>
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 496bf5903ed3d..09e32f08028e4 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1565,6 +1565,14 @@ static void adjust_nested_exec_perms(struct kvm *kvm,
> *prot &= ~KVM_PGTABLE_PROT_PX;
> }
>
> +struct kvm_s2_fault_desc {
> + struct kvm_vcpu *vcpu;
> + phys_addr_t fault_ipa;
> + struct kvm_s2_trans *nested;
> + struct kvm_memory_slot *memslot;
> + unsigned long hva;
> +};
> +
> static int gmem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> struct kvm_s2_trans *nested,
> struct kvm_memory_slot *memslot, bool is_perm)
> @@ -1640,23 +1648,20 @@ static int gmem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> return ret != -EAGAIN ? ret : 0;
> }
>
> -static short kvm_s2_resolve_vma_size(struct vm_area_struct *vma,
> - unsigned long hva,
> - struct kvm_memory_slot *memslot,
> - struct kvm_s2_trans *nested,
> - bool *force_pte)
> +static short kvm_s2_resolve_vma_size(const struct kvm_s2_fault_desc *s2fd,
> + struct vm_area_struct *vma, bool *force_pte)
> {
> short vma_shift;
>
> if (*force_pte)
> vma_shift = PAGE_SHIFT;
> else
> - vma_shift = get_vma_page_shift(vma, hva);
> + vma_shift = get_vma_page_shift(vma, s2fd->hva);
>
> switch (vma_shift) {
> #ifndef __PAGETABLE_PMD_FOLDED
> case PUD_SHIFT:
> - if (fault_supports_stage2_huge_mapping(memslot, hva, PUD_SIZE))
> + if (fault_supports_stage2_huge_mapping(s2fd->memslot, s2fd->hva, PUD_SIZE))
> break;
> fallthrough;
> #endif
> @@ -1664,7 +1669,7 @@ static short kvm_s2_resolve_vma_size(struct vm_area_struct *vma,
> vma_shift = PMD_SHIFT;
> fallthrough;
> case PMD_SHIFT:
> - if (fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE))
> + if (fault_supports_stage2_huge_mapping(s2fd->memslot, s2fd->hva, PMD_SIZE))
> break;
> fallthrough;
> case CONT_PTE_SHIFT:
> @@ -1677,7 +1682,7 @@ static short kvm_s2_resolve_vma_size(struct vm_area_struct *vma,
> WARN_ONCE(1, "Unknown vma_shift %d", vma_shift);
> }
>
> - if (nested) {
> + if (s2fd->nested) {
> unsigned long max_map_size;
>
> max_map_size = *force_pte ? PAGE_SIZE : PUD_SIZE;
> @@ -1687,7 +1692,7 @@ static short kvm_s2_resolve_vma_size(struct vm_area_struct *vma,
> * can only create a block mapping if the guest stage 2 page
> * table uses at least as big a mapping.
> */
> - max_map_size = min(kvm_s2_trans_size(nested), max_map_size);
> + max_map_size = min(kvm_s2_trans_size(s2fd->nested), max_map_size);
>
> /*
> * Be careful that if the mapping size falls between
> @@ -1706,11 +1711,6 @@ static short kvm_s2_resolve_vma_size(struct vm_area_struct *vma,
> }
>
> struct kvm_s2_fault {
> - struct kvm_vcpu *vcpu;
> - phys_addr_t fault_ipa;
> - struct kvm_s2_trans *nested;
> - struct kvm_memory_slot *memslot;
> - unsigned long hva;
> bool fault_is_perm;
>
> bool write_fault;
> @@ -1732,28 +1732,28 @@ struct kvm_s2_fault {
> vm_flags_t vm_flags;
> };
>
> -static int kvm_s2_fault_get_vma_info(struct kvm_s2_fault *fault)
> +static int kvm_s2_fault_get_vma_info(const struct kvm_s2_fault_desc *s2fd,
> + struct kvm_s2_fault *fault)
> {
> struct vm_area_struct *vma;
> - struct kvm *kvm = fault->vcpu->kvm;
> + struct kvm *kvm = s2fd->vcpu->kvm;
>
> mmap_read_lock(current->mm);
> - vma = vma_lookup(current->mm, fault->hva);
> + vma = vma_lookup(current->mm, s2fd->hva);
> if (unlikely(!vma)) {
> - kvm_err("Failed to find VMA for fault->hva 0x%lx\n", fault->hva);
> + kvm_err("Failed to find VMA for hva 0x%lx\n", s2fd->hva);
> mmap_read_unlock(current->mm);
> return -EFAULT;
> }
>
> - fault->vma_pagesize = 1UL << kvm_s2_resolve_vma_size(vma, fault->hva, fault->memslot,
> - fault->nested, &fault->force_pte);
> + fault->vma_pagesize = BIT(kvm_s2_resolve_vma_size(s2fd, vma, &fault->force_pte));
>
> /*
> * Both the canonical IPA and fault IPA must be aligned to the
> * mapping size to ensure we find the right PFN and lay down the
> * mapping in the right place.
> */
> - fault->gfn = ALIGN_DOWN(fault->fault_ipa, fault->vma_pagesize) >> PAGE_SHIFT;
> + fault->gfn = ALIGN_DOWN(s2fd->fault_ipa, fault->vma_pagesize) >> PAGE_SHIFT;
>
> fault->mte_allowed = kvm_vma_mte_allowed(vma);
>
> @@ -1775,31 +1775,33 @@ static int kvm_s2_fault_get_vma_info(struct kvm_s2_fault *fault)
> return 0;
> }
>
> -static gfn_t get_canonical_gfn(struct kvm_s2_fault *fault)
> +static gfn_t get_canonical_gfn(const struct kvm_s2_fault_desc *s2fd,
> + const struct kvm_s2_fault *fault)
> {
> phys_addr_t ipa;
>
> - if (!fault->nested)
> + if (!s2fd->nested)
> return fault->gfn;
>
> - ipa = kvm_s2_trans_output(fault->nested);
> + ipa = kvm_s2_trans_output(s2fd->nested);
> return ALIGN_DOWN(ipa, fault->vma_pagesize) >> PAGE_SHIFT;
> }
>
> -static int kvm_s2_fault_pin_pfn(struct kvm_s2_fault *fault)
> +static int kvm_s2_fault_pin_pfn(const struct kvm_s2_fault_desc *s2fd,
> + struct kvm_s2_fault *fault)
> {
> int ret;
>
> - ret = kvm_s2_fault_get_vma_info(fault);
> + ret = kvm_s2_fault_get_vma_info(s2fd, fault);
> if (ret)
> return ret;
>
> - fault->pfn = __kvm_faultin_pfn(fault->memslot, get_canonical_gfn(fault),
> + fault->pfn = __kvm_faultin_pfn(s2fd->memslot, get_canonical_gfn(s2fd, fault),
> fault->write_fault ? FOLL_WRITE : 0,
> &fault->writable, &fault->page);
> if (unlikely(is_error_noslot_pfn(fault->pfn))) {
> if (fault->pfn == KVM_PFN_ERR_HWPOISON) {
> - kvm_send_hwpoison_signal(fault->hva, __ffs(fault->vma_pagesize));
> + kvm_send_hwpoison_signal(s2fd->hva, __ffs(fault->vma_pagesize));
> return 0;
> }
> return -EFAULT;
> @@ -1808,9 +1810,10 @@ static int kvm_s2_fault_pin_pfn(struct kvm_s2_fault *fault)
> return 1;
> }
>
> -static int kvm_s2_fault_compute_prot(struct kvm_s2_fault *fault)
> +static int kvm_s2_fault_compute_prot(const struct kvm_s2_fault_desc *s2fd,
> + struct kvm_s2_fault *fault)
> {
> - struct kvm *kvm = fault->vcpu->kvm;
> + struct kvm *kvm = s2fd->vcpu->kvm;
>
> /*
> * Check if this is non-struct page memory PFN, and cannot support
> @@ -1862,13 +1865,13 @@ static int kvm_s2_fault_compute_prot(struct kvm_s2_fault *fault)
> * and trigger the exception here. Since the memslot is valid, inject
> * the fault back to the guest.
> */
> - if (esr_fsc_is_excl_atomic_fault(kvm_vcpu_get_esr(fault->vcpu))) {
> - kvm_inject_dabt_excl_atomic(fault->vcpu, kvm_vcpu_get_hfar(fault->vcpu));
> + if (esr_fsc_is_excl_atomic_fault(kvm_vcpu_get_esr(s2fd->vcpu))) {
> + kvm_inject_dabt_excl_atomic(s2fd->vcpu, kvm_vcpu_get_hfar(s2fd->vcpu));
> return 1;
> }
>
> - if (fault->nested)
> - adjust_nested_fault_perms(fault->nested, &fault->prot, &fault->writable);
> + if (s2fd->nested)
> + adjust_nested_fault_perms(s2fd->nested, &fault->prot, &fault->writable);
>
> if (fault->writable)
> fault->prot |= KVM_PGTABLE_PROT_W;
> @@ -1882,8 +1885,8 @@ static int kvm_s2_fault_compute_prot(struct kvm_s2_fault *fault)
> else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC))
> fault->prot |= KVM_PGTABLE_PROT_X;
>
> - if (fault->nested)
> - adjust_nested_exec_perms(kvm, fault->nested, &fault->prot);
> + if (s2fd->nested)
> + adjust_nested_exec_perms(kvm, s2fd->nested, &fault->prot);
>
> if (!fault->fault_is_perm && !fault->s2_force_noncacheable && kvm_has_mte(kvm)) {
> /* Check the VMM hasn't introduced a new disallowed VMA */
> @@ -1899,15 +1902,16 @@ static phys_addr_t get_ipa(const struct kvm_s2_fault *fault)
> return gfn_to_gpa(fault->gfn);
> }
>
> -static int kvm_s2_fault_map(struct kvm_s2_fault *fault, void *memcache)
> +static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
> + struct kvm_s2_fault *fault, void *memcache)
> {
> - struct kvm *kvm = fault->vcpu->kvm;
> + struct kvm *kvm = s2fd->vcpu->kvm;
> struct kvm_pgtable *pgt;
> int ret;
> enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_SHARED;
>
> kvm_fault_lock(kvm);
> - pgt = fault->vcpu->arch.hw_mmu->pgt;
> + pgt = s2fd->vcpu->arch.hw_mmu->pgt;
> ret = -EAGAIN;
> if (mmu_invalidate_retry(kvm, fault->mmu_seq))
> goto out_unlock;
> @@ -1921,8 +1925,8 @@ static int kvm_s2_fault_map(struct kvm_s2_fault *fault, void *memcache)
> if (fault->fault_is_perm && fault->fault_granule > PAGE_SIZE) {
> fault->vma_pagesize = fault->fault_granule;
> } else {
> - fault->vma_pagesize = transparent_hugepage_adjust(kvm, fault->memslot,
> - fault->hva, &fault->pfn,
> + fault->vma_pagesize = transparent_hugepage_adjust(kvm, s2fd->memslot,
> + s2fd->hva, &fault->pfn,
> &fault->gfn);
>
> if (fault->vma_pagesize < 0) {
> @@ -1960,34 +1964,27 @@ static int kvm_s2_fault_map(struct kvm_s2_fault *fault, void *memcache)
>
> /* Mark the page dirty only if the fault is handled successfully */
> if (fault->writable && !ret)
> - mark_page_dirty_in_slot(kvm, fault->memslot, get_canonical_gfn(fault));
> + mark_page_dirty_in_slot(kvm, s2fd->memslot, get_canonical_gfn(s2fd, fault));
>
> if (ret != -EAGAIN)
> return ret;
> return 0;
> }
>
> -static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> - struct kvm_s2_trans *nested,
> - struct kvm_memory_slot *memslot, unsigned long hva,
> - bool fault_is_perm)
> +static int user_mem_abort(const struct kvm_s2_fault_desc *s2fd)
> {
> - bool write_fault = kvm_is_write_fault(vcpu);
> - bool logging_active = memslot_is_logging(memslot);
> + bool perm_fault = kvm_vcpu_trap_is_permission_fault(s2fd->vcpu);
> + bool write_fault = kvm_is_write_fault(s2fd->vcpu);
> + bool logging_active = memslot_is_logging(s2fd->memslot);
> struct kvm_s2_fault fault = {
> - .vcpu = vcpu,
> - .fault_ipa = fault_ipa,
> - .nested = nested,
> - .memslot = memslot,
> - .hva = hva,
> - .fault_is_perm = fault_is_perm,
> + .fault_is_perm = perm_fault,
> .logging_active = logging_active,
> .force_pte = logging_active,
> .prot = KVM_PGTABLE_PROT_R,
> - .fault_granule = fault_is_perm ? kvm_vcpu_trap_get_perm_fault_granule(vcpu) : 0,
> + .fault_granule = perm_fault ? kvm_vcpu_trap_get_perm_fault_granule(s2fd->vcpu) : 0,
> .write_fault = write_fault,
> - .exec_fault = kvm_vcpu_trap_is_exec_fault(vcpu),
> - .topup_memcache = !fault_is_perm || (logging_active && write_fault),
> + .exec_fault = kvm_vcpu_trap_is_exec_fault(s2fd->vcpu),
> + .topup_memcache = !perm_fault || (logging_active && write_fault),
> };
> void *memcache;
> int ret;
> @@ -2000,7 +1997,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> * only exception to this is when dirty logging is enabled at runtime
> * and a write fault needs to collapse a block entry into a table.
> */
> - ret = prepare_mmu_memcache(vcpu, fault.topup_memcache, &memcache);
> + ret = prepare_mmu_memcache(s2fd->vcpu, fault.topup_memcache, &memcache);
> if (ret)
> return ret;
>
> @@ -2008,17 +2005,17 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
> * Let's check if we will get back a huge page backed by hugetlbfs, or
> * get block mapping for device MMIO region.
> */
> - ret = kvm_s2_fault_pin_pfn(&fault);
> + ret = kvm_s2_fault_pin_pfn(s2fd, &fault);
> if (ret != 1)
> return ret;
>
> - ret = kvm_s2_fault_compute_prot(&fault);
> + ret = kvm_s2_fault_compute_prot(s2fd, &fault);
> if (ret) {
> kvm_release_page_unused(fault.page);
> return ret;
> }
>
> - return kvm_s2_fault_map(&fault, memcache);
> + return kvm_s2_fault_map(s2fd, &fault, memcache);
> }
>
> /* Resolve the access fault by making the page young again. */
> @@ -2284,12 +2281,20 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
> VM_WARN_ON_ONCE(kvm_vcpu_trap_is_permission_fault(vcpu) &&
> !write_fault && !kvm_vcpu_trap_is_exec_fault(vcpu));
>
> + const struct kvm_s2_fault_desc s2fd = {
> + .vcpu = vcpu,
> + .fault_ipa = fault_ipa,
> + .nested = nested,
> + .memslot = memslot,
> + .hva = hva,
> + };
> +
> if (kvm_slot_has_gmem(memslot))
> ret = gmem_abort(vcpu, fault_ipa, nested, memslot,
> esr_fsc_is_permission_fault(esr));
> else
> - ret = user_mem_abort(vcpu, fault_ipa, nested, memslot, hva,
> - esr_fsc_is_permission_fault(esr));
> + ret = user_mem_abort(&s2fd);
> +
> if (ret == 0)
> ret = 1;
> out:
^ permalink raw reply
* Re: [PATCH 1/2] pmdomain/rockchip: skip QoS operations for idle-only domains
From: Shawn Lin @ 2026-04-01 2:54 UTC (permalink / raw)
To: Daniel Bozeman
Cc: shawn.lin, linux-pm, linux-arm-kernel, linux-rockchip,
linux-kernel, ulf.hansson, heiko
In-Reply-To: <CAG+Ngm+xJCCQMPddZx8AbPEeH3rUrn3GKF575zXpGPJrnELvMw@mail.gmail.com>
在 2026/04/01 星期三 10:34, Daniel Bozeman 写道:
> The NanoPi Zero2 (RK3528) kernel panics during boot when a
> GPIO-controlled USB VBUS regulator is defined on GPIO4 (which
> is in PD_RKVENC). The goal of this series is to make USB host
> power work on boards that use GPIO4 for regulator control.
>
> The root cause is a probe ordering issue. On RK3528, the power
> domain controller's first probe attempt fails because PD_GPU's
> clock lookup returns -EPROBE_DEFER (CRU hasn't probed yet).
> The driver then tears down all domains, including PD_RKVENC
> which would have registered successfully (it has no clock
> requirements). During this window, the USB regulator driver
> probes and requests GPIO4, which is in the now-unregistered
> PD_RKVENC. This triggers a synchronous external abort.
>
> With patch 2 alone (skipping deferred domains), the idle-only
> domains register successfully. But the genpd framework then
> attempts to power them off via genpd_power_off_work_fn. This
> calls rockchip_pd_power(), which does QoS save and idle
> requests on domains with pwr_mask == 0 that cannot actually
> be powered off.
>
> To your question about why QoS registers become inaccessible
> on idle-only domains: I have not root-caused that specifically.
> What I can confirm is the crash trace below, which occurs when
> patch 2 is applied without patch 1. The abort happens during
This sounds like a parent-child dependency which hasn't been sorted
out. My another question will be: with patch 1 applied, how to save-
restore qos registers during normal S2R usage?
> rockchip_pmu_set_idle_request on an idle-only domain:
>
> Internal error: synchronous external abort: 0000000096000010
> CPU: 2 PID: 60 Comm: kworker/2:3
> Workqueue: pm genpd_power_off_work_fn
> pc : regmap_mmio_read32le+0x8/0x20
> lr : regmap_mmio_read+0x44/0x70
> Call trace:
> regmap_mmio_read32le+0x8/0x20
> _regmap_bus_reg_read+0x6c/0xac
> _regmap_read+0x60/0xd8
> regmap_read+0x4c/0x7c
> rockchip_pmu_set_idle_request.isra.0+0x94/0x1b4
> rockchip_pd_power+0x37c/0x608
> rockchip_pd_power_off+0x14/0x38
> genpd_power_off.isra.0+0x1f0/0x2f0
> genpd_power_off_work_fn+0x34/0x54
>
> The two patches work together: patch 1 prevents QoS access
> on idle-only domains, and patch 2 prevents the full probe
> teardown when a single domain defers.
>
> Tested on NanoPi Zero2 (fixes panic) and Radxa E20C (no
> regression).
>
> On Tue, Mar 31, 2026 at 6:17 PM Shawn Lin <shawn.lin@rock-chips.com
> <mailto:shawn.lin@rock-chips.com>> wrote:
>
> Hi Daniel,
>
> 在 2026/04/01 星期三 2:02, Daniel Bozeman 写道:
> > Idle-only power domains (pwr_mask == 0) cannot actually be powered
> > on or off. rockchip_do_pmu_set_power_domain() already returns early
> > for these domains, but rockchip_pd_power() still attempts QoS save
> > and idle requests before reaching that check.
> >
> > On RK3528, the idle-only domains (PD_RKVENC, PD_VO, PD_VPU) have
> > QoS registers that may be inaccessible when the generic power domain
> > framework attempts to power them off, leading to synchronous external
> > aborts.
> >
>
> Is it the real abort happened on your RK3528 board? I am trying to
> understand the problem first. Even with idle-only powerdomain, the code
> also save the QoS registers before set idle to the powerdomain, so
> how the QoS registers become inaccessible?
>
> > Return early from rockchip_pd_power() when pwr_mask is zero, matching
> > the existing guard in rockchip_do_pmu_set_power_domain().
> >
> > Fixes: 1fe767a56c32 ("soc: rockchip: power-domain: allow domains
> only handling idle requests")
> > Signed-off-by: Daniel Bozeman <daniel@orb.net
> <mailto:daniel@orb.net>>
> > ---
> > drivers/pmdomain/rockchip/pm-domains.c | 3 +++
> > 1 file changed, 3 insertions(+)
> >
> > diff --git a/drivers/pmdomain/rockchip/pm-domains.c
> b/drivers/pmdomain/rockchip/pm-domains.c
> > index 490bbb1d1d..2eecae092a 100644
> > --- a/drivers/pmdomain/rockchip/pm-domains.c
> > +++ b/drivers/pmdomain/rockchip/pm-domains.c
> > @@ -640,6 +640,9 @@ static int rockchip_pd_power(struct
> rockchip_pm_domain *pd, bool power_on)
> > if (rockchip_pmu_domain_is_on(pd) == power_on)
> > return 0;
> >
> > + if (pd->info->pwr_mask == 0)
> > + return 0;
> > +
> > ret = clk_bulk_enable(pd->num_clks, pd->clks);
> > if (ret < 0) {
> > dev_err(pmu->dev, "failed to enable clocks\n");
> >
> > base-commit: bc330699801d3b4f99110365512caed5adcfaca3
>
^ permalink raw reply
* Re: [RESEND PATCH net v3 2/2] net: stmmac: Prevent indefinite RX stall on buffer exhaustion
From: Jakub Kicinski @ 2026-04-01 2:59 UTC (permalink / raw)
To: Sam Edwards
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Paolo Abeni,
Maxime Coquelin, Alexandre Torgue, Russell King (Oracle),
Maxime Chevallier, Ovidiu Panait, Vladimir Oltean, Baruch Siach,
Serge Semin, Giuseppe Cavallaro, netdev, linux-stm32,
linux-arm-kernel, linux-kernel, stable
In-Reply-To: <20260328192503.520689-3-CFSworks@gmail.com>
On Sat, 28 Mar 2026 12:25:03 -0700 Sam Edwards wrote:
> @@ -5870,6 +5871,10 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
> priv->xstats.rx_dropped += rx_dropped;
> priv->xstats.rx_errors += rx_errors;
>
> + /* If stmmac_rx_refill() failed, keep trying until it doesn't. */
> + if (unlikely(stmmac_rx_dirty(priv, queue) > 0))
> + return budget;
If the system is OOMing having ksoftirq busy looping indefinitely is
not going to be very helpful. 1) only react if the fill level is below
some critical threshold, 2) try to add some delay (timer)? before the
retry
--
pw-bot: cr
^ permalink raw reply
* Re: [PATCH] KVM: arm64: pkvm: Rollback refcount on hyp share/unshare error
From: Vincent Donnefort @ 2026-04-01 3:01 UTC (permalink / raw)
To: Quentin Perret
Cc: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will, linux-arm-kernel, kvmarm, kernel-team
In-Reply-To: <acpCq1qZCMFqocs3@google.com>
On Mon, Mar 30, 2026 at 09:41:01AM +0000, Quentin Perret wrote:
> Hey Vincent,
>
> On Tuesday 24 Mar 2026 at 17:27:57 (+0000), Vincent Donnefort wrote:
> > If one of the HVC __pkvm_host_share_hyp or __pkvm_host_unshare_hyp fails,
> > rollback the refcount to ensure the hyp_shared_pfns tracking reflects
> > the actual sharing status.
>
> If any of these hypercalls fail I think we're still in trouble as
> kvm_{un}share_hyp() work on multi-page ranges and we could leak pages in
> a borked state if we fail halfway through. And failing any of these
> hypercalls is also sign of a bigger problem somewhere else so I wasn't
> too worried.
Yes, my bad, I haven't made that clear in the commit message: a failed HVC
right now is very much unlikely. I meant more to future proof and this isn't
fixing an existing corner case.
>
> But if we're going to fix this properly, I'd suggest also improving the
> error handling in kvm_share_hyp(). 'Fixing' kvm_unshare_hyp() is a bit
> harder because we must tell the caller to leak the data structure that
> was shared I presume, so maybe we just keep the WARN and cross our
> fingers :)
ack
>
> Cheers,
> Quentin
>
> > Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
> >
> > diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> > index 17d64a1e11e5..0fb41d2c8b44 100644
> > --- a/arch/arm64/kvm/mmu.c
> > +++ b/arch/arm64/kvm/mmu.c
> > @@ -493,11 +493,17 @@ static int share_pfn_hyp(u64 pfn)
> > goto unlock;
> > }
> >
> > + ret = kvm_call_hyp_nvhe(__pkvm_host_share_hyp, pfn);
> > + if (ret) {
> > + kfree(this);
> > + goto unlock;
> > + }
> > +
> > this->pfn = pfn;
> > this->count = 1;
> > rb_link_node(&this->node, parent, node);
> > rb_insert_color(&this->node, &hyp_shared_pfns);
> > - ret = kvm_call_hyp_nvhe(__pkvm_host_share_hyp, pfn);
> > +
> > unlock:
> > mutex_unlock(&hyp_shared_pfns_lock);
> >
> > @@ -521,9 +527,15 @@ static int unshare_pfn_hyp(u64 pfn)
> > if (this->count)
> > goto unlock;
> >
> > + ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_hyp, pfn);
> > + if (ret) {
> > + this->count++;
> > + goto unlock;
> > + }
> > +
> > rb_erase(&this->node, &hyp_shared_pfns);
> > kfree(this);
> > - ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_hyp, pfn);
> > +
> > unlock:
> > mutex_unlock(&hyp_shared_pfns_lock);
> >
> >
> > base-commit: c369299895a591d96745d6492d4888259b004a9e
> > --
> > 2.53.0.1018.g2bb0e51243-goog
> >
^ permalink raw reply
* Re: [PATCH v2 17/30] KVM: arm64: Replace fault_is_perm with a helper
From: Anshuman Khandual @ 2026-04-01 3:18 UTC (permalink / raw)
To: Marc Zyngier, kvmarm, linux-arm-kernel, kvm
Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
Fuad Tabba, Will Deacon, Quentin Perret
In-Reply-To: <20260327113618.4051534-18-maz@kernel.org>
On 27/03/26 5:06 PM, Marc Zyngier wrote:
> Carrying a boolean to indicate that a given fault is a permission fault
> is slightly odd, as this is a property of the fault itself, and we'd
> better avoid duplicating state.
>
> For this purpose, introduce a kvm_s2_fault_is_perm() predicate that
> can take a fault descriptor as a parameter. fault_is_perm is therefore
> dropped from kvm_s2_fault.
>
> Tested-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Reviewed-by: Joey Gouly <joey.gouly@arm.com>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
> arch/arm64/kvm/mmu.c | 17 ++++++++++-------
> 1 file changed, 10 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 09e32f08028e4..1e0d93d6d265a 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1711,8 +1711,6 @@ static short kvm_s2_resolve_vma_size(const struct kvm_s2_fault_desc *s2fd,
> }
>
> struct kvm_s2_fault {
> - bool fault_is_perm;
> -
> bool write_fault;
> bool exec_fault;
> bool writable;
> @@ -1732,6 +1730,11 @@ struct kvm_s2_fault {
> vm_flags_t vm_flags;
> };
>
> +static bool kvm_s2_fault_is_perm(const struct kvm_s2_fault_desc *s2fd)
> +{
> + return kvm_vcpu_trap_is_permission_fault(s2fd->vcpu);
> +}
> +
> static int kvm_s2_fault_get_vma_info(const struct kvm_s2_fault_desc *s2fd,
> struct kvm_s2_fault *fault)
> {
> @@ -1888,7 +1891,7 @@ static int kvm_s2_fault_compute_prot(const struct kvm_s2_fault_desc *s2fd,
> if (s2fd->nested)
> adjust_nested_exec_perms(kvm, s2fd->nested, &fault->prot);
>
> - if (!fault->fault_is_perm && !fault->s2_force_noncacheable && kvm_has_mte(kvm)) {
> + if (!kvm_s2_fault_is_perm(s2fd) && !fault->s2_force_noncacheable && kvm_has_mte(kvm)) {
> /* Check the VMM hasn't introduced a new disallowed VMA */
> if (!fault->mte_allowed)
> return -EFAULT;
> @@ -1905,6 +1908,7 @@ static phys_addr_t get_ipa(const struct kvm_s2_fault *fault)
> static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
> struct kvm_s2_fault *fault, void *memcache)
> {
> + bool fault_is_perm = kvm_s2_fault_is_perm(s2fd);
> struct kvm *kvm = s2fd->vcpu->kvm;
> struct kvm_pgtable *pgt;
> int ret;
> @@ -1922,7 +1926,7 @@ static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
> */
> if (fault->vma_pagesize == PAGE_SIZE &&
> !(fault->force_pte || fault->s2_force_noncacheable)) {
> - if (fault->fault_is_perm && fault->fault_granule > PAGE_SIZE) {
> + if (fault_is_perm && fault->fault_granule > PAGE_SIZE) {
> fault->vma_pagesize = fault->fault_granule;
> } else {
> fault->vma_pagesize = transparent_hugepage_adjust(kvm, s2fd->memslot,
> @@ -1936,7 +1940,7 @@ static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
> }
> }
>
> - if (!fault->fault_is_perm && !fault->s2_force_noncacheable && kvm_has_mte(kvm))
> + if (!fault_is_perm && !fault->s2_force_noncacheable && kvm_has_mte(kvm))
> sanitise_mte_tags(kvm, fault->pfn, fault->vma_pagesize);
>
> /*
> @@ -1944,7 +1948,7 @@ static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
> * permissions only if fault->vma_pagesize equals fault->fault_granule. Otherwise,
> * kvm_pgtable_stage2_map() should be called to change block size.
> */
> - if (fault->fault_is_perm && fault->vma_pagesize == fault->fault_granule) {
> + if (fault_is_perm && fault->vma_pagesize == fault->fault_granule) {
> /*
> * Drop the SW bits in favour of those stored in the
> * PTE, which will be preserved.
> @@ -1977,7 +1981,6 @@ static int user_mem_abort(const struct kvm_s2_fault_desc *s2fd)
> bool write_fault = kvm_is_write_fault(s2fd->vcpu);
> bool logging_active = memslot_is_logging(s2fd->memslot);
> struct kvm_s2_fault fault = {
> - .fault_is_perm = perm_fault,
> .logging_active = logging_active,
> .force_pte = logging_active,
> .prot = KVM_PGTABLE_PROT_R,
^ permalink raw reply
* Re: [PATCH v4] net: stmmac: skip VLAN restore when VLAN hash ops are missing
From: patchwork-bot+netdevbpf @ 2026-04-01 3:20 UTC (permalink / raw)
To: Michal Piekos
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, mcoquelin.stm32,
alexandre.torgue, ovidiu.panait.rb, netdev, linux-stm32,
linux-arm-kernel, linux-kernel
In-Reply-To: <20260328-vlan-restore-error-v4-1-f88624c530dc@mmpsystems.pl>
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Sat, 28 Mar 2026 09:55:51 +0100 you wrote:
> stmmac_vlan_restore() unconditionally calls stmmac_vlan_update() when
> NETIF_F_VLAN_FEATURES is set. On platforms where priv->hw->vlan (or
> ->update_vlan_hash) is not provided, stmmac_update_vlan_hash() returns
> -EINVAL via stmmac_do_void_callback(), resulting in a spurious
> "Failed to restore VLANs" error even when no VLAN filtering is in use.
>
> Remove not needed comment.
> Remove not used return value from stmmac_vlan_restore().
>
> [...]
Here is the summary with links:
- [v4] net: stmmac: skip VLAN restore when VLAN hash ops are missing
https://git.kernel.org/netdev/net/c/48b3cd69265f
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH v2 18/30] KVM: arm64: Constrain fault_granule to kvm_s2_fault_map()
From: Anshuman Khandual @ 2026-04-01 3:26 UTC (permalink / raw)
To: Marc Zyngier, kvmarm, linux-arm-kernel, kvm
Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
Fuad Tabba, Will Deacon, Quentin Perret
In-Reply-To: <20260327113618.4051534-19-maz@kernel.org>
On 27/03/26 5:06 PM, Marc Zyngier wrote:
> The notion of fault_granule is specific to kvm_s2_fault_map(), and
> is unused anywhere else.
>
> Move this variable locally, removing it from kvm_s2_fault.
>
> Tested-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> arch/arm64/kvm/mmu.c | 17 +++++++++--------
> 1 file changed, 9 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 1e0d93d6d265a..981c04a74ab7a 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1724,7 +1724,6 @@ struct kvm_s2_fault {
> bool logging_active;
> bool force_pte;
> long vma_pagesize;
> - long fault_granule;
> enum kvm_pgtable_prot prot;
> struct page *page;
> vm_flags_t vm_flags;
> @@ -1908,9 +1907,9 @@ static phys_addr_t get_ipa(const struct kvm_s2_fault *fault)
> static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
> struct kvm_s2_fault *fault, void *memcache)
> {
> - bool fault_is_perm = kvm_s2_fault_is_perm(s2fd);
> struct kvm *kvm = s2fd->vcpu->kvm;
> struct kvm_pgtable *pgt;
> + long perm_fault_granule;
> int ret;
> enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_SHARED;
>
> @@ -1920,14 +1919,17 @@ static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
> if (mmu_invalidate_retry(kvm, fault->mmu_seq))
> goto out_unlock;
>
> + perm_fault_granule = (kvm_s2_fault_is_perm(s2fd) ?
> + kvm_vcpu_trap_get_perm_fault_granule(s2fd->vcpu) : 0);
> +
> /*
> * If we are not forced to use page mapping, check if we are
> * backed by a THP and thus use block mapping if possible.
> */
> if (fault->vma_pagesize == PAGE_SIZE &&
> !(fault->force_pte || fault->s2_force_noncacheable)) {
> - if (fault_is_perm && fault->fault_granule > PAGE_SIZE) {
> - fault->vma_pagesize = fault->fault_granule;
> + if (perm_fault_granule > PAGE_SIZE) {
> + fault->vma_pagesize = perm_fault_granule;
> } else {
> fault->vma_pagesize = transparent_hugepage_adjust(kvm, s2fd->memslot,
> s2fd->hva, &fault->pfn,
> @@ -1940,15 +1942,15 @@ static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
> }
> }
>
> - if (!fault_is_perm && !fault->s2_force_noncacheable && kvm_has_mte(kvm))
> + if (!perm_fault_granule && !fault->s2_force_noncacheable && kvm_has_mte(kvm))
> sanitise_mte_tags(kvm, fault->pfn, fault->vma_pagesize);
>
> /*
> * Under the premise of getting a FSC_PERM fault, we just need to relax
> - * permissions only if fault->vma_pagesize equals fault->fault_granule. Otherwise,
> + * permissions only if vma_pagesize equals perm_fault_granule. Otherwise,
> * kvm_pgtable_stage2_map() should be called to change block size.
> */
> - if (fault_is_perm && fault->vma_pagesize == fault->fault_granule) {
> + if (fault->vma_pagesize == perm_fault_granule) {
> /*
> * Drop the SW bits in favour of those stored in the
> * PTE, which will be preserved.
> @@ -1984,7 +1986,6 @@ static int user_mem_abort(const struct kvm_s2_fault_desc *s2fd)
> .logging_active = logging_active,
> .force_pte = logging_active,
> .prot = KVM_PGTABLE_PROT_R,
> - .fault_granule = perm_fault ? kvm_vcpu_trap_get_perm_fault_granule(s2fd->vcpu) : 0,
> .write_fault = write_fault,
> .exec_fault = kvm_vcpu_trap_is_exec_fault(s2fd->vcpu),
> .topup_memcache = !perm_fault || (logging_active && write_fault),
^ permalink raw reply
* Re: [PATCH v2 19/30] KVM: arm64: Kill write_fault from kvm_s2_fault
From: Anshuman Khandual @ 2026-04-01 3:31 UTC (permalink / raw)
To: Marc Zyngier, kvmarm, linux-arm-kernel, kvm
Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
Fuad Tabba, Will Deacon, Quentin Perret
In-Reply-To: <20260327113618.4051534-20-maz@kernel.org>
On 27/03/26 5:06 PM, Marc Zyngier wrote:
> We already have kvm_is_write_fault() as a predicate indicating
> a S2 fault on a write, and we're better off just using that instead
> of duplicating the state.
>
> Tested-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
> arch/arm64/kvm/mmu.c | 11 +++--------
> 1 file changed, 3 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 981c04a74ab7a..7dab0c3faa5bf 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1711,7 +1711,6 @@ static short kvm_s2_resolve_vma_size(const struct kvm_s2_fault_desc *s2fd,
> }
>
> struct kvm_s2_fault {
> - bool write_fault;
> bool exec_fault;
> bool writable;
> bool topup_memcache;
> @@ -1799,7 +1798,7 @@ static int kvm_s2_fault_pin_pfn(const struct kvm_s2_fault_desc *s2fd,
> return ret;
>
> fault->pfn = __kvm_faultin_pfn(s2fd->memslot, get_canonical_gfn(s2fd, fault),
> - fault->write_fault ? FOLL_WRITE : 0,
> + kvm_is_write_fault(s2fd->vcpu) ? FOLL_WRITE : 0,
> &fault->writable, &fault->page);
> if (unlikely(is_error_noslot_pfn(fault->pfn))) {
> if (fault->pfn == KVM_PFN_ERR_HWPOISON) {
> @@ -1850,7 +1849,7 @@ static int kvm_s2_fault_compute_prot(const struct kvm_s2_fault_desc *s2fd,
> */
> fault->s2_force_noncacheable = true;
> }
> - } else if (fault->logging_active && !fault->write_fault) {
> + } else if (fault->logging_active && !kvm_is_write_fault(s2fd->vcpu)) {
> /*
> * Only actually map the page as writable if this was a write
> * fault.
> @@ -1980,21 +1979,17 @@ static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
> static int user_mem_abort(const struct kvm_s2_fault_desc *s2fd)
> {
> bool perm_fault = kvm_vcpu_trap_is_permission_fault(s2fd->vcpu);
> - bool write_fault = kvm_is_write_fault(s2fd->vcpu);
> bool logging_active = memslot_is_logging(s2fd->memslot);
> struct kvm_s2_fault fault = {
> .logging_active = logging_active,
> .force_pte = logging_active,
> .prot = KVM_PGTABLE_PROT_R,
> - .write_fault = write_fault,
> .exec_fault = kvm_vcpu_trap_is_exec_fault(s2fd->vcpu),
> - .topup_memcache = !perm_fault || (logging_active && write_fault),
> + .topup_memcache = !perm_fault || (logging_active && kvm_is_write_fault(s2fd->vcpu)),
> };
> void *memcache;
> int ret;
>
> - VM_WARN_ON_ONCE(fault.write_fault && fault.exec_fault);
> -
> /*
> * Permission faults just need to update the existing leaf entry,
> * and so normally don't require allocations from the memcache. The
^ permalink raw reply
* Re: [PATCH v2 20/30] KVM: arm64: Kill exec_fault from kvm_s2_fault
From: Anshuman Khandual @ 2026-04-01 3:35 UTC (permalink / raw)
To: Marc Zyngier, kvmarm, linux-arm-kernel, kvm
Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
Fuad Tabba, Will Deacon, Quentin Perret
In-Reply-To: <20260327113618.4051534-21-maz@kernel.org>
On 27/03/26 5:06 PM, Marc Zyngier wrote:
> Similarly to write_fault, exec_fault can be advantageously replaced
> by the kvm_vcpu_trap_is_exec_fault() predicate where needed.
>
> Another one bites the dust...
>
> Tested-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
> arch/arm64/kvm/mmu.c | 6 ++----
> 1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 7dab0c3faa5bf..e8bda71e862b2 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1711,7 +1711,6 @@ static short kvm_s2_resolve_vma_size(const struct kvm_s2_fault_desc *s2fd,
> }
>
> struct kvm_s2_fault {
> - bool exec_fault;
> bool writable;
> bool topup_memcache;
> bool mte_allowed;
> @@ -1857,7 +1856,7 @@ static int kvm_s2_fault_compute_prot(const struct kvm_s2_fault_desc *s2fd,
> fault->writable = false;
> }
>
> - if (fault->exec_fault && fault->s2_force_noncacheable)
> + if (kvm_vcpu_trap_is_exec_fault(s2fd->vcpu) && fault->s2_force_noncacheable)
> return -ENOEXEC;
>
> /*
> @@ -1877,7 +1876,7 @@ static int kvm_s2_fault_compute_prot(const struct kvm_s2_fault_desc *s2fd,
> if (fault->writable)
> fault->prot |= KVM_PGTABLE_PROT_W;
>
> - if (fault->exec_fault)
> + if (kvm_vcpu_trap_is_exec_fault(s2fd->vcpu))
> fault->prot |= KVM_PGTABLE_PROT_X;
>
> if (fault->s2_force_noncacheable)
> @@ -1984,7 +1983,6 @@ static int user_mem_abort(const struct kvm_s2_fault_desc *s2fd)
> .logging_active = logging_active,
> .force_pte = logging_active,
> .prot = KVM_PGTABLE_PROT_R,
> - .exec_fault = kvm_vcpu_trap_is_exec_fault(s2fd->vcpu),
> .topup_memcache = !perm_fault || (logging_active && kvm_is_write_fault(s2fd->vcpu)),
> };
> void *memcache;
^ permalink raw reply
* [PATCH net v4 0/2] stmmac crash/stall fixes when under memory pressure
From: Sam Edwards @ 2026-04-01 4:19 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Maxime Coquelin, Alexandre Torgue, Russell King (Oracle),
Maxime Chevallier, Ovidiu Panait, Vladimir Oltean, Baruch Siach,
Serge Semin, Giuseppe Cavallaro, netdev, linux-stm32,
linux-arm-kernel, linux-kernel, Sam Edwards
Hi netdev,
This is v4 of my series containing a pair of bugfixes for the stmmac driver's
receive pipeline. These issues occur when stmmac_rx_refill() does not (fully)
succeed, which happens more frequently when free memory is low.
The first patch closes Bugzilla bug #221010 [1], where stmmac_rx() can circle
around to a still-dirty descriptor (with a NULL buffer pointer), mistake it for
a filled descriptor (due to OWN=0), and attempt to dereference the buffer.
In testing that patch, I discovered a second issue: starvation of available RX
buffers causes the NIC to stop sending interrupts; if the driver stops polling,
it will wait indefinitely for an interrupt that will never come. (Note: the
first patch makes this issue more prominent -- mostly because it lets the
system survive long enough to exhibit it -- but doesn't *cause* it.) The second
patch addresses that problem as well.
Both patches are minimal, appropriate for stable, and designated to `net`. My
focus is on small, obviously-correct, easy-to-explain changes: I'll follow up
with another patch/series (something like [2]) for `net-next` that fixes the
ring in a more robust way.
The tx and zc paths seem to have similar low-memory bugs, to be addressed in
separate series.
Regards,
Sam
---
[1] https://bugzilla.kernel.org/show_bug.cgi?id=221010
[2] https://lore.kernel.org/netdev/20260316021009.262358-4-CFSworks@gmail.com/
v4:
- Changed patch 2 to tolerate dirty stragglers up to a critical threshold (the
same threshold tolerated by the zero-copy path), to avoid nuisance looping
during OOM conditions (thanks Jakub)
v3: https://lore.kernel.org/netdev/20260328192503.520689-1-CFSworks@gmail.com/T/
- Rebased on latest net/main
- Changed patch 2 to require that stmmac_rx_refill() *fully* succeeds before
exiting polling, to reduce the chance of rx drops.
- DID NOT use the CIRC_SPACE() macro as suggested by Russell: I fear that the
perspective shift (first think of the dirty descriptors as the "work" that
refill "consumes" -- therefore the "space" is how much stmmac_rx() may loop)
is too counterintuitive for a stable fix, but I'll do it in v4 if reviewers
insist.
- Updated the recipients for the series, which was invalidated in v2 due to the
`Fixes:`
v2: https://lore.kernel.org/netdev/20260319184031.8596-1-CFSworks@gmail.com/T/
- Completely rewrote the commit message of patch 1, now assuming the reader is
generally familiar with DMA but wholly unfamiliar with the stmmac device
(thanks Jakub!)
- Added missing `Fixes:` to patch 2
- Moved patch 2's `int budget = limit;` decl per the reverse-xmas-tree rule
- Dropped patch 3: this was a code improvement not appropriate for stable
- Generated the series with --subject-prefix='PATCH net'
v1: https://lore.kernel.org/netdev/20260316021009.262358-1-CFSworks@gmail.com/
Sam Edwards (2):
net: stmmac: Prevent NULL deref when RX memory exhausted
net: stmmac: Prevent indefinite RX stall on buffer exhaustion
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
--
2.52.0
^ permalink raw reply
* [PATCH net v4 1/2] net: stmmac: Prevent NULL deref when RX memory exhausted
From: Sam Edwards @ 2026-04-01 4:19 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Maxime Coquelin, Alexandre Torgue, Russell King (Oracle),
Maxime Chevallier, Ovidiu Panait, Vladimir Oltean, Baruch Siach,
Serge Semin, Giuseppe Cavallaro, netdev, linux-stm32,
linux-arm-kernel, linux-kernel, Sam Edwards, stable
In-Reply-To: <20260401041929.12392-1-CFSworks@gmail.com>
The CPU receives frames from the MAC through conventional DMA: the CPU
allocates buffers for the MAC, then the MAC fills them and returns
ownership to the CPU. For each hardware RX queue, the CPU and MAC
coordinate through a shared ring array of DMA descriptors: one
descriptor per DMA buffer. Each descriptor includes the buffer's
physical address and a status flag ("OWN") indicating which side owns
the buffer: OWN=0 for CPU, OWN=1 for MAC. The CPU is only allowed to set
the flag and the MAC is only allowed to clear it, and both must move
through the ring in sequence: thus the ring is used for both
"submissions" and "completions."
In the stmmac driver, stmmac_rx() bookmarks its position in the ring
with the `cur_rx` index. The main receive loop in that function checks
for rx_descs[cur_rx].own=0, gives the corresponding buffer to the
network stack (NULLing the pointer), and increments `cur_rx` modulo the
ring size. After the loop exits, stmmac_rx_refill(), which bookmarks its
position with `dirty_rx`, allocates fresh buffers and rearms the
descriptors (setting OWN=1). If it fails any allocation, it simply stops
early (leaving OWN=0) and will retry where it left off when next called.
This means descriptors have a three-stage lifecycle (terms my own):
- `empty` (OWN=1, buffer valid)
- `full` (OWN=0, buffer valid and populated)
- `dirty` (OWN=0, buffer NULL)
But because stmmac_rx() only checks OWN, it confuses `full`/`dirty`. In
the past (see 'Fixes:'), there was a bug where the loop could cycle
`cur_rx` all the way back to the first descriptor it dirtied, resulting
in a NULL dereference when mistaken for `full`. The aforementioned
commit resolved that *specific* failure by capping the loop's iteration
limit at `dma_rx_size - 1`, but this is only a partial fix: if the
previous stmmac_rx_refill() didn't complete, then there are leftover
`dirty` descriptors that the loop might encounter without needing to
cycle fully around. The current code therefore panics (see 'Closes:')
when stmmac_rx_refill() is memory-starved long enough for `cur_rx` to
catch up to `dirty_rx`.
Fix this by further tightening the clamp from `dma_rx_size - 1` to
`dma_rx_size - stmmac_rx_dirty() - 1`, subtracting any remnant dirty
entries and limiting the loop so that `cur_rx` cannot catch back up to
`dirty_rx`. This carries no risk of arithmetic underflow: since the
maximum possible return value of stmmac_rx_dirty() is `dma_rx_size - 1`,
the worst the clamp can do is prevent the loop from running at all.
Fixes: b6cb4541853c7 ("net: stmmac: avoid rx queue overrun")
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221010
Cc: stable@vger.kernel.org
Signed-off-by: Sam Edwards <CFSworks@gmail.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 13d3cac056be..fc11f75f7dc0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -5609,7 +5609,8 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
dma_dir = page_pool_get_dma_dir(rx_q->page_pool);
bufsz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE;
- limit = min(priv->dma_conf.dma_rx_size - 1, (unsigned int)limit);
+ limit = min(priv->dma_conf.dma_rx_size - stmmac_rx_dirty(priv, queue) - 1,
+ (unsigned int)limit);
if (netif_msg_rx_status(priv)) {
void *rx_head;
--
2.52.0
^ permalink raw reply related
* [PATCH net v4 2/2] net: stmmac: Prevent indefinite RX stall on buffer exhaustion
From: Sam Edwards @ 2026-04-01 4:19 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Maxime Coquelin, Alexandre Torgue, Russell King (Oracle),
Maxime Chevallier, Ovidiu Panait, Vladimir Oltean, Baruch Siach,
Serge Semin, Giuseppe Cavallaro, netdev, linux-stm32,
linux-arm-kernel, linux-kernel, Sam Edwards, stable
In-Reply-To: <20260401041929.12392-1-CFSworks@gmail.com>
The stmmac driver handles interrupts in the usual NAPI way: an interrupt
arrives, the NAPI instance is scheduled and interrupts are masked, and
the actual work occurs in the NAPI polling function. Once no further
work remains, interrupts are unmasked and the NAPI instance is put to
sleep to await a future interrupt. In the receive case, the MAC only
sends the interrupt when a DMA operation completes; thus the driver must
make sure a usable RX DMA descriptor exists before expecting a future
interrupt.
The main receive loop in stmmac_rx() exits under one of 3 conditions:
1) It encounters a DMA descriptor with OWN=1, indicating that no further
pending data exists. The MAC will use this descriptor for the next
RX DMA operation, so the driver can expect a future interrupt.
2) It exhausts the NAPI budget. In this case, the driver doesn't know
whether the MAC has any usable DMA descriptors. But when the driver
consumes its full budget, that signals NAPI to keep polling, so the
question is moot.
3) It runs out of (non-dirty) descriptors in the RX ring. In this case,
the MAC will only have a usable descriptor if stmmac_rx_refill()
succeeds (at least partially).
Currently, stmmac_rx() lacks any check against scenario #3 and
stmmac_rx_refill() failing: it will stop NAPI polling and unmask
interrupts to await an interrupt that will never arrive, stalling the
receive pipeline indefinitely.
Also: even if not all descriptors are dirty, letting them accumulate
risks dropping frames in the next incoming traffic burst, if large
enough to exhaust the remaining valid ones.
Fix both of these problems by checking stmmac_rx_dirty() before return:
Use the same threshold as the zero-copy path (STMMAC_RX_FILL_BATCH) for
an unacceptably high number of neglected dirties, and tell NAPI to keep
polling (i.e. return budget) when that threshold is met.
Fixes: 47dd7a540b8a ("net: add support for STMicroelectronics Ethernet controllers.")
Cc: stable@vger.kernel.org
Signed-off-by: Sam Edwards <CFSworks@gmail.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index fc11f75f7dc0..6822ca27cb0f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -5604,6 +5604,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
unsigned int desc_size;
struct sk_buff *skb = NULL;
struct stmmac_xdp_buff ctx;
+ int budget = limit;
int xdp_status = 0;
int bufsz;
@@ -5870,6 +5871,14 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
priv->xstats.rx_dropped += rx_dropped;
priv->xstats.rx_errors += rx_errors;
+ /* stmmac_rx_refill() may fail, leaving some dirty entries behind.
+ * A few is OK, but if it gets out of hand, we risk dropping frames
+ * in the next traffic burst; in the worst case (100% dirty) we won't
+ * even receive any future "DMA completed" interrupts.
+ */
+ if (unlikely(stmmac_rx_dirty(priv, queue) >= STMMAC_RX_FILL_BATCH))
+ return budget;
+
return count;
}
--
2.52.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox