x86, 64-bit: swapgs pvop with a user-stack can never be called
authorJeremy Fitzhardinge <jeremy@goop.org>
Wed, 25 Jun 2008 04:19:30 +0000 (00:19 -0400)
committerIngo Molnar <mingo@elte.hu>
Tue, 8 Jul 2008 11:15:56 +0000 (13:15 +0200)
It's never safe to call a swapgs pvop when the user stack is current -
it must be inline replaced.  Rather than making a call, the
SWAPGS_UNSAFE_STACK pvop always just puts "swapgs" as a placeholder,
which must either be replaced inline or trap'n'emulated (somehow).

Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Cc: xen-devel <xen-devel@lists.xensource.com>
Cc: Stephen Tweedie <sct@redhat.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Mark McLoughlin <markmc@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
include/asm-x86/irqflags.h
include/asm-x86/paravirt.h

index ea9bd2635d596337e6f212d2e38c7160f827cfb1..d17e1f623dbb14f733e067d651bc43dc25fff26c 100644 (file)
@@ -111,6 +111,7 @@ static inline unsigned long __raw_local_irq_save(void)
 #define DISABLE_INTERRUPTS(x)  cli
 
 #ifdef CONFIG_X86_64
+#define SWAPGS_UNSAFE_STACK    swapgs
 #define INTERRUPT_RETURN       iretq
 #define USERGS_SYSRET64                                \
        swapgs;                                 \
@@ -185,7 +186,6 @@ static inline void trace_hardirqs_fixup(void)
  * Either way, this is a good way to document that we don't
  * have a reliable stack. x86_64 only.
  */
-#define SWAPGS_UNSAFE_STACK    swapgs
 #define ARCH_TRACE_IRQS_ON             call trace_hardirqs_on_thunk
 #define ARCH_TRACE_IRQS_OFF            call trace_hardirqs_off_thunk
 #define ARCH_LOCKDEP_SYS_EXIT          call lockdep_sys_exit_thunk
index 33f72f8fe7573600602127fff473a1445e91c948..3286a0c63b42de9243cc847fb67e8e482abca062 100644 (file)
@@ -1522,6 +1522,16 @@ static inline unsigned long __raw_local_irq_save(void)
 
 
 #else  /* !CONFIG_X86_32 */
+
+/*
+ * If swapgs is used while the userspace stack is still current,
+ * there's no way to call a pvop.  The PV replacement *must* be
+ * inlined, or the swapgs instruction must be trapped and emulated.
+ */
+#define SWAPGS_UNSAFE_STACK                                            \
+       PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE,     \
+                 swapgs)
+
 #define SWAPGS                                                         \
        PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_swapgs), CLBR_NONE,     \
                  PV_SAVE_REGS;                                         \