Repository navigation
aarch64: implement KrnIsSuper(), add SMP-IntCtx test - #2265
Conversation
Minor: the arm-native 32-bit Pi could get thCPSR. |
5d44c06 to
45d6436
Compare
|
Thanks, all five were right. Updated:
SMP-IntCtx also checks 1 and 2 from the task now: a nested SuperState() |
CheckSuperState() fails wherever SuperState() cannot enter supervisor modeThe SMP tests are built for every target (
Both report bit 1 ("not supervisor") and SMP-IntCtx fails there with nothing wrong. Called from ssp = SuperState();
if (!ssp)
return -1; /* no supervisor mode to enter */ super = CheckSuperState();
if (super < 0)
{
bug("[smpintctx] SuperState() has no supervisor mode here, skipped\n");
super = 0;
}
else
bug("[smpintctx] SuperState(): not supervisor %d, ...", ...);arm-native will fail it for real
Minor
|
The generic version answers FALSE, so Enable() and Signal() in an interrupt handler unmasked IRQ and FIQ and the handler could nest. Handlers and SuperState() run at EL1h, tasks at EL1t. SuperState() now returns NULL at EL1h, and SC_USERSTATE sets the IRQ/FIQ mask from the Disable() nesting instead of always unmasking. Every supervisor check in exec now applies at EL1h, as on m68k and x86: Permit() does not reschedule there, AllocMem() takes its supervisor path, and CheckSemaphore() alerts on semaphore calls from a handler or inside SuperState().
A VBlank server checks that KrnIsSuper() is set, that it is entered with interrupts masked, and that neither Disable()/Enable() nor Signal() unmasks them. The mask is only read on aarch64. The task then checks that a nested SuperState() returns NULL and that UserState() leaves the mask as the Disable() nesting says. Skipped where SuperState() has no supervisor mode to enter (hosted, riscv64). Expected to fail on arm-native until its SuperState() is fixed: it issues SC_SUPERSTATE unconditionally, so a nested call returns an SP.
A Cause() on a pending softint is coalesced, so the worker waits for NT_INTERRUPT before the next one. A second softint Causes itself twice while running and must run exactly once per request. main clears the Ctrl-D/Ctrl-F worker signals, which otherwise abort the calling script.
45d6436 to
c36277f
Compare
|
Thanks, fixed:
|
aarch64 had no KrnIsSuper() and used the generic one, which always
returns FALSE. Enable() in an interrupt handler therefore unmasked IRQ
and FIQ, and so did Signal(), which does its own Disable()/Enable() on
SMP. A handler could nest onto itself or onto a spinlock it held.
SuperState() at EL1h.
IRQ/FIQ mask from the Disable() nesting instead of always unmasking.
x86: Permit() does not reschedule there, AllocMem() takes its
supervisor path, and CheckSemaphore() alerts on semaphore calls from
a handler or inside SuperState().
that it is entered masked, and that Disable()/Enable() and Signal()
leave the mask alone. The task then checks nested SuperState() and
the mask after UserState(). Skipped where SuperState() has no
supervisor mode to enter. Expected to fail on arm-native, whose
SuperState() has the same nesting bug.
Cause(), a second softint Causes itself while running, and main
clears its Ctrl-D/Ctrl-F worker signals so it no longer aborts the
calling script.
Tested on Pi 3B+ (4 cores) and QEMU raspi3b. Not run on Pi 4/5.