Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 23 Jun 2011 04:35:45 +0000 (UTC)
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r223463 - head/sys/powerpc/ps3
Message-ID:  <201106230435.p5N4Zj6G083097@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: nwhitehorn
Date: Thu Jun 23 04:35:45 2011
New Revision: 223463
URL: http://svn.freebsd.org/changeset/base/223463

Log:
  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.

Modified:
  head/sys/powerpc/ps3/ps3pic.c

Modified: head/sys/powerpc/ps3/ps3pic.c
==============================================================================
--- head/sys/powerpc/ps3/ps3pic.c	Thu Jun 23 04:06:33 2011	(r223462)
+++ head/sys/powerpc/ps3/ps3pic.c	Thu Jun 23 04:35:45 2011	(r223463)
@@ -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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106230435.p5N4Zj6G083097>