linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/3] Nested virtualization fixes for root partition
@ 2025-07-11 19:18 Nuno Das Neves
  2025-07-11 19:18 ` [PATCH v3 1/3] Drivers: hv: Use nested hypercall for post message and signal event Nuno Das Neves
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Nuno Das Neves @ 2025-07-11 19:18 UTC (permalink / raw)
  To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, wei.liu,
	mhklinux, tglx, bhelgaas, romank
  Cc: kys, haiyangz, decui, catalin.marinas, will, mingo, bp,
	dave.hansen, hpa, lpieralisi, kw, robh, jinankjain, skinsburskii,
	mrathor, x86, Nuno Das Neves

Fixes for running as nested root partition on the Microsoft Hypervisor.

The first patch changes vmbus to make hypercalls to the L0 hypervisor
instead of the L1. This is needed because L0 hypervisor, not the L1, is
the one hosting the Windows root partition with the VMM that provides
vmbus.

The 2nd and 3rd patches fix interrupt unmasking on nested. In this
scenario, the L1 (nested) hypervisor does the interrupt mapping to root
partition cores. The vectors just need to be mapped with
MAP_DEVICE_INTERRUPT instead of affinitized with RETARGET_INTERRUPT.

Changes in v3:
- Remove 3 patches (#1,#3,#4 from v2) which were merged already (Wei Liu)
- Fix bug in #1 introduced in v2 (Michael Kelley)
- Improve commit message in #2 (Michael Kelley)
- Document return value of hv_map_msi_interrupt() in #2 (Michael Kelley)

Changes in v2:
- Reword commit messages for clarity (Michael Kelley, Bjorn Helgaas)
- Open-code nested hypercalls to reduce unnecessary code (Michael Kelley)
- Add patch (#3) to fix cpu_online_mask issue (Thomas Gleixner)
- Add patch (#4) to fix error return values (Michael Kelley)
- Remove several redundant error messages and checks (Michael Kelley)

Nuno Das Neves (1):
  Drivers: hv: Use nested hypercall for post message and signal event

Stanislav Kinsburskii (2):
  x86/hyperv: Expose hv_map_msi_interrupt()
  PCI: hv: Use the correct hypercall for unmasking interrupts on nested

 arch/x86/hyperv/irqdomain.c         | 40 +++++++++++++++++++++--------
 arch/x86/include/asm/mshyperv.h     | 22 ++--------------
 drivers/hv/connection.c             |  5 +++-
 drivers/hv/hv.c                     |  6 +++--
 drivers/pci/controller/pci-hyperv.c | 18 +++++++++++--
 5 files changed, 55 insertions(+), 36 deletions(-)

-- 
2.34.1



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 1/3] Drivers: hv: Use nested hypercall for post message and signal event
  2025-07-11 19:18 [PATCH v3 0/3] Nested virtualization fixes for root partition Nuno Das Neves
@ 2025-07-11 19:18 ` Nuno Das Neves
  2025-07-11 19:25   ` Michael Kelley
  2025-07-11 19:18 ` [PATCH v3 2/3] x86/hyperv: Expose hv_map_msi_interrupt() Nuno Das Neves
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Nuno Das Neves @ 2025-07-11 19:18 UTC (permalink / raw)
  To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, wei.liu,
	mhklinux, tglx, bhelgaas, romank
  Cc: kys, haiyangz, decui, catalin.marinas, will, mingo, bp,
	dave.hansen, hpa, lpieralisi, kw, robh, jinankjain, skinsburskii,
	mrathor, x86, Nuno Das Neves

When running nested, these hypercalls must be sent to the L0 hypervisor
or VMBus will fail.

