From: Sergiu Moga Date: Mon, 24 Mar 2025 16:42:17 +0000 (+0200) Subject: lib/syscall_shim/arch/arm64: Store caller's link register X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=87fa095ae8bfffa4bd9b621fa9915451db8a31e5;p=unikraft%2Funikraft.git lib/syscall_shim/arch/arm64: Store caller's link register So far for storing LR and ELR_EL1 we have been using the current link register for both instead. This does not reflect reality when it comes to LR as we should instead store the LR that the caller would know. To achieve this, do a brief level 1 stack unwinding and fetch caller's LR from the top of its frame. Signed-off-by: Sergiu Moga Approved-by: Michalis Pappas Reviewed-by: Michalis Pappas Reviewed-by: Andrei Tatar GitHub-Closes: #1618 --- diff --git a/lib/syscall_shim/arch/arm64/include/arch/syscall_prologue.h b/lib/syscall_shim/arch/arm64/include/arch/syscall_prologue.h index c04659bf1..e1103815c 100644 --- a/lib/syscall_shim/arch/arm64/include/arch/syscall_prologue.h +++ b/lib/syscall_shim/arch/arm64/include/arch/syscall_prologue.h @@ -92,13 +92,28 @@ "stp x24, x25, [sp, #16 * 12]\n\t" \ "stp x26, x27, [sp, #16 * 13]\n\t" \ "stp x28, x29, [sp, #16 * 14]\n\t" \ - "/* Here we should push lr and elr_el1, however\n\t" \ + "/* Here we should push elr_el1, however\n\t" \ " * we are not in an actual exception, but instead\n\t" \ " * we are trying to emulate a SVC with a function\n\t" \ " * call which makes elr_el1 invalid and we instead\n\t"\ - " * double push lr (x30).\n\t" \ + " * push lr (x30).\n\t" \ " */\n\t" \ - "stp x30, x30, [sp, #16 * 15]\n\t" \ + "str x30, [sp, #16 * 15 + 8]\n\t" \ + "/* Here we should push lr, however\n\t" \ + " * our lr has been overwritten with the return\n\t" \ + " * address back to the caller itself, so we will\n\t" \ + " * have to do a little bit of a level 1 stack\n\t" \ + " * stack unwinding. In the process we\n\t" \ + " * are dirtying lr but this is fine because we are\n\t"\ + " * restoring it at the end anyway.\n\t" \ + " */\n\t" \ + "/* Get previous frame address */\n\t" \ + "ldr x30, [x29]\n\t" \ + "/* lr is typically saved at offset 8 from new\n\t" \ + " * frame\n\t" \ + " */\n\t" \ + "ldr x30, [x29, #8]\n\t" \ + "str x30, [sp, #16 * 15]\n\t" \ "/* Just like above for elr_el1, spsr_el1 is also\n\t" \ " * invalid. Therefore we use a sane default value\n\t" \ " * which one would normally see in spsr_el1\n\t" \ @@ -134,7 +149,7 @@ "ldp x22, x23, [sp, #16 * 11]\t\n" \ "ldp x20, x21, [sp, #16 * 10]\t\n" \ "ldp x18, x19, [sp, #16 * 9]\t\n" \ - "/* Restore rsp from where it was stored */\n\t" \ + "/* Restore sp from where it was stored */\n\t" \ "ldr x9, [sp, #" STRINGIFY(__SP_OFFSET) "]\n\t" \ "mov sp, x9\n\t" \ "ret\n\t" \