Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1597867
| From | Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH 4.4 09/91] MIPS: Calculate microMIPS ra properly when unwinding the stack |
| Date | 2017-03-10 15:40 +0100 |
| Message-ID | <tjtS3-5k0-43@gated-at.bofh.it> (permalink) |
| References | <tjoSl-1MV-3@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Burton <paul.burton@imgtec.com>
commit bb9bc4689b9c635714fbcd5d335bad9934a7ebfc upstream.
get_frame_info() calculates the offset of the return address within a
stack frame simply by dividing a the bottom 16 bits of the instruction,
treated as a signed integer, by the size of a long. Whilst this works
for MIPS32 & MIPS64 ISAs where the sw or sd instructions are used, it's
incorrect for microMIPS where encodings differ. The result is that we
typically completely fail to unwind the stack on microMIPS.
Fix this by adjusting is_ra_save_ins() to calculate the return address
offset, and take into account the various different encodings there in
the same place as we consider whether an instruction is storing the
ra/$31 register.
With this we are now able to unwind the stack for kernels targetting the
microMIPS ISA, for example we can produce:
Call Trace:
[<80109e1f>] show_stack+0x63/0x7c
[<8011ea17>] __warn+0x9b/0xac
[<8011ea45>] warn_slowpath_fmt+0x1d/0x20
[<8013fe53>] register_console+0x43/0x314
[<8067c58d>] of_setup_earlycon+0x1dd/0x1ec
[<8067f63f>] early_init_dt_scan_chosen_stdout+0xe7/0xf8
[<8066c115>] do_early_param+0x75/0xac
[<801302f9>] parse_args+0x1dd/0x308
[<8066c459>] parse_early_options+0x25/0x28
[<8066c48b>] parse_early_param+0x2f/0x38
[<8066e8cf>] setup_arch+0x113/0x488
[<8066c4f3>] start_kernel+0x57/0x328
---[ end trace 0000000000000000 ]---
Whereas previously we only produced:
Call Trace:
[<80109e1f>] show_stack+0x63/0x7c
---[ end trace 0000000000000000 ]---
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Fixes: 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.")
Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/14532/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/mips/kernel/process.c | 85 +++++++++++++++++++++++++++++++++------------
1 file changed, 64 insertions(+), 21 deletions(-)
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -191,7 +191,7 @@ struct mips_frame_info {
#define J_TARGET(pc,target) \
(((unsigned long)(pc) & 0xf0000000) | ((target) << 2))
-static inline int is_ra_save_ins(union mips_instruction *ip)
+static inline int is_ra_save_ins(union mips_instruction *ip, int *poff)
{
#ifdef CONFIG_CPU_MICROMIPS
/*
@@ -204,25 +204,70 @@ static inline int is_ra_save_ins(union m
* microMIPS is way more fun...
*/
if (mm_insn_16bit(ip->halfword[1])) {
- return (ip->mm16_r5_format.opcode == mm_swsp16_op &&
- ip->mm16_r5_format.rt == 31) ||
- (ip->mm16_m_format.opcode == mm_pool16c_op &&
- ip->mm16_m_format.func == mm_swm16_op);
- }
- else {
- return (ip->mm_m_format.opcode == mm_pool32b_op &&
- ip->mm_m_format.rd > 9 &&
- ip->mm_m_format.base == 29 &&
- ip->mm_m_format.func == mm_swm32_func) ||
- (ip->i_format.opcode == mm_sw32_op &&
- ip->i_format.rs == 29 &&
- ip->i_format.rt == 31);
+ switch (ip->mm16_r5_format.opcode) {
+ case mm_swsp16_op:
+ if (ip->mm16_r5_format.rt != 31)
+ return 0;
+
+ *poff = ip->mm16_r5_format.simmediate;
+ *poff = (*poff << 2) / sizeof(ulong);
+ return 1;
+
+ case mm_pool16c_op:
+ switch (ip->mm16_m_format.func) {
+ case mm_swm16_op:
+ *poff = ip->mm16_m_format.imm;
+ *poff += 1 + ip->mm16_m_format.rlist;
+ *poff = (*poff << 2) / sizeof(ulong);
+ return 1;
+
+ default:
+ return 0;
+ }
+
+ default:
+ return 0;
+ }
+ }
+
+ switch (ip->i_format.opcode) {
+ case mm_sw32_op:
+ if (ip->i_format.rs != 29)
+ return 0;
+ if (ip->i_format.rt != 31)
+ return 0;
+
+ *poff = ip->i_format.simmediate / sizeof(ulong);
+ return 1;
+
+ case mm_pool32b_op:
+ switch (ip->mm_m_format.func) {
+ case mm_swm32_func:
+ if (ip->mm_m_format.rd < 0x10)
+ return 0;
+ if (ip->mm_m_format.base != 29)
+ return 0;
+
+ *poff = ip->mm_m_format.simmediate;
+ *poff += (ip->mm_m_format.rd & 0xf) * sizeof(u32);
+ *poff /= sizeof(ulong);
+ return 1;
+ default:
+ return 0;
+ }
+
+ default:
+ return 0;
}
#else
/* sw / sd $ra, offset($sp) */
- return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
- ip->i_format.rs == 29 &&
- ip->i_format.rt == 31;
+ if ((ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
+ ip->i_format.rs == 29 && ip->i_format.rt == 31) {
+ *poff = ip->i_format.simmediate / sizeof(ulong);
+ return 1;
+ }
+
+ return 0;
#endif
}
@@ -345,11 +390,9 @@ static int get_frame_info(struct mips_fr
}
continue;
}
- if (info->pc_offset == -1 && is_ra_save_ins(&insn)) {
- info->pc_offset =
- ip->i_format.simmediate / sizeof(long);
+ if (info->pc_offset == -1 &&
+ is_ra_save_ins(&insn, &info->pc_offset))
break;
- }
}
if (info->frame_size && info->pc_offset >= 0) /* nested */
return 0;
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH 4.4 00/91] 4.4.53-stable review Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-03-10 15:40 +0100 [PATCH 4.4 39/91] sd: get disk reference in sd_check_events() Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-03-10 15:40 +0100 [PATCH 4.4 09/91] MIPS: Calculate microMIPS ra properly when unwinding the stack Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-03-10 15:40 +0100 [PATCH 4.4 45/91] ext4: do not polute the extents cache while shifting extents Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-03-10 15:40 +0100 [PATCH 4.4 32/91] dm cache: fix corruption seen when using cache > 2TB Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-03-10 15:40 +0100 [PATCH 4.4 37/91] scsi: aacraid: Reorder Adapter status check Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-03-10 15:40 +0100 [PATCH 4.4 22/91] ALSA: hda - Add subwoofer support for Dell Inspiron 17 7000 Gaming Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-03-10 15:40 +0100 [PATCH 4.4 19/91] ALSA: timer: Reject user params with too small ticks Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-03-10 15:50 +0100 [PATCH 4.4 01/91] MIPS: Fix special case in 64 bit IP checksumming. Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-03-10 15:50 +0100 [PATCH 4.4 15/91] ARM: dts: at91: Enable DMA on sama5d4_xplained console Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-03-10 15:50 +0100 [PATCH 4.4 33/91] dm stats: fix a leaked s->histogram_boundaries array Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-03-10 15:50 +0100 [PATCH 4.4 13/91] [media] media: fix dm1105.c build error Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-03-10 15:50 +0100 Re: [PATCH 4.4 00/91] 4.4.53-stable review Guenter Roeck <linux@roeck-us.net> - 2017-03-10 19:40 +0100 Re: [PATCH 4.4 00/91] 4.4.53-stable review Shuah Khan <shuahkh@osg.samsung.com> - 2017-03-10 20:20 +0100 Re: [PATCH 4.4 00/91] 4.4.53-stable review Thomas Petazzoni <thomas.petazzoni@free-electrons.com> - 2017-03-13 10:00 +0100
csiph-web