]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 15 May 2015 19:48:06 +0000 (12:48 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 15 May 2015 19:48:06 +0000 (12:48 -0700)
added patches:
acpica-tables-change-acpi_find_root_pointer-to-use-acpi_physical_address.patch
revert-softirq-add-support-for-triggering-softirq-work-on-softirqs.patch
sound-oss-fix-deadlock-in-sequencer_ioctl-sndctl_seq_outofband.patch

queue-3.10/acpica-tables-change-acpi_find_root_pointer-to-use-acpi_physical_address.patch [new file with mode: 0644]
queue-3.10/revert-softirq-add-support-for-triggering-softirq-work-on-softirqs.patch [new file with mode: 0644]
queue-3.10/series
queue-3.10/sound-oss-fix-deadlock-in-sequencer_ioctl-sndctl_seq_outofband.patch [new file with mode: 0644]

diff --git a/queue-3.10/acpica-tables-change-acpi_find_root_pointer-to-use-acpi_physical_address.patch b/queue-3.10/acpica-tables-change-acpi_find_root_pointer-to-use-acpi_physical_address.patch
new file mode 100644 (file)
index 0000000..87bdfc2
--- /dev/null
@@ -0,0 +1,75 @@
+From f254e3c57b9d952e987502aefa0804c177dd2503 Mon Sep 17 00:00:00 2001
+From: Lv Zheng <lv.zheng@intel.com>
+Date: Mon, 13 Apr 2015 11:48:18 +0800
+Subject: ACPICA: Tables: Change acpi_find_root_pointer() to use acpi_physical_address.
+
+From: Lv Zheng <lv.zheng@intel.com>
+
+commit f254e3c57b9d952e987502aefa0804c177dd2503 upstream.
+
+ACPICA commit 7d9fd64397d7c38899d3dc497525f6e6b044e0e3
+
+OSPMs like Linux expect an acpi_physical_address returning value from
+acpi_find_root_pointer(). This triggers warnings if sizeof (acpi_size) doesn't
+equal to sizeof (acpi_physical_address):
+  drivers/acpi/osl.c:275:3: warning: passing argument 1 of 'acpi_find_root_pointer' from incompatible pointer type [enabled by default]
+  In file included from include/acpi/acpi.h:64:0,
+                   from include/linux/acpi.h:36,
+                   from drivers/acpi/osl.c:41:
+  include/acpi/acpixf.h:433:1: note: expected 'acpi_size *' but argument is of type 'acpi_physical_address *'
+This patch corrects acpi_find_root_pointer().
+
+Link: https://github.com/acpica/acpica/commit/7d9fd643
+Signed-off-by: Lv Zheng <lv.zheng@intel.com>
+Signed-off-by: Bob Moore <robert.moore@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Dirk Behme <dirk.behme@gmail.com>
+Signed-off-by: George G. Davis <george_davis@mentor.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/acpica/tbxfroot.c |    7 ++++---
+ include/acpi/acpixf.h          |    2 +-
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/acpi/acpica/tbxfroot.c
++++ b/drivers/acpi/acpica/tbxfroot.c
+@@ -118,7 +118,7 @@ static acpi_status acpi_tb_validate_rsdp
+  *
+  ******************************************************************************/
+-acpi_status acpi_find_root_pointer(acpi_size *table_address)
++acpi_status acpi_find_root_pointer(acpi_physical_address * table_address)
+ {
+       u8 *table_ptr;
+       u8 *mem_rover;
+@@ -176,7 +176,8 @@ acpi_status acpi_find_root_pointer(acpi_
+                       physical_address +=
+                           (u32) ACPI_PTR_DIFF(mem_rover, table_ptr);
+-                      *table_address = physical_address;
++                      *table_address =
++                          (acpi_physical_address) physical_address;
+                       return_ACPI_STATUS(AE_OK);
+               }
+       }
+@@ -209,7 +210,7 @@ acpi_status acpi_find_root_pointer(acpi_
+                   (ACPI_HI_RSDP_WINDOW_BASE +
+                    ACPI_PTR_DIFF(mem_rover, table_ptr));
+-              *table_address = physical_address;
++              *table_address = (acpi_physical_address) physical_address;
+               return_ACPI_STATUS(AE_OK);
+       }
+--- a/include/acpi/acpixf.h
++++ b/include/acpi/acpixf.h
+@@ -177,7 +177,7 @@ acpi_status acpi_load_tables(void);
+  */
+ acpi_status acpi_reallocate_root_table(void);
+-acpi_status acpi_find_root_pointer(acpi_size *rsdp_address);
++acpi_status acpi_find_root_pointer(acpi_physical_address *rsdp_address);
+ acpi_status acpi_unload_table_id(acpi_owner_id id);
diff --git a/queue-3.10/revert-softirq-add-support-for-triggering-softirq-work-on-softirqs.patch b/queue-3.10/revert-softirq-add-support-for-triggering-softirq-work-on-softirqs.patch
new file mode 100644 (file)
index 0000000..c6664dc
--- /dev/null
@@ -0,0 +1,230 @@
+From fc21c0cff2f425891b28ff6fb6b03b325c977428 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@infradead.org>
+Date: Thu, 14 Nov 2013 14:32:06 -0800
+Subject: revert "softirq: Add support for triggering softirq work on softirqs"
+
+From: Christoph Hellwig <hch@infradead.org>
+
+commit fc21c0cff2f425891b28ff6fb6b03b325c977428 upstream.
+
+This commit was incomplete in that code to remove items from the per-cpu
+lists was missing and never acquired a user in the 5 years it has been in
+the tree.  We're going to implement what it seems to try to archive in a
+simpler way, and this code is in the way of doing so.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Cc: Jan Kara <jack@suse.cz>
+Cc: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Pan Xinhui <xinhuix.pan@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/interrupt.h |   22 -------
+ kernel/softirq.c          |  131 ----------------------------------------------
+ 2 files changed, 153 deletions(-)
+
+--- a/include/linux/interrupt.h
++++ b/include/linux/interrupt.h
+@@ -11,8 +11,6 @@
+ #include <linux/irqnr.h>
+ #include <linux/hardirq.h>
+ #include <linux/irqflags.h>
+-#include <linux/smp.h>
+-#include <linux/percpu.h>
+ #include <linux/hrtimer.h>
+ #include <linux/kref.h>
+ #include <linux/workqueue.h>
+@@ -488,15 +486,6 @@ extern void __raise_softirq_irqoff(unsig
+ extern void raise_softirq_irqoff(unsigned int nr);
+ extern void raise_softirq(unsigned int nr);
+-/* This is the worklist that queues up per-cpu softirq work.
+- *
+- * send_remote_sendirq() adds work to these lists, and
+- * the softirq handler itself dequeues from them.  The queues
+- * are protected by disabling local cpu interrupts and they must
+- * only be accessed by the local cpu that they are for.
+- */
+-DECLARE_PER_CPU(struct list_head [NR_SOFTIRQS], softirq_work_list);
+-
+ DECLARE_PER_CPU(struct task_struct *, ksoftirqd);
+ static inline struct task_struct *this_cpu_ksoftirqd(void)
+@@ -504,17 +493,6 @@ static inline struct task_struct *this_c
+       return this_cpu_read(ksoftirqd);
+ }
+-/* Try to send a softirq to a remote cpu.  If this cannot be done, the
+- * work will be queued to the local cpu.
+- */
+-extern void send_remote_softirq(struct call_single_data *cp, int cpu, int softirq);
+-
+-/* Like send_remote_softirq(), but the caller must disable local cpu interrupts
+- * and compute the current cpu, passed in as 'this_cpu'.
+- */
+-extern void __send_remote_softirq(struct call_single_data *cp, int cpu,
+-                                int this_cpu, int softirq);
+-
+ /* Tasklets --- multithreaded analogue of BHs.
+    Main feature differing them of generic softirqs: tasklet
+--- a/kernel/softirq.c
++++ b/kernel/softirq.c
+@@ -6,8 +6,6 @@
+  *    Distribute under GPLv2.
+  *
+  *    Rewritten. Old one was good in 2.2, but in 2.3 it was immoral. --ANK (990903)
+- *
+- *    Remote softirq infrastructure is by Jens Axboe.
+  */
+ #include <linux/export.h>
+@@ -620,146 +618,17 @@ void tasklet_hrtimer_init(struct tasklet
+ }
+ EXPORT_SYMBOL_GPL(tasklet_hrtimer_init);
+-/*
+- * Remote softirq bits
+- */
+-
+-DEFINE_PER_CPU(struct list_head [NR_SOFTIRQS], softirq_work_list);
+-EXPORT_PER_CPU_SYMBOL(softirq_work_list);
+-
+-static void __local_trigger(struct call_single_data *cp, int softirq)
+-{
+-      struct list_head *head = &__get_cpu_var(softirq_work_list[softirq]);
+-
+-      list_add_tail(&cp->list, head);
+-
+-      /* Trigger the softirq only if the list was previously empty.  */
+-      if (head->next == &cp->list)
+-              raise_softirq_irqoff(softirq);
+-}
+-
+-#ifdef CONFIG_USE_GENERIC_SMP_HELPERS
+-static void remote_softirq_receive(void *data)
+-{
+-      struct call_single_data *cp = data;
+-      unsigned long flags;
+-      int softirq;
+-
+-      softirq = *(int *)cp->info;
+-      local_irq_save(flags);
+-      __local_trigger(cp, softirq);
+-      local_irq_restore(flags);
+-}
+-
+-static int __try_remote_softirq(struct call_single_data *cp, int cpu, int softirq)
+-{
+-      if (cpu_online(cpu)) {
+-              cp->func = remote_softirq_receive;
+-              cp->info = &softirq;
+-              cp->flags = 0;
+-
+-              __smp_call_function_single(cpu, cp, 0);
+-              return 0;
+-      }
+-      return 1;
+-}
+-#else /* CONFIG_USE_GENERIC_SMP_HELPERS */
+-static int __try_remote_softirq(struct call_single_data *cp, int cpu, int softirq)
+-{
+-      return 1;
+-}
+-#endif
+-
+-/**
+- * __send_remote_softirq - try to schedule softirq work on a remote cpu
+- * @cp: private SMP call function data area
+- * @cpu: the remote cpu
+- * @this_cpu: the currently executing cpu
+- * @softirq: the softirq for the work
+- *
+- * Attempt to schedule softirq work on a remote cpu.  If this cannot be
+- * done, the work is instead queued up on the local cpu.
+- *
+- * Interrupts must be disabled.
+- */
+-void __send_remote_softirq(struct call_single_data *cp, int cpu, int this_cpu, int softirq)
+-{
+-      if (cpu == this_cpu || __try_remote_softirq(cp, cpu, softirq))
+-              __local_trigger(cp, softirq);
+-}
+-EXPORT_SYMBOL(__send_remote_softirq);
+-
+-/**
+- * send_remote_softirq - try to schedule softirq work on a remote cpu
+- * @cp: private SMP call function data area
+- * @cpu: the remote cpu
+- * @softirq: the softirq for the work
+- *
+- * Like __send_remote_softirq except that disabling interrupts and
+- * computing the current cpu is done for the caller.
+- */
+-void send_remote_softirq(struct call_single_data *cp, int cpu, int softirq)
+-{
+-      unsigned long flags;
+-      int this_cpu;
+-
+-      local_irq_save(flags);
+-      this_cpu = smp_processor_id();
+-      __send_remote_softirq(cp, cpu, this_cpu, softirq);
+-      local_irq_restore(flags);
+-}
+-EXPORT_SYMBOL(send_remote_softirq);
+-
+-static int __cpuinit remote_softirq_cpu_notify(struct notifier_block *self,
+-                                             unsigned long action, void *hcpu)
+-{
+-      /*
+-       * If a CPU goes away, splice its entries to the current CPU
+-       * and trigger a run of the softirq
+-       */
+-      if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) {
+-              int cpu = (unsigned long) hcpu;
+-              int i;
+-
+-              local_irq_disable();
+-              for (i = 0; i < NR_SOFTIRQS; i++) {
+-                      struct list_head *head = &per_cpu(softirq_work_list[i], cpu);
+-                      struct list_head *local_head;
+-
+-                      if (list_empty(head))
+-                              continue;
+-
+-                      local_head = &__get_cpu_var(softirq_work_list[i]);
+-                      list_splice_init(head, local_head);
+-                      raise_softirq_irqoff(i);
+-              }
+-              local_irq_enable();
+-      }
+-
+-      return NOTIFY_OK;
+-}
+-
+-static struct notifier_block __cpuinitdata remote_softirq_cpu_notifier = {
+-      .notifier_call  = remote_softirq_cpu_notify,
+-};
+-
+ void __init softirq_init(void)
+ {
+       int cpu;
+       for_each_possible_cpu(cpu) {
+-              int i;
+-
+               per_cpu(tasklet_vec, cpu).tail =
+                       &per_cpu(tasklet_vec, cpu).head;
+               per_cpu(tasklet_hi_vec, cpu).tail =
+                       &per_cpu(tasklet_hi_vec, cpu).head;
+-              for (i = 0; i < NR_SOFTIRQS; i++)
+-                      INIT_LIST_HEAD(&per_cpu(softirq_work_list[i], cpu));
+       }
+-      register_hotcpu_notifier(&remote_softirq_cpu_notifier);
+-
+       open_softirq(TASKLET_SOFTIRQ, tasklet_action);
+       open_softirq(HI_SOFTIRQ, tasklet_hi_action);
+ }
index b9837664e5b8b97bedbdb521881385eecca83e6f..00f40595b337fb64af135bfa373510c67e229ee2 100644 (file)
@@ -11,3 +11,6 @@ arm-mvebu-armada-xp-openblocks-ax3-4-disable-internal-rtc.patch
 drm-i915-add-missing-macbook-pro-models-with-dual-channel-lvds.patch
 pinctrl-don-t-just-pretend-to-protect-pinctrl_maps-do-it-for-real.patch
 mmc-card-don-t-access-rpmb-partitions-for-normal-read-write.patch
+sound-oss-fix-deadlock-in-sequencer_ioctl-sndctl_seq_outofband.patch
+revert-softirq-add-support-for-triggering-softirq-work-on-softirqs.patch
+acpica-tables-change-acpi_find_root_pointer-to-use-acpi_physical_address.patch
diff --git a/queue-3.10/sound-oss-fix-deadlock-in-sequencer_ioctl-sndctl_seq_outofband.patch b/queue-3.10/sound-oss-fix-deadlock-in-sequencer_ioctl-sndctl_seq_outofband.patch
new file mode 100644 (file)
index 0000000..6019b9a
--- /dev/null
@@ -0,0 +1,83 @@
+From bc26d4d06e337ade069f33d3f4377593b24e6e36 Mon Sep 17 00:00:00 2001
+From: Alexey Khoroshilov <khoroshilov@ispras.ru>
+Date: Sat, 18 Apr 2015 02:53:25 +0300
+Subject: sound/oss: fix deadlock in sequencer_ioctl(SNDCTL_SEQ_OUTOFBAND)
+
+From: Alexey Khoroshilov <khoroshilov@ispras.ru>
+
+commit bc26d4d06e337ade069f33d3f4377593b24e6e36 upstream.
+
+A deadlock can be initiated by userspace via ioctl(SNDCTL_SEQ_OUTOFBAND)
+on /dev/sequencer with TMR_ECHO midi event.
+
+In this case the control flow is:
+sound_ioctl()
+-> case SND_DEV_SEQ:
+   case SND_DEV_SEQ2:
+     sequencer_ioctl()
+     -> case SNDCTL_SEQ_OUTOFBAND:
+          spin_lock_irqsave(&lock,flags);
+          play_event();
+          -> case EV_TIMING:
+               seq_timing_event()
+               -> case TMR_ECHO:
+                    seq_copy_to_input()
+                    -> spin_lock_irqsave(&lock,flags);
+
+It seems that spin_lock_irqsave() around play_event() is not necessary,
+because the only other call location in seq_startplay() makes the call
+without acquiring spinlock.
+
+So, the patch just removes spinlocks around play_event().
+By the way, it removes unreachable code in seq_timing_event(),
+since (seq_mode == SEQ_2) case is handled in the beginning.
+
+Compile tested only.
+
+Found by Linux Driver Verification project (linuxtesting.org).
+
+Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Cc: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/oss/sequencer.c |   12 ++----------
+ 1 file changed, 2 insertions(+), 10 deletions(-)
+
+--- a/sound/oss/sequencer.c
++++ b/sound/oss/sequencer.c
+@@ -683,13 +683,8 @@ static int seq_timing_event(unsigned cha
+                       break;
+               case TMR_ECHO:
+-                      if (seq_mode == SEQ_2)
+-                              seq_copy_to_input(event_rec, 8);
+-                      else
+-                      {
+-                              parm = (parm << 8 | SEQ_ECHO);
+-                              seq_copy_to_input((unsigned char *) &parm, 4);
+-                      }
++                      parm = (parm << 8 | SEQ_ECHO);
++                      seq_copy_to_input((unsigned char *) &parm, 4);
+                       break;
+               default:;
+@@ -1332,7 +1327,6 @@ int sequencer_ioctl(int dev, struct file
+       int mode = translate_mode(file);
+       struct synth_info inf;
+       struct seq_event_rec event_rec;
+-      unsigned long flags;
+       int __user *p = arg;
+       orig_dev = dev = dev >> 4;
+@@ -1487,9 +1481,7 @@ int sequencer_ioctl(int dev, struct file
+               case SNDCTL_SEQ_OUTOFBAND:
+                       if (copy_from_user(&event_rec, arg, sizeof(event_rec)))
+                               return -EFAULT;
+-                      spin_lock_irqsave(&lock,flags);
+                       play_event(event_rec.arr);
+-                      spin_unlock_irqrestore(&lock,flags);
+                       return 0;
+               case SNDCTL_MIDI_INFO: