Dynamically configure machdep->stacksize based on page size.
Specifically, set it to 32KB for 16KB pages (default for CONFIG_ARM64_16K_PAGES)
and 64KB for 64KB pages, instead of using the hardcoded 16KB ARM64_STACK_SIZE.
Update arm64_unwind_frame and arm64_unwind_frame_v2 to use
machdep->stacksize for stack_mask calculation instead of ARM64_STACK_SIZE.
This fixes unwinding failures when the stack frame crosses the 16KB boundary
on a 32KB stack.
Signed-off-by: Dean Liao <deanliao(a)google.com>
---
arm64.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/arm64.c b/arm64.c
index d177092..3ce14aa 100644
--- a/arm64.c
+++ b/arm64.c
@@ -630,7 +630,22 @@ arm64_init(int when)
machdep->last_ptbl_read = 0;
machdep->clear_machdep_cache = arm64_clear_machdep_cache;
- machdep->stacksize = ARM64_STACK_SIZE;
+ /*
+ * Refer to arch/arm64/include/asm/memory.h in kernel source:
+ * THREAD_SIZE is PAGE_SIZE << THREAD_SIZE_ORDER.
+ * When CONFIG_VMAP_STACK is enabled, THREAD_SHIFT is at
+ * least PAGE_SHIFT.
+ * - 4KB pages -> 16KB stack (ARM64_STACK_SIZE)
+ * - 16KB pages -> 32KB stack (MIN_THREAD_SHIFT=15 if KASAN
+ * enabled, or Android default)
+ * - 64KB pages -> 64KB stack (THREAD_SHIFT=PAGE_SHIFT=16)
+ */
+ if (machdep->pagesize == 16384)
+ machdep->stacksize = 32768;
+ else if (machdep->pagesize == 65536)
+ machdep->stacksize = 65536;
+ else
+ machdep->stacksize = ARM64_STACK_SIZE;
machdep->flags |= VMEMMAP;
machdep->uvtop = arm64_uvtop;
machdep->is_uvaddr = arm64_is_uvaddr;
@@ -3311,7 +3326,7 @@ arm64_unwind_frame(struct bt_info *bt, struct arm64_stackframe
*frame)
struct arm64_pt_regs *ptregs;
struct machine_specific *ms = machdep->machspec;
- stack_mask = (unsigned long)(ARM64_STACK_SIZE) - 1;
+ stack_mask = machdep->stacksize - 1;
fp = frame->fp;
low = frame->sp;
@@ -3521,7 +3536,7 @@ arm64_unwind_frame_v2(struct bt_info *bt, struct arm64_stackframe
*frame,
unsigned long irq_stack_ptr;
struct machine_specific *ms;
- stack_mask = (unsigned long)(ARM64_STACK_SIZE) - 1;
+ stack_mask = machdep->stacksize - 1;
fp = frame->fp;
low = frame->sp;
--
2.55.0.rc0.799.gd6f94ed593-goog