Oh, almost forgot it, Peter, what about the version? Thanks!
在 2013-05-06一的 13:55 +0800,liguang写道: > for helper_{lsl, lar, verr, verw}, there are > common parts, so move them outside, and then > call this new helper-helper function. > > Signed-off-by: liguang <lig.f...@cn.fujitsu.com> > --- > v2: change misc_check_helper to privilege_check > --- > target-i386/seg_helper.c | 179 ++++++++++++++------------------------------- > 1 files changed, 56 insertions(+), 123 deletions(-) > > diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c > index ff93374..eb9dc04 100644 > --- a/target-i386/seg_helper.c > +++ b/target-i386/seg_helper.c > @@ -2288,9 +2288,10 @@ void helper_sysexit(CPUX86State *env, int dflag) > EIP = EDX; > } > > -target_ulong helper_lsl(CPUX86State *env, target_ulong selector1) > + > +static target_ulong privilege_check(CPUX86State *env, target_ulong selector1, > + int inst) > { > - unsigned int limit; > uint32_t e1, e2, eflags, selector; > int rpl, dpl, cpl, type; > > @@ -2302,14 +2303,30 @@ target_ulong helper_lsl(CPUX86State *env, > target_ulong selector1) > if (load_segment(env, &e1, &e2, selector) != 0) { > goto fail; > } > + > + CC_SRC = eflags & ~CC_Z; > + > rpl = selector & 3; > dpl = (e2 >> DESC_DPL_SHIFT) & 3; > cpl = env->hflags & HF_CPL_MASK; > + > if (e2 & DESC_S_MASK) { > - if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) { > - /* conforming */ > - } else { > - if (dpl < cpl || dpl < rpl) { > + if (e2 & DESC_CS_MASK) { > + switch (inst) { > + case 1: > + goto fail; > + case 2: > + if (!(e2 & (DESC_R_MASK | DESC_C_MASK))) { > + goto fail; > + } > + break; > + case 3: > + case 4: > + if (!(e2 & DESC_C_MASK)) { > + goto check_pl; > + } > + break; > + default: > goto fail; > } > } > @@ -2321,140 +2338,56 @@ target_ulong helper_lsl(CPUX86State *env, > target_ulong selector1) > case 3: > case 9: > case 11: > - break; > + if (inst == 3) { > + break; > + } > + case 5: > + case 12: > + if (inst == 4) { > + break; > + } > default: > goto fail; > } > - if (dpl < cpl || dpl < rpl) { > - fail: > - CC_SRC = eflags & ~CC_Z; > - return 0; > - } > + goto check_pl; > + } > + > + if (inst == 3) { > + e2 &= 0x00f0ff00; > } > - limit = get_seg_limit(e1, e2); > + if (inst == 4) { > + e2 = get_seg_limit(e1, e2); > + } > + > CC_SRC = eflags | CC_Z; > - return limit; > + > +check_pl: > + if (dpl < cpl || dpl < rpl) { > + goto fail; > + } > + > +fail: > + return e2; > } > > -target_ulong helper_lar(CPUX86State *env, target_ulong selector1) > +target_ulong helper_lsl(CPUX86State *env, target_ulong selector1) > { > - uint32_t e1, e2, eflags, selector; > - int rpl, dpl, cpl, type; > + return privilege_check(env, selector1, 4); > +} > > - selector = selector1 & 0xffff; > - eflags = cpu_cc_compute_all(env, CC_OP); > - if ((selector & 0xfffc) == 0) { > - goto fail; > - } > - if (load_segment(env, &e1, &e2, selector) != 0) { > - goto fail; > - } > - rpl = selector & 3; > - dpl = (e2 >> DESC_DPL_SHIFT) & 3; > - cpl = env->hflags & HF_CPL_MASK; > - if (e2 & DESC_S_MASK) { > - if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) { > - /* conforming */ > - } else { > - if (dpl < cpl || dpl < rpl) { > - goto fail; > - } > - } > - } else { > - type = (e2 >> DESC_TYPE_SHIFT) & 0xf; > - switch (type) { > - case 1: > - case 2: > - case 3: > - case 4: > - case 5: > - case 9: > - case 11: > - case 12: > - break; > - default: > - goto fail; > - } > - if (dpl < cpl || dpl < rpl) { > - fail: > - CC_SRC = eflags & ~CC_Z; > - return 0; > - } > - } > - CC_SRC = eflags | CC_Z; > - return e2 & 0x00f0ff00; > +target_ulong helper_lar(CPUX86State *env, target_ulong selector1) > +{ > + return privilege_check(env, selector1, 3); > } > > void helper_verr(CPUX86State *env, target_ulong selector1) > { > - uint32_t e1, e2, eflags, selector; > - int rpl, dpl, cpl; > - > - selector = selector1 & 0xffff; > - eflags = cpu_cc_compute_all(env, CC_OP); > - if ((selector & 0xfffc) == 0) { > - goto fail; > - } > - if (load_segment(env, &e1, &e2, selector) != 0) { > - goto fail; > - } > - if (!(e2 & DESC_S_MASK)) { > - 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)) { > - goto fail; > - } > - if (!(e2 & DESC_C_MASK)) { > - if (dpl < cpl || dpl < rpl) { > - goto fail; > - } > - } > - } else { > - if (dpl < cpl || dpl < rpl) { > - fail: > - CC_SRC = eflags & ~CC_Z; > - return; > - } > - } > - CC_SRC = eflags | CC_Z; > + privilege_check(env, selector1, 2); > } > > void helper_verw(CPUX86State *env, target_ulong selector1) > { > - uint32_t e1, e2, eflags, selector; > - int rpl, dpl, cpl; > - > - selector = selector1 & 0xffff; > - eflags = cpu_cc_compute_all(env, CC_OP); > - if ((selector & 0xfffc) == 0) { > - goto fail; > - } > - if (load_segment(env, &e1, &e2, selector) != 0) { > - goto fail; > - } > - if (!(e2 & DESC_S_MASK)) { > - goto fail; > - } > - rpl = selector & 3; > - dpl = (e2 >> DESC_DPL_SHIFT) & 3; > - cpl = env->hflags & HF_CPL_MASK; > - if (e2 & DESC_CS_MASK) { > - goto fail; > - } else { > - if (dpl < cpl || dpl < rpl) { > - goto fail; > - } > - if (!(e2 & DESC_W_MASK)) { > - fail: > - CC_SRC = eflags & ~CC_Z; > - return; > - } > - } > - CC_SRC = eflags | CC_Z; > + privilege_check(env, selector1, 1); > } > > #if defined(CONFIG_USER_ONLY)