Skip to content

Commit 0107973

Browse files
babumogerbonzini
authored andcommitted
KVM: x86: Introduce cr3_lm_rsvd_bits in kvm_vcpu_arch
SEV guests fail to boot on a system that supports the PCID feature. While emulating the RSM instruction, KVM reads the guest CR3 and calls kvm_set_cr3(). If the vCPU is in the long mode, kvm_set_cr3() does a sanity check for the CR3 value. In this case, it validates whether the value has any reserved bits set. The reserved bit range is 63:cpuid_maxphysaddr(). When AMD memory encryption is enabled, the memory encryption bit is set in the CR3 value. The memory encryption bit may fall within the KVM reserved bit range, causing the KVM emulation failure. Introduce a new field cr3_lm_rsvd_bits in kvm_vcpu_arch which will cache the reserved bits in the CR3 value. This will be initialized to rsvd_bits(cpuid_maxphyaddr(vcpu), 63). If the architecture has any special bits(like AMD SEV encryption bit) that needs to be masked from the reserved bits, should be cleared in vendor specific kvm_x86_ops.vcpu_after_set_cpuid handler. Fixes: a780a3e ("KVM: X86: Fix reserved bits check for MOV to CR3") Signed-off-by: Babu Moger <babu.moger@amd.com> Message-Id: <160521947657.32054.3264016688005356563.stgit@bmoger-ubuntu> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 51b958e commit 0107973

3 files changed

Lines changed: 4 additions & 1 deletion

File tree

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,7 @@ struct kvm_vcpu_arch {
639639
int cpuid_nent;
640640
struct kvm_cpuid_entry2 *cpuid_entries;
641641

642+
unsigned long cr3_lm_rsvd_bits;
642643
int maxphyaddr;
643644
int max_tdp_level;
644645

arch/x86/kvm/cpuid.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
178178
vcpu->arch.cr4_guest_rsvd_bits =
179179
__cr4_reserved_bits(guest_cpuid_has, vcpu);
180180

181+
vcpu->arch.cr3_lm_rsvd_bits = rsvd_bits(cpuid_maxphyaddr(vcpu), 63);
182+
181183
/* Invoke the vendor callback only after the above state is updated. */
182184
kvm_x86_ops.vcpu_after_set_cpuid(vcpu);
183185
}

arch/x86/kvm/x86.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,7 @@ int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
10411041
}
10421042

10431043
if (is_long_mode(vcpu) &&
1044-
(cr3 & rsvd_bits(cpuid_maxphyaddr(vcpu), 63)))
1044+
(cr3 & vcpu->arch.cr3_lm_rsvd_bits))
10451045
return 1;
10461046
else if (is_pae_paging(vcpu) &&
10471047
!load_pdptrs(vcpu, vcpu->arch.walk_mmu, cr3))

0 commit comments

Comments
 (0)