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

[Xen-changelog] [xen stable-4.4] x86/HVM: sanity check xsave area when migrating or restoring from older Xen versions



commit 12e92e613b4985270c21da6b90183ac9330fb645
Author:     Don Koch <dkoch@xxxxxxxxxxx>
AuthorDate: Thu Nov 13 09:47:30 2014 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Nov 13 09:47:30 2014 +0100

    x86/HVM: sanity check xsave area when migrating or restoring from older Xen 
versions
    
    Xen 4.3.0, 4.2.3 and older transferred a maximum sized xsave area (as
    if all the available XCR0 bits were set); the new version only
    transfers based on the actual XCR0 bits. This may result in a smaller
    area if the last sections were missing (e.g., the LWP area from an AMD
    machine). If the size doesn't match the XCR0 derived size, the size is
    checked against the maximum size and the part of the xsave area
    between the actual and maximum used size is checked for zero data. If
    either the max size check or any part of the overflow area is
    non-zero, we return with an error.
    
    Signed-off-by: Don Koch <dkoch@xxxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    master commit: d7bb8e88a087690feba63ef83c13ba067f041da0
    master date: 2014-10-27 16:45:09 +0100
---
 xen/arch/x86/hvm/hvm.c |   31 ++++++++++++++++++++-----------
 1 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 0c04972..b004b74 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -1041,6 +1041,7 @@ static int hvm_load_cpu_xsave_states(struct domain *d, 
hvm_domain_context_t *h)
     struct vcpu *v;
     struct hvm_hw_cpu_xsave *ctxt;
     struct hvm_save_descriptor *desc;
+    unsigned int i, desc_start;
 
     /* Which vcpu is this? */
     vcpuid = hvm_load_instance(h);
@@ -1081,15 +1082,8 @@ static int hvm_load_cpu_xsave_states(struct domain *d, 
hvm_domain_context_t *h)
                         save_area) + XSTATE_AREA_MIN_SIZE);
         return -EINVAL;
     }
-    size = HVM_CPU_XSAVE_SIZE(xfeature_mask);
-    if ( desc->length > size )
-    {
-        printk(XENLOG_G_WARNING
-               "HVM%d.%d restore mismatch: xsave length %u > %u\n",
-               d->domain_id, vcpuid, desc->length, size);
-        return -EOPNOTSUPP;
-    }
     h->cur += sizeof (*desc);
+    desc_start = h->cur;
 
     ctxt = (struct hvm_hw_cpu_xsave *)&h->data[h->cur];
     h->cur += desc->length;
@@ -1109,10 +1103,24 @@ static int hvm_load_cpu_xsave_states(struct domain *d, 
hvm_domain_context_t *h)
     size = HVM_CPU_XSAVE_SIZE(ctxt->xcr0_accum);
     if ( desc->length > size )
     {
+        /*
+         * Xen 4.3.0, 4.2.3 and older used to send longer-than-needed
+         * xsave regions.  Permit loading the record if the extra data
+         * is all zero.
+         */
+        for ( i = size; i < desc->length; i++ )
+        {
+            if ( h->data[desc_start + i] )
+            {
+                printk(XENLOG_G_WARNING
+                       "HVM%d.%u restore mismatch: xsave length %#x > %#x 
(non-zero data at %#x)\n",
+                       d->domain_id, vcpuid, desc->length, size, i);
+                return -EOPNOTSUPP;
+            }
+        }
         printk(XENLOG_G_WARNING
-               "HVM%d.%d restore mismatch: xsave length %u > %u\n",
+               "HVM%d.%u restore mismatch: xsave length %#x > %#x\n",
                d->domain_id, vcpuid, desc->length, size);
-        return -EOPNOTSUPP;
     }
     /* Checking finished */
 
@@ -1121,7 +1129,8 @@ static int hvm_load_cpu_xsave_states(struct domain *d, 
hvm_domain_context_t *h)
     if ( ctxt->xcr0_accum & XSTATE_NONLAZY )
         v->arch.nonlazy_xstate_used = 1;
     memcpy(v->arch.xsave_area, &ctxt->save_area,
-           desc->length - offsetof(struct hvm_hw_cpu_xsave, save_area));
+           min(desc->length, size) - offsetof(struct hvm_hw_cpu_xsave,
+           save_area));
 
     return 0;
 }
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.4

_______________________________________________
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®.