qemu: Add disable-modern option for virtio devices

For some cases, we have to disable the fast MMIO support, by disabling
virtio 1.0. The reason for this is that we want to be able to nest our
qemu VM inside a VM run by an hypervisor with no support for fast MMIO.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2017-08-16 02:21:20 -07:00
parent 8d617ff5b9
commit e74aeef1ad
2 changed files with 70 additions and 35 deletions

30
qemu.go
View File

@ -202,6 +202,9 @@ type FSDevice struct {
// SecurityModel is the security model for this filesystem device. // SecurityModel is the security model for this filesystem device.
SecurityModel SecurityModelType SecurityModel SecurityModelType
// DisableModern prevents qemu from relying on fast MMIO.
DisableModern bool
} }
// Valid returns true if the FSDevice structure is valid and complete. // Valid returns true if the FSDevice structure is valid and complete.
@ -220,6 +223,9 @@ func (fsdev FSDevice) QemuParams(config *Config) []string {
var qemuParams []string var qemuParams []string
deviceParams = append(deviceParams, fmt.Sprintf("%s", fsdev.Driver)) deviceParams = append(deviceParams, fmt.Sprintf("%s", fsdev.Driver))
if fsdev.DisableModern {
deviceParams = append(deviceParams, ",disable-modern=true")
}
deviceParams = append(deviceParams, fmt.Sprintf(",fsdev=%s", fsdev.ID)) deviceParams = append(deviceParams, fmt.Sprintf(",fsdev=%s", fsdev.ID))
deviceParams = append(deviceParams, fmt.Sprintf(",mount_tag=%s", fsdev.MountTag)) deviceParams = append(deviceParams, fmt.Sprintf(",mount_tag=%s", fsdev.MountTag))
@ -276,6 +282,9 @@ type CharDevice struct {
ID string ID string
Path string Path string
Name string Name string
// DisableModern prevents qemu from relying on fast MMIO.
DisableModern bool
} }
// Valid returns true if the CharDevice structure is valid and complete. // Valid returns true if the CharDevice structure is valid and complete.
@ -294,6 +303,9 @@ func (cdev CharDevice) QemuParams(config *Config) []string {
var qemuParams []string var qemuParams []string
deviceParams = append(deviceParams, fmt.Sprintf("%s", cdev.Driver)) deviceParams = append(deviceParams, fmt.Sprintf("%s", cdev.Driver))
if cdev.DisableModern {
deviceParams = append(deviceParams, ",disable-modern=true")
}
if cdev.Bus != "" { if cdev.Bus != "" {
deviceParams = append(deviceParams, fmt.Sprintf(",bus=%s", cdev.Bus)) deviceParams = append(deviceParams, fmt.Sprintf(",bus=%s", cdev.Bus))
} }
@ -366,6 +378,9 @@ type NetDevice struct {
// MACAddress is the networking device interface MAC address. // MACAddress is the networking device interface MAC address.
MACAddress string MACAddress string
// DisableModern prevents qemu from relying on fast MMIO.
DisableModern bool
} }
// Valid returns true if the NetDevice structure is valid and complete. // Valid returns true if the NetDevice structure is valid and complete.
@ -394,6 +409,9 @@ func (netdev NetDevice) QemuParams(config *Config) []string {
deviceParams = append(deviceParams, "driver=") deviceParams = append(deviceParams, "driver=")
} }
deviceParams = append(deviceParams, fmt.Sprintf("%s", netdev.Driver)) deviceParams = append(deviceParams, fmt.Sprintf("%s", netdev.Driver))
if netdev.DisableModern {
deviceParams = append(deviceParams, ",disable-modern=true")
}
deviceParams = append(deviceParams, fmt.Sprintf(",netdev=%s", netdev.ID)) deviceParams = append(deviceParams, fmt.Sprintf(",netdev=%s", netdev.ID))
deviceParams = append(deviceParams, fmt.Sprintf(",mac=%s", netdev.MACAddress)) deviceParams = append(deviceParams, fmt.Sprintf(",mac=%s", netdev.MACAddress))
@ -454,6 +472,9 @@ type SerialDevice struct {
// ID is the serial device identifier. // ID is the serial device identifier.
ID string ID string
// DisableModern prevents qemu from relying on fast MMIO.
DisableModern bool
} }
// Valid returns true if the SerialDevice structure is valid and complete. // Valid returns true if the SerialDevice structure is valid and complete.
@ -471,6 +492,9 @@ func (dev SerialDevice) QemuParams(config *Config) []string {
var qemuParams []string var qemuParams []string
deviceParams = append(deviceParams, fmt.Sprintf("%s", dev.Driver)) deviceParams = append(deviceParams, fmt.Sprintf("%s", dev.Driver))
if dev.DisableModern {
deviceParams = append(deviceParams, ",disable-modern=true")
}
deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", dev.ID)) deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", dev.ID))
qemuParams = append(qemuParams, "-device") qemuParams = append(qemuParams, "-device")
@ -519,6 +543,9 @@ type BlockDevice struct {
Format BlockDeviceFormat Format BlockDeviceFormat
SCSI bool SCSI bool
WCE bool WCE bool
// DisableModern prevents qemu from relying on fast MMIO.
DisableModern bool
} }
// Valid returns true if the BlockDevice structure is valid and complete. // Valid returns true if the BlockDevice structure is valid and complete.
@ -537,6 +564,9 @@ func (blkdev BlockDevice) QemuParams(config *Config) []string {
var qemuParams []string var qemuParams []string
deviceParams = append(deviceParams, fmt.Sprintf("%s", blkdev.Driver)) deviceParams = append(deviceParams, fmt.Sprintf("%s", blkdev.Driver))
if blkdev.DisableModern {
deviceParams = append(deviceParams, ",disable-modern=true")
}
deviceParams = append(deviceParams, fmt.Sprintf(",drive=%s", blkdev.ID)) deviceParams = append(deviceParams, fmt.Sprintf(",drive=%s", blkdev.ID))
if blkdev.SCSI == false { if blkdev.SCSI == false {
deviceParams = append(deviceParams, ",scsi=off") deviceParams = append(deviceParams, ",scsi=off")

View File

@ -104,7 +104,7 @@ func TestAppendDeviceNVDIMM(t *testing.T) {
testAppend(object, deviceNVDIMMString, t) testAppend(object, deviceNVDIMMString, t)
} }
var deviceFSString = "-device virtio-9p-pci,fsdev=workload9p,mount_tag=rootfs -fsdev local,id=workload9p,path=/var/lib/docker/devicemapper/mnt/e31ebda2,security_model=none" var deviceFSString = "-device virtio-9p-pci,disable-modern=true,fsdev=workload9p,mount_tag=rootfs -fsdev local,id=workload9p,path=/var/lib/docker/devicemapper/mnt/e31ebda2,security_model=none"
func TestAppendDeviceFS(t *testing.T) { func TestAppendDeviceFS(t *testing.T) {
fsdev := FSDevice{ fsdev := FSDevice{
@ -114,12 +114,13 @@ func TestAppendDeviceFS(t *testing.T) {
Path: "/var/lib/docker/devicemapper/mnt/e31ebda2", Path: "/var/lib/docker/devicemapper/mnt/e31ebda2",
MountTag: "rootfs", MountTag: "rootfs",
SecurityModel: None, SecurityModel: None,
DisableModern: true,
} }
testAppend(fsdev, deviceFSString, t) testAppend(fsdev, deviceFSString, t)
} }
var deviceNetworkString = "-device virtio-net,netdev=tap0,mac=01:02:de:ad:be:ef -netdev tap,id=tap0,ifname=ceth0,downscript=no,script=no,fds=3:4,vhost=on" var deviceNetworkString = "-device virtio-net,disable-modern=true,netdev=tap0,mac=01:02:de:ad:be:ef -netdev tap,id=tap0,ifname=ceth0,downscript=no,script=no,fds=3:4,vhost=on"
func TestAppendDeviceNetwork(t *testing.T) { func TestAppendDeviceNetwork(t *testing.T) {
foo, _ := ioutil.TempFile(os.TempDir(), "qemu-ciao-test") foo, _ := ioutil.TempFile(os.TempDir(), "qemu-ciao-test")
@ -138,12 +139,13 @@ func TestAppendDeviceNetwork(t *testing.T) {
FDs: []*os.File{foo, bar}, FDs: []*os.File{foo, bar},
VHost: true, VHost: true,
MACAddress: "01:02:de:ad:be:ef", MACAddress: "01:02:de:ad:be:ef",
DisableModern: true,
} }
testAppend(netdev, deviceNetworkString, t) testAppend(netdev, deviceNetworkString, t)
} }
var deviceNetworkPCIString = "-device driver=virtio-net-pci,netdev=tap0,mac=01:02:de:ad:be:ef,bus=/pci-bus/pcie.0,addr=ff -netdev tap,id=tap0,ifname=ceth0,downscript=no,script=no,fds=3:4,vhost=on" var deviceNetworkPCIString = "-device driver=virtio-net-pci,disable-modern=true,netdev=tap0,mac=01:02:de:ad:be:ef,bus=/pci-bus/pcie.0,addr=ff -netdev tap,id=tap0,ifname=ceth0,downscript=no,script=no,fds=3:4,vhost=on"
func TestAppendDeviceNetworkPCI(t *testing.T) { func TestAppendDeviceNetworkPCI(t *testing.T) {
foo, _ := ioutil.TempFile(os.TempDir(), "qemu-ciao-test") foo, _ := ioutil.TempFile(os.TempDir(), "qemu-ciao-test")
@ -164,17 +166,19 @@ func TestAppendDeviceNetworkPCI(t *testing.T) {
FDs: []*os.File{foo, bar}, FDs: []*os.File{foo, bar},
VHost: true, VHost: true,
MACAddress: "01:02:de:ad:be:ef", MACAddress: "01:02:de:ad:be:ef",
DisableModern: true,
} }
testAppend(netdev, deviceNetworkPCIString, t) testAppend(netdev, deviceNetworkPCIString, t)
} }
var deviceSerialString = "-device virtio-serial-pci,id=serial0" var deviceSerialString = "-device virtio-serial-pci,disable-modern=true,id=serial0"
func TestAppendDeviceSerial(t *testing.T) { func TestAppendDeviceSerial(t *testing.T) {
sdev := SerialDevice{ sdev := SerialDevice{
Driver: VirtioSerial, Driver: VirtioSerial,
ID: "serial0", ID: "serial0",
DisableModern: true,
} }
testAppend(sdev, deviceSerialString, t) testAppend(sdev, deviceSerialString, t)
@ -195,7 +199,7 @@ func TestAppendDeviceSerialPort(t *testing.T) {
testAppend(chardev, deviceSerialPortString, t) testAppend(chardev, deviceSerialPortString, t)
} }
var deviceBlockString = "-device virtio-blk,drive=hd0,scsi=off,config-wce=off -drive id=hd0,file=/var/lib/ciao.img,aio=threads,format=qcow2,if=none" var deviceBlockString = "-device virtio-blk,disable-modern=true,drive=hd0,scsi=off,config-wce=off -drive id=hd0,file=/var/lib/ciao.img,aio=threads,format=qcow2,if=none"
func TestAppendDeviceBlock(t *testing.T) { func TestAppendDeviceBlock(t *testing.T) {
blkdev := BlockDevice{ blkdev := BlockDevice{
@ -207,6 +211,7 @@ func TestAppendDeviceBlock(t *testing.T) {
Interface: NoInterface, Interface: NoInterface,
SCSI: false, SCSI: false,
WCE: false, WCE: false,
DisableModern: true,
} }
testAppend(blkdev, deviceBlockString, t) testAppend(blkdev, deviceBlockString, t)