x86/paravirt, 64-bit: add adjust_exception_frame
authorJeremy Fitzhardinge <jeremy@goop.org>
Wed, 25 Jun 2008 04:19:31 +0000 (00:19 -0400)
committerIngo Molnar <mingo@elte.hu>
Tue, 8 Jul 2008 11:15:57 +0000 (13:15 +0200)
64-bit Xen pushes a couple of extra words onto an exception frame.
Add a hook to deal with them.

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>
arch/x86/kernel/asm-offsets_64.c
arch/x86/kernel/entry_64.S
arch/x86/kernel/paravirt.c
arch/x86/xen/enlighten.c
include/asm-x86/paravirt.h
include/asm-x86/processor.h

index 06c451a..3295e7c 100644 (file)
@@ -61,6 +61,7 @@ int main(void)
        OFFSET(PARAVIRT_PATCH_pv_irq_ops, paravirt_patch_template, pv_irq_ops);
        OFFSET(PV_IRQ_irq_disable, pv_irq_ops, irq_disable);
        OFFSET(PV_IRQ_irq_enable, pv_irq_ops, irq_enable);
+       OFFSET(PV_IRQ_adjust_exception_frame, pv_irq_ops, adjust_exception_frame);
        OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
        OFFSET(PV_CPU_usergs_sysret32, pv_cpu_ops, usergs_sysret32);
        OFFSET(PV_CPU_usergs_sysret64, pv_cpu_ops, usergs_sysret64);
index 880ffe5..70fe13a 100644 (file)
@@ -736,6 +736,7 @@ END(spurious_interrupt)
  */            
        .macro zeroentry sym
        INTR_FRAME
+       PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq $0        /* push error code/oldrax */ 
        CFI_ADJUST_CFA_OFFSET 8
        pushq %rax      /* push real oldrax to the rdi slot */ 
@@ -748,6 +749,7 @@ END(spurious_interrupt)
 
        .macro errorentry sym
        XCPT_FRAME
+       PARAVIRT_ADJUST_EXCEPTION_FRAME
        pushq %rax
        CFI_ADJUST_CFA_OFFSET 8
        CFI_REL_OFFSET rax,0
index bf1067e..b20c369 100644 (file)
@@ -296,6 +296,9 @@ struct pv_irq_ops pv_irq_ops = {
        .irq_enable = native_irq_enable,
        .safe_halt = native_safe_halt,
        .halt = native_halt,
+#ifdef CONFIG_X86_64
+       .adjust_exception_frame = paravirt_nop,
+#endif
 };
 
 struct pv_cpu_ops pv_cpu_ops = {
index 119c88f..3b98083 100644 (file)
@@ -1123,6 +1123,9 @@ static const struct pv_irq_ops xen_irq_ops __initdata = {
        .irq_enable = xen_irq_enable,
        .safe_halt = xen_safe_halt,
        .halt = xen_halt,
+#ifdef CONFIG_X86_64
+       .adjust_exception_frame = paravirt_nop,
+#endif
 };
 
 static const struct pv_apic_ops xen_apic_ops __initdata = {
index 3286a0c..3dc223d 100644 (file)
@@ -189,6 +189,10 @@ struct pv_irq_ops {
        void (*irq_enable)(void);
        void (*safe_halt)(void);
        void (*halt)(void);
+
+#ifdef CONFIG_X86_64
+       void (*adjust_exception_frame)(void);
+#endif
 };
 
 struct pv_apic_ops {
@@ -1544,6 +1548,11 @@ static inline unsigned long __raw_local_irq_save(void)
        movq %rax, %rcx;                                \
        xorq %rax, %rax;
 
+#define PARAVIRT_ADJUST_EXCEPTION_FRAME                                        \
+       PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_adjust_exception_frame), \
+                 CLBR_NONE,                                            \
+                 call PARA_INDIRECT(pv_irq_ops+PV_IRQ_adjust_exception_frame))
+
 #define USERGS_SYSRET64                                                        \
        PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64),       \
                  CLBR_NONE,                                            \
index 12b5ede..df2459f 100644 (file)
@@ -532,6 +532,8 @@ static inline void load_sp0(struct tss_struct *tss,
 
 #define set_iopl_mask native_set_iopl_mask
 #define SWAPGS swapgs
+
+#define PARAVIRT_ADJUST_EXCEPTION_FRAME        /*  */
 #endif /* CONFIG_PARAVIRT */
 
 /*