cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

unicam driver null pointer dereference

Sat Sep 25, 2021 4:59 am

i tried spinning up the unicam driver on my pi2 today, with the open firmware, only to discover it has a null-pointer deference in it

Code: Select all

[    1.232720] 8<--- cut here ---
[    1.235911] Unable to handle kernel NULL pointer dereference at virtual address 00000028
[    1.244275] pgd = (ptrval)
[    1.247081] [00000028] *pgd=00000000
[    1.250801] Internal error: Oops: 5 [#1] ARM
[    1.255223] Modules linked in:
[    1.258395] CPU: 0 PID: 1 Comm: swapper Tainted: G        W         5.14.2+ #12
[    1.265960] Hardware name: BCM2835
[    1.269478] PC is at v4l2_event_subscribed+0x18/0x4c
[    1.274631] LR is at __v4l2_event_queue_fh+0x34/0x200
[    1.279866] pc : [<c061599c>]    lr : [<c06160d8>]    psr: 00000193
[    1.286345] sp : c151f988  ip : c151f998  fp : c151f994
[    1.291748] r10: c0cc70b1  r9 : 00000193  r8 : 492653d1
[    1.297151] r7 : 492653d1  r6 : c151f9f8  r5 : 00000000  r4 : c15237c0
[    1.303900] r3 : 00000000  r2 : 00000000  r1 : 00000004  r0 : 00000000
[    1.310648] Flags: nzcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
[    1.318122] Control: 10c53c7d  Table: 00004059  DAC: 00000051
[    1.324059] Register r0 information: NULL pointer
[    1.328932] Register r1 information: non-paged memory
[    1.336207] Register r2 information: NULL pointer
[    1.343137] Register r3 information: NULL pointer
[    1.349985] Register r4 information: slab kmalloc-4k start c1523000 pointer offset 1984 size 4096
[    1.363118] Register r5 information: NULL pointer
[    1.369960] Register r6 information: non-slab/vmalloc memory
[    1.377720] Register r7 information: non-paged memory
[    1.384848] Register r8 information: non-paged memory
[    1.391944] Register r9 information: non-paged memory
[    1.398995] Register r10 information: non-slab/vmalloc memory
[    1.406776] Register r11 information: non-slab/vmalloc memory
[    1.414492] Register r12 information: non-slab/vmalloc memory
[    1.422125] Process swapper (pid: 1, stack limit = 0x(ptrval))
[    1.429873] Stack: (0xc151f988 to 0xc1520000)
[    1.436119] f980:                   c151f9cc c151f998 c06160d8 c0615990 c151f9cc 00000000
[    1.448110] f9a0: c0170cc8 c15237c0 00000000 c151f9f8 492653d1 00000000 00000193 c0cc70b1
[    1.460204] f9c0: c151f9f4 c151f9d0 c0616304 c06160b0 c1523000 00000001 c1523b70 00000007
[    1.472472] f9e0: c11394d0 c1523b70 c151fa9c c151f9f8 c063f1f0 c06162b0 00000004 00000000
[    1.484830] fa00: 00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    1.497268] fa20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    1.509973] fa40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    1.523009] fa60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    1.536127] fa80: 00000000 c0f04248 c11394d0 c1523000 c151fae4 c151faa0 c0640f60 c063f1a0
[    1.549490] faa0: c151faf8 00000000 c151facc 00000000 492648d4 c1523b70 00000000 c16daec0
[    1.563233] fac0: 00000000 0000003f c14ed300 c151fb20 00000000 c107075e c151fb1c c151fae8
[    1.577275] fae0: c015c7d4 c0640d84 c06892ec c044a7d8 c151fb1c c14ed300 00000000 c14ed314
[    1.591652] fb00: 00000000 0000003f c151e000 60000013 c151fb3c c151fb20 c015c914 c015c774
[    1.606140] fb20: 00000000 c0f04248 c14ed300 00000000 c151fb54 c151fb40 c015c99c c015c8e4
[    1.620695] fb40: c14ed300 00000000 c151fb74 c151fb58 c0160dc0 c015c970 c0f04b1c c1406180
[    1.635249] fb60: 00000008 00000000 c151fb84 c151fb78 c015ba84 c0160d58 c151fb94 c151fb88
[    1.652929] fb80: c015bdfc c015ba5c c151fbac c151fb98 c0453280 c015bde8 c102000c c1406180
[    1.667483] fba0: c151fbbc c151fbb0 c015ba84 c045325c c151fbdc c151fbc0 c015c140 c015ba5c
[    1.682036] fbc0: c015c9d0 60000013 ffffffff c151fc24 c151fbec c151fbe0 c0101300 c015c100
[    1.696587] fbe0: c151fc4c c151fbf0 c0100b4c c01012c8 60000013 00000000 00000000 60000013
[    1.711141] fc00: c14ed300 c16daec0 00000000 00000000 0000003f c14ed3b0 60000013 c151fc4c
[    1.725698] fc20: c151fc50 c151fc40 c015e320 c015c9d0 60000013 ffffffff 00000051 00000000
[    1.740256] fc40: c151fc8c c151fc50 c015e320 c015c9bc c15a2810 00000000 c0cc72ea c14ed33c
[    1.754815] fc60: c0640d78 00000000 c16daec0 c14ed300 c14ed314 0000003f 00000000 c1523000
[    1.769375] fc80: c151fcbc c151fc90 c015e558 c015de30 00000000 c17348c0 c0cc72ea c15a2810
[    1.783936] fca0: 0000003f c1523000 c0640d78 00000000 c151fcf4 c151fcc0 c0161774 c015e4a8
[    1.798495] fcc0: c0cc72ea c1523000 c151fcf4 c1523000 00000001 c15a2810 c103931c 00000000
[    1.813054] fce0: c15a2800 000000cb c151fd7c c151fcf8 c0641e28 c01616fc 00000000 c0cc72ea
[    1.827612] fd00: c1523000 c151fd10 c0689cf0 c06894fc ffffffff 00000001 00000000 00000000
[    1.842168] fd20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c0f04248
[    1.856728] fd40: c151fd74 c15a2810 c151fd6c c0f04248 c05410f0 00000000 c15a2810 c103931c
[    1.871288] fd60: c103931c 00000000 c0e36830 000000cb c151fd9c c151fd80 c053297c c0641cd4
[    1.885846] fd80: c15a2810 00000000 00000000 c103931c c151fdc4 c151fda0 c05303ac c0532920
[    1.900405] fda0: c151fdc4 c151fdb0 c15a2810 c103931c c103931c c15a2810 c151fdf4 c151fdc8
[    1.914963] fdc0: c053078c c05301cc c151fdec c151fdd8 c1137ffc c1138000 c103931c c15a2810
[    1.929521] fde0: 00000000 c0e36830 c151fe1c c151fdf8 c0530800 c05305e0 c15a2810 00000000
[    1.944077] fe00: c103931c 00000000 c0d56290 c0e36830 c151fe3c c151fe20 c0530de8 c05307cc
[    1.958635] fe20: c15a2810 c103931c c0530cbc 00000000 c151fe6c c151fe40 c052e1b4 c0530cc8
[    1.973195] fe40: c0e36830 c150510c c159fdb0 c0f04248 c17341b4 c103931c c1734180 c1028df0
[    1.987753] fe60: c151fe7c c151fe70 c052fa34 c052e148 c151fea4 c151fe80 c052f4d0 c052fa18
[    2.002310] fe80: c0cc792d c151fe90 c103931c 00000007 c0e36850 00000000 c151febc c151fea8
[    2.016868] fea0: c05314b0 c052f354 c0e2708c 00000007 c151fecc c151fec0 c053272c c0531400
[    2.031426] fec0: c151fedc c151fed0 c0e270ac c0532710 c151ff4c c151fee0 c0101f94 c0e27098
[    2.045986] fee0: c140ba00 c024def4 c1401300 c0d57200 000000ca c0d5726c 00000000 00000006
[    2.060545] ff00: 00000006 000000cb c0d56290 c0e00448 00000dc0 c140bb13 c140bb1c c0f04248
[    2.075106] ff20: c0f0cb68 c140ba00 00000007 c0f04248 c140ba00 00000007 c0e36850 c1096000
[    2.089664] ff40: c151ff94 c151ff50 c0e013c8 c0101f3c 00000006 00000006 00000000 c0e00448
[    2.104221] ff60: c0913e9c c0e6f1c4 00000000 00000000 c0912578 00000000 00000000 00000000
[    2.118781] ff80: 00000000 00000000 c151ffac c151ff98 c0912598 c0e01208 00000000 c0912578
[    2.133340] ffa0: 00000000 c151ffb0 c0100150 c0912584 00000000 00000000 00000000 00000000
[    2.147896] ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    2.162452] ffe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
[    2.176997] Backtrace: 
[    2.182511] [<c0615984>] (v4l2_event_subscribed) from [<c06160d8>] (__v4l2_event_queue_fh+0x34/0x200)
[    2.198000] [<c06160a4>] (__v4l2_event_queue_fh) from [<c0616304>] (v4l2_event_queue+0x60/0x68)
[    2.212961]  r10:c0cc70b1 r9:00000193 r8:00000000 r7:492653d1 r6:c151f9f8 r5:00000000
[    2.226978]  r4:c15237c0
[    2.232488] [<c06162a4>] (v4l2_event_queue) from [<c063f1f0>] (unicam_queue_event_sof+0x5c/0x80)
[    2.247353]  r9:c1523b70 r8:c11394d0 r7:00000007 r6:c1523b70 r5:00000001 r4:c1523000
[    2.261090] [<c063f194>] (unicam_queue_event_sof) from [<c0640f60>] (unicam_isr+0x1e8/0x2f0)
[    2.275579]  r4:c1523000
[    2.280996] [<c0640d78>] (unicam_isr) from [<c015c7d4>] (__handle_irq_event_percpu+0x6c/0x170)
[    2.295502]  r10:c107075e r9:00000000 r8:c151fb20 r7:c14ed300 r6:0000003f r5:00000000
[    2.309149]  r4:c16daec0
[    2.314474] [<c015c768>] (__handle_irq_event_percpu) from [<c015c914>] (handle_irq_event_percpu+0x3c/0x8c)
[    2.329859]  r10:60000013 r9:c151e000 r8:0000003f r7:00000000 r6:c14ed314 r5:00000000
[    2.343316]  r4:c14ed300
[    2.348546] [<c015c8d8>] (handle_irq_event_percpu) from [<c015c99c>] (handle_irq_event+0x38/0x4c)
[    2.363089]  r5:00000000 r4:c14ed300
[    2.369413] [<c015c964>] (handle_irq_event) from [<c0160dc0>] (handle_level_irq+0x74/0xac)
[    2.383205]  r5:00000000 r4:c14ed300
[    2.389459] [<c0160d4c>] (handle_level_irq) from [<c015ba84>] (handle_irq_desc+0x34/0x44)
[    2.403114]  r7:00000000 r6:00000008 r5:c1406180 r4:c0f04b1c
[    2.411578] [<c015ba50>] (handle_irq_desc) from [<c015bdfc>] (generic_handle_domain_irq+0x20/0x24)
[    2.426060] [<c015bddc>] (generic_handle_domain_irq) from [<c0453280>] (bcm2836_chained_handle_irq+0x30/0x38)
[    2.441537] [<c0453250>] (bcm2836_chained_handle_irq) from [<c015ba84>] (handle_irq_desc+0x34/0x44)
[    2.456192]  r5:c1406180 r4:c102000c
[    2.462522] [<c015ba50>] (handle_irq_desc) from [<c015c140>] (handle_domain_irq+0x4c/0x64)
[    2.476316] [<c015c0f4>] (handle_domain_irq) from [<c0101300>] (bcm2836_arm_irqchip_handle_irq+0x44/0x4c)
[    2.491554]  r7:c151fc24 r6:ffffffff r5:60000013 r4:c015c9d0
[    2.500088] [<c01012bc>] (bcm2836_arm_irqchip_handle_irq) from [<c0100b4c>] (__irq_svc+0x6c/0x90)
[    2.514630] Exception stack(0xc151fbf0 to 0xc151fc38)
[    2.522519] fbe0:                                     60000013 00000000 00000000 60000013
[    2.536375] fc00: c14ed300 c16daec0 00000000 00000000 0000003f c14ed3b0 60000013 c151fc4c
[    2.550248] fc20: c151fc50 c151fc40 c015e320 c015c9d0 60000013 ffffffff
[    2.559829] [<c015c9b0>] (arch_local_irq_restore) from [<c015e320>] (__setup_irq+0x4fc/0x678)
[    2.574171] [<c015de24>] (__setup_irq) from [<c015e558>] (request_threaded_irq+0xbc/0x148)
[    2.588343]  r10:c1523000 r9:00000000 r8:0000003f r7:c14ed314 r6:c14ed300 r5:c16daec0
[    2.602071]  r4:00000000
[    2.607442] [<c015e49c>] (request_threaded_irq) from [<c0161774>] (devm_request_threaded_irq+0x84/0xbc)
[    2.622662]  r10:00000000 r9:c0640d78 r8:c1523000 r7:0000003f r6:c15a2810 r5:c0cc72ea
[    2.636temp changed -6.183990 -> 38.470001224]  r4:c17348c0 r3:00000000
[    2.645688] [<c01616f0>] (devm_request_threaded_irq) from [<c0641e28>] (unicam_probe+0x160/0x5a8)
[    2.660543]  r10:000000cb r9:c15a2800 r8:00000000 r7:c103931c r6:c15a2810 r5:00000001
[    2.674095]  r4:c1523000
[    2.679393] [<c0641cc8>] (unicam_probe) from [<c053297c>] (platform_probe+0x68/0xb8)
[    2.692790]  r10:000000cb r9:c0e36830 r8:00000000 r7:c103931c r6:c103931c r5:c15a2810
[    2.706289]  r4:00000000
[    2.711598] [<c0532914>] (platform_probe) from [<c05303ac>] (really_probe+0x1ec/0x414)
[    2.725164]  r7:c103931c r6:00000000 r5:00000000 r4:c15a2810
[    2.733668] [<c05301c0>] (really_probe) from [<c053078c>] (__driver_probe_device+0x1b8/0x1ec)
[    2.747830]  r7:c15a2810 r6:c103931c r5:c103931c r4:c15a2810
[    2.756316] [<c05305d4>] (__driver_probe_device) from [<c0530800>] (driver_probe_device+0x40/0xbc)
[    2.770865]  r9:c0e36830 r8:00000000 r7:c15a2810 r6:c103931c r5:c1138000 r4:c1137ffc
[    2.784193] [<c05307c0>] (driver_probe_device) from [<c0530de8>] (__driver_attach+0x12c/0x158)
[    2.798566]  r9:c0e36830 r8:c0d56290 r7:00000000 r6:c103931c r5:00000000 r4:c15a2810
[    2.812000] [<c0530cbc>] (__driver_attach) from [<c052e1b4>] (bus_for_each_dev+0x78/0xb8)
[    2.826048]  r7:00000000 r6:c0530cbc r5:c103931c r4:c15a2810
[    2.834663] [<c052e13c>] (bus_for_each_dev) from [<c052fa34>] (driver_attach+0x28/0x30)
[    2.848481]  r6:c1028df0 r5:c1734180 r4:c103931c
[    2.856048] [<c052fa0c>] (driver_attach) from [<c052f4d0>] (bus_add_driver+0x188/0x1f0)
[    2.869931] [<c052f348>] (bus_add_driver) from [<c05314b0>] (driver_register+0xbc/0x100)
[    2.883925]  r7:00000000 r6:c0e36850 r5:00000007 r4:c103931c
[    2.892626] [<c05313f4>] (driver_register) from [<c053272c>] (__platform_driver_register+0x28/0x30)
[    2.907713]  r5:00000007 r4:c0e2708c
[    2.914230] [<c0532704>] (__platform_driver_register) from [<c0e270ac>] (unicam_driver_init+0x20/0x28)
[    2.929519] [<c0e2708c>] (unicam_driver_init) from [<c0101f94>] (do_one_initcall+0x64/0x178)
[    2.943960] [<c0101f30>] (do_one_initcall) from [<c0e013c8>] (kernel_init_freeable+0x1cc/0x20c)
[    2.958694]  r7:c1096000 r6:c0e36850 r5:00000007 r4:c140ba00
[    2.967376] [<c0e011fc>] (kernel_init_freeable) from [<c0912598>] (kernel_init+0x20/0x13c)
[    2.981604]  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0912578
[    2.995332]  r4:00000000
[    3.000699] [<c0912578>] (kernel_init) from [<c0100150>] (ret_from_fork+0x14/0x24)
[    3.014041] Exception stack(0xc151ffb0 to 0xc151fff8)
[    3.022018] ffa0:                                     00000000 00000000 00000000 00000000
[    3.035928] ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    3.049851] ffe0: 00000000 00000000 00000000 00000000 00000013 00000000
[    3.059423]  r5:c0912578 r4:00000000
[    3.065833] Code: e24cb004 e52de004 e8bd4000 e1a03000 (e5b30028) 
[    3.074825] ---[ end trace 3982f302762a7bdb ]---
[    3.082273] Kernel panic - not syncing: Fatal exception in interrupt
[    3.091504] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---
and the disassembly of the faulting function:

