On Wed, Aug 19, 2026 at 10:04:42AM +0200, Luigi Leonardi wrote: > The correct way to register an NVMe namespace in fw_boot_order is to use > the NVMe controller as the device pointer with the namespace ID appended > as a suffix, producing: > > /pci@i0cf8/pci1b36,0010@4/namespace@1,0 > > This is how the controller-level bootindex works. > Explicit nvme-ns devices instead register the nvme-ns device itself, > which is wrong: realize() reparents the namespace onto the NVMe subsystem > bus, disconnecting it from the controller in the bus hierarchy. > qdev_get_fw_dev_path() therefore produces a path without the controller's > address: > > /nvme-ns/namespace@1,0 > > Fix by re-registering in realize(), once the controller and final nsid > are known, using the controller as the device pointer with the namespace > suffix. The old entry (registered against the nvme-ns device) must be > removed first since add_boot_device_path() only removes entries matching > the same device pointer, and leaving both would cause a > duplicate-bootindex error. > > device_add_bootindex_property() cannot be called in realize() because > QEMU parses command-line properties before realize() runs, so the > bootindex property must exist by instance_init() time. The final nsid is > not yet known then either as it's assigned in realize(). > > The fix is restricted to non-shared namespaces: for shared namespaces > there is no single controller to register the boot path against. > > Also add the symmetric unrealize() cleanup so that hot-unplugging a > non-shared nvme-ns with a bootindex removes the fw_boot_order entry that > was registered against the controller in realize(). > > Reported-by: Gerd Hoffmann <[email protected]> > Signed-off-by: Luigi Leonardi <[email protected]>
Reviewed-by: Gerd Hoffmann <[email protected]> take care, Gerd
