2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
21 #include <palacios/vmm.h>
22 #include <palacios/vmm_msr.h>
23 #include <palacios/vmm_mem.h>
25 #define SYM_MSR_NUM 0x535
30 static int msr_read(uint_t msr, struct v3_msr * dst, void * priv_data) {
31 struct guest_info * info = (struct guest_info *)priv_data;
32 struct v3_sym_state * state = &(info->sym_state);
34 dst->value = state->guest_pg_addr;
39 static int msr_write(uint_t msr, struct v3_msr src, void * priv_data) {
40 struct guest_info * info = (struct guest_info *)priv_data;
41 struct v3_sym_state * state = &(info->sym_state);
43 if (state->active == 1) {
45 struct v3_shadow_region * old_reg = v3_get_shadow_region(info, (addr_t)state->guest_pg_addr);
47 if (old_reg == NULL) {
48 PrintError("Could not find previously active symbiotic page (%p)\n", (void *)state->guest_pg_addr);
52 v3_delete_shadow_region(info, old_reg);
55 state->guest_pg_addr = src.value;
56 state->guest_pg_addr &= ~0xfffLL;
61 v3_add_shadow_mem(info, (addr_t)state->guest_pg_addr,
62 (addr_t)(state->guest_pg_addr + PAGE_SIZE_4KB - 1),
70 int v3_init_sym_iface(struct guest_info * info) {
71 struct v3_sym_state * state = &(info->sym_state);
73 memset(state, 0, sizeof(struct v3_sym_state));
75 PrintDebug("Allocating symbiotic page\n");
76 state->sym_page_pa = (addr_t)V3_AllocPages(1);
77 state->sym_page = (struct v3_sym_interface *)V3_VAddr((void *)state->sym_page_pa);
79 PrintDebug("Clearing symbiotic page\n");
80 memset(state->sym_page, 0, PAGE_SIZE_4KB);
82 PrintDebug("hooking MSR\n");
83 v3_hook_msr(info, SYM_MSR_NUM, msr_read, msr_write, info);
89 int v3_sym_map_pci_passthrough(struct guest_info * info, uint_t bus, uint_t dev, uint_t fn) {
90 struct v3_sym_state * state = &(info->sym_state);
91 uint_t dev_index = (bus << 16) + (dev << 8) + fn;
92 uint_t major = dev_index / 8;
93 uint_t minor = dev_index % 8;
95 state->sym_page->pci_pt_map[major] |= 0x1 << minor;
100 int v3_sym_unmap_pci_passthrough(struct guest_info * info, uint_t bus, uint_t dev, uint_t fn) {
101 struct v3_sym_state * state = &(info->sym_state);
102 uint_t dev_index = (bus << 16) + (dev << 8) + fn;
103 uint_t major = dev_index / 8;
104 uint_t minor = dev_index % 8;
106 state->sym_page->pci_pt_map[major] &= ~(0x1 << minor);