mirror of
https://github.com/momo5502/hypervisor.git
synced 2025-04-19 13:42:55 +00:00
Cleanup gdt loading
This commit is contained in:
parent
6052d25070
commit
4253953003
@ -456,38 +456,38 @@ VOID
|
|||||||
ShvUtilConvertGdtEntry(
|
ShvUtilConvertGdtEntry(
|
||||||
_In_ uint64_t GdtBase,
|
_In_ uint64_t GdtBase,
|
||||||
_In_ UINT16 Selector,
|
_In_ UINT16 Selector,
|
||||||
_Out_ PVMX_GDTENTRY64 VmxGdtEntry
|
_Out_ vmx_gdt_entry* VmxGdtEntry
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PKGDTENTRY64 gdtEntry;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reject LDT or NULL entries
|
// Reject LDT or NULL entries
|
||||||
//
|
//
|
||||||
if ((Selector == 0) ||
|
if ((Selector == 0) ||
|
||||||
(Selector & SEGMENT_SELECTOR_TABLE_FLAG) != 0)
|
(Selector & SEGMENT_SELECTOR_TABLE_FLAG) != 0)
|
||||||
{
|
{
|
||||||
VmxGdtEntry->Limit = VmxGdtEntry->AccessRights = 0;
|
VmxGdtEntry->limit = 0;
|
||||||
VmxGdtEntry->Base = 0;
|
VmxGdtEntry->access_rights.flags = 0;
|
||||||
VmxGdtEntry->Selector = 0;
|
VmxGdtEntry->base = 0;
|
||||||
VmxGdtEntry->Bits.Unusable = TRUE;
|
VmxGdtEntry->selector = 0;
|
||||||
|
VmxGdtEntry->access_rights.unusable = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Read the GDT entry at the given selector, masking out the RPL bits.
|
// Read the GDT entry at the given selector, masking out the RPL bits.
|
||||||
//
|
//
|
||||||
gdtEntry = (PKGDTENTRY64)(GdtBase + (Selector & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK));
|
auto* gdt_entry = (segment_descriptor_64*)(GdtBase + (Selector & ~
|
||||||
|
SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Write the selector directly
|
// Write the selector directly
|
||||||
//
|
//
|
||||||
VmxGdtEntry->Selector = Selector;
|
VmxGdtEntry->selector = Selector;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Use the LSL intrinsic to read the segment limit
|
// Use the LSL intrinsic to read the segment limit
|
||||||
//
|
//
|
||||||
VmxGdtEntry->Limit = __segmentlimit(Selector);
|
VmxGdtEntry->limit = __segmentlimit(Selector);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Build the full 64-bit effective address, keeping in mind that only when
|
// Build the full 64-bit effective address, keeping in mind that only when
|
||||||
@ -498,23 +498,35 @@ ShvUtilConvertGdtEntry(
|
|||||||
// The actual location of the SYSTEM bit is encoded as the highest bit in
|
// The actual location of the SYSTEM bit is encoded as the highest bit in
|
||||||
// the "Type" field.
|
// the "Type" field.
|
||||||
//
|
//
|
||||||
VmxGdtEntry->Base = ((gdtEntry->Bytes.BaseHigh << 24) |
|
VmxGdtEntry->base = 0;
|
||||||
(gdtEntry->Bytes.BaseMiddle << 16) |
|
VmxGdtEntry->base |= static_cast<uint64_t>(gdt_entry->base_address_low);
|
||||||
(gdtEntry->BaseLow)) & 0xFFFFFFFF;
|
VmxGdtEntry->base |= static_cast<uint64_t>(gdt_entry->base_address_middle) << 16;
|
||||||
VmxGdtEntry->Base |= ((gdtEntry->Bits.Type & 0x10) == 0) ? ((uintptr_t)gdtEntry->BaseUpper << 32) : 0;
|
VmxGdtEntry->base |= static_cast<uint64_t>(gdt_entry->base_address_high) << 24;
|
||||||
|
if (gdt_entry->descriptor_type == 0u)
|
||||||
|
{
|
||||||
|
VmxGdtEntry->base |= static_cast<uint64_t>(gdt_entry->base_address_upper) << 32;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Load the access rights
|
// Load the access rights
|
||||||
//
|
//
|
||||||
VmxGdtEntry->AccessRights = 0;
|
VmxGdtEntry->access_rights.flags = 0;
|
||||||
VmxGdtEntry->Bytes.Flags1 = gdtEntry->Bytes.Flags1;
|
|
||||||
VmxGdtEntry->Bytes.Flags2 = gdtEntry->Bytes.Flags2;
|
VmxGdtEntry->access_rights.type = gdt_entry->type;
|
||||||
|
VmxGdtEntry->access_rights.descriptor_type = gdt_entry->descriptor_type;
|
||||||
|
VmxGdtEntry->access_rights.descriptor_privilege_level = gdt_entry->descriptor_privilege_level;
|
||||||
|
VmxGdtEntry->access_rights.present = gdt_entry->present;
|
||||||
|
VmxGdtEntry->access_rights.reserved1 = gdt_entry->segment_limit_high;
|
||||||
|
VmxGdtEntry->access_rights.available_bit = gdt_entry->system;
|
||||||
|
VmxGdtEntry->access_rights.long_mode = gdt_entry->long_mode;
|
||||||
|
VmxGdtEntry->access_rights.default_big = gdt_entry->default_big;
|
||||||
|
VmxGdtEntry->access_rights.granularity = gdt_entry->granularity;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Finally, handle the VMX-specific bits
|
// Finally, handle the VMX-specific bits
|
||||||
//
|
//
|
||||||
VmxGdtEntry->Bits.Reserved = 0;
|
VmxGdtEntry->access_rights.reserved1 = 0;
|
||||||
VmxGdtEntry->Bits.Unusable = !gdtEntry->Bits.Present;
|
VmxGdtEntry->access_rights.unusable = !gdt_entry->present;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT32
|
UINT32
|
||||||
@ -894,7 +906,7 @@ void ShvVmxSetupVmcsForVp(vmx::vm_state* VpData)
|
|||||||
{
|
{
|
||||||
auto* state = &VpData->special_registers;
|
auto* state = &VpData->special_registers;
|
||||||
PCONTEXT context = &VpData->context_frame;
|
PCONTEXT context = &VpData->context_frame;
|
||||||
VMX_GDTENTRY64 vmxGdtEntry; // vmx_segment_access_rights
|
vmx_gdt_entry vmxGdtEntry;
|
||||||
ept_pointer vmxEptp;
|
ept_pointer vmxEptp;
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -990,60 +1002,60 @@ void ShvVmxSetupVmcsForVp(vmx::vm_state* VpData)
|
|||||||
// Load the CS Segment (Ring 0 Code)
|
// Load the CS Segment (Ring 0 Code)
|
||||||
//
|
//
|
||||||
ShvUtilConvertGdtEntry(state->gdtr.base_address, context->SegCs, &vmxGdtEntry);
|
ShvUtilConvertGdtEntry(state->gdtr.base_address, context->SegCs, &vmxGdtEntry);
|
||||||
__vmx_vmwrite(VMCS_GUEST_CS_SELECTOR, vmxGdtEntry.Selector);
|
__vmx_vmwrite(VMCS_GUEST_CS_SELECTOR, vmxGdtEntry.selector);
|
||||||
__vmx_vmwrite(VMCS_GUEST_CS_LIMIT, vmxGdtEntry.Limit);
|
__vmx_vmwrite(VMCS_GUEST_CS_LIMIT, vmxGdtEntry.limit);
|
||||||
__vmx_vmwrite(VMCS_GUEST_CS_ACCESS_RIGHTS, vmxGdtEntry.AccessRights);
|
__vmx_vmwrite(VMCS_GUEST_CS_ACCESS_RIGHTS, vmxGdtEntry.access_rights.flags);
|
||||||
__vmx_vmwrite(VMCS_GUEST_CS_BASE, vmxGdtEntry.Base);
|
__vmx_vmwrite(VMCS_GUEST_CS_BASE, vmxGdtEntry.base);
|
||||||
__vmx_vmwrite(VMCS_HOST_CS_SELECTOR, context->SegCs & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK);
|
__vmx_vmwrite(VMCS_HOST_CS_SELECTOR, context->SegCs & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Load the SS Segment (Ring 0 Data)
|
// Load the SS Segment (Ring 0 Data)
|
||||||
//
|
//
|
||||||
ShvUtilConvertGdtEntry(state->gdtr.base_address, context->SegSs, &vmxGdtEntry);
|
ShvUtilConvertGdtEntry(state->gdtr.base_address, context->SegSs, &vmxGdtEntry);
|
||||||
__vmx_vmwrite(VMCS_GUEST_SS_SELECTOR, vmxGdtEntry.Selector);
|
__vmx_vmwrite(VMCS_GUEST_SS_SELECTOR, vmxGdtEntry.selector);
|
||||||
__vmx_vmwrite(VMCS_GUEST_SS_LIMIT, vmxGdtEntry.Limit);
|
__vmx_vmwrite(VMCS_GUEST_SS_LIMIT, vmxGdtEntry.limit);
|
||||||
__vmx_vmwrite(VMCS_GUEST_SS_ACCESS_RIGHTS, vmxGdtEntry.AccessRights);
|
__vmx_vmwrite(VMCS_GUEST_SS_ACCESS_RIGHTS, vmxGdtEntry.access_rights.flags);
|
||||||
__vmx_vmwrite(VMCS_GUEST_SS_BASE, vmxGdtEntry.Base);
|
__vmx_vmwrite(VMCS_GUEST_SS_BASE, vmxGdtEntry.base);
|
||||||
__vmx_vmwrite(VMCS_HOST_SS_SELECTOR, context->SegSs & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK);
|
__vmx_vmwrite(VMCS_HOST_SS_SELECTOR, context->SegSs & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Load the DS Segment (Ring 3 Data)
|
// Load the DS Segment (Ring 3 Data)
|
||||||
//
|
//
|
||||||
ShvUtilConvertGdtEntry(state->gdtr.base_address, context->SegDs, &vmxGdtEntry);
|
ShvUtilConvertGdtEntry(state->gdtr.base_address, context->SegDs, &vmxGdtEntry);
|
||||||
__vmx_vmwrite(VMCS_GUEST_DS_SELECTOR, vmxGdtEntry.Selector);
|
__vmx_vmwrite(VMCS_GUEST_DS_SELECTOR, vmxGdtEntry.selector);
|
||||||
__vmx_vmwrite(VMCS_GUEST_DS_LIMIT, vmxGdtEntry.Limit);
|
__vmx_vmwrite(VMCS_GUEST_DS_LIMIT, vmxGdtEntry.limit);
|
||||||
__vmx_vmwrite(VMCS_GUEST_DS_ACCESS_RIGHTS, vmxGdtEntry.AccessRights);
|
__vmx_vmwrite(VMCS_GUEST_DS_ACCESS_RIGHTS, vmxGdtEntry.access_rights.flags);
|
||||||
__vmx_vmwrite(VMCS_GUEST_DS_BASE, vmxGdtEntry.Base);
|
__vmx_vmwrite(VMCS_GUEST_DS_BASE, vmxGdtEntry.base);
|
||||||
__vmx_vmwrite(VMCS_HOST_DS_SELECTOR, context->SegDs & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK);
|
__vmx_vmwrite(VMCS_HOST_DS_SELECTOR, context->SegDs & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Load the ES Segment (Ring 3 Data)
|
// Load the ES Segment (Ring 3 Data)
|
||||||
//
|
//
|
||||||
ShvUtilConvertGdtEntry(state->gdtr.base_address, context->SegEs, &vmxGdtEntry);
|
ShvUtilConvertGdtEntry(state->gdtr.base_address, context->SegEs, &vmxGdtEntry);
|
||||||
__vmx_vmwrite(VMCS_GUEST_ES_SELECTOR, vmxGdtEntry.Selector);
|
__vmx_vmwrite(VMCS_GUEST_ES_SELECTOR, vmxGdtEntry.selector);
|
||||||
__vmx_vmwrite(VMCS_GUEST_ES_LIMIT, vmxGdtEntry.Limit);
|
__vmx_vmwrite(VMCS_GUEST_ES_LIMIT, vmxGdtEntry.limit);
|
||||||
__vmx_vmwrite(VMCS_GUEST_ES_ACCESS_RIGHTS, vmxGdtEntry.AccessRights);
|
__vmx_vmwrite(VMCS_GUEST_ES_ACCESS_RIGHTS, vmxGdtEntry.access_rights.flags);
|
||||||
__vmx_vmwrite(VMCS_GUEST_ES_BASE, vmxGdtEntry.Base);
|
__vmx_vmwrite(VMCS_GUEST_ES_BASE, vmxGdtEntry.base);
|
||||||
__vmx_vmwrite(VMCS_HOST_ES_SELECTOR, context->SegEs & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK);
|
__vmx_vmwrite(VMCS_HOST_ES_SELECTOR, context->SegEs & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Load the FS Segment (Ring 3 Compatibility-Mode TEB)
|
// Load the FS Segment (Ring 3 Compatibility-Mode TEB)
|
||||||
//
|
//
|
||||||
ShvUtilConvertGdtEntry(state->gdtr.base_address, context->SegFs, &vmxGdtEntry);
|
ShvUtilConvertGdtEntry(state->gdtr.base_address, context->SegFs, &vmxGdtEntry);
|
||||||
__vmx_vmwrite(VMCS_GUEST_FS_SELECTOR, vmxGdtEntry.Selector);
|
__vmx_vmwrite(VMCS_GUEST_FS_SELECTOR, vmxGdtEntry.selector);
|
||||||
__vmx_vmwrite(VMCS_GUEST_FS_LIMIT, vmxGdtEntry.Limit);
|
__vmx_vmwrite(VMCS_GUEST_FS_LIMIT, vmxGdtEntry.limit);
|
||||||
__vmx_vmwrite(VMCS_GUEST_FS_ACCESS_RIGHTS, vmxGdtEntry.AccessRights);
|
__vmx_vmwrite(VMCS_GUEST_FS_ACCESS_RIGHTS, vmxGdtEntry.access_rights.flags);
|
||||||
__vmx_vmwrite(VMCS_GUEST_FS_BASE, vmxGdtEntry.Base);
|
__vmx_vmwrite(VMCS_GUEST_FS_BASE, vmxGdtEntry.base);
|
||||||
__vmx_vmwrite(VMCS_HOST_FS_BASE, vmxGdtEntry.Base);
|
__vmx_vmwrite(VMCS_HOST_FS_BASE, vmxGdtEntry.base);
|
||||||
__vmx_vmwrite(VMCS_HOST_FS_SELECTOR, context->SegFs & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK);
|
__vmx_vmwrite(VMCS_HOST_FS_SELECTOR, context->SegFs & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Load the GS Segment (Ring 3 Data if in Compatibility-Mode, MSR-based in Long Mode)
|
// Load the GS Segment (Ring 3 Data if in Compatibility-Mode, MSR-based in Long Mode)
|
||||||
//
|
//
|
||||||
ShvUtilConvertGdtEntry(state->gdtr.base_address, context->SegGs, &vmxGdtEntry);
|
ShvUtilConvertGdtEntry(state->gdtr.base_address, context->SegGs, &vmxGdtEntry);
|
||||||
__vmx_vmwrite(VMCS_GUEST_GS_SELECTOR, vmxGdtEntry.Selector);
|
__vmx_vmwrite(VMCS_GUEST_GS_SELECTOR, vmxGdtEntry.selector);
|
||||||
__vmx_vmwrite(VMCS_GUEST_GS_LIMIT, vmxGdtEntry.Limit);
|
__vmx_vmwrite(VMCS_GUEST_GS_LIMIT, vmxGdtEntry.limit);
|
||||||
__vmx_vmwrite(VMCS_GUEST_GS_ACCESS_RIGHTS, vmxGdtEntry.AccessRights);
|
__vmx_vmwrite(VMCS_GUEST_GS_ACCESS_RIGHTS, vmxGdtEntry.access_rights.flags);
|
||||||
__vmx_vmwrite(VMCS_GUEST_GS_BASE, state->msr_gs_base);
|
__vmx_vmwrite(VMCS_GUEST_GS_BASE, state->msr_gs_base);
|
||||||
__vmx_vmwrite(VMCS_HOST_GS_BASE, state->msr_gs_base);
|
__vmx_vmwrite(VMCS_HOST_GS_BASE, state->msr_gs_base);
|
||||||
__vmx_vmwrite(VMCS_HOST_GS_SELECTOR, context->SegGs & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK);
|
__vmx_vmwrite(VMCS_HOST_GS_SELECTOR, context->SegGs & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK);
|
||||||
@ -1052,21 +1064,21 @@ void ShvVmxSetupVmcsForVp(vmx::vm_state* VpData)
|
|||||||
// Load the Task Register (Ring 0 TSS)
|
// Load the Task Register (Ring 0 TSS)
|
||||||
//
|
//
|
||||||
ShvUtilConvertGdtEntry(state->gdtr.base_address, state->tr, &vmxGdtEntry);
|
ShvUtilConvertGdtEntry(state->gdtr.base_address, state->tr, &vmxGdtEntry);
|
||||||
__vmx_vmwrite(VMCS_GUEST_TR_SELECTOR, vmxGdtEntry.Selector);
|
__vmx_vmwrite(VMCS_GUEST_TR_SELECTOR, vmxGdtEntry.selector);
|
||||||
__vmx_vmwrite(VMCS_GUEST_TR_LIMIT, vmxGdtEntry.Limit);
|
__vmx_vmwrite(VMCS_GUEST_TR_LIMIT, vmxGdtEntry.limit);
|
||||||
__vmx_vmwrite(VMCS_GUEST_TR_ACCESS_RIGHTS, vmxGdtEntry.AccessRights);
|
__vmx_vmwrite(VMCS_GUEST_TR_ACCESS_RIGHTS, vmxGdtEntry.access_rights.flags);
|
||||||
__vmx_vmwrite(VMCS_GUEST_TR_BASE, vmxGdtEntry.Base);
|
__vmx_vmwrite(VMCS_GUEST_TR_BASE, vmxGdtEntry.base);
|
||||||
__vmx_vmwrite(VMCS_HOST_TR_BASE, vmxGdtEntry.Base);
|
__vmx_vmwrite(VMCS_HOST_TR_BASE, vmxGdtEntry.base);
|
||||||
__vmx_vmwrite(VMCS_HOST_TR_SELECTOR, state->tr & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK);
|
__vmx_vmwrite(VMCS_HOST_TR_SELECTOR, state->tr & ~SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Load the Local Descriptor Table (Ring 0 LDT on Redstone)
|
// Load the Local Descriptor Table (Ring 0 LDT on Redstone)
|
||||||
//
|
//
|
||||||
ShvUtilConvertGdtEntry(state->gdtr.base_address, state->ldtr, &vmxGdtEntry);
|
ShvUtilConvertGdtEntry(state->gdtr.base_address, state->ldtr, &vmxGdtEntry);
|
||||||
__vmx_vmwrite(VMCS_GUEST_LDTR_SELECTOR, vmxGdtEntry.Selector);
|
__vmx_vmwrite(VMCS_GUEST_LDTR_SELECTOR, vmxGdtEntry.selector);
|
||||||
__vmx_vmwrite(VMCS_GUEST_LDTR_LIMIT, vmxGdtEntry.Limit);
|
__vmx_vmwrite(VMCS_GUEST_LDTR_LIMIT, vmxGdtEntry.limit);
|
||||||
__vmx_vmwrite(VMCS_GUEST_LDTR_ACCESS_RIGHTS, vmxGdtEntry.AccessRights);
|
__vmx_vmwrite(VMCS_GUEST_LDTR_ACCESS_RIGHTS, vmxGdtEntry.access_rights.flags);
|
||||||
__vmx_vmwrite(VMCS_GUEST_LDTR_BASE, vmxGdtEntry.Base);
|
__vmx_vmwrite(VMCS_GUEST_LDTR_BASE, vmxGdtEntry.base);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Now load the GDT itself
|
// Now load the GDT itself
|
||||||
|
@ -64,85 +64,10 @@ namespace vmx
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct vmx_gdt_entry
|
||||||
typedef struct _VMX_GDTENTRY64
|
|
||||||
{
|
{
|
||||||
UINT64 Base;
|
uint64_t base;
|
||||||
UINT32 Limit;
|
uint32_t limit;
|
||||||
|
vmx_segment_access_rights access_rights;
|
||||||
union
|
uint16_t selector;
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
UINT8 Flags1;
|
|
||||||
UINT8 Flags2;
|
|
||||||
UINT8 Flags3;
|
|
||||||
UINT8 Flags4;
|
|
||||||
} Bytes;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
UINT16 SegmentType : 4;
|
|
||||||
UINT16 DescriptorType : 1;
|
|
||||||
UINT16 Dpl : 2;
|
|
||||||
UINT16 Present : 1;
|
|
||||||
|
|
||||||
UINT16 Reserved : 4;
|
|
||||||
UINT16 System : 1;
|
|
||||||
UINT16 LongMode : 1;
|
|
||||||
UINT16 DefaultBig : 1;
|
|
||||||
UINT16 Granularity : 1;
|
|
||||||
|
|
||||||
UINT16 Unusable : 1;
|
|
||||||
UINT16 Reserved2 : 15;
|
|
||||||
} Bits;
|
|
||||||
|
|
||||||
UINT32 AccessRights;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
UINT16 Selector;
|
|
||||||
} VMX_GDTENTRY64, *PVMX_GDTENTRY64;
|
|
||||||
|
|
||||||
|
|
||||||
typedef union _KGDTENTRY64
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
UINT16 LimitLow;
|
|
||||||
UINT16 BaseLow;
|
|
||||||
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
UINT8 BaseMiddle;
|
|
||||||
UINT8 Flags1;
|
|
||||||
UINT8 Flags2;
|
|
||||||
UINT8 BaseHigh;
|
|
||||||
} Bytes;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
UINT32 BaseMiddle : 8;
|
|
||||||
UINT32 Type : 5;
|
|
||||||
UINT32 Dpl : 2;
|
|
||||||
UINT32 Present : 1;
|
|
||||||
UINT32 LimitHigh : 4;
|
|
||||||
UINT32 System : 1;
|
|
||||||
UINT32 LongMode : 1;
|
|
||||||
UINT32 DefaultBig : 1;
|
|
||||||
UINT32 Granularity : 1;
|
|
||||||
UINT32 BaseHigh : 8;
|
|
||||||
} Bits;
|
|
||||||
};
|
|
||||||
|
|
||||||
UINT32 BaseUpper;
|
|
||||||
UINT32 MustBeZero;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
INT64 DataLow;
|
|
||||||
INT64 DataHigh;
|
|
||||||
};
|
|
||||||
} KGDTENTRY64, *PKGDTENTRY64;
|
|
Loading…
x
Reference in New Issue
Block a user