Files
vmware-host-modules/vmmon-only/include/x86types.h
T

480 lines
10 KiB
C

/*********************************************************
* Copyright (C) 2003-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation version 2 and no later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*********************************************************/
/*
* x86types.h --
*
* Type definitions for the x86 architecture.
*/
#ifndef _X86TYPES_H_
#define _X86TYPES_H_
#define INCLUDE_ALLOW_USERLEVEL
#define INCLUDE_ALLOW_MODULE
#define INCLUDE_ALLOW_VMK_MODULE
#define INCLUDE_ALLOW_VMKERNEL
#define INCLUDE_ALLOW_DISTRIBUTE
#define INCLUDE_ALLOW_VMCORE
#define INCLUDE_ALLOW_VMMON
#include "includeCheck.h"
#include "vm_basic_types.h"
#include "vm_basic_defs.h"
#include "address_defs.h"
#include "x86segdescrs.h"
/*
* Types used for PL4 page table in x86_64 and arm64
*/
typedef uint64 VM_L4E;
typedef uint64 VM_L3E;
typedef uint64 VM_L2E;
typedef uint64 VM_L1E;
/*
* Page table
*/
typedef uint32 VM_PDE;
typedef uint32 VM_PTE;
typedef uint64 VM_PAE_PDE;
typedef uint64 VM_PAE_PTE;
typedef uint64 VM_PDPTE;
/*
* Extended page table
*/
typedef uint64 VM_EPTE;
/*
* Registers
*/
typedef union SharedReg64 {
Reg8 reg8[2];
Reg16 reg16;
Reg32 reg32;
Reg64 reg64;
} SharedReg64;
typedef union SharedUReg64 {
UReg8 ureg8[2];
UReg16 ureg16;
UReg32 ureg32;
UReg32 ureg32Pair[2];
UReg64 ureg64;
} SharedUReg64;
typedef uint8 Instruction;
typedef uint16 Selector;
/*
* tasks
*/
#define IST_NUM_ENTRIES 8
#pragma pack(push, 1)
typedef struct Task64 {
uint32 reserved0;
uint64 rsp[3]; // Stacks for CPL 0-2.
uint64 ist[IST_NUM_ENTRIES]; // ist[0] is reserved.
uint64 reserved1;
uint16 reserved2;
uint16 IOMapBase;
} Task64;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct Task32 {
uint32 prevTask;
uint32 esp0;
uint32 ss0;
uint32 esp1;
uint32 ss1;
uint32 esp2;
uint32 ss2;
uint32 cr3;
uint32 eip;
uint32 eflags;
uint32 eax;
uint32 ecx;
uint32 edx;
uint32 ebx;
uint32 esp;
uint32 ebp;
uint32 esi;
uint32 edi;
uint32 es;
uint32 cs;
uint32 ss;
uint32 ds;
uint32 fs;
uint32 gs;
uint32 ldt;
uint16 trap;
uint16 IOMapBase;
} Task32;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct {
uint16 prevTask;
uint16 sp0; // static. Unmarked fields are dynamic
uint16 ss0; // static
uint16 sp1; // static
uint16 ss1; // static
uint16 sp2; // static
uint16 ss2; // static
uint16 ip;
uint16 flags;
uint16 ax;
uint16 cx;
uint16 dx;
uint16 bx;
uint16 sp;
uint16 bp;
uint16 si;
uint16 di;
uint16 es;
uint16 cs;
uint16 ss;
uint16 ds;
uint16 ldt; // static
} Task16;
#pragma pack(pop)
// Task defaults to Task32 for everyone except vmkernel. Task64 is used where
// needed by these products.
#if defined VMX86_SERVER && defined VMKERNEL
#ifdef VM_X86_64
typedef Task64 Task;
#else
typedef Task32 Task;
#endif
#else /* VMX86_SERVER && defined VMKERNEL */
typedef Task32 Task;
#endif
/*
* far pointers
*/
#pragma pack(push, 1)
typedef struct {
#if defined(VMM) || defined(COREQUERY)
uint64 va;
#else
uint32 va;
#endif
Selector seg;
} FarPtr;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct FarPtr16 {
uint16 offset;
uint16 selector;
} FarPtr16;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct FarPtr32 {
uint32 offset;
uint16 selector;
} FarPtr32;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct FarPtr64 {
uint64 offset;
uint16 selector;
} FarPtr64;
#pragma pack(pop)
/*
* X86-defined stack layouts for interrupts, exceptions, irets, calls, etc.
*/
/*
* Layout of the 64-bit stack frame on exception.
*/
#pragma pack(push, 1)
typedef struct x86ExcFrame64 {
uint64 rip;
uint16 cs, __sel[3];
uint64 rflags;
uint64 rsp;
uint16 ss, __ssel[3];
} x86ExcFrame64;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct x86ExcFrame64WithErrorCode {
uint32 errorCode, __errorCode;
uint64 rip;
uint16 cs, __sel[3];
uint64 rflags;
uint64 rsp;
uint16 ss, __ssel[3];
} x86ExcFrame64WithErrorCode;
#pragma pack(pop)
/*
* Layout of the 32-bit stack frame on exception.
*/
#pragma pack(push, 1)
typedef struct x86ExcFrame32 {
uint32 eip;
union {
struct {
uint16 sel, __sel;
} cs16;
uint32 cs32;
} u;
uint32 eflags;
} x86ExcFrame32;
#pragma pack(pop)
/*
* Layout of the 32-bit stack frame with ss:esp and no error code.
*/
#pragma pack(push, 1)
typedef struct x86ExcFrame32WithStack {
uint32 eip;
uint16 cs, __csu;
uint32 eflags;
uint32 esp;
uint16 ss, __ssu;
} x86ExcFrame32WithStack;
#pragma pack(pop)
/*
* Layout of the 32-bit stack frame on inter-level transfer.
*/
#pragma pack(push, 1)
typedef struct x86ExcFrame32IL {
uint32 errorCode;
uint32 eip;
uint16 cs, __csu;
uint32 eflags;
uint32 esp;
uint16 ss, __ssu;
} x86ExcFrame32IL;
#pragma pack(pop)
/*
* Layout of the 16-bit stack frame on exception.
*/
#pragma pack(push, 1)
typedef struct x86ExcFrame16 {
uint16 eip;
uint16 cs;
uint16 eflags;
} x86ExcFrame16;
#pragma pack(pop)
/*
* Layout of the 16-bit stack frame which incudes ss:sp.
*/
#pragma pack(push, 1)
typedef struct x86ExcFrame16WithStack {
uint16 ip;
uint16 cs;
uint16 flags;
uint16 sp;
uint16 ss;
} x86ExcFrame16WithStack;
#pragma pack(pop)
/*
* Layout of the 32-bit stack frame on exception
* from V8086 mode. It is also a superset
* of inter-level exception stack frame, which
* in turn is superset of intra-level exception
* stack frame.
*/
#pragma pack(push, 1)
typedef struct x86ExcFrameV8086 {
uint32 eip;
union {
struct {
uint16 sel, __sel;
} cs16;
uint32 cs32;
} u;
uint32 eflags;
uint32 esp;
uint16 ss, __ss;
uint16 es, __es;
uint16 ds, __ds;
uint16 fs, __fs;
uint16 gs, __gs;
} x86ExcFrameV8086;
#pragma pack(pop)
/*
* Layout of the 32-bit stack frame on exception
* from V8086 mode with errorCode. It is
* superset of SegmentExcFrameV8086.
*/
#pragma pack(push, 1)
typedef struct x86ExcFrameV8086WithErrorCode {
uint32 errorCode;
uint32 eip;
union {
struct {
uint16 sel, __sel;
} cs16;
uint32 cs32;
} u;
uint32 eflags;
uint32 esp;
uint16 ss, __ss;
uint16 es, __es;
uint16 ds, __ds;
uint16 fs, __fs;
uint16 gs, __gs;
} x86ExcFrameV8086WithErrorCode;
#pragma pack(pop)
/*
* Layout of the stack on a 32 bit far call.
*/
#pragma pack(push, 1)
typedef struct x86CallStack32 {
uint32 eip;
uint16 cs, __cs;
} x86CallStack32;
#pragma pack(pop)
/*
* Layout of the stack on a 16 bit far call.
*/
#pragma pack(push, 1)
typedef struct x86CallStack16 {
uint16 ip;
uint16 cs;
} x86CallStack16;
#pragma pack(pop)
/*
* Layout of the stack on a 32 bit far call.
*/
#pragma pack(push, 1)
typedef struct x86CallGateStack32 {
uint32 eip;
uint16 cs, __cs;
uint32 esp;
uint16 ss, __ss;
} x86CallGateStack32;
#pragma pack(pop)
/*
* Layout of the stack on a 16 bit far call.
*/
#pragma pack(push, 1)
typedef struct x86CallGateStack16 {
uint16 ip;
uint16 cs;
uint16 sp;
uint16 ss;
} x86CallGateStack16;
#pragma pack(pop)
typedef struct DebugControlRegister {
int l0:1;
int g0:1;
int l1:1;
int g1:1;
int l2:1;
int g2:1;
int l3:1;
int g3:1;
int le:1;
int ge:1;
int oo1:3;
int gd:1;
int oo:2;
int rw0:2;
int len0:2;
int rw1:2;
int len1:2;
int rw2:2;
int len2:2;
int rw3:2;
int len3:2;
} DebugControlRegister;
/*
* When an interrupt descriptor has an IST entry programmed, for any raised
* interrupt (or fault, or exception), the stack pointer is switched to the top
* of a specified stack and the exception frame is pushed. If another
* interrupt is raised with the same IST entry programmed before the first is
* handled, the first's context is corrupted and system integrity is
* compromised.
*
* When the monitor binary translates code for a guest, any interrupt must be
* taken on a host stack, and thus IST entries are used for all vectors. The
* vmkernel uses a separate stack for #MCE handling, programmed via an IST
* entry. In both cases, the danger of context corruption by successive faults
* is real and must be dealt with.
*
* In handlers for these exceptions, the initial exception frame is copied
* further down the stack and the stack pointer updated to point to the copy.
* The distance from the top of the stack for the copy is situation-dependent.
*
* ExcFrame64ForCopy extends x86ExcFrame64 and maintains congruence with the
* full x86 exception frame types (VMKFullExcFrame and the monitor's ExcFrame).
* Enough space is afforded for a couple of temporary software-pushed registers
* to accommodate the stack copy.
*/
#pragma pack(push, 1)
typedef struct ExcFrame64ForCopy {
UReg64 r13; // Pushed by SW. Used as temp reg.
UReg64 r14; // Pushed by SW. Used as temp reg.
UReg64 r15; // Pushed by SW. Pushed by gate.
UReg64 errorCode; // Pushed by SW or HW.
UReg64 rip; // Pushed by HW.
uint16 cs, __csu[3]; // Pushed by HW.
uint64 rflags; // Pushed by HW.
UReg64 rsp; // Pushed by HW.
uint16 ss, __ssu[3]; // Pushed by HW.
} ExcFrame64ForCopy;
#pragma pack(pop)
#endif // ifndef _X86TYPES_H_