diff options
Diffstat (limited to 'arch/i386/kernel')
-rw-r--r-- | arch/i386/kernel/entry.S | 71 | ||||
-rw-r--r-- | arch/i386/kernel/head.S | 5 | ||||
-rw-r--r-- | arch/i386/kernel/vmlinux.lds.S | 1 |
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 |
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 | ||
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 | ||
514 | ENTRY(swapper_pg_dir) | 515 | ENTRY(swapper_pg_dir) |
515 | .fill 1024,4,0 | 516 | .fill 1024,4,0 |
516 | ENTRY(swapper_pg_pmd) | 517 | ENTRY(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 | ||