Skip to content

Commit d0fe7b6

Browse files
sean-jcbonzini
authored andcommitted
KVM: x86: Remove emulator's broken checks on CR0/CR3/CR4 loads
Remove the emulator's checks for illegal CR0, CR3, and CR4 values, as the checks are redundant, outdated, and in the case of SEV's C-bit, broken. The emulator manually calculates MAXPHYADDR from CPUID and neglects to mask off the C-bit. For all other checks, kvm_set_cr*() are a superset of the emulator checks, e.g. see CR4.LA57. Fixes: a780a3e ("KVM: X86: Fix reserved bits check for MOV to CR3") Cc: Babu Moger <[email protected]> Signed-off-by: Sean Christopherson <[email protected]> Message-Id: <[email protected]> Cc: [email protected] [Unify check_cr_read and check_cr_write. - Paolo] Signed-off-by: Paolo Bonzini <[email protected]>
1 parent dbdd096 commit d0fe7b6

File tree

1 file changed

+3
-77
lines changed

1 file changed

+3
-77
lines changed

arch/x86/kvm/emulate.c

Lines changed: 3 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -4220,88 +4220,14 @@ static bool valid_cr(int nr)
42204220
}
42214221
}
42224222

4223-
static int check_cr_read(struct x86_emulate_ctxt *ctxt)
4223+
static int check_cr_access(struct x86_emulate_ctxt *ctxt)
42244224
{
42254225
if (!valid_cr(ctxt->modrm_reg))
42264226
return emulate_ud(ctxt);
42274227

42284228
return X86EMUL_CONTINUE;
42294229
}
42304230

4231-
static int check_cr_write(struct x86_emulate_ctxt *ctxt)
4232-
{
4233-
u64 new_val = ctxt->src.val64;
4234-
int cr = ctxt->modrm_reg;
4235-
u64 efer = 0;
4236-
4237-
static u64 cr_reserved_bits[] = {
4238-
0xffffffff00000000ULL,
4239-
0, 0, 0, /* CR3 checked later */
4240-
CR4_RESERVED_BITS,
4241-
0, 0, 0,
4242-
CR8_RESERVED_BITS,
4243-
};
4244-
4245-
if (!valid_cr(cr))
4246-
return emulate_ud(ctxt);
4247-
4248-
if (new_val & cr_reserved_bits[cr])
4249-
return emulate_gp(ctxt, 0);
4250-
4251-
switch (cr) {
4252-
case 0: {
4253-
u64 cr4;
4254-
if (((new_val & X86_CR0_PG) && !(new_val & X86_CR0_PE)) ||
4255-
((new_val & X86_CR0_NW) && !(new_val & X86_CR0_CD)))
4256-
return emulate_gp(ctxt, 0);
4257-
4258-
cr4 = ctxt->ops->get_cr(ctxt, 4);
4259-
ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
4260-
4261-
if ((new_val & X86_CR0_PG) && (efer & EFER_LME) &&
4262-
!(cr4 & X86_CR4_PAE))
4263-
return emulate_gp(ctxt, 0);
4264-
4265-
break;
4266-
}
4267-
case 3: {
4268-
u64 rsvd = 0;
4269-
4270-
ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
4271-
if (efer & EFER_LMA) {
4272-
u64 maxphyaddr;
4273-
u32 eax, ebx, ecx, edx;
4274-
4275-
eax = 0x80000008;
4276-
ecx = 0;
4277-
if (ctxt->ops->get_cpuid(ctxt, &eax, &ebx, &ecx,
4278-
&edx, true))
4279-
maxphyaddr = eax & 0xff;
4280-
else
4281-
maxphyaddr = 36;
4282-
rsvd = rsvd_bits(maxphyaddr, 63);
4283-
if (ctxt->ops->get_cr(ctxt, 4) & X86_CR4_PCIDE)
4284-
rsvd &= ~X86_CR3_PCID_NOFLUSH;
4285-
}
4286-
4287-
if (new_val & rsvd)
4288-
return emulate_gp(ctxt, 0);
4289-
4290-
break;
4291-
}
4292-
case 4: {
4293-
ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
4294-
4295-
if ((efer & EFER_LMA) && !(new_val & X86_CR4_PAE))
4296-
return emulate_gp(ctxt, 0);
4297-
4298-
break;
4299-
}
4300-
}
4301-
4302-
return X86EMUL_CONTINUE;
4303-
}
4304-
43054231
static int check_dr7_gd(struct x86_emulate_ctxt *ctxt)
43064232
{
43074233
unsigned long dr7;
@@ -4841,10 +4767,10 @@ static const struct opcode twobyte_table[256] = {
48414767
D(ImplicitOps | ModRM | SrcMem | NoAccess), /* 8 * reserved NOP */
48424768
D(ImplicitOps | ModRM | SrcMem | NoAccess), /* NOP + 7 * reserved NOP */
48434769
/* 0x20 - 0x2F */
4844-
DIP(ModRM | DstMem | Priv | Op3264 | NoMod, cr_read, check_cr_read),
4770+
DIP(ModRM | DstMem | Priv | Op3264 | NoMod, cr_read, check_cr_access),
48454771
DIP(ModRM | DstMem | Priv | Op3264 | NoMod, dr_read, check_dr_read),
48464772
IIP(ModRM | SrcMem | Priv | Op3264 | NoMod, em_cr_write, cr_write,
4847-
check_cr_write),
4773+
check_cr_access),
48484774
IIP(ModRM | SrcMem | Priv | Op3264 | NoMod, em_dr_write, dr_write,
48494775
check_dr_write),
48504776
N, N, N, N,

0 commit comments

Comments
 (0)