summaryrefslogtreecommitdiffstats
path: root/src/kernel/block.C
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2011-08-22 16:20:11 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2011-08-31 14:24:59 -0500
commit0ebac914541254c4b9ee2a271f26cd67fc2b94a0 (patch)
tree872be77d5870ea788513d8cb044f837904ddf8cc /src/kernel/block.C
parentf7b7b56dea28dd69a44a877f7b7073c4496ced9e (diff)
downloadtalos-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.C61
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);
+ }
+ }
+}
OpenPOWER on IntegriCloud