diff options
Diffstat (limited to 'arch/x86/kernel/entry_64.S')
-rw-r--r-- | arch/x86/kernel/entry_64.S | 120 |
1 files changed, 115 insertions, 5 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index ae63e584c340..8410e26f4183 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -349,8 +349,7 @@ ENTRY(system_call_after_swapgs) | |||
349 | movq %rcx,RIP-ARGOFFSET(%rsp) | 349 | movq %rcx,RIP-ARGOFFSET(%rsp) |
350 | CFI_REL_OFFSET rip,RIP-ARGOFFSET | 350 | CFI_REL_OFFSET rip,RIP-ARGOFFSET |
351 | GET_THREAD_INFO(%rcx) | 351 | GET_THREAD_INFO(%rcx) |
352 | testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP), \ | 352 | testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%rcx) |
353 | TI_flags(%rcx) | ||
354 | jnz tracesys | 353 | jnz tracesys |
355 | cmpq $__NR_syscall_max,%rax | 354 | cmpq $__NR_syscall_max,%rax |
356 | ja badsys | 355 | ja badsys |
@@ -430,7 +429,12 @@ tracesys: | |||
430 | FIXUP_TOP_OF_STACK %rdi | 429 | FIXUP_TOP_OF_STACK %rdi |
431 | movq %rsp,%rdi | 430 | movq %rsp,%rdi |
432 | call syscall_trace_enter | 431 | call syscall_trace_enter |
433 | LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ | 432 | /* |
433 | * Reload arg registers from stack in case ptrace changed them. | ||
434 | * We don't reload %rax because syscall_trace_enter() returned | ||
435 | * the value it wants us to use in the table lookup. | ||
436 | */ | ||
437 | LOAD_ARGS ARGOFFSET, 1 | ||
434 | RESTORE_REST | 438 | RESTORE_REST |
435 | cmpq $__NR_syscall_max,%rax | 439 | cmpq $__NR_syscall_max,%rax |
436 | ja int_ret_from_sys_call /* RAX(%rsp) set to -ENOSYS above */ | 440 | ja int_ret_from_sys_call /* RAX(%rsp) set to -ENOSYS above */ |
@@ -483,7 +487,7 @@ int_very_careful: | |||
483 | ENABLE_INTERRUPTS(CLBR_NONE) | 487 | ENABLE_INTERRUPTS(CLBR_NONE) |
484 | SAVE_REST | 488 | SAVE_REST |
485 | /* Check for syscall exit trace */ | 489 | /* Check for syscall exit trace */ |
486 | testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edx | 490 | testl $_TIF_WORK_SYSCALL_EXIT,%edx |
487 | jz int_signal | 491 | jz int_signal |
488 | pushq %rdi | 492 | pushq %rdi |
489 | CFI_ADJUST_CFA_OFFSET 8 | 493 | CFI_ADJUST_CFA_OFFSET 8 |
@@ -491,7 +495,7 @@ int_very_careful: | |||
491 | call syscall_trace_leave | 495 | call syscall_trace_leave |
492 | popq %rdi | 496 | popq %rdi |
493 | CFI_ADJUST_CFA_OFFSET -8 | 497 | CFI_ADJUST_CFA_OFFSET -8 |
494 | andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi | 498 | andl $~(_TIF_WORK_SYSCALL_EXIT|_TIF_SYSCALL_EMU),%edi |
495 | jmp int_restore_rest | 499 | jmp int_restore_rest |
496 | 500 | ||
497 | int_signal: | 501 | int_signal: |
@@ -1189,6 +1193,7 @@ END(device_not_available) | |||
1189 | /* runs on exception stack */ | 1193 | /* runs on exception stack */ |
1190 | KPROBE_ENTRY(debug) | 1194 | KPROBE_ENTRY(debug) |
1191 | INTR_FRAME | 1195 | INTR_FRAME |
1196 | PARAVIRT_ADJUST_EXCEPTION_FRAME | ||
1192 | pushq $0 | 1197 | pushq $0 |
1193 | CFI_ADJUST_CFA_OFFSET 8 | 1198 | CFI_ADJUST_CFA_OFFSET 8 |
1194 | paranoidentry do_debug, DEBUG_STACK | 1199 | paranoidentry do_debug, DEBUG_STACK |
@@ -1198,6 +1203,7 @@ KPROBE_END(debug) | |||
1198 | /* runs on exception stack */ | 1203 | /* runs on exception stack */ |
1199 | KPROBE_ENTRY(nmi) | 1204 | KPROBE_ENTRY(nmi) |
1200 | INTR_FRAME | 1205 | INTR_FRAME |
1206 | PARAVIRT_ADJUST_EXCEPTION_FRAME | ||
1201 | pushq $-1 | 1207 | pushq $-1 |
1202 | CFI_ADJUST_CFA_OFFSET 8 | 1208 | CFI_ADJUST_CFA_OFFSET 8 |
1203 | paranoidentry do_nmi, 0, 0 | 1209 | paranoidentry do_nmi, 0, 0 |
@@ -1211,6 +1217,7 @@ KPROBE_END(nmi) | |||
1211 | 1217 | ||
1212 | KPROBE_ENTRY(int3) | 1218 | KPROBE_ENTRY(int3) |
1213 | INTR_FRAME | 1219 | INTR_FRAME |
1220 | PARAVIRT_ADJUST_EXCEPTION_FRAME | ||
1214 | pushq $0 | 1221 | pushq $0 |
1215 | CFI_ADJUST_CFA_OFFSET 8 | 1222 | CFI_ADJUST_CFA_OFFSET 8 |
1216 | paranoidentry do_int3, DEBUG_STACK | 1223 | paranoidentry do_int3, DEBUG_STACK |
@@ -1237,6 +1244,7 @@ END(coprocessor_segment_overrun) | |||
1237 | /* runs on exception stack */ | 1244 | /* runs on exception stack */ |
1238 | ENTRY(double_fault) | 1245 | ENTRY(double_fault) |
1239 | XCPT_FRAME | 1246 | XCPT_FRAME |
1247 | PARAVIRT_ADJUST_EXCEPTION_FRAME | ||
1240 | paranoidentry do_double_fault | 1248 | paranoidentry do_double_fault |
1241 | jmp paranoid_exit1 | 1249 | jmp paranoid_exit1 |
1242 | CFI_ENDPROC | 1250 | CFI_ENDPROC |
@@ -1253,6 +1261,7 @@ END(segment_not_present) | |||
1253 | /* runs on exception stack */ | 1261 | /* runs on exception stack */ |
1254 | ENTRY(stack_segment) | 1262 | ENTRY(stack_segment) |
1255 | XCPT_FRAME | 1263 | XCPT_FRAME |
1264 | PARAVIRT_ADJUST_EXCEPTION_FRAME | ||
1256 | paranoidentry do_stack_segment | 1265 | paranoidentry do_stack_segment |
1257 | jmp paranoid_exit1 | 1266 | jmp paranoid_exit1 |
1258 | CFI_ENDPROC | 1267 | CFI_ENDPROC |
@@ -1278,6 +1287,7 @@ END(spurious_interrupt_bug) | |||
1278 | /* runs on exception stack */ | 1287 | /* runs on exception stack */ |
1279 | ENTRY(machine_check) | 1288 | ENTRY(machine_check) |
1280 | INTR_FRAME | 1289 | INTR_FRAME |
1290 | PARAVIRT_ADJUST_EXCEPTION_FRAME | ||
1281 | pushq $0 | 1291 | pushq $0 |
1282 | CFI_ADJUST_CFA_OFFSET 8 | 1292 | CFI_ADJUST_CFA_OFFSET 8 |
1283 | paranoidentry do_machine_check | 1293 | paranoidentry do_machine_check |
@@ -1312,3 +1322,103 @@ KPROBE_ENTRY(ignore_sysret) | |||
1312 | sysret | 1322 | sysret |
1313 | CFI_ENDPROC | 1323 | CFI_ENDPROC |
1314 | ENDPROC(ignore_sysret) | 1324 | ENDPROC(ignore_sysret) |
1325 | |||
1326 | #ifdef CONFIG_XEN | ||
1327 | ENTRY(xen_hypervisor_callback) | ||
1328 | zeroentry xen_do_hypervisor_callback | ||
1329 | END(xen_hypervisor_callback) | ||
1330 | |||
1331 | /* | ||
1332 | # A note on the "critical region" in our callback handler. | ||
1333 | # We want to avoid stacking callback handlers due to events occurring | ||
1334 | # during handling of the last event. To do this, we keep events disabled | ||
1335 | # until we've done all processing. HOWEVER, we must enable events before | ||
1336 | # popping the stack frame (can't be done atomically) and so it would still | ||
1337 | # be possible to get enough handler activations to overflow the stack. | ||
1338 | # Although unlikely, bugs of that kind are hard to track down, so we'd | ||
1339 | # like to avoid the possibility. | ||
1340 | # So, on entry to the handler we detect whether we interrupted an | ||
1341 | # existing activation in its critical region -- if so, we pop the current | ||
1342 | # activation and restart the handler using the previous one. | ||
1343 | */ | ||
1344 | ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) | ||
1345 | CFI_STARTPROC | ||
1346 | /* Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will | ||
1347 | see the correct pointer to the pt_regs */ | ||
1348 | movq %rdi, %rsp # we don't return, adjust the stack frame | ||
1349 | CFI_ENDPROC | ||
1350 | CFI_DEFAULT_STACK | ||
1351 | 11: incl %gs:pda_irqcount | ||
1352 | movq %rsp,%rbp | ||
1353 | CFI_DEF_CFA_REGISTER rbp | ||
1354 | cmovzq %gs:pda_irqstackptr,%rsp | ||
1355 | pushq %rbp # backlink for old unwinder | ||
1356 | call xen_evtchn_do_upcall | ||
1357 | popq %rsp | ||
1358 | CFI_DEF_CFA_REGISTER rsp | ||
1359 | decl %gs:pda_irqcount | ||
1360 | jmp error_exit | ||
1361 | CFI_ENDPROC | ||
1362 | END(do_hypervisor_callback) | ||
1363 | |||
1364 | /* | ||
1365 | # Hypervisor uses this for application faults while it executes. | ||
1366 | # We get here for two reasons: | ||
1367 | # 1. Fault while reloading DS, ES, FS or GS | ||
1368 | # 2. Fault while executing IRET | ||
1369 | # Category 1 we do not need to fix up as Xen has already reloaded all segment | ||
1370 | # registers that could be reloaded and zeroed the others. | ||
1371 | # Category 2 we fix up by killing the current process. We cannot use the | ||
1372 | # normal Linux return path in this case because if we use the IRET hypercall | ||
1373 | # to pop the stack frame we end up in an infinite loop of failsafe callbacks. | ||
1374 | # We distinguish between categories by comparing each saved segment register | ||
1375 | # with its current contents: any discrepancy means we in category 1. | ||
1376 | */ | ||
1377 | ENTRY(xen_failsafe_callback) | ||
1378 | framesz = (RIP-0x30) /* workaround buggy gas */ | ||
1379 | _frame framesz | ||
1380 | CFI_REL_OFFSET rcx, 0 | ||
1381 | CFI_REL_OFFSET r11, 8 | ||
1382 | movw %ds,%cx | ||
1383 | cmpw %cx,0x10(%rsp) | ||
1384 | CFI_REMEMBER_STATE | ||
1385 | jne 1f | ||
1386 | movw %es,%cx | ||
1387 | cmpw %cx,0x18(%rsp) | ||
1388 | jne 1f | ||
1389 | movw %fs,%cx | ||
1390 | cmpw %cx,0x20(%rsp) | ||
1391 | jne 1f | ||
1392 | movw %gs,%cx | ||
1393 | cmpw %cx,0x28(%rsp) | ||
1394 | jne 1f | ||
1395 | /* All segments match their saved values => Category 2 (Bad IRET). */ | ||
1396 | movq (%rsp),%rcx | ||
1397 | CFI_RESTORE rcx | ||
1398 | movq 8(%rsp),%r11 | ||
1399 | CFI_RESTORE r11 | ||
1400 | addq $0x30,%rsp | ||
1401 | CFI_ADJUST_CFA_OFFSET -0x30 | ||
1402 | pushq $0 | ||
1403 | CFI_ADJUST_CFA_OFFSET 8 | ||
1404 | pushq %r11 | ||
1405 | CFI_ADJUST_CFA_OFFSET 8 | ||
1406 | pushq %rcx | ||
1407 | CFI_ADJUST_CFA_OFFSET 8 | ||
1408 | jmp general_protection | ||
1409 | CFI_RESTORE_STATE | ||
1410 | 1: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */ | ||
1411 | movq (%rsp),%rcx | ||
1412 | CFI_RESTORE rcx | ||
1413 | movq 8(%rsp),%r11 | ||
1414 | CFI_RESTORE r11 | ||
1415 | addq $0x30,%rsp | ||
1416 | CFI_ADJUST_CFA_OFFSET -0x30 | ||
1417 | pushq $0 | ||
1418 | CFI_ADJUST_CFA_OFFSET 8 | ||
1419 | SAVE_ALL | ||
1420 | jmp error_exit | ||
1421 | CFI_ENDPROC | ||
1422 | END(xen_failsafe_callback) | ||
1423 | |||
1424 | #endif /* CONFIG_XEN */ | ||