Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


added new debugging directives
[palacios.git] / palacios / src / palacios / svm.c
1 #include <palacios/svm.h>
2 #include <palacios/vmm.h>
3
4 #include <palacios/vmcb.h>
5 #include <palacios/vmm_mem.h>
6 #include <palacios/vmm_paging.h>
7 #include <palacios/svm_handler.h>
8
9 #include <palacios/vmm_debug.h>
10 #include <palacios/vm_guest_mem.h>
11
12 #include <palacios/vmm_decoder.h>
13
14
15 extern struct vmm_os_hooks * os_hooks;
16
17 extern uint_t cpuid_ecx(uint_t op);
18 extern uint_t cpuid_edx(uint_t op);
19 extern void Get_MSR(uint_t MSR, uint_t * high_byte, uint_t * low_byte); 
20 extern void Set_MSR(uint_t MSR, uint_t high_byte, uint_t low_byte);
21 extern uint_t launch_svm(vmcb_t * vmcb_addr);
22 extern void safe_svm_launch(vmcb_t * vmcb_addr, struct v3_gprs * gprs);
23
24 extern void STGI();
25 extern void CLGI();
26
27 extern uint_t Get_CR3();
28
29
30 extern void DisableInts();
31 extern void EnableInts();
32
33
34
35
36
37
38
39 static vmcb_t * Allocate_VMCB() {
40   vmcb_t * vmcb_page = (vmcb_t*)os_hooks->allocate_pages(1);
41
42
43   memset(vmcb_page, 0, 4096);
44
45   return vmcb_page;
46 }
47
48
49
50
51
52 static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info *vm_info) {
53   vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb);
54   vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA(vmcb);
55   uint_t i;
56
57
58   guest_state->rsp = vm_info->vm_regs.rsp;
59   // guest_state->rip = vm_info->rip;
60   guest_state->rip = 0xfff0;
61
62   guest_state->cpl = 0;
63
64   //ctrl_area->instrs.instrs.CR0 = 1;
65   ctrl_area->cr_reads.cr0 = 1;
66   ctrl_area->cr_writes.cr0 = 1;
67
68   guest_state->efer |= EFER_MSR_svm_enable;
69   guest_state->rflags = 0x00000002; // The reserved bit is always 1
70   ctrl_area->svm_instrs.VMRUN = 1;
71   ctrl_area->instrs.HLT = 1;
72   // guest_state->cr0 = 0x00000001;    // PE 
73   ctrl_area->guest_ASID = 1;
74
75   
76   /*
77     ctrl_area->exceptions.de = 1;
78     ctrl_area->exceptions.df = 1;
79     
80     ctrl_area->exceptions.ts = 1;
81     ctrl_area->exceptions.ss = 1;
82     ctrl_area->exceptions.ac = 1;
83     ctrl_area->exceptions.mc = 1;
84     ctrl_area->exceptions.gp = 1;
85     ctrl_area->exceptions.ud = 1;
86     ctrl_area->exceptions.np = 1;
87     ctrl_area->exceptions.of = 1;
88   
89     ctrl_area->exceptions.nmi = 1;
90   */
91   // Debug of boot on physical machines - 7/14/08
92   ctrl_area->instrs.NMI=1;
93   ctrl_area->instrs.SMI=1;
94   ctrl_area->instrs.INIT=1;
95   ctrl_area->instrs.PAUSE=1;
96   ctrl_area->instrs.shutdown_evts=1;
97
98
99
100   vm_info->vm_regs.rdx = 0x00000f00;
101
102   guest_state->cr0 = 0x60000010;
103
104   guest_state->cs.selector = 0xf000;
105   guest_state->cs.limit=0xffff;
106   guest_state->cs.base = 0x0000000f0000LL;
107   guest_state->cs.attrib.raw = 0xf3;
108
109   
110   struct vmcb_selector *segregs [] = {&(guest_state->ss), &(guest_state->ds), &(guest_state->es), &(guest_state->fs), &(guest_state->gs), NULL};
111   for ( i = 0; segregs[i] != NULL; i++) {
112     struct vmcb_selector * seg = segregs[i];
113     
114     seg->selector = 0x0000;
115     //    seg->base = seg->selector << 4;
116     seg->base = 0x00000000;
117     seg->attrib.raw = 0xf3;
118     seg->limit = ~0u;
119   }
120   
121   guest_state->gdtr.limit = 0x0000ffff;
122   guest_state->gdtr.base = 0x0000000000000000LL;
123   guest_state->idtr.limit = 0x0000ffff;
124   guest_state->idtr.base = 0x0000000000000000LL;
125
126   guest_state->ldtr.selector = 0x0000;
127   guest_state->ldtr.limit = 0x0000ffff;
128   guest_state->ldtr.base = 0x0000000000000000LL;
129   guest_state->tr.selector = 0x0000;
130   guest_state->tr.limit = 0x0000ffff;
131   guest_state->tr.base = 0x0000000000000000LL;
132
133
134   guest_state->dr6 = 0x00000000ffff0ff0LL;
135   guest_state->dr7 = 0x0000000000000400LL;
136
137   if (vm_info->io_map.num_ports > 0) {
138     vmm_io_hook_t * iter;
139     addr_t io_port_bitmap;
140     
141     io_port_bitmap = (addr_t)os_hooks->allocate_pages(3);
142     memset((uchar_t*)io_port_bitmap, 0, PAGE_SIZE * 3);
143     
144     ctrl_area->IOPM_BASE_PA = io_port_bitmap;
145
146     //PrintDebug("Setting up IO Map at 0x%x\n", io_port_bitmap);
147
148     FOREACH_IO_HOOK(vm_info->io_map, iter) {
149       ushort_t port = iter->port;
150       uchar_t * bitmap = (uchar_t *)io_port_bitmap;
151
152       bitmap += (port / 8);
153       PrintDebug("Setting Bit for port 0x%x\n", port);
154       *bitmap |= 1 << (port % 8);
155     }
156
157
158     //PrintDebugMemDump((uchar_t*)io_port_bitmap, PAGE_SIZE *2);
159
160     ctrl_area->instrs.IOIO_PROT = 1;
161   }
162
163
164
165   PrintDebug("Exiting on interrupts\n");
166   ctrl_area->guest_ctrl.V_INTR_MASKING = 1;
167   ctrl_area->instrs.INTR = 1;
168
169
170   if (vm_info->shdw_pg_mode == SHADOW_PAGING) {
171     PrintDebug("Creating initial shadow page table\n");
172     vm_info->direct_map_pt = (addr_t)create_passthrough_pde32_pts(vm_info);
173     vm_info->shdw_pg_state.shadow_cr3 |= (vm_info->direct_map_pt & ~0xfff);
174     vm_info->shdw_pg_state.guest_cr0 = 0x0000000000000010LL;
175     PrintDebug("Created\n");
176
177     guest_state->cr3 = vm_info->shdw_pg_state.shadow_cr3;
178
179     //PrintDebugPageTables((pde32_t*)(vm_info->shdw_pg_state.shadow_cr3.e_reg.low));
180
181     ctrl_area->cr_reads.cr3 = 1;
182     ctrl_area->cr_writes.cr3 = 1;
183
184
185     ctrl_area->instrs.INVLPG = 1;
186     ctrl_area->instrs.INVLPGA = 1;
187
188     ctrl_area->exceptions.pf = 1;
189
190     /* JRL: This is a performance killer, and a simplistic solution */
191     /* We need to fix this */
192     ctrl_area->TLB_CONTROL = 1;
193     
194
195
196     guest_state->g_pat = 0x7040600070406ULL;
197
198     guest_state->cr0 |= 0x80000000;
199
200   } else if (vm_info->shdw_pg_mode == NESTED_PAGING) {
201     // Flush the TLB on entries/exits
202     ctrl_area->TLB_CONTROL = 1;
203
204     // Enable Nested Paging
205     ctrl_area->NP_ENABLE = 1;
206
207     PrintDebug("NP_Enable at 0x%x\n", &(ctrl_area->NP_ENABLE));
208
209     // Set the Nested Page Table pointer
210     vm_info->direct_map_pt = ((addr_t)create_passthrough_pde32_pts(vm_info) & ~0xfff);
211     ctrl_area->N_CR3 = vm_info->direct_map_pt;
212
213     //   ctrl_area->N_CR3 = Get_CR3();
214     // guest_state->cr3 |= (Get_CR3() & 0xfffff000);
215
216     guest_state->g_pat = 0x7040600070406ULL;
217   }
218
219
220
221 }
222
223
224
225
226
227
228
229
230
231 static int init_svm_guest(struct guest_info *info) {
232  
233   PrintDebug("Allocating VMCB\n");
234   info->vmm_data = (void*)Allocate_VMCB();
235
236
237   //PrintDebug("Generating Guest nested page tables\n");
238   //  info->page_tables = NULL;
239   //info->page_tables = generate_guest_page_tables_64(&(info->mem_layout), &(info->mem_list));
240   //info->page_tables = generate_guest_page_tables(&(info->mem_layout), &(info->mem_list));
241   //  PrintDebugPageTables(info->page_tables);
242
243
244   PrintDebug("Initializing VMCB (addr=%x)\n", info->vmm_data);
245   Init_VMCB_BIOS((vmcb_t*)(info->vmm_data), info);
246   
247
248   //  info->rip = 0;
249
250   info->vm_regs.rdi = 0;
251   info->vm_regs.rsi = 0;
252   info->vm_regs.rbp = 0;
253   info->vm_regs.rsp = 0;
254   info->vm_regs.rbx = 0;
255   info->vm_regs.rdx = 0;
256   info->vm_regs.rcx = 0;
257   info->vm_regs.rax = 0;
258   
259   return 0;
260 }
261
262
263 // can we start a kernel thread here...
264 static int start_svm_guest(struct guest_info *info) {
265   vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
266   vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
267
268   PrintDebug("Launching SVM VM (vmcb=%x)\n", info->vmm_data);
269   //PrintDebugVMCB((vmcb_t*)(info->vmm_data));
270
271   while (1) {
272     ullong_t tmp_tsc;
273
274
275     EnableInts();
276     CLGI();
277
278     //    PrintDebug("SVM Entry to rip=%x...\n", info->rip);
279
280     rdtscll(info->time_state.cached_host_tsc);
281     guest_ctrl->TSC_OFFSET = info->time_state.guest_tsc - info->time_state.cached_host_tsc;
282
283     safe_svm_launch((vmcb_t*)(info->vmm_data), &(info->vm_regs));
284
285     rdtscll(tmp_tsc);
286     //PrintDebug("SVM Returned\n");
287
288
289     v3_update_time(info, tmp_tsc - info->time_state.cached_host_tsc);
290
291     STGI();
292
293      
294     if (handle_svm_exit(info) != 0) {
295
296       addr_t host_addr;
297       addr_t linear_addr = 0;
298
299       PrintDebug("SVM ERROR!!\n"); 
300       
301       PrintDebug("RIP: %x\n", guest_state->rip);
302
303
304       linear_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs));
305
306
307       PrintDebug("RIP Linear: %x\n", linear_addr);
308       PrintV3Segments(info);
309       PrintV3CtrlRegs(info);
310       PrintV3GPRs(info);
311       
312       if (info->mem_mode == PHYSICAL_MEM) {
313         guest_pa_to_host_pa(info, linear_addr, &host_addr);
314       } else if (info->mem_mode == VIRTUAL_MEM) {
315         guest_va_to_host_pa(info, linear_addr, &host_addr);
316       }
317
318
319       PrintDebug("Host Address of rip = 0x%x\n", host_addr);
320
321       PrintDebug("Instr (15 bytes) at %x:\n", host_addr);
322       PrintTraceMemDump((char*)host_addr, 15);
323
324       break;
325     }
326   }
327   return 0;
328 }
329
330
331
332
333 /* Checks machine SVM capability */
334 /* Implemented from: AMD Arch Manual 3, sect 15.4 */ 
335 int is_svm_capable() {
336
337 #if 1
338   // Dinda
339
340   uint_t ret;
341   uint_t vm_cr_low = 0, vm_cr_high = 0;
342
343
344   ret =  cpuid_ecx(CPUID_FEATURE_IDS);
345   
346   PrintDebug("CPUID_FEATURE_IDS_ecx=0x%x\n",ret);
347
348   if ((ret & CPUID_FEATURE_IDS_ecx_svm_avail) == 0) {
349     PrintDebug("SVM Not Available\n");
350     return 0;
351   }  else {
352     Get_MSR(SVM_VM_CR_MSR, &vm_cr_high, &vm_cr_low);
353     
354     PrintDebug("SVM_VM_CR_MSR = 0x%x 0x%x\n",vm_cr_high,vm_cr_low);
355     
356     if ((vm_cr_low & SVM_VM_CR_MSR_svmdis) == 1) {
357       PrintDebug("SVM is available but is disabled.\n");
358
359       ret = cpuid_edx(CPUID_SVM_REV_AND_FEATURE_IDS);
360       
361       PrintDebug("CPUID_FEATURE_IDS_edx=0x%x\n",ret);
362       
363       if ((ret & CPUID_SVM_REV_AND_FEATURE_IDS_edx_svml) == 0) {
364         PrintDebug("SVM BIOS Disabled, not unlockable\n");
365       } else {
366         PrintDebug("SVM is locked with a key\n");
367       }
368       return 0;
369
370     } else {
371       PrintDebug("SVM is available and  enabled.\n");
372
373       ret = cpuid_edx(CPUID_SVM_REV_AND_FEATURE_IDS);
374       
375       PrintDebug("CPUID_FEATURE_IDS_edx=0x%x\n",ret);
376
377       if ((ret & CPUID_SVM_REV_AND_FEATURE_IDS_edx_np) == 0) {
378         PrintDebug("SVM Nested Paging not supported\n");
379       } else {
380         PrintDebug("SVM Nested Paging supported\n");
381       }
382       
383       return 1;
384       
385     }
386   }
387
388 #else
389
390   uint_t ret =  cpuid_ecx(CPUID_FEATURE_IDS);
391   uint_t vm_cr_low = 0, vm_cr_high = 0;
392
393
394   if ((ret & CPUID_FEATURE_IDS_ecx_svm_avail) == 0) {
395     PrintDebug("SVM Not Available\n");
396     return 0;
397   } 
398
399   Get_MSR(SVM_VM_CR_MSR, &vm_cr_high, &vm_cr_low);
400
401   PrintDebug("SVM_VM_CR_MSR = 0x%x 0x%x\n",vm_cr_high,vm_cr_low);
402
403
404   // this part is clearly wrong, since the np bit is in 
405   // edx, not ecx
406   if ((ret & CPUID_SVM_REV_AND_FEATURE_IDS_edx_np) == 1) {
407     PrintDebug("Nested Paging not supported\n");
408   } else {
409     PrintDebug("Nested Paging supported\n");
410   }
411
412   if ((vm_cr_low & SVM_VM_CR_MSR_svmdis) == 0) {
413     PrintDebug("SVM is disabled.\n");
414     return 1;
415   }
416
417   ret = cpuid_edx(CPUID_SVM_REV_AND_FEATURE_IDS);
418
419   if ((ret & CPUID_SVM_REV_AND_FEATURE_IDS_edx_svml) == 0) {
420     PrintDebug("SVM BIOS Disabled, not unlockable\n");
421   } else {
422     PrintDebug("SVM is locked with a key\n");
423   }
424
425   return 0;
426
427 #endif
428
429 }
430
431 int has_svm_nested_paging() {
432   uint32_t ret;
433
434   ret = cpuid_edx(CPUID_SVM_REV_AND_FEATURE_IDS);
435       
436   //PrintDebug("CPUID_FEATURE_IDS_edx=0x%x\n",ret);
437   
438   if ((ret & CPUID_SVM_REV_AND_FEATURE_IDS_edx_np) == 0) {
439     PrintDebug("SVM Nested Paging not supported\n");
440     return 0;
441   } else {
442     PrintDebug("SVM Nested Paging supported\n");
443     return 1;
444   }
445
446 }
447
448
449
450 void Init_SVM(struct vmm_ctrl_ops * vmm_ops) {
451   reg_ex_t msr;
452   void * host_state;
453
454
455   // Enable SVM on the CPU
456   Get_MSR(EFER_MSR, &(msr.e_reg.high), &(msr.e_reg.low));
457   msr.e_reg.low |= EFER_MSR_svm_enable;
458   Set_MSR(EFER_MSR, 0, msr.e_reg.low);
459   
460   PrintDebug("SVM Enabled\n");
461
462
463   // Setup the host state save area
464   host_state = os_hooks->allocate_pages(4);
465   
466   msr.e_reg.high = 0;
467   msr.e_reg.low = (uint_t)host_state;
468
469
470   PrintDebug("Host State being saved at %x\n", (uint_t)host_state);
471   Set_MSR(SVM_VM_HSAVE_PA_MSR, msr.e_reg.high, msr.e_reg.low);
472
473
474
475   // Setup the SVM specific vmm operations
476   vmm_ops->init_guest = &init_svm_guest;
477   vmm_ops->start_guest = &start_svm_guest;
478   vmm_ops->has_nested_paging = &has_svm_nested_paging;
479
480   return;
481 }
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534 /*static void Init_VMCB(vmcb_t * vmcb, struct guest_info vm_info) {
535   vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb);
536   vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA(vmcb);
537   uint_t i;
538
539
540   guest_state->rsp = vm_info.vm_regs.rsp;
541   guest_state->rip = vm_info.rip;
542
543
544   //ctrl_area->instrs.instrs.CR0 = 1;
545   ctrl_area->cr_reads.cr0 = 1;
546   ctrl_area->cr_writes.cr0 = 1;
547
548   guest_state->efer |= EFER_MSR_svm_enable;
549   guest_state->rflags = 0x00000002; // The reserved bit is always 1
550   ctrl_area->svm_instrs.VMRUN = 1;
551   // guest_state->cr0 = 0x00000001;    // PE 
552   ctrl_area->guest_ASID = 1;
553
554
555   ctrl_area->exceptions.de = 1;
556   ctrl_area->exceptions.df = 1;
557   ctrl_area->exceptions.pf = 1;
558   ctrl_area->exceptions.ts = 1;
559   ctrl_area->exceptions.ss = 1;
560   ctrl_area->exceptions.ac = 1;
561   ctrl_area->exceptions.mc = 1;
562   ctrl_area->exceptions.gp = 1;
563   ctrl_area->exceptions.ud = 1;
564   ctrl_area->exceptions.np = 1;
565   ctrl_area->exceptions.of = 1;
566   ctrl_area->exceptions.nmi = 1;
567
568   guest_state->cs.selector = 0x0000;
569   guest_state->cs.limit=~0u;
570   guest_state->cs.base = guest_state->cs.selector<<4;
571   guest_state->cs.attrib.raw = 0xf3;
572
573   
574   struct vmcb_selector *segregs [] = {&(guest_state->ss), &(guest_state->ds), &(guest_state->es), &(guest_state->fs), &(guest_state->gs), NULL};
575   for ( i = 0; segregs[i] != NULL; i++) {
576     struct vmcb_selector * seg = segregs[i];
577     
578     seg->selector = 0x0000;
579     seg->base = seg->selector << 4;
580     seg->attrib.raw = 0xf3;
581     seg->limit = ~0u;
582   }
583   
584   if (vm_info.io_map.num_ports > 0) {
585     vmm_io_hook_t * iter;
586     addr_t io_port_bitmap;
587     
588     io_port_bitmap = (addr_t)os_hooks->allocate_pages(3);
589     memset((uchar_t*)io_port_bitmap, 0, PAGE_SIZE * 3);
590     
591     ctrl_area->IOPM_BASE_PA = io_port_bitmap;
592
593     //PrintDebug("Setting up IO Map at 0x%x\n", io_port_bitmap);
594
595     FOREACH_IO_HOOK(vm_info.io_map, iter) {
596       ushort_t port = iter->port;
597       uchar_t * bitmap = (uchar_t *)io_port_bitmap;
598
599       bitmap += (port / 8);
600       PrintDebug("Setting Bit in block %x\n", bitmap);
601       *bitmap |= 1 << (port % 8);
602     }
603
604
605     //PrintDebugMemDump((uchar_t*)io_port_bitmap, PAGE_SIZE *2);
606
607     ctrl_area->instrs.IOIO_PROT = 1;
608   }
609
610   ctrl_area->instrs.INTR = 1;
611
612
613
614   if (vm_info.page_mode == SHADOW_PAGING) {
615     PrintDebug("Creating initial shadow page table\n");
616     vm_info.shdw_pg_state.shadow_cr3 |= ((addr_t)create_passthrough_pde32_pts(&vm_info) & ~0xfff);
617     PrintDebug("Created\n");
618
619     guest_state->cr3 = vm_info.shdw_pg_state.shadow_cr3;
620
621     ctrl_area->cr_reads.cr3 = 1;
622     ctrl_area->cr_writes.cr3 = 1;
623
624
625     ctrl_area->instrs.INVLPG = 1;
626     ctrl_area->instrs.INVLPGA = 1;
627
628     guest_state->g_pat = 0x7040600070406ULL;
629
630     guest_state->cr0 |= 0x80000000;
631   } else if (vm_info.page_mode == NESTED_PAGING) {
632     // Flush the TLB on entries/exits
633     //ctrl_area->TLB_CONTROL = 1;
634
635     // Enable Nested Paging
636     //ctrl_area->NP_ENABLE = 1;
637
638     //PrintDebug("NP_Enable at 0x%x\n", &(ctrl_area->NP_ENABLE));
639
640         // Set the Nested Page Table pointer
641     //    ctrl_area->N_CR3 = ((addr_t)vm_info.page_tables);
642     // ctrl_area->N_CR3 = (addr_t)(vm_info.page_tables);
643
644     //   ctrl_area->N_CR3 = Get_CR3();
645     // guest_state->cr3 |= (Get_CR3() & 0xfffff000);
646
647     //    guest_state->g_pat = 0x7040600070406ULL;
648   }
649
650
651
652 }
653 */
654
655
656
657
658
659
660
661 #if 0
662 void Init_VMCB_pe(vmcb_t *vmcb, struct guest_info vm_info) {
663   vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb);
664   vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA(vmcb);
665   uint_t i = 0;
666
667
668   guest_state->rsp = vm_info.vm_regs.rsp;
669   guest_state->rip = vm_info.rip;
670
671
672   /* I pretty much just gutted this from TVMM */
673   /* Note: That means its probably wrong */
674
675   // set the segment registers to mirror ours
676   guest_state->cs.selector = 1<<3;
677   guest_state->cs.attrib.fields.type = 0xa; // Code segment+read
678   guest_state->cs.attrib.fields.S = 1;
679   guest_state->cs.attrib.fields.P = 1;
680   guest_state->cs.attrib.fields.db = 1;
681   guest_state->cs.attrib.fields.G = 1;
682   guest_state->cs.limit = 0xfffff;
683   guest_state->cs.base = 0;
684   
685   struct vmcb_selector *segregs [] = {&(guest_state->ss), &(guest_state->ds), &(guest_state->es), &(guest_state->fs), &(guest_state->gs), NULL};
686   for ( i = 0; segregs[i] != NULL; i++) {
687     struct vmcb_selector * seg = segregs[i];
688     
689     seg->selector = 2<<3;
690     seg->attrib.fields.type = 0x2; // Data Segment+read/write
691     seg->attrib.fields.S = 1;
692     seg->attrib.fields.P = 1;
693     seg->attrib.fields.db = 1;
694     seg->attrib.fields.G = 1;
695     seg->limit = 0xfffff;
696     seg->base = 0;
697   }
698
699
700   {
701     /* JRL THIS HAS TO GO */
702     
703     //    guest_state->tr.selector = GetTR_Selector();
704     guest_state->tr.attrib.fields.type = 0x9; 
705     guest_state->tr.attrib.fields.P = 1;
706     // guest_state->tr.limit = GetTR_Limit();
707     //guest_state->tr.base = GetTR_Base();// - 0x2000;
708     /* ** */
709   }
710
711
712   /* ** */
713
714
715   guest_state->efer |= EFER_MSR_svm_enable;
716   guest_state->rflags = 0x00000002; // The reserved bit is always 1
717   ctrl_area->svm_instrs.VMRUN = 1;
718   guest_state->cr0 = 0x00000001;    // PE 
719   ctrl_area->guest_ASID = 1;
720
721
722   //  guest_state->cpl = 0;
723
724
725
726   // Setup exits
727
728   ctrl_area->cr_writes.cr4 = 1;
729   
730   ctrl_area->exceptions.de = 1;
731   ctrl_area->exceptions.df = 1;
732   ctrl_area->exceptions.pf = 1;
733   ctrl_area->exceptions.ts = 1;
734   ctrl_area->exceptions.ss = 1;
735   ctrl_area->exceptions.ac = 1;
736   ctrl_area->exceptions.mc = 1;
737   ctrl_area->exceptions.gp = 1;
738   ctrl_area->exceptions.ud = 1;
739   ctrl_area->exceptions.np = 1;
740   ctrl_area->exceptions.of = 1;
741   ctrl_area->exceptions.nmi = 1;
742
743   
744
745   ctrl_area->instrs.IOIO_PROT = 1;
746   ctrl_area->IOPM_BASE_PA = (uint_t)os_hooks->allocate_pages(3);
747   
748   {
749     reg_ex_t tmp_reg;
750     tmp_reg.r_reg = ctrl_area->IOPM_BASE_PA;
751     memset((void*)(tmp_reg.e_reg.low), 0xffffffff, PAGE_SIZE * 2);
752   }
753
754   ctrl_area->instrs.INTR = 1;
755
756   
757   {
758     char gdt_buf[6];
759     char idt_buf[6];
760
761     memset(gdt_buf, 0, 6);
762     memset(idt_buf, 0, 6);
763
764
765     uint_t gdt_base, idt_base;
766     ushort_t gdt_limit, idt_limit;
767     
768     GetGDTR(gdt_buf);
769     gdt_base = *(ulong_t*)((uchar_t*)gdt_buf + 2) & 0xffffffff;
770     gdt_limit = *(ushort_t*)(gdt_buf) & 0xffff;
771     PrintDebug("GDT: base: %x, limit: %x\n", gdt_base, gdt_limit);
772
773     GetIDTR(idt_buf);
774     idt_base = *(ulong_t*)(idt_buf + 2) & 0xffffffff;
775     idt_limit = *(ushort_t*)(idt_buf) & 0xffff;
776     PrintDebug("IDT: base: %x, limit: %x\n",idt_base, idt_limit);
777
778
779     // gdt_base -= 0x2000;
780     //idt_base -= 0x2000;
781
782     guest_state->gdtr.base = gdt_base;
783     guest_state->gdtr.limit = gdt_limit;
784     guest_state->idtr.base = idt_base;
785     guest_state->idtr.limit = idt_limit;
786
787
788   }
789   
790   
791   // also determine if CPU supports nested paging
792   /*
793   if (vm_info.page_tables) {
794     //   if (0) {
795     // Flush the TLB on entries/exits
796     ctrl_area->TLB_CONTROL = 1;
797
798     // Enable Nested Paging
799     ctrl_area->NP_ENABLE = 1;
800
801     PrintDebug("NP_Enable at 0x%x\n", &(ctrl_area->NP_ENABLE));
802
803         // Set the Nested Page Table pointer
804     ctrl_area->N_CR3 |= ((addr_t)vm_info.page_tables & 0xfffff000);
805
806
807     //   ctrl_area->N_CR3 = Get_CR3();
808     // guest_state->cr3 |= (Get_CR3() & 0xfffff000);
809
810     guest_state->g_pat = 0x7040600070406ULL;
811
812     PrintDebug("Set Nested CR3: lo: 0x%x  hi: 0x%x\n", (uint_t)*(&(ctrl_area->N_CR3)), (uint_t)*((unsigned char *)&(ctrl_area->N_CR3) + 4));
813     PrintDebug("Set Guest CR3: lo: 0x%x  hi: 0x%x\n", (uint_t)*(&(guest_state->cr3)), (uint_t)*((unsigned char *)&(guest_state->cr3) + 4));
814     // Enable Paging
815     //    guest_state->cr0 |= 0x80000000;
816   }
817   */
818
819 }
820
821
822
823
824
825 #endif
826
827