Sure, in the same way most people today don't run their entire application in ring 0, but instead run on top of a kernel. Privilege levels like that are another thing that high level languages don't need. A compiler or JIT can generate low-level code just fine.
>certainly every multithreaded imperative shared memory ones (and IMO nothing is close to these in terms of efficiency on multicore)
You're begging the question here. Why is shared memory multithreading the fastest way available? It's because cache coherence is heavily optimized in hardware. But, of course, cache coherence is built on shared-nothing message-passing under the hood. So why not just use message-passing directly? Plenty of languages where that's the native primitive.
Only sometimes, and only for nearer caches. Data still often gets shared by both sources reading and writing a shared memory location (whether a farther-out cache or main memory or disk).
Shared memory multithreading is fastest because explicitly communicating all of your tasks' inputs and outputs without any caching will transfer more data than using caches where several tasks can read the same thing from the same place. Cache coherence is not only built on shared nothing-message-passing under the hood, it's built on caches. If you cache your messages/accesses/whatever somewhere, you'll have coherence problems, if you don't, you'll have efficiency problems.
Just because you have a language with a native primitive doesn't mean this language doesn't throw efficiency out the window by building things around this primitive. Say, plenty of languages have cons cells for all the wrong reasons (I think Clojure is the one language that escaped this in its lineage) and still cons sells are fundamentally inefficient no matter what you do in hardware, this part I elaborated on in TFA. Just like having a language with a primitive solving the halting problem doesn't solve the halting problem, you can't have a language with arbitrary primitives and a magic machine making the sw+hw system as efficient as any alternative.
Enormous effort has been spent to allow HPC applications to talk directly to the network interface hardware without going through the OS (for instance using the Infiniband verbs API), because system calls are way too slow. This puts a lot of burden on the hardware vendors, because hardware implementation bugs might expose security vulnerabilities that could be exploited by malicious software, and there's no OS layer in between to sanity-check the hardware commands.
If a system call is just calling a function, then that's not an issue anymore; you can just use system calls for everything, because it's fast. The compiler might even inline them. The OS can insert any sanity checks it wants and expose a safe API to the application.
Regarding unsafe code, it's true than unsafe code blocks can violate the memory safety of the whole system, but that doesn't mean you can never use them, it just means that you need to use them carefully. An unsafe code block could be treated like kernel code or a setuid root binary. In a language like Rust, ideally many of the unsafe code patterns would be migrated into the standard library with a safe interface, and the unsafe low-level hardware interaction that the OS would need to do would be another set of unsafe code blocks. Normal application could be forbidden from using their own unsafe blocks (unless the superuser says it's okay), but they can still call into the kernel and into the standard library. (The way I imagine this working is that the operating system would have a policy of not executing any code that wasn't compiled by a trusted compiler, with compiler options dictated by some security policy. Code that was compiled on an un-trusted compiler can run inside an emulator.)
If having unsafe code blocks anywhere in the system seems wrong, consider that operating system kernels are essentially large unsafe code blocks. If we can abstract out the bits that truly need to be unsafe and write the rest as safe code, the end result may be far fewer corners for memory corruption bugs to lurk in, and an overall improvement in security and stability.
That sounds like basically running node.js in kernel space, which is entirely doable. I think people have put HLLs into kernel space before.
One could also go in the opposite direction and write an OS that just runs as a process inside another OS. Kind of like virtualization, but you don't need any of the specialized virtualization hardware features to do it. An advantage to doing this is that you could in theory setup the same environment on Windows, Linux, MacOS, or whatever, and be able to run one application on any of those platforms inside your process-level "guest OS" without modification. Sort of like Java, but with more OS-like features (like a shell, process and user management, a filesystem, and maybe a desktop environment), native code generation, and no GC.
http://www.cl.cam.ac.uk/research/srg/netos/projects/archive/... (2000)
No commercial application, I believe.