From 121d96b903b221e2c63fa0fc5a8901dc24645a47 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 31 Jul 2024 16:35:31 +0100 Subject: [cpuid] Allow reading hypervisor CPUID leaves Hypervisors typically intercept CPUID leaves in the range 0x40000000 to 0x400000ff, with leaf 0x40000000 returning the maximum supported function within this range in register %eax. iPXE currently masks off bit 30 from the requested CPUID leaf when checking to see if a function is supported, which causes this check to read from leaf 0x00000000 instead of 0x40000000. Fix by including bit 30 within the mask. Signed-off-by: Michael Brown --- src/arch/x86/core/cpuid.c | 4 ++-- src/arch/x86/include/ipxe/cpuid.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/core/cpuid.c b/src/arch/x86/core/cpuid.c index 1a7c93e83..b7d9fb6c6 100644 --- a/src/arch/x86/core/cpuid.c +++ b/src/arch/x86/core/cpuid.c @@ -84,8 +84,8 @@ int cpuid_supported ( uint32_t function ) { return rc; /* Find highest supported function number within this family */ - cpuid ( ( function & CPUID_EXTENDED ), 0, &max_function, &discard_b, - &discard_c, &discard_d ); + cpuid ( ( function & ( CPUID_EXTENDED | CPUID_HYPERVISOR ) ), 0, + &max_function, &discard_b, &discard_c, &discard_d ); /* Fail if maximum function number is meaningless (e.g. if we * are attempting to call an extended function on a CPU which diff --git a/src/arch/x86/include/ipxe/cpuid.h b/src/arch/x86/include/ipxe/cpuid.h index 90d1bf01d..99b91c5c8 100644 --- a/src/arch/x86/include/ipxe/cpuid.h +++ b/src/arch/x86/include/ipxe/cpuid.h @@ -33,6 +33,9 @@ struct x86_features { /** CPUID extended function */ #define CPUID_EXTENDED 0x80000000UL +/** CPUID hypervisor function */ +#define CPUID_HYPERVISOR 0x40000000UL + /** Get vendor ID and largest standard function */ #define CPUID_VENDOR_ID 0x00000000UL -- cgit