Quitting an Intel x86 Hypervisor
halobates.de121 points by todsacerdoti a month ago
121 points by todsacerdoti a month ago
This reminds me of DOS-based Windows which would need to get out of the V86 mode that EMM386 used before going into protected mode itself; a task which was done using the undocumented (at the time) GEMMIS interface.
Similarly, Novell NetWare, which was its own OS with its own filesystem, used DOS as a preboot environment and allowed you to exit to DOS.
The reason for the undocumented interface is not because Windows needs to go into protected mode itself (which would be a simple operation that later on came to be available through the more documented DPMI-alikes) , but rather because Windows wants to _replace_ EMM386 itself and "therefore" (usual troll MS logic of the era) needs access to its internals.
I mean, enhanced windows wants to be running in protected mode with its kernel in ring 0. If you're running DOS in real mode, no problem, windows will switch.
But, if you've loaded Emm386, it already has the machine in protected mode with its kernel in ring 0.
GEMMIS allows switching out the kernel, and later switching back.
Almost every other 386-era DOS game also wants to switch the machine to protected mode, even in the presence of EMM386, and doesn't need something as absurdly complicated as GEMMIS to do that. My point is: GEMMIS is for replacing EMM386 itself, not for temporarily enabling protected mode, for which there are (and were) alternatives. That's why GEMMIS is basically exposing the internals of EMM386 and why no one likes to implement it (implementing it forces you to design your manager as per EMM386 internals), plus why it is typical of the behavior of MS in the era (even when they make a standard, never miss an opportunity to abuse it to give your product an edge).
Fun stuff. Reminds me of writing code to restore a state snapshot for a sound module with its own processor. It had four byte-wide shared I/O registers in a row. After restoring almost all memory, I put a two-byte infinite-loop branch instruction in the last two bytes and had the sound CPU jump to it, loaded a 1- or 2- byte instruction in the first two bytes, then modified the branch offset to execute this instruction as part of the loop, let it run a few times, then modified the offset to just be a single-instruction loop. I did this multiple times to execute each instruction needed to finish loading memory, restore all registers, and finally jump to the execution address with everything restored.
Does this work with multiple processors? It seems like you would have trouble if processor 1 calls cpuid but processor 2 does not for a long time, your emulation of proc 2 would need to be precise to a much-higher-than normal degree to be consistent with proc 1 behavior.
This technique works with any instruction that clobbers a register, not just with CPUID. In the worst case you could just single step the other CPUs until you hit an instruction that overwrites a register too. These are common.
In my case (for a custom hypervisor for a sadly cancelled project) it wasn't a problem because the hypervisor quit itself in early guest boot, which is single CPU only.
Awful.
Fortunately, we won't have to suffer x86 much longer.
I've been hearing this since the 90s when hollywood was telling me RISC was going to change everything with machines that look crispy in the dark. People were probably saying it in the 80s and I just didn't hear it.
AMD and Intel have no reason to leave x86. ARM is certainly crowding into their markets, but this isn't the first time, and there's room for multiple architectures.
I wonder how different history might have been if Intel had chose to design something more workable instead of Itanium. We're just now ending the x86-64 transition (no more 32 bit Windows, most all software x86 software is 64 bit native nowadays) and maybe that would never have happened, we'd have just went to 64 bit other-thing.
Either way there is definitely room for multiple architectures for a long while. Even if one believes ARM or RISC-V or whatever will be the end of x86 it would still take a decade to stop seeing new x86 CPU designs come out just from the momentum.
Yeah, in terms of new designs, Itanium got its last new processor in 2017, although wikipedia says it's basically the same as the 2012 design, and that was for an architecture with a poor release in 2001 and effectively dead by 2005. Manufacturing continued until 2020.
x86 will probably get at least a similar lifetime beyond the point where it's clearly dead. And then those systems will likely last another ten years. Maybe there will be retro builds for even longer (Intel Quark was more or less an OG pentium, 20 years later)
Be carefull for what you wish for.
The design is basically an overextension of the 8008 processer, which assumed 64k of memory and manually programmed in assembly. We've expanded that design for 40 years, and the whole software design philosophy below it has changed. Every design will suffer in these conditions.
Meanwhile, almost all info about it is in the open. Culture has closed a lot, even including stuff like RISC V.
It's bizarre to me there are people cheering on the potential death of x86. Sure it has warts, but it is an accidentally created mostly-open platform we'll likely never see created again. And ARM's vaulted power efficiency advantages are really overblown, having more to do with different design goals and not needing to care about a diverse platform than inherent advantages of the underlying cpu architecture. I suspect if x86 ecosystem does die we won't end up with much to show for it compared to what will be lost.
They are too smart to repeat the mistake of the IBM PC again. Even with "open" ISAs, kernels, they will rules-lawyer out the blackbox part out just like with Android phone makers etc.
Weird mobile SoCs are increasingly open. There's device tree. Modern Pixel devices use UEFI.
Why bother with obfuscated nonstandard schemes when it gets you bad PR and increases your own development costs to get a FOSS stack up and running? Manufacturers just lock the bootloader instead. That can't be reverse engineered around.
Thats what I meant. They will find some other part of the stack to lock down to rules lawyer against the openness of whatever the rest of the stack is. You have an open source Linux kernel, you may have an open source chip, so as you said they might cryptographically lock the bootloader. And now Android I believe is trying to make an end run around drivers in the Linux layer too. If thats true then manufacturers will jump to shift drivers into the Apache layer instead of the GPL kernel. ie if they even provide source dumps at all.
edit: It seems I am misinformed about the moving drivers above part. Perhaps I might have confused this from Fuchsia. In any case the main point was that as you yourself gave the example of, they will always find some part of the stack to hide all the real power/real logic into even if the other parts are open.
there isn't much out there which is well known and completely open source other than risc-v. mayb urbit