SYSENTER/SYSEXIT IA-32e implementation v4
PATCH 3/3 SYSENTER/SYSEXIT IA-32e implementation v4
On Intel CPUs, sysenter and sysexit are valid in 64-bit mode. This patch makes both 64-bit aware and enables them for Intel CPUs.
Changes since v1: Add cpu save/load for 64-bit wide sysenter variables Changes since v3: Use betls instead of bels
Signed-off-by Alexander Graf <[email protected]>
target-i386/cpu.h +3 -3
@@ -549,8 +549,8 @@ typedef struct CPUX86State {/* sysenter registers */ uint32_t sysenter_cs; -uint32_t sysenter_esp; -uint32_t sysenter_eip; +target_ulong sysenter_esp; +target_ulong sysenter_eip;uint64_t efer;uint64_t star;
@@ -737,7 +737,7 @@ static inline int cpu_get_time_fast(void#define cpu_signal_handler cpu_x86_signal_handler#define cpu_list x86_cpu_list -#define CPU_SAVE_VERSION 6 +#define CPU_SAVE_VERSION 7/* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel
target-i386/helper.h +1 -1
@@ -55,7 +55,7 @@ DEF_HELPER(void, helper_enter_level, (in DEF_HELPER(void, helper_enter64_level, (int level, int data64, target_ulong t1))#endif DEF_HELPER(void, helper_sysenter, (void)) -DEF_HELPER(void, helper_sysexit, (void)) +DEF_HELPER(void, helper_sysexit, (int dflag)) #ifdef TARGET_X86_64 DEF_HELPER(void, helper_syscall, (int next_eip_addend)) DEF_HELPER(void, helper_sysret, (int dflag))
target-i386/op_helper.c +44 -16
78 lines not on this page · raw message
target-i386/translate.c +5 -3
@@ -6401,7 +6401,8 @@ static target_ulong disas_insn(DisasConttcg_gen_helper_0_0 (helper_rdpmc);break ;case 0x134 :/* sysenter */ -if (CODE64 (s)) +/* For Intel SYSENTER is valid on 64-bit */ +if (CODE64 (s) && cpu_single_env->cpuid_vendor1 !=CPUID_VENDOR_INTEL_1 ) goto illegal_op;if (!s->pe) {gen_exception (s,EXCP0D_GPF , pc_start - s->cs_base);
@@ -6416,7 +6417,8 @@ static target_ulong disas_insn(DisasCont }break ;case 0x135 :/* sysexit */ -if (CODE64 (s)) +/* For Intel SYSEXIT is valid on 64-bit */ +if (CODE64 (s) && cpu_single_env->cpuid_vendor1 !=CPUID_VENDOR_INTEL_1 ) goto illegal_op;if (!s->pe) {gen_exception (s,EXCP0D_GPF , pc_start - s->cs_base);
@@ -6426,7 +6428,7 @@ static target_ulong disas_insn(DisasCont s->cc_op =CC_OP_DYNAMIC ; }gen_jmp_im (pc_start - s->cs_base); -tcg_gen_helper_0_0 (helper_sysexit); +tcg_gen_helper_0_1 (helper_sysexit,tcg_const_i32 (dflag));gen_eob (s); }break ;
target-i386/machine.c +11 -6
@@ -88,9 +88,9 @@ void cpu_save(QEMUFile *f, void *opaque)cpu_put_seg (f, &env->gdt);cpu_put_seg (f, &env->idt); -qemu_put_be32s (f, &env->sysenter_cs); -qemu_put_be32s (f, &env->sysenter_esp); -qemu_put_be32s (f, &env->sysenter_eip); +qemu_put_betls (f, &env->sysenter_cs); +qemu_put_betls (f, &env->sysenter_esp); +qemu_put_betls (f, &env->sysenter_eip);qemu_put_betls (f, &env->cr[0 ]);qemu_put_betls (f, &env->cr[2 ]);
@@ -169,7 +169,7 @@ int cpu_load(QEMUFile *f, void *opaque,int32_t a20_mask;if (version_id !=3 && version_id !=4 && version_id !=5 - && version_id !=6 ) + && version_id !=6 && version_id !=7 )return -EINVAL ;for (i =0 ; i <CPU_NB_REGS ; i++)qemu_get_betls (f, &env->regs[i]);
@@ -244,8 +244,13 @@ int cpu_load(QEMUFile *f, void *opaque,cpu_get_seg (f, &env->idt);qemu_get_be32s (f, &env->sysenter_cs); -qemu_get_be32s (f, &env->sysenter_esp); -qemu_get_be32s (f, &env->sysenter_eip); +if (version_id >=7 ) { +qemu_get_betls (f, &env->sysenter_esp); +qemu_get_betls (f, &env->sysenter_eip); + }else { +qemu_get_be32s (f, &env->sysenter_esp); +qemu_get_be32s (f, &env->sysenter_eip); + }qemu_get_betls (f, &env->cr[0 ]);qemu_get_betls (f, &env->cr[2 ]);