Remove hv_do_nested_hypercall() and hv_do_fast_nested_hypercall8()
altogether and open-code these cases, since there are only 2 and all
they do is add the nested bit.

Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Roman Kisel <romank@linux.microsoft.com>
---
 arch/x86/include/asm/mshyperv.h | 20 --------------------
 drivers/hv/connection.c         |  5 ++++-
 drivers/hv/hv.c                 |  6 ++++--
 3 files changed, 8 insertions(+), 23 deletions(-)

diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index e1752ba47e67..ab097a3a8b75 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -112,12 +112,6 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
 	return hv_status;
 }
 
-/* Hypercall to the L0 hypervisor */
-static inline u64 hv_do_nested_hypercall(u64 control, void *input, void *output)
-{
-	return hv_do_hypercall(control | HV_HYPERCALL_NESTED, input, output);
-}
-
 /* Fast hypercall with 8 bytes of input and no output */
 static inline u64 _hv_do_fast_hypercall8(u64 control, u64 input1)
 {
@@ -165,13 +159,6 @@ static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1)
 	return _hv_do_fast_hypercall8(control, input1);
 }
 
-static inline u64 hv_do_fast_nested_hypercall8(u16 code, u64 input1)
-{
-	u64 control = (u64)code | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_NESTED;
-
-	return _hv_do_fast_hypercall8(control, input1);
-}
-
 /* Fast hypercall with 16 bytes of input */
 static inline u64 _hv_do_fast_hypercall16(u64 control, u64 input1, u64 input2)
 {
@@ -223,13 +210,6 @@ static inline u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2)
 	return _hv_do_fast_hypercall16(control, input1, input2);
 }
 
