Alexander Shursha wrote: > Signed-off-by: Alexander Shursha <kekek2@xxxxx> > --- > src/bhyve/bhyve_parse_command.c | 60 +++++++++++++++++++ > .../bhyveargv2xml-passthru.args | 7 +++ > .../bhyveargv2xml-passthru.xml | 22 +++++++ > tests/bhyveargv2xmltest.c | 1 + > 4 files changed, 90 insertions(+) > create mode 100644 tests/bhyveargv2xmldata/bhyveargv2xml-passthru.args > create mode 100644 tests/bhyveargv2xmldata/bhyveargv2xml-passthru.xml > > diff --git a/src/bhyve/bhyve_parse_command.c b/src/bhyve/bhyve_parse_command.c > index 29d3a678bf..394fc151aa 100644 > --- a/src/bhyve/bhyve_parse_command.c > +++ b/src/bhyve/bhyve_parse_command.c > @@ -5,6 +5,7 @@ > * Copyright (C) 2006 Daniel P. Berrange > * Copyright (c) 2011 NetApp, Inc. > * Copyright (C) 2020 Fabian Freyer > + * Copyright (C) 2024-2025 Future Crew, LLC > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public > @@ -639,6 +640,63 @@ bhyveParsePCIFbuf(virDomainDef *def, > return -1; > } > > +static int > +bhyveParsePassthru(virDomainDef *def G_GNUC_UNUSED, > + unsigned pcibus, > + unsigned pcislot, > + unsigned pcifunction, > + char *addr) > +{ > + /* -s slot,bus/slot/function */ > + /* -s slot,pcibus:slot:function */ > + virDomainHostdevDef *hostdev = NULL; > + g_auto(GStrv) params = NULL; > + GStrv param; > + char *p = NULL; > + > + hostdev = virDomainHostdevDefNew(); Need to check if hostdev is NULL. > + hostdev->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; > + hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI; > + > + hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; > + hostdev->info->addr.pci.bus = pcibus; > + hostdev->info->addr.pci.slot = pcislot; > + hostdev->info->addr.pci.function = pcifunction; > + > + if (!addr) > + goto error; > + > + if (!(params = g_strsplit(addr, ":", -1))) { > + virReportError(VIR_ERR_OPERATION_FAILED, _("Failed to parse PCI address %1$s"), addr); > + goto error; > + } > + if (g_str_equal(addr, *params)) { > + g_free(params); > + if (!(params = g_strsplit(addr, "/", -1))) { > + virReportError(VIR_ERR_OPERATION_FAILED, _("Failed to parse PCI address %1$s"), addr); > + goto error; > + } > + } > + if (g_strv_length(params) != 3) { > + virReportError(VIR_ERR_OPERATION_FAILED, _("Failed to parse PCI address %1$s"), addr); > + goto error; > + } > + param = params; > + hostdev->source.subsys.u.pci.addr.bus = g_ascii_strtoull(*param++, &p, 10); > + hostdev->source.subsys.u.pci.addr.slot = g_ascii_strtoull(*param++, &p, 10); > + hostdev->source.subsys.u.pci.addr.function = g_ascii_strtoull(*param, &p, 10); Would it make sense to use the virStrToLong_ullp() wrapper here instead of g_ascii_strtoull()? The rest looks good to me. > + hostdev->source.subsys.u.pci.addr.domain = 0; > + hostdev->managed = false; > + > + VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev); > + return 0; > + > + error: > + virDomainHostdevDefFree(hostdev); > + return -1; > +} > + > static int > bhyveParseBhyvePCIArg(virDomainDef *def, > virDomainXMLOption *xmlopt, > @@ -703,6 +761,8 @@ bhyveParseBhyvePCIArg(virDomainDef *def, > VIR_DOMAIN_NET_MODEL_E1000, conf); > else if (STREQ(emulation, "fbuf")) > bhyveParsePCIFbuf(def, xmlopt, caps, bus, slot, function, conf); > + else if (STREQ(emulation, "passthru")) > + bhyveParsePassthru(def, bus, slot, function, conf); > > VIR_FREE(emulation); > VIR_FREE(slotdef); > diff --git a/tests/bhyveargv2xmldata/bhyveargv2xml-passthru.args b/tests/bhyveargv2xmldata/bhyveargv2xml-passthru.args > new file mode 100644 > index 0000000000..4eb1ff14b5 > --- /dev/null > +++ b/tests/bhyveargv2xmldata/bhyveargv2xml-passthru.args > @@ -0,0 +1,7 @@ > +/usr/sbin/bhyve \ > +-c 1 \ > +-m 214 \ > +-H \ > +-P \ > +-s 0:0,hostbridge \ > +-s 7,passthru,3/0/0 bhyve > diff --git a/tests/bhyveargv2xmldata/bhyveargv2xml-passthru.xml b/tests/bhyveargv2xmldata/bhyveargv2xml-passthru.xml > new file mode 100644 > index 0000000000..64118ff89c > --- /dev/null > +++ b/tests/bhyveargv2xmldata/bhyveargv2xml-passthru.xml > @@ -0,0 +1,22 @@ > +<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='pci' managed='no'> > + <source> > + <address domain='0x0000' bus='0x03' slot='0x00' function='0x0'/> > + </source> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> > + </hostdev> > + </devices> > +</domain> > diff --git a/tests/bhyveargv2xmltest.c b/tests/bhyveargv2xmltest.c > index 92189a2e58..f61235e04f 100644 > --- a/tests/bhyveargv2xmltest.c > +++ b/tests/bhyveargv2xmltest.c > @@ -161,6 +161,7 @@ mymain(void) > DO_TEST("virtio-blk"); > DO_TEST("virtio-net"); > DO_TEST("e1000"); > + DO_TEST("passthru"); > DO_TEST_WARN("virtio-net2"); > DO_TEST_WARN("virtio-net3"); > DO_TEST_WARN("virtio-net4"); > -- > 2.47.1