Skip to content

History / README

Revisions

  • kernel: change 11 — rknpu_gem_create_ioctl dereferences an unreferenced GEM pointer The second live caller of the lookup-then-put rknpu_gem_object_find(). It reads the object four times with only the handle table keeping it alive, so a concurrent close frees it underneath. Hardening rather than a suspected crash source: unlike change 10, nothing sleeps between the lookup and the last use, so the window is short — but it is real, and the vendor had already left a commented-out object_get() in the middle of it. Both branches now leave exactly one reference owned by the ioctl, dropped before return. Net refcount across the ioctl is unchanged. The third caller, rknpu_gem_dumb_map_offset, is the worst on paper (it calls drm_gem_create_mmap_offset, which can sleep, on an unreferenced object) but sits inside #if KERNEL_VERSION(4,19,0) > LINUX_VERSION_CODE and is not compiled on 6.1.115 — confirmed against the built object file, not just the #if. Left untouched deliberately; the live path is DRM core's drm_gem_dumb_map_offset. Built and running as kernel #14, make test ALL TESTS PASSED.

    @mafischer mafischer committed Aug 26, 2026
  • kernel: change 10 — rknpu_gem_destroy_ioctl held an unreferenced GEM pointer across an ~18 s wait rknpu_gem_object_find() is lookup-then-put and hands back an unreferenced pointer, kept alive only by the handle table; its kerneldoc claimed the refcount would be increased, which is false and is corrected here. rknpu_gem_destroy_ioctl then held that pointer across rknpu_iommu_domain_get_and_switch's 3 x 6 s timeout, and dereferenced it inside the retry loop. A process death in that window (SIGTERM -> DRM file close -> handles released -> objects freed) leaves it dangling. Not theoretical: a stalled NPU job is what makes the switch time out, and a stuck run is when the process gets killed — the exact combination that produced the corruption this session. Prime suspect for 'BUG: Bad page cache ... still mapped when deleted', because rknpu vm_insert_page()s the GEM's shmem pages and clears VM_PFNMAP while vma->vm_file stays the DRM node, so the shmem inode's i_mmap tree cannot find those VMAs to unmap at evict — the GEM refcount is the only protection. Built and running as kernel #13, make test ALL TESTS PASSED. Not yet PROVEN to fix the corruption; that needs a run reproducing the old crash. Also corrects the record on change 8: it was briefly suspected of stalling dispatch, but rknpu_job_next only advances when subcore_data->job is NULL, so a stale non-NULL entry blocks the core and clearing it can only help.

    @mafischer mafischer committed Aug 26, 2026
  • kernel: export changes 7-9 — two real fixes (NULL iommu domain, abort's freed job pointer) + the diagnostic bundle Changes 7 and 8 are genuine vendor bugs found while chasing the int4 doorbell dispatch stall, and both are board-killers: - rknpu_iommu_dma_{map,unmap}_sg / _alloc_iova dereference the IOMMU domain with no NULL check, and rknpu_iommu_switch_domain can leave the device attached to no domain at all. Reached whenever a stalled job makes the switch time out. The guard fired 12 times in a single run. - rknpu_job_abort clears subcore_data->job only when !job->irq_entry[i] but frees the job unconditionally, publishing a dangling pointer that the IRQ handler, rknpu_job_next and the watchdog all read. The resulting slab corruption panics later somewhere unrelated, which is why it never looked like an NPU bug. Both are exported standalone (verified to apply cleanly to a pristine worktree at base 1cd878b3ac49, and to reverse-apply against the board tree), alongside 99-ALL-current-state.patch, the complete cumulative diff for kernel #12. Change 9 is the diagnostic scaffolding and is documented as default-off. It carries a RETRACTION: the earlier "IOMMU re-attach recovers 3/3 vs 0/11" result does not survive Change 8 — the kick now recovers 0/5, and the original was almost certainly re-committing an already-freed job. It also records four hypotheses refuted with counters, and the 100x throughput trap in the watchdog sampling cadence.

    @mafischer mafischer committed Aug 26, 2026
  • kernel: Change 6 — rknpu IRQ handler faults on MMIO while powered down (the hard-wedge bug); retract the Change-5 attribution

    @mafischer mafischer committed Aug 26, 2026
  • kernel-patches: add 04 (fence signal on abort) + 05 (progress watchdog); record the power-safety trap

    @mafischer mafischer committed Aug 25, 2026
  • kernel-patches: export the two board patches out of the container They existed only as uncommitted working-tree edits in a stopped docker container on the .239 VM -- one docker rm from unrecoverable, with no diff anywhere else. Now in version control with the base commit they apply to.

    @mafischer mafischer committed Aug 24, 2026