|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |