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.


bbeaf4ceb54650315d27194748721c89bd8ca51b
[palacios.git] / palacios / src / palacios / vmm_ctrl_regs.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_mem.h>
21 #include <palacios/vmm.h>
22 #include <palacios/vmcb.h>
23 #include <palacios/vmm_decoder.h>
24 #include <palacios/vm_guest_mem.h>
25 #include <palacios/vmm_ctrl_regs.h>
26 #include <palacios/vmm_direct_paging.h>
27
28 #ifndef CONFIG_DEBUG_CTRL_REGS
29 #undef PrintDebug
30 #define PrintDebug(fmt, args...)
31 #endif
32
33
34 static int handle_lmsw(struct guest_info * info, struct x86_instr * dec_instr);
35 static int handle_clts(struct guest_info * info, struct x86_instr * dec_instr);
36 static int handle_mov_to_cr0(struct guest_info * info, struct x86_instr * dec_instr);
37
38
39 // First Attempt = 494 lines
40 // current = 106 lines
41 int v3_handle_cr0_write(struct guest_info * info) {
42     uchar_t instr[15];
43     int ret;
44     struct x86_instr dec_instr;
45     
46     if (info->mem_mode == PHYSICAL_MEM) { 
47         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
48     } else { 
49         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
50     }
51     
52     if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
53         PrintError("Could not decode instruction\n");
54         return -1;
55     }
56
57     
58     if (dec_instr.op_type == V3_OP_LMSW) {
59         if (handle_lmsw(info, &dec_instr) == -1) {
60             return -1;
61         }
62     } else if (dec_instr.op_type == V3_OP_MOV2CR) {
63         if (handle_mov_to_cr0(info, &dec_instr) == -1) {
64             return -1;
65         }
66     } else if (dec_instr.op_type == V3_OP_CLTS) {
67         if (handle_clts(info, &dec_instr) == -1) {
68             return -1;
69         }
70     } else {
71         PrintError("Unhandled opcode in handle_cr0_write\n");
72         return -1;
73     }
74     
75     info->rip += dec_instr.instr_length;
76     
77     return 0;
78 }
79
80
81
82
83 // The CR0 register only has flags in the low 32 bits
84 // The hardware does a format check to make sure the high bits are zero
85 // Because of this we can ignore the high 32 bits here
86 static int handle_mov_to_cr0(struct guest_info * info, struct x86_instr * dec_instr) {
87     // 32 bit registers
88     struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
89     struct cr0_32 * new_cr0 = (struct cr0_32 *)(dec_instr->src_operand.operand);
90     struct cr0_32 * guest_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
91     uint_t paging_transition = 0;
92     
93     PrintDebug("MOV2CR0 (MODE=%s)\n", v3_cpu_mode_to_str(info->cpu_mode));
94     
95     PrintDebug("OperandVal = %x, length=%d\n", *(uint_t *)new_cr0, dec_instr->src_operand.size);
96     
97     PrintDebug("Old CR0=%x\n", *(uint_t *)shadow_cr0);
98     PrintDebug("Old Guest CR0=%x\n", *(uint_t *)guest_cr0);     
99     
100     
101     // We detect if this is a paging transition
102     if (guest_cr0->pg != new_cr0->pg) {
103         paging_transition = 1;
104     }  
105     
106     // Guest always sees the value they wrote
107     *guest_cr0 = *new_cr0;
108     
109     // This value must always be set to 1 
110     guest_cr0->et = 1;    
111     
112     // Set the shadow register to catch non-virtualized flags
113     *shadow_cr0 = *guest_cr0;
114     
115     // Paging is always enabled
116     shadow_cr0->pg = 1;  
117     
118     // Was there a paging transition
119     // Meaning we need to change the page tables
120     if (paging_transition) {
121         if (v3_get_vm_mem_mode(info) == VIRTUAL_MEM) {
122             
123             struct efer_64 * guest_efer  = (struct efer_64 *)&(info->shdw_pg_state.guest_efer);
124             struct efer_64 * shadow_efer = (struct efer_64 *)&(info->ctrl_regs.efer);
125             
126             // Check long mode LME to set LME
127             if (guest_efer->lme == 1) {
128                 PrintDebug("Enabing Long Mode\n");
129                 guest_efer->lma = 1;
130                 
131                 shadow_efer->lma = 1;
132                 shadow_efer->lme = 1;
133                 
134                 PrintDebug("New EFER %p\n", (void *)*(addr_t *)(shadow_efer));
135             }
136             
137             PrintDebug("Activating Shadow Page Tables\n");
138             
139             if (v3_activate_shadow_pt(info) == -1) {
140                 PrintError("Failed to activate shadow page tables\n");
141                 return -1;
142             }
143         } else {
144
145             shadow_cr0->wp = 1;
146             
147             if (v3_activate_passthrough_pt(info) == -1) {
148                 PrintError("Failed to activate passthrough page tables\n");
149                 return -1;
150             }
151         }
152     }
153     
154     
155     PrintDebug("New Guest CR0=%x\n",*(uint_t *)guest_cr0);  
156     PrintDebug("New CR0=%x\n", *(uint_t *)shadow_cr0);
157     
158     return 0;
159 }
160
161
162
163
164 static int handle_clts(struct guest_info * info, struct x86_instr * dec_instr) {
165     // CLTS
166     struct cr0_32 * real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
167     
168     real_cr0->ts = 0;
169     
170     if (info->shdw_pg_mode == SHADOW_PAGING) {
171         struct cr0_32 * guest_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
172         guest_cr0->ts = 0;
173     }
174     return 0;
175 }
176
177
178 static int handle_lmsw(struct guest_info * info, struct x86_instr * dec_instr) {
179     struct cr0_real * real_cr0  = (struct cr0_real *)&(info->ctrl_regs.cr0);
180     // XED is a mess, and basically reverses the operand order for an LMSW
181     struct cr0_real * new_cr0 = (struct cr0_real *)(dec_instr->dst_operand.operand);    
182     uchar_t new_cr0_val;
183     
184     PrintDebug("LMSW\n");
185     
186     new_cr0_val = (*(char*)(new_cr0)) & 0x0f;
187     
188     PrintDebug("OperandVal = %x\n", new_cr0_val);
189     
190     // We can just copy the new value through
191     // we don't need to virtualize the lower 4 bits
192     PrintDebug("Old CR0=%x\n", *(uint_t *)real_cr0);    
193     *(uchar_t*)real_cr0 &= 0xf0;
194     *(uchar_t*)real_cr0 |= new_cr0_val;
195     PrintDebug("New CR0=%x\n", *(uint_t *)real_cr0);    
196     
197     
198     // If Shadow paging is enabled we push the changes to the virtualized copy of cr0
199     if (info->shdw_pg_mode == SHADOW_PAGING) {
200         struct cr0_real * guest_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
201         
202         PrintDebug("Old Guest CR0=%x\n", *(uint_t *)guest_cr0); 
203         *(uchar_t*)guest_cr0 &= 0xf0;
204         *(uchar_t*)guest_cr0 |= new_cr0_val;
205         PrintDebug("New Guest CR0=%x\n", *(uint_t *)guest_cr0); 
206     }
207     return 0;
208 }
209
210
211
212
213
214 // First attempt = 253 lines
215 // current = 51 lines
216 int v3_handle_cr0_read(struct guest_info * info) {
217     uchar_t instr[15];
218     int ret;
219     struct x86_instr dec_instr;
220     
221     if (info->mem_mode == PHYSICAL_MEM) { 
222         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
223     } else { 
224         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
225     }
226     
227     
228     if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
229         PrintError("Could not decode instruction\n");
230         return -1;
231     }
232     
233     if (dec_instr.op_type == V3_OP_MOVCR2) {
234         PrintDebug("MOVCR2 (mode=%s)\n", v3_cpu_mode_to_str(info->cpu_mode));
235
236         if ((v3_get_vm_cpu_mode(info) == LONG) || 
237             (v3_get_vm_cpu_mode(info) == LONG_32_COMPAT)) {
238             struct cr0_64 * dst_reg = (struct cr0_64 *)(dec_instr.dst_operand.operand);
239         
240             if (info->shdw_pg_mode == SHADOW_PAGING) {
241                 struct cr0_64 * guest_cr0 = (struct cr0_64 *)&(info->shdw_pg_state.guest_cr0);
242                 *dst_reg = *guest_cr0;
243             } else {
244                 struct cr0_64 * shadow_cr0 = (struct cr0_64 *)&(info->ctrl_regs.cr0);
245                 *dst_reg = *shadow_cr0;
246             }
247
248             PrintDebug("returned CR0: %p\n", (void *)*(addr_t *)dst_reg);
249         } else {
250             struct cr0_32 * dst_reg = (struct cr0_32 *)(dec_instr.dst_operand.operand);
251         
252             if (info->shdw_pg_mode == SHADOW_PAGING) {
253                 struct cr0_32 * guest_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
254                 *dst_reg = *guest_cr0;
255             } else {
256                 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
257                 *dst_reg = *shadow_cr0;
258             }
259
260             PrintDebug("returned CR0: %x\n", *(uint_t*)dst_reg);
261         }
262
263     } else if (dec_instr.op_type == V3_OP_SMSW) {
264         struct cr0_real * shadow_cr0 = (struct cr0_real *)&(info->ctrl_regs.cr0);
265         struct cr0_real * dst_reg = (struct cr0_real *)(dec_instr.dst_operand.operand);
266         char cr0_val = *(char*)shadow_cr0 & 0x0f;
267         
268         PrintDebug("SMSW\n");
269         
270         // The lower 4 bits of the guest/shadow CR0 are mapped through
271         // We can treat nested and shadow paging the same here
272         *(char *)dst_reg &= 0xf0;
273         *(char *)dst_reg |= cr0_val;
274         
275     } else {
276         PrintError("Unhandled opcode in handle_cr0_read\n");
277         return -1;
278     }
279     
280     info->rip += dec_instr.instr_length;
281
282     return 0;
283 }
284
285
286
287
288 // First Attempt = 256 lines
289 // current = 65 lines
290 int v3_handle_cr3_write(struct guest_info * info) {
291     int ret;
292     uchar_t instr[15];
293     struct x86_instr dec_instr;
294     
295     if (info->mem_mode == PHYSICAL_MEM) { 
296         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
297     } else { 
298         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
299     }
300     
301     if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
302         PrintError("Could not decode instruction\n");
303         return -1;
304     }
305     
306     if (dec_instr.op_type == V3_OP_MOV2CR) {
307         PrintDebug("MOV2CR3 (cpu_mode=%s)\n", v3_cpu_mode_to_str(info->cpu_mode));
308         
309         if (info->shdw_pg_mode == SHADOW_PAGING) {
310             PrintDebug("Old Shadow CR3=%p; Old Guest CR3=%p\n", 
311                        (void *)(addr_t)(info->ctrl_regs.cr3), 
312                        (void*)(addr_t)(info->shdw_pg_state.guest_cr3));
313             
314             
315             // We update the guest CR3    
316             if (info->cpu_mode == LONG) {
317                 struct cr3_64 * new_cr3 = (struct cr3_64 *)(dec_instr.src_operand.operand);
318                 struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->shdw_pg_state.guest_cr3);
319                 *guest_cr3 = *new_cr3;
320             } else {
321                 struct cr3_32 * new_cr3 = (struct cr3_32 *)(dec_instr.src_operand.operand);
322                 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
323                 *guest_cr3 = *new_cr3;
324             }
325
326
327 #ifdef CONFIG_CRAY_XT
328             
329             // If Paging is enabled in the guest then we need to change the shadow page tables
330             if (info->mem_mode == VIRTUAL_MEM) {
331                 if (info->shdw_pg_state.prev_guest_cr3 != info->shdw_pg_state.guest_cr3) {
332                     if (v3_activate_shadow_pt(info) == -1) {
333                         PrintError("Failed to activate 32 bit shadow page table\n");
334                         return -1;
335                     }
336                 }
337             }
338
339             info->shdw_pg_state.prev_guest_cr3 = info->shdw_pg_state.guest_cr3;
340 #else 
341
342             // If Paging is enabled in the guest then we need to change the shadow page tables
343             if (info->mem_mode == VIRTUAL_MEM) {
344                 if (v3_activate_shadow_pt(info) == -1) {
345                     PrintError("Failed to activate 32 bit shadow page table\n");
346                     return -1;
347                 }
348             }
349
350 #endif
351
352             
353             PrintDebug("New Shadow CR3=%p; New Guest CR3=%p\n", 
354                        (void *)(addr_t)(info->ctrl_regs.cr3), 
355                        (void*)(addr_t)(info->shdw_pg_state.guest_cr3));
356             
357         } else if (info->shdw_pg_mode == NESTED_PAGING) {
358             
359             // This is just a passthrough operation which we probably don't need here
360             if (info->cpu_mode == LONG) {
361                 struct cr3_64 * new_cr3 = (struct cr3_64 *)(dec_instr.src_operand.operand);
362                 struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->ctrl_regs.cr3);
363                 *guest_cr3 = *new_cr3;
364             } else {
365                 struct cr3_32 * new_cr3 = (struct cr3_32 *)(dec_instr.src_operand.operand);
366                 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
367                 *guest_cr3 = *new_cr3;
368             }
369             
370         }
371     } else {
372         PrintError("Unhandled opcode in handle_cr3_write\n");
373         return -1;
374     }
375     
376     info->rip += dec_instr.instr_length;
377     
378     return 0;
379 }
380
381
382
383 // first attempt = 156 lines
384 // current = 36 lines
385 int v3_handle_cr3_read(struct guest_info * info) {
386     uchar_t instr[15];
387     int ret;
388     struct x86_instr dec_instr;
389     
390     if (info->mem_mode == PHYSICAL_MEM) { 
391         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
392     } else { 
393         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
394     }
395     
396     if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
397         PrintError("Could not decode instruction\n");
398         return -1;
399     }
400     
401     if (dec_instr.op_type == V3_OP_MOVCR2) {
402         PrintDebug("MOVCR32 (mode=%s)\n", v3_cpu_mode_to_str(info->cpu_mode));
403         
404         if (info->shdw_pg_mode == SHADOW_PAGING) {
405             
406             if ((v3_get_vm_cpu_mode(info) == LONG) || 
407                 (v3_get_vm_cpu_mode(info) == LONG_32_COMPAT)) {
408                 struct cr3_64 * dst_reg = (struct cr3_64 *)(dec_instr.dst_operand.operand);
409                 struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->shdw_pg_state.guest_cr3);
410                 *dst_reg = *guest_cr3;
411             } else {
412                 struct cr3_32 * dst_reg = (struct cr3_32 *)(dec_instr.dst_operand.operand);
413                 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
414                 *dst_reg = *guest_cr3;
415             }
416             
417         } else if (info->shdw_pg_mode == NESTED_PAGING) {
418             
419             // This is just a passthrough operation which we probably don't need here
420             if ((v3_get_vm_cpu_mode(info) == LONG) || 
421                 (v3_get_vm_cpu_mode(info) == LONG_32_COMPAT)) {
422                 struct cr3_64 * dst_reg = (struct cr3_64 *)(dec_instr.dst_operand.operand);
423                 struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->ctrl_regs.cr3);
424                 *dst_reg = *guest_cr3;
425             } else {
426                 struct cr3_32 * dst_reg = (struct cr3_32 *)(dec_instr.dst_operand.operand);
427                 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
428                 *dst_reg = *guest_cr3;
429             }
430         }
431         
432     } else {
433         PrintError("Unhandled opcode in handle_cr3_read\n");
434         return -1;
435     }
436     
437     info->rip += dec_instr.instr_length;
438     
439     return 0;
440 }
441
442
443 // We don't need to virtualize CR4, all we need is to detect the activation of PAE
444 int v3_handle_cr4_read(struct guest_info * info) {
445     //  PrintError("CR4 Read not handled\n");
446     // Do nothing...
447     return 0;
448 }
449
450 int v3_handle_cr4_write(struct guest_info * info) {
451     uchar_t instr[15];
452     int ret;
453     int flush_tlb=0;
454     struct x86_instr dec_instr;
455     v3_cpu_mode_t cpu_mode = v3_get_vm_cpu_mode(info);
456     
457     if (info->mem_mode == PHYSICAL_MEM) { 
458         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
459     } else { 
460         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
461     }
462     
463     if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
464         PrintError("Could not decode instruction\n");
465         return -1;
466     }
467     
468     if (dec_instr.op_type != V3_OP_MOV2CR) {
469         PrintError("Invalid opcode in write to CR4\n");
470         return -1;
471     }
472     
473     // Check to see if we need to flush the tlb
474     
475     if (v3_get_vm_mem_mode(info) == VIRTUAL_MEM) { 
476         struct cr4_32 * new_cr4 = (struct cr4_32 *)(dec_instr.src_operand.operand);
477         struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
478         
479         // if pse, pge, or pae have changed while PG (in any mode) is on
480         // the side effect is a TLB flush, which means we need to
481         // toss the current shadow page tables too
482         //
483         // 
484         // TODO - PAE FLAG needs to be special cased
485         if ((cr4->pse != new_cr4->pse) || 
486             (cr4->pge != new_cr4->pge) || 
487             (cr4->pae != new_cr4->pae)) { 
488             PrintDebug("Handling PSE/PGE/PAE -> TLBFlush case, flag set\n");
489             flush_tlb=1;
490             
491         }
492     }
493     
494
495     if ((cpu_mode == PROTECTED) || (cpu_mode == PROTECTED_PAE)) {
496         struct cr4_32 * new_cr4 = (struct cr4_32 *)(dec_instr.src_operand.operand);
497         struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
498         
499         PrintDebug("OperandVal = %x, length = %d\n", *(uint_t *)new_cr4, dec_instr.src_operand.size);
500         PrintDebug("Old CR4=%x\n", *(uint_t *)cr4);
501         
502         if ((info->shdw_pg_mode == SHADOW_PAGING)) { 
503             if (v3_get_vm_mem_mode(info) == PHYSICAL_MEM) {
504                 
505                 if ((cr4->pae == 0) && (new_cr4->pae == 1)) {
506                     PrintDebug("Creating PAE passthrough tables\n");
507                     
508                     // create 32 bit PAE direct map page table
509                     if (v3_reset_passthrough_pts(info) == -1) {
510                         PrintError("Could not create 32 bit PAE passthrough pages tables\n");
511                         return -1;
512                     }
513
514                     // reset cr3 to new page tables
515                     info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
516                     
517                 } else if ((cr4->pae == 1) && (new_cr4->pae == 0)) {
518                     // Create passthrough standard 32bit pagetables
519                     PrintError("Switching From PAE to Protected mode not supported\n");
520                     return -1;
521                 } 
522             }
523         }
524         
525         *cr4 = *new_cr4;
526         PrintDebug("New CR4=%x\n", *(uint_t *)cr4);
527         
528     } else if ((cpu_mode == LONG) || (cpu_mode == LONG_32_COMPAT)) {
529         struct cr4_64 * new_cr4 = (struct cr4_64 *)(dec_instr.src_operand.operand);
530         struct cr4_64 * cr4 = (struct cr4_64 *)&(info->ctrl_regs.cr4);
531         
532         PrintDebug("Old CR4=%p\n", (void *)*(addr_t *)cr4);
533         PrintDebug("New CR4=%p\n", (void *)*(addr_t *)new_cr4);
534         
535         if (new_cr4->pae == 0) {
536             // cannot turn off PAE in long mode GPF the guest
537             PrintError("Cannot disable PAE in long mode, should send GPF\n");
538             return -1;
539         }
540         
541         *cr4 = *new_cr4;
542         
543     } else {
544         PrintError("CR4 write not supported in CPU_MODE: %s\n", v3_cpu_mode_to_str(cpu_mode));
545         return -1;
546     }
547     
548     
549     if (flush_tlb) {
550         PrintDebug("Handling PSE/PGE/PAE -> TLBFlush (doing flush now!)\n");
551         if (v3_activate_shadow_pt(info) == -1) {
552             PrintError("Failed to activate shadow page tables when emulating TLB flush in handling cr4 write\n");
553             return -1;
554         }
555     }
556     
557     
558     info->rip += dec_instr.instr_length;
559     return 0;
560 }
561
562
563 int v3_handle_efer_read(uint_t msr, struct v3_msr * dst, void * priv_data) {
564     struct guest_info * info = (struct guest_info *)(priv_data);
565     PrintDebug("EFER Read HI=%x LO=%x\n", info->shdw_pg_state.guest_efer.hi, info->shdw_pg_state.guest_efer.lo);
566     
567     dst->value = info->shdw_pg_state.guest_efer.value;
568     
569     return 0;
570 }
571
572
573
574 // TODO: this is a disaster we need to clean this up...
575 int v3_handle_efer_write(uint_t msr, struct v3_msr src, void * priv_data) {
576     struct guest_info * info = (struct guest_info *)(priv_data);
577     //struct efer_64 * new_efer = (struct efer_64 *)&(src.value);
578     struct efer_64 * shadow_efer = (struct efer_64 *)&(info->ctrl_regs.efer);
579     struct v3_msr * guest_efer = &(info->shdw_pg_state.guest_efer);
580     
581     PrintDebug("EFER Write\n");
582     PrintDebug("EFER Write Values: HI=%x LO=%x\n", src.hi, src.lo);
583     //PrintDebug("Old EFER=%p\n", (void *)*(addr_t*)(shadow_efer));
584     
585     // We virtualize the guests efer to hide the SVME and LMA bits
586     guest_efer->value = src.value;
587     
588     
589     // Enable/Disable Syscall
590     shadow_efer->sce = src.value & 0x1;
591     
592     return 0;
593 }