Skip to content

Commit 3318e97

Browse files
KAGA-KOKOIngo Molnar
authored andcommitted
x86/idt: Prepare for table based init
The IDT setup code is handled in several places. All of them use variants of set_intr_gate() inlines. This can be done with a table based initialization, which allows to reduce the inline zoo and puts all IDT related code and information into a single place. Add the infrastructure. Signed-off-by: Thomas Gleixner <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: Denys Vlasenko <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Josh Poimboeuf <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Steven Rostedt <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 87e8178 commit 3318e97

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

arch/x86/kernel/idt.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,49 @@
55
*/
66
#include <linux/interrupt.h>
77

8+
#include <asm/traps.h>
9+
#include <asm/proto.h>
810
#include <asm/desc.h>
911

12+
struct idt_data {
13+
unsigned int vector;
14+
unsigned int segment;
15+
struct idt_bits bits;
16+
const void *addr;
17+
};
18+
19+
#define DPL0 0x0
20+
#define DPL3 0x3
21+
22+
#define DEFAULT_STACK 0
23+
24+
#define G(_vector, _addr, _ist, _type, _dpl, _segment) \
25+
{ \
26+
.vector = _vector, \
27+
.bits.ist = _ist, \
28+
.bits.type = _type, \
29+
.bits.dpl = _dpl, \
30+
.bits.p = 1, \
31+
.addr = _addr, \
32+
.segment = _segment, \
33+
}
34+
35+
/* Interrupt gate */
36+
#define INTG(_vector, _addr) \
37+
G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL0, __KERNEL_CS)
38+
39+
/* System interrupt gate */
40+
#define SYSG(_vector, _addr) \
41+
G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL3, __KERNEL_CS)
42+
43+
/* Interrupt gate with interrupt stack */
44+
#define ISTG(_vector, _addr, _ist) \
45+
G(_vector, _addr, _ist, GATE_INTERRUPT, DPL0, __KERNEL_CS)
46+
47+
/* Task gate */
48+
#define TSKG(_vector, _gdt) \
49+
G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3)
50+
1051
/* Must be page-aligned because the real IDT is used in a fixmap. */
1152
gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss;
1253

@@ -25,6 +66,32 @@ const struct desc_ptr debug_idt_descr = {
2566
};
2667
#endif
2768

69+
static inline void idt_init_desc(gate_desc *gate, const struct idt_data *d)
70+
{
71+
unsigned long addr = (unsigned long) d->addr;
72+
73+
gate->offset_low = (u16) addr;
74+
gate->segment = (u16) d->segment;
75+
gate->bits = d->bits;
76+
gate->offset_middle = (u16) (addr >> 16);
77+
#ifdef CONFIG_X86_64
78+
gate->offset_high = (u32) (addr >> 32);
79+
gate->reserved = 0;
80+
#endif
81+
}
82+
83+
static __init void
84+
idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size)
85+
{
86+
gate_desc desc;
87+
88+
for (; size > 0; t++, size--) {
89+
idt_init_desc(&desc, t);
90+
set_bit(t->vector, used_vectors);
91+
write_idt_entry(idt, t->vector, &desc);
92+
}
93+
}
94+
2895
/**
2996
* idt_setup_early_handler - Initializes the idt table with early handlers
3097
*/

0 commit comments

Comments
 (0)