target/i386: seg_helper: Correct segment selector nullification in the RET/IRET helper
Per the SDM, when returning to outer privilege level, for segment registers (ES, FS, GS, and DS) if the check fails, the segment selector becomes null, but QEMU clears the base/limit/flags as well as nullifying the segment selector, which should be a spec violation. Real hardware seems to be compliant with the spec, at least on one Coffee Lake board I tested. Signed-off-by: Bin Meng <bin.meng@windriver.com> Message-Id: <1605261378-77971-1-git-send-email-bmeng.cn@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
c1bb5418e3
commit
c2ba0515f2
|
@ -2108,7 +2108,10 @@ static inline void validate_seg(CPUX86State *env, int seg_reg, int cpl)
|
||||||
if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) {
|
if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) {
|
||||||
/* data or non conforming code segment */
|
/* data or non conforming code segment */
|
||||||
if (dpl < cpl) {
|
if (dpl < cpl) {
|
||||||
cpu_x86_load_seg_cache(env, seg_reg, 0, 0, 0, 0);
|
cpu_x86_load_seg_cache(env, seg_reg, 0,
|
||||||
|
env->segs[seg_reg].base,
|
||||||
|
env->segs[seg_reg].limit,
|
||||||
|
env->segs[seg_reg].flags & ~DESC_P_MASK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue