diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 7f0cbf4621..905f08ff9f 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -5,6 +5,7 @@ revision history in source control. Contributors who wish to be recognized in this file should add themselves (or their employer, as appropriate). +- afrosi@de.ibm.com - archana.m.shinde@intel.com - eric.ernst@intel.com - james.o.hunt@intel.com diff --git a/qemu/qemu.go b/qemu/qemu.go index 7acc3c2559..8bd6afbef0 100644 --- a/qemu/qemu.go +++ b/qemu/qemu.go @@ -65,6 +65,9 @@ const ( // VirtioNetPCI is the virt-io pci networking device driver. VirtioNetPCI DeviceDriver = "virtio-net-pci" + // VirtioNetCCW is the virt-io ccw networking device driver. + VirtioNetCCW DeviceDriver = "virtio-net-ccw" + // VirtioBlock is the block device driver. VirtioBlock DeviceDriver = "virtio-blk" diff --git a/qemu/qemu_s390x.go b/qemu/qemu_s390x.go new file mode 100644 index 0000000000..d8395837fc --- /dev/null +++ b/qemu/qemu_s390x.go @@ -0,0 +1,115 @@ +// +build s390x + +/* +// Copyright contributors to the Virtual Machine Manager for Go project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ + +package qemu + +import "log" + +// IBM Z uses CCW devices intead of PCI devices. +// See https://wiki.qemu.org/Documentation/Platforms/S390X +const ( + // Virtio9P is the 9pfs device driver. + Virtio9P DeviceDriver = "virtio-9p-ccw" + + // VirtioSerial is the serial device driver. + VirtioSerial DeviceDriver = "virtio-serial-ccw" + + // VirtioNet is the virt-io ccw networking device driver. + VirtioNet DeviceDriver = VirtioNetCCW + + // Vfio is the vfio driver + Vfio DeviceDriver = "vfio-ccw" + + // VirtioScsi is the virtio-scsi device + VirtioScsi DeviceDriver = "virtio-scsi-ccw" + + // VHostVSock is a generic Vsock Device + VHostVSock DeviceDriver = "vhost-vsock-ccw" +) + +// isVirtioPCI is a fake map on s390x to always avoid the "romfile" +// option +var isVirtioPCI = map[DeviceDriver]bool{ + NVDIMM: false, + Virtio9P: false, + VirtioNetCCW: false, + VirtioSerial: false, + VirtioBlock: false, + Console: false, + VirtioSerialPort: false, + VHostVSock: false, + VirtioRng: false, + VirtioBalloon: false, + VhostUserSCSI: false, + VhostUserBlk: false, + Vfio: false, + VirtioScsi: false, + PCIBridgeDriver: false, + PCIePCIBridgeDriver: false, +} + +// QemuDeviceParam converts to the QEMU -device parameter notation +// This function has been reimplemented for the s390x architecture to deal +// with the VHOSTUSER case. Vhost user devices are not implemented on s390x +// architecture. For further details see issue +// https://github.com/kata-containers/runtime/issues/659 +func (n NetDeviceType) QemuDeviceParam() string { + switch n { + case TAP: + return string(VirtioNet) + case MACVTAP: + return string(VirtioNet) + case IPVTAP: + return string(VirtioNet) + case VETHTAP: + return string(VirtioNet) + case VFIO: + return string(Vfio) + case VHOSTUSER: + log.Fatal("vhost-user devices are not supported on IBM Z") + return "" + default: + return "" + } +} + +// QemuNetdevParam converts to the QEMU -netdev parameter notation +// This function has been reimplemented for the s390x architecture to deal +// with the VHOSTUSER case. Vhost user devices are not implemented on s390x +// architecture. For further details see issue +// https://github.com/kata-containers/runtime/issues/659 +func (n NetDeviceType) QemuNetdevParam() string { + switch n { + case TAP: + return "tap" + case MACVTAP: + return "tap" + case IPVTAP: + return "tap" + case VETHTAP: + return "tap" + case VFIO: + return "" + case VHOSTUSER: + log.Fatal("vhost-user devices are not supported on IBM Z") + return "" + default: + return "" + + } +} diff --git a/qemu/qemu_s390x_test.go b/qemu/qemu_s390x_test.go new file mode 100644 index 0000000000..b76af3ced5 --- /dev/null +++ b/qemu/qemu_s390x_test.go @@ -0,0 +1,57 @@ +// +build s390x + +/* +// Copyright contributors to the Virtual Machine Manager for Go project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ + +package qemu + +import "testing" + +// -pci devices don't play well with Z hence replace them with corresponding -ccw devices +// See https://wiki.qemu.org/Documentation/Platforms/S390X +var ( + deviceFSString = "-device virtio-9p-ccw,fsdev=workload9p,mount_tag=rootfs -fsdev local,id=workload9p,path=/var/lib/docker/devicemapper/mnt/e31ebda2,security_model=none" + deviceNetworkString = "-netdev tap,id=tap0,vhost=on,ifname=ceth0,downscript=no,script=no -device driver=virtio-net-ccw,netdev=tap0,mac=01:02:de:ad:be:ef" + deviceNetworkStringMq = "-netdev tap,id=tap0,vhost=on,fds=3:4 -device driver=virtio-net-ccw,netdev=tap0,mac=01:02:de:ad:be:ef,mq=on" + deviceNetworkPCIString = "-netdev tap,id=tap0,vhost=on,ifname=ceth0,downscript=no,script=no -device driver=virtio-net-ccw,netdev=tap0,mac=01:02:de:ad:be:ef,bus=/pci-bus/pcie.0,addr=ff" + deviceNetworkPCIStringMq = "-netdev tap,id=tap0,vhost=on,fds=3:4 -device driver=virtio-net-ccw,netdev=tap0,mac=01:02:de:ad:be:ef,bus=/pci-bus/pcie.0,addr=ff,mq=on" + deviceSerialString = "-device virtio-serial-ccw,id=serial0" + deviceVSOCKString = "-device vhost-vsock-ccw,id=vhost-vsock-pci0,guest-cid=4" + deviceVFIOString = "-device vfio-ccw,host=02:10.0" + deviceSCSIControllerStr = "-device virtio-scsi-ccw,id=foo" + deviceSCSIControllerBusAddrStr = "-device virtio-scsi-ccw,id=foo,bus=pci.0,addr=00:04.0,iothread=iothread1" + deviceBlockString = "-device virtio-blk,drive=hd0,scsi=off,config-wce=off -drive id=hd0,file=/var/lib/vm.img,aio=threads,format=qcow2,if=none" + devicePCIBridgeString = "-device pci-bridge,bus=/pci-bus/pcie.0,id=mybridge,chassis_nr=5,shpc=on,addr=ff" + devicePCIEBridgeString = "-device pcie-pci-bridge,bus=/pci-bus/pcie.0,id=mybridge,addr=ff" + romfile = "" +) + +func TestAppendVirtioBalloon(t *testing.T) { + balloonDevice := BalloonDevice{ + ID: "balloon", + } + + var deviceString = "-device " + string(VirtioBalloon) + deviceString += ",id=" + balloonDevice.ID + + var OnDeflateOnOMM = ",deflate-on-oom=on" + var OffDeflateOnOMM = ",deflate-on-oom=off" + + testAppend(balloonDevice, deviceString+OffDeflateOnOMM, t) + + balloonDevice.DeflateOnOOM = true + testAppend(balloonDevice, deviceString+OnDeflateOnOMM, t) +} diff --git a/qemu/qmp.go b/qemu/qmp.go index ef56415fbe..98371e579f 100644 --- a/qemu/qmp.go +++ b/qemu/qmp.go @@ -971,6 +971,26 @@ func (q *QMP) ExecuteNetPCIDeviceAdd(ctx context.Context, netdevID, devID, macAd return q.executeCommand(ctx, "device_add", args, nil) } +// ExecuteNetCCWDeviceAdd adds a Net CCW device to a QEMU instance +// using the device_add command. devID is the id of the device to add. +// Must be valid QMP identifier. netdevID is the id of nic added by previous netdev_add. +// queues is the number of queues of a nic. +func (q *QMP) ExecuteNetCCWDeviceAdd(ctx context.Context, netdevID, devID, macAddr, addr, bus string, queues int) error { + args := map[string]interface{}{ + "id": devID, + "driver": VirtioNetCCW, + "netdev": netdevID, + "mac": macAddr, + "addr": addr, + } + + if queues > 0 { + args["mq"] = "on" + } + + return q.executeCommand(ctx, "device_add", args, nil) +} + // ExecuteDeviceDel deletes guest portion of a QEMU device by sending a // device_del command. devId is the identifier of the device to delete. // Typically it would match the devID parameter passed to an earlier call diff --git a/qemu/qmp_test.go b/qemu/qmp_test.go index a28e0e91c9..270c473136 100644 --- a/qemu/qmp_test.go +++ b/qemu/qmp_test.go @@ -536,6 +536,22 @@ func TestQMPNetPCIDeviceAdd(t *testing.T) { <-disconnectedCh } +func TestQMPNetCCWDeviceAdd(t *testing.T) { + connectedCh := make(chan *QMPVersion) + disconnectedCh := make(chan struct{}) + buf := newQMPTestCommandBuffer(t) + buf.AddCommand("device_add", nil, "return", nil) + cfg := QMPConfig{Logger: qmpTestLogger{}} + q := startQMPLoop(buf, cfg, connectedCh, disconnectedCh) + checkVersion(t, connectedCh) + err := q.ExecuteNetCCWDeviceAdd(context.Background(), "br0", "virtio-0", "02:42:ac:11:00:02", "0x7", "", 8) + if err != nil { + t.Fatalf("Unexpected error %v", err) + } + q.Shutdown() + <-disconnectedCh +} + // Checks that the device_add command is correctly sent. // // We start a QMPLoop, send the device_add command and stop the loop.