SYSENTER/SYSEXIT IA-32e implementation v3
PATCH 3/3 SYSENTER/SYSEXIT IA-32e implementation v3
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
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_bels (f, &env->sysenter_cs); +qemu_put_bels (f, &env->sysenter_esp); +qemu_put_bels (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_bels (f, &env->sysenter_esp); +qemu_get_bels (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 ]);
Quoted 13 lines · Alexander Graf
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
Signed-off-by Alexander Graf <[email protected]>Index:
qemu/target-i386/machine.c
===================================================================
target-i386/machine.c void cpu_save(QEMUFile *f, void *opaque) · line 93
Quoted 9 lines
target-i386/machine.c +3
-3@@ -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_bels (f, &env->sysenter_cs); +qemu_put_bels (f, &env->sysenter_esp); +qemu_put_bels (f, &env->sysenter_eip);
What exactly is be1s? Don't you mean be64s?
Quoted 13 lines
target-i386/machine.c +1
-1qemu_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]);
target-i386/machine.c int cpu_load(QEMUFile *f, void *opaque, · line 250
Quoted 9 lines
target-i386/machine.c +3
-2@@ -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_bels (f, &env->sysenter_esp); +qemu_get_bels (f, &env->sysenter_eip);
Same here. This doesn't compile, does it?
Quoted 7 lines
target-i386/machine.c +4
-0+ }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]);
Regards,
Anthony Liguori
Quoted 9 lines · Anthony Liguori
Quoted 8 lines · Alexander Graf
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
Signed-off-by Alexander Graf <[email protected]>
Quoted 15 lines
target-i386/machine.c void cpu_save(QEMUFile *f, void *opaque) · line 92
Quoted 13 lines
Index:
qemu/target-i386/machine.c
===================================================================target-i386/machine.c +3
-3@@ -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_bels (f, &env->sysenter_cs); +qemu_put_bels (f, &env->sysenter_esp); +qemu_put_bels (f, &env->sysenter_eip);What exactly is be1s? Don't you mean be64s?
Oh my god you are so right. Now that's embarrassing. Of course I meant betls.
Quoted 13 lines
Quoted 13 lines
target-i386/machine.c +1
-1qemu_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);
Quoted 8 lines
target-i386/machine.c int cpu_load(QEMUFile *f, void *opaque, · line 254
Quoted 6 lines
target-i386/machine.c +3
-2-qemu_get_be32s (f, &env->sysenter_esp); -qemu_get_be32s (f, &env->sysenter_eip); +if (version_id >=7 ) { +qemu_get_bels (f, &env->sysenter_esp); +qemu_get_bels (f, &env->sysenter_eip);Same here. This doesn't compile, does it?
No, it doesn't. I'm really sorry about that. I'll send a new series right away.
Alex
Quoted 14 lines
target-i386/machine.c int cpu_load(QEMUFile *f, void *opaque, · line 256
Quoted 8 lines
target-i386/machine.c +4
-0+ }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 ]);Regards,
Anthony Liguori