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. |
