Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v5 3/3] arm64,ppc64le/kdump: pass dm-crypt keys to kdump kernel
From: Coiby Xu @ 2026-04-02  1:44 UTC (permalink / raw)
  To: Rob Herring
  Cc: kexec, linux-arm-kernel, linuxppc-dev, devicetree,
	Arnaud Lefebvre, Baoquan he, Dave Young, Kairui Song, Pingfan Liu,
	Andrew Morton, Krzysztof Kozlowski, Thomas Staudt, Sourabh Jain,
	Will Deacon, Christophe Leroy (CS GROUP), Catalin Marinas,
	Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
	Saravana Kannan, open list
In-Reply-To: <CAL_Jsq+0w2hGN=Loy=ucHbZcdnn+ty3x9qS4WVX0Vj+g19tfpg@mail.gmail.com>

On Mon, Mar 30, 2026 at 06:44:15AM -0500, Rob Herring wrote:
>On Wed, Feb 25, 2026 at 12:04 AM Coiby Xu <coxu@redhat.com> wrote:
>>
>> CONFIG_CRASH_DM_CRYPT has been introduced to support LUKS-encrypted
>> device dump target by addressing two challenges [1],
>>  - Kdump kernel may not be able to decrypt the LUKS partition. For some
>>    machines, a system administrator may not have a chance to enter the
>>    password to decrypt the device in kdump initramfs after the 1st kernel
>>    crashes
>>
>>  - LUKS2 by default use the memory-hard Argon2 key derivation function
>>    which is quite memory-consuming compared to the limited memory reserved
>>    for kdump.
>>
>> To also enable this feature for ARM64 and PowerPC, the missing piece is
>> to let the kdump kernel know where to find the dm-crypt keys which are
>> randomly stored in memory reserved for kdump. Introduce a new device
>> tree property dmcryptkeys [2] as similar to elfcorehdr to pass the
>> memory address of the stored info of dm-crypt keys to the kdump kernel.
>> Since this property is only needed by the kdump kernel, it won't be
>> exposed to user space.
>>
>> [1] https://lore.kernel.org/all/20250502011246.99238-1-coxu@redhat.com/
>> [2] https://github.com/devicetree-org/dt-schema/pull/181
>>
>> Cc: Arnaud Lefebvre <arnaud.lefebvre@clever-cloud.com>
>> Cc: Baoquan he <bhe@redhat.com>
>> Cc: Dave Young <dyoung@redhat.com>
>> Cc: Kairui Song <ryncsn@gmail.com>
>> Cc: Pingfan Liu <kernelfans@gmail.com>
>> Cc: Andrew Morton <akpm@linux-foundation.org>
>> Cc: Krzysztof Kozlowski <krzk@kernel.org>
>> Cc: Rob Herring <robh@kernel.org>
>> Cc: Thomas Staudt <tstaudt@de.ibm.com>
>> Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
>> Cc: Will Deacon <will@kernel.org>
>> Cc: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
>> Signed-off-by: Coiby Xu <coxu@redhat.com>
>> ---
>>  arch/arm64/kernel/machine_kexec_file.c |  4 ++++
>>  arch/powerpc/kexec/elf_64.c            |  4 ++++
>>  drivers/of/fdt.c                       | 21 +++++++++++++++++++++
>>  drivers/of/kexec.c                     | 19 +++++++++++++++++++
>>  4 files changed, 48 insertions(+)
>
>Acked-by: Rob Herring (Arm) <robh@kernel.org>

Hi Rob,

Thanks for acknowledging this device tree patch and also merging the
dt-schema PR!

-- 
Best regards,
Coiby



^ permalink raw reply

* Re: [PATCH v5 1/3] crash_dump/dm-crypt: Don't print in arch-specific code
From: Coiby Xu @ 2026-04-02  1:46 UTC (permalink / raw)
  To: Baoquan He
  Cc: kexec, linux-arm-kernel, linuxppc-dev, devicetree, Will Deacon,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin,
	Andrew Morton, Vivek Goyal, Dave Young,
	open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)
In-Reply-To: <actzxO1p6OlmK2gp@fedora>

On Tue, Mar 31, 2026 at 03:12:04PM +0800, Baoquan He wrote:
>On 02/25/26 at 02:03pm, Coiby Xu wrote:
>> When the vmcore dumping target is not a LUKS-encrypted target, it's
>> expected that there is no dm-crypt key thus no need to return -ENOENT.
>> Also print more logs in crash_load_dm_crypt_keys. The benefit is
>> arch-specific code can be more succinct.
>>
>> Suggested-by: Will Deacon <will@kernel.org>
>> Signed-off-by: Coiby Xu <coxu@redhat.com>
>> ---
>>  arch/x86/kernel/kexec-bzimage64.c | 6 +-----
>>  kernel/crash_dump_dm_crypt.c      | 7 +++++--
>>  2 files changed, 6 insertions(+), 7 deletions(-)
>
>Acked-by: Baoquan He <bhe@redhat.com>

Thank Baoquan for ack'ing the kexec/kdump part of this patch set!

-- 
Best regards,
Coiby



^ permalink raw reply

* Re: [PATCH] stmmac: cleanup dead dependencies on STMMAC_PLATFORM and STMMAC_ETH in Kconfig
From: Jakub Kicinski @ 2026-04-02  1:58 UTC (permalink / raw)
  To: Julian Braha
  Cc: manabian, davem, peppe.cavallaro, alexandre.torgue,
	mcoquelin.stm32, netdev, linux-arm-kernel, linux-kernel
In-Reply-To: <20260331125817.117091-1-julianbraha@gmail.com>

On Tue, 31 Mar 2026 13:58:17 +0100 Julian Braha wrote:
> @@ -53,7 +51,6 @@ config DWMAC_DWC_QOS_ETH
>  
>  config DWMAC_GENERIC
>  	tristate "Generic driver for DWMAC"
> -	default STMMAC_PLATFORM
>  	help

This is a default not depends.

As much as I'd love to make stmmac default to y this will probably
break boot for some people..
-- 
pw-bot: cr


^ permalink raw reply

* Re: [PATCH 0/5] Exynos850 APM-to-AP mailbox support
From: Alexey Klimov @ 2026-04-02  2:19 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Alexey Klimov
  Cc: Sylwester Nawrocki, Chanwoo Choi, Alim Akhtar, Sam Protsenko,
	Michael Turquette, Stephen Boyd, Rob Herring, Conor Dooley,
	Tudor Ambarus, Jassi Brar, Krzysztof Kozlowski, Peter Griffin,
	linux-samsung-soc, linux-arm-kernel, linux-clk, devicetree,
	linux-kernel
In-Reply-To: <20260321-beautiful-garnet-magpie-de4fbd@quoll>

On Sat Mar 21, 2026 at 10:44 AM GMT, Krzysztof Kozlowski wrote:
> On Fri, Mar 20, 2026 at 09:15:12PM +0000, Alexey Klimov wrote:
>> Hi all,
>> 
>> This patch series introduces support for the APM-to-AP mailbox on the 
>> Exynos850 SoC. This mailbox is required for communicating with the APM 
>> co-processor using ACPM.
>> 
>> The Exynos850 mailbox operates similarly to the existing gs101 
>> implementation, but the register offsets and IRQ mask bits differ. 
>> This series abstracts these differences into platform-specific data 
>> structures matched via the device tree.
>> 
>> Also, it requires APM-to-AP mailbox clock in CMU_APM block.
>> 
>> In theory this can be split into two series with correct dependecies:
>> device tree node requires clock changes to be merged. The suggestion
>> is to let this go through Samsung SoC tree with corresponding acks
>> if it is okay.
>
> I don't understand why this cannot be split into two seris
> *practically*. What is exactly the dependency between mailbox and DTS,
> that it had to be combined here?

Do you suggest to send 3 single patches with proper dependencies
description? DT bindings change first, then mailbox change that specifically
depends on dt-bindings change and then dts update (which will depend on both)?

I thought that mbox driver change depends implicitly on bindings update?

Best regards,
Alexey


^ permalink raw reply

* [PATCH v2 0/3] Exynos850 APM-to-AP mailbox support
From: Alexey Klimov @ 2026-04-02  2:20 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
	Alim Akhtar, Sam Protsenko, Michael Turquette, Stephen Boyd,
	Rob Herring, Conor Dooley, Tudor Ambarus, Jassi Brar
  Cc: Krzysztof Kozlowski, Peter Griffin, linux-samsung-soc,
	linux-arm-kernel, linux-clk, devicetree, linux-kernel,
	Alexey Klimov

This patch series introduces support for the APM-to-AP mailbox on the 
Exynos850 SoC. This mailbox is required for communicating with the APM 
co-processor using ACPM.

The Exynos850 mailbox operates similarly to the existing gs101 
implementation, but the register offsets and IRQ mask bits differ. 
This series abstracts these differences into platform-specific data 
structures matched via the device tree.

Also, it requires APM-to-AP mailbox clock in CMU_APM block. These
were marged already (thanks Krzysztof!) so they are dropped from
this v2.

Please also advice if mailbox change should be split out as a separate
patch.

Will be appreciated if it can be tested on gs101 to make sure that I
didn't break anything, I don't have dev gs101 devices.

Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
---
Changes in v2:
- dropped clock patches (they seem to be merged);
- patch 3: updated commit description mentioning that
  exynos850 is not compatible to gs101 mbox (as suggested by Krzysztof);
- fixed comment description for struct exynos_mbox_driver_data
  (reported by kernel test robot <lkp@intel.com>);
- Link to v1: https://lore.kernel.org/r/20260320-exynos850-ap2apm-mailbox-v1-0-983eb3f296fc@linaro.org

---
Alexey Klimov (3):
      dt-bindings: mailbox: google,gs101-mbox: Add samsung,exynos850-mbox
      mailbox: exynos: Add support for Exynos850 mailbox
      arm64: dts: exynos850: Add ap2apm mailbox

 .../bindings/mailbox/google,gs101-mbox.yaml        |  4 +-
 arch/arm64/boot/dts/exynos/exynos850.dtsi          |  9 +++
 drivers/mailbox/exynos-mailbox.c                   | 67 +++++++++++++++++++++-
 3 files changed, 76 insertions(+), 4 deletions(-)
---
base-commit: bd0f139e5fc11182777b81cefc3893ea508544ec
change-id: 20260320-exynos850-ap2apm-mailbox-cff0c8d69898

Best regards,
-- 
Alexey Klimov <alexey.klimov@linaro.org>



^ permalink raw reply

* [PATCH v2 1/3] dt-bindings: mailbox: google,gs101-mbox: Add samsung,exynos850-mbox
From: Alexey Klimov @ 2026-04-02  2:20 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
	Alim Akhtar, Sam Protsenko, Michael Turquette, Stephen Boyd,
	Rob Herring, Conor Dooley, Tudor Ambarus, Jassi Brar
  Cc: Krzysztof Kozlowski, Peter Griffin, linux-samsung-soc,
	linux-arm-kernel, linux-clk, devicetree, linux-kernel,
	Alexey Klimov
In-Reply-To: <20260402-exynos850-ap2apm-mailbox-v2-0-ca5ffdff99d4@linaro.org>

Document support for a mailbox present on Exynos850-based platforms.
The registers offsets are different from gs101 mailbox, but the
workflow is similar, hence new compatible.

Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
---
 Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml b/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
index e249db4c1fbc..c109c1f7af24 100644
--- a/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
+++ b/Documentation/devicetree/bindings/mailbox/google,gs101-mbox.yaml
@@ -20,7 +20,9 @@ description:
 
 properties:
   compatible:
-    const: google,gs101-mbox
+    enum:
+      - google,gs101-mbox
+      - samsung,exynos850-mbox
 
   reg:
     maxItems: 1

-- 
2.51.0



^ permalink raw reply related

* [PATCH v2 2/3] mailbox: exynos: Add support for Exynos850 mailbox
From: Alexey Klimov @ 2026-04-02  2:20 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
	Alim Akhtar, Sam Protsenko, Michael Turquette, Stephen Boyd,
	Rob Herring, Conor Dooley, Tudor Ambarus, Jassi Brar
  Cc: Krzysztof Kozlowski, Peter Griffin, linux-samsung-soc,
	linux-arm-kernel, linux-clk, devicetree, linux-kernel,
	Alexey Klimov
In-Reply-To: <20260402-exynos850-ap2apm-mailbox-v2-0-ca5ffdff99d4@linaro.org>

Exynos850-based platforms support ACPM and has similar workflow
of communicating with ACPM via mailbox, however mailbox controller
registers are located at different offsets and writes/reads could be
different. To distinguish between such different behaviours,
the registers offsets for Exynos850 and the platform-specific data
structs are introduced and configuration is described in such structs
for gs101 and exynos850 based SoCs. Probe routine now selects the
corresponding platform-specific data via device_get_match_data().

Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
---
 drivers/mailbox/exynos-mailbox.c | 67 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 64 insertions(+), 3 deletions(-)

diff --git a/drivers/mailbox/exynos-mailbox.c b/drivers/mailbox/exynos-mailbox.c
index d2355b128ba4..f9c59c07558a 100644
--- a/drivers/mailbox/exynos-mailbox.c
+++ b/drivers/mailbox/exynos-mailbox.c
@@ -31,14 +31,61 @@
 
 #define EXYNOS_MBOX_CHAN_COUNT		HWEIGHT32(EXYNOS_MBOX_INTGR1_MASK)
 
+#define EXYNOS850_MBOX_MCUCTRL		0x0	/* Mailbox Control Register		*/
+#define EXYNOS850_MBOX_INTGR0		0x8	/* Interrupt Generation Register 0	*/
+#define EXYNOS850_MBOX_INTCR0		0x0C	/* Interrupt Clear Register 0		*/
+#define EXYNOS850_MBOX_INTMR0		0x10	/* Interrupt Mask Register 0		*/
+#define EXYNOS850_MBOX_INTSR0		0x14	/* Interrupt Status Register 0		*/
+#define EXYNOS850_MBOX_INTMSR0		0x18	/* Interrupt Mask Status Register 0	*/
+#define EXYNOS850_MBOX_INTGR1		0x1C	/* Interrupt Generation Register 1	*/
+#define EXYNOS850_MBOX_INTMR1		0x24	/* Interrupt Mask Register 1		*/
+#define EXYNOS850_MBOX_INTSR1		0x28	/* Interrupt Status Register 1		*/
+#define EXYNOS850_MBOX_INTMSR1		0x2C	/* Interrupt Mask Status Register 1	*/
+#define EXYNOS850_MBOX_VERSION		0x70
+
+#define EXYNOS850_MBOX_INTMR1_MASK	GENMASK(15, 0)
+
+/**
+ * struct exynos_mbox_driver_data - platform-specific mailbox configuration.
+ * @irq_doorbell_offset:	offset to the IRQ generation register, doorbell
+ *				to APM co-processor.
+ * @irq_doorbell_shift:		shift to apply to the value written to IRQ
+ *				generation register.
+ * @irq_mask_offset:		offset to the IRQ mask register.
+ * @irq_mask_value:		value to right to the mask register to mask out
+ *				all interrupts.
+ */
+struct exynos_mbox_driver_data {
+	u16 irq_doorbell_offset;
+	u16 irq_doorbell_shift;
+	u16 irq_mask_offset;
+	u16 irq_mask_value;
+};
+
 /**
  * struct exynos_mbox - driver's private data.
  * @regs:	mailbox registers base address.
  * @mbox:	pointer to the mailbox controller.
+ * @data:	pointer to driver platform-specific data.
  */
 struct exynos_mbox {
 	void __iomem *regs;
 	struct mbox_controller *mbox;
+	const struct exynos_mbox_driver_data *data;
+};
+
+static const struct exynos_mbox_driver_data exynos850_mbox_data = {
+	.irq_doorbell_offset = EXYNOS850_MBOX_INTGR0,
+	.irq_doorbell_shift = 16,
+	.irq_mask_offset = EXYNOS850_MBOX_INTMR1,
+	.irq_mask_value = EXYNOS850_MBOX_INTMR1_MASK,
+};
+
+static const struct exynos_mbox_driver_data exynos_gs101_mbox_data = {
+	.irq_doorbell_offset = EXYNOS_MBOX_INTGR1,
+	.irq_doorbell_shift = 0,
+	.irq_mask_offset = EXYNOS_MBOX_INTMR0,
+	.irq_mask_value = EXYNOS_MBOX_INTMR0_MASK,
 };
 
 static int exynos_mbox_send_data(struct mbox_chan *chan, void *data)
@@ -57,7 +104,8 @@ static int exynos_mbox_send_data(struct mbox_chan *chan, void *data)
 		return -EINVAL;
 	}
 
-	writel(BIT(msg->chan_id), exynos_mbox->regs + EXYNOS_MBOX_INTGR1);
+	writel(BIT(msg->chan_id) << exynos_mbox->data->irq_doorbell_shift,
+	       exynos_mbox->regs + exynos_mbox->data->irq_doorbell_offset);
 
 	return 0;
 }
@@ -87,13 +135,21 @@ static struct mbox_chan *exynos_mbox_of_xlate(struct mbox_controller *mbox,
 }
 
 static const struct of_device_id exynos_mbox_match[] = {
-	{ .compatible = "google,gs101-mbox" },
+	{
+		.compatible = "google,gs101-mbox",
+		.data = &exynos_gs101_mbox_data
+	},
+	{
+		.compatible = "samsung,exynos850-mbox",
+		.data = &exynos850_mbox_data
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, exynos_mbox_match);
 
 static int exynos_mbox_probe(struct platform_device *pdev)
 {
+	const struct exynos_mbox_driver_data *data;
 	struct device *dev = &pdev->dev;
 	struct exynos_mbox *exynos_mbox;
 	struct mbox_controller *mbox;
@@ -122,6 +178,11 @@ static int exynos_mbox_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(pclk),
 				     "Failed to enable clock.\n");
 
+	data = device_get_match_data(&pdev->dev);
+	if (!data)
+		return -ENODEV;
+
+	exynos_mbox->data = data;
 	mbox->num_chans = EXYNOS_MBOX_CHAN_COUNT;
 	mbox->chans = chans;
 	mbox->dev = dev;
@@ -133,7 +194,7 @@ static int exynos_mbox_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, exynos_mbox);
 
 	/* Mask out all interrupts. We support just polling channels for now. */
-	writel(EXYNOS_MBOX_INTMR0_MASK, exynos_mbox->regs + EXYNOS_MBOX_INTMR0);
+	writel(data->irq_mask_value, exynos_mbox->regs + data->irq_mask_offset);
 
 	return devm_mbox_controller_register(dev, mbox);
 }

-- 
2.51.0



^ permalink raw reply related

