Assumption
User mode register stack is dynamically grow and paged out. That is to say,
while executing instructions, including 'save' instruction, page fault may
occur.
Problem
If page fault occurrs while saving local register to memory under user mode,
control is transferred to kernel via rTT register. Kernel tries to allocate
physical memory and map them to users virtual address. To do this work, it
requires local and global registers. First, kernel saves user's local and
global registers with 'save' instruction. But there is no physical memory to
save user's registers. So, users registers are lost.
My Solution
My first solution requires new special register. But I feel that
introducing new special register is against the design of MMIX.
So, I changed my solution.
New solution requires only changes in SAVE/UNSAVE instructions.
Following is the outline of new solution.
If 'save' instruction is executed in kernel mode, and rS register is in user
space. Then treat $X as input. It contains "physical address" of ram to where
the global and local registers are saved.
If 'unsave' instruction is executed in kernel mode, and $Z is not in kernel space.
Then treat the contents of $Z as "physical address" of ram from where
the global and local registers are unsaved.
With these modifications, while kernel saving user regsters, page fault never
occurs and user context never lost.