mirror of
https://github.com/qemu/qemu.git
synced 2024-11-28 14:24:02 +08:00
target/i386: Added consistency checks for EFER
EFER.SVME has to be set, and EFER reserved bits must be zero. In addition the combinations * EFER.LMA or EFER.LME is non-zero and the processor does not support LM * non-zero EFER.LME and CR0.PG and zero CR4.PAE * non-zero EFER.LME and CR0.PG and zero CR0.PE * non-zero EFER.LME, CR0.PG, CR4.PAE, CS.L and CS.D are all invalid. (AMD64 Architecture Programmer's Manual, V2, 15.5) Signed-off-by: Lara Lazier <laramglazier@gmail.com> Message-Id: <20210721152651.14683-3-laramglazier@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
213ff024a2
commit
d499f196fe
@ -475,6 +475,11 @@ typedef enum X86Seg {
|
||||
#define MSR_EFER_SVME (1 << 12)
|
||||
#define MSR_EFER_FFXSR (1 << 14)
|
||||
|
||||
#define MSR_EFER_RESERVED\
|
||||
(~(target_ulong)(MSR_EFER_SCE | MSR_EFER_LME\
|
||||
| MSR_EFER_LMA | MSR_EFER_NXE | MSR_EFER_SVME\
|
||||
| MSR_EFER_FFXSR))
|
||||
|
||||
#define MSR_STAR 0xc0000081
|
||||
#define MSR_LSTAR 0xc0000082
|
||||
#define MSR_CSTAR 0xc0000083
|
||||
|
@ -75,6 +75,41 @@ static inline bool ctl_has_irq(uint32_t int_ctl)
|
||||
return (int_ctl & V_IRQ_MASK) && (int_prio >= tpr);
|
||||
}
|
||||
|
||||
static inline bool is_efer_invalid_state (CPUX86State *env)
|
||||
{
|
||||
if (!(env->efer & MSR_EFER_SVME)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (env->efer & MSR_EFER_RESERVED) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((env->efer & (MSR_EFER_LMA | MSR_EFER_LME)) &&
|
||||
!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((env->efer & MSR_EFER_LME) && (env->cr[0] & CR0_PG_MASK)
|
||||
&& !(env->cr[4] & CR4_PAE_MASK)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((env->efer & MSR_EFER_LME) && (env->cr[0] & CR0_PG_MASK)
|
||||
&& !(env->cr[0] & CR0_PE_MASK)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((env->efer & MSR_EFER_LME) && (env->cr[0] & CR0_PG_MASK)
|
||||
&& (env->cr[4] & CR4_PAE_MASK)
|
||||
&& (env->segs[R_CS].flags & DESC_L_MASK)
|
||||
&& (env->segs[R_CS].flags & DESC_B_MASK)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
@ -291,6 +326,10 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (is_efer_invalid_state(env)) {
|
||||
cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
|
||||
}
|
||||
|
||||
switch (x86_ldub_phys(cs,
|
||||
env->vm_vmcb + offsetof(struct vmcb, control.tlb_ctl))) {
|
||||
case TLB_CONTROL_DO_NOTHING:
|
||||
|
Loading…
Reference in New Issue
Block a user