From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nadav Amit Subject: [PATCH 12/21] KVM: x86: MOV to CR3 can set bit 63 Date: Sun, 2 Nov 2014 11:54:52 +0200 Message-ID: <1414922101-17626-13-git-send-email-namit@cs.technion.ac.il> References: <1414922101-17626-1-git-send-email-namit@cs.technion.ac.il> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: kvm@vger.kernel.org, nadav.amit@gmail.com, Nadav Amit To: pbonzini@redhat.com Return-path: Received: from mailgw12.technion.ac.il ([132.68.225.12]:46469 "EHLO mailgw12.technion.ac.il" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751133AbaKBJzV (ORCPT ); Sun, 2 Nov 2014 04:55:21 -0500 In-Reply-To: <1414922101-17626-1-git-send-email-namit@cs.technion.ac.il> Sender: kvm-owner@vger.kernel.org List-ID: Although Intel SDM mentions bit 63 is reserved, MOV to CR3 can have bit= 63 set. As Intel SDM states in section 4.10.4 "Invalidation of TLBs and Paging-Structure Caches": " MOV to CR3. ... If CR4.PCIDE =3D 1 and bit = 63 of the instruction=E2=80=99s source operand is 0 ..." In other words, bit 63 is not reserved. KVM emulator currently consider= bit 63 as reserved. Fix it. Signed-off-by: Nadav Amit --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/emulate.c | 2 +- arch/x86/kvm/x86.c | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm= _host.h index 904535f..dc932d3 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -51,6 +51,7 @@ | X86_CR0_NW | X86_CR0_CD | X86_CR0_PG)) =20 #define CR3_L_MODE_RESERVED_BITS 0xFFFFFF0000000000ULL +#define CR3_PCID_INVD (1UL << 63) #define CR4_RESERVED_BITS = \ (~(unsigned long)(X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | X86_CR4_D= E\ | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \ diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index d45a57b..259c04b 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -3544,7 +3544,7 @@ static int check_cr_write(struct x86_emulate_ctxt= *ctxt) =20 ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); if (efer & EFER_LMA) - rsvd =3D CR3_L_MODE_RESERVED_BITS; + rsvd =3D CR3_L_MODE_RESERVED_BITS & ~CR3_PCID_INVD; =20 if (new_val & rsvd) return emulate_gp(ctxt, 0); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 9b90ea7..204e5b4 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -750,6 +750,8 @@ EXPORT_SYMBOL_GPL(kvm_set_cr4); =20 int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) { + cr3 &=3D ~CR3_PCID_INVD; + if (cr3 =3D=3D kvm_read_cr3(vcpu) && !pdptrs_changed(vcpu)) { kvm_mmu_sync_roots(vcpu); kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); --=20 1.9.1