At least in the first generation of UML, the guest processes are in fact host processes. The guest kernel (a userland process) essentially runs them under ptrace() and catches all of the system calls made by the guest process and rewires them so they do operations inside of the guest kernel. They otherwise run like host processes on host CPU, though.
Completing the illusion, however, the guest kernel also skillfully rewires the guest ptrace() calls so you can still use strace or gdb inside of the guest!
It's good enough that you can go deeper and run UML inside of UML.
> What’s the real-world utility here? Is UML suitable for running isolated workloads? My educated guess is: probably not for most production scenarios.
Back in the day there were hosts offering UML VMs for rent. This is actually how Linode got its start!