diff options
author | Michael Brown <mcb30@ipxe.org> | 2024-07-31 16:43:27 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2024-08-01 12:54:49 +0100 |
commit | a064d397688930dcb341f62587db4e8e786777a0 (patch) | |
tree | b2e5e47d170d658c2dc7c5963895c081863f976c | |
parent | 121d96b903b221e2c63fa0fc5a8901dc24645a47 (diff) | |
download | ipxe-a064d397688930dcb341f62587db4e8e786777a0.zip ipxe-a064d397688930dcb341f62587db4e8e786777a0.tar.gz ipxe-a064d397688930dcb341f62587db4e8e786777a0.tar.bz2 |
[cpuid] Allow hypervisor CPUID leaves to be accessed as settings
Redefine bit 30 of an SMBIOS numerical setting to be part of the
function number, in order to allow access to hypervisor CPUID leaves.
This technically breaks backwards compatibility with scripts
attempting to read more than 64 consecutive functions. Since there is
no meaningful block of 64 consecutive related functions, it is
vanishingly unlikely that this capability has ever been used.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r-- | src/arch/x86/core/cpuid_settings.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/src/arch/x86/core/cpuid_settings.c b/src/arch/x86/core/cpuid_settings.c index 0b67ee9..9bc69f4 100644 --- a/src/arch/x86/core/cpuid_settings.c +++ b/src/arch/x86/core/cpuid_settings.c @@ -38,7 +38,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * * Bit 31 Extended function * Bits 30-24 (bit 22 = 1) Subfunction number - * (bit 22 = 0) Number of consecutive functions to call, minus one + * Bit 30 (bit 22 = 0) Hypervisor function + * Bits 29-24 (bit 22 = 0) Number of consecutive functions to call, minus one * Bit 23 Return result as little-endian (used for strings) * Bit 22 Interpret bits 30-24 as a subfunction number * Bits 21-18 Unused @@ -98,7 +99,7 @@ enum cpuid_flags { * @v tag Setting tag * @ret function Starting function number */ -#define CPUID_FUNCTION( tag ) ( (tag) & 0x800000ffUL ) +#define CPUID_FUNCTION( tag ) ( (tag) & 0xc00000ffUL ) /** * Extract subfunction number from CPUID setting tag @@ -109,6 +110,14 @@ enum cpuid_flags { #define CPUID_SUBFUNCTION( tag ) ( ( (tag) >> 24 ) & 0x7f ) /** + * Extract number of consecutive functions from CPUID setting tag + * + * @v tag Setting tag + * @ret num_functions Number of consecutive functions + */ +#define CPUID_NUM_FUNCTIONS( tag ) ( ( ( (tag) >> 24 ) & 0x3f ) + 1 ) + +/** * Extract register array from CPUID setting tag * * @v tag Setting tag @@ -165,12 +174,13 @@ static int cpuid_settings_fetch ( struct settings *settings, /* Call each function in turn */ function = CPUID_FUNCTION ( setting->tag ); - subfunction = CPUID_SUBFUNCTION ( setting->tag ); if ( setting->tag & CPUID_USE_SUBFUNCTION ) { + function &= ~CPUID_HYPERVISOR; + subfunction = CPUID_SUBFUNCTION ( setting->tag ); num_functions = 1; } else { - num_functions = ( subfunction + 1 ); subfunction = 0; + num_functions = CPUID_NUM_FUNCTIONS ( setting->tag ); } for ( ; num_functions-- ; function++ ) { |