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

[Xen-changelog] [xen master] VT-d: decouple SandyBridge quirk from VTd timeout



commit 10e7747bca538205555e313574432f231070153b
Author:     Don Dugger <donald.d.dugger@xxxxxxxxx>
AuthorDate: Fri Dec 5 12:46:15 2014 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Fri Dec 5 12:46:15 2014 +0100

    VT-d: decouple SandyBridge quirk from VTd timeout
    
    Currently the quirk code for SandyBridge uses the VTd timeout value when
    writing to an IGD register.  This is the wrong timeout to use and, at
    1000 msec., is also much too large.  This patch changes the quirk code
    to use a timeout that is specific to the IGD device and allows the user
    control of the timeout.
    
    Boolean settings for the boot parameter `snb_igd_quirk' keep their current
    meaning, enabling or disabling the quirk code with a timeout of 1000 msec.
    
    In addition specifying `snb_igd_quirk=default' will enable the code and
    set the timeout to the theoretical maximum of 670 msec.  For finer control,
    specifying `snb_igd_quirk=n', where `n' is a decimal number, will enable
    the code and set the timeout to `n' msec.
    
    Signed-off-by: Don Dugger <donald.d.dugger@xxxxxxxxx>
    Acked-by: Kevin Tian <kevin.tian@xxxxxxxxx>
    
    Update documentation.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 docs/misc/xen-command-line.markdown  |    7 ++++-
 xen/drivers/passthrough/vtd/quirks.c |   46 +++++++++++++++++++++++++++++----
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/docs/misc/xen-command-line.markdown 
b/docs/misc/xen-command-line.markdown
index 0866df2..311316a 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -1171,7 +1171,12 @@ Flag to enable Supervisor Mode Execution Protection
 Flag to enable Supervisor Mode Access Prevention
 
 ### snb\_igd\_quirk
-> `= <boolean>`
+> `= <boolean> | cap | <integer>`
+
+A true boolean value enables legacy behavior (1s timeout), while `cap`
+enforces the maximum theoretically necessary timeout of 670ms. Any number
+is being interpreted as a custom timeout in milliseconds. Zero or boolean
+false disable the quirk workaround, which is also the default.
 
 ### sync\_console
 > `= <boolean>`
diff --git a/xen/drivers/passthrough/vtd/quirks.c 
b/xen/drivers/passthrough/vtd/quirks.c
index 839dc45..b24fb12 100644
--- a/xen/drivers/passthrough/vtd/quirks.c
+++ b/xen/drivers/passthrough/vtd/quirks.c
@@ -50,6 +50,11 @@
 #define IS_ILK(id)    (id == 0x00408086 || id == 0x00448086 || id== 0x00628086 
|| id == 0x006A8086)
 #define IS_CPT(id)    (id == 0x01008086 || id == 0x01048086)
 
+/* SandyBridge IGD timeouts in milliseconds */
+#define SNB_IGD_TIMEOUT_LEGACY    1000
+#define SNB_IGD_TIMEOUT            670
+static unsigned int snb_igd_timeout;
+
 static u32 __read_mostly ioh_id;
 static u32 __initdata igd_id;
 bool_t __read_mostly rwbf_quirk;
@@ -158,6 +163,16 @@ static int cantiga_vtd_ops_preamble(struct iommu* iommu)
  * Workaround is to prevent graphics get into RC6
  * state when doing VT-d IOTLB operations, do the VT-d
  * IOTLB operation, and then re-enable RC6 state.
+ *
+ * This quirk is enabled with the snb_igd_quirk command
+ * line parameter.  Specifying snb_igd_quirk with no value
+ * (or any of the standard boolean values) enables this
+ * quirk and sets the timeout to the legacy timeout of
+ * 1000 msec.  Setting this parameter to the string
+ * "cap" enables this quirk and sets the timeout to
+ * the theoretical maximum of 670 msec.  Setting this
+ * parameter to a numerical value enables the quirk and
+ * sets the timeout to that numerical number of msecs.
  */
 static void snb_vtd_ops_preamble(struct iommu* iommu)
 {
@@ -177,7 +192,7 @@ static void snb_vtd_ops_preamble(struct iommu* iommu)
     start_time = NOW();
     while ( (*(volatile u32 *)(igd_reg_va + 0x22AC) & 0xF) != 0 )
     {
-        if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
+        if ( NOW() > start_time + snb_igd_timeout )
         {
             dprintk(XENLOG_INFO VTDPREFIX,
                     "snb_vtd_ops_preamble: failed to disable idle 
handshake\n");
@@ -208,13 +223,10 @@ static void snb_vtd_ops_postamble(struct iommu* iommu)
  * call before VT-d translation enable and IOTLB flush operations.
  */
 
-static int snb_igd_quirk;
-boolean_param("snb_igd_quirk", snb_igd_quirk);
-
 void vtd_ops_preamble_quirk(struct iommu* iommu)
 {
     cantiga_vtd_ops_preamble(iommu);
-    if ( snb_igd_quirk )
+    if ( snb_igd_timeout != 0 )
     {
         spin_lock(&igd_lock);
 
@@ -228,7 +240,7 @@ void vtd_ops_preamble_quirk(struct iommu* iommu)
  */
 void vtd_ops_postamble_quirk(struct iommu* iommu)
 {
-    if ( snb_igd_quirk )
+    if ( snb_igd_timeout != 0 )
     {
         snb_vtd_ops_postamble(iommu);
 
@@ -237,6 +249,28 @@ void vtd_ops_postamble_quirk(struct iommu* iommu)
     }
 }
 
+static void __init parse_snb_timeout(const char *s)
+{
+    int t;
+
+    t = parse_bool(s);
+    if ( t < 0 )
+    {
+        if ( *s == '\0' )
+            t = SNB_IGD_TIMEOUT_LEGACY;
+        else if ( strcmp(s, "cap") == 0 )
+            t = SNB_IGD_TIMEOUT;
+        else
+            t = strtoul(s, NULL, 0);
+    }
+    else
+        t = t ? SNB_IGD_TIMEOUT_LEGACY : 0;
+    snb_igd_timeout = MILLISECS(t);
+
+    return;
+}
+custom_param("snb_igd_quirk", parse_snb_timeout);
+
 /* 5500/5520/X58 Chipset Interrupt remapping errata, for stepping B-3.
  * Fixed in stepping C-2. */
 static void __init tylersburg_intremap_quirk(void)
--
generated by git-patchbot for /home/xen/git/xen.git#master

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


 


Rackspace

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