There must be a way to alter a core's instruction pointer from another core or from hardware to support killing processes running untrusted machine code, and to support pre-emptive multithreading without needing to have compilers add a check for preemption on all backward branches and calls.
These features are very worth the hassle of providing this capability (which is known as "IPI"s), and once you have that hardware interrupts become pretty much free to support by using the same capability and the OS/user can then decide whether to dedicate a core, to affinity them to a core, to load balance them among all cores or to disable the interrupts and poll instead.
I was thinking rather than mucking with instruction pointers you would just send a message back to the other CPU saying “pause & switch to context X”. Technically an interrupt but one that can be handled internally within the CPU.
What do you think "switch to context X" does, if not muck with the instruction pointer? Where do you think mucking with the instruction pointer is handled, if not within the CPU?
These features are very worth the hassle of providing this capability (which is known as "IPI"s), and once you have that hardware interrupts become pretty much free to support by using the same capability and the OS/user can then decide whether to dedicate a core, to affinity them to a core, to load balance them among all cores or to disable the interrupts and poll instead.