·
Last changedVersion:
This version passed the hardening gate. Hardening updated the skill content and independently checked the resulting changes. Classified findings before hardening: 3. Classified findings closed: 0. Classified findings remaining: 3. Unclassified scanner findings remaining: 0. Review findings closed: 2. Review findings remaining: 16.
3
3
Expand | File | Group | Subtype | Severity | Status |
|---|---|---|---|---|---|
SKILL.md | Privilege Escalation & Host / Cloud Compromise | Privilege escalation | Medium | Open | |
evals/evals.json | Sensitive Data & Secret Exposure | Agent snooping | Medium | Open | |
BENCHMARK.md | Sensitive Data & Secret Exposure | Agent snooping | Medium | Open |
3 findings
Customize CPU, GPU, and EMC clock behavior on a Jetson target by editing files under Linux_for_Tegra/ before flashing the image. Two layers are in scope:
Linux_for_Tegra/bootloader/<BPFDTB_FILE> — per-clock max-rate-custom ceilings, plus the EMC DVFS gate (bwmgr + cactmon on all SoCs; osp-controller on T26x only).Linux_for_Tegra/rootfs/etc/systemd/nvpower.sh — cpufreq / devfreq governors and (optionally) per-device min / max / static rates written to sysfs at boot.Common triggers: "lock CPU/GPU/EMC frequency", "pin GPU to Fmax", "pin EMC to MAXN", "disable/enable EMC DVFS", "disable/enable CPU DVFS", "set CPU/GPU max rate", "change cpufreq governor".
Out of scope: runtime clock tuning on a live target (no flash step), nvpmodel power-mode edits (use the sibling skill /jetson-customize-nvpmodel), and silicon-ceiling overrides (max-rate-maxn is read-only).
Resolve the active profile per
../../context/target-platform-contract.md.
Refuse and route in these cases:
| Condition | Refuse with |
|---|---|
No active profile, or | Route to |
Profile lacks | Route to |
| Route to |
| Route to |
Resolve paths:
<bsp_image.root_path> from bsp_image.root_path: if present, else <workspace>/Image.<source.root_path> from source.root_path: if present, else <workspace>/Source.<bsp_image.root_path> is read-only for this skill; every write
(Operation 1's BPMP DTB and Operation 2's nvpower.sh) lands under
<source.root_path> (the overlay tracker). This is the workflow
invariant in
../../context/bsp-customization-workflow.md#workflow-invariants —
hand-editing upstream silently destroys the diff trail and makes
/jetson-promote-image a noop.
nvpower.sh), or the MAXN recipe for both./jetson-promote-image → /jetson-flash-image. The new BPMP DTB and nvpower.sh take effect on the next boot.| Operation | Where the edit lives | Procedure section |
|---|---|---|
Lock a CPU / GPU clock to a specific rate | BPMP DTB | "Content edit: |
Lock EMC at its init rate (disable EMC DVFS) | BPMP DTB: | "Content edit: EMC DVFS disable / enable" |
Re-enable EMC DVFS | BPMP DTB: | "Content edit: EMC DVFS disable / enable" |
Pin everything to MAXN for stress runs | Combine the above + nvpmodel MAXN as boot default | see Recipe |
Lower a clock's hard ceiling without locking | BPMP DTB | "Content edit: |
Bound a device's rate without pinning |
| "Pick the edit" |
Follow the BPMP-DTB customization protocol in
../../references/bsp-customization-bpmp-dtb.md.
The protocol owns the mechanics — pristine import on first touch,
dtc decompile, recompile, sanity-check, commit. This skill
supplies only the clock-specific content (which nodes and
properties to edit during the protocol's "Edit the DTS" step).
The edited .dtb lands in the <source.root_path>/Linux_for_Tegra/
overlay tracker. /jetson-promote-image's channel A walks the
tracker and copies the file into bsp_image. Do not edit
<bsp_image.root_path>/Linux_for_Tegra/bootloader/<bpmp-dtb>
directly — that's the promote output, not an input.
Per the protocol's "Resolving the active BPMP DTB" section, read
BPFDTB_FILE from the active flash conf. For the common Thor /
single-SKU conf shapes this is the static BPFDTB_FILE=... line
in the per-board .conf and the value is authoritative as-is.
For SKU-multiplexed conf shapes (Orin AGX devkit conf chain
that selects a different BPMP DTB per board_sku/board_FAB
via update_flash_args_common — see
../../context/bsp-customization-software-layers.md#per-board-conf-dispatch--update_flash_args_common),
walk the dispatch chain with board_sku=<module.sku> and
board_FAB=<module.revision or empty> from the active profile,
and read BPFDTB_FILE from the dispatch output — not from
the static line of the per-board .conf. Static and dispatched
values match for non-multiplexed confs; the dispatch is
mandatory only when the conf chain conditionally overrides
BPFDTB_FILE.
Inspect both layers of the runtime ceiling — see references/clock-control-model.md#effective-runtime-ceiling — before deciding on a max-rate-custom value.
Inspection cookbook (BPMP-side decompile + grep; nvpmodel-side awk over the boot default mode) is in references/bpmp-dtb-clock-edits.md#inspection-cookbook.
For the nvpmodel layer see /jetson-customize-nvpmodel.
This step does not mutate state — it's a precondition for sizing
the edit in the "Content edit: max-rate-custom on a named clock node" step.
max-rate-custom on a named clock nodeDuring the "Edit the DTS" step of the protocol, modify the property
inside the named clock node — never lateinit. max-rate-custom
must be strictly below the clock's hard cap (max-rate-maxn if
defined, otherwise the live max_rate from a running target of
the same chip / SKU).
DTS edit form, semantics, and the nvpmodel ↔ BPMP clock-node
mapping live in references/bpmp-dtb-clock-edits.md.
Then hand control back to the protocol — its "Recompile", "Sanity-check
the recompiled blob", "Stage in the overlay tracker", and "Cleanup"
steps cover the rest.
Commit-message convention per the protocol:
<BPMP_BASENAME>: jetson-customize-clocks — <clock-node> max-rate-custom = <value>.
Default behavior (EMC DVFS on) requires no edit. Disabling EMC
DVFS is a multi-node edit applied inside the same "Edit the DTS" step of
the protocol, not a bwmgr toggle:
| # | Edit | Scope |
|---|---|---|
1 |
| All SoCs, mandatory |
2 |
| All SoCs, mandatory |
3 |
| T26x (Thor) mandatory — T23x (Orin) has no such node, skip |
Detection: dtc -I dtb -O dts <bpmp-dtb> | grep -c osp-controller
— zero hits ⇒ T23x path. Full DTS snippets, the surviving-paths
failure modes, and the re-enable procedure are in
references/emc-dvfs-disable.md.
Apply the protocol's "Recompile" through "Cleanup" steps once the multi-node edit is in
place. Commit-message convention:
<BPMP_BASENAME>: jetson-customize-clocks — EMC DVFS disable (bwmgr + cactmon[+ osp-controller]).
Disabling raises idle power; intended for stress / performance tests, not production rootfs.
Per the protocol's "Re-runnability" section, re-running this
skill with the same target value produces a no-op commit. Re-
running with a different value rewrites the same property — git log -- $BPMP_REL shows the per-run history. To return a clock
to its max-rate-maxn ceiling, edit the DTS to remove the
max-rate-custom line and recompile.
Edits nvpower.sh, which runs at boot via nvpower.service to set
cpufreq / devfreq governors and rates.
The script this Operation edits has the relative path:
It lives in two roots; the Operation walks both:
| Role | Location | Skill writes? |
|---|---|---|
Detection + pristine source |
| no — read-only |
Overlay edit target + git commit |
| yes |
Subsequent sub-steps refer to the per-script file to mean the overlay
copy under <source.root_path>. The <bsp_image.root_path> copy is read
once during the pristine-import step below, then never touched again.
Follow the canonical
Off-skill edits recipe
in the workflow doc — pristine import + customization commit pair, both
gated by the preview gate. nvpower.sh is a single file with no
propagation set; one pristine commit + one customization commit covers
the entire change.
Concrete substitutions for this skill:
<rel>/<file> is rootfs/etc/systemd/nvpower.sh.import pristine: rootfs/etc/systemd/nvpower.sh,
body Source: <bsp_image.root_path>/Linux_for_Tegra/ (BSP <bsp_image.version>).jetson-customize-clocks: nvpower.sh <summary>,
body lines like set_cpufreq_governor: desired_cpufreq_gov "schedutil" -> "performance".Function locations (set_cpufreq_governor, set_devfreq_governor), common-edit recipes (pin to Fmax, static rate, min/max bounds), and the nvidia-l4t-init package-upgrade caveat live in references/nvpower-sh-edits.md.
The customization commit in the overlay tracker does not reach the device on its own. The Deploy chain:
/jetson-promote-image — copies every tracked file in the overlay
into <bsp_image.root_path>/Linux_for_Tegra/. Diff-aware (skip
byte-identical); uses sudo cp -p for rootfs/* destinations./jetson-flash-image — flashes the updated bsp_image to the
device. nvpower.service runs the new script on the next boot.Editing <source.root_path>/... without committing — or editing
<bsp_image.root_path>/... directly — does nothing for /jetson-promote-image
and is silently lost on the next /jetson-init-image re-extract.
Combines Operations 1 + 2. Operation 1's BPMP edits all flow
through one round of the protocol (a single decompile / multi-node
edit / recompile / commit cycle — don't round-trip the protocol
twice for the same .dtb):
max-rate-custom on a named clock node" step content): leave max-rate-custom unset on every CPU / GPU / EMC clock; remove existing max-rate-custom lines that lower the ceiling.bwmgr.enabled = 0, cactmon.enabled = 0, plus /delete-node/ osp-controller on T26x (skip on T23x).desired_cpufreq_gov="performance" and desired_devfreq_gov="performance" unconditionally; remove the GPU/nvjpg skip in set_devfreq_governor. Applies via Operation 2's overlay edit recipe (the "Overlay edit recipe (apply before editing nvpower.sh)" step) — a separate overlay-tracker pristine + customization commit pair on the rootfs script, distinct from the BPMP-DTB protocol's commit./jetson-customize-nvpmodel — the per-clock nvpmodel cap clamps below max-rate-maxn regardless of BPMP DTB content.Deploy /jetson-promote-image → /jetson-flash-image picks up the new BPMP DTB (via the overlay tracker) and the edited nvpower.sh (via the same overlay tracker) on the next flash.
<source.root_path>/Linux_for_Tegra/ and reach the device only via /jetson-promote-image → /jetson-flash-image. Live-target tuning is out of scope.max-rate-custom only lowers the ceiling. It must be strictly below max-rate-maxn; raising the silicon cap is not supported.min(BPMP cap, active-nvpmodel-mode cap). The nvpmodel cap is owned by /jetson-customize-nvpmodel; this skill does not edit it.osp-controller). Mis-detection produces undefined behavior.nafll_gpusys and every nafll_gpcX; the cap binds only when applied to all of them.nvpower.sh is package-managed. It ships in nvidia-l4t-init; package upgrades clobber in-place edits. Long-lived setups should prefer a systemd drop-in or sibling helper.max-rate-maxn and lateinit are off-limits. max-rate-maxn is the silicon ceiling (read-only). lateinit is for boot-time clock init, not ceiling overrides — never touch either.BPFDTB_FILE is selected by board_sku / board_FAB via update_flash_args_common. Reading the static BPFDTB_FILE= line is wrong when the chain conditionally overrides it; resolve via the dispatch instead.| Error | Cause | Solution |
|---|---|---|
| Only | Apply the same |
EMC DVFS disable appears to apply but EMC still scales on T26x | Only | Add edits #2 ( |
EMC DVFS disable rejected on T23x with "node not found" for | T23x (Orin) BPMP DTBs do not contain | Detect SoC family with the |
BPMP refuses to load DTB after edit: |
| Lower |
|
| Replace with |
Edits to |
| For long-lived test setups, package edits into a systemd drop-in or a sibling helper file referenced by |
| The edit was applied to | Move the edit to |
Cap appears to apply on first boot then resets after a power-mode change | The active nvpmodel mode's per-clock cap clamps below | Inspect both layers; if nvpmodel is binding, raise (or remove) the nvpmodel cap via |
../../references/bsp-customization-bpmp-dtb.md — canonical BPMP-DTB customization protocol (pristine import, decompile, edit, recompile, sanity-check, commit). Operation 1 of this skill is a content-only consumer; the protocol owns the mechanics.references/clock-control-model.md — layer stack, two-ceilings overview, effective-runtime-ceiling formula.references/bpmp-dtb-clock-edits.md — two-ceilings semantics, DTS edit form, nvpmodel ↔ BPMP clock-node mapping, inspection cookbook.references/emc-dvfs-disable.md — full SoC-conditional EMC DVFS disable procedure with DTS snippets, detection, re-enable.references/nvpower-sh-edits.md — nvpower.sh function locations + common-edit recipes + package-upgrade caveat./jetson-customize-nvpmodel — sibling skill: nvpmodel power modes. The active mode's per-clock cap clamps below the BPMP DTB cap.Get started with chainctlchainctl skill install public/nvidia/jetson-customize-clocks:latest
Bring Chainguard's hardening pipeline to your first-party skills — custom rulesets, automated remediation, full audit trail.
skills.chainreg.biz/public/github.com/nvidia/skills/jetson-customize-clocks:latest
Apache-2.0
BENCHMARK.md
HARDENING.md
LICENSE
SKILL.md
evals/evals.json
references/bpmp-dtb-clock-edits.md
references/clock-control-model.md
references/emc-dvfs-disable.md
references/nvpower-sh-edits.md
skill-card.md
skill.oms.sig