diff options
Diffstat (limited to 'arch/i386/kernel/entry.S')
-rw-r--r-- | arch/i386/kernel/entry.S | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 3c3c220488c9..ffb236544270 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S | |||
@@ -1023,6 +1023,77 @@ ENTRY(kernel_thread_helper) | |||
1023 | CFI_ENDPROC | 1023 | CFI_ENDPROC |
1024 | ENDPROC(kernel_thread_helper) | 1024 | ENDPROC(kernel_thread_helper) |
1025 | 1025 | ||
1026 | #ifdef CONFIG_XEN | ||
1027 | ENTRY(xen_hypervisor_callback) | ||
1028 | CFI_STARTPROC | ||
1029 | pushl $0 | ||
1030 | CFI_ADJUST_CFA_OFFSET 4 | ||
1031 | SAVE_ALL | ||
1032 | TRACE_IRQS_OFF | ||
1033 | mov %esp, %eax | ||
1034 | call xen_evtchn_do_upcall | ||
1035 | jmp ret_from_intr | ||
1036 | CFI_ENDPROC | ||
1037 | ENDPROC(xen_hypervisor_callback) | ||
1038 | |||
1039 | # Hypervisor uses this for application faults while it executes. | ||
1040 | # We get here for two reasons: | ||
1041 | # 1. Fault while reloading DS, ES, FS or GS | ||
1042 | # 2. Fault while executing IRET | ||
1043 | # Category 1 we fix up by reattempting the load, and zeroing the segment | ||
1044 | # register if the load fails. | ||
1045 | # Category 2 we fix up by jumping to do_iret_error. We cannot use the | ||
1046 | # normal Linux return path in this case because if we use the IRET hypercall | ||
1047 | # to pop the stack frame we end up in an infinite loop of failsafe callbacks. | ||
1048 | # We distinguish between categories by maintaining a status value in EAX. | ||
1049 | ENTRY(xen_failsafe_callback) | ||
1050 | CFI_STARTPROC | ||
1051 | pushl %eax | ||
1052 | CFI_ADJUST_CFA_OFFSET 4 | ||
1053 | movl $1,%eax | ||
1054 | 1: mov 4(%esp),%ds | ||
1055 | 2: mov 8(%esp),%es | ||
1056 | 3: mov 12(%esp),%fs | ||
1057 | 4: mov 16(%esp),%gs | ||
1058 | testl %eax,%eax | ||
1059 | popl %eax | ||
1060 | CFI_ADJUST_CFA_OFFSET -4 | ||
1061 | lea 16(%esp),%esp | ||
1062 | CFI_ADJUST_CFA_OFFSET -16 | ||
1063 | jz 5f | ||
1064 | addl $16,%esp | ||
1065 | jmp iret_exc # EAX != 0 => Category 2 (Bad IRET) | ||
1066 | 5: pushl $0 # EAX == 0 => Category 1 (Bad segment) | ||
1067 | CFI_ADJUST_CFA_OFFSET 4 | ||
1068 | SAVE_ALL | ||
1069 | jmp ret_from_exception | ||
1070 | CFI_ENDPROC | ||
1071 | |||
1072 | .section .fixup,"ax" | ||
1073 | 6: xorl %eax,%eax | ||
1074 | movl %eax,4(%esp) | ||
1075 | jmp 1b | ||
1076 | 7: xorl %eax,%eax | ||
1077 | movl %eax,8(%esp) | ||
1078 | jmp 2b | ||
1079 | 8: xorl %eax,%eax | ||
1080 | movl %eax,12(%esp) | ||
1081 | jmp 3b | ||
1082 | 9: xorl %eax,%eax | ||
1083 | movl %eax,16(%esp) | ||
1084 | jmp 4b | ||
1085 | .previous | ||
1086 | .section __ex_table,"a" | ||
1087 | .align 4 | ||
1088 | .long 1b,6b | ||
1089 | .long 2b,7b | ||
1090 | .long 3b,8b | ||
1091 | .long 4b,9b | ||
1092 | .previous | ||
1093 | ENDPROC(xen_failsafe_callback) | ||
1094 | |||
1095 | #endif /* CONFIG_XEN */ | ||
1096 | |||
1026 | .section .rodata,"a" | 1097 | .section .rodata,"a" |
1027 | #include "syscall_table.S" | 1098 | #include "syscall_table.S" |
1028 | 1099 | ||