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


Reply via email to