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.


ugg
[palacios.git] / palacios / src / palacios / vmm_ctrl_regs.c
1 #include <palacios/vmm_mem.h>
2 #include <palacios/vmm.h>
3 #include <palacios/vmcb.h>
4 #include <palacios/vmm_decoder.h>
5 #include <palacios/vm_guest_mem.h>
6 #include <palacios/vmm_ctrl_regs.h>
7
8
9
10 extern void SerialMemDump(unsigned char *start, int n);
11
12
13 /* Segmentation is a problem here...
14  *
15  * When we get a memory operand, presumably we use the default segment (which is?) 
16  * unless an alternate segment was specfied in the prefix...
17  */
18
19
20 int handle_cr0_write(struct guest_info * info) {
21   char instr[15];
22   
23   
24   switch (info->cpu_mode) { 
25   case REAL: 
26     {
27       int index = 0;
28       int ret;
29       
30       PrintDebug("Real Mode write to CR0 at linear guest pa 0x%x\n",get_addr_linear(info,info->rip,&(info->segments.cs)));
31
32       PrintV3Segments(&(info->segments));
33
34       // The real rip address is actually a combination of the rip + CS base 
35       ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
36       if (ret != 15) {
37         // I think we should inject a GPF into the guest
38         PrintDebug("Could not read instruction (ret=%d)\n", ret);
39         return -1;
40       }
41
42       while (is_prefix_byte(instr[index])) {
43         switch(instr[index]) {
44         case PREFIX_CS_OVERRIDE:
45         case PREFIX_SS_OVERRIDE:
46         case PREFIX_DS_OVERRIDE:
47         case PREFIX_ES_OVERRIDE:
48         case PREFIX_FS_OVERRIDE:
49         case PREFIX_GS_OVERRIDE:
50           PrintDebug("Segment Override!!\n");
51           return -1;
52           break;
53         default:
54           break;
55         }
56         index++; 
57       }
58
59       if ((instr[index] == cr_access_byte) && 
60           (instr[index + 1] == lmsw_byte) && 
61           (MODRM_REG(instr[index + 2]) == lmsw_reg_byte)) {
62  
63         addr_t first_operand;
64         addr_t second_operand;
65         struct cr0_real *real_cr0;
66         struct cr0_real *new_cr0;
67         operand_type_t addr_type;
68         char new_cr0_val = 0;
69         // LMSW
70         // decode mod/RM
71         index += 2;
72  
73         real_cr0 = (struct cr0_real*)&(info->ctrl_regs.cr0);
74
75         addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
76
77
78         if (addr_type == REG_OPERAND) {
79           new_cr0 = (struct cr0_real *)first_operand;
80         } else if (addr_type == MEM_OPERAND) {
81           addr_t host_addr;
82
83           if (guest_pa_to_host_va(info, first_operand + (info->segments.ds.base << 4), &host_addr) == -1) {
84             // gpf the guest
85             return -1;
86           }
87
88           new_cr0 = (struct cr0_real *)host_addr;
89         } else {
90
91           // error... don't know what to do
92           return -1;
93         }
94                  
95         if ((new_cr0->pe == 1) && (real_cr0->pe == 0)) {
96           info->cpu_mode = PROTECTED;
97         } else if ((new_cr0->pe == 0) && (real_cr0->pe == 1)) {
98           info->cpu_mode = REAL;
99         }
100       
101         new_cr0_val = (*(char*)(new_cr0)) & 0x0f;
102
103
104         if (info->shdw_pg_mode == SHADOW_PAGING) {
105           struct cr0_real * shadow_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
106
107           PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);        
108           /* struct cr0_real is only 4 bits wide, 
109            * so we can overwrite the real_cr0 without worrying about the shadow fields
110            */
111           *(char*)real_cr0 &= 0xf0;
112           *(char*)real_cr0 |= new_cr0_val;
113         
114           *(char*)shadow_cr0 &= 0xf0;
115           *(char*)shadow_cr0 |= new_cr0_val;
116
117
118           PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);        
119         } else {
120           PrintDebug("Old CR0=%x\n", *real_cr0);        
121           // for now we just pass through....
122           *(char*)real_cr0 &= 0xf0;
123           *(char*)real_cr0 |= new_cr0_val;
124
125           PrintDebug("New CR0=%x\n", *real_cr0);        
126         }
127
128
129         info->rip += index;
130
131       } else if ((instr[index] == cr_access_byte) && 
132                  (instr[index + 1] == clts_byte)) {
133         // CLTS
134         PrintDebug("CLTS unhandled in CR0 write\n");
135         return -1;
136
137       } else if ((instr[index] == cr_access_byte) && 
138                  (instr[index + 1] = mov_to_cr_byte)) {
139         addr_t first_operand;
140         addr_t second_operand;
141         struct cr0_32 *real_cr0;
142         struct cr0_32 *new_cr0;
143         operand_type_t addr_type;
144      
145       
146         index += 2;
147  
148         real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
149
150         addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
151
152         if (addr_type != REG_OPERAND) {
153           PrintDebug("Moving to CR0 from non-register operand in CR0 write\n");
154           /* Mov to CR0 Can only be a 32 bit register */
155           // FIX ME
156           return -1;
157         }
158
159         new_cr0 = (struct cr0_32 *)first_operand;
160
161         if (new_cr0->pe == 1) {
162           PrintDebug("Entering Protected Mode\n");
163           info->cpu_mode = PROTECTED;
164         }
165
166         if (new_cr0->pe == 0) { 
167           PrintDebug("Entering Real Mode\n");
168           info->cpu_mode = REAL;
169         }
170           
171
172
173         if ((new_cr0->pg == 1) && (new_cr0->pe == 1)) {
174           PrintDebug("Paging is already turned on in switch to protected mode in CR0 write\n");
175
176           // Actually This appears to be Ok. 
177           // Why shouldn't windows be allowed to switch to real mode whenever it wants to modify its page tables?
178
179           info->mem_mode = VIRTUAL_MEM;
180
181           // GPF the guest??
182           //  return -1;
183         } else if ((new_cr0->pg == 1) && (new_cr0->pe == 0)) {
184           PrintDebug("Will the madness Never End??\n");
185           return -1;
186         }
187         
188
189         if (info->shdw_pg_mode == SHADOW_PAGING) {
190           struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
191         
192           PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);        
193           *real_cr0 = *new_cr0;
194           real_cr0->pg = 1;
195           real_cr0->et = 1;
196
197           *shadow_cr0 = *new_cr0;
198           shadow_cr0->et = 1;
199
200           // Setup the page tables...???
201           if (info->mem_mode == VIRTUAL_MEM) {
202             // If we aren't in paged mode then we have to preserve the identity mapped CR3
203             info->ctrl_regs.cr3 = *(addr_t*)&(info->shdw_pg_state.shadow_cr3);
204           }
205
206           PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);        
207         } else {
208           PrintDebug("Old CR0=%x\n", *real_cr0);        
209           *real_cr0 = *new_cr0;
210           PrintDebug("New CR0=%x\n", *real_cr0);        
211         }
212
213         info->rip += index;
214
215       } else {
216         PrintDebug("Unsupported Instruction\n");
217         // unsupported instruction, UD the guest
218         return -1;
219       }
220
221     } 
222     break;
223  
224   case PROTECTED: 
225     {
226
227       int index = 0;
228       int ret;
229
230       PrintDebug("Protected %s Mode write to CR0 at guest %s linear rip 0x%x\n", 
231                  info->mem_mode == VIRTUAL_MEM ? "Paged" : "",
232                  info->mem_mode == VIRTUAL_MEM ? "virtual" : "",
233                  get_addr_linear(info, info->rip, &(info->segments.cs)));
234
235       // OK, now we will read the instruction
236       // The only difference between PROTECTED and PROTECTED_PG is whether we read
237       // from guest_pa or guest_va
238       if (info->mem_mode == PHYSICAL_MEM) { 
239         // The real rip address is actually a combination of the rip + CS base 
240         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
241       } else { 
242         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
243       }
244         
245
246       if (ret != 15) {
247         // I think we should inject a GPF into the guest
248         PrintDebug("Could not read instruction (ret=%d)\n", ret);
249         return -1;
250       }
251
252
253       while (is_prefix_byte(instr[index])) {
254         switch(instr[index]) {
255         case PREFIX_CS_OVERRIDE:
256         case PREFIX_SS_OVERRIDE:
257         case PREFIX_DS_OVERRIDE:
258         case PREFIX_ES_OVERRIDE:
259         case PREFIX_FS_OVERRIDE:
260         case PREFIX_GS_OVERRIDE:
261           PrintDebug("Segment Override!!\n");
262           return -1;
263           break;
264         default:
265           break;
266         }
267         index++; 
268       }
269
270       /*
271         while (is_prefix_byte(instr[index])) {
272         index++; 
273         }
274       */
275
276       struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
277
278       struct cr0_32 * real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
279
280       if ((instr[index] == cr_access_byte) && 
281           (instr[index + 1] == mov_to_cr_byte)) {
282
283         // MOV to CR0
284     
285         addr_t first_operand;
286         addr_t second_operand;
287         struct cr0_32 *new_cr0;
288         operand_type_t addr_type;
289
290         index += 2;
291  
292         PrintDebug("MovToCR0 instr:\n");
293         PrintTraceMemDump(instr, 15);
294         PrintDebug("EAX=%x\n", *(uint_t*)&(info->vm_regs.rax));
295
296         addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
297
298         if (addr_type != REG_OPERAND) {
299           PrintDebug("Non-register operand in write to CR0\n");
300           return -1;
301         }
302
303         new_cr0 = (struct cr0_32 *)first_operand;
304
305         PrintDebug("first operand=%x\n", *(uint_t *)first_operand);
306
307         if (info->shdw_pg_mode == SHADOW_PAGING) {
308           struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
309
310           if (new_cr0->pg == 1){
311             // This should be new_cr0->pg && !(old_cr->pg), right?
312             // and then a case for turning paging off?
313
314             struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
315
316             info->mem_mode = VIRTUAL_MEM;
317           
318             *shadow_cr0 = *new_cr0;
319             *real_cr0 = *new_cr0;
320             shadow_cr0->et = 1;
321             real_cr0->et = 1;
322
323             //
324             // Activate Shadow Paging
325             //
326             PrintDebug("Turning on paging in the guest\n");
327
328             info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
329           
330
331           } else if (new_cr0->pe == 0) {
332             info->cpu_mode = REAL;
333             info->mem_mode = PHYSICAL_MEM;
334             PrintDebug("Entering Real Mode\n");
335
336             PrintV3CtrlRegs(&(info->ctrl_regs));
337             // reinstate the identity mapped paged tables
338             // But keep the shadow tables around to handle TLB issues.... UGH...
339             //info->shdw_pg_state.shadow_cr3 &= 0x00000fff;
340             //info->shdw_pg_state.shadow_cr3 |= ((addr_t)create_passthrough_pde32_pts(info) & ~0xfff);
341
342             //info->ctrl_regs.cr3 = info->shdw_pg_state.shadow_cr3;
343             info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
344
345             *shadow_cr0 = *new_cr0;
346             *real_cr0 = *new_cr0;
347             real_cr0->pg = 1;
348             shadow_cr0->et = 1;
349             real_cr0->et = 1;
350
351             PrintV3CtrlRegs(&(info->ctrl_regs));
352
353           }
354
355
356         } else {
357           *real_cr0 = *new_cr0;
358         }
359
360         info->rip += index;
361       } else if ((instr[index] == cr_access_byte) &&
362                  (instr[index + 1] == lmsw_byte) &&
363                  (MODRM_REG(instr[index + 2]) == lmsw_reg_byte)) {
364         addr_t first_operand;
365         addr_t second_operand;
366         struct cr0_real *real_cr0;
367         struct cr0_real *new_cr0;
368         operand_type_t addr_type;
369         char new_cr0_val = 0;
370
371         index += 2;
372
373         real_cr0 = (struct cr0_real*)&(info->ctrl_regs.cr0);
374
375         addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
376
377         if (addr_type == REG_OPERAND) {
378           new_cr0 = (struct cr0_real *)first_operand;
379         } else if (addr_type == MEM_OPERAND) {
380           addr_t host_addr;
381           // check segment descriptors....
382
383           /* TODO, TODO, TODO: Lookup segment overrides */
384           struct v3_segment *lmsw_segment = &(info->segments.ds);
385
386           if (info->mem_mode == PHYSICAL_MEM) {
387             if (guest_pa_to_host_va(info, get_addr_linear(info, first_operand, lmsw_segment), &host_addr) == -1) {
388               return -1;
389             }
390           } else {
391             if (guest_va_to_host_va(info, get_addr_linear(info, first_operand, lmsw_segment), &host_addr) == -1) {
392               return -1;
393             }
394           }
395
396           new_cr0 = (struct cr0_real *)host_addr;
397         } else {
398           return -1;
399         }
400
401         
402         if (new_cr0->pe == 0) {
403           // According to the intel manual this it is illegal to use 
404           // lmsw to turn _off_ Protected mode
405           PrintDebug("Cannot switch to real mode with LMSW, unclear what to do\n");
406           return -1;
407         }
408
409         new_cr0_val = (*(char *)(new_cr0)) & 0x0f;
410
411
412         if (info->shdw_pg_mode == SHADOW_PAGING) {
413           struct cr0_real * shadow_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
414
415           PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);        
416           /* struct cr0_real is only 4 bits wide, 
417            * so we can overwrite the real_cr0 without worrying about the shadow fields
418            */
419           *(char*)real_cr0 &= 0xf0;
420           *(char*)real_cr0 |= new_cr0_val;
421         
422           *(char*)shadow_cr0 &= 0xf0;
423           *(char*)shadow_cr0 |= new_cr0_val;
424
425
426           PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
427         } else {
428           PrintDebug("Old CR0=%x\n", *real_cr0);        
429           // for now we just pass through....
430           *(char*)real_cr0 &= 0xf0;
431           *(char*)real_cr0 |= new_cr0_val;
432
433           PrintDebug("New CR0=%x\n", *real_cr0);
434         }
435
436         info->rip += index;
437
438
439       } else if ((instr[index] == 0x0f) &&
440                  (instr[index + 1] == 0x06)) { 
441         // CLTS instruction
442         PrintDebug("CLTS instruction - clearing TS flag of real and shadow CR0\n");
443         shadow_cr0->ts = 0;
444         real_cr0->ts = 0;
445         
446         index+=2;
447         
448         info->rip+=index;
449
450       } else {
451         PrintDebug("Unkown instruction: \n");
452         SerialMemDump(instr,15);
453         return -1;
454       }
455     }
456     break;
457     
458   case PROTECTED_PAE:
459     PrintDebug("Protected PAE Mode write to CR0 is UNIMPLEMENTED\n");
460     return -1;
461
462   case LONG:
463     PrintDebug("Protected Long Mode write to CR0 is UNIMPLEMENTED\n");
464     return -1;
465
466   default: 
467     {
468       PrintDebug("Unknown Mode write to CR0 (info->cpu_mode=0x%x\n)",info->cpu_mode);
469       return -1;
470     }
471     break;
472
473   }
474
475   return 0;
476 }
477
478
479 int handle_cr0_read(struct guest_info * info) {
480   char instr[15];
481
482   switch (info->cpu_mode) { 
483
484   case REAL: 
485     {
486
487       int index = 0;
488       int ret;
489
490       PrintDebug("Real Mode read from CR0 at linear guest pa 0x%x\n",get_addr_linear(info,info->rip,&(info->segments.cs)));
491       PrintV3Segments(&(info->segments));
492
493       // The real rip address is actually a combination of the rip + CS base 
494       ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
495       if (ret != 15) {
496         // I think we should inject a GPF into the guest
497         PrintDebug("Could not read Real Mode instruction (ret=%d)\n", ret);
498         return -1;
499       }
500
501
502       while (is_prefix_byte(instr[index])) {
503         switch(instr[index]) {
504         case PREFIX_CS_OVERRIDE:
505         case PREFIX_SS_OVERRIDE:
506         case PREFIX_DS_OVERRIDE:
507         case PREFIX_ES_OVERRIDE:
508         case PREFIX_FS_OVERRIDE:
509         case PREFIX_GS_OVERRIDE:
510           PrintDebug("Segment Override!!\n");
511           return -1;
512           break;
513         default:
514           break;
515         }
516         index++; 
517       }
518
519       /*
520         while (is_prefix_byte(instr[index])) {
521         index++; 
522         }
523       */
524
525       if ((instr[index] == cr_access_byte) && 
526           (instr[index + 1] == smsw_byte) && 
527           (MODRM_REG(instr[index + 2]) == smsw_reg_byte)) {
528
529         // SMSW (store machine status word)
530
531         addr_t first_operand;
532         addr_t second_operand;
533         struct cr0_real *cr0;
534         operand_type_t addr_type;
535         char cr0_val = 0;
536
537         index += 2;
538       
539         cr0 = (struct cr0_real*)&(info->ctrl_regs.cr0);
540       
541       
542         addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
543       
544         if (addr_type == MEM_OPERAND) {
545           addr_t host_addr;
546         
547           if (guest_pa_to_host_va(info, first_operand + (info->segments.ds.base << 4), &host_addr) == -1) {
548             // gpf the guest
549             PrintDebug("Could not convert guest physical address to host virtual address\n");
550             return -1;
551           }
552         
553           first_operand = host_addr;
554         } else {
555           // Register operand
556           // Should be ok??
557         }
558
559         cr0_val = *(char*)cr0 & 0x0f;
560
561         *(char *)first_operand &= 0xf0;
562         *(char *)first_operand |= cr0_val;
563
564         PrintDebug("index = %d, rip = %x\n", index, (ulong_t)(info->rip));
565         info->rip += index;
566         PrintDebug("new_rip = %x\n", (ulong_t)(info->rip));
567         // success
568
569       } else if ((instr[index] == cr_access_byte) &&
570                  (instr[index+1] == mov_from_cr_byte)) {
571         /* Mov from CR0
572          * This can only take a 32 bit register argument in anything less than 64 bit mode.
573          */
574         addr_t first_operand;
575         addr_t second_operand;
576         operand_type_t addr_type;
577
578         struct cr0_32 * real_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
579
580         index += 2;
581
582         addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
583      
584         struct cr0_32 * virt_cr0 = (struct cr0_32 *)first_operand;
585   
586         if (addr_type != REG_OPERAND) {
587           // invalid opcode to guest
588           PrintDebug("Invalid operand type in mov from CR0\n");
589           return -1;
590         }
591
592         if (info->shdw_pg_mode == SHADOW_PAGING) {
593           *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
594         } else {
595           *virt_cr0 = *real_cr0;
596         }
597
598         info->rip += index;
599
600       } else {
601         PrintDebug("Unknown read instr from CR0\n");
602         return -1;
603       }
604
605     } 
606
607     break;
608
609   case PROTECTED:
610     {
611     
612       int index = 0;
613       int ret;
614
615       PrintDebug("Protected %s Mode read from CR0 at guest %s linear rip 0x%x\n", 
616                  info->mem_mode == VIRTUAL_MEM ? "Paged" : "",
617                  info->mem_mode == VIRTUAL_MEM ? "virtual" : "",
618                  get_addr_linear(info, info->rip, &(info->segments.cs)));
619
620       // We need to read the instruction, which is at CS:IP, but that 
621       // linear address is guest physical without PG and guest virtual with PG
622       if (info->cpu_mode == PHYSICAL_MEM) { 
623         // The real rip address is actually a combination of the rip + CS base 
624         ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
625       } else { 
626         // The real rip address is actually a combination of the rip + CS base 
627         ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
628       }
629
630
631       PrintDebug("Instr (15 bytes) at %x:\n", instr);
632       PrintTraceMemDump((char*)instr, 15);
633
634       if (ret != 15) {
635         // I think we should inject a GPF into the guest
636         PrintDebug("Could not read Protected %s mode instruction (ret=%d)\n", 
637                    info->cpu_mode == VIRTUAL_MEM ? "Paged" : "", ret);
638         return -1;
639       }
640
641
642       while (is_prefix_byte(instr[index])) {
643         switch(instr[index]) {
644         case PREFIX_CS_OVERRIDE:
645         case PREFIX_SS_OVERRIDE:
646         case PREFIX_DS_OVERRIDE:
647         case PREFIX_ES_OVERRIDE:
648         case PREFIX_FS_OVERRIDE:
649         case PREFIX_GS_OVERRIDE:
650           PrintDebug("Segment Override!!\n");
651           return -1;
652           break;
653         default:
654           break;
655         }
656         index++; 
657       }
658
659
660       /*
661         while (is_prefix_byte(instr[index])) {
662         index++; 
663         }
664       */
665
666       if ((instr[index] == cr_access_byte) &&
667           (instr[index+1] == mov_from_cr_byte)) {
668         
669         // MOV from CR0 to register
670
671         addr_t first_operand;
672         addr_t second_operand;
673         operand_type_t addr_type;
674         struct cr0_32 * virt_cr0;
675         struct cr0_32 * real_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
676
677         index += 2;
678
679         addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
680
681         if (addr_type != REG_OPERAND) {
682           PrintDebug("Invalid operand type in mov from CR0\n");
683           return -1;
684         }
685       
686         virt_cr0 = (struct cr0_32 *)first_operand;
687
688         if (info->shdw_pg_mode == SHADOW_PAGING) {
689           *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
690           
691           if (info->mem_mode == PHYSICAL_MEM) {
692             virt_cr0->pg = 0; // clear the pg bit because guest doesn't think it's on
693           }
694
695           PrintDebug("real CR0: %x\n", *(uint_t*)real_cr0);
696           PrintDebug("returned CR0: %x\n", *(uint_t*)virt_cr0);
697
698           
699         } else {
700           *virt_cr0 = *real_cr0;
701         }
702       
703         info->rip += index;
704
705       } else { 
706         PrintDebug("Unknown read instruction from CR0\n");
707         return -1;
708       }
709     }
710     break;
711
712   case PROTECTED_PAE:
713     PrintDebug("Protected PAE Mode read to CR0 is UNIMPLEMENTED\n");
714     return -1;
715
716   case LONG:
717     PrintDebug("Protected Long Mode read to CR0 is UNIMPLEMENTED\n");
718     return -1;
719
720
721   default:
722     {
723       PrintDebug("Unknown Mode read from CR0 (info->cpu_mode=0x%x)\n",info->cpu_mode);
724       return -1;
725     }
726     break;
727   }
728
729
730   return 0;
731 }
732
733
734
735
736 int handle_cr3_write(struct guest_info * info) {
737   if (info->cpu_mode == REAL) {
738     // WHAT THE HELL DOES THIS EVEN MEAN?????
739
740     int index = 0;
741     int ret;
742     char instr[15];
743
744     PrintDebug("Real Mode Write to CR3??? What the fuck???\n");
745     // We need to read the instruction, which is at CS:IP, but that 
746     // linear address is guest physical without PG and guest virtual with PG
747
748     ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
749
750     if (ret != 15) {
751       PrintDebug("Could not read instruction (ret=%d)\n", ret);
752       return -1;
753     }
754
755     while (is_prefix_byte(instr[index])) {
756       switch(instr[index]) {
757       case PREFIX_CS_OVERRIDE:
758       case PREFIX_SS_OVERRIDE:
759       case PREFIX_DS_OVERRIDE:
760       case PREFIX_ES_OVERRIDE:
761       case PREFIX_FS_OVERRIDE:
762       case PREFIX_GS_OVERRIDE:
763         PrintDebug("Segment Override!!\n");
764         return -1;
765         break;
766       default:
767         break;
768       }
769       index++; 
770     }
771     
772
773     if ((instr[index] == cr_access_byte) && 
774         (instr[index + 1] == mov_to_cr_byte)) {
775
776       addr_t first_operand;
777       addr_t second_operand;
778       struct cr3_32 * new_cr3;
779       //      struct cr3_32 * real_cr3;
780       operand_type_t addr_type;
781
782       index += 2;
783
784       addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
785
786       if (addr_type != REG_OPERAND) {
787         /* Mov to CR3 can only be a 32 bit register */
788         return -1;
789       }
790
791       new_cr3 = (struct cr3_32 *)first_operand;
792
793       if (info->shdw_pg_mode == SHADOW_PAGING) {
794         addr_t shadow_pt;
795         struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
796         struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
797
798         /*
799
800           if (CR3_TO_PDE32(*(uint_t*)shadow_cr3) != 0) {
801             PrintDebug("Shadow Page Table\n");
802             PrintDebugPageTables((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
803           }
804         */
805
806         /* Delete the current Page Tables */
807         delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
808
809         PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n", 
810                    *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
811
812
813         *guest_cr3 = *new_cr3;
814
815
816
817         // Something like this
818         shadow_pt =  create_new_shadow_pt32(info);
819         //shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
820
821         /* Copy Various flags */
822         *shadow_cr3 = *new_cr3;
823
824         /*
825         {
826           addr_t tmp_addr;
827           guest_pa_to_host_va(info, ((*(uint_t*)guest_cr3) & 0xfffff000), &tmp_addr);
828           PrintDebug("Guest PD\n");
829           PrintPD32((pde32_t *)tmp_addr);
830
831         }
832         */
833
834         
835         shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
836
837         PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n", 
838                    *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
839
840
841
842
843       }
844       info->rip += index;
845
846     } else {
847       PrintDebug("Unknown Instruction\n");
848       SerialMemDump(instr,15);
849       return -1;
850     }
851
852
853
854   } else if (info->cpu_mode == PROTECTED) {
855     int index = 0;
856     int ret;
857     char instr[15];
858
859     PrintDebug("Protected %s mode write to CR3 at %s 0x%x\n",
860                info->cpu_mode==PROTECTED ? "" : "Paged", 
861                info->cpu_mode==PROTECTED ? "guest physical" : "guest virtual",
862                get_addr_linear(info,info->rip,&(info->segments.cs)));
863
864     // We need to read the instruction, which is at CS:IP, but that 
865     // linear address is guest physical without PG and guest virtual with PG
866     if (info->mem_mode == PHYSICAL_MEM) { 
867       // The real rip address is actually a combination of the rip + CS base 
868       PrintDebug("Writing Guest CR3 Write (Physical Address)\n");
869       ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
870     } else { 
871       PrintDebug("Writing Guest CR3 Write (Virtual Address)\n");
872       // The real rip address is actually a combination of the rip + CS base 
873       ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
874     }
875
876     if (ret != 15) {
877       PrintDebug("Could not read instruction (ret=%d)\n", ret);
878       return -1;
879     }
880
881     while (is_prefix_byte(instr[index])) {
882       switch(instr[index]) {
883       case PREFIX_CS_OVERRIDE:
884       case PREFIX_SS_OVERRIDE:
885       case PREFIX_DS_OVERRIDE:
886       case PREFIX_ES_OVERRIDE:
887       case PREFIX_FS_OVERRIDE:
888       case PREFIX_GS_OVERRIDE:
889         PrintDebug("Segment Override!!\n");
890         return -1;
891         break;
892       default:
893         break;
894       }
895       index++; 
896     }
897     
898     /*    
899           while (is_prefix_byte(instr[index])) {
900           index++;
901           }
902     */
903
904     if ((instr[index] == cr_access_byte) && 
905         (instr[index + 1] == mov_to_cr_byte)) {
906
907       addr_t first_operand;
908       addr_t second_operand;
909       struct cr3_32 * new_cr3;
910       //      struct cr3_32 * real_cr3;
911       operand_type_t addr_type;
912
913       index += 2;
914
915       addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
916
917       if (addr_type != REG_OPERAND) {
918         /* Mov to CR3 can only be a 32 bit register */
919         return -1;
920       }
921
922       new_cr3 = (struct cr3_32 *)first_operand;
923
924       if (info->shdw_pg_mode == SHADOW_PAGING) {
925         addr_t shadow_pt;
926         struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
927         struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
928
929
930         /*
931           if (CR3_TO_PDE32(*(uint_t*)shadow_cr3) != 0) {
932             PrintDebug("Shadow Page Table\n");
933             PrintDebugPageTables((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
934           }
935         */
936
937         /* Delete the current Page Tables */
938         delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
939
940         PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n", 
941                    *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
942
943
944         *guest_cr3 = *new_cr3;
945
946
947
948         // Something like this
949         shadow_pt =  create_new_shadow_pt32(info);
950         //shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
951
952         /* Copy Various flags */
953         *shadow_cr3 = *new_cr3;
954
955         /*
956         {
957           addr_t tmp_addr;
958           guest_pa_to_host_va(info, ((*(uint_t*)guest_cr3) & 0xfffff000), &tmp_addr);
959           PrintDebug("Guest PD\n");
960           PrintPD32((pde32_t *)tmp_addr);
961
962         }
963         */
964
965         
966         shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
967
968         PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n", 
969                    *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
970
971
972
973         if (info->mem_mode == VIRTUAL_MEM) {
974           // If we aren't in paged mode then we have to preserve the identity mapped CR3
975           info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
976         }
977       }
978
979       info->rip += index;
980
981     } else {
982       PrintDebug("Unknown Instruction\n");
983       SerialMemDump(instr,15);
984       return -1;
985     }
986   } else {
987     PrintDebug("Invalid operating Mode (0x%x)\n", info->cpu_mode);
988     return -1;
989   }
990
991   return 0;
992 }
993
994
995
996
997 int handle_cr3_read(struct guest_info * info) {
998
999   if (info->cpu_mode == REAL) {
1000     char instr[15];
1001     int ret;
1002     int index = 0;
1003     addr_t linear_addr = 0;
1004
1005     linear_addr = get_addr_linear(info, info->rip, &(info->segments.cs));
1006
1007     
1008     PrintDebug("RIP Linear: %x\n", linear_addr);
1009     PrintV3Segments(&(info->segments));
1010     
1011     ret = read_guest_pa_memory(info, linear_addr, 15, instr);
1012
1013     if (ret != 15) {
1014       PrintDebug("Could not read instruction (ret=%d)\n", ret);
1015       return -1;
1016     }
1017     
1018     while (is_prefix_byte(instr[index])) {
1019       switch(instr[index]) {
1020       case PREFIX_CS_OVERRIDE:
1021       case PREFIX_SS_OVERRIDE:
1022       case PREFIX_DS_OVERRIDE:
1023       case PREFIX_ES_OVERRIDE:
1024       case PREFIX_FS_OVERRIDE:
1025       case PREFIX_GS_OVERRIDE:
1026         PrintDebug("Segment Override!!\n");
1027         return -1;
1028         break;
1029       default:
1030         break;
1031       }
1032       index++; 
1033     }
1034
1035
1036     if ((instr[index] == cr_access_byte) && 
1037         (instr[index + 1] == mov_from_cr_byte)) {
1038       addr_t first_operand;
1039       addr_t second_operand;
1040       struct cr3_32 * virt_cr3;
1041       struct cr3_32 * real_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
1042       operand_type_t addr_type;
1043
1044       index += 2;
1045
1046       addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
1047
1048       if (addr_type != REG_OPERAND) {
1049         /* Mov to CR3 can only be a 32 bit register */
1050         return -1;
1051       }
1052
1053       virt_cr3 = (struct cr3_32 *)first_operand;
1054
1055       if (info->shdw_pg_mode == SHADOW_PAGING) {
1056         *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
1057       } else {
1058         *virt_cr3 = *real_cr3;
1059       }
1060       
1061       info->rip += index;
1062     } else {
1063       PrintDebug("Unknown Instruction\n");
1064       SerialMemDump(instr,15);
1065       return -1;
1066     }
1067
1068
1069     return 0;
1070   } else if (info->cpu_mode == PROTECTED) {
1071
1072     int index = 0;
1073     int ret;
1074     char instr[15];
1075
1076    
1077     // We need to read the instruction, which is at CS:IP, but that 
1078     // linear address is guest physical without PG and guest virtual with PG
1079     if (info->cpu_mode == PHYSICAL_MEM) { 
1080       // The real rip address is actually a combination of the rip + CS base 
1081       ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
1082     } else { 
1083       // The real rip address is actually a combination of the rip + CS base 
1084       ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
1085     }
1086
1087     if (ret != 15) {
1088       PrintDebug("Could not read instruction (ret=%d)\n", ret);
1089       return -1;
1090     }
1091     
1092     while (is_prefix_byte(instr[index])) {
1093       switch(instr[index]) {
1094       case PREFIX_CS_OVERRIDE:
1095       case PREFIX_SS_OVERRIDE:
1096       case PREFIX_DS_OVERRIDE:
1097       case PREFIX_ES_OVERRIDE:
1098       case PREFIX_FS_OVERRIDE:
1099       case PREFIX_GS_OVERRIDE:
1100         PrintDebug("Segment Override!!\n");
1101         return -1;
1102         break;
1103       default:
1104         break;
1105       }
1106       index++; 
1107     }
1108
1109     /*
1110       while (is_prefix_byte(instr[index])) {
1111       index++;
1112       }
1113     */
1114
1115     if ((instr[index] == cr_access_byte) && 
1116         (instr[index + 1] == mov_from_cr_byte)) {
1117       addr_t first_operand;
1118       addr_t second_operand;
1119       struct cr3_32 * virt_cr3;
1120       struct cr3_32 * real_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
1121       operand_type_t addr_type;
1122
1123       index += 2;
1124
1125       addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
1126
1127       if (addr_type != REG_OPERAND) {
1128         /* Mov to CR3 can only be a 32 bit register */
1129         return -1;
1130       }
1131
1132       virt_cr3 = (struct cr3_32 *)first_operand;
1133
1134       if (info->shdw_pg_mode == SHADOW_PAGING) {
1135         *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
1136       } else {
1137         *virt_cr3 = *real_cr3;
1138       }
1139       
1140       info->rip += index;
1141     } else {
1142       PrintDebug("Unknown Instruction\n");
1143       SerialMemDump(instr,15);
1144       return -1;
1145     }
1146   } else {
1147     PrintDebug("Invalid operating Mode (0x%x), control registers follow\n", info->cpu_mode);
1148     PrintV3CtrlRegs(&(info->ctrl_regs));
1149     return -1;
1150   }
1151
1152   return 0;
1153 }