diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2011-08-22 16:20:11 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2011-08-31 14:24:59 -0500 |
commit | 0ebac914541254c4b9ee2a271f26cd67fc2b94a0 (patch) | |
tree | 872be77d5870ea788513d8cb044f837904ddf8cc /src/kernel/block.C | |
parent | f7b7b56dea28dd69a44a877f7b7073c4496ced9e (diff) | |
download | talos-hostboot-0ebac914541254c4b9ee2a271f26cd67fc2b94a0.tar.gz talos-hostboot-0ebac914541254c4b9ee2a271f26cd67fc2b94a0.zip |
Dynamic stack support.
- Create stack segment.
- Allocate stack blocks on stack create.
Change-Id: Ida90055afb68f208c479b5fdc19d3d931d026105
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/271
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/kernel/block.C')
-rw-r--r-- | src/kernel/block.C | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/src/kernel/block.C b/src/kernel/block.C index 68db26a95..1402bd60a 100644 --- a/src/kernel/block.C +++ b/src/kernel/block.C @@ -98,7 +98,7 @@ bool Block::handlePageFault(task_t* i_task, uint64_t i_addr) //Done(waiting for response) return true; } - else if (pte->allocate_from_zero) + else if (pte->isAllocateFromZero()) { void* l_page = PageManager::allocatePage(); memset(l_page, '\0', PAGESIZE); @@ -144,8 +144,21 @@ void Block::setPhysicalPage(uint64_t i_vAddr, uint64_t i_pAddr, // Create virtual to physical mapping. ShadowPTE* pte = getPTE(i_vAddr); - pte->setPageAddr(i_pAddr); - pte->setPresent(true); + if (i_pAddr != 0) + { + pte->setPageAddr(i_pAddr); + pte->setPresent(true); + + // Modified an SPTE, clear the HPTE. + PageTableManager::delEntry(i_vAddr); + } + // If the page is already present, we might be changing permissions, so + // clear the HPTE. + else if (pte->isPresent()) + { + PageTableManager::delEntry(i_vAddr); + } + switch(i_access) { case VmmManager::READ_O_ACCESS: @@ -209,3 +222,45 @@ 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. + kassert(iv_nextBlock); + } + return; + } + + // Set page to allocate-from-zero. + ShadowPTE* pte = getPTE(i_vAddr); + pte->setAllocateFromZero(true); +} + +void Block::releaseAllPages() +{ + // Release all pages from page table. + PageTableManager::delRangeVA(iv_baseAddr, iv_baseAddr + iv_size); + + // Free all pages back to page manager. + for(uint64_t page = iv_baseAddr; + page < (iv_baseAddr + iv_size); + page += PAGESIZE) + { + ShadowPTE* pte = getPTE(page); + if (pte->isPresent() && (0 != pte->getPageAddr())) + { + PageManager::freePage(reinterpret_cast<void*>(pte->getPageAddr())); + pte->setPresent(false); + pte->setPageAddr(NULL); + } + } +} |