static __always_inline bool cpuid_function_is_indexed(u32 function)
{ switch (function) { case 4: case 7: case 0xb: case 0xd: case 0xf: case 0x10: case 0x12: case 0x14: case 0x17: case 0x18: case 0x1d: case 0x1e: case 0x1f: case 0x24: case 0x8000001d: returntrue;
}
returnfalse;
}
#define for_each_possible_cpuid_base_hypervisor(function) \ for (function = 0x40000000; function < 0x40010000; function += 0x100)
/* * This must not compile to "call memcmp" because it's called * from PVH early boot code before instrumentation is set up * and memcmp() itself may be instrumented.
*/ if (!__builtin_memcmp(sig, signature, 12) &&
(leaves == 0 || ((eax - base) >= leaves))) return base;
}
return 0;
}
/* * CPUID(0x2) parsing:
*/
/** * cpuid_leaf_0x2() - Return sanitized CPUID(0x2) register output * @regs: Output parameter * * Query CPUID(0x2) and store its output in @regs. Force set any * invalid 1-byte descriptor returned by the hardware to zero (the NULL * cache/TLB descriptor) before returning it to the caller. * * Use for_each_cpuid_0x2_desc() to iterate over the register output in * parsed form.
*/ staticinlinevoid cpuid_leaf_0x2(union leaf_0x2_regs *regs)
{
cpuid_leaf(0x2, regs);
/* * All Intel CPUs must report an iteration count of 1. In case * of bogus hardware, treat all returned descriptors as NULL.
*/ if (regs->desc[0] != 0x01) { for (int i = 0; i < 4; i++)
regs->regv[i] = 0; return;
}
/* * The most significant bit (MSB) of each register must be clear. * If a register is invalid, replace its descriptors with NULL.
*/ for (int i = 0; i < 4; i++) { if (regs->reg[i].invalid)
regs->regv[i] = 0;
}
}
/** * for_each_cpuid_0x2_desc() - Iterator for parsed CPUID(0x2) descriptors * @_regs: CPUID(0x2) register output, as returned by cpuid_leaf_0x2() * @_ptr: u8 pointer, for macro internal use only * @_desc: Pointer to the parsed CPUID(0x2) descriptor at each iteration * * Loop over the 1-byte descriptors in the passed CPUID(0x2) output registers * @_regs. Provide the parsed information for each descriptor through @_desc. * * To handle cache-specific descriptors, switch on @_desc->c_type. For TLB * descriptors, switch on @_desc->t_type. * * Example usage for cache descriptors:: * * const struct leaf_0x2_table *desc; * union leaf_0x2_regs regs; * u8 *ptr; * * cpuid_leaf_0x2(®s); * for_each_cpuid_0x2_desc(regs, ptr, desc) { * switch (desc->c_type) { * ... * } * }
*/ #define for_each_cpuid_0x2_desc(_regs, _ptr, _desc) \ for (_ptr = &(_regs).desc[1]; \
_ptr < &(_regs).desc[16] && (_desc = &cpuid_0x2_table[*_ptr]); \
_ptr++)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.