[Memory] BaseHeap::TranslateRelative including host address offset

This commit is contained in:
Triang3l 2019-08-15 00:31:21 +03:00
parent 0451153760
commit e862169156
2 changed files with 24 additions and 20 deletions

View File

@ -401,7 +401,7 @@ uint32_t Memory::SearchAligned(uint32_t start, uint32_t end,
matched++; matched++;
} }
if (matched == value_count) { if (matched == value_count) {
return uint32_t(reinterpret_cast<const uint8_t*>(p) - virtual_membase_); return HostToGuestVirtual(p);
} }
} }
p++; p++;
@ -633,8 +633,8 @@ void BaseHeap::Dispose() {
++page_number) { ++page_number) {
auto& page_entry = page_table_[page_number]; auto& page_entry = page_table_[page_number];
if (page_entry.state) { if (page_entry.state) {
xe::memory::DeallocFixed(membase_ + heap_base_ + page_number * page_size_, xe::memory::DeallocFixed(TranslateRelative(page_number * page_size_), 0,
0, xe::memory::DeallocationType::kRelease); xe::memory::DeallocationType::kRelease);
page_number += page_entry.region_page_count; page_number += page_entry.region_page_count;
} }
} }
@ -732,7 +732,7 @@ bool BaseHeap::Save(ByteStream* stream) {
// TODO(DrChat): write compressed with snappy. // TODO(DrChat): write compressed with snappy.
if (page.state & kMemoryAllocationCommit) { if (page.state & kMemoryAllocationCommit) {
void* addr = membase_ + heap_base_ + i * page_size_; void* addr = TranslateRelative(i * page_size_);
memory::PageAccess old_access; memory::PageAccess old_access;
memory::Protect(addr, page_size_, memory::PageAccess::kReadWrite, memory::Protect(addr, page_size_, memory::PageAccess::kReadWrite,
@ -769,7 +769,7 @@ bool BaseHeap::Restore(ByteStream* stream) {
// Commit the memory if it isn't already. We do not need to reserve any // Commit the memory if it isn't already. We do not need to reserve any
// memory, as the mapping has already taken care of that. // memory, as the mapping has already taken care of that.
if (page.state & kMemoryAllocationCommit) { if (page.state & kMemoryAllocationCommit) {
xe::memory::AllocFixed(membase_ + heap_base_ + i * page_size_, page_size_, xe::memory::AllocFixed(TranslateRelative(i * page_size_), page_size_,
memory::AllocationType::kCommit, memory::AllocationType::kCommit,
memory::PageAccess::kReadWrite); memory::PageAccess::kReadWrite);
} }
@ -778,7 +778,7 @@ bool BaseHeap::Restore(ByteStream* stream) {
// protection back to its previous state. // protection back to its previous state.
// TODO(DrChat): read compressed with snappy. // TODO(DrChat): read compressed with snappy.
if (page.state & kMemoryAllocationCommit) { if (page.state & kMemoryAllocationCommit) {
void* addr = membase_ + heap_base_ + i * page_size_; void* addr = TranslateRelative(i * page_size_);
xe::memory::Protect(addr, page_size_, memory::PageAccess::kReadWrite, xe::memory::Protect(addr, page_size_, memory::PageAccess::kReadWrite,
nullptr); nullptr);
@ -858,7 +858,7 @@ bool BaseHeap::AllocFixed(uint32_t base_address, uint32_t size,
? xe::memory::AllocationType::kCommit ? xe::memory::AllocationType::kCommit
: xe::memory::AllocationType::kReserve; : xe::memory::AllocationType::kReserve;
void* result = xe::memory::AllocFixed( void* result = xe::memory::AllocFixed(
membase_ + heap_base_ + start_page_number * page_size_, TranslateRelative(start_page_number * page_size_),
page_count * page_size_, alloc_type, ToPageAccess(protect)); page_count * page_size_, alloc_type, ToPageAccess(protect));
if (!result) { if (!result) {
XELOGE("BaseHeap::AllocFixed failed to alloc range from host"); XELOGE("BaseHeap::AllocFixed failed to alloc range from host");
@ -1006,7 +1006,7 @@ bool BaseHeap::AllocRange(uint32_t low_address, uint32_t high_address,
? xe::memory::AllocationType::kCommit ? xe::memory::AllocationType::kCommit
: xe::memory::AllocationType::kReserve; : xe::memory::AllocationType::kReserve;
void* result = xe::memory::AllocFixed( void* result = xe::memory::AllocFixed(
membase_ + heap_base_ + start_page_number * page_size_, TranslateRelative(start_page_number * page_size_),
page_count * page_size_, alloc_type, ToPageAccess(protect)); page_count * page_size_, alloc_type, ToPageAccess(protect));
if (!result) { if (!result) {
XELOGE("BaseHeap::Alloc failed to alloc range from host"); XELOGE("BaseHeap::Alloc failed to alloc range from host");
@ -1047,7 +1047,7 @@ bool BaseHeap::Decommit(uint32_t address, uint32_t size) {
// TODO(benvanik): find a way to actually decommit memory; // TODO(benvanik): find a way to actually decommit memory;
// mapped memory cannot be decommitted. // mapped memory cannot be decommitted.
/*BOOL result = /*BOOL result =
VirtualFree(membase_ + heap_base_ + start_page_number * page_size_, VirtualFree(TranslateRelative(start_page_number * page_size_),
page_count * page_size_, MEM_DECOMMIT); page_count * page_size_, MEM_DECOMMIT);
if (!result) { if (!result) {
PLOGW("BaseHeap::Decommit failed due to host VirtualFree failure"); PLOGW("BaseHeap::Decommit failed due to host VirtualFree failure");
@ -1087,7 +1087,7 @@ bool BaseHeap::Release(uint32_t base_address, uint32_t* out_region_size) {
// Release from host not needed as mapping reserves the range for us. // Release from host not needed as mapping reserves the range for us.
// TODO(benvanik): protect with NOACCESS? // TODO(benvanik): protect with NOACCESS?
/*BOOL result = VirtualFree( /*BOOL result = VirtualFree(
membase_ + heap_base_ + base_page_number * page_size_, 0, MEM_RELEASE); TranslateRelative(base_page_number * page_size_), 0, MEM_RELEASE);
if (!result) { if (!result) {
PLOGE("BaseHeap::Release failed due to host VirtualFree failure"); PLOGE("BaseHeap::Release failed due to host VirtualFree failure");
return false; return false;
@ -1102,10 +1102,9 @@ bool BaseHeap::Release(uint32_t base_address, uint32_t* out_region_size) {
// it. It's possible this is some virtual/physical stuff where the GPU // it. It's possible this is some virtual/physical stuff where the GPU
// still can access it. // still can access it.
if (cvars::protect_on_release) { if (cvars::protect_on_release) {
if (!xe::memory::Protect( if (!xe::memory::Protect(TranslateRelative(base_page_number * page_size_),
membase_ + heap_base_ + base_page_number * page_size_, base_page_entry.region_page_count * page_size_,
base_page_entry.region_page_count * page_size_, xe::memory::PageAccess::kNoAccess, nullptr)) {
xe::memory::PageAccess::kNoAccess, nullptr)) {
XELOGW("BaseHeap::Release failed due to host VirtualProtect failure"); XELOGW("BaseHeap::Release failed due to host VirtualProtect failure");
} }
} }
@ -1157,10 +1156,9 @@ bool BaseHeap::Protect(uint32_t address, uint32_t size, uint32_t protect,
(((page_count * page_size_) % xe::memory::page_size() == 0) && (((page_count * page_size_) % xe::memory::page_size() == 0) &&
((start_page_number * page_size_) % xe::memory::page_size() == 0))) { ((start_page_number * page_size_) % xe::memory::page_size() == 0))) {
memory::PageAccess old_protect_access; memory::PageAccess old_protect_access;
if (!xe::memory::Protect( if (!xe::memory::Protect(TranslateRelative(start_page_number * page_size_),
membase_ + heap_base_ + start_page_number * page_size_, page_count * page_size_, ToPageAccess(protect),
page_count * page_size_, ToPageAccess(protect), old_protect ? &old_protect_access : nullptr)) {
old_protect ? &old_protect_access : nullptr)) {
XELOGE("BaseHeap::Protect failed due to host VirtualProtect failure"); XELOGE("BaseHeap::Protect failed due to host VirtualProtect failure");
return false; return false;
} }
@ -1524,7 +1522,7 @@ void PhysicalHeap::WatchPhysicalWrite(uint32_t physical_address,
// Protect the pages and mark them as watched. Don't mark non-writable pages // Protect the pages and mark them as watched. Don't mark non-writable pages
// as watched, so true access violations can still occur there. // as watched, so true access violations can still occur there.
uint8_t* protect_base = membase_ + heap_base_; uint8_t* protect_base = TranslateRelative(0);
uint32_t protect_system_page_first = UINT32_MAX; uint32_t protect_system_page_first = UINT32_MAX;
for (uint32_t i = system_page_first; i <= system_page_last; ++i) { for (uint32_t i = system_page_first; i <= system_page_last; ++i) {
uint64_t page_bit = uint64_t(1) << (i & 63); uint64_t page_bit = uint64_t(1) << (i & 63);
@ -1682,7 +1680,7 @@ bool PhysicalHeap::TriggerWatches(uint32_t virtual_address, uint32_t length,
// Unprotect ranges that need unprotection. // Unprotect ranges that need unprotection.
if (unprotect) { if (unprotect) {
uint8_t* protect_base = membase_ + heap_base_; uint8_t* protect_base = TranslateRelative(0);
uint32_t unprotect_system_page_first = UINT32_MAX; uint32_t unprotect_system_page_first = UINT32_MAX;
for (uint32_t i = system_page_first; i <= system_page_last; ++i) { for (uint32_t i = system_page_first; i <= system_page_last; ++i) {
// Check if need to allow writing to this page. // Check if need to allow writing to this page.

View File

@ -109,6 +109,12 @@ class BaseHeap {
// (not including membase). // (not including membase).
uint32_t host_address_offset() const { return host_address_offset_; } uint32_t host_address_offset() const { return host_address_offset_; }
template <typename T = uint8_t*>
inline T TranslateRelative(size_t relative_address) const {
return reinterpret_cast<T>(membase_ + heap_base_ + host_address_offset_ +
relative_address);
}
// Disposes and decommits all memory and clears the page table. // Disposes and decommits all memory and clears the page table.
virtual void Dispose(); virtual void Dispose();