From d75cd22fdd5f7d203fb60014d426942df33dd9a6 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 25 Jun 2008 00:19:26 -0400 Subject: x86/paravirt: split sysret and sysexit Don't conflate sysret and sysexit; they're different instructions with different semantics, and may be in use at the same time (at least within the same kernel, depending on whether its an Intel or AMD system). sysexit - just return to userspace, does no register restoration of any kind; must explicitly atomically enable interrupts. sysret - reloads flags from r11, so no need to explicitly enable interrupts on 64-bit, responsible for restoring usermode %gs Signed-off-by: Jeremy Fitzhardinge Cc: xen-devel Cc: Stephen Tweedie Cc: Eduardo Habkost Cc: Mark McLoughlin Signed-off-by: Ingo Molnar --- include/asm-x86/irqflags.h | 4 ++-- include/asm-x86/paravirt.h | 15 ++++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/asm-x86/irqflags.h b/include/asm-x86/irqflags.h index c242527f970..99ee5256a7e 100644 --- a/include/asm-x86/irqflags.h +++ b/include/asm-x86/irqflags.h @@ -112,13 +112,13 @@ static inline unsigned long __raw_local_irq_save(void) #ifdef CONFIG_X86_64 #define INTERRUPT_RETURN iretq -#define ENABLE_INTERRUPTS_SYSCALL_RET \ +#define USERSP_SYSRET \ movq %gs:pda_oldrsp, %rsp; \ swapgs; \ sysretq; #else #define INTERRUPT_RETURN iret -#define ENABLE_INTERRUPTS_SYSCALL_RET sti; sysexit +#define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit #define GET_CR0_INTO_EAX movl %cr0, %eax #endif diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index 82cdcde4b22..2668903b70f 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -141,8 +141,9 @@ struct pv_cpu_ops { u64 (*read_pmc)(int counter); unsigned long long (*read_tscp)(unsigned int *aux); - /* These two are jmp to, not actually called. */ - void (*irq_enable_syscall_ret)(void); + /* These three are jmp to, not actually called. */ + void (*irq_enable_sysexit)(void); + void (*usersp_sysret)(void); void (*iret)(void); void (*swapgs)(void); @@ -1480,10 +1481,10 @@ static inline unsigned long __raw_local_irq_save(void) call PARA_INDIRECT(pv_irq_ops+PV_IRQ_irq_enable); \ PV_RESTORE_REGS;) -#define ENABLE_INTERRUPTS_SYSCALL_RET \ - PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_syscall_ret),\ +#define ENABLE_INTERRUPTS_SYSEXIT \ + PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), \ CLBR_NONE, \ - jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_irq_enable_syscall_ret)) + jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_irq_enable_sysexit)) #ifdef CONFIG_X86_32 @@ -1504,6 +1505,10 @@ static inline unsigned long __raw_local_irq_save(void) movq %rax, %rcx; \ xorq %rax, %rax; +#define USERSP_SYSRET \ + PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usersp_sysret), \ + CLBR_NONE, \ + jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_usersp_sysret)) #endif #endif /* __ASSEMBLY__ */ -- cgit v1.2.3