|
|
@ -16,13 +16,14 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|
|
|
SECTION("mapping memory") {
|
|
|
|
SECTION("mapping memory") {
|
|
|
|
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
|
|
|
|
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
|
|
|
|
auto manager = std::make_unique<Kernel::VMManager>(memory);
|
|
|
|
auto manager = std::make_unique<Kernel::VMManager>(memory);
|
|
|
|
auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(),
|
|
|
|
auto result =
|
|
|
|
Kernel::MemoryState::Private);
|
|
|
|
manager->MapBackingMemory(Memory::HEAP_VADDR, block, static_cast<u32>(block.GetSize()),
|
|
|
|
|
|
|
|
Kernel::MemoryState::Private);
|
|
|
|
REQUIRE(result.Code() == RESULT_SUCCESS);
|
|
|
|
REQUIRE(result.Code() == RESULT_SUCCESS);
|
|
|
|
|
|
|
|
|
|
|
|
auto vma = manager->FindVMA(Memory::HEAP_VADDR);
|
|
|
|
auto vma = manager->FindVMA(Memory::HEAP_VADDR);
|
|
|
|
CHECK(vma != manager->vma_map.end());
|
|
|
|
CHECK(vma != manager->vma_map.end());
|
|
|
|
CHECK(vma->second.size == block.GetSize());
|
|
|
|
CHECK(vma->second.size == static_cast<u32>(block.GetSize()));
|
|
|
|
CHECK(vma->second.type == Kernel::VMAType::BackingMemory);
|
|
|
|
CHECK(vma->second.type == Kernel::VMAType::BackingMemory);
|
|
|
|
CHECK(vma->second.backing_memory.GetPtr() == block.GetPtr());
|
|
|
|
CHECK(vma->second.backing_memory.GetPtr() == block.GetPtr());
|
|
|
|
CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private);
|
|
|
|
CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private);
|
|
|
@ -31,11 +32,13 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|
|
|
SECTION("unmapping memory") {
|
|
|
|
SECTION("unmapping memory") {
|
|
|
|
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
|
|
|
|
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
|
|
|
|
auto manager = std::make_unique<Kernel::VMManager>(memory);
|
|
|
|
auto manager = std::make_unique<Kernel::VMManager>(memory);
|
|
|
|
auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(),
|
|
|
|
auto result =
|
|
|
|
Kernel::MemoryState::Private);
|
|
|
|
manager->MapBackingMemory(Memory::HEAP_VADDR, block, static_cast<u32>(block.GetSize()),
|
|
|
|
|
|
|
|
Kernel::MemoryState::Private);
|
|
|
|
REQUIRE(result.Code() == RESULT_SUCCESS);
|
|
|
|
REQUIRE(result.Code() == RESULT_SUCCESS);
|
|
|
|
|
|
|
|
|
|
|
|
ResultCode code = manager->UnmapRange(Memory::HEAP_VADDR, block.GetSize());
|
|
|
|
ResultCode code =
|
|
|
|
|
|
|
|
manager->UnmapRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()));
|
|
|
|
REQUIRE(code == RESULT_SUCCESS);
|
|
|
|
REQUIRE(code == RESULT_SUCCESS);
|
|
|
|
|
|
|
|
|
|
|
|
auto vma = manager->FindVMA(Memory::HEAP_VADDR);
|
|
|
|
auto vma = manager->FindVMA(Memory::HEAP_VADDR);
|
|
|
@ -47,36 +50,39 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|
|
|
SECTION("changing memory permissions") {
|
|
|
|
SECTION("changing memory permissions") {
|
|
|
|
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
|
|
|
|
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
|
|
|
|
auto manager = std::make_unique<Kernel::VMManager>(memory);
|
|
|
|
auto manager = std::make_unique<Kernel::VMManager>(memory);
|
|
|
|
auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(),
|
|
|
|
auto result =
|
|
|
|
Kernel::MemoryState::Private);
|
|
|
|
manager->MapBackingMemory(Memory::HEAP_VADDR, block, static_cast<u32>(block.GetSize()),
|
|
|
|
|
|
|
|
Kernel::MemoryState::Private);
|
|
|
|
REQUIRE(result.Code() == RESULT_SUCCESS);
|
|
|
|
REQUIRE(result.Code() == RESULT_SUCCESS);
|
|
|
|
|
|
|
|
|
|
|
|
ResultCode code = manager->ReprotectRange(Memory::HEAP_VADDR, block.GetSize(),
|
|
|
|
ResultCode code = manager->ReprotectRange(
|
|
|
|
Kernel::VMAPermission::Execute);
|
|
|
|
Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), Kernel::VMAPermission::Execute);
|
|
|
|
CHECK(code == RESULT_SUCCESS);
|
|
|
|
CHECK(code == RESULT_SUCCESS);
|
|
|
|
|
|
|
|
|
|
|
|
auto vma = manager->FindVMA(Memory::HEAP_VADDR);
|
|
|
|
auto vma = manager->FindVMA(Memory::HEAP_VADDR);
|
|
|
|
CHECK(vma != manager->vma_map.end());
|
|
|
|
CHECK(vma != manager->vma_map.end());
|
|
|
|
CHECK(vma->second.permissions == Kernel::VMAPermission::Execute);
|
|
|
|
CHECK(vma->second.permissions == Kernel::VMAPermission::Execute);
|
|
|
|
|
|
|
|
|
|
|
|
code = manager->UnmapRange(Memory::HEAP_VADDR, block.GetSize());
|
|
|
|
code = manager->UnmapRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()));
|
|
|
|
REQUIRE(code == RESULT_SUCCESS);
|
|
|
|
REQUIRE(code == RESULT_SUCCESS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SECTION("changing memory state") {
|
|
|
|
SECTION("changing memory state") {
|
|
|
|
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
|
|
|
|
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
|
|
|
|
auto manager = std::make_unique<Kernel::VMManager>(memory);
|
|
|
|
auto manager = std::make_unique<Kernel::VMManager>(memory);
|
|
|
|
auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(),
|
|
|
|
auto result =
|
|
|
|
Kernel::MemoryState::Private);
|
|
|
|
manager->MapBackingMemory(Memory::HEAP_VADDR, block, static_cast<u32>(block.GetSize()),
|
|
|
|
|
|
|
|
Kernel::MemoryState::Private);
|
|
|
|
REQUIRE(result.Code() == RESULT_SUCCESS);
|
|
|
|
REQUIRE(result.Code() == RESULT_SUCCESS);
|
|
|
|
|
|
|
|
|
|
|
|
ResultCode code = manager->ReprotectRange(Memory::HEAP_VADDR, block.GetSize(),
|
|
|
|
ResultCode code =
|
|
|
|
Kernel::VMAPermission::ReadWrite);
|
|
|
|
manager->ReprotectRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()),
|
|
|
|
|
|
|
|
Kernel::VMAPermission::ReadWrite);
|
|
|
|
REQUIRE(code == RESULT_SUCCESS);
|
|
|
|
REQUIRE(code == RESULT_SUCCESS);
|
|
|
|
|
|
|
|
|
|
|
|
SECTION("with invalid address") {
|
|
|
|
SECTION("with invalid address") {
|
|
|
|
ResultCode code = manager->ChangeMemoryState(
|
|
|
|
ResultCode code = manager->ChangeMemoryState(
|
|
|
|
0xFFFFFFFF, block.GetSize(), Kernel::MemoryState::Locked,
|
|
|
|
0xFFFFFFFF, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Locked,
|
|
|
|
Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased,
|
|
|
|
Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased,
|
|
|
|
Kernel::VMAPermission::Execute);
|
|
|
|
Kernel::VMAPermission::Execute);
|
|
|
|
CHECK(code == Kernel::ERR_INVALID_ADDRESS);
|
|
|
|
CHECK(code == Kernel::ERR_INVALID_ADDRESS);
|
|
|
@ -84,7 +90,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|
|
|
|
|
|
|
|
|
|
|
SECTION("ignoring the original permissions") {
|
|
|
|
SECTION("ignoring the original permissions") {
|
|
|
|
ResultCode code = manager->ChangeMemoryState(
|
|
|
|
ResultCode code = manager->ChangeMemoryState(
|
|
|
|
Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Private,
|
|
|
|
Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Private,
|
|
|
|
Kernel::VMAPermission::None, Kernel::MemoryState::Locked,
|
|
|
|
Kernel::VMAPermission::None, Kernel::MemoryState::Locked,
|
|
|
|
Kernel::VMAPermission::Write);
|
|
|
|
Kernel::VMAPermission::Write);
|
|
|
|
CHECK(code == RESULT_SUCCESS);
|
|
|
|
CHECK(code == RESULT_SUCCESS);
|
|
|
@ -97,7 +103,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|
|
|
|
|
|
|
|
|
|
|
SECTION("enforcing the original permissions with correct expectations") {
|
|
|
|
SECTION("enforcing the original permissions with correct expectations") {
|
|
|
|
ResultCode code = manager->ChangeMemoryState(
|
|
|
|
ResultCode code = manager->ChangeMemoryState(
|
|
|
|
Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Private,
|
|
|
|
Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Private,
|
|
|
|
Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased,
|
|
|
|
Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased,
|
|
|
|
Kernel::VMAPermission::Execute);
|
|
|
|
Kernel::VMAPermission::Execute);
|
|
|
|
CHECK(code == RESULT_SUCCESS);
|
|
|
|
CHECK(code == RESULT_SUCCESS);
|
|
|
@ -110,7 +116,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|
|
|
|
|
|
|
|
|
|
|
SECTION("with incorrect permission expectations") {
|
|
|
|
SECTION("with incorrect permission expectations") {
|
|
|
|
ResultCode code = manager->ChangeMemoryState(
|
|
|
|
ResultCode code = manager->ChangeMemoryState(
|
|
|
|
Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Private,
|
|
|
|
Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Private,
|
|
|
|
Kernel::VMAPermission::Execute, Kernel::MemoryState::Aliased,
|
|
|
|
Kernel::VMAPermission::Execute, Kernel::MemoryState::Aliased,
|
|
|
|
Kernel::VMAPermission::Execute);
|
|
|
|
Kernel::VMAPermission::Execute);
|
|
|
|
CHECK(code == Kernel::ERR_INVALID_ADDRESS_STATE);
|
|
|
|
CHECK(code == Kernel::ERR_INVALID_ADDRESS_STATE);
|
|
|
@ -123,7 +129,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|
|
|
|
|
|
|
|
|
|
|
SECTION("with incorrect state expectations") {
|
|
|
|
SECTION("with incorrect state expectations") {
|
|
|
|
ResultCode code = manager->ChangeMemoryState(
|
|
|
|
ResultCode code = manager->ChangeMemoryState(
|
|
|
|
Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Locked,
|
|
|
|
Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Locked,
|
|
|
|
Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased,
|
|
|
|
Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased,
|
|
|
|
Kernel::VMAPermission::Execute);
|
|
|
|
Kernel::VMAPermission::Execute);
|
|
|
|
CHECK(code == Kernel::ERR_INVALID_ADDRESS_STATE);
|
|
|
|
CHECK(code == Kernel::ERR_INVALID_ADDRESS_STATE);
|
|
|
@ -134,7 +140,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
|
|
|
|
CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private);
|
|
|
|
CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
code = manager->UnmapRange(Memory::HEAP_VADDR, block.GetSize());
|
|
|
|
code = manager->UnmapRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()));
|
|
|
|
REQUIRE(code == RESULT_SUCCESS);
|
|
|
|
REQUIRE(code == RESULT_SUCCESS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|