summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Fiddaman <omnios@citrus-it.co.uk>2022-02-25 14:31:30 +0000
committerAndy Fiddaman <omnios@citrus-it.co.uk>2022-05-12 18:30:12 +0000
commitd7b72f7b52f902da47cc7210a9121f4caabbcb9c (patch)
tree2d9698100bb217a732ff8632ca0e4b03308c9c25
parent530a8aa611843ce1c3faf0296e774bbbcb900ac7 (diff)
downloadillumos-joyent-d7b72f7b52f902da47cc7210a9121f4caabbcb9c.tar.gz
14578 bhyve upstream sync 2022 March
14493 Three small memory leaks in bhyve Reviewed by: Patrick Mooney <pmooney@pfmooney.com> Approved by: Dan McDonald <danmcd@mnx.io>
-rw-r--r--exception_lists/copyright3
-rw-r--r--exception_lists/cstyle2
-rw-r--r--exception_lists/wscheck3
-rw-r--r--usr/src/Targetdirs7
-rw-r--r--usr/src/cmd/bhyve/README.sync20
-rw-r--r--usr/src/cmd/bhyve/acpi.c46
-rw-r--r--usr/src/cmd/bhyve/bhyverun.c58
-rw-r--r--usr/src/cmd/bhyve/block_if.c29
-rw-r--r--usr/src/cmd/bhyve/bootrom.c52
-rw-r--r--usr/src/cmd/bhyve/bootrom.h4
-rw-r--r--usr/src/cmd/bhyve/config.c21
-rw-r--r--usr/src/cmd/bhyve/config.h12
-rw-r--r--usr/src/cmd/bhyve/gdb.c5
-rw-r--r--usr/src/cmd/bhyve/mem.c9
-rw-r--r--usr/src/cmd/bhyve/mem.h2
-rw-r--r--usr/src/cmd/bhyve/pci_ahci.c2
-rw-r--r--usr/src/cmd/bhyve/pci_emul.c128
-rw-r--r--usr/src/cmd/bhyve/pci_emul.h11
-rw-r--r--usr/src/cmd/bhyve/pci_lpc.c31
-rw-r--r--usr/src/cmd/bhyve/pci_nvme.c315
-rw-r--r--usr/src/cmd/bhyve/pci_passthru.c199
-rw-r--r--usr/src/cmd/bhyve/pci_passthru.h18
-rw-r--r--usr/src/cmd/bhyve/pci_virtio_console.c2
-rw-r--r--usr/src/cmd/bhyve/pci_virtio_rnd.c2
-rw-r--r--usr/src/cmd/bhyve/pci_virtio_scsi.c2
-rw-r--r--usr/src/cmd/bhyve/ps2kbd.c95
-rw-r--r--usr/src/cmd/bhyve/uart_emul.c9
-rw-r--r--usr/src/cmd/bhyve/virtio.h2
-rw-r--r--usr/src/contrib/bhyve/dev/nvme/nvme.h111
-rw-r--r--usr/src/data/Makefile3
-rw-r--r--usr/src/data/bhyve/Makefile32
-rw-r--r--usr/src/data/bhyve/kbdlayout/Makefile70
-rw-r--r--usr/src/data/bhyve/kbdlayout/am10
-rw-r--r--usr/src/data/bhyve/kbdlayout/be45
-rw-r--r--usr/src/data/bhyve/kbdlayout/be_acc42
-rw-r--r--usr/src/data/bhyve/kbdlayout/bg_bds10
-rw-r--r--usr/src/data/bhyve/kbdlayout/bg_phonetic9
-rw-r--r--usr/src/data/bhyve/kbdlayout/br19
-rw-r--r--usr/src/data/bhyve/kbdlayout/br_noacc22
-rw-r--r--usr/src/data/bhyve/kbdlayout/centraleuropean12
-rw-r--r--usr/src/data/bhyve/kbdlayout/ch36
-rw-r--r--usr/src/data/bhyve/kbdlayout/ch-fr36
-rw-r--r--usr/src/data/bhyve/kbdlayout/ch-fr_acc33
-rw-r--r--usr/src/data/bhyve/kbdlayout/ch_acc33
-rw-r--r--usr/src/data/bhyve/kbdlayout/ch_macbook_acc37
-rw-r--r--usr/src/data/bhyve/kbdlayout/cz11
-rw-r--r--usr/src/data/bhyve/kbdlayout/de37
-rw-r--r--usr/src/data/bhyve/kbdlayout/de_acc36
-rw-r--r--usr/src/data/bhyve/kbdlayout/de_noacc38
-rw-r--r--usr/src/data/bhyve/kbdlayout/default248
-rw-r--r--usr/src/data/bhyve/kbdlayout/dk32
-rw-r--r--usr/src/data/bhyve/kbdlayout/dk_macbook35
-rw-r--r--usr/src/data/bhyve/kbdlayout/ee31
-rw-r--r--usr/src/data/bhyve/kbdlayout/es28
-rw-r--r--usr/src/data/bhyve/kbdlayout/es_acc28
-rw-r--r--usr/src/data/bhyve/kbdlayout/es_dvorak78
-rw-r--r--usr/src/data/bhyve/kbdlayout/fi32
-rw-r--r--usr/src/data/bhyve/kbdlayout/fr46
-rw-r--r--usr/src/data/bhyve/kbdlayout/fr_acc46
-rw-r--r--usr/src/data/bhyve/kbdlayout/fr_dvorak87
-rw-r--r--usr/src/data/bhyve/kbdlayout/fr_dvorak_acc86
-rw-r--r--usr/src/data/bhyve/kbdlayout/fr_macbook49
-rw-r--r--usr/src/data/bhyve/kbdlayout/gr9
-rw-r--r--usr/src/data/bhyve/kbdlayout/gr_101_acc9
-rw-r--r--usr/src/data/bhyve/kbdlayout/gr_elot_acc17
-rw-r--r--usr/src/data/bhyve/kbdlayout/hr36
-rw-r--r--usr/src/data/bhyve/kbdlayout/hu_1019
-rw-r--r--usr/src/data/bhyve/kbdlayout/hu_10241
-rw-r--r--usr/src/data/bhyve/kbdlayout/is33
-rw-r--r--usr/src/data/bhyve/kbdlayout/is_acc32
-rw-r--r--usr/src/data/bhyve/kbdlayout/it34
-rw-r--r--usr/src/data/bhyve/kbdlayout/jp36
-rw-r--r--usr/src/data/bhyve/kbdlayout/jp_capsctrl37
-rw-r--r--usr/src/data/bhyve/kbdlayout/kz_io11
-rw-r--r--usr/src/data/bhyve/kbdlayout/kz_kst11
-rw-r--r--usr/src/data/bhyve/kbdlayout/latinamerican33
-rw-r--r--usr/src/data/bhyve/kbdlayout/latinamerican_acc31
-rw-r--r--usr/src/data/bhyve/kbdlayout/lt10
-rw-r--r--usr/src/data/bhyve/kbdlayout/nl31
-rw-r--r--usr/src/data/bhyve/kbdlayout/no32
-rw-r--r--usr/src/data/bhyve/kbdlayout/no_dvorak81
-rw-r--r--usr/src/data/bhyve/kbdlayout/nordic_asus-eee32
-rw-r--r--usr/src/data/bhyve/kbdlayout/pl_dvorak74
-rw-r--r--usr/src/data/bhyve/kbdlayout/pt31
-rw-r--r--usr/src/data/bhyve/kbdlayout/pt_acc28
-rw-r--r--usr/src/data/bhyve/kbdlayout/ru14
-rw-r--r--usr/src/data/bhyve/kbdlayout/ru_shift9
-rw-r--r--usr/src/data/bhyve/kbdlayout/ru_win9
-rw-r--r--usr/src/data/bhyve/kbdlayout/se32
-rw-r--r--usr/src/data/bhyve/kbdlayout/si36
-rw-r--r--usr/src/data/bhyve/kbdlayout/tr36
-rw-r--r--usr/src/data/bhyve/kbdlayout/tr_f81
-rw-r--r--usr/src/data/bhyve/kbdlayout/ua9
-rw-r--r--usr/src/data/bhyve/kbdlayout/ua_shift_alt10
-rw-r--r--usr/src/data/bhyve/kbdlayout/uk14
-rw-r--r--usr/src/data/bhyve/kbdlayout/uk_capsctrl14
-rw-r--r--usr/src/data/bhyve/kbdlayout/uk_dvorak78
-rw-r--r--usr/src/data/bhyve/kbdlayout/uk_macbook10
-rw-r--r--usr/src/data/bhyve/kbdlayout/us_dvorak74
-rw-r--r--usr/src/data/bhyve/kbdlayout/us_dvorakl88
-rw-r--r--usr/src/data/bhyve/kbdlayout/us_dvorakp95
-rw-r--r--usr/src/data/bhyve/kbdlayout/us_dvorakr86
-rw-r--r--usr/src/data/bhyve/kbdlayout/us_dvorakx80
-rw-r--r--usr/src/data/bhyve/kbdlayout/us_emacs9
-rw-r--r--usr/src/data/bhyve/kbdlayout/us_unix14
-rw-r--r--usr/src/lib/libvmmapi/common/vmmapi.c47
-rw-r--r--usr/src/lib/libvmmapi/common/vmmapi.h1
-rw-r--r--usr/src/man/man5/bhyve_config.512
-rw-r--r--usr/src/man/man8/bhyve.818
-rw-r--r--usr/src/pkg/manifests/system-bhyve.p5m77
-rw-r--r--usr/src/uts/intel/io/vmm/vmm.c118
-rw-r--r--usr/src/uts/intel/io/vmm/vmm_sol_dev.c4
-rw-r--r--usr/src/uts/intel/io/vmm/vmm_stat.c23
-rw-r--r--usr/src/uts/intel/io/vmm/vmm_stat.h6
-rw-r--r--usr/src/uts/intel/sys/vmm.h2
-rw-r--r--usr/src/uts/intel/sys/vmm_dev.h3
116 files changed, 4120 insertions, 284 deletions
diff --git a/exception_lists/copyright b/exception_lists/copyright
index 8b7937994e..2656359cea 100644
--- a/exception_lists/copyright
+++ b/exception_lists/copyright
@@ -507,7 +507,7 @@ usr/src/cmd/bhyve/pci_hostbridge.c
usr/src/cmd/bhyve/pci_irq.[ch]
usr/src/cmd/bhyve/pci_lpc.[ch]
usr/src/cmd/bhyve/pci_nvme.c
-usr/src/cmd/bhyve/pci_passthru.c
+usr/src/cmd/bhyve/pci_passthru.[ch]
usr/src/cmd/bhyve/pci_uart.c
usr/src/cmd/bhyve/pci_virtio_block.c
usr/src/cmd/bhyve/pci_virtio_console.c
@@ -539,6 +539,7 @@ usr/src/cmd/bhyvectl/THIRDPARTYLICENSE.descrip
usr/src/cmd/bhyvectl/bhyvectl.c
usr/src/compat/bhyve/*
usr/src/contrib/bhyve/*
+usr/src/data/bhyve/kbdlayout/*
usr/src/lib/libvmmapi/THIRDPARTYLICENSE
usr/src/lib/libvmmapi/THIRDPARTYLICENSE.descrip
usr/src/lib/libvmmapi/common/vmmapi.[ch]
diff --git a/exception_lists/cstyle b/exception_lists/cstyle
index 1518560691..271dc7ec35 100644
--- a/exception_lists/cstyle
+++ b/exception_lists/cstyle
@@ -1356,7 +1356,7 @@ usr/src/cmd/bhyve/pci_hostbridge.c
usr/src/cmd/bhyve/pci_irq.[ch]
usr/src/cmd/bhyve/pci_lpc.[ch]
usr/src/cmd/bhyve/pci_nvme.c
-usr/src/cmd/bhyve/pci_passthru.c
+usr/src/cmd/bhyve/pci_passthru.[ch]
usr/src/cmd/bhyve/pci_uart.c
usr/src/cmd/bhyve/pci_virtio_9p.c
usr/src/cmd/bhyve/pci_virtio_block.c
diff --git a/exception_lists/wscheck b/exception_lists/wscheck
index 61c1e46791..889bea8a9f 100644
--- a/exception_lists/wscheck
+++ b/exception_lists/wscheck
@@ -68,7 +68,7 @@ usr/src/cmd/bhyve/pci_hostbridge.c
usr/src/cmd/bhyve/pci_irq.[ch]
usr/src/cmd/bhyve/pci_lpc.[ch]
usr/src/cmd/bhyve/pci_nvme.c
-usr/src/cmd/bhyve/pci_passthru.c
+usr/src/cmd/bhyve/pci_passthru.[ch]
usr/src/cmd/bhyve/pci_uart.c
usr/src/cmd/bhyve/pci_virtio_9p.c
usr/src/cmd/bhyve/pci_virtio_block.c
@@ -96,6 +96,7 @@ usr/src/cmd/bhyve/virtio.[ch]
usr/src/cmd/bhyve/xmsr.[ch]
usr/src/cmd/bhyvectl/bhyvectl.c
usr/src/contrib/bhyve/*
+usr/src/data/bhyve/kbdlayout/default
usr/src/lib/libvmmapi/common/vmmapi.[ch]
usr/src/lib/lib9p/common/*
diff --git a/usr/src/Targetdirs b/usr/src/Targetdirs
index 94ec907b77..38c42c2a1a 100644
--- a/usr/src/Targetdirs
+++ b/usr/src/Targetdirs
@@ -28,7 +28,7 @@
# Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
# Copyright 2017 Nexenta Systems, Inc.
# Copyright 2017 RackTop Systems.
-# Copyright 2021 OmniOS Community Edition (OmniOSce) Association.
+# Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
# Copyright 2020 Joyent, Inc.
#
@@ -54,9 +54,10 @@ i386_DIRS= \
/platform/i86pc \
/lib/libmvec \
/usr/lib/xen \
- /usr/lib/xen/bin
+ /usr/lib/xen/bin \
+ /usr/share/bhyve
-sparc_DIRS= \
+sparc_DIRS= \
/usr/lib/ldoms
sparc_64ONLY= $(POUND_SIGN)
diff --git a/usr/src/cmd/bhyve/README.sync b/usr/src/cmd/bhyve/README.sync
index b59e0f399a..2031c7ed0a 100644
--- a/usr/src/cmd/bhyve/README.sync
+++ b/usr/src/cmd/bhyve/README.sync
@@ -1,17 +1,25 @@
Git commit hashes in this file refer to the official FreeBSD distributed
public Git repository at https://git.freebsd.org/src.git
-The bhyve kernel module and its associated userland consumers have been updated
-to the latest upstream FreeBSD sources as of:
+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 4558c11f1b4dfd7fd505d70b79467eb7f1193f07
- Author: Mark Johnston <markj@FreeBSD.org>
- Date: Wed Jan 5 10:08:13 2022 -0500
+ commit 3ebe1109348f53f64b395293578416abedef4090
+ Author: Robert Wing <rew@FreeBSD.org>
+ Date: Thu Mar 17 21:55:52 2022 -0800
- bhyve: Correct unmapping of the MSI-X table BAR
+ bhyve: sweep MAX_VMNAME
+
+ MAX_VMNAME is no longer used.
Divergence Notes:
+The kernel component of bhyve has diverged from the FreeBSD sources and
+will continue to evolve away from the initial compatibility interfaces towards
+native illumos ones. The vmmapi library abstracts those interfaces wherever
+possible so that the bhyve userspace can remain close to upstream.
+
The source code for the following components is present and included in
syncs from FreeBSD, but currently disabled. See the comments in 'Makefile'
for more details:
diff --git a/usr/src/cmd/bhyve/acpi.c b/usr/src/cmd/bhyve/acpi.c
index 1eb2246b94..757111590f 100644
--- a/usr/src/cmd/bhyve/acpi.c
+++ b/usr/src/cmd/bhyve/acpi.c
@@ -89,10 +89,10 @@ __FBSDID("$FreeBSD$");
* 44 Fixed Header
* 8 * maxcpu Processor Local APIC entries
* 12 I/O APIC entry
- * 2 * 10 Interrupt Source Override entires
+ * 2 * 10 Interrupt Source Override entries
* 6 Local APIC NMI entry
*/
-#define MADT_SIZE (44 + VM_MAXCPU*8 + 12 + 2*10 + 6)
+#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)
@@ -951,28 +951,10 @@ basl_make_templates(void)
return (err);
}
-static struct {
- int (*wsect)(FILE *fp);
- uint64_t offset;
-} basl_ftables[] =
-{
- { basl_fwrite_rsdp, 0},
- { basl_fwrite_rsdt, RSDT_OFFSET },
- { basl_fwrite_xsdt, XSDT_OFFSET },
- { basl_fwrite_madt, MADT_OFFSET },
- { basl_fwrite_fadt, FADT_OFFSET },
- { basl_fwrite_hpet, HPET_OFFSET },
- { basl_fwrite_mcfg, MCFG_OFFSET },
- { basl_fwrite_facs, FACS_OFFSET },
- { basl_fwrite_dsdt, DSDT_OFFSET },
- { NULL }
-};
-
int
acpi_build(struct vmctx *ctx, int ncpu)
{
int err;
- int i;
basl_ncpu = ncpu;
@@ -994,18 +976,30 @@ acpi_build(struct vmctx *ctx, int ncpu)
if (getenv("BHYVE_ACPI_KEEPTMPS"))
basl_keep_temps = 1;
- i = 0;
err = basl_make_templates();
/*
* Run through all the ASL files, compiling them and
* copying them into guest memory
*/
- while (!err && basl_ftables[i].wsect != NULL) {
- err = basl_compile(ctx, basl_ftables[i].wsect,
- basl_ftables[i].offset);
- i++;
- }
+ 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);
}
diff --git a/usr/src/cmd/bhyve/bhyverun.c b/usr/src/cmd/bhyve/bhyverun.c
index 40c7d2a5e1..63dd6a129a 100644
--- a/usr/src/cmd/bhyve/bhyverun.c
+++ b/usr/src/cmd/bhyve/bhyverun.c
@@ -202,8 +202,10 @@ static cpuset_t cpumask;
static void vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip);
-static struct vm_exit vmexit[VM_MAXCPU];
-static struct vm_entry vmentry[VM_MAXCPU];
+static struct vm_exit *vmexit;
+#ifndef __FreeBSD__
+static struct vm_entry *vmentry;
+#endif
struct bhyvestats {
uint64_t vmexit_bogus;
@@ -223,10 +225,10 @@ struct mt_vmm_info {
struct vmctx *mt_ctx;
int mt_vcpu;
uint64_t mt_startrip;
-} mt_vmm_info[VM_MAXCPU];
+} *mt_vmm_info;
#ifdef __FreeBSD__
-static cpuset_t *vcpumap[VM_MAXCPU] = { NULL };
+static cpuset_t **vcpumap;
#endif
static void
@@ -260,6 +262,7 @@ usage(int code)
" -H: vmexit from the guest on hlt\n"
" -h: help\n"
" -k: key=value flat config file\n"
+ " -K: PS2 keyboard layout\n"
" -l: LPC device configuration\n"
" -m: memory size\n"
" -o: set config 'var' to 'value'\n"
@@ -292,7 +295,7 @@ usage(int code)
static int
topology_parse(const char *opt)
{
- char *cp, *str;
+ char *cp, *str, *tofree;
if (*opt == '\0') {
set_config_value("sockets", "1");
@@ -302,7 +305,7 @@ topology_parse(const char *opt)
return (0);
}
- str = strdup(opt);
+ tofree = str = strdup(opt);
if (str == NULL)
errx(4, "Failed to allocate memory");
@@ -324,11 +327,11 @@ topology_parse(const char *opt)
else
set_config_value("cpus", cp);
}
- free(str);
+ free(tofree);
return (0);
out:
- free(str);
+ free(tofree);
return (-1);
}
@@ -450,9 +453,8 @@ pincpu_parse(const char *opt)
return (-1);
}
- if (vcpu < 0 || vcpu >= VM_MAXCPU) {
- fprintf(stderr, "vcpu '%d' outside valid range from 0 to %d\n",
- vcpu, VM_MAXCPU - 1);
+ if (vcpu < 0) {
+ fprintf(stderr, "invalid vcpu '%d'\n", vcpu);
return (-1);
}
@@ -529,6 +531,7 @@ build_vcpumaps(void)
const char *value;
int vcpu;
+ vcpumap = calloc(guest_ncpus, sizeof(*vcpumap));
for (vcpu = 0; vcpu < guest_ncpus; vcpu++) {
snprintf(key, sizeof(key), "vcpu.%d.cpuset", vcpu);
value = get_config_value(key);
@@ -1175,23 +1178,28 @@ vm_loop(struct vmctx *ctx, int vcpu, uint64_t startrip)
static int
num_vcpus_allowed(struct vmctx *ctx)
{
+ uint16_t sockets, cores, threads, maxcpus;
#ifdef __FreeBSD__
int tmp, error;
- error = vm_get_capability(ctx, BSP, VM_CAP_UNRESTRICTED_GUEST, &tmp);
-
/*
* The guest is allowed to spinup more than one processor only if the
* UNRESTRICTED_GUEST capability is available.
*/
- if (error == 0)
- return (VM_MAXCPU);
- else
+ error = vm_get_capability(ctx, BSP, VM_CAP_UNRESTRICTED_GUEST, &tmp);
+ if (error != 0)
return (1);
#else
+ int error;
/* Unrestricted Guest is always enabled on illumos */
- return (VM_MAXCPU);
+
#endif /* __FreeBSD__ */
+
+ error = vm_get_topology(ctx, &sockets, &cores, &threads, &maxcpus);
+ if (error == 0)
+ return (maxcpus);
+ else
+ return (1);
}
void
@@ -1419,10 +1427,10 @@ main(int argc, char *argv[])
progname = basename(argv[0]);
#ifdef __FreeBSD__
- optstr = "aehuwxACDHIPSWYk:o:p:G:c:s:m:l:U:";
+ optstr = "aehuwxACDHIPSWYk:o:p:G:c:s:m:l:K:U:";
#else
/* +d, +B, -p */
- optstr = "adehuwxACDHIPSWYk:o:G:c:s:m:l:B:U:";
+ optstr = "adehuwxACDHIPSWYk:o:G:c:s:m:l:B:K:U:";
#endif
while ((c = getopt(argc, argv, optstr)) != -1) {
switch (c) {
@@ -1479,6 +1487,9 @@ main(int argc, char *argv[])
case 'k':
parse_simple_config_file(optarg);
break;
+ case 'K':
+ set_config_value("keyboard.layout", optarg);
+ break;
case 'l':
if (strncmp(optarg, "help", strlen(optarg)) == 0) {
lpc_print_supported_devices();
@@ -1622,7 +1633,7 @@ main(int argc, char *argv[])
exit(4);
}
- init_mem();
+ init_mem(guest_ncpus);
init_inout();
#ifdef __FreeBSD__
kernemu_dev_init();
@@ -1638,6 +1649,13 @@ 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
*/
diff --git a/usr/src/cmd/bhyve/block_if.c b/usr/src/cmd/bhyve/block_if.c
index 29d55dfdda..48948b4f23 100644
--- a/usr/src/cmd/bhyve/block_if.c
+++ b/usr/src/cmd/bhyve/block_if.c
@@ -544,7 +544,7 @@ blockif_open(nvlist_t *nvl, const char *ident)
#ifndef WITHOUT_CAPSICUM
cap_rights_t rights;
- cap_ioctl_t cmds[] = { DIOCGFLUSH, DIOCGDELETE };
+ cap_ioctl_t cmds[] = { DIOCGFLUSH, DIOCGDELETE, DIOCGMEDIASIZE };
#endif
pthread_once(&blockif_once, blockif_init);
@@ -657,9 +657,10 @@ blockif_open(nvlist_t *nvl, const char *ident)
struct dk_minfo_ext dkmext;
int wce_val;
- /* Look for a more accurate physical blocksize */
+ /* Look for a more accurate physical block/media size */
if (ioctl(fd, DKIOCGMEDIAINFOEXT, &dkmext) == 0) {
psectsz = dkmext.dki_pbsize;
+ size = dkmext.dki_lbsize * dkmext.dki_capacity;
}
/* See if a configurable write cache is present and working */
if (ioctl(fd, DKIOCGETWCE, &wce_val) == 0) {
@@ -807,14 +808,34 @@ blockif_resized(int fd, enum ev_type type, void *arg)
{
struct blockif_ctxt *bc;
struct stat sb;
+ off_t mediasize;
if (fstat(fd, &sb) != 0)
return;
+#ifdef __FreeBSD__
+ if (S_ISCHR(sb.st_mode)) {
+ if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) < 0) {
+ EPRINTLN("blockif_resized: get mediasize failed: %s",
+ strerror(errno));
+ return;
+ }
+ } else
+ mediasize = sb.st_size;
+#else
+ mediasize = sb.st_size;
+ if (S_ISCHR(sb.st_mode)) {
+ struct dk_minfo dkm;
+
+ if (ioctl(fd, DKIOCGMEDIAINFO, &dkm) == 0)
+ mediasize = dkm.dki_lbsize * dkm.dki_capacity;
+ }
+#endif
+
bc = arg;
pthread_mutex_lock(&bc->bc_mtx);
- if (sb.st_size != bc->bc_size) {
- bc->bc_size = sb.st_size;
+ if (mediasize != bc->bc_size) {
+ bc->bc_size = mediasize;
bc->bc_resize_cb(bc, bc->bc_resize_cb_arg, bc->bc_size);
}
pthread_mutex_unlock(&bc->bc_mtx);
diff --git a/usr/src/cmd/bhyve/bootrom.c b/usr/src/cmd/bhyve/bootrom.c
index cbb05c8c50..00f0a1a2a5 100644
--- a/usr/src/cmd/bhyve/bootrom.c
+++ b/usr/src/cmd/bhyve/bootrom.c
@@ -191,19 +191,33 @@ bootrom_alloc(struct vmctx *ctx, size_t len, int prot, int flags,
}
int
-bootrom_loadrom(struct vmctx *ctx, const char *romfile)
+bootrom_loadrom(struct vmctx *ctx, const nvlist_t *nvl)
{
struct stat sbuf;
ssize_t rlen;
off_t rom_size, var_size, total_size;
- char *ptr, *varfile;
+ char *ptr, *romfile;
int fd, varfd, i, rv;
+ const char *bootrom, *varfile;
rv = -1;
varfd = -1;
- varfile = strdup(romfile);
- romfile = strsep(&varfile, ",");
+ bootrom = get_config_value_node(nvl, "bootrom");
+ if (bootrom == NULL) {
+ return (-1);
+ }
+
+ /*
+ * get_config_value_node may use a thread local buffer to return
+ * variables. So, when we query the second variable, the first variable
+ * might get overwritten. For that reason, the bootrom should be
+ * duplicated.
+ */
+ romfile = strdup(bootrom);
+ if (romfile == NULL) {
+ return (-1);
+ }
fd = open(romfile, O_RDONLY);
if (fd < 0) {
@@ -212,6 +226,16 @@ bootrom_loadrom(struct vmctx *ctx, const char *romfile)
goto done;
}
+ if (fstat(fd, &sbuf) < 0) {
+ EPRINTLN("Could not fstat bootrom file \"%s\": %s", romfile,
+ strerror(errno));
+ goto done;
+ }
+
+ rom_size = sbuf.st_size;
+
+ varfile = get_config_value_node(nvl, "bootvars");
+ var_size = 0;
if (varfile != NULL) {
varfd = open(varfile, O_RDWR);
if (varfd < 0) {
@@ -219,23 +243,14 @@ bootrom_loadrom(struct vmctx *ctx, const char *romfile)
"\"%s\": %s\n", varfile, strerror(errno));
goto done;
}
- }
-
- if (fstat(fd, &sbuf) < 0) {
- EPRINTLN("Could not fstat bootrom file \"%s\": %s",
- romfile, strerror(errno));
- goto done;
- }
- rom_size = sbuf.st_size;
- if (varfd < 0) {
- var_size = 0;
- } else {
if (fstat(varfd, &sbuf) < 0) {
- fprintf(stderr, "Could not fstat bootrom variable file \"%s\": %s\n",
- varfile, strerror(errno));
+ fprintf(stderr,
+ "Could not fstat bootrom variable file \"%s\": %s\n",
+ varfile, strerror(errno));
goto done;
}
+
var_size = sbuf.st_size;
}
@@ -296,7 +311,10 @@ bootrom_loadrom(struct vmctx *ctx, const char *romfile)
rv = 0;
done:
+ if (varfd >= 0)
+ close(varfd);
if (fd >= 0)
close(fd);
+ free(romfile);
return (rv);
}
diff --git a/usr/src/cmd/bhyve/bootrom.h b/usr/src/cmd/bhyve/bootrom.h
index da802343ee..f718d5728c 100644
--- a/usr/src/cmd/bhyve/bootrom.h
+++ b/usr/src/cmd/bhyve/bootrom.h
@@ -36,6 +36,8 @@
#include <stdint.h>
#include <limits.h>
+#include "config.h"
+
struct vmctx;
void init_bootrom(struct vmctx *ctx);
@@ -45,6 +47,6 @@ enum {
};
int bootrom_alloc(struct vmctx *ctx, size_t len, int prot, int flags,
char **region_out, uint64_t *gpa_out);
-int bootrom_loadrom(struct vmctx *ctx, const char *romfile);
+int bootrom_loadrom(struct vmctx *ctx, const nvlist_t *nvl);
#endif
diff --git a/usr/src/cmd/bhyve/config.c b/usr/src/cmd/bhyve/config.c
index 9383e49093..f8aace3b73 100644
--- a/usr/src/cmd/bhyve/config.c
+++ b/usr/src/cmd/bhyve/config.c
@@ -143,6 +143,17 @@ set_config_value_node(nvlist_t *parent, const char *name, const char *value)
}
void
+set_config_value_node_if_unset(nvlist_t *const parent, const char *const name,
+ const char *const value)
+{
+ if (get_config_value_node(parent, name) != NULL) {
+ return;
+ }
+
+ set_config_value_node(parent, name, value);
+}
+
+void
set_config_value(const char *path, const char *value)
{
const char *name;
@@ -174,6 +185,16 @@ set_config_value(const char *path, const char *value)
set_config_value_node(nvl, name, value);
}
+void
+set_config_value_if_unset(const char *const path, const char *const value)
+{
+ if (get_config_value(path) != NULL) {
+ return;
+ }
+
+ set_config_value(path, value);
+}
+
static const char *
get_raw_config_value(const char *path)
{
diff --git a/usr/src/cmd/bhyve/config.h b/usr/src/cmd/bhyve/config.h
index 574da966df..8d3f6f90b2 100644
--- a/usr/src/cmd/bhyve/config.h
+++ b/usr/src/cmd/bhyve/config.h
@@ -100,11 +100,23 @@ void set_config_value_node(nvlist_t *parent, const char *name,
const char *value);
/*
+ * Similar to set_config_value_node but only sets value if it's unset yet.
+ */
+void set_config_value_node_if_unset(nvlist_t *const parent,
+ const char *const name, const char *const value);
+
+/*
* Similar to set_config_value_node but expects a full path to the
* leaf node.
*/
void set_config_value(const char *path, const char *value);
+/*
+ * Similar to set_config_value but only sets the value if it's unset yet.
+ */
+void set_config_value_if_unset(const char *const path,
+ const char *const value);
+
/* Convenience wrappers for boolean variables. */
bool get_config_bool(const char *path);
bool get_config_bool_node(const nvlist_t *parent, const char *name);
diff --git a/usr/src/cmd/bhyve/gdb.c b/usr/src/cmd/bhyve/gdb.c
index fcd6931532..1d1203e138 100644
--- a/usr/src/cmd/bhyve/gdb.c
+++ b/usr/src/cmd/bhyve/gdb.c
@@ -1931,8 +1931,9 @@ init_gdb(struct vmctx *_ctx)
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_NUMERICSERV | AI_PASSIVE;
- if (getaddrinfo(saddr, sport, &hints, &gdbaddr) != 0)
- err(1, "gdb address resolve");
+ error = getaddrinfo(saddr, sport, &hints, &gdbaddr);
+ if (error != 0)
+ errx(1, "gdb address resolution: %s", gai_strerror(error));
ctx = _ctx;
s = socket(gdbaddr->ai_family, gdbaddr->ai_socktype, 0);
diff --git a/usr/src/cmd/bhyve/mem.c b/usr/src/cmd/bhyve/mem.c
index 4341bf6c88..74ce0103a3 100644
--- a/usr/src/cmd/bhyve/mem.c
+++ b/usr/src/cmd/bhyve/mem.c
@@ -79,7 +79,8 @@ RB_HEAD(mmio_rb_tree, mmio_rb_range) mmio_rb_root, mmio_rb_fallback;
* consecutive addresses in a range, it makes sense to cache the
* result of a lookup.
*/
-static struct mmio_rb_range *mmio_hint[VM_MAXCPU];
+static struct mmio_rb_range **mmio_hint;
+static int mmio_ncpu;
static pthread_rwlock_t mmio_rwlock;
@@ -359,7 +360,7 @@ unregister_mem(struct mem_range *memp)
RB_REMOVE(mmio_rb_tree, &mmio_rb_root, entry);
/* flush Per-vCPU cache */
- for (i=0; i < VM_MAXCPU; i++) {
+ for (i = 0; i < mmio_ncpu; i++) {
if (mmio_hint[i] == entry)
mmio_hint[i] = NULL;
}
@@ -374,9 +375,11 @@ unregister_mem(struct mem_range *memp)
}
void
-init_mem(void)
+init_mem(int ncpu)
{
+ mmio_ncpu = ncpu;
+ mmio_hint = calloc(ncpu, sizeof(*mmio_hint));
RB_INIT(&mmio_rb_root);
RB_INIT(&mmio_rb_fallback);
pthread_rwlock_init(&mmio_rwlock, NULL);
diff --git a/usr/src/cmd/bhyve/mem.h b/usr/src/cmd/bhyve/mem.h
index 8b81b93a02..631307b0ba 100644
--- a/usr/src/cmd/bhyve/mem.h
+++ b/usr/src/cmd/bhyve/mem.h
@@ -52,7 +52,7 @@ struct mem_range {
#define MEM_F_RW 0x3
#define MEM_F_IMMUTABLE 0x4 /* mem_range cannot be unregistered */
-void init_mem(void);
+void init_mem(int ncpu);
int emulate_mem(struct vmctx *ctx, int vcpu, struct vm_mmio *mmio);
diff --git a/usr/src/cmd/bhyve/pci_ahci.c b/usr/src/cmd/bhyve/pci_ahci.c
index 6f99795ca4..f973b8964f 100644
--- a/usr/src/cmd/bhyve/pci_ahci.c
+++ b/usr/src/cmd/bhyve/pci_ahci.c
@@ -2435,7 +2435,7 @@ pci_ahci_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl)
slots = 32;
ports_nvl = find_relative_config_node(nvl, "port");
- for (p = 0; p < MAX_PORTS; p++) {
+ for (p = 0; ports_nvl != NULL && p < MAX_PORTS; p++) {
struct ata_params *ata_ident = &sc->port[p].ata_ident;
char ident[AHCI_PORT_IDENT];
diff --git a/usr/src/cmd/bhyve/pci_emul.c b/usr/src/cmd/bhyve/pci_emul.c
index 3cbf01158a..413633411d 100644
--- a/usr/src/cmd/bhyve/pci_emul.c
+++ b/usr/src/cmd/bhyve/pci_emul.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/linker_set.h>
+#include <sys/mman.h>
#include <ctype.h>
#include <err.h>
@@ -113,6 +114,9 @@ static struct businfo *pci_businfo[MAXBUSES];
SET_DECLARE(pci_devemu_set, struct pci_devemu);
static uint64_t pci_emul_iobase;
+static uint8_t *pci_emul_rombase;
+static uint64_t pci_emul_romoffset;
+static uint8_t *pci_emul_romlim;
static uint64_t pci_emul_membase32;
static uint64_t pci_emul_membase64;
static uint64_t pci_emul_memlim64;
@@ -130,6 +134,8 @@ TAILQ_HEAD(pci_bar_list, pci_bar_allocation) pci_bars = TAILQ_HEAD_INITIALIZER(
#define PCI_EMUL_IOBASE 0x2000
#define PCI_EMUL_IOLIMIT 0x10000
+#define PCI_EMUL_ROMSIZE 0x10000000
+
#define PCI_EMUL_ECFG_BASE 0xE0000000 /* 3.5GB */
#define PCI_EMUL_ECFG_SIZE (MAXBUSES * 1024 * 1024) /* 1MB per bus */
SYSRES_MEM(PCI_EMUL_ECFG_BASE, PCI_EMUL_ECFG_SIZE);
@@ -574,6 +580,12 @@ modify_bar_registration(struct pci_devinst *pi, int idx, int registration)
(*pe->pe_baraddr)(pi->pi_vmctx, pi, idx, registration,
pi->pi_bar[idx].addr);
break;
+ case PCIBAR_ROM:
+ error = 0;
+ if (pe->pe_baraddr != NULL)
+ (*pe->pe_baraddr)(pi->pi_vmctx, pi, idx, registration,
+ pi->pi_bar[idx].addr);
+ break;
default:
error = EINVAL;
break;
@@ -595,6 +607,14 @@ register_bar(struct pci_devinst *pi, int idx)
modify_bar_registration(pi, idx, 1);
}
+/* Is the ROM enabled for the emulated pci device? */
+static int
+romen(struct pci_devinst *pi)
+{
+ return (pi->pi_bar[PCI_ROM_IDX].lobits & PCIM_BIOS_ENABLE) ==
+ PCIM_BIOS_ENABLE;
+}
+
/* Are we decoding i/o port accesses for the emulated pci device? */
static int
porten(struct pci_devinst *pi)
@@ -661,7 +681,8 @@ int
pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, enum pcibar_type type,
uint64_t size)
{
- assert(idx >= 0 && idx <= PCI_BARMAX);
+ assert((type == PCIBAR_ROM) || (idx >= 0 && idx <= PCI_BARMAX));
+ assert((type != PCIBAR_ROM) || (idx == PCI_ROM_IDX));
if ((size & (size - 1)) != 0)
size = 1UL << flsl(size); /* round up to a power of 2 */
@@ -670,6 +691,9 @@ pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, enum pcibar_type type,
if (type == PCIBAR_IO) {
if (size < 4)
size = 4;
+ } else if (type == PCIBAR_ROM) {
+ if (size < ~PCIM_BIOS_ADDR_MASK + 1)
+ size = ~PCIM_BIOS_ADDR_MASK + 1;
} else {
if (size < 16)
size = 16;
@@ -785,6 +809,16 @@ pci_emul_assign_bar(struct pci_devinst *const pdi, const int idx,
mask = PCIM_BAR_MEM_BASE;
lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_32;
break;
+ case PCIBAR_ROM:
+ /* do not claim memory for ROM. OVMF will do it for us. */
+ baseptr = NULL;
+ limit = 0;
+ mask = PCIM_BIOS_ADDR_MASK;
+ lobits = 0;
+#ifndef __FreeBSD__
+ addr = 0;
+#endif
+ break;
default:
printf("pci_emul_alloc_base: invalid bar type %d\n", type);
#ifdef FreeBSD
@@ -823,7 +857,57 @@ pci_emul_assign_bar(struct pci_devinst *const pdi, const int idx,
pci_set_cfgdata32(pdi, PCIR_BAR(idx + 1), bar >> 32);
}
- register_bar(pdi, idx);
+ if (type != PCIBAR_ROM) {
+ register_bar(pdi, idx);
+ }
+
+ return (0);
+}
+
+int
+pci_emul_alloc_rom(struct pci_devinst *const pdi, const uint64_t size,
+ void **const addr)
+{
+ /* allocate ROM space once on first call */
+ if (pci_emul_rombase == 0) {
+ pci_emul_rombase = vm_create_devmem(pdi->pi_vmctx, VM_PCIROM,
+ "pcirom", PCI_EMUL_ROMSIZE);
+ if (pci_emul_rombase == MAP_FAILED) {
+ warnx("%s: failed to create rom segment", __func__);
+ return (-1);
+ }
+ pci_emul_romlim = pci_emul_rombase + PCI_EMUL_ROMSIZE;
+ pci_emul_romoffset = 0;
+ }
+
+ /* ROM size should be a power of 2 and greater than 2 KB */
+ const uint64_t rom_size = MAX(1UL << flsl(size),
+ ~PCIM_BIOS_ADDR_MASK + 1);
+
+ /* check if ROM fits into ROM space */
+ if (pci_emul_romoffset + rom_size > PCI_EMUL_ROMSIZE) {
+ warnx("%s: no space left in rom segment:", __func__);
+ warnx("%16lu bytes left",
+ PCI_EMUL_ROMSIZE - pci_emul_romoffset);
+ warnx("%16lu bytes required by %d/%d/%d", rom_size, pdi->pi_bus,
+ pdi->pi_slot, pdi->pi_func);
+ return (-1);
+ }
+
+ /* allocate ROM BAR */
+ const int error = pci_emul_alloc_bar(pdi, PCI_ROM_IDX, PCIBAR_ROM,
+ rom_size);
+ if (error)
+ return error;
+
+ /* return address */
+ *addr = pci_emul_rombase + pci_emul_romoffset;
+
+ /* save offset into ROM Space */
+ pdi->pi_romoffset = pci_emul_romoffset;
+
+ /* increase offset for next ROM */
+ pci_emul_romoffset += rom_size;
return (0);
}
@@ -1906,7 +1990,7 @@ pci_emul_cmd_changed(struct pci_devinst *pi, uint16_t old)
* If the MMIO or I/O address space decoding has changed then
* register/unregister all BARs that decode that address space.
*/
- for (i = 0; i <= PCI_BARMAX; i++) {
+ for (i = 0; i <= PCI_BARMAX_WITH_ROM; i++) {
switch (pi->pi_bar[i].type) {
case PCIBAR_NONE:
case PCIBAR_MEMHI64:
@@ -1920,6 +2004,11 @@ pci_emul_cmd_changed(struct pci_devinst *pi, uint16_t old)
unregister_bar(pi, i);
}
break;
+ case PCIBAR_ROM:
+ /* skip (un-)register of ROM if it disabled */
+ if (!romen(pi))
+ break;
+ /* fallthrough */
case PCIBAR_MEM32:
case PCIBAR_MEM64:
/* MMIO address space decoding changed? */
@@ -2041,16 +2130,29 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func,
return;
/*
- * Special handling for write to BAR registers
+ * Special handling for write to BAR and ROM registers
*/
- if (coff >= PCIR_BAR(0) && coff < PCIR_BAR(PCI_BARMAX + 1)) {
+ if ((coff >= PCIR_BAR(0) && coff < PCIR_BAR(PCI_BARMAX + 1)) ||
+ (coff >= PCIR_BIOS && coff < PCIR_BIOS + 4)) {
/*
* Ignore writes to BAR registers that are not
* 4-byte aligned.
*/
if (bytes != 4 || (coff & 0x3) != 0)
return;
- idx = (coff - PCIR_BAR(0)) / 4;
+#ifndef __FreeBSD__
+ if (coff < PCIR_BIOS) {
+ idx = (coff - PCIR_BAR(0)) / 4;
+ } else {
+ idx = PCI_ROM_IDX;
+ }
+#else
+ if (coff != PCIR_BIOS) {
+ idx = (coff - PCIR_BAR(0)) / 4;
+ } else {
+ idx = PCI_ROM_IDX;
+ }
+#endif
mask = ~(pi->pi_bar[idx].size - 1);
switch (pi->pi_bar[idx].type) {
case PCIBAR_NONE:
@@ -2093,6 +2195,20 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func,
PCIBAR_MEMHI64);
}
break;
+ case PCIBAR_ROM:
+ addr = bar = *eax & mask;
+ if (memen(pi) && romen(pi)) {
+ unregister_bar(pi, idx);
+ }
+ pi->pi_bar[idx].addr = addr;
+ pi->pi_bar[idx].lobits = *eax &
+ PCIM_BIOS_ENABLE;
+ /* romen could have changed it value */
+ if (memen(pi) && romen(pi)) {
+ register_bar(pi, idx);
+ }
+ bar |= pi->pi_bar[idx].lobits;
+ break;
default:
assert(0);
}
diff --git a/usr/src/cmd/bhyve/pci_emul.h b/usr/src/cmd/bhyve/pci_emul.h
index d01d2a7596..2929e0c307 100644
--- a/usr/src/cmd/bhyve/pci_emul.h
+++ b/usr/src/cmd/bhyve/pci_emul.h
@@ -45,6 +45,8 @@
#include <assert.h>
#define PCI_BARMAX PCIR_MAX_BAR_0 /* BAR registers in a Type 0 header */
+#define PCI_BARMAX_WITH_ROM (PCI_BARMAX + 1)
+#define PCI_ROM_IDX (PCI_BARMAX + 1)
struct vmctx;
struct pci_devinst;
@@ -92,7 +94,8 @@ enum pcibar_type {
PCIBAR_IO,
PCIBAR_MEM32,
PCIBAR_MEM64,
- PCIBAR_MEMHI64
+ PCIBAR_MEMHI64,
+ PCIBAR_ROM,
};
struct pcibar {
@@ -167,7 +170,9 @@ struct pci_devinst {
void *pi_arg; /* devemu-private data */
u_char pi_cfgdata[PCI_REGMAX + 1];
- struct pcibar pi_bar[PCI_BARMAX + 1];
+ /* ROM is handled like a BAR */
+ struct pcibar pi_bar[PCI_BARMAX_WITH_ROM + 1];
+ uint64_t pi_romoffset;
};
struct msicap {
@@ -231,6 +236,8 @@ int init_pci(struct vmctx *ctx);
void pci_callback(void);
int pci_emul_alloc_bar(struct pci_devinst *pdi, int idx,
enum pcibar_type type, uint64_t size);
+int pci_emul_alloc_rom(struct pci_devinst *const pdi, const uint64_t size,
+ void **const addr);
int pci_emul_add_msicap(struct pci_devinst *pi, int msgnum);
int pci_emul_add_pciecap(struct pci_devinst *pi, int pcie_device_type);
void pci_emul_capwrite(struct pci_devinst *pi, int offset, int bytes,
diff --git a/usr/src/cmd/bhyve/pci_lpc.c b/usr/src/cmd/bhyve/pci_lpc.c
index 189623b5fc..27cf8004b4 100644
--- a/usr/src/cmd/bhyve/pci_lpc.c
+++ b/usr/src/cmd/bhyve/pci_lpc.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <machine/vmm.h>
+#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -98,13 +99,24 @@ lpc_device_parse(const char *opts)
{
int unit, error;
char *str, *cpy, *lpcdev, *node_name;
+ const char *romfile, *varfile;
error = -1;
str = cpy = strdup(opts);
lpcdev = strsep(&str, ",");
if (lpcdev != NULL) {
if (strcasecmp(lpcdev, "bootrom") == 0) {
- set_config_value("lpc.bootrom", str);
+ romfile = strsep(&str, ",");
+ if (romfile == NULL) {
+ errx(4, "invalid bootrom option \"%s\"", opts);
+ }
+ set_config_value("lpc.bootrom", romfile);
+
+ varfile = strsep(&str, ",");
+ if (varfile != NULL) {
+ set_config_value("lpc.bootvars", varfile);
+ }
+
error = 0;
goto done;
}
@@ -222,16 +234,25 @@ lpc_init(struct vmctx *ctx)
{
struct lpc_uart_softc *sc;
struct inout_port iop;
- const char *backend, *name, *romfile;
+ const char *backend, *name;
char *node_name;
int unit, error;
+ const nvlist_t *nvl;
- romfile = get_config_value("lpc.bootrom");
- if (romfile != NULL) {
- error = bootrom_loadrom(ctx, romfile);
+ nvl = find_config_node("lpc");
+#ifndef __FreeBSD__
+ if (nvl != NULL && nvlist_exists((nvlist_t *)nvl, "bootrom")) {
+ error = bootrom_loadrom(ctx, nvl);
if (error)
return (error);
}
+#else
+ if (nvl != NULL && nvlist_exists(nvl, "bootrom")) {
+ error = bootrom_loadrom(ctx, nvl);
+ if (error)
+ return (error);
+ }
+#endif
/* COM1 and COM2 */
for (unit = 0; unit < LPC_UART_NUM; unit++) {
diff --git a/usr/src/cmd/bhyve/pci_nvme.c b/usr/src/cmd/bhyve/pci_nvme.c
index a69c49a388..488c7d4770 100644
--- a/usr/src/cmd/bhyve/pci_nvme.c
+++ b/usr/src/cmd/bhyve/pci_nvme.c
@@ -119,6 +119,9 @@ static int nvme_debug = 0;
#define NVME_NO_STATUS 0xffff
#define NVME_COMPLETION_VALID(c) ((c).status != NVME_NO_STATUS)
+/* Reported temperature in Kelvin (i.e. room temperature) */
+#define NVME_TEMPERATURE 296
+
/* helpers */
/* Convert a zero-based value into a one-based value */
@@ -269,16 +272,20 @@ struct pci_nvme_aer {
uint16_t cid; /* Command ID of the submitted AER */
};
+/** Asynchronous Event Information - Notice */
typedef enum {
- PCI_NVME_AE_INFO_NS_ATTR_CHANGED = 0,
- PCI_NVME_AE_INFO_FW_ACTIVATION,
- PCI_NVME_AE_INFO_TELEMETRY_CHANGE,
- PCI_NVME_AE_INFO_ANA_CHANGE,
- PCI_NVME_AE_INFO_PREDICT_LATENCY_CHANGE,
- PCI_NVME_AE_INFO_LBA_STATUS_ALERT,
- PCI_NVME_AE_INFO_ENDURANCE_GROUP_CHANGE,
- PCI_NVME_AE_INFO_MAX,
-} pci_nvme_async_info;
+ PCI_NVME_AEI_NOTICE_NS_ATTR_CHANGED = 0,
+ PCI_NVME_AEI_NOTICE_FW_ACTIVATION,
+ PCI_NVME_AEI_NOTICE_TELEMETRY_CHANGE,
+ PCI_NVME_AEI_NOTICE_ANA_CHANGE,
+ PCI_NVME_AEI_NOTICE_PREDICT_LATENCY_CHANGE,
+ PCI_NVME_AEI_NOTICE_LBA_STATUS_ALERT,
+ PCI_NVME_AEI_NOTICE_ENDURANCE_GROUP_CHANGE,
+ PCI_NVME_AEI_NOTICE_MAX,
+} pci_nvme_async_event_info_notice;
+
+#define PCI_NVME_AEI_NOTICE_SHIFT 8
+#define PCI_NVME_AEI_NOTICE_MASK(event) (1 << (event + PCI_NVME_AEI_NOTICE_SHIFT))
/* Asynchronous Event Notifications */
struct pci_nvme_aen {
@@ -287,6 +294,19 @@ struct pci_nvme_aen {
bool posted;
};
+/*
+ * By default, enable all Asynchrnous Event Notifications:
+ * SMART / Health Critical Warnings
+ * Namespace Attribute Notices
+ */
+#define PCI_NVME_AEN_DEFAULT_MASK 0x11f
+
+typedef enum {
+ NVME_CNTRLTYPE_IO = 1,
+ NVME_CNTRLTYPE_DISCOVERY = 2,
+ NVME_CNTRLTYPE_ADMIN = 3,
+} pci_nvme_cntrl_type;
+
struct pci_nvme_softc {
struct pci_devinst *nsc_pi;
@@ -395,6 +415,10 @@ static void nvme_feature_invalid_cb(struct pci_nvme_softc *,
struct nvme_feature_obj *,
struct nvme_command *,
struct nvme_completion *);
+static void nvme_feature_temperature(struct pci_nvme_softc *,
+ struct nvme_feature_obj *,
+ struct nvme_command *,
+ struct nvme_completion *);
static void nvme_feature_num_queues(struct pci_nvme_softc *,
struct nvme_feature_obj *,
struct nvme_command *,
@@ -403,6 +427,10 @@ static void nvme_feature_iv_config(struct pci_nvme_softc *,
struct nvme_feature_obj *,
struct nvme_command *,
struct nvme_completion *);
+static void nvme_feature_async_event(struct pci_nvme_softc *,
+ struct nvme_feature_obj *,
+ struct nvme_command *,
+ struct nvme_completion *);
static void *aen_thr(void *arg);
@@ -460,13 +488,8 @@ pci_nvme_init_queues(struct pci_nvme_softc *sc, uint32_t nsq, uint32_t ncq)
} else {
struct nvme_submission_queue *sq = sc->submit_queues;
-#ifndef __FreeBSD__
for (i = 0; i < sc->num_squeues + 1; i++)
pthread_mutex_init(&sq[i].mtx, NULL);
-#else
- for (i = 0; i < sc->num_squeues; i++)
- pthread_mutex_init(&sq[i].mtx, NULL);
-#endif
}
/*
@@ -488,13 +511,8 @@ pci_nvme_init_queues(struct pci_nvme_softc *sc, uint32_t nsq, uint32_t ncq)
} else {
struct nvme_completion_queue *cq = sc->compl_queues;
-#ifndef __FreeBSD__
for (i = 0; i < sc->num_cqueues + 1; i++)
pthread_mutex_init(&cq[i].mtx, NULL);
-#else
- for (i = 0; i < sc->num_cqueues; i++)
- pthread_mutex_init(&cq[i].mtx, NULL);
-#endif
}
}
@@ -521,21 +539,11 @@ pci_nvme_init_ctrldata(struct pci_nvme_softc *sc)
cd->mdts = NVME_MDTS; /* max data transfer size (2^mdts * CAP.MPSMIN) */
- cd->ver = 0x00010300;
+ cd->ver = NVME_REV(1,4);
+ cd->cntrltype = NVME_CNTRLTYPE_IO;
cd->oacs = 1 << NVME_CTRLR_DATA_OACS_FORMAT_SHIFT;
-#ifndef __FreeBSD__
- /*
- * Reported upstream against https://reviews.freebsd.org/D32953
- * which introduced support for the namespace attribute changed AEN
- * and the corresponding changed namespace log page, without setting
- * the bit in oaes. A future sync will likely include this
- * definition in usr/src/contrib/bhyve/dev/nvme/nvme.h once it's
- * fixed there.
- */
-#define NVME_CTRLR_DATA_OAES_NSCHANGE_SHIFT (8)
- cd->oaes = 1 << NVME_CTRLR_DATA_OAES_NSCHANGE_SHIFT;
-#endif
+ cd->oaes = NVMEB(NVME_CTRLR_DATA_OAES_NS_ATTR);
cd->acl = 2;
cd->aerl = 4;
@@ -548,6 +556,7 @@ pci_nvme_init_ctrldata(struct pci_nvme_softc *sc)
/* Warning Composite Temperature Threshold */
cd->wctemp = 0x0157;
+ cd->cctemp = 0x0157;
cd->sqes = (6 << NVME_CTRLR_DATA_SQES_MAX_SHIFT) |
(6 << NVME_CTRLR_DATA_SQES_MIN_SHIFT);
@@ -568,7 +577,10 @@ pci_nvme_init_ctrldata(struct pci_nvme_softc *sc)
break;
}
- cd->fna = 0x03;
+ cd->fna = NVME_CTRLR_DATA_FNA_FORMAT_ALL_MASK <<
+ NVME_CTRLR_DATA_FNA_FORMAT_ALL_SHIFT;
+
+ cd->vwc = NVME_CTRLR_DATA_VWC_ALL_NO << NVME_CTRLR_DATA_VWC_ALL_SHIFT;
cd->power_state[0].mp = 10;
}
@@ -683,7 +695,7 @@ pci_nvme_init_logpages(struct pci_nvme_softc *sc)
sc->write_dunits_remainder = 999;
/* Set nominal Health values checked by implementations */
- sc->health_log.temperature = 310;
+ sc->health_log.temperature = NVME_TEMPERATURE;
sc->health_log.available_spare = 100;
sc->health_log.available_spare_threshold = 10;
}
@@ -691,21 +703,41 @@ pci_nvme_init_logpages(struct pci_nvme_softc *sc)
static void
pci_nvme_init_features(struct pci_nvme_softc *sc)
{
-
- sc->feat[0].set = nvme_feature_invalid_cb;
- sc->feat[0].get = nvme_feature_invalid_cb;
-
- sc->feat[NVME_FEAT_LBA_RANGE_TYPE].namespace_specific = true;
- sc->feat[NVME_FEAT_ERROR_RECOVERY].namespace_specific = true;
- sc->feat[NVME_FEAT_NUMBER_OF_QUEUES].set = nvme_feature_num_queues;
- sc->feat[NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION].set =
- nvme_feature_iv_config;
- /* Enable all AENs by default */
- sc->feat[NVME_FEAT_ASYNC_EVENT_CONFIGURATION].cdw11 = 0x31f;
- sc->feat[NVME_FEAT_PREDICTABLE_LATENCY_MODE_CONFIG].get =
- nvme_feature_invalid_cb;
- sc->feat[NVME_FEAT_PREDICTABLE_LATENCY_MODE_WINDOW].get =
- nvme_feature_invalid_cb;
+ enum nvme_feature fid;
+
+ for (fid = 0; fid < NVME_FID_MAX; fid++) {
+ switch (fid) {
+ case NVME_FEAT_ARBITRATION:
+ case NVME_FEAT_POWER_MANAGEMENT:
+ case NVME_FEAT_INTERRUPT_COALESCING: //XXX
+ case NVME_FEAT_WRITE_ATOMICITY:
+ /* Mandatory but no special handling required */
+ //XXX hang - case NVME_FEAT_PREDICTABLE_LATENCY_MODE_CONFIG:
+ //XXX hang - case NVME_FEAT_HOST_BEHAVIOR_SUPPORT:
+ // this returns a data buffer
+ break;
+ case NVME_FEAT_TEMPERATURE_THRESHOLD:
+ sc->feat[fid].set = nvme_feature_temperature;
+ break;
+ case NVME_FEAT_ERROR_RECOVERY:
+ sc->feat[fid].namespace_specific = true;
+ break;
+ case NVME_FEAT_NUMBER_OF_QUEUES:
+ sc->feat[fid].set = nvme_feature_num_queues;
+ break;
+ case NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION:
+ sc->feat[fid].set = nvme_feature_iv_config;
+ break;
+ case NVME_FEAT_ASYNC_EVENT_CONFIGURATION:
+ sc->feat[fid].set = nvme_feature_async_event;
+ /* Enable all AENs by default */
+ sc->feat[fid].cdw11 = PCI_NVME_AEN_DEFAULT_MASK;
+ break;
+ default:
+ sc->feat[fid].set = nvme_feature_invalid_cb;
+ sc->feat[fid].get = nvme_feature_invalid_cb;
+ }
+ }
}
static void
@@ -769,9 +801,6 @@ pci_nvme_aer_add(struct pci_nvme_softc *sc, uint16_t cid)
{
struct pci_nvme_aer *aer = NULL;
- if (pci_nvme_aer_limit_reached(sc))
- return (-1);
-
aer = calloc(1, sizeof(struct pci_nvme_aer));
if (aer == NULL)
return (-1);
@@ -927,35 +956,34 @@ pci_nvme_aen_process(struct pci_nvme_softc *sc)
lid = NVME_LOG_HEALTH_INFORMATION;
break;
case PCI_NVME_AE_TYPE_NOTICE:
- if (aen->event_data >= PCI_NVME_AE_INFO_MAX) {
+ if (aen->event_data >= PCI_NVME_AEI_NOTICE_MAX) {
EPRINTLN("%s unknown AEN notice type %u",
__func__, aen->event_data);
status = NVME_SC_INTERNAL_DEVICE_ERROR;
break;
}
- mask >>= 8;
- if (((1 << aen->event_data) & mask) == 0)
+ if ((PCI_NVME_AEI_NOTICE_MASK(aen->event_data) & mask) == 0)
continue;
switch (aen->event_data) {
- case PCI_NVME_AE_INFO_NS_ATTR_CHANGED:
+ case PCI_NVME_AEI_NOTICE_NS_ATTR_CHANGED:
lid = NVME_LOG_CHANGED_NAMESPACE;
break;
- case PCI_NVME_AE_INFO_FW_ACTIVATION:
+ case PCI_NVME_AEI_NOTICE_FW_ACTIVATION:
lid = NVME_LOG_FIRMWARE_SLOT;
break;
- case PCI_NVME_AE_INFO_TELEMETRY_CHANGE:
+ case PCI_NVME_AEI_NOTICE_TELEMETRY_CHANGE:
lid = NVME_LOG_TELEMETRY_CONTROLLER_INITIATED;
break;
- case PCI_NVME_AE_INFO_ANA_CHANGE:
- lid = NVME_LOG_ASYMMETRIC_NAMESPAVE_ACCESS; //TODO spelling
+ case PCI_NVME_AEI_NOTICE_ANA_CHANGE:
+ lid = NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS;
break;
- case PCI_NVME_AE_INFO_PREDICT_LATENCY_CHANGE:
+ case PCI_NVME_AEI_NOTICE_PREDICT_LATENCY_CHANGE:
lid = NVME_LOG_PREDICTABLE_LATENCY_EVENT_AGGREGATE;
break;
- case PCI_NVME_AE_INFO_LBA_STATUS_ALERT:
+ case PCI_NVME_AEI_NOTICE_LBA_STATUS_ALERT:
lid = NVME_LOG_LBA_STATUS_INFORMATION;
break;
- case PCI_NVME_AE_INFO_ENDURANCE_GROUP_CHANGE:
+ case PCI_NVME_AEI_NOTICE_ENDURANCE_GROUP_CHANGE:
lid = NVME_LOG_ENDURANCE_GROUP_EVENT_AGGREGATE;
break;
default:
@@ -1019,10 +1047,9 @@ pci_nvme_reset_locked(struct pci_nvme_softc *sc)
sc->regs.cap_hi = 1 << NVME_CAP_HI_REG_CSS_NVM_SHIFT;
- sc->regs.vs = 0x00010300; /* NVMe v1.3 */
+ sc->regs.vs = NVME_REV(1,4); /* NVMe v1.4 */
sc->regs.cc = 0;
- sc->regs.csts = 0;
assert(sc->submit_queues != NULL);
@@ -1047,6 +1074,12 @@ pci_nvme_reset_locked(struct pci_nvme_softc *sc)
pci_nvme_aer_destroy(sc);
pci_nvme_aen_destroy(sc);
+
+ /*
+ * Clear CSTS.RDY last to prevent the host from enabling Controller
+ * before cleanup completes
+ */
+ sc->regs.csts = 0;
}
static void
@@ -1360,6 +1393,7 @@ static int
nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command,
struct nvme_completion* compl)
{
+ uint64_t logoff;
uint32_t logsize;
uint8_t logpage = command->cdw10 & 0xFF;
@@ -1377,15 +1411,28 @@ nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command,
*/
logsize = ((command->cdw11 << 16) | (command->cdw10 >> 16)) + 1;
logsize *= sizeof(uint32_t);
+ logoff = ((uint64_t)(command->cdw13) << 32) | command->cdw12;
switch (logpage) {
case NVME_LOG_ERROR:
+ if (logoff >= sizeof(sc->err_log)) {
+ pci_nvme_status_genc(&compl->status,
+ NVME_SC_INVALID_FIELD);
+ break;
+ }
+
nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
- command->prp2, (uint8_t *)&sc->err_log,
- MIN(logsize, sizeof(sc->err_log)),
+ command->prp2, (uint8_t *)&sc->err_log + logoff,
+ MIN(logsize - logoff, sizeof(sc->err_log)),
NVME_COPY_TO_PRP);
break;
case NVME_LOG_HEALTH_INFORMATION:
+ if (logoff >= sizeof(sc->health_log)) {
+ pci_nvme_status_genc(&compl->status,
+ NVME_SC_INVALID_FIELD);
+ break;
+ }
+
pthread_mutex_lock(&sc->mtx);
memcpy(&sc->health_log.data_units_read, &sc->read_data_units,
sizeof(sc->health_log.data_units_read));
@@ -1398,20 +1445,32 @@ nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command,
pthread_mutex_unlock(&sc->mtx);
nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
- command->prp2, (uint8_t *)&sc->health_log,
- MIN(logsize, sizeof(sc->health_log)),
+ command->prp2, (uint8_t *)&sc->health_log + logoff,
+ MIN(logsize - logoff, sizeof(sc->health_log)),
NVME_COPY_TO_PRP);
break;
case NVME_LOG_FIRMWARE_SLOT:
+ if (logoff >= sizeof(sc->fw_log)) {
+ pci_nvme_status_genc(&compl->status,
+ NVME_SC_INVALID_FIELD);
+ break;
+ }
+
nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
- command->prp2, (uint8_t *)&sc->fw_log,
- MIN(logsize, sizeof(sc->fw_log)),
+ command->prp2, (uint8_t *)&sc->fw_log + logoff,
+ MIN(logsize - logoff, sizeof(sc->fw_log)),
NVME_COPY_TO_PRP);
break;
case NVME_LOG_CHANGED_NAMESPACE:
+ if (logoff >= sizeof(sc->ns_log)) {
+ pci_nvme_status_genc(&compl->status,
+ NVME_SC_INVALID_FIELD);
+ break;
+ }
+
nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
- command->prp2, (uint8_t *)&sc->ns_log,
- MIN(logsize, sizeof(sc->ns_log)),
+ command->prp2, (uint8_t *)&sc->ns_log + logoff,
+ MIN(logsize - logoff, sizeof(sc->ns_log)),
NVME_COPY_TO_PRP);
memset(&sc->ns_log, 0, sizeof(sc->ns_log));
break;
@@ -1444,6 +1503,12 @@ nvme_opc_identify(struct pci_nvme_softc* sc, struct nvme_command* command,
switch (command->cdw10 & 0xFF) {
case 0x00: /* return Identify Namespace data structure */
+ /* Global NS only valid with NS Management */
+ if (command->nsid == NVME_GLOBAL_NAMESPACE_TAG) {
+ pci_nvme_status_genc(&status,
+ NVME_SC_INVALID_NAMESPACE_OR_FORMAT);
+ break;
+ }
nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
command->prp2, (uint8_t *)&sc->nsdata, sizeof(sc->nsdata),
NVME_COPY_TO_PRP);
@@ -1629,7 +1694,65 @@ nvme_feature_iv_config(struct pci_nvme_softc *sc,
pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS);
}
}
+}
+
+#define NVME_ASYNC_EVENT_ENDURANCE_GROUP (0x4000)
+static void
+nvme_feature_async_event(struct pci_nvme_softc *sc,
+ struct nvme_feature_obj *feat,
+ struct nvme_command *command,
+ struct nvme_completion *compl)
+{
+
+ if (command->cdw11 & NVME_ASYNC_EVENT_ENDURANCE_GROUP)
+ pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
+}
+
+#define NVME_TEMP_THRESH_OVER 0
+#define NVME_TEMP_THRESH_UNDER 1
+static void
+nvme_feature_temperature(struct pci_nvme_softc *sc,
+ struct nvme_feature_obj *feat,
+ struct nvme_command *command,
+ struct nvme_completion *compl)
+{
+ uint16_t tmpth; /* Temperature Threshold */
+ uint8_t tmpsel; /* Threshold Temperature Select */
+ uint8_t thsel; /* Threshold Type Select */
+ bool set_crit = false;
+
+ tmpth = command->cdw11 & 0xffff;
+ tmpsel = (command->cdw11 >> 16) & 0xf;
+ thsel = (command->cdw11 >> 20) & 0x3;
+
+ DPRINTF("%s: tmpth=%#x tmpsel=%#x thsel=%#x", __func__, tmpth, tmpsel, thsel);
+
+ /* Check for unsupported values */
+ if (((tmpsel != 0) && (tmpsel != 0xf)) ||
+ (thsel > NVME_TEMP_THRESH_UNDER)) {
+ pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
+ return;
+ }
+
+ if (((thsel == NVME_TEMP_THRESH_OVER) && (NVME_TEMPERATURE >= tmpth)) ||
+ ((thsel == NVME_TEMP_THRESH_UNDER) && (NVME_TEMPERATURE <= tmpth)))
+ set_crit = true;
+
+ pthread_mutex_lock(&sc->mtx);
+ if (set_crit)
+ sc->health_log.critical_warning |=
+ NVME_CRIT_WARN_ST_TEMPERATURE;
+ else
+ sc->health_log.critical_warning &=
+ ~NVME_CRIT_WARN_ST_TEMPERATURE;
+ pthread_mutex_unlock(&sc->mtx);
+
+ if (set_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);
}
static void
@@ -1699,6 +1822,11 @@ nvme_opc_set_features(struct pci_nvme_softc *sc, struct nvme_command *command,
}
feat = &sc->feat[fid];
+ if (feat->namespace_specific && (nsid == NVME_GLOBAL_NAMESPACE_TAG)) {
+ pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD);
+ return (1);
+ }
+
if (!feat->namespace_specific &&
!((nsid == 0) || (nsid == NVME_GLOBAL_NAMESPACE_TAG))) {
pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC,
@@ -1723,12 +1851,16 @@ nvme_opc_set_features(struct pci_nvme_softc *sc, struct nvme_command *command,
return (0);
}
+#define NVME_FEATURES_SEL_SUPPORTED 0x3
+#define NVME_FEATURES_NS_SPECIFIC (1 << 1)
+
static int
nvme_opc_get_features(struct pci_nvme_softc* sc, struct nvme_command* command,
struct nvme_completion* compl)
{
struct nvme_feature_obj *feat;
uint8_t fid = command->cdw10 & 0xFF;
+ uint8_t sel = (command->cdw10 >> 8) & 0x7;
DPRINTF("%s: Feature ID 0x%x (%s)", __func__, fid, nvme_fid_to_name(fid));
@@ -1747,7 +1879,10 @@ nvme_opc_get_features(struct pci_nvme_softc* sc, struct nvme_command* command,
}
if (compl->status == NVME_SC_SUCCESS) {
- compl->cdw0 = feat->cdw11;
+ if ((sel == NVME_FEATURES_SEL_SUPPORTED) && feat->namespace_specific)
+ compl->cdw0 = NVME_FEATURES_NS_SPECIFIC;
+ else
+ compl->cdw0 = feat->cdw11;
}
return (0);
@@ -1812,7 +1947,8 @@ nvme_opc_format_nvm(struct pci_nvme_softc* sc, struct nvme_command* command,
pci_nvme_status_genc(&compl->status,
NVME_SC_INTERNAL_DEVICE_ERROR);
pci_nvme_release_ioreq(sc, req);
- }
+ } else
+ compl->status = NVME_NO_STATUS;
}
return (1);
@@ -1939,12 +2075,22 @@ pci_nvme_handle_admin_cmd(struct pci_nvme_softc* sc, uint64_t value)
if ((sc->ctrldata.oacs &
(1 << NVME_CTRLR_DATA_OACS_FORMAT_SHIFT)) == 0) {
pci_nvme_status_genc(&compl.status, NVME_SC_INVALID_OPCODE);
+ break;
}
- compl.status = NVME_NO_STATUS;
nvme_opc_format_nvm(sc, cmd, &compl);
break;
+ case NVME_OPC_SECURITY_SEND:
+ case NVME_OPC_SECURITY_RECEIVE:
+ case NVME_OPC_SANITIZE:
+ case NVME_OPC_GET_LBA_STATUS:
+ DPRINTF("%s command OPC=%#x (unsupported)", __func__,
+ cmd->opc);
+ /* Valid but unsupported opcodes */
+ pci_nvme_status_genc(&compl.status, NVME_SC_INVALID_FIELD);
+ break;
default:
- DPRINTF("0x%x command is not implemented",
+ DPRINTF("%s command OPC=%#X (not implemented)",
+ __func__,
cmd->opc);
pci_nvme_status_genc(&compl.status, NVME_SC_INVALID_OPCODE);
}
@@ -2010,8 +2156,8 @@ pci_nvme_stats_write_read_update(struct pci_nvme_softc *sc, uint8_t opc,
}
/*
- * Check if the combination of Starting LBA (slba) and Number of Logical
- * Blocks (nlb) exceeds the range of the underlying storage.
+ * Check if the combination of Starting LBA (slba) and number of blocks
+ * exceeds the range of the underlying storage.
*
* Because NVMe specifies the SLBA in blocks as a uint64_t and blockif stores
* the capacity in bytes as a uint64_t, care must be taken to avoid integer
@@ -2019,7 +2165,7 @@ pci_nvme_stats_write_read_update(struct pci_nvme_softc *sc, uint8_t opc,
*/
static bool
pci_nvme_out_of_range(struct pci_nvme_blockstore *nvstore, uint64_t slba,
- uint32_t nlb)
+ uint32_t nblocks)
{
size_t offset, bytes;
@@ -2028,10 +2174,10 @@ pci_nvme_out_of_range(struct pci_nvme_blockstore *nvstore, uint64_t slba,
return (true);
offset = slba << nvstore->sectsz_bits;
- bytes = nlb << nvstore->sectsz_bits;
+ bytes = nblocks << nvstore->sectsz_bits;
/* Overflow check of Number of Logical Blocks */
- if ((nvstore->size - offset) < bytes)
+ if ((nvstore->size <= offset) || ((nvstore->size - offset) < bytes))
return (true);
return (false);
@@ -2352,7 +2498,8 @@ nvme_opc_write_read(struct pci_nvme_softc *sc,
nblocks = (cmd->cdw12 & 0xFFFF) + 1;
if (pci_nvme_out_of_range(nvstore, lba, nblocks)) {
- WPRINTF("%s command would exceed LBA range", __func__);
+ WPRINTF("%s command would exceed LBA range(slba=%#lx nblocks=%#lx)",
+ __func__, lba, nblocks);
pci_nvme_status_genc(status, NVME_SC_LBA_OUT_OF_RANGE);
goto out;
}
@@ -3069,7 +3216,7 @@ pci_nvme_resized(struct blockif_ctxt *bctxt, void *arg, size_t new_size)
sc->ns_log.ns[1] = 0;
pci_nvme_aen_post(sc, PCI_NVME_AE_TYPE_NOTICE,
- PCI_NVME_AE_INFO_NS_ATTR_CHANGED);
+ PCI_NVME_AEI_NOTICE_NS_ATTR_CHANGED);
}
static int
diff --git a/usr/src/cmd/bhyve/pci_passthru.c b/usr/src/cmd/bhyve/pci_passthru.c
index 0c512188b0..da64288bc5 100644
--- a/usr/src/cmd/bhyve/pci_passthru.c
+++ b/usr/src/cmd/bhyve/pci_passthru.c
@@ -32,13 +32,11 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
-#ifndef WITHOUT_CAPSICUM
-#include <sys/capsicum.h>
-#endif
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/pciio.h>
#include <sys/ioctl.h>
+#include <sys/stat.h>
#include <sys/pci.h>
@@ -47,9 +45,6 @@ __FBSDID("$FreeBSD$");
#include <machine/iodev.h>
-#ifndef WITHOUT_CAPSICUM
-#include <capsicum_helpers.h>
-#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -65,7 +60,7 @@ __FBSDID("$FreeBSD$");
#include "config.h"
#include "debug.h"
-#include "pci_emul.h"
+#include "pci_passthru.h"
#include "mem.h"
#define LEGACY_SUPPORT 1
@@ -75,7 +70,8 @@ __FBSDID("$FreeBSD$");
struct passthru_softc {
struct pci_devinst *psc_pi;
- struct pcibar psc_bar[PCI_BARMAX + 1];
+ /* ROM is handled like a BAR */
+ struct pcibar psc_bar[PCI_BARMAX_WITH_ROM + 1];
struct {
int capoff;
int msgctrl;
@@ -112,7 +108,7 @@ msi_caplen(int msgctrl)
}
static uint32_t
-read_config(const struct passthru_softc *sc, long reg, int width)
+passthru_read_config(const struct passthru_softc *sc, long reg, int width)
{
struct ppt_cfg_io pi;
@@ -126,7 +122,7 @@ read_config(const struct passthru_softc *sc, long reg, int width)
}
static void
-write_config(const struct passthru_softc *sc, long reg, int width,
+passthru_write_config(const struct passthru_softc *sc, long reg, int width,
uint32_t data)
{
struct ppt_cfg_io pi;
@@ -138,6 +134,22 @@ write_config(const struct passthru_softc *sc, long reg, int width,
(void) ioctl(sc->pptfd, PPT_CFG_WRITE, &pi);
}
+uint32_t
+read_config(struct pci_devinst *pi, long reg, int width)
+{
+ struct passthru_softc *sc = pi->pi_arg;
+
+ return (passthru_read_config(sc, reg, width));
+}
+
+void
+write_config(struct pci_devinst *pi, long reg, int width, uint32_t data)
+{
+ struct passthru_softc *sc = pi->pi_arg;
+
+ passthru_write_config(sc, reg, width, data);
+}
+
static int
passthru_get_bar(struct passthru_softc *sc, int bar, enum pcibar_type *type,
uint64_t *base, uint64_t *size)
@@ -258,24 +270,25 @@ cfginitmsi(struct passthru_softc *sc)
* Parse the capabilities and cache the location of the MSI
* and MSI-X capabilities.
*/
- sts = read_config(sc, PCIR_STATUS, 2);
+ sts = passthru_read_config(sc, PCIR_STATUS, 2);
if (sts & PCIM_STATUS_CAPPRESENT) {
- ptr = read_config(sc, PCIR_CAP_PTR, 1);
+ ptr = passthru_read_config(sc, PCIR_CAP_PTR, 1);
while (ptr != 0 && ptr != 0xff) {
- cap = read_config(sc, ptr + PCICAP_ID, 1);
+ cap = passthru_read_config(sc, ptr + PCICAP_ID, 1);
if (cap == PCIY_MSI) {
/*
* Copy the MSI capability into the config
* space of the emulated pci device
*/
sc->psc_msi.capoff = ptr;
- sc->psc_msi.msgctrl = read_config(sc,
+ sc->psc_msi.msgctrl = passthru_read_config(sc,
ptr + 2, 2);
sc->psc_msi.emulated = 0;
caplen = msi_caplen(sc->psc_msi.msgctrl);
capptr = ptr;
while (caplen > 0) {
- u32 = read_config(sc, capptr, 4);
+ u32 = passthru_read_config(sc,
+ capptr, 4);
pci_set_cfgdata32(pi, capptr, u32);
caplen -= 4;
capptr += 4;
@@ -289,7 +302,8 @@ cfginitmsi(struct passthru_softc *sc)
msixcap_ptr = (uint32_t*) &msixcap;
capptr = ptr;
while (caplen > 0) {
- u32 = read_config(sc, capptr, 4);
+ u32 = passthru_read_config(sc,
+ capptr, 4);
*msixcap_ptr = u32;
pci_set_cfgdata32(pi, capptr, u32);
caplen -= 4;
@@ -297,7 +311,7 @@ cfginitmsi(struct passthru_softc *sc)
msixcap_ptr++;
}
}
- ptr = read_config(sc, ptr + PCICAP_NEXTPTR, 1);
+ ptr = passthru_read_config(sc, ptr + PCICAP_NEXTPTR, 1);
}
}
@@ -334,7 +348,7 @@ cfginitmsi(struct passthru_softc *sc)
*/
if ((sts & PCIM_STATUS_CAPPRESENT) != 0 && sc->psc_msi.capoff == 0) {
int origptr, msiptr;
- origptr = read_config(sc, PCIR_CAP_PTR, 1);
+ origptr = passthru_read_config(sc, PCIR_CAP_PTR, 1);
msiptr = passthru_add_msicap(pi, 1, origptr);
sc->psc_msi.capoff = msiptr;
sc->psc_msi.msgctrl = pci_get_cfgdata16(pi, msiptr + 2);
@@ -593,7 +607,7 @@ cfginitbar(struct vmctx *ctx, struct passthru_softc *sc)
return (-1);
/* Use same lobits as physical bar */
- uint8_t lobits = read_config(sc, PCIR_BAR(i), 0x01);
+ uint8_t lobits = passthru_read_config(sc, PCIR_BAR(i), 0x01);
if (bartype == PCIBAR_MEM32 || bartype == PCIBAR_MEM64) {
lobits &= ~PCIM_BAR_MEM_BASE;
} else {
@@ -630,7 +644,8 @@ cfginit(struct vmctx *ctx, struct passthru_softc *sc)
return (-1);
}
- write_config(sc, PCIR_COMMAND, 2, pci_get_cfgdata16(pi, PCIR_COMMAND));
+ passthru_write_config(sc, PCIR_COMMAND, 2,
+ pci_get_cfgdata16(pi, PCIR_COMMAND));
/*
* We need to do this after PCIR_COMMAND got possibly updated, e.g.,
@@ -651,18 +666,84 @@ done:
}
static int
-passthru_legacy_config(nvlist_t *nvl, const char *opts)
+passthru_legacy_config(nvlist_t *nvl, const char *opt)
{
- if (opts == NULL)
- return (0);
+ char *config, *name, *tofree, *value;
- if (strncmp(opts, "/dev/ppt", 8) == 0)
- set_config_value_node(nvl, "path", opts);
+ if (opt == NULL)
+ return (0);
+ config = tofree = strdup(opt);
+ while ((name = strsep(&config, ",")) != NULL) {
+ value = strchr(name, '=');
+ if (value != NULL) {
+ *value++ = '\0';
+ set_config_value_node(nvl, name, value);
+ } else {
+ if (strncmp(name, "/dev/ppt", 8) != 0) {
+ EPRINTLN("passthru: invalid path \"%s\"", name);
+ free(tofree);
+ return (-1);
+ }
+ set_config_value_node(nvl, "path", name);
+ }
+ }
+ free(tofree);
return (0);
}
static int
+passthru_init_rom(struct vmctx *const ctx, struct passthru_softc *const sc,
+ const char *const romfile)
+{
+ if (romfile == NULL) {
+ return (0);
+ }
+
+ const int fd = open(romfile, O_RDONLY);
+ if (fd < 0) {
+ warnx("%s: can't open romfile \"%s\"", __func__, romfile);
+ return (-1);
+ }
+
+ struct stat sbuf;
+ if (fstat(fd, &sbuf) < 0) {
+ warnx("%s: can't fstat romfile \"%s\"", __func__, romfile);
+ close(fd);
+ return (-1);
+ }
+ const uint64_t rom_size = sbuf.st_size;
+
+ void *const rom_data = mmap(NULL, rom_size, PROT_READ, MAP_SHARED, fd,
+ 0);
+ if (rom_data == MAP_FAILED) {
+ warnx("%s: unable to mmap romfile \"%s\" (%d)", __func__,
+ romfile, errno);
+ close(fd);
+ return (-1);
+ }
+
+ void *rom_addr;
+ int error = pci_emul_alloc_rom(sc->psc_pi, rom_size, &rom_addr);
+ if (error) {
+ warnx("%s: failed to alloc rom segment", __func__);
+ munmap(rom_data, rom_size);
+ close(fd);
+ return (error);
+ }
+ memcpy(rom_addr, rom_data, rom_size);
+
+ sc->psc_bar[PCI_ROM_IDX].type = PCIBAR_ROM;
+ sc->psc_bar[PCI_ROM_IDX].addr = (uint64_t)rom_addr;
+ sc->psc_bar[PCI_ROM_IDX].size = rom_size;
+
+ munmap(rom_data, rom_size);
+ close(fd);
+
+ return (0);
+ }
+
+static int
passthru_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl)
{
int error, memflags, pptfd;
@@ -701,7 +782,15 @@ passthru_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl)
goto done;
/* initialize config space */
- error = cfginit(ctx, sc);
+ if ((error = cfginit(ctx, sc)) != 0)
+ goto done;
+
+ /* initialize ROM */
+ if ((error = passthru_init_rom(ctx, sc,
+ get_config_value_node(nvl, "rom"))) != 0) {
+ goto done;
+ }
+
done:
if (error) {
free(sc);
@@ -714,7 +803,8 @@ done:
static int
bar_access(int coff)
{
- if (coff >= PCIR_BAR(0) && coff < PCIR_BAR(PCI_BARMAX + 1))
+ if ((coff >= PCIR_BAR(0) && coff < PCIR_BAR(PCI_BARMAX + 1)) ||
+ coff == PCIR_BIOS)
return (1);
else
return (0);
@@ -788,12 +878,12 @@ passthru_cfgread(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
if (bytes <= 2)
return (-1);
*rv = pci_get_cfgdata16(pi, PCIR_COMMAND) << 16 |
- read_config(sc, PCIR_STATUS, 2);
+ passthru_read_config(sc, PCIR_STATUS, 2);
return (0);
}
/* Everything else just read from the device's config space */
- *rv = read_config(sc, coff, bytes);
+ *rv = passthru_read_config(sc, coff, bytes);
return (0);
}
@@ -862,7 +952,7 @@ passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
}
#endif
- write_config(sc, coff, bytes, val);
+ passthru_write_config(sc, coff, bytes, val);
if (coff == PCIR_COMMAND) {
cmd_old = pci_get_cfgdata16(pi, PCIR_COMMAND);
if (bytes == 1)
@@ -982,16 +1072,49 @@ passthru_mmio_addr(struct vmctx *ctx, struct pci_devinst *pi, int baridx,
}
static void
-passthru_addr(struct vmctx *ctx, struct pci_devinst *pi, int baridx,
- int enabled, uint64_t address)
+passthru_addr_rom(struct pci_devinst *const pi, const int idx,
+ const int enabled)
{
+ const uint64_t addr = pi->pi_bar[idx].addr;
+ const uint64_t size = pi->pi_bar[idx].size;
- if (pi->pi_bar[baridx].type == PCIBAR_IO)
- return;
- if (baridx == pci_msix_table_bar(pi))
- passthru_msix_addr(ctx, pi, baridx, enabled, address);
- else
- passthru_mmio_addr(ctx, pi, baridx, enabled, address);
+ if (!enabled) {
+ if (vm_munmap_memseg(pi->pi_vmctx, addr, size) != 0) {
+ errx(4, "%s: munmap_memseg @ [%016lx - %016lx] failed",
+ __func__, addr, addr + size);
+ }
+
+ } else {
+ if (vm_mmap_memseg(pi->pi_vmctx, addr, VM_PCIROM,
+ pi->pi_romoffset, size, PROT_READ | PROT_EXEC) != 0) {
+ errx(4, "%s: mnmap_memseg @ [%016lx - %016lx] failed",
+ __func__, addr, addr + size);
+ }
+ }
+}
+
+static void
+passthru_addr(struct vmctx *ctx, struct pci_devinst *pi, int baridx,
+ int enabled, uint64_t address)
+{
+ switch (pi->pi_bar[baridx].type) {
+ case PCIBAR_IO:
+ /* IO BARs are emulated */
+ break;
+ case PCIBAR_ROM:
+ passthru_addr_rom(pi, baridx, enabled);
+ break;
+ case PCIBAR_MEM32:
+ case PCIBAR_MEM64:
+ if (baridx == pci_msix_table_bar(pi))
+ passthru_msix_addr(ctx, pi, baridx, enabled, address);
+ else
+ passthru_mmio_addr(ctx, pi, baridx, enabled, address);
+ break;
+ default:
+ errx(4, "%s: invalid BAR type %d", __func__,
+ pi->pi_bar[baridx].type);
+ }
}
struct pci_devemu passthru = {
diff --git a/usr/src/cmd/bhyve/pci_passthru.h b/usr/src/cmd/bhyve/pci_passthru.h
new file mode 100644
index 0000000000..9cc1d2d07a
--- /dev/null
+++ b/usr/src/cmd/bhyve/pci_passthru.h
@@ -0,0 +1,18 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Beckhoff Automation GmbH & Co. KG
+ * Author: Corvin K<C3><B6>hne <c.koehne@beckhoff.com>
+ */
+
+#ifndef _PCI_PASSTHRU_H_
+#define _PCI_PASSTHRU_H_
+
+#include <vmmapi.h>
+
+#include "pci_emul.h"
+
+uint32_t read_config(struct pci_devinst *pi, long reg, int width);
+void write_config(struct pci_devinst *pi, long reg, int width, uint32_t data);
+
+#endif /* _PCI_PASSTHRU_H_ */
diff --git a/usr/src/cmd/bhyve/pci_virtio_console.c b/usr/src/cmd/bhyve/pci_virtio_console.c
index a153dc7ae3..59099e688e 100644
--- a/usr/src/cmd/bhyve/pci_virtio_console.c
+++ b/usr/src/cmd/bhyve/pci_virtio_console.c
@@ -725,9 +725,7 @@ pci_vtcon_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl)
sc->vsc_config->cols = 80;
sc->vsc_config->rows = 25;
-#ifndef __FreeBSD__
pthread_mutex_init(&sc->vsc_mtx, NULL);
-#endif
vi_softc_linkup(&sc->vsc_vs, &vtcon_vi_consts, sc, pi, sc->vsc_queues);
sc->vsc_vs.vs_mtx = &sc->vsc_mtx;
diff --git a/usr/src/cmd/bhyve/pci_virtio_rnd.c b/usr/src/cmd/bhyve/pci_virtio_rnd.c
index 8e7f995e9f..4aff95a34e 100644
--- a/usr/src/cmd/bhyve/pci_virtio_rnd.c
+++ b/usr/src/cmd/bhyve/pci_virtio_rnd.c
@@ -179,9 +179,7 @@ pci_vtrnd_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl)
sc = calloc(1, sizeof(struct pci_vtrnd_softc));
-#ifndef __FreeBSD__
pthread_mutex_init(&sc->vrsc_mtx, NULL);
-#endif
vi_softc_linkup(&sc->vrsc_vs, &vtrnd_vi_consts, sc, pi, &sc->vrsc_vq);
sc->vrsc_vs.vs_mtx = &sc->vrsc_mtx;
diff --git a/usr/src/cmd/bhyve/pci_virtio_scsi.c b/usr/src/cmd/bhyve/pci_virtio_scsi.c
index b080749f79..6f00f58811 100644
--- a/usr/src/cmd/bhyve/pci_virtio_scsi.c
+++ b/usr/src/cmd/bhyve/pci_virtio_scsi.c
@@ -700,6 +700,8 @@ pci_vtscsi_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl)
return (1);
}
+ pthread_mutex_init(&sc->vss_mtx, NULL);
+
vi_softc_linkup(&sc->vss_vs, &vtscsi_vi_consts, sc, pi, sc->vss_vq);
sc->vss_vs.vs_mtx = &sc->vss_mtx;
diff --git a/usr/src/cmd/bhyve/ps2kbd.c b/usr/src/cmd/bhyve/ps2kbd.c
index d7e2fef180..1abf0ece81 100644
--- a/usr/src/cmd/bhyve/ps2kbd.c
+++ b/usr/src/cmd/bhyve/ps2kbd.c
@@ -31,6 +31,7 @@
__FBSDID("$FreeBSD$");
#include <sys/types.h>
+#include <sys/stat.h>
#include <assert.h>
#include <stdbool.h>
@@ -39,9 +40,13 @@ __FBSDID("$FreeBSD$");
#include <strings.h>
#include <pthread.h>
#include <pthread_np.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "bhyverun.h"
#include "atkbdc.h"
#include "debug.h"
+#include "config.h"
#include "console.h"
/* keyboard device commands */
@@ -59,6 +64,10 @@ __FBSDID("$FreeBSD$");
#define PS2KBD_FIFOSZ 16
+#define PS2KBD_LAYOUT_BASEDIR "/usr/share/bhyve/kbdlayout/"
+
+#define MAX_PATHNAME 256
+
struct fifo {
uint8_t buf[PS2KBD_FIFOSZ];
int rindex; /* index to read from */
@@ -87,7 +96,7 @@ struct extended_translation {
/*
* FIXME: Pause/break and Print Screen/SysRq require special handling.
*/
-static const struct extended_translation extended_translations[] = {
+static struct extended_translation extended_translations[128] = {
{0xff08, 0x66}, /* Back space */
{0xff09, 0x0d}, /* Tab */
{0xff0d, 0x5a}, /* Return */
@@ -159,7 +168,7 @@ static const struct extended_translation extended_translations[] = {
};
/* ASCII to type 2 scancode lookup table */
-static const uint8_t ascii_translations[128] = {
+static uint8_t ascii_translations[128] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -337,7 +346,7 @@ ps2kbd_keysym_queue(struct ps2kbd_softc *sc,
assert(pthread_mutex_isowned_np(&sc->mtx));
int e0_prefix, found;
uint8_t code;
- const struct extended_translation *trans;
+ struct extended_translation *trans;
if (keycode) {
code = keyset1to2_translations[(uint8_t)(keycode & 0x7f)];
@@ -393,11 +402,91 @@ ps2kbd_event(int down, uint32_t keysym, uint32_t keycode, void *arg)
atkbdc_event(sc->atkbdc_sc, 1);
}
+static void
+ps2kbd_update_extended_translation(uint32_t keycode, uint32_t scancode, uint32_t prefix)
+{
+ int i = 0;
+
+ do {
+ if (extended_translations[i].keysym == keycode)
+ break;
+ } while(extended_translations[++i].keysym);
+
+ if (i == (sizeof(extended_translations) / sizeof(struct extended_translation) - 1))
+ return;
+
+ if (!extended_translations[i].keysym) {
+ extended_translations[i].keysym = keycode;
+
+ extended_translations[i+1].keysym = 0;
+ extended_translations[i+1].scancode = 0;
+ extended_translations[i+1].flags = 0;
+ }
+
+ extended_translations[i].scancode = (uint8_t)(scancode & 0xff);
+ extended_translations[i].flags = (prefix ? SCANCODE_E0_PREFIX : 0);
+}
+
+static void
+ps2kbd_setkbdlayout(void)
+{
+ int err;
+ int fd;
+ char path[MAX_PATHNAME];
+ char *buf, *next, *line;
+ struct stat sb;
+ size_t sz;
+ uint8_t ascii;
+ uint32_t keycode, scancode, prefix;
+
+ snprintf(path, MAX_PATHNAME, PS2KBD_LAYOUT_BASEDIR"%s", get_config_value("keyboard.layout") );
+
+ err = stat(path, &sb);
+ if (err)
+ return;
+
+ buf = (char *)malloc(sizeof(char) * sb.st_size);
+ if (buf == NULL)
+ return;
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ goto out;
+
+ sz = read(fd, buf, sb.st_size );
+
+ close(fd);
+
+ if (sz != sb.st_size )
+ goto out;
+
+ next = buf;
+ while ((line = strsep(&next, "\n")) != NULL) {
+ if (sscanf(line, "'%c',%x;", &ascii, &scancode) == 2) {
+ if (ascii < 0x80)
+ ascii_translations[ascii] = (uint8_t)(scancode & 0xff);
+ } else if (sscanf(line, "%x,%x,%x;", &keycode, &scancode, &prefix) == 3 ) {
+ ps2kbd_update_extended_translation(keycode, scancode, prefix);
+ } else if (sscanf(line, "%x,%x;", &keycode, &scancode) == 2) {
+ if (keycode < 0x80)
+ ascii_translations[(uint8_t)(keycode & 0xff)] = (uint8_t)(scancode & 0xff);
+ else
+ ps2kbd_update_extended_translation(keycode, scancode, 0);
+ }
+ }
+
+out:
+ free(buf);
+}
+
struct ps2kbd_softc *
ps2kbd_init(struct atkbdc_softc *atkbdc_sc)
{
struct ps2kbd_softc *sc;
+ if (get_config_value("keyboard.layout") != NULL)
+ ps2kbd_setkbdlayout();
+
sc = calloc(1, sizeof (struct ps2kbd_softc));
pthread_mutex_init(&sc->mtx, NULL);
fifo_init(sc);
diff --git a/usr/src/cmd/bhyve/uart_emul.c b/usr/src/cmd/bhyve/uart_emul.c
index 7ada0e76ee..2485c7ebb6 100644
--- a/usr/src/cmd/bhyve/uart_emul.c
+++ b/usr/src/cmd/bhyve/uart_emul.c
@@ -846,7 +846,7 @@ uart_init(uart_intr_func_t intr_assert, uart_intr_func_t intr_deassert,
static int
uart_sock_backend(struct uart_softc *sc, const char *inopts)
{
- char *opts;
+ char *opts, *tofree;
char *opt;
char *nextopt;
char *path = NULL;
@@ -858,7 +858,7 @@ uart_sock_backend(struct uart_softc *sc, const char *inopts)
return (-1);
}
- nextopt = opts;
+ tofree = nextopt = opts;
for (opt = strsep(&nextopt, ","); opt != NULL;
opt = strsep(&nextopt, ",")) {
if (path == NULL && *opt == '/') {
@@ -869,13 +869,13 @@ uart_sock_backend(struct uart_softc *sc, const char *inopts)
* XXX check for server and client options here. For now,
* everything is a server
*/
- free(opts);
+ free(tofree);
return (-1);
}
sc->usc_sock.clifd = -1;
if ((sc->usc_sock.servfd = init_sock(path)) == -1) {
- free(opts);
+ free(tofree);
return (-1);
}
sc->sock = true;
@@ -884,6 +884,7 @@ uart_sock_backend(struct uart_softc *sc, const char *inopts)
uart_sock_accept, sc);
assert(sc->usc_sock.servmev != NULL);
+ free(tofree);
return (0);
}
#endif /* not __FreeBSD__ */
diff --git a/usr/src/cmd/bhyve/virtio.h b/usr/src/cmd/bhyve/virtio.h
index ed6a99fa54..f14323cc4c 100644
--- a/usr/src/cmd/bhyve/virtio.h
+++ b/usr/src/cmd/bhyve/virtio.h
@@ -171,8 +171,8 @@
#define VIRTIO_DEV_NET 0x1000
#define VIRTIO_DEV_BLOCK 0x1001
#define VIRTIO_DEV_CONSOLE 0x1003
+#define VIRTIO_DEV_SCSI 0x1004
#define VIRTIO_DEV_RANDOM 0x1005
-#define VIRTIO_DEV_SCSI 0x1008
#define VIRTIO_DEV_9P 0x1009
#define VIRTIO_DEV_INPUT 0x1052
diff --git a/usr/src/contrib/bhyve/dev/nvme/nvme.h b/usr/src/contrib/bhyve/dev/nvme/nvme.h
index 6fbf2b758f..2f393ea1d1 100644
--- a/usr/src/contrib/bhyve/dev/nvme/nvme.h
+++ b/usr/src/contrib/bhyve/dev/nvme/nvme.h
@@ -251,6 +251,35 @@
#define NVME_CTRLR_DATA_MIC_ANAR_SHIFT (3)
#define NVME_CTRLR_DATA_MIC_ANAR_MASK (0x1)
+/** OAES - Optional Asynchronous Events Supported */
+/* supports Namespace Attribute Notices event */
+#define NVME_CTRLR_DATA_OAES_NS_ATTR_SHIFT (8)
+#define NVME_CTRLR_DATA_OAES_NS_ATTR_MASK (0x1)
+/* supports Firmware Activation Notices event */
+#define NVME_CTRLR_DATA_OAES_FW_ACTIVATE_SHIFT (9)
+#define NVME_CTRLR_DATA_OAES_FW_ACTIVATE_MASK (0x1)
+/* supports Asymmetric Namespace Access Change Notices event */
+#define NVME_CTRLR_DATA_OAES_ASYM_NS_CHANGE_SHIFT (11)
+#define NVME_CTRLR_DATA_OAES_ASYM_NS_CHANGE_MASK (0x1)
+/* supports Predictable Latency Event Aggregate Log Change Notices event */
+#define NVME_CTRLR_DATA_OAES_PREDICT_LATENCY_SHIFT (12)
+#define NVME_CTRLR_DATA_OAES_PREDICT_LATENCY_MASK (0x1)
+/* supports LBA Status Information Notices event */
+#define NVME_CTRLR_DATA_OAES_LBA_STATUS_SHIFT (13)
+#define NVME_CTRLR_DATA_OAES_LBA_STATUS_MASK (0x1)
+/* supports Endurance Group Event Aggregate Log Page Changes Notices event */
+#define NVME_CTRLR_DATA_OAES_ENDURANCE_GROUP_SHIFT (14)
+#define NVME_CTRLR_DATA_OAES_ENDURANCE_GROUP_MASK (0x1)
+/* supports Normal NVM Subsystem Shutdown event */
+#define NVME_CTRLR_DATA_OAES_NORMAL_SHUTDOWN_SHIFT (15)
+#define NVME_CTRLR_DATA_OAES_NORMAL_SHUTDOWN_MASK (0x1)
+/* supports Zone Descriptor Changed Notices event */
+#define NVME_CTRLR_DATA_OAES_ZONE_DESC_CHANGE_SHIFT (27)
+#define NVME_CTRLR_DATA_OAES_ZONE_DESC_CHANGE_MASK (0x1)
+/* supports Discovery Log Page Change Notification event */
+#define NVME_CTRLR_DATA_OAES_LOG_PAGE_CHANGE_SHIFT (31)
+#define NVME_CTRLR_DATA_OAES_LOG_PAGE_CHANGE_MASK (0x1)
+
/** OACS - optional admin command support */
/* supports security send/receive commands */
#define NVME_CTRLR_DATA_OACS_SECURITY_SHIFT (0)
@@ -547,6 +576,9 @@ enum nvme_critical_warning_state {
#define NVME_SS_PAGE_SSTAT_GDE_SHIFT (8)
#define NVME_SS_PAGE_SSTAT_GDE_MASK (0x1)
+/* Helper macro to combine *_MASK and *_SHIFT defines */
+#define NVMEB(name) (name##_MASK << name##_SHIFT)
+
/* CC register SHN field values */
enum shn_value {
NVME_SHN_NORMAL = 0x1,
@@ -560,8 +592,7 @@ enum shst_value {
NVME_SHST_COMPLETE = 0x2,
};
-struct nvme_registers
-{
+struct nvme_registers {
uint32_t cap_lo; /* controller capabilities */
uint32_t cap_hi;
uint32_t vs; /* version */
@@ -593,13 +624,12 @@ struct nvme_registers
struct {
uint32_t sq_tdbl; /* submission queue tail doorbell */
uint32_t cq_hdbl; /* completion queue head doorbell */
- } doorbell[1] __packed;
-} __packed;
+ } doorbell[1];
+};
_Static_assert(sizeof(struct nvme_registers) == 0x1008, "bad size for nvme_registers");
-struct nvme_command
-{
+struct nvme_command {
/* dword 0 */
uint8_t opc; /* opcode */
uint8_t fuse; /* fused operation */
@@ -628,7 +658,7 @@ struct nvme_command
uint32_t cdw13; /* command-specific */
uint32_t cdw14; /* command-specific */
uint32_t cdw15; /* command-specific */
-} __packed;
+};
_Static_assert(sizeof(struct nvme_command) == 16 * 4, "bad size for nvme_command");
@@ -646,7 +676,7 @@ struct nvme_completion {
/* dword 3 */
uint16_t cid; /* command identifier */
uint16_t status;
-} __packed;
+} __aligned(8); /* riscv: nvme_qpair_process_completions has better code gen */
_Static_assert(sizeof(struct nvme_completion) == 4 * 4, "bad size for nvme_completion");
@@ -654,7 +684,7 @@ struct nvme_dsm_range {
uint32_t attributes;
uint32_t length;
uint64_t starting_lba;
-} __packed;
+};
/* Largest DSM Trim that can be done */
#define NVME_MAX_DSM_TRIM 4096
@@ -1297,7 +1327,7 @@ enum nvme_log_page {
NVME_LOG_ENDURANCE_GROUP_INFORMATION = 0x09,
NVME_LOG_PREDICTABLE_LATENCY_PER_NVM_SET = 0x0a,
NVME_LOG_PREDICTABLE_LATENCY_EVENT_AGGREGATE = 0x0b,
- NVME_LOG_ASYMMETRIC_NAMESPAVE_ACCESS = 0x0c,
+ NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS = 0x0c,
NVME_LOG_PERSISTENT_EVENT_LOG = 0x0d,
NVME_LOG_LBA_STATUS_INFORMATION = 0x0e,
NVME_LOG_ENDURANCE_GROUP_EVENT_AGGREGATE = 0x0f,
@@ -1413,6 +1443,31 @@ struct nvme_command_effects_page {
_Static_assert(sizeof(struct nvme_command_effects_page) == 4096,
"bad size for nvme_command_effects_page");
+struct nvme_device_self_test_page {
+ uint8_t curr_operation;
+ uint8_t curr_compl;
+ uint8_t rsvd2[2];
+ struct {
+ uint8_t status;
+ uint8_t segment_num;
+ uint8_t valid_diag_info;
+ uint8_t rsvd3;
+ uint64_t poh;
+ uint32_t nsid;
+ /* Define as an array to simplify alignment issues */
+ uint8_t failing_lba[8];
+ uint8_t status_code_type;
+ uint8_t status_code;
+ uint8_t vendor_specific[2];
+ } __packed result[20];
+} __packed __aligned(4);
+
+/* Currently sparse/smatch incorrectly packs this struct in some situations. */
+#ifndef __CHECKER__
+_Static_assert(sizeof(struct nvme_device_self_test_page) == 564,
+ "bad size for nvme_device_self_test_page");
+#endif
+
struct nvme_res_notification_page {
uint64_t log_page_count;
uint8_t log_page_type;
@@ -1441,8 +1496,7 @@ struct nvme_sanitize_status_page {
_Static_assert(sizeof(struct nvme_sanitize_status_page) == 512,
"bad size for nvme_sanitize_status_page");
-struct intel_log_temp_stats
-{
+struct intel_log_temp_stats {
uint64_t current;
uint64_t overtemp_flag_last;
uint64_t overtemp_flag_life;
@@ -1456,8 +1510,7 @@ struct intel_log_temp_stats
_Static_assert(sizeof(struct intel_log_temp_stats) == 13 * 8, "bad size for intel_log_temp_stats");
-struct nvme_resv_reg_ctrlr
-{
+struct nvme_resv_reg_ctrlr {
uint16_t ctrlr_id; /* Controller ID */
uint8_t rcsts; /* Reservation Status */
uint8_t reserved3[5];
@@ -1467,8 +1520,7 @@ struct nvme_resv_reg_ctrlr
_Static_assert(sizeof(struct nvme_resv_reg_ctrlr) == 24, "bad size for nvme_resv_reg_ctrlr");
-struct nvme_resv_reg_ctrlr_ext
-{
+struct nvme_resv_reg_ctrlr_ext {
uint16_t ctrlr_id; /* Controller ID */
uint8_t rcsts; /* Reservation Status */
uint8_t reserved3[5];
@@ -1479,8 +1531,7 @@ struct nvme_resv_reg_ctrlr_ext
_Static_assert(sizeof(struct nvme_resv_reg_ctrlr_ext) == 64, "bad size for nvme_resv_reg_ctrlr_ext");
-struct nvme_resv_status
-{
+struct nvme_resv_status {
uint32_t gen; /* Generation */
uint8_t rtype; /* Reservation Type */
uint8_t regctl[2]; /* Number of Registered Controllers */
@@ -1492,8 +1543,7 @@ struct nvme_resv_status
_Static_assert(sizeof(struct nvme_resv_status) == 24, "bad size for nvme_resv_status");
-struct nvme_resv_status_ext
-{
+struct nvme_resv_status_ext {
uint32_t gen; /* Generation */
uint8_t rtype; /* Reservation Type */
uint8_t regctl[2]; /* Number of Registered Controllers */
@@ -2033,4 +2083,25 @@ void nvme_resv_status_ext_swapbytes(struct nvme_resv_status_ext *s __unused,
#endif
}
+static inline void
+nvme_device_self_test_swapbytes(struct nvme_device_self_test_page *s __unused)
+{
+#ifndef _LITTLE_ENDIAN
+ uint8_t *tmp;
+ uint32_t r, i;
+ uint8_t b;
+
+ for (r = 0; r < 20; r++) {
+ s->result[r].poh = le64toh(s->result[r].poh);
+ s->result[r].nsid = le32toh(s->result[r].nsid);
+ /* Unaligned 64-bit loads fail on some architectures */
+ tmp = s->result[r].failing_lba;
+ for (i = 0; i < 4; i++) {
+ b = tmp[i];
+ tmp[i] = tmp[7-i];
+ tmp[7-i] = b;
+ }
+ }
+#endif
+}
#endif /* __NVME_H__ */
diff --git a/usr/src/data/Makefile b/usr/src/data/Makefile
index a5a486ac28..2ae271ce87 100644
--- a/usr/src/data/Makefile
+++ b/usr/src/data/Makefile
@@ -12,6 +12,7 @@
#
# Copyright 2017 Nexenta Systems, Inc.
# Copyright 2019 Joyent, Inc.
+# Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
#
COMMON_SUBDIRS= consfonts \
@@ -20,7 +21,7 @@ COMMON_SUBDIRS= consfonts \
terminfo \
zoneinfo
-i386_SUBDIRS= amdpmc perfmon ucode
+i386_SUBDIRS= amdpmc bhyve perfmon ucode
SUBDIRS = $(COMMON_SUBDIRS) $($(MACH)_SUBDIRS)
diff --git a/usr/src/data/bhyve/Makefile b/usr/src/data/bhyve/Makefile
new file mode 100644
index 0000000000..d20a8f6590
--- /dev/null
+++ b/usr/src/data/bhyve/Makefile
@@ -0,0 +1,32 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
+#
+
+SUBDIRS = kbdlayout
+
+all := TARGET=all
+clean := TARGET=clean
+clobber := TARGET=clobber
+install := TARGET=install
+
+.PARALLEL: $(SUBDIRS)
+
+.KEEP_STATE:
+
+all clean clobber install: $(SUBDIRS)
+
+$(SUBDIRS): FRC
+ cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
diff --git a/usr/src/data/bhyve/kbdlayout/Makefile b/usr/src/data/bhyve/kbdlayout/Makefile
new file mode 100644
index 0000000000..3bf1098589
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/Makefile
@@ -0,0 +1,70 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+# Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
+
+include ../../Makefile.data
+
+ROOTSHBHYVE= $(ROOTSH)/bhyve
+ROOTSHBHYVEKBD= $(ROOTSHBHYVE)/kbdlayout
+
+FILES= default \
+ am \
+ be be_acc \
+ bg_bds bg_phonetic \
+ br br_noacc \
+ centraleuropean \
+ ch ch_acc ch_macbook_acc ch-fr ch-fr_acc \
+ cz \
+ de de_acc de_noacc \
+ dk dk_macbook \
+ ee \
+ es es_acc es_dvorak \
+ fi \
+ fr fr_acc fr_dvorak fr_dvorak_acc fr_macbook \
+ gr gr_101_acc gr_elot_acc \
+ hr \
+ hu_101 hu_102 \
+ is is_acc \
+ it \
+ jp jp_capsctrl \
+ kz_io kz_kst \
+ latinamerican latinamerican_acc \
+ lt \
+ nl \
+ no no_dvorak nordic_asus-eee \
+ pl_dvorak \
+ pt pt_acc \
+ ru ru_shift ru_win \
+ se \
+ si \
+ tr tr_f \
+ ua ua_shift_alt \
+ uk uk_capsctrl uk_dvorak uk_macbook \
+ us_dvorak us_dvorakl us_dvorakp us_dvorakr us_dvorakx \
+ us_emacs us_unix
+
+ROOTFILES= $(FILES:%=$(ROOTSHBHYVEKBD)/%)
+
+$(ROOTFILES) := FILEMODE = 0444
+
+all:
+
+install: $(ROOTSHBHYVEKBD) $(ROOTFILES)
+
+clean clobber:
+
+$(ROOTSHBHYVEKBD):
+ $(INS.dir)
+
+$(ROOTSHBHYVEKBD)/%: %
+ $(INS.file)
+
diff --git a/usr/src/data/bhyve/kbdlayout/am b/usr/src/data/bhyve/kbdlayout/am
new file mode 100644
index 0000000000..c102fb1080
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/am
@@ -0,0 +1,10 @@
+# bhyve ps2kbd keyboard layout file
+# (am : Armenian phonetic layout)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+')',0x87; ) (0x29)
+'+',0xce; + (0x2b)
+
diff --git a/usr/src/data/bhyve/kbdlayout/be b/usr/src/data/bhyve/kbdlayout/be
new file mode 100644
index 0000000000..26f8cdc3ac
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/be
@@ -0,0 +1,45 @@
+# bhyve ps2kbd keyboard layout file
+# (be : Belgian)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x3e; ! (0x21)
+'"',0x26; " (0x22)
+'$',0x5b; $ (0x24)
+'%',0x52; % (0x25)
+'&',0x16; & (0x26)
+''',0x25; ' (0x27)
+'(',0x2e; ( (0x28)
+')',0x4e; ) (0x29)
+'*',0x5b; * (0x2a)
+'+',0x4a; + (0x2b)
+',',0x3a; , (0x2c)
+'-',0x55; - (0x2d)
+'.',0x41; . (0x2e)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x4a; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x3a; ? (0x3f)
+'A',0x15; A (0x41)
+'M',0x4c; M (0x4d)
+'Q',0x1c; Q (0x51)
+'W',0x1a; W (0x57)
+'Z',0x1d; Z (0x5a)
+'\',0x61; \ (0x5c)
+'^',0x54; ^ (0x5e)
+'_',0x55; _ (0x5f)
+'`',0x5d; ` (0x60)
+'a',0x15; a (0x61)
+'m',0x4c; m (0x6d)
+'q',0x1c; q (0x71)
+'w',0x1a; w (0x77)
+'z',0x1d; z (0x7a)
+'{',0x46; { (0x7b)
+'|',0x16; | (0x7c)
+'}',0x45; } (0x7d)
+'~',0x4a; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/be_acc b/usr/src/data/bhyve/kbdlayout/be_acc
new file mode 100644
index 0000000000..adf136634e
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/be_acc
@@ -0,0 +1,42 @@
+# bhyve ps2kbd keyboard layout file
+# (be_acc : Belgian (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x3e; ! (0x21)
+'"',0x26; " (0x22)
+'$',0x5b; $ (0x24)
+'%',0x52; % (0x25)
+'&',0x16; & (0x26)
+''',0x25; ' (0x27)
+'(',0x2e; ( (0x28)
+')',0x4e; ) (0x29)
+'*',0x5b; * (0x2a)
+'+',0x4a; + (0x2b)
+',',0x3a; , (0x2c)
+'-',0x55; - (0x2d)
+'.',0x41; . (0x2e)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x4a; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x3a; ? (0x3f)
+'A',0x15; A (0x41)
+'M',0x4c; M (0x4d)
+'Q',0x1c; Q (0x51)
+'W',0x1a; W (0x57)
+'Z',0x1d; Z (0x5a)
+'\',0x61; \ (0x5c)
+'_',0x55; _ (0x5f)
+'a',0x15; a (0x61)
+'m',0x4c; m (0x6d)
+'q',0x1c; q (0x71)
+'w',0x1a; w (0x77)
+'z',0x1d; z (0x7a)
+'{',0x46; { (0x7b)
+'|',0x16; | (0x7c)
+'}',0x45; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/bg_bds b/usr/src/data/bhyve/kbdlayout/bg_bds
new file mode 100644
index 0000000000..9c25ed4640
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/bg_bds
@@ -0,0 +1,10 @@
+# bhyve ps2kbd keyboard layout file
+# (bg_bds : Bulgarian (BDS))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'(',0xa9; ( (0x28)
+'*',0xb7; * (0x2a)
+
diff --git a/usr/src/data/bhyve/kbdlayout/bg_phonetic b/usr/src/data/bhyve/kbdlayout/bg_phonetic
new file mode 100644
index 0000000000..dfe972db5b
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/bg_phonetic
@@ -0,0 +1,9 @@
+# bhyve ps2kbd keyboard layout file
+# (bg_phonetic : Bulgarian (Phonetic))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'*',0xb7; * (0x2a)
+
diff --git a/usr/src/data/bhyve/kbdlayout/br b/usr/src/data/bhyve/kbdlayout/br
new file mode 100644
index 0000000000..b4605e1748
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/br
@@ -0,0 +1,19 @@
+# bhyve ps2kbd keyboard layout file
+# (br : Brazilian (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x0e; " (0x22)
+''',0x0e; ' (0x27)
+':',0x4a; : (0x3a)
+';',0x4a; ; (0x3b)
+'?',0x51; ? (0x3f)
+'[',0x5b; [ (0x5b)
+'\',0x61; \ (0x5c)
+']',0x5d; ] (0x5d)
+'{',0x5b; { (0x7b)
+'|',0x61; | (0x7c)
+'}',0x5d; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/br_noacc b/usr/src/data/bhyve/kbdlayout/br_noacc
new file mode 100644
index 0000000000..62bea6254c
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/br_noacc
@@ -0,0 +1,22 @@
+# bhyve ps2kbd keyboard layout file
+# (br_noacc : Brazilian (without accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x0e; " (0x22)
+''',0x0e; ' (0x27)
+':',0x4a; : (0x3a)
+';',0x4a; ; (0x3b)
+'?',0x51; ? (0x3f)
+'[',0x5b; [ (0x5b)
+'\',0x61; \ (0x5c)
+']',0x5d; ] (0x5d)
+'^',0x52; ^ (0x5e)
+'`',0x54; ` (0x60)
+'{',0x5b; { (0x7b)
+'|',0x61; | (0x7c)
+'}',0x5d; } (0x7d)
+'~',0x52; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/centraleuropean b/usr/src/data/bhyve/kbdlayout/centraleuropean
new file mode 100644
index 0000000000..7b3a2f883a
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/centraleuropean
@@ -0,0 +1,12 @@
+# bhyve ps2kbd keyboard layout file
+# (centraleuropean : Central European)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'Y',0x1a; Y (0x59)
+'Z',0x35; Z (0x5a)
+'y',0x1a; y (0x79)
+'z',0x35; z (0x7a)
+
diff --git a/usr/src/data/bhyve/kbdlayout/ch b/usr/src/data/bhyve/kbdlayout/ch
new file mode 100644
index 0000000000..c68f78a49e
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/ch
@@ -0,0 +1,36 @@
+# bhyve ps2kbd keyboard layout file
+# (ch : Swiss-German)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x5b; ! (0x21)
+'"',0x1e; " (0x22)
+'$',0x5d; $ (0x24)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x26; * (0x2a)
+'+',0x16; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'Y',0x1a; Y (0x59)
+'Z',0x35; Z (0x5a)
+'\',0x61; \ (0x5c)
+'^',0x55; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x55; ` (0x60)
+'y',0x1a; y (0x79)
+'z',0x35; z (0x7a)
+'{',0x52; { (0x7b)
+'|',0x16; | (0x7c)
+'}',0x5d; } (0x7d)
+'~',0x55; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/ch-fr b/usr/src/data/bhyve/kbdlayout/ch-fr
new file mode 100644
index 0000000000..33d747f58f
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/ch-fr
@@ -0,0 +1,36 @@
+# bhyve ps2kbd keyboard layout file
+# (ch-fr : Swiss-French)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x5b; ! (0x21)
+'"',0x1e; " (0x22)
+'$',0x5d; $ (0x24)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x26; * (0x2a)
+'+',0x16; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'Y',0x1a; Y (0x59)
+'Z',0x35; Z (0x5a)
+'\',0x61; \ (0x5c)
+'^',0x55; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x55; ` (0x60)
+'y',0x1a; y (0x79)
+'z',0x35; z (0x7a)
+'{',0x52; { (0x7b)
+'|',0x16; | (0x7c)
+'}',0x5d; } (0x7d)
+'~',0x55; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/ch-fr_acc b/usr/src/data/bhyve/kbdlayout/ch-fr_acc
new file mode 100644
index 0000000000..3d081fb671
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/ch-fr_acc
@@ -0,0 +1,33 @@
+# bhyve ps2kbd keyboard layout file
+# (ch-fr_acc : Swiss-French (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x5b; ! (0x21)
+'"',0x1e; " (0x22)
+'$',0x5d; $ (0x24)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x26; * (0x2a)
+'+',0x16; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'Y',0x1a; Y (0x59)
+'Z',0x35; Z (0x5a)
+'\',0x61; \ (0x5c)
+'_',0x4a; _ (0x5f)
+'y',0x1a; y (0x79)
+'z',0x35; z (0x7a)
+'{',0x52; { (0x7b)
+'|',0x16; | (0x7c)
+'}',0x5d; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/ch_acc b/usr/src/data/bhyve/kbdlayout/ch_acc
new file mode 100644
index 0000000000..5b916d444e
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/ch_acc
@@ -0,0 +1,33 @@
+# bhyve ps2kbd keyboard layout file
+# (ch_acc : Swiss-German (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x5b; ! (0x21)
+'"',0x1e; " (0x22)
+'$',0x5d; $ (0x24)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x26; * (0x2a)
+'+',0x16; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'Y',0x1a; Y (0x59)
+'Z',0x35; Z (0x5a)
+'\',0x61; \ (0x5c)
+'_',0x4a; _ (0x5f)
+'y',0x1a; y (0x79)
+'z',0x35; z (0x7a)
+'{',0x52; { (0x7b)
+'|',0x16; | (0x7c)
+'}',0x5d; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/ch_macbook_acc b/usr/src/data/bhyve/kbdlayout/ch_macbook_acc
new file mode 100644
index 0000000000..3c7a032beb
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/ch_macbook_acc
@@ -0,0 +1,37 @@
+# bhyve ps2kbd keyboard layout file
+# (ch_macbook_acc : Swiss-German Macbook/Macbook Pro (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x5b; ! (0x21)
+'"',0x1e; " (0x22)
+'$',0x5d; $ (0x24)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x26; * (0x2a)
+'+',0x16; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x0e; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x0e; > (0x3e)
+'?',0x4e; ? (0x3f)
+'@',0x34; @ (0x40)
+'Y',0x1a; Y (0x59)
+'Z',0x35; Z (0x5a)
+'[',0x2e; [ (0x5b)
+'\',0x61; \ (0x5c)
+']',0x36; ] (0x5d)
+'_',0x4a; _ (0x5f)
+'y',0x1a; y (0x79)
+'z',0x35; z (0x7a)
+'{',0x3e; { (0x7b)
+'|',0x3d; | (0x7c)
+'}',0x46; } (0x7d)
+'~',0x31; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/cz b/usr/src/data/bhyve/kbdlayout/cz
new file mode 100644
index 0000000000..98f6108231
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/cz
@@ -0,0 +1,11 @@
+# bhyve ps2kbd keyboard layout file
+# (cz : Czech (QWERTZ, accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+')',0x9b; ) (0x29)
+'*',0xb7; * (0x2a)
+'+',0x82; + (0x2b)
+
diff --git a/usr/src/data/bhyve/kbdlayout/de b/usr/src/data/bhyve/kbdlayout/de
new file mode 100644
index 0000000000..745f826a9d
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/de
@@ -0,0 +1,37 @@
+# bhyve ps2kbd keyboard layout file
+# (de : German)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'#',0x5d; # (0x23)
+'&',0x36; & (0x26)
+''',0x5d; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5b; * (0x2a)
+'+',0x5b; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'@',0x15; @ (0x40)
+'Y',0x1a; Y (0x59)
+'Z',0x35; Z (0x5a)
+'[',0x3e; [ (0x5b)
+'\',0x4e; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x0e; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'y',0x1a; y (0x79)
+'z',0x35; z (0x7a)
+'{',0x3d; { (0x7b)
+'|',0x61; | (0x7c)
+'}',0x45; } (0x7d)
+'~',0x5b; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/de_acc b/usr/src/data/bhyve/kbdlayout/de_acc
new file mode 100644
index 0000000000..2ba06f3d16
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/de_acc
@@ -0,0 +1,36 @@
+# bhyve ps2kbd keyboard layout file
+# (de_acc : German (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'#',0x5d; # (0x23)
+'&',0x36; & (0x26)
+''',0x5d; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5b; * (0x2a)
+'+',0x5b; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'@',0x15; @ (0x40)
+'Y',0x1a; Y (0x59)
+'Z',0x35; Z (0x5a)
+'[',0x3e; [ (0x5b)
+'\',0x4e; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x0e; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'y',0x1a; y (0x79)
+'z',0x35; z (0x7a)
+'{',0x3d; { (0x7b)
+'|',0x61; | (0x7c)
+'}',0x45; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/de_noacc b/usr/src/data/bhyve/kbdlayout/de_noacc
new file mode 100644
index 0000000000..4d215116e2
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/de_noacc
@@ -0,0 +1,38 @@
+# bhyve ps2kbd keyboard layout file
+# (de_noacc : German (no accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'#',0x5d; # (0x23)
+'&',0x36; & (0x26)
+''',0x55; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5b; * (0x2a)
+'+',0x5b; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'@',0x15; @ (0x40)
+'Y',0x1a; Y (0x59)
+'Z',0x35; Z (0x5a)
+'[',0x3e; [ (0x5b)
+'\',0x4e; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x0e; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x55; ` (0x60)
+'y',0x1a; y (0x79)
+'z',0x35; z (0x7a)
+'{',0x3d; { (0x7b)
+'|',0x61; | (0x7c)
+'}',0x45; } (0x7d)
+'~',0x5b; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/default b/usr/src/data/bhyve/kbdlayout/default
new file mode 100644
index 0000000000..8674c28028
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/default
@@ -0,0 +1,248 @@
+# bhyve ps2kbd keyboard layout file (US - default)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+# for those who create the Keyboard Layout File. ******************************
+# To create the keyboard layout file, first copy this 'default' file into the
+# same dir. with the layout name as the file name.
+# The file name is a character string that can be specified as it is in the
+# -k option of the bhyve command, so a normal language name is desirable.
+# Then, it is necessary to define the difference between the standard US keyboard
+# and the keyboard for each language according to the setting method described
+# in the comment below.
+#
+# Note that lines starting with '#' and blank lines are ignored.
+# In addition, the definition of the standard layout setting (US keyboard)
+# is described as a comment line below for reference.
+# So you usually only need to remove the '#' and fix it to the correct ScanCode
+# only on the lines of the key that you can't type correctly with the standard
+# US keyboard settings.
+
+
+# Alphabet/Number/Sign Keys ---------------------------------------------------
+# Format:
+# 'Chr',ScanCode(Hex); <Comment>
+# or
+# AsciiCode(Hex),ScanCode(Hex); <Comment>
+#
+# If there are ASCII characters that cannot be entered correctly with the
+# standard settings(US Keyboard layout), delete the "#" at the beginning of the
+# relevant line below and set the correct ScanCode.
+#
+# For example, when a Japanese Keyboard is used, the '@' sign cannot be input
+# correctly and the number '2' is input.
+# This is because the US keyboard can input the '@' sign with the Shift + number'2'
+# keys, and the ScanCode of the '@' sign is the number '2' key by default.
+# In this case, remove the '#' at the beginning of the line with the '@' sign
+# below and correct the ScanCode from 0x1e to 0x54 so that you can enter it
+# correctly.
+# ScanCode differs depending on the keyboard of eash language, so check it on
+# the Internet.
+# Note that keys that have no problems with input have the same settings as
+# the US keyboard, so you do not need to set anything below.
+# See the "/usr/share/bhyve/kbdlayout/jp106" file for the specific setting method.
+
+# '!',0x16; ! (0x21)
+# '"',0x52; " (0x22)
+# '#',0x26; # (0x23)
+# '$',0x25; $ (0x24)
+# '%',0x2e; % (0x25)
+# '&',0x3d; & (0x26)
+# ''',0x52; ' (0x27)
+# '(',0x46; ( (0x28)
+# ')',0x45; ) (0x29)
+# '*',0x3e; * (0x2a)
+# '+',0x55; + (0x2b)
+# ',',0x41; , (0x2c)
+# '-',0x4e; - (0x2d)
+# '.',0x49; . (0x2e)
+# '/',0x4a; / (0x2f)
+
+# '0',0x45; 0 (0x30)
+# '1',0x16; 1 (0x31)
+# '2',0x1e; 2 (0x32)
+# '3',0x26; 3 (0x33)
+# '4',0x25; 4 (0x34)
+# '5',0x2e; 5 (0x35)
+# '6',0x36; 6 (0x36)
+# '7',0x3d; 7 (0x37)
+# '8',0x3e; 8 (0x38)
+# '9',0x46; 9 (0x39)
+# ':',0x4c; : (0x3a)
+# ';',0x4c; ; (0x3b)
+# '<',0x41; < (0x3c)
+# '=',0x55; = (0x3d)
+# '>',0x49; > (0x3e)
+# '?',0x4a; ? (0x3f)
+
+# '@',0x1e; @ (0x40)
+# 'A',0x1c; A (0x41)
+# 'B',0x32; B (0x42)
+# 'C',0x21; C (0x43)
+# 'D',0x23; D (0x44)
+# 'E',0x24; E (0x45)
+# 'F',0x2b; F (0x46)
+# 'G',0x34; G (0x47)
+# 'H',0x33; H (0x48)
+# 'I',0x43; I (0x49)
+# 'J',0x3b; J (0x4a)
+# 'K',0x42; K (0x4b)
+# 'L',0x4b; L (0x4c)
+# 'M',0x3a; M (0x4d)
+# 'N',0x31; N (0x4e)
+# 'O',0x44; O (0x4f)
+
+# 'P',0x4d; P (0x50)
+# 'Q',0x15; Q (0x51)
+# 'R',0x2d; R (0x52)
+# 'S',0x1b; S (0x53)
+# 'T',0x2c; T (0x54)
+# 'U',0x3c; U (0x55)
+# 'V',0x2a; V (0x56)
+# 'W',0x1d; W (0x57)
+# 'X',0x22; X (0x58)
+# 'Y',0x35; Y (0x59)
+# 'Z',0x1a; Z (0x5a)
+# '[',0x54; [ (0x5b)
+# '\',0x5d; \ (0x5c)
+# ']',0x5b; ] (0x5d)
+# '^',0x36; ^ (0x5e)
+# '_',0x4e; _ (0x5f)
+
+# '`',0x0e; ` (0x60)
+# 'a',0x1c; a (0x61)
+# 'b',0x32; b (0x62)
+# 'c',0x21; c (0x63)
+# 'd',0x23; d (0x64)
+# 'e',0x24; e (0x65)
+# 'f',0x2b; f (0x66)
+# 'g',0x34; g (0x67)
+# 'h',0x33; h (0x68)
+# 'i',0x43; i (0x69)
+# 'j',0x3b; j (0x6a)
+# 'k',0x42; k (0x6b)
+# 'l',0x4b; l (0x6c)
+# 'm',0x3a; m (0x6d)
+# 'n',0x31; n (0x6e)
+# 'o',0x44; o (0x6f)
+
+# 'p',0x4d; p (0x70)
+# 'q',0x15; q (0x71)
+# 'r',0x2d; r (0x72)
+# 's',0x1b; s (0x73)
+# 't',0x2c; t (0x74)
+# 'u',0x3c; u (0x75)
+# 'v',0x2a; v (0x76)
+# 'w',0x1d; w (0x77)
+# 'x',0x22; x (0x78)
+# 'y',0x35; y (0x79)
+# 'z',0x1a; z (0x7a)
+# '{',0x54; { (0x7b)
+# '|',0x5d; | (0x7c)
+# '}',0x5b; } (0x7d)
+# '~',0x0e; ~ (0x7e)
+
+
+# Functional Keys -------------------------------------------------------------
+# Format:
+# Xorg KeySym(Hex:2Byte),ScanCode(Hex); <Comment>
+# or
+# Xorg KeySym(Hex:2Byte),ScanCode(Hex),Prefix(Hex); <Comment>
+#
+# Key definitions other than alphanumeric characters such as Enter and Escape
+# are set in this section.
+# If there is a key that can not be entered correctly with the standard settings
+# (US Keyboard layout),, delete the '#' at the beginning of the corresponding
+# line and set the correct scan code.
+# The Xorg KeySym Code can be checked by using the 'xev' command from X window
+# on the guest OS.
+# In addition, some keys have ScanCodes that have a Prefix Byte.
+# In this case, define '0xe0' as the third argument.(example Home Key,etc)
+# Note that keys that have no problems with input have the same settings as
+# the US keyboard, so you do not need to set anything below.
+# See the "/usr/share/bhyve/kbdlayout/jp106" file for the specific setting method.
+
+# 0xff08,0x66; Back space
+# 0xff09,0x0d; Tab
+# 0xff0d,0x5a; Return
+# 0xff1b,0x76; Escape
+# 0xff50,0x6c,0xe0; Home
+# 0xff51,0x6b,0xe0; Left arrow
+# 0xff52,0x75,0xe0; Up arrow
+# 0xff53,0x74,0xe0; Right arrow
+# 0xff54,0x72,0xe0; Down arrow
+# 0xff55,0x7d,0xe0; PgUp
+# 0xff56,0x7a,0xe0; PgDown
+# 0xff57,0x69,0xe0; End
+# 0xff63,0x70,0xe0; Ins
+# 0xff8d,0x5a,0xe0; Keypad Enter
+# 0xffe1,0x12; Left shift
+# 0xffe2,0x59; Right shift
+# 0xffe3,0x14; Left control
+# 0xffe4,0x14,0xe0; Right control
+# 0xffe9,0x11; Left alt
+# 0xfe03,0x11,0xe0; AltGr
+# 0xffea,0x11,0xe0; Right alt
+# 0xffeb,0x1f,0xe0; Left Windows
+# 0xffec,0x27,0xe0; 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
+# 0xffff,0x71,0xe0; Del
+# 0xff14,0x7e; ScrollLock
+
+
+# NumLock and Keypads ---------------------------------------------------------
+#
+# The numeric keypad settings are the same as the Functional Key section above.
+
+# 0xff7f,0x77; NumLock
+# 0xffaf,0x4a,0xe0; 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
+
+
+# Language Specific Keys -------------------------------------------------------
+#
+# If a key not exist in the US keyboard is added to the keyboard of each language,
+# it is necessary to add the combination of Xorg KeySym and ScanCode of the
+# corresponding key.
+# The setting format is the same as the Functional Key section above.
+# example:
+# 0xff2a,0x0e; Hankaku/Zenkaku|Kanji (Japanese 106 keyboard original Key)
+
+
diff --git a/usr/src/data/bhyve/kbdlayout/dk b/usr/src/data/bhyve/kbdlayout/dk
new file mode 100644
index 0000000000..5183691bfb
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/dk
@@ -0,0 +1,32 @@
+# bhyve ps2kbd keyboard layout file
+# (dk : Danish)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x5b; " (0x22)
+'&',0x36; & (0x26)
+''',0x55; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5d; * (0x2a)
+'+',0x4e; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'[',0x3e; [ (0x5b)
+'\',0x61; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x5b; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x55; ` (0x60)
+'{',0x3d; { (0x7b)
+'|',0x55; | (0x7c)
+'}',0x45; } (0x7d)
+'~',0x5b; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/dk_macbook b/usr/src/data/bhyve/kbdlayout/dk_macbook
new file mode 100644
index 0000000000..a9d9c1b743
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/dk_macbook
@@ -0,0 +1,35 @@
+# bhyve ps2kbd keyboard layout file
+# (dk_macbook : Danish (macbook))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'$',0x0e; $ (0x24)
+'&',0x36; & (0x26)
+''',0x5d; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5d; * (0x2a)
+'+',0x4e; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'@',0x5d; @ (0x40)
+'G',0x7a,0xe0; G (0x47)
+'I',0x6c,0xe0; I (0x49)
+'O',0x69,0xe0; O (0x4f)
+'Q',0x7d,0xe0; Q (0x51)
+'[',0x3e; [ (0x5b)
+'\',0x61; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x5b; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'|',0x43; | (0x7c)
+'~',0x5b; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/ee b/usr/src/data/bhyve/kbdlayout/ee
new file mode 100644
index 0000000000..c2ebbdb081
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/ee
@@ -0,0 +1,31 @@
+# bhyve ps2kbd keyboard layout file
+# (ee : Nordic layout on Asus eeePC Estonian)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x5d; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5d; * (0x2a)
+'+',0x4e; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'[',0x3e; [ (0x5b)
+'\',0x4e; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x52; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x55; ` (0x60)
+'{',0x3d; { (0x7b)
+'|',0x61; | (0x7c)
+'}',0x45; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/es b/usr/src/data/bhyve/kbdlayout/es
new file mode 100644
index 0000000000..54ffb24bfc
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/es
@@ -0,0 +1,28 @@
+# bhyve ps2kbd keyboard layout file
+# (es : Spanish (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5b; * (0x2a)
+'+',0x5b; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'\',0x0e; \ (0x5c)
+'_',0x4a; _ (0x5f)
+'{',0x52; { (0x7b)
+'|',0x16; | (0x7c)
+'}',0x5d; } (0x7d)
+'~',0x25; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/es_acc b/usr/src/data/bhyve/kbdlayout/es_acc
new file mode 100644
index 0000000000..cd091791c0
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/es_acc
@@ -0,0 +1,28 @@
+# bhyve ps2kbd keyboard layout file
+# (es_acc : Spanish (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5b; * (0x2a)
+'+',0x5b; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'\',0x0e; \ (0x5c)
+'_',0x4a; _ (0x5f)
+'{',0x52; { (0x7b)
+'|',0x16; | (0x7c)
+'}',0x5d; } (0x7d)
+'~',0x25; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/es_dvorak b/usr/src/data/bhyve/kbdlayout/es_dvorak
new file mode 100644
index 0000000000..b84e95c913
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/es_dvorak
@@ -0,0 +1,78 @@
+# bhyve ps2kbd keyboard layout file
+# (es_dvorak : Spanish Dvorak)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5b; * (0x2a)
+'+',0x5b; + (0x2b)
+',',0x1d; , (0x2c)
+'-',0x1a; - (0x2d)
+'.',0x15; . (0x2e)
+':',0x15; : (0x3a)
+';',0x1d; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'B',0x31; B (0x42)
+'C',0x43; C (0x43)
+'D',0x33; D (0x44)
+'E',0x23; E (0x45)
+'F',0x35; F (0x46)
+'G',0x3c; G (0x47)
+'H',0x44; H (0x48)
+'I',0x34; I (0x49)
+'J',0x21; J (0x4a)
+'K',0x2a; K (0x4b)
+'L',0x4d; L (0x4c)
+'N',0x4b; N (0x4e)
+'O',0x1b; O (0x4f)
+'P',0x2d; P (0x50)
+'Q',0x22; Q (0x51)
+'R',0x3b; R (0x52)
+'S',0x4c; S (0x53)
+'T',0x42; T (0x54)
+'U',0x2b; U (0x55)
+'V',0x49; V (0x56)
+'W',0x41; W (0x57)
+'X',0x32; X (0x58)
+'Y',0x2c; Y (0x59)
+'Z',0x4a; Z (0x5a)
+'\',0x0e; \ (0x5c)
+'_',0x1a; _ (0x5f)
+'b',0x31; b (0x62)
+'c',0x43; c (0x63)
+'d',0x33; d (0x64)
+'e',0x23; e (0x65)
+'f',0x35; f (0x66)
+'g',0x3c; g (0x67)
+'h',0x44; h (0x68)
+'i',0x34; i (0x69)
+'j',0x21; j (0x6a)
+'k',0x2a; k (0x6b)
+'l',0x4d; l (0x6c)
+'n',0x4b; n (0x6e)
+'o',0x1b; o (0x6f)
+'p',0x2d; p (0x70)
+'q',0x22; q (0x71)
+'r',0x3b; r (0x72)
+'s',0x4c; s (0x73)
+'t',0x42; t (0x74)
+'u',0x2b; u (0x75)
+'v',0x49; v (0x76)
+'w',0x41; w (0x77)
+'x',0x32; x (0x78)
+'y',0x2c; y (0x79)
+'z',0x4a; z (0x7a)
+'{',0x52; { (0x7b)
+'|',0x0e; | (0x7c)
+'}',0x5d; } (0x7d)
+'~',0x25; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/fi b/usr/src/data/bhyve/kbdlayout/fi
new file mode 100644
index 0000000000..c4bdea09a6
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/fi
@@ -0,0 +1,32 @@
+# bhyve ps2kbd keyboard layout file
+# (fi : Finnish)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x5d; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5d; * (0x2a)
+'+',0x4e; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'[',0x3e; [ (0x5b)
+'\',0x4e; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x5b; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x55; ` (0x60)
+'{',0x3d; { (0x7b)
+'|',0x4c; | (0x7c)
+'}',0x45; } (0x7d)
+'~',0x5b; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/fr b/usr/src/data/bhyve/kbdlayout/fr
new file mode 100644
index 0000000000..6009090ff0
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/fr
@@ -0,0 +1,46 @@
+# bhyve ps2kbd keyboard layout file
+# (fr : French French Canadian (accent keys) Swiss-French)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x4a; ! (0x21)
+'"',0x26; " (0x22)
+'$',0x5b; $ (0x24)
+'%',0x52; % (0x25)
+'&',0x16; & (0x26)
+''',0x25; ' (0x27)
+'(',0x2e; ( (0x28)
+')',0x4e; ) (0x29)
+'*',0x5d; * (0x2a)
+',',0x3a; , (0x2c)
+'-',0x36; - (0x2d)
+'.',0x41; . (0x2e)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'>',0x61; > (0x3e)
+'?',0x3a; ? (0x3f)
+'@',0x45; @ (0x40)
+'A',0x15; A (0x41)
+'M',0x4c; M (0x4d)
+'Q',0x1c; Q (0x51)
+'W',0x1a; W (0x57)
+'Z',0x1d; Z (0x5a)
+'[',0x2e; [ (0x5b)
+'\',0x3e; \ (0x5c)
+']',0x4e; ] (0x5d)
+'^',0x46; ^ (0x5e)
+'_',0x3e; _ (0x5f)
+'`',0x3d; ` (0x60)
+'a',0x15; a (0x61)
+'m',0x4c; m (0x6d)
+'q',0x1c; q (0x71)
+'w',0x1a; w (0x77)
+'z',0x1d; z (0x7a)
+'{',0x25; { (0x7b)
+'|',0x36; | (0x7c)
+'}',0x55; } (0x7d)
+'~',0x1e; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/fr_acc b/usr/src/data/bhyve/kbdlayout/fr_acc
new file mode 100644
index 0000000000..ef8730f62f
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/fr_acc
@@ -0,0 +1,46 @@
+# bhyve ps2kbd keyboard layout file
+# (fr_acc : French (accent keys) Swiss-French (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x4a; ! (0x21)
+'"',0x26; " (0x22)
+'$',0x5b; $ (0x24)
+'%',0x52; % (0x25)
+'&',0x16; & (0x26)
+''',0x25; ' (0x27)
+'(',0x2e; ( (0x28)
+')',0x4e; ) (0x29)
+'*',0x5d; * (0x2a)
+',',0x3a; , (0x2c)
+'-',0x36; - (0x2d)
+'.',0x41; . (0x2e)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'>',0x61; > (0x3e)
+'?',0x3a; ? (0x3f)
+'@',0x45; @ (0x40)
+'A',0x15; A (0x41)
+'M',0x4c; M (0x4d)
+'Q',0x1c; Q (0x51)
+'W',0x1a; W (0x57)
+'Z',0x1d; Z (0x5a)
+'[',0x2e; [ (0x5b)
+'\',0x3e; \ (0x5c)
+']',0x4e; ] (0x5d)
+'^',0x46; ^ (0x5e)
+'_',0x3e; _ (0x5f)
+'`',0x3d; ` (0x60)
+'a',0x15; a (0x61)
+'m',0x4c; m (0x6d)
+'q',0x1c; q (0x71)
+'w',0x1a; w (0x77)
+'z',0x1d; z (0x7a)
+'{',0x25; { (0x7b)
+'|',0x36; | (0x7c)
+'}',0x55; } (0x7d)
+'~',0x1e; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/fr_dvorak b/usr/src/data/bhyve/kbdlayout/fr_dvorak
new file mode 100644
index 0000000000..f739c8e155
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/fr_dvorak
@@ -0,0 +1,87 @@
+# bhyve ps2kbd keyboard layout file
+# (fr_dvorak : French Dvorak-like)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x2c; ! (0x21)
+'"',0x45; " (0x22)
+'#',0x5d; # (0x23)
+'%',0x55; % (0x25)
+'&',0x5b; & (0x26)
+''',0x1d; ' (0x27)
+'(',0x3d; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x61; * (0x2a)
+'+',0x61; + (0x2b)
+',',0x21; , (0x2c)
+'-',0x26; - (0x2d)
+'.',0x2c; . (0x2e)
+'/',0x2e; / (0x2f)
+':',0x15; : (0x3a)
+';',0x1a; ; (0x3b)
+'<',0x1d; < (0x3c)
+'=',0x16; = (0x3d)
+'>',0x24; > (0x3e)
+'?',0x15; ? (0x3f)
+'@',0x1a; @ (0x40)
+'A',0x1b; A (0x41)
+'B',0x34; B (0x42)
+'C',0x43; C (0x43)
+'D',0x4c; D (0x44)
+'E',0x2b; E (0x45)
+'F',0x33; F (0x46)
+'G',0x2d; G (0x47)
+'H',0x35; H (0x48)
+'I',0x2a; I (0x49)
+'J',0x4a; J (0x4a)
+'K',0x4d; K (0x4b)
+'L',0x41; L (0x4c)
+'M',0x44; M (0x4d)
+'N',0x4b; N (0x4e)
+'O',0x1c; O (0x4f)
+'P',0x49; P (0x50)
+'Q',0x22; Q (0x51)
+'R',0x3a; R (0x52)
+'S',0x3b; S (0x53)
+'T',0x42; T (0x54)
+'U',0x23; U (0x55)
+'V',0x3c; V (0x56)
+'W',0x52; W (0x57)
+'X',0x31; X (0x58)
+'Y',0x32; Y (0x59)
+'Z',0x54; Z (0x5a)
+'[',0x4e; [ (0x5b)
+'\',0x21; \ (0x5c)
+']',0x55; ] (0x5d)
+'`',0x3e; ` (0x60)
+'a',0x1b; a (0x61)
+'b',0x34; b (0x62)
+'c',0x43; c (0x63)
+'d',0x4c; d (0x64)
+'e',0x2b; e (0x65)
+'f',0x33; f (0x66)
+'g',0x2d; g (0x67)
+'h',0x35; h (0x68)
+'i',0x2a; i (0x69)
+'j',0x4a; j (0x6a)
+'k',0x4d; k (0x6b)
+'l',0x41; l (0x6c)
+'m',0x44; m (0x6d)
+'n',0x4b; n (0x6e)
+'o',0x1c; o (0x6f)
+'p',0x49; p (0x70)
+'q',0x22; q (0x71)
+'r',0x3a; r (0x72)
+'s',0x3b; s (0x73)
+'t',0x42; t (0x74)
+'u',0x23; u (0x75)
+'v',0x3c; v (0x76)
+'w',0x52; w (0x77)
+'x',0x31; x (0x78)
+'y',0x32; y (0x79)
+'z',0x54; z (0x7a)
+'|',0x4e; | (0x7c)
+'~',0x5d; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/fr_dvorak_acc b/usr/src/data/bhyve/kbdlayout/fr_dvorak_acc
new file mode 100644
index 0000000000..c126572b7e
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/fr_dvorak_acc
@@ -0,0 +1,86 @@
+# bhyve ps2kbd keyboard layout file
+# (fr_dvorak_acc : French Dvorak-like (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x2c; ! (0x21)
+'"',0x45; " (0x22)
+'#',0x5d; # (0x23)
+'%',0x55; % (0x25)
+'&',0x5b; & (0x26)
+''',0x1d; ' (0x27)
+'(',0x3d; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x0e; * (0x2a)
+'+',0x4e; + (0x2b)
+',',0x21; , (0x2c)
+'-',0x26; - (0x2d)
+'.',0x2c; . (0x2e)
+'/',0x1e; / (0x2f)
+':',0x15; : (0x3a)
+';',0x1a; ; (0x3b)
+'<',0x1d; < (0x3c)
+'=',0x16; = (0x3d)
+'>',0x24; > (0x3e)
+'?',0x15; ? (0x3f)
+'@',0x21; @ (0x40)
+'A',0x1b; A (0x41)
+'B',0x34; B (0x42)
+'C',0x43; C (0x43)
+'D',0x4c; D (0x44)
+'E',0x2b; E (0x45)
+'F',0x33; F (0x46)
+'G',0x2d; G (0x47)
+'H',0x35; H (0x48)
+'I',0x2a; I (0x49)
+'J',0x4a; J (0x4a)
+'K',0x4d; K (0x4b)
+'L',0x41; L (0x4c)
+'M',0x44; M (0x4d)
+'N',0x4b; N (0x4e)
+'O',0x1c; O (0x4f)
+'P',0x49; P (0x50)
+'Q',0x22; Q (0x51)
+'R',0x3a; R (0x52)
+'S',0x3b; S (0x53)
+'T',0x42; T (0x54)
+'U',0x23; U (0x55)
+'V',0x3c; V (0x56)
+'W',0x52; W (0x57)
+'X',0x31; X (0x58)
+'Y',0x32; Y (0x59)
+'Z',0x54; Z (0x5a)
+'[',0x4e; [ (0x5b)
+'\',0x2e; \ (0x5c)
+']',0x55; ] (0x5d)
+'_',0x0e; _ (0x5f)
+'a',0x1b; a (0x61)
+'b',0x34; b (0x62)
+'c',0x43; c (0x63)
+'d',0x4c; d (0x64)
+'e',0x2b; e (0x65)
+'f',0x33; f (0x66)
+'g',0x2d; g (0x67)
+'h',0x35; h (0x68)
+'i',0x2a; i (0x69)
+'j',0x4a; j (0x6a)
+'k',0x4d; k (0x6b)
+'l',0x41; l (0x6c)
+'m',0x44; m (0x6d)
+'n',0x4b; n (0x6e)
+'o',0x1c; o (0x6f)
+'p',0x49; p (0x70)
+'q',0x22; q (0x71)
+'r',0x3a; r (0x72)
+'s',0x3b; s (0x73)
+'t',0x42; t (0x74)
+'u',0x23; u (0x75)
+'v',0x3c; v (0x76)
+'w',0x52; w (0x77)
+'x',0x31; x (0x78)
+'y',0x32; y (0x79)
+'z',0x54; z (0x7a)
+'|',0x1a; | (0x7c)
+
diff --git a/usr/src/data/bhyve/kbdlayout/fr_macbook b/usr/src/data/bhyve/kbdlayout/fr_macbook
new file mode 100644
index 0000000000..ddb756c8a6
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/fr_macbook
@@ -0,0 +1,49 @@
+# bhyve ps2kbd keyboard layout file
+# (fr_macbook : French Macbook/Macbook Pro (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x3e; ! (0x21)
+'"',0x26; " (0x22)
+'#',0x0e; # (0x23)
+'$',0x5b; $ (0x24)
+'%',0x52; % (0x25)
+'&',0x16; & (0x26)
+''',0x25; ' (0x27)
+'(',0x2e; ( (0x28)
+')',0x4e; ) (0x29)
+'*',0x5b; * (0x2a)
+'+',0x4a; + (0x2b)
+',',0x3a; , (0x2c)
+'-',0x55; - (0x2d)
+'.',0x41; . (0x2e)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x4a; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x3a; ? (0x3f)
+'@',0x0e; @ (0x40)
+'A',0x15; A (0x41)
+'M',0x4c; M (0x4d)
+'Q',0x1c; Q (0x51)
+'W',0x1a; W (0x57)
+'Z',0x1d; Z (0x5a)
+'[',0x2e; [ (0x5b)
+'\',0x3e; \ (0x5c)
+']',0x4e; ] (0x5d)
+'^',0x46; ^ (0x5e)
+'_',0x55; _ (0x5f)
+'`',0x3d; ` (0x60)
+'a',0x15; a (0x61)
+'m',0x4c; m (0x6d)
+'q',0x1c; q (0x71)
+'w',0x1a; w (0x77)
+'z',0x1d; z (0x7a)
+'{',0x25; { (0x7b)
+'|',0x36; | (0x7c)
+'}',0x55; } (0x7d)
+'~',0x1e; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/gr b/usr/src/data/bhyve/kbdlayout/gr
new file mode 100644
index 0000000000..cba9175095
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/gr
@@ -0,0 +1,9 @@
+# bhyve ps2kbd keyboard layout file
+# (gr : Greek (104 keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'*',0xb7; * (0x2a)
+
diff --git a/usr/src/data/bhyve/kbdlayout/gr_101_acc b/usr/src/data/bhyve/kbdlayout/gr_101_acc
new file mode 100644
index 0000000000..1a4ef7657f
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/gr_101_acc
@@ -0,0 +1,9 @@
+# bhyve ps2kbd keyboard layout file
+# (gr_101_acc : Greek (101 keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'*',0xb7; * (0x2a)
+
diff --git a/usr/src/data/bhyve/kbdlayout/gr_elot_acc b/usr/src/data/bhyve/kbdlayout/gr_elot_acc
new file mode 100644
index 0000000000..2e84a99633
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/gr_elot_acc
@@ -0,0 +1,17 @@
+# bhyve ps2kbd keyboard layout file
+# (gr_elot_acc : Greek ELOT)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'#',0x5d; # (0x23)
+''',0x0e; ' (0x27)
+'*',0xb7; * (0x2a)
+'/',0x52; / (0x2f)
+'@',0x52; @ (0x40)
+'\',0x61; \ (0x5c)
+'|',0x61; | (0x7c)
+'~',0x5d; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/hr b/usr/src/data/bhyve/kbdlayout/hr
new file mode 100644
index 0000000000..8ec2e11dcb
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/hr
@@ -0,0 +1,36 @@
+# bhyve ps2kbd keyboard layout file
+# (hr : Croatian)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x55; * (0x2a)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'@',0x2a; @ (0x40)
+'Y',0x1a; Y (0x59)
+'Z',0x35; Z (0x5a)
+'[',0x2b; [ (0x5b)
+'\',0x15; \ (0x5c)
+']',0x34; ] (0x5d)
+'^',0x26; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x3d; ` (0x60)
+'y',0x1a; y (0x79)
+'z',0x35; z (0x7a)
+'{',0x32; { (0x7b)
+'|',0x1d; | (0x7c)
+'}',0x31; } (0x7d)
+'~',0x16; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/hu_101 b/usr/src/data/bhyve/kbdlayout/hu_101
new file mode 100644
index 0000000000..00d4176d1b
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/hu_101
@@ -0,0 +1,9 @@
+# bhyve ps2kbd keyboard layout file
+# (hu_101 : Hungarian (101 keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'*',0xb7; * (0x2a)
+
diff --git a/usr/src/data/bhyve/kbdlayout/hu_102 b/usr/src/data/bhyve/kbdlayout/hu_102
new file mode 100644
index 0000000000..eb9d0ae4e4
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/hu_102
@@ -0,0 +1,41 @@
+# bhyve ps2kbd keyboard layout file
+# (hu_102 : Hungarian (102 keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x25; ! (0x21)
+'"',0x1e; " (0x22)
+'#',0x22; # (0x23)
+'$',0x4c; $ (0x24)
+'&',0x21; & (0x26)
+''',0x16; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x4a; * (0x2a)
+'+',0x26; + (0x2b)
+'-',0x4a; - (0x2d)
+'0',0x0e; 0 (0x30)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x3a; < (0x3c)
+'=',0x3d; = (0x3d)
+'>',0x1a; > (0x3e)
+'?',0x41; ? (0x3f)
+'@',0x2a; @ (0x40)
+'Y',0x1a; Y (0x59)
+'Z',0x35; Z (0x5a)
+'[',0x2b; [ (0x5b)
+'\',0x15; \ (0x5c)
+']',0x34; ] (0x5d)
+'^',0x26; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x3d; ` (0x60)
+'y',0x1a; y (0x79)
+'z',0x35; z (0x7a)
+'{',0x32; { (0x7b)
+'|',0x1d; | (0x7c)
+'}',0x31; } (0x7d)
+'~',0x16; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/is b/usr/src/data/bhyve/kbdlayout/is
new file mode 100644
index 0000000000..4cfd793f73
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/is
@@ -0,0 +1,33 @@
+# bhyve ps2kbd keyboard layout file
+# (is : Icelandic)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x5b; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5d; * (0x2a)
+'+',0x5d; + (0x2b)
+'-',0x55; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x5b; ? (0x3f)
+'@',0x15; @ (0x40)
+'[',0x3e; [ (0x5b)
+'\',0x4e; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x0e; ^ (0x5e)
+'_',0x55; _ (0x5f)
+'`',0x5d; ` (0x60)
+'{',0x3d; { (0x7b)
+'|',0x4c; | (0x7c)
+'}',0x45; } (0x7d)
+'~',0x5b; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/is_acc b/usr/src/data/bhyve/kbdlayout/is_acc
new file mode 100644
index 0000000000..f7391b3529
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/is_acc
@@ -0,0 +1,32 @@
+# bhyve ps2kbd keyboard layout file
+# (is_acc : Icelandic (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x5b; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5d; * (0x2a)
+'+',0x5d; + (0x2b)
+'-',0x55; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x5b; ? (0x3f)
+'@',0x15; @ (0x40)
+'[',0x3e; [ (0x5b)
+'\',0x4e; \ (0x5c)
+']',0x46; ] (0x5d)
+'_',0x55; _ (0x5f)
+'`',0x5d; ` (0x60)
+'{',0x3d; { (0x7b)
+'|',0x4c; | (0x7c)
+'}',0x45; } (0x7d)
+'~',0x5b; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/it b/usr/src/data/bhyve/kbdlayout/it
new file mode 100644
index 0000000000..a286bf8684
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/it
@@ -0,0 +1,34 @@
+# bhyve ps2kbd keyboard layout file
+# (it : Italian)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'#',0x52; # (0x23)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5b; * (0x2a)
+'+',0x5b; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'@',0x15; @ (0x40)
+'[',0x3e; [ (0x5b)
+'\',0x0e; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x55; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x4e; ` (0x60)
+'{',0x3d; { (0x7b)
+'|',0x0e; | (0x7c)
+'}',0x45; } (0x7d)
+'~',0x55; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/jp b/usr/src/data/bhyve/kbdlayout/jp
new file mode 100644
index 0000000000..550571ea1d
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/jp
@@ -0,0 +1,36 @@
+# bhyve ps2kbd keyboard layout file
+# (jp : Japanese 106)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+# Alphabet/Number/Sign Keys ---------------------------------------------------
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x3d; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x52; * (0x2a)
+'+',0x4c; + (0x2b)
+':',0x52; : (0x3a)
+'=',0x4e; = (0x3d)
+'@',0x54; @ (0x40)
+'[',0x5b; [ (0x5b)
+'\',0x51; \ (0x5c)
+']',0x5d; ] (0x5d)
+'^',0x55; ^ (0x5e)
+'_',0x51; _ (0x5f)
+'`',0x54; ` (0x60)
+'{',0x5b; { (0x7b)
+'|',0x6a; | (0x7c)
+'}',0x5d; } (0x7d)
+'~',0x55; ~ (0x7e)
+
+# Language Specific Keys ------------------------------------------------------
+0xff2a,0x0e; Hankaku/Zenkaku|Kanji
+0xffe5,0x58; CapsLock
+0xff22,0x67; Muhenkan
+0xff23,0x64; Henkan_Mode
+0xff27,0x13; Katakana-Hiragana/RomaJi
+
diff --git a/usr/src/data/bhyve/kbdlayout/jp_capsctrl b/usr/src/data/bhyve/kbdlayout/jp_capsctrl
new file mode 100644
index 0000000000..46fd6e154a
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/jp_capsctrl
@@ -0,0 +1,37 @@
+# bhyve ps2kbd keyboard layout file
+# (jp.capsctrl : Japanese 106x)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+# Alphabet/Number/Sign Keys ---------------------------------------------------
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x3d; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x52; * (0x2a)
+'+',0x4c; + (0x2b)
+':',0x52; : (0x3a)
+'=',0x4e; = (0x3d)
+'@',0x54; @ (0x40)
+'[',0x5b; [ (0x5b)
+'\',0x51; \ (0x5c)
+']',0x5d; ] (0x5d)
+'^',0x55; ^ (0x5e)
+'_',0x51; _ (0x5f)
+'`',0x54; ` (0x60)
+'{',0x5b; { (0x7b)
+'|',0x6a; | (0x7c)
+'}',0x5d; } (0x7d)
+'~',0x55; ~ (0x7e)
+
+# Language Specific Keys ------------------------------------------------------
+0xff2a,0x0e; Hankaku/Zenkaku|Kanji
+0xffe5,0x58; CapsLock
+0xff22,0x67; Muhenkan
+0xff23,0x64; Henkan_Mode
+0xff27,0x13; Katakana-Hiragana/RomaJi
+0xffe3,0x58; Left control
+
diff --git a/usr/src/data/bhyve/kbdlayout/kz_io b/usr/src/data/bhyve/kbdlayout/kz_io
new file mode 100644
index 0000000000..c158028e0a
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/kz_io
@@ -0,0 +1,11 @@
+# bhyve ps2kbd keyboard layout file
+# (kz_io : Kazakh)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x82; " (0x22)
+'(',0xa9; ( (0x28)
+'*',0xb7; * (0x2a)
+
diff --git a/usr/src/data/bhyve/kbdlayout/kz_kst b/usr/src/data/bhyve/kbdlayout/kz_kst
new file mode 100644
index 0000000000..7c1281a7dc
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/kz_kst
@@ -0,0 +1,11 @@
+# bhyve ps2kbd keyboard layout file
+# (kz_kst : Kazakh)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x82; " (0x22)
+'(',0xa9; ( (0x28)
+'*',0xb7; * (0x2a)
+
diff --git a/usr/src/data/bhyve/kbdlayout/latinamerican b/usr/src/data/bhyve/kbdlayout/latinamerican
new file mode 100644
index 0000000000..ac2920ab4a
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/latinamerican
@@ -0,0 +1,33 @@
+# bhyve ps2kbd keyboard layout file
+# (latinamerican : Latin American)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5b; * (0x2a)
+'+',0x5b; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'@',0x15; @ (0x40)
+'[',0x52; [ (0x5b)
+'\',0x4e; \ (0x5c)
+']',0x5d; ] (0x5d)
+'^',0x52; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x5d; ` (0x60)
+'{',0x52; { (0x7b)
+'|',0x0e; | (0x7c)
+'}',0x5d; } (0x7d)
+'~',0x5b; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/latinamerican_acc b/usr/src/data/bhyve/kbdlayout/latinamerican_acc
new file mode 100644
index 0000000000..7fd97dc3db
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/latinamerican_acc
@@ -0,0 +1,31 @@
+# bhyve ps2kbd keyboard layout file
+# (latinamerican_acc : Latin American (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5b; * (0x2a)
+'+',0x5b; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'@',0x15; @ (0x40)
+'[',0x52; [ (0x5b)
+'\',0x4e; \ (0x5c)
+']',0x5d; ] (0x5d)
+'_',0x4a; _ (0x5f)
+'{',0x52; { (0x7b)
+'|',0x0e; | (0x7c)
+'}',0x5d; } (0x7d)
+'~',0x5b; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/lt b/usr/src/data/bhyve/kbdlayout/lt
new file mode 100644
index 0000000000..114d0624df
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/lt
@@ -0,0 +1,10 @@
+# bhyve ps2kbd keyboard layout file
+# (lt : Lithuanian Ukrainian (with Russian) (shift))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'*',0xb7; * (0x2a)
+0xffea,0x61; Right alt
+
diff --git a/usr/src/data/bhyve/kbdlayout/nl b/usr/src/data/bhyve/kbdlayout/nl
new file mode 100644
index 0000000000..f715494337
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/nl
@@ -0,0 +1,31 @@
+# bhyve ps2kbd keyboard layout file
+# (nl : Dutch (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x45; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5b; * (0x2a)
+'+',0x4c; + (0x2b)
+'-',0x4a; - (0x2d)
+'/',0x4e; / (0x2f)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x5d; < (0x3c)
+'=',0x4a; = (0x3d)
+'>',0x5d; > (0x3e)
+'?',0x4e; ? (0x3f)
+'@',0x0e; @ (0x40)
+'[',0x61; [ (0x5b)
+'\',0x4e; \ (0x5c)
+']',0x61; ] (0x5d)
+'_',0x3d; _ (0x5f)
+'{',0x3e; { (0x7b)
+'|',0x5b; | (0x7c)
+'}',0x46; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/no b/usr/src/data/bhyve/kbdlayout/no
new file mode 100644
index 0000000000..bd26206316
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/no
@@ -0,0 +1,32 @@
+# bhyve ps2kbd keyboard layout file
+# (no : Norwegian)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x5d; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5d; * (0x2a)
+'+',0x4e; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'[',0x3e; [ (0x5b)
+'\',0x55; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x5b; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x55; ` (0x60)
+'{',0x3d; { (0x7b)
+'|',0x0e; | (0x7c)
+'}',0x45; } (0x7d)
+'~',0x5b; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/no_dvorak b/usr/src/data/bhyve/kbdlayout/no_dvorak
new file mode 100644
index 0000000000..f419786459
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/no_dvorak
@@ -0,0 +1,81 @@
+# bhyve ps2kbd keyboard layout file
+# (no_dvorak : Norwegian dvorak)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x54; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x54; * (0x2a)
+'+',0x4e; + (0x2b)
+',',0x1d; , (0x2c)
+'-',0x52; - (0x2d)
+'.',0x24; . (0x2e)
+':',0x24; : (0x3a)
+';',0x1d; ; (0x3b)
+'<',0x5d; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x5d; > (0x3e)
+'?',0x4e; ? (0x3f)
+'B',0x31; B (0x42)
+'C',0x43; C (0x43)
+'D',0x33; D (0x44)
+'E',0x23; E (0x45)
+'F',0x35; F (0x46)
+'G',0x3c; G (0x47)
+'H',0x3b; H (0x48)
+'I',0x34; I (0x49)
+'J',0x21; J (0x4a)
+'K',0x2a; K (0x4b)
+'L',0x4d; L (0x4c)
+'N',0x4b; N (0x4e)
+'O',0x1b; O (0x4f)
+'P',0x2d; P (0x50)
+'Q',0x22; Q (0x51)
+'R',0x44; R (0x52)
+'S',0x4c; S (0x53)
+'T',0x42; T (0x54)
+'U',0x2b; U (0x55)
+'V',0x49; V (0x56)
+'W',0x41; W (0x57)
+'X',0x32; X (0x58)
+'Y',0x2c; Y (0x59)
+'Z',0x4a; Z (0x5a)
+'[',0x3e; [ (0x5b)
+'\',0x55; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x5b; ^ (0x5e)
+'_',0x52; _ (0x5f)
+'`',0x55; ` (0x60)
+'b',0x31; b (0x62)
+'c',0x43; c (0x63)
+'d',0x33; d (0x64)
+'e',0x23; e (0x65)
+'f',0x35; f (0x66)
+'g',0x3c; g (0x67)
+'h',0x3b; h (0x68)
+'i',0x34; i (0x69)
+'j',0x21; j (0x6a)
+'k',0x2a; k (0x6b)
+'l',0x4d; l (0x6c)
+'n',0x4b; n (0x6e)
+'o',0x1b; o (0x6f)
+'p',0x2d; p (0x70)
+'q',0x22; q (0x71)
+'r',0x44; r (0x72)
+'s',0x4c; s (0x73)
+'t',0x42; t (0x74)
+'u',0x2b; u (0x75)
+'v',0x49; v (0x76)
+'w',0x41; w (0x77)
+'x',0x32; x (0x78)
+'y',0x2c; y (0x79)
+'z',0x4a; z (0x7a)
+'{',0x3d; { (0x7b)
+'|',0x0e; | (0x7c)
+'}',0x45; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/nordic_asus-eee b/usr/src/data/bhyve/kbdlayout/nordic_asus-eee
new file mode 100644
index 0000000000..c0fb79ca4f
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/nordic_asus-eee
@@ -0,0 +1,32 @@
+# bhyve ps2kbd keyboard layout file
+# (nordic_asus-eee : Nordic layout on Asus eeePC)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x5d; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5d; * (0x2a)
+'+',0x4e; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'[',0x3e; [ (0x5b)
+'\',0x4e; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x5b; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x55; ` (0x60)
+'{',0x3d; { (0x7b)
+'|',0x4c; | (0x7c)
+'}',0x45; } (0x7d)
+'~',0x5b; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/pl_dvorak b/usr/src/data/bhyve/kbdlayout/pl_dvorak
new file mode 100644
index 0000000000..4162839eb8
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/pl_dvorak
@@ -0,0 +1,74 @@
+# bhyve ps2kbd keyboard layout file
+# (pl_dvorak : Polish Dvorak)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x15; " (0x22)
+''',0x15; ' (0x27)
+'+',0x5b; + (0x2b)
+',',0x1d; , (0x2c)
+'-',0x52; - (0x2d)
+'.',0x24; . (0x2e)
+'/',0x54; / (0x2f)
+':',0x1a; : (0x3a)
+';',0x1a; ; (0x3b)
+'<',0x1d; < (0x3c)
+'=',0x5b; = (0x3d)
+'>',0x24; > (0x3e)
+'?',0x54; ? (0x3f)
+'B',0x31; B (0x42)
+'C',0x43; C (0x43)
+'D',0x33; D (0x44)
+'E',0x23; E (0x45)
+'F',0x35; F (0x46)
+'G',0x3c; G (0x47)
+'H',0x3b; H (0x48)
+'I',0x34; I (0x49)
+'J',0x21; J (0x4a)
+'K',0x2a; K (0x4b)
+'L',0x4d; L (0x4c)
+'N',0x4b; N (0x4e)
+'O',0x1b; O (0x4f)
+'P',0x2d; P (0x50)
+'Q',0x22; Q (0x51)
+'R',0x44; R (0x52)
+'S',0x4c; S (0x53)
+'T',0x42; T (0x54)
+'U',0x2b; U (0x55)
+'V',0x49; V (0x56)
+'W',0x41; W (0x57)
+'X',0x32; X (0x58)
+'Y',0x2c; Y (0x59)
+'Z',0x4a; Z (0x5a)
+'[',0x4e; [ (0x5b)
+']',0x55; ] (0x5d)
+'_',0x52; _ (0x5f)
+'b',0x31; b (0x62)
+'c',0x43; c (0x63)
+'d',0x33; d (0x64)
+'e',0x23; e (0x65)
+'f',0x35; f (0x66)
+'g',0x3c; g (0x67)
+'h',0x3b; h (0x68)
+'i',0x34; i (0x69)
+'j',0x21; j (0x6a)
+'k',0x2a; k (0x6b)
+'l',0x4d; l (0x6c)
+'n',0x4b; n (0x6e)
+'o',0x1b; o (0x6f)
+'p',0x2d; p (0x70)
+'q',0x22; q (0x71)
+'r',0x44; r (0x72)
+'s',0x4c; s (0x73)
+'t',0x42; t (0x74)
+'u',0x2b; u (0x75)
+'v',0x49; v (0x76)
+'w',0x41; w (0x77)
+'x',0x32; x (0x78)
+'y',0x2c; y (0x79)
+'z',0x4a; z (0x7a)
+'{',0x4e; { (0x7b)
+'}',0x55; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/pt b/usr/src/data/bhyve/kbdlayout/pt
new file mode 100644
index 0000000000..9ca6dc125a
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/pt
@@ -0,0 +1,31 @@
+# bhyve ps2kbd keyboard layout file
+# (pt : Portuguese)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x54; * (0x2a)
+'+',0x54; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'[',0x3e; [ (0x5b)
+'\',0x0e; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x5d; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x5b; ` (0x60)
+'{',0x3d; { (0x7b)
+'|',0x0e; | (0x7c)
+'}',0x45; } (0x7d)
+'~',0x5d; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/pt_acc b/usr/src/data/bhyve/kbdlayout/pt_acc
new file mode 100644
index 0000000000..85ca7485af
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/pt_acc
@@ -0,0 +1,28 @@
+# bhyve ps2kbd keyboard layout file
+# (pt_acc : Portuguese (accent keys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x54; * (0x2a)
+'+',0x54; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'[',0x3e; [ (0x5b)
+'\',0x0e; \ (0x5c)
+']',0x46; ] (0x5d)
+'_',0x4a; _ (0x5f)
+'{',0x3d; { (0x7b)
+'|',0x0e; | (0x7c)
+'}',0x45; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/ru b/usr/src/data/bhyve/kbdlayout/ru
new file mode 100644
index 0000000000..32bcf88dcf
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/ru
@@ -0,0 +1,14 @@
+# bhyve ps2kbd keyboard layout file
+# (ru : Russian)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x82; ! (0x21)
+'"',0x00; " (0x22)
+'(',0x8a; ( (0x28)
+')',0x8b; ) (0x29)
+'*',0x85; * (0x2a)
+':',0x86; : (0x3a)
+
diff --git a/usr/src/data/bhyve/kbdlayout/ru_shift b/usr/src/data/bhyve/kbdlayout/ru_shift
new file mode 100644
index 0000000000..1edc9310d2
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/ru_shift
@@ -0,0 +1,9 @@
+# bhyve ps2kbd keyboard layout file
+# (ru_shift : Russian (shift))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'*',0xb7; * (0x2a)
+
diff --git a/usr/src/data/bhyve/kbdlayout/ru_win b/usr/src/data/bhyve/kbdlayout/ru_win
new file mode 100644
index 0000000000..04b2775bf7
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/ru_win
@@ -0,0 +1,9 @@
+# bhyve ps2kbd keyboard layout file
+# (ru_win : Russian (winkeys))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'*',0xb7; * (0x2a)
+
diff --git a/usr/src/data/bhyve/kbdlayout/se b/usr/src/data/bhyve/kbdlayout/se
new file mode 100644
index 0000000000..afd0aca06c
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/se
@@ -0,0 +1,32 @@
+# bhyve ps2kbd keyboard layout file
+# (se : Swedish)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x5d; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x5d; * (0x2a)
+'+',0x4e; + (0x2b)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'[',0x3e; [ (0x5b)
+'\',0x4e; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x5b; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x55; ` (0x60)
+'{',0x3d; { (0x7b)
+'|',0x4c; | (0x7c)
+'}',0x45; } (0x7d)
+'~',0x5b; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/si b/usr/src/data/bhyve/kbdlayout/si
new file mode 100644
index 0000000000..4c3f119e03
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/si
@@ -0,0 +1,36 @@
+# bhyve ps2kbd keyboard layout file
+# (si : Slovenian)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x4e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x55; * (0x2a)
+'-',0x4a; - (0x2d)
+':',0x49; : (0x3a)
+';',0x41; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'@',0x2a; @ (0x40)
+'Y',0x1a; Y (0x59)
+'Z',0x35; Z (0x5a)
+'[',0x2b; [ (0x5b)
+'\',0x15; \ (0x5c)
+']',0x34; ] (0x5d)
+'^',0x26; ^ (0x5e)
+'_',0x4a; _ (0x5f)
+'`',0x3d; ` (0x60)
+'y',0x1a; y (0x79)
+'z',0x35; z (0x7a)
+'{',0x32; { (0x7b)
+'|',0x1d; | (0x7c)
+'}',0x31; } (0x7d)
+'~',0x16; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/tr b/usr/src/data/bhyve/kbdlayout/tr
new file mode 100644
index 0000000000..5c80df6b50
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/tr
@@ -0,0 +1,36 @@
+# bhyve ps2kbd keyboard layout file
+# (tr : Turkish (Q))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x0e; " (0x22)
+'&',0x36; & (0x26)
+''',0x1e; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x4e; * (0x2a)
+'+',0x25; + (0x2b)
+',',0x5d; , (0x2c)
+'-',0x55; - (0x2d)
+'.',0x4a; . (0x2e)
+':',0x4a; : (0x3a)
+';',0x5d; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'@',0x15; @ (0x40)
+'[',0x3e; [ (0x5b)
+'\',0x4e; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x26; ^ (0x5e)
+'_',0x55; _ (0x5f)
+'`',0x5d; ` (0x60)
+'i',0x52; i (0x69)
+'{',0x3d; { (0x7b)
+'|',0x61; | (0x7c)
+'}',0x45; } (0x7d)
+'~',0x5b; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/tr_f b/usr/src/data/bhyve/kbdlayout/tr_f
new file mode 100644
index 0000000000..9f4fe1512b
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/tr_f
@@ -0,0 +1,81 @@
+# bhyve ps2kbd keyboard layout file
+# (tr_f : Turkish (F))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'&',0x36; & (0x26)
+''',0x3d; ' (0x27)
+'(',0x3e; ( (0x28)
+')',0x46; ) (0x29)
+'*',0x0e; * (0x2a)
+'+',0x0e; + (0x2b)
+',',0x4a; , (0x2c)
+'-',0x55; - (0x2d)
+'/',0x4e; / (0x2f)
+':',0x49; : (0x3a)
+';',0x4a; ; (0x3b)
+'<',0x61; < (0x3c)
+'=',0x45; = (0x3d)
+'>',0x61; > (0x3e)
+'?',0x4e; ? (0x3f)
+'@',0x15; @ (0x40)
+'A',0x2b; A (0x41)
+'B',0x41; B (0x42)
+'C',0x2a; C (0x43)
+'D',0x35; D (0x44)
+'E',0x23; E (0x45)
+'F',0x15; F (0x46)
+'G',0x1d; G (0x47)
+'H',0x44; H (0x48)
+'I',0x2d; I (0x49)
+'J',0x1a; J (0x4a)
+'K',0x3b; K (0x4b)
+'M',0x42; M (0x4d)
+'N',0x43; N (0x4e)
+'O',0x2c; O (0x4f)
+'Q',0x54; Q (0x51)
+'R',0x3c; R (0x52)
+'S',0x3a; S (0x53)
+'T',0x33; T (0x54)
+'U',0x1c; U (0x55)
+'V',0x21; V (0x56)
+'W',0x5b; W (0x57)
+'X',0x5d; X (0x58)
+'Y',0x4c; Y (0x59)
+'Z',0x31; Z (0x5a)
+'[',0x3e; [ (0x5b)
+'\',0x4e; \ (0x5c)
+']',0x46; ] (0x5d)
+'^',0x26; ^ (0x5e)
+'_',0x55; _ (0x5f)
+'a',0x2b; a (0x61)
+'b',0x41; b (0x62)
+'c',0x2a; c (0x63)
+'d',0x35; d (0x64)
+'e',0x23; e (0x65)
+'f',0x15; f (0x66)
+'g',0x1d; g (0x67)
+'h',0x44; h (0x68)
+'i',0x1b; i (0x69)
+'j',0x1a; j (0x6a)
+'k',0x3b; k (0x6b)
+'m',0x42; m (0x6d)
+'n',0x43; n (0x6e)
+'o',0x2c; o (0x6f)
+'q',0x54; q (0x71)
+'r',0x3c; r (0x72)
+'s',0x3a; s (0x73)
+'t',0x33; t (0x74)
+'u',0x1c; u (0x75)
+'v',0x21; v (0x76)
+'w',0x5b; w (0x77)
+'x',0x5d; x (0x78)
+'y',0x4c; y (0x79)
+'z',0x31; z (0x7a)
+'{',0x3d; { (0x7b)
+'|',0x55; | (0x7c)
+'}',0x45; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/ua b/usr/src/data/bhyve/kbdlayout/ua
new file mode 100644
index 0000000000..683b39c505
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/ua
@@ -0,0 +1,9 @@
+# bhyve ps2kbd keyboard layout file
+# (ua : Ukrainian)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'*',0xb7; * (0x2a)
+
diff --git a/usr/src/data/bhyve/kbdlayout/ua_shift_alt b/usr/src/data/bhyve/kbdlayout/ua_shift_alt
new file mode 100644
index 0000000000..be5d704107
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/ua_shift_alt
@@ -0,0 +1,10 @@
+# bhyve ps2kbd keyboard layout file
+# (ua_shift_alt : Ukrainian (with Russian) (shift))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'*',0xb7; * (0x2a)
+0xffb5,0x71; Keypad 5
+
diff --git a/usr/src/data/bhyve/kbdlayout/uk b/usr/src/data/bhyve/kbdlayout/uk
new file mode 100644
index 0000000000..25289fa6d2
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/uk
@@ -0,0 +1,14 @@
+# bhyve ps2kbd keyboard layout file
+# (uk : United Kingdom)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'#',0x5d; # (0x23)
+'@',0x52; @ (0x40)
+'\',0x61; \ (0x5c)
+'|',0x61; | (0x7c)
+'~',0x5d; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/uk_capsctrl b/usr/src/data/bhyve/kbdlayout/uk_capsctrl
new file mode 100644
index 0000000000..8b869bf883
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/uk_capsctrl
@@ -0,0 +1,14 @@
+# bhyve ps2kbd keyboard layout file
+# (uk_capsctrl : United Kingdom (Caps Lock acts as Left Ctrl))
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'#',0x5d; # (0x23)
+'@',0x52; @ (0x40)
+'\',0x61; \ (0x5c)
+'|',0x61; | (0x7c)
+'~',0x5d; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/uk_dvorak b/usr/src/data/bhyve/kbdlayout/uk_dvorak
new file mode 100644
index 0000000000..0b365b7ead
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/uk_dvorak
@@ -0,0 +1,78 @@
+# bhyve ps2kbd keyboard layout file
+# (uk_dvorak : United Kingdom Dvorak)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x1e; " (0x22)
+'#',0x5d; # (0x23)
+''',0x15; ' (0x27)
+'+',0x5b; + (0x2b)
+',',0x1d; , (0x2c)
+'-',0x52; - (0x2d)
+'.',0x24; . (0x2e)
+'/',0x54; / (0x2f)
+':',0x1a; : (0x3a)
+';',0x1a; ; (0x3b)
+'<',0x1d; < (0x3c)
+'=',0x5b; = (0x3d)
+'>',0x24; > (0x3e)
+'?',0x54; ? (0x3f)
+'@',0x15; @ (0x40)
+'B',0x31; B (0x42)
+'C',0x43; C (0x43)
+'D',0x33; D (0x44)
+'E',0x23; E (0x45)
+'F',0x35; F (0x46)
+'G',0x3c; G (0x47)
+'H',0x3b; H (0x48)
+'I',0x34; I (0x49)
+'J',0x21; J (0x4a)
+'K',0x2a; K (0x4b)
+'L',0x4d; L (0x4c)
+'N',0x4b; N (0x4e)
+'O',0x1b; O (0x4f)
+'P',0x2d; P (0x50)
+'Q',0x22; Q (0x51)
+'R',0x44; R (0x52)
+'S',0x4c; S (0x53)
+'T',0x42; T (0x54)
+'U',0x2b; U (0x55)
+'V',0x49; V (0x56)
+'W',0x41; W (0x57)
+'X',0x32; X (0x58)
+'Y',0x2c; Y (0x59)
+'Z',0x4a; Z (0x5a)
+'[',0x4e; [ (0x5b)
+'\',0x61; \ (0x5c)
+']',0x55; ] (0x5d)
+'_',0x52; _ (0x5f)
+'b',0x31; b (0x62)
+'c',0x43; c (0x63)
+'d',0x33; d (0x64)
+'e',0x23; e (0x65)
+'f',0x35; f (0x66)
+'g',0x3c; g (0x67)
+'h',0x3b; h (0x68)
+'i',0x34; i (0x69)
+'j',0x21; j (0x6a)
+'k',0x2a; k (0x6b)
+'l',0x4d; l (0x6c)
+'n',0x4b; n (0x6e)
+'o',0x1b; o (0x6f)
+'p',0x2d; p (0x70)
+'q',0x22; q (0x71)
+'r',0x44; r (0x72)
+'s',0x4c; s (0x73)
+'t',0x42; t (0x74)
+'u',0x2b; u (0x75)
+'v',0x49; v (0x76)
+'w',0x41; w (0x77)
+'x',0x32; x (0x78)
+'y',0x2c; y (0x79)
+'z',0x4a; z (0x7a)
+'{',0x4e; { (0x7b)
+'|',0x61; | (0x7c)
+'}',0x55; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/uk_macbook b/usr/src/data/bhyve/kbdlayout/uk_macbook
new file mode 100644
index 0000000000..6283842afa
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/uk_macbook
@@ -0,0 +1,10 @@
+# bhyve ps2kbd keyboard layout file
+# (uk_macbook : United Kingdom Macbook)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'`',0x61; ` (0x60)
+'~',0x61; ~ (0x7e)
+
diff --git a/usr/src/data/bhyve/kbdlayout/us_dvorak b/usr/src/data/bhyve/kbdlayout/us_dvorak
new file mode 100644
index 0000000000..6fa21a2bca
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/us_dvorak
@@ -0,0 +1,74 @@
+# bhyve ps2kbd keyboard layout file
+# (us_dvorak : United States of America dvorak)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x15; " (0x22)
+''',0x15; ' (0x27)
+'+',0x5b; + (0x2b)
+',',0x1d; , (0x2c)
+'-',0x52; - (0x2d)
+'.',0x24; . (0x2e)
+'/',0x54; / (0x2f)
+':',0x1a; : (0x3a)
+';',0x1a; ; (0x3b)
+'<',0x1d; < (0x3c)
+'=',0x5b; = (0x3d)
+'>',0x24; > (0x3e)
+'?',0x54; ? (0x3f)
+'B',0x31; B (0x42)
+'C',0x43; C (0x43)
+'D',0x33; D (0x44)
+'E',0x23; E (0x45)
+'F',0x35; F (0x46)
+'G',0x3c; G (0x47)
+'H',0x3b; H (0x48)
+'I',0x34; I (0x49)
+'J',0x21; J (0x4a)
+'K',0x2a; K (0x4b)
+'L',0x4d; L (0x4c)
+'N',0x4b; N (0x4e)
+'O',0x1b; O (0x4f)
+'P',0x2d; P (0x50)
+'Q',0x22; Q (0x51)
+'R',0x44; R (0x52)
+'S',0x4c; S (0x53)
+'T',0x42; T (0x54)
+'U',0x2b; U (0x55)
+'V',0x49; V (0x56)
+'W',0x41; W (0x57)
+'X',0x32; X (0x58)
+'Y',0x2c; Y (0x59)
+'Z',0x4a; Z (0x5a)
+'[',0x4e; [ (0x5b)
+']',0x55; ] (0x5d)
+'_',0x52; _ (0x5f)
+'b',0x31; b (0x62)
+'c',0x43; c (0x63)
+'d',0x33; d (0x64)
+'e',0x23; e (0x65)
+'f',0x35; f (0x66)
+'g',0x3c; g (0x67)
+'h',0x3b; h (0x68)
+'i',0x34; i (0x69)
+'j',0x21; j (0x6a)
+'k',0x2a; k (0x6b)
+'l',0x4d; l (0x6c)
+'n',0x4b; n (0x6e)
+'o',0x1b; o (0x6f)
+'p',0x2d; p (0x70)
+'q',0x22; q (0x71)
+'r',0x44; r (0x72)
+'s',0x4c; s (0x73)
+'t',0x42; t (0x74)
+'u',0x2b; u (0x75)
+'v',0x49; v (0x76)
+'w',0x41; w (0x77)
+'x',0x32; x (0x78)
+'y',0x2c; y (0x79)
+'z',0x4a; z (0x7a)
+'{',0x4e; { (0x7b)
+'}',0x55; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/us_dvorakl b/usr/src/data/bhyve/kbdlayout/us_dvorakl
new file mode 100644
index 0000000000..38e6857f69
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/us_dvorakl
@@ -0,0 +1,88 @@
+# bhyve ps2kbd keyboard layout file
+# (us_dvorakl : United States of America lefthand dvorak)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x55; ! (0x21)
+'"',0x1a; " (0x22)
+'#',0x45; # (0x23)
+'$',0x46; $ (0x24)
+'%',0x54; % (0x25)
+'&',0x52; & (0x26)
+''',0x1a; ' (0x27)
+'(',0x4a; ( (0x28)
+')',0x49; ) (0x29)
+'*',0x4c; * (0x2a)
+'+',0x5b; + (0x2b)
+'-',0x1c; - (0x2d)
+'.',0x44; . (0x2e)
+'/',0x26; / (0x2f)
+'0',0x49; 0 (0x30)
+'1',0x55; 1 (0x31)
+'2',0x4e; 2 (0x32)
+'3',0x45; 3 (0x33)
+'4',0x46; 4 (0x34)
+'5',0x54; 5 (0x35)
+'6',0x4d; 6 (0x36)
+'7',0x52; 7 (0x37)
+'8',0x4c; 8 (0x38)
+'9',0x4a; 9 (0x39)
+':',0x15; : (0x3a)
+';',0x15; ; (0x3b)
+'=',0x5b; = (0x3d)
+'>',0x44; > (0x3e)
+'?',0x26; ? (0x3f)
+'@',0x4e; @ (0x40)
+'A',0x42; A (0x41)
+'B',0x24; B (0x42)
+'C',0x23; C (0x43)
+'D',0x2b; D (0x44)
+'E',0x3b; E (0x45)
+'F',0x2e; F (0x46)
+'G',0x21; G (0x47)
+'I',0x3a; I (0x49)
+'J',0x3e; J (0x4a)
+'K',0x1b; K (0x4b)
+'L',0x3d; L (0x4c)
+'M',0x36; M (0x4d)
+'O',0x43; O (0x4f)
+'P',0x25; P (0x50)
+'Q',0x1d; Q (0x51)
+'R',0x3c; R (0x52)
+'S',0x35; S (0x53)
+'T',0x34; T (0x54)
+'U',0x2c; U (0x55)
+'W',0x32; W (0x57)
+'Y',0x2d; Y (0x59)
+'Z',0x4b; Z (0x5a)
+'[',0x16; [ (0x5b)
+']',0x1e; ] (0x5d)
+'^',0x4d; ^ (0x5e)
+'_',0x1c; _ (0x5f)
+'a',0x42; a (0x61)
+'b',0x24; b (0x62)
+'c',0x23; c (0x63)
+'d',0x2b; d (0x64)
+'e',0x3b; e (0x65)
+'f',0x2e; f (0x66)
+'g',0x21; g (0x67)
+'i',0x3a; i (0x69)
+'j',0x3e; j (0x6a)
+'k',0x1b; k (0x6b)
+'l',0x3d; l (0x6c)
+'m',0x36; m (0x6d)
+'o',0x43; o (0x6f)
+'p',0x25; p (0x70)
+'q',0x1d; q (0x71)
+'r',0x3c; r (0x72)
+'s',0x35; s (0x73)
+'t',0x34; t (0x74)
+'u',0x2c; u (0x75)
+'w',0x32; w (0x77)
+'y',0x2d; y (0x79)
+'z',0x4b; z (0x7a)
+'{',0x16; { (0x7b)
+'}',0x1e; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/us_dvorakp b/usr/src/data/bhyve/kbdlayout/us_dvorakp
new file mode 100644
index 0000000000..c66c9d5e4b
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/us_dvorakp
@@ -0,0 +1,95 @@
+# bhyve ps2kbd keyboard layout file
+# (us_dvorakp : United States of America Programmer Dvorak)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'!',0x4e; ! (0x21)
+'"',0x1a; " (0x22)
+'#',0x55; # (0x23)
+'$',0x0e; $ (0x24)
+'%',0x16; % (0x25)
+'&',0x16; & (0x26)
+''',0x1a; ' (0x27)
+'(',0x2e; ( (0x28)
+')',0x3e; ) (0x29)
+'*',0x3d; * (0x2a)
+'+',0x46; + (0x2b)
+',',0x1d; , (0x2c)
+'-',0x52; - (0x2d)
+'.',0x24; . (0x2e)
+'/',0x54; / (0x2f)
+'0',0x3d; 0 (0x30)
+'1',0x2e; 1 (0x31)
+'2',0x3e; 2 (0x32)
+'3',0x25; 3 (0x33)
+'4',0x46; 4 (0x34)
+'5',0x26; 5 (0x35)
+'6',0x45; 6 (0x36)
+'7',0x1e; 7 (0x37)
+'8',0x4e; 8 (0x38)
+'9',0x36; 9 (0x39)
+':',0x15; : (0x3a)
+';',0x15; ; (0x3b)
+'<',0x1d; < (0x3c)
+'=',0x36; = (0x3d)
+'>',0x24; > (0x3e)
+'?',0x54; ? (0x3f)
+'@',0x5b; @ (0x40)
+'B',0x31; B (0x42)
+'C',0x43; C (0x43)
+'D',0x33; D (0x44)
+'E',0x23; E (0x45)
+'F',0x35; F (0x46)
+'G',0x3c; G (0x47)
+'H',0x3b; H (0x48)
+'I',0x34; I (0x49)
+'J',0x21; J (0x4a)
+'K',0x2a; K (0x4b)
+'L',0x4d; L (0x4c)
+'N',0x4b; N (0x4e)
+'O',0x1b; O (0x4f)
+'P',0x2d; P (0x50)
+'Q',0x22; Q (0x51)
+'R',0x44; R (0x52)
+'S',0x4c; S (0x53)
+'T',0x42; T (0x54)
+'U',0x2b; U (0x55)
+'V',0x49; V (0x56)
+'W',0x41; W (0x57)
+'X',0x32; X (0x58)
+'Y',0x2c; Y (0x59)
+'Z',0x4a; Z (0x5a)
+'[',0x1e; [ (0x5b)
+']',0x45; ] (0x5d)
+'^',0x5b; ^ (0x5e)
+'_',0x52; _ (0x5f)
+'`',0x55; ` (0x60)
+'b',0x31; b (0x62)
+'c',0x43; c (0x63)
+'d',0x33; d (0x64)
+'e',0x23; e (0x65)
+'f',0x35; f (0x66)
+'g',0x3c; g (0x67)
+'h',0x3b; h (0x68)
+'i',0x34; i (0x69)
+'j',0x21; j (0x6a)
+'k',0x2a; k (0x6b)
+'l',0x4d; l (0x6c)
+'n',0x4b; n (0x6e)
+'o',0x1b; o (0x6f)
+'p',0x2d; p (0x70)
+'q',0x22; q (0x71)
+'r',0x44; r (0x72)
+'s',0x4c; s (0x73)
+'t',0x42; t (0x74)
+'u',0x2b; u (0x75)
+'v',0x49; v (0x76)
+'w',0x41; w (0x77)
+'x',0x32; x (0x78)
+'y',0x2c; y (0x79)
+'z',0x4a; z (0x7a)
+'{',0x26; { (0x7b)
+'}',0x25; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/us_dvorakr b/usr/src/data/bhyve/kbdlayout/us_dvorakr
new file mode 100644
index 0000000000..95485730c4
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/us_dvorakr
@@ -0,0 +1,86 @@
+# bhyve ps2kbd keyboard layout file
+# (us_dvorakr : United States of America righthand dvorak)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x4a; " (0x22)
+'%',0x15; % (0x25)
+'&',0x1c; & (0x26)
+''',0x4a; ' (0x27)
+'(',0x1a; ( (0x28)
+')',0x22; ) (0x29)
+'*',0x1b; * (0x2a)
+'+',0x5b; + (0x2b)
+',',0x2a; , (0x2c)
+'-',0x52; - (0x2d)
+'.',0x2d; . (0x2e)
+'/',0x45; / (0x2f)
+'0',0x22; 0 (0x30)
+'5',0x15; 5 (0x35)
+'6',0x1d; 6 (0x36)
+'7',0x1c; 7 (0x37)
+'8',0x1b; 8 (0x38)
+'9',0x1a; 9 (0x39)
+':',0x54; : (0x3a)
+';',0x54; ; (0x3b)
+'<',0x2a; < (0x3c)
+'=',0x5b; = (0x3d)
+'>',0x2d; > (0x3e)
+'?',0x45; ? (0x3f)
+'A',0x2b; A (0x41)
+'B',0x4d; B (0x42)
+'C',0x4b; C (0x43)
+'D',0x42; D (0x44)
+'E',0x34; E (0x45)
+'F',0x3e; F (0x46)
+'G',0x49; G (0x47)
+'I',0x32; I (0x49)
+'J',0x2e; J (0x4a)
+'K',0x4c; K (0x4b)
+'L',0x36; L (0x4c)
+'M',0x3d; M (0x4d)
+'O',0x2c; O (0x4f)
+'P',0x46; P (0x50)
+'Q',0x24; Q (0x51)
+'R',0x35; R (0x52)
+'S',0x3c; S (0x53)
+'T',0x3b; T (0x54)
+'U',0x43; U (0x55)
+'V',0x41; V (0x56)
+'W',0x3a; W (0x57)
+'X',0x21; X (0x58)
+'Y',0x44; Y (0x59)
+'Z',0x23; Z (0x5a)
+'[',0x4e; [ (0x5b)
+']',0x55; ] (0x5d)
+'^',0x1d; ^ (0x5e)
+'_',0x52; _ (0x5f)
+'a',0x2b; a (0x61)
+'b',0x4d; b (0x62)
+'c',0x4b; c (0x63)
+'d',0x42; d (0x64)
+'e',0x34; e (0x65)
+'f',0x3e; f (0x66)
+'g',0x49; g (0x67)
+'i',0x32; i (0x69)
+'j',0x2e; j (0x6a)
+'k',0x4c; k (0x6b)
+'l',0x36; l (0x6c)
+'m',0x3d; m (0x6d)
+'o',0x2c; o (0x6f)
+'p',0x46; p (0x70)
+'q',0x24; q (0x71)
+'r',0x35; r (0x72)
+'s',0x3c; s (0x73)
+'t',0x3b; t (0x74)
+'u',0x43; u (0x75)
+'v',0x41; v (0x76)
+'w',0x3a; w (0x77)
+'x',0x21; x (0x78)
+'y',0x44; y (0x79)
+'z',0x23; z (0x7a)
+'{',0x4e; { (0x7b)
+'}',0x55; } (0x7d)
+
diff --git a/usr/src/data/bhyve/kbdlayout/us_dvorakx b/usr/src/data/bhyve/kbdlayout/us_dvorakx
new file mode 100644
index 0000000000..2419587500
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/us_dvorakx
@@ -0,0 +1,80 @@
+# bhyve ps2kbd keyboard layout file
+# (us_dvorakx : United States of America dvorakx)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'"',0x15; " (0x22)
+''',0x15; ' (0x27)
+'+',0x5d; + (0x2b)
+',',0x1d; , (0x2c)
+'-',0x52; - (0x2d)
+'.',0x24; . (0x2e)
+'/',0x54; / (0x2f)
+':',0x1a; : (0x3a)
+';',0x1a; ; (0x3b)
+'<',0x1d; < (0x3c)
+'=',0x5d; = (0x3d)
+'>',0x24; > (0x3e)
+'?',0x54; ? (0x3f)
+'B',0x31; B (0x42)
+'C',0x43; C (0x43)
+'D',0x33; D (0x44)
+'E',0x23; E (0x45)
+'F',0x35; F (0x46)
+'G',0x3c; G (0x47)
+'H',0x3b; H (0x48)
+'I',0x34; I (0x49)
+'J',0x21; J (0x4a)
+'K',0x2a; K (0x4b)
+'L',0x4d; L (0x4c)
+'N',0x4b; N (0x4e)
+'O',0x1b; O (0x4f)
+'P',0x2d; P (0x50)
+'Q',0x22; Q (0x51)
+'R',0x44; R (0x52)
+'S',0x4c; S (0x53)
+'T',0x42; T (0x54)
+'U',0x2b; U (0x55)
+'V',0x49; V (0x56)
+'W',0x41; W (0x57)
+'X',0x32; X (0x58)
+'Y',0x2c; Y (0x59)
+'Z',0x4a; Z (0x5a)
+'[',0x4e; [ (0x5b)
+'\',0x5b; \ (0x5c)
+']',0x55; ] (0x5d)
+'_',0x52; _ (0x5f)
+'`',0x76; ` (0x60)
+'b',0x31; b (0x62)
+'c',0x43; c (0x63)
+'d',0x33; d (0x64)
+'e',0x23; e (0x65)
+'f',0x35; f (0x66)
+'g',0x3c; g (0x67)
+'h',0x3b; h (0x68)
+'i',0x34; i (0x69)
+'j',0x21; j (0x6a)
+'k',0x2a; k (0x6b)
+'l',0x4d; l (0x6c)
+'n',0x4b; n (0x6e)
+'o',0x1b; o (0x6f)
+'p',0x2d; p (0x70)
+'q',0x22; q (0x71)
+'r',0x44; r (0x72)
+'s',0x4c; s (0x73)
+'t',0x42; t (0x74)
+'u',0x2b; u (0x75)
+'v',0x49; v (0x76)
+'w',0x41; w (0x77)
+'x',0x32; x (0x78)
+'y',0x2c; y (0x79)
+'z',0x4a; z (0x7a)
+'{',0x4e; { (0x7b)
+'|',0x5b; | (0x7c)
+'}',0x55; } (0x7d)
+'~',0x76; ~ (0x7e)
+0xff1b,0x0e; Escape
+0xffe3,0x58; Left control
+
diff --git a/usr/src/data/bhyve/kbdlayout/us_emacs b/usr/src/data/bhyve/kbdlayout/us_emacs
new file mode 100644
index 0000000000..01b108583f
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/us_emacs
@@ -0,0 +1,9 @@
+# bhyve ps2kbd keyboard layout file
+# (us_emacs : United States of America Emacs optimized layout)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+0xffff,0x66; Del
+
diff --git a/usr/src/data/bhyve/kbdlayout/us_unix b/usr/src/data/bhyve/kbdlayout/us_unix
new file mode 100644
index 0000000000..c4b2739ad1
--- /dev/null
+++ b/usr/src/data/bhyve/kbdlayout/us_unix
@@ -0,0 +1,14 @@
+# bhyve ps2kbd keyboard layout file
+# (us_unix : United States of America Traditional Unix Workstation)
+#
+# Created by: Koine Yuusuke(koinec) <koinec@users.osdn.me>
+#
+# $FreeBSD$
+
+'`',0x76; ` (0x60)
+'~',0x76; ~ (0x7e)
+0xff08,0x71; Back space
+0xff1b,0x0e; Escape
+0xffe3,0x58; Left control
+0xffff,0x66; Del
+
diff --git a/usr/src/lib/libvmmapi/common/vmmapi.c b/usr/src/lib/libvmmapi/common/vmmapi.c
index 9a53a9d653..540cbf0bc5 100644
--- a/usr/src/lib/libvmmapi/common/vmmapi.c
+++ b/usr/src/lib/libvmmapi/common/vmmapi.c
@@ -84,6 +84,8 @@ __FBSDID("$FreeBSD$");
/* Rely on PROT_NONE for guard purposes */
#define MAP_GUARD (MAP_PRIVATE | MAP_ANON | MAP_NORESERVE)
+
+#define _Thread_local __thread
#endif
/*
@@ -1340,21 +1342,48 @@ uint64_t *
vm_get_stats(struct vmctx *ctx, int vcpu, struct timeval *ret_tv,
int *ret_entries)
{
- int error;
-
- static struct vm_stats vmstats;
+ static _Thread_local uint64_t *stats_buf;
+ static _Thread_local uint32_t stats_count;
+ uint64_t *new_stats;
+ struct vm_stats vmstats;
+ uint32_t count, index;
+ bool have_stats;
+ have_stats = false;
vmstats.cpuid = vcpu;
+ count = 0;
+ for (index = 0;; index += nitems(vmstats.statbuf)) {
+ vmstats.index = index;
+ if (ioctl(ctx->fd, VM_STATS_IOC, &vmstats) != 0)
+ break;
+ if (stats_count < index + vmstats.num_entries) {
+ new_stats = reallocarray(stats_buf,
+ index + vmstats.num_entries, sizeof(uint64_t));
+ if (new_stats == NULL) {
+ errno = ENOMEM;
+ return (NULL);
+ }
+ stats_count = index + vmstats.num_entries;
+ stats_buf = new_stats;
+ }
+ memcpy(stats_buf + index, vmstats.statbuf,
+ vmstats.num_entries * sizeof(uint64_t));
+ count += vmstats.num_entries;
+ have_stats = true;
- error = ioctl(ctx->fd, VM_STATS_IOC, &vmstats);
- if (error == 0) {
+ if (vmstats.num_entries != nitems(vmstats.statbuf))
+ break;
+ }
+
+ if (have_stats) {
if (ret_entries)
- *ret_entries = vmstats.num_entries;
+ *ret_entries = count;
if (ret_tv)
*ret_tv = vmstats.tv;
- return (vmstats.statbuf);
- } else
- return (NULL);
+ return (stats_buf);
+ }
+
+ return (NULL);
}
const char *
diff --git a/usr/src/lib/libvmmapi/common/vmmapi.h b/usr/src/lib/libvmmapi/common/vmmapi.h
index 6949ea4e5a..9d5470f729 100644
--- a/usr/src/lib/libvmmapi/common/vmmapi.h
+++ b/usr/src/lib/libvmmapi/common/vmmapi.h
@@ -91,6 +91,7 @@ enum {
#endif
VM_BOOTROM,
VM_FRAMEBUFFER,
+ VM_PCIROM,
};
/*
diff --git a/usr/src/man/man5/bhyve_config.5 b/usr/src/man/man5/bhyve_config.5
index 17788deaf8..f031165f89 100644
--- a/usr/src/man/man5/bhyve_config.5
+++ b/usr/src/man/man5/bhyve_config.5
@@ -137,6 +137,11 @@ will listen for connections on this port.
.It Va gdb.wait Ta bool Ta false Ta
If the debug server is enabled, wait for a debugger to connect
before starting the guest.
+.It Va keyboard.layout Ta string Ta Ta
+Specify the keyboard layout name with the file name in
+.Pa /usr/share/bhyve/kbdlayout .
+This value only works when loaded with UEFI mode for VNC, and when a VNC client
+that doesn't support the QEMU Extended Key Event Message us used.
.It Va rtc.use_localtime Ta bool Ta true Ta
The real time clock uses the local time of the host.
If this is set to false, the real time clock uses UTC.
@@ -428,6 +433,11 @@ The contents of this file are copied into the guest's
memory ending just before the 4GB physical address.
If a boot ROM is present, a firmware interface device is
also enabled for use by the boot ROM.
+.It Va bootvars Ta path Ta Ta
+Path to boot variables file.
+The contents of this file are copied beneath the boot ROM.
+Firmware can write to it to save variables.
+Variables will be persistent across guest reboots.
.It Va com1 Ta node Ta Ta
Settings for the COM1 serial port device.
.It Va com2 Ta node Ta Ta
@@ -490,6 +500,8 @@ Path to a PCI passthrough device in the form
where
.Ar N
is the device number.
+.It Va rom Ta path Ta Ta
+ROM file of the device which will be executed by OVMF to initialise the device.
.El
.Ss VirtIO 9p Settings
Each VirtIO 9p device exposes a single filesystem from a host path.
diff --git a/usr/src/man/man8/bhyve.8 b/usr/src/man/man8/bhyve.8
index 9e4e3b68bb..a862668b8c 100644
--- a/usr/src/man/man8/bhyve.8
+++ b/usr/src/man/man8/bhyve.8
@@ -61,6 +61,7 @@
.Oc
.Sm on
.Op Fl k Ar config_file
+.Op Fl K Ar layout
.Oo Fl l
.Sm off
.Ar lpcdev Op Cm \&, Ar conf
@@ -205,6 +206,17 @@ are ignored.
See
.Xr bhyve_config 5
for more details.
+.It Fl K Ar layout
+Specify the keyboard layout.
+The value that can be specified sets the file name in
+.Pa /usr/share/bhyve/kbdlayout .
+This specification only works when loaded with UEFI mode for VNC.
+When using a VNC client that supports QEMU Extended Key Event Message
+.Pq e.g. TigerVNC ,
+this option isn't needed.
+When using a VNC client that doesn't support QEMU Extended Key Event Message
+.Pq e.g. tightVNC ,
+the layout defaults to the US keyboard unless specified otherwise.
.It Fl l Cm help
Print a list of supported LPC devices.
.It Fl l Ar lpcdev Ns Op \&, Ns Ar conf
@@ -492,6 +504,12 @@ to that file.
.Bl -tag -width 10n
.It Pa /dev/ppt Ns Ar N
Connect to a PCI device on the host identified by the specified path.
+.It Cm rom= Ns Ar romfile
+Add
+.Ar romfile
+as option ROM to the PCI device.
+The ROM will be loaded by firmware and should be capable of initialising the
+device.
.El
.Pp
Guest memory must be wired using the
diff --git a/usr/src/pkg/manifests/system-bhyve.p5m b/usr/src/pkg/manifests/system-bhyve.p5m
index 51f4877582..ae95d62061 100644
--- a/usr/src/pkg/manifests/system-bhyve.p5m
+++ b/usr/src/pkg/manifests/system-bhyve.p5m
@@ -15,7 +15,7 @@
#
# Copyright 2018 Joyent, Inc.
-# Copyright 2021 OmniOS Community Edition (OmniOSce) Association.
+# Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
#
#
@@ -46,6 +46,81 @@ file path=usr/sbin/bhyve mode=0555
file path=usr/sbin/bhyvectl mode=0555
file path=usr/sbin/pptadm mode=0555
dir path=usr/share
+dir path=usr/share/bhyve
+dir path=usr/share/bhyve/kbdlayout
+file path=usr/share/bhyve/kbdlayout/am mode=0444
+file path=usr/share/bhyve/kbdlayout/be mode=0444
+file path=usr/share/bhyve/kbdlayout/be_acc mode=0444
+file path=usr/share/bhyve/kbdlayout/bg_bds mode=0444
+file path=usr/share/bhyve/kbdlayout/bg_phonetic mode=0444
+file path=usr/share/bhyve/kbdlayout/br mode=0444
+file path=usr/share/bhyve/kbdlayout/br_noacc mode=0444
+file path=usr/share/bhyve/kbdlayout/centraleuropean mode=0444
+file path=usr/share/bhyve/kbdlayout/ch mode=0444
+file path=usr/share/bhyve/kbdlayout/ch-fr mode=0444
+file path=usr/share/bhyve/kbdlayout/ch-fr_acc mode=0444
+file path=usr/share/bhyve/kbdlayout/ch_acc mode=0444
+file path=usr/share/bhyve/kbdlayout/ch_macbook_acc mode=0444
+file path=usr/share/bhyve/kbdlayout/cz mode=0444
+file path=usr/share/bhyve/kbdlayout/de mode=0444
+file path=usr/share/bhyve/kbdlayout/de_acc mode=0444
+file path=usr/share/bhyve/kbdlayout/de_noacc mode=0444
+file path=usr/share/bhyve/kbdlayout/default mode=0444
+file path=usr/share/bhyve/kbdlayout/dk mode=0444
+file path=usr/share/bhyve/kbdlayout/dk_macbook mode=0444
+file path=usr/share/bhyve/kbdlayout/ee mode=0444
+file path=usr/share/bhyve/kbdlayout/es mode=0444
+file path=usr/share/bhyve/kbdlayout/es_acc mode=0444
+file path=usr/share/bhyve/kbdlayout/es_dvorak mode=0444
+file path=usr/share/bhyve/kbdlayout/fi mode=0444
+file path=usr/share/bhyve/kbdlayout/fr mode=0444
+file path=usr/share/bhyve/kbdlayout/fr_acc mode=0444
+file path=usr/share/bhyve/kbdlayout/fr_dvorak mode=0444
+file path=usr/share/bhyve/kbdlayout/fr_dvorak_acc mode=0444
+file path=usr/share/bhyve/kbdlayout/fr_macbook mode=0444
+file path=usr/share/bhyve/kbdlayout/gr mode=0444
+file path=usr/share/bhyve/kbdlayout/gr_101_acc mode=0444
+file path=usr/share/bhyve/kbdlayout/gr_elot_acc mode=0444
+file path=usr/share/bhyve/kbdlayout/hr mode=0444
+file path=usr/share/bhyve/kbdlayout/hu_101 mode=0444
+file path=usr/share/bhyve/kbdlayout/hu_102 mode=0444
+file path=usr/share/bhyve/kbdlayout/is mode=0444
+file path=usr/share/bhyve/kbdlayout/is_acc mode=0444
+file path=usr/share/bhyve/kbdlayout/it mode=0444
+file path=usr/share/bhyve/kbdlayout/jp mode=0444
+file path=usr/share/bhyve/kbdlayout/jp_capsctrl mode=0444
+file path=usr/share/bhyve/kbdlayout/kz_io mode=0444
+file path=usr/share/bhyve/kbdlayout/kz_kst mode=0444
+file path=usr/share/bhyve/kbdlayout/latinamerican mode=0444
+file path=usr/share/bhyve/kbdlayout/latinamerican_acc mode=0444
+file path=usr/share/bhyve/kbdlayout/lt mode=0444
+file path=usr/share/bhyve/kbdlayout/nl mode=0444
+file path=usr/share/bhyve/kbdlayout/no mode=0444
+file path=usr/share/bhyve/kbdlayout/no_dvorak mode=0444
+file path=usr/share/bhyve/kbdlayout/nordic_asus-eee mode=0444
+file path=usr/share/bhyve/kbdlayout/pl_dvorak mode=0444
+file path=usr/share/bhyve/kbdlayout/pt mode=0444
+file path=usr/share/bhyve/kbdlayout/pt_acc mode=0444
+file path=usr/share/bhyve/kbdlayout/ru mode=0444
+file path=usr/share/bhyve/kbdlayout/ru_shift mode=0444
+file path=usr/share/bhyve/kbdlayout/ru_win mode=0444
+file path=usr/share/bhyve/kbdlayout/se mode=0444
+file path=usr/share/bhyve/kbdlayout/si mode=0444
+file path=usr/share/bhyve/kbdlayout/tr mode=0444
+file path=usr/share/bhyve/kbdlayout/tr_f mode=0444
+file path=usr/share/bhyve/kbdlayout/ua mode=0444
+file path=usr/share/bhyve/kbdlayout/ua_shift_alt mode=0444
+file path=usr/share/bhyve/kbdlayout/uk mode=0444
+file path=usr/share/bhyve/kbdlayout/uk_capsctrl mode=0444
+file path=usr/share/bhyve/kbdlayout/uk_dvorak mode=0444
+file path=usr/share/bhyve/kbdlayout/uk_macbook mode=0444
+file path=usr/share/bhyve/kbdlayout/us_dvorak mode=0444
+file path=usr/share/bhyve/kbdlayout/us_dvorakl mode=0444
+file path=usr/share/bhyve/kbdlayout/us_dvorakp mode=0444
+file path=usr/share/bhyve/kbdlayout/us_dvorakr mode=0444
+file path=usr/share/bhyve/kbdlayout/us_dvorakx mode=0444
+file path=usr/share/bhyve/kbdlayout/us_emacs mode=0444
+file path=usr/share/bhyve/kbdlayout/us_unix mode=0444
dir path=usr/share/man
dir path=usr/share/man/man5
file path=usr/share/man/man5/bhyve_config.5
diff --git a/usr/src/uts/intel/io/vmm/vmm.c b/usr/src/uts/intel/io/vmm/vmm.c
index 6d70cd31a0..8699810c2c 100644
--- a/usr/src/uts/intel/io/vmm/vmm.c
+++ b/usr/src/uts/intel/io/vmm/vmm.c
@@ -103,6 +103,22 @@ typedef struct vm_thread_ctx {
enum vcpu_ustate vtc_ustate;
} vm_thread_ctx_t;
+#define VMM_MTRR_VAR_MAX 10
+#define VMM_MTRR_DEF_MASK \
+ (MTRR_DEF_ENABLE | MTRR_DEF_FIXED_ENABLE | MTRR_DEF_TYPE)
+#define VMM_MTRR_PHYSBASE_MASK (MTRR_PHYSBASE_PHYSBASE | MTRR_PHYSBASE_TYPE)
+#define VMM_MTRR_PHYSMASK_MASK (MTRR_PHYSMASK_PHYSMASK | MTRR_PHYSMASK_VALID)
+struct vm_mtrr {
+ uint64_t def_type;
+ uint64_t fixed4k[8];
+ uint64_t fixed16k[2];
+ uint64_t fixed64k;
+ struct {
+ uint64_t base;
+ uint64_t mask;
+ } var[VMM_MTRR_VAR_MAX];
+};
+
/*
* Initialization:
* (a) allocated when vcpu is created
@@ -139,6 +155,7 @@ struct vcpu {
struct vie *vie_ctx; /* (x) instruction emulation context */
vm_client_t *vmclient; /* (a) VM-system client */
uint64_t tsc_offset; /* (x) offset from host TSC */
+ struct vm_mtrr mtrr; /* (i) vcpu's MTRR */
enum vcpu_ustate ustate; /* (i) microstate for the vcpu */
hrtime_t ustate_when; /* (i) time of last ustate change */
@@ -156,7 +173,7 @@ struct mem_seg {
bool sysmem;
vm_object_t *object;
};
-#define VM_MAX_MEMSEGS 4
+#define VM_MAX_MEMSEGS 5
struct mem_map {
vm_paddr_t gpa;
@@ -362,6 +379,7 @@ vcpu_init(struct vm *vm, int vcpu_id, bool create)
if (vcpu->ustate != VU_INIT) {
vcpu_ustate_change(vm, vcpu_id, VU_INIT);
}
+ bzero(&vcpu->mtrr, sizeof (vcpu->mtrr));
}
vcpu->run_state = VRS_HALT;
@@ -1859,8 +1877,91 @@ vm_handle_run_state(struct vm *vm, int vcpuid)
}
static int
+vm_rdmtrr(struct vm_mtrr *mtrr, uint32_t num, uint64_t *val)
+{
+ switch (num) {
+ case MSR_MTRRcap:
+ *val = MTRR_CAP_WC | MTRR_CAP_FIXED | VMM_MTRR_VAR_MAX;
+ break;
+ case MSR_MTRRdefType:
+ *val = mtrr->def_type;
+ break;
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
+ *val = mtrr->fixed4k[num - MSR_MTRR4kBase];
+ break;
+ case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
+ *val = mtrr->fixed16k[num - MSR_MTRR16kBase];
+ break;
+ case MSR_MTRR64kBase:
+ *val = mtrr->fixed64k;
+ break;
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1: {
+ uint_t offset = num - MSR_MTRRVarBase;
+ if (offset % 2 == 0) {
+ *val = mtrr->var[offset / 2].base;
+ } else {
+ *val = mtrr->var[offset / 2].mask;
+ }
+ break;
+ }
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int
+vm_wrmtrr(struct vm_mtrr *mtrr, uint32_t num, uint64_t val)
+{
+ switch (num) {
+ case MSR_MTRRcap:
+ /* MTRRCAP is read only */
+ return (-1);
+ case MSR_MTRRdefType:
+ if (val & ~VMM_MTRR_DEF_MASK) {
+ /* generate #GP on writes to reserved fields */
+ return (-1);
+ }
+ mtrr->def_type = val;
+ break;
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
+ mtrr->fixed4k[num - MSR_MTRR4kBase] = val;
+ break;
+ case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
+ mtrr->fixed16k[num - MSR_MTRR16kBase] = val;
+ break;
+ case MSR_MTRR64kBase:
+ mtrr->fixed64k = val;
+ break;
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1: {
+ uint_t offset = num - MSR_MTRRVarBase;
+ if (offset % 2 == 0) {
+ if (val & ~VMM_MTRR_PHYSBASE_MASK) {
+ /* generate #GP on writes to reserved fields */
+ return (-1);
+ }
+ mtrr->var[offset / 2].base = val;
+ } else {
+ if (val & ~VMM_MTRR_PHYSMASK_MASK) {
+ /* generate #GP on writes to reserved fields */
+ return (-1);
+ }
+ mtrr->var[offset / 2].mask = val;
+ }
+ break;
+ }
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int
vm_handle_rdmsr(struct vm *vm, int vcpuid, struct vm_exit *vme)
{
+ struct vcpu *vcpu = &vm->vcpu[vcpuid];
const uint32_t code = vme->u.msr.code;
uint64_t val = 0;
@@ -1872,10 +1973,12 @@ vm_handle_rdmsr(struct vm *vm, int vcpuid, struct vm_exit *vme)
case MSR_MTRRcap:
case MSR_MTRRdefType:
- case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
case MSR_MTRR64kBase:
- val = 0;
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1:
+ if (vm_rdmtrr(&vcpu->mtrr, code, &val) != 0)
+ vm_inject_gp(vm, vcpuid);
break;
case MSR_TSC:
@@ -1919,13 +2022,13 @@ vm_handle_wrmsr(struct vm *vm, int vcpuid, struct vm_exit *vme)
break;
case MSR_MTRRcap:
- vm_inject_gp(vm, vcpuid);
- break;
case MSR_MTRRdefType:
- case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
case MSR_MTRR64kBase:
- /* Ignore writes */
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1:
+ if (vm_wrmtrr(&vcpu->mtrr, code, val) != 0)
+ vm_inject_gp(vm, vcpuid);
break;
case MSR_TSC:
@@ -2965,6 +3068,7 @@ vcpu_arch_reset(struct vm *vm, int vcpuid, bool init_only)
(void) hma_fpu_init(vcpu->guestfpu);
/* XXX: clear MSRs and other pieces */
+ bzero(&vcpu->mtrr, sizeof (vcpu->mtrr));
}
return (0);
diff --git a/usr/src/uts/intel/io/vmm/vmm_sol_dev.c b/usr/src/uts/intel/io/vmm/vmm_sol_dev.c
index 60a888e600..625c71c618 100644
--- a/usr/src/uts/intel/io/vmm/vmm_sol_dev.c
+++ b/usr/src/uts/intel/io/vmm/vmm_sol_dev.c
@@ -567,13 +567,13 @@ vmmdev_do_ioctl(vmm_softc_t *sc, int cmd, intptr_t arg, int md,
case VM_STATS_IOC: {
struct vm_stats vmstats;
- CTASSERT(MAX_VM_STATS >= MAX_VMM_STAT_ELEMS);
if (ddi_copyin(datap, &vmstats, sizeof (vmstats), md)) {
error = EFAULT;
break;
}
hrt2tv(gethrtime(), &vmstats.tv);
- error = vmm_stat_copy(sc->vmm_vm, vmstats.cpuid,
+ error = vmm_stat_copy(sc->vmm_vm, vmstats.cpuid, vmstats.index,
+ nitems(vmstats.statbuf),
&vmstats.num_entries, vmstats.statbuf);
if (error == 0 &&
ddi_copyout(&vmstats, datap, sizeof (vmstats), md)) {
diff --git a/usr/src/uts/intel/io/vmm/vmm_stat.c b/usr/src/uts/intel/io/vmm/vmm_stat.c
index b2b73f890d..1d8644f48d 100644
--- a/usr/src/uts/intel/io/vmm/vmm_stat.c
+++ b/usr/src/uts/intel/io/vmm/vmm_stat.c
@@ -82,15 +82,29 @@ vmm_stat_register(void *arg)
}
int
-vmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf)
+vmm_stat_copy(struct vm *vm, int vcpu, int index, int count, int *num_stats,
+ uint64_t *buf)
{
struct vmm_stat_type *vst;
uint64_t *stats;
- int i;
+ int i, tocopy;
if (vcpu < 0 || vcpu >= vm_get_maxcpus(vm))
return (EINVAL);
+ if (index < 0 || count < 0)
+ return (EINVAL);
+
+ if (index > vst_num_elems)
+ return (ENOENT);
+
+ if (index == vst_num_elems) {
+ *num_stats = 0;
+ return (0);
+ }
+
+ tocopy = min(vst_num_elems - index, count);
+
/* Let stats functions update their counters */
for (i = 0; i < vst_num_types; i++) {
vst = vsttab[i];
@@ -100,9 +114,8 @@ vmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf)
/* Copy over the stats */
stats = vcpu_stats(vm, vcpu);
- for (i = 0; i < vst_num_elems; i++)
- buf[i] = stats[i];
- *num_stats = vst_num_elems;
+ memcpy(buf, stats + index, tocopy * sizeof (stats[0]));
+ *num_stats = tocopy;
return (0);
}
diff --git a/usr/src/uts/intel/io/vmm/vmm_stat.h b/usr/src/uts/intel/io/vmm/vmm_stat.h
index 2975a4a914..48d2642b82 100644
--- a/usr/src/uts/intel/io/vmm/vmm_stat.h
+++ b/usr/src/uts/intel/io/vmm/vmm_stat.h
@@ -96,10 +96,8 @@ void *vmm_stat_alloc(void);
void vmm_stat_init(void *vp);
void vmm_stat_free(void *vp);
-/*
- * 'buf' should be at least fit 'MAX_VMM_STAT_TYPES' entries
- */
-int vmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf);
+int vmm_stat_copy(struct vm *vm, int vcpu, int index, int count,
+ int *num_stats, uint64_t *buf);
int vmm_stat_desc_copy(int index, char *buf, int buflen);
static __inline void
diff --git a/usr/src/uts/intel/sys/vmm.h b/usr/src/uts/intel/sys/vmm.h
index e58d63761e..edafabaf15 100644
--- a/usr/src/uts/intel/sys/vmm.h
+++ b/usr/src/uts/intel/sys/vmm.h
@@ -131,7 +131,9 @@ enum x2apic_state {
#define VM_MAX_NAMELEN 128
#define VM_MAX_SEG_NAMELEN 128
+#ifdef _KERNEL
#define VM_MAXCPU 32 /* maximum virtual cpus */
+#endif
/*
* Identifiers for optional vmm capabilities
diff --git a/usr/src/uts/intel/sys/vmm_dev.h b/usr/src/uts/intel/sys/vmm_dev.h
index 0e883f21bb..2e4c0c6e40 100644
--- a/usr/src/uts/intel/sys/vmm_dev.h
+++ b/usr/src/uts/intel/sys/vmm_dev.h
@@ -179,10 +179,11 @@ struct vm_nmi {
int cpuid;
};
-#define MAX_VM_STATS (64 + VM_MAXCPU)
+#define MAX_VM_STATS 64
struct vm_stats {
int cpuid; /* in */
+ int index; /* in */
int num_entries; /* out */
struct timeval tv;
uint64_t statbuf[MAX_VM_STATS];