-
Notifications
You must be signed in to change notification settings - Fork 12
/
uhyve-x86_64.h
129 lines (111 loc) · 3.84 KB
/
uhyve-x86_64.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#ifndef __UHYVE_CPU_H__
#define __UHYVE_CPU_H__
#define BOOT_INFO_ADDR 0x9000ULL
#ifndef _BITUL
#ifdef __ASSEMBLY__
#define _AC(X,Y) X
#define _AT(T,X) X
#else
#define __AC(X,Y) (X##Y)
#define _AC(X,Y) __AC(X,Y)
#define _AT(T,X) ((T)(X))
#endif
#define _BITUL(x) (_AC(1,UL) << (x))
#define _BITULL(x) (_AC(1,ULL) << (x))
#endif
/*
* EFLAGS bits
*/
#define X86_EFLAGS_CF 0x00000001 /* Carry Flag */
/*
* Basic CPU control in CR0
*/
#define X86_CR0_PE_BIT 0 /* Protection Enable */
#define X86_CR0_PE _BITUL(X86_CR0_PE_BIT)
#define X86_CR0_PG_BIT 31 /* Paging */
#define X86_CR0_PG _BITUL(X86_CR0_PG_BIT)
/*
* Intel CPU features in CR4
*/
#define X86_CR4_PAE_BIT 5 /* enable physical address extensions */
#define X86_CR4_PAE _BITUL(X86_CR4_PAE_BIT)
/*
* Intel long mode page directory/table entries
*/
#define X86_PDPT_P_BIT 0 /* Present */
#define X86_PDPT_P _BITUL(X86_PDPT_P_BIT)
#define X86_PDPT_RW_BIT 1 /* Writable */
#define X86_PDPT_RW _BITUL(X86_PDPT_RW_BIT)
#define X86_PDPT_PS_BIT 7 /* Page size */
#define X86_PDPT_PS _BITUL(X86_PDPT_PS_BIT)
/*
* GDT and KVM segment manipulation
*/
#define GDT_DESC_OFFSET(n) ((n) * 0x8)
#define GDT_GET_BASE(x) ( \
(((x) & 0xFF00000000000000) >> 32) | \
(((x) & 0x000000FF00000000) >> 16) | \
(((x) & 0x00000000FFFF0000) >> 16))
#define GDT_GET_LIMIT(x) (__u32)( \
(((x) & 0x000F000000000000) >> 32) | \
(((x) & 0x000000000000FFFF)))
/* Constructor for a conventional segment GDT (or LDT) entry */
/* This is a macro so it can be used in initializers */
#define GDT_ENTRY(flags, base, limit) \
((((base) & _AC(0xff000000, ULL)) << (56-24)) | \
(((flags) & _AC(0x0000f0ff, ULL)) << 40) | \
(((limit) & _AC(0x000f0000, ULL)) << (48-16)) | \
(((base) & _AC(0x00ffffff, ULL)) << 16) | \
(((limit) & _AC(0x0000ffff, ULL))))
#define GDT_GET_G(x) (__u8)(((x) & 0x0080000000000000) >> 55)
#define GDT_GET_DB(x) (__u8)(((x) & 0x0040000000000000) >> 54)
#define GDT_GET_L(x) (__u8)(((x) & 0x0020000000000000) >> 53)
#define GDT_GET_AVL(x) (__u8)(((x) & 0x0010000000000000) >> 52)
#define GDT_GET_P(x) (__u8)(((x) & 0x0000800000000000) >> 47)
#define GDT_GET_DPL(x) (__u8)(((x) & 0x0000600000000000) >> 45)
#define GDT_GET_S(x) (__u8)(((x) & 0x0000100000000000) >> 44)
#define GDT_GET_TYPE(x)(__u8)(((x) & 0x00000F0000000000) >> 40)
#define GDT_TO_KVM_SEGMENT(seg, gdt_table, sel) \
do { \
__u64 gdt_ent = gdt_table[sel]; \
seg.base = GDT_GET_BASE(gdt_ent); \
seg.limit = GDT_GET_LIMIT(gdt_ent); \
seg.selector = sel * 8; \
seg.type = GDT_GET_TYPE(gdt_ent); \
seg.present = GDT_GET_P(gdt_ent); \
seg.dpl = GDT_GET_DPL(gdt_ent); \
seg.db = GDT_GET_DB(gdt_ent); \
seg.s = GDT_GET_S(gdt_ent); \
seg.l = GDT_GET_L(gdt_ent); \
seg.g = GDT_GET_G(gdt_ent); \
seg.avl = GDT_GET_AVL(gdt_ent); \
} while (0)
typedef struct kernel_header {
uint32_t magic_number;
uint32_t version;
uint64_t base;
uint64_t limit;
uint64_t image_size;
uint64_t tls_start;
uint64_t tls_filesz;
uint64_t tls_memsz;
uint64_t current_stack_address;
uint64_t current_percore_address;
uint64_t host_logical_addr;
uint64_t boot_gtod;
uint64_t mb_info;
uint64_t cmdline;
uint64_t cmdsize;
uint32_t cpu_freq;
uint32_t boot_processor;
uint32_t cpu_online;
uint32_t possible_cpus;
uint32_t current_boot_id;
uint16_t uartport;
uint8_t single_kernel;
uint8_t uhyve;
uint8_t hcip[4];
uint8_t hcgateway[4];
uint8_t hcmask[4];
} kernel_header_t;
#endif