* [PATCH v2 3/3] arm64: dts: exynos850: Add ap2apm mailbox
From: Alexey Klimov @ 2026-04-02  2:20 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
	Alim Akhtar, Sam Protsenko, Michael Turquette, Stephen Boyd,
	Rob Herring, Conor Dooley, Tudor Ambarus, Jassi Brar
  Cc: Krzysztof Kozlowski, Peter Griffin, linux-samsung-soc,
	linux-arm-kernel, linux-clk, devicetree, linux-kernel,
	Alexey Klimov
In-Reply-To: <20260402-exynos850-ap2apm-mailbox-v2-0-ca5ffdff99d4@linaro.org>

Add mailbox node that describes AP-to-APM mailbox, that can be
used for communicating with APM co-processor on Exynos850 SoCs.

Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
---
 arch/arm64/boot/dts/exynos/exynos850.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
index cb55015c8dce..fcb665ccc7ae 100644
--- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
@@ -298,6 +298,15 @@ cmu_apm: clock-controller@11800000 {
 			clock-names = "oscclk", "dout_clkcmu_apm_bus";
 		};
 
+		ap2apm_mailbox: mailbox@11900000 {
+			compatible = "samsung,exynos850-mbox";
+			reg = <0x11900000 0x1000>;
+			clocks = <&cmu_apm CLK_GOUT_MAILBOX_APM_AP_PCLK>;
+			clock-names = "pclk";
+			interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+			#mbox-cells = <0>;
+		};
+
 		cmu_cmgp: clock-controller@11c00000 {
 			compatible = "samsung,exynos850-cmu-cmgp";
 			reg = <0x11c00000 0x8000>;

-- 
2.51.0



^ permalink raw reply related

* [PATCH v2 0/2] Add PWM support Amlogic S7 S7D S6
From: Xianwei Zhao via B4 Relay @ 2026-04-02  2:40 UTC (permalink / raw)
  To: Uwe Kleine-König, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Heiner Kallweit, Neil Armstrong, Kevin Hilman,
	Jerome Brunet, Martin Blumenstingl
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	linux-amlogic, Xianwei Zhao, Junyi Zhao, Krzysztof Kozlowski

Add bindings and driver support Amlogic S7/S7D/S6 SoCs.

Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
Changes in v2:
- Simpler s7 clock desc, and drop the example in bindings.
- Make minor changes to probe based on Martin's suggestion.
- Link to v1: https://lore.kernel.org/r/20260326-s6-s7-pwm-v1-0-67e2f72b98bc@amlogic.com

---
Junyi Zhao (1):
      dt-bindings: pwm: amlogic: Add new bindings for S6 S7 S7D

Xianwei Zhao (1):
      pwm: meson: Add support for Amlogic S7

 .../devicetree/bindings/pwm/pwm-amlogic.yaml       | 19 +++++++++++++
 drivers/pwm/pwm-meson.c                            | 32 ++++++++++++++++++++--
 2 files changed, 48 insertions(+), 3 deletions(-)
---
base-commit: 8ab1fc9104158045f68fde2d0ae16f5fbcf8bfbd
change-id: 20260325-s6-s7-pwm-281658b88736

Best regards,
-- 
Xianwei Zhao <xianwei.zhao@amlogic.com>




^ permalink raw reply

* [PATCH v2 1/2] dt-bindings: pwm: amlogic: Add new bindings for S6 S7 S7D
From: Xianwei Zhao via B4 Relay @ 2026-04-02  2:40 UTC (permalink / raw)
  To: Uwe Kleine-König, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Heiner Kallweit, Neil Armstrong, Kevin Hilman,
	Jerome Brunet, Martin Blumenstingl
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	linux-amlogic, Xianwei Zhao, Junyi Zhao, Krzysztof Kozlowski
In-Reply-To: <20260402-s6-s7-pwm-v2-0-657dce040956@amlogic.com>

From: Junyi Zhao <junyi.zhao@amlogic.com>

Amlogic S7/S7D/S6 different from the previous SoCs, a controller
includes one pwm, at the same time, the controller has only one
input clock source.

Signed-off-by: Junyi Zhao <junyi.zhao@amlogic.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
 .../devicetree/bindings/pwm/pwm-amlogic.yaml          | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/Documentation/devicetree/bindings/pwm/pwm-amlogic.yaml b/Documentation/devicetree/bindings/pwm/pwm-amlogic.yaml
index c337d85da40f..93fa97f4011b 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-amlogic.yaml
+++ b/Documentation/devicetree/bindings/pwm/pwm-amlogic.yaml
@@ -37,6 +37,7 @@ properties:
       - enum:
           - amlogic,meson8-pwm-v2
           - amlogic,meson-s4-pwm
+          - amlogic,s7-pwm
       - items:
           - enum:
               - amlogic,a4-pwm
@@ -45,6 +46,11 @@ properties:
               - amlogic,t7-pwm
               - amlogic,meson-a1-pwm
           - const: amlogic,meson-s4-pwm
+      - items:
+          - enum:
+              - amlogic,s6-pwm
+              - amlogic,s7d-pwm
+          - const: amlogic,s7-pwm
       - items:
           - enum:
               - amlogic,meson8b-pwm-v2
@@ -146,6 +152,19 @@ allOf:
         clock-names: false
       required:
         - clocks
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - amlogic,s7-pwm
+    then:
+      properties:
+        clocks:
+          maxItems: 1
+        clock-names: false
+      required:
+        - clocks
 
   - if:
       properties:

-- 
2.52.0




^ permalink raw reply related

* [PATCH v2 2/2] pwm: meson: Add support for Amlogic S7
From: Xianwei Zhao via B4 Relay @ 2026-04-02  2:40 UTC (permalink / raw)
  To: Uwe Kleine-König, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Heiner Kallweit, Neil Armstrong, Kevin Hilman,
	Jerome Brunet, Martin Blumenstingl
  Cc: linux-pwm, devicetree, linux-kernel, linux-arm-kernel,
	linux-amlogic, Xianwei Zhao
In-Reply-To: <20260402-s6-s7-pwm-v2-0-657dce040956@amlogic.com>

From: Xianwei Zhao <xianwei.zhao@amlogic.com>

Add support for Amlogic S7 PWM. Amlogic S7 different from the
previous SoCs, a controller includes one pwm, at the same time,
the controller has only one input clock source.

Signed-off-by: Xianwei Zhao <xianwei.zhao@amlogic.com>
---
 drivers/pwm/pwm-meson.c | 32 +++++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index 8c6bf3d49753..7a43c42ef3d6 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -113,6 +113,7 @@ struct meson_pwm_data {
 	int (*channels_init)(struct pwm_chip *chip);
 	bool has_constant;
 	bool has_polarity;
+	bool single_pwm;
 };
 
 struct meson_pwm {
@@ -503,6 +504,18 @@ static void meson_pwm_s4_put_clk(void *data)
 	clk_put(clk);
 }
 
+static int meson_pwm_init_channels_s7(struct pwm_chip *chip)
+{
+	struct device *dev = pwmchip_parent(chip);
+	struct meson_pwm *meson = to_meson_pwm(chip);
+
+	meson->channels[0].clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(meson->channels[0].clk))
+		return dev_err_probe(dev, PTR_ERR(meson->channels[0].clk),
+				     "Failed to get clk\n");
+	return 0;
+}
+
 static int meson_pwm_init_channels_s4(struct pwm_chip *chip)
 {
 	struct device *dev = pwmchip_parent(chip);
@@ -592,6 +605,13 @@ static const struct meson_pwm_data pwm_s4_data = {
 	.has_polarity = true,
 };
 
+static const struct meson_pwm_data pwm_s7_data = {
+	.channels_init = meson_pwm_init_channels_s7,
+	.has_constant = true,
+	.has_polarity = true,
+	.single_pwm = true,
+};
+
 static const struct of_device_id meson_pwm_matches[] = {
 	{
 		.compatible = "amlogic,meson8-pwm-v2",
@@ -642,6 +662,10 @@ static const struct of_device_id meson_pwm_matches[] = {
 		.compatible = "amlogic,meson-s4-pwm",
 		.data = &pwm_s4_data
 	},
+	{
+		.compatible = "amlogic,s7-pwm",
+		.data = &pwm_s7_data
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, meson_pwm_matches);
@@ -650,9 +674,11 @@ static int meson_pwm_probe(struct platform_device *pdev)
 {
 	struct pwm_chip *chip;
 	struct meson_pwm *meson;
-	int err;
+	const struct meson_pwm_data *pdata = of_device_get_match_data(&pdev->dev);
+	int err, npwm;
 
-	chip = devm_pwmchip_alloc(&pdev->dev, MESON_NUM_PWMS, sizeof(*meson));
+	npwm = pdata->single_pwm ? 1 : MESON_NUM_PWMS;
+	chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*meson));
 	if (IS_ERR(chip))
 		return PTR_ERR(chip);
 	meson = to_meson_pwm(chip);
@@ -664,7 +690,7 @@ static int meson_pwm_probe(struct platform_device *pdev)
 	spin_lock_init(&meson->lock);
 	chip->ops = &meson_pwm_ops;
 
-	meson->data = of_device_get_match_data(&pdev->dev);
+	meson->data = pdata;
 
 	err = meson->data->channels_init(chip);
 	if (err < 0)

-- 
2.52.0




^ permalink raw reply related

* Re: [PATCH v3 0/5] Support the FEAT_HDBSS introduced in Armv9.5
From: Tian Zheng @ 2026-04-02  2:40 UTC (permalink / raw)
  To: Leonardo Bras
  Cc: maz, oupton, catalin.marinas, corbet, pbonzini, will, yuzenghui,
	wangzhou1, liuyonglong, Jonathan.Cameron, yezhenyu2, linuxarm,
	joey.gouly, kvmarm, kvm, linux-arm-kernel, linux-doc,
	linux-kernel, skhan, suzuki.poulose
In-Reply-To: <acvWnjG0AZBHL21q@devkitleo>


On 3/31/2026 10:13 PM, Leonardo Bras wrote:
> On Wed, Feb 25, 2026 at 12:04:16PM +0800, Tian Zheng wrote:
>> This series of patches add support to the Hardware Dirty state tracking
>> Structure(HDBSS) feature, which is introduced by the ARM architecture
>> in the DDI0601(ID121123) version.
>>
>> The HDBSS feature is an extension to the architecture that enhances
>> tracking translation table descriptors' dirty state, identified as
>> FEAT_HDBSS. This feature utilizes hardware assistance to achieve dirty
>> page tracking, aiming to significantly reduce the overhead of scanning
>> for dirty pages.
>>
>> The purpose of this feature is to make the execution overhead of live
>> migration lower to both the guest and the host, compared to existing
>> approaches (write-protect or search stage 2 tables).
>>
>> After these patches, users(such as qemu) can use the
>> KVM_CAP_ARM_HW_DIRTY_STATE_TRACK ioctl to enable or disable the HDBSS
>> feature before and after the live migration.
>>
>> v2:
>> https://lore.kernel.org/linux-arm-kernel/20251121092342.3393318-1-zhengtian10@huawei.com/
>>
>> v2->v3 changes:
>> - Remove the ARM64_HDBSS configuration option and ensure this feature
>> is only enabled in VHE mode.
>> - Move HDBSS-related variables to the arch-independent portion of the
>> kvm structure.
>> - Remove error messages during HDBSS enable/disable operations
>> - Change HDBSS buffer flushing from handle_exit to vcpu_put,
>> check_vcpu_requests, and kvm_handle_guest_abort.
>> - Add fault handling for HDBSS including buffer full, external abort,
>> and general protection fault (GPF).
>> - Add support for a 4KB HDBSS buffer size, mapped to the value 0b0000.
>> - Add a second argument to the ioctl to turn HDBSS on or off.
>>
>> Tian Zheng (1):
>>    KVM: arm64: Document HDBSS ioctl
>>
>> eillon (4):
>>    arm64/sysreg: Add HDBSS related register information
>>    KVM: arm64: Add support to set the DBM attr during memory abort
>>    KVM: arm64: Add support for FEAT_HDBSS
>>    KVM: arm64: Enable HDBSS support and handle HDBSSF events
>>
>>   Documentation/virt/kvm/api.rst       |  16 +++++
>>   arch/arm64/include/asm/cpufeature.h  |   5 ++
>>   arch/arm64/include/asm/esr.h         |   7 ++
>>   arch/arm64/include/asm/kvm_host.h    |  17 +++++
>>   arch/arm64/include/asm/kvm_mmu.h     |   1 +
>>   arch/arm64/include/asm/kvm_pgtable.h |   4 ++
>>   arch/arm64/include/asm/sysreg.h      |  11 +++
>>   arch/arm64/kernel/cpufeature.c       |  12 ++++
>>   arch/arm64/kvm/arm.c                 | 102 +++++++++++++++++++++++++++
>>   arch/arm64/kvm/hyp/pgtable.c         |   6 ++
>>   arch/arm64/kvm/hyp/vhe/switch.c      |  19 +++++
>>   arch/arm64/kvm/mmu.c                 |  70 ++++++++++++++++++
>>   arch/arm64/kvm/reset.c               |   3 +
>>   arch/arm64/tools/cpucaps             |   1 +
>>   arch/arm64/tools/sysreg              |  29 ++++++++
>>   include/uapi/linux/kvm.h             |   1 +
>>   tools/include/uapi/linux/kvm.h       |   1 +
>>   17 files changed, 305 insertions(+)
>>
>> --
>> 2.33.0
>>
>
> Hi Tian,
>
> I was thinking: maybe instead of putting the HDBSS (and HACDBS) stuff
> across a bunch of KVM files, we should try to focus them all on a single
> arch/arm64/kvm/dirty_bit.c file (plus a header such as
> arch/arm64/include/asm/kvm_dirty_bit.h).
>
> What is your opinion on that?
>
> Thanks!
> Leo


Sorry for the late reply. Yes, I had the same thought before. In the 
next version, I will

move all the HDBSS-related content into the same file, such as 
arch/arm64/kvm/dirty_bit.c

and arch/arm64/include/asm/kvm_dirty_bit.h.


Tian


>
>


^ permalink raw reply

* Re: [RFC PATCH 1/7] media: v4l2-ctrls: Add V4L2_CID_MEMORY_USAGE control
From: Ming Qian(OSS) @ 2026-04-02  3:14 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: <d8c12ba1-5004-4a51-8a2b-3d500184778b@oss.nxp.com>

Hi Nicolas,

On 4/1/2026 10:23 AM, Ming Qian(OSS) wrote:
> 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
> 

Regarding the discussion about using fdinfo instead of a V4L2 control, I
have two questions:

	1. Key consistency in fdinfo
	fdinfo uses key–value pairs, which is flexible, but if multiple
	drivers want to expose the same “memory usage” information,
	they need to agree on a common key name and meaning. Otherwise
	user‑space must handle each driver differently. A V4L2 control
	naturally provides a unified interface without this coordination
	effort.


	2. Lack of notification in fdinfo
	With a control, user‑space can subscribe to control events and
	receive notifications when the memory usage changes. fdinfo does
	not have a built‑in event mechanism, so users must either poll
	or rely on additional eventfd‑like or custom event mechanisms.

Do you have any suggestions or existing practices to address these two
issues when using fdinfo?

Thanks again for your time and comments.

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 02/10] dmaengine: imx-sdma: fix spba-bus handling for i.MX8M
From: Shengjiu Wang @ 2026-04-02  3:33 UTC (permalink / raw)
  To: Marco Felsch
  Cc: Vinod Koul, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
	Fabio Estevam, Jiada Wang, dmaengine, imx, linux-arm-kernel,
	linux-kernel
In-Reply-To: <20250911-v6-16-topic-sdma-v2-2-d315f56343b5@pengutronix.de>

On Fri, Sep 12, 2025 at 6:05 AM Marco Felsch <m.felsch@pengutronix.de> wrote:
>
> Starting with i.MX8M* devices there are multiple spba-busses so we can't
> just search the whole DT for the first spba-bus match and take it.
> Instead we need to check for each device to which bus it belongs and
> setup the spba_{start,end}_addr accordingly per sdma_channel.
>
> While on it, don't ignore errors from of_address_to_resource() if they
> are valid.
>
> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
>  drivers/dma/imx-sdma.c | 58 ++++++++++++++++++++++++++++++++++----------------
>  1 file changed, 40 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> index 3ecb917214b1268b148a29df697b780bc462afa4..56daaeb7df03986850c9c74273d0816700581dc0 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -429,6 +429,8 @@ struct sdma_desc {
>   * @event_mask:                event mask used in p_2_p script
>   * @watermark_level:   value for gReg[7], some script will extend it from
>   *                     basic watermark such as p_2_p
> + * @spba_start_addr:   SDMA controller SPBA bus start address
> + * @spba_end_addr:     SDMA controller SPBA bus end address
>   * @shp_addr:          value for gReg[6]
>   * @per_addr:          value for gReg[2]
>   * @status:            status of dma channel
> @@ -461,6 +463,8 @@ struct sdma_channel {
>         dma_addr_t                      per_address, per_address2;
>         unsigned long                   event_mask[2];
>         unsigned long                   watermark_level;
> +       u32                             spba_start_addr;
> +       u32                             spba_end_addr;
>         u32                             shp_addr, per_addr;
>         enum dma_status                 status;
>         struct imx_dma_data             data;
> @@ -534,8 +538,6 @@ struct sdma_engine {
>         u32                             script_number;
>         struct sdma_script_start_addrs  *script_addrs;
>         const struct sdma_driver_data   *drvdata;
> -       u32                             spba_start_addr;
> -       u32                             spba_end_addr;
>         unsigned int                    irq;
>         dma_addr_t                      bd0_phys;
>         struct sdma_buffer_descriptor   *bd0;
> @@ -1236,8 +1238,6 @@ static void sdma_channel_synchronize(struct dma_chan *chan)
>
>  static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac)
>  {
> -       struct sdma_engine *sdma = sdmac->sdma;
> -
>         int lwml = sdmac->watermark_level & SDMA_WATERMARK_LEVEL_LWML;
>         int hwml = (sdmac->watermark_level & SDMA_WATERMARK_LEVEL_HWML) >> 16;
>
> @@ -1263,12 +1263,12 @@ static void sdma_set_watermarklevel_for_p2p(struct sdma_channel *sdmac)
>                 swap(sdmac->event_mask[0], sdmac->event_mask[1]);
>         }
>
> -       if (sdmac->per_address2 >= sdma->spba_start_addr &&
> -                       sdmac->per_address2 <= sdma->spba_end_addr)
> +       if (sdmac->per_address2 >= sdmac->spba_start_addr &&
> +                       sdmac->per_address2 <= sdmac->spba_end_addr)
>                 sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_SP;
>
> -       if (sdmac->per_address >= sdma->spba_start_addr &&
> -                       sdmac->per_address <= sdma->spba_end_addr)
> +       if (sdmac->per_address >= sdmac->spba_start_addr &&
> +                       sdmac->per_address <= sdmac->spba_end_addr)
>                 sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_DP;
>
>         sdmac->watermark_level |= SDMA_WATERMARK_LEVEL_CONT;
> @@ -1447,6 +1447,31 @@ static void sdma_desc_free(struct virt_dma_desc *vd)
>         kfree(desc);
>  }
>
> +static int sdma_config_spba_slave(struct dma_chan *chan)
> +{
> +       struct sdma_channel *sdmac = to_sdma_chan(chan);
> +       struct device_node *spba_bus;
> +       struct resource spba_res;
> +       int ret;
> +
> +       spba_bus = of_get_parent(chan->slave->of_node);

if the chan is requested by __dma_request_channel(),  the chan->slave = NULL
Then there will be an issue here.

Best regards
Shengjiu Wang

> +       /* Device doesn't belong to the spba-bus */
> +       if (!of_device_is_compatible(spba_bus, "fsl,spba-bus"))
> +               return 0;
> +
> +       ret = of_address_to_resource(spba_bus, 0, &spba_res);
> +       of_node_put(spba_bus);
> +       if (ret) {
> +               dev_err(sdmac->sdma->dev, "Failed to get spba-bus resources\n");
> +               return -EINVAL;
> +       }
> +
> +       sdmac->spba_start_addr = spba_res.start;
> +       sdmac->spba_end_addr = spba_res.end;
> +
> +       return 0;
> +}
> +
>  static int sdma_alloc_chan_resources(struct dma_chan *chan)
>  {
>         struct sdma_channel *sdmac = to_sdma_chan(chan);
> @@ -1527,6 +1552,8 @@ static void sdma_free_chan_resources(struct dma_chan *chan)
>
>         sdmac->event_id0 = 0;
>         sdmac->event_id1 = 0;
> +       sdmac->spba_start_addr = 0;
> +       sdmac->spba_end_addr = 0;
>
>         sdma_set_channel_priority(sdmac, 0);
>
> @@ -1837,6 +1864,7 @@ static int sdma_config(struct dma_chan *chan,
>  {
>         struct sdma_channel *sdmac = to_sdma_chan(chan);
>         struct sdma_engine *sdma = sdmac->sdma;
> +       int ret;
>
>         memcpy(&sdmac->slave_config, dmaengine_cfg, sizeof(*dmaengine_cfg));
>
> @@ -1867,6 +1895,10 @@ static int sdma_config(struct dma_chan *chan,
>                 sdma_event_enable(sdmac, sdmac->event_id1);
>         }
>
> +       ret = sdma_config_spba_slave(chan);
> +       if (ret)
> +               return ret;
> +
>         return 0;
>  }
>
> @@ -2235,11 +2267,9 @@ static struct dma_chan *sdma_xlate(struct of_phandle_args *dma_spec,
>  static int sdma_probe(struct platform_device *pdev)
>  {
>         struct device_node *np = pdev->dev.of_node;
> -       struct device_node *spba_bus;
>         const char *fw_name;
>         int ret;
>         int irq;
> -       struct resource spba_res;
>         int i;
>         struct sdma_engine *sdma;
>         s32 *saddr_arr;
> @@ -2375,14 +2405,6 @@ static int sdma_probe(struct platform_device *pdev)
>                         dev_err(&pdev->dev, "failed to register controller\n");
>                         goto err_register;
>                 }
> -
> -               spba_bus = of_find_compatible_node(NULL, NULL, "fsl,spba-bus");
> -               ret = of_address_to_resource(spba_bus, 0, &spba_res);
> -               if (!ret) {
> -                       sdma->spba_start_addr = spba_res.start;
> -                       sdma->spba_end_addr = spba_res.end;
> -               }
> -               of_node_put(spba_bus);
>         }
>
>         /*
>
> --
> 2.47.3
>
>


^ permalink raw reply

* Re: [RFC PATCH v2 1/5] iommu/arm-smmu-v3: Add basic debugfs framework
From: Qinxin Xia @ 2026-04-02  3:50 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: robin.murphy, will, jpb, linux-arm-kernel, iommu, wangzhou1,
	prime.zeng, fanghao11, jonathan.cameron, wuyifan50, linuxarm
In-Reply-To: <acpUoZ7wx9gdT5BG@nvidia.com>



On 2026/3/30 18:46:57, Nicolin Chen <nicolinc@nvidia.com> wrote:
> On Sat, Mar 28, 2026 at 06:17:02PM +0800, Qinxin Xia wrote:
>> Add basic debugfs framework for ARM SMMUv3 driver.This creates the
> 
> Needs a space after "."
> 
>> +static int smmu_debugfs_capabilities_show(struct seq_file *seq, void *unused)
>> +{
>> +	struct arm_smmu_device *smmu = seq->private;
>> +
>> +	if (!smmu) {
>> +		seq_puts(seq, "SMMU not available\n");
>> +		return 0;
>> +	}
>> +
>> +	seq_puts(seq, "SMMUv3 Capabilities:\n");
>> +	seq_printf(seq, "  Stage1 Translation: %s\n",
>> +		   smmu->features & ARM_SMMU_FEAT_TRANS_S1 ? "Yes" : "No");
>> +	seq_printf(seq, "  Stage2 Translation: %s\n",
>> +		   smmu->features & ARM_SMMU_FEAT_TRANS_S2 ? "Yes" : "No");
>> +	seq_printf(seq, "  Coherent Walk: %s\n",
>> +		   smmu->features & ARM_SMMU_FEAT_COHERENCY ? "Yes" : "No");
>> +	seq_printf(seq, "  ATS Support: %s\n",
>> +		   smmu->features & ARM_SMMU_FEAT_ATS ? "Yes" : "No");
>> +	seq_printf(seq, "  PRI Support: %s\n",
>> +		   smmu->features & ARM_SMMU_FEAT_PRI ? "Yes" : "No");
>> +	seq_printf(seq, "  Stream Table Size: %d\n", 1 << smmu->sid_bits);
>> +	seq_printf(seq, "  Command Queue Depth: %d\n",
>> +		   1 << smmu->cmdq.q.llq.max_n_shift);
>> +	seq_printf(seq, "  Event Queue Depth: %d\n",
>> +		   1 << smmu->evtq.q.llq.max_n_shift);
> 
> Nit: should we do all sizes or all depths? Any good reason to mix
> them here?
>

Stream Table is a table, not a queue, so 'Size' is more appropriate; 
queues use 'Depth'. But I can change to unify if preferred.

>> +/**
>> + * arm_smmu_debugfs_remove() - Clean up debugfs entries for an SMMU device
>> + * @smmu: SMMU device
>> + *
>> + * This function removes the debugfs directories created by setup.
>> + */
>> +void arm_smmu_debugfs_remove(struct arm_smmu_device *smmu)
>> +{
>> +	struct arm_smmu_debugfs *debugfs;
>> +
>> +	scoped_guard(mutex, &arm_smmu_debugfs_lock) {
> 
> It could be just normal guard().
> 
>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> index 4d00d796f078..cbb3fccc501b 100644
>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> @@ -4904,6 +4904,15 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
>>   	/* Check for RMRs and install bypass STEs if any */
>>   	arm_smmu_rmr_install_bypass_ste(smmu);
>>   
>> +#ifdef CONFIG_ARM_SMMU_V3_DEBUGFS
>> +	char name[32];
> 
> This could be moved to the top, as iommu_device_sysfs_add() can use
> it, whether CONFIG_ARM_SMMU_V3_DEBUGFS=y or =n.
> 
>> +	snprintf(name, sizeof(name), "smmu3.%pa", &ioaddr);
> 
> And this could be moved after ioaddr gets a copy from res->start.
> 
>>   
>> +#ifdef CONFIG_ARM_SMMU_V3_DEBUGFS
>> +struct arm_smmu_debugfs {
>> +	struct dentry			*smmu_dir;
> 
> A personal preference: for new structures, maybe drop those tabs?
> 
>>   /* An SMMUv3 instance */
>>   struct arm_smmu_device {
>>   	struct device			*dev;
>> @@ -803,6 +813,11 @@ struct arm_smmu_device {
>>   
>>   	struct rb_root			streams;
>>   	struct mutex			streams_mutex;
>> +
>> +#ifdef CONFIG_ARM_SMMU_V3_DEBUGFS
>> +	/* DebugFS Info */
> 
> Doesn't seem very useful. I'd drop it.
> 
>> +	struct arm_smmu_debugfs		*debugfs;
>> +#endif
>   
> Nicolin
> 
-- 
Thanks,
Qinxin



^ permalink raw reply

* Re: [PATCH 00/11] Drivers: hv: Add ARM64 support in mshv_vtl
From: Naman Jain @ 2026-04-02  4:01 UTC (permalink / raw)
  To: Michael Kelley, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Long Li, Catalin Marinas, Will Deacon,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
	x86@kernel.org, H . Peter Anvin, Arnd Bergmann, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti
  Cc: Marc Zyngier, Timothy Hayes, Lorenzo Pieralisi, mrigendrachaubey,
	ssengar@linux.microsoft.com, linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	linux-riscv@lists.infradead.org
In-Reply-To: <SN6PR02MB4157E4E088F39106979BE4EDD450A@SN6PR02MB4157.namprd02.prod.outlook.com>



On 4/1/2026 10:24 PM, Michael Kelley wrote:
> From: Naman Jain <namjain@linux.microsoft.com> Sent: Tuesday, March 17, 2026 9:23 PM
>>
>> On 3/18/2026 3:33 AM, Michael Kelley wrote:
>>> From: Naman Jain <namjain@linux.microsoft.com> Sent: Monday, March 16, 2026 5:13 AM
>>>>
>>>> The series intends to add support for ARM64 to mshv_vtl driver.
> 
> No need to be tentative. :-)  Just write as:
> 
> "The series adds support for ARM64 to the mshv_vtl driver."
> 
>>>> For this, common Hyper-V code is refactored, necessary support is added,
>>>> mshv_vtl_main.c is refactored and then finally support is added in
>>>> Kconfig.
>>>>
>>>> Based on commit 1f318b96cc84 ("Linux 7.0-rc3")
>>>
>>> There's now an online LLM-based tool that is automatically reviewing
>>> kernel patches. For this patch set, the results are here:
>>>
>>> https://sashiko.dev/#/patchset/20260316121241.910764-1-namjain%40linux.microsoft.com
>>>
>>> It has flagged several things that are worth checking, but I haven't
>>> reviewed them to see if they are actually valid.
>>>
>>> FWIW, the announcement about sashiko.dev is here:
>>>
>>> https://lore.kernel.org/lkml/7ia4o6kmpj5s.fsf@castle.c.googlers.com/
>>>
>>> Michael
>>
>>
>> Thanks for sharing Michael,
>> I'll check it out and do the needful.
>>
> 
> I've done a full review of this patch set and provided comments in the
> individual patches. Some of my comments reference the Sashiko AI
> comments, but there are still some Sashiko AI comments to consider
> that I haven't referenced.
> 
> FWIW, the Sashiko AI comments are quite good -- it found some things
> here that I missed on my own, and in my earlier reviews of the original VTL
> code. :-(
> 
> Michael


Thank you so much Michael for reviewing these. I was also trying to 
address review comments from Sashiko, and noticed some of them were 
false positives in the sense that these were existing issues and not 
introduced by arm64 changes. I thought of keeping them separate from the 
scope of this series for future.

I'll review your comments and address them.

Regards,
Naman


^ permalink raw reply

* [PATCH v1 02/27] KVM, vfio: remove symbol_get(kvm_get_kvm_safe) from vfio
From: Steffen Eiden @ 2026-04-02  4:20 UTC (permalink / raw)
  To: kvm, kvmarm, linux-arm-kernel, linux-kernel, linux-s390
  Cc: Andreas Grapentin, Arnd Bergmann, Catalin Marinas,
	Christian Borntraeger, Claudio Imbrenda, David Hildenbrand,
	Gautam Gala, Hendrik Brueckner, Janosch Frank, Joey Gouly,
	Marc Zyngier, Nina Schoetterl-Glausch, Oliver Upton,
	Paolo Bonzini, Suzuki K Poulose, Ulrich Weigand, Will Deacon,
	Zenghui Yu
In-Reply-To: <20260402042125.3948963-1-seiden@linux.ibm.com>

From: Paolo Bonzini <pbonzini@redhat.com>

Right now, KVM and VFIO are using symbol_get to access each other's
symbols because of a circular reference between the modules, as well
as to avoid loading them unnecessarily.

However, usage of symbol_get is mostly deprecated and there are just a
handful of users left. In the case of VFIO, in particular, the
functions it calls can be made inline. Start with kvm_get_kvm_safe, for
which it is trivial to do so.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
 arch/x86/kvm/mmu/tdp_mmu.c |  2 +-
 arch/x86/kvm/vmx/nested.h  |  4 ++--
 drivers/vfio/vfio_main.c   | 10 +---------
 include/linux/kvm_host.h   |  9 +++++----
 include/linux/kvm_types.h  | 24 ++++++++++++++++++++++++
 virt/kvm/kvm_main.c        | 26 +++++---------------------
 6 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 9c26038f6b77..a88686b5db24 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -1136,7 +1136,7 @@ void kvm_tdp_mmu_invalidate_roots(struct kvm *kvm,
 	 * being destroyed in an error path of KVM_CREATE_VM.
 	 */
 	if (IS_ENABLED(CONFIG_PROVE_LOCKING) &&
-	    refcount_read(&kvm->users_count) && kvm->created_vcpus)
+	    refcount_read(&kvm->rc.users_count) && kvm->created_vcpus)
 		lockdep_assert_held_write(&kvm->mmu_lock);
 
 	/*
diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h
index 213a448104af..2c83fc905698 100644
--- a/arch/x86/kvm/vmx/nested.h
+++ b/arch/x86/kvm/vmx/nested.h
@@ -58,7 +58,7 @@ bool nested_vmx_check_io_bitmaps(struct kvm_vcpu *vcpu, unsigned int port,
 static inline struct vmcs12 *get_vmcs12(struct kvm_vcpu *vcpu)
 {
 	lockdep_assert_once(lockdep_is_held(&vcpu->mutex) ||
-			    !refcount_read(&vcpu->kvm->users_count));
+			    !refcount_read(&vcpu->kvm->rc.users_count));
 
 	return to_vmx(vcpu)->nested.cached_vmcs12;
 }
@@ -66,7 +66,7 @@ static inline struct vmcs12 *get_vmcs12(struct kvm_vcpu *vcpu)
 static inline struct vmcs12 *get_shadow_vmcs12(struct kvm_vcpu *vcpu)
 {
 	lockdep_assert_once(lockdep_is_held(&vcpu->mutex) ||
-			    !refcount_read(&vcpu->kvm->users_count));
+			    !refcount_read(&vcpu->kvm->rc.users_count));
 
 	return to_vmx(vcpu)->nested.cached_shadow_vmcs12;
 }
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index b1b753889a77..42f515519d87 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -437,7 +437,6 @@ void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm,
 			      struct module *kvm_module)
 {
 	void (*pfn)(struct kvm *kvm);
-	bool (*fn)(struct kvm *kvm);
 	bool ret;
 
 	lockdep_assert_held(&device->dev_set->lock);
@@ -452,14 +451,7 @@ void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm,
 	if (WARN_ON(!pfn))
 		return;
 
-	fn = symbol_get(kvm_get_kvm_safe);
-	if (WARN_ON(!fn)) {
-		symbol_put(kvm_put_kvm);
-		return;
-	}
-
-	ret = fn(kvm);
-	symbol_put(kvm_get_kvm_safe);
+	ret = kvm_get_kvm_safe(kvm);
 	if (!ret) {
 		symbol_put(kvm_put_kvm);
 		return;
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 6b76e7a6f4c2..dc18ee99bba4 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -767,6 +767,9 @@ struct kvm_memslots {
 };
 
 struct kvm {
+	/* Must be the first field, see function definitions in kvm_types.h.  */
+	struct kvm_refcount rc;
+
 #ifdef KVM_HAVE_MMU_RWLOCK
 	rwlock_t mmu_lock;
 #else
@@ -830,7 +833,6 @@ struct kvm {
 	struct list_head ioeventfds;
 	struct kvm_vm_stat stat;
 	struct kvm_arch arch;
-	refcount_t users_count;
 #ifdef CONFIG_KVM_MMIO
 	struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
 	spinlock_t ring_lock;
@@ -876,6 +878,7 @@ struct kvm {
 #endif
 	char stats_id[KVM_STATS_NAME_SIZE];
 };
+static_assert(offsetof(struct kvm, rc) == 0);
 
 #define kvm_err(fmt, ...) \
 	pr_err("kvm [%i]: " fmt, task_pid_nr(current), ## __VA_ARGS__)
@@ -1062,8 +1065,6 @@ static inline void kvm_irqfd_exit(void)
 int kvm_init(unsigned vcpu_size, unsigned vcpu_align, struct module *module);
 void kvm_exit(void);
 
-void kvm_get_kvm(struct kvm *kvm);
-bool kvm_get_kvm_safe(struct kvm *kvm);
 void kvm_put_kvm(struct kvm *kvm);
 bool file_is_kvm(struct file *file);
 void kvm_put_kvm_no_destroy(struct kvm *kvm);
@@ -1073,7 +1074,7 @@ static inline struct kvm_memslots *__kvm_memslots(struct kvm *kvm, int as_id)
 	as_id = array_index_nospec(as_id, KVM_MAX_NR_ADDRESS_SPACES);
 	return srcu_dereference_check(kvm->memslots[as_id], &kvm->srcu,
 			lockdep_is_held(&kvm->slots_lock) ||
-			!refcount_read(&kvm->users_count));
+			!refcount_read(&kvm->rc.users_count));
 }
 
 static inline struct kvm_memslots *kvm_memslots(struct kvm *kvm)
diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h
index a568d8e6f4e8..add7cc2016e8 100644
--- a/include/linux/kvm_types.h
+++ b/include/linux/kvm_types.h
@@ -33,6 +33,7 @@
 
 #include <linux/mutex.h>
 #include <linux/spinlock_types.h>
+#include <linux/refcount.h>
 
 struct kvm;
 struct kvm_async_pf;
@@ -140,6 +141,29 @@ struct kvm_vcpu_stat_generic {
 };
 
 #define KVM_STATS_NAME_SIZE	48
+
+struct kvm_refcount {
+	refcount_t users_count;
+};
+
+static inline void kvm_get_kvm(struct kvm *kvm)
+{
+	struct kvm_refcount *rc = (struct kvm_refcount *)kvm;
+
+	refcount_inc(&rc->users_count);
+}
+
+/*
+ * A safe version of kvm_get_kvm(), making sure the vm is not being destroyed.
+ * Return true if kvm referenced successfully, false otherwise.
+ */
+static inline bool kvm_get_kvm_safe(struct kvm *kvm)
+{
+	struct kvm_refcount *rc = (struct kvm_refcount *)kvm;
+
+	return refcount_inc_not_zero(&rc->users_count);
+}
+
 #endif /* !__ASSEMBLER__ */
 
 #endif /* __KVM_TYPES_H__ */
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 9093251beb39..cb5e01f92503 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1099,7 +1099,7 @@ static inline struct kvm_io_bus *kvm_get_bus_for_destruction(struct kvm *kvm,
 							     enum kvm_bus idx)
 {
 	return rcu_dereference_protected(kvm->buses[idx],
-					 !refcount_read(&kvm->users_count));
+					 !refcount_read(&kvm->rc.users_count));
 }
 
 static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
@@ -1153,7 +1153,7 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
 	if (r)
 		goto out_err_no_irq_routing;
 
-	refcount_set(&kvm->users_count, 1);
+	refcount_set(&kvm->rc.users_count, 1);
 
 	for (i = 0; i < kvm_arch_nr_memslot_as_ids(kvm); i++) {
 		for (j = 0; j < 2; j++) {
@@ -1223,7 +1223,7 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
 out_err_no_disable:
 	kvm_arch_destroy_vm(kvm);
 out_err_no_arch_destroy_vm:
-	WARN_ON_ONCE(!refcount_dec_and_test(&kvm->users_count));
+	WARN_ON_ONCE(!refcount_dec_and_test(&kvm->rc.users_count));
 	for (i = 0; i < KVM_NR_BUSES; i++)
 		kfree(kvm_get_bus_for_destruction(kvm, i));
 	kvm_free_irq_routing(kvm);
@@ -1316,25 +1316,9 @@ static void kvm_destroy_vm(struct kvm *kvm)
 	mmdrop(mm);
 }
 
-void kvm_get_kvm(struct kvm *kvm)
-{
-	refcount_inc(&kvm->users_count);
-}
-EXPORT_SYMBOL_GPL(kvm_get_kvm);
-
-/*
- * Make sure the vm is not during destruction, which is a safe version of
- * kvm_get_kvm().  Return true if kvm referenced successfully, false otherwise.
- */
-bool kvm_get_kvm_safe(struct kvm *kvm)
-{
-	return refcount_inc_not_zero(&kvm->users_count);
-}
-EXPORT_SYMBOL_GPL(kvm_get_kvm_safe);
-
 void kvm_put_kvm(struct kvm *kvm)
 {
-	if (refcount_dec_and_test(&kvm->users_count))
+	if (refcount_dec_and_test(&kvm->rc.users_count))
 		kvm_destroy_vm(kvm);
 }
 EXPORT_SYMBOL_GPL(kvm_put_kvm);
@@ -1348,7 +1332,7 @@ EXPORT_SYMBOL_GPL(kvm_put_kvm);
  */
 void kvm_put_kvm_no_destroy(struct kvm *kvm)
 {
-	WARN_ON(refcount_dec_and_test(&kvm->users_count));
+	WARN_ON(refcount_dec_and_test(&kvm->rc.users_count));
 }
 EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_put_kvm_no_destroy);
 
-- 
2.51.0



^ permalink raw reply related

* [PATCH v1 00/27] KVM: s390: Introduce arm64 KVM
From: Steffen Eiden @ 2026-04-02  4:20 UTC (permalink / raw)
  To: kvm, kvmarm, linux-arm-kernel, linux-kernel, linux-s390
  Cc: Andreas Grapentin, Arnd Bergmann, Catalin Marinas,
	Christian Borntraeger, Claudio Imbrenda, David Hildenbrand,
	Gautam Gala, Hendrik Brueckner, Janosch Frank, Joey Gouly,
	Marc Zyngier, Nina Schoetterl-Glausch, Oliver Upton,
	Paolo Bonzini, Suzuki K Poulose, Ulrich Weigand, Will Deacon,
	Zenghui Yu

By introducing a novel virtualization acceleration for the ARM architecture on
s390 architecture, we aim to expand the platform's software ecosystem. This
initial patch series lays the groundwork by enabling KVM-accelerated ARM CPU
virtualization on s390. To achieve this, a common KVM layer between s390 and
arm64 is introduced (see below for more details). Design considerations of
arm64 on the s390 Architecture The s390 virtualization architecture is extended
with a set of new instructions dedicated to supporting ARM-based virtual
machines. The s390 KVM host acts as EL2 (hypervisor) for a EL1/EL0
(OS/application) arm64 guest. To achieve this, the new Start-Arm-Execution
(SAE) instruction enables accelerated execution of arm64 VMs.  Additional new
s390 instructions are introduced to query available arm64 features, used to
populate the arm64 ID register contents, as well as, new s390 instructions to
save/restore various arm64 registers in the VM context.

Summary of changes to arm64 KVM

UAPI / KAPI changes

The arm64 KVM UAPI headers are relocated to include/uapi/arch/arm64/,
allowing non‑arm64 hosts (such as s390) to use the arm64 KVM userspace API.
Likewise, the arm64 KVM kernel‑internal headers are relocated to
include/kvm/arm64/, and several arm64 asm headers are relocated to
include/arch/arm64/asm for architecture‑independent consumption.

Refactoring of arm64 headers and shared arm64 KVM functionality

To avoid code duplication, sharing logic between arm64/kvm and s390/kvm/arm64
is maximized while refactoring noise was minimized. IOCTL (arch) entry points
are deliberately kept separate for arm64 and arm64 on s390. This ensures full
control over execution paths for each KVM implementation. The arm64 sysreg
definitions and pstate/SPSR constants are extracted from their native headers
into dedicated, shareable files (sysreg-defs.h, pstate.h). This enables
other architectures to access sysreg name‑to‑ID mappings and pstate definitions
without relying on arm64‑specific, non‑shareable headers.

A new virt/kvm/arm64/ source directory is introduced to hold shared Arm64 KVM
implementation code, including guest register handling, exit handling,
general‑register reset logic, and IPA size/shift
calculations. Several functions are also refactored to improve portability for
non‑arm64 KVM implementations. 

Maintainership considerations

Introducing a shared arm64 KVM code base for both native arm64 and s390
implementations may have subtle implications for each architecture,
depending on the context and the contributor’s expertise. We therefore
recognize the importance of clear maintainership guidelines and
well-defined review processes to ensure the stability and correctness of
both implementations. We welcome community feedback on how best to
structure maintainership and the review workflow, and we are open to
suggestions for effective coordination between the arm64 and s390
maintainer teams.

UAPI design

The arm64 KVM UAPI headers are relocated from arch/arm64/include/uapi/
to the new include/uapi/arch/arm64/ directory, and generic KVM definitions are
split into include/uapi/linux/kvm-generic.h for use across all architectures.
To maintain ABI compatibility, type aliases are introduced; they resolve to
native arm64 types on arm64 and to equivalent inline struct definitions on
foreign hosts. The build system installs the headers in their original location
on arm64, while conditionally exporting them to the new location for s390.

KAPI design

The include/arch/arm64/asm/ directory is introduced to host arm64 asm headers
that are independent of the host CPU. On native arm64 systems, this path is
added with the highest precedence so that existing <asm/header.h> includes
continue to work without modification. Foreign architectures can opt in by
adding this path to their include search, enabling them to use these
architecture‑agnostic headers.

The KVM‑related headers are moved to include/kvm/arm64/, decoupling them from
the arm64 architecture directory. The design convention is that
architecture‑specific headers under <arch>/include/asm/ include from this
shared location, allowing non‑arm64 hosts to consume the arm64 KVM
infrastructure without duplicating code.

Series structure

KVM symbol cleanup:
	Three preparatory patches clean up KVM module symbol exports, making it
	possible to load two KVM modules side by side.

Arm64 header and code sharing:
	Selected arm64 UAPI, asm, and KVM kernel headers are
	refactored into architecture-agnostic include paths, and shared arm64 KVM code
	is relocated accordingly. This enables non-arm64 hosts to use the arm64 KVM
	infrastructure without duplication. 

s390 & KVM reorganization:
	The existing s390 KVM code is moved into a dedicated s390 subdirectory
	to make room for a second KVM implementation alongside it. The KVM
	core is extended to support a configurable device name (needed for two
	KVM devices on one architecture) Arm64

KVM on s390:
	The SAE (Start Arm Execution) instruction is introduced as the
	s390 mechanism for running Arm64 guests, and a new kvm-arm64 module is
	built up incrementally.

Upcoming patch series will introduce system-register handling, interrupt
support, hypercalls, and additional features such as PMU.

We appreciate your feedback and review.

The Linux on s390 team

Hendrik Brueckner (1):
  s390/hwcaps: Report SAE support as hwcap

Nina Schoetterl-Glausch (3):
  arm64: Extract sysreg definitions
  arm64: Extract pstate definitions from ptrace
  KVM: arm64: Share reset general register code

Paolo Bonzini (3):
  VFIO: take reference to the KVM module
  KVM, vfio: remove symbol_get(kvm_get_kvm_safe) from vfio
  KVM, vfio: remove symbol_get(kvm_put_kvm) from vfio

Steffen Eiden (20):
  arm64: Provide arm64 UAPI for other host architectures
  arm64: Provide arm64 API for non-native architectures
  KVM: arm64: Provide arm64 KVM API for non-native architectures
  KVM: arm64: Share kvm_emulate definitions
  KVM: arm64: Make some arm64 KVM code shareable
  KVM: arm64: Access elements of vcpu_gp_regs individually
  KVM: arm64: Extract & share ipa size shift calculation
  KVM: s390: Move s390 kvm code into a subdirectory
  KVM: S390: Refactor gmap
  KVM: Make device name configurable
  KVM: Remove KVM_MMIO as config option
  KVM: s390: Prepare kvm-s390 for a second kvm module
  s390: Introduce Start Arm Execution instruction
  KVM: s390: arm64: Introduce host definitions
  KVM: s390: Add basic arm64 kvm module
  KVM: s390: arm64: Implement required functions
  KVM: s390: arm64: Implement vm/vcpu create destroy.
  KVM: s390: arm64: Implement vCPU IOCTLs
  KVM: s390: arm64: Implement basic page fault handler
  KVM: s390: arm64: Enable KVM_ARM64 config and Kbuild

 MAINTAINERS                                   |    5 +
 arch/arm64/Makefile                           |    2 +
 arch/arm64/include/asm/Kbuild                 |    2 +-
 arch/arm64/include/asm/el2_setup.h            |    2 +-
 arch/arm64/include/asm/hardirq.h              |    2 +-
 arch/arm64/include/asm/kvm_emulate.h          |  245 +--
 arch/arm64/include/asm/kvm_host.h             |  200 +-
 arch/arm64/include/asm/kvm_mmu.h              |   41 +-
 arch/arm64/include/asm/ptrace.h               |   34 +-
 arch/arm64/include/asm/sysreg.h               |  972 +---------
 arch/arm64/include/uapi/asm/Kbuild            |    4 +
 arch/arm64/include/uapi/asm/ptrace.h          |   49 +-
 arch/arm64/kernel/head.S                      |    2 +-
 arch/arm64/kernel/hyp-stub.S                  |    2 +-
 arch/arm64/kernel/traps.c                     |   53 -
 arch/arm64/kvm/Kconfig                        |    1 -
 arch/arm64/kvm/Makefile                       |    5 +-
 arch/arm64/kvm/arm.c                          |   54 +-
 arch/arm64/kvm/debug.c                        |    2 +-
 arch/arm64/kvm/guest.c                        |  294 +--
 arch/arm64/kvm/handle_exit.c                  |   52 +-
 arch/arm64/kvm/hyp/entry.S                    |    2 +-
 arch/arm64/kvm/hyp/exception.c                |    7 +-
 arch/arm64/kvm/hyp/hyp-entry.S                |    2 +-
 arch/arm64/kvm/hyp/include/hyp/adjust_pc.h    |   17 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h       |    6 +-
 arch/arm64/kvm/hyp/nvhe/host.S                |    2 +-
 arch/arm64/kvm/hyp/nvhe/hyp-init.S            |    2 +-
 arch/arm64/kvm/mmu.c                          |   20 +-
 arch/arm64/kvm/nested.c                       |    2 +-
 arch/arm64/kvm/reset.c                        |   34 +-
 arch/arm64/kvm/sys_regs.c                     |    2 +-
 arch/arm64/kvm/trace_arm.h                    |   25 -
 arch/arm64/kvm/vgic/vgic-its.c                |    2 +-
 arch/arm64/kvm/vgic/vgic-mmio-v3.c            |    2 +-
 arch/arm64/kvm/vgic/vgic-v3-nested.c          |    2 +-
 arch/arm64/tools/Makefile                     |   14 +-
 arch/arm64/tools/Makefile.sysreg              |   12 +
 arch/arm64/tools/gen-sysreg.awk               |    6 +-
 arch/loongarch/include/asm/kvm_host.h         |    2 +
 arch/loongarch/kvm/Kconfig                    |    1 -
 arch/mips/include/asm/kvm_host.h              |    2 +
 arch/mips/kvm/Kconfig                         |    1 -
 arch/powerpc/include/asm/kvm_host.h           |    7 +
 arch/powerpc/kvm/Kconfig                      |    4 -
 arch/riscv/include/asm/kvm_host.h             |    2 +
 arch/riscv/kvm/Kconfig                        |    1 -
 arch/s390/Kconfig                             |    2 +-
 arch/s390/boot/ipl_parm.c                     |    2 +-
 arch/s390/boot/uv.c                           |    2 +-
 arch/s390/configs/defconfig                   |    3 +-
 arch/s390/include/asm/asm-prototypes.h        |    1 +
 arch/s390/include/asm/elf.h                   |    2 +
 arch/s390/include/asm/kvm.h                   |    6 +
 arch/s390/include/asm/kvm_emulate.h           |  135 ++
 arch/s390/include/asm/kvm_host.h              |  748 +-------
 arch/s390/include/asm/kvm_host_arm64.h        |  199 ++
 arch/s390/include/asm/kvm_host_arm64_types.h  |  128 ++
 .../asm/{kvm_host.h => kvm_host_s390.h}       |   19 +-
 ...kvm_host_types.h => kvm_host_s390_types.h} |    0
 arch/s390/include/asm/kvm_mmu.h               |   12 +
 arch/s390/include/asm/kvm_nested.h            |   13 +
 arch/s390/include/asm/sae.h                   |   39 +
 arch/s390/include/asm/sclp.h                  |    5 +-
 arch/s390/include/asm/stacktrace.h            |    5 +
 arch/s390/kernel/asm-offsets.c                |    3 +-
 arch/s390/kernel/early.c                      |    2 +-
 arch/s390/kernel/entry.S                      |   34 +-
 arch/s390/kernel/perf_event.c                 |    2 +-
 arch/s390/kernel/processor.c                  |    3 +
 arch/s390/kvm/Kconfig                         |   36 +-
 arch/s390/kvm/Makefile                        |   12 +-
 arch/s390/kvm/arm64/Kconfig                   |   23 +
 arch/s390/kvm/arm64/Makefile                  |  107 ++
 arch/s390/kvm/arm64/arm.c                     |  704 +++++++
 arch/s390/kvm/arm64/arm.h                     |   61 +
 arch/s390/kvm/arm64/guest.c                   |  162 ++
 arch/s390/kvm/arm64/guest.h                   |   15 +
 arch/s390/kvm/arm64/handle_exit.c             |   52 +
 arch/s390/kvm/arm64/inject_fault.c            |   15 +
 arch/s390/kvm/arm64/mmu.c                     |  153 ++
 arch/s390/kvm/arm64/reset.c                   |   42 +
 arch/s390/kvm/arm64/reset.h                   |   11 +
 arch/s390/kvm/gmap/Makefile                   |    5 +
 arch/s390/kvm/{ => gmap}/dat.c                |    0
 arch/s390/kvm/{ => gmap}/dat.h                |    6 +-
 arch/s390/kvm/{ => gmap}/faultin.c            |   11 +-
 arch/s390/kvm/{ => gmap}/faultin.h            |    6 +-
 arch/s390/kvm/{ => gmap}/gmap.c               |   13 +-
 arch/s390/kvm/{ => gmap}/gmap.h               |   17 +-
 arch/s390/kvm/gmap/mmu.c                      |  154 ++
 arch/s390/kvm/gmap/trace-gmap.h               |   59 +
 arch/s390/kvm/{ => s390}/Kconfig              |   25 +-
 arch/s390/kvm/{ => s390}/Makefile             |   10 +-
 arch/s390/kvm/{ => s390}/diag.c               |    2 +-
 arch/s390/kvm/{ => s390}/gaccess.c            |    2 +-
 arch/s390/kvm/{ => s390}/gaccess.h            |    2 +-
 arch/s390/kvm/{ => s390}/guestdbg.c           |    2 +-
 arch/s390/kvm/{ => s390}/intercept.c          |    2 +-
 arch/s390/kvm/{ => s390}/interrupt.c          |    2 +-
 arch/s390/kvm/{ => s390}/pci.c                |    2 +-
 arch/s390/kvm/{ => s390}/pci.h                |    0
 arch/s390/kvm/{ => s390}/priv.c               |    2 +-
 arch/s390/kvm/{ => s390}/pv.c                 |    2 +-
 arch/s390/kvm/{kvm-s390.c => s390/s390.c}     |  126 +-
 arch/s390/kvm/{kvm-s390.h => s390/s390.h}     |   18 +-
 arch/s390/kvm/{ => s390}/sigp.c               |    2 +-
 arch/s390/kvm/{ => s390}/trace-s390.h         |    0
 arch/s390/kvm/{ => s390}/trace.h              |   14 -
 arch/s390/kvm/{ => s390}/vsie.c               |    2 +-
 arch/s390/tools/Makefile                      |    2 +
 arch/s390/tools/opcodes.txt                   |    3 +
 arch/x86/include/asm/kvm_host.h               |    2 +
 arch/x86/kvm/Kconfig                          |    1 -
 arch/x86/kvm/mmu/tdp_mmu.c                    |    2 +-
 arch/x86/kvm/vmx/nested.h                     |    4 +-
 drivers/s390/char/sclp_early.c                |    1 +
 drivers/vfio/device_cdev.c                    |    2 +-
 drivers/vfio/group.c                          |    5 +-
 drivers/vfio/vfio.h                           |   15 +-
 drivers/vfio/vfio_main.c                      |   49 +-
 .../arch/arm64}/asm/brk-imm.h                 |    0
 .../include => include/arch/arm64}/asm/esr.h  |   56 +-
 include/arch/arm64/asm/pstate.h               |   46 +
 .../arch/arm64/asm/sysreg-defs.h              |  344 +---
 include/kvm/arm64/guest.h                     |   13 +
 include/kvm/arm64/handle_exit.h               |   14 +
 .../asm => include/kvm/arm64}/kvm_arm.h       |    5 +-
 include/kvm/arm64/kvm_emulate.h               |  268 +++
 include/kvm/arm64/kvm_host.h                  |  205 ++
 include/kvm/arm64/kvm_mmu.h                   |   47 +
 include/kvm/arm64/reset.h                     |    8 +
 include/linux/kvm_host.h                      |   18 +-
 include/linux/kvm_types.h                     |   33 +
 include/linux/vfio.h                          |    4 +-
 include/uapi/Kbuild                           |    6 +
 .../uapi/arch/arm64}/asm/kvm.h                |   24 +-
 include/uapi/arch/arm64/asm/pstate.h          |   53 +
 .../uapi/arch/arm64}/asm/sve_context.h        |    0
 include/uapi/arch/arm64/linux/kvm.h           |    8 +
 include/uapi/linux/{kvm.h => kvm-generic.h}   |   11 +-
 include/uapi/linux/kvm.h                      | 1649 +----------------
 scripts/Makefile.asm-headers                  |   14 +-
 usr/include/Makefile                          |    1 +
 virt/kvm/Kconfig                              |    3 -
 virt/kvm/Makefile.kvm                         |    3 +-
 virt/kvm/arm64/Makefile.kvm                   |   13 +
 virt/kvm/arm64/arm.c                          |   75 +
 virt/kvm/arm64/guest.c                        |  302 +++
 virt/kvm/arm64/handle_exit.c                  |   54 +
 {arch/arm64/kvm => virt/kvm/arm64}/mmio.c     |    1 +
 virt/kvm/arm64/reset.c                        |   42 +
 virt/kvm/arm64/trace.h                        |   42 +
 virt/kvm/coalesced_mmio.c                     |    3 +
 virt/kvm/coalesced_mmio.h                     |    2 +-
 virt/kvm/kvm_main.c                           |   62 +-
 virt/kvm/vfio.c                               |   14 +-
 157 files changed, 3855 insertions(+), 5120 deletions(-)
 create mode 100644 arch/arm64/tools/Makefile.sysreg
 create mode 100644 arch/s390/include/asm/kvm.h
 create mode 100644 arch/s390/include/asm/kvm_emulate.h
 create mode 100644 arch/s390/include/asm/kvm_host_arm64.h
 create mode 100644 arch/s390/include/asm/kvm_host_arm64_types.h
 copy arch/s390/include/asm/{kvm_host.h => kvm_host_s390.h} (98%)
 rename arch/s390/include/asm/{kvm_host_types.h => kvm_host_s390_types.h} (100%)
 create mode 100644 arch/s390/include/asm/kvm_mmu.h
 create mode 100644 arch/s390/include/asm/kvm_nested.h
 create mode 100644 arch/s390/include/asm/sae.h
 create mode 100644 arch/s390/kvm/arm64/Kconfig
 create mode 100644 arch/s390/kvm/arm64/Makefile
 create mode 100644 arch/s390/kvm/arm64/arm.c
 create mode 100644 arch/s390/kvm/arm64/arm.h
 create mode 100644 arch/s390/kvm/arm64/guest.c
 create mode 100644 arch/s390/kvm/arm64/guest.h
 create mode 100644 arch/s390/kvm/arm64/handle_exit.c
 create mode 100644 arch/s390/kvm/arm64/inject_fault.c
 create mode 100644 arch/s390/kvm/arm64/mmu.c
 create mode 100644 arch/s390/kvm/arm64/reset.c
 create mode 100644 arch/s390/kvm/arm64/reset.h
 create mode 100644 arch/s390/kvm/gmap/Makefile
 rename arch/s390/kvm/{ => gmap}/dat.c (100%)
 rename arch/s390/kvm/{ => gmap}/dat.h (99%)
 rename arch/s390/kvm/{ => gmap}/faultin.c (96%)
 rename arch/s390/kvm/{ => gmap}/faultin.h (96%)
 rename arch/s390/kvm/{ => gmap}/gmap.c (99%)
 rename arch/s390/kvm/{ => gmap}/gmap.h (93%)
 create mode 100644 arch/s390/kvm/gmap/mmu.c
 create mode 100644 arch/s390/kvm/gmap/trace-gmap.h
 copy arch/s390/kvm/{ => s390}/Kconfig (62%)
 copy arch/s390/kvm/{ => s390}/Makefile (53%)
 rename arch/s390/kvm/{ => s390}/diag.c (99%)
 rename arch/s390/kvm/{ => s390}/gaccess.c (99%)
 rename arch/s390/kvm/{ => s390}/gaccess.h (99%)
 rename arch/s390/kvm/{ => s390}/guestdbg.c (99%)
 rename arch/s390/kvm/{ => s390}/intercept.c (99%)
 rename arch/s390/kvm/{ => s390}/interrupt.c (99%)
 rename arch/s390/kvm/{ => s390}/pci.c (99%)
 rename arch/s390/kvm/{ => s390}/pci.h (100%)
 rename arch/s390/kvm/{ => s390}/priv.c (99%)
 rename arch/s390/kvm/{ => s390}/pv.c (99%)
 rename arch/s390/kvm/{kvm-s390.c => s390/s390.c} (98%)
 rename arch/s390/kvm/{kvm-s390.h => s390/s390.h} (97%)
 rename arch/s390/kvm/{ => s390}/sigp.c (99%)
 rename arch/s390/kvm/{ => s390}/trace-s390.h (100%)
 rename arch/s390/kvm/{ => s390}/trace.h (97%)
 rename arch/s390/kvm/{ => s390}/vsie.c (99%)
 rename {arch/arm64/include => include/arch/arm64}/asm/brk-imm.h (100%)
 rename {arch/arm64/include => include/arch/arm64}/asm/esr.h (88%)
 create mode 100644 include/arch/arm64/asm/pstate.h
 copy arch/arm64/include/asm/sysreg.h => include/arch/arm64/asm/sysreg-defs.h (80%)
 create mode 100644 include/kvm/arm64/guest.h
 create mode 100644 include/kvm/arm64/handle_exit.h
 rename {arch/arm64/include/asm => include/kvm/arm64}/kvm_arm.h (99%)
 create mode 100644 include/kvm/arm64/kvm_emulate.h
 create mode 100644 include/kvm/arm64/kvm_host.h
 create mode 100644 include/kvm/arm64/kvm_mmu.h
 create mode 100644 include/kvm/arm64/reset.h
 rename {arch/arm64/include/uapi => include/uapi/arch/arm64}/asm/kvm.h (97%)
 create mode 100644 include/uapi/arch/arm64/asm/pstate.h
 rename {arch/arm64/include/uapi => include/uapi/arch/arm64}/asm/sve_context.h (100%)
 create mode 100644 include/uapi/arch/arm64/linux/kvm.h
 copy include/uapi/linux/{kvm.h => kvm-generic.h} (99%)
 create mode 100644 virt/kvm/arm64/Makefile.kvm
 create mode 100644 virt/kvm/arm64/arm.c
 create mode 100644 virt/kvm/arm64/guest.c
 create mode 100644 virt/kvm/arm64/handle_exit.c
 rename {arch/arm64/kvm => virt/kvm/arm64}/mmio.c (99%)
 create mode 100644 virt/kvm/arm64/reset.c
 create mode 100644 virt/kvm/arm64/trace.h


base-commit: 46b513250491a7bfc97d98791dbe6a10bcc8129d
-- 
2.51.0



^ permalink raw reply

* [PATCH v1 03/27] KVM, vfio: remove symbol_get(kvm_put_kvm) from vfio
From: Steffen Eiden @ 2026-04-02  4:20 UTC (permalink / raw)
  To: kvm, kvmarm, linux-arm-kernel, linux-kernel, linux-s390
  Cc: Andreas Grapentin, Arnd Bergmann, Catalin Marinas,
	Christian Borntraeger, Claudio Imbrenda, David Hildenbrand,
	Gautam Gala, Hendrik Brueckner, Janosch Frank, Joey Gouly,
	Marc Zyngier, Nina Schoetterl-Glausch, Oliver Upton,
	Paolo Bonzini, Suzuki K Poulose, Ulrich Weigand, Will Deacon,
	Zenghui Yu
In-Reply-To: <20260402042125.3948963-1-seiden@linux.ibm.com>

From: Paolo Bonzini <pbonzini@redhat.com>

Right now, KVM and VFIO are using symbol_get to access each other's
symbols because of a circular reference between the modules, as well
as to avoid loading them unnecessarily.

The remaining use in VFIO is for kvm_put_kvm, which is not inline
because it needs to call kvm_destroy_vm.  However, storing the
address of kvm_destroy_vm in the "struct kvm" is enough to remove
the dependency from VFIO.

This also makes it possible to direct kvm_put_kvm to different
implementations of kvm_destroy_vm.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
 drivers/vfio/vfio_main.c  | 29 +++++------------------------
 include/linux/kvm_host.h  |  1 -
 include/linux/kvm_types.h |  9 +++++++++
 include/linux/vfio.h      |  1 -
 virt/kvm/kvm_main.c       |  9 ++-------
 5 files changed, 16 insertions(+), 33 deletions(-)

diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index 42f515519d87..e9c6353c74d8 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -17,7 +17,7 @@
 #include <linux/idr.h>
 #include <linux/iommu.h>
 #if IS_ENABLED(CONFIG_KVM)
-#include <linux/kvm_host.h>
+#include <linux/kvm_types.h>
 #endif
 #include <linux/list.h>
 #include <linux/miscdevice.h>
@@ -436,9 +436,6 @@ EXPORT_SYMBOL_GPL(vfio_unregister_group_dev);
 void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm,
 			      struct module *kvm_module)
 {
-	void (*pfn)(struct kvm *kvm);
-	bool ret;
-
 	lockdep_assert_held(&device->dev_set->lock);
 
 	if (!kvm)
@@ -447,19 +444,10 @@ void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm,
 	if (!try_module_get(kvm_module))
 		return;
 
-	pfn = symbol_get(kvm_put_kvm);
-	if (WARN_ON(!pfn))
-		return;
-
-	ret = kvm_get_kvm_safe(kvm);
-	if (!ret) {
-		symbol_put(kvm_put_kvm);
-		return;
+	if (kvm_get_kvm_safe(kvm)) {
+		device->kvm = kvm;
+		device->kvm_module = kvm_module;
 	}
-
-	device->put_kvm = pfn;
-	device->kvm = kvm;
-	device->kvm_module = kvm_module;
 }
 
 void vfio_device_put_kvm(struct vfio_device *device)
@@ -469,15 +457,8 @@ void vfio_device_put_kvm(struct vfio_device *device)
 	if (!device->kvm)
 		return;
 
-	if (WARN_ON(!device->put_kvm))
-		goto clear;
-
-	device->put_kvm(device->kvm);
-	device->put_kvm = NULL;
-	symbol_put(kvm_put_kvm);
-
-clear:
 	module_put(device->kvm_module);
+	kvm_put_kvm(device->kvm);
 	device->kvm_module = NULL;
 	device->kvm = NULL;
 }
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index dc18ee99bba4..13f903993ed0 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1065,7 +1065,6 @@ static inline void kvm_irqfd_exit(void)
 int kvm_init(unsigned vcpu_size, unsigned vcpu_align, struct module *module);
 void kvm_exit(void);
 
-void kvm_put_kvm(struct kvm *kvm);
 bool file_is_kvm(struct file *file);
 void kvm_put_kvm_no_destroy(struct kvm *kvm);
 
diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h
index add7cc2016e8..aadee536771a 100644
--- a/include/linux/kvm_types.h
+++ b/include/linux/kvm_types.h
@@ -144,6 +144,7 @@ struct kvm_vcpu_stat_generic {
 
 struct kvm_refcount {
 	refcount_t users_count;
+	void (*destroy)(struct kvm *kvm);
 };
 
 static inline void kvm_get_kvm(struct kvm *kvm)
@@ -164,6 +165,14 @@ static inline bool kvm_get_kvm_safe(struct kvm *kvm)
 	return refcount_inc_not_zero(&rc->users_count);
 }
 
+static inline void kvm_put_kvm(struct kvm *kvm)
+{
+	struct kvm_refcount *rc = (struct kvm_refcount *)kvm;
+
+	if (refcount_dec_and_test(&rc->users_count))
+		rc->destroy(kvm);
+}
+
 #endif /* !__ASSEMBLER__ */
 
 #endif /* __KVM_TYPES_H__ */
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 69a8d527b0e8..5c69532d6127 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -65,7 +65,6 @@ struct vfio_device {
 	unsigned int open_count;
 	struct completion comp;
 	struct iommufd_access *iommufd_access;
-	void (*put_kvm)(struct kvm *kvm);
 	struct inode *inode;
 #if IS_ENABLED(CONFIG_IOMMUFD)
 	struct iommufd_device *iommufd_device;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index cb5e01f92503..642f9e9638cc 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -120,6 +120,7 @@ static struct dentry *kvm_debugfs_dir;
 
 static const struct file_operations stat_fops_per_vm;
 
+static void kvm_destroy_vm(struct kvm *kvm);
 static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
 			   unsigned long arg);
 #ifdef CONFIG_KVM_COMPAT
@@ -1154,6 +1155,7 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
 		goto out_err_no_irq_routing;
 
 	refcount_set(&kvm->rc.users_count, 1);
+	kvm->rc.destroy = kvm_destroy_vm;
 
 	for (i = 0; i < kvm_arch_nr_memslot_as_ids(kvm); i++) {
 		for (j = 0; j < 2; j++) {
@@ -1316,13 +1318,6 @@ static void kvm_destroy_vm(struct kvm *kvm)
 	mmdrop(mm);
 }
 
-void kvm_put_kvm(struct kvm *kvm)
-{
-	if (refcount_dec_and_test(&kvm->rc.users_count))
-		kvm_destroy_vm(kvm);
-}
-EXPORT_SYMBOL_GPL(kvm_put_kvm);
-
 /*
  * Used to put a reference that was taken on behalf of an object associated
  * with a user-visible file descriptor, e.g. a vcpu or device, if installation
-- 
2.51.0



^ permalink raw reply related

* [PATCH v1 13/27] KVM: arm64: Extract & share ipa size shift calculation
From: Steffen Eiden @ 2026-04-02  4:21 UTC (permalink / raw)
  To: kvm, kvmarm, linux-arm-kernel, linux-kernel, linux-s390
  Cc: Andreas Grapentin, Arnd Bergmann, Catalin Marinas,
	Christian Borntraeger, Claudio Imbrenda, David Hildenbrand,
	Gautam Gala, Hendrik Brueckner, Janosch Frank, Joey Gouly,
	Marc Zyngier, Nina Schoetterl-Glausch, Oliver Upton,
	Paolo Bonzini, Suzuki K Poulose, Ulrich Weigand, Will Deacon,
	Zenghui Yu
In-Reply-To: <20260402042125.3948963-1-seiden@linux.ibm.com>

Extract the ipa shift calculation from kvm_init_ipa_range into its own
function kvm_vm_type_ipa_size_shift to be shared across architectures.

User space passes a type parameter to the VM creation ioctl, indicating
the physical size of the VM. Therefore extract the ipa shift calculation
from kvm_init_ipa_range into its own function kvm_vm_type_ipa_size_shift,
so all implementers of arm64 KVM can make use of it for VM creation.

Co-developed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
 arch/arm64/kvm/mmu.c         | 18 ++++++------------
 include/kvm/arm64/kvm_host.h |  1 +
 virt/kvm/arm64/arm.c         | 21 +++++++++++++++++++++
 3 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index e19ff77b3cd5..9d71bb3627fc 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -874,27 +874,21 @@ static struct kvm_pgtable_mm_ops kvm_s2_mm_ops = {
 
 static int kvm_init_ipa_range(struct kvm_s2_mmu *mmu, unsigned long type)
 {
-	u32 kvm_ipa_limit = get_kvm_ipa_limit();
 	u64 mmfr0, mmfr1;
 	u32 phys_shift;
+	int r;
 
 	if (type & ~KVM_VM_TYPE_ARM_IPA_SIZE_MASK)
 		return -EINVAL;
 
 	phys_shift = KVM_VM_TYPE_ARM_IPA_SIZE(type);
 	if (is_protected_kvm_enabled()) {
-		phys_shift = kvm_ipa_limit;
-	} else if (phys_shift) {
-		if (phys_shift > kvm_ipa_limit ||
-		    phys_shift < ARM64_MIN_PARANGE_BITS)
-			return -EINVAL;
+		phys_shift = get_kvm_ipa_limit();
 	} else {
-		phys_shift = KVM_PHYS_SHIFT;
-		if (phys_shift > kvm_ipa_limit) {
-			pr_warn_once("%s using unsupported default IPA limit, upgrade your VMM\n",
-				     current->comm);
-			return -EINVAL;
-		}
+		r = kvm_vm_type_ipa_size_shift(type);
+		if (r < 0)
+			return r;
+		phys_shift = r;
 	}
 
 	mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
diff --git a/include/kvm/arm64/kvm_host.h b/include/kvm/arm64/kvm_host.h
index 20b824ecf16e..8c39ec485730 100644
--- a/include/kvm/arm64/kvm_host.h
+++ b/include/kvm/arm64/kvm_host.h
@@ -33,6 +33,7 @@ int kvm_vcpu_init_check_features(struct kvm_vcpu *vcpu,
 				 const struct kvm_vcpu_init *init);
 bool kvm_vcpu_init_changed(struct kvm_vcpu *vcpu,
 			   const struct kvm_vcpu_init *init);
+int kvm_vm_type_ipa_size_shift(unsigned long type);
 
 /* MMIO helpers */
 void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data);
diff --git a/virt/kvm/arm64/arm.c b/virt/kvm/arm64/arm.c
index b47adef65e5f..0bbfbe63e558 100644
--- a/virt/kvm/arm64/arm.c
+++ b/virt/kvm/arm64/arm.c
@@ -52,3 +52,24 @@ bool kvm_vcpu_init_changed(struct kvm_vcpu *vcpu,
 	return !bitmap_equal(vcpu->kvm->arch.vcpu_features, &features,
 			     KVM_VCPU_MAX_FEATURES);
 }
+
+int kvm_vm_type_ipa_size_shift(unsigned long type)
+{
+	int phys_shift;
+
+	phys_shift = KVM_VM_TYPE_ARM_IPA_SIZE(type);
+	if (phys_shift) {
+		if (phys_shift > get_kvm_ipa_limit() ||
+		    phys_shift < ARM64_MIN_PARANGE_BITS)
+			return -EINVAL;
+	} else {
+		phys_shift = KVM_PHYS_SHIFT;
+		if (phys_shift > get_kvm_ipa_limit()) {
+			pr_warn_once("%s using unsupported default IPA limit, upgrade your VMM\n",
+				     current->comm);
+			return -EINVAL;
+		}
+	}
+
+	return phys_shift;
+}
-- 
2.51.0



^ permalink raw reply related

* [PATCH v1 18/27] KVM: s390: Prepare kvm-s390 for a second kvm module
From: Steffen Eiden @ 2026-04-02  4:21 UTC (permalink / raw)
  To: kvm, kvmarm, linux-arm-kernel, linux-kernel, linux-s390
  Cc: Andreas Grapentin, Arnd Bergmann, Catalin Marinas,
	Christian Borntraeger, Claudio Imbrenda, David Hildenbrand,
	Gautam Gala, Hendrik Brueckner, Janosch Frank, Joey Gouly,
	Marc Zyngier, Nina Schoetterl-Glausch, Oliver Upton,
	Paolo Bonzini, Suzuki K Poulose, Ulrich Weigand, Will Deacon,
	Zenghui Yu
In-Reply-To: <20260402042125.3948963-1-seiden@linux.ibm.com>

The second KVM module will have a different Kconfig set.
When both modules are compiled the Kconfig sets get merged and
the native s390 KVM needs to implement functionality required by
the respective config options. Ensure that s390-KVM will still compile.

Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
 arch/s390/kvm/s390/s390.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/s390/kvm/s390/s390.c b/arch/s390/kvm/s390/s390.c
index 497abe3a83f4..8a99d6e9f7e7 100644
--- a/arch/s390/kvm/s390/s390.c
+++ b/arch/s390/kvm/s390/s390.c
@@ -5665,6 +5665,14 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
 	return gmap_unmap_gfn_range(kvm->arch.gmap, range->slot, range->start, range->end);
 }
 
+#ifdef CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE
+/* Make s390 compile if arm64-on-s390 is selected */
+int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
+{
+	return 0;
+}
+#endif /* CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE */
+
 static inline unsigned long nonhyp_mask(int i)
 {
 	unsigned int nonhyp_fai = (sclp.hmfai << i * 2) >> 30;
-- 
2.51.0



^ permalink raw reply related

* [PATCH v1 01/27] VFIO: take reference to the KVM module
From: Steffen Eiden @ 2026-04-02  4:20 UTC (permalink / raw)
  To: kvm, kvmarm, linux-arm-kernel, linux-kernel, linux-s390
  Cc: Andreas Grapentin, Arnd Bergmann, Catalin Marinas,
	Christian Borntraeger, Claudio Imbrenda, David Hildenbrand,
	Gautam Gala, Hendrik Brueckner, Janosch Frank, Joey Gouly,
	Marc Zyngier, Nina Schoetterl-Glausch, Oliver Upton,
	Paolo Bonzini, Suzuki K Poulose, Ulrich Weigand, Will Deacon,
	Zenghui Yu
In-Reply-To: <20260402042125.3948963-1-seiden@linux.ibm.com>

From: Paolo Bonzini <pbonzini@redhat.com>

VFIO is implicitly taking a reference to the KVM module between
vfio_device_get_kvm_safe and vfio_device_put_kvm, thanks to
symbol_get and symbol_put.

In preparation for removing symbol_get and symbol_put themselves
from VFIO, actually store a pointer to the KVM module and use
module_get()/module_put() to keep KVM alive.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
 drivers/vfio/device_cdev.c |  2 +-
 drivers/vfio/group.c       |  5 +++--
 drivers/vfio/vfio.h        | 15 ++++++++++-----
 drivers/vfio/vfio_main.c   | 18 +++++++++++++-----
 include/linux/vfio.h       |  3 ++-
 virt/kvm/vfio.c            | 14 ++++++++------
 6 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/drivers/vfio/device_cdev.c b/drivers/vfio/device_cdev.c
index 8ceca24ac136..a67d7215c239 100644
--- a/drivers/vfio/device_cdev.c
+++ b/drivers/vfio/device_cdev.c
@@ -56,7 +56,7 @@ int vfio_device_fops_cdev_open(struct inode *inode, struct file *filep)
 static void vfio_df_get_kvm_safe(struct vfio_device_file *df)
 {
 	spin_lock(&df->kvm_ref_lock);
-	vfio_device_get_kvm_safe(df->device, df->kvm);
+	vfio_device_get_kvm_safe(df->device, df->kvm, df->kvm_module);
 	spin_unlock(&df->kvm_ref_lock);
 }
 
diff --git a/drivers/vfio/group.c b/drivers/vfio/group.c
index 4f15016d2a5f..7d28f45fefaa 100644
--- a/drivers/vfio/group.c
+++ b/drivers/vfio/group.c
@@ -158,7 +158,7 @@ static int vfio_group_ioctl_set_container(struct vfio_group *group,
 static void vfio_device_group_get_kvm_safe(struct vfio_device *device)
 {
 	spin_lock(&device->group->kvm_ref_lock);
-	vfio_device_get_kvm_safe(device, device->group->kvm);
+	vfio_device_get_kvm_safe(device, device->group->kvm, device->group->kvm_module);
 	spin_unlock(&device->group->kvm_ref_lock);
 }
 
@@ -858,10 +858,11 @@ bool vfio_group_enforced_coherent(struct vfio_group *group)
 	return ret;
 }
 
-void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm)
+void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm, struct module *kvm_module)
 {
 	spin_lock(&group->kvm_ref_lock);
 	group->kvm = kvm;
+	group->kvm_module = kvm_module;
 	spin_unlock(&group->kvm_ref_lock);
 }
 
diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h
index 50128da18bca..a0c38f89b30a 100644
--- a/drivers/vfio/vfio.h
+++ b/drivers/vfio/vfio.h
@@ -22,8 +22,9 @@ struct vfio_device_file {
 
 	u8 access_granted;
 	u32 devid; /* only valid when iommufd is valid */
-	spinlock_t kvm_ref_lock; /* protect kvm field */
+	spinlock_t kvm_ref_lock; /* protect kvm and kvm_module fields */
 	struct kvm *kvm;
+	struct module *kvm_module;
 	struct iommufd_ctx *iommufd; /* protected by struct vfio_device_set::lock */
 };
 
@@ -89,6 +90,7 @@ struct vfio_group {
 	enum vfio_group_type		type;
 	struct mutex			group_lock;
 	struct kvm			*kvm;
+	struct module			*kvm_module;
 	struct file			*opened_file;
 	struct blocking_notifier_head	notifier;
 	struct iommufd_ctx		*iommufd;
@@ -108,7 +110,7 @@ void vfio_device_group_unuse_iommu(struct vfio_device *device);
 void vfio_df_group_close(struct vfio_device_file *df);
 struct vfio_group *vfio_group_from_file(struct file *file);
 bool vfio_group_enforced_coherent(struct vfio_group *group);
-void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm);
+void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm, struct module *kvm_module);
 bool vfio_device_has_container(struct vfio_device *device);
 int __init vfio_group_init(void);
 void vfio_group_cleanup(void);
