您的位置:首页 > 运维架构 > Linux

Linux kernel crash and analysis example (3)

2013-10-10 10:11 525 查看
BUG:

Randomly, ARMv7 mobile crashed when USB OTG operations are executed.

Context:

[   30.648925] C0 [m.android.phone] Unable to handle kernel paging request at virtual address 6b6b6b9f
[   30.657958] C0 [m.android.phone] pgd = ec58c000
[   30.662506] C0 [m.android.phone] [6b6b6b9f] *pgd=00000000
[   30.667938] C0 [m.android.phone] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
[   30.675079] C0 [m.android.phone] kona_fb: die notifier invoked
[   30.680908] C0 [m.android.phone] kona_display_crash_image:531 image_idx=4
[   30.688690] C0 [m.android.phone] post_async:626 Likely tearing on screen posted:0x80000000 curr= 0x80000000 nxt=0x80000000
[   30.699737] C0 [m.android.phone] axipv_dump_buff_status:141 0x80000000 state=2
[   30.706970] C0 [m.android.phone] axipv_dump_buff_status:141 0x80384000 state=1
[   30.714263] C0 [m.android.phone] Modules linked in:
[   30.719177] C0 [m.android.phone] CPU: 0    Tainted: G        W     (3.4.5 #1)
[   30.726318] C0 [m.android.phone] PC is at handle_hc_nak_intr+0x3c/0x110
[   30.732940] C0 [m.android.phone] LR is at dwc_otg_hcd_handle_hc_n_intr+0x468/0x5c8
[   30.740509] C0 [m.android.phone] pc : [<c0326ca0>]    lr : [<c032747c>]    psr: 60000193
[   30.740539] C0 [m.android.phone] sp : ec58be88  ip : 00000000  fp : 00000000
[   30.755615] C0 [m.android.phone] r10: 00000012  r9 : 00000012  r8 : 00000001
[   30.762664] C0 [m.android.phone] r7 : ed8e2f00  r6 : fe020500  r5 : ee2e63c0  r4 : ebf5a900
[   30.770996] C0 [m.android.phone] r3 : ebf5a900  r2 : 6b6b6b6b  r1 : ee2e63c0  r0 : ed8e2f00
[   30.779327] C0 [m.android.phone] Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment user
[   30.787414] C2 [    kworker/2:1] bsc-i2c 3e018000.i2c: controller timed out
[   30.787414] C2 [    kworker/2:1] bsc-i2c 3e018000.i2c: failed to send the start command
[   30.787445] C2 [    kworker/2:1] bsc-i2c 3e018000.i2c: start command failed
[   30.810150] C0 [m.android.phone] Control: 10c53c7d  Table: ae58c06a  DAC: 00000015
[   30.817718] C0 [m.android.phone]
[   30.817718] C0 [m.android.phone] PC: 0xc0326c20:
[   30.825653] C0 [m.android.phone] 6c20
[   30.827545] C2 [    usb-storage] usb 1-1: reset high-speed USB device number 2 using dwc_otg
[   30.837799] C0 [m.android.phone]  e1a00006 e1a01005 e1a02004 e1a03007 eaffff65 e1a00006 e1a01005 e1a02004
[   30.847564] C0 [m.android.phone] 6c40  e1a03007 ebfffcc8 e288000c e3a01001 e3a02000 eb001749 e3a00001 e8bd8ffe
[   30.857727] C0 [m.android.phone] 6c60  fffff05b e92d40f7 e1a07000 e5d1c024 e1a05001 e1a06002 e1a04003 e35c0000
[   30.867919] C0 [m.android.phone] 6c80  0a000005 e5d13025 e3530000 e3a03000 15c43010 e5c43008 ea000028 e5932018
[   30.878173] C0 [m.android.phone] 6ca0  e5d23034 e3530002 0a000003 e3530003 0a000025 e3530000 1a000027 e5973000
[   30.888427] C0 [m.android.phone] 6cc0  e5d33066 e3530000 0a000006 e5d53002 e2033008 e6ef3073 e3530000 13a03000
[   30.898651] C0 [m.android.phone] 6ce0  15c43010 1a00001c e3a03000 e5c43010 e595302c e5d33006 e3530000 1a00000f
[   30.908874] C0 [m.android.phone] 6d00  e3a03004 e1a00005 e58d3000 e1a01006 e1a03004 ebfffc77 e1a02004 e1a00005
[   30.919067] C0 [m.android.phone]
[   30.919067] C0 [m.android.phone] LR: 0xc03273fc:
[   30.927001] C0 [m.android.phone] 73fc  e3888001 e7c5a29f e6ef907a e2093004 e6ef3073 e3530000 0a000005 e1a00005
[   30.937255] C0 [m.android.phone] 741c  e1a01004 e1a02006 e1a03007 ebfff8ee e1888000 e2093008 e6ef3073 e3530000
[   30.947479] C0 [m.android.phone] 743c  0a000005 e1a00005 e1a01004 e1a02006 e1a03007 ebfffb1b e1888000 e2093010
[   30.957489] C2 [    kworker/2:1] bsc-i2c 3e018000.i2c: controller timed out
[   30.957519] C2 [    kworker/2:1] bsc-i2c 3e018000.i2c: failed to send the start command
[   30.957550] C2 [    kworker/2:1] bsc-i2c 3e018000.i2c: start command failed
[   30.979461] C0 [m.android.phone] 745c  e6ef3073 e3530000 0a000005 e1a00005 e1a01004 e1a02006 e1a03007 ebfffdf9
[   30.989593] C0 [m.android.phone] 747c  e1888000 e2093020 e6ef3073 e3530000 0a000005 e1a00005 e1a01004 e1a02006
[   30.999755] C0 [m.android.phone] 749c  e1a03007 ebfffb36 e1888000 e2093040 e6ef3073 e3530000 0a000005 e1a00005
[   31.009918] C0 [m.android.phone] 74bc  e1a01004 e1a02006 e1a03007 ebfffe29 e1888000 e2099080 e6ef9079 e3590000
[   31.020050] C0 [m.android.phone] 74dc  0a000005 e1a00005 e1a01004 e1a02006 e1a03007 ebfffe7b e1888000 e7e7a45a


Analysis:

1) Find offending function

