Commit graph

155 commits

Author SHA1 Message Date
Petr Beneš
84b3f3c241 cosmetic changes
Tabs/spaces, codestyle unification
2021-03-15 13:43:53 +01:00
Can Bölük
d41723bdca Fixing prefix handling of SYSCALL/RDTSC leaking the existence of the VMM 2021-03-15 13:43:53 +01:00
Can Bölük
c2db255b71 Fixing guest-to-host stack overflow. 2021-03-15 13:43:53 +01:00
Petr Benes
c9b6de15a5 make capacity of the heap-allocator configurable
The capacity is configurable via "AllocatorCapacity" registry value.
If this value is missing (or is invalid), then value of hypervisor_allocator_recommended_capacity() is used.
2020-01-06 19:03:33 +01:00
Petr Benes
cfe3d320b8 make logging, trace-logging and asserts optional during compile-time 2020-01-06 19:03:33 +01:00
Petr Benes
50fd7bbc2d add check if hypervisor_allocator() exists in the generic_free() method
This fixes crash that occurred if memory was freed/deleted before
the hypervisor_allocator is initialized.
2020-01-06 19:03:16 +01:00
Petr Benes
7b976e63a3 introduce ept_t::map_identity_sparse() method 2020-01-06 19:03:16 +01:00
Petr Benes
b76feb2d98 make global_t instances static
These structures are mainly used for purpose of easier debugging.
That means - instead of adding each member separately "on the watch"
of the debugger, the whole structure is put on the watch.