@@ -171,7 +173,8 @@ static inline bool vfio_group_enforced_coherent(struct vfio_group *group)
 	return true;
 }
 
-static inline void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm)
+static inline void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm,
+				      struct module *kvm_module)
 {
 }
 
@@ -435,11 +438,13 @@ static inline void vfio_virqfd_exit(void)
 #endif
 
 #if IS_ENABLED(CONFIG_KVM)
-void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm);
+void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm,
+			      struct module *kvm_module);
 void vfio_device_put_kvm(struct vfio_device *device);
 #else
 static inline void vfio_device_get_kvm_safe(struct vfio_device *device,
-					    struct kvm *kvm)
+					    struct kvm *kvm,
+					    struct module *kvm_module)
 {
 }
 
diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index 742477546b15..b1b753889a77 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -433,7 +433,8 @@ void vfio_unregister_group_dev(struct vfio_device *device)
 EXPORT_SYMBOL_GPL(vfio_unregister_group_dev);
 
 #if IS_ENABLED(CONFIG_KVM)
-void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm)
+void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm,
+			      struct module *kvm_module)
 {
 	void (*pfn)(struct kvm *kvm);
 	bool (*fn)(struct kvm *kvm);
@@ -444,6 +445,9 @@ void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm)
 	if (!kvm)
 		return;
 
+	if (!try_module_get(kvm_module))
+		return;
+
 	pfn = symbol_get(kvm_put_kvm);
 	if (WARN_ON(!pfn))
 		return;
@@ -463,6 +467,7 @@ void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm)
 
 	device->put_kvm = pfn;
 	device->kvm = kvm;
+	device->kvm_module = kvm_module;
 }
 
 void vfio_device_put_kvm(struct vfio_device *device)
@@ -480,6 +485,8 @@ void vfio_device_put_kvm(struct vfio_device *device)
 	symbol_put(kvm_put_kvm);
 
 clear:
+	module_put(device->kvm_module);
+	device->kvm_module = NULL;
 	device->kvm = NULL;
 }
 #endif
@@ -1483,7 +1490,7 @@ bool vfio_file_enforced_coherent(struct file *file)
 }
 EXPORT_SYMBOL_GPL(vfio_file_enforced_coherent);
 
-static void vfio_device_file_set_kvm(struct file *file, struct kvm *kvm)
+static void vfio_device_file_set_kvm(struct file *file, struct kvm *kvm, struct module *kvm_module)
 {
 	struct vfio_device_file *df = file->private_data;
 
@@ -1494,6 +1501,7 @@ static void vfio_device_file_set_kvm(struct file *file, struct kvm *kvm)
 	 */
 	spin_lock(&df->kvm_ref_lock);
 	df->kvm = kvm;
+	df->kvm_module = kvm_module;
 	spin_unlock(&df->kvm_ref_lock);
 }
 
@@ -1505,16 +1513,16 @@ static void vfio_device_file_set_kvm(struct file *file, struct kvm *kvm)
  * When a VFIO device is first opened the KVM will be available in
  * device->kvm if one was associated with the file.
  */
-void vfio_file_set_kvm(struct file *file, struct kvm *kvm)
+void vfio_file_set_kvm(struct file *file, struct kvm *kvm, struct module *kvm_module)
 {
 	struct vfio_group *group;
 
 	group = vfio_group_from_file(file);
 	if (group)
-		vfio_group_set_kvm(group, kvm);
+		vfio_group_set_kvm(group, kvm, kvm_module);
 
 	if (vfio_device_from_file(file))
-		vfio_device_file_set_kvm(file, kvm);
+		vfio_device_file_set_kvm(file, kvm, kvm_module);
 }
 EXPORT_SYMBOL_GPL(vfio_file_set_kvm);
 
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index e90859956514..69a8d527b0e8 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -53,6 +53,7 @@ struct vfio_device {
 	struct list_head dev_set_list;
 	unsigned int migration_flags;
 	struct kvm *kvm;
+	struct module *kvm_module;
 
 	/* Members below here are private, not for driver use */
 	unsigned int index;
@@ -339,7 +340,7 @@ static inline bool vfio_file_has_dev(struct file *file, struct vfio_device *devi
 #endif
 bool vfio_file_is_valid(struct file *file);
 bool vfio_file_enforced_coherent(struct file *file);
-void vfio_file_set_kvm(struct file *file, struct kvm *kvm);
+void vfio_file_set_kvm(struct file *file, struct kvm *kvm, struct module *kvm_module);
 
 #define VFIO_PIN_PAGES_MAX_ENTRIES	(PAGE_SIZE/sizeof(unsigned long))
 
diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c
index 9f9acb66cc1e..8161229f4b86 100644
--- a/virt/kvm/vfio.c
+++ b/virt/kvm/vfio.c
@@ -35,15 +35,15 @@ struct kvm_vfio {
 	bool noncoherent;
 };
 
-static void kvm_vfio_file_set_kvm(struct file *file, struct kvm *kvm)
+static void kvm_vfio_file_set_kvm(struct file *file, struct kvm *kvm, struct module *module)
 {
-	void (*fn)(struct file *file, struct kvm *kvm);
+	void (*fn)(struct file *file, struct kvm *kvm, struct module *kvm_module);
 
 	fn = symbol_get(vfio_file_set_kvm);
 	if (!fn)
 		return;
 
-	fn(file, kvm);
+	fn(file, kvm, module);
 
 	symbol_put(vfio_file_set_kvm);
 }
@@ -142,6 +142,7 @@ static void kvm_vfio_update_coherency(struct kvm_device *dev)
 
 static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)
 {
+	struct module *module;
 	struct kvm_vfio *kv = dev->private;
 	struct kvm_vfio_file *kvf;
 	struct file *filp;
@@ -157,6 +158,7 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)
 		goto out_fput;
 	}
 
+	module = filp->f_op->owner;
 	mutex_lock(&kv->lock);
 
 	list_for_each_entry(kvf, &kv->file_list, node) {
@@ -175,7 +177,7 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd)
 	kvf->file = get_file(filp);
 	list_add_tail(&kvf->node, &kv->file_list);
 
-	kvm_vfio_file_set_kvm(kvf->file, dev->kvm);
+	kvm_vfio_file_set_kvm(kvf->file, dev->kvm, module);
 	kvm_vfio_update_coherency(dev);
 
 out_unlock:
@@ -207,7 +209,7 @@ static int kvm_vfio_file_del(struct kvm_device *dev, unsigned int fd)
 #ifdef CONFIG_SPAPR_TCE_IOMMU
 		kvm_spapr_tce_release_vfio_group(dev->kvm, kvf);
 #endif
-		kvm_vfio_file_set_kvm(kvf->file, NULL);
+		kvm_vfio_file_set_kvm(kvf->file, NULL, NULL);
 		fput(kvf->file);
 		kfree(kvf);
 		ret = 0;
@@ -330,7 +332,7 @@ static void kvm_vfio_release(struct kvm_device *dev)
 #ifdef CONFIG_SPAPR_TCE_IOMMU
 		kvm_spapr_tce_release_vfio_group(dev->kvm, kvf);
 #endif
-		kvm_vfio_file_set_kvm(kvf->file, NULL);
+		kvm_vfio_file_set_kvm(kvf->file, NULL, NULL);
 		fput(kvf->file);
 		list_del(&kvf->node);
 		kfree(kvf);
-- 
2.51.0



^ permalink raw reply related

* [PATCH v1 16/27] KVM: Make device name configurable
From: Steffen Eiden @ 2026-04-02  4:21 UTC (permalink / raw)
  To: kvm, kvmarm, linux-arm-kernel, linux-kernel, linux-s390
  Cc: Andreas Grapentin, Arnd Bergmann, Catalin Marinas,
	Christian Borntraeger, Claudio Imbrenda, David Hildenbrand,
	Gautam Gala, Hendrik Brueckner, Janosch Frank, Joey Gouly,
	Marc Zyngier, Nina Schoetterl-Glausch, Oliver Upton,
	Paolo Bonzini, Suzuki K Poulose, Ulrich Weigand, Will Deacon,
	Zenghui Yu
In-Reply-To: <20260402042125.3948963-1-seiden@linux.ibm.com>

Allow KVM implementations to choose alternative device names. This is
especially useful for architectures providing multiple KVM
implementations simultaneously.

Co-developed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
 include/linux/kvm_host.h |  4 +++-
 virt/kvm/kvm_main.c      | 21 ++++++++++++++-------
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index ff2aff71e207..d5d9757e40ca 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1062,7 +1062,9 @@ static inline void kvm_irqfd_exit(void)
 {
 }
 #endif
-int kvm_init(unsigned vcpu_size, unsigned vcpu_align, struct module *module);
+int kvm_init(unsigned int vcpu_size, unsigned int vcpu_align, struct module *module);
+int kvm_init_with_dev(unsigned int vcpu_size, unsigned int vcpu_align,
+		      struct module *module, const char *dev_name, int minor);
 void kvm_exit(void);
 
 bool file_is_kvm(struct file *file);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 642f9e9638cc..d05e2c1e6fb0 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -5547,9 +5547,7 @@ static struct file_operations kvm_chardev_ops = {
 };
 
 static struct miscdevice kvm_dev = {
-	KVM_MINOR,
-	"kvm",
-	&kvm_chardev_ops,
+	.fops = &kvm_chardev_ops,
 };
 
 #ifdef CONFIG_KVM_GENERIC_HARDWARE_ENABLING
@@ -6321,13 +6319,13 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm)
 	kfree(env);
 }
 