[   30.726318] C0 [m.android.phone] PC is at handle_hc_nak_intr+0x3c/0x110


/**
* Handles a host channel NAK interrupt. This handler may be called in either
* DMA mode or Slave mode.
*/
static int32_t handle_hc_nak_intr(dwc_otg_hcd_t *hcd,
dwc_hc_t *hc,
dwc_otg_hc_regs_t *hc_regs,
dwc_otg_qtd_t *qtd)
{
DWC_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
"NAK Received--\n", hc->hc_num);

/*
* Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and
* interrupt.  Re-start the SSPLIT transfer.
*/
if (hc->do_split) {
if (hc->complete_split)
qtd->error_count = 0;

qtd->complete_split = 0;
halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
goto handle_nak_done;
}

switch (dwc_otg_hcd_get_pipe_type(&qtd->urb->pipe_info)) {
case UE_CONTROL:
case UE_BULK:
if (hcd->core_if->dma_enable && hc->ep_is_in) {
/*
* NAK interrupts are enabled on bulk/control IN
* transfers in DMA mode for the sole purpose of
* resetting the error count after a transaction error
* occurs. The core will continue transferring data.
*/
qtd->error_count = 0;
goto handle_nak_done;
}

/*
* NAK interrupts normally occur during OUT transfers in DMA
* or Slave mode. For IN transfers, more requests will be
* queued as request queue space is available.
*/
qtd->error_count = 0;

if (!hc->qh->ping_state) {
update_urb_state_xfer_intr(hc, hc_regs,
qtd->urb, qtd,
DWC_OTG_HC_XFER_NAK);
dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd);

if (hc->speed == DWC_OTG_EP_SPEED_HIGH)
hc->qh->ping_state = 1;
}

