x86/svm: Fix svm_update_guest_efer() for domains using shadow paging
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 4 Oct 2018 16:36:35 +0000 (16:36 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 17 Oct 2018 16:50:14 +0000 (17:50 +0100)
commit2442519adf57344e4d0dc5fdc3bf1d4feae50824
treeaf74414a51d72cd007c55817bf15b4431fdb0721
parenta3ae747dea48664b622ac7fc96a598578d406e86
x86/svm: Fix svm_update_guest_efer() for domains using shadow paging

When using shadow paging, EFER.NX is a Xen controlled bit, and is required by
the shadow pagefault handler to distinguish instruction fetches from data
accesses.

This can be observed by a guest which has NX and SMEP clear but SMAP active by
attempting to execute code on a user mapping.  The first attempt to build the
target shadow will #PF so is handled by the shadow code, but when walking the
the guest pagetables, the lack of PFEC_insn_fetch being signalled causes the
shadow code to mistake the instruction fetch for a data fetch, and believe
that it is a real guest fault.  As a result, the guest receives #PF[-d-srP]
for an action which should complete successfully.

The suspicious-looking gymnastics with LME is actually a subtle corner case
with shadow paging.  When dropping out of Long Mode, a guests choice of LME
and Xen's choice of CR0.PG cause hardware to operate in Long Mode, but the
shadow code to operate in 2-on-3 mode.

In addition to describing this corner case in the SVM side, extend the comment
for the same fix on the VT-x side.  (I have a suspicion that I've just worked
out why VT-x doesn't tolerate LMA != LME when Unrestricted Guest is clear.)

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/vmx/vmx.c