From 59d65d3175825093531e82f44269d948ed510a00 Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Sun, 6 Nov 2022 00:53:40 +0000 Subject: [PATCH] 15325 bhyve upstream sync 2023 January Reviewed by: Jorge Schrauwen Reviewed by: Jason King Reviewed by: Patrick Mooney Approved by: Robert Mustacchi --- exception_lists/copyright | 1 + exception_lists/cstyle | 1 + exception_lists/hdrchk | 1 + exception_lists/wscheck | 1 + usr/src/cmd/bhyve/Makefile | 20 +- usr/src/cmd/bhyve/README.sync | 6 +- usr/src/cmd/bhyve/acpi.c | 1793 ++++++++++------------- usr/src/cmd/bhyve/atkbdc.c | 8 +- usr/src/cmd/bhyve/audio.c | 28 +- usr/src/cmd/bhyve/audio.h | 4 +- usr/src/cmd/bhyve/basl.c | 608 ++++++++ usr/src/cmd/bhyve/basl.h | 125 ++ usr/src/cmd/bhyve/bhyverun.c | 425 +++--- usr/src/cmd/bhyve/bhyverun.h | 16 +- usr/src/cmd/bhyve/block_if.c | 62 +- usr/src/cmd/bhyve/bootrom.c | 5 +- usr/src/cmd/bhyve/config.c | 19 +- usr/src/cmd/bhyve/config.h | 2 +- usr/src/cmd/bhyve/fwctl.c | 36 +- usr/src/cmd/bhyve/gdb.c | 16 +- usr/src/cmd/bhyve/hda_codec.c | 8 +- usr/src/cmd/bhyve/hexdump.c | 97 ++ usr/src/cmd/bhyve/{post.c => hexdump.h} | 51 +- usr/src/cmd/bhyve/inout.c | 6 +- usr/src/cmd/bhyve/inout.h | 2 +- usr/src/cmd/bhyve/iov.c | 4 +- usr/src/cmd/bhyve/mem.c | 4 + usr/src/cmd/bhyve/mevent.c | 2 +- usr/src/cmd/bhyve/mptbl.c | 4 +- usr/src/cmd/bhyve/net_backends.c | 85 +- usr/src/cmd/bhyve/pci_ahci.c | 61 +- usr/src/cmd/bhyve/pci_e82545.c | 107 +- usr/src/cmd/bhyve/pci_emul.c | 93 +- usr/src/cmd/bhyve/pci_emul.h | 8 +- usr/src/cmd/bhyve/pci_fbuf.c | 9 +- usr/src/cmd/bhyve/pci_hda.c | 57 +- usr/src/cmd/bhyve/pci_hda.h | 4 +- usr/src/cmd/bhyve/pci_hostbridge.c | 6 +- usr/src/cmd/bhyve/pci_irq.c | 46 +- usr/src/cmd/bhyve/pci_lpc.c | 23 +- usr/src/cmd/bhyve/pci_nvme.c | 93 +- usr/src/cmd/bhyve/pci_passthru.c | 48 +- usr/src/cmd/bhyve/pci_uart.c | 14 +- usr/src/cmd/bhyve/pci_virtio_9p.c | 44 +- usr/src/cmd/bhyve/pci_virtio_block.c | 33 +- usr/src/cmd/bhyve/pci_virtio_console.c | 40 +- usr/src/cmd/bhyve/pci_virtio_input.c | 28 +- usr/src/cmd/bhyve/pci_virtio_net.c | 22 +- usr/src/cmd/bhyve/pci_virtio_rnd.c | 19 +- usr/src/cmd/bhyve/pci_virtio_scsi.c | 88 +- usr/src/cmd/bhyve/pci_virtio_viona.c | 4 +- usr/src/cmd/bhyve/pci_xhci.c | 125 +- usr/src/cmd/bhyve/pci_xhci.h | 64 +- usr/src/cmd/bhyve/pctestdev.c | 23 +- usr/src/cmd/bhyve/pm.c | 30 +- usr/src/cmd/bhyve/post.c | 4 +- usr/src/cmd/bhyve/ps2kbd.c | 120 +- usr/src/cmd/bhyve/ps2mouse.c | 3 +- usr/src/cmd/bhyve/rtc.c | 4 +- usr/src/cmd/bhyve/smbiostbl.c | 181 +-- usr/src/cmd/bhyve/spinup_ap.c | 49 +- usr/src/cmd/bhyve/spinup_ap.h | 6 +- usr/src/cmd/bhyve/task_switch.c | 2 +- usr/src/cmd/bhyve/uart_emul.c | 2 +- usr/src/cmd/bhyve/usb_emul.h | 2 +- usr/src/cmd/bhyve/usb_mouse.c | 4 +- usr/src/cmd/bhyve/vga.c | 4 +- usr/src/cmd/bhyve/virtio.c | 24 +- usr/src/cmd/bhyve/virtio.h | 12 +- usr/src/cmd/bhyve/xmsr.c | 1 + usr/src/compat/bhyve/amd64/machine/specialreg.h | 9 +- usr/src/contrib/bhyve/dev/nvme/nvme.h | 20 +- usr/src/contrib/bhyve/x86/specialreg.h | 94 +- usr/src/data/bhyve/kbdlayout/de | 3 + usr/src/data/bhyve/kbdlayout/de_acc | 3 + usr/src/data/bhyve/kbdlayout/de_noacc | 3 + usr/src/uts/intel/io/vmm/io/ppt.c | 5 + usr/src/uts/intel/io/vmm/io/vlapic.c | 106 +- usr/src/uts/intel/io/vmm/vmm_instruction_emul.c | 4 +- 79 files changed, 3035 insertions(+), 2159 deletions(-) rewrite usr/src/cmd/bhyve/acpi.c (71%) create mode 100644 usr/src/cmd/bhyve/basl.c create mode 100644 usr/src/cmd/bhyve/basl.h create mode 100644 usr/src/cmd/bhyve/hexdump.c copy usr/src/cmd/bhyve/{post.c => hexdump.h} (50%) diff --git a/exception_lists/copyright b/exception_lists/copyright index 2688984285..60f724e47d 100644 --- a/exception_lists/copyright +++ b/exception_lists/copyright @@ -481,6 +481,7 @@ usr/src/cmd/bhyve/THIRDPARTYLICENSE.descrip usr/src/cmd/bhyve/acpi.[ch] usr/src/cmd/bhyve/ahci.h usr/src/cmd/bhyve/atkbdc.[ch] +usr/src/cmd/bhyve/basl.[ch] usr/src/cmd/bhyve/bhyvegc.[ch] usr/src/cmd/bhyve/bhyverun.[ch] usr/src/cmd/bhyve/block_if.[ch] diff --git a/exception_lists/cstyle b/exception_lists/cstyle index 814d5534cc..e399026043 100644 --- a/exception_lists/cstyle +++ b/exception_lists/cstyle @@ -1323,6 +1323,7 @@ usr/src/cmd/bhyve/acpi.[ch] usr/src/cmd/bhyve/ahci.h usr/src/cmd/bhyve/atkbdc.[ch] usr/src/cmd/bhyve/audio.[ch] +usr/src/cmd/bhyve/basl.[ch] usr/src/cmd/bhyve/bhyvegc.[ch] usr/src/cmd/bhyve/bhyverun.[ch] usr/src/cmd/bhyve/block_if.[ch] diff --git a/exception_lists/hdrchk b/exception_lists/hdrchk index 8985ced0e0..ef07991f3e 100644 --- a/exception_lists/hdrchk +++ b/exception_lists/hdrchk @@ -388,6 +388,7 @@ usr/src/cmd/bhyve/acpi.h usr/src/cmd/bhyve/ahci.h usr/src/cmd/bhyve/atkbdc.h usr/src/cmd/bhyve/audio.h +usr/src/cmd/bhyve/basl.h usr/src/cmd/bhyve/bhyvegc.h usr/src/cmd/bhyve/bhyverun.h usr/src/cmd/bhyve/block_if.h diff --git a/exception_lists/wscheck b/exception_lists/wscheck index 41e2272227..3f044605d7 100644 --- a/exception_lists/wscheck +++ b/exception_lists/wscheck @@ -39,6 +39,7 @@ usr/src/cmd/bhyve/acpi.[ch] usr/src/cmd/bhyve/ahci.h usr/src/cmd/bhyve/atkbdc.[ch] usr/src/cmd/bhyve/audio.[ch] +usr/src/cmd/bhyve/basl.[ch] usr/src/cmd/bhyve/bhyvegc.[ch] usr/src/cmd/bhyve/bhyverun.[ch] usr/src/cmd/bhyve/block_if.[ch] diff --git a/usr/src/cmd/bhyve/Makefile b/usr/src/cmd/bhyve/Makefile index 509c389f11..847d4d947c 100644 --- a/usr/src/cmd/bhyve/Makefile +++ b/usr/src/cmd/bhyve/Makefile @@ -31,6 +31,7 @@ clobber := TARGET = clobber SRCS = acpi.c \ atkbdc.c \ + basl.c \ bhyvegc.c \ bhyverun.c \ block_if.c \ @@ -39,6 +40,7 @@ SRCS = acpi.c \ config.c \ fwctl.c \ gdb.c \ + hexdump.c \ inout.c \ ioapic.c \ mem.c \ @@ -113,7 +115,7 @@ CLEANFILES = $(OBJS) $(MEVENT_TEST_OBJS) CLOBBERFILES = $(PROG) $(MEVENT_TEST_PROG) CFLAGS += $(CCVERBOSE) -CFLAGS += -_gcc=-Wimplicit-function-declaration -_gcc=-Wno-parentheses +CFLAGS += -_gcc=-Wimplicit-function-declaration CPPFLAGS = -I$(COMPAT)/bhyve -I$(CONTRIB)/bhyve \ -I$(COMPAT)/bhyve/amd64 -I$(CONTRIB)/bhyve/amd64 \ -I$(CONTRIB)/bhyve/dev/usb/controller \ @@ -126,21 +128,7 @@ CPPFLAGS = -I$(COMPAT)/bhyve -I$(CONTRIB)/bhyve \ -I$(SRC)/uts/intel \ -DWITHOUT_CAPSICUM -pci_nvme.o := CERRWARN += -_gcc=-Wno-pointer-sign -pci_nvme.o := CERRWARN += -_gcc10=-Wno-address-of-packed-member -pci_nvme.o := CERRWARN += -_gcc11=-Wno-address-of-packed-member -pci_nvme.o := SMOFF += kmalloc_wrong_size - -pci_passthru.o := CERRWARN += -_gcc10=-Wno-address-of-packed-member -pci_passthru.o := CERRWARN += -_gcc11=-Wno-address-of-packed-member - -pci_virtio_9p.o := SMOFF += kmalloc_wrong_size - -pci_xhci.o := CERRWARN += -_gcc10=-Wno-address-of-packed-member -pci_xhci.o := CERRWARN += -_gcc11=-Wno-address-of-packed-member - -SMOFF += all_func_returns,leaks,no_if_block - +SMOFF += all_func_returns rfb.o := SMOFF= # Force c99 for everything diff --git a/usr/src/cmd/bhyve/README.sync b/usr/src/cmd/bhyve/README.sync index 8175237b32..1044f74274 100644 --- a/usr/src/cmd/bhyve/README.sync +++ b/usr/src/cmd/bhyve/README.sync @@ -5,11 +5,11 @@ The bhyve userland code in this directory, and its associated libraries and parts of the kernel module have been updated to the latest upstream FreeBSD sources as of: - commit fa46f3704b7618f9d9493c126df781faf59040a8 + commit e53fcff1848bb5acafc3dc38cfeb34724d9b0b96 Author: John Baldwin - Date: Wed Aug 17 10:01:16 2022 -0700 + Date: Wed Dec 21 10:33:34 2022 -0800 - bhyve e1000: Skip packets with a small header. + bhyve: Simplify spinup_ap_realmode slightly. Divergence Notes: diff --git a/usr/src/cmd/bhyve/acpi.c b/usr/src/cmd/bhyve/acpi.c dissimilarity index 71% index fd0a6f732e..466f435ac2 100644 --- a/usr/src/cmd/bhyve/acpi.c +++ b/usr/src/cmd/bhyve/acpi.c @@ -1,1005 +1,788 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2012 NetApp, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * bhyve ACPI table generator. - * - * Create the minimal set of ACPI tables required to boot FreeBSD (and - * hopefully other o/s's) by writing out ASL template files for each of - * the tables and the compiling them to AML with the Intel iasl compiler. - * The AML files are then read into guest memory. - * - * The tables are placed in the guest's ROM area just below 1MB physical, - * above the MPTable. - * - * Layout (No longer correct at FADT and beyond due to properly - * calculating the size of the MADT to allow for changes to - * VM_MAXCPU above 21 which overflows this layout.) - * ------ - * RSDP -> 0xf2400 (36 bytes fixed) - * RSDT -> 0xf2440 (36 bytes + 4*7 table addrs, 4 used) - * XSDT -> 0xf2480 (36 bytes + 8*7 table addrs, 4 used) - * MADT -> 0xf2500 (depends on #CPUs) - * FADT -> 0xf2600 (268 bytes) - * HPET -> 0xf2740 (56 bytes) - * MCFG -> 0xf2780 (60 bytes) - * FACS -> 0xf27C0 (64 bytes) - * DSDT -> 0xf2800 (variable - can go up to 0x100000) - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "bhyverun.h" -#include "acpi.h" -#include "pci_emul.h" -#include "vmgenc.h" - -/* - * Define the base address of the ACPI tables, the sizes of some tables, - * and the offsets to the individual tables, - */ -#define BHYVE_ACPI_BASE 0xf2400 -#define RSDT_OFFSET 0x040 -#define XSDT_OFFSET 0x080 -#define MADT_OFFSET 0x100 -/* - * The MADT consists of: - * 44 Fixed Header - * 8 * maxcpu Processor Local APIC entries - * 12 I/O APIC entry - * 2 * 10 Interrupt Source Override entries - * 6 Local APIC NMI entry - */ -#define MADT_SIZE roundup2((44 + basl_ncpu*8 + 12 + 2*10 + 6), 0x100) -#define FADT_OFFSET (MADT_OFFSET + MADT_SIZE) -#define FADT_SIZE 0x140 -#define HPET_OFFSET (FADT_OFFSET + FADT_SIZE) -#define HPET_SIZE 0x40 -#define MCFG_OFFSET (HPET_OFFSET + HPET_SIZE) -#define MCFG_SIZE 0x40 -#define FACS_OFFSET (MCFG_OFFSET + MCFG_SIZE) -#define FACS_SIZE 0x40 -#define DSDT_OFFSET (FACS_OFFSET + FACS_SIZE) - -#define BHYVE_ASL_TEMPLATE "bhyve.XXXXXXX" -#define BHYVE_ASL_SUFFIX ".aml" -#define BHYVE_ASL_COMPILER "/usr/sbin/iasl" - -static int basl_keep_temps; -static int basl_verbose_iasl; -static int basl_ncpu; -static uint32_t basl_acpi_base = BHYVE_ACPI_BASE; -static uint32_t hpet_capabilities; - -/* - * Contains the full pathname of the template to be passed - * to mkstemp/mktemps(3) - */ -static char basl_template[MAXPATHLEN]; -static char basl_stemplate[MAXPATHLEN]; - -/* - * State for dsdt_line(), dsdt_indent(), and dsdt_unindent(). - */ -static FILE *dsdt_fp; -static int dsdt_indent_level; -static int dsdt_error; - -struct basl_fio { - int fd; - FILE *fp; - char f_name[MAXPATHLEN]; -}; - -#define EFPRINTF(...) \ - if (fprintf(__VA_ARGS__) < 0) goto err_exit; - -#define EFFLUSH(x) \ - if (fflush(x) != 0) goto err_exit; - -static int -basl_fwrite_rsdp(FILE *fp) -{ - EFPRINTF(fp, "/*\n"); - EFPRINTF(fp, " * bhyve RSDP template\n"); - EFPRINTF(fp, " */\n"); - EFPRINTF(fp, "[0008]\t\tSignature : \"RSD PTR \"\n"); - EFPRINTF(fp, "[0001]\t\tChecksum : 43\n"); - EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); - EFPRINTF(fp, "[0001]\t\tRevision : 02\n"); - EFPRINTF(fp, "[0004]\t\tRSDT Address : %08X\n", - basl_acpi_base + RSDT_OFFSET); - EFPRINTF(fp, "[0004]\t\tLength : 00000024\n"); - EFPRINTF(fp, "[0008]\t\tXSDT Address : 00000000%08X\n", - basl_acpi_base + XSDT_OFFSET); - EFPRINTF(fp, "[0001]\t\tExtended Checksum : 00\n"); - EFPRINTF(fp, "[0003]\t\tReserved : 000000\n"); - - EFFLUSH(fp); - - return (0); - -err_exit: - return (errno); -} - -static int -basl_fwrite_rsdt(FILE *fp) -{ - EFPRINTF(fp, "/*\n"); - EFPRINTF(fp, " * bhyve RSDT template\n"); - EFPRINTF(fp, " */\n"); - EFPRINTF(fp, "[0004]\t\tSignature : \"RSDT\"\n"); - EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); - EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); - EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); - EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); - EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVRSDT \"\n"); - EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); - /* iasl will fill in the compiler ID/revision fields */ - EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); - EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); - EFPRINTF(fp, "\n"); - - /* Add in pointers to the MADT, FADT and HPET */ - EFPRINTF(fp, "[0004]\t\tACPI Table Address 0 : %08X\n", - basl_acpi_base + MADT_OFFSET); - EFPRINTF(fp, "[0004]\t\tACPI Table Address 1 : %08X\n", - basl_acpi_base + FADT_OFFSET); - EFPRINTF(fp, "[0004]\t\tACPI Table Address 2 : %08X\n", - basl_acpi_base + HPET_OFFSET); - EFPRINTF(fp, "[0004]\t\tACPI Table Address 3 : %08X\n", - basl_acpi_base + MCFG_OFFSET); - - EFFLUSH(fp); - - return (0); - -err_exit: - return (errno); -} - -static int -basl_fwrite_xsdt(FILE *fp) -{ - EFPRINTF(fp, "/*\n"); - EFPRINTF(fp, " * bhyve XSDT template\n"); - EFPRINTF(fp, " */\n"); - EFPRINTF(fp, "[0004]\t\tSignature : \"XSDT\"\n"); - EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); - EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); - EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); - EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); - EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVXSDT \"\n"); - EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); - /* iasl will fill in the compiler ID/revision fields */ - EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); - EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); - EFPRINTF(fp, "\n"); - - /* Add in pointers to the MADT, FADT and HPET */ - EFPRINTF(fp, "[0004]\t\tACPI Table Address 0 : 00000000%08X\n", - basl_acpi_base + MADT_OFFSET); - EFPRINTF(fp, "[0004]\t\tACPI Table Address 1 : 00000000%08X\n", - basl_acpi_base + FADT_OFFSET); - EFPRINTF(fp, "[0004]\t\tACPI Table Address 2 : 00000000%08X\n", - basl_acpi_base + HPET_OFFSET); - EFPRINTF(fp, "[0004]\t\tACPI Table Address 3 : 00000000%08X\n", - basl_acpi_base + MCFG_OFFSET); - - EFFLUSH(fp); - - return (0); - -err_exit: - return (errno); -} - -static int -basl_fwrite_madt(FILE *fp) -{ - int i; - - EFPRINTF(fp, "/*\n"); - EFPRINTF(fp, " * bhyve MADT template\n"); - EFPRINTF(fp, " */\n"); - EFPRINTF(fp, "[0004]\t\tSignature : \"APIC\"\n"); - EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); - EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); - EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); - EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); - EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVMADT \"\n"); - EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); - - /* iasl will fill in the compiler ID/revision fields */ - EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); - EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, "[0004]\t\tLocal Apic Address : FEE00000\n"); - EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000001\n"); - EFPRINTF(fp, "\t\t\tPC-AT Compatibility : 1\n"); - EFPRINTF(fp, "\n"); - - /* Add a Processor Local APIC entry for each CPU */ - for (i = 0; i < basl_ncpu; i++) { - EFPRINTF(fp, "[0001]\t\tSubtable Type : 00\n"); - EFPRINTF(fp, "[0001]\t\tLength : 08\n"); - /* iasl expects hex values for the proc and apic id's */ - EFPRINTF(fp, "[0001]\t\tProcessor ID : %02x\n", i); - EFPRINTF(fp, "[0001]\t\tLocal Apic ID : %02x\n", i); - EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000001\n"); - EFPRINTF(fp, "\t\t\tProcessor Enabled : 1\n"); -#ifdef __FreeBSD__ - EFPRINTF(fp, "\t\t\tRuntime Online Capable : 0\n"); -#else - /* - * Until iasl is updated to support the "Runtime Online - * Capable" entry, it must be omitted. This should be - * re-checked when illumos receives an acpica update. - */ -#endif /* __FreeBSD__ */ - EFPRINTF(fp, "\n"); - } - - /* Always a single IOAPIC entry, with ID 0 */ - EFPRINTF(fp, "[0001]\t\tSubtable Type : 01\n"); - EFPRINTF(fp, "[0001]\t\tLength : 0C\n"); - /* iasl expects a hex value for the i/o apic id */ - EFPRINTF(fp, "[0001]\t\tI/O Apic ID : %02x\n", 0); - EFPRINTF(fp, "[0001]\t\tReserved : 00\n"); - EFPRINTF(fp, "[0004]\t\tAddress : fec00000\n"); - EFPRINTF(fp, "[0004]\t\tInterrupt : 00000000\n"); - EFPRINTF(fp, "\n"); - - /* Legacy IRQ0 is connected to pin 2 of the IOAPIC */ - EFPRINTF(fp, "[0001]\t\tSubtable Type : 02\n"); - EFPRINTF(fp, "[0001]\t\tLength : 0A\n"); - EFPRINTF(fp, "[0001]\t\tBus : 00\n"); - EFPRINTF(fp, "[0001]\t\tSource : 00\n"); - EFPRINTF(fp, "[0004]\t\tInterrupt : 00000002\n"); - EFPRINTF(fp, "[0002]\t\tFlags (decoded below) : 0005\n"); - EFPRINTF(fp, "\t\t\tPolarity : 1\n"); - EFPRINTF(fp, "\t\t\tTrigger Mode : 1\n"); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, "[0001]\t\tSubtable Type : 02\n"); - EFPRINTF(fp, "[0001]\t\tLength : 0A\n"); - EFPRINTF(fp, "[0001]\t\tBus : 00\n"); - EFPRINTF(fp, "[0001]\t\tSource : %02X\n", SCI_INT); - EFPRINTF(fp, "[0004]\t\tInterrupt : %08X\n", SCI_INT); - EFPRINTF(fp, "[0002]\t\tFlags (decoded below) : 0000\n"); - EFPRINTF(fp, "\t\t\tPolarity : 3\n"); - EFPRINTF(fp, "\t\t\tTrigger Mode : 3\n"); - EFPRINTF(fp, "\n"); - - /* Local APIC NMI is connected to LINT 1 on all CPUs */ - EFPRINTF(fp, "[0001]\t\tSubtable Type : 04\n"); - EFPRINTF(fp, "[0001]\t\tLength : 06\n"); - EFPRINTF(fp, "[0001]\t\tProcessor ID : FF\n"); - EFPRINTF(fp, "[0002]\t\tFlags (decoded below) : 0005\n"); - EFPRINTF(fp, "\t\t\tPolarity : 1\n"); - EFPRINTF(fp, "\t\t\tTrigger Mode : 1\n"); - EFPRINTF(fp, "[0001]\t\tInterrupt Input LINT : 01\n"); - EFPRINTF(fp, "\n"); - - EFFLUSH(fp); - - return (0); - -err_exit: - return (errno); -} - -static int -basl_fwrite_fadt(FILE *fp) -{ - EFPRINTF(fp, "/*\n"); - EFPRINTF(fp, " * bhyve FADT template\n"); - EFPRINTF(fp, " */\n"); - EFPRINTF(fp, "[0004]\t\tSignature : \"FACP\"\n"); - EFPRINTF(fp, "[0004]\t\tTable Length : 0000010C\n"); - EFPRINTF(fp, "[0001]\t\tRevision : 05\n"); - EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); - EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); - EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVFACP \"\n"); - EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); - /* iasl will fill in the compiler ID/revision fields */ - EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); - EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, "[0004]\t\tFACS Address : %08X\n", - basl_acpi_base + FACS_OFFSET); - EFPRINTF(fp, "[0004]\t\tDSDT Address : %08X\n", - basl_acpi_base + DSDT_OFFSET); - EFPRINTF(fp, "[0001]\t\tModel : 01\n"); - EFPRINTF(fp, "[0001]\t\tPM Profile : 00 [Unspecified]\n"); - EFPRINTF(fp, "[0002]\t\tSCI Interrupt : %04X\n", - SCI_INT); - EFPRINTF(fp, "[0004]\t\tSMI Command Port : %08X\n", - SMI_CMD); - EFPRINTF(fp, "[0001]\t\tACPI Enable Value : %02X\n", - BHYVE_ACPI_ENABLE); - EFPRINTF(fp, "[0001]\t\tACPI Disable Value : %02X\n", - BHYVE_ACPI_DISABLE); - EFPRINTF(fp, "[0001]\t\tS4BIOS Command : 00\n"); - EFPRINTF(fp, "[0001]\t\tP-State Control : 00\n"); - EFPRINTF(fp, "[0004]\t\tPM1A Event Block Address : %08X\n", - PM1A_EVT_ADDR); - EFPRINTF(fp, "[0004]\t\tPM1B Event Block Address : 00000000\n"); - EFPRINTF(fp, "[0004]\t\tPM1A Control Block Address : %08X\n", - PM1A_CNT_ADDR); - EFPRINTF(fp, "[0004]\t\tPM1B Control Block Address : 00000000\n"); - EFPRINTF(fp, "[0004]\t\tPM2 Control Block Address : 00000000\n"); - EFPRINTF(fp, "[0004]\t\tPM Timer Block Address : %08X\n", - IO_PMTMR); - EFPRINTF(fp, "[0004]\t\tGPE0 Block Address : %08X\n", IO_GPE0_BLK); - EFPRINTF(fp, "[0004]\t\tGPE1 Block Address : 00000000\n"); - EFPRINTF(fp, "[0001]\t\tPM1 Event Block Length : 04\n"); - EFPRINTF(fp, "[0001]\t\tPM1 Control Block Length : 02\n"); - EFPRINTF(fp, "[0001]\t\tPM2 Control Block Length : 00\n"); - EFPRINTF(fp, "[0001]\t\tPM Timer Block Length : 04\n"); - EFPRINTF(fp, "[0001]\t\tGPE0 Block Length : %02x\n", IO_GPE0_LEN); - EFPRINTF(fp, "[0001]\t\tGPE1 Block Length : 00\n"); - EFPRINTF(fp, "[0001]\t\tGPE1 Base Offset : 00\n"); - EFPRINTF(fp, "[0001]\t\t_CST Support : 00\n"); - EFPRINTF(fp, "[0002]\t\tC2 Latency : 0000\n"); - EFPRINTF(fp, "[0002]\t\tC3 Latency : 0000\n"); - EFPRINTF(fp, "[0002]\t\tCPU Cache Size : 0000\n"); - EFPRINTF(fp, "[0002]\t\tCache Flush Stride : 0000\n"); - EFPRINTF(fp, "[0001]\t\tDuty Cycle Offset : 00\n"); - EFPRINTF(fp, "[0001]\t\tDuty Cycle Width : 00\n"); - EFPRINTF(fp, "[0001]\t\tRTC Day Alarm Index : 00\n"); - EFPRINTF(fp, "[0001]\t\tRTC Month Alarm Index : 00\n"); - EFPRINTF(fp, "[0001]\t\tRTC Century Index : 32\n"); - EFPRINTF(fp, "[0002]\t\tBoot Flags (decoded below) : 0000\n"); - EFPRINTF(fp, "\t\t\tLegacy Devices Supported (V2) : 0\n"); - EFPRINTF(fp, "\t\t\t8042 Present on ports 60/64 (V2) : 0\n"); - EFPRINTF(fp, "\t\t\tVGA Not Present (V4) : 1\n"); - EFPRINTF(fp, "\t\t\tMSI Not Supported (V4) : 0\n"); - EFPRINTF(fp, "\t\t\tPCIe ASPM Not Supported (V4) : 1\n"); - EFPRINTF(fp, "\t\t\tCMOS RTC Not Present (V5) : 0\n"); - EFPRINTF(fp, "[0001]\t\tReserved : 00\n"); - EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000000\n"); - EFPRINTF(fp, "\t\t\tWBINVD instruction is operational (V1) : 1\n"); - EFPRINTF(fp, "\t\t\tWBINVD flushes all caches (V1) : 0\n"); - EFPRINTF(fp, "\t\t\tAll CPUs support C1 (V1) : 1\n"); - EFPRINTF(fp, "\t\t\tC2 works on MP system (V1) : 0\n"); - EFPRINTF(fp, "\t\t\tControl Method Power Button (V1) : 0\n"); - EFPRINTF(fp, "\t\t\tControl Method Sleep Button (V1) : 1\n"); - EFPRINTF(fp, "\t\t\tRTC wake not in fixed reg space (V1) : 0\n"); - EFPRINTF(fp, "\t\t\tRTC can wake system from S4 (V1) : 0\n"); - EFPRINTF(fp, "\t\t\t32-bit PM Timer (V1) : 1\n"); - EFPRINTF(fp, "\t\t\tDocking Supported (V1) : 0\n"); - EFPRINTF(fp, "\t\t\tReset Register Supported (V2) : 1\n"); - EFPRINTF(fp, "\t\t\tSealed Case (V3) : 0\n"); - EFPRINTF(fp, "\t\t\tHeadless - No Video (V3) : 1\n"); - EFPRINTF(fp, "\t\t\tUse native instr after SLP_TYPx (V3) : 0\n"); - EFPRINTF(fp, "\t\t\tPCIEXP_WAK Bits Supported (V4) : 0\n"); - EFPRINTF(fp, "\t\t\tUse Platform Timer (V4) : 0\n"); - EFPRINTF(fp, "\t\t\tRTC_STS valid on S4 wake (V4) : 0\n"); - EFPRINTF(fp, "\t\t\tRemote Power-on capable (V4) : 0\n"); - EFPRINTF(fp, "\t\t\tUse APIC Cluster Model (V4) : 0\n"); - EFPRINTF(fp, "\t\t\tUse APIC Physical Destination Mode (V4) : 1\n"); - EFPRINTF(fp, "\t\t\tHardware Reduced (V5) : 0\n"); - EFPRINTF(fp, "\t\t\tLow Power S0 Idle (V5) : 0\n"); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, - "[0012]\t\tReset Register : [Generic Address Structure]\n"); - EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); - EFPRINTF(fp, "[0001]\t\tBit Width : 08\n"); - EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); - EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 01 [Byte Access:8]\n"); - EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000CF9\n"); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, "[0001]\t\tValue to cause reset : 06\n"); - EFPRINTF(fp, "[0002]\t\tARM Flags (decoded below): 0000\n"); - EFPRINTF(fp, "\t\t\tPSCI Compliant : 0\n"); - EFPRINTF(fp, "\t\t\tMust use HVC for PSCI : 0\n"); - EFPRINTF(fp, "[0001]\t\tFADT Minor Revision : 01\n"); - EFPRINTF(fp, "[0008]\t\tFACS Address : 00000000%08X\n", - basl_acpi_base + FACS_OFFSET); - EFPRINTF(fp, "[0008]\t\tDSDT Address : 00000000%08X\n", - basl_acpi_base + DSDT_OFFSET); - EFPRINTF(fp, - "[0012]\t\tPM1A Event Block : [Generic Address Structure]\n"); - EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); - EFPRINTF(fp, "[0001]\t\tBit Width : 20\n"); - EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); - EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 02 [Word Access:16]\n"); - EFPRINTF(fp, "[0008]\t\tAddress : 00000000%08X\n", - PM1A_EVT_ADDR); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, - "[0012]\t\tPM1B Event Block : [Generic Address Structure]\n"); - EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); - EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); - EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); - EFPRINTF(fp, - "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); - EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, - "[0012]\t\tPM1A Control Block : [Generic Address Structure]\n"); - EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); - EFPRINTF(fp, "[0001]\t\tBit Width : 10\n"); - EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); - EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 02 [Word Access:16]\n"); - EFPRINTF(fp, "[0008]\t\tAddress : 00000000%08X\n", - PM1A_CNT_ADDR); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, - "[0012]\t\tPM1B Control Block : [Generic Address Structure]\n"); - EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); - EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); - EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); - EFPRINTF(fp, - "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); - EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, - "[0012]\t\tPM2 Control Block : [Generic Address Structure]\n"); - EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); - EFPRINTF(fp, "[0001]\t\tBit Width : 08\n"); - EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); - EFPRINTF(fp, - "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); - EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); - EFPRINTF(fp, "\n"); - - /* Valid for bhyve */ - EFPRINTF(fp, - "[0012]\t\tPM Timer Block : [Generic Address Structure]\n"); - EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); - EFPRINTF(fp, "[0001]\t\tBit Width : 20\n"); - EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); - EFPRINTF(fp, - "[0001]\t\tEncoded Access Width : 03 [DWord Access:32]\n"); - EFPRINTF(fp, "[0008]\t\tAddress : 00000000%08X\n", - IO_PMTMR); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, "[0012]\t\tGPE0 Block : [Generic Address Structure]\n"); - EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); - EFPRINTF(fp, "[0001]\t\tBit Width : %02x\n", IO_GPE0_LEN * 8); - EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); - EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 01 [Byte Access:8]\n"); - EFPRINTF(fp, "[0008]\t\tAddress : %016X\n", IO_GPE0_BLK); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, "[0012]\t\tGPE1 Block : [Generic Address Structure]\n"); - EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); - EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); - EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); - EFPRINTF(fp, - "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); - EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, - "[0012]\t\tSleep Control Register : [Generic Address Structure]\n"); - EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); - EFPRINTF(fp, "[0001]\t\tBit Width : 08\n"); - EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); - EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 01 [Byte Access:8]\n"); - EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, - "[0012]\t\tSleep Status Register : [Generic Address Structure]\n"); - EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); - EFPRINTF(fp, "[0001]\t\tBit Width : 08\n"); - EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); - EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 01 [Byte Access:8]\n"); - EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); - - EFFLUSH(fp); - - return (0); - -err_exit: - return (errno); -} - -static int -basl_fwrite_hpet(FILE *fp) -{ - EFPRINTF(fp, "/*\n"); - EFPRINTF(fp, " * bhyve HPET template\n"); - EFPRINTF(fp, " */\n"); - EFPRINTF(fp, "[0004]\t\tSignature : \"HPET\"\n"); - EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); - EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); - EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); - EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); - EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVHPET \"\n"); - EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); - - /* iasl will fill in the compiler ID/revision fields */ - EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); - EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, "[0004]\t\tHardware Block ID : %08X\n", hpet_capabilities); - EFPRINTF(fp, - "[0012]\t\tTimer Block Register : [Generic Address Structure]\n"); - EFPRINTF(fp, "[0001]\t\tSpace ID : 00 [SystemMemory]\n"); - EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); - EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); - EFPRINTF(fp, - "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); - EFPRINTF(fp, "[0008]\t\tAddress : 00000000FED00000\n"); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, "[0001]\t\tSequence Number : 00\n"); - EFPRINTF(fp, "[0002]\t\tMinimum Clock Ticks : 0000\n"); - EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000001\n"); - EFPRINTF(fp, "\t\t\t4K Page Protect : 1\n"); - EFPRINTF(fp, "\t\t\t64K Page Protect : 0\n"); - EFPRINTF(fp, "\n"); - - EFFLUSH(fp); - - return (0); - -err_exit: - return (errno); -} - -static int -basl_fwrite_mcfg(FILE *fp) -{ - EFPRINTF(fp, "/*\n"); - EFPRINTF(fp, " * bhyve MCFG template\n"); - EFPRINTF(fp, " */\n"); - EFPRINTF(fp, "[0004]\t\tSignature : \"MCFG\"\n"); - EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); - EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); - EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); - EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); - EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVMCFG \"\n"); - EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); - - /* iasl will fill in the compiler ID/revision fields */ - EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); - EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); - EFPRINTF(fp, "[0008]\t\tReserved : 0\n"); - EFPRINTF(fp, "\n"); - - EFPRINTF(fp, "[0008]\t\tBase Address : %016lX\n", pci_ecfg_base()); - EFPRINTF(fp, "[0002]\t\tSegment Group Number : 0000\n"); - EFPRINTF(fp, "[0001]\t\tStart Bus Number : 00\n"); - EFPRINTF(fp, "[0001]\t\tEnd Bus Number : FF\n"); - EFPRINTF(fp, "[0004]\t\tReserved : 0\n"); - EFFLUSH(fp); - return (0); -err_exit: - return (errno); -} - -static int -basl_fwrite_facs(FILE *fp) -{ - EFPRINTF(fp, "/*\n"); - EFPRINTF(fp, " * bhyve FACS template\n"); - EFPRINTF(fp, " */\n"); - EFPRINTF(fp, "[0004]\t\tSignature : \"FACS\"\n"); - EFPRINTF(fp, "[0004]\t\tLength : 00000040\n"); - EFPRINTF(fp, "[0004]\t\tHardware Signature : 00000000\n"); - EFPRINTF(fp, "[0004]\t\t32 Firmware Waking Vector : 00000000\n"); - EFPRINTF(fp, "[0004]\t\tGlobal Lock : 00000000\n"); - EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000000\n"); - EFPRINTF(fp, "\t\t\tS4BIOS Support Present : 0\n"); - EFPRINTF(fp, "\t\t\t64-bit Wake Supported (V2) : 0\n"); - EFPRINTF(fp, - "[0008]\t\t64 Firmware Waking Vector : 0000000000000000\n"); - EFPRINTF(fp, "[0001]\t\tVersion : 02\n"); - EFPRINTF(fp, "[0003]\t\tReserved : 000000\n"); - EFPRINTF(fp, "[0004]\t\tOspmFlags (decoded below) : 00000000\n"); - EFPRINTF(fp, "\t\t\t64-bit Wake Env Required (V2) : 0\n"); - - EFFLUSH(fp); - - return (0); - -err_exit: - return (errno); -} - -/* - * Helper routines for writing to the DSDT from other modules. - */ -void -dsdt_line(const char *fmt, ...) -{ - va_list ap; - - if (dsdt_error != 0) - return; - - if (strcmp(fmt, "") != 0) { - if (dsdt_indent_level != 0) - EFPRINTF(dsdt_fp, "%*c", dsdt_indent_level * 2, ' '); - va_start(ap, fmt); - if (vfprintf(dsdt_fp, fmt, ap) < 0) { - va_end(ap); - goto err_exit; - } - va_end(ap); - } - EFPRINTF(dsdt_fp, "\n"); - return; - -err_exit: - dsdt_error = errno; -} - -void -dsdt_indent(int levels) -{ - - dsdt_indent_level += levels; - assert(dsdt_indent_level >= 0); -} - -void -dsdt_unindent(int levels) -{ - - assert(dsdt_indent_level >= levels); - dsdt_indent_level -= levels; -} - -void -dsdt_fixed_ioport(uint16_t iobase, uint16_t length) -{ - - dsdt_line("IO (Decode16,"); - dsdt_line(" 0x%04X, // Range Minimum", iobase); - dsdt_line(" 0x%04X, // Range Maximum", iobase); - dsdt_line(" 0x01, // Alignment"); - dsdt_line(" 0x%02X, // Length", length); - dsdt_line(" )"); -} - -void -dsdt_fixed_irq(uint8_t irq) -{ - - dsdt_line("IRQNoFlags ()"); - dsdt_line(" {%d}", irq); -} - -void -dsdt_fixed_mem32(uint32_t base, uint32_t length) -{ - - dsdt_line("Memory32Fixed (ReadWrite,"); - dsdt_line(" 0x%08X, // Address Base", base); - dsdt_line(" 0x%08X, // Address Length", length); - dsdt_line(" )"); -} - -static int -basl_fwrite_dsdt(FILE *fp) -{ - dsdt_fp = fp; - dsdt_error = 0; - dsdt_indent_level = 0; - - dsdt_line("/*"); - dsdt_line(" * bhyve DSDT template"); - dsdt_line(" */"); - dsdt_line("DefinitionBlock (\"bhyve_dsdt.aml\", \"DSDT\", 2," - "\"BHYVE \", \"BVDSDT \", 0x00000001)"); - dsdt_line("{"); - dsdt_line(" Name (_S5, Package ()"); - dsdt_line(" {"); - dsdt_line(" 0x05,"); - dsdt_line(" Zero,"); - dsdt_line(" })"); - - pci_write_dsdt(); - - dsdt_line(""); - dsdt_line(" Scope (_SB.PC00)"); - dsdt_line(" {"); - dsdt_line(" Device (HPET)"); - dsdt_line(" {"); - dsdt_line(" Name (_HID, EISAID(\"PNP0103\"))"); - dsdt_line(" Name (_UID, 0)"); - dsdt_line(" Name (_CRS, ResourceTemplate ()"); - dsdt_line(" {"); - dsdt_indent(4); - dsdt_fixed_mem32(0xFED00000, 0x400); - dsdt_unindent(4); - dsdt_line(" })"); - dsdt_line(" }"); - dsdt_line(" }"); - - vmgenc_write_dsdt(); - - dsdt_line("}"); - - if (dsdt_error != 0) - return (dsdt_error); - - EFFLUSH(fp); - - return (0); - -err_exit: - return (errno); -} - -static int -basl_open(struct basl_fio *bf, int suffix) -{ - int err; - - err = 0; - - if (suffix) { - strlcpy(bf->f_name, basl_stemplate, MAXPATHLEN); - bf->fd = mkstemps(bf->f_name, strlen(BHYVE_ASL_SUFFIX)); - } else { - strlcpy(bf->f_name, basl_template, MAXPATHLEN); - bf->fd = mkstemp(bf->f_name); - } - - if (bf->fd > 0) { - bf->fp = fdopen(bf->fd, "w+"); - if (bf->fp == NULL) { - unlink(bf->f_name); - close(bf->fd); - } - } else { - err = 1; - } - - return (err); -} - -static void -basl_close(struct basl_fio *bf) -{ - - if (!basl_keep_temps) - unlink(bf->f_name); - fclose(bf->fp); -} - -static int -basl_start(struct basl_fio *in, struct basl_fio *out) -{ - int err; - - err = basl_open(in, 0); - if (!err) { - err = basl_open(out, 1); - if (err) { - basl_close(in); - } - } - - return (err); -} - -static void -basl_end(struct basl_fio *in, struct basl_fio *out) -{ - - basl_close(in); - basl_close(out); -} - -static int -basl_load(struct vmctx *ctx, int fd, uint64_t off) -{ - struct stat sb; - void *gaddr; - - if (fstat(fd, &sb) < 0) - return (errno); - - gaddr = paddr_guest2host(ctx, basl_acpi_base + off, sb.st_size); - if (gaddr == NULL) - return (EFAULT); - - if (read(fd, gaddr, sb.st_size) < 0) - return (errno); - - return (0); -} - -static int -basl_compile(struct vmctx *ctx, int (*fwrite_section)(FILE *), uint64_t offset) -{ - struct basl_fio io[2]; - static char iaslbuf[3*MAXPATHLEN + 10]; - const char *fmt; - int err; - - err = basl_start(&io[0], &io[1]); - if (!err) { - err = (*fwrite_section)(io[0].fp); - - if (!err) { - /* - * iasl sends the results of the compilation to - * stdout. Shut this down by using the shell to - * redirect stdout to /dev/null, unless the user - * has requested verbose output for debugging - * purposes - */ - fmt = basl_verbose_iasl ? - "%s -p %s %s" : - "/bin/sh -c \"%s -p %s %s\" 1> /dev/null"; - - snprintf(iaslbuf, sizeof(iaslbuf), - fmt, - BHYVE_ASL_COMPILER, - io[1].f_name, io[0].f_name); - err = system(iaslbuf); - - if (!err) { - /* - * Copy the aml output file into guest - * memory at the specified location - */ - err = basl_load(ctx, io[1].fd, offset); - } - } - basl_end(&io[0], &io[1]); - } - - return (err); -} - -static int -basl_make_templates(void) -{ - const char *tmpdir; - int err; - int len; - - err = 0; - - /* - * - */ - if ((tmpdir = getenv("BHYVE_TMPDIR")) == NULL || *tmpdir == '\0' || - (tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0') { - tmpdir = _PATH_TMP; - } - - len = strlen(tmpdir); - - if ((len + sizeof(BHYVE_ASL_TEMPLATE) + 1) < MAXPATHLEN) { - strcpy(basl_template, tmpdir); - while (len > 0 && basl_template[len - 1] == '/') - len--; - basl_template[len] = '/'; - strcpy(&basl_template[len + 1], BHYVE_ASL_TEMPLATE); - } else - err = E2BIG; - - if (!err) { - /* - * len has been intialized (and maybe adjusted) above - */ - if ((len + sizeof(BHYVE_ASL_TEMPLATE) + 1 + - sizeof(BHYVE_ASL_SUFFIX)) < MAXPATHLEN) { - strcpy(basl_stemplate, tmpdir); - basl_stemplate[len] = '/'; - strcpy(&basl_stemplate[len + 1], BHYVE_ASL_TEMPLATE); - len = strlen(basl_stemplate); - strcpy(&basl_stemplate[len], BHYVE_ASL_SUFFIX); - } else - err = E2BIG; - } - - return (err); -} - -int -acpi_build(struct vmctx *ctx, int ncpu) -{ - int err; - - basl_ncpu = ncpu; - - err = vm_get_hpet_capabilities(ctx, &hpet_capabilities); - if (err != 0) - return (err); - - /* - * For debug, allow the user to have iasl compiler output sent - * to stdout rather than /dev/null - */ - if (getenv("BHYVE_ACPI_VERBOSE_IASL")) - basl_verbose_iasl = 1; - - /* - * Allow the user to keep the generated ASL files for debugging - * instead of deleting them following use - */ - if (getenv("BHYVE_ACPI_KEEPTMPS")) - basl_keep_temps = 1; - - err = basl_make_templates(); - - /* - * Run through all the ASL files, compiling them and - * copying them into guest memory - */ - if (err == 0) - err = basl_compile(ctx, basl_fwrite_rsdp, 0); - if (err == 0) - err = basl_compile(ctx, basl_fwrite_rsdt, RSDT_OFFSET); - if (err == 0) - err = basl_compile(ctx, basl_fwrite_xsdt, XSDT_OFFSET); - if (err == 0) - err = basl_compile(ctx, basl_fwrite_madt, MADT_OFFSET); - if (err == 0) - err = basl_compile(ctx, basl_fwrite_fadt, FADT_OFFSET); - if (err == 0) - err = basl_compile(ctx, basl_fwrite_hpet, HPET_OFFSET); - if (err == 0) - err = basl_compile(ctx, basl_fwrite_mcfg, MCFG_OFFSET); - if (err == 0) - err = basl_compile(ctx, basl_fwrite_facs, FACS_OFFSET); - if (err == 0) - err = basl_compile(ctx, basl_fwrite_dsdt, DSDT_OFFSET); - - return (err); -} +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2012 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * bhyve ACPI table generator. + * + * Create the minimal set of ACPI tables required to boot FreeBSD (and + * hopefully other o/s's). + * + * The tables are placed in the guest's ROM area just below 1MB physical, + * above the MPTable. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "bhyverun.h" +#include "acpi.h" +#include "basl.h" +#include "pci_emul.h" +#include "vmgenc.h" + +#define BHYVE_ASL_TEMPLATE "bhyve.XXXXXXX" +#define BHYVE_ASL_SUFFIX ".aml" +#define BHYVE_ASL_COMPILER "/usr/sbin/iasl" + +#define BHYVE_ADDRESS_IOAPIC 0xFEC00000 +#define BHYVE_ADDRESS_HPET 0xFED00000 +#define BHYVE_ADDRESS_LAPIC 0xFEE00000 + +static int basl_keep_temps; +static int basl_verbose_iasl; +static int basl_ncpu; +static uint32_t hpet_capabilities; + +/* + * Contains the full pathname of the template to be passed + * to mkstemp/mktemps(3) + */ +static char basl_template[MAXPATHLEN]; +static char basl_stemplate[MAXPATHLEN]; + +/* + * State for dsdt_line(), dsdt_indent(), and dsdt_unindent(). + */ +static FILE *dsdt_fp; +static int dsdt_indent_level; +static int dsdt_error; + +static struct basl_table *rsdt; +static struct basl_table *xsdt; + +struct basl_fio { + int fd; + FILE *fp; + char f_name[MAXPATHLEN]; +}; + +#define EFPRINTF(...) \ + if (fprintf(__VA_ARGS__) < 0) goto err_exit; + +#define EFFLUSH(x) \ + if (fflush(x) != 0) goto err_exit; + +/* + * Helper routines for writing to the DSDT from other modules. + */ +void +dsdt_line(const char *fmt, ...) +{ + va_list ap; + + if (dsdt_error != 0) + return; + + if (strcmp(fmt, "") != 0) { + if (dsdt_indent_level != 0) + EFPRINTF(dsdt_fp, "%*c", dsdt_indent_level * 2, ' '); + va_start(ap, fmt); + if (vfprintf(dsdt_fp, fmt, ap) < 0) { + va_end(ap); + goto err_exit; + } + va_end(ap); + } + EFPRINTF(dsdt_fp, "\n"); + return; + +err_exit: + dsdt_error = errno; +} + +void +dsdt_indent(int levels) +{ + + dsdt_indent_level += levels; + assert(dsdt_indent_level >= 0); +} + +void +dsdt_unindent(int levels) +{ + + assert(dsdt_indent_level >= levels); + dsdt_indent_level -= levels; +} + +void +dsdt_fixed_ioport(uint16_t iobase, uint16_t length) +{ + + dsdt_line("IO (Decode16,"); + dsdt_line(" 0x%04X, // Range Minimum", iobase); + dsdt_line(" 0x%04X, // Range Maximum", iobase); + dsdt_line(" 0x01, // Alignment"); + dsdt_line(" 0x%02X, // Length", length); + dsdt_line(" )"); +} + +void +dsdt_fixed_irq(uint8_t irq) +{ + + dsdt_line("IRQNoFlags ()"); + dsdt_line(" {%d}", irq); +} + +void +dsdt_fixed_mem32(uint32_t base, uint32_t length) +{ + + dsdt_line("Memory32Fixed (ReadWrite,"); + dsdt_line(" 0x%08X, // Address Base", base); + dsdt_line(" 0x%08X, // Address Length", length); + dsdt_line(" )"); +} + +static int +basl_fwrite_dsdt(FILE *fp) +{ + dsdt_fp = fp; + dsdt_error = 0; + dsdt_indent_level = 0; + + dsdt_line("/*"); + dsdt_line(" * bhyve DSDT template"); + dsdt_line(" */"); + dsdt_line("DefinitionBlock (\"bhyve_dsdt.aml\", \"DSDT\", 2," + "\"BHYVE \", \"BVDSDT \", 0x00000001)"); + dsdt_line("{"); + dsdt_line(" Name (_S5, Package ()"); + dsdt_line(" {"); + dsdt_line(" 0x05,"); + dsdt_line(" Zero,"); + dsdt_line(" })"); + + pci_write_dsdt(); + + dsdt_line(""); + dsdt_line(" Scope (_SB.PC00)"); + dsdt_line(" {"); + dsdt_line(" Device (HPET)"); + dsdt_line(" {"); + dsdt_line(" Name (_HID, EISAID(\"PNP0103\"))"); + dsdt_line(" Name (_UID, 0)"); + dsdt_line(" Name (_CRS, ResourceTemplate ()"); + dsdt_line(" {"); + dsdt_indent(4); + dsdt_fixed_mem32(0xFED00000, 0x400); + dsdt_unindent(4); + dsdt_line(" })"); + dsdt_line(" }"); + dsdt_line(" }"); + + vmgenc_write_dsdt(); + + dsdt_line("}"); + + if (dsdt_error != 0) + return (dsdt_error); + + EFFLUSH(fp); + + return (0); + +err_exit: + return (errno); +} + +static int +basl_open(struct basl_fio *bf, int suffix) +{ + int err; + + err = 0; + + if (suffix) { + strlcpy(bf->f_name, basl_stemplate, MAXPATHLEN); + bf->fd = mkstemps(bf->f_name, strlen(BHYVE_ASL_SUFFIX)); + } else { + strlcpy(bf->f_name, basl_template, MAXPATHLEN); + bf->fd = mkstemp(bf->f_name); + } + + if (bf->fd > 0) { + bf->fp = fdopen(bf->fd, "w+"); + if (bf->fp == NULL) { + unlink(bf->f_name); + close(bf->fd); + } + } else { + err = 1; + } + + return (err); +} + +static void +basl_close(struct basl_fio *bf) +{ + + if (!basl_keep_temps) + unlink(bf->f_name); + fclose(bf->fp); +} + +static int +basl_start(struct basl_fio *in, struct basl_fio *out) +{ + int err; + + err = basl_open(in, 0); + if (!err) { + err = basl_open(out, 1); + if (err) { + basl_close(in); + } + } + + return (err); +} + +static void +basl_end(struct basl_fio *in, struct basl_fio *out) +{ + + basl_close(in); + basl_close(out); +} + +static int +basl_load(struct vmctx *ctx, int fd) +{ + struct stat sb; + void *addr; + + if (fstat(fd, &sb) < 0) + return (errno); + + addr = calloc(1, sb.st_size); + if (addr == NULL) + return (EFAULT); + + if (read(fd, addr, sb.st_size) < 0) + return (errno); + + struct basl_table *table; + + uint8_t name[ACPI_NAMESEG_SIZE + 1] = { 0 }; + memcpy(name, addr, sizeof(name) - 1 /* last char is '\0' */); + BASL_EXEC(basl_table_create(&table, ctx, name, BASL_TABLE_ALIGNMENT)); + BASL_EXEC(basl_table_append_bytes(table, addr, sb.st_size)); + + return (0); +} + +static int +basl_compile(struct vmctx *ctx, int (*fwrite_section)(FILE *)) +{ + struct basl_fio io[2]; + static char iaslbuf[3*MAXPATHLEN + 10]; + const char *fmt; + int err; + + err = basl_start(&io[0], &io[1]); + if (!err) { + err = (*fwrite_section)(io[0].fp); + + if (!err) { + /* + * iasl sends the results of the compilation to + * stdout. Shut this down by using the shell to + * redirect stdout to /dev/null, unless the user + * has requested verbose output for debugging + * purposes + */ + fmt = basl_verbose_iasl ? + "%s -p %s %s" : + "/bin/sh -c \"%s -p %s %s\" 1> /dev/null"; + + snprintf(iaslbuf, sizeof(iaslbuf), + fmt, + BHYVE_ASL_COMPILER, + io[1].f_name, io[0].f_name); + err = system(iaslbuf); + + if (!err) { + /* + * Copy the aml output file into guest + * memory at the specified location + */ + err = basl_load(ctx, io[1].fd); + } + } + basl_end(&io[0], &io[1]); + } + + return (err); +} + +static int +basl_make_templates(void) +{ + const char *tmpdir; + int err; + int len; + + err = 0; + + /* + * + */ + if ((tmpdir = getenv("BHYVE_TMPDIR")) == NULL || *tmpdir == '\0' || + (tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0') { + tmpdir = _PATH_TMP; + } + + len = strlen(tmpdir); + + if ((len + sizeof(BHYVE_ASL_TEMPLATE) + 1) < MAXPATHLEN) { + strcpy(basl_template, tmpdir); + while (len > 0 && basl_template[len - 1] == '/') + len--; + basl_template[len] = '/'; + strcpy(&basl_template[len + 1], BHYVE_ASL_TEMPLATE); + } else + err = E2BIG; + + if (!err) { + /* + * len has been intialized (and maybe adjusted) above + */ + if ((len + sizeof(BHYVE_ASL_TEMPLATE) + 1 + + sizeof(BHYVE_ASL_SUFFIX)) < MAXPATHLEN) { + strcpy(basl_stemplate, tmpdir); + basl_stemplate[len] = '/'; + strcpy(&basl_stemplate[len + 1], BHYVE_ASL_TEMPLATE); + len = strlen(basl_stemplate); + strcpy(&basl_stemplate[len], BHYVE_ASL_SUFFIX); + } else + err = E2BIG; + } + + return (err); +} + +static int +build_dsdt(struct vmctx *const ctx) +{ + BASL_EXEC(basl_compile(ctx, basl_fwrite_dsdt)); + + return (0); +} + +static int +build_facs(struct vmctx *const ctx) +{ + ACPI_TABLE_FACS facs; + struct basl_table *table; + BASL_EXEC(basl_table_create(&table, ctx, ACPI_SIG_FACS, + BASL_TABLE_ALIGNMENT_FACS)); + + memset(&facs, 0, sizeof(facs)); + memcpy(facs.Signature, ACPI_SIG_FACS, ACPI_NAMESEG_SIZE); + facs.Length = sizeof(facs); + facs.Version = htole32(2); + BASL_EXEC(basl_table_append_bytes(table, &facs, sizeof(facs))); + + return (0); +} + +static int +build_fadt(struct vmctx *const ctx) +{ + ACPI_TABLE_FADT fadt; + struct basl_table *table; + + BASL_EXEC(basl_table_create(&table, ctx, ACPI_SIG_FADT, + BASL_TABLE_ALIGNMENT)); + + memset(&fadt, 0, sizeof(fadt)); + BASL_EXEC(basl_table_append_header(table, ACPI_SIG_FADT, 5, 1)); + fadt.Facs = htole32(0); /* patched by basl */ + fadt.Dsdt = htole32(0); /* patched by basl */ + fadt.SciInterrupt = htole16(SCI_INT); + fadt.SmiCommand = htole32(SMI_CMD); + fadt.AcpiEnable = BHYVE_ACPI_ENABLE; + fadt.AcpiDisable = BHYVE_ACPI_DISABLE; + fadt.Pm1aEventBlock = htole32(PM1A_EVT_ADDR); + fadt.Pm1aControlBlock = htole32(PM1A_CNT_ADDR); + fadt.PmTimerBlock = htole32(IO_PMTMR); + fadt.Gpe0Block = htole32(IO_GPE0_BLK); + fadt.Pm1EventLength = 4; + fadt.Pm1ControlLength = 2; + fadt.PmTimerLength = 4; + fadt.Gpe0BlockLength = IO_GPE0_LEN; + fadt.Century = 0x32; + fadt.BootFlags = htole16(ACPI_FADT_NO_VGA | ACPI_FADT_NO_ASPM); + fadt.Flags = htole32(ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED | + ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_32BIT_TIMER | + ACPI_FADT_RESET_REGISTER | ACPI_FADT_HEADLESS | + ACPI_FADT_APIC_PHYSICAL); + basl_fill_gas(&fadt.ResetRegister, ACPI_ADR_SPACE_SYSTEM_IO, 8, 0, + ACPI_GAS_ACCESS_WIDTH_BYTE, 0xCF9); + fadt.ResetValue = 6; + fadt.MinorRevision = 1; + fadt.XFacs = htole64(0); /* patched by basl */ + fadt.XDsdt = htole64(0); /* patched by basl */ + basl_fill_gas(&fadt.XPm1aEventBlock, ACPI_ADR_SPACE_SYSTEM_IO, 0x20, 0, + ACPI_GAS_ACCESS_WIDTH_WORD, PM1A_EVT_ADDR); + basl_fill_gas(&fadt.XPm1bEventBlock, ACPI_ADR_SPACE_SYSTEM_IO, 0, 0, + ACPI_GAS_ACCESS_WIDTH_UNDEFINED, 0); + basl_fill_gas(&fadt.XPm1aControlBlock, ACPI_ADR_SPACE_SYSTEM_IO, 0x10, + 0, ACPI_GAS_ACCESS_WIDTH_WORD, PM1A_CNT_ADDR); + basl_fill_gas(&fadt.XPm1bControlBlock, ACPI_ADR_SPACE_SYSTEM_IO, 0, 0, + ACPI_GAS_ACCESS_WIDTH_UNDEFINED, 0); + basl_fill_gas(&fadt.XPm2ControlBlock, ACPI_ADR_SPACE_SYSTEM_IO, 8, 0, + ACPI_GAS_ACCESS_WIDTH_UNDEFINED, 0); + basl_fill_gas(&fadt.XPmTimerBlock, ACPI_ADR_SPACE_SYSTEM_IO, 0x20, 0, + ACPI_GAS_ACCESS_WIDTH_DWORD, IO_PMTMR); + basl_fill_gas(&fadt.XGpe0Block, ACPI_ADR_SPACE_SYSTEM_IO, + IO_GPE0_LEN * 8, 0, ACPI_GAS_ACCESS_WIDTH_BYTE, IO_GPE0_BLK); + basl_fill_gas(&fadt.XGpe1Block, ACPI_ADR_SPACE_SYSTEM_IO, 0, 0, + ACPI_GAS_ACCESS_WIDTH_UNDEFINED, 0); + basl_fill_gas(&fadt.SleepControl, ACPI_ADR_SPACE_SYSTEM_IO, 8, 0, + ACPI_GAS_ACCESS_WIDTH_BYTE, 0); + basl_fill_gas(&fadt.SleepStatus, ACPI_ADR_SPACE_SYSTEM_IO, 8, 0, + ACPI_GAS_ACCESS_WIDTH_BYTE, 0); + BASL_EXEC(basl_table_append_content(table, &fadt, sizeof(fadt))); + + BASL_EXEC(basl_table_add_pointer(table, ACPI_SIG_FACS, + offsetof(ACPI_TABLE_FADT, Facs), sizeof(fadt.Facs))); + BASL_EXEC(basl_table_add_pointer(table, ACPI_SIG_DSDT, + offsetof(ACPI_TABLE_FADT, Dsdt), sizeof(fadt.Dsdt))); + BASL_EXEC(basl_table_add_pointer(table, ACPI_SIG_FACS, + offsetof(ACPI_TABLE_FADT, XFacs), sizeof(fadt.XFacs))); + BASL_EXEC(basl_table_add_pointer(table, ACPI_SIG_DSDT, + offsetof(ACPI_TABLE_FADT, XDsdt), sizeof(fadt.XDsdt))); + + BASL_EXEC(basl_table_append_pointer(rsdt, ACPI_SIG_FADT, + ACPI_RSDT_ENTRY_SIZE)); + BASL_EXEC(basl_table_append_pointer(xsdt, ACPI_SIG_FADT, + ACPI_XSDT_ENTRY_SIZE)); + + return (0); +} + +static int +build_hpet(struct vmctx *const ctx) +{ + ACPI_TABLE_HPET hpet; + struct basl_table *table; + + BASL_EXEC(basl_table_create(&table, ctx, ACPI_SIG_HPET, + BASL_TABLE_ALIGNMENT)); + + memset(&hpet, 0, sizeof(hpet)); + BASL_EXEC(basl_table_append_header(table, ACPI_SIG_HPET, 1, 1)); + hpet.Id = htole32(hpet_capabilities); + basl_fill_gas(&hpet.Address, ACPI_ADR_SPACE_SYSTEM_MEMORY, 0, 0, + ACPI_GAS_ACCESS_WIDTH_LEGACY, BHYVE_ADDRESS_HPET); + hpet.Flags = ACPI_HPET_PAGE_PROTECT4; + BASL_EXEC(basl_table_append_content(table, &hpet, sizeof(hpet))); + + BASL_EXEC(basl_table_append_pointer(rsdt, ACPI_SIG_HPET, + ACPI_RSDT_ENTRY_SIZE)); + BASL_EXEC(basl_table_append_pointer(xsdt, ACPI_SIG_HPET, + ACPI_XSDT_ENTRY_SIZE)); + + return (0); +} + +static int +build_madt(struct vmctx *const ctx) +{ + ACPI_TABLE_MADT madt; + ACPI_MADT_LOCAL_APIC madt_lapic; + ACPI_MADT_IO_APIC madt_ioapic; + ACPI_MADT_INTERRUPT_OVERRIDE madt_irq_override; + ACPI_MADT_LOCAL_APIC_NMI madt_lapic_nmi; + struct basl_table *table; + + BASL_EXEC(basl_table_create(&table, ctx, ACPI_SIG_MADT, + BASL_TABLE_ALIGNMENT)); + + memset(&madt, 0, sizeof(madt)); + BASL_EXEC(basl_table_append_header(table, ACPI_SIG_MADT, 1, 1)); + madt.Address = htole32(BHYVE_ADDRESS_LAPIC); + madt.Flags = htole32(ACPI_MADT_PCAT_COMPAT); + BASL_EXEC(basl_table_append_content(table, &madt, sizeof(madt))); + + /* Local APIC for each CPU */ + for (int i = 0; i < basl_ncpu; ++i) { + memset(&madt_lapic, 0, sizeof(madt_lapic)); + madt_lapic.Header.Type = ACPI_MADT_TYPE_LOCAL_APIC; + madt_lapic.Header.Length = sizeof(madt_lapic); + madt_lapic.ProcessorId = i; + madt_lapic.Id = i; + madt_lapic.LapicFlags = htole32(ACPI_MADT_ENABLED); + BASL_EXEC(basl_table_append_bytes(table, &madt_lapic, + sizeof(madt_lapic))); + } + + /* I/O APIC */ + memset(&madt_ioapic, 0, sizeof(madt_ioapic)); + madt_ioapic.Header.Type = ACPI_MADT_TYPE_IO_APIC; + madt_ioapic.Header.Length = sizeof(madt_ioapic); + madt_ioapic.Address = htole32(BHYVE_ADDRESS_IOAPIC); + BASL_EXEC( + basl_table_append_bytes(table, &madt_ioapic, sizeof(madt_ioapic))); + + /* Legacy IRQ0 is connected to pin 2 of the I/O APIC */ + memset(&madt_irq_override, 0, sizeof(madt_irq_override)); + madt_irq_override.Header.Type = ACPI_MADT_TYPE_INTERRUPT_OVERRIDE; + madt_irq_override.Header.Length = sizeof(madt_irq_override); + madt_irq_override.GlobalIrq = htole32(2); + madt_irq_override.IntiFlags = htole16( + ACPI_MADT_POLARITY_ACTIVE_HIGH | ACPI_MADT_TRIGGER_EDGE); + BASL_EXEC(basl_table_append_bytes(table, &madt_irq_override, + sizeof(madt_irq_override))); + + memset(&madt_irq_override, 0, sizeof(madt_irq_override)); + madt_irq_override.Header.Type = ACPI_MADT_TYPE_INTERRUPT_OVERRIDE; + madt_irq_override.Header.Length = sizeof(madt_irq_override); + madt_irq_override.SourceIrq = SCI_INT; + madt_irq_override.GlobalIrq = htole32(SCI_INT); + madt_irq_override.IntiFlags = htole16( + ACPI_MADT_POLARITY_ACTIVE_LOW | ACPI_MADT_TRIGGER_LEVEL); + BASL_EXEC(basl_table_append_bytes(table, &madt_irq_override, + sizeof(madt_irq_override))); + + /* Local APIC NMI is conntected to LINT 1 on all CPUs */ + memset(&madt_lapic_nmi, 0, sizeof(madt_lapic_nmi)); + madt_lapic_nmi.Header.Type = ACPI_MADT_TYPE_LOCAL_APIC_NMI; + madt_lapic_nmi.Header.Length = sizeof(madt_lapic_nmi); + madt_lapic_nmi.ProcessorId = 0xFF; + madt_lapic_nmi.IntiFlags = htole16( + ACPI_MADT_POLARITY_ACTIVE_HIGH | ACPI_MADT_TRIGGER_EDGE); + madt_lapic_nmi.Lint = 1; + BASL_EXEC(basl_table_append_bytes(table, &madt_lapic_nmi, + sizeof(madt_lapic_nmi))); + + BASL_EXEC(basl_table_append_pointer(rsdt, ACPI_SIG_MADT, + ACPI_RSDT_ENTRY_SIZE)); + BASL_EXEC(basl_table_append_pointer(xsdt, ACPI_SIG_MADT, + ACPI_XSDT_ENTRY_SIZE)); + + return (0); +} + +static int +build_mcfg(struct vmctx *const ctx) +{ + ACPI_TABLE_MCFG mcfg; + ACPI_MCFG_ALLOCATION mcfg_allocation; + struct basl_table *table; + + BASL_EXEC(basl_table_create(&table, ctx, ACPI_SIG_MCFG, + BASL_TABLE_ALIGNMENT)); + + memset(&mcfg, 0, sizeof(mcfg)); + BASL_EXEC(basl_table_append_header(table, ACPI_SIG_MCFG, 1, 1)); + BASL_EXEC(basl_table_append_content(table, &mcfg, sizeof(mcfg))); + + memset(&mcfg_allocation, 0, sizeof(mcfg_allocation)); + mcfg_allocation.Address = htole64(pci_ecfg_base()); + mcfg_allocation.EndBusNumber = 0xFF; + BASL_EXEC(basl_table_append_bytes(table, &mcfg_allocation, + sizeof(mcfg_allocation))); + + BASL_EXEC(basl_table_append_pointer(rsdt, ACPI_SIG_MCFG, + ACPI_RSDT_ENTRY_SIZE)); + BASL_EXEC(basl_table_append_pointer(xsdt, ACPI_SIG_MCFG, + ACPI_XSDT_ENTRY_SIZE)); + + return (0); +} + +static int +build_rsdp(struct vmctx *const ctx) +{ + ACPI_TABLE_RSDP rsdp; + struct basl_table *table; + + BASL_EXEC(basl_table_create(&table, ctx, ACPI_RSDP_NAME, + BASL_TABLE_ALIGNMENT)); + + memset(&rsdp, 0, sizeof(rsdp)); + memcpy(rsdp.Signature, ACPI_SIG_RSDP, 8); + rsdp.Checksum = 0; /* patched by basl */ + memcpy(rsdp.OemId, "BHYVE ", ACPI_OEM_ID_SIZE); + rsdp.Revision = 2; + rsdp.RsdtPhysicalAddress = htole32(0); /* patched by basl */ + rsdp.Length = htole32(0); /* patched by basl */ + rsdp.XsdtPhysicalAddress = htole64(0); /* patched by basl */ + rsdp.ExtendedChecksum = 0; /* patched by basl */ + BASL_EXEC(basl_table_append_bytes(table, &rsdp, sizeof(rsdp))); + + BASL_EXEC(basl_table_add_checksum(table, + offsetof(ACPI_TABLE_RSDP, Checksum), 0, 20)); + BASL_EXEC(basl_table_add_pointer(table, ACPI_SIG_RSDT, + offsetof(ACPI_TABLE_RSDP, RsdtPhysicalAddress), + sizeof(rsdp.RsdtPhysicalAddress))); + BASL_EXEC(basl_table_add_length(table, + offsetof(ACPI_TABLE_RSDP, Length), sizeof(rsdp.Length))); + BASL_EXEC(basl_table_add_pointer(table, ACPI_SIG_XSDT, + offsetof(ACPI_TABLE_RSDP, XsdtPhysicalAddress), + sizeof(rsdp.XsdtPhysicalAddress))); + BASL_EXEC(basl_table_add_checksum(table, + offsetof(ACPI_TABLE_RSDP, ExtendedChecksum), 0, + BASL_TABLE_CHECKSUM_LEN_FULL_TABLE)); + + return (0); +} + +static int +build_rsdt(struct vmctx *const ctx) +{ + BASL_EXEC( + basl_table_create(&rsdt, ctx, ACPI_SIG_RSDT, BASL_TABLE_ALIGNMENT)); + + /* Header */ + BASL_EXEC(basl_table_append_header(rsdt, ACPI_SIG_RSDT, 1, 1)); + /* Pointers (added by other build_XXX funcs) */ + + return (0); +} + +static int +build_spcr(struct vmctx *const ctx) +{ + ACPI_TABLE_SPCR spcr; + struct basl_table *table; + + BASL_EXEC(basl_table_create(&table, ctx, ACPI_SIG_SPCR, + BASL_TABLE_ALIGNMENT)); + + memset(&spcr, 0, sizeof(spcr)); + BASL_EXEC(basl_table_append_header(table, ACPI_SIG_SPCR, 1, 1)); + spcr.InterfaceType = ACPI_DBG2_16550_COMPATIBLE; + basl_fill_gas(&spcr.SerialPort, ACPI_ADR_SPACE_SYSTEM_IO, 8, 0, + ACPI_GAS_ACCESS_WIDTH_LEGACY, 0x3F8); + spcr.InterruptType = ACPI_SPCR_INTERRUPT_TYPE_8259; + spcr.PcInterrupt = 4; + spcr.BaudRate = ACPI_SPCR_BAUD_RATE_115200; + spcr.Parity = ACPI_SPCR_PARITY_NO_PARITY; + spcr.StopBits = ACPI_SPCR_STOP_BITS_1; + spcr.FlowControl = 3; /* RTS/CTS | DCD */ + spcr.TerminalType = ACPI_SPCR_TERMINAL_TYPE_VT_UTF8; + BASL_EXEC(basl_table_append_content(table, &spcr, sizeof(spcr))); + + BASL_EXEC(basl_table_append_pointer(rsdt, ACPI_SIG_SPCR, + ACPI_RSDT_ENTRY_SIZE)); + BASL_EXEC(basl_table_append_pointer(xsdt, ACPI_SIG_SPCR, + ACPI_XSDT_ENTRY_SIZE)); + + return (0); +} + +static int +build_xsdt(struct vmctx *const ctx) +{ + BASL_EXEC( + basl_table_create(&xsdt, ctx, ACPI_SIG_XSDT, BASL_TABLE_ALIGNMENT)); + + /* Header */ + BASL_EXEC(basl_table_append_header(xsdt, ACPI_SIG_XSDT, 1, 1)); + /* Pointers (added by other build_XXX funcs) */ + + return (0); +} + +int +acpi_build(struct vmctx *ctx, int ncpu) +{ + int err; + + basl_ncpu = ncpu; + + err = vm_get_hpet_capabilities(ctx, &hpet_capabilities); + if (err != 0) + return (err); + + /* + * For debug, allow the user to have iasl compiler output sent + * to stdout rather than /dev/null + */ + if (getenv("BHYVE_ACPI_VERBOSE_IASL")) + basl_verbose_iasl = 1; + + /* + * Allow the user to keep the generated ASL files for debugging + * instead of deleting them following use + */ + if (getenv("BHYVE_ACPI_KEEPTMPS")) + basl_keep_temps = 1; + + BASL_EXEC(basl_init()); + + BASL_EXEC(basl_make_templates()); + + /* + * Generate ACPI tables and copy them into guest memory. + * + * According to UEFI Specification v6.3 chapter 5.1 the FADT should be + * the first table pointed to by XSDT. For that reason, build it as the + * first table after XSDT. + */ + BASL_EXEC(build_rsdp(ctx)); + BASL_EXEC(build_rsdt(ctx)); + BASL_EXEC(build_xsdt(ctx)); + BASL_EXEC(build_fadt(ctx)); + BASL_EXEC(build_madt(ctx)); + BASL_EXEC(build_hpet(ctx)); + BASL_EXEC(build_mcfg(ctx)); + BASL_EXEC(build_facs(ctx)); + BASL_EXEC(build_spcr(ctx)); + BASL_EXEC(build_dsdt(ctx)); + + BASL_EXEC(basl_finish()); + + return (0); +} diff --git a/usr/src/cmd/bhyve/atkbdc.c b/usr/src/cmd/bhyve/atkbdc.c index 1c1838c2e8..d7e2ad0714 100644 --- a/usr/src/cmd/bhyve/atkbdc.c +++ b/usr/src/cmd/bhyve/atkbdc.c @@ -302,8 +302,8 @@ atkbdc_dequeue_data(struct atkbdc_softc *sc, uint8_t *buf) } static int -atkbdc_data_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +atkbdc_data_handler(struct vmctx *ctx __unused, int in, + int port __unused, int bytes, uint32_t *eax, void *arg) { struct atkbdc_softc *sc; uint8_t buf; @@ -388,8 +388,8 @@ atkbdc_data_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, } static int -atkbdc_sts_ctl_handler(struct vmctx *ctx, int vcpu, int in, int port, - int bytes, uint32_t *eax, void *arg) +atkbdc_sts_ctl_handler(struct vmctx *ctx, int in, + int port __unused, int bytes, uint32_t *eax, void *arg) { struct atkbdc_softc *sc; int error, retval; diff --git a/usr/src/cmd/bhyve/audio.c b/usr/src/cmd/bhyve/audio.c index ee6bdabc54..165face586 100644 --- a/usr/src/cmd/bhyve/audio.c +++ b/usr/src/cmd/bhyve/audio.c @@ -221,10 +221,11 @@ audio_set_params(struct audio *aud, struct audio_params *params) * @count - the number of bytes in buffer */ int -audio_playback(struct audio *aud, const void *buf, size_t count) +audio_playback(struct audio *aud, const uint8_t *buf, size_t count) { - int audio_fd = -1; - ssize_t len = 0, total = 0; + ssize_t len; + size_t total; + int audio_fd; assert(aud); assert(aud->dir); @@ -233,16 +234,13 @@ audio_playback(struct audio *aud, const void *buf, size_t count) audio_fd = aud->fd; assert(audio_fd != -1); - total = 0; - while (total < count) { + for (total = 0; total < count; total += len) { len = write(audio_fd, buf + total, count - total); - if (len == -1) { + if (len < 0) { DPRINTF("Fail to write to fd: %d, errno: %d", audio_fd, errno); return -1; } - - total += len; } return 0; @@ -257,10 +255,11 @@ audio_playback(struct audio *aud, const void *buf, size_t count) * Returns -1 on error and 0 on success */ int -audio_record(struct audio *aud, void *buf, size_t count) +audio_record(struct audio *aud, uint8_t *buf, size_t count) { - int audio_fd = -1; - ssize_t len = 0, total = 0; + ssize_t len; + size_t total; + int audio_fd; assert(aud); assert(!aud->dir); @@ -269,16 +268,13 @@ audio_record(struct audio *aud, void *buf, size_t count) audio_fd = aud->fd; assert(audio_fd != -1); - total = 0; - while (total < count) { + for (total = 0; total < count; total += len) { len = read(audio_fd, buf + total, count - total); - if (len == -1) { + if (len < 0) { DPRINTF("Fail to write to fd: %d, errno: %d", audio_fd, errno); return -1; } - - total += len; } return 0; diff --git a/usr/src/cmd/bhyve/audio.h b/usr/src/cmd/bhyve/audio.h index 88f4dc8709..143030b29a 100644 --- a/usr/src/cmd/bhyve/audio.h +++ b/usr/src/cmd/bhyve/audio.h @@ -73,7 +73,7 @@ int audio_set_params(struct audio *aud, struct audio_params *params); * @count - the number of bytes in buffer * Returns -1 on error and 0 on success */ -int audio_playback(struct audio *aud, const void *buf, size_t count); +int audio_playback(struct audio *aud, const uint8_t *buf, size_t count); /* * audio_record - records samples from the sound device using blocking @@ -83,6 +83,6 @@ int audio_playback(struct audio *aud, const void *buf, size_t count); * @count - the number of bytes to capture in buffer * Returns -1 on error and 0 on success */ -int audio_record(struct audio *aud, void *buf, size_t count); +int audio_record(struct audio *aud, uint8_t *buf, size_t count); #endif /* _AUDIO_EMUL_H_ */ diff --git a/usr/src/cmd/bhyve/basl.c b/usr/src/cmd/bhyve/basl.c new file mode 100644 index 0000000000..e0c05d69ea --- /dev/null +++ b/usr/src/cmd/bhyve/basl.c @@ -0,0 +1,608 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2022 Beckhoff Automation GmbH & Co. KG + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#ifndef __FreeBSD__ +#include "hexdump.h" +#endif + +#include "basl.h" + +struct basl_table_checksum { + STAILQ_ENTRY(basl_table_checksum) chain; + uint32_t off; + uint32_t start; + uint32_t len; +}; + +struct basl_table_length { + STAILQ_ENTRY(basl_table_length) chain; + uint32_t off; + uint8_t size; +}; + +struct basl_table_pointer { + STAILQ_ENTRY(basl_table_pointer) chain; + uint8_t src_signature[ACPI_NAMESEG_SIZE]; + uint32_t off; + uint8_t size; +}; + +struct basl_table { + STAILQ_ENTRY(basl_table) chain; + struct vmctx *ctx; + uint8_t fwcfg_name[QEMU_FWCFG_MAX_NAME]; + void *data; + uint32_t len; + uint32_t off; + uint32_t alignment; + STAILQ_HEAD(basl_table_checksum_list, basl_table_checksum) checksums; + STAILQ_HEAD(basl_table_length_list, basl_table_length) lengths; + STAILQ_HEAD(basl_table_pointer_list, basl_table_pointer) pointers; +}; +static STAILQ_HEAD(basl_table_list, basl_table) basl_tables = STAILQ_HEAD_INITIALIZER( + basl_tables); + +static __inline uint64_t +basl_le_dec(void *pp, size_t len) +{ + assert(len <= 8); + + switch (len) { + case 1: + return ((uint8_t *)pp)[0]; + case 2: + return le16dec(pp); + case 4: + return le32dec(pp); + case 8: + return le64dec(pp); + } + + return 0; +} + +static __inline void +basl_le_enc(void *pp, uint64_t val, size_t len) +{ + char buf[8]; + + assert(len <= 8); + + le64enc(buf, val); + memcpy(pp, buf, len); +} + +static int +basl_dump_table(const struct basl_table *const table, const bool mem) +{ + const ACPI_TABLE_HEADER *const header = table->data; + const uint8_t *data; + + if (!mem) { + data = table->data; + } else { + data = vm_map_gpa(table->ctx, BHYVE_ACPI_BASE + table->off, + table->len); + if (data == NULL) { + return (ENOMEM); + } + } + + printf("%.4s @ %8x (%s)\n", header->Signature, + BHYVE_ACPI_BASE + table->off, mem ? "Memory" : "FwCfg"); + hexdump(data, table->len, NULL, 0); + + return (0); +} + +static int __unused +basl_dump(const bool mem) +{ + struct basl_table *table; + + STAILQ_FOREACH(table, &basl_tables, chain) { + BASL_EXEC(basl_dump_table(table, mem)); + } + + return (0); +} + +void +basl_fill_gas(ACPI_GENERIC_ADDRESS *const gas, const uint8_t space_id, + const uint8_t bit_width, const uint8_t bit_offset, + const uint8_t access_width, const uint64_t address) +{ + assert(gas != NULL); + + gas->SpaceId = space_id; + gas->BitWidth = bit_width; + gas->BitOffset = bit_offset; + gas->AccessWidth = access_width; + gas->Address = htole64(address); +} + +static int +basl_finish_install_guest_tables(struct basl_table *const table, uint32_t *const off) +{ + void *gva; + + table->off = roundup2(*off, table->alignment); + *off = table->off + table->len; + if (*off <= table->off) { + warnx("%s: invalid table length 0x%8x @ offset 0x%8x", __func__, + table->len, table->off); + return (EFAULT); + } + + /* + * Install ACPI tables directly in guest memory for use by guests which + * do not boot via EFI. EFI ROMs provide a pointer to the firmware + * generated ACPI tables instead, but it doesn't hurt to install the + * tables always. + */ + gva = vm_map_gpa(table->ctx, BHYVE_ACPI_BASE + table->off, table->len); + if (gva == NULL) { + warnx("%s: could not map gpa [ 0x%16lx, 0x%16lx ]", __func__, + (uint64_t)BHYVE_ACPI_BASE + table->off, + (uint64_t)BHYVE_ACPI_BASE + table->off + table->len); + return (ENOMEM); + } + memcpy(gva, table->data, table->len); + + return (0); +} + +static int +basl_finish_patch_checksums(struct basl_table *const table) +{ + struct basl_table_checksum *checksum; + + STAILQ_FOREACH(checksum, &table->checksums, chain) { + uint8_t *gva, *checksum_gva; + uint64_t gpa; + uint32_t len; + uint8_t sum; + + len = checksum->len; + if (len == BASL_TABLE_CHECKSUM_LEN_FULL_TABLE) { + len = table->len; + } + + assert(checksum->off < table->len); + assert(checksum->start < table->len); + assert(checksum->start + len <= table->len); + + /* + * Install ACPI tables directly in guest memory for use by + * guests which do not boot via EFI. EFI ROMs provide a pointer + * to the firmware generated ACPI tables instead, but it doesn't + * hurt to install the tables always. + */ + gpa = BHYVE_ACPI_BASE + table->off + checksum->start; + if ((gpa < BHYVE_ACPI_BASE) || + (gpa < BHYVE_ACPI_BASE + table->off)) { + warnx("%s: invalid gpa (off 0x%8x start 0x%8x)", + __func__, table->off, checksum->start); + return (EFAULT); + } + + gva = vm_map_gpa(table->ctx, gpa, len); + if (gva == NULL) { + warnx("%s: could not map gpa [ 0x%16lx, 0x%16lx ]", + __func__, gpa, gpa + len); + return (ENOMEM); + } + + checksum_gva = gva + checksum->off; + if (checksum_gva < gva) { + warnx("%s: invalid checksum offset 0x%8x", __func__, + checksum->off); + return (EFAULT); + } + + sum = 0; + for (uint32_t i = 0; i < len; ++i) { + sum += *(gva + i); + } + *checksum_gva = -sum; + } + + return (0); +} + +static struct basl_table * +basl_get_table_by_signature(const uint8_t signature[ACPI_NAMESEG_SIZE]) +{ + struct basl_table *table; + + STAILQ_FOREACH(table, &basl_tables, chain) { + const ACPI_TABLE_HEADER *const header = + (const ACPI_TABLE_HEADER *)table->data; + +#ifdef __FreeBSD__ + if (strncmp(header->Signature, signature, + sizeof(header->Signature)) == 0) { + return (table); +#else + if (strncmp(header->Signature, (char *)signature, + sizeof(header->Signature)) == 0) { + return (table); +#endif + } + } + + warnx("%s: %.4s not found", __func__, signature); + return (NULL); +} + +static int +basl_finish_patch_pointers(struct basl_table *const table) +{ + struct basl_table_pointer *pointer; + + STAILQ_FOREACH(pointer, &table->pointers, chain) { + const struct basl_table *src_table; + uint8_t *gva; + uint64_t gpa, val; + + assert(pointer->off < table->len); + assert(pointer->off + pointer->size <= table->len); + + src_table = basl_get_table_by_signature(pointer->src_signature); + if (src_table == NULL) { + warnx("%s: could not find ACPI table %.4s", __func__, + pointer->src_signature); + return (EFAULT); + } + + /* + * Install ACPI tables directly in guest memory for use by + * guests which do not boot via EFI. EFI ROMs provide a pointer + * to the firmware generated ACPI tables instead, but it doesn't + * hurt to install the tables always. + */ + gpa = BHYVE_ACPI_BASE + table->off; + if (gpa < BHYVE_ACPI_BASE) { + warnx("%s: table offset of 0x%8x is too large", + __func__, table->off); + return (EFAULT); + } + + gva = vm_map_gpa(table->ctx, gpa, table->len); + if (gva == NULL) { + warnx("%s: could not map gpa [ 0x%16lx, 0x%16lx ]", + __func__, gpa, gpa + table->len); + return (ENOMEM); + } + + val = basl_le_dec(gva + pointer->off, pointer->size); + val += BHYVE_ACPI_BASE + src_table->off; + basl_le_enc(gva + pointer->off, val, pointer->size); + } + + return (0); +} + +static int +basl_finish_set_length(struct basl_table *const table) +{ + struct basl_table_length *length; + + STAILQ_FOREACH(length, &table->lengths, chain) { + assert(length->off < table->len); + assert(length->off + length->size <= table->len); + + basl_le_enc((uint8_t *)table->data + length->off, table->len, + length->size); + } + + return (0); +} + +int +basl_finish(void) +{ + struct basl_table *table; + uint32_t off = 0; + + if (STAILQ_EMPTY(&basl_tables)) { + warnx("%s: no ACPI tables found", __func__); + return (EINVAL); + } + + /* + * We have to install all tables before we can patch them. Therefore, + * use two loops. The first one installs all tables and the second one + * patches them. + */ + STAILQ_FOREACH(table, &basl_tables, chain) { + BASL_EXEC(basl_finish_set_length(table)); + BASL_EXEC(basl_finish_install_guest_tables(table, &off)); + } + STAILQ_FOREACH(table, &basl_tables, chain) { + BASL_EXEC(basl_finish_patch_pointers(table)); + + /* + * Calculate the checksum as last step! + */ + BASL_EXEC(basl_finish_patch_checksums(table)); + } + + return (0); +} + +int +basl_init(void) +{ + return (0); +} + +int +basl_table_add_checksum(struct basl_table *const table, const uint32_t off, + const uint32_t start, const uint32_t len) +{ + struct basl_table_checksum *checksum; + + assert(table != NULL); + + checksum = calloc(1, sizeof(struct basl_table_checksum)); + if (checksum == NULL) { + warnx("%s: failed to allocate checksum", __func__); + return (ENOMEM); + } + + checksum->off = off; + checksum->start = start; + checksum->len = len; + + STAILQ_INSERT_TAIL(&table->checksums, checksum, chain); + + return (0); +} + +int +basl_table_add_length(struct basl_table *const table, const uint32_t off, + const uint8_t size) +{ + struct basl_table_length *length; + + assert(table != NULL); + assert(size == 4 || size == 8); + + length = calloc(1, sizeof(struct basl_table_length)); + if (length == NULL) { + warnx("%s: failed to allocate length", __func__); + return (ENOMEM); + } + + length->off = off; + length->size = size; + + STAILQ_INSERT_TAIL(&table->lengths, length, chain); + + return (0); +} + +int +basl_table_add_pointer(struct basl_table *const table, + const uint8_t src_signature[ACPI_NAMESEG_SIZE], const uint32_t off, + const uint8_t size) +{ + struct basl_table_pointer *pointer; + + assert(table != NULL); + assert(size == 4 || size == 8); + + pointer = calloc(1, sizeof(struct basl_table_pointer)); + if (pointer == NULL) { + warnx("%s: failed to allocate pointer", __func__); + return (ENOMEM); + } + + memcpy(pointer->src_signature, src_signature, + sizeof(pointer->src_signature)); + pointer->off = off; + pointer->size = size; + + STAILQ_INSERT_TAIL(&table->pointers, pointer, chain); + + return (0); +} + +int +basl_table_append_bytes(struct basl_table *const table, const void *const bytes, + const uint32_t len) +{ + void *end; + + assert(table != NULL); + assert(bytes != NULL); + + if (table->len + len <= table->len) { + warnx("%s: table too large (table->len 0x%8x len 0x%8x)", + __func__, table->len, len); + return (EFAULT); + } + + table->data = reallocf(table->data, table->len + len); + if (table->data == NULL) { + warnx("%s: failed to realloc table to length 0x%8x", __func__, + table->len + len); + table->len = 0; + return (ENOMEM); + } + + end = (uint8_t *)table->data + table->len; + table->len += len; + + memcpy(end, bytes, len); + + return (0); +} + +int +basl_table_append_checksum(struct basl_table *const table, const uint32_t start, + const uint32_t len) +{ + assert(table != NULL); + + BASL_EXEC(basl_table_add_checksum(table, table->len, start, len)); + BASL_EXEC(basl_table_append_int(table, 0, 1)); + + return (0); +} + +int +basl_table_append_content(struct basl_table *table, void *data, uint32_t len) +{ + assert(data != NULL); + assert(len >= sizeof(ACPI_TABLE_HEADER)); + + return (basl_table_append_bytes(table, + (void *)((uintptr_t)(data) + sizeof(ACPI_TABLE_HEADER)), + len - sizeof(ACPI_TABLE_HEADER))); +} + +int +basl_table_append_gas(struct basl_table *const table, const uint8_t space_id, + const uint8_t bit_width, const uint8_t bit_offset, + const uint8_t access_width, const uint64_t address) +{ + ACPI_GENERIC_ADDRESS gas_le = { + .SpaceId = space_id, + .BitWidth = bit_width, + .BitOffset = bit_offset, + .AccessWidth = access_width, + .Address = htole64(address), + }; + + return (basl_table_append_bytes(table, &gas_le, sizeof(gas_le))); +} + +int +basl_table_append_header(struct basl_table *const table, + const uint8_t signature[ACPI_NAMESEG_SIZE], const uint8_t revision, + const uint32_t oem_revision) +{ + ACPI_TABLE_HEADER header_le; + /* + 1 is required for the null terminator */ + char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1]; + + assert(table != NULL); + assert(table->len == 0); + + memcpy(header_le.Signature, signature, ACPI_NAMESEG_SIZE); + header_le.Length = 0; /* patched by basl_finish */ + header_le.Revision = revision; + header_le.Checksum = 0; /* patched by basl_finish */ + memcpy(header_le.OemId, "BHYVE ", ACPI_OEM_ID_SIZE); + snprintf(oem_table_id, ACPI_OEM_TABLE_ID_SIZE, "BV%.4s ", signature); + memcpy(header_le.OemTableId, oem_table_id, + sizeof(header_le.OemTableId)); + header_le.OemRevision = htole32(oem_revision); + memcpy(header_le.AslCompilerId, "BASL", ACPI_NAMESEG_SIZE); + header_le.AslCompilerRevision = htole32(0x20220504); + + BASL_EXEC( + basl_table_append_bytes(table, &header_le, sizeof(header_le))); + + BASL_EXEC(basl_table_add_length(table, + offsetof(ACPI_TABLE_HEADER, Length), sizeof(header_le.Length))); + BASL_EXEC(basl_table_add_checksum(table, + offsetof(ACPI_TABLE_HEADER, Checksum), 0, + BASL_TABLE_CHECKSUM_LEN_FULL_TABLE)); + + return (0); +} + +int +basl_table_append_int(struct basl_table *const table, const uint64_t val, + const uint8_t size) +{ + char buf[8]; + + assert(size <= sizeof(val)); + + basl_le_enc(buf, val, size); + return (basl_table_append_bytes(table, buf, size)); +} + +int +basl_table_append_length(struct basl_table *const table, const uint8_t size) +{ + assert(table != NULL); + assert(size <= sizeof(table->len)); + + BASL_EXEC(basl_table_add_length(table, table->len, size)); + BASL_EXEC(basl_table_append_int(table, 0, size)); + + return (0); +} + +int +basl_table_append_pointer(struct basl_table *const table, + const uint8_t src_signature[ACPI_NAMESEG_SIZE], const uint8_t size) +{ + assert(table != NULL); + assert(size == 4 || size == 8); + + BASL_EXEC(basl_table_add_pointer(table, src_signature, table->len, size)); + BASL_EXEC(basl_table_append_int(table, 0, size)); + + return (0); +} + +int +basl_table_create(struct basl_table **const table, struct vmctx *ctx, + const uint8_t *const name, const uint32_t alignment) +{ + struct basl_table *new_table; + + assert(table != NULL); + + new_table = calloc(1, sizeof(struct basl_table)); + if (new_table == NULL) { + warnx("%s: failed to allocate table", __func__); + return (ENOMEM); + } + + new_table->ctx = ctx; + +#ifdef __FreeBSD__ + snprintf(new_table->fwcfg_name, sizeof(new_table->fwcfg_name), + "etc/acpi/%s", name); +#else + snprintf((char *)new_table->fwcfg_name, sizeof (new_table->fwcfg_name), + "etc/acpi/%s", name); +#endif + + new_table->alignment = alignment; + + STAILQ_INIT(&new_table->checksums); + STAILQ_INIT(&new_table->lengths); + STAILQ_INIT(&new_table->pointers); + + STAILQ_INSERT_TAIL(&basl_tables, new_table, chain); + + *table = new_table; + + return (0); +} diff --git a/usr/src/cmd/bhyve/basl.h b/usr/src/cmd/bhyve/basl.h new file mode 100644 index 0000000000..869199157f --- /dev/null +++ b/usr/src/cmd/bhyve/basl.h @@ -0,0 +1,125 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2022 Beckhoff Automation GmbH & Co. KG + */ + +#pragma once + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#include +#pragma GCC diagnostic pop + +#ifndef __FreeBSD__ +/* Until the in-gate ACPI is updated, map the new name to the old. */ +#define ACPI_NAMESEG_SIZE ACPI_NAME_SIZE +/* + * Also to avoid type conflicts without having to pepper the code with ifdefs, + * redefine these constants to be uint8_t * + */ +#undef ACPI_SIG_FACS +#undef ACPI_SIG_MCFG +#undef ACPI_SIG_HPET +#undef ACPI_SIG_MADT +#undef ACPI_SIG_DSDT +#undef ACPI_SIG_FADT +#undef ACPI_SIG_XSDT +#undef ACPI_SIG_RSDT +#undef ACPI_RSDP_NAME +#undef ACPI_SIG_SPCR +#define ACPI_SIG_FACS (const uint8_t *)"FACS" +#define ACPI_SIG_MCFG (const uint8_t *)"MCFG" +#define ACPI_SIG_HPET (const uint8_t *)"HPET" +#define ACPI_SIG_MADT (const uint8_t *)"APIC" +#define ACPI_SIG_DSDT (const uint8_t *)"DSDT" +#define ACPI_SIG_FADT (const uint8_t *)"FACP" +#define ACPI_SIG_XSDT (const uint8_t *)"XSDT" +#define ACPI_SIG_RSDT (const uint8_t *)"RSDT" +#define ACPI_RSDP_NAME (const uint8_t *)"RSDP" +#define ACPI_SIG_SPCR (const uint8_t *)"SPCR" +#endif /* !__FreeBSD__ */ + +#define ACPI_GAS_ACCESS_WIDTH_LEGACY 0 +#define ACPI_GAS_ACCESS_WIDTH_UNDEFINED 0 +#define ACPI_GAS_ACCESS_WIDTH_BYTE 1 +#define ACPI_GAS_ACCESS_WIDTH_WORD 2 +#define ACPI_GAS_ACCESS_WIDTH_DWORD 3 +#define ACPI_GAS_ACCESS_WIDTH_QWORD 4 + +#define ACPI_SPCR_INTERRUPT_TYPE_8259 0x1 +#define ACPI_SPCR_INTERRUPT_TYPE_APIC 0x2 +#define ACPI_SPCR_INTERRUPT_TYPE_SAPIC 0x4 +#define ACPI_SPCR_INTERRUPT_TYPE_GIC 0x8 + +#define ACPI_SPCR_BAUD_RATE_9600 3 +#define ACPI_SPCR_BAUD_RATE_19200 4 +#define ACPI_SPCR_BAUD_RATE_57600 6 +#define ACPI_SPCR_BAUD_RATE_115200 7 + +#define ACPI_SPCR_PARITY_NO_PARITY 0 + +#define ACPI_SPCR_STOP_BITS_1 1 + +#define ACPI_SPCR_FLOW_CONTROL_DCD 0x1 +#define ACPI_SPCR_FLOW_CONTROL_RTS_CTS 0x2 +#define ACPI_SPCR_FLOW_CONTROL_XON_XOFF 0x4 + +#define ACPI_SPCR_TERMINAL_TYPE_VT100 0 +#define ACPI_SPCR_TERMINAL_TYPE_VT100_PLUS 1 +#define ACPI_SPCR_TERMINAL_TYPE_VT_UTF8 2 +#define ACPI_SPCR_TERMINAL_TYPE_ANSI 3 + +#define BHYVE_ACPI_BASE 0xf2400 + +#define BASL_TABLE_ALIGNMENT 0x10 +#define BASL_TABLE_ALIGNMENT_FACS 0x40 + +#define BASL_TABLE_CHECKSUM_LEN_FULL_TABLE (-1U) + +#define BASL_EXEC(x) \ + do { \ + const int error = (x); \ + if (error) { \ + warnc(error, \ + "BASL failed @ %s:%d\n Failed to execute %s", \ + __func__, __LINE__, #x); \ + return (error); \ + } \ + } while (0) + +#define QEMU_FWCFG_MAX_NAME 56 + +struct basl_table; + +void basl_fill_gas(ACPI_GENERIC_ADDRESS *gas, uint8_t space_id, + uint8_t bit_width, uint8_t bit_offset, uint8_t access_width, + uint64_t address); +int basl_finish(void); +int basl_init(void); +int basl_table_add_checksum(struct basl_table *const table, const uint32_t off, + const uint32_t start, const uint32_t len); +int basl_table_add_length(struct basl_table *const table, const uint32_t off, + const uint8_t size); +int basl_table_add_pointer(struct basl_table *const table, + const uint8_t src_signature[ACPI_NAMESEG_SIZE], const uint32_t off, + const uint8_t size); +int basl_table_append_bytes(struct basl_table *table, const void *bytes, + uint32_t len); +int basl_table_append_checksum(struct basl_table *table, uint32_t start, + uint32_t len); +/* Add an ACPI_TABLE_* to basl without its header. */ +int basl_table_append_content(struct basl_table *table, void *data, + uint32_t len); +int basl_table_append_gas(struct basl_table *table, uint8_t space_id, + uint8_t bit_width, uint8_t bit_offset, uint8_t access_width, + uint64_t address); +int basl_table_append_header(struct basl_table *table, + const uint8_t signature[ACPI_NAMESEG_SIZE], uint8_t revision, + uint32_t oem_revision); +int basl_table_append_int(struct basl_table *table, uint64_t val, uint8_t size); +int basl_table_append_length(struct basl_table *table, uint8_t size); +int basl_table_append_pointer(struct basl_table *table, + const uint8_t src_signature[ACPI_NAMESEG_SIZE], uint8_t size); +int basl_table_create(struct basl_table **table, struct vmctx *ctx, + const uint8_t *name, uint32_t alignment); diff --git a/usr/src/cmd/bhyve/bhyverun.c b/usr/src/cmd/bhyve/bhyverun.c index 90260a4ac9..7b4a5e7330 100644 --- a/usr/src/cmd/bhyve/bhyverun.c +++ b/usr/src/cmd/bhyve/bhyverun.c @@ -52,11 +52,11 @@ __FBSDID("$FreeBSD$"); #endif #include #include -#include #ifdef __FreeBSD__ #include #else +#include #include #endif @@ -84,12 +84,14 @@ __FBSDID("$FreeBSD$"); #ifndef WITHOUT_CAPSICUM #include #endif +#ifdef __FreeBSD__ +#include +#endif #include #include "bhyverun.h" #include "acpi.h" #include "atkbdc.h" -#include "console.h" #include "bootrom.h" #include "config.h" #include "inout.h" @@ -107,9 +109,7 @@ __FBSDID("$FreeBSD$"); #include "smbiostbl.h" #include "xmsr.h" #include "spinup_ap.h" -#include "rfb.h" #include "rtc.h" -#include "vga.h" #include "vmgenc.h" #ifndef __FreeBSD__ #include "privileges.h" @@ -188,10 +188,9 @@ static const char * const vmx_exit_reason_desc[] = { }; typedef int (*vmexit_handler_t)(struct vmctx *, struct vm_exit *, int *vcpu); -extern int vmexit_task_switch(struct vmctx *, struct vm_exit *, int *vcpu); int guest_ncpus; -uint16_t cores, maxcpus, sockets, threads; +uint16_t cpu_cores, cpu_sockets, cpu_threads; int raw_stdio = 0; @@ -200,31 +199,33 @@ static const int BSP = 0; static cpuset_t cpumask; -static void vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip); +static void vm_loop(struct vmctx *ctx, int vcpu); -static struct vm_exit *vmexit; #ifndef __FreeBSD__ static struct vm_entry *vmentry; #endif -struct bhyvestats { +static struct bhyvestats { uint64_t vmexit_bogus; uint64_t vmexit_reqidle; uint64_t vmexit_hlt; uint64_t vmexit_pause; uint64_t vmexit_mtrap; +#ifdef __FreeBSD__ + uint64_t vmexit_inst_emul; +#else uint64_t vmexit_mmio; uint64_t vmexit_inout; + uint64_t mmio_unhandled; +#endif uint64_t cpu_switch_rotate; uint64_t cpu_switch_direct; - uint64_t mmio_unhandled; } stats; -struct mt_vmm_info { +static struct mt_vmm_info { pthread_t mt_thr; struct vmctx *mt_ctx; int mt_vcpu; - uint64_t mt_startrip; } *mt_vmm_info; #ifdef __FreeBSD__ @@ -256,13 +257,16 @@ usage(int code) " -B type,key=value,...: set SMBIOS information\n" #endif " -C: include guest memory in core file\n" - " -c: number of cpus and/or topology specification\n" + " -c: number of CPUs and/or topology specification\n" " -D: destroy on power-off\n" #ifndef __FreeBSD__ - " -d: suspend cpu at boot\n" + " -d: suspend cpu at boot\n" #endif " -e: exit on unhandled I/O access\n" - " -H: vmexit from the guest on hlt\n" +#ifdef __FreeBSD__ + " -G: start a debug server\n" +#endif + " -H: vmexit from the guest on HLT\n" " -h: help\n" " -k: key=value flat config file\n" " -K: PS2 keyboard layout\n" @@ -275,11 +279,11 @@ usage(int code) #endif " -S: guest memory cannot be swapped\n" " -s: PCI slot config\n" - " -U: uuid\n" + " -U: UUID\n" " -u: RTC keeps UTC time\n" " -W: force virtio to use single-vector MSI\n" " -w: ignore unimplemented MSRs\n" - " -x: local apic is in x2APIC mode\n" + " -x: local APIC is in x2APIC mode\n" " -Y: disable MPtable generation\n", progname, (int)strlen(progname), "", (int)strlen(progname), "", (int)strlen(progname), ""); @@ -360,7 +364,7 @@ parse_int_value(const char *key, const char *value, int minval, int maxval) * vm_set_topology(). vmm.ko may enforce tighter limits. */ static void -calc_topolopgy(void) +calc_topology(void) { const char *value; bool explicit_cpus; @@ -376,80 +380,47 @@ calc_topolopgy(void) } value = get_config_value("cores"); if (value != NULL) - cores = parse_int_value("cores", value, 1, UINT16_MAX); + cpu_cores = parse_int_value("cores", value, 1, UINT16_MAX); else - cores = 1; + cpu_cores = 1; value = get_config_value("threads"); if (value != NULL) - threads = parse_int_value("threads", value, 1, UINT16_MAX); + cpu_threads = parse_int_value("threads", value, 1, UINT16_MAX); else - threads = 1; + cpu_threads = 1; value = get_config_value("sockets"); if (value != NULL) - sockets = parse_int_value("sockets", value, 1, UINT16_MAX); + cpu_sockets = parse_int_value("sockets", value, 1, UINT16_MAX); else - sockets = guest_ncpus; + cpu_sockets = guest_ncpus; /* * Compute sockets * cores * threads avoiding overflow. The * range check above insures these are 16 bit values. */ - ncpus = (uint64_t)sockets * cores * threads; + ncpus = (uint64_t)cpu_sockets * cpu_cores * cpu_threads; if (ncpus > UINT16_MAX) errx(4, "Computed number of vCPUs too high: %ju", (uintmax_t)ncpus); if (explicit_cpus) { - if (guest_ncpus != ncpus) + if (guest_ncpus != (int)ncpus) errx(4, "Topology (%d sockets, %d cores, %d threads) " - "does not match %d vCPUs", sockets, cores, threads, + "does not match %d vCPUs", + cpu_sockets, cpu_cores, cpu_threads, guest_ncpus); } else guest_ncpus = ncpus; } -#ifndef WITHOUT_CAPSICUM -/* - * 11-stable capsicum helpers - */ -static void -bhyve_caph_cache_catpages(void) -{ - - (void)catopen("libc", NL_CAT_LOCALE); -} - -static int -bhyve_caph_limit_stdoe(void) -{ - cap_rights_t rights; - unsigned long cmds[] = { TIOCGETA, TIOCGWINSZ }; - int i, fds[] = { STDOUT_FILENO, STDERR_FILENO }; - - cap_rights_init(&rights, CAP_FCNTL, CAP_FSTAT, CAP_IOCTL); - cap_rights_set(&rights, CAP_WRITE); - - for (i = 0; i < nitems(fds); i++) { - if (cap_rights_limit(fds[i], &rights) < 0 && errno != ENOSYS) - return (-1); - - if (cap_ioctls_limit(fds[i], cmds, nitems(cmds)) < 0 && errno != ENOSYS) - return (-1); - - if (cap_fcntls_limit(fds[i], CAP_FCNTL_GETFL) < 0 && errno != ENOSYS) - return (-1); - } - - return (0); -} - -#endif - #ifdef __FreeBSD__ static int pincpu_parse(const char *opt) { int vcpu, pcpu; + const char *value; + char *newval; + char key[16]; if (sscanf(opt, "%d:%d", &vcpu, &pcpu) != 2) { fprintf(stderr, "invalid format: %s\n", opt); @@ -505,12 +476,12 @@ parse_cpuset(int vcpu, const char *list, cpuset_t *set) errx(4, "Invalid hostcpu range %d-%d", start, pcpu); while (start < pcpu) { - CPU_SET(start, vcpumap[vcpu]); + CPU_SET(start, set); start++; } start = -1; } - CPU_SET(pcpu, vcpumap[vcpu]); + CPU_SET(pcpu, set); break; case '-': if (start >= 0) @@ -582,7 +553,11 @@ fbsdrun_start_thread(void *param) { char tname[MAXCOMLEN + 1]; struct mt_vmm_info *mtp; +#ifdef __FreeBSD__ + int error, vcpu; +#else int vcpu; +#endif mtp = param; vcpu = mtp->mt_vcpu; @@ -590,53 +565,39 @@ fbsdrun_start_thread(void *param) snprintf(tname, sizeof(tname), "vcpu %d", vcpu); pthread_set_name_np(mtp->mt_thr, tname); +#ifdef __FreeBSD__ + if (vcpumap[vcpu] != NULL) { + error = pthread_setaffinity_np(pthread_self(), + sizeof(cpuset_t), vcpumap[vcpu]); + assert(error == 0); + } +#endif + gdb_cpu_add(vcpu); - vm_loop(mtp->mt_ctx, vcpu, mtp->mt_startrip); + vm_loop(mtp->mt_ctx, vcpu); /* not reached */ exit(1); return (NULL); } -#ifdef __FreeBSD__ -void -fbsdrun_addcpu(struct vmctx *ctx, int fromcpu, int newcpu, uint64_t rip) -#else void -fbsdrun_addcpu(struct vmctx *ctx, int newcpu, uint64_t rip, bool suspend) -#endif +fbsdrun_addcpu(struct vmctx *ctx, int newcpu, bool suspend) { int error; -#ifdef __FreeBSD__ - assert(fromcpu == BSP); -#endif - - /* - * The 'newcpu' must be activated in the context of 'fromcpu'. If - * vm_activate_cpu() is delayed until newcpu's pthread starts running - * then vmm.ko is out-of-sync with bhyve and this can create a race - * with vm_suspend(). - */ error = vm_activate_cpu(ctx, newcpu); if (error != 0) err(EX_OSERR, "could not activate CPU %d", newcpu); CPU_SET_ATOMIC(newcpu, &cpumask); -#ifndef __FreeBSD__ if (suspend) (void) vm_suspend_cpu(ctx, newcpu); -#endif - /* - * Set up the vmexit struct to allow execution to start - * at the given RIP - */ mt_vmm_info[newcpu].mt_ctx = ctx; mt_vmm_info[newcpu].mt_vcpu = newcpu; - mt_vmm_info[newcpu].mt_startrip = rip; error = pthread_create(&mt_vmm_info[newcpu].mt_thr, NULL, fbsdrun_start_thread, &mt_vmm_info[newcpu]); @@ -644,7 +605,7 @@ fbsdrun_addcpu(struct vmctx *ctx, int newcpu, uint64_t rip, bool suspend) } static int -fbsdrun_deletecpu(struct vmctx *ctx, int vcpu) +fbsdrun_deletecpu(int vcpu) { if (!CPU_ISSET(vcpu, &cpumask)) { @@ -656,6 +617,7 @@ fbsdrun_deletecpu(struct vmctx *ctx, int vcpu) return (CPU_EMPTY(&cpumask)); } +#ifndef __FreeBSD__ static void vmentry_mmio_read(int vcpu, uint64_t gpa, uint8_t bytes, uint64_t data) { @@ -715,10 +677,11 @@ vmentry_inout_write(int vcpu, uint16_t port, uint8_t bytes) inout->port = port; inout->eax = 0; } +#endif static int -vmexit_handle_notify(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu, - uint32_t eax) +vmexit_handle_notify(struct vmctx *ctx __unused, struct vm_exit *vme __unused, + int *pvcpu __unused, uint32_t eax __unused) { #if BHYVE_DEBUG /* @@ -756,7 +719,7 @@ vmexit_inout(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) fprintf(stderr, "Unhandled %s%c 0x%04x at 0x%lx\n", in ? "in" : "out", bytes == 1 ? 'b' : (bytes == 2 ? 'w' : 'l'), - inout.port, vmexit->rip); + inout.port, vme->rip); return (VMEXIT_ABORT); } else { /* @@ -818,17 +781,7 @@ vmexit_wrmsr(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) return (VMEXIT_CONTINUE); } -#ifdef __FreeBSD__ -static int -vmexit_spinup_ap(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) -{ - - (void)spinup_ap(ctx, *pvcpu, - vme->u.spinup_ap.vcpu, vme->u.spinup_ap.rip); - - return (VMEXIT_CONTINUE); -} -#else +#ifndef __FreeBSD__ static int vmexit_run_state(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) { @@ -877,22 +830,22 @@ vmexit_vmx_desc(uint32_t exit_reason) } static int -vmexit_vmx(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +vmexit_vmx(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) { fprintf(stderr, "vm exit[%d]\n", *pvcpu); fprintf(stderr, "\treason\t\tVMX\n"); - fprintf(stderr, "\trip\t\t0x%016lx\n", vmexit->rip); - fprintf(stderr, "\tinst_length\t%d\n", vmexit->inst_length); - fprintf(stderr, "\tstatus\t\t%d\n", vmexit->u.vmx.status); - fprintf(stderr, "\texit_reason\t%u (%s)\n", vmexit->u.vmx.exit_reason, - vmexit_vmx_desc(vmexit->u.vmx.exit_reason)); + fprintf(stderr, "\trip\t\t0x%016lx\n", vme->rip); + fprintf(stderr, "\tinst_length\t%d\n", vme->inst_length); + fprintf(stderr, "\tstatus\t\t%d\n", vme->u.vmx.status); + fprintf(stderr, "\texit_reason\t%u (%s)\n", vme->u.vmx.exit_reason, + vmexit_vmx_desc(vme->u.vmx.exit_reason)); fprintf(stderr, "\tqualification\t0x%016lx\n", - vmexit->u.vmx.exit_qualification); - fprintf(stderr, "\tinst_type\t\t%d\n", vmexit->u.vmx.inst_type); - fprintf(stderr, "\tinst_error\t\t%d\n", vmexit->u.vmx.inst_error); + vme->u.vmx.exit_qualification); + fprintf(stderr, "\tinst_type\t\t%d\n", vme->u.vmx.inst_type); + fprintf(stderr, "\tinst_error\t\t%d\n", vme->u.vmx.inst_error); #ifdef DEBUG_EPT_MISCONFIG - if (vmexit->u.vmx.exit_reason == EXIT_REASON_EPT_MISCONFIG) { + if (vme->u.vmx.exit_reason == EXIT_REASON_EPT_MISCONFIG) { vm_get_register(ctx, *pvcpu, VMCS_IDENT(VMCS_GUEST_PHYSICAL_ADDRESS), &ept_misconfig_gpa); @@ -910,24 +863,25 @@ vmexit_vmx(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) } static int -vmexit_svm(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +vmexit_svm(struct vmctx *ctx __unused, struct vm_exit *vme, int *pvcpu) { fprintf(stderr, "vm exit[%d]\n", *pvcpu); fprintf(stderr, "\treason\t\tSVM\n"); - fprintf(stderr, "\trip\t\t0x%016lx\n", vmexit->rip); - fprintf(stderr, "\tinst_length\t%d\n", vmexit->inst_length); - fprintf(stderr, "\texitcode\t%#lx\n", vmexit->u.svm.exitcode); - fprintf(stderr, "\texitinfo1\t%#lx\n", vmexit->u.svm.exitinfo1); - fprintf(stderr, "\texitinfo2\t%#lx\n", vmexit->u.svm.exitinfo2); + fprintf(stderr, "\trip\t\t0x%016lx\n", vme->rip); + fprintf(stderr, "\tinst_length\t%d\n", vme->inst_length); + fprintf(stderr, "\texitcode\t%#lx\n", vme->u.svm.exitcode); + fprintf(stderr, "\texitinfo1\t%#lx\n", vme->u.svm.exitinfo1); + fprintf(stderr, "\texitinfo2\t%#lx\n", vme->u.svm.exitinfo2); return (VMEXIT_ABORT); } static int -vmexit_bogus(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +vmexit_bogus(struct vmctx *ctx __unused, struct vm_exit *vme, + int *pvcpu __unused) { - assert(vmexit->inst_length == 0); + assert(vme->inst_length == 0); stats.vmexit_bogus++; @@ -935,10 +889,11 @@ vmexit_bogus(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) } static int -vmexit_reqidle(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +vmexit_reqidle(struct vmctx *ctx __unused, struct vm_exit *vme, + int *pvcpu __unused) { - assert(vmexit->inst_length == 0); + assert(vme->inst_length == 0); stats.vmexit_reqidle++; @@ -946,7 +901,8 @@ vmexit_reqidle(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) } static int -vmexit_hlt(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +vmexit_hlt(struct vmctx *ctx __unused, struct vm_exit *vme __unused, + int *pvcpu __unused) { stats.vmexit_hlt++; @@ -960,7 +916,8 @@ vmexit_hlt(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) } static int -vmexit_pause(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +vmexit_pause(struct vmctx *ctx __unused, struct vm_exit *vme __unused, + int *pvcpu __unused) { stats.vmexit_pause++; @@ -969,10 +926,10 @@ vmexit_pause(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) } static int -vmexit_mtrap(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +vmexit_mtrap(struct vmctx *ctx __unused, struct vm_exit *vme, int *pvcpu) { - assert(vmexit->inst_length == 0); + assert(vme->inst_length == 0); stats.vmexit_mtrap++; @@ -982,28 +939,28 @@ vmexit_mtrap(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) } static int -vmexit_inst_emul(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +vmexit_inst_emul(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) { uint8_t i, valid; fprintf(stderr, "Failed to emulate instruction sequence "); - valid = vmexit->u.inst_emul.num_valid; + valid = vme->u.inst_emul.num_valid; if (valid != 0) { - assert(valid <= sizeof (vmexit->u.inst_emul.inst)); + assert(valid <= sizeof (vme->u.inst_emul.inst)); fprintf(stderr, "["); for (i = 0; i < valid; i++) { if (i == 0) { fprintf(stderr, "%02x", - vmexit->u.inst_emul.inst[i]); + vme->u.inst_emul.inst[i]); } else { fprintf(stderr, ", %02x", - vmexit->u.inst_emul.inst[i]); + vme->u.inst_emul.inst[i]); } } fprintf(stderr, "] "); } - fprintf(stderr, "@ %rip = %x\n", vmexit->rip); + fprintf(stderr, "@ %rip = %x\n", vme->rip); return (VMEXIT_ABORT); } @@ -1054,13 +1011,13 @@ static pthread_mutex_t resetcpu_mtx = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t resetcpu_cond = PTHREAD_COND_INITIALIZER; static int -vmexit_suspend(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +vmexit_suspend(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) { enum vm_suspend_how how; - how = vmexit->u.suspended.how; + how = vme->u.suspended.how; - fbsdrun_deletecpu(ctx, *pvcpu); + fbsdrun_deletecpu(*pvcpu); if (*pvcpu != BSP) { pthread_mutex_lock(&resetcpu_mtx); @@ -1094,7 +1051,8 @@ vmexit_suspend(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) } static int -vmexit_debug(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +vmexit_debug(struct vmctx *ctx __unused, struct vm_exit *vme __unused, + int *pvcpu) { gdb_cpu_suspend(*pvcpu); @@ -1102,13 +1060,44 @@ vmexit_debug(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) } static int -vmexit_breakpoint(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +vmexit_breakpoint(struct vmctx *ctx __unused, struct vm_exit *vme, int *pvcpu) { - gdb_cpu_breakpoint(*pvcpu, vmexit); + gdb_cpu_breakpoint(*pvcpu, vme); return (VMEXIT_CONTINUE); } +#ifdef __FreeBSD__ +static int +vmexit_ipi(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu __unused) +{ + int error = -1; + int i; + switch (vme->u.ipi.mode) { + case APIC_DELMODE_INIT: + CPU_FOREACH_ISSET(i, &vme->u.ipi.dmask) { + error = vm_suspend_cpu(ctx, i); + if (error) { + warnx("%s: failed to suspend cpu %d\n", + __func__, i); + break; + } + } + break; + case APIC_DELMODE_STARTUP: + CPU_FOREACH_ISSET(i, &vme->u.ipi.dmask) { + spinup_ap(ctx, i, vme->u.ipi.vector << PAGE_SHIFT); + } + error = 0; + break; + default: + break; + } + + return (error); +} +#endif + static vmexit_handler_t handler[VM_EXITCODE_MAX] = { [VM_EXITCODE_INOUT] = vmexit_inout, [VM_EXITCODE_MMIO] = vmexit_mmio, @@ -1120,9 +1109,7 @@ static vmexit_handler_t handler[VM_EXITCODE_MAX] = { [VM_EXITCODE_WRMSR] = vmexit_wrmsr, [VM_EXITCODE_MTRAP] = vmexit_mtrap, [VM_EXITCODE_INST_EMUL] = vmexit_inst_emul, -#ifdef __FreeBSD__ - [VM_EXITCODE_SPINUP_AP] = vmexit_spinup_ap, -#else +#ifndef __FreeBSD__ [VM_EXITCODE_RUN_STATE] = vmexit_run_state, [VM_EXITCODE_PAGING] = vmexit_paging, [VM_EXITCODE_HLT] = vmexit_hlt, @@ -1131,35 +1118,27 @@ static vmexit_handler_t handler[VM_EXITCODE_MAX] = { [VM_EXITCODE_TASK_SWITCH] = vmexit_task_switch, [VM_EXITCODE_DEBUG] = vmexit_debug, [VM_EXITCODE_BPT] = vmexit_breakpoint, +#ifdef __FreeBSD__ + [VM_EXITCODE_IPI] = vmexit_ipi, +#endif }; static void -vm_loop(struct vmctx *ctx, int vcpu, uint64_t startrip) +vm_loop(struct vmctx *ctx, int vcpu) { + struct vm_exit vme; int error, rc; enum vm_exitcode exitcode; cpuset_t active_cpus; - struct vm_exit *vexit; struct vm_entry *ventry; -#ifdef __FreeBSD__ - if (vcpumap[vcpu] != NULL) { - error = pthread_setaffinity_np(pthread_self(), - sizeof(cpuset_t), vcpumap[vcpu]); - assert(error == 0); - } -#endif error = vm_active_cpus(ctx, &active_cpus); assert(CPU_ISSET(vcpu, &active_cpus)); - error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RIP, startrip); - assert(error == 0); - ventry = &vmentry[vcpu]; - vexit = &vmexit[vcpu]; while (1) { - error = vm_run(ctx, vcpu, ventry, vexit); + error = vm_run(ctx, vcpu, ventry, &vme); if (error != 0) break; @@ -1171,14 +1150,14 @@ vm_loop(struct vmctx *ctx, int vcpu, uint64_t startrip) bzero(ventry, sizeof (*ventry)); } - exitcode = vexit->exitcode; + exitcode = vme.exitcode; if (exitcode >= VM_EXITCODE_MAX || handler[exitcode] == NULL) { fprintf(stderr, "vm_loop: unexpected exitcode 0x%x\n", exitcode); exit(4); } - rc = (*handler[exitcode])(ctx, vexit, &vcpu); + rc = (*handler[exitcode])(ctx, &vme, &vcpu); switch (rc) { case VMEXIT_CONTINUE: @@ -1219,7 +1198,7 @@ num_vcpus_allowed(struct vmctx *ctx) return (1); } -void +static void fbsdrun_set_capabilities(struct vmctx *ctx, int cpu) { int err, tmp; @@ -1276,6 +1255,9 @@ fbsdrun_set_capabilities(struct vmctx *ctx, int cpu) #ifdef __FreeBSD__ vm_set_capability(ctx, cpu, VM_CAP_ENABLE_INVPCID, 1); + + err = vm_set_capability(ctx, cpu, VM_CAP_IPI_EXIT, 1); + assert(err == 0); #endif } @@ -1285,11 +1267,6 @@ do_open(const char *vmname) struct vmctx *ctx; int error; bool reinit, romboot; -#ifndef WITHOUT_CAPSICUM - cap_rights_t rights; - const cap_ioctl_t *cmds; - size_t ncmds; -#endif reinit = romboot = false; @@ -1336,16 +1313,8 @@ do_open(const char *vmname) } #ifndef WITHOUT_CAPSICUM - cap_rights_init(&rights, CAP_IOCTL, CAP_MMAP_RW); - if (caph_rights_limit(vm_get_device_fd(ctx), &rights) == -1) - errx(EX_OSERR, "Unable to apply rights for sandbox"); - vm_get_ioctls(&ncmds); - cmds = vm_get_ioctls(NULL); - if (cmds == NULL) - errx(EX_OSERR, "out of memory"); - if (caph_ioctls_limit(vm_get_device_fd(ctx), cmds, ncmds) == -1) - errx(EX_OSERR, "Unable to apply rights for sandbox"); - free((cap_ioctl_t *)cmds); + if (vm_limit_rights(ctx) != 0) + err(EX_OSERR, "vm_limit_rights"); #endif if (reinit) { @@ -1359,12 +1328,55 @@ do_open(const char *vmname) exit(4); } } - error = vm_set_topology(ctx, sockets, cores, threads, maxcpus); + error = vm_set_topology(ctx, cpu_sockets, cpu_cores, cpu_threads, + 0 /* maxcpus, unimplemented */); if (error) errx(EX_OSERR, "vm_set_topology"); return (ctx); } +static void +spinup_vcpu(struct vmctx *ctx, int vcpu, bool suspend) +{ + int error; + + if (vcpu != BSP) { +#ifndef __FreeBSD__ + /* + * On illumos, all APs are spun up halted and run-state + * transitions (INIT, SIPI, etc) are handled in-kernel. + */ + spinup_ap(ctx, vcpu, 0); +#endif + + fbsdrun_set_capabilities(ctx, vcpu); + +#ifdef __FreeBSD__ + /* + * Enable the 'unrestricted guest' mode for APs. + * + * APs startup in power-on 16-bit mode. + */ + error = vm_set_capability(ctx, vcpu, VM_CAP_UNRESTRICTED_GUEST, 1); + assert(error == 0); +#endif + } + +#ifndef __FreeBSD__ + /* + * The value of 'suspend' for the BSP depends on whether the -d + * (suspend_at_boot) flag was given to bhyve. Regardless of that + * value we always want to set the BSP to VRS_RUN and all others to + * VRS_HALT. + */ + error = vm_set_run_state(ctx, vcpu, + vcpu == BSP ? VRS_RUN : VRS_HALT, 0); + assert(error == 0); +#endif + + fbsdrun_addcpu(ctx, vcpu, suspend); +} + static bool parse_config_option(const char *option) { @@ -1410,24 +1422,24 @@ parse_simple_config_file(const char *path) } static void -parse_gdb_options(char *optarg) +parse_gdb_options(const char *opt) { const char *sport; char *colon; - if (optarg[0] == 'w') { + if (opt[0] == 'w') { set_config_bool("gdb.wait", true); - optarg++; + opt++; } - colon = strrchr(optarg, ':'); + colon = strrchr(opt, ':'); if (colon == NULL) { - sport = optarg; + sport = opt; } else { *colon = '\0'; colon++; sport = colon; - set_config_value("gdb.address", optarg); + set_config_value("gdb.address", opt); } set_config_value("gdb.port", sport); @@ -1450,8 +1462,7 @@ main(int argc, char *argv[]) struct vmctx *ctx; uint64_t rip; size_t memsize; - const char *value, *vmname; - char *optstr; + const char *optstr, *value, *vmname; init_config(); set_defaults(); @@ -1612,7 +1623,8 @@ main(int argc, char *argv[]) illumos_priv_init(); #endif - calc_topolopgy(); + calc_topology(); + #ifdef __FreeBSD__ build_vcpumaps(); #endif @@ -1624,8 +1636,8 @@ main(int argc, char *argv[]) ctx = do_open(vmname); - max_vcpus = num_vcpus_allowed(ctx); - if (guest_ncpus > max_vcpus) { + max_vcpus = num_vcpus_allowed(ctx); + if (guest_ncpus > max_vcpus) { fprintf(stderr, "%d vCPUs requested but only %d available\n", guest_ncpus, max_vcpus); exit(4); @@ -1680,13 +1692,6 @@ main(int argc, char *argv[]) pmtmr_init(ctx); #endif - /* Allocate per-VCPU resources. */ - vmexit = calloc(guest_ncpus, sizeof(*vmexit)); - mt_vmm_info = calloc(guest_ncpus, sizeof(*mt_vmm_info)); -#ifndef __FreeBSD__ - vmentry = calloc(guest_ncpus, sizeof(*vmentry)); -#endif - /* * Exit if a device emulation finds an error in its initilization */ @@ -1733,7 +1738,7 @@ main(int argc, char *argv[]) assert(error == 0); /* - * build the guest tables, MP etc. + * build the guest tables, MP etc. */ if (get_config_bool_default("x86.mptable", true)) { error = mptable_build(ctx, guest_ncpus); @@ -1774,23 +1779,25 @@ main(int argc, char *argv[]) illumos_priv_lock(); #endif -#ifdef __FreeBSD__ + /* Allocate per-VCPU resources. */ + mt_vmm_info = calloc(guest_ncpus, sizeof(*mt_vmm_info)); +#ifndef __FreeBSD__ + vmentry = calloc(guest_ncpus, sizeof(*vmentry)); +#endif + /* - * Add CPU 0 + * Add all vCPUs. */ - fbsdrun_addcpu(ctx, BSP, BSP, rip); + for (int vcpu = 0; vcpu < guest_ncpus; vcpu++) { +#ifdef __FreeBSD__ + bool suspend = (vcpu != BSP); #else - /* Set BSP to run (unlike the APs which wait for INIT) */ - error = vm_set_run_state(ctx, BSP, VRS_RUN, 0); - assert(error == 0); - fbsdrun_addcpu(ctx, BSP, rip, - get_config_bool_default("suspend_at_boot", false)); - - /* Add subsequent CPUs, which will wait until INIT/SIPI-ed */ - for (uint_t i = 1; i < guest_ncpus; i++) { - spinup_halted_ap(ctx, i); - } + bool suspend = vcpu == BSP && + get_config_bool_default("suspend_at_boot", false); #endif + spinup_vcpu(ctx, vcpu, suspend); + } + /* * Head off to the main event dispatch loop */ diff --git a/usr/src/cmd/bhyve/bhyverun.h b/usr/src/cmd/bhyve/bhyverun.h index 24ff115345..39bdaa35e4 100644 --- a/usr/src/cmd/bhyve/bhyverun.h +++ b/usr/src/cmd/bhyve/bhyverun.h @@ -46,18 +46,18 @@ #define VMEXIT_CONTINUE (0) #define VMEXIT_ABORT (-1) -struct vmctx; extern int guest_ncpus; -extern uint16_t cores, sockets, threads; +extern uint16_t cpu_cores, cpu_sockets, cpu_threads; + +struct vmctx; +struct vm_exit; void *paddr_guest2host(struct vmctx *ctx, uintptr_t addr, size_t len); -void fbsdrun_set_capabilities(struct vmctx *ctx, int cpu); -#ifdef __FreeBSD__ -void fbsdrun_addcpu(struct vmctx *ctx, int fromcpu, int newcpu, uint64_t rip); -#else -void fbsdrun_addcpu(struct vmctx *ctx, int newcpu, uint64_t rip, bool suspend); -#endif +void fbsdrun_addcpu(struct vmctx *ctx, int newcpu, bool suspend); + int fbsdrun_virtio_msix(void); +int vmexit_task_switch(struct vmctx *, struct vm_exit *, int *vcpu); + #endif diff --git a/usr/src/cmd/bhyve/block_if.c b/usr/src/cmd/bhyve/block_if.c index dfbb9df85e..889e207f3f 100644 --- a/usr/src/cmd/bhyve/block_if.c +++ b/usr/src/cmd/bhyve/block_if.c @@ -121,7 +121,7 @@ enum blockif_wce { #endif struct blockif_ctxt { - int bc_magic; + unsigned int bc_magic; int bc_fd; int bc_ischr; int bc_isgeom; @@ -272,44 +272,48 @@ blockif_flush_bc(struct blockif_ctxt *bc) static void blockif_proc(struct blockif_ctxt *bc, struct blockif_elem *be, uint8_t *buf) { +#ifdef __FreeBSD__ + struct spacectl_range range; +#endif struct blockif_req *br; #ifdef __FreeBSD__ off_t arg[2]; #endif - ssize_t clen, len, off, boff, voff; + ssize_t n; + size_t clen, len, off, boff, voff; int i, err; -#ifdef __FreeBSD__ - struct spacectl_range range; -#endif br = be->be_req; + assert(br->br_resid >= 0); + if (br->br_iovcnt <= 1) buf = NULL; err = 0; switch (be->be_op) { case BOP_READ: if (buf == NULL) { - if ((len = preadv(bc->bc_fd, br->br_iov, br->br_iovcnt, - br->br_offset)) < 0) + if ((n = preadv(bc->bc_fd, br->br_iov, br->br_iovcnt, + br->br_offset)) < 0) err = errno; else - br->br_resid -= len; + br->br_resid -= n; break; } i = 0; off = voff = 0; while (br->br_resid > 0) { len = MIN(br->br_resid, MAXPHYS); - if (pread(bc->bc_fd, buf, len, br->br_offset + - off) < 0) { + n = pread(bc->bc_fd, buf, len, br->br_offset + off); + if (n < 0) { err = errno; break; } + len = (size_t)n; boff = 0; do { clen = MIN(len - boff, br->br_iov[i].iov_len - voff); - memcpy(br->br_iov[i].iov_base + voff, + memcpy((uint8_t *)br->br_iov[i].iov_base + voff, buf + boff, clen); if (clen < br->br_iov[i].iov_len - voff) voff += clen; @@ -329,11 +333,11 @@ blockif_proc(struct blockif_ctxt *bc, struct blockif_elem *be, uint8_t *buf) break; } if (buf == NULL) { - if ((len = pwritev(bc->bc_fd, br->br_iov, br->br_iovcnt, - br->br_offset)) < 0) + if ((n = pwritev(bc->bc_fd, br->br_iov, br->br_iovcnt, + br->br_offset)) < 0) err = errno; else - br->br_resid -= len; + br->br_resid -= n; break; } i = 0; @@ -345,7 +349,8 @@ blockif_proc(struct blockif_ctxt *bc, struct blockif_elem *be, uint8_t *buf) clen = MIN(len - boff, br->br_iov[i].iov_len - voff); memcpy(buf + boff, - br->br_iov[i].iov_base + voff, clen); + (uint8_t *)br->br_iov[i].iov_base + voff, + clen); if (clen < br->br_iov[i].iov_len - voff) voff += clen; else { @@ -354,13 +359,14 @@ blockif_proc(struct blockif_ctxt *bc, struct blockif_elem *be, uint8_t *buf) } boff += clen; } while (boff < len); - if (pwrite(bc->bc_fd, buf, len, br->br_offset + - off) < 0) { + + n = pwrite(bc->bc_fd, buf, len, br->br_offset + off); + if (n < 0) { err = errno; break; } - off += len; - br->br_resid -= len; + off += n; + br->br_resid -= n; } break; case BOP_FLUSH: @@ -481,10 +487,11 @@ blockif_thr(void *arg) #ifdef __FreeBSD__ static void -blockif_sigcont_handler(int signal, enum ev_type type, void *arg) +blockif_sigcont_handler(int signal __unused, enum ev_type type __unused, + void *arg __unused) #else static void -blockif_sigcont_handler(int signal) +blockif_sigcont_handler(int signal __unused) #endif { struct blockif_sig_elem *bse; @@ -822,7 +829,7 @@ err: } static void -blockif_resized(int fd, enum ev_type type, void *arg) +blockif_resized(int fd, enum ev_type type __unused, void *arg) { struct blockif_ctxt *bc; struct stat sb; @@ -865,13 +872,12 @@ blockif_register_resize_callback(struct blockif_ctxt *bc, blockif_resize_cb *cb, { struct stat sb; int err; -#ifndef __FreeBSD__ - err = 0; -#endif if (cb == NULL) return (EINVAL); + err = 0; + pthread_mutex_lock(&bc->bc_mtx); if (bc->bc_resize_cb != NULL) { err = EBUSY; @@ -1083,10 +1089,10 @@ blockif_chs(struct blockif_ctxt *bc, uint16_t *c, uint8_t *h, uint8_t *s) sectors = bc->bc_size / bc->bc_sectsz; /* Clamp the size to the largest possible with CHS */ - if (sectors > 65535UL*16*255) - sectors = 65535UL*16*255; + if (sectors > 65535L * 16 * 255) + sectors = 65535L * 16 * 255; - if (sectors >= 65536UL*16*63) { + if (sectors >= 65536L * 16 * 63) { secpt = 255; heads = 16; hcyl = sectors / secpt; diff --git a/usr/src/cmd/bhyve/bootrom.c b/usr/src/cmd/bhyve/bootrom.c index 00f0a1a2a5..fa20fa8ac9 100644 --- a/usr/src/cmd/bhyve/bootrom.c +++ b/usr/src/cmd/bhyve/bootrom.c @@ -84,8 +84,9 @@ static struct bootrom_var_state { * that the Firmware Volume area is writable and persistent. */ static int -bootrom_var_mem_handler(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, - int size, uint64_t *val, void *arg1, long arg2) +bootrom_var_mem_handler(struct vmctx *ctx __unused, int vcpu __unused, int dir, + uint64_t addr, int size, uint64_t *val, void *arg1 __unused, + long arg2 __unused) { off_t offset; diff --git a/usr/src/cmd/bhyve/config.c b/usr/src/cmd/bhyve/config.c index 5d6f2c0170..214bb0daf6 100644 --- a/usr/src/cmd/bhyve/config.c +++ b/usr/src/cmd/bhyve/config.c @@ -33,6 +33,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifndef __FreeBSD__ +#include +#endif #include "config.h" @@ -64,7 +67,17 @@ _lookup_config_node(nvlist_t *parent, const char *path, bool create) break; } if (nvlist_exists_nvlist(nvl, name)) - nvl = (nvlist_t *)nvlist_get_nvlist(nvl, name); + /* + * XXX-MJ it is incorrect to cast away the const + * qualifier like this since the contract with nvlist + * says that values are immutable, and some consumers + * will indeed add nodes to the returned nvlist. In + * practice, however, it appears to be harmless with the + * current nvlist implementation, so we just live with + * it until the implementation is reworked. + */ + nvl = __DECONST(nvlist_t *, + nvlist_get_nvlist(nvl, name)); else if (nvlist_exists(nvl, name)) { for (copy = tofree; copy < name; copy++) if (*copy == '\0') @@ -75,6 +88,10 @@ _lookup_config_node(nvlist_t *parent, const char *path, bool create) nvl = NULL; break; } else if (create) { + /* + * XXX-MJ as with the case above, "new_nvl" shouldn't be + * mutated after its ownership is given to "nvl". + */ new_nvl = nvlist_create(0); if (new_nvl == NULL) errx(4, "Failed to allocate memory"); diff --git a/usr/src/cmd/bhyve/config.h b/usr/src/cmd/bhyve/config.h index 8d3f6f90b2..a7e4b6d03a 100644 --- a/usr/src/cmd/bhyve/config.h +++ b/usr/src/cmd/bhyve/config.h @@ -38,7 +38,7 @@ * The database only stores string values. Callers should parse * values into other types if needed. String values can reference * other configuration variables using a '%(name)' syntax. In this - * case, the name must be the the full path of the configuration + * case, the name must be the full path of the configuration * variable. The % character can be escaped with a preceding \ to * avoid expansion. Any \ characters must be escaped. * diff --git a/usr/src/cmd/bhyve/fwctl.c b/usr/src/cmd/bhyve/fwctl.c index 7027e34a77..047a1050e7 100644 --- a/usr/src/cmd/bhyve/fwctl.c +++ b/usr/src/cmd/bhyve/fwctl.c @@ -88,20 +88,17 @@ static struct op_info *ops[OP_MAX+1]; /* Return 0-padded uint32_t */ static uint32_t -fwctl_send_rest(uint32_t *data, size_t len) +fwctl_send_rest(uint8_t *data, size_t len) { union { uint8_t c[4]; uint32_t w; } u; - uint8_t *cdata; - int i; + size_t i; - cdata = (uint8_t *) data; u.w = 0; - - for (i = 0, u.w = 0; i < len; i++) - u.c[i] = *cdata++; + for (i = 0; i < len; i++) + u.c[i] = *data++; return (u.w); } @@ -119,7 +116,7 @@ errop_set(int err) } static int -errop_start(uint32_t len) +errop_start(uint32_t len __unused) { errop_code = ENOENT; @@ -128,7 +125,7 @@ errop_start(uint32_t len) } static void -errop_data(uint32_t data, uint32_t len) +errop_data(uint32_t data __unused, uint32_t len __unused) { /* ignore */ @@ -144,7 +141,7 @@ errop_result(struct iovec **data) } static void -errop_done(struct iovec *data) +errop_done(struct iovec *data __unused) { /* assert data is NULL */ @@ -200,10 +197,10 @@ fget_start(uint32_t len) } static void -fget_data(uint32_t data, uint32_t len) +fget_data(uint32_t data, uint32_t len __unused) { - *((uint32_t *) &fget_str[fget_cnt]) = data; + memcpy(&fget_str[fget_cnt], &data, sizeof(data)); fget_cnt += sizeof(uint32_t); } @@ -244,7 +241,7 @@ fget_result(struct iovec **data, int val) } static void -fget_done(struct iovec *data) +fget_done(struct iovec *data __unused) { /* nothing needs to be freed */ @@ -401,7 +398,7 @@ fwctl_request(uint32_t value) static int fwctl_response(uint32_t *retval) { - uint32_t *dp; + uint8_t *dp; ssize_t remlen; switch(rinfo.resp_count) { @@ -425,10 +422,9 @@ fwctl_response(uint32_t *retval) break; default: remlen = rinfo.resp_size - rinfo.resp_off; - dp = (uint32_t *) - ((uint8_t *)rinfo.resp_biov->iov_base + rinfo.resp_off); - if (remlen >= sizeof(uint32_t)) { - *retval = *dp; + dp = (uint8_t *)rinfo.resp_biov->iov_base + rinfo.resp_off; + if (remlen >= (ssize_t)sizeof(uint32_t)) { + memcpy(retval, dp, sizeof(uint32_t)); } else if (remlen > 0) { *retval = fwctl_send_rest(dp, remlen); } @@ -520,8 +516,8 @@ fwctl_outl(uint32_t val) } static int -fwctl_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +fwctl_handler(struct vmctx *ctx __unused, int in, + int port __unused, int bytes, uint32_t *eax, void *arg __unused) { if (in) { diff --git a/usr/src/cmd/bhyve/gdb.c b/usr/src/cmd/bhyve/gdb.c index 5dda1737b3..05b14b4b8a 100644 --- a/usr/src/cmd/bhyve/gdb.c +++ b/usr/src/cmd/bhyve/gdb.c @@ -981,7 +981,6 @@ static void gdb_read_regs(void) { uint64_t regvals[nitems(gdb_regset)]; - int i; if (vm_get_register_set(ctx, cur_vcpu, nitems(gdb_regset), gdb_regset, regvals) == -1) { @@ -989,7 +988,7 @@ gdb_read_regs(void) return; } start_packet(); - for (i = 0; i < nitems(regvals); i++) + for (size_t i = 0; i < nitems(regvals); i++) append_unsigned_native(regvals[i], gdb_regsize[i]); finish_packet(); } @@ -1738,15 +1737,18 @@ check_command(int fd) } static void -gdb_readable(int fd, enum ev_type event, void *arg) +gdb_readable(int fd, enum ev_type event __unused, void *arg __unused) { + size_t pending; ssize_t nread; - int pending; + int n; - if (ioctl(fd, FIONREAD, &pending) == -1) { + if (ioctl(fd, FIONREAD, &n) == -1) { warn("FIONREAD on GDB socket"); return; } + assert(n >= 0); + pending = n; /* * 'pending' might be zero due to EOF. We need to call read @@ -1777,14 +1779,14 @@ gdb_readable(int fd, enum ev_type event, void *arg) } static void -gdb_writable(int fd, enum ev_type event, void *arg) +gdb_writable(int fd, enum ev_type event __unused, void *arg __unused) { send_pending_data(fd); } static void -new_connection(int fd, enum ev_type event, void *arg) +new_connection(int fd, enum ev_type event __unused, void *arg) { int optval, s; diff --git a/usr/src/cmd/bhyve/hda_codec.c b/usr/src/cmd/bhyve/hda_codec.c index 2cc875d3d2..cfab2e7f25 100644 --- a/usr/src/cmd/bhyve/hda_codec.c +++ b/usr/src/cmd/bhyve/hda_codec.c @@ -465,7 +465,7 @@ hda_codec_init(struct hda_codec_inst *hci, const char *play, static int hda_codec_reset(struct hda_codec_inst *hci) { - struct hda_ops *hops = NULL; + const struct hda_ops *hops = NULL; struct hda_codec_softc *sc = NULL; struct hda_codec_stream *st = NULL; int i; @@ -500,8 +500,8 @@ hda_codec_reset(struct hda_codec_inst *hci) static int hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data) { + const struct hda_ops *hops = NULL; struct hda_codec_softc *sc = NULL; - struct hda_ops *hops = NULL; uint8_t cad = 0, nid = 0; uint16_t verb = 0, payload = 0; uint32_t res = 0; @@ -677,9 +677,9 @@ hda_codec_audio_output_nid(struct hda_codec_softc *sc, uint16_t verb, static void hda_codec_audio_output_do_transfer(void *arg) { + const struct hda_ops *hops = NULL; struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; struct hda_codec_inst *hci = NULL; - struct hda_ops *hops = NULL; struct hda_codec_stream *st = NULL; struct audio *aud = NULL; int err; @@ -738,9 +738,9 @@ hda_codec_audio_input_nid(struct hda_codec_softc *sc, uint16_t verb, static void hda_codec_audio_input_do_transfer(void *arg) { + const struct hda_ops *hops = NULL; struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; struct hda_codec_inst *hci = NULL; - struct hda_ops *hops = NULL; struct hda_codec_stream *st = NULL; struct audio *aud = NULL; int err; diff --git a/usr/src/cmd/bhyve/hexdump.c b/usr/src/cmd/bhyve/hexdump.c new file mode 100644 index 0000000000..b128622182 --- /dev/null +++ b/usr/src/cmd/bhyve/hexdump.c @@ -0,0 +1,97 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1986, 1988, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include "hexdump.h" + +void +hexdump(const void *ptr, int length, const char *hdr, int flags) +{ + int i, j, k; + int cols; + const unsigned char *cp; + char delim; + + if ((flags & HD_DELIM_MASK) != 0) + delim = (flags & HD_DELIM_MASK) >> 8; + else + delim = ' '; + + if ((flags & HD_COLUMN_MASK) != 0) + cols = flags & HD_COLUMN_MASK; + else + cols = 16; + + cp = ptr; + for (i = 0; i < length; i += cols) { + if (hdr != NULL) + printf("%s", hdr); + + if ((flags & HD_OMIT_COUNT) == 0) + printf("%04x ", i); + + if ((flags & HD_OMIT_HEX) == 0) { + for (j = 0; j < cols; j++) { + k = i + j; + if (k < length) + printf("%c%02x", delim, cp[k]); + else + printf(" "); + } + } + + if ((flags & HD_OMIT_CHARS) == 0) { + printf(" |"); + for (j = 0; j < cols; j++) { + k = i + j; + if (k >= length) + printf(" "); + else if (cp[k] >= ' ' && cp[k] <= '~') + printf("%c", cp[k]); + else + printf("."); + } + printf("|"); + } + printf("\n"); + } +} diff --git a/usr/src/cmd/bhyve/post.c b/usr/src/cmd/bhyve/hexdump.h similarity index 50% copy from usr/src/cmd/bhyve/post.c copy to usr/src/cmd/bhyve/hexdump.h index d3040a8df7..14ef719911 100644 --- a/usr/src/cmd/bhyve/post.c +++ b/usr/src/cmd/bhyve/hexdump.h @@ -1,22 +1,32 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-3-Clause * - * Copyright (c) 2011 NetApp, Inc. + * Copyright (c) 1996 Peter Wemm . * All rights reserved. + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * Portions of this software were developed for the FreeBSD Project by + * ThinkSec AS and NAI Labs, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions + * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. * - * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -28,28 +38,15 @@ * $FreeBSD$ */ -#include -__FBSDID("$FreeBSD$"); - -#include - -#include - -#include "inout.h" -#include "pci_lpc.h" - -static int -post_data_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) -{ - assert(in == 1); +#ifndef _HEXDUMP_H_ +#define _HEXDUMP_H_ - if (bytes != 1) - return (-1); +#define HD_COLUMN_MASK 0xff +#define HD_DELIM_MASK 0xff00 +#define HD_OMIT_COUNT (1 << 16) +#define HD_OMIT_HEX (1 << 17) +#define HD_OMIT_CHARS (1 << 18) - *eax = 0xff; /* return some garbage */ - return (0); -} +void hexdump(const void *, int, const char *, int); -INOUT_PORT(post, 0x84, IOPORT_F_IN, post_data_handler); -SYSRES_IO(0x84, 1); +#endif /* !_HEXDUMP_H_ */ diff --git a/usr/src/cmd/bhyve/inout.c b/usr/src/cmd/bhyve/inout.c index 0548807730..b4add9da7a 100644 --- a/usr/src/cmd/bhyve/inout.c +++ b/usr/src/cmd/bhyve/inout.c @@ -79,8 +79,8 @@ struct inout_handler { static struct inout_handler inout_handlers[MAX_IOPORTS]; static int -default_inout(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +default_inout(struct vmctx *ctx __unused, int in, + int port __unused, int bytes, uint32_t *eax, void *arg __unused) { if (in) { switch (bytes) { @@ -147,7 +147,7 @@ emulate_inout(struct vmctx *ctx, int vcpu, struct vm_inout *inout) return (-1); } - error = hfunc(ctx, vcpu, in, inout->port, bytes, &inout->eax, harg); + error = hfunc(ctx, in, inout->port, bytes, &inout->eax, harg); return (error); } diff --git a/usr/src/cmd/bhyve/inout.h b/usr/src/cmd/bhyve/inout.h index a3b64b9001..7945b4231d 100644 --- a/usr/src/cmd/bhyve/inout.h +++ b/usr/src/cmd/bhyve/inout.h @@ -54,7 +54,7 @@ struct vm_inout; /* * inout emulation handlers return 0 on success and -1 on failure. */ -typedef int (*inout_func_t)(struct vmctx *ctx, int vcpu, int in, int port, +typedef int (*inout_func_t)(struct vmctx *ctx, int in, int port, int bytes, uint32_t *eax, void *arg); struct inout_port { diff --git a/usr/src/cmd/bhyve/iov.c b/usr/src/cmd/bhyve/iov.c index 2fa58ef9aa..ec2d806c6d 100644 --- a/usr/src/cmd/bhyve/iov.c +++ b/usr/src/cmd/bhyve/iov.c @@ -111,7 +111,7 @@ iov_to_buf(const struct iovec *iov, int niov, void **buf) return (-1); for (i = 0, ptr = 0; i < niov; i++) { - memcpy(*buf + ptr, iov[i].iov_base, iov[i].iov_len); + memcpy((uint8_t *)*buf + ptr, iov[i].iov_base, iov[i].iov_len); ptr += iov[i].iov_len; } @@ -141,7 +141,7 @@ buf_to_iov(const void *buf, size_t buflen, const struct iovec *iov, int niov, for (i = 0; i < niov && off < buflen; i++) { len = MIN(iov[i].iov_len, buflen - off); - memcpy(iov[i].iov_base, buf + off, len); + memcpy(iov[i].iov_base, (const uint8_t *)buf + off, len); off += len; } diff --git a/usr/src/cmd/bhyve/mem.c b/usr/src/cmd/bhyve/mem.c index 08756161a4..c7ab17f401 100644 --- a/usr/src/cmd/bhyve/mem.c +++ b/usr/src/cmd/bhyve/mem.c @@ -320,6 +320,10 @@ register_mem_int(struct mmio_rb_tree *rbt, struct mem_range *memp) pthread_rwlock_wrlock(&mmio_rwlock); if (mmio_rb_lookup(rbt, memp->base, &entry) != 0) err = mmio_rb_add(rbt, mrp); +#ifndef __FreeBSD__ + else /* smatch warn: possible memory leak of 'mrp' */ + free(mrp); +#endif perror = pthread_rwlock_unlock(&mmio_rwlock); assert(perror == 0); if (err) diff --git a/usr/src/cmd/bhyve/mevent.c b/usr/src/cmd/bhyve/mevent.c index 29f7d7fcfc..dcf82a5ce1 100644 --- a/usr/src/cmd/bhyve/mevent.c +++ b/usr/src/cmd/bhyve/mevent.c @@ -139,7 +139,7 @@ mevent_qunlock(void) } static void -mevent_pipe_read(int fd, enum ev_type type, void *param) +mevent_pipe_read(int fd, enum ev_type type __unused, void *param __unused) { char buf[MEVENT_MAX]; int status; diff --git a/usr/src/cmd/bhyve/mptbl.c b/usr/src/cmd/bhyve/mptbl.c index 923e0f42f5..55d828134b 100644 --- a/usr/src/cmd/bhyve/mptbl.c +++ b/usr/src/cmd/bhyve/mptbl.c @@ -213,8 +213,8 @@ mpt_count_ioint_entries(void) } static void -mpt_generate_pci_int(int bus, int slot, int pin, int pirq_pin, int ioapic_irq, - void *arg) +mpt_generate_pci_int(int bus, int slot, int pin, int pirq_pin __unused, + int ioapic_irq, void *arg) { int_entry_ptr *mpiep, mpie; diff --git a/usr/src/cmd/bhyve/net_backends.c b/usr/src/cmd/bhyve/net_backends.c index b870f4e865..1ef17a8e89 100644 --- a/usr/src/cmd/bhyve/net_backends.c +++ b/usr/src/cmd/bhyve/net_backends.c @@ -179,10 +179,12 @@ struct net_backend { /* Size of backend-specific private data. */ size_t priv_size; - /* Room for backend-specific data. */ - char opaque[0]; + /* Backend-specific private data follows. */ }; +#define NET_BE_PRIV(be) ((void *)((be) + 1)) +#define NET_BE_SIZE(be) (sizeof(*be) + (be)->priv_size) + SET_DECLARE(net_backend_set, struct net_backend); #define VNET_HDR_LEN sizeof(struct virtio_net_rxhdr) @@ -220,7 +222,7 @@ struct tap_priv { static void tap_cleanup(struct net_backend *be) { - struct tap_priv *priv = (struct tap_priv *)be->opaque; + struct tap_priv *priv = NET_BE_PRIV(be); if (priv->mevp) { mevent_delete(priv->mevp); @@ -233,14 +235,14 @@ tap_cleanup(struct net_backend *be) static int tap_init(struct net_backend *be, const char *devname, - nvlist_t *nvl, net_be_rxeof_t cb, void *param) + nvlist_t *nvl __unused, net_be_rxeof_t cb, void *param) { - struct tap_priv *priv = (struct tap_priv *)be->opaque; + struct tap_priv *priv = NET_BE_PRIV(be); char tbuf[80]; int opt = 1; #if defined(INET6) || defined(INET) struct ifreq ifrq; - int i, s; + int s; #endif #ifndef WITHOUT_CAPSICUM cap_rights_t rights; @@ -281,7 +283,7 @@ tap_init(struct net_backend *be, const char *devname, } s = -1; - for (i = 0; s == -1 && i < nitems(pf_list); i++) + for (size_t i = 0; s == -1 && i < nitems(pf_list); i++) s = socket(pf_list[i], SOCK_DGRAM, 0); if (s == -1) { WPRINTF(("Could open socket")); @@ -336,7 +338,7 @@ tap_send(struct net_backend *be, const struct iovec *iov, int iovcnt) static ssize_t tap_peek_recvlen(struct net_backend *be) { - struct tap_priv *priv = (struct tap_priv *)be->opaque; + struct tap_priv *priv = NET_BE_PRIV(be); ssize_t ret; if (priv->bbuflen > 0) { @@ -366,7 +368,7 @@ tap_peek_recvlen(struct net_backend *be) static ssize_t tap_recv(struct net_backend *be, const struct iovec *iov, int iovcnt) { - struct tap_priv *priv = (struct tap_priv *)be->opaque; + struct tap_priv *priv = NET_BE_PRIV(be); ssize_t ret; if (priv->bbuflen > 0) { @@ -394,7 +396,7 @@ tap_recv(struct net_backend *be, const struct iovec *iov, int iovcnt) static void tap_recv_enable(struct net_backend *be) { - struct tap_priv *priv = (struct tap_priv *)be->opaque; + struct tap_priv *priv = NET_BE_PRIV(be); mevent_enable(priv->mevp); } @@ -402,21 +404,21 @@ tap_recv_enable(struct net_backend *be) static void tap_recv_disable(struct net_backend *be) { - struct tap_priv *priv = (struct tap_priv *)be->opaque; + struct tap_priv *priv = NET_BE_PRIV(be); mevent_disable(priv->mevp); } static uint64_t -tap_get_cap(struct net_backend *be) +tap_get_cap(struct net_backend *be __unused) { return (0); /* no capabilities for now */ } static int -tap_set_cap(struct net_backend *be, uint64_t features, - unsigned vnet_hdr_len) +tap_set_cap(struct net_backend *be __unused, uint64_t features, + unsigned vnet_hdr_len) { return ((features || vnet_hdr_len) ? -1 : 0); @@ -463,10 +465,10 @@ DATA_SET(net_backend_set, vmnet_backend); #define NG_SBUF_MAX_SIZE (4 * 1024 * 1024) static int -ng_init(struct net_backend *be, const char *devname, +ng_init(struct net_backend *be, const char *devname __unused, nvlist_t *nvl, net_be_rxeof_t cb, void *param) { - struct tap_priv *p = (struct tap_priv *)be->opaque; + struct tap_priv *p = NET_BE_PRIV(be); struct ngm_connect ngc; const char *value, *nodename; int sbsz; @@ -642,7 +644,7 @@ netmap_set_vnet_hdr_len(struct net_backend *be, int vnet_hdr_len) { int err; struct nmreq req; - struct netmap_priv *priv = (struct netmap_priv *)be->opaque; + struct netmap_priv *priv = NET_BE_PRIV(be); nmreq_init(&req, priv->ifname); req.nr_cmd = NETMAP_BDG_VNET_HDR; @@ -662,7 +664,7 @@ netmap_set_vnet_hdr_len(struct net_backend *be, int vnet_hdr_len) static int netmap_has_vnet_hdr_len(struct net_backend *be, unsigned vnet_hdr_len) { - int prev_hdr_len = be->be_vnet_hdr_len; + unsigned prev_hdr_len = be->be_vnet_hdr_len; int ret; if (vnet_hdr_len == prev_hdr_len) { @@ -688,8 +690,8 @@ netmap_get_cap(struct net_backend *be) } static int -netmap_set_cap(struct net_backend *be, uint64_t features, - unsigned vnet_hdr_len) +netmap_set_cap(struct net_backend *be, uint64_t features __unused, + unsigned vnet_hdr_len) { return (netmap_set_vnet_hdr_len(be, vnet_hdr_len)); @@ -697,9 +699,9 @@ netmap_set_cap(struct net_backend *be, uint64_t features, static int netmap_init(struct net_backend *be, const char *devname, - nvlist_t *nvl, net_be_rxeof_t cb, void *param) + nvlist_t *nvl __unused, net_be_rxeof_t cb, void *param) { - struct netmap_priv *priv = (struct netmap_priv *)be->opaque; + struct netmap_priv *priv = NET_BE_PRIV(be); strlcpy(priv->ifname, devname, sizeof(priv->ifname)); priv->ifname[sizeof(priv->ifname) - 1] = '\0'; @@ -708,7 +710,6 @@ netmap_init(struct net_backend *be, const char *devname, if (priv->nmd == NULL) { WPRINTF(("Unable to nm_open(): interface '%s', errno (%s)", devname, strerror(errno))); - free(priv); return (-1); } @@ -731,7 +732,7 @@ netmap_init(struct net_backend *be, const char *devname, static void netmap_cleanup(struct net_backend *be) { - struct netmap_priv *priv = (struct netmap_priv *)be->opaque; + struct netmap_priv *priv = NET_BE_PRIV(be); if (priv->mevp) { mevent_delete(priv->mevp); @@ -746,13 +747,13 @@ static ssize_t netmap_send(struct net_backend *be, const struct iovec *iov, int iovcnt) { - struct netmap_priv *priv = (struct netmap_priv *)be->opaque; + struct netmap_priv *priv = NET_BE_PRIV(be); struct netmap_ring *ring; ssize_t totlen = 0; int nm_buf_size; int nm_buf_len; uint32_t head; - void *nm_buf; + uint8_t *nm_buf; int j; ring = priv->tx; @@ -766,8 +767,8 @@ netmap_send(struct net_backend *be, const struct iovec *iov, nm_buf_len = 0; for (j = 0; j < iovcnt; j++) { + uint8_t *iov_frag_buf = iov[j].iov_base; int iov_frag_size = iov[j].iov_len; - void *iov_frag_buf = iov[j].iov_base; totlen += iov_frag_size; @@ -825,7 +826,7 @@ txsync: static ssize_t netmap_peek_recvlen(struct net_backend *be) { - struct netmap_priv *priv = (struct netmap_priv *)be->opaque; + struct netmap_priv *priv = NET_BE_PRIV(be); struct netmap_ring *ring = priv->rx; uint32_t head = ring->head; ssize_t totlen = 0; @@ -845,10 +846,10 @@ netmap_peek_recvlen(struct net_backend *be) static ssize_t netmap_recv(struct net_backend *be, const struct iovec *iov, int iovcnt) { - struct netmap_priv *priv = (struct netmap_priv *)be->opaque; + struct netmap_priv *priv = NET_BE_PRIV(be); struct netmap_slot *slot = NULL; struct netmap_ring *ring; - void *iov_frag_buf; + uint8_t *iov_frag_buf; int iov_frag_size; ssize_t totlen = 0; uint32_t head; @@ -861,8 +862,8 @@ netmap_recv(struct net_backend *be, const struct iovec *iov, int iovcnt) iov_frag_size = iov->iov_len; do { + uint8_t *nm_buf; int nm_buf_len; - void *nm_buf; if (head == ring->tail) { return (0); @@ -912,7 +913,7 @@ netmap_recv(struct net_backend *be, const struct iovec *iov, int iovcnt) static void netmap_recv_enable(struct net_backend *be) { - struct netmap_priv *priv = (struct netmap_priv *)be->opaque; + struct netmap_priv *priv = NET_BE_PRIV(be); mevent_enable(priv->mevp); } @@ -920,7 +921,7 @@ netmap_recv_enable(struct net_backend *be) static void netmap_recv_disable(struct net_backend *be) { - struct netmap_priv *priv = (struct netmap_priv *)be->opaque; + struct netmap_priv *priv = NET_BE_PRIV(be); mevent_disable(priv->mevp); } @@ -986,7 +987,7 @@ typedef struct be_dlpi_priv { static void be_dlpi_cleanup(net_backend_t *be) { - be_dlpi_priv_t *priv = (be_dlpi_priv_t *)be->opaque; + be_dlpi_priv_t *priv = NET_BE_PRIV(be); if (priv->bdp_dhp != NULL) dlpi_close(priv->bdp_dhp); @@ -1010,7 +1011,7 @@ static int be_dlpi_init(net_backend_t *be, const char *devname __unused, nvlist_t *nvl, net_be_rxeof_t cb, void *param) { - be_dlpi_priv_t *priv = (be_dlpi_priv_t *)be->opaque; + be_dlpi_priv_t *priv = NET_BE_PRIV(be); const char *vnic; int ret; @@ -1099,7 +1100,7 @@ error: static ssize_t be_dlpi_send(net_backend_t *be, const struct iovec *iov, int iovcnt) { - be_dlpi_priv_t *priv = (be_dlpi_priv_t *)be->opaque; + be_dlpi_priv_t *priv = NET_BE_PRIV(be); ssize_t len = 0; int ret; @@ -1128,7 +1129,7 @@ be_dlpi_send(net_backend_t *be, const struct iovec *iov, int iovcnt) static ssize_t be_dlpi_peek_recvlen(net_backend_t *be) { - be_dlpi_priv_t *priv = (be_dlpi_priv_t *)be->opaque; + be_dlpi_priv_t *priv = NET_BE_PRIV(be); dlpi_recvinfo_t recv; size_t len; int ret; @@ -1171,7 +1172,7 @@ be_dlpi_peek_recvlen(net_backend_t *be) static ssize_t be_dlpi_recv(net_backend_t *be, const struct iovec *iov, int iovcnt) { - be_dlpi_priv_t *priv = (be_dlpi_priv_t *)be->opaque; + be_dlpi_priv_t *priv = NET_BE_PRIV(be); size_t len; int ret; @@ -1208,7 +1209,7 @@ be_dlpi_recv(net_backend_t *be, const struct iovec *iov, int iovcnt) static void be_dlpi_recv_enable(net_backend_t *be) { - be_dlpi_priv_t *priv = (be_dlpi_priv_t *)be->opaque; + be_dlpi_priv_t *priv = NET_BE_PRIV(be); mevent_enable(priv->bdp_mevp); } @@ -1216,7 +1217,7 @@ be_dlpi_recv_enable(net_backend_t *be) static void be_dlpi_recv_disable(net_backend_t *be) { - be_dlpi_priv_t *priv = (be_dlpi_priv_t *)be->opaque; + be_dlpi_priv_t *priv = NET_BE_PRIV(be); mevent_disable(priv->bdp_mevp); } @@ -1237,7 +1238,7 @@ be_dlpi_set_cap(net_backend_t *be, uint64_t features, static int be_dlpi_get_mac(net_backend_t *be, void *buf, size_t *buflen) { - be_dlpi_priv_t *priv = (be_dlpi_priv_t *)be->opaque; + be_dlpi_priv_t *priv = NET_BE_PRIV(be); uchar_t physaddr[DLPI_PHYSADDR_MAX]; size_t physaddrlen = DLPI_PHYSADDR_MAX; int ret; @@ -1395,7 +1396,7 @@ netbe_init(struct net_backend **ret, nvlist_t *nvl, net_be_rxeof_t cb, return (EINVAL); } - nbe = calloc(1, sizeof(*nbe) + tbe->priv_size); + nbe = calloc(1, NET_BE_SIZE(tbe)); *nbe = *tbe; /* copy the template */ nbe->fd = -1; nbe->sc = param; diff --git a/usr/src/cmd/bhyve/pci_ahci.c b/usr/src/cmd/bhyve/pci_ahci.c index 2a4b97fbbf..e66945655a 100644 --- a/usr/src/cmd/bhyve/pci_ahci.c +++ b/usr/src/cmd/bhyve/pci_ahci.c @@ -612,8 +612,10 @@ ahci_build_iov(struct ahci_port *p, struct ahci_ioreq *aior, struct ahci_prdt_entry *prdt, uint16_t prdtl) { struct blockif_req *breq = &aior->io_req; - int i, j, skip, todo, left, extra; - uint32_t dbcsz; + uint32_t dbcsz, extra, left, skip, todo; + int i, j; + + assert(aior->len >= aior->done); /* Copy part of PRDT between 'done' and 'len' bytes into the iov. */ skip = aior->done; @@ -781,13 +783,14 @@ ahci_handle_flush(struct ahci_port *p, int slot, uint8_t *cfis) } static inline void -read_prdt(struct ahci_port *p, int slot, uint8_t *cfis, - void *buf, int size) +read_prdt(struct ahci_port *p, int slot, uint8_t *cfis, void *buf, + unsigned int size) { struct ahci_cmd_hdr *hdr; struct ahci_prdt_entry *prdt; - void *to; - int i, len; + uint8_t *to; + unsigned int len; + int i; hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); len = size; @@ -796,7 +799,7 @@ read_prdt(struct ahci_port *p, int slot, uint8_t *cfis, for (i = 0; i < hdr->prdtl && len; i++) { uint8_t *ptr; uint32_t dbcsz; - int sublen; + unsigned int sublen; dbcsz = (prdt->dbc & DBCMASK) + 1; ptr = paddr_guest2host(ahci_ctx(p->pr_sc), prdt->dba, dbcsz); @@ -895,13 +898,14 @@ next: } static inline void -write_prdt(struct ahci_port *p, int slot, uint8_t *cfis, - void *buf, int size) +write_prdt(struct ahci_port *p, int slot, uint8_t *cfis, void *buf, + unsigned int size) { struct ahci_cmd_hdr *hdr; struct ahci_prdt_entry *prdt; - void *from; - int i, len; + uint8_t *from; + unsigned int len; + int i; hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); len = size; @@ -1138,7 +1142,7 @@ atapi_inquiry(struct ahci_port *p, int slot, uint8_t *cfis) { uint8_t buf[36]; uint8_t *acmd; - int len; + unsigned int len; uint32_t tfd; acmd = cfis + 0x40; @@ -1200,7 +1204,7 @@ atapi_read_toc(struct ahci_port *p, int slot, uint8_t *cfis) { uint8_t *acmd; uint8_t format; - int len; + unsigned int len; acmd = cfis + 0x40; @@ -1209,7 +1213,8 @@ atapi_read_toc(struct ahci_port *p, int slot, uint8_t *cfis) switch (format) { case 0: { - int msf, size; + size_t size; + int msf; uint64_t sectors; uint8_t start_track, buf[20], *bp; @@ -1283,7 +1288,8 @@ atapi_read_toc(struct ahci_port *p, int slot, uint8_t *cfis) } case 2: { - int msf, size; + size_t size; + int msf; uint64_t sectors; uint8_t *bp, buf[50]; @@ -1445,7 +1451,7 @@ atapi_request_sense(struct ahci_port *p, int slot, uint8_t *cfis) { uint8_t buf[64]; uint8_t *acmd; - int len; + unsigned int len; acmd = cfis + 0x40; len = acmd[4]; @@ -1491,7 +1497,7 @@ atapi_mode_sense(struct ahci_port *p, int slot, uint8_t *cfis) uint8_t *acmd; uint32_t tfd = 0; uint8_t pc, code; - int len; + unsigned int len; acmd = cfis + 0x40; len = be16dec(acmd + 7); @@ -1576,7 +1582,7 @@ atapi_get_event_status_notification(struct ahci_port *p, int slot, tfd = (p->sense_key << 12) | ATA_S_READY | ATA_S_ERROR; } else { uint8_t buf[8]; - int len; + unsigned int len; len = be16dec(acmd + 7); if (len > sizeof(buf)) @@ -2186,8 +2192,9 @@ pci_ahci_host_write(struct pci_ahci_softc *sc, uint64_t offset, uint64_t value) } static void -pci_ahci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size, uint64_t value) +pci_ahci_write(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size, + uint64_t value) { struct pci_ahci_softc *sc = pi->pi_arg; @@ -2198,7 +2205,7 @@ pci_ahci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, if (offset < AHCI_OFFSET) pci_ahci_host_write(sc, offset, value); - else if (offset < AHCI_OFFSET + sc->ports * AHCI_STEP) + else if (offset < (uint64_t)AHCI_OFFSET + sc->ports * AHCI_STEP) pci_ahci_port_write(sc, offset, value); else WPRINTF("pci_ahci: unknown i/o write offset 0x%"PRIx64"", offset); @@ -2280,8 +2287,8 @@ pci_ahci_port_read(struct pci_ahci_softc *sc, uint64_t offset) } static uint64_t -pci_ahci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, - uint64_t regoff, int size) +pci_ahci_read(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t regoff, int size) { struct pci_ahci_softc *sc = pi->pi_arg; uint64_t offset; @@ -2296,7 +2303,7 @@ pci_ahci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, offset = regoff & ~0x3; /* round down to a multiple of 4 bytes */ if (offset < AHCI_OFFSET) value = pci_ahci_host_read(sc, offset); - else if (offset < AHCI_OFFSET + sc->ports * AHCI_STEP) + else if (offset < (uint64_t)AHCI_OFFSET + sc->ports * AHCI_STEP) value = pci_ahci_port_read(sc, offset); else { value = 0; @@ -2408,9 +2415,9 @@ pci_ahci_hd_legacy_config(nvlist_t *nvl, const char *opts) } static int -pci_ahci_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) +pci_ahci_init(struct vmctx *ctx __unused, struct pci_devinst *pi, nvlist_t *nvl) { - char bident[sizeof("XX:XX:XX")]; + char bident[sizeof("XXX:XXX:XXX")]; char node_name[sizeof("XX")]; struct blockif_ctxt *bctxt; struct pci_ahci_softc *sc; @@ -2457,7 +2464,7 @@ pci_ahci_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) * Attempt to open the backing image. Use the PCI slot/func * and the port number for the identifier string. */ - snprintf(bident, sizeof(bident), "%d:%d:%d", pi->pi_slot, + snprintf(bident, sizeof(bident), "%u:%u:%u", pi->pi_slot, pi->pi_func, p); bctxt = blockif_open(port_nvl, bident); diff --git a/usr/src/cmd/bhyve/pci_e82545.c b/usr/src/cmd/bhyve/pci_e82545.c index 363e203692..6a9ca2442d 100644 --- a/usr/src/cmd/bhyve/pci_e82545.c +++ b/usr/src/cmd/bhyve/pci_e82545.c @@ -363,7 +363,7 @@ static void e82545_tx_start(struct e82545_softc *sc); static void e82545_tx_enable(struct e82545_softc *sc); static void e82545_tx_disable(struct e82545_softc *sc); -static inline int +static inline int __unused e82545_size_stat_index(uint32_t size) { if (size <= 64) { @@ -406,15 +406,15 @@ e82545_init_eeprom(struct e82545_softc *sc) } static void -e82545_write_mdi(struct e82545_softc *sc, uint8_t reg_addr, - uint8_t phy_addr, uint32_t data) +e82545_write_mdi(struct e82545_softc *sc __unused, uint8_t reg_addr, + uint8_t phy_addr, uint32_t data) { DPRINTF("Write mdi reg:0x%x phy:0x%x data: 0x%x", reg_addr, phy_addr, data); } static uint32_t -e82545_read_mdi(struct e82545_softc *sc, uint8_t reg_addr, - uint8_t phy_addr) +e82545_read_mdi(struct e82545_softc *sc __unused, uint8_t reg_addr, + uint8_t phy_addr) { //DPRINTF("Read mdi reg:0x%x phy:0x%x", reg_addr, phy_addr); switch (reg_addr) { @@ -553,7 +553,7 @@ e82545_eecd_strobe(struct e82545_softc *sc) } static void -e82545_itr_callback(int fd, enum ev_type type, void *param) +e82545_itr_callback(int fd __unused, enum ev_type type __unused, void *param) { uint32_t new; struct e82545_softc *sc = param; @@ -829,12 +829,13 @@ e82545_bufsz(uint32_t rctl) /* XXX one packet at a time until this is debugged */ static void -e82545_rx_callback(int fd, enum ev_type type, void *param) +e82545_rx_callback(int fd __unused, enum ev_type type __unused, void *param) { struct e82545_softc *sc = param; struct e1000_rx_desc *rxd; struct iovec vec[64]; - int left, len, lim, maxpktsz, maxpktdesc, bufsz, i, n, size; + ssize_t len; + int left, lim, maxpktsz, maxpktdesc, bufsz, i, n, size; uint32_t cause = 0; uint16_t *tp, tag, head; @@ -876,7 +877,7 @@ e82545_rx_callback(int fd, enum ev_type type, void *param) } len = netbe_recv(sc->esc_be, vec, maxpktdesc); if (len <= 0) { - DPRINTF("netbe_recv() returned %d", len); + DPRINTF("netbe_recv() returned %zd", len); goto done; } @@ -891,7 +892,7 @@ e82545_rx_callback(int fd, enum ev_type type, void *param) len += ETHER_CRC_LEN; n = (len + bufsz - 1) / bufsz; - DPRINTF("packet read %d bytes, %d segs, head %d", + DPRINTF("packet read %zd bytes, %d segs, head %d", len, n, head); /* Apply VLAN filter. */ @@ -928,7 +929,7 @@ e82545_rx_callback(int fd, enum ev_type type, void *param) E1000_RXD_STAT_EOP | E1000_RXD_STAT_DD; /* Schedule receive interrupts. */ - if (len <= sc->esc_RSRPD) { + if ((uint32_t)len <= sc->esc_RSRPD) { cause |= E1000_ICR_SRPD | E1000_ICR_RXT0; } else { /* XXX: RDRT and RADV timers should be here. */ @@ -975,7 +976,7 @@ e82545_buf_checksum(uint8_t *buf, int len) uint32_t sum = 0; /* Checksum all the pairs of bytes first... */ - for (i = 0; i < (len & ~1U); i += 2) + for (i = 0; i < (len & ~1); i += 2) sum += *((u_int16_t *)(buf + i)); /* @@ -990,9 +991,10 @@ e82545_buf_checksum(uint8_t *buf, int len) } static uint16_t -e82545_iov_checksum(struct iovec *iov, int iovcnt, int off, int len) +e82545_iov_checksum(struct iovec *iov, int iovcnt, unsigned int off, + unsigned int len) { - int now, odd; + unsigned int now, odd; uint32_t sum = 0, s; /* Skip completely unneeded vectors. */ @@ -1006,11 +1008,7 @@ e82545_iov_checksum(struct iovec *iov, int iovcnt, int off, int len) odd = 0; while (len > 0 && iovcnt > 0) { now = MIN(len, iov->iov_len - off); -#ifdef __FreeBSD__ - s = e82545_buf_checksum(iov->iov_base + off, now); -#else s = e82545_buf_checksum((uint8_t *)iov->iov_base + off, now); -#endif sum += odd ? (s << 8) : s; odd ^= (now & 1); len -= now; @@ -1042,11 +1040,11 @@ static void e82545_transmit_checksum(struct iovec *iov, int iovcnt, struct ck_info *ck) { uint16_t cksum; - int cklen; + unsigned int cklen; DPRINTF("tx cksum: iovcnt/s/off/len %d/%d/%d/%d", iovcnt, ck->ck_start, ck->ck_off, ck->ck_len); - cklen = ck->ck_len ? ck->ck_len - ck->ck_start + 1 : INT_MAX; + cklen = ck->ck_len ? ck->ck_len - ck->ck_start + 1U : UINT_MAX; cksum = e82545_iov_checksum(iov, iovcnt, ck->ck_start, cklen); *(uint16_t *)((uint8_t *)iov[0].iov_base + ck->ck_off) = ~cksum; } @@ -1087,9 +1085,8 @@ e82545_transmit(struct e82545_softc *sc, uint16_t head, uint16_t tail, struct ck_info ckinfo[2]; struct iovec *iov; union e1000_tx_udesc *dsc; - int desc, dtype, len, ntype, iovcnt, tcp, tso; - int mss, paylen, seg, tiovcnt, left, now, nleft, nnow, pv, pvoff; - unsigned hdrlen, vlen, pktlen; + int desc, dtype, ntype, iovcnt, tcp, tso, paylen, seg, tiovcnt, pv; + unsigned hdrlen, vlen, pktlen, len, left, mss, now, nnow, nleft, pvoff; uint32_t tcpsum, tcpseq; uint16_t ipcs, tcpcs, ipid, ohead; bool invalid; @@ -1233,9 +1230,9 @@ e82545_transmit(struct e82545_softc *sc, uint16_t head, uint16_t tail, if (!tso) { /* Estimate required writable space for checksums. */ if (ckinfo[0].ck_valid) - hdrlen = MAX(hdrlen, ckinfo[0].ck_off + 2); + hdrlen = MAX(hdrlen, ckinfo[0].ck_off + 2U); if (ckinfo[1].ck_valid) - hdrlen = MAX(hdrlen, ckinfo[1].ck_off + 2); + hdrlen = MAX(hdrlen, ckinfo[1].ck_off + 2U); /* Round up writable space to the first vector. */ if (hdrlen != 0 && iov[0].iov_len > hdrlen && iov[0].iov_len < hdrlen + 100) @@ -1284,26 +1281,26 @@ e82545_transmit(struct e82545_softc *sc, uint16_t head, uint16_t tail, * TCP | flags | 13 | 1 * UDP | len | 4 | 4 */ - if (hdrlen < ckinfo[0].ck_start + 6 || - hdrlen < ckinfo[0].ck_off + 2) { + if (hdrlen < ckinfo[0].ck_start + 6U || + hdrlen < ckinfo[0].ck_off + 2U) { WPRINTF("TSO hdrlen too small for IP fields (%d) " "-- dropped", hdrlen); goto done; } if (sc->esc_txctx.cmd_and_length & E1000_TXD_CMD_TCP) { - if (hdrlen < ckinfo[1].ck_start + 14) { + if (hdrlen < ckinfo[1].ck_start + 14U) { WPRINTF("TSO hdrlen too small for TCP fields " "(%d) -- dropped", hdrlen); goto done; } } else { - if (hdrlen < ckinfo[1].ck_start + 8) { + if (hdrlen < ckinfo[1].ck_start + 8U) { WPRINTF("TSO hdrlen too small for UDP fields " "(%d) -- dropped", hdrlen); goto done; } } - if (ckinfo[1].ck_valid && hdrlen < ckinfo[1].ck_off + 2) { + if (ckinfo[1].ck_valid && hdrlen < ckinfo[1].ck_off + 2U) { WPRINTF("TSO hdrlen too small for TCP/UDP fields " "(%d) -- dropped", hdrlen); goto done; @@ -1328,7 +1325,21 @@ e82545_transmit(struct e82545_softc *sc, uint16_t head, uint16_t tail, left -= now, hdrp += now) { now = MIN(left, iov->iov_len); memcpy(hdrp, iov->iov_base, now); +#ifdef __FreeBSD__ + iov->iov_base = (uint8_t *)iov->iov_base + now; +#else + /* + * The type of iov_base changed in SUS (XPG4v2) from + * caddr_t (char * - note signed) to 'void *'. On + * illumos, bhyve is not currently compiled with XPG4v2 + * or higher, and so we can't cast the RHS to unsigned. + * error: pointer targets in assignment differ in + * signedness + * This also means that we need to apply some casts to + * (caddr_t) below. + */ iov->iov_base += now; +#endif iov->iov_len -= now; if (iov->iov_len == 0) { iov++; @@ -1387,7 +1398,7 @@ e82545_transmit(struct e82545_softc *sc, uint16_t head, uint16_t tail, tcp = (sc->esc_txctx.cmd_and_length & E1000_TXD_CMD_TCP) != 0; mss = sc->esc_txctx.tcp_seg_setup.fields.mss; paylen = (sc->esc_txctx.cmd_and_length & 0x000fffff); - DPRINTF("tx %s segmentation offload %d+%d/%d bytes %d iovs", + DPRINTF("tx %s segmentation offload %d+%d/%u bytes %d iovs", tcp ? "TCP" : "UDP", hdrlen, paylen, mss, iovcnt); ipid = ntohs(*(uint16_t *)&hdr[ckinfo[0].ck_start + 4]); tcpseq = 0; @@ -1414,7 +1425,12 @@ e82545_transmit(struct e82545_softc *sc, uint16_t head, uint16_t tail, /* Include respective part of payload IOV. */ for (nleft = now; pv < iovcnt && nleft > 0; nleft -= nnow) { nnow = MIN(nleft, iov[pv].iov_len - pvoff); - tiov[tiovcnt].iov_base = iov[pv].iov_base + pvoff; +#ifdef __FreeBSD__ + tiov[tiovcnt].iov_base = (uint8_t *)iov[pv].iov_base + + pvoff; +#else + tiov[tiovcnt].iov_base += pvoff; +#endif tiov[tiovcnt++].iov_len = nnow; if (pvoff + nnow == iov[pv].iov_len) { pv++; @@ -1486,9 +1502,12 @@ e82545_tx_run(struct e82545_softc *sc) uint16_t head, rhead, tail, size; int lim, tdwb, sent; - head = sc->esc_TDH; - tail = sc->esc_TDT; size = sc->esc_TDLEN / 16; + if (size == 0) + return; + + head = sc->esc_TDH % size; + tail = sc->esc_TDT % size; DPRINTF("tx_run: head %x, rhead %x, tail %x", sc->esc_TDH, sc->esc_TDHr, sc->esc_TDT); @@ -1754,12 +1773,17 @@ e82545_write_register(struct e82545_softc *sc, uint32_t offset, uint32_t value) e82545_tx_update_tdba(sc); break; case E1000_TDH(0): - //assert(!sc->esc_tx_enabled); - /* XXX should only ever be zero ? Range check ? */ + if (sc->esc_tx_enabled) { + WPRINTF("ignoring write to TDH while transmit enabled"); + break; + } + if (value != 0) { + WPRINTF("ignoring non-zero value written to TDH"); + break; + } sc->esc_TDHr = sc->esc_TDH = value; break; case E1000_TDT(0): - /* XXX range check ? */ sc->esc_TDT = value; if (sc->esc_tx_enabled) e82545_tx_start(sc); @@ -2122,8 +2146,9 @@ e82545_read_register(struct e82545_softc *sc, uint32_t offset) } static void -e82545_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, - uint64_t offset, int size, uint64_t value) +e82545_write(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size, + uint64_t value) { struct e82545_softc *sc; @@ -2172,8 +2197,8 @@ e82545_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, } static uint64_t -e82545_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, - uint64_t offset, int size) +e82545_read(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size) { struct e82545_softc *sc; uint64_t retval; diff --git a/usr/src/cmd/bhyve/pci_emul.c b/usr/src/cmd/bhyve/pci_emul.c index ccb1ce9c4d..b67b09a064 100644 --- a/usr/src/cmd/bhyve/pci_emul.c +++ b/usr/src/cmd/bhyve/pci_emul.c @@ -128,8 +128,9 @@ struct pci_bar_allocation { enum pcibar_type type; uint64_t size; }; -TAILQ_HEAD(pci_bar_list, pci_bar_allocation) pci_bars = TAILQ_HEAD_INITIALIZER( - pci_bars); + +static TAILQ_HEAD(pci_bar_list, pci_bar_allocation) pci_bars = + TAILQ_HEAD_INITIALIZER(pci_bars); #define PCI_EMUL_IOBASE 0x2000 #define PCI_EMUL_IOLIMIT 0x10000 @@ -151,7 +152,7 @@ SYSRES_MEM(PCI_EMUL_ECFG_BASE, PCI_EMUL_ECFG_SIZE); static struct pci_devemu *pci_emul_finddev(const char *name); static void pci_lintr_route(struct pci_devinst *pi); static void pci_lintr_update(struct pci_devinst *pi); -static void pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, +static void pci_cfgrw(struct vmctx *ctx, int in, int bus, int slot, int func, int coff, int bytes, uint32_t *val); static __inline void @@ -458,24 +459,27 @@ pci_msix_pba_bar(struct pci_devinst *pi) } static int -pci_emul_io_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +pci_emul_io_handler(struct vmctx *ctx, int in, int port, + int bytes, uint32_t *eax, void *arg) { struct pci_devinst *pdi = arg; struct pci_devemu *pe = pdi->pi_d; uint64_t offset; int i; + assert(port >= 0); + for (i = 0; i <= PCI_BARMAX; i++) { if (pdi->pi_bar[i].type == PCIBAR_IO && - port >= pdi->pi_bar[i].addr && - port + bytes <= pdi->pi_bar[i].addr + pdi->pi_bar[i].size) { + (uint64_t)port >= pdi->pi_bar[i].addr && + (uint64_t)port + bytes <= + pdi->pi_bar[i].addr + pdi->pi_bar[i].size) { offset = port - pdi->pi_bar[i].addr; if (in) - *eax = (*pe->pe_barread)(ctx, vcpu, pdi, i, + *eax = (*pe->pe_barread)(ctx, pdi, i, offset, bytes); else - (*pe->pe_barwrite)(ctx, vcpu, pdi, i, offset, + (*pe->pe_barwrite)(ctx, pdi, i, offset, bytes, *eax); return (0); } @@ -484,8 +488,8 @@ pci_emul_io_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, } static int -pci_emul_mem_handler(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, - int size, uint64_t *val, void *arg1, long arg2) +pci_emul_mem_handler(struct vmctx *ctx, int vcpu __unused, int dir, + uint64_t addr, int size, uint64_t *val, void *arg1, long arg2) { struct pci_devinst *pdi = arg1; struct pci_devemu *pe = pdi->pi_d; @@ -502,22 +506,22 @@ pci_emul_mem_handler(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, if (dir == MEM_F_WRITE) { if (size == 8) { - (*pe->pe_barwrite)(ctx, vcpu, pdi, bidx, offset, + (*pe->pe_barwrite)(ctx, pdi, bidx, offset, 4, *val & 0xffffffff); - (*pe->pe_barwrite)(ctx, vcpu, pdi, bidx, offset + 4, + (*pe->pe_barwrite)(ctx, pdi, bidx, offset + 4, 4, *val >> 32); } else { - (*pe->pe_barwrite)(ctx, vcpu, pdi, bidx, offset, + (*pe->pe_barwrite)(ctx, pdi, bidx, offset, size, *val); } } else { if (size == 8) { - *val = (*pe->pe_barread)(ctx, vcpu, pdi, bidx, + *val = (*pe->pe_barread)(ctx, pdi, bidx, offset, 4); - *val |= (*pe->pe_barread)(ctx, vcpu, pdi, bidx, + *val |= (*pe->pe_barread)(ctx, pdi, bidx, offset + 4, 4) << 32; } else { - *val = (*pe->pe_barread)(ctx, vcpu, pdi, bidx, + *val = (*pe->pe_barread)(ctx, pdi, bidx, offset, size); } } @@ -1177,9 +1181,9 @@ msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, pci_lintr_update(pi); } -void -pciecap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, - int bytes, uint32_t val) +static void +pciecap_cfgwrite(struct pci_devinst *pi, int capoff __unused, int offset, + int bytes, uint32_t val) { /* XXX don't write to the readonly parts */ @@ -1290,8 +1294,9 @@ pci_emul_iscap(struct pci_devinst *pi, int offset) } static int -pci_emul_fallback_handler(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, - int size, uint64_t *val, void *arg1, long arg2) +pci_emul_fallback_handler(struct vmctx *ctx __unused, int vcpu __unused, + int dir, uint64_t addr __unused, int size __unused, uint64_t *val, + void *arg1 __unused, long arg2 __unused) { /* * Ignore writes; return 0xff's for reads. The mem read code @@ -1305,8 +1310,9 @@ pci_emul_fallback_handler(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, } static int -pci_emul_ecfg_handler(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, - int bytes, uint64_t *val, void *arg1, long arg2) +pci_emul_ecfg_handler(struct vmctx *ctx, int vcpu __unused, int dir, + uint64_t addr, int bytes, uint64_t *val, void *arg1 __unused, + long arg2 __unused) { int bus, slot, func, coff, in; @@ -1317,7 +1323,7 @@ pci_emul_ecfg_handler(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, in = (dir == MEM_F_READ); if (in) *val = ~0UL; - pci_cfgrw(ctx, vcpu, in, bus, slot, func, coff, bytes, (uint32_t *)val); + pci_cfgrw(ctx, in, bus, slot, func, coff, bytes, (uint32_t *)val); return (0); } @@ -1502,8 +1508,8 @@ init_pci(struct vmctx *ctx) } static void -pci_apic_prt_entry(int bus, int slot, int pin, int pirq_pin, int ioapic_irq, - void *arg) +pci_apic_prt_entry(int bus __unused, int slot, int pin, int pirq_pin __unused, + int ioapic_irq, void *arg __unused) { dsdt_line(" Package ()"); @@ -1516,8 +1522,8 @@ pci_apic_prt_entry(int bus, int slot, int pin, int pirq_pin, int ioapic_irq, } static void -pci_pirq_prt_entry(int bus, int slot, int pin, int pirq_pin, int ioapic_irq, - void *arg) +pci_pirq_prt_entry(int bus __unused, int slot, int pin, int pirq_pin, + int ioapic_irq __unused, void *arg __unused) { char *name; @@ -2069,7 +2075,7 @@ pci_emul_cmdsts_write(struct pci_devinst *pi, int coff, uint32_t new, int bytes) } static void -pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func, +pci_cfgrw(struct vmctx *ctx, int in, int bus, int slot, int func, int coff, int bytes, uint32_t *eax) { struct businfo *bi; @@ -2124,8 +2130,7 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func, if (in) { /* Let the device emulation override the default handler */ if (pe->pe_cfgread != NULL) { - needcfg = pe->pe_cfgread(ctx, vcpu, pi, coff, bytes, - eax); + needcfg = pe->pe_cfgread(ctx, pi, coff, bytes, eax); } else { needcfg = 1; } @@ -2137,7 +2142,7 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func, } else { /* Let the device emulation override the default handler */ if (pe->pe_cfgwrite != NULL && - (*pe->pe_cfgwrite)(ctx, vcpu, pi, coff, bytes, *eax) == 0) + (*pe->pe_cfgwrite)(ctx, pi, coff, bytes, *eax) == 0) return; /* @@ -2234,8 +2239,8 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func, static int cfgenable, cfgbus, cfgslot, cfgfunc, cfgoff; static int -pci_emul_cfgaddr(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +pci_emul_cfgaddr(struct vmctx *ctx __unused, int in, + int port __unused, int bytes, uint32_t *eax, void *arg __unused) { uint32_t x; @@ -2264,8 +2269,8 @@ pci_emul_cfgaddr(struct vmctx *ctx, int vcpu, int in, int port, int bytes, INOUT_PORT(pci_cfgaddr, CONF1_ADDR_PORT, IOPORT_F_INOUT, pci_emul_cfgaddr); static int -pci_emul_cfgdata(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +pci_emul_cfgdata(struct vmctx *ctx, int in, int port, + int bytes, uint32_t *eax, void *arg __unused) { int coff; @@ -2273,7 +2278,7 @@ pci_emul_cfgdata(struct vmctx *ctx, int vcpu, int in, int port, int bytes, coff = cfgoff + (port - CONF1_DATA_PORT); if (cfgenable) { - pci_cfgrw(ctx, vcpu, in, cfgbus, cfgslot, cfgfunc, coff, bytes, + pci_cfgrw(ctx, in, cfgbus, cfgslot, cfgfunc, coff, bytes, eax); } else { /* Ignore accesses to cfgdata if not enabled by cfgaddr */ @@ -2304,7 +2309,8 @@ struct pci_emul_dsoftc { #define PCI_EMUL_MSIX_MSGS 16 static int -pci_emul_dinit(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) +pci_emul_dinit(struct vmctx *ctx __unused, struct pci_devinst *pi, + nvlist_t *nvl __unused) { int error; struct pci_emul_dsoftc *sc; @@ -2333,8 +2339,9 @@ pci_emul_dinit(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) } static void -pci_emul_diow(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, - uint64_t offset, int size, uint64_t value) +pci_emul_diow(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size, + uint64_t value) { int i; struct pci_emul_dsoftc *sc = pi->pi_arg; @@ -2400,8 +2407,8 @@ pci_emul_diow(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, } static uint64_t -pci_emul_dior(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, - uint64_t offset, int size) +pci_emul_dior(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size) { struct pci_emul_dsoftc *sc = pi->pi_arg; uint32_t value; diff --git a/usr/src/cmd/bhyve/pci_emul.h b/usr/src/cmd/bhyve/pci_emul.h index c19b6d2fac..f5a46da724 100644 --- a/usr/src/cmd/bhyve/pci_emul.h +++ b/usr/src/cmd/bhyve/pci_emul.h @@ -65,18 +65,18 @@ struct pci_devemu { void (*pe_write_dsdt)(struct pci_devinst *); /* config space read/write callbacks */ - int (*pe_cfgwrite)(struct vmctx *ctx, int vcpu, + int (*pe_cfgwrite)(struct vmctx *ctx, struct pci_devinst *pi, int offset, int bytes, uint32_t val); - int (*pe_cfgread)(struct vmctx *ctx, int vcpu, + int (*pe_cfgread)(struct vmctx *ctx, struct pci_devinst *pi, int offset, int bytes, uint32_t *retval); /* BAR read/write callbacks */ - void (*pe_barwrite)(struct vmctx *ctx, int vcpu, + void (*pe_barwrite)(struct vmctx *ctx, struct pci_devinst *pi, int baridx, uint64_t offset, int size, uint64_t value); - uint64_t (*pe_barread)(struct vmctx *ctx, int vcpu, + uint64_t (*pe_barread)(struct vmctx *ctx, struct pci_devinst *pi, int baridx, uint64_t offset, int size); diff --git a/usr/src/cmd/bhyve/pci_fbuf.c b/usr/src/cmd/bhyve/pci_fbuf.c index 35764f253f..5afcc5d0b0 100644 --- a/usr/src/cmd/bhyve/pci_fbuf.c +++ b/usr/src/cmd/bhyve/pci_fbuf.c @@ -121,8 +121,9 @@ static struct pci_fbuf_softc *fbuf_sc; #define PCI_FBUF_MSI_MSGS 4 static void -pci_fbuf_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size, uint64_t value) +pci_fbuf_write(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size, + uint64_t value) { struct pci_fbuf_softc *sc; uint8_t *p; @@ -175,8 +176,8 @@ pci_fbuf_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, } static uint64_t -pci_fbuf_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size) +pci_fbuf_read(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size) { struct pci_fbuf_softc *sc; uint8_t *p; diff --git a/usr/src/cmd/bhyve/pci_hda.c b/usr/src/cmd/bhyve/pci_hda.c index 1a2a3844ab..a85935a5ca 100644 --- a/usr/src/cmd/bhyve/pci_hda.c +++ b/usr/src/cmd/bhyve/pci_hda.c @@ -201,7 +201,7 @@ static int hda_signal_state_change(struct hda_codec_inst *hci); static int hda_response(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol); static int hda_transfer(struct hda_codec_inst *hci, uint8_t stream, - uint8_t dir, void *buf, size_t count); + uint8_t dir, uint8_t *buf, size_t count); static void hda_set_pib(struct hda_softc *sc, uint8_t stream_ind, uint32_t pib); static uint64_t hda_get_clock_ns(void); @@ -210,9 +210,9 @@ static uint64_t hda_get_clock_ns(void); * PCI HDA function declarations */ static int pci_hda_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl); -static void pci_hda_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, +static void pci_hda_write(struct vmctx *ctx, struct pci_devinst *pi, int baridx, uint64_t offset, int size, uint64_t value); -static uint64_t pci_hda_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, +static uint64_t pci_hda_read(struct vmctx *ctx, struct pci_devinst *pi, int baridx, uint64_t offset, int size); /* * HDA global data @@ -264,7 +264,7 @@ static const uint16_t hda_rirb_sizes[] = { [HDAC_RIRBSIZE_RIRBSIZE_MASK] = 0, }; -static struct hda_ops hops = { +static const struct hda_ops hops = { .signal = hda_signal_state_change, .response = hda_response, .transfer = hda_transfer, @@ -615,7 +615,6 @@ hda_stream_start(struct hda_softc *sc, uint8_t stream_ind) uint32_t sdctl = 0; uint8_t strm = 0; uint8_t dir = 0; - int i; assert(!st->run); @@ -640,7 +639,7 @@ hda_stream_start(struct hda_softc *sc, uint8_t stream_ind) st->bdl_cnt = bdl_cnt; bdle = (struct hda_bdle *)bdl_vaddr; - for (i = 0; i < bdl_cnt; i++, bdle++) { + for (size_t i = 0; i < bdl_cnt; i++, bdle++) { bdle_sz = bdle->len; assert(!(bdle_sz % HDA_DMA_ACCESS_LEN)); @@ -659,7 +658,7 @@ hda_stream_start(struct hda_softc *sc, uint8_t stream_ind) bdle_desc->len = bdle_sz; bdle_desc->ioc = bdle->ioc; - DPRINTF("bdle: 0x%x bdle_sz: 0x%x", i, bdle_sz); + DPRINTF("bdle: 0x%zx bdle_sz: 0x%x", i, bdle_sz); } sdctl = hda_get_reg_by_offset(sc, off + HDAC_SDCTL0); @@ -793,8 +792,8 @@ hda_corb_run(struct hda_softc *sc) corb->rp++; corb->rp %= corb->size; - verb = hda_dma_ld_dword(corb->dma_vaddr + \ - HDA_CORB_ENTRY_LEN * corb->rp); + verb = hda_dma_ld_dword((uint8_t *)corb->dma_vaddr + + HDA_CORB_ENTRY_LEN * corb->rp); err = hda_send_command(sc, verb); assert(!err); @@ -890,7 +889,7 @@ hda_get_offset_stream(uint8_t stream_ind) } static void -hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old) +hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old __unused) { uint32_t value = hda_get_reg_by_offset(sc, offset); @@ -913,7 +912,8 @@ hda_set_statests(struct hda_softc *sc, uint32_t offset, uint32_t old) } static void -hda_set_corbwp(struct hda_softc *sc, uint32_t offset, uint32_t old) +hda_set_corbwp(struct hda_softc *sc, uint32_t offset __unused, + uint32_t old __unused) { hda_corb_run(sc); } @@ -939,7 +939,7 @@ hda_set_corbctl(struct hda_softc *sc, uint32_t offset, uint32_t old) } static void -hda_set_rirbctl(struct hda_softc *sc, uint32_t offset, uint32_t old) +hda_set_rirbctl(struct hda_softc *sc, uint32_t offset, uint32_t old __unused) { uint32_t value = hda_get_reg_by_offset(sc, offset); int err; @@ -1025,7 +1025,7 @@ hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old) } static void -hda_set_sdctl2(struct hda_softc *sc, uint32_t offset, uint32_t old) +hda_set_sdctl2(struct hda_softc *sc, uint32_t offset, uint32_t old __unused) { uint32_t value = hda_get_reg_by_offset(sc, offset); @@ -1087,10 +1087,10 @@ hda_response(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol) rirb->wp++; rirb->wp %= rirb->size; - hda_dma_st_dword(rirb->dma_vaddr + HDA_RIRB_ENTRY_LEN * \ - rirb->wp, response); - hda_dma_st_dword(rirb->dma_vaddr + HDA_RIRB_ENTRY_LEN * \ - rirb->wp + 0x04, response_ex); + hda_dma_st_dword((uint8_t *)rirb->dma_vaddr + + HDA_RIRB_ENTRY_LEN * rirb->wp, response); + hda_dma_st_dword((uint8_t *)rirb->dma_vaddr + + HDA_RIRB_ENTRY_LEN * rirb->wp + 0x04, response_ex); hda_set_reg_by_offset(sc, HDAC_RIRBWP, rirb->wp); @@ -1106,7 +1106,7 @@ hda_response(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol) static int hda_transfer(struct hda_codec_inst *hci, uint8_t stream, uint8_t dir, - void *buf, size_t count) + uint8_t *buf, size_t count) { struct hda_softc *sc = NULL; struct hda_stream_desc *st = NULL; @@ -1160,11 +1160,11 @@ hda_transfer(struct hda_codec_inst *hci, uint8_t stream, uint8_t dir, bdle_desc = &bdl[st->be]; if (dir) - *(uint32_t *)buf = \ - hda_dma_ld_dword(bdle_desc->addr + st->bp); + *(uint32_t *)buf = hda_dma_ld_dword( + (uint8_t *)bdle_desc->addr + st->bp); else - hda_dma_st_dword(bdle_desc->addr + st->bp, - *(uint32_t *)buf); + hda_dma_st_dword((uint8_t *)bdle_desc->addr + + st->bp, *(uint32_t *)buf); buf += HDA_DMA_ACCESS_LEN; st->bp += HDA_DMA_ACCESS_LEN; @@ -1204,8 +1204,8 @@ hda_set_pib(struct hda_softc *sc, uint8_t stream_ind, uint32_t pib) /* LPIB Alias */ hda_set_reg_by_offset(sc, 0x2000 + off + HDAC_SDLPIB, pib); if (sc->dma_pib_vaddr) - *(uint32_t *)(sc->dma_pib_vaddr + stream_ind * \ - HDA_DMA_PIB_ENTRY_LEN) = pib; + *(uint32_t *)((uint8_t *)sc->dma_pib_vaddr + stream_ind * + HDA_DMA_PIB_ENTRY_LEN) = pib; } static uint64_t hda_get_clock_ns(void) @@ -1256,8 +1256,9 @@ pci_hda_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) } static void -pci_hda_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size, uint64_t value) +pci_hda_write(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size, + uint64_t value) { struct hda_softc *sc = pi->pi_arg; int err; @@ -1273,8 +1274,8 @@ pci_hda_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, } static uint64_t -pci_hda_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size) +pci_hda_read(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size) { struct hda_softc *sc = pi->pi_arg; uint64_t value = 0; diff --git a/usr/src/cmd/bhyve/pci_hda.h b/usr/src/cmd/bhyve/pci_hda.h index e868671921..a021aa9c28 100644 --- a/usr/src/cmd/bhyve/pci_hda.h +++ b/usr/src/cmd/bhyve/pci_hda.h @@ -65,7 +65,7 @@ struct hda_codec_inst { uint8_t cad; struct hda_codec_class *codec; struct hda_softc *hda; - struct hda_ops *hops; + const struct hda_ops *hops; void *priv; }; @@ -84,7 +84,7 @@ struct hda_ops { int (*response)(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol); int (*transfer)(struct hda_codec_inst *hci, uint8_t stream, - uint8_t dir, void *buf, size_t count); + uint8_t dir, uint8_t *buf, size_t count); }; #define HDA_EMUL_SET(x) DATA_SET(hda_codec_class_set, x); diff --git a/usr/src/cmd/bhyve/pci_hostbridge.c b/usr/src/cmd/bhyve/pci_hostbridge.c index db7690e4b6..4c70f4426a 100644 --- a/usr/src/cmd/bhyve/pci_hostbridge.c +++ b/usr/src/cmd/bhyve/pci_hostbridge.c @@ -63,7 +63,8 @@ static struct pci_hostbridge_model { #endif static int -pci_hostbridge_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) +pci_hostbridge_init(struct vmctx *ctx __unused, struct pci_devinst *pi, + nvlist_t *nvl) { const char *value; u_int vendor, device; @@ -147,9 +148,8 @@ pci_hostbridge_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) } static int -pci_amd_hostbridge_legacy_config(nvlist_t *nvl, const char *opts) +pci_amd_hostbridge_legacy_config(nvlist_t *nvl, const char *opts __unused) { - set_config_value_node(nvl, "vendor", "0x1022"); /* AMD */ set_config_value_node(nvl, "devid", "0x7432"); /* made up */ diff --git a/usr/src/cmd/bhyve/pci_irq.c b/usr/src/cmd/bhyve/pci_irq.c index 4ecb3eddb0..2ce962cdec 100644 --- a/usr/src/cmd/bhyve/pci_irq.c +++ b/usr/src/cmd/bhyve/pci_irq.c @@ -63,14 +63,16 @@ __FBSDID("$FreeBSD$"); /* IRQ count to disable an IRQ. */ #define IRQ_DISABLED 0xff +#define NPIRQS 8 static struct pirq { uint8_t reg; int use_count; int active_count; pthread_mutex_t lock; -} pirqs[8]; +} pirqs[NPIRQS]; -static u_char irq_counts[16]; +#define NIRQ_COUNTS 16 +static u_char irq_counts[NIRQ_COUNTS]; static int pirq_cold = 1; /* @@ -91,7 +93,7 @@ uint8_t pirq_read(int pin) { - assert(pin > 0 && pin <= nitems(pirqs)); + assert(pin > 0 && pin <= NPIRQS); return (pirqs[pin - 1].reg); } @@ -100,7 +102,7 @@ pirq_write(struct vmctx *ctx, int pin, uint8_t val) { struct pirq *pirq; - assert(pin > 0 && pin <= nitems(pirqs)); + assert(pin > 0 && pin <= NPIRQS); pirq = &pirqs[pin - 1]; pthread_mutex_lock(&pirq->lock); if (pirq->reg != (val & (PIRQ_DIS | PIRQ_IRQ))) { @@ -117,7 +119,7 @@ void pci_irq_reserve(int irq) { - assert(irq >= 0 && irq < nitems(irq_counts)); + assert(irq >= 0 && irq < NIRQ_COUNTS); assert(pirq_cold); assert(irq_counts[irq] == 0 || irq_counts[irq] == IRQ_DISABLED); irq_counts[irq] = IRQ_DISABLED; @@ -127,24 +129,24 @@ void pci_irq_use(int irq) { - assert(irq >= 0 && irq < nitems(irq_counts)); + assert(irq >= 0 && irq < NIRQ_COUNTS); assert(pirq_cold); assert(irq_counts[irq] != IRQ_DISABLED); irq_counts[irq]++; } void -pci_irq_init(struct vmctx *ctx) +pci_irq_init(struct vmctx *ctx __unused) { int i; - for (i = 0; i < nitems(pirqs); i++) { + for (i = 0; i < NPIRQS; i++) { pirqs[i].reg = PIRQ_DIS; pirqs[i].use_count = 0; pirqs[i].active_count = 0; pthread_mutex_init(&pirqs[i].lock, NULL); } - for (i = 0; i < nitems(irq_counts); i++) { + for (i = 0; i < NIRQ_COUNTS; i++) { if (IRQ_PERMITTED(i)) irq_counts[i] = 0; else @@ -156,10 +158,12 @@ void pci_irq_assert(struct pci_devinst *pi) { struct pirq *pirq; + int pin; - if (pi->pi_lintr.pirq_pin > 0) { - assert(pi->pi_lintr.pirq_pin <= nitems(pirqs)); - pirq = &pirqs[pi->pi_lintr.pirq_pin - 1]; + pin = pi->pi_lintr.pirq_pin; + if (pin > 0) { + assert(pin <= NPIRQS); + pirq = &pirqs[pin - 1]; pthread_mutex_lock(&pirq->lock); pirq->active_count++; if (pirq->active_count == 1 && pirq_valid_irq(pirq->reg)) { @@ -177,10 +181,12 @@ void pci_irq_deassert(struct pci_devinst *pi) { struct pirq *pirq; + int pin; - if (pi->pi_lintr.pirq_pin > 0) { - assert(pi->pi_lintr.pirq_pin <= nitems(pirqs)); - pirq = &pirqs[pi->pi_lintr.pirq_pin - 1]; + pin = pi->pi_lintr.pirq_pin; + if (pin > 0) { + assert(pin <= NPIRQS); + pirq = &pirqs[pin - 1]; pthread_mutex_lock(&pirq->lock); pirq->active_count--; if (pirq->active_count == 0 && pirq_valid_irq(pirq->reg)) { @@ -209,7 +215,7 @@ pirq_alloc_pin(struct pci_devinst *pi) /* Find the least-used PIRQ pin. */ best_pin = 0; best_count = pirqs[0].use_count; - for (pin = 1; pin < nitems(pirqs); pin++) { + for (pin = 1; pin < NPIRQS; pin++) { if (pirqs[pin].use_count < best_count) { best_pin = pin; best_count = pirqs[pin].use_count; @@ -222,7 +228,7 @@ pirq_alloc_pin(struct pci_devinst *pi) if (pirqs[best_pin].reg == PIRQ_DIS) { best_irq = -1; best_count = 0; - for (irq = 0; irq < nitems(irq_counts); irq++) { + for (irq = 0; irq < NIRQ_COUNTS; irq++) { if (irq_counts[irq] == IRQ_DISABLED) continue; if (best_irq == -1 || irq_counts[irq] < best_count) { @@ -242,7 +248,7 @@ pirq_alloc_pin(struct pci_devinst *pi) int pirq_irq(int pin) { - assert(pin > 0 && pin <= nitems(pirqs)); + assert(pin > 0 && pin <= NPIRQS); return (pirqs[pin - 1].reg & PIRQ_IRQ); } @@ -255,7 +261,7 @@ pirq_dsdt(void) int irq, pin; irq_prs = NULL; - for (irq = 0; irq < nitems(irq_counts); irq++) { + for (irq = 0; irq < NIRQ_COUNTS; irq++) { if (!IRQ_PERMITTED(irq)) continue; if (irq_prs == NULL) @@ -294,7 +300,7 @@ pirq_dsdt(void) dsdt_line(" Return (0x01)"); dsdt_line("}"); - for (pin = 0; pin < nitems(pirqs); pin++) { + for (pin = 0; pin < NPIRQS; pin++) { dsdt_line(""); dsdt_line("Device (LNK%c)", 'A' + pin); dsdt_line("{"); diff --git a/usr/src/cmd/bhyve/pci_lpc.c b/usr/src/cmd/bhyve/pci_lpc.c index 2702e0fdca..8dbdbe3d10 100644 --- a/usr/src/cmd/bhyve/pci_lpc.c +++ b/usr/src/cmd/bhyve/pci_lpc.c @@ -174,7 +174,7 @@ lpc_uart_intr_assert(void *arg) } static void -lpc_uart_intr_deassert(void *arg) +lpc_uart_intr_deassert(void *arg __unused) { /* * The COM devices on the LPC bus generate edge triggered interrupts, @@ -183,8 +183,8 @@ lpc_uart_intr_deassert(void *arg) } static int -lpc_uart_io_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +lpc_uart_io_handler(struct vmctx *ctx __unused, int in, + int port, int bytes, uint32_t *eax, void *arg) { int offset; struct lpc_uart_softc *sc = arg; @@ -424,8 +424,8 @@ pci_lpc_uart_dsdt(void) LPC_DSDT(pci_lpc_uart_dsdt); static int -pci_lpc_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int coff, int bytes, uint32_t val) +pci_lpc_cfgwrite(struct vmctx *ctx, struct pci_devinst *pi, + int coff, int bytes, uint32_t val) { int pirq_pin; @@ -445,14 +445,16 @@ pci_lpc_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, } static void -pci_lpc_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size, uint64_t value) +pci_lpc_write(struct vmctx *ctx __unused, + struct pci_devinst *pi __unused, int baridx __unused, + uint64_t offset __unused, int size __unused, uint64_t value __unused) { } static uint64_t -pci_lpc_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size) +pci_lpc_read(struct vmctx *ctx __unused, + struct pci_devinst *pi __unused, int baridx __unused, uint64_t offset __unused, + int size __unused) { return (0); } @@ -461,9 +463,8 @@ pci_lpc_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, #define LPC_VENDOR 0x8086 static int -pci_lpc_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) +pci_lpc_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl __unused) { - /* * Do not allow more than one LPC bridge to be configured. */ diff --git a/usr/src/cmd/bhyve/pci_nvme.c b/usr/src/cmd/bhyve/pci_nvme.c index 717d400bc0..b9d8873a87 100644 --- a/usr/src/cmd/bhyve/pci_nvme.c +++ b/usr/src/cmd/bhyve/pci_nvme.c @@ -691,6 +691,7 @@ pci_nvme_init_nsdata(struct pci_nvme_softc *sc, static void pci_nvme_init_logpages(struct pci_nvme_softc *sc) { + __uint128_t power_cycles = 1; memset(&sc->err_log, 0, sizeof(sc->err_log)); memset(&sc->health_log, 0, sizeof(sc->health_log)); @@ -710,6 +711,9 @@ pci_nvme_init_logpages(struct pci_nvme_softc *sc) sc->fw_log.afi = (1 << NVME_FIRMWARE_PAGE_AFI_SLOT_SHIFT); memcpy(&sc->fw_log.revision[0], sc->ctrldata.fr, sizeof(sc->fw_log.revision[0])); + + memcpy(&sc->health_log.power_cycles, &power_cycles, + sizeof(sc->health_log.power_cycles)); } static void @@ -797,7 +801,7 @@ pci_nvme_aer_limit_reached(struct pci_nvme_softc *sc) struct nvme_controller_data *cd = &sc->ctrldata; /* AERL is a zero based value while aer_count is one's based */ - return (sc->aer_count == (cd->aerl + 1)); + return (sc->aer_count == (cd->aerl + 1U)); } /* @@ -972,6 +976,7 @@ pci_nvme_aen_process(struct pci_nvme_softc *sc) EPRINTLN("%s unknown AEN notice type %u", __func__, aen->event_data); status = NVME_SC_INTERNAL_DEVICE_ERROR; + lid = 0; break; } if ((PCI_NVME_AEI_NOTICE_MASK(aen->event_data) & mask) == 0) @@ -1006,6 +1011,7 @@ pci_nvme_aen_process(struct pci_nvme_softc *sc) /* bad type?!? */ EPRINTLN("%s unknown AEN type %u", __func__, atype); status = NVME_SC_INTERNAL_DEVICE_ERROR; + lid = 0; break; } @@ -1532,13 +1538,10 @@ nvme_opc_identify(struct pci_nvme_softc* sc, struct nvme_command* command, void *dest; uint16_t status; -#ifndef __FreeBSD__ - status = 0; -#endif - DPRINTF("%s identify 0x%x nsid 0x%x", __func__, command->cdw10 & 0xFF, command->nsid); + status = 0; pci_nvme_status_genc(&status, NVME_SC_SUCCESS); switch (command->cdw10 & 0xFF) { @@ -1767,6 +1770,7 @@ nvme_feature_temperature(struct pci_nvme_softc *sc, uint8_t tmpsel; /* Threshold Temperature Select */ uint8_t thsel; /* Threshold Type Select */ bool set_crit = false; + bool report_crit; tmpth = command->cdw11 & 0xffff; tmpsel = (command->cdw11 >> 16) & 0xf; @@ -1794,11 +1798,13 @@ nvme_feature_temperature(struct pci_nvme_softc *sc, ~NVME_CRIT_WARN_ST_TEMPERATURE; pthread_mutex_unlock(&sc->mtx); - if (set_crit) + report_crit = sc->feat[NVME_FEAT_ASYNC_EVENT_CONFIGURATION].cdw11 & + NVME_CRIT_WARN_ST_TEMPERATURE; + + if (set_crit && report_crit) pci_nvme_aen_post(sc, PCI_NVME_AE_TYPE_SMART, sc->health_log.critical_warning); - DPRINTF("%s: set_crit=%c critical_warning=%#x status=%#x", __func__, set_crit ? 'T':'F', sc->health_log.critical_warning, compl->status); } @@ -1858,7 +1864,8 @@ nvme_opc_set_features(struct pci_nvme_softc *sc, struct nvme_command *command, { struct nvme_feature_obj *feat; uint32_t nsid = command->nsid; - uint8_t fid = command->cdw10 & 0xFF; + uint8_t fid = NVMEV(NVME_FEAT_SET_FID, command->cdw10); + bool sv = NVMEV(NVME_FEAT_SET_SV, command->cdw10); DPRINTF("%s: Feature ID 0x%x (%s)", __func__, fid, nvme_fid_to_name(fid)); @@ -1867,6 +1874,13 @@ nvme_opc_set_features(struct pci_nvme_softc *sc, struct nvme_command *command, pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD); return (1); } + + if (sv) { + pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC, + NVME_SC_FEATURE_NOT_SAVEABLE); + return (1); + } + feat = &sc->feat[fid]; if (feat->namespace_specific && (nsid == NVME_GLOBAL_NAMESPACE_TAG)) { @@ -1886,6 +1900,11 @@ nvme_opc_set_features(struct pci_nvme_softc *sc, struct nvme_command *command, if (feat->set) feat->set(sc, feat, command, compl); + else { + pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC, + NVME_SC_FEATURE_NOT_CHANGEABLE); + return (1); + } DPRINTF("%s: status=%#x cdw11=%#x", __func__, compl->status, command->cdw11); if (compl->status == NVME_SC_SUCCESS) { @@ -2231,8 +2250,8 @@ pci_nvme_out_of_range(struct pci_nvme_blockstore *nvstore, uint64_t slba, } static int -pci_nvme_append_iov_req(struct pci_nvme_softc *sc, struct pci_nvme_ioreq *req, - uint64_t gpaddr, size_t size, int do_write, uint64_t offset) +pci_nvme_append_iov_req(struct pci_nvme_softc *sc __unused, + struct pci_nvme_ioreq *req, uint64_t gpaddr, size_t size, uint64_t offset) { int iovidx; bool range_is_contiguous; @@ -2372,14 +2391,11 @@ pci_nvme_io_done(struct blockif_req *br, int err) struct nvme_submission_queue *sq = req->nvme_sq; uint16_t code, status; -#ifndef __FreeBSD__ - status = 0; -#endif - DPRINTF("%s error %d %s", __func__, err, strerror(err)); /* TODO return correct error */ code = err ? NVME_SC_DATA_TRANSFER_ERROR : NVME_SC_SUCCESS; + status = 0; pci_nvme_status_genc(&status, code); pci_nvme_set_completion(req->sc, sq, req->sqid, req->cid, status); @@ -2439,15 +2455,12 @@ nvme_write_read_ram(struct pci_nvme_softc *sc, enum nvme_copy_dir dir; uint16_t status; -#ifndef __FreeBSD__ - status = 0; -#endif - if (is_write) dir = NVME_COPY_TO_PRP; else dir = NVME_COPY_FROM_PRP; + status = 0; if (nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, prp1, prp2, buf + offset, bytes, dir)) pci_nvme_status_genc(&status, @@ -2471,8 +2484,7 @@ nvme_write_read_blockif(struct pci_nvme_softc *sc, uint16_t status = NVME_NO_STATUS; size = MIN(PAGE_SIZE - (prp1 % PAGE_SIZE), bytes); - if (pci_nvme_append_iov_req(sc, req, prp1, - size, is_write, offset)) { + if (pci_nvme_append_iov_req(sc, req, prp1, size, offset)) { err = -1; goto out; } @@ -2484,8 +2496,7 @@ nvme_write_read_blockif(struct pci_nvme_softc *sc, ; } else if (bytes <= PAGE_SIZE) { size = bytes; - if (pci_nvme_append_iov_req(sc, req, prp2, - size, is_write, offset)) { + if (pci_nvme_append_iov_req(sc, req, prp2, size, offset)) { err = -1; goto out; } @@ -2511,8 +2522,8 @@ nvme_write_read_blockif(struct pci_nvme_softc *sc, size = MIN(bytes, PAGE_SIZE); - if (pci_nvme_append_iov_req(sc, req, *prp_list, - size, is_write, offset)) { + if (pci_nvme_append_iov_req(sc, req, *prp_list, size, + offset)) { err = -1; goto out; } @@ -2597,10 +2608,7 @@ pci_nvme_dealloc_sm(struct blockif_req *br, int err) bool done = true; uint16_t status; -#ifndef __FreeBSD__ status = 0; -#endif - if (err) { pci_nvme_status_genc(&status, NVME_SC_INTERNAL_DEVICE_ERROR); } else if ((req->prev_gpaddr + 1) == (req->prev_size)) { @@ -2648,7 +2656,13 @@ nvme_opc_dataset_mgmt(struct pci_nvme_softc *sc, nr = cmd->cdw10 & 0xff; /* copy locally because a range entry could straddle PRPs */ +#ifdef __FreeBSD__ range = calloc(1, NVME_MAX_DSM_TRIM); +#else + _Static_assert(NVME_MAX_DSM_TRIM % sizeof(struct nvme_dsm_range) == 0, + "NVME_MAX_DSM_TRIM is not a multiple of struct size"); + range = calloc(NVME_MAX_DSM_TRIM / sizeof (*range), sizeof (*range)); +#endif if (range == NULL) { pci_nvme_status_genc(status, NVME_SC_INTERNAL_DEVICE_ERROR); goto out; @@ -2754,10 +2768,6 @@ pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint16_t idx) uint16_t status; uint16_t sqhead; -#ifndef __FreeBSD__ - status = 0; -#endif - /* handle all submissions up to sq->tail index */ sq = &sc->submit_queues[idx]; @@ -2841,7 +2851,7 @@ complete: } static void -pci_nvme_handle_doorbell(struct vmctx *ctx __unused, struct pci_nvme_softc* sc, +pci_nvme_handle_doorbell(struct pci_nvme_softc* sc, uint64_t idx, int is_sq, uint64_t value) { DPRINTF("nvme doorbell %lu, %s, val 0x%lx", @@ -2964,7 +2974,7 @@ pci_nvme_write_bar_0(struct vmctx *ctx, struct pci_nvme_softc* sc, } else if (sc->compl_queues[idx].qbase == NULL) return; - pci_nvme_handle_doorbell(ctx, sc, idx, is_sq, value); + pci_nvme_handle_doorbell(sc, idx, is_sq, value); return; } @@ -3067,7 +3077,7 @@ pci_nvme_write_bar_0(struct vmctx *ctx, struct pci_nvme_softc* sc, } static void -pci_nvme_write(struct vmctx *ctx, int vcpu __unused, struct pci_devinst *pi, +pci_nvme_write(struct vmctx *ctx, struct pci_devinst *pi, int baridx, uint64_t offset, int size, uint64_t value) { struct pci_nvme_softc* sc = pi->pi_arg; @@ -3130,7 +3140,7 @@ static uint64_t pci_nvme_read_bar_0(struct pci_nvme_softc* sc, static uint64_t -pci_nvme_read(struct vmctx *ctx __unused, int vcpu __unused, +pci_nvme_read(struct vmctx *ctx __unused, struct pci_devinst *pi, int baridx, uint64_t offset, int size) { struct pci_nvme_softc* sc = pi->pi_arg; @@ -3157,7 +3167,7 @@ pci_nvme_read(struct vmctx *ctx __unused, int vcpu __unused, static int pci_nvme_parse_config(struct pci_nvme_softc *sc, nvlist_t *nvl) { - char bident[sizeof("XX:X:X")]; + char bident[sizeof("XXX:XXX")]; const char *value; uint32_t sectsz; @@ -3168,8 +3178,13 @@ pci_nvme_parse_config(struct pci_nvme_softc *sc, nvlist_t *nvl) sc->num_cqueues = sc->max_queues; sc->dataset_management = NVME_DATASET_MANAGEMENT_AUTO; sectsz = 0; +#ifdef __FreeBSD__ snprintf(sc->ctrldata.sn, sizeof(sc->ctrldata.sn), "NVME-%d-%d", sc->nsc_pi->pi_slot, sc->nsc_pi->pi_func); +#else + snprintf((char *)sc->ctrldata.sn, sizeof(sc->ctrldata.sn), + "NVME-%d-%d", sc->nsc_pi->pi_slot, sc->nsc_pi->pi_func); +#endif value = get_config_value_node(nvl, "maxq"); if (value != NULL) @@ -3231,7 +3246,7 @@ pci_nvme_parse_config(struct pci_nvme_softc *sc, nvlist_t *nvl) return (-1); } } else { - snprintf(bident, sizeof(bident), "%d:%d", + snprintf(bident, sizeof(bident), "%u:%u", sc->nsc_pi->pi_slot, sc->nsc_pi->pi_func); sc->nvstore.ctx = blockif_open(nvl, bident); if (sc->nvstore.ctx == NULL) { @@ -3248,7 +3263,7 @@ pci_nvme_parse_config(struct pci_nvme_softc *sc, nvlist_t *nvl) else if (sc->nvstore.type != NVME_STOR_RAM) sc->nvstore.sectsz = blockif_sectsz(sc->nvstore.ctx); for (sc->nvstore.sectsz_bits = 9; - (1 << sc->nvstore.sectsz_bits) < sc->nvstore.sectsz; + (1U << sc->nvstore.sectsz_bits) < sc->nvstore.sectsz; sc->nvstore.sectsz_bits++); if (sc->max_queues <= 0 || sc->max_queues > NVME_QUEUES) @@ -3301,7 +3316,7 @@ pci_nvme_init(struct vmctx *ctx __unused, struct pci_devinst *pi, nvlist_t *nvl) STAILQ_INIT(&sc->ioreqs_free); sc->ioreqs = calloc(sc->ioslots, sizeof(struct pci_nvme_ioreq)); - for (int i = 0; i < sc->ioslots; i++) { + for (uint32_t i = 0; i < sc->ioslots; i++) { STAILQ_INSERT_TAIL(&sc->ioreqs_free, &sc->ioreqs[i], link); } diff --git a/usr/src/cmd/bhyve/pci_passthru.c b/usr/src/cmd/bhyve/pci_passthru.c index 8b5f3d05ab..8506b1884a 100644 --- a/usr/src/cmd/bhyve/pci_passthru.c +++ b/usr/src/cmd/bhyve/pci_passthru.c @@ -200,7 +200,7 @@ passthru_dev_open(const char *path, int *pptfdp) static int passthru_add_msicap(struct pci_devinst *pi, int msgnum, int nextptr) { - int capoff, i; + int capoff; struct msicap msicap; u_char *capdata; @@ -214,7 +214,7 @@ passthru_add_msicap(struct pci_devinst *pi, int msgnum, int nextptr) */ capoff = 256 - roundup(sizeof(msicap), 4); capdata = (u_char *)&msicap; - for (i = 0; i < sizeof(msicap); i++) + for (size_t i = 0; i < sizeof(msicap); i++) pci_set_cfgdata8(pi, capoff + i, capdata[i]); return (capoff); @@ -264,7 +264,7 @@ cfginitmsi(struct passthru_softc *sc) uint32_t u32; struct pci_devinst *pi = sc->psc_pi; struct msixcap msixcap; - uint32_t *msixcap_ptr; + char *msixcap_ptr; /* * Parse the capabilities and cache the location of the MSI @@ -299,16 +299,16 @@ cfginitmsi(struct passthru_softc *sc) */ sc->psc_msix.capoff = ptr; caplen = 12; - msixcap_ptr = (uint32_t*) &msixcap; + msixcap_ptr = (char *)&msixcap; capptr = ptr; while (caplen > 0) { u32 = passthru_read_config(sc, capptr, 4); - *msixcap_ptr = u32; + memcpy(msixcap_ptr, &u32, 4); pci_set_cfgdata32(pi, capptr, u32); caplen -= 4; capptr += 4; - msixcap_ptr++; + msixcap_ptr += 4; } } ptr = passthru_read_config(sc, ptr + PCICAP_NEXTPTR, 1); @@ -439,7 +439,7 @@ msix_table_read(struct passthru_softc *sc, uint64_t offset, int size) } static void -msix_table_write(struct vmctx *ctx, int vcpu, struct passthru_softc *sc, +msix_table_write(struct vmctx *ctx, struct passthru_softc *sc, uint64_t offset, int size, uint64_t data) { struct pci_devinst *pi; @@ -491,14 +491,14 @@ msix_table_write(struct vmctx *ctx, int vcpu, struct passthru_softc *sc, assert(entry_offset % 4 == 0); vector_control = entry->vector_control; - dest32 = (uint32_t *)((void *)entry + entry_offset); + dest32 = (uint32_t *)((uint8_t *)entry + entry_offset); *dest32 = data; /* If MSI-X hasn't been enabled, do nothing */ if (pi->pi_msix.enabled) { /* If the entry is masked, don't set it up */ if ((entry->vector_control & PCIM_MSIX_VCTRL_MASK) == 0 || (vector_control & PCIM_MSIX_VCTRL_MASK) == 0) { - (void) vm_setup_pptdev_msix(ctx, vcpu, sc->pptfd, + (void) vm_setup_pptdev_msix(ctx, 0, sc->pptfd, index, entry->addr, entry->msg_data, entry->vector_control); } @@ -506,7 +506,7 @@ msix_table_write(struct vmctx *ctx, int vcpu, struct passthru_softc *sc, } static int -init_msix_table(struct vmctx *ctx, struct passthru_softc *sc) +init_msix_table(struct vmctx *ctx __unused, struct passthru_softc *sc) { struct pci_devinst *pi = sc->psc_pi; uint32_t table_size, table_offset; @@ -569,7 +569,7 @@ init_msix_table(struct vmctx *ctx, struct passthru_softc *sc) } static int -cfginitbar(struct vmctx *ctx, struct passthru_softc *sc) +cfginitbar(struct vmctx *ctx __unused, struct passthru_softc *sc) { struct pci_devinst *pi = sc->psc_pi; uint_t i; @@ -693,8 +693,8 @@ passthru_legacy_config(nvlist_t *nvl, const char *opt) } static int -passthru_init_rom(struct vmctx *const ctx, struct passthru_softc *const sc, - const char *const romfile) +passthru_init_rom(struct vmctx *const ctx __unused, + struct passthru_softc *const sc, const char *const romfile) { if (romfile == NULL) { return (0); @@ -837,8 +837,8 @@ msixcap_access(struct passthru_softc *sc, int coff) } static int -passthru_cfgread(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int coff, int bytes, uint32_t *rv) +passthru_cfgread(struct vmctx *ctx __unused, struct pci_devinst *pi, int coff, + int bytes, uint32_t *rv) { struct passthru_softc *sc; @@ -889,8 +889,8 @@ passthru_cfgread(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, } static int -passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int coff, int bytes, uint32_t val) +passthru_cfgwrite(struct vmctx *ctx, struct pci_devinst *pi, int coff, + int bytes, uint32_t val) { int error, msix_table_entries, i; struct passthru_softc *sc; @@ -910,7 +910,7 @@ passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, if (msicap_access(sc, coff)) { pci_emul_capwrite(pi, coff, bytes, val, sc->psc_msi.capoff, PCIY_MSI); - error = vm_setup_pptdev_msi(ctx, vcpu, sc->pptfd, + error = vm_setup_pptdev_msi(ctx, 0, sc->pptfd, pi->pi_msi.addr, pi->pi_msi.msg_data, pi->pi_msi.maxmsgnum); if (error != 0) err(1, "vm_setup_pptdev_msi"); @@ -923,7 +923,7 @@ passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, if (pi->pi_msix.enabled) { msix_table_entries = pi->pi_msix.table_count; for (i = 0; i < msix_table_entries; i++) { - error = vm_setup_pptdev_msix(ctx, vcpu, + error = vm_setup_pptdev_msix(ctx, 0, sc->pptfd, i, pi->pi_msix.table[i].addr, pi->pi_msix.table[i].msg_data, @@ -966,13 +966,13 @@ passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, } static void -passthru_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, - uint64_t offset, int size, uint64_t value) +passthru_write(struct vmctx *ctx, struct pci_devinst *pi, int baridx, + uint64_t offset, int size, uint64_t value) { struct passthru_softc *sc = pi->pi_arg; if (baridx == pci_msix_table_bar(pi)) { - msix_table_write(ctx, vcpu, sc, offset, size, value); + msix_table_write(ctx, sc, offset, size, value); } else { struct ppt_bar_io pbi; @@ -987,8 +987,8 @@ passthru_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, } static uint64_t -passthru_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, - uint64_t offset, int size) +passthru_read(struct vmctx *ctx __unused, struct pci_devinst *pi, int baridx, + uint64_t offset, int size) { struct passthru_softc *sc = pi->pi_arg; uint64_t val; diff --git a/usr/src/cmd/bhyve/pci_uart.c b/usr/src/cmd/bhyve/pci_uart.c index 3064d6fe62..7ccc3c7b6c 100644 --- a/usr/src/cmd/bhyve/pci_uart.c +++ b/usr/src/cmd/bhyve/pci_uart.c @@ -66,19 +66,19 @@ pci_uart_intr_deassert(void *arg) } static void -pci_uart_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size, uint64_t value) +pci_uart_write(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size, + uint64_t value) { - assert(baridx == 0); assert(size == 1); uart_write(pi->pi_arg, offset, value); } -uint64_t -pci_uart_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size) +static uint64_t +pci_uart_read(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size) { uint8_t val; @@ -99,7 +99,7 @@ pci_uart_legacy_config(nvlist_t *nvl, const char *opts) } static int -pci_uart_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) +pci_uart_init(struct vmctx *ctx __unused, struct pci_devinst *pi, nvlist_t *nvl) { struct uart_softc *sc; const char *device; diff --git a/usr/src/cmd/bhyve/pci_virtio_9p.c b/usr/src/cmd/bhyve/pci_virtio_9p.c index 2e169dc7cb..386eba31b1 100644 --- a/usr/src/cmd/bhyve/pci_virtio_9p.c +++ b/usr/src/cmd/bhyve/pci_virtio_9p.c @@ -98,7 +98,11 @@ struct pci_vt9p_request { struct pci_vt9p_config { uint16_t tag_len; +#ifdef __FreeBSD__ char tag[0]; +#else + char tag[VT9P_MAXTAGSZ]; +#endif } __attribute__((packed)); static int pci_vt9p_send(struct l9p_request *, const struct iovec *, @@ -111,18 +115,16 @@ static int pci_vt9p_cfgread(void *, int, int, uint32_t *); static void pci_vt9p_neg_features(void *, uint64_t); static struct virtio_consts vt9p_vi_consts = { - "vt9p", /* our name */ - 1, /* we support 1 virtqueue */ - VT9P_CONFIGSPACESZ, /* config reg size */ - pci_vt9p_reset, /* reset */ - pci_vt9p_notify, /* device-wide qnotify */ - pci_vt9p_cfgread, /* read virtio config */ - NULL, /* write virtio config */ - pci_vt9p_neg_features, /* apply negotiated features */ - (1 << 0), /* our capabilities */ + .vc_name = "vt9p", + .vc_nvq = 1, + .vc_cfgsize = VT9P_CONFIGSPACESZ, + .vc_reset = pci_vt9p_reset, + .vc_qnotify = pci_vt9p_notify, + .vc_cfgread = pci_vt9p_cfgread, + .vc_apply_features = pci_vt9p_neg_features, + .vc_hv_caps = (1 << 0), }; - static void pci_vt9p_reset(void *vsc) { @@ -155,7 +157,7 @@ pci_vt9p_cfgread(void *vsc, int offset, int size, uint32_t *retval) static int pci_vt9p_get_buffer(struct l9p_request *req, struct iovec *iov, size_t *niov, - void *arg) + void *arg __unused) { struct pci_vt9p_request *preq = req->lr_aux; size_t n = preq->vsr_niov - preq->vsr_respidx; @@ -167,8 +169,8 @@ pci_vt9p_get_buffer(struct l9p_request *req, struct iovec *iov, size_t *niov, } static int -pci_vt9p_send(struct l9p_request *req, const struct iovec *iov, - const size_t niov, const size_t iolen, void *arg) +pci_vt9p_send(struct l9p_request *req, const struct iovec *iov __unused, + const size_t niov __unused, const size_t iolen, void *arg __unused) { struct pci_vt9p_request *preq = req->lr_aux; struct pci_vt9p_softc *sc = preq->vsr_sc; @@ -184,8 +186,8 @@ pci_vt9p_send(struct l9p_request *req, const struct iovec *iov, } static void -pci_vt9p_drop(struct l9p_request *req, const struct iovec *iov, size_t niov, - void *arg) +pci_vt9p_drop(struct l9p_request *req, const struct iovec *iov __unused, + size_t niov __unused, void *arg __unused) { struct pci_vt9p_request *preq = req->lr_aux; struct pci_vt9p_softc *sc = preq->vsr_sc; @@ -264,7 +266,7 @@ pci_vt9p_legacy_config(nvlist_t *nvl, const char *opts) } static int -pci_vt9p_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) +pci_vt9p_init(struct vmctx *ctx __unused, struct pci_devinst *pi, nvlist_t *nvl) { struct pci_vt9p_softc *sc; const char *value; @@ -314,16 +316,16 @@ pci_vt9p_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) } sc = calloc(1, sizeof(struct pci_vt9p_softc)); -#ifndef __FreeBSD__ +#ifdef __FreeBSD__ + sc->vsc_config = calloc(1, sizeof(struct pci_vt9p_config) + + VT9P_MAXTAGSZ); +#else if (sc == NULL) { EPRINTLN("virtio-9p: soft state allocation failure: %s", strerror(errno)); return (1); } -#endif - sc->vsc_config = calloc(1, sizeof(struct pci_vt9p_config) + - VT9P_MAXTAGSZ); -#ifndef __FreeBSD__ + sc->vsc_config = calloc(1, sizeof(struct pci_vt9p_config)); if (sc == NULL) { EPRINTLN("virtio-9p: vsc_config allocation failure: %s", strerror(errno)); diff --git a/usr/src/cmd/bhyve/pci_virtio_block.c b/usr/src/cmd/bhyve/pci_virtio_block.c index 7a0667e7b0..fde899144f 100644 --- a/usr/src/cmd/bhyve/pci_virtio_block.c +++ b/usr/src/cmd/bhyve/pci_virtio_block.c @@ -219,19 +219,19 @@ static void pci_vtblk_apply_feats(void *, uint64_t); #endif static struct virtio_consts vtblk_vi_consts = { - "vtblk", /* our name */ - 1, /* we support 1 virtqueue */ - sizeof(struct vtblk_config), /* config reg size */ - pci_vtblk_reset, /* reset */ - pci_vtblk_notify, /* device-wide qnotify */ - pci_vtblk_cfgread, /* read PCI config */ - pci_vtblk_cfgwrite, /* write PCI config */ + .vc_name = "vtblk", + .vc_nvq = 1, + .vc_cfgsize = sizeof(struct vtblk_config), + .vc_reset = pci_vtblk_reset, + .vc_qnotify = pci_vtblk_notify, + .vc_cfgread = pci_vtblk_cfgread, + .vc_cfgwrite = pci_vtblk_cfgwrite, #ifndef __FreeBSD__ - pci_vtblk_apply_feats, /* apply negotiated features */ + .vc_apply_features = pci_vtblk_apply_feats, #else - NULL, /* apply negotiated features */ + .vc_apply_features = NULL, #endif - VTBLK_S_HOSTCAPS, /* our capabilities */ + .vc_hv_caps = VTBLK_S_HOSTCAPS, }; static void @@ -418,7 +418,8 @@ pci_vtblk_notify(void *vsc, struct vqueue_info *vq) } static void -pci_vtblk_resized(struct blockif_ctxt *bctxt, void *arg, size_t new_size) +pci_vtblk_resized(struct blockif_ctxt *bctxt __unused, void *arg, + size_t new_size) { struct pci_vtblk_softc *sc; @@ -430,9 +431,10 @@ pci_vtblk_resized(struct blockif_ctxt *bctxt, void *arg, size_t new_size) } static int -pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) +pci_vtblk_init(struct vmctx *ctx __unused, struct pci_devinst *pi, + nvlist_t *nvl) { - char bident[sizeof("XX:X:X")]; + char bident[sizeof("XXX:XXX")]; struct blockif_ctxt *bctxt; const char *path, *serial; MD5_CTX mdctx; @@ -444,7 +446,7 @@ pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) /* * The supplied backing file has to exist */ - snprintf(bident, sizeof(bident), "%d:%d", pi->pi_slot, pi->pi_func); + snprintf(bident, sizeof(bident), "%u:%u", pi->pi_slot, pi->pi_func); bctxt = blockif_open(nvl, bident); if (bctxt == NULL) { perror("Could not open backing file"); @@ -552,7 +554,8 @@ pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) } static int -pci_vtblk_cfgwrite(void *vsc, int offset, int size, uint32_t value) +pci_vtblk_cfgwrite(void *vsc __unused, int offset, int size __unused, + uint32_t value __unused) { DPRINTF(("vtblk: write to readonly reg %d", offset)); diff --git a/usr/src/cmd/bhyve/pci_virtio_console.c b/usr/src/cmd/bhyve/pci_virtio_console.c index 51b7acb1ba..4b3f578b3b 100644 --- a/usr/src/cmd/bhyve/pci_virtio_console.c +++ b/usr/src/cmd/bhyve/pci_virtio_console.c @@ -173,18 +173,16 @@ static void pci_vtcon_announce_port(struct pci_vtcon_port *); static void pci_vtcon_open_port(struct pci_vtcon_port *, bool); static struct virtio_consts vtcon_vi_consts = { - "vtcon", /* our name */ - VTCON_MAXQ, /* we support VTCON_MAXQ virtqueues */ - sizeof(struct pci_vtcon_config), /* config reg size */ - pci_vtcon_reset, /* reset */ - NULL, /* device-wide qnotify */ - pci_vtcon_cfgread, /* read virtio config */ - pci_vtcon_cfgwrite, /* write virtio config */ - pci_vtcon_neg_features, /* apply negotiated features */ - VTCON_S_HOSTCAPS, /* our capabilities */ + .vc_name = "vtcon", + .vc_nvq = VTCON_MAXQ, + .vc_cfgsize = sizeof(struct pci_vtcon_config), + .vc_reset = pci_vtcon_reset, + .vc_cfgread = pci_vtcon_cfgread, + .vc_cfgwrite = pci_vtcon_cfgwrite, + .vc_apply_features = pci_vtcon_neg_features, + .vc_hv_caps = VTCON_S_HOSTCAPS, }; - static void pci_vtcon_reset(void *vsc) { @@ -216,9 +214,9 @@ pci_vtcon_cfgread(void *vsc, int offset, int size, uint32_t *retval) } static int -pci_vtcon_cfgwrite(void *vsc, int offset, int size, uint32_t val) +pci_vtcon_cfgwrite(void *vsc __unused, int offset __unused, int size __unused, + uint32_t val __unused) { - return (0); } @@ -279,11 +277,10 @@ static int pci_vtcon_sock_add(struct pci_vtcon_softc *sc, const char *port_name, const nvlist_t *nvl) { + struct pci_vtcon_sock *sock = NULL; #ifdef __FreeBSD__ - struct pci_vtcon_sock *sock; struct sockaddr_un sun; #else - struct pci_vtcon_sock *sock = NULL; /* Our compiler #defines 'sun' as '1'. Awesome. */ struct sockaddr_un addr; #endif @@ -487,8 +484,8 @@ close: } static void -pci_vtcon_sock_tx(struct pci_vtcon_port *port, void *arg, struct iovec *iov, - int niov) +pci_vtcon_sock_tx(struct pci_vtcon_port *port __unused, void *arg __unused, + struct iovec *iov, int niov) { struct pci_vtcon_sock *sock; int i, ret; @@ -517,8 +514,8 @@ pci_vtcon_sock_tx(struct pci_vtcon_port *port, void *arg, struct iovec *iov, } static void -pci_vtcon_control_tx(struct pci_vtcon_port *port, void *arg, struct iovec *iov, - int niov) +pci_vtcon_control_tx(struct pci_vtcon_port *port, void *arg __unused, + struct iovec *iov, int niov) { struct pci_vtcon_softc *sc; struct pci_vtcon_port *tmp; @@ -612,8 +609,8 @@ pci_vtcon_control_send(struct pci_vtcon_softc *sc, memcpy(iov.iov_base, ctrl, sizeof(struct pci_vtcon_control)); if (payload != NULL && len > 0) - memcpy(iov.iov_base + sizeof(struct pci_vtcon_control), - payload, len); + memcpy((uint8_t *)iov.iov_base + + sizeof(struct pci_vtcon_control), payload, len); vq_relchain(vq, req.idx, sizeof(struct pci_vtcon_control) + len); vq_endchains(vq, 1); @@ -711,7 +708,8 @@ pci_vtcon_legacy_config(nvlist_t *nvl, const char *opts) } static int -pci_vtcon_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) +pci_vtcon_init(struct vmctx *ctx __unused, struct pci_devinst *pi, + nvlist_t *nvl) { struct pci_vtcon_softc *sc; nvlist_t *ports_nvl; diff --git a/usr/src/cmd/bhyve/pci_virtio_input.c b/usr/src/cmd/bhyve/pci_virtio_input.c index 404213d907..13e193f8d9 100644 --- a/usr/src/cmd/bhyve/pci_virtio_input.c +++ b/usr/src/cmd/bhyve/pci_virtio_input.c @@ -159,15 +159,13 @@ static int pci_vtinput_cfgread(void *, int, int, uint32_t *); static int pci_vtinput_cfgwrite(void *, int, int, uint32_t); static struct virtio_consts vtinput_vi_consts = { - "vtinput", /* our name */ - VTINPUT_MAXQ, /* we support 1 virtqueue */ - sizeof(struct vtinput_config), /* config reg size */ - pci_vtinput_reset, /* reset */ - NULL, /* device-wide qnotify -- not used */ - pci_vtinput_cfgread, /* read virtio config */ - pci_vtinput_cfgwrite, /* write virtio config */ - NULL, /* apply negotiated features */ - 0, /* our capabilities */ + .vc_name = "vtinput", + .vc_nvq = VTINPUT_MAXQ, + .vc_cfgsize = sizeof(struct vtinput_config), + .vc_reset = pci_vtinput_reset, + .vc_cfgread = pci_vtinput_cfgread, + .vc_cfgwrite = pci_vtinput_cfgwrite, + .vc_hv_caps = 0, }; static void @@ -180,7 +178,7 @@ pci_vtinput_reset(void *vsc) } static void -pci_vtinput_notify_eventq(void *vsc, struct vqueue_info *vq) +pci_vtinput_notify_eventq(void *vsc __unused, struct vqueue_info *vq __unused) { DPRINTF(("%s", __func__)); } @@ -423,7 +421,7 @@ pci_vtinput_cfgread(void *vsc, int offset, int size, uint32_t *retval) struct pci_vtinput_softc *sc = vsc; /* check for valid offset and size */ - if (offset + size > sizeof(struct vtinput_config)) { + if (offset + size > (int)sizeof(struct vtinput_config)) { WPRINTF(("%s: read to invalid offset/size %d/%d", __func__, offset, size)); memset(retval, 0, size); @@ -476,15 +474,14 @@ vtinput_eventqueue_add_event( if (queue->idx >= queue->size) { /* alloc new elements for queue */ const uint32_t newSize = queue->idx; - const void *newPtr = realloc(queue->events, + void *newPtr = realloc(queue->events, queue->size * sizeof(struct vtinput_event_elem)); if (newPtr == NULL) { WPRINTF(("%s: realloc memory for eventqueue failed!", __func__)); return (1); } - /* save new size and eventqueue */ - queue->events = (struct vtinput_event_elem *)newPtr; + queue->events = newPtr; queue->size = newSize; } @@ -641,7 +638,8 @@ pci_vtinput_legacy_config(nvlist_t *nvl, const char *opts) } static int -pci_vtinput_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) +pci_vtinput_init(struct vmctx *ctx __unused, struct pci_devinst *pi, + nvlist_t *nvl) { struct pci_vtinput_softc *sc; diff --git a/usr/src/cmd/bhyve/pci_virtio_net.c b/usr/src/cmd/bhyve/pci_virtio_net.c index a496414809..9187215d5e 100644 --- a/usr/src/cmd/bhyve/pci_virtio_net.c +++ b/usr/src/cmd/bhyve/pci_virtio_net.c @@ -139,15 +139,14 @@ static int pci_vtnet_cfgwrite(void *, int, int, uint32_t); static void pci_vtnet_neg_features(void *, uint64_t); static struct virtio_consts vtnet_vi_consts = { - "vtnet", /* our name */ - VTNET_MAXQ - 1, /* we currently support 2 virtqueues */ - sizeof(struct virtio_net_config), /* config reg size */ - pci_vtnet_reset, /* reset */ - NULL, /* device-wide qnotify -- not used */ - pci_vtnet_cfgread, /* read PCI config */ - pci_vtnet_cfgwrite, /* write PCI config */ - pci_vtnet_neg_features, /* apply negotiated features */ - VTNET_S_HOSTCAPS, /* our capabilities */ + .vc_name = "vtnet", + .vc_nvq = VTNET_MAXQ - 1, + .vc_cfgsize = sizeof(struct virtio_net_config), + .vc_reset = pci_vtnet_reset, + .vc_cfgread = pci_vtnet_cfgread, + .vc_cfgwrite = pci_vtnet_cfgwrite, + .vc_apply_features = pci_vtnet_neg_features, + .vc_hv_caps = VTNET_S_HOSTCAPS, }; static void @@ -414,7 +413,7 @@ pci_vtnet_rx(struct pci_vtnet_softc *sc) * an entire ethernet frame + rx header. */ static void -pci_vtnet_rx_callback(int fd, enum ev_type type, void *param) +pci_vtnet_rx_callback(int fd __unused, enum ev_type type __unused, void *param) { struct pci_vtnet_softc *sc = param; @@ -578,7 +577,8 @@ pci_vtnet_ping_ctlq(void *vsc, struct vqueue_info *vq) #endif static int -pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) +pci_vtnet_init(struct vmctx *ctx __unused, struct pci_devinst *pi, + nvlist_t *nvl) { struct pci_vtnet_softc *sc; const char *value; diff --git a/usr/src/cmd/bhyve/pci_virtio_rnd.c b/usr/src/cmd/bhyve/pci_virtio_rnd.c index 4fbedc639c..2c989650a9 100644 --- a/usr/src/cmd/bhyve/pci_virtio_rnd.c +++ b/usr/src/cmd/bhyve/pci_virtio_rnd.c @@ -84,18 +84,14 @@ static void pci_vtrnd_reset(void *); static void pci_vtrnd_notify(void *, struct vqueue_info *); static struct virtio_consts vtrnd_vi_consts = { - "vtrnd", /* our name */ - 1, /* we support 1 virtqueue */ - 0, /* config reg size */ - pci_vtrnd_reset, /* reset */ - pci_vtrnd_notify, /* device-wide qnotify */ - NULL, /* read virtio config */ - NULL, /* write virtio config */ - NULL, /* apply negotiated features */ - 0, /* our capabilities */ + .vc_name = "vtrnd", + .vc_nvq = 1, + .vc_cfgsize = 0, + .vc_reset = pci_vtrnd_reset, + .vc_qnotify = pci_vtrnd_notify, + .vc_hv_caps = 0, }; - static void pci_vtrnd_reset(void *vsc) { @@ -144,7 +140,8 @@ pci_vtrnd_notify(void *vsc, struct vqueue_info *vq) static int -pci_vtrnd_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) +pci_vtrnd_init(struct vmctx *ctx __unused, struct pci_devinst *pi, + nvlist_t *nvl __unused) { struct pci_vtrnd_softc *sc; int fd; diff --git a/usr/src/cmd/bhyve/pci_virtio_scsi.c b/usr/src/cmd/bhyve/pci_virtio_scsi.c index 6f7dceb05d..617074469f 100644 --- a/usr/src/cmd/bhyve/pci_virtio_scsi.c +++ b/usr/src/cmd/bhyve/pci_virtio_scsi.c @@ -88,8 +88,8 @@ __FBSDID("$FreeBSD$"); #define VIRTIO_SCSI_F_CHANGE (1 << 2) static int pci_vtscsi_debug = 0; -#define DPRINTF(params) if (pci_vtscsi_debug) PRINTLN params -#define WPRINTF(params) PRINTLN params +#define WPRINTF(msg, params...) PRINTLN("virtio-scsi: " msg, ##params) +#define DPRINTF(msg, params...) if (pci_vtscsi_debug) WPRINTF(msg, ##params) struct pci_vtscsi_config { uint32_t num_queues; @@ -248,15 +248,14 @@ static int pci_vtscsi_init_queue(struct pci_vtscsi_softc *, static int pci_vtscsi_init(struct vmctx *, struct pci_devinst *, nvlist_t *); static struct virtio_consts vtscsi_vi_consts = { - "vtscsi", /* our name */ - VTSCSI_MAXQ, /* we support 2+n virtqueues */ - sizeof(struct pci_vtscsi_config), /* config reg size */ - pci_vtscsi_reset, /* reset */ - NULL, /* device-wide qnotify */ - pci_vtscsi_cfgread, /* read virtio config */ - pci_vtscsi_cfgwrite, /* write virtio config */ - pci_vtscsi_neg_features, /* apply negotiated features */ - 0, /* our capabilities */ + .vc_name = "vtscsi", + .vc_nvq = VTSCSI_MAXQ, + .vc_cfgsize = sizeof(struct pci_vtscsi_config), + .vc_reset = pci_vtscsi_reset, + .vc_cfgread = pci_vtscsi_cfgread, + .vc_cfgwrite = pci_vtscsi_cfgwrite, + .vc_apply_features = pci_vtscsi_neg_features, + .vc_hv_caps = 0, }; static void * @@ -289,8 +288,7 @@ pci_vtscsi_proc(void *arg) vq_endchains(q->vsq_vq, 0); pthread_mutex_unlock(&q->vsq_qmtx); - DPRINTF(("virtio-scsi: request completed", - req->vsr_idx)); + DPRINTF("request completed", req->vsr_idx); free(req); } @@ -305,7 +303,7 @@ pci_vtscsi_reset(void *vsc) sc = vsc; - DPRINTF(("vtscsi: device reset requested")); + DPRINTF("device reset requested"); vi_reset_dev(&sc->vss_vs); /* initialize config structure */ @@ -344,9 +342,9 @@ pci_vtscsi_cfgread(void *vsc, int offset, int size, uint32_t *retval) } static int -pci_vtscsi_cfgwrite(void *vsc, int offset, int size, uint32_t val) +pci_vtscsi_cfgwrite(void *vsc __unused, int offset __unused, int size __unused, + uint32_t val __unused) { - return (0); } @@ -365,14 +363,27 @@ pci_vtscsi_control_handle(struct pci_vtscsi_softc *sc, void *buf, struct pci_vtscsi_ctrl_an *an; uint32_t type; + if (bufsize < sizeof(uint32_t)) { + WPRINTF("ignoring truncated control request"); + return (0); + } + type = *(uint32_t *)buf; if (type == VIRTIO_SCSI_T_TMF) { + if (bufsize != sizeof(*tmf)) { + WPRINTF("ignoring tmf request with size %zu", bufsize); + return (0); + } tmf = (struct pci_vtscsi_ctrl_tmf *)buf; return (pci_vtscsi_tmf_handle(sc, tmf)); } if (type == VIRTIO_SCSI_T_AN_QUERY) { + if (bufsize != sizeof(*an)) { + WPRINTF("ignoring AN request with size %zu", bufsize); + return (0); + } an = (struct pci_vtscsi_ctrl_an *)buf; return (pci_vtscsi_an_handle(sc, an)); } @@ -394,7 +405,8 @@ pci_vtscsi_tmf_handle(struct pci_vtscsi_softc *sc, io->io_hdr.nexus.initid = sc->vss_iid; io->io_hdr.nexus.targ_lun = pci_vtscsi_get_lun(tmf->lun); io->taskio.tag_type = CTL_TAG_SIMPLE; - io->taskio.tag_num = (uint32_t)tmf->id; + io->taskio.tag_num = tmf->id; + io->io_hdr.flags |= CTL_FLAG_USER_TAG; switch (tmf->subtype) { case VIRTIO_SCSI_T_TMF_ABORT_TASK: @@ -434,13 +446,13 @@ pci_vtscsi_tmf_handle(struct pci_vtscsi_softc *sc, struct sbuf *sb = sbuf_new_auto(); ctl_io_sbuf(io, sb); sbuf_finish(sb); - DPRINTF(("pci_virtio_scsi: %s", sbuf_data(sb))); + DPRINTF("%s", sbuf_data(sb)); sbuf_delete(sb); } err = ioctl(sc->vss_ctl_fd, CTL_IO, io); if (err != 0) - WPRINTF(("CTL_IO: err=%d (%s)", errno, strerror(errno))); + WPRINTF("CTL_IO: err=%d (%s)", errno, strerror(errno)); tmf->response = io->taskio.task_status; ctl_scsi_free_io(io); @@ -448,10 +460,9 @@ pci_vtscsi_tmf_handle(struct pci_vtscsi_softc *sc, } static int -pci_vtscsi_an_handle(struct pci_vtscsi_softc *sc, - struct pci_vtscsi_ctrl_an *an) +pci_vtscsi_an_handle(struct pci_vtscsi_softc *sc __unused, + struct pci_vtscsi_ctrl_an *an __unused) { - return (0); } @@ -469,6 +480,15 @@ pci_vtscsi_request_handle(struct pci_vtscsi_queue *q, struct iovec *iov_in, uint32_t ext_data_len = 0, ext_sg_entries = 0; int err, nxferred; + if (count_iov(iov_out, niov_out) < VTSCSI_OUT_HEADER_LEN(sc)) { + WPRINTF("ignoring request with insufficient output"); + return (0); + } + if (count_iov(iov_in, niov_in) < VTSCSI_IN_HEADER_LEN(sc)) { + WPRINTF("ignoring request with incomplete header"); + return (0); + } + seek_iov(iov_in, niov_in, data_iov_in, &data_niov_in, VTSCSI_IN_HEADER_LEN(sc)); seek_iov(iov_out, niov_out, data_iov_out, &data_niov_out, @@ -478,7 +498,7 @@ pci_vtscsi_request_handle(struct pci_vtscsi_queue *q, struct iovec *iov_in, truncate_iov(iov_out, &niov_out, VTSCSI_OUT_HEADER_LEN(sc)); iov_to_buf(iov_in, niov_in, (void **)&cmd_rd); - cmd_wr = malloc(VTSCSI_OUT_HEADER_LEN(sc)); + cmd_wr = calloc(1, VTSCSI_OUT_HEADER_LEN(sc)); io = ctl_scsi_alloc_io(sc->vss_iid); ctl_scsi_zero_io(io); @@ -500,7 +520,8 @@ pci_vtscsi_request_handle(struct pci_vtscsi_queue *q, struct iovec *iov_in, } io->scsiio.sense_len = sc->vss_config.sense_size; - io->scsiio.tag_num = (uint32_t)cmd_rd->id; + io->scsiio.tag_num = cmd_rd->id; + io->io_hdr.flags |= CTL_FLAG_USER_TAG; switch (cmd_rd->task_attr) { case VIRTIO_SCSI_S_ORDERED: io->scsiio.tag_type = CTL_TAG_ORDERED; @@ -527,18 +548,18 @@ pci_vtscsi_request_handle(struct pci_vtscsi_queue *q, struct iovec *iov_in, struct sbuf *sb = sbuf_new_auto(); ctl_io_sbuf(io, sb); sbuf_finish(sb); - DPRINTF(("pci_virtio_scsi: %s", sbuf_data(sb))); + DPRINTF("%s", sbuf_data(sb)); sbuf_delete(sb); } err = ioctl(sc->vss_ctl_fd, CTL_IO, io); if (err != 0) { - WPRINTF(("CTL_IO: err=%d (%s)", errno, strerror(errno))); + WPRINTF("CTL_IO: err=%d (%s)", errno, strerror(errno)); cmd_wr->response = VIRTIO_SCSI_S_FAILURE; } else { cmd_wr->sense_len = MIN(io->scsiio.sense_len, sc->vss_config.sense_size); - cmd_wr->residual = io->scsiio.residual; + cmd_wr->residual = ext_data_len - io->scsiio.ext_data_filled; cmd_wr->status = io->scsiio.scsi_status; cmd_wr->response = VIRTIO_SCSI_S_OK; memcpy(&cmd_wr->sense, &io->scsiio.sense_data, @@ -571,7 +592,7 @@ pci_vtscsi_controlq_notify(void *vsc, struct vqueue_info *vq) bufsize = iov_to_buf(iov, n, &buf); iolen = pci_vtscsi_control_handle(sc, buf, bufsize); - buf_to_iov(buf + bufsize - iolen, iolen, iov, n, + buf_to_iov((uint8_t *)buf + bufsize - iolen, iolen, iov, n, bufsize - iolen); /* @@ -584,9 +605,8 @@ pci_vtscsi_controlq_notify(void *vsc, struct vqueue_info *vq) } static void -pci_vtscsi_eventq_notify(void *vsc, struct vqueue_info *vq) +pci_vtscsi_eventq_notify(void *vsc __unused, struct vqueue_info *vq) { - vq_kick_disable(vq); } @@ -622,8 +642,7 @@ pci_vtscsi_requestq_notify(void *vsc, struct vqueue_info *vq) pthread_cond_signal(&q->vsq_cv); pthread_mutex_unlock(&q->vsq_mtx); - DPRINTF(("virtio-scsi: request enqueued", - vireq.idx)); + DPRINTF("request enqueued", vireq.idx); } } @@ -679,7 +698,8 @@ pci_vtscsi_legacy_config(nvlist_t *nvl, const char *opts) } static int -pci_vtscsi_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) +pci_vtscsi_init(struct vmctx *ctx __unused, struct pci_devinst *pi, + nvlist_t *nvl) { struct pci_vtscsi_softc *sc; const char *devname, *value; @@ -695,7 +715,7 @@ pci_vtscsi_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) devname = "/dev/cam/ctl"; sc->vss_ctl_fd = open(devname, O_RDWR); if (sc->vss_ctl_fd < 0) { - WPRINTF(("cannot open %s: %s", devname, strerror(errno))); + WPRINTF("cannot open %s: %s", devname, strerror(errno)); free(sc); return (1); } diff --git a/usr/src/cmd/bhyve/pci_virtio_viona.c b/usr/src/cmd/bhyve/pci_virtio_viona.c index 8ee3880100..cac8ece9f3 100644 --- a/usr/src/cmd/bhyve/pci_virtio_viona.c +++ b/usr/src/cmd/bhyve/pci_virtio_viona.c @@ -643,7 +643,7 @@ pci_viona_baraddr(struct vmctx *ctx, struct pci_devinst *pi, int baridx, } static void -pci_viona_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, +pci_viona_write(struct vmctx *ctx __unused, struct pci_devinst *pi, int baridx, uint64_t offset, int size, uint64_t value) { struct pci_viona_softc *sc = pi->pi_arg; @@ -747,7 +747,7 @@ pci_viona_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, } static uint64_t -pci_viona_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, +pci_viona_read(struct vmctx *ctx __unused, struct pci_devinst *pi, int baridx, uint64_t offset, int size) { struct pci_viona_softc *sc = pi->pi_arg; diff --git a/usr/src/cmd/bhyve/pci_xhci.c b/usr/src/cmd/bhyve/pci_xhci.c index 4caa32e981..278df0d355 100644 --- a/usr/src/cmd/bhyve/pci_xhci.c +++ b/usr/src/cmd/bhyve/pci_xhci.c @@ -569,6 +569,10 @@ pci_xhci_portregs_write(struct pci_xhci_softc *sc, uint64_t offset, */ p->porthlpmc = value; break; + default: + DPRINTF(("pci_xhci: unaligned portreg write offset %#lx", + offset)); + break; } } @@ -651,8 +655,7 @@ pci_xhci_init_ep(struct pci_xhci_dev_emu *dev, int epid) struct xhci_dev_ctx *dev_ctx; struct pci_xhci_dev_ep *devep; struct xhci_endp_ctx *ep_ctx; - uint32_t pstreams; - int i; + uint32_t i, pstreams; dev_ctx = dev->dev_ctx; ep_ctx = &dev_ctx->ctx_ep[epid]; @@ -1185,8 +1188,7 @@ done: static uint32_t pci_xhci_find_stream(struct pci_xhci_softc *sc, struct xhci_endp_ctx *ep, - struct pci_xhci_dev_ep *devep, uint32_t streamid, - struct xhci_stream_ctx **osctx) + struct pci_xhci_dev_ep *devep, uint32_t streamid) { struct xhci_stream_ctx *sctx; @@ -1205,12 +1207,11 @@ pci_xhci_find_stream(struct pci_xhci_softc *sc, struct xhci_endp_ctx *ep, if (streamid > devep->ep_MaxPStreams) return (XHCI_TRB_ERROR_STREAM_TYPE); - sctx = XHCI_GADDR(sc, ep->qwEpCtx2 & ~0xFUL) + streamid; + sctx = (struct xhci_stream_ctx *)XHCI_GADDR(sc, ep->qwEpCtx2 & ~0xFUL) + + streamid; if (!XHCI_SCTX_0_SCT_GET(sctx->qwSctx0)) return (XHCI_TRB_ERROR_STREAM_TYPE); - *osctx = sctx; - return (XHCI_TRB_ERROR_SUCCESS); } @@ -1265,12 +1266,8 @@ pci_xhci_cmd_set_tr(struct pci_xhci_softc *sc, uint32_t slot, streamid = XHCI_TRB_2_STREAM_GET(trb->dwTrb2); if (devep->ep_MaxPStreams > 0) { - struct xhci_stream_ctx *sctx; - - sctx = NULL; - cmderr = pci_xhci_find_stream(sc, ep_ctx, devep, streamid, - &sctx); - if (sctx != NULL) { + cmderr = pci_xhci_find_stream(sc, ep_ctx, devep, streamid); + if (cmderr == XHCI_TRB_ERROR_SUCCESS) { assert(devep->ep_sctx != NULL); devep->ep_sctx[streamid].qwSctx0 = trb->qwTrb0; @@ -1634,9 +1631,9 @@ pci_xhci_xfer_complete(struct pci_xhci_softc *sc, struct usb_data_xfer *xfer, } static void -pci_xhci_update_ep_ring(struct pci_xhci_softc *sc, struct pci_xhci_dev_emu *dev, - struct pci_xhci_dev_ep *devep, struct xhci_endp_ctx *ep_ctx, - uint32_t streamid, uint64_t ringaddr, int ccs) +pci_xhci_update_ep_ring(struct pci_xhci_softc *sc, + struct pci_xhci_dev_emu *dev __unused, struct pci_xhci_dev_ep *devep, + struct xhci_endp_ctx *ep_ctx, uint32_t streamid, uint64_t ringaddr, int ccs) { if (devep->ep_MaxPStreams != 0) { @@ -1743,7 +1740,7 @@ pci_xhci_handle_transfer(struct pci_xhci_softc *sc, DPRINTF(("pci_xhci handle_transfer slot %u", slot)); retry: - err = 0; + err = XHCI_TRB_ERROR_INVALID; do_retry = 0; do_intr = 0; setup_trb = NULL; @@ -1867,24 +1864,26 @@ retry: goto errout; if (epid == 1) { - err = USB_ERR_NOT_STARTED; + int usberr; + if (dev->dev_ue->ue_request != NULL) - err = dev->dev_ue->ue_request(dev->dev_sc, xfer); - setup_trb = NULL; + usberr = dev->dev_ue->ue_request(dev->dev_sc, xfer); + else + usberr = USB_ERR_NOT_STARTED; + err = USB_TO_XHCI_ERR(usberr); + if (err == XHCI_TRB_ERROR_SUCCESS || + err == XHCI_TRB_ERROR_STALL || + err == XHCI_TRB_ERROR_SHORT_PKT) { + err = pci_xhci_xfer_complete(sc, xfer, slot, epid, + &do_intr); + if (err != XHCI_TRB_ERROR_SUCCESS) + do_retry = 0; + } + } else { /* handle data transfer */ pci_xhci_try_usb_xfer(sc, dev, devep, ep_ctx, slot, epid); err = XHCI_TRB_ERROR_SUCCESS; - goto errout; - } - - err = USB_TO_XHCI_ERR(err); - if ((err == XHCI_TRB_ERROR_SUCCESS) || - (err == XHCI_TRB_ERROR_STALL) || - (err == XHCI_TRB_ERROR_SHORT_PKT)) { - err = pci_xhci_xfer_complete(sc, xfer, slot, epid, &do_intr); - if (err != XHCI_TRB_ERROR_SUCCESS) - do_retry = 0; } errout: @@ -1922,6 +1921,7 @@ pci_xhci_device_doorbell(struct pci_xhci_softc *sc, uint32_t slot, struct xhci_trb *trb; uint64_t ringaddr; uint32_t ccs; + int error; DPRINTF(("pci_xhci doorbell slot %u epid %u stream %u", slot, epid, streamid)); @@ -1967,8 +1967,6 @@ pci_xhci_device_doorbell(struct pci_xhci_softc *sc, uint32_t slot, /* get next trb work item */ if (devep->ep_MaxPStreams != 0) { - struct xhci_stream_ctx *sctx; - /* * Stream IDs of 0, 65535 (any stream), and 65534 * (prime) are invalid. @@ -1978,10 +1976,10 @@ pci_xhci_device_doorbell(struct pci_xhci_softc *sc, uint32_t slot, return; } - sctx = NULL; - pci_xhci_find_stream(sc, ep_ctx, devep, streamid, &sctx); - if (sctx == NULL) { - DPRINTF(("pci_xhci: invalid stream %u", streamid)); + error = pci_xhci_find_stream(sc, ep_ctx, devep, streamid); + if (error != XHCI_TRB_ERROR_SUCCESS) { + DPRINTF(("pci_xhci: invalid stream %u: %d", + streamid, error)); return; } sctx_tr = &devep->ep_sctx_trbs[streamid]; @@ -2124,7 +2122,7 @@ pci_xhci_rtsregs_write(struct pci_xhci_softc *sc, uint64_t offset, if (rts->er_events_cnt > 0) { uint64_t erdp; - uint32_t erdp_i; + int erdp_i; erdp = rts->intrreg.erdp & ~0xF; erdp_i = (erdp - rts->erstba_p->qwEvrsTablePtr) / @@ -2153,13 +2151,15 @@ pci_xhci_rtsregs_write(struct pci_xhci_softc *sc, uint64_t offset, static uint64_t pci_xhci_portregs_read(struct pci_xhci_softc *sc, uint64_t offset) { + struct pci_xhci_portregs *portregs; int port; - uint32_t *p; + uint32_t reg; if (sc->portregs == NULL) return (0); - port = (offset - 0x3F0) / 0x10; + port = (offset - XHCI_PORTREGS_PORT0) / XHCI_PORTREGS_SETSZ; + offset = (offset - XHCI_PORTREGS_PORT0) % XHCI_PORTREGS_SETSZ; if (port > XHCI_MAX_DEVS) { DPRINTF(("pci_xhci: portregs_read port %d >= XHCI_MAX_DEVS", @@ -2169,15 +2169,31 @@ pci_xhci_portregs_read(struct pci_xhci_softc *sc, uint64_t offset) return (XHCI_PS_SPEED_SET(3)); } - offset = (offset - 0x3F0) % 0x10; - - p = &sc->portregs[port].portsc; - p += offset / sizeof(uint32_t); + portregs = XHCI_PORTREG_PTR(sc, port); + switch (offset) { + case 0: + reg = portregs->portsc; + break; + case 4: + reg = portregs->portpmsc; + break; + case 8: + reg = portregs->portli; + break; + case 12: + reg = portregs->porthlpmc; + break; + default: + DPRINTF(("pci_xhci: unaligned portregs read offset %#lx", + offset)); + reg = 0xffffffff; + break; + } DPRINTF(("pci_xhci: portregs read offset 0x%lx port %u -> 0x%x", - offset, port, *p)); + offset, port, reg)); - return (*p); + return (reg); } static void @@ -2268,8 +2284,9 @@ pci_xhci_hostop_write(struct pci_xhci_softc *sc, uint64_t offset, static void -pci_xhci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size, uint64_t value) +pci_xhci_write(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size __unused, + uint64_t value) { struct pci_xhci_softc *sc; @@ -2403,9 +2420,9 @@ pci_xhci_hostop_read(struct pci_xhci_softc *sc, uint64_t offset) } static uint64_t -pci_xhci_dbregs_read(struct pci_xhci_softc *sc, uint64_t offset) +pci_xhci_dbregs_read(struct pci_xhci_softc *sc __unused, + uint64_t offset __unused) { - /* read doorbell always returns 0 */ return (0); } @@ -2490,8 +2507,8 @@ pci_xhci_xecp_read(struct pci_xhci_softc *sc, uint64_t offset) static uint64_t -pci_xhci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, - uint64_t offset, int size) +pci_xhci_read(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size) { struct pci_xhci_softc *sc; uint32_t value; @@ -2663,9 +2680,9 @@ done: } static int -pci_xhci_dev_event(struct usb_hci *hci, enum hci_usbev evid, void *param) +pci_xhci_dev_event(struct usb_hci *hci, enum hci_usbev evid __unused, + void *param __unused) { - DPRINTF(("xhci device event port %d", hci->hci_port)); return (0); } @@ -2859,7 +2876,7 @@ bad: } static int -pci_xhci_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) +pci_xhci_init(struct vmctx *ctx __unused, struct pci_devinst *pi, nvlist_t *nvl) { struct pci_xhci_softc *sc; int error; diff --git a/usr/src/cmd/bhyve/pci_xhci.h b/usr/src/cmd/bhyve/pci_xhci.h index 7502f9396a..9112b5b30c 100644 --- a/usr/src/cmd/bhyve/pci_xhci.h +++ b/usr/src/cmd/bhyve/pci_xhci.h @@ -90,7 +90,7 @@ enum { #define XHCI_PAGE_SIZE 4096 /* bytes */ struct xhci_slot_ctx { - volatile uint32_t dwSctx0; + uint32_t dwSctx0; #define XHCI_SCTX_0_ROUTE_SET(x) ((x) & 0xFFFFF) #define XHCI_SCTX_0_ROUTE_GET(x) ((x) & 0xFFFFF) #define XHCI_SCTX_0_SPEED_SET(x) (((x) & 0xF) << 20) @@ -101,14 +101,14 @@ struct xhci_slot_ctx { #define XHCI_SCTX_0_HUB_GET(x) (((x) >> 26) & 0x1) #define XHCI_SCTX_0_CTX_NUM_SET(x) (((x) & 0x1F) << 27) #define XHCI_SCTX_0_CTX_NUM_GET(x) (((x) >> 27) & 0x1F) - volatile uint32_t dwSctx1; + uint32_t dwSctx1; #define XHCI_SCTX_1_MAX_EL_SET(x) ((x) & 0xFFFF) #define XHCI_SCTX_1_MAX_EL_GET(x) ((x) & 0xFFFF) #define XHCI_SCTX_1_RH_PORT_SET(x) (((x) & 0xFF) << 16) #define XHCI_SCTX_1_RH_PORT_GET(x) (((x) >> 16) & 0xFF) #define XHCI_SCTX_1_NUM_PORTS_SET(x) (((x) & 0xFF) << 24) #define XHCI_SCTX_1_NUM_PORTS_GET(x) (((x) >> 24) & 0xFF) - volatile uint32_t dwSctx2; + uint32_t dwSctx2; #define XHCI_SCTX_2_TT_HUB_SID_SET(x) ((x) & 0xFF) #define XHCI_SCTX_2_TT_HUB_SID_GET(x) ((x) & 0xFF) #define XHCI_SCTX_2_TT_PORT_NUM_SET(x) (((x) & 0xFF) << 8) @@ -117,19 +117,19 @@ struct xhci_slot_ctx { #define XHCI_SCTX_2_TT_THINK_TIME_GET(x) (((x) >> 16) & 0x3) #define XHCI_SCTX_2_IRQ_TARGET_SET(x) (((x) & 0x3FF) << 22) #define XHCI_SCTX_2_IRQ_TARGET_GET(x) (((x) >> 22) & 0x3FF) - volatile uint32_t dwSctx3; + uint32_t dwSctx3; #define XHCI_SCTX_3_DEV_ADDR_SET(x) ((x) & 0xFF) #define XHCI_SCTX_3_DEV_ADDR_GET(x) ((x) & 0xFF) #define XHCI_SCTX_3_SLOT_STATE_SET(x) (((x) & 0x1F) << 27) #define XHCI_SCTX_3_SLOT_STATE_GET(x) (((x) >> 27) & 0x1F) - volatile uint32_t dwSctx4; - volatile uint32_t dwSctx5; - volatile uint32_t dwSctx6; - volatile uint32_t dwSctx7; + uint32_t dwSctx4; + uint32_t dwSctx5; + uint32_t dwSctx6; + uint32_t dwSctx7; }; struct xhci_endp_ctx { - volatile uint32_t dwEpCtx0; + uint32_t dwEpCtx0; #define XHCI_EPCTX_0_EPSTATE_SET(x) ((x) & 0x7) #define XHCI_EPCTX_0_EPSTATE_GET(x) ((x) & 0x7) #define XHCI_EPCTX_0_MULT_SET(x) (((x) & 0x3) << 8) @@ -140,7 +140,7 @@ struct xhci_endp_ctx { #define XHCI_EPCTX_0_LSA_GET(x) (((x) >> 15) & 0x1) #define XHCI_EPCTX_0_IVAL_SET(x) (((x) & 0xFF) << 16) #define XHCI_EPCTX_0_IVAL_GET(x) (((x) >> 16) & 0xFF) - volatile uint32_t dwEpCtx1; + uint32_t dwEpCtx1; #define XHCI_EPCTX_1_CERR_SET(x) (((x) & 0x3) << 1) #define XHCI_EPCTX_1_CERR_GET(x) (((x) >> 1) & 0x3) #define XHCI_EPCTX_1_EPTYPE_SET(x) (((x) & 0x7) << 3) @@ -151,32 +151,32 @@ struct xhci_endp_ctx { #define XHCI_EPCTX_1_MAXB_GET(x) (((x) >> 8) & 0xFF) #define XHCI_EPCTX_1_MAXP_SIZE_SET(x) (((x) & 0xFFFF) << 16) #define XHCI_EPCTX_1_MAXP_SIZE_GET(x) (((x) >> 16) & 0xFFFF) - volatile uint64_t qwEpCtx2; + uint64_t qwEpCtx2; #define XHCI_EPCTX_2_DCS_SET(x) ((x) & 0x1) #define XHCI_EPCTX_2_DCS_GET(x) ((x) & 0x1) #define XHCI_EPCTX_2_TR_DQ_PTR_MASK 0xFFFFFFFFFFFFFFF0U - volatile uint32_t dwEpCtx4; + uint32_t dwEpCtx4; #define XHCI_EPCTX_4_AVG_TRB_LEN_SET(x) ((x) & 0xFFFF) #define XHCI_EPCTX_4_AVG_TRB_LEN_GET(x) ((x) & 0xFFFF) #define XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_SET(x) (((x) & 0xFFFF) << 16) #define XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_GET(x) (((x) >> 16) & 0xFFFF) - volatile uint32_t dwEpCtx5; - volatile uint32_t dwEpCtx6; - volatile uint32_t dwEpCtx7; + uint32_t dwEpCtx5; + uint32_t dwEpCtx6; + uint32_t dwEpCtx7; }; struct xhci_input_ctx { #define XHCI_INCTX_NON_CTRL_MASK 0xFFFFFFFCU - volatile uint32_t dwInCtx0; + uint32_t dwInCtx0; #define XHCI_INCTX_0_DROP_MASK(n) (1U << (n)) - volatile uint32_t dwInCtx1; + uint32_t dwInCtx1; #define XHCI_INCTX_1_ADD_MASK(n) (1U << (n)) - volatile uint32_t dwInCtx2; - volatile uint32_t dwInCtx3; - volatile uint32_t dwInCtx4; - volatile uint32_t dwInCtx5; - volatile uint32_t dwInCtx6; - volatile uint32_t dwInCtx7; + uint32_t dwInCtx2; + uint32_t dwInCtx3; + uint32_t dwInCtx4; + uint32_t dwInCtx5; + uint32_t dwInCtx6; + uint32_t dwInCtx7; }; struct xhci_input_dev_ctx { @@ -197,7 +197,7 @@ struct xhci_dev_ctx { #define ctx_ep ctx_dev_slep.u_ep struct xhci_stream_ctx { - volatile uint64_t qwSctx0; + uint64_t qwSctx0; #define XHCI_SCTX_0_DCS_GET(x) ((x) & 0x1) #define XHCI_SCTX_0_DCS_SET(x) ((x) & 0x1) #define XHCI_SCTX_0_SCT_SET(x) (((x) & 0x7) << 1) @@ -211,15 +211,15 @@ struct xhci_stream_ctx { #define XHCI_SCTX_0_SCT_PRIM_SSA_128 0x6 #define XHCI_SCTX_0_SCT_PRIM_SSA_256 0x7 #define XHCI_SCTX_0_TR_DQ_PTR_MASK 0xFFFFFFFFFFFFFFF0U - volatile uint32_t dwSctx2; - volatile uint32_t dwSctx3; + uint32_t dwSctx2; + uint32_t dwSctx3; }; struct xhci_trb { - volatile uint64_t qwTrb0; + uint64_t qwTrb0; #define XHCI_TRB_0_DIR_IN_MASK (0x80ULL << 0) #define XHCI_TRB_0_WLENGTH_MASK (0xFFFFULL << 48) - volatile uint32_t dwTrb2; + uint32_t dwTrb2; #define XHCI_TRB_2_ERROR_GET(x) (((x) >> 24) & 0xFF) #define XHCI_TRB_2_ERROR_SET(x) (((x) & 0xFF) << 24) #define XHCI_TRB_2_TDSZ_GET(x) (((x) >> 17) & 0x1F) @@ -233,7 +233,7 @@ struct xhci_trb { #define XHCI_TRB_2_STREAM_GET(x) (((x) >> 16) & 0xFFFF) #define XHCI_TRB_2_STREAM_SET(x) (((x) & 0xFFFF) << 16) - volatile uint32_t dwTrb3; + uint32_t dwTrb3; #define XHCI_TRB_3_TYPE_GET(x) (((x) >> 10) & 0x3F) #define XHCI_TRB_3_TYPE_SET(x) (((x) & 0x3F) << 10) #define XHCI_TRB_3_CYCLE_BIT (1U << 0) @@ -347,9 +347,9 @@ struct xhci_dev_endpoint_trbs { }; struct xhci_event_ring_seg { - volatile uint64_t qwEvrsTablePtr; - volatile uint32_t dwEvrsTableSize; - volatile uint32_t dwEvrsReserved; + uint64_t qwEvrsTablePtr; + uint32_t dwEvrsTableSize; + uint32_t dwEvrsReserved; }; #endif /* _PCI_XHCI_H_ */ diff --git a/usr/src/cmd/bhyve/pctestdev.c b/usr/src/cmd/bhyve/pctestdev.c index 49e03b2a43..8b810e641b 100644 --- a/usr/src/cmd/bhyve/pctestdev.c +++ b/usr/src/cmd/bhyve/pctestdev.c @@ -72,14 +72,14 @@ static bool pctestdev_inited; static uint8_t pctestdev_iomem_buf[IOMEM_LEN]; static uint32_t pctestdev_ioport_data; -static int pctestdev_debugexit_io(struct vmctx *ctx, int vcpu, int in, +static int pctestdev_debugexit_io(struct vmctx *ctx, int in, int port, int bytes, uint32_t *eax, void *arg); static int pctestdev_iomem_io(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, int size, uint64_t *val, void *arg1, long arg2); -static int pctestdev_ioport_io(struct vmctx *ctx, int vcpu, int in, +static int pctestdev_ioport_io(struct vmctx *ctx, int in, int port, int bytes, uint32_t *eax, void *arg); -static int pctestdev_irq_io(struct vmctx *ctx, int vcpu, int in, +static int pctestdev_irq_io(struct vmctx *ctx, int in, int port, int bytes, uint32_t *eax, void *arg); const char * @@ -178,8 +178,8 @@ fail: } static int -pctestdev_debugexit_io(struct vmctx *ctx, int vcpu, int in, int port, - int bytes, uint32_t *eax, void *arg) +pctestdev_debugexit_io(struct vmctx *ctx __unused, int in, + int port __unused, int bytes __unused, uint32_t *eax, void *arg __unused) { if (in) *eax = 0; @@ -190,8 +190,9 @@ pctestdev_debugexit_io(struct vmctx *ctx, int vcpu, int in, int port, } static int -pctestdev_iomem_io(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, - int size, uint64_t *val, void *arg1, long arg2) +pctestdev_iomem_io(struct vmctx *ctx __unused, int vcpu __unused, int dir, + uint64_t addr, int size, uint64_t *val, void *arg1 __unused, + long arg2 __unused) { uint64_t offset; @@ -210,8 +211,8 @@ pctestdev_iomem_io(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, } static int -pctestdev_ioport_io(struct vmctx *ctx, int vcpu, int in, int port, - int bytes, uint32_t *eax, void *arg) +pctestdev_ioport_io(struct vmctx *ctx __unused, int in, + int port, int bytes, uint32_t *eax, void *arg __unused) { uint32_t mask; int lsb; @@ -233,8 +234,8 @@ pctestdev_ioport_io(struct vmctx *ctx, int vcpu, int in, int port, } static int -pctestdev_irq_io(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +pctestdev_irq_io(struct vmctx *ctx, int in, int port, + int bytes, uint32_t *eax, void *arg __unused) { int irq; diff --git a/usr/src/cmd/bhyve/pm.c b/usr/src/cmd/bhyve/pm.c index d2732242f9..5bfbe5d848 100644 --- a/usr/src/cmd/bhyve/pm.c +++ b/usr/src/cmd/bhyve/pm.c @@ -73,8 +73,8 @@ static const unsigned gpe0_valid = (1u << GPE_VMGENC); * reset. */ static int -reset_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +reset_handler(struct vmctx *ctx __unused, int in, + int port __unused, int bytes, uint32_t *eax, void *arg __unused) { int error; @@ -171,8 +171,8 @@ sci_update(struct vmctx *ctx) } static int -pm1_status_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +pm1_status_handler(struct vmctx *ctx, int in, + int port __unused, int bytes, uint32_t *eax, void *arg __unused) { if (bytes != 2) @@ -195,8 +195,8 @@ pm1_status_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, } static int -pm1_enable_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +pm1_enable_handler(struct vmctx *ctx, int in, + int port __unused, int bytes, uint32_t *eax, void *arg __unused) { if (bytes != 2) @@ -222,7 +222,7 @@ INOUT_PORT(pm1_enable, PM1A_EVT_ADDR + 2, IOPORT_F_INOUT, pm1_enable_handler); #ifdef __FreeBSD__ static void -power_button_handler(int signal, enum ev_type type, void *arg) +power_button_handler(int signal __unused, enum ev_type type __unused, void *arg) { struct vmctx *ctx; @@ -278,8 +278,8 @@ static uint16_t pm1_control; #define PM1_ALWAYS_ZERO 0xc003 static int -pm1_control_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +pm1_control_handler(struct vmctx *ctx, int in, + int port __unused, int bytes, uint32_t *eax, void *arg __unused) { int error; @@ -330,8 +330,8 @@ acpi_raise_gpe(struct vmctx *ctx, unsigned bit) } static int -gpe0_sts(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +gpe0_sts(struct vmctx *ctx, int in, int port __unused, + int bytes, uint32_t *eax, void *arg __unused) { /* * ACPI 6.2 specifies the GPE register blocks are accessed @@ -354,8 +354,8 @@ gpe0_sts(struct vmctx *ctx, int vcpu, int in, int port, int bytes, INOUT_PORT(gpe0_sts, IO_GPE0_STS, IOPORT_F_INOUT, gpe0_sts); static int -gpe0_en(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +gpe0_en(struct vmctx *ctx, int in, int port __unused, + int bytes, uint32_t *eax, void *arg __unused) { if (bytes != 1) return (-1); @@ -378,8 +378,8 @@ INOUT_PORT(gpe0_en, IO_GPE0_EN, IOPORT_F_INOUT, gpe0_en); * This write-only register is used to enable and disable ACPI. */ static int -smi_cmd_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +smi_cmd_handler(struct vmctx *ctx, int in, int port __unused, + int bytes, uint32_t *eax, void *arg __unused) { assert(!in); diff --git a/usr/src/cmd/bhyve/post.c b/usr/src/cmd/bhyve/post.c index d3040a8df7..69cf5cf39d 100644 --- a/usr/src/cmd/bhyve/post.c +++ b/usr/src/cmd/bhyve/post.c @@ -39,8 +39,8 @@ __FBSDID("$FreeBSD$"); #include "pci_lpc.h" static int -post_data_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +post_data_handler(struct vmctx *ctx __unused, int in, + int port __unused, int bytes, uint32_t *eax, void *arg __unused) { assert(in == 1); diff --git a/usr/src/cmd/bhyve/ps2kbd.c b/usr/src/cmd/bhyve/ps2kbd.c index 1abf0ece81..d7ff5688d5 100644 --- a/usr/src/cmd/bhyve/ps2kbd.c +++ b/usr/src/cmd/bhyve/ps2kbd.c @@ -43,11 +43,12 @@ __FBSDID("$FreeBSD$"); #include #include -#include "bhyverun.h" #include "atkbdc.h" -#include "debug.h" +#include "bhyverun.h" #include "config.h" #include "console.h" +#include "debug.h" +#include "ps2kbd.h" /* keyboard device commands */ #define PS2KC_RESET_DEV 0xff @@ -97,10 +98,10 @@ struct extended_translation { * FIXME: Pause/break and Print Screen/SysRq require special handling. */ static struct extended_translation extended_translations[128] = { - {0xff08, 0x66}, /* Back space */ - {0xff09, 0x0d}, /* Tab */ - {0xff0d, 0x5a}, /* Return */ - {0xff1b, 0x76}, /* Escape */ + {0xff08, 0x66, 0}, /* Back space */ + {0xff09, 0x0d, 0}, /* Tab */ + {0xff0d, 0x5a, 0}, /* Return */ + {0xff1b, 0x76, 0}, /* Escape */ {0xff50, 0x6c, SCANCODE_E0_PREFIX}, /* Home */ {0xff51, 0x6b, SCANCODE_E0_PREFIX}, /* Left arrow */ {0xff52, 0x75, SCANCODE_E0_PREFIX}, /* Up arrow */ @@ -111,59 +112,59 @@ static struct extended_translation extended_translations[128] = { {0xff57, 0x69, SCANCODE_E0_PREFIX}, /* End */ {0xff63, 0x70, SCANCODE_E0_PREFIX}, /* Ins */ {0xff8d, 0x5a, SCANCODE_E0_PREFIX}, /* Keypad Enter */ - {0xffe1, 0x12}, /* Left shift */ - {0xffe2, 0x59}, /* Right shift */ - {0xffe3, 0x14}, /* Left control */ + {0xffe1, 0x12, 0}, /* Left shift */ + {0xffe2, 0x59, 0}, /* Right shift */ + {0xffe3, 0x14, 0}, /* Left control */ {0xffe4, 0x14, SCANCODE_E0_PREFIX}, /* Right control */ /* {0xffe7, XXX}, Left meta */ /* {0xffe8, XXX}, Right meta */ - {0xffe9, 0x11}, /* Left alt */ + {0xffe9, 0x11, 0}, /* Left alt */ {0xfe03, 0x11, SCANCODE_E0_PREFIX}, /* AltGr */ {0xffea, 0x11, SCANCODE_E0_PREFIX}, /* Right alt */ {0xffeb, 0x1f, SCANCODE_E0_PREFIX}, /* Left Windows */ {0xffec, 0x27, SCANCODE_E0_PREFIX}, /* Right Windows */ - {0xffbe, 0x05}, /* F1 */ - {0xffbf, 0x06}, /* F2 */ - {0xffc0, 0x04}, /* F3 */ - {0xffc1, 0x0c}, /* F4 */ - {0xffc2, 0x03}, /* F5 */ - {0xffc3, 0x0b}, /* F6 */ - {0xffc4, 0x83}, /* F7 */ - {0xffc5, 0x0a}, /* F8 */ - {0xffc6, 0x01}, /* F9 */ - {0xffc7, 0x09}, /* F10 */ - {0xffc8, 0x78}, /* F11 */ - {0xffc9, 0x07}, /* F12 */ + {0xffbe, 0x05, 0}, /* F1 */ + {0xffbf, 0x06, 0}, /* F2 */ + {0xffc0, 0x04, 0}, /* F3 */ + {0xffc1, 0x0c, 0}, /* F4 */ + {0xffc2, 0x03, 0}, /* F5 */ + {0xffc3, 0x0b, 0}, /* F6 */ + {0xffc4, 0x83, 0}, /* F7 */ + {0xffc5, 0x0a, 0}, /* F8 */ + {0xffc6, 0x01, 0}, /* F9 */ + {0xffc7, 0x09, 0}, /* F10 */ + {0xffc8, 0x78, 0}, /* F11 */ + {0xffc9, 0x07, 0}, /* F12 */ {0xffff, 0x71, SCANCODE_E0_PREFIX}, /* Del */ - {0xff14, 0x7e}, /* ScrollLock */ + {0xff14, 0x7e, 0}, /* ScrollLock */ /* NumLock and Keypads*/ - {0xff7f, 0x77}, /* NumLock */ + {0xff7f, 0x77, 0}, /* NumLock */ {0xffaf, 0x4a, SCANCODE_E0_PREFIX}, /* Keypad slash */ - {0xffaa, 0x7c}, /* Keypad asterisk */ - {0xffad, 0x7b}, /* Keypad minus */ - {0xffab, 0x79}, /* Keypad plus */ - {0xffb7, 0x6c}, /* Keypad 7 */ - {0xff95, 0x6c}, /* Keypad home */ - {0xffb8, 0x75}, /* Keypad 8 */ - {0xff97, 0x75}, /* Keypad up arrow */ - {0xffb9, 0x7d}, /* Keypad 9 */ - {0xff9a, 0x7d}, /* Keypad PgUp */ - {0xffb4, 0x6b}, /* Keypad 4 */ - {0xff96, 0x6b}, /* Keypad left arrow */ - {0xffb5, 0x73}, /* Keypad 5 */ - {0xff9d, 0x73}, /* Keypad empty */ - {0xffb6, 0x74}, /* Keypad 6 */ - {0xff98, 0x74}, /* Keypad right arrow */ - {0xffb1, 0x69}, /* Keypad 1 */ - {0xff9c, 0x69}, /* Keypad end */ - {0xffb2, 0x72}, /* Keypad 2 */ - {0xff99, 0x72}, /* Keypad down arrow */ - {0xffb3, 0x7a}, /* Keypad 3 */ - {0xff9b, 0x7a}, /* Keypad PgDown */ - {0xffb0, 0x70}, /* Keypad 0 */ - {0xff9e, 0x70}, /* Keypad ins */ - {0xffae, 0x71}, /* Keypad . */ - {0xff9f, 0x71}, /* Keypad del */ + {0xffaa, 0x7c, 0}, /* Keypad asterisk */ + {0xffad, 0x7b, 0}, /* Keypad minus */ + {0xffab, 0x79, 0}, /* Keypad plus */ + {0xffb7, 0x6c, 0}, /* Keypad 7 */ + {0xff95, 0x6c, 0}, /* Keypad home */ + {0xffb8, 0x75, 0}, /* Keypad 8 */ + {0xff97, 0x75, 0}, /* Keypad up arrow */ + {0xffb9, 0x7d, 0}, /* Keypad 9 */ + {0xff9a, 0x7d, 0}, /* Keypad PgUp */ + {0xffb4, 0x6b, 0}, /* Keypad 4 */ + {0xff96, 0x6b, 0}, /* Keypad left arrow */ + {0xffb5, 0x73, 0}, /* Keypad 5 */ + {0xff9d, 0x73, 0}, /* Keypad empty */ + {0xffb6, 0x74, 0}, /* Keypad 6 */ + {0xff98, 0x74, 0}, /* Keypad right arrow */ + {0xffb1, 0x69, 0}, /* Keypad 1 */ + {0xff9c, 0x69, 0}, /* Keypad end */ + {0xffb2, 0x72, 0}, /* Keypad 2 */ + {0xff99, 0x72, 0}, /* Keypad down arrow */ + {0xffb3, 0x7a, 0}, /* Keypad 3 */ + {0xff9b, 0x7a, 0}, /* Keypad PgDown */ + {0xffb0, 0x70, 0}, /* Keypad 0 */ + {0xff9e, 0x70, 0}, /* Keypad ins */ + {0xffae, 0x71, 0}, /* Keypad . */ + {0xff9f, 0x71, 0}, /* Keypad del */ {0, 0, 0} /* Terminator */ }; @@ -188,7 +189,7 @@ static uint8_t ascii_translations[128] = { }; /* ScanCode set1 to set2 lookup table */ -const uint8_t keyset1to2_translations[128] = { +static const uint8_t keyset1to2_translations[128] = { 0, 0x76, 0x16, 0x1E, 0x26, 0x25, 0x2e, 0x36, 0x3d, 0x3e, 0x46, 0x45, 0x4e, 0x55, 0x66, 0x0d, 0x15, 0x1d, 0x24, 0x2d, 0x2c, 0x35, 0x3c, 0x43, @@ -343,10 +344,11 @@ static void ps2kbd_keysym_queue(struct ps2kbd_softc *sc, int down, uint32_t keysym, uint32_t keycode) { - assert(pthread_mutex_isowned_np(&sc->mtx)); + const struct extended_translation *trans; int e0_prefix, found; uint8_t code; - struct extended_translation *trans; + + assert(pthread_mutex_isowned_np(&sc->mtx)); if (keycode) { code = keyset1to2_translations[(uint8_t)(keycode & 0x7f)]; @@ -359,8 +361,8 @@ ps2kbd_keysym_queue(struct ps2kbd_softc *sc, e0_prefix = 0; found = 1; } else { - for (trans = &(extended_translations[0]); trans->keysym != 0; - trans++) { + for (trans = &extended_translations[0]; + trans->keysym != 0; trans++) { if (keysym == trans->keysym) { code = trans->scancode; e0_prefix = trans->flags & SCANCODE_E0_PREFIX; @@ -407,10 +409,10 @@ ps2kbd_update_extended_translation(uint32_t keycode, uint32_t scancode, uint32_t { int i = 0; - do { + do { if (extended_translations[i].keysym == keycode) break; - } while(extended_translations[++i].keysym); + } while (extended_translations[++i].keysym); if (i == (sizeof(extended_translations) / sizeof(struct extended_translation) - 1)) return; @@ -435,7 +437,7 @@ ps2kbd_setkbdlayout(void) char path[MAX_PATHNAME]; char *buf, *next, *line; struct stat sb; - size_t sz; + ssize_t sz; uint8_t ascii; uint32_t keycode, scancode, prefix; @@ -453,11 +455,11 @@ ps2kbd_setkbdlayout(void) if (fd == -1) goto out; - sz = read(fd, buf, sb.st_size ); + sz = read(fd, buf, sb.st_size); close(fd); - if (sz != sb.st_size ) + if (sz < 0 || sz != sb.st_size) goto out; next = buf; diff --git a/usr/src/cmd/bhyve/ps2mouse.c b/usr/src/cmd/bhyve/ps2mouse.c index f42d2e7260..b2b4f25f7e 100644 --- a/usr/src/cmd/bhyve/ps2mouse.c +++ b/usr/src/cmd/bhyve/ps2mouse.c @@ -41,8 +41,9 @@ __FBSDID("$FreeBSD$"); #include #include "atkbdc.h" -#include "debug.h" #include "console.h" +#include "debug.h" +#include "ps2mouse.h" /* mouse device commands */ #define PS2MC_RESET_DEV 0xff diff --git a/usr/src/cmd/bhyve/rtc.c b/usr/src/cmd/bhyve/rtc.c index 9125b4f86a..3c0429e547 100644 --- a/usr/src/cmd/bhyve/rtc.c +++ b/usr/src/cmd/bhyve/rtc.c @@ -60,7 +60,7 @@ __FBSDID("$FreeBSD$"); * Returns the current RTC time as number of seconds since 00:00:00 Jan 1, 1970 */ static time_t -rtc_time(struct vmctx *ctx) +rtc_time(void) { struct tm tm; time_t t; @@ -102,7 +102,7 @@ rtc_init(struct vmctx *ctx) err = vm_rtc_write(ctx, RTC_HMEM_MSB, himem >> 16); assert(err == 0); - err = vm_rtc_settime(ctx, rtc_time(ctx)); + err = vm_rtc_settime(ctx, rtc_time()); assert(err == 0); } diff --git a/usr/src/cmd/bhyve/smbiostbl.c b/usr/src/cmd/bhyve/smbiostbl.c index fc0d69e9fc..fc2d8060ec 100644 --- a/usr/src/cmd/bhyve/smbiostbl.c +++ b/usr/src/cmd/bhyve/smbiostbl.c @@ -86,14 +86,14 @@ struct smbios_string { const char *value; }; -typedef int (*initializer_func_t)(struct smbios_structure *template_entry, - struct smbios_string *template_strings, char *curaddr, char **endaddr, - uint16_t *n, uint16_t *size); +typedef int (*initializer_func_t)(const struct smbios_structure *template_entry, + const struct smbios_string *template_strings, char *curaddr, char **endaddr, + uint16_t *n); struct smbios_template_entry { - struct smbios_structure *entry; - struct smbios_string *strings; - initializer_func_t initializer; + const struct smbios_structure *entry; + const struct smbios_string *strings; + initializer_func_t initializer; }; /* @@ -344,7 +344,7 @@ struct smbios_table_type127 { struct smbios_structure header; } __packed; -struct smbios_table_type0 smbios_type0_template = { +static const struct smbios_table_type0 smbios_type0_template = { { SMBIOS_TYPE_BIOS, sizeof (struct smbios_table_type0), 0 }, 1, /* bios vendor string */ 2, /* bios version string */ @@ -360,14 +360,14 @@ struct smbios_table_type0 smbios_type0_template = { 0xff /* embedded controller firmware minor release */ }; -struct smbios_string smbios_type0_strings[] = { +static const struct smbios_string smbios_type0_strings[] = { { "bios.vendor", "BHYVE" }, /* vendor string */ { "bios.version", FIRMWARE_VERSION }, /* bios version string */ { "bios.release_date", FIRMWARE_RELEASE_DATE }, /* bios release date string */ { 0 } }; -struct smbios_table_type1 smbios_type1_template = { +static const struct smbios_table_type1 smbios_type1_template = { { SMBIOS_TYPE_SYSTEM, sizeof (struct smbios_table_type1), 0 }, 1, /* manufacturer string */ 2, /* product string */ @@ -379,11 +379,11 @@ struct smbios_table_type1 smbios_type1_template = { 6 /* family string */ }; -static int smbios_type1_initializer(struct smbios_structure *template_entry, - struct smbios_string *template_strings, char *curaddr, char **endaddr, - uint16_t *n, uint16_t *size); +static int smbios_type1_initializer(const struct smbios_structure *template_entry, + const struct smbios_string *template_strings, char *curaddr, char **endaddr, + uint16_t *n); -struct smbios_string smbios_type1_strings[] = { +static const struct smbios_string smbios_type1_strings[] = { { "system.manufacturer", "illumos" }, /* manufacturer string */ { "system.product_name", "BHYVE" }, /* product string */ { "system.version", "1.0" }, /* version string */ @@ -393,7 +393,7 @@ struct smbios_string smbios_type1_strings[] = { { 0 } }; -struct smbios_table_type2 smbios_type2_template = { +static const struct smbios_table_type2 smbios_type2_template = { { SMBIOS_TYPE_BOARD, sizeof (struct smbios_table_type2), 0 }, 1, /* manufacturer string */ 2, /* product string */ @@ -407,7 +407,7 @@ struct smbios_table_type2 smbios_type2_template = { 0 }; -struct smbios_string smbios_type2_strings[] = { +static const struct smbios_string smbios_type2_strings[] = { { "board.manufacturer", "illumos" }, /* manufacturer string */ { "board.product_name", "BHYVE" }, /* product name string */ { "board.version", "1.0" }, /* version string */ @@ -417,7 +417,7 @@ struct smbios_string smbios_type2_strings[] = { { 0 } }; -struct smbios_table_type3 smbios_type3_template = { +static const struct smbios_table_type3 smbios_type3_template = { { SMBIOS_TYPE_CHASSIS, sizeof (struct smbios_table_type3), 0 }, 1, /* manufacturer string */ SMBIOS_CHT_UNKNOWN, @@ -436,7 +436,7 @@ struct smbios_table_type3 smbios_type3_template = { 5 /* sku number string */ }; -struct smbios_string smbios_type3_strings[] = { +static const struct smbios_string smbios_type3_strings[] = { { "chassis.manufacturer", "illumos" }, /* manufacturer string */ { "chassis.version", "1.0" }, /* version string */ { "chassis.serial_number", "None" }, /* serial number string */ @@ -445,7 +445,7 @@ struct smbios_string smbios_type3_strings[] = { { 0 } }; -struct smbios_table_type4 smbios_type4_template = { +static const struct smbios_table_type4 smbios_type4_template = { { SMBIOS_TYPE_PROCESSOR, sizeof (struct smbios_table_type4), 0 }, 1, /* socket designation string */ SMBIOS_PRT_CENTRAL, @@ -472,7 +472,7 @@ struct smbios_table_type4 smbios_type4_template = { SMBIOS_PRF_OTHER }; -struct smbios_string smbios_type4_strings[] = { +static const struct smbios_string smbios_type4_strings[] = { { NULL, " " }, /* socket designation string */ { NULL, " " }, /* manufacturer string */ { NULL, " " }, /* version string */ @@ -482,11 +482,12 @@ struct smbios_string smbios_type4_strings[] = { { 0 } }; -static int smbios_type4_initializer(struct smbios_structure *template_entry, - struct smbios_string *template_strings, char *curaddr, char **endaddr, - uint16_t *n, uint16_t *size); +static int smbios_type4_initializer( + const struct smbios_structure *template_entry, + const struct smbios_string *template_strings, char *curaddr, char **endaddr, + uint16_t *n); -struct smbios_table_type16 smbios_type16_template = { +static const struct smbios_table_type16 smbios_type16_template = { { SMBIOS_TYPE_MEMARRAY, sizeof (struct smbios_table_type16), 0 }, SMBIOS_MAL_SYSMB, SMBIOS_MAU_SYSTEM, @@ -497,11 +498,12 @@ struct smbios_table_type16 smbios_type16_template = { 0 /* extended maximum memory capacity in bytes (TBD) */ }; -static int smbios_type16_initializer(struct smbios_structure *template_entry, - struct smbios_string *template_strings, char *curaddr, char **endaddr, - uint16_t *n, uint16_t *size); +static int smbios_type16_initializer( + const struct smbios_structure *template_entry, + const struct smbios_string *template_strings, char *curaddr, char **endaddr, + uint16_t *n); -struct smbios_table_type17 smbios_type17_template = { +static const struct smbios_table_type17 smbios_type17_template = { { SMBIOS_TYPE_MEMDEVICE, sizeof (struct smbios_table_type17), 0 }, -1, /* handle of physical memory array */ -1, /* handle of memory error data */ @@ -527,7 +529,7 @@ struct smbios_table_type17 smbios_type17_template = { 0 /* configured voltage in mv (0=unknown) */ }; -struct smbios_string smbios_type17_strings[] = { +static const struct smbios_string smbios_type17_strings[] = { { NULL, " " }, /* device locator string */ { NULL, " " }, /* physical bank locator string */ { NULL, " " }, /* manufacturer string */ @@ -537,11 +539,12 @@ struct smbios_string smbios_type17_strings[] = { { 0 } }; -static int smbios_type17_initializer(struct smbios_structure *template_entry, - struct smbios_string *template_strings, char *curaddr, char **endaddr, - uint16_t *n, uint16_t *size); +static int smbios_type17_initializer( + const struct smbios_structure *template_entry, + const struct smbios_string *template_strings, char *curaddr, char **endaddr, + uint16_t *n); -struct smbios_table_type19 smbios_type19_template = { +static const struct smbios_table_type19 smbios_type19_template = { { SMBIOS_TYPE_MEMARRAYMAP, sizeof (struct smbios_table_type19), 0 }, 0xffffffff, /* starting phys addr in kb (0xffffffff=use ext) */ 0xffffffff, /* ending phys addr in kb (0xffffffff=use ext) */ @@ -551,53 +554,55 @@ struct smbios_table_type19 smbios_type19_template = { 0 /* extended ending phys addr in bytes (TDB) */ }; -static int smbios_type19_initializer(struct smbios_structure *template_entry, - struct smbios_string *template_strings, char *curaddr, char **endaddr, - uint16_t *n, uint16_t *size); +static int smbios_type19_initializer( + const struct smbios_structure *template_entry, + const struct smbios_string *template_strings, char *curaddr, char **endaddr, + uint16_t *n); -struct smbios_table_type32 smbios_type32_template = { +static struct smbios_table_type32 smbios_type32_template = { { SMBIOS_TYPE_BOOT, sizeof (struct smbios_table_type32), 0 }, { 0, 0, 0, 0, 0, 0 }, SMBIOS_BOOT_NORMAL }; -struct smbios_table_type127 smbios_type127_template = { +static const struct smbios_table_type127 smbios_type127_template = { { SMBIOS_TYPE_EOT, sizeof (struct smbios_table_type127), 0 } }; -static int smbios_generic_initializer(struct smbios_structure *template_entry, - struct smbios_string *template_strings, char *curaddr, char **endaddr, - uint16_t *n, uint16_t *size); +static int smbios_generic_initializer( + const struct smbios_structure *template_entry, + const struct smbios_string *template_strings, char *curaddr, char **endaddr, + uint16_t *n); static struct smbios_template_entry smbios_template[] = { - { (struct smbios_structure *)&smbios_type0_template, + { (const struct smbios_structure *)&smbios_type0_template, smbios_type0_strings, smbios_generic_initializer }, - { (struct smbios_structure *)&smbios_type1_template, + { (const struct smbios_structure *)&smbios_type1_template, smbios_type1_strings, smbios_type1_initializer }, - { (struct smbios_structure *)&smbios_type2_template, + { (const struct smbios_structure *)&smbios_type2_template, smbios_type2_strings, smbios_generic_initializer }, - { (struct smbios_structure *)&smbios_type3_template, + { (const struct smbios_structure *)&smbios_type3_template, smbios_type3_strings, smbios_generic_initializer }, - { (struct smbios_structure *)&smbios_type4_template, + { (const struct smbios_structure *)&smbios_type4_template, smbios_type4_strings, smbios_type4_initializer }, - { (struct smbios_structure *)&smbios_type16_template, + { (const struct smbios_structure *)&smbios_type16_template, NULL, smbios_type16_initializer }, - { (struct smbios_structure *)&smbios_type17_template, + { (const struct smbios_structure *)&smbios_type17_template, smbios_type17_strings, smbios_type17_initializer }, - { (struct smbios_structure *)&smbios_type19_template, + { (const struct smbios_structure *)&smbios_type19_template, NULL, smbios_type19_initializer }, - { (struct smbios_structure *)&smbios_type32_template, + { (const struct smbios_structure *)&smbios_type32_template, NULL, smbios_generic_initializer }, - { (struct smbios_structure *)&smbios_type127_template, + { (const struct smbios_structure *)&smbios_type127_template, NULL, smbios_generic_initializer }, { NULL,NULL, NULL } @@ -607,9 +612,9 @@ static uint64_t guest_lomem, guest_himem; static uint16_t type16_handle; static int -smbios_generic_initializer(struct smbios_structure *template_entry, - struct smbios_string *template_strings, char *curaddr, char **endaddr, - uint16_t *n, uint16_t *size) +smbios_generic_initializer(const struct smbios_structure *template_entry, + const struct smbios_string *template_strings, char *curaddr, char **endaddr, + uint16_t *n) { struct smbios_structure *entry; @@ -654,15 +659,15 @@ smbios_generic_initializer(struct smbios_structure *template_entry, } static int -smbios_type1_initializer(struct smbios_structure *template_entry, - struct smbios_string *template_strings, char *curaddr, char **endaddr, - uint16_t *n, uint16_t *size) +smbios_type1_initializer(const struct smbios_structure *template_entry, + const struct smbios_string *template_strings, char *curaddr, char **endaddr, + uint16_t *n) { struct smbios_table_type1 *type1; const char *guest_uuid_str; smbios_generic_initializer(template_entry, template_strings, - curaddr, endaddr, n, size); + curaddr, endaddr, n); type1 = (struct smbios_table_type1 *)curaddr; guest_uuid_str = get_config_value("uuid"); @@ -712,19 +717,19 @@ smbios_type1_initializer(struct smbios_structure *template_entry, } static int -smbios_type4_initializer(struct smbios_structure *template_entry, - struct smbios_string *template_strings, char *curaddr, char **endaddr, - uint16_t *n, uint16_t *size) +smbios_type4_initializer(const struct smbios_structure *template_entry, + const struct smbios_string *template_strings, char *curaddr, char **endaddr, + uint16_t *n) { int i; - for (i = 0; i < sockets; i++) { + for (i = 0; i < cpu_sockets; i++) { struct smbios_table_type4 *type4; char *p; int nstrings, len; smbios_generic_initializer(template_entry, template_strings, - curaddr, endaddr, n, size); + curaddr, endaddr, n); type4 = (struct smbios_table_type4 *)curaddr; p = curaddr + sizeof (struct smbios_table_type4); nstrings = 0; @@ -738,15 +743,15 @@ smbios_type4_initializer(struct smbios_structure *template_entry, (*endaddr)++; type4->socket = nstrings + 1; /* Revise cores and threads after update to smbios 3.0 */ - if (cores > 254) + if (cpu_cores > 254) type4->cores = 0; else - type4->cores = cores; + type4->cores = cpu_cores; /* This threads is total threads in a socket */ - if ((cores * threads) > 254) + if (cpu_cores * cpu_threads > 254) type4->threads = 0; else - type4->threads = (cores * threads); + type4->threads = cpu_cores * cpu_threads; curaddr = *endaddr; } @@ -754,15 +759,15 @@ smbios_type4_initializer(struct smbios_structure *template_entry, } static int -smbios_type16_initializer(struct smbios_structure *template_entry, - struct smbios_string *template_strings, char *curaddr, char **endaddr, - uint16_t *n, uint16_t *size) +smbios_type16_initializer(const struct smbios_structure *template_entry, + const struct smbios_string *template_strings, char *curaddr, char **endaddr, + uint16_t *n) { struct smbios_table_type16 *type16; type16_handle = *n; smbios_generic_initializer(template_entry, template_strings, - curaddr, endaddr, n, size); + curaddr, endaddr, n); type16 = (struct smbios_table_type16 *)curaddr; type16->xsize = guest_lomem + guest_himem; type16->ndevs = guest_himem > 0 ? 2 : 1; @@ -771,15 +776,15 @@ smbios_type16_initializer(struct smbios_structure *template_entry, } static int -smbios_type17_initializer(struct smbios_structure *template_entry, - struct smbios_string *template_strings, char *curaddr, char **endaddr, - uint16_t *n, uint16_t *size) +smbios_type17_initializer(const struct smbios_structure *template_entry, + const struct smbios_string *template_strings, char *curaddr, char **endaddr, + uint16_t *n) { struct smbios_table_type17 *type17; uint64_t memsize, size_KB, size_MB; smbios_generic_initializer(template_entry, template_strings, - curaddr, endaddr, n, size); + curaddr, endaddr, n); type17 = (struct smbios_table_type17 *)curaddr; type17->arrayhand = type16_handle; @@ -815,14 +820,14 @@ smbios_type17_initializer(struct smbios_structure *template_entry, } static int -smbios_type19_initializer(struct smbios_structure *template_entry, - struct smbios_string *template_strings, char *curaddr, char **endaddr, - uint16_t *n, uint16_t *size) +smbios_type19_initializer(const struct smbios_structure *template_entry, + const struct smbios_string *template_strings, char *curaddr, char **endaddr, + uint16_t *n) { struct smbios_table_type19 *type19; smbios_generic_initializer(template_entry, template_strings, - curaddr, endaddr, n, size); + curaddr, endaddr, n); type19 = (struct smbios_table_type19 *)curaddr; type19->arrayhand = type16_handle; type19->xsaddr = 0; @@ -831,7 +836,7 @@ smbios_type19_initializer(struct smbios_structure *template_entry, if (guest_himem > 0) { curaddr = *endaddr; smbios_generic_initializer(template_entry, template_strings, - curaddr, endaddr, n, size); + curaddr, endaddr, n); type19 = (struct smbios_table_type19 *)curaddr; type19->arrayhand = type16_handle; type19->xsaddr = 4*GB; @@ -945,24 +950,24 @@ smbios_build(struct vmctx *ctx) n = 0; maxssize = 0; for (i = 0; smbios_template[i].entry != NULL; i++) { - struct smbios_structure *entry; - struct smbios_string *strings; + const struct smbios_structure *entry; + const struct smbios_string *strings; initializer_func_t initializer; char *endaddr; - uint16_t size; + size_t size; entry = smbios_template[i].entry; strings = smbios_template[i].strings; initializer = smbios_template[i].initializer; - err = (*initializer)(entry, strings, curaddr, &endaddr, - &n, &size); + err = (*initializer)(entry, strings, curaddr, &endaddr, &n); if (err != 0) return (err); + size = endaddr - curaddr; + assert(size <= UINT16_MAX); if (size > maxssize) - maxssize = size; - + maxssize = (uint16_t)size; curaddr = endaddr; } @@ -983,7 +988,7 @@ static struct { { 1, "family", "family_name" }, }; -static struct smbios_string *smbios_tbl_map[] = { +static const struct smbios_string *smbios_tbl_map[] = { smbios_type0_strings, smbios_type1_strings, smbios_type2_strings, @@ -1003,7 +1008,7 @@ smbios_parse(const char *opts) { char *buf, *lasts, *token, *typekey = NULL; const char *errstr; - struct smbios_string *tbl; + const struct smbios_string *tbl; nvlist_t *nvl; uint_t i; long type; diff --git a/usr/src/cmd/bhyve/spinup_ap.c b/usr/src/cmd/bhyve/spinup_ap.c index 96eef44bcf..9b82e41754 100644 --- a/usr/src/cmd/bhyve/spinup_ap.c +++ b/usr/src/cmd/bhyve/spinup_ap.c @@ -58,21 +58,20 @@ __FBSDID("$FreeBSD$"); #ifdef __FreeBSD__ static void -spinup_ap_realmode(struct vmctx *ctx, int newcpu, uint64_t *rip) +spinup_ap_realmode(struct vmctx *ctx, int newcpu, uint64_t rip) { int vector, error; uint16_t cs; uint64_t desc_base; uint32_t desc_limit, desc_access; - vector = *rip >> PAGE_SHIFT; - *rip = 0; + vector = rip >> PAGE_SHIFT; /* * Update the %cs and %rip of the guest so that it starts * executing real mode code at at 'vector << 12'. */ - error = vm_set_register(ctx, newcpu, VM_REG_GUEST_RIP, *rip); + error = vm_set_register(ctx, newcpu, VM_REG_GUEST_RIP, 0); assert(error == 0); error = vm_get_desc(ctx, newcpu, VM_REG_GUEST_CS, &desc_base, @@ -88,38 +87,10 @@ spinup_ap_realmode(struct vmctx *ctx, int newcpu, uint64_t *rip) error = vm_set_register(ctx, newcpu, VM_REG_GUEST_CS, cs); assert(error == 0); } +#endif /* __FreeBSD__ */ -int -spinup_ap(struct vmctx *ctx, int vcpu, int newcpu, uint64_t rip) -{ - int error; - - assert(newcpu != 0); - assert(newcpu < guest_ncpus); - - error = vcpu_reset(ctx, newcpu); - assert(error == 0); - - fbsdrun_set_capabilities(ctx, newcpu); - - /* - * Enable the 'unrestricted guest' mode for 'newcpu'. - * - * Set up the processor state in power-on 16-bit mode, with the CS:IP - * init'd to the specified low-mem 4K page. - */ - error = vm_set_capability(ctx, newcpu, VM_CAP_UNRESTRICTED_GUEST, 1); - assert(error == 0); - - spinup_ap_realmode(ctx, newcpu, &rip); - - fbsdrun_addcpu(ctx, vcpu, newcpu, rip); - - return (newcpu); -} -#else /* __FreeBSD__ */ void -spinup_halted_ap(struct vmctx *ctx, int newcpu) +spinup_ap(struct vmctx *ctx, int newcpu, uint64_t rip) { int error; @@ -129,11 +100,9 @@ spinup_halted_ap(struct vmctx *ctx, int newcpu) error = vcpu_reset(ctx, newcpu); assert(error == 0); - fbsdrun_set_capabilities(ctx, newcpu); +#ifdef __FreeBSD__ + spinup_ap_realmode(ctx, newcpu, rip); - error = vm_set_run_state(ctx, newcpu, VRS_HALT, 0); - assert(error == 0); - - fbsdrun_addcpu(ctx, newcpu, 0, false); + vm_resume_cpu(ctx, newcpu); +#endif } -#endif /* __FreeBSD__ */ diff --git a/usr/src/cmd/bhyve/spinup_ap.h b/usr/src/cmd/bhyve/spinup_ap.h index bce4f3878c..ee201427c5 100644 --- a/usr/src/cmd/bhyve/spinup_ap.h +++ b/usr/src/cmd/bhyve/spinup_ap.h @@ -31,10 +31,6 @@ #ifndef _SPINUP_AP_H_ #define _SPINUP_AP_H_ -#ifdef __FreeBSD__ -int spinup_ap(struct vmctx *ctx, int vcpu, int newcpu, uint64_t rip); -#else -void spinup_halted_ap(struct vmctx *ctx, int newcpu); -#endif /* __FreeBSD__ */ +void spinup_ap(struct vmctx *ctx, int newcpu, uint64_t rip); #endif diff --git a/usr/src/cmd/bhyve/task_switch.c b/usr/src/cmd/bhyve/task_switch.c index c4a087b54f..4b2a464a7b 100644 --- a/usr/src/cmd/bhyve/task_switch.c +++ b/usr/src/cmd/bhyve/task_switch.c @@ -929,7 +929,7 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) minlimit = 0; assert(minlimit > 0); - if (nt.limit < minlimit) { + if (nt.limit < (unsigned int)minlimit) { sel_exception(ctx, vcpu, IDT_TS, nt_sel, ext); goto done; } diff --git a/usr/src/cmd/bhyve/uart_emul.c b/usr/src/cmd/bhyve/uart_emul.c index 2485c7ebb6..0965a7a51d 100644 --- a/usr/src/cmd/bhyve/uart_emul.c +++ b/usr/src/cmd/bhyve/uart_emul.c @@ -813,7 +813,7 @@ int uart_legacy_alloc(int which, int *baseaddr, int *irq) { - if (which < 0 || which >= UART_NLDEVS || uart_lres[which].inuse) + if (which < 0 || which >= (int)UART_NLDEVS || uart_lres[which].inuse) return (-1); uart_lres[which].inuse = true; diff --git a/usr/src/cmd/bhyve/usb_emul.h b/usr/src/cmd/bhyve/usb_emul.h index ede0fe0154..f84aee3ec7 100644 --- a/usr/src/cmd/bhyve/usb_emul.h +++ b/usr/src/cmd/bhyve/usb_emul.h @@ -53,7 +53,7 @@ struct usb_data_xfer; /* Device emulation handlers */ struct usb_devemu { - char *ue_emu; /* name of device emulation */ + const char *ue_emu; /* name of device emulation */ int ue_usbver; /* usb version: 2 or 3 */ int ue_usbspeed; /* usb device speed */ diff --git a/usr/src/cmd/bhyve/usb_mouse.c b/usr/src/cmd/bhyve/usb_mouse.c index 21e8873c5f..50cdfb7024 100644 --- a/usr/src/cmd/bhyve/usb_mouse.c +++ b/usr/src/cmd/bhyve/usb_mouse.c @@ -216,7 +216,7 @@ struct umouse_bos_desc { } __packed; -struct umouse_bos_desc umouse_bosd = { +static struct umouse_bos_desc umouse_bosd = { .bosd = { .bLength = sizeof(umouse_bosd.bosd), .bDescriptorType = UDESC_BOS, @@ -793,7 +793,7 @@ umouse_stop(void *scarg) } -struct usb_devemu ue_mouse = { +static struct usb_devemu ue_mouse = { .ue_emu = "tablet", .ue_usbver = 3, .ue_usbspeed = USB_SPEED_HIGH, diff --git a/usr/src/cmd/bhyve/vga.c b/usr/src/cmd/bhyve/vga.c index 314ddeb1e8..07dd5e4d71 100644 --- a/usr/src/cmd/bhyve/vga.c +++ b/usr/src/cmd/bhyve/vga.c @@ -1238,8 +1238,8 @@ vga_port_out_handler(struct vmctx *ctx, int in, int port, int bytes, } static int -vga_port_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, - uint32_t *eax, void *arg) +vga_port_handler(struct vmctx *ctx, int in, int port, + int bytes, uint32_t *eax, void *arg) { uint8_t val; int error; diff --git a/usr/src/cmd/bhyve/virtio.c b/usr/src/cmd/bhyve/virtio.c index 01a532cde5..e8d1eca2d5 100644 --- a/usr/src/cmd/bhyve/virtio.c +++ b/usr/src/cmd/bhyve/virtio.c @@ -215,10 +215,9 @@ vi_vq_init(struct virtio_softc *vs, uint32_t pfn) * descriptor. */ static inline void -_vq_record(int i, volatile struct vring_desc *vd, - struct vmctx *ctx, struct iovec *iov, int n_iov, - struct vi_req *reqp) { - +_vq_record(int i, struct vring_desc *vd, struct vmctx *ctx, struct iovec *iov, + int n_iov, struct vi_req *reqp) +{ if (i >= n_iov) return; iov[i].iov_base = paddr_guest2host(ctx, vd->addr, vd->len); @@ -272,7 +271,7 @@ vq_getchain(struct vqueue_info *vq, struct iovec *iov, int niov, u_int ndesc, n_indir; u_int idx, next; struct vi_req req; - volatile struct vring_desc *vdir, *vindir, *vp; + struct vring_desc *vdir, *vindir, *vp; struct vmctx *ctx; struct virtio_softc *vs; const char *name; @@ -410,8 +409,8 @@ vq_retchains(struct vqueue_info *vq, uint16_t n_chains) void vq_relchain_prepare(struct vqueue_info *vq, uint16_t idx, uint32_t iolen) { - volatile struct vring_used *vuh; - volatile struct vring_used_elem *vue; + struct vring_used *vuh; + struct vring_used_elem *vue; uint16_t mask; /* @@ -560,8 +559,8 @@ vi_find_cr(int offset) { * Otherwise dispatch to the actual driver. */ uint64_t -vi_pci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size) +vi_pci_read(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size) { struct virtio_softc *vs = pi->pi_arg; struct virtio_consts *vc; @@ -680,8 +679,9 @@ done: * Otherwise dispatch to the actual driver. */ void -vi_pci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size, uint64_t value) +vi_pci_write(struct vmctx *ctx __unused, + struct pci_devinst *pi, int baridx, uint64_t offset, int size, + uint64_t value) { struct virtio_softc *vs = pi->pi_arg; struct vqueue_info *vq; @@ -773,7 +773,7 @@ bad: vs->vs_curq = value; break; case VIRTIO_PCI_QUEUE_NOTIFY: - if (value >= vc->vc_nvq) { + if (value >= (unsigned int)vc->vc_nvq) { EPRINTLN("%s: queue %d notify out of range", name, (int)value); goto done; diff --git a/usr/src/cmd/bhyve/virtio.h b/usr/src/cmd/bhyve/virtio.h index f14323cc4c..2220cc7492 100644 --- a/usr/src/cmd/bhyve/virtio.h +++ b/usr/src/cmd/bhyve/virtio.h @@ -312,14 +312,14 @@ struct vqueue_info { uint32_t vq_pfn; /* PFN of virt queue (not shifted!) */ - volatile struct vring_desc *vq_desc; /* descriptor array */ - volatile struct vring_avail *vq_avail; /* the "avail" ring */ - volatile struct vring_used *vq_used; /* the "used" ring */ + struct vring_desc *vq_desc; /* descriptor array */ + struct vring_avail *vq_avail; /* the "avail" ring */ + struct vring_used *vq_used; /* the "used" ring */ }; /* as noted above, these are sort of backwards, name-wise */ #define VQ_AVAIL_EVENT_IDX(vq) \ - (*(volatile uint16_t *)&(vq)->vq_used->ring[(vq)->vq_qsize]) + (*(uint16_t *)&(vq)->vq_used->ring[(vq)->vq_qsize]) #define VQ_USED_EVENT_IDX(vq) \ ((vq)->vq_avail->ring[(vq)->vq_qsize]) @@ -438,8 +438,8 @@ void vq_relchain_publish(struct vqueue_info *vq); void vq_relchain(struct vqueue_info *vq, uint16_t idx, uint32_t iolen); void vq_endchains(struct vqueue_info *vq, int used_all_avail); -uint64_t vi_pci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, +uint64_t vi_pci_read(struct vmctx *ctx, struct pci_devinst *pi, int baridx, uint64_t offset, int size); -void vi_pci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, +void vi_pci_write(struct vmctx *ctx, struct pci_devinst *pi, int baridx, uint64_t offset, int size, uint64_t value); #endif /* _BHYVE_VIRTIO_H_ */ diff --git a/usr/src/cmd/bhyve/xmsr.c b/usr/src/cmd/bhyve/xmsr.c index 1a91e4bbba..925235f0a0 100644 --- a/usr/src/cmd/bhyve/xmsr.c +++ b/usr/src/cmd/bhyve/xmsr.c @@ -122,6 +122,7 @@ emulate_rdmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t *val) case MSR_PP0_ENERGY_STATUS: case MSR_PP1_ENERGY_STATUS: case MSR_DRAM_ENERGY_STATUS: + case MSR_MISC_FEATURE_ENABLES: *val = 0; break; case MSR_RAPL_POWER_UNIT: diff --git a/usr/src/compat/bhyve/amd64/machine/specialreg.h b/usr/src/compat/bhyve/amd64/machine/specialreg.h index ead63aaaab..4bb42c0481 100644 --- a/usr/src/compat/bhyve/amd64/machine/specialreg.h +++ b/usr/src/compat/bhyve/amd64/machine/specialreg.h @@ -40,6 +40,8 @@ #undef CR4_PKE #undef CR4_FSGSBASE #undef CR4_PCIDE +#undef CR4_UMIP +#undef CR4_LA57 #endif /* _SYS_CONTROLREGS_H */ #ifdef _SYS_X86_ARCHEXT_H @@ -50,10 +52,15 @@ #undef IA32_ARCH_CAP_SKIP_L1DFL_VMENTRY #undef IA32_ARCH_CAP_SSB_NO #undef IA32_ARCH_CAP_MDS_NO +#undef IA32_ARCH_CAP_IF_PSCHANGE_MC_NO +#undef IA32_ARCH_CAP_TSX_CTRL +#undef IA32_ARCH_CAP_TAA_NO +#undef IA32_FLUSH_CMD_L1D #undef IA32_SPEC_CTRL_IBRS #undef IA32_SPEC_CTRL_STIBP #undef IA32_SPEC_CTRL_SSBD -#undef IA32_FLUSH_CMD_L1D +#undef IA32_TSX_CTRL_RTM_DISABLE +#undef IA32_TSX_CTRL_TSX_CPUID_CLEAR #undef MSR_IA32_SPEC_CTRL #undef MSR_IA32_PRED_CMD #endif /* _SYS_X86_ARCHEXT_H */ diff --git a/usr/src/contrib/bhyve/dev/nvme/nvme.h b/usr/src/contrib/bhyve/dev/nvme/nvme.h index 5820908f3c..bf088f09a4 100644 --- a/usr/src/contrib/bhyve/dev/nvme/nvme.h +++ b/usr/src/contrib/bhyve/dev/nvme/nvme.h @@ -580,9 +580,25 @@ enum nvme_critical_warning_state { #define NVME_SS_PAGE_SSTAT_GDE_SHIFT (8) #define NVME_SS_PAGE_SSTAT_GDE_MASK (0x1) +/* Features */ +/* Get Features */ +#define NVME_FEAT_GET_SEL_SHIFT (8) +#define NVME_FEAT_GET_SEL_MASK (0x7) +#define NVME_FEAT_GET_FID_SHIFT (0) +#define NVME_FEAT_GET_FID_MASK (0xff) + +/* Set Features */ +#define NVME_FEAT_SET_SV_SHIFT (31) +#define NVME_FEAT_SET_SV_MASK (0x1) +#define NVME_FEAT_SET_FID_SHIFT (0) +#define NVME_FEAT_SET_FID_MASK (0xff) + /* Helper macro to combine *_MASK and *_SHIFT defines */ #define NVMEB(name) (name##_MASK << name##_SHIFT) +/* Helper macro to extract value from x */ +#define NVMEV(name, x) (((x) >> name##_SHIFT) & name##_MASK) + /* CC register SHN field values */ enum shn_value { NVME_SHN_NORMAL = 0x1, @@ -2056,7 +2072,7 @@ void nvme_resv_status_swapbytes(struct nvme_resv_status *s __unused, size_t size __unused) { #ifndef _LITTLE_ENDIAN - u_int i, n; + size_t i, n; s->gen = le32toh(s->gen); n = (s->regctl[1] << 8) | s->regctl[0]; @@ -2074,7 +2090,7 @@ void nvme_resv_status_ext_swapbytes(struct nvme_resv_status_ext *s __unused, size_t size __unused) { #ifndef _LITTLE_ENDIAN - u_int i, n; + size_t i, n; s->gen = le32toh(s->gen); n = (s->regctl[1] << 8) | s->regctl[0]; diff --git a/usr/src/contrib/bhyve/x86/specialreg.h b/usr/src/contrib/bhyve/x86/specialreg.h index b170cf3981..0185317dbd 100644 --- a/usr/src/contrib/bhyve/x86/specialreg.h +++ b/usr/src/contrib/bhyve/x86/specialreg.h @@ -71,6 +71,8 @@ #define CR4_PCE 0x00000100 /* Performance monitoring counter enable */ #define CR4_FXSR 0x00000200 /* Fast FPU save/restore used by OS */ #define CR4_XMM 0x00000400 /* enable SIMD/MMX2 to use except 16 */ +#define CR4_UMIP 0x00000800 /* User Mode Instruction Prevention */ +#define CR4_LA57 0x00001000 /* Enable 5-level paging */ #define CR4_VMXE 0x00002000 /* enable VMX operation (Intel-specific) */ #define CR4_FSGSBASE 0x00010000 /* Enable FS/GS BASE accessing instructions */ #define CR4_PCIDE 0x00020000 /* Enable Context ID */ @@ -90,6 +92,7 @@ #define EFER_LMSLE 0x000002000 /* Long Mode Segment Limit Enable */ #define EFER_FFXSR 0x000004000 /* Fast FXSAVE/FSRSTOR */ #define EFER_TCE 0x000008000 /* Translation Cache Extension */ +#define EFER_MCOMMIT 0x00020000 /* Enable MCOMMIT (AMD) */ /* * Intel Extended Features registers @@ -183,21 +186,6 @@ #define CPUID2_RDRAND 0x40000000 #define CPUID2_HV 0x80000000 -/* - * Important bits in the Thermal and Power Management flags - * CPUID.6 EAX and ECX. - */ -#define CPUTPM1_SENSOR 0x00000001 -#define CPUTPM1_TURBO 0x00000002 -#define CPUTPM1_ARAT 0x00000004 -#define CPUTPM1_HWP 0x00000080 -#define CPUTPM1_HWP_NOTIFICATION 0x00000100 -#define CPUTPM1_HWP_ACTIVITY_WINDOW 0x00000200 -#define CPUTPM1_HWP_PERF_PREF 0x00000400 -#define CPUTPM1_HWP_PKG 0x00000800 -#define CPUTPM1_HWP_FLEXIBLE 0x00020000 -#define CPUTPM2_EFFREQ 0x00000001 - /* Intel Processor Trace CPUID. */ /* Leaf 0 ebx. */ @@ -293,6 +281,7 @@ ((((id) & CPUID_FAMILY) >> 8) + \ (((id) & CPUID_EXT_FAMILY) >> 20)) #endif +#define CPUID_TO_STEPPING(id) ((id) & CPUID_STEPPING) /* * CPUID instruction 1 ebx info @@ -326,10 +315,34 @@ #define MWAIT_INTRBREAK 0x00000001 /* - * CPUID instruction 6 ecx info + * CPUID leaf 6: Thermal and Power management. */ -#define CPUID_PERF_STAT 0x00000001 -#define CPUID_PERF_BIAS 0x00000008 +/* Eax. */ +#define CPUTPM1_SENSOR 0x00000001 +#define CPUTPM1_TURBO 0x00000002 +#define CPUTPM1_ARAT 0x00000004 +#define CPUTPM1_PLN 0x00000010 +#define CPUTPM1_ECMD 0x00000020 +#define CPUTPM1_PTM 0x00000040 +#define CPUTPM1_HWP 0x00000080 +#define CPUTPM1_HWP_NOTIFICATION 0x00000100 +#define CPUTPM1_HWP_ACTIVITY_WINDOW 0x00000200 +#define CPUTPM1_HWP_PERF_PREF 0x00000400 +#define CPUTPM1_HWP_PKG 0x00000800 +#define CPUTPM1_HDC 0x00002000 +#define CPUTPM1_TURBO30 0x00004000 +#define CPUTPM1_HWP_CAPABILITIES 0x00008000 +#define CPUTPM1_HWP_PECI_OVR 0x00010000 +#define CPUTPM1_HWP_FLEXIBLE 0x00020000 +#define CPUTPM1_HWP_FAST_MSR 0x00040000 +#define CPUTPM1_HWP_IGN_IDLE 0x00100000 + +/* Ebx. */ +#define CPUTPM_B_NSENSINTTHRESH 0x0000000f + +/* Ecx. */ +#define CPUID_PERF_STAT 0x00000001 +#define CPUID_PERF_BIAS 0x00000008 /* * CPUID instruction 0xb ebx info. @@ -375,6 +388,9 @@ #define AMDFEID_CLZERO 0x00000001 #define AMDFEID_IRPERF 0x00000002 #define AMDFEID_XSAVEERPTR 0x00000004 +#define AMDFEID_RDPRU 0x00000010 +#define AMDFEID_MCOMMIT 0x00000100 +#define AMDFEID_WBNOINVD 0x00000200 #define AMDFEID_IBPB 0x00001000 #define AMDFEID_IBRS 0x00004000 #define AMDFEID_STIBP 0x00008000 @@ -382,6 +398,7 @@ #define AMDFEID_IBRS_ALWAYSON 0x00010000 #define AMDFEID_STIBP_ALWAYSON 0x00020000 #define AMDFEID_PREFER_IBRS 0x00040000 +#define AMDFEID_PPIN 0x00800000 #define AMDFEID_SSBD 0x01000000 /* SSBD via MSRC001_011F instead of MSR 0x48: */ #define AMDFEID_VIRT_SSBD 0x02000000 @@ -419,7 +436,7 @@ #define CPUID_STDEXT_ADX 0x00080000 #define CPUID_STDEXT_SMAP 0x00100000 #define CPUID_STDEXT_AVX512IFMA 0x00200000 -#define CPUID_STDEXT_PCOMMIT 0x00400000 +/* Formerly PCOMMIT */ #define CPUID_STDEXT_CLFLUSHOPT 0x00800000 #define CPUID_STDEXT_CLWB 0x01000000 #define CPUID_STDEXT_PROCTRACE 0x02000000 @@ -445,11 +462,13 @@ #define CPUID_STDEXT2_VPCLMULQDQ 0x00000400 #define CPUID_STDEXT2_AVX512VNNI 0x00000800 #define CPUID_STDEXT2_AVX512BITALG 0x00001000 +#define CPUID_STDEXT2_TME 0x00002000 #define CPUID_STDEXT2_AVX512VPOPCNTDQ 0x00004000 +#define CPUID_STDEXT2_LA57 0x00010000 #define CPUID_STDEXT2_RDPID 0x00400000 #define CPUID_STDEXT2_CLDEMOTE 0x02000000 #define CPUID_STDEXT2_MOVDIRI 0x08000000 -#define CPUID_STDEXT2_MOVDIRI64B 0x10000000 +#define CPUID_STDEXT2_MOVDIR64B 0x10000000 #define CPUID_STDEXT2_ENQCMD 0x20000000 #define CPUID_STDEXT2_SGXLC 0x40000000 @@ -458,7 +477,9 @@ */ #define CPUID_STDEXT3_AVX5124VNNIW 0x00000004 #define CPUID_STDEXT3_AVX5124FMAPS 0x00000008 +#define CPUID_STDEXT3_FSRM 0x00000010 #define CPUID_STDEXT3_AVX512VP2INTERSECT 0x00000100 +#define CPUID_STDEXT3_MCUOPT 0x00000200 #define CPUID_STDEXT3_MD_CLEAR 0x00000400 #define CPUID_STDEXT3_TSXFA 0x00002000 #define CPUID_STDEXT3_PCONFIG 0x00040000 @@ -476,6 +497,13 @@ #define IA32_ARCH_CAP_SKIP_L1DFL_VMENTRY 0x00000008 #define IA32_ARCH_CAP_SSB_NO 0x00000010 #define IA32_ARCH_CAP_MDS_NO 0x00000020 +#define IA32_ARCH_CAP_IF_PSCHANGE_MC_NO 0x00000040 +#define IA32_ARCH_CAP_TSX_CTRL 0x00000080 +#define IA32_ARCH_CAP_TAA_NO 0x00000100 + +/* MSR IA32_TSX_CTRL bits */ +#define IA32_TSX_CTRL_RTM_DISABLE 0x00000001 +#define IA32_TSX_CTRL_TSX_CPUID_CLEAR 0x00000002 /* * CPUID manufacturers identifiers @@ -490,6 +518,7 @@ #define SIS_VENDOR_ID "SiS SiS SiS " #define TRANSMETA_VENDOR_ID "GenuineTMx86" #define UMC_VENDOR_ID "UMC UMC UMC " +#define HYGON_VENDOR_ID "HygonGenuine" /* * Model-specific registers for the i386 family @@ -528,6 +557,9 @@ #define MSR_BBL_CR_TRIG 0x11a #define MSR_BBL_CR_BUSY 0x11b #define MSR_BBL_CR_CTL3 0x11e +#define MSR_IA32_TSX_CTRL 0x122 +#define MSR_IA32_MCU_OPT_CTRL 0x123 +#define MSR_MISC_FEATURE_ENABLES 0x140 #define MSR_SYSENTER_CS_MSR 0x174 #define MSR_SYSENTER_ESP_MSR 0x175 #define MSR_SYSENTER_EIP_MSR 0x176 @@ -543,6 +575,7 @@ #define MSR_IA32_TEMPERATURE_TARGET 0x1a2 #define MSR_TURBO_RATIO_LIMIT 0x1ad #define MSR_TURBO_RATIO_LIMIT1 0x1ae +#define MSR_IA32_ENERGY_PERF_BIAS 0x1b0 #define MSR_DEBUGCTLMSR 0x1d9 #define MSR_LASTBRANCHFROMIP 0x1db #define MSR_LASTBRANCHTOIP 0x1dc @@ -576,6 +609,7 @@ #define MSR_MC4_STATUS 0x411 #define MSR_MC4_ADDR 0x412 #define MSR_MC4_MISC 0x413 +#define MSR_MCG_EXT_CTL 0x4d0 #define MSR_RAPL_POWER_UNIT 0x606 #define MSR_PKG_ENERGY_STATUS 0x611 #define MSR_DRAM_ENERGY_STATUS 0x619 @@ -738,6 +772,7 @@ #define IA32_FEATURE_CONTROL_LOCK 0x01 /* lock bit */ #define IA32_FEATURE_CONTROL_SMX_EN 0x02 /* enable VMX inside SMX */ #define IA32_FEATURE_CONTROL_VMX_EN 0x04 /* enable VMX outside SMX */ +#define IA32_FEATURE_CONTROL_LMCE_EN 0x100000 /* enable local MCE */ /* MSR IA32_MISC_ENABLE */ #define IA32_MISC_EN_FASTSTR 0x0000000000000001ULL @@ -769,6 +804,9 @@ /* MSR IA32_FLUSH_CMD */ #define IA32_FLUSH_CMD_L1D 0x00000001 +/* MSR IA32_MCU_OPT_CTRL */ +#define IA32_RNGDS_MITG_DIS 0x00000001 + /* MSR IA32_HWP_CAPABILITIES */ #define IA32_HWP_CAPABILITIES_HIGHEST_PERFORMANCE(x) (((x) >> 0) & 0xff) #define IA32_HWP_CAPABILITIES_GUARANTEED_PERFORMANCE(x) (((x) >> 8) & 0xff) @@ -788,6 +826,9 @@ #define IA32_HWP_REQUEST_MAXIMUM_PERFORMANCE (0xffULL << 8) #define IA32_HWP_MINIMUM_PERFORMANCE (0xffULL << 0) +/* MSR IA32_ENERGY_PERF_BIAS */ +#define IA32_ENERGY_PERF_BIAS_POLICY_HINT_MASK (0xfULL << 0) + /* * PAT modes. */ @@ -910,9 +951,13 @@ #define MCG_CAP_TES_P 0x00000800 #define MCG_CAP_EXT_CNT 0x00ff0000 #define MCG_CAP_SER_P 0x01000000 +#define MCG_CAP_EMC_P 0x02000000 +#define MCG_CAP_ELOG_P 0x04000000 +#define MCG_CAP_LMCE_P 0x08000000 #define MCG_STATUS_RIPV 0x00000001 #define MCG_STATUS_EIPV 0x00000002 #define MCG_STATUS_MCIP 0x00000004 +#define MCG_STATUS_LMCS 0x00000008 /* if MCG_CAP_LMCE_P */ #define MCG_CTL_ENABLE 0xffffffffffffffff #define MCG_CTL_DISABLE 0x0000000000000000 #define MSR_MC_CTL(x) (MSR_MC0_CTL + (x) * 4) @@ -936,6 +981,11 @@ #define MC_STATUS_VAL 0x8000000000000000 #define MC_MISC_RA_LSB 0x000000000000003f /* If MCG_CAP_SER_P */ #define MC_MISC_ADDRESS_MODE 0x00000000000001c0 /* If MCG_CAP_SER_P */ +#define MC_MISC_PCIE_RID 0x00000000ffff0000 +#define MC_MISC_PCIE_FUNC 0x0000000000070000 +#define MC_MISC_PCIE_SLOT 0x0000000000f80000 +#define MC_MISC_PCIE_BUS 0x00000000ff000000 +#define MC_MISC_PCIE_SEG 0x000000ff00000000 #define MC_CTL2_THRESHOLD 0x0000000000007fff #define MC_CTL2_CMCI_EN 0x0000000040000000 #define MC_AMDNB_BANK 4 @@ -1088,6 +1138,7 @@ #define MSR_NB_CFG1 0xc001001f /* NB configuration 1 */ #define MSR_K8_UCODE_UPDATE 0xc0010020 /* update microcode */ #define MSR_MC0_CTL_MASK 0xc0010044 +#define MSR_AMDK8_IPM 0xc0010055 #define MSR_P_STATE_LIMIT 0xc0010061 /* P-state Current Limit Register */ #define MSR_P_STATE_CONTROL 0xc0010062 /* P-state Control Register */ #define MSR_P_STATE_STATUS 0xc0010063 /* P-state Status Register */ @@ -1105,6 +1156,9 @@ /* MSR_VM_CR related */ #define VM_CR_SVMDIS 0x10 /* SVM: disabled by BIOS */ +#define AMDK8_SMIONCMPHALT (1ULL << 27) +#define AMDK8_C1EONCMPHALT (1ULL << 28) + /* VIA ACE crypto featureset: for via_feature_rng */ #define VIA_HAS_RNG 1 /* cpu has RNG */ diff --git a/usr/src/data/bhyve/kbdlayout/de b/usr/src/data/bhyve/kbdlayout/de index 745f826a9d..82381f705a 100644 --- a/usr/src/data/bhyve/kbdlayout/de +++ b/usr/src/data/bhyve/kbdlayout/de @@ -14,6 +14,7 @@ '*',0x5b; * (0x2a) '+',0x5b; + (0x2b) '-',0x4a; - (0x2d) +'/',0x3d; / (0x2f) ':',0x49; : (0x3a) ';',0x41; ; (0x3b) '<',0x61; < (0x3c) @@ -35,3 +36,5 @@ '}',0x45; } (0x7d) '~',0x5b; ~ (0x7e) +# Language Specific Keys ------------------------------------------------------ +0xa7,0x26; section sign (§) diff --git a/usr/src/data/bhyve/kbdlayout/de_acc b/usr/src/data/bhyve/kbdlayout/de_acc index 2ba06f3d16..4ee39b9b05 100644 --- a/usr/src/data/bhyve/kbdlayout/de_acc +++ b/usr/src/data/bhyve/kbdlayout/de_acc @@ -14,6 +14,7 @@ '*',0x5b; * (0x2a) '+',0x5b; + (0x2b) '-',0x4a; - (0x2d) +'/',0x3d; / (0x2f) ':',0x49; : (0x3a) ';',0x41; ; (0x3b) '<',0x61; < (0x3c) @@ -34,3 +35,5 @@ '|',0x61; | (0x7c) '}',0x45; } (0x7d) +# Language Specific Keys ------------------------------------------------------ +0xa7,0x26; section sign (§) diff --git a/usr/src/data/bhyve/kbdlayout/de_noacc b/usr/src/data/bhyve/kbdlayout/de_noacc index 4d215116e2..6dfcbc63ae 100644 --- a/usr/src/data/bhyve/kbdlayout/de_noacc +++ b/usr/src/data/bhyve/kbdlayout/de_noacc @@ -14,6 +14,7 @@ '*',0x5b; * (0x2a) '+',0x5b; + (0x2b) '-',0x4a; - (0x2d) +'/',0x3d; / (0x2f) ':',0x49; : (0x3a) ';',0x41; ; (0x3b) '<',0x61; < (0x3c) @@ -36,3 +37,5 @@ '}',0x45; } (0x7d) '~',0x5b; ~ (0x7e) +# Language Specific Keys ------------------------------------------------------ +0xa7,0x26; section sign (§) diff --git a/usr/src/uts/intel/io/vmm/io/ppt.c b/usr/src/uts/intel/io/vmm/io/ppt.c index 3492603d38..5da0095887 100644 --- a/usr/src/uts/intel/io/vmm/io/ppt.c +++ b/usr/src/uts/intel/io/vmm/io/ppt.c @@ -1139,6 +1139,11 @@ ppt_map_mmio(struct vm *vm, int pptfd, vm_paddr_t gpa, size_t len, struct pptdev *ppt; int err = 0; + if ((len & PAGEOFFSET) != 0 || len == 0 || (gpa & PAGEOFFSET) != 0 || + (hpa & PAGEOFFSET) != 0 || gpa + len < gpa || hpa + len < hpa) { + return (EINVAL); + } + mutex_enter(&pptdev_mtx); err = ppt_findf(vm, pptfd, &ppt); if (err != 0) { diff --git a/usr/src/uts/intel/io/vmm/io/vlapic.c b/usr/src/uts/intel/io/vmm/io/vlapic.c index 2395dc2fa3..5037c3b109 100644 --- a/usr/src/uts/intel/io/vmm/io/vlapic.c +++ b/usr/src/uts/intel/io/vmm/io/vlapic.c @@ -76,7 +76,7 @@ __FBSDID("$FreeBSD$"); */ #define PRIO(x) ((x) & 0xf0) -#define VLAPIC_VERSION (16) +#define VLAPIC_VERSION (0x14) /* * The 'vlapic->timer_lock' is used to provide mutual exclusion between the @@ -949,6 +949,91 @@ vlapic_get_cr8(const struct vlapic *vlapic) return (lapic->tpr >> 4); } +static bool +vlapic_is_icr_valid(uint64_t icrval) +{ + uint32_t mode = icrval & APIC_DELMODE_MASK; + uint32_t level = icrval & APIC_LEVEL_MASK; + uint32_t trigger = icrval & APIC_TRIGMOD_MASK; + uint32_t shorthand = icrval & APIC_DEST_MASK; + + switch (mode) { + case APIC_DELMODE_FIXED: + if (trigger == APIC_TRIGMOD_EDGE) + return (true); + /* + * AMD allows a level assert IPI and Intel converts a level + * assert IPI into an edge IPI. + */ + if (trigger == APIC_TRIGMOD_LEVEL && level == APIC_LEVEL_ASSERT) + return (true); + break; + case APIC_DELMODE_LOWPRIO: + case APIC_DELMODE_SMI: + case APIC_DELMODE_NMI: + case APIC_DELMODE_INIT: + if (trigger == APIC_TRIGMOD_EDGE && + (shorthand == APIC_DEST_DESTFLD || + shorthand == APIC_DEST_ALLESELF)) { + return (true); + } + /* + * AMD allows a level assert IPI and Intel converts a level + * assert IPI into an edge IPI. + */ + if (trigger == APIC_TRIGMOD_LEVEL && + level == APIC_LEVEL_ASSERT && + (shorthand == APIC_DEST_DESTFLD || + shorthand == APIC_DEST_ALLESELF)) { + return (true); + } + /* + * An level triggered deassert INIT is defined in the Intel + * Multiprocessor Specification and the Intel Software Developer + * Manual. Due to the MPS it's required to send a level assert + * INIT to a cpu and then a level deassert INIT. Some operating + * systems e.g. FreeBSD or Linux use that algorithm. According + * to the SDM a level deassert INIT is only supported by Pentium + * and P6 processors. It's always send to all cpus regardless of + * the destination or shorthand field. It resets the arbitration + * id register. This register is not software accessible and + * only required for the APIC bus arbitration. So, the level + * deassert INIT doesn't need any emulation and we should ignore + * it. The SDM also defines that newer processors don't support + * the level deassert INIT and it's not valid any more. As it's + * defined for older systems, it can't be invalid per se. + * Otherwise, backward compatibility would be broken. However, + * when returning false here, it'll be ignored which is the + * desired behaviour. + */ + if (mode == APIC_DELMODE_INIT && + trigger == APIC_TRIGMOD_LEVEL && + level == APIC_LEVEL_DEASSERT) { + return (false); + } + break; + case APIC_DELMODE_STARTUP: + if (shorthand == APIC_DEST_DESTFLD || + shorthand == APIC_DEST_ALLESELF) { + return (true); + } + break; + case APIC_DELMODE_RR: + /* Only available on AMD! */ + if (trigger == APIC_TRIGMOD_EDGE && + shorthand == APIC_DEST_DESTFLD) { + return (true); + } + break; + case APIC_DELMODE_RESV: + return (false); + default: + panic("vlapic_is_icr_valid: invalid mode 0x%08x", mode); + } + + return (false); +} + void vlapic_icrlo_write_handler(struct vlapic *vlapic) { @@ -962,6 +1047,12 @@ vlapic_icrlo_write_handler(struct vlapic *vlapic) lapic->icr_lo &= ~APIC_DELSTAT_PEND; icrval = ((uint64_t)lapic->icr_hi << 32) | lapic->icr_lo; + /* + * Ignore invalid combinations of the icr. + */ + if (!vlapic_is_icr_valid(icrval)) + return; + if (vlapic_x2mode(vlapic)) dest = icrval >> 32; else @@ -974,23 +1065,12 @@ vlapic_icrlo_write_handler(struct vlapic *vlapic) vlapic_set_error(vlapic, APIC_ESR_SEND_ILLEGAL_VECTOR, false); return; } + if (mode == APIC_DELMODE_INIT && (icrval & APIC_LEVEL_MASK) == APIC_LEVEL_DEASSERT) { /* No work required to deassert INIT */ return; } - if ((mode == APIC_DELMODE_STARTUP || mode == APIC_DELMODE_INIT) && - !(dsh == APIC_DEST_DESTFLD || dsh == APIC_DEST_ALLESELF)) { - /* - * While Intel makes no mention of restrictions for destination - * shorthand when sending INIT or SIPI, AMD requires either a - * specific destination or all-excluding self. Common use seems - * to be restricted to those two cases. Until handling is in - * place to halt a guest which makes such a frivolous request, - * we will ignore them. - */ - return; - } switch (dsh) { case APIC_DEST_DESTFLD: diff --git a/usr/src/uts/intel/io/vmm/vmm_instruction_emul.c b/usr/src/uts/intel/io/vmm/vmm_instruction_emul.c index 9fbb923cd9..c3b3b4d03e 100644 --- a/usr/src/uts/intel/io/vmm/vmm_instruction_emul.c +++ b/usr/src/uts/intel/io/vmm/vmm_instruction_emul.c @@ -1725,8 +1725,8 @@ static int vie_emulate_bextr(struct vie *vie, struct vm *vm, int vcpuid, uint64_t gpa) { uint64_t src1, src2, dst, rflags; - unsigned start, len; - int error, size; + unsigned start, len, size; + int error; struct vm_guest_paging *paging; size = vie->opsize; -- 2.11.4.GIT