Revision 2ed51f5b target-i386/op_helper.c

b/target-i386/op_helper.c
595 595
        return 0xffff;
596 596
}
597 597

  
598
static int exeption_has_error_code(int intno)
599
{
600
        switch(intno) {
601
        case 8:
602
        case 10:
603
        case 11:
604
        case 12:
605
        case 13:
606
        case 14:
607
        case 17:
608
            return 1;
609
        }
610
	return 0;
611
}
612

  
598 613
#ifdef TARGET_X86_64
599 614
#define SET_ESP(val, sp_mask)\
600 615
do {\
......
650 665
    uint32_t old_eip, sp_mask;
651 666

  
652 667
    has_error_code = 0;
653
    if (!is_int && !is_hw) {
654
        switch(intno) {
655
        case 8:
656
        case 10:
657
        case 11:
658
        case 12:
659
        case 13:
660
        case 14:
661
        case 17:
662
            has_error_code = 1;
663
            break;
664
        }
665
    }
668
    if (!is_int && !is_hw)
669
        has_error_code = exeption_has_error_code(intno);
666 670
    if (is_int)
667 671
        old_eip = next_eip;
668 672
    else
......
886 890
    target_ulong old_eip, esp, offset;
887 891

  
888 892
    has_error_code = 0;
889
    if (!is_int && !is_hw) {
890
        switch(intno) {
891
        case 8:
892
        case 10:
893
        case 11:
894
        case 12:
895
        case 13:
896
        case 14:
897
        case 17:
898
            has_error_code = 1;
899
            break;
900
        }
901
    }
893
    if (!is_int && !is_hw)
894
        has_error_code = exeption_has_error_code(intno);
902 895
    if (is_int)
903 896
        old_eip = next_eip;
904 897
    else
......
1198 1191
        EIP = next_eip;
1199 1192
}
1200 1193

  
1194
static void handle_even_inj(int intno, int is_int, int error_code,
1195
		int is_hw, int rm)
1196
{
1197
    uint32_t event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj));
1198
    if (!(event_inj & SVM_EVTINJ_VALID)) {
1199
	    int type;
1200
	    if (is_int)
1201
		    type = SVM_EVTINJ_TYPE_SOFT;
1202
	    else
1203
		    type = SVM_EVTINJ_TYPE_EXEPT;
1204
	    event_inj = intno | type | SVM_EVTINJ_VALID;
1205
	    if (!rm && exeption_has_error_code(intno)) {
1206
		    event_inj |= SVM_EVTINJ_VALID_ERR;
1207
		    stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err), error_code);
1208
	    }
1209
	    stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj);
1210
    }
1211
}
1212

  
1201 1213
/*
1202 1214
 * Begin execution of an interruption. is_int is TRUE if coming from
1203 1215
 * the int instruction. next_eip is the EIP value AFTER the interrupt
......
1238 1250
        }
1239 1251
    }
1240 1252
    if (env->cr[0] & CR0_PE_MASK) {
1253
        if (env->hflags & HF_SVMI_MASK)
1254
            handle_even_inj(intno, is_int, error_code, is_hw, 0);
1241 1255
#ifdef TARGET_X86_64
1242 1256
        if (env->hflags & HF_LMA_MASK) {
1243 1257
            do_interrupt64(intno, is_int, error_code, next_eip, is_hw);
......
1247 1261
            do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw);
1248 1262
        }
1249 1263
    } else {
1264
        if (env->hflags & HF_SVMI_MASK)
1265
            handle_even_inj(intno, is_int, error_code, is_hw, 1);
1250 1266
        do_interrupt_real(intno, is_int, error_code, next_eip);
1251 1267
    }
1268

  
1269
    if (env->hflags & HF_SVMI_MASK) {
1270
	    uint32_t event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj));
1271
	    stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj & ~SVM_EVTINJ_VALID);
1272
    }
1252 1273
}
1253 1274

  
1254 1275
/* This should come from sysemu.h - if we could include it here... */
......
4994 5015
        uint8_t vector = event_inj & SVM_EVTINJ_VEC_MASK;
4995 5016
        uint16_t valid_err = event_inj & SVM_EVTINJ_VALID_ERR;
4996 5017
        uint32_t event_inj_err = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err));
4997
        stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj & ~SVM_EVTINJ_VALID);
4998 5018

  
4999 5019
        qemu_log_mask(CPU_LOG_TB_IN_ASM, "Injecting(%#hx): ", valid_err);
5000 5020
        /* FIXME: need to implement valid_err */
......
5332 5352
    stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_code), exit_code);
5333 5353
    stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_1), exit_info_1);
5334 5354

  
5355
    stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info),
5356
             ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj)));
5357
    stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info_err),
5358
             ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err)));
5359

  
5335 5360
    env->hflags2 &= ~HF2_GIF_MASK;
5336 5361
    /* FIXME: Resets the current ASID register to zero (host ASID). */
5337 5362

  

Also available in: Unified diff