Permalink
Switch branches/tags
Nothing to show
Find file Copy path
84c5f91 Sep 3, 2016
0 contributors

Users who have contributed to this file

107 lines (85 sloc) 2.63 KB
/*++
Copyright (c) Alex Ionescu. All rights reserved.
Module Name:
shvutil.c
Abstract:
This module implements utility functions for the Simple Hyper Visor.
Author:
Alex Ionescu (@aionescu) 16-Mar-2016 - Initial version
Environment:
Kernel mode only.
--*/
#include "shv.h"
VOID
ShvUtilConvertGdtEntry (
_In_ VOID* GdtBase,
_In_ UINT16 Selector,
_Out_ PVMX_GDTENTRY64 VmxGdtEntry
)
{
PKGDTENTRY64 gdtEntry;
//
// Reject LDT or NULL entries
//
if ((Selector == 0) ||
(Selector & SELECTOR_TABLE_INDEX) != 0)
{
VmxGdtEntry->Limit = VmxGdtEntry->AccessRights = 0;
VmxGdtEntry->Base = 0;
VmxGdtEntry->Selector = 0;
VmxGdtEntry->Bits.Unusable = TRUE;
return;
}
//
// Read the GDT entry at the given selector, masking out the RPL bits.
//
gdtEntry = (PKGDTENTRY64)((uintptr_t)GdtBase + (Selector & ~RPL_MASK));
//
// Write the selector directly
//
VmxGdtEntry->Selector = Selector;
//
// Use the LSL intrinsic to read the segment limit
//
VmxGdtEntry->Limit = __segmentlimit(Selector);
//
// Build the full 64-bit effective address, keeping in mind that only when
// the System bit is unset, should this be done.
//
// NOTE: The Windows definition of KGDTENTRY64 is WRONG. The "System" field
// is incorrectly defined at the position of where the AVL bit should be.
// The actual location of the SYSTEM bit is encoded as the highest bit in
// the "Type" field.
//
VmxGdtEntry->Base = ((gdtEntry->Bytes.BaseHigh << 24) |
(gdtEntry->Bytes.BaseMiddle << 16) |
(gdtEntry->BaseLow)) & 0xFFFFFFFF;
VmxGdtEntry->Base |= ((gdtEntry->Bits.Type & 0x10) == 0) ?
((uintptr_t)gdtEntry->BaseUpper << 32) : 0;
//
// Load the access rights
//
VmxGdtEntry->AccessRights = 0;
VmxGdtEntry->Bytes.Flags1 = gdtEntry->Bytes.Flags1;
VmxGdtEntry->Bytes.Flags2 = gdtEntry->Bytes.Flags2;
//
// Finally, handle the VMX-specific bits
//
VmxGdtEntry->Bits.Reserved = 0;
VmxGdtEntry->Bits.Unusable = !gdtEntry->Bits.Present;
}
UINT32
ShvUtilAdjustMsr (
_In_ LARGE_INTEGER ControlValue,
_In_ UINT32 DesiredValue
)
{
//
// VMX feature/capability MSRs encode the "must be 0" bits in the high word
// of their value, and the "must be 1" bits in the low word of their value.
// Adjust any requested capability/feature based on these requirements.
//
DesiredValue &= ControlValue.HighPart;
DesiredValue |= ControlValue.LowPart;
return DesiredValue;
}