summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
authorMissy Connell <missyc@us.ibm.com>2011-10-25 11:12:55 -0500
committerMelissa J. Connell <missyc@us.ibm.com>2011-10-27 15:56:31 -0500
commit9e86b070a4429e7db34a5438611a67098ab92dfb (patch)
tree52e04b08288a7496359c41eff98e8463e73ae5dc /src/kernel
parent71564141e3a6c7f023a9484549baf319f0e1807e (diff)
downloadtalos-hostboot-9e86b070a4429e7db34a5438611a67098ab92dfb.tar.gz
talos-hostboot-9e86b070a4429e7db34a5438611a67098ab92dfb.zip
Full permissions with no_access as default
MERGED changes.. only need Patrick and Mark to review extintsvctasks.H Change-Id: Iba5814e1b5913c6181a2be96df9682555fa2ab58 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/458 Tested-by: Jenkins Server Reviewed-by: Melissa J. Connell <missyc@us.ibm.com>
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/basesegment.C41
-rw-r--r--src/kernel/block.C427
-rw-r--r--src/kernel/blockmsghdlr.C9
-rw-r--r--src/kernel/devicesegment.C2
-rw-r--r--src/kernel/ptmgr.C177
-rw-r--r--src/kernel/stacksegment.C3
6 files changed, 399 insertions, 260 deletions
diff --git a/src/kernel/basesegment.C b/src/kernel/basesegment.C
index e55c3b735..7b33eed7a 100644
--- a/src/kernel/basesegment.C
+++ b/src/kernel/basesegment.C
@@ -80,14 +80,14 @@ void BaseSegment::_init()
// Set pages in kernel text section to be read-only / executable.
if (((uint64_t)&data_load_address) > i)
{
- iv_block->setPhysicalPage(i, i, VmmManager::RO_EXE_ACCESS);
+ // Set the Text section to Excutable (implies read)
+ iv_block->setPhysicalPage(i, i, EXECUTABLE);
}
// Set all other pages to initially be read/write. VFS will set
// permissions on pages outside kernel.
- // (@TODO: Future Sprint, for now keep NORMAL_ACCESS as RWX, not RW.)
else
{
- iv_block->setPhysicalPage(i, i, VmmManager::NORMAL_ACCESS);
+ iv_block->setPhysicalPage(i, i, WRITABLE);
}
}
}
@@ -164,39 +164,10 @@ int BaseSegment::mmSetPermission(void* i_va, uint64_t i_size, uint64_t i_access_
*/
int BaseSegment::_mmSetPermission(void* i_va, uint64_t i_size, uint64_t i_access_type)
{
- int l_rc = 0;
- Block *l_block = iv_block;
- uint64_t l_va = reinterpret_cast<uint64_t>(i_va);
-
-
- do
- {
- // If the va is not part of this block
- if (!(l_block->isContained(l_va)))
- {
- // Check to see if there is a next block
- if (l_block->iv_nextBlock)
- {
- // set local block to the next block
- l_block = l_block->iv_nextBlock;
- }
- else
- {
- // address passed in does not fall into a block
- return -EINVAL;
- }
- }
- // The virtual address falls within this block
- else
- {
- // Set the permission on the the current block.
- return(l_block->mmSetPermission(l_va, i_size, i_access_type));
-
- }
- } while (l_block);
-
- return l_rc;
+ Block *l_block = iv_block;
+ uint64_t l_va = reinterpret_cast<uint64_t>(i_va);
+ return (l_block->mmSetPermission(l_va, i_size, i_access_type));
}
void BaseSegment::castOutPages(uint64_t i_type)
diff --git a/src/kernel/block.C b/src/kernel/block.C
index bdec164de..40706ba48 100644
--- a/src/kernel/block.C
+++ b/src/kernel/block.C
@@ -36,6 +36,7 @@
#include <kernel/pagemgr.H>
#include <kernel/console.H>
#include <util/align.H>
+#include <kernel/basesegment.H>
Block::~Block()
{
@@ -86,6 +87,20 @@ bool Block::handlePageFault(task_t* i_task, uint64_t i_addr)
ShadowPTE* pte = getPTE(l_addr_palign);
+ // TODO... have this commented out at this point because
+ // checking this here causes the vmmbasetest.H testcases
+ // to fail... Need to determine how you want the
+ // NULL condition and the printk testcases handled in the
+ // testcase or change their default values.
+
+ // If the page table entry has default permission settings
+/* if (getPermission(pte) == NO_ACCESS)
+ {
+ printk("NO_ACCESS permission for addr 0x%.lX\n", i_addr);
+ return -EINVAL;
+ } */
+
+
if (!pte->isPresent())
{
if (this->iv_readMsgHdlr != NULL)
@@ -97,11 +112,9 @@ bool Block::handlePageFault(task_t* i_task, uint64_t i_addr)
l_page = PageManager::allocatePage();
//Add to ShadowPTE
pte->setPageAddr(reinterpret_cast<uint64_t>(l_page));
- //TODO - Update to correct permissions requested
- pte->setExecutable(false);
- pte->setWritable(true);
}
- //Send message to handler to read page
+
+
this->iv_readMsgHdlr->sendMessage(MSG_MM_RP_READ,
reinterpret_cast<void*>(l_addr_palign),l_page,i_task);
//Done(waiting for response)
@@ -114,6 +127,12 @@ bool Block::handlePageFault(task_t* i_task, uint64_t i_addr)
pte->setPageAddr(reinterpret_cast<uint64_t>(l_page));
pte->setPresent(true);
+
+ // TODO.. add this and test it..
+ /* if (BaseSegment::mmSetPermission(reinterpret_cast<void*>(l_page), 0, NO_ACCESS))
+ {
+ printk(" Got an error trying to set permissions in handle page fault\n");
+ } */
}
else
{
@@ -125,16 +144,16 @@ bool Block::handlePageFault(task_t* i_task, uint64_t i_addr)
PageTableManager::addEntry(
l_addr_palign,
pte->getPage(),
- (pte->isExecutable() ? VmmManager::RO_EXE_ACCESS :
- (pte->isWritable() ? VmmManager::NORMAL_ACCESS :
- VmmManager::READ_O_ACCESS)));
+ (pte->isExecutable() ? EXECUTABLE :
+ (pte->isWritable() ? WRITABLE :
+ READ_ONLY)));
return true;
}
void Block::setPhysicalPage(uint64_t i_vAddr, uint64_t i_pAddr,
- VmmManager::ACCESS_TYPES i_access)
+ uint64_t i_access)
{
// Check containment, call down chain if address isn't in this block.
if (!isContained(i_vAddr))
@@ -168,32 +187,17 @@ void Block::setPhysicalPage(uint64_t i_vAddr, uint64_t i_pAddr,
PageTableManager::delEntry(i_vAddr);
}
- switch(i_access)
- {
- case VmmManager::READ_O_ACCESS:
- pte->setReadable(true);
- pte->setExecutable(false);
- pte->setWritable(false);
- break;
-
- case VmmManager::NORMAL_ACCESS:
- pte->setReadable(true);
- pte->setExecutable(false);
- pte->setWritable(true);
- break;
-
- case VmmManager::RO_EXE_ACCESS:
- pte->setReadable(true);
- pte->setExecutable(true);
- pte->setWritable(false);
- break;
- default:
- kassert(false);
- break;
+ // make a call that sets the permssions on a
+ // shadow page table entry
+ if (setPermSPTE(pte, i_access))
+ {
+ kassert(false);
}
+
}
+
void Block::setIsPresent(void* i_vaddr)
{
uint64_t l_vaddr = reinterpret_cast<uint64_t>(i_vaddr);
@@ -208,10 +212,10 @@ void Block::addPTE(void* i_vaddr)
ShadowPTE* l_pte = getPTE(l_vaddr);
//Add page table entry
PageTableManager::addEntry((l_vaddr / PAGESIZE) * PAGESIZE,
- l_pte->getPage(),
- (l_pte->isExecutable() ? VmmManager::RO_EXE_ACCESS :
- (l_pte->isWritable() ? VmmManager::NORMAL_ACCESS :
- VmmManager::READ_O_ACCESS)));
+ l_pte->getPage(),
+ (l_pte->isExecutable() ? EXECUTABLE :
+ (l_pte->isWritable() ? WRITABLE :
+ READ_ONLY)));
}
uint64_t Block::findPhysicalAddress(uint64_t i_vaddr) const
@@ -235,28 +239,6 @@ uint64_t Block::findPhysicalAddress(uint64_t i_vaddr) const
return paddr;
}
-void Block::setPageAllocateFromZero(uint64_t i_vAddr)
-{
- // Check containment, call down chain if address isn't in this block.
- if (!isContained(i_vAddr))
- {
- if (iv_nextBlock)
- {
- iv_nextBlock->setPageAllocateFromZero(i_vAddr);
- }
- else
- {
- // No block owns this address. Code bug.
- printk("setPageAllocateFromZero> i_vaddr=0x%.lX\n", i_vAddr );
- kassert(iv_nextBlock);
- }
- return;
- }
-
- // Set page to allocate-from-zero.
- ShadowPTE* pte = getPTE(i_vAddr);
- pte->setAllocateFromZero(true);
-}
void Block::releaseAllPages()
{
@@ -272,6 +254,14 @@ void Block::releaseAllPages()
if (pte->isPresent() && (0 != pte->getPageAddr()))
{
PageManager::freePage(reinterpret_cast<void*>(pte->getPageAddr()));
+
+/* TODO.. add this into code and test.
+ if (BaseSegment::mmSetPermission(reinterpret_cast<void*>(pte->getPageAddr()),
+ 0, WRITABLE))
+ {
+ printk("Got an error trying to set permissions in release all pages\n");
+ }
+*/
pte->setPresent(false);
pte->setPageAddr(NULL);
}
@@ -316,6 +306,40 @@ void Block::updateRefCount( uint64_t i_vaddr,
}
}
+bool Block::evictPage(ShadowPTE* i_pte)
+{
+ ShadowPTE* pte = i_pte;
+ bool do_cast_out = false;
+
+ if(!pte->isWritable()) // ro, executable
+ {
+ do_cast_out = true;
+ }
+ else // is writable...
+ {
+ // if pte->isWriteTracked() flush then cast out
+ }
+
+ if(do_cast_out)
+ {
+ PageTableManager::delEntry(pte->getPageAddr());
+ PageManager::freePage(reinterpret_cast<void*>(pte->getPageAddr()));
+
+/* TODO.. Add this back in and test
+ // Need to set the permissions of the heap back to R/W
+ if (BaseSegment::mmSetPermission(reinterpret_cast<void*>(pte->getPageAddr()),
+ 0, WRITABLE))
+ {
+ printk(" EVICT Got an error trying to set permissions in evict page\n");
+ }
+*/
+ pte->setPresent(false);
+ pte->setPageAddr(NULL);
+ }
+
+ return do_cast_out;
+}
+
void Block::castOutPages(uint64_t i_type)
{
void* l_vaddr = NULL;
@@ -378,107 +402,196 @@ void Block::castOutPages(uint64_t i_type)
int Block::mmSetPermission(uint64_t i_va, uint64_t i_size,uint64_t i_access_type)
{
- int l_rc = 0;
-
- // Need to align the page address and the size on a page boundary. before I get the page.
- uint64_t l_aligned_va = ALIGN_PAGE_DOWN(i_va);
- uint64_t l_aligned_size = ALIGN_PAGE(i_size);
-//printk("aligned VA = 0x%.lX aligned size = %ld\n", l_aligned_va, l_aligned_size);
-
- // if size is zero..we are only updating 1 page.. so need to increment the size to 1 page
- if (i_size == 0)
- {
- l_aligned_size+=PAGESIZE;
- }
-
- // loop through all the pages asked for based on passed aligned
- // Virtual address and passed in aligned size.
- for(uint64_t cur_page_addr = l_aligned_va;
- cur_page_addr < (l_aligned_va + l_aligned_size);
- cur_page_addr += PAGESIZE)
- {
-//printk("aligned VA = 0x%.lX aligned size = %ld\n", l_aligned_va, l_aligned_size);
- ShadowPTE* spte = getPTE(cur_page_addr);
-
- // if the page present need to delete the hardware
- // page table entry before we set permissions.
- if (spte->isPresent())
- {
- // delete the hardware page table entry
- PageTableManager::delEntry(cur_page_addr);
- }
-
- // If read_only
- if ( i_access_type & READ_ONLY)
- {
- spte->setReadable(true);
- spte->setExecutable(false);
- spte->setWritable(false);
-
- // If the writable or executable access bits
- // are set.. invalid combination.. return error
- if ((i_access_type & WRITABLE) || (i_access_type & EXECUTABLE))
- {
+ int l_rc = 0;
+
+ // Need to align the page address and the size on a page boundary.
+ uint64_t l_aligned_va = ALIGN_PAGE_DOWN(i_va);
+ uint64_t l_aligned_size = ALIGN_PAGE(i_size);
+
+
+ if(!isContained(l_aligned_va))
+ {
+ return (iv_nextBlock ?
+ iv_nextBlock->mmSetPermission(i_va,i_size,i_access_type):-EINVAL);
+ }
+
+//printk("\n aligned VA = 0x%.lX aligned size = %ld access_type = 0x%.lX\n", l_aligned_va, l_aligned_size, i_access_type);
+
+ // if i_size is zero..we are only updating 1 page..inncrement the size to 1 page
+ if (i_size == 0)
+ {
+ l_aligned_size+=PAGESIZE;
+ }
+
+ // loop through all the pages asked for based on passed aligned
+ // Virtual address and passed in aligned size.
+ for(uint64_t cur_page_addr = l_aligned_va;
+ cur_page_addr < (l_aligned_va + l_aligned_size);
+ cur_page_addr += PAGESIZE)
+ {
+
+ ShadowPTE* spte = getPTE(cur_page_addr);
+
+ // if the page present need to delete the hardware
+ // page table entry before we set permissions.
+ if (spte->isPresent())
+ {
+ // delete the hardware page table entry
+ PageTableManager::delEntry(cur_page_addr);
+ }
+
+ if (setPermSPTE(spte, i_access_type))
+ {
+ printkd(" SET PERMISSIONS.. FAILED \n");
+ return -EINVAL;
+ }
+ }
+
+ return l_rc;
+}
+
+int Block::setPermSPTE( ShadowPTE* i_spte, uint64_t i_access_type)
+{
+
+ // If read_only
+ if ( i_access_type & READ_ONLY)
+ {
+ // If the writable, executable, write_tracked
+ // or allocate from zero access bits are set
+ // we have an invalid combination.. return error
+ if ((i_access_type & WRITABLE) ||
+ (i_access_type & EXECUTABLE) ||
+ (i_access_type & WRITE_TRACKED) ||
+ (i_access_type & ALLOCATE_FROM_ZERO))
+ {
return -EINVAL;
- }
- }
- // if writable
- else if ( i_access_type & WRITABLE)
- {
- spte->setReadable(true);
- spte->setWritable(true);
- spte->setExecutable(false);
-
- if (i_access_type & EXECUTABLE)
+ }
+
+ // Set the bits after we have verified
+ // the valid combinations so if we are setting
+ // permissions on a range only the first page would
+ // get set to READ_ONLY before we fail.
+ i_spte->setReadable(true);
+ i_spte->setExecutable(false);
+ i_spte->setWritable(false);
+ }
+ // if writable
+ else if ( i_access_type & WRITABLE)
+ {
+ if (i_access_type & EXECUTABLE)
+ {
+ return -EINVAL;
+ }
+
+ i_spte->setReadable(true);
+ i_spte->setWritable(true);
+ i_spte->setExecutable(false);
+
+ }
+ // if executable
+ else if ( i_access_type & EXECUTABLE)
+ {
+ i_spte->setReadable(true);
+ i_spte->setExecutable(true);
+ i_spte->setWritable(false);
+ }
+
+ // if write_tracked
+ if ( i_access_type & WRITE_TRACKED)
+ {
+ // TODO.. fail if no message handler when trying to
+ // set a page to write tracked.
+
+ // If the page is already READ_ONLY
+ // you cannot set to WRITE_TRACKED
+ if (getPermission(i_spte) == READ_ONLY)
+ {
+ return -EINVAL;
+ }
+ i_spte->setWriteTracked(true);
+ }
+ else
+ {
+ i_spte->setWriteTracked(false);
+ }
+
+ // if Allocate from zero
+ if ( i_access_type & ALLOCATE_FROM_ZERO)
+ {
+ // If the page is already READ_ONLY
+ // you cannot set to ALLOCATE_FROM_ZERO
+ if (getPermission(i_spte) == READ_ONLY)
+ {
+ return -EINVAL;
+ }
+
+ i_spte->setAllocateFromZero(true);
+ }
+ // not allocated from zero
+ else
+ {
+ i_spte->setAllocateFromZero(false);
+ }
+
+ // if no access
+ if ( i_access_type & NO_ACCESS)
+ {
+ i_spte->setReadable(false);
+ i_spte->setExecutable(false);
+ i_spte->setWritable(false);
+ i_spte->setAllocateFromZero(false);
+ i_spte->setWriteTracked(false);
+ }
+
+ return 0;
+}
+
+uint64_t Block::getPermission( ShadowPTE* i_spte)
+{
+
+ uint64_t l_accessType = 0;
+
+ if ((!i_spte->isReadable())&&
+ (!i_spte->isExecutable())&&
+ (!i_spte->isWritable())&&
+ (!i_spte->isAllocateFromZero())&&
+ (!i_spte->isWriteTracked()))
+ {
+ return NO_ACCESS;
+ }
+
+ if (i_spte->isReadable()&&
+ (!i_spte->isExecutable())&&
+ (!i_spte->isWritable()))
+ {
+ return READ_ONLY;
+ }
+
+ if (i_spte->isWritable())
+ {
+ l_accessType |= WRITABLE;
+ }
+
+ if (i_spte->isExecutable())
{
- // error condition.. not valid to be
- // writable and executable
- return -EINVAL;
+ l_accessType |= EXECUTABLE;
}
- }
- // if executable
- else if ( i_access_type & EXECUTABLE)
- {
- spte->setReadable(true);
- spte->setExecutable(true);
- spte->setWritable(false);
- }
-
- // if write_tracked
- if ( i_access_type & WRITE_TRACKED)
- {
- spte->setWriteTracked(true);
- }
- else
- {
- spte->setWriteTracked(false);
- }
-
- // if Allocate from zero
- if ( i_access_type & ALLOCATE_FROM_ZERO)
- {
- spte->setAllocateFromZero(true);
- }
- // not allocated from zero
- else
- {
- spte->setAllocateFromZero(false);
- }
-
- // if no access
- if ( i_access_type & NO_ACCESS)
- {
- spte->setReadable(false);
- spte->setExecutable(false);
- spte->setWritable(false);
- spte->setAllocateFromZero(false);
- spte->setWriteTracked(false);
- }
-
- }
- return l_rc;
+
+ if (i_spte->isWriteTracked())
+ {
+ l_accessType |= WRITE_TRACKED;
+ }
+
+ if (i_spte->isAllocateFromZero())
+ {
+ l_accessType |= ALLOCATE_FROM_ZERO;
+ }
+
+ return l_accessType;
}
+
+
int Block::removePages(VmmManager::PAGE_REMOVAL_OPS i_op, void* i_vaddr,
uint64_t i_size, task_t* i_task)
{
@@ -519,6 +632,9 @@ int Block::removePages(VmmManager::PAGE_REMOVAL_OPS i_op, void* i_vaddr,
{
this->iv_writeMsgHdlr->incMsgCount(i_task);
}
+
+// TODO.. Need to map the physical page here before sending the message because
+// the RP uses the physical page off the message queue.. (comment from patrick)
this->iv_writeMsgHdlr->addVirtAddr(
reinterpret_cast<void*>(l_vaddr),pageAddr);
this->iv_writeMsgHdlr->sendMessage(MSG_MM_RP_WRITE,
@@ -535,6 +651,13 @@ int Block::removePages(VmmManager::PAGE_REMOVAL_OPS i_op, void* i_vaddr,
//'Release' page entry
releasePTE(pte);
PageManager::freePage(reinterpret_cast<void*>(pageAddr));
+
+/* TODO.. Add this back in and test.
+printk(" \nInside flush.. setting all permissions back to writable on the heap\n");
+// Need to set the permissions of the heap back to R/W
+ BaseSegment::mmSetPermission(reinterpret_cast<void*>(pte->getPageAddr()),
+ 0, WRITABLE);
+*/
}
}
}
diff --git a/src/kernel/blockmsghdlr.C b/src/kernel/blockmsghdlr.C
index fc49ae89d..6a69f3b31 100644
--- a/src/kernel/blockmsghdlr.C
+++ b/src/kernel/blockmsghdlr.C
@@ -23,7 +23,7 @@
#include <kernel/blockmsghdlr.H>
#include <kernel/block.H>
#include <kernel/pagemgr.H>
-
+#include <kernel/basesegment.H>
MessageHandler::HandleResult BlockReadMsgHdlr::handleResponse(
msg_sys_types_t i_type, void* i_key, task_t* i_task, int i_rc)
{
@@ -37,6 +37,13 @@ MessageHandler::HandleResult BlockReadMsgHdlr::handleResponse(
{
//Set the present bit for the address associated with this block
iv_block->setIsPresent(i_key);
+
+ // TODO.. Add this call here and test
+ // update permission for the page that corresponds
+ // to the physical page addr.
+ // BaseSegment::mmSetPermission(i_key, 0, NO_ACCESS);
+
+
//Add the address into the page table associated with this block
iv_block->addPTE(i_key);
return SUCCESS;
diff --git a/src/kernel/devicesegment.C b/src/kernel/devicesegment.C
index bdf1eab0f..7fb4803dd 100644
--- a/src/kernel/devicesegment.C
+++ b/src/kernel/devicesegment.C
@@ -111,7 +111,7 @@ bool DeviceSegment::handlePageFault(task_t* i_task, uint64_t i_addr)
PageTableManager::addEntry((i_addr / PAGESIZE) * PAGESIZE,
(iv_mmioMap[idx].addr + device_offset) / PAGESIZE,
- VmmManager::CI_ACCESS);
+ SegmentManager::CI_ACCESS);
return true;
}
diff --git a/src/kernel/ptmgr.C b/src/kernel/ptmgr.C
index 9d0055e83..9807750ed 100644
--- a/src/kernel/ptmgr.C
+++ b/src/kernel/ptmgr.C
@@ -175,7 +175,7 @@ void PageTableManager::init()
*/
void PageTableManager::addEntry( uint64_t i_vAddr,
uint64_t i_page,
- VmmManager::ACCESS_TYPES i_accessType )
+ uint64_t i_accessType )
{
return Singleton<PageTableManager>::instance()._addEntry( i_vAddr, i_page, i_accessType );
}
@@ -308,7 +308,7 @@ PageTableManager::~PageTableManager()
*/
void PageTableManager::_addEntry( uint64_t i_vAddr,
uint64_t i_page,
- VmmManager::ACCESS_TYPES i_accessType )
+ uint64_t i_accessType )
{
Tprintk( ">> PageTableManager::_addEntry( i_vAddr=0x%.16lX, i_page=%ld, i_accessType=%d )\n", i_vAddr, i_page, i_accessType );
@@ -381,7 +381,7 @@ void PageTableManager::_addEntry( uint64_t i_vAddr,
Dprintk( "<< PageTableManager::_addEntry()\n" );
}
-/**
+/**.
* @brief Remove an entry from the hardware page table
*/
void PageTableManager::_delEntry( uint64_t i_vAddr )
@@ -475,24 +475,31 @@ uint64_t PageTableManager::getStatus( PageTableEntry* i_pte )
status |= PTE_VALID;
}
- VmmManager::ACCESS_TYPES access = getAccessType(i_pte);
- switch( access ) {
- case( VmmManager::CI_ACCESS ):
- status |= PTE_CACHE_INHIBITED;
- break;
- case( VmmManager::READ_O_ACCESS ):
- status |= PTE_READ_ONLY;
- break;
- case( VmmManager::NORMAL_ACCESS ):
- status |= PTE_EXECUTE; //@fixme?
- break;
- case( VmmManager::RO_EXE_ACCESS ):
- status |= PTE_READ_ONLY;
- status |= PTE_EXECUTE;
- break;
- default:
- break;
- };
+ uint64_t access = getAccessType(i_pte);
+
+ switch (access)
+ {
+ case SegmentManager::CI_ACCESS:
+ status |= PTE_CACHE_INHIBITED;
+ break;
+
+ case READ_ONLY:
+ status |= PTE_READ;
+ break;
+
+ case WRITABLE:
+ status |= PTE_WRITABLE;
+ status |= PTE_READ;
+ break;
+
+ case EXECUTABLE:
+ status |= PTE_EXECUTE;
+ status |= PTE_READ;
+ break;
+
+ default:
+ break;
+ }
if( i_pte->C == 1 ) {
status |= PTE_MODIFIED;
@@ -788,66 +795,98 @@ inline uint64_t PageTableManager::getSize( void )
* @brief Set bits in PTE for the given ACCESS_TYPES
*/
void PageTableManager::setAccessBits( PageTableEntry* o_pte,
- VmmManager::ACCESS_TYPES i_accessType )
+ uint64_t i_accessType )
{
o_pte->dword1 &= ~PTE_ACCESS_BITS;
- if( VmmManager::NO_USER_ACCESS == i_accessType ) {
- o_pte->WIMG = 0b0010; // Memory Coherency Required
- o_pte->N = 0b1; // No Execute
- } else if( VmmManager::READ_O_ACCESS == i_accessType ) {
- o_pte->WIMG = 0b0010; // Memory Coherency Required
- o_pte->pp1_2 = 0b01; // PP=001
- o_pte->N = 0b1; // No Execute
- } else if( VmmManager::NORMAL_ACCESS == i_accessType ) {
- o_pte->WIMG = 0b0010; // Memory Coherency Required
- o_pte->pp1_2 = 0b10; // PP=010
- o_pte->N = 0b0; // @TODO Change to 'No Execute' when VFS supports.
- } else if( VmmManager::CI_ACCESS == i_accessType ) {
- o_pte->WIMG = 0b0101; // Cache Inhibited, Guarded
- o_pte->pp1_2 = 0b10; // PP=010
- o_pte->N = 0b1; // No Execute
- } else if( VmmManager::RO_EXE_ACCESS == i_accessType ) {
- o_pte->WIMG = 0b0010; // Memory Coherency Required
- o_pte->pp1_2 = 0b01; // PP=001
- o_pte->N = 0b0; // Execute
- } else {
- //@fixme - add RO_EXE_ACCESS
- Eprintk( "** unrecognized access=%d\n", i_accessType );
+
+/* Description of the WIMG bits.
+ W1,3 0 - not Write Through Required
+ 1 - Write Through Required
+ I3 0 - not Caching Inhibited
+ 1 - Caching Inhibited
+ M2 0 - not Memory Coherence Required
+ 1 - Memory Coherence Required
+ G 0 - not Guarded
+ 1 - Guarded
+*/
+ if( SegmentManager::CI_ACCESS == i_accessType )
+ {
+ o_pte->WIMG = 0b0101; // Cache Inhibited, Guarded
+ o_pte->pp1_2 = 0b10; // PP=010
+ o_pte->N = 0b1; // No Execute
+ }
+ else
+ {
+ // Only setting that changes WIMG is CI_ACCESSS
+ // All others are set to 0b0010
+ o_pte->WIMG = 0b0010; // Memory Coherency Required
+
+ if (i_accessType & READ_ONLY)
+ {
+ o_pte->pp1_2 = 0b01; // PP=001
+ o_pte->N = 0b1; // No Execute
+ }
+ // if writable (implied readable)
+ else if (i_accessType & WRITABLE)
+ {
+ o_pte->pp1_2 = 0b10; // PP=010
+ o_pte->N = 0b1; // No Execute
+ }
+ // if executable (implied readable)
+ else if (i_accessType & EXECUTABLE)
+ {
+ o_pte->pp1_2 = 0b01; // PP=001
+ o_pte->N = 0b0; // Execute
+ }
+ else {
+ //@fixme - add RO_EXE_ACCESS
+ Eprintk( "** unrecognized access=%ld\n", i_accessType );
+ }
}
}
/**
* @brief Convert the bits from a PTE into a ACCESS_TYPES
*/
-VmmManager::ACCESS_TYPES PageTableManager::getAccessType( const PageTableEntry* i_pte )
+uint64_t PageTableManager::getAccessType( const PageTableEntry* i_pte )
{
- if( i_pte->pp0 == 0b0 )
+
+ if( i_pte->pp0 == 0b0 )
+ {
+ // If set to Cache Inhibited.
+ if( (i_pte->WIMG == 0b0101) && (i_pte->pp1_2 == 0b10) )
{
- if( (i_pte->WIMG == 0b0101) && (i_pte->pp1_2 == 0b10) )
- {
- return VmmManager::CI_ACCESS;
- }
- else if( (i_pte->WIMG == 0b0010) && (i_pte->pp1_2 == 0b00) )
- {
- return VmmManager::NO_USER_ACCESS;
- }
- else if( (i_pte->WIMG == 0b0010) && (i_pte->pp1_2 == 0b01) )
- {
- return VmmManager::READ_O_ACCESS;
- }
- else if( (i_pte->WIMG == 0b0010) && (i_pte->pp1_2 == 0b10) )
- {
- return VmmManager::NORMAL_ACCESS;
- }
- //@fixme - add RO_EXE_ACCESS
+ return SegmentManager::CI_ACCESS;
}
-
- Eprintk( "I don't recognize this PTE : WIMG=%ld, pp1_2=%ld\n", i_pte->WIMG, i_pte->pp1_2 );
- printPTE( "getAccessType", i_pte); /*no effect*/ // BEAM Fix.
- kassert(false);
- return VmmManager::NO_USER_ACCESS;
+ else if (i_pte->WIMG == 0b0010)
+ {
+ if (i_pte->pp1_2 == 0b00)
+ {
+ return NO_ACCESS;
+ }
+ // If read and no execute
+ else if ((i_pte->pp1_2 == 0b01) && (i_pte->N == 0b1))
+ {
+ return READ_ONLY;
+ }
+ // if writeable and no executable
+ else if ((i_pte->pp1_2 == 0b10) && (i_pte->N == 0b1))
+ {
+ return WRITABLE;
+ }
+ // if readably and executable..
+ else if ((i_pte->pp1_2 == 0b01) && (i_pte->N == 0b0))
+ {
+ return EXECUTABLE;
+ }
+ }
+ }
+ Eprintk( "I don't recognize this PTE : WIMG=%ld, pp1_2=%ld\n", i_pte->WIMG, i_pte->pp1_2 );
+ printPTE( "getAccessType", i_pte);
+ kassert(false);
+ return NO_ACCESS;
+
}
-
/**
* @brief Fill in default values for the PTE
*/
diff --git a/src/kernel/stacksegment.C b/src/kernel/stacksegment.C
index 0c04a2444..0ea3e24a8 100644
--- a/src/kernel/stacksegment.C
+++ b/src/kernel/stacksegment.C
@@ -134,8 +134,7 @@ void* StackSegment::_createStack(tid_t i_task)
// Set pages to be allocate-from-zero.
for(uint64_t i = l_addr_bottom; i <= l_addr_top; i += PAGE_SIZE)
{
- l_block->setPhysicalPage(i, 0, VmmManager::NORMAL_ACCESS);
- l_block->setPageAllocateFromZero(i);
+ l_block->setPhysicalPage(i, 0, WRITABLE | ALLOCATE_FROM_ZERO);
}
// Insert block to list.
OpenPOWER on IntegriCloud