summaryrefslogtreecommitdiffstats
path: root/sys/x86
diff options
context:
space:
mode:
authorrpaulo <rpaulo@FreeBSD.org>2010-08-30 18:12:21 +0000
committerrpaulo <rpaulo@FreeBSD.org>2010-08-30 18:12:21 +0000
commit3cf9c58268317dd153bdb1a1307860ce3701edb8 (patch)
tree270e1e66e9ba69e25c31408f9e35c4541a0d0685 /sys/x86
parentc2cb836190c82be4859c68f5fabd199508638762 (diff)
downloadFreeBSD-src-3cf9c58268317dd153bdb1a1307860ce3701edb8.zip
FreeBSD-src-3cf9c58268317dd153bdb1a1307860ce3701edb8.tar.gz
When DTrace is enabled, make sure we don't overwrite the IDT_DTRACE_RET
entry with an IRQ for some hardware component. Reviewed by: jhb Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'sys/x86')
-rw-r--r--sys/x86/x86/local_apic.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index a05abe4..f479bbe 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -89,6 +89,7 @@ CTASSERT(IPI_STOP < APIC_SPURIOUS_INT);
/* Magic IRQ values for the timer and syscalls. */
#define IRQ_TIMER (NUM_IO_INTS + 1)
#define IRQ_SYSCALL (NUM_IO_INTS + 2)
+#define IRQ_DTRACE_RET (NUM_IO_INTS + 3)
/*
* Support for local APICs. Local APICs manage interrupts on each
@@ -307,6 +308,10 @@ lapic_create(u_int apic_id, int boot_cpu)
lapics[apic_id].la_ioint_irqs[IDT_SYSCALL - APIC_IO_INTS] = IRQ_SYSCALL;
lapics[apic_id].la_ioint_irqs[APIC_TIMER_INT - APIC_IO_INTS] =
IRQ_TIMER;
+#ifdef KDTRACE_HOOKS
+ lapics[apic_id].la_ioint_irqs[IDT_DTRACE_RET - APIC_IO_INTS] = IRQ_DTRACE_RET;
+#endif
+
#ifdef SMP
cpu_add(apic_id, boot_cpu);
@@ -1028,6 +1033,10 @@ apic_enable_vector(u_int apic_id, u_int vector)
KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry"));
KASSERT(ioint_handlers[vector / 32] != NULL,
("No ISR handler for vector %u", vector));
+#ifdef KDTRACE_HOOKS
+ KASSERT(vector != IDT_DTRACE_RET,
+ ("Attempt to overwrite DTrace entry"));
+#endif
setidt(vector, ioint_handlers[vector / 32], SDT_APIC, SEL_KPL,
GSEL_APIC);
}
@@ -1037,6 +1046,10 @@ apic_disable_vector(u_int apic_id, u_int vector)
{
KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry"));
+#ifdef KDTRACE_HOOKS
+ KASSERT(vector != IDT_DTRACE_RET,
+ ("Attempt to overwrite DTrace entry"));
+#endif
KASSERT(ioint_handlers[vector / 32] != NULL,
("No ISR handler for vector %u", vector));
#ifdef notyet
@@ -1060,6 +1073,10 @@ apic_free_vector(u_int apic_id, u_int vector, u_int irq)
KASSERT(irq < NUM_IO_INTS, ("Invalid IRQ %u", irq));
KASSERT(lapics[apic_id].la_ioint_irqs[vector - APIC_IO_INTS] ==
irq, ("IRQ mismatch"));
+#ifdef KDTRACE_HOOKS
+ KASSERT(vector != IDT_DTRACE_RET,
+ ("Attempt to overwrite DTrace entry"));
+#endif
/*
* Bind us to the cpu that owned the vector before freeing it so
@@ -1092,6 +1109,10 @@ apic_idt_to_irq(u_int apic_id, u_int vector)
KASSERT(vector >= APIC_IO_INTS && vector != IDT_SYSCALL &&
vector <= APIC_IO_INTS + APIC_NUM_IOINTS,
("Vector %u does not map to an IRQ line", vector));
+#ifdef KDTRACE_HOOKS
+ KASSERT(vector != IDT_DTRACE_RET,
+ ("Attempt to overwrite DTrace entry"));
+#endif
irq = lapics[apic_id].la_ioint_irqs[vector - APIC_IO_INTS];
if (irq < 0)
irq = 0;
@@ -1123,6 +1144,10 @@ DB_SHOW_COMMAND(apic, db_show_apic)
irq = lapics[apic_id].la_ioint_irqs[i];
if (irq == -1 || irq == IRQ_SYSCALL)
continue;
+#ifdef KDTRACE_HOOKS
+ if (irq == IRQ_DTRACE_RET)
+ continue;
+#endif
db_printf("vec 0x%2x -> ", i + APIC_IO_INTS);
if (irq == IRQ_TIMER)
db_printf("lapic timer\n");
OpenPOWER on IntegriCloud