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.


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