Code: Select all

c0615984 <v4l2_event_subscribed>:
c0615984:       e1a0c00d        mov     ip, sp
c0615988:       e92dd800        push    {fp, ip, lr, pc}
c061598c:       e24cb004        sub     fp, ip, #4
c0615990:       e52de004        push    {lr}            ; (str lr, [sp, #-4]!)
c0615994:       ebebdda0        bl      c010d01c <__gnu_mcount_nc>
c0615998:       e1a03000        mov     r3, r0
c061599c:       e5b30028        ldr     r0, [r3, #40]!  ; 0x28
c06159a0:       e1500003        cmp     r0, r3
c06159a4:       1a000001        bne     c06159b0 <v4l2_event_subscribed+0x2c>
c06159a8:       e3a00000        mov     r0, #0
c06159ac:       e89da800        ldm     sp, {fp, sp, pc}
c06159b0:       e590c008        ldr     ip, [r0, #8]
c06159b4:       e15c0001        cmp     ip, r1
c06159b8:       1a000002        bne     c06159c8 <v4l2_event_subscribed+0x44>
c06159bc:       e590c00c        ldr     ip, [r0, #12]
c06159c0:       e15c0002        cmp     ip, r2
c06159c4:       089da800        ldmeq   sp, {fp, sp, pc}
c06159c8:       e5900000        ldr     r0, [r0]
c06159cc:       eafffff3        b       c06159a0 <v4l2_event_subscribed+0x1c>
from that, i can see that:

Code: Select all

/* Caller must hold fh->vdev->fh_lock! */
static struct v4l2_subscribed_event *v4l2_event_subscribed(
                struct v4l2_fh *fh, u32 type, u32 id) 
{
        struct v4l2_subscribed_event *sev;

        assert_spin_locked(&fh->vdev->fh_lock);

        list_for_each_entry(sev, &fh->subscribed, list)
                if (sev->type == type && sev->id == id) 
                        return sev;

        return NULL;
}
the "fh" pointer in here was null

and then looking at the backtrace closer, i can see that the instant the IRQ was registered, it fired, before even returning back to unicam_probe()

what i think is happening here, is that there is an error condition present in the unicam, and the irq handler is being configured before the driver is ready to handle IRQ's

so i moved the irq configuration down later in probe:

Code: Select all

[nix-shell:~/apps/rpi/linux-5.14]$ git diff
diff --git a/drivers/media/platform/bcm2835/bcm2835-unicam.c b/drivers/media/platform/bcm2835/bcm2835-unicam.c
index f1ea1c2da6c3..87ed05eeedaf 100644
--- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
@@ -2807,21 +2807,6 @@ static int unicam_probe(struct platform_device *pdev)
                goto err_unicam_put;
        }
 
-       ret = platform_get_irq(pdev, 0);
-       if (ret <= 0) {
-               dev_err(&pdev->dev, "No IRQ resource\n");
-               ret = -EINVAL;
-               goto err_unicam_put;
-       }
-
-       ret = devm_request_irq(&pdev->dev, ret, unicam_isr, 0,
-                              "unicam_capture0", unicam);
-       if (ret) {
-               dev_err(&pdev->dev, "Unable to request interrupt\n");
-               ret = -EINVAL;
-               goto err_unicam_put;
-       }
-
        unicam->mdev.dev = &pdev->dev;
        strscpy(unicam->mdev.model, UNICAM_MODULE_NAME,
                sizeof(unicam->mdev.model));
@@ -2862,6 +2847,21 @@ static int unicam_probe(struct platform_device *pdev)
                goto err_media_unregister;
        }
 
+       ret = platform_get_irq(pdev, 0);
+       if (ret <= 0) {
+               dev_err(&pdev->dev, "No IRQ resource\n");
+               ret = -EINVAL;
+               goto err_media_unregister;
+       }
+
+       ret = devm_request_irq(&pdev->dev, ret, unicam_isr, 0,
+                              "unicam_capture0", unicam);
+       if (ret) {
+               dev_err(&pdev->dev, "Unable to request interrupt\n");
+               ret = -EINVAL;
+               goto err_media_unregister;
+       }
+
        /* Enable the block power domain */
        pm_runtime_enable(&pdev->dev);
that does resolve the null-pointer, but now it just hangs hard

i think the error condition, isnt something linux is expecting, so linux isnt clearing the fault
and the irq handler is then getting called in an infinite loop, so it cant progress any further in the bootup


where could i find more documentation on the unicam?
how could i debug what isnt initialized right and is causing it to get stuck an irq handler?

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 11812
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: unicam driver null pointer dereference

Sat Sep 25, 2021 12:02 pm

Unicam producing a Frame Start Interrupt would imply that the sensor is streaming, and that would be a totally unexpected situation. Stranger still that the analogue side of Unicam is kept in reset until unicam_start_rx, and we're using pm_runtime to control powering up the power domain, so it really shouldn't be doing anything at that point.

Sorry, we can't publish details of Unicam as it's Broadcom IP.

Whilst we could defer requesting the iRQ until later on, or add a trap in the isr to ensure we're initialised, something feels quite wrong.
The isr does have a log line at https://github.com/raspberrypi/linux/bl ... cam.c#L814 if the debug level is 3 or greater to show what interrupt bits are set, so knowing that would help. All of them are cleared, so none should fire repeatedly without cause.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Sat Sep 25, 2021 12:42 pm

i did try booting with "bcm2835-unicam.debug=3" but that didnt produce any useful logs

i suspect the reason is that it used request_threaded_irq(), so the unicam_isr() is ran in a thread

but the backtrace says otherwise...

i'll see if i can get mode details out of things, either jtag or printk spam

also of note:

Code: Select all

    csi1: csi@7e801000 {
      compatible = "brcm,bcm2835-unicam";
      reg = <0x7e801000 0x800>, <0x7e802004 0x4>;
      interrupts = <2 7>;
      clocks = <&clocks BCM2835_CLOCK_CAM1>, <&clocks BCM2835_CLOCK_VPU>;
      clock-names = "lp", "vpu";
      #address-cells = <1>;
      #size-cells = <0>;
      #clock-cells = <1>;
      //power-domains = <&power RPI_POWER_DOMAIN_UNICAM1>;
      brcm,num-data-lanes = <2>;
      port {
        csi1_ep: endpoint {
          remote-endpoint = <&ov5647_0>;
          data-lanes = <1 2>;
        };
      };
    };
the power domain is commented out currently
i assumed that if i can see the "ucam" id code in the MMIO window, the power domain is already on
but from what youve said, the power domain only impacts the analog side

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Sat Sep 25, 2021 3:15 pm

Code: Select all

(gdb) set $pc=0x28
(gdb) break unicam_isr
Breakpoint 1 at 0xc0640d78: file ../drivers/media/platform/bcm2835/bcm2835-unicam.c, line 800.
(gdb) c
Continuing.
^Crpi2.a7.0 rev 5, partnum c07, arch f, variant 0, implementor 41

Program received signal SIGINT, Interrupt.
__arch_counter_get_cntvct () at ../arch/arm/include/asm/arch_timer.h:106
106     ../arch/arm/include/asm/arch_timer.h: No such file or directory.
(gdb) bt
#0  __arch_counter_get_cntvct () at ../arch/arm/include/asm/arch_timer.h:106
#1  arch_counter_get_cntvct () at ../drivers/clocksource/arm_arch_timer.c:181
#2  0xc010d014 in arch_timer_read_counter_long () at ../arch/arm/kernel/arch_timer.c:19
#3  0xc0438454 in read_current_timer (timer_val=timer_val@entry=0xc151f7e0) at ../arch/arm/lib/delay.c:35
#4  0xc04384b4 in __timer_delay (cycles=19199) at ../arch/arm/lib/delay.c:49
#5  0xc0438548 in __timer_const_udelay (xloops=<optimized out>) at ../arch/arm/lib/delay.c:57
#6  0xc090a1d0 in panic (fmt=0xc0c4dd1f "Fatal exception in interrupt") at ../kernel/panic.c:361
#7  0xc010b7f4 in oops_end (signr=6500, regs=0xc1096390 <panic_on_oops>, flags=1610613139) at ../arch/arm/kernel/traps.c:349
#8  die (str=0x18 "", str@entry=0xc0c4f142 "Oops", regs=0xc1096390 <panic_on_oops>, regs@entry=0xc151f930, err=-1060162612, err@entry=5) at ../arch/arm/kernel/traps.c:371
#9  0xc0112164 in __do_kernel_fault (mm=0x0, mm@entry=0x5, addr=40, addr@entry=3243374896, fsr=fsr@entry=5, regs=regs@entry=0xc151f930) at ../arch/arm/mm/fault.c:126
#10 0xc09170a0 in __do_kernel_fault (regs=0xc151f930, fsr=5, addr=3243374896, mm=0x5) at ../arch/arm/mm/fault.c:113
#11 do_page_fault (addr=3243374896, fsr=fsr@entry=5, regs=0xc151f930) at ../arch/arm/mm/fault.c:361
#12 0xc0917148 in do_translation_fault (addr=<optimized out>, fsr=5, regs=<optimized out>) at ../arch/arm/mm/fault.c:401
#13 0xc0112274 in do_DataAbort (addr=40, fsr=5, regs=0xc151f930) at ../arch/arm/mm/fault.c:522
#14 0xc0100aa0 in __dabt_svc () at ../arch/arm/kernel/entry-armv.S:196
#15 0xc0100aa0 in __dabt_svc () at ../arch/arm/kernel/entry-armv.S:196
#16 0xc0100aa0 in __dabt_svc () at ../arch/arm/kernel/entry-armv.S:196
i'm able to connect over jtag
but the breakpoint is refusing to work
and i dont know what virtual addr linux mapped the unicam at, so i cant dump it directly

will need to investigate more

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 11812
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: unicam driver null pointer dereference

Sat Sep 25, 2021 4:50 pm

Sorry, not something I'm going to spend any significant amount of time investigating.
I didn't remember there being an ID register in Unicam. Most peripherals read back the same value for all registers should the block be unpowered to stop an AXI bus lockup, although that may be a VPU thing rather than ARM.

Power domain controls clock and power gating to the block. There is further gating of the analogue side via the UNICAM_ANA register.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Sat Sep 25, 2021 5:16 pm

ah, found an openocd command to read by physical addr, bypassing the MMU

Code: Select all

(gdb) monitor mdw phys 0x3f801000
0x3f801000: 00001210 UNICAM_CTRL
0x3f801004: 002a4000 UNICAM_STA
0x3f801008: 00000406 UNICAM_ANA
0x3f80100c: 00000010 UNICAM_PRI
0x3f801104: 00000005 UNICAM_ISTA
and then cross-referencing the linux source

Code: Select all

/* UNICAM_STA Register */
#define UNICAM_IS               BIT(14)
#define UNICAM_FSI_S            BIT(17)
#define UNICAM_LCI_S            BIT(19)
#define UNICAM_BUF0_NO          BIT(21)
/* UNICAM_ISTA Register */
#define UNICAM_FSI              BIT(0)
#define UNICAM_LCI              BIT(2)
those bits are all present when it caused a kernel panic
6by9 wrote:
Sat Sep 25, 2021 4:50 pm
I didn't remember there being an ID register in Unicam.
if i flip it back to status="disabled"; then i can:

Code: Select all

[root@nixos:~]# ramdumper -m -a 0x3f801000 -l 0x100
starting at 0x3f801000 (1016MB)
0x3f801000 10 02 00 00 00 c0 2a 00  06 04 00 00 10 00 00 00  |......*.........|
0x3f801010 02 00 00 4d 00 00 00 00  00 00 00 80 02 00 00 80  |...M............|
0x3f801020 02 00 00 92 02 00 00 02  00 00 00 00 00 00 00 00  |................|
0x3f801030 00 01 00 00 08 00 40 00  92 00 00 00 6d 61 63 75  |......@.....macu|
0x3f801040 6d 61 63 75 6d 61 63 75  6d 61 63 75 6d 61 63 75  |macumacumacumacu|
0x3f801050 6d 61 63 75 6d 61 63 75  6d 61 63 75 6d 61 63 75  |macumacumacumacu|
0x3f801060 6d 61 63 75 6d 61 63 75  6d 61 63 75 6d 61 63 75  |macumacumacumacu|
0x3f801070 6d 61 63 75 6d 61 63 75  6d 61 63 75 6d 61 63 75  |macumacumacumacu|
0x3f801080 6d 61 63 75 6d 61 63 75  6d 61 63 75 6d 61 63 75  |macumacumacumacu|
0x3f801090 6d 61 63 75 6d 61 63 75  6d 61 63 75 6d 61 63 75  |macumacumacumacu|
0x3f8010a0 6d 61 63 75 6d 61 63 75  6d 61 63 75 6d 61 63 75  |macumacumacumacu|
0x3f8010b0 6d 61 63 75 6d 61 63 75  6d 61 63 75 6d 61 63 75  |macumacumacumacu|
0x3f8010c0 6d 61 63 75 6d 61 63 75  6d 61 63 75 6d 61 63 75  |macumacumacumacu|
0x3f8010d0 6d 61 63 75 6d 61 63 75  6d 61 63 75 6d 61 63 75  |macumacumacumacu|
0x3f8010e0 6d 61 63 75 6d 61 63 75  6d 61 63 75 6d 61 63 75  |macumacumacumacu|
0x3f8010f0 00 00 00 00 00 00 30 00  00 00 30 00 00 00 00 00  |......0...0.....|

[root@nixos:~]# 
i can see a "ucam" repeating for an invalid register

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Sat Sep 25, 2021 6:50 pm

Code: Select all

[  197.572562] ISR: ISTA: 0x5, STA: 0x2A4000, sequence 0, lines done 0
[  197.578836] not initialized yet!?
[  197.582173] ISR: ISTA: 0x5, STA: 0x2A4000, sequence 0, lines done 0
[  197.588447] not initialized yet!?
i added a bool to the main "struct unicam_device" to stop it from doing too much until unicam_probe_complete() has been ran
i also switched unicam to a kernel module, so i can get away with copying smaller files on each iteration, making the test cycle far faster

with those 2 changes, the system deadlocks, printing the above error infinitely, because the IRQ condition isnt clearing

Code: Select all

 801 static irqreturn_t unicam_isr(int irq, void *dev)
 802 {
 803         struct unicam_device *unicam = dev;
 804         unsigned int lines_done = unicam_get_lines_done(dev);
 805         unsigned int sequence = unicam->sequence;
 806         unsigned int i;
 807         u32 ista, sta;
 808         bool fe;
 809         u64 ts;
 810 
 811         sta = reg_read(unicam, UNICAM_STA);
 812         /* Write value back to clear the interrupts */
 813         reg_write(unicam, UNICAM_STA, sta);
 814 
 815         ista = reg_read(unicam, UNICAM_ISTA);
 816         /* Write value back to clear the interrupts */
 817         reg_write(unicam, UNICAM_ISTA, ista);
 818 
 819         printk("ISR: ISTA: 0x%X, STA: 0x%X, sequence %d, lines done %d\n",
 820                    ista, sta, sequence, lines_done);
 821 
 822         if (!unicam->fully_initialized) {
 823           printk("not initialized yet!?\n");
 824           return IRQ_HANDLED;
 825         }
but line 813/817 are attempting to clear those conditions, so something does seem to be off, i'll need to dig thru the source, and try and figure out what those bits mean

edit:
and thats a bust
UNICAM_IS, UNICAM_FSI_S, UNICAM_LCI_S, UNICAM_BUF0_NO, UNICAM_FSI and UNICAM_LCI are all set

of those, the linux driver only checks for 2 of them, so i have zero clue what the other ones mean
Last edited by cleverca22 on Sat Sep 25, 2021 7:13 pm, edited 1 time in total.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 11812
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: unicam driver null pointer dereference

Sat Sep 25, 2021 7:08 pm

Interrupts aren't enabled from the block until ICTL is set at https://github.com/raspberrypi/linux/bl ... am.c#L1461
Something is very strange that the interrupts are firing at all.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Sat Sep 25, 2021 7:17 pm

Code: Select all

[ 1770.690275] initial ICTL: 0x1
from:

Code: Select all

2850         /* set the driver data in platform device */
2851         platform_set_drvdata(pdev, unicam);
2852 
2853         ret = of_unicam_connect_subdevs(unicam);
2854         if (ret) {
2855                 dev_err(&pdev->dev, "Failed to connect subdevs\n");
2856                 goto err_media_unregister;
2857         }
2858 
2859         printk("initial ICTL: 0x%x\n", reg_read(unicam, UNICAM_ICTL));
2860         goto err_media_unregister;
2861 
2862         ret = platform_get_irq(pdev, 0);
let me see what happens if i zero that out during probe...

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Sat Sep 25, 2021 7:25 pm

Code: Select all

nixos login: [   70.602878] initial ICTL: 0x1
[   70.605930] ISR: ISTA: 0x7, STA: 0x12AC000, sequence 0, lines done 0
[   70.612296] not initialized yet!?
[   70.615628] ISR: ISTA: 0x5, STA: 0x12A4000, sequence 0, lines done 0
[   70.621989] not initialized yet!?
nope, pre-zeroing ICTL (after its print) doesnt help

but i do notice, there are some interrupt conditions that where only present on the first interrupt

UNICAM_FEI and UNICAM_PI0 where set the first time, and stayed clear after the initial interruption

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 11812
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: unicam driver null pointer dereference

Sat Sep 25, 2021 7:32 pm

Hmm, datasheet says the default is 0 for ICTL.

There are interrupts controlled via DCS bit 2 (and then 0&1), DBCTL (not used), CMP0 and CMP1 bit 9, all are disabled by default.

CAMCTL bit 2 is the peripheral reset
Set to clear the receiver status, reset all state
machines and flush the pipeline. Buffer pointers
are set to the start addresses. Panic priorities
are reset back to zero. Interrupts are disabled.
FIFO statistics are reset. Apart from these, no
other control registers are affected; they remain
in their current state.
This bit should be held for a period then deasserted to ensure the pipeline is flushed
completely. It is used to recover from errors in
the data stream without resetting the entire
peripheral
CAMCTL Bit 0 is the master enable for the block.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Sat Sep 25, 2021 7:43 pm

Code: Select all

[  395.848310] R 0x100 -> 0x1
[  395.851044] initial ICTL: 0x1
[  395.854028] W 0x100 <- 0x0
[  395.856757] R 0x100 -> 0x0
[  395.859564] post-zero ICTL: 0x0
[  395.867850] R 0x4 -> 0x2ac000
[  395.870848] W 0x4 <- 0x2ac000
[  395.873819] R 0x104 -> 0x7
[  395.876529] W 0x104 <- 0x7
[  395.879238] ISR: ISTA: 0x7, STA: 0x2AC000, sequence 0, lines done 0
[  395.885512] not initialized yet!?
[  395.888848] R 0x4 -> 0x2a4000
[  395.891821] W 0x4 <- 0x2a4000
[  395.894791] R 0x104 -> 0x5
[  395.897500] W 0x104 <- 0x5
[  395.900208] ISR: ISTA: 0x5, STA: 0x2A4000, sequence 0, lines done 0
[  395.906480] not initialized yet!?
[  395.909813] R 0x4 -> 0x2a4000
[  395.912785] W 0x4 <- 0x2a4000
[  395.915754] R 0x104 -> 0x5
[  395.918463] W 0x104 <- 0x5
[  395.921172] ISR: ISTA: 0x5, STA: 0x2A4000, sequence 0, lines done 0
[  395.927443] not initialized yet!?
[  395.930772] R 0x4 -> 0x2a4000
[  395.933744] W 0x4 <- 0x2a4000
[  395.936714] R 0x104 -> 0x5
[  395.939423] W 0x104 <- 0x5
[  395.942131] ISR: ISTA: 0x5, STA: 0x2A4000, sequence 0, lines done 0
[  395.948403] not initialized yet!?
[  395.951736] R 0x4 -> 0x2a4000
[  395.954709] W 0x4 <- 0x2a4000
[  395.957679] R 0x104 -> 0x5
[  395.960388] W 0x104 <- 0x5
i modified reg_read and reg_write to just print every single IO action done against the hw
6by9 wrote:
Sat Sep 25, 2021 7:32 pm
Hmm, datasheet says the default is 0 for ICTL.

Code: Select all

[clever@amd-nixos:~/apps/rpi/rpi-open-firmware/common]$ git grep CAM1_ICTL
broadcom/bcm2708_chip/cam1_a0.h:#define CAM1_ICTL                                                HW_REGISTER_RW( 0x7e801100 ) 
broadcom/bcm2708_chip/cam1_a0.h:   #define CAM1_ICTL_MASK                                        0xffffffff
broadcom/bcm2708_chip/cam1_a0.h:   #define CAM1_ICTL_WIDTH                                       32
broadcom/bcm2708_chip/cam1_a0.h:   #define CAM1_ICTL_RESET                                       0000000000

[clever@amd-nixos:~/apps/rpi/rpi-open-firmware/common]$ git grep CAM1_CAMICTL
broadcom/bcm2708_chip/cam1.h:#define CAM1_CAMICTL                                             HW_REGISTER_RW( 0x7e801100 ) 
broadcom/bcm2708_chip/cam1.h:   #define CAM1_CAMICTL_MASK                                     0xffffffff
broadcom/bcm2708_chip/cam1.h:   #define CAM1_CAMICTL_WIDTH                                    32
broadcom/bcm2708_chip/cam1.h:   #define CAM1_CAMICTL_RESET                                    0000000000
the broadcom headers agree with you

Code: Select all

printf("CAM1_ICTL: 0x%x\n", *REG32(0x7e801100));
Fatal VPU Exception: Dummy
VPU registers:
     r0: 0xc400d30c  r1: 0xdeadbeef  r2: 0x7e801100  r3: 0xc4012168
     r4: 0xc400a736  r5: 0xa0000000  r6: 0x00000000  r7: 0x00000000
     r8: 0x00000000  r9: 0x00000000 r10: 0xc4001198 r11: 0x00000000
    r12: 0x00000000 r13: 0x00000000 r14: 0x00000000 r15: 0x00000000
     pc: 0xc400897c  lr: 0xc40004c8  sr: 0x20000008
Exception info (IC0):
   src0: 0x00000001 src1: 0x02000000 vaddr: 0x02000000
      C: 0x00000000    S: 0x00000000
Exception info (IC1):
   src0: 0x00000001 src1: 0x02000000 vaddr: 0x02000000
      C: 0x00000000    S: 0x00000000
We are hanging here ...
and there is definitely some power-domain stuff going on
if i try to read it too early (before VEC is enabled), i get an exception

Code: Select all

arm starting...
CAM1_ICTL: 0x1
but if i read it later on, after the VEC is functional and the ARM is being started up, i can see a 1 in there!!

either the datasheets are wrong about the reset value, or the maybe i missed a memory-repair step in the power-domain bringup?

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Sat Sep 25, 2021 7:51 pm

Code: Select all

[  441.947976] R 0x100 -> 0x1   UNICAM_ICTL
[  441.950713] initial ICTL: 0x1
[  441.953690] R 0x200 -> 0x104 UNICAM_DCS
[  441.956594] R 0x300 -> 0x0   UNICAM_DBCTL
[  441.959400] R 0x2c -> 0x0    UNICAM_CMP0
[  441.962040] R 0x30 -> 0x100  UNICAM_CMP1
[  441.964861] W 0x100 <- 0x0   UNICAM_ICTL
[  441.967617] W 0x200 <- 0x0   UNICAM_DCS
[  441.970339] W 0x300 <- 0x0   UNICAM_DBCTL
[  441.973065] R 0x100 -> 0x0   UNICAM_ICTL
[  441.975791] post-zero ICTL: 0x0
[  441.989641] R 0x4 -> 0x12ac000
[  441.992730] W 0x4 <- 0x12ac000
[  441.995789] R 0x104 -> 0x7
[  441.998499] W 0x104 <- 0x7
printing out all of the interrupt related regs you just mentioned

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Sat Sep 25, 2021 7:57 pm

6by9 wrote:
Sat Sep 25, 2021 7:32 pm
CAMCTL bit 2 is the peripheral reset
CAMCTL Bit 0 is the master enable for the block.
based on that, i dug around a bit in the linux driver, and found that unicam_disable() both does a full reset, and disables the peripheral
it is already called from unicam_stop_streaming(), which implies that the unicam is "disabled" when idle

so i tossed an extra call to disable inside probe, and that has solved all of the crashing problems!

now to see if i can actually capture anything...

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Sat Sep 25, 2021 8:25 pm

Code: Select all

[root@nixos:~]# yavta --capture=10 /dev/video0
Device /dev/video0 opened.
Device `unicam' on `platform:3f801000.csi' (driver 'unicam') supports video, capture, without mplanes.
Video format: SBGGR10P (41414270) 640x480 (stride 800) field none buffer size 384000
8 buffers requested.
length: 384000 offset: 0 timestamp type/source: mono/EoF
Buffer 0/0 mapped at address 0xb6dea000.
length: 384000 offset: 385024 timestamp type/source: mono/EoF
Buffer 1/0 mapped at address 0xb6d8c000.
length: 384000 offset: 770048 timestamp type/source: mono/EoF
Buffer 2/0 mapped at address 0xb6d2e000.
length: 384000 offset: 1155072 timestamp type/source: mono/EoF
Buffer 3/0 mapped at address 0xb6cd0000.
length: 384000 offset: 1540096 timestamp type/source: mono/EoF
Buffer 4/0 mapped at address 0xb6c72000.
length: 384000 offset: 1925120 timestamp type/source: mono/EoF
Buffer 5/0 mapped at address 0xb6c14000.
length: 384000 offset: 2310144 timestamp type/source: mono/EoF
Buffer 6/0 mapped at address 0xb6bb6000.
length: 384000 offset: 2695168 timestamp type/source: mono/EoF
Buffer 7/0 mapped at address 0xb6b58000.

^C^C
and also

Code: Select all

[ 1382.173227] unicam 3f801000.csi: __subdev_get_format 640x480 code:3007
[ 1382.204438] unicam 3f801000.csi: Running with 2 data lanes
[ 1382.204728] W 0x0 <- 0x2
[ 1382.207292] W 0x8 <- 0x774
[ 1382.212539] R 0x8 -> 0x774
[ 1382.215401] W 0x8 <- 0x770
[ 1382.218147] R 0x0 -> 0x2
[ 1382.220710] W 0x0 <- 0x6
[ 1382.223257] R 0x0 -> 0x6
[ 1382.225848] W 0x0 <- 0x2
[ 1382.228402] R 0x0 -> 0x2
[ 1382.230948] W 0x0 <- 0x2
[ 1382.233507] R 0x0 -> 0x2
[ 1382.236093] W 0x0 <- 0x80f02
[ 1382.238989] W 0x120 <- 0x0
[ 1382.241721] W 0x128 <- 0x0
[ 1382.244475] R 0xc -> 0x0
[ 1382.247025] W 0xc <- 0xe85
[ 1382.249752] R 0x8 -> 0x770
[ 1382.252477] W 0x8 <- 0x770
[ 1382.255225] W 0x100 <- 0x80000f
[ 1382.258389] W 0x4 <- 0x1b6fc
[ 1382.261288] W 0x104 <- 0x7
[ 1382.264042] R 0x14 -> 0x0
[ 1382.266683] W 0x14 <- 0x2
[ 1382.269316] R 0x14 -> 0x2
[ 1382.271965] W 0x14 <- 0x602
[ 1382.274807] R 0x28 -> 0x0
[ 1382.277443] W 0x28 <- 0x2
[ 1382.280088] R 0x28 -> 0x2
[ 1382.282726] W 0x28 <- 0x602
[ 1382.285560] R 0x28 -> 0x602
[ 1382.288376] W 0x28 <- 0x602
[ 1382.291190] R 0x0 -> 0x80f02
[ 1382.294110] W 0x0 <- 0x80f02
[ 1382.297014] W 0x2c <- 0x80000301
[ 1382.300261] W 0x10 <- 0x1d
[ 1382.302982] W 0x18 <- 0x1d
[ 1382.305735] W 0x1c <- 0x1d
[ 1382.308468] W 0x118 <- 0x320
[ 1382.311362] W 0x110 <- 0xde080000
[ 1382.314723] W 0x114 <- 0xde0ddc00
[ 1382.318060] W 0x10c <- 0x0
[ 1382.320787] W 0x108 <- 0x2b
[ 1382.323598] R 0x400 -> 0x0
[ 1382.326350] W 0x400 <- 0x240
[ 1382.329254] R 0x0 -> 0x80f02
[ 1382.332153] W 0x0 <- 0x80f03
[ 1382.335074] R 0x100 -> 0x80000f
[ 1382.338246] W 0x100 <- 0x80002f
[ 1382.341406] R 0x100 -> 0x80000f
[ 1382.344594] W 0x100 <- 0x80001f
ctrl+c happened here
[ 1401.758069] R 0x8 -> 0x770
[ 1401.760852] W 0x8 <- 0x778
[ 1401.763652] R 0x0 -> 0x80f03
[ 1401.766552] W 0x0 <- 0x80f13
[ 1401.769460] W 0x18 <- 0x0
[ 1401.772101] W 0x1c <- 0x0
[ 1401.774762] R 0x0 -> 0x80f13
[ 1401.777666] W 0x0 <- 0x80f17
[ 1401.809943] R 0x0 -> 0x80f17
[ 1401.813022] W 0x0 <- 0x80f13
[ 1401.815994] R 0x0 -> 0x80f13
[ 1401.818901] W 0x0 <- 0x80f12
[ 1401.821794] W 0x200 <- 0x0
[ 1401.824559] 8<--- cut here ---
[ 1401.827633] Unable to handle kernel paging request at virtual address fffffff8
[ 1401.834905] pgd = e5925547
[ 1401.837643] [fffffff8] *pgd=1dfee861, *pte=00000000, *ppte=00000000
[ 1401.844003] Internal error: Oops: 37 [#1] ARM
[ 1401.848375] Modules linked in: bcm2835_unicam videobuf2_dma_contig videobuf2_memops videobuf2_v4l2 videobuf2_common
[ 1401.858863] CPU: 0 PID: 834 Comm: yavta Tainted: G        W         5.14.2+ #2
[ 1401.866098] Hardware name: BCM2835
[ 1401.869502] PC is at clk_request_done+0x1c/0xa4
[ 1401.874059] LR is at unicam_stop_streaming+0x64/0x118 [bcm2835_unicam]
[ 1401.880651] pc : [<c0480dec>]    lr : [<bf029894>]    psr: a0030013
[ 1401.886922] sp : cff65d70  ip : cff65d90  fp : cff65d8c
[ 1401.892151] r10: 00000036  r9 : 00000000  r8 : 00000001
[ 1401.897379] r7 : c79444dc  r6 : 00000000  r5 : c7944278  r4 : fffffff0
[ 1401.903913] r3 : 00000001  r2 : 5a000000  r1 : e0843200  r0 : fffffff0
[ 1401.910446] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[ 1401.917592] Control: 10c53c7d  Table: 03a4c059  DAC: 00000051
[ 1401.923338] Register r0 information: non-paged memory
[ 1401.928402] Register r1 information: 0-page vmalloc region starting at 0xe0843000 allocated at __devm_ioremap+0x70/0xb4
[ 1401.939218] Register r2 information: non-paged memory
[ 1401.944279] Register r3 information: non-paged memory
[ 1401.949339] Register r4 information: non-paged memory
[ 1401.954399] Register r5 information: slab kmalloc-4k start c7944000 pointer offset 632 size 4096
[ 1401.963230] Register r6 information: NULL pointer
[ 1401.967943] Register r7 information: slab kmalloc-4k start c7944000 pointer offset 1244 size 4096
[ 1401.976856] Register r8 information: non-paged memory
[ 1401.981916] Register r9 information: NULL pointer
[ 1401.986629] Register r10 information: non-paged memory
[ 1401.991777] Register r11 information: non-slab/vmalloc memory
[ 1401.997533] Register r12 information: non-slab/vmalloc memory
[ 1402.003288] Process yavta (pid: 834, stack limit = 0x8641e445)
[ 1402.009130] Stack: (0xcff65d70 to 0xcff66000)
[ 1402.013501] 5d60:                                     c7944000 c7944278 00000000 c79444dc
[ 1402.021692] 5d80: cff65dac cff65d90 bf029894 c0480ddc c7944390 c79443f0 c79444e8 c79444dc
[ 1402.029884] 5da0: cff65dd4 cff65db0 bf001564 bf02983c c7944390 c79443f0 c79444e8 c79444dc
[ 1402.038075] 5dc0: 00000001 00000000 cff65dec cff65dd8 bf003b8c bf001538 00000000 cfd93000
[ 1402.046266] 5de0: cff65e0c cff65df0 bf0107d0 bf003b70 c7944278 c16bd840 cfd93000 c79444dc
[ 1402.054457] 5e00: cff65e34 cff65e10 bf0281f4 bf010790 bf0281a8 c79444e8 cfd93000 c17730d0
[ 1402.062648] 5e20: ca9dadd0 00000000 cff65e54 cff65e38 c060dd04 bf0281b4 cfd93000 cfd89990
[ 1402.070840] 5e40: 000e001f c17730d0 cff65e8c cff65e58 c025bba8 c060dc4c ffffe000 cff89d80
[ 1402.079031] 5e60: 00000000 c0f04248 c0279940 cfdf0a80 c240a4c0 cfd93000 c1096c10 cfd5af40
[ 1402.087222] 5e80: cff65e9c cff65e90 c025bd54 c025bab8 cff65ebc cff65ea0 c0138658 c025bd48
[ 1402.095413] 5ea0: c240a4c0 cfe9d1c0 cff64000 ffffe000 cff65ee4 cff65ec0 c011f7ec c01385e4
[ 1402.103604] 5ec0: c0127b48 c0127afc cff65ee4 c0f04248 c0128dd4 cfd9cf00 cff65efc cff65ee8
[ 1402.111795] 5ee0: c0120834 c011f388 00000009 ffffe000 cff65f34 cff65f00 c012c548 c01207dc
[ 1402.119987] 5f00: c026c040 c060d804 cff65fa4 cff65fb0 00000001 fffffe00 b6f3da68 b6f3da6c
[ 1402.128177] 5f20: 5ac3c35a 00000036 cff65fac cff65f38 c010ac70 c012c32c c7b016c0 00000000
[ 1402.136368] 5f40: cff65f64 c7b016c0 cff65f94 00000000 c025ac40 00000017 00000009 cff65fb0
[ 1402.144560] 5f60: c0f092c0 10c53c7d bea65010 00028f18 cff65fac c0f04248 c0112274 c0f04248
[ 1402.152749] 5f80: 00000001 00000003 00000001 be9a3fb0 00000036 c0100264 cff64000 00000036
[ 1402.160940] 5fa0: 00000000 cff65fb0 c01000d0 c010ab7c 00000003 c0445611 be9a3f6c 00000008
[ 1402.169129] 5fc0: 00000003 00000001 be9a3fb0 00000036 0005dc00 00000000 be9a3f6c be9a3fb0
[ 1402.177320] 5fe0: 00028f5c be9a3e5c 00012758 b6f3da68 80070010 00000003 00000000 00000000
[ 1402.185497] Backtrace:
[ 1402.187953] [<c0480dd0>] (clk_request_done) from [<bf029894>] (unicam_stop_streaming+0x64/0x118 [bcm2835_unicam])
[ 1402.198296]  r7:c79444dc r6:00000000 r5:c7944278 r4:c7944000
[ 1402.203956] [<bf029830>] (unicam_stop_streaming [bcm2835_unicam]) from [<bf001564>] (__vb2_queue_cancel+0x38/0x204 [videobuf2_common])
[ 1402.216211]  r7:c79444dc r6:c79444e8 r5:c79443f0 r4:c7944390
[ 1402.221871] [<bf00152c>] (__vb2_queue_cancel [videobuf2_common]) from [<bf003b8c>] (vb2_core_queue_release+0x28/0x48 [videobuf2_common])
[ 1402.234314]  r9:00000000 r8:00000001 r7:c79444dc r6:c79444e8 r5:c79443f0 r4:c7944390
[ 1402.242057] [<bf003b64>] (vb2_core_queue_release [videobuf2_common]) from [<bf0107d0>] (_vb2_fop_release+0x4c/0x74 [videobuf2_v4l2])
[ 1402.254128]  r5:cfd93000 r4:00000000
[ 1402.257704] [<bf010784>] (_vb2_fop_release [videobuf2_v4l2]) from [<bf0281f4>] (unicam_v4l2_release+0x4c/0xd8 [bcm2835_unicam])
[ 1402.269297]  r7:c79444dc r6:cfd93000 r5:c16bd840 r4:c7944278
[ 1402.274957] [<bf0281a8>] (unicam_v4l2_release [bcm2835_unicam]) from [<c060dd04>] (v4l2_release+0xc4/0xd4)
[ 1402.284695]  r9:00000000 r8:ca9dadd0 r7:c17730d0 r6:cfd93000 r5:c79444e8 r4:bf0281a8
[ 1402.292438] [<c060dc40>] (v4l2_release) from [<c025bba8>] (__fput+0xfc/0x224)
[ 1402.299617]  r7:c17730d0 r6:000e001f r5:cfd89990 r4:cfd93000
[ 1402.305276] [<c025baac>] (__fput) from [<c025bd54>] (____fput+0x18/0x1c)
[ 1402.312017]  r8:cfd5af40 r7:c1096c10 r6:cfd93000 r5:c240a4c0 r4:cfdf0a80
[ 1402.318718] [<c025bd3c>] (____fput) from [<c0138658>] (task_work_run+0x80/0x94)
[ 1402.326057] [<c01385d8>] (task_work_run) from [<c011f7ec>] (do_exit+0x470/0x930)
[ 1402.333492]  r7:ffffe000 r6:cff64000 r5:cfe9d1c0 r4:c240a4c0
[ 1402.339151] [<c011f37c>] (do_exit) from [<c0120834>] (do_group_exit+0x64/0xb8)
[ 1402.346400]  r7:cfd9cf00
[ 1402.348934] [<c01207d0>] (do_group_exit) from [<c012c548>] (get_signal+0x228/0x6c4)
[ 1402.356623]  r5:ffffe000 r4:00000009
[ 1402.360200] [<c012c320>] (get_signal) from [<c010ac70>] (do_work_pending+0x100/0x460)
[ 1402.368073]  r10:00000036 r9:5ac3c35a r8:b6f3da6c r7:b6f3da68 r6:fffffe00 r5:00000001
[ 1402.375904]  r4:cff65fb0
[ 1402.378439] [<c010ab70>] (do_work_pending) from [<c01000d0>] (slow_work_pending+0xc/0x20)
[ 1402.386642] Exception stack(0xcff65fb0 to 0xcff65ff8)
[ 1402.391705] 5fa0:                                     00000003 c0445611 be9a3f6c 00000008
[ 1402.399896] 5fc0: 00000003 00000001 be9a3fb0 00000036 0005dc00 00000000 be9a3f6c be9a3fb0
[ 1402.408084] 5fe0: 00028f5c be9a3e5c 00012758 b6f3da68 80070010 00000003
[ 1402.414715]  r10:00000036 r9:cff64000 r8:c0100264 r7:00000036 r6:be9a3fb0 r5:00000001
[ 1402.422547]  r4:00000003
[ 1402.425094] Code: e52de004 e8bd4000 e2504000 089da8f0 (e5943008)
[ 1402.431375] ---[ end trace ced7e82d74e916e6 ]---
[ 1402.436130] Fixing recursive fault but reboot is needed!
i suspect the problem now is due to the analog power domain not being wired up in device-tree
i'll investigate that more, and figure out which power node it was meant to be wired up to, and report back later

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Sun Sep 26, 2021 1:34 pm

Code: Select all

@@ -1697,7 +1710,7 @@ static int unicam_start_streaming(struct vb2_queue *vq, unsigned int count)
                   dev->active_data_lanes);
 
        dev->vpu_req = clk_request_start(dev->vpu_clock, MIN_VPU_CLOCK_RATE);
-       if (!dev->vpu_req) {
+       if (IS_ERR(dev->vpu_req)) {
                unicam_err(dev, "failed to set up VPU clock\n");
                goto err_pm_put;
        }
this bug, caused it to silently ignore the failure to bump up the VPU rate
then at shutdown, it passed an invalid pointer to clk_request_done() and crashed hard

now i need to dig into the clock management code, to solve that issue
and yes, i will be filing a PR for all of these changes when i'm done

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Sun Sep 26, 2021 4:06 pm

after more poking around, i got it into a state where yavta can start/stop without any errors, but it does not actually get any buffers
i then looked into the missing power domain, found that linux had zero support for it and always uses mailbox properties to turn it on

further digging, and i found PM_CAM1

Code: Select all

#define PM_CAM1 0x7e100048
static void cam1_enable(void) {
  uint32_t t = *REG32(PM_CAM1);
  *REG32(PM_CAM1) = t | PM_PASSWORD | 0x1;
  t = *REG32(PM_CAM1);
  *REG32(PM_CAM1) = t | PM_PASSWORD | 0x4;
}
at the expense of idle power usage, i just flipped it on during boot (can improve later)
yavta can now capture complete buffers!

Code: Select all

[root@nixos:~]# yavta --capture=1 /dev/video0 -s 640x480 --file=rawcapture
Device /dev/video0 opened.
Device `unicam' on `platform:3f801000.csi' (driver 'unicam') supports video, capture, without mplanes.
Video format set: SBGGR10P (41414270) 640x480 (stride 800) field none buffer size 384000
Video format: SBGGR10P (41414270) 640x480 (stride 800) field none buffer size 384000
8 buffers requested.
length: 384000 offset: 0 timestamp type/source: mono/EoF
Buffer 0/0 mapped at address 0xb6dbf000.
length: 384000 offset: 385024 timestamp type/source: mono/EoF
Buffer 1/0 mapped at address 0xb6d61000.
length: 384000 offset: 770048 timestamp type/source: mono/EoF
Buffer 2/0 mapped at address 0xb6d03000.
length: 384000 offset: 1155072 timestamp type/source: mono/EoF
Buffer 3/0 mapped at address 0xb6ca5000.
length: 384000 offset: 1540096 timestamp type/source: mono/EoF
Buffer 4/0 mapped at address 0xb6c47000.
length: 384000 offset: 1925120 timestamp type/source: mono/EoF
Buffer 5/0 mapped at address 0xb6be9000.
length: 384000 offset: 2310144 timestamp type/source: mono/EoF
Buffer 6/0 mapped at address 0xb6b8b000.
length: 384000 offset: 2695168 timestamp type/source: mono/EoF
Buffer 7/0 mapped at address 0xb6b2d000.
0 (0) [-] none 0 384000 B 449.791258 449.886753 -62.484 fps ts mono/EoF
Captured 1 frames in 0.079490 seconds (12.580108 fps, 4830761.565032 B/s).
8 buffers released.

[root@nixos:~]# hexdump -C rawcapture 
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00407400
but the image data captured, is 100% nulls

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Sun Sep 26, 2021 4:34 pm

is "lines done 0" normal?

Code: Select all

[  294.851457] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  294.851487] ISR: ISTA: 0x0, STA: 0xD0BF, sequence 202, lines done 0
[  294.857779] ISR: ISTA: 0x0, STA: 0xD03C, sequence 203, lines done 0
[  294.864537] ISR: ISTA: 0x0, STA: 0xD03E, sequence 204, lines done 0
[  294.870841] ISR: ISTA: 0x0, STA: 0xD0BC, sequence 205, lines done 0
[  294.877133] ISR: ISTA: 0x1, STA: 0xD03E, sequence 206, lines done 0
[  294.883408] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  294.883441] ISR: ISTA: 0x0, STA: 0xD0BC, sequence 207, lines done 0
[  294.889737] ISR: ISTA: 0x0, STA: 0xD03E, sequence 208, lines done 0
[  294.902001] ISR: ISTA: 0x1, STA: 0x503C, sequence 209, lines done 0
[  294.908288] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  294.908603] ISR: ISTA: 0x1, STA: 0x503E, sequence 209, lines done 0
[  294.914881] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  294.914915] ISR: ISTA: 0x0, STA: 0xD03C, sequence 209, lines done 0
[  294.921210] ISR: ISTA: 0x0, STA: 0xD03E, sequence 210, lines done 0
[  294.927500] ISR: ISTA: 0x1, STA: 0xD03C, sequence 211, lines done 0
[  294.933775] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  294.943022] ISR: ISTA: 0x0, STA: 0xD03E, sequence 212, lines done 0
[  294.949317] ISR: ISTA: 0x0, STA: 0xD03C, sequence 213, lines done 0
[  294.960357] ISR: ISTA: 0x0, STA: 0xD03E, sequence 214, lines done 0
[  294.970388] ISR: ISTA: 0x0, STA: 0xD0BC, sequence 215, lines done 0
[  294.976702] ISR: ISTA: 0x0, STA: 0xD03E, sequence 216, lines done 0
[  294.982997] ISR: ISTA: 0x1, STA: 0xD03C, sequence 217, lines done 0
[  294.989273] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  294.989308] ISR: ISTA: 0x0, STA: 0xD0BE, sequence 218, lines done 0
[  294.995598] ISR: ISTA: 0x1, STA: 0xD03C, sequence 219, lines done 0
[  295.001872] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  295.001904] ISR: ISTA: 0x0, STA: 0xD03E, sequence 220, lines done 0
[  295.008192] ISR: ISTA: 0x1, STA: 0x503C, sequence 221, lines done 0
[  295.014467] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  295.014500] ISR: ISTA: 0x1, STA: 0xD0BE, sequence 221, lines done 0
[  295.020775] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  295.021823] ISR: ISTA: 0x0, STA: 0xD03C, sequence 222, lines done 0
[  295.028121] ISR: ISTA: 0x0, STA: 0xD03E, sequence 223, lines done 0
[  295.034416] ISR: ISTA: 0x0, STA: 0xD0BC, sequence 224, lines done 0
[  295.040726] ISR: ISTA: 0x1, STA: 0xD0BE, sequence 225, lines done 0
[  295.047003] unicam 3f801000.csi: Scheduling dummy buffer for node 0
...
[  296.976634] ISR: ISTA: 0x1, STA: 0x503C, sequence 451, lines done 0
[  296.976652] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  296.982974] ISR: ISTA: 0x1, STA: 0x50BE, sequence 451, lines done 0
[  296.982993] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  296.989308] ISR: ISTA: 0x1, STA: 0xD03C, sequence 451, lines done 0
[  296.989327] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  296.995624] ISR: ISTA: 0x0, STA: 0xD0BE, sequence 452, lines done 0
[  297.001972] unicam_stop_streaming(0x6236aa84)
[  297.007891] ISR: ISTA: 0x0, STA: 0xD03C, sequence 453, lines done 0
[  297.014202] ISR: ISTA: 0x0, STA: 0xD0BE, sequence 454, lines done 0
[  297.020495] ISR: ISTA: 0x1, STA: 0xD03C, sequence 455, lines done 0
[  297.026789] ISR: ISTA: 0x0, STA: 0xD03E, sequence 456, lines done 0
[  297.033089] ISR: ISTA: 0x1, STA: 0x503C, sequence 457, lines done 0
[  297.039982] ISR: ISTA: 0x0, STA: 0xD03E, sequence 457, lines done 0
[  297.046294] ISR: ISTA: 0x0, STA: 0xD0BC, sequence 458, lines done 0
[  297.052592] ISR: ISTA: 0x0, STA: 0xD03E, sequence 459, lines done 0
[  297.058883] ISR: ISTA: 0x1, STA: 0xD0BC, sequence 460, lines done 0
[  297.065175] ISR: ISTA: 0x0, STA: 0xD03E, sequence 461, lines done 0
[  297.083282] unicam_disable()
[  297.091609] ------------[ cut here ]------------
[  297.096267] WARNING: CPU: 0 PID: 798 at drivers/media/common/videobuf2/videobuf2-core.c:1956 __vb2_queue_cancel+0x5c/0x204 [videobuf2_common]
[  297.109175] Modules linked in: bcm2835_unicam videobuf2_dma_contig videobuf2_memops videobuf2_v4l2 videobuf2_common
[  297.119737] CPU: 0 PID: 798 Comm: yavta Tainted: G        W         5.14.2+ #3
[  297.126994] Hardware name: BCM2835
[  297.130443] Backtrace: 
[  297.132927] [<c08fcc7c>] (dump_backtrace) from [<c08fcf18>] (show_stack+0x20/0x24)
[  297.140600]  r7:00000000 r6:00000000 r5:00000009 r4:c0cde6a0
[  297.146277] [<c08fcef8>] (show_stack) from [<c08ff760>] (dump_stack+0x28/0x30)
[  297.153572] [<c08ff738>] (dump_stack) from [<c011da78>] (__warn+0xcc/0xf8)
[  297.160543]  r5:00000009 r4:bf006fad
[  297.164139] [<c011d9ac>] (__warn) from [<c08fd5f0>] (warn_slowpath_fmt+0x88/0xc8)
[  297.171728]  r9:00000000 r8:00000000 r7:00000009 r6:bf001588 r5:000007a4 r4:bf006fad
[  297.179514] [<c08fd56c>] (warn_slowpath_fmt) from [<bf001588>] (__vb2_queue_cancel+0x5c/0x204 [videobuf2_common])
[  297.189970]  r8:00000001 r7:c37cb404 r6:c37cb4e8 r5:c37cb3f0 r4:c37cb390
[  297.196690] [<bf00152c>] (__vb2_queue_cancel [videobuf2_common]) from [<bf003b8c>] (vb2_core_queue_release+0x28/0x48 [videobuf2_common])
[  297.209198]  r9:00000000 r8:00000001 r7:c37cb4dc r6:c37cb4e8 r5:c37cb3f0 r4:c37cb390
[  297.216999] [<bf003b64>] (vb2_core_queue_release [videobuf2_common]) from [<bf011f58>] (vb2_queue_release+0x2c/0x34 [videobuf2_v4l2])
[  297.229224]  r5:cfa4d540 r4:c37cb390
[  297.232846] [<bf011f2c>] (vb2_queue_release [videobuf2_v4l2]) from [<bf0107b4>] (_vb2_fop_release+0x4c/0x74 [videobuf2_v4l2])
[  297.244338]  r5:cfa4d540 r4:00000000
[  297.247931] [<bf010768>] (_vb2_fop_release [videobuf2_v4l2]) from [<bf02852c>] (unicam_v4l2_release+0x58/0xe8 [bcm2835_unicam])
[  297.259609]  r7:c37cb4dc r6:c16bd840 r5:cfa4d540 r4:c37cb278
[  297.265287] [<bf0284d4>] (unicam_v4l2_release [bcm2835_unicam]) from [<c060dd24>] (v4l2_release+0xc4/0xd4)
[  297.275098]  r9:00000000 r8:cb1aa5d8 r7:c17730d0 r6:cfa4d540 r5:c37cb4e8 r4:bf0284d4
[  297.282886] [<c060dc60>] (v4l2_release) from [<c025bba8>] (__fput+0xfc/0x224)
[  297.290111]  r7:c17730d0 r6:000e001f r5:cfb9ccb0 r4:cfa4d540
[  297.295790] [<c025baac>] (__fput) from [<c025bd54>] (____fput+0x18/0x1c)
[  297.302607]  r8:cfbb0540 r7:c1096c10 r6:cfa4d540 r5:cfa1ea00 r4:c93c79c0
[  297.309355] [<c025bd3c>] (____fput) from [<c0138658>] (task_work_run+0x80/0x94)
[  297.316717] [<c01385d8>] (task_work_run) from [<c011f7ec>] (do_exit+0x470/0x930)
[  297.324230]  r7:ffffe000 r6:c935a000 r5:cfb4d380 r4:cfa1ea00
[  297.329937] [<c011f37c>] (do_exit) from [<c0120834>] (do_group_exit+0x64/0xb8)
[  297.337222]  r7:cfa4e280
[  297.339798] [<c01207d0>] (do_group_exit) from [<c012c548>] (get_signal+0x228/0x6c4)
[  297.347521]  r5:ffffe000 r4:00000009
[  297.351142] [<c012c320>] (get_signal) from [<c010ac70>] (do_work_pending+0x100/0x460)
[  297.359038]  r10:00000036 r9:5ac3c35a r8:b6f20a6c r7:b6f20a68 r6:fffffe00 r5:00000001
[  297.366920]  r4:c935bfb0
[  297.369493] [<c010ab70>] (do_work_pending) from [<c01000d0>] (slow_work_pending+0xc/0x20)
[  297.377717] Exception stack(0xc935bfb0 to 0xc935bff8)
[  297.382840] bfa0:                                     00000003 c0445611 bedd6f2c 00000008
[  297.391074] bfc0: 00000003 00000001 00017ba0 00000036 00000008 00000006 bedd6f2c bedd6f70
[  297.399314] bfe0: 00028f5c bedd6e1c 00012758 b6f20a68 80070010 00000003
[  297.405980]  r10:00000036 r9:c935a000 r8:c0100264 r7:00000036 r6:00017ba0 r5:00000001
[  297.413861]  r4:00000003
[  297.416413] ---[ end trace fbfdb1da93cd296c ]---
[  297.421071] videobuf2_common: driver bug: stop_streaming operation is leaving buf 82ccc8bd in active state
[  297.430785] videobuf2_common: driver bug: stop_streaming operation is leaving buf cec9e90b in active state
[  297.440491] videobuf2_common: driver bug: stop_streaming operation is leaving buf 83100b87 in active state
[  297.450194] videobuf2_common: driver bug: stop_streaming operation is leaving buf 6d43b13c in active state

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Mon Sep 27, 2021 6:55 am

