@@ -30,41 +30,38 @@ static inline void pvm_cpuid(unsigned int *eax, unsigned int *ebx,
3030}
3131
3232/*
33- * pvm_detect() is called before event handling is set up and it might be
34- * possibly called under any hypervisor other than PVM, so it should not
35- * trigger any trap in all possible scenarios. PVM_SYNTHETIC_CPUID is supposed
36- * to not trigger any trap in the real or virtual x86 kernel mode and is also
37- * guaranteed to trigger a trap in the underlying hardware user mode for the
38- * hypervisor emulating it.
33+ * pvm_detect() is required to be called before event handling is set up, but
34+ * it might also be possibly called under any hypervisor other than PVM.
35+ *
36+ * Any hypervisor that places the guest kernel in a state where the underlying
37+ * interrupt flag is enabled and the underlying CS is 3 should intercept
38+ * the CPUID instruction in the PVM_SYNTHETIC_CPUID, which must not trigger
39+ * any trap according to the corresponding [paravirtual] architecture.
3940 */
4041static inline bool pvm_detect (void )
4142{
4243 unsigned long cs ;
4344 uint32_t eax , signature [3 ];
4445
45- /* check underlying interrupt flags */
46+ /* check the underlying interrupt flag */
4647 if (arch_irqs_disabled_flags (native_save_fl ()))
4748 return false;
4849
49- /* check underlying CS */
50+ /* check the underlying CS */
5051 asm volatile ("mov %%cs,%0\n\t" : "=r" (cs ) : );
5152 if ((cs & 3 ) != 3 )
5253 return false;
5354
54- /* check KVM_SIGNATURE and KVM_CPUID_VENDOR_FEATURES */
55+ /* check the KVM_SIGNATURE leaf */
5556 eax = KVM_CPUID_SIGNATURE ;
5657 pvm_cpuid (& eax , & signature [0 ], & signature [1 ], & signature [2 ]);
5758 if (memcmp (KVM_SIGNATURE , signature , 12 ))
5859 return false;
59- if (eax < KVM_CPUID_VENDOR_FEATURES )
60- return false;
61-
62- /* check PVM_CPUID_SIGNATURE */
63- eax = KVM_CPUID_VENDOR_FEATURES ;
64- pvm_cpuid (& eax , & signature [0 ], & signature [1 ], & signature [2 ]);
65- if (signature [0 ] != PVM_CPUID_SIGNATURE )
66- return false;
6760
61+ /*
62+ * PVM is the only KVM variant that places the guest kernel in
63+ * a state where the underlying IF == 1 and underlying CS == 3.
64+ */
6865 return true;
6966}
7067#else
0 commit comments