# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1197455375 0
# Node ID ef83b50fc4a43368bf9531f88edfab3906549395
# Parent 5a451d2c36bcb21f9b5a4098d66ed6815a762162
vt-d: Test device assignability in xend, but defer actual assignment to qemu-dm.
Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
---
tools/ioemu/hw/pass-through.c | 12 +++++++++++-
tools/libxc/xc_domain.c | 16 +++++++++++++++-
tools/libxc/xenctrl.h | 4 ++++
tools/python/xen/lowlevel/xc/xc.c | 14 +++++++-------
tools/python/xen/xend/XendDomainInfo.py | 4 ++--
xen/arch/x86/domctl.c | 26 +++++++++++++++++++++++---
xen/include/public/domctl.h | 7 ++++---
7 files changed, 66 insertions(+), 17 deletions(-)
diff -r 5a451d2c36bc -r ef83b50fc4a4 tools/ioemu/hw/pass-through.c
--- a/tools/ioemu/hw/pass-through.c Wed Dec 12 10:25:18 2007 +0000
+++ b/tools/ioemu/hw/pass-through.c Wed Dec 12 10:29:35 2007 +0000
@@ -327,6 +327,7 @@ struct pt_dev * register_real_device(PCI
struct pt_dev *assigned_device = NULL;
struct pci_dev *pci_dev;
uint8_t e_device, e_intx;
+ struct pci_config_cf8 machine_bdf;
PT_LOG("Assigning real physical device %02x:%02x.%x ...\n",
r_bus, r_dev, r_func);
@@ -360,13 +361,22 @@ struct pt_dev * register_real_device(PCI
/* Issue PCIe FLR */
pdev_flr(pci_dev);
+ /* Assign device */
+ machine_bdf.reg = 0;
+ machine_bdf.bus = r_bus;
+ machine_bdf.dev = r_dev;
+ machine_bdf.func = r_func;
+ rc = xc_assign_device(xc_handle, domid, machine_bdf.value);
+ if ( rc < 0 )
+ PT_LOG("Error: xc_assign_device error %d\n", rc);
+
/* Initialize virtualized PCI configuration (Extended 256 Bytes) */
for ( i = 0; i < PCI_CONFIG_SIZE; i++ )
assigned_device->dev.config[i] = pci_read_byte(pci_dev, i);
/* Handle real device's MMIO/PIO BARs */
pt_register_regions(assigned_device);
-
+
/* Bind interrupt */
e_device = (assigned_device->dev.devfn >> 3) & 0x1f;
e_intx = assigned_device->dev.config[0x3d]-1;
diff -r 5a451d2c36bc -r ef83b50fc4a4 tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c Wed Dec 12 10:25:18 2007 +0000
+++ b/tools/libxc/xc_domain.c Wed Dec 12 10:29:35 2007 +0000
@@ -759,7 +759,21 @@ int xc_assign_device(
domctl.cmd = XEN_DOMCTL_assign_device;
domctl.domain = domid;
domctl.u.assign_device.machine_bdf = machine_bdf;
-
+
+ return do_domctl(xc_handle, &domctl);
+}
+
+int xc_test_assign_device(
+ int xc_handle,
+ uint32_t domid,
+ uint32_t machine_bdf)
+{
+ DECLARE_DOMCTL;
+
+ domctl.cmd = XEN_DOMCTL_test_assign_device;
+ domctl.domain = domid;
+ domctl.u.test_assign_device.machine_bdf = machine_bdf;
+
return do_domctl(xc_handle, &domctl);
}
diff -r 5a451d2c36bc -r ef83b50fc4a4 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Wed Dec 12 10:25:18 2007 +0000
+++ b/tools/libxc/xenctrl.h Wed Dec 12 10:29:35 2007 +0000
@@ -914,6 +914,10 @@ int xc_assign_device(int xc_handle,
uint32_t domid,
uint32_t machine_bdf);
+int xc_test_assign_device(int xc_handle,
+ uint32_t domid,
+ uint32_t machine_bdf);
+
int xc_domain_memory_mapping(int xc_handle,
uint32_t domid,
unsigned long first_gfn,
diff -r 5a451d2c36bc -r ef83b50fc4a4 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Wed Dec 12 10:25:18 2007 +0000
+++ b/tools/python/xen/lowlevel/xc/xc.c Wed Dec 12 10:29:35 2007 +0000
@@ -560,9 +560,9 @@ static int next_bdf(char **str, int *seg
return 1;
}
-static PyObject *pyxc_assign_device(XcObject *self,
- PyObject *args,
- PyObject *kwds)
+static PyObject *pyxc_test_assign_device(XcObject *self,
+ PyObject *args,
+ PyObject *kwds)
{
uint32_t dom;
char *pci_str;
@@ -580,7 +580,7 @@ static PyObject *pyxc_assign_device(XcOb
bdf |= (dev & 0x1f) << 11;
bdf |= (func & 0x7) << 8;
- if ( xc_assign_device(self->xc_handle, dom, bdf) != 0 )
+ if ( xc_test_assign_device(self->xc_handle, dom, bdf) != 0 )
break;
bdf = 0;
@@ -1426,10 +1426,10 @@ static PyMethodDef pyxc_methods[] = {
" value [long]: Value of param.\n"
"Returns: [int] 0 on success.\n" },
- { "assign_device",
- (PyCFunction)pyxc_assign_device,
+ { "test_assign_device",
+ (PyCFunction)pyxc_test_assign_device,
METH_VARARGS | METH_KEYWORDS, "\n"
- "assign device with VT-d.\n"
+ "test device assignment with VT-d.\n"
" dom [int]: Identifier of domain to build into.\n"
" pci_str [str]: PCI devices.\n"
"Returns: [int] 0 on success, or device bdf that can't be assigned.\n"
},
diff -r 5a451d2c36bc -r ef83b50fc4a4 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Wed Dec 12 10:25:18 2007 +0000
+++ b/tools/python/xen/xend/XendDomainInfo.py Wed Dec 12 10:29:35 2007 +0000
@@ -1653,10 +1653,10 @@ class XendDomainInfo:
# Set maximum number of vcpus in domain
xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max']))
- # Assign devices with VT-d
+ # Test whether the devices can be assigned with VT-d
pci_str = str(self.info["platform"].get("pci"))
if hvm and pci_str:
- bdf = xc.assign_device(self.domid, pci_str)
+ bdf = xc.test_assign_device(self.domid, pci_str)
if bdf != 0:
bus = (bdf >> 16) & 0xff
devfn = (bdf >> 8) & 0xff
diff -r 5a451d2c36bc -r ef83b50fc4a4 xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Wed Dec 12 10:25:18 2007 +0000
+++ b/xen/arch/x86/domctl.c Wed Dec 12 10:29:35 2007 +0000
@@ -525,10 +525,31 @@ long arch_do_domctl(
}
break;
+ case XEN_DOMCTL_test_assign_device:
+ {
+ u8 bus, devfn;
+
+ ret = -EINVAL;
+ if ( !vtd_enabled )
+ break;
+
+ bus = (domctl->u.test_assign_device.machine_bdf >> 16) & 0xff;
+ devfn = (domctl->u.test_assign_device.machine_bdf >> 8) & 0xff;
+
+ if ( device_assigned(bus, devfn) )
+ {
+ gdprintk(XENLOG_ERR, "XEN_DOMCTL_test_assign_device: "
+ "%x:%x:%x already assigned\n",
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ break;
+ }
+ ret = 0;
+ }
+ break;
+
case XEN_DOMCTL_assign_device:
{
struct domain *d;
- struct hvm_iommu *hd;
u8 bus, devfn;
ret = -EINVAL;
@@ -541,7 +562,6 @@ long arch_do_domctl(
"XEN_DOMCTL_assign_device: get_domain_by_id() failed\n");
break;
}
- hd = domain_hvm_iommu(d);
bus = (domctl->u.assign_device.machine_bdf >> 16) & 0xff;
devfn = (domctl->u.assign_device.machine_bdf >> 8) & 0xff;
@@ -549,7 +569,7 @@ long arch_do_domctl(
{
gdprintk(XENLOG_ERR, "XEN_DOMCTL_assign_device: "
"%x:%x:%x already assigned\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
break;
}
diff -r 5a451d2c36bc -r ef83b50fc4a4 xen/include/public/domctl.h
--- a/xen/include/public/domctl.h Wed Dec 12 10:25:18 2007 +0000
+++ b/xen/include/public/domctl.h Wed Dec 12 10:29:35 2007 +0000
@@ -435,9 +435,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendt
/* Assign PCI device to HVM guest. Sets up IOMMU structures. */
-#define XEN_DOMCTL_assign_device 37
-#define DPCI_ADD_MAPPING 1
-#define DPCI_REMOVE_MAPPING 0
+#define XEN_DOMCTL_assign_device 37
+#define XEN_DOMCTL_test_assign_device 45
struct xen_domctl_assign_device {
uint32_t machine_bdf; /* machine PCI ID of assigned device */
};
@@ -473,6 +472,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_bind_
/* Bind machine I/O address range -> HVM address range. */
#define XEN_DOMCTL_memory_mapping 39
+#define DPCI_ADD_MAPPING 1
+#define DPCI_REMOVE_MAPPING 0
struct xen_domctl_memory_mapping {
uint64_aligned_t first_gfn; /* first page (hvm guest phys page) in range */
uint64_aligned_t first_mfn; /* first page (machine page) in range */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|