aboutsummaryrefslogtreecommitdiff
path: root/arch/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/kernel/process.c5
-rw-r--r--arch/ia64/kernel/unwind.c21
-rw-r--r--arch/ia64/pci/pci.c11
-rw-r--r--arch/ia64/sn/kernel/setup.c2
4 files changed, 27 insertions, 12 deletions
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index d1c3ed9943e..af73b8dfde2 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -763,6 +763,9 @@ get_wchan (struct task_struct *p)
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
@@ -773,6 +776,8 @@ get_wchan (struct task_struct *p)
*/
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);
diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c
index 7d3dd6cdafa..b0b08b5f3ec 100644
--- a/arch/ia64/kernel/unwind.c
+++ b/arch/ia64/kernel/unwind.c
@@ -1860,7 +1860,7 @@ int
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;
@@ -1870,14 +1870,16 @@ unw_unwind (struct unw_frame_info *info)
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);
@@ -1885,12 +1887,14 @@ unw_unwind (struct unw_frame_info *info)
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: */
@@ -1992,13 +1996,16 @@ init_frame_info (struct unw_frame_info *info, struct task_struct *t,
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;
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 3549f3b4259..73696b4a2ee 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -354,10 +354,13 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
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)
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index a574fcd163d..684b1c984a4 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -194,7 +194,7 @@ void __init early_sn_setup(void)
}
extern int platform_intr_list[];
-static int __initdata shub_1_1_found;
+static int __cpuinitdata shub_1_1_found;
/*
* sn_check_for_wars