X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Finclude%2Fgeekos%2Fvmm_paging.h;h=f18a4921394c2d0ce5eb4d7d7738939a31570c8f;hb=ebf600fd1dc3b43e8100be168452c6e03b8a2dda;hp=6125d5da0bf7d4cc0be8f9a3804e9ecf518b5e79;hpb=04fc4c8fbac29e04f0d0817a2906687c2c972559;p=palacios.git diff --git a/palacios/include/geekos/vmm_paging.h b/palacios/include/geekos/vmm_paging.h index 6125d5d..f18a492 100644 --- a/palacios/include/geekos/vmm_paging.h +++ b/palacios/include/geekos/vmm_paging.h @@ -1,6 +1,7 @@ #ifndef __VMM_PAGING_H #define __VMM_PAGING_H + #include @@ -8,6 +9,73 @@ #include #include +/* + +In the following, when we say "page table", we mean the whole 2 or 4 layer +page table (PDEs, PTEs), etc. + + +guest-visible paging state + This is the state that the guest thinks the machine is using + It consists of + - guest physical memory + The physical memory addresses the guest is allowed to use + (see shadow page maps, below) + - guest page tables + (we care about when the current one changes) + - guest paging registers (these are never written to hardware) + CR0 + CR3 + + +shadow paging state + This the state that the machine will actually use when the guest + is running. It consists of: + - current shadow page table + This is the page table actually useed when the guest is running. + It is changed/regenerated when the guest page table changes + It mostly reflects the guest page table, except that it restricts + physical addresses to those the VMM allocates to the guest. + - shadow page maps + This is a mapping from guest physical memory addresses to + the current location of the guest physical memory content. + It maps from regions of physical memory addresses to regions + located in physical memory or elsewhere. + (8192,16384) -> MEM(8912,...) + (0,8191) -> DISK(65536,..) + - guest paging registers (these are written to guest state) + CR0 + CR3 + +host paging state + This is the state we expect to be operative when the VMM is running. + Typically, this is set up by the host os into which we have embedded + the VMM, but we include the description here for clarity. + - current page table + This is the page table we use when we are executing in + the VMM (or the host os) + - paging regisers + CR0 + CR3 + + +The reason why the shadow paging state and the host paging state are +distinct is to permit the guest to use any virtual address it wants, +irrespective of the addresses the VMM or the host os use. These guest +virtual addresses are reflected in the shadow paging state. When we +exit from the guest, we switch to the host paging state so that any +virtual addresses that overlap between the guest and VMM/host now map +to the physical addresses epxected by the VMM/host. On AMD SVM, this +switch is done by the hardware. On Intel VT, the switch is done +by the hardware as well, but we are responsible for manually updating +the host state in the vmcs before entering the guest. + + +*/ + + + + #define MAX_PAGE_TABLE_ENTRIES 1024 #define MAX_PAGE_DIR_ENTRIES 1024 @@ -20,11 +88,18 @@ #define PAGE_TABLE_INDEX(x) ((((uint_t)x) >> 12) & 0x3ff) #define PAGE_OFFSET(x) ((((uint_t)x) & 0xfff)) -#define PAGE_ALLIGNED_ADDR(x) (((uint_t) (x)) >> 12) -#define PAGE_ADDR(x) (PAGE_ALLIGNED_ADDR(x) << 12) +#define PAGE_ALIGNED_ADDR(x) (((uint_t) (x)) >> 12) + +#ifndef PAGE_ADDR +#define PAGE_ADDR(x) (PAGE_ALIGNED_ADDR(x) << 12) +#endif #define PAGE_POWER 12 +#define CR3_TO_PDE(cr3) (((ulong_t)cr3) & 0xfffff000) +#define CR3_TO_PDPTRE(cr3) (((ulong_t)cr3) & 0xffffffe0) +#define CR3_TO_PML4E(cr3) (((ullong_t)cr3) & 0x000ffffffffff000) + #define VM_WRITE 1 #define VM_USER 2 #define VM_NOCACHE 8 @@ -32,9 +107,6 @@ #define VM_EXEC 0 -#define GUEST_PAGE 0x0 -#define SHARED_PAGE 0x1 - typedef struct pde { uint_t present : 1; uint_t flags : 4; @@ -122,14 +194,41 @@ typedef struct pml4e { } pml4e64_t; -vmm_pde_t * generate_guest_page_tables(vmm_mem_layout_t * layout, vmm_mem_list_t * list); -pml4e64_t * generate_guest_page_tables_64(vmm_mem_layout_t * layout, vmm_mem_list_t * list); -void free_guest_page_tables(vmm_pde_t * pde); +typedef enum { PDE32 } paging_mode_t; -void PrintDebugPageTables(vmm_pde_t * pde); +typedef struct shadow_page_state { + + // these two reflect the top-level page directory + // of the guest page table + paging_mode_t guest_mode; + reg_ex_t guest_cr3; // points to guest's current page table + // Should thi sbe here + reg_ex_t guest_cr0; + + // these two reflect the top-level page directory + // the shadow page table + paging_mode_t shadow_mode; + reg_ex_t shadow_cr3; + + +} shadow_page_state_t; + + + +int init_shadow_page_state(shadow_page_state_t * state); + +// This function will cause the shadow page table to be deleted +// and rewritten to reflect the guest page table and the shadow map +int wholesale_update_shadow_page_state(shadow_page_state_t * state, shadow_map_t * mem_map); + +vmm_pde_t * create_passthrough_pde32_pts(shadow_map_t * map); + +//void free_guest_page_tables(vmm_pde_t * pde); + +void PrintDebugPageTables(vmm_pde_t * pde); #endif