summaryrefslogtreecommitdiff
path: root/arch/sparc/kernel/visemul.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-11-28 07:22:38 -0200
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-11-28 07:22:38 -0200
commitd033a308d81ec83908760a15a841c2bd0d5e0ea3 (patch)
tree647abd67987fe4d7fee80105fc823edf3f53b4f6 /arch/sparc/kernel/visemul.c
parentc6c22955f80f2db9614b01fe5a3d1cfcd8b3d848 (diff)
parente23739b4ade80a3a7f87198f008f6c44a7cbc9fd (diff)
Merge remote-tracking branch 'linus/master' into staging/for_v3.8
* linus/master: (1428 commits) futex: avoid wake_futex() for a PI futex_q watchdog: using u64 in get_sample_period() writeback: put unused inodes to LRU after writeback completion mm: vmscan: check for fatal signals iff the process was throttled Revert "mm: remove __GFP_NO_KSWAPD" proc: check vma->vm_file before dereferencing UAPI: strip the _UAPI prefix from header guards during header installation include/linux/bug.h: fix sparse warning related to BUILD_BUG_ON_INVALID Linux 3.7-rc7 powerpc/eeh: Do not invalidate PE properly ALSA: hda - Fix build without CONFIG_PM of/address: sparc: Declare of_iomap as an extern function for sparc again PM / QoS: fix wrong error-checking condition bnx2x: remove redundant warning log vxlan: fix command usage in its doc 8139cp: revert "set ring address before enabling receiver" MPI: Fix compilation on MIPS with GCC 4.4 and newer MIPS: Fix crash that occurs when function tracing is enabled MIPS: Merge overlapping bootmem ranges jbd: Fix lock ordering bug in journal_unmap_buffer() ...
Diffstat (limited to 'arch/sparc/kernel/visemul.c')
-rw-r--r--arch/sparc/kernel/visemul.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c
index 08e074b7eb6a..c096c624ac4d 100644
--- a/arch/sparc/kernel/visemul.c
+++ b/arch/sparc/kernel/visemul.c
@@ -149,21 +149,24 @@ static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2,
static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
{
- unsigned long value;
+ unsigned long value, fp;
if (reg < 16)
return (!reg ? 0 : regs->u_regs[reg]);
+
+ fp = regs->u_regs[UREG_FP];
+
if (regs->tstate & TSTATE_PRIV) {
struct reg_window *win;
- win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+ win = (struct reg_window *)(fp + STACK_BIAS);
value = win->locals[reg - 16];
- } else if (test_thread_flag(TIF_32BIT)) {
+ } else if (!test_thread_64bit_stack(fp)) {
struct reg_window32 __user *win32;
- win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
+ win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
get_user(value, &win32->locals[reg - 16]);
} else {
struct reg_window __user *win;
- win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+ win = (struct reg_window __user *)(fp + STACK_BIAS);
get_user(value, &win->locals[reg - 16]);
}
return value;
@@ -172,16 +175,18 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs)
static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg,
struct pt_regs *regs)
{
+ unsigned long fp = regs->u_regs[UREG_FP];
+
BUG_ON(reg < 16);
BUG_ON(regs->tstate & TSTATE_PRIV);
- if (test_thread_flag(TIF_32BIT)) {
+ if (!test_thread_64bit_stack(fp)) {
struct reg_window32 __user *win32;
- win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP]));
+ win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp));
return (unsigned long __user *)&win32->locals[reg - 16];
} else {
struct reg_window __user *win;
- win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS);
+ win = (struct reg_window __user *)(fp + STACK_BIAS);
return &win->locals[reg - 16];
}
}
@@ -204,7 +209,7 @@ static void store_reg(struct pt_regs *regs, unsigned long val, unsigned long rd)
} else {
unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs);
- if (test_thread_flag(TIF_32BIT))
+ if (!test_thread_64bit_stack(regs->u_regs[UREG_FP]))
__put_user((u32)val, (u32 __user *)rd_user);
else
__put_user(val, rd_user);