diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-22 19:46:29 -0400 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-22 19:46:29 -0400 | 
| commit | 5fd52203e1856ad925b1a6adae9a22e533da94e2 (patch) | |
| tree | 9c1943df7bb47a5170a855a301beb69c6ebd6db3 /arch/ia64/kernel/unwind.c | |
| parent | 5453e7723b95958f4591b2e0063573d8d53e7699 (diff) | |
| parent | a66aa704d6f332b001dfb0e787c92b2c61c75081 (diff) | |
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6:
  [IA64] fix kmalloc(0) in arch/ia64/pci/pci.c
  [IA64] Only unwind non-running tasks.
  [IA64] Improve unwind checking.
  [IA64] Yet another section mismatch warning
  [IA64] Fix bogus messages about system calls not implemented.
Diffstat (limited to 'arch/ia64/kernel/unwind.c')
| -rw-r--r-- | arch/ia64/kernel/unwind.c | 21 | 
1 files changed, 14 insertions, 7 deletions
| diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c index 7d3dd6cdafa4..b0b08b5f3eca 100644 --- a/arch/ia64/kernel/unwind.c +++ b/arch/ia64/kernel/unwind.c | |||
| @@ -1860,7 +1860,7 @@ int | |||
| 1860 | unw_unwind (struct unw_frame_info *info) | 1860 | unw_unwind (struct unw_frame_info *info) | 
| 1861 | { | 1861 | { | 
| 1862 | unsigned long prev_ip, prev_sp, prev_bsp; | 1862 | unsigned long prev_ip, prev_sp, prev_bsp; | 
| 1863 | unsigned long ip, pr, num_regs; | 1863 | unsigned long ip, pr, num_regs, rp_loc, pfs_loc; | 
| 1864 | STAT(unsigned long start, flags;) | 1864 | STAT(unsigned long start, flags;) | 
| 1865 | int retval; | 1865 | int retval; | 
| 1866 | 1866 | ||
| @@ -1870,14 +1870,16 @@ unw_unwind (struct unw_frame_info *info) | |||
| 1870 | prev_sp = info->sp; | 1870 | prev_sp = info->sp; | 
| 1871 | prev_bsp = info->bsp; | 1871 | prev_bsp = info->bsp; | 
| 1872 | 1872 | ||
| 1873 | /* restore the ip */ | 1873 | /* validate the return IP pointer */ | 
| 1874 | if (!info->rp_loc) { | 1874 | rp_loc = (unsigned long) info->rp_loc; | 
| 1875 | if ((rp_loc < info->regstk.limit) || (rp_loc > info->regstk.top)) { | ||
| 1875 | /* FIXME: should really be level 0 but it occurs too often. KAO */ | 1876 | /* FIXME: should really be level 0 but it occurs too often. KAO */ | 
| 1876 | UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n", | 1877 | UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n", | 
| 1877 | __FUNCTION__, info->ip); | 1878 | __FUNCTION__, info->ip); | 
| 1878 | STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); | 1879 | STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); | 
| 1879 | return -1; | 1880 | return -1; | 
| 1880 | } | 1881 | } | 
| 1882 | /* restore the ip */ | ||
| 1881 | ip = info->ip = *info->rp_loc; | 1883 | ip = info->ip = *info->rp_loc; | 
| 1882 | if (ip < GATE_ADDR) { | 1884 | if (ip < GATE_ADDR) { | 
| 1883 | UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __FUNCTION__, ip); | 1885 | 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) | |||
| 1885 | return -1; | 1887 | return -1; | 
| 1886 | } | 1888 | } | 
| 1887 | 1889 | ||
| 1888 | /* restore the cfm: */ | 1890 | /* validate the previous stack frame pointer */ | 
| 1889 | if (!info->pfs_loc) { | 1891 | pfs_loc = (unsigned long) info->pfs_loc; | 
| 1892 | if ((pfs_loc < info->regstk.limit) || (pfs_loc > info->regstk.top)) { | ||
| 1890 | UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__); | 1893 | UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__); | 
| 1891 | STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); | 1894 | STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); | 
| 1892 | return -1; | 1895 | return -1; | 
| 1893 | } | 1896 | } | 
| 1897 | /* restore the cfm: */ | ||
| 1894 | info->cfm_loc = info->pfs_loc; | 1898 | info->cfm_loc = info->pfs_loc; | 
| 1895 | 1899 | ||
| 1896 | /* restore the bsp: */ | 1900 | /* restore the bsp: */ | 
| @@ -1992,13 +1996,16 @@ init_frame_info (struct unw_frame_info *info, struct task_struct *t, | |||
| 1992 | memset(info, 0, sizeof(*info)); | 1996 | memset(info, 0, sizeof(*info)); | 
| 1993 | 1997 | ||
| 1994 | rbslimit = (unsigned long) t + IA64_RBS_OFFSET; | 1998 | rbslimit = (unsigned long) t + IA64_RBS_OFFSET; | 
| 1999 | stklimit = (unsigned long) t + IA64_STK_OFFSET; | ||
| 2000 | |||
| 1995 | rbstop = sw->ar_bspstore; | 2001 | rbstop = sw->ar_bspstore; | 
| 1996 | if (rbstop - (unsigned long) t >= IA64_STK_OFFSET) | 2002 | if (rbstop > stklimit || rbstop < rbslimit) | 
| 1997 | rbstop = rbslimit; | 2003 | rbstop = rbslimit; | 
| 1998 | 2004 | ||
| 1999 | stklimit = (unsigned long) t + IA64_STK_OFFSET; | ||
| 2000 | if (stktop <= rbstop) | 2005 | if (stktop <= rbstop) | 
| 2001 | stktop = rbstop; | 2006 | stktop = rbstop; | 
| 2007 | if (stktop > stklimit) | ||
| 2008 | stktop = stklimit; | ||
| 2002 | 2009 | ||
| 2003 | info->regstk.limit = rbslimit; | 2010 | info->regstk.limit = rbslimit; | 
| 2004 | info->regstk.top = rbstop; | 2011 | info->regstk.top = rbstop; | 
