Greg Kroah-Hartman | b244131 | 2017-11-01 15:07:57 +0100 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
Avi Kivity | 249e83f | 2006-12-07 02:14:04 +0100 | [diff] [blame] | 2 | /* Written 2000 by Andi Kleen */ |
H. Peter Anvin | 1965aae | 2008-10-22 22:26:29 -0700 | [diff] [blame] | 3 | #ifndef _ASM_X86_DESC_DEFS_H |
| 4 | #define _ASM_X86_DESC_DEFS_H |
Avi Kivity | 249e83f | 2006-12-07 02:14:04 +0100 | [diff] [blame] | 5 | |
| 6 | /* |
| 7 | * Segment descriptor structure definitions, usable from both x86_64 and i386 |
| 8 | * archs. |
| 9 | */ |
| 10 | |
| 11 | #ifndef __ASSEMBLY__ |
| 12 | |
| 13 | #include <linux/types.h> |
| 14 | |
Joe Perches | b776190 | 2008-03-23 01:01:57 -0700 | [diff] [blame] | 15 | /* 8 byte segment descriptor */ |
Avi Kivity | 249e83f | 2006-12-07 02:14:04 +0100 | [diff] [blame] | 16 | struct desc_struct { |
Thomas Gleixner | 38e9e81 | 2017-08-28 08:47:41 +0200 | [diff] [blame] | 17 | u16 limit0; |
| 18 | u16 base0; |
| 19 | u16 base1: 8, type: 4, s: 1, dpl: 2, p: 1; |
| 20 | u16 limit1: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8; |
Glauber de Oliveira Costa | 6842ef0 | 2008-01-30 13:31:11 +0100 | [diff] [blame] | 21 | } __attribute__((packed)); |
Avi Kivity | 249e83f | 2006-12-07 02:14:04 +0100 | [diff] [blame] | 22 | |
Thomas Gleixner | 38e9e81 | 2017-08-28 08:47:41 +0200 | [diff] [blame] | 23 | #define GDT_ENTRY_INIT(flags, base, limit) \ |
| 24 | { \ |
| 25 | .limit0 = (u16) (limit), \ |
| 26 | .limit1 = ((limit) >> 16) & 0x0F, \ |
| 27 | .base0 = (u16) (base), \ |
| 28 | .base1 = ((base) >> 16) & 0xFF, \ |
| 29 | .base2 = ((base) >> 24) & 0xFF, \ |
| 30 | .type = (flags & 0x0f), \ |
| 31 | .s = (flags >> 4) & 0x01, \ |
| 32 | .dpl = (flags >> 5) & 0x03, \ |
| 33 | .p = (flags >> 7) & 0x01, \ |
| 34 | .avl = (flags >> 12) & 0x01, \ |
| 35 | .l = (flags >> 13) & 0x01, \ |
| 36 | .d = (flags >> 14) & 0x01, \ |
| 37 | .g = (flags >> 15) & 0x01, \ |
| 38 | } |
Akinobu Mita | 1e5de18 | 2009-07-19 00:12:20 +0900 | [diff] [blame] | 39 | |
Avi Kivity | 249e83f | 2006-12-07 02:14:04 +0100 | [diff] [blame] | 40 | enum { |
| 41 | GATE_INTERRUPT = 0xE, |
| 42 | GATE_TRAP = 0xF, |
| 43 | GATE_CALL = 0xC, |
Glauber de Oliveira Costa | 507f90c | 2008-01-30 13:31:14 +0100 | [diff] [blame] | 44 | GATE_TASK = 0x5, |
Avi Kivity | 249e83f | 2006-12-07 02:14:04 +0100 | [diff] [blame] | 45 | }; |
| 46 | |
Avi Kivity | 249e83f | 2006-12-07 02:14:04 +0100 | [diff] [blame] | 47 | enum { |
| 48 | DESC_TSS = 0x9, |
| 49 | DESC_LDT = 0x2, |
Joe Perches | b776190 | 2008-03-23 01:01:57 -0700 | [diff] [blame] | 50 | DESCTYPE_S = 0x10, /* !system */ |
Avi Kivity | 249e83f | 2006-12-07 02:14:04 +0100 | [diff] [blame] | 51 | }; |
| 52 | |
Thomas Gleixner | 87cc037 | 2017-08-28 08:47:42 +0200 | [diff] [blame] | 53 | /* LDT or TSS descriptor in the GDT. */ |
| 54 | struct ldttss_desc { |
| 55 | u16 limit0; |
| 56 | u16 base0; |
| 57 | |
| 58 | u16 base1 : 8, type : 5, dpl : 2, p : 1; |
| 59 | u16 limit1 : 4, zero0 : 3, g : 1, base2 : 8; |
| 60 | #ifdef CONFIG_X86_64 |
| 61 | u32 base3; |
| 62 | u32 zero1; |
| 63 | #endif |
Avi Kivity | 249e83f | 2006-12-07 02:14:04 +0100 | [diff] [blame] | 64 | } __attribute__((packed)); |
| 65 | |
Thomas Gleixner | 87cc037 | 2017-08-28 08:47:42 +0200 | [diff] [blame] | 66 | typedef struct ldttss_desc ldt_desc; |
| 67 | typedef struct ldttss_desc tss_desc; |
Glauber de Oliveira Costa | 010d4f8 | 2008-01-30 13:31:12 +0100 | [diff] [blame] | 68 | |
Thomas Gleixner | 64b163f | 2017-08-28 08:47:37 +0200 | [diff] [blame] | 69 | struct idt_bits { |
| 70 | u16 ist : 3, |
| 71 | zero : 5, |
| 72 | type : 5, |
| 73 | dpl : 2, |
| 74 | p : 1; |
| 75 | } __attribute__((packed)); |
| 76 | |
| 77 | struct gate_struct { |
| 78 | u16 offset_low; |
| 79 | u16 segment; |
| 80 | struct idt_bits bits; |
| 81 | u16 offset_middle; |
| 82 | #ifdef CONFIG_X86_64 |
| 83 | u32 offset_high; |
| 84 | u32 reserved; |
| 85 | #endif |
| 86 | } __attribute__((packed)); |
| 87 | |
| 88 | typedef struct gate_struct gate_desc; |
| 89 | |
| 90 | static inline unsigned long gate_offset(const gate_desc *g) |
| 91 | { |
| 92 | #ifdef CONFIG_X86_64 |
| 93 | return g->offset_low | ((unsigned long)g->offset_middle << 16) | |
| 94 | ((unsigned long) g->offset_high << 32); |
| 95 | #else |
| 96 | return g->offset_low | ((unsigned long)g->offset_middle << 16); |
| 97 | #endif |
| 98 | } |
| 99 | |
| 100 | static inline unsigned long gate_segment(const gate_desc *g) |
| 101 | { |
| 102 | return g->segment; |
| 103 | } |
| 104 | |
Avi Kivity | 249e83f | 2006-12-07 02:14:04 +0100 | [diff] [blame] | 105 | struct desc_ptr { |
| 106 | unsigned short size; |
| 107 | unsigned long address; |
| 108 | } __attribute__((packed)) ; |
| 109 | |
Avi Kivity | 249e83f | 2006-12-07 02:14:04 +0100 | [diff] [blame] | 110 | #endif /* !__ASSEMBLY__ */ |
| 111 | |
Andy Lutomirski | 8ff5bd2 | 2016-02-16 15:09:02 -0800 | [diff] [blame] | 112 | /* Access rights as returned by LAR */ |
| 113 | #define AR_TYPE_RODATA (0 * (1 << 9)) |
| 114 | #define AR_TYPE_RWDATA (1 * (1 << 9)) |
| 115 | #define AR_TYPE_RODATA_EXPDOWN (2 * (1 << 9)) |
| 116 | #define AR_TYPE_RWDATA_EXPDOWN (3 * (1 << 9)) |
| 117 | #define AR_TYPE_XOCODE (4 * (1 << 9)) |
| 118 | #define AR_TYPE_XRCODE (5 * (1 << 9)) |
| 119 | #define AR_TYPE_XOCODE_CONF (6 * (1 << 9)) |
| 120 | #define AR_TYPE_XRCODE_CONF (7 * (1 << 9)) |
| 121 | #define AR_TYPE_MASK (7 * (1 << 9)) |
| 122 | |
| 123 | #define AR_DPL0 (0 * (1 << 13)) |
| 124 | #define AR_DPL3 (3 * (1 << 13)) |
| 125 | #define AR_DPL_MASK (3 * (1 << 13)) |
| 126 | |
| 127 | #define AR_A (1 << 8) /* "Accessed" */ |
| 128 | #define AR_S (1 << 12) /* If clear, "System" segment */ |
| 129 | #define AR_P (1 << 15) /* "Present" */ |
| 130 | #define AR_AVL (1 << 20) /* "AVaiLable" (no HW effect) */ |
| 131 | #define AR_L (1 << 21) /* "Long mode" for code segments */ |
| 132 | #define AR_DB (1 << 22) /* D/B, effect depends on type */ |
| 133 | #define AR_G (1 << 23) /* "Granularity" (limit in pages) */ |
| 134 | |
H. Peter Anvin | 1965aae | 2008-10-22 22:26:29 -0700 | [diff] [blame] | 135 | #endif /* _ASM_X86_DESC_DEFS_H */ |