From 6b54dcbbef6a003ae4c5fb9ae77f2f261f82dbf9 Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Wed, 12 Oct 2016 09:40:41 +0200 Subject: bsps/i386: replace global interrupt disable by SMP build supporting locking. --- c/src/lib/libbsp/i386/shared/irq/idt.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'c/src/lib/libbsp/i386/shared/irq/idt.c') diff --git a/c/src/lib/libbsp/i386/shared/irq/idt.c b/c/src/lib/libbsp/i386/shared/irq/idt.c index ee6f8e02ab..ac79a97004 100644 --- a/c/src/lib/libbsp/i386/shared/irq/idt.c +++ b/c/src/lib/libbsp/i386/shared/irq/idt.c @@ -19,6 +19,16 @@ #include #include +/* + * This locking is not enough if IDT is changed at runtime + * and entry can be changed for vector which is enabled + * at change time. But such use is broken anyway. + * Protect code only against concurrent changes. + * Even that is probably unnecessary if different + * entries are changed concurrently. + */ +RTEMS_INTERRUPT_LOCK_DEFINE( static, rtems_idt_access_lock, "rtems_idt_access_lock" ); + static rtems_raw_irq_connect_data* raw_irq_table; static rtems_raw_irq_connect_data default_raw_irq_entry; static interrupt_gate_descriptor default_idt_entry; @@ -60,7 +70,7 @@ int i386_set_idt_entry (const rtems_raw_irq_connect_data* irq) { interrupt_gate_descriptor* idt_entry_tbl; unsigned limit; - rtems_interrupt_level level; + rtems_interrupt_lock_context lock_context; i386_get_info_from_IDTR (&idt_entry_tbl, &limit); @@ -81,14 +91,14 @@ int i386_set_idt_entry (const rtems_raw_irq_connect_data* irq) return 0; } - rtems_interrupt_disable(level); + rtems_interrupt_lock_acquire(&rtems_idt_access_lock, &lock_context); raw_irq_table [irq->idtIndex] = *irq; create_interrupt_gate_descriptor (&idt_entry_tbl[irq->idtIndex], irq->hdl); if (irq->on) irq->on(irq); - rtems_interrupt_enable(level); + rtems_interrupt_lock_release(&rtems_idt_access_lock, &lock_context); return 1; } @@ -99,7 +109,7 @@ void _CPU_ISR_install_vector (uint32_t vector, interrupt_gate_descriptor* idt_entry_tbl; unsigned limit; interrupt_gate_descriptor new; - rtems_interrupt_level level; + rtems_interrupt_lock_context lock_context; i386_get_info_from_IDTR (&idt_entry_tbl, &limit); @@ -109,14 +119,14 @@ void _CPU_ISR_install_vector (uint32_t vector, if (vector >= limit) { return; } - rtems_interrupt_disable(level); + rtems_interrupt_lock_acquire(&rtems_idt_access_lock, &lock_context); * ((unsigned int *) oldHdl) = idt_entry_tbl[vector].low_offsets_bits | (idt_entry_tbl[vector].high_offsets_bits << 16); create_interrupt_gate_descriptor(&new, hdl); idt_entry_tbl[vector] = new; - rtems_interrupt_enable(level); + rtems_interrupt_lock_release(&rtems_idt_access_lock, &lock_context); } int i386_get_current_idt_entry (rtems_raw_irq_connect_data* irq) @@ -143,7 +153,7 @@ int i386_delete_idt_entry (const rtems_raw_irq_connect_data* irq) { interrupt_gate_descriptor* idt_entry_tbl; unsigned limit; - rtems_interrupt_level level; + rtems_interrupt_lock_context lock_context; i386_get_info_from_IDTR (&idt_entry_tbl, &limit); @@ -163,7 +173,7 @@ int i386_delete_idt_entry (const rtems_raw_irq_connect_data* irq) if (get_hdl_from_vector(irq->idtIndex) != irq->hdl){ return 0; } - rtems_interrupt_disable(level); + rtems_interrupt_lock_acquire(&rtems_idt_access_lock, &lock_context); idt_entry_tbl[irq->idtIndex] = default_idt_entry; @@ -173,7 +183,7 @@ int i386_delete_idt_entry (const rtems_raw_irq_connect_data* irq) raw_irq_table[irq->idtIndex] = default_raw_irq_entry; raw_irq_table[irq->idtIndex].idtIndex = irq->idtIndex; - rtems_interrupt_enable(level); + rtems_interrupt_lock_release(&rtems_idt_access_lock, &lock_context); return 1; } @@ -185,7 +195,7 @@ int i386_init_idt (rtems_raw_irq_global_settings* config) { unsigned limit; unsigned i; - rtems_interrupt_level level; + rtems_interrupt_lock_context lock_context; interrupt_gate_descriptor* idt_entry_tbl; i386_get_info_from_IDTR (&idt_entry_tbl, &limit); @@ -203,7 +213,7 @@ int i386_init_idt (rtems_raw_irq_global_settings* config) local_settings = config; default_raw_irq_entry = config->defaultRawEntry; - rtems_interrupt_disable(level); + rtems_interrupt_lock_acquire(&rtems_idt_access_lock, &lock_context); create_interrupt_gate_descriptor (&default_idt_entry, default_raw_irq_entry.hdl); @@ -218,7 +228,7 @@ int i386_init_idt (rtems_raw_irq_global_settings* config) raw_irq_table[i].off(&raw_irq_table[i]); } } - rtems_interrupt_enable(level); + rtems_interrupt_lock_release(&rtems_idt_access_lock, &lock_context); return 1; } -- cgit v1.2.3