diff options
| -rw-r--r-- | arch/i386/kernel/sysenter.c | 1 | ||||
| -rw-r--r-- | arch/i386/kernel/vm86.c | 2 | ||||
| -rw-r--r-- | include/asm-i386/processor.h | 13 |
3 files changed, 11 insertions, 5 deletions
diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index 2345e5da7d2a..8d86b0b7071d 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c @@ -40,6 +40,7 @@ void enable_sep_cpu(void *info) int cpu = get_cpu(); struct tss_struct *tss = init_tss + cpu; + tss->ss1 = __KERNEL_CS; wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp0, 0); wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0); diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c index ea5b776be202..0f56219bbd94 100644 --- a/arch/i386/kernel/vm86.c +++ b/arch/i386/kernel/vm86.c @@ -291,7 +291,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk tss = init_tss + smp_processor_id(); tss->esp0 = tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; - disable_sysenter(); + disable_sysenter(tss); tsk->thread.screen_bitmap = info->screen_bitmap; if (info->flags & VM86_SCREEN_BITMAP) diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 5ed85117e7ef..00014406c6ac 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -347,7 +347,7 @@ struct tss_struct { unsigned long esp0; unsigned short ss0,__ss0h; unsigned long esp1; - unsigned short ss1,__ss1h; + unsigned short ss1,__ss1h; /* ss1 is used to cache MSR_IA32_SYSENTER_CS */ unsigned long esp2; unsigned short ss2,__ss2h; unsigned long __cr3; @@ -413,15 +413,20 @@ static inline void load_esp0(struct tss_struct *tss, unsigned long esp0) { tss->esp0 = esp0; if (cpu_has_sep) { - wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); + if (tss->ss1 != __KERNEL_CS) { + tss->ss1 = __KERNEL_CS; + wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); + } wrmsr(MSR_IA32_SYSENTER_ESP, esp0, 0); } } -static inline void disable_sysenter(void) +static inline void disable_sysenter(struct tss_struct *tss) { - if (cpu_has_sep) + if (cpu_has_sep) { + tss->ss1 = 0; wrmsr(MSR_IA32_SYSENTER_CS, 0, 0); + } } #define start_thread(regs, new_eip, new_esp) do { \ |
