37 |
#include "asm.h" |
#include "asm.h" |
38 |
#include "cpu_mmu.h" |
#include "cpu_mmu.h" |
39 |
#include "mm.h" |
#include "mm.h" |
40 |
|
#include "mtrr.h" |
41 |
#include "vt_internal.h" |
#include "vt_internal.h" |
42 |
#include "constants.h" |
#include "constants.h" |
43 |
#include "current.h" |
#include "current.h" |
50 |
#define EPT_WRITE 0x2 |
#define EPT_WRITE 0x2 |
51 |
#define EPT_EXECUTE 0x4 |
#define EPT_EXECUTE 0x4 |
52 |
#define EPT_VAILED_MASK 0x7 |
#define EPT_VAILED_MASK 0x7 |
53 |
|
#define EPT_MEMTYPE_TO_PTE(memtype) ((memtype) << 3) |
54 |
|
|
55 |
#define EPT_WB 0x6 |
#define VMCS_EPT_POINTER_ADDR_WB 0x6 |
56 |
#define EPT_LENGTH ((EPT_MAX_LEVEL - 1) << 3) |
#define VMCS_EPT_POINTER_ADDR_EPT_LENGTH ((EPT_MAX_LEVEL - 1) << 3) |
57 |
|
|
58 |
#define VMCS_EXIT_QUALIFICATION_READ_BIT 0x1 |
#define VMCS_EXIT_QUALIFICATION_READ_BIT 0x1 |
59 |
#define VMCS_EXIT_QUALIFICATION_WRITE_BIT 0x2 |
#define VMCS_EXIT_QUALIFICATION_WRITE_BIT 0x2 |
127 |
asm_vmwrite (VMCS_PAGEFAULT_ERRCODE_MATCH, 0xffffffff); |
asm_vmwrite (VMCS_PAGEFAULT_ERRCODE_MATCH, 0xffffffff); |
128 |
|
|
129 |
asm_vmwrite64(VMCS_EPT_POINTER_ADDR, |
asm_vmwrite64(VMCS_EPT_POINTER_ADDR, |
130 |
vt_data->ept_l4tbl | EPT_WB | EPT_LENGTH); |
vt_data->ept_l4tbl | |
131 |
|
VMCS_EPT_POINTER_ADDR_WB | |
132 |
|
VMCS_EPT_POINTER_ADDR_EPT_LENGTH); |
133 |
} |
} |
134 |
|
|
135 |
static u64 * |
static u64 * |
194 |
struct vt_vm_data *vt_data = ¤t->vm->vt; |
struct vt_vm_data *vt_data = ¤t->vm->vt; |
195 |
void *ept_l4tbl; |
void *ept_l4tbl; |
196 |
u64 *pte; |
u64 *pte; |
197 |
|
u8 memtype; |
198 |
phys_t gphys; |
phys_t gphys; |
199 |
phys_t hphys; |
phys_t hphys; |
200 |
vmmerr_t ret; |
vmmerr_t ret; |
232 |
return; |
return; |
233 |
} |
} |
234 |
|
|
235 |
|
memtype = mtrr_get_mem_type(hphys); |
236 |
|
|
237 |
spinlock_lock(&vt_data->ept_lock); |
spinlock_lock(&vt_data->ept_lock); |
238 |
ept_l4tbl = (void *)phys_to_virt(vt_data->ept_l4tbl); |
ept_l4tbl = (void *)phys_to_virt(vt_data->ept_l4tbl); |
239 |
pte = vt_ept_walk(gphys, ept_l4tbl); |
pte = vt_ept_walk(gphys, ept_l4tbl); |
240 |
*pte = (hphys & PAGE_MASK) | |
|
241 |
EPT_READ | EPT_WRITE | EPT_EXECUTE; /* UC for now */ |
if (*pte & EPT_VAILED_MASK) { |
242 |
|
if ((*pte & PAGE_MASK) != (hphys & PAGE_MASK)) { |
243 |
|
panic("EPT PTE is already set. " |
244 |
|
"gphys 0x%llx, hphys 0x%llx, pte 0x%llx", |
245 |
|
gphys, hphys, *pte); |
246 |
|
} |
247 |
|
} else { |
248 |
|
*pte = (hphys & PAGE_MASK) | |
249 |
|
EPT_READ | EPT_WRITE | EPT_EXECUTE | |
250 |
|
EPT_MEMTYPE_TO_PTE(memtype) | |
251 |
|
0x40; /* Force ept mem type for now */ |
252 |
|
} |
253 |
|
|
254 |
spinlock_unlock(&vt_data->ept_lock); |
spinlock_unlock(&vt_data->ept_lock); |
255 |
|
|