diff options
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r-- | arch/ia64/kernel/acpi.c | 23 | ||||
-rw-r--r-- | arch/ia64/kernel/entry.S | 2 | ||||
-rw-r--r-- | arch/ia64/kernel/fsys.S | 4 | ||||
-rw-r--r-- | arch/ia64/kernel/mca_drv.c | 4 | ||||
-rw-r--r-- | arch/ia64/kernel/mca_drv_asm.S | 18 | ||||
-rw-r--r-- | arch/ia64/kernel/perfmon.c | 43 | ||||
-rw-r--r-- | arch/ia64/kernel/process.c | 55 | ||||
-rw-r--r-- | arch/ia64/kernel/signal.c | 3 |
8 files changed, 97 insertions, 55 deletions
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index a8e99c56a768..72dfd9e7de0f 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -779,7 +779,7 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) | |||
779 | union acpi_object *obj; | 779 | union acpi_object *obj; |
780 | struct acpi_table_iosapic *iosapic; | 780 | struct acpi_table_iosapic *iosapic; |
781 | unsigned int gsi_base; | 781 | unsigned int gsi_base; |
782 | int node; | 782 | int pxm, node; |
783 | 783 | ||
784 | /* Only care about objects w/ a method that returns the MADT */ | 784 | /* Only care about objects w/ a method that returns the MADT */ |
785 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) | 785 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) |
@@ -805,29 +805,16 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) | |||
805 | gsi_base = iosapic->global_irq_base; | 805 | gsi_base = iosapic->global_irq_base; |
806 | 806 | ||
807 | acpi_os_free(buffer.pointer); | 807 | acpi_os_free(buffer.pointer); |
808 | buffer.length = ACPI_ALLOCATE_BUFFER; | ||
809 | buffer.pointer = NULL; | ||
810 | 808 | ||
811 | /* | 809 | /* |
812 | * OK, it's an IOSAPIC MADT entry, look for a _PXM method to tell | 810 | * OK, it's an IOSAPIC MADT entry, look for a _PXM value to tell |
813 | * us which node to associate this with. | 811 | * us which node to associate this with. |
814 | */ | 812 | */ |
815 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PXM", NULL, &buffer))) | 813 | pxm = acpi_get_pxm(handle); |
816 | return AE_OK; | 814 | if (pxm < 0) |
817 | |||
818 | if (!buffer.length || !buffer.pointer) | ||
819 | return AE_OK; | ||
820 | |||
821 | obj = buffer.pointer; | ||
822 | |||
823 | if (obj->type != ACPI_TYPE_INTEGER || | ||
824 | obj->integer.value >= MAX_PXM_DOMAINS) { | ||
825 | acpi_os_free(buffer.pointer); | ||
826 | return AE_OK; | 815 | return AE_OK; |
827 | } | ||
828 | 816 | ||
829 | node = pxm_to_nid_map[obj->integer.value]; | 817 | node = pxm_to_nid_map[pxm]; |
830 | acpi_os_free(buffer.pointer); | ||
831 | 818 | ||
832 | if (node >= MAX_NUMNODES || !node_online(node) || | 819 | if (node >= MAX_NUMNODES || !node_online(node) || |
833 | cpus_empty(node_to_cpumask(node))) | 820 | cpus_empty(node_to_cpumask(node))) |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index d3f093820bc7..81c45d447394 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -782,7 +782,7 @@ GLOBAL_ENTRY(ia64_ret_from_ia32_execve) | |||
782 | st8.spill [r2]=r8 // store return value in slot for r8 and set unat bit | 782 | st8.spill [r2]=r8 // store return value in slot for r8 and set unat bit |
783 | .mem.offset 8,0 | 783 | .mem.offset 8,0 |
784 | st8.spill [r3]=r0 // clear error indication in slot for r10 and set unat bit | 784 | st8.spill [r3]=r0 // clear error indication in slot for r10 and set unat bit |
785 | END(ia64_ret_from_ia32_execve_syscall) | 785 | END(ia64_ret_from_ia32_execve) |
786 | // fall through | 786 | // fall through |
787 | #endif /* CONFIG_IA32_SUPPORT */ | 787 | #endif /* CONFIG_IA32_SUPPORT */ |
788 | GLOBAL_ENTRY(ia64_leave_kernel) | 788 | GLOBAL_ENTRY(ia64_leave_kernel) |
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 0d8650f7fce7..4f3cdef75797 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S | |||
@@ -611,8 +611,10 @@ GLOBAL_ENTRY(fsys_bubble_down) | |||
611 | movl r2=ia64_ret_from_syscall | 611 | movl r2=ia64_ret_from_syscall |
612 | ;; | 612 | ;; |
613 | mov rp=r2 // set the real return addr | 613 | mov rp=r2 // set the real return addr |
614 | tbit.z p8,p0=r3,TIF_SYSCALL_TRACE | 614 | and r3=_TIF_SYSCALL_TRACEAUDIT,r3 |
615 | ;; | 615 | ;; |
616 | cmp.eq p8,p0=r3,r0 | ||
617 | |||
616 | (p10) br.cond.spnt.many ia64_ret_from_syscall // p10==true means out registers are more than 8 | 618 | (p10) br.cond.spnt.many ia64_ret_from_syscall // p10==true means out registers are more than 8 |
617 | (p8) br.call.sptk.many b6=b6 // ignore this return addr | 619 | (p8) br.call.sptk.many b6=b6 // ignore this return addr |
618 | br.cond.sptk ia64_trace_syscall | 620 | br.cond.sptk ia64_trace_syscall |
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index ab478172c349..abc0113a821d 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c | |||
@@ -132,8 +132,7 @@ mca_handler_bh(unsigned long paddr) | |||
132 | spin_unlock(&mca_bh_lock); | 132 | spin_unlock(&mca_bh_lock); |
133 | 133 | ||
134 | /* This process is about to be killed itself */ | 134 | /* This process is about to be killed itself */ |
135 | force_sig(SIGKILL, current); | 135 | do_exit(SIGKILL); |
136 | schedule(); | ||
137 | } | 136 | } |
138 | 137 | ||
139 | /** | 138 | /** |
@@ -439,6 +438,7 @@ recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_chec | |||
439 | psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr; | 438 | psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr; |
440 | psr2->cpl = 0; | 439 | psr2->cpl = 0; |
441 | psr2->ri = 0; | 440 | psr2->ri = 0; |
441 | psr2->i = 0; | ||
442 | 442 | ||
443 | return 1; | 443 | return 1; |
444 | } | 444 | } |
diff --git a/arch/ia64/kernel/mca_drv_asm.S b/arch/ia64/kernel/mca_drv_asm.S index bcfa05acc561..2d7e0217638d 100644 --- a/arch/ia64/kernel/mca_drv_asm.S +++ b/arch/ia64/kernel/mca_drv_asm.S | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <asm/asmmacro.h> | 11 | #include <asm/asmmacro.h> |
12 | #include <asm/processor.h> | 12 | #include <asm/processor.h> |
13 | #include <asm/ptrace.h> | ||
13 | 14 | ||
14 | GLOBAL_ENTRY(mca_handler_bhhook) | 15 | GLOBAL_ENTRY(mca_handler_bhhook) |
15 | invala // clear RSE ? | 16 | invala // clear RSE ? |
@@ -20,12 +21,21 @@ GLOBAL_ENTRY(mca_handler_bhhook) | |||
20 | ;; | 21 | ;; |
21 | alloc r16=ar.pfs,0,2,1,0 // make a new frame | 22 | alloc r16=ar.pfs,0,2,1,0 // make a new frame |
22 | ;; | 23 | ;; |
24 | mov ar.rsc=0 | ||
25 | ;; | ||
23 | mov r13=IA64_KR(CURRENT) // current task pointer | 26 | mov r13=IA64_KR(CURRENT) // current task pointer |
24 | ;; | 27 | ;; |
25 | adds r12=IA64_TASK_THREAD_KSP_OFFSET,r13 | 28 | mov r2=r13 |
29 | ;; | ||
30 | addl r22=IA64_RBS_OFFSET,r2 | ||
31 | ;; | ||
32 | mov ar.bspstore=r22 | ||
26 | ;; | 33 | ;; |
27 | ld8 r12=[r12] // stack pointer | 34 | addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 |
28 | ;; | 35 | ;; |
36 | adds r2=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 | ||
37 | ;; | ||
38 | st1 [r2]=r0 // clear current->thread.on_ustack flag | ||
29 | mov loc0=r16 | 39 | mov loc0=r16 |
30 | movl loc1=mca_handler_bh // recovery C function | 40 | movl loc1=mca_handler_bh // recovery C function |
31 | ;; | 41 | ;; |
@@ -34,7 +44,9 @@ GLOBAL_ENTRY(mca_handler_bhhook) | |||
34 | ;; | 44 | ;; |
35 | mov loc1=rp | 45 | mov loc1=rp |
36 | ;; | 46 | ;; |
37 | br.call.sptk.many rp=b6 // not return ... | 47 | ssm psr.i |
48 | ;; | ||
49 | br.call.sptk.many rp=b6 // does not return ... | ||
38 | ;; | 50 | ;; |
39 | mov ar.pfs=loc0 | 51 | mov ar.pfs=loc0 |
40 | mov rp=loc1 | 52 | mov rp=loc1 |
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 376fcbc3f8da..71c101601e3e 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -1265,6 +1265,8 @@ out: | |||
1265 | } | 1265 | } |
1266 | EXPORT_SYMBOL(pfm_unregister_buffer_fmt); | 1266 | EXPORT_SYMBOL(pfm_unregister_buffer_fmt); |
1267 | 1267 | ||
1268 | extern void update_pal_halt_status(int); | ||
1269 | |||
1268 | static int | 1270 | static int |
1269 | pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) | 1271 | pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) |
1270 | { | 1272 | { |
@@ -1311,6 +1313,11 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) | |||
1311 | is_syswide, | 1313 | is_syswide, |
1312 | cpu)); | 1314 | cpu)); |
1313 | 1315 | ||
1316 | /* | ||
1317 | * disable default_idle() to go to PAL_HALT | ||
1318 | */ | ||
1319 | update_pal_halt_status(0); | ||
1320 | |||
1314 | UNLOCK_PFS(flags); | 1321 | UNLOCK_PFS(flags); |
1315 | 1322 | ||
1316 | return 0; | 1323 | return 0; |
@@ -1366,6 +1373,12 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu) | |||
1366 | is_syswide, | 1373 | is_syswide, |
1367 | cpu)); | 1374 | cpu)); |
1368 | 1375 | ||
1376 | /* | ||
1377 | * if possible, enable default_idle() to go into PAL_HALT | ||
1378 | */ | ||
1379 | if (pfm_sessions.pfs_task_sessions == 0 && pfm_sessions.pfs_sys_sessions == 0) | ||
1380 | update_pal_halt_status(1); | ||
1381 | |||
1369 | UNLOCK_PFS(flags); | 1382 | UNLOCK_PFS(flags); |
1370 | 1383 | ||
1371 | return 0; | 1384 | return 0; |
@@ -4202,7 +4215,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) | |||
4202 | DPRINT(("cannot load to [%d], invalid ctx_state=%d\n", | 4215 | DPRINT(("cannot load to [%d], invalid ctx_state=%d\n", |
4203 | req->load_pid, | 4216 | req->load_pid, |
4204 | ctx->ctx_state)); | 4217 | ctx->ctx_state)); |
4205 | return -EINVAL; | 4218 | return -EBUSY; |
4206 | } | 4219 | } |
4207 | 4220 | ||
4208 | DPRINT(("load_pid [%d] using_dbreg=%d\n", req->load_pid, ctx->ctx_fl_using_dbreg)); | 4221 | DPRINT(("load_pid [%d] using_dbreg=%d\n", req->load_pid, ctx->ctx_fl_using_dbreg)); |
@@ -4704,16 +4717,26 @@ recheck: | |||
4704 | if (task == current || ctx->ctx_fl_system) return 0; | 4717 | if (task == current || ctx->ctx_fl_system) return 0; |
4705 | 4718 | ||
4706 | /* | 4719 | /* |
4707 | * if context is UNLOADED we are safe to go | 4720 | * we are monitoring another thread |
4708 | */ | ||
4709 | if (state == PFM_CTX_UNLOADED) return 0; | ||
4710 | |||
4711 | /* | ||
4712 | * no command can operate on a zombie context | ||
4713 | */ | 4721 | */ |
4714 | if (state == PFM_CTX_ZOMBIE) { | 4722 | switch(state) { |
4715 | DPRINT(("cmd %d state zombie cannot operate on context\n", cmd)); | 4723 | case PFM_CTX_UNLOADED: |
4716 | return -EINVAL; | 4724 | /* |
4725 | * if context is UNLOADED we are safe to go | ||
4726 | */ | ||
4727 | return 0; | ||
4728 | case PFM_CTX_ZOMBIE: | ||
4729 | /* | ||
4730 | * no command can operate on a zombie context | ||
4731 | */ | ||
4732 | DPRINT(("cmd %d state zombie cannot operate on context\n", cmd)); | ||
4733 | return -EINVAL; | ||
4734 | case PFM_CTX_MASKED: | ||
4735 | /* | ||
4736 | * PMU state has been saved to software even though | ||
4737 | * the thread may still be running. | ||
4738 | */ | ||
4739 | if (cmd != PFM_UNLOAD_CONTEXT) return 0; | ||
4717 | } | 4740 | } |
4718 | 4741 | ||
4719 | /* | 4742 | /* |
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 7c43aea5f7f7..ebb71f3d6d19 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
@@ -50,7 +50,7 @@ | |||
50 | #include "sigframe.h" | 50 | #include "sigframe.h" |
51 | 51 | ||
52 | void (*ia64_mark_idle)(int); | 52 | void (*ia64_mark_idle)(int); |
53 | static cpumask_t cpu_idle_map; | 53 | static DEFINE_PER_CPU(unsigned int, cpu_idle_state); |
54 | 54 | ||
55 | unsigned long boot_option_idle_override = 0; | 55 | unsigned long boot_option_idle_override = 0; |
56 | EXPORT_SYMBOL(boot_option_idle_override); | 56 | EXPORT_SYMBOL(boot_option_idle_override); |
@@ -173,7 +173,9 @@ do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall | |||
173 | ia64_do_signal(oldset, scr, in_syscall); | 173 | ia64_do_signal(oldset, scr, in_syscall); |
174 | } | 174 | } |
175 | 175 | ||
176 | static int pal_halt = 1; | 176 | static int pal_halt = 1; |
177 | static int can_do_pal_halt = 1; | ||
178 | |||
177 | static int __init nohalt_setup(char * str) | 179 | static int __init nohalt_setup(char * str) |
178 | { | 180 | { |
179 | pal_halt = 0; | 181 | pal_halt = 0; |
@@ -181,16 +183,20 @@ static int __init nohalt_setup(char * str) | |||
181 | } | 183 | } |
182 | __setup("nohalt", nohalt_setup); | 184 | __setup("nohalt", nohalt_setup); |
183 | 185 | ||
186 | void | ||
187 | update_pal_halt_status(int status) | ||
188 | { | ||
189 | can_do_pal_halt = pal_halt && status; | ||
190 | } | ||
191 | |||
184 | /* | 192 | /* |
185 | * We use this if we don't have any better idle routine.. | 193 | * We use this if we don't have any better idle routine.. |
186 | */ | 194 | */ |
187 | void | 195 | void |
188 | default_idle (void) | 196 | default_idle (void) |
189 | { | 197 | { |
190 | unsigned long pmu_active = ia64_getreg(_IA64_REG_PSR) & (IA64_PSR_PP | IA64_PSR_UP); | ||
191 | |||
192 | while (!need_resched()) | 198 | while (!need_resched()) |
193 | if (pal_halt && !pmu_active) | 199 | if (can_do_pal_halt) |
194 | safe_halt(); | 200 | safe_halt(); |
195 | else | 201 | else |
196 | cpu_relax(); | 202 | cpu_relax(); |
@@ -223,20 +229,31 @@ static inline void play_dead(void) | |||
223 | } | 229 | } |
224 | #endif /* CONFIG_HOTPLUG_CPU */ | 230 | #endif /* CONFIG_HOTPLUG_CPU */ |
225 | 231 | ||
226 | |||
227 | void cpu_idle_wait(void) | 232 | void cpu_idle_wait(void) |
228 | { | 233 | { |
229 | int cpu; | 234 | unsigned int cpu, this_cpu = get_cpu(); |
230 | cpumask_t map; | 235 | cpumask_t map; |
231 | 236 | ||
232 | for_each_online_cpu(cpu) | 237 | set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); |
233 | cpu_set(cpu, cpu_idle_map); | 238 | put_cpu(); |
234 | 239 | ||
235 | wmb(); | 240 | cpus_clear(map); |
236 | do { | 241 | for_each_online_cpu(cpu) { |
237 | ssleep(1); | 242 | per_cpu(cpu_idle_state, cpu) = 1; |
238 | cpus_and(map, cpu_idle_map, cpu_online_map); | 243 | cpu_set(cpu, map); |
239 | } while (!cpus_empty(map)); | 244 | } |
245 | |||
246 | __get_cpu_var(cpu_idle_state) = 0; | ||
247 | |||
248 | wmb(); | ||
249 | do { | ||
250 | ssleep(1); | ||
251 | for_each_online_cpu(cpu) { | ||
252 | if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu)) | ||
253 | cpu_clear(cpu, map); | ||
254 | } | ||
255 | cpus_and(map, map, cpu_online_map); | ||
256 | } while (!cpus_empty(map)); | ||
240 | } | 257 | } |
241 | EXPORT_SYMBOL_GPL(cpu_idle_wait); | 258 | EXPORT_SYMBOL_GPL(cpu_idle_wait); |
242 | 259 | ||
@@ -244,7 +261,6 @@ void __attribute__((noreturn)) | |||
244 | cpu_idle (void) | 261 | cpu_idle (void) |
245 | { | 262 | { |
246 | void (*mark_idle)(int) = ia64_mark_idle; | 263 | void (*mark_idle)(int) = ia64_mark_idle; |
247 | int cpu = smp_processor_id(); | ||
248 | 264 | ||
249 | /* endless idle loop with no priority at all */ | 265 | /* endless idle loop with no priority at all */ |
250 | while (1) { | 266 | while (1) { |
@@ -255,12 +271,13 @@ cpu_idle (void) | |||
255 | while (!need_resched()) { | 271 | while (!need_resched()) { |
256 | void (*idle)(void); | 272 | void (*idle)(void); |
257 | 273 | ||
274 | if (__get_cpu_var(cpu_idle_state)) | ||
275 | __get_cpu_var(cpu_idle_state) = 0; | ||
276 | |||
277 | rmb(); | ||
258 | if (mark_idle) | 278 | if (mark_idle) |
259 | (*mark_idle)(1); | 279 | (*mark_idle)(1); |
260 | 280 | ||
261 | if (cpu_isset(cpu, cpu_idle_map)) | ||
262 | cpu_clear(cpu, cpu_idle_map); | ||
263 | rmb(); | ||
264 | idle = pm_idle; | 281 | idle = pm_idle; |
265 | if (!idle) | 282 | if (!idle) |
266 | idle = default_idle; | 283 | idle = default_idle; |
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 6891d86937d9..499b7e5317cf 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c | |||
@@ -224,7 +224,8 @@ ia64_rt_sigreturn (struct sigscratch *scr) | |||
224 | * could be corrupted. | 224 | * could be corrupted. |
225 | */ | 225 | */ |
226 | retval = (long) &ia64_leave_kernel; | 226 | retval = (long) &ia64_leave_kernel; |
227 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | 227 | if (test_thread_flag(TIF_SYSCALL_TRACE) |
228 | || test_thread_flag(TIF_SYSCALL_AUDIT)) | ||
228 | /* | 229 | /* |
229 | * strace expects to be notified after sigreturn returns even though the | 230 | * strace expects to be notified after sigreturn returns even though the |
230 | * context to which we return may not be in the middle of a syscall. | 231 | * context to which we return may not be in the middle of a syscall. |