Skip to content

Commit

Permalink
Fix serialization for MMIO
Browse files Browse the repository at this point in the history
  • Loading branch information
momo5502 committed Nov 18, 2024
1 parent 1a23e82 commit df5c8a3
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 28 deletions.
59 changes: 32 additions & 27 deletions src/emulator/memory_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,16 @@ namespace
}
}

static void serialize(utils::buffer_serializer& buffer, const memory_manager::committed_region& region)
{
buffer.write<uint64_t>(region.length);
buffer.write(region.pemissions);
}

static void deserialize(utils::buffer_deserializer& buffer, memory_manager::committed_region& region)
{
region.length = static_cast<size_t>(buffer.read<uint64_t>());
region.pemissions = buffer.read<memory_permission>();
}

static void serialize(utils::buffer_serializer& buffer, const memory_manager::reserved_region& region)
{
buffer.write(region.is_mmio);
buffer.write<uint64_t>(region.length);
buffer.write_map(region.committed_regions);
}

static void deserialize(utils::buffer_deserializer& buffer, memory_manager::reserved_region& region)
{
buffer.read(region.is_mmio);
region.length = static_cast<size_t>(buffer.read<uint64_t>());
buffer.read_map(region.committed_regions);
}
Expand All @@ -100,6 +90,11 @@ void memory_manager::serialize_memory_state(utils::buffer_serializer& buffer, co

for (const auto& reserved_region : this->reserved_regions_)
{
if (reserved_region.second.is_mmio)
{
continue;
}

for (const auto& region : reserved_region.second.committed_regions)
{
data.resize(region.second.length);
Expand Down Expand Up @@ -133,9 +128,18 @@ void memory_manager::deserialize_memory_state(utils::buffer_deserializer& buffer

std::vector<uint8_t> data{};

for (const auto& reserved_region : this->reserved_regions_)
for (auto i = this->reserved_regions_.begin(); i != this->reserved_regions_.end();)
{
for (const auto& region : reserved_region.second.committed_regions)
auto& reserved_region = i->second;
if (reserved_region.is_mmio)
{
i = this->reserved_regions_.erase(i);
continue;
}

++i;

for (const auto& region : reserved_region.committed_regions)
{
data.resize(region.second.length);

Expand Down Expand Up @@ -198,7 +202,7 @@ bool memory_manager::protect_memory(const uint64_t address, const size_t size, c
return true;
}

bool memory_manager::allocate_mmio(uint64_t address, size_t size, mmio_read_callback read_cb,
bool memory_manager::allocate_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb,
mmio_write_callback write_cb)
{
if (this->overlaps_reserved_region(address, size))
Expand All @@ -208,10 +212,13 @@ bool memory_manager::allocate_mmio(uint64_t address, size_t size, mmio_read_call

this->map_mmio(address, size, std::move(read_cb), std::move(write_cb));

const auto entry = this->reserved_regions_.try_emplace(address, size).first;
entry->second.committed_regions[address] = committed_region{
.length = size, .pemissions = memory_permission::read_write, .is_mmio = true,
};
const auto entry = this->reserved_regions_.try_emplace(address,
reserved_region{
.length = size,
.is_mmio = true,
}).first;

entry->second.committed_regions[address] = committed_region{size, memory_permission::read_write};

return true;
}
Expand All @@ -229,9 +236,7 @@ bool memory_manager::allocate_memory(const uint64_t address, const size_t size,
if (!reserve_only)
{
this->map_memory(address, size, permissions);
entry->second.committed_regions[address] = committed_region{
.length = size, .pemissions = memory_permission::read_write
};
entry->second.committed_regions[address] = committed_region{size, memory_permission::read_write};
}

return true;
Expand Down Expand Up @@ -304,6 +309,11 @@ bool memory_manager::decommit_memory(const uint64_t address, const size_t size)
return false;
}

if (entry->second.is_mmio)
{
throw std::runtime_error("Not allowed to decommit MMIO!");
}

const auto end = address + size;
const auto region_end = entry->first + entry->second.length;

Expand All @@ -323,11 +333,6 @@ bool memory_manager::decommit_memory(const uint64_t address, const size_t size)
break;
}

if (i->second.is_mmio)
{
throw std::runtime_error("Not allowed to decommit MMIO!");
}

const auto sub_region_end = i->first + i->second.length;
if (i->first >= address && sub_region_end <= end)
{
Expand Down
2 changes: 1 addition & 1 deletion src/emulator/memory_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ class memory_manager
{
size_t length{};
memory_permission pemissions{};
bool is_mmio{false};
};

using committed_region_map = std::map<uint64_t, committed_region>;
Expand All @@ -32,6 +31,7 @@ class memory_manager
{
size_t length{};
committed_region_map committed_regions{};
bool is_mmio{false};
};

virtual ~memory_manager() = default;
Expand Down

0 comments on commit df5c8a3

Please sign in to comment.