Revision db620f46
b/cpu-exec.c | ||
---|---|---|
368 | 368 |
next_tb = 0; /* force lookup of first TB */ |
369 | 369 |
for(;;) { |
370 | 370 |
interrupt_request = env->interrupt_request; |
371 |
if (__builtin_expect(interrupt_request, 0) |
|
372 |
#if defined(TARGET_I386) |
|
373 |
&& env->hflags & HF_GIF_MASK |
|
374 |
#endif |
|
375 |
&& likely(!(env->singlestep_enabled & SSTEP_NOIRQ))) { |
|
371 |
if (__builtin_expect(interrupt_request, 0) && |
|
372 |
likely(!(env->singlestep_enabled & SSTEP_NOIRQ))) { |
|
376 | 373 |
if (interrupt_request & CPU_INTERRUPT_DEBUG) { |
377 | 374 |
env->interrupt_request &= ~CPU_INTERRUPT_DEBUG; |
378 | 375 |
env->exception_index = EXCP_DEBUG; |
... | ... | |
388 | 385 |
} |
389 | 386 |
#endif |
390 | 387 |
#if defined(TARGET_I386) |
391 |
if ((interrupt_request & CPU_INTERRUPT_SMI) && |
|
392 |
!(env->hflags & HF_SMM_MASK)) { |
|
393 |
svm_check_intercept(SVM_EXIT_SMI); |
|
394 |
env->interrupt_request &= ~CPU_INTERRUPT_SMI; |
|
395 |
do_smm_enter(); |
|
396 |
next_tb = 0; |
|
397 |
} else if ((interrupt_request & CPU_INTERRUPT_NMI) && |
|
398 |
!(env->hflags & HF_NMI_MASK)) { |
|
399 |
env->interrupt_request &= ~CPU_INTERRUPT_NMI; |
|
400 |
env->hflags |= HF_NMI_MASK; |
|
401 |
do_interrupt(EXCP02_NMI, 0, 0, 0, 1); |
|
402 |
next_tb = 0; |
|
403 |
} else if ((interrupt_request & CPU_INTERRUPT_HARD) && |
|
404 |
(env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) && |
|
405 |
!(env->hflags & HF_INHIBIT_IRQ_MASK)) { |
|
406 |
int intno; |
|
407 |
svm_check_intercept(SVM_EXIT_INTR); |
|
408 |
env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); |
|
409 |
intno = cpu_get_pic_interrupt(env); |
|
410 |
if (loglevel & CPU_LOG_TB_IN_ASM) { |
|
411 |
fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno); |
|
412 |
} |
|
413 |
do_interrupt(intno, 0, 0, 0, 1); |
|
414 |
/* ensure that no TB jump will be modified as |
|
415 |
the program flow was changed */ |
|
416 |
next_tb = 0; |
|
388 |
if (env->hflags2 & HF2_GIF_MASK) { |
|
389 |
if ((interrupt_request & CPU_INTERRUPT_SMI) && |
|
390 |
!(env->hflags & HF_SMM_MASK)) { |
|
391 |
svm_check_intercept(SVM_EXIT_SMI); |
|
392 |
env->interrupt_request &= ~CPU_INTERRUPT_SMI; |
|
393 |
do_smm_enter(); |
|
394 |
next_tb = 0; |
|
395 |
} else if ((interrupt_request & CPU_INTERRUPT_NMI) && |
|
396 |
!(env->hflags2 & HF2_NMI_MASK)) { |
|
397 |
env->interrupt_request &= ~CPU_INTERRUPT_NMI; |
|
398 |
env->hflags2 |= HF2_NMI_MASK; |
|
399 |
do_interrupt(EXCP02_NMI, 0, 0, 0, 1); |
|
400 |
next_tb = 0; |
|
401 |
} else if ((interrupt_request & CPU_INTERRUPT_HARD) && |
|
402 |
(((env->hflags2 & HF2_VINTR_MASK) && |
|
403 |
(env->hflags2 & HF2_HIF_MASK)) || |
|
404 |
(!(env->hflags2 & HF2_VINTR_MASK) && |
|
405 |
(env->eflags & IF_MASK && |
|
406 |
!(env->hflags & HF_INHIBIT_IRQ_MASK))))) { |
|
407 |
int intno; |
|
408 |
svm_check_intercept(SVM_EXIT_INTR); |
|
409 |
env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); |
|
410 |
intno = cpu_get_pic_interrupt(env); |
|
411 |
if (loglevel & CPU_LOG_TB_IN_ASM) { |
|
412 |
fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno); |
|
413 |
} |
|
414 |
do_interrupt(intno, 0, 0, 0, 1); |
|
415 |
/* ensure that no TB jump will be modified as |
|
416 |
the program flow was changed */ |
|
417 |
next_tb = 0; |
|
417 | 418 |
#if !defined(CONFIG_USER_ONLY) |
418 |
} else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && |
|
419 |
(env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) { |
|
420 |
int intno; |
|
421 |
/* FIXME: this should respect TPR */ |
|
422 |
env->interrupt_request &= ~CPU_INTERRUPT_VIRQ; |
|
423 |
svm_check_intercept(SVM_EXIT_VINTR); |
|
424 |
intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); |
|
425 |
if (loglevel & CPU_LOG_TB_IN_ASM) |
|
426 |
fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno); |
|
427 |
do_interrupt(intno, 0, 0, -1, 1); |
|
428 |
stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), |
|
429 |
ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK); |
|
430 |
next_tb = 0; |
|
419 |
} else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && |
|
420 |
(env->eflags & IF_MASK) && |
|
421 |
!(env->hflags & HF_INHIBIT_IRQ_MASK)) { |
|
422 |
int intno; |
|
423 |
/* FIXME: this should respect TPR */ |
|
424 |
svm_check_intercept(SVM_EXIT_VINTR); |
|
425 |
env->interrupt_request &= ~CPU_INTERRUPT_VIRQ; |
|
426 |
intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); |
|
427 |
if (loglevel & CPU_LOG_TB_IN_ASM) |
|
428 |
fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno); |
|
429 |
do_interrupt(intno, 0, 0, 0, 1); |
|
430 |
next_tb = 0; |
|
431 | 431 |
#endif |
432 |
} |
|
432 | 433 |
} |
433 | 434 |
#elif defined(TARGET_PPC) |
434 | 435 |
#if 0 |
b/target-i386/cpu.h | ||
---|---|---|
145 | 145 |
#define HF_OSFXSR_SHIFT 16 /* CR4.OSFXSR */ |
146 | 146 |
#define HF_VM_SHIFT 17 /* must be same as eflags */ |
147 | 147 |
#define HF_SMM_SHIFT 19 /* CPU in SMM mode */ |
148 |
#define HF_GIF_SHIFT 20 /* if set CPU takes interrupts */ |
|
149 |
#define HF_HIF_SHIFT 21 /* shadow copy of IF_MASK when in SVM */ |
|
150 |
#define HF_NMI_SHIFT 22 /* CPU serving NMI */ |
|
151 |
#define HF_SVME_SHIFT 23 /* SVME enabled (copy of EFER.SVME) */ |
|
152 |
#define HF_SVMI_SHIFT 24 /* SVM intercepts are active */ |
|
148 |
#define HF_SVME_SHIFT 20 /* SVME enabled (copy of EFER.SVME) */ |
|
149 |
#define HF_SVMI_SHIFT 21 /* SVM intercepts are active */ |
|
153 | 150 |
|
154 | 151 |
#define HF_CPL_MASK (3 << HF_CPL_SHIFT) |
155 | 152 |
#define HF_SOFTMMU_MASK (1 << HF_SOFTMMU_SHIFT) |
... | ... | |
166 | 163 |
#define HF_CS64_MASK (1 << HF_CS64_SHIFT) |
167 | 164 |
#define HF_OSFXSR_MASK (1 << HF_OSFXSR_SHIFT) |
168 | 165 |
#define HF_SMM_MASK (1 << HF_SMM_SHIFT) |
169 |
#define HF_GIF_MASK (1 << HF_GIF_SHIFT) |
|
170 |
#define HF_HIF_MASK (1 << HF_HIF_SHIFT) |
|
171 |
#define HF_NMI_MASK (1 << HF_NMI_SHIFT) |
|
172 | 166 |
#define HF_SVME_MASK (1 << HF_SVME_SHIFT) |
173 | 167 |
#define HF_SVMI_MASK (1 << HF_SVMI_SHIFT) |
174 | 168 |
|
169 |
/* hflags2 */ |
|
170 |
|
|
171 |
#define HF2_GIF_SHIFT 0 /* if set CPU takes interrupts */ |
|
172 |
#define HF2_HIF_SHIFT 1 /* value of IF_MASK when entering SVM */ |
|
173 |
#define HF2_NMI_SHIFT 2 /* CPU serving NMI */ |
|
174 |
#define HF2_VINTR_SHIFT 3 /* value of V_INTR_MASKING bit */ |
|
175 |
|
|
176 |
#define HF2_GIF_MASK (1 << HF2_GIF_SHIFT) |
|
177 |
#define HF2_HIF_MASK (1 << HF2_HIF_SHIFT) |
|
178 |
#define HF2_NMI_MASK (1 << HF2_NMI_SHIFT) |
|
179 |
#define HF2_VINTR_MASK (1 << HF2_VINTR_SHIFT) |
|
180 |
|
|
175 | 181 |
#define CR0_PE_MASK (1 << 0) |
176 | 182 |
#define CR0_MP_MASK (1 << 1) |
177 | 183 |
#define CR0_EM_MASK (1 << 2) |
... | ... | |
488 | 494 |
target_ulong cc_dst; |
489 | 495 |
uint32_t cc_op; |
490 | 496 |
int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */ |
491 |
uint32_t hflags; /* hidden flags, see HF_xxx constants */ |
|
497 |
uint32_t hflags; /* TB flags, see HF_xxx constants. These flags |
|
498 |
are known at translation time. */ |
|
499 |
uint32_t hflags2; /* various other flags, see HF2_xxx constants. */ |
|
492 | 500 |
|
493 | 501 |
/* segments */ |
494 | 502 |
SegmentCache segs[6]; /* selector values */ |
... | ... | |
497 | 505 |
SegmentCache gdt; /* only base and limit are used */ |
498 | 506 |
SegmentCache idt; /* only base and limit are used */ |
499 | 507 |
|
500 |
target_ulong cr[9]; /* NOTE: cr1, cr5-7 are unused */
|
|
508 |
target_ulong cr[5]; /* NOTE: cr1 is unused */
|
|
501 | 509 |
uint64_t a20_mask; |
502 | 510 |
|
503 | 511 |
/* FPU state */ |
... | ... | |
541 | 549 |
uint16_t intercept_dr_read; |
542 | 550 |
uint16_t intercept_dr_write; |
543 | 551 |
uint32_t intercept_exceptions; |
552 |
uint8_t v_tpr; |
|
544 | 553 |
|
545 | 554 |
#ifdef TARGET_X86_64 |
546 | 555 |
target_ulong lstar; |
b/target-i386/helper.c | ||
---|---|---|
374 | 374 |
#ifdef CONFIG_SOFTMMU |
375 | 375 |
env->hflags |= HF_SOFTMMU_MASK; |
376 | 376 |
#endif |
377 |
env->hflags |= HF_GIF_MASK;
|
|
377 |
env->hflags2 |= HF2_GIF_MASK;
|
|
378 | 378 |
|
379 | 379 |
cpu_x86_update_cr0(env, 0x60000010); |
380 | 380 |
env->a20_mask = ~0x0; |
b/target-i386/helper.h | ||
---|---|---|
47 | 47 |
DEF_HELPER(void, helper_write_crN, (int reg, target_ulong t0)) |
48 | 48 |
DEF_HELPER(void, helper_lmsw, (target_ulong t0)) |
49 | 49 |
DEF_HELPER(void, helper_clts, (void)) |
50 |
#if !defined(CONFIG_USER_ONLY) |
|
51 |
DEF_HELPER(target_ulong, helper_movtl_T0_cr8, (void)) |
|
52 |
#endif |
|
53 | 50 |
DEF_HELPER(void, helper_movl_drN_T0, (int reg, target_ulong t0)) |
54 | 51 |
DEF_HELPER(void, helper_invlpg, (target_ulong addr)) |
55 | 52 |
|
... | ... | |
102 | 99 |
DEF_HELPER(void, helper_vmexit, (uint32_t exit_code, uint64_t exit_info_1)) |
103 | 100 |
DEF_HELPER(void, helper_svm_check_io, (uint32_t port, uint32_t param, |
104 | 101 |
uint32_t next_eip_addend)) |
105 |
DEF_HELPER(void, helper_vmrun, (int aflag)) |
|
102 |
DEF_HELPER(void, helper_vmrun, (int aflag, int next_eip_addend))
|
|
106 | 103 |
DEF_HELPER(void, helper_vmmcall, (void)) |
107 | 104 |
DEF_HELPER(void, helper_vmload, (int aflag)) |
108 | 105 |
DEF_HELPER(void, helper_vmsave, (int aflag)) |
b/target-i386/op_helper.c | ||
---|---|---|
2591 | 2591 |
if (shift == 0) |
2592 | 2592 |
eflags_mask &= 0xffff; |
2593 | 2593 |
load_eflags(new_eflags, eflags_mask); |
2594 |
env->hflags &= ~HF_NMI_MASK;
|
|
2594 |
env->hflags2 &= ~HF2_NMI_MASK;
|
|
2595 | 2595 |
} |
2596 | 2596 |
|
2597 | 2597 |
static inline void validate_seg(int seg_reg, int cpl) |
... | ... | |
2843 | 2843 |
} else { |
2844 | 2844 |
helper_ret_protected(shift, 1, 0); |
2845 | 2845 |
} |
2846 |
env->hflags &= ~HF_NMI_MASK;
|
|
2846 |
env->hflags2 &= ~HF2_NMI_MASK;
|
|
2847 | 2847 |
#ifdef USE_KQEMU |
2848 | 2848 |
if (kqemu_is_ok(env)) { |
2849 | 2849 |
CC_OP = CC_OP_EFLAGS; |
... | ... | |
2934 | 2934 |
val = env->cr[reg]; |
2935 | 2935 |
break; |
2936 | 2936 |
case 8: |
2937 |
val = cpu_get_apic_tpr(env); |
|
2937 |
if (!(env->hflags2 & HF2_VINTR_MASK)) { |
|
2938 |
val = cpu_get_apic_tpr(env); |
|
2939 |
} else { |
|
2940 |
val = env->v_tpr; |
|
2941 |
} |
|
2938 | 2942 |
break; |
2939 | 2943 |
} |
2940 | 2944 |
return val; |
... | ... | |
2954 | 2958 |
cpu_x86_update_cr4(env, t0); |
2955 | 2959 |
break; |
2956 | 2960 |
case 8: |
2957 |
cpu_set_apic_tpr(env, t0); |
|
2958 |
env->cr[8] = t0; |
|
2961 |
if (!(env->hflags2 & HF2_VINTR_MASK)) { |
|
2962 |
cpu_set_apic_tpr(env, t0); |
|
2963 |
} |
|
2964 |
env->v_tpr = t0 & 0x0f; |
|
2959 | 2965 |
break; |
2960 | 2966 |
default: |
2961 | 2967 |
env->cr[reg] = t0; |
... | ... | |
2978 | 2984 |
env->hflags &= ~HF_TS_MASK; |
2979 | 2985 |
} |
2980 | 2986 |
|
2981 |
#if !defined(CONFIG_USER_ONLY) |
|
2982 |
target_ulong helper_movtl_T0_cr8(void) |
|
2983 |
{ |
|
2984 |
return cpu_get_apic_tpr(env); |
|
2985 |
} |
|
2986 |
#endif |
|
2987 |
|
|
2988 | 2987 |
/* XXX: do more */ |
2989 | 2988 |
void helper_movl_drN_T0(int reg, target_ulong t0) |
2990 | 2989 |
{ |
... | ... | |
4721 | 4720 |
|
4722 | 4721 |
#if defined(CONFIG_USER_ONLY) |
4723 | 4722 |
|
4724 |
void helper_vmrun(int aflag) |
|
4723 |
void helper_vmrun(int aflag, int next_eip_addend)
|
|
4725 | 4724 |
{ |
4726 | 4725 |
} |
4727 | 4726 |
void helper_vmmcall(void) |
... | ... | |
4791 | 4790 |
sc->base, sc->limit, sc->flags); |
4792 | 4791 |
} |
4793 | 4792 |
|
4794 |
void helper_vmrun(int aflag) |
|
4793 |
void helper_vmrun(int aflag, int next_eip_addend)
|
|
4795 | 4794 |
{ |
4796 | 4795 |
target_ulong addr; |
4797 | 4796 |
uint32_t event_inj; |
... | ... | |
4820 | 4819 |
stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr2), env->cr[2]); |
4821 | 4820 |
stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr3), env->cr[3]); |
4822 | 4821 |
stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr4), env->cr[4]); |
4823 |
stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr8), env->cr[8]); |
|
4824 | 4822 |
stq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr6), env->dr[6]); |
4825 | 4823 |
stq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr7), env->dr[7]); |
4826 | 4824 |
|
... | ... | |
4836 | 4834 |
svm_save_seg(env->vm_hsave + offsetof(struct vmcb, save.ds), |
4837 | 4835 |
&env->segs[R_DS]); |
4838 | 4836 |
|
4839 |
stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip), EIP); |
|
4837 |
stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip), |
|
4838 |
EIP + next_eip_addend); |
|
4840 | 4839 |
stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp), ESP); |
4841 | 4840 |
stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax), EAX); |
4842 | 4841 |
|
... | ... | |
4866 | 4865 |
cpu_x86_update_cr3(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr3))); |
4867 | 4866 |
env->cr[2] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr2)); |
4868 | 4867 |
int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)); |
4868 |
env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK); |
|
4869 | 4869 |
if (int_ctl & V_INTR_MASKING_MASK) { |
4870 |
env->cr[8] = int_ctl & V_TPR_MASK;
|
|
4871 |
cpu_set_apic_tpr(env, env->cr[8]);
|
|
4870 |
env->v_tpr = int_ctl & V_TPR_MASK;
|
|
4871 |
env->hflags2 |= HF2_VINTR_MASK;
|
|
4872 | 4872 |
if (env->eflags & IF_MASK) |
4873 |
env->hflags |= HF_HIF_MASK;
|
|
4873 |
env->hflags2 |= HF2_HIF_MASK;
|
|
4874 | 4874 |
} |
4875 | 4875 |
|
4876 |
#ifdef TARGET_X86_64 |
|
4877 | 4876 |
cpu_load_efer(env, |
4878 | 4877 |
ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.efer))); |
4879 |
#endif |
|
4880 | 4878 |
env->eflags = 0; |
4881 | 4879 |
load_eflags(ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags)), |
4882 | 4880 |
~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); |
... | ... | |
4912 | 4910 |
|
4913 | 4911 |
helper_stgi(); |
4914 | 4912 |
|
4913 |
if (int_ctl & V_IRQ_MASK) { |
|
4914 |
env->interrupt_request |= CPU_INTERRUPT_VIRQ; |
|
4915 |
} |
|
4916 |
|
|
4915 | 4917 |
/* maybe we need to inject an event */ |
4916 | 4918 |
event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj)); |
4917 | 4919 |
if (event_inj & SVM_EVTINJ_VALID) { |
... | ... | |
4931 | 4933 |
env->exception_next_eip = -1; |
4932 | 4934 |
if (loglevel & CPU_LOG_TB_IN_ASM) |
4933 | 4935 |
fprintf(logfile, "INTR"); |
4936 |
/* XXX: is it always correct ? */ |
|
4937 |
do_interrupt(vector, 0, 0, 0, 1); |
|
4934 | 4938 |
break; |
4935 | 4939 |
case SVM_EVTINJ_TYPE_NMI: |
4936 |
env->exception_index = vector;
|
|
4940 |
env->exception_index = EXCP02_NMI;
|
|
4937 | 4941 |
env->error_code = event_inj_err; |
4938 | 4942 |
env->exception_is_int = 0; |
4939 | 4943 |
env->exception_next_eip = EIP; |
4940 | 4944 |
if (loglevel & CPU_LOG_TB_IN_ASM) |
4941 | 4945 |
fprintf(logfile, "NMI"); |
4946 |
cpu_loop_exit(); |
|
4942 | 4947 |
break; |
4943 | 4948 |
case SVM_EVTINJ_TYPE_EXEPT: |
4944 | 4949 |
env->exception_index = vector; |
... | ... | |
4947 | 4952 |
env->exception_next_eip = -1; |
4948 | 4953 |
if (loglevel & CPU_LOG_TB_IN_ASM) |
4949 | 4954 |
fprintf(logfile, "EXEPT"); |
4955 |
cpu_loop_exit(); |
|
4950 | 4956 |
break; |
4951 | 4957 |
case SVM_EVTINJ_TYPE_SOFT: |
4952 | 4958 |
env->exception_index = vector; |
... | ... | |
4955 | 4961 |
env->exception_next_eip = EIP; |
4956 | 4962 |
if (loglevel & CPU_LOG_TB_IN_ASM) |
4957 | 4963 |
fprintf(logfile, "SOFT"); |
4964 |
cpu_loop_exit(); |
|
4958 | 4965 |
break; |
4959 | 4966 |
} |
4960 | 4967 |
if (loglevel & CPU_LOG_TB_IN_ASM) |
4961 | 4968 |
fprintf(logfile, " %#x %#x\n", env->exception_index, env->error_code); |
4962 | 4969 |
} |
4963 |
if ((int_ctl & V_IRQ_MASK) || |
|
4964 |
(env->intercept & (1ULL << (SVM_EXIT_INTR - SVM_EXIT_INTR)))) { |
|
4965 |
env->interrupt_request |= CPU_INTERRUPT_VIRQ; |
|
4966 |
} |
|
4967 |
|
|
4968 |
cpu_loop_exit(); |
|
4969 | 4970 |
} |
4970 | 4971 |
|
4971 | 4972 |
void helper_vmmcall(void) |
... | ... | |
5049 | 5050 |
void helper_stgi(void) |
5050 | 5051 |
{ |
5051 | 5052 |
helper_svm_check_intercept_param(SVM_EXIT_STGI, 0); |
5052 |
env->hflags |= HF_GIF_MASK;
|
|
5053 |
env->hflags2 |= HF2_GIF_MASK;
|
|
5053 | 5054 |
} |
5054 | 5055 |
|
5055 | 5056 |
void helper_clgi(void) |
5056 | 5057 |
{ |
5057 | 5058 |
helper_svm_check_intercept_param(SVM_EXIT_CLGI, 0); |
5058 |
env->hflags &= ~HF_GIF_MASK;
|
|
5059 |
env->hflags2 &= ~HF2_GIF_MASK;
|
|
5059 | 5060 |
} |
5060 | 5061 |
|
5061 | 5062 |
void helper_skinit(void) |
... | ... | |
5204 | 5205 |
stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr3), env->cr[3]); |
5205 | 5206 |
stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr4), env->cr[4]); |
5206 | 5207 |
|
5207 |
if ((int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl))) & V_INTR_MASKING_MASK) { |
|
5208 |
int_ctl &= ~V_TPR_MASK; |
|
5209 |
int_ctl |= env->cr[8] & V_TPR_MASK; |
|
5210 |
stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), int_ctl); |
|
5211 |
} |
|
5208 |
int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)); |
|
5209 |
int_ctl &= ~(V_TPR_MASK | V_IRQ_MASK); |
|
5210 |
int_ctl |= env->v_tpr & V_TPR_MASK; |
|
5211 |
if (env->interrupt_request & CPU_INTERRUPT_VIRQ) |
|
5212 |
int_ctl |= V_IRQ_MASK; |
|
5213 |
stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), int_ctl); |
|
5212 | 5214 |
|
5213 | 5215 |
stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags), compute_eflags()); |
5214 | 5216 |
stq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip), env->eip); |
... | ... | |
5219 | 5221 |
stb_phys(env->vm_vmcb + offsetof(struct vmcb, save.cpl), env->hflags & HF_CPL_MASK); |
5220 | 5222 |
|
5221 | 5223 |
/* Reload the host state from vm_hsave */ |
5222 |
env->hflags &= ~HF_HIF_MASK;
|
|
5224 |
env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK);
|
|
5223 | 5225 |
env->hflags &= ~HF_SVMI_MASK; |
5224 | 5226 |
env->intercept = 0; |
5225 | 5227 |
env->intercept_exceptions = 0; |
... | ... | |
5234 | 5236 |
cpu_x86_update_cr0(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr0)) | CR0_PE_MASK); |
5235 | 5237 |
cpu_x86_update_cr4(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr4))); |
5236 | 5238 |
cpu_x86_update_cr3(env, ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr3))); |
5237 |
if (int_ctl & V_INTR_MASKING_MASK) { |
|
5238 |
env->cr[8] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr8)); |
|
5239 |
cpu_set_apic_tpr(env, env->cr[8]); |
|
5240 |
} |
|
5241 | 5239 |
/* we need to set the efer after the crs so the hidden flags get |
5242 | 5240 |
set properly */ |
5243 |
#ifdef TARGET_X86_64 |
|
5244 | 5241 |
cpu_load_efer(env, |
5245 | 5242 |
ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.efer))); |
5246 |
#endif |
|
5247 |
|
|
5248 | 5243 |
env->eflags = 0; |
5249 | 5244 |
load_eflags(ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.rflags)), |
5250 | 5245 |
~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); |
b/target-i386/svm.h | ||
---|---|---|
205 | 205 |
uint64_t sysenter_esp; |
206 | 206 |
uint64_t sysenter_eip; |
207 | 207 |
uint64_t cr2; |
208 |
/* qemu: cr8 added to reuse this as hsave */ |
|
209 |
uint64_t cr8; |
|
210 |
uint8_t reserved_6[32 - 8]; /* originally 32 */ |
|
208 |
uint8_t reserved_6[32]; |
|
211 | 209 |
uint64_t g_pat; |
212 | 210 |
uint64_t dbgctl; |
213 | 211 |
uint64_t br_from; |
b/target-i386/translate.c | ||
---|---|---|
6569 | 6569 |
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); |
6570 | 6570 |
break; |
6571 | 6571 |
} else { |
6572 |
tcg_gen_helper_0_1(helper_vmrun, |
|
6573 |
tcg_const_i32(s->aflag)); |
|
6574 |
s->cc_op = CC_OP_EFLAGS; |
|
6575 |
gen_eob(s); |
|
6572 |
tcg_gen_helper_0_2(helper_vmrun, |
|
6573 |
tcg_const_i32(s->aflag), |
|
6574 |
tcg_const_i32(s->pc - pc_start)); |
|
6575 |
tcg_gen_exit_tb(0); |
|
6576 |
s->is_jmp = 3; |
|
6576 | 6577 |
} |
6577 | 6578 |
break; |
6578 | 6579 |
case 1: /* VMMCALL */ |
Also available in: Unified diff