Revision 023fe10d

b/target-i386/exec.h
167 167
void helper_idivl_EAX_T0(uint32_t eip);
168 168
void helper_cmpxchg8b(void);
169 169
void helper_cpuid(void);
170
void helper_sysenter(void);
171
void helper_sysexit(void);
170 172
void helper_rdtsc(void);
171 173
void helper_rdmsr(void);
172 174
void helper_wrmsr(void);
b/target-i386/helper.c
1746 1746
    helper_ret_protected(shift, 0, addend);
1747 1747
}
1748 1748

  
1749
void helper_sysenter(void)
1750
{
1751
    if (env->sysenter_cs == 0) {
1752
        raise_exception_err(EXCP0D_GPF, 0);
1753
    }
1754
    env->eflags &= ~(VM_MASK | IF_MASK | RF_MASK);
1755
    cpu_x86_set_cpl(env, 0);
1756
    cpu_x86_load_seg_cache(env, R_CS, env->sysenter_cs & 0xfffc, 
1757
                           NULL, 0xffffffff, 
1758
                           DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
1759
                           DESC_S_MASK |
1760
                           DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
1761
    cpu_x86_load_seg_cache(env, R_SS, (env->sysenter_cs + 8) & 0xfffc, 
1762
                           NULL, 0xffffffff,
1763
                           DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
1764
                           DESC_S_MASK |
1765
                           DESC_W_MASK | DESC_A_MASK);
1766
    ESP = env->sysenter_esp;
1767
    EIP = env->sysenter_eip;
1768
}
1769

  
1770
void helper_sysexit(void)
1771
{
1772
    int cpl;
1773

  
1774
    cpl = env->hflags & HF_CPL_MASK;
1775
    if (env->sysenter_cs == 0 || cpl != 0) {
1776
        raise_exception_err(EXCP0D_GPF, 0);
1777
    }
1778
    cpu_x86_set_cpl(env, 3);
1779
    cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 16) & 0xfffc) | 3, 
1780
                           NULL, 0xffffffff, 
1781
                           DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
1782
                           DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
1783
                           DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
1784
    cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 24) & 0xfffc) | 3, 
1785
                           NULL, 0xffffffff,
1786
                           DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
1787
                           DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
1788
                           DESC_W_MASK | DESC_A_MASK);
1789
    ESP = ECX;
1790
    EIP = EDX;
1791
}
1792

  
1749 1793
void helper_movl_crN_T0(int reg)
1750 1794
{
1751 1795
    switch(reg) {
b/target-i386/op.c
700 700
    helper_cpuid();
701 701
}
702 702

  
703
void OPPROTO op_sysenter(void)
704
{
705
    helper_sysenter();
706
}
707

  
708
void OPPROTO op_sysexit(void)
709
{
710
    helper_sysexit();
711
}
712

  
703 713
void OPPROTO op_rdmsr(void)
704 714
{
705 715
    helper_rdmsr();
b/target-i386/translate.c
2973 2973
            case 0x0a: /* grp d9/2 */
2974 2974
                switch(rm) {
2975 2975
                case 0: /* fnop */
2976
                    /* check exceptions (FreeBSD FPU probe) */
2977
                    if (s->cc_op != CC_OP_DYNAMIC)
2978
                        gen_op_set_cc_op(s->cc_op);
2979
                    gen_op_jmp_im(pc_start - s->cs_base);
2980
                    gen_op_fwait();
2976 2981
                    break;
2977 2982
                default:
2978 2983
                    goto illegal_op;
......
3881 3886
    case 0x131: /* rdtsc */
3882 3887
        gen_op_rdtsc();
3883 3888
        break;
3889
    case 0x134: /* sysenter */
3890
        if (!s->pe) {
3891
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3892
        } else {
3893
            if (s->cc_op != CC_OP_DYNAMIC) {
3894
                gen_op_set_cc_op(s->cc_op);
3895
                s->cc_op = CC_OP_DYNAMIC;
3896
            }
3897
            gen_op_jmp_im(pc_start - s->cs_base);
3898
            gen_op_sysenter();
3899
            gen_eob(s);
3900
        }
3901
        break;
3902
    case 0x135: /* sysexit */
3903
        if (!s->pe) {
3904
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3905
        } else {
3906
            if (s->cc_op != CC_OP_DYNAMIC) {
3907
                gen_op_set_cc_op(s->cc_op);
3908
                s->cc_op = CC_OP_DYNAMIC;
3909
            }
3910
            gen_op_jmp_im(pc_start - s->cs_base);
3911
            gen_op_sysexit();
3912
            gen_eob(s);
3913
        }
3914
        break;
3884 3915
    case 0x1a2: /* cpuid */
3885 3916
        gen_op_cpuid();
3886 3917
        break;

Also available in: Unified diff