@@ -212,15 +212,16 @@ static inline void idt_init_desc(gate_desc *gate, const struct idt_data *d)
212
212
#endif
213
213
}
214
214
215
- static __init void
216
- idt_setup_from_table (gate_desc * idt , const struct idt_data * t , int size )
215
+ static void
216
+ idt_setup_from_table (gate_desc * idt , const struct idt_data * t , int size , bool sys )
217
217
{
218
218
gate_desc desc ;
219
219
220
220
for (; size > 0 ; t ++ , size -- ) {
221
221
idt_init_desc (& desc , t );
222
- set_bit (t -> vector , used_vectors );
223
222
write_idt_entry (idt , t -> vector , & desc );
223
+ if (sys )
224
+ set_bit (t -> vector , used_vectors );
224
225
}
225
226
}
226
227
@@ -233,7 +234,8 @@ idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size)
233
234
*/
234
235
void __init idt_setup_early_traps (void )
235
236
{
236
- idt_setup_from_table (idt_table , early_idts , ARRAY_SIZE (early_idts ));
237
+ idt_setup_from_table (idt_table , early_idts , ARRAY_SIZE (early_idts ),
238
+ true);
237
239
load_idt (& idt_descr );
238
240
}
239
241
@@ -242,7 +244,7 @@ void __init idt_setup_early_traps(void)
242
244
*/
243
245
void __init idt_setup_traps (void )
244
246
{
245
- idt_setup_from_table (idt_table , def_idts , ARRAY_SIZE (def_idts ));
247
+ idt_setup_from_table (idt_table , def_idts , ARRAY_SIZE (def_idts ), true );
246
248
}
247
249
248
250
#ifdef CONFIG_X86_64
@@ -259,15 +261,15 @@ void __init idt_setup_traps(void)
259
261
void __init idt_setup_early_pf (void )
260
262
{
261
263
idt_setup_from_table (idt_table , early_pf_idts ,
262
- ARRAY_SIZE (early_pf_idts ));
264
+ ARRAY_SIZE (early_pf_idts ), true );
263
265
}
264
266
265
267
/**
266
268
* idt_setup_ist_traps - Initialize the idt table with traps using IST
267
269
*/
268
270
void __init idt_setup_ist_traps (void )
269
271
{
270
- idt_setup_from_table (idt_table , ist_idts , ARRAY_SIZE (ist_idts ));
272
+ idt_setup_from_table (idt_table , ist_idts , ARRAY_SIZE (ist_idts ), true );
271
273
}
272
274
273
275
/**
@@ -277,7 +279,7 @@ void __init idt_setup_debugidt_traps(void)
277
279
{
278
280
memcpy (& debug_idt_table , & idt_table , IDT_ENTRIES * 16 );
279
281
280
- idt_setup_from_table (debug_idt_table , dbg_idts , ARRAY_SIZE (dbg_idts ));
282
+ idt_setup_from_table (debug_idt_table , dbg_idts , ARRAY_SIZE (dbg_idts ), false );
281
283
}
282
284
#endif
283
285
@@ -289,7 +291,7 @@ void __init idt_setup_apic_and_irq_gates(void)
289
291
int i = FIRST_EXTERNAL_VECTOR ;
290
292
void * entry ;
291
293
292
- idt_setup_from_table (idt_table , apic_idts , ARRAY_SIZE (apic_idts ));
294
+ idt_setup_from_table (idt_table , apic_idts , ARRAY_SIZE (apic_idts ), true );
293
295
294
296
for_each_clear_bit_from (i , used_vectors , FIRST_SYSTEM_VECTOR ) {
295
297
entry = irq_entries_start + 8 * (i - FIRST_EXTERNAL_VECTOR );
@@ -333,3 +335,26 @@ void idt_invalidate(void *addr)
333
335
334
336
load_idt (& idt );
335
337
}
338
+
339
+ void set_intr_gate (unsigned int n , const void * addr )
340
+ {
341
+ struct idt_data data ;
342
+
343
+ BUG_ON (n > 0xFF );
344
+
345
+ memset (& data , 0 , sizeof (data ));
346
+ data .vector = n ;
347
+ data .addr = addr ;
348
+ data .segment = __KERNEL_CS ;
349
+ data .bits .type = GATE_INTERRUPT ;
350
+ data .bits .p = 1 ;
351
+
352
+ idt_setup_from_table (idt_table , & data , 1 , false);
353
+ }
354
+
355
+ void alloc_intr_gate (unsigned int n , const void * addr )
356
+ {
357
+ BUG_ON (test_bit (n , used_vectors ) || n < FIRST_SYSTEM_VECTOR );
358
+ set_bit (n , used_vectors );
359
+ set_intr_gate (n , addr );
360
+ }
0 commit comments