Free allocated BOs for read-only user pointer
- when pinning fails with EFAULT due to read-only memory used for allocation (BO), mark the allocated fragments to be freed, as cpu copy will be used. - prevent possible leaks Change-Id: I200ba276da5e3a8557df28fe2e411ef30d69a86a
This commit is contained in:
parent
1e81426599
commit
eec43f65a7
|
@ -472,6 +472,7 @@ uint64_t DrmMemoryManager::getInternalHeapBaseAddress() {
|
|||
MemoryManager::AllocationStatus DrmMemoryManager::populateOsHandles(OsHandleStorage &handleStorage) {
|
||||
BufferObject *allocatedBos[max_fragments_count];
|
||||
size_t numberOfBosAllocated = 0;
|
||||
uint32_t indexesOfAllocatedBos[max_fragments_count];
|
||||
|
||||
for (unsigned int i = 0; i < max_fragments_count; i++) {
|
||||
// If there is no fragment it means it already exists.
|
||||
|
@ -489,6 +490,7 @@ MemoryManager::AllocationStatus DrmMemoryManager::populateOsHandles(OsHandleStor
|
|||
}
|
||||
|
||||
allocatedBos[numberOfBosAllocated] = handleStorage.fragmentStorageData[i].osHandleStorage->bo;
|
||||
indexesOfAllocatedBos[numberOfBosAllocated] = i;
|
||||
numberOfBosAllocated++;
|
||||
|
||||
hostPtrManager.storeFragment(handleStorage.fragmentStorageData[i]);
|
||||
|
@ -499,6 +501,9 @@ MemoryManager::AllocationStatus DrmMemoryManager::populateOsHandles(OsHandleStor
|
|||
int result = pinBB->pin(allocatedBos, numberOfBosAllocated);
|
||||
|
||||
if (result == EFAULT) {
|
||||
for (uint32_t i = 0; i < numberOfBosAllocated; i++) {
|
||||
handleStorage.fragmentStorageData[indexesOfAllocatedBos[i]].freeTheFragment = true;
|
||||
}
|
||||
return AllocationStatus::InvalidHostPointer;
|
||||
} else if (result != 0) {
|
||||
return AllocationStatus::Error;
|
||||
|
|
|
@ -2571,3 +2571,49 @@ TEST_F(DrmMemoryManagerWithExplicitExpectationsTest, givenForcePinNotAllowedAndH
|
|||
|
||||
::alignedFree(ptr);
|
||||
}
|
||||
|
||||
TEST_F(DrmMemoryManagerWithExplicitExpectationsTest, givenEnabledValidateHostMemoryWhenReadOnlyPointerCausesPinningFailWithEfaultThenPopulateOsHandlesMarksFragmentsToFree) {
|
||||
std::unique_ptr<TestedDrmMemoryManager> testedMemoryManager(new TestedDrmMemoryManager(this->mock, false, true));
|
||||
ASSERT_NE(nullptr, testedMemoryManager.get());
|
||||
ASSERT_NE(nullptr, testedMemoryManager->getPinBB());
|
||||
|
||||
mock->reset();
|
||||
|
||||
DrmMockCustom::IoctlResExt ioctlResExt = {2, -1};
|
||||
mock->ioctl_res_ext = &ioctlResExt;
|
||||
mock->errnoValue = EFAULT;
|
||||
mock->ioctl_expected.gemUserptr = 2;
|
||||
mock->ioctl_expected.execbuffer2 = 1;
|
||||
|
||||
OsHandleStorage handleStorage;
|
||||
OsHandle handle1;
|
||||
handleStorage.fragmentStorageData[0].osHandleStorage = &handle1;
|
||||
handleStorage.fragmentStorageData[0].cpuPtr = (void *)0x1000;
|
||||
handleStorage.fragmentStorageData[0].fragmentSize = 4096;
|
||||
|
||||
handleStorage.fragmentStorageData[1].osHandleStorage = nullptr;
|
||||
handleStorage.fragmentStorageData[1].cpuPtr = (void *)0x2000;
|
||||
handleStorage.fragmentStorageData[1].fragmentSize = 8192;
|
||||
|
||||
handleStorage.fragmentStorageData[2].osHandleStorage = nullptr;
|
||||
handleStorage.fragmentStorageData[2].cpuPtr = (void *)0x4000;
|
||||
handleStorage.fragmentStorageData[2].fragmentSize = 4096;
|
||||
|
||||
auto result = testedMemoryManager->populateOsHandles(handleStorage);
|
||||
EXPECT_EQ(MemoryManager::AllocationStatus::InvalidHostPointer, result);
|
||||
|
||||
mock->testIoctls();
|
||||
|
||||
EXPECT_NE(nullptr, handleStorage.fragmentStorageData[0].osHandleStorage);
|
||||
EXPECT_NE(nullptr, handleStorage.fragmentStorageData[1].osHandleStorage);
|
||||
EXPECT_NE(nullptr, handleStorage.fragmentStorageData[2].osHandleStorage);
|
||||
|
||||
EXPECT_TRUE(handleStorage.fragmentStorageData[1].freeTheFragment);
|
||||
EXPECT_TRUE(handleStorage.fragmentStorageData[2].freeTheFragment);
|
||||
|
||||
handleStorage.fragmentStorageData[0].freeTheFragment = false;
|
||||
handleStorage.fragmentStorageData[1].freeTheFragment = true;
|
||||
handleStorage.fragmentStorageData[2].freeTheFragment = true;
|
||||
|
||||
testedMemoryManager->cleanOsHandles(handleStorage);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue