add stack patches

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
diff --git a/queue/dma-api-Teach-the-DMA-from-stack-check-about-vmapped.patch b/queue/dma-api-Teach-the-DMA-from-stack-check-about-vmapped.patch
new file mode 100644
index 0000000..b308073
--- /dev/null
+++ b/queue/dma-api-Teach-the-DMA-from-stack-check-about-vmapped.patch
@@ -0,0 +1,108 @@
+From b4a0f533e5976cb1a79f31d6152e1d322d79b7f1 Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@kernel.org>
+Date: Thu, 11 Aug 2016 02:35:22 -0700
+Subject: [PATCH] dma-api: Teach the "DMA-from-stack" check about vmapped
+ stacks
+
+commit b4a0f533e5976cb1a79f31d6152e1d322d79b7f1 upstream.
+
+If we're using CONFIG_VMAP_STACK=y and we manage to point an sg entry
+at the stack, then either the sg page will be in highmem or sg_virt()
+will return the direct-map alias.  In neither case will the existing
+check_for_stack() implementation realize that it's a stack page.
+
+Fix it by explicitly checking for stack pages.
+
+This has no effect by itself.  It's broken out for ease of review.
+
+Signed-off-by: Andy Lutomirski <luto@kernel.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Brian Gerst <brgerst@gmail.com>
+Cc: Denys Vlasenko <dvlasenk@redhat.com>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Link: http://lkml.kernel.org/r/448460622731312298bf19dcbacb1606e75de7a9.1470907718.git.luto@kernel.org
+[ Minor edits. ]
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+
+diff --git a/lib/dma-debug.c b/lib/dma-debug.c
+index fcfa1939ac41..06f02f6aecd2 100644
+--- a/lib/dma-debug.c
++++ b/lib/dma-debug.c
+@@ -22,6 +22,7 @@
+ #include <linux/stacktrace.h>
+ #include <linux/dma-debug.h>
+ #include <linux/spinlock.h>
++#include <linux/vmalloc.h>
+ #include <linux/debugfs.h>
+ #include <linux/uaccess.h>
+ #include <linux/export.h>
+@@ -1164,11 +1165,32 @@ static void check_unmap(struct dma_debug_entry *ref)
+ 	put_hash_bucket(bucket, &flags);
+ }
+ 
+-static void check_for_stack(struct device *dev, void *addr)
++static void check_for_stack(struct device *dev,
++			    struct page *page, size_t offset)
+ {
+-	if (object_is_on_stack(addr))
+-		err_printk(dev, NULL, "DMA-API: device driver maps memory from "
+-				"stack [addr=%p]\n", addr);
++	void *addr;
++	struct vm_struct *stack_vm_area = task_stack_vm_area(current);
++
++	if (!stack_vm_area) {
++		/* Stack is direct-mapped. */
++		if (PageHighMem(page))
++			return;
++		addr = page_address(page) + offset;
++		if (object_is_on_stack(addr))
++			err_printk(dev, NULL, "DMA-API: device driver maps memory from stack [addr=%p]\n", addr);
++	} else {
++		/* Stack is vmalloced. */
++		int i;
++
++		for (i = 0; i < stack_vm_area->nr_pages; i++) {
++			if (page != stack_vm_area->pages[i])
++				continue;
++
++			addr = (u8 *)current->stack + i * PAGE_SIZE + offset;
++			err_printk(dev, NULL, "DMA-API: device driver maps memory from stack [probable addr=%p]\n", addr);
++			break;
++		}
++	}
+ }
+ 
+ static inline bool overlap(void *addr, unsigned long len, void *start, void *end)
+@@ -1291,10 +1313,11 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset,
+ 	if (map_single)
+ 		entry->type = dma_debug_single;
+ 
++	check_for_stack(dev, page, offset);
++
+ 	if (!PageHighMem(page)) {
+ 		void *addr = page_address(page) + offset;
+ 
+-		check_for_stack(dev, addr);
+ 		check_for_illegal_area(dev, addr, size);
+ 	}
+ 
+@@ -1386,8 +1409,9 @@ void debug_dma_map_sg(struct device *dev, struct scatterlist *sg,
+ 		entry->sg_call_ents   = nents;
+ 		entry->sg_mapped_ents = mapped_ents;
+ 
++		check_for_stack(dev, sg_page(s), s->offset);
++
+ 		if (!PageHighMem(sg_page(s))) {
+-			check_for_stack(dev, sg_virt(s));
+ 			check_for_illegal_area(dev, sg_virt(s), sg_dma_len(s));
+ 		}
+ 
+-- 
+2.15.0
+
diff --git a/queue/iommu-amd-Don-t-put-completion-wait-semaphore-on-sta.patch b/queue/iommu-amd-Don-t-put-completion-wait-semaphore-on-sta.patch
new file mode 100644
index 0000000..9f9e30b
--- /dev/null
+++ b/queue/iommu-amd-Don-t-put-completion-wait-semaphore-on-sta.patch
@@ -0,0 +1,151 @@
+From a3de0b63f25363f419fdf26144153dceb94981dd Mon Sep 17 00:00:00 2001
+From: Joerg Roedel <jroedel@suse.de>
+Date: Wed, 14 Sep 2016 11:41:59 +0200
+Subject: [PATCH] iommu/amd: Don't put completion-wait semaphore on stack
+
+commit 4bf5beef578e46393f11eb69dda7d17a065e05ff upstream.
+
+The semaphore used by the AMD IOMMU to signal command
+completion lived on the stack until now, which was safe as
+the driver busy-waited on the semaphore with IRQs disabled,
+so the stack can't go away under the driver.
+
+But the recently introduced vmap-based stacks break this as
+the physical address of the semaphore can't be determinded
+easily anymore. The driver used the __pa() macro, but that
+only works in the direct-mapping. The result were
+Completion-Wait timeout errors seen by the IOMMU driver,
+breaking system boot.
+
+Since putting the semaphore on the stack is bad design
+anyway, move the semaphore into 'struct amd_iommu'. It is
+protected by the per-iommu lock and now in the direct
+mapping again. This fixes the Completion-Wait timeout errors
+and makes AMD IOMMU systems boot again with vmap-based
+stacks enabled.
+
+Reported-by: Borislav Petkov <bp@alien8.de>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+
+diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
+index 2d1f9d4c020f..ca127b8c8fea 100644
+--- a/drivers/iommu/amd_iommu.c
++++ b/drivers/iommu/amd_iommu.c
+@@ -940,15 +940,13 @@ static void build_inv_irt(struct iommu_cmd *cmd, u16 devid)
+  * Writes the command to the IOMMUs command buffer and informs the
+  * hardware about the new command.
+  */
+-static int iommu_queue_command_sync(struct amd_iommu *iommu,
+-				    struct iommu_cmd *cmd,
+-				    bool sync)
++static int __iommu_queue_command_sync(struct amd_iommu *iommu,
++				      struct iommu_cmd *cmd,
++				      bool sync)
+ {
+ 	u32 left, tail, head, next_tail;
+-	unsigned long flags;
+ 
+ again:
+-	spin_lock_irqsave(&iommu->lock, flags);
+ 
+ 	head      = readl(iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);
+ 	tail      = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
+@@ -957,15 +955,14 @@ again:
+ 
+ 	if (left <= 0x20) {
+ 		struct iommu_cmd sync_cmd;
+-		volatile u64 sem = 0;
+ 		int ret;
+ 
+-		build_completion_wait(&sync_cmd, (u64)&sem);
+-		copy_cmd_to_buffer(iommu, &sync_cmd, tail);
++		iommu->cmd_sem = 0;
+ 
+-		spin_unlock_irqrestore(&iommu->lock, flags);
++		build_completion_wait(&sync_cmd, (u64)&iommu->cmd_sem);
++		copy_cmd_to_buffer(iommu, &sync_cmd, tail);
+ 
+-		if ((ret = wait_on_sem(&sem)) != 0)
++		if ((ret = wait_on_sem(&iommu->cmd_sem)) != 0)
+ 			return ret;
+ 
+ 		goto again;
+@@ -976,9 +973,21 @@ again:
+ 	/* We need to sync now to make sure all commands are processed */
+ 	iommu->need_sync = sync;
+ 
++	return 0;
++}
++
++static int iommu_queue_command_sync(struct amd_iommu *iommu,
++				    struct iommu_cmd *cmd,
++				    bool sync)
++{
++	unsigned long flags;
++	int ret;
++
++	spin_lock_irqsave(&iommu->lock, flags);
++	ret = __iommu_queue_command_sync(iommu, cmd, sync);
+ 	spin_unlock_irqrestore(&iommu->lock, flags);
+ 
+-	return 0;
++	return ret;
+ }
+ 
+ static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
+@@ -993,19 +1002,29 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
+ static int iommu_completion_wait(struct amd_iommu *iommu)
+ {
+ 	struct iommu_cmd cmd;
+-	volatile u64 sem = 0;
++	unsigned long flags;
+ 	int ret;
+ 
+ 	if (!iommu->need_sync)
+ 		return 0;
+ 
+-	build_completion_wait(&cmd, (u64)&sem);
+ 
+-	ret = iommu_queue_command_sync(iommu, &cmd, false);
++	build_completion_wait(&cmd, (u64)&iommu->cmd_sem);
++
++	spin_lock_irqsave(&iommu->lock, flags);
++
++	iommu->cmd_sem = 0;
++
++	ret = __iommu_queue_command_sync(iommu, &cmd, false);
+ 	if (ret)
+-		return ret;
++		goto out_unlock;
++
++	ret = wait_on_sem(&iommu->cmd_sem);
+ 
+-	return wait_on_sem(&sem);
++out_unlock:
++	spin_unlock_irqrestore(&iommu->lock, flags);
++
++	return ret;
+ }
+ 
+ static int iommu_flush_dte(struct amd_iommu *iommu, u16 devid)
+diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
+index caf5e3822715..9652848e3155 100644
+--- a/drivers/iommu/amd_iommu_types.h
++++ b/drivers/iommu/amd_iommu_types.h
+@@ -524,6 +524,8 @@ struct amd_iommu {
+ 	struct irq_domain *ir_domain;
+ 	struct irq_domain *msi_domain;
+ #endif
++
++	volatile u64 __aligned(8) cmd_sem;
+ };
+ 
+ #define ACPIHID_UID_LEN 256
+-- 
+2.15.0
+
diff --git a/queue/kthread-Pin-the-stack-via-try_get_task_stack-put_tas.patch b/queue/kthread-Pin-the-stack-via-try_get_task_stack-put_tas.patch
new file mode 100644
index 0000000..3bccea6
--- /dev/null
+++ b/queue/kthread-Pin-the-stack-via-try_get_task_stack-put_tas.patch
@@ -0,0 +1,75 @@
+From 4f20a35ad56f5ee15bbcc4e14966960647931940 Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Thu, 15 Sep 2016 22:45:44 -0700
+Subject: [PATCH] kthread: Pin the stack via
+ try_get_task_stack()/put_task_stack() in to_live_kthread() function
+
+commit 23196f2e5f5d810578a772785807dcdc2b9fdce9 upstream.
+
+get_task_struct(tsk) no longer pins tsk->stack so all users of
+to_live_kthread() should do try_get_task_stack/put_task_stack to protect
+"struct kthread" which lives on kthread's stack.
+
+TODO: Kill to_live_kthread(), perhaps we can even kill "struct kthread" too,
+and rework kthread_stop(), it can use task_work_add() to sync with the exiting
+kernel thread.
+
+Message-Id: <20160629180357.GA7178@redhat.com>
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Signed-off-by: Andy Lutomirski <luto@kernel.org>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Brian Gerst <brgerst@gmail.com>
+Cc: Denys Vlasenko <dvlasenk@redhat.com>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Jann Horn <jann@thejh.net>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Link: http://lkml.kernel.org/r/cb9b16bbc19d4aea4507ab0552e4644c1211d130.1474003868.git.luto@kernel.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+
+diff --git a/kernel/kthread.c b/kernel/kthread.c
+index 850b255649a2..d982c65f1578 100644
+--- a/kernel/kthread.c
++++ b/kernel/kthread.c
+@@ -65,7 +65,7 @@ static inline struct kthread *to_kthread(struct task_struct *k)
+ static struct kthread *to_live_kthread(struct task_struct *k)
+ {
+ 	struct completion *vfork = ACCESS_ONCE(k->vfork_done);
+-	if (likely(vfork))
++	if (likely(vfork) && try_get_task_stack(k))
+ 		return __to_kthread(vfork);
+ 	return NULL;
+ }
+@@ -427,8 +427,10 @@ void kthread_unpark(struct task_struct *k)
+ {
+ 	struct kthread *kthread = to_live_kthread(k);
+ 
+-	if (kthread)
++	if (kthread) {
+ 		__kthread_unpark(k, kthread);
++		put_task_stack(k);
++	}
+ }
+ EXPORT_SYMBOL_GPL(kthread_unpark);
+ 
+@@ -457,6 +459,7 @@ int kthread_park(struct task_struct *k)
+ 				wait_for_completion(&kthread->parked);
+ 			}
+ 		}
++		put_task_stack(k);
+ 		ret = 0;
+ 	}
+ 	return ret;
+@@ -492,6 +495,7 @@ int kthread_stop(struct task_struct *k)
+ 		__kthread_unpark(k, kthread);
+ 		wake_up_process(k);
+ 		wait_for_completion(&kthread->exited);
++		put_task_stack(k);
+ 	}
+ 	ret = k->exit_code;
+ 	put_task_struct(k);
+-- 
+2.15.0
+
diff --git a/queue/lib-syscall-Pin-the-task-stack-in-collect_syscall.patch b/queue/lib-syscall-Pin-the-task-stack-in-collect_syscall.patch
new file mode 100644
index 0000000..dd86783
--- /dev/null
+++ b/queue/lib-syscall-Pin-the-task-stack-in-collect_syscall.patch
@@ -0,0 +1,60 @@
+From 92040c8c2cd1a408802bea57fb586ccbb7a59c15 Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@kernel.org>
+Date: Thu, 15 Sep 2016 22:45:47 -0700
+Subject: [PATCH] lib/syscall: Pin the task stack in collect_syscall()
+
+commit aa1f1a639621672b68f654dc815a7d8298ff396f upstream.
+
+This will avoid a potential read-after-free if collect_syscall()
+(e.g. /proc/PID/syscall) is called on an exiting task.
+
+Reported-by: Jann Horn <jann@thejh.net>
+Signed-off-by: Andy Lutomirski <luto@kernel.org>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Brian Gerst <brgerst@gmail.com>
+Cc: Denys Vlasenko <dvlasenk@redhat.com>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Link: http://lkml.kernel.org/r/0bfd8e6d4729c97745d3781a29610a33d0a8091d.1474003868.git.luto@kernel.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+
+diff --git a/lib/syscall.c b/lib/syscall.c
+index e30e03932480..63239e097b13 100644
+--- a/lib/syscall.c
++++ b/lib/syscall.c
+@@ -7,9 +7,19 @@ static int collect_syscall(struct task_struct *target, long *callno,
+ 			   unsigned long args[6], unsigned int maxargs,
+ 			   unsigned long *sp, unsigned long *pc)
+ {
+-	struct pt_regs *regs = task_pt_regs(target);
+-	if (unlikely(!regs))
++	struct pt_regs *regs;
++
++	if (!try_get_task_stack(target)) {
++		/* Task has no stack, so the task isn't in a syscall. */
++		*callno = -1;
++		return 0;
++	}
++
++	regs = task_pt_regs(target);
++	if (unlikely(!regs)) {
++		put_task_stack(target);
+ 		return -EAGAIN;
++	}
+ 
+ 	*sp = user_stack_pointer(regs);
+ 	*pc = instruction_pointer(regs);
+@@ -18,6 +28,7 @@ static int collect_syscall(struct task_struct *target, long *callno,
+ 	if (*callno != -1L && maxargs > 0)
+ 		syscall_get_arguments(target, regs, 0, maxargs, args);
+ 
++	put_task_stack(target);
+ 	return 0;
+ }
+ 
+-- 
+2.15.0
+
diff --git a/queue/mm-kmemleak-ensure-that-the-task-stack-is-not-freed-.patch b/queue/mm-kmemleak-ensure-that-the-task-stack-is-not-freed-.patch
new file mode 100644
index 0000000..a6e55bb
--- /dev/null
+++ b/queue/mm-kmemleak-ensure-that-the-task-stack-is-not-freed-.patch
@@ -0,0 +1,52 @@
+From 37df49f433bc3a11f5716fe65aaec5189c6402cb Mon Sep 17 00:00:00 2001
+From: Catalin Marinas <catalin.marinas@arm.com>
+Date: Thu, 27 Oct 2016 17:46:47 -0700
+Subject: [PATCH] mm: kmemleak: ensure that the task stack is not freed during
+ scanning
+
+commit 37df49f433bc3a11f5716fe65aaec5189c6402cb upstream.
+
+Commit 68f24b08ee89 ("sched/core: Free the stack early if
+CONFIG_THREAD_INFO_IN_TASK") may cause the task->stack to be freed
+during kmemleak_scan() execution, leading to either a NULL pointer fault
+(if task->stack is NULL) or kmemleak accessing already freed memory.
+
+This patch uses the new try_get_task_stack() API to ensure that the task
+stack is not freed during kmemleak stack scanning.
+
+Addresses https://bugzilla.kernel.org/show_bug.cgi?id=173901.
+
+Fixes: 68f24b08ee89 ("sched/core: Free the stack early if CONFIG_THREAD_INFO_IN_TASK")
+Link: http://lkml.kernel.org/r/1476266223-14325-1-git-send-email-catalin.marinas@arm.com
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Reported-by: CAI Qian <caiqian@redhat.com>
+Tested-by: CAI Qian <caiqian@redhat.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: CAI Qian <caiqian@redhat.com>
+Cc: Hillf Danton <hillf.zj@alibaba-inc.com>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+
+diff --git a/mm/kmemleak.c b/mm/kmemleak.c
+index a5e453cf05c4..e5355a5b423f 100644
+--- a/mm/kmemleak.c
++++ b/mm/kmemleak.c
+@@ -1453,8 +1453,11 @@ static void kmemleak_scan(void)
+ 
+ 		read_lock(&tasklist_lock);
+ 		do_each_thread(g, p) {
+-			scan_block(task_stack_page(p), task_stack_page(p) +
+-				   THREAD_SIZE, NULL);
++			void *stack = try_get_task_stack(p);
++			if (stack) {
++				scan_block(stack, stack + THREAD_SIZE, NULL);
++				put_task_stack(p);
++			}
+ 		} while_each_thread(g, p);
+ 		read_unlock(&tasklist_lock);
+ 	}
+-- 
+2.15.0
+
diff --git a/queue/series b/queue/series
index 9aa0e96..5051e98 100644
--- a/queue/series
+++ b/queue/series
@@ -1,2 +1,23 @@
+# v4.9-rc1~160^2~60
+dma-api-Teach-the-DMA-from-stack-check-about-vmapped.patch
+# v4.9-rc1~160^2~21
+iommu-amd-Don-t-put-completion-wait-semaphore-on-sta.patch
+# v4.9-rc1~160^2~18
+kthread-Pin-the-stack-via-try_get_task_stack-put_tas.patch
+# v4.9-rc1~160^2~17
+x86-dumpstack-Pin-the-target-stack-when-dumping-it.patch
+# v4.9-rc1~160^2~16
+x86-process-Pin-the-target-stack-in-get_wchan.patch
+# v4.9-rc1~160^2~15
+lib-syscall-Pin-the-task-stack-in-collect_syscall.patch
+# v4.9-rc1~160^2~14
+# sched/core: Free the stack early if CONFIG_THREAD_INFO_IN_TASK
+
+# v4.9-rc3~24^2~9
+mm-kmemleak-ensure-that-the-task-stack-is-not-freed-.patch
+
+# v4.9-rc6~36^2
+x86-efi-Prevent-mixed-mode-boot-corruption-with-CONF.patch
+
 # v4.14-rc7~7
 assoc_array-Fix-a-buggy-node-splitting-case.patch
diff --git a/queue/x86-dumpstack-Pin-the-target-stack-when-dumping-it.patch b/queue/x86-dumpstack-Pin-the-target-stack-when-dumping-it.patch
new file mode 100644
index 0000000..811d2e7
--- /dev/null
+++ b/queue/x86-dumpstack-Pin-the-target-stack-when-dumping-it.patch
@@ -0,0 +1,94 @@
+From 8a567429ebb70da56eb63f05deee51d9328c5c00 Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@kernel.org>
+Date: Thu, 15 Sep 2016 22:45:45 -0700
+Subject: [PATCH] x86/dumpstack: Pin the target stack when dumping it
+
+commit 1959a60182f48879635812a03a99c02231ea8677 upstream.
+
+Specifically, pin the stack in save_stack_trace_tsk() and
+show_trace_log_lvl().
+
+This will prevent a crash if the target task dies before or while
+dumping its stack once we start freeing task stacks early.
+
+Signed-off-by: Andy Lutomirski <luto@kernel.org>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Brian Gerst <brgerst@gmail.com>
+Cc: Denys Vlasenko <dvlasenk@redhat.com>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Jann Horn <jann@thejh.net>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Link: http://lkml.kernel.org/r/cf0082cde65d1941a996d026f2b2cdbfaca17bfa.1474003868.git.luto@kernel.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+
+diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
+index 09675712eba8..8ad32dc94e8d 100644
+--- a/arch/x86/kernel/dumpstack_32.c
++++ b/arch/x86/kernel/dumpstack_32.c
+@@ -95,6 +95,9 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
+ 	unsigned long *stack;
+ 	int i;
+ 
++	if (!try_get_task_stack(task))
++		return;
++
+ 	if (sp == NULL) {
+ 		if (regs)
+ 			sp = (unsigned long *)regs->sp;
+@@ -118,6 +121,8 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
+ 	}
+ 	pr_cont("\n");
+ 	show_trace_log_lvl(task, regs, sp, bp, log_lvl);
++
++	put_task_stack(task);
+ }
+ 
+ 
+diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
+index 9ee4520ce83c..1bcdb164afd9 100644
+--- a/arch/x86/kernel/dumpstack_64.c
++++ b/arch/x86/kernel/dumpstack_64.c
+@@ -253,6 +253,9 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
+ 	int cpu;
+ 	int i;
+ 
++	if (!try_get_task_stack(task))
++		return;
++
+ 	preempt_disable();
+ 	cpu = smp_processor_id();
+ 
+@@ -303,6 +306,8 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
+ 
+ 	pr_cont("\n");
+ 	show_trace_log_lvl(task, regs, sp, bp, log_lvl);
++
++	put_task_stack(task);
+ }
+ 
+ void show_regs(struct pt_regs *regs)
+diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
+index 4738f5e0f2ab..b3f32fbe3ba4 100644
+--- a/arch/x86/kernel/stacktrace.c
++++ b/arch/x86/kernel/stacktrace.c
+@@ -79,9 +79,14 @@ void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
+ 
+ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
+ {
++	if (!try_get_task_stack(tsk))
++		return;
++
+ 	dump_trace(tsk, NULL, NULL, 0, &save_stack_ops_nosched, trace);
+ 	if (trace->nr_entries < trace->max_entries)
+ 		trace->entries[trace->nr_entries++] = ULONG_MAX;
++
++	put_task_stack(tsk);
+ }
+ EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
+ 
+-- 
+2.15.0
+
diff --git a/queue/x86-efi-Prevent-mixed-mode-boot-corruption-with-CONF.patch b/queue/x86-efi-Prevent-mixed-mode-boot-corruption-with-CONF.patch
new file mode 100644
index 0000000..0d649d8
--- /dev/null
+++ b/queue/x86-efi-Prevent-mixed-mode-boot-corruption-with-CONF.patch
@@ -0,0 +1,217 @@
+From f6697df36bdf0bf7fce984605c2918d4a7b4269f Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt@codeblueprint.co.uk>
+Date: Sat, 12 Nov 2016 21:04:24 +0000
+Subject: [PATCH] x86/efi: Prevent mixed mode boot corruption with
+ CONFIG_VMAP_STACK=y
+
+commit f6697df36bdf0bf7fce984605c2918d4a7b4269f upstream.
+
+Booting an EFI mixed mode kernel has been crashing since commit:
+
+  e37e43a497d5 ("x86/mm/64: Enable vmapped stacks (CONFIG_HAVE_ARCH_VMAP_STACK=y)")
+
+The user-visible effect in my test setup was the kernel being unable
+to find the root file system ramdisk. This was likely caused by silent
+memory or page table corruption.
+
+Enabling CONFIG_DEBUG_VIRTUAL=y immediately flagged the thunking code as
+abusing virt_to_phys() because it was passing addresses that were not
+part of the kernel direct mapping.
+
+Use the slow version instead, which correctly handles all memory
+regions by performing a page table walk.
+
+Suggested-by: Andy Lutomirski <luto@amacapital.net>
+Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Brian Gerst <brgerst@gmail.com>
+Cc: Denys Vlasenko <dvlasenk@redhat.com>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: linux-efi@vger.kernel.org
+Link: http://lkml.kernel.org/r/20161112210424.5157-3-matt@codeblueprint.co.uk
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+
+diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
+index 58b0f801f66f..319148bd4b05 100644
+--- a/arch/x86/platform/efi/efi_64.c
++++ b/arch/x86/platform/efi/efi_64.c
+@@ -31,6 +31,7 @@
+ #include <linux/io.h>
+ #include <linux/reboot.h>
+ #include <linux/slab.h>
++#include <linux/ucs2_string.h>
+ 
+ #include <asm/setup.h>
+ #include <asm/page.h>
+@@ -211,6 +212,35 @@ void efi_sync_low_kernel_mappings(void)
+ 	memcpy(pud_efi, pud_k, sizeof(pud_t) * num_entries);
+ }
+ 
++/*
++ * Wrapper for slow_virt_to_phys() that handles NULL addresses.
++ */
++static inline phys_addr_t
++virt_to_phys_or_null_size(void *va, unsigned long size)
++{
++	bool bad_size;
++
++	if (!va)
++		return 0;
++
++	if (virt_addr_valid(va))
++		return virt_to_phys(va);
++
++	/*
++	 * A fully aligned variable on the stack is guaranteed not to
++	 * cross a page bounary. Try to catch strings on the stack by
++	 * checking that 'size' is a power of two.
++	 */
++	bad_size = size > PAGE_SIZE || !is_power_of_2(size);
++
++	WARN_ON(!IS_ALIGNED((unsigned long)va, size) || bad_size);
++
++	return slow_virt_to_phys(va);
++}
++
++#define virt_to_phys_or_null(addr)				\
++	virt_to_phys_or_null_size((addr), sizeof(*(addr)))
++
+ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
+ {
+ 	unsigned long pfn, text;
+@@ -494,8 +524,8 @@ static efi_status_t efi_thunk_get_time(efi_time_t *tm, efi_time_cap_t *tc)
+ 
+ 	spin_lock(&rtc_lock);
+ 
+-	phys_tm = virt_to_phys(tm);
+-	phys_tc = virt_to_phys(tc);
++	phys_tm = virt_to_phys_or_null(tm);
++	phys_tc = virt_to_phys_or_null(tc);
+ 
+ 	status = efi_thunk(get_time, phys_tm, phys_tc);
+ 
+@@ -511,7 +541,7 @@ static efi_status_t efi_thunk_set_time(efi_time_t *tm)
+ 
+ 	spin_lock(&rtc_lock);
+ 
+-	phys_tm = virt_to_phys(tm);
++	phys_tm = virt_to_phys_or_null(tm);
+ 
+ 	status = efi_thunk(set_time, phys_tm);
+ 
+@@ -529,9 +559,9 @@ efi_thunk_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending,
+ 
+ 	spin_lock(&rtc_lock);
+ 
+-	phys_enabled = virt_to_phys(enabled);
+-	phys_pending = virt_to_phys(pending);
+-	phys_tm = virt_to_phys(tm);
++	phys_enabled = virt_to_phys_or_null(enabled);
++	phys_pending = virt_to_phys_or_null(pending);
++	phys_tm = virt_to_phys_or_null(tm);
+ 
+ 	status = efi_thunk(get_wakeup_time, phys_enabled,
+ 			     phys_pending, phys_tm);
+@@ -549,7 +579,7 @@ efi_thunk_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
+ 
+ 	spin_lock(&rtc_lock);
+ 
+-	phys_tm = virt_to_phys(tm);
++	phys_tm = virt_to_phys_or_null(tm);
+ 
+ 	status = efi_thunk(set_wakeup_time, enabled, phys_tm);
+ 
+@@ -558,6 +588,10 @@ efi_thunk_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
+ 	return status;
+ }
+ 
++static unsigned long efi_name_size(efi_char16_t *name)
++{
++	return ucs2_strsize(name, EFI_VAR_NAME_LEN) + 1;
++}
+ 
+ static efi_status_t
+ efi_thunk_get_variable(efi_char16_t *name, efi_guid_t *vendor,
+@@ -567,11 +601,11 @@ efi_thunk_get_variable(efi_char16_t *name, efi_guid_t *vendor,
+ 	u32 phys_name, phys_vendor, phys_attr;
+ 	u32 phys_data_size, phys_data;
+ 
+-	phys_data_size = virt_to_phys(data_size);
+-	phys_vendor = virt_to_phys(vendor);
+-	phys_name = virt_to_phys(name);
+-	phys_attr = virt_to_phys(attr);
+-	phys_data = virt_to_phys(data);
++	phys_data_size = virt_to_phys_or_null(data_size);
++	phys_vendor = virt_to_phys_or_null(vendor);
++	phys_name = virt_to_phys_or_null_size(name, efi_name_size(name));
++	phys_attr = virt_to_phys_or_null(attr);
++	phys_data = virt_to_phys_or_null_size(data, *data_size);
+ 
+ 	status = efi_thunk(get_variable, phys_name, phys_vendor,
+ 			   phys_attr, phys_data_size, phys_data);
+@@ -586,9 +620,9 @@ efi_thunk_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+ 	u32 phys_name, phys_vendor, phys_data;
+ 	efi_status_t status;
+ 
+-	phys_name = virt_to_phys(name);
+-	phys_vendor = virt_to_phys(vendor);
+-	phys_data = virt_to_phys(data);
++	phys_name = virt_to_phys_or_null_size(name, efi_name_size(name));
++	phys_vendor = virt_to_phys_or_null(vendor);
++	phys_data = virt_to_phys_or_null_size(data, data_size);
+ 
+ 	/* If data_size is > sizeof(u32) we've got problems */
+ 	status = efi_thunk(set_variable, phys_name, phys_vendor,
+@@ -605,9 +639,9 @@ efi_thunk_get_next_variable(unsigned long *name_size,
+ 	efi_status_t status;
+ 	u32 phys_name_size, phys_name, phys_vendor;
+ 
+-	phys_name_size = virt_to_phys(name_size);
+-	phys_vendor = virt_to_phys(vendor);
+-	phys_name = virt_to_phys(name);
++	phys_name_size = virt_to_phys_or_null(name_size);
++	phys_vendor = virt_to_phys_or_null(vendor);
++	phys_name = virt_to_phys_or_null_size(name, *name_size);
+ 
+ 	status = efi_thunk(get_next_variable, phys_name_size,
+ 			   phys_name, phys_vendor);
+@@ -621,7 +655,7 @@ efi_thunk_get_next_high_mono_count(u32 *count)
+ 	efi_status_t status;
+ 	u32 phys_count;
+ 
+-	phys_count = virt_to_phys(count);
++	phys_count = virt_to_phys_or_null(count);
+ 	status = efi_thunk(get_next_high_mono_count, phys_count);
+ 
+ 	return status;
+@@ -633,7 +667,7 @@ efi_thunk_reset_system(int reset_type, efi_status_t status,
+ {
+ 	u32 phys_data;
+ 
+-	phys_data = virt_to_phys(data);
++	phys_data = virt_to_phys_or_null_size(data, data_size);
+ 
+ 	efi_thunk(reset_system, reset_type, status, data_size, phys_data);
+ }
+@@ -661,9 +695,9 @@ efi_thunk_query_variable_info(u32 attr, u64 *storage_space,
+ 	if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
+ 		return EFI_UNSUPPORTED;
+ 
+-	phys_storage = virt_to_phys(storage_space);
+-	phys_remaining = virt_to_phys(remaining_space);
+-	phys_max = virt_to_phys(max_variable_size);
++	phys_storage = virt_to_phys_or_null(storage_space);
++	phys_remaining = virt_to_phys_or_null(remaining_space);
++	phys_max = virt_to_phys_or_null(max_variable_size);
+ 
+ 	status = efi_thunk(query_variable_info, attr, phys_storage,
+ 			   phys_remaining, phys_max);
+-- 
+2.15.0
+
diff --git a/queue/x86-process-Pin-the-target-stack-in-get_wchan.patch b/queue/x86-process-Pin-the-target-stack-in-get_wchan.patch
new file mode 100644
index 0000000..550411f
--- /dev/null
+++ b/queue/x86-process-Pin-the-target-stack-in-get_wchan.patch
@@ -0,0 +1,78 @@
+From 57d2b47069f4fb80f0736f9101a5899b361bb18f Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@kernel.org>
+Date: Thu, 15 Sep 2016 22:45:46 -0700
+Subject: [PATCH] x86/process: Pin the target stack in get_wchan()
+
+commit 74327a3e884a0ff895ba7b51d3488e6a177407b2 upstream.
+
+This will prevent a crash if get_wchan() runs after the task stack
+is freed.
+
+Signed-off-by: Andy Lutomirski <luto@kernel.org>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Brian Gerst <brgerst@gmail.com>
+Cc: Denys Vlasenko <dvlasenk@redhat.com>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Jann Horn <jann@thejh.net>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Link: http://lkml.kernel.org/r/337aeca8614024aa4d8d9c81053bbf8fcffbe4ad.1474003868.git.luto@kernel.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index 8089f4955bbc..26c7ffa8190c 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -520,15 +520,18 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
+  */
+ unsigned long get_wchan(struct task_struct *p)
+ {
+-	unsigned long start, bottom, top, sp, fp, ip;
++	unsigned long start, bottom, top, sp, fp, ip, ret = 0;
+ 	int count = 0;
+ 
+ 	if (!p || p == current || p->state == TASK_RUNNING)
+ 		return 0;
+ 
++	if (!try_get_task_stack(p))
++		return 0;
++
+ 	start = (unsigned long)task_stack_page(p);
+ 	if (!start)
+-		return 0;
++		goto out;
+ 
+ 	/*
+ 	 * Layout of the stack page:
+@@ -552,16 +555,21 @@ unsigned long get_wchan(struct task_struct *p)
+ 
+ 	sp = READ_ONCE(p->thread.sp);
+ 	if (sp < bottom || sp > top)
+-		return 0;
++		goto out;
+ 
+ 	fp = READ_ONCE_NOCHECK(((struct inactive_task_frame *)sp)->bp);
+ 	do {
+ 		if (fp < bottom || fp > top)
+-			return 0;
++			goto out;
+ 		ip = READ_ONCE_NOCHECK(*(unsigned long *)(fp + sizeof(unsigned long)));
+-		if (!in_sched_functions(ip))
+-			return ip;
++		if (!in_sched_functions(ip)) {
++			ret = ip;
++			goto out;
++		}
+ 		fp = READ_ONCE_NOCHECK(*(unsigned long *)fp);
+ 	} while (count++ < 16 && p->state != TASK_RUNNING);
+-	return 0;
++
++out:
++	put_task_stack(p);
++	return ret;
+ }
+-- 
+2.15.0
+