aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/entry_64.S
diff options
context:
space:
mode:
authorAlexander van Heukelum <heukelum@mailshack.com>2008-11-20 08:40:11 -0500
committerIngo Molnar <mingo@elte.hu>2008-11-20 13:05:21 -0500
commitdcd072e26055de600cecdc3f7a1e083ecd55c2e4 (patch)
treed1c8080930aefdbed577c462a92d9add7a16a478 /arch/x86/kernel/entry_64.S
parentd99015b1abbad743aa049b439c1e1dede6d0fa49 (diff)
x86: clean up after: move entry_64.S register saving out of the macros
This add-on patch to x86: move entry_64.S register saving out of the macros visually cleans up the appearance of the code by introducing some basic helper macro's. It also adds some cfi annotations which were missing. Signed-off-by: Alexander van Heukelum <heukelum@fastmail.fm> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/entry_64.S')
-rw-r--r--arch/x86/kernel/entry_64.S220
1 files changed, 112 insertions, 108 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 5a12432ccdf9..7a04f696121d 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -60,6 +60,23 @@
60#define __AUDIT_ARCH_LE 0x40000000 60#define __AUDIT_ARCH_LE 0x40000000
61 61
62 .code64 62 .code64
63/*
64 * Some macro's to hide the most frequently occuring CFI annotations.
65 */
66 .macro CFI_PUSHQ reg
67 pushq \reg
68 CFI_ADJUST_CFA_OFFSET 8
69 .endm
70
71 .macro CFI_POPQ reg
72 popq \reg
73 CFI_ADJUST_CFA_OFFSET -8
74 .endm
75
76 .macro CFI_MOVQ reg offset=0
77 movq %\reg, \offset(%rsp)
78 CFI_REL_OFFSET \reg, \offset
79 .endm
63 80
64#ifdef CONFIG_FUNCTION_TRACER 81#ifdef CONFIG_FUNCTION_TRACER
65#ifdef CONFIG_DYNAMIC_FTRACE 82#ifdef CONFIG_DYNAMIC_FTRACE
@@ -213,84 +230,84 @@ ENTRY(native_usergs_sysret64)
213 CFI_ADJUST_CFA_OFFSET -(6*8) 230 CFI_ADJUST_CFA_OFFSET -(6*8)
214 .endm 231 .endm
215 232
216 .macro CFI_DEFAULT_STACK start=1 233/*
234 * initial frame state for interrupts (and exceptions without error code)
235 */
236 .macro EMPTY_FRAME start=1 offset=0
217 .if \start 237 .if \start
218 CFI_STARTPROC simple 238 CFI_STARTPROC simple
219 CFI_SIGNAL_FRAME 239 CFI_SIGNAL_FRAME
220 CFI_DEF_CFA rsp,SS+8 240 CFI_DEF_CFA rsp,8+\offset
221 .else 241 .else
222 CFI_DEF_CFA_OFFSET SS+8 242 CFI_DEF_CFA_OFFSET 8+\offset
223 .endif 243 .endif
224 CFI_REL_OFFSET r15,R15
225 CFI_REL_OFFSET r14,R14
226 CFI_REL_OFFSET r13,R13
227 CFI_REL_OFFSET r12,R12
228 CFI_REL_OFFSET rbp,RBP
229 CFI_REL_OFFSET rbx,RBX
230 CFI_REL_OFFSET r11,R11
231 CFI_REL_OFFSET r10,R10
232 CFI_REL_OFFSET r9,R9
233 CFI_REL_OFFSET r8,R8
234 CFI_REL_OFFSET rax,RAX
235 CFI_REL_OFFSET rcx,RCX
236 CFI_REL_OFFSET rdx,RDX
237 CFI_REL_OFFSET rsi,RSI
238 CFI_REL_OFFSET rdi,RDI
239 CFI_REL_OFFSET rip,RIP
240 /*CFI_REL_OFFSET cs,CS*/
241 /*CFI_REL_OFFSET rflags,EFLAGS*/
242 CFI_REL_OFFSET rsp,RSP
243 /*CFI_REL_OFFSET ss,SS*/
244 .endm 244 .endm
245 245
246/* 246/*
247 * initial frame state for interrupts and exceptions 247 * initial frame state for interrupts (and exceptions without error code)
248 */ 248 */
249 .macro _frame ref 249 .macro INTR_FRAME start=1 offset=0
250 CFI_STARTPROC simple 250 EMPTY_FRAME \start, (SS+8-RIP)+\offset
251 CFI_SIGNAL_FRAME 251 /*CFI_REL_OFFSET ss, SS-RIP+\offset*/
252 CFI_DEF_CFA rsp,SS+8-\ref 252 CFI_REL_OFFSET rsp, RSP-RIP+\offset
253 /*CFI_REL_OFFSET ss,SS-\ref*/ 253 /*CFI_REL_OFFSET rflags, EFLAGS-RIP+\offset*/
254 CFI_REL_OFFSET rsp,RSP-\ref 254 /*CFI_REL_OFFSET cs, CS-RIP+\offset*/
255 /*CFI_REL_OFFSET rflags,EFLAGS-\ref*/ 255 CFI_REL_OFFSET rip, RIP-RIP+\offset
256 /*CFI_REL_OFFSET cs,CS-\ref*/
257 CFI_REL_OFFSET rip,RIP-\ref
258 .endm 256 .endm
259 257
260/* 258/*
261 * initial frame state for interrupts (and exceptions without error code)
262 */
263#define INTR_FRAME _frame RIP
264/*
265 * initial frame state for exceptions with error code (and interrupts 259 * initial frame state for exceptions with error code (and interrupts
266 * with vector already pushed) 260 * with vector already pushed)
267 */ 261 */
268#define XCPT_FRAME _frame ORIG_RAX 262 .macro XCPT_FRAME start=1 offset=0
263 INTR_FRAME \start, (RIP-ORIG_RAX)+\offset
264 /*CFI_REL_OFFSET orig_rax, ORIG_RAX-ORIG_RAX*/
265 .endm
266
267/*
268 * frame that enables calling into C.
269 */
270 .macro PARTIAL_FRAME start=1 offset=0
271 XCPT_FRAME \start, (ORIG_RAX-ARGOFFSET)+\offset
272 CFI_REL_OFFSET rdi, (RDI-ARGOFFSET)+\offset
273 CFI_REL_OFFSET rsi, (RSI-ARGOFFSET)+\offset
274 CFI_REL_OFFSET rdx, (RDX-ARGOFFSET)+\offset
275 CFI_REL_OFFSET rcx, (RCX-ARGOFFSET)+\offset
276 CFI_REL_OFFSET rax, (RAX-ARGOFFSET)+\offset
277 CFI_REL_OFFSET r8, (R8-ARGOFFSET)+\offset
278 CFI_REL_OFFSET r9, (R9-ARGOFFSET)+\offset
279 CFI_REL_OFFSET r10, (R10-ARGOFFSET)+\offset
280 CFI_REL_OFFSET r11, (R11-ARGOFFSET)+\offset
281 .endm
282
283/*
284 * frame that enables passing a complete pt_regs to a C function.
285 */
286 .macro DEFAULT_FRAME start=1 offset=0
287 PARTIAL_FRAME \start, (R11-R15)+\offset
288 CFI_REL_OFFSET rbx, RBX+\offset
289 CFI_REL_OFFSET rbp, RBP+\offset
290 CFI_REL_OFFSET r12, R12+\offset
291 CFI_REL_OFFSET r13, R13+\offset
292 CFI_REL_OFFSET r14, R14+\offset
293 CFI_REL_OFFSET r15, R15+\offset
294 .endm
269 295
270/* save partial stack frame */ 296/* save partial stack frame */
271ENTRY(save_args) 297ENTRY(save_args)
272 XCPT_FRAME 298 XCPT_FRAME
273 cld 299 cld
274 movq %rdi, 8*8+16(%rsp) 300 CFI_MOVQ rdi, (RDI-ARGOFFSET)+16
275 CFI_REL_OFFSET rdi, 8*8+16 301 CFI_MOVQ rsi, (RSI-ARGOFFSET)+16
276 movq %rsi, 7*8+16(%rsp) 302 CFI_MOVQ rdx, (RDX-ARGOFFSET)+16
277 CFI_REL_OFFSET rsi, 7*8+16 303 CFI_MOVQ rcx, (RCX-ARGOFFSET)+16
278 movq %rdx, 6*8+16(%rsp) 304 CFI_MOVQ rax, (RAX-ARGOFFSET)+16
279 CFI_REL_OFFSET rdx, 6*8+16 305 CFI_MOVQ r8, (R8-ARGOFFSET)+16
280 movq %rcx, 5*8+16(%rsp) 306 CFI_MOVQ r9, (R9-ARGOFFSET)+16
281 CFI_REL_OFFSET rcx, 5*8+16 307 CFI_MOVQ r10, (R10-ARGOFFSET)+16
282 movq %rax, 4*8+16(%rsp) 308 CFI_MOVQ r11, (R11-ARGOFFSET)+16
283 CFI_REL_OFFSET rax, 4*8+16
284 movq %r8, 3*8+16(%rsp)
285 CFI_REL_OFFSET r8, 3*8+16
286 movq %r9, 2*8+16(%rsp)
287 CFI_REL_OFFSET r9, 2*8+16
288 movq %r10, 1*8+16(%rsp)
289 CFI_REL_OFFSET r10, 1*8+16
290 movq %r11, 0*8+16(%rsp)
291 CFI_REL_OFFSET r11, 0*8+16
292 leaq -ARGOFFSET+16(%rsp),%rdi /* arg1 for handler */ 309 leaq -ARGOFFSET+16(%rsp),%rdi /* arg1 for handler */
293 movq %rbp, 8(%rsp) /* push %rbp */ 310 CFI_MOVQ rbp, 8 /* push %rbp */
294 leaq 8(%rsp), %rbp /* mov %rsp, %ebp */ 311 leaq 8(%rsp), %rbp /* mov %rsp, %ebp */
295 testl $3, CS(%rdi) 312 testl $3, CS(%rdi)
296 je 1f 313 je 1f
@@ -303,9 +320,10 @@ ENTRY(save_args)
303 */ 320 */
3041: incl %gs:pda_irqcount 3211: incl %gs:pda_irqcount
305 jne 2f 322 jne 2f
306 pop %rax /* move return address... */ 323 CFI_POPQ %rax /* move return address... */
307 mov %gs:pda_irqstackptr,%rsp 324 mov %gs:pda_irqstackptr,%rsp
308 push %rax /* ... to the new stack */ 325 EMPTY_FRAME 0
326 CFI_PUSHQ %rax /* ... to the new stack */
309 /* 327 /*
310 * We entered an interrupt context - irqs are off: 328 * We entered an interrupt context - irqs are off:
311 */ 329 */
@@ -319,7 +337,7 @@ END(save_args)
319 */ 337 */
320/* rdi: prev */ 338/* rdi: prev */
321ENTRY(ret_from_fork) 339ENTRY(ret_from_fork)
322 CFI_DEFAULT_STACK 340 DEFAULT_FRAME
323 push kernel_eflags(%rip) 341 push kernel_eflags(%rip)
324 CFI_ADJUST_CFA_OFFSET 8 342 CFI_ADJUST_CFA_OFFSET 8
325 popf # reset kernel eflags 343 popf # reset kernel eflags
@@ -732,6 +750,7 @@ END(interrupt)
732 subq $10*8, %rsp 750 subq $10*8, %rsp
733 CFI_ADJUST_CFA_OFFSET 10*8 751 CFI_ADJUST_CFA_OFFSET 10*8
734 call save_args 752 call save_args
753 PARTIAL_FRAME 0
735 call \func 754 call \func
736 .endm 755 .endm
737 756
@@ -949,11 +968,11 @@ END(spurious_interrupt)
949 .macro zeroentry sym 968 .macro zeroentry sym
950 INTR_FRAME 969 INTR_FRAME
951 PARAVIRT_ADJUST_EXCEPTION_FRAME 970 PARAVIRT_ADJUST_EXCEPTION_FRAME
952 pushq $-1 /* ORIG_RAX: no syscall to restart */ 971 CFI_PUSHQ $-1 /* ORIG_RAX: no syscall to restart */
953 CFI_ADJUST_CFA_OFFSET 8
954 subq $15*8,%rsp 972 subq $15*8,%rsp
955 CFI_ADJUST_CFA_OFFSET 15*8 973 CFI_ADJUST_CFA_OFFSET 15*8
956 call error_entry 974 call error_entry
975 DEFAULT_FRAME 0
957 movq %rsp,%rdi /* pt_regs pointer */ 976 movq %rsp,%rdi /* pt_regs pointer */
958 xorl %esi,%esi /* no error code */ 977 xorl %esi,%esi /* no error code */
959 call \sym 978 call \sym
@@ -967,6 +986,7 @@ END(spurious_interrupt)
967 subq $15*8,%rsp 986 subq $15*8,%rsp
968 CFI_ADJUST_CFA_OFFSET 15*8 987 CFI_ADJUST_CFA_OFFSET 15*8
969 call error_entry 988 call error_entry
989 DEFAULT_FRAME 0
970 movq %rsp,%rdi /* pt_regs pointer */ 990 movq %rsp,%rdi /* pt_regs pointer */
971 movq ORIG_RAX(%rsp),%rsi /* get error code */ 991 movq ORIG_RAX(%rsp),%rsi /* get error code */
972 movq $-1,ORIG_RAX(%rsp) /* no syscall to restart */ 992 movq $-1,ORIG_RAX(%rsp) /* no syscall to restart */
@@ -1079,40 +1099,25 @@ paranoid_schedule\trace:
1079 * returns in "no swapgs flag" in %ebx. 1099 * returns in "no swapgs flag" in %ebx.
1080 */ 1100 */
1081KPROBE_ENTRY(error_entry) 1101KPROBE_ENTRY(error_entry)
1082 _frame RDI 1102 XCPT_FRAME
1083 CFI_ADJUST_CFA_OFFSET 15*8 1103 CFI_ADJUST_CFA_OFFSET 15*8
1084 /* oldrax contains error code */ 1104 /* oldrax contains error code */
1085 cld 1105 cld
1086 movq %rdi,14*8+8(%rsp) 1106 CFI_MOVQ rdi, RDI+8
1087 CFI_REL_OFFSET rdi,RDI+8 1107 CFI_MOVQ rsi, RSI+8
1088 movq %rsi,13*8+8(%rsp) 1108 CFI_MOVQ rdx, RDX+8
1089 CFI_REL_OFFSET rsi,RSI+8 1109 CFI_MOVQ rcx, RCX+8
1090 movq %rdx,12*8+8(%rsp) 1110 CFI_MOVQ rax, RAX+8
1091 CFI_REL_OFFSET rdx,RDX+8 1111 CFI_MOVQ r8, R8+8
1092 movq %rcx,11*8+8(%rsp) 1112 CFI_MOVQ r9, R9+8
1093 CFI_REL_OFFSET rcx,RCX+8 1113 CFI_MOVQ r10, R10+8
1094 movq %rax,10*8+8(%rsp) 1114 CFI_MOVQ r11, R11+8
1095 CFI_REL_OFFSET rax,RAX+8 1115 CFI_MOVQ rbx, RBX+8
1096 movq %r8, 9*8+8(%rsp) 1116 CFI_MOVQ rbp, RBP+8
1097 CFI_REL_OFFSET r8,R8+8 1117 CFI_MOVQ r12, R12+8
1098 movq %r9, 8*8+8(%rsp) 1118 CFI_MOVQ r13, R13+8
1099 CFI_REL_OFFSET r9,R9+8 1119 CFI_MOVQ r14, R14+8
1100 movq %r10,7*8+8(%rsp) 1120 CFI_MOVQ r15, R15+8
1101 CFI_REL_OFFSET r10,R10+8
1102 movq %r11,6*8+8(%rsp)
1103 CFI_REL_OFFSET r11,R11+8
1104 movq %rbx,5*8+8(%rsp)
1105 CFI_REL_OFFSET rbx,RBX+8
1106 movq %rbp,4*8+8(%rsp)
1107 CFI_REL_OFFSET rbp,RBP+8
1108 movq %r12,3*8+8(%rsp)
1109 CFI_REL_OFFSET r12,R12+8
1110 movq %r13,2*8+8(%rsp)
1111 CFI_REL_OFFSET r13,R13+8
1112 movq %r14,1*8+8(%rsp)
1113 CFI_REL_OFFSET r14,R14+8
1114 movq %r15,0*8+8(%rsp)
1115 CFI_REL_OFFSET r15,R15+8
1116 xorl %ebx,%ebx 1121 xorl %ebx,%ebx
1117 testl $3,CS+8(%rsp) 1122 testl $3,CS+8(%rsp)
1118 je error_kernelspace 1123 je error_kernelspace
@@ -1146,7 +1151,7 @@ KPROBE_END(error_entry)
1146 1151
1147/* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */ 1152/* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */
1148KPROBE_ENTRY(error_exit) 1153KPROBE_ENTRY(error_exit)
1149 _frame R15 1154 DEFAULT_FRAME
1150 movl %ebx,%eax 1155 movl %ebx,%eax
1151 RESTORE_REST 1156 RESTORE_REST
1152 DISABLE_INTERRUPTS(CLBR_NONE) 1157 DISABLE_INTERRUPTS(CLBR_NONE)
@@ -1455,7 +1460,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs)
1455 see the correct pointer to the pt_regs */ 1460 see the correct pointer to the pt_regs */
1456 movq %rdi, %rsp # we don't return, adjust the stack frame 1461 movq %rdi, %rsp # we don't return, adjust the stack frame
1457 CFI_ENDPROC 1462 CFI_ENDPROC
1458 CFI_DEFAULT_STACK 1463 DEFAULT_FRAME
145911: incl %gs:pda_irqcount 146411: incl %gs:pda_irqcount
1460 movq %rsp,%rbp 1465 movq %rsp,%rbp
1461 CFI_DEF_CFA_REGISTER rbp 1466 CFI_DEF_CFA_REGISTER rbp
@@ -1483,10 +1488,13 @@ END(do_hypervisor_callback)
1483# with its current contents: any discrepancy means we in category 1. 1488# with its current contents: any discrepancy means we in category 1.
1484*/ 1489*/
1485ENTRY(xen_failsafe_callback) 1490ENTRY(xen_failsafe_callback)
1486 framesz = (RIP-0x30) /* workaround buggy gas */ 1491 INTR_FRAME 1 (6*8)
1487 _frame framesz 1492 /*CFI_REL_OFFSET gs,GS*/
1488 CFI_REL_OFFSET rcx, 0 1493 /*CFI_REL_OFFSET fs,FS*/
1489 CFI_REL_OFFSET r11, 8 1494 /*CFI_REL_OFFSET es,ES*/
1495 /*CFI_REL_OFFSET ds,DS*/
1496 CFI_REL_OFFSET r11,8
1497 CFI_REL_OFFSET rcx,0
1490 movw %ds,%cx 1498 movw %ds,%cx
1491 cmpw %cx,0x10(%rsp) 1499 cmpw %cx,0x10(%rsp)
1492 CFI_REMEMBER_STATE 1500 CFI_REMEMBER_STATE
@@ -1507,12 +1515,9 @@ ENTRY(xen_failsafe_callback)
1507 CFI_RESTORE r11 1515 CFI_RESTORE r11
1508 addq $0x30,%rsp 1516 addq $0x30,%rsp
1509 CFI_ADJUST_CFA_OFFSET -0x30 1517 CFI_ADJUST_CFA_OFFSET -0x30
1510 pushq $0 1518 CFI_PUSHQ $0 /* RIP */
1511 CFI_ADJUST_CFA_OFFSET 8 1519 CFI_PUSHQ %r11
1512 pushq %r11 1520 CFI_PUSHQ %rcx
1513 CFI_ADJUST_CFA_OFFSET 8
1514 pushq %rcx
1515 CFI_ADJUST_CFA_OFFSET 8
1516 jmp general_protection 1521 jmp general_protection
1517 CFI_RESTORE_STATE 1522 CFI_RESTORE_STATE
15181: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */ 15231: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */
@@ -1522,8 +1527,7 @@ ENTRY(xen_failsafe_callback)
1522 CFI_RESTORE r11 1527 CFI_RESTORE r11
1523 addq $0x30,%rsp 1528 addq $0x30,%rsp
1524 CFI_ADJUST_CFA_OFFSET -0x30 1529 CFI_ADJUST_CFA_OFFSET -0x30
1525 pushq $0 1530 CFI_PUSHQ $0
1526 CFI_ADJUST_CFA_OFFSET 8
1527 SAVE_ALL 1531 SAVE_ALL
1528 jmp error_exit 1532 jmp error_exit
1529 CFI_ENDPROC 1533 CFI_ENDPROC