From patchwork Tue Jan 15 09:27:29 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andreas_F=C3=A4rber?= X-Patchwork-Id: 212063 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 8795B2C00A6 for ; Tue, 15 Jan 2013 21:08:08 +1100 (EST) Received: from localhost ([::1]:45329 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tv2ou-0003cf-VJ for incoming@patchwork.ozlabs.org; Tue, 15 Jan 2013 04:28:36 -0500 Received: from eggs.gnu.org ([208.118.235.92]:57959) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tv2oR-0002aR-Hg for qemu-devel@nongnu.org; Tue, 15 Jan 2013 04:28:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Tv2oO-0000eA-Bi for qemu-devel@nongnu.org; Tue, 15 Jan 2013 04:28:07 -0500 Received: from cantor2.suse.de ([195.135.220.15]:41040 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tv2oO-0000du-22 for qemu-devel@nongnu.org; Tue, 15 Jan 2013 04:28:04 -0500 Received: from relay1.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 954C9A51FF; Tue, 15 Jan 2013 10:28:03 +0100 (CET) From: =?UTF-8?q?Andreas=20F=C3=A4rber?= To: qemu-devel@nongnu.org Date: Tue, 15 Jan 2013 10:27:29 +0100 Message-Id: <1358242058-1404-12-git-send-email-afaerber@suse.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1358242058-1404-1-git-send-email-afaerber@suse.de> References: <1358242058-1404-1-git-send-email-afaerber@suse.de> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 195.135.220.15 Cc: Eduardo Habkost , =?UTF-8?q?Andreas=20F=C3=A4rber?= Subject: [Qemu-devel] [PATCH 11/20] target-i386: kvm_check_features_against_host(): Use feature_word_info 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 From: Eduardo Habkost Instead of carrying the CPUID leaf/register and feature name array on the model_features_t struct, move that information into feature_word_info so it can be reused by other functions. The goal is to eventually kill model_features_t entirely, but to do that we have to either convert x86_def_t.features to an array or use offsetof() inside FeatureWordInfo (to replace the pointers inside model_features_t). So by now just move most of the model_features_t fields to FeatureWordInfo except for the two pointers to local arguments. Signed-off-by: Eduardo Habkost Reviewed-by: Gleb Natapov Signed-off-by: Andreas Färber --- target-i386/cpu.c | 73 +++++++++++++++++++++++++++++++++++------------------ 1 Datei geändert, 49 Zeilen hinzugefügt(+), 24 Zeilen entfernt(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index e17709c..0e531f9 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -126,16 +126,39 @@ static const char *cpuid_7_0_ebx_feature_name[] = { typedef struct FeatureWordInfo { const char **feat_names; + uint32_t cpuid_eax; /* Input EAX for CPUID */ + int cpuid_reg; /* R_* register constant */ } FeatureWordInfo; static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { - [FEAT_1_EDX] = { .feat_names = feature_name }, - [FEAT_1_ECX] = { .feat_names = ext_feature_name }, - [FEAT_8000_0001_EDX] = { .feat_names = ext2_feature_name }, - [FEAT_8000_0001_ECX] = { .feat_names = ext3_feature_name }, - [FEAT_KVM] = { .feat_names = kvm_feature_name }, - [FEAT_SVM] = { .feat_names = svm_feature_name }, - [FEAT_7_0_EBX] = { .feat_names = cpuid_7_0_ebx_feature_name }, + [FEAT_1_EDX] = { + .feat_names = feature_name, + .cpuid_eax = 1, .cpuid_reg = R_EDX, + }, + [FEAT_1_ECX] = { + .feat_names = ext_feature_name, + .cpuid_eax = 1, .cpuid_reg = R_ECX, + }, + [FEAT_8000_0001_EDX] = { + .feat_names = ext2_feature_name, + .cpuid_eax = 0x80000001, .cpuid_reg = R_EDX, + }, + [FEAT_8000_0001_ECX] = { + .feat_names = ext3_feature_name, + .cpuid_eax = 0x80000001, .cpuid_reg = R_ECX, + }, + [FEAT_KVM] = { + .feat_names = kvm_feature_name, + .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EAX, + }, + [FEAT_SVM] = { + .feat_names = svm_feature_name, + .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX, + }, + [FEAT_7_0_EBX] = { + .feat_names = cpuid_7_0_ebx_feature_name, + .cpuid_eax = 7, .cpuid_reg = R_EBX, + }, }; const char *get_register_name_32(unsigned int reg) @@ -162,9 +185,7 @@ const char *get_register_name_32(unsigned int reg) typedef struct model_features_t { uint32_t *guest_feat; uint32_t *host_feat; - const char **flag_names; - uint32_t cpuid; - int reg; + FeatureWord feat_word; } model_features_t; int check_cpuid = 0; @@ -962,19 +983,19 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def) #endif /* CONFIG_KVM */ } -static int unavailable_host_feature(struct model_features_t *f, uint32_t mask) +static int unavailable_host_feature(FeatureWordInfo *f, uint32_t mask) { int i; for (i = 0; i < 32; ++i) if (1 << i & mask) { - const char *reg = get_register_name_32(f->reg); + const char *reg = get_register_name_32(f->cpuid_reg); assert(reg); fprintf(stderr, "warning: host doesn't support requested feature: " "CPUID.%02XH:%s%s%s [bit %d]\n", - f->cpuid, reg, - f->flag_names[i] ? "." : "", - f->flag_names[i] ? f->flag_names[i] : "", i); + f->cpuid_eax, reg, + f->feat_names[i] ? "." : "", + f->feat_names[i] ? f->feat_names[i] : "", i); break; } return 0; @@ -992,25 +1013,29 @@ static int kvm_check_features_against_host(x86_def_t *guest_def) int rv, i; struct model_features_t ft[] = { {&guest_def->features, &host_def.features, - feature_name, 0x00000001, R_EDX}, + FEAT_1_EDX }, {&guest_def->ext_features, &host_def.ext_features, - ext_feature_name, 0x00000001, R_ECX}, + FEAT_1_ECX }, {&guest_def->ext2_features, &host_def.ext2_features, - ext2_feature_name, 0x80000001, R_EDX}, + FEAT_8000_0001_EDX }, {&guest_def->ext3_features, &host_def.ext3_features, - ext3_feature_name, 0x80000001, R_ECX} + FEAT_8000_0001_ECX }, }; assert(kvm_enabled()); kvm_cpu_fill_host(&host_def); - for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i) - for (mask = 1; mask; mask <<= 1) + for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i) { + FeatureWord w = ft[i].feat_word; + FeatureWordInfo *wi = &feature_word_info[w]; + for (mask = 1; mask; mask <<= 1) { if (*ft[i].guest_feat & mask && !(*ft[i].host_feat & mask)) { - unavailable_host_feature(&ft[i], mask); - rv = 1; - } + unavailable_host_feature(wi, mask); + rv = 1; + } + } + } return rv; }