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@xxxxxxxxxxxxx> --- 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 5b1d80083a..9f4030f6a3 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -362,6 +362,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) @@ -613,6 +730,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..90b82cc02b --- /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 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