-static void kvm_init_debug(void)
+static void kvm_init_debug(const char *dev_name)
 {
 	const struct file_operations *fops;
 	const struct kvm_stats_desc *pdesc;
 	int i;
 
-	kvm_debugfs_dir = debugfs_create_dir("kvm", NULL);
+	kvm_debugfs_dir = debugfs_create_dir(dev_name, NULL);
 
 	for (i = 0; i < kvm_vm_stats_header.num_desc; ++i) {
 		pdesc = &kvm_vm_stats_desc[i];
@@ -6463,11 +6461,20 @@ void kvm_unregister_perf_callbacks(void)
 }
 #endif
 
-int kvm_init(unsigned vcpu_size, unsigned vcpu_align, struct module *module)
+int kvm_init(unsigned int vcpu_size, unsigned int vcpu_align, struct module *module)
+{
+	return kvm_init_with_dev(vcpu_size, vcpu_align, module, "kvm", KVM_MINOR);
+}
+
+int kvm_init_with_dev(unsigned int vcpu_size, unsigned int vcpu_align,
+		      struct module *module, const char *dev_name, int minor)
 {
 	int r;
 	int cpu;
 
+	kvm_dev.name = dev_name;
+	kvm_dev.minor = minor;
+
 	/* A kmem cache lets us meet the alignment requirements of fx_save. */
 	if (!vcpu_align)
 		vcpu_align = __alignof__(struct kvm_vcpu);
@@ -6505,7 +6512,7 @@ int kvm_init(unsigned vcpu_size, unsigned vcpu_align, struct module *module)
 	kvm_preempt_ops.sched_in = kvm_sched_in;
 	kvm_preempt_ops.sched_out = kvm_sched_out;
 
-	kvm_init_debug();
+	kvm_init_debug(kvm_dev.name);
 
 	r = kvm_vfio_ops_init();
 	if (WARN_ON_ONCE(r))
-- 
2.51.0



^ permalink raw reply related

* [PATCH v1 08/27] arm64: Extract pstate definitions from ptrace
From: Steffen Eiden @ 2026-04-02  4:21 UTC (permalink / raw)
  To: kvm, kvmarm, linux-arm-kernel, linux-kernel, linux-s390
  Cc: Andreas Grapentin, Arnd Bergmann, Catalin Marinas,
	Christian Borntraeger, Claudio Imbrenda, David Hildenbrand,
	Gautam Gala, Hendrik Brueckner, Janosch Frank, Joey Gouly,
	Marc Zyngier, Nina Schoetterl-Glausch, Oliver Upton,
	Paolo Bonzini, Suzuki K Poulose, Ulrich Weigand, Will Deacon,
	Zenghui Yu
In-Reply-To: <20260402042125.3948963-1-seiden@linux.ibm.com>

From: Nina Schoetterl-Glausch <nsg@linux.ibm.com>

Split all definitions that can be used by non-native architectures into a
separate file pstate.h. This allows other architectures using
the pstate definitions. While at it refactor SPSR related definitions
to use the BIT(n) macro and move them into sysreg-defs.h

Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
 arch/arm64/include/asm/ptrace.h      | 34 +-----------------
 arch/arm64/include/uapi/asm/Kbuild   |  1 +
 arch/arm64/include/uapi/asm/ptrace.h | 49 +------------------------
 include/arch/arm64/asm/pstate.h      | 46 ++++++++++++++++++++++++
 include/arch/arm64/asm/sysreg-defs.h | 42 ++++++++++++++++++++++
 include/uapi/arch/arm64/asm/pstate.h | 53 ++++++++++++++++++++++++++++
 6 files changed, 144 insertions(+), 81 deletions(-)
 create mode 100644 include/arch/arm64/asm/pstate.h
 create mode 100644 include/uapi/arch/arm64/asm/pstate.h

diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 39582511ad72..72ea0a8af960 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -9,6 +9,7 @@
 #define __ASM_PTRACE_H
 
 #include <asm/cpufeature.h>
+#include <asm/pstate.h>
 
 #include <uapi/asm/ptrace.h>
 
@@ -28,10 +29,6 @@
 
 #define GIC_PRIO_PSR_I_SET	GICV3_PRIO_PSR_I_SET
 
-/* Additional SPSR bits not exposed in the UABI */
-#define PSR_MODE_THREAD_BIT	(1 << 0)
-#define PSR_IL_BIT		(1 << 20)
-
 /* AArch32-specific ptrace requests */
 #define COMPAT_PTRACE_GETREGS		12
 #define COMPAT_PTRACE_SETREGS		13
@@ -42,41 +39,12 @@
 #define COMPAT_PTRACE_GETHBPREGS	29
 #define COMPAT_PTRACE_SETHBPREGS	30
 
-/* SPSR_ELx bits for exceptions taken from AArch32 */
-#define PSR_AA32_MODE_MASK	0x0000001f
-#define PSR_AA32_MODE_USR	0x00000010
-#define PSR_AA32_MODE_FIQ	0x00000011
-#define PSR_AA32_MODE_IRQ	0x00000012
-#define PSR_AA32_MODE_SVC	0x00000013
-#define PSR_AA32_MODE_ABT	0x00000017
-#define PSR_AA32_MODE_HYP	0x0000001a
-#define PSR_AA32_MODE_UND	0x0000001b
-#define PSR_AA32_MODE_SYS	0x0000001f
-#define PSR_AA32_T_BIT		0x00000020
-#define PSR_AA32_F_BIT		0x00000040
-#define PSR_AA32_I_BIT		0x00000080
-#define PSR_AA32_A_BIT		0x00000100
-#define PSR_AA32_E_BIT		0x00000200
-#define PSR_AA32_PAN_BIT	0x00400000
-#define PSR_AA32_SSBS_BIT	0x00800000
-#define PSR_AA32_DIT_BIT	0x01000000
-#define PSR_AA32_Q_BIT		0x08000000
-#define PSR_AA32_V_BIT		0x10000000
-#define PSR_AA32_C_BIT		0x20000000
-#define PSR_AA32_Z_BIT		0x40000000
-#define PSR_AA32_N_BIT		0x80000000
-#define PSR_AA32_IT_MASK	0x0600fc00	/* If-Then execution state mask */
-#define PSR_AA32_GE_MASK	0x000f0000
-
 #ifdef CONFIG_CPU_BIG_ENDIAN
 #define PSR_AA32_ENDSTATE	PSR_AA32_E_BIT
 #else
 #define PSR_AA32_ENDSTATE	0
 #endif
 
-/* AArch32 CPSR bits, as seen in AArch32 */
-#define COMPAT_PSR_DIT_BIT	0x00200000
-
 /*
  * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
  * process is located in memory.
diff --git a/arch/arm64/include/uapi/asm/Kbuild b/arch/arm64/include/uapi/asm/Kbuild
index b45584e83448..43d1a8ab98e1 100644
--- a/arch/arm64/include/uapi/asm/Kbuild
+++ b/arch/arm64/include/uapi/asm/Kbuild
@@ -5,3 +5,4 @@ generic-y += kvm_para.h
 
 shared-uapi-y += kvm.h
 shared-uapi-y += sve_context.h
+shared-uapi-y += pstate.h
diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index 6fed93fb2536..6e743eb021e8 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -24,54 +24,7 @@
 
 #include <asm/hwcap.h>
 #include <asm/sve_context.h>
-
-
-/*
- * PSR bits
- */
-#define PSR_MODE_EL0t	0x00000000
-#define PSR_MODE_EL1t	0x00000004
-#define PSR_MODE_EL1h	0x00000005
-#define PSR_MODE_EL2t	0x00000008
-#define PSR_MODE_EL2h	0x00000009
-#define PSR_MODE_EL3t	0x0000000c
-#define PSR_MODE_EL3h	0x0000000d
-#define PSR_MODE_MASK	0x0000000f
-
-/* AArch32 CPSR bits */
-#define PSR_MODE32_BIT		0x00000010
-
-/* AArch64 SPSR bits */
-#define PSR_F_BIT	0x00000040
-#define PSR_I_BIT	0x00000080
-#define PSR_A_BIT	0x00000100
-#define PSR_D_BIT	0x00000200
-#define PSR_BTYPE_MASK	0x00000c00
-#define PSR_SSBS_BIT	0x00001000
-#define PSR_PAN_BIT	0x00400000
-#define PSR_UAO_BIT	0x00800000
-#define PSR_DIT_BIT	0x01000000
-#define PSR_TCO_BIT	0x02000000
-#define PSR_V_BIT	0x10000000
-#define PSR_C_BIT	0x20000000
-#define PSR_Z_BIT	0x40000000
-#define PSR_N_BIT	0x80000000
-
-#define PSR_BTYPE_SHIFT		10
-
-/*
- * Groups of PSR bits
- */
-#define PSR_f		0xff000000	/* Flags		*/
-#define PSR_s		0x00ff0000	/* Status		*/
-#define PSR_x		0x0000ff00	/* Extension		*/
-#define PSR_c		0x000000ff	/* Control		*/
-
-/* Convenience names for the values of PSTATE.BTYPE */
-#define PSR_BTYPE_NONE		(0b00 << PSR_BTYPE_SHIFT)
-#define PSR_BTYPE_JC		(0b01 << PSR_BTYPE_SHIFT)
-#define PSR_BTYPE_C		(0b10 << PSR_BTYPE_SHIFT)
-#define PSR_BTYPE_J		(0b11 << PSR_BTYPE_SHIFT)
+#include <asm/pstate.h>
 
 /* syscall emulation path in ptrace */
 #define PTRACE_SYSEMU		  31
diff --git a/include/arch/arm64/asm/pstate.h b/include/arch/arm64/asm/pstate.h
new file mode 100644
index 000000000000..3ff6073a0eaa
--- /dev/null
+++ b/include/arch/arm64/asm/pstate.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __ASM_PSTATE_H
+#define __ASM_PSTATE_H
+
+#include <asm/sysreg-defs.h>
+#ifdef __arm64__
+#include <uapi/asm/pstate.h>
+#else
+#include <uapi/arch/arm64/asm/pstate.h>
+#endif // __arm64__
+
+/* Additional SPSR bits not exposed in the UABI */
+#define PSR_MODE_THREAD_BIT	BIT(0)
+#define PSR_IL_BIT		SPSR_IL
+
+/* SPSR_ELx bits for exceptions taken from AArch32 */
+#define PSR_AA32_MODE_MASK	SPSR_MODE_MASK
+#define PSR_AA32_MODE_USR	(SPSR_MODE_32BIT | SPSR32_MODE_USR)
+#define PSR_AA32_MODE_FIQ	(SPSR_MODE_32BIT | SPSR32_MODE_FIQ)
+#define PSR_AA32_MODE_IRQ	(SPSR_MODE_32BIT | SPSR32_MODE_IRQ)
+#define PSR_AA32_MODE_SVC	(SPSR_MODE_32BIT | SPSR32_MODE_SVC)
+#define PSR_AA32_MODE_ABT	(SPSR_MODE_32BIT | SPSR32_MODE_ABT)
+#define PSR_AA32_MODE_HYP	(SPSR_MODE_32BIT | SPSR32_MODE_HYP)
+#define PSR_AA32_MODE_UND	(SPSR_MODE_32BIT | SPSR32_MODE_UND)
+#define PSR_AA32_MODE_SYS	(SPSR_MODE_32BIT | SPSR32_MODE_SYS)
+#define PSR_AA32_T_BIT		SPSR32_T
+#define PSR_AA32_F_BIT		SPSR_F
+#define PSR_AA32_I_BIT		SPSR_I
+#define PSR_AA32_A_BIT		SPSR_A
+#define PSR_AA32_E_BIT		SPSR32_E
+#define PSR_AA32_PAN_BIT	SPSR_PAN
+#define PSR_AA32_SSBS_BIT	SPSR32_SSBS
+#define PSR_AA32_DIT_BIT	SPSR_DIT
+#define PSR_AA32_Q_BIT		SPSR32_Q
+#define PSR_AA32_V_BIT		SPSR_V
+#define PSR_AA32_C_BIT		SPSR_C
+#define PSR_AA32_Z_BIT		SPSR_Z
+#define PSR_AA32_N_BIT		SPSR_N
+#define PSR_AA32_IT_MASK	SPSR32_IT_MASK	/* If-Then execution state mask */
+#define PSR_AA32_GE_MASK	SPSR32_GE_MASK
+
+/* AArch32 CPSR bits, as seen in AArch32 */
+#define COMPAT_PSR_DIT_BIT	0x00200000
+
+#endif /* __ASM_PSTATE_H */
diff --git a/include/arch/arm64/asm/sysreg-defs.h b/include/arch/arm64/asm/sysreg-defs.h
index d5196f293e19..4460fae38623 100644
--- a/include/arch/arm64/asm/sysreg-defs.h
+++ b/include/arch/arm64/asm/sysreg-defs.h
@@ -470,6 +470,48 @@
 #define SYS_FPEXC32_EL2			sys_reg(3, 4, 5, 3, 0)
 #define SYS_TFSR_EL2			sys_reg(3, 4, 5, 6, 0)
 
+#define SPSR_PPEND			BIT(33)
+#define SPSR_N				BIT(31)
+#define SPSR_Z				BIT(30)
+#define SPSR_C				BIT(29)
+#define SPSR_V				BIT(28)
+#define SPSR32_Q			BIT(27)
+#define SPSR32_IT_MASK			(GENMASK(26, 25) | GENMASK(15, 10))
+#define SPSR64_TCO			BIT(25)
+#define SPSR_DIT			BIT(24)
+#define SPSR64_UAO			BIT(23)
+#define SPSR32_SSBS			BIT(23)
+#define SPSR_PAN			BIT(22)
+#define SPSR_SS				BIT(21)
+#define SPSR_IL				BIT(20)
+#define SPSR32_GE_MASK			GENMASK(19, 16)
+#define SPSR64_SSBS			BIT(12)
+#define SPSR64_BTYPE_SHIFT		10
+#define SPSR64_BTYPE_MASK		(UL(3) << SPSR64_BTYPE_SHIFT)
+#define SPSR64_D			BIT(9)
+#define SPSR32_E			BIT(9)
+#define SPSR_A				BIT(8)
+#define SPSR_I				BIT(7)
+#define SPSR_F				BIT(6)
+#define SPSR32_T			BIT(5)
+#define SPSR_MODE_MASK			UL(0x1f)
+#define SPSR_MODE_32BIT			BIT(4)
+#define SPSR64_MODE_EL0			UL(0x0)
+#define SPSR64_MODE_EL1t		UL(0x4)
+#define SPSR64_MODE_EL1h		UL(0x5)
+#define SPSR64_MODE_EL2t		UL(0x8)
+#define SPSR64_MODE_EL2h		UL(0x9)
+#define SPSR64_MODE_EL3t		UL(0xc)
+#define SPSR64_MODE_EL3h		UL(0xd)
+#define SPSR32_MODE_USR			UL(0x0)
+#define SPSR32_MODE_FIQ			UL(0x1)
+#define SPSR32_MODE_IRQ			UL(0x2)
+#define SPSR32_MODE_SVC			UL(0x3)
+#define SPSR32_MODE_ABT			UL(0x7)
+#define SPSR32_MODE_HYP			UL(0xa)
+#define SPSR32_MODE_UND			UL(0xb)
+#define SPSR32_MODE_SYS			UL(0xf)
+
 #define SYS_FAR_EL2			sys_reg(3, 4, 6, 0, 0)
 #define SYS_HPFAR_EL2			sys_reg(3, 4, 6, 0, 4)
 
diff --git a/include/uapi/arch/arm64/asm/pstate.h b/include/uapi/arch/arm64/asm/pstate.h
new file mode 100644
index 000000000000..87b2acec9ac2
--- /dev/null
+++ b/include/uapi/arch/arm64/asm/pstate.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+
+#ifndef _UAPI__ASM_PSTATE_H
+#define _UAPI__ASM_PSTATE_H
+
+/*
+ * PSR bits
+ */
+#define PSR_MODE_EL0t  0x00000000
+#define PSR_MODE_EL1t  0x00000004
+#define PSR_MODE_EL1h  0x00000005
+#define PSR_MODE_EL2t  0x00000008
+#define PSR_MODE_EL2h  0x00000009
+#define PSR_MODE_EL3t  0x0000000c
+#define PSR_MODE_EL3h  0x0000000d
+#define PSR_MODE_MASK  0x0000000f
+
+/* AArch32 CPSR bits */
+#define PSR_MODE32_BIT         0x00000010
+
+/* AArch64 SPSR bits */
+#define PSR_F_BIT      0x00000040
+#define PSR_I_BIT      0x00000080
+#define PSR_A_BIT      0x00000100
+#define PSR_D_BIT      0x00000200
+#define PSR_BTYPE_MASK 0x00000c00
+#define PSR_SSBS_BIT   0x00001000
+#define PSR_PAN_BIT    0x00400000
+#define PSR_UAO_BIT    0x00800000
+#define PSR_DIT_BIT    0x01000000
+#define PSR_TCO_BIT    0x02000000
+#define PSR_V_BIT      0x10000000
+#define PSR_C_BIT      0x20000000
+#define PSR_Z_BIT      0x40000000
+#define PSR_N_BIT      0x80000000
+
+#define PSR_BTYPE_SHIFT                10
+
+/*
+ * Groups of PSR bits
+ */
+#define PSR_f          0xff000000      /* Flags                */
+#define PSR_s          0x00ff0000      /* Status               */
+#define PSR_x          0x0000ff00      /* Extension            */
+#define PSR_c          0x000000ff      /* Control              */
+
+/* Convenience names for the values of PSTATE.BTYPE */
+#define PSR_BTYPE_NONE         (0b00 << PSR_BTYPE_SHIFT)
+#define PSR_BTYPE_JC           (0b01 << PSR_BTYPE_SHIFT)
+#define PSR_BTYPE_C            (0b10 << PSR_BTYPE_SHIFT)
+#define PSR_BTYPE_J            (0b11 << PSR_BTYPE_SHIFT)
+
+#endif /* _UAPI__ASM_PSTATE_H */
-- 
2.51.0



^ permalink raw reply related

* [PATCH v1 09/27] KVM: arm64: Share kvm_emulate definitions
From: Steffen Eiden @ 2026-04-02  4:21 UTC (permalink / raw)
  To: kvm, kvmarm, linux-arm-kernel, linux-kernel, linux-s390
  Cc: Andreas Grapentin, Arnd Bergmann, Catalin Marinas,
	Christian Borntraeger, Claudio Imbrenda, David Hildenbrand,
	Gautam Gala, Hendrik Brueckner, Janosch Frank, Joey Gouly,
	Marc Zyngier, Nina Schoetterl-Glausch, Oliver Upton,
	Paolo Bonzini, Suzuki K Poulose, Ulrich Weigand, Will Deacon,
	Zenghui Yu
In-Reply-To: <20260402042125.3948963-1-seiden@linux.ibm.com>

Move functions and definitions useful for emulating arm64 instructions
to include/kvm/arm64.

Co-developed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
 arch/arm64/include/asm/kvm_emulate.h       | 235 +-----------------
 arch/arm64/kvm/hyp/include/hyp/adjust_pc.h |  13 -
 include/kvm/arm64/kvm_emulate.h            | 268 +++++++++++++++++++++
 3 files changed, 269 insertions(+), 247 deletions(-)
 create mode 100644 include/kvm/arm64/kvm_emulate.h

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 822f6077b107..39fa3a12730c 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -23,18 +23,7 @@
 #include <asm/virt.h>
 
 #include <kvm/arm64/kvm_arm.h>
-
-#define CURRENT_EL_SP_EL0_VECTOR	0x0
-#define CURRENT_EL_SP_ELx_VECTOR	0x200
-#define LOWER_EL_AArch64_VECTOR		0x400
-#define LOWER_EL_AArch32_VECTOR		0x600
-
-enum exception_type {
-	except_type_sync	= 0,
-	except_type_irq		= 0x80,
-	except_type_fiq		= 0x100,
-	except_type_serror	= 0x180,
-};
+#include <kvm/arm64/kvm_emulate.h>
 
 #define kvm_exception_type_names		\
 	{ except_type_sync,	"SYNC"   },	\
@@ -45,36 +34,8 @@ enum exception_type {
 bool kvm_condition_valid32(const struct kvm_vcpu *vcpu);
 void kvm_skip_instr32(struct kvm_vcpu *vcpu);
 
-void kvm_inject_undefined(struct kvm_vcpu *vcpu);
 void kvm_inject_sync(struct kvm_vcpu *vcpu, u64 esr);
-int kvm_inject_serror_esr(struct kvm_vcpu *vcpu, u64 esr);
-int kvm_inject_sea(struct kvm_vcpu *vcpu, bool iabt, u64 addr);
 int kvm_inject_dabt_excl_atomic(struct kvm_vcpu *vcpu, u64 addr);
-void kvm_inject_size_fault(struct kvm_vcpu *vcpu);
-
-static inline int kvm_inject_sea_dabt(struct kvm_vcpu *vcpu, u64 addr)
-{
-	return kvm_inject_sea(vcpu, false, addr);
-}
-
-static inline int kvm_inject_sea_iabt(struct kvm_vcpu *vcpu, u64 addr)
-{
-	return kvm_inject_sea(vcpu, true, addr);
-}
-
-static inline int kvm_inject_serror(struct kvm_vcpu *vcpu)
-{
-	/*
-	 * ESR_ELx.ISV (later renamed to IDS) indicates whether or not
-	 * ESR_ELx.ISS contains IMPLEMENTATION DEFINED syndrome information.
-	 *
-	 * Set the bit when injecting an SError w/o an ESR to indicate ISS
-	 * does not follow the architected format.
-	 */
-	return kvm_inject_serror_esr(vcpu, ESR_ELx_ISV);
-}
-
-void kvm_vcpu_wfi(struct kvm_vcpu *vcpu);
 
 void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu);
 int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2);
@@ -160,24 +121,6 @@ static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
 	*vcpu_cpsr(vcpu) |= PSR_AA32_T_BIT;
 }
 
-/*
- * vcpu_get_reg and vcpu_set_reg should always be passed a register number
- * coming from a read of ESR_EL2. Otherwise, it may give the wrong result on
- * AArch32 with banked registers.
- */
-static __always_inline unsigned long vcpu_get_reg(const struct kvm_vcpu *vcpu,
-					 u8 reg_num)
-{
-	return (reg_num == 31) ? 0 : vcpu_gp_regs(vcpu)->regs[reg_num];
-}
-
-static __always_inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,
-				unsigned long val)
-{
-	if (reg_num != 31)
-		vcpu_gp_regs(vcpu)->regs[reg_num] = val;
-}
-
 static inline bool vcpu_is_el2_ctxt(const struct kvm_cpu_context *ctxt)
 {
 	switch (ctxt->regs.pstate & (PSR_MODE32_BIT | PSR_MODE_MASK)) {
@@ -361,82 +304,11 @@ static inline u64 kvm_vcpu_get_disr(const struct kvm_vcpu *vcpu)
 	return vcpu->arch.fault.disr_el1;
 }
 
-static inline u32 kvm_vcpu_hvc_get_imm(const struct kvm_vcpu *vcpu)
-{
-	return kvm_vcpu_get_esr(vcpu) & ESR_ELx_xVC_IMM_MASK;
-}
-
-static __always_inline bool kvm_vcpu_dabt_isvalid(const struct kvm_vcpu *vcpu)
-{
-	return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_ISV);
-}
-
 static inline unsigned long kvm_vcpu_dabt_iss_nisv_sanitized(const struct kvm_vcpu *vcpu)
 {
 	return kvm_vcpu_get_esr(vcpu) & (ESR_ELx_CM | ESR_ELx_WNR | ESR_ELx_FSC);
 }
 
-static inline bool kvm_vcpu_dabt_issext(const struct kvm_vcpu *vcpu)
-{
-	return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_SSE);
-}
-
-static inline bool kvm_vcpu_dabt_issf(const struct kvm_vcpu *vcpu)
-{
-	return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_SF);
-}
-
-static __always_inline int kvm_vcpu_dabt_get_rd(const struct kvm_vcpu *vcpu)
-{
-	return (kvm_vcpu_get_esr(vcpu) & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT;
-}
-
-static __always_inline bool kvm_vcpu_abt_iss1tw(const struct kvm_vcpu *vcpu)
-{
-	return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_S1PTW);
-}
-
-/* Always check for S1PTW *before* using this. */
-static __always_inline bool kvm_vcpu_dabt_iswrite(const struct kvm_vcpu *vcpu)
-{
-	return kvm_vcpu_get_esr(vcpu) & ESR_ELx_WNR;
-}
-
-static inline bool kvm_vcpu_dabt_is_cm(const struct kvm_vcpu *vcpu)
-{
-	return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_CM);
-}
-
-static __always_inline unsigned int kvm_vcpu_dabt_get_as(const struct kvm_vcpu *vcpu)
-{
-	return 1 << ((kvm_vcpu_get_esr(vcpu) & ESR_ELx_SAS) >> ESR_ELx_SAS_SHIFT);
-}
-
-/* This one is not specific to Data Abort */
-static __always_inline bool kvm_vcpu_trap_il_is32bit(const struct kvm_vcpu *vcpu)
-{
-	return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_IL);
-}
-
-static __always_inline u8 kvm_vcpu_trap_get_class(const struct kvm_vcpu *vcpu)
-{
-	return ESR_ELx_EC(kvm_vcpu_get_esr(vcpu));
-}
-
-static inline bool kvm_vcpu_trap_is_iabt(const struct kvm_vcpu *vcpu)
-{
-	return kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_IABT_LOW;
-}
-
-static inline bool kvm_vcpu_trap_is_exec_fault(const struct kvm_vcpu *vcpu)
-{
-	return kvm_vcpu_trap_is_iabt(vcpu) && !kvm_vcpu_abt_iss1tw(vcpu);
-}
-
-static __always_inline u8 kvm_vcpu_trap_get_fault(const struct kvm_vcpu *vcpu)
-{
-	return kvm_vcpu_get_esr(vcpu) & ESR_ELx_FSC;
-}
 
 static inline
 bool kvm_vcpu_trap_is_permission_fault(const struct kvm_vcpu *vcpu)
@@ -472,36 +344,6 @@ static __always_inline bool kvm_vcpu_abt_issea(const struct kvm_vcpu *vcpu)
 	}
 }
 
-static __always_inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu)
-{
-	u64 esr = kvm_vcpu_get_esr(vcpu);
-	return ESR_ELx_SYS64_ISS_RT(esr);
-}
-
-static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
-{
-	if (kvm_vcpu_abt_iss1tw(vcpu)) {
-		/*
-		 * Only a permission fault on a S1PTW should be
-		 * considered as a write. Otherwise, page tables baked
-		 * in a read-only memslot will result in an exception
-		 * being delivered in the guest.
-		 *
-		 * The drawback is that we end-up faulting twice if the
-		 * guest is using any of HW AF/DB: a translation fault
-		 * to map the page containing the PT (read only at
-		 * first), then a permission fault to allow the flags
-		 * to be set.
-		 */
-		return kvm_vcpu_trap_is_permission_fault(vcpu);
-	}
-
-	if (kvm_vcpu_trap_is_iabt(vcpu))
-		return false;
-
-	return kvm_vcpu_dabt_iswrite(vcpu);
-}
-
 static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu)
 {
 	return __vcpu_sys_reg(vcpu, MPIDR_EL1) & MPIDR_HWID_BITMASK;
@@ -537,81 +379,6 @@ static inline bool kvm_vcpu_is_be(struct kvm_vcpu *vcpu)
 	return vcpu_read_sys_reg(vcpu, r) & bit;
 }
 
-static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu,
-						    unsigned long data,
-						    unsigned int len)
-{
-	if (kvm_vcpu_is_be(vcpu)) {
-		switch (len) {
-		case 1:
-			return data & 0xff;
-		case 2:
-			return be16_to_cpu(data & 0xffff);
-		case 4:
-			return be32_to_cpu(data & 0xffffffff);
-		default:
-			return be64_to_cpu(data);
-		}
-	} else {
-		switch (len) {
-		case 1:
-			return data & 0xff;
-		case 2:
-			return le16_to_cpu(data & 0xffff);
-		case 4:
-			return le32_to_cpu(data & 0xffffffff);
-		default:
-			return le64_to_cpu(data);
-		}
-	}
-
-	return data;		/* Leave LE untouched */
-}
-
-static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu,
-						    unsigned long data,
-						    unsigned int len)
-{
-	if (kvm_vcpu_is_be(vcpu)) {
-		switch (len) {
-		case 1:
-			return data & 0xff;
-		case 2:
-			return cpu_to_be16(data & 0xffff);
-		case 4:
-			return cpu_to_be32(data & 0xffffffff);
-		default:
-			return cpu_to_be64(data);
-		}
-	} else {
-		switch (len) {
-		case 1:
-			return data & 0xff;
-		case 2:
-			return cpu_to_le16(data & 0xffff);
-		case 4:
-			return cpu_to_le32(data & 0xffffffff);
-		default:
-			return cpu_to_le64(data);
-		}
-	}
-
-	return data;		/* Leave LE untouched */
-}
-
-static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
-{
-	WARN_ON(vcpu_get_flag(vcpu, PENDING_EXCEPTION));
-	vcpu_set_flag(vcpu, INCREMENT_PC);
-}
-
-#define kvm_pend_exception(v, e)					\
-	do {								\
-		WARN_ON(vcpu_get_flag((v), INCREMENT_PC));		\
-		vcpu_set_flag((v), PENDING_EXCEPTION);			\
-		vcpu_set_flag((v), e);					\
-	} while (0)
-
 /*
  * Returns a 'sanitised' view of CPTR_EL2, translating from nVHE to the VHE
  * format if E2H isn't set.
diff --git a/arch/arm64/kvm/hyp/include/hyp/adjust_pc.h b/arch/arm64/kvm/hyp/include/hyp/adjust_pc.h
index 4fdfeabefeb4..15e1e5db73e1 100644
--- a/arch/arm64/kvm/hyp/include/hyp/adjust_pc.h
+++ b/arch/arm64/kvm/hyp/include/hyp/adjust_pc.h
@@ -13,19 +13,6 @@
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_host.h>
 
-static inline void kvm_skip_instr(struct kvm_vcpu *vcpu)
-{
-	if (vcpu_mode_is_32bit(vcpu)) {
-		kvm_skip_instr32(vcpu);
-	} else {
-		*vcpu_pc(vcpu) += 4;
-		*vcpu_cpsr(vcpu) &= ~PSR_BTYPE_MASK;
-	}
-
-	/* advance the singlestep state machine */
-	*vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;
-}
-
 /*
  * Skip an instruction which has been emulated at hyp while most guest sysregs
  * are live.
diff --git a/include/kvm/arm64/kvm_emulate.h b/include/kvm/arm64/kvm_emulate.h
new file mode 100644
index 000000000000..25322b95af21
--- /dev/null
+++ b/include/kvm/arm64/kvm_emulate.h
@@ -0,0 +1,268 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef KVM_ARM64_KVM_EMULATE_H
+#define KVM_ARM64_KVM_EMULATE_H
+
+#include <asm/esr.h>
+#include <asm/pstate.h>
+#include <asm/sysreg-defs.h>
+
+static inline bool kvm_vcpu_is_be(struct kvm_vcpu *vcpu);
+static __always_inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu);
+static __always_inline unsigned long *vcpu_cpsr(const struct kvm_vcpu *vcpu);
+static inline bool kvm_vcpu_trap_is_permission_fault(const struct kvm_vcpu *vcpu);
+static u64 kvm_vcpu_get_esr(const struct kvm_vcpu *vcpu);
+static __always_inline bool vcpu_mode_is_32bit(const struct kvm_vcpu *vcpu);
+
+#define CURRENT_EL_SP_EL0_VECTOR	0x0
+#define CURRENT_EL_SP_ELx_VECTOR	0x200
+#define LOWER_EL_AArch64_VECTOR		0x400
+#define LOWER_EL_AArch32_VECTOR		0x600
+
+enum exception_type {
+	except_type_sync	= 0,
+	except_type_irq		= 0x80,
+	except_type_fiq		= 0x100,
+	except_type_serror	= 0x180,
+};
+
+void kvm_skip_instr32(struct kvm_vcpu *vcpu);
+
+void kvm_inject_undefined(struct kvm_vcpu *vcpu);
+int kvm_inject_serror_esr(struct kvm_vcpu *vcpu, u64 esr);
+int kvm_inject_sea(struct kvm_vcpu *vcpu, bool iabt, u64 addr);
+void kvm_inject_size_fault(struct kvm_vcpu *vcpu);
+
+static inline int kvm_inject_sea_dabt(struct kvm_vcpu *vcpu, u64 addr)
+{
+	return kvm_inject_sea(vcpu, false, addr);
+}
+
+static inline int kvm_inject_sea_iabt(struct kvm_vcpu *vcpu, u64 addr)
+{
+	return kvm_inject_sea(vcpu, true, addr);
+}
+
+static inline int kvm_inject_serror(struct kvm_vcpu *vcpu)
+{
+	/*
+	 * ESR_ELx.ISV (later renamed to IDS) indicates whether or not
+	 * ESR_ELx.ISS contains IMPLEMENTATION DEFINED syndrome information.
+	 *
+	 * Set the bit when injecting an SError w/o an ESR to indicate ISS
+	 * does not follow the architected format.
+	 */
+	return kvm_inject_serror_esr(vcpu, ESR_ELx_ISV);
+}
+
+void kvm_vcpu_wfi(struct kvm_vcpu *vcpu);
+
+static inline void kvm_skip_instr(struct kvm_vcpu *vcpu)
+{
+	if (vcpu_mode_is_32bit(vcpu)) {
+		kvm_skip_instr32(vcpu);
+	} else {
+		*vcpu_pc(vcpu) += 4;
+		*vcpu_cpsr(vcpu) &= ~SPSR64_BTYPE_MASK;
+	}
+
+	/* advance the singlestep state machine */
+	*vcpu_cpsr(vcpu) &= ~SPSR_SS;
+}
+
+/*
+ * vcpu_get_reg and vcpu_set_reg should always be passed a register number
+ * coming from a read of ESR_EL2. Otherwise, it may give the wrong result on
+ * AArch32 with banked registers.
+ */
+static __always_inline unsigned long vcpu_get_reg(const struct kvm_vcpu *vcpu,
+						  u8 reg_num)
+{
+	return (reg_num == 31) ? 0 : vcpu_gp_regs(vcpu)->regs[reg_num];
+}
+
+static __always_inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,
+					 unsigned long val)
+{
+	if (reg_num != 31)
+		vcpu_gp_regs(vcpu)->regs[reg_num] = val;
+}
+
+static inline u32 kvm_vcpu_hvc_get_imm(const struct kvm_vcpu *vcpu)
+{
+	return kvm_vcpu_get_esr(vcpu) & ESR_ELx_xVC_IMM_MASK;
+}
+
+static __always_inline bool kvm_vcpu_dabt_isvalid(const struct kvm_vcpu *vcpu)
+{
+	return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_ISV);
+}
+
+static inline bool kvm_vcpu_dabt_issext(const struct kvm_vcpu *vcpu)
+{
+	return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_SSE);
+}
+
+static inline bool kvm_vcpu_dabt_issf(const struct kvm_vcpu *vcpu)
+{
+	return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_SF);
+}
+
+static __always_inline int kvm_vcpu_dabt_get_rd(const struct kvm_vcpu *vcpu)
+{
+	return (kvm_vcpu_get_esr(vcpu) & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT;
+}
+
+static __always_inline bool kvm_vcpu_abt_iss1tw(const struct kvm_vcpu *vcpu)
+{
+	return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_S1PTW);
+}
+
+/* Always check for S1PTW *before* using this. */
+static __always_inline bool kvm_vcpu_dabt_iswrite(const struct kvm_vcpu *vcpu)
+{
+	return kvm_vcpu_get_esr(vcpu) & ESR_ELx_WNR;
+}
+
+static inline bool kvm_vcpu_dabt_is_cm(const struct kvm_vcpu *vcpu)
+{
+	return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_CM);
+}
+
+static __always_inline unsigned int kvm_vcpu_dabt_get_as(const struct kvm_vcpu *vcpu)
+{
+	return 1 << ((kvm_vcpu_get_esr(vcpu) & ESR_ELx_SAS) >> ESR_ELx_SAS_SHIFT);
+}
+
+/* This one is not specific to Data Abort */
+static __always_inline bool kvm_vcpu_trap_il_is32bit(const struct kvm_vcpu *vcpu)
+{
+	return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_IL);
+}
+
+static __always_inline u8 kvm_vcpu_trap_get_class(const struct kvm_vcpu *vcpu)
+{
+	return ESR_ELx_EC(kvm_vcpu_get_esr(vcpu));
+}
+
+static inline bool kvm_vcpu_trap_is_iabt(const struct kvm_vcpu *vcpu)
+{
+	return kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_IABT_LOW;
+}
+
+static inline bool kvm_vcpu_trap_is_exec_fault(const struct kvm_vcpu *vcpu)
+{
+	return kvm_vcpu_trap_is_iabt(vcpu) && !kvm_vcpu_abt_iss1tw(vcpu);
+}
+
+static __always_inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu)
+{
+	u64 esr = kvm_vcpu_get_esr(vcpu);
+
+	return ESR_ELx_SYS64_ISS_RT(esr);
+}
+
+static __always_inline u8 kvm_vcpu_trap_get_fault(const struct kvm_vcpu *vcpu)
+{
+	return kvm_vcpu_get_esr(vcpu) & ESR_ELx_FSC;
+}
+
+static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
+{
+	if (kvm_vcpu_abt_iss1tw(vcpu)) {
+		/*
+		 * Only a permission fault on a S1PTW should be
+		 * considered as a write. Otherwise, page tables baked
+		 * in a read-only memslot will result in an exception
+		 * being delivered in the guest.
+		 *
+		 * The drawback is that we end-up faulting twice if the
+		 * guest is using any of HW AF/DB: a translation fault
+		 * to map the page containing the PT (read only at
+		 * first), then a permission fault to allow the flags
+		 * to be set.
+		 */
+		return kvm_vcpu_trap_is_permission_fault(vcpu);
+	}
+
+	if (kvm_vcpu_trap_is_iabt(vcpu))
+		return false;
+
+	return kvm_vcpu_dabt_iswrite(vcpu);
+}
+
+static inline unsigned long vcpu_data_guest_to_host(struct kvm_vcpu *vcpu,
+						    unsigned long data,
+						    unsigned int len)
+{
+	if (kvm_vcpu_is_be(vcpu)) {
+		switch (len) {
+		case 1:
+			return data & 0xff;
+		case 2:
+			return be16_to_cpu(data & 0xffff);
+		case 4:
+			return be32_to_cpu(data & 0xffffffff);
+		default:
+			return be64_to_cpu(data);
+		}
+	} else {
+		switch (len) {
+		case 1:
+			return data & 0xff;
+		case 2:
+			return le16_to_cpu(data & 0xffff);
+		case 4:
+			return le32_to_cpu(data & 0xffffffff);
+		default:
+			return le64_to_cpu(data);
+		}
+	}
+
+	return data;		/* Leave LE untouched */
+}
+
+static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu,
+						    unsigned long data,
+						    unsigned int len)
+{
+	if (kvm_vcpu_is_be(vcpu)) {
+		switch (len) {
+		case 1:
+			return data & 0xff;
+		case 2:
+			return cpu_to_be16(data & 0xffff);
+		case 4:
+			return cpu_to_be32(data & 0xffffffff);
+		default:
+			return cpu_to_be64(data);
+		}
+	} else {
+		switch (len) {
+		case 1:
+			return data & 0xff;
+		case 2:
+			return cpu_to_le16(data & 0xffff);
+		case 4:
+			return cpu_to_le32(data & 0xffffffff);
+		default:
+			return cpu_to_le64(data);
+		}
+	}
+
+	return data;		/* Leave LE untouched */
+}
+
+static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
+{
+	WARN_ON(vcpu_get_flag(vcpu, PENDING_EXCEPTION));
+	vcpu_set_flag(vcpu, INCREMENT_PC);
+}
+
+#define kvm_pend_exception(v, e)					\
+	do {								\
+		WARN_ON(vcpu_get_flag((v), INCREMENT_PC));		\
+		vcpu_set_flag((v), PENDING_EXCEPTION);			\
+		vcpu_set_flag((v), e);					\
+	} while (0)
+
+#endif /* KVM_ARM64_KVM_EMULATE_H */
-- 
2.51.0



^ permalink raw reply related


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