x86/xstate: Fix array overrun on hardware with LWP
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 13 Jan 2017 18:51:04 +0000 (18:51 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 16 Jan 2017 17:37:26 +0000 (17:37 +0000)
c/s da62246e4c "x86/xsaves: enable xsaves/xrstors/xsavec in xen" introduced
setup_xstate_features() to allocate and fill xstate_offsets[] and
xstate_sizes[].

However, fls() casts xfeature_mask to 32bits which truncates LWP out of the
calculation.  As a result, the arrays are allocated too short, and the cpuid
infrastructure reads off the end of them when calculating xstate_size for the
guest.

On one test system, this results in 0x3fec83c0 being returned as the maximum
size of an xsave area, which surprisingly appears not to bother Windows or
Linux too much.  I suspect they both use current size based on xcr0, which Xen
forwards from real hardware.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/xstate.c

index 6073e1d3ace985905154e9d434557210c433f642..b8ae6568613f8fec46eb777063d2235e9595c090 100644 (file)
@@ -92,7 +92,7 @@ static int setup_xstate_features(bool_t bsp)
 
     if ( bsp )
     {
-        xstate_features = fls(xfeature_mask);
+        xstate_features = flsl(xfeature_mask);
         xstate_offsets = xzalloc_array(unsigned int, xstate_features);
         if ( !xstate_offsets )
             return -ENOMEM;