-static inline u64 hv_do_fast_nested_hypercall16(u16 code, u64 input1, u64 input2)
-{
-	u64 control = (u64)code | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_NESTED;
-
-	return _hv_do_fast_hypercall16(control, input1, input2);
-}
-
 extern struct hv_vp_assist_page **hv_vp_assist_page;
 
 static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu)
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index be490c598785..1fe3573ae52a 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -519,7 +519,10 @@ void vmbus_set_event(struct vmbus_channel *channel)
 		else
 			WARN_ON_ONCE(1);
 	} else {
-		hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, channel->sig_event);
+		u64 control = HVCALL_SIGNAL_EVENT;
+
+		control |= hv_nested ? HV_HYPERCALL_NESTED : 0;
+		hv_do_fast_hypercall8(control, channel->sig_event);
 	}
 }
 EXPORT_SYMBOL_GPL(vmbus_set_event);
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 308c8f279df8..b14c5f9e0ef2 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -85,8 +85,10 @@ int hv_post_message(union hv_connection_id connection_id,
 		else
 			status = HV_STATUS_INVALID_PARAMETER;
 	} else {
-		status = hv_do_hypercall(HVCALL_POST_MESSAGE,
-					 aligned_msg, NULL);
+		u64 control = HVCALL_POST_MESSAGE;
+
+		control |= hv_nested ? HV_HYPERCALL_NESTED : 0;
+		status = hv_do_hypercall(control, aligned_msg, NULL);
 	}
 
 	local_irq_restore(flags);
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 2/3] x86/hyperv: Expose hv_map_msi_interrupt()
  2025-07-11 19:18 [PATCH v3 0/3] Nested virtualization fixes for root partition Nuno Das Neves
  2025-07-11 19:18 ` [PATCH v3 1/3] Drivers: hv: Use nested hypercall for post message and signal event Nuno Das Neves
@ 2025-07-11 19:18 ` Nuno Das Neves
  2025-07-11 19:28   ` Michael Kelley
  2025-07-11 19:18 ` [PATCH v3 3/3] PCI: hv: Use the correct hypercall for unmasking interrupts on nested Nuno Das Neves
  2025-07-15  6:24 ` [PATCH v3 0/3] Nested virtualization fixes for root partition Wei Liu
  3 siblings, 1 reply; 7+ messages in thread
From: Nuno Das Neves @ 2025-07-11 19:18 UTC (permalink / raw)
  To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, wei.liu,
	mhklinux, tglx, bhelgaas, romank
  Cc: kys, haiyangz, decui, catalin.marinas, will, mingo, bp,
	dave.hansen, hpa, lpieralisi, kw, robh, jinankjain, skinsburskii,
	mrathor, x86, Nuno Das Neves

From: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>

Move some of the logic of hv_irq_compose_irq_message() into
hv_map_msi_interrupt(). Make hv_map_msi_interrupt() a globally-available
helper function, which will be used to map PCI interrupts when running
in the root partition.

Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Roman Kisel <romank@linux.microsoft.com>
---
 arch/x86/hyperv/irqdomain.c     | 40 ++++++++++++++++++++++++---------
 arch/x86/include/asm/mshyperv.h |  2 ++
 2 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c
index ad4dff48cf14..090f5ac9f492 100644
--- a/arch/x86/hyperv/irqdomain.c
+++ b/arch/x86/hyperv/irqdomain.c
@@ -173,13 +173,34 @@ static union hv_device_id hv_build_pci_dev_id(struct pci_dev *dev)
 	return dev_id;
 }
 
-static int hv_map_msi_interrupt(struct pci_dev *dev, int cpu, int vector,
-				struct hv_interrupt_entry *entry)
+/**
+ * hv_map_msi_interrupt() - "Map" the MSI IRQ in the hypervisor.
+ * @data:      Describes the IRQ
+ * @out_entry: Hypervisor (MSI) interrupt entry (can be NULL)
+ *
+ * Map the IRQ in the hypervisor by issuing a MAP_DEVICE_INTERRUPT hypercall.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+int hv_map_msi_interrupt(struct irq_data *data,
+			 struct hv_interrupt_entry *out_entry)
 {
-	union hv_device_id device_id = hv_build_pci_dev_id(dev);
+	struct irq_cfg *cfg = irqd_cfg(data);
+	struct hv_interrupt_entry dummy;
+	union hv_device_id device_id;
+	struct msi_desc *msidesc;
+	struct pci_dev *dev;
+	int cpu;
 
-	return hv_map_interrupt(device_id, false, cpu, vector, entry);
+	msidesc = irq_data_get_msi_desc(data);
+	dev = msi_desc_to_pci_dev(msidesc);
+	device_id = hv_build_pci_dev_id(dev);
+	cpu = cpumask_first(irq_data_get_effective_affinity_mask(data));
+
+	return hv_map_interrupt(device_id, false, cpu, cfg->vector,
+				out_entry ? out_entry : &dummy);
 }
+EXPORT_SYMBOL_GPL(hv_map_msi_interrupt);
 
 static inline void entry_to_msi_msg(struct hv_interrupt_entry *entry, struct msi_msg *msg)
 {
@@ -192,11 +213,11 @@ static inline void entry_to_msi_msg(struct hv_interrupt_entry *entry, struct msi
 static int hv_unmap_msi_interrupt(struct pci_dev *dev, struct hv_interrupt_entry *old_entry);
 static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 {
-	struct hv_interrupt_entry out_entry, *stored_entry;
+	struct hv_interrupt_entry *stored_entry;
 	struct irq_cfg *cfg = irqd_cfg(data);
 	struct msi_desc *msidesc;
 	struct pci_dev *dev;
-	int cpu, ret;
+	int ret;
 
 	msidesc = irq_data_get_msi_desc(data);
 	dev = msi_desc_to_pci_dev(msidesc);
@@ -206,8 +227,6 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 		return;
 	}
 
-	cpu = cpumask_first(irq_data_get_effective_affinity_mask(data));
-
 	if (data->chip_data) {
 		/*
 		 * This interrupt is already mapped. Let's unmap first.
@@ -234,15 +253,14 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 		return;
 	}
 
-	ret = hv_map_msi_interrupt(dev, cpu, cfg->vector, &out_entry);
+	ret = hv_map_msi_interrupt(data, stored_entry);
 	if (ret) {
 		kfree(stored_entry);
 		return;
 	}
 
-	*stored_entry = out_entry;
 	data->chip_data = stored_entry;
-	entry_to_msi_msg(&out_entry, msg);
+	entry_to_msi_msg(data->chip_data, msg);
 
 	return;
 }
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index ab097a3a8b75..abc4659f5809 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -242,6 +242,8 @@ static inline void hv_apic_init(void) {}
 
 struct irq_domain *hv_create_pci_msi_domain(void);
 
+int hv_map_msi_interrupt(struct irq_data *data,
+			 struct hv_interrupt_entry *out_entry);
 int hv_map_ioapic_interrupt(int ioapic_id, bool level, int vcpu, int vector,
 		struct hv_interrupt_entry *entry);
 int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 3/3] PCI: hv: Use the correct hypercall for unmasking interrupts on nested
  2025-07-11 19:18 [PATCH v3 0/3] Nested virtualization fixes for root partition Nuno Das Neves
  2025-07-11 19:18 ` [PATCH v3 1/3] Drivers: hv: Use nested hypercall for post message and signal event Nuno Das Neves
  2025-07-11 19:18 ` [PATCH v3 2/3] x86/hyperv: Expose hv_map_msi_interrupt() Nuno Das Neves
@ 2025-07-11 19:18 ` Nuno Das Neves
  2025-07-15  6:24 ` [PATCH v3 0/3] Nested virtualization fixes for root partition Wei Liu
  3 siblings, 0 replies; 7+ messages in thread
From: Nuno Das Neves @ 2025-07-11 19:18 UTC (permalink / raw)
  To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, wei.liu,
	mhklinux, tglx, bhelgaas, romank
  Cc: kys, haiyangz, decui, catalin.marinas, will, mingo, bp,
	dave.hansen, hpa, lpieralisi, kw, robh, jinankjain, skinsburskii,
	mrathor, x86, Nuno Das Neves

From: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>

Running as nested root on MSHV imposes a different requirement
for the pci-hyperv controller.

In this setup, the interrupt will first come to the L1 (nested) hypervisor,
which will deliver it to the appropriate root CPU. Instead of issuing the
RETARGET hypercall, issue the MAP_DEVICE_INTERRUPT hypercall to L1 to
complete the setup.

Rename hv_arch_irq_unmask() to hv_irq_retarget_interrupt().

Co-developed-by: Jinank Jain <jinankjain@linux.microsoft.com>
Signed-off-by: Jinank Jain <jinankjain@linux.microsoft.com>
Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Roman Kisel <romank@linux.microsoft.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/controller/pci-hyperv.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index 275b23af3de2..13680363ff19 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -600,7 +600,7 @@ static unsigned int hv_msi_get_int_vector(struct irq_data *data)
 #define hv_msi_prepare		pci_msi_prepare
 
 /**
- * hv_arch_irq_unmask() - "Unmask" the IRQ by setting its current
+ * hv_irq_retarget_interrupt() - "Unmask" the IRQ by setting its current
  * affinity.
  * @data:	Describes the IRQ
  *
@@ -609,7 +609,7 @@ static unsigned int hv_msi_get_int_vector(struct irq_data *data)
  * is built out of this PCI bus's instance GUID and the function
  * number of the device.
  */
-static void hv_arch_irq_unmask(struct irq_data *data)
+static void hv_irq_retarget_interrupt(struct irq_data *data)
 {
 	struct msi_desc *msi_desc = irq_data_get_msi_desc(data);
 	struct hv_retarget_device_interrupt *params;
@@ -714,6 +714,20 @@ static void hv_arch_irq_unmask(struct irq_data *data)
 		dev_err(&hbus->hdev->device,
 			"%s() failed: %#llx", __func__, res);
 }
+
+static void hv_arch_irq_unmask(struct irq_data *data)
+{
+	if (hv_root_partition())
+		/*
+		 * In case of the nested root partition, the nested hypervisor
+		 * is taking care of interrupt remapping and thus the
+		 * MAP_DEVICE_INTERRUPT hypercall is required instead of
+		 * RETARGET_INTERRUPT.
+		 */
+		(void)hv_map_msi_interrupt(data, NULL);
+	else
+		hv_irq_retarget_interrupt(data);
+}
 #elif defined(CONFIG_ARM64)
 /*
  * SPI vectors to use for vPCI; arch SPIs range is [32, 1019], but leaving a bit
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* RE: [PATCH v3 1/3] Drivers: hv: Use nested hypercall for post message and signal event
  2025-07-11 19:18 ` [PATCH v3 1/3] Drivers: hv: Use nested hypercall for post message and signal event Nuno Das Neves
