Asm!'s nostack and ARM interrupts

Can option(nostack) be set on an asm!() call if the hardware's interrupt mechanism pushes to the stack and it's possible for an interrupt to occur during execution of the assembly? Does it matter whether it's a hardware or software interrupt?

Context on the question:

On ARM, a hardware exception will automatically align the stack pointer and push some data (e.g. the register values) onto the current thread's stack. When the exception handler returns, the stack pointer is restored to its previous value, but the bytes that were overwritten remain changed. This is true for both hardware and software exceptions.

Tock OS's userspace support library makes system calls by issuing a svc instruction in inline assembly. Many of Tock's system calls do not conceptually touch the stack, but because they go through the software exception mechanism the hardware will still push data to the stack then restore it. We're currently having a discussion at nostack option for ARM system calls · Issue #577 · tock/libtock-rs · GitHub over whether or not nostack can be set on these inline assembly blocks.

My initial reaction is that the answer is "yes, nostack is okay" because if the answer is "no", then the only time nostack can be used is if interrupts are disabled. However, reading through the reference and Rust by Example descriptions of nostack, it's not clear that my initial reaction is correct.

When I look up conversations about nostack, it seems the general sentiment is that nostack is only about the red-zone (which I don't believe ARM has -- or if it has it, then the hardware must respect it as well), but I haven't find anything authoritative saying that.

Yes, I believe option(nostack) is only about stack pointer alignment and the red zone. It isn't explicitly stated in the reference though. Maybe open a PR to the reference for this?

I've started working on a PR to the Rust reference to clarify this, but I realized there's an important piece of terminology that I don't fully understand (perhaps because it hasn't been specified). I have the following mental model of stack memory:

+--------+ <- Top of space provided by the platform for the stack
| Stack  |
| frames |
| in use |
+--------+ <- Current stack pointer value
| Red    |
| zone   |
+--------+
| ???    |
+--------+ <- Bottom of space provided by the platform for the stack

Here, "platform" refers to the thing that decided where this thread's stack will live (OS, linker script, etc). The ??? region is where ARM saves the registers during an interrupt. The question is, is the ??? region part of the stack? From the platform's perspective it is, but perhaps from the perspective of the Rust language it is not part of the stack.

If the ??? is part of the stack, then my Rust reference PR will say something along the lines of "nostack does not restrict memory accesses by the target itself". If ??? is not part of the stack, then I suppose that answers the question: nostack is fine in assembly that calls software interrupts because software interrupts do not touch Rust stack memory.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.