diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2005-04-17 19:50:21 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2005-04-17 19:50:21 +0000 |
commit | 5516d670f69dafc77c936a02ff9916a9fba9fcd0 (patch) | |
tree | a8813cd3afae0c753dd52838d133f74b42b6a837 /target-i386 | |
parent | cc6f538bf6768cec1383c72e864f547ad9f04e30 (diff) |
make lsl, lar verr and verw exception safe
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1369 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-i386')
-rw-r--r-- | target-i386/helper.c | 78 |
1 files changed, 45 insertions, 33 deletions
diff --git a/target-i386/helper.c b/target-i386/helper.c index b358c2ecfe..2c852090aa 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -2335,13 +2335,13 @@ void helper_rdmsr(void) void helper_lsl(void) { unsigned int selector, limit; - uint32_t e1, e2; + uint32_t e1, e2, eflags; 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; if (load_segment(&e1, &e2, selector) != 0) - return; + goto fail; rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; @@ -2350,7 +2350,7 @@ void helper_lsl(void) /* conforming */ } else { if (dpl < cpl || dpl < rpl) - return; + goto fail; } } else { type = (e2 >> DESC_TYPE_SHIFT) & 0xf; @@ -2362,28 +2362,31 @@ void helper_lsl(void) case 11: break; default: - return; + goto fail; } - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { + fail: + CC_SRC = eflags & ~CC_Z; return; + } } limit = get_seg_limit(e1, e2); T1 = limit; - CC_SRC |= CC_Z; + CC_SRC = eflags | CC_Z; } void helper_lar(void) { unsigned int selector; - uint32_t e1, e2; + uint32_t e1, e2, eflags; 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; if ((selector & 0xfffc) == 0) - return; + goto fail; if (load_segment(&e1, &e2, selector) != 0) - return; + goto fail; rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; @@ -2392,7 +2395,7 @@ void helper_lar(void) /* conforming */ } else { if (dpl < cpl || dpl < rpl) - return; + goto fail; } } else { type = (e2 >> DESC_TYPE_SHIFT) & 0xf; @@ -2407,72 +2410,81 @@ void helper_lar(void) case 12: break; default: - return; + goto fail; } - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { + fail: + CC_SRC = eflags & ~CC_Z; return; + } } T1 = e2 & 0x00f0ff00; - CC_SRC |= CC_Z; + CC_SRC = eflags | CC_Z; } void helper_verr(void) { unsigned int selector; - uint32_t e1, e2; + uint32_t e1, e2, eflags; int rpl, dpl, cpl; - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; + eflags = cc_table[CC_OP].compute_all(); selector = T0 & 0xffff; if ((selector & 0xfffc) == 0) - return; + goto fail; if (load_segment(&e1, &e2, selector) != 0) - return; + goto fail; if (!(e2 & DESC_S_MASK)) - return; + goto fail; rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; if (e2 & DESC_CS_MASK) { if (!(e2 & DESC_R_MASK)) - return; + goto fail; if (!(e2 & DESC_C_MASK)) { if (dpl < cpl || dpl < rpl) - return; + goto fail; } } else { - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { + fail: + CC_SRC = eflags & ~CC_Z; return; + } } - CC_SRC |= CC_Z; + CC_SRC = eflags | CC_Z; } void helper_verw(void) { unsigned int selector; - uint32_t e1, e2; + uint32_t e1, e2, eflags; int rpl, dpl, cpl; - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; + eflags = cc_table[CC_OP].compute_all(); selector = T0 & 0xffff; if ((selector & 0xfffc) == 0) - return; + goto fail; if (load_segment(&e1, &e2, selector) != 0) - return; + goto fail; if (!(e2 & DESC_S_MASK)) - return; + goto fail; rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; if (e2 & DESC_CS_MASK) { - return; + goto fail; } else { if (dpl < cpl || dpl < rpl) + goto fail; + if (!(e2 & DESC_W_MASK)) { + fail: + CC_SRC = eflags & ~CC_Z; return; - if (!(e2 & DESC_W_MASK)) - return; + } } - CC_SRC |= CC_Z; + CC_SRC = eflags | CC_Z; } /* FPU helpers */ |