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.


added simplistic page table cache
[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
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             
341             PrintDebug("New Shadow CR3=%p; New Guest CR3=%p\n", 
342                        (void *)(addr_t)(info->ctrl_regs.cr3), 
343                        (void*)(addr_t)(info->shdw_pg_state.guest_cr3));
344             
345         } else if (info->shdw_pg_mode == NESTED_PAGING) {
346             
347             // This is just a passthrough operation which we probably don't need here
348             if (info->cpu_mode == LONG) {
349                 struct cr3_64 * new_cr3 = (struct cr3_64 *)(dec_instr.src_operand.operand);
350                 struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->ctrl_regs.cr3);
351                 *guest_cr3 = *new_cr3;
352             } else {
353                 struct cr3_32 * new_cr3 = (struct cr3_32 *)(dec_instr.src_operand.operand);
354                 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
355                 *guest_cr3 = *new_cr3;
356             }
357             
358         }
359     } else {
360         PrintError("Unhandled opcode in handle_cr3_write\n");
361         return -1;
362     }
363     
364     info->rip += dec_instr.instr_length;
365     
366     return 0;
367 }
368
369
370
371 // first attempt = 156 lines
372 // current = 36 lines
373 int v3_handle_cr3_read(struct guest_info * info) {
374     uchar_t instr[15];
375     int ret;
376     struct x86_instr dec_instr;
377     
378     if (info->mem_mode == PHYSICAL_MEM) { 
379         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
380     } else { 
381         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
382     }
383     
384     if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
385         PrintError("Could not decode instruction\n");
386         return -1;
387     }
388     
389     if (dec_instr.op_type == V3_OP_MOVCR2) {
390         PrintDebug("MOVCR32 (mode=%s)\n", v3_cpu_mode_to_str(info->cpu_mode));
391         
392         if (info->shdw_pg_mode == SHADOW_PAGING) {
393             
394             if ((v3_get_vm_cpu_mode(info) == LONG) || 
395                 (v3_get_vm_cpu_mode(info) == LONG_32_COMPAT)) {
396                 struct cr3_64 * dst_reg = (struct cr3_64 *)(dec_instr.dst_operand.operand);
397                 struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->shdw_pg_state.guest_cr3);
398                 *dst_reg = *guest_cr3;
399             } else {
400                 struct cr3_32 * dst_reg = (struct cr3_32 *)(dec_instr.dst_operand.operand);
401                 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
402                 *dst_reg = *guest_cr3;
403             }
404             
405         } else if (info->shdw_pg_mode == NESTED_PAGING) {
406             
407             // This is just a passthrough operation which we probably don't need here
408             if ((v3_get_vm_cpu_mode(info) == LONG) || 
409                 (v3_get_vm_cpu_mode(info) == LONG_32_COMPAT)) {
410                 struct cr3_64 * dst_reg = (struct cr3_64 *)(dec_instr.dst_operand.operand);
411                 struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->ctrl_regs.cr3);
412                 *dst_reg = *guest_cr3;
413             } else {
414                 struct cr3_32 * dst_reg = (struct cr3_32 *)(dec_instr.dst_operand.operand);
415                 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
416                 *dst_reg = *guest_cr3;
417             }
418         }
419         
420     } else {
421         PrintError("Unhandled opcode in handle_cr3_read\n");
422         return -1;
423     }
424     
425     info->rip += dec_instr.instr_length;
426     
427     return 0;
428 }
429
430
431 // We don't need to virtualize CR4, all we need is to detect the activation of PAE
432 int v3_handle_cr4_read(struct guest_info * info) {
433     //  PrintError("CR4 Read not handled\n");
434     // Do nothing...
435     return 0;
436 }
437
438 int v3_handle_cr4_write(struct guest_info * info) {
439     uchar_t instr[15];
440     int ret;
441     int flush_tlb=0;
442     struct x86_instr dec_instr;
443     v3_cpu_mode_t cpu_mode = v3_get_vm_cpu_mode(info);
444     
445     if (info->mem_mode == PHYSICAL_MEM) { 
446         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
447     } else { 
448         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
449     }
450     
451     if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
452         PrintError("Could not decode instruction\n");
453         return -1;
454     }
455     
456     if (dec_instr.op_type != V3_OP_MOV2CR) {
457         PrintError("Invalid opcode in write to CR4\n");
458         return -1;
459     }
460     
461     // Check to see if we need to flush the tlb
462     
463     if (v3_get_vm_mem_mode(info) == VIRTUAL_MEM) { 
464         struct cr4_32 * new_cr4 = (struct cr4_32 *)(dec_instr.src_operand.operand);
465         struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
466         
467         // if pse, pge, or pae have changed while PG (in any mode) is on
468         // the side effect is a TLB flush, which means we need to
469         // toss the current shadow page tables too
470         //
471         // 
472         // TODO - PAE FLAG needs to be special cased
473         if ((cr4->pse != new_cr4->pse) || 
474             (cr4->pge != new_cr4->pge) || 
475             (cr4->pae != new_cr4->pae)) { 
476             PrintDebug("Handling PSE/PGE/PAE -> TLBFlush case, flag set\n");
477             flush_tlb=1;
478             
479         }
480     }
481     
482
483     if ((cpu_mode == PROTECTED) || (cpu_mode == PROTECTED_PAE)) {
484         struct cr4_32 * new_cr4 = (struct cr4_32 *)(dec_instr.src_operand.operand);
485         struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
486         
487         PrintDebug("OperandVal = %x, length = %d\n", *(uint_t *)new_cr4, dec_instr.src_operand.size);
488         PrintDebug("Old CR4=%x\n", *(uint_t *)cr4);
489         
490         if ((info->shdw_pg_mode == SHADOW_PAGING)) { 
491             if (v3_get_vm_mem_mode(info) == PHYSICAL_MEM) {
492                 
493                 if ((cr4->pae == 0) && (new_cr4->pae == 1)) {
494                     PrintDebug("Creating PAE passthrough tables\n");
495                     
496                     // create 32 bit PAE direct map page table
497                     if (v3_reset_passthrough_pts(info) == -1) {
498                         PrintError("Could not create 32 bit PAE passthrough pages tables\n");
499                         return -1;
500                     }
501
502                     // reset cr3 to new page tables
503                     info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
504                     
505                 } else if ((cr4->pae == 1) && (new_cr4->pae == 0)) {
506                     // Create passthrough standard 32bit pagetables
507                     PrintError("Switching From PAE to Protected mode not supported\n");
508                     return -1;
509                 } 
510             }
511         }
512         
513         *cr4 = *new_cr4;
514         PrintDebug("New CR4=%x\n", *(uint_t *)cr4);
515         
516     } else if ((cpu_mode == LONG) || (cpu_mode == LONG_32_COMPAT)) {
517         struct cr4_64 * new_cr4 = (struct cr4_64 *)(dec_instr.src_operand.operand);
518         struct cr4_64 * cr4 = (struct cr4_64 *)&(info->ctrl_regs.cr4);
519         
520         PrintDebug("Old CR4=%p\n", (void *)*(addr_t *)cr4);
521         PrintDebug("New CR4=%p\n", (void *)*(addr_t *)new_cr4);
522         
523         if (new_cr4->pae == 0) {
524             // cannot turn off PAE in long mode GPF the guest
525             PrintError("Cannot disable PAE in long mode, should send GPF\n");
526             return -1;
527         }
528         
529         *cr4 = *new_cr4;
530         
531     } else {
532         PrintError("CR4 write not supported in CPU_MODE: %s\n", v3_cpu_mode_to_str(cpu_mode));
533         return -1;
534     }
535     
536     
537     if (flush_tlb) {
538         PrintDebug("Handling PSE/PGE/PAE -> TLBFlush (doing flush now!)\n");
539         if (v3_activate_shadow_pt(info) == -1) {
540             PrintError("Failed to activate shadow page tables when emulating TLB flush in handling cr4 write\n");
541             return -1;
542         }
543     }
544     
545     
546     info->rip += dec_instr.instr_length;
547     return 0;
548 }
549
550
551 int v3_handle_efer_read(uint_t msr, struct v3_msr * dst, void * priv_data) {
552     struct guest_info * info = (struct guest_info *)(priv_data);
553     PrintDebug("EFER Read HI=%x LO=%x\n", info->shdw_pg_state.guest_efer.hi, info->shdw_pg_state.guest_efer.lo);
554     
555     dst->value = info->shdw_pg_state.guest_efer.value;
556     
557     return 0;
558 }
559
560
561
562 // TODO: this is a disaster we need to clean this up...
563 int v3_handle_efer_write(uint_t msr, struct v3_msr src, void * priv_data) {
564     struct guest_info * info = (struct guest_info *)(priv_data);
565     //struct efer_64 * new_efer = (struct efer_64 *)&(src.value);
566     struct efer_64 * shadow_efer = (struct efer_64 *)&(info->ctrl_regs.efer);
567     struct v3_msr * guest_efer = &(info->shdw_pg_state.guest_efer);
568     
569     PrintDebug("EFER Write\n");
570     PrintDebug("EFER Write Values: HI=%x LO=%x\n", src.hi, src.lo);
571     //PrintDebug("Old EFER=%p\n", (void *)*(addr_t*)(shadow_efer));
572     
573     // We virtualize the guests efer to hide the SVME and LMA bits
574     guest_efer->value = src.value;
575     
576     
577     // Enable/Disable Syscall
578     shadow_efer->sce = src.value & 0x1;
579     
580     return 0;
581 }