Skip to content

Upstreaming and external registrations

This document tracks the work that cannot be done inside this repository: patches that have to be posted to a mailing list, and identifiers that have to be requested from someone else. It exists because that work is easy to lose - it produces no commit here, so nothing in CI notices it is outstanding.

Everything below is ordered by what unblocks what. Tracks 1 and 2 can go out today. Track 3 gates tracks 4, 5 and 6, so it should be sent first even though it is the least interesting.

Author identity for all upstream submissions is Weqaar Janjua <weqaar.janjua@gmail.com>, which is what the existing commits in the qemu submodule are already authored as. Upstream projects require a Signed-off-by: line (Developer Certificate of Origin); note this is the one context where this repository's usual no-Signed-off-by convention does not apply, because the DCO is a legal requirement of contributing there.


Track 1, aspeed GPIO fix (ready to send, no blockers)

A genuine bug in an existing upstream device, found while bringing up the sled BMC. The Aspeed GPIO model did not drive a pin when firmware flipped its direction to output, so the first assertion after a direction change was lost. Firmware routinely writes the data register first and the direction register second, so this affects real workloads, not just ours.

This has no dependency on anything Cnuas. It touches only hw/gpio/aspeed_gpio.c, is 9 lines, and is the single most likely thing here to be accepted quickly.

  • Commit: 4b9e24b6fc "hw/gpio/aspeed: drive pins when direction flips to output"
  • checkpatch.pl: clean (0 errors, 0 warnings)
  • Test: tests/qtest/aspeed_gpio-test.c gained /ast2600/gpio/output_on_direction_flip, which stages a level while the pin is an input, flips the direction, and asserts the pin drives. Confirmed to fail with the fix reverted and pass with it applied, so it genuinely pins the behaviour rather than merely passing.

Send it as a two patch series, fix first and test second.

The series is generated and verified. It lives in upstream/qemu-aspeed-gpio/ and on branch upstream-aspeed-gpio in the qemu submodule, rebuilt on current upstream master b428fe0362 rather than on the v11.0.0-rc1 base this fork sits on. checkpatch is clean on both patches, the build is clean, and the test suite is 3/3. Reverting the fix makes the new test fail at the intended assertion while the two pre-existing tests still pass, which is the evidence that it pins the behaviour and does not regress anything. See upstream/README.md for the send-email command.

Track 2, CMIS optical module (ready to send, no blockers)

hw/i2c/cmis_module.c models a CMIS 5.0 optical module on an I2C bus: page select, identity on page 00h, thresholds on 02h, TxDisable on 10h and per-lane diagnostics on 11h. It is useful to anyone testing switch or BMC firmware that reads optics, which is why it is worth offering upstream rather than keeping local.

It needs no PCI ID, since it is an I2C device. That is what separates it from tracks 4 and 5.

  • Commit: 3e6c1d99fc "hw/i2c: model a CMIS optical module"
  • checkpatch.pl: clean after the fixups now staged in the submodule (long lines, block comment style, and a missing MAINTAINERS entry)

The series is generated and verified. It lives in upstream/qemu-cmis-module/ and on branch upstream-cmis in the qemu submodule, as three patches - device, specification, test - rebuilt on current upstream master. checkpatch reports 0 errors; the two remaining warnings are advisory (SPDX on a .rst, which only 1 of 37 files in docs/specs/ carries, and a false-positive MAINTAINERS prompt, since MAINTAINERS is updated in patch 1). The build is clean and the CMIS qtests are 4/4.

Two things had to change on the way out. The qtest needed an SPDX identifier and had to drop its licence boilerplate, which checkpatch rejects on new files. And the default vendor part and serial numbers were CNUAS-QDD-400G-DR4 and CNUAS0000000000; upstream should not carry our branding in a generic device, so they are now QEMU-*. Both are properties, so nothing on our side depends on the defaults.

Reconstructing the series exposed a hazard worth recording, because it is silent: checking out whole files from this fork onto current upstream master reverts unrelated upstream work. Taking hw/arm/Kconfig and hw/i2c/Kconfig wholesale deleted FSL_IMX8MM, TEGRA241_CMDQV and DESIGNWARE_I2C and dropped ARM_GICV5, WDT_SBSA, CAN_FLEXCAN, XLNX_ZYNQ_DDRC and IMX6UL_LCDIF, purely because our base predates them. Only the specific hunks may be applied. The check that catches it is that git diff --stat upstream/master..HEAD must show additions only.

See upstream/README.md for the send-email command; the primary addressee is Corey Minyard, who maintains I2C and SMBus.

Track 3, official PCI device IDs (send first, gates tracks 4-6)

The emulated devices currently use 1af4:10f0 (CnuasNIC), 1af4:10f1 (CnuasGPU) and 1af4:10f2 (switch IB NodeInfo). qemu/docs/specs/pci-ids.rst permits that range "for experimental usage without registration", but explicitly requires official IDs "when the code leaves the test lab (i.e. when seeking upstream merge or shipping a distro/product)". So this must be settled before tracks 4, 5 or 6 are posted anywhere.

Cnuas is emulation-only, so no PCI-SIG membership is needed; the correct path is an assignment under Red Hat's QEMU vendor ID 0x1b36. At the time of writing the highest allocated ID in that range is 1b36:0014 (RISC-V IOMMU), so 0015-0017 are the likely next free values.

Do not reuse 0x1ed5 - that is assigned to Moore Threads.

Was blocked on the Cnuas/HiCAIN naming split (now resolved)

The historical passages in this section quote the pre-rename Hi* names on purpose, and also quote third-party upstream names. They are deliberately not subject to the rename. See "A note on this document" at the end of the section.

Corrected 2026-08-01. Cnuas is the Virtual AI/HPC Datacentre platform and owns all the emulated hardware; HiCAIN is a separate open-source AI/HPC education/LMS product that consumes Cnuas. An earlier draft of this document had that the wrong way round. Consequently every emulated device below - the NIC, the accelerator and the switch endpoint - belongs to Cnuas, and the request above has been reworded accordingly. Device names in the request must be finalised after the Hi* to Cnuas* rename, not before.

There is also a hard naming conflict independent of branding: hinic and hinic3 already exist upstream as Huawei's HiNIC drivers under drivers/net/ethernet/huawei/. Submitting a second hinic is a non-starter, so the rename is a prerequisite for track 5 rather than a cosmetic exercise. hilink is likewise taken, by HiSilicon's HNS3 driver.

Rename execution hazards

