aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r--arch/ia64/kernel/acpi.c10
-rw-r--r--arch/ia64/kernel/entry.S26
-rw-r--r--arch/ia64/kernel/palinfo.c6
-rw-r--r--arch/ia64/kernel/perfmon.c16
-rw-r--r--arch/ia64/kernel/process.c25
-rw-r--r--arch/ia64/kernel/sal.c11
-rw-r--r--arch/ia64/kernel/setup.c29
7 files changed, 96 insertions, 27 deletions
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 19709a079635..853d1f11be00 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -117,7 +117,10 @@ acpi_get_sysname(void)
117 if (!strcmp(hdr->oem_id, "HP")) { 117 if (!strcmp(hdr->oem_id, "HP")) {
118 return "hpzx1"; 118 return "hpzx1";
119 } else if (!strcmp(hdr->oem_id, "SGI")) { 119 } else if (!strcmp(hdr->oem_id, "SGI")) {
120 return "sn2"; 120 if (!strcmp(hdr->oem_table_id + 4, "UV"))
121 return "uv";
122 else
123 return "sn2";
121 } 124 }
122 125
123 return "dig"; 126 return "dig";
@@ -130,6 +133,8 @@ acpi_get_sysname(void)
130 return "hpzx1_swiotlb"; 133 return "hpzx1_swiotlb";
131# elif defined (CONFIG_IA64_SGI_SN2) 134# elif defined (CONFIG_IA64_SGI_SN2)
132 return "sn2"; 135 return "sn2";
136# elif defined (CONFIG_IA64_SGI_UV)
137 return "uv";
133# elif defined (CONFIG_IA64_DIG) 138# elif defined (CONFIG_IA64_DIG)
134 return "dig"; 139 return "dig";
135# else 140# else
@@ -622,6 +627,9 @@ void acpi_unregister_gsi(u32 gsi)
622 if (acpi_irq_model == ACPI_IRQ_MODEL_PLATFORM) 627 if (acpi_irq_model == ACPI_IRQ_MODEL_PLATFORM)
623 return; 628 return;
624 629
630 if (has_8259 && gsi < 16)
631 return;
632
625 iosapic_unregister_intr(gsi); 633 iosapic_unregister_intr(gsi);
626} 634}
627 635
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index e49ad8c5dc69..ca2bb95726de 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1156,6 +1156,9 @@ skip_rbs_switch:
1156 * r31 = current->thread_info->flags 1156 * r31 = current->thread_info->flags
1157 * On exit: 1157 * On exit:
1158 * p6 = TRUE if work-pending-check needs to be redone 1158 * p6 = TRUE if work-pending-check needs to be redone
1159 *
1160 * Interrupts are disabled on entry, reenabled depend on work, and
1161 * disabled on exit.
1159 */ 1162 */
1160.work_pending_syscall: 1163.work_pending_syscall:
1161 add r2=-8,r2 1164 add r2=-8,r2
@@ -1164,16 +1167,16 @@ skip_rbs_switch:
1164 st8 [r2]=r8 1167 st8 [r2]=r8
1165 st8 [r3]=r10 1168 st8 [r3]=r10
1166.work_pending: 1169.work_pending:
1167 tbit.z p6,p0=r31,TIF_NEED_RESCHED // current_thread_info()->need_resched==0? 1170 tbit.z p6,p0=r31,TIF_NEED_RESCHED // is resched not needed?
1168(p6) br.cond.sptk.few .notify 1171(p6) br.cond.sptk.few .notify
1169#ifdef CONFIG_PREEMPT 1172#ifdef CONFIG_PREEMPT
1170(pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1 1173(pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1
1171 ;; 1174 ;;
1172(pKStk) st4 [r20]=r21 1175(pKStk) st4 [r20]=r21
1173 ssm psr.i // enable interrupts
1174#endif 1176#endif
1177 ssm psr.i // enable interrupts
1175 br.call.spnt.many rp=schedule 1178 br.call.spnt.many rp=schedule
1176.ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 1179.ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 (re-check)
1177 rsm psr.i // disable interrupts 1180 rsm psr.i // disable interrupts
1178 ;; 1181 ;;
1179#ifdef CONFIG_PREEMPT 1182#ifdef CONFIG_PREEMPT
@@ -1182,13 +1185,13 @@ skip_rbs_switch:
1182(pKStk) st4 [r20]=r0 // preempt_count() <- 0 1185(pKStk) st4 [r20]=r0 // preempt_count() <- 0
1183#endif 1186#endif
1184(pLvSys)br.cond.sptk.few .work_pending_syscall_end 1187(pLvSys)br.cond.sptk.few .work_pending_syscall_end
1185 br.cond.sptk.many .work_processed_kernel // re-check 1188 br.cond.sptk.many .work_processed_kernel
1186 1189
1187.notify: 1190.notify:
1188(pUStk) br.call.spnt.many rp=notify_resume_user 1191(pUStk) br.call.spnt.many rp=notify_resume_user
1189.ret10: cmp.ne p6,p0=r0,r0 // p6 <- 0 1192.ret10: cmp.ne p6,p0=r0,r0 // p6 <- 0 (don't re-check)
1190(pLvSys)br.cond.sptk.few .work_pending_syscall_end 1193(pLvSys)br.cond.sptk.few .work_pending_syscall_end
1191 br.cond.sptk.many .work_processed_kernel // don't re-check 1194 br.cond.sptk.many .work_processed_kernel
1192 1195
1193.work_pending_syscall_end: 1196.work_pending_syscall_end:
1194 adds r2=PT(R8)+16,r12 1197 adds r2=PT(R8)+16,r12
@@ -1196,7 +1199,7 @@ skip_rbs_switch:
1196 ;; 1199 ;;
1197 ld8 r8=[r2] 1200 ld8 r8=[r2]
1198 ld8 r10=[r3] 1201 ld8 r10=[r3]
1199 br.cond.sptk.many .work_processed_syscall // re-check 1202 br.cond.sptk.many .work_processed_syscall
1200 1203
1201END(ia64_leave_kernel) 1204END(ia64_leave_kernel)
1202 1205
@@ -1234,9 +1237,12 @@ GLOBAL_ENTRY(ia64_invoke_schedule_tail)
1234END(ia64_invoke_schedule_tail) 1237END(ia64_invoke_schedule_tail)
1235 1238
1236 /* 1239 /*
1237 * Setup stack and call do_notify_resume_user(). Note that pSys and pNonSys need to 1240 * Setup stack and call do_notify_resume_user(), keeping interrupts
1238 * be set up by the caller. We declare 8 input registers so the system call 1241 * disabled.
1239 * args get preserved, in case we need to restart a system call. 1242 *
1243 * Note that pSys and pNonSys need to be set up by the caller.
1244 * We declare 8 input registers so the system call args get preserved,
1245 * in case we need to restart a system call.
1240 */ 1246 */
1241ENTRY(notify_resume_user) 1247ENTRY(notify_resume_user)
1242 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) 1248 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c
index 4547a2092af9..9dc00f7fe10e 100644
--- a/arch/ia64/kernel/palinfo.c
+++ b/arch/ia64/kernel/palinfo.c
@@ -900,12 +900,6 @@ static void
900palinfo_smp_call(void *info) 900palinfo_smp_call(void *info)
901{ 901{
902 palinfo_smp_data_t *data = (palinfo_smp_data_t *)info; 902 palinfo_smp_data_t *data = (palinfo_smp_data_t *)info;
903 if (data == NULL) {
904 printk(KERN_ERR "palinfo: data pointer is NULL\n");
905 data->ret = 0; /* no output */
906 return;
907 }
908 /* does this actual call */
909 data->ret = (*data->func)(data->page); 903 data->ret = (*data->func)(data->page);
910} 904}
911 905
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index c1ad27de2dd2..71d05133f556 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -5013,12 +5013,13 @@ pfm_context_force_terminate(pfm_context_t *ctx, struct pt_regs *regs)
5013} 5013}
5014 5014
5015static int pfm_ovfl_notify_user(pfm_context_t *ctx, unsigned long ovfl_pmds); 5015static int pfm_ovfl_notify_user(pfm_context_t *ctx, unsigned long ovfl_pmds);
5016
5016 /* 5017 /*
5017 * pfm_handle_work() can be called with interrupts enabled 5018 * pfm_handle_work() can be called with interrupts enabled
5018 * (TIF_NEED_RESCHED) or disabled. The down_interruptible 5019 * (TIF_NEED_RESCHED) or disabled. The down_interruptible
5019 * call may sleep, therefore we must re-enable interrupts 5020 * call may sleep, therefore we must re-enable interrupts
5020 * to avoid deadlocks. It is safe to do so because this function 5021 * to avoid deadlocks. It is safe to do so because this function
5021 * is called ONLY when returning to user level (PUStk=1), in which case 5022 * is called ONLY when returning to user level (pUStk=1), in which case
5022 * there is no risk of kernel stack overflow due to deep 5023 * there is no risk of kernel stack overflow due to deep
5023 * interrupt nesting. 5024 * interrupt nesting.
5024 */ 5025 */
@@ -5034,7 +5035,8 @@ pfm_handle_work(void)
5034 5035
5035 ctx = PFM_GET_CTX(current); 5036 ctx = PFM_GET_CTX(current);
5036 if (ctx == NULL) { 5037 if (ctx == NULL) {
5037 printk(KERN_ERR "perfmon: [%d] has no PFM context\n", task_pid_nr(current)); 5038 printk(KERN_ERR "perfmon: [%d] has no PFM context\n",
5039 task_pid_nr(current));
5038 return; 5040 return;
5039 } 5041 }
5040 5042
@@ -5058,11 +5060,12 @@ pfm_handle_work(void)
5058 /* 5060 /*
5059 * must be done before we check for simple-reset mode 5061 * must be done before we check for simple-reset mode
5060 */ 5062 */
5061 if (ctx->ctx_fl_going_zombie || ctx->ctx_state == PFM_CTX_ZOMBIE) goto do_zombie; 5063 if (ctx->ctx_fl_going_zombie || ctx->ctx_state == PFM_CTX_ZOMBIE)
5062 5064 goto do_zombie;
5063 5065
5064 //if (CTX_OVFL_NOBLOCK(ctx)) goto skip_blocking; 5066 //if (CTX_OVFL_NOBLOCK(ctx)) goto skip_blocking;
5065 if (reason == PFM_TRAP_REASON_RESET) goto skip_blocking; 5067 if (reason == PFM_TRAP_REASON_RESET)
5068 goto skip_blocking;
5066 5069
5067 /* 5070 /*
5068 * restore interrupt mask to what it was on entry. 5071 * restore interrupt mask to what it was on entry.
@@ -5110,7 +5113,8 @@ do_zombie:
5110 /* 5113 /*
5111 * in case of interruption of down() we don't restart anything 5114 * in case of interruption of down() we don't restart anything
5112 */ 5115 */
5113 if (ret < 0) goto nothing_to_do; 5116 if (ret < 0)
5117 goto nothing_to_do;
5114 5118
5115skip_blocking: 5119skip_blocking:
5116 pfm_resume_after_ovfl(ctx, ovfl_regs, regs); 5120 pfm_resume_after_ovfl(ctx, ovfl_regs, regs);
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 58dcfac5ea88..a3a34b4eb038 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -167,11 +167,18 @@ void tsk_clear_notify_resume(struct task_struct *tsk)
167 clear_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME); 167 clear_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME);
168} 168}
169 169
170/*
171 * do_notify_resume_user():
172 * Called from notify_resume_user at entry.S, with interrupts disabled.
173 */
170void 174void
171do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall) 175do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
172{ 176{
173 if (fsys_mode(current, &scr->pt)) { 177 if (fsys_mode(current, &scr->pt)) {
174 /* defer signal-handling etc. until we return to privilege-level 0. */ 178 /*
179 * defer signal-handling etc. until we return to
180 * privilege-level 0.
181 */
175 if (!ia64_psr(&scr->pt)->lp) 182 if (!ia64_psr(&scr->pt)->lp)
176 ia64_psr(&scr->pt)->lp = 1; 183 ia64_psr(&scr->pt)->lp = 1;
177 return; 184 return;
@@ -179,16 +186,26 @@ do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall
179 186
180#ifdef CONFIG_PERFMON 187#ifdef CONFIG_PERFMON
181 if (current->thread.pfm_needs_checking) 188 if (current->thread.pfm_needs_checking)
189 /*
190 * Note: pfm_handle_work() allow us to call it with interrupts
191 * disabled, and may enable interrupts within the function.
192 */
182 pfm_handle_work(); 193 pfm_handle_work();
183#endif 194#endif
184 195
185 /* deal with pending signal delivery */ 196 /* deal with pending signal delivery */
186 if (test_thread_flag(TIF_SIGPENDING)) 197 if (test_thread_flag(TIF_SIGPENDING)) {
198 local_irq_enable(); /* force interrupt enable */
187 ia64_do_signal(scr, in_syscall); 199 ia64_do_signal(scr, in_syscall);
200 }
188 201
189 /* copy user rbs to kernel rbs */ 202 /* copy user rbs to kernel rbs */
190 if (unlikely(test_thread_flag(TIF_RESTORE_RSE))) 203 if (unlikely(test_thread_flag(TIF_RESTORE_RSE))) {
204 local_irq_enable(); /* force interrupt enable */
191 ia64_sync_krbs(); 205 ia64_sync_krbs();
206 }
207
208 local_irq_disable(); /* force interrupt disable */
192} 209}
193 210
194static int pal_halt = 1; 211static int pal_halt = 1;
diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c
index a3022dc48ef8..7e0259709c04 100644
--- a/arch/ia64/kernel/sal.c
+++ b/arch/ia64/kernel/sal.c
@@ -229,6 +229,14 @@ static void __init sal_desc_ap_wakeup(void *p) { }
229 */ 229 */
230static int sal_cache_flush_drops_interrupts; 230static int sal_cache_flush_drops_interrupts;
231 231
232static int __init
233force_pal_cache_flush(char *str)
234{
235 sal_cache_flush_drops_interrupts = 1;
236 return 0;
237}
238early_param("force_pal_cache_flush", force_pal_cache_flush);
239
232void __init 240void __init
233check_sal_cache_flush (void) 241check_sal_cache_flush (void)
234{ 242{
@@ -237,6 +245,9 @@ check_sal_cache_flush (void)
237 u64 vector, cache_type = 3; 245 u64 vector, cache_type = 3;
238 struct ia64_sal_retval isrv; 246 struct ia64_sal_retval isrv;
239 247
248 if (sal_cache_flush_drops_interrupts)
249 return;
250
240 cpu = get_cpu(); 251 cpu = get_cpu();
241 local_irq_save(flags); 252 local_irq_save(flags);
242 253
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 5015ca1275ca..e9596cd0cdab 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -239,6 +239,25 @@ __initcall(register_memory);
239 239
240 240
241#ifdef CONFIG_KEXEC 241#ifdef CONFIG_KEXEC
242
243/*
244 * This function checks if the reserved crashkernel is allowed on the specific
245 * IA64 machine flavour. Machines without an IO TLB use swiotlb and require
246 * some memory below 4 GB (i.e. in 32 bit area), see the implementation of
247 * lib/swiotlb.c. The hpzx1 architecture has an IO TLB but cannot use that
248 * in kdump case. See the comment in sba_init() in sba_iommu.c.
249 *
250 * So, the only machvec that really supports loading the kdump kernel
251 * over 4 GB is "sn2".
252 */
253static int __init check_crashkernel_memory(unsigned long pbase, size_t size)
254{
255 if (ia64_platform_is("sn2") || ia64_platform_is("uv"))
256 return 1;
257 else
258 return pbase < (1UL << 32);
259}
260
242static void __init setup_crashkernel(unsigned long total, int *n) 261static void __init setup_crashkernel(unsigned long total, int *n)
243{ 262{
244 unsigned long long base = 0, size = 0; 263 unsigned long long base = 0, size = 0;
@@ -252,6 +271,16 @@ static void __init setup_crashkernel(unsigned long total, int *n)
252 base = kdump_find_rsvd_region(size, 271 base = kdump_find_rsvd_region(size,
253 rsvd_region, *n); 272 rsvd_region, *n);
254 } 273 }
274
275 if (!check_crashkernel_memory(base, size)) {
276 pr_warning("crashkernel: There would be kdump memory "
277 "at %ld GB but this is unusable because it "
278 "must\nbe below 4 GB. Change the memory "
279 "configuration of the machine.\n",
280 (unsigned long)(base >> 30));
281 return;
282 }
283
255 if (base != ~0UL) { 284 if (base != ~0UL) {
256 printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " 285 printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
257 "for crashkernel (System RAM: %ldMB)\n", 286 "for crashkernel (System RAM: %ldMB)\n",