| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 
|---|
| 2 | /* Written 2000 by Andi Kleen */ | 
|---|
| 3 | #ifndef _ASM_X86_DESC_DEFS_H | 
|---|
| 4 | #define _ASM_X86_DESC_DEFS_H | 
|---|
| 5 |  | 
|---|
| 6 | /* | 
|---|
| 7 | * Segment descriptor structure definitions, usable from both x86_64 and i386 | 
|---|
| 8 | * archs. | 
|---|
| 9 | */ | 
|---|
| 10 |  | 
|---|
| 11 | /* | 
|---|
| 12 | * Low-level interface mapping flags/field names to bits | 
|---|
| 13 | */ | 
|---|
| 14 |  | 
|---|
| 15 | /* Flags for _DESC_S (non-system) descriptors */ | 
|---|
| 16 | #define _DESC_ACCESSED		0x0001 | 
|---|
| 17 | #define _DESC_DATA_WRITABLE	0x0002 | 
|---|
| 18 | #define _DESC_CODE_READABLE	0x0002 | 
|---|
| 19 | #define _DESC_DATA_EXPAND_DOWN	0x0004 | 
|---|
| 20 | #define _DESC_CODE_CONFORMING	0x0004 | 
|---|
| 21 | #define _DESC_CODE_EXECUTABLE	0x0008 | 
|---|
| 22 |  | 
|---|
| 23 | /* Common flags */ | 
|---|
| 24 | #define _DESC_S			0x0010 | 
|---|
| 25 | #define _DESC_DPL(dpl)		((dpl) << 5) | 
|---|
| 26 | #define _DESC_PRESENT		0x0080 | 
|---|
| 27 |  | 
|---|
| 28 | #define _DESC_LONG_CODE		0x2000 | 
|---|
| 29 | #define _DESC_DB		0x4000 | 
|---|
| 30 | #define _DESC_GRANULARITY_4K	0x8000 | 
|---|
| 31 |  | 
|---|
| 32 | /* System descriptors have a numeric "type" field instead of flags */ | 
|---|
| 33 | #define _DESC_SYSTEM(code)	(code) | 
|---|
| 34 |  | 
|---|
| 35 | /* | 
|---|
| 36 | * High-level interface mapping intended usage to low-level combinations | 
|---|
| 37 | * of flags | 
|---|
| 38 | */ | 
|---|
| 39 |  | 
|---|
| 40 | #define _DESC_DATA		(_DESC_S | _DESC_PRESENT | _DESC_ACCESSED | \ | 
|---|
| 41 | _DESC_DATA_WRITABLE) | 
|---|
| 42 | #define _DESC_CODE		(_DESC_S | _DESC_PRESENT | _DESC_ACCESSED | \ | 
|---|
| 43 | _DESC_CODE_READABLE | _DESC_CODE_EXECUTABLE) | 
|---|
| 44 |  | 
|---|
| 45 | #define DESC_DATA16		(_DESC_DATA) | 
|---|
| 46 | #define DESC_CODE16		(_DESC_CODE) | 
|---|
| 47 |  | 
|---|
| 48 | #define DESC_DATA32		(_DESC_DATA | _DESC_GRANULARITY_4K | _DESC_DB) | 
|---|
| 49 | #define DESC_DATA32_BIOS	(_DESC_DATA | _DESC_DB) | 
|---|
| 50 |  | 
|---|
| 51 | #define DESC_CODE32		(_DESC_CODE | _DESC_GRANULARITY_4K | _DESC_DB) | 
|---|
| 52 | #define DESC_CODE32_BIOS	(_DESC_CODE | _DESC_DB) | 
|---|
| 53 |  | 
|---|
| 54 | #define DESC_TSS32		(_DESC_SYSTEM(9) | _DESC_PRESENT) | 
|---|
| 55 |  | 
|---|
| 56 | #define DESC_DATA64		(_DESC_DATA | _DESC_GRANULARITY_4K | _DESC_DB) | 
|---|
| 57 | #define DESC_CODE64		(_DESC_CODE | _DESC_GRANULARITY_4K | _DESC_LONG_CODE) | 
|---|
| 58 |  | 
|---|
| 59 | #define DESC_USER		(_DESC_DPL(3)) | 
|---|
| 60 |  | 
|---|
| 61 | #ifndef __ASSEMBLER__ | 
|---|
| 62 |  | 
|---|
| 63 | #include <linux/types.h> | 
|---|
| 64 |  | 
|---|
| 65 | /* 8 byte segment descriptor */ | 
|---|
| 66 | struct desc_struct { | 
|---|
| 67 | u16	limit0; | 
|---|
| 68 | u16	base0; | 
|---|
| 69 | u16	base1: 8, type: 4, s: 1, dpl: 2, p: 1; | 
|---|
| 70 | u16	limit1: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8; | 
|---|
| 71 | } __attribute__((packed)); | 
|---|
| 72 |  | 
|---|
| 73 | #define GDT_ENTRY_INIT(flags, base, limit)			\ | 
|---|
| 74 | {							\ | 
|---|
| 75 | .limit0		= ((limit) >>  0) & 0xFFFF,	\ | 
|---|
| 76 | .limit1		= ((limit) >> 16) & 0x000F,	\ | 
|---|
| 77 | .base0		= ((base)  >>  0) & 0xFFFF,	\ | 
|---|
| 78 | .base1		= ((base)  >> 16) & 0x00FF,	\ | 
|---|
| 79 | .base2		= ((base)  >> 24) & 0x00FF,	\ | 
|---|
| 80 | .type		= ((flags) >>  0) & 0x000F,	\ | 
|---|
| 81 | .s		= ((flags) >>  4) & 0x0001,	\ | 
|---|
| 82 | .dpl		= ((flags) >>  5) & 0x0003,	\ | 
|---|
| 83 | .p		= ((flags) >>  7) & 0x0001,	\ | 
|---|
| 84 | .avl		= ((flags) >> 12) & 0x0001,	\ | 
|---|
| 85 | .l		= ((flags) >> 13) & 0x0001,	\ | 
|---|
| 86 | .d		= ((flags) >> 14) & 0x0001,	\ | 
|---|
| 87 | .g		= ((flags) >> 15) & 0x0001,	\ | 
|---|
| 88 | } | 
|---|
| 89 |  | 
|---|
| 90 | enum { | 
|---|
| 91 | GATE_INTERRUPT = 0xE, | 
|---|
| 92 | GATE_TRAP = 0xF, | 
|---|
| 93 | GATE_CALL = 0xC, | 
|---|
| 94 | GATE_TASK = 0x5, | 
|---|
| 95 | }; | 
|---|
| 96 |  | 
|---|
| 97 | enum { | 
|---|
| 98 | DESC_TSS = 0x9, | 
|---|
| 99 | DESC_LDT = 0x2, | 
|---|
| 100 | DESCTYPE_S = 0x10,	/* !system */ | 
|---|
| 101 | }; | 
|---|
| 102 |  | 
|---|
| 103 | /* LDT or TSS descriptor in the GDT. */ | 
|---|
| 104 | struct ldttss_desc { | 
|---|
| 105 | u16	limit0; | 
|---|
| 106 | u16	base0; | 
|---|
| 107 |  | 
|---|
| 108 | u16	base1 : 8, type : 5, dpl : 2, p : 1; | 
|---|
| 109 | u16	limit1 : 4, zero0 : 3, g : 1, base2 : 8; | 
|---|
| 110 | #ifdef CONFIG_X86_64 | 
|---|
| 111 | u32	base3; | 
|---|
| 112 | u32	zero1; | 
|---|
| 113 | #endif | 
|---|
| 114 | } __attribute__((packed)); | 
|---|
| 115 |  | 
|---|
| 116 | typedef struct ldttss_desc ldt_desc; | 
|---|
| 117 | typedef struct ldttss_desc tss_desc; | 
|---|
| 118 |  | 
|---|
| 119 | struct idt_bits { | 
|---|
| 120 | u16		ist	: 3, | 
|---|
| 121 | zero	: 5, | 
|---|
| 122 | type	: 5, | 
|---|
| 123 | dpl	: 2, | 
|---|
| 124 | p	: 1; | 
|---|
| 125 | } __attribute__((packed)); | 
|---|
| 126 |  | 
|---|
| 127 | struct idt_data { | 
|---|
| 128 | unsigned int	vector; | 
|---|
| 129 | unsigned int	segment; | 
|---|
| 130 | struct idt_bits	bits; | 
|---|
| 131 | const void	*addr; | 
|---|
| 132 | }; | 
|---|
| 133 |  | 
|---|
| 134 | struct gate_struct { | 
|---|
| 135 | u16		offset_low; | 
|---|
| 136 | u16		segment; | 
|---|
| 137 | struct idt_bits	bits; | 
|---|
| 138 | u16		offset_middle; | 
|---|
| 139 | #ifdef CONFIG_X86_64 | 
|---|
| 140 | u32		offset_high; | 
|---|
| 141 | u32		reserved; | 
|---|
| 142 | #endif | 
|---|
| 143 | } __attribute__((packed)); | 
|---|
| 144 |  | 
|---|
| 145 | typedef struct gate_struct gate_desc; | 
|---|
| 146 |  | 
|---|
| 147 | #ifndef _SETUP | 
|---|
| 148 | static inline unsigned long gate_offset(const gate_desc *g) | 
|---|
| 149 | { | 
|---|
| 150 | #ifdef CONFIG_X86_64 | 
|---|
| 151 | return g->offset_low | ((unsigned long)g->offset_middle << 16) | | 
|---|
| 152 | ((unsigned long) g->offset_high << 32); | 
|---|
| 153 | #else | 
|---|
| 154 | return g->offset_low | ((unsigned long)g->offset_middle << 16); | 
|---|
| 155 | #endif | 
|---|
| 156 | } | 
|---|
| 157 |  | 
|---|
| 158 | static inline unsigned long gate_segment(const gate_desc *g) | 
|---|
| 159 | { | 
|---|
| 160 | return g->segment; | 
|---|
| 161 | } | 
|---|
| 162 | #endif | 
|---|
| 163 |  | 
|---|
| 164 | struct desc_ptr { | 
|---|
| 165 | unsigned short size; | 
|---|
| 166 | unsigned long address; | 
|---|
| 167 | } __attribute__((packed)) ; | 
|---|
| 168 |  | 
|---|
| 169 | #endif /* !__ASSEMBLER__ */ | 
|---|
| 170 |  | 
|---|
| 171 | /* Boot IDT definitions */ | 
|---|
| 172 | #define	BOOT_IDT_ENTRIES	32 | 
|---|
| 173 |  | 
|---|
| 174 | /* Access rights as returned by LAR */ | 
|---|
| 175 | #define AR_TYPE_RODATA		(0 * (1 << 9)) | 
|---|
| 176 | #define AR_TYPE_RWDATA		(1 * (1 << 9)) | 
|---|
| 177 | #define AR_TYPE_RODATA_EXPDOWN	(2 * (1 << 9)) | 
|---|
| 178 | #define AR_TYPE_RWDATA_EXPDOWN	(3 * (1 << 9)) | 
|---|
| 179 | #define AR_TYPE_XOCODE		(4 * (1 << 9)) | 
|---|
| 180 | #define AR_TYPE_XRCODE		(5 * (1 << 9)) | 
|---|
| 181 | #define AR_TYPE_XOCODE_CONF	(6 * (1 << 9)) | 
|---|
| 182 | #define AR_TYPE_XRCODE_CONF	(7 * (1 << 9)) | 
|---|
| 183 | #define AR_TYPE_MASK		(7 * (1 << 9)) | 
|---|
| 184 |  | 
|---|
| 185 | #define AR_DPL0			(0 * (1 << 13)) | 
|---|
| 186 | #define AR_DPL3			(3 * (1 << 13)) | 
|---|
| 187 | #define AR_DPL_MASK		(3 * (1 << 13)) | 
|---|
| 188 |  | 
|---|
| 189 | #define AR_A			(1 << 8)   /* "Accessed" */ | 
|---|
| 190 | #define AR_S			(1 << 12)  /* If clear, "System" segment */ | 
|---|
| 191 | #define AR_P			(1 << 15)  /* "Present" */ | 
|---|
| 192 | #define AR_AVL			(1 << 20)  /* "AVaiLable" (no HW effect) */ | 
|---|
| 193 | #define AR_L			(1 << 21)  /* "Long mode" for code segments */ | 
|---|
| 194 | #define AR_DB			(1 << 22)  /* D/B, effect depends on type */ | 
|---|
| 195 | #define AR_G			(1 << 23)  /* "Granularity" (limit in pages) */ | 
|---|
| 196 |  | 
|---|
| 197 | #endif /* _ASM_X86_DESC_DEFS_H */ | 
|---|
| 198 |  | 
|---|