Changed u8* to MemoryRef

This commit is contained in:
Hamish Milne 2020-01-04 22:39:54 +00:00 committed by zhupengfei
parent cf985631e0
commit 65d96bf6c1
24 changed files with 486 additions and 177 deletions

View file

@ -22,8 +22,7 @@ TestEnvironment::TestEnvironment(bool mutable_memory_)
kernel->SetCurrentProcess(kernel->CreateProcess(kernel->CreateCodeSet("", 0)));
page_table = &kernel->GetCurrentProcess()->vm_manager.page_table;
page_table->pointers.fill(nullptr);
page_table->attributes.fill(Memory::PageType::Unmapped);
page_table->Clear();
memory->MapIoRegion(*page_table, 0x00000000, 0x80000000, test_memory);
memory->MapIoRegion(*page_table, 0x80000000, 0x80000000, test_memory);

View file

@ -138,67 +138,70 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
}
SECTION("translates StaticBuffer descriptors") {
auto buffer = std::make_shared<std::vector<u8>>(Memory::PAGE_SIZE);
std::fill(buffer->begin(), buffer->end(), 0xAB);
auto mem = std::make_shared<BufferMem>(Memory::PAGE_SIZE);
MemoryRef buffer{mem};
std::fill(buffer.GetPtr(), buffer.GetPtr() + buffer.GetSize(), 0xAB);
VAddr target_address = 0x10000000;
auto result = process->vm_manager.MapBackingMemory(target_address, buffer->data(),
buffer->size(), MemoryState::Private);
auto result = process->vm_manager.MapBackingMemory(target_address, buffer, buffer.GetSize(),
MemoryState::Private);
REQUIRE(result.Code() == RESULT_SUCCESS);
const u32_le input[]{
IPC::MakeHeader(0, 0, 2),
IPC::StaticBufferDesc(buffer->size(), 0),
IPC::StaticBufferDesc(buffer.GetSize(), 0),
target_address,
};
context.PopulateFromIncomingCommandBuffer(input, *process);
CHECK(context.GetStaticBuffer(0) == *buffer);
CHECK(context.GetStaticBuffer(0) == mem->Vector());
REQUIRE(process->vm_manager.UnmapRange(target_address, buffer->size()) == RESULT_SUCCESS);
REQUIRE(process->vm_manager.UnmapRange(target_address, buffer.GetSize()) == RESULT_SUCCESS);
}
SECTION("translates MappedBuffer descriptors") {
auto buffer = std::make_shared<std::vector<u8>>(Memory::PAGE_SIZE);
std::fill(buffer->begin(), buffer->end(), 0xCD);
auto mem = std::make_shared<BufferMem>(Memory::PAGE_SIZE);
MemoryRef buffer{mem};
std::fill(buffer.GetPtr(), buffer.GetPtr() + buffer.GetSize(), 0xCD);
VAddr target_address = 0x10000000;
auto result = process->vm_manager.MapBackingMemory(target_address, buffer->data(),
buffer->size(), MemoryState::Private);
auto result = process->vm_manager.MapBackingMemory(target_address, buffer, buffer.GetSize(),
MemoryState::Private);
const u32_le input[]{
IPC::MakeHeader(0, 0, 2),
IPC::MappedBufferDesc(buffer->size(), IPC::R),
IPC::MappedBufferDesc(buffer.GetSize(), IPC::R),
target_address,
};
context.PopulateFromIncomingCommandBuffer(input, *process);
std::vector<u8> other_buffer(buffer->size());
context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer->size());
std::vector<u8> other_buffer(buffer.GetSize());
context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer.GetSize());
CHECK(other_buffer == *buffer);
CHECK(other_buffer == mem->Vector());
REQUIRE(process->vm_manager.UnmapRange(target_address, buffer->size()) == RESULT_SUCCESS);
REQUIRE(process->vm_manager.UnmapRange(target_address, buffer.GetSize()) == RESULT_SUCCESS);
}
SECTION("translates mixed params") {
auto buffer_static = std::make_shared<std::vector<u8>>(Memory::PAGE_SIZE);
std::fill(buffer_static->begin(), buffer_static->end(), 0xCE);
auto mem_static = std::make_shared<BufferMem>(Memory::PAGE_SIZE);
MemoryRef buffer_static{mem_static};
std::fill(buffer_static.GetPtr(), buffer_static.GetPtr() + buffer_static.GetSize(), 0xCE);
auto buffer_mapped = std::make_shared<std::vector<u8>>(Memory::PAGE_SIZE);
std::fill(buffer_mapped->begin(), buffer_mapped->end(), 0xDF);
auto mem_mapped = std::make_shared<BufferMem>(Memory::PAGE_SIZE);
MemoryRef buffer_mapped{mem_mapped};
std::fill(buffer_mapped.GetPtr(), buffer_mapped.GetPtr() + buffer_mapped.GetSize(), 0xDF);
VAddr target_address_static = 0x10000000;
auto result =
process->vm_manager.MapBackingMemory(target_address_static, buffer_static->data(),
buffer_static->size(), MemoryState::Private);
auto result = process->vm_manager.MapBackingMemory(
target_address_static, buffer_static, buffer_static.GetSize(), MemoryState::Private);
REQUIRE(result.Code() == RESULT_SUCCESS);
VAddr target_address_mapped = 0x20000000;
result = process->vm_manager.MapBackingMemory(target_address_mapped, buffer_mapped->data(),
buffer_mapped->size(), MemoryState::Private);
result = process->vm_manager.MapBackingMemory(
target_address_mapped, buffer_mapped, buffer_mapped.GetSize(), MemoryState::Private);
REQUIRE(result.Code() == RESULT_SUCCESS);
auto a = MakeObject(kernel);
@ -210,9 +213,9 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
process->handle_table.Create(a).Unwrap(),
IPC::CallingPidDesc(),
0,
IPC::StaticBufferDesc(buffer_static->size(), 0),
IPC::StaticBufferDesc(buffer_static.GetSize(), 0),
target_address_static,
IPC::MappedBufferDesc(buffer_mapped->size(), IPC::R),
IPC::MappedBufferDesc(buffer_mapped.GetSize(), IPC::R),
target_address_mapped,
};
@ -223,14 +226,14 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel
CHECK(output[2] == 0xABCDEF00);
CHECK(context.GetIncomingHandle(output[4]) == a);
CHECK(output[6] == process->process_id);
CHECK(context.GetStaticBuffer(0) == *buffer_static);
std::vector<u8> other_buffer(buffer_mapped->size());
context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer_mapped->size());
CHECK(other_buffer == *buffer_mapped);
CHECK(context.GetStaticBuffer(0) == mem_static->Vector());
std::vector<u8> other_buffer(buffer_mapped.GetSize());
context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer_mapped.GetSize());
CHECK(other_buffer == mem_mapped->Vector());
REQUIRE(process->vm_manager.UnmapRange(target_address_static, buffer_static->size()) ==
REQUIRE(process->vm_manager.UnmapRange(target_address_static, buffer_static.GetSize()) ==
RESULT_SUCCESS);
REQUIRE(process->vm_manager.UnmapRange(target_address_mapped, buffer_mapped->size()) ==
REQUIRE(process->vm_manager.UnmapRange(target_address_mapped, buffer_mapped.GetSize()) ==
RESULT_SUCCESS);
}
}
@ -317,10 +320,12 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
context.AddStaticBuffer(0, input_buffer);
auto output_buffer = std::make_shared<std::vector<u8>>(Memory::PAGE_SIZE);
auto output_mem = std::make_shared<BufferMem>(Memory::PAGE_SIZE);
MemoryRef output_buffer{output_mem};
VAddr target_address = 0x10000000;
auto result = process->vm_manager.MapBackingMemory(
target_address, output_buffer->data(), output_buffer->size(), MemoryState::Private);
target_address, output_buffer, output_buffer.GetSize(), MemoryState::Private);
REQUIRE(result.Code() == RESULT_SUCCESS);
input[0] = IPC::MakeHeader(0, 0, 2);
@ -332,13 +337,13 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
std::array<u32_le, IPC::COMMAND_BUFFER_LENGTH + 2> output_cmdbuff;
// Set up the output StaticBuffer
output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH] =
IPC::StaticBufferDesc(output_buffer->size(), 0);
IPC::StaticBufferDesc(output_buffer.GetSize(), 0);
output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH + 1] = target_address;
context.WriteToOutgoingCommandBuffer(output_cmdbuff.data(), *process);
CHECK(*output_buffer == input_buffer);
REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer->size()) ==
CHECK(output_mem->Vector() == input_buffer);
REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer.GetSize()) ==
RESULT_SUCCESS);
}
@ -346,15 +351,17 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
std::vector<u8> input_buffer(Memory::PAGE_SIZE);
std::fill(input_buffer.begin(), input_buffer.end(), 0xAB);
auto output_buffer = std::make_shared<std::vector<u8>>(Memory::PAGE_SIZE);
auto output_mem = std::make_shared<BufferMem>(Memory::PAGE_SIZE);
MemoryRef output_buffer{output_mem};
VAddr target_address = 0x10000000;
auto result = process->vm_manager.MapBackingMemory(
target_address, output_buffer->data(), output_buffer->size(), MemoryState::Private);
target_address, output_buffer, output_buffer.GetSize(), MemoryState::Private);
REQUIRE(result.Code() == RESULT_SUCCESS);
const u32_le input_cmdbuff[]{
IPC::MakeHeader(0, 0, 2),
IPC::MappedBufferDesc(output_buffer->size(), IPC::W),
IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W),
target_address,
};
@ -363,15 +370,15 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") {
context.GetMappedBuffer(0).Write(input_buffer.data(), 0, input_buffer.size());
input[0] = IPC::MakeHeader(0, 0, 2);
input[1] = IPC::MappedBufferDesc(output_buffer->size(), IPC::W);
input[1] = IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W);
input[2] = 0;
context.WriteToOutgoingCommandBuffer(output, *process);
CHECK(output[1] == IPC::MappedBufferDesc(output_buffer->size(), IPC::W));
CHECK(output[1] == IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W));
CHECK(output[2] == target_address);
CHECK(*output_buffer == input_buffer);
REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer->size()) ==
CHECK(output_mem->Vector() == input_buffer);
REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer.GetSize()) ==
RESULT_SUCCESS);
}
}

View file

@ -10,47 +10,48 @@
#include "core/memory.h"
TEST_CASE("Memory Basics", "[kernel][memory]") {
auto block = std::make_shared<std::vector<u8>>(Memory::PAGE_SIZE);
auto mem = std::make_shared<BufferMem>(Memory::PAGE_SIZE);
MemoryRef block{mem};
Memory::MemorySystem memory;
SECTION("mapping memory") {
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
auto manager = std::make_unique<Kernel::VMManager>(memory);
auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block->data(), block->size(),
auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(),
Kernel::MemoryState::Private);
REQUIRE(result.Code() == RESULT_SUCCESS);
auto vma = manager->FindVMA(Memory::HEAP_VADDR);
CHECK(vma != manager->vma_map.end());
CHECK(vma->second.size == block->size());
CHECK(vma->second.size == block.GetSize());
CHECK(vma->second.type == Kernel::VMAType::BackingMemory);
CHECK(vma->second.backing_memory == block->data());
CHECK(vma->second.backing_memory.GetPtr() == block.GetPtr());
CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private);
}
SECTION("unmapping memory") {
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
auto manager = std::make_unique<Kernel::VMManager>(memory);
auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block->data(), block->size(),
auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(),
Kernel::MemoryState::Private);
REQUIRE(result.Code() == RESULT_SUCCESS);
ResultCode code = manager->UnmapRange(Memory::HEAP_VADDR, block->size());
ResultCode code = manager->UnmapRange(Memory::HEAP_VADDR, block.GetSize());
REQUIRE(code == RESULT_SUCCESS);
auto vma = manager->FindVMA(Memory::HEAP_VADDR);
CHECK(vma != manager->vma_map.end());
CHECK(vma->second.type == Kernel::VMAType::Free);
CHECK(vma->second.backing_memory == nullptr);
CHECK(vma->second.backing_memory.GetPtr() == nullptr);
}
SECTION("changing memory permissions") {
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
auto manager = std::make_unique<Kernel::VMManager>(memory);
auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block->data(), block->size(),
auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(),
Kernel::MemoryState::Private);
REQUIRE(result.Code() == RESULT_SUCCESS);
ResultCode code = manager->ReprotectRange(Memory::HEAP_VADDR, block->size(),
ResultCode code = manager->ReprotectRange(Memory::HEAP_VADDR, block.GetSize(),
Kernel::VMAPermission::Execute);
CHECK(code == RESULT_SUCCESS);
@ -58,24 +59,24 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
CHECK(vma != manager->vma_map.end());
CHECK(vma->second.permissions == Kernel::VMAPermission::Execute);
code = manager->UnmapRange(Memory::HEAP_VADDR, block->size());
code = manager->UnmapRange(Memory::HEAP_VADDR, block.GetSize());
REQUIRE(code == RESULT_SUCCESS);
}
SECTION("changing memory state") {
// Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
auto manager = std::make_unique<Kernel::VMManager>(memory);
auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block->data(), block->size(),
auto result = manager->MapBackingMemory(Memory::HEAP_VADDR, block, block.GetSize(),
Kernel::MemoryState::Private);
REQUIRE(result.Code() == RESULT_SUCCESS);
ResultCode code = manager->ReprotectRange(Memory::HEAP_VADDR, block->size(),
ResultCode code = manager->ReprotectRange(Memory::HEAP_VADDR, block.GetSize(),
Kernel::VMAPermission::ReadWrite);
REQUIRE(code == RESULT_SUCCESS);
SECTION("with invalid address") {
ResultCode code = manager->ChangeMemoryState(
0xFFFFFFFF, block->size(), Kernel::MemoryState::Locked,
0xFFFFFFFF, block.GetSize(), Kernel::MemoryState::Locked,
Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased,
Kernel::VMAPermission::Execute);
CHECK(code == Kernel::ERR_INVALID_ADDRESS);
@ -83,7 +84,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
SECTION("ignoring the original permissions") {
ResultCode code = manager->ChangeMemoryState(
Memory::HEAP_VADDR, block->size(), Kernel::MemoryState::Private,
Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Private,
Kernel::VMAPermission::None, Kernel::MemoryState::Locked,
Kernel::VMAPermission::Write);
CHECK(code == RESULT_SUCCESS);
@ -96,7 +97,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
SECTION("enforcing the original permissions with correct expectations") {
ResultCode code = manager->ChangeMemoryState(
Memory::HEAP_VADDR, block->size(), Kernel::MemoryState::Private,
Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Private,
Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased,
Kernel::VMAPermission::Execute);
CHECK(code == RESULT_SUCCESS);
@ -109,7 +110,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
SECTION("with incorrect permission expectations") {
ResultCode code = manager->ChangeMemoryState(
Memory::HEAP_VADDR, block->size(), Kernel::MemoryState::Private,
Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Private,
Kernel::VMAPermission::Execute, Kernel::MemoryState::Aliased,
Kernel::VMAPermission::Execute);
CHECK(code == Kernel::ERR_INVALID_ADDRESS_STATE);
@ -122,7 +123,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
SECTION("with incorrect state expectations") {
ResultCode code = manager->ChangeMemoryState(
Memory::HEAP_VADDR, block->size(), Kernel::MemoryState::Locked,
Memory::HEAP_VADDR, block.GetSize(), Kernel::MemoryState::Locked,
Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased,
Kernel::VMAPermission::Execute);
CHECK(code == Kernel::ERR_INVALID_ADDRESS_STATE);
@ -133,7 +134,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") {
CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private);
}
code = manager->UnmapRange(Memory::HEAP_VADDR, block->size());
code = manager->UnmapRange(Memory::HEAP_VADDR, block.GetSize());
REQUIRE(code == RESULT_SUCCESS);
}
}