]> xenbits.xensource.com Git - people/dwmw2/xen.git/commitdiff
x86/vvmx: Fix nested virt on VMCS-Shadow capable hardware
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 30 Jul 2019 14:19:04 +0000 (15:19 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 12 Aug 2019 14:50:10 +0000 (15:50 +0100)
c/s e9986b0dd "x86/vvmx: Simplify per-CPU memory allocations" had the wrong
indirection on its pointer check in nvmx_cpu_up_prepare(), causing the
VMCS-shadowing buffer never be allocated.  Fix it.

This in turn results in a massive quantity of logspam, as every virtual
vmentry/exit hits both gdprintk()s in the *_bulk() functions.

Switch these to using printk_once(), but still only in debug builds.  The size
of the buffer is chosen at compile time, so complaining about it repeatedly is
of no benefit.

Finally, drop the runtime NULL pointer checks.  It is not terribly appropriate
to be repeatedly checking infrastructure which is set up from start-of-day,
and in this case, actually hid the above bug.

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

index 332623d00625df1b03295a1c5161760edc401c97..fdf449bfd12551e95f9f06b8e797d8eaa6855e64 100644 (file)
@@ -43,7 +43,7 @@ int nvmx_cpu_up_prepare(unsigned int cpu)
     uint64_t **vvmcs_buf;
 
     if ( cpu_has_vmx_vmcs_shadowing &&
-         (vvmcs_buf = &per_cpu(vvmcs_buf, cpu)) == NULL )
+         *(vvmcs_buf = &per_cpu(vvmcs_buf, cpu)) == NULL )
     {
         void *ptr = xzalloc_array(uint64_t, VMCS_BUF_SIZE);
 
@@ -922,11 +922,11 @@ static void vvmcs_to_shadow_bulk(struct vcpu *v, unsigned int n,
     if ( !cpu_has_vmx_vmcs_shadowing )
         goto fallback;
 
-    if ( !value || n > VMCS_BUF_SIZE )
+    if ( n > VMCS_BUF_SIZE )
     {
-        gdprintk(XENLOG_DEBUG, "vmcs sync fall back to non-bulk mode, "
-                 "buffer: %p, buffer size: %d, fields number: %d.\n",
-                 value, VMCS_BUF_SIZE, n);
+        if ( IS_ENABLED(CONFIG_DEBUG) )
+            printk_once(XENLOG_ERR "%pv VMCS sync too many fields %u\n",
+                        v, n);
         goto fallback;
     }
 
@@ -962,11 +962,11 @@ static void shadow_to_vvmcs_bulk(struct vcpu *v, unsigned int n,
     if ( !cpu_has_vmx_vmcs_shadowing )
         goto fallback;
 
-    if ( !value || n > VMCS_BUF_SIZE )
+    if ( n > VMCS_BUF_SIZE )
     {
-        gdprintk(XENLOG_DEBUG, "vmcs sync fall back to non-bulk mode, "
-                 "buffer: %p, buffer size: %d, fields number: %d.\n",
-                 value, VMCS_BUF_SIZE, n);
+        if ( IS_ENABLED(CONFIG_DEBUG) )
+            printk_once(XENLOG_ERR "%pv VMCS sync too many fields %u\n",
+                        v, n);
         goto fallback;
     }