@ 2025-07-11 19:25   ` Michael Kelley
  0 siblings, 0 replies; 7+ messages in thread
From: Michael Kelley @ 2025-07-11 19:25 UTC (permalink / raw)
  To: Nuno Das Neves, linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,
	wei.liu@kernel.org, tglx@linutronix.de, bhelgaas@google.com,
	romank@linux.microsoft.com
  Cc: kys@microsoft.com, haiyangz@microsoft.com, decui@microsoft.com,
	catalin.marinas@arm.com, will@kernel.org, mingo@redhat.com,
	bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com,
	lpieralisi@kernel.org, kw@linux.com, robh@kernel.org,
	jinankjain@linux.microsoft.com, skinsburskii@linux.microsoft.com,
	mrathor@linux.microsoft.com, x86@kernel.org

From: Nuno Das Neves <nunodasneves@linux.microsoft.com> Sent: Friday, July 11, 2025 12:19 PM
> 
> When running nested, these hypercalls must be sent to the L0 hypervisor
> or VMBus will fail.
> 
> Remove hv_do_nested_hypercall() and hv_do_fast_nested_hypercall8()
> altogether and open-code these cases, since there are only 2 and all
> they do is add the nested bit.
> 
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> Reviewed-by: Roman Kisel <romank@linux.microsoft.com>
> ---
>  arch/x86/include/asm/mshyperv.h | 20 --------------------
>  drivers/hv/connection.c         |  5 ++++-
>  drivers/hv/hv.c                 |  6 ++++--
>  3 files changed, 8 insertions(+), 23 deletions(-)
> 
> diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
> index e1752ba47e67..ab097a3a8b75 100644
> --- a/arch/x86/include/asm/mshyperv.h
> +++ b/arch/x86/include/asm/mshyperv.h
> @@ -112,12 +112,6 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
>  	return hv_status;
>  }
> 
> -/* Hypercall to the L0 hypervisor */
> -static inline u64 hv_do_nested_hypercall(u64 control, void *input, void *output)
> -{
> -	return hv_do_hypercall(control | HV_HYPERCALL_NESTED, input, output);
> -}
> -
>  /* Fast hypercall with 8 bytes of input and no output */
>  static inline u64 _hv_do_fast_hypercall8(u64 control, u64 input1)
>  {
> @@ -165,13 +159,6 @@ static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1)
>  	return _hv_do_fast_hypercall8(control, input1);
>  }
> 
> -static inline u64 hv_do_fast_nested_hypercall8(u16 code, u64 input1)
> -{
> -	u64 control = (u64)code | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_NESTED;
> -
> -	return _hv_do_fast_hypercall8(control, input1);
> -}
> -
>  /* Fast hypercall with 16 bytes of input */
>  static inline u64 _hv_do_fast_hypercall16(u64 control, u64 input1, u64 input2)
>  {
> @@ -223,13 +210,6 @@ static inline u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2)
>  	return _hv_do_fast_hypercall16(control, input1, input2);
>  }
> 
> -static inline u64 hv_do_fast_nested_hypercall16(u16 code, u64 input1, u64 input2)
> -{
> -	u64 control = (u64)code | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_NESTED;
> -
> -	return _hv_do_fast_hypercall16(control, input1, input2);
> -}
> -
>  extern struct hv_vp_assist_page **hv_vp_assist_page;
> 
>  static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu)
> diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
> index be490c598785..1fe3573ae52a 100644
> --- a/drivers/hv/connection.c
> +++ b/drivers/hv/connection.c
> @@ -519,7 +519,10 @@ void vmbus_set_event(struct vmbus_channel *channel)
>  		else
>  			WARN_ON_ONCE(1);
>  	} else {
> -		hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, channel->sig_event);
> +		u64 control = HVCALL_SIGNAL_EVENT;
> +
> +		control |= hv_nested ? HV_HYPERCALL_NESTED : 0;
> +		hv_do_fast_hypercall8(control, channel->sig_event);
>  	}
>  }
>  EXPORT_SYMBOL_GPL(vmbus_set_event);
> diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
> index 308c8f279df8..b14c5f9e0ef2 100644
> --- a/drivers/hv/hv.c
> +++ b/drivers/hv/hv.c
> @@ -85,8 +85,10 @@ int hv_post_message(union hv_connection_id connection_id,
>  		else
>  			status = HV_STATUS_INVALID_PARAMETER;
>  	} else {
> -		status = hv_do_hypercall(HVCALL_POST_MESSAGE,
> -					 aligned_msg, NULL);
> +		u64 control = HVCALL_POST_MESSAGE;
> +
> +		control |= hv_nested ? HV_HYPERCALL_NESTED : 0;
> +		status = hv_do_hypercall(control, aligned_msg, NULL);
>  	}
> 
>  	local_irq_restore(flags);
> --
> 2.34.1

Reviewed-by: Michael Kelley <mhklinux@outlook.com>



^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH v3 2/3] x86/hyperv: Expose hv_map_msi_interrupt()
  2025-07-11 19:18 ` [PATCH v3 2/3] x86/hyperv: Expose hv_map_msi_interrupt() Nuno Das Neves
