From patchwork Thu Aug 16 16:59:11 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eduardo Habkost X-Patchwork-Id: 178073 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id CADF92C0080 for ; Fri, 17 Aug 2012 04:34:17 +1000 (EST) Received: from localhost ([::1]:41899 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T24jh-0002pa-4v for incoming@patchwork.ozlabs.org; Thu, 16 Aug 2012 14:24:01 -0400 Received: from eggs.gnu.org ([208.118.235.92]:53150) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T24jC-0001qg-V2 for qemu-devel@nongnu.org; Thu, 16 Aug 2012 14:23:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T24jB-00065f-Dn for qemu-devel@nongnu.org; Thu, 16 Aug 2012 14:23:30 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40748) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T24jB-00065W-5w for qemu-devel@nongnu.org; Thu, 16 Aug 2012 14:23:29 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q7GILSn7022946 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 16 Aug 2012 14:23:04 -0400 Received: from blackpad.lan.raisama.net (vpn1-6-48.gru2.redhat.com [10.97.6.48]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q7GGw90U032637; Thu, 16 Aug 2012 12:58:10 -0400 Received: by blackpad.lan.raisama.net (Postfix, from userid 500) id 55F34201548; Thu, 16 Aug 2012 13:59:15 -0300 (BRT) From: Eduardo Habkost To: qemu-devel@nongnu.org Date: Thu, 16 Aug 2012 13:59:11 -0300 Message-Id: <1345136352-10756-13-git-send-email-ehabkost@redhat.com> In-Reply-To: <1345136352-10756-1-git-send-email-ehabkost@redhat.com> References: <1345136352-10756-1-git-send-email-ehabkost@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: aliguori@us.ibm.com, stefanha@linux.vnet.ibm.com, gleb@redhat.com, vijaymohan.pandarathil@hp.com, jan.kiszka@siemens.com, mtosatti@redhat.com, mdroth@linux.vnet.ibm.com, blauwirbel@gmail.com, avi@redhat.com, pbonzini@redhat.com, akong@redhat.com, lersek@redhat.com, afaerber@suse.de Subject: [Qemu-devel] [RFC 12/13] register a class for each CPU model (v2) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The trick here is to replace only the cpu_x86_find_by_name() logic and nothing else. So, the only difference in relation to the previous code is that instead of looking at the CPU model table on cpu_x86_create()/cpu_x86_find_by_name(), we just use the right CPU class, that will already contain the CPU model definition inside it. I'm not sure what would be the best naming convention for the CPU classes. I'm using "-cpu." (as TYPE_X86CPU is "-cpu"). Note: This patch won't work as-is, yet, because of initialization ordering problems. The next patch will be a hack to make this work, by now. Reordering the initialization will be easier once we eliminate the support for cpudef config sections. Changes v1 -> v2: - Rebase on top of CPU properties series - Use a static type (with a different class init function) for the "-cpu host" class Signed-off-by: Eduardo Habkost --- target-i386/cpu-qom.h | 2 + target-i386/cpu.c | 114 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 79 insertions(+), 37 deletions(-) diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h index 2cd4f1a..6a003ff 100644 --- a/target-i386/cpu-qom.h +++ b/target-i386/cpu-qom.h @@ -68,6 +68,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 9209bb1..4f718af 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -1397,28 +1397,6 @@ static void cpu_x86_set_props(X86CPU *cpu, QDict *features, Error **errp) } } -static int cpu_x86_find_by_name(X86CPU *cpu, X86CPUDefinition *x86_cpu_def, - const char *cpu_model, Error **errp) -{ - X86CPUModelTableEntry *def; - - for (def = x86_defs; def; def = def->next) { - if (!strcmp(cpu_model, def->name)) { - break; - } - } - if (kvm_enabled() && strcmp(cpu_model, "host") == 0) { - cpu_x86_fill_host(x86_cpu_def); - } else if (!def) { - error_set(errp, QERR_DEVICE_NOT_FOUND, cpu_model); - return -1; - } else { - memcpy(x86_cpu_def, def, sizeof(*def)); - } - - return 0; -} - /* 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. @@ -1494,45 +1472,54 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) return cpu_list; } +/* 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; + ObjectClass *cpu_class; CPUX86State *env; X86CPUDefinition def1, *def = &def1; Error *error = NULL; QDict *features = NULL; char *name = NULL; + char *class_name = NULL; - /* for CPU subclasses should go into cpu_x86_init() before object_new() */ compat_normalize_cpu_model(cpu_model, &name, &features, &error); if (error_is_set(&error)) { goto error_normalize; } - /* this block should be replaced by CPU subclasses */ - memset(def, 0, sizeof(*def)); - - cpu = X86_CPU(object_new(TYPE_X86_CPU)); - env = &cpu->env; - env->cpu_model_str = cpu_model; - if (!cpu_model) { error_set(&error, QERR_INVALID_PARAMETER_VALUE, "cpu_model", "NULL"); - goto error; + goto error_normalize; } - if (cpu_x86_find_by_name(cpu, def, name, &error) < 0) { - goto error; + class_name = build_cpu_class_name(name); + cpu_class = object_class_by_name(class_name); + if (!cpu_class) { + error_set(&error, QERR_DEVICE_NOT_FOUND, cpu_model); + goto error_normalize; } + + cpu = X86_CPU(object_new(class_name)); + env = &cpu->env; + env->cpu_model_str = cpu_model; + + *def = X86_CPU_GET_CLASS(cpu)->cpudef; + cpudef_2_x86_cpu(cpu, def, &error); - /* for CPU subclasses should go between object_new() and - * x86_cpu_realize() */ cpu_x86_set_props(cpu, features, &error); if (error_is_set(&error)) { goto error; } + g_free(class_name); QDECREF(features); g_free(name); @@ -1541,6 +1528,7 @@ X86CPU *cpu_x86_create(const char *cpu_model) error: object_delete(OBJECT(cpu)); error_normalize: + g_free(class_name); QDECREF(features); g_free(name); if (error_is_set(&error)) { @@ -2206,15 +2194,67 @@ 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_class_init(ObjectClass *oc, void *data) +{ + X86CPUClass *xcc = X86_CPU_CLASS(oc); + X86CPUDefinition *def = data; + + xcc->cpudef = *def; +} + +/* Register a CPU class for a specific X86CPUDefinintion */ +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_host_class_init(ObjectClass *oc, void *data) +{ + X86CPUClass *xcc = X86_CPU_CLASS(oc); + + cpu_x86_fill_host(&xcc->cpudef); +} + +static TypeInfo x86_cpu_host_type_info = { + .name = TYPE_X86_CPU ".host", + .parent = TYPE_X86_CPU, + .instance_size = sizeof(X86CPU), + .instance_init = x86_cpu_initfn, + .class_size = sizeof(X86CPUClass), + .class_init = x86_cpu_host_class_init, +}; + static void x86_cpu_register_types(void) { + X86CPUModelTableEntry *def; + + /* Abstract X86CPU class */ type_register_static(&x86_cpu_type_info); + + /* -cpu host class */ + type_register_static(&x86_cpu_host_type_info); + + /* One class for each CPU model: */ + for (def = x86_defs; def; def = def->next) { + x86_cpu_register_class(def->name, &def->cpudef); + } + } type_init(x86_cpu_register_types)