As a starting point a trivial way to model this in the XML will be:
<controller type='nvme' index='1' model='nvme'>
And then add the storage into it as:
<disk type='file' device='disk'>
<source dev='/Host/QEMUGuest1.qcow2'/>
<target dev='sda' bus='nvme'/>
'target dev' is how the device appears in the guest, right? It should be
something like 'nvme0n1'. I'm not sure though this is something that we can
put here anyway, I think the guest driver can number controllers arbitrarily.
Maybe we should specify something like BDF? Or is this something QEMU will
have to figure out how to do?
<address type='drive' controller='1'
bus='0' target='0' unit='0'/>
</disk>
<disk type='file' device='disk'>
<source dev='/Host/QEMUGuest2.qcow2'/>
<target dev='sdb' bus='nvme'/>
<address type='drive' controller='1' bus='0'
target='0' unit='1'/>
</disk>
The 'drive' address here maps the disk to the controller. This example
uses unit= as the way to specify the namespace ID. Both 'bus' and
'target'
must be 0.
You can theoretically also add your own address type if 'drive' doesn't
look right.
This model will have problems with hotplug/unplug if the NVMe spec
doesn't actually allow hotplug of a single namespace into a controller
as libvirt's hotplug APIs only deal with one element at time.
The NVMe spec does allow hotplug/unplug of namespaces, so libvirt should be
fine supporting this?