summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/Makefile1
-rw-r--r--usr/src/cmd/isainfo/isainfo.c12
-rw-r--r--usr/src/cmd/kvmstat/Makefile41
-rw-r--r--usr/src/cmd/kvmstat/kvmstat.c465
-rw-r--r--usr/src/common/dis/i386/dis_tables.c105
-rw-r--r--usr/src/common/elfcap/elfcap.c9
-rw-r--r--usr/src/common/elfcap/elfcap.h2
-rw-r--r--usr/src/lib/brand/kvm/Makefile51
-rw-r--r--usr/src/lib/brand/kvm/Makefile.kvm29
-rw-r--r--usr/src/lib/brand/kvm/zone/Makefile56
-rw-r--r--usr/src/lib/brand/kvm/zone/common.ksh68
-rw-r--r--usr/src/lib/brand/kvm/zone/config.xml108
-rwxr-xr-xusr/src/lib/brand/kvm/zone/kattach.ksh73
-rwxr-xr-xusr/src/lib/brand/kvm/zone/kdetach.ksh59
-rwxr-xr-xusr/src/lib/brand/kvm/zone/kinstall.ksh58
-rwxr-xr-xusr/src/lib/brand/kvm/zone/kuninstall.ksh69
-rwxr-xr-xusr/src/lib/brand/kvm/zone/pinstall.ksh71
-rw-r--r--usr/src/lib/brand/kvm/zone/platform.xml145
-rwxr-xr-xusr/src/lib/brand/kvm/zone/poststate.ksh43
-rwxr-xr-xusr/src/lib/brand/kvm/zone/prestate.ksh43
-rwxr-xr-xusr/src/lib/brand/kvm/zone/statechange.ksh136
-rw-r--r--usr/src/lib/libdtrace/common/dt_open.c2
-rw-r--r--usr/src/lib/libdtrace/i386/regs.d.in146
-rw-r--r--usr/src/uts/common/crypto/core/kcf_sched.c6
-rw-r--r--usr/src/uts/common/dtrace/dtrace.c16
-rw-r--r--usr/src/uts/common/os/clock_highres.c25
-rw-r--r--usr/src/uts/common/sys/auxv_386.h18
-rw-r--r--usr/src/uts/common/sys/dtrace.h1
-rw-r--r--usr/src/uts/common/sys/dtrace_impl.h7
-rw-r--r--usr/src/uts/i86pc/ml/locore.s22
-rw-r--r--usr/src/uts/i86pc/os/cpuid.c23
-rw-r--r--usr/src/uts/intel/dtrace/dtrace_asm.s37
-rw-r--r--usr/src/uts/intel/sys/x86_archext.h4
-rw-r--r--usr/src/uts/sparc/dtrace/dtrace_isa.c9
34 files changed, 1919 insertions, 41 deletions
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile
index b04c6c9aaa..f2344afb60 100644
--- a/usr/src/cmd/Makefile
+++ b/usr/src/cmd/Makefile
@@ -219,6 +219,7 @@ COMMON_SUBDIRS= \
krb5 \
ksh \
kstat \
+ kvmstat \
last \
lastcomm \
ldap \
diff --git a/usr/src/cmd/isainfo/isainfo.c b/usr/src/cmd/isainfo/isainfo.c
index b460ef289e..fb7ef19c97 100644
--- a/usr/src/cmd/isainfo/isainfo.c
+++ b/usr/src/cmd/isainfo/isainfo.c
@@ -23,7 +23,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
#include <sys/types.h>
#include <sys/systeminfo.h>
@@ -161,13 +163,13 @@ report_hwcap(int d, const char *isa)
int linecnt = 0;
for (p = strtok(buffer, " "); p; p = strtok(NULL, " ")) {
- if (linecnt == 0)
- linecnt = printf("\t");
- linecnt += printf("%s ", p);
- if (linecnt > 68) {
+ if (linecnt + strlen(p) > 68) {
(void) printf("\n");
linecnt = 0;
}
+ if (linecnt == 0)
+ linecnt = printf("\t");
+ linecnt += printf("%s ", p);
}
if (linecnt != 0)
(void) printf("\n");
diff --git a/usr/src/cmd/kvmstat/Makefile b/usr/src/cmd/kvmstat/Makefile
new file mode 100644
index 0000000000..2b3cce0eee
--- /dev/null
+++ b/usr/src/cmd/kvmstat/Makefile
@@ -0,0 +1,41 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2011, Joyent, Inc. All rights reserved.
+#
+
+PROG= kvmstat
+
+include ../Makefile.cmd
+
+LDLIBS += -lkstat
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTPROG)
+
+clean:
+ $(RM) $(PROG)
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/kvmstat/kvmstat.c b/usr/src/cmd/kvmstat/kvmstat.c
new file mode 100644
index 0000000000..3268b24ad4
--- /dev/null
+++ b/usr/src/cmd/kvmstat/kvmstat.c
@@ -0,0 +1,465 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
+#include <sys/kstat.h>
+#include <kstat.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <alloca.h>
+#include <signal.h>
+#include <sys/varargs.h>
+#include <sys/int_limits.h>
+
+#define KSTAT_FIELD_USEINSTANCE 0x01
+#define KSTAT_FIELD_NODELTA 0x02
+#define KSTAT_FIELD_FILLER 0x04
+
+typedef struct kstat_field {
+ char *ksf_header; /* header for field */
+ char *ksf_name; /* name of stat, if any */
+ int ksf_width; /* width for field in output line */
+ uint32_t ksf_flags; /* flags for this field, if any */
+ int ksf_hint; /* index hint for field in kstat */
+} kstat_field_t;
+
+typedef struct kstat_instance {
+ char ksi_name[KSTAT_STRLEN]; /* name of the underlying kstat */
+ int ksi_instance; /* instance identifer of this kstat */
+ kstat_t *ksi_ksp; /* pointer to the kstat */
+ uint64_t *ksi_data[2]; /* pointer to two generations of data */
+ hrtime_t ksi_snaptime[2]; /* hrtime for data generations */
+ int ksi_gen; /* current generation */
+ struct kstat_instance *ksi_next; /* next in instance list */
+} kstat_instance_t;
+
+const char *g_cmd = "kvmstat";
+
+static void
+fatal(char *fmt, ...)
+{
+ va_list ap;
+ int error = errno;
+
+ va_start(ap, fmt);
+
+ (void) fprintf(stderr, "%s: ", g_cmd);
+ /*LINTED*/
+ (void) vfprintf(stderr, fmt, ap);
+
+ if (fmt[strlen(fmt) - 1] != '\n')
+ (void) fprintf(stderr, ": %s\n", strerror(error));
+
+ exit(EXIT_FAILURE);
+}
+
+int
+kstat_field_hint(kstat_t *ksp, kstat_field_t *field)
+{
+ kstat_named_t *nm = KSTAT_NAMED_PTR(ksp);
+ int i;
+
+ assert(ksp->ks_type == KSTAT_TYPE_NAMED);
+
+ for (i = 0; i < ksp->ks_ndata; i++) {
+ if (strcmp(field->ksf_name, nm[i].name) == 0)
+ return (field->ksf_hint = i);
+ }
+
+ fatal("could not find field '%s' in %s:%d\n",
+ field->ksf_name, ksp->ks_name, ksp->ks_instance);
+
+ return (0);
+}
+
+int
+kstat_instances_compare(const void *lhs, const void *rhs)
+{
+ kstat_instance_t *l = *((kstat_instance_t **)lhs);
+ kstat_instance_t *r = *((kstat_instance_t **)rhs);
+ int rval;
+
+ if ((rval = strcmp(l->ksi_name, r->ksi_name)) != 0)
+ return (rval);
+
+ if (l->ksi_instance < r->ksi_instance)
+ return (-1);
+
+ if (l->ksi_instance > r->ksi_instance)
+ return (1);
+
+ return (0);
+}
+
+void
+kstat_instances_update(kstat_ctl_t *kcp, kstat_instance_t **head,
+ boolean_t (*interested)(kstat_t *))
+{
+ int ninstances = 0, i;
+ kstat_instance_t **sorted, *ksi, *next;
+ kstat_t *ksp;
+ kid_t kid;
+
+ if ((kid = kstat_chain_update(kcp)) == 0 && *head != NULL)
+ return;
+
+ if (kid == -1)
+ fatal("failed to update kstat chain");
+
+ for (ksi = *head; ksi != NULL; ksi = ksi->ksi_next)
+ ksi->ksi_ksp = NULL;
+
+ for (ksp = kcp->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
+ kstat_instance_t *last = NULL;
+
+ if (!interested(ksp))
+ continue;
+
+ /*
+ * Now look to see if we have this instance and name. (Yes,
+ * this is a linear search; we're assuming that this list is
+ * modest in size.)
+ */
+ for (ksi = *head; ksi != NULL; ksi = ksi->ksi_next) {
+ last = ksi;
+
+ if (ksi->ksi_instance != ksp->ks_instance)
+ continue;
+
+ if (strcmp(ksi->ksi_name, ksp->ks_name) != 0)
+ continue;
+
+ ksi->ksi_ksp = ksp;
+ ninstances++;
+ break;
+ }
+
+ if (ksi != NULL)
+ continue;
+
+ if ((ksi = malloc(sizeof (kstat_instance_t))) == NULL)
+ fatal("could not allocate memory for stat instance");
+
+ bzero(ksi, sizeof (kstat_instance_t));
+ (void) strlcpy(ksi->ksi_name, ksp->ks_name, KSTAT_STRLEN);
+ ksi->ksi_instance = ksp->ks_instance;
+ ksi->ksi_ksp = ksp;
+ ksi->ksi_next = NULL;
+
+ if (last == NULL) {
+ assert(*head == NULL);
+ *head = ksi;
+ } else {
+ last->ksi_next = ksi;
+ }
+
+ ninstances++;
+ }
+
+ /*
+ * Now we know how many instances we have; iterate back over them,
+ * pruning the stale ones and adding the active ones to a holding
+ * array in which to sort them.
+ */
+ sorted = (void *)alloca(ninstances * sizeof (kstat_instance_t *));
+ ninstances = 0;
+
+ for (ksi = *head; ksi != NULL; ksi = next) {
+ next = ksi->ksi_next;
+
+ if (ksi->ksi_ksp == NULL) {
+ free(ksi);
+ } else {
+ sorted[ninstances++] = ksi;
+ }
+ }
+
+ if (ninstances == 0) {
+ *head = NULL;
+ return;
+ }
+
+ qsort(sorted, ninstances, sizeof (kstat_instance_t *),
+ kstat_instances_compare);
+
+ *head = sorted[0];
+
+ for (i = 0; i < ninstances; i++) {
+ ksi = sorted[i];
+ ksi->ksi_next = i < ninstances - 1 ? sorted[i + 1] : NULL;
+ }
+}
+
+void
+kstat_instances_read(kstat_ctl_t *kcp, kstat_instance_t *instances,
+ kstat_field_t *fields)
+{
+ kstat_instance_t *ksi;
+ int i, nfields;
+
+ for (nfields = 0; fields[nfields].ksf_header != NULL; nfields++)
+ continue;
+
+ for (ksi = instances; ksi != NULL; ksi = ksi->ksi_next) {
+ kstat_t *ksp = ksi->ksi_ksp;
+
+ if (kstat_read(kcp, ksp, NULL) == -1) {
+ fatal("failed to read kstat %s:%d",
+ ksi->ksi_name, ksi->ksi_instance);
+ }
+
+ if (ksp->ks_type != KSTAT_TYPE_NAMED) {
+ fatal("%s:%d is not a named kstat", ksi->ksi_name,
+ ksi->ksi_instance);
+ }
+
+ if (ksi->ksi_data[0] == NULL) {
+ size_t size = nfields * sizeof (uint64_t) * 2;
+ uint64_t *data;
+
+ if ((data = malloc(size)) == NULL)
+ fatal("could not allocate memory");
+
+ bzero(data, size);
+ ksi->ksi_data[0] = data;
+ ksi->ksi_data[1] = &data[nfields];
+ }
+
+ for (i = 0; i < nfields; i++) {
+ kstat_named_t *nm = KSTAT_NAMED_PTR(ksp);
+ kstat_field_t *field = &fields[i];
+ int hint = field->ksf_hint;
+
+ if (field->ksf_name == NULL)
+ continue;
+
+ if (hint < 0 || hint >= ksp->ks_ndata ||
+ strcmp(field->ksf_name, nm[hint].name) != 0) {
+ hint = kstat_field_hint(ksp, field);
+ }
+
+ ksi->ksi_data[ksi->ksi_gen][i] = nm[hint].value.ui64;
+ }
+
+ ksi->ksi_snaptime[ksi->ksi_gen] = ksp->ks_snaptime;
+ ksi->ksi_gen ^= 1;
+ }
+}
+
+uint64_t
+kstat_instances_delta(kstat_instance_t *ksi, int i)
+{
+ int gen = ksi->ksi_gen;
+ uint64_t delta = ksi->ksi_data[gen ^ 1][i] - ksi->ksi_data[gen][i];
+ uint64_t tdelta = ksi->ksi_snaptime[gen ^ 1] - ksi->ksi_snaptime[gen];
+
+ return (((delta * (uint64_t)NANOSEC) + (tdelta / 2)) / tdelta);
+}
+
+void
+kstat_instances_print(kstat_instance_t *instances, kstat_field_t *fields,
+ boolean_t header)
+{
+ kstat_instance_t *ksi = instances;
+ int i, nfields;
+
+ for (nfields = 0; fields[nfields].ksf_header != NULL; nfields++)
+ continue;
+
+ if (header) {
+ for (i = 0; i < nfields; i++) {
+ (void) printf("%*s%c", fields[i].ksf_width,
+ fields[i].ksf_header, i < nfields - 1 ? ' ' : '\n');
+ }
+ }
+
+ for (ksi = instances; ksi != NULL; ksi = ksi->ksi_next) {
+ if (ksi->ksi_snaptime[1] == 0)
+ continue;
+
+ for (i = 0; i < nfields; i++) {
+ char trailer = i < nfields - 1 ? ' ' : '\n';
+
+ if (fields[i].ksf_flags & KSTAT_FIELD_FILLER) {
+ (void) printf("%*s%c", fields[i].ksf_width,
+ fields[i].ksf_header, trailer);
+ continue;
+ }
+
+ (void) printf("%*lld%c", fields[i].ksf_width,
+ fields[i].ksf_flags & KSTAT_FIELD_USEINSTANCE ?
+ ksi->ksi_instance :
+ fields[i].ksf_flags & KSTAT_FIELD_NODELTA ?
+ ksi->ksi_data[ksi->ksi_gen ^ 1][i] :
+ kstat_instances_delta(ksi, i), trailer);
+ }
+ }
+}
+
+boolean_t
+interested(kstat_t *ksp)
+{
+ const char *module = "kvm";
+ const char *class = "misc";
+ const char *name = "vcpu-";
+
+ if (strcmp(ksp->ks_module, module) != 0)
+ return (B_FALSE);
+
+ if (strcmp(ksp->ks_class, class) != 0)
+ return (B_FALSE);
+
+ if (strstr(ksp->ks_name, name) != ksp->ks_name)
+ return (B_FALSE);
+
+ return (B_TRUE);
+}
+
+/* BEGIN CSTYLED */
+char *g_usage = "Usage: kvmstat [interval [count]]\n"
+ "\n"
+ " Displays statistics for running kernel virtual machines, with one line\n"
+ " per virtual CPU. All statistics are reported as per-second rates.\n"
+ "\n"
+ " The columns are as follows:\n"
+ "\n"
+ " pid => identifier of process controlling the virtual CPU\n"
+ " vcpu => virtual CPU identifier relative to its virtual machine\n"
+ " exits => virtual machine exits for the virtual CPU\n"
+ " haltx => virtual machine exits due to the HLT instruction\n"
+ " irqx => virtual machine exits due to a pending external interrupt\n"
+ " irqwx => virtual machine exits due to an open interrupt window\n"
+ " iox => virtual machine exits due to an I/O instruction\n"
+ " mmiox => virtual machine exits due to memory mapped I/O \n"
+ " irqs => interrupts injected into the virtual CPU\n"
+ " emul => instructions emulated in the kernel\n"
+ " eptv => extended page table violations\n"
+ "\n";
+/* END CSTYLED */
+
+void
+usage()
+{
+ (void) fprintf(stderr, "%s", g_usage);
+ exit(EXIT_FAILURE);
+}
+
+/*ARGSUSED*/
+void
+intr(int sig)
+{}
+
+/*ARGSUSED*/
+int
+main(int argc, char **argv)
+{
+ kstat_ctl_t *kcp;
+ kstat_instance_t *instances = NULL;
+ int i = 0;
+ int interval = 1;
+ int count = INT32_MAX;
+ struct itimerval itimer;
+ struct sigaction act;
+ sigset_t set;
+ char *endp;
+
+ kstat_field_t fields[] = {
+ { "pid", "pid", 6, KSTAT_FIELD_NODELTA },
+ { "vcpu", NULL, 4, KSTAT_FIELD_USEINSTANCE },
+ { "|", NULL, 1, KSTAT_FIELD_FILLER },
+ { "exits", "exits", 6 },
+ { ":", NULL, 1, KSTAT_FIELD_FILLER },
+ { "haltx", "halt-exits", 6 },
+ { "irqx", "irq-exits", 6 },
+ { "irqwx", "irq-window-exits", 6 },
+ { "iox", "io-exits", 6 },
+ { "mmiox", "mmio-exits", 6 },
+ { "|", NULL, 1, KSTAT_FIELD_FILLER },
+ { "irqs", "irq-injections", 6 },
+ { "emul", "insn-emulation", 6 },
+ { "eptv", "pf-fixed", 6 },
+ { NULL }
+ };
+
+ if (argc > 1) {
+ interval = strtol(argv[1], &endp, 10);
+
+ if (*endp != '\0' || interval <= 0)
+ usage();
+ }
+
+ if (argc > 2) {
+ count = strtol(argv[2], &endp, 10);
+
+ if (*endp != '\0' || count <= 0)
+ usage();
+ }
+
+ if ((kcp = kstat_open()) == NULL)
+ fatal("could not open /dev/kstat");
+
+ (void) sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_handler = intr;
+ (void) sigaction(SIGALRM, &act, NULL);
+
+ (void) sigemptyset(&set);
+ (void) sigaddset(&set, SIGALRM);
+ (void) sigprocmask(SIG_BLOCK, &set, NULL);
+
+ bzero(&itimer, sizeof (itimer));
+ itimer.it_value.tv_sec = interval;
+ itimer.it_interval.tv_sec = interval;
+
+ if (setitimer(ITIMER_REAL, &itimer, NULL) != 0) {
+ fatal("could not set timer to %d second%s", interval,
+ interval == 1 ? "" : "s");
+ }
+
+ (void) sigemptyset(&set);
+
+ for (;;) {
+ kstat_instances_update(kcp, &instances, interested);
+ kstat_instances_read(kcp, instances, fields);
+
+ if (i++ > 0) {
+ kstat_instances_print(instances, fields,
+ instances != NULL && instances->ksi_next == NULL ?
+ (((i - 2) % 20) == 0) : B_TRUE);
+ }
+
+ if (i > count)
+ break;
+
+ (void) sigsuspend(&set);
+ }
+
+ /*NOTREACHED*/
+ return (0);
+}
diff --git a/usr/src/common/dis/i386/dis_tables.c b/usr/src/common/dis/i386/dis_tables.c
index 116191a462..5b3286c63e 100644
--- a/usr/src/common/dis/i386/dis_tables.c
+++ b/usr/src/common/dis/i386/dis_tables.c
@@ -21,6 +21,7 @@
*/
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
*/
/*
@@ -101,6 +102,7 @@ enum {
Mv,
Mw,
M, /* register or memory */
+ MG9, /* register or memory in group 9 (prefix optional) */
Mb, /* register or memory, always byte sized */
MO, /* memory only (no registers) */
PREF,
@@ -111,6 +113,7 @@ enum {
SEG,
MR,
RM,
+ RM_66r, /* RM, but with a required 0x66 prefix */
IA,
MA,
SD,
@@ -225,7 +228,9 @@ enum {
VEX_RRi, /* VEX mod_rm, imm8 -> mod_reg */
VEX_RM, /* VEX mod_reg -> mod_rm */
VEX_RRM, /* VEX VEX.vvvv, mod_reg -> mod_rm */
- VEX_RMX /* VEX VEX.vvvv, mod_rm -> mod_reg */
+ VEX_RMX, /* VEX VEX.vvvv, mod_rm -> mod_reg */
+ VMx, /* vmcall/vmlaunch/vmresume/vmxoff */
+ VMxo /* VMx instruction with optional prefix */
};
/*
@@ -493,7 +498,7 @@ const instable_t dis_op0F00[8] = {
*/
const instable_t dis_op0F01[8] = {
-/* [0] */ TNSZ("sgdt",MO,6), TNSZ("sidt",MONITOR_MWAIT,6), TNSZ("lgdt",XGETBV_XSETBV,6), TNSZ("lidt",MO,6),
+/* [0] */ TNSZ("sgdt",VMx,6), TNSZ("sidt",MONITOR_MWAIT,6), TNSZ("lgdt",XGETBV_XSETBV,6), TNSZ("lidt",MO,6),
/* [4] */ TNSZ("smsw",M,2), INVALID, TNSZ("lmsw",M,2), TNS("invlpg",SWAPGS),
};
@@ -525,15 +530,34 @@ const instable_t dis_op0FBA[8] = {
};
/*
- * Decode table for 0x0FC7 opcode
+ * Decode table for 0x0FC7 opcode (group 9)
*/
const instable_t dis_op0FC7[8] = {
/* [0] */ INVALID, TNS("cmpxchg8b",M), INVALID, INVALID,
-/* [4] */ INVALID, INVALID, INVALID, INVALID,
+/* [4] */ INVALID, INVALID, TNS("vmptrld",MG9), TNS("vmptrst",MG9),
};
+/*
+ * Decode table for 0x0FC7 opcode with 0x66 prefix
+ */
+
+const instable_t dis_op660FC7[8] = {
+
+/* [0] */ INVALID, INVALID, INVALID, INVALID,
+/* [4] */ INVALID, INVALID, TNS("vmclear",M), INVALID,
+};
+
+/*
+ * Decode table for 0x0FC7 opcode with 0xF3 prefix
+ */
+
+const instable_t dis_opF30FC7[8] = {
+
+/* [0] */ INVALID, INVALID, INVALID, INVALID,
+/* [4] */ INVALID, INVALID, TNS("vmxon",M), INVALID,
+};
/*
* Decode table for 0x0FC8 opcode -- 486 bswap instruction
@@ -1144,7 +1168,7 @@ const instable_t dis_op0F38[256] = {
/* [78] */ INVALID, INVALID, INVALID, INVALID,
/* [7C] */ INVALID, INVALID, INVALID, INVALID,
-/* [80] */ INVALID, INVALID, INVALID, INVALID,
+/* [80] */ TNSy("invept", RM_66r), TNSy("invvpid", RM_66r),INVALID, INVALID,
/* [84] */ INVALID, INVALID, INVALID, INVALID,
/* [88] */ INVALID, INVALID, INVALID, INVALID,
/* [8C] */ INVALID, INVALID, INVALID, INVALID,
@@ -1443,7 +1467,7 @@ const instable_t dis_op0F[16][16] = {
/* [10] */ TNSZ("movups",XMMO,16), TNSZ("movups",XMMOS,16),TNSZ("movlps",XMMO,8), TNSZ("movlps",XMMOS,8),
/* [14] */ TNSZ("unpcklps",XMMO,16),TNSZ("unpckhps",XMMO,16),TNSZ("movhps",XMMOM,8),TNSZ("movhps",XMMOMS,8),
/* [18] */ IND(dis_op0F18), INVALID, INVALID, INVALID,
-/* [1C] */ INVALID, INVALID, INVALID, INVALID,
+/* [1C] */ INVALID, INVALID, INVALID, TS("nop",Mw),
}, {
/* [20] */ TSy("mov",SREG), TSy("mov",SREG), TSy("mov",SREG), TSy("mov",SREG),
/* [24] */ TSx("mov",SREG), INVALID, TSx("mov",SREG), INVALID,
@@ -1472,7 +1496,7 @@ const instable_t dis_op0F[16][16] = {
}, {
/* [70] */ TNSZ("pshufw",MMOPM,8), TNS("psrXXX",MR), TNS("psrXXX",MR), TNS("psrXXX",MR),
/* [74] */ TNSZ("pcmpeqb",MMO,8), TNSZ("pcmpeqw",MMO,8), TNSZ("pcmpeqd",MMO,8), TNS("emms",NORM),
-/* [78] */ TNS("INVALID",XMMO), TNS("INVALID",XMMO), INVALID, INVALID,
+/* [78] */ TNSy("vmread",RM), TNSy("vmwrite",MR), INVALID, INVALID,
/* [7C] */ INVALID, INVALID, TNSZ("movd",MMOS,4), TNSZ("movq",MMOS,8),
}, {
/* [80] */ TNS("jo",D), TNS("jno",D), TNS("jb",D), TNS("jae",D),
@@ -2902,6 +2926,7 @@ dtrace_disx86(dis86_t *x, uint_t cpu_mode)
goto error;
#endif
switch (dp->it_adrmode) {
+ case RM_66r:
case XMM_66r:
case XMMM_66r:
if (opnd_size_prefix == 0) {
@@ -3051,6 +3076,42 @@ dtrace_disx86(dis86_t *x, uint_t cpu_mode)
}
break;
+ case MG9:
+ /*
+ * More horribleness: the group 9 (0xF0 0xC7) instructions are
+ * allowed an optional prefix of 0x66 or 0xF3. This is similar
+ * to the SIMD business described above, but with a different
+ * addressing mode (and an indirect table), so we deal with it
+ * separately (if similarly).
+ */
+
+ /*
+ * Calculate our offset in dis_op0FC7 (the group 9 table)
+ */
+ if ((uintptr_t)dp - (uintptr_t)dis_op0FC7 > sizeof (dis_op0FC7))
+ goto error;
+
+ off = ((uintptr_t)dp - (uintptr_t)dis_op0FC7) /
+ sizeof (instable_t);
+
+ /*
+ * Rewrite if this instruction used one of the magic prefixes.
+ */
+ if (rep_prefix) {
+ if (rep_prefix == 0xf3)
+ dp = (instable_t *)&dis_opF30FC7[off];
+ else
+ goto error;
+ rep_prefix = 0;
+ } else if (opnd_size_prefix) {
+ dp = (instable_t *)&dis_op660FC7[off];
+ opnd_size_prefix = 0;
+ if (opnd_size == SIZE16)
+ opnd_size = SIZE32;
+ }
+ break;
+
+
case MMOSH:
/*
* As with the "normal" SIMD instructions, the MMX
@@ -3448,6 +3509,7 @@ just_mem:
/* single memory or register operand */
case M:
+ case MG9:
wbit = LONG_OPND;
goto just_mem;
@@ -3456,6 +3518,34 @@ just_mem:
wbit = BYTE_OPND;
goto just_mem;
+ case VMx:
+ if (mode == 3) {
+ char *vminstr;
+
+ switch (r_m) {
+ case 1:
+ vminstr = "vmcall";
+ break;
+ case 2:
+ vminstr = "vmlaunch";
+ break;
+ case 3:
+ vminstr = "vmresume";
+ break;
+ case 4:
+ vminstr = "vmxoff";
+ break;
+ default:
+ goto error;
+ }
+
+#ifdef DIS_TEXT
+ (void) strncpy(x->d86_mnem, vminstr, OPLEN);
+#endif
+ NOMEM;
+ break;
+ }
+ /*FALLTHROUGH*/
case MONITOR_MWAIT:
if (mode == 3) {
if (r_m == 0) {
@@ -3594,6 +3684,7 @@ just_mem:
break;
case RM:
+ case RM_66r:
wbit = LONG_OPND;
STANDARD_MODRM(x, mode, reg, r_m, rex_prefix, wbit, 1);
break;
diff --git a/usr/src/common/elfcap/elfcap.c b/usr/src/common/elfcap/elfcap.c
index 0e1558468a..3cd9b4aedc 100644
--- a/usr/src/common/elfcap/elfcap.c
+++ b/usr/src/common/elfcap/elfcap.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
*/
/* LINTLIBRARY */
@@ -295,6 +296,14 @@ static const elfcap_desc_t hw1_386[ELFCAP_NUM_HW1_386] = {
{ /* 0x20000000 */
AV_386_AVX, STRDESC("AV_386_AVX"),
STRDESC("AVX"), STRDESC("avx"),
+ },
+ { /* 0x40000000 */
+ AV_386_VMX, STRDESC("AV_386_VMX"),
+ STRDESC("VMX"), STRDESC("vmx"),
+ },
+ { /* 0x80000000 */
+ AV_386_AMD_SVM, STRDESC("AV_386_AMD_SVM"),
+ STRDESC("AMD_SVM"), STRDESC("amd_svm"),
}
};
diff --git a/usr/src/common/elfcap/elfcap.h b/usr/src/common/elfcap/elfcap.h
index 9f0ef25f09..a1cbf8af9b 100644
--- a/usr/src/common/elfcap/elfcap.h
+++ b/usr/src/common/elfcap/elfcap.h
@@ -113,7 +113,7 @@ typedef enum {
*/
#define ELFCAP_NUM_SF1 3
#define ELFCAP_NUM_HW1_SPARC 17
-#define ELFCAP_NUM_HW1_386 30
+#define ELFCAP_NUM_HW1_386 32
/*
diff --git a/usr/src/lib/brand/kvm/Makefile b/usr/src/lib/brand/kvm/Makefile
new file mode 100644
index 0000000000..9e3a7b3eeb
--- /dev/null
+++ b/usr/src/lib/brand/kvm/Makefile
@@ -0,0 +1,51 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2010 Joyent, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+default: all
+
+include Makefile.kvm
+
+# Build everything in parallel; use .WAIT for dependencies
+.PARALLEL:
+
+SUBDIRS = zone
+MSGSUBDIRS = zone
+
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+lint := TARGET= lint
+_msg := TARGET= _msg
+
+.KEEP_STATE:
+
+all install clean clobber lint: $(SUBDIRS)
+
+_msg: $(MSGSUBDIRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
diff --git a/usr/src/lib/brand/kvm/Makefile.kvm b/usr/src/lib/brand/kvm/Makefile.kvm
new file mode 100644
index 0000000000..de1287189c
--- /dev/null
+++ b/usr/src/lib/brand/kvm/Makefile.kvm
@@ -0,0 +1,29 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2010 Joyent, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# include global definitions
+
+BRAND = kvm
+
+include $(SRC)/lib/brand/Makefile.brand
+
diff --git a/usr/src/lib/brand/kvm/zone/Makefile b/usr/src/lib/brand/kvm/zone/Makefile
new file mode 100644
index 0000000000..6a1055e36d
--- /dev/null
+++ b/usr/src/lib/brand/kvm/zone/Makefile
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2010, 2011 Joyent, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+PROGS = kattach kdetach kinstall kuninstall pinstall prestate \
+ poststate statechange
+XMLDOCS= config.xml platform.xml common.ksh
+USERFILES=
+TEMPLATES =
+CLOBBERFILES= $(ROOTPROGS) $(ROOTXMLDOCS) $(ROOTTEMPLATES)
+
+include $(SRC)/cmd/Makefile.cmd
+include ../Makefile.kvm
+
+.KEEP_STATE:
+
+all: $(PROGS)
+
+POFILES = $(PROGS:%=%.po) common.po
+POFILE = kvm.po
+
+$(POFILE): $(POFILES)
+ $(RM) $@
+ $(CAT) $(POFILES) > $@
+
+install: $(PROGS) $(XMLDOCS) $(ROOTPROGS) $(ROOTXMLDOCS) \
+ $(ROOTTEMPLATES) $(ETCUSER)
+
+lint:
+
+clean:
+ -$(RM) $(PROGS) $(POFILES) $(POFILE)
+
+include $(SRC)/cmd/Makefile.targ
diff --git a/usr/src/lib/brand/kvm/zone/common.ksh b/usr/src/lib/brand/kvm/zone/common.ksh
new file mode 100644
index 0000000000..61b674b370
--- /dev/null
+++ b/usr/src/lib/brand/kvm/zone/common.ksh
@@ -0,0 +1,68 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2011 Joyent, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+final_setup()
+{
+ # Convert quota to MB and use 10% of that value for the zone core dump
+ # dataset. The infrastructure zones can use 50%.
+ if [ ! -d $ZONEPATH/cores ]; then
+ case $ZONENAME in
+ adminui|assets|atropos|ca|capi|dhcpd|mapi|portal| \
+ pubapi|rabbitmq)
+ CORE_QUOTA=$((($ZQUOTA * 1000) / 2));;
+ *)
+ CORE_QUOTA=$((($ZQUOTA * 1000) / 10));;
+ esac
+ zfs create -o quota=${CORE_QUOTA}m -o compression=gzip \
+ $PDS_NAME/$bname/cores
+ fi
+
+ chmod 700 $ZONEPATH
+
+ egrep -s "netcfg:" $ZROOT/etc/passwd
+ if (( $? != 0 )); then
+ echo "netcfg:x:17:65:Network Configuration Admin:/:" \
+ >> $ZROOT/etc/passwd
+ echo "netcfg:*LK*:::::::" >> $ZROOT/etc/shadow
+ fi
+ egrep -s "netadm:" $ZROOT/etc/group
+ (( $? != 0 )) && echo "netadm::65:" >> $ZROOT/etc/group
+
+ # /etc/svc/profile needs to be a directory with some contents which we
+ # can get from the template. The early manifest import svc
+ # (lib/svc/method/manifest-import) copies some symlinks from the
+ # template's var/svc/profile dir and we need to make sure those are
+ # pointing at the right files and not left dangling.
+ ZPROFILE=$ZROOT/etc/svc/profile
+ if [ ! -d $ZPROFILE ]; then
+ mkdir $ZPROFILE
+ cp -p $ZROOT/var/svc/profile/generic_limited_net.xml $ZPROFILE
+ cp -p $ZROOT/var/svc/profile/inetd_generic.xml $ZPROFILE
+ cp -p $ZROOT/var/svc/profile/ns_dns.xml $ZPROFILE
+ cp -p $ZROOT/var/svc/profile/platform_none.xml $ZPROFILE
+ fi
+
+ touch $ZROOT/var/log/courier.log
+}
diff --git a/usr/src/lib/brand/kvm/zone/config.xml b/usr/src/lib/brand/kvm/zone/config.xml
new file mode 100644
index 0000000000..2008498e1b
--- /dev/null
+++ b/usr/src/lib/brand/kvm/zone/config.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0"?>
+
+<!--
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+ Copyright 2010,2011 Joyent, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ DO NOT EDIT THIS FILE.
+-->
+
+<!DOCTYPE brand PUBLIC "-//Joyent Inc//DTD Brands//EN"
+ "file:///usr/share/lib/xml/dtd/brand.dtd.1">
+
+<brand name="kvm">
+ <modname></modname>
+
+ <initname>/usr/sbin/qemu</initname>
+ <login_cmd>/usr/bin/login -z %Z %u</login_cmd>
+ <forcedlogin_cmd>/usr/bin/login -z %Z -f %u</forcedlogin_cmd>
+ <user_cmd>/usr/bin/getent passwd %u</user_cmd>
+
+ <install>/usr/lib/brand/kvm/kinstall -z %z -R %R</install>
+ <installopts>R:t:U:q:z:</installopts>
+ <boot></boot>
+ <halt></halt>
+ <verify_cfg></verify_cfg>
+ <verify_adm></verify_adm>
+ <postclone></postclone>
+ <postinstall>/usr/lib/brand/kvm/pinstall -z %z -R %R</postinstall>
+ <attach>/usr/lib/brand/kvm/kattach -z %z -R %R</attach>
+ <detach>/usr/lib/brand/kvm/kdetach -z %z -R %R</detach>
+ <clone></clone>
+ <uninstall>/usr/lib/brand/kvm/kuninstall -z %z -R %R</uninstall>
+ <prestatechange>/usr/lib/brand/kvm/prestate %z %R</prestatechange>
+ <poststatechange>/usr/lib/brand/kvm/poststate %z %R</poststatechange>
+
+ <privilege set="default" name="contract_event" />
+ <privilege set="default" name="contract_identity" />
+ <privilege set="default" name="contract_observer" />
+ <privilege set="default" name="file_chown" />
+ <privilege set="default" name="file_chown_self" />
+ <privilege set="default" name="file_dac_execute" />
+ <privilege set="default" name="file_dac_read" />
+ <privilege set="default" name="file_dac_search" />
+ <privilege set="default" name="file_dac_write" />
+ <privilege set="default" name="file_owner" />
+ <privilege set="default" name="file_setid" />
+ <privilege set="default" name="ipc_dac_read" />
+ <privilege set="default" name="ipc_dac_write" />
+ <privilege set="default" name="ipc_owner" />
+ <privilege set="default" name="net_bindmlp" />
+ <privilege set="default" name="net_icmpaccess" />
+ <privilege set="default" name="net_mac_aware" />
+ <privilege set="default" name="net_observability" />
+ <privilege set="default" name="net_privaddr" />
+ <privilege set="default" name="net_rawaccess" ip-type="exclusive" />
+ <privilege set="default" name="proc_chroot" />
+ <privilege set="default" name="sys_audit" />
+ <privilege set="default" name="proc_audit" />
+ <privilege set="default" name="proc_lock_memory" />
+ <privilege set="default" name="proc_owner" />
+ <privilege set="default" name="proc_setid" />
+ <privilege set="default" name="proc_taskid" />
+ <privilege set="default" name="sys_acct" />
+ <privilege set="default" name="sys_admin" />
+ <privilege set="default" name="sys_ip_config" ip-type="exclusive" />
+ <privilege set="default" name="sys_iptun_config" ip-type="exclusive" />
+ <privilege set="default" name="sys_mount" />
+ <privilege set="default" name="sys_nfs" />
+ <privilege set="default" name="sys_resource" />
+ <privilege set="default" name="sys_ppp_config" ip-type="exclusive" />
+
+ <privilege set="prohibited" name="dtrace_kernel" />
+ <privilege set="prohibited" name="proc_zone" />
+ <privilege set="prohibited" name="sys_config" />
+ <privilege set="prohibited" name="sys_devices" />
+ <privilege set="prohibited" name="sys_ip_config" ip-type="shared" />
+ <privilege set="prohibited" name="sys_linkdir" />
+ <privilege set="prohibited" name="sys_net_config" />
+ <privilege set="prohibited" name="sys_res_config" />
+ <privilege set="prohibited" name="sys_suser_compat" />
+ <privilege set="prohibited" name="xvm_control" />
+ <privilege set="prohibited" name="virt_manage" />
+ <privilege set="prohibited" name="sys_ppp_config" ip-type="shared" />
+
+ <privilege set="required" name="proc_exec" />
+ <privilege set="required" name="proc_fork" />
+ <privilege set="required" name="sys_ip_config" ip-type="exclusive" />
+ <privilege set="required" name="sys_mount" />
+</brand>
diff --git a/usr/src/lib/brand/kvm/zone/kattach.ksh b/usr/src/lib/brand/kvm/zone/kattach.ksh
new file mode 100755
index 0000000000..945b4d0873
--- /dev/null
+++ b/usr/src/lib/brand/kvm/zone/kattach.ksh
@@ -0,0 +1,73 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2011 Joyent, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+unset LD_LIBRARY_PATH
+PATH=/usr/bin:/usr/sbin
+export PATH
+
+. /usr/lib/brand/shared/common.ksh
+. /usr/lib/brand/kvm/common.ksh
+
+ZONENAME=""
+ZONEPATH=""
+# Default to 10GB diskset quota
+ZQUOTA=10
+
+while getopts "R:t:U:q:z:" opt
+do
+ case "$opt" in
+ R) ZONEPATH="$OPTARG";;
+ q) ZQUOTA="$OPTARG";;
+ z) ZONENAME="$OPTARG";;
+ *) printf "$m_usage\n"
+ exit $ZONE_SUBPROC_USAGE;;
+ esac
+done
+shift OPTIND-1
+
+if [[ -z $ZONEPATH || -z $ZONENAME ]]; then
+ print -u2 "Brand error: No zone path or name"
+ exit $ZONE_SUBPROC_USAGE
+fi
+
+# The dataset quota must be a number.
+case $ZQUOTA in *[!0-9]*)
+ print -u2 "Brand error: The quota $ZQUOTA is not a number"
+ exit $ZONE_SUBPROC_USAGE;;
+esac
+
+ZROOT=$ZONEPATH/root
+
+# Get the dataset of the parent directory of the zonepath.
+dname=${ZONEPATH%/*}
+bname=${ZONEPATH##*/}
+zfs list -H -t filesystem -o mountpoint,name | egrep "^$dname " | \
+ read mp PDS_NAME
+[ -z "$PDS_NAME" ] && \
+ print -u2 "Brand error: missing parent ZFS dataset for $dname"
+
+final_setup
+
+exit $ZONE_SUBPROC_OK
diff --git a/usr/src/lib/brand/kvm/zone/kdetach.ksh b/usr/src/lib/brand/kvm/zone/kdetach.ksh
new file mode 100755
index 0000000000..ea074022fe
--- /dev/null
+++ b/usr/src/lib/brand/kvm/zone/kdetach.ksh
@@ -0,0 +1,59 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2011 Joyent, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+unset LD_LIBRARY_PATH
+PATH=/usr/bin:/usr/sbin
+export PATH
+
+. /usr/lib/brand/shared/common.ksh
+. /usr/lib/brand/kvm/common.ksh
+
+ZONENAME=""
+ZONEPATH=""
+
+while getopts "R:t:U:z:" opt
+do
+ case "$opt" in
+ R) ZONEPATH="$OPTARG";;
+ z) ZONENAME="$OPTARG";;
+ *) printf "$m_usage\n"
+ exit $ZONE_SUBPROC_USAGE;;
+ esac
+done
+shift OPTIND-1
+
+if [[ -z $ZONEPATH || -z $ZONENAME ]]; then
+ print -u2 "Brand error: No zone path or name"
+ exit $ZONE_SUBPROC_USAGE
+fi
+
+#
+# We just need a brand hook so that we can bypass the mount checking
+# that zoneadm does. This is needed because we have the cores dataset
+# mounted under {zonepath}/root.
+#
+cp /etc/zones/${ZONENAME}.xml ${ZONEPATH}/SUNWdetached.xml
+
+exit $ZONE_SUBPROC_OK
diff --git a/usr/src/lib/brand/kvm/zone/kinstall.ksh b/usr/src/lib/brand/kvm/zone/kinstall.ksh
new file mode 100755
index 0000000000..00055a80fc
--- /dev/null
+++ b/usr/src/lib/brand/kvm/zone/kinstall.ksh
@@ -0,0 +1,58 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2010 Joyent, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+unset LD_LIBRARY_PATH
+PATH=/usr/bin:/usr/sbin
+export PATH
+
+. /usr/lib/brand/shared/common.ksh
+. /usr/lib/brand/kvm/common.ksh
+
+ZONENAME=""
+ZONEPATH=""
+# Default to 10GB diskset quota
+ZQUOTA=10
+
+while getopts "R:t:U:q:z:" opt
+do
+ case "$opt" in
+ R) ZONEPATH="$OPTARG";;
+ t) TMPLZONE="$OPTARG";;
+ # UUID is only used in the postinstall script
+ U) UUID="$OPTARG";;
+ q) ZQUOTA="$OPTARG";;
+ z) ZONENAME="$OPTARG";;
+ *) printf "$m_usage\n"
+ exit $ZONE_SUBPROC_USAGE;;
+ esac
+done
+shift OPTIND-1
+
+if [[ -z $ZONEPATH || -z $ZONENAME ]]; then
+ print -u2 "Brand error: No zone path or name"
+ exit $ZONE_SUBPROC_USAGE
+fi
+
+exit $ZONE_SUBPROC_OK
diff --git a/usr/src/lib/brand/kvm/zone/kuninstall.ksh b/usr/src/lib/brand/kvm/zone/kuninstall.ksh
new file mode 100755
index 0000000000..a8a6a51c77
--- /dev/null
+++ b/usr/src/lib/brand/kvm/zone/kuninstall.ksh
@@ -0,0 +1,69 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2010, 2011 Joyent, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+unset LD_LIBRARY_PATH
+PATH=/usr/bin:/usr/sbin
+export PATH
+
+. /usr/lib/brand/shared/common.ksh
+
+ZONENAME=""
+ZONEPATH=""
+
+while getopts "FR:z:" opt
+do
+ case "$opt" in
+ F) ;;
+ R) ZONEPATH="$OPTARG";;
+ z) ZONENAME="$OPTARG";;
+ *) printf "$m_usage\n"
+ exit $ZONE_SUBPROC_USAGE;;
+ esac
+done
+shift OPTIND-1
+
+if [[ -z $ZONEPATH || -z $ZONENAME ]]; then
+ print -u2 "Brand error: No zone path or name"
+ exit $ZONE_SUBPROC_USAGE
+fi
+
+# Get the dataset of the parent directory of the zonepath.
+dname=${ZONEPATH%/*}
+bname=${ZONEPATH##*/}
+zfs list -H -t filesystem -o mountpoint,name | egrep "^$dname " | \
+ read mp PDS_NAME
+if [[ -z "$PDS_NAME" ]]; then
+ print -u2 "Brand error: missing parent ZFS dataset for $dname"
+ exit $ZONE_SUBPROC_USAGE
+fi
+
+ORIGIN=`zfs get -H -ovalue origin $PDS_NAME/$bname`
+
+zfs destroy -r $PDS_NAME/$bname
+[ "$ORIGIN" != "-" ] && zfs destroy $ORIGIN
+
+rm -rf $ZONEPATH
+
+exit $ZONE_SUBPROC_OK
diff --git a/usr/src/lib/brand/kvm/zone/pinstall.ksh b/usr/src/lib/brand/kvm/zone/pinstall.ksh
new file mode 100755
index 0000000000..dd78bf6452
--- /dev/null
+++ b/usr/src/lib/brand/kvm/zone/pinstall.ksh
@@ -0,0 +1,71 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2010 Joyent, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+unset LD_LIBRARY_PATH
+PATH=/usr/bin:/usr/sbin
+export PATH
+
+. /usr/lib/brand/shared/common.ksh
+
+ZONENAME=""
+ZONEPATH=""
+# Default to 10GB diskset quota
+ZQUOTA=10
+
+while getopts "R:t:U:q:z:" opt
+do
+ case "$opt" in
+ R) ZONEPATH="$OPTARG";;
+ # template is only used in the postinstall script
+ t) TMPLZONE="$OPTARG";;
+ U) UUID="$OPTARG";;
+ # zquota is only used in the postinstall script
+ q) ZQUOTA="$OPTARG";;
+ z) ZONENAME="$OPTARG";;
+ *) printf "$m_usage\n"
+ exit $ZONE_SUBPROC_USAGE;;
+ esac
+done
+shift OPTIND-1
+
+if [[ -z $ZONENAME ]]; then
+ print -u2 "Brand error: No zone name"
+ exit $ZONE_SUBPROC_USAGE
+fi
+
+# If no UUID provided, then nothing to do.
+[[ -z $UUID ]] && exit $ZONE_SUBPROC_OK
+
+nawk -F: -v zonename=$ZONENAME -v uuid=$UUID '{
+ if ($1 != zonename) {
+ print $0
+ next
+ }
+ printf("%s:%s:%s:%s\n", $1, $2, $3, uuid);
+}' /etc/zones/index >/etc/zones/index.new
+cp /etc/zones/index.new /etc/zones/index
+rm -f /etc/zones/index.new
+
+exit $ZONE_SUBPROC_OK
diff --git a/usr/src/lib/brand/kvm/zone/platform.xml b/usr/src/lib/brand/kvm/zone/platform.xml
new file mode 100644
index 0000000000..905fcd79cf
--- /dev/null
+++ b/usr/src/lib/brand/kvm/zone/platform.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0"?>
+
+<!--
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+ Copyright 2010, 2011 Joyent, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ DO NOT EDIT THIS FILE.
+-->
+
+<!DOCTYPE platform PUBLIC "-//Joyent Inc//Zones Platform//EN"
+ "file:///usr/share/lib/xml/dtd/zone_platform.dtd.1">
+
+<platform name="kvm" allow-exclusive-ip="true">
+
+ <!-- Global filesystems to mount when booting the zone -->
+ <global_mount special="/dev" directory="/dev" type="dev"
+ opt="attrdir=%R/root/dev"/>
+
+ <global_mount special="/lib" directory="/lib"
+ opt="ro,nodevices" type="lofs" />
+ <global_mount special="/sbin" directory="/sbin"
+ opt="ro,nodevices" type="lofs" />
+ <global_mount special="/usr" directory="/usr"
+ opt="ro,nodevices" type="lofs" />
+
+ <!-- Local filesystems to mount when booting the zone -->
+ <mount special="/proc" directory="/proc" type="proc" />
+ <mount special="ctfs" directory="/system/contract" type="ctfs" />
+ <mount special="mnttab" directory="/etc/mnttab" type="mntfs" />
+ <mount special="objfs" directory="/system/object" type="objfs" />
+ <mount special="swap" directory="/etc/svc/volatile" type="tmpfs" />
+
+ <!-- Devices to create under /dev -->
+ <device match="arp" />
+ <device match="bpf" />
+ <device match="conslog" />
+ <device match="cpu/self/cpuid" />
+ <device match="crypto" />
+ <device match="cryptoadm" />
+ <device match="dsk" />
+ <device match="dtrace/*" />
+ <device match="dtrace/provider/*" />
+ <device match="fd" />
+ <device match="ipnet" />
+ <device match="kstat" />
+ <device match="lo0" />
+ <device match="lofictl" />
+ <device match="lofi" />
+ <device match="log" />
+ <device match="logindmux" />
+ <device match="nsmb" />
+ <device match="net/*" />
+ <device match="null" />
+ <device match="openprom" arch="sparc" />
+ <device match="poll" />
+ <device match="pool" />
+ <device match="ptmx" />
+ <device match="pts/*" />
+ <device match="random" />
+ <device match="rdsk" />
+ <device match="rlofi" />
+ <device match="rmt" />
+ <device match="sad/user" />
+ <device match="svvslo0" />
+ <device match="svvslo1" />
+ <device match="svvslo2" />
+ <device match="svvslo3" />
+ <device match="swap" />
+ <device match="sysevent" />
+ <device match="tcp" />
+ <device match="tcp6" />
+ <device match="term" />
+ <device match="ticlts" />
+ <device match="ticots" />
+ <device match="ticotsord" />
+ <device match="tty" />
+ <device match="udp" />
+ <device match="udp6" />
+ <device match="urandom" />
+ <device match="zero" />
+ <device match="zfs" />
+
+ <!-- Devices to create in exclusive IP zone only -->
+ <device match="dld" ip-type="exclusive" />
+ <device match="icmp" ip-type="exclusive" />
+ <device match="icmp6" ip-type="exclusive" />
+ <device match="ip" ip-type="exclusive" />
+ <device match="ip6" ip-type="exclusive" />
+ <device match="ipauth" ip-type="exclusive" />
+ <device match="ipf" ip-type="exclusive" />
+ <device match="ipl" ip-type="exclusive" />
+ <device match="iplookup" ip-type="exclusive" />
+ <device match="ipmpstub" ip-type="exclusive" />
+ <device match="ipnat" ip-type="exclusive" />
+ <device match="ipscan" ip-type="exclusive" />
+ <device match="ipsecah" ip-type="exclusive" />
+ <device match="ipsecesp" ip-type="exclusive" />
+ <device match="ipstate" ip-type="exclusive" />
+ <device match="ipsync" ip-type="exclusive" />
+ <device match="keysock" ip-type="exclusive" />
+ <device match="rawip" ip-type="exclusive" />
+ <device match="rawip6" ip-type="exclusive" />
+ <device match="rts" ip-type="exclusive" />
+ <device match="sad/admin" ip-type="exclusive" />
+ <device match="sctp" ip-type="exclusive" />
+ <device match="sctp6" ip-type="exclusive" />
+ <device match="spdsock" ip-type="exclusive" />
+ <device match="sppp" ip-type="exclusive" />
+ <device match="sppptun" ip-type="exclusive" />
+ <device match="vni" ip-type="exclusive" />
+
+ <!-- Renamed devices to create under /dev -->
+ <device match="zcons/%z/zoneconsole" name="zconsole" />
+
+ <!-- Symlinks to create under /dev -->
+ <symlink source="console" target="zconsole" />
+ <symlink source="dtremote" target="/dev/null" />
+ <symlink source="msglog" target="zconsole" />
+ <symlink source="stderr" target="./fd/2" />
+ <symlink source="stdin" target="./fd/0" />
+ <symlink source="stdout" target="./fd/1" />
+ <symlink source="syscon" target="zconsole" />
+ <symlink source="sysmsg" target="zconsole" />
+ <symlink source="systty" target="zconsole" />
+
+</platform>
diff --git a/usr/src/lib/brand/kvm/zone/poststate.ksh b/usr/src/lib/brand/kvm/zone/poststate.ksh
new file mode 100755
index 0000000000..3770d3d5bc
--- /dev/null
+++ b/usr/src/lib/brand/kvm/zone/poststate.ksh
@@ -0,0 +1,43 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2010, 2011 Joyent, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+unset LD_LIBRARY_PATH
+PATH=/usr/bin:/usr/sbin
+export PATH
+
+if [[ -n $_ZONEADMD_brand_debug ]]; then
+ logfile=/var/log/zone_bh.$1
+ date >>$logfile
+ echo "zone $1 post-state-change $3 $4" >>$logfile
+ ksh -x /usr/lib/brand/kvm/statechange "post" $1 $2 $3 $4 \
+ >>$logfile 2>&1
+ res=$?
+ echo "zone $1 post-state-change result $?" >>$logfile
+else
+ /usr/lib/brand/kvm/statechange "post" $1 $2 $3 $4
+ res=$?
+fi
+
+exit $res
diff --git a/usr/src/lib/brand/kvm/zone/prestate.ksh b/usr/src/lib/brand/kvm/zone/prestate.ksh
new file mode 100755
index 0000000000..cc1ca9052f
--- /dev/null
+++ b/usr/src/lib/brand/kvm/zone/prestate.ksh
@@ -0,0 +1,43 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2010, 2011 Joyent, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+unset LD_LIBRARY_PATH
+PATH=/usr/bin:/usr/sbin
+export PATH
+
+if [[ -n $_ZONEADMD_brand_debug ]]; then
+ logfile=/var/log/zone_bh.$1
+ date >>$logfile
+ echo "zone $1 pre-state-change $3 $4" >>$logfile
+ ksh -x /usr/lib/brand/kvm/statechange "pre" $1 $2 $3 $4 \
+ >>$logfile 2>&1
+ res=$?
+ echo "zone $1 pre-state-change result $?" >>$logfile
+else
+ /usr/lib/brand/kvm/statechange "pre" $1 $2 $3 $4
+ res=$?
+fi
+
+exit $res
diff --git a/usr/src/lib/brand/kvm/zone/statechange.ksh b/usr/src/lib/brand/kvm/zone/statechange.ksh
new file mode 100755
index 0000000000..2b4da6f6dd
--- /dev/null
+++ b/usr/src/lib/brand/kvm/zone/statechange.ksh
@@ -0,0 +1,136 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2010, 2011 Joyent, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+unset LD_LIBRARY_PATH
+PATH=/usr/bin:/usr/sbin
+export PATH
+
+. /lib/sdc/config.sh
+
+# subcommand:
+# pre
+# post
+
+# state
+# ZONE_STATE_CONFIGURED 0 (script will never see this)
+# ZONE_STATE_INCOMPLETE 1 (script will never see this)
+# ZONE_STATE_INSTALLED 2
+# ZONE_STATE_READY 3
+# ZONE_STATE_RUNNING 4
+# ZONE_STATE_SHUTTING_DOWN 5
+# ZONE_STATE_DOWN 6
+# ZONE_STATE_MOUNTED 7
+
+# cmd
+#
+# ready 0
+# boot 1
+# halt 4
+
+subcommand=$1
+ZONENAME=$2
+ZONEPATH=$3
+state=$4
+cmd=$5
+
+LOCKFILE=/etc/dladm/zone.lck
+KVMLOG=/tmp/kvm.log=
+
+#
+# Create a lock file which we use to serialize datalink operations across zones.
+#
+lock_file()
+{
+ while true; do
+ if (set -o noclobber; echo "$$" >$LOCKFILE) 2>/dev/null; then
+ trap 'rm -f $LOCKFILE; exit $?' INT TERM EXIT
+ break;
+ else
+ sleep 1
+ fi
+ done
+}
+
+unlock_file()
+{
+ rm -f $LOCKFILE
+ trap - INT TERM EXIT
+}
+
+#
+# Set up the vnic(s) for the zone.
+#
+setup_net()
+{
+ touch $ZONEPATH/netsetup
+}
+
+#
+# We're readying the zone. Make sure the per-zone writable
+# directories exist so that we can lofs mount them. We do this here,
+# instead of in the install script, since this list has evolved and
+# there are already zones out there in the installed state.
+#
+setup_fs()
+{
+ uname -v > $ZONEPATH/lastbooted
+}
+
+#
+# We're halting the zone, perform network cleanup.
+#
+cleanup_net()
+{
+ # Cleanup any flows that were setup.
+ for nic in $_ZONECFG_net_resources
+ do
+ lock_file
+
+ flowadm remove-flow -t -z $ZONENAME -l $nic
+ if (( $? != 0 )); then
+ echo "error removing flows for $nic"
+ logger -p daemon.err "zone $ZONENAME " \
+ "error removing flows for $nic"
+ fi
+
+ unlock_file
+ done
+}
+
+#
+# Main
+#
+
+# Load sysinfo variables with SYSINFO_ prefix
+load_sdc_sysinfo
+# Load config variables with CONFIG_ prefix, and sets the headnode variable
+load_sdc_config
+
+echo "statechange $subcommand $cmd" >>/tmp/kvm.log
+[[ "$subcommand" == "pre" && $cmd == 0 ]] && setup_fs
+[[ "$subcommand" == "pre" && $cmd == 4 ]] && cleanup_net
+[[ "$subcommand" == "post" && $cmd == 0 ]] && setup_net
+
+exit 0
diff --git a/usr/src/lib/libdtrace/common/dt_open.c b/usr/src/lib/libdtrace/common/dt_open.c
index bd60702e49..d5259c9a2e 100644
--- a/usr/src/lib/libdtrace/common/dt_open.c
+++ b/usr/src/lib/libdtrace/common/dt_open.c
@@ -403,6 +403,8 @@ static const dt_ident_t _dtrace_globals[] = {
&dt_idops_type, "uint32_t" },
{ "usym", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN,
DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
+{ "vmregs", DT_IDENT_ARRAY, 0, DIF_VAR_VMREGS, DT_ATTR_STABCMN, DT_VERS_1_7,
+ &dt_idops_regs, NULL },
{ "vtimestamp", DT_IDENT_SCALAR, 0, DIF_VAR_VTIMESTAMP,
DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_type, "uint64_t" },
diff --git a/usr/src/lib/libdtrace/i386/regs.d.in b/usr/src/lib/libdtrace/i386/regs.d.in
index 3328f33515..30a6f0616b 100644
--- a/usr/src/lib/libdtrace/i386/regs.d.in
+++ b/usr/src/lib/libdtrace/i386/regs.d.in
@@ -115,3 +115,149 @@ inline int R_R14 = @REG_R14@;
inline int R_R15 = @REG_R15@;
#pragma D binding "1.0" R_R15
+enum vmregs_vmx {
+ VMX_VIRTUAL_PROCESSOR_ID = 0x00000000,
+ VMX_GUEST_ES_SELECTOR = 0x00000800,
+ VMX_GUEST_CS_SELECTOR = 0x00000802,
+ VMX_GUEST_SS_SELECTOR = 0x00000804,
+ VMX_GUEST_DS_SELECTOR = 0x00000806,
+ VMX_GUEST_FS_SELECTOR = 0x00000808,
+ VMX_GUEST_GS_SELECTOR = 0x0000080a,
+ VMX_GUEST_LDTR_SELECTOR = 0x0000080c,
+ VMX_GUEST_TR_SELECTOR = 0x0000080e,
+ VMX_HOST_ES_SELECTOR = 0x00000c00,
+ VMX_HOST_CS_SELECTOR = 0x00000c02,
+ VMX_HOST_SS_SELECTOR = 0x00000c04,
+ VMX_HOST_DS_SELECTOR = 0x00000c06,
+ VMX_HOST_FS_SELECTOR = 0x00000c08,
+ VMX_HOST_GS_SELECTOR = 0x00000c0a,
+ VMX_HOST_TR_SELECTOR = 0x00000c0c,
+ VMX_IO_BITMAP_A = 0x00002000,
+ VMX_IO_BITMAP_A_HIGH = 0x00002001,
+ VMX_IO_BITMAP_B = 0x00002002,
+ VMX_IO_BITMAP_B_HIGH = 0x00002003,
+ VMX_MSR_BITMAP = 0x00002004,
+ VMX_MSR_BITMAP_HIGH = 0x00002005,
+ VMX_VM_EXIT_MSR_STORE_ADDR = 0x00002006,
+ VMX_VM_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007,
+ VMX_VM_EXIT_MSR_LOAD_ADDR = 0x00002008,
+ VMX_VM_EXIT_MSR_LOAD_ADDR_HIGH = 0x00002009,
+ VMX_VM_ENTRY_MSR_LOAD_ADDR = 0x0000200a,
+ VMX_VM_ENTRY_MSR_LOAD_ADDR_HIGH = 0x0000200b,
+ VMX_TSC_OFFSET = 0x00002010,
+ VMX_TSC_OFFSET_HIGH = 0x00002011,
+ VMX_VIRTUAL_APIC_PAGE_ADDR = 0x00002012,
+ VMX_VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013,
+ VMX_APIC_ACCESS_ADDR = 0x00002014,
+ VMX_APIC_ACCESS_ADDR_HIGH = 0x00002015,
+ VMX_EPT_POINTER = 0x0000201a,
+ VMX_EPT_POINTER_HIGH = 0x0000201b,
+ VMX_GUEST_PHYSICAL_ADDRESS = 0x00002400,
+ VMX_GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401,
+ VMX_VMCS_LINK_POINTER = 0x00002800,
+ VMX_VMCS_LINK_POINTER_HIGH = 0x00002801,
+ VMX_GUEST_IA32_DEBUGCTL = 0x00002802,
+ VMX_GUEST_IA32_DEBUGCTL_HIGH = 0x00002803,
+ VMX_GUEST_IA32_PAT = 0x00002804,
+ VMX_GUEST_IA32_PAT_HIGH = 0x00002805,
+ VMX_GUEST_PDPTR0 = 0x0000280a,
+ VMX_GUEST_PDPTR0_HIGH = 0x0000280b,
+ VMX_GUEST_PDPTR1 = 0x0000280c,
+ VMX_GUEST_PDPTR1_HIGH = 0x0000280d,
+ VMX_GUEST_PDPTR2 = 0x0000280e,
+ VMX_GUEST_PDPTR2_HIGH = 0x0000280f,
+ VMX_GUEST_PDPTR3 = 0x00002810,
+ VMX_GUEST_PDPTR3_HIGH = 0x00002811,
+ VMX_HOST_IA32_PAT = 0x00002c00,
+ VMX_HOST_IA32_PAT_HIGH = 0x00002c01,
+ VMX_PIN_BASED_VM_EXEC_CONTROL = 0x00004000,
+ VMX_CPU_BASED_VM_EXEC_CONTROL = 0x00004002,
+ VMX_EXCEPTION_BITMAP = 0x00004004,
+ VMX_PAGE_FAULT_ERROR_CODE_MASK = 0x00004006,
+ VMX_PAGE_FAULT_ERROR_CODE_MATCH = 0x00004008,
+ VMX_CR3_TARGET_COUNT = 0x0000400a,
+ VMX_VM_EXIT_CONTROLS = 0x0000400c,
+ VMX_VM_EXIT_MSR_STORE_COUNT = 0x0000400e,
+ VMX_VM_EXIT_MSR_LOAD_COUNT = 0x00004010,
+ VMX_VM_ENTRY_CONTROLS = 0x00004012,
+ VMX_VM_ENTRY_MSR_LOAD_COUNT = 0x00004014,
+ VMX_VM_ENTRY_INTR_INFO_FIELD = 0x00004016,
+ VMX_VM_ENTRY_EXCEPTION_ERROR_CODE = 0x00004018,
+ VMX_VM_ENTRY_INSTRUCTION_LEN = 0x0000401a,
+ VMX_TPR_THRESHOLD = 0x0000401c,
+ VMX_SECONDARY_VM_EXEC_CONTROL = 0x0000401e,
+ VMX_PLE_GAP = 0x00004020,
+ VMX_PLE_WINDOW = 0x00004022,
+ VMX_VM_INSTRUCTION_ERROR = 0x00004400,
+ VMX_VM_EXIT_REASON = 0x00004402,
+ VMX_VM_EXIT_INTR_INFO = 0x00004404,
+ VMX_VM_EXIT_INTR_ERROR_CODE = 0x00004406,
+ VMX_IDT_VECTORING_INFO_FIELD = 0x00004408,
+ VMX_IDT_VECTORING_ERROR_CODE = 0x0000440a,
+ VMX_VM_EXIT_INSTRUCTION_LEN = 0x0000440c,
+ VMX_VMX_INSTRUCTION_INFO = 0x0000440e,
+ VMX_GUEST_ES_LIMIT = 0x00004800,
+ VMX_GUEST_CS_LIMIT = 0x00004802,
+ VMX_GUEST_SS_LIMIT = 0x00004804,
+ VMX_GUEST_DS_LIMIT = 0x00004806,
+ VMX_GUEST_FS_LIMIT = 0x00004808,
+ VMX_GUEST_GS_LIMIT = 0x0000480a,
+ VMX_GUEST_LDTR_LIMIT = 0x0000480c,
+ VMX_GUEST_TR_LIMIT = 0x0000480e,
+ VMX_GUEST_GDTR_LIMIT = 0x00004810,
+ VMX_GUEST_IDTR_LIMIT = 0x00004812,
+ VMX_GUEST_ES_AR_BYTES = 0x00004814,
+ VMX_GUEST_CS_AR_BYTES = 0x00004816,
+ VMX_GUEST_SS_AR_BYTES = 0x00004818,
+ VMX_GUEST_DS_AR_BYTES = 0x0000481a,
+ VMX_GUEST_FS_AR_BYTES = 0x0000481c,
+ VMX_GUEST_GS_AR_BYTES = 0x0000481e,
+ VMX_GUEST_LDTR_AR_BYTES = 0x00004820,
+ VMX_GUEST_TR_AR_BYTES = 0x00004822,
+ VMX_GUEST_INTERRUPTIBILITY_INFO = 0x00004824,
+ VMX_GUEST_ACTIVITY_STATE = 0X00004826,
+ VMX_GUEST_SYSENTER_CS = 0x0000482A,
+ VMX_HOST_IA32_SYSENTER_CS = 0x00004c00,
+ VMX_CR0_GUEST_HOST_MASK = 0x00006000,
+ VMX_CR4_GUEST_HOST_MASK = 0x00006002,
+ VMX_CR0_READ_SHADOW = 0x00006004,
+ VMX_CR4_READ_SHADOW = 0x00006006,
+ VMX_CR3_TARGET_VALUE0 = 0x00006008,
+ VMX_CR3_TARGET_VALUE1 = 0x0000600a,
+ VMX_CR3_TARGET_VALUE2 = 0x0000600c,
+ VMX_CR3_TARGET_VALUE3 = 0x0000600e,
+ VMX_EXIT_QUALIFICATION = 0x00006400,
+ VMX_GUEST_LINEAR_ADDRESS = 0x0000640a,
+ VMX_GUEST_CR0 = 0x00006800,
+ VMX_GUEST_CR3 = 0x00006802,
+ VMX_GUEST_CR4 = 0x00006804,
+ VMX_GUEST_ES_BASE = 0x00006806,
+ VMX_GUEST_CS_BASE = 0x00006808,
+ VMX_GUEST_SS_BASE = 0x0000680a,
+ VMX_GUEST_DS_BASE = 0x0000680c,
+ VMX_GUEST_FS_BASE = 0x0000680e,
+ VMX_GUEST_GS_BASE = 0x00006810,
+ VMX_GUEST_LDTR_BASE = 0x00006812,
+ VMX_GUEST_TR_BASE = 0x00006814,
+ VMX_GUEST_GDTR_BASE = 0x00006816,
+ VMX_GUEST_IDTR_BASE = 0x00006818,
+ VMX_GUEST_DR7 = 0x0000681a,
+ VMX_GUEST_RSP = 0x0000681c,
+ VMX_GUEST_RIP = 0x0000681e,
+ VMX_GUEST_RFLAGS = 0x00006820,
+ VMX_GUEST_PENDING_DBG_EXCEPTIONS = 0x00006822,
+ VMX_GUEST_SYSENTER_ESP = 0x00006824,
+ VMX_GUEST_SYSENTER_EIP = 0x00006826,
+ VMX_HOST_CR0 = 0x00006c00,
+ VMX_HOST_CR3 = 0x00006c02,
+ VMX_HOST_CR4 = 0x00006c04,
+ VMX_HOST_FS_BASE = 0x00006c06,
+ VMX_HOST_GS_BASE = 0x00006c08,
+ VMX_HOST_TR_BASE = 0x00006c0a,
+ VMX_HOST_GDTR_BASE = 0x00006c0c,
+ VMX_HOST_IDTR_BASE = 0x00006c0e,
+ VMX_HOST_IA32_SYSENTER_ESP = 0x00006c10,
+ VMX_HOST_IA32_SYSENTER_EIP = 0x00006c12,
+ VMX_HOST_RSP = 0x00006c14,
+ VMX_HOST_RIP = 0x00006c16
+};
diff --git a/usr/src/uts/common/crypto/core/kcf_sched.c b/usr/src/uts/common/crypto/core/kcf_sched.c
index f461fe048c..8b2760b237 100644
--- a/usr/src/uts/common/crypto/core/kcf_sched.c
+++ b/usr/src/uts/common/crypto/core/kcf_sched.c
@@ -1027,9 +1027,9 @@ kcfpool_svc(void *arg)
case 0:
case -1:
/*
- * Woke up with no work to do. Check
- * if this thread should exit. We keep
- * at least kcf_minthreads.
+ * Woke up with no work to do. Check if we
+ * should lwp_exit() (which won't return). We
+ * keep at least kcf_minthreads.
*/
if (kcfpool->kp_threads > kcf_minthreads) {
KCF_ATOMIC_DECR(kcfpool->kp_threads);
diff --git a/usr/src/uts/common/dtrace/dtrace.c b/usr/src/uts/common/dtrace/dtrace.c
index 10e66021f9..5c73deb95b 100644
--- a/usr/src/uts/common/dtrace/dtrace.c
+++ b/usr/src/uts/common/dtrace/dtrace.c
@@ -2757,6 +2757,22 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v,
return (dtrace_getreg(lwp->lwp_regs, ndx));
}
+ case DIF_VAR_VMREGS: {
+ uint64_t rval;
+
+ if (!dtrace_priv_kernel(state))
+ return (0);
+
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
+
+ rval = dtrace_getvmreg(ndx,
+ &cpu_core[CPU->cpu_id].cpuc_dtrace_flags);
+
+ DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
+
+ return (rval);
+ }
+
case DIF_VAR_CURTHREAD:
if (!dtrace_priv_kernel(state))
return (0);
diff --git a/usr/src/uts/common/os/clock_highres.c b/usr/src/uts/common/os/clock_highres.c
index e097f355ec..03dd1b4371 100644
--- a/usr/src/uts/common/os/clock_highres.c
+++ b/usr/src/uts/common/os/clock_highres.c
@@ -24,7 +24,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2011, Joyent Inc. All rights reserved.
+ */
#include <sys/timer.h>
#include <sys/systm.h>
@@ -112,6 +114,25 @@ clock_highres_timer_settime(itimer_t *it, int flags,
cyctime.cyt_when = ts2hrt(&when->it_value);
cyctime.cyt_interval = ts2hrt(&when->it_interval);
+ if (cyctime.cyt_when != 0 && cyctime.cyt_interval == 0 &&
+ it->it_itime.it_interval.tv_sec == 0 &&
+ it->it_itime.it_interval.tv_nsec == 0 &&
+ (cyc = *cycp) != CYCLIC_NONE) {
+ /*
+ * If our existing timer is a one-shot and our new timer is a
+ * one-shot, we'll save ourselves a world of grief and just
+ * reprogram the cyclic.
+ */
+ it->it_itime = *when;
+
+ if (!(flags & TIMER_ABSTIME))
+ cyctime.cyt_when += gethrtime();
+
+ hrt2ts(cyctime.cyt_when, &it->it_itime.it_value);
+ cyclic_reprogram(cyc, cyctime.cyt_when);
+ return (0);
+ }
+
mutex_enter(&cpu_lock);
if ((cyc = *cycp) != CYCLIC_NONE) {
cyclic_remove(cyc);
@@ -185,8 +206,6 @@ clock_highres_timer_settime(itimer_t *it, int flags,
if (cyctime.cyt_when != 0)
*cycp = cyc = cyclic_add(&hdlr, &cyctime);
- else
- *cycp = cyc = CYCLIC_NONE;
/*
* Now that we have the cyclic created, we need to bind it to our
diff --git a/usr/src/uts/common/sys/auxv_386.h b/usr/src/uts/common/sys/auxv_386.h
index f9b4867f10..6692daf6e6 100644
--- a/usr/src/uts/common/sys/auxv_386.h
+++ b/usr/src/uts/common/sys/auxv_386.h
@@ -69,16 +69,18 @@ extern "C" {
#define AV_386_PCLMULQDQ 0x8000000 /* Intel PCLMULQDQ insn */
#define AV_386_XSAVE 0x10000000 /* Intel XSAVE/XRSTOR insns */
#define AV_386_AVX 0x20000000 /* Intel AVX insns */
+#define AV_386_VMX 0x40000000 /* Intel VMX support */
+#define AV_386_AMD_SVM 0x20000000 /* AMD SVM support */
#define FMT_AV_386 \
- "\20" \
- "\36avx\35xsave" \
- "\34pclmulqdq\33aes" \
- "\32movbe\31sse4.2" \
- "\30sse4.1\27ssse3\26amd_lzcnt\25popcnt" \
- "\24amd_sse4a\23tscp\22ahf\21cx16" \
- "\17sse3\15sse2\14sse\13fxsr\12amd3dx\11amd3d" \
- "\10amdmmx\7mmx\6cmov\5amdsysc\4sep\3cx8\2tsc\1fpu"
+ "\020" \
+ "\040svm\037vmx\036avx\035xsave" \
+ "\034pclmulqdq\033aes" \
+ "\032movbe\031sse4.2" \
+ "\030sse4.1\027ssse3\026amd_lzcnt\025popcnt" \
+ "\024amd_sse4a\023tscp\022ahf\021cx16" \
+ "\017sse3\015sse2\014sse\013fxsr\012amd3dx\011amd3d" \
+ "\010amdmmx\07mmx\06cmov\05amdsysc\04sep\03cx8\02tsc\01fpu"
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/sys/dtrace.h b/usr/src/uts/common/sys/dtrace.h
index aa78528654..0c3523d165 100644
--- a/usr/src/uts/common/sys/dtrace.h
+++ b/usr/src/uts/common/sys/dtrace.h
@@ -206,6 +206,7 @@ typedef enum dtrace_probespec {
#define DIF_VAR_ARGS 0x0000 /* arguments array */
#define DIF_VAR_REGS 0x0001 /* registers array */
#define DIF_VAR_UREGS 0x0002 /* user registers array */
+#define DIF_VAR_VMREGS 0x0003 /* virtual machine registers array */
#define DIF_VAR_CURTHREAD 0x0100 /* thread pointer */
#define DIF_VAR_TIMESTAMP 0x0101 /* timestamp */
#define DIF_VAR_VTIMESTAMP 0x0102 /* virtual timestamp */
diff --git a/usr/src/uts/common/sys/dtrace_impl.h b/usr/src/uts/common/sys/dtrace_impl.h
index fed537e18b..8cff6f0172 100644
--- a/usr/src/uts/common/sys/dtrace_impl.h
+++ b/usr/src/uts/common/sys/dtrace_impl.h
@@ -24,11 +24,13 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
#ifndef _SYS_DTRACE_IMPL_H
#define _SYS_DTRACE_IMPL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -1246,6 +1248,7 @@ extern void dtrace_copyoutstr(uintptr_t, uintptr_t, size_t,
volatile uint16_t *);
extern void dtrace_getpcstack(pc_t *, int, int, uint32_t *);
extern ulong_t dtrace_getreg(struct regs *, uint_t);
+extern uint64_t dtrace_getvmreg(uint_t, volatile uint16_t *);
extern int dtrace_getstackdepth(int);
extern void dtrace_getupcstack(uint64_t *, int);
extern void dtrace_getufpstack(uint64_t *, uint64_t *, int);
diff --git a/usr/src/uts/i86pc/ml/locore.s b/usr/src/uts/i86pc/ml/locore.s
index 8aec1537e5..894a289c2c 100644
--- a/usr/src/uts/i86pc/ml/locore.s
+++ b/usr/src/uts/i86pc/ml/locore.s
@@ -1144,28 +1144,34 @@ cmntrap()
.dtrace_induced:
cmpw $KCS_SEL, REGOFF_CS(%rbp) /* test CS for user-mode trap */
- jne 2f /* if from user, panic */
+ jne 3f /* if from user, panic */
cmpl $T_PGFLT, REGOFF_TRAPNO(%rbp)
- je 0f
+ je 1f
cmpl $T_GPFLT, REGOFF_TRAPNO(%rbp)
- jne 3f /* if not PF or GP, panic */
+ je 0f
+
+ cmpl $T_ILLINST, REGOFF_TRAPNO(%rbp)
+ je 0f
+
+ jne 4f /* if not PF, GP or UD, panic */
/*
* If we've taken a GPF, we don't (unfortunately) have the address that
* induced the fault. So instead of setting the fault to BADADDR,
* we'll set the fault to ILLOP.
*/
+0:
orw $CPU_DTRACE_ILLOP, %cx
movw %cx, CPUC_DTRACE_FLAGS(%rax)
- jmp 1f
-0:
+ jmp 2f
+1:
orw $CPU_DTRACE_BADADDR, %cx
movw %cx, CPUC_DTRACE_FLAGS(%rax) /* set fault to bad addr */
movq %r15, CPUC_DTRACE_ILLVAL(%rax)
/* fault addr is illegal value */
-1:
+2:
movq REGOFF_RIP(%rbp), %rdi
movq %rdi, %r12
call dtrace_instr_size
@@ -1174,11 +1180,11 @@ cmntrap()
INTR_POP
IRET
/*NOTREACHED*/
-2:
+3:
leaq dtrace_badflags(%rip), %rdi
xorl %eax, %eax
call panic
-3:
+4:
leaq dtrace_badtrap(%rip), %rdi
xorl %eax, %eax
call panic
diff --git a/usr/src/uts/i86pc/os/cpuid.c b/usr/src/uts/i86pc/os/cpuid.c
index 1a472c9e93..09707f151c 100644
--- a/usr/src/uts/i86pc/os/cpuid.c
+++ b/usr/src/uts/i86pc/os/cpuid.c
@@ -28,7 +28,9 @@
/*
* Portions Copyright 2009 Advanced Micro Devices, Inc.
*/
-
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
/*
* Various routines to handle identification
* and classification of x86 processors.
@@ -155,7 +157,10 @@ static char *x86_feature_names[NUM_X86_FEATURES] = {
"aes",
"pclmulqdq",
"xsave",
- "avx" };
+ "avx",
+ "vmx",
+ "svm"
+};
boolean_t
is_x86_feature(void *featureset, uint_t feature)
@@ -1263,8 +1268,12 @@ cpuid_pass1(cpu_t *cpu, uchar_t *featureset)
}
#endif /* __xpv */
+ if (cp->cp_ecx & CPUID_INTC_ECX_VMX) {
+ add_x86_feature(featureset, X86FSET_VMX);
+ }
+
/*
- * Only need it first time, rest of the cpus would follow suite.
+ * Only need it first time, rest of the cpus would follow suit.
* we only capture this for the bootcpu.
*/
if (cp->cp_edx & CPUID_INTC_EDX_CLFSH) {
@@ -1421,6 +1430,10 @@ cpuid_pass1(cpu_t *cpu, uchar_t *featureset)
if (cp->cp_edx & CPUID_AMD_EDX_TSCP) {
add_x86_feature(featureset, X86FSET_TSCP);
}
+
+ if (cp->cp_ecx & CPUID_AMD_ECX_SVM) {
+ add_x86_feature(featureset, X86FSET_SVM);
+ }
break;
default:
break;
@@ -2566,6 +2579,8 @@ cpuid_pass4(cpu_t *cpu)
(*ecx & CPUID_INTC_ECX_OSXSAVE))
hwcap_flags |= AV_386_XSAVE;
}
+ if (*ecx & CPUID_INTC_ECX_VMX)
+ hwcap_flags |= AV_386_VMX;
if (*ecx & CPUID_INTC_ECX_POPCNT)
hwcap_flags |= AV_386_POPCNT;
if (*edx & CPUID_INTC_EDX_FPU)
@@ -2653,6 +2668,8 @@ cpuid_pass4(cpu_t *cpu)
hwcap_flags |= AV_386_AMD_3DNow;
if (*edx & CPUID_AMD_EDX_3DNowx)
hwcap_flags |= AV_386_AMD_3DNowx;
+ if (*ecx & CPUID_AMD_ECX_SVM)
+ hwcap_flags |= AV_386_AMD_SVM;
switch (cpi->cpi_vendor) {
case X86_VENDOR_AMD:
diff --git a/usr/src/uts/intel/dtrace/dtrace_asm.s b/usr/src/uts/intel/dtrace/dtrace_asm.s
index 47b981d1e3..754343925c 100644
--- a/usr/src/uts/intel/dtrace/dtrace_asm.s
+++ b/usr/src/uts/intel/dtrace/dtrace_asm.s
@@ -62,6 +62,43 @@ dtrace_getfp(void)
#if defined(lint) || defined(__lint)
+uint64_t
+dtrace_getvmreg(uint32_t reg, volatile uint16_t *flags)
+{ return (0); }
+
+#else /* lint */
+
+#if defined(__amd64)
+
+ ENTRY_NP(dtrace_getvmreg)
+
+ movq %rdi, %rdx
+ vmread %rdx, %rax
+ ret
+
+ SET_SIZE(dtrace_getvmreg)
+
+#elif defined(__i386)
+
+ ENTRY_NP(dtrace_getvmreg)
+ pushl %ebp / Setup stack frame
+ movl %esp, %ebp
+
+ movl 12(%ebp), %eax / Load flag pointer
+ movw (%eax), %cx / Load flags
+ orw $CPU_DTRACE_ILLOP, %cx / Set ILLOP
+ movw %cx, (%eax) / Store flags
+
+ leave
+ ret
+ SET_SIZE(dtrace_getvmreg)
+
+#endif /* __i386 */
+#endif /* lint */
+
+
+#if defined(lint) || defined(__lint)
+
uint32_t
dtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new)
{
diff --git a/usr/src/uts/intel/sys/x86_archext.h b/usr/src/uts/intel/sys/x86_archext.h
index 383610bbee..aeda1bfa3e 100644
--- a/usr/src/uts/intel/sys/x86_archext.h
+++ b/usr/src/uts/intel/sys/x86_archext.h
@@ -362,6 +362,8 @@ extern "C" {
#define X86FSET_PCLMULQDQ 32
#define X86FSET_XSAVE 33
#define X86FSET_AVX 34
+#define X86FSET_VMX 35
+#define X86FSET_SVM 36
/*
* flags to patch tsc_read routine.
@@ -585,7 +587,7 @@ extern "C" {
#if defined(_KERNEL) || defined(_KMEMUSER)
-#define NUM_X86_FEATURES 35
+#define NUM_X86_FEATURES 37
extern uchar_t x86_featureset[];
extern void free_x86_featureset(void *featureset);
diff --git a/usr/src/uts/sparc/dtrace/dtrace_isa.c b/usr/src/uts/sparc/dtrace/dtrace_isa.c
index 9fd9d90fc0..8b2dbe7f00 100644
--- a/usr/src/uts/sparc/dtrace/dtrace_isa.c
+++ b/usr/src/uts/sparc/dtrace/dtrace_isa.c
@@ -936,3 +936,12 @@ got_fp:
return (value);
}
+
+/*ARGSUSED*/
+uint64_t
+dtrace_getvmreg(uint_t ndx, volatile uint16_t *flags)
+{
+ *flags |= CPU_DTRACE_ILLOP;
+
+ return (0);
+}