Permalink
Browse files

Merge branch 'master' into vmnet-tap

  • Loading branch information...
xez committed Jul 7, 2015
2 parents f14c1f2 + eccf36b commit bd68d2b99cb9fff167cd1d1878f6c1f5229b5331
View
@@ -1,3 +1,5 @@
+GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags)
+
ifeq ($V, 1)
VERBOSE =
else
@@ -30,7 +32,7 @@ VMM_SRC := \
src/vmm/io/vrtc.c
XHYVE_SRC := \
- src/acpi.c \
+ src/acpitbl.c \
src/atkbdc.c \
src/block_if.c \
src/consport.c \
@@ -62,7 +64,8 @@ XHYVE_SRC := \
src/xmsr.c
FIRMWARE_SRC := \
- src/firmware/kexec.c
+ src/firmware/kexec.c \
+ src/firmware/fbsd.c
SRC := \
$(VMM_SRC) \
@@ -73,6 +76,8 @@ OBJ := $(SRC:src/%.c=build/%.o)
DEP := $(OBJ:%.o=%.d)
INC := -Iinclude
+CFLAGS += -DVERSION=\"$(GIT_VERSION)\"
+
TARGET = build/xhyve
all: $(TARGET) | build
View
@@ -6,7 +6,7 @@
About
-----
-The *xhyve hypervisor* is a port of [bhyve](http://www.bhyve.org) to OS X. It is built on top of Hypervisor.framework in OS X 10.10 Yosemite and higher, runs entirely in userspace, and has no other dependencies. It can run vanilla Linux distributions and may gain support for other guest operating systems in the future.
+The *xhyve hypervisor* is a port of [bhyve](http://www.bhyve.org) to OS X. It is built on top of Hypervisor.framework in OS X 10.10 Yosemite and higher, runs entirely in userspace, and has no other dependencies. It can run FreeBSD and vanilla Linux distributions and may gain support for other guest operating systems in the future.
License: BSD
@@ -180,31 +180,26 @@ TODO
----
- vmm:
- - enable APIC access page to speed up APIC emulation
- - enable x2APIC MSRs (even faster)
+ - enable APIC access page to speed up APIC emulation (**performance**)
+ - enable x2APIC MSRs (even faster) (**performance**)
- vmm_callout:
- is a quick'n'dirty implementation of the FreeBSD kernel callout mechanism
- seems to be racy
- fix races or perhaps replace with something better
- - use per vCPU timer event thread (performance)?
+ - use per vCPU timer event thread (**performance**)?
+ - use hardware VMX preemption timer instead of `pthread_cond_wait` (**performance**)
- some 32-bit guests are broken (support PAE paging in VMCS)
- - PCID guest support (performance)
+ - PCID guest support (**performance**)
- block_if:
- - OS X does not support preadv/pwritev, we need to serialize reads and writes for the time being until we find a better solution. (performance)
+ - OS X does not support `preadv`/`pwritev`, we need to serialize reads and writes for the time being until we find a better solution. (**performance**)
- support block devices other than plain files
- virtio_net:
- unify TAP and vmnet backends
- vmnet: make it not require root
- - vmnet: send/receive more than a single packet at a time (performance)
-- ACPI tables don't work
- - bhyve creates ASL on the fly and then calls out to an ASL compiler (iasl) on
- every VM boot to create the DSDT:
- - remove dependency on iasl by creating AML bytecode directly
- - shouldn't be to hard since we we are only interested in a very small
- subset of ASL
+ - vmnet: send/receive more than a single packet at a time (**performance**)
- virtio_rnd:
- is untested
- remove explicit state transitions:
- - since only the owning task/thread can modify the VM/vCPUs a lot of the synchronization might be unnecessary
+ - since only the owning task/thread can modify the VM/vCPUs a lot of the synchronization might be unnecessary (**performance**)
- performance, performance and performance
- remove vestigial code, cleanup
View
@@ -30,6 +30,9 @@
#include <stdint.h>
+/* if set, create AML instead of ASL and calling out to iasl */
+#define ACPITBL_AML 1
+
#define SCI_INT 9
#define SMI_CMD 0xb2
@@ -49,4 +52,6 @@ void dsdt_fixed_irq(uint8_t irq);
void dsdt_fixed_mem32(uint32_t base, uint32_t length);
void dsdt_indent(int levels);
void dsdt_unindent(int levels);
+void dsdt_fixup(int bus, uint16_t iobase, uint16_t iolimit, uint32_t membase32,
+ uint32_t memlimit32, uint64_t membase64, uint64_t memlimit64);
void sci_init(void);
@@ -0,0 +1,102 @@
+#pragma once
+
+#include <stdint.h>
+
+/*
+ * USERBOOT interface versions
+ */
+#define USERBOOT_VERSION_1 1
+#define USERBOOT_VERSION_2 2
+#define USERBOOT_VERSION_3 3
+
+/*
+ * Exit codes from the loader
+ */
+#define USERBOOT_EXIT_QUIT 1
+#define USERBOOT_EXIT_REBOOT 2
+
+struct loader_callbacks {
+ /* Console i/o */
+
+ /* Wait until a key is pressed on the console and then return it */
+ int (*getc)(void *arg);
+ /* Write the character ch to the console */
+ void (*putc)(void *arg, int ch);
+ /* Return non-zero if a key can be read from the console */
+ int (*poll)(void *arg);
+
+ /* Host filesystem i/o */
+
+ /* Open a file in the host filesystem */
+ int (*open)(void *arg, const char *filename, void **h_return);
+ /* Close a file */
+ int (*close)(void *arg, void *h);
+ /* Return non-zero if the file is a directory */
+ int (*isdir)(void *arg, void *h);
+ /* Read size bytes from a file. The number of bytes remaining in dst after
+ * reading is returned in *resid_return
+ */
+ int (*read)(void *arg, void *h, void *dst, size_t size,
+ size_t *resid_return);
+ /* Read an entry from a directory. The entry's inode number is returned in
+ * fileno_return, its type in *type_return and the name length in
+ * *namelen_return. The name itself is copied to the buffer name which must
+ * be at least PATH_MAX in size.
+ */
+ int (*readdir)(void *arg, void *h, uint32_t *fileno_return,
+ uint8_t *type_return, size_t *namelen_return, char *name);
+ /* Seek to a location within an open file */
+ int (*seek)(void *arg, void *h, uint64_t offset, int whence);
+ /* Return some stat(2) related information about the file */
+ int (*stat)(void *arg, void *h, int *mode_return, int *uid_return,
+ int *gid_return, uint64_t *size_return);
+
+ /* Disk image i/o */
+
+ /* Read from a disk image at the given offset */
+ int (*diskread)(void *arg, int unit, uint64_t offset, void *dst,
+ size_t size, size_t *resid_return);
+
+ /* Guest virtual machine i/o */
+
+ /* Copy to the guest address space */
+ int (*copyin)(void *arg, const void *from, uint64_t to, size_t size);
+ /* Copy from the guest address space */
+ int (*copyout)(void *arg, uint64_t from, void *to, size_t size);
+ /* Set a guest register value */
+ void (*setreg)(void *arg, int, uint64_t);
+ /* Set a guest MSR value */
+ void (*setmsr)(void *arg, int, uint64_t);
+ /* Set a guest CR value */
+ void (*setcr)(void *arg, int, uint64_t);
+ /* Set the guest GDT address */
+ void (*setgdt)(void *arg, uint64_t, size_t);
+ /* Transfer control to the guest at the given address */
+ void (*exec)(void *arg, uint64_t pc);
+
+ /* Misc */
+
+ /* Sleep for usec microseconds */
+ void (*delay)(void *arg, int usec);
+ /* Exit with the given exit code */
+ void (*exit)(void);
+ /* Return guest physical memory map details */
+ void (*getmem)(void *arg, uint64_t *lowmem, uint64_t *highmem);
+ /* ioctl interface to the disk device */
+ int (*diskioctl)(void *arg, int unit, u_long cmd, void *data);
+ /*
+ * Returns an environment variable in the form "name=value".
+ *
+ * If there are no more variables that need to be set in the
+ * loader environment then return NULL.
+ *
+ * 'num' is used as a handle for the callback to identify which
+ * environment variable to return next. It will begin at 0 and
+ * each invocation will add 1 to the previous value of 'num'.
+ */
+ const char * (*getenv)(void *arg, int num);
+};
+
+void fbsd_init(char *userboot_path, char *bootvolume_path, char *kernelenv,
+ char *cons);
+uint64_t fbsd_load(void);
@@ -54,23 +54,26 @@
#define LSEL(s,r) (((s)<<3) | SEL_LDT | r) /* a local selector */
#define GSEL(s,r) (((s)<<3) | r) /* a global selector */
-// /*
-// * User segment descriptors (%cs, %ds etc for i386 apps. 64 bit wide)
-// * For long-mode apps, %cs only has the conforming bit in sd_type, the sd_dpl,
-// * sd_p, sd_l and sd_def32 which must be zero). %ds only has sd_p.
-// */
-// struct segment_descriptor {
-// unsigned sd_lolimit:16; /* segment extent (lsb) */
-// unsigned sd_lobase:24; /* segment base address (lsb) */
-// unsigned sd_type:5; /* segment type */
-// unsigned sd_dpl:2; /* segment descriptor priority level */
-// unsigned sd_p:1; /* segment descriptor present */
-// unsigned sd_hilimit:4; /* segment extent (msb) */
-// unsigned sd_xx:2; /* unused */
-// unsigned sd_def32:1; /* default 32 vs 16 bit size */
-// unsigned sd_gran:1; /* limit granularity (byte/page units)*/
-// unsigned sd_hibase:8; /* segment base address (msb) */
-// } __packed;
+/*
+ * User segment descriptors (%cs, %ds etc for i386 apps. 64 bit wide)
+ * For long-mode apps, %cs only has the conforming bit in sd_type, the sd_dpl,
+ * sd_p, sd_l and sd_def32 which must be zero). %ds only has sd_p.
+ */
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpacked"
+struct segment_descriptor {
+ unsigned sd_lolimit:16; /* segment extent (lsb) */
+ unsigned sd_lobase:24; /* segment base address (lsb) */
+ unsigned sd_type:5; /* segment type */
+ unsigned sd_dpl:2; /* segment descriptor priority level */
+ unsigned sd_p:1; /* segment descriptor present */
+ unsigned sd_hilimit:4; /* segment extent (msb) */
+ unsigned sd_xx:2; /* unused */
+ unsigned sd_def32:1; /* default 32 vs 16 bit size */
+ unsigned sd_gran:1; /* limit granularity (byte/page units)*/
+ unsigned sd_hibase:8; /* segment base address (msb) */
+} __packed;
+#pragma clang diagnostic pop
struct user_segment_descriptor {
uint64_t sd_lolimit:16; /* segment extent (lsb) */
@@ -167,16 +170,16 @@ struct user_segment_descriptor {
// /* memory segment types */
// #define SDT_MEMRO 16 memory read only
// #define SDT_MEMROA 17 /* memory read only accessed */
-// #define SDT_MEMRW 18 /* memory read write */
-// #define SDT_MEMRWA 19 /* memory read write accessed */
+#define SDT_MEMRW 18 /* memory read write */
+#define SDT_MEMRWA 19 /* memory read write accessed */
// #define SDT_MEMROD 20 /* memory read only expand dwn limit */
// #define SDT_MEMRODA 21 /* memory read only expand dwn limit accessed */
// #define SDT_MEMRWD 22 /* memory read write expand dwn limit */
// #define SDT_MEMRWDA 23 /* memory read write expand dwn limit accessed*/
// #define SDT_MEME 24 /* memory execute only */
// #define SDT_MEMEA 25 /* memory execute only accessed */
-// #define SDT_MEMER 26 /* memory execute read */
-// #define SDT_MEMERA 27 /* memory execute read accessed */
+#define SDT_MEMER 26 /* memory execute read */
+#define SDT_MEMERA 27 /* memory execute read accessed */
// #define SDT_MEMEC 28 /* memory execute only conforming */
// #define SDT_MEMEAC 29 /* memory execute only accessed conforming */
// #define SDT_MEMERC 30 /* memory execute read conforming */
@@ -93,7 +93,7 @@ void vmm_stat_free(void *vp);
* 'buf' should be at least fit 'MAX_VMM_STAT_TYPES' entries
*/
int vmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf);
-int vmm_stat_desc_copy(int index, char *buf, int buflen);
+int vmm_stat_desc_copy(int index, char *buf, size_t buflen);
static void __inline
vmm_stat_array_incr(struct vm *vm, int vcpu, struct vmm_stat_type *vst,
Oops, something went wrong.

1 comment on commit bd68d2b

@exdrunmeswt

This comment has been minimized.

Show comment
Hide comment

#bd68d2b

Please sign in to comment.