xl: add cpuid parsing and translation
PATCH 2/2 xl: add cpuid parsing and translation
Hi,
this one actually parses the cpuid option string and translates it into the 32-character string libxc expects. Please comment!
Signed-off-by Andre Przywara <[email protected]>
Signature · 3 lines
Andre Przywara AMD-Operating System Research Center (OSRC), Dresden, Germany Tel: +49 351 448-3567-12
Quoted 1 line
From
042a22523e7ea68019e0a5733139671435d50ccfMon Sep 17 00:00:00 2001
From: Andre Przywara <[email protected]>
Date: Thu, 19 Aug 2010 11:51:00 +0200
Subject: [PATCH 2/2] xl: implement parsing of cpuid parameter and translate to Xen interface
Signed-off-by Andre Przywara <[email protected]>
--- tools/libxl/xl_cmdimpl.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 209 insertions(+), 0 deletions(-)
tools/libxl/xl_cmdimpl.c +209 -0
@@ -562,6 +562,212 @@ static int parse_action_on_shutdown(const char *buf, enum action_on_shutdown *a)return 0 ; } +#define REG_INV 0 +#define REG_EAX 1 +#define REG_EBX 2 +#define REG_ECX 3 +#define REG_EDX 4 + +struct cpuid_flags { +char * name; +uint32_t leaf; +int reg; +int bit; +int length; +}; + +static libxl_cpuid_type *cpuid_find_match (libxl_cpuid_type **list, +uint32_t leaf,uint32_t subleaf) +{ +int i =0 ; + +if (*list !=NULL ) { +for (i =0 ; (*list)[i].input[0 ] !=XEN_CPUID_INPUT_UNUSED ; i++) { +if ((*list)[i].input[0 ] == leaf && (*list)[i].input[1 ] == subleaf) +return *list + i; + } + } + *list =realloc (*list,sizeof (libxl_cpuid_type) * (i +2 )); + (*list)[i].input[0 ] = leaf; + (*list)[i].input[1 ] = subleaf; +memset ((*list)[i].policy,0 ,4 *sizeof (char *)); + (*list)[i +1 ].input[0 ] =XEN_CPUID_INPUT_UNUSED ; +return *list + i; +} + +static libxl_cpuid_type *parse_cpuid (const char * cpuidstr) +{ +struct cpuid_flags cpuid_flags[] = { + {"maxleaf" ,0x00000000 ,REG_EAX ,0 ,32 }, + {"family" ,0x00000001 ,REG_EAX ,8 ,8 },/* subject to tweaking */ + {"model" ,0x00000001 ,REG_EAX ,4 ,8 },/* subject to tweaking */ + {"stepping" ,0x00000001 ,REG_EAX ,0 ,4 }, + {"localapicid" ,0x00000001 ,REG_EBX ,24 ,8 }, + {"proccount" ,0x00000001 ,REG_EBX ,16 ,8 }, + {"clflush" ,0x00000001 ,REG_EBX ,8 ,8 }, + {"brandid" ,0x00000001 ,REG_EBX ,0 ,8 }, + {"osxsave" ,0x00000001 ,REG_ECX ,27 ,1 }, + {"xsave" ,0x00000001 ,REG_ECX ,26 ,1 }, + {"popcnt" ,0x00000001 ,REG_ECX ,23 ,1 }, + {"movbe" ,0x00000001 ,REG_ECX ,22 ,1 }, + {"x2apic" ,0x00000001 ,REG_ECX ,21 ,1 }, + {"sse4.2" ,0x00000001 ,REG_ECX ,20 ,1 }, + {"sse4.1" ,0x00000001 ,REG_ECX ,19 ,1 }, + {"dca" ,0x00000001 ,REG_ECX ,18 ,1 }, + {"pdcm" ,0x00000001 ,REG_ECX ,15 ,1 }, + {"xtpr" ,0x00000001 ,REG_ECX ,14 ,1 }, + {"cmpxchg16" ,0x00000001 ,REG_ECX ,13 ,1 }, + {"cntxid" ,0x00000001 ,REG_ECX ,10 ,1 }, + {"ssse3" ,0x00000001 ,REG_ECX ,9 ,1 }, + {"tm2" ,0x00000001 ,REG_ECX ,8 ,1 }, + {"est" ,0x00000001 ,REG_ECX ,7 ,1 }, + {"smx" ,0x00000001 ,REG_ECX ,6 ,1 }, + {"vmx" ,0x00000001 ,REG_ECX ,5 ,1 }, + {"dscpl" ,0x00000001 ,REG_ECX ,4 ,1 }, + {"monitor" ,0x00000001 ,REG_ECX ,3 ,1 }, + {"dtes64" ,0x00000001 ,REG_ECX ,2 ,1 }, + {"sse3" ,0x00000001 ,REG_ECX ,0 ,1 }, + {"pbe" ,0x00000001 ,REG_EDX ,31 ,1 }, + {"ia64" ,0x00000001 ,REG_EDX ,30 ,1 }, + {"tm" ,0x00000001 ,REG_EDX ,29 ,1 }, + {"htt" ,0x00000001 ,REG_EDX ,28 ,1 }, + {"ss" ,0x00000001 ,REG_EDX ,27 ,1 }, + {"sse2" ,0x00000001 ,REG_EDX ,26 ,1 }, + {"sse" ,0x00000001 ,REG_EDX ,25 ,1 }, + {"fxsr" ,0x00000001 ,REG_EDX ,24 ,1 }, + {"mmx" ,0x00000001 ,REG_EDX ,23 ,1 }, + {"acpi" ,0x00000001 ,REG_EDX ,22 ,1 }, + {"ds" ,0x00000001 ,REG_EDX ,21 ,1 }, + {"clfsh" ,0x00000001 ,REG_EDX ,19 ,1 }, + {"psn" ,0x00000001 ,REG_EDX ,18 ,1 }, + {"pse36" ,0x00000001 ,REG_EDX ,17 ,1 }, + {"pat" ,0x00000001 ,REG_EDX ,16 ,1 }, + {"cmov" ,0x00000001 ,REG_EDX ,15 ,1 }, + {"mca" ,0x00000001 ,REG_EDX ,14 ,1 }, + {"pge" ,0x00000001 ,REG_EDX ,13 ,1 }, + {"mtrr" ,0x00000001 ,REG_EDX ,12 ,1 }, + {"sysenter" ,0x00000001 ,REG_EDX ,11 ,1 }, + {"apic" ,0x00000001 ,REG_EDX ,9 ,1 }, + {"cmpxchg8" ,0x00000001 ,REG_EDX ,8 ,1 }, + {"mce" ,0x00000001 ,REG_EDX ,7 ,1 }, + {"pae" ,0x00000001 ,REG_EDX ,6 ,1 }, + {"msr" ,0x00000001 ,REG_EDX ,5 ,1 }, + {"tsc" ,0x00000001 ,REG_EDX ,4 ,1 }, + {"pse" ,0x00000001 ,REG_EDX ,3 ,1 }, + {"de" ,0x00000001 ,REG_EDX ,2 ,1 }, + {"vme" ,0x00000001 ,REG_EDX ,1 ,1 }, + {"fpu" ,0x00000001 ,REG_EDX ,0 ,1 }, + {"wdt" ,0x80000001 ,REG_ECX ,13 ,1 }, + {"skinit" ,0x80000001 ,REG_ECX ,12 ,1 }, + {"xop" ,0x80000001 ,REG_ECX ,11 ,1 }, + {"ibs" ,0x80000001 ,REG_ECX ,10 ,1 }, + {"osvw" ,0x80000001 ,REG_ECX ,10 ,1 }, + {"3dnowprefetch" ,0x80000001 ,REG_ECX ,8 ,1 }, + {"misalignsse" ,0x80000001 ,REG_ECX ,7 ,1 }, + {"sse4a" ,0x80000001 ,REG_ECX ,6 ,1 }, + {"abm" ,0x80000001 ,REG_ECX ,5 ,1 }, + {"altmovcr8" ,0x80000001 ,REG_ECX ,4 ,1 }, + {"extapic" ,0x80000001 ,REG_ECX ,3 ,1 }, + {"svm" ,0x80000001 ,REG_ECX ,2 ,1 }, + {"cmplegacy" ,0x80000001 ,REG_ECX ,1 ,1 }, + {"lahfsahf" ,0x80000001 ,REG_ECX ,0 ,1 }, + {"3dnowext" ,0x80000001 ,REG_EDX ,31 ,1 }, + {"3dnow" ,0x80000001 ,REG_EDX ,30 ,1 }, + {"lm" ,0x80000001 ,REG_EDX ,29 ,1 }, + {"rdtscp" ,0x80000001 ,REG_EDX ,27 ,1 }, + {"page1gb" ,0x80000001 ,REG_EDX ,26 ,1 }, + {"ffxsr" ,0x80000001 ,REG_EDX ,25 ,1 }, + {"mmxext" ,0x80000001 ,REG_EDX ,22 ,1 }, + {"nx" ,0x80000001 ,REG_EDX ,20 ,1 }, + {"syscall" ,0x80000001 ,REG_EDX ,11 ,1 }, + {"apicidsize" ,0x80000008 ,REG_ECX ,12 ,4 }, + {"nc" ,0x80000008 ,REG_ECX ,0 ,8 }, + + {NULL ,0 ,0 ,0 ,0 } + }; +char *buf, *strtok_ptr, *p, *val, *endptr; +int i; +struct cpuid_flags *flag; +libxl_cpuid_type *cpuid_info =NULL , *entry; +unsigned long num; +char flags[33 ], *resstr; + + buf =strdup (cpuidstr); + p =strtok_r (buf,"," , &strtok_ptr); +/* base model is ignored for now */ +for (; p; p =strtok_r (NULL ,"," , &strtok_ptr)) { + val =strchr (p,'=' ); +/* detect leading + or - for en/disabling feature bits */ +if (val ==NULL ) { +if (*p =='+' ) { + p++; + val ="1" ; + }else if (*p =='-' ) { + p++; + val ="0" ; + }else +continue ; + }else { + *val++ =0 ; + } +for (flag = cpuid_flags; flag->name !=NULL ; flag++) +if (!strcmp (p, flag->name)) +break ; +if (flag->name ==NULL ) { +fprintf (stderr,"cpuid: could not find feature called \"%s\"\n" , p); +continue ; + } + entry =cpuid_find_match (&cpuid_info, flag->leaf, +XEN_CPUID_INPUT_UNUSED ); + resstr = entry->policy[flag->reg -1 ]; +if (resstr ==NULL ) + resstr =strdup ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ); + num =strtoull (val, &endptr,0 ); + flags[flag->length] =0 ; +if (endptr != val) { +for (i =0 ; i < flag->length; i++) + flags[flag->length -1 - i] ="01" [!!(num & (1 << i))]; + }else { +switch (val[0 ]) { +case 'x' :case 'k' :case 's' : +memset (flags, val[0 ], flag->length); +break ; +default : +fprintf (stderr, +"invalid value \"%s\" for flag \"%s\"\n" , + val, p); +continue ; + } + } +/* the family and model entry is potentially split up across +* two fields in Fn0000_0001_EAX, so handle them here separately. +*/ +if (!strcmp (p,"family" )) { +if (num <16 ) { +memcpy (resstr + (32 -4 ) - flag->bit, flags +4 ,4 ); +memcpy (resstr + (32 -8 ) -20 ,"00000000" ,8 ); + }else { + num -=15 ; +memcpy (resstr + (32 -4 ) - flag->bit,"1111" ,4 ); +for (i =0 ; i <7 ; i++) { + flags[7 - i] ="01" [num &1 ]; + num >>=1 ; + } +memcpy (resstr + (32 -8 ) -20 , flags,8 ); + } + }else if (!strcmp (p,"model" )) { +memcpy (resstr + (32 -4 ) -16 , flags,4 ); +memcpy (resstr + (32 -4 ) - flag->bit, flags +4 ,4 ); + }else +memcpy (resstr + (32 - flag->length) - flag->bit, flags, + flag->length); + entry->policy[flag->reg -1 ] = resstr; + } +free (buf); + +return cpuid_info; +} + static void parse_config_data(const char *configfile_filename_report, const char *configfile_data, int configfile_len,
@@ -1001,6 +1207,9 @@ skip_vfb: } } +if (!xlu_cfg_get_string (config,"cpuid" , &buf)) + b_info->cpuid =parse_cpuid (buf); +if (c_info->hvm ==1 ) {/* init dm from c and b */ init_dm_info (dm_info, c_info, b_info);
Signature · 1 line
1.6.4
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel