Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


329ee0fc93f48b183a17adb3f4a20d7f9d2f2f1f
[palacios.git] / palacios / src / palacios / vmm_ss_emulator.c
1 /* 
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.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
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.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm.h>
21 #include <palacios/vmm_emulator.h>
22 #include <palacios/vm_guest_mem.h>
23 #include <palacios/vmm_decoder.h>
24 #include <palacios/vmm_debug.h>
25 #include <palacios/vmcb.h>
26 #include <palacios/vmm_ctrl_regs.h>
27
28
29 #ifndef DEBUG_EMULATOR
30 #undef PrintDebug
31 #define PrintDebug(fmt, args...)
32 #endif
33
34
35 int v3_init_emulator(struct guest_info * info) {
36
37
38     emulator->tf_enabled = 0;
39
40     return 0;
41 }
42
43
44
45
46
47
48
49
50
51
52 static int set_stepping(struct guest_info * info) {
53     vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
54     ctrl_area->exceptions.db = 1;
55
56     info->emulator.tf_enabled = ((struct rflags *)&(info->ctrl_regs.rflags))->tf;
57
58     ((struct rflags *)&(info->ctrl_regs.rflags))->tf = 1;
59
60     return 0;
61 }
62
63
64 static int unset_stepping(struct guest_info * info) {
65     vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
66     ctrl_area->exceptions.db = 0;
67
68     ((struct rflags *)&(info->ctrl_regs.rflags))->tf = info->emulator.tf_enabled;
69
70     if (info->emulator.tf_enabled) {
71         // Inject breakpoint exception into guest
72     }
73
74     return 0;
75
76 }
77
78
79 int v3_emulate_memory_read(struct guest_info * info, addr_t read_gva, 
80                            int (*read)(addr_t read_addr, void * dst, uint_t length, void * priv_data), 
81                            addr_t read_gpa, void * private_data) {
82     struct basic_instr_info instr_info;
83     uchar_t instr[15];
84     int ret;
85     addr_t data_addr_offset = PAGE_OFFSET(read_gva);
86  
87     PrintDebug("Emulating Read\n");
88
89     if (info->mem_mode == PHYSICAL_MEM) { 
90         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
91     } else { 
92         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
93     }
94
95     if (ret == -1) {
96         PrintError("Could not read guest memory\n");
97         return -1;
98     }
99
100 #ifdef DEBUG_EMULATOR
101     PrintDebug("Instr (15 bytes) at %p:\n", (void *)(addr_t)instr);
102     PrintTraceMemDump(instr, 15);
103 #endif  
104
105
106     if (v3_basic_mem_decode(info, (addr_t)instr, &instr_info) == -1) {
107         PrintError("Could not do a basic memory instruction decode\n");
108         V3_Free(data_page);
109         return -1;
110     }
111
112     // Read the data directly onto the emulated page
113     ret = read(read_gpa, (void *)(data_page->page_addr + data_addr_offset), instr_info.op_size, private_data);
114     if ((ret == -1) || ((uint_t)ret != instr_info.op_size)) {
115         PrintError("Read error in emulator\n");
116         return -1;
117     }
118
119  
120
121     // setup_code_page(info, instr, &instr_info);
122     set_stepping(info);
123
124     info->emulator.running = 1;
125     info->run_state = VM_EMULATING;
126     info->emulator.instr_length = instr_info.instr_length;
127
128     return 0;
129 }
130
131
132
133 int v3_emulate_memory_write(struct guest_info * info, addr_t write_gva,
134                             int (*write)(addr_t write_addr, void * src, uint_t length, void * priv_data), 
135                             addr_t write_gpa, void * private_data) {
136
137     struct basic_instr_info instr_info;
138     uchar_t instr[15];
139     int ret;
140     addr_t data_addr_offset = PAGE_OFFSET(write_gva);
141     int i;
142
143     PrintDebug("Emulating Write for instruction at 0x%p\n", (void *)(addr_t)(info->rip));
144
145     if (info->mem_mode == PHYSICAL_MEM) { 
146         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
147     } else { 
148         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
149     }
150
151
152   
153     if (v3_basic_mem_decode(info, (addr_t)instr, &instr_info) == -1) {
154         PrintError("Could not do a basic memory instruction decode\n");
155         V3_Free(write_op);
156         V3_Free(data_page);
157         return -1;
158     }
159
160     if (instr_info.has_rep==1) { 
161         PrintDebug("Emulated instruction has rep\n");
162     }
163
164
165     if (info->emulator.running == 0) {
166         //    setup_code_page(info, instr, &instr_info);
167         set_stepping(info);
168         info->emulator.running = 1;
169         info->run_state = VM_EMULATING;
170         info->emulator.instr_length = instr_info.instr_length;
171     }
172
173     return 0;
174 }
175
176
177 // end emulation
178 int v3_emulation_exit_handler(struct guest_info * info) {
179   
180     unset_stepping(info);
181
182
183     PrintDebug("returning from emulation\n");
184
185     return 0;
186 }