runtime-rs: Enable virtio-net-ccw for s390x

When using `virtio-net-pci` for IBM SE, the following error occurs:

```
update interface: Link not found (Address: f2:21:48:25:f4:10)
```

On s390x, it is more appropriate to use the CCW type of virtio
network device.
This commit ensures that a subchannel is configured accordingly.

Signed-off-by: Hyounggyu Choi <Hyounggyu.Choi@ibm.com>
This commit is contained in:
Hyounggyu Choi 2025-02-28 15:54:59 +01:00
parent 59c1f0b59b
commit e8aa5a5ab7
2 changed files with 30 additions and 7 deletions

View File

@ -387,7 +387,7 @@ enum CcwError {
/// Represents a CCW subchannel for managing devices /// Represents a CCW subchannel for managing devices
#[derive(Debug)] #[derive(Debug)]
struct CcwSubChannel { pub struct CcwSubChannel {
devices: HashMap<String, u32>, // Maps device IDs to slot indices devices: HashMap<String, u32>, // Maps device IDs to slot indices
addr: u32, // Subchannel address addr: u32, // Subchannel address
next_slot: u32, // Next available slot index next_slot: u32, // Next available slot index
@ -1219,17 +1219,26 @@ pub struct DeviceVirtioNet {
num_queues: u32, num_queues: u32,
iommu_platform: bool, iommu_platform: bool,
bus_type: VirtioBusType,
devno: Option<String>,
} }
impl DeviceVirtioNet { impl DeviceVirtioNet {
fn new(netdev_id: &str, mac_address: Address) -> DeviceVirtioNet { fn new(
netdev_id: &str,
mac_address: Address,
bus_type: VirtioBusType,
devno: Option<String>,
) -> DeviceVirtioNet {
DeviceVirtioNet { DeviceVirtioNet {
device_driver: "virtio-net-pci".to_owned(), device_driver: format!("virtio-net-{}", bus_type),
netdev_id: netdev_id.to_owned(), netdev_id: netdev_id.to_owned(),
mac_address, mac_address,
disable_modern: false, disable_modern: false,
num_queues: 1, num_queues: 1,
iommu_platform: false, iommu_platform: false,
bus_type,
devno,
} }
} }
@ -1287,8 +1296,14 @@ impl ToQemuParams for DeviceVirtioNet {
params.push("iommu_platform=on".to_owned()); params.push("iommu_platform=on".to_owned());
} }
if let Some(devno) = &self.devno {
params.push(format!("devno={}", devno));
}
params.push("mq=on".to_owned()); params.push("mq=on".to_owned());
params.push(format!("vectors={}", 2 * self.num_queues + 2)); if self.bus_type == VirtioBusType::Pci {
params.push(format!("vectors={}", 2 * self.num_queues + 2));
}
Ok(vec!["-device".to_owned(), params.join(",")]) Ok(vec!["-device".to_owned(), params.join(",")])
} }
@ -2099,8 +2114,12 @@ impl<'a> QemuCmdLine<'a> {
} }
pub fn add_network_device(&mut self, host_dev_name: &str, guest_mac: Address) -> Result<()> { pub fn add_network_device(&mut self, host_dev_name: &str, guest_mac: Address) -> Result<()> {
let (netdev, virtio_net_device) = let (netdev, virtio_net_device) = get_network_device(
get_network_device(self.config, host_dev_name, guest_mac)?; self.config,
host_dev_name,
guest_mac,
&mut self.ccw_subchannel,
)?;
self.devices.push(Box::new(netdev)); self.devices.push(Box::new(netdev));
self.devices.push(Box::new(virtio_net_device)); self.devices.push(Box::new(virtio_net_device));
@ -2217,6 +2236,7 @@ pub fn get_network_device(
config: &HypervisorConfig, config: &HypervisorConfig,
host_dev_name: &str, host_dev_name: &str,
guest_mac: Address, guest_mac: Address,
ccw_subchannel: &mut Option<CcwSubChannel>,
) -> Result<(Netdev, DeviceVirtioNet)> { ) -> Result<(Netdev, DeviceVirtioNet)> {
let mut netdev = Netdev::new( let mut netdev = Netdev::new(
&format!("network-{}", host_dev_name), &format!("network-{}", host_dev_name),
@ -2227,7 +2247,9 @@ pub fn get_network_device(
netdev.set_disable_vhost_net(true); netdev.set_disable_vhost_net(true);
} }
let mut virtio_net_device = DeviceVirtioNet::new(&netdev.id, guest_mac); let devno = get_devno_ccw(ccw_subchannel, &netdev.id);
let mut virtio_net_device =
DeviceVirtioNet::new(&netdev.id, guest_mac, bus_type(config), devno);
if should_disable_modern() { if should_disable_modern() {
virtio_net_device.set_disable_modern(true); virtio_net_device.set_disable_modern(true);

View File

@ -591,6 +591,7 @@ impl QemuInner {
&self.config, &self.config,
&network_device.config.host_dev_name, &network_device.config.host_dev_name,
network_device.config.guest_mac.clone().unwrap(), network_device.config.guest_mac.clone().unwrap(),
&mut None,
)?; )?;
qmp.hotplug_network_device(&netdev, &virtio_net_device)? qmp.hotplug_network_device(&netdev, &virtio_net_device)?
} }