aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel')
-rw-r--r--arch/i386/kernel/entry.S71
-rw-r--r--arch/i386/kernel/head.S5
-rw-r--r--arch/i386/kernel/vmlinux.lds.S1
3 files changed, 76 insertions, 1 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
1024ENDPROC(kernel_thread_helper) 1024ENDPROC(kernel_thread_helper)
1025 1025
1026#ifdef CONFIG_XEN
1027ENTRY(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
1037ENDPROC(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.
1049ENTRY(xen_failsafe_callback)
1050 CFI_STARTPROC
1051 pushl %eax
1052 CFI_ADJUST_CFA_OFFSET 4
1053 movl $1,%eax
10541: mov 4(%esp),%ds
10552: mov 8(%esp),%es
10563: mov 12(%esp),%fs
10574: 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)
10665: 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"
10736: xorl %eax,%eax
1074 movl %eax,4(%esp)
1075 jmp 1b
10767: xorl %eax,%eax
1077 movl %eax,8(%esp)
1078 jmp 2b
10798: xorl %eax,%eax
1080 movl %eax,12(%esp)
1081 jmp 3b
10829: 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
1093ENDPROC(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
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index 82714668d43b..7c52b222207e 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -510,7 +510,8 @@ ENTRY(_stext)
510/* 510/*
511 * BSS section 511 * BSS section
512 */ 512 */
513.section ".bss.page_aligned","w" 513.section ".bss.page_aligned","wa"
514 .align PAGE_SIZE_asm
514ENTRY(swapper_pg_dir) 515ENTRY(swapper_pg_dir)
515 .fill 1024,4,0 516 .fill 1024,4,0
516ENTRY(swapper_pg_pmd) 517ENTRY(swapper_pg_pmd)
@@ -538,6 +539,8 @@ fault_msg:
538 .ascii "Int %d: CR2 %p err %p EIP %p CS %p flags %p\n" 539 .ascii "Int %d: CR2 %p err %p EIP %p CS %p flags %p\n"
539 .asciz "Stack: %p %p %p %p %p %p %p %p\n" 540 .asciz "Stack: %p %p %p %p %p %p %p %p\n"
540 541
542#include "../xen/xen-head.S"
543
541/* 544/*
542 * The IDT and GDT 'descriptors' are a strange 48-bit object 545 * The IDT and GDT 'descriptors' are a strange 48-bit object
543 * only used by the lidt and lgdt instructions. They are not 546 * only used by the lidt and lgdt instructions. They are not
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index aa87b06c7c82..00f1bc47d3a2 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -88,6 +88,7 @@ SECTIONS
88 88
89 . = ALIGN(4096); 89 . = ALIGN(4096);
90 .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { 90 .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
91 *(.data.page_aligned)
91 *(.data.idt) 92 *(.data.idt)
92 } 93 }
93 94