diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 16:07:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 16:07:55 -0400 |
commit | b278240839e20fa9384ea430df463b367b90e04e (patch) | |
tree | f99f0c8cdd4cc7f177cd75440e6bd181cded7fb3 /arch/i386/kernel/traps.c | |
parent | dd77a4ee0f3981693d4229aa1d57cea9e526ff47 (diff) | |
parent | 3f75f42d7733e73aca5c78326489efd4189e0111 (diff) |
Merge branch 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6
* 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6: (225 commits)
[PATCH] Don't set calgary iommu as default y
[PATCH] i386/x86-64: New Intel feature flags
[PATCH] x86: Add a cumulative thermal throttle event counter.
[PATCH] i386: Make the jiffies compares use the 64bit safe macros.
[PATCH] x86: Refactor thermal throttle processing
[PATCH] Add 64bit jiffies compares (for use with get_jiffies_64)
[PATCH] Fix unwinder warning in traps.c
[PATCH] x86: Allow disabling early pci scans with pci=noearly or disallowing conf1
[PATCH] x86: Move direct PCI scanning functions out of line
[PATCH] i386/x86-64: Make all early PCI scans dependent on CONFIG_PCI
[PATCH] Don't leak NT bit into next task
[PATCH] i386/x86-64: Work around gcc bug with noreturn functions in unwinder
[PATCH] Fix some broken white space in ia32_signal.c
[PATCH] Initialize argument registers for 32bit signal handlers.
[PATCH] Remove all traces of signal number conversion
[PATCH] Don't synchronize time reading on single core AMD systems
[PATCH] Remove outdated comment in x86-64 mmconfig code
[PATCH] Use string instructions for Core2 copy/clear
[PATCH] x86: - restore i8259A eoi status on resume
[PATCH] i386: Split multi-line printk in oops output.
...
Diffstat (limited to 'arch/i386/kernel/traps.c')
-rw-r--r-- | arch/i386/kernel/traps.c | 224 |
1 files changed, 130 insertions, 94 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 4fcc6690be99..21aa1cd57773 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <asm/smp.h> | 51 | #include <asm/smp.h> |
52 | #include <asm/arch_hooks.h> | 52 | #include <asm/arch_hooks.h> |
53 | #include <asm/kdebug.h> | 53 | #include <asm/kdebug.h> |
54 | #include <asm/stacktrace.h> | ||
54 | 55 | ||
55 | #include <linux/module.h> | 56 | #include <linux/module.h> |
56 | 57 | ||
@@ -118,26 +119,16 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) | |||
118 | p < (void *)tinfo + THREAD_SIZE - 3; | 119 | p < (void *)tinfo + THREAD_SIZE - 3; |
119 | } | 120 | } |
120 | 121 | ||
121 | /* | ||
122 | * Print one address/symbol entries per line. | ||
123 | */ | ||
124 | static inline void print_addr_and_symbol(unsigned long addr, char *log_lvl) | ||
125 | { | ||
126 | printk(" [<%08lx>] ", addr); | ||
127 | |||
128 | print_symbol("%s\n", addr); | ||
129 | } | ||
130 | |||
131 | static inline unsigned long print_context_stack(struct thread_info *tinfo, | 122 | static inline unsigned long print_context_stack(struct thread_info *tinfo, |
132 | unsigned long *stack, unsigned long ebp, | 123 | unsigned long *stack, unsigned long ebp, |
133 | char *log_lvl) | 124 | struct stacktrace_ops *ops, void *data) |
134 | { | 125 | { |
135 | unsigned long addr; | 126 | unsigned long addr; |
136 | 127 | ||
137 | #ifdef CONFIG_FRAME_POINTER | 128 | #ifdef CONFIG_FRAME_POINTER |
138 | while (valid_stack_ptr(tinfo, (void *)ebp)) { | 129 | while (valid_stack_ptr(tinfo, (void *)ebp)) { |
139 | addr = *(unsigned long *)(ebp + 4); | 130 | addr = *(unsigned long *)(ebp + 4); |
140 | print_addr_and_symbol(addr, log_lvl); | 131 | ops->address(data, addr); |
141 | /* | 132 | /* |
142 | * break out of recursive entries (such as | 133 | * break out of recursive entries (such as |
143 | * end_of_stack_stop_unwind_function): | 134 | * end_of_stack_stop_unwind_function): |
@@ -150,30 +141,37 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, | |||
150 | while (valid_stack_ptr(tinfo, stack)) { | 141 | while (valid_stack_ptr(tinfo, stack)) { |
151 | addr = *stack++; | 142 | addr = *stack++; |
152 | if (__kernel_text_address(addr)) | 143 | if (__kernel_text_address(addr)) |
153 | print_addr_and_symbol(addr, log_lvl); | 144 | ops->address(data, addr); |
154 | } | 145 | } |
155 | #endif | 146 | #endif |
156 | return ebp; | 147 | return ebp; |
157 | } | 148 | } |
158 | 149 | ||
150 | struct ops_and_data { | ||
151 | struct stacktrace_ops *ops; | ||
152 | void *data; | ||
153 | }; | ||
154 | |||
159 | static asmlinkage int | 155 | static asmlinkage int |
160 | show_trace_unwind(struct unwind_frame_info *info, void *log_lvl) | 156 | dump_trace_unwind(struct unwind_frame_info *info, void *data) |
161 | { | 157 | { |
158 | struct ops_and_data *oad = (struct ops_and_data *)data; | ||
162 | int n = 0; | 159 | int n = 0; |
163 | 160 | ||
164 | while (unwind(info) == 0 && UNW_PC(info)) { | 161 | while (unwind(info) == 0 && UNW_PC(info)) { |
165 | n++; | 162 | n++; |
166 | print_addr_and_symbol(UNW_PC(info), log_lvl); | 163 | oad->ops->address(oad->data, UNW_PC(info)); |
167 | if (arch_unw_user_mode(info)) | 164 | if (arch_unw_user_mode(info)) |
168 | break; | 165 | break; |
169 | } | 166 | } |
170 | return n; | 167 | return n; |
171 | } | 168 | } |
172 | 169 | ||
173 | static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | 170 | void dump_trace(struct task_struct *task, struct pt_regs *regs, |
174 | unsigned long *stack, char *log_lvl) | 171 | unsigned long *stack, |
172 | struct stacktrace_ops *ops, void *data) | ||
175 | { | 173 | { |
176 | unsigned long ebp; | 174 | unsigned long ebp = 0; |
177 | 175 | ||
178 | if (!task) | 176 | if (!task) |
179 | task = current; | 177 | task = current; |
@@ -181,54 +179,116 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
181 | if (call_trace >= 0) { | 179 | if (call_trace >= 0) { |
182 | int unw_ret = 0; | 180 | int unw_ret = 0; |
183 | struct unwind_frame_info info; | 181 | struct unwind_frame_info info; |
182 | struct ops_and_data oad = { .ops = ops, .data = data }; | ||
184 | 183 | ||
185 | if (regs) { | 184 | if (regs) { |
186 | if (unwind_init_frame_info(&info, task, regs) == 0) | 185 | if (unwind_init_frame_info(&info, task, regs) == 0) |
187 | unw_ret = show_trace_unwind(&info, log_lvl); | 186 | unw_ret = dump_trace_unwind(&info, &oad); |
188 | } else if (task == current) | 187 | } else if (task == current) |
189 | unw_ret = unwind_init_running(&info, show_trace_unwind, log_lvl); | 188 | unw_ret = unwind_init_running(&info, dump_trace_unwind, &oad); |
190 | else { | 189 | else { |
191 | if (unwind_init_blocked(&info, task) == 0) | 190 | if (unwind_init_blocked(&info, task) == 0) |
192 | unw_ret = show_trace_unwind(&info, log_lvl); | 191 | unw_ret = dump_trace_unwind(&info, &oad); |
193 | } | 192 | } |
194 | if (unw_ret > 0) { | 193 | if (unw_ret > 0) { |
195 | if (call_trace == 1 && !arch_unw_user_mode(&info)) { | 194 | if (call_trace == 1 && !arch_unw_user_mode(&info)) { |
196 | print_symbol("DWARF2 unwinder stuck at %s\n", | 195 | ops->warning_symbol(data, "DWARF2 unwinder stuck at %s\n", |
197 | UNW_PC(&info)); | 196 | UNW_PC(&info)); |
198 | if (UNW_SP(&info) >= PAGE_OFFSET) { | 197 | if (UNW_SP(&info) >= PAGE_OFFSET) { |
199 | printk("Leftover inexact backtrace:\n"); | 198 | ops->warning(data, "Leftover inexact backtrace:\n"); |
200 | stack = (void *)UNW_SP(&info); | 199 | stack = (void *)UNW_SP(&info); |
200 | if (!stack) | ||
201 | return; | ||
202 | ebp = UNW_FP(&info); | ||
201 | } else | 203 | } else |
202 | printk("Full inexact backtrace again:\n"); | 204 | ops->warning(data, "Full inexact backtrace again:\n"); |
203 | } else if (call_trace >= 1) | 205 | } else if (call_trace >= 1) |
204 | return; | 206 | return; |
205 | else | 207 | else |
206 | printk("Full inexact backtrace again:\n"); | 208 | ops->warning(data, "Full inexact backtrace again:\n"); |
207 | } else | 209 | } else |
208 | printk("Inexact backtrace:\n"); | 210 | ops->warning(data, "Inexact backtrace:\n"); |
211 | } | ||
212 | if (!stack) { | ||
213 | unsigned long dummy; | ||
214 | stack = &dummy; | ||
215 | if (task && task != current) | ||
216 | stack = (unsigned long *)task->thread.esp; | ||
209 | } | 217 | } |
210 | 218 | ||
211 | if (task == current) { | 219 | #ifdef CONFIG_FRAME_POINTER |
212 | /* Grab ebp right from our regs */ | 220 | if (!ebp) { |
213 | asm ("movl %%ebp, %0" : "=r" (ebp) : ); | 221 | if (task == current) { |
214 | } else { | 222 | /* Grab ebp right from our regs */ |
215 | /* ebp is the last reg pushed by switch_to */ | 223 | asm ("movl %%ebp, %0" : "=r" (ebp) : ); |
216 | ebp = *(unsigned long *) task->thread.esp; | 224 | } else { |
225 | /* ebp is the last reg pushed by switch_to */ | ||
226 | ebp = *(unsigned long *) task->thread.esp; | ||
227 | } | ||
217 | } | 228 | } |
229 | #endif | ||
218 | 230 | ||
219 | while (1) { | 231 | while (1) { |
220 | struct thread_info *context; | 232 | struct thread_info *context; |
221 | context = (struct thread_info *) | 233 | context = (struct thread_info *) |
222 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); | 234 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); |
223 | ebp = print_context_stack(context, stack, ebp, log_lvl); | 235 | ebp = print_context_stack(context, stack, ebp, ops, data); |
236 | /* Should be after the line below, but somewhere | ||
237 | in early boot context comes out corrupted and we | ||
238 | can't reference it -AK */ | ||
239 | if (ops->stack(data, "IRQ") < 0) | ||
240 | break; | ||
224 | stack = (unsigned long*)context->previous_esp; | 241 | stack = (unsigned long*)context->previous_esp; |
225 | if (!stack) | 242 | if (!stack) |
226 | break; | 243 | break; |
227 | printk("%s =======================\n", log_lvl); | ||
228 | } | 244 | } |
229 | } | 245 | } |
246 | EXPORT_SYMBOL(dump_trace); | ||
247 | |||
248 | static void | ||
249 | print_trace_warning_symbol(void *data, char *msg, unsigned long symbol) | ||
250 | { | ||
251 | printk(data); | ||
252 | print_symbol(msg, symbol); | ||
253 | printk("\n"); | ||
254 | } | ||
255 | |||
256 | static void print_trace_warning(void *data, char *msg) | ||
257 | { | ||
258 | printk("%s%s\n", (char *)data, msg); | ||
259 | } | ||
260 | |||
261 | static int print_trace_stack(void *data, char *name) | ||
262 | { | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | /* | ||
267 | * Print one address/symbol entries per line. | ||
268 | */ | ||
269 | static void print_trace_address(void *data, unsigned long addr) | ||
270 | { | ||
271 | printk("%s [<%08lx>] ", (char *)data, addr); | ||
272 | print_symbol("%s\n", addr); | ||
273 | } | ||
274 | |||
275 | static struct stacktrace_ops print_trace_ops = { | ||
276 | .warning = print_trace_warning, | ||
277 | .warning_symbol = print_trace_warning_symbol, | ||
278 | .stack = print_trace_stack, | ||
279 | .address = print_trace_address, | ||
280 | }; | ||
281 | |||
282 | static void | ||
283 | show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | ||
284 | unsigned long * stack, char *log_lvl) | ||
285 | { | ||
286 | dump_trace(task, regs, stack, &print_trace_ops, log_lvl); | ||
287 | printk("%s =======================\n", log_lvl); | ||
288 | } | ||
230 | 289 | ||
231 | void show_trace(struct task_struct *task, struct pt_regs *regs, unsigned long * stack) | 290 | void show_trace(struct task_struct *task, struct pt_regs *regs, |
291 | unsigned long * stack) | ||
232 | { | 292 | { |
233 | show_trace_log_lvl(task, regs, stack, ""); | 293 | show_trace_log_lvl(task, regs, stack, ""); |
234 | } | 294 | } |
@@ -291,8 +351,9 @@ void show_registers(struct pt_regs *regs) | |||
291 | ss = regs->xss & 0xffff; | 351 | ss = regs->xss & 0xffff; |
292 | } | 352 | } |
293 | print_modules(); | 353 | print_modules(); |
294 | printk(KERN_EMERG "CPU: %d\nEIP: %04x:[<%08lx>] %s VLI\n" | 354 | printk(KERN_EMERG "CPU: %d\n" |
295 | "EFLAGS: %08lx (%s %.*s) \n", | 355 | KERN_EMERG "EIP: %04x:[<%08lx>] %s VLI\n" |
356 | KERN_EMERG "EFLAGS: %08lx (%s %.*s)\n", | ||
296 | smp_processor_id(), 0xffff & regs->xcs, regs->eip, | 357 | smp_processor_id(), 0xffff & regs->xcs, regs->eip, |
297 | print_tainted(), regs->eflags, system_utsname.release, | 358 | print_tainted(), regs->eflags, system_utsname.release, |
298 | (int)strcspn(system_utsname.version, " "), | 359 | (int)strcspn(system_utsname.version, " "), |
@@ -634,18 +695,24 @@ gp_in_kernel: | |||
634 | } | 695 | } |
635 | } | 696 | } |
636 | 697 | ||
637 | static void mem_parity_error(unsigned char reason, struct pt_regs * regs) | 698 | static __kprobes void |
699 | mem_parity_error(unsigned char reason, struct pt_regs * regs) | ||
638 | { | 700 | { |
639 | printk(KERN_EMERG "Uhhuh. NMI received. Dazed and confused, but trying " | 701 | printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x on " |
640 | "to continue\n"); | 702 | "CPU %d.\n", reason, smp_processor_id()); |
641 | printk(KERN_EMERG "You probably have a hardware problem with your RAM " | 703 | printk(KERN_EMERG "You probably have a hardware problem with your RAM " |
642 | "chips\n"); | 704 | "chips\n"); |
705 | if (panic_on_unrecovered_nmi) | ||
706 | panic("NMI: Not continuing"); | ||
707 | |||
708 | printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); | ||
643 | 709 | ||
644 | /* Clear and disable the memory parity error line. */ | 710 | /* Clear and disable the memory parity error line. */ |
645 | clear_mem_error(reason); | 711 | clear_mem_error(reason); |
646 | } | 712 | } |
647 | 713 | ||
648 | static void io_check_error(unsigned char reason, struct pt_regs * regs) | 714 | static __kprobes void |
715 | io_check_error(unsigned char reason, struct pt_regs * regs) | ||
649 | { | 716 | { |
650 | unsigned long i; | 717 | unsigned long i; |
651 | 718 | ||
@@ -661,7 +728,8 @@ static void io_check_error(unsigned char reason, struct pt_regs * regs) | |||
661 | outb(reason, 0x61); | 728 | outb(reason, 0x61); |
662 | } | 729 | } |
663 | 730 | ||
664 | static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) | 731 | static __kprobes void |
732 | unknown_nmi_error(unsigned char reason, struct pt_regs * regs) | ||
665 | { | 733 | { |
666 | #ifdef CONFIG_MCA | 734 | #ifdef CONFIG_MCA |
667 | /* Might actually be able to figure out what the guilty party | 735 | /* Might actually be able to figure out what the guilty party |
@@ -671,15 +739,18 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) | |||
671 | return; | 739 | return; |
672 | } | 740 | } |
673 | #endif | 741 | #endif |
674 | printk("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n", | 742 | printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x on " |
675 | reason, smp_processor_id()); | 743 | "CPU %d.\n", reason, smp_processor_id()); |
676 | printk("Dazed and confused, but trying to continue\n"); | 744 | printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n"); |
677 | printk("Do you have a strange power saving mode enabled?\n"); | 745 | if (panic_on_unrecovered_nmi) |
746 | panic("NMI: Not continuing"); | ||
747 | |||
748 | printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); | ||
678 | } | 749 | } |
679 | 750 | ||
680 | static DEFINE_SPINLOCK(nmi_print_lock); | 751 | static DEFINE_SPINLOCK(nmi_print_lock); |
681 | 752 | ||
682 | void die_nmi (struct pt_regs *regs, const char *msg) | 753 | void __kprobes die_nmi(struct pt_regs *regs, const char *msg) |
683 | { | 754 | { |
684 | if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 2, SIGINT) == | 755 | if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 2, SIGINT) == |
685 | NOTIFY_STOP) | 756 | NOTIFY_STOP) |
@@ -711,7 +782,7 @@ void die_nmi (struct pt_regs *regs, const char *msg) | |||
711 | do_exit(SIGSEGV); | 782 | do_exit(SIGSEGV); |
712 | } | 783 | } |
713 | 784 | ||
714 | static void default_do_nmi(struct pt_regs * regs) | 785 | static __kprobes void default_do_nmi(struct pt_regs * regs) |
715 | { | 786 | { |
716 | unsigned char reason = 0; | 787 | unsigned char reason = 0; |
717 | 788 | ||
@@ -728,12 +799,12 @@ static void default_do_nmi(struct pt_regs * regs) | |||
728 | * Ok, so this is none of the documented NMI sources, | 799 | * Ok, so this is none of the documented NMI sources, |
729 | * so it must be the NMI watchdog. | 800 | * so it must be the NMI watchdog. |
730 | */ | 801 | */ |
731 | if (nmi_watchdog) { | 802 | if (nmi_watchdog_tick(regs, reason)) |
732 | nmi_watchdog_tick(regs); | ||
733 | return; | 803 | return; |
734 | } | 804 | if (!do_nmi_callback(regs, smp_processor_id())) |
735 | #endif | 805 | #endif |
736 | unknown_nmi_error(reason, regs); | 806 | unknown_nmi_error(reason, regs); |
807 | |||
737 | return; | 808 | return; |
738 | } | 809 | } |
739 | if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) | 810 | if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) |
@@ -749,14 +820,7 @@ static void default_do_nmi(struct pt_regs * regs) | |||
749 | reassert_nmi(); | 820 | reassert_nmi(); |
750 | } | 821 | } |
751 | 822 | ||
752 | static int dummy_nmi_callback(struct pt_regs * regs, int cpu) | 823 | fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code) |
753 | { | ||
754 | return 0; | ||
755 | } | ||
756 | |||
757 | static nmi_callback_t nmi_callback = dummy_nmi_callback; | ||
758 | |||
759 | fastcall void do_nmi(struct pt_regs * regs, long error_code) | ||
760 | { | 824 | { |
761 | int cpu; | 825 | int cpu; |
762 | 826 | ||
@@ -766,25 +830,11 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code) | |||
766 | 830 | ||
767 | ++nmi_count(cpu); | 831 | ++nmi_count(cpu); |
768 | 832 | ||
769 | if (!rcu_dereference(nmi_callback)(regs, cpu)) | 833 | default_do_nmi(regs); |
770 | default_do_nmi(regs); | ||
771 | 834 | ||
772 | nmi_exit(); | 835 | nmi_exit(); |
773 | } | 836 | } |
774 | 837 | ||
775 | void set_nmi_callback(nmi_callback_t callback) | ||
776 | { | ||
777 | vmalloc_sync_all(); | ||
778 | rcu_assign_pointer(nmi_callback, callback); | ||
779 | } | ||
780 | EXPORT_SYMBOL_GPL(set_nmi_callback); | ||
781 | |||
782 | void unset_nmi_callback(void) | ||
783 | { | ||
784 | nmi_callback = dummy_nmi_callback; | ||
785 | } | ||
786 | EXPORT_SYMBOL_GPL(unset_nmi_callback); | ||
787 | |||
788 | #ifdef CONFIG_KPROBES | 838 | #ifdef CONFIG_KPROBES |
789 | fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) | 839 | fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) |
790 | { | 840 | { |
@@ -1124,20 +1174,6 @@ void __init trap_init_f00f_bug(void) | |||
1124 | } | 1174 | } |
1125 | #endif | 1175 | #endif |
1126 | 1176 | ||
1127 | #define _set_gate(gate_addr,type,dpl,addr,seg) \ | ||
1128 | do { \ | ||
1129 | int __d0, __d1; \ | ||
1130 | __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ | ||
1131 | "movw %4,%%dx\n\t" \ | ||
1132 | "movl %%eax,%0\n\t" \ | ||
1133 | "movl %%edx,%1" \ | ||
1134 | :"=m" (*((long *) (gate_addr))), \ | ||
1135 | "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \ | ||
1136 | :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ | ||
1137 | "3" ((char *) (addr)),"2" ((seg) << 16)); \ | ||
1138 | } while (0) | ||
1139 | |||
1140 | |||
1141 | /* | 1177 | /* |
1142 | * This needs to use 'idt_table' rather than 'idt', and | 1178 | * This needs to use 'idt_table' rather than 'idt', and |
1143 | * thus use the _nonmapped_ version of the IDT, as the | 1179 | * thus use the _nonmapped_ version of the IDT, as the |
@@ -1146,7 +1182,7 @@ do { \ | |||
1146 | */ | 1182 | */ |
1147 | void set_intr_gate(unsigned int n, void *addr) | 1183 | void set_intr_gate(unsigned int n, void *addr) |
1148 | { | 1184 | { |
1149 | _set_gate(idt_table+n,14,0,addr,__KERNEL_CS); | 1185 | _set_gate(n, DESCTYPE_INT, addr, __KERNEL_CS); |
1150 | } | 1186 | } |
1151 | 1187 | ||
1152 | /* | 1188 | /* |
@@ -1154,22 +1190,22 @@ void set_intr_gate(unsigned int n, void *addr) | |||
1154 | */ | 1190 | */ |
1155 | static inline void set_system_intr_gate(unsigned int n, void *addr) | 1191 | static inline void set_system_intr_gate(unsigned int n, void *addr) |
1156 | { | 1192 | { |
1157 | _set_gate(idt_table+n, 14, 3, addr, __KERNEL_CS); | 1193 | _set_gate(n, DESCTYPE_INT | DESCTYPE_DPL3, addr, __KERNEL_CS); |
1158 | } | 1194 | } |
1159 | 1195 | ||
1160 | static void __init set_trap_gate(unsigned int n, void *addr) | 1196 | static void __init set_trap_gate(unsigned int n, void *addr) |
1161 | { | 1197 | { |
1162 | _set_gate(idt_table+n,15,0,addr,__KERNEL_CS); | 1198 | _set_gate(n, DESCTYPE_TRAP, addr, __KERNEL_CS); |
1163 | } | 1199 | } |
1164 | 1200 | ||
1165 | static void __init set_system_gate(unsigned int n, void *addr) | 1201 | static void __init set_system_gate(unsigned int n, void *addr) |
1166 | { | 1202 | { |
1167 | _set_gate(idt_table+n,15,3,addr,__KERNEL_CS); | 1203 | _set_gate(n, DESCTYPE_TRAP | DESCTYPE_DPL3, addr, __KERNEL_CS); |
1168 | } | 1204 | } |
1169 | 1205 | ||
1170 | static void __init set_task_gate(unsigned int n, unsigned int gdt_entry) | 1206 | static void __init set_task_gate(unsigned int n, unsigned int gdt_entry) |
1171 | { | 1207 | { |
1172 | _set_gate(idt_table+n,5,0,0,(gdt_entry<<3)); | 1208 | _set_gate(n, DESCTYPE_TASK, (void *)0, (gdt_entry<<3)); |
1173 | } | 1209 | } |
1174 | 1210 | ||
1175 | 1211 | ||