@ 2025-07-11 19:28   ` Michael Kelley
  0 siblings, 0 replies; 7+ messages in thread
From: Michael Kelley @ 2025-07-11 19:28 UTC (permalink / raw)
  To: Nuno Das Neves, linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,
	wei.liu@kernel.org, tglx@linutronix.de, bhelgaas@google.com,
	romank@linux.microsoft.com
  Cc: kys@microsoft.com, haiyangz@microsoft.com, decui@microsoft.com,
	catalin.marinas@arm.com, will@kernel.org, mingo@redhat.com,
	bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com,
	lpieralisi@kernel.org, kw@linux.com, robh@kernel.org,
	jinankjain@linux.microsoft.com, skinsburskii@linux.microsoft.com,
	mrathor@linux.microsoft.com, x86@kernel.org

From: Nuno Das Neves <nunodasneves@linux.microsoft.com> Sent: Friday, July 11, 2025 12:19 PM
> From: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
> 
> Move some of the logic of hv_irq_compose_irq_message() into
> hv_map_msi_interrupt(). Make hv_map_msi_interrupt() a globally-available
> helper function, which will be used to map PCI interrupts when running
> in the root partition.
> 
> Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
> Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
> Reviewed-by: Roman Kisel <romank@linux.microsoft.com>
> ---
>  arch/x86/hyperv/irqdomain.c     | 40 ++++++++++++++++++++++++---------
>  arch/x86/include/asm/mshyperv.h |  2 ++
>  2 files changed, 31 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c
> index ad4dff48cf14..090f5ac9f492 100644
> --- a/arch/x86/hyperv/irqdomain.c
> +++ b/arch/x86/hyperv/irqdomain.c
> @@ -173,13 +173,34 @@ static union hv_device_id hv_build_pci_dev_id(struct pci_dev *dev)
>  	return dev_id;
>  }
> 
> -static int hv_map_msi_interrupt(struct pci_dev *dev, int cpu, int vector,
> -				struct hv_interrupt_entry *entry)
> +/**
> + * hv_map_msi_interrupt() - "Map" the MSI IRQ in the hypervisor.
> + * @data:      Describes the IRQ
> + * @out_entry: Hypervisor (MSI) interrupt entry (can be NULL)
> + *
> + * Map the IRQ in the hypervisor by issuing a MAP_DEVICE_INTERRUPT hypercall.
> + *
> + * Return: 0 on success, -errno on failure
> + */
> +int hv_map_msi_interrupt(struct irq_data *data,
> +			 struct hv_interrupt_entry *out_entry)
>  {
> -	union hv_device_id device_id = hv_build_pci_dev_id(dev);
> +	struct irq_cfg *cfg = irqd_cfg(data);
> +	struct hv_interrupt_entry dummy;
> +	union hv_device_id device_id;
> +	struct msi_desc *msidesc;
> +	struct pci_dev *dev;
> +	int cpu;
> 
> -	return hv_map_interrupt(device_id, false, cpu, vector, entry);
> +	msidesc = irq_data_get_msi_desc(data);
> +	dev = msi_desc_to_pci_dev(msidesc);
> +	device_id = hv_build_pci_dev_id(dev);
> +	cpu = cpumask_first(irq_data_get_effective_affinity_mask(data));
> +
> +	return hv_map_interrupt(device_id, false, cpu, cfg->vector,
> +				out_entry ? out_entry : &dummy);
>  }
> +EXPORT_SYMBOL_GPL(hv_map_msi_interrupt);
> 
>  static inline void entry_to_msi_msg(struct hv_interrupt_entry *entry, struct msi_msg *msg)
>  {
> @@ -192,11 +213,11 @@ static inline void entry_to_msi_msg(struct hv_interrupt_entry *entry, struct msi
>  static int hv_unmap_msi_interrupt(struct pci_dev *dev, struct hv_interrupt_entry *old_entry);
>  static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
>  {
> -	struct hv_interrupt_entry out_entry, *stored_entry;
> +	struct hv_interrupt_entry *stored_entry;
>  	struct irq_cfg *cfg = irqd_cfg(data);
>  	struct msi_desc *msidesc;
>  	struct pci_dev *dev;
> -	int cpu, ret;
> +	int ret;
> 
>  	msidesc = irq_data_get_msi_desc(data);
>  	dev = msi_desc_to_pci_dev(msidesc);
> @@ -206,8 +227,6 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
>  		return;
>  	}
> 
> -	cpu = cpumask_first(irq_data_get_effective_affinity_mask(data));
> -
>  	if (data->chip_data) {
>  		/*
>  		 * This interrupt is already mapped. Let's unmap first.
> @@ -234,15 +253,14 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
>  		return;
>  	}
> 
> -	ret = hv_map_msi_interrupt(dev, cpu, cfg->vector, &out_entry);
> +	ret = hv_map_msi_interrupt(data, stored_entry);
>  	if (ret) {
>  		kfree(stored_entry);
>  		return;
>  	}
> 
> -	*stored_entry = out_entry;
>  	data->chip_data = stored_entry;
> -	entry_to_msi_msg(&out_entry, msg);
> +	entry_to_msi_msg(data->chip_data, msg);
> 
>  	return;
>  }
> diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
> index ab097a3a8b75..abc4659f5809 100644
> --- a/arch/x86/include/asm/mshyperv.h
> +++ b/arch/x86/include/asm/mshyperv.h
> @@ -242,6 +242,8 @@ static inline void hv_apic_init(void) {}
> 
>  struct irq_domain *hv_create_pci_msi_domain(void);
> 
> +int hv_map_msi_interrupt(struct irq_data *data,
> +			 struct hv_interrupt_entry *out_entry);
>  int hv_map_ioapic_interrupt(int ioapic_id, bool level, int vcpu, int vector,
>  		struct hv_interrupt_entry *entry);
>  int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
> --
> 2.34.1

Reviewed-by: Michael Kelley <mhklinux@outlook.com>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 0/3] Nested virtualization fixes for root partition
  2025-07-11 19:18 [PATCH v3 0/3] Nested virtualization fixes for root partition Nuno Das Neves
                   ` (2 preceding siblings ...)
  2025-07-11 19:18 ` [PATCH v3 3/3] PCI: hv: Use the correct hypercall for unmasking interrupts on nested Nuno Das Neves
@ 2025-07-15  6:24 ` Wei Liu
  3 siblings, 0 replies; 7+ messages in thread
