Commit 93a6c0ea authored by Charlie Jacobsen's avatar Charlie Jacobsen Committed by Vikram Narayanan

Added guest physical allocation, cleaned up guest phys code.

parent 42c2e9f4
...@@ -1260,11 +1260,17 @@ static void vmx_free_ept_dir_level(lcd_arch_epte_t *dir, int level) ...@@ -1260,11 +1260,17 @@ static void vmx_free_ept_dir_level(lcd_arch_epte_t *dir, int level)
/* /*
* Base case of recursion * Base case of recursion
* *
* Free the host page frame * Free any mapped host page frames, notify
*
* XXX: This can lead to nasty double frees if we made a
* mistake and just forgot to unmap in the ept.
*/ */
for (idx = 0; idx < LCD_ARCH_PTRS_PER_EPTE; idx++) { for (idx = 0; idx < LCD_ARCH_PTRS_PER_EPTE; idx++) {
if (vmx_epte_present(dir[idx])) if (vmx_epte_present(dir[idx])) {
LCD_ARCH_ERR("memory leak at hva %lx",
hva_val(vmx_epte_hva(dir[idx])));
free_page(hva_val(vmx_epte_hva(dir[idx]))); free_page(hva_val(vmx_epte_hva(dir[idx])));
}
} }
} else { } else {
/* /*
......
...@@ -66,10 +66,58 @@ struct lcd_thread { ...@@ -66,10 +66,58 @@ struct lcd_thread {
* LCD Memory Layout * LCD Memory Layout
* ================= * =================
* *
* The layout below reflects the guest physical *and* virtual memory * Guest Physical
* layout. This means guest physical and virtual addresses have identical * --------------
* values. (See the arch-dependent code header for the arch-dependent *
* part of the address space.) * The low addresses are occupied by the arch-dependent chunk of memory.
* We use a 16 MB part of the guest physical address space for dynamically
* mapping pages as they are allocated for the LCD, and a simple bitmap
* for tracking which pages in the address space are allocated.
*
* The rest of guest physical is unused, and the top part is unusable (see
* Intel SDM V3 28.2.2). Some of the guest virtual address space code uses
* host code for paging - and this depends on the host's physical address
* configuration (e.g., extracting a guest physical address from a page
* table entry will use the physical address width of the host). Beware!
*
* +---------------------------+ 0xFFFF FFFF FFFF FFFF
* | |
* | Unusable |
* | |
* +---------------------------+ 0x0000 FFFF FFFF FFFF
* | |
* | |
* : Free Guest Physical :
* : Space :
* | |
* | |
* +---------------------------+
* | |
* | Guest Physical | (16 MBs)
* | "Page Heap" |
* | |
* LCD_ARCH_TOP----> +---------------------------+
* | |
* : Reserved Arch Memory :
* | |
* LCD_ARCH_BOTTOM-> +---------------------------+
* : Not mapped :
* +---------------------------+ 0x0000 0000 0000 0000
*
* Guest Virtual
* -------------
*
* Since we will be running modules (for now), and these are mapped in the
* host at high addresses, we have set up the address space to accomodate
* that.
*
* -- Arch-dependent memory is mapped "one-to-one" to guest physical
* addresses.
* -- A 4 MB part is used for a temporary boot guest virtual address
* space.
* -- A 4 KB page is for the initial thread's stack/utcb.
* -- The module is mapped in the guest virtual at the same place that it is
* in the host virtual - so we can avoid relocating symbols, etc.
* *
* Stack/utcb pages: Except for the first thread, these are set up on demand. * Stack/utcb pages: Except for the first thread, these are set up on demand.
* The microkernel will set up and map the first thread's stack/utcb in the * The microkernel will set up and map the first thread's stack/utcb in the
...@@ -80,20 +128,15 @@ struct lcd_thread { ...@@ -80,20 +128,15 @@ struct lcd_thread {
* makes the microkernel logic simpler and puts the tricky/vulnerable * makes the microkernel logic simpler and puts the tricky/vulnerable
* guest address space allocation logic inside the LCD. * guest address space allocation logic inside the LCD.
* *
* The module is mapped to the same guest physical / guest virtual
* address space as the host, to avoid relocating symbols.
*
* The LCD is free to modify its guest virtual -> guest physical mappings after * The LCD is free to modify its guest virtual -> guest physical mappings after
* it starts. The guest virtual paging memory is for the microkernel's * it starts.
* initial set up of the guest virtual address space (mapping the arch
* dependent chunks, the module, and the stack for the first thread).
* *
* +---------------------------+ * +---------------------------+ 0xFFFF FFFF FFFF FFFF
* module mapped | | * | |
* somewhere in : : * | |
* here -------> : : * : Free Guest Virtual :
* at a higher | FREE SPACE | * : Space :
* address | | * | |
* | | * | |
* +---------------------------+ * +---------------------------+
* | Stack 0 | * | Stack 0 |
...@@ -106,10 +149,16 @@ struct lcd_thread { ...@@ -106,10 +149,16 @@ struct lcd_thread {
* | | * | |
* : Reserved Arch Memory : * : Reserved Arch Memory :
* | | * | |
* LCD_ARCH_BOTTOM-> +---------------------------+
* : Not mapped :
* +---------------------------+ 0x0000 0000 0000 0000 * +---------------------------+ 0x0000 0000 0000 0000
*/ */
#define LCD_PAGING_MEM_SIZE (4 << 20) #define LCD_GP_MEM_SIZE (16 << 20)
#define LCD_GP_BMAP_NBITS (LCD_GP_MEM_SIZE >> PAGE_SHIFT)
#define LCD_GP_MEM_START LCD_ARCH_TOP
#define LCD_GV_MEM_SIZE (4 << 20)
#define LCD_GV_MEM_START LCD_ARCH_TOP
struct lcd { struct lcd {
/* /*
...@@ -132,6 +181,15 @@ struct lcd { ...@@ -132,6 +181,15 @@ struct lcd {
struct mutex lock; struct mutex lock;
unsigned int count; unsigned int count;
} lcd_threads; } lcd_threads;
/*
* Guest physical address space
*
* We use a simple bitmap to track allocation of pages in the
* guest physical address space.
*/
struct {
DECLARE_BITMAP(bmap, LCD_GP_BMAP_NBITS);
} gp_paging;
/* /*
* Guest virtual paging * Guest virtual paging
* *
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment