diff options
Diffstat (limited to 'usr.sbin/bhyve')
-rw-r--r-- | usr.sbin/bhyve/aarch64/vmexit.c | 2 | ||||
-rw-r--r-- | usr.sbin/bhyve/amd64/Makefile.inc | 1 | ||||
-rw-r--r-- | usr.sbin/bhyve/amd64/vmexit.c | 2 | ||||
-rw-r--r-- | usr.sbin/bhyve/bhyve.8 | 2 | ||||
-rw-r--r-- | usr.sbin/bhyve/bhyverun.c | 6 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_passthru_quirks.c | 48 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_xhci.c | 35 | ||||
-rw-r--r-- | usr.sbin/bhyve/rfb.c | 19 | ||||
-rw-r--r-- | usr.sbin/bhyve/riscv/vmexit.c | 2 | ||||
-rw-r--r-- | usr.sbin/bhyve/usb_emul.h | 4 | ||||
-rw-r--r-- | usr.sbin/bhyve/usb_mouse.c | 13 |
11 files changed, 112 insertions, 22 deletions
diff --git a/usr.sbin/bhyve/aarch64/vmexit.c b/usr.sbin/bhyve/aarch64/vmexit.c index 3acad4020a3c..2457cbe76b5e 100644 --- a/usr.sbin/bhyve/aarch64/vmexit.c +++ b/usr.sbin/bhyve/aarch64/vmexit.c @@ -122,6 +122,8 @@ vmexit_suspend(struct vmctx *ctx, struct vcpu *vcpu, struct vm_run *vmrun) exit(1); case VM_SUSPEND_HALT: exit(2); + case VM_SUSPEND_DESTROY: + exit(4); default: fprintf(stderr, "vmexit_suspend: invalid reason %d\n", how); exit(100); diff --git a/usr.sbin/bhyve/amd64/Makefile.inc b/usr.sbin/bhyve/amd64/Makefile.inc index 92e53433ff01..50a011ed4bfd 100644 --- a/usr.sbin/bhyve/amd64/Makefile.inc +++ b/usr.sbin/bhyve/amd64/Makefile.inc @@ -13,6 +13,7 @@ SRCS+= \ pci_gvt-d.c \ pci_lpc.c \ pci_passthru.c \ + pci_passthru_quirks.c \ pctestdev.c \ pm.c \ post.c \ diff --git a/usr.sbin/bhyve/amd64/vmexit.c b/usr.sbin/bhyve/amd64/vmexit.c index 944f5de34645..14f89563fd0f 100644 --- a/usr.sbin/bhyve/amd64/vmexit.c +++ b/usr.sbin/bhyve/amd64/vmexit.c @@ -418,6 +418,8 @@ vmexit_suspend(struct vmctx *ctx, struct vcpu *vcpu, struct vm_run *vmrun) exit(2); case VM_SUSPEND_TRIPLEFAULT: exit(3); + case VM_SUSPEND_DESTROY: + exit(4); default: EPRINTLN("vmexit_suspend: invalid reason %d", how); exit(100); diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8 index 89c0b23961a8..c902c265da9e 100644 --- a/usr.sbin/bhyve/bhyve.8 +++ b/usr.sbin/bhyve/bhyve.8 @@ -1126,7 +1126,7 @@ powered off .It 2 halted .It 3 -triple fault +triple fault (amd64 only) .It 4 exited due to an error .El diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c index 9ead49582a7d..bfc0b949a75d 100644 --- a/usr.sbin/bhyve/bhyverun.c +++ b/usr.sbin/bhyve/bhyverun.c @@ -561,10 +561,8 @@ fbsdrun_start_thread(void *param) #endif vm_loop(vi->ctx, vi->vcpu); - - /* not reached */ - exit(1); - return (NULL); + /* We get here if the VM was destroyed asynchronously. */ + exit(4); } void diff --git a/usr.sbin/bhyve/pci_passthru_quirks.c b/usr.sbin/bhyve/pci_passthru_quirks.c new file mode 100644 index 000000000000..5ba0e674f311 --- /dev/null +++ b/usr.sbin/bhyve/pci_passthru_quirks.c @@ -0,0 +1,48 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2025 Beckhoff Automation GmbH & Co. KG + * Author: Corvin Köhne <c.koehne@beckhoff.com> + */ + +#include <dev/pci/pcireg.h> + +#include <errno.h> + +#include "pci_passthru.h" + +#define PCI_VENDOR_NVIDIA 0x10DE + +static int +nvidia_gpu_probe(struct pci_devinst *const pi) +{ + struct passthru_softc *sc; + uint16_t vendor; + uint8_t class; + + sc = pi->pi_arg; + + vendor = pci_host_read_config(passthru_get_sel(sc), PCIR_VENDOR, 0x02); + if (vendor != PCI_VENDOR_NVIDIA) + return (ENXIO); + + class = pci_host_read_config(passthru_get_sel(sc), PCIR_CLASS, 0x01); + if (class != PCIC_DISPLAY) + return (ENXIO); + + return (0); +} + +static int +nvidia_gpu_init(struct pci_devinst *const pi, nvlist_t *const nvl __unused) +{ + pci_set_cfgdata8(pi, PCIR_INTPIN, 1); + + return (0); +} + +static struct passthru_dev nvidia_gpu = { + .probe = nvidia_gpu_probe, + .init = nvidia_gpu_init, +}; +PASSTHRU_DEV_SET(nvidia_gpu); diff --git a/usr.sbin/bhyve/pci_xhci.c b/usr.sbin/bhyve/pci_xhci.c index 0871bbb87fe5..ff12e40359e2 100644 --- a/usr.sbin/bhyve/pci_xhci.c +++ b/usr.sbin/bhyve/pci_xhci.c @@ -406,7 +406,7 @@ pci_xhci_usbcmd_write(struct pci_xhci_softc *sc, uint32_t cmd) * XHCI 4.19.3 USB2 RxDetect->Polling, * USB3 Polling->U0 */ - if (dev->dev_ue->ue_usbver == 2) + if (dev->hci.hci_usbver == 2) port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_POLL); else @@ -2590,7 +2590,7 @@ pci_xhci_reset_port(struct pci_xhci_softc *sc, int portn, int warm) port->portsc |= XHCI_PS_PED | XHCI_PS_SPEED_SET(dev->hci.hci_speed); - if (warm && dev->dev_ue->ue_usbver == 3) { + if (warm && dev->hci.hci_usbver == 3) { port->portsc |= XHCI_PS_WRC; } @@ -2620,7 +2620,7 @@ pci_xhci_init_port(struct pci_xhci_softc *sc, int portn) port->portsc = XHCI_PS_CCS | /* connected */ XHCI_PS_PP; /* port power */ - if (dev->dev_ue->ue_usbver == 2) { + if (dev->hci.hci_usbver == 2) { port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_POLL) | XHCI_PS_SPEED_SET(dev->hci.hci_speed); } else { @@ -2785,8 +2785,8 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl) cookie = NULL; while ((name = nvlist_next(slots_nvl, &type, &cookie)) != NULL) { - if (usb2_port == ((sc->usb2_port_start) + XHCI_MAX_DEVS/2) || - usb3_port == ((sc->usb3_port_start) + XHCI_MAX_DEVS/2)) { + if (usb2_port == ((sc->usb2_port_start) + XHCI_MAX_DEVS / 2) || + usb3_port == ((sc->usb3_port_start) + XHCI_MAX_DEVS / 2)) { WPRINTF(("pci_xhci max number of USB 2 or 3 " "devices reached, max %d", XHCI_MAX_DEVS/2)); goto bad; @@ -2834,12 +2834,25 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl) dev->hci.hci_intr = pci_xhci_dev_intr; dev->hci.hci_event = pci_xhci_dev_event; dev->hci.hci_speed = USB_SPEED_MAX; + dev->hci.hci_usbver = -1; - if (ue->ue_usbver == 2) { + devsc = ue->ue_probe(&dev->hci, nvl); + if (devsc == NULL) { + free(dev); + goto bad; + } + dev->dev_sc = devsc; + + if (dev->hci.hci_usbver == -1) + dev->hci.hci_usbver = ue->ue_usbver; + + if (dev->hci.hci_usbver == 2) { if (usb2_port == sc->usb2_port_start + XHCI_MAX_DEVS / 2) { WPRINTF(("pci_xhci max number of USB 2 devices " "reached, max %d", XHCI_MAX_DEVS / 2)); + free(dev->dev_sc); + free(dev); goto bad; } dev->hci.hci_port = usb2_port; @@ -2849,6 +2862,8 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl) XHCI_MAX_DEVS / 2) { WPRINTF(("pci_xhci max number of USB 3 devices " "reached, max %d", XHCI_MAX_DEVS / 2)); + free(dev->dev_sc); + free(dev); goto bad; } dev->hci.hci_port = usb3_port; @@ -2857,13 +2872,10 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl) XHCI_DEVINST_PTR(sc, dev->hci.hci_port) = dev; dev->hci.hci_address = 0; - devsc = ue->ue_init(&dev->hci, nvl); - if (devsc == NULL) { + if (ue->ue_init(dev->dev_sc)) goto bad; - } dev->dev_ue = ue; - dev->dev_sc = devsc; if (dev->hci.hci_speed == USB_SPEED_MAX) dev->hci.hci_speed = ue->ue_usbspeed; @@ -2885,6 +2897,8 @@ portsfinal: bad: for (i = 1; i <= XHCI_MAX_DEVS; i++) { + if (XHCI_DEVINST_PTR(sc, i) != NULL) + free(XHCI_DEVINST_PTR(sc, i)->dev_sc); free(XHCI_DEVINST_PTR(sc, i)); } @@ -3232,6 +3246,7 @@ pci_xhci_snapshot(struct vm_snapshot_meta *meta) SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_address, meta, ret, done); SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_port, meta, ret, done); SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_speed, meta, ret, done); + SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_usbver, meta, ret, done); } SNAPSHOT_VAR_OR_LEAVE(sc->usb2_port_start, meta, ret, done); diff --git a/usr.sbin/bhyve/rfb.c b/usr.sbin/bhyve/rfb.c index 6af374a83bbe..716e191e2fc0 100644 --- a/usr.sbin/bhyve/rfb.c +++ b/usr.sbin/bhyve/rfb.c @@ -63,6 +63,7 @@ #include "bhyvegc.h" #include "debug.h" #include "console.h" +#include "config.h" #include "rfb.h" #include "sockstream.h" @@ -152,6 +153,8 @@ struct rfb_softc { struct pixfmt pixfmt; /* owned by the write thread */ struct pixfmt new_pixfmt; /* managed with pixfmt_mtx */ uint32_t *pixrow; + char *fbname; + int fbnamelen; }; struct rfb_pixfmt { @@ -262,7 +265,7 @@ struct rfb_cuttext_msg { }; static void -rfb_send_server_init_msg(int cfd) +rfb_send_server_init_msg(struct rfb_softc *rc, int cfd) { struct bhyvegc_image *gc_image; struct rfb_srvr_info sinfo; @@ -284,9 +287,9 @@ rfb_send_server_init_msg(int cfd) sinfo.pixfmt.pad[0] = 0; sinfo.pixfmt.pad[1] = 0; sinfo.pixfmt.pad[2] = 0; - sinfo.namelen = htonl(strlen("bhyve")); + sinfo.namelen = htonl(rc->fbnamelen); (void)stream_write(cfd, &sinfo, sizeof(sinfo)); - (void)stream_write(cfd, "bhyve", strlen("bhyve")); + (void)stream_write(cfd, rc->fbname, rc->fbnamelen); } static void @@ -1144,7 +1147,7 @@ report_and_done: len = stream_read(cfd, buf, 1); /* 4a. Write server-init info */ - rfb_send_server_init_msg(cfd); + rfb_send_server_init_msg(rc, cfd); if (!rc->zbuf) { rc->zbuf = malloc(RFB_ZLIB_BUFSZ + 16); @@ -1276,6 +1279,13 @@ rfb_init(const char *hostname, int port, int wait, const char *password) rc->password = password; + rc->fbnamelen = asprintf(&rc->fbname, "bhyve:%s", + get_config_value("name")); + if (rc->fbnamelen < 0) { + EPRINTLN("rfb: failed to allocate memory for VNC title"); + goto error; + } + rc->pixrow = malloc(RFB_MAX_WIDTH * sizeof(uint32_t)); if (rc->pixrow == NULL) { EPRINTLN("rfb: failed to allocate memory for pixrow buffer"); @@ -1358,6 +1368,7 @@ rfb_init(const char *hostname, int port, int wait, const char *password) free(rc->crc); free(rc->crc_tmp); free(rc->pixrow); + free(rc->fbname); free(rc); return (-1); } diff --git a/usr.sbin/bhyve/riscv/vmexit.c b/usr.sbin/bhyve/riscv/vmexit.c index 3bc83b3bef4e..985f8e4e9065 100644 --- a/usr.sbin/bhyve/riscv/vmexit.c +++ b/usr.sbin/bhyve/riscv/vmexit.c @@ -121,6 +121,8 @@ vmexit_suspend(struct vmctx *ctx, struct vcpu *vcpu, struct vm_run *vmrun) exit(1); case VM_SUSPEND_HALT: exit(2); + case VM_SUSPEND_DESTROY: + exit(4); default: fprintf(stderr, "vmexit_suspend: invalid reason %d\n", how); exit(100); diff --git a/usr.sbin/bhyve/usb_emul.h b/usr.sbin/bhyve/usb_emul.h index 85dedfeacd3b..43b6b53b5205 100644 --- a/usr.sbin/bhyve/usb_emul.h +++ b/usr.sbin/bhyve/usb_emul.h @@ -52,7 +52,8 @@ struct usb_devemu { int ue_usbspeed; /* usb device speed */ /* instance creation */ - void *(*ue_init)(struct usb_hci *hci, nvlist_t *nvl); + void *(*ue_probe)(struct usb_hci *hci, nvlist_t *nvl); + int (*ue_init)(void *sc); /* handlers */ int (*ue_request)(void *sc, struct usb_data_xfer *xfer); @@ -86,6 +87,7 @@ struct usb_hci { int hci_address; int hci_port; int hci_speed; + int hci_usbver; }; /* diff --git a/usr.sbin/bhyve/usb_mouse.c b/usr.sbin/bhyve/usb_mouse.c index a37941c0cd9d..82b1159d5f61 100644 --- a/usr.sbin/bhyve/usb_mouse.c +++ b/usr.sbin/bhyve/usb_mouse.c @@ -295,20 +295,28 @@ umouse_event(uint8_t button, int x, int y, void *arg) } static void * -umouse_init(struct usb_hci *hci, nvlist_t *nvl __unused) +umouse_probe(struct usb_hci *hci, nvlist_t *nvl __unused) { struct umouse_softc *sc; sc = calloc(1, sizeof(struct umouse_softc)); sc->hci = hci; + return (sc); +} + +static int +umouse_init(void *scarg) +{ + struct umouse_softc *sc = (struct umouse_softc *)scarg; + sc->hid.protocol = 1; /* REPORT protocol */ pthread_mutex_init(&sc->mtx, NULL); pthread_mutex_init(&sc->ev_mtx, NULL); console_ptr_register(umouse_event, sc, 10); - return (sc); + return (0); } #define UREQ(x,y) ((x) | ((y) << 8)) @@ -811,6 +819,7 @@ static struct usb_devemu ue_mouse = { .ue_emu = "tablet", .ue_usbver = 3, .ue_usbspeed = USB_SPEED_HIGH, + .ue_probe = umouse_probe, .ue_init = umouse_init, .ue_request = umouse_request, .ue_data = umouse_data_handler, |