diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2008-07-08 18:07:00 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-16 05:02:31 -0400 |
commit | 997409d3d0bd6894f33e31ced251c0fdf523aa14 (patch) | |
tree | cc4a963310cc9ae00138607cdaa35c99e7d5f76c | |
parent | e176d367d0cc8b8efd2e0960c9edf5d2fe7cd9f1 (diff) |
xen64: deal with extra words Xen pushes onto exception frames
Xen pushes two extra words containing the values of rcx and r11. This
pvop hook copies the words back into their appropriate registers, and
cleans them off the stack. This leaves the stack in native form, so
the normal handler can run unchanged.
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.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>
-rw-r--r-- | arch/x86/xen/enlighten.c | 2 | ||||
-rw-r--r-- | arch/x86/xen/xen-asm_64.S | 5 | ||||
-rw-r--r-- | arch/x86/xen/xen-ops.h | 2 |
3 files changed, 8 insertions, 1 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index f5e96f7a4c5c..9d94483b3b5e 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -1091,7 +1091,7 @@ static const struct pv_irq_ops xen_irq_ops __initdata = { | |||
1091 | .safe_halt = xen_safe_halt, | 1091 | .safe_halt = xen_safe_halt, |
1092 | .halt = xen_halt, | 1092 | .halt = xen_halt, |
1093 | #ifdef CONFIG_X86_64 | 1093 | #ifdef CONFIG_X86_64 |
1094 | .adjust_exception_frame = paravirt_nop, | 1094 | .adjust_exception_frame = xen_adjust_exception_frame, |
1095 | #endif | 1095 | #endif |
1096 | }; | 1096 | }; |
1097 | 1097 | ||
diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S index 4ec10827370b..b147b495daef 100644 --- a/arch/x86/xen/xen-asm_64.S +++ b/arch/x86/xen/xen-asm_64.S | |||
@@ -133,6 +133,11 @@ check_events: | |||
133 | ret | 133 | ret |
134 | #endif | 134 | #endif |
135 | 135 | ||
136 | ENTRY(xen_adjust_exception_frame) | ||
137 | mov 8+0(%rsp),%rcx | ||
138 | mov 8+8(%rsp),%r11 | ||
139 | ret $16 | ||
140 | |||
136 | ENTRY(xen_iret) | 141 | ENTRY(xen_iret) |
137 | pushq $0 | 142 | pushq $0 |
138 | jmp hypercall_page + __HYPERVISOR_iret * 32 | 143 | jmp hypercall_page + __HYPERVISOR_iret * 32 |
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index aca4a7803e2c..c4800a2c5a41 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
@@ -67,7 +67,9 @@ DECL_ASM(void, xen_irq_disable_direct, void); | |||
67 | DECL_ASM(unsigned long, xen_save_fl_direct, void); | 67 | DECL_ASM(unsigned long, xen_save_fl_direct, void); |
68 | DECL_ASM(void, xen_restore_fl_direct, unsigned long); | 68 | DECL_ASM(void, xen_restore_fl_direct, unsigned long); |
69 | 69 | ||
70 | /* These are not functions, and cannot be called normally */ | ||
70 | void xen_iret(void); | 71 | void xen_iret(void); |
71 | void xen_sysexit(void); | 72 | void xen_sysexit(void); |
73 | void xen_adjust_exception_frame(void); | ||
72 | 74 | ||
73 | #endif /* XEN_OPS_H */ | 75 | #endif /* XEN_OPS_H */ |