From: Chris Lalancette <clalance@redhat.com> Date: Fri, 20 Mar 2009 10:23:05 +0100 Subject: [x86] vmware: look for DMI string in product serial key Message-id: 49C36079.5090409@redhat.com O-Subject: [RHEL5.4 PATCH 8/14]: x86: vmware: look for DMI string in the product serial key Bugzilla: 463573 RH-Acked-by: Rik van Riel <riel@redhat.com> RH-Acked-by: Justin M. Forbes <jforbes@redhat.com> Impact: Should permit VMware detection on older platforms where the vendor is changed. Could theoretically cause a regression if some weird serial number scheme contains the string "VMware" by pure chance. Seems unlikely, especially with the mixed case. In some user configured cases, VMware may choose not to put a VMware specifi DMI string, but the product serial key is always there and is VMware specifi Add a interface to check the serial key, when checking for VMware in the DMI information. upstream commit fd8cd7e1919fc1c27fe2fdccd2a1cd32f791ef0f Fixes BZ 463573 diff --git a/arch/i386/kernel/cpu/vmware.c b/arch/i386/kernel/cpu/vmware.c index f17a461..2d377f4 100644 --- a/arch/i386/kernel/cpu/vmware.c +++ b/arch/i386/kernel/cpu/vmware.c @@ -63,6 +63,11 @@ static unsigned long __vmware_get_tsc_khz(void) return tsc_hz; } +/* + * While checking the dmi string infomation, just checking the product + * serial key should be enough, as this will always have a VMware + * specific string when running under VMware hypervisor. + */ int vmware_platform(void) { if (cpu_has_hypervisor) { @@ -76,7 +81,7 @@ int vmware_platform(void) hyper_vendor_id[12] = '\0'; if (!strcmp(hyper_vendor_id, "VMwareVMware")) return 1; - } else if (dmi_name_in_vendors("VMware") && + } else if (dmi_name_in_serial("VMware") && __vmware_platform()) return 1; diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 0ba53d5..14804bc 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -342,6 +342,17 @@ char *dmi_get_system_info(int field) } EXPORT_SYMBOL(dmi_get_system_info); +/** + * dmi_name_in_serial - Check if string is in the DMI product serial information + * @str: string to check for + */ +int dmi_name_in_serial(const char *str) +{ + int f = DMI_PRODUCT_SERIAL; + if (dmi_ident[f] && strstr(dmi_ident[f], str)) + return 1; + return 0; +} /** * dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information. diff --git a/include/linux/dmi.h b/include/linux/dmi.h index 904bf3d..93f21dc 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h @@ -70,6 +70,7 @@ extern struct dmi_device * dmi_find_device(int type, const char *name, extern void dmi_scan_machine(void); extern int dmi_get_year(int field); extern int dmi_name_in_vendors(char *str); +extern int dmi_name_in_serial(const char *str); #else @@ -79,6 +80,7 @@ static inline struct dmi_device * dmi_find_device(int type, const char *name, struct dmi_device *from) { return NULL; } static inline int dmi_get_year(int year) { return 0; } static inline int dmi_name_in_vendors(char *s) { return 0; } +static inline int dmi_name_in_serial(const char *s) { return 0; } #endif