Skip to content

Commit

Permalink
KVM: MMU: check guest CR3 reserved bits based on its physical address…
Browse files Browse the repository at this point in the history
… width.

Currently, KVM uses CR3_L_MODE_RESERVED_BITS to check the
reserved bits in CR3. Yet the length of reserved bits in
guest CR3 should be based on the physical address width
exposed to the VM. This patch changes CR3 check logic to
calculate the reserved bits at runtime.

Signed-off-by: Yu Zhang <yu.c.zhang@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
Yu Zhang authored and Paolo Bonzini committed Aug 24, 2017
1 parent e911eb3 commit d1cd3ce
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 7 deletions.
1 change: 0 additions & 1 deletion arch/x86/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@
| X86_CR0_ET | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM \
| X86_CR0_NW | X86_CR0_CD | X86_CR0_PG))

#define CR3_L_MODE_RESERVED_BITS 0xFFFFFF0000000000ULL
#define CR3_PCID_INVD BIT_64(63)
#define CR4_RESERVED_BITS \
(~(unsigned long)(X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | X86_CR4_DE\
Expand Down
14 changes: 12 additions & 2 deletions arch/x86/kvm/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include "x86.h"
#include "tss.h"
#include "mmu.h"

/*
* Operand types
Expand Down Expand Up @@ -4097,8 +4098,17 @@ static int check_cr_write(struct x86_emulate_ctxt *ctxt)
u64 rsvd = 0;

ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
if (efer & EFER_LMA)
rsvd = CR3_L_MODE_RESERVED_BITS & ~CR3_PCID_INVD;
if (efer & EFER_LMA) {
u64 maxphyaddr;
u32 eax = 0x80000008;

if (ctxt->ops->get_cpuid(ctxt, &eax, NULL, NULL,
NULL, false))
maxphyaddr = eax & 0xff;
else
maxphyaddr = 36;
rsvd = rsvd_bits(maxphyaddr, 62);
}

if (new_val & rsvd)
return emulate_gp(ctxt, 0);
Expand Down
3 changes: 3 additions & 0 deletions arch/x86/kvm/mmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@

static inline u64 rsvd_bits(int s, int e)
{
if (e < s)
return 0;

return ((1ULL << (e - s + 1)) - 1) << s;
}

Expand Down
8 changes: 4 additions & 4 deletions arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -813,10 +813,10 @@ int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
return 0;
}

if (is_long_mode(vcpu)) {
if (cr3 & CR3_L_MODE_RESERVED_BITS)
return 1;
} else if (is_pae(vcpu) && is_paging(vcpu) &&
if (is_long_mode(vcpu) &&
(cr3 & rsvd_bits(cpuid_maxphyaddr(vcpu), 62)))
return 1;
else if (is_pae(vcpu) && is_paging(vcpu) &&
!load_pdptrs(vcpu, vcpu->arch.walk_mmu, cr3))
return 1;

Expand Down

0 comments on commit d1cd3ce

Please sign in to comment.