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 more 64 bit support,
[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
27
28
29 /* Segmentation is a problem here...
30  *
31  * When we get a memory operand, presumably we use the default segment (which is?) 
32  * unless an alternate segment was specfied in the prefix...
33  */
34
35
36 #ifndef DEBUG_CTRL_REGS
37 #undef PrintDebug
38 #define PrintDebug(fmt, args...)
39 #endif
40
41
42 static int handle_lmsw(struct guest_info * info, struct x86_instr * dec_instr);
43 static int handle_clts(struct guest_info * info, struct x86_instr * dec_instr);
44
45 static int handle_mov_to_cr0(struct guest_info * info, struct x86_instr * dec_instr);
46 static int handle_mov_to_cr0_32(struct guest_info * info, struct x86_instr * dec_instr);
47 static int handle_mov_to_cr0_32pae(struct guest_info * info, struct x86_instr * dec_instr);
48 static int handle_mov_to_cr0_64(struct guest_info * info, struct x86_instr * dec_instr);
49 static int handle_mov_to_cr0_64compat(struct guest_info * info, struct x86_instr * dec_instr);
50
51 static int handle_mov_to_cr3_32(struct guest_info * info, struct x86_instr * dec_instr);
52 static int handle_mov_to_cr3_32pae(struct guest_info * info, struct x86_instr * dec_instr);
53 static int handle_mov_to_cr3_64(struct guest_info * info, struct x86_instr * dec_instr);
54 static int handle_mov_to_cr3_64compat(struct guest_info * info, struct x86_instr * dec_instr);
55
56
57
58 // First Attempt = 494 lines
59 // current = 106 lines
60 int v3_handle_cr0_write(struct guest_info * info) {
61   uchar_t instr[15];
62   int ret;
63   struct x86_instr dec_instr;
64
65   if (info->mem_mode == PHYSICAL_MEM) { 
66     ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
67   } else { 
68     ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
69   }
70
71   /* The IFetch will already have faulted in the necessary bytes for the full instruction
72     if (ret != 15) {
73     // I think we should inject a GPF into the guest
74     PrintError("Could not read instruction (ret=%d)\n", ret);
75     return -1;
76     }
77   */
78
79   if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
80     PrintError("Could not decode instruction\n");
81     return -1;
82   }
83
84   if (v3_opcode_cmp(V3_OPCODE_LMSW, (const uchar_t *)(dec_instr.opcode)) == 0) {
85
86     if (handle_lmsw(info, &dec_instr) == -1) {
87       return -1;
88     }
89
90   } else if (v3_opcode_cmp(V3_OPCODE_MOV2CR, (const uchar_t *)(dec_instr.opcode)) == 0) {
91
92     if (handle_mov_to_cr0(info, &dec_instr) == -1) {
93       return -1;
94     }
95
96   } else if (v3_opcode_cmp(V3_OPCODE_CLTS, (const uchar_t *)(dec_instr.opcode)) == 0) {
97
98     if (handle_clts(info, &dec_instr) == -1) {
99       return -1;
100     }
101
102   } else {
103     PrintError("Unhandled opcode in handle_cr0_write\n");
104     return -1;
105   }
106
107   info->rip += dec_instr.instr_length;
108
109   return 0;
110 }
111
112
113
114
115 static int handle_mov_to_cr0(struct guest_info * info, struct x86_instr * dec_instr) {
116   PrintDebug("MOV2CR0\n");
117
118   switch (info->cpu_mode) {
119   case REAL:
120   case PROTECTED:
121     return handle_mov_to_cr0_32(info, dec_instr);    
122   case PROTECTED_PAE:
123     return handle_mov_to_cr0_32pae(info, dec_instr);
124   case LONG:
125     return handle_mov_to_cr0_64(info, dec_instr);
126   case LONG_32_COMPAT:
127     return handle_mov_to_cr0_64compat(info, dec_instr);
128   default:
129     PrintError("Invalid CPU Operating Mode: %d\n", info->cpu_mode);
130     return -1;
131
132   }
133 }
134
135 static int handle_mov_to_cr0_32pae(struct guest_info * info, struct x86_instr * dec_instr) {
136   PrintError("32 bit PAE mov to CR0 not implemented\n");
137   return -1;
138 }
139
140 static int handle_mov_to_cr0_64(struct guest_info * info, struct x86_instr * dec_instr) {
141   PrintError("64 bit mov to CR0 not implemented\n");
142   return -1;
143 }
144
145 static int handle_mov_to_cr0_64compat(struct guest_info * info, struct x86_instr * dec_instr) {
146   PrintError("64 bit compatibility mode move to CR0 not implemented\n");
147   return -1;
148 }
149
150
151 static int handle_mov_to_cr0_32(struct guest_info * info, struct x86_instr * dec_instr) {
152
153   // 32 bit registers
154   struct cr0_32 *real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
155   struct cr0_32 *new_cr0= (struct cr0_32 *)(dec_instr->src_operand.operand);
156   
157   PrintDebug("OperandVal = %x, length=%d\n", *(uint_t *)new_cr0, dec_instr->src_operand.size);
158   
159   
160   PrintDebug("Old CR0=%x\n", *(uint_t *)real_cr0);
161   *real_cr0 = *new_cr0;
162   
163   
164   if (info->shdw_pg_mode == SHADOW_PAGING) {
165     struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
166     
167     PrintDebug("Old Shadow CR0=%x\n", *(uint_t *)shadow_cr0);   
168     
169     real_cr0->et = 1;
170     
171     *shadow_cr0 = *new_cr0;
172     shadow_cr0->et = 1;
173     
174     if (v3_get_mem_mode(info) == VIRTUAL_MEM) {
175       struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
176       PrintDebug("Setting up Shadow Page Table\n");
177       info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
178     } else  {
179       info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
180       real_cr0->pg = 1;
181     }
182     
183     PrintDebug("New Shadow CR0=%x\n",*(uint_t *)shadow_cr0);
184   }
185   PrintDebug("New CR0=%x\n", *(uint_t *)real_cr0);
186   
187   return 0;
188 }
189
190
191
192
193 static int handle_clts(struct guest_info * info, struct x86_instr * dec_instr) {
194   // CLTS
195   struct cr0_32 *real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
196   
197   real_cr0->ts = 0;
198   
199   if (info->shdw_pg_mode == SHADOW_PAGING) {
200     struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
201     shadow_cr0->ts = 0;
202   }
203   return 0;
204 }
205
206
207 static int handle_lmsw(struct guest_info * info, struct x86_instr * dec_instr) {
208  struct cr0_real *real_cr0  = (struct cr0_real*)&(info->ctrl_regs.cr0);
209  struct cr0_real *new_cr0 = (struct cr0_real *)(dec_instr->src_operand.operand);        
210  uchar_t new_cr0_val;
211  
212  PrintDebug("LMSW\n");
213  
214  new_cr0_val = (*(char*)(new_cr0)) & 0x0f;
215  
216  PrintDebug("OperandVal = %x\n", new_cr0_val);
217  
218  PrintDebug("Old CR0=%x\n", *(uint_t *)real_cr0);       
219  *(uchar_t*)real_cr0 &= 0xf0;
220  *(uchar_t*)real_cr0 |= new_cr0_val;
221  PrintDebug("New CR0=%x\n", *(uint_t *)real_cr0);       
222  
223  
224  if (info->shdw_pg_mode == SHADOW_PAGING) {
225    struct cr0_real * shadow_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
226    
227    PrintDebug(" Old Shadow CR0=%x\n", *(uint_t *)shadow_cr0);   
228    *(uchar_t*)shadow_cr0 &= 0xf0;
229    *(uchar_t*)shadow_cr0 |= new_cr0_val;
230    PrintDebug("New Shadow CR0=%x\n", *(uint_t *)shadow_cr0);    
231  }
232  return 0;
233 }
234
235
236
237
238
239
240
241
242
243
244 // First attempt = 253 lines
245 // current = 51 lines
246 int v3_handle_cr0_read(struct guest_info * info) {
247   uchar_t instr[15];
248   int ret;
249   struct x86_instr dec_instr;
250
251   if (info->mem_mode == PHYSICAL_MEM) { 
252     ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
253   } else { 
254     ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
255   }
256
257   /* The IFetch will already have faulted in the necessary bytes for the full instruction
258      if (ret != 15) {
259      // I think we should inject a GPF into the guest
260      PrintError("Could not read instruction (ret=%d)\n", ret);
261      return -1;
262      }
263   */
264
265   if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
266     PrintError("Could not decode instruction\n");
267     return -1;
268   }
269   
270   if (v3_opcode_cmp(V3_OPCODE_MOVCR2, (const uchar_t *)(dec_instr.opcode)) == 0) {
271     struct cr0_32 * virt_cr0 = (struct cr0_32 *)(dec_instr.dst_operand.operand);
272     struct cr0_32 * real_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
273     
274     PrintDebug("MOVCR2\n");
275     PrintDebug("CR0 at 0x%p\n", (void *)real_cr0);
276
277     if (info->shdw_pg_mode == SHADOW_PAGING) {
278       *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
279     } else {
280       *virt_cr0 = *real_cr0;
281     }
282     
283     PrintDebug("real CR0: %x\n", *(uint_t*)real_cr0);
284     PrintDebug("returned CR0: %x\n", *(uint_t*)virt_cr0);
285   } else if (v3_opcode_cmp(V3_OPCODE_SMSW, (const uchar_t *)(dec_instr.opcode)) == 0) {
286     struct cr0_real *real_cr0= (struct cr0_real*)&(info->ctrl_regs.cr0);
287     struct cr0_real *virt_cr0 = (struct cr0_real *)(dec_instr.dst_operand.operand);
288     char cr0_val = *(char*)real_cr0 & 0x0f;
289     
290     PrintDebug("SMSW\n");
291
292     PrintDebug("CR0 at 0x%p\n", real_cr0);
293
294     *(char *)virt_cr0 &= 0xf0;
295     *(char *)virt_cr0 |= cr0_val;
296     
297   } else {
298     PrintError("Unhandled opcode in handle_cr0_read\n");
299     return -1;
300   }
301
302   info->rip += dec_instr.instr_length;
303
304   return 0;
305 }
306
307
308
309
310 // First Attempt = 256 lines
311 // current = 65 lines
312 int v3_handle_cr3_write(struct guest_info * info) {
313   int ret;
314   uchar_t instr[15];
315   struct x86_instr dec_instr;
316
317   if (info->mem_mode == PHYSICAL_MEM) { 
318     ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
319   } else { 
320     ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
321   }
322
323   if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
324     PrintError("Could not decode instruction\n");
325     return -1;
326   }
327
328   if (v3_opcode_cmp(V3_OPCODE_MOV2CR, (const uchar_t *)(dec_instr.opcode)) == 0) {
329     PrintDebug("MOV2CR3\n");
330
331     if (info->mem_mode == PHYSICAL_MEM) {
332       // All we do is update the guest CR3
333
334       if (info->cpu_mode == LONG) {
335         struct cr3_64 * new_cr3 = (struct cr3_64 *)(dec_instr.src_operand.operand);
336         struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->shdw_pg_state.guest_cr3);
337         *guest_cr3 = *new_cr3;
338       } else {
339         struct cr3_32 * new_cr3 = (struct cr3_32 *)(dec_instr.src_operand.operand);
340         struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
341         *guest_cr3 = *new_cr3;
342       }
343
344     } else {
345
346       switch (info->cpu_mode) {
347       case PROTECTED:
348         if (handle_mov_to_cr3_32(info, &dec_instr) == -1) {
349           return -1;
350         }
351       case PROTECTED_PAE:
352         if (handle_mov_to_cr3_32pae(info, &dec_instr) == -1) {
353           return -1;
354         }
355       case LONG:
356         if (handle_mov_to_cr3_64(info, &dec_instr) == -1) {
357           return -1;
358         }
359       case LONG_32_COMPAT:
360         if (handle_mov_to_cr3_64compat(info, &dec_instr) == -1) {
361           return -1;
362         }
363       default:
364         PrintError("Unhandled CPU mode: %d\n", info->cpu_mode);
365         return -1;
366       }
367     }
368   } else {
369     PrintError("Unhandled opcode in handle_cr3_write\n");
370     return -1;
371   }
372
373   info->rip += dec_instr.instr_length;
374
375   return 0;
376 }
377
378
379
380
381
382
383
384 static int handle_mov_to_cr3_32(struct guest_info * info, struct x86_instr * dec_instr) {
385   PrintDebug("CR3 at 0x%p\n", &(info->ctrl_regs.cr3));
386
387   if (info->shdw_pg_mode == SHADOW_PAGING) {
388     struct cr3_32 * new_cr3 = (struct cr3_32 *)(dec_instr->src_operand.operand);        
389     struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
390     struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
391     int cached = 0;
392     
393     
394     PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n", 
395                *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
396     
397     
398     
399     cached = v3_cache_page_tables32(info, (addr_t)V3_PAddr((void *)(addr_t)CR3_TO_PDE32((void *)*(addr_t *)new_cr3)));
400     
401     if (cached == -1) {
402       PrintError("CR3 Cache failed\n");
403       return -1;
404     } else if (cached == 0) {
405       addr_t shadow_pt;
406       
407       if(info->mem_mode == VIRTUAL_MEM) {
408         PrintDebug("New CR3 is different - flushing shadow page table %p\n", shadow_cr3 );
409         delete_page_tables_32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
410       }
411       
412       shadow_pt =  v3_create_new_shadow_pt();
413       
414       shadow_cr3->pdt_base_addr = (addr_t)V3_PAddr((void *)(addr_t)PD32_BASE_ADDR(shadow_pt));
415       PrintDebug( "Created new shadow page table %p\n", (void *)(addr_t)shadow_cr3->pdt_base_addr );
416       //PrintDebugPageTables( (pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3) );
417       
418       
419     } else {
420       PrintDebug("Reusing cached shadow Page table\n");
421     }
422     
423     
424     shadow_cr3->pwt = new_cr3->pwt;
425     shadow_cr3->pcd = new_cr3->pcd;
426     
427     // What the hell...
428     *guest_cr3 = *new_cr3;
429     
430     PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n", 
431                *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
432     
433     if (info->mem_mode == VIRTUAL_MEM) {
434       // If we aren't in paged mode then we have to preserve the identity mapped CR3
435       info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
436     }
437   }
438   return 0;
439 }
440
441
442 static int handle_mov_to_cr3_32pae(struct guest_info * info, struct x86_instr * dec_instr) {
443   PrintError("32 Bit PAE mode Mov to CR3 not implemented\n");
444   return -1;
445 }
446
447 static int handle_mov_to_cr3_64(struct guest_info * info, struct x86_instr * dec_instr) {
448   PrintError("Long mode Mov to CR3 not implemented\n");
449   return -1;
450 }
451
452 static int handle_mov_to_cr3_64compat(struct guest_info * info, struct x86_instr * dec_instr) {
453   PrintError("Long compatiblity mode move to CR3 not implemented\n");
454   return -1;
455 }
456
457
458
459 // first attempt = 156 lines
460 // current = 36 lines
461 int v3_handle_cr3_read(struct guest_info * info) {
462   uchar_t instr[15];
463   int ret;
464   struct x86_instr dec_instr;
465
466   if (info->mem_mode == PHYSICAL_MEM) { 
467     ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
468   } else { 
469     ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
470   }
471
472   /* The IFetch will already have faulted in the necessary bytes for the full instruction
473      if (ret != 15) {
474      // I think we should inject a GPF into the guest
475      PrintError("Could not read instruction (ret=%d)\n", ret);
476      return -1;
477      }
478   */
479
480   if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
481     PrintError("Could not decode instruction\n");
482     return -1;
483   }
484
485   if (v3_opcode_cmp(V3_OPCODE_MOVCR2, (const uchar_t *)(dec_instr.opcode)) == 0) {
486     PrintDebug("MOVCR32\n");
487     struct cr3_32 * virt_cr3 = (struct cr3_32 *)(dec_instr.dst_operand.operand);
488
489     PrintDebug("CR3 at 0x%p\n", &(info->ctrl_regs.cr3));
490
491     if (info->shdw_pg_mode == SHADOW_PAGING) {
492       *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
493     } else {
494       *virt_cr3 = *(struct cr3_32 *)&(info->ctrl_regs.cr3);
495     }
496   } else {
497     PrintError("Unhandled opcode in handle_cr3_read\n");
498     return -1;
499   }
500
501   info->rip += dec_instr.instr_length;
502
503   return 0;
504 }
505
506 int v3_handle_cr4_read(struct guest_info * info) {
507   PrintError("CR4 Read not handled\n");
508   return -1;
509 }
510
511 int v3_handle_cr4_write(struct guest_info * info) {
512   uchar_t instr[15];
513   int ret;
514   struct x86_instr dec_instr;
515
516   if (info->mem_mode == PHYSICAL_MEM) { 
517     ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
518   } else { 
519     ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
520   }
521
522   if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
523     PrintError("Could not decode instruction\n");
524     return -1;
525   }
526
527   if (v3_opcode_cmp(V3_OPCODE_MOV2CR, (const uchar_t *)(dec_instr.opcode)) != 0) {
528     PrintError("Invalid opcode in write to CR4\n");
529     return -1;
530   }
531
532   if ((info->cpu_mode == PROTECTED) || (info->cpu_mode == PROTECTED_PAE)) {
533     struct cr4_32 * new_cr4 = (struct cr4_32 *)(dec_instr.src_operand.operand);
534     struct cr4_32 * old_cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
535     
536     PrintDebug("OperandVal = %x, length = %d\n", *(uint_t *)new_cr4, dec_instr.src_operand.size);
537     PrintDebug("Old CR4=%x\n", *(uint_t *)old_cr4);
538
539
540
541
542     if ((info->shdw_pg_mode == SHADOW_PAGING) && 
543         (v3_get_mem_mode(info) == PHYSICAL_MEM)) {
544
545       if ((old_cr4->pae == 0) && (new_cr4->pae == 1)) {
546         PrintDebug("Creating PAE passthrough tables\n");
547
548         // Delete the old 32 bit direct map page tables
549         delete_page_tables_32((pde32_t *)V3_VAddr((void *)(info->direct_map_pt)));
550
551         // create 32 bit PAE direct map page table
552         info->direct_map_pt = (addr_t)V3_PAddr(create_passthrough_pts_32PAE(info));
553
554         // reset cr3 to new page tables
555         info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
556
557       } else if ((old_cr4->pae == 1) && (new_cr4->pae == 0)) {
558         // Create passthrough standard 32bit pagetables
559         return -1;
560       }
561     }
562
563     *old_cr4 = *new_cr4;
564     PrintDebug("New CR4=%x\n", *(uint_t *)old_cr4);
565
566   } else {
567     return -1;
568   }
569
570   info->rip += dec_instr.instr_length;
571   return 0;
572 }
573
574
575 int v3_handle_efer_read(uint_t msr, struct v3_msr * dst, void * priv_data) {
576   PrintError("EFER Read not handled\n");
577   return -1;
578 }
579
580
581 int v3_handle_efer_write(uint_t msr, struct v3_msr src, void * priv_data) {
582   struct guest_info * info = (struct guest_info *)(priv_data);
583   struct efer_64 * new_efer = (struct efer_64 *)&(src.value);
584   struct efer_64 * old_efer = (struct efer_64 *)&(info->ctrl_regs.efer);
585
586   PrintDebug("Old EFER=%p\n", (void *)*(addr_t*)(old_efer));
587
588   if ((info->shdw_pg_mode == SHADOW_PAGING) && 
589       (v3_get_mem_mode(info) == PHYSICAL_MEM)) {
590     
591     if ((old_efer->lme == 0) && (new_efer->lme == 1)) {
592       PrintDebug("Transition to longmode\n");
593       PrintDebug("Creating Passthrough 64 bit page tables\n");
594       
595       // Delete the old 32 bit direct map page tables
596       /* 
597        * JRL BUG? 
598        * Will these page tables always be in PAE format?? 
599        */
600       PrintDebug("Deleting old PAE Page tables\n");
601       PrintError("JRL BUG?: Will the old page tables always be in PAE format??\n");
602       delete_page_tables_32PAE((pdpe32pae_t *)V3_VAddr((void *)(info->direct_map_pt)));
603       
604       // create 64 bit direct map page table
605       info->direct_map_pt = (addr_t)V3_PAddr(create_passthrough_pts_64(info));
606       
607       // reset cr3 to new page tables
608       info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
609       
610
611       // Does this mean we will have to fully virtualize a shadow  EFER?? (yes it does)
612       ((struct efer_64 *)&(info->guest_efer.value))->lme = 1;
613
614       new_efer->lma = 1;
615       
616     } else if ((old_efer->lme == 1) && (new_efer->lme == 0)) {
617       // transition out of long mode
618       //((struct efer_64 *)&(info->guest_efer.value))->lme = 0;
619       //((struct efer_64 *)&(info->guest_efer.value))->lma = 0;
620       
621       return -1;
622     }
623
624     *old_efer = *new_efer;
625     PrintDebug("New EFER=%p\n", (void *)*(addr_t *)(old_efer));
626   } else {
627     return -1;
628   }
629
630   info->rip += 2; // WRMSR/RDMSR are two byte operands
631
632   return 0;
633 }