diff options
author | Dan McDonald <danmcd@mnx.io> | 2022-06-15 13:44:36 -0400 |
---|---|---|
committer | Dan McDonald <danmcd@mnx.io> | 2022-06-15 13:44:36 -0400 |
commit | 60c144394d29f66e3db1d244e6d0078f79c22e4f (patch) | |
tree | 817dcb6f545b07a7eafa22fc523ce50e1a1409fa | |
parent | b66333d8fa2df710a3b017d364b027432453db40 (diff) | |
parent | 5c22bad5dcbd030d95aca36e1c2fb0f77b505e17 (diff) | |
download | illumos-joyent-60c144394d29f66e3db1d244e6d0078f79c22e4f.tar.gz |
[illumos-gate merge]
commit 5c22bad5dcbd030d95aca36e1c2fb0f77b505e17
14680 tem: add support for window manipulation functions
commit e760f15095bdc9fa107e7c20ed2a5e4fb5865c1d
14732 split vtd out of vmm kernel module
Conflicts:
manifest
26 files changed, 552 insertions, 479 deletions
@@ -5088,6 +5088,9 @@ d usr/kernel/kmdb 0755 root sys d usr/kernel/kmdb/amd64 0755 root sys f usr/kernel/kmdb/amd64/smbfs 0555 root sys f usr/kernel/kmdb/amd64/smbsrv 0555 root sys +d usr/kernel/misc 0755 root sys +d usr/kernel/misc/amd64 0755 root sys +f usr/kernel/misc/amd64/vmm_vtd 0755 root sys d usr/kernel/sched 0755 root sys d usr/kernel/sched/amd64 0755 root sys f usr/kernel/sched/amd64/FSS 0755 root sys diff --git a/usr/src/pkg/manifests/system-bhyve-tests.p5m b/usr/src/pkg/manifests/system-bhyve-tests.p5m index e06f3fc817..1df6e67bd5 100644 --- a/usr/src/pkg/manifests/system-bhyve-tests.p5m +++ b/usr/src/pkg/manifests/system-bhyve-tests.p5m @@ -50,6 +50,7 @@ file path=opt/bhyve-tests/tests/mevent/read_requeue mode=0555 file path=opt/bhyve-tests/tests/mevent/vnode_file mode=0555 file path=opt/bhyve-tests/tests/mevent/vnode_zvol mode=0555 dir path=opt/bhyve-tests/tests/vmm +file path=opt/bhyve-tests/tests/vmm/check_iommu mode=0555 file path=opt/bhyve-tests/tests/vmm/fpu_getset mode=0555 file path=opt/bhyve-tests/tests/vmm/interface_version mode=0555 file path=opt/bhyve-tests/tests/vmm/mem_devmem mode=0555 diff --git a/usr/src/pkg/manifests/system-bhyve.p5m b/usr/src/pkg/manifests/system-bhyve.p5m index ae95d62061..84e74d27cb 100644 --- a/usr/src/pkg/manifests/system-bhyve.p5m +++ b/usr/src/pkg/manifests/system-bhyve.p5m @@ -16,6 +16,7 @@ # # Copyright 2018 Joyent, Inc. # Copyright 2022 OmniOS Community Edition (OmniOSce) Association. +# Copyright 2022 Oxide Computer Company # # @@ -40,6 +41,9 @@ file path=usr/kernel/drv/$(ARCH64)/vmm file path=usr/kernel/drv/ppt.conf file path=usr/kernel/drv/viona.conf file path=usr/kernel/drv/vmm.conf +dir path=usr/kernel/misc group=sys +dir path=usr/kernel/misc/$(ARCH64) group=sys +file path=usr/kernel/misc/$(ARCH64)/vmm_vtd mode=0755 file path=usr/lib/rsrvrctl mode=0555 dir path=usr/sbin file path=usr/sbin/bhyve mode=0555 diff --git a/usr/src/test/bhyve-tests/tests/vmm/Makefile b/usr/src/test/bhyve-tests/tests/vmm/Makefile index eeca882915..e774f5f6c0 100644 --- a/usr/src/test/bhyve-tests/tests/vmm/Makefile +++ b/usr/src/test/bhyve-tests/tests/vmm/Makefile @@ -19,7 +19,8 @@ PROG = mem_partial \ mem_seg_map \ mem_devmem \ fpu_getset \ - interface_version + interface_version \ + check_iommu COMMON_OBJS = common.o CLEAN_OBJS = $(PROG:%=%.o) diff --git a/usr/src/test/bhyve-tests/tests/vmm/check_iommu.c b/usr/src/test/bhyve-tests/tests/vmm/check_iommu.c new file mode 100644 index 0000000000..1b7ffb01a8 --- /dev/null +++ b/usr/src/test/bhyve-tests/tests/vmm/check_iommu.c @@ -0,0 +1,45 @@ +/* + * 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 Oxide Computer Company + */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <fcntl.h> +#include <libgen.h> + +#include <sys/vmm.h> +#include <sys/vmm_dev.h> + +int +main(int argc, char *argv[]) +{ + const char *suite_name = basename(argv[0]); + + int ctl_fd = open(VMM_CTL_DEV, O_EXCL | O_RDWR); + if (ctl_fd < 0) { + perror("could not open vmmctl device"); + return (EXIT_FAILURE); + } + + int res = ioctl(ctl_fd, VMM_CHECK_IOMMU, 0); + if (res < 0) { + perror("VMM_CHECK_IOMMU ioctl failed"); + return (EXIT_FAILURE); + } + + (void) close(ctl_fd); + (void) printf("%s\tPASS\n", suite_name); + return (0); +} diff --git a/usr/src/uts/common/io/conskbd.c b/usr/src/uts/common/io/conskbd.c index feaf659d33..03188b3a6c 100644 --- a/usr/src/uts/common/io/conskbd.c +++ b/usr/src/uts/common/io/conskbd.c @@ -149,7 +149,7 @@ static struct qinit conskbdlrinit = { /* lower write processing procedures structures */ static struct qinit conskbdlwinit = { putq, /* qi_putp */ - conskbdlwserv, /* qi_srvp */ + conskbdlwserv, /* qi_srvp */ (int (*)())NULL, /* qi_qopen */ (int (*)())NULL, /* qi_qclose */ (int (*)())NULL, /* qi_qadmin */ @@ -1131,6 +1131,15 @@ conskbdlrput(queue_t *q, mblk_t *mp) DPRINTF(PRINT_L1, PRINT_MASK_ALL, ("conskbdlrput\n")); switch (mp->b_datap->db_type) { + case M_CTL: + mp->b_datap->db_type = M_DATA; + if (conskbd.conskbd_directio) + putnext(conskbd_regqueue, mp); + else if (conskbd_consqueue != NULL) + putnext(conskbd_consqueue, mp); + else + freemsg(mp); + break; case M_FLUSH: if (*mp->b_rptr == FLUSHR) { diff --git a/usr/src/uts/common/io/tem.c b/usr/src/uts/common/io/tem.c index 42b34ab37c..7c34655bd6 100644 --- a/usr/src/uts/common/io/tem.c +++ b/usr/src/uts/common/io/tem.c @@ -276,7 +276,7 @@ tem_initialized(tem_vt_state_t tem_arg) } tem_vt_state_t -tem_init(cred_t *credp) +tem_init(cred_t *credp, queue_t *rq) { struct tem_vt_state *ptem; @@ -288,6 +288,7 @@ tem_init(cred_t *credp) ptem->tvs_isactive = B_FALSE; ptem->tvs_fbmode = KD_TEXT; + ptem->tvs_queue = rq; /* * A tem is regarded as initialized only after tem_internal_init(), diff --git a/usr/src/uts/common/io/tem_safe.c b/usr/src/uts/common/io/tem_safe.c index 41f93c42be..04e598f994 100644 --- a/usr/src/uts/common/io/tem_safe.c +++ b/usr/src/uts/common/io/tem_safe.c @@ -845,6 +845,57 @@ tem_safe_selgraph(struct tem_vt_state *tem) } /* + * Handle window manipulation. + */ +static void +tem_safe_window(struct tem_vt_state *tem, enum called_from called_from) +{ + int curparam; + int param; + int index = 0; + mblk_t *bp; + size_t len; + char buf[27]; + + tem->tvs_state = A_STATE_START; + curparam = tem->tvs_curparam; + do { + param = tem->tvs_params[index]; + + switch (param) { + case 8: /* Resize window to Ps2 lines and Ps3 columns. */ + /* We ignore this */ + index += 2; + curparam -= 2; + break; + + case 18: /* Reports terminal size in characters. */ + if (called_from == CALLED_FROM_STANDALONE) + break; + if (!canputnext(tem->tvs_queue)) + break; + + /* Response: CSI 8 ; lines ; columns t */ + len = snprintf(buf, sizeof (buf), "%c[8;%u;%ut", + 0x1b, tems.ts_c_dimension.height, + tems.ts_c_dimension.width); + + bp = allocb(len, BPRI_HI); + if (bp != NULL) { + bp->b_datap->db_type = M_CTL; + bcopy(buf, bp->b_wptr, len); + bp->b_wptr += len; + (void) putnext(tem->tvs_queue, bp); + } + break; + } + + index++; + curparam--; + } while (curparam > 0); +} + +/* * perform the appropriate action for the escape sequence * * General rule: This code does not validate the arguments passed. @@ -1080,6 +1131,11 @@ tem_safe_chkparam(struct tem_vt_state *tem, tem_char_t ch, cred_t *credp, credp, called_from); break; + case 't': + tem_safe_send_data(tem, credp, called_from); + tem_safe_window(tem, called_from); + break; + case 'X': /* erase char */ tem_safe_setparam(tem, 1, 1); tem_safe_clear_chars(tem, diff --git a/usr/src/uts/common/io/vcons.c b/usr/src/uts/common/io/vcons.c index 5d7a1c67d0..54d0b76b1c 100644 --- a/usr/src/uts/common/io/vcons.c +++ b/usr/src/uts/common/io/vcons.c @@ -351,7 +351,7 @@ vt_open(minor_t minor, queue_t *rq, cred_t *crp) * vc_tem might not be intialized if !tems.ts_initialized, * and this only happens during console configuration. */ - pvc->vc_tem = tem_init(crp); + pvc->vc_tem = tem_init(crp, rq); } if (!(pvc->vc_flags & WCS_INIT)) diff --git a/usr/src/uts/common/sys/tem.h b/usr/src/uts/common/sys/tem.h index 6fa3ca01a3..549c2c4deb 100644 --- a/usr/src/uts/common/sys/tem.h +++ b/usr/src/uts/common/sys/tem.h @@ -33,6 +33,7 @@ extern "C" { #ifdef _KERNEL +#include <sys/stream.h> #include <sys/visual_io.h> #include <sys/cred.h> #include <sys/beep.h> @@ -44,7 +45,7 @@ typedef struct __tem_vt_state *tem_vt_state_t; boolean_t tem_initialized(tem_vt_state_t); -tem_vt_state_t tem_init(cred_t *); +tem_vt_state_t tem_init(cred_t *, queue_t *); void tem_destroy(tem_vt_state_t, cred_t *); diff --git a/usr/src/uts/common/sys/tem_impl.h b/usr/src/uts/common/sys/tem_impl.h index 8af55ab75f..202eebb45b 100644 --- a/usr/src/uts/common/sys/tem_impl.h +++ b/usr/src/uts/common/sys/tem_impl.h @@ -187,6 +187,7 @@ typedef struct term_char { * State structure for each virtual terminal emulator */ struct tem_vt_state { + queue_t *tvs_queue; /* read queue for console */ kmutex_t tvs_lock; uchar_t tvs_fbmode; /* framebuffer mode */ uchar_t tvs_alpha; /* rgb alpha channel */ diff --git a/usr/src/uts/intel/Makefile.files b/usr/src/uts/intel/Makefile.files index c062f7400f..4df166d8ef 100644 --- a/usr/src/uts/intel/Makefile.files +++ b/usr/src/uts/intel/Makefile.files @@ -475,3 +475,8 @@ VIONA_OBJS = \ # bhyve PCI-passthru # PPT_OBJS = ppt.o + +# +# bhyve VT-d +# +VMM_VTD_OBJS = vtd.o diff --git a/usr/src/uts/intel/Makefile.intel b/usr/src/uts/intel/Makefile.intel index 8a5adf6f19..79f4c3f26b 100644 --- a/usr/src/uts/intel/Makefile.intel +++ b/usr/src/uts/intel/Makefile.intel @@ -770,3 +770,4 @@ DRV_KMODS += viona # bhyve PCI-passthru # DRV_KMODS += ppt +DRV_KMODS += vmm_vtd diff --git a/usr/src/uts/intel/io/vmm/Makefile.vmm b/usr/src/uts/intel/io/vmm/Makefile.vmm index 84ef0548d9..d7c26183fc 100644 --- a/usr/src/uts/intel/io/vmm/Makefile.vmm +++ b/usr/src/uts/intel/io/vmm/Makefile.vmm @@ -29,7 +29,7 @@ AS_INC_PATH += -I$(UTSBASE)/intel/io/vmm -I$(OBJS_DIR) # enable collection of VMM statistics CFLAGS += -DVMM_KEEP_STATS -LDFLAGS += -N misc/acpica -N misc/pcie -N fs/dev +LDFLAGS += -N misc/pcie -N fs/dev LDFLAGS += -M $(MAPFILE) # devmem span calculations currently run afoul of overflow checks @@ -66,13 +66,10 @@ VMM_OBJS = \ vmx_msr.o \ vmx.o \ vmx_support.o \ - vtd.o \ - vtd_sol.o \ svm.o \ svm_msr.o \ vmcb.o \ svm_support.o \ - amdv.o \ vmm_gpt.o \ seg_vmm.o \ vmm_reservoir.o \ diff --git a/usr/src/uts/intel/io/vmm/amd/amdv.c b/usr/src/uts/intel/io/vmm/amd/amdv.c deleted file mode 100644 index b056ab86d2..0000000000 --- a/usr/src/uts/intel/io/vmm/amd/amdv.c +++ /dev/null @@ -1,148 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2011 NetApp, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -/* - * 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 2014 Pluribus Networks Inc. - * Copyright 2017 Joyent, Inc. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/errno.h> - -#include <machine/vmm.h> -#include "io/iommu.h" - -static int -amd_iommu_init(void) -{ - - printf("amd_iommu_init: not implemented\n"); - return (ENXIO); -} - -static void -amd_iommu_cleanup(void) -{ - - printf("amd_iommu_cleanup: not implemented\n"); -} - -static void -amd_iommu_enable(void) -{ - - printf("amd_iommu_enable: not implemented\n"); -} - -static void -amd_iommu_disable(void) -{ - - printf("amd_iommu_disable: not implemented\n"); -} - -static void * -amd_iommu_create_domain(vm_paddr_t maxaddr) -{ - - printf("amd_iommu_create_domain: not implemented\n"); - return (NULL); -} - -static void -amd_iommu_destroy_domain(void *domain) -{ - - printf("amd_iommu_destroy_domain: not implemented\n"); -} - -static uint64_t -amd_iommu_create_mapping(void *domain, vm_paddr_t gpa, vm_paddr_t hpa, - uint64_t len) -{ - - printf("amd_iommu_create_mapping: not implemented\n"); - return (0); -} - -static uint64_t -amd_iommu_remove_mapping(void *domain, vm_paddr_t gpa, uint64_t len) -{ - - printf("amd_iommu_remove_mapping: not implemented\n"); - return (0); -} - -static void -amd_iommu_add_device(void *domain, uint16_t rid) -{ - - printf("amd_iommu_add_device: not implemented\n"); -} - -static void -amd_iommu_remove_device(void *domain, uint16_t rid) -{ - - printf("amd_iommu_remove_device: not implemented\n"); -} - -static void -amd_iommu_invalidate_tlb(void *domain) -{ - - printf("amd_iommu_invalidate_tlb: not implemented\n"); -} - -const struct iommu_ops iommu_ops_amd = { - amd_iommu_init, - amd_iommu_cleanup, - amd_iommu_enable, - amd_iommu_disable, - amd_iommu_create_domain, - amd_iommu_destroy_domain, - amd_iommu_create_mapping, - amd_iommu_remove_mapping, - amd_iommu_add_device, - amd_iommu_remove_device, - amd_iommu_invalidate_tlb, -}; diff --git a/usr/src/uts/intel/io/vmm/intel/vtd.c b/usr/src/uts/intel/io/vmm/intel/vtd.c index 6f5e6626c8..d365b92163 100644 --- a/usr/src/uts/intel/io/vmm/intel/vtd.c +++ b/usr/src/uts/intel/io/vmm/intel/vtd.c @@ -27,6 +27,19 @@ * * $FreeBSD$ */ +/* + * 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 2018 Joyent, Inc. + * Copyright 2022 Oxide Computer Company + */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -124,9 +137,7 @@ static int drhd_num; static struct vtdmap *vtdmaps[DRHD_MAX_UNITS]; static int max_domains; typedef int (*drhd_ident_func_t)(void); -#ifndef __FreeBSD__ -static dev_info_t *vtddips[DRHD_MAX_UNITS]; -#endif +static dev_info_t *vtddips[DRHD_MAX_UNITS]; static uint64_t root_table[PAGE_SIZE / sizeof (uint64_t)] __aligned(4096); static uint64_t ctx_tables[256][PAGE_SIZE / sizeof (uint64_t)] __aligned(4096); @@ -342,12 +353,71 @@ vtd_unmap(dev_info_t *dip) ddi_regs_map_free(&hdl); } -#ifndef __FreeBSD__ -/* - * This lives in vtd_sol.c for license reasons. - */ -extern dev_info_t *vtd_get_dip(ACPI_DMAR_HARDWARE_UNIT *, int); -#endif +static dev_info_t * +vtd_get_dip(ACPI_DMAR_HARDWARE_UNIT *drhd, int unit) +{ + dev_info_t *dip; + struct ddi_parent_private_data *pdptr; + struct regspec reg; + int circ; + + /* + * Try to find an existing devinfo node for this vtd unit. + */ + ndi_devi_enter(ddi_root_node(), &circ); + dip = ddi_find_devinfo("vtd", unit, 0); + ndi_devi_exit(ddi_root_node(), circ); + + if (dip != NULL) + return (dip); + + /* + * None found, construct a devinfo node for this vtd unit. + */ + dip = ddi_add_child(ddi_root_node(), "vtd", + DEVI_SID_NODEID, unit); + + reg.regspec_bustype = 0; + reg.regspec_addr = drhd->Address; + reg.regspec_size = PAGE_SIZE; + + /* + * update the reg properties + * + * reg property will be used for register + * set access + * + * refer to the bus_map of root nexus driver + * I/O or memory mapping: + * + * <bustype=0, addr=x, len=x>: memory + * <bustype=1, addr=x, len=x>: i/o + * <bustype>1, addr=0, len=x>: x86-compatibility i/o + */ + (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, + dip, "reg", (int *)®, + sizeof (struct regspec) / sizeof (int)); + + /* + * This is an artificially constructed dev_info, and we + * need to set a few more things to be able to use it + * for ddi_dma_alloc_handle/free_handle. + */ + ddi_set_driver(dip, ddi_get_driver(ddi_root_node())); + DEVI(dip)->devi_bus_dma_allochdl = + DEVI(ddi_get_driver((ddi_root_node()))); + + pdptr = kmem_zalloc(sizeof (struct ddi_parent_private_data) + + sizeof (struct regspec), KM_SLEEP); + pdptr->par_nreg = 1; + pdptr->par_reg = (struct regspec *)(pdptr + 1); + pdptr->par_reg->regspec_bustype = 0; + pdptr->par_reg->regspec_addr = drhd->Address; + pdptr->par_reg->regspec_size = PAGE_SIZE; + ddi_set_parent_data(dip, pdptr); + + return (dip); +} static int vtd_init(void) @@ -859,7 +929,7 @@ vtd_destroy_domain(void *arg) kmem_free(dom, sizeof (*dom)); } -const struct iommu_ops iommu_ops_intel = { +const struct iommu_ops vmm_iommu_ops = { .init = vtd_init, .cleanup = vtd_cleanup, .enable = vtd_enable, @@ -872,3 +942,33 @@ const struct iommu_ops iommu_ops_intel = { .remove_device = vtd_remove_device, .invalidate_tlb = vtd_invalidate_tlb, }; + + +static struct modlmisc modlmisc = { + &mod_miscops, + "bhyve vmm vtd", +}; + +static struct modlinkage modlinkage = { + MODREV_1, + &modlmisc, + NULL +}; + +int +_init(void) +{ + return (mod_install(&modlinkage)); +} + +int +_fini(void) +{ + return (mod_remove(&modlinkage)); +} + +int +_info(struct modinfo *modinfop) +{ + return (mod_info(&modlinkage, modinfop)); +} diff --git a/usr/src/uts/intel/io/vmm/intel/vtd_sol.c b/usr/src/uts/intel/io/vmm/intel/vtd_sol.c deleted file mode 100644 index 26c6c5b024..0000000000 --- a/usr/src/uts/intel/io/vmm/intel/vtd_sol.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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. - */ -/* This file is dual-licensed; see usr/src/contrib/bhyve/LICENSE */ - -/* - * Copyright 2018 Joyent, Inc. - */ - -#include <sys/sunndi.h> -#include <contrib/dev/acpica/include/acpi.h> - -dev_info_t * -vtd_get_dip(ACPI_DMAR_HARDWARE_UNIT *drhd, int unit) -{ - dev_info_t *dip; - struct ddi_parent_private_data *pdptr; - struct regspec reg; - int circ; - - /* - * Try to find an existing devinfo node for this vtd unit. - */ - ndi_devi_enter(ddi_root_node(), &circ); - dip = ddi_find_devinfo("vtd", unit, 0); - ndi_devi_exit(ddi_root_node(), circ); - - if (dip != NULL) - return (dip); - - /* - * None found, construct a devinfo node for this vtd unit. - */ - dip = ddi_add_child(ddi_root_node(), "vtd", - DEVI_SID_NODEID, unit); - - reg.regspec_bustype = 0; - reg.regspec_addr = drhd->Address; - reg.regspec_size = PAGE_SIZE; - - /* - * update the reg properties - * - * reg property will be used for register - * set access - * - * refer to the bus_map of root nexus driver - * I/O or memory mapping: - * - * <bustype=0, addr=x, len=x>: memory - * <bustype=1, addr=x, len=x>: i/o - * <bustype>1, addr=0, len=x>: x86-compatibility i/o - */ - (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, - dip, "reg", (int *)®, - sizeof (struct regspec) / sizeof (int)); - - /* - * This is an artificially constructed dev_info, and we - * need to set a few more things to be able to use it - * for ddi_dma_alloc_handle/free_handle. - */ - ddi_set_driver(dip, ddi_get_driver(ddi_root_node())); - DEVI(dip)->devi_bus_dma_allochdl = - DEVI(ddi_get_driver((ddi_root_node()))); - - pdptr = kmem_zalloc(sizeof (struct ddi_parent_private_data) - + sizeof (struct regspec), KM_SLEEP); - pdptr->par_nreg = 1; - pdptr->par_reg = (struct regspec *)(pdptr + 1); - pdptr->par_reg->regspec_bustype = 0; - pdptr->par_reg->regspec_addr = drhd->Address; - pdptr->par_reg->regspec_size = PAGE_SIZE; - ddi_set_parent_data(dip, pdptr); - - return (dip); -} diff --git a/usr/src/uts/intel/io/vmm/io/iommu.c b/usr/src/uts/intel/io/vmm/io/iommu.c index 3ebd394b99..8374a6da58 100644 --- a/usr/src/uts/intel/io/vmm/io/iommu.c +++ b/usr/src/uts/intel/io/vmm/io/iommu.c @@ -27,6 +27,18 @@ * * $FreeBSD$ */ +/* + * 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 Oxide Computer Company + */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -50,132 +62,16 @@ __FBSDID("$FreeBSD$"); #include "vmm_util.h" #include "iommu.h" -static int iommu_avail; -static int iommu_enable = 1; +static kmutex_t iommu_lock; +static uint_t iommu_refcnt; +ddi_modhandle_t iommu_modhdl; static const struct iommu_ops *ops; static void *host_domain; -#ifdef __FreeBSD__ -static eventhandler_tag add_tag, delete_tag; -#endif -#ifndef __FreeBSD__ static volatile uint_t iommu_initted; -#endif - -static __inline int -IOMMU_INIT(void) -{ - if (ops != NULL) - return ((*ops->init)()); - else - return (ENXIO); -} - -static __inline void -IOMMU_CLEANUP(void) -{ - if (ops != NULL && iommu_avail) - (*ops->cleanup)(); -} - -static __inline void * -IOMMU_CREATE_DOMAIN(vm_paddr_t maxaddr) -{ - - if (ops != NULL && iommu_avail) - return ((*ops->create_domain)(maxaddr)); - else - return (NULL); -} - -static __inline void -IOMMU_DESTROY_DOMAIN(void *dom) -{ - - if (ops != NULL && iommu_avail) - (*ops->destroy_domain)(dom); -} - -static __inline uint64_t -IOMMU_CREATE_MAPPING(void *domain, vm_paddr_t gpa, vm_paddr_t hpa, uint64_t len) -{ - - if (ops != NULL && iommu_avail) - return ((*ops->create_mapping)(domain, gpa, hpa, len)); - else - return (len); /* XXX */ -} - -static __inline uint64_t -IOMMU_REMOVE_MAPPING(void *domain, vm_paddr_t gpa, uint64_t len) -{ - - if (ops != NULL && iommu_avail) - return ((*ops->remove_mapping)(domain, gpa, len)); - else - return (len); /* XXX */ -} - -static __inline void -IOMMU_ADD_DEVICE(void *domain, uint16_t rid) -{ - - if (ops != NULL && iommu_avail) - (*ops->add_device)(domain, rid); -} - -static __inline void -IOMMU_REMOVE_DEVICE(void *domain, uint16_t rid) -{ - - if (ops != NULL && iommu_avail) - (*ops->remove_device)(domain, rid); -} - -static __inline void -IOMMU_INVALIDATE_TLB(void *domain) -{ - - if (ops != NULL && iommu_avail) - (*ops->invalidate_tlb)(domain); -} - -static __inline void -IOMMU_ENABLE(void) -{ - - if (ops != NULL && iommu_avail) - (*ops->enable)(); -} - -static __inline void -IOMMU_DISABLE(void) -{ - - if (ops != NULL && iommu_avail) - (*ops->disable)(); -} -#ifdef __FreeBSD__ -static void -iommu_pci_add(void *arg, device_t dev) -{ - - /* Add new devices to the host domain. */ - iommu_add_device(host_domain, pci_get_rid(dev)); -} - -static void -iommu_pci_delete(void *arg, device_t dev) -{ - - iommu_remove_device(host_domain, pci_get_rid(dev)); -} -#endif - -#ifndef __FreeBSD__ static int iommu_find_device(dev_info_t *dip, void *arg) { @@ -196,110 +92,153 @@ vmm_mem_maxaddr(void) { return (ptoa(physmax + 1)); } -#endif -static void +static int iommu_init(void) { - int error; - vm_paddr_t maxaddr; + const char *mod_name; + int error = 0; - if (!iommu_enable) - return; + ASSERT(MUTEX_HELD(&iommu_lock)); - if (vmm_is_intel()) - ops = &iommu_ops_intel; - else if (vmm_is_svm()) - ops = &iommu_ops_amd; - else - ops = NULL; + if (vmm_is_intel()) { + mod_name = "misc/vmm_vtd"; + } else if (vmm_is_svm()) { + /* Use the expected name for if/when this is ported */ + mod_name = "misc/vmm_amdvi"; + } else { + return (ENXIO); + } - error = IOMMU_INIT(); - if (error) - return; + /* Load the backend driver */ + iommu_modhdl = ddi_modopen(mod_name, KRTLD_MODE_FIRST, &error); + if (iommu_modhdl == NULL) { + return (error); + } - iommu_avail = 1; + /* Locate the iommu_ops struct */ + ops = ddi_modsym(iommu_modhdl, IOMMU_OPS_SYM_NAME, &error); + if (ops == NULL) { + goto bail; + } - /* - * Create a domain for the devices owned by the host - */ - maxaddr = vmm_mem_maxaddr(); - host_domain = IOMMU_CREATE_DOMAIN(maxaddr); + /* Initialize the backend */ + error = ops->init(); + if (error != 0) { + goto bail; + } + + /* Create a domain for the devices owned by the host */ + const vm_paddr_t maxaddr = vmm_mem_maxaddr(); + host_domain = ops->create_domain(maxaddr); if (host_domain == NULL) { - printf("iommu_init: unable to create a host domain"); - IOMMU_CLEANUP(); - ops = NULL; - iommu_avail = 0; - return; + goto bail; } - /* - * Create 1:1 mappings from '0' to 'maxaddr' for devices assigned to - * the host - */ + /* ... and populate it with 1:1 mappings for all of physical mem */ iommu_create_mapping(host_domain, 0, 0, maxaddr); ddi_walk_devs(ddi_root_node(), iommu_find_device, (void *)B_TRUE); - IOMMU_ENABLE(); + ops->enable(); + + return (0); +bail: + if (ops != NULL) { + ops->cleanup(); + ops = NULL; + } + if (iommu_modhdl != NULL) { + (void) ddi_modclose(iommu_modhdl); + iommu_modhdl = NULL; + } + return (error); } -void +static void iommu_cleanup(void) { -#ifdef __FreeBSD__ - if (add_tag != NULL) { - EVENTHANDLER_DEREGISTER(pci_add_device, add_tag); - add_tag = NULL; - } - if (delete_tag != NULL) { - EVENTHANDLER_DEREGISTER(pci_delete_device, delete_tag); - delete_tag = NULL; - } -#else - atomic_store_rel_int(&iommu_initted, 0); -#endif - IOMMU_DISABLE(); -#ifndef __FreeBSD__ + ASSERT(MUTEX_HELD(&iommu_lock)); + ASSERT3P(ops, !=, NULL); + ASSERT0(iommu_refcnt); + + ops->disable(); ddi_walk_devs(ddi_root_node(), iommu_find_device, (void *)B_FALSE); -#endif - IOMMU_DESTROY_DOMAIN(host_domain); - IOMMU_CLEANUP(); -#ifndef __FreeBSD__ + + ops->destroy_domain(host_domain); + host_domain = NULL; + + ops->cleanup(); ops = NULL; -#endif + + (void) ddi_modclose(iommu_modhdl); + iommu_modhdl = NULL; +} + +static bool +iommu_ref(void) +{ + mutex_enter(&iommu_lock); + if (ops == NULL) { + int err = iommu_init(); + + if (err != 0) { + VERIFY3P(ops, ==, NULL); + mutex_exit(&iommu_lock); + return (false); + } + VERIFY3P(ops, !=, NULL); + } + iommu_refcnt++; + VERIFY3U(iommu_refcnt, <, UINT_MAX); + mutex_exit(&iommu_lock); + + return (true); +} + +static void +iommu_unref(void) +{ + mutex_enter(&iommu_lock); + VERIFY3U(iommu_refcnt, >, 0); + iommu_refcnt--; + if (iommu_refcnt == 0) { + iommu_cleanup(); + VERIFY3P(ops, ==, NULL); + } + mutex_exit(&iommu_lock); } void * iommu_create_domain(vm_paddr_t maxaddr) { - if (iommu_initted < 2) { - if (atomic_cmpset_int(&iommu_initted, 0, 1)) { - iommu_init(); - atomic_store_rel_int(&iommu_initted, 2); - } else - while (iommu_initted == 1) - cpu_spinwait(); + if (iommu_ref()) { + return (ops->create_domain(maxaddr)); + } else { + return (NULL); } - return (IOMMU_CREATE_DOMAIN(maxaddr)); } void -iommu_destroy_domain(void *dom) +iommu_destroy_domain(void *domain) { + ASSERT3P(domain, !=, NULL); - IOMMU_DESTROY_DOMAIN(dom); + ops->destroy_domain(domain); + iommu_unref(); } void -iommu_create_mapping(void *dom, vm_paddr_t gpa, vm_paddr_t hpa, size_t len) +iommu_create_mapping(void *domain, vm_paddr_t gpa, vm_paddr_t hpa, size_t len) { - uint64_t mapped, remaining; + uint64_t remaining = len; - remaining = len; + ASSERT3P(domain, !=, NULL); while (remaining > 0) { - mapped = IOMMU_CREATE_MAPPING(dom, gpa, hpa, remaining); + uint64_t mapped; + + mapped = ops->create_mapping(domain, gpa, hpa, remaining); gpa += mapped; hpa += mapped; remaining -= mapped; @@ -307,14 +246,16 @@ iommu_create_mapping(void *dom, vm_paddr_t gpa, vm_paddr_t hpa, size_t len) } void -iommu_remove_mapping(void *dom, vm_paddr_t gpa, size_t len) +iommu_remove_mapping(void *domain, vm_paddr_t gpa, size_t len) { - uint64_t unmapped, remaining; + uint64_t remaining = len; - remaining = len; + ASSERT3P(domain, !=, NULL); while (remaining > 0) { - unmapped = IOMMU_REMOVE_MAPPING(dom, gpa, remaining); + uint64_t unmapped; + + unmapped = ops->remove_mapping(domain, gpa, remaining); gpa += unmapped; remaining -= unmapped; } @@ -323,27 +264,29 @@ iommu_remove_mapping(void *dom, vm_paddr_t gpa, size_t len) void * iommu_host_domain(void) { - return (host_domain); } void -iommu_add_device(void *dom, uint16_t rid) +iommu_add_device(void *domain, uint16_t rid) { + ASSERT3P(domain, !=, NULL); - IOMMU_ADD_DEVICE(dom, rid); + ops->add_device(domain, rid); } void -iommu_remove_device(void *dom, uint16_t rid) +iommu_remove_device(void *domain, uint16_t rid) { + ASSERT3P(domain, !=, NULL); - IOMMU_REMOVE_DEVICE(dom, rid); + ops->remove_device(domain, rid); } void iommu_invalidate_tlb(void *domain) { + ASSERT3P(domain, !=, NULL); - IOMMU_INVALIDATE_TLB(domain); + ops->invalidate_tlb(domain); } diff --git a/usr/src/uts/intel/io/vmm/io/iommu.h b/usr/src/uts/intel/io/vmm/io/iommu.h index 0d1c4b1ee2..a7d0214091 100644 --- a/usr/src/uts/intel/io/vmm/io/iommu.h +++ b/usr/src/uts/intel/io/vmm/io/iommu.h @@ -27,6 +27,18 @@ * * $FreeBSD$ */ +/* + * 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 Oxide Computer Company + */ #ifndef _IO_IOMMU_H_ #define _IO_IOMMU_H_ @@ -42,8 +54,8 @@ typedef uint64_t (*iommu_create_mapping_t)(void *domain, vm_paddr_t gpa, typedef uint64_t (*iommu_remove_mapping_t)(void *domain, vm_paddr_t gpa, uint64_t len); typedef void (*iommu_add_device_t)(void *domain, uint16_t rid); -typedef void (*iommu_remove_device_t)(void *dom, uint16_t rid); -typedef void (*iommu_invalidate_tlb_t)(void *dom); +typedef void (*iommu_remove_device_t)(void *domain, uint16_t rid); +typedef void (*iommu_invalidate_tlb_t)(void *domain); struct iommu_ops { iommu_init_func_t init; /* module wide */ @@ -60,19 +72,17 @@ struct iommu_ops { iommu_invalidate_tlb_t invalidate_tlb; }; -extern const struct iommu_ops iommu_ops_intel; -extern const struct iommu_ops iommu_ops_amd; +#define IOMMU_OPS_SYM_NAME "vmm_iommu_ops" -void iommu_cleanup(void); -void *iommu_host_domain(void); -void *iommu_create_domain(vm_paddr_t maxaddr); -void iommu_destroy_domain(void *dom); -void iommu_create_mapping(void *dom, vm_paddr_t gpa, vm_paddr_t hpa, +void *iommu_host_domain(void); +void *iommu_create_domain(vm_paddr_t maxaddr); +void iommu_destroy_domain(void *domain); +void iommu_create_mapping(void *domain, vm_paddr_t gpa, vm_paddr_t hpa, size_t len); -void iommu_remove_mapping(void *dom, vm_paddr_t gpa, size_t len); -void iommu_add_device(void *dom, uint16_t rid); -void iommu_remove_device(void *dom, uint16_t rid); -void iommu_invalidate_tlb(void *domain); +void iommu_remove_mapping(void *domain, vm_paddr_t gpa, size_t len); +void iommu_add_device(void *domain, uint16_t rid); +void iommu_remove_device(void *domain, uint16_t rid); +void iommu_invalidate_tlb(void *domain); /* Glue functions used by iommu provider(s) */ void *vmm_ptp_alloc(void); diff --git a/usr/src/uts/intel/io/vmm/sys/vmm_kernel.h b/usr/src/uts/intel/io/vmm/sys/vmm_kernel.h index 29e90e3a1e..87f8e18b47 100644 --- a/usr/src/uts/intel/io/vmm/sys/vmm_kernel.h +++ b/usr/src/uts/intel/io/vmm/sys/vmm_kernel.h @@ -383,6 +383,8 @@ void vmm_contig_free(void *, size_t); int vmm_mod_load(void); int vmm_mod_unload(void); +bool vmm_check_iommu(void); + void vmm_call_trap(uint64_t); /* diff --git a/usr/src/uts/intel/io/vmm/vmm.c b/usr/src/uts/intel/io/vmm/vmm.c index 800ae4d8ee..0ff23e88b2 100644 --- a/usr/src/uts/intel/io/vmm/vmm.c +++ b/usr/src/uts/intel/io/vmm/vmm.c @@ -458,7 +458,6 @@ vmm_mod_unload() VERIFY(vmm_initialized == 1); - iommu_cleanup(); error = VMM_CLEANUP(); if (error) return (error); @@ -467,6 +466,24 @@ vmm_mod_unload() return (0); } +/* + * Create a test IOMMU domain to see if the host system has necessary hardware + * and drivers to do so. + */ +bool +vmm_check_iommu(void) +{ + void *domain; + const size_t arb_test_sz = (1UL << 32); + + domain = iommu_create_domain(arb_test_sz); + if (domain == NULL) { + return (false); + } + iommu_destroy_domain(domain); + return (true); +} + static void vm_init(struct vm *vm, bool create) { @@ -975,15 +992,9 @@ vm_iommu_modify(struct vm *vm, bool map) int i, sz; vm_paddr_t gpa, hpa; struct mem_map *mm; -#ifdef __FreeBSD__ - void *vp, *cookie, *host_domain; -#endif vm_client_t *vmc; sz = PAGE_SIZE; -#ifdef __FreeBSD__ - host_domain = iommu_host_domain(); -#endif vmc = vmspace_client_alloc(vm->vmspace); for (i = 0; i < VM_MAX_MEMMAPS; i++) { @@ -1016,16 +1027,22 @@ vm_iommu_modify(struct vm *vm, bool map) hpa = ((uintptr_t)vmp_get_pfn(vmp) << PAGESHIFT); (void) vmp_release(vmp); + /* + * When originally ported from FreeBSD, the logic for + * adding memory to the guest domain would + * simultaneously remove it from the host domain. The + * justification for that is not clear, and FreeBSD has + * subsequently changed the behavior to not remove the + * memory from the host domain. + * + * Leaving the guest memory in the host domain for the + * life of the VM is necessary to make it available for + * DMA, such as through viona in the TX path. + */ if (map) { iommu_create_mapping(vm->iommu, gpa, hpa, sz); -#ifdef __FreeBSD__ - iommu_remove_mapping(host_domain, hpa, sz); -#endif } else { iommu_remove_mapping(vm->iommu, gpa, sz); -#ifdef __FreeBSD__ - iommu_create_mapping(host_domain, hpa, hpa, sz); -#endif } gpa += PAGE_SIZE; @@ -1037,14 +1054,7 @@ vm_iommu_modify(struct vm *vm, bool map) * Invalidate the cached translations associated with the domain * from which pages were removed. */ -#ifdef __FreeBSD__ - if (map) - iommu_invalidate_tlb(host_domain); - else - iommu_invalidate_tlb(vm->iommu); -#else iommu_invalidate_tlb(vm->iommu); -#endif } int diff --git a/usr/src/uts/intel/io/vmm/vmm.mapfile b/usr/src/uts/intel/io/vmm/vmm.mapfile index fb1c9366de..e4d58aac6d 100644 --- a/usr/src/uts/intel/io/vmm/vmm.mapfile +++ b/usr/src/uts/intel/io/vmm/vmm.mapfile @@ -12,7 +12,7 @@ # # Copyright 2019 Joyent, Inc. -# Copyright 2021 Oxide Computer Company +# Copyright 2022 Oxide Computer Company # # @@ -64,6 +64,10 @@ SYMBOL_VERSION ILLUMOSprivate { vm_iommu_domain; vm_map_mmio; vm_unmap_mmio; + vmm_ptp_alloc; + vmm_ptp_free; + invalidate_cache_all; + vtophys; local: *; 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 bf57cba26f..a58e9d63f9 100644 --- a/usr/src/uts/intel/io/vmm/vmm_sol_dev.c +++ b/usr/src/uts/intel/io/vmm/vmm_sol_dev.c @@ -2492,6 +2492,11 @@ vmm_ctl_ioctl(int cmd, intptr_t arg, int md, cred_t *cr, int *rvalp) case VMM_INTERFACE_VERSION: *rvalp = VMM_CURRENT_INTERFACE_VERSION; return (0); + case VMM_CHECK_IOMMU: + if (!vmm_check_iommu()) { + return (ENXIO); + } + return (0); case VMM_RESV_QUERY: case VMM_RESV_ADD: case VMM_RESV_REMOVE: diff --git a/usr/src/uts/intel/io/vmm/vmm_vtd.mapfile b/usr/src/uts/intel/io/vmm/vmm_vtd.mapfile new file mode 100644 index 0000000000..bb12b7b132 --- /dev/null +++ b/usr/src/uts/intel/io/vmm/vmm_vtd.mapfile @@ -0,0 +1,45 @@ +# +# 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. +# +# This file is dual-licensed; see usr/src/contrib/bhyve/LICENSE + +# +# Copyright 2022 Oxide Computer Company +# + +# +# MAPFILE HEADER START +# +# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. +# Object versioning must comply with the rules detailed in +# +# usr/src/lib/README.mapfiles +# +# You should not be making modifications here until you've read the most current +# copy of that file. If you need help, contact a gatekeeper for guidance. +# +# MAPFILE HEADER END +# + +$mapfile_version 2 + +SYMBOL_VERSION ILLUMOSprivate { + global: + # DDI Interfaces + _fini; + _init; + _info; + + # IOMMU ops consumed by bhyve + vmm_iommu_ops; + + local: + *; +}; diff --git a/usr/src/uts/intel/sys/vmm_dev.h b/usr/src/uts/intel/sys/vmm_dev.h index 2e4c0c6e40..5333facacf 100644 --- a/usr/src/uts/intel/sys/vmm_dev.h +++ b/usr/src/uts/intel/sys/vmm_dev.h @@ -379,6 +379,7 @@ struct vmm_dirty_tracker { #define VMM_DESTROY_VM (VMMCTL_IOC_BASE | 0x02) #define VMM_VM_SUPPORTED (VMMCTL_IOC_BASE | 0x03) #define VMM_INTERFACE_VERSION (VMMCTL_IOC_BASE | 0x04) +#define VMM_CHECK_IOMMU (VMMCTL_IOC_BASE | 0x05) #define VMM_RESV_QUERY (VMMCTL_IOC_BASE | 0x10) #define VMM_RESV_ADD (VMMCTL_IOC_BASE | 0x11) diff --git a/usr/src/uts/intel/vmm_vtd/Makefile b/usr/src/uts/intel/vmm_vtd/Makefile new file mode 100644 index 0000000000..f3e6acd0e2 --- /dev/null +++ b/usr/src/uts/intel/vmm_vtd/Makefile @@ -0,0 +1,60 @@ +# +# 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 2019 Joyent, Inc. +# Copyright 2022 Oxide Computer Company +# + +UTSBASE = ../.. + +MODULE = vmm_vtd +OBJECTS = $(VMM_VTD_OBJS:%=$(OBJS_DIR)/%) +ROOTMODULE = $(USR_MISC_DIR)/$(MODULE) +CONF_SRCDIR = $(UTSBASE)/intel/io/vmm +MAPFILE = $(UTSBASE)/intel/io/vmm/vmm_vtd.mapfile + +PRE_INC_PATH = \ + -I$(COMPAT)/bhyve \ + -I$(COMPAT)/bhyve/amd64 \ + -I$(CONTRIB)/bhyve \ + -I$(CONTRIB)/bhyve/amd64 + +INC_PATH += -I$(UTSBASE)/intel/io/vmm -I$(UTSBASE)/intel/io/vmm/io +AS_INC_PATH += -I$(UTSBASE)/intel/io/vmm -I$(OBJS_DIR) + +LDFLAGS += -N drv/vmm -N misc/acpica -N misc/pcie +LDFLAGS += -M $(MAPFILE) + +include $(UTSBASE)/intel/Makefile.intel + +ALL_TARGET = $(BINARY) +INSTALL_TARGET = $(BINARY) $(ROOTMODULE) + +ALL_BUILDS = $(ALL_BUILDSONLY64) +DEF_BUILDS = $(DEF_BUILDSONLY64) + +.PARALLEL: $(OBJECTS) + +.KEEP_STATE: + +def: $(DEF_DEPS) + +all: $(ALL_DEPS) + +clean: $(CLEAN_DEPS) + +clobber: $(CLOBBER_DEPS) + +install: $(INSTALL_DEPS) + +include $(UTSBASE)/intel/Makefile.targ +include $(UTSBASE)/intel/io/vmm/Makefile.rules |