[JP7.2] Memory corruption when HDMI display is connected at cold boot — Orin Nano on custom carrier

## Environment

- **Module**: P3767-0004

- **Software**: JetPack 7.2 / Jetson Linux **r39.2.0** (GCID 45755727), kernel `6.8.12-1021-tegra`, Ubuntu 24.04.4, UEFI `39.2.0-gcid-45755727`

- **Displays tested** (all plain HDMI-to-HDMI cables):

- two different small 7-inch-class HDMI panels from different vendors (one identified as **Daewoo CL07-HDMI**) → **both trigger the bug**

- one large **4K AOC** monitor → **never triggers the bug** (multiple cold boots)

- Boot from NVMe, X11 (WaylandEnable=false, nvidia X driver)

**Important context**: the exact same carrier board + these same small monitors ran **JetPack 6.x for a long time with zero issues** (display always connected at power-on). This only started with JP7.2, so we consider the monitors/EDID and our hardware ruled out.

To preempt the “custom board” question: our kernel/DT changes compared to stock r39.2 are **peripherals only** (WiFi/BT, CAN, MIPI cameras). The entire display pipeline — `display@13800000` / `dce@d800000` DT nodes, nvdisplay/DCE KMD, unified GPU driver, DCE firmware, UEFI — is **unmodified NVIDIA r39.2 code** (verified in our BSP git tree).

## Symptom

- **Small HDMI panel plugged in before power-on → system gets memory-corrupted and dies** (~100% reproducible over dozens of cold boots, both small panels)

- **The 4K AOC monitor plugged in before power-on → no problems at all** (multiple cold boots, clean every time)

- Plugging any of these displays **after** the system is up → everything works perfectly, indefinitely

- No display → everything works perfectly

So the bug is display-dependent: only the small panels trigger it. With a triggering panel at power-on and graphical target, the GDM greeter screen flickers and the machine freezes within ~16 s. With multi-user target it survives ~15 min as an idle text console, then hard-hangs silently (watchdog reset).

## What actually happens (captured on serial console)

At ~16 s the kernel enters an oops storm — **random physical memory is being scribbled by something**:

```

Internal error: Oops: 0000000096000044 [#1] PREEMPT SMP

CPU: 1 PID: 2362 Comm: gnome-shell

pc : __rmqueue_pcplist+0x104/0xaf4 x5 : dead000000000100 (LIST_POISON)

→ 15+ oopses within 5 s: __lruvec_stat_mod_folio, anon_vma_interval_tree_insert,

queued_spin_lock_slowpath, free_pcppages_bulk …

→ victims: gnome-shell, snapd, nm-dispatcher, kworkers, 7× udev-workers

→ i.e. struct page array / buddy lists / slab / dentries / user pages all corrupted

```

In parallel the **DCE firmware itself crashes twice** (Cortex-R5, loaded by UEFI from the `A_dce-fw` partition to 0x174000000, VA base 0x50000000):

```

Prefetch abort in user mode, Background fetching from 0x4f47a928

global worker@0x50248824 sp 0x5018fef0 …

(another instance: heap freelist walk loop — same PC 0x5000a754 repeated ~20× in the call stack)

```

**Notably: not a single arm-smmu context fault is logged during any of this.**

Corruption rate clearly scales with display activity:

| Configuration (all cold boots) | Outcome |

|—|—|

| HDMI + graphical target | oops storm, dead in ~16 s (multiple runs) |

| HDMI + multi-user (idle fbcon) | silent hard hang after ~15 min (multiple runs) |

| HDMI + multi-user, gdm started manually ~80 s after boot | healthy for the observation window |

| No HDMI, or HDMI hot-plugged after boot | healthy indefinitely |

## UEFI → kernel display handoff details (triggering small panel connected)

UEFI leaves in the kernel DT (captured with a triggering panel):
```

reserved-memory {

framebuffer@1,79E00000 {              // node absent/disabled without a display

    reg = <0x1 0x79e00000 0x0 0x800000>;          // PA 0x179E00000, 8 MB

    iommu-addresses = <&nvdisplay 0x1 0x79e00000 0x0 0x800000>;  // identity IOVA

};

};

```

Note the 8 MB size — exactly one 1920×1080 AR24 frame. We have not yet dumped this node for the 4K monitor; if its framebuffer is sized/placed differently (a 4K frame is ~32 MB), that difference may be why it does not trigger.

