提交 5516d670 编写于 作者: B bellard

make lsl, lar verr and verw exception safe


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1369 c046a42c-6fe2-441c-8c8c-71466251a162
上级 cc6f538b
...@@ -2335,13 +2335,13 @@ void helper_rdmsr(void) ...@@ -2335,13 +2335,13 @@ void helper_rdmsr(void)
void helper_lsl(void) void helper_lsl(void)
{ {
unsigned int selector, limit; unsigned int selector, limit;
uint32_t e1, e2; uint32_t e1, e2, eflags;
int rpl, dpl, cpl, type; int rpl, dpl, cpl, type;
CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; eflags = cc_table[CC_OP].compute_all();
selector = T0 & 0xffff; selector = T0 & 0xffff;
if (load_segment(&e1, &e2, selector) != 0) if (load_segment(&e1, &e2, selector) != 0)
return; goto fail;
rpl = selector & 3; rpl = selector & 3;
dpl = (e2 >> DESC_DPL_SHIFT) & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3;
cpl = env->hflags & HF_CPL_MASK; cpl = env->hflags & HF_CPL_MASK;
...@@ -2350,7 +2350,7 @@ void helper_lsl(void) ...@@ -2350,7 +2350,7 @@ void helper_lsl(void)
/* conforming */ /* conforming */
} else { } else {
if (dpl < cpl || dpl < rpl) if (dpl < cpl || dpl < rpl)
return; goto fail;
} }
} else { } else {
type = (e2 >> DESC_TYPE_SHIFT) & 0xf; type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
...@@ -2362,28 +2362,31 @@ void helper_lsl(void) ...@@ -2362,28 +2362,31 @@ void helper_lsl(void)
case 11: case 11:
break; break;
default: default:
return; goto fail;
} }
if (dpl < cpl || dpl < rpl) if (dpl < cpl || dpl < rpl) {
fail:
CC_SRC = eflags & ~CC_Z;
return; return;
} }
}
limit = get_seg_limit(e1, e2); limit = get_seg_limit(e1, e2);
T1 = limit; T1 = limit;
CC_SRC |= CC_Z; CC_SRC = eflags | CC_Z;
} }
void helper_lar(void) void helper_lar(void)
{ {
unsigned int selector; unsigned int selector;
uint32_t e1, e2; uint32_t e1, e2, eflags;
int rpl, dpl, cpl, type; int rpl, dpl, cpl, type;
CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; eflags = cc_table[CC_OP].compute_all();
selector = T0 & 0xffff; selector = T0 & 0xffff;
if ((selector & 0xfffc) == 0) if ((selector & 0xfffc) == 0)
return; goto fail;
if (load_segment(&e1, &e2, selector) != 0) if (load_segment(&e1, &e2, selector) != 0)
return; goto fail;
rpl = selector & 3; rpl = selector & 3;
dpl = (e2 >> DESC_DPL_SHIFT) & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3;
cpl = env->hflags & HF_CPL_MASK; cpl = env->hflags & HF_CPL_MASK;
...@@ -2392,7 +2395,7 @@ void helper_lar(void) ...@@ -2392,7 +2395,7 @@ void helper_lar(void)
/* conforming */ /* conforming */
} else { } else {
if (dpl < cpl || dpl < rpl) if (dpl < cpl || dpl < rpl)
return; goto fail;
} }
} else { } else {
type = (e2 >> DESC_TYPE_SHIFT) & 0xf; type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
...@@ -2407,72 +2410,81 @@ void helper_lar(void) ...@@ -2407,72 +2410,81 @@ void helper_lar(void)
case 12: case 12:
break; break;
default: default:
return; goto fail;
} }
if (dpl < cpl || dpl < rpl) if (dpl < cpl || dpl < rpl) {
fail:
CC_SRC = eflags & ~CC_Z;
return; return;
} }
}
T1 = e2 & 0x00f0ff00; T1 = e2 & 0x00f0ff00;
CC_SRC |= CC_Z; CC_SRC = eflags | CC_Z;
} }
void helper_verr(void) void helper_verr(void)
{ {
unsigned int selector; unsigned int selector;
uint32_t e1, e2; uint32_t e1, e2, eflags;
int rpl, dpl, cpl; int rpl, dpl, cpl;
CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; eflags = cc_table[CC_OP].compute_all();
selector = T0 & 0xffff; selector = T0 & 0xffff;
if ((selector & 0xfffc) == 0) if ((selector & 0xfffc) == 0)
return; goto fail;
if (load_segment(&e1, &e2, selector) != 0) if (load_segment(&e1, &e2, selector) != 0)
return; goto fail;
if (!(e2 & DESC_S_MASK)) if (!(e2 & DESC_S_MASK))
return; goto fail;
rpl = selector & 3; rpl = selector & 3;
dpl = (e2 >> DESC_DPL_SHIFT) & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3;
cpl = env->hflags & HF_CPL_MASK; cpl = env->hflags & HF_CPL_MASK;
if (e2 & DESC_CS_MASK) { if (e2 & DESC_CS_MASK) {
if (!(e2 & DESC_R_MASK)) if (!(e2 & DESC_R_MASK))
return; goto fail;
if (!(e2 & DESC_C_MASK)) { if (!(e2 & DESC_C_MASK)) {
if (dpl < cpl || dpl < rpl) if (dpl < cpl || dpl < rpl)
return; goto fail;
} }
} else { } else {
if (dpl < cpl || dpl < rpl) if (dpl < cpl || dpl < rpl) {
fail:
CC_SRC = eflags & ~CC_Z;
return; return;
} }
CC_SRC |= CC_Z; }
CC_SRC = eflags | CC_Z;
} }
void helper_verw(void) void helper_verw(void)
{ {
unsigned int selector; unsigned int selector;
uint32_t e1, e2; uint32_t e1, e2, eflags;
int rpl, dpl, cpl; int rpl, dpl, cpl;
CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; eflags = cc_table[CC_OP].compute_all();
selector = T0 & 0xffff; selector = T0 & 0xffff;
if ((selector & 0xfffc) == 0) if ((selector & 0xfffc) == 0)
return; goto fail;
if (load_segment(&e1, &e2, selector) != 0) if (load_segment(&e1, &e2, selector) != 0)
return; goto fail;
if (!(e2 & DESC_S_MASK)) if (!(e2 & DESC_S_MASK))
return; goto fail;
rpl = selector & 3; rpl = selector & 3;
dpl = (e2 >> DESC_DPL_SHIFT) & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3;
cpl = env->hflags & HF_CPL_MASK; cpl = env->hflags & HF_CPL_MASK;
if (e2 & DESC_CS_MASK) { if (e2 & DESC_CS_MASK) {
return; goto fail;
} else { } else {
if (dpl < cpl || dpl < rpl) if (dpl < cpl || dpl < rpl)
goto fail;
if (!(e2 & DESC_W_MASK)) {
fail:
CC_SRC = eflags & ~CC_Z;
return; return;
if (!(e2 & DESC_W_MASK))
return;
} }
CC_SRC |= CC_Z; }
CC_SRC = eflags | CC_Z;
} }
/* FPU helpers */ /* FPU helpers */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册