diff --git a/sysemu.h b/sysemu.h
index 5582633..7187920 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -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;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 87c04e5..585af4c 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -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;
diff --git a/vl.c b/vl.c
index 5d86e69..9098603 100644
--- a/vl.c
+++ b/vl.c
@@ -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;
