--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+#ifndef __VMM_SYM_IFACE_H__
+#define __VMM_SYM_IFACE_H__
+
+#ifdef __V3VEE__
+
+
+
+
+
+struct v3_sym_interface {
+ uint64_t magic;
+
+
+ union {
+ uint32_t feature_flags;
+ struct {
+ uint_t cur_proc_valid : 1;
+ uint_t proc_list_valid : 1;
+ } __attribute__((packed));
+ } __attribute__((packed));
+
+ addr_t current_proc;
+ addr_t proc_list;
+
+ uint8_t pci_pt_map[256 / 8];
+} __attribute__((packed));
+
+
+struct v3_sym_state {
+
+ struct v3_sym_interface * sym_page;
+ addr_t sym_page_pa;
+
+ uint_t active;
+ uint64_t guest_pg_addr;
+
+};
+
+int v3_init_sym_iface(struct guest_info * info);
+
+
+int v3_sym_map_pci_passthrough(struct guest_info * info, uint_t bus, uint_t dev, uint_t fn);
+int v3_sym_unmap_pci_passthrough(struct guest_info * info, uint_t bus, uint_t dev, uint_t fn);
+
+
+
+#endif
+
+#endif
#include <palacios/vmm_mem.h>
#include <palacios/vmm_hypercall.h>
#include <palacios/vmm_dev_mgr.h>
+#include <palacios/vmm_sym_iface.h>
#ifdef CONFIG_SYMBIOTIC_SWAP
#include <palacios/vmm_sym_swap.h>
}
#endif
- v3_init_time(info);
+ v3_init_hypercall_map(info);
v3_init_io_map(info);
v3_init_msr_map(info);
- v3_init_interrupt_state(info);
- v3_init_exception_state(info);
- v3_init_dev_mgr(info);
v3_init_host_events(info);
-
- v3_init_decoder(info);
-
- v3_init_hypercall_map(info);
-
-#ifdef CONFIG_SYMBIOTIC_SWAP
- v3_init_sym_swap(info);
-#endif
-
-
-
// Initialize the memory map
v3_init_shadow_map(info);
info->shdw_pg_mode = SHADOW_PAGING;
}
+ v3_init_sym_iface(info);
+
+ v3_init_time(info);
+ v3_init_interrupt_state(info);
+ v3_init_exception_state(info);
+ v3_init_dev_mgr(info);
+ v3_init_decoder(info);
+
+#ifdef CONFIG_SYMBIOTIC_SWAP
+ PrintDebug("initializing symbiotic swap\n");
+ v3_init_sym_swap(info);
+#endif
if (config_ptr->schedule_freq == 0) {
return -1;
}
+ v3_print_io_map(info);
+ v3_print_msr_map(info);
+
info->run_state = VM_STOPPED;
info->vm_regs.rdi = 0;
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+#include <palacios/vmm.h>
+#include <palacios/vmm_msr.h>
+#include <palacios/vmm_mem.h>
+
+#define SYM_MSR_NUM 0x535
+
+
+
+
+static int msr_read(uint_t msr, struct v3_msr * dst, void * priv_data) {
+ struct guest_info * info = (struct guest_info *)priv_data;
+ struct v3_sym_state * state = &(info->sym_state);
+
+ dst->value = state->guest_pg_addr;
+
+ return 0;
+}
+
+static int msr_write(uint_t msr, struct v3_msr src, void * priv_data) {
+ struct guest_info * info = (struct guest_info *)priv_data;
+ struct v3_sym_state * state = &(info->sym_state);
+
+ if (state->active == 1) {
+ // unmap page
+ struct v3_shadow_region * old_reg = v3_get_shadow_region(info, (addr_t)state->guest_pg_addr);
+
+ if (old_reg == NULL) {
+ PrintError("Could not find previously active symbiotic page (%p)\n", (void *)state->guest_pg_addr);
+ return -1;
+ }
+
+ v3_delete_shadow_region(info, old_reg);
+ }
+
+ state->guest_pg_addr = src.value;
+ state->guest_pg_addr &= ~0xfffLL;
+
+ state->active = 1;
+
+ // map page
+ v3_add_shadow_mem(info, (addr_t)state->guest_pg_addr,
+ (addr_t)(state->guest_pg_addr + PAGE_SIZE_4KB - 1),
+ state->sym_page_pa);
+
+ return 0;
+}
+
+
+
+int v3_init_sym_iface(struct guest_info * info) {
+ struct v3_sym_state * state = &(info->sym_state);
+
+ memset(state, 0, sizeof(struct v3_sym_state));
+
+ PrintDebug("Allocating symbiotic page\n");
+ state->sym_page_pa = (addr_t)V3_AllocPages(1);
+ state->sym_page = (struct v3_sym_interface *)V3_VAddr((void *)state->sym_page_pa);
+
+ PrintDebug("Clearing symbiotic page\n");
+ memset(state->sym_page, 0, PAGE_SIZE_4KB);
+
+ PrintDebug("hooking MSR\n");
+ v3_hook_msr(info, SYM_MSR_NUM, msr_read, msr_write, info);
+
+ PrintDebug("Done\n");
+ return 0;
+}
+
+int v3_sym_map_pci_passthrough(struct guest_info * info, uint_t bus, uint_t dev, uint_t fn) {
+ struct v3_sym_state * state = &(info->sym_state);
+ uint_t dev_index = (bus << 16) + (dev << 8) + fn;
+ uint_t major = dev_index / 8;
+ uint_t minor = dev_index % 8;
+
+ state->sym_page->pci_pt_map[major] |= 0x1 << minor;
+
+ return 0;
+}
+
+int v3_sym_unmap_pci_passthrough(struct guest_info * info, uint_t bus, uint_t dev, uint_t fn) {
+ struct v3_sym_state * state = &(info->sym_state);
+ uint_t dev_index = (bus << 16) + (dev << 8) + fn;
+ uint_t major = dev_index / 8;
+ uint_t minor = dev_index % 8;
+
+ state->sym_page->pci_pt_map[major] &= ~(0x1 << minor);
+
+ return 0;
+}