|
@@ -753,6 +753,38 @@ no_context(struct pt_regs *regs, unsigned long error_code,
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef CONFIG_VMAP_STACK
|
|
|
|
+ /*
|
|
|
|
+ * Stack overflow? During boot, we can fault near the initial
|
|
|
|
+ * stack in the direct map, but that's not an overflow -- check
|
|
|
|
+ * that we're in vmalloc space to avoid this.
|
|
|
|
+ */
|
|
|
|
+ if (is_vmalloc_addr((void *)address) &&
|
|
|
|
+ (((unsigned long)tsk->stack - 1 - address < PAGE_SIZE) ||
|
|
|
|
+ address - ((unsigned long)tsk->stack + THREAD_SIZE) < PAGE_SIZE)) {
|
|
|
|
+ register void *__sp asm("rsp");
|
|
|
|
+ unsigned long stack = this_cpu_read(orig_ist.ist[DOUBLEFAULT_STACK]) - sizeof(void *);
|
|
|
|
+ /*
|
|
|
|
+ * We're likely to be running with very little stack space
|
|
|
|
+ * left. It's plausible that we'd hit this condition but
|
|
|
|
+ * double-fault even before we get this far, in which case
|
|
|
|
+ * we're fine: the double-fault handler will deal with it.
|
|
|
|
+ *
|
|
|
|
+ * We don't want to make it all the way into the oops code
|
|
|
|
+ * and then double-fault, though, because we're likely to
|
|
|
|
+ * break the console driver and lose most of the stack dump.
|
|
|
|
+ */
|
|
|
|
+ asm volatile ("movq %[stack], %%rsp\n\t"
|
|
|
|
+ "call handle_stack_overflow\n\t"
|
|
|
|
+ "1: jmp 1b"
|
|
|
|
+ : "+r" (__sp)
|
|
|
|
+ : "D" ("kernel stack overflow (page fault)"),
|
|
|
|
+ "S" (regs), "d" (address),
|
|
|
|
+ [stack] "rm" (stack));
|
|
|
|
+ unreachable();
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* 32-bit:
|
|
* 32-bit:
|
|
*
|
|
*
|