diff options
author | Missy Connell <missyc@us.ibm.com> | 2011-10-25 11:12:55 -0500 |
---|---|---|
committer | Melissa J. Connell <missyc@us.ibm.com> | 2011-10-27 15:56:31 -0500 |
commit | 9e86b070a4429e7db34a5438611a67098ab92dfb (patch) | |
tree | 52e04b08288a7496359c41eff98e8463e73ae5dc | |
parent | 71564141e3a6c7f023a9484549baf319f0e1807e (diff) | |
download | talos-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>
-rw-r--r-- | src/include/kernel/block.H | 72 | ||||
-rw-r--r-- | src/include/kernel/ptmgr.H | 21 | ||||
-rw-r--r-- | src/include/kernel/segmentmgr.H | 6 | ||||
-rw-r--r-- | src/include/kernel/vmmmgr.H | 9 | ||||
-rw-r--r-- | src/kernel/basesegment.C | 41 | ||||
-rw-r--r-- | src/kernel/block.C | 427 | ||||
-rw-r--r-- | src/kernel/blockmsghdlr.C | 9 | ||||
-rw-r--r-- | src/kernel/devicesegment.C | 2 | ||||
-rw-r--r-- | src/kernel/ptmgr.C | 177 | ||||
-rw-r--r-- | src/kernel/stacksegment.C | 3 | ||||
-rw-r--r-- | src/usr/initservice/extinitsvc/extinitsvctasks.H | 48 | ||||
-rw-r--r-- | src/usr/initservice/test/initservicetest.H | 2 | ||||
-rw-r--r-- | src/usr/pnor/pnorrp.C | 8 | ||||
-rw-r--r-- | src/usr/testcore/kernel/ptmgrtest.H | 4 | ||||
-rw-r--r-- | src/usr/testcore/kernel/vmmpagetest.H | 137 |
15 files changed, 613 insertions, 353 deletions
diff --git a/src/include/kernel/block.H b/src/include/kernel/block.H index 60aeadaf0..b5ab709cc 100644 --- a/src/include/kernel/block.H +++ b/src/include/kernel/block.H @@ -140,23 +140,6 @@ class Block void updateRefCount( uint64_t i_vaddr, PageTableManager::UsageStats_t i_stats ); - /** - * @brief Cast out older phyiscal memory pages - * @param[in] i_type - Castout contraint @see VmmManager::castOutPages() - */ - void castOutPages(uint64_t i_type); - - /** - * @brief Removes a range of pages within a block of virtual memory - * @param[in] i_op - Page removal operation to perform - * @param[in] i_vaddr - Virtual address associated to page(s) - * @param[in] i_size - Size of memory to perform page removal on - * @param[in] i_task - Task requesting page removal. - * @return int - 0 for successful page removal, non-zero otherwise - */ - int removePages(VmmManager::PAGE_REMOVAL_OPS i_op, void* i_vaddr, - uint64_t i_size, task_t* i_task); - friend class Segment; friend class BaseSegment; friend class StackSegment; @@ -194,14 +177,7 @@ class Block * mode is still set. */ void setPhysicalPage(uint64_t i_vAddr, uint64_t i_pAddr, - VmmManager::ACCESS_TYPES i_access); - - /** - * @brief Set up a virtual address to be "allocate-from-zero". - * - * @param[in] i_vAddr - The virtual address of the page. - */ - void setPageAllocateFromZero(uint64_t i_vAddr); + uint64_t i_access); /** * @brief Adds up the total size of all blocks within the segment @@ -231,7 +207,7 @@ class Block * individual page. * @param i_access_type[in] - type of permission to set using * PAGE_PERMISSION enum values OR'd together - * @return int - 0 for successful block allocation, + * @return int - 0 for successful permission update, * non-zero otherwise */ int mmSetPermission(uint64_t i_va, uint64_t i_size, uint64_t i_access_type); @@ -260,6 +236,50 @@ class Block */ void releasePTE(ShadowPTE* i_pte); + /** + * @brief Cast out older phyiscal memory pages + * @param[in] i_type - Castout contraint @see VmmManager::castOutPages() + */ + void castOutPages(uint64_t i_type); + + /** + * @brief Evict a memory page + * @param[in] i_pte shadow page table entry + * @return true of page was evicted + */ + bool evictPage(ShadowPTE* i_pte); + + /** + * @brief Sets the page permissions for a given SPTE + * @param i_spte[in] - i_pte shadow page table entry + * @param i_access_type[in] - type of permission to set using + * PAGE_PERMISSION enum values OR'd together + * @return int - 0 for successful update + * non-zero otherwise + */ + int setPermSPTE( ShadowPTE* i_spte, uint64_t i_access_type); + + /** + * @brief Gets the page permissions for a given SPTE + * @param i_spte[in] - i_pte shadow page table entry + * @return uint64_t - type of permission for that SPTE using + * PAGE_PERMISSION enum values OR'd together + */ + uint64_t getPermission( ShadowPTE* i_spte); + + /** + * @brief Removes a range of pages within a block of virtual memory + * @param[in] i_op - Page removal operation to perform + * @param[in] i_vaddr - Virtual address associated to page(s) + * @param[in] i_size - Size of memory to perform page removal on + * @param[in] i_task - Task requesting page removal. + * @return int - 0 for successful page removal, non-zero otherwise + */ + int removePages(VmmManager::PAGE_REMOVAL_OPS i_op, void* i_vaddr, + uint64_t i_size, task_t* i_task); + + + private: /** Base address of the block */ const uint64_t iv_baseAddr; diff --git a/src/include/kernel/ptmgr.H b/src/include/kernel/ptmgr.H index 9ae092857..918e4211f 100644 --- a/src/include/kernel/ptmgr.H +++ b/src/include/kernel/ptmgr.H @@ -44,11 +44,12 @@ class PageTableManager PTE_UNKNOWN = 0x0000000000000000, /**< Entry wasn't found */ PTE_PRESENT = 0x0000000000000001, /**< Entry is present in table */ PTE_VALID = 0x0000000000000002, /**< Entry is valid */ - PTE_READ_ONLY = 0x0000000000000004, /**< Read-Only */ - PTE_EXECUTE = 0x0000000000000008, /**< Execute permission */ - PTE_CACHE_INHIBITED = 0x0000000000000010, /**< Cache-Inhibited Access */ - PTE_MODIFIED = 0x0000000000000020, /**< Page has been modified */ - PTE_ACCESSED = 0x0000000000000040, /**< Page has been accessed */ + PTE_READ = 0x0000000000000004, /**< Read permission */ + PTE_WRITABLE = 0x0000000000000008, /**< Write permission */ + PTE_EXECUTE = 0x0000000000000010, /**< Execute permission */ + PTE_CACHE_INHIBITED = 0x0000000000000020, /**< Cache-Inhibited Access */ + PTE_MODIFIED = 0x0000000000000040, /**< Page has been modified */ + PTE_ACCESSED = 0x0000000000000080, /**< Page has been accessed */ }; /** @@ -96,7 +97,7 @@ class PageTableManager */ static void addEntry( uint64_t i_vAddr, uint64_t i_page, - VmmManager::ACCESS_TYPES i_accessType ); + uint64_t i_accessType ); /** * @brief Remove an entry from the hardware page table @@ -315,7 +316,7 @@ class PageTableManager */ void _addEntry( uint64_t i_vAddr, uint64_t i_page, - VmmManager::ACCESS_TYPES i_accessType ); + uint64_t i_accessType ); /** * @brief Remove an entry from the hardware page table @@ -423,16 +424,16 @@ class PageTableManager * @param[in] i_accessType Access parameter to apply to PTE */ void setAccessBits( PageTableEntry* o_pte, - VmmManager::ACCESS_TYPES i_accessType ); + uint64_t i_accessType ); /** * @brief Convert the bits from a PTE into a ACCESS_TYPES * * @param[in] i_pte PTE to examine * - * @return ACCESS_TYPES Access parameters of given PTE + * @return uint64_t Access parameters of given PTE */ - VmmManager::ACCESS_TYPES getAccessType( const PageTableEntry* i_pte ); + uint64_t getAccessType( const PageTableEntry* i_pte ); /** * @brief Calculate the original Virtual Address from a PTE diff --git a/src/include/kernel/segmentmgr.H b/src/include/kernel/segmentmgr.H index 7232c7d4f..d2e4be2df 100644 --- a/src/include/kernel/segmentmgr.H +++ b/src/include/kernel/segmentmgr.H @@ -57,6 +57,12 @@ class SegmentManager MAX_SEGMENTS = 4 }; + enum + { + CI_ACCESS = 0xFFFFFFFF + // Set to all F's to identify this type + }; + /** * Constructor. Initializes instance variables. */ diff --git a/src/include/kernel/vmmmgr.H b/src/include/kernel/vmmmgr.H index 98b202db1..6e41ddb34 100644 --- a/src/include/kernel/vmmmgr.H +++ b/src/include/kernel/vmmmgr.H @@ -46,15 +46,6 @@ class VmmManager HTABORG = (FULL_MEM_SIZE - PTSIZE), }; - enum ACCESS_TYPES - { - NO_USER_ACCESS, - READ_O_ACCESS, - NORMAL_ACCESS, - CI_ACCESS, - RO_EXE_ACCESS, - }; - enum castout_t { NORMAL, 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. diff --git a/src/usr/initservice/extinitsvc/extinitsvctasks.H b/src/usr/initservice/extinitsvc/extinitsvctasks.H index 761295319..9ac783eb9 100644 --- a/src/usr/initservice/extinitsvc/extinitsvctasks.H +++ b/src/usr/initservice/extinitsvc/extinitsvctasks.H @@ -106,30 +106,35 @@ const TaskInfo g_exttaskinfolist[] = { START_PLAT_ERRL_ID, // module id } }, - + +// TODO: Added this in order to successfull init.. Need to remove this and put +// the module load and unload from a the istep dispatcher /** - * @brief targeting task, + * @brief HWAS, */ + + { - "libtargeting.so" , // taskname + "libhwas.so" , // taskname NULL, // no pointer to fn { - START_TASK, // task type + INIT_TASK, // task type EXT_IMAGE, // Extended Module - START_TARGETING_ERRL_ID, // module id + EXECUTE_ISTEPS_ERRL_ID, // module id } }, +// end TODO /** - * @brief IStep Dispatcher task, runs ISteps + * @brief FSI Device Driver */ { - "libistepdisp.so" , // taskname + "libfsi.so" , // taskname NULL, // no pointer to fn { - START_TASK, // task type + INIT_TASK, // task type EXT_IMAGE, // Extended Module - EXECUTE_ISTEPS_ERRL_ID, // module id + START_FSIDD_ERRL_ID, // module id } }, @@ -137,28 +142,41 @@ const TaskInfo g_exttaskinfolist[] = { * @brief FSI Device Driver */ { - "libfsi.so" , // taskname + "libfsiscom.so" , // taskname NULL, // no pointer to fn { INIT_TASK, // task type EXT_IMAGE, // Extended Module - START_FSIDD_ERRL_ID, // module id + START_FSISCOM_ERRL_ID, // module id } }, /** - * @brief FSI Device Driver + * @brief targeting task, */ { - "libfsiscom.so" , // taskname + "libtargeting.so" , // taskname NULL, // no pointer to fn { - INIT_TASK, // task type + START_TASK, // task type EXT_IMAGE, // Extended Module - START_FSISCOM_ERRL_ID, // module id + START_TARGETING_ERRL_ID, // module id } }, + /** + * @brief IStep Dispatcher task, runs ISteps + */ + { + "libistepdisp.so" , // taskname + NULL, // no pointer to fn + { + START_TASK, // task type + EXT_IMAGE, // Extended Module + EXECUTE_ISTEPS_ERRL_ID, // module id + } + }, + // NOTE: libistepdisp.so needs to always be last in this list!! // --------------------------------------------------------------- // ----- END OF LIST!!! --------------------------------------- diff --git a/src/usr/initservice/test/initservicetest.H b/src/usr/initservice/test/initservicetest.H index 6a32d73fd..1a8951ff3 100644 --- a/src/usr/initservice/test/initservicetest.H +++ b/src/usr/initservice/test/initservicetest.H @@ -63,7 +63,7 @@ const INITSERVICE::TaskInfo TASK_TEST2 = { NULL, // ptr to fn { INITSERVICE::START_TASK, // startflag=true, try to start - INITSERVICE::BASE_IMAGE, // Base Module + INITSERVICE::EXT_IMAGE, // Ext Inmage Module INITSERVICE::INIT_SVC_TEST2_ERRL_ID, // module id for errorlog }, }; diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C index 5a479f03e..76bcb89b1 100644 --- a/src/usr/pnor/pnorrp.C +++ b/src/usr/pnor/pnorrp.C @@ -193,6 +193,14 @@ void PnorRP::initDaemon() break; } + + // Need to set permissions to R/W + rc = mm_set_permission((void*) BASE_VADDR, + TOTAL_SIZE , + WRITABLE); + + + // start task to wait on the queue task_create( wait_for_message, NULL ); diff --git a/src/usr/testcore/kernel/ptmgrtest.H b/src/usr/testcore/kernel/ptmgrtest.H index 1d87b312e..e97457513 100644 --- a/src/usr/testcore/kernel/ptmgrtest.H +++ b/src/usr/testcore/kernel/ptmgrtest.H @@ -144,7 +144,7 @@ class ptmgrtest : public CxxTest::TestSuite for( uint64_t x = 0; x < (sizeof(TEST_DATA)/sizeof(TEST_DATA[0])); x++ ) { // 2) Add some PTEs - ptmgr->_addEntry( TEST_DATA[x].va, TEST_DATA[x].page, VmmManager::NORMAL_ACCESS ); + ptmgr->_addEntry( TEST_DATA[x].va, TEST_DATA[x].page, WRITABLE ); // 3) Verify the PTE we just added is in the Page Table status = ptmgr->_getStatus( TEST_DATA[x].va, pn ); @@ -406,7 +406,7 @@ class ptmgrtest : public CxxTest::TestSuite for( uint64_t x = 0; x < (sizeof(TEST_DATA)/sizeof(TEST_DATA[0])); x++ ) { // 2) Add some PTEs - ptmgr->_addEntry( TEST_DATA[x].va, TEST_DATA[x].page, VmmManager::NORMAL_ACCESS ); + ptmgr->_addEntry( TEST_DATA[x].va, TEST_DATA[x].page, WRITABLE ); } } diff --git a/src/usr/testcore/kernel/vmmpagetest.H b/src/usr/testcore/kernel/vmmpagetest.H index 39090b542..3559fd3cb 100644 --- a/src/usr/testcore/kernel/vmmpagetest.H +++ b/src/usr/testcore/kernel/vmmpagetest.H @@ -39,6 +39,7 @@ class vmmpagetest: public CxxTest::TestSuite public: static volatile int rc; + static volatile int iv_rc; //Testing page removal variables static msg_q_t iv_mq; static uint64_t iv_va; @@ -63,8 +64,15 @@ class vmmpagetest: public CxxTest::TestSuite void testReadPageRelease() { + rc = mm_set_permission(reinterpret_cast<void*>(iv_va+2*PAGESIZE),0, + WRITABLE); + //Dependent on block being initialized to READ_ONLY (*(volatile uint64_t *)(iv_va+2*PAGESIZE)) = 0x11111111; sync(); + + rc = mm_set_permission(reinterpret_cast<void*>(iv_va+2*PAGESIZE),0, + READ_ONLY); + rc = mm_remove_pages(RELEASE, reinterpret_cast<void*>(iv_va),iv_size); if (rc != 0) @@ -75,17 +83,19 @@ class vmmpagetest: public CxxTest::TestSuite void testWriteTrackPageFlush() { - (*(volatile uint64_t *)iv_va) = 0x12345678; sync(); - (*(volatile uint64_t *)(iv_va+PAGESIZE)) = 0x87654321; sync(); - (*(volatile uint64_t *)(iv_va+2*PAGESIZE)) = 0x22222222; sync(); - uint64_t updPerm = (uint64_t)(WRITE_TRACKED); - rc = mm_set_permission(reinterpret_cast<void*>(iv_va),0,updPerm); + rc = mm_set_permission(reinterpret_cast<void*>(iv_va),3*PAGESIZE,WRITABLE|WRITE_TRACKED); if (rc != 0) { TS_FAIL( "Failed to set WRITE_TRACKED permissions on first page.\n"); } - rc = mm_set_permission(reinterpret_cast<void*>((iv_va+PAGESIZE)),0, + + (*(volatile uint64_t *)iv_va) = 0x12345678; sync(); + (*(volatile uint64_t *)(iv_va+PAGESIZE)) = 0x87654321; sync(); + (*(volatile uint64_t *)(iv_va+2*PAGESIZE)) = 0x22222222; sync(); + uint64_t updPerm = (uint64_t)(READ_ONLY); + + rc = mm_set_permission(reinterpret_cast<void*>((iv_va+2*PAGESIZE)),0, updPerm); if (rc != 0) { @@ -102,8 +112,24 @@ class vmmpagetest: public CxxTest::TestSuite void testWriteTrackPageRelease() { + rc = mm_set_permission(reinterpret_cast<void*>(iv_va+2*PAGESIZE),0 ,WRITABLE); + if (rc != 0) + { + TS_FAIL( + "Failed to set WRITE_TRACKED permissions on first page.\n"); + } + (*(volatile uint64_t *)(iv_va+2*PAGESIZE)) = 0x33333333; sync(); (*(volatile uint64_t *)iv_va) = 0x12121212; sync(); + + uint64_t updPerm = (uint64_t)(READ_ONLY); + rc = mm_set_permission(reinterpret_cast<void*>(iv_va+2*PAGESIZE),0,updPerm); + if (rc != 0) + { + TS_FAIL( + "Failed to set WRITE_TRACKED permissions on first page.\n"); + } + rc = mm_remove_pages(RELEASE, reinterpret_cast<void*>(iv_va),iv_size); if (rc != 0) @@ -114,48 +140,80 @@ class vmmpagetest: public CxxTest::TestSuite void testSetPerm() { - int rc = 1; - uint64_t va = 0xC800000000; //800GB - uint64_t size = 0x0; - uint64_t access = (uint64_t)(WRITABLE | ALLOCATE_FROM_ZERO); //Access value - printkd("Update Page Permissions. Writable/Allocate from zero to addr 800Gb and size = 0 \n"); - rc = mm_set_permission(reinterpret_cast<void*>(va), size, access); + + rc = mm_set_permission(reinterpret_cast<void*>(iv_va+4*PAGESIZE), 3*PAGESIZE, READ_ONLY); if (rc != 0) { TS_FAIL(" 1 Failed to Update permissions.\n"); } - rc = 1; - size = PAGESIZE * 3; - access = (uint64_t)(WRITE_TRACKED); //Access value - printkd("Update Page Permissions. write_tracked to addr 800Gb and size = 3 pages\n"); - rc = mm_set_permission(reinterpret_cast<void*>(va), size, access); + // try to write to a read_only page + iv_rc = 0; sync(); + printk("\nTest case1: Expect to see uncaught exception! "); + task_create(writeAddrWithNoPerm, NULL); + while (iv_rc == 0) task_yield(); + task_yield(); + if (iv_rc == -1) + { + TS_FAIL("ERROR! Write to READ_ONLY address not caught."); + } + + rc = mm_set_permission(reinterpret_cast<void*>(iv_va+4*PAGESIZE), 3*PAGESIZE, EXECUTABLE); if (rc != 0) { TS_FAIL("2 Failed to Update permissions.\n"); } - rc = 1; - va = 0xC800000000 + (PAGESIZE * 10); - size = PAGESIZE * 2; - access = (uint64_t)(EXECUTABLE); //Access value - printkd("Update Page Permissions. executable to addr C800A000 and size = 2 pages\n"); - rc = mm_set_permission(reinterpret_cast<void*>(va), size, access); + + // try to write to an executable page + iv_rc = 0; sync(); + printk("\nTest case2: Expect to see uncaught exception! "); + task_create(writeAddrWithNoPerm2, NULL); + while (iv_rc == 0) task_yield(); + task_yield(); + if (iv_rc == -1) + { + TS_FAIL("ERROR! Write to EXECUTABLE address not caught."); + } + + rc = mm_set_permission(reinterpret_cast<void*>(iv_va+4*PAGESIZE), 3*PAGESIZE, NO_ACCESS); if (rc != 0) { TS_FAIL("3 Failed to Update permissions.\n"); } - rc = 0; - va = 0xC800000000; //800GB - size = 0x0; - access = (uint64_t)(WRITABLE | EXECUTABLE); //Access value - printkd("Update Page Permissions. Writable/executable to addr 800Gb and size = 0 \n"); - rc = mm_set_permission(reinterpret_cast<void*>(va), size, access); + + // try to write to a no access page + iv_rc = 0; sync(); + printk("\nTest case3: Expect to see uncaught exception! "); + task_create(writeAddrWithNoPerm, NULL); + while (iv_rc == 0) task_yield(); + task_yield(); + if (iv_rc == -1) + { + TS_FAIL("ERROR! write to a NO_ACCESS addr not caught.\n"); + } + + // test that you cannot set WRITABLE and EXECUTABLE permissions + rc = mm_set_permission(reinterpret_cast<void*>(iv_va+4*PAGESIZE), 3*PAGESIZE, WRITABLE|EXECUTABLE); if (rc == 0) { printk("Error .. invalid combination that did not get detected\n"); + TS_FAIL(" ERROR..Failed to detect a bad parm condition.\n"); + } + + rc = mm_set_permission(reinterpret_cast<void*>(iv_va+4*PAGESIZE), 3*PAGESIZE, WRITABLE); + if (rc != 0) + { TS_FAIL(" 4 Failed to detect a bad parm condition.\n"); } - } + + + (*(volatile uint64_t *)(iv_va+4*PAGESIZE)) = 0x34343434; + + + printk("\n%lx\n", (*(volatile uint64_t *)(iv_va+4*PAGESIZE))); + //printkd(" Successfully read from a WRITABLE page\n"); + + } private: @@ -177,8 +235,27 @@ class vmmpagetest: public CxxTest::TestSuite } } + + static void writeAddrWithNoPerm(void* unused) + { + iv_rc = 1; sync(); + (*(volatile uint64_t *)(iv_va+4*PAGESIZE)) = 0x11111111; sync(); + iv_rc = -1; sync(); + task_end(); + } + + static void writeAddrWithNoPerm2(void* unused) + { + iv_rc = 1; sync(); + (*(volatile uint64_t *)(iv_va+4*PAGESIZE+2*PAGESIZE)) = 0x22222222; sync(); + iv_rc = -1; sync(); + task_end(); + } + + }; volatile int vmmpagetest::rc = 0; +volatile int vmmpagetest::iv_rc = 0; msg_q_t vmmpagetest::iv_mq = msg_q_create(); uint64_t vmmpagetest::iv_va = VMM_VADDR_RMVPAGE_TEST; uint64_t vmmpagetest::iv_size = VMM_SIZE_RMVPAGE_TEST; |