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 MSR hook framework
[palacios.git] / palacios / include / palacios / vmm_paging.h
index e11a452..41d4b6f 100644 (file)
@@ -1,9 +1,28 @@
-/* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
-/* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National 
+ * Science Foundation and the Department of Energy.  
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+#ifndef __VMM_PAGING_H__
+#define __VMM_PAGING_H__
 
-#ifndef __VMM_PAGING_H
-#define __VMM_PAGING_H
 
+#ifdef __V3VEE__
 
 #include <palacios/vmm_types.h>
 #include <palacios/vmm_util.h>
@@ -71,11 +90,15 @@ the host state in the vmcs before entering the guest.
 */
 
 
-#ifdef __V3VEE__
+
 
 #define MAX_PTE32_ENTRIES          1024
 #define MAX_PDE32_ENTRIES          1024
 
+#define MAX_PTE32PAE_ENTRIES       512
+#define MAX_PDE32PAE_ENTRIES       512
+#define MAX_PDPE32PAE_ENTRIES      4
+
 #define MAX_PTE64_ENTRIES          512
 #define MAX_PDE64_ENTRIES          512
 #define MAX_PDPE64_ENTRIES         512
@@ -86,11 +109,30 @@ the host state in the vmcs before entering the guest.
 #define PDE32_INDEX(x)  ((((uint_t)x) >> 22) & 0x3ff)
 #define PTE32_INDEX(x)  ((((uint_t)x) >> 12) & 0x3ff)
 
+
 /* Gets the base address needed for a Page Table entry */
+/* Deprecate these :*/
 #define PD32_BASE_ADDR(x) (((uint_t)x) >> 12)
 #define PT32_BASE_ADDR(x) (((uint_t)x) >> 12)
 #define PD32_4MB_BASE_ADDR(x) (((uint_t)x) >> 22)
 
+#define PML4E64_BASE_ADDR(x) (((ullong_t)x) >> 12)
+#define PDPE64_BASE_ADDR(x) (((ullong_t)x) >> 12)
+#define PDE64_BASE_ADDR(x) (((ullong_t)x) >> 12)
+#define PTE64_BASE_ADDR(x) (((ullong_t)x) >> 12)
+/* Accessor functions for the page table structures */
+#define PDE32_T_ADDR(x) (((x).pt_base_addr) << 12)
+#define PTE32_T_ADDR(x) (((x).page_base_addr) << 12)
+#define PDE32_4MB_T_ADDR(x) (((x).page_base_addr) << 22)
+
+/* Replace The above with these... */
+#define PAGE_BASE_ADDR(x) (((uint_t)x) >> 12)
+#define LARGE_PAGE_BASE_ADDR(x) (((uint_t)x) >> 22)
+#define BASE_TO_PAGE_ADDR(x) (((uint_t)x) << 12)
+#define LARGE_BASE_TO_PAGE_ADDR(x) (((uint_t)x) << 22)
+
+
+
 #define PT32_PAGE_ADDR(x)   (((uint_t)x) & 0xfffff000)
 #define PT32_PAGE_OFFSET(x) (((uint_t)x) & 0xfff)
 #define PT32_PAGE_POWER 12
@@ -110,24 +152,21 @@ the host state in the vmcs before entering the guest.
 
 
 
-#define CR3_TO_PDE32(cr3) (((ulong_t)cr3) & 0xfffff000)
-#define CR3_TO_PDPTRE(cr3) (((ulong_t)cr3) & 0xffffffe0)
-#define CR3_TO_PML4E64(cr3)  (((ullong_t)cr3) & 0x000ffffffffff000LL)
+#define CR3_TO_PDE32(cr3) (V3_VAddr((void *)(((ulong_t)cr3) & 0xfffff000)))
+#define CR3_TO_PDPTRE(cr3) (V3_VAddr((void *)(((ulong_t)cr3) & 0xffffffe0)))
+#define CR3_TO_PML4E64(cr3)  (V3_VAddr((void *)(((ullong_t)cr3) & 0x000ffffffffff000LL)))
+
 
 
 
 
-/* Accessor functions for the page table structures */
-#define PDE32_T_ADDR(x) (((x).pt_base_addr) << 12)
-#define PTE32_T_ADDR(x) (((x).page_base_addr) << 12)
-#define PDE32_4MB_T_ADDR(x) (((x).page_base_addr) << 22)
 
 /* Page Table Flag Values */
 #define PT32_HOOK 0x1
 #define PT32_GUEST_PT 0x2
 
 
