Handle PCI passthrough and virtio-scsi using hostdev devices.
Example PCI passthrough:
domain xml snippet
```
<memoryBacking>
<locked/>
</memoryBacking>
<devices>
<hostdev mode='subsystem' type='pci'>
<source>
<address domain='0x0000' bus='0x06' slot='0x02'
function='0x00'/>
</source>
<address type='pci' domain='0x0000' bus='0x00'
slot='0x02' function='0x00'/>
</hostdev>
</devices>
```
loader.conf snippet
```
vmm_load="YES"
pptdevs="6/2/0"
```
Example SCSI passthrough:
domain xml snippet
```
<hostdev mode='subsystem' type='scsi_ctl' model='virtio'>
<source protocol='ioctl' pp='5' vp='0'/>
<address type='pci' domain='0x0000' bus='0x00'
slot='0x02' function='0x00'/>
</hostdev>
```
ctl.conf snippet
```
portal-group "pg0" {
discovery-auth-group "no-authentication"
listen "127.0.0.1"
}
target iqn.2020-01.com.example:target0 {
auth-group "no-authentication"
portal-group "pg0"
port ioctl/5/0
lun 0 { path "/dev/zvol/storage/lun0" }
lun 1 { path "/dev/zvol/storage/lun1" }
lun 2 { path "/dev/zvol/storage/lun2" }
lun 3 { path "/dev/zvol/storage/lun3" }
}
```
Signed-off-by: Ryan Moeller <ryan(a)iXsystems.com>
---
docs/schemas/domaincommon.rng | 30 ++++
src/bhyve/bhyve_capabilities.c | 14 ++
src/bhyve/bhyve_capabilities.h | 1 +
src/bhyve/bhyve_command.c | 121 ++++++++++++++++
src/bhyve/bhyve_parse_command.c | 90 ++++++++++++
src/conf/domain_audit.c | 5 +
src/conf/domain_conf.c | 131 ++++++++++++++++++
src/conf/domain_conf.h | 29 +++-
src/conf/virconftypes.h | 3 +
src/qemu/qemu_command.c | 2 +
src/qemu/qemu_domain.c | 5 +
src/qemu/qemu_hostdev.c | 1 +
src/qemu/qemu_hotplug.c | 2 +
src/qemu/qemu_migration.c | 1 +
src/security/security_apparmor.c | 1 +
src/security/security_dac.c | 28 ++++
src/security/security_selinux.c | 8 ++
.../bhyveargv2xml-passthru.args | 8 ++
.../bhyveargv2xml-passthru.xml | 26 ++++
.../bhyveargv2xml-virtio-scsi.args | 9 ++
.../bhyveargv2xml-virtio-scsi.xml | 20 +++
tests/bhyveargv2xmltest.c | 2 +
.../bhyvexml2argv-passthru.args | 11 ++
.../bhyvexml2argv-passthru.ldargs | 1 +
.../bhyvexml2argv-passthru.xml | 22 +++
.../bhyvexml2argv-virtio-scsi.args | 9 ++
.../bhyvexml2argv-virtio-scsi.ldargs | 1 +
.../bhyvexml2argv-virtio-scsi.xml | 21 +++
tests/bhyvexml2argvtest.c | 4 +-
.../bhyvexml2xmlout-passthru.xml | 29 ++++
.../bhyvexml2xmlout-virtio-scsi.xml | 23 +++
tests/bhyvexml2xmltest.c | 2 +
32 files changed, 658 insertions(+), 2 deletions(-)
create mode 100644 tests/bhyveargv2xmldata/bhyveargv2xml-passthru.args
create mode 100644 tests/bhyveargv2xmldata/bhyveargv2xml-passthru.xml
create mode 100644 tests/bhyveargv2xmldata/bhyveargv2xml-virtio-scsi.args
create mode 100644 tests/bhyveargv2xmldata/bhyveargv2xml-virtio-scsi.xml
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-passthru.args
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-passthru.ldargs
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-passthru.xml
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-virtio-scsi.args
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-virtio-scsi.ldargs
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-virtio-scsi.xml
create mode 100644 tests/bhyvexml2xmloutdata/bhyvexml2xmlout-passthru.xml
create mode 100644 tests/bhyvexml2xmloutdata/bhyvexml2xmlout-virtio-scsi.xml
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index c00ace7d9c..e5250e1f32 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -4697,6 +4697,7 @@
</attribute>
</optional>
<choice>
+ <ref name="hostdevsubsysctl"/>
<ref name="hostdevsubsyspci"/>
<ref name="hostdevsubsysusb"/>
<ref name="hostdevsubsysscsi"/>
@@ -4723,6 +4724,34 @@
</define>
+ <define name="hostdevsubsysctl">
+ <attribute name="type">
+ <value>scsi_ctl</value>
+ </attribute>
+ <optional>
+ <attribute name="model">
+ <choice>
+ <value>virtio</value>
+ </choice>
+ </attribute>
+ </optional>
+ <element name="source">
+ <choice>
+ <group>
+ <attribute name="protocol">
+ <value>ioctl</value> <!-- ioctl, required -->
+ </attribute>
+ <attribute name="pp">
+ <data type="unsignedInt"/>
+ </attribute>
+ <attribute name="vp">
+ <data type="unsignedInt"/>
+ </attribute>
+ </group>
+ </choice>
+ </element>
+ </define>
+
<define name="hostdevsubsyspci">
<attribute name="type">
<value>pci</value>
@@ -4734,6 +4763,7 @@
<choice>
<value>kvm</value>
<value>vfio</value>
+ <value>vmm</value>
<value>xen</value>
</choice>
</attribute>
diff --git a/src/bhyve/bhyve_capabilities.c b/src/bhyve/bhyve_capabilities.c
index fb8829d571..fb6be0aaba 100644
--- a/src/bhyve/bhyve_capabilities.c
+++ b/src/bhyve/bhyve_capabilities.c
@@ -323,6 +323,17 @@ bhyveProbeCapsXHCIController(unsigned int *caps, char *binary)
}
+static int
+bhyveProbeCapsVirtioSCSI(unsigned int *caps, char *binary)
+{
+ return bhyveProbeCapsDeviceHelper(caps, binary,
+ "-s",
+ "0,virtio-scsi",
+ "pci slot 0:0: unknown device
\"virtio-scsi\"",
+ BHYVE_CAP_VIRTIOSCSI);
+}
+
+
int
virBhyveProbeCaps(unsigned int *caps)
{
@@ -351,6 +362,9 @@ virBhyveProbeCaps(unsigned int *caps)
if ((ret = bhyveProbeCapsXHCIController(caps, binary)))
goto out;
+ if ((ret = bhyveProbeCapsVirtioSCSI(caps, binary)))
+ goto out;
+
out:
VIR_FREE(binary);
return ret;
diff --git a/src/bhyve/bhyve_capabilities.h b/src/bhyve/bhyve_capabilities.h
index 12926cf423..bb62bdfb15 100644
--- a/src/bhyve/bhyve_capabilities.h
+++ b/src/bhyve/bhyve_capabilities.h
@@ -49,6 +49,7 @@ typedef enum {
BHYVE_CAP_FBUF = 1 << 4,
BHYVE_CAP_XHCI = 1 << 5,
BHYVE_CAP_CPUTOPOLOGY = 1 << 6,
+ BHYVE_CAP_VIRTIOSCSI = 1 << 7,
} virBhyveCapsFlags;
int virBhyveProbeGrubCaps(virBhyveGrubCapsFlags *caps);
diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c
index bf1cfef3ab..dbf6fbf168 100644
--- a/src/bhyve/bhyve_command.c
+++ b/src/bhyve/bhyve_command.c
@@ -366,6 +366,123 @@ bhyveBuildControllerArgStr(const virDomainDef *def,
return 0;
}
+static int
+bhyveBuildHostdevSubsysPCIArgStr(const virDomainDef *def,
+ virDomainHostdevDefPtr dev,
+ bhyveConnPtr driver G_GNUC_UNUSED,
+ virCommandPtr cmd)
+{
+ virDomainHostdevSubsysPCIPtr pcisrc = &dev->source.subsys.u.pci;
+
+ switch (pcisrc->backend) {
+ case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
+ pcisrc->backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VMM;
+ G_GNUC_FALLTHROUGH;
+ case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VMM:
+ if (!def->mem.locked) {
+ /* TODO: maybe just configure it automatically? */
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("guest memory must be locked (wired) for "
+ "PCI passthrough"));
+ return -1;
+ }
+ virCommandAddArg(cmd, "-s");
+ virCommandAddArgFormat(cmd, "%u:%u:%u,passthru,%u/%u/%u",
+ dev->info->addr.pci.bus,
+ dev->info->addr.pci.slot,
+ dev->info->addr.pci.function,
+ pcisrc->addr.bus,
+ pcisrc->addr.slot,
+ pcisrc->addr.function);
+ break;
+ default:
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("unsupported hostdev pci backend"));
+ return -1;
+ }
+ return 0;
+}
+
+static int
+bhyveBuildHostdevSubsysSCSICTLArgStr(const virDomainDef *def G_GNUC_UNUSED,
+ virDomainHostdevDefPtr dev,
+ bhyveConnPtr driver,
+ virCommandPtr cmd)
+{
+ virDomainHostdevSubsysSCSICTLPtr ctlsrc = &dev->source.subsys.u.scsi_ctl;
+
+ /* Actually CAM Target Layer (CTL), not VHost on FreeBSD. */
+ if (!(bhyveDriverGetBhyveCaps(driver) & BHYVE_CAP_VIRTIOSCSI)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Installed bhyve binary does not support "
+ "defining virtio-scsi devices"));
+ return -1;
+ }
+ if (ctlsrc->protocol !=
+ VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_PROTOCOL_TYPE_IOCTL) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("unsupported hostdev scsi_ctl protocol"));
+ return -1;
+ }
+ switch (ctlsrc->model) {
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_MODEL_TYPE_DEFAULT:
+ ctlsrc->model =
+ VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_MODEL_TYPE_VIRTIO;
+ G_GNUC_FALLTHROUGH;
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_MODEL_TYPE_VIRTIO:
+ virCommandAddArg(cmd, "-s");
+ virCommandAddArgFormat(cmd, "%u:%u,virtio-scsi,/dev/cam/ctl%u.%u",
+ dev->info->addr.pci.slot,
+ dev->info->addr.pci.function,
+ ctlsrc->pp, ctlsrc->vp);
+ break;
+ default:
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("unsupported hostdev scsi_ctl model"));
+ return -1;
+ }
+ return 0;
+}
+
+static int
+bhyveBuildHostdevSubsysArgStr(const virDomainDef *def,
+ virDomainHostdevDefPtr dev,
+ bhyveConnPtr driver,
+ virCommandPtr cmd)
+{
+ switch (dev->source.subsys.type) {
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
+ if (bhyveBuildHostdevSubsysPCIArgStr(def, dev, driver, cmd) < 0)
+ return -1;
+ break;
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
+ if (bhyveBuildHostdevSubsysSCSICTLArgStr(def, dev, driver, cmd) < 0)
+ return -1;
+ break;
+ default:
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("unsupported hostdev subsystem type"));
+ return -1;
+ }
+ return 0;
+}
+
+static int
+bhyveBuildHostdevArgStr(const virDomainDef *def,
+ virDomainHostdevDefPtr dev,
+ bhyveConnPtr driver,
+ virCommandPtr cmd)
+{
+ switch (dev->mode) {
+ case VIR_DOMAIN_HOSTDEV_MODE_SUBSYS:
+ return bhyveBuildHostdevSubsysArgStr(def, dev, driver, cmd);
+ default:
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("unsupported hostdev device mode"));
+ return -1;
+ }
+}
+
static int
bhyveBuildLPCArgStr(const virDomainDef *def G_GNUC_UNUSED,
virCommandPtr cmd)
@@ -617,6 +734,10 @@ virBhyveProcessBuildBhyveCmd(bhyveConnPtr driver, virDomainDefPtr
def,
if (bhyveBuildDiskArgStr(def, def->disks[i], cmd) < 0)
goto error;
}
+ for (i = 0; i < def->nhostdevs; i++) {
+ if (bhyveBuildHostdevArgStr(def, def->hostdevs[i], driver, cmd) < 0)
+ goto error;
+ }
if (def->ngraphics && def->nvideos) {
if (def->ngraphics == 1 && def->nvideos == 1) {
diff --git a/src/bhyve/bhyve_parse_command.c b/src/bhyve/bhyve_parse_command.c
index 76423730d9..d69d23ace8 100644
--- a/src/bhyve/bhyve_parse_command.c
+++ b/src/bhyve/bhyve_parse_command.c
@@ -476,6 +476,92 @@ bhyveParsePCIDisk(virDomainDefPtr def,
return -1;
}
+static int
+bhyveParsePCIPassthru(virDomainDefPtr def,
+ unsigned vmbus,
+ unsigned vmslot,
+ unsigned vmfunction,
+ char *config)
+{
+ /* -s bus:slot:function,passthru,BUS/SLOT/FUNCTION */
+ virDomainHostdevDefPtr dev = NULL;
+ virDomainHostdevSubsysPCIPtr pcisrc = NULL;
+ unsigned hostbus, hostslot, hostfunction;
+
+ hostslot = hostbus = hostfunction = 0;
+ if (sscanf(config, "%u/%u/%u", &hostbus, &hostslot,
&hostfunction) != 3)
+ return -1;
+
+ if ((dev = virDomainHostdevDefNew()) == NULL)
+ return -1;
+ dev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+ dev->info->addr.pci.bus = vmbus;
+ dev->info->addr.pci.slot = vmslot;
+ dev->info->addr.pci.function = vmfunction;
+ dev->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
+ dev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
+ pcisrc = &dev->source.subsys.u.pci;
+ pcisrc->backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VMM;
+ pcisrc->addr.bus = hostbus;
+ pcisrc->addr.slot = hostslot;
+ pcisrc->addr.function = hostfunction;
+
+ if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, dev) < 0)
+ goto error;
+
+ return 0;
+
+ error:
+ virDomainHostdevDefFree(dev);
+ return -1;
+}
+
+static int
+bhyveParseSCSICTL(virDomainDefPtr def,
+ unsigned bus,
+ unsigned slot,
+ unsigned function,
+ char *config)
+{
+ /* -s slot,virtio-scsi,[dev=]/dev/cam/ctlPP.VP[,scsi-device-options] */
+ virDomainHostdevDefPtr dev = NULL;
+ virDomainHostdevSubsysSCSICTLPtr ctlsrc = NULL;
+ unsigned pp, vp;
+
+ /* Skip [dev=] if present. */
+ if (STRPREFIX(config, "dev="))
+ config = strchr(config, '=') + 1;
+
+ pp = vp = 0;
+ if (sscanf(config, "/dev/cam/ctl%u.%u", &pp, &vp) != 2)
+ return -1;
+
+ if ((dev = virDomainHostdevDefNew()) == NULL)
+ return -1;
+ dev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+ dev->info->addr.pci.bus = bus;
+ dev->info->addr.pci.slot = slot;
+ dev->info->addr.pci.function = function;
+ dev->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
+ dev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL;
+ ctlsrc = &dev->source.subsys.u.scsi_ctl;
+ ctlsrc->model =
+ VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_MODEL_TYPE_VIRTIO;
+ ctlsrc->protocol =
+ VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_PROTOCOL_TYPE_IOCTL;
+ ctlsrc->pp = pp;
+ ctlsrc->vp = vp;
+
+ if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, dev) < 0)
+ goto error;
+
+ return 0;
+
+ error:
+ virDomainHostdevDefFree(dev);
+ return -1;
+}
+
static int
bhyveParsePCINet(virDomainDefPtr def,
virDomainXMLOptionPtr xmlopt,
@@ -601,6 +687,8 @@ bhyveParseBhyvePCIArg(virDomainDefPtr def,
nvirtiodisk,
nahcidisk,
conf);
+ else if (STREQ(emulation, "passthru"))
+ bhyveParsePCIPassthru(def, bus, slot, function, conf);
else if (STREQ(emulation, "virtio-blk"))
bhyveParsePCIDisk(def, caps, bus, slot, function,
VIR_DOMAIN_DISK_BUS_VIRTIO,
@@ -611,6 +699,8 @@ bhyveParseBhyvePCIArg(virDomainDefPtr def,
else if (STREQ(emulation, "virtio-net"))
bhyveParsePCINet(def, xmlopt, caps, bus, slot, function,
VIR_DOMAIN_NET_MODEL_VIRTIO, conf);
+ else if (STREQ(emulation, "virtio-scsi"))
+ bhyveParseSCSICTL(def, bus, slot, function, conf);
else if (STREQ(emulation, "e1000"))
bhyveParsePCINet(def, xmlopt, caps, bus, slot, function,
VIR_DOMAIN_NET_MODEL_E1000, conf);
diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
index 1b0abb21a0..7322eca80c 100644
--- a/src/conf/domain_audit.c
+++ b/src/conf/domain_audit.c
@@ -348,6 +348,7 @@ virDomainAuditHostdev(virDomainObjPtr vm, virDomainHostdevDefPtr
hostdev,
virDomainHostdevSubsysUSBPtr usbsrc = &hostdev->source.subsys.u.usb;
virDomainHostdevSubsysPCIPtr pcisrc = &hostdev->source.subsys.u.pci;
virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
+ virDomainHostdevSubsysSCSICTLPtr ctlsrc = &hostdev->source.subsys.u.scsi_ctl;
virDomainHostdevSubsysSCSIVHostPtr hostsrc =
&hostdev->source.subsys.u.scsi_host;
virDomainHostdevSubsysMediatedDevPtr mdevsrc =
&hostdev->source.subsys.u.mdev;
@@ -387,6 +388,10 @@ virDomainAuditHostdev(virDomainObjPtr vm, virDomainHostdevDefPtr
hostdev,
}
break;
}
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
+ address = g_strdup_printf("/dev/cam/ctl%u.%u",
+ ctlsrc->pp, ctlsrc->vp);
+ break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
address = g_strdup(hostsrc->wwpn);
break;
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cef49df3f8..12f8bb43c0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -898,6 +898,7 @@ VIR_ENUM_IMPL(virDomainHostdevSubsys,
"usb",
"pci",
"scsi",
+ "scsi_ctl",
"scsi_host",
"mdev",
);
@@ -908,6 +909,7 @@ VIR_ENUM_IMPL(virDomainHostdevSubsysPCIBackend,
"kvm",
"vfio",
"xen",
+ "vmm",
);
VIR_ENUM_IMPL(virDomainHostdevSubsysSCSIProtocol,
@@ -916,6 +918,18 @@ VIR_ENUM_IMPL(virDomainHostdevSubsysSCSIProtocol,
"iscsi",
);
+VIR_ENUM_IMPL(virDomainHostdevSubsysSCSICTLProtocol,
+ VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_PROTOCOL_TYPE_LAST,
+ "none",
+ "ioctl",
+);
+
+VIR_ENUM_IMPL(virDomainHostdevSubsysSCSICTLModel,
+ VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_MODEL_TYPE_LAST,
+ "default",
+ "virtio",
+);
+
VIR_ENUM_IMPL(virDomainHostdevSubsysSCSIHostProtocol,
VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_LAST,
"none",
@@ -2958,6 +2972,7 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
break;
@@ -5046,6 +5061,7 @@ virDomainHostdevDefPostParse(virDomainHostdevDefPtr dev,
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
break;
@@ -6484,6 +6500,16 @@ virDomainHostdevDefValidate(const virDomainHostdevDef *hostdev)
return -1;
}
break;
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
+ if (hostdev->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE
&&
+ hostdev->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED
&&
+ hostdev->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("SCSI CTL host devices must use 'pci' or
"
+ "'unassigned' address type"));
+ return -1;
+ }
+ break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
if (hostdev->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE
&&
hostdev->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI
&&
@@ -8320,6 +8346,64 @@ virDomainHostdevSubsysSCSIVHostDefParseXML(xmlNodePtr sourcenode,
return 0;
}
+static int
+virDomainHostdevSubsysSCSICTLDefParseXML(xmlNodePtr sourcenode,
+ virDomainHostdevDefPtr def)
+{
+ virDomainHostdevSubsysSCSICTLPtr ctlsrc = &def->source.subsys.u.scsi_ctl;
+ g_autofree char *protocol = NULL;
+ g_autofree char *pp = NULL;
+ g_autofree char *vp = NULL;
+
+ if (!(protocol = virXMLPropString(sourcenode, "protocol"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Missing scsi_ctl subsystem protocol"));
+ return -1;
+ }
+
+ if ((ctlsrc->protocol =
+ virDomainHostdevSubsysSCSICTLProtocolTypeFromString(protocol)) <= 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Unknown scsi_ctl subsystem protocol '%s'"),
+ protocol);
+ return -1;
+ }
+
+ switch ((virDomainHostdevSubsysSCSICTLProtocolType) ctlsrc->protocol) {
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_PROTOCOL_TYPE_IOCTL:
+ if (!(pp = virXMLPropString(sourcenode, "pp"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing scsi_ctl hostdev source pp"));
+ return -1;
+ }
+ if (virStrToLong_ui(pp, NULL, 10, &ctlsrc->pp) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Cannot parse scsi_ctl hostdev source 'pp'
attribute"));
+ return -1;
+ }
+ if (!(vp = virXMLPropString(sourcenode, "vp"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing scsi_ctl hostdev source vp"));
+ return -1;
+ }
+ if (virStrToLong_ui(vp, NULL, 10, &ctlsrc->vp) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Cannot parse scsi_ctl hostdev source 'vp'
attribute"));
+ return -1;
+ }
+ break;
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_PROTOCOL_TYPE_NONE:
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_PROTOCOL_TYPE_LAST:
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid hostdev protocol '%s'"),
+
virDomainHostdevSubsysSCSICTLProtocolTypeToString(ctlsrc->protocol));
+ return -1;
+ break;
+ }
+
+ return 0;
+}
+
static int
virDomainHostdevSubsysMediatedDevDefParseXML(virDomainHostdevDefPtr def,
xmlXPathContextPtr ctxt)
@@ -8363,6 +8447,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
int backend;
virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci;
virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi;
+ virDomainHostdevSubsysSCSICTLPtr scsictlsrc = &def->source.subsys.u.scsi_ctl;
virDomainHostdevSubsysSCSIVHostPtr scsihostsrc =
&def->source.subsys.u.scsi_host;
virDomainHostdevSubsysMediatedDevPtr mdevsrc = &def->source.subsys.u.mdev;
g_autofree char *managed = NULL;
@@ -8453,6 +8538,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
}
if (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV &&
+ def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL &&
def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST) {
if (model) {
virReportError(VIR_ERR_XML_ERROR,
@@ -8471,6 +8557,14 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
model);
return -1;
}
+ } else if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL) {
+ if (model &&
+ ((scsictlsrc->model =
virDomainHostdevSubsysSCSICTLModelTypeFromString(model)) < 0)) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("unknown hostdev model '%s'"),
+ model);
+ return -1;
+ }
} else if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV) {
if (!model) {
virReportError(VIR_ERR_XML_ERROR, "%s",
@@ -8533,10 +8627,16 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
return -1;
break;
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
+ if (virDomainHostdevSubsysSCSICTLDefParseXML(sourcenode, def) < 0)
+ return -1;
+ break;
+
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
if (virDomainHostdevSubsysSCSIVHostDefParseXML(sourcenode, def) < 0)
return -1;
break;
+
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
if (virDomainHostdevSubsysMediatedDevDefParseXML(def, ctxt) < 0)
return -1;
@@ -15914,6 +16014,7 @@ virDomainHostdevDefParseXML(virDomainXMLOptionPtr xmlopt,
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
@@ -16963,6 +17064,13 @@ virDomainHostdevMatchSubsys(virDomainHostdevDefPtr a,
return virDomainHostdevMatchSubsysSCSIiSCSI(a, b);
else
return virDomainHostdevMatchSubsysSCSIHost(a, b);
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
+ return ((a->source.subsys.u.scsi_ctl.protocol ==
+ b->source.subsys.u.scsi_ctl.protocol) &&
+ (a->source.subsys.u.scsi_ctl.pp ==
+ b->source.subsys.u.scsi_ctl.pp) &&
+ (a->source.subsys.u.scsi_ctl.vp ==
+ b->source.subsys.u.scsi_ctl.vp)) ? 1 : 0;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
if (a->source.subsys.u.scsi_host.protocol !=
b->source.subsys.u.scsi_host.protocol)
@@ -25354,6 +25462,7 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
virDomainHostdevSubsysUSBPtr usbsrc = &def->source.subsys.u.usb;
virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci;
virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi;
+ virDomainHostdevSubsysSCSICTLPtr ctlsrc = &def->source.subsys.u.scsi_ctl;
virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host;
virDomainHostdevSubsysMediatedDevPtr mdevsrc = &def->source.subsys.u.mdev;
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
@@ -25396,6 +25505,15 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
protocol, iscsisrc->src->path);
}
+ if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL) {
+ const char *protocol =
+ virDomainHostdevSubsysSCSICTLProtocolTypeToString(ctlsrc->protocol);
+ closedSource = true;
+
+ virBufferAsprintf(buf, " protocol='%s' pp='%u'
vp='%u'/",
+ protocol, ctlsrc->pp, ctlsrc->vp);
+ }
+
if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST) {
const char *protocol =
virDomainHostdevSubsysSCSIHostProtocolTypeToString(hostsrc->protocol);
@@ -25457,6 +25575,7 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
scsihostsrc->unit);
}
break;
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
@@ -27560,6 +27679,7 @@ virDomainHostdevDefFormat(virBufferPtr buf,
virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi;
virDomainHostdevSubsysMediatedDevPtr mdevsrc = &def->source.subsys.u.mdev;
virDomainHostdevSubsysSCSIVHostPtr scsihostsrc =
&def->source.subsys.u.scsi_host;
+ virDomainHostdevSubsysSCSICTLPtr scsictlsrc = &def->source.subsys.u.scsi_ctl;
const char *type;
if (!mode) {
@@ -27610,6 +27730,12 @@ virDomainHostdevDefFormat(virBufferPtr buf,
virTristateBoolTypeToString(scsisrc->rawio));
}
+ if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL
&&
+ scsictlsrc->model) {
+ virBufferAsprintf(buf, " model='%s'",
+
virDomainHostdevSubsysSCSICTLModelTypeToString(scsictlsrc->model));
+ }
+
if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST
&&
scsihostsrc->model) {
virBufferAsprintf(buf, " model='%s'",
@@ -31142,6 +31268,11 @@ virDomainNetDefActualToNetworkPort(virDomainDefPtr dom,
port->plug.hostdevpci.driver = VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO;
break;
+ case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VMM:
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Unexpected PCI backend 'vmm'"));
+ break;
+
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Unexpected PCI backend 'xen'"));
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index cdc4d25700..4e0fc01c2b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -195,6 +195,7 @@ typedef enum {
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB,
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI,
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI,
+ VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL,
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST,
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV,
@@ -203,10 +204,11 @@ typedef enum {
/* the backend driver used for PCI hostdev devices */
typedef enum {
- VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT, /* detect automatically, prefer VFIO */
+ VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT, /* detect automatically, prefer VFIO or VMM
*/
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM, /* force legacy kvm style */
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO, /* force vfio */
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN, /* force legacy xen style, use pciback */
+ VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VMM, /* force vmm (FreeBSD bhyve) */
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST
} virDomainHostdevSubsysPCIBackendType;
@@ -258,6 +260,30 @@ struct _virDomainHostdevSubsysSCSI {
} u;
};
+typedef enum {
+ VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_PROTOCOL_TYPE_NONE,
+ VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_PROTOCOL_TYPE_IOCTL,
+
+ VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_PROTOCOL_TYPE_LAST,
+} virDomainHostdevSubsysSCSICTLProtocolType;
+
+VIR_ENUM_DECL(virDomainHostdevSubsysSCSICTLProtocol);
+
+typedef enum {
+ VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_MODEL_TYPE_DEFAULT,
+ VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_MODEL_TYPE_VIRTIO,
+
+ VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_CTL_MODEL_TYPE_LAST,
+} virDomainHostdevSubsysSCSICTLModelType;
+
+VIR_ENUM_DECL(virDomainHostdevSubsysSCSICTLModel);
+
+struct _virDomainHostdevSubsysSCSICTL {
+ int protocol; /* enum virDomainHostdevSubsysSCSICTLProtocolType */
+ unsigned pp, vp;
+ int model; /* enum virDomainHostdevSubsysSCSICTLModelType */
+};
+
struct _virDomainHostdevSubsysMediatedDev {
int model; /* enum virMediatedDeviceModelType */
int display; /* virTristateSwitch */
@@ -298,6 +324,7 @@ struct _virDomainHostdevSubsys {
virDomainHostdevSubsysPCI pci;
virDomainHostdevSubsysSCSI scsi;
virDomainHostdevSubsysSCSIVHost scsi_host;
+ virDomainHostdevSubsysSCSICTL scsi_ctl;
virDomainHostdevSubsysMediatedDev mdev;
} u;
};
diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h
index 1c62cde251..66cf40f8f0 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -180,6 +180,9 @@ typedef virDomainHostdevSubsysPCI *virDomainHostdevSubsysPCIPtr;
typedef struct _virDomainHostdevSubsysSCSI virDomainHostdevSubsysSCSI;
typedef virDomainHostdevSubsysSCSI *virDomainHostdevSubsysSCSIPtr;
+typedef struct _virDomainHostdevSubsysSCSICTL virDomainHostdevSubsysSCSICTL;
+typedef virDomainHostdevSubsysSCSICTL *virDomainHostdevSubsysSCSICTLPtr;
+
typedef struct _virDomainHostdevSubsysSCSIHost virDomainHostdevSubsysSCSIHost;
typedef virDomainHostdevSubsysSCSIHost *virDomainHostdevSubsysSCSIHostPtr;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index f69a9e651c..fdd59a35a4 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4677,6 +4677,7 @@ qemuBuildPCIHostdevDevStr(const virDomainDef *def,
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT:
+ case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VMM:
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN:
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -5439,6 +5440,7 @@ qemuBuildHostdevCommandLine(virCommandPtr cmd,
break;
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
break;
}
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index af6817cc05..3ebb864b4c 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -6674,8 +6674,11 @@ qemuDomainDeviceDefValidateHostdev(const virDomainHostdevDef
*hostdev,
return -1;
}
break;
+
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
return qemuDomainMdevDefValidate(hostdev, def, qemuCaps);
+
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
default:
virReportEnumRangeError(virDomainHostdevSubsysType,
@@ -14031,6 +14034,8 @@ qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev,
perm = VIR_CGROUP_DEVICE_RW;
break;
+
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
break;
}
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 1774850640..0e1432f23d 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -203,6 +203,7 @@ qemuHostdevPreparePCIDevicesCheckSupport(virDomainHostdevDefPtr
*hostdevs,
return false;
break;
+ case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VMM:
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN:
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
break;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 9800491755..94fa64f216 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1576,6 +1576,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM:
break;
+ case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VMM:
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN:
case VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_LAST:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -4535,6 +4536,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
qemuDomainRemoveMediatedDevice(driver, vm, hostdev);
break;
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
break;
}
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index a307c5ebe2..93144b741f 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1105,6 +1105,7 @@ qemuMigrationSrcIsAllowedHostdev(const virDomainDef *def)
continue;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index ca02631f7f..eadf2580b6 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -959,6 +959,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
break;
}
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
ret = 0;
break;
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index d75b18170b..de85e53a9a 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1212,6 +1212,7 @@ virSecurityDACSetHostdevLabel(virSecurityManagerPtr mgr,
virDomainHostdevSubsysUSBPtr usbsrc = &dev->source.subsys.u.usb;
virDomainHostdevSubsysPCIPtr pcisrc = &dev->source.subsys.u.pci;
virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
+ virDomainHostdevSubsysSCSICTLPtr ctlsrc = &dev->source.subsys.u.scsi_ctl;
virDomainHostdevSubsysSCSIVHostPtr hostsrc = &dev->source.subsys.u.scsi_host;
virDomainHostdevSubsysMediatedDevPtr mdevsrc = &dev->source.subsys.u.mdev;
int ret = -1;
@@ -1300,6 +1301,19 @@ virSecurityDACSetHostdevLabel(virSecurityManagerPtr mgr,
break;
}
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL: {
+ char *ctldev = g_strdup_printf("/dev/cam/ctl%u.%u",
+ ctlsrc->pp, ctlsrc->vp);
+
+ if (!ctldev)
+ return -1;
+
+ ret = virSecurityDACSetHostdevLabelHelper(ctldev, true, &cbdata);
+
+ VIR_FREE(ctldev);
+ break;
+ }
+
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: {
virSCSIVHostDevicePtr host = virSCSIVHostDeviceNew(hostsrc->wwpn);
@@ -1386,6 +1400,7 @@ virSecurityDACRestoreHostdevLabel(virSecurityManagerPtr mgr,
virDomainHostdevSubsysUSBPtr usbsrc = &dev->source.subsys.u.usb;
virDomainHostdevSubsysPCIPtr pcisrc = &dev->source.subsys.u.pci;
virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi;
+ virDomainHostdevSubsysSCSICTLPtr ctlsrc = &dev->source.subsys.u.scsi_ctl;
virDomainHostdevSubsysSCSIVHostPtr hostsrc = &dev->source.subsys.u.scsi_host;
virDomainHostdevSubsysMediatedDevPtr mdevsrc = &dev->source.subsys.u.mdev;
int ret = -1;
@@ -1463,6 +1478,19 @@ virSecurityDACRestoreHostdevLabel(virSecurityManagerPtr mgr,
break;
}
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL: {
+ char *ctldev = g_strdup_printf("/dev/cam/ctl%u.%u",
+ ctlsrc->pp, ctlsrc->vp);
+
+ if (!ctldev)
+ return -1;
+
+ ret = virSecurityDACRestoreFileLabel(mgr, ctldev);
+
+ VIR_FREE(ctldev);
+ break;
+ }
+
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: {
virSCSIVHostDevicePtr host = virSCSIVHostDeviceNew(hostsrc->wwpn);
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 3f6968a57a..96f483ee14 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -2149,6 +2149,10 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManagerPtr mgr,
break;
}
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
+ /* FreeBSD only */
+ return -1;
+
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: {
virSCSIVHostDevicePtr host = virSCSIVHostDeviceNew(hostsrc->wwpn);
@@ -2384,6 +2388,10 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManagerPtr
mgr,
break;
}
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_CTL:
+ /* FreeBSD only */
+ return -1;
+
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: {
virSCSIVHostDevicePtr host = virSCSIVHostDeviceNew(hostsrc->wwpn);
diff --git a/tests/bhyveargv2xmldata/bhyveargv2xml-passthru.args
b/tests/bhyveargv2xmldata/bhyveargv2xml-passthru.args
new file mode 100644
index 0000000000..697bafd642
--- /dev/null
+++ b/tests/bhyveargv2xmldata/bhyveargv2xml-passthru.args
@@ -0,0 +1,8 @@
+/usr/sbin/bhyve \
+-c 1 \
+-m 214 \
+-H \
+-P \
+-S \
+-s 0:0,hostbridge \
+-s 0:1:0,passthru,5/0/7 bhyve
diff --git a/tests/bhyveargv2xmldata/bhyveargv2xml-passthru.xml
b/tests/bhyveargv2xmldata/bhyveargv2xml-passthru.xml
new file mode 100644
index 0000000000..af99279448
--- /dev/null
+++ b/tests/bhyveargv2xmldata/bhyveargv2xml-passthru.xml
@@ -0,0 +1,26 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <memoryBacking>
+ <locked/>
+ </memoryBacking>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type>hvm</type>
+ </os>
+ <clock offset='localtime'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>destroy</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <hostdev mode='subsystem' type='pci' managed='no'>
+ <driver name='vmm'/>
+ <source>
+ <address domain='0x0000' bus='0x05' slot='0x00'
function='0x7'/>
+ </source>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x01' function='0x0'/>
+ </hostdev>
+ </devices>
+</domain>
diff --git a/tests/bhyveargv2xmldata/bhyveargv2xml-virtio-scsi.args
b/tests/bhyveargv2xmldata/bhyveargv2xml-virtio-scsi.args
new file mode 100644
index 0000000000..ae38208853
--- /dev/null
+++ b/tests/bhyveargv2xmldata/bhyveargv2xml-virtio-scsi.args
@@ -0,0 +1,9 @@
+/usr/sbin/bhyve \
+-c 1 \
+-m 214 \
+-H \
+-P \
+-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI_CODE-devel.fd \
+-s 0:0,hostbridge \
+-s 1:0,lpc \
+-s 2:0,virtio-scsi,/dev/cam/ctl5.0 bhyve
diff --git a/tests/bhyveargv2xmldata/bhyveargv2xml-virtio-scsi.xml
b/tests/bhyveargv2xmldata/bhyveargv2xml-virtio-scsi.xml
new file mode 100644
index 0000000000..23ad90a2a5
--- /dev/null
+++ b/tests/bhyveargv2xmldata/bhyveargv2xml-virtio-scsi.xml
@@ -0,0 +1,20 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type>hvm</type>
+ </os>
+ <clock offset='localtime'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>destroy</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <hostdev mode='subsystem' type='scsi_ctl' managed='no'
model='virtio'>
+ <source protocol='ioctl' pp='5' vp='0'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x02' function='0x0'/>
+ </hostdev>
+ </devices>
+</domain>
diff --git a/tests/bhyveargv2xmltest.c b/tests/bhyveargv2xmltest.c
index 735cc4b338..1cfe4e3ddb 100644
--- a/tests/bhyveargv2xmltest.c
+++ b/tests/bhyveargv2xmltest.c
@@ -173,6 +173,8 @@ mymain(void)
DO_TEST("ahci-hd");
DO_TEST("virtio-blk");
DO_TEST("virtio-net");
+ DO_TEST("virtio-scsi");
+ DO_TEST("passthru");
DO_TEST("e1000");
DO_TEST_WARN("virtio-net2");
DO_TEST_WARN("virtio-net3");
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-passthru.args
b/tests/bhyvexml2argvdata/bhyvexml2argv-passthru.args
new file mode 100644
index 0000000000..c268da957c
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-passthru.args
@@ -0,0 +1,11 @@
+/usr/sbin/bhyve \
+-c 1 \
+-m 214 \
+-S \
+-u \
+-H \
+-P \
+-s 0:0,hostbridge \
+-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI_CODE-devel.fd \
+-s 0:3:0,passthru,5/0/7 \
+-s 1,lpc bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-passthru.ldargs
b/tests/bhyvexml2argvdata/bhyvexml2argv-passthru.ldargs
new file mode 100644
index 0000000000..2995a4d0e7
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-passthru.ldargs
@@ -0,0 +1 @@
+dummy
\ No newline at end of file
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-passthru.xml
b/tests/bhyvexml2argvdata/bhyvexml2argv-passthru.xml
new file mode 100644
index 0000000000..ba0744f35d
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-passthru.xml
@@ -0,0 +1,22 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory>219136</memory>
+ <memoryBacking>
+ <locked/>
+ </memoryBacking>
+ <vcpu>1</vcpu>
+ <os>
+ <type>hvm</type>
+ <loader readonly='yes'
type='pflash'>/usr/local/share/uefi-firmware/BHYVE_UEFI_CODE-devel.fd</loader>
+ </os>
+ <devices>
+ <hostdev mode='subsystem' type='pci' managed='no'>
+ <driver name='vmm'/>
+ <source>
+ <address domain='0x0000' bus='0x05' slot='0x00'
function='0x7'/>
+ </source>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x03' function='0x0'/>
+ </hostdev>
+ </devices>
+</domain>
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-virtio-scsi.args
b/tests/bhyvexml2argvdata/bhyvexml2argv-virtio-scsi.args
new file mode 100644
index 0000000000..372f989095
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-virtio-scsi.args
@@ -0,0 +1,9 @@
+/usr/sbin/bhyve \
+-c 1 \
+-m 214 \
+-H \
+-P \
+-s 0:0,hostbridge \
+-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI_CODE-devel.fd \
+-s 2:0,virtio-scsi,/dev/cam/ctl5.0 \
+-s 1,lpc bhyve
\ No newline at end of file
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-virtio-scsi.ldargs
b/tests/bhyvexml2argvdata/bhyvexml2argv-virtio-scsi.ldargs
new file mode 100644
index 0000000000..421376db9e
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-virtio-scsi.ldargs
@@ -0,0 +1 @@
+dummy
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-virtio-scsi.xml
b/tests/bhyvexml2argvdata/bhyvexml2argv-virtio-scsi.xml
new file mode 100644
index 0000000000..394ff20ffc
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-virtio-scsi.xml
@@ -0,0 +1,21 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type>hvm</type>
+ <loader readonly='yes'
type='pflash'>/usr/local/share/uefi-firmware/BHYVE_UEFI_CODE-devel.fd</loader>
+ </os>
+ <clock offset='localtime'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>destroy</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <hostdev mode='subsystem' type='scsi_ctl'
model='virtio'>
+ <source protocol='ioctl' pp='5' vp='0'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x02' function='0x0'/>
+ </hostdev>
+ </devices>
+</domain>
diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c
index 9e7eb218b8..7ce2d5c6b1 100644
--- a/tests/bhyvexml2argvtest.c
+++ b/tests/bhyvexml2argvtest.c
@@ -175,7 +175,7 @@ mymain(void)
driver.bhyvecaps = BHYVE_CAP_RTC_UTC | BHYVE_CAP_AHCI32SLOT | \
BHYVE_CAP_NET_E1000 | BHYVE_CAP_LPC_BOOTROM | \
BHYVE_CAP_FBUF | BHYVE_CAP_XHCI | \
- BHYVE_CAP_CPUTOPOLOGY;
+ BHYVE_CAP_CPUTOPOLOGY | BHYVE_CAP_VIRTIOSCSI;
DO_TEST("base");
DO_TEST("wired");
@@ -210,6 +210,8 @@ mymain(void)
DO_TEST_FAILURE("cputopology-nvcpu-mismatch");
DO_TEST("commandline");
DO_TEST("msrs");
+ DO_TEST("virtio-scsi");
+ DO_TEST("passthru");
/* Address allocation tests */
DO_TEST("addr-single-sata-disk");
diff --git a/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-passthru.xml
b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-passthru.xml
new file mode 100644
index 0000000000..0313fa0dfa
--- /dev/null
+++ b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-passthru.xml
@@ -0,0 +1,29 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <memoryBacking>
+ <locked/>
+ </memoryBacking>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64'>hvm</type>
+ <loader readonly='yes'
type='pflash'>/usr/local/share/uefi-firmware/BHYVE_UEFI_CODE-devel.fd</loader>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <controller type='pci' index='0' model='pci-root'/>
+ <hostdev mode='subsystem' type='pci' managed='no'>
+ <driver name='vmm'/>
+ <source>
+ <address domain='0x0000' bus='0x05' slot='0x00'
function='0x7'/>
+ </source>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x03' function='0x0'/>
+ </hostdev>
+ </devices>
+</domain>
diff --git a/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-virtio-scsi.xml
b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-virtio-scsi.xml
new file mode 100644
index 0000000000..771591689a
--- /dev/null
+++ b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-virtio-scsi.xml
@@ -0,0 +1,23 @@
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64'>hvm</type>
+ <loader readonly='yes'
type='pflash'>/usr/local/share/uefi-firmware/BHYVE_UEFI_CODE-devel.fd</loader>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='localtime'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>destroy</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <controller type='pci' index='0' model='pci-root'/>
+ <hostdev mode='subsystem' type='scsi_ctl' managed='no'
model='virtio'>
+ <source protocol='ioctl' pp='5' vp='0'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x02' function='0x0'/>
+ </hostdev>
+ </devices>
+</domain>
diff --git a/tests/bhyvexml2xmltest.c b/tests/bhyvexml2xmltest.c
index a0c20a14c1..3a2a46014a 100644
--- a/tests/bhyvexml2xmltest.c
+++ b/tests/bhyvexml2xmltest.c
@@ -83,6 +83,7 @@ mymain(void)
DO_TEST_DIFFERENT("acpiapic");
DO_TEST_DIFFERENT("base");
DO_TEST_DIFFERENT("wired");
+ DO_TEST_DIFFERENT("passthru");
DO_TEST_DIFFERENT("bhyveload-bootorder");
DO_TEST_DIFFERENT("bhyveload-bootorder1");
DO_TEST_DIFFERENT("bhyveload-bootorder2");
@@ -94,6 +95,7 @@ mymain(void)
DO_TEST_DIFFERENT("disk-cdrom");
DO_TEST_DIFFERENT("disk-cdrom-grub");
DO_TEST_DIFFERENT("disk-virtio");
+ DO_TEST_DIFFERENT("virtio-scsi");
DO_TEST_DIFFERENT("grub-bootorder");
DO_TEST_DIFFERENT("grub-bootorder2");
DO_TEST_DIFFERENT("grub-defaults");
--
2.24.1