Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/idt: Make IDT init functions static inlines

Move these two functions from kernel/idt.c to include/asm/desc.h:

* init_idt_data()
* idt_init_desc()

These functions are needed to setup IDT entries very early and need to
be called from head64.c. To be usable this early, these functions need
to be compiled without instrumentation and the stack-protector feature.

These features need to be kept enabled for kernel/idt.c, so head64.c
must use its own versions.

[ bp: Take Kees' suggested patch title and add his Rev-by. ]

Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Kees Cook <keescook@chromium.org>
Link: https://lkml.kernel.org/r/20200907131613.12703-35-joro@8bytes.org

authored by

Joerg Roedel and committed by
Borislav Petkov
097ee5b7 f5963ba7

+34 -34
+27
arch/x86/include/asm/desc.h
··· 383 383 384 384 void alloc_intr_gate(unsigned int n, const void *addr); 385 385 386 + static inline void init_idt_data(struct idt_data *data, unsigned int n, 387 + const void *addr) 388 + { 389 + BUG_ON(n > 0xFF); 390 + 391 + memset(data, 0, sizeof(*data)); 392 + data->vector = n; 393 + data->addr = addr; 394 + data->segment = __KERNEL_CS; 395 + data->bits.type = GATE_INTERRUPT; 396 + data->bits.p = 1; 397 + } 398 + 399 + static inline void idt_init_desc(gate_desc *gate, const struct idt_data *d) 400 + { 401 + unsigned long addr = (unsigned long) d->addr; 402 + 403 + gate->offset_low = (u16) addr; 404 + gate->segment = (u16) d->segment; 405 + gate->bits = d->bits; 406 + gate->offset_middle = (u16) (addr >> 16); 407 + #ifdef CONFIG_X86_64 408 + gate->offset_high = (u32) (addr >> 32); 409 + gate->reserved = 0; 410 + #endif 411 + } 412 + 386 413 extern unsigned long system_vectors[]; 387 414 388 415 extern void load_current_idt(void);
+7
arch/x86/include/asm/desc_defs.h
··· 74 74 p : 1; 75 75 } __attribute__((packed)); 76 76 77 + struct idt_data { 78 + unsigned int vector; 79 + unsigned int segment; 80 + struct idt_bits bits; 81 + const void *addr; 82 + }; 83 + 77 84 struct gate_struct { 78 85 u16 offset_low; 79 86 u16 segment;
-34
arch/x86/kernel/idt.c
··· 11 11 #include <asm/desc.h> 12 12 #include <asm/hw_irq.h> 13 13 14 - struct idt_data { 15 - unsigned int vector; 16 - unsigned int segment; 17 - struct idt_bits bits; 18 - const void *addr; 19 - }; 20 - 21 14 #define DPL0 0x0 22 15 #define DPL3 0x3 23 16 ··· 171 178 } 172 179 #endif 173 180 174 - static inline void idt_init_desc(gate_desc *gate, const struct idt_data *d) 175 - { 176 - unsigned long addr = (unsigned long) d->addr; 177 - 178 - gate->offset_low = (u16) addr; 179 - gate->segment = (u16) d->segment; 180 - gate->bits = d->bits; 181 - gate->offset_middle = (u16) (addr >> 16); 182 - #ifdef CONFIG_X86_64 183 - gate->offset_high = (u32) (addr >> 32); 184 - gate->reserved = 0; 185 - #endif 186 - } 187 - 188 181 static __init void 189 182 idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size, bool sys) 190 183 { ··· 182 203 if (sys) 183 204 set_bit(t->vector, system_vectors); 184 205 } 185 - } 186 - 187 - static void init_idt_data(struct idt_data *data, unsigned int n, 188 - const void *addr) 189 - { 190 - BUG_ON(n > 0xFF); 191 - 192 - memset(data, 0, sizeof(*data)); 193 - data->vector = n; 194 - data->addr = addr; 195 - data->segment = __KERNEL_CS; 196 - data->bits.type = GATE_INTERRUPT; 197 - data->bits.p = 1; 198 206 } 199 207 200 208 static __init void set_intr_gate(unsigned int n, const void *addr)