From daecaea038587b28304f83fb5930b5d870bacde3 Mon Sep 17 00:00:00 2001 From: Roman Bogorodskiy Date: Mon, 20 Mar 2017 17:58:51 +0400 Subject: [PATCH] bhyve: add xhci tablet support 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: - Introduces a new capability bit for XHCI support in bhyve - Adds an XHCI controller and tabled support with 1:1 mapping between them - Adds 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 +++++++ ...hyvexml2argv-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 6769f1888a..f97834242d 100644 --- a/src/bhyve/bhyve_capabilities.c +++ b/src/bhyve/bhyve_capabilities.c @@ -310,6 +310,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) { @@ -337,6 +349,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 194061fde6..0e310e6eda 100644 --- a/src/bhyve/bhyve_capabilities.h +++ b/src/bhyve/bhyve_capabilities.h @@ -48,6 +48,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 ec7a71572e..e0528ed77a 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -248,6 +248,45 @@ bhyveBuildAHCIControllerArgStr(const virDomainDef *def, return ret; } +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, @@ -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 a3a263b7e2..fdfd512e10 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 0000000000..b1c0c94d03 --- /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 0000000000..32538b558e --- /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 0000000000..95492e6cbe --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-input-xhci-tablet.xml @@ -0,0 +1,18 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + + + + + + diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-controllers.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-controllers.xml new file mode 100644 index 0000000000..b3f2592267 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-controllers.xml @@ -0,0 +1,19 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + + + + + + + diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-devs.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-devs.xml new file mode 100644 index 0000000000..b0828f6326 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-multiple-devs.xml @@ -0,0 +1,19 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + + + + + + + diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-no-devs.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-no-devs.xml new file mode 100644 index 0000000000..323063354c --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-xhci-no-devs.xml @@ -0,0 +1,17 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + + + + + diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c index 4cbc398b74..475e626669 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 0000000000..797868e7f2 --- /dev/null +++ b/tests/bhyvexml2xmloutdata/bhyvexml2xmlout-input-xhci-tablet.xml @@ -0,0 +1,31 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + + + + +
+ + +
+ + + +
+ + + + diff --git a/tests/bhyvexml2xmltest.c b/tests/bhyvexml2xmltest.c index ba9af29960..3270fee3ce 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); -- GitLab