/*
* Halt the channel so the transfer can be re-started from
* the appropriate point or the PING protocol will
* start/continue.
*/
halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
break;
case UE_INTERRUPT:
qtd->error_count = 0;
halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
break;
case UE_ISOCHRONOUS:
/* Should never get called for isochronous transfers. */
DWC_ASSERT(1, "NACK interrupt for ISOC transfer\n");
break;
}

handle_nak_done:
disable_hc_int(hc_regs, nak);

return 1;
}


2) assembly code

00001630 <handle_hc_nak_intr>:
*/
static int32_t handle_hc_nak_intr(dwc_otg_hcd_t *hcd,
dwc_hc_t *hc,
dwc_otg_hc_regs_t *hc_regs,
dwc_otg_qtd_t *qtd)
{
1630:	e92d40f7 	push	{r0, r1, r2, r4, r5, r6, r7, lr}
1634:	e1a07000 	mov	r7, r0

/*
* Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and
* interrupt.  Re-start the SSPLIT transfer.
*/
if (hc->do_split) {
1638:	e5d1c024 	ldrb	ip, [r1, #36]	; 0x24
*/
static int32_t handle_hc_nak_intr(dwc_otg_hcd_t *hcd,
dwc_hc_t *hc,
dwc_otg_hc_regs_t *hc_regs,
dwc_otg_qtd_t *qtd)
{
163c:	e1a05001 	mov	r5, r1
1640:	e1a06002 	mov	r6, r2
1644:	e1a04003 	mov	r4, r3

/*
* Handle NAK for IN/OUT SSPLIT/CSPLIT transfers, bulk, control, and
* interrupt.  Re-start the SSPLIT transfer.
*/
if (hc->do_split) {
1648:	e35c0000 	cmp	ip, #0
164c:	0a000005 	beq	1668 <handle_hc_nak_intr+0x38>
if (hc->complete_split)
1650:	e5d13025 	ldrb	r3, [r1, #37]	; 0x25
1654:	e3530000 	cmp	r3, #0
1658:	e3a03000 	mov	r3, #0
qtd->error_count = 0;
165c:	15c43010 	strbne	r3, [r4, #16]

qtd->complete_split = 0;
1660:	e5c43008 	strb	r3, [r4, #8]
1664:	ea000028 	b	170c <handle_hc_nak_intr+0xdc>
halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
goto handle_nak_done;
}

switch (dwc_otg_hcd_get_pipe_type(&qtd->urb->pipe_info)) {
1668:	e5932018 	ldr	r2, [r3, #24]
166c:	e5d23034 	ldrb	r3, [r2, #52]	; 0x34
1670:	e3530002 	cmp	r3, #2
1674:	0a000003 	beq	1688 <handle_hc_nak_intr+0x58>
1678:	e3530003 	cmp	r3, #3
167c:	0a000025 	beq	1718 <handle_hc_nak_intr+0xe8>
1680:	e3530000 	cmp	r3, #0
1684:	1a000027 	bne	1728 <handle_hc_nak_intr+0xf8>
case UE_CONTROL:
case UE_BULK:
if (hcd->core_if->dma_enable && hc->ep_is_in) {
1688:	e5973000 	ldr	r3, [r7]
168c:	e5d33066 	ldrb	r3, [r3, #102]	; 0x66
1690:	e3530000 	cmp	r3, #0
1694:	0a000006 	beq	16b4 <handle_hc_nak_intr+0x84>
1698:	e5d53002 	ldrb	r3, [r5, #2]
169c:	e2033008 	and	r3, r3, #8
16a0:	e6ef3073 	uxtb	r3, r3
16a4:	e3530000 	cmp	r3, #0
* NAK interrupts are enabled on bulk/control IN
* transfers in DMA mode for the sole purpose of
* resetting the error count after a transaction error
* occurs. The core will continue transferring data.
*/
qtd->error_count = 0;
16a8:	13a03000 	movne	r3, #0
16ac:	15c43010 	strbne	r3, [r4, #16]
}

switch (dwc_otg_hcd_get_pipe_type(&qtd->urb->pipe_info)) {
case UE_CONTROL:
case UE_BULK:
if (hcd->core_if->dma_enable && hc->ep_is_in) {
16b0:	1a00001c 	bne	1728 <handle_hc_nak_intr+0xf8>
/*
* NAK interrupts normally occur during OUT transfers in DMA
* or Slave mode. For IN transfers, more requests will be
* queued as request queue space is available.
*/
qtd->error_count = 0;
16b4:	e3a03000 	mov	r3, #0
16b8:	e5c43010 	strb	r3, [r4, #16]

if (!hc->qh->ping_state) {
16bc:	e595302c 	ldr	r3, [r5, #44]	; 0x2c
16c0:	e5d33006 	ldrb	r3, [r3, #6]
16c4:	e3530000 	cmp	r3, #0
16c8:	1a00000f 	bne	170c <handle_hc_nak_intr+0xdc>
update_urb_state_xfer_intr(hc, hc_regs,
16cc:	e3a03004 	mov	r3, #4
16d0:	e1a00005 	mov	r0, r5
16d4:	e58d3000 	str	r3, [sp]
16d8:	e1a01006 	mov	r1, r6
16dc:	e1a03004 	mov	r3, r4
16e0:	ebfffc77 	bl	8c4 <update_urb_state_xfer_intr>
qtd->urb, qtd,
DWC_OTG_HC_XFER_NAK);
dwc_otg_hcd_save_data_toggle(hc, hc_regs, qtd);
16e4:	e1a02004 	mov	r2, r4
16e8:	e1a00005 	mov	r0, r5
16ec:	e1a01006 	mov	r1, r6
16f0:	ebfffffe 	bl	11d4 <dwc_otg_hcd_save_data_toggle>

if (hc->speed == DWC_OTG_EP_SPEED_HIGH)
16f4:	e5d53002 	ldrb	r3, [r5, #2]
16f8:	e2033030 	and	r3, r3, #48	; 0x30
16fc:	e3530020 	cmp	r3, #32
hc->qh->ping_state = 1;
1700:	0595302c 	ldreq	r3, [r5, #44]	; 0x2c
1704:	03a02001 	moveq	r2, #1
1708:	05c32006 	strbeq	r2, [r3, #6]
/*
* Halt the channel so the transfer can be re-started from
* the appropriate point or the PING protocol will
* start/continue.
*/
halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
170c:	e1a00007 	mov	r0, r7
1710:	e1a01005 	mov	r1, r5
1714:	ea000000 	b	171c <handle_hc_nak_intr+0xec>
break;
case UE_INTERRUPT:
qtd->error_count = 0;
1718:	e5c4c010 	strb	ip, [r4, #16]
halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_NAK);
171c:	e1a02004 	mov	r2, r4
1720:	e3a03004 	mov	r3, #4
1724:	ebfffc83 	bl	938 <halt_channel>
DWC_ASSERT(1, "NACK interrupt for ISOC transfer\n");
break;
}

handle_nak_done:
disable_hc_int(hc_regs, nak);
1728:	e286000c 	add	r0, r6, #12
172c:	e3a01010 	mov	r1, #16
1730:	e3a02000 	mov	r2, #0
1734:	ebfffffe 	bl	0 <DWC_MODIFY_REG32>

return 1;
}
1738:	e3a00001 	mov	r0, #1
173c:	e8bd80fe 	pop	{r1, r2, r3, r4, r5, r6, r7, pc}


3) offending code

1668:	e5932018 	ldr	r2, [r3, #24]
166c:	e5d23034 	ldrb	r3, [r2, #52]	; 0x34         // [r2, #52] is 0


4) Must check null pointer before usage

dwc_otg_hcd_get_pipe_type(&qtd->urb->pipe_info)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: