Skip to content

morello: uaccess: Disable asm_goto_output#28

Open
heshamelmatary wants to merge 1 commit into
codasip-cheri-riscv-7.0from
morello_goto
Open

morello: uaccess: Disable asm_goto_output#28
heshamelmatary wants to merge 1 commit into
codasip-cheri-riscv-7.0from
morello_goto

Conversation

@heshamelmatary
Copy link
Copy Markdown
Collaborator

The use of asm_goto_output in __get_mem_asm allows the compiler to optimise the success path by branching directly out of inline assembly to a C label on error. However, this breaks execution state guarantees on Morello.

When a memory fault triggers on a user-space load, the hardware exception handler uses the exception table to rewrite the Program Counter. If the entry targets the C label directly, execution resumes there immediately—completely bypassing the trailing __ASM_UACCESS_AFTER macro inside the block.

On Morello, __ASM_UACCESS_BEFORE and __ASM_UACCESS_AFTER manage critical architectural transitions, such as switching between A64 and C64 (Capability) execution modes via PSTATE.C64. Bypassing the cleanup path leaves the processor stuck in C64 mode, corrupting subsequent A64 instruction streams and causing immediate kernel panics.

Fix this by gating asm_goto_output out when Morello is enabled. Fall back to a traditional linear asm volatile block that uses an explicit, sequential landing pad placed right before __ASM_UACCESS_AFTER. This guarantees that execution state cleanup runs on both success and fault paths before checking the error code in standard C.

I also experimented with the following alternative solution that does still use asm_goto_output that seems to pass the same number of tests with this PR and doesn't trigger panics:


#define __get_mem_asm(load, reg, x, addr, label, type)       \
  asm_goto_output(                                           \
  __ASM_UACCESS_BEFORE                                       \
  "1: " load "  " reg "0, [%1]\n"                            \
  __ASM_UACCESS_AFTER                                        \
  ".pushsection .text.fixup, \"ax\"\n"                       \
  "2: " __ASM_UACCESS_AFTER "\n"                             \
  "   b %l2\n"                                               \
  ".popsection\n"                                            \
  _ASM_EXTABLE_##type##ACCESS(1b, 2b)                        \
  : "=r" (x)                                                 \
  : "r" (addr) : : label)

It is a bit hacky but it does force this block to use __ASM_UACCESS_AFTER

The use of asm_goto_output in __get_mem_asm allows the
compiler to optimise the success path by branching directly
out of inline assembly to a C label on error. However, this
breaks execution state guarantees on Morello.

When a memory fault triggers on a user-space load, the
hardware exception handler uses the exception table to rewrite
the Program Counter. If the entry targets the C label directly,
execution resumes there immediately—completely bypassing the
trailing __ASM_UACCESS_AFTER macro inside the block.

On Morello, __ASM_UACCESS_BEFORE and __ASM_UACCESS_AFTER
manage critical architectural transitions, such as switching
between A64 and C64 (Capability) execution modes via
PSTATE.C64. Bypassing the cleanup path leaves the processor
stuck in C64 mode, corrupting subsequent A64 instruction
streams and causing immediate kernel panics.

Fix this by gating asm_goto_output out when Morello is
enabled. Fall back to a traditional linear asm volatile
block that uses an explicit, sequential landing pad placed
right before __ASM_UACCESS_AFTER. This guarantees that
execution state cleanup runs on both success and fault paths
before checking the error code in standard C.

Signed-off-by: Hesham Almatary <hesham.almatary@cl.cam.ac.uk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant