SELFOUR-501: x86 - Remove PAE support

This commit is contained in:
Hesham Almatary 2016-10-20 10:23:53 +11:00
parent 135ab71dff
commit 3e57e647e9
15 changed files with 14 additions and 697 deletions

View file

@ -29,11 +29,7 @@ endpoint_ptr_get_epQueue_tail_fp(endpoint_t *ep_ptr)
static inline vspace_root_t *
cap_vtable_cap_get_vspace_root_fp(cap_t vtable_cap)
{
#if defined(CONFIG_PAE_PAGING)
return PDPTE_PTR(cap_pdpt_cap_get_capPDPTBasePtr(vtable_cap));
#else
return PDE_PTR(cap_page_directory_cap_get_capPDBasePtr(vtable_cap));
#endif
}
static inline void FORCE_INLINE
@ -72,11 +68,7 @@ mdb_node_ptr_set_mdbPrev_np(mdb_node_t *node_ptr, word_t mdbPrev)
static inline bool_t
isValidVTableRoot_fp(cap_t vspace_root_cap)
{
#if defined(CONFIG_PAE_PAGING)
return likely(cap_capType_equals(vspace_root_cap, cap_pdpt_cap) && cap_pdpt_cap_get_capPDPTIsMapped(vspace_root_cap));
#else
return likely(cap_capType_equals(vspace_root_cap, cap_page_directory_cap) && cap_page_directory_cap_get_capPDIsMapped(vspace_root_cap));
#endif
return cap_capType_equals(vspace_root_cap, cap_page_directory_cap) && cap_page_directory_cap_get_capPDIsMapped(vspace_root_cap);
}
static inline void

View file

@ -59,16 +59,6 @@ block page_directory_cap {
field capType 4
}
block pdpt_cap {
padding 19
field capPDPTIsMapped 1
field capPDPTMappedASID 12
padding 1
field_high capPDPTBasePtr 27
field capType 4
}
-- Cap to the table of 2^6 ASID pools
block asid_control_cap {
padding 32
@ -201,7 +191,6 @@ tagged_union cap capType {
tag frame_cap 1
tag page_table_cap 3
tag page_directory_cap 5
tag pdpt_cap 7
tag asid_control_cap 9
tag asid_pool_cap 11
tag io_space_cap 13
@ -413,9 +402,6 @@ block pdpte {
}
block pde_small {
#ifdef CONFIG_PAE_PAGING
padding 32
#endif
field_high pt_base_address 20
field avl 3
padding 1
@ -430,9 +416,6 @@ block pde_small {
}
block pde_large {
#ifdef CONFIG_PAE_PAGING
padding 32
#endif
field_high page_base_address 11
padding 8
field pat 1
@ -454,9 +437,6 @@ tagged_union pde page_size {
}
block pte {
#ifdef CONFIG_PAE_PAGING
padding 32
#endif
field_high page_base_address 20
field avl 3
field global 1

View file

@ -23,16 +23,6 @@
#define GDT_IPCBUF 7
#define GDT_ENTRIES 8
#ifdef CONFIG_PAE_PAGING
#define PDPTE_SIZE_BITS 3
#define PDPT_INDEX_BITS 2
#define PDE_SIZE_BITS 3
#define PD_INDEX_BITS 9
#define PTE_SIZE_BITS 3
#define PT_INDEX_BITS 9
#define X86_GLOBAL_VSPACE_ROOT ia32KSGlobalPDPT
typedef pdpte_t vspace_root_t;
#else
#define PDPTE_SIZE_BITS 0
#define PDPT_INDEX_BITS 0
#define PDE_SIZE_BITS 2
@ -41,7 +31,6 @@ typedef pdpte_t vspace_root_t;
#define PT_INDEX_BITS 10
#define X86_GLOBAL_VSPACE_ROOT ia32KSGlobalPD
typedef pde_t vspace_root_t;
#endif
#define GET_VSPACE_ROOT_INDEX(x) ((x) >> (seL4_PageBits + PT_INDEX_BITS))
@ -128,9 +117,6 @@ cap_get_capMappedASID(cap_t cap)
ctag = cap_get_capType(cap);
switch (ctag) {
case cap_pdpt_cap:
return cap_pdpt_cap_get_capPDPTMappedASID(cap);
case cap_page_directory_cap:
return cap_page_directory_cap_get_capPDMappedASID(cap);

View file

@ -168,9 +168,6 @@ cap_get_archCapSizeBits(cap_t cap)
case cap_page_directory_cap:
return seL4_PageDirBits;
case cap_pdpt_cap:
return seL4_PDPTBits;
case cap_io_port_cap:
return 0;
case cap_io_space_cap:
@ -221,9 +218,6 @@ cap_get_archCapIsPhysical(cap_t cap)
case cap_page_directory_cap:
return true;
case cap_pdpt_cap:
return true;
case cap_io_port_cap:
return false;
@ -276,9 +270,6 @@ cap_get_archCapPtr(cap_t cap)
case cap_page_directory_cap:
return PT_PTR(cap_page_directory_cap_get_capPDBasePtr(cap));
case cap_pdpt_cap:
return PDPT_PTR(cap_pdpt_cap_get_capPDPTBasePtr(cap));
case cap_io_port_cap:
return NULL;

View file

@ -18,11 +18,7 @@
#define PADDR_LOAD 0x00100000
#define PPTR_BASE 0xe0000000
#ifdef CONFIG_PAE_PAGING
#define PPTR_USER_TOP (PPTR_BASE & (~MASK(seL4_HugePageBits)))
#else
#define PPTR_USER_TOP (PPTR_BASE & (~MASK(seL4_LargePageBits)))
#endif
/* Calculate virtual address space reserved for TLB Bitmap. ROOT_ENTRIES
* will be zero in the case where the bitmap is unused */

View file

@ -14,12 +14,7 @@
#include <autoconf.h>
#define SEL4_MAPPING_LOOKUP_LEVEL 2
#ifdef CONFIG_PAE_PAGING
#define SEL4_MAPPING_LOOKUP_NO_PT 21
#define SEL4_MAPPING_LOOKUP_NO_PD 30
#else
#define SEL4_MAPPING_LOOKUP_NO_PT 22
#endif
LIBSEL4_INLINE_FUNC seL4_Word seL4_MappingFailedLookupLevel(void)
{

View file

@ -16,16 +16,9 @@
#endif /* HAVE_AUTOCONF */
typedef enum _mode_object {
#ifdef CONFIG_PAE_PAGING
seL4_IA32_PDPTObject = seL4_NonArchObjectTypeCount,
seL4_ModeObjectTypeCount
#else
seL4_ModeObjectTypeCount = seL4_NonArchObjectTypeCount,
#endif
} seL4_ModeObjectType;
#ifndef CONFIG_PAE_PAGING
#define seL4_IA32_PDPTObject 0xffffffff
#endif
#endif

View file

@ -36,14 +36,6 @@ BEGIN_FUNC(enable_paging)
orl $0x10, %eax
movl %eax, %cr4
#ifdef CONFIG_PAE_PAGING
# Set PAE (bit 5) so that we will switch to PAE paging mode
# when we enable paging below
movl %cr4, %eax
orl $0x20, %eax
movl %eax, %cr4
#endif
# Load the boot PD (or PDPT) address into CR3
leal _boot_pd, %eax
movl %eax, %cr3

View file

@ -9,7 +9,6 @@
#
ARCH_C_SOURCES += 32/kernel/vspace_32paging.c \
32/kernel/vspace_pae.c \
32/kernel/thread.c \
32/kernel/vspace.c \
32/kernel/elf.c \

View file

@ -220,18 +220,6 @@ map_kernel_window(
pte_t pte;
unsigned int UNUSED i;
if (config_set(CONFIG_PAE_PAGING)) {
for (idx = 0; idx < BIT(PDPT_INDEX_BITS); idx++) {
pdpte_ptr_new(&ia32KSGlobalPDPT[idx],
pptr_to_paddr(&ia32KSGlobalPD[idx * BIT(PD_INDEX_BITS)]),
0, /* avl*/
0, /* cache_disabled */
0, /* write_through */
1 /* present */
);
}
}
/* Mapping of PPTR_BASE (virtual address) to kernel's PADDR_BASE
* up to end of virtual address space except for the last large page.
*/
@ -461,68 +449,18 @@ create_it_address_space(cap_t root_cnode_cap, v_region_t it_v_reg)
seL4_SlotPos slot_pos_after;
slot_pos_before = ndks_boot.slot_pos_cur;
if (PDPT_INDEX_BITS == 0) {
cap_t pd_cap;
pptr_t pd_pptr;
/* just create single PD obj and cap */
pd_pptr = alloc_region(seL4_PageDirBits);
if (!pd_pptr) {
return cap_null_cap_new();
}
memzero(PDE_PTR(pd_pptr), 1 << seL4_PageDirBits);
copyGlobalMappings((vspace_root_t*)pd_pptr);
pd_cap = create_it_page_directory_cap(cap_null_cap_new(), pd_pptr, 0, IT_ASID);
write_slot(SLOT_PTR(pptr_of_cap(root_cnode_cap), seL4_CapInitThreadVSpace), pd_cap);
vspace_cap = pd_cap;
} else {
cap_t pdpt_cap;
pptr_t pdpt_pptr;
unsigned int i;
/* create a PDPT obj and cap */
pdpt_pptr = alloc_region(seL4_PDPTBits);
if (!pdpt_pptr) {
return cap_null_cap_new();
}
memzero(PDPTE_PTR(pdpt_pptr), 1 << seL4_PDPTBits);
pdpt_cap = cap_pdpt_cap_new(
true, /* capPDPTISMapped */
IT_ASID, /* capPDPTMappedASID */
pdpt_pptr /* capPDPTBasePtr */
);
/* create all PD objs and caps necessary to cover userland image. For simplicity
* to ensure we also cover the kernel window we create all PDs */
for (i = 0; i < BIT(PDPT_INDEX_BITS); i++) {
/* The compiler is under the mistaken belief here that this shift could be
* undefined. However, in the case that it would be undefined this code path
* is not reachable because PDPT_INDEX_BITS == 0 (see if statement at the top of
* this function), so to work around it we must both put in a redundant
* if statement AND place the shift in a variable. While the variable
* will get compiled away it prevents the compiler from evaluating
* the 1 << 32 as a constant when it shouldn't
* tl;dr gcc evaluates constants even if code is unreachable */
int shift = (PD_INDEX_BITS + PT_INDEX_BITS + PAGE_BITS);
if (shift != 32) {
vptr = i << shift;
} else {
return cap_null_cap_new();
}
pptr = alloc_region(seL4_PageDirBits);
if (!pptr) {
return cap_null_cap_new();
}
memzero(PDE_PTR(pptr), 1 << seL4_PageDirBits);
if (!provide_cap(root_cnode_cap,
create_it_page_directory_cap(pdpt_cap, pptr, vptr, IT_ASID))
) {
return cap_null_cap_new();
}
}
/* now that PDs exist we can copy the global mappings */
copyGlobalMappings((vspace_root_t*)pdpt_pptr);
write_slot(SLOT_PTR(pptr_of_cap(root_cnode_cap), seL4_CapInitThreadVSpace), pdpt_cap);
vspace_cap = pdpt_cap;
cap_t pd_cap;
pptr_t pd_pptr;
/* just create single PD obj and cap */
pd_pptr = alloc_region(seL4_PageDirBits);
if (!pd_pptr) {
return cap_null_cap_new();
}
memzero(PDE_PTR(pd_pptr), 1 << seL4_PageDirBits);
copyGlobalMappings((vspace_root_t*)pd_pptr);
pd_cap = create_it_page_directory_cap(cap_null_cap_new(), pd_pptr, 0, IT_ASID);
write_slot(SLOT_PTR(pptr_of_cap(root_cnode_cap), seL4_CapInitThreadVSpace), pd_cap);
vspace_cap = pd_cap;
/* create all PT objs and caps necessary to cover userland image */
@ -698,11 +636,7 @@ void setVMRoot(tcb_t* tcb)
vspace_root = getValidNativeRoot(threadRoot);
if (!vspace_root) {
SMP_COND_STATEMENT(tlb_bitmap_unset(paddr_to_pptr(getCurrentPD()), getCurrentCPUIndex());)
if (config_set(CONFIG_PAE_PAGING)) {
setCurrentPD(pptr_to_paddr(ia32KSGlobalPDPT));
} else {
setCurrentPD(pptr_to_paddr(ia32KSGlobalPD));
}
setCurrentPD(pptr_to_paddr(ia32KSGlobalPD));
return;
}
@ -710,11 +644,7 @@ void setVMRoot(tcb_t* tcb)
find_ret = findVSpaceForASID(asid);
if (find_ret.status != EXCEPTION_NONE || find_ret.vspace_root != vspace_root) {
SMP_COND_STATEMENT(tlb_bitmap_unset(paddr_to_pptr(getCurrentPD()), getCurrentCPUIndex());)
if (config_set(CONFIG_PAE_PAGING)) {
setCurrentPD(pptr_to_paddr(ia32KSGlobalPDPT));
} else {
setCurrentPD(pptr_to_paddr(ia32KSGlobalPD));
}
setCurrentPD(pptr_to_paddr(ia32KSGlobalPD));
return;
}
@ -745,10 +675,6 @@ decodeX86ModeMMUInvocation(
)
{
switch (cap_get_capType(cap)) {
case cap_pdpt_cap:
current_syscall_error.type = seL4_IllegalOperation;
return EXCEPTION_SYSCALL_ERROR;
case cap_page_directory_cap:
return decodeIA32PageDirectoryInvocation(invLabel, length, cte, cap, excaps, buffer);

View file

@ -22,8 +22,6 @@
#include <arch/linker.h>
#include <util.h>
#ifndef CONFIG_PAE_PAGING
/* setup initial boot page directory */
/* The boot pd is referenced by code that runs before paging, so
@ -399,5 +397,3 @@ Arch_userStackTrace(tcb_t *tptr)
}
}
#endif
#endif

View file

@ -1,479 +0,0 @@
/*
* Copyright 2014, General Dynamics C4 Systems
*
* This software may be distributed and modified according to the terms of
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
* See "LICENSE_GPLv2.txt" for details.
*
* @TAG(GD_GPL)
*/
#include <config.h>
#include <machine/io.h>
#include <kernel/boot.h>
#include <model/statedata.h>
#include <arch/kernel/vspace.h>
#include <util.h>
#ifdef CONFIG_PAE_PAGING
/* The boot pd is referenced by code that runs before paging, so
* place it in PHYS_DATA. In PAE mode the top level is actually
* a PDPTE, but we call it _boot_pd for compatibility */
pdpte_t _boot_pd[BIT(PDPT_INDEX_BITS)] ALIGN(BIT(PAGE_BITS)) VISIBLE PHYS_BSS;
/* Allocate enough page directories to fill every slot in the PDPT */
pde_t _boot_pds[BIT(PD_INDEX_BITS + PDPT_INDEX_BITS)] ALIGN(BIT(PAGE_BITS)) VISIBLE PHYS_BSS;
BOOT_CODE
pde_t *get_boot_pd()
{
/* return a pointer to the continus array of boot pds */
return _boot_pds;
}
/* These functions arefrom what is generated by the bitfield tool. It is
* required by functions that need to call it before the MMU is turned on.
* Any changes made to the bitfield generation need to be replicated here.
*/
PHYS_CODE
static inline void
pdpte_ptr_new_phys(pdpte_t *pdpte_ptr, uint32_t pd_base_address, uint32_t avl, uint32_t cache_disabled, uint32_t write_through, uint32_t present)
{
pdpte_ptr->words[0] = 0;
pdpte_ptr->words[1] = 0;
pdpte_ptr->words[0] |= (pd_base_address & 0xfffff000) >> 0;
pdpte_ptr->words[0] |= (avl & 0x7) << 9;
pdpte_ptr->words[0] |= (cache_disabled & 0x1) << 4;
pdpte_ptr->words[0] |= (write_through & 0x1) << 3;
pdpte_ptr->words[0] |= (present & 0x1) << 0;
}
PHYS_CODE
static inline void
pde_pde_large_ptr_new_phys(pde_t *pde_ptr, uint32_t page_base_address,
uint32_t pat, uint32_t avl, uint32_t global, uint32_t dirty,
uint32_t accessed, uint32_t cache_disabled, uint32_t write_through,
uint32_t super_user, uint32_t read_write, uint32_t present)
{
pde_ptr->words[0] = 0;
pde_ptr->words[1] = 0;
pde_ptr->words[0] |= (page_base_address & 0xffe00000) >> 0;
pde_ptr->words[0] |= (pat & 0x1) << 12;
pde_ptr->words[0] |= (avl & 0x7) << 9;
pde_ptr->words[0] |= (global & 0x1) << 8;
pde_ptr->words[0] |= ((uint32_t)pde_pde_large & 0x1) << 7;
pde_ptr->words[0] |= (dirty & 0x1) << 6;
pde_ptr->words[0] |= (accessed & 0x1) << 5;
pde_ptr->words[0] |= (cache_disabled & 0x1) << 4;
pde_ptr->words[0] |= (write_through & 0x1) << 3;
pde_ptr->words[0] |= (super_user & 0x1) << 2;
pde_ptr->words[0] |= (read_write & 0x1) << 1;
pde_ptr->words[0] |= (present & 0x1) << 0;
}
PHYS_CODE VISIBLE void
init_boot_pd(void)
{
word_t i;
/* first map in all the pds into the pdpt */
for (i = 0; i < BIT(PDPT_INDEX_BITS); i++) {
uint32_t pd_base = (uint32_t)&_boot_pds[i * BIT(PD_INDEX_BITS)];
pdpte_ptr_new_phys(
_boot_pd + i,
pd_base, /* pd_base_address */
0, /* avl */
0, /* cache_disabled */
0, /* write_through */
1 /* present */
);
}
/* identity mapping from 0 up to PPTR_BASE (virtual address) */
for (i = 0; (i << seL4_LargePageBits) < PPTR_BASE; i++) {
pde_pde_large_ptr_new_phys(
_boot_pds + i,
i << seL4_LargePageBits, /* physical address */
0, /* pat */
0, /* avl */
1, /* global */
0, /* dirty */
0, /* accessed */
0, /* cache_disabled */
0, /* write_through */
0, /* super_user */
1, /* read_write */
1 /* present */
);
}
/* mapping of PPTR_BASE (virtual address) to PADDR_BASE up to end of virtual address space */
for (i = 0; (i << seL4_LargePageBits) < -PPTR_BASE; i++) {
pde_pde_large_ptr_new_phys(
_boot_pds + i + (PPTR_BASE >> seL4_LargePageBits),
(i << seL4_LargePageBits) + PADDR_BASE, /* physical address */
0, /* pat */
0, /* avl */
1, /* global */
0, /* dirty */
0, /* accessed */
0, /* cache_disabled */
0, /* write_through */
0, /* super_user */
1, /* read_write */
1 /* present */
);
}
}
BOOT_CODE void
map_it_frame_cap(cap_t vspace_cap, cap_t frame_cap)
{
pdpte_t *pdpt = PDPTE_PTR(pptr_of_cap(vspace_cap));
pde_t *pd;
pte_t *pt;
void *frame = (void*)cap_frame_cap_get_capFBasePtr(frame_cap);
vptr_t vptr = cap_frame_cap_get_capFMappedAddress(frame_cap);
assert(cap_frame_cap_get_capFMappedASID(frame_cap) != 0);
pdpt += (vptr >> seL4_HugePageBits);
assert(pdpte_ptr_get_present(pdpt));
pd = paddr_to_pptr(pdpte_ptr_get_pd_base_address(pdpt));
pd += ( (vptr & MASK(seL4_HugePageBits)) >> seL4_LargePageBits);
assert(pde_pde_small_ptr_get_present(pd));
pt = paddr_to_pptr(pde_pde_small_ptr_get_pt_base_address(pd));
pte_ptr_new(
pt + ((vptr & MASK(seL4_LargePageBits)) >> seL4_PageBits),
pptr_to_paddr(frame),
0, /* avl */
0, /* global */
0, /* pat */
0, /* dirty */
0, /* accessed */
0, /* cache_disabled */
0, /* write_through */
1, /* super_user */
1, /* read_write */
1 /* present */
);
invalidateLocalPageStructureCache();
}
BOOT_CODE void
map_it_pt_cap(cap_t vspace_cap, cap_t pt_cap)
{
pdpte_t *pdpt = PDPTE_PTR(pptr_of_cap(vspace_cap));
pde_t *pd;
pte_t *pt = PT_PTR(cap_page_table_cap_get_capPTBasePtr(pt_cap));
vptr_t vptr = cap_page_table_cap_get_capPTMappedAddress(pt_cap);
assert(cap_page_table_cap_get_capPTIsMapped(pt_cap));
pdpt += (vptr >> seL4_HugePageBits);
assert(pdpte_ptr_get_present(pdpt));
pd = paddr_to_pptr(pdpte_ptr_get_pd_base_address(pdpt));
pde_pde_small_ptr_new(
pd + (vptr >> seL4_LargePageBits),
pptr_to_paddr(pt),
0, /* avl*/
0, /* accessed */
0, /* cache_disabled */
0, /* write_through */
1, /* super_user */
1, /* read_write */
1 /* present */
);
invalidateLocalPageStructureCache();
}
BOOT_CODE void
map_it_pd_cap(cap_t vspace_cap, cap_t pd_cap)
{
pdpte_t *pdpt = PDPTE_PTR(pptr_of_cap(vspace_cap));
pde_t *pd = PDE_PTR(cap_page_directory_cap_get_capPDBasePtr(pd_cap));
vptr_t vptr = cap_page_directory_cap_get_capPDMappedAddress(pd_cap);
assert(cap_page_directory_cap_get_capPDIsMapped(pd_cap));
pdpte_ptr_new(
pdpt + (vptr >> seL4_HugePageBits),
pptr_to_paddr(pd),
0, /* avl */
0, /* cache_disabled */
0, /* write_through */
1 /* present */
);
invalidateLocalPageStructureCache();
}
/* ==================== BOOT CODE FINISHES HERE ==================== */
void copyGlobalMappings(vspace_root_t* new_vspace)
{
word_t i;
pdpte_t *pdpt = (pdpte_t*)new_vspace;
for (i = PPTR_BASE >> seL4_HugePageBits; i < BIT(PDPT_INDEX_BITS); i++) {
pdpt[i] = ia32KSGlobalPDPT[i];
}
}
bool_t CONST isVTableRoot(cap_t cap)
{
return cap_get_capType(cap) == cap_pdpt_cap;
}
bool_t CONST isValidNativeRoot(cap_t cap)
{
if (!isVTableRoot(cap) ||
!cap_pdpt_cap_get_capPDPTIsMapped(cap)) {
return false;
}
return true;
}
vspace_root_t *getValidNativeRoot(cap_t vspace_cap)
{
if (isValidNativeRoot(vspace_cap)) {
return PDPTE_PTR(cap_pdpt_cap_get_capPDPTBasePtr(vspace_cap));
}
return NULL;
}
static inline pdpte_t *lookupPDPTSlot(vspace_root_t *vspace, vptr_t vptr)
{
pdpte_t *pdpt = PDPT_PTR(vspace);
return pdpt + (vptr >> seL4_HugePageBits);
}
lookupPDSlot_ret_t lookupPDSlot(vspace_root_t *vspace, vptr_t vptr)
{
pdpte_t *pdptSlot;
lookupPDSlot_ret_t ret;
pdptSlot = lookupPDPTSlot(vspace, vptr);
if (!pdpte_ptr_get_present(pdptSlot)) {
current_lookup_fault = lookup_fault_missing_capability_new(PAGE_BITS + PT_INDEX_BITS + PD_INDEX_BITS);
ret.pdSlot = NULL;
ret.status = EXCEPTION_LOOKUP_FAULT;
return ret;
} else {
pde_t *pd;
pde_t *pdSlot;
unsigned int pdIndex;
pd = paddr_to_pptr(pdpte_ptr_get_pd_base_address(pdptSlot));
pdIndex = (vptr >> (PAGE_BITS + PT_INDEX_BITS)) & MASK(PD_INDEX_BITS);
pdSlot = pd + pdIndex;
ret.pdSlot = pdSlot;
ret.status = EXCEPTION_NONE;
return ret;
}
}
exception_t performASIDPoolInvocation(asid_t asid, asid_pool_t* poolPtr, cte_t* vspaceCapSlot)
{
cap_pdpt_cap_ptr_set_capPDPTMappedASID(&vspaceCapSlot->cap, asid);
cap_pdpt_cap_ptr_set_capPDPTIsMapped(&vspaceCapSlot->cap, 1);
poolPtr->array[asid & MASK(asidLowBits)] = PDPTE_PTR(cap_pdpt_cap_get_capPDPTBasePtr(vspaceCapSlot->cap));
return EXCEPTION_NONE;
}
void unmapPageDirectory(asid_t asid, vptr_t vaddr, pde_t *pd)
{
findVSpaceForASID_ret_t find_ret;
cap_t threadRoot;
pdpte_t *pdptSlot;
find_ret = findVSpaceForASID(asid);
if (find_ret.status != EXCEPTION_NONE) {
return;
}
pdptSlot = lookupPDPTSlot(find_ret.vspace_root, vaddr);
/* check if the PDPT has the PD */
if (! (pdpte_ptr_get_present(pdptSlot) &&
(pdpte_ptr_get_pd_base_address(pdptSlot) == pptr_to_paddr(pd)))) {
return;
}
*pdptSlot = pdpte_new(
0, /* pd_base_address */
0, /* avl */
0, /* cache_disabled */
0, /* write_through */
0 /* present */
);
/* check if page directory belongs to current address space */
threadRoot = TCB_PTR_CTE_PTR(NODE_STATE(ksCurThread), tcbVTable)->cap;
if (isValidNativeRoot(threadRoot) && (vspace_root_t*)pptr_of_cap(threadRoot) == find_ret.vspace_root) {
/* according to the intel manual if we modify a pdpt we must
* reload cr3 */
write_cr3(read_cr3());
}
invalidateLocalPageStructureCache();
}
static exception_t
performIA32PageDirectoryInvocationUnmap(cap_t cap, cte_t *ctSlot)
{
if (cap_page_directory_cap_get_capPDIsMapped(cap)) {
pde_t *pd = PDE_PTR(cap_page_directory_cap_get_capPDBasePtr(cap));
unmapPageDirectory(
cap_page_directory_cap_get_capPDMappedASID(cap),
cap_page_directory_cap_get_capPDMappedAddress(cap),
pd
);
clearMemory((void *)pd, cap_get_capSizeBits(cap));
}
cap_page_directory_cap_ptr_set_capPDIsMapped(&(ctSlot->cap), 0);
return EXCEPTION_NONE;
}
static exception_t
performIA32PageDirectoryInvocationMap(cap_t cap, cte_t *ctSlot, pdpte_t pdpte, pdpte_t *pdptSlot, cap_t threadRootCap, cap_t vspaceCap)
{
ctSlot->cap = cap;
*pdptSlot = pdpte;
/* according to the intel manual if we modify a pdpt we must
* reload cr3 */
if (isValidNativeRoot(threadRootCap) && (vspace_root_t *)pptr_of_cap(threadRootCap) == (vspace_root_t *)pptr_of_cap(vspaceCap)) {
write_cr3(read_cr3());
}
invalidateLocalPageStructureCache();
return EXCEPTION_NONE;
}
exception_t
decodeIA32PageDirectoryInvocation(
word_t invLabel,
word_t length,
cte_t* cte,
cap_t cap,
extra_caps_t excaps,
word_t* buffer
)
{
word_t vaddr;
vm_attributes_t attr;
pdpte_t* pdptSlot;
cap_t vspaceCap;
vspace_root_t* vspace;
pdpte_t pdpte;
paddr_t paddr;
asid_t asid;
cap_t threadRoot;
if (invLabel == X86PageDirectoryUnmap) {
if (!isFinalCapability(cte)) {
current_syscall_error.type = seL4_RevokeFirst;
userError("X86PageDirectory: Cannot unmap if more than one cap exists.");
return EXCEPTION_SYSCALL_ERROR;
}
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
return performIA32PageDirectoryInvocationUnmap(cap, cte);
}
if (invLabel != X86PageDirectoryMap) {
userError("X86PageDirectory: Illegal operation.");
current_syscall_error.type = seL4_IllegalOperation;
return EXCEPTION_SYSCALL_ERROR;
}
if (length < 2 || excaps.excaprefs[0] == NULL) {
userError("X86PageDirectory: Truncated message.");
current_syscall_error.type = seL4_TruncatedMessage;
return EXCEPTION_SYSCALL_ERROR;
}
if (cap_page_directory_cap_get_capPDIsMapped(cap)) {
userError("X86PageDirectory: Page directory is already mapped to a PDPT.");
current_syscall_error.type = seL4_InvalidCapability;
current_syscall_error.invalidCapNumber = 0;
return EXCEPTION_SYSCALL_ERROR;
}
vaddr = getSyscallArg(0, buffer) & (~MASK(seL4_HugePageBits));
attr = vmAttributesFromWord(getSyscallArg(1, buffer));
vspaceCap = excaps.excaprefs[0]->cap;
if (!isValidNativeRoot(vspaceCap)) {
current_syscall_error.type = seL4_InvalidCapability;
current_syscall_error.invalidCapNumber = 1;
return EXCEPTION_SYSCALL_ERROR;
}
vspace = (vspace_root_t*)pptr_of_cap(vspaceCap);
asid = cap_get_capMappedASID(vspaceCap);
if (vaddr >= PPTR_USER_TOP) {
userError("X86PageDirectory: Mapping address too high.");
current_syscall_error.type = seL4_InvalidArgument;
current_syscall_error.invalidArgumentNumber = 0;
return EXCEPTION_SYSCALL_ERROR;
}
{
findVSpaceForASID_ret_t find_ret;
find_ret = findVSpaceForASID(asid);
if (find_ret.status != EXCEPTION_NONE) {
current_syscall_error.type = seL4_FailedLookup;
current_syscall_error.failedLookupWasSource = false;
return EXCEPTION_SYSCALL_ERROR;
}
if (find_ret.vspace_root != vspace) {
current_syscall_error.type = seL4_InvalidCapability;
current_syscall_error.invalidCapNumber = 1;
return EXCEPTION_SYSCALL_ERROR;
}
}
pdptSlot = lookupPDPTSlot(vspace, vaddr);
if (pdpte_ptr_get_present(pdptSlot)) {
current_syscall_error.type = seL4_DeleteFirst;
return EXCEPTION_SYSCALL_ERROR;
}
paddr = pptr_to_paddr(PDE_PTR(cap_page_directory_cap_get_capPDBasePtr(cap)));
pdpte = pdpte_new(
paddr, /* pd_base_address */
0, /* avl */
vm_attributes_get_x86PCDBit(attr), /* cache_disabled */
vm_attributes_get_x86PWTBit(attr), /* write_through */
1 /* present */
);
cap = cap_page_directory_cap_set_capPDIsMapped(cap, 1);
cap = cap_page_directory_cap_set_capPDMappedASID(cap, asid);
cap = cap_page_directory_cap_set_capPDMappedAddress(cap, vaddr);
threadRoot = TCB_PTR_CTE_PTR(NODE_STATE(ksCurThread), tcbVTable)->cap;
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
return performIA32PageDirectoryInvocationMap(cap, cte, pdpte, pdptSlot, threadRoot, vspaceCap);
}
#if CONFIG_PRINTING
/* FIXME implement */
void
Arch_userStackTrace(tcb_t *tptr)
{
}
#endif
#endif

View file

@ -60,15 +60,6 @@ cap_t Mode_finaliseCap(cap_t cap, bool_t final)
{
switch (cap_get_capType(cap)) {
case cap_pdpt_cap:
if (final && cap_pdpt_cap_get_capPDPTIsMapped(cap)) {
deleteASID(
cap_pdpt_cap_get_capPDPTMappedASID(cap),
(vspace_root_t*)PDPTE_PTR(cap_pdpt_cap_get_capPDPTBasePtr(cap))
);
}
break;
case cap_frame_cap:
if (final && cap_frame_cap_get_capFMappedASID(cap)) {
switch (cap_frame_cap_get_capFMapType(cap)) {
@ -177,9 +168,7 @@ Mode_createObject(object_t t, void *regionBase, word_t userSize, bool_t deviceMe
);
case seL4_X86_PageDirectoryObject:
#ifndef CONFIG_PAE_PAGING
copyGlobalMappings(regionBase);
#endif
return cap_page_directory_cap_new(
0, /* capPDIsMapped */
asidInvalid, /* capPDMappedASID */
@ -187,17 +176,6 @@ Mode_createObject(object_t t, void *regionBase, word_t userSize, bool_t deviceMe
(word_t)regionBase /* capPDBasePtr */
);
#ifdef CONFIG_PAE_PAGING
case seL4_IA32_PDPTObject:
copyGlobalMappings(regionBase);
return cap_pdpt_cap_new(
0, /* capPDPTIsMapped */
asidInvalid, /* capPDPTMappedAsid*/
(word_t)regionBase /* capPDPTBasePtr */
);
#endif
case seL4_X86_IOPageTableObject:
return cap_io_page_table_cap_new(
0, /* capIOPTIsMapped */
@ -224,7 +202,6 @@ Mode_decodeInvocation(
)
{
switch (cap_get_capType(cap)) {
case cap_pdpt_cap:
case cap_page_directory_cap:
case cap_page_table_cap:
case cap_frame_cap:

View file

@ -53,18 +53,6 @@ deriveCap_ret_t Arch_deriveCap(cte_t* slot, cap_t cap)
}
return ret;
case cap_pdpt_cap:
if (cap_pdpt_cap_get_capPDPTIsMapped(cap)) {
ret.cap = cap;
ret.status = EXCEPTION_NONE;
} else {
userError("Deriving a PDPT cap without an assigned ASID");
current_syscall_error.type = seL4_IllegalOperation;
ret.cap = cap_null_cap_new();
ret.status = EXCEPTION_SYSCALL_ERROR;
}
return ret;
case cap_asid_control_cap:
case cap_asid_pool_cap:
ret.cap = cap;
@ -332,13 +320,6 @@ bool_t CONST Arch_sameRegionAs(cap_t cap_a, cap_t cap_b)
}
break;
case cap_pdpt_cap:
if (cap_get_capType(cap_b) == cap_pdpt_cap) {
return cap_pdpt_cap_get_capPDPTBasePtr(cap_a) ==
cap_pdpt_cap_get_capPDPTBasePtr(cap_b);
}
break;
case cap_asid_control_cap:
if (cap_get_capType(cap_b) == cap_asid_control_cap) {
return true;

View file

@ -89,14 +89,6 @@ config MAX_VPIDS
should be sized as small as possible to save memory, but be at least
the number of VCPUs that will be run for optimum performance
config PAE_PAGING
bool "Use PAE Paging"
depends on ARCH_IA32
default n
help
PAE paging uses 4K/2M pages and has three levels of paging. If this
is not used the old 32-bit paging with 4K/4M pages will be used
config HUGE_PAGE
bool "Use 1GB Huge Page"
depends on ARCH_X86_64