aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2024-07-31 16:43:27 +0100
committerMichael Brown <mcb30@ipxe.org>2024-08-01 12:54:49 +0100
commita064d397688930dcb341f62587db4e8e786777a0 (patch)
treeb2e5e47d170d658c2dc7c5963895c081863f976c
parent121d96b903b221e2c63fa0fc5a8901dc24645a47 (diff)
downloadipxe-master.zip
ipxe-master.tar.gz
ipxe-master.tar.bz2
[cpuid] Allow hypervisor CPUID leaves to be accessed as settingsHEADmaster
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.c18
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++ ) {