From: Roger Pau Monne <roger.pau@citrix.com>
To: xen-devel@lists.xenproject.org
Cc: Andrew Cooper <andrew.cooper3@citrix.com>,
boris.ostrovsky@oracle.com,
Roger Pau Monne <roger.pau@citrix.com>,
Jan Beulich <jbeulich@suse.com>
Subject: [PATCH v2 6/9] xen/vpci: trap access to the list of PCI capabilities
Date: Thu, 20 Apr 2017 16:17:40 +0100 [thread overview]
Message-ID: <20170420151743.90889-7-roger.pau@citrix.com> (raw)
In-Reply-To: <20170420151743.90889-1-roger.pau@citrix.com>
Add traps to each capability PCI_CAP_LIST_NEXT field in order to mask them on
request.
All capabilities from the device are fetched and stored in an internal list,
that's later used in order to return the next capability to the guest. Note
that this only removes the capability from the linked list as seen by the
guest, but the actual capability structure could still be accessed by the
guest, provided that it's position can be found using another mechanism.
Finally the MSI and MSI-X capabilities are masked until Xen knows how to
properly handle accesses to them.
This should allow a PVH Dom0 to boot on some hardware, provided that the
hardware doesn't require MSI/MSI-X and that there are no SR-IOV devices in the
system, so the panic at the end of the PVH Dom0 build is replaced by a
warning.
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v1:
- Add missing newline between cmd handlers.
- Switch the handler to use list_for_each_entry_continue instead of a wrong
open-coded version of it.
---
xen/arch/x86/hvm/dom0_build.c | 2 +-
xen/drivers/vpci/Makefile | 2 +-
xen/drivers/vpci/capabilities.c | 159 ++++++++++++++++++++++++++++++++++++++++
xen/include/xen/vpci.h | 3 +
4 files changed, 164 insertions(+), 2 deletions(-)
create mode 100644 xen/drivers/vpci/capabilities.c
diff --git a/xen/arch/x86/hvm/dom0_build.c b/xen/arch/x86/hvm/dom0_build.c
index 65f606d33a..bcd10bd69c 100644
--- a/xen/arch/x86/hvm/dom0_build.c
+++ b/xen/arch/x86/hvm/dom0_build.c
@@ -1097,7 +1097,7 @@ int __init dom0_construct_pvh(struct domain *d, const module_t *image,
return rc;
}
- panic("Building a PVHv2 Dom0 is not yet supported.");
+ printk("WARNING: PVH is an experimental mode with limited functionality\n");
return 0;
}
diff --git a/xen/drivers/vpci/Makefile b/xen/drivers/vpci/Makefile
index 241467212f..c3f3085c93 100644
--- a/xen/drivers/vpci/Makefile
+++ b/xen/drivers/vpci/Makefile
@@ -1 +1 @@
-obj-y += vpci.o header.o
+obj-y += vpci.o header.o capabilities.o
diff --git a/xen/drivers/vpci/capabilities.c b/xen/drivers/vpci/capabilities.c
new file mode 100644
index 0000000000..b2a3326aa7
--- /dev/null
+++ b/xen/drivers/vpci/capabilities.c
@@ -0,0 +1,159 @@
+/*
+ * Generic functionality for handling accesses to the PCI capabilities from
+ * the configuration space.
+ *
+ * Copyright (C) 2017 Citrix Systems R&D
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms and conditions of the GNU General Public
+ * License, version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <xen/sched.h>
+#include <xen/vpci.h>
+
+struct vpci_capability {
+ struct list_head next;
+ uint8_t offset;
+ bool masked;
+};
+
+static int vpci_cap_read(struct pci_dev *pdev, unsigned int reg,
+ union vpci_val *val, void *data)
+{
+ struct vpci_capability *cap = data;
+
+ val->half_word = 0;
+
+ /* Return the position of the next non-masked capability. */
+ list_for_each_entry_continue ( cap, &pdev->vpci->cap_list, next )
+ {
+ if ( !cap->masked )
+ {
+ val->half_word = cap->offset;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int vpci_cap_write(struct pci_dev *pdev, unsigned int reg,
+ union vpci_val val, void *data)
+{
+ /* Ignored. */
+ return 0;
+}
+
+static int vpci_index_capabilities(struct pci_dev *pdev)
+{
+ uint8_t seg = pdev->seg, bus = pdev->bus;
+ uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn);
+ uint8_t pos = PCI_CAPABILITY_LIST;
+ uint16_t status;
+ unsigned int max_cap = 48;
+ struct vpci_capability *cap;
+ int rc;
+
+ INIT_LIST_HEAD(&pdev->vpci->cap_list);
+
+ /* Check if device has capabilities. */
+ status = pci_conf_read16(seg, bus, slot, func, PCI_STATUS);
+ if ( !(status & PCI_STATUS_CAP_LIST) )
+ return 0;
+
+ /* Add the root capability pointer. */
+ cap = xzalloc(struct vpci_capability);
+ if ( !cap )
+ return -ENOMEM;
+
+ cap->offset = pos;
+ list_add_tail(&cap->next, &pdev->vpci->cap_list);
+ rc = xen_vpci_add_register(pdev, vpci_cap_read, vpci_cap_write, pos,
+ 1, cap);
+ if ( rc )
+ return rc;
+
+ /*
+ * Iterate over the list of capabilities present in the device, and
+ * add a handler for each register pointer to the next item
+ * (PCI_CAP_LIST_NEXT).
+ */
+ while ( max_cap-- )
+ {
+ pos = pci_conf_read8(seg, bus, slot, func, pos);
+ if ( pos < 0x40 )
+ break;
+
+ cap = xzalloc(struct vpci_capability);
+ if ( !cap )
+ return -ENOMEM;
+
+ cap->offset = pos;
+ list_add_tail(&cap->next, &pdev->vpci->cap_list);
+ pos += PCI_CAP_LIST_NEXT;
+ rc = xen_vpci_add_register(pdev, vpci_cap_read, vpci_cap_write, pos,
+ 1, cap);
+ if ( rc )
+ return rc;
+ }
+
+ return 0;
+}
+
+static void vpci_mask_capability(struct pci_dev *pdev, uint8_t cap_id)
+{
+ struct vpci_capability *cap;
+ uint8_t cap_offset;
+
+ cap_offset = pci_find_cap_offset(pdev->seg, pdev->bus,
+ PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn), cap_id);
+ if ( !cap_offset )
+ return;
+
+ list_for_each_entry ( cap, &pdev->vpci->cap_list, next )
+ {
+ if ( cap->offset == cap_offset )
+ {
+ cap->masked = true;
+ break;
+ }
+ }
+}
+
+static int vpci_capabilities_init(struct pci_dev *pdev)
+{
+ int rc;
+
+ rc = vpci_index_capabilities(pdev);
+ if ( rc )
+ return rc;
+
+ /* Mask MSI and MSI-X capabilities until Xen handles them. */
+ vpci_mask_capability(pdev, PCI_CAP_ID_MSI);
+ vpci_mask_capability(pdev, PCI_CAP_ID_MSIX);
+
+ return 0;
+}
+
+REGISTER_VPCI_INIT(vpci_capabilities_init);
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
+
diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h
index 68a2ab9cd5..53443f5164 100644
--- a/xen/include/xen/vpci.h
+++ b/xen/include/xen/vpci.h
@@ -76,6 +76,9 @@ struct vpci {
bool sizing;
} bars[6];
} header;
+
+ /* List of capabilities supported by the device. */
+ struct list_head cap_list;
#endif
};
--
2.11.0 (Apple Git-81)
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2017-04-20 15:19 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-20 15:17 [PATCH v2 0/9] vpci: PCI config space emulation Roger Pau Monne
2017-04-20 15:17 ` [PATCH v2 1/9] xen/vpci: introduce basic handlers to trap accesses to the PCI config space Roger Pau Monne
2017-04-21 16:07 ` Paul Durrant
2017-04-24 9:09 ` Roger Pau Monne
2017-04-24 9:34 ` Paul Durrant
2017-04-24 10:08 ` Roger Pau Monne
2017-04-24 10:19 ` Paul Durrant
2017-04-24 11:02 ` Roger Pau Monne
2017-04-24 11:50 ` Paul Durrant
2017-04-25 8:27 ` Roger Pau Monne
2017-04-25 8:35 ` Paul Durrant
2017-04-21 16:23 ` Paul Durrant
2017-04-24 9:42 ` Roger Pau Monne
2017-04-24 9:55 ` Paul Durrant
2017-04-24 9:58 ` Paul Durrant
2017-04-24 10:11 ` Roger Pau Monne
2017-04-24 10:12 ` Paul Durrant
2017-04-20 15:17 ` [PATCH v2 2/9] x86/ecam: add handlers for the PVH Dom0 MMCFG areas Roger Pau Monne
2017-04-20 15:17 ` [PATCH v2 3/9] xen/mm: move modify_identity_mmio to global file and drop __init Roger Pau Monne
2017-04-24 14:42 ` Julien Grall
2017-04-25 8:01 ` Roger Pau Monne
2017-04-25 9:09 ` Julien Grall
2017-04-25 9:25 ` Roger Pau Monne
2017-04-25 9:32 ` Jan Beulich
2017-04-26 8:26 ` Roger Pau Monne
2017-04-26 8:51 ` Jan Beulich
2017-04-27 8:58 ` Roger Pau Monne
2017-04-27 9:08 ` Julien Grall
2017-04-27 9:29 ` Jan Beulich
2017-04-20 15:17 ` [PATCH v2 4/9] xen/pci: split code to size BARs from pci_add_device Roger Pau Monne
2017-04-20 15:17 ` [PATCH v2 5/9] xen/vpci: add handlers to map the BARs Roger Pau Monne
2017-04-20 15:17 ` Roger Pau Monne [this message]
2017-04-20 15:17 ` [PATCH v2 7/9] vpci: add a priority field to the vPCI register initializer Roger Pau Monne
2017-04-20 15:17 ` [PATCH v2 8/9] vpci/msi: add MSI handlers Roger Pau Monne
2017-04-21 8:38 ` Roger Pau Monne
2017-04-24 15:31 ` Julien Grall
2017-04-25 11:49 ` Roger Pau Monne
2017-04-25 12:00 ` Julien Grall
2017-04-25 13:19 ` Roger Pau Monne
2017-04-20 15:17 ` [PATCH v2 9/9] vpci/msix: add MSI-X handlers Roger Pau Monne
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170420151743.90889-7-roger.pau@citrix.com \
--to=roger.pau@citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=boris.ostrovsky@oracle.com \
--cc=jbeulich@suse.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).