diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 03e2c3a..20144ea 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -69,6 +69,8 @@ typedef struct X86CPUClass {
     /*< public >*/
 
     void (*parent_reset)(CPUState *cpu);
+
+    X86CPUDefinition cpudef;
 } X86CPUClass;
 
 /**
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index f401a16..df4fb1f 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1262,28 +1262,6 @@ error:
     return -1;
 }
 
-static int cpu_x86_find_by_name(X86CPUDefinition *x86_cpu_def, const char *name)
-{
-    X86CPUModelTableEntry *def;
-
-    for (def = x86_defs; def; def = def->next) {
-        if (name && !strcmp(name, def->name)) {
-            break;
-        }
-    }
-
-    if (kvm_enabled() && name && strcmp(name, "host") == 0) {
-        cpu_x86_fill_host(x86_cpu_def);
-    } else if (!def) {
-        goto error;
-    } else {
-        memcpy(x86_cpu_def, &def->cpudef, sizeof(*def));
-    }
-    return 0;
-error:
-    return -1;
-}
-
 /* generate a composite string into buf of all cpuid names in featureset
  * selected by fbits.  indicate truncation at bufsize in the event of overflow.
  * if flags, suppress names undefined in featureset.
@@ -1434,6 +1412,12 @@ static int cpu_x86_init_from_def(X86CPU *cpu, X86CPUDefinition *def)
     return 0;
 }
 
+/* Build class name for specific CPU model */
+static char *build_cpu_class_name(const char *model)
+{
+    return g_strdup_printf("%s.%s", TYPE_X86_CPU, model);
+}
+
 X86CPU *cpu_x86_create(const char *cpu_model)
 {
     X86CPU *cpu;
@@ -1443,16 +1427,14 @@ X86CPU *cpu_x86_create(const char *cpu_model)
     char *s = g_strdup(cpu_model);
     char *name = strtok_r(s, ",", &last);
     char *featlist = strtok_r(NULL, "", &last);
+    char *class_name = build_cpu_class_name(name);
 
-    cpu = X86_CPU(object_new(TYPE_X86_CPU));
+    cpu = X86_CPU(object_new(class_name));
+    g_free(class_name);
     env = &cpu->env;
     env->cpu_model_str = cpu_model;
 
-    memset(def, 0, sizeof(*def));
-
-    if (cpu_x86_find_by_name(def, name) != 0) {
-        goto error;
-    }
+    *def = X86_CPU_GET_CLASS(cpu)->cpudef;
 
     if (cpu_x86_extend_features(def, featlist) < 0) {
         goto error;
@@ -2090,19 +2072,55 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->reset = x86_cpu_reset;
 }
 
+static void x86_cpu_class_init(ObjectClass *oc, void *data)
+{
+    X86CPUClass *xcc = X86_CPU_CLASS(oc);
+    X86CPUDefinition *def = data;
+
+    xcc->cpudef = *def;
+}
+
 static const TypeInfo x86_cpu_type_info = {
     .name = TYPE_X86_CPU,
     .parent = TYPE_CPU,
     .instance_size = sizeof(X86CPU),
-    .instance_init = x86_cpu_initfn,
-    .abstract = false,
+    .abstract = true,
     .class_size = sizeof(X86CPUClass),
     .class_init = x86_cpu_common_class_init,
 };
 
+static void x86_cpu_register_class(const char *name, X86CPUDefinition *def)
+{
+    char *class_name = build_cpu_class_name(name);
+    TypeInfo type = {
+        .name = class_name,
+        .parent = TYPE_X86_CPU,
+        .instance_size = sizeof(X86CPU),
+        .instance_init = x86_cpu_initfn,
+        .class_size = sizeof(X86CPUClass),
+        .class_init = x86_cpu_class_init,
+        .class_data = def,
+    };
+    type_register(&type);
+    g_free(class_name);
+}
+
 static void x86_cpu_register_types(void)
 {
+    X86CPUModelTableEntry *def;
+    X86CPUDefinition host_def;
+
+    /* Abstract CPUX86 class */
     type_register_static(&x86_cpu_type_info);
+
+    /* One class for each CPU model: */
+    for (def = x86_defs; def; def = def->next) {
+        x86_cpu_register_class(def->name, &def->cpudef);
+    }
+
+    /* -cpu host class */
+    cpu_x86_fill_host(&host_def);
+    x86_cpu_register_class("host", &host_def);
 }
 
 type_init(x86_cpu_register_types)
