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.cgained/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 missingMAINTAINERSentry)
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:
- The
linuxsubmodule must be excluded entirely. It vendors Huawei'shinic(88 files) and HiSilicon'shilinkreferences. An unfiltered token pass rewrites 8310 hits there, of which exactly one is ours. The residue outsidedrivers/net/ethernet/{huawei,hisilicon}/is also upstream:reset_hinic_vf_devindrivers/pci/quirks.c, the MAINTAINERS entries, and"Phinic Helix Board"insound/firewire/bebob/bebob.c, wherehinicsits inside an unrelated word. - Our entire footprint in
linuxis one line -RDMA_DRIVER_HICAINatinclude/uapi/rdma/ib_user_ioctl_verbs.h:259, nowRDMA_DRIVER_CNUAS. Edit it by hand; never run the token map against that tree. hicais unsafe as a bare substring. It occurs inside the ordinary wordsgraphical,hierarchical,cryptographically,geographicalandmythical(~71 occurrences), which a literal pass turns intograpcnuasland similar. The camelCase runtime API (hicaMalloc,hicaStreamCreate) therefore has to be matched as\bhica, and a snake-case-onlyhica_token misses ~650 real occurrences.- 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,higpuandHigpu- the last in C type names (HigpuState) and Bazel targets.HiIR(80 hits) was absent from an earlier map whileHiir(0 real hits, matching only "Hiironen" inlinux's CREDITS) was present. - Token ordering must use effective length, ignoring any
re:or\bmarkers, so thathicainandhicartare 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: everyhi_token in theqemutree is upstream code using "hi" for high word (hi_dword,HI_COMMPAGE,HI_XSR), andbmc/firmware'sorv3_regmap.chas a generichi_idx. It is renamed by a second, tightly scoped map that excludes both.libhibecamelibcnuasdevrather thanlibcnuas, because that name was already taken by the NIC provider. git mvrefuses to move a submodule while.gitmodulesis 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--repopaths move out from under the run.- Filenames and link flags drift out of step with contents.
hicasmihad its contents renamed but not its filename, and-lhisurvived in three Makefiles. Only a real build catches these. - A hard-coded prefix length.
cnuas/src/cnuas/adapters/gpu.pyslicedname[5:]to strip"higpu"; the new prefix is eight characters, so device enumeration silently returned nothing. It now derives the offset fromCOMPONENT. 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:
- 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:.gitmoduleshad already been rewritten to theCnuas*URLs, so a recursive clone failed until the renames landed. - The
linuxbranchcnuas-v6.19was 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. - The
cnuas-*tags were pushed additively inlinuxandqemu. The oldhicain-*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_CNUASinlinux/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, ...)insrc/cnuasnic/rdma-core/cnuas.cand aspackaging/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.rstandqemu/docs/specs/cnuasgpu.rstare written, wired intodocs/specs/index.rstandMAINTAINERS, 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.cis 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, tonetdev@vger.kernel.orgsrc/cnuasnic/kernel/cnuas_ib.c- RDMA driver (5574 lines), tolinux-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.plclean 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/umadNwill 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: currentlyscarthgap styhead walnascar whinlatter wrynose blacksail, whilemeta-phosphorandmeta-aspeedboth declarewrynose whinlatter. - [ ] Add an
OWNERSfile, criterion 6. - [ ] Add Robot Framework tests;
README.mdexpects contributions to include tests. - [ ] Rework
cnuas-rackmondout 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.