From patchwork Mon Jan 7 18:20:46 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eduardo Habkost X-Patchwork-Id: 1941811 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id E81033FED4 for ; Mon, 7 Jan 2013 18:20:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754762Ab3AGSUB (ORCPT ); Mon, 7 Jan 2013 13:20:01 -0500 Received: from mx1.redhat.com ([209.132.183.28]:64119 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754640Ab3AGSTx (ORCPT ); Mon, 7 Jan 2013 13:19:53 -0500 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r07IJBV8023474 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 7 Jan 2013 13:19:11 -0500 Received: from blackpad.lan.raisama.net (vpn1-7-15.gru2.redhat.com [10.97.7.15]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r07IJA2f027816; Mon, 7 Jan 2013 13:19:10 -0500 Received: by blackpad.lan.raisama.net (Postfix, from userid 500) id 8B95F203D43; Mon, 7 Jan 2013 16:20:50 -0200 (BRST) From: Eduardo Habkost To: qemu-devel@nongnu.org Cc: libvir-list@redhat.com, kvm@vger.kernel.org, =?UTF-8?q?Andreas=20F=C3=A4rber?= , Igor Mammedov , Gleb Natapov Subject: [PATCH qom-cpu 5/7] target-i386: kvm_check_features_against_host(): Use feature_word_info Date: Mon, 7 Jan 2013 16:20:46 -0200 Message-Id: <1357582848-16575-6-git-send-email-ehabkost@redhat.com> In-Reply-To: <1357582848-16575-1-git-send-email-ehabkost@redhat.com> References: <1357582848-16575-1-git-send-email-ehabkost@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org 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 --- target-i386/cpu.c | 73 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 7d62d48..4b3ee63 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; @@ -935,19 +956,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; @@ -965,25 +986,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; }