1. Malware can infer details from CPUID to guess if it’s in a VM or not. Useful to avoid detection/analysis.
2. When processes execute in a legacy mode you may trap on CPUID to hide details the library won’t understand, or doesn’t expect to exist. To avoid backwards compatibility issues... better safe then sorry.
3. When developing SIMD related libraries which need to be portable across multiple CPU versions you may set up a CPUID mask (so trap, then hide features) to ensure compatibility on legacy computers.
Overall having the ability to trap, and rewrite the CPUID instruction is incredibly useful. The difference between denying, and rewriting just boils down to if a callback is provided or not. Both features require disabling native CPUID execution.
CPUID on x86 is a user-level instruction. When you're doing processor-assisted emulation, CPUID is an instruction that does cause an exit to the hypervisor, which does allow you to do CPUID emulation. You clearly don't need such instructions to be privileged to do emulation games with CPUID.
> 3. When developing SIMD related libraries which need to be portable across multiple CPU versions you may set up a CPUID mask (so trap, then hide features) to ensure compatibility on legacy computers.
Huh? My impression was CPUID was exactly the opposite: using it properly allows ensuring compatibility on older computers while still getting maximum performance, since one can dynamically dispatch to an implementation that uses only what is supported. (E.g. switch between an SSE2 version and an AVX version.)
I think GP is saying that unit tests for such dynamically-dispatching code will want to be able to inject older CPUIDs, so the compatibility fallbacks have test coverage. If CPUID is a native instruction, it's harder to inject a fake value.
I'm not sure I find this compelling though. It's easy to make your own CPUID function that doesn't actually call "CPUID" in a test build.
1. Malware can infer details from CPUID to guess if it’s in a VM or not. Useful to avoid detection/analysis.
2. When processes execute in a legacy mode you may trap on CPUID to hide details the library won’t understand, or doesn’t expect to exist. To avoid backwards compatibility issues... better safe then sorry.
3. When developing SIMD related libraries which need to be portable across multiple CPU versions you may set up a CPUID mask (so trap, then hide features) to ensure compatibility on legacy computers.
Overall having the ability to trap, and rewrite the CPUID instruction is incredibly useful. The difference between denying, and rewriting just boils down to if a callback is provided or not. Both features require disabling native CPUID execution.