Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch Work in progress on MSI/MSI-X on Xen (MSI works on ...



details:   https://anonhg.NetBSD.org/src/rev/603e6bd31459
branches:  trunk
changeset: 366364:603e6bd31459
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Mon May 23 15:03:05 2022 +0000

description:
Work in progress on MSI/MSI-X on Xen (MSI works on my hardware, more work
needed for MSI-X):
- Xen silently rejects 32 bits writes to MSI configuration registers
  (especially when setting PCI_MSI_CTL_MSI_ENABLE/PCI_MSIX_CTL_ENABLE),
  it expects 16 bits writes. So introduce a pci_conf_write16(),
  only available on XENPV (and working only for mode 1 without
  PCI_OVERRIDE_CONF_WRITE) and use it to enable MSI or MSI-X on XENPV.
- for multi-MSI vectors, Xen allocates all of them in a single hypercall,
  so it's not convenient to do it at intr_establish() time.
  So do it at alloc() time and register the pirqs in the msipic structure.
  xen_pic_to_gsi() now just returns the values cached in the msipic.
  As a bonus, if the PHYSDEVOP_map_pirq hypercall fails we can fail
  the alloc() and we don't need the xen_pci_msi*_probe() hacks.

options NO_PCI_MSI_MSIX still on by default for XEN3_DOM0.

diffstat:

 sys/arch/x86/pci/msipic.c          |   36 +++++++++-
 sys/arch/x86/pci/msipic.h          |    5 +-
 sys/arch/x86/pci/pci_machdep.c     |   42 ++++++++++++-
 sys/arch/x86/pci/pci_msi_machdep.c |   44 ++++++++-----
 sys/arch/xen/include/intr.h        |    6 +-
 sys/arch/xen/include/pci_machdep.h |    6 +-
 sys/arch/xen/x86/pintr.c           |  120 ++++++++++++++++++++++++++++--------
 7 files changed, 200 insertions(+), 59 deletions(-)

diffs (truncated from 515 to 300 lines):

diff -r 60777fde0a7e -r 603e6bd31459 sys/arch/x86/pci/msipic.c
--- a/sys/arch/x86/pci/msipic.c Mon May 23 13:53:37 2022 +0000
+++ b/sys/arch/x86/pci/msipic.c Mon May 23 15:03:05 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msipic.c,v 1.25 2020/12/11 09:22:20 knakahara Exp $    */
+/*     $NetBSD: msipic.c,v 1.26 2022/05/23 15:03:05 bouyer Exp $       */
 
 /*
  * Copyright (c) 2015 Internet Initiative Japan Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: msipic.c,v 1.25 2020/12/11 09:22:20 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msipic.c,v 1.26 2022/05/23 15:03:05 bouyer Exp $");
 
 #include "opt_intrdebug.h"
 
@@ -282,6 +282,16 @@
        msipic_release_common_msi_devid(msipic->mp_devid);
        mutex_exit(&msipic_list_lock);
 
+       if (msipic->mp_i.mp_xen_pirq != NULL) {
+               KASSERT(msipic->mp_i.mp_veccnt > 0);
+#ifdef DIAGNOSTIC
+               for (int i = 0; i < msipic->mp_i.mp_veccnt; i++) {
+                       KASSERT(msipic->mp_i.mp_xen_pirq[i] == 0);
+               }
+#endif
+               kmem_free(msipic->mp_i.mp_xen_pirq, 
+                   sizeof(*msipic->mp_i.mp_xen_pirq) * msipic->mp_i.mp_veccnt);
+       }
        kmem_free(msipic, sizeof(*msipic));
        kmem_free(msi_pic, sizeof(*msi_pic));
 }
@@ -421,7 +431,11 @@
        }
 #endif /* !XENPV */
        ctl |= PCI_MSI_CTL_MSI_ENABLE;
+#ifdef XENPV
+       pci_conf_write16(pc, tag, off + PCI_MSI_CTL + 2, ctl >> 16);
+#else
        pci_conf_write(pc, tag, off + PCI_MSI_CTL, ctl);
+#endif
 }
 
 /*
@@ -546,9 +560,9 @@
        pci_chipset_tag_t pc;
        struct pci_attach_args *pa;
        pcitag_t tag;
+#ifndef XENPV
        bus_space_tag_t bstag;
        bus_space_handle_t bshandle;
-#ifndef XENPV
        uint64_t entry_base;
        pcireg_t addr, data;
 #endif
@@ -567,6 +581,7 @@
        err = pci_get_capability(pc, tag, PCI_CAP_MSIX, &off, NULL);
        KASSERT(err != 0);
 
+#ifndef XENPV
        /* Disable MSI-X before writing MSI-X table */
        ctl = pci_conf_read(pc, tag, off + PCI_MSIX_CTL);
        ctl &= ~PCI_MSIX_CTL_ENABLE;
