summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/ps3
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2011-06-23 04:35:45 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2011-06-23 04:35:45 +0000
commit6d4918e45e29c8527fe3383af8f33ef6ed977e35 (patch)
tree96caa0b0bc52f149e1c9f7b542b967489b0a21e8 /sys/powerpc/ps3
parentb51f0413bb9eea9e7f306823369257ccace21801 (diff)
downloadFreeBSD-src-6d4918e45e29c8527fe3383af8f33ef6ed977e35.zip
FreeBSD-src-6d4918e45e29c8527fe3383af8f33ef6ed977e35.tar.gz
Use atomic operations to mask and unmask IRQs. This prevents a problem
(obvious in retrospect) in which interrupts on one CPU that are temporarily masked can end up permanently masked when a handler on another CPU clobbers the interrupt mask register with an old copy.
Diffstat (limited to 'sys/powerpc/ps3')
-rw-r--r--sys/powerpc/ps3/ps3pic.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/sys/powerpc/ps3/ps3pic.c b/sys/powerpc/ps3/ps3pic.c
index c00585b..3a62e3c 100644
--- a/sys/powerpc/ps3/ps3pic.c
+++ b/sys/powerpc/ps3/ps3pic.c
@@ -56,10 +56,10 @@ static void ps3pic_mask(device_t, u_int);
static void ps3pic_unmask(device_t, u_int);
struct ps3pic_softc {
- uint64_t *bitmap_thread0;
- uint64_t *mask_thread0;
- uint64_t *bitmap_thread1;
- uint64_t *mask_thread1;
+ volatile uint64_t *bitmap_thread0;
+ volatile uint64_t *mask_thread0;
+ volatile uint64_t *bitmap_thread1;
+ volatile uint64_t *mask_thread1;
uint64_t sc_ipi_outlet[2];
int sc_vector[64];
@@ -219,8 +219,8 @@ ps3pic_mask(device_t dev, u_int irq)
if (irq == sc->sc_ipi_outlet[0])
return;
- sc->mask_thread0[0] &= ~(1UL << (63 - irq));
- sc->mask_thread1[0] &= ~(1UL << (63 - irq));
+ atomic_clear_64(&sc->mask_thread0[0], 1UL << (63 - irq));
+ atomic_clear_64(&sc->mask_thread1[0], 1UL << (63 - irq));
lv1_get_logical_ppe_id(&ppe);
lv1_did_update_interrupt_mask(ppe, 0);
@@ -234,8 +234,8 @@ ps3pic_unmask(device_t dev, u_int irq)
uint64_t ppe;
sc = device_get_softc(dev);
- sc->mask_thread0[0] |= (1UL << (63 - irq));
- sc->mask_thread1[0] |= (1UL << (63 - irq));
+ atomic_set_64(&sc->mask_thread0[0], 1UL << (63 - irq));
+ atomic_set_64(&sc->mask_thread1[0], 1UL << (63 - irq));
lv1_get_logical_ppe_id(&ppe);
lv1_did_update_interrupt_mask(ppe, 0);
OpenPOWER on IntegriCloud