Skip to content

Commit

Permalink
introduce ept_t::map_identity_sparse() method
Browse files Browse the repository at this point in the history
  • Loading branch information
wbenny committed Jan 6, 2020
1 parent b76feb2 commit 7b976e6
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 6 deletions.
41 changes: 35 additions & 6 deletions src/hvpp/hvpp/ept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,6 @@ void ept_t::map_identity(epte_t::access_type access /* = epte_t::access_type::re
// loss.
//

//
// TODO:
// - Map only valid physical memory ranges?
// - Map up to max valid physical memory address? (incl. "holes")
//

static constexpr auto _512gb = 512ull * 1024
* 1024
* 1024;
Expand All @@ -87,6 +81,41 @@ void ept_t::map_identity(epte_t::access_type access /* = epte_t::access_type::re
}
}

void ept_t::map_identity_sparse(epte_t::access_type access /* = epte_t::access_type::read_write_execute */) noexcept
{
//
// This method is similar to the map_identity() method above, except that
// the memory is covered by using physical_memory_descriptor() as opposed to
// covering the first 512 GB of physical memory.
//
// The benefit of this approach is that it uses significantly less memory
// for the EPT structures. Only addresses backed by actual physical memory
// are mapped (considering that the machine doesn't have 512 GB+).
//
// The drawback of this approach is that it doesn't cover MMIO address ranges.
// Therefore there is a good chance that you'll receive several EPT violations.
// EPT violation handler then should create and map EPT entries for the missing
// pages.
//

//
// #TODO
// Consider combined approach where the first 4GB is mapped unconditionally (most
// MMIO is there) and rest is filled with physical_memory_descriptor().
//

for (auto& range : mm::physical_memory_descriptor())
{
auto from = pa_t{ page_align (range.begin().value(), pd_t{}) };
auto to = pa_t{ page_align_up(range.end().value(), pd_t{}) };

for (pa_t pa = from; pa < to; pa += ept_pd_t::size)
{
map_2mb(pa, pa, access);
}
}
}

epte_t* ept_t::map(pa_t guest_pa, pa_t host_pa,
epte_t::access_type access /* = epte_t::access_type::read_write_execute */,
pml level /* = pml::pt */) noexcept
Expand Down
1 change: 1 addition & 0 deletions src/hvpp/hvpp/ept.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class ept_t final
ept_t& operator=(ept_t&& other) noexcept = delete;

void map_identity(epte_t::access_type access = epte_t::access_type::read_write_execute) noexcept;
void map_identity_sparse(epte_t::access_type access = epte_t::access_type::read_write_execute) noexcept;

epte_t* map (pa_t guest_pa, pa_t host_pa,
epte_t::access_type access = epte_t::access_type::read_write_execute,
Expand Down
19 changes: 19 additions & 0 deletions src/hvpp/hvpp/hvpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,25 @@ HvppEptMapIdentityEx(
ept_->map_identity((epte_t::access_type)(Access));
}

VOID
NTAPI
HvppEptMapIdentitySparse(
_In_ PEPT Ept
)
{
ept_->map_identity_sparse();
}

VOID
NTAPI
HvppEptMapIdentitySparseEx(
_In_ PEPT Ept,
_In_ ULONG Access
)
{
ept_->map_identity_sparse((epte_t::access_type)(Access));
}

PEPTE
NTAPI
HvppEptMap(
Expand Down
13 changes: 13 additions & 0 deletions src/hvpp/hvpp/hvpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,19 @@ HvppEptMapIdentityEx(
_In_ ULONG Access
);

VOID
NTAPI
HvppEptMapIdentitySparse(
_In_ PEPT Ept
);

VOID
NTAPI
HvppEptMapIdentitySparseEx(
_In_ PEPT Ept,
_In_ ULONG Access
);

PEPTE
NTAPI
HvppEptMap(
Expand Down

0 comments on commit 7b976e6

Please sign in to comment.