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.


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