x86/pv: Fix consistency of 64bit segment bases
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 11 Sep 2020 12:10:57 +0000 (14:10 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 11 Sep 2020 12:10:57 +0000 (14:10 +0200)
commit431d52afd9438a3a126dfd787bd2d69b76906cb5
tree585f8006add6278259dcad37628f4ff45699d934
parentceafff707c96ca5cf01a435e4cf6f64c2dfc9a4d
x86/pv: Fix consistency of 64bit segment bases

The comments in save_segments(), _toggle_guest_pt() and write_cr() are false.
The %fs and %gs bases can be updated at any time by the guest.

As a consequence, Xen's fs_base/etc tracking state is always stale when the
vcpu is in context, and must not be used to complete MSR_{FS,GS}_BASE reads, etc.

In particular, a sequence such as:

  wrmsr(MSR_FS_BASE, 0x1ull << 32);
  write_fs(__USER_DS);
  base = rdmsr(MSR_FS_BASE);

will return the stale base, not the new base.  This may cause guest a guest
kernel's context switching of userspace to malfunction.

Therefore:
 * Update save_segments(), _toggle_guest_pt() and read_msr() to always read
   the segment bases from hardware.
 * Update write_cr(), write_msr() and do_set_segment_base() to not not waste
   time caching data which is instantly going to become stale again.
 * Provide comments explaining when the tracking state is and isn't stale.

This bug has been present for 14 years, but several bugfixes since have built
on and extended the original flawed logic.

Fixes: ba9adb737ba ("Apply stricter checking to RDMSR/WRMSR emulations.")
Fixes: c42494acb2f ("x86: fix FS/GS base handling when using the fsgsbase feature")
Fixed: eccc170053e ("x86/pv: Don't have %cr4.fsgsbase active behind a guest kernels back")
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
master commit: a5eaac9245f4f382a3cd0e9710e9d1cba7db20e4
master date: 2020-09-07 11:32:34 +0100
xen/arch/x86/domain.c
xen/arch/x86/pv/domain.c
xen/arch/x86/pv/emul-priv-op.c
xen/arch/x86/x86_64/mm.c
xen/include/asm-x86/domain.h