From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linutronix.de (193.142.43.55:993) by crypto-ml.lab.linutronix.de with IMAP4-SSL for ; 25 Oct 2019 08:37:49 -0000 Received: from mx2.suse.de ([195.135.220.15] helo=mx1.suse.de) by Galois.linutronix.de with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1iNv6R-0002e1-PJ for speck@linutronix.de; Fri, 25 Oct 2019 10:37:49 +0200 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 87D61B210 for ; Fri, 25 Oct 2019 08:37:41 +0000 (UTC) Date: Fri, 25 Oct 2019 10:37:39 +0200 From: Joerg Roedel Subject: [MODERATED] Re: ***UNCHECKED*** [PATCH v7 3/5] NX 3 Message-ID: <20191025083739.GC7069@suse.de> References: <1571934870-34323-1-git-send-email-pbonzini@redhat.com> <1571934870-34323-4-git-send-email-pbonzini@redhat.com> MIME-Version: 1.0 In-Reply-To: <1571934870-34323-4-git-send-email-pbonzini@redhat.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit To: speck@linutronix.de List-ID: Hi Paolo, On Thu, Oct 24, 2019 at 06:34:28PM +0200, speck for Paolo Bonzini wrote: > Documentation/admin-guide/kernel-parameters.txt | 11 ++ > arch/x86/include/asm/kvm_host.h | 2 + > arch/x86/kernel/cpu/bugs.c | 13 ++- > arch/x86/kvm/mmu.c | 135 ++++++++++++++++++++++-- > arch/x86/kvm/paging_tmpl.h | 29 +++-- > arch/x86/kvm/x86.c | 9 ++ > 6 files changed, 186 insertions(+), 13 deletions(-) I did some testing on 5.4-rc4 with these patches and they break the ept=off case on some machines, especially those with the load_ia32_efer capability: kvm [10312]: vcpu0, guest rIP: 0xffffffff810643f8 disabled perfctr wrmsr: 0xc2 data 0xffff walk_shadow_page_get_mmio_spte: detect reserved bits on spte, addr 0xbffbffd8, dump hierarchy: ------ spte 0x80000003ab000ce7 level 2. The reason is that during early guest boot KVM direct-maps the guest memory with a PAE page-table and pages there get the NX bit set. But the guest has EFER.NX=0, which causes the NX-bit to be reserved. I fixed it with this diff: diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index e7970a2e8eae..6e9380a0ca41 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -997,7 +997,7 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset) * On CPUs that support "load IA32_EFER", always switch EFER * atomically, since it's faster than switching it manually. */ - if (cpu_has_load_ia32_efer() || + if ((cpu_has_load_ia32_efer() && (guest_efer & EFER_NX)) || (enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX))) { if (!(guest_efer & EFER_LMA)) guest_efer &= ~EFER_LME; Regards, Joerg