Two kernel-side observations that we believe are the key:

1. At ~9.9 s: `iommu smmu.0x0000000010000000: IOMMU driver was not able to establish FW requested direct mapping.`

We instrumented `drivers/iommu/iommu.c` and found this warning is a **false positive**: the first `iommu_map()` returns `-19` (expected for arm-smmu, mapping before first attach), and the kernel’s retry 5 ms later **succeeds**:

```

DMDBG: 13800000.display: resv region [0x179e00000 + 0x800000] type=0 prot=0x3 pgsize=0x1000 dma_dom=1

DMDBG: 13800000.display: iommu_map(iova=0x179e00000 pa=0x179e00000 size=0x800000 prot=0x3) FAILED ret=-19

DMDBG: 13800000.display: resv region [0x179e00000 + 0x800000] type=0 prot=0x3 pgsize=0x1000 dma_dom=1

(no failure) → retry succeeded, mapping established

```

2. At ~14.4 s: `nv_platform 13800000.display: Cannot reserve IOVA region of 0 size` — from `drivers/iommu/of_iommu.c:264`.

The **same** `iommu-addresses` property that the iommu core path parses as a valid 8 MB region (see above) is parsed as **size 0** here, so the region is **not reserved**.

In fast-dying boots we additionally see the GPU ACR firmware fail to load (all 9 firmware paths, error -40) followed by `nvgpu_finalize_poweron: Failed initialization for: g->ops.acr.acr_construct_execute`, ~3 s before the corruption storm. We currently read this as a downstream victim of the early corruption rather than the root cause, since the same file loads fine when the GPU powers on later in a healthy boot.
Also present in *every* HDMI boot (including healthy ones), DCE firmware console prints:

`[dce_mem_init_from_gsc] Failed to get ast region 2 mapping`

## Our working hypothesis

Because the framebuffer’s IOVA region fails to get reserved (the size-0 parse), the DMA IOVA allocator on `smmu_iso` can hand the `0x179E00000` range to **other** buffers, while the display pipeline keeps using it as the identity-mapped framebuffer → the display engine’s writes land in whatever physical page now lives at that IOVA → random memory corruption whose rate scales with display activity. This matches every observation, including “hot-plug is fine” (no UEFI framebuffer → no identity region → no collision) and plausibly the monitor dependence (different EDID → different mode → different framebuffer size/placement; we have not yet dumped the DT handoff for the 4K monitor for comparison).

We have not yet been able to dump the domain mappings on a live corrupted boot to prove the double-allocation.

Here is the complete serial port abnormal startup log. We hope to receive any assistance.

jp72_forum_abnormal_boot.log (63.0 KB)

What does that mean " is **unmodified NVIDIA r39.2 code** ? What board config are you using on your custom board?

Sorry, that sentence was a bit misleading. What I meant is: the display-related components themselves are unmodified r39.2. (submodule)The board device tree is our own — it adds MIPI camera nodes and changes some pinmux settings. These DT/pinmux configs are exactly the same as what we used on JetPack 6.x, where the same board and same monitors worked without any issues.

Hi,

How do you flash your board now? What is the command here?

Hi WayneWWW,

The instructions for flashing the firmware are as follows:

sudo ./tools/kernel_flash/l4t_initrd_flash.sh --external-device nvme0n1p1 -c tools/kernel_flash/flash_l4t_nvme.xml -S 80GiB -p "-c bootloader/generic/cfg/flash_t234_qspi.xml" --network usb0 recomputer-orin-j401 external

What is “recomputer-orin-j401”? This thing is already not something called “unmodified NVIDIA r39.2 code”…

This is a custom board and we totally don’t know what is the content of "recomputer-orin-j401.

Are you the board vendor for this? or you bought a custom board from them?

Hi,

Yes, we are the suppliers. We sincerely apologize for the incorrect initial expression that led to your misunderstanding. What I meant to say was that we did not make any changes to the related submodule for the display. Would you like to tell me if you have encountered similar problems? And do you have any suggestions for debugging? Any help would be greatly appreciated.

Do you have NV devkit (Orin Nano + Xavier NX devkit) to reproduce this issue?

If you are the suppliers, then you should know that you should use NV devkit to reproduce issue.