diff options
Diffstat (limited to 'usr/src/lib')
-rw-r--r-- | usr/src/lib/Makefile | 3 | ||||
-rw-r--r-- | usr/src/lib/libppt/Makefile | 44 | ||||
-rw-r--r-- | usr/src/lib/libppt/Makefile.com | 46 | ||||
-rw-r--r-- | usr/src/lib/libppt/amd64/Makefile | 19 | ||||
-rw-r--r-- | usr/src/lib/libppt/common/libppt.c | 506 | ||||
-rw-r--r-- | usr/src/lib/libppt/common/libppt.h | 36 | ||||
-rw-r--r-- | usr/src/lib/libppt/common/llib-lppt | 19 | ||||
-rw-r--r-- | usr/src/lib/libppt/common/mapfile-vers | 40 | ||||
-rw-r--r-- | usr/src/lib/libppt/i386/Makefile | 18 | ||||
-rw-r--r-- | usr/src/lib/libppt/sparc/Makefile | 18 | ||||
-rw-r--r-- | usr/src/lib/libppt/sparcv9/Makefile | 19 | ||||
-rw-r--r-- | usr/src/lib/libvmmapi/common/mapfile-vers | 1 | ||||
-rw-r--r-- | usr/src/lib/libvmmapi/common/vmmapi.c | 100 | ||||
-rw-r--r-- | usr/src/lib/libvmmapi/common/vmmapi.h | 15 |
14 files changed, 883 insertions, 1 deletions
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile index b64d4c2bc1..c40721fd55 100644 --- a/usr/src/lib/Makefile +++ b/usr/src/lib/Makefile @@ -186,6 +186,7 @@ SUBDIRS += \ libpkg \ libpool \ libpp \ + libppt \ libproc \ libproject \ libpthread \ @@ -446,6 +447,7 @@ HDRSUBDIRS= \ libpicltree \ libpool \ libpp \ + libppt \ libproc \ libraidcfg \ librcm \ @@ -657,6 +659,7 @@ libpctx: libproc libpkg: libscf libadm libpool: libscf libexacct libpp: libast +libppt: libpcidb libdevinfo libcmdutils libproc: ../cmd/sgs/librtld_db ../cmd/sgs/libelf libctf $(INTEL_BLD)libproc: libsaveargs libproject: libpool libproc libsecdb diff --git a/usr/src/lib/libppt/Makefile b/usr/src/lib/libppt/Makefile new file mode 100644 index 0000000000..21c26d447e --- /dev/null +++ b/usr/src/lib/libppt/Makefile @@ -0,0 +1,44 @@ +# +# 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. +# + +include $(SRC)/lib/Makefile.lib + +SUBDIRS = $(MACH) $(BUILD64) $(MACH64) + +HDRS = libppt.h +HDRDIR = common + +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install +lint := TARGET= lint + +.KEEP_STATE: + +all clean clobber install lint: $(SUBDIRS) + +install_h: $(ROOTHDRS) + +all install: install_h + +check: $(CHECKHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include $(SRC)/lib/Makefile.targ diff --git a/usr/src/lib/libppt/Makefile.com b/usr/src/lib/libppt/Makefile.com new file mode 100644 index 0000000000..7b2ff4885f --- /dev/null +++ b/usr/src/lib/libppt/Makefile.com @@ -0,0 +1,46 @@ +# +# 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. +# + +LIBRARY = libppt.a +VERS = .1 + +OBJECTS = libppt.o + +include $(SRC)/lib/Makefile.lib + +SRCDIR = ../common + +LIBS = $(DYNLIB) $(LINTLIB) +SRCS = $(SRCDIR)/libppt.c + +CSTD= $(CSTD_GNU99) +C99LMODE= -Xc99=%all + +# +# lint doesn't like %4s in sscanf(). +# +LINTFLAGS += -erroff=E_BAD_FORMAT_ARG_TYPE2 +LINTFLAGS64 += -erroff=E_BAD_FORMAT_ARG_TYPE2 + +$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) +LDLIBS += -lpcidb -ldevinfo -lcmdutils -lnvpair -lc + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include $(SRC)/lib/Makefile.targ diff --git a/usr/src/lib/libppt/amd64/Makefile b/usr/src/lib/libppt/amd64/Makefile new file mode 100644 index 0000000000..5a304d7fe7 --- /dev/null +++ b/usr/src/lib/libppt/amd64/Makefile @@ -0,0 +1,19 @@ +# +# 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. +# + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) diff --git a/usr/src/lib/libppt/common/libppt.c b/usr/src/lib/libppt/common/libppt.c new file mode 100644 index 0000000000..7e8385da06 --- /dev/null +++ b/usr/src/lib/libppt/common/libppt.c @@ -0,0 +1,506 @@ +/* + * 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. + * + * Convenience routines for identifying current or available devices that are + * suitable for PCI passthrough to a bhyve guest. + */ + +#include <libdevinfo.h> +#include <libppt.h> + +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/list.h> +#include <strings.h> +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <pcidb.h> +#include <glob.h> + +typedef struct node_data { + pcidb_hdl_t *nd_db; + list_t nd_matches; + nvlist_t *nd_nvl; + int nd_err; +} node_data_t; + +typedef struct ppt_match { + list_node_t pm_list; + char pm_path[MAXPATHLEN]; + char pm_vendor[5]; + char pm_device[5]; +} ppt_match_t; + +static boolean_t +is_pci(di_node_t di_node) +{ + char *svals; + + if (di_prop_lookup_strings(DDI_DEV_T_ANY, di_parent_node(di_node), + "device_type", &svals) != 1) + return (B_FALSE); + + return (strcmp(svals, "pci") == 0 || strcmp(svals, "pciex") == 0); +} + +static int +populate_int_prop(di_node_t di_node, nvlist_t *nvl, const char *name, int *ival) +{ + char val[20]; + int *ivals; + int err; + + if (di_prop_lookup_ints(DDI_DEV_T_ANY, di_node, name, &ivals) != 1) + return (errno); + + (void) snprintf(val, sizeof (val), "%x", ivals[0]); + + err = nvlist_add_string(nvl, name, val); + + if (err == 0 && ival != NULL) + *ival = ivals[0]; + + return (err); +} + +static int +dev_getlabel(pcidb_hdl_t *db, int vid, int did, char *buf, size_t buflen) +{ + pcidb_vendor_t *vend = NULL; + pcidb_device_t *dev = NULL; + + if ((vend = pcidb_lookup_vendor(db, vid)) == NULL) + return (ENOENT); + + if ((dev = pcidb_lookup_device_by_vendor(vend, did)) == NULL) + return (ENOENT); + + (void) snprintf(buf, buflen, "%s %s", pcidb_vendor_name(vend), + pcidb_device_name(dev)); + + return (0); +} + +static nvlist_t * +dev_getinfo(di_node_t di_node, pcidb_hdl_t *db, + const char *dev, const char *path) +{ + char label[MAXPATHLEN]; + nvlist_t *nvl = NULL; + int vid, did; + int err; + + if ((err = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0)) != 0) + goto out; + + if (dev != NULL && (err = nvlist_add_string(nvl, "dev", dev)) != 0) + goto out; + if ((err = nvlist_add_string(nvl, "path", path)) != 0) + goto out; + if ((err = populate_int_prop(di_node, nvl, "vendor-id", &vid)) != 0) + goto out; + if ((err = populate_int_prop(di_node, nvl, "device-id", &did)) != 0) + goto out; + if ((err = populate_int_prop(di_node, nvl, + "subsystem-vendor-id", NULL)) != 0) + goto out; + if ((err = populate_int_prop(di_node, nvl, "subsystem-id", NULL)) != 0) + goto out; + if ((err = populate_int_prop(di_node, nvl, "revision-id", NULL)) != 0) + goto out; + + err = dev_getlabel(db, vid, did, label, sizeof (label)); + + if (err == 0) { + err = nvlist_add_string(nvl, "label", label); + } else if (err == ENOENT) { + err = 0; + } + +out: + if (err) { + nvlist_free(nvl); + errno = err; + return (NULL); + } + + return (nvl); +} + +/* + * /devices/pci0@0/....@0,1:ppt -> /pci0@0/...@0,1 + */ +static const char * +fs_to_phys_path(char *fspath) +{ + const char prefix[] = "/devices"; + char *c; + + if ((c = strrchr(fspath, ':')) != NULL && strcmp(c, ":ppt") == 0) + *c = '\0'; + + c = fspath; + + if (strncmp(c, prefix, sizeof (prefix) - 1) == 0) + c += sizeof (prefix) - 1; + + return (c); +} + +/* + * Return an nvlist representing the mappings of /dev/ppt* devices to physical + * devices. Of the form: + * + * /pci@0,0/... { + * dev: "/dev/ppt0" + * path: "/pci@0,0/..." + * vendor-id: "8086" + * device-id: "1528" + * subsystem-vendor-id: "8086" + * subsystem-id: "1528" + * revision-id: "1" + * label: "Intel Corporation ..." + * }, + * /pci@0,0/... + * + * The nvlist should be freed by the caller. + */ +nvlist_t * +ppt_list_assigned(void) +{ + di_node_t di_root = DI_NODE_NIL; + pcidb_hdl_t *db = NULL; + nvlist_t *nvl = NULL; + glob_t gl; + int err; + + bzero(&gl, sizeof (gl)); + + if ((di_root = di_init("/", DINFOCACHE)) == DI_NODE_NIL) + return (NULL); + + if ((db = pcidb_open(PCIDB_VERSION)) == NULL) { + err = errno; + goto out; + } + + if ((err = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0)) != 0) + goto out; + + if ((err = glob("/dev/ppt*", GLOB_KEEPSTAT | GLOB_ERR, + NULL, &gl)) != 0) { + err = (err == GLOB_NOMATCH) ? 0 : errno; + goto out; + } + + for (size_t i = 0; i < gl.gl_pathc; i++) { + char fspath[MAXPATHLEN]; + nvlist_t *info_nvl; + di_node_t di_node; + const char *path; + + if (!S_ISLNK(gl.gl_statv[i]->st_mode)) + continue; + + if (realpath(gl.gl_pathv[i], fspath) == NULL) { + err = errno; + goto out; + } + + path = fs_to_phys_path(fspath); + + /* + * path argument is treated as const. + */ + if ((di_node = di_lookup_node(di_root, (char *)path)) == NULL) { + err = errno; + goto out; + } + + if (!is_pci(di_node)) + continue; + + info_nvl = dev_getinfo(di_node, db, gl.gl_pathv[i], path); + + if (info_nvl == NULL) { + err = errno; + goto out; + } + + err = nvlist_add_nvlist(nvl, path, info_nvl); + nvlist_free(info_nvl); + + if (err) + goto out; + } + +out: + if (di_root != DI_NODE_NIL) + di_fini(di_root); + + pcidb_close(db); + globfree(&gl); + + if (err) { + nvlist_free(nvl); + errno = err; + return (NULL); + } + + return (nvl); +} + +/* + * Read in our list of potential PPT devices. A boot-module provided file + * explicitly over-rides anything delivered. + */ +static int +get_matches(list_t *listp) +{ + int err = 0; + FILE *fp; + + list_create(listp, sizeof (ppt_match_t), + offsetof(ppt_match_t, pm_list)); + + if ((fp = fopen("/system/boot/etc/ppt_matches", "r")) == NULL) { + if (errno != ENOENT) + return (errno); + + if ((fp = fopen("/etc/ppt_matches", "r")) == NULL) { + if (errno == ENOENT) + return (0); + return (errno); + } + } + + for (;;) { + char *line = NULL; + ppt_match_t *pm; + size_t cap = 0; + ssize_t read; + + if ((read = getline(&line, &cap, fp)) <= 0) { + free(line); + break; + } + + if (line[read - 1] == '\n') + line[read - 1] = '\0'; + + if ((pm = malloc(sizeof (*pm))) == NULL) { + err = errno; + free(line); + goto out; + } + + bzero(pm, sizeof (*pm)); + + if (sscanf(line, "pciex%4s,%4s", &pm->pm_vendor, + &pm->pm_device) == 2 || + sscanf(line, "pci%4s,%4s", &pm->pm_vendor, + &pm->pm_device) == 2 || + sscanf(line, "pciex%4s", &pm->pm_vendor) == 1 || + sscanf(line, "pci%4s", &pm->pm_vendor) == 1) { + list_insert_tail(listp, pm); + } else if (line[0] == '/') { + (void) strlcpy(pm->pm_path, line, sizeof (pm->pm_path)); + list_insert_tail(listp, pm); + } else { + /* + * Ignore any line we don't understand. + */ + free(pm); + } + + free(line); + } + +out: + (void) fclose(fp); + return (err); +} + +static boolean_t +match_ppt(list_t *matches, nvlist_t *nvl) +{ + char *vendor; + char *device; + char *path; + + if (nvlist_lookup_string(nvl, "path", &path) != 0 || + nvlist_lookup_string(nvl, "vendor-id", &vendor) != 0 || + nvlist_lookup_string(nvl, "device-id", &device) != 0) + return (B_FALSE); + + for (ppt_match_t *pm = list_head(matches); pm != NULL; + pm = list_next(matches, pm)) { + if (pm->pm_path[0] != '\0' && strcmp(pm->pm_path, path) == 0) + return (B_TRUE); + + if (pm->pm_vendor[0] != '\0' && + strcmp(pm->pm_vendor, vendor) == 0) { + if (pm->pm_device[0] == '\0') + return (B_TRUE); + if (strcmp(pm->pm_device, device) == 0) + return (B_TRUE); + } + } + + return (B_FALSE); +} + +static int +inspect_node(di_node_t di_node, void *arg) +{ + node_data_t *data = arg; + nvlist_t *info_nvl = NULL; + char *devname = NULL; + const char *driver; + char *path = NULL; + + if (!is_pci(di_node)) + return (DI_WALK_CONTINUE); + + driver = di_driver_name(di_node); + + if (driver != NULL && strcmp(driver, "ppt") == 0) { + if (asprintf(&devname, "/dev/ppt%d", + di_instance(di_node)) < 0) { + data->nd_err = errno; + goto out; + } + } + + if ((path = di_devfs_path(di_node)) == NULL) { + data->nd_err = ENOENT; + goto out; + } + + info_nvl = dev_getinfo(di_node, data->nd_db, devname, path); + + if (info_nvl == NULL) + goto out; + + if (devname == NULL && !match_ppt(&data->nd_matches, info_nvl)) + goto out; + + data->nd_err = nvlist_add_nvlist(data->nd_nvl, path, info_nvl); + +out: + free(path); + free(devname); + nvlist_free(info_nvl); + return (data->nd_err ? DI_WALK_TERMINATE : DI_WALK_CONTINUE); +} + +/* + * Like ppt_list_assigned() output, but includes all devices that could be used + * for passthrough, whether assigned or not. + */ +nvlist_t * +ppt_list(void) +{ + node_data_t nd = { NULL, }; + di_node_t di_root; + int err; + + if ((di_root = di_init("/", DINFOCACHE)) == DI_NODE_NIL) + return (NULL); + + if ((err = get_matches(&nd.nd_matches)) != 0) + goto out; + + if ((nd.nd_db = pcidb_open(PCIDB_VERSION)) == NULL) { + err = errno; + goto out; + } + + if ((err = nvlist_alloc(&nd.nd_nvl, NV_UNIQUE_NAME, 0)) != 0) + goto out; + + if ((err = di_walk_node(di_root, DI_WALK_CLDFIRST, + &nd, inspect_node)) != 0) + goto out; + + err = nd.nd_err; + +out: + pcidb_close(nd.nd_db); + + for (ppt_match_t *pm = list_head(&nd.nd_matches); pm != NULL; ) { + ppt_match_t *next = list_next(&nd.nd_matches, pm); + free(pm); + pm = next; + } + + if (di_root != DI_NODE_NIL) + di_fini(di_root); + + if (err) { + nvlist_free(nd.nd_nvl); + errno = err; + return (NULL); + } + + return (nd.nd_nvl); +} + +/* + * Given a physical path such as "/devices/pci0@0...", return the "/dev/pptX" + * that is bound to it, if any. The "/devices/" prefix is optional. The + * physical path may have the ":ppt" minor name suffix. + * + * Returns ENOENT if no such PPT device exists. + */ +int +ppt_devpath_to_dev(const char *inpath, char *buf, size_t buflen) +{ + char fspath[MAXPATHLEN] = ""; + nvpair_t *nvp = NULL; + const char *devpath; + int err = ENOENT; + nvlist_t *nvl; + + if (strlcat(fspath, inpath, sizeof (fspath)) >= sizeof (fspath)) + return (ENAMETOOLONG); + + devpath = fs_to_phys_path(fspath); + + if ((nvl = ppt_list_assigned()) == NULL) + return (errno); + + while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { + const char *name = nvpair_name(nvp); + char *ppt = NULL; + nvlist_t *props; + + (void) nvpair_value_nvlist(nvp, &props); + + if (strcmp(name, devpath) == 0) { + (void) nvlist_lookup_string(props, "dev", &ppt); + + err = 0; + + if (strlcpy(buf, ppt, buflen) >= buflen) + err = ENAMETOOLONG; + break; + } + } + + nvlist_free(nvl); + return (err); +} diff --git a/usr/src/lib/libppt/common/libppt.h b/usr/src/lib/libppt/common/libppt.h new file mode 100644 index 0000000000..efbf2c7b8b --- /dev/null +++ b/usr/src/lib/libppt/common/libppt.h @@ -0,0 +1,36 @@ +/* + * 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. + */ + +#ifndef _LIBPPT_H +#define _LIBPPT_H + +#include <sys/types.h> + +#include <libnvpair.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern int ppt_devpath_to_dev(const char *, char *, size_t); + +extern nvlist_t *ppt_list_assigned(void); + +extern nvlist_t *ppt_list(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBPPT_H */ diff --git a/usr/src/lib/libppt/common/llib-lppt b/usr/src/lib/libppt/common/llib-lppt new file mode 100644 index 0000000000..dadd992a31 --- /dev/null +++ b/usr/src/lib/libppt/common/llib-lppt @@ -0,0 +1,19 @@ +/* + * 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. + */ + +/* LINTLIBRARY */ +/* PROTOLIB1 */ + +#include <libppt.h> diff --git a/usr/src/lib/libppt/common/mapfile-vers b/usr/src/lib/libppt/common/mapfile-vers new file mode 100644 index 0000000000..d9d882874b --- /dev/null +++ b/usr/src/lib/libppt/common/mapfile-vers @@ -0,0 +1,40 @@ +# +# 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. +# + +# +# 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: + ppt_devpath_to_dev; + ppt_list_assigned; + ppt_list; + + local: + *; +}; diff --git a/usr/src/lib/libppt/i386/Makefile b/usr/src/lib/libppt/i386/Makefile new file mode 100644 index 0000000000..3f11e556d4 --- /dev/null +++ b/usr/src/lib/libppt/i386/Makefile @@ -0,0 +1,18 @@ +# +# 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. +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/libppt/sparc/Makefile b/usr/src/lib/libppt/sparc/Makefile new file mode 100644 index 0000000000..3f11e556d4 --- /dev/null +++ b/usr/src/lib/libppt/sparc/Makefile @@ -0,0 +1,18 @@ +# +# 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. +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/libppt/sparcv9/Makefile b/usr/src/lib/libppt/sparcv9/Makefile new file mode 100644 index 0000000000..5a304d7fe7 --- /dev/null +++ b/usr/src/lib/libppt/sparcv9/Makefile @@ -0,0 +1,19 @@ +# +# 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. +# + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) diff --git a/usr/src/lib/libvmmapi/common/mapfile-vers b/usr/src/lib/libvmmapi/common/mapfile-vers index a64231ad1c..397ebd7d59 100644 --- a/usr/src/lib/libvmmapi/common/mapfile-vers +++ b/usr/src/lib/libvmmapi/common/mapfile-vers @@ -61,6 +61,7 @@ SYMBOL_VERSION ILLUMOSprivate { vm_get_lowmem_size; vm_get_memflags; vm_get_memseg; + vm_get_pptdev_limits; vm_get_register; vm_get_register_set; vm_get_seg_desc; diff --git a/usr/src/lib/libvmmapi/common/vmmapi.c b/usr/src/lib/libvmmapi/common/vmmapi.c index 0b9b871081..ceac495746 100644 --- a/usr/src/lib/libvmmapi/common/vmmapi.c +++ b/usr/src/lib/libvmmapi/common/vmmapi.c @@ -995,6 +995,7 @@ vm_set_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, int val) return (ioctl(ctx->fd, VM_SET_CAPABILITY, &vmcap)); } +#ifdef __FreeBSD__ int vm_assign_pptdev(struct vmctx *ctx, int bus, int slot, int func) { @@ -1056,7 +1057,7 @@ vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, return (ioctl(ctx->fd, VM_PPTDEV_MSI, &pptmsi)); } -int +int vm_setup_pptdev_msix(struct vmctx *ctx, int vcpu, int bus, int slot, int func, int idx, uint64_t addr, uint64_t msg, uint32_t vector_control) { @@ -1075,6 +1076,103 @@ vm_setup_pptdev_msix(struct vmctx *ctx, int vcpu, int bus, int slot, int func, return ioctl(ctx->fd, VM_PPTDEV_MSIX, &pptmsix); } +int +vm_get_pptdev_limits(struct vmctx *ctx, int bus, int slot, int func, + int *msi_limit, int *msix_limit) +{ + struct vm_pptdev_limits pptlimits; + int error; + + bzero(&pptlimits, sizeof (pptlimits)); + pptlimits.bus = bus; + pptlimits.slot = slot; + pptlimits.func = func; + + error = ioctl(ctx->fd, VM_GET_PPTDEV_LIMITS, &pptlimits); + + *msi_limit = pptlimits.msi_limit; + *msix_limit = pptlimits.msix_limit; + + return (error); +} +#else /* __FreeBSD__ */ +int +vm_assign_pptdev(struct vmctx *ctx, int pptfd) +{ + struct vm_pptdev pptdev; + + pptdev.pptfd = pptfd; + return (ioctl(ctx->fd, VM_BIND_PPTDEV, &pptdev)); +} + +int +vm_unassign_pptdev(struct vmctx *ctx, int pptfd) +{ + struct vm_pptdev pptdev; + + pptdev.pptfd = pptfd; + return (ioctl(ctx->fd, VM_UNBIND_PPTDEV, &pptdev)); +} + +int +vm_map_pptdev_mmio(struct vmctx *ctx, int pptfd, vm_paddr_t gpa, size_t len, + vm_paddr_t hpa) +{ + struct vm_pptdev_mmio pptmmio; + + pptmmio.pptfd = pptfd; + pptmmio.gpa = gpa; + pptmmio.len = len; + pptmmio.hpa = hpa; + return (ioctl(ctx->fd, VM_MAP_PPTDEV_MMIO, &pptmmio)); +} + +int +vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int pptfd, uint64_t addr, + uint64_t msg, int numvec) +{ + struct vm_pptdev_msi pptmsi; + + pptmsi.vcpu = vcpu; + pptmsi.pptfd = pptfd; + pptmsi.msg = msg; + pptmsi.addr = addr; + pptmsi.numvec = numvec; + return (ioctl(ctx->fd, VM_PPTDEV_MSI, &pptmsi)); +} + +int +vm_setup_pptdev_msix(struct vmctx *ctx, int vcpu, int pptfd, int idx, + uint64_t addr, uint64_t msg, uint32_t vector_control) +{ + struct vm_pptdev_msix pptmsix; + + pptmsix.vcpu = vcpu; + pptmsix.pptfd = pptfd; + pptmsix.idx = idx; + pptmsix.msg = msg; + pptmsix.addr = addr; + pptmsix.vector_control = vector_control; + return ioctl(ctx->fd, VM_PPTDEV_MSIX, &pptmsix); +} + +int +vm_get_pptdev_limits(struct vmctx *ctx, int pptfd, int *msi_limit, + int *msix_limit) +{ + struct vm_pptdev_limits pptlimits; + int error; + + bzero(&pptlimits, sizeof (pptlimits)); + pptlimits.pptfd = pptfd; + error = ioctl(ctx->fd, VM_GET_PPTDEV_LIMITS, &pptlimits); + + *msi_limit = pptlimits.msi_limit; + *msix_limit = pptlimits.msix_limit; + return (error); +} +#endif /* __FreeBSD__ */ + uint64_t * vm_get_stats(struct vmctx *ctx, int vcpu, struct timeval *ret_tv, int *ret_entries) diff --git a/usr/src/lib/libvmmapi/common/vmmapi.h b/usr/src/lib/libvmmapi/common/vmmapi.h index a1507255cb..1b08a9cae5 100644 --- a/usr/src/lib/libvmmapi/common/vmmapi.h +++ b/usr/src/lib/libvmmapi/common/vmmapi.h @@ -177,6 +177,7 @@ int vm_get_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, int *retval); int vm_set_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, int val); +#ifdef __FreeBSD__ int vm_assign_pptdev(struct vmctx *ctx, int bus, int slot, int func); int vm_unassign_pptdev(struct vmctx *ctx, int bus, int slot, int func); int vm_map_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, @@ -186,6 +187,20 @@ int vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int vm_setup_pptdev_msix(struct vmctx *ctx, int vcpu, int bus, int slot, int func, int idx, uint64_t addr, uint64_t msg, uint32_t vector_control); +int vm_get_pptdev_limits(struct vmctx *ctx, int bus, int slot, int func, + int *msi_limit, int *msix_limit); +#else /* __FreeBSD__ */ +int vm_assign_pptdev(struct vmctx *ctx, int pptfd); +int vm_unassign_pptdev(struct vmctx *ctx, int pptfd); +int vm_map_pptdev_mmio(struct vmctx *ctx, int pptfd, vm_paddr_t gpa, + size_t len, vm_paddr_t hpa); +int vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int pptfd, + uint64_t addr, uint64_t msg, int numvec); +int vm_setup_pptdev_msix(struct vmctx *ctx, int vcpu, int pptfd, + int idx, uint64_t addr, uint64_t msg, uint32_t vector_control); +int vm_get_pptdev_limits(struct vmctx *ctx, int pptfd, int *msi_limit, + int *msix_limit); +#endif /* __FreeBSD__ */ int vm_get_intinfo(struct vmctx *ctx, int vcpu, uint64_t *i1, uint64_t *i2); int vm_set_intinfo(struct vmctx *ctx, int vcpu, uint64_t exit_intinfo); |