diff options
Diffstat (limited to 'arch/ia64')
29 files changed, 734 insertions, 272 deletions
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 3dba24c318b7..b76ce1fe2e7f 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -168,6 +168,19 @@ config IA64_PAGE_SIZE_64KB | |||
168 | 168 | ||
169 | endchoice | 169 | endchoice |
170 | 170 | ||
171 | choice | ||
172 | prompt "Page Table Levels" | ||
173 | default PGTABLE_3 | ||
174 | |||
175 | config PGTABLE_3 | ||
176 | bool "3 Levels" | ||
177 | |||
178 | config PGTABLE_4 | ||
179 | depends on !IA64_PAGE_SIZE_64KB | ||
180 | bool "4 Levels" | ||
181 | |||
182 | endchoice | ||
183 | |||
171 | source kernel/Kconfig.hz | 184 | source kernel/Kconfig.hz |
172 | 185 | ||
173 | config IA64_BRL_EMU | 186 | config IA64_BRL_EMU |
@@ -195,6 +208,7 @@ config IOSAPIC | |||
195 | 208 | ||
196 | config IA64_SGI_SN_XP | 209 | config IA64_SGI_SN_XP |
197 | tristate "Support communication between SGI SSIs" | 210 | tristate "Support communication between SGI SSIs" |
211 | depends on IA64_GENERIC || IA64_SGI_SN2 | ||
198 | select IA64_UNCACHED_ALLOCATOR | 212 | select IA64_UNCACHED_ALLOCATOR |
199 | help | 213 | help |
200 | An SGI machine can be divided into multiple Single System | 214 | An SGI machine can be divided into multiple Single System |
@@ -430,8 +444,21 @@ config GENERIC_PENDING_IRQ | |||
430 | 444 | ||
431 | source "arch/ia64/hp/sim/Kconfig" | 445 | source "arch/ia64/hp/sim/Kconfig" |
432 | 446 | ||
447 | menu "Instrumentation Support" | ||
448 | depends on EXPERIMENTAL | ||
449 | |||
433 | source "arch/ia64/oprofile/Kconfig" | 450 | source "arch/ia64/oprofile/Kconfig" |
434 | 451 | ||
452 | config KPROBES | ||
453 | bool "Kprobes (EXPERIMENTAL)" | ||
454 | help | ||
455 | Kprobes allows you to trap at almost any kernel address and | ||
456 | execute a callback function. register_kprobe() establishes | ||
457 | a probepoint and specifies the callback. Kprobes is useful | ||
458 | for kernel debugging, non-intrusive instrumentation and testing. | ||
459 | If in doubt, say "N". | ||
460 | endmenu | ||
461 | |||
435 | source "arch/ia64/Kconfig.debug" | 462 | source "arch/ia64/Kconfig.debug" |
436 | 463 | ||
437 | source "security/Kconfig" | 464 | source "security/Kconfig" |
diff --git a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug index fda67ac993d7..de9d507ba0fd 100644 --- a/arch/ia64/Kconfig.debug +++ b/arch/ia64/Kconfig.debug | |||
@@ -2,17 +2,6 @@ menu "Kernel hacking" | |||
2 | 2 | ||
3 | source "lib/Kconfig.debug" | 3 | source "lib/Kconfig.debug" |
4 | 4 | ||
5 | config KPROBES | ||
6 | bool "Kprobes" | ||
7 | depends on DEBUG_KERNEL | ||
8 | help | ||
9 | Kprobes allows you to trap at almost any kernel address and | ||
10 | execute a callback function. register_kprobe() establishes | ||
11 | a probepoint and specifies the callback. Kprobes is useful | ||
12 | for kernel debugging, non-intrusive instrumentation and testing. | ||
13 | If in doubt, say "N". | ||
14 | |||
15 | |||
16 | choice | 5 | choice |
17 | prompt "Physical memory granularity" | 6 | prompt "Physical memory granularity" |
18 | default IA64_GRANULE_64MB | 7 | default IA64_GRANULE_64MB |
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig index 08112ab38468..87cfd31a4a39 100644 --- a/arch/ia64/configs/sn2_defconfig +++ b/arch/ia64/configs/sn2_defconfig | |||
@@ -80,6 +80,8 @@ CONFIG_MCKINLEY=y | |||
80 | # CONFIG_IA64_PAGE_SIZE_8KB is not set | 80 | # CONFIG_IA64_PAGE_SIZE_8KB is not set |
81 | CONFIG_IA64_PAGE_SIZE_16KB=y | 81 | CONFIG_IA64_PAGE_SIZE_16KB=y |
82 | # CONFIG_IA64_PAGE_SIZE_64KB is not set | 82 | # CONFIG_IA64_PAGE_SIZE_64KB is not set |
83 | # CONFIG_PGTABLE_3 is not set | ||
84 | CONFIG_PGTABLE_4=y | ||
83 | # CONFIG_HZ_100 is not set | 85 | # CONFIG_HZ_100 is not set |
84 | CONFIG_HZ_250=y | 86 | CONFIG_HZ_250=y |
85 | # CONFIG_HZ_1000 is not set | 87 | # CONFIG_HZ_1000 is not set |
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig index 6e3f147e03e5..275a26c6e5aa 100644 --- a/arch/ia64/defconfig +++ b/arch/ia64/defconfig | |||
@@ -82,6 +82,8 @@ CONFIG_MCKINLEY=y | |||
82 | # CONFIG_IA64_PAGE_SIZE_8KB is not set | 82 | # CONFIG_IA64_PAGE_SIZE_8KB is not set |
83 | CONFIG_IA64_PAGE_SIZE_16KB=y | 83 | CONFIG_IA64_PAGE_SIZE_16KB=y |
84 | # CONFIG_IA64_PAGE_SIZE_64KB is not set | 84 | # CONFIG_IA64_PAGE_SIZE_64KB is not set |
85 | CONFIG_PGTABLE_3=y | ||
86 | # CONFIG_PGTABLE_4 is not set | ||
85 | # CONFIG_HZ_100 is not set | 87 | # CONFIG_HZ_100 is not set |
86 | CONFIG_HZ_250=y | 88 | CONFIG_HZ_250=y |
87 | # CONFIG_HZ_1000 is not set | 89 | # CONFIG_HZ_1000 is not set |
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index b42ec37be51c..19ee635eeb70 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c | |||
@@ -642,10 +642,8 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
642 | info->event = 0; | 642 | info->event = 0; |
643 | info->tty = 0; | 643 | info->tty = 0; |
644 | if (info->blocked_open) { | 644 | if (info->blocked_open) { |
645 | if (info->close_delay) { | 645 | if (info->close_delay) |
646 | current->state = TASK_INTERRUPTIBLE; | 646 | schedule_timeout_interruptible(info->close_delay); |
647 | schedule_timeout(info->close_delay); | ||
648 | } | ||
649 | wake_up_interruptible(&info->open_wait); | 647 | wake_up_interruptible(&info->open_wait); |
650 | } | 648 | } |
651 | info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 649 | info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
diff --git a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c index 164b211f4174..88739394f6df 100644 --- a/arch/ia64/ia32/ia32_ioctl.c +++ b/arch/ia64/ia32/ia32_ioctl.c | |||
@@ -29,10 +29,8 @@ | |||
29 | #define CODE | 29 | #define CODE |
30 | #include "compat_ioctl.c" | 30 | #include "compat_ioctl.c" |
31 | 31 | ||
32 | typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *); | ||
33 | |||
34 | #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) | 32 | #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) |
35 | #define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl32_handler_t)(handler), NULL }, | 33 | #define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL }, |
36 | #define IOCTL_TABLE_START \ | 34 | #define IOCTL_TABLE_START \ |
37 | struct ioctl_trans ioctl_start[] = { | 35 | struct ioctl_trans ioctl_start[] = { |
38 | #define IOCTL_TABLE_END \ | 36 | #define IOCTL_TABLE_END \ |
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index f72ea6aebcb1..a3aa45cbcfa0 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c | |||
@@ -987,7 +987,7 @@ efi_initialize_iomem_resources(struct resource *code_resource, | |||
987 | break; | 987 | break; |
988 | } | 988 | } |
989 | 989 | ||
990 | if ((res = kcalloc(1, sizeof(struct resource), GFP_KERNEL)) == NULL) { | 990 | if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) { |
991 | printk(KERN_ERR "failed to alocate resource for iomem\n"); | 991 | printk(KERN_ERR "failed to alocate resource for iomem\n"); |
992 | return; | 992 | return; |
993 | } | 993 | } |
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index c13ca0d49c4a..e06f21f60dc5 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S | |||
@@ -114,7 +114,7 @@ ENTRY(vhpt_miss) | |||
114 | shl r21=r16,3 // shift bit 60 into sign bit | 114 | shl r21=r16,3 // shift bit 60 into sign bit |
115 | shr.u r17=r16,61 // get the region number into r17 | 115 | shr.u r17=r16,61 // get the region number into r17 |
116 | ;; | 116 | ;; |
117 | shr r22=r21,3 | 117 | shr.u r22=r21,3 |
118 | #ifdef CONFIG_HUGETLB_PAGE | 118 | #ifdef CONFIG_HUGETLB_PAGE |
119 | extr.u r26=r25,2,6 | 119 | extr.u r26=r25,2,6 |
120 | ;; | 120 | ;; |
@@ -140,20 +140,34 @@ ENTRY(vhpt_miss) | |||
140 | (p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 | 140 | (p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 |
141 | (p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) | 141 | (p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) |
142 | cmp.eq p7,p6=0,r21 // unused address bits all zeroes? | 142 | cmp.eq p7,p6=0,r21 // unused address bits all zeroes? |
143 | shr.u r18=r22,PMD_SHIFT // shift L2 index into position | 143 | #ifdef CONFIG_PGTABLE_4 |
144 | shr.u r28=r22,PUD_SHIFT // shift L2 index into position | ||
145 | #else | ||
146 | shr.u r18=r22,PMD_SHIFT // shift L3 index into position | ||
147 | #endif | ||
144 | ;; | 148 | ;; |
145 | ld8 r17=[r17] // fetch the L1 entry (may be 0) | 149 | ld8 r17=[r17] // fetch the L1 entry (may be 0) |
146 | ;; | 150 | ;; |
147 | (p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? | 151 | (p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? |
148 | dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry | 152 | #ifdef CONFIG_PGTABLE_4 |
153 | dep r28=r28,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry | ||
154 | ;; | ||
155 | shr.u r18=r22,PMD_SHIFT // shift L3 index into position | ||
156 | (p7) ld8 r29=[r28] // fetch the L2 entry (may be 0) | ||
149 | ;; | 157 | ;; |
150 | (p7) ld8 r20=[r17] // fetch the L2 entry (may be 0) | 158 | (p7) cmp.eq.or.andcm p6,p7=r29,r0 // was L2 entry NULL? |
151 | shr.u r19=r22,PAGE_SHIFT // shift L3 index into position | 159 | dep r17=r18,r29,3,(PAGE_SHIFT-3) // compute address of L3 page table entry |
160 | #else | ||
161 | dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L3 page table entry | ||
162 | #endif | ||
152 | ;; | 163 | ;; |
153 | (p7) cmp.eq.or.andcm p6,p7=r20,r0 // was L2 entry NULL? | 164 | (p7) ld8 r20=[r17] // fetch the L3 entry (may be 0) |
154 | dep r21=r19,r20,3,(PAGE_SHIFT-3) // compute address of L3 page table entry | 165 | shr.u r19=r22,PAGE_SHIFT // shift L4 index into position |
155 | ;; | 166 | ;; |
156 | (p7) ld8 r18=[r21] // read the L3 PTE | 167 | (p7) cmp.eq.or.andcm p6,p7=r20,r0 // was L3 entry NULL? |
168 | dep r21=r19,r20,3,(PAGE_SHIFT-3) // compute address of L4 page table entry | ||
169 | ;; | ||
170 | (p7) ld8 r18=[r21] // read the L4 PTE | ||
157 | mov r19=cr.isr // cr.isr bit 0 tells us if this is an insn miss | 171 | mov r19=cr.isr // cr.isr bit 0 tells us if this is an insn miss |
158 | ;; | 172 | ;; |
159 | (p7) tbit.z p6,p7=r18,_PAGE_P_BIT // page present bit cleared? | 173 | (p7) tbit.z p6,p7=r18,_PAGE_P_BIT // page present bit cleared? |
@@ -192,14 +206,21 @@ ENTRY(vhpt_miss) | |||
192 | * between reading the pagetable and the "itc". If so, flush the entry we | 206 | * between reading the pagetable and the "itc". If so, flush the entry we |
193 | * inserted and retry. | 207 | * inserted and retry. |
194 | */ | 208 | */ |
195 | ld8 r25=[r21] // read L3 PTE again | 209 | ld8 r25=[r21] // read L4 entry again |
196 | ld8 r26=[r17] // read L2 entry again | 210 | ld8 r26=[r17] // read L3 PTE again |
211 | #ifdef CONFIG_PGTABLE_4 | ||
212 | ld8 r18=[r28] // read L2 entry again | ||
213 | #endif | ||
214 | cmp.ne p6,p7=r0,r0 | ||
197 | ;; | 215 | ;; |
198 | cmp.ne p6,p7=r26,r20 // did L2 entry change | 216 | cmp.ne.or.andcm p6,p7=r26,r20 // did L3 entry change |
217 | #ifdef CONFIG_PGTABLE_4 | ||
218 | cmp.ne.or.andcm p6,p7=r29,r18 // did L4 PTE change | ||
219 | #endif | ||
199 | mov r27=PAGE_SHIFT<<2 | 220 | mov r27=PAGE_SHIFT<<2 |
200 | ;; | 221 | ;; |
201 | (p6) ptc.l r22,r27 // purge PTE page translation | 222 | (p6) ptc.l r22,r27 // purge PTE page translation |
202 | (p7) cmp.ne.or.andcm p6,p7=r25,r18 // did L3 PTE change | 223 | (p7) cmp.ne.or.andcm p6,p7=r25,r18 // did L4 PTE change |
203 | ;; | 224 | ;; |
204 | (p6) ptc.l r16,r27 // purge translation | 225 | (p6) ptc.l r16,r27 // purge translation |
205 | #endif | 226 | #endif |
@@ -432,18 +453,30 @@ ENTRY(nested_dtlb_miss) | |||
432 | (p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 | 453 | (p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8 |
433 | (p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) | 454 | (p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8) |
434 | cmp.eq p7,p6=0,r21 // unused address bits all zeroes? | 455 | cmp.eq p7,p6=0,r21 // unused address bits all zeroes? |
435 | shr.u r18=r22,PMD_SHIFT // shift L2 index into position | 456 | #ifdef CONFIG_PGTABLE_4 |
457 | shr.u r18=r22,PUD_SHIFT // shift L2 index into position | ||
458 | #else | ||
459 | shr.u r18=r22,PMD_SHIFT // shift L3 index into position | ||
460 | #endif | ||
436 | ;; | 461 | ;; |
437 | ld8 r17=[r17] // fetch the L1 entry (may be 0) | 462 | ld8 r17=[r17] // fetch the L1 entry (may be 0) |
438 | ;; | 463 | ;; |
439 | (p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? | 464 | (p7) cmp.eq p6,p7=r17,r0 // was L1 entry NULL? |
440 | dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry | 465 | dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry |
441 | ;; | 466 | ;; |
467 | #ifdef CONFIG_PGTABLE_4 | ||
442 | (p7) ld8 r17=[r17] // fetch the L2 entry (may be 0) | 468 | (p7) ld8 r17=[r17] // fetch the L2 entry (may be 0) |
443 | shr.u r19=r22,PAGE_SHIFT // shift L3 index into position | 469 | shr.u r18=r22,PMD_SHIFT // shift L3 index into position |
444 | ;; | 470 | ;; |
445 | (p7) cmp.eq.or.andcm p6,p7=r17,r0 // was L2 entry NULL? | 471 | (p7) cmp.eq.or.andcm p6,p7=r17,r0 // was L2 entry NULL? |
446 | dep r17=r19,r17,3,(PAGE_SHIFT-3) // compute address of L3 page table entry | 472 | dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry |
473 | ;; | ||
474 | #endif | ||
475 | (p7) ld8 r17=[r17] // fetch the L3 entry (may be 0) | ||
476 | shr.u r19=r22,PAGE_SHIFT // shift L4 index into position | ||
477 | ;; | ||
478 | (p7) cmp.eq.or.andcm p6,p7=r17,r0 // was L3 entry NULL? | ||
479 | dep r17=r19,r17,3,(PAGE_SHIFT-3) // compute address of L4 page table entry | ||
447 | (p6) br.cond.spnt page_fault | 480 | (p6) br.cond.spnt page_fault |
448 | mov b0=r30 | 481 | mov b0=r30 |
449 | br.sptk.many b0 // return to continuation point | 482 | br.sptk.many b0 // return to continuation point |
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 471086b808a4..801eeaeaf3de 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/config.h> | 26 | #include <linux/config.h> |
27 | #include <linux/kprobes.h> | 27 | #include <linux/kprobes.h> |
28 | #include <linux/ptrace.h> | 28 | #include <linux/ptrace.h> |
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/string.h> | 29 | #include <linux/string.h> |
31 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
32 | #include <linux/preempt.h> | 31 | #include <linux/preempt.h> |
@@ -38,13 +37,8 @@ | |||
38 | 37 | ||
39 | extern void jprobe_inst_return(void); | 38 | extern void jprobe_inst_return(void); |
40 | 39 | ||
41 | /* kprobe_status settings */ | 40 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; |
42 | #define KPROBE_HIT_ACTIVE 0x00000001 | 41 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); |
43 | #define KPROBE_HIT_SS 0x00000002 | ||
44 | |||
45 | static struct kprobe *current_kprobe, *kprobe_prev; | ||
46 | static unsigned long kprobe_status, kprobe_status_prev; | ||
47 | static struct pt_regs jprobe_saved_regs; | ||
48 | 42 | ||
49 | enum instruction_type {A, I, M, F, B, L, X, u}; | 43 | enum instruction_type {A, I, M, F, B, L, X, u}; |
50 | static enum instruction_type bundle_encoding[32][3] = { | 44 | static enum instruction_type bundle_encoding[32][3] = { |
@@ -313,21 +307,22 @@ static int __kprobes valid_kprobe_addr(int template, int slot, | |||
313 | return 0; | 307 | return 0; |
314 | } | 308 | } |
315 | 309 | ||
316 | static inline void save_previous_kprobe(void) | 310 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) |
317 | { | 311 | { |
318 | kprobe_prev = current_kprobe; | 312 | kcb->prev_kprobe.kp = kprobe_running(); |
319 | kprobe_status_prev = kprobe_status; | 313 | kcb->prev_kprobe.status = kcb->kprobe_status; |
320 | } | 314 | } |
321 | 315 | ||
322 | static inline void restore_previous_kprobe(void) | 316 | static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) |
323 | { | 317 | { |
324 | current_kprobe = kprobe_prev; | 318 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; |
325 | kprobe_status = kprobe_status_prev; | 319 | kcb->kprobe_status = kcb->prev_kprobe.status; |
326 | } | 320 | } |
327 | 321 | ||
328 | static inline void set_current_kprobe(struct kprobe *p) | 322 | static inline void set_current_kprobe(struct kprobe *p, |
323 | struct kprobe_ctlblk *kcb) | ||
329 | { | 324 | { |
330 | current_kprobe = p; | 325 | __get_cpu_var(current_kprobe) = p; |
331 | } | 326 | } |
332 | 327 | ||
333 | static void kretprobe_trampoline(void) | 328 | static void kretprobe_trampoline(void) |
@@ -347,11 +342,12 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
347 | struct kretprobe_instance *ri = NULL; | 342 | struct kretprobe_instance *ri = NULL; |
348 | struct hlist_head *head; | 343 | struct hlist_head *head; |
349 | struct hlist_node *node, *tmp; | 344 | struct hlist_node *node, *tmp; |
350 | unsigned long orig_ret_address = 0; | 345 | unsigned long flags, orig_ret_address = 0; |
351 | unsigned long trampoline_address = | 346 | unsigned long trampoline_address = |
352 | ((struct fnptr *)kretprobe_trampoline)->ip; | 347 | ((struct fnptr *)kretprobe_trampoline)->ip; |
353 | 348 | ||
354 | head = kretprobe_inst_table_head(current); | 349 | spin_lock_irqsave(&kretprobe_lock, flags); |
350 | head = kretprobe_inst_table_head(current); | ||
355 | 351 | ||
356 | /* | 352 | /* |
357 | * It is possible to have multiple instances associated with a given | 353 | * It is possible to have multiple instances associated with a given |
@@ -367,9 +363,9 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
367 | * kretprobe_trampoline | 363 | * kretprobe_trampoline |
368 | */ | 364 | */ |
369 | hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { | 365 | hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { |
370 | if (ri->task != current) | 366 | if (ri->task != current) |
371 | /* another task is sharing our hash bucket */ | 367 | /* another task is sharing our hash bucket */ |
372 | continue; | 368 | continue; |
373 | 369 | ||
374 | if (ri->rp && ri->rp->handler) | 370 | if (ri->rp && ri->rp->handler) |
375 | ri->rp->handler(ri, regs); | 371 | ri->rp->handler(ri, regs); |
@@ -389,17 +385,19 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
389 | BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); | 385 | BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); |
390 | regs->cr_iip = orig_ret_address; | 386 | regs->cr_iip = orig_ret_address; |
391 | 387 | ||
392 | unlock_kprobes(); | 388 | reset_current_kprobe(); |
389 | spin_unlock_irqrestore(&kretprobe_lock, flags); | ||
393 | preempt_enable_no_resched(); | 390 | preempt_enable_no_resched(); |
394 | 391 | ||
395 | /* | 392 | /* |
396 | * By returning a non-zero value, we are telling | 393 | * By returning a non-zero value, we are telling |
397 | * kprobe_handler() that we have handled unlocking | 394 | * kprobe_handler() that we don't want the post_handler |
398 | * and re-enabling preemption. | 395 | * to run (and have re-enabled preemption) |
399 | */ | 396 | */ |
400 | return 1; | 397 | return 1; |
401 | } | 398 | } |
402 | 399 | ||
400 | /* Called with kretprobe_lock held */ | ||
403 | void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, | 401 | void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, |
404 | struct pt_regs *regs) | 402 | struct pt_regs *regs) |
405 | { | 403 | { |
@@ -606,17 +604,22 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) | |||
606 | int ret = 0; | 604 | int ret = 0; |
607 | struct pt_regs *regs = args->regs; | 605 | struct pt_regs *regs = args->regs; |
608 | kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs); | 606 | kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs); |
607 | struct kprobe_ctlblk *kcb; | ||
609 | 608 | ||
609 | /* | ||
610 | * We don't want to be preempted for the entire | ||
611 | * duration of kprobe processing | ||
612 | */ | ||
610 | preempt_disable(); | 613 | preempt_disable(); |
614 | kcb = get_kprobe_ctlblk(); | ||
611 | 615 | ||
612 | /* Handle recursion cases */ | 616 | /* Handle recursion cases */ |
613 | if (kprobe_running()) { | 617 | if (kprobe_running()) { |
614 | p = get_kprobe(addr); | 618 | p = get_kprobe(addr); |
615 | if (p) { | 619 | if (p) { |
616 | if ( (kprobe_status == KPROBE_HIT_SS) && | 620 | if ((kcb->kprobe_status == KPROBE_HIT_SS) && |
617 | (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) { | 621 | (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) { |
618 | ia64_psr(regs)->ss = 0; | 622 | ia64_psr(regs)->ss = 0; |
619 | unlock_kprobes(); | ||
620 | goto no_kprobe; | 623 | goto no_kprobe; |
621 | } | 624 | } |
622 | /* We have reentered the pre_kprobe_handler(), since | 625 | /* We have reentered the pre_kprobe_handler(), since |
@@ -625,17 +628,17 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) | |||
625 | * just single step on the instruction of the new probe | 628 | * just single step on the instruction of the new probe |
626 | * without calling any user handlers. | 629 | * without calling any user handlers. |
627 | */ | 630 | */ |
628 | save_previous_kprobe(); | 631 | save_previous_kprobe(kcb); |
629 | set_current_kprobe(p); | 632 | set_current_kprobe(p, kcb); |
630 | p->nmissed++; | 633 | p->nmissed++; |
631 | prepare_ss(p, regs); | 634 | prepare_ss(p, regs); |
632 | kprobe_status = KPROBE_REENTER; | 635 | kcb->kprobe_status = KPROBE_REENTER; |
633 | return 1; | 636 | return 1; |
634 | } else if (args->err == __IA64_BREAK_JPROBE) { | 637 | } else if (args->err == __IA64_BREAK_JPROBE) { |
635 | /* | 638 | /* |
636 | * jprobe instrumented function just completed | 639 | * jprobe instrumented function just completed |
637 | */ | 640 | */ |
638 | p = current_kprobe; | 641 | p = __get_cpu_var(current_kprobe); |
639 | if (p->break_handler && p->break_handler(p, regs)) { | 642 | if (p->break_handler && p->break_handler(p, regs)) { |
640 | goto ss_probe; | 643 | goto ss_probe; |
641 | } | 644 | } |
@@ -645,10 +648,8 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) | |||
645 | } | 648 | } |
646 | } | 649 | } |
647 | 650 | ||
648 | lock_kprobes(); | ||
649 | p = get_kprobe(addr); | 651 | p = get_kprobe(addr); |
650 | if (!p) { | 652 | if (!p) { |
651 | unlock_kprobes(); | ||
652 | if (!is_ia64_break_inst(regs)) { | 653 | if (!is_ia64_break_inst(regs)) { |
653 | /* | 654 | /* |
654 | * The breakpoint instruction was removed right | 655 | * The breakpoint instruction was removed right |
@@ -665,8 +666,8 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) | |||
665 | goto no_kprobe; | 666 | goto no_kprobe; |
666 | } | 667 | } |
667 | 668 | ||
668 | kprobe_status = KPROBE_HIT_ACTIVE; | 669 | set_current_kprobe(p, kcb); |
669 | set_current_kprobe(p); | 670 | kcb->kprobe_status = KPROBE_HIT_ACTIVE; |
670 | 671 | ||
671 | if (p->pre_handler && p->pre_handler(p, regs)) | 672 | if (p->pre_handler && p->pre_handler(p, regs)) |
672 | /* | 673 | /* |
@@ -678,7 +679,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) | |||
678 | 679 | ||
679 | ss_probe: | 680 | ss_probe: |
680 | prepare_ss(p, regs); | 681 | prepare_ss(p, regs); |
681 | kprobe_status = KPROBE_HIT_SS; | 682 | kcb->kprobe_status = KPROBE_HIT_SS; |
682 | return 1; | 683 | return 1; |
683 | 684 | ||
684 | no_kprobe: | 685 | no_kprobe: |
@@ -688,23 +689,25 @@ no_kprobe: | |||
688 | 689 | ||
689 | static int __kprobes post_kprobes_handler(struct pt_regs *regs) | 690 | static int __kprobes post_kprobes_handler(struct pt_regs *regs) |
690 | { | 691 | { |
691 | if (!kprobe_running()) | 692 | struct kprobe *cur = kprobe_running(); |
693 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
694 | |||
695 | if (!cur) | ||
692 | return 0; | 696 | return 0; |
693 | 697 | ||
694 | if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) { | 698 | if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) { |
695 | kprobe_status = KPROBE_HIT_SSDONE; | 699 | kcb->kprobe_status = KPROBE_HIT_SSDONE; |
696 | current_kprobe->post_handler(current_kprobe, regs, 0); | 700 | cur->post_handler(cur, regs, 0); |
697 | } | 701 | } |
698 | 702 | ||
699 | resume_execution(current_kprobe, regs); | 703 | resume_execution(cur, regs); |
700 | 704 | ||
701 | /*Restore back the original saved kprobes variables and continue. */ | 705 | /*Restore back the original saved kprobes variables and continue. */ |
702 | if (kprobe_status == KPROBE_REENTER) { | 706 | if (kcb->kprobe_status == KPROBE_REENTER) { |
703 | restore_previous_kprobe(); | 707 | restore_previous_kprobe(kcb); |
704 | goto out; | 708 | goto out; |
705 | } | 709 | } |
706 | 710 | reset_current_kprobe(); | |
707 | unlock_kprobes(); | ||
708 | 711 | ||
709 | out: | 712 | out: |
710 | preempt_enable_no_resched(); | 713 | preempt_enable_no_resched(); |
@@ -713,16 +716,15 @@ out: | |||
713 | 716 | ||
714 | static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr) | 717 | static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr) |
715 | { | 718 | { |
716 | if (!kprobe_running()) | 719 | struct kprobe *cur = kprobe_running(); |
717 | return 0; | 720 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
718 | 721 | ||
719 | if (current_kprobe->fault_handler && | 722 | if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) |
720 | current_kprobe->fault_handler(current_kprobe, regs, trapnr)) | ||
721 | return 1; | 723 | return 1; |
722 | 724 | ||
723 | if (kprobe_status & KPROBE_HIT_SS) { | 725 | if (kcb->kprobe_status & KPROBE_HIT_SS) { |
724 | resume_execution(current_kprobe, regs); | 726 | resume_execution(cur, regs); |
725 | unlock_kprobes(); | 727 | reset_current_kprobe(); |
726 | preempt_enable_no_resched(); | 728 | preempt_enable_no_resched(); |
727 | } | 729 | } |
728 | 730 | ||
@@ -733,31 +735,42 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
733 | unsigned long val, void *data) | 735 | unsigned long val, void *data) |
734 | { | 736 | { |
735 | struct die_args *args = (struct die_args *)data; | 737 | struct die_args *args = (struct die_args *)data; |
738 | int ret = NOTIFY_DONE; | ||
739 | |||
736 | switch(val) { | 740 | switch(val) { |
737 | case DIE_BREAK: | 741 | case DIE_BREAK: |
738 | if (pre_kprobes_handler(args)) | 742 | /* err is break number from ia64_bad_break() */ |
739 | return NOTIFY_STOP; | 743 | if (args->err == 0x80200 || args->err == 0x80300) |
744 | if (pre_kprobes_handler(args)) | ||
745 | ret = NOTIFY_STOP; | ||
740 | break; | 746 | break; |
741 | case DIE_SS: | 747 | case DIE_FAULT: |
742 | if (post_kprobes_handler(args->regs)) | 748 | /* err is vector number from ia64_fault() */ |
743 | return NOTIFY_STOP; | 749 | if (args->err == 36) |
750 | if (post_kprobes_handler(args->regs)) | ||
751 | ret = NOTIFY_STOP; | ||
744 | break; | 752 | break; |
745 | case DIE_PAGE_FAULT: | 753 | case DIE_PAGE_FAULT: |
746 | if (kprobes_fault_handler(args->regs, args->trapnr)) | 754 | /* kprobe_running() needs smp_processor_id() */ |
747 | return NOTIFY_STOP; | 755 | preempt_disable(); |
756 | if (kprobe_running() && | ||
757 | kprobes_fault_handler(args->regs, args->trapnr)) | ||
758 | ret = NOTIFY_STOP; | ||
759 | preempt_enable(); | ||
748 | default: | 760 | default: |
749 | break; | 761 | break; |
750 | } | 762 | } |
751 | return NOTIFY_DONE; | 763 | return ret; |
752 | } | 764 | } |
753 | 765 | ||
754 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | 766 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) |
755 | { | 767 | { |
756 | struct jprobe *jp = container_of(p, struct jprobe, kp); | 768 | struct jprobe *jp = container_of(p, struct jprobe, kp); |
757 | unsigned long addr = ((struct fnptr *)(jp->entry))->ip; | 769 | unsigned long addr = ((struct fnptr *)(jp->entry))->ip; |
770 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
758 | 771 | ||
759 | /* save architectural state */ | 772 | /* save architectural state */ |
760 | jprobe_saved_regs = *regs; | 773 | kcb->jprobe_saved_regs = *regs; |
761 | 774 | ||
762 | /* after rfi, execute the jprobe instrumented function */ | 775 | /* after rfi, execute the jprobe instrumented function */ |
763 | regs->cr_iip = addr & ~0xFULL; | 776 | regs->cr_iip = addr & ~0xFULL; |
@@ -775,7 +788,10 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
775 | 788 | ||
776 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | 789 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) |
777 | { | 790 | { |
778 | *regs = jprobe_saved_regs; | 791 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
792 | |||
793 | *regs = kcb->jprobe_saved_regs; | ||
794 | preempt_enable_no_resched(); | ||
779 | return 1; | 795 | return 1; |
780 | } | 796 | } |
781 | 797 | ||
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 52c47da17246..355af15287c7 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -51,6 +51,9 @@ | |||
51 | * | 51 | * |
52 | * 2005-08-12 Keith Owens <kaos@sgi.com> | 52 | * 2005-08-12 Keith Owens <kaos@sgi.com> |
53 | * Convert MCA/INIT handlers to use per event stacks and SAL/OS state. | 53 | * Convert MCA/INIT handlers to use per event stacks and SAL/OS state. |
54 | * | ||
55 | * 2005-10-07 Keith Owens <kaos@sgi.com> | ||
56 | * Add notify_die() hooks. | ||
54 | */ | 57 | */ |
55 | #include <linux/config.h> | 58 | #include <linux/config.h> |
56 | #include <linux/types.h> | 59 | #include <linux/types.h> |
@@ -58,7 +61,6 @@ | |||
58 | #include <linux/sched.h> | 61 | #include <linux/sched.h> |
59 | #include <linux/interrupt.h> | 62 | #include <linux/interrupt.h> |
60 | #include <linux/irq.h> | 63 | #include <linux/irq.h> |
61 | #include <linux/kallsyms.h> | ||
62 | #include <linux/smp_lock.h> | 64 | #include <linux/smp_lock.h> |
63 | #include <linux/bootmem.h> | 65 | #include <linux/bootmem.h> |
64 | #include <linux/acpi.h> | 66 | #include <linux/acpi.h> |
@@ -69,6 +71,7 @@ | |||
69 | #include <linux/workqueue.h> | 71 | #include <linux/workqueue.h> |
70 | 72 | ||
71 | #include <asm/delay.h> | 73 | #include <asm/delay.h> |
74 | #include <asm/kdebug.h> | ||
72 | #include <asm/machvec.h> | 75 | #include <asm/machvec.h> |
73 | #include <asm/meminit.h> | 76 | #include <asm/meminit.h> |
74 | #include <asm/page.h> | 77 | #include <asm/page.h> |
@@ -132,6 +135,14 @@ extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe); | |||
132 | 135 | ||
133 | static int mca_init; | 136 | static int mca_init; |
134 | 137 | ||
138 | |||
139 | static void inline | ||
140 | ia64_mca_spin(const char *func) | ||
141 | { | ||
142 | printk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func); | ||
143 | while (1) | ||
144 | cpu_relax(); | ||
145 | } | ||
135 | /* | 146 | /* |
136 | * IA64_MCA log support | 147 | * IA64_MCA log support |
137 | */ | 148 | */ |
@@ -526,13 +537,16 @@ ia64_mca_wakeup_all(void) | |||
526 | * Outputs : None | 537 | * Outputs : None |
527 | */ | 538 | */ |
528 | static irqreturn_t | 539 | static irqreturn_t |
529 | ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs) | 540 | ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs) |
530 | { | 541 | { |
531 | unsigned long flags; | 542 | unsigned long flags; |
532 | int cpu = smp_processor_id(); | 543 | int cpu = smp_processor_id(); |
533 | 544 | ||
534 | /* Mask all interrupts */ | 545 | /* Mask all interrupts */ |
535 | local_irq_save(flags); | 546 | local_irq_save(flags); |
547 | if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, 0, 0, 0) | ||
548 | == NOTIFY_STOP) | ||
549 | ia64_mca_spin(__FUNCTION__); | ||
536 | 550 | ||
537 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE; | 551 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE; |
538 | /* Register with the SAL monarch that the slave has | 552 | /* Register with the SAL monarch that the slave has |
@@ -540,10 +554,18 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs) | |||
540 | */ | 554 | */ |
541 | ia64_sal_mc_rendez(); | 555 | ia64_sal_mc_rendez(); |
542 | 556 | ||
557 | if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, 0, 0, 0) | ||
558 | == NOTIFY_STOP) | ||
559 | ia64_mca_spin(__FUNCTION__); | ||
560 | |||
543 | /* Wait for the monarch cpu to exit. */ | 561 | /* Wait for the monarch cpu to exit. */ |
544 | while (monarch_cpu != -1) | 562 | while (monarch_cpu != -1) |
545 | cpu_relax(); /* spin until monarch leaves */ | 563 | cpu_relax(); /* spin until monarch leaves */ |
546 | 564 | ||
565 | if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, 0, 0, 0) | ||
566 | == NOTIFY_STOP) | ||
567 | ia64_mca_spin(__FUNCTION__); | ||
568 | |||
547 | /* Enable all interrupts */ | 569 | /* Enable all interrupts */ |
548 | local_irq_restore(flags); | 570 | local_irq_restore(flags); |
549 | return IRQ_HANDLED; | 571 | return IRQ_HANDLED; |
@@ -933,6 +955,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
933 | oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ | 955 | oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ |
934 | previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); | 956 | previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); |
935 | monarch_cpu = cpu; | 957 | monarch_cpu = cpu; |
958 | if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, 0, 0, 0) | ||
959 | == NOTIFY_STOP) | ||
960 | ia64_mca_spin(__FUNCTION__); | ||
936 | ia64_wait_for_slaves(cpu); | 961 | ia64_wait_for_slaves(cpu); |
937 | 962 | ||
938 | /* Wakeup all the processors which are spinning in the rendezvous loop. | 963 | /* Wakeup all the processors which are spinning in the rendezvous loop. |
@@ -942,6 +967,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
942 | * spinning in SAL does not work. | 967 | * spinning in SAL does not work. |
943 | */ | 968 | */ |
944 | ia64_mca_wakeup_all(); | 969 | ia64_mca_wakeup_all(); |
970 | if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, 0, 0, 0) | ||
971 | == NOTIFY_STOP) | ||
972 | ia64_mca_spin(__FUNCTION__); | ||
945 | 973 | ||
946 | /* Get the MCA error record and log it */ | 974 | /* Get the MCA error record and log it */ |
947 | ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA); | 975 | ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA); |
@@ -960,6 +988,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
960 | ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA); | 988 | ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA); |
961 | sos->os_status = IA64_MCA_CORRECTED; | 989 | sos->os_status = IA64_MCA_CORRECTED; |
962 | } | 990 | } |
991 | if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, 0, 0, recover) | ||
992 | == NOTIFY_STOP) | ||
993 | ia64_mca_spin(__FUNCTION__); | ||
963 | 994 | ||
964 | set_curr_task(cpu, previous_current); | 995 | set_curr_task(cpu, previous_current); |
965 | monarch_cpu = -1; | 996 | monarch_cpu = -1; |
@@ -1188,6 +1219,37 @@ ia64_mca_cpe_poll (unsigned long dummy) | |||
1188 | 1219 | ||
1189 | #endif /* CONFIG_ACPI */ | 1220 | #endif /* CONFIG_ACPI */ |
1190 | 1221 | ||
1222 | static int | ||
1223 | default_monarch_init_process(struct notifier_block *self, unsigned long val, void *data) | ||
1224 | { | ||
1225 | int c; | ||
1226 | struct task_struct *g, *t; | ||
1227 | if (val != DIE_INIT_MONARCH_PROCESS) | ||
1228 | return NOTIFY_DONE; | ||
1229 | printk(KERN_ERR "Processes interrupted by INIT -"); | ||
1230 | for_each_online_cpu(c) { | ||
1231 | struct ia64_sal_os_state *s; | ||
1232 | t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET); | ||
1233 | s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET); | ||
1234 | g = s->prev_task; | ||
1235 | if (g) { | ||
1236 | if (g->pid) | ||
1237 | printk(" %d", g->pid); | ||
1238 | else | ||
1239 | printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g); | ||
1240 | } | ||
1241 | } | ||
1242 | printk("\n\n"); | ||
1243 | if (read_trylock(&tasklist_lock)) { | ||
1244 | do_each_thread (g, t) { | ||
1245 | printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm); | ||
1246 | show_stack(t, NULL); | ||
1247 | } while_each_thread (g, t); | ||
1248 | read_unlock(&tasklist_lock); | ||
1249 | } | ||
1250 | return NOTIFY_DONE; | ||
1251 | } | ||
1252 | |||
1191 | /* | 1253 | /* |
1192 | * C portion of the OS INIT handler | 1254 | * C portion of the OS INIT handler |
1193 | * | 1255 | * |
@@ -1212,8 +1274,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1212 | static atomic_t slaves; | 1274 | static atomic_t slaves; |
1213 | static atomic_t monarchs; | 1275 | static atomic_t monarchs; |
1214 | task_t *previous_current; | 1276 | task_t *previous_current; |
1215 | int cpu = smp_processor_id(), c; | 1277 | int cpu = smp_processor_id(); |
1216 | struct task_struct *g, *t; | ||
1217 | 1278 | ||
1218 | oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ | 1279 | oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ |
1219 | console_loglevel = 15; /* make sure printks make it to console */ | 1280 | console_loglevel = 15; /* make sure printks make it to console */ |
@@ -1253,8 +1314,17 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1253 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT; | 1314 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT; |
1254 | while (monarch_cpu == -1) | 1315 | while (monarch_cpu == -1) |
1255 | cpu_relax(); /* spin until monarch enters */ | 1316 | cpu_relax(); /* spin until monarch enters */ |
1317 | if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, 0, 0, 0) | ||
1318 | == NOTIFY_STOP) | ||
1319 | ia64_mca_spin(__FUNCTION__); | ||
1320 | if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, 0, 0, 0) | ||
1321 | == NOTIFY_STOP) | ||
1322 | ia64_mca_spin(__FUNCTION__); | ||
1256 | while (monarch_cpu != -1) | 1323 | while (monarch_cpu != -1) |
1257 | cpu_relax(); /* spin until monarch leaves */ | 1324 | cpu_relax(); /* spin until monarch leaves */ |
1325 | if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, 0, 0, 0) | ||
1326 | == NOTIFY_STOP) | ||
1327 | ia64_mca_spin(__FUNCTION__); | ||
1258 | printk("Slave on cpu %d returning to normal service.\n", cpu); | 1328 | printk("Slave on cpu %d returning to normal service.\n", cpu); |
1259 | set_curr_task(cpu, previous_current); | 1329 | set_curr_task(cpu, previous_current); |
1260 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; | 1330 | ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; |
@@ -1263,6 +1333,9 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1263 | } | 1333 | } |
1264 | 1334 | ||
1265 | monarch_cpu = cpu; | 1335 | monarch_cpu = cpu; |
1336 | if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, 0, 0, 0) | ||
1337 | == NOTIFY_STOP) | ||
1338 | ia64_mca_spin(__FUNCTION__); | ||
1266 | 1339 | ||
1267 | /* | 1340 | /* |
1268 | * Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be | 1341 | * Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be |
@@ -1273,27 +1346,16 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, | |||
1273 | printk("Delaying for 5 seconds...\n"); | 1346 | printk("Delaying for 5 seconds...\n"); |
1274 | udelay(5*1000000); | 1347 | udelay(5*1000000); |
1275 | ia64_wait_for_slaves(cpu); | 1348 | ia64_wait_for_slaves(cpu); |
1276 | printk(KERN_ERR "Processes interrupted by INIT -"); | 1349 | /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through |
1277 | for_each_online_cpu(c) { | 1350 | * to default_monarch_init_process() above and just print all the |
1278 | struct ia64_sal_os_state *s; | 1351 | * tasks. |
1279 | t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET); | 1352 | */ |
1280 | s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET); | 1353 | if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, 0, 0, 0) |
1281 | g = s->prev_task; | 1354 | == NOTIFY_STOP) |
1282 | if (g) { | 1355 | ia64_mca_spin(__FUNCTION__); |
1283 | if (g->pid) | 1356 | if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, 0, 0, 0) |
1284 | printk(" %d", g->pid); | 1357 | == NOTIFY_STOP) |
1285 | else | 1358 | ia64_mca_spin(__FUNCTION__); |
1286 | printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g); | ||
1287 | } | ||
1288 | } | ||
1289 | printk("\n\n"); | ||
1290 | if (read_trylock(&tasklist_lock)) { | ||
1291 | do_each_thread (g, t) { | ||
1292 | printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm); | ||
1293 | show_stack(t, NULL); | ||
1294 | } while_each_thread (g, t); | ||
1295 | read_unlock(&tasklist_lock); | ||
1296 | } | ||
1297 | printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); | 1359 | printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); |
1298 | atomic_dec(&monarchs); | 1360 | atomic_dec(&monarchs); |
1299 | set_curr_task(cpu, previous_current); | 1361 | set_curr_task(cpu, previous_current); |
@@ -1462,6 +1524,10 @@ ia64_mca_init(void) | |||
1462 | s64 rc; | 1524 | s64 rc; |
1463 | struct ia64_sal_retval isrv; | 1525 | struct ia64_sal_retval isrv; |
1464 | u64 timeout = IA64_MCA_RENDEZ_TIMEOUT; /* platform specific */ | 1526 | u64 timeout = IA64_MCA_RENDEZ_TIMEOUT; /* platform specific */ |
1527 | static struct notifier_block default_init_monarch_nb = { | ||
1528 | .notifier_call = default_monarch_init_process, | ||
1529 | .priority = 0/* we need to notified last */ | ||
1530 | }; | ||
1465 | 1531 | ||
1466 | IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__); | 1532 | IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__); |
1467 | 1533 | ||
@@ -1555,6 +1621,10 @@ ia64_mca_init(void) | |||
1555 | "(status %ld)\n", rc); | 1621 | "(status %ld)\n", rc); |
1556 | return; | 1622 | return; |
1557 | } | 1623 | } |
1624 | if (register_die_notifier(&default_init_monarch_nb)) { | ||
1625 | printk(KERN_ERR "Failed to register default monarch INIT process\n"); | ||
1626 | return; | ||
1627 | } | ||
1558 | 1628 | ||
1559 | IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__); | 1629 | IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__); |
1560 | 1630 | ||
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index f081c60ab206..3492e3211a44 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c | |||
@@ -88,7 +88,7 @@ mca_page_isolate(unsigned long paddr) | |||
88 | if (!ia64_phys_addr_valid(paddr)) | 88 | if (!ia64_phys_addr_valid(paddr)) |
89 | return ISOLATE_NONE; | 89 | return ISOLATE_NONE; |
90 | 90 | ||
91 | if (!pfn_valid(paddr)) | 91 | if (!pfn_valid(paddr >> PAGE_SHIFT)) |
92 | return ISOLATE_NONE; | 92 | return ISOLATE_NONE; |
93 | 93 | ||
94 | /* convert physical address to physical page number */ | 94 | /* convert physical address to physical page number */ |
@@ -108,6 +108,7 @@ mca_page_isolate(unsigned long paddr) | |||
108 | return ISOLATE_NG; | 108 | return ISOLATE_NG; |
109 | 109 | ||
110 | /* add attribute 'Reserved' and register the page */ | 110 | /* add attribute 'Reserved' and register the page */ |
111 | get_page(p); | ||
111 | SetPageReserved(p); | 112 | SetPageReserved(p); |
112 | page_isolate[num_page_isolate++] = p; | 113 | page_isolate[num_page_isolate++] = p; |
113 | 114 | ||
@@ -546,9 +547,20 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, | |||
546 | (pal_processor_state_info_t*)peidx_psp(peidx); | 547 | (pal_processor_state_info_t*)peidx_psp(peidx); |
547 | 548 | ||
548 | /* | 549 | /* |
549 | * We cannot recover errors with other than bus_check. | 550 | * Processor recovery status must key off of the PAL recovery |
551 | * status in the Processor State Parameter. | ||
550 | */ | 552 | */ |
551 | if (psp->cc || psp->rc || psp->uc) | 553 | |
554 | /* | ||
555 | * The machine check is corrected. | ||
556 | */ | ||
557 | if (psp->cm == 1) | ||
558 | return 1; | ||
559 | |||
560 | /* | ||
561 | * The error was not contained. Software must be reset. | ||
562 | */ | ||
563 | if (psp->us || psp->ci == 0) | ||
552 | return 0; | 564 | return 0; |
553 | 565 | ||
554 | /* | 566 | /* |
@@ -569,8 +581,6 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, | |||
569 | return 0; | 581 | return 0; |
570 | if (pbci->eb && pbci->bsi > 0) | 582 | if (pbci->eb && pbci->bsi > 0) |
571 | return 0; | 583 | return 0; |
572 | if (psp->ci == 0) | ||
573 | return 0; | ||
574 | 584 | ||
575 | /* | 585 | /* |
576 | * This is a local MCA and estimated as recoverble external bus error. | 586 | * This is a local MCA and estimated as recoverble external bus error. |
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index f7dfc107cb7b..410d4804fa6e 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -4940,7 +4940,7 @@ abort_locked: | |||
4940 | if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT; | 4940 | if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT; |
4941 | 4941 | ||
4942 | error_args: | 4942 | error_args: |
4943 | if (args_k) kfree(args_k); | 4943 | kfree(args_k); |
4944 | 4944 | ||
4945 | DPRINT(("cmd=%s ret=%ld\n", PFM_CMD_NAME(cmd), ret)); | 4945 | DPRINT(("cmd=%s ret=%ld\n", PFM_CMD_NAME(cmd), ret)); |
4946 | 4946 | ||
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 051e050359e4..e92ea64d8040 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
@@ -4,6 +4,9 @@ | |||
4 | * Copyright (C) 1998-2003 Hewlett-Packard Co | 4 | * Copyright (C) 1998-2003 Hewlett-Packard Co |
5 | * David Mosberger-Tang <davidm@hpl.hp.com> | 5 | * David Mosberger-Tang <davidm@hpl.hp.com> |
6 | * 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support | 6 | * 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support |
7 | * | ||
8 | * 2005-10-07 Keith Owens <kaos@sgi.com> | ||
9 | * Add notify_die() hooks. | ||
7 | */ | 10 | */ |
8 | #define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */ | 11 | #define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */ |
9 | #include <linux/config.h> | 12 | #include <linux/config.h> |
@@ -34,6 +37,7 @@ | |||
34 | #include <asm/elf.h> | 37 | #include <asm/elf.h> |
35 | #include <asm/ia32.h> | 38 | #include <asm/ia32.h> |
36 | #include <asm/irq.h> | 39 | #include <asm/irq.h> |
40 | #include <asm/kdebug.h> | ||
37 | #include <asm/pgalloc.h> | 41 | #include <asm/pgalloc.h> |
38 | #include <asm/processor.h> | 42 | #include <asm/processor.h> |
39 | #include <asm/sal.h> | 43 | #include <asm/sal.h> |
@@ -197,11 +201,15 @@ void | |||
197 | default_idle (void) | 201 | default_idle (void) |
198 | { | 202 | { |
199 | local_irq_enable(); | 203 | local_irq_enable(); |
200 | while (!need_resched()) | 204 | while (!need_resched()) { |
201 | if (can_do_pal_halt) | 205 | if (can_do_pal_halt) { |
202 | safe_halt(); | 206 | local_irq_disable(); |
203 | else | 207 | if (!need_resched()) |
208 | safe_halt(); | ||
209 | local_irq_enable(); | ||
210 | } else | ||
204 | cpu_relax(); | 211 | cpu_relax(); |
212 | } | ||
205 | } | 213 | } |
206 | 214 | ||
207 | #ifdef CONFIG_HOTPLUG_CPU | 215 | #ifdef CONFIG_HOTPLUG_CPU |
@@ -263,16 +271,16 @@ void __attribute__((noreturn)) | |||
263 | cpu_idle (void) | 271 | cpu_idle (void) |
264 | { | 272 | { |
265 | void (*mark_idle)(int) = ia64_mark_idle; | 273 | void (*mark_idle)(int) = ia64_mark_idle; |
274 | int cpu = smp_processor_id(); | ||
275 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
266 | 276 | ||
267 | /* endless idle loop with no priority at all */ | 277 | /* endless idle loop with no priority at all */ |
268 | while (1) { | 278 | while (1) { |
279 | if (!need_resched()) { | ||
280 | void (*idle)(void); | ||
269 | #ifdef CONFIG_SMP | 281 | #ifdef CONFIG_SMP |
270 | if (!need_resched()) | ||
271 | min_xtp(); | 282 | min_xtp(); |
272 | #endif | 283 | #endif |
273 | while (!need_resched()) { | ||
274 | void (*idle)(void); | ||
275 | |||
276 | if (__get_cpu_var(cpu_idle_state)) | 284 | if (__get_cpu_var(cpu_idle_state)) |
277 | __get_cpu_var(cpu_idle_state) = 0; | 285 | __get_cpu_var(cpu_idle_state) = 0; |
278 | 286 | ||
@@ -284,17 +292,17 @@ cpu_idle (void) | |||
284 | if (!idle) | 292 | if (!idle) |
285 | idle = default_idle; | 293 | idle = default_idle; |
286 | (*idle)(); | 294 | (*idle)(); |
287 | } | 295 | if (mark_idle) |
288 | 296 | (*mark_idle)(0); | |
289 | if (mark_idle) | ||
290 | (*mark_idle)(0); | ||
291 | |||
292 | #ifdef CONFIG_SMP | 297 | #ifdef CONFIG_SMP |
293 | normal_xtp(); | 298 | normal_xtp(); |
294 | #endif | 299 | #endif |
300 | } | ||
301 | preempt_enable_no_resched(); | ||
295 | schedule(); | 302 | schedule(); |
303 | preempt_disable(); | ||
296 | check_pgt_cache(); | 304 | check_pgt_cache(); |
297 | if (cpu_is_offline(smp_processor_id())) | 305 | if (cpu_is_offline(cpu)) |
298 | play_dead(); | 306 | play_dead(); |
299 | } | 307 | } |
300 | } | 308 | } |
@@ -804,12 +812,14 @@ cpu_halt (void) | |||
804 | void | 812 | void |
805 | machine_restart (char *restart_cmd) | 813 | machine_restart (char *restart_cmd) |
806 | { | 814 | { |
815 | (void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0); | ||
807 | (*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL); | 816 | (*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL); |
808 | } | 817 | } |
809 | 818 | ||
810 | void | 819 | void |
811 | machine_halt (void) | 820 | machine_halt (void) |
812 | { | 821 | { |
822 | (void) notify_die(DIE_MACHINE_HALT, "", NULL, 0, 0, 0); | ||
813 | cpu_halt(); | 823 | cpu_halt(); |
814 | } | 824 | } |
815 | 825 | ||
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index fc56ca2da358..5add0bcf87a7 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
@@ -92,6 +92,13 @@ extern void efi_initialize_iomem_resources(struct resource *, | |||
92 | extern char _text[], _end[], _etext[]; | 92 | extern char _text[], _end[], _etext[]; |
93 | 93 | ||
94 | unsigned long ia64_max_cacheline_size; | 94 | unsigned long ia64_max_cacheline_size; |
95 | |||
96 | int dma_get_cache_alignment(void) | ||
97 | { | ||
98 | return ia64_max_cacheline_size; | ||
99 | } | ||
100 | EXPORT_SYMBOL(dma_get_cache_alignment); | ||
101 | |||
95 | unsigned long ia64_iobase; /* virtual address for I/O accesses */ | 102 | unsigned long ia64_iobase; /* virtual address for I/O accesses */ |
96 | EXPORT_SYMBOL(ia64_iobase); | 103 | EXPORT_SYMBOL(ia64_iobase); |
97 | struct io_space io_space[MAX_IO_SPACES]; | 104 | struct io_space io_space[MAX_IO_SPACES]; |
@@ -454,6 +461,7 @@ setup_arch (char **cmdline_p) | |||
454 | #endif | 461 | #endif |
455 | 462 | ||
456 | cpu_init(); /* initialize the bootstrap CPU */ | 463 | cpu_init(); /* initialize the bootstrap CPU */ |
464 | mmu_context_init(); /* initialize context_id bitmap */ | ||
457 | 465 | ||
458 | #ifdef CONFIG_ACPI | 466 | #ifdef CONFIG_ACPI |
459 | acpi_boot_init(); | 467 | acpi_boot_init(); |
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 774f34b675cf..58ce07efc56e 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c | |||
@@ -387,15 +387,14 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, | |||
387 | struct sigscratch *scr) | 387 | struct sigscratch *scr) |
388 | { | 388 | { |
389 | extern char __kernel_sigtramp[]; | 389 | extern char __kernel_sigtramp[]; |
390 | unsigned long tramp_addr, new_rbs = 0; | 390 | unsigned long tramp_addr, new_rbs = 0, new_sp; |
391 | struct sigframe __user *frame; | 391 | struct sigframe __user *frame; |
392 | long err; | 392 | long err; |
393 | 393 | ||
394 | frame = (void __user *) scr->pt.r12; | 394 | new_sp = scr->pt.r12; |
395 | tramp_addr = (unsigned long) __kernel_sigtramp; | 395 | tramp_addr = (unsigned long) __kernel_sigtramp; |
396 | if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags((unsigned long) frame) == 0) { | 396 | if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(new_sp) == 0) { |
397 | frame = (void __user *) ((current->sas_ss_sp + current->sas_ss_size) | 397 | new_sp = current->sas_ss_sp + current->sas_ss_size; |
398 | & ~(STACK_ALIGN - 1)); | ||
399 | /* | 398 | /* |
400 | * We need to check for the register stack being on the signal stack | 399 | * We need to check for the register stack being on the signal stack |
401 | * separately, because it's switched separately (memory stack is switched | 400 | * separately, because it's switched separately (memory stack is switched |
@@ -404,7 +403,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, | |||
404 | if (!rbs_on_sig_stack(scr->pt.ar_bspstore)) | 403 | if (!rbs_on_sig_stack(scr->pt.ar_bspstore)) |
405 | new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1); | 404 | new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1); |
406 | } | 405 | } |
407 | frame = (void __user *) frame - ((sizeof(*frame) + STACK_ALIGN - 1) & ~(STACK_ALIGN - 1)); | 406 | frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN); |
408 | 407 | ||
409 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 408 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
410 | return force_sigsegv_info(sig, frame); | 409 | return force_sigsegv_info(sig, frame); |
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 400a48987124..8f44e7d2df66 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
@@ -399,6 +399,7 @@ start_secondary (void *unused) | |||
399 | Dprintk("start_secondary: starting CPU 0x%x\n", hard_smp_processor_id()); | 399 | Dprintk("start_secondary: starting CPU 0x%x\n", hard_smp_processor_id()); |
400 | efi_map_pal_code(); | 400 | efi_map_pal_code(); |
401 | cpu_init(); | 401 | cpu_init(); |
402 | preempt_disable(); | ||
402 | smp_callin(); | 403 | smp_callin(); |
403 | 404 | ||
404 | cpu_idle(); | 405 | cpu_idle(); |
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index f970359e7edf..fba5fdd1f968 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c | |||
@@ -30,17 +30,20 @@ fpswa_interface_t *fpswa_interface; | |||
30 | EXPORT_SYMBOL(fpswa_interface); | 30 | EXPORT_SYMBOL(fpswa_interface); |
31 | 31 | ||
32 | struct notifier_block *ia64die_chain; | 32 | struct notifier_block *ia64die_chain; |
33 | static DEFINE_SPINLOCK(die_notifier_lock); | ||
34 | 33 | ||
35 | int register_die_notifier(struct notifier_block *nb) | 34 | int |
35 | register_die_notifier(struct notifier_block *nb) | ||
36 | { | 36 | { |
37 | int err = 0; | 37 | return notifier_chain_register(&ia64die_chain, nb); |
38 | unsigned long flags; | ||
39 | spin_lock_irqsave(&die_notifier_lock, flags); | ||
40 | err = notifier_chain_register(&ia64die_chain, nb); | ||
41 | spin_unlock_irqrestore(&die_notifier_lock, flags); | ||
42 | return err; | ||
43 | } | 38 | } |
39 | EXPORT_SYMBOL_GPL(register_die_notifier); | ||
40 | |||
41 | int | ||
42 | unregister_die_notifier(struct notifier_block *nb) | ||
43 | { | ||
44 | return notifier_chain_unregister(&ia64die_chain, nb); | ||
45 | } | ||
46 | EXPORT_SYMBOL_GPL(unregister_die_notifier); | ||
44 | 47 | ||
45 | void __init | 48 | void __init |
46 | trap_init (void) | 49 | trap_init (void) |
@@ -105,6 +108,7 @@ die (const char *str, struct pt_regs *regs, long err) | |||
105 | if (++die.lock_owner_depth < 3) { | 108 | if (++die.lock_owner_depth < 3) { |
106 | printk("%s[%d]: %s %ld [%d]\n", | 109 | printk("%s[%d]: %s %ld [%d]\n", |
107 | current->comm, current->pid, str, err, ++die_counter); | 110 | current->comm, current->pid, str, err, ++die_counter); |
111 | (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); | ||
108 | show_regs(regs); | 112 | show_regs(regs); |
109 | } else | 113 | } else |
110 | printk(KERN_ERR "Recursive die() failure, output suppressed\n"); | 114 | printk(KERN_ERR "Recursive die() failure, output suppressed\n"); |
@@ -155,9 +159,8 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) | |||
155 | switch (break_num) { | 159 | switch (break_num) { |
156 | case 0: /* unknown error (used by GCC for __builtin_abort()) */ | 160 | case 0: /* unknown error (used by GCC for __builtin_abort()) */ |
157 | if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP) | 161 | if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP) |
158 | == NOTIFY_STOP) { | 162 | == NOTIFY_STOP) |
159 | return; | 163 | return; |
160 | } | ||
161 | die_if_kernel("bugcheck!", regs, break_num); | 164 | die_if_kernel("bugcheck!", regs, break_num); |
162 | sig = SIGILL; code = ILL_ILLOPC; | 165 | sig = SIGILL; code = ILL_ILLOPC; |
163 | break; | 166 | break; |
@@ -210,15 +213,6 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) | |||
210 | sig = SIGILL; code = __ILL_BNDMOD; | 213 | sig = SIGILL; code = __ILL_BNDMOD; |
211 | break; | 214 | break; |
212 | 215 | ||
213 | case 0x80200: | ||
214 | case 0x80300: | ||
215 | if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP) | ||
216 | == NOTIFY_STOP) { | ||
217 | return; | ||
218 | } | ||
219 | sig = SIGTRAP; code = TRAP_BRKPT; | ||
220 | break; | ||
221 | |||
222 | default: | 216 | default: |
223 | if (break_num < 0x40000 || break_num > 0x100000) | 217 | if (break_num < 0x40000 || break_num > 0x100000) |
224 | die_if_kernel("Bad break", regs, break_num); | 218 | die_if_kernel("Bad break", regs, break_num); |
@@ -226,6 +220,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) | |||
226 | if (break_num < 0x80000) { | 220 | if (break_num < 0x80000) { |
227 | sig = SIGILL; code = __ILL_BREAK; | 221 | sig = SIGILL; code = __ILL_BREAK; |
228 | } else { | 222 | } else { |
223 | if (notify_die(DIE_BREAK, "bad break", regs, break_num, TRAP_BRKPT, SIGTRAP) | ||
224 | == NOTIFY_STOP) | ||
225 | return; | ||
229 | sig = SIGTRAP; code = TRAP_BRKPT; | 226 | sig = SIGTRAP; code = TRAP_BRKPT; |
230 | } | 227 | } |
231 | } | 228 | } |
@@ -578,12 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
578 | #endif | 575 | #endif |
579 | break; | 576 | break; |
580 | case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break; | 577 | case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break; |
581 | case 36: | 578 | case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break; |
582 | if (notify_die(DIE_SS, "ss", ®s, vector, | ||
583 | vector, SIGTRAP) == NOTIFY_STOP) | ||
584 | return; | ||
585 | siginfo.si_code = TRAP_TRACE; ifa = 0; break; | ||
586 | } | 579 | } |
580 | if (notify_die(DIE_FAULT, "ia64_fault", ®s, vector, siginfo.si_code, SIGTRAP) | ||
581 | == NOTIFY_STOP) | ||
582 | return; | ||
587 | siginfo.si_signo = SIGTRAP; | 583 | siginfo.si_signo = SIGTRAP; |
588 | siginfo.si_errno = 0; | 584 | siginfo.si_errno = 0; |
589 | siginfo.si_addr = (void __user *) ifa; | 585 | siginfo.si_addr = (void __user *) ifa; |
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index a88cdb7232f8..0f776b032d31 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c | |||
@@ -350,14 +350,12 @@ static void __init initialize_pernode_data(void) | |||
350 | * for best. | 350 | * for best. |
351 | * @nid: node id | 351 | * @nid: node id |
352 | * @pernodesize: size of this node's pernode data | 352 | * @pernodesize: size of this node's pernode data |
353 | * @align: alignment to use for this node's pernode data | ||
354 | */ | 353 | */ |
355 | static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize, | 354 | static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize) |
356 | unsigned long align) | ||
357 | { | 355 | { |
358 | void *ptr = NULL; | 356 | void *ptr = NULL; |
359 | u8 best = 0xff; | 357 | u8 best = 0xff; |
360 | int bestnode = -1, node; | 358 | int bestnode = -1, node, anynode = 0; |
361 | 359 | ||
362 | for_each_online_node(node) { | 360 | for_each_online_node(node) { |
363 | if (node_isset(node, memory_less_mask)) | 361 | if (node_isset(node, memory_less_mask)) |
@@ -366,13 +364,15 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize, | |||
366 | best = node_distance(nid, node); | 364 | best = node_distance(nid, node); |
367 | bestnode = node; | 365 | bestnode = node; |
368 | } | 366 | } |
367 | anynode = node; | ||
369 | } | 368 | } |
370 | 369 | ||
371 | ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat, | 370 | if (bestnode == -1) |
372 | pernodesize, align, __pa(MAX_DMA_ADDRESS)); | 371 | bestnode = anynode; |
372 | |||
373 | ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat, pernodesize, | ||
374 | PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS)); | ||
373 | 375 | ||
374 | if (!ptr) | ||
375 | panic("NO memory for memory less node\n"); | ||
376 | return ptr; | 376 | return ptr; |
377 | } | 377 | } |
378 | 378 | ||
@@ -413,8 +413,7 @@ static void __init memory_less_nodes(void) | |||
413 | 413 | ||
414 | for_each_node_mask(node, memory_less_mask) { | 414 | for_each_node_mask(node, memory_less_mask) { |
415 | pernodesize = compute_pernodesize(node); | 415 | pernodesize = compute_pernodesize(node); |
416 | pernode = memory_less_node_alloc(node, pernodesize, | 416 | pernode = memory_less_node_alloc(node, pernodesize); |
417 | (node) ? (node * PERCPU_PAGE_SIZE) : (1024*1024)); | ||
418 | fill_pernode(node, __pa(pernode), pernodesize); | 417 | fill_pernode(node, __pa(pernode), pernodesize); |
419 | } | 418 | } |
420 | 419 | ||
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index c79a9b96d02b..41105d454423 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c | |||
@@ -8,6 +8,8 @@ | |||
8 | * Modified RID allocation for SMP | 8 | * Modified RID allocation for SMP |
9 | * Goutham Rao <goutham.rao@intel.com> | 9 | * Goutham Rao <goutham.rao@intel.com> |
10 | * IPI based ptc implementation and A-step IPI implementation. | 10 | * IPI based ptc implementation and A-step IPI implementation. |
11 | * Rohit Seth <rohit.seth@intel.com> | ||
12 | * Ken Chen <kenneth.w.chen@intel.com> | ||
11 | */ | 13 | */ |
12 | #include <linux/config.h> | 14 | #include <linux/config.h> |
13 | #include <linux/module.h> | 15 | #include <linux/module.h> |
@@ -16,78 +18,75 @@ | |||
16 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
17 | #include <linux/smp.h> | 19 | #include <linux/smp.h> |
18 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
21 | #include <linux/bootmem.h> | ||
19 | 22 | ||
20 | #include <asm/delay.h> | 23 | #include <asm/delay.h> |
21 | #include <asm/mmu_context.h> | 24 | #include <asm/mmu_context.h> |
22 | #include <asm/pgalloc.h> | 25 | #include <asm/pgalloc.h> |
23 | #include <asm/pal.h> | 26 | #include <asm/pal.h> |
24 | #include <asm/tlbflush.h> | 27 | #include <asm/tlbflush.h> |
28 | #include <asm/dma.h> | ||
25 | 29 | ||
26 | static struct { | 30 | static struct { |
27 | unsigned long mask; /* mask of supported purge page-sizes */ | 31 | unsigned long mask; /* mask of supported purge page-sizes */ |
28 | unsigned long max_bits; /* log2() of largest supported purge page-size */ | 32 | unsigned long max_bits; /* log2 of largest supported purge page-size */ |
29 | } purge; | 33 | } purge; |
30 | 34 | ||
31 | struct ia64_ctx ia64_ctx = { | 35 | struct ia64_ctx ia64_ctx = { |
32 | .lock = SPIN_LOCK_UNLOCKED, | 36 | .lock = SPIN_LOCK_UNLOCKED, |
33 | .next = 1, | 37 | .next = 1, |
34 | .limit = (1 << 15) - 1, /* start out with the safe (architected) limit */ | ||
35 | .max_ctx = ~0U | 38 | .max_ctx = ~0U |
36 | }; | 39 | }; |
37 | 40 | ||
38 | DEFINE_PER_CPU(u8, ia64_need_tlb_flush); | 41 | DEFINE_PER_CPU(u8, ia64_need_tlb_flush); |
39 | 42 | ||
40 | /* | 43 | /* |
44 | * Initializes the ia64_ctx.bitmap array based on max_ctx+1. | ||
45 | * Called after cpu_init() has setup ia64_ctx.max_ctx based on | ||
46 | * maximum RID that is supported by boot CPU. | ||
47 | */ | ||
48 | void __init | ||
49 | mmu_context_init (void) | ||
50 | { | ||
51 | ia64_ctx.bitmap = alloc_bootmem((ia64_ctx.max_ctx+1)>>3); | ||
52 | ia64_ctx.flushmap = alloc_bootmem((ia64_ctx.max_ctx+1)>>3); | ||
53 | } | ||
54 | |||
55 | /* | ||
41 | * Acquire the ia64_ctx.lock before calling this function! | 56 | * Acquire the ia64_ctx.lock before calling this function! |
42 | */ | 57 | */ |
43 | void | 58 | void |
44 | wrap_mmu_context (struct mm_struct *mm) | 59 | wrap_mmu_context (struct mm_struct *mm) |
45 | { | 60 | { |
46 | unsigned long tsk_context, max_ctx = ia64_ctx.max_ctx; | 61 | int i, cpu; |
47 | struct task_struct *tsk; | 62 | unsigned long flush_bit; |
48 | int i; | ||
49 | 63 | ||
50 | if (ia64_ctx.next > max_ctx) | 64 | for (i=0; i <= ia64_ctx.max_ctx / BITS_PER_LONG; i++) { |
51 | ia64_ctx.next = 300; /* skip daemons */ | 65 | flush_bit = xchg(&ia64_ctx.flushmap[i], 0); |
52 | ia64_ctx.limit = max_ctx + 1; | 66 | ia64_ctx.bitmap[i] ^= flush_bit; |
67 | } | ||
68 | |||
69 | /* use offset at 300 to skip daemons */ | ||
70 | ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap, | ||
71 | ia64_ctx.max_ctx, 300); | ||
72 | ia64_ctx.limit = find_next_bit(ia64_ctx.bitmap, | ||
73 | ia64_ctx.max_ctx, ia64_ctx.next); | ||
53 | 74 | ||
54 | /* | 75 | /* |
55 | * Scan all the task's mm->context and set proper safe range | 76 | * can't call flush_tlb_all() here because of race condition |
77 | * with O(1) scheduler [EF] | ||
56 | */ | 78 | */ |
57 | 79 | cpu = get_cpu(); /* prevent preemption/migration */ | |
58 | read_lock(&tasklist_lock); | 80 | for_each_online_cpu(i) |
59 | repeat: | 81 | if (i != cpu) |
60 | for_each_process(tsk) { | 82 | per_cpu(ia64_need_tlb_flush, i) = 1; |
61 | if (!tsk->mm) | 83 | put_cpu(); |
62 | continue; | ||
63 | tsk_context = tsk->mm->context; | ||
64 | if (tsk_context == ia64_ctx.next) { | ||
65 | if (++ia64_ctx.next >= ia64_ctx.limit) { | ||
66 | /* empty range: reset the range limit and start over */ | ||
67 | if (ia64_ctx.next > max_ctx) | ||
68 | ia64_ctx.next = 300; | ||
69 | ia64_ctx.limit = max_ctx + 1; | ||
70 | goto repeat; | ||
71 | } | ||
72 | } | ||
73 | if ((tsk_context > ia64_ctx.next) && (tsk_context < ia64_ctx.limit)) | ||
74 | ia64_ctx.limit = tsk_context; | ||
75 | } | ||
76 | read_unlock(&tasklist_lock); | ||
77 | /* can't call flush_tlb_all() here because of race condition with O(1) scheduler [EF] */ | ||
78 | { | ||
79 | int cpu = get_cpu(); /* prevent preemption/migration */ | ||
80 | for_each_online_cpu(i) { | ||
81 | if (i != cpu) | ||
82 | per_cpu(ia64_need_tlb_flush, i) = 1; | ||
83 | } | ||
84 | put_cpu(); | ||
85 | } | ||
86 | local_flush_tlb_all(); | 84 | local_flush_tlb_all(); |
87 | } | 85 | } |
88 | 86 | ||
89 | void | 87 | void |
90 | ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long nbits) | 88 | ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, |
89 | unsigned long end, unsigned long nbits) | ||
91 | { | 90 | { |
92 | static DEFINE_SPINLOCK(ptcg_lock); | 91 | static DEFINE_SPINLOCK(ptcg_lock); |
93 | 92 | ||
@@ -135,7 +134,8 @@ local_flush_tlb_all (void) | |||
135 | } | 134 | } |
136 | 135 | ||
137 | void | 136 | void |
138 | flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end) | 137 | flush_tlb_range (struct vm_area_struct *vma, unsigned long start, |
138 | unsigned long end) | ||
139 | { | 139 | { |
140 | struct mm_struct *mm = vma->vm_mm; | 140 | struct mm_struct *mm = vma->vm_mm; |
141 | unsigned long size = end - start; | 141 | unsigned long size = end - start; |
@@ -149,7 +149,8 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long | |||
149 | #endif | 149 | #endif |
150 | 150 | ||
151 | nbits = ia64_fls(size + 0xfff); | 151 | nbits = ia64_fls(size + 0xfff); |
152 | while (unlikely (((1UL << nbits) & purge.mask) == 0) && (nbits < purge.max_bits)) | 152 | while (unlikely (((1UL << nbits) & purge.mask) == 0) && |
153 | (nbits < purge.max_bits)) | ||
153 | ++nbits; | 154 | ++nbits; |
154 | if (nbits > purge.max_bits) | 155 | if (nbits > purge.max_bits) |
155 | nbits = purge.max_bits; | 156 | nbits = purge.max_bits; |
@@ -191,5 +192,5 @@ ia64_tlb_init (void) | |||
191 | local_cpu_data->ptce_stride[0] = ptce_info.stride[0]; | 192 | local_cpu_data->ptce_stride[0] = ptce_info.stride[0]; |
192 | local_cpu_data->ptce_stride[1] = ptce_info.stride[1]; | 193 | local_cpu_data->ptce_stride[1] = ptce_info.stride[1]; |
193 | 194 | ||
194 | local_flush_tlb_all(); /* nuke left overs from bootstrapping... */ | 195 | local_flush_tlb_all(); /* nuke left overs from bootstrapping... */ |
195 | } | 196 | } |
diff --git a/arch/ia64/oprofile/Kconfig b/arch/ia64/oprofile/Kconfig index 56e6f614b04a..97271ab484dc 100644 --- a/arch/ia64/oprofile/Kconfig +++ b/arch/ia64/oprofile/Kconfig | |||
@@ -1,7 +1,3 @@ | |||
1 | |||
2 | menu "Profiling support" | ||
3 | depends on EXPERIMENTAL | ||
4 | |||
5 | config PROFILING | 1 | config PROFILING |
6 | bool "Profiling support (EXPERIMENTAL)" | 2 | bool "Profiling support (EXPERIMENTAL)" |
7 | help | 3 | help |
@@ -22,5 +18,3 @@ config OPROFILE | |||
22 | 18 | ||
23 | If unsure, say N. | 19 | If unsure, say N. |
24 | 20 | ||
25 | endmenu | ||
26 | |||
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 017cfc3f4789..20d76fae24e8 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -95,7 +95,7 @@ pci_sal_write (unsigned int seg, unsigned int bus, unsigned int devfn, | |||
95 | } | 95 | } |
96 | 96 | ||
97 | static struct pci_raw_ops pci_sal_ops = { | 97 | static struct pci_raw_ops pci_sal_ops = { |
98 | .read = pci_sal_read, | 98 | .read = pci_sal_read, |
99 | .write = pci_sal_write | 99 | .write = pci_sal_write |
100 | }; | 100 | }; |
101 | 101 | ||
@@ -137,35 +137,98 @@ alloc_pci_controller (int seg) | |||
137 | return controller; | 137 | return controller; |
138 | } | 138 | } |
139 | 139 | ||
140 | static u64 __devinit | 140 | struct pci_root_info { |
141 | add_io_space (struct acpi_resource_address64 *addr) | 141 | struct pci_controller *controller; |
142 | char *name; | ||
143 | }; | ||
144 | |||
145 | static unsigned int | ||
146 | new_space (u64 phys_base, int sparse) | ||
142 | { | 147 | { |
143 | u64 offset; | 148 | u64 mmio_base; |
144 | int sparse = 0; | ||
145 | int i; | 149 | int i; |
146 | 150 | ||
147 | if (addr->address_translation_offset == 0) | 151 | if (phys_base == 0) |
148 | return IO_SPACE_BASE(0); /* part of legacy IO space */ | 152 | return 0; /* legacy I/O port space */ |
149 | |||
150 | if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION) | ||
151 | sparse = 1; | ||
152 | 153 | ||
153 | offset = (u64) ioremap(addr->address_translation_offset, 0); | 154 | mmio_base = (u64) ioremap(phys_base, 0); |
154 | for (i = 0; i < num_io_spaces; i++) | 155 | for (i = 0; i < num_io_spaces; i++) |
155 | if (io_space[i].mmio_base == offset && | 156 | if (io_space[i].mmio_base == mmio_base && |
156 | io_space[i].sparse == sparse) | 157 | io_space[i].sparse == sparse) |
157 | return IO_SPACE_BASE(i); | 158 | return i; |
158 | 159 | ||
159 | if (num_io_spaces == MAX_IO_SPACES) { | 160 | if (num_io_spaces == MAX_IO_SPACES) { |
160 | printk("Too many IO port spaces\n"); | 161 | printk(KERN_ERR "PCI: Too many IO port spaces " |
162 | "(MAX_IO_SPACES=%lu)\n", MAX_IO_SPACES); | ||
161 | return ~0; | 163 | return ~0; |
162 | } | 164 | } |
163 | 165 | ||
164 | i = num_io_spaces++; | 166 | i = num_io_spaces++; |
165 | io_space[i].mmio_base = offset; | 167 | io_space[i].mmio_base = mmio_base; |
166 | io_space[i].sparse = sparse; | 168 | io_space[i].sparse = sparse; |
167 | 169 | ||
168 | return IO_SPACE_BASE(i); | 170 | return i; |
171 | } | ||
172 | |||
173 | static u64 __devinit | ||
174 | add_io_space (struct pci_root_info *info, struct acpi_resource_address64 *addr) | ||
175 | { | ||
176 | struct resource *resource; | ||
177 | char *name; | ||
178 | u64 base, min, max, base_port; | ||
179 | unsigned int sparse = 0, space_nr, len; | ||
180 | |||
181 | resource = kzalloc(sizeof(*resource), GFP_KERNEL); | ||
182 | if (!resource) { | ||
183 | printk(KERN_ERR "PCI: No memory for %s I/O port space\n", | ||
184 | info->name); | ||
185 | goto out; | ||
186 | } | ||
187 | |||
188 | len = strlen(info->name) + 32; | ||
189 | name = kzalloc(len, GFP_KERNEL); | ||
190 | if (!name) { | ||
191 | printk(KERN_ERR "PCI: No memory for %s I/O port space name\n", | ||
192 | info->name); | ||
193 | goto free_resource; | ||
194 | } | ||
195 | |||
196 | min = addr->min_address_range; | ||
197 | max = min + addr->address_length - 1; | ||
198 | if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION) | ||
199 | sparse = 1; | ||
200 | |||
201 | space_nr = new_space(addr->address_translation_offset, sparse); | ||
202 | if (space_nr == ~0) | ||
203 | goto free_name; | ||
204 | |||
205 | base = __pa(io_space[space_nr].mmio_base); | ||
206 | base_port = IO_SPACE_BASE(space_nr); | ||
207 | snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->name, | ||
208 | base_port + min, base_port + max); | ||
209 | |||
210 | /* | ||
211 | * The SDM guarantees the legacy 0-64K space is sparse, but if the | ||
212 | * mapping is done by the processor (not the bridge), ACPI may not | ||
213 | * mark it as sparse. | ||
214 | */ | ||
215 | if (space_nr == 0) | ||
216 | sparse = 1; | ||
217 | |||
218 | resource->name = name; | ||
219 | resource->flags = IORESOURCE_MEM; | ||
220 | resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min); | ||
221 | resource->end = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max); | ||
222 | insert_resource(&iomem_resource, resource); | ||
223 | |||
224 | return base_port; | ||
225 | |||
226 | free_name: | ||
227 | kfree(name); | ||
228 | free_resource: | ||
229 | kfree(resource); | ||
230 | out: | ||
231 | return ~0; | ||
169 | } | 232 | } |
170 | 233 | ||
171 | static acpi_status __devinit resource_to_window(struct acpi_resource *resource, | 234 | static acpi_status __devinit resource_to_window(struct acpi_resource *resource, |
@@ -205,11 +268,6 @@ count_window (struct acpi_resource *resource, void *data) | |||
205 | return AE_OK; | 268 | return AE_OK; |
206 | } | 269 | } |
207 | 270 | ||
208 | struct pci_root_info { | ||
209 | struct pci_controller *controller; | ||
210 | char *name; | ||
211 | }; | ||
212 | |||
213 | static __devinit acpi_status add_window(struct acpi_resource *res, void *data) | 271 | static __devinit acpi_status add_window(struct acpi_resource *res, void *data) |
214 | { | 272 | { |
215 | struct pci_root_info *info = data; | 273 | struct pci_root_info *info = data; |
@@ -231,7 +289,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) | |||
231 | } else if (addr.resource_type == ACPI_IO_RANGE) { | 289 | } else if (addr.resource_type == ACPI_IO_RANGE) { |
232 | flags = IORESOURCE_IO; | 290 | flags = IORESOURCE_IO; |
233 | root = &ioport_resource; | 291 | root = &ioport_resource; |
234 | offset = add_io_space(&addr); | 292 | offset = add_io_space(info, &addr); |
235 | if (offset == ~0) | 293 | if (offset == ~0) |
236 | return AE_OK; | 294 | return AE_OK; |
237 | } else | 295 | } else |
@@ -241,7 +299,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) | |||
241 | window->resource.name = info->name; | 299 | window->resource.name = info->name; |
242 | window->resource.flags = flags; | 300 | window->resource.flags = flags; |
243 | window->resource.start = addr.min_address_range + offset; | 301 | window->resource.start = addr.min_address_range + offset; |
244 | window->resource.end = addr.max_address_range + offset; | 302 | window->resource.end = window->resource.start + addr.address_length - 1; |
245 | window->resource.child = NULL; | 303 | window->resource.child = NULL; |
246 | window->offset = offset; | 304 | window->offset = offset; |
247 | 305 | ||
@@ -739,7 +797,7 @@ int pci_vector_resources(int last, int nr_released) | |||
739 | { | 797 | { |
740 | int count = nr_released; | 798 | int count = nr_released; |
741 | 799 | ||
742 | count += (IA64_LAST_DEVICE_VECTOR - last); | 800 | count += (IA64_LAST_DEVICE_VECTOR - last); |
743 | 801 | ||
744 | return count; | 802 | return count; |
745 | } | 803 | } |
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index b4f5053f5e1b..05e4ea889981 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
@@ -349,7 +349,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
349 | return; /*bus # does not exist */ | 349 | return; /*bus # does not exist */ |
350 | prom_bussoft_ptr = __va(prom_bussoft_ptr); | 350 | prom_bussoft_ptr = __va(prom_bussoft_ptr); |
351 | 351 | ||
352 | controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL); | 352 | controller = kzalloc(sizeof(struct pci_controller), GFP_KERNEL); |
353 | controller->segment = segment; | 353 | controller->segment = segment; |
354 | if (!controller) | 354 | if (!controller) |
355 | BUG(); | 355 | BUG(); |
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 0fb579ef18c2..e510dce9971f 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/root_dev.h> | 30 | #include <linux/root_dev.h> |
31 | #include <linux/nodemask.h> | 31 | #include <linux/nodemask.h> |
32 | #include <linux/pm.h> | 32 | #include <linux/pm.h> |
33 | #include <linux/efi.h> | ||
33 | 34 | ||
34 | #include <asm/io.h> | 35 | #include <asm/io.h> |
35 | #include <asm/sal.h> | 36 | #include <asm/sal.h> |
@@ -242,6 +243,135 @@ static void __init sn_check_for_wars(void) | |||
242 | } | 243 | } |
243 | } | 244 | } |
244 | 245 | ||
246 | /* | ||
247 | * Scan the EFI PCDP table (if it exists) for an acceptable VGA console | ||
248 | * output device. If one exists, pick it and set sn_legacy_{io,mem} to | ||
249 | * reflect the bus offsets needed to address it. | ||
250 | * | ||
251 | * Since pcdp support in SN is not supported in the 2.4 kernel (or at least | ||
252 | * the one lbs is based on) just declare the needed structs here. | ||
253 | * | ||
254 | * Reference spec http://www.dig64.org/specifications/DIG64_PCDPv20.pdf | ||
255 | * | ||
256 | * Returns 0 if no acceptable vga is found, !0 otherwise. | ||
257 | * | ||
258 | * Note: This stuff is duped here because Altix requires the PCDP to | ||
259 | * locate a usable VGA device due to lack of proper ACPI support. Structures | ||
260 | * could be used from drivers/firmware/pcdp.h, but it was decided that moving | ||
261 | * this file to a more public location just for Altix use was undesireable. | ||
262 | */ | ||
263 | |||
264 | struct hcdp_uart_desc { | ||
265 | u8 pad[45]; | ||
266 | }; | ||
267 | |||
268 | struct pcdp { | ||
269 | u8 signature[4]; /* should be 'HCDP' */ | ||
270 | u32 length; | ||
271 | u8 rev; /* should be >=3 for pcdp, <3 for hcdp */ | ||
272 | u8 sum; | ||
273 | u8 oem_id[6]; | ||
274 | u64 oem_tableid; | ||
275 | u32 oem_rev; | ||
276 | u32 creator_id; | ||
277 | u32 creator_rev; | ||
278 | u32 num_type0; | ||
279 | struct hcdp_uart_desc uart[0]; /* num_type0 of these */ | ||
280 | /* pcdp descriptors follow */ | ||
281 | } __attribute__((packed)); | ||
282 | |||
283 | struct pcdp_device_desc { | ||
284 | u8 type; | ||
285 | u8 primary; | ||
286 | u16 length; | ||
287 | u16 index; | ||
288 | /* interconnect specific structure follows */ | ||
289 | /* device specific structure follows that */ | ||
290 | } __attribute__((packed)); | ||
291 | |||
292 | struct pcdp_interface_pci { | ||
293 | u8 type; /* 1 == pci */ | ||
294 | u8 reserved; | ||
295 | u16 length; | ||
296 | u8 segment; | ||
297 | u8 bus; | ||
298 | u8 dev; | ||
299 | u8 fun; | ||
300 | u16 devid; | ||
301 | u16 vendid; | ||
302 | u32 acpi_interrupt; | ||
303 | u64 mmio_tra; | ||
304 | u64 ioport_tra; | ||
305 | u8 flags; | ||
306 | u8 translation; | ||
307 | } __attribute__((packed)); | ||
308 | |||
309 | struct pcdp_vga_device { | ||
310 | u8 num_eas_desc; | ||
311 | /* ACPI Extended Address Space Desc follows */ | ||
312 | } __attribute__((packed)); | ||
313 | |||
314 | /* from pcdp_device_desc.primary */ | ||
315 | #define PCDP_PRIMARY_CONSOLE 0x01 | ||
316 | |||
317 | /* from pcdp_device_desc.type */ | ||
318 | #define PCDP_CONSOLE_INOUT 0x0 | ||
319 | #define PCDP_CONSOLE_DEBUG 0x1 | ||
320 | #define PCDP_CONSOLE_OUT 0x2 | ||
321 | #define PCDP_CONSOLE_IN 0x3 | ||
322 | #define PCDP_CONSOLE_TYPE_VGA 0x8 | ||
323 | |||
324 | #define PCDP_CONSOLE_VGA (PCDP_CONSOLE_TYPE_VGA | PCDP_CONSOLE_OUT) | ||
325 | |||
326 | /* from pcdp_interface_pci.type */ | ||
327 | #define PCDP_IF_PCI 1 | ||
328 | |||
329 | /* from pcdp_interface_pci.translation */ | ||
330 | #define PCDP_PCI_TRANS_IOPORT 0x02 | ||
331 | #define PCDP_PCI_TRANS_MMIO 0x01 | ||
332 | |||
333 | static void | ||
334 | sn_scan_pcdp(void) | ||
335 | { | ||
336 | u8 *bp; | ||
337 | struct pcdp *pcdp; | ||
338 | struct pcdp_device_desc device; | ||
339 | struct pcdp_interface_pci if_pci; | ||
340 | extern struct efi efi; | ||
341 | |||
342 | pcdp = efi.hcdp; | ||
343 | if (! pcdp) | ||
344 | return; /* no hcdp/pcdp table */ | ||
345 | |||
346 | if (pcdp->rev < 3) | ||
347 | return; /* only support PCDP (rev >= 3) */ | ||
348 | |||
349 | for (bp = (u8 *)&pcdp->uart[pcdp->num_type0]; | ||
350 | bp < (u8 *)pcdp + pcdp->length; | ||
351 | bp += device.length) { | ||
352 | memcpy(&device, bp, sizeof(device)); | ||
353 | if (! (device.primary & PCDP_PRIMARY_CONSOLE)) | ||
354 | continue; /* not primary console */ | ||
355 | |||
356 | if (device.type != PCDP_CONSOLE_VGA) | ||
357 | continue; /* not VGA descriptor */ | ||
358 | |||
359 | memcpy(&if_pci, bp+sizeof(device), sizeof(if_pci)); | ||
360 | if (if_pci.type != PCDP_IF_PCI) | ||
361 | continue; /* not PCI interconnect */ | ||
362 | |||
363 | if (if_pci.translation & PCDP_PCI_TRANS_IOPORT) | ||
364 | vga_console_iobase = | ||
365 | if_pci.ioport_tra | __IA64_UNCACHED_OFFSET; | ||
366 | |||
367 | if (if_pci.translation & PCDP_PCI_TRANS_MMIO) | ||
368 | vga_console_membase = | ||
369 | if_pci.mmio_tra | __IA64_UNCACHED_OFFSET; | ||
370 | |||
371 | break; /* once we find the primary, we're done */ | ||
372 | } | ||
373 | } | ||
374 | |||
245 | /** | 375 | /** |
246 | * sn_setup - SN platform setup routine | 376 | * sn_setup - SN platform setup routine |
247 | * @cmdline_p: kernel command line | 377 | * @cmdline_p: kernel command line |
@@ -263,16 +393,35 @@ void __init sn_setup(char **cmdline_p) | |||
263 | 393 | ||
264 | #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) | 394 | #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) |
265 | /* | 395 | /* |
266 | * If there was a primary vga adapter identified through the | 396 | * Handle SN vga console. |
267 | * EFI PCDP table, make it the preferred console. Otherwise | 397 | * |
268 | * zero out conswitchp. | 398 | * SN systems do not have enough ACPI table information |
399 | * being passed from prom to identify VGA adapters and the legacy | ||
400 | * addresses to access them. Until that is done, SN systems rely | ||
401 | * on the PCDP table to identify the primary VGA console if one | ||
402 | * exists. | ||
403 | * | ||
404 | * However, kernel PCDP support is optional, and even if it is built | ||
405 | * into the kernel, it will not be used if the boot cmdline contains | ||
406 | * console= directives. | ||
407 | * | ||
408 | * So, to work around this mess, we duplicate some of the PCDP code | ||
409 | * here so that the primary VGA console (as defined by PCDP) will | ||
410 | * work on SN systems even if a different console (e.g. serial) is | ||
411 | * selected on the boot line (or CONFIG_EFI_PCDP is off). | ||
269 | */ | 412 | */ |
270 | 413 | ||
414 | if (! vga_console_membase) | ||
415 | sn_scan_pcdp(); | ||
416 | |||
271 | if (vga_console_membase) { | 417 | if (vga_console_membase) { |
272 | /* usable vga ... make tty0 the preferred default console */ | 418 | /* usable vga ... make tty0 the preferred default console */ |
273 | add_preferred_console("tty", 0, NULL); | 419 | if (!strstr(*cmdline_p, "console=")) |
420 | add_preferred_console("tty", 0, NULL); | ||
274 | } else { | 421 | } else { |
275 | printk(KERN_DEBUG "SGI: Disabling VGA console\n"); | 422 | printk(KERN_DEBUG "SGI: Disabling VGA console\n"); |
423 | if (!strstr(*cmdline_p, "console=")) | ||
424 | add_preferred_console("ttySG", 0, NULL); | ||
276 | #ifdef CONFIG_DUMMY_CONSOLE | 425 | #ifdef CONFIG_DUMMY_CONSOLE |
277 | conswitchp = &dummy_con; | 426 | conswitchp = &dummy_con; |
278 | #else | 427 | #else |
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h index fbcedc7c27fa..5483a9f227d4 100644 --- a/arch/ia64/sn/kernel/xpc.h +++ b/arch/ia64/sn/kernel/xpc.h | |||
@@ -163,7 +163,7 @@ struct xpc_vars { | |||
163 | u8 version; | 163 | u8 version; |
164 | u64 heartbeat; | 164 | u64 heartbeat; |
165 | u64 heartbeating_to_mask; | 165 | u64 heartbeating_to_mask; |
166 | u64 kdb_status; /* 0 = machine running */ | 166 | u64 heartbeat_offline; /* if 0, heartbeat should be changing */ |
167 | int act_nasid; | 167 | int act_nasid; |
168 | int act_phys_cpuid; | 168 | int act_phys_cpuid; |
169 | u64 vars_part_pa; | 169 | u64 vars_part_pa; |
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c index cece3c7c69be..b617236524c6 100644 --- a/arch/ia64/sn/kernel/xpc_main.c +++ b/arch/ia64/sn/kernel/xpc_main.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/reboot.h> | 57 | #include <linux/reboot.h> |
58 | #include <asm/sn/intr.h> | 58 | #include <asm/sn/intr.h> |
59 | #include <asm/sn/sn_sal.h> | 59 | #include <asm/sn/sn_sal.h> |
60 | #include <asm/kdebug.h> | ||
60 | #include <asm/uaccess.h> | 61 | #include <asm/uaccess.h> |
61 | #include "xpc.h" | 62 | #include "xpc.h" |
62 | 63 | ||
@@ -188,6 +189,11 @@ static struct notifier_block xpc_reboot_notifier = { | |||
188 | .notifier_call = xpc_system_reboot, | 189 | .notifier_call = xpc_system_reboot, |
189 | }; | 190 | }; |
190 | 191 | ||
192 | static int xpc_system_die(struct notifier_block *, unsigned long, void *); | ||
193 | static struct notifier_block xpc_die_notifier = { | ||
194 | .notifier_call = xpc_system_die, | ||
195 | }; | ||
196 | |||
191 | 197 | ||
192 | /* | 198 | /* |
193 | * Timer function to enforce the timelimit on the partition disengage request. | 199 | * Timer function to enforce the timelimit on the partition disengage request. |
@@ -997,6 +1003,9 @@ xpc_do_exit(enum xpc_retval reason) | |||
997 | /* take ourselves off of the reboot_notifier_list */ | 1003 | /* take ourselves off of the reboot_notifier_list */ |
998 | (void) unregister_reboot_notifier(&xpc_reboot_notifier); | 1004 | (void) unregister_reboot_notifier(&xpc_reboot_notifier); |
999 | 1005 | ||
1006 | /* take ourselves off of the die_notifier list */ | ||
1007 | (void) unregister_die_notifier(&xpc_die_notifier); | ||
1008 | |||
1000 | /* close down protections for IPI operations */ | 1009 | /* close down protections for IPI operations */ |
1001 | xpc_restrict_IPI_ops(); | 1010 | xpc_restrict_IPI_ops(); |
1002 | 1011 | ||
@@ -1011,6 +1020,63 @@ xpc_do_exit(enum xpc_retval reason) | |||
1011 | 1020 | ||
1012 | 1021 | ||
1013 | /* | 1022 | /* |
1023 | * Called when the system is about to be either restarted or halted. | ||
1024 | */ | ||
1025 | static void | ||
1026 | xpc_die_disengage(void) | ||
1027 | { | ||
1028 | struct xpc_partition *part; | ||
1029 | partid_t partid; | ||
1030 | unsigned long engaged; | ||
1031 | long time, print_time, disengage_request_timeout; | ||
1032 | |||
1033 | |||
1034 | /* keep xpc_hb_checker thread from doing anything (just in case) */ | ||
1035 | xpc_exiting = 1; | ||
1036 | |||
1037 | xpc_vars->heartbeating_to_mask = 0; /* indicate we're deactivated */ | ||
1038 | |||
1039 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | ||
1040 | part = &xpc_partitions[partid]; | ||
1041 | |||
1042 | if (!XPC_SUPPORTS_DISENGAGE_REQUEST(part-> | ||
1043 | remote_vars_version)) { | ||
1044 | |||
1045 | /* just in case it was left set by an earlier XPC */ | ||
1046 | xpc_clear_partition_engaged(1UL << partid); | ||
1047 | continue; | ||
1048 | } | ||
1049 | |||
1050 | if (xpc_partition_engaged(1UL << partid) || | ||
1051 | part->act_state != XPC_P_INACTIVE) { | ||
1052 | xpc_request_partition_disengage(part); | ||
1053 | xpc_mark_partition_disengaged(part); | ||
1054 | xpc_IPI_send_disengage(part); | ||
1055 | } | ||
1056 | } | ||
1057 | |||
1058 | print_time = rtc_time(); | ||
1059 | disengage_request_timeout = print_time + | ||
1060 | (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second); | ||
1061 | |||
1062 | /* wait for all other partitions to disengage from us */ | ||
1063 | |||
1064 | while ((engaged = xpc_partition_engaged(-1UL)) && | ||
1065 | (time = rtc_time()) < disengage_request_timeout) { | ||
1066 | |||
1067 | if (time >= print_time) { | ||
1068 | dev_info(xpc_part, "waiting for remote partitions to " | ||
1069 | "disengage, engaged=0x%lx\n", engaged); | ||
1070 | print_time = time + (XPC_DISENGAGE_PRINTMSG_INTERVAL * | ||
1071 | sn_rtc_cycles_per_second); | ||
1072 | } | ||
1073 | } | ||
1074 | dev_info(xpc_part, "finished waiting for remote partitions to " | ||
1075 | "disengage, engaged=0x%lx\n", engaged); | ||
1076 | } | ||
1077 | |||
1078 | |||
1079 | /* | ||
1014 | * This function is called when the system is being rebooted. | 1080 | * This function is called when the system is being rebooted. |
1015 | */ | 1081 | */ |
1016 | static int | 1082 | static int |
@@ -1038,6 +1104,33 @@ xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused) | |||
1038 | } | 1104 | } |
1039 | 1105 | ||
1040 | 1106 | ||
1107 | /* | ||
1108 | * This function is called when the system is being rebooted. | ||
1109 | */ | ||
1110 | static int | ||
1111 | xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused) | ||
1112 | { | ||
1113 | switch (event) { | ||
1114 | case DIE_MACHINE_RESTART: | ||
1115 | case DIE_MACHINE_HALT: | ||
1116 | xpc_die_disengage(); | ||
1117 | break; | ||
1118 | case DIE_MCA_MONARCH_ENTER: | ||
1119 | case DIE_INIT_MONARCH_ENTER: | ||
1120 | xpc_vars->heartbeat++; | ||
1121 | xpc_vars->heartbeat_offline = 1; | ||
1122 | break; | ||
1123 | case DIE_MCA_MONARCH_LEAVE: | ||
1124 | case DIE_INIT_MONARCH_LEAVE: | ||
1125 | xpc_vars->heartbeat++; | ||
1126 | xpc_vars->heartbeat_offline = 0; | ||
1127 | break; | ||
1128 | } | ||
1129 | |||
1130 | return NOTIFY_DONE; | ||
1131 | } | ||
1132 | |||
1133 | |||
1041 | int __init | 1134 | int __init |
1042 | xpc_init(void) | 1135 | xpc_init(void) |
1043 | { | 1136 | { |
@@ -1154,6 +1247,12 @@ xpc_init(void) | |||
1154 | dev_warn(xpc_part, "can't register reboot notifier\n"); | 1247 | dev_warn(xpc_part, "can't register reboot notifier\n"); |
1155 | } | 1248 | } |
1156 | 1249 | ||
1250 | /* add ourselves to the die_notifier list (i.e., ia64die_chain) */ | ||
1251 | ret = register_die_notifier(&xpc_die_notifier); | ||
1252 | if (ret != 0) { | ||
1253 | dev_warn(xpc_part, "can't register die notifier\n"); | ||
1254 | } | ||
1255 | |||
1157 | 1256 | ||
1158 | /* | 1257 | /* |
1159 | * Set the beating to other partitions into motion. This is | 1258 | * Set the beating to other partitions into motion. This is |
@@ -1179,6 +1278,9 @@ xpc_init(void) | |||
1179 | /* take ourselves off of the reboot_notifier_list */ | 1278 | /* take ourselves off of the reboot_notifier_list */ |
1180 | (void) unregister_reboot_notifier(&xpc_reboot_notifier); | 1279 | (void) unregister_reboot_notifier(&xpc_reboot_notifier); |
1181 | 1280 | ||
1281 | /* take ourselves off of the die_notifier list */ | ||
1282 | (void) unregister_die_notifier(&xpc_die_notifier); | ||
1283 | |||
1182 | del_timer_sync(&xpc_hb_timer); | 1284 | del_timer_sync(&xpc_hb_timer); |
1183 | free_irq(SGI_XPC_ACTIVATE, NULL); | 1285 | free_irq(SGI_XPC_ACTIVATE, NULL); |
1184 | xpc_restrict_IPI_ops(); | 1286 | xpc_restrict_IPI_ops(); |
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c index 581e113d2d37..cdd6431853a1 100644 --- a/arch/ia64/sn/kernel/xpc_partition.c +++ b/arch/ia64/sn/kernel/xpc_partition.c | |||
@@ -436,13 +436,13 @@ xpc_check_remote_hb(void) | |||
436 | } | 436 | } |
437 | 437 | ||
438 | dev_dbg(xpc_part, "partid = %d, heartbeat = %ld, last_heartbeat" | 438 | dev_dbg(xpc_part, "partid = %d, heartbeat = %ld, last_heartbeat" |
439 | " = %ld, kdb_status = %ld, HB_mask = 0x%lx\n", partid, | 439 | " = %ld, heartbeat_offline = %ld, HB_mask = 0x%lx\n", |
440 | remote_vars->heartbeat, part->last_heartbeat, | 440 | partid, remote_vars->heartbeat, part->last_heartbeat, |
441 | remote_vars->kdb_status, | 441 | remote_vars->heartbeat_offline, |
442 | remote_vars->heartbeating_to_mask); | 442 | remote_vars->heartbeating_to_mask); |
443 | 443 | ||
444 | if (((remote_vars->heartbeat == part->last_heartbeat) && | 444 | if (((remote_vars->heartbeat == part->last_heartbeat) && |
445 | (remote_vars->kdb_status == 0)) || | 445 | (remote_vars->heartbeat_offline == 0)) || |
446 | !xpc_hb_allowed(sn_partition_id, remote_vars)) { | 446 | !xpc_hb_allowed(sn_partition_id, remote_vars)) { |
447 | 447 | ||
448 | XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat); | 448 | XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat); |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 7b03b8084ffc..1f500c81002c 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c | |||
@@ -212,13 +212,13 @@ void pcibr_target_interrupt(struct sn_irq_info *sn_irq_info) | |||
212 | pdi_pcibus_info; | 212 | pdi_pcibus_info; |
213 | 213 | ||
214 | /* Disable the device's IRQ */ | 214 | /* Disable the device's IRQ */ |
215 | pcireg_intr_enable_bit_clr(pcibus_info, bit); | 215 | pcireg_intr_enable_bit_clr(pcibus_info, (1 << bit)); |
216 | 216 | ||
217 | /* Change the device's IRQ */ | 217 | /* Change the device's IRQ */ |
218 | pcireg_intr_addr_addr_set(pcibus_info, bit, xtalk_addr); | 218 | pcireg_intr_addr_addr_set(pcibus_info, bit, xtalk_addr); |
219 | 219 | ||
220 | /* Re-enable the device's IRQ */ | 220 | /* Re-enable the device's IRQ */ |
221 | pcireg_intr_enable_bit_set(pcibus_info, bit); | 221 | pcireg_intr_enable_bit_set(pcibus_info, (1 << bit)); |
222 | 222 | ||
223 | pcibr_force_interrupt(sn_irq_info); | 223 | pcibr_force_interrupt(sn_irq_info); |
224 | } | 224 | } |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c index 4f718c3e93d3..5d534091262c 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c | |||
@@ -131,7 +131,7 @@ void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) | |||
131 | __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits); | 131 | __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits); |
132 | break; | 132 | break; |
133 | case PCIBR_BRIDGETYPE_PIC: | 133 | case PCIBR_BRIDGETYPE_PIC: |
134 | __sn_clrq_relaxed(&ptr->pic.p_int_enable, ~bits); | 134 | __sn_clrq_relaxed(&ptr->pic.p_int_enable, bits); |
135 | break; | 135 | break; |
136 | default: | 136 | default: |
137 | panic | 137 | panic |
diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index 9f03d4e5121c..dda196c9e324 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c | |||
@@ -218,7 +218,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port, | |||
218 | if (i > last) | 218 | if (i > last) |
219 | return 0; | 219 | return 0; |
220 | 220 | ||
221 | map = kcalloc(1, sizeof(struct tioce_dmamap), GFP_ATOMIC); | 221 | map = kzalloc(sizeof(struct tioce_dmamap), GFP_ATOMIC); |
222 | if (!map) | 222 | if (!map) |
223 | return 0; | 223 | return 0; |
224 | 224 | ||
@@ -555,7 +555,7 @@ tioce_kern_init(struct tioce_common *tioce_common) | |||
555 | struct tioce *tioce_mmr; | 555 | struct tioce *tioce_mmr; |
556 | struct tioce_kernel *tioce_kern; | 556 | struct tioce_kernel *tioce_kern; |
557 | 557 | ||
558 | tioce_kern = kcalloc(1, sizeof(struct tioce_kernel), GFP_KERNEL); | 558 | tioce_kern = kzalloc(sizeof(struct tioce_kernel), GFP_KERNEL); |
559 | if (!tioce_kern) { | 559 | if (!tioce_kern) { |
560 | return NULL; | 560 | return NULL; |
561 | } | 561 | } |
@@ -727,7 +727,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont | |||
727 | * Allocate kernel bus soft and copy from prom. | 727 | * Allocate kernel bus soft and copy from prom. |
728 | */ | 728 | */ |
729 | 729 | ||
730 | tioce_common = kcalloc(1, sizeof(struct tioce_common), GFP_KERNEL); | 730 | tioce_common = kzalloc(sizeof(struct tioce_common), GFP_KERNEL); |
731 | if (!tioce_common) | 731 | if (!tioce_common) |
732 | return NULL; | 732 | return NULL; |
733 | 733 | ||