x86/vmx: Fix handing of MSR_DEBUGCTL on VMExit
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 24 May 2018 17:20:09 +0000 (17:20 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 14 Aug 2018 15:59:23 +0000 (16:59 +0100)
commit4254e9874006cc2641b67d0531a3a65374f34c35
tree11d214d616fe95caee542b2195613013543723f8
parent6fe9726aebc11433083b9810402501f1a71d02fd
x86/vmx: Fix handing of MSR_DEBUGCTL on VMExit

Currently, whenever the guest writes a nonzero value to MSR_DEBUGCTL, Xen
updates a host MSR load list entry with the current hardware value of
MSR_DEBUGCTL.

On VMExit, hardware automatically resets MSR_DEBUGCTL to 0.  Later, when the
guest writes to MSR_DEBUGCTL, the current value in hardware (0) is fed back
into guest load list.  As a practical result, `ler` debugging gets lost on any
PCPU which has ever scheduled an HVM vcpu, and the common case when `ler`
debugging isn't active, guest actions result in an unnecessary load list entry
repeating the MSR_DEBUGCTL reset.

Restoration of Xen's debugging setting needs to happen from the very first
vmexit.  Due to the automatic reset, Xen need take no action in the general
case, and only needs to load a value when debugging is active.

This could be fixed by using a host MSR load list entry set up during
construct_vmcs().  However, a more efficient option is to use an alternative
block in the VMExit path, keyed on whether hypervisor debugging has been
enabled.

In order to set this up, drop the per cpu ler_msr variable (as there is no
point having it per cpu when it will be the same everywhere), and use a single
read_mostly variable instead.  Split calc_ler_msr() out of percpu_traps_init()
for clarity.

Finally, clean up do_debug().  Reinstate LBR early to help catch cascade
errors, which allows for the removal of the out label.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
(cherry picked from commit 730dc8d2c9e1b6402e66973cf99a7c56bc78be4c)
xen/arch/x86/hvm/vmx/entry.S
xen/arch/x86/hvm/vmx/vmx.c
xen/arch/x86/traps.c
xen/arch/x86/x86_64/traps.c
xen/include/asm-x86/cpufeature.h
xen/include/asm-x86/cpufeatures.h
xen/include/asm-x86/msr.h