aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/entry_64.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/entry_64.S')
-rw-r--r--arch/x86/kernel/entry_64.S106
1 files changed, 106 insertions, 0 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index ae63e584c340..80d5663db3bc 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1189,6 +1189,7 @@ END(device_not_available)
1189 /* runs on exception stack */ 1189 /* runs on exception stack */
1190KPROBE_ENTRY(debug) 1190KPROBE_ENTRY(debug)
1191 INTR_FRAME 1191 INTR_FRAME
1192 PARAVIRT_ADJUST_EXCEPTION_FRAME
1192 pushq $0 1193 pushq $0
1193 CFI_ADJUST_CFA_OFFSET 8 1194 CFI_ADJUST_CFA_OFFSET 8
1194 paranoidentry do_debug, DEBUG_STACK 1195 paranoidentry do_debug, DEBUG_STACK
@@ -1198,6 +1199,7 @@ KPROBE_END(debug)
1198 /* runs on exception stack */ 1199 /* runs on exception stack */
1199KPROBE_ENTRY(nmi) 1200KPROBE_ENTRY(nmi)
1200 INTR_FRAME 1201 INTR_FRAME
1202 PARAVIRT_ADJUST_EXCEPTION_FRAME
1201 pushq $-1 1203 pushq $-1
1202 CFI_ADJUST_CFA_OFFSET 8 1204 CFI_ADJUST_CFA_OFFSET 8
1203 paranoidentry do_nmi, 0, 0 1205 paranoidentry do_nmi, 0, 0
@@ -1211,6 +1213,7 @@ KPROBE_END(nmi)
1211 1213
1212KPROBE_ENTRY(int3) 1214KPROBE_ENTRY(int3)
1213 INTR_FRAME 1215 INTR_FRAME
1216 PARAVIRT_ADJUST_EXCEPTION_FRAME
1214 pushq $0 1217 pushq $0
1215 CFI_ADJUST_CFA_OFFSET 8 1218 CFI_ADJUST_CFA_OFFSET 8
1216 paranoidentry do_int3, DEBUG_STACK 1219 paranoidentry do_int3, DEBUG_STACK
@@ -1237,6 +1240,7 @@ END(coprocessor_segment_overrun)
1237 /* runs on exception stack */ 1240 /* runs on exception stack */
1238ENTRY(double_fault) 1241ENTRY(double_fault)
1239 XCPT_FRAME 1242 XCPT_FRAME
1243 PARAVIRT_ADJUST_EXCEPTION_FRAME
1240 paranoidentry do_double_fault 1244 paranoidentry do_double_fault
1241 jmp paranoid_exit1 1245 jmp paranoid_exit1
1242 CFI_ENDPROC 1246 CFI_ENDPROC
@@ -1253,6 +1257,7 @@ END(segment_not_present)
1253 /* runs on exception stack */ 1257 /* runs on exception stack */
1254ENTRY(stack_segment) 1258ENTRY(stack_segment)
1255 XCPT_FRAME 1259 XCPT_FRAME
1260 PARAVIRT_ADJUST_EXCEPTION_FRAME
1256 paranoidentry do_stack_segment 1261 paranoidentry do_stack_segment
1257 jmp paranoid_exit1 1262 jmp paranoid_exit1
1258 CFI_ENDPROC 1263 CFI_ENDPROC
@@ -1278,6 +1283,7 @@ END(spurious_interrupt_bug)
1278 /* runs on exception stack */ 1283 /* runs on exception stack */
1279ENTRY(machine_check) 1284ENTRY(machine_check)
1280 INTR_FRAME 1285 INTR_FRAME
1286 PARAVIRT_ADJUST_EXCEPTION_FRAME
1281 pushq $0 1287 pushq $0
1282 CFI_ADJUST_CFA_OFFSET 8 1288 CFI_ADJUST_CFA_OFFSET 8
1283 paranoidentry do_machine_check 1289 paranoidentry do_machine_check
@@ -1312,3 +1318,103 @@ KPROBE_ENTRY(ignore_sysret)
1312 sysret 1318 sysret
1313 CFI_ENDPROC 1319 CFI_ENDPROC
1314ENDPROC(ignore_sysret) 1320ENDPROC(ignore_sysret)
1321
1322#ifdef CONFIG_XEN
1323ENTRY(xen_hypervisor_callback)
1324 zeroentry xen_do_hypervisor_callback
1325END(xen_hypervisor_callback)
1326
1327/*
1328# A note on the "critical region" in our callback handler.
1329# We want to avoid stacking callback handlers due to events occurring
1330# during handling of the last event. To do this, we keep events disabled
1331# until we've done all processing. HOWEVER, we must enable events before
1332# popping the stack frame (can't be done atomically) and so it would still
1333# be possible to get enough handler activations to overflow the stack.
1334# Although unlikely, bugs of that kind are hard to track down, so we'd
1335# like to avoid the possibility.
1336# So, on entry to the handler we detect whether we interrupted an
1337# existing activation in its critical region -- if so, we pop the current
1338# activation and restart the handler using the previous one.
1339*/
1340ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs)
1341 CFI_STARTPROC
1342/* Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will
1343 see the correct pointer to the pt_regs */
1344 movq %rdi, %rsp # we don't return, adjust the stack frame
1345 CFI_ENDPROC
1346 CFI_DEFAULT_STACK
134711: incl %gs:pda_irqcount
1348 movq %rsp,%rbp
1349 CFI_DEF_CFA_REGISTER rbp
1350 cmovzq %gs:pda_irqstackptr,%rsp
1351 pushq %rbp # backlink for old unwinder
1352 call xen_evtchn_do_upcall
1353 popq %rsp
1354 CFI_DEF_CFA_REGISTER rsp
1355 decl %gs:pda_irqcount
1356 jmp error_exit
1357 CFI_ENDPROC
1358END(do_hypervisor_callback)
1359
1360/*
1361# Hypervisor uses this for application faults while it executes.
1362# We get here for two reasons:
1363# 1. Fault while reloading DS, ES, FS or GS
1364# 2. Fault while executing IRET
1365# Category 1 we do not need to fix up as Xen has already reloaded all segment
1366# registers that could be reloaded and zeroed the others.
1367# Category 2 we fix up by killing the current process. We cannot use the
1368# normal Linux return path in this case because if we use the IRET hypercall
1369# to pop the stack frame we end up in an infinite loop of failsafe callbacks.
1370# We distinguish between categories by comparing each saved segment register
1371# with its current contents: any discrepancy means we in category 1.
1372*/
1373ENTRY(xen_failsafe_callback)
1374 framesz = (RIP-0x30) /* workaround buggy gas */
1375 _frame framesz
1376 CFI_REL_OFFSET rcx, 0
1377 CFI_REL_OFFSET r11, 8
1378 movw %ds,%cx
1379 cmpw %cx,0x10(%rsp)
1380 CFI_REMEMBER_STATE
1381 jne 1f
1382 movw %es,%cx
1383 cmpw %cx,0x18(%rsp)
1384 jne 1f
1385 movw %fs,%cx
1386 cmpw %cx,0x20(%rsp)
1387 jne 1f
1388 movw %gs,%cx
1389 cmpw %cx,0x28(%rsp)
1390 jne 1f
1391 /* All segments match their saved values => Category 2 (Bad IRET). */
1392 movq (%rsp),%rcx
1393 CFI_RESTORE rcx
1394 movq 8(%rsp),%r11
1395 CFI_RESTORE r11
1396 addq $0x30,%rsp
1397 CFI_ADJUST_CFA_OFFSET -0x30
1398 pushq $0
1399 CFI_ADJUST_CFA_OFFSET 8
1400 pushq %r11
1401 CFI_ADJUST_CFA_OFFSET 8
1402 pushq %rcx
1403 CFI_ADJUST_CFA_OFFSET 8
1404 jmp general_protection
1405 CFI_RESTORE_STATE
14061: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */
1407 movq (%rsp),%rcx
1408 CFI_RESTORE rcx
1409 movq 8(%rsp),%r11
1410 CFI_RESTORE r11
1411 addq $0x30,%rsp
1412 CFI_ADJUST_CFA_OFFSET -0x30
1413 pushq $0
1414 CFI_ADJUST_CFA_OFFSET 8
1415 SAVE_ALL
1416 jmp error_exit
1417 CFI_ENDPROC
1418END(xen_failsafe_callback)
1419
1420#endif /* CONFIG_XEN */