from the debug output, a crash always seems to happen right after an interrupt in kernel mode (this can happen when allocating memory and it needs to swap in more pages)
(because the kernel typically allocates blocks of about 32 bytes long, and swapping happens once every 4096 bytes. so each allocation has less than 1% chance of triggering a nested exception, and perhaps not all of those cause issues. and most kernel allocation happens before userspace code runs so there are no exception registers to mess up.)
a nested interrupt will overwrite the saved registers, so I should probably stash those somewhere when there may be nested interrupts!