diff options
author | Alexander van Heukelum <heukelum@mailshack.com> | 2008-11-20 08:40:11 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-11-20 13:05:21 -0500 |
commit | dcd072e26055de600cecdc3f7a1e083ecd55c2e4 (patch) | |
tree | d1c8080930aefdbed577c462a92d9add7a16a478 /arch/x86/kernel/entry_64.S | |
parent | d99015b1abbad743aa049b439c1e1dede6d0fa49 (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.S | 220 |
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 */ |
271 | ENTRY(save_args) | 297 | ENTRY(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 | */ |
304 | 1: incl %gs:pda_irqcount | 321 | 1: 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 */ |
321 | ENTRY(ret_from_fork) | 339 | ENTRY(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 | */ |
1081 | KPROBE_ENTRY(error_entry) | 1101 | KPROBE_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) */ |
1148 | KPROBE_ENTRY(error_exit) | 1153 | KPROBE_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 |
1459 | 11: incl %gs:pda_irqcount | 1464 | 11: 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 | */ |
1485 | ENTRY(xen_failsafe_callback) | 1490 | ENTRY(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 |
1518 | 1: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */ | 1523 | 1: /* 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 |