Also, these structures shouldn't be accessible outside of the compilation
unit, therefore it makes sense to make them static. This has also benefit
of avoiding potential name conflicts.
2020-01-06 19:03:16 +01:00
Petr Benes
d2d1cabdc3 cosmetic changes (reword ept_t::map_identity() description) 2020-01-06 19:02:49 +01:00
Petr Benes
946a9b5cec add configuration for .inl files to .editorconfig 2019-10-31 16:24:30 +01:00
Petr Benes
f1eece7d0d introduce vmexit_handler::terminate() method
Previously, vmexit_handler::teardown() initiated the termination of VMX operation (e.g. by vmcall, which subsequently executed VMXOFF).
Now this process is moved into vmexit_handler::terminate() method (in layman's terms, "teardown" method has been renamed to "terminate").

The vmexit_handler::teardown() method hasn't been removed, though. From now, it is used as a complementary method to vmexit_handler::setup().
2019-10-31 15:11:45 +01:00
Petr Benes
a2e52fbbf6 redo usage of EPT, again
Previously, EPT was completely managed by vcpu_t.
Current design delegates all EPT management to the user, which gives
them more freedom in how they use EPT.

More specifically, in previous design it was impossible to create new
EPT dynamically, after virtualization has been enabled.  This issue is
resolved with the new design.
2019-10-31 15:11:39 +01:00
Petr Benes
fb0be3b6ab add vcpu_t::user_data()
Holds per-VCPU data assigned by the user.
2019-10-31 15:11:39 +01:00
Petr Benes
1d6b3d0e59 add new parameter "was_force_resumed" to vmexit_handler::handle_guest_resume() method
if was_force_resumed == true, then vmexit handler was resumed using vcpu_t::guest_resume() was called
2019-10-31 15:11:39 +01:00
Petr Benes
7922700cfe add kernel_(begin/end)_address and (highest_user/system_range_start)_address to the "driver" namespace 2019-10-31 15:11:39 +01:00
Petr Benes
c7cba16b20 add HvppNtStatusToErrorCode()/HvppErrorCodeToNtStatus() 2019-10-31 15:11:39 +01:00
Petr Benes
b839eff4fa add forgotten <cstddef> include for deque.h 2019-10-31 15:11:39 +01:00
Petr Benes
3862f71215 clear hypervisor_allocator_* variables after destroying the allocator 2019-10-31 15:11:39 +01:00
Petr Benes
5552f21bed fix "unused variable" for "alignment" in hypervisor_memory_allocator 2019-10-31 15:11:39 +01:00
Petr Benes
7b74a9a0a8 fix initialization of device::impl_ to nullptr 2019-10-31 15:11:39 +01:00
Petr Benes
02a06d4ea1 make vmx::vmcall() call vmx::vmcall_slow() or vmx::vmcall_fast() based on number of arguments 2019-10-31 15:11:39 +01:00
Petr Benes
b454563763 make enum operator functions "inline" 2019-10-31 15:11:39 +01:00
Petr Benes
408622ae40 make cr3_guard non-copyable, but movable 2019-10-31 15:11:39 +01:00
Petr Benes
e2e25b571c cosmetic changes 2019-10-31 15:11:32 +01:00
Petr Benes
58f9f6f859 fix crash on hvppdrv_c unload 2019-08-01 21:14:02 +02:00
Petr Benes
1cdbec6159 introduce vcpu_t::guest_resume() method
Calling this method will perform "long-jump" at the end of the VM-exit handler.  You can imagine it as some kind of "throw"-statement, that VM-exit handler "catch".

Note that calling this method IS DANGEROUS, AS IT WON'T FREE ANY OBJECTS ON STACK.
2019-08-01 21:14:02 +02:00
Petr Benes
b5a99457b1 rename *_to_string() functions just to to_string() 2019-08-01 21:14:02 +02:00
Petr Benes
bc5a342e8d make vmexit_handler::setup() return error_code_t 2019-08-01 21:14:02 +02:00
Petr Benes
80141935f6 switch to "auto method() -> return_type" convention in device object 2019-08-01 21:14:02 +02:00
Petr Benes
d8eb913052 introduce new flexible memory allocator
Previous "custom" allocator was non-replaceable and hard-coded.
The "custom allocator" term has been replaced with "hypervisor allocator", as it more closely reflects when is this allocator used.

Most importantly, this change allows anyone to write their own allocator/heap manager (or use existing one, such as dlmalloc) and bind it as the hypervisor allocator.
2019-08-01 21:13:58 +02:00
Petr Benes
82b7070c8b replace std::aligned_storage_t with std::array in object_t
Since std::aligned_storage_t is being deprecated, replace it with `alignas(T) std::array<std::byte, sizeof(T)>`.
2019-08-01 20:59:14 +02:00
Petr Benes
68db2ad3fb lock memory in device::copy_from_user() & device::copy_to_user() methods 2019-08-01 20:59:05 +02:00
Petr Benes
fc842b7019 allocate page_size-aligned memory for EPT subtables 2019-08-01 20:58:58 +02:00
Petr Benes
cd23e08137 make bitmap class template-specialized and remove bitmap_local class 2019-08-01 20:58:57 +02:00
Petr Benes
d30f38bfd8 add rdtsc/rdtscp opcode emulation
This might be useful in cases where it's desired to catch rdtsc/rdtscp begin executed only in user-mode.

Disabling rdtsc/rdstcp for user-mode is achieved by setting cr4_t::timestamp_disable flag (it might be needed to set correct value to the shadow CR4 due to patch-guard).

Note: this commit temporarily disables VMWARE_WORKAROUND, until correct solution is implemented.
2019-08-01 20:58:47 +02:00
Petr Benes
71673248c1 add correct handling of syscall/sysret
Using cr3_guard for reading instructions is not optimal, as the memory holding the instructions could be paged out (probably due to being only in instruction cache and not data cache).
Crash is more probable on system with more than 1 CPU.

The solution is to try to read the memory manually via page tables. In case the pages are not present, a page-fault exception is injected into the guest.
2019-08-01 20:58:38 +02:00
Petr Benes
b21b3c954f add vmexit_passthrough_handler::handle_nmi_window method 2019-08-01 20:58:33 +02:00
Petr Benes
465157c16a add tracing of interrupt handling 2019-08-01 20:58:32 +02:00
Petr Benes
b41d9f924e improve interrupt queue in vcpu_t 2019-08-01 20:58:29 +02:00
Petr Benes
4b676306ed add "fixed_dequeue" class 2019-08-01 20:58:24 +02:00
Petr Benes
56fc52225a add timestamp counter information into the vcpu_t class 2019-08-01 20:58:19 +02:00
Petr Benes
3a41720b77 add helper enum macros, that easily enable bitwise operations
Usage is demonstrated in logger.
2019-08-01 20:58:17 +02:00
Petr Benes
d3d975275a make memory_mapper & memory_translator part of vcpu_t
This will come in handy in vmexit_handler classes, when reading guest virtual memory is needed.
2019-08-01 20:58:00 +02:00
Petr Benes
8469e4cf13 introduce mm::memory_translator
Purpose of this class is to safely access guest-virtual-memory, instead of naive CR3 switch.
CR3 switch and accessing the virtual addresses directly may result in page-fault, which is undesirable in VMX-root mode. Even if we use something like MmIsAddressValid(), other CPU might unmap any virtual address we're about to touch.
The solution is "memory_translator", which helps to manipulate with guest virtual memory in safe manner, i.e. by manually looking up physical addresses for virtual addresses, and copying directly from/to them.
2019-08-01 20:57:23 +02:00
Petr Benes
73b0d8cbc5 fix setting wrong CR3 for VMX-root
Previous code assumed that callbacks called from the KeIpiGenericCall function are guaranteed to have system CR3. That assumption was wrong and the hypervisor might have crashed because of this.
2019-08-01 20:57:10 +02:00
Petr Benes
1c98c4edef introduce mm::paging_descriptor
This class initializes pointers to important paging structures (PML4, PDPT, PD, PT).

When the system is older than Win10 RS1, then page-tables are at fixed known location.

Since Win10 RS1, paging structures are not located at fixed virtual address, therefore we have to find them dynamically.
There are 2 ways to do this:
  1) Look at some function that references PTE_BASE (e.g. MmGetVirtualForPhysical) and take the pointer from there
  2) Find KDDEBUGGER_DATA64 structure, and read it from the PteBase field.

2nd method seems more reliable, as KDDEBUGGER_DATA64 is easy to find in memory, the structure is documented
and it doesn't change between versions.
2019-08-01 20:56:48 +02:00
Petr Benes
efd6e34dc6 improve va_t class, add methods like canonical()/is_canonical() 2019-08-01 20:56:40 +02:00
Petr Benes
b357ab64a8 rename va_t::index() to va_t::offset() (also for pa_t)
The naming is now equivalent with NT naming.
2019-08-01 20:56:29 +02:00
Petr Benes
9608bc71c4 memory manager refactoring
* make ia32::byte_offset return uint64_t instead of uint32_t
* move ia32::mapping_t to mm::memory_mapper
* move ia32::physical_memory_descriptor to mm::physical_memory_descriptor
* move ia32::mtrr to mm::mtrr_descriptor
* remove useless pa_from_va (with cr3) function; the reason is that physical address for each active CR3 is actually always same
2019-08-01 20:55:40 +02:00
Petr Benes
188479c084 vcpu_t::exit_context() -> vcpu_t::context()
Also, "guest_context_" & "exit_context_" are now merged in an union.
2019-08-01 20:55:21 +02:00