@@ -120,6 +120,8 @@ extern int usb_enabled;
extern int virtio_balloon;
extern const char *virtio_balloon_devaddr;
extern int smp_cpus;
+extern int cpu_cores;
+extern int core_threads;
extern int cursor_hide;
extern int graphic_rotate;
extern int no_quit;
@@ -24,6 +24,8 @@
#include <inttypes.h>
#include <signal.h>
+#include "qemu-common.h"
+#include "sysemu.h"
#include "cpu.h"
#include "exec-all.h"
#include "qemu-common.h"
@@ -122,7 +124,7 @@ static x86_def_t x86_defs[] = {
#ifdef TARGET_X86_64
{
.name = "qemu64",
- .level = 2,
+ .level = 4,
.vendor1 = CPUID_VENDOR_AMD_1,
.vendor2 = CPUID_VENDOR_AMD_2,
.vendor3 = CPUID_VENDOR_AMD_3,
@@ -194,7 +196,7 @@ static x86_def_t x86_defs[] = {
#endif
{
.name = "qemu32",
- .level = 2,
+ .level = 4,
.family = 6,
.model = 3,
.stepping = 3,
@@ -260,7 +262,7 @@ static x86_def_t x86_defs[] = {
},
{
.name = "athlon",
- .level = 2,
+ .level = 4,
.vendor1 = CPUID_VENDOR_AMD_1,
.vendor2 = CPUID_VENDOR_AMD_2,
.vendor3 = CPUID_VENDOR_AMD_3,
@@ -483,6 +485,8 @@ static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
env->cpuid_version |= def->stepping;
env->cpuid_features = def->features;
+ if (cpu_cores * core_threads > 1)
+ env->cpuid_features |= CPUID_HT;
env->pat = 0x0007040600070406ULL;
env->cpuid_ext_features = def->ext_features;
env->cpuid_ext2_features = def->ext2_features;
@@ -1564,7 +1568,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
break;
case 1:
*eax = env->cpuid_version;
- *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
+ *ebx = (env->cpuid_apic_id << 24) | (cpu_cores*core_threads) << 16
+ | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
*ecx = env->cpuid_ext_features;
*edx = env->cpuid_features;
break;
@@ -1579,7 +1584,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
/* cache info: needed for Core compatibility */
switch (count) {
case 0: /* L1 dcache info */
- *eax = 0x0000121;
+ *eax = 0x0000121 | ((cpu_cores - 1) << 26);
*ebx = 0x1c0003f;
*ecx = 0x000003f;
*edx = 0x0000001;
@@ -244,6 +244,8 @@ int singlestep = 0;
const char *assigned_devices[MAX_DEV_ASSIGN_CMDLINE];
int assigned_devices_index;
int smp_cpus = 1;
+int cpu_cores = 1;
+int core_threads = 1;
const char *vnc_display;
int acpi_enabled = 1;
int no_hpet = 0;
@@ -5696,12 +5698,23 @@ int main(int argc, char **argv, char **envp)
usb_devices_index++;
break;
case QEMU_OPTION_smp:
- smp_cpus = atoi(optarg);
+ {
+ char *p;
+ char option[128];
+ smp_cpus = strtol(optarg, &p, 10);
if (smp_cpus < 1) {
- fprintf(stderr, "Invalid number of CPUs\n");
+ fprintf(stderr, "Invalid number of slots\n");
exit(1);
}
+ if (*p++ != ',')
+ break;
+ if (get_param_value(option, 128, "cores", p))
+ cpu_cores = strtol(option, NULL, 0);
+ if (get_param_value(option, 128, "threads", p))
+ core_threads = strtol(option, NULL, 0);
+ smp_cpus *= (cpu_cores * core_threads);
break;
+ }
case QEMU_OPTION_vnc:
display_type = DT_VNC;
vnc_display = optarg;