ia64/xen-unstable

changeset 16595:ef83b50fc4a4

vt-d: Test device assignability in xend, but defer actual assignment to qemu-dm.
Signed-off-by: Weidong Han <weidong.han@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Dec 12 10:29:35 2007 +0000 (2007-12-12)
parents 5a451d2c36bc
children 23febc32fc1b
files tools/ioemu/hw/pass-through.c tools/libxc/xc_domain.c tools/libxc/xenctrl.h tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/XendDomainInfo.py xen/arch/x86/domctl.c xen/include/public/domctl.h
line diff
     1.1 --- a/tools/ioemu/hw/pass-through.c	Wed Dec 12 10:25:18 2007 +0000
     1.2 +++ b/tools/ioemu/hw/pass-through.c	Wed Dec 12 10:29:35 2007 +0000
     1.3 @@ -327,6 +327,7 @@ struct pt_dev * register_real_device(PCI
     1.4      struct pt_dev *assigned_device = NULL;
     1.5      struct pci_dev *pci_dev;
     1.6      uint8_t e_device, e_intx;
     1.7 +    struct pci_config_cf8 machine_bdf;
     1.8  
     1.9      PT_LOG("Assigning real physical device %02x:%02x.%x ...\n",
    1.10          r_bus, r_dev, r_func);
    1.11 @@ -360,13 +361,22 @@ struct pt_dev * register_real_device(PCI
    1.12      /* Issue PCIe FLR */
    1.13      pdev_flr(pci_dev);
    1.14  
    1.15 +    /* Assign device */
    1.16 +    machine_bdf.reg = 0;
    1.17 +    machine_bdf.bus = r_bus;
    1.18 +    machine_bdf.dev = r_dev;
    1.19 +    machine_bdf.func = r_func;
    1.20 +    rc = xc_assign_device(xc_handle, domid, machine_bdf.value);
    1.21 +    if ( rc < 0 )
    1.22 +        PT_LOG("Error: xc_assign_device error %d\n", rc);
    1.23 +
    1.24      /* Initialize virtualized PCI configuration (Extended 256 Bytes) */
    1.25      for ( i = 0; i < PCI_CONFIG_SIZE; i++ )
    1.26          assigned_device->dev.config[i] = pci_read_byte(pci_dev, i);
    1.27  
    1.28      /* Handle real device's MMIO/PIO BARs */
    1.29      pt_register_regions(assigned_device);
    1.30 -    
    1.31 +
    1.32      /* Bind interrupt */
    1.33      e_device = (assigned_device->dev.devfn >> 3) & 0x1f;
    1.34      e_intx = assigned_device->dev.config[0x3d]-1;
     2.1 --- a/tools/libxc/xc_domain.c	Wed Dec 12 10:25:18 2007 +0000
     2.2 +++ b/tools/libxc/xc_domain.c	Wed Dec 12 10:29:35 2007 +0000
     2.3 @@ -759,7 +759,21 @@ int xc_assign_device(
     2.4      domctl.cmd = XEN_DOMCTL_assign_device;
     2.5      domctl.domain = domid;
     2.6      domctl.u.assign_device.machine_bdf = machine_bdf;
     2.7 - 
     2.8 +
     2.9 +    return do_domctl(xc_handle, &domctl);
    2.10 +}
    2.11 +
    2.12 +int xc_test_assign_device(
    2.13 +    int xc_handle,
    2.14 +    uint32_t domid,
    2.15 +    uint32_t machine_bdf)
    2.16 +{
    2.17 +    DECLARE_DOMCTL;
    2.18 +
    2.19 +    domctl.cmd = XEN_DOMCTL_test_assign_device;
    2.20 +    domctl.domain = domid;
    2.21 +    domctl.u.test_assign_device.machine_bdf = machine_bdf;
    2.22 +
    2.23      return do_domctl(xc_handle, &domctl);
    2.24  }
    2.25  
     3.1 --- a/tools/libxc/xenctrl.h	Wed Dec 12 10:25:18 2007 +0000
     3.2 +++ b/tools/libxc/xenctrl.h	Wed Dec 12 10:29:35 2007 +0000
     3.3 @@ -914,6 +914,10 @@ int xc_assign_device(int xc_handle,
     3.4                       uint32_t domid,
     3.5                       uint32_t machine_bdf);
     3.6  
     3.7 +int xc_test_assign_device(int xc_handle,
     3.8 +                          uint32_t domid,
     3.9 +                          uint32_t machine_bdf);
    3.10 +
    3.11  int xc_domain_memory_mapping(int xc_handle,
    3.12                               uint32_t domid,
    3.13                               unsigned long first_gfn,
     4.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Wed Dec 12 10:25:18 2007 +0000
     4.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Wed Dec 12 10:29:35 2007 +0000
     4.3 @@ -560,9 +560,9 @@ static int next_bdf(char **str, int *seg
     4.4      return 1;
     4.5  }
     4.6  
     4.7 -static PyObject *pyxc_assign_device(XcObject *self,
     4.8 -                                    PyObject *args,
     4.9 -                                    PyObject *kwds)
    4.10 +static PyObject *pyxc_test_assign_device(XcObject *self,
    4.11 +                                         PyObject *args,
    4.12 +                                         PyObject *kwds)
    4.13  {
    4.14      uint32_t dom;
    4.15      char *pci_str;
    4.16 @@ -580,7 +580,7 @@ static PyObject *pyxc_assign_device(XcOb
    4.17          bdf |= (dev & 0x1f) << 11;
    4.18          bdf |= (func & 0x7) << 8;
    4.19  
    4.20 -        if ( xc_assign_device(self->xc_handle, dom, bdf) != 0 )
    4.21 +        if ( xc_test_assign_device(self->xc_handle, dom, bdf) != 0 )
    4.22              break;
    4.23  
    4.24          bdf = 0;
    4.25 @@ -1426,10 +1426,10 @@ static PyMethodDef pyxc_methods[] = {
    4.26        " value   [long]:     Value of param.\n"
    4.27        "Returns: [int] 0 on success.\n" },
    4.28  
    4.29 -     { "assign_device",
    4.30 -       (PyCFunction)pyxc_assign_device,
    4.31 +     { "test_assign_device",
    4.32 +       (PyCFunction)pyxc_test_assign_device,
    4.33         METH_VARARGS | METH_KEYWORDS, "\n"
    4.34 -       "assign device with VT-d.\n"
    4.35 +       "test device assignment with VT-d.\n"
    4.36         " dom     [int]:      Identifier of domain to build into.\n"
    4.37         " pci_str [str]:      PCI devices.\n"
    4.38         "Returns: [int] 0 on success, or device bdf that can't be assigned.\n" },
     5.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Dec 12 10:25:18 2007 +0000
     5.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Dec 12 10:29:35 2007 +0000
     5.3 @@ -1653,10 +1653,10 @@ class XendDomainInfo:
     5.4          # Set maximum number of vcpus in domain
     5.5          xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max']))
     5.6  
     5.7 -        # Assign devices with VT-d
     5.8 +        # Test whether the devices can be assigned with VT-d
     5.9          pci_str = str(self.info["platform"].get("pci"))
    5.10          if hvm and pci_str:
    5.11 -            bdf = xc.assign_device(self.domid, pci_str)
    5.12 +            bdf = xc.test_assign_device(self.domid, pci_str)
    5.13              if bdf != 0:
    5.14                  bus = (bdf >> 16) & 0xff
    5.15                  devfn = (bdf >> 8) & 0xff
     6.1 --- a/xen/arch/x86/domctl.c	Wed Dec 12 10:25:18 2007 +0000
     6.2 +++ b/xen/arch/x86/domctl.c	Wed Dec 12 10:29:35 2007 +0000
     6.3 @@ -525,10 +525,31 @@ long arch_do_domctl(
     6.4      }
     6.5      break;
     6.6  
     6.7 +    case XEN_DOMCTL_test_assign_device:
     6.8 +    {
     6.9 +        u8 bus, devfn;
    6.10 +
    6.11 +        ret = -EINVAL;
    6.12 +        if ( !vtd_enabled )
    6.13 +            break;
    6.14 +
    6.15 +        bus = (domctl->u.test_assign_device.machine_bdf >> 16) & 0xff;
    6.16 +        devfn = (domctl->u.test_assign_device.machine_bdf >> 8) & 0xff;
    6.17 +
    6.18 +        if ( device_assigned(bus, devfn) )
    6.19 +        {
    6.20 +            gdprintk(XENLOG_ERR, "XEN_DOMCTL_test_assign_device: "
    6.21 +                     "%x:%x:%x already assigned\n",
    6.22 +                     bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
    6.23 +            break;
    6.24 +        }
    6.25 +        ret = 0;
    6.26 +    }
    6.27 +    break;
    6.28 +
    6.29      case XEN_DOMCTL_assign_device:
    6.30      {
    6.31          struct domain *d;
    6.32 -        struct hvm_iommu *hd;
    6.33          u8 bus, devfn;
    6.34  
    6.35          ret = -EINVAL;
    6.36 @@ -541,7 +562,6 @@ long arch_do_domctl(
    6.37                  "XEN_DOMCTL_assign_device: get_domain_by_id() failed\n");
    6.38              break;
    6.39          }
    6.40 -        hd = domain_hvm_iommu(d);
    6.41          bus = (domctl->u.assign_device.machine_bdf >> 16) & 0xff;
    6.42          devfn = (domctl->u.assign_device.machine_bdf >> 8) & 0xff;
    6.43  
    6.44 @@ -549,7 +569,7 @@ long arch_do_domctl(
    6.45          {
    6.46              gdprintk(XENLOG_ERR, "XEN_DOMCTL_assign_device: "
    6.47                       "%x:%x:%x already assigned\n",
    6.48 -                     bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); 
    6.49 +                     bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
    6.50              break;
    6.51          }
    6.52  
     7.1 --- a/xen/include/public/domctl.h	Wed Dec 12 10:25:18 2007 +0000
     7.2 +++ b/xen/include/public/domctl.h	Wed Dec 12 10:29:35 2007 +0000
     7.3 @@ -435,9 +435,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendt
     7.4  
     7.5  
     7.6  /* Assign PCI device to HVM guest. Sets up IOMMU structures. */
     7.7 -#define XEN_DOMCTL_assign_device     37
     7.8 -#define DPCI_ADD_MAPPING         1
     7.9 -#define DPCI_REMOVE_MAPPING      0 
    7.10 +#define XEN_DOMCTL_assign_device      37
    7.11 +#define XEN_DOMCTL_test_assign_device 45
    7.12  struct xen_domctl_assign_device {
    7.13      uint32_t  machine_bdf;   /* machine PCI ID of assigned device */
    7.14  };
    7.15 @@ -473,6 +472,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_bind_
    7.16  
    7.17  /* Bind machine I/O address range -> HVM address range. */
    7.18  #define XEN_DOMCTL_memory_mapping    39
    7.19 +#define DPCI_ADD_MAPPING         1
    7.20 +#define DPCI_REMOVE_MAPPING      0
    7.21  struct xen_domctl_memory_mapping {
    7.22      uint64_aligned_t first_gfn; /* first page (hvm guest phys page) in range */
    7.23      uint64_aligned_t first_mfn; /* first page (machine page) in range */