Each UML process has its own thread in the host kernel. So, a context switch from one to another involves stopping the outgoing process and continuing the incoming one.
UML also gives each of its processes its own address space. This speeds up context switching. If there were only one address space multiplexed among all processes, then a context switch would involve walking it and totally remapping it for the incoming process.
Pages in the incoming process may have been unmapped and reused while it was switched out. The host process will still have them mapped, so it is necessary to unmap them before it is allowed to return to userspace. These pages are identified by a pair of UML-specific pte bits which are set in ptes that are out-of-date with respect to the host process address space. When the pte is modified, these bits are set appropriately and they are cleared when the host mapping is updated.
A final subtlety with context switching is the handling of SIGIO. A SIGIO on a file descriptor will be queued to the process registered as its recipient of asynchronous notification. So, when a context switch happens, that SIGIO registration must be changed from the outgoing process to the incoming one.