* [PATCH net-next v5 3/4] test/vsock: Add retry mechanism to ioctl wrapper
From: Xuewei Niu @ 2025-07-06 4:36 UTC (permalink / raw)
To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Stefano Garzarella, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: linux-hyperv, virtualization, netdev, linux-kernel, Xuewei Niu,
fupan.lfp
In-Reply-To: <20250706-siocinq-v5-0-8d0b96a87465@antgroup.com>
Wrap the ioctl in `ioctl_int()`, which takes a pointer to the actual
int value and an expected int value. The function will not return until
either the ioctl returns the expected value or a timeout occurs, thus
avoiding immediate failure.
Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
---
tools/testing/vsock/util.c | 30 +++++++++++++++++++++---------
tools/testing/vsock/util.h | 1 +
2 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
index 803f1e075b62228c25f9dffa1eff131b8072a06a..1e65c5abd85b8bcf5886272de15437d7be13eb89 100644
--- a/tools/testing/vsock/util.c
+++ b/tools/testing/vsock/util.c
@@ -17,6 +17,7 @@
#include <unistd.h>
#include <assert.h>
#include <sys/epoll.h>
+#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/sockios.h>
@@ -101,28 +102,39 @@ void vsock_wait_remote_close(int fd)
close(epollfd);
}
-/* Wait until transport reports no data left to be sent.
- * Return false if transport does not implement the unsent_bytes() callback.
+/* Wait until ioctl gives an expected int value.
+ * Return false if the op is not supported.
*/
-bool vsock_wait_sent(int fd)
+bool vsock_ioctl_int(int fd, unsigned long op, int expected)
{
- int ret, sock_bytes_unsent;
+ int actual, ret;
+ char name[32];
+
+ snprintf(name, sizeof(name), "ioctl(%lu)", op);
timeout_begin(TIMEOUT);
do {
- ret = ioctl(fd, SIOCOUTQ, &sock_bytes_unsent);
+ ret = ioctl(fd, op, &actual);
if (ret < 0) {
if (errno == EOPNOTSUPP)
break;
- perror("ioctl(SIOCOUTQ)");
+ perror(name);
exit(EXIT_FAILURE);
}
- timeout_check("SIOCOUTQ");
- } while (sock_bytes_unsent != 0);
+ timeout_check(name);
+ } while (actual != expected);
timeout_end();
- return !ret;
+ return ret >= 0;
+}
+
+/* Wait until transport reports no data left to be sent.
+ * Return false if transport does not implement the unsent_bytes() callback.
+ */
+bool vsock_wait_sent(int fd)
+{
+ return vsock_ioctl_int(fd, SIOCOUTQ, 0);
}
/* Create socket <type>, bind to <cid, port>.
diff --git a/tools/testing/vsock/util.h b/tools/testing/vsock/util.h
index fdd4649fe2d49f57c93c4aa5dfbb37b710c65918..142c02a6834acb7117aca485b661332b73754b63 100644
--- a/tools/testing/vsock/util.h
+++ b/tools/testing/vsock/util.h
@@ -87,6 +87,7 @@ int vsock_stream_listen(unsigned int cid, unsigned int port);
int vsock_seqpacket_accept(unsigned int cid, unsigned int port,
struct sockaddr_vm *clientaddrp);
void vsock_wait_remote_close(int fd);
+bool vsock_ioctl_int(int fd, unsigned long op, int expected);
bool vsock_wait_sent(int fd);
void send_buf(int fd, const void *buf, size_t len, int flags,
ssize_t expected_ret);
--
2.34.1
^ permalink raw reply related
* [PATCH net-next v5 2/4] vsock: Add support for SIOCINQ ioctl
From: Xuewei Niu @ 2025-07-06 4:36 UTC (permalink / raw)
To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Stefano Garzarella, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: linux-hyperv, virtualization, netdev, linux-kernel, Xuewei Niu,
fupan.lfp
In-Reply-To: <20250706-siocinq-v5-0-8d0b96a87465@antgroup.com>
Add support for SIOCINQ ioctl, indicating the length of bytes unread in the
socket. The value is obtained from `vsock_stream_has_data()`.
Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
---
net/vmw_vsock/af_vsock.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 2e7a3034e965db30b6ee295370d866e6d8b1c341..bae6b89bb5fb7dd7a3a378f92097561a98a0c814 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1389,6 +1389,28 @@ static int vsock_do_ioctl(struct socket *sock, unsigned int cmd,
vsk = vsock_sk(sk);
switch (cmd) {
+ case SIOCINQ: {
+ ssize_t n_bytes;
+
+ if (!vsk->transport) {
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ if (sock_type_connectible(sk->sk_type) &&
+ sk->sk_state == TCP_LISTEN) {
+ ret = -EINVAL;
+ break;
+ }
+
+ n_bytes = vsock_stream_has_data(vsk);
+ if (n_bytes < 0) {
+ ret = n_bytes;
+ break;
+ }
+ ret = put_user(n_bytes, arg);
+ break;
+ }
case SIOCOUTQ: {
ssize_t n_bytes;
--
2.34.1
^ permalink raw reply related
* [PATCH net-next v5 1/4] hv_sock: Return the readable bytes in hvs_stream_has_data()
From: Xuewei Niu @ 2025-07-06 4:36 UTC (permalink / raw)
To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Stefano Garzarella, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: linux-hyperv, virtualization, netdev, linux-kernel, Xuewei Niu,
fupan.lfp
In-Reply-To: <20250706-siocinq-v5-0-8d0b96a87465@antgroup.com>
When hv_sock was originally added, __vsock_stream_recvmsg() and
vsock_stream_has_data() actually only needed to know whether there
is any readable data or not, so hvs_stream_has_data() was written to
return 1 or 0 for simplicity.
However, now hvs_stream_has_data() should return the readable bytes
because vsock_data_ready() -> vsock_stream_has_data() needs to know the
actual bytes rather than a boolean value of 1 or 0.
The SIOCINQ ioctl support also needs hvs_stream_has_data() to return
the readable bytes.
Let hvs_stream_has_data() return the readable bytes of the payload in
the next host-to-guest VMBus hv_sock packet.
Note: there may be multpile incoming hv_sock packets pending in the
VMBus channel's ringbuffer, but so far there is not a VMBus API that
allows us to know all the readable bytes in total without reading and
caching the payload of the multiple packets, so let's just return the
readable bytes of the next single packet. In the future, we'll either
add a VMBus API that allows us to know the total readable bytes without
touching the data in the ringbuffer, or the hv_sock driver needs to
understand the VMBus packet format and parse the packets directly.
Signed-off-by: Dexuan Cui <decui@microsoft.com>
---
net/vmw_vsock/hyperv_transport.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
index 31342ab502b4fc35feb812d2c94e0e35ded73771..432fcbbd14d4f44bd2550be8376e42ce65122758 100644
--- a/net/vmw_vsock/hyperv_transport.c
+++ b/net/vmw_vsock/hyperv_transport.c
@@ -694,15 +694,26 @@ static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg,
static s64 hvs_stream_has_data(struct vsock_sock *vsk)
{
struct hvsock *hvs = vsk->trans;
+ bool need_refill;
s64 ret;
if (hvs->recv_data_len > 0)
- return 1;
+ return hvs->recv_data_len;
switch (hvs_channel_readable_payload(hvs->chan)) {
case 1:
- ret = 1;
- break;
+ need_refill = !hvs->recv_desc;
+ if (!need_refill)
+ return -EIO;
+
+ hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
+ if (!hvs->recv_desc)
+ return -ENOBUFS;
+
+ ret = hvs_update_recv_data(hvs);
+ if (ret)
+ return ret;
+ return hvs->recv_data_len;
case 0:
vsk->peer_shutdown |= SEND_SHUTDOWN;
ret = 0;
--
2.34.1
^ permalink raw reply related
* [PATCH net-next v5 0/4] vsock: Introduce SIOCINQ ioctl support
From: Xuewei Niu @ 2025-07-06 4:36 UTC (permalink / raw)
To: K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui,
Stefano Garzarella, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: linux-hyperv, virtualization, netdev, linux-kernel, Xuewei Niu,
fupan.lfp
Introduce SIOCINQ ioctl support for vsock, indicating the length of unread
bytes.
Similar with SIOCOUTQ ioctl, the information is transport-dependent.
The first patch adds SIOCINQ ioctl support in AF_VSOCK.
Thanks to @dexuan, the second patch is to fix the issue where hyper-v
`hvs_stream_has_data()` doesn't return the readable bytes.
The third patch wraps the ioctl into `ioctl_int()`, which implements a
retry mechanism to prevent immediate failure.
The last one adds two test cases to check the functionality. The changes
have been tested, and the results are as expected.
Signed-off-by: Xuewei Niu <niuxuewei.nxw@antgroup.com>
--
v1->v2:
https://lore.kernel.org/lkml/20250519070649.3063874-1-niuxuewei.nxw@antgroup.com/
- Use net-next tree.
- Reuse `rx_bytes` to count unread bytes.
- Wrap ioctl syscall with an int pointer argument to implement a retry
mechanism.
v2->v3:
https://lore.kernel.org/netdev/20250613031152.1076725-1-niuxuewei.nxw@antgroup.com/
- Update commit messages following the guidelines
- Remove `unread_bytes` callback and reuse `vsock_stream_has_data()`
- Move the tests to the end of array
- Split the refactoring patch
- Include <sys/ioctl.h> in the util.c
v3->v4:
https://lore.kernel.org/netdev/20250617045347.1233128-1-niuxuewei.nxw@antgroup.com/
- Hyper-v `hvs_stream_has_data()` returns the readable bytes
- Skip testing the null value for `actual` (int pointer)
- Rename `ioctl_int()` to `vsock_ioctl_int()`
- Fix a typo and a format issue in comments
- Remove the `RECEIVED` barrier.
- The return type of `vsock_ioctl_int()` has been changed to bool
v4->v5:
https://lore.kernel.org/netdev/20250630075727.210462-1-niuxuewei.nxw@antgroup.com/
- Put the hyper-v fix before the SIOCINQ ioctl implementation.
- Remove my SOB from the hyper-v fix patch.
- Move the `need_refill` initialization into the `case 1` block.
- Remove the `actual` argument from `vsock_ioctl_int()`.
- Replace `TIOCINQ` with `SIOCINQ`.
---
Xuewei Niu (4):
hv_sock: Return the readable bytes in hvs_stream_has_data()
vsock: Add support for SIOCINQ ioctl
test/vsock: Add retry mechanism to ioctl wrapper
test/vsock: Add ioctl SIOCINQ tests
net/vmw_vsock/af_vsock.c | 22 +++++++++++
net/vmw_vsock/hyperv_transport.c | 17 +++++++--
tools/testing/vsock/util.c | 30 ++++++++++-----
tools/testing/vsock/util.h | 1 +
tools/testing/vsock/vsock_test.c | 79 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 137 insertions(+), 12 deletions(-)
---
base-commit: 5f712c3877f99d5b5e4d011955c6467ae0e535a6
change-id: 20250703-siocinq-9e2907939806
Best regards,
--
Xuewei Niu <niuxuewei.nxw@antgroup.com>
^ permalink raw reply
* Re: [PATCH 14/16] PCI: hv: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-07-05 10:02 UTC (permalink / raw)
To: Michael Kelley
Cc: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org, Karthikeyan Mitran, Hou Zhiqiang,
Thomas Petazzoni, Pali Rohár, K . Y . Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi, Jim Quinlan,
Nicolas Saenz Julienne, Florian Fainelli,
Broadcom internal kernel review list, Ray Jui, Scott Branden,
Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
Matthias Brugger, AngeloGioacchino Del Regno,
linux-arm-kernel@lists.infradead.org,
linux-hyperv@vger.kernel.org,
linux-rpi-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <20250705094655.sEu3KWbJ@linutronix.de>
On Sat, Jul 05, 2025 at 11:46:59AM +0200, Nam Cao wrote:
> On Sat, Jul 05, 2025 at 03:51:48AM +0000, Michael Kelley wrote:
> > From: Nam Cao <namcao@linutronix.de> Sent: Thursday, June 26, 2025 7:48 AM
> > >
> > > Move away from the legacy MSI domain setup, switch to use
> > > msi_create_parent_irq_domain().
> >
> > With the additional tweak to this patch that you supplied separately,
> > everything in my testing on both x86 and arm64 seems to work OK. So
> > that's all good.
>
> Thanks so much for examining the patch,
Btw, you probably would also be interested in
https://lore.kernel.org/lkml/cover.1751277765.git.namcao@linutronix.de/
which does a similar conversion for the other hyperv driver.
Nam
^ permalink raw reply
* Re: [PATCH 14/16] PCI: hv: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-07-05 9:46 UTC (permalink / raw)
To: Michael Kelley
Cc: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org, Karthikeyan Mitran, Hou Zhiqiang,
Thomas Petazzoni, Pali Rohár, K . Y . Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi, Jim Quinlan,
Nicolas Saenz Julienne, Florian Fainelli,
Broadcom internal kernel review list, Ray Jui, Scott Branden,
Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
Matthias Brugger, AngeloGioacchino Del Regno,
linux-arm-kernel@lists.infradead.org,
linux-hyperv@vger.kernel.org,
linux-rpi-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <SN6PR02MB41571145B5ECA505CDA6BD90D44DA@SN6PR02MB4157.namprd02.prod.outlook.com>
On Sat, Jul 05, 2025 at 03:51:48AM +0000, Michael Kelley wrote:
> From: Nam Cao <namcao@linutronix.de> Sent: Thursday, June 26, 2025 7:48 AM
> >
> > Move away from the legacy MSI domain setup, switch to use
> > msi_create_parent_irq_domain().
>
> With the additional tweak to this patch that you supplied separately,
> everything in my testing on both x86 and arm64 seems to work OK. So
> that's all good.
>
> On arm64, I did notice the following IRQ domain information from
> /sys/kernel/debug/irq/domains:
>
> # cat HV-PCI-MSIX-1e03\:00\:00.0-12
> name: HV-PCI-MSIX-1e03:00:00.0-12
> size: 0
> mapped: 7
> flags: 0x00000213
> IRQ_DOMAIN_FLAG_HIERARCHY
> IRQ_DOMAIN_NAME_ALLOCATED
> IRQ_DOMAIN_FLAG_MSI
> IRQ_DOMAIN_FLAG_MSI_DEVICE
> parent: 5D202AA8-1E03-4F0F-A786-390A0D2749E9-3
> name: 5D202AA8-1E03-4F0F-A786-390A0D2749E9-3
> size: 0
> mapped: 7
> flags: 0x00000103
> IRQ_DOMAIN_FLAG_HIERARCHY
> IRQ_DOMAIN_NAME_ALLOCATED
> IRQ_DOMAIN_FLAG_MSI_PARENT
> parent: hv_vpci_arm64
> name: hv_vpci_arm64
> size: 956
> mapped: 31
> flags: 0x00000003
> IRQ_DOMAIN_FLAG_HIERARCHY
> IRQ_DOMAIN_NAME_ALLOCATED
> parent: irqchip@0x00000000ffff0000-1
> name: irqchip@0x00000000ffff0000-1
> size: 0
> mapped: 47
> flags: 0x00000003
> IRQ_DOMAIN_FLAG_HIERARCHY
> IRQ_DOMAIN_NAME_ALLOCATED
>
> The 5D202AA8-1E03-4F0F-A786-390A0D2749E9-3 domain has
> IRQ_DOMAIN_FLAG_MSI_PARENT set. But the hv_vpci_arm64
> and irqchip@... domains do not. Is that a problem? On x86,
> the output is this, with IRQ_DOMAIN_FLAG_MSI_PARENT set
> in the next level up VECTOR domain:
That looks normal. IRQ_DOMAIN_FLAG_MSI_PARENT is set for domains which
provide MSI parent domain capability, which happens to be the case for x86
vector.
> # cat HV-PCI-MSIX-6b71\:00\:02.0-12
> name: HV-PCI-MSIX-6b71:00:02.0-12
> size: 0
> mapped: 17
> flags: 0x00000213
> IRQ_DOMAIN_FLAG_HIERARCHY
> IRQ_DOMAIN_NAME_ALLOCATED
> IRQ_DOMAIN_FLAG_MSI
> IRQ_DOMAIN_FLAG_MSI_DEVICE
> parent: 8564CB14-6B71-477C-B189-F175118E6FF0-3
> name: 8564CB14-6B71-477C-B189-F175118E6FF0-3
> size: 0
> mapped: 17
> flags: 0x00000103
> IRQ_DOMAIN_FLAG_HIERARCHY
> IRQ_DOMAIN_NAME_ALLOCATED
> IRQ_DOMAIN_FLAG_MSI_PARENT
> parent: VECTOR
> name: VECTOR
> size: 0
> mapped: 67
> flags: 0x00000103
> IRQ_DOMAIN_FLAG_HIERARCHY
> IRQ_DOMAIN_NAME_ALLOCATED
> IRQ_DOMAIN_FLAG_MSI_PARENT
>
> Finally, I've noted a couple of code review comments below. These
> comments may reflect my lack of fully understanding the MSI
> IRQ handling, in which case, please set me straight. Thanks,
>
> Michael
>
> >
> > Signed-off-by: Nam Cao <namcao@linutronix.de>
> > ---
> > Cc: K. Y. Srinivasan <kys@microsoft.com>
> > Cc: Haiyang Zhang <haiyangz@microsoft.com>
> > Cc: Wei Liu <wei.liu@kernel.org>
> > Cc: Dexuan Cui <decui@microsoft.com>
> > Cc: linux-hyperv@vger.kernel.org
> > ---
> > drivers/pci/Kconfig | 1 +
> > drivers/pci/controller/pci-hyperv.c | 98 +++++++++++++++++++++++------
> > 2 files changed, 80 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
> > index 9c0e4aaf4e8cb..9a249c65aedcd 100644
> > --- a/drivers/pci/Kconfig
> > +++ b/drivers/pci/Kconfig
> > @@ -223,6 +223,7 @@ config PCI_HYPERV
> > tristate "Hyper-V PCI Frontend"
> > depends on ((X86 && X86_64) || ARM64) && HYPERV && PCI_MSI && SYSFS
> > select PCI_HYPERV_INTERFACE
> > + select IRQ_MSI_LIB
> > help
> > The PCI device frontend driver allows the kernel to import arbitrary
> > PCI devices from a PCI backend to support PCI driver domains.
> > diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
> > index ef5d655a0052c..3a24fadddb83b 100644
> > --- a/drivers/pci/controller/pci-hyperv.c
> > +++ b/drivers/pci/controller/pci-hyperv.c
> > @@ -44,6 +44,7 @@
> > #include <linux/delay.h>
> > #include <linux/semaphore.h>
> > #include <linux/irq.h>
> > +#include <linux/irqchip/irq-msi-lib.h>
> > #include <linux/msi.h>
> > #include <linux/hyperv.h>
> > #include <linux/refcount.h>
> > @@ -508,7 +509,6 @@ struct hv_pcibus_device {
> > struct list_head children;
> > struct list_head dr_list;
> >
> > - struct msi_domain_info msi_info;
> > struct irq_domain *irq_domain;
> >
> > struct workqueue_struct *wq;
> > @@ -1687,7 +1687,7 @@ static void hv_msi_free(struct irq_domain *domain, struct msi_domain_info *info,
> > struct msi_desc *msi = irq_data_get_msi_desc(irq_data);
> >
> > pdev = msi_desc_to_pci_dev(msi);
> > - hbus = info->data;
> > + hbus = domain->host_data;
> > int_desc = irq_data_get_irq_chip_data(irq_data);
> > if (!int_desc)
> > return;
> > @@ -1705,7 +1705,6 @@ static void hv_msi_free(struct irq_domain *domain, struct msi_domain_info *info,
> >
> > static void hv_irq_mask(struct irq_data *data)
> > {
> > - pci_msi_mask_irq(data);
> > if (data->parent_data->chip->irq_mask)
> > irq_chip_mask_parent(data);
> > }
> > @@ -1716,7 +1715,6 @@ static void hv_irq_unmask(struct irq_data *data)
> >
> > if (data->parent_data->chip->irq_unmask)
> > irq_chip_unmask_parent(data);
> > - pci_msi_unmask_irq(data);
> > }
> >
> > struct compose_comp_ctxt {
> > @@ -2101,6 +2099,44 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
> > msg->data = 0;
> > }
> >
> > +static bool hv_pcie_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
> > + struct irq_domain *real_parent, struct msi_domain_info *info)
> > +{
> > + struct irq_chip *chip = info->chip;
> > +
> > + if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info))
> > + return false;
> > +
> > + info->ops->msi_prepare = hv_msi_prepare;
> > +
> > + chip->irq_set_affinity = irq_chip_set_affinity_parent;
> > +
> > + if (IS_ENABLED(CONFIG_X86))
> > + chip->flags |= IRQCHIP_MOVE_DEFERRED;
> > +
> > + return true;
> > +}
> > +
> > +#define HV_PCIE_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
> > + MSI_FLAG_USE_DEF_CHIP_OPS | \
> > + MSI_FLAG_PCI_MSI_MASK_PARENT)
> > +#define HV_PCIE_MSI_FLAGS_SUPPORTED (MSI_FLAG_MULTI_PCI_MSI | \
> > + MSI_FLAG_PCI_MSIX | \
> > + MSI_GENERIC_FLAGS_MASK)
> > +
> > +static const struct msi_parent_ops hv_pcie_msi_parent_ops = {
> > + .required_flags = HV_PCIE_MSI_FLAGS_REQUIRED,
> > + .supported_flags = HV_PCIE_MSI_FLAGS_SUPPORTED,
> > + .bus_select_token = DOMAIN_BUS_PCI_MSI,
> > +#ifdef CONFIG_X86
> > + .chip_flags = MSI_CHIP_FLAG_SET_ACK,
> > +#elif defined(CONFIG_ARM64)
> > + .chip_flags = MSI_CHIP_FLAG_SET_EOI,
> > +#endif
> > + .prefix = "HV-",
> > + .init_dev_msi_info = hv_pcie_init_dev_msi_info,
> > +};
> > +
> > /* HW Interrupt Chip Descriptor */
> > static struct irq_chip hv_msi_irq_chip = {
> > .name = "Hyper-V PCIe MSI",
> > @@ -2108,7 +2144,6 @@ static struct irq_chip hv_msi_irq_chip = {
> > .irq_set_affinity = irq_chip_set_affinity_parent,
> > #ifdef CONFIG_X86
> > .irq_ack = irq_chip_ack_parent,
> > - .flags = IRQCHIP_MOVE_DEFERRED,
> > #elif defined(CONFIG_ARM64)
> > .irq_eoi = irq_chip_eoi_parent,
> > #endif
>
> Would it work to drop the #ifdef's and always set both .irq_ack and
> .irq_eoi on x86 and on ARM64? Is which one gets called controlled by the
> child HV-PCI-MSIX- ... domain, based on the .chip_flags?
>
> I'm trying to reduce the #ifdef clutter. I
> tested without the #ifdefs on both x86 and arm64, and
> everything works, but I know that doesn't prove that it's
> OK.
Nothing is wrong with that, as far as I can tell.
> If the #ifdefs can go away, then I'd like to see a tweak to the way
> .chip_flags is set. Rather than do an #ifdef inline for struct
> msi_parent_ops hv_pcie_msi_parent_ops, add a #define
> HV_MSI_CHIP_FLAGS in the existing #ifdef X86 and #ifdef ARM64
> sections respectively near the top of this source file, and then
> use HV_MSI_CHIP_FLAGS in struct msi_parent_ops
> hv_pcie_msi_parent_ops. As much as is reasonable, I'd like to
> not clutter the code with #ifdef X86 #elseif ARM64, but instead
> group all the differences under the existing #ifdefs near the top.
> There are some places where this isn't practical, but this seems
> like a place that is practical.
Yes, that would be better. I will do it in v2.
> > @@ -2116,9 +2151,37 @@ static struct irq_chip hv_msi_irq_chip = {
> > .irq_unmask = hv_irq_unmask,
> > };
> >
> > -static struct msi_domain_ops hv_msi_ops = {
> > - .msi_prepare = hv_msi_prepare,
> > - .msi_free = hv_msi_free,
> > +static int hv_pcie_domain_alloc(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs,
> > + void *arg)
> > +{
> > + /* TODO: move the content of hv_compose_msi_msg() in here */
>
> Could you elaborate on this TODO? Is the idea to loop through all the IRQs and
> generate the MSI message for each one? What is the advantage to doing it here?
> I noticed in Patch 3 of the series, the Aardvark controller has
> advk_msi_irq_compose_msi_msg(), but you had not moved it into the domain
> allocation path.
Sorry for being unclear. hv_compose_msi_msg() should not be moved here
entirely. Let me elaborate this in v2.
What I meant is that, hv_compose_msi_msg() is doing more than what this
callback is supposed to do (composing message). It works, but it is not
correct. Interrupt allocation is the responsibility of
irq_domain_ops::alloc(). Allocating and populating int_desc should be in
hv_pcie_domain_alloc() instead.
irq_domain_ops's .alloc() and .free() should be asymmetric.
>
> Also, is there some point in the time in the future where the "TODO" is likely to
> become a "MUST DO"?
There's nothing planned that would make this non-functional, as far as I
know.
Thanks so much for examining the patch,
Nam
^ permalink raw reply
* RE: [PATCH] irqdomain: Export irq_domain_free_irqs_top()
From: Michael Kelley @ 2025-07-05 3:54 UTC (permalink / raw)
To: Nam Cao, Thomas Gleixner, K . Y . Srinivasan, Bjorn Helgaas,
Haiyang Zhang, Wei Liu, Dexuan Cui, linux-hyperv@vger.kernel.org
In-Reply-To: <20250703212054.2561551-1-namcao@linutronix.de>
From: Nam Cao <namcao@linutronix.de> Sent: Thursday, July 3, 2025 2:21 PM
>
> Export irq_domain_free_irqs_top(), making it usable for drivers compiled as
> modules.
>
> Signed-off-by: Nam Cao <namcao@linutronix.de>
> ---
> kernel/irq/irqdomain.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index c8b6de09047b..46919e6c9c45 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -1561,6 +1561,7 @@ void irq_domain_free_irqs_top(struct irq_domain *domain, unsigned int virq,
> }
> irq_domain_free_irqs_common(domain, virq, nr_irqs);
> }
> +EXPORT_SYMBOL_GPL(irq_domain_free_irqs_top);
>
> static void irq_domain_free_irqs_hierarchy(struct irq_domain *domain,
> unsigned int irq_base,
> --
> 2.39.5
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
^ permalink raw reply
* RE: [PATCH 14/16] PCI: hv: Switch to msi_create_parent_irq_domain()
From: Michael Kelley @ 2025-07-05 3:51 UTC (permalink / raw)
To: Nam Cao, Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org, Karthikeyan Mitran, Hou Zhiqiang,
Thomas Petazzoni, Pali Rohár, K . Y . Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi, Jim Quinlan,
Nicolas Saenz Julienne, Florian Fainelli,
Broadcom internal kernel review list, Ray Jui, Scott Branden,
Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
Matthias Brugger, AngeloGioacchino Del Regno,
linux-arm-kernel@lists.infradead.org,
linux-hyperv@vger.kernel.org,
linux-rpi-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <024f0122314198fe0a42fef01af53e8953a687ec.1750858083.git.namcao@linutronix.de>
From: Nam Cao <namcao@linutronix.de> Sent: Thursday, June 26, 2025 7:48 AM
>
> Move away from the legacy MSI domain setup, switch to use
> msi_create_parent_irq_domain().
With the additional tweak to this patch that you supplied separately,
everything in my testing on both x86 and arm64 seems to work OK. So
that's all good.
On arm64, I did notice the following IRQ domain information from
/sys/kernel/debug/irq/domains:
# cat HV-PCI-MSIX-1e03\:00\:00.0-12
name: HV-PCI-MSIX-1e03:00:00.0-12
size: 0
mapped: 7
flags: 0x00000213
IRQ_DOMAIN_FLAG_HIERARCHY
IRQ_DOMAIN_NAME_ALLOCATED
IRQ_DOMAIN_FLAG_MSI
IRQ_DOMAIN_FLAG_MSI_DEVICE
parent: 5D202AA8-1E03-4F0F-A786-390A0D2749E9-3
name: 5D202AA8-1E03-4F0F-A786-390A0D2749E9-3
size: 0
mapped: 7
flags: 0x00000103
IRQ_DOMAIN_FLAG_HIERARCHY
IRQ_DOMAIN_NAME_ALLOCATED
IRQ_DOMAIN_FLAG_MSI_PARENT
parent: hv_vpci_arm64
name: hv_vpci_arm64
size: 956
mapped: 31
flags: 0x00000003
IRQ_DOMAIN_FLAG_HIERARCHY
IRQ_DOMAIN_NAME_ALLOCATED
parent: irqchip@0x00000000ffff0000-1
name: irqchip@0x00000000ffff0000-1
size: 0
mapped: 47
flags: 0x00000003
IRQ_DOMAIN_FLAG_HIERARCHY
IRQ_DOMAIN_NAME_ALLOCATED
The 5D202AA8-1E03-4F0F-A786-390A0D2749E9-3 domain has
IRQ_DOMAIN_FLAG_MSI_PARENT set. But the hv_vpci_arm64
and irqchip@... domains do not. Is that a problem? On x86,
the output is this, with IRQ_DOMAIN_FLAG_MSI_PARENT set
in the next level up VECTOR domain:
# cat HV-PCI-MSIX-6b71\:00\:02.0-12
name: HV-PCI-MSIX-6b71:00:02.0-12
size: 0
mapped: 17
flags: 0x00000213
IRQ_DOMAIN_FLAG_HIERARCHY
IRQ_DOMAIN_NAME_ALLOCATED
IRQ_DOMAIN_FLAG_MSI
IRQ_DOMAIN_FLAG_MSI_DEVICE
parent: 8564CB14-6B71-477C-B189-F175118E6FF0-3
name: 8564CB14-6B71-477C-B189-F175118E6FF0-3
size: 0
mapped: 17
flags: 0x00000103
IRQ_DOMAIN_FLAG_HIERARCHY
IRQ_DOMAIN_NAME_ALLOCATED
IRQ_DOMAIN_FLAG_MSI_PARENT
parent: VECTOR
name: VECTOR
size: 0
mapped: 67
flags: 0x00000103
IRQ_DOMAIN_FLAG_HIERARCHY
IRQ_DOMAIN_NAME_ALLOCATED
IRQ_DOMAIN_FLAG_MSI_PARENT
Finally, I've noted a couple of code review comments below. These
comments may reflect my lack of fully understanding the MSI
IRQ handling, in which case, please set me straight. Thanks,
Michael
>
> Signed-off-by: Nam Cao <namcao@linutronix.de>
> ---
> Cc: K. Y. Srinivasan <kys@microsoft.com>
> Cc: Haiyang Zhang <haiyangz@microsoft.com>
> Cc: Wei Liu <wei.liu@kernel.org>
> Cc: Dexuan Cui <decui@microsoft.com>
> Cc: linux-hyperv@vger.kernel.org
> ---
> drivers/pci/Kconfig | 1 +
> drivers/pci/controller/pci-hyperv.c | 98 +++++++++++++++++++++++------
> 2 files changed, 80 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
> index 9c0e4aaf4e8cb..9a249c65aedcd 100644
> --- a/drivers/pci/Kconfig
> +++ b/drivers/pci/Kconfig
> @@ -223,6 +223,7 @@ config PCI_HYPERV
> tristate "Hyper-V PCI Frontend"
> depends on ((X86 && X86_64) || ARM64) && HYPERV && PCI_MSI && SYSFS
> select PCI_HYPERV_INTERFACE
> + select IRQ_MSI_LIB
> help
> The PCI device frontend driver allows the kernel to import arbitrary
> PCI devices from a PCI backend to support PCI driver domains.
> diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
> index ef5d655a0052c..3a24fadddb83b 100644
> --- a/drivers/pci/controller/pci-hyperv.c
> +++ b/drivers/pci/controller/pci-hyperv.c
> @@ -44,6 +44,7 @@
> #include <linux/delay.h>
> #include <linux/semaphore.h>
> #include <linux/irq.h>
> +#include <linux/irqchip/irq-msi-lib.h>
> #include <linux/msi.h>
> #include <linux/hyperv.h>
> #include <linux/refcount.h>
> @@ -508,7 +509,6 @@ struct hv_pcibus_device {
> struct list_head children;
> struct list_head dr_list;
>
> - struct msi_domain_info msi_info;
> struct irq_domain *irq_domain;
>
> struct workqueue_struct *wq;
> @@ -1687,7 +1687,7 @@ static void hv_msi_free(struct irq_domain *domain, struct msi_domain_info *info,
> struct msi_desc *msi = irq_data_get_msi_desc(irq_data);
>
> pdev = msi_desc_to_pci_dev(msi);
> - hbus = info->data;
> + hbus = domain->host_data;
> int_desc = irq_data_get_irq_chip_data(irq_data);
> if (!int_desc)
> return;
> @@ -1705,7 +1705,6 @@ static void hv_msi_free(struct irq_domain *domain, struct msi_domain_info *info,
>
> static void hv_irq_mask(struct irq_data *data)
> {
> - pci_msi_mask_irq(data);
> if (data->parent_data->chip->irq_mask)
> irq_chip_mask_parent(data);
> }
> @@ -1716,7 +1715,6 @@ static void hv_irq_unmask(struct irq_data *data)
>
> if (data->parent_data->chip->irq_unmask)
> irq_chip_unmask_parent(data);
> - pci_msi_unmask_irq(data);
> }
>
> struct compose_comp_ctxt {
> @@ -2101,6 +2099,44 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
> msg->data = 0;
> }
>
> +static bool hv_pcie_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
> + struct irq_domain *real_parent, struct msi_domain_info *info)
> +{
> + struct irq_chip *chip = info->chip;
> +
> + if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info))
> + return false;
> +
> + info->ops->msi_prepare = hv_msi_prepare;
> +
> + chip->irq_set_affinity = irq_chip_set_affinity_parent;
> +
> + if (IS_ENABLED(CONFIG_X86))
> + chip->flags |= IRQCHIP_MOVE_DEFERRED;
> +
> + return true;
> +}
> +
> +#define HV_PCIE_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
> + MSI_FLAG_USE_DEF_CHIP_OPS | \
> + MSI_FLAG_PCI_MSI_MASK_PARENT)
> +#define HV_PCIE_MSI_FLAGS_SUPPORTED (MSI_FLAG_MULTI_PCI_MSI | \
> + MSI_FLAG_PCI_MSIX | \
> + MSI_GENERIC_FLAGS_MASK)
> +
> +static const struct msi_parent_ops hv_pcie_msi_parent_ops = {
> + .required_flags = HV_PCIE_MSI_FLAGS_REQUIRED,
> + .supported_flags = HV_PCIE_MSI_FLAGS_SUPPORTED,
> + .bus_select_token = DOMAIN_BUS_PCI_MSI,
> +#ifdef CONFIG_X86
> + .chip_flags = MSI_CHIP_FLAG_SET_ACK,
> +#elif defined(CONFIG_ARM64)
> + .chip_flags = MSI_CHIP_FLAG_SET_EOI,
> +#endif
> + .prefix = "HV-",
> + .init_dev_msi_info = hv_pcie_init_dev_msi_info,
> +};
> +
> /* HW Interrupt Chip Descriptor */
> static struct irq_chip hv_msi_irq_chip = {
> .name = "Hyper-V PCIe MSI",
> @@ -2108,7 +2144,6 @@ static struct irq_chip hv_msi_irq_chip = {
> .irq_set_affinity = irq_chip_set_affinity_parent,
> #ifdef CONFIG_X86
> .irq_ack = irq_chip_ack_parent,
> - .flags = IRQCHIP_MOVE_DEFERRED,
> #elif defined(CONFIG_ARM64)
> .irq_eoi = irq_chip_eoi_parent,
> #endif
Would it work to drop the #ifdef's and always set both .irq_ack
and .irq_eoi on x86 and on ARM64? Is which one gets called
controlled by the child HV-PCI-MSIX- ... domain, based on
the .chip_flags? I'm trying to reduce the #ifdef clutter. I
tested without the #ifdefs on both x86 and arm64, and
everything works, but I know that doesn't prove that it's
OK.
If the #ifdefs can go away, then I'd like to see a tweak to the way
.chip_flags is set. Rather than do an #ifdef inline for struct
msi_parent_ops hv_pcie_msi_parent_ops, add a #define
HV_MSI_CHIP_FLAGS in the existing #ifdef X86 and #ifdef ARM64
sections respectively near the top of this source file, and then
use HV_MSI_CHIP_FLAGS in struct msi_parent_ops
hv_pcie_msi_parent_ops. As much as is reasonable, I'd like to
not clutter the code with #ifdef X86 #elseif ARM64, but instead
group all the differences under the existing #ifdefs near the top.
There are some places where this isn't practical, but this seems
like a place that is practical.
> @@ -2116,9 +2151,37 @@ static struct irq_chip hv_msi_irq_chip = {
> .irq_unmask = hv_irq_unmask,
> };
>
> -static struct msi_domain_ops hv_msi_ops = {
> - .msi_prepare = hv_msi_prepare,
> - .msi_free = hv_msi_free,
> +static int hv_pcie_domain_alloc(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs,
> + void *arg)
> +{
> + /* TODO: move the content of hv_compose_msi_msg() in here */
Could you elaborate on this TODO? Is the idea to loop through all the IRQs and
generate the MSI message for each one? What is the advantage to doing it here?
I noticed in Patch 3 of the series, the Aardvark controller has
advk_msi_irq_compose_msi_msg(), but you had not moved it into the domain
allocation path.
Also, is there some point in the time in the future where the "TODO" is likely to
become a "MUST DO"?
> + int ret;
> +
> + ret = irq_domain_alloc_irqs_parent(d, virq, nr_irqs, arg);
> + if (ret < 0)
> + return ret;
> +
> + for (int i = 0; i < nr_irqs; i++) {
> + irq_domain_set_info(d, virq + i, 0, &hv_msi_irq_chip, NULL, FLOW_HANDLER, NULL,
> + FLOW_NAME);
> + }
> +
> + return 0;
> +}
> +
> +static void hv_pcie_domain_free(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs)
> +{
> + struct msi_domain_info *info = d->host_data;
> +
> + for (int i = 0; i < nr_irqs; i++)
> + hv_msi_free(d, info, virq + i);
> +
> + irq_domain_free_irqs_top(d, virq, nr_irqs);
> +}
> +
> +static const struct irq_domain_ops hv_pcie_domain_ops = {
> + .alloc = hv_pcie_domain_alloc,
> + .free = hv_pcie_domain_free,
> };
>
> /**
> @@ -2136,17 +2199,14 @@ static struct msi_domain_ops hv_msi_ops = {
> */
> static int hv_pcie_init_irq_domain(struct hv_pcibus_device *hbus)
> {
> - hbus->msi_info.chip = &hv_msi_irq_chip;
> - hbus->msi_info.ops = &hv_msi_ops;
> - hbus->msi_info.flags = (MSI_FLAG_USE_DEF_DOM_OPS |
> - MSI_FLAG_USE_DEF_CHIP_OPS | MSI_FLAG_MULTI_PCI_MSI |
> - MSI_FLAG_PCI_MSIX);
> - hbus->msi_info.handler = FLOW_HANDLER;
> - hbus->msi_info.handler_name = FLOW_NAME;
> - hbus->msi_info.data = hbus;
> - hbus->irq_domain = pci_msi_create_irq_domain(hbus->fwnode,
> - &hbus->msi_info,
> - hv_pci_get_root_domain());
> + struct irq_domain_info info = {
> + .fwnode = hbus->fwnode,
> + .ops = &hv_pcie_domain_ops,
> + .host_data = hbus,
> + .parent = hv_pci_get_root_domain(),
> + };
> +
> + hbus->irq_domain = msi_create_parent_irq_domain(&info, &hv_pcie_msi_parent_ops);
> if (!hbus->irq_domain) {
> dev_err(&hbus->hdev->device,
> "Failed to build an MSI IRQ domain\n");
> --
> 2.39.5
>
^ permalink raw reply
* RE: [PATCH 14/16] PCI: hv: Switch to msi_create_parent_irq_domain()
From: Michael Kelley @ 2025-07-04 4:58 UTC (permalink / raw)
To: Nam Cao
Cc: Thomas Gleixner, Marc Zyngier, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org, Karthikeyan Mitran, Hou Zhiqiang,
Thomas Petazzoni, Pali Rohár, K . Y . Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi, Jim Quinlan,
Nicolas Saenz Julienne, Florian Fainelli,
Broadcom internal kernel review list, Ray Jui, Scott Branden,
Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
Matthias Brugger, AngeloGioacchino Del Regno,
linux-arm-kernel@lists.infradead.org,
linux-hyperv@vger.kernel.org,
linux-rpi-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <20250704043255.JCK9HyRj@linutronix.de>
From: Nam Cao <namcao@linutronix.de> Sent: Thursday, July 3, 2025 9:33 PM
>
> On Fri, Jul 04, 2025 at 02:27:01AM +0000, Michael Kelley wrote:
> > I haven't resolved the conflict. As a shortcut for testing I just
> > removed the conflicting patch since it is for a Microsoft custom NIC
> > ("MANA") that's not in the configuration I'm testing with. I'll have to
> > look more closely to figure out the resolution.
> >
> > Separately, this patch (the switch to misc_create_parent_irq_domain)
> > isn't working for Linux VMs on Hyper-V on ARM64. The initial symptom
> > is that interrupts from the NVMe controller aren't getting handled
> > and everything hangs. Here's the dmesg output:
> >
> > [ 84.463419] hv_vmbus: registering driver hv_pci
> > [ 84.463875] hv_pci abee639e-0b9d-49b7-9a07-c54ba8cd5734: PCI VMBus probing: Using version 0x10004
> > [ 84.464518] hv_pci abee639e-0b9d-49b7-9a07-c54ba8cd5734: PCI host bridge to bus 0b9d:00
> > [ 84.464529] pci_bus 0b9d:00: root bus resource [mem 0xfc0000000-0xfc00fffff window]
> > [ 84.464531] pci_bus 0b9d:00: No busn resource found for root bus, will use [bus 00-ff]
> > [ 84.465211] pci 0b9d:00:00.0: [1414:b111] type 00 class 0x010802 PCIe Endpoint
> > [ 84.466657] pci 0b9d:00:00.0: BAR 0 [mem 0xfc0000000-0xfc00fffff 64bit]
> > [ 84.481923] pci_bus 0b9d:00: busn_res: [bus 00-ff] end is updated to 00
> > [ 84.481936] pci 0b9d:00:00.0: BAR 0 [mem 0xfc0000000-0xfc00fffff 64bit]: assigned
> > [ 84.482413] nvme nvme0: pci function 0b9d:00:00.0
> > [ 84.482513] nvme 0b9d:00:00.0: enabling device (0000 -> 0002)
> > [ 84.556871] irq 17, desc: 00000000e8529819, depth: 0, count: 0, unhandled: 0
> > [ 84.556883] ->handle_irq(): 0000000062fa78bc, handle_bad_irq+0x0/0x270
> > [ 84.556892] ->irq_data.chip(): 00000000ba07832f, 0xffff00011469dc30
> > [ 84.556895] ->action(): 0000000069f160b3
> > [ 84.556896] ->action->handler(): 00000000e15d8191, nvme_irq+0x0/0x3e8
> > [ 172.307920] watchdog: BUG: soft lockup - CPU#6 stuck for 26s! [kworker/6:1H:195]
>
> Thanks for the report.
>
> On arm64, this driver relies on the parent irq domain to set handler. So
> the driver must not overwrite it to NULL.
>
> This should cures it:
>
> diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
> index 3a24fadddb83..f4a435b0456c 100644
> --- a/drivers/pci/controller/pci-hyperv.c
> +++ b/drivers/pci/controller/pci-hyperv.c
> @@ -577,8 +577,6 @@ static void hv_pci_onchannelcallback(void *context);
>
> #ifdef CONFIG_X86
> #define DELIVERY_MODE APIC_DELIVERY_MODE_FIXED
> -#define FLOW_HANDLER handle_edge_irq
> -#define FLOW_NAME "edge"
>
> static int hv_pci_irqchip_init(void)
> {
> @@ -723,8 +721,6 @@ static void hv_arch_irq_unmask(struct irq_data *data)
> #define HV_PCI_MSI_SPI_START 64
> #define HV_PCI_MSI_SPI_NR (1020 - HV_PCI_MSI_SPI_START)
> #define DELIVERY_MODE 0
> -#define FLOW_HANDLER NULL
> -#define FLOW_NAME NULL
> #define hv_msi_prepare NULL
>
> struct hv_pci_chip_data {
> @@ -2162,8 +2158,9 @@ static int hv_pcie_domain_alloc(struct irq_domain *d,
> unsigned int virq, unsigne
> return ret;
>
> for (int i = 0; i < nr_irqs; i++) {
> - irq_domain_set_info(d, virq + i, 0, &hv_msi_irq_chip, NULL, FLOW_HANDLER, NULL,
> - FLOW_NAME);
> + irq_domain_set_hwirq_and_chip(d, virq + i, 0, &hv_msi_irq_chip, NULL);
> + if (IS_ENABLED(CONFIG_X86))
> + __irq_set_handler(virq + i, handle_edge_irq, 0, "edge");
> }
>
> return 0;
Yes, that fixes the problem. Linux now boots with the PCI NIC VF and two
NVMe controllers being visible and operational. Thanks for the fix! It
would have taken me a while to figure it out.
I want to do some additional testing tomorrow, and look more closely at the
code, but now I have something that works well enough to make further
progress.
Michael
^ permalink raw reply
* Re: [PATCH 00/16] PCI: MSI parent domain conversion
From: Nam Cao @ 2025-07-04 4:48 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, linux-pci, linux-kernel, Karthikeyan Mitran,
Hou Zhiqiang, Thomas Petazzoni, Pali Rohár,
K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi,
Jim Quinlan, Nicolas Saenz Julienne, Florian Fainelli,
Broadcom internal kernel review list, Ray Jui, Scott Branden,
Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
Matthias Brugger, AngeloGioacchino Del Regno, linux-arm-kernel,
linux-hyperv, linux-rpi-kernel, linux-mediatek, linux-renesas-soc
In-Reply-To: <20250703172801.GA1934994@bhelgaas>
On Thu, Jul 03, 2025 at 12:28:01PM -0500, Bjorn Helgaas wrote:
> On Thu, Jun 26, 2025 at 04:47:50PM +0200, Nam Cao wrote:
> > The initial implementation of PCI/MSI interrupt domains in the hierarchical
> > interrupt domain model used a shortcut by providing a global PCI/MSI
> > domain.
> >
> > This works because the PCI/MSI[X] hardware is standardized and uniform, but
> > it violates the basic design principle of hierarchical interrupt domains:
> > Each hardware block involved in the interrupt delivery chain should have a
> > separate interrupt domain.
> >
> > For PCI/MSI[X], the interrupt controller is per PCI device and not a global
> > made-up entity.
> >
> > Unsurprisingly, the shortcut turned out to have downsides as it does not
> > allow dynamic allocation of interrupt vectors after initialization and it
> > prevents supporting IMS on PCI. For further details, see:
> >
> > https://lore.kernel.org/lkml/20221111120501.026511281@linutronix.de/
> >
> > The solution is implementing per device MSI domains, this means the
> > entities which provide global PCI/MSI domain so far have to implement MSI
> > parent domain functionality instead.
> >
> > This series converts the PCI controller drivers to implement MSI parent
> > domain.
> >
> > drivers/pci/Kconfig | 1 +
> > drivers/pci/controller/Kconfig | 11 +
> > drivers/pci/controller/dwc/Kconfig | 1 +
> > .../pci/controller/dwc/pcie-designware-host.c | 68 ++----
> > drivers/pci/controller/dwc/pcie-designware.h | 1 -
> > drivers/pci/controller/mobiveil/Kconfig | 1 +
> > .../controller/mobiveil/pcie-mobiveil-host.c | 42 ++--
> > .../pci/controller/mobiveil/pcie-mobiveil.h | 1 -
> > drivers/pci/controller/pci-aardvark.c | 59 ++---
> > drivers/pci/controller/pci-hyperv.c | 98 ++++++--
> > drivers/pci/controller/pcie-altera-msi.c | 44 ++--
> > drivers/pci/controller/pcie-brcmstb.c | 44 ++--
> > drivers/pci/controller/pcie-iproc-msi.c | 45 ++--
> > drivers/pci/controller/pcie-mediatek-gen3.c | 67 ++---
> > drivers/pci/controller/pcie-mediatek.c | 46 ++--
> > drivers/pci/controller/pcie-rcar-host.c | 69 ++----
> > drivers/pci/controller/pcie-xilinx-dma-pl.c | 48 ++--
> > drivers/pci/controller/pcie-xilinx-nwl.c | 45 ++--
> > drivers/pci/controller/pcie-xilinx.c | 55 +++--
> > drivers/pci/controller/plda/Kconfig | 1 +
> > drivers/pci/controller/plda/pcie-plda-host.c | 44 ++--
> > drivers/pci/controller/plda/pcie-plda.h | 1 -
> > drivers/pci/controller/vmd.c | 229 +++++++++---------
> > 23 files changed, 504 insertions(+), 517 deletions(-)
>
> Looks good to me, thanks! I think Mani will probably pick this up.
>
> I might have included the specific "legacy MSI domain" thing you're
> replacing. It looks like you're replacing pci_msi_create_irq_domain()
> with msi_create_parent_irq_domain()?
Yes, pci_msi_create_irq_domain() is legacy. We will delete it once
everything is converted.
> Minor merge conflict in pcie-mediatek-gen3.c with dcbea1c7e94e ("PCI:
> mediatek-gen3: Use dev_fwnode() for irq_domain_create_linear()"). No
> problem, we can easily fix that up.
Thanks!
> The "++i" in vmd.c stuck out to me since "i++" is so much more common.
I always do "++i", maybe I'm the weird one..
Best regards,
Nam
^ permalink raw reply
* Re: [PATCH 14/16] PCI: hv: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-07-04 4:32 UTC (permalink / raw)
To: Michael Kelley
Cc: Thomas Gleixner, Marc Zyngier, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org, Karthikeyan Mitran, Hou Zhiqiang,
Thomas Petazzoni, Pali Rohár, K . Y . Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi, Jim Quinlan,
Nicolas Saenz Julienne, Florian Fainelli,
Broadcom internal kernel review list, Ray Jui, Scott Branden,
Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
Matthias Brugger, AngeloGioacchino Del Regno,
linux-arm-kernel@lists.infradead.org,
linux-hyperv@vger.kernel.org,
linux-rpi-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <SN6PR02MB41573141969F6B3028099C65D442A@SN6PR02MB4157.namprd02.prod.outlook.com>
On Fri, Jul 04, 2025 at 02:27:01AM +0000, Michael Kelley wrote:
> I haven't resolved the conflict. As a shortcut for testing I just
> removed the conflicting patch since it is for a Microsoft custom NIC
> ("MANA") that's not in the configuration I'm testing with. I'll have to
> look more closely to figure out the resolution.
>
> Separately, this patch (the switch to misc_create_parent_irq_domain)
> isn't working for Linux VMs on Hyper-V on ARM64. The initial symptom
> is that interrupts from the NVMe controller aren't getting handled
> and everything hangs. Here's the dmesg output:
>
> [ 84.463419] hv_vmbus: registering driver hv_pci
> [ 84.463875] hv_pci abee639e-0b9d-49b7-9a07-c54ba8cd5734: PCI VMBus probing: Using version 0x10004
> [ 84.464518] hv_pci abee639e-0b9d-49b7-9a07-c54ba8cd5734: PCI host bridge to bus 0b9d:00
> [ 84.464529] pci_bus 0b9d:00: root bus resource [mem 0xfc0000000-0xfc00fffff window]
> [ 84.464531] pci_bus 0b9d:00: No busn resource found for root bus, will use [bus 00-ff]
> [ 84.465211] pci 0b9d:00:00.0: [1414:b111] type 00 class 0x010802 PCIe Endpoint
> [ 84.466657] pci 0b9d:00:00.0: BAR 0 [mem 0xfc0000000-0xfc00fffff 64bit]
> [ 84.481923] pci_bus 0b9d:00: busn_res: [bus 00-ff] end is updated to 00
> [ 84.481936] pci 0b9d:00:00.0: BAR 0 [mem 0xfc0000000-0xfc00fffff 64bit]: assigned
> [ 84.482413] nvme nvme0: pci function 0b9d:00:00.0
> [ 84.482513] nvme 0b9d:00:00.0: enabling device (0000 -> 0002)
> [ 84.556871] irq 17, desc: 00000000e8529819, depth: 0, count: 0, unhandled: 0
> [ 84.556883] ->handle_irq(): 0000000062fa78bc, handle_bad_irq+0x0/0x270
> [ 84.556892] ->irq_data.chip(): 00000000ba07832f, 0xffff00011469dc30
> [ 84.556895] ->action(): 0000000069f160b3
> [ 84.556896] ->action->handler(): 00000000e15d8191, nvme_irq+0x0/0x3e8
> [ 172.307920] watchdog: BUG: soft lockup - CPU#6 stuck for 26s! [kworker/6:1H:195]
Thanks for the report.
On arm64, this driver relies on the parent irq domain to set handler. So
the driver must not overwrite it to NULL.
This should cures it:
diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index 3a24fadddb83..f4a435b0456c 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -577,8 +577,6 @@ static void hv_pci_onchannelcallback(void *context);
#ifdef CONFIG_X86
#define DELIVERY_MODE APIC_DELIVERY_MODE_FIXED
-#define FLOW_HANDLER handle_edge_irq
-#define FLOW_NAME "edge"
static int hv_pci_irqchip_init(void)
{
@@ -723,8 +721,6 @@ static void hv_arch_irq_unmask(struct irq_data *data)
#define HV_PCI_MSI_SPI_START 64
#define HV_PCI_MSI_SPI_NR (1020 - HV_PCI_MSI_SPI_START)
#define DELIVERY_MODE 0
-#define FLOW_HANDLER NULL
-#define FLOW_NAME NULL
#define hv_msi_prepare NULL
struct hv_pci_chip_data {
@@ -2162,8 +2158,9 @@ static int hv_pcie_domain_alloc(struct irq_domain *d, unsigned int virq, unsigne
return ret;
for (int i = 0; i < nr_irqs; i++) {
- irq_domain_set_info(d, virq + i, 0, &hv_msi_irq_chip, NULL, FLOW_HANDLER, NULL,
- FLOW_NAME);
+ irq_domain_set_hwirq_and_chip(d, virq + i, 0, &hv_msi_irq_chip, NULL);
+ if (IS_ENABLED(CONFIG_X86))
+ __irq_set_handler(virq + i, handle_edge_irq, 0, "edge");
}
return 0;
^ permalink raw reply related
* RE: [PATCH 14/16] PCI: hv: Switch to msi_create_parent_irq_domain()
From: Michael Kelley @ 2025-07-04 2:27 UTC (permalink / raw)
To: Thomas Gleixner, Nam Cao, Marc Zyngier, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org, Karthikeyan Mitran, Hou Zhiqiang,
Thomas Petazzoni, Pali Rohár, K . Y . Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi, Jim Quinlan,
Nicolas Saenz Julienne, Florian Fainelli,
Broadcom internal kernel review list, Ray Jui, Scott Branden,
Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
Matthias Brugger, AngeloGioacchino Del Regno,
linux-arm-kernel@lists.infradead.org,
linux-hyperv@vger.kernel.org,
linux-rpi-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <87zfdlrmvr.ffs@tglx>
From: Thomas Gleixner <tglx@linutronix.de> Sent: Thursday, July 3, 2025 2:22 PM
>
> On Thu, Jul 03 2025 at 20:15, Michael Kelley wrote:
> > From: Thomas Gleixner <tglx@linutronix.de> Sent: Thursday, July 3, 2025 1:00 PM
> >> Does it conflict against the PCI tree?
> >
> > There's no conflict in the "next" or "for-linus" tags in
> > https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/
> >
> > The conflict is with Patch 2 of this series:
> >
> > https://lore.kernel.org/linux-hyperv/1749650984-9193-1-git-send-email-shradhagupta@linux.microsoft.com/
> >
> > which is in netdev/net-next.
>
> That's a trivial one. There are two ways to handle it:
>
> 1) Take it through the PCI tree and provide a conflict resolution for
> linux-next and later for Linus as reference.
>
> 2) Route it through the net-next tree with an updated patch.
>
> As there are no further dependencies (aside of the missing export which
> is needed anyway) it's obvious to pick #2 as it creates the least
> headaches. Assumed that the PCI folks have no objections.
>
> Michael, as you have resolved the conflict already, can you please
> either take care of it yourself or provide the resolution here as
> reference for Nam?
I haven't resolved the conflict. As a shortcut for testing I just
removed the conflicting patch since it is for a Microsoft custom NIC
("MANA") that's not in the configuration I'm testing with. I'll have to
look more closely to figure out the resolution.
Separately, this patch (the switch to misc_create_parent_irq_domain)
isn't working for Linux VMs on Hyper-V on ARM64. The initial symptom
is that interrupts from the NVMe controller aren't getting handled
and everything hangs. Here's the dmesg output:
[ 84.463419] hv_vmbus: registering driver hv_pci
[ 84.463875] hv_pci abee639e-0b9d-49b7-9a07-c54ba8cd5734: PCI VMBus probing: Using version 0x10004
[ 84.464518] hv_pci abee639e-0b9d-49b7-9a07-c54ba8cd5734: PCI host bridge to bus 0b9d:00
[ 84.464529] pci_bus 0b9d:00: root bus resource [mem 0xfc0000000-0xfc00fffff window]
[ 84.464531] pci_bus 0b9d:00: No busn resource found for root bus, will use [bus 00-ff]
[ 84.465211] pci 0b9d:00:00.0: [1414:b111] type 00 class 0x010802 PCIe Endpoint
[ 84.466657] pci 0b9d:00:00.0: BAR 0 [mem 0xfc0000000-0xfc00fffff 64bit]
[ 84.481923] pci_bus 0b9d:00: busn_res: [bus 00-ff] end is updated to 00
[ 84.481936] pci 0b9d:00:00.0: BAR 0 [mem 0xfc0000000-0xfc00fffff 64bit]: assigned
[ 84.482413] nvme nvme0: pci function 0b9d:00:00.0
[ 84.482513] nvme 0b9d:00:00.0: enabling device (0000 -> 0002)
[ 84.556871] irq 17, desc: 00000000e8529819, depth: 0, count: 0, unhandled: 0
[ 84.556883] ->handle_irq(): 0000000062fa78bc, handle_bad_irq+0x0/0x270
[ 84.556892] ->irq_data.chip(): 00000000ba07832f, 0xffff00011469dc30
[ 84.556895] ->action(): 0000000069f160b3
[ 84.556896] ->action->handler(): 00000000e15d8191, nvme_irq+0x0/0x3e8
[ 172.307920] watchdog: BUG: soft lockup - CPU#6 stuck for 26s! [kworker/6:1H:195]
Everything looks normal up to the "irq 17" line. Meanwhile, the device probe path
is waiting with this stack trace, which I suspect is the first Interaction with the NVMe
controller:
[<0>] blk_execute_rq+0x1ec/0x348
[<0>] nvme_execute_rq+0x20/0x68
[<0>] __nvme_submit_sync_cmd+0xc8/0x170
[<0>] nvme_identify_ctrl.isra.0+0x90/0xf0
[<0>] nvme_init_identify+0x44/0xee0
[<0>] nvme_init_ctrl_finish+0x84/0x370
[<0>] nvme_probe+0x668/0x7d8
[<0>] local_pci_probe+0x48/0xd0
[<0>] pci_device_probe+0xd0/0x248
[<0>] really_probe+0xd4/0x388
[<0>] __driver_probe_device+0x90/0x1a8
[<0>] driver_probe_device+0x48/0x150
[<0>] __device_attach_driver+0xe0/0x1b8
[<0>] bus_for_each_drv+0x8c/0xf8
[<0>] __device_attach+0x104/0x1e8
[<0>] device_attach+0x1c/0x30
[<0>] pci_bus_add_device+0xe0/0x188
[<0>] pci_bus_add_devices+0x40/0x98
[<0>] hv_pci_probe+0x4b0/0x690 [pci_hyperv]
[<0>] vmbus_probe+0x4c/0xb0 [hv_vmbus]
[<0>] really_probe+0xd4/0x388
[<0>] __driver_probe_device+0x90/0x1a8
[<0>] driver_probe_device+0x48/0x150
[<0>] __driver_attach+0xe8/0x1c8
[<0>] bus_for_each_dev+0x80/0xf0
[<0>] driver_attach+0x2c/0x40
[<0>] bus_add_driver+0x118/0x260
[<0>] driver_register+0x68/0x138
[<0>] __vmbus_driver_register+0x70/0x98 [hv_vmbus]
[<0>] init_hv_pci_drv+0x1b8/0xfff8 [pci_hyperv]
[<0>] do_one_initcall+0x4c/0x2c8
[<0>] do_init_module+0x60/0x280
[<0>] load_module+0x2318/0x2448
[<0>] init_module_from_file+0x94/0xe0
[<0>] __arm64_sys_finit_module+0x228/0x3e8
[<0>] invoke_syscall+0x6c/0xf8
[<0>] el0_svc_common.constprop.0+0xc8/0xf0
[<0>] do_el0_svc+0x24/0x38
[<0>] el0_svc+0x40/0x1a0
[<0>] el0t_64_sync_handler+0xd0/0xe8
[<0>] el0t_64_sync+0x1b0/0x1b8
I'll try to figure out what's going wrong.
Michael
^ permalink raw reply
* [PATCH v2 6/6] PCI: hv: Use the correct hypercall for unmasking interrupts on nested
From: Nuno Das Neves @ 2025-07-03 22:44 UTC (permalink / raw)
To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, mhklinux,
tglx, bhelgaas, romank
Cc: kys, haiyangz, wei.liu, decui, catalin.marinas, will, mingo, bp,
dave.hansen, hpa, lpieralisi, kw, robh, jinankjain, skinsburskii,
mrathor, x86, Nuno Das Neves
In-Reply-To: <1751582677-30930-1-git-send-email-nunodasneves@linux.microsoft.com>
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>
---
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 4d25754dfe2f..9a8cba39ea6b 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
* [PATCH v2 5/6] x86: hyperv: Expose hv_map_msi_interrupt function
From: Nuno Das Neves @ 2025-07-03 22:44 UTC (permalink / raw)
To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, mhklinux,
tglx, bhelgaas, romank
Cc: kys, haiyangz, wei.liu, decui, catalin.marinas, will, mingo, bp,
dave.hansen, hpa, lpieralisi, kw, robh, jinankjain, skinsburskii,
mrathor, x86, Nuno Das Neves
In-Reply-To: <1751582677-30930-1-git-send-email-nunodasneves@linux.microsoft.com>
From: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
This patch moves a part of currently internal logic into the
hv_map_msi_interrupt function and makes it globally available helper
function, which will be used to map PCI interrupts in case of 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 | 38 +++++++++++++++++++++++----------
arch/x86/include/asm/mshyperv.h | 2 ++
2 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c
index 75b25724b045..eca015563420 100644
--- a/arch/x86/hyperv/irqdomain.c
+++ b/arch/x86/hyperv/irqdomain.c
@@ -172,13 +172,32 @@ 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.
+ */
+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)
{
@@ -191,11 +210,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);
@@ -205,8 +224,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.
@@ -233,15 +250,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 e00a8431ef8e..42ea9c68f8c8 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -241,6 +241,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
* [PATCH v2 4/6] x86/hyperv: Clean up hv_map/unmap_interrupt() return values
From: Nuno Das Neves @ 2025-07-03 22:44 UTC (permalink / raw)
To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, mhklinux,
tglx, bhelgaas, romank
Cc: kys, haiyangz, wei.liu, decui, catalin.marinas, will, mingo, bp,
dave.hansen, hpa, lpieralisi, kw, robh, jinankjain, skinsburskii,
mrathor, x86, Nuno Das Neves
In-Reply-To: <1751582677-30930-1-git-send-email-nunodasneves@linux.microsoft.com>
Fix the return values of these hypercall helpers so they return
a negated errno either directly or via hv_result_to_errno().
Update the callers to check for errno instead of using
hv_status_success(), and remove redundant error printing.
While at it, rearrange some variable declarations to adhere to style
guidelines i.e. "reverse fir tree order".
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
---
arch/x86/hyperv/irqdomain.c | 32 ++++++++++++++------------------
drivers/iommu/hyperv-iommu.c | 33 ++++++++++++---------------------
2 files changed, 26 insertions(+), 39 deletions(-)
diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c
index e28c317ac9e8..75b25724b045 100644
--- a/arch/x86/hyperv/irqdomain.c
+++ b/arch/x86/hyperv/irqdomain.c
@@ -46,7 +46,7 @@ static int hv_map_interrupt(union hv_device_id device_id, bool level,
if (nr_bank < 0) {
local_irq_restore(flags);
pr_err("%s: unable to generate VP set\n", __func__);
- return EINVAL;
+ return -EINVAL;
}
intr_desc->target.flags = HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET;
@@ -66,7 +66,7 @@ static int hv_map_interrupt(union hv_device_id device_id, bool level,
if (!hv_result_success(status))
hv_status_err(status, "\n");
- return hv_result(status);
+ return hv_result_to_errno(status);
}
static int hv_unmap_interrupt(u64 id, struct hv_interrupt_entry *old_entry)
@@ -88,7 +88,10 @@ static int hv_unmap_interrupt(u64 id, struct hv_interrupt_entry *old_entry)
status = hv_do_hypercall(HVCALL_UNMAP_DEVICE_INTERRUPT, input, NULL);
local_irq_restore(flags);
- return hv_result(status);
+ if (!hv_result_success(status))
+ hv_status_err(status, "\n");
+
+ return hv_result_to_errno(status);
}
#ifdef CONFIG_PCI_MSI
@@ -188,12 +191,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 msi_desc *msidesc;
- struct pci_dev *dev;
struct hv_interrupt_entry out_entry, *stored_entry;
struct irq_cfg *cfg = irqd_cfg(data);
- int cpu;
- u64 status;
+ struct msi_desc *msidesc;
+ struct pci_dev *dev;
+ int cpu, ret;
msidesc = irq_data_get_msi_desc(data);
dev = msi_desc_to_pci_dev(msidesc);
@@ -217,14 +219,12 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
stored_entry = data->chip_data;
data->chip_data = NULL;
- status = hv_unmap_msi_interrupt(dev, stored_entry);
+ ret = hv_unmap_msi_interrupt(dev, stored_entry);
kfree(stored_entry);
- if (status != HV_STATUS_SUCCESS) {
- hv_status_debug(status, "failed to unmap\n");
+ if (ret)
return;
- }
}
stored_entry = kzalloc(sizeof(*stored_entry), GFP_ATOMIC);
@@ -233,8 +233,8 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
return;
}
- status = hv_map_msi_interrupt(dev, cpu, cfg->vector, &out_entry);
- if (status != HV_STATUS_SUCCESS) {
+ ret = hv_map_msi_interrupt(dev, cpu, cfg->vector, &out_entry);
+ if (ret) {
kfree(stored_entry);
return;
}
@@ -255,7 +255,6 @@ static void hv_teardown_msi_irq(struct pci_dev *dev, struct irq_data *irqd)
{
struct hv_interrupt_entry old_entry;
struct msi_msg msg;
- u64 status;
if (!irqd->chip_data) {
pr_debug("%s: no chip data\n!", __func__);
@@ -268,10 +267,7 @@ static void hv_teardown_msi_irq(struct pci_dev *dev, struct irq_data *irqd)
kfree(irqd->chip_data);
irqd->chip_data = NULL;
- status = hv_unmap_msi_interrupt(dev, &old_entry);
-
- if (status != HV_STATUS_SUCCESS)
- hv_status_err(status, "\n");
+ (void)hv_unmap_msi_interrupt(dev, &old_entry);
}
static void hv_msi_free_irq(struct irq_domain *domain,
diff --git a/drivers/iommu/hyperv-iommu.c b/drivers/iommu/hyperv-iommu.c
index 761ab647f372..0961ac805944 100644
--- a/drivers/iommu/hyperv-iommu.c
+++ b/drivers/iommu/hyperv-iommu.c
@@ -193,15 +193,13 @@ struct hyperv_root_ir_data {
static void
hyperv_root_ir_compose_msi_msg(struct irq_data *irq_data, struct msi_msg *msg)
{
- u64 status;
- u32 vector;
- struct irq_cfg *cfg;
- int ioapic_id;
- const struct cpumask *affinity;
- int cpu;
- struct hv_interrupt_entry entry;
struct hyperv_root_ir_data *data = irq_data->chip_data;
+ struct hv_interrupt_entry entry;
+ const struct cpumask *affinity;
struct IO_APIC_route_entry e;
+ struct irq_cfg *cfg;
+ int cpu, ioapic_id;
+ u32 vector;
cfg = irqd_cfg(irq_data);
affinity = irq_data_get_effective_affinity_mask(irq_data);
@@ -214,23 +212,16 @@ hyperv_root_ir_compose_msi_msg(struct irq_data *irq_data, struct msi_msg *msg)
&& data->entry.ioapic_rte.as_uint64) {
entry = data->entry;
- status = hv_unmap_ioapic_interrupt(ioapic_id, &entry);
-
- if (status != HV_STATUS_SUCCESS)
- hv_status_debug(status, "failed to unmap\n");
+ (void)hv_unmap_ioapic_interrupt(ioapic_id, &entry);
data->entry.ioapic_rte.as_uint64 = 0;
data->entry.source = 0; /* Invalid source */
}
- status = hv_map_ioapic_interrupt(ioapic_id, data->is_level, cpu,
- vector, &entry);
-
- if (status != HV_STATUS_SUCCESS) {
- hv_status_err(status, "map failed\n");
+ if (hv_map_ioapic_interrupt(ioapic_id, data->is_level, cpu,
+ vector, &entry))
return;
- }
data->entry = entry;
@@ -322,10 +313,10 @@ static void hyperv_root_irq_remapping_free(struct irq_domain *domain,
data = irq_data->chip_data;
e = &data->entry;
- if (e->source == HV_DEVICE_TYPE_IOAPIC
- && e->ioapic_rte.as_uint64)
- hv_unmap_ioapic_interrupt(data->ioapic_id,
- &data->entry);
+ if (e->source == HV_DEVICE_TYPE_IOAPIC &&
+ e->ioapic_rte.as_uint64)
+ (void)hv_unmap_ioapic_interrupt(data->ioapic_id,
+ &data->entry);
kfree(data);
}
--
2.34.1
^ permalink raw reply related
* [PATCH v2 3/6] x86/hyperv: Fix usage of cpu_online_mask to get valid cpu
From: Nuno Das Neves @ 2025-07-03 22:44 UTC (permalink / raw)
To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, mhklinux,
tglx, bhelgaas, romank
Cc: kys, haiyangz, wei.liu, decui, catalin.marinas, will, mingo, bp,
dave.hansen, hpa, lpieralisi, kw, robh, jinankjain, skinsburskii,
mrathor, x86, Nuno Das Neves
In-Reply-To: <1751582677-30930-1-git-send-email-nunodasneves@linux.microsoft.com>
Accessing cpu_online_mask here is problematic because the cpus read lock
is not held in this context.
However, cpu_online_mask isn't needed here since the effective affinity
mask is guaranteed to be valid in this callback. So, just use
cpumask_first() to get the cpu instead of ANDing it with cpus_online_mask
unnecessarily.
Fixes: e39397d1fd68 ("x86/hyperv: implement an MSI domain for root partition")
Reported-by: Michael Kelley <mhklinux@outlook.com>
Closes: https://lore.kernel.org/linux-hyperv/SN6PR02MB4157639630F8AD2D8FD8F52FD475A@SN6PR02MB4157.namprd02.prod.outlook.com/
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
---
arch/x86/hyperv/irqdomain.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c
index 31f0d29cbc5e..e28c317ac9e8 100644
--- a/arch/x86/hyperv/irqdomain.c
+++ b/arch/x86/hyperv/irqdomain.c
@@ -192,7 +192,6 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
struct pci_dev *dev;
struct hv_interrupt_entry out_entry, *stored_entry;
struct irq_cfg *cfg = irqd_cfg(data);
- const cpumask_t *affinity;
int cpu;
u64 status;
@@ -204,8 +203,7 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
return;
}
- affinity = irq_data_get_effective_affinity_mask(data);
- cpu = cpumask_first_and(affinity, cpu_online_mask);
+ cpu = cpumask_first(irq_data_get_effective_affinity_mask(data));
if (data->chip_data) {
/*
--
2.34.1
^ permalink raw reply related
* [PATCH v2 2/6] Drivers: hv: Use nested hypercall for post message and signal event
From: Nuno Das Neves @ 2025-07-03 22:44 UTC (permalink / raw)
To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, mhklinux,
tglx, bhelgaas, romank
Cc: kys, haiyangz, wei.liu, decui, catalin.marinas, will, mingo, bp,
dave.hansen, hpa, lpieralisi, kw, robh, jinankjain, skinsburskii,
mrathor, x86, Nuno Das Neves
In-Reply-To: <1751582677-30930-1-git-send-email-nunodasneves@linux.microsoft.com>
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 | 7 +++++--
drivers/hv/hv.c | 6 ++++--
3 files changed, 9 insertions(+), 24 deletions(-)
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 5ec92e3e2e37..e00a8431ef8e 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -111,12 +111,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)
{
@@ -164,13 +158,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)
{
@@ -222,13 +209,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..47c93cee1ef6 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -518,8 +518,11 @@ void vmbus_set_event(struct vmbus_channel *channel)
channel->sig_event, 0);
else
WARN_ON_ONCE(1);
- } else {
- hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, channel->sig_event);
+ } else if (hv_nested) {
+ 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
* [PATCH v2 1/6] PCI: hv: Don't load the driver for baremetal root partition
From: Nuno Das Neves @ 2025-07-03 22:44 UTC (permalink / raw)
To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, mhklinux,
tglx, bhelgaas, romank
Cc: kys, haiyangz, wei.liu, decui, catalin.marinas, will, mingo, bp,
dave.hansen, hpa, lpieralisi, kw, robh, jinankjain, skinsburskii,
mrathor, x86, Nuno Das Neves
In-Reply-To: <1751582677-30930-1-git-send-email-nunodasneves@linux.microsoft.com>
From: Mukesh Rathor <mrathor@linux.microsoft.com>
The root partition only uses VMBus when running nested.
When running on baremetal the Hyper-V PCI driver is not needed,
so do not initialize it.
Signed-off-by: Mukesh Rathor <mrathor@linux.microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Roman Kisel <romank@linux.microsoft.com>
---
drivers/pci/controller/pci-hyperv.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index b4f29ee75848..4d25754dfe2f 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -4150,6 +4150,9 @@ static int __init init_hv_pci_drv(void)
if (!hv_is_hyperv_initialized())
return -ENODEV;
+ if (hv_root_partition() && !hv_nested)
+ return -ENODEV;
+
ret = hv_pci_irqchip_init();
if (ret)
return ret;
--
2.34.1
^ permalink raw reply related
* [PATCH v2 0/6] Nested virtualization fixes for root partition
From: Nuno Das Neves @ 2025-07-03 22:44 UTC (permalink / raw)
To: linux-hyperv, linux-arm-kernel, linux-kernel, linux-pci, mhklinux,
tglx, bhelgaas, romank
Cc: kys, haiyangz, wei.liu, 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.
Address issues with vmbus. The first patch prevents the Hyper-V PCI driver
being registered on baremetal, since there's no vmbus.
The second 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 3rd patch fixes a bug where cpu_online_mask is used unnecessarily
in an interrupt chip callback.
The 4th patch fixes up error return values in hv_map/unmap_interrupt() and
their callers, and cleans up style issues.
The 5th and 6th 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 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)
Mukesh Rathor (1):
PCI: hv: Don't load the driver for baremetal root partition
Nuno Das Neves (3):
Drivers: hv: Use nested hypercall for post message and signal event
x86/hyperv: Fix usage of cpu_online_mask to get valid cpu
x86/hyperv: Clean up hv_map/unmap_interrupt() return values
Stanislav Kinsburskii (2):
x86: hyperv: Expose hv_map_msi_interrupt function
PCI: hv: Use the correct hypercall for unmasking interrupts on nested
arch/x86/hyperv/irqdomain.c | 66 +++++++++++++++++------------
arch/x86/include/asm/mshyperv.h | 22 +---------
drivers/hv/connection.c | 7 ++-
drivers/hv/hv.c | 6 ++-
drivers/iommu/hyperv-iommu.c | 33 ++++++---------
drivers/pci/controller/pci-hyperv.c | 21 ++++++++-
6 files changed, 80 insertions(+), 75 deletions(-)
--
2.34.1
^ permalink raw reply
* Re: [PATCH 14/16] PCI: hv: Switch to msi_create_parent_irq_domain()
From: Thomas Gleixner @ 2025-07-03 21:52 UTC (permalink / raw)
To: Nam Cao, Michael Kelley
Cc: Marc Zyngier, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Bjorn Helgaas,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
Karthikeyan Mitran, Hou Zhiqiang, Thomas Petazzoni,
Pali Rohár, K . Y . Srinivasan, Haiyang Zhang, Wei Liu,
Dexuan Cui, Joyce Ooi, Jim Quinlan, Nicolas Saenz Julienne,
Florian Fainelli, Broadcom internal kernel review list, Ray Jui,
Scott Branden, Ryder Lee, Jianjun Wang, Marek Vasut,
Yoshihiro Shimoda, Michal Simek, Daire McNamara, Nirmal Patel,
Jonathan Derrick, Matthias Brugger, AngeloGioacchino Del Regno,
linux-arm-kernel@lists.infradead.org,
linux-hyperv@vger.kernel.org,
linux-rpi-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <20250703210056.sDzAytHT@linutronix.de>
On Thu, Jul 03 2025 at 23:00, Nam Cao wrote:
> On Thu, Jul 03, 2025 at 08:15:07PM +0000, Michael Kelley wrote:
>> which is in netdev/net-next.
>
> I need some guidance here. If I make it apply cleanly to linux-next, it
> won't apply to pci tree.
>
> I saw this type of conflict being resolved during merging to Linus's tree.
> Shouldn't we do the same for this case?
There are many ways to skin a cat. See my other reply.
^ permalink raw reply
* RE: [PATCH 14/16] PCI: hv: Switch to msi_create_parent_irq_domain()
From: Thomas Gleixner @ 2025-07-03 21:21 UTC (permalink / raw)
To: Michael Kelley, Nam Cao, Marc Zyngier, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org, Karthikeyan Mitran, Hou Zhiqiang,
Thomas Petazzoni, Pali Rohár, K . Y . Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi, Jim Quinlan,
Nicolas Saenz Julienne, Florian Fainelli,
Broadcom internal kernel review list, Ray Jui, Scott Branden,
Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
Matthias Brugger, AngeloGioacchino Del Regno,
linux-arm-kernel@lists.infradead.org,
linux-hyperv@vger.kernel.org,
linux-rpi-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <SN6PR02MB41576745C28D8F49081B8E77D443A@SN6PR02MB4157.namprd02.prod.outlook.com>
On Thu, Jul 03 2025 at 20:15, Michael Kelley wrote:
> From: Thomas Gleixner <tglx@linutronix.de> Sent: Thursday, July 3, 2025 1:00 PM
>> Does it conflict against the PCI tree?
>
> There's no conflict in the "next" or "for-linus" tags in
> https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/.
>
> The conflict is with Patch 2 of this series:
>
> https://lore.kernel.org/linux-hyperv/1749650984-9193-1-git-send-email-shradhagupta@linux.microsoft.com/
>
> which is in netdev/net-next.
That's a trivial one. There are two ways to handle it:
1) Take it through the PCI tree and provide a conflict resolution for
linux-next and later for Linus as reference.
2) Route it through the net-next tree with an updated patch.
As there are no further dependencies (aside of the missing export which
is needed anyway) it's obvious to pick #2 as it creates the least
headaches. Assumed that the PCI folks have no objections.
Michael, as you have resolved the conflict already, can you please
either take care of it yourself or provide the resolution here as
reference for Nam?
Thanks,
tglx
^ permalink raw reply
* [PATCH] irqdomain: Export irq_domain_free_irqs_top()
From: Nam Cao @ 2025-07-03 21:20 UTC (permalink / raw)
To: Thomas Gleixner, K . Y . Srinivasan, Michael Kelley,
Bjorn Helgaas, Haiyang Zhang, Wei Liu, Dexuan Cui, linux-hyperv
Cc: Nam Cao
Export irq_domain_free_irqs_top(), making it usable for drivers compiled as
modules.
Signed-off-by: Nam Cao <namcao@linutronix.de>
---
kernel/irq/irqdomain.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index c8b6de09047b..46919e6c9c45 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -1561,6 +1561,7 @@ void irq_domain_free_irqs_top(struct irq_domain *domain, unsigned int virq,
}
irq_domain_free_irqs_common(domain, virq, nr_irqs);
}
+EXPORT_SYMBOL_GPL(irq_domain_free_irqs_top);
static void irq_domain_free_irqs_hierarchy(struct irq_domain *domain,
unsigned int irq_base,
--
2.39.5
^ permalink raw reply related
* Re: [PATCH 14/16] PCI: hv: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-07-03 21:00 UTC (permalink / raw)
To: Michael Kelley
Cc: Thomas Gleixner, Marc Zyngier, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org, Karthikeyan Mitran, Hou Zhiqiang,
Thomas Petazzoni, Pali Rohár, K . Y . Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi, Jim Quinlan,
Nicolas Saenz Julienne, Florian Fainelli,
Broadcom internal kernel review list, Ray Jui, Scott Branden,
Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
Matthias Brugger, AngeloGioacchino Del Regno,
linux-arm-kernel@lists.infradead.org,
linux-hyperv@vger.kernel.org,
linux-rpi-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <SN6PR02MB41576745C28D8F49081B8E77D443A@SN6PR02MB4157.namprd02.prod.outlook.com>
On Thu, Jul 03, 2025 at 08:15:07PM +0000, Michael Kelley wrote:
> From: Thomas Gleixner <tglx@linutronix.de> Sent: Thursday, July 3, 2025 1:00 PM
> >
> > On Thu, Jul 03 2025 at 17:41, Michael Kelley wrote:
> > > From: Nam Cao <namcao@linutronix.de> Sent: Thursday, June 26, 2025 7:48 AM
> > >>
> > >> Move away from the legacy MSI domain setup, switch to use
> > >> msi_create_parent_irq_domain().
> > >
> > > From a build standpoint, this patch does not apply cleanly to
> > > linux-next20250630. See also an issue below where a needed irq
> > > function isn't exported.
> >
> > Does it conflict against the PCI tree?
>
> There's no conflict in the "next" or "for-linus" tags in
> https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/.
>
> The conflict is with Patch 2 of this series:
>
> https://lore.kernel.org/linux-hyperv/1749650984-9193-1-git-send-email-shradhagupta@linux.microsoft.com/
>
> which is in netdev/net-next.
I need some guidance here. If I make it apply cleanly to linux-next, it
won't apply to pci tree.
I saw this type of conflict being resolved during merging to Linus's tree.
Shouldn't we do the same for this case?
> Michael
>
> >
> > > At runtime, I've done basic smoke testing on an x86 VM in the Azure
> > > cloud that has a Mellanox NIC VF and two NVMe devices as PCI devices.
> > > So far everything looks good. But I'm still doing additional testing, and
> > > I want to also test on an ARM64 VM. Please give me another day or two
> > > to be completely satisfied.
Good to hear, thanks!
> > Sure.
> > >> +static void hv_pcie_domain_free(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs)
> > >> +{
> > >> + struct msi_domain_info *info = d->host_data;
> > >> +
> > >> + for (int i = 0; i < nr_irqs; i++)
> > >> + hv_msi_free(d, info, virq + i);
> > >> +
> > >> + irq_domain_free_irqs_top(d, virq, nr_irqs);
> > >
> > > This code can be built as a module, so irq_domain_free_irqs_top() needs to be
> > > exported, which it currently is not.
> >
> > Nam, can you please create a seperate patch, which exports this and take
> > care of the conflict?
Will do.
Best regards,
Nam
^ permalink raw reply
* RE: [PATCH 14/16] PCI: hv: Switch to msi_create_parent_irq_domain()
From: Michael Kelley @ 2025-07-03 20:15 UTC (permalink / raw)
To: Thomas Gleixner, Nam Cao, Marc Zyngier, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org, Karthikeyan Mitran, Hou Zhiqiang,
Thomas Petazzoni, Pali Rohár, K . Y . Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi, Jim Quinlan,
Nicolas Saenz Julienne, Florian Fainelli,
Broadcom internal kernel review list, Ray Jui, Scott Branden,
Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
Matthias Brugger, AngeloGioacchino Del Regno,
linux-arm-kernel@lists.infradead.org,
linux-hyperv@vger.kernel.org,
linux-rpi-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <87cyaht595.ffs@tglx>
From: Thomas Gleixner <tglx@linutronix.de> Sent: Thursday, July 3, 2025 1:00 PM
>
> On Thu, Jul 03 2025 at 17:41, Michael Kelley wrote:
> > From: Nam Cao <namcao@linutronix.de> Sent: Thursday, June 26, 2025 7:48 AM
> >>
> >> Move away from the legacy MSI domain setup, switch to use
> >> msi_create_parent_irq_domain().
> >
> > From a build standpoint, this patch does not apply cleanly to
> > linux-next20250630. See also an issue below where a needed irq
> > function isn't exported.
>
> Does it conflict against the PCI tree?
There's no conflict in the "next" or "for-linus" tags in
https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git/.
The conflict is with Patch 2 of this series:
https://lore.kernel.org/linux-hyperv/1749650984-9193-1-git-send-email-shradhagupta@linux.microsoft.com/
which is in netdev/net-next.
Michael
>
> > At runtime, I've done basic smoke testing on an x86 VM in the Azure
> > cloud that has a Mellanox NIC VF and two NVMe devices as PCI devices.
> > So far everything looks good. But I'm still doing additional testing, and
> > I want to also test on an ARM64 VM. Please give me another day or two
> > to be completely satisfied.
>
> Sure.
> >> +static void hv_pcie_domain_free(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs)
> >> +{
> >> + struct msi_domain_info *info = d->host_data;
> >> +
> >> + for (int i = 0; i < nr_irqs; i++)
> >> + hv_msi_free(d, info, virq + i);
> >> +
> >> + irq_domain_free_irqs_top(d, virq, nr_irqs);
> >
> > This code can be built as a module, so irq_domain_free_irqs_top() needs to be
> > exported, which it currently is not.
>
> Nam, can you please create a seperate patch, which exports this and take
> care of the conflict?
>
> Thanks,
>
> tglx
^ permalink raw reply
* RE: [PATCH 14/16] PCI: hv: Switch to msi_create_parent_irq_domain()
From: Thomas Gleixner @ 2025-07-03 19:59 UTC (permalink / raw)
To: Michael Kelley, Nam Cao, Marc Zyngier, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
Bjorn Helgaas, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org, Karthikeyan Mitran, Hou Zhiqiang,
Thomas Petazzoni, Pali Rohár, K . Y . Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi, Jim Quinlan,
Nicolas Saenz Julienne, Florian Fainelli,
Broadcom internal kernel review list, Ray Jui, Scott Branden,
Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
Matthias Brugger, AngeloGioacchino Del Regno,
linux-arm-kernel@lists.infradead.org,
linux-hyperv@vger.kernel.org,
linux-rpi-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org,
linux-renesas-soc@vger.kernel.org
In-Reply-To: <SN6PR02MB4157A6F9B2ABD3C69CE5B521D443A@SN6PR02MB4157.namprd02.prod.outlook.com>
On Thu, Jul 03 2025 at 17:41, Michael Kelley wrote:
> From: Nam Cao <namcao@linutronix.de> Sent: Thursday, June 26, 2025 7:48 AM
>>
>> Move away from the legacy MSI domain setup, switch to use
>> msi_create_parent_irq_domain().
>
> From a build standpoint, this patch does not apply cleanly to
> linux-next20250630. See also an issue below where a needed irq
> function isn't exported.
Does it conflict against the PCI tree?
> At runtime, I've done basic smoke testing on an x86 VM in the Azure
> cloud that has a Mellanox NIC VF and two NVMe devices as PCI devices.
> So far everything looks good. But I'm still doing additional testing, and
> I want to also test on an ARM64 VM. Please give me another day or two
> to be completely satisfied.
Sure.
>> +static void hv_pcie_domain_free(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs)
>> +{
>> + struct msi_domain_info *info = d->host_data;
>> +
>> + for (int i = 0; i < nr_irqs; i++)
>> + hv_msi_free(d, info, virq + i);
>> +
>> + irq_domain_free_irqs_top(d, virq, nr_irqs);
>
> This code can be built as a module, so irq_domain_free_irqs_top() needs to be
> exported, which it currently is not.
Nam, can you please create a seperate patch, which exports this and take
care of the conflict?
Thanks,
tglx
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox