From: Greg Kroah-Hartman Date: Thu, 6 Feb 2014 23:09:54 +0000 (-0800) Subject: 3.10-stable patches X-Git-Tag: v3.4.80~88 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9c17324f7105dedf4216c8921980edcaba100c58;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: arch-sh-kernel-kgdb.c-add-missing-include-linux-sched.h.patch audit-correct-a-type-mismatch-in-audit_syscall_exit.patch audit-reset-audit-backlog-wait-time-after-error-recovery.patch ftrace-have-function-graph-only-trace-based-on-global_ops-filters.patch fuse-fix-pipe_buf_operations.patch intel-iommu-fix-off-by-one-in-pagetable-freeing.patch revert-eisa-initialize-device-before-its-resources.patch selinux-fix-memory-leak-upon-loading-policy.patch tracing-check-if-tracing-is-enabled-in-trace_puts.patch tracing-have-trace-buffer-point-back-to-trace_array.patch --- diff --git a/queue-3.10/arch-sh-kernel-kgdb.c-add-missing-include-linux-sched.h.patch b/queue-3.10/arch-sh-kernel-kgdb.c-add-missing-include-linux-sched.h.patch new file mode 100644 index 00000000000..27a040ee275 --- /dev/null +++ b/queue-3.10/arch-sh-kernel-kgdb.c-add-missing-include-linux-sched.h.patch @@ -0,0 +1,43 @@ +From 53a52f17d96c8d47c79a7dafa81426317e89c7c1 Mon Sep 17 00:00:00 2001 +From: Wanlong Gao +Date: Tue, 21 Jan 2014 15:48:41 -0800 +Subject: arch/sh/kernel/kgdb.c: add missing #include + +From: Wanlong Gao + +commit 53a52f17d96c8d47c79a7dafa81426317e89c7c1 upstream. + + arch/sh/kernel/kgdb.c: In function 'sleeping_thread_to_gdb_regs': + arch/sh/kernel/kgdb.c:225:32: error: implicit declaration of function 'task_stack_page' [-Werror=implicit-function-declaration] + arch/sh/kernel/kgdb.c:242:23: error: dereferencing pointer to incomplete type + arch/sh/kernel/kgdb.c:243:22: error: dereferencing pointer to incomplete type + arch/sh/kernel/kgdb.c: In function 'singlestep_trap_handler': + arch/sh/kernel/kgdb.c:310:27: error: 'SIGTRAP' undeclared (first use in this function) + arch/sh/kernel/kgdb.c:310:27: note: each undeclared identifier is reported only once for each function it appears in + +This was introduced by commit 16559ae48c76 ("kgdb: remove #include + from kgdb.h"). + +[geert@linux-m68k.org: reworded and reformatted] +Signed-off-by: Wanlong Gao +Signed-off-by: Geert Uytterhoeven +Reported-by: Fengguang Wu +Acked-by: Greg Kroah-Hartman +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/sh/kernel/kgdb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/sh/kernel/kgdb.c ++++ b/arch/sh/kernel/kgdb.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + diff --git a/queue-3.10/audit-correct-a-type-mismatch-in-audit_syscall_exit.patch b/queue-3.10/audit-correct-a-type-mismatch-in-audit_syscall_exit.patch new file mode 100644 index 00000000000..2d680e4f2c7 --- /dev/null +++ b/queue-3.10/audit-correct-a-type-mismatch-in-audit_syscall_exit.patch @@ -0,0 +1,39 @@ +From 06bdadd7634551cfe8ce071fe44d0311b3033d9e Mon Sep 17 00:00:00 2001 +From: AKASHI Takahiro +Date: Mon, 13 Jan 2014 13:33:09 -0800 +Subject: audit: correct a type mismatch in audit_syscall_exit() + +From: AKASHI Takahiro + +commit 06bdadd7634551cfe8ce071fe44d0311b3033d9e upstream. + +audit_syscall_exit() saves a result of regs_return_value() in intermediate +"int" variable and passes it to __audit_syscall_exit(), which expects its +second argument as a "long" value. This will result in truncating the +value returned by a system call and making a wrong audit record. + +I don't know why gcc compiler doesn't complain about this, but anyway it +causes a problem at runtime on arm64 (and probably most 64-bit archs). + +Signed-off-by: AKASHI Takahiro +Cc: Al Viro +Cc: Eric Paris +Signed-off-by: Andrew Morton +Signed-off-by: Eric Paris +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/audit.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/audit.h ++++ b/include/linux/audit.h +@@ -135,7 +135,7 @@ static inline void audit_syscall_exit(vo + { + if (unlikely(current->audit_context)) { + int success = is_syscall_success(pt_regs); +- int return_code = regs_return_value(pt_regs); ++ long return_code = regs_return_value(pt_regs); + + __audit_syscall_exit(success, return_code); + } diff --git a/queue-3.10/audit-reset-audit-backlog-wait-time-after-error-recovery.patch b/queue-3.10/audit-reset-audit-backlog-wait-time-after-error-recovery.patch new file mode 100644 index 00000000000..351efcb07aa --- /dev/null +++ b/queue-3.10/audit-reset-audit-backlog-wait-time-after-error-recovery.patch @@ -0,0 +1,48 @@ +From e789e561a50de0aaa8c695662d97aaa5eac9d55f Mon Sep 17 00:00:00 2001 +From: Richard Guy Briggs +Date: Thu, 12 Sep 2013 23:03:51 -0400 +Subject: audit: reset audit backlog wait time after error recovery + +From: Richard Guy Briggs + +commit e789e561a50de0aaa8c695662d97aaa5eac9d55f upstream. + +When the audit queue overflows and times out (audit_backlog_wait_time), the +audit queue overflow timeout is set to zero. Once the audit queue overflow +timeout condition recovers, the timeout should be reset to the original value. + +See also: + https://lkml.org/lkml/2013/9/2/473 + +Signed-off-by: Luiz Capitulino +Signed-off-by: Dan Duval +Signed-off-by: Chuck Anderson +Signed-off-by: Richard Guy Briggs +Signed-off-by: Eric Paris +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/audit.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/kernel/audit.c ++++ b/kernel/audit.c +@@ -103,7 +103,8 @@ static int audit_rate_limit; + + /* Number of outstanding audit_buffers allowed. */ + static int audit_backlog_limit = 64; +-static int audit_backlog_wait_time = 60 * HZ; ++#define AUDIT_BACKLOG_WAIT_TIME (60 * HZ) ++static int audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME; + static int audit_backlog_wait_overflow = 0; + + /* The identity of the user shutting down the audit system. */ +@@ -1135,6 +1136,8 @@ struct audit_buffer *audit_log_start(str + return NULL; + } + ++ audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME; ++ + ab = audit_buffer_alloc(ctx, gfp_mask, type); + if (!ab) { + audit_log_lost("out of memory in audit_log_start"); diff --git a/queue-3.10/ftrace-have-function-graph-only-trace-based-on-global_ops-filters.patch b/queue-3.10/ftrace-have-function-graph-only-trace-based-on-global_ops-filters.patch new file mode 100644 index 00000000000..7826b4642ad --- /dev/null +++ b/queue-3.10/ftrace-have-function-graph-only-trace-based-on-global_ops-filters.patch @@ -0,0 +1,184 @@ +From 23a8e8441a0a74dd612edf81dc89d1600bc0a3d1 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Red Hat)" +Date: Mon, 13 Jan 2014 10:30:23 -0500 +Subject: ftrace: Have function graph only trace based on global_ops filters + +From: "Steven Rostedt (Red Hat)" + +commit 23a8e8441a0a74dd612edf81dc89d1600bc0a3d1 upstream. + +Doing some different tests, I discovered that function graph tracing, when +filtered via the set_ftrace_filter and set_ftrace_notrace files, does +not always keep with them if another function ftrace_ops is registered +to trace functions. + +The reason is that function graph just happens to trace all functions +that the function tracer enables. When there was only one user of +function tracing, the function graph tracer did not need to worry about +being called by functions that it did not want to trace. But now that there +are other users, this becomes a problem. + +For example, one just needs to do the following: + + # cd /sys/kernel/debug/tracing + # echo schedule > set_ftrace_filter + # echo function_graph > current_tracer + # cat trace +[..] + 0) | schedule() { + ------------------------------------------ + 0) -0 => rcu_pre-7 + ------------------------------------------ + + 0) ! 2980.314 us | } + 0) | schedule() { + ------------------------------------------ + 0) rcu_pre-7 => -0 + ------------------------------------------ + + 0) + 20.701 us | } + + # echo 1 > /proc/sys/kernel/stack_tracer_enabled + # cat trace +[..] + 1) + 20.825 us | } + 1) + 21.651 us | } + 1) + 30.924 us | } /* SyS_ioctl */ + 1) | do_page_fault() { + 1) | __do_page_fault() { + 1) 0.274 us | down_read_trylock(); + 1) 0.098 us | find_vma(); + 1) | handle_mm_fault() { + 1) | _raw_spin_lock() { + 1) 0.102 us | preempt_count_add(); + 1) 0.097 us | do_raw_spin_lock(); + 1) 2.173 us | } + 1) | do_wp_page() { + 1) 0.079 us | vm_normal_page(); + 1) 0.086 us | reuse_swap_page(); + 1) 0.076 us | page_move_anon_rmap(); + 1) | unlock_page() { + 1) 0.082 us | page_waitqueue(); + 1) 0.086 us | __wake_up_bit(); + 1) 1.801 us | } + 1) 0.075 us | ptep_set_access_flags(); + 1) | _raw_spin_unlock() { + 1) 0.098 us | do_raw_spin_unlock(); + 1) 0.105 us | preempt_count_sub(); + 1) 1.884 us | } + 1) 9.149 us | } + 1) + 13.083 us | } + 1) 0.146 us | up_read(); + +When the stack tracer was enabled, it enabled all functions to be traced, which +now the function graph tracer also traces. This is a side effect that should +not occur. + +To fix this a test is added when the function tracing is changed, as well as when +the graph tracer is enabled, to see if anything other than the ftrace global_ops +function tracer is enabled. If so, then the graph tracer calls a test trampoline +that will look at the function that is being traced and compare it with the +filters defined by the global_ops. + +As an optimization, if there's no other function tracers registered, or if +the only registered function tracers also use the global ops, the function +graph infrastructure will call the registered function graph callback directly +and not go through the test trampoline. + +Fixes: d2d45c7a03a2 "tracing: Have stack_tracer use a separate list of functions" +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/ftrace.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 44 insertions(+), 1 deletion(-) + +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -278,6 +278,12 @@ static void update_global_ops(void) + global_ops.func = func; + } + ++#ifdef CONFIG_FUNCTION_GRAPH_TRACER ++static void update_function_graph_func(void); ++#else ++static inline void update_function_graph_func(void) { } ++#endif ++ + static void update_ftrace_function(void) + { + ftrace_func_t func; +@@ -325,6 +331,8 @@ static int remove_ftrace_ops(struct ftra + { + struct ftrace_ops **p; + ++ update_function_graph_func(); ++ + /* + * If we are removing the last function, then simply point + * to the ftrace_stub. +@@ -4728,6 +4736,7 @@ int ftrace_graph_entry_stub(struct ftrac + trace_func_graph_ret_t ftrace_graph_return = + (trace_func_graph_ret_t)ftrace_stub; + trace_func_graph_ent_t ftrace_graph_entry = ftrace_graph_entry_stub; ++static trace_func_graph_ent_t __ftrace_graph_entry = ftrace_graph_entry_stub; + + /* Try to assign a return stack array on FTRACE_RETSTACK_ALLOC_SIZE tasks. */ + static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) +@@ -4869,6 +4878,30 @@ static struct ftrace_ops fgraph_ops __re + FTRACE_OPS_FL_RECURSION_SAFE, + }; + ++static int ftrace_graph_entry_test(struct ftrace_graph_ent *trace) ++{ ++ if (!ftrace_ops_test(&global_ops, trace->func, NULL)) ++ return 0; ++ return __ftrace_graph_entry(trace); ++} ++ ++/* ++ * The function graph tracer should only trace the functions defined ++ * by set_ftrace_filter and set_ftrace_notrace. If another function ++ * tracer ops is registered, the graph tracer requires testing the ++ * function against the global ops, and not just trace any function ++ * that any ftrace_ops registered. ++ */ ++static void update_function_graph_func(void) ++{ ++ if (ftrace_ops_list == &ftrace_list_end || ++ (ftrace_ops_list == &global_ops && ++ global_ops.next == &ftrace_list_end)) ++ ftrace_graph_entry = __ftrace_graph_entry; ++ else ++ ftrace_graph_entry = ftrace_graph_entry_test; ++} ++ + int register_ftrace_graph(trace_func_graph_ret_t retfunc, + trace_func_graph_ent_t entryfunc) + { +@@ -4893,7 +4926,16 @@ int register_ftrace_graph(trace_func_gra + } + + ftrace_graph_return = retfunc; +- ftrace_graph_entry = entryfunc; ++ ++ /* ++ * Update the indirect function to the entryfunc, and the ++ * function that gets called to the entry_test first. Then ++ * call the update fgraph entry function to determine if ++ * the entryfunc should be called directly or not. ++ */ ++ __ftrace_graph_entry = entryfunc; ++ ftrace_graph_entry = ftrace_graph_entry_test; ++ update_function_graph_func(); + + ret = ftrace_startup(&fgraph_ops, FTRACE_START_FUNC_RET); + +@@ -4912,6 +4954,7 @@ void unregister_ftrace_graph(void) + ftrace_graph_active--; + ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub; + ftrace_graph_entry = ftrace_graph_entry_stub; ++ __ftrace_graph_entry = ftrace_graph_entry_stub; + ftrace_shutdown(&fgraph_ops, FTRACE_STOP_FUNC_RET); + unregister_pm_notifier(&ftrace_suspend_notifier); + unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL); diff --git a/queue-3.10/fuse-fix-pipe_buf_operations.patch b/queue-3.10/fuse-fix-pipe_buf_operations.patch new file mode 100644 index 00000000000..f7bd8d784ab --- /dev/null +++ b/queue-3.10/fuse-fix-pipe_buf_operations.patch @@ -0,0 +1,152 @@ +From 28a625cbc2a14f17b83e47ef907b2658576a32aa Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Wed, 22 Jan 2014 19:36:57 +0100 +Subject: fuse: fix pipe_buf_operations + +From: Miklos Szeredi + +commit 28a625cbc2a14f17b83e47ef907b2658576a32aa upstream. + +Having this struct in module memory could Oops when if the module is +unloaded while the buffer still persists in a pipe. + +Since sock_pipe_buf_ops is essentially the same as fuse_dev_pipe_buf_steal +merge them into nosteal_pipe_buf_ops (this is the same as +default_pipe_buf_ops except stealing the page from the buffer is not +allowed). + +Reported-by: Al Viro +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fuse/dev.c | 22 +++++----------------- + fs/splice.c | 18 ++++++++++++++++++ + include/linux/pipe_fs_i.h | 2 ++ + net/core/skbuff.c | 32 +------------------------------- + 4 files changed, 26 insertions(+), 48 deletions(-) + +--- a/fs/fuse/dev.c ++++ b/fs/fuse/dev.c +@@ -1296,22 +1296,6 @@ static ssize_t fuse_dev_read(struct kioc + return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs)); + } + +-static int fuse_dev_pipe_buf_steal(struct pipe_inode_info *pipe, +- struct pipe_buffer *buf) +-{ +- return 1; +-} +- +-static const struct pipe_buf_operations fuse_dev_pipe_buf_ops = { +- .can_merge = 0, +- .map = generic_pipe_buf_map, +- .unmap = generic_pipe_buf_unmap, +- .confirm = generic_pipe_buf_confirm, +- .release = generic_pipe_buf_release, +- .steal = fuse_dev_pipe_buf_steal, +- .get = generic_pipe_buf_get, +-}; +- + static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, + size_t len, unsigned int flags) +@@ -1358,7 +1342,11 @@ static ssize_t fuse_dev_splice_read(stru + buf->page = bufs[page_nr].page; + buf->offset = bufs[page_nr].offset; + buf->len = bufs[page_nr].len; +- buf->ops = &fuse_dev_pipe_buf_ops; ++ /* ++ * Need to be careful about this. Having buf->ops in module ++ * code can Oops if the buffer persists after module unload. ++ */ ++ buf->ops = &nosteal_pipe_buf_ops; + + pipe->nrbufs++; + page_nr++; +--- a/fs/splice.c ++++ b/fs/splice.c +@@ -555,6 +555,24 @@ static const struct pipe_buf_operations + .get = generic_pipe_buf_get, + }; + ++static int generic_pipe_buf_nosteal(struct pipe_inode_info *pipe, ++ struct pipe_buffer *buf) ++{ ++ return 1; ++} ++ ++/* Pipe buffer operations for a socket and similar. */ ++const struct pipe_buf_operations nosteal_pipe_buf_ops = { ++ .can_merge = 0, ++ .map = generic_pipe_buf_map, ++ .unmap = generic_pipe_buf_unmap, ++ .confirm = generic_pipe_buf_confirm, ++ .release = generic_pipe_buf_release, ++ .steal = generic_pipe_buf_nosteal, ++ .get = generic_pipe_buf_get, ++}; ++EXPORT_SYMBOL(nosteal_pipe_buf_ops); ++ + static ssize_t kernel_readv(struct file *file, const struct iovec *vec, + unsigned long vlen, loff_t offset) + { +--- a/include/linux/pipe_fs_i.h ++++ b/include/linux/pipe_fs_i.h +@@ -157,6 +157,8 @@ int generic_pipe_buf_confirm(struct pipe + int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); + void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *); + ++extern const struct pipe_buf_operations nosteal_pipe_buf_ops; ++ + /* for F_SETPIPE_SZ and F_GETPIPE_SZ */ + long pipe_fcntl(struct file *, unsigned int, unsigned long arg); + struct pipe_inode_info *get_pipe_info(struct file *file); +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -74,36 +74,6 @@ + struct kmem_cache *skbuff_head_cache __read_mostly; + static struct kmem_cache *skbuff_fclone_cache __read_mostly; + +-static void sock_pipe_buf_release(struct pipe_inode_info *pipe, +- struct pipe_buffer *buf) +-{ +- put_page(buf->page); +-} +- +-static void sock_pipe_buf_get(struct pipe_inode_info *pipe, +- struct pipe_buffer *buf) +-{ +- get_page(buf->page); +-} +- +-static int sock_pipe_buf_steal(struct pipe_inode_info *pipe, +- struct pipe_buffer *buf) +-{ +- return 1; +-} +- +- +-/* Pipe buffer operations for a socket. */ +-static const struct pipe_buf_operations sock_pipe_buf_ops = { +- .can_merge = 0, +- .map = generic_pipe_buf_map, +- .unmap = generic_pipe_buf_unmap, +- .confirm = generic_pipe_buf_confirm, +- .release = sock_pipe_buf_release, +- .steal = sock_pipe_buf_steal, +- .get = sock_pipe_buf_get, +-}; +- + /** + * skb_panic - private function for out-of-line support + * @skb: buffer +@@ -1811,7 +1781,7 @@ int skb_splice_bits(struct sk_buff *skb, + .partial = partial, + .nr_pages_max = MAX_SKB_FRAGS, + .flags = flags, +- .ops = &sock_pipe_buf_ops, ++ .ops = &nosteal_pipe_buf_ops, + .spd_release = sock_spd_release, + }; + struct sk_buff *frag_iter; diff --git a/queue-3.10/intel-iommu-fix-off-by-one-in-pagetable-freeing.patch b/queue-3.10/intel-iommu-fix-off-by-one-in-pagetable-freeing.patch new file mode 100644 index 00000000000..86e14c028e5 --- /dev/null +++ b/queue-3.10/intel-iommu-fix-off-by-one-in-pagetable-freeing.patch @@ -0,0 +1,61 @@ +From 08336fd218e087cc4fcc458e6b6dcafe8702b098 Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Tue, 21 Jan 2014 15:48:18 -0800 +Subject: intel-iommu: fix off-by-one in pagetable freeing + +From: Alex Williamson + +commit 08336fd218e087cc4fcc458e6b6dcafe8702b098 upstream. + +dma_pte_free_level() has an off-by-one error when checking whether a pte +is completely covered by a range. Take for example the case of +attempting to free pfn 0x0 - 0x1ff, ie. 512 entries covering the first +2M superpage. + +The level_size() is 0x200 and we test: + + static void dma_pte_free_level(... + ... + + if (!(0 > 0 || 0x1ff < 0 + 0x200)) { + ... + } + +Clearly the 2nd test is true, which means we fail to take the branch to +clear and free the pagetable entry. As a result, we're leaking +pagetables and failing to install new pages over the range. + +This was found with a PCI device assigned to a QEMU guest using vfio-pci +without a VGA device present. The first 1M of guest address space is +mapped with various combinations of 4K pages, but eventually the range +is entirely freed and replaced with a 2M contiguous mapping. +intel-iommu errors out with something like: + + ERROR: DMA PTE for vPFN 0x0 already set (to 5c2b8003 not 849c00083) + +In this case 5c2b8003 is the pointer to the previous leaf page that was +neither freed nor cleared and 849c00083 is the superpage entry that +we're trying to replace it with. + +Signed-off-by: Alex Williamson +Cc: David Woodhouse +Cc: Joerg Roedel +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/intel-iommu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -917,7 +917,7 @@ static void dma_pte_free_level(struct dm + + /* If range covers entire pagetable, free it */ + if (!(start_pfn > level_pfn || +- last_pfn < level_pfn + level_size(level))) { ++ last_pfn < level_pfn + level_size(level) - 1)) { + dma_clear_pte(pte); + domain_flush_cache(domain, pte, sizeof(*pte)); + free_pgtable_page(level_pte); diff --git a/queue-3.10/revert-eisa-initialize-device-before-its-resources.patch b/queue-3.10/revert-eisa-initialize-device-before-its-resources.patch new file mode 100644 index 00000000000..6de968b6a61 --- /dev/null +++ b/queue-3.10/revert-eisa-initialize-device-before-its-resources.patch @@ -0,0 +1,96 @@ +From 765ee51f9a3f652959b4c7297d198a28e37952b4 Mon Sep 17 00:00:00 2001 +From: Bjorn Helgaas +Date: Fri, 17 Jan 2014 14:57:29 -0700 +Subject: Revert "EISA: Initialize device before its resources" + +From: Bjorn Helgaas + +commit 765ee51f9a3f652959b4c7297d198a28e37952b4 upstream. + +This reverts commit 26abfeed4341872364386c6a52b9acef8c81a81a. + +In the eisa_probe() force_probe path, if we were unable to request slot +resources (e.g., [io 0x800-0x8ff]), we skipped the slot with "Cannot +allocate resource for EISA slot %d" before reading the EISA signature in +eisa_init_device(). + +Commit 26abfeed4341 moved eisa_init_device() earlier, so we tried to read +the EISA signature before requesting the slot resources, and this caused +hangs during boot. + +Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1251816 +Signed-off-by: Bjorn Helgaas +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/eisa/eisa-bus.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +--- a/drivers/eisa/eisa-bus.c ++++ b/drivers/eisa/eisa-bus.c +@@ -275,11 +275,13 @@ static int __init eisa_request_resources + } + + if (slot) { ++ edev->res[i].name = NULL; + edev->res[i].start = SLOT_ADDRESS(root, slot) + + (i * 0x400); + edev->res[i].end = edev->res[i].start + 0xff; + edev->res[i].flags = IORESOURCE_IO; + } else { ++ edev->res[i].name = NULL; + edev->res[i].start = SLOT_ADDRESS(root, slot) + + EISA_VENDOR_ID_OFFSET; + edev->res[i].end = edev->res[i].start + 3; +@@ -326,19 +328,20 @@ static int __init eisa_probe(struct eisa + return -ENOMEM; + } + +- if (eisa_init_device(root, edev, 0)) { ++ if (eisa_request_resources(root, edev, 0)) { ++ dev_warn(root->dev, ++ "EISA: Cannot allocate resource for mainboard\n"); + kfree(edev); + if (!root->force_probe) +- return -ENODEV; ++ return -EBUSY; + goto force_probe; + } + +- if (eisa_request_resources(root, edev, 0)) { +- dev_warn(root->dev, +- "EISA: Cannot allocate resource for mainboard\n"); ++ if (eisa_init_device(root, edev, 0)) { ++ eisa_release_resources(edev); + kfree(edev); + if (!root->force_probe) +- return -EBUSY; ++ return -ENODEV; + goto force_probe; + } + +@@ -361,11 +364,6 @@ static int __init eisa_probe(struct eisa + continue; + } + +- if (eisa_init_device(root, edev, i)) { +- kfree(edev); +- continue; +- } +- + if (eisa_request_resources(root, edev, i)) { + dev_warn(root->dev, + "Cannot allocate resource for EISA slot %d\n", +@@ -373,6 +371,12 @@ static int __init eisa_probe(struct eisa + kfree(edev); + continue; + } ++ ++ if (eisa_init_device(root, edev, i)) { ++ eisa_release_resources(edev); ++ kfree(edev); ++ continue; ++ } + + if (edev->state == (EISA_CONFIG_ENABLED | EISA_CONFIG_FORCED)) + enabled_str = " (forced enabled)"; diff --git a/queue-3.10/selinux-fix-memory-leak-upon-loading-policy.patch b/queue-3.10/selinux-fix-memory-leak-upon-loading-policy.patch new file mode 100644 index 00000000000..373ee438ed0 --- /dev/null +++ b/queue-3.10/selinux-fix-memory-leak-upon-loading-policy.patch @@ -0,0 +1,79 @@ +From 8ed814602876bec9bad2649ca17f34b499357a1c Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Mon, 6 Jan 2014 21:28:15 +0900 +Subject: SELinux: Fix memory leak upon loading policy + +From: Tetsuo Handa + +commit 8ed814602876bec9bad2649ca17f34b499357a1c upstream. + +Hello. + +I got below leak with linux-3.10.0-54.0.1.el7.x86_64 . + +[ 681.903890] kmemleak: 5538 new suspected memory leaks (see /sys/kernel/debug/kmemleak) + +Below is a patch, but I don't know whether we need special handing for undoing +ebitmap_set_bit() call. +---------- +>>From fe97527a90fe95e2239dfbaa7558f0ed559c0992 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Mon, 6 Jan 2014 16:30:21 +0900 +Subject: SELinux: Fix memory leak upon loading policy + +Commit 2463c26d "SELinux: put name based create rules in a hashtable" did not +check return value from hashtab_insert() in filename_trans_read(). It leaks +memory if hashtab_insert() returns error. + + unreferenced object 0xffff88005c9160d0 (size 8): + comm "systemd", pid 1, jiffies 4294688674 (age 235.265s) + hex dump (first 8 bytes): + 57 0b 00 00 6b 6b 6b a5 W...kkk. + backtrace: + [] kmemleak_alloc+0x4e/0xb0 + [] kmem_cache_alloc_trace+0x12e/0x360 + [] policydb_read+0xd1d/0xf70 + [] security_load_policy+0x6c/0x500 + [] sel_write_load+0xac/0x750 + [] vfs_write+0xc0/0x1f0 + [] SyS_write+0x4c/0xa0 + [] system_call_fastpath+0x16/0x1b + [] 0xffffffffffffffff + +However, we should not return EEXIST error to the caller, or the systemd will +show below message and the boot sequence freezes. + + systemd[1]: Failed to load SELinux policy. Freezing. + +Signed-off-by: Tetsuo Handa +Acked-by: Eric Paris +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + security/selinux/ss/policydb.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +--- a/security/selinux/ss/policydb.c ++++ b/security/selinux/ss/policydb.c +@@ -1941,7 +1941,19 @@ static int filename_trans_read(struct po + if (rc) + goto out; + +- hashtab_insert(p->filename_trans, ft, otype); ++ rc = hashtab_insert(p->filename_trans, ft, otype); ++ if (rc) { ++ /* ++ * Do not return -EEXIST to the caller, or the system ++ * will not boot. ++ */ ++ if (rc != -EEXIST) ++ goto out; ++ /* But free memory to avoid memory leak. */ ++ kfree(ft); ++ kfree(name); ++ kfree(otype); ++ } + } + hash_eval(p->filename_trans, "filenametr"); + return 0; diff --git a/queue-3.10/series b/queue-3.10/series new file mode 100644 index 00000000000..033377071be --- /dev/null +++ b/queue-3.10/series @@ -0,0 +1,10 @@ +selinux-fix-memory-leak-upon-loading-policy.patch +ftrace-have-function-graph-only-trace-based-on-global_ops-filters.patch +tracing-have-trace-buffer-point-back-to-trace_array.patch +tracing-check-if-tracing-is-enabled-in-trace_puts.patch +arch-sh-kernel-kgdb.c-add-missing-include-linux-sched.h.patch +intel-iommu-fix-off-by-one-in-pagetable-freeing.patch +revert-eisa-initialize-device-before-its-resources.patch +fuse-fix-pipe_buf_operations.patch +audit-reset-audit-backlog-wait-time-after-error-recovery.patch +audit-correct-a-type-mismatch-in-audit_syscall_exit.patch diff --git a/queue-3.10/tracing-check-if-tracing-is-enabled-in-trace_puts.patch b/queue-3.10/tracing-check-if-tracing-is-enabled-in-trace_puts.patch new file mode 100644 index 00000000000..33c77bf45dc --- /dev/null +++ b/queue-3.10/tracing-check-if-tracing-is-enabled-in-trace_puts.patch @@ -0,0 +1,44 @@ +From 3132e107d608f8753240d82d61303c500fd515b4 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Red Hat)" +Date: Thu, 23 Jan 2014 12:27:59 -0500 +Subject: tracing: Check if tracing is enabled in trace_puts() + +From: "Steven Rostedt (Red Hat)" + +commit 3132e107d608f8753240d82d61303c500fd515b4 upstream. + +If trace_puts() is used very early in boot up, it can crash the machine +if it is called before the ring buffer is allocated. If a trace_printk() +is used with no arguments, then it will be converted into a trace_puts() +and suffer the same fate. + +Fixes: 09ae72348ecc "tracing: Add trace_puts() for even faster trace_printk() tracing" +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -424,6 +424,9 @@ int __trace_puts(unsigned long ip, const + unsigned long irq_flags; + int alloc; + ++ if (unlikely(tracing_selftest_running || tracing_disabled)) ++ return 0; ++ + alloc = sizeof(*entry) + size + 2; /* possible \n added */ + + local_save_flags(irq_flags); +@@ -464,6 +467,9 @@ int __trace_bputs(unsigned long ip, cons + unsigned long irq_flags; + int size = sizeof(struct bputs_entry); + ++ if (unlikely(tracing_selftest_running || tracing_disabled)) ++ return 0; ++ + local_save_flags(irq_flags); + buffer = global_trace.trace_buffer.buffer; + event = trace_buffer_lock_reserve(buffer, TRACE_BPUTS, size, diff --git a/queue-3.10/tracing-have-trace-buffer-point-back-to-trace_array.patch b/queue-3.10/tracing-have-trace-buffer-point-back-to-trace_array.patch new file mode 100644 index 00000000000..4d4d2754cb5 --- /dev/null +++ b/queue-3.10/tracing-have-trace-buffer-point-back-to-trace_array.patch @@ -0,0 +1,36 @@ +From dced341b2d4f06668efaab33f88de5d287c0f45b Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Red Hat)" +Date: Tue, 14 Jan 2014 10:19:46 -0500 +Subject: tracing: Have trace buffer point back to trace_array + +From: "Steven Rostedt (Red Hat)" + +commit dced341b2d4f06668efaab33f88de5d287c0f45b upstream. + +The trace buffer has a descriptor pointer that goes back to the trace +array. But it was never assigned. Luckily, nothing uses it (yet), but +it will in the future. + +Although nothing currently uses this, if any of the new features get +backported to older kernels, and because this is such a simple change, +I'm marking it for stable too. + +Fixes: 12883efb670c "tracing: Consolidate max_tr into main trace_array structure" +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -5878,6 +5878,8 @@ allocate_trace_buffer(struct trace_array + + rb_flags = trace_flags & TRACE_ITER_OVERWRITE ? RB_FL_OVERWRITE : 0; + ++ buf->tr = tr; ++ + buf->buffer = ring_buffer_alloc(size, rb_flags); + if (!buf->buffer) + return -ENOMEM;