Hi, On 24/09/2007, Dan Kenigsberg <[EMAIL PROTECTED]> wrote: > As with previous "Takes" of this patch, its purpose is to expose host > CPU features to guests. It proved rather helpful to KVM in various > benchmarks, and it should similarly speed kqemu up. Note that it does > not extend the set of emulated opcodes, only exposes what's supported by > the host CPU. > > Another purpose for "Take 2" is to add the -cpu option to the x86 > architecture, similarly to that of other architectures. > -cpu 486, pentium, pentium2 and pentium3 are supported in addition to > finer-grained features such as -cpu pentium,-mmx . As in Take 1, > -cpu host exposes host features to guest. > > This patch exposes the requested CPU also right after RESET command, and > not only in CPUID. > > Please let me know if you have more suggestions, > > Dan. > > ======================================= > > Index: vl.c > =================================================================== > RCS file: /sources/qemu/qemu/vl.c,v > retrieving revision 1.342 > diff -u -p -r1.342 vl.c > --- vl.c 17 Sep 2007 21:25:20 -0000 1.342 > +++ vl.c 24 Sep 2007 16:53:29 -0000 > @@ -7694,6 +7694,8 @@ int main(int argc, char **argv) > mips_cpu_list(stdout, &fprintf); > #elif defined(TARGET_SPARC) > sparc_cpu_list(stdout, &fprintf); > +#elif defined(TARGET_I386) > + x86_cpu_list(stdout, &fprintf); > #endif > exit(0); > } else { > Index: hw/pc.c > =================================================================== > RCS file: /sources/qemu/qemu/hw/pc.c,v > retrieving revision 1.85 > diff -u -p -r1.85 pc.c > --- hw/pc.c 17 Sep 2007 08:09:47 -0000 1.85 > +++ hw/pc.c 24 Sep 2007 16:53:29 -0000 > @@ -666,7 +666,7 @@ static void pc_init1(int ram_size, int v > DisplayState *ds, const char **fd_filename, int > snapshot, > const char *kernel_filename, const char *kernel_cmdline, > const char *initrd_filename, > - int pci_enabled) > + int pci_enabled, const char *cpu_model) > { > char buf[1024]; > int ret, linux_boot, i; > @@ -682,6 +682,13 @@ static void pc_init1(int ram_size, int v > linux_boot = (kernel_filename != NULL); > > /* init CPUs */ > + if (cpu_model == NULL) > + cpu_model = "basic"; > + > + if (x86_find_cpu_by_name(cpu_model)) { > + fprintf(stderr, "Unable to find x86 CPU definition\n"); > + exit(1); > + } > for(i = 0; i < smp_cpus; i++) { > env = cpu_init(); > if (i != 0) > @@ -948,7 +955,7 @@ static void pc_init_pci(int ram_size, in > pc_init1(ram_size, vga_ram_size, boot_device, > ds, fd_filename, snapshot, > kernel_filename, kernel_cmdline, > - initrd_filename, 1); > + initrd_filename, 1, cpu_model); > } > > static void pc_init_isa(int ram_size, int vga_ram_size, int boot_device, > @@ -962,7 +969,7 @@ static void pc_init_isa(int ram_size, in > pc_init1(ram_size, vga_ram_size, boot_device, > ds, fd_filename, snapshot, > kernel_filename, kernel_cmdline, > - initrd_filename, 0); > + initrd_filename, 0, cpu_model); > } > > QEMUMachine pc_machine = { > Index: target-i386/cpu.h > =================================================================== > RCS file: /sources/qemu/qemu/target-i386/cpu.h,v > retrieving revision 1.48 > diff -u -p -r1.48 cpu.h > --- target-i386/cpu.h 23 Sep 2007 15:28:04 -0000 1.48 > +++ target-i386/cpu.h 24 Sep 2007 16:53:30 -0000 > @@ -274,23 +274,56 @@ > #define CPUID_CMOV (1 << 15) > #define CPUID_PAT (1 << 16) > #define CPUID_PSE36 (1 << 17) > +#define CPUID_PN (1 << 18) > #define CPUID_CLFLUSH (1 << 19) > -/* ... */ > +#define CPUID_DTS (1 << 21) > +#define CPUID_ACPI (1 << 22) > #define CPUID_MMX (1 << 23) > #define CPUID_FXSR (1 << 24) > #define CPUID_SSE (1 << 25) > #define CPUID_SSE2 (1 << 26) > +#define CPUID_SS (1 << 27) > +#define CPUID_HT (1 << 28) > +#define CPUID_TM (1 << 29) > +#define CPUID_IA64 (1 << 30) > +#define CPUID_PBE (1 << 31) > > #define CPUID_EXT_SSE3 (1 << 0) > #define CPUID_EXT_MONITOR (1 << 3) > +#define CPUID_EXT_DSCPL (1 << 4) > +#define CPUID_EXT_VMX (1 << 5) > +#define CPUID_EXT_SMX (1 << 6) > +#define CPUID_EXT_EST (1 << 7) > +#define CPUID_EXT_TM2 (1 << 8) > +#define CPUID_EXT_SSSE3 (1 << 9) > +#define CPUID_EXT_CID (1 << 10) > #define CPUID_EXT_CX16 (1 << 13) > +#define CPUID_EXT_XTPR (1 << 14) > +#define CPUID_EXT_DCA (1 << 17) > +#define CPUID_EXT_POPCNT (1 << 22) > > #define CPUID_EXT2_SYSCALL (1 << 11) > +#define CPUID_EXT2_MP (1 << 19) > #define CPUID_EXT2_NX (1 << 20) > +#define CPUID_EXT2_MMXEXT (1 << 22) > #define CPUID_EXT2_FFXSR (1 << 25) > +#define CPUID_EXT2_PDPE1GB (1 << 26) > +#define CPUID_EXT2_RDTSCP (1 << 27) > #define CPUID_EXT2_LM (1 << 29) > +#define CPUID_EXT2_3DNOWEXT (1 << 30) > +#define CPUID_EXT2_3DNOW (1 << 31) > > +#define CPUID_EXT3_LAHF_LM (1 << 0) > +#define CPUID_EXT3_CMP_LEG (1 << 1) > #define CPUID_EXT3_SVM (1 << 2) > +#define CPUID_EXT3_EXTAPIC (1 << 3) > +#define CPUID_EXT3_CR8LEG (1 << 4) > +#define CPUID_EXT3_ABM (1 << 5) > +#define CPUID_EXT3_SSE4A (1 << 6) > +#define CPUID_EXT3_MISALIGNSSE (1 << 7) > +#define CPUID_EXT3_3DNOWPREFETCH (1 << 8) > +#define CPUID_EXT3_OSVW (1 << 9) > +#define CPUID_EXT3_IBS (1 << 10) > > #define EXCP00_DIVZ 0 > #define EXCP01_SSTP 1 > @@ -564,6 +597,9 @@ typedef struct CPUX86State { > CPUX86State *cpu_x86_init(void); > int cpu_x86_exec(CPUX86State *s); > void cpu_x86_close(CPUX86State *s); > +int x86_find_cpu_by_name (const unsigned char *name); > +void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, > + ...)); > int cpu_get_pic_interrupt(CPUX86State *s); > /* MSDOS compatibility mode FPU exception support */ > void cpu_set_ferr(CPUX86State *s); > Index: target-i386/helper2.c > =================================================================== > RCS file: /sources/qemu/qemu/target-i386/helper2.c,v > retrieving revision 1.52 > diff -u -p -r1.52 helper2.c > --- target-i386/helper2.c 23 Sep 2007 15:28:04 -0000 1.52 > +++ target-i386/helper2.c 24 Sep 2007 16:53:30 -0000 > @@ -46,6 +46,98 @@ int modify_ldt(int func, void *ptr, unsi > #endif > #endif /* USE_CODE_COPY */ > > +static struct x86_def_t *x86_cpu_def; > +typedef struct x86_def_t x86_def_t; > +static int cpu_x86_register (CPUX86State *env, const x86_def_t *def); > + > +/* x86_cap_flags taken from Linux's arch/i386/kernel/cpu/proc.c */ > +static const char * const x86_cap_flags[] = { > + /* Intel-defined */ > + "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", > + "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", > + "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx", > + "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe", > + > + /* AMD-defined */ > + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, > + NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, > + NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL, > + NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext", > "3dnow", > + > + /* Transmeta-defined */ > + "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL, > + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, > + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, > + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, > + > + /* Other (Linux-defined) */ > + "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", > + NULL, NULL, NULL, NULL, > + "constant_tsc", "up", NULL, NULL, NULL, NULL, NULL, NULL, > + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, > + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, > + > + /* Intel-defined (#2) */ > + "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est", > + "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL, > + NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt", > + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, > + > + /* VIA/Cyrix/Centaur-defined */ > + NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en", > + "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL, > + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, > + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, > + > + /* AMD-defined (#2) */ > + "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8legacy", "abm", > + "sse4a", "misalignsse", > + "3dnowprefetch", "osvw", "ibs", NULL, NULL, NULL, NULL, NULL, > + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, > + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, > +}; > + > +void add_flagname_to_bitmaps(char *flagname, uint32_t *features, uint32_t > *ext_features, uint32_t *ext2_features, uint32_t *ext3_features) > +{ > + int i; > + for ( i = 0 ; i < 32 ; i++ ) > + if (x86_cap_flags[i] && !strcmp (flagname, x86_cap_flags[i])) { > + *features |= 1 << i; > + return; > + } > + for ( i = 0 ; i < 32 ; i++ ) > + if (x86_cap_flags[32*4+i] && !strcmp (flagname, > x86_cap_flags[32*4+i])) { > + *ext_features |= 1 << i; > + return; > + } > + for ( i = 0 ; i < 32 ; i++ ) > + if (x86_cap_flags[32*1+i] && !strcmp (flagname, > x86_cap_flags[32*1+i])) { > + *ext2_features |= 1 << i; > + return; > + } > + for ( i = 0 ; i < 32 ; i++ ) > + if (x86_cap_flags[32*6+i] && !strcmp (flagname, > x86_cap_flags[32*6+i])) { > + *ext3_features |= 1 << i; > + return; > + } > + /* Silently ignore Linux-defined features */ > + for ( i = 0 ; i < 32 ; i++ ) > + if (x86_cap_flags[32*3+i] && !strcmp (flagname, > x86_cap_flags[32*3+i])) { > + return; > + } > + fprintf(stderr, "CPU feature %s not found\n", flagname); > +} > + > +static void host_cpuid (uint32_t function, uint32_t *ax,uint32_t *bx, > uint32_t *cx, uint32_t *dx) > +{ > + asm("cpuid" > + : "=a" (*ax), > + "=b" (*bx), > + "=c" (*cx), > + "=d" (*dx) > + : "a" (function)); > +}
I haven't really read through the rest of your code but this piece appears to be outside any #ifdef/#endif so it will only build on x86. Regards