Revision 678dde13

b/cpu-exec.c
360 360
                                 env->exception_is_int, 
361 361
                                 env->error_code, 
362 362
                                 env->exception_next_eip, 0);
363
                    /* successfully delivered */
364
                    env->old_exception = -1;
363 365
#elif defined(TARGET_PPC)
364 366
                    do_interrupt(env);
365 367
#elif defined(TARGET_MIPS)
b/target-i386/cpu.h
515 515
    uint32_t smbase;
516 516
    int interrupt_request; 
517 517
    int user_mode_only; /* user mode only simulation */
518
    int old_exception;  /* exception in flight */
518 519

  
519 520
    CPU_COMMON
520 521

  
b/target-i386/helper.c
1193 1193
}
1194 1194

  
1195 1195
/*
1196
 * Check nested exceptions and change to double or triple fault if
1197
 * needed. It should only be called, if this is not an interrupt.
1198
 * Returns the new exception number.
1199
 */
1200
int check_exception(int intno, int *error_code)
1201
{
1202
    char first_contributory = env->old_exception == 0 ||
1203
                              (env->old_exception >= 10 &&
1204
                               env->old_exception <= 13);
1205
    char second_contributory = intno == 0 ||
1206
                               (intno >= 10 && intno <= 13);
1207

  
1208
    if (loglevel & CPU_LOG_INT)
1209
        fprintf(logfile, "check_exception old: %x new %x\n",
1210
                env->old_exception, intno);
1211

  
1212
    if (env->old_exception == EXCP08_DBLE)
1213
        cpu_abort(env, "triple fault");
1214

  
1215
    if ((first_contributory && second_contributory)
1216
        || (env->old_exception == EXCP0E_PAGE &&
1217
            (second_contributory || (intno == EXCP0E_PAGE)))) {
1218
        intno = EXCP08_DBLE;
1219
        *error_code = 0;
1220
    }
1221

  
1222
    if (second_contributory || (intno == EXCP0E_PAGE) ||
1223
        (intno == EXCP08_DBLE))
1224
        env->old_exception = intno;
1225

  
1226
    return intno;
1227
}
1228

  
1229
/*
1196 1230
 * Signal an interruption. It is executed in the main CPU loop.
1197 1231
 * is_int is TRUE if coming from the int instruction. next_eip is the
1198 1232
 * EIP value AFTER the interrupt instruction. It is only relevant if
......
1201 1235
void raise_interrupt(int intno, int is_int, int error_code, 
1202 1236
                     int next_eip_addend)
1203 1237
{
1238
    if (!is_int)
1239
        intno = check_exception(intno, &error_code);
1240

  
1204 1241
    env->exception_index = intno;
1205 1242
    env->error_code = error_code;
1206 1243
    env->exception_is_int = is_int;
......
1211 1248
/* same as raise_exception_err, but do not restore global registers */
1212 1249
static void raise_exception_err_norestore(int exception_index, int error_code)
1213 1250
{
1251
    exception_index = check_exception(exception_index, &error_code);
1252

  
1214 1253
    env->exception_index = exception_index;
1215 1254
    env->error_code = error_code;
1216 1255
    env->exception_is_int = 0;

Also available in: Unified diff