--- /dev/null
+From bcd5cff7216f9b2de0a148cc355eac199dc6f1cf Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Date: Mon, 17 Oct 2011 11:50:30 +0200
+Subject: cputimer: Cure lock inversion
+
+From: Peter Zijlstra <a.p.zijlstra@chello.nl>
+
+commit bcd5cff7216f9b2de0a148cc355eac199dc6f1cf upstream.
+
+There's a lock inversion between the cputimer->lock and rq->lock;
+notably the two callchains involved are:
+
+ update_rlimit_cpu()
+ sighand->siglock
+ set_process_cpu_timer()
+ cpu_timer_sample_group()
+ thread_group_cputimer()
+ cputimer->lock
+ thread_group_cputime()
+ task_sched_runtime()
+ ->pi_lock
+ rq->lock
+
+ scheduler_tick()
+ rq->lock
+ task_tick_fair()
+ update_curr()
+ account_group_exec()
+ cputimer->lock
+
+Where the first one is enabling a CLOCK_PROCESS_CPUTIME_ID timer, and
+the second one is keeping up-to-date.
+
+This problem was introduced by e8abccb7193 ("posix-cpu-timers: Cure
+SMP accounting oddities").
+
+Cure the problem by removing the cputimer->lock and rq->lock nesting,
+this leaves concurrent enablers doing duplicate work, but the time
+wasted should be on the same order otherwise wasted spinning on the
+lock and the greater-than assignment filter should ensure we preserve
+monotonicity.
+
+Reported-by: Dave Jones <davej@redhat.com>
+Reported-by: Simon Kirby <sim@hostway.ca>
+Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Link: http://lkml.kernel.org/r/1318928713.21167.4.camel@twins
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/posix-cpu-timers.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/kernel/posix-cpu-timers.c
++++ b/kernel/posix-cpu-timers.c
+@@ -274,9 +274,7 @@ void thread_group_cputimer(struct task_s
+ struct task_cputime sum;
+ unsigned long flags;
+
+- spin_lock_irqsave(&cputimer->lock, flags);
+ if (!cputimer->running) {
+- cputimer->running = 1;
+ /*
+ * The POSIX timer interface allows for absolute time expiry
+ * values through the TIMER_ABSTIME flag, therefore we have
+@@ -284,8 +282,11 @@ void thread_group_cputimer(struct task_s
+ * it.
+ */
+ thread_group_cputime(tsk, &sum);
++ spin_lock_irqsave(&cputimer->lock, flags);
++ cputimer->running = 1;
+ update_gt_cputime(&cputimer->cputime, &sum);
+- }
++ } else
++ spin_lock_irqsave(&cputimer->lock, flags);
+ *times = cputimer->cputime;
+ spin_unlock_irqrestore(&cputimer->lock, flags);
+ }
--- /dev/null
+From 5a6e8482a16e61250a9121fc9ec719ab0529e760 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Tue, 18 Oct 2011 20:10:05 -0400
+Subject: drm/radeon/kms/atom: fix handling of FB scratch indices
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 5a6e8482a16e61250a9121fc9ec719ab0529e760 upstream.
+
+FB scratch indices are dword indices, but we were treating
+them as byte indices. As such, we were getting the wrong
+FB scratch data for non-0 indices. Fix the indices and
+guard the indexing against indices larger than the scratch
+allocation.
+
+Fixes memory corruption on some boards if data was written
+past the end of the FB scratch array.
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Reported-by: Dave Airlie <airlied@redhat.com>
+Tested-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/radeon/atom.c | 15 +++++++++++++--
+ drivers/gpu/drm/radeon/atom.h | 1 +
+ 2 files changed, 14 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/atom.c
++++ b/drivers/gpu/drm/radeon/atom.c
+@@ -277,7 +277,12 @@ static uint32_t atom_get_src_int(atom_ex
+ case ATOM_ARG_FB:
+ idx = U8(*ptr);
+ (*ptr)++;
+- val = gctx->scratch[((gctx->fb_base + idx) / 4)];
++ if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) {
++ DRM_ERROR("ATOM: fb read beyond scratch region: %d vs. %d\n",
++ gctx->fb_base + (idx * 4), gctx->scratch_size_bytes);
++ val = 0;
++ } else
++ val = gctx->scratch[(gctx->fb_base / 4) + idx];
+ if (print)
+ DEBUG("FB[0x%02X]", idx);
+ break;
+@@ -531,7 +536,11 @@ static void atom_put_dst(atom_exec_conte
+ case ATOM_ARG_FB:
+ idx = U8(*ptr);
+ (*ptr)++;
+- gctx->scratch[((gctx->fb_base + idx) / 4)] = val;
++ if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) {
++ DRM_ERROR("ATOM: fb write beyond scratch region: %d vs. %d\n",
++ gctx->fb_base + (idx * 4), gctx->scratch_size_bytes);
++ } else
++ gctx->scratch[(gctx->fb_base / 4) + idx] = val;
+ DEBUG("FB[0x%02X]", idx);
+ break;
+ case ATOM_ARG_PLL:
+@@ -1367,11 +1376,13 @@ int atom_allocate_fb_scratch(struct atom
+
+ usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
+ }
++ ctx->scratch_size_bytes = 0;
+ if (usage_bytes == 0)
+ usage_bytes = 20 * 1024;
+ /* allocate some scratch memory */
+ ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
+ if (!ctx->scratch)
+ return -ENOMEM;
++ ctx->scratch_size_bytes = usage_bytes;
+ return 0;
+ }
+--- a/drivers/gpu/drm/radeon/atom.h
++++ b/drivers/gpu/drm/radeon/atom.h
+@@ -137,6 +137,7 @@ struct atom_context {
+ int cs_equal, cs_above;
+ int io_mode;
+ uint32_t *scratch;
++ int scratch_size_bytes;
+ };
+
+ extern int atom_debug;
hid-usbhid-add-support-for-sigma-micro-chip.patch
hwmon-w83627ehf-properly-report-thermal-diode-sensors.patch
avoid-using-variable-length-arrays-in-kernel-sys.c.patch
+drm-radeon-kms-atom-fix-handling-of-fb-scratch-indices.patch
+cputimer-cure-lock-inversion.patch