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.


large change to break apart the guest operation mode parameters
Jack Lange [Mon, 30 Jun 2008 23:09:14 +0000 (23:09 +0000)]
palacios/include/palacios/vm_guest.h
palacios/include/palacios/vmm_decoder.h
palacios/include/palacios/vmm_intr.h
palacios/include/palacios/vmm_shadow_paging.h
palacios/src/geekos/vm.c
palacios/src/palacios/svm.c
palacios/src/palacios/svm_handler.c
palacios/src/palacios/vm_guest_mem.c
palacios/src/palacios/vmm_ctrl_regs.c
palacios/src/palacios/vmm_shadow_paging.c

index 0987f95..2582cf0 100644 (file)
@@ -79,21 +79,20 @@ struct vm_ctrl_ops {
 
 
 
-typedef enum {SHADOW_PAGING, NESTED_PAGING} vm_page_mode_t;
-typedef enum {REAL, PROTECTED, PROTECTED_PG, PROTECTED_PAE, PROTECTED_PAE_PG, LONG, LONG_PG} vm_cpu_mode_t;
+typedef enum {SHADOW_PAGING, NESTED_PAGING} vmm_paging_mode_t;
+typedef enum {REAL, PROTECTED, PROTECTED_PAE, LONG} vm_cpu_mode_t;
+typedef enum {PHYSICAL_MEM, VIRTUAL_MEM} vm_mem_mode_t;
 
 struct guest_info {
   ullong_t rip;
 
-
   uint_t cpl;
 
-
   struct shadow_map mem_map;
 
   struct vm_time time_state;
   
-  vm_page_mode_t page_mode;
+  vmm_paging_mode_t shdw_pg_mode;
   struct shadow_page_state shdw_pg_state;
   // nested_paging_t nested_page_state;
 
@@ -107,6 +106,7 @@ struct guest_info {
   struct vmm_dev_mgr  dev_mgr;
 
   vm_cpu_mode_t cpu_mode;
+  vm_mem_mode_t mem_mode;
 
 
   struct v3_gprs vm_regs;
index fda3729..f37a205 100644 (file)
@@ -154,7 +154,6 @@ static inline v3_reg_t get_gpr_mask(struct guest_info * info) {
     return 0xffff;
     break;
   case PROTECTED:
-  case PROTECTED_PG:
     return 0xffffffff;
   default:
     V3_ASSERT(0);
@@ -169,7 +168,6 @@ static inline addr_t get_addr_linear(struct guest_info * info, addr_t addr, stru
     return addr + (seg->selector << 4);
     break;
   case PROTECTED:
-  case PROTECTED_PG:
     return addr + seg->base;
     break;
   default:
index eccf8fc..30bb2b5 100644 (file)
@@ -25,7 +25,7 @@
 #define SX_EXCEPTION          0x1e
 
 
-typedef enum {INVALID_INTR, EXTERNAL_IRQ, NMI, EXCEPTION, SOFTWARE, VIRTUAL} intr_type_t;
+typedef enum {INVALID_INTR, EXTERNAL_IRQ, NMI, EXCEPTION, SOFTWARE_INTR, VIRTUAL_INTR} intr_type_t;
 
 struct guest_info;
 
index 0b69b6a..141eedf 100644 (file)
@@ -203,9 +203,10 @@ int RunVMM(struct Boot_Info * bootInfo) {
     init_shadow_map(&(vm_info.mem_map));
     init_shadow_page_state(&(vm_info.shdw_pg_state));
     v3_init_time(&(vm_info.time_state));
-    vm_info.page_mode = SHADOW_PAGING;
+    vm_info.shdw_pg_mode = SHADOW_PAGING;
 
     vm_info.cpu_mode = REAL;
+    vm_info.mem_mode = PHYSICAL_MEM;
 
     //init_irq_map(&(vm_info.irq_map));
     init_vmm_io_map(&(vm_info.io_map));
@@ -313,7 +314,7 @@ int RunVMM(struct Boot_Info * bootInfo) {
 
       //add_shadow_region_passthrough(&vm_info, 0x100000, 0x2000000, (addr_t)Allocate_VMM_Pages(8192));
       add_shadow_region_passthrough(&vm_info, 0x100000, 0x1000000, (addr_t)Allocate_VMM_Pages(4096));
-
+      add_shadow_region_passthrough(&vm_info, 0xc0000000, 0xffffffff, 0xc0000000);
 
       print_shadow_map(&(vm_info.mem_map));
 
index 7a81e7e..1a9f1b8 100644 (file)
@@ -154,7 +154,7 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info vm_info) {
   ctrl_area->instrs.INTR = 1;
 
 
-  if (vm_info.page_mode == SHADOW_PAGING) {
+  if (vm_info.shdw_pg_mode == SHADOW_PAGING) {
     PrintDebug("Creating initial shadow page table\n");
     vm_info.shdw_pg_state.shadow_cr3 |= ((addr_t)create_passthrough_pde32_pts(&vm_info) & ~0xfff);
     PrintDebug("Created\n");
@@ -173,7 +173,7 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info vm_info) {
     guest_state->g_pat = 0x7040600070406ULL;
 
     guest_state->cr0 |= 0x80000000;
-  } else if (vm_info.page_mode == NESTED_PAGING) {
+  } else if (vm_info.shdw_pg_mode == NESTED_PAGING) {
     // Flush the TLB on entries/exits
     //ctrl_area->TLB_CONTROL = 1;
 
@@ -273,7 +273,6 @@ static int start_svm_guest(struct guest_info *info) {
 
       PrintDebug("SVM ERROR!!\n"); 
       
-
       PrintDebug("RIP: %x\n", guest_state->rip);
 
 
@@ -282,7 +281,13 @@ static int start_svm_guest(struct guest_info *info) {
 
       PrintDebug("RIP Linear: %x\n", linear_addr);
 
-      guest_pa_to_host_pa(info, linear_addr, &host_addr);
+      
+      if (info->mem_mode == PHYSICAL_MEM) {
+       guest_pa_to_host_pa(info, linear_addr, &host_addr);
+      } else if (info->mem_mode == VIRTUAL_MEM) {
+       guest_va_to_host_pa(info, linear_addr, &host_addr);
+      }
+
 
       PrintDebug("Host Address of rip = 0x%x\n", host_addr);
 
index 7e1a91b..fa71162 100644 (file)
@@ -106,7 +106,7 @@ int handle_svm_exit(struct guest_info * info) {
     
     PrintDebug("PageFault at %x (error=%d)\n", fault_addr, *error_code);
 
-    if (info->page_mode == SHADOW_PAGING) {
+    if (info->shdw_pg_mode == SHADOW_PAGING) {
       if (handle_shadow_pagefault(info, fault_addr, *error_code) == -1) {
        return -1;
       }
@@ -116,7 +116,7 @@ int handle_svm_exit(struct guest_info * info) {
     }
 
   } else if (exit_code == VMEXIT_INVLPG) {
-    if (info->page_mode == SHADOW_PAGING) {
+    if (info->shdw_pg_mode == SHADOW_PAGING) {
       PrintDebug("Invlpg\n");
       if (handle_shadow_invlpg(info) == -1) {
        return -1;
@@ -158,8 +158,18 @@ int handle_svm_exit(struct guest_info * info) {
 
     
 
-    if (guest_pa_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
-      PrintDebug("Could not translate guest_state->rip to host address\n");
+    if (info->mem_mode == PHYSICAL_MEM) {
+      if (guest_pa_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
+       PrintDebug("Could not translate guest_state->rip to host address\n");
+       return -1;
+      }
+    } else if (info->mem_mode == VIRTUAL_MEM) {
+      if (guest_va_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
+       PrintDebug("Could not translate guest_state->rip to host address\n");
+       return -1;
+      }
+    } else {
+      PrintDebug("Invalid memory mode\n");
       return -1;
     }
 
@@ -169,7 +179,11 @@ int handle_svm_exit(struct guest_info * info) {
     
     PrintDebug("Reading from 0x%x in guest\n", rip_addr);
     
-    read_guest_pa_memory(info, rip_addr, 15, buf);
+    if (info->mem_mode == PHYSICAL_MEM) {
+      read_guest_pa_memory(info, rip_addr, 15, buf);
+    } else {
+      read_guest_va_memory(info, rip_addr, 15, buf);
+    }
 
     PrintTraceMemDump(buf, 15);
 
@@ -223,10 +237,10 @@ int handle_svm_exit(struct guest_info * info) {
        injecting_intr(info, excp, EXCEPTION);
        break;
       }
-    case SOFTWARE:
+    case SOFTWARE_INTR:
       guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
       break;
-    case VIRTUAL:
+    case VIRTUAL_INTR:
       guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
       break;
 
index 7b98d83..70914b4 100644 (file)
@@ -115,16 +115,16 @@ int guest_pa_to_host_va(struct guest_info * guest_info, addr_t guest_pa, addr_t
 
 
 int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t * guest_pa) {
-  if (guest_info->page_mode == SHADOW_PAGING) {
-    switch (guest_info->cpu_mode) {
-    case REAL:
-    case PROTECTED:
-    case LONG:
-    case PROTECTED_PAE:
+  if (guest_info->shdw_pg_mode == SHADOW_PAGING) {
+    if (guest_info->mem_mode == PHYSICAL_MEM) {
       // guest virtual address is the same as the physical
       *guest_pa = guest_va;
       return 0;
-    case PROTECTED_PG:
+    }
+    
+    // Guest Is in Paged mode
+    switch (guest_info->cpu_mode) {
+    case PROTECTED:
       {
        addr_t tmp_pa = 0;
        pde32_t * pde = 0;
@@ -167,18 +167,18 @@ int guest_va_to_guest_pa(struct guest_info * guest_info, addr_t guest_va, addr_t
          return -1;
        }
       }
-      case PROTECTED_PAE_PG:
+      case PROTECTED_PAE:
        {
          // Fill in
        }
-      case LONG_PG:
+      case LONG:
        {
          // Fill in
        }
     default:
       return -1;
     }
-  } else if (guest_info->page_mode == NESTED_PAGING) {
+  } else if (guest_info->shdw_pg_mode == NESTED_PAGING) {
 
     // Fill in
 
index 245ba44..82853bc 100644 (file)
@@ -85,7 +85,7 @@ int handle_cr0_write(struct guest_info * info) {
        new_cr0_val = *(char*)(new_cr0) & 0x0f;
 
 
-       if (info->page_mode == SHADOW_PAGING) {
+       if (info->shdw_pg_mode == SHADOW_PAGING) {
          struct cr0_real * shadow_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
 
          PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);        
@@ -153,7 +153,7 @@ int handle_cr0_write(struct guest_info * info) {
          return -1;
        }
 
-       if (info->page_mode == SHADOW_PAGING) {
+       if (info->shdw_pg_mode == SHADOW_PAGING) {
          struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
        
          PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);        
@@ -181,24 +181,23 @@ int handle_cr0_write(struct guest_info * info) {
     break;
  
   case PROTECTED: 
-  case PROTECTED_PG:
     {
 
       int index = 0;
       int ret;
 
       PrintDebug("Protected %s Mode write to CR0 at guest %s linear rip 0x%x\n", 
-                info->cpu_mode==PROTECTED_PG ? "Paged" : "",
-                info->cpu_mode==PROTECTED_PG ? "virtual" : "",
-                get_addr_linear(info,info->rip,&(info->segments.cs)));
+                info->mem_mode == VIRTUAL_MEM ? "Paged" : "",
+                info->mem_mode == VIRTUAL_MEM ? "virtual" : "",
+                get_addr_linear(info, info->rip, &(info->segments.cs)));
 
       // OK, now we will read the instruction
       // The only difference between PROTECTED and PROTECTED_PG is whether we read
       // from guest_pa or guest_va
-      if (info->cpu_mode==PROTECTED) { 
+      if (info->mem_mode == PHYSICAL_MEM) { 
        // The real rip address is actually a combination of the rip + CS base 
        ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
-      } else { //PROTECTED_PG
+      } else { 
        ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
       }
        
@@ -240,7 +239,7 @@ int handle_cr0_write(struct guest_info * info) {
 
 
 
-       if (info->page_mode == SHADOW_PAGING) {
+       if (info->shdw_pg_mode == SHADOW_PAGING) {
          struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
 
          if (new_cr0->pg == 1){
@@ -249,7 +248,7 @@ int handle_cr0_write(struct guest_info * info) {
 
            struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
 
-           info->cpu_mode = PROTECTED_PG;
+           info->mem_mode = VIRTUAL_MEM;
          
            *shadow_cr0 = *new_cr0;
            *real_cr0 = *new_cr0;
@@ -300,18 +299,10 @@ int handle_cr0_write(struct guest_info * info) {
     PrintDebug("Protected PAE Mode write to CR0 is UNIMPLEMENTED\n");
     return -1;
 
-  case PROTECTED_PAE_PG:
-    PrintDebug("Protected PAE Paged Mode write to CR0 is UNIMPLEMENTED\n");
-    return -1;
-
   case LONG:
     PrintDebug("Protected Long Mode write to CR0 is UNIMPLEMENTED\n");
     return -1;
 
-  case LONG_PG:
-    PrintDebug("Protected Long Paged Mode write to CR0 is UNIMPLEMENTED\n");
-    return -1;
-
   default: 
     {
       PrintDebug("Unknown Mode write to CR0 (info->cpu_mode=0x%x\n)",info->cpu_mode);
@@ -418,7 +409,7 @@ int handle_cr0_read(struct guest_info * info) {
          return -1;
        }
 
-       if (info->page_mode == SHADOW_PAGING) {
+       if (info->shdw_pg_mode == SHADOW_PAGING) {
          *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
        } else {
          *virt_cr0 = *real_cr0;
@@ -436,23 +427,22 @@ int handle_cr0_read(struct guest_info * info) {
     break;
 
   case PROTECTED:
-  case PROTECTED_PG:
     {
     
       int index = 0;
       int ret;
 
       PrintDebug("Protected %s Mode read from CR0 at guest %s linear rip 0x%x\n", 
-                info->cpu_mode==PROTECTED_PG ? "Paged" : "",
-                info->cpu_mode==PROTECTED_PG ? "virtual" : "",
-                get_addr_linear(info,info->rip,&(info->segments.cs)));
+                info->mem_mode == VIRTUAL_MEM ? "Paged" : "",
+                info->mem_mode == VIRTUAL_MEM ? "virtual" : "",
+                get_addr_linear(info, info->rip, &(info->segments.cs)));
 
       // We need to read the instruction, which is at CS:IP, but that 
       // linear address is guest physical without PG and guest virtual with PG
-      if (info->cpu_mode==PROTECTED) { 
+      if (info->cpu_mode == PHYSICAL_MEM) { 
        // The real rip address is actually a combination of the rip + CS base 
        ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
-      } else { // PROTECTED_PG
+      } else { 
        // The real rip address is actually a combination of the rip + CS base 
        ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
       }
@@ -460,7 +450,7 @@ int handle_cr0_read(struct guest_info * info) {
       if (ret != 15) {
        // I think we should inject a GPF into the guest
        PrintDebug("Could not read Protected %s mode instruction (ret=%d)\n", 
-                  info->cpu_mode==PROTECTED_PG ? "Paged" : "", ret);
+                  info->cpu_mode == VIRTUAL_MEM ? "Paged" : "", ret);
        return -1;
       }
 
@@ -491,7 +481,7 @@ int handle_cr0_read(struct guest_info * info) {
       
        virt_cr0 = (struct cr0_32 *)first_operand;
 
-       if (info->page_mode == SHADOW_PAGING) {
+       if (info->shdw_pg_mode == SHADOW_PAGING) {
          *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
        } else {
          *virt_cr0 = *real_cr0;
@@ -510,17 +500,11 @@ int handle_cr0_read(struct guest_info * info) {
     PrintDebug("Protected PAE Mode read to CR0 is UNIMPLEMENTED\n");
     return -1;
 
-  case PROTECTED_PAE_PG:
-    PrintDebug("Protected PAE Paged Mode read to CR0 is UNIMPLEMENTED\n");
-    return -1;
-
   case LONG:
     PrintDebug("Protected Long Mode read to CR0 is UNIMPLEMENTED\n");
     return -1;
 
-  case LONG_PG:
-    PrintDebug("Protected Long Paged Mode read to CR0 is UNIMPLEMENTED\n");
-    return -1;
+
   default:
     {
       PrintDebug("Unknown Mode read from CR0 (info->cpu_mode=0x%x)\n",info->cpu_mode);
@@ -537,14 +521,25 @@ int handle_cr0_read(struct guest_info * info) {
 
 
 int handle_cr3_write(struct guest_info * info) {
-  if ((info->cpu_mode == PROTECTED) || (info->cpu_mode == PROTECTED_PG)) {
+  if (info->cpu_mode == PROTECTED) {
     int index = 0;
     int ret;
     char instr[15];
 
 
-    /* Isn't the RIP a Guest Virtual Address???????? */
-    ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
+    // We need to read the instruction, which is at CS:IP, but that 
+    // linear address is guest physical without PG and guest virtual with PG
+    if (info->cpu_mode == PHYSICAL_MEM) { 
+      // The real rip address is actually a combination of the rip + CS base 
+      PrintDebug("Writing Guest CR3 Write (Physical Address)\n");
+      ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
+    } else { 
+      PrintDebug("Writing Guest CR3 Write (Virtual Address)\n");
+      // The real rip address is actually a combination of the rip + CS base 
+      ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
+    }
+
+
     if (ret != 15) {
       PrintDebug("Could not read instruction (ret=%d)\n", ret);
       return -1;
@@ -574,17 +569,16 @@ int handle_cr3_write(struct guest_info * info) {
 
       new_cr3 = (struct cr3_32 *)first_operand;
 
-      if (info->page_mode == SHADOW_PAGING) {
+      if (info->shdw_pg_mode == SHADOW_PAGING) {
        addr_t shadow_pt;
        struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
        struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
 
-       PrintDebug("fooo1\n");
 
        /* Delete the current Page Tables */
        delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
 
-       PrintDebug("fooo2\n");
+
        *guest_cr3 = *new_cr3;
 
        // Something like this
@@ -597,7 +591,7 @@ int handle_cr3_write(struct guest_info * info) {
        
        shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
 
-       if (info->cpu_mode == PROTECTED_PG) {
+       if (info->mem_mode == VIRTUAL_MEM) {
          // If we aren't in paged mode then we have to preserve the identity mapped CR3
          info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
        }
@@ -621,12 +615,22 @@ int handle_cr3_write(struct guest_info * info) {
 
 
 int handle_cr3_read(struct guest_info * info) {
-  if ((info->cpu_mode == PROTECTED) || (info->cpu_mode == PROTECTED_PG)) {
+  if (info->cpu_mode == PROTECTED) {
     int index = 0;
     int ret;
     char instr[15];
 
-    ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
+   
+    // We need to read the instruction, which is at CS:IP, but that 
+    // linear address is guest physical without PG and guest virtual with PG
+    if (info->cpu_mode == PHYSICAL_MEM) { 
+      // The real rip address is actually a combination of the rip + CS base 
+      ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
+    } else { 
+      // The real rip address is actually a combination of the rip + CS base 
+      ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
+    }
+
     if (ret != 15) {
       PrintDebug("Could not read instruction (ret=%d)\n", ret);
       return -1;
@@ -655,7 +659,7 @@ int handle_cr3_read(struct guest_info * info) {
 
       virt_cr3 = (struct cr3_32 *)first_operand;
 
-      if (info->page_mode == SHADOW_PAGING) {
+      if (info->shdw_pg_mode == SHADOW_PAGING) {
        *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
       } else {
        *virt_cr3 = *real_cr3;
index 5536f04..360e532 100644 (file)
@@ -19,23 +19,25 @@ int init_shadow_page_state(struct shadow_page_state * state) {
 
 int handle_shadow_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
   
-  switch (info->cpu_mode) {
-  case PROTECTED_PG:
-    return handle_shadow_pagefault32(info, fault_addr, error_code);
-    break;
-  case PROTECTED_PAE_PG:
-  case LONG_PG:
-    // currently not handled
-    return -1;
-    break;
-  case REAL:
-  case PROTECTED:
-  case PROTECTED_PAE:
-  case LONG:
+  if (info->mem_mode == PHYSICAL_MEM) {
     // If paging is not turned on we need to handle the special cases
     return handle_special_page_fault(info, fault_addr, error_code);
-    break;
-  default:
+  } else if (info->mem_mode == VIRTUAL_MEM) {
+
+    switch (info->cpu_mode) {
+    case PROTECTED:
+      return handle_shadow_pagefault32(info, fault_addr, error_code);
+      break;
+    case PROTECTED_PAE:
+    case LONG:
+      // currently not handled
+      return -1;
+      break;
+    default:
+      return -1;
+    }
+  } else {
+    PrintDebug("Invalid Memory mode\n");
     return -1;
   }
 }
@@ -151,7 +153,7 @@ int handle_shadow_pagefault32(struct guest_info * info, addr_t fault_addr, pf_er
     return -1;
   }
 
-  PrintDebugPageTables(shadow_pde);
+  //PrintDebugPageTables(shadow_pde);
 
   return 0;
 }
@@ -277,7 +279,15 @@ addr_t create_new_shadow_pt32(struct guest_info * info) {
 
 /* Currently Does not work with Segmentation!!! */
 int handle_shadow_invlpg(struct guest_info * info) {
-  if (info->cpu_mode == PROTECTED_PG) {
+  if (info->mem_mode != VIRTUAL_MEM) {
+    // Paging must be turned on...
+    // should handle with some sort of fault I think
+    PrintDebug("ERROR: INVLPG called in non paged mode\n");
+    return -1;
+  }
+
+
+  if (info->cpu_mode == PROTECTED) {
     char instr[15];
     int ret;
     int index = 0;
@@ -334,7 +344,7 @@ int handle_shadow_invlpg(struct guest_info * info) {
       PrintDebug("invalid Instruction Opcode\n");
       PrintTraceMemDump(instr, 15);
       return -1;
-    }       
+    }
   }
 
   return 0;