linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ARM: Fix a race in the vfp_notifier() function on SMP systems
@ 2009-12-18 13:45 Catalin Marinas
  2009-12-18 14:11 ` Russell King - ARM Linux
  0 siblings, 1 reply; 10+ messages in thread
From: Catalin Marinas @ 2009-12-18 13:45 UTC (permalink / raw)
  To: linux-arm-kernel

	(patch updated following Russell's changes to vfpmodule.c)

The vfp_notifier(THREAD_NOTIFY_RELEASE) maybe be called with thread->cpu
different from the current one, causing a race condition with both the
THREAD_NOTIFY_SWITCH path and vfp_support_entry().

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm/vfp/vfpmodule.c |   23 ++++++++++++++++++++---
 1 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index aed05bc..2828767 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -69,8 +69,19 @@ static void vfp_thread_release(struct thread_info *thread)
 	union vfp_state *vfp = &thread->vfpstate;
 	unsigned int cpu = thread->cpu;
 
+#ifndef CONFIG_SMP
 	if (last_VFP_context[cpu] == vfp)
 		last_VFP_context[cpu] = NULL;
+#else
+	/*
+	 * Since release_thread() may be called from a different CPU, we use
+	 * cmpxchg() here to avoid a race with the vfp_support_entry() code
+	 * which modifies last_VFP_context[cpu]. Note that on SMP systems, a
+	 * STR instruction on a different CPU clears the global exclusive
+	 * monitor state.
+	 */
+	(void)cmpxchg(&last_VFP_context[cpu], vfp, NULL);
+#endif
 }
 
 /*
@@ -105,13 +116,19 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
 		unsigned int cpu = thread->cpu;
 
 		/*
+		 * The vfpstate structure pointed to by last_VFP_context[cpu]
+		 * may be released via call_rcu(delayed_put_task_struct) but
+		 * atomic_notifier_call_chain() already holds the RCU lock.
+		 */
+		vfp = last_VFP_context[cpu];
+		/*
 		 * On SMP, if VFP is enabled, save the old state in
 		 * case the thread migrates to a different CPU. The
 		 * restoring is done lazily.
 		 */
-		if ((fpexc & FPEXC_EN) && last_VFP_context[cpu]) {
-			vfp_save_state(last_VFP_context[cpu], fpexc);
-			last_VFP_context[cpu]->hard.cpu = cpu;
+		if ((fpexc & FPEXC_EN) && vfp) {
+			vfp_save_state(vfp, fpexc);
+			vfp->hard.cpu = cpu;
 		}
 		/*
 		 * Thread migration, just force the reloading of the

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-12-22 15:36 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-18 13:45 [PATCH] ARM: Fix a race in the vfp_notifier() function on SMP systems Catalin Marinas
2009-12-18 14:11 ` Russell King - ARM Linux
2009-12-18 14:22   ` [PATCH] ARM: Fix a race in the vfp_notifier() function on SMPsystems Catalin Marinas
2009-12-18 14:25   ` [PATCH] ARM: Fix a race in the vfp_notifier() function on SMP systems Russell King - ARM Linux
2009-12-18 14:47     ` Russell King - ARM Linux
2009-12-18 14:51       ` [PATCH] ARM: Fix a race in the vfp_notifier() function on SMPsystems Catalin Marinas
2009-12-18 14:53         ` Russell King - ARM Linux
2009-12-19  8:20           ` Dirk Behme
2009-12-22 15:36             ` Russell King - ARM Linux
2009-12-18 22:17       ` [PATCH] ARM: Fix a race in the vfp_notifier() function on SMP systems Ryan Mallon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).