direct-io.hg

view xen/include/asm-x86/x86_32/asm_defns.h @ 15417:015d9abeacfb

i386: Simplify failsafe callback handling.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Thu Jun 21 21:36:26 2007 +0100 (2007-06-21)
parents acb7aa72fac7
children
line source
1 #ifndef __X86_32_ASM_DEFNS_H__
2 #define __X86_32_ASM_DEFNS_H__
4 #include <asm/percpu.h>
6 #ifdef CONFIG_FRAME_POINTER
7 /* Indicate special exception stack frame by inverting the frame pointer. */
8 #define SETUP_EXCEPTION_FRAME_POINTER \
9 movl %esp,%ebp; \
10 notl %ebp
11 #else
12 #define SETUP_EXCEPTION_FRAME_POINTER
13 #endif
15 #ifndef NDEBUG
16 #define ASSERT_INTERRUPT_STATUS(x) \
17 pushf; \
18 testb $X86_EFLAGS_IF>>8,1(%esp); \
19 j##x 1f; \
20 ud2a; \
21 1: addl $4,%esp;
22 #else
23 #define ASSERT_INTERRUPT_STATUS(x)
24 #endif
26 #define ASSERT_INTERRUPTS_ENABLED ASSERT_INTERRUPT_STATUS(nz)
27 #define ASSERT_INTERRUPTS_DISABLED ASSERT_INTERRUPT_STATUS(z)
29 #define SAVE_ALL_GPRS \
30 cld; \
31 pushl %eax; \
32 pushl %ebp; \
33 SETUP_EXCEPTION_FRAME_POINTER; \
34 pushl %edi; \
35 pushl %esi; \
36 pushl %edx; \
37 pushl %ecx; \
38 pushl %ebx
40 /*
41 * Saves all register state into an exception/interrupt stack frame.
42 * Returns to the caller at <xen_lbl> if the interrupted context is within
43 * Xen; at <vm86_lbl> if the interrupted context is vm86; or falls through
44 * if the interrupted context is an ordinary guest protected-mode context.
45 * In all cases %ecx contains __HYPERVISOR_DS. %ds/%es are guaranteed to
46 * contain __HYPERVISOR_DS unless control passes to <xen_lbl>, in which case
47 * the caller is reponsible for validity of %ds/%es.
48 */
49 #define SAVE_ALL(xen_lbl, vm86_lbl) \
50 SAVE_ALL_GPRS; \
51 testl $(X86_EFLAGS_VM),UREGS_eflags(%esp); \
52 mov %ds,%edi; \
53 mov %es,%esi; \
54 mov $(__HYPERVISOR_DS),%ecx; \
55 jnz 86f; \
56 .text 1; \
57 86: call setup_vm86_frame; \
58 jmp vm86_lbl; \
59 .previous; \
60 testb $3,UREGS_cs(%esp); \
61 jz xen_lbl; \
62 /* \
63 * We are the outermost Xen context, but our \
64 * life is complicated by NMIs and MCEs. These \
65 * could occur in our critical section and \
66 * pollute %ds and %es. We have to detect that \
67 * this has occurred and avoid saving Xen DS/ES \
68 * values to the guest stack frame. \
69 */ \
70 cmpw %cx,%di; \
71 mov %ecx,%ds; \
72 mov %fs,UREGS_fs(%esp); \
73 cmove UREGS_ds(%esp),%edi; \
74 cmpw %cx,%si; \
75 mov %edi,UREGS_ds(%esp); \
76 cmove UREGS_es(%esp),%esi; \
77 mov %ecx,%es; \
78 mov %gs,UREGS_gs(%esp); \
79 mov %esi,UREGS_es(%esp)
81 #ifdef PERF_COUNTERS
82 #define PERFC_INCR(_name,_idx,_cur) \
83 pushl _cur; \
84 movl VCPU_processor(_cur),_cur; \
85 shll $PERCPU_SHIFT,_cur; \
86 incl per_cpu__perfcounters+_name*4(_cur,_idx,4);\
87 popl _cur
88 #else
89 #define PERFC_INCR(_name,_idx,_cur)
90 #endif
92 #ifdef CONFIG_X86_SUPERVISOR_MODE_KERNEL
93 #define FIXUP_RING0_GUEST_STACK \
94 testl $2,8(%esp); \
95 jnz 1f; /* rings 2 & 3 permitted */ \
96 testl $1,8(%esp); \
97 jz 2f; \
98 ud2; /* ring 1 should not be used */ \
99 2:cmpl $(__HYPERVISOR_VIRT_START),%esp; \
100 jge 1f; \
101 call fixup_ring0_guest_stack; \
102 1:
103 #else
104 #define FIXUP_RING0_GUEST_STACK
105 #endif
107 #define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v)
108 #define XBUILD_SMP_INTERRUPT(x,v) \
109 asmlinkage void x(void); \
110 __asm__( \
111 "\n"__ALIGN_STR"\n" \
112 ".globl " STR(x) "\n\t" \
113 STR(x) ":\n\t" \
114 "pushl $"#v"<<16\n\t" \
115 STR(FIXUP_RING0_GUEST_STACK) \
116 STR(SAVE_ALL(1f,1f)) "\n\t" \
117 "1:movl %esp,%eax\n\t" \
118 "pushl %eax\n\t" \
119 "call "STR(smp_##x)"\n\t" \
120 "addl $4,%esp\n\t" \
121 "jmp ret_from_intr\n");
123 #define BUILD_COMMON_IRQ() \
124 __asm__( \
125 "\n" __ALIGN_STR"\n" \
126 "common_interrupt:\n\t" \
127 STR(FIXUP_RING0_GUEST_STACK) \
128 STR(SAVE_ALL(1f,1f)) "\n\t" \
129 "1:movl %esp,%eax\n\t" \
130 "pushl %eax\n\t" \
131 "call " STR(do_IRQ) "\n\t" \
132 "addl $4,%esp\n\t" \
133 "jmp ret_from_intr\n");
135 #define IRQ_NAME2(nr) nr##_interrupt(void)
136 #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
138 #define BUILD_IRQ(nr) \
139 asmlinkage void IRQ_NAME(nr); \
140 __asm__( \
141 "\n"__ALIGN_STR"\n" \
142 STR(IRQ) #nr "_interrupt:\n\t" \
143 "pushl $"#nr"<<16\n\t" \
144 "jmp common_interrupt");
146 #endif /* __X86_32_ASM_DEFNS_H__ */