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.


fixed debug formats
[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 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_mem_mode(info) == VIRTUAL_MEM) {
122             
123             struct efer_64 * guest_efer  = (struct efer_64 *)&(info->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             if (v3_activate_passthrough_pt(info) == -1) {
146                 PrintError("Failed to activate passthrough page tables\n");
147                 return -1;
148             }
149         }
150     }
151     
152     
153     PrintDebug("New Guest CR0=%x\n",*(uint_t *)guest_cr0);  
154     PrintDebug("New CR0=%x\n", *(uint_t *)shadow_cr0);
155     
156     return 0;
157 }
158
159
160
161
162 static int handle_clts(struct guest_info * info, struct x86_instr * dec_instr) {
163     // CLTS
164     struct cr0_32 * real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
165     
166     real_cr0->ts = 0;
167     
168     if (info->shdw_pg_mode == SHADOW_PAGING) {
169         struct cr0_32 * guest_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
170         guest_cr0->ts = 0;
171     }
172     return 0;
173 }
174
175
176 static int handle_lmsw(struct guest_info * info, struct x86_instr * dec_instr) {
177     struct cr0_real * real_cr0  = (struct cr0_real *)&(info->ctrl_regs.cr0);
178     // XED is a mess, and basically reverses the operand order for an LMSW
179     struct cr0_real * new_cr0 = (struct cr0_real *)(dec_instr->dst_operand.operand);    
180     uchar_t new_cr0_val;
181     
182     PrintDebug("LMSW\n");
183     
184     new_cr0_val = (*(char*)(new_cr0)) & 0x0f;
185     
186     PrintDebug("OperandVal = %x\n", new_cr0_val);
187     
188     // We can just copy the new value through
189     // we don't need to virtualize the lower 4 bits
190     PrintDebug("Old CR0=%x\n", *(uint_t *)real_cr0);    
191     *(uchar_t*)real_cr0 &= 0xf0;
192     *(uchar_t*)real_cr0 |= new_cr0_val;
193     PrintDebug("New CR0=%x\n", *(uint_t *)real_cr0);    
194     
195     
196     // If Shadow paging is enabled we push the changes to the virtualized copy of cr0
197     if (info->shdw_pg_mode == SHADOW_PAGING) {
198         struct cr0_real * guest_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
199         
200         PrintDebug("Old Guest CR0=%x\n", *(uint_t *)guest_cr0); 
201         *(uchar_t*)guest_cr0 &= 0xf0;
202         *(uchar_t*)guest_cr0 |= new_cr0_val;
203         PrintDebug("New Guest CR0=%x\n", *(uint_t *)guest_cr0); 
204     }
205     return 0;
206 }
207
208
209
210
211
212 // First attempt = 253 lines
213 // current = 51 lines
214 int v3_handle_cr0_read(struct guest_info * info) {
215     uchar_t instr[15];
216     int ret;
217     struct x86_instr dec_instr;
218     
219     if (info->mem_mode == PHYSICAL_MEM) { 
220         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
221     } else { 
222         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
223     }
224     
225     
226     if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
227         PrintError("Could not decode instruction\n");
228         return -1;
229     }
230     
231     if (dec_instr.op_type == V3_OP_MOVCR2) {
232         PrintDebug("MOVCR2 (mode=%s)\n", v3_cpu_mode_to_str(info->cpu_mode));
233
234         if ((v3_get_cpu_mode(info) == LONG) || 
235             (v3_get_cpu_mode(info) == LONG_32_COMPAT)) {
236             struct cr0_64 * dst_reg = (struct cr0_64 *)(dec_instr.dst_operand.operand);
237         
238             if (info->shdw_pg_mode == SHADOW_PAGING) {
239                 struct cr0_64 * guest_cr0 = (struct cr0_64 *)&(info->shdw_pg_state.guest_cr0);
240                 *dst_reg = *guest_cr0;
241             } else {
242                 struct cr0_64 * shadow_cr0 = (struct cr0_64 *)&(info->ctrl_regs.cr0);
243                 *dst_reg = *shadow_cr0;
244             }
245
246             PrintDebug("returned CR0: %p\n", (void *)*(addr_t *)dst_reg);
247         } else {
248             struct cr0_32 * dst_reg = (struct cr0_32 *)(dec_instr.dst_operand.operand);
249         
250             if (info->shdw_pg_mode == SHADOW_PAGING) {
251                 struct cr0_32 * guest_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
252                 *dst_reg = *guest_cr0;
253             } else {
254                 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
255                 *dst_reg = *shadow_cr0;
256             }
257
258             PrintDebug("returned CR0: %x\n", *(uint_t*)dst_reg);
259         }
260
261     } else if (dec_instr.op_type == V3_OP_SMSW) {
262         struct cr0_real * shadow_cr0 = (struct cr0_real *)&(info->ctrl_regs.cr0);
263         struct cr0_real * dst_reg = (struct cr0_real *)(dec_instr.dst_operand.operand);
264         char cr0_val = *(char*)shadow_cr0 & 0x0f;
265         
266         PrintDebug("SMSW\n");
267         
268         // The lower 4 bits of the guest/shadow CR0 are mapped through
269         // We can treat nested and shadow paging the same here
270         *(char *)dst_reg &= 0xf0;
271         *(char *)dst_reg |= cr0_val;
272         
273     } else {
274         PrintError("Unhandled opcode in handle_cr0_read\n");
275         return -1;
276     }
277     
278     info->rip += dec_instr.instr_length;
279
280     return 0;
281 }
282
283
284
285
286 // First Attempt = 256 lines
287 // current = 65 lines
288 int v3_handle_cr3_write(struct guest_info * info) {
289     int ret;
290     uchar_t instr[15];
291     struct x86_instr dec_instr;
292     
293     if (info->mem_mode == PHYSICAL_MEM) { 
294         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
295     } else { 
296         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
297     }
298     
299     if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
300         PrintError("Could not decode instruction\n");
301         return -1;
302     }
303     
304     if (dec_instr.op_type == V3_OP_MOV2CR) {
305         PrintDebug("MOV2CR3 (cpu_mode=%s)\n", v3_cpu_mode_to_str(info->cpu_mode));
306         
307         if (info->shdw_pg_mode == SHADOW_PAGING) {
308             PrintDebug("Old Shadow CR3=%p; Old Guest CR3=%p\n", 
309                        (void *)(addr_t)(info->ctrl_regs.cr3), 
310                        (void*)(addr_t)(info->shdw_pg_state.guest_cr3));
311             
312             
313             // We update the guest CR3    
314             if (info->cpu_mode == LONG) {
315                 struct cr3_64 * new_cr3 = (struct cr3_64 *)(dec_instr.src_operand.operand);
316                 struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->shdw_pg_state.guest_cr3);
317                 *guest_cr3 = *new_cr3;
318             } else {
319                 struct cr3_32 * new_cr3 = (struct cr3_32 *)(dec_instr.src_operand.operand);
320                 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
321                 *guest_cr3 = *new_cr3;
322             }
323             
324             // If Paging is enabled in the guest then we need to change the shadow page tables
325             if (info->mem_mode == VIRTUAL_MEM) {
326                 if (v3_activate_shadow_pt(info) == -1) {
327                     PrintError("Failed to activate 32 bit shadow page table\n");
328                     return -1;
329                 }
330             } 
331             
332             PrintDebug("New Shadow CR3=%p; New Guest CR3=%p\n", 
333                        (void *)(addr_t)(info->ctrl_regs.cr3), 
334                        (void*)(addr_t)(info->shdw_pg_state.guest_cr3));
335             
336         } else if (info->shdw_pg_mode == NESTED_PAGING) {
337             
338             // This is just a passthrough operation which we probably don't need here
339             if (info->cpu_mode == LONG) {
340                 struct cr3_64 * new_cr3 = (struct cr3_64 *)(dec_instr.src_operand.operand);
341                 struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->ctrl_regs.cr3);
342                 *guest_cr3 = *new_cr3;
343             } else {
344                 struct cr3_32 * new_cr3 = (struct cr3_32 *)(dec_instr.src_operand.operand);
345                 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
346                 *guest_cr3 = *new_cr3;
347             }
348             
349         }
350     } else {
351         PrintError("Unhandled opcode in handle_cr3_write\n");
352         return -1;
353     }
354     
355     info->rip += dec_instr.instr_length;
356     
357     return 0;
358 }
359
360
361
362 // first attempt = 156 lines
363 // current = 36 lines
364 int v3_handle_cr3_read(struct guest_info * info) {
365     uchar_t instr[15];
366     int ret;
367     struct x86_instr dec_instr;
368     
369     if (info->mem_mode == PHYSICAL_MEM) { 
370         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
371     } else { 
372         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
373     }
374     
375     if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
376         PrintError("Could not decode instruction\n");
377         return -1;
378     }
379     
380     if (dec_instr.op_type == V3_OP_MOVCR2) {
381         PrintDebug("MOVCR32 (mode=%s)\n", v3_cpu_mode_to_str(info->cpu_mode));
382         
383         if (info->shdw_pg_mode == SHADOW_PAGING) {
384             
385             if ((v3_get_cpu_mode(info) == LONG) || 
386                 (v3_get_cpu_mode(info) == LONG_32_COMPAT)) {
387                 struct cr3_64 * dst_reg = (struct cr3_64 *)(dec_instr.dst_operand.operand);
388                 struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->shdw_pg_state.guest_cr3);
389                 *dst_reg = *guest_cr3;
390             } else {
391                 struct cr3_32 * dst_reg = (struct cr3_32 *)(dec_instr.dst_operand.operand);
392                 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
393                 *dst_reg = *guest_cr3;
394             }
395             
396         } else if (info->shdw_pg_mode == NESTED_PAGING) {
397             
398             // This is just a passthrough operation which we probably don't need here
399             if ((v3_get_cpu_mode(info) == LONG) || 
400                 (v3_get_cpu_mode(info) == LONG_32_COMPAT)) {
401                 struct cr3_64 * dst_reg = (struct cr3_64 *)(dec_instr.dst_operand.operand);
402                 struct cr3_64 * guest_cr3 = (struct cr3_64 *)&(info->ctrl_regs.cr3);
403                 *dst_reg = *guest_cr3;
404             } else {
405                 struct cr3_32 * dst_reg = (struct cr3_32 *)(dec_instr.dst_operand.operand);
406                 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
407                 *dst_reg = *guest_cr3;
408             }
409         }
410         
411     } else {
412         PrintError("Unhandled opcode in handle_cr3_read\n");
413         return -1;
414     }
415     
416     info->rip += dec_instr.instr_length;
417     
418     return 0;
419 }
420
421
422 // We don't need to virtualize CR4, all we need is to detect the activation of PAE
423 int v3_handle_cr4_read(struct guest_info * info) {
424     //  PrintError("CR4 Read not handled\n");
425     // Do nothing...
426     return 0;
427 }
428
429 int v3_handle_cr4_write(struct guest_info * info) {
430     uchar_t instr[15];
431     int ret;
432     int flush_tlb=0;
433     struct x86_instr dec_instr;
434     v3_vm_cpu_mode_t cpu_mode = v3_get_cpu_mode(info);
435     
436     if (info->mem_mode == PHYSICAL_MEM) { 
437         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
438     } else { 
439         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
440     }
441     
442     if (v3_decode(info, (addr_t)instr, &dec_instr) == -1) {
443         PrintError("Could not decode instruction\n");
444         return -1;
445     }
446     
447     if (dec_instr.op_type != V3_OP_MOV2CR) {
448         PrintError("Invalid opcode in write to CR4\n");
449         return -1;
450     }
451     
452     // Check to see if we need to flush the tlb
453     
454     if (v3_get_mem_mode(info) == VIRTUAL_MEM) { 
455         struct cr4_32 * new_cr4 = (struct cr4_32 *)(dec_instr.src_operand.operand);
456         struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
457         
458         // if pse, pge, or pae have changed while PG (in any mode) is on
459         // the side effect is a TLB flush, which means we need to
460         // toss the current shadow page tables too
461         //
462         // 
463         // TODO - PAE FLAG needs to be special cased
464         if ((cr4->pse != new_cr4->pse) || 
465             (cr4->pge != new_cr4->pge) || 
466             (cr4->pae != new_cr4->pae)) { 
467             PrintDebug("Handling PSE/PGE/PAE -> TLBFlush case, flag set\n");
468             flush_tlb=1;
469             
470         }
471     }
472     
473
474     if ((cpu_mode == PROTECTED) || (cpu_mode == PROTECTED_PAE)) {
475         struct cr4_32 * new_cr4 = (struct cr4_32 *)(dec_instr.src_operand.operand);
476         struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
477         
478         PrintDebug("OperandVal = %x, length = %d\n", *(uint_t *)new_cr4, dec_instr.src_operand.size);
479         PrintDebug("Old CR4=%x\n", *(uint_t *)cr4);
480         
481         if ((info->shdw_pg_mode == SHADOW_PAGING)) { 
482             if (v3_get_mem_mode(info) == PHYSICAL_MEM) {
483                 
484                 if ((cr4->pae == 0) && (new_cr4->pae == 1)) {
485                     PrintDebug("Creating PAE passthrough tables\n");
486                     
487                     // Delete the old 32 bit direct map page tables
488                     delete_page_tables_32((pde32_t *)V3_VAddr((void *)(info->direct_map_pt)));
489                     
490                     // create 32 bit PAE direct map page table
491                     info->direct_map_pt = (addr_t)V3_PAddr((void *)v3_create_direct_passthrough_pts(info));
492                     
493                     // reset cr3 to new page tables
494                     info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
495                     
496                 } else if ((cr4->pae == 1) && (new_cr4->pae == 0)) {
497                     // Create passthrough standard 32bit pagetables
498                     return -1;
499                 } 
500             }
501         }
502         
503         *cr4 = *new_cr4;
504         PrintDebug("New CR4=%x\n", *(uint_t *)cr4);
505         
506     } else if ((cpu_mode == LONG) || (cpu_mode == LONG_32_COMPAT)) {
507         struct cr4_64 * new_cr4 = (struct cr4_64 *)(dec_instr.src_operand.operand);
508         struct cr4_64 * cr4 = (struct cr4_64 *)&(info->ctrl_regs.cr4);
509         
510         PrintDebug("Old CR4=%p\n", (void *)*(addr_t *)cr4);
511         PrintDebug("New CR4=%p\n", (void *)*(addr_t *)new_cr4);
512         
513         if (new_cr4->pae == 0) {
514             // cannot turn off PAE in long mode GPF the guest
515             PrintError("Cannot disable PAE in long mode, sending GPF\n");
516             return -1;
517         }
518         
519         *cr4 = *new_cr4;
520         
521     } else {
522         PrintError("CR4 write not supported in CPU_MODE: %s\n", v3_cpu_mode_to_str(cpu_mode));
523         return -1;
524     }
525     
526     
527     if (flush_tlb) {
528         PrintDebug("Handling PSE/PGE/PAE -> TLBFlush (doing flush now!)\n");
529         if (v3_activate_shadow_pt(info) == -1) {
530             PrintError("Failed to activate shadow page tables when emulating TLB flush in handling cr4 write\n");
531             return -1;
532         }
533     }
534     
535     
536     info->rip += dec_instr.instr_length;
537     return 0;
538 }
539
540
541 int v3_handle_efer_read(uint_t msr, struct v3_msr * dst, void * priv_data) {
542     struct guest_info * info = (struct guest_info *)(priv_data);
543     PrintDebug("EFER Read HI=%x LO=%x\n", info->guest_efer.hi, info->guest_efer.lo);
544     
545     dst->value = info->guest_efer.value;
546     
547     info->rip += 2; // WRMSR/RDMSR are two byte operands
548     return 0;
549 }
550
551
552
553 // TODO: this is a disaster we need to clean this up...
554 int v3_handle_efer_write(uint_t msr, struct v3_msr src, void * priv_data) {
555     struct guest_info * info = (struct guest_info *)(priv_data);
556     //struct efer_64 * new_efer = (struct efer_64 *)&(src.value);
557     struct efer_64 * shadow_efer = (struct efer_64 *)&(info->ctrl_regs.efer);
558     struct v3_msr * guest_efer = &(info->guest_efer);
559     
560     PrintDebug("EFER Write\n");
561     PrintDebug("EFER Write Values: HI=%x LO=%x\n", src.hi, src.lo);
562     //PrintDebug("Old EFER=%p\n", (void *)*(addr_t*)(shadow_efer));
563     
564     // We virtualize the guests efer to hide the SVME and LMA bits
565     guest_efer->value = src.value;
566     
567     
568     // Enable/Disable Syscall
569     shadow_efer->sce = src.value & 0x1;
570     
571     
572     // We have to handle long mode writes....
573     
574     /* 
575        if ((info->shdw_pg_mode == SHADOW_PAGING) && 
576        (v3_get_mem_mode(info) == PHYSICAL_MEM)) {
577        
578        if ((shadow_efer->lme == 0) && (new_efer->lme == 1)) {
579        PrintDebug("Transition to longmode\n");
580        PrintDebug("Creating Passthrough 64 bit page tables\n");
581        
582        // Delete the old 32 bit direct map page tables
583        
584        PrintDebug("Deleting old PAE Page tables\n");
585        PrintError("JRL BUG?: Will the old page tables always be in PAE format??\n");
586        delete_page_tables_32PAE((pdpe32pae_t *)V3_VAddr((void *)(info->direct_map_pt)));
587        
588        // create 64 bit direct map page table
589        info->direct_map_pt = (addr_t)V3_PAddr(create_passthrough_pts_64(info));
590        
591        // reset cr3 to new page tables
592        info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
593        
594        // We mark the Long Mode active  because we have paging enabled
595        // We do this in new_efer because we copy the msr in full below
596        // new_efer->lma = 1;
597        
598        } else if ((shadow_efer->lme == 1) && (new_efer->lme == 0)) {
599        // transition out of long mode
600        //((struct efer_64 *)&(info->guest_efer.value))->lme = 0;
601        //((struct efer_64 *)&(info->guest_efer.value))->lma = 0;
602        
603        return -1;
604        }
605        
606        // accept all changes to the efer, but make sure that the SVME bit is set... (SVM specific)
607        *shadow_efer = *new_efer;
608        shadow_efer->svme = 1;
609        
610        
611        
612        PrintDebug("New EFER=%p\n", (void *)*(addr_t *)(shadow_efer));
613        } else {
614        PrintError("Write to EFER in NESTED_PAGING or VIRTUAL_MEM mode not supported\n");
615        // Should probably just check for a long mode transition, and bomb out if it is
616        return -1;
617        }
618     */
619     info->rip += 2; // WRMSR/RDMSR are two byte operands
620     
621     return 0;
622 }