Hi NVIDIA team,
On AGX Orin with r36.4.4 (kernel 5.15.148-tegra), we found a bug in the VI5 error path that corrupts kernel memory and leads to a system reset.
Root cause
In vi5_fops.c, tegra_channel_capture_setup() allocates the descriptor ring into chan->request[vi_port], but when vi_capture_setup() fails it frees chan->request instead. That is the address of the pointer array inside struct tegra_channel, not the DMA buffer.
c
err = vi_capture_setup(chan->tegra_vi_channel[vi_port], &setup);
if (err) {
dev_err(chan->vi->dev, "vi capture setup failed\n");
dma_free_coherent(chan->tegra_vi_channel[vi_port]->rtcpu_dev,
setup.queue_depth * setup.request_size,
chan->request, setup.iova); /* should be chan->request[vi_port] */
return err;
}
As a result, a live kernel page is returned to the allocator, the real DMA buffer is leaked, and the pointer is left dangling.
Evidence
The path is easily hit when cameras are disconnected and several channels retry VIDIOC_STREAMON at the same time. Then channel context at N is busy makes vi_capture_setup() fail:
[2247.727] channel context at 0 is busy (WARN, capture-ivc.c:195, Comm: ai_framework)
[2248.733] tegra194-vi5 ...vi0@15c00000: failed to update control callback
[2248.733] tegra-camrtc-capture-vi tegra-capture-vi: vi capture setup failed <- this error path
[2249.396] BUG: Bad page state in process ai_framework ... page dumped because: non-NULL mapping
-> IVC control submit failed / MBOX_TX_QUEUE_LEN -> Oops -> panic -> reset
Across the resets we checked, the number of “vi capture setup failed” messages matches the “Bad page state” reports (e.g. 6 → 5 in one boot), and every reset was preceded by this sequence. The same busy → “failed to update control callback” → Bad page state pattern also appears in Topic 317977.
Proposed fix
c
dma_free_coherent(chan->tegra_vi_channel[vi_port]->rtcpu_dev,
setup.queue_depth * setup.request_size,
chan->request[vi_port], setup.iova);
chan->request[vi_port] = NULL;
Related leaks in the same area: the csi_chan == NULL (-EINVAL) branch in the same function, and the err_set_stream error path of vi5_channel_start_streaming(), both never free chan->request[vi_port].
Already applied: the capture-ivc multi-cam race fix (337341), the error_recover leak fix (337609), and the infinite capture timeout.
Questions
- Can you confirm this bug and provide an official patch for r36.x?
- Is it fixed in a later release?
Thanks.