The bulk rename must not be run naively. Five distinct traps were measured:

  1. The linux submodule must be excluded entirely. It vendors Huawei's hinic (88 files) and HiSilicon's hilink references. An unfiltered token pass rewrites 8310 hits there, of which exactly one is ours. The residue outside drivers/net/ethernet/{huawei,hisilicon}/ is also upstream: reset_hinic_vf_dev in drivers/pci/quirks.c, the MAINTAINERS entries, and "Phinic Helix Board" in sound/firewire/bebob/bebob.c, where hinic sits inside an unrelated word.
  2. Our entire footprint in linux is one line - RDMA_DRIVER_HICAIN at include/uapi/rdma/ib_user_ioctl_verbs.h:259, now RDMA_DRIVER_CNUAS. Edit it by hand; never run the token map against that tree.
  3. hica is unsafe as a bare substring. It occurs inside the ordinary words graphical, hierarchical, cryptographically, geographical and mythical (~71 occurrences), which a literal pass turns into grapcnuasl and similar. The camelCase runtime API (hicaMalloc, hicaStreamCreate) therefore has to be matched as \bhica, and a snake-case-only hica_ token misses ~650 real occurrences.
  4. Case variants are easy to miss and produce a partial rename, which is worse than none. The tree uses four forms per product - HiGPU, HIGPU, higpu and Higpu - the last in C type names (HigpuState) and Bazel targets. HiIR (80 hits) was absent from an earlier map while Hiir (0 real hits, matching only "Hiironen" in linux's CREDITS) was present.
  5. Token ordering must use effective length, ignoring any re: or \b markers, so that hicain and hicart are consumed before \bhica.

git mv of the submodule paths, the libcnuasrt.so soname, the tools/src/cnuas_tools/ package directory and its entry points, Yocto recipe and machine names, and the Bazel targets all need handling beyond a text pass. Renaming src/cnuasnic/rdma-core/cnuas.c's PROVIDER_DRIVER(cnuas, ...) without its matching packaging/rdma-provider/cnuas.driver breaks RDMA at runtime with no build error.

What execution actually required

The rename has been applied. Four further problems surfaced only during execution, and none of them would have been caught by inspecting the diff:

  • A separate hi_/HI_ device-shim prefix (284 occurrences) that the main map never covered. It could not be folded in: every hi_ token in the qemu tree is upstream code using "hi" for high word (hi_dword, HI_COMMPAGE, HI_XSR), and bmc/firmware's orv3_regmap.c has a generic hi_idx. It is renamed by a second, tightly scoped map that excludes both. libhi became libcnuasdev rather than libcnuas, because that name was already taken by the NIC provider.
  • git mv refuses to move a submodule while .gitmodules is dirty, so the content pass must stage its own edits before the path pass, and the superproject must be processed after the submodules or the --repo paths move out from under the run.
  • Filenames and link flags drift out of step with contents. hicasmi had its contents renamed but not its filename, and -lhi survived in three Makefiles. Only a real build catches these.
  • A hard-coded prefix length. cnuas/src/cnuas/adapters/gpu.py sliced name[5:] to strip "higpu"; the new prefix is eight characters, so device enumeration silently returned nothing. It now derives the offset from COMPONENT. A text-only rename cannot see this class of bug, which is why the test suites are the real gate.

External actions (completed 2026-08-02)

These could not be done from the repository. All are now done:

  1. The four GitHub repositories were renamed - HiGPU->CnuasGPU, HiNIC->CnuasNIC, HiLink->CnuasLink, HiSwitch->CnuasSwitch - and the submodule remotes repointed off GitHub's redirects. This was not optional in the end: .gitmodules had already been rewritten to the Cnuas* URLs, so a recursive clone failed until the renames landed.
  2. The linux branch cnuas-v6.19 was pushed, and the six submodule commits published. The superproject commit had to be corrected first - it was made before the submodules and so recorded all six pre-rename gitlinks, producing a tree that renamed every path while pointing at the old contents. It was still unpushed, so it was amended rather than rewritten in public.
  3. The cnuas-* tags were pushed additively in linux and qemu. The old hicain-* tags were deliberately kept, since deleting published tags breaks anyone who has fetched them.

Still outstanding: PacketFive/linux still defaults to the hicain-v6.19 branch.

The OpenBMC/Yocto images were expected to need a rebuild, on the assumption that they bake renamed runtime paths. They do not. The meta-cnuas layer was already Cnuas-named before this rename, so the rename touched only eight files under bmc/ and every change in them is a comment - including in the two device trees, which are the only compiled artefacts there. Verified directly against the built images: obmc-phosphor-image-cnuas-{sled,rmc,tor}.static.mtd contain zero occurrences of hicain, higpu, hinic, hiswitch or hilink. No rebuild is required.

Naming is now settled: the rename has been applied. The device names in the request land permanently in upstream docs/specs/pci-ids.rst, and there is only one clean opportunity to ask, so this had to be resolved first. The QEMU devices are now cnuas-vnic (hw/net/cnuas_vnic.c) and cnuasgpu (hw/misc/cnuasgpu.c), and the draft below uses those names. The email is ready to send once the four GitHub repository renames are done, so that the project URLs in it resolve.

Tracks 1 and 2 are unaffected: the aspeed GPIO fix and the CMIS module contain no Cnuas naming at all, so they can be posted upstream regardless of how the rename resolves.

As of this writing nothing has been posted upstream and the PCI ID request has not been made, so no name is externally committed yet. That makes this the cheapest moment the rename will ever have. Two surfaces would otherwise have become permanent, and both are still free to change only because the submissions have not gone out:

  • RDMA_DRIVER_CNUAS in linux/include/uapi/rdma/ib_user_ioctl_verbs.h. It is appended last in the enum, so the numeric value is stable, but the identifier becomes frozen kernel UAPI the moment it is accepted.
  • The rdma-core provider name, which appears as PROVIDER_DRIVER(cnuas, ...) in src/cnuasnic/rdma-core/cnuas.c and as packaging/rdma-provider/cnuas.driver. It must match the kernel driver's registered device name; renaming one without the other breaks RDMA at runtime with no build-time error.

The remaining exposure is therefore internal only: matched pairs that must be renamed atomically, and deployed state that must be regenerated. The measured interface surface is cnuas-tools (213 hits), cnuas_tools (169), cnuas-vswitchd (134), cnuas-cli (137), libcnuasrt (92), /run/cnuas (79), /var/run/cnuas (63), cnuaslink-cli (40), cnuas-vnic (32), CNUAS_RUN_DIR (18), RDMA_DRIVER_CNUAS (14) and cnuas.driver (6). Everything else in the ~4,100-line footprint is prose and is free to change.

The email

The sendable text is upstream/pci-id-request/email.txt. It is a plain email, not a patch, so send it with a normal mail client rather than git send-email.

It names the devices as they now exist - cnuas-vnic (hw/net/cnuas_vnic.c) and cnuasgpu (hw/misc/cnuasgpu.c) - and both facts it relies on were re-checked against upstream's docs/specs/pci-ids.rst: Gerd Hoffmann is the contact named in that file, and the highest allocation under 1b36 is 0014 (RISC-V IOMMU), so 0015-0017 are the next free values. The email asks for three IDs but explicitly defers to whatever he prefers, since the numbering is his to decide.

It also mentions in passing that tracks 1 and 2 are being posted separately and need no IDs, so that the request is not mistaken for a blocker on them.

After the IDs are assigned

Replace the experimental IDs atomically across all three repositories - a partial replacement produces a device the driver silently will not bind to:

Repository Files
qemu hw/net/cnuas_vnic.c, hw/misc/cnuasgpu.c, docs/specs/pci-ids.rst
cnuas src/cnuasnic/kernel/cnuas_net.h, src/cnuasnic/userspace/libcnuas.c, src/cnuasnic/kernel/cnuas_ib.c, src/cnuasgpu/driver/cnuasgpu.h, src/cnuasswitch/switch/src/ib_sma.c
docs datasheets, design docs, CI and e2e expectations, FPGA readback values

Tracked as todo pci-id-acquisition.

Track 4, QEMU Cnuas devices (blocked on track 3)

hw/net/cnuas_vnic.c and hw/misc/cnuasgpu.c. These are substantially larger asks than tracks 1 and 2, and upstream will reasonably question why QEMU should carry devices with no corresponding silicon. The honest framing is the same one used above: they exist to let driver and fabric software be developed and tested without hardware.

Prerequisites beyond the PCI IDs:

  • ~~A device specification under docs/specs/~~ Done. qemu/docs/specs/cnuas-vnic.rst and qemu/docs/specs/cnuasgpu.rst are written, wired into docs/specs/index.rst and MAINTAINERS, and checkpatch-clean. These are the datasheets upstream will ask for: every register, every option, the wire format, and the cases where a frame is dropped. They were derived from the source and each claim was checked against it.
  • qtests. Not yet written. tests/qtest/cmis-module-test.c is the model to follow, but these are PCI devices, so the qgraph node is a PCI bus rather than an I2C bus, and exercising DMA needs a guest-memory allocator.
  • Migration state (VMStateDescription) review.
  • A rebase onto current master; the fork is based on v11.0.0-rc1.

Consider offering the specification first and gauging the response before investing in the full submission. The two .rst files above are exactly what such a first posting would contain, so this option is now cheap to exercise.

Track 5, Linux kernel drivers (blocked on track 3)

  • src/cnuasnic/kernel/cnuas_net.c - netdev driver, to netdev@vger.kernel.org
  • src/cnuasnic/kernel/cnuas_ib.c - RDMA driver (5574 lines), to linux-rdma@vger.kernel.org

Realistically the RDMA driver is the hardest item in this document. Upstream RDMA maintainers have historically been resistant to drivers for devices that cannot be bought, and rdma-core requires a matching userspace provider (track 6) to be accepted in lockstep. Expect this to be a long conversation, and expect the question "who else can run this?" to be the crux of it.

Prerequisites:

  • Official PCI IDs (track 3).
  • scripts/checkpatch.pl clean against the kernel tree, not QEMU's.
  • The device specification from track 4, since the same interface is involved.
  • Resolution of hinic-ib-umad-chardev; a driver whose MAD path does not create /dev/infiniband/umadN will not survive review.

Ask before building the RFC

Because "who else can run this?" is the crux and it is a question about appetite rather than about code quality, it should be asked before the driver is polished for review, not after. upstream/linux-rdma-driver-id/ holds an RFC email to Jason Gunthorpe and Leon Romanovsky that does exactly that. If the answer is no, a large amount of work is saved; if it is yes, the reply will say what the driver has to look like.

The RFC states the objections as plainly as the arguments - no users, a frozen UAPI driver ID that cannot be withdrawn, and drift against the QEMU model - because the maintainers will raise them regardless, and pre-empting them is cheaper than being corrected. The argument it does make is that this differs from rxe and siw: those implement verbs in software, whereas this models a device interface, so it exercises the doorbell, queue and MMIO paths that they by construction do not.

The driver-ID patch itself is written and checkpatch-clean under --strict:

  • upstream/linux-rdma-driver-id/0001-RDMA-uapi-add-RDMA_DRIVER_CNUAS-driver-ID.patch

Do not send that patch on its own. A driver ID with no driver behind it is not useful to anyone, and unlike everything else in this document it becomes frozen kernel UAPI the moment it is accepted. It belongs as patch 1 of the eventual driver series, and it is included in the RFC only to show what it looks like.

Track 6, rdma-core provider (blocked on track 5)

src/cnuasnic/rdma-core/ holds the userspace provider. rdma-core will not take a provider for a kernel driver that is not upstream, so this strictly follows track 5.


Track 7, OpenBMC meta-cnuas layer (RFC ready, no blockers)

bmc/meta-cnuas/ adds three AST2600 machines (cnuas-sled, cnuas-tor, cnuas-rmc) on top of meta-aspeed and meta-phosphor. All three images build and boot, and the RMC reads the ORv3 power shelf over the emulated RS-485 segment and publishes it on Redfish.

Like track 5, this starts with a question rather than with code, because the answer may be no. upstream/openbmc-meta-cnuas/RFC-email.txt is generated and can be sent today.

The gating question

OpenBMC has no written policy on emulated-only machines, for or against. The precedent that helps is meta-evb/meta-evb-arm/meta-evb-fvp-base, a pure ARM Fixed Virtual Platform simulation carried in tree and listed in supported-machines.md as machine fvp. The distinction that hurts is that fvp simulates real ARM IP and evb-ast2600 is a board ASPEED sells, whereas the Cnuas machines simulate a system that does not exist in any form.

hw-vendor-repos-policy.md criterion 5 is "generally useful to the OpenBMC organization", decided by the TOF, and criterion 6 needs a named maintainer. The honest framing is not "our product" but "a topology the project cannot currently CI-test at all".

Structure, if the answer is yes

Not a top-level meta-cnuas. meta-evb/README.md reserves company layers for BSPs supporting "a hardware device in a system", which this is not, so the right home is meta-evb/meta-evb-cnuas/, mirroring meta-evb-fvp-base. Probably one machine first, the RMC, since it is the one that demonstrates something new.

Mechanism

Gerrit, not GitHub PRs. gerrit.openbmc.org (note .gitreview in the tree still names the old gerrit.openbmc-project.xyz). Both a signed CLA and a DCO Signed-off-by are required; people commonly get that wrong and assume one or the other.

What goes elsewhere

Piece Correct destination Why
cnuas-rackmond openbmc/phosphor-modbus meta-layer-guidelines.md rule 8 forbids compiled code in meta layers. That repo already has an rtu/ transport and a mocked_test_device/.
cnuas-sled.json openbmc/entity-manager Configs are upstreamed there, by vendor directory. configurations/ocp/ already exists.
aspeed-bmc-cnuas-*.dts probably nowhere No new compatible strings, and the only consumer is an emulator. Carry in-layer as meta-hpe/meta-dl360poc does. Ask on the list before approaching devicetree@vger.kernel.org.
aspeed GPIO fix qemu-devel Already track 1.

There is no rackmon in openbmc/openbmc; it lives in facebook/openbmc, which is a different project with a GitHub PR workflow. Contributing there would not get anything into OpenBMC.

Licensing, which gates this

The repository LICENSE is Apache-2.0 plus an amendment rider adding geographic restrictions. That is not OSI open source (it fails the non-discrimination criteria) and is not Apache-2.0 compatible, while hw-vendor-repos-policy.md criterion 1 requires Apache-2.0 compatibility. Since Packet Five holds the copyright it can contribute the same code upstream under plain Apache-2.0 with no rider, which is what the RFC states. Nothing carrying the rider can be dropped into an OpenBMC tree as-is.

Before proposing anything for merge

  • [ ] Run yocto-check-layer, never yet run.
  • [ ] Fix LAYERSERIES_COMPAT: currently scarthgap styhead walnascar whinlatter wrynose blacksail, while meta-phosphor and meta-aspeed both declare wrynose whinlatter.
  • [ ] Add an OWNERS file, criterion 6.
  • [ ] Add Robot Framework tests; README.md expects contributions to include tests.
  • [ ] Rework cnuas-rackmond out of the layer.

Already fine: both bbappends set configuration only and patch nothing, so meta-layer-guidelines.md rule 1 is satisfied.

Contacts

openbmc@lists.ozlabs.org, Discord #openbmc. phosphor-modbus owners are Patrick Williams and Jagpal Singh Gill, both current TOF members.


Status summary

Everything marked "generated" below has its actual bytes in upstream/, with send commands in upstream/README.md.

Track Item Blocked by Ready?
1 aspeed GPIO fix - generated, on upstream master: checkpatch clean, 3/3 tests, fails without the fix
2 CMIS optical module - generated, on upstream master: checkpatch clean, builds, 4/4 qtests
3 PCI ID request email - generated, upstream/pci-id-request/email.txt
4 QEMU Cnuas devices track 3, qtests specs done, rest no
5 Linux kernel drivers track 3, hinic-ib-umad-chardev RFC generated; driver itself no
6 rdma-core provider track 5 no
7 OpenBMC meta-cnuas layer - RFC generated, upstream/openbmc-meta-cnuas/RFC-email.txt

Tracks 1, 2 and 3 can all be sent today and are independent of each other. Track 5's RFC can also be sent today, since it asks a question rather than proposing code, and its answer determines whether tracks 5 and 6 are worth pursuing at all. Track 7's RFC is the same shape and is likewise sendable now.