From patchwork Mon Sep 5 08:52:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 9313267 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7032C600CA for ; Mon, 5 Sep 2016 09:20:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5E5CF289B4 for ; Mon, 5 Sep 2016 09:20:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 52FB3289E0; Mon, 5 Sep 2016 09:20:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A7DB4289D8 for ; Mon, 5 Sep 2016 09:20:52 +0000 (UTC) Received: from localhost ([::1]:53230 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgq5D-0003dD-Sy for patchwork-qemu-devel@patchwork.kernel.org; Mon, 05 Sep 2016 05:20:51 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54575) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgpeS-0006H0-DP for qemu-devel@nongnu.org; Mon, 05 Sep 2016 04:53:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bgpeI-0008Nh-PQ for qemu-devel@nongnu.org; Mon, 05 Sep 2016 04:53:12 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:37737) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgpeI-0008NT-Ha for qemu-devel@nongnu.org; Mon, 05 Sep 2016 04:53:02 -0400 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id u858qn06139343 for ; Mon, 5 Sep 2016 04:52:56 -0400 Received: from e06smtp14.uk.ibm.com (e06smtp14.uk.ibm.com [195.75.94.110]) by mx0a-001b2d01.pphosted.com with ESMTP id 257u1am03v-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Mon, 05 Sep 2016 04:52:56 -0400 Received: from localhost by e06smtp14.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 5 Sep 2016 09:52:54 +0100 Received: from d06dlp02.portsmouth.uk.ibm.com (9.149.20.14) by e06smtp14.uk.ibm.com (192.168.101.144) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 5 Sep 2016 09:52:52 +0100 X-IBM-Helo: d06dlp02.portsmouth.uk.ibm.com X-IBM-MailFrom: dahi@linux.vnet.ibm.com X-IBM-RcptTo: qemu-devel@nongnu.org Received: from b06cxnps4074.portsmouth.uk.ibm.com (d06relay11.portsmouth.uk.ibm.com [9.149.109.196]) by d06dlp02.portsmouth.uk.ibm.com (Postfix) with ESMTP id 3203B2190066 for ; Mon, 5 Sep 2016 09:52:14 +0100 (BST) Received: from d06av07.portsmouth.uk.ibm.com (d06av07.portsmouth.uk.ibm.com [9.149.37.248]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u858qpnP24707496 for ; Mon, 5 Sep 2016 08:52:51 GMT Received: from d06av07.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av07.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u858qprr031548 for ; Mon, 5 Sep 2016 04:52:51 -0400 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av07.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u858qlQ8031408; Mon, 5 Sep 2016 04:52:51 -0400 From: David Hildenbrand To: qemu-devel@nongnu.org Date: Mon, 5 Sep 2016 10:52:24 +0200 X-Mailer: git-send-email 2.8.4 In-Reply-To: <20160905085244.99980-1-dahi@linux.vnet.ibm.com> References: <20160905085244.99980-1-dahi@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16090508-0016-0000-0000-0000022BB9DD X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16090508-0017-0000-0000-000022DD863E Message-Id: <20160905085244.99980-11-dahi@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-09-05_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000 definitions=main-1609050135 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] X-Received-From: 148.163.156.1 Subject: [Qemu-devel] [Patch v4 10/30] s390x/cpumodel: expose features and feature groups as properties X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, borntraeger@de.ibm.com, fiuczy@linux.vnet.ibm.com, cornelia.huck@de.ibm.com, imammedo@redhat.com, jdenemar@redhat.com, mimu@linux.vnet.ibm.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Let's add all features and feature groups as properties to all CPU models. If the "host" CPU model is unknown, we can neither query nor change features. KVM will just continue to work like it did until now. We will not allow to enable features that were not part of the original CPU model, because that could collide with the IBC in KVM. Acked-by: Cornelia Huck Signed-off-by: David Hildenbrand --- target-s390x/cpu.c | 1 + target-s390x/cpu.h | 1 + target-s390x/cpu_models.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c index d7d0b62..2f3c8e2 100644 --- a/target-s390x/cpu.c +++ b/target-s390x/cpu.c @@ -291,6 +291,7 @@ static void s390_cpu_initfn(Object *obj) cs->exception_index = EXCP_HLT; object_property_add(OBJECT(cpu), "id", "int64_t", s390x_cpu_get_id, s390x_cpu_set_id, NULL, NULL, NULL); + s390_cpu_model_register_props(obj); #if !defined(CONFIG_USER_ONLY) qemu_get_timedate(&tm, 0); env->tod_offset = TOD_UNIX_EPOCH + diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index 3b76654..d03f0f1 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -632,6 +632,7 @@ extern void subsystem_reset(void); void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf); #define cpu_list s390_cpu_list +void s390_cpu_model_register_props(Object *obj); void s390_cpu_model_class_register_props(ObjectClass *oc); void s390_realize_cpu_model(CPUState *cs, Error **errp); ObjectClass *s390_cpu_class_by_name(const char *name); diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c index 5045aef..1daa208 100644 --- a/target-s390x/cpu_models.c +++ b/target-s390x/cpu_models.c @@ -14,6 +14,7 @@ #include "cpu.h" #include "gen-features.h" #include "qapi/error.h" +#include "qapi/visitor.h" #ifndef CONFIG_USER_ONLY #include "sysemu/arch_init.h" #endif @@ -103,8 +104,24 @@ void s390_cpu_list(FILE *f, fprintf_function print) f = f, print = print, }; + S390FeatGroup group; + S390Feat feat; object_class_foreach(print_cpu_model_list, TYPE_S390_CPU, false, &info); + + (*print)(f, "\nRecognized feature flags:\n"); + for (feat = 0; feat < S390_FEAT_MAX; feat++) { + const S390FeatDef *def = s390_feat_def(feat); + + (*print)(f, "%-20s %-50s\n", def->name, def->desc); + } + + (*print)(f, "\nRecognized feature groups:\n"); + for (group = 0; group < S390_FEAT_GROUP_MAX; group++) { + const S390FeatGroupDef *def = s390_feat_group_def(group); + + (*print)(f, "%-20s %-50s\n", def->name, def->desc); + } } #ifndef CONFIG_USER_ONLY @@ -151,6 +168,138 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp) } } +static void get_feature(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + S390Feat feat = (S390Feat) opaque; + S390CPU *cpu = S390_CPU(obj); + bool value; + + if (!cpu->model) { + error_setg(errp, "Details about the host CPU model are not available, " + "features cannot be queried."); + return; + } + + value = test_bit(feat, cpu->model->features); + visit_type_bool(v, name, &value, errp); +} + +static void set_feature(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + S390Feat feat = (S390Feat) opaque; + DeviceState *dev = DEVICE(obj); + S390CPU *cpu = S390_CPU(obj); + bool value; + + if (dev->realized) { + error_setg(errp, "Attempt to set property '%s' on '%s' after " + "it was realized", name, object_get_typename(obj)); + return; + } else if (!cpu->model) { + error_setg(errp, "Details about the host CPU model are not available, " + "features cannot be changed."); + return; + } + + visit_type_bool(v, name, &value, errp); + if (*errp) { + return; + } + if (value) { + if (!test_bit(feat, cpu->model->def->full_feat)) { + error_setg(errp, "Feature '%s' is not available for CPU model '%s'," + " it was introduced with later models.", + name, cpu->model->def->name); + return; + } + set_bit(feat, cpu->model->features); + } else { + clear_bit(feat, cpu->model->features); + } +} + +static void get_feature_group(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + S390FeatGroup group = (S390FeatGroup) opaque; + const S390FeatGroupDef *def = s390_feat_group_def(group); + S390CPU *cpu = S390_CPU(obj); + S390FeatBitmap tmp; + bool value; + + if (!cpu->model) { + error_setg(errp, "Details about the host CPU model are not available, " + "features cannot be queried."); + return; + } + + /* a group is enabled if all features are enabled */ + bitmap_and(tmp, cpu->model->features, def->feat, S390_FEAT_MAX); + value = bitmap_equal(tmp, def->feat, S390_FEAT_MAX); + visit_type_bool(v, name, &value, errp); +} + +static void set_feature_group(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + S390FeatGroup group = (S390FeatGroup) opaque; + const S390FeatGroupDef *def = s390_feat_group_def(group); + DeviceState *dev = DEVICE(obj); + S390CPU *cpu = S390_CPU(obj); + bool value; + + if (dev->realized) { + error_setg(errp, "Attempt to set property '%s' on '%s' after " + "it was realized", name, object_get_typename(obj)); + return; + } else if (!cpu->model) { + error_setg(errp, "Details about the host CPU model are not available, " + "features cannot be changed."); + return; + } + + visit_type_bool(v, name, &value, errp); + if (*errp) { + return; + } + if (value) { + /* groups are added in one shot, so an intersect is sufficient */ + if (!bitmap_intersects(def->feat, cpu->model->def->full_feat, + S390_FEAT_MAX)) { + error_setg(errp, "Group '%s' is not available for CPU model '%s'," + " it was introduced with later models.", + name, cpu->model->def->name); + return; + } + bitmap_or(cpu->model->features, cpu->model->features, def->feat, + S390_FEAT_MAX); + } else { + bitmap_andnot(cpu->model->features, cpu->model->features, def->feat, + S390_FEAT_MAX); + } +} + +void s390_cpu_model_register_props(Object *obj) +{ + S390FeatGroup group; + S390Feat feat; + + for (feat = 0; feat < S390_FEAT_MAX; feat++) { + const S390FeatDef *def = s390_feat_def(feat); + object_property_add(obj, def->name, "bool", get_feature, + set_feature, NULL, (void *) feat, NULL); + object_property_set_description(obj, def->name, def->desc , NULL); + } + for (group = 0; group < S390_FEAT_GROUP_MAX; group++) { + const S390FeatGroupDef *def = s390_feat_group_def(group); + object_property_add(obj, def->name, "bool", get_feature_group, + set_feature_group, NULL, (void *) group, NULL); + object_property_set_description(obj, def->name, def->desc , NULL); + } +} + static void s390_cpu_model_initfn(Object *obj) { S390CPU *cpu = S390_CPU(obj);