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

[Xen-devel] [PATCH v4 3/9] x86/physdev: enable PHYSDEVOP_pci_mmcfg_reserved for PVH Dom0



So that hotplug (or MMCFG regions not present in the MCFG ACPI table)
can be added at run time by the hardware domain.

When a new MMCFG area is added to a PVH Dom0, Xen will scan it and add
the devices to the hardware domain.

Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
Cc: Jan Beulich <jbeulich@xxxxxxxx>
Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
changes since v3:
 - New in this version.
---
 tools/tests/vpci/emul.h       |  2 --
 xen/arch/x86/hvm/hypercall.c  |  4 ++++
 xen/arch/x86/physdev.c        | 19 +++++++++++++++++++
 xen/drivers/passthrough/pci.c | 37 ++++++++++++++++++++++++++++++++++---
 xen/drivers/vpci/vpci.c       |  4 ++--
 xen/include/xen/pci.h         |  1 +
 6 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/tools/tests/vpci/emul.h b/tools/tests/vpci/emul.h
index 1b0217e7e3..047079de4c 100644
--- a/tools/tests/vpci/emul.h
+++ b/tools/tests/vpci/emul.h
@@ -58,8 +58,6 @@ extern struct pci_dev test_pdev;
 
 #include "vpci.h"
 
-#define __hwdom_init
-
 #define has_vpci(d) true
 
 /* Define our own locks. */
diff --git a/xen/arch/x86/hvm/hypercall.c b/xen/arch/x86/hvm/hypercall.c
index e7238ce293..89625d514c 100644
--- a/xen/arch/x86/hvm/hypercall.c
+++ b/xen/arch/x86/hvm/hypercall.c
@@ -89,6 +89,10 @@ static long hvm_physdev_op(int cmd, 
XEN_GUEST_HANDLE_PARAM(void) arg)
         if ( !has_pirq(curr->domain) )
             return -ENOSYS;
         break;
+    case PHYSDEVOP_pci_mmcfg_reserved:
+        if ( !is_hardware_domain(curr->domain) )
+            return -ENOSYS;
+        break;
     }
 
     if ( !curr->hcall_compat )
diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c
index 0eb409758f..6b1c92fa0b 100644
--- a/xen/arch/x86/physdev.c
+++ b/xen/arch/x86/physdev.c
@@ -559,6 +559,25 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) 
arg)
 
         ret = pci_mmcfg_reserved(info.address, info.segment,
                                  info.start_bus, info.end_bus, info.flags);
+        if ( ret || !is_hvm_domain(currd) )
+            break;
+
+        /*
+         * For HVM (PVH) domains try to add the newly found MMCFG to the
+         * domain.
+         */
+        ret = register_vpci_mmcfg_handler(currd, info.address, info.start_bus,
+                                          info.end_bus, info.segment);
+        if ( ret == -EEXIST )
+        {
+            ret = 0;
+            break;
+        }
+        if ( ret )
+            break;
+
+        ret = pci_scan_and_setup_segment(info.segment);
+
         break;
     }
 
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index 3208cd5d71..2d38a5a297 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -924,7 +924,7 @@ out:
     return ret;
 }
 
-bool_t __init pci_device_detect(u16 seg, u8 bus, u8 dev, u8 func)
+bool pci_device_detect(u16 seg, u8 bus, u8 dev, u8 func)
 {
     u32 vendor;
 
@@ -971,7 +971,7 @@ void pci_check_disable_device(u16 seg, u8 bus, u8 devfn)
  * scan pci devices to add all existed PCI devices to alldevs_list,
  * and setup pci hierarchy in array bus2bridge.
  */
-static int __init _scan_pci_devices(struct pci_seg *pseg, void *arg)
+static int _scan_pci_devices(struct pci_seg *pseg, void *arg)
 {
     struct pci_dev *pdev;
     int bus, dev, func;
@@ -1050,7 +1050,7 @@ static void setup_one_hwdom_device(const struct 
setup_hwdom *ctxt,
                ctxt->d->domain_id, err);
 }
 
-static int __hwdom_init _setup_hwdom_pci_devices(struct pci_seg *pseg, void 
*arg)
+static int _setup_hwdom_pci_devices(struct pci_seg *pseg, void *arg)
 {
     struct setup_hwdom *ctxt = arg;
     int bus, devfn;
@@ -1110,6 +1110,37 @@ void __hwdom_init setup_hwdom_pci_devices(
     pcidevs_unlock();
 }
 
+static int add_device(uint8_t devfn, struct pci_dev *pdev)
+{
+    return iommu_add_device(pdev);
+}
+
+int pci_scan_and_setup_segment(uint16_t segment)
+{
+    struct pci_seg *pseg = get_pseg(segment);
+    struct setup_hwdom ctxt = {
+        .d = current->domain,
+        .handler = add_device,
+    };
+    int ret;
+
+    if ( !pseg )
+        return -EINVAL;
+
+    pcidevs_lock();
+    ret = _scan_pci_devices(pseg, NULL);
+    if ( ret )
+        goto out;
+
+    ret = _setup_hwdom_pci_devices(pseg, &ctxt);
+    if ( ret )
+        goto out;
+
+ out:
+    pcidevs_unlock();
+    return ret;
+}
+
 #ifdef CONFIG_ACPI
 #include <acpi/acpi.h>
 #include <acpi/apei.h>
diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c
index c54de83b82..7d4ecd5fb5 100644
--- a/xen/drivers/vpci/vpci.c
+++ b/xen/drivers/vpci/vpci.c
@@ -33,12 +33,12 @@ struct vpci_register {
     struct list_head node;
 };
 
-int __hwdom_init vpci_add_handlers(struct pci_dev *pdev)
+int vpci_add_handlers(struct pci_dev *pdev)
 {
     unsigned int i;
     int rc = 0;
 
-    if ( !has_vpci(pdev->domain) )
+    if ( !has_vpci(pdev->domain) || pdev->vpci )
         return 0;
 
     pdev->vpci = xzalloc(struct vpci);
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index a9b80e330b..e550effcc9 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -131,6 +131,7 @@ struct pci_dev *pci_get_real_pdev(int seg, int bus, int 
devfn);
 struct pci_dev *pci_get_pdev_by_domain(
     struct domain *, int seg, int bus, int devfn);
 void pci_check_disable_device(u16 seg, u8 bus, u8 devfn);
+int pci_scan_and_setup_segment(uint16_t segment);
 
 uint8_t pci_conf_read8(
     unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
-- 
2.11.0 (Apple Git-81)


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.