> It seems like some hardware timer would be necessary?
Yes, the kernel relies on hardware to generate an interrupt at regular intervals. On PCs, this was historically the 8253/8254 programmable interval timer, or an emulation thereof, then the local APIC timer, then the HPET.
Current Linux kernels can be built to run “tickless” when possible: the kernel will program timers to only fire when necessary, and if a given CPU is running a single process, that may well be “never”. In most cases, dynamic ticks are used, so the kernel sets timers up to fire at varying intervals depending on its requirements — fewer interrupts means fewer wake-ups, which means idle CPUs can be kept in low-power modes for longer periods, which saves energy.