Along with video and VNC support, bhyve has introduced USB tablet support as an input device. This tablet is exposed to a guest as a device on an XHCI controller. At present, tablet is the only supported device on the XHCI controller in bhyve, so to make things simple, it's allowed to only have a single XHCI controller with a single tablet device. In detail, this commit: - Introduce a new capability bit for XHCI support in bhyve - Add an XHCI controller and tabled support with 1:1 mapping between them - Add a couple of unit tests --- src/bhyve/bhyve_capabilities.c | 15 +++++++ src/bhyve/bhyve_capabilities.h | 1 + src/bhyve/bhyve_command.c | 50 ++++++++++++++++++++++ src/bhyve/bhyve_device.c | 4 +- .../bhyvexml2argv-input-xhci-tablet.args | 9 ++++ .../bhyvexml2argv-input-xhci-tablet.ldargs | 3 ++ .../bhyvexml2argv-input-xhci-tablet.xml | 18 ++++++++ .../bhyvexml2argv-xhci-multiple-controllers.xml | 19 ++++++++ .../bhyvexml2argv-xhci-multiple-devs.xml | 19 ++++++++ .../bhyvexml2argv-xhci-no-devs.xml | 17 ++++++++ tests/bhyvexml2argvtest.c | 10 ++++- .../bhyvexml2xmlout-input-xhci-tablet.xml | 31 ++++++++++++++ tests/bhyvexml2xmltest.c | 3 ++ 13 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.ldargs create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-controllers.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-devs.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-xhci-no-devs.xml create mode 100644 tests/bhyvexml2xmloutdata/bhyvexml2xmlout-input-xhci-tablet.xml diff --git a/src/bhyve/bhyve_capabilities.c b/src/bhyve/bhyve_capabilities.c index f72fdea41..a34c596f0 100644 --- a/src/bhyve/bhyve_capabilities.c +++ b/src/bhyve/bhyve_capabilities.c @@ -286,6 +286,18 @@ bhyveProbeCapsFramebuffer(unsigned int *caps, char *binary) BHYVE_CAP_FBUF); } + +static int +bhyveProbeCapsXHCIController(unsigned int *caps, char *binary) +{ + return bhyveProbeCapsDeviceHelper(caps, binary, + "-s", + "0,xhci", + "pci slot 0:0: unknown device \"xhci\"", + BHYVE_CAP_FBUF); +} + + int virBhyveProbeCaps(unsigned int *caps) { @@ -313,6 +325,9 @@ virBhyveProbeCaps(unsigned int *caps) if ((ret = bhyveProbeCapsFramebuffer(caps, binary))) goto out; + if ((ret = bhyveProbeCapsXHCIController(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 3db4f1b88..3db51af02 100644 --- a/src/bhyve/bhyve_capabilities.h +++ b/src/bhyve/bhyve_capabilities.h @@ -45,6 +45,7 @@ typedef enum { BHYVE_CAP_NET_E1000 = 1 << 2, BHYVE_CAP_LPC_BOOTROM = 1 << 3, BHYVE_CAP_FBUF = 1 << 4, + BHYVE_CAP_XHCI = 1 << 5, } virBhyveCapsFlags; int virBhyveProbeGrubCaps(virBhyveGrubCapsFlags *caps); diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index ec7a71572..e0528ed77 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -249,6 +249,45 @@ bhyveBuildAHCIControllerArgStr(const virDomainDef *def, } static int +bhyveBuildUSBControllerArgStr(const virDomainDef *def, + virDomainControllerDefPtr controller, + virCommandPtr cmd) +{ + size_t i; + int ndevices = 0; + + for (i = 0; i < def->ninputs; i++) { + virDomainInputDefPtr input = def->inputs[i]; + + if (input->bus != VIR_DOMAIN_INPUT_BUS_USB) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("only USB input devices are supported")); + return -1; + } + + if (input->type != VIR_DOMAIN_INPUT_TYPE_TABLET) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("only tablet input devices are supported")); + return -1; + } + ndevices++; + } + + if (ndevices != 1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("only single input device is supported")); + return -1; + } + + virCommandAddArg(cmd, "-s"); + virCommandAddArgFormat(cmd, "%d:%d,xhci,tablet", + controller->info.addr.pci.slot, + controller->info.addr.pci.function); + + return 0; +} + +static int bhyveBuildVirtIODiskArgStr(const virDomainDef *def ATTRIBUTE_UNUSED, virDomainDiskDefPtr disk, virConnectPtr conn, @@ -392,6 +431,7 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, */ size_t i; bool add_lpc = false; + int nusbcontrollers = 0; virCommandPtr cmd = virCommandNew(BHYVE); @@ -476,6 +516,16 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, if (bhyveBuildAHCIControllerArgStr(def, controller, conn, cmd) < 0) goto error; break; + case VIR_DOMAIN_CONTROLLER_TYPE_USB: + if (++nusbcontrollers > 1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + "%s", _("only single USB controller is supported")); + goto error; + } + + if (bhyveBuildUSBControllerArgStr(def, controller, cmd) < 0) + goto error; + break; } } for (i = 0; i < def->nnets; i++) { diff --git a/src/bhyve/bhyve_device.c b/src/bhyve/bhyve_device.c index a3a263b7e..fdfd512e1 100644 --- a/src/bhyve/bhyve_device.c +++ b/src/bhyve/bhyve_device.c @@ -106,7 +106,9 @@ bhyveAssignDevicePCISlots(virDomainDefPtr def, for (i = 0; i < def->ncontrollers; i++) { if ((def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) || - (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA)) { + (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA) || + ((def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) && + (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI))) { if (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT || !virDeviceInfoPCIAddressWanted(&def->controllers[i]->info)) continue; diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.args b/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.args new file mode 100644 index 000000000..b1c0c94d0 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.args @@ -0,0 +1,9 @@ +/usr/sbin/bhyve \ +-c 1 \ +-m 214 \ +-u \ +-H \ +-P \ +-s 0:0,hostbridge \ +-s 2:0,xhci,tablet \ +-s 3:0,ahci-hd,/tmp/freebsd.img bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.ldargs new file mode 100644 index 000000000..32538b558 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.ldargs @@ -0,0 +1,3 @@ +/usr/sbin/bhyveload \ +-m 214 \ +-d /tmp/freebsd.img bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.xml new file mode 100644 index 000000000..95492e6cb --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.xml @@ -0,0 +1,18 @@ +<domain type='bhyve'> + <name>bhyve</name> + <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid> + <memory>219136</memory> + <vcpu>1</vcpu> + <os> + <type>hvm</type> + </os> + <devices> + <disk type='file'> + <driver name='file' type='raw'/> + <source file='/tmp/freebsd.img'/> + <target dev='hda' bus='sata'/> + </disk> + <controller type='usb' model='nec-xhci'/> + <input type='tablet' bus='usb'/> + </devices> +</domain> diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-controllers.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-controllers.xml new file mode 100644 index 000000000..b3f259226 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-controllers.xml @@ -0,0 +1,19 @@ +<domain type='bhyve'> + <name>bhyve</name> + <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid> + <memory>219136</memory> + <vcpu>1</vcpu> + <os> + <type>hvm</type> + </os> + <devices> + <disk type='file'> + <driver name='file' type='raw'/> + <source file='/tmp/freebsd.img'/> + <target dev='hda' bus='sata'/> + </disk> + <controller type='usb' model='nec-xhci'/> + <controller type='usb' model='nec-xhci'/> + <input type='tablet' bus='usb'/> + </devices> +</domain> diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-devs.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-devs.xml new file mode 100644 index 000000000..b0828f632 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-devs.xml @@ -0,0 +1,19 @@ +<domain type='bhyve'> + <name>bhyve</name> + <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid> + <memory>219136</memory> + <vcpu>1</vcpu> + <os> + <type>hvm</type> + </os> + <devices> + <disk type='file'> + <driver name='file' type='raw'/> + <source file='/tmp/freebsd.img'/> + <target dev='hda' bus='sata'/> + </disk> + <controller type='usb' model='nec-xhci'/> + <input type='tablet' bus='usb'/> + <input type='tablet' bus='usb'/> + </devices> +</domain> diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-no-devs.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-no-devs.xml new file mode 100644 index 000000000..323063354 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-no-devs.xml @@ -0,0 +1,17 @@ +<domain type='bhyve'> + <name>bhyve</name> + <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid> + <memory>219136</memory> + <vcpu>1</vcpu> + <os> + <type>hvm</type> + </os> + <devices> + <disk type='file'> + <driver name='file' type='raw'/> + <source file='/tmp/freebsd.img'/> + <target dev='hda' bus='sata'/> + </disk> + <controller type='usb' model='nec-xhci'/> + </devices> +</domain> diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c index 4cbc398b7..475e62666 100644 --- a/tests/bhyvexml2argvtest.c +++ b/tests/bhyvexml2argvtest.c @@ -167,7 +167,7 @@ mymain(void) driver.grubcaps = BHYVE_GRUB_CAP_CONSDEV; driver.bhyvecaps = BHYVE_CAP_RTC_UTC | BHYVE_CAP_AHCI32SLOT | \ BHYVE_CAP_NET_E1000 | BHYVE_CAP_LPC_BOOTROM | \ - BHYVE_CAP_FBUF; + BHYVE_CAP_FBUF | BHYVE_CAP_XHCI; DO_TEST("base"); DO_TEST("acpiapic"); @@ -207,6 +207,14 @@ mymain(void) DO_TEST("addr-no32devs-multiple-sata-disks"); DO_TEST_FAILURE("addr-no32devs-more-than-32-sata-disks"); + /* USB xhci tablet */ + DO_TEST("input-xhci-tablet"); + DO_TEST_FAILURE("xhci-multiple-controllers"); + DO_TEST_FAILURE("xhci-no-devs"); + DO_TEST_FAILURE("xhci-multiple-devs"); + driver.bhyvecaps ^= BHYVE_CAP_XHCI; + DO_TEST_FAILURE("input-xhci-tablet"); + driver.grubcaps = 0; DO_TEST("serial-grub-nocons"); diff --git a/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-input-xhci-tablet.xml b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-input-xhci-tablet.xml new file mode 100644 index 000000000..797868e7f --- /dev/null +++ b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-input-xhci-tablet.xml @@ -0,0 +1,31 @@ +<domain type='bhyve'> + <name>bhyve</name> + <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid> + <memory unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <disk type='file' device='disk'> + <driver name='file' type='raw'/> + <source file='/tmp/freebsd.img'/> + <target dev='hda' bus='sata'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0' model='nec-xhci'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </controller> + <input type='tablet' bus='usb'/> + </devices> +</domain> diff --git a/tests/bhyvexml2xmltest.c b/tests/bhyvexml2xmltest.c index ba9af2996..3270fee3c 100644 --- a/tests/bhyvexml2xmltest.c +++ b/tests/bhyvexml2xmltest.c @@ -118,6 +118,9 @@ mymain(void) DO_TEST_DIFFERENT("addr-no32devs-multiple-sata-disks"); DO_TEST_FAILURE("addr-no32devs-more-than-32-sata-disks"); + /* USB xhci tablet */ + DO_TEST_DIFFERENT("input-xhci-tablet"); + virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt); -- 2.11.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list