Commit d42e3fae authored by Jim Mattson's avatar Jim Mattson Committed by Paolo Bonzini
Browse files

kvm: x86: Read PDPTEs on CR0.CD and CR0.NW changes



According to the SDM, when PAE paging would be in use following a
MOV-to-CR0 that modifies any of CR0.CD, CR0.NW, or CR0.PG, then the
PDPTEs are loaded from the address in CR3. Previously, kvm only loaded
the PDPTEs when PAE paging would be in use following a MOV-to-CR0 that
modified CR0.PG.

Signed-off-by: default avatarJim Mattson <jmattson@google.com>
Reviewed-by: default avatarOliver Upton <oupton@google.com>
Reviewed-by: default avatarPeter Shier <pshier@google.com>
Message-Id: <20200707223630.336700-1-jmattson@google.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 9a3c05e6
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -798,6 +798,7 @@ EXPORT_SYMBOL_GPL(pdptrs_changed);
int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
{
	unsigned long old_cr0 = kvm_read_cr0(vcpu);
	unsigned long pdptr_bits = X86_CR0_CD | X86_CR0_NW | X86_CR0_PG;
	unsigned long update_bits = X86_CR0_PG | X86_CR0_WP;

	cr0 |= X86_CR0_ET;
@@ -815,9 +816,9 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
	if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE))
		return 1;

	if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) {
	if (cr0 & X86_CR0_PG) {
#ifdef CONFIG_X86_64
		if ((vcpu->arch.efer & EFER_LME)) {
		if (!is_paging(vcpu) && (vcpu->arch.efer & EFER_LME)) {
			int cs_db, cs_l;

			if (!is_pae(vcpu))
@@ -827,8 +828,8 @@ int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
				return 1;
		} else
#endif
		if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.walk_mmu,
						 kvm_read_cr3(vcpu)))
		if (is_pae(vcpu) && ((cr0 ^ old_cr0) & pdptr_bits) &&
		    !load_pdptrs(vcpu, vcpu->arch.walk_mmu, kvm_read_cr3(vcpu)))
			return 1;
	}