From: Wei Liu @ 2025-07-15  6:24 UTC (permalink / raw)
  To: Nuno Das Neves
  Cc: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, wei.liu,
	mhklinux, tglx, bhelgaas, romank, kys, haiyangz, decui,
	catalin.marinas, will, mingo, bp, dave.hansen, hpa, lpieralisi,
	kw, robh, jinankjain, skinsburskii, mrathor, x86

On Fri, Jul 11, 2025 at 12:18:49PM -0700, Nuno Das Neves wrote:
> Fixes for running as nested root partition on the Microsoft Hypervisor.
> 
> The first patch changes vmbus to make hypercalls to the L0 hypervisor
> instead of the L1. This is needed because L0 hypervisor, not the L1, is
> the one hosting the Windows root partition with the VMM that provides
> vmbus.
> 
> The 2nd and 3rd patches fix interrupt unmasking on nested. In this
> scenario, the L1 (nested) hypervisor does the interrupt mapping to root
> partition cores. The vectors just need to be mapped with
> MAP_DEVICE_INTERRUPT instead of affinitized with RETARGET_INTERRUPT.
> 
> Changes in v3:
> - Remove 3 patches (#1,#3,#4 from v2) which were merged already (Wei Liu)
> - Fix bug in #1 introduced in v2 (Michael Kelley)
> - Improve commit message in #2 (Michael Kelley)
> - Document return value of hv_map_msi_interrupt() in #2 (Michael Kelley)
> 
> Changes in v2:
> - Reword commit messages for clarity (Michael Kelley, Bjorn Helgaas)
> - Open-code nested hypercalls to reduce unnecessary code (Michael Kelley)
> - Add patch (#3) to fix cpu_online_mask issue (Thomas Gleixner)
> - Add patch (#4) to fix error return values (Michael Kelley)
> - Remove several redundant error messages and checks (Michael Kelley)
> 
> Nuno Das Neves (1):
>   Drivers: hv: Use nested hypercall for post message and signal event
> 
> Stanislav Kinsburskii (2):
>   x86/hyperv: Expose hv_map_msi_interrupt()
>   PCI: hv: Use the correct hypercall for unmasking interrupts on nested
> 

Applied. Thanks.


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-07-15  6:27 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-11 19:18 [PATCH v3 0/3] Nested virtualization fixes for root partition Nuno Das Neves
2025-07-11 19:18 ` [PATCH v3 1/3] Drivers: hv: Use nested hypercall for post message and signal event Nuno Das Neves
2025-07-11 19:25   ` Michael Kelley
2025-07-11 19:18 ` [PATCH v3 2/3] x86/hyperv: Expose hv_map_msi_interrupt() Nuno Das Neves
2025-07-11 19:28   ` Michael Kelley
2025-07-11 19:18 ` [PATCH v3 3/3] PCI: hv: Use the correct hypercall for unmasking interrupts on nested Nuno Das Neves
2025-07-15  6:24 ` [PATCH v3 0/3] Nested virtualization fixes for root partition Wei Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).