-#endif
+
 
 /* PDE 32 bit PAGE STRUCTURES */
 typedef enum {PDE32_ENTRY_NOT_PRESENT, PDE32_ENTRY_PTE32, PDE32_ENTRY_LARGE_PAGE} pde32_entry_type_t;
@@ -145,7 +184,7 @@ typedef struct pde32 {
   uint_t global_page     : 1;
   uint_t vmm_info        : 3;
   uint_t pt_base_addr    : 20;
-} pde32_t;
+} __attribute__((packed))  pde32_t;
 
 typedef struct pde32_4MB {
   uint_t present         : 1;
@@ -162,7 +201,7 @@ typedef struct pde32_4MB {
   uint_t rsvd            : 9;
   uint_t page_base_addr  : 10;
 
-} pde32_4MB_t;
+} __attribute__((packed))  pde32_4MB_t;
 
 typedef struct pte32 {
   uint_t present         : 1;
@@ -176,14 +215,76 @@ typedef struct pte32 {
   uint_t global_page     : 1;
   uint_t vmm_info        : 3;
   uint_t page_base_addr  : 20;
-} pte32_t;
+}  __attribute__((packed)) pte32_t;
 /* ***** */
 
 /* 32 bit PAE PAGE STRUCTURES */
+typedef struct pdpe32pae {
+  uint_t present       : 1;
+  uint_t rsvd          : 2; // MBZ
+  uint_t write_through : 1;
+  uint_t cache_disable : 1;
+  uint_t accessed      : 1; 
+  uint_t avail         : 1;
+  uint_t rsvd2         : 2;  // MBZ
+  uint_t vmm_info      : 3;
+  uint_t pd_base_addr  : 24;
+  uint_t rsvd3         : 28; // MBZ
+} __attribute__((packed)) pdpe32pae_t;
+
+
+
+typedef struct pde32pae {
+  uint_t present         : 1;
+  uint_t writable        : 1;
+  uint_t user_page       : 1;
+  uint_t write_through   : 1;
+  uint_t cache_disable   : 1;
+  uint_t accessed        : 1;
+  uint_t avail           : 1;
+  uint_t large_page      : 1;
+  uint_t global_page     : 1;
+  uint_t vmm_info        : 3;
+  uint_t pt_base_addr    : 24;
+  uint_t rsvd            : 28;
+} __attribute__((packed)) pde32pae_t;
+
+typedef struct pde32pae_4MB {
+  uint_t present         : 1;
+  uint_t writable        : 1;
+  uint_t user_page       : 1;
+  uint_t write_through   : 1;
+  uint_t cache_disable   : 1;
+  uint_t accessed        : 1;
+  uint_t dirty           : 1;
+  uint_t one             : 1;
+  uint_t global_page     : 1;
+  uint_t vmm_info        : 3;
+  uint_t pat             : 1;
+  uint_t rsvd            : 9;
+  uint_t page_base_addr  : 14;
+  uint_t rsvd2           : 28;
+
+} __attribute__((packed)) pde32pae_4MB_t;
+
+typedef struct pte32pae {
+  uint_t present         : 1;
+  uint_t writable        : 1;
+  uint_t user_page       : 1;
+  uint_t write_through   : 1;
+  uint_t cache_disable   : 1;
+  uint_t accessed        : 1;
+  uint_t dirty           : 1;
+  uint_t pte_attr        : 1;
+  uint_t global_page     : 1;
+  uint_t vmm_info        : 3;
+  uint_t page_base_addr  : 24;
+  uint_t rsvd            : 28;
+} __attribute__((packed)) pte32pae_t;
+
+
+
 
-//
-// Fill in
-//
 
 /* ********** */
 
@@ -192,67 +293,69 @@ typedef struct pte32 {
 typedef struct pml4e64 {
   uint_t present        : 1;
   uint_t writable       : 1;
-  uint_t user           : 1;
-  uint_t pwt            : 1;
-  uint_t pcd            : 1;
+  uint_t user_page           : 1;
+  uint_t write_through  : 1;
+  uint_t cache_disable  : 1;
   uint_t accessed       : 1;
   uint_t reserved       : 1;
   uint_t zero           : 2;
   uint_t vmm_info       : 3;
-  uint_t pdp_base_addr_lo : 20;
-  uint_t pdp_base_addr_hi : 20;
+  ullong_t pdp_base_addr : 40;
   uint_t available      : 11;
   uint_t no_execute     : 1;
-} pml4e64_t;
+} __attribute__((packed)) pml4e64_t;
 
 
 typedef struct pdpe64 {
   uint_t present        : 1;
   uint_t writable       : 1;
-  uint_t user           : 1;
-  uint_t pwt            : 1;
-  uint_t pcd            : 1;
+  uint_t user_page           : 1;
+  uint_t write_through  : 1;
+  uint_t cache_disable  : 1;
   uint_t accessed       : 1;
   uint_t reserved       : 1;
-  uint_t large_pages    : 1;
+  uint_t large_page    : 1;
   uint_t zero           : 1;
   uint_t vmm_info       : 3;
-  uint_t pd_base_addr_lo : 20;
-  uint_t pd_base_addr_hi : 20;
+  ullong_t pd_base_addr : 40;
   uint_t available      : 11;
   uint_t no_execute     : 1;
-} pdpe64_t;
+} __attribute__((packed)) pdpe64_t;
 
 
 
 
 typedef struct pde64 {
   uint_t present         : 1;
-  uint_t flags           : 4;
+  uint_t writable        : 1;
+  uint_t user_page       : 1;
+  uint_t write_through   : 1;
+  uint_t cache_disable   : 1;
   uint_t accessed        : 1;
   uint_t reserved        : 1;
-  uint_t large_pages     : 1;
+  uint_t large_page     : 1;
   uint_t reserved2       : 1;
   uint_t vmm_info        : 3;
-  uint_t pt_base_addr_lo    : 20;
-  uint_t pt_base_addr_hi : 20;
+  ullong_t pt_base_addr  : 40;
   uint_t available       : 11;
   uint_t no_execute      : 1;
-} pde64_t;
+} __attribute__((packed)) pde64_t;
 
 typedef struct pte64 {
   uint_t present         : 1;
-  uint_t flags           : 4;
+  uint_t writable        : 1;
+  uint_t user_page       : 1;
+  uint_t write_through   : 1;
+  uint_t cache_disable   : 1;
   uint_t accessed        : 1;
   uint_t dirty           : 1;
   uint_t pte_attr        : 1;
   uint_t global_page     : 1;
   uint_t vmm_info        : 3;
-  uint_t page_base_addr_lo  : 20;
-  uint_t page_base_addr_hi : 20;
+  ullong_t page_base_addr : 40;
   uint_t available       : 11;
   uint_t no_execute      : 1;
-} pte64_t;
+} __attribute__((packed)) pte64_t;
 
 /* *************** */
 
@@ -263,9 +366,7 @@ typedef struct pf_error_code {
   uint_t rsvd_access       : 1; // if 1, fault from reading a 1 from a reserved field (?)
   uint_t ifetch            : 1; // if 1, faulting access was an instr fetch (only with NX)
   uint_t rsvd              : 27;
-} pf_error_t;
-
-typedef enum { PDE32 } paging_mode_t;
+} __attribute__((packed)) pf_error_t;
 
 
 
@@ -291,8 +392,9 @@ pt_access_status_t can_access_pte32(pte32_t * pte, addr_t addr, pf_error_t acces
 
 struct guest_info;
 
-pde32_t * create_passthrough_pde32_pts(struct guest_info * guest_info);
-
+pde32_t * create_passthrough_pts_32(struct guest_info * guest_info);
+pdpe32pae_t * create_passthrough_pts_PAE32(struct guest_info * guest_info);
+pml4e64_t * create_passthrough_pts_64(struct guest_info * info);
 
 
 
@@ -301,13 +403,17 @@ pde32_t * create_passthrough_pde32_pts(struct guest_info * guest_info);
 void PrintDebugPageTables(pde32_t * pde);
 
 
-#ifdef __V3VEE__
 
 
 void PrintPT32(addr_t starting_address, pte32_t * pte);
 void PrintPD32(pde32_t * pde);
 void PrintPTE32(addr_t virtual_address, pte32_t * pte);
 void PrintPDE32(addr_t virtual_address, pde32_t * pde);
+  
+void PrintDebugPageTables32PAE(pdpe32pae_t * pde);
+void PrintPTE32PAE(addr_t virtual_address, pte32pae_t * pte);
+void PrintPDE32PAE(addr_t virtual_address, pde32pae_t * pde);
+void PrintPTE64(addr_t virtual_address, pte64_t * pte);
 
 #endif // !__V3VEE__