Code: Select all

pi@pi2:~/yavta $ ./yavta --capture=1 /dev/video0 -s 640x480 --file=rawcapture --skip=30 --set-control='0x00980912 1'
Device /dev/video0 opened.
Device `unicam' on `platform:3f801000.csi' (driver 'unicam') supports video, capture, without mplanes.
Control 0x00980912 set to 1, is 1
Video format set: SBGGR10P (41414270) 640x480 (stride 800) field none buffer size 384000
Video format: SBGGR10P (41414270) 640x480 (stride 800) field none buffer size 384000
8 buffers requested.
length: 384000 offset: 0 timestamp type/source: mono/EoF
Buffer 0/0 mapped at address 0x76cd3000.
length: 384000 offset: 385024 timestamp type/source: mono/EoF
Buffer 1/0 mapped at address 0x76c75000.
length: 384000 offset: 770048 timestamp type/source: mono/EoF
Buffer 2/0 mapped at address 0x76c17000.
length: 384000 offset: 1155072 timestamp type/source: mono/EoF
Buffer 3/0 mapped at address 0x76bb9000.
length: 384000 offset: 1540096 timestamp type/source: mono/EoF
Buffer 4/0 mapped at address 0x76b5b000.
length: 384000 offset: 1925120 timestamp type/source: mono/EoF
Buffer 5/0 mapped at address 0x76afd000.
length: 384000 offset: 2310144 timestamp type/source: mono/EoF
Buffer 6/0 mapped at address 0x76a9f000.
length: 384000 offset: 2695168 timestamp type/source: mono/EoF
Buffer 7/0 mapped at address 0x76a41000.
0 (0) [-] none 0 384000 B 36.955354 36.970738 -150.286 fps ts mono/EoF
Captured 1 frames in 0.008729 seconds (114.557786 fps, 43990189.729459 B/s).
8 buffers released.
pi@pi2:~/yavta $ ls -ltrh
total 560K
-rw-r--r-- 1 pi pi 375K Sep 27 03:39 rawcapture
pi@pi2:~/yavta $ dmesg
[   36.904730] unicam 3f801000.csi: unicam_calc_format_size_bpl: fourcc: 41414270 size: 640x480 bpl:800 img_size:384000
[   36.906926] unicam 3f801000.csi: __subdev_set_format 640x480 code:3007
[   36.906954] unicam 3f801000.csi: __subdev_get_format 640x480 code:3007
[   36.906978] unicam 3f801000.csi: unicam_calc_format_size_bpl: fourcc: 41414270 size: 640x480 bpl:800 img_size:384000
[   36.906998] unicam 3f801000.csi: unicam_s_fmt_vid_cap 640x480, mbus_fmt 0x00003007, V4L2 pix 0x41414270.
[   36.907122] unicam 3f801000.csi: __subdev_get_format 640x480 code:3007
[   36.922699] unicam 3f801000.csi: Running with 2 data lanes
[   36.927250] unicam 3f801000.csi: ISR: ISTA: 0x1, STA: 0x4006, sequence 0, lines done 0
[   36.927264] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[   36.964447] unicam 3f801000.csi: ISR: ISTA: 0x1, STA: 0x4010, sequence 0, lines done 1310
[   36.964463] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[   36.968589] unicam 3f801000.csi: ISR: ISTA: 0x4, STA: 0x4003, sequence 0, lines done 1439
[   36.972662] unicam 3f801000.csi: ISR: ISTA: 0x4, STA: 0x4001, sequence 0, lines done 1567
[   36.976716] unicam 3f801000.csi: ISR: ISTA: 0x4, STA: 0x4003, sequence 0, lines done 1695
[   36.979759] unicam 3f801000.csi: ISR: ISTA: 0x0, STA: 0xC000, sequence 0, lines done 1790
[   36.982103] ------------[ cut here ]------------
[   36.982200] WARNING: CPU: 3 PID: 1053 at drivers/media/common/videobuf2/videobuf2-core.c:1945 __vb2_queue_cancel+0x1e0/0x258 [videobuf2_common]
[   36.982214] Modules linked in: fuse sha256_generic cfg80211 rfkill 8021q garp stp llc ov5647 vc4 cec drm_kms_helper drm i2c_mux_pinctrl i2c_mux drm_panel_orientation_quirks snd_soc_core snd_compress snd_pcm_dmaengine syscopyarea sysfillrect sysimgblt raspberrypi_hwmon fb_sys_fops backlight bcm2835_unicam v4l2_dv_timings v4l2_fwnode i2c_bcm2835 bcm2835_codec(C) bcm2835_isp(C) bcm2835_v4l2(C) v4l2_mem2mem bcm2835_mmal_vchiq(C) snd_bcm2835(C) videobuf2_vmalloc videobuf2_dma_contig snd_pcm videobuf2_memops videobuf2_v4l2 snd_timer videobuf2_common snd videodev vc_sm_cma(C) mc fixed uio_pdrv_genirq uio uinput i2c_dev ip_tables x_tables ipv6
[   36.982829] CPU: 3 PID: 1053 Comm: yavta Tainted: G         C        5.10.52-v7+ #1439
[   36.982836] Hardware name: BCM2835
[   36.982845] Backtrace: 
[   36.982876] [<809eff20>] (dump_backtrace) from [<809f02b0>] (show_stack+0x20/0x24)
[   36.982893]  r7:ffffffff r6:00000000 r5:60000013 r4:80fe5e94
[   36.982911] [<809f0290>] (show_stack) from [<809f44c0>] (dump_stack+0xcc/0xf8)
[   36.982930] [<809f43f4>] (dump_stack) from [<8011ecb8>] (__warn+0xfc/0x114)
[   36.982947]  r10:7f16937c r9:00000009 r8:7f0e16b4 r7:00000799 r6:00000009 r5:7f0e16b4
[   36.982958]  r4:7f0e6f90 r3:80f05050
[   36.982974] [<8011ebbc>] (__warn) from [<809f08fc>] (warn_slowpath_fmt+0x70/0xd8)
[   36.982989]  r7:00000799 r6:7f0e6f90 r5:80f05008 r4:00000000
[   36.983033] [<809f0890>] (warn_slowpath_fmt) from [<7f0e16b4>] (__vb2_queue_cancel+0x1e0/0x258 [videobuf2_common])
[   36.983051]  r9:7f0ff098 r8:82411508 r7:00000001 r6:824113a8 r5:920179c0 r4:824113a8
[   36.983117] [<7f0e14d4>] (__vb2_queue_cancel [videobuf2_common]) from [<7f0e26b4>] (vb2_core_streamoff+0x28/0xbc [videobuf2_common])
[   36.983135]  r10:7f16937c r9:7f0ff098 r8:82411508 r7:00000001 r6:80f05008 r5:920179c0
[   36.983145]  r4:824113a8 r3:00000001
[   36.983215] [<7f0e268c>] (vb2_core_streamoff [videobuf2_common]) from [<7f17e0e4>] (vb2_streamoff+0x24/0x64 [videobuf2_v4l2])
[   36.983226]  r5:920179c0 r4:00000001
[   36.983273] [<7f17e0c0>] (vb2_streamoff [videobuf2_v4l2]) from [<7f17e170>] (vb2_ioctl_streamoff+0x4c/0x50 [videobuf2_v4l2])
[   36.983528] [<7f17e124>] (vb2_ioctl_streamoff [videobuf2_v4l2]) from [<7f0ff0c4>] (v4l_streamoff+0x2c/0x30 [videodev])
[   36.983540]  r5:40045613 r4:7f17e124
[   36.983780] [<7f0ff098>] (v4l_streamoff [videodev]) from [<7f104114>] (__video_do_ioctl+0x234/0x460 [videodev])
[   36.983791]  r5:40045613 r4:82411520
[   36.984029] [<7f103ee0>] (__video_do_ioctl [videodev]) from [<7f104b38>] (video_usercopy+0x138/0x5f0 [videodev])
[   36.984047]  r10:00000000 r9:8af75e3c r8:00000000 r7:80f05008 r6:00000000 r5:40045613
[   36.984055]  r4:40045613
[   36.984293] [<7f104a00>] (video_usercopy [videodev]) from [<7f105010>] (video_ioctl2+0x20/0x24 [videodev])
[   36.984310]  r10:00000003 r9:8af74000 r8:00000000 r7:920179c0 r6:920179c0 r5:80f05008
[   36.984319]  r4:7f104ff0
[   36.984555] [<7f104ff0>] (video_ioctl2 [videodev]) from [<7f0fd1f4>] (v4l2_ioctl+0x4c/0x60 [videodev])
[   36.984687] [<7f0fd1a8>] (v4l2_ioctl [videodev]) from [<80349c20>] (sys_ioctl+0x1d4/0x8ec)
[   36.984699]  r5:80f05008 r4:40045613
[   36.984718] [<80349a4c>] (sys_ioctl) from [<80100040>] (ret_fast_syscall+0x0/0x28)
[   36.984728] Exception stack(0x8af75fa8 to 0x8af75ff0)
[   36.984743] 5fa0:                   00000001 00000003 00000003 40045613 7ea909fc 00000001
[   36.984758] 5fc0: 00000001 00000003 00000001 00000036 76cd3000 000e93da 0000001d 00000000
[   36.984770] 5fe0: 00028040 7ea909f4 000149bc 76e2a51c
[   36.984787]  r10:00000036 r9:8af74000 r8:80100204 r7:00000036 r6:00000001 r5:00000003
[   36.984796]  r4:00000001
[   36.984807] ---[ end trace 6cbbe9f46f165689 ]---
[   36.984829] videobuf2_common: driver bug: stop_streaming operation is leaving buf 0831b94e in active state
how it functions on raspi-os with the official firmware, so i have something to compare against

the rawcapture file still seems way too dark, and i'm not sure how to open it yet, but it has way more entropy then under the open firmware
shining a flashlight into the sensor has no noticable impact on the hexdump

cleverca22
Posts: 4667
Joined: Sat Aug 18, 2012 2:33 pm

Re: unicam driver null pointer dereference

Mon Sep 27, 2021 9:19 am

went over a decent chunk of the driver in linux, and now i have a better understanding of how it works

Code: Select all

[  140.762908] unicam_start_rx()
[  140.764967] unicam_wr_dma_addr(dev, 0xde080000, 0x5dc00, 0)
[  140.841052] ISR: ISTA: 0x1, STA: 0x4016, sequence 0, lines done 0
[  140.841084] UNICAM_IBWP(0x11c): 0xde080000
[  140.841100] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  140.841116] unicam_wr_dma_addr(dev, 0xde041000, 0x1000, 0)
[  140.841137] unicam_wr_dma_addr(dev, 0xde100000, 0x5dc00, 0)
[  140.841166] ISR: ISTA: 0x1, STA: 0x4004, sequence 0, lines done 0
[  140.841185] UNICAM_IBWP(0x11c): 0xde080000
[  140.841199] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  140.841213] unicam_wr_dma_addr(dev, 0xde041000, 0x1000, 0)
[  140.841232] unicam_wr_dma_addr(dev, 0xde180000, 0x5dc00, 0)
[  140.907978] ISR: ISTA: 0x1, STA: 0x503E, sequence 0, lines done 1310
[  140.908010] UNICAM_IBWP(0x11c): 0xde180000
[  140.908025] unicam 3f801000.csi: Scheduling dummy buffer for node 0
[  140.908040] unicam_wr_dma_addr(dev, 0xde041000, 0x1000, 0)
[  140.908060] unicam_wr_dma_addr(dev, 0xde200000, 0x5dc00, 0)
[  140.919946] ISR: ISTA: 0x0, STA: 0xD03C, sequence 0, lines done 1310
[  140.919974] UNICAM_IBWP(0x11c): 0xde180000
[  140.922614] ISR: ISTA: 0x0, STA: 0xD03E, sequence 1, lines done 5368053
[  140.922649] UNICAM_IBWP(0x11c): 0xde180000
so i can tell that something is very wrong, when UNICAM_IBWP isnt advancing at all
its not even updating when a new start/end addr get written by unicam_wr_dma_addr(), which causes the lines-done computation to just go nuts

i am seeing the occasional frame-start interrupt in ISTA
but i'm never seeing a frame-end interrupt in ISTA!

but i do see UNICAM_PI0 catching some end of frame signals via the packet-compare logic instead
which is very different from how it functions under the closed firmware

from what ive seen so far, i'm guessing there are 2 clock domains involved
the digital side probably runs off the VPU clock, given that linux tries to bump the VPU up to a min of 250mhz
the analog side probably runs directly off the raw CSI clock from the sensor??

with 2 lane 500mhz DDR coming over the CSI link, thats 2gigabit of raw data coming over
if the digital end then consumed 8bits on every clock cycle, it would still be able to keep up with the data transfer rates
if dealing with 4lane CSI, that it would need to move 16bits on each clock cycle

but given that the stride for the raw data buffer must be a multiple of 32 bytes, it probably operates on 256bit chunks?, probably to get better axi bursts

Return to “Interfacing (DSI, CSI, I2C, etc.)”