Get AddressSpace to expectMemory from page table entry bits

Change-Id: I1aacdf98f436261b523765e0ca591e8d8333274e
This commit is contained in:
Hoppe, Mateusz
2018-09-20 19:33:21 -07:00
committed by sys_ocldev
parent e8b6f11cad
commit a470aa2072
7 changed files with 87 additions and 17 deletions

View File

@ -7,10 +7,12 @@
#pragma once
#include <stdint.h>
#include <cstdint>
#include <limits>
namespace PageTableEntry {
const uint32_t presentBit = 0;
const uint32_t writableBit = 1;
const uint32_t userSupervisorBit = 2;
const uint64_t nonValidBits = std::numeric_limits<uint64_t>::max();
} // namespace PageTableEntry

View File

@ -103,6 +103,8 @@ class AUBCommandStreamReceiverHw : public CommandStreamReceiverHw<GfxFamily> {
return CommandStreamReceiverType::CSR_AUB;
}
int getAddressSpaceFromPTEBits(uint64_t entryBits) const;
protected:
int getAddressSpace(int hint);

View File

@ -703,6 +703,11 @@ int AUBCommandStreamReceiverHw<GfxFamily>::getAddressSpace(int hint) {
return AubMemDump::AddressSpaceValues::TraceNonlocal;
}
template <typename GfxFamily>
int AUBCommandStreamReceiverHw<GfxFamily>::getAddressSpaceFromPTEBits(uint64_t entryBits) const {
return AubMemDump::AddressSpaceValues::TraceNonlocal;
}
template <typename GfxFamily>
uint64_t AUBCommandStreamReceiverHw<GfxFamily>::getGTTBits() const {
return 0;

View File

@ -5,6 +5,7 @@
*
*/
#include "runtime/aub_mem_dump/page_table_entry_bits.h"
#include "runtime/memory_manager/page_table.h"
#include "runtime/memory_manager/page_table.inl"
@ -16,19 +17,20 @@ uintptr_t PTE::map(uintptr_t vm, size_t size, uint64_t entryBits, uint32_t memor
size_t indexStart = (vm >> shift) & mask;
size_t indexEnd = ((vm + size - 1) >> shift) & mask;
uintptr_t res = -1;
entryBits &= 0xfff;
entryBits |= 0x1;
bool updateEntryBits = entryBits != PageTableEntry::nonValidBits;
uint64_t newEntryBits = entryBits & 0xfff;
newEntryBits |= 0x1;
for (size_t index = indexStart; index <= indexEnd; index++) {
if (entries[index] == 0x0) {
uint64_t tmp = allocator->reservePage(memoryBank);
entries[index] = reinterpret_cast<void *>(tmp | entryBits);
} else {
entries[index] = reinterpret_cast<void *>((reinterpret_cast<uintptr_t>(entries[index]) & 0xfffff000u) | entryBits);
entries[index] = reinterpret_cast<void *>(tmp | newEntryBits);
} else if (updateEntryBits) {
entries[index] = reinterpret_cast<void *>((reinterpret_cast<uintptr_t>(entries[index]) & 0xfffff000u) | newEntryBits);
}
res = std::min(reinterpret_cast<uintptr_t>(entries[index]) & 0xfffff000u, res);
}
return (res & ~entryBits) + (vm & (pageSize - 1));
return (res & ~newEntryBits) + (vm & (pageSize - 1));
}
void PTE::pageWalk(uintptr_t vm, size_t size, size_t offset, uint64_t entryBits, PageWalker &pageWalker, uint32_t memoryBank) {
@ -39,15 +41,16 @@ void PTE::pageWalk(uintptr_t vm, size_t size, size_t offset, uint64_t entryBits,
size_t indexEnd = ((vm + size - 1) >> shift) & mask;
uint64_t res = -1;
uintptr_t rem = vm & (pageSize - 1);
entryBits &= 0xfff;
entryBits |= 0x1;
bool updateEntryBits = entryBits != PageTableEntry::nonValidBits;
uint64_t newEntryBits = entryBits & 0xfff;
newEntryBits |= 0x1;
for (size_t index = indexStart; index <= indexEnd; index++) {
if (entries[index] == 0x0) {
uint64_t tmp = allocator->reservePage(memoryBank);
entries[index] = reinterpret_cast<void *>(tmp | entryBits);
} else {
entries[index] = reinterpret_cast<void *>((reinterpret_cast<uintptr_t>(entries[index]) & 0xfffff000u) | entryBits);
entries[index] = reinterpret_cast<void *>(tmp | newEntryBits);
} else if (updateEntryBits) {
entries[index] = reinterpret_cast<void *>((reinterpret_cast<uintptr_t>(entries[index]) & 0xfffff000u) | newEntryBits);
}
res = reinterpret_cast<uintptr_t>(entries[index]) & 0xfffff000u;

View File

@ -7,6 +7,7 @@
#pragma once
#include "runtime/aub_mem_dump/aub_mem_dump.h"
#include "runtime/aub_mem_dump/page_table_entry_bits.h"
#include "runtime/command_stream/aub_command_stream_receiver_hw.h"
#include "runtime/command_stream/command_stream_receiver_with_aub_dump.h"
#include "runtime/command_stream/tbx_command_stream_receiver_hw.h"
@ -64,10 +65,10 @@ class AUBCommandStreamFixture : public CommandStreamFixture {
aubCsr->stream->expectMemory(physAddress,
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(srcAddress) + offset),
size,
AubMemDump::CmdServicesMemTraceMemoryCompare::AddressSpaceValues::TraceNonlocal);
aubCsr->getAddressSpaceFromPTEBits(entryBits));
};
aubCsr->ppgtt->pageWalk(reinterpret_cast<uintptr_t>(gfxAddress), length, 0, 0, walker, PageTableHelper::memoryBankNotSpecified);
aubCsr->ppgtt->pageWalk(reinterpret_cast<uintptr_t>(gfxAddress), length, 0, PageTableEntry::nonValidBits, walker, PageTableHelper::memoryBankNotSpecified);
}
CommandStreamReceiver *pCommandStreamReceiver = nullptr;

View File

@ -6,6 +6,7 @@
*/
#include "runtime/aub_mem_dump/aub_mem_dump.h"
#include "runtime/aub_mem_dump/page_table_entry_bits.h"
#include "runtime/command_stream/aub_command_stream_receiver_hw.h"
#include "runtime/helpers/array_count.h"
#include "runtime/helpers/dispatch_info.h"
@ -1805,6 +1806,14 @@ HWTEST_F(AubCommandStreamReceiverTests, givenPhysicalAddressWhenSetGttEntryIsCal
EXPECT_FALSE(entry.pageConfig.LocalMemory);
}
HWTEST_F(AubCommandStreamReceiverTests, givenEntryBitsPresentAndWritableWhenGetAddressSpaceFromPTEBitsIsCalledThenTraceNonLocalIsReturned) {
const HardwareInfo &hwInfoIn = *platformDevices[0];
std::unique_ptr<MockAubCsr<FamilyType>> aubCsr(new MockAubCsr<FamilyType>(hwInfoIn, "", true, *pDevice->executionEnvironment));
auto space = aubCsr->getAddressSpaceFromPTEBits(PageTableEntry::presentBit | PageTableEntry::writableBit);
EXPECT_EQ(AubMemDump::AddressSpaceValues::TraceNonlocal, space);
}
template <typename GfxFamily>
struct MockAubCsrToTestExternalAllocations : public AUBCommandStreamReceiverHw<GfxFamily> {
using AUBCommandStreamReceiverHw<GfxFamily>::AUBCommandStreamReceiverHw;

View File

@ -5,6 +5,7 @@
*
*/
#include "runtime/aub_mem_dump/page_table_entry_bits.h"
#include "runtime/helpers/ptr_math.h"
#include "runtime/helpers/selectors.h"
#include "runtime/memory_manager/page_table.h"
@ -270,7 +271,7 @@ TEST_F(PageTableTests48, givenEntryBitsWhenPageWalkIsCalledThenEntryBitsArePasse
EXPECT_EQ(ppgttBits, entryBitsPassed);
}
TEST_F(PageTableTests48, givenTwoPageWalksWhenSecondWalkHasDifferenEntryBitsThenEntryIsUpdated) {
TEST_F(PageTableTests48, givenTwoPageWalksWhenSecondWalkHasDifferentEntryBitsThenEntryIsUpdated) {
std::unique_ptr<TypeSelector<MockPML4, MockPDPE, sizeof(void *) == 8>::type>
pageTable(std::make_unique<TypeSelector<MockPML4, MockPDPE, sizeof(void *) == 8>::type>(&allocator));
@ -295,12 +296,59 @@ TEST_F(PageTableTests48, givenTwoPageWalksWhenSecondWalkHasDifferenEntryBitsThen
EXPECT_EQ(ppgttBits, entryBitsPassed);
}
TEST_F(PageTableTests48, givenTwoPageWalksWhenSecondWalkHasNonValidEntryBitsThenEntryIsNotUpdated) {
std::unique_ptr<TypeSelector<MockPML4, MockPDPE, sizeof(void *) == 8>::type>
pageTable(std::make_unique<TypeSelector<MockPML4, MockPDPE, sizeof(void *) == 8>::type>(&allocator));
uintptr_t gpuVa = 0x1000;
size_t size = pageSize;
size_t walked = 0u;
uint64_t ppgttBits = 0xabc;
uint64_t entryBitsPassed = 0u;
uint64_t entryBitsPassedFirstTime = 0u;
uint64_t entryBitsPassedSecondTime = 0u;
PageWalker walker = [&](uint64_t physAddress, size_t size, size_t offset, uint64_t entryBits) {
walked += size;
entryBitsPassed = entryBits;
};
pageTable->pageWalk(gpuVa, size, 0, ppgttBits, walker, 0);
ppgttBits |= 0x1;
EXPECT_EQ(ppgttBits, entryBitsPassed);
entryBitsPassedFirstTime = entryBitsPassed;
ppgttBits = PageTableEntry::nonValidBits;
pageTable->pageWalk(gpuVa, size, 0, ppgttBits, walker, 0);
entryBitsPassedSecondTime = entryBitsPassed;
EXPECT_EQ(entryBitsPassedFirstTime, entryBitsPassedSecondTime);
}
TEST_F(PageTableTests48, givenTwoMapsWhenSecondMapHasDifferentEntryBitsThenEntryIsUpdated) {
std::unique_ptr<TypeSelector<MockPML4, MockPDPE, sizeof(void *) == 8>::type>
pageTable(std::make_unique<TypeSelector<MockPML4, MockPDPE, sizeof(void *) == 8>::type>(&allocator));
uintptr_t gpuVa = 0x1000;
size_t size = pageSize;
uint64_t ppgttBits = 0xabc;
auto address = allocator.nextPageAddress.load();
pageTable->map(gpuVa, size, ppgttBits, 0);
ASSERT_NE(nullptr, pageTable->entries[0]);
PageTableEntryChecker::testEntry<TypeSelector<MockPML4, MockPDPE, sizeof(void *) == 8>::type>(pageTable.get(), 1, static_cast<uintptr_t>(address | ppgttBits | 0x1));
ppgttBits = 0x345;
pageTable->map(gpuVa, size, ppgttBits, 0);
PageTableEntryChecker::testEntry<TypeSelector<MockPML4, MockPDPE, sizeof(void *) == 8>::type>(pageTable.get(), 1, static_cast<uintptr_t>(address | ppgttBits | 0x1));
}
TEST_F(PageTableTests48, givenTwoMapsWhenSecondMapHasNonValidEntryBitsThenEntryIsNotUpdated) {
std::unique_ptr<TypeSelector<MockPML4, MockPDPE, sizeof(void *) == 8>::type>
pageTable(std::make_unique<TypeSelector<MockPML4, MockPDPE, sizeof(void *) == 8>::type>(&allocator));
uintptr_t gpuVa = 0x1000;
size_t size = pageSize;
uint64_t ppgttBits = 0xabc;
auto address = allocator.nextPageAddress.load();
pageTable->map(gpuVa, size, ppgttBits, 0);
@ -308,8 +356,8 @@ TEST_F(PageTableTests48, givenTwoMapsWhenSecondMapHasDifferentEntryBitsThenEntry
PageTableEntryChecker::testEntry<TypeSelector<MockPML4, MockPDPE, sizeof(void *) == 8>::type>(pageTable.get(), 1, static_cast<uintptr_t>(address | ppgttBits | 0x1));
ppgttBits = 0x345;
pageTable->map(gpuVa, size, ppgttBits, 0);
uint64_t nonValidPpgttBits = PageTableEntry::nonValidBits;
pageTable->map(gpuVa, size, nonValidPpgttBits, 0);
PageTableEntryChecker::testEntry<TypeSelector<MockPML4, MockPDPE, sizeof(void *) == 8>::type>(pageTable.get(), 1, static_cast<uintptr_t>(address | ppgttBits | 0x1));
}