WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] vtd: do FLR before xc.domain_destroy()

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] vtd: do FLR before xc.domain_destroy()
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 27 Aug 2008 11:23:25 -0700
Delivery-date: Wed, 27 Aug 2008 11:23:18 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1219756299 -3600
# Node ID c5a7ceb199cde8a1181aad6059ad17af8176ab05
# Parent  493a0a87919e4403d88dc716254fbdf646afa2f1
vtd: do FLR before xc.domain_destroy()

When we "xm destroy" a guest with assigned devices, in
xen/common/domain.c:domain_kill(), we relinquish guest's memory first,
then invoke domain_destroy() -> complete_domain_destroy() ->
arch_domain_destroy() -> pci_release_devices()/iommu_domain_destroy().

Between relinquish_memory() and domain_destroy(), a device may be
issuing DMA request and access guest's relinquished  memory.

We can do_FLR() to quiesce devices before xc.domain_destroy().

Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx>
---
 tools/python/xen/util/pci.py                  |   37 +++++++++++++++++++++++---
 tools/python/xen/xend/XendDomain.py           |    4 ++
 tools/python/xen/xend/XendDomainInfo.py       |   24 ++++++++++++++++
 tools/python/xen/xend/server/DevController.py |    8 -----
 tools/python/xen/xend/server/pciif.py         |   25 +++--------------
 5 files changed, 67 insertions(+), 31 deletions(-)

diff -r 493a0a87919e -r c5a7ceb199cd tools/python/xen/util/pci.py
--- a/tools/python/xen/util/pci.py      Tue Aug 26 14:10:17 2008 +0100
+++ b/tools/python/xen/util/pci.py      Tue Aug 26 14:11:39 2008 +0100
@@ -40,6 +40,7 @@ DEV_TYPE_PCI_BRIDGE     = 2
 DEV_TYPE_PCI_BRIDGE     = 2
 DEV_TYPE_PCI            = 3    
 
+PCI_VENDOR_ID = 0x0
 PCI_STATUS = 0x6
 PCI_CLASS_DEVICE = 0x0a
 PCI_CLASS_BRIDGE_PCI = 0x0604
@@ -68,6 +69,11 @@ PCI_PM_CTRL_NO_SOFT_RESET = 0x0004
 PCI_PM_CTRL_NO_SOFT_RESET = 0x0004
 PCI_PM_CTRL_STATE_MASK = 0x0003
 PCI_D3hot = 3
+
+VENDOR_INTEL  = 0x8086
+PCI_CAP_ID_VENDOR_SPECIFIC_CAP = 0x09
+PCI_CLASS_ID_USB = 0x0c03
+PCI_USB_FLRCTRL = 0x4
 
 PCI_CAP_ID_AF = 0x13
 PCI_AF_CAPs   = 0x3
@@ -487,7 +493,7 @@ class PciDevice:
     def do_Dstate_transition(self):
         pos = self.find_cap_offset(PCI_CAP_ID_PM)
         if pos == 0:
-            return 
+            return False
         
         (pci_list, cfg_list) = save_pci_conf_space([self.name])
         
@@ -504,6 +510,31 @@ class PciDevice:
         time.sleep(0.010)
 
         restore_pci_conf_space((pci_list, cfg_list))
+        return True
+
+    def do_vendor_specific_FLR_method(self):
+        pos = self.find_cap_offset(PCI_CAP_ID_VENDOR_SPECIFIC_CAP)
+        if pos == 0:
+            return
+
+        vendor_id = self.pci_conf_read16(PCI_VENDOR_ID)
+        if vendor_id != VENDOR_INTEL:
+            return
+
+        class_id = self.pci_conf_read16(PCI_CLASS_DEVICE)
+        if class_id != PCI_CLASS_ID_USB:
+            return
+
+        (pci_list, cfg_list) = save_pci_conf_space([self.name])
+
+        self.pci_conf_write8(pos + PCI_USB_FLRCTRL, 1)
+        time.sleep(0.010)
+
+        restore_pci_conf_space((pci_list, cfg_list))
+
+    def do_FLR_for_integrated_device(self):
+        if not self.do_Dstate_transition():
+            self.do_vendor_specific_FLR_method()
 
     def find_all_the_multi_functions(self):
         sysfs_mnt = find_sysfs_mnt()
@@ -676,7 +707,7 @@ class PciDevice:
                 restore_pci_conf_space((pci_list, cfg_list))
             else:
                 if self.bus == 0:
-                    self.do_Dstate_transition()
+                    self.do_FLR_for_integrated_device()
                 else:
                     funcs = self.find_all_the_multi_functions()
                     self.devs_check_driver(funcs)
@@ -697,7 +728,7 @@ class PciDevice:
                 restore_pci_conf_space((pci_list, cfg_list))
             else:
                 if self.bus == 0:
-                    self.do_Dstate_transition()
+                    self.do_FLR_for_integrated_device()
                 else:
                     devs = self.find_coassigned_devices(False)
                     # Remove the element 0 which is a bridge
diff -r 493a0a87919e -r c5a7ceb199cd tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Tue Aug 26 14:10:17 2008 +0100
+++ b/tools/python/xen/xend/XendDomain.py       Tue Aug 26 14:11:39 2008 +0100
@@ -419,6 +419,8 @@ class XendDomain:
                 except VmError:
                     log.exception("Unable to recreate domain")
                     try:
+                        xc.domain_pause(domid)
+                        do_FLR(domid)
                         xc.domain_destroy(domid)
                     except:
                         log.exception("Hard destruction of domain failed: %d" %
@@ -1255,6 +1257,8 @@ class XendDomain:
             val = dominfo.destroy()
         else:
             try:
+                xc.domain_pause(int(domid))
+                do_FLR(int(domid))
                 val = xc.domain_destroy(int(domid))
             except ValueError:
                 raise XendInvalidDomain(domid)
diff -r 493a0a87919e -r c5a7ceb199cd tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Tue Aug 26 14:10:17 2008 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Tue Aug 26 14:11:39 2008 +0100
@@ -287,6 +287,28 @@ def dom_get(dom):
         log.trace("domain_getinfo(%d) failed, ignoring: %s", dom, str(err))
     return None
 
+def do_FLR(domid):
+    from xen.xend.server.pciif import parse_pci_name, PciDevice
+    path = '/local/domain/0/backend/pci/%u/0/' % domid
+    num_devs = xstransact.Read(path + 'num_devs');
+    if num_devs is None or num_devs == "":
+        return;
+
+    num_devs = int(xstransact.Read(path + 'num_devs'));
+
+    dev_str_list = []
+    for i in range(num_devs):
+        dev_str = xstransact.Read(path + 'dev-%i' % i)
+        dev_str_list = dev_str_list + [dev_str]
+
+    for dev_str in dev_str_list:
+        (dom, b, d, f) = parse_pci_name(dev_str)
+        try:
+            dev = PciDevice(dom, b, d, f)
+        except Exception, e:
+            raise VmError("pci: failed to locate device and "+
+                    "parse it's resources - "+str(e))
+        dev.do_FLR()
 
 class XendDomainInfo:
     """An object represents a domain.
@@ -2410,6 +2432,8 @@ class XendDomainInfo:
         try:
             if self.domid is not None:
                 xc.domain_destroy_hook(self.domid)
+                xc.domain_pause(self.domid)
+                do_FLR(self.domid)
                 xc.domain_destroy(self.domid)
                 for state in DOM_STATES_OLD:
                     self.info[state] = 0
diff -r 493a0a87919e -r c5a7ceb199cd 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Tue Aug 26 14:10:17 
2008 +0100
+++ b/tools/python/xen/xend/server/DevController.py     Tue Aug 26 14:11:39 
2008 +0100
@@ -223,12 +223,6 @@ class DevController:
         raise VmError('%s devices may not be reconfigured' % self.deviceClass)
 
 
-    def cleanupDeviceOnDomainDestroy(self, devid):
-        """ Some devices may need special cleanup when the guest domain
-            is destroyed.
-        """
-        return
-
     def destroyDevice(self, devid, force):
         """Destroy the specified device.
 
@@ -244,8 +238,6 @@ class DevController:
         """
 
         dev = self.convertToDeviceNumber(devid)
-
-        self.cleanupDeviceOnDomainDestroy(dev)
 
         # Modify online status /before/ updating state (latter is watched by
         # drivers, so this ordering avoids a race).
diff -r 493a0a87919e -r c5a7ceb199cd tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py     Tue Aug 26 14:10:17 2008 +0100
+++ b/tools/python/xen/xend/server/pciif.py     Tue Aug 26 14:11:39 2008 +0100
@@ -383,10 +383,10 @@ class PciController(DevController):
             if (dev.dev_type == DEV_TYPE_PCIe_ENDPOINT) and not dev.pcie_flr:
                 if dev.bus == 0:
                     # We cope with this case by using the Dstate transition
-                    # method for now.
+                    # method or some vendor specific methods for now.
                     err_msg = 'pci: %s: it is on bus 0, but has no PCIe' +\
                         ' FLR Capability. Will try the Dstate transition'+\
-                        ' method if available.'
+                        ' method or some vendor specific methods if available.'
                     log.warn(err_msg % dev.name)
                 else:
                     funcs = dev.find_all_the_multi_functions()
@@ -404,10 +404,11 @@ class PciController(DevController):
                 if dev.bus == 0 or arch.type == "ia64":
                     if not dev.pci_af_flr:
                         # We cope with this case by using the Dstate transition
-                        # method for now.
+                        # method or some vendor specific methods for now.
                         err_msg = 'pci: %s: it is on bus 0, but has no PCI' +\
                             ' Advanced Capabilities for FLR. Will try the'+\
-                            ' Dstate transition method if available.'
+                            ' Dstate transition method or some vendor' +\
+                            ' specific methods if available.'
                         log.warn(err_msg % dev.name)
                 else:
                     # All devices behind the uppermost PCI/PCI-X bridge must 
be\
@@ -543,22 +544,6 @@ class PciController(DevController):
 
         return new_num_devs
 
-    def cleanupDeviceOnDomainDestroy(self, devid):
-        num_devs = int(self.readBackend(devid, 'num_devs'))
-        dev_str_list = []
-        for i in range(num_devs):
-            dev_str = self.readBackend(devid, 'dev-%i' % i)
-            dev_str_list = dev_str_list + [dev_str]
-
-        for dev_str in dev_str_list:
-            (dom, b, d, f) = parse_pci_name(dev_str)
-            try:
-                dev = PciDevice(dom, b, d, f)
-            except Exception, e:
-                raise VmError("pci: failed to locate device and "+
-                        "parse it's resources - "+str(e))
-            dev.do_FLR()
-
     def waitForBackend(self,devid):
         return (0, "ok - no hotplug")
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] vtd: do FLR before xc.domain_destroy(), Xen patchbot-unstable <=