With a mechanism in place to intercept process system calls and switch between user and kernel mode and back, virtualizing system calls is fairly straightforward.
The system call obviously must be annulled in the host kernel. This is done by changing the register containing the system call number to __NR_getpid. When this is done, the tracing thread saves the process registers in the thread structure, and imposes some previously saved state. This new state causes the process to start executing the system call handler, which reads the system call and arguments from its saved registers and calls the system call code.
When the system call is finished, the process stores the return value in its saved registers, and requests that the tracing thread return it to user mode. The tracing thread restores the saved registers, and continues the process with system call tracing on.