Skip to content

Commit

Permalink
x86: provide 64-bit with a load_sp0 function.
Browse files Browse the repository at this point in the history
Paravirt guests need to inform the underlying hypervisor whenever the sp0
tss field changes. i386 already has such a function, and we use it for
x86_64 too. There's an unnecessary (for 64-bit) msr handling part in the original
version, and it is placed around an ifdef. Making no more sense in
processor_32.h, it is moved to the common header

Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
  • Loading branch information
Glauber de Oliveira Costa authored and Ingo Molnar committed Jan 30, 2008
1 parent ca241c7 commit 7818a1e
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 23 deletions.
2 changes: 1 addition & 1 deletion arch/x86/kernel/process_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
/*
* Reload esp0, LDT and the page table pointer:
*/
tss->x86_tss.sp0 = next->sp0;
load_sp0(tss, next);

/*
* Switch DS and ES.
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/smpboot_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
start_rip = setup_trampoline();

init_rsp = c_idle.idle->thread.sp;
per_cpu(init_tss, cpu).x86_tss.sp0 = init_rsp;
load_sp0(&per_cpu(init_tss, cpu), &c_idle.idle->thread);
initial_code = start_secondary;
clear_tsk_thread_flag(c_idle.idle, TIF_FORK);

Expand Down
22 changes: 21 additions & 1 deletion include/asm-x86/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,22 @@ static inline void native_set_iopl_mask(unsigned mask)
#endif
}

static inline void native_load_sp0(struct tss_struct *tss,
struct thread_struct *thread)
{
tss->x86_tss.sp0 = thread->sp0;
#ifdef CONFIG_X86_32
/* Only happens when SEP is enabled, no need to test "SEP"arately */
if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) {
tss->x86_tss.ss1 = thread->sysenter_cs;
wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
}
#endif
}

#ifndef CONFIG_PARAVIRT
#ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h>
#else
#define __cpuid native_cpuid
#define paravirt_enabled() 0

Expand All @@ -206,6 +220,12 @@ static inline void native_set_iopl_mask(unsigned mask)
#define set_debugreg(value, register) \
native_set_debugreg(register, value)

static inline void load_sp0(struct tss_struct *tss,
struct thread_struct *thread)
{
native_load_sp0(tss, thread);
}

#define set_iopl_mask native_set_iopl_mask
#endif /* CONFIG_PARAVIRT */

Expand Down
20 changes: 0 additions & 20 deletions include/asm-x86/processor_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,26 +278,6 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);

#define KSTK_ESP(task) (task_pt_regs(task)->sp)

static inline void native_load_sp0(struct tss_struct *tss, struct thread_struct *thread)
{
tss->x86_tss.sp0 = thread->sp0;
/* This can only happen when SEP is enabled, no need to test "SEP"arately */
if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) {
tss->x86_tss.ss1 = thread->sysenter_cs;
wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
}
}

#ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h>
#else

static inline void load_sp0(struct tss_struct *tss, struct thread_struct *thread)
{
native_load_sp0(tss, thread);
}
#endif /* CONFIG_PARAVIRT */

/* generic versions from gas */
#define GENERIC_NOP1 ".byte 0x90\n"
#define GENERIC_NOP2 ".byte 0x89,0xf6\n"
Expand Down

0 comments on commit 7818a1e

Please sign in to comment.