Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch for Xen MSI, fallback to INTx when PHYSDEVOP_map_pi...
details: https://anonhg.NetBSD.org/src/rev/24011aafcc0a
branches: trunk
changeset: 973964:24011aafcc0a
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Sun Jul 19 14:27:07 2020 +0000
description:
for Xen MSI, fallback to INTx when PHYSDEVOP_map_pirq fails for the device
apparently Xen requires VT-d to be enabled in BIOS for PHYSDEVOP_map_pirq
to work, this change makes it work on systems with VT-d disabled or missing
adresses the panic part of PR port-xen/55285 by Patrick Welche
diffstat:
sys/arch/x86/pci/pci_msi_machdep.c | 20 +++++++-
sys/arch/xen/include/intr.h | 3 +-
sys/arch/xen/x86/pintr.c | 86 +++++++++++++++++++++++++++----------
3 files changed, 83 insertions(+), 26 deletions(-)
diffs (179 lines):
diff -r a8ae7db5a315 -r 24011aafcc0a sys/arch/x86/pci/pci_msi_machdep.c
--- a/sys/arch/x86/pci/pci_msi_machdep.c Sun Jul 19 14:23:02 2020 +0000
+++ b/sys/arch/x86/pci/pci_msi_machdep.c Sun Jul 19 14:27:07 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_msi_machdep.c,v 1.13 2017/07/28 14:26:50 maxv Exp $ */
+/* $NetBSD: pci_msi_machdep.c,v 1.14 2020/07/19 14:27:07 jdolecek 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.13 2017/07/28 14:26:50 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_msi_machdep.c,v 1.14 2020/07/19 14:27:07 jdolecek Exp $");
#include "opt_intrdebug.h"
#include "ioapic.h"
@@ -175,6 +175,14 @@
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);
@@ -262,6 +270,14 @@
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);
diff -r a8ae7db5a315 -r 24011aafcc0a sys/arch/xen/include/intr.h
--- a/sys/arch/xen/include/intr.h Sun Jul 19 14:23:02 2020 +0000
+++ b/sys/arch/xen/include/intr.h Sun Jul 19 14:27:07 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.h,v 1.57 2020/05/15 07:42:58 jdolecek Exp $ */
+/* $NetBSD: intr.h,v 1.58 2020/07/19 14:27:07 jdolecek Exp $ */
/* NetBSD intr.h,v 1.15 2004/10/31 10:39:34 yamt Exp */
/*-
@@ -72,6 +72,7 @@
#if defined(DOM0OPS) || NPCI > 0
int xen_pic_to_gsi(struct pic *, int);
+int xen_pci_msi_probe(struct pic *, int);
#endif /* defined(DOM0OPS) || NPCI > 0 */
#ifdef MULTIPROCESSOR
diff -r a8ae7db5a315 -r 24011aafcc0a sys/arch/xen/x86/pintr.c
--- a/sys/arch/xen/x86/pintr.c Sun Jul 19 14:23:02 2020 +0000
+++ b/sys/arch/xen/x86/pintr.c Sun Jul 19 14:27:07 2020 +0000
@@ -103,7 +103,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pintr.c,v 1.17 2020/05/23 14:51:19 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pintr.c,v 1.18 2020/07/19 14:27:07 jdolecek Exp $");
#include "opt_multiprocessor.h"
#include "opt_xen.h"
@@ -163,6 +163,67 @@
#endif
#if defined(DOM0OPS) || NPCI > 0
+
+static int
+xen_map_msi_pirq(struct pic *pic, int count, int *gsi)
+{
+ struct physdev_map_pirq map_irq;
+ const struct msipic_pci_info *i = msipic_get_pci_info(pic);
+ int ret;
+
+ if (count == -1)
+ count = i->mp_veccnt;
+ KASSERT(count > 0);
+
+ memset(&map_irq, 0, sizeof(map_irq));
+ map_irq.domid = DOMID_SELF;
+ map_irq.type = MAP_PIRQ_TYPE_MSI_SEG;
+ map_irq.index = -1;
+ map_irq.pirq = -1;
+ map_irq.bus = i->mp_bus;
+ map_irq.devfn = (i->mp_dev << 3) | i->mp_fun;
+ map_irq.entry_nr = count;
+ if (pic->pic_type == PIC_MSI && i->mp_veccnt > 1) {
+ map_irq.type = MAP_PIRQ_TYPE_MULTI_MSI;
+ } else if (pic->pic_type == PIC_MSIX) {
+ map_irq.table_base = i->mp_table_base;
+ }
+
+ ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
+
+ if (ret == 0) {
+ KASSERT(map_irq.entry_nr == count);
+ *gsi = map_irq.pirq;
+ }
+
+ return ret;
+}
+
+/*
+ * Check if we can map MSI interrupt. The Xen call fails if VT-d is not
+ * available or disabled.
+ */
+int
+xen_pci_msi_probe(struct pic *pic, int count)
+{
+ int pirq, ret;
+
+ ret = xen_map_msi_pirq(pic, count, &pirq);
+
+ if (ret == 0) {
+ struct physdev_unmap_pirq unmap_irq;
+ unmap_irq.domid = DOMID_SELF;
+ unmap_irq.pirq = pirq;
+
+ (void)HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq);
+ } else {
+ aprint_debug("PHYSDEVOP_map_pirq() failed %d, MSI disabled\n",
+ ret);
+ }
+
+ return ret;
+}
+
/*
* This function doesn't "allocate" anything. It merely translates our
* understanding of PIC to the XEN 'gsi' namespace. In the case of
@@ -213,32 +274,11 @@
case PIC_MSI:
case PIC_MSIX:
#ifdef __HAVE_PCI_MSI_MSIX
- {
- struct physdev_map_pirq map_irq;
- const struct msipic_pci_info *i = msipic_get_pci_info(pic);
-
- memset(&map_irq, 0, sizeof(map_irq));
- map_irq.domid = DOMID_SELF;
- map_irq.type = MAP_PIRQ_TYPE_MSI_SEG;
- map_irq.index = -1;
- map_irq.pirq = -1;
- map_irq.bus = i->mp_bus;
- map_irq.devfn = (i->mp_dev << 3) | i->mp_fun;
- KASSERT(i->mp_veccnt > 0);
- map_irq.entry_nr = i->mp_veccnt;
- if (pic->pic_type == PIC_MSI && i->mp_veccnt > 1) {
- map_irq.type = MAP_PIRQ_TYPE_MULTI_MSI;
- } else if (pic->pic_type == PIC_MSIX) {
- map_irq.table_base = i->mp_table_base;
- }
- ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
+ ret = xen_map_msi_pirq(pic, -1, &gsi);
if (ret != 0)
panic("physdev_op(PHYSDEVOP_map_pirq) MSI fail %d",
ret);
- KASSERT(map_irq.entry_nr == i->mp_veccnt);
- gsi = map_irq.pirq;
break;
- }
#endif
default:
panic("unknown pic_type %d", pic->pic_type);
Home |
Main Index |
Thread Index |
Old Index