summaryrefslogtreecommitdiff
path: root/gvm_types.h
diff options
context:
space:
mode:
Diffstat (limited to 'gvm_types.h')
-rwxr-xr-xgvm_types.h1534
1 files changed, 1534 insertions, 0 deletions
diff --git a/gvm_types.h b/gvm_types.h
new file mode 100755
index 0000000..9c54710
--- /dev/null
+++ b/gvm_types.h
@@ -0,0 +1,1534 @@
+/*
+ * Copyright 2019 Google LLC
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+
+ * 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.
+ */
+
+#pragma once
+#pragma warning(disable : 4018)
+#pragma warning(disable : 4100)
+#pragma warning(disable : 4152)
+#pragma warning(disable : 4389)
+#pragma warning(disable : 4267)
+#pragma warning(disable : 4242)
+#pragma warning(disable : 4244)
+#pragma warning(disable : 4245)
+#include <intrin.h>
+#include <ntddk.h>
+
+#define __align(a) __declspec(align(a))
+#define inline __inline
+#define __always_inline __forceinline
+#define __alwaysinline __forceinline
+
+typedef unsigned char uint8_t;
+typedef char int8_t;
+typedef unsigned short uint16_t;
+typedef short int16_t;
+typedef unsigned int uint32_t;
+typedef int int32_t;
+typedef unsigned long long uint64_t;
+typedef long long int64_t;
+
+typedef unsigned char u8;
+typedef char s8;
+typedef unsigned short u16;
+typedef short s16;
+typedef unsigned int u32;
+typedef int s32;
+typedef unsigned long long u64;
+typedef long long s64;
+
+typedef unsigned char __u8;
+typedef char __s8;
+typedef unsigned short __u16;
+typedef short __s16;
+typedef unsigned int __u32;
+typedef int __s32;
+typedef unsigned long long __u64;
+typedef long long __s64;
+
+/* This is a hack. We should really replace ulong to size_t */
+typedef size_t ulong;
+
+#define bool _Bool
+#define null NULL
+
+/* It seems VS has size_t but not ssize_t*/
+typedef intptr_t ssize_t;
+
+// per-cpu implementation
+#define MAX_CPU_NUMBERS 512
+#define DEFINE_PER_CPU(type, name) \
+ type name[MAX_CPU_NUMBERS]
+
+#define DECLARE_PER_CPU(type, name) \
+ extern type name[MAX_CPU_NUMBERS]
+
+#define per_cpu(name, cpu) \
+ name[cpu]
+#define this_cpu_ptr(pname) \
+ pname[raw_smp_processor_id()]
+#define __this_cpu_write(name, val) \
+ name[smp_processor_id()] = val
+
+//intel pmc stuff
+#define INTEL_PMC_MAX_GENERIC 32
+#define INTEL_PMC_MAX_FIXED 3
+
+struct irq_work {
+ int DONOTCARE2;
+};
+
+typedef u8 mtrr_type;
+
+#define PAGE_MASK (~(unsigned long long)(PAGE_SIZE - 1))
+
+#define kvm_PAGE_TRACK_MAX 1
+
+/*
+* These are used to make use of C type-checking..
+*/
+typedef size_t pteval_t;
+typedef size_t pmdval_t;
+typedef size_t pudval_t;
+typedef size_t pgdval_t;
+typedef size_t pgprotval_t;
+
+typedef struct { pteval_t pte; } pte_t;
+
+#define __default_cpu_present_to_apicid(a) 0
+
+#define NR_CPU_REGS 17
+
+/* BITS_PER_LONG is coming from linux kernel where long int has 64bits for
+ * x86_64 and 32bits for x86. Microsoft VC always treats long as int. So
+ * We keep the linux kernel definitions here. Since we replaced long(ulong)
+ * to ssize_t(size_t). This definition is indeed BITS_PER_SIZET.
+ */
+#ifdef _WIN64
+#define BITS_PER_LONG 64
+#else
+#define BITS_PER_LONG 32
+#endif
+
+#define atomic_read(a) *a
+
+#define __must_check
+
+#define false (unsigned char)0
+#define true (unsigned char)1
+
+#pragma warning(disable : 4201)
+#pragma pack(push, 1)
+struct desc_struct {
+ union {
+ struct {
+ unsigned int a;
+ unsigned int b;
+ };
+ struct {
+ u16 limit0;
+ u16 base0;
+ unsigned base1 : 8, type : 4, s : 1, dpl : 2, p : 1;
+ unsigned limit : 4, avl : 1, l : 1, d : 1, g : 1, base2 : 8;
+ };
+ };
+};
+
+/* LDT or TSS descriptor in the GDT. 16 bytes. */
+struct ldttss_desc64 {
+ u16 limit0;
+ u16 base0;
+ unsigned base1 : 8, type : 5, dpl : 2, p : 1;
+ unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8;
+ u32 base3;
+ u32 zero1;
+};
+#pragma pack(pop)
+
+static __inline size_t get_desc_base(const struct desc_struct *desc)
+{
+ return (size_t)(desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24));
+}
+
+static __inline void set_desc_base(struct desc_struct *desc, size_t base)
+{
+ desc->base0 = base & 0xffff;
+ desc->base1 = (base >> 16) & 0xff;
+ desc->base2 = (base >> 24) & 0xff;
+}
+
+static __inline size_t get_desc_limit(const struct desc_struct *desc)
+{
+ return desc->limit0 | (desc->limit << 16);
+}
+
+static __inline void set_desc_limit(struct desc_struct *desc, size_t limit)
+{
+ desc->limit0 = limit & 0xffff;
+ desc->limit = (limit >> 16) & 0xf;
+}
+
+#define __user
+
+#ifndef EPERM
+#define EPERM 1 /* Operation not permitted */
+#endif
+
+#ifndef ENOENT
+#define ENOENT 2 /* No such file or directory */
+#endif
+
+#ifndef ESRCH
+#define ESRCH 3 /* No such process */
+#endif
+
+#ifndef EINTR
+#define EINTR 4 /* Interrupted system call */
+#endif
+
+#ifndef EIO
+#define EIO 5 /* I/O error */
+#endif
+
+#ifndef ENXIO
+#define ENXIO 6 /* No such device or address */
+#endif
+
+#ifndef E2BIG
+#define E2BIG 7 /* Arg list too long */
+#endif
+
+#ifndef ENOEXEC
+#define ENOEXEC 8 /* Exec format error */
+#endif
+
+#ifndef EBADF
+#define EBADF 9 /* Bad file number */
+#endif
+
+#ifndef ECHILD
+#define ECHILD 10 /* No child processes */
+#endif
+
+#ifndef EAGAIN
+#define EAGAIN 11 /* Try again */
+#endif
+
+#ifndef ENOMEM
+#define ENOMEM 12 /* Out of memory */
+#endif
+
+#ifndef EACCES
+#define EACCES 13 /* Permission denied */
+#endif
+
+#ifndef EFAULT
+#define EFAULT 14 /* Bad address */
+#endif
+
+#ifndef ENOTBLK
+#define ENOTBLK 15 /* Block device required */
+#endif
+
+#ifndef EBUSY
+#define EBUSY 16 /* Device or resource busy */
+#endif
+
+#ifndef EEXIST
+#define EEXIST 17 /* File exists */
+#endif
+
+#ifndef EXDEV
+#define EXDEV 18 /* Cross-device link */
+#endif
+
+#ifndef ENODEV
+#define ENODEV 19 /* No such device */
+#endif
+
+#ifndef ENOTDIR
+#define ENOTDIR 20 /* Not a directory */
+#endif
+
+#ifndef EISDIR
+#define EISDIR 21 /* Is a directory */
+#endif
+
+#ifndef EINVAL
+#define EINVAL 22 /* Invalid argument */
+#endif
+
+#ifndef ENFILE
+#define ENFILE 23 /* File table overflow */
+#endif
+
+#ifndef EMFILE
+#define EMFILE 24 /* Too many open files */
+#endif
+
+#ifndef ENOTTY
+#define ENOTTY 25 /* Not a typewriter */
+#endif
+
+#ifndef ETXTBSY
+#define ETXTBSY 26 /* Text file busy */
+#endif
+
+#ifndef EFBIG
+#define EFBIG 27 /* File too large */
+#endif
+
+#ifndef ENOSPC
+#define ENOSPC 28 /* No space left on device */
+#endif
+
+#ifndef ESPIPE
+#define ESPIPE 29 /* Illegal seek */
+#endif
+
+#ifndef EROFS
+#define EROFS 30 /* Read-only file system */
+#endif
+
+#ifndef EMLINK
+#define EMLINK 31 /* Too many links */
+#endif
+
+#ifndef EPIPE
+#define EPIPE 32 /* Broken pipe */
+#endif
+
+#ifndef EDOM
+#define EDOM 33 /* Math argument out of domain of func */
+#endif
+
+#ifndef ERANGE
+#define ERANGE 34 /* Math result not representable */
+#endif
+
+#ifndef EDEADLK
+#define EDEADLK 35 /* Resource deadlock would occur */
+#endif
+
+#ifndef ENAMETOOLONG
+#define ENAMETOOLONG 36 /* File name too long */
+#endif
+
+#ifndef ENOLCK
+#define ENOLCK 37 /* No record locks available */
+#endif
+
+#ifndef ENOSYS
+#define ENOSYS 38 /* Function not implemented */
+#endif
+
+#ifndef ENOTEMPTY
+#define ENOTEMPTY 39 /* Directory not empty */
+#endif
+
+#ifndef ELOOP
+#define ELOOP 40 /* Too many symbolic links encountered */
+#endif
+
+#ifndef EWOULDBLOCK
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+#endif
+
+#ifndef ENOMSG
+#define ENOMSG 42 /* No message of desired type */
+#endif
+
+#ifndef EIDRM
+#define EIDRM 43 /* Identifier removed */
+#endif
+
+#ifndef ECHRNG
+#define ECHRNG 44 /* Channel number out of range */
+#endif
+
+#ifndef EL2NSYNC
+#define EL2NSYNC 45 /* Level 2 not synchronized */
+#endif
+
+#ifndef EL3HLT
+#define EL3HLT 46 /* Level 3 halted */
+#endif
+
+#ifndef EL3RST
+#define EL3RST 47 /* Level 3 reset */
+#endif
+
+#ifndef ELNRNG
+#define ELNRNG 48 /* Link number out of range */
+#endif
+
+#ifndef EUNATCH
+#define EUNATCH 49 /* Protocol driver not attached */
+#endif
+
+#ifndef ENOCSI
+#define ENOCSI 50 /* No CSI structure available */
+#endif
+
+#ifndef EL2HLT
+#define EL2HLT 51 /* Level 2 halted */
+#endif
+
+#ifndef EBADE
+#define EBADE 52 /* Invalid exchange */
+#endif
+
+#ifndef EBADR
+#define EBADR 53 /* Invalid request descriptor */
+#endif
+
+#ifndef EXFULL
+#define EXFULL 54 /* Exchange full */
+#endif
+
+#ifndef ENOANO
+#define ENOANO 55 /* No anode */
+#endif
+
+#ifndef EBADRQC
+#define EBADRQC 56 /* Invalid request code */
+#endif
+
+#ifndef EBADSLT
+#define EBADSLT 57 /* Invalid slot */
+#endif
+
+#ifndef EDEADLOCK
+#define EDEADLOCK EDEADLK
+#endif
+
+#ifndef EBFONT
+#define EBFONT 59 /* Bad font file format */
+#endif
+
+#ifndef ENOSTR
+#define ENOSTR 60 /* Device not a stream */
+#endif
+
+#ifndef ENODATA
+#define ENODATA 61 /* No data available */
+#endif
+
+#ifndef ETIME
+#define ETIME 62 /* Timer expired */
+#endif
+
+#ifndef ENOSR
+#define ENOSR 63 /* Out of streams resources */
+#endif
+
+#ifndef ENONET
+#define ENONET 64 /* Machine is not on the network */
+#endif
+
+#ifndef ENOPKG
+#define ENOPKG 65 /* Package not installed */
+#endif
+
+#ifndef EREMOTE
+#define EREMOTE 66 /* Object is remote */
+#endif
+
+#ifndef ENOLINK
+#define ENOLINK 67 /* Link has been severed */
+#endif
+
+#ifndef EADV
+#define EADV 68 /* Advertise error */
+#endif
+
+#ifndef ESRMNT
+#define ESRMNT 69 /* Srmount error */
+#endif
+
+#ifndef ECOMM
+#define ECOMM 70 /* Communication error on send */
+#endif
+
+#ifndef EPROTO
+#define EPROTO 71 /* Protocol error */
+#endif
+
+#ifndef EMULTIHOP
+#define EMULTIHOP 72 /* Multihop attempted */
+#endif
+
+#ifndef EDOTDOT
+#define EDOTDOT 73 /* RFS specific error */
+#endif
+
+#ifndef EBADMSG
+#define EBADMSG 74 /* Not a data message */
+#endif
+
+#ifndef EOVERFLOW
+#define EOVERFLOW 75 /* Value too large for defined data type */
+#endif
+
+#ifndef ENOTUNIQ
+#define ENOTUNIQ 76 /* Name not unique on network */
+#endif
+
+#ifndef EBADFD
+#define EBADFD 77 /* File descriptor in bad state */
+#endif
+
+#ifndef EREMCHG
+#define EREMCHG 78 /* Remote address changed */
+#endif
+
+#ifndef ELIBACC
+#define ELIBACC 79 /* Can not access a needed shared library */
+#endif
+
+#ifndef ELIBBAD
+#define ELIBBAD 80 /* Accessing a corrupted shared library */
+#endif
+
+#ifndef ELIBSCN
+#define ELIBSCN 81 /* .lib section in a.out corrupted */
+#endif
+
+#ifndef ELIBMAX
+#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
+#endif
+
+#ifndef ELIBEXEC
+#define ELIBEXEC 83 /* Cannot exec a shared library directly */
+#endif
+
+#ifndef EILSEQ
+#define EILSEQ 84 /* Illegal byte sequence */
+#endif
+
+#ifndef ERESTART
+#define ERESTART 85 /* Interrupted system call should be restarted */
+#endif
+
+#ifndef ESTRPIPE
+#define ESTRPIPE 86 /* Streams pipe error */
+#endif
+
+#ifndef EUSERS
+#define EUSERS 87 /* Too many users */
+#endif
+
+#ifndef ENOTSOCK
+#define ENOTSOCK 88 /* Socket operation on non-socket */
+#endif
+
+#ifndef EDESTADDRREQ
+#define EDESTADDRREQ 89 /* Destination address required */
+#endif
+
+#ifndef EMSGSIZE
+#define EMSGSIZE 90 /* Message too long */
+#endif
+
+#ifndef EPROTOTYPE
+#define EPROTOTYPE 91 /* Protocol wrong type for socket */
+#endif
+
+#ifndef ENOPROTOOPT
+#define ENOPROTOOPT 92 /* Protocol not available */
+#endif
+
+#ifndef EPROTONOSUPPORT
+#define EPROTONOSUPPORT 93 /* Protocol not supported */
+#endif
+
+#ifndef ESOCKTNOSUPPORT
+#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
+#endif
+
+#ifndef EOPNOTSUPP
+#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
+#endif
+
+#ifndef EPFNOSUPPORT
+#define EPFNOSUPPORT 96 /* Protocol family not supported */
+#endif
+
+#ifndef EAFNOSUPPORT
+#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
+#endif
+
+#ifndef EADDRINUSE
+#define EADDRINUSE 98 /* Address already in use */
+#endif
+
+#ifndef EADDRNOTAVAIL
+#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
+#endif
+
+#ifndef ENETDOWN
+#define ENETDOWN 100 /* Network is down */
+#endif
+
+#ifndef ENETUNREACH
+#define ENETUNREACH 101 /* Network is unreachable */
+#endif
+
+#ifndef ENETRESET
+#define ENETRESET 102 /* Network dropped connection because of reset */
+#endif
+
+#ifndef ECONNABORTED
+#define ECONNABORTED 103 /* Software caused connection abort */
+#endif
+
+#ifndef ECONNRESET
+#define ECONNRESET 104 /* Connection reset by peer */
+#endif
+
+#ifndef ENOBUFS
+#define ENOBUFS 105 /* No buffer space available */
+#endif
+
+#ifndef EISCONN
+#define EISCONN 106 /* Transport endpoint is already connected */
+#endif
+
+#ifndef ENOTCONN
+#define ENOTCONN 107 /* Transport endpoint is not connected */
+#endif
+
+#ifndef ESHUTDOWN
+#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
+#endif
+
+#ifndef ETOOMANYREFS
+#define ETOOMANYREFS 109 /* Too many references: cannot splice */
+#endif
+
+#ifndef ETIMEDOUT
+#define ETIMEDOUT 110 /* Connection timed out */
+#endif
+
+#ifndef ECONNREFUSED
+#define ECONNREFUSED 111 /* Connection refused */
+#endif
+
+#ifndef EHOSTDOWN
+#define EHOSTDOWN 112 /* Host is down */
+#endif
+
+#ifndef EHOSTUNREACH
+#define EHOSTUNREACH 113 /* No route to host */
+#endif
+
+#ifndef EALREADY
+#define EALREADY 114 /* Operation already in progress */
+#endif
+
+#ifndef EINPROGRESS
+#define EINPROGRESS 115 /* Operation now in progress */
+#endif
+
+#ifndef ESTALE
+#define ESTALE 116 /* Stale NFS file handle */
+#endif
+
+#ifndef EUCLEAN
+#define EUCLEAN 117 /* Structure needs cleaning */
+#endif
+
+#ifndef ENOTNAM
+#define ENOTNAM 118 /* Not a XENIX named type file */
+#endif
+
+#ifndef ENAVAIL
+#define ENAVAIL 119 /* No XENIX semaphores available */
+#endif
+
+#ifndef EISNAM
+#define EISNAM 120 /* Is a named type file */
+#endif
+
+#ifndef EREMOTEIO
+#define EREMOTEIO 121 /* Remote I/O error */
+#endif
+
+#ifndef EDQUOT
+#define EDQUOT 122 /* Quota exceeded */
+#endif
+
+#ifndef ENOMEDIUM
+#define ENOMEDIUM 123 /* No medium found */
+#endif
+
+#ifndef EMEDIUMTYPE
+#define EMEDIUMTYPE 124 /* Wrong medium type */
+#endif
+
+#ifndef ECANCELED
+#define ECANCELED 125 /* Operation Cancelled */
+#endif
+
+#ifndef ENOKEY
+#define ENOKEY 126 /* Required key not available */
+#endif
+
+#ifndef EKEYEXPIRED
+#define EKEYEXPIRED 127 /* Key has expired */
+#endif
+
+#ifndef EKEYREVOKED
+#define EKEYREVOKED 128 /* Key has been revoked */
+#endif
+
+#ifndef EKEYREJECTED
+#define EKEYREJECTED 129 /* Key was rejected by service */
+#endif
+
+#ifndef MAX_ERRNO
+#define MAX_ERRNO 4095
+#endif
+
+#define IS_ERR_VALUE(x) ((x) >= (size_t)-MAX_ERRNO)
+
+static __inline void* ERR_PTR(ssize_t error)
+{
+ return (void *)error;
+}
+
+static __inline size_t PTR_ERR(const void *ptr)
+{
+ return (size_t)ptr;
+}
+
+static __inline size_t IS_ERR(const void *ptr)
+{
+ return IS_ERR_VALUE((size_t)ptr);
+}
+
+#define FOLL_NOWAIT 0
+#define FOLL_HWPOISON 0
+#define FOLL_WRITE 0
+#define FOLL_TOUCH 0
+#define FOLL_NOWAIT 0
+
+#define VM_READ
+
+#define down_read(a)
+#define up_read(a)
+
+#define WRITE_ONCE(a, b) \
+do { \
+ _ReadWriteBarrier(); \
+ a = b; \
+} while(0)
+#define ACCESS_ONCE(a, b) \
+do { \
+ _ReadWriteBarrier(); \
+ b = a; \
+} while(0)
+#define READ_ONCE(a, b) ACCESS_ONCE(a, b)
+
+#define WARN_ON(a) 0
+
+#define PIDTYPE_PID 0
+
+#define NOTIFY_OK 0
+
+#define atomic_set(a, b) WRITE_ONCE(*a, b)
+
+#define XSAVE_HDR_SIZE 0
+#define XSAVE_HDR_OFFSET 0x10
+#define XFEATURE_MASK_EXTEND 0x0
+
+#define might_sleep() 0
+
+// visual c compiler does not support branch hint
+#define likely(a) a
+#define unlikely(a) a
+
+#define kvm_pmu_refresh(a) 0
+#define printk DbgPrint
+#define pr_info_ratelimited DbgPrint
+#define printk_ratelimited DbgPrint
+#define printk_once DbgPrint
+#define kdprint DbgPrint
+#define pr_info DbgPrint
+#define pr_warn_once DbgPrint
+
+// cpuid.c
+enum cpuid_leafs
+{
+ CPUID_1_EDX = 0,
+ CPUID_8000_0001_EDX,
+ CPUID_8086_0001_EDX,
+ CPUID_LNX_1,
+ CPUID_1_ECX,
+ CPUID_C000_0001_EDX,
+ CPUID_8000_0001_ECX,
+ CPUID_LNX_2,
+ CPUID_LNX_3,
+ CPUID_7_0_EBX,
+ CPUID_D_1_EAX,
+ CPUID_F_0_EDX,
+ CPUID_F_1_EDX,
+ CPUID_8000_0008_EBX,
+ CPUID_6_EAX,
+ CPUID_8000_000A_EDX,
+ CPUID_7_ECX,
+ CPUID_8000_0007_EBX,
+};
+
+extern int CPU_HAS_X86_FEATURE_XSAVE;
+extern int CPU_HAS_X86_FEATURE_PKU;
+extern int CPU_HAS_X86_FEATURE_GBPAGES;
+extern int CPU_HAS_X86_FEATURE_HLE;
+extern int CPU_HAS_X86_FEATURE_RTM;
+extern int CPU_HAS_X86_FEATURE_NX;
+extern int CPU_HAS_X86_FEATURE_FXSR_OPT;
+extern int CPU_HAS_X86_FEATURE_NPT;
+extern int CPU_HAS_X86_FEATURE_AVIC;
+extern int CPU_HAS_X86_FEATURE_DECODEASSISTS;
+extern int CPU_HAS_X86_FEATURE_RDTSCP;
+extern int CPU_HAS_X86_FEATURE_LBRV;
+extern int CPU_HAS_X86_FEATURE_NRIPS;
+extern int CPU_HAS_X86_FEATURE_SMEP;
+extern int CPU_HAS_X86_FEATURE_MPX;
+extern int CPU_HAS_X86_FEATURE_XSAVES;
+extern int CPU_HAS_X86_FEATURE_CONSTANT_TSC;
+extern int CPU_HAS_X86_BUG_AMD_TLB_MMATCH;
+extern int CPU_HAS_X86_FEATURE_FLUSHBYASID;
+extern int CPU_HAS_X86_FEATURE_OSVW;
+extern int CPU_HAS_X86_FEATURE_SVM;
+
+#define cpu_has(notused, feature) (CPU_HAS_##feature)
+#define boot_cpu_has(feature) (CPU_HAS_##feature)
+#define static_cpu_has(feature) (CPU_HAS_##feature)
+
+#define WARN_ON_ONCE(a) 0
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
+
+#define __min_t_func_type(a) \
+static __inline a __##a##_min(a b, a c) \
+{ \
+ return (b < c) ? b : c; \
+}
+
+__min_t_func_type(unsigned)
+__min_t_func_type(u64)
+__min_t_func_type(u32)
+__min_t_func_type(int)
+
+#define min_t(a, b, c) __##a##_min((b), (c))
+
+#define offset_in_page(p) ((size_t)(p) & ~PAGE_MASK)
+// Let's borrow MS's HYPERVISOR_ERR here
+#define BUG() KeBugCheck(0x00020001)
+#define BUG_ON(cond) do { if (cond) BUG();} while (0)
+#define volatile
+
+#define min3(a, b, c) min(min(a, b),c)
+
+#pragma pack(push, 1)
+struct desc_ptr {
+ unsigned short size;
+ size_t address;
+};
+#pragma pack(pop)
+
+/*
+ * Bottom two bits of selector give the ring
+ * privilege level
+ */
+#define SEGMENT_RPL_MASK 0x3
+
+/* User mode is privilege level 3: */
+#define USER_RPL 0x3
+
+/* Bit 2 is Table Indicator (TI): selects between LDT or GDT */
+#define SEGMENT_TI_MASK 0x4
+/* LDT segment has TI set ... */
+#define SEGMENT_LDT 0x4
+/* ... GDT has it cleared */
+#define SEGMENT_GDT 0x0
+
+#define GDT_ENTRY_INVALID_SEG 0
+
+#define swab16 RtlUshortByteSwap
+#define swab32 RtlUlongByteSwap
+#define swab64 RtlUlonglongByteSwap
+
+#define container_of CONTAINING_RECORD
+#define KERN_WARNING
+#define KERN_INFO
+#define KERN_ERR
+#define KERN_CRIT
+#define KERN_DEBUG
+
+// Bitmaps
+#define BITS_TO_LONGS(bits) (bits + BITS_PER_LONG - 1)/BITS_PER_LONG
+#define DECLARE_BITMAP(name, bits) \
+ size_t name[BITS_TO_LONGS(bits)]
+
+#define BITMAP_FIRST_WORD_MASK(start) (~(size_t)0 << ((start) & (BITS_PER_LONG - 1)))
+#define BITMAP_LAST_WORD_MASK(nbits) (~(size_t)0 >> (-((ssize_t)nbits) & (BITS_PER_LONG - 1)))
+
+#define small_const_nbits(nbits) \
+ ((nbits) <= BITS_PER_LONG)
+
+static __inline int __bitmap_and(size_t *dst, const size_t *bitmap1,
+ const size_t *bitmap2, unsigned int bits)
+{
+ unsigned int k;
+ unsigned int lim = bits / BITS_PER_LONG;
+ size_t result = 0;
+
+ for (k = 0; k < lim; k++)
+ result |= (dst[k] = bitmap1[k] & bitmap2[k]);
+ if (bits % BITS_PER_LONG)
+ result |= (dst[k] = bitmap1[k] & bitmap2[k] &
+ BITMAP_LAST_WORD_MASK(bits));
+ return result != 0;
+}
+
+static __inline void __bitmap_or(size_t *dst, const size_t *bitmap1,
+ const size_t *bitmap2, unsigned int bits)
+{
+ unsigned int k;
+ unsigned int nr = BITS_TO_LONGS(bits);
+
+ for (k = 0; k < nr; k++)
+ dst[k] = bitmap1[k] | bitmap2[k];
+}
+
+static __inline void __bitmap_xor(size_t *dst, const size_t *bitmap1,
+ const size_t *bitmap2, unsigned int bits)
+{
+ unsigned int k;
+ unsigned int nr = BITS_TO_LONGS(bits);
+
+ for (k = 0; k < nr; k++)
+ dst[k] = bitmap1[k] ^ bitmap2[k];
+}
+
+static __inline int __bitmap_andnot(size_t *dst, const size_t *bitmap1,
+ const size_t *bitmap2, unsigned int bits)
+{
+ unsigned int k;
+ unsigned int lim = bits / BITS_PER_LONG;
+ size_t result = 0;
+
+ for (k = 0; k < lim; k++)
+ result |= (dst[k] = bitmap1[k] & ~bitmap2[k]);
+ if (bits % BITS_PER_LONG)
+ result |= (dst[k] = bitmap1[k] & ~bitmap2[k] &
+ BITMAP_LAST_WORD_MASK(bits));
+ return result != 0;
+}
+
+static __inline void __bitmap_complement(size_t *dst, const size_t *src, unsigned int bits)
+{
+ unsigned int k, lim = bits / BITS_PER_LONG;
+ for (k = 0; k < lim; ++k)
+ dst[k] = ~src[k];
+
+ if (bits % BITS_PER_LONG)
+ dst[k] = ~src[k];
+}
+
+static __inline void bitmap_zero(size_t *dst, unsigned int nbits)
+{
+ if (small_const_nbits(nbits))
+ *dst = 0UL;
+ else {
+ unsigned int len = BITS_TO_LONGS(nbits) * sizeof(size_t);
+ memset(dst, 0, len);
+ }
+}
+
+static __inline void bitmap_copy(size_t *dst, const size_t *src,
+ unsigned int nbits)
+{
+ if (small_const_nbits(nbits))
+ *dst = *src;
+ else {
+ unsigned int len = BITS_TO_LONGS(nbits) * sizeof(size_t);
+ memcpy(dst, src, len);
+ }
+}
+
+static __inline int bitmap_and(size_t *dst, const size_t *src1,
+ const size_t *src2, unsigned int nbits)
+{
+ if (small_const_nbits(nbits))
+ return (*dst = *src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)) != 0;
+ return __bitmap_and(dst, src1, src2, nbits);
+}
+
+static __inline void bitmap_or(size_t *dst, const size_t *src1,
+ const size_t *src2, unsigned int nbits)
+{
+ if (small_const_nbits(nbits))
+ *dst = *src1 | *src2;
+ else
+ __bitmap_or(dst, src1, src2, nbits);
+}
+
+static __inline void bitmap_xor(size_t *dst, const size_t *src1,
+ const size_t *src2, unsigned int nbits)
+{
+ if (small_const_nbits(nbits))
+ *dst = *src1 ^ *src2;
+ else
+ __bitmap_xor(dst, src1, src2, nbits);
+}
+
+static __inline int bitmap_andnot(size_t *dst, const size_t *src1,
+ const size_t *src2, unsigned int nbits)
+{
+ if (small_const_nbits(nbits))
+ return (*dst = *src1 & ~(*src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
+ return __bitmap_andnot(dst, src1, src2, nbits);
+}
+
+static inline void bitmap_complement(size_t *dst, const size_t *src,
+ unsigned int nbits)
+{
+ if (small_const_nbits(nbits))
+ *dst = ~(*src);
+ else
+ __bitmap_complement(dst, src, nbits);
+}
+
+// Bitwise operations
+#ifdef _WIN64
+// Non-atomic
+static __forceinline bool __test_and_set_bit(size_t pos, volatile size_t *bitmap)
+{
+ return _bittestandset64((LONG64 *)bitmap, (LONG64)pos);
+}
+
+// Non-atomic
+static __forceinline bool __test_and_clear_bit(size_t pos, volatile size_t *bitmap)
+{
+ return _bittestandreset64((LONG64 *)bitmap, (LONG64)pos);
+}
+
+// Atomic
+static __forceinline bool test_and_set_bit(size_t pos, volatile size_t *bitmap)
+{
+ return _interlockedbittestandset64((LONG64 *)bitmap, (LONG64)pos);
+}
+
+// Atomic
+static __forceinline bool test_and_clear_bit(size_t pos, volatile size_t *bitmap)
+{
+ return _interlockedbittestandreset64((LONG64 *)bitmap, (LONG64)pos);
+}
+
+// Non-atomic
+static __forceinline void __set_bit(size_t nr, volatile size_t *addr)
+{
+ _bittestandset64((LONG64 *)addr, (LONG64)nr);
+}
+
+// Non-atomic
+static __forceinline void __clear_bit(size_t nr, volatile size_t *addr)
+{
+ _bittestandreset64((LONG64 *)addr, (LONG64)nr);
+}
+
+// Atomic
+static __forceinline void set_bit(size_t nr, volatile size_t *addr)
+{
+ _interlockedbittestandset64((LONG64 *)addr, (LONG64)nr);
+}
+
+// Atomic
+static __forceinline void clear_bit(size_t nr, volatile size_t *addr)
+{
+ _interlockedbittestandreset64((LONG64 *)addr, (LONG64)nr);
+}
+
+static __forceinline unsigned char test_bit(size_t nr, volatile size_t *addr)
+{
+ return _bittest64((LONG64 *)addr, (LONG64)nr);
+}
+#else
+// Non-atomic
+static __forceinline bool __test_and_set_bit(size_t pos, volatile size_t *bitmap)
+{
+ return _bittestandset((LONG *)bitmap, (LONG)pos);
+}
+
+// Non-atomic
+static __forceinline bool __test_and_clear_bit(size_t pos, volatile size_t *bitmap)
+{
+ return _bittestandreset((LONG *)bitmap, (LONG)pos);
+}
+
+// Atomic
+static __forceinline bool test_and_set_bit(size_t pos, volatile size_t *bitmap)
+{
+ return _interlockedbittestandset((LONG *)bitmap, (LONG)pos);
+}
+
+// Atomic
+static __forceinline bool test_and_clear_bit(size_t pos, volatile size_t *bitmap)
+{
+ return _interlockedbittestandreset((LONG *)bitmap, (LONG)pos);
+}
+
+// Non-atomic
+static __forceinline void __set_bit(size_t nr, volatile size_t *addr)
+{
+ _bittestandset((LONG *)addr, (LONG)nr);
+}
+
+// Non-atomic
+static __forceinline void __clear_bit(size_t nr, volatile size_t *addr)
+{
+ _bittestandreset((LONG *)addr, (LONG)nr);
+}
+
+// Atomic
+static __forceinline void set_bit(size_t nr, volatile size_t *addr)
+{
+ _interlockedbittestandset((LONG *)addr, (LONG)nr);
+}
+
+// Atomic
+static __forceinline void clear_bit(size_t nr, volatile size_t *addr)
+{
+ _interlockedbittestandreset((LONG *)addr, (LONG)nr);
+}
+
+static __forceinline unsigned char test_bit(size_t nr, volatile size_t *addr)
+{
+ return _bittest((LONG *)addr, (LONG)nr);
+}
+#endif
+
+#ifdef _WIN64
+static __forceinline size_t __ffs(size_t mask)
+{
+ unsigned long pos;
+ _BitScanForward64(&pos, mask);
+ return pos;
+}
+
+static __forceinline size_t __fls(size_t mask)
+{
+ unsigned long pos;
+ _BitScanReverse64(&pos, mask);
+ return pos;
+}
+#else
+static __forceinline size_t __ffs(size_t mask)
+{
+ unsigned long pos;
+ _BitScanForward(&pos, mask);
+ return pos;
+}
+
+static __forceinline size_t __fls(size_t mask)
+{
+ unsigned long pos;
+ _BitScanReverse(&pos, mask);
+ return pos;
+}
+#endif
+
+
+// Note the difference of linux kernel ffs with BitScanForward
+static __forceinline unsigned int ffs(int x)
+{
+ unsigned long pos;
+ unsigned char ret = _BitScanForward(&pos, x);
+ return ret ? pos + 1 : ret;
+}
+
+static __forceinline size_t ffz(size_t x)
+{
+ return __ffs(~x);
+}
+
+static __forceinline unsigned int fls(int x)
+{
+ unsigned long pos;
+ unsigned char ret = _BitScanReverse(&pos, x);
+ return ret ? pos + 1 : ret;
+}
+
+#ifdef _WIN64
+static __forceinline int fls64(size_t x)
+{
+ unsigned long pos;
+ unsigned char ret = _BitScanReverse64(&pos, x);
+ return ret ? pos + 1 : ret;
+}
+#else
+static __forceinline int fls64(__u64 x)
+{
+ __u32 h = x >> 32;
+ if (h)
+ return fls(h) + 32;
+ return fls(x);
+}
+#endif
+
+static __forceinline u64 do_div(u64 *n, u64 base)
+{
+ u64 rem = (*n) % base;
+ *n = (*n) / base;
+
+ return rem;
+}
+
+#ifdef _WIN64
+static __inline uint64_t div64_u64(uint64_t dividend, uint64_t divisor)
+{
+ return dividend / divisor;
+}
+#else
+static __inline uint64_t div64_u64(uint64_t dividend, uint64_t divisor)
+{
+ uint32_t high, d;
+
+ high = divisor >> 32;
+ if (high)
+ {
+ unsigned int shift = __fls(high);
+
+ d = divisor >> shift;
+ dividend >>= shift;
+ }
+ else
+ {
+ d = divisor;
+ }
+
+ do_div(dividend, d);
+
+ return dividend;
+}
+#endif
+
+#define __read_mostly
+
+#define HZ 100
+
+#define module_param_named(a, b, c, d) 0
+#define module_param(a, b, c) 0
+
+#define GDT_ENTRY_TSS 8
+
+#define _PAGE_BIT_PRESENT 0 /* is present */
+#define _PAGE_BIT_RW 1 /* writeable */
+#define _PAGE_BIT_USER 2 /* userspace addressable */
+#define _PAGE_BIT_PWT 3 /* page write through */
+#define _PAGE_BIT_PCD 4 /* page cache disabled */
+#define _PAGE_BIT_ACCESSED 5 /* was accessed (raised by CPU) */
+#define _PAGE_BIT_DIRTY 6 /* was written to (raised by CPU) */
+#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */
+#define _PAGE_BIT_PAT 7 /* on 4KB pages */
+#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */
+#define _PAGE_BIT_SOFTW1 9 /* available for programmer */
+#define _PAGE_BIT_SOFTW2 10 /* " */
+#define _PAGE_BIT_SOFTW3 11 /* " */
+#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
+#define _PAGE_BIT_SOFTW4 58 /* available for programmer */
+#define _PAGE_BIT_PKEY_BIT0 59 /* Protection Keys, bit 1/4 */
+#define _PAGE_BIT_PKEY_BIT1 60 /* Protection Keys, bit 2/4 */
+#define _PAGE_BIT_PKEY_BIT2 61 /* Protection Keys, bit 3/4 */
+#define _PAGE_BIT_PKEY_BIT3 62 /* Protection Keys, bit 4/4 */
+#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
+
+#define _PAGE_BIT_SPECIAL _PAGE_BIT_SOFTW1
+#define _PAGE_BIT_CPA_TEST _PAGE_BIT_SOFTW1
+#define _PAGE_BIT_HIDDEN _PAGE_BIT_SOFTW3 /* hidden by kmemcheck */
+#define _PAGE_BIT_SOFT_DIRTY _PAGE_BIT_SOFTW3 /* software dirty tracking */
+#define _PAGE_BIT_DEVMAP _PAGE_BIT_SOFTW4
+
+/* If _PAGE_BIT_PRESENT is clear, we use these: */
+/* - if the user mapped it with PROT_NONE; pte_present gives true */
+#define _PAGE_BIT_PROTNONE _PAGE_BIT_GLOBAL
+
+#define _AT(x, y) y
+
+#define _PAGE_PRESENT (_AT(pteval_t, 1) << _PAGE_BIT_PRESENT)
+#define _PAGE_RW (_AT(pteval_t, 1) << _PAGE_BIT_RW)
+#define _PAGE_USER (_AT(pteval_t, 1) << _PAGE_BIT_USER)
+#define _PAGE_PWT (_AT(pteval_t, 1) << _PAGE_BIT_PWT)
+#define _PAGE_PCD (_AT(pteval_t, 1) << _PAGE_BIT_PCD)
+#define _PAGE_ACCESSED (_AT(pteval_t, 1) << _PAGE_BIT_ACCESSED)
+#define _PAGE_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)
+#define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE)
+#define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
+#define _PAGE_SOFTW1 (_AT(pteval_t, 1) << _PAGE_BIT_SOFTW1)
+#define _PAGE_SOFTW2 (_AT(pteval_t, 1) << _PAGE_BIT_SOFTW2)
+#define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT)
+#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
+#define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL)
+#define _PAGE_CPA_TEST (_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST)
+
+#define NMI_VECTOR 2
+
+#define pr_err_ratelimited DbgPrint
+#define pr_err DbgPrint
+#define pr_debug DbgPrint
+
+//TODO:IOW/R
+#define FILE_DEVICE_GVM 0xE3E3
+#define _IO(a, b) CTL_CODE(FILE_DEVICE_GVM,b,METHOD_BUFFERED,FILE_ANY_ACCESS)
+#define _IOR(a, b, c) CTL_CODE(FILE_DEVICE_GVM,b,METHOD_BUFFERED,FILE_ANY_ACCESS)
+#define _IOW(a, b, c) CTL_CODE(FILE_DEVICE_GVM,b,METHOD_BUFFERED,FILE_ANY_ACCESS)
+#define _IOWR(a, b, c) CTL_CODE(FILE_DEVICE_GVM,b,METHOD_BUFFERED,FILE_ANY_ACCESS)
+
+// bit maps
+
+/*
+* This looks more complex than it should be. But we need to
+* get the type for the ~ right in round_down (it needs to be
+* as wide as the result!), and we want to evaluate the macro
+* arguments just once each.
+*/
+#define __round_mask(x, y) ((size_t)((y)-1))
+#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
+#define round_down(x, y) ((x) & ~__round_mask(x, y))
+
+/*
+* This is a common helper function for find_next_bit and
+* find_next_zero_bit. The difference is the "invert" argument, which
+* is XORed with each fetched word before searching it for one bits.
+*/
+
+static size_t _find_next_bit(const size_t *addr,
+ size_t nbits, size_t start, size_t invert)
+{
+ size_t tmp;
+
+ if (!nbits || start >= nbits)
+ return nbits;
+
+ tmp = addr[start / BITS_PER_LONG] ^ invert;
+
+ /* Handle 1st word. */
+ tmp &= BITMAP_FIRST_WORD_MASK(start);
+ start = round_down(start, BITS_PER_LONG);
+
+ while (!tmp) {
+ start += BITS_PER_LONG;
+ if (start >= nbits)
+ return nbits;
+
+ tmp = addr[start / BITS_PER_LONG] ^ invert;
+ }
+
+ return min(start + __ffs(tmp), nbits);
+}
+
+static size_t find_next_bit(const size_t *addr, size_t size, size_t offset)
+{
+ return _find_next_bit(addr, size, offset, (size_t)0);
+}
+
+static size_t find_next_zero_bit(const size_t *addr, size_t size, size_t offset)
+{
+ return _find_next_bit(addr, size, offset, ~(size_t)0);
+}
+/*
+* Find the first zero bit in a memory region
+*/
+static size_t find_first_zero_bit(const size_t *addr, size_t size)
+{
+ size_t idx;
+
+ for (idx = 0; idx * BITS_PER_LONG < size; idx++) {
+ if (addr[idx] != ~0UL)
+ return min(idx * BITS_PER_LONG + ffz(addr[idx]), size);
+ }
+
+ return size;
+}
+
+/*
+* Find the first set bit in a memory region.
+*/
+static __inline size_t find_first_bit(const size_t *addr, size_t size)
+{
+ size_t idx;
+
+ for (idx = 0; idx * BITS_PER_LONG < size; idx++) {
+ if (addr[idx])
+ return min(idx * BITS_PER_LONG + __ffs(addr[idx]), size);
+ }
+
+ return size;
+}
+
+#define for_each_set_bit(bit, addr, size) \
+ for ((bit) = find_first_bit((addr), (size)); \
+ (bit) < (size); \
+ (bit) = find_next_bit((addr), (size), (bit) + 1))
+
+#define REPEAT_BYTE(x) ((~0ull / 0xff) * (x))
+
+//cpumask
+#define NR_CPUS 512
+struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); };
+typedef struct cpumask cpumask_t;
+typedef struct cpumask *cpumask_var_t;
+#define cpumask_bits(maskp) (&((maskp)->bits[0]))
+
+static inline unsigned int cpumask_check(unsigned int cpu)
+{
+ return cpu;
+}
+
+static __inline void cpumask_set_cpu(unsigned int cpu, struct cpumask *dstp)
+{
+ set_bit(cpumask_check(cpu), cpumask_bits(dstp));
+}
+
+static __inline void cpumask_clear_cpu(int cpu, struct cpumask *dstp)
+{
+ clear_bit(cpumask_check(cpu), cpumask_bits(dstp));
+}
+
+static __inline void cpumask_clear(struct cpumask *dstp)
+{
+ memset(dstp->bits, 0, NR_CPUS / 8);
+}
+
+static __inline unsigned char cpumask_test_cpu(int cpu, struct cpumask *dstp)
+{
+ return test_bit(cpumask_check(cpu), cpumask_bits(dstp));
+}
+
+static inline bool cpumask_empty(const struct cpumask *srcp)
+{
+ return find_first_bit(cpumask_bits(srcp), MAX_CPU_NUMBERS)
+ == MAX_CPU_NUMBERS;
+}
+
+static _forceinline unsigned int cpumask_next(int n, const struct cpumask *srcp)
+{
+ return (unsigned int)_find_next_bit(cpumask_bits(srcp), MAX_CPU_NUMBERS, n+1, 0);
+}
+
+/**
+* for_each_cpu - iterate over every cpu in a mask
+* @cpu: the (optionally unsigned) integer iterator
+* @mask: the cpumask pointer
+*
+* After the loop, cpu is >= nr_cpu_ids.
+*/
+#define for_each_cpu(cpu, mask) \
+ for ((cpu) = -1; \
+ (cpu) = cpumask_next((cpu), (mask)), \
+ (cpu) < MAX_CPU_NUMBERS;)
+
+#define for_each_online_cpu(cpu) \
+ for_each_cpu(cpu, cpu_online_mask)
+
+#define for_each_possible_cpu(cpu) \
+ for_each_cpu(cpu, cpu_online_mask)
+
+#define VM_FAULT_SIGBUS 0x0002
+
+/*
+* Defines x86 CPU feature bits
+*/
+#define NCAPINTS 18 /* N 32-bit words worth of info */
+#define NBUGINTS 1 /* N 32-bit bug flags */
+
+/*
+* CPU type and hardware bug flags. Kept separately for each CPU.
+* Members of this structure are referenced in head.S, so think twice
+* before touching them. [mj]
+*/
+
+struct cpuinfo_x86 {
+ __u8 x86; /* CPU family */
+ __u8 x86_vendor; /* CPU vendor */
+ __u8 x86_model;
+ __u8 x86_mask;
+#ifdef CONFIG_X86_32
+ char wp_works_ok; /* It doesn't on 386's */
+
+ /* Problems on some 486Dx4's and old 386's: */
+ char rfu;
+ char pad0;
+ char pad1;
+#else
+ /* Number of 4K pages in DTLB/ITLB combined(in pages): */
+ int x86_tlbsize;
+#endif
+ __u8 x86_virt_bits;
+ __u8 x86_phys_bits;
+ /* CPUID returned core id bits: */
+ __u8 x86_coreid_bits;
+ /* Max extended CPUID function supported: */
+ __u32 extended_cpuid_level;
+ /* Maximum supported CPUID level, -1=no CPUID: */
+ int cpuid_level;
+ __u32 x86_capability[NCAPINTS + NBUGINTS];
+ char x86_vendor_id[16];
+ char x86_model_id[64];
+ /* in KB - valid for CPUS which support this call: */
+ int x86_cache_size;
+ int x86_cache_alignment; /* In bytes */
+ /* Cache QoS architectural values: */
+ int x86_cache_max_rmid; /* max index */
+ int x86_cache_occ_scale; /* scale to bytes */
+ int x86_power;
+ unsigned long loops_per_jiffy;
+ /* cpuid returned max cores value: */
+ u16 x86_max_cores;
+ u16 apicid;
+ u16 initial_apicid;
+ u16 x86_clflush_size;
+ /* number of cores as seen by the OS: */
+ u16 booted_cores;
+ /* Physical processor id: */
+ u16 phys_proc_id;
+ /* Logical processor id: */
+ u16 logical_proc_id;
+ /* Core id: */
+ u16 cpu_core_id;
+ /* Index into per_cpu list: */
+ u16 cpu_index;
+ u32 microcode;
+};
+
+extern struct cpuinfo_x86 boot_cpu_data;
+
+#pragma warning(disable : 4214)
+/* 16byte gate */
+#pragma pack(push, 1)
+struct gate_struct64 {
+ u16 offset_low;
+ u16 segment;
+ u16 ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
+ u16 offset_middle;
+ u32 offset_high;
+ u32 zero1;
+};
+#pragma pack(pop)
+#ifdef CONFIG_X86_64
+typedef struct gate_struct64 gate_desc;
+#define gate_offset(g) ((g).offset_low | ((size_t)(g).offset_middle << 16) | ((size_t)(g).offset_high << 32))
+#endif
+