unsigned long ip;
int count = 0;
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+
/*
* Note: p may not be a blocked task (it could be current or
* another process running on some other CPU. Rather than
*/
unw_init_from_blocked_task(&info, p);
do {
+ if (p->state == TASK_RUNNING)
+ return 0;
if (unw_unwind(&info) < 0)
return 0;
unw_get_ip(&info, &ip);
unw_unwind (struct unw_frame_info *info)
{
unsigned long prev_ip, prev_sp, prev_bsp;
- unsigned long ip, pr, num_regs;
+ unsigned long ip, pr, num_regs, rp_loc, pfs_loc;
STAT(unsigned long start, flags;)
int retval;
prev_sp = info->sp;
prev_bsp = info->bsp;
- /* restore the ip */
- if (!info->rp_loc) {
+ /* validate the return IP pointer */
+ rp_loc = (unsigned long) info->rp_loc;
+ if ((rp_loc < info->regstk.limit) || (rp_loc > info->regstk.top)) {
/* FIXME: should really be level 0 but it occurs too often. KAO */
UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n",
__FUNCTION__, info->ip);
STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
return -1;
}
+ /* restore the ip */
ip = info->ip = *info->rp_loc;
if (ip < GATE_ADDR) {
UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __FUNCTION__, ip);
return -1;
}
- /* restore the cfm: */
- if (!info->pfs_loc) {
+ /* validate the previous stack frame pointer */
+ pfs_loc = (unsigned long) info->pfs_loc;
+ if ((pfs_loc < info->regstk.limit) || (pfs_loc > info->regstk.top)) {
UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__);
STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
return -1;
}
+ /* restore the cfm: */
info->cfm_loc = info->pfs_loc;
/* restore the bsp: */
memset(info, 0, sizeof(*info));
rbslimit = (unsigned long) t + IA64_RBS_OFFSET;
+ stklimit = (unsigned long) t + IA64_STK_OFFSET;
+
rbstop = sw->ar_bspstore;
- if (rbstop - (unsigned long) t >= IA64_STK_OFFSET)
+ if (rbstop > stklimit || rbstop < rbslimit)
rbstop = rbslimit;
- stklimit = (unsigned long) t + IA64_STK_OFFSET;
if (stktop <= rbstop)
stktop = rbstop;
+ if (stktop > stklimit)
+ stktop = stklimit;
info->regstk.limit = rbslimit;
info->regstk.top = rbstop;
acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
&windows);
- controller->window = kmalloc_node(sizeof(*controller->window) * windows,
- GFP_KERNEL, controller->node);
- if (!controller->window)
- goto out2;
+ if (windows) {
+ controller->window =
+ kmalloc_node(sizeof(*controller->window) * windows,
+ GFP_KERNEL, controller->node);
+ if (!controller->window)
+ goto out2;
+ }
name = kmalloc(16, GFP_KERNEL);
if (!name)
}
extern int platform_intr_list[];
-static int __initdata shub_1_1_found;
+static int __cpuinitdata shub_1_1_found;
/*
* sn_check_for_wars
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
+ .pmc_type = PPC_PMC_IBM,
.cpu_setup = __setup_cpu_ppc970,
.cpu_restore = __restore_cpu_ppc970,
.oprofile_cpu_type = "ppc64/970MP",
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 8,
+ .pmc_type = PPC_PMC_IBM,
.cpu_setup = __setup_cpu_ppc970MP,
.cpu_restore = __restore_cpu_ppc970,
.oprofile_cpu_type = "ppc64/970MP",
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 6,
+ .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/power6",
.oprofile_type = PPC_OPROFILE_POWER4,
.oprofile_mmcra_sihv = POWER6_MMCRA_SIHV,
.icache_bsize = 128,
.dcache_bsize = 128,
.num_pmcs = 6,
+ .pmc_type = PPC_PMC_IBM,
.oprofile_cpu_type = "ppc64/power6",
.oprofile_type = PPC_OPROFILE_POWER4,
.oprofile_mmcra_sihv = POWER6_MMCRA_SIHV,
#include <asm/cputable.h>
#include <asm/pmc.h>
-#ifndef MMCR0_PMA0
-#define MMCR0_PMA0 0
+#ifndef MMCR0_PMAO
+#define MMCR0_PMAO 0
#endif
static void dummy_perf(struct pt_regs *regs)
mtpmr(PMRN_PMGC0, mfpmr(PMRN_PMGC0) & ~PMGC0_PMIE);
#elif defined(CONFIG_PPC64) || defined(CONFIG_6xx)
if (cur_cpu_spec->pmc_type == PPC_PMC_IBM)
- mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~(MMCR0_PMXE|MMCR0_PMA0));
+ mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~(MMCR0_PMXE|MMCR0_PMAO));
#else
mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_PMXE);
#endif
/* Can deadlock when called with interrupts disabled */
WARN_ON(irqs_disabled());
- /* remove 'self' from the map */
- if (cpu_isset(smp_processor_id(), map))
- cpu_clear(smp_processor_id(), map);
-
- /* sanity check the map, remove any non-online processors. */
- cpus_and(map, map, cpu_online_map);
-
if (unlikely(smp_ops == NULL))
return ret;
/* Must grab online cpu count with preempt disabled, otherwise
* it can change. */
num_cpus = num_online_cpus() - 1;
- if (!num_cpus || cpus_empty(map)) {
- ret = 0;
- goto out;
- }
+ if (!num_cpus)
+ goto done;
+
+ /* remove 'self' from the map */
+ if (cpu_isset(smp_processor_id(), map))
+ cpu_clear(smp_processor_id(), map);
+
+ /* sanity check the map, remove any non-online processors. */
+ cpus_and(map, map, cpu_online_map);
+ if (cpus_empty(map))
+ goto done;
call_data = &data;
smp_wmb();
}
}
+ done:
ret = 0;
out:
int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int nonatomic,
int wait)
{
- cpumask_t map=CPU_MASK_NONE;
+ cpumask_t map = CPU_MASK_NONE;
+ int ret = -EBUSY;
if (!cpu_online(cpu))
return -EINVAL;
- if (cpu == smp_processor_id())
- return -EBUSY;
-
cpu_set(cpu, map);
- return smp_call_function_map(func,info,nonatomic,wait,map);
+ if (cpu != get_cpu())
+ ret = smp_call_function_map(func,info,nonatomic,wait,map);
+ put_cpu();
+ return ret;
}
EXPORT_SYMBOL(smp_call_function_single);
/* Text and gots */
.text : {
_text = .;
- *(.text.*)
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT
#ifdef CONFIG_HIGHMEM
map_page(PKMAP_BASE, 0, 0); /* XXX gross */
- pkmap_page_table = pte_offset_kernel(pmd_offset(pgd_offset_k
- (PKMAP_BASE), PKMAP_BASE), PKMAP_BASE);
+ pkmap_page_table = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k
+ (PKMAP_BASE), PKMAP_BASE), PKMAP_BASE), PKMAP_BASE);
map_page(KMAP_FIX_BEGIN, 0, 0); /* XXX gross */
- kmap_pte = pte_offset_kernel(pmd_offset(pgd_offset_k
- (KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN);
+ kmap_pte = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k
+ (KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN),
+ KMAP_FIX_BEGIN);
kmap_prot = PAGE_KERNEL;
#endif /* CONFIG_HIGHMEM */
#define NR_syscalls 286 /* length of syscall table */
+/*
+ * The following defines stop scripts/checksyscalls.sh from complaining about
+ * unimplemented system calls. Glibc provides for each of these by using
+ * more modern equivalent system calls.
+ */
+#define __IGNORE_fork /* clone() */
+#define __IGNORE_time /* gettimeofday() */
+#define __IGNORE_alarm /* setitimer(ITIMER_REAL, ... */
+#define __IGNORE_pause /* rt_sigprocmask(), rt_sigsuspend() */
+#define __IGNORE_utime /* utimes() */
+#define __IGNORE_getpgrp /* getpgid() */
+#define __IGNORE_vfork /* clone() */
+
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND