+++ /dev/null
-Index: kvm-86/cpu-defs.h
-===================================================================
---- kvm-86.orig/cpu-defs.h 2009-09-24 14:19:14.000000000 +0200
-+++ kvm-86/cpu-defs.h 2009-09-24 14:47:00.000000000 +0200
-@@ -194,6 +194,8 @@
- int cpu_index; /* CPU index (informative) */ \
- uint32_t host_tid; /* host thread ID */ \
- int numa_node; /* NUMA node this cpu is belonging to */ \
-+ int nr_cores; /* number of cores within this CPU package */ \
-+ int nr_threads;/* number of threads within this CPU */ \
- int running; /* Nonzero if cpu is currently running(usermode). */ \
- int thread_id; \
- /* user data */ \
-Index: kvm-86/target-i386/helper.c
-===================================================================
---- kvm-86.orig/target-i386/helper.c 2009-09-24 14:19:14.000000000 +0200
-+++ kvm-86/target-i386/helper.c 2009-09-24 14:50:18.000000000 +0200
-@@ -121,7 +121,7 @@
- #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,
-@@ -192,7 +192,7 @@
- #endif
- {
- .name = "qemu32",
-- .level = 2,
-+ .level = 4,
- .family = 6,
- .model = 3,
- .stepping = 3,
-@@ -1638,6 +1638,12 @@
- *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
- *ecx = env->cpuid_ext_features;
- *edx = env->cpuid_features;
-+
-+ if (env->nr_cores * env->nr_threads > 1) {
-+ *ebx |= (env->nr_cores * env->nr_threads) << 16;
-+ *edx |= 1 << 28; /* HTT bit */
-+ }
-+
- break;
- case 2:
- /* cache info: needed for Pentium Pro compatibility */
-@@ -1648,21 +1654,29 @@
- break;
- case 4:
- /* cache info: needed for Core compatibility */
-+ if (env->nr_cores > 1) {
-+ *eax = (env->nr_cores - 1) << 26;
-+ } else {
-+ *eax = 0;
-+ }
- switch (count) {
- case 0: /* L1 dcache info */
-- *eax = 0x0000121;
-+ *eax |= 0x0000121;
- *ebx = 0x1c0003f;
- *ecx = 0x000003f;
- *edx = 0x0000001;
- break;
- case 1: /* L1 icache info */
-- *eax = 0x0000122;
-+ *eax |= 0x0000122;
- *ebx = 0x1c0003f;
- *ecx = 0x000003f;
- *edx = 0x0000001;
- break;
- case 2: /* L2 cache info */
-- *eax = 0x0000143;
-+ *eax |= 0x0000143;
-+ if (env->nr_threads > 1) {
-+ *eax |= (env->nr_threads - 1) << 14;
-+ }
- *ebx = 0x3c0003f;
- *ecx = 0x0000fff;
- *edx = 0x0000001;
-@@ -1715,6 +1729,16 @@
- *ecx = env->cpuid_ext3_features;
- *edx = env->cpuid_ext2_features;
-
-+ if (env->nr_cores * env->nr_threads > 1) {
-+ uint32_t teax, tebx, tecx, tedx;
-+ cpu_x86_cpuid(env, 0, 0, &teax, &tebx, &tecx, &tedx);
-+ if ( tebx == CPUID_VENDOR_AMD_1 &&
-+ tedx == CPUID_VENDOR_AMD_2 &&
-+ tecx == CPUID_VENDOR_AMD_3) {
-+ *ecx |= 1 << 1; /* CmpLegacy bit */
-+ }
-+ }
-+
- if (kvm_enabled()) {
- uint32_t h_eax, h_edx;
-
-@@ -1790,6 +1814,9 @@
- *ebx = 0;
- *ecx = 0;
- *edx = 0;
-+ if (env->nr_cores * env->nr_threads > 1) {
-+ *ecx |= (env->nr_cores * env->nr_threads) - 1;
-+ }
- break;
- case 0x8000000A:
- *eax = 0x00000001; /* SVM Revision */
-Index: kvm-86/vl.c
-===================================================================
---- kvm-86.orig/vl.c 2009-09-24 14:30:14.000000000 +0200
-+++ kvm-86/vl.c 2009-09-24 14:47:00.000000000 +0200
-@@ -230,6 +230,8 @@
- const char *assigned_devices[MAX_DEV_ASSIGN_CMDLINE];
- int assigned_devices_index;
- int smp_cpus = 1;
-+int smp_cores = 1;
-+int smp_threads = 1;
- int fairsched_id = 0;
- const char *vnc_display;
- int acpi_enabled = 1;
-@@ -2499,6 +2501,52 @@
- return;
- }
-
-+static void smp_parse(const char *optarg)
-+{
-+ int smp, sockets = 0, threads = 0, cores = 0;
-+ char *endptr;
-+ char option[128];
-+
-+ smp = strtoul(optarg, &endptr, 10);
-+ if (endptr != optarg) {
-+ if (*endptr == ',') {
-+ endptr++;
-+ }
-+ }
-+ if (get_param_value(option, 128, "sockets", endptr) != 0)
-+ sockets = strtoull(option, NULL, 10);
-+ if (get_param_value(option, 128, "cores", endptr) != 0)
-+ cores = strtoull(option, NULL, 10);
-+ if (get_param_value(option, 128, "threads", endptr) != 0)
-+ threads = strtoull(option, NULL, 10);
-+
-+ /* compute missing values, prefer sockets over cores over threads */
-+ if (smp == 0 || sockets == 0) {
-+ sockets = sockets > 0 ? sockets : 1;
-+ cores = cores > 0 ? cores : 1;
-+ threads = threads > 0 ? threads : 1;
-+ if (smp == 0) {
-+ smp = cores * threads * sockets;
-+ } else {
-+ sockets = smp / (cores * threads);
-+ }
-+ } else {
-+ if (cores == 0) {
-+ threads = threads > 0 ? threads : 1;
-+ cores = smp / (sockets * threads);
-+ } else {
-+ if (sockets == 0) {
-+ sockets = smp / (cores * threads);
-+ } else {
-+ threads = smp / (cores * sockets);
-+ }
-+ }
-+ }
-+ smp_cpus = smp;
-+ smp_cores = cores > 0 ? cores : 1;
-+ smp_threads = threads > 0 ? threads : 1;
-+}
-+
- /***********************************************************/
- /* USB devices */
-
-@@ -3727,6 +3775,8 @@
-
- if (kvm_enabled())
- kvm_init_vcpu(env);
-+ env->nr_cores = smp_cores;
-+ env->nr_threads = smp_threads;
- return;
- }
-
-@@ -4060,6 +4110,8 @@
- kvm_start_vcpu(env);
- else
- tcg_init_vcpu(env);
-+ env->nr_cores = smp_cores;
-+ env->nr_threads = smp_threads;
- }
-
- void qemu_notify_event(void)
-@@ -5560,7 +5612,7 @@
- usb_devices_index++;
- break;
- case QEMU_OPTION_smp:
-- smp_cpus = atoi(optarg);
-+ smp_parse(optarg);
- if (smp_cpus < 1) {
- fprintf(stderr, "Invalid number of CPUs\n");
- exit(1);