@@ -574,7 +589,6 @@
 
        bstag = pic->pic_msipic->mp_bstag;
        bshandle = pic->pic_msipic->mp_bshandle;
-#ifndef XENPV
        entry_base = PCI_MSIX_TABLE_ENTRY_SIZE * msix_vec;
 
        /*
@@ -597,12 +611,19 @@
            entry_base + PCI_MSIX_TABLE_ENTRY_ADDR_HI, 0);
        bus_space_write_4(bstag, bshandle,
            entry_base + PCI_MSIX_TABLE_ENTRY_DATA, data);
+       BUS_SPACE_WRITE_FLUSH(bstag, bshandle);
 #endif /* !XENPV */
-       BUS_SPACE_WRITE_FLUSH(bstag, bshandle);
 
        ctl = pci_conf_read(pc, tag, off + PCI_MSIX_CTL);
+       if (ctl & PCI_MSIX_CTL_FUNCMASK) {
+               ctl &= ~PCI_MSIX_CTL_FUNCMASK;
+       }
        ctl |= PCI_MSIX_CTL_ENABLE;
+#ifdef XENPV
+       pci_conf_write16(pc, tag, off + PCI_MSIX_CTL + 2, ctl >> 16);
+#else
        pci_conf_write(pc, tag, off + PCI_MSIX_CTL, ctl);
+#endif
 }
 
 /*
@@ -803,6 +824,11 @@
        }
 
        msi_pic->pic_msipic->mp_i.mp_veccnt = count;
+#ifdef XENPV
+       msi_pic->pic_msipic->mp_i.mp_xen_pirq =
+           kmem_zalloc(sizeof(*msi_pic->pic_msipic->mp_i.mp_xen_pirq) * count,
+           KM_SLEEP);
+#endif
        return 0;
 }
 
diff -r 60777fde0a7e -r 603e6bd31459 sys/arch/x86/pci/msipic.h
--- a/sys/arch/x86/pci/msipic.h Mon May 23 13:53:37 2022 +0000
+++ b/sys/arch/x86/pci/msipic.h Mon May 23 15:03:05 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: msipic.h,v 1.3 2020/05/04 15:55:56 jdolecek Exp $      */
+/*     $NetBSD: msipic.h,v 1.4 2022/05/23 15:03:05 bouyer Exp $        */
 
 /*
  * Copyright (c) 2015 Internet Initiative Japan Inc.
@@ -44,7 +44,8 @@
 struct msipic_pci_info {
        int mp_bus, mp_dev, mp_fun;
        int mp_veccnt; /* The number of MSI/MSI-X vectors. */
-       uint32_t mp_table_base; /* MSI-X table location in memory space */
+       uint32_t mp_table_base; /* Xen: MSI-X table location in memory space */
+       int *mp_xen_pirq; /* Xen: pirq numbers */
 };
 
 const struct msipic_pci_info *msipic_get_pci_info(struct pic *);
diff -r 60777fde0a7e -r 603e6bd31459 sys/arch/x86/pci/pci_machdep.c
--- a/sys/arch/x86/pci/pci_machdep.c    Mon May 23 13:53:37 2022 +0000
+++ b/sys/arch/x86/pci/pci_machdep.c    Mon May 23 15:03:05 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pci_machdep.c,v 1.89 2021/10/15 18:51:38 jmcneill Exp $        */
+/*     $NetBSD: pci_machdep.c,v 1.90 2022/05/23 15:03:05 bouyer Exp $  */
 
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -73,7 +73,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.89 2021/10/15 18:51:38 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.90 2022/05/23 15:03:05 bouyer Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -740,6 +740,44 @@
        pci_conf_unlock(&ocl);
 }
 
+#ifdef XENPV
+void
+pci_conf_write16(pci_chipset_tag_t pc, pcitag_t tag, int reg, uint16_t data)
+{
+       pci_chipset_tag_t ipc;
+       struct pci_conf_lock ocl;
+       int dev;
+
+       KASSERT((reg & 0x1) == 0);
+
+       for (ipc = pc; ipc != NULL; ipc = ipc->pc_super) {
+               if ((ipc->pc_present & PCI_OVERRIDE_CONF_WRITE) == 0)
+                       continue;
+               panic("pci_conf_write16 and override");
+       }
+
+       pci_decompose_tag(pc, tag, NULL, &dev, NULL);
+       if (__predict_false(pci_mode == 2 && dev >= 16)) {
+               return;
+       }
+
+       if (reg < 0)
+               return;
+       if (reg >= PCI_CONF_SIZE) {
+#if NACPICA > 0 && !defined(NO_PCI_EXTENDED_CONFIG)
+               if (reg >= PCI_EXTCONF_SIZE)
+                       return;
+               panic("pci_conf_write16 and reg >= PCI_CONF_SIZE");
+#endif
+               return;
+       }
+
+       pci_conf_lock(&ocl, pci_conf_selector(tag, reg & ~0x3));
+       outl(pci_conf_port(tag, reg & ~0x3) + (reg & 0x3), data);
+       pci_conf_unlock(&ocl);
+}
+#endif /* XENPV */
+
 void
 pci_mode_set(int mode)
 {
diff -r 60777fde0a7e -r 603e6bd31459 sys/arch/x86/pci/pci_msi_machdep.c
--- a/sys/arch/x86/pci/pci_msi_machdep.c        Mon May 23 13:53:37 2022 +0000
+++ b/sys/arch/x86/pci/pci_msi_machdep.c        Mon May 23 15:03:05 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pci_msi_machdep.c,v 1.16 2021/12/05 04:56:39 msaitoh Exp $     */
+/*     $NetBSD: pci_msi_machdep.c,v 1.17 2022/05/23 15:03:05 bouyer Exp $      */
 
 /*
  * Copyright (c) 2015 Internet Initiative Japan Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_msi_machdep.c,v 1.16 2021/12/05 04:56:39 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_msi_machdep.c,v 1.17 2022/05/23 15:03:05 bouyer Exp $");
 
 #include "opt_intrdebug.h"
 #include "ioapic.h"
@@ -175,14 +175,6 @@
                return EINVAL;
        }
 
-#ifdef XENPV
-       if (xen_pci_msi_probe(msi_pic, *count)) {
-               DPRINTF(("xen_pci_msi_probe() failed\n"));
-               msipic_destruct_msi_pic(msi_pic);
-               return EINVAL;
-       }
-#endif
-
        vectors = NULL;
        while (*count > 0) {
                vectors = pci_msi_alloc_vectors(msi_pic, NULL, count);
@@ -216,6 +208,15 @@
        }
 
        *ihps = vectors;
+#ifdef XENPV
+       if (xen_map_msi_pirq(msi_pic, *count)) {
+               DPRINTF(("xen_map_msi_pirq() failed\n"));
+               pci_msi_free_vectors(msi_pic, vectors, *count);
+               msipic_destruct_msi_pic(msi_pic);
+               return EINVAL;
+       }
+#endif
+
        return 0;
 }
 #endif /* __HAVE_PCI_MSI_MSIX */
@@ -270,14 +271,6 @@
        if (msix_pic == NULL)
                return EINVAL;
 
-#ifdef XENPV
-       if (xen_pci_msi_probe(msix_pic, *count)) {
-               DPRINTF(("xen_pci_msi_probe() failed\n"));
-               msipic_destruct_msix_pic(msix_pic);
-               return EINVAL;
-       }
-#endif
-
        vectors = NULL;
        while (*count > 0) {
                vectors = pci_msi_alloc_vectors(msix_pic, table_indexes, count);
@@ -311,6 +304,15 @@
        }
 
        *ihps = vectors;
+
+#ifdef XENPV
+       if (xen_map_msix_pirq(msix_pic, *count)) {
+               DPRINTF(("xen_map_msi_pirq() failed\n"));
+               pci_msi_free_vectors(msix_pic, vectors, *count);
+               msipic_destruct_msix_pic(msix_pic);
+               return EINVAL;
+       }
+#endif
        return 0;
 }
 
@@ -340,6 +342,9 @@
        if (pic == NULL)
                return;
 
+#ifdef XENPV
+       xen_pci_msi_release(pic, count);
+#endif
        pci_msi_free_vectors(pic, pihs, count);
        msipic_destruct_msi_pic(pic);
 }
@@ -379,6 +384,9 @@
        if (pic == NULL)
                return;
 
+#ifdef XENPV
+       xen_pci_msi_release(pic, count);
+#endif
        pci_msi_free_vectors(pic, pihs, count);
        msipic_destruct_msix_pic(pic);
 }
diff -r 60777fde0a7e -r 603e6bd31459 sys/arch/xen/include/intr.h
--- a/sys/arch/xen/include/intr.h       Mon May 23 13:53:37 2022 +0000
+++ b/sys/arch/xen/include/intr.h       Mon May 23 15:03:05 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: intr.h,v 1.58 2020/07/19 14:27:07 jdolecek Exp $       */
+/*     $NetBSD: intr.h,v 1.59 2022/05/23 15:03:05 bouyer Exp $ */
 /*     NetBSD intr.h,v 1.15 2004/10/31 10:39:34 yamt Exp       */
 
 /*-
@@ -72,7 +72,9 @@
 



Home | Main Index | Thread Index | Old Index