From: Andrew Cooper Date: Tue, 26 Sep 2017 16:08:33 +0000 (+0100) Subject: x86/svm: Fix a livelock when trying to run shadowed unpaged guests X-Git-Tag: archive/raspbian/4.11.1-1+rpi1~1^2~66^2~1285 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=3164f2f9db1e63ea64c3f9520d40cb09920d2b35;p=xen.git x86/svm: Fix a livelock when trying to run shadowed unpaged guests On AMD processors which support SMEP (Some Fam16h processors) and SMAP (Zen, Fam17h), a guest which is running with shadow paging and clears CR0.PG while keeping CR4.{SMEP,SMAP} set will livelock, as hardware raises #PF which the shadow pagetable concludes shouldn't happen. This occurs because hardware is running with host paging settings, which causes the guests choice of SMEP/SMAP to actually take effect, even though they shouldn't from the guests point of view. Signed-off-by: Andrew Cooper Reviewed-by: Boris Ostrovsky --- diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 12ddc8ae16..b9cf423fd9 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -576,6 +576,24 @@ void svm_update_guest_cr(struct vcpu *v, unsigned int cr) if ( paging_mode_hap(v->domain) ) value &= ~X86_CR4_PAE; value |= v->arch.hvm_vcpu.guest_cr[4]; + + if ( !hvm_paging_enabled(v) ) + { + /* + * When the guest thinks paging is disabled, Xen may need to hide + * the effects of shadow paging, as hardware runs with the host + * paging settings, rather than the guests settings. + * + * Without CR0.PG, all memory accesses are user mode, so + * _PAGE_USER must be set in the shadow pagetables for guest + * userspace to function. This in turn trips up guest supervisor + * mode if SMEP/SMAP are left active in context. They wouldn't + * have any effect if paging was actually disabled, so hide them + * behind the back of the guest. + */ + value &= ~(X86_CR4_SMEP | X86_CR4_SMAP); + } + vmcb_set_cr4(vmcb, value); break; default: