summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bhyvectl
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2015-06-27 22:48:22 +0000
committerneel <neel@FreeBSD.org>2015-06-27 22:48:22 +0000
commit115742fae3f7a7c52d6d5f4894f37e68dff4fd5c (patch)
treecb845c4cb2d3a3b67b3e1134742c3c5b250ae954 /usr.sbin/bhyvectl
parent02efaba1d135756ed65855bdc99e7d83f46cc4a2 (diff)
downloadFreeBSD-src-115742fae3f7a7c52d6d5f4894f37e68dff4fd5c.zip
FreeBSD-src-115742fae3f7a7c52d6d5f4894f37e68dff4fd5c.tar.gz
MFC r276428:
Replace bhyve's minimal RTC emulation with a fully featured one in vmm.ko. MFC r276432: Initialize all fields of 'struct vm_exception exception' before passing it to vm_inject_exception(). MFC r276763: Clear blocking due to STI or MOV SS in the hypervisor when an instruction is emulated or when the vcpu incurs an exception. MFC r277149: Clean up usage of 'struct vm_exception' to only to communicate information from userspace to vmm.ko when injecting an exception. MFC r277168: Fix typo (missing comma). MFC r277309: Make the error message explicit instead of just printing the usage if the virtual machine name is not specified. MFC r277310: Simplify instruction restart logic in bhyve. MFC r277359: Fix a bug in libvmmapi 'vm_copy_setup()' where it would return success even if the 'gpa' was in the guest MMIO region. MFC r277360: MOVS instruction emulation. MFC r277626: Add macro to identify AVIC capability (advanced virtual interrupt controller) in AMD processors. MFC r279220: Don't close a block context if it couldn't be opened avoiding a null deref. MFC r279225: Add "-u" option to bhyve(8) to indicate that the RTC should maintain UTC time. MFC r279227: Emulate MSR 0xC0011024 when running on AMD processors. MFC r279228: Always emulate MSR_PAT on Intel processors and don't rely on PAT save/restore capability of VT-x. This lets bhyve run nested in older VMware versions that don't support the PAT save/restore capability. MFC r279540: Fix warnings/errors when building vmm.ko with gcc.
Diffstat (limited to 'usr.sbin/bhyvectl')
-rw-r--r--usr.sbin/bhyvectl/bhyvectl.c89
1 files changed, 85 insertions, 4 deletions
diff --git a/usr.sbin/bhyvectl/bhyvectl.c b/usr.sbin/bhyvectl/bhyvectl.c
index 0c4457e..e2b514d 100644
--- a/usr.sbin/bhyvectl/bhyvectl.c
+++ b/usr.sbin/bhyvectl/bhyvectl.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <fcntl.h>
#include <string.h>
#include <getopt.h>
+#include <time.h>
#include <assert.h>
#include <machine/cpufunc.h>
@@ -157,6 +158,11 @@ usage(bool cpu_intel)
" [--inject-nmi]\n"
" [--force-reset]\n"
" [--force-poweroff]\n"
+ " [--get-rtc-time]\n"
+ " [--set-rtc-time=<secs>]\n"
+ " [--get-rtc-nvram]\n"
+ " [--set-rtc-nvram=<val>]\n"
+ " [--rtc-nvram-offset=<offset>]\n"
" [--get-active-cpus]\n"
" [--get-suspended-cpus]\n"
" [--get-intinfo]\n"
@@ -220,6 +226,12 @@ usage(bool cpu_intel)
exit(1);
}
+static int get_rtc_time, set_rtc_time;
+static int get_rtc_nvram, set_rtc_nvram;
+static int rtc_nvram_offset;
+static uint8_t rtc_nvram_value;
+static time_t rtc_secs;
+
static int get_stats, getcap, setcap, capval, get_gpa_pmap;
static int inject_nmi, assert_lapic_lvt;
static int force_reset, force_poweroff;
@@ -545,6 +557,9 @@ enum {
UNASSIGN_PPTDEV,
GET_GPA_PMAP,
ASSERT_LAPIC_LVT,
+ SET_RTC_TIME,
+ SET_RTC_NVRAM,
+ RTC_NVRAM_OFFSET,
};
static void
@@ -1269,6 +1284,11 @@ setup_options(bool cpu_intel)
{ "setcap", REQ_ARG, 0, SET_CAP },
{ "get-gpa-pmap", REQ_ARG, 0, GET_GPA_PMAP },
{ "assert-lapic-lvt", REQ_ARG, 0, ASSERT_LAPIC_LVT },
+ { "get-rtc-time", NO_ARG, &get_rtc_time, 1 },
+ { "set-rtc-time", REQ_ARG, 0, SET_RTC_TIME },
+ { "rtc-nvram-offset", REQ_ARG, 0, RTC_NVRAM_OFFSET },
+ { "get-rtc-nvram", NO_ARG, &get_rtc_nvram, 1 },
+ { "set-rtc-nvram", REQ_ARG, 0, SET_RTC_NVRAM },
{ "getcap", NO_ARG, &getcap, 1 },
{ "get-stats", NO_ARG, &get_stats, 1 },
{ "get-desc-ds",NO_ARG, &get_desc_ds, 1 },
@@ -1462,6 +1482,33 @@ setup_options(bool cpu_intel)
return (all_opts);
}
+static const char *
+wday_str(int idx)
+{
+ static const char *weekdays[] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ };
+
+ if (idx >= 0 && idx < 7)
+ return (weekdays[idx]);
+ else
+ return ("UNK");
+}
+
+static const char *
+mon_str(int idx)
+{
+ static const char *months[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+
+ if (idx >= 0 && idx < 12)
+ return (months[idx]);
+ else
+ return ("UNK");
+}
+
int
main(int argc, char *argv[])
{
@@ -1477,6 +1524,7 @@ main(int argc, char *argv[])
cpuset_t cpus;
bool cpu_intel;
uint64_t cs, ds, es, fs, gs, ss, tr, ldtr;
+ struct tm tm;
struct option *opts;
cpu_intel = cpu_vendor_intel();
@@ -1594,6 +1642,17 @@ main(int argc, char *argv[])
capval = strtoul(optarg, NULL, 0);
setcap = 1;
break;
+ case SET_RTC_TIME:
+ rtc_secs = strtoul(optarg, NULL, 0);
+ set_rtc_time = 1;
+ break;
+ case SET_RTC_NVRAM:
+ rtc_nvram_value = (uint8_t)strtoul(optarg, NULL, 0);
+ set_rtc_nvram = 1;
+ break;
+ case RTC_NVRAM_OFFSET:
+ rtc_nvram_offset = strtoul(optarg, NULL, 0);
+ break;
case GET_GPA_PMAP:
gpa_pmap = strtoul(optarg, NULL, 0);
get_gpa_pmap = 1;
@@ -1971,6 +2030,31 @@ main(int argc, char *argv[])
}
}
+ if (!error && set_rtc_nvram)
+ error = vm_rtc_write(ctx, rtc_nvram_offset, rtc_nvram_value);
+
+ if (!error && (get_rtc_nvram || get_all)) {
+ error = vm_rtc_read(ctx, rtc_nvram_offset, &rtc_nvram_value);
+ if (error == 0) {
+ printf("rtc nvram[%03d]: 0x%02x\n", rtc_nvram_offset,
+ rtc_nvram_value);
+ }
+ }
+
+ if (!error && set_rtc_time)
+ error = vm_rtc_settime(ctx, rtc_secs);
+
+ if (!error && (get_rtc_time || get_all)) {
+ error = vm_rtc_gettime(ctx, &rtc_secs);
+ if (error == 0) {
+ gmtime_r(&rtc_secs, &tm);
+ printf("rtc time %#lx: %s %s %02d %02d:%02d:%02d %d\n",
+ rtc_secs, wday_str(tm.tm_wday), mon_str(tm.tm_mon),
+ tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
+ 1900 + tm.tm_year);
+ }
+ }
+
if (!error && (getcap || get_all)) {
int captype, val, getcaptype;
@@ -2034,10 +2118,7 @@ main(int argc, char *argv[])
}
if (!error && run) {
- error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RIP, &rip);
- assert(error == 0);
-
- error = vm_run(ctx, vcpu, rip, &vmexit);
+ error = vm_run(ctx, vcpu, &vmexit);
if (error == 0)
dump_vm_run_exitcode(&vmexit, vcpu);
else
OpenPOWER on IntegriCloud