Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4dfc896e authored by Jiri Kosina's avatar Jiri Kosina Committed by Linus Torvalds
Browse files

[PATCH] oprofile: fix potential deadlock on oprofilefs_lock



nmi_cpu_setup() is called from hardirq context and acquires oprofilefs_lock.
alloc_event_buffer() and oprofilefs_ulong_from_user() acquire this lock
without disabling irqs, which could deadlock.

Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 6faee84b
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -70,11 +70,12 @@ void wake_up_buffer_waiter(void)
int alloc_event_buffer(void)
{
	int err = -ENOMEM;
	unsigned long flags;

	spin_lock(&oprofilefs_lock);
	spin_lock_irqsave(&oprofilefs_lock, flags);
	buffer_size = fs_buffer_size;
	buffer_watershed = fs_buffer_watershed;
	spin_unlock(&oprofilefs_lock);
	spin_unlock_irqrestore(&oprofilefs_lock, flags);
 
	if (buffer_watershed >= buffer_size)
		return -EINVAL;
+3 −2
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user * buf, size_t co
int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, size_t count)
{
	char tmpbuf[TMPBUFSIZE];
	unsigned long flags;

	if (!count)
		return 0;
@@ -77,9 +78,9 @@ int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, siz
	if (copy_from_user(tmpbuf, buf, count))
		return -EFAULT;

	spin_lock(&oprofilefs_lock);
	spin_lock_irqsave(&oprofilefs_lock, flags);
	*val = simple_strtoul(tmpbuf, NULL, 0);
	spin_unlock(&oprofilefs_lock);
	spin_unlock_irqrestore(&oprofilefs_lock, flags);
	return 0;
}