From nobody Sun May 19 02:26:35 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1493757336619740.3908816307909; Tue, 2 May 2017 13:35:36 -0700 (PDT) Received: from localhost ([::1]:33576 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d5eWF-0007o2-0q for importer@patchew.org; Tue, 02 May 2017 16:35:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49965) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d5eSA-0004iF-TL for qemu-devel@nongnu.org; Tue, 02 May 2017 16:31:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d5eS9-00050L-3s for qemu-devel@nongnu.org; Tue, 02 May 2017 16:31:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:54984) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d5eS8-0004ys-Q8 for qemu-devel@nongnu.org; Tue, 02 May 2017 16:31:21 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8761B2564B7; Tue, 2 May 2017 20:31:19 +0000 (UTC) Received: from localhost (ovpn-116-8.gru2.redhat.com [10.97.116.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1266C19E1E; Tue, 2 May 2017 20:31:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 8761B2564B7 Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=ehabkost@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 8761B2564B7 From: Eduardo Habkost To: qemu-devel@nongnu.org Date: Tue, 2 May 2017 17:31:12 -0300 Message-Id: <20170502203115.22233-2-ehabkost@redhat.com> In-Reply-To: <20170502203115.22233-1-ehabkost@redhat.com> References: <20170502203115.22233-1-ehabkost@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Tue, 02 May 2017 20:31:19 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 1/4] visitor: Add 'supported_qtypes' parameter to visit_start_alternate() 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: Michael Roth , Alexander Graf , Markus Armbruster , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This will allow visitors to make decisions based on the supported qtypes of a given alternate type. The new parameter can replace the old 'promote_int' argument, as qobject-input-visitor can simply check if QTYPE_QINT is set in supported_qtypes. Signed-off-by: Eduardo Habkost --- include/qapi/visitor.h | 5 +++-- include/qapi/visitor-impl.h | 2 +- scripts/qapi-visit.py | 14 ++++++++------ qapi/qapi-visit-core.c | 7 ++++--- qapi/qapi-clone-visitor.c | 3 ++- qapi/qapi-dealloc-visitor.c | 3 ++- qapi/qobject-input-visitor.c | 6 ++++-- qapi/trace-events | 2 +- 8 files changed, 25 insertions(+), 17 deletions(-) diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index 1a1b62012b..8c2bff4a05 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -408,7 +408,8 @@ void visit_end_list(Visitor *v, void **list); * the qtype of the next thing to be visited, stored in (*@obj)->type. * Other visitors will leave @obj unchanged. * - * If @promote_int, treat integers as QTYPE_FLOAT. + * @supported_qtypes is a bit mask indicating which QTypes are supported + * by the alternate. * * If successful, this must be paired with visit_end_alternate() with * the same @obj to clean up, even if visiting the contents of the @@ -416,7 +417,7 @@ void visit_end_list(Visitor *v, void **list); */ void visit_start_alternate(Visitor *v, const char *name, GenericAlternate **obj, size_t size, - bool promote_int, Error **errp); + unsigned long supported_qtypes, Error **errp); =20 /* * Finish visiting an alternate type. diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h index e87709db5c..50c2b2feef 100644 --- a/include/qapi/visitor-impl.h +++ b/include/qapi/visitor-impl.h @@ -71,7 +71,7 @@ struct Visitor * optional for output visitors. */ void (*start_alternate)(Visitor *v, const char *name, GenericAlternate **obj, size_t size, - bool promote_int, Error **errp); + unsigned long supported_qtypes, Error **errp); =20 /* Optional, needed for dealloc visitor */ void (*end_alternate)(Visitor *v, void **obj); diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index 5737aefa05..ebf7e67109 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -161,20 +161,21 @@ void visit_type_%(c_name)s(Visitor *v, const char *na= me, %(c_name)s *obj, Error =20 =20 def gen_visit_alternate(name, variants): - promote_int =3D 'true' + qtypes =3D ['BIT(%s)' % (var.type.alternate_qtype()) + for var in variants.variants] + supported_qtypes =3D '|'.join(qtypes) ret =3D '' - for var in variants.variants: - if var.type.alternate_qtype() =3D=3D 'QTYPE_QINT': - promote_int =3D 'false' =20 ret +=3D mcgen(''' =20 void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj,= Error **errp) { Error *err =3D NULL; + unsigned long supported_qtypes =3D %(supported_qtypes)s; =20 + assert(QTYPE__MAX < BITS_PER_LONG); visit_start_alternate(v, name, (GenericAlternate **)obj, sizeof(**obj), - %(promote_int)s, &err); + supported_qtypes, &err); if (err) { goto out; } @@ -183,7 +184,7 @@ void visit_type_%(c_name)s(Visitor *v, const char *name= , %(c_name)s **obj, Error } switch ((*obj)->type) { ''', - c_name=3Dc_name(name), promote_int=3Dpromote_int) + c_name=3Dc_name(name), supported_qtypes=3Dsupported_qtype= s) =20 for var in variants.variants: ret +=3D mcgen(''' @@ -375,6 +376,7 @@ h_comment =3D ''' =20 fdef.write(mcgen(''' #include "qemu/osdep.h" +#include "qemu/bitmap.h" #include "qemu-common.h" #include "qapi/error.h" #include "%(prefix)sqapi-visit.h" diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index 43a09d147d..784ba1b756 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -106,15 +106,16 @@ void visit_end_list(Visitor *v, void **obj) =20 void visit_start_alternate(Visitor *v, const char *name, GenericAlternate **obj, size_t size, - bool promote_int, Error **errp) + unsigned long supported_qtypes, + Error **errp) { Error *err =3D NULL; =20 assert(obj && size >=3D sizeof(GenericAlternate)); assert(!(v->type & VISITOR_OUTPUT) || *obj); - trace_visit_start_alternate(v, name, obj, size, promote_int); + trace_visit_start_alternate(v, name, obj, size, supported_qtypes); if (v->start_alternate) { - v->start_alternate(v, name, obj, size, promote_int, &err); + v->start_alternate(v, name, obj, size, supported_qtypes, &err); } if (v->type & VISITOR_INPUT) { assert(v->start_alternate && !err !=3D !*obj); diff --git a/qapi/qapi-clone-visitor.c b/qapi/qapi-clone-visitor.c index 34086cbfc0..5550871488 100644 --- a/qapi/qapi-clone-visitor.c +++ b/qapi/qapi-clone-visitor.c @@ -70,7 +70,8 @@ static GenericList *qapi_clone_next_list(Visitor *v, Gene= ricList *tail, =20 static void qapi_clone_start_alternate(Visitor *v, const char *name, GenericAlternate **obj, size_t size, - bool promote_int, Error **errp) + unsigned long supported_qtypes, + Error **errp) { qapi_clone_start_struct(v, name, (void **)obj, size, errp); } diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c index e39457bc79..ef83d1420b 100644 --- a/qapi/qapi-dealloc-visitor.c +++ b/qapi/qapi-dealloc-visitor.c @@ -38,7 +38,8 @@ static void qapi_dealloc_end_struct(Visitor *v, void **ob= j) =20 static void qapi_dealloc_start_alternate(Visitor *v, const char *name, GenericAlternate **obj, size_t si= ze, - bool promote_int, Error **errp) + unsigned long supported_qtypes, + Error **errp) { } =20 diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c index 865e948ac0..393220b3a6 100644 --- a/qapi/qobject-input-visitor.c +++ b/qapi/qobject-input-visitor.c @@ -22,6 +22,7 @@ #include "qapi/qmp/types.h" #include "qapi/qmp/qerror.h" #include "qemu/cutils.h" +#include "qemu/bitops.h" #include "qemu/option.h" =20 typedef struct StackObject { @@ -338,7 +339,8 @@ static void qobject_input_check_list(Visitor *v, Error = **errp) =20 static void qobject_input_start_alternate(Visitor *v, const char *name, GenericAlternate **obj, size_t s= ize, - bool promote_int, Error **errp) + unsigned long supported_qtypes, + Error **errp) { QObjectInputVisitor *qiv =3D to_qiv(v); QObject *qobj =3D qobject_input_get_object(qiv, name, false, errp); @@ -349,7 +351,7 @@ static void qobject_input_start_alternate(Visitor *v, c= onst char *name, } *obj =3D g_malloc0(size); (*obj)->type =3D qobject_type(qobj); - if (promote_int && (*obj)->type =3D=3D QTYPE_QINT) { + if (!(supported_qtypes & BIT(QTYPE_QINT)) && (*obj)->type =3D=3D QTYPE= _QINT) { (*obj)->type =3D QTYPE_QFLOAT; } } diff --git a/qapi/trace-events b/qapi/trace-events index 339cacf0ad..db42dd8353 100644 --- a/qapi/trace-events +++ b/qapi/trace-events @@ -11,7 +11,7 @@ visit_next_list(void *v, void *tail, size_t size) "v=3D%p= tail=3D%p size=3D%zu" visit_check_list(void *v) "v=3D%p" visit_end_list(void *v, void *obj) "v=3D%p obj=3D%p" =20 -visit_start_alternate(void *v, const char *name, void *obj, size_t size, b= ool promote_int) "v=3D%p name=3D%s obj=3D%p size=3D%zu promote_int=3D%d" +visit_start_alternate(void *v, const char *name, void *obj, size_t size, u= nsigned long supported_qtypes) "v=3D%p name=3D%s obj=3D%p size=3D%zu suppor= ted_qtypes=3D0x%lx" visit_end_alternate(void *v, void *obj) "v=3D%p obj=3D%p" =20 visit_optional(void *v, const char *name, bool *present) "v=3D%p name=3D%s= present=3D%p" --=20 2.11.0.259.g40922b1 From nobody Sun May 19 02:26:35 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1493757187123421.5329057805577; Tue, 2 May 2017 13:33:07 -0700 (PDT) Received: from localhost ([::1]:33560 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d5eTp-0005iw-Kv for importer@patchew.org; Tue, 02 May 2017 16:33:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49984) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d5eSC-0004iK-5u for qemu-devel@nongnu.org; Tue, 02 May 2017 16:31:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d5eSA-000526-PP for qemu-devel@nongnu.org; Tue, 02 May 2017 16:31:24 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50832) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d5eSA-00051N-G3 for qemu-devel@nongnu.org; Tue, 02 May 2017 16:31:22 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 70B477B2C3; Tue, 2 May 2017 20:31:21 +0000 (UTC) Received: from localhost (ovpn-116-8.gru2.redhat.com [10.97.116.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id F09C21714F; Tue, 2 May 2017 20:31:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 70B477B2C3 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=ehabkost@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 70B477B2C3 From: Eduardo Habkost To: qemu-devel@nongnu.org Date: Tue, 2 May 2017 17:31:13 -0300 Message-Id: <20170502203115.22233-3-ehabkost@redhat.com> In-Reply-To: <20170502203115.22233-1-ehabkost@redhat.com> References: <20170502203115.22233-1-ehabkost@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 02 May 2017 20:31:21 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 2/4] string-input-visitor: Support alternate types 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: Michael Roth , Alexander Graf , Markus Armbruster , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" When parsing alternates from a string, there are some limitations in what we can do, but it is a valid use case in some situations. We can support booleans, integer types, and enums. This will be used to support 'feature=3Dforce' in -cpu options, while keeping 'feature=3Don|off|true|false' represented as boolean values. Signed-off-by: Eduardo Habkost --- qapi/string-input-visitor.c | 71 ++++++++++++++++++++++---- tests/test-string-input-visitor.c | 89 +++++++++++++++++++++++++++++= ++++ tests/qapi-schema/qapi-schema-test.json | 8 +++ 3 files changed, 158 insertions(+), 10 deletions(-) diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c index c089491c24..bf8f58748b 100644 --- a/qapi/string-input-visitor.c +++ b/qapi/string-input-visitor.c @@ -19,6 +19,7 @@ #include "qemu/option.h" #include "qemu/queue.h" #include "qemu/range.h" +#include "qemu/bitops.h" =20 =20 struct StringInputVisitor @@ -278,21 +279,34 @@ static void parse_type_size(Visitor *v, const char *n= ame, uint64_t *obj, *obj =3D val; } =20 +static int try_parse_bool(const char *s, bool *result) +{ + if (!strcasecmp(s, "on") || + !strcasecmp(s, "yes") || + !strcasecmp(s, "true")) { + if (result) { + *result =3D true; + } + return 0; + } + if (!strcasecmp(s, "off") || + !strcasecmp(s, "no") || + !strcasecmp(s, "false")) { + if (result) { + *result =3D false; + } + return 0; + } + + return -1; +} + static void parse_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) { StringInputVisitor *siv =3D to_siv(v); =20 - if (!strcasecmp(siv->string, "on") || - !strcasecmp(siv->string, "yes") || - !strcasecmp(siv->string, "true")) { - *obj =3D true; - return; - } - if (!strcasecmp(siv->string, "off") || - !strcasecmp(siv->string, "no") || - !strcasecmp(siv->string, "false")) { - *obj =3D false; + if (try_parse_bool(siv->string, obj) =3D=3D 0) { return; } =20 @@ -326,6 +340,42 @@ static void parse_type_number(Visitor *v, const char *= name, double *obj, *obj =3D val; } =20 +/* Support for alternates on string-input-visitor is limited, because + * the input string doesn't have any type information. + * + * Supported alternate member types: + * 1) enums + * 2) integer types + * 3) booleans (but only if the there's no enum variant + * containing "on", "off", "true", or "false" as members) + * + * UNSUPPORTED alternate member types: + * 1) strings + * 2) complex types + */ +static void start_alternate(Visitor *v, const char *name, + GenericAlternate **obj, size_t size, + unsigned long supported_qtypes, Error **errp) +{ + StringInputVisitor *siv =3D to_siv(v); + QType t =3D QTYPE_QSTRING; + + if (supported_qtypes & BIT(QTYPE_QBOOL)) { + if (try_parse_bool(siv->string, NULL) =3D=3D 0) { + t =3D QTYPE_QBOOL; + } + } + + if (supported_qtypes & BIT(QTYPE_QINT)) { + if (parse_str(siv, name, NULL) =3D=3D 0) { + t =3D QTYPE_QINT; + } + } + + *obj =3D g_malloc0(size); + (*obj)->type =3D t; +} + static void string_input_free(Visitor *v) { StringInputVisitor *siv =3D to_siv(v); @@ -353,6 +403,7 @@ Visitor *string_input_visitor_new(const char *str) v->visitor.next_list =3D next_list; v->visitor.check_list =3D check_list; v->visitor.end_list =3D end_list; + v->visitor.start_alternate =3D start_alternate; v->visitor.free =3D string_input_free; =20 v->string =3D str; diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-vi= sitor.c index 79313a7f7a..1e867d62c9 100644 --- a/tests/test-string-input-visitor.c +++ b/tests/test-string-input-visitor.c @@ -290,6 +290,91 @@ static void test_visitor_in_enum(TestInputVisitorData = *data, } } =20 +static void test_visitor_in_alt_bool_enum(TestInputVisitorData *data, + const void *unused) +{ + Error *err =3D NULL; + Visitor *v; + AltBoolEnum *be =3D NULL; + + v =3D visitor_input_test_init(data, "true"); + visit_type_AltBoolEnum(v, NULL, &be, &err); + g_assert(!err); + g_assert_cmpint(be->type, =3D=3D, QTYPE_QBOOL); + g_assert(be->u.b); + qapi_free_AltBoolEnum(be); + + v =3D visitor_input_test_init(data, "off"); + visit_type_AltBoolEnum(v, NULL, &be, &err); + g_assert(!err); + g_assert_cmpint(be->type, =3D=3D, QTYPE_QBOOL); + g_assert(!be->u.b); + qapi_free_AltBoolEnum(be); + + v =3D visitor_input_test_init(data, "value2"); + visit_type_AltBoolEnum(v, NULL, &be, &err); + g_assert(!err); + g_assert_cmpint(be->type, =3D=3D, QTYPE_QSTRING); + g_assert_cmpint(be->u.e, =3D=3D, ENUM_ONE_VALUE2); + qapi_free_AltBoolEnum(be); + + v =3D visitor_input_test_init(data, "value100"); + visit_type_AltBoolEnum(v, NULL, &be, &err); + error_free_or_abort(&err); + qapi_free_AltBoolEnum(be); + + v =3D visitor_input_test_init(data, "10"); + visit_type_AltBoolEnum(v, NULL, &be, &err); + error_free_or_abort(&err); + qapi_free_AltBoolEnum(be); +} + +static void test_visitor_in_alt_enum_int(TestInputVisitorData *data, + const void *unused) +{ + Error *err =3D NULL; + Visitor *v; + AltOnOffInt *be =3D NULL; + + v =3D visitor_input_test_init(data, "on"); + visit_type_AltOnOffInt(v, NULL, &be, &err); + g_assert(!err); + g_assert_cmpint(be->type, =3D=3D, QTYPE_QSTRING); + g_assert_cmpint(be->u.o, =3D=3D, TEST_ON_OFF_AUTO_ON); + qapi_free_AltOnOffInt(be); + + v =3D visitor_input_test_init(data, "off"); + visit_type_AltOnOffInt(v, NULL, &be, &err); + g_assert(!err); + g_assert_cmpint(be->type, =3D=3D, QTYPE_QSTRING); + g_assert_cmpint(be->u.o, =3D=3D, TEST_ON_OFF_AUTO_OFF); + qapi_free_AltOnOffInt(be); + + v =3D visitor_input_test_init(data, "auto"); + visit_type_AltOnOffInt(v, NULL, &be, &err); + g_assert(!err); + g_assert_cmpint(be->type, =3D=3D, QTYPE_QSTRING); + g_assert_cmpint(be->u.o, =3D=3D, TEST_ON_OFF_AUTO_AUTO); + qapi_free_AltOnOffInt(be); + + v =3D visitor_input_test_init(data, "-12345"); + visit_type_AltOnOffInt(v, NULL, &be, &err); + g_assert(!err); + g_assert_cmpint(be->type, =3D=3D, QTYPE_QINT); + g_assert_cmpint(be->u.i, =3D=3D, -12345); + qapi_free_AltOnOffInt(be); + + v =3D visitor_input_test_init(data, "true"); + visit_type_AltOnOffInt(v, NULL, &be, &err); + error_free_or_abort(&err); + qapi_free_AltOnOffInt(be); + + v =3D visitor_input_test_init(data, "value2"); + visit_type_AltOnOffInt(v, NULL, &be, &err); + error_free_or_abort(&err); + qapi_free_AltOnOffInt(be); +} + /* Try to crash the visitors */ static void test_visitor_in_fuzz(TestInputVisitorData *data, const void *unused) @@ -366,6 +451,10 @@ int main(int argc, char **argv) &in_visitor_data, test_visitor_in_string); input_visitor_test_add("/string-visitor/input/enum", &in_visitor_data, test_visitor_in_enum); + input_visitor_test_add("/string-visitor/input/alternate/bool_enum", + &in_visitor_data, test_visitor_in_alt_bool_enu= m); + input_visitor_test_add("/string-visitor/input/alternate/enum_int", + &in_visitor_data, test_visitor_in_alt_enum_int= ); input_visitor_test_add("/string-visitor/input/fuzz", &in_visitor_data, test_visitor_in_fuzz); =20 diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qa= pi-schema-test.json index 842ea3c5e3..231c8952e8 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -106,6 +106,14 @@ { 'alternate': 'AltIntNum', 'data': { 'i': 'int', 'n': 'number' } } { 'alternate': 'AltNumInt', 'data': { 'n': 'number', 'i': 'int' } } =20 + +# for testing string-input-visitor handling of alternates: +{ 'enum': 'TestOnOffAuto', + 'data': [ 'on', 'off', 'auto' ] } + +{ 'alternate': 'AltBoolEnum', 'data': { 'b': 'bool', 'e': 'EnumOne' } } +{ 'alternate': 'AltOnOffInt', 'data': { 'o': 'TestOnOffAuto', 'i': 'int' }= } + # for testing native lists { 'union': 'UserDefNativeListUnion', 'data': { 'integer': ['int'], --=20 2.11.0.259.g40922b1 From nobody Sun May 19 02:26:35 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1493757339356892.509190061887; Tue, 2 May 2017 13:35:39 -0700 (PDT) Received: from localhost ([::1]:33577 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d5eWI-0007rY-1E for importer@patchew.org; Tue, 02 May 2017 16:35:38 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49997) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d5eSD-0004iq-NR for qemu-devel@nongnu.org; Tue, 02 May 2017 16:31:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d5eSC-00053E-Lv for qemu-devel@nongnu.org; Tue, 02 May 2017 16:31:25 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49418) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d5eSC-00052d-Cr for qemu-devel@nongnu.org; Tue, 02 May 2017 16:31:24 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4FA314EA21; Tue, 2 May 2017 20:31:23 +0000 (UTC) Received: from localhost (ovpn-116-8.gru2.redhat.com [10.97.116.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id D1F0B17168; Tue, 2 May 2017 20:31:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 4FA314EA21 Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=ehabkost@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 4FA314EA21 From: Eduardo Habkost To: qemu-devel@nongnu.org Date: Tue, 2 May 2017 17:31:14 -0300 Message-Id: <20170502203115.22233-4-ehabkost@redhat.com> In-Reply-To: <20170502203115.22233-1-ehabkost@redhat.com> References: <20170502203115.22233-1-ehabkost@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 02 May 2017 20:31:23 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 3/4] tests: Add [+-]feature and feature=on|off test cases 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: Michael Roth , Alexander Graf , Markus Armbruster , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add test code to ensure features are enabled/disabled correctly in the command-line. The test case use the "feature-words" and "filtered-features" properties to check if the features were enabled/disabled correctly. Signed-off-by: Eduardo Habkost --- tests/test-x86-cpuid-compat.c | 107 ++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 107 insertions(+) diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c index 79a2e69a28..00ee8a264f 100644 --- a/tests/test-x86-cpuid-compat.c +++ b/tests/test-x86-cpuid-compat.c @@ -1,6 +1,7 @@ #include "qemu/osdep.h" #include "qemu-common.h" #include "qapi/qmp/qlist.h" +#include "qapi/qmp/qstring.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qint.h" #include "qapi/qmp/qbool.h" @@ -68,6 +69,9 @@ static void test_cpuid_prop(const void *data) g_free(path); } =20 +/* Add simple test that ensure that a given (integer) property has + * the right value after running QEMU using cmdline + */ static void add_cpuid_test(const char *name, const char *cmdline, const char *property, int64_t expected_value) { @@ -78,6 +82,83 @@ static void add_cpuid_test(const char *name, const char = *cmdline, qtest_add_data_func(name, args, test_cpuid_prop); } =20 + +/* Parameters to a add_feature_test() test case */ +typedef struct FeatureTestArgs { + /* cmdline to start QEMU */ + const char *cmdline; + /* + * cpuid-input-eax and cpuid-input-ecx values to look for, + * in "feature-words" and "filtered-features" properties. + */ + uint32_t input_eax, input_ecx; + /* The register name to look for, in the X86CPUFeatureWordInfo array */ + const char *reg; + /* The bit to check in X86CPUFeatureWordInfo.features */ + int bitnr; + /* The expected value for the bit in (X86CPUFeatureWordInfo.features) = */ + bool expected_value; +} FeatureTestArgs; + +/* Get the value for a feature word in a X86CPUFeatureWordInfo list */ +static uint32_t get_feature_word(QList *features, uint32_t eax, uint32_t e= cx, const char *reg) +{ + const QListEntry *e; + + for (e =3D qlist_first(features); e; e =3D qlist_next(e)) { + QDict *w =3D qobject_to_qdict(qlist_entry_obj(e)); + if (eax =3D=3D qint_get_int(qobject_to_qint(qdict_get(w, "cpuid-in= put-eax"))) + && (!qdict_haskey(w, "cpuid-input-ecx") + || ecx =3D=3D qint_get_int(qobject_to_qint(qdict_get(w, "c= puid-input-ecx")))) + && !strcmp(qstring_get_str(qobject_to_qstring(qdict_get(w, "cp= uid-register"))), reg)) { + return qint_get_int(qobject_to_qint(qdict_get(w, "features"))); + } + } + return 0; +} + +static void test_feature_flag(const void *data) +{ + const FeatureTestArgs *args =3D data; + char *path; + QList *present, *filtered; + uint32_t value; + + qtest_start(args->cmdline); + path =3D get_cpu0_qom_path(); + present =3D qobject_to_qlist(qom_get(path, "feature-words")); + filtered =3D qobject_to_qlist(qom_get(path, "filtered-features")); + value =3D get_feature_word(present, args->input_eax, args->input_ecx, = args->reg); + value |=3D get_feature_word(filtered, args->input_eax, args->input_ecx= , args->reg); + qtest_end(); + + g_assert(!!(value & (1U << args->bitnr)) =3D=3D args->expected_value); + + QDECREF(present); + QDECREF(filtered); + g_free(path); +} + +/* Add test case to ensure that a given feature flag is set in + * either "feature-words" or "filtered-features", when running QEMU + * using cmdline + */ +static FeatureTestArgs *add_feature_test(const char *name, const char *cmd= line, + uint32_t eax, uint32_t ecx, + const char *reg, int bitnr, + bool expected_value) +{ + FeatureTestArgs *args =3D g_new0(FeatureTestArgs, 1); + args->cmdline =3D cmdline; + args->input_eax =3D eax; + args->input_ecx =3D ecx; + args->reg =3D reg; + args->bitnr =3D bitnr; + args->expected_value =3D expected_value; + qtest_add_data_func(name, args, test_feature_flag); + return args; +} + #ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS static void test_plus_minus_subprocess(void) { @@ -229,5 +310,31 @@ int main(int argc, char **argv) "-machine pc-i440fx-2.7 -cpu 486,+xstore", "xlevel2", 0); =20 + /* Test feature parsing */ + add_feature_test("x86/cpuid/features/plus", + "-cpu 486,+arat", + 6, 0, "EAX", 2, true); + add_feature_test("x86/cpuid/features/minus", + "-cpu pentium,-mmx", + 1, 0, "EDX", 23, false); + add_feature_test("x86/cpuid/features/on", + "-cpu 486,arat=3Don", + 6, 0, "EAX", 2, true); + add_feature_test("x86/cpuid/features/off", + "-cpu pentium,mmx=3Doff", + 1, 0, "EDX", 23, false); + add_feature_test("x86/cpuid/features/max-plus-invtsc", + "-machine accel=3Dkvm:tcg -cpu max,+invtsc", + 0x80000007, 0, "EDX", 8, true); + add_feature_test("x86/cpuid/features/max-invtsc-on", + "-machine accel=3Dkvm:tcg -cpu max,invtsc=3Don", + 0x80000007, 0, "EDX", 8, true); + add_feature_test("x86/cpuid/features/max-minus-mmx", + "-machine accel=3Dkvm:tcg -cpu max,-mmx", + 1, 0, "EDX", 23, false); + add_feature_test("x86/cpuid/features/max-invtsc-on,mmx=3Doff", + "-machine accel=3Dkvm:tcg -cpu max,mmx=3Doff", + 1, 0, "EDX", 23, false); + return g_test_run(); } --=20 2.11.0.259.g40922b1 From nobody Sun May 19 02:26:35 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1493757201003809.6847759652276; Tue, 2 May 2017 13:33:21 -0700 (PDT) Received: from localhost ([::1]:33561 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d5eU0-0005xb-Ec for importer@patchew.org; Tue, 02 May 2017 16:33:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50011) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d5eSF-0004ke-Qm for qemu-devel@nongnu.org; Tue, 02 May 2017 16:31:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d5eSE-00055B-GI for qemu-devel@nongnu.org; Tue, 02 May 2017 16:31:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44918) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d5eSE-00053e-7E for qemu-devel@nongnu.org; Tue, 02 May 2017 16:31:26 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 36687C05AD64; Tue, 2 May 2017 20:31:25 +0000 (UTC) Received: from localhost (ovpn-116-8.gru2.redhat.com [10.97.116.8]) by smtp.corp.redhat.com (Postfix) with ESMTP id B6C5F1BD861; Tue, 2 May 2017 20:31:24 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 36687C05AD64 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=ehabkost@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 36687C05AD64 From: Eduardo Habkost To: qemu-devel@nongnu.org Date: Tue, 2 May 2017 17:31:15 -0300 Message-Id: <20170502203115.22233-5-ehabkost@redhat.com> In-Reply-To: <20170502203115.22233-1-ehabkost@redhat.com> References: <20170502203115.22233-1-ehabkost@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 02 May 2017 20:31:25 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 4/4] x86: Support feature=force on the command-line 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: Michael Roth , Alexander Graf , Markus Armbruster , Igor Mammedov , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Introduce a new CPUFeatureSetting QAPI data type, and use it to support feature=3Dforce on -cpu. Signed-off-by: Eduardo Habkost --- qapi-schema.json | 32 +++++++++++++++++++++++++ target/i386/cpu.h | 2 ++ target/i386/cpu.c | 55 +++++++++++++++++++++++++++++++++------= ---- tests/test-x86-cpuid-compat.c | 14 ++++++++++- 4 files changed, 90 insertions(+), 13 deletions(-) diff --git a/qapi-schema.json b/qapi-schema.json index 01b087fa16..d716409114 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4250,6 +4250,38 @@ { 'command': 'query-machines', 'returns': ['MachineInfo'] } =20 ## +# @CPUFeatureSettingEnum: +# +# Additional valid values for a CPUFeatureSetting property. +# +# @force: Force feature to be enabled, even if the accelerator +# reports the feature as unavailable. Should be used only +# for testing or debugging purposes. +# +# Since: 2.10 +## +{ 'enum': 'CPUFeatureSettingEnum', + 'data': ['force'] } + +## +# @CPUFeatureSetting: +# +# Values for a CPU feature property. +# +# @bool: If false, the feature is forcibly disabled. +# If true, QEMU will try to enable the feature. QEMU will +# refuse to start if the feature is unavailable and +# 'enforce' mode is enabled in the CPU. +# +# @enum: See @CPUFeatureSettingEnum. +# +# Since: 2.10 +## +{ 'alternate': 'CPUFeatureSetting', + 'data': { 'bool': 'bool', + 'enum': 'CPUFeatureSettingEnum' } } + +## # @CpuDefinitionInfo: # # Virtual CPU definition. diff --git a/target/i386/cpu.h b/target/i386/cpu.h index c4602ca80d..7a34998e0a 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1149,6 +1149,8 @@ typedef struct CPUX86State { FeatureWordArray features; /* Features that were explicitly enabled/disabled */ FeatureWordArray user_features; + /* Features set to 'force' */ + FeatureWordArray forced_features; uint32_t cpuid_model[12]; =20 /* MTRRs */ diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 13c0985f11..6c24b92cee 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -3463,7 +3463,7 @@ static int x86_cpu_filter_features(X86CPU *cpu) uint32_t host_feat =3D x86_cpu_get_supported_feature_word(w, false); uint32_t requested_features =3D env->features[w]; - env->features[w] &=3D host_feat; + env->features[w] &=3D host_feat | env->forced_features[w]; cpu->filtered_features[w] =3D requested_features & ~env->features[= w]; if (cpu->filtered_features[w]) { rv =3D 1; @@ -3705,9 +3705,19 @@ static void x86_cpu_get_bit_prop(Object *obj, Visito= r *v, const char *name, { X86CPU *cpu =3D X86_CPU(obj); BitProperty *fp =3D opaque; - uint32_t f =3D cpu->env.features[fp->w]; - bool value =3D (f & fp->mask) =3D=3D fp->mask; - visit_type_bool(v, name, &value, errp); + bool bvalue =3D (cpu->env.features[fp->w] & fp->mask) =3D=3D fp->mask; + bool forced =3D (cpu->env.forced_features[fp->w] & fp->mask) =3D=3D fp= ->mask; + CPUFeatureSetting *value =3D g_new0(CPUFeatureSetting, 1); + + if (!forced) { + value->type =3D QTYPE_QBOOL; + value->u.q_bool =3D bvalue; + } else { + value->type =3D QTYPE_QSTRING; + value->u.q_enum =3D CPU_FEATURE_SETTING_ENUM_FORCE; + } + visit_type_CPUFeatureSetting(v, name, &value, errp); + qapi_free_CPUFeatureSetting(value); } =20 static void x86_cpu_set_bit_prop(Object *obj, Visitor *v, const char *name, @@ -3717,25 +3727,46 @@ static void x86_cpu_set_bit_prop(Object *obj, Visit= or *v, const char *name, X86CPU *cpu =3D X86_CPU(obj); BitProperty *fp =3D opaque; Error *local_err =3D NULL; - bool value; + CPUFeatureSetting *value =3D NULL; =20 if (dev->realized) { qdev_prop_set_after_realize(dev, name, errp); return; } =20 - visit_type_bool(v, name, &value, &local_err); + visit_type_CPUFeatureSetting(v, name, &value, &local_err); if (local_err) { error_propagate(errp, local_err); return; } =20 - if (value) { - cpu->env.features[fp->w] |=3D fp->mask; - } else { - cpu->env.features[fp->w] &=3D ~fp->mask; + switch (value->type) { + case QTYPE_QBOOL: + if (value->u.q_bool) { + cpu->env.features[fp->w] |=3D fp->mask; + } else { + cpu->env.features[fp->w] &=3D ~fp->mask; + } + cpu->env.forced_features[fp->w] &=3D ~fp->mask; + cpu->env.user_features[fp->w] |=3D fp->mask; + break; + case QTYPE_QSTRING: + switch (value->u.q_enum) { + case CPU_FEATURE_SETTING_ENUM_FORCE: + cpu->env.features[fp->w] |=3D fp->mask; + cpu->env.forced_features[fp->w] |=3D fp->mask; + break; + default: + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, + "CPUFeatureSetting"); + } + break; + default: + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, + "CPUFeatureSetting"); } - cpu->env.user_features[fp->w] |=3D fp->mask; + + qapi_free_CPUFeatureSetting(value); } =20 static void x86_cpu_release_bit_prop(Object *obj, const char *name, @@ -3769,7 +3800,7 @@ static void x86_cpu_register_bit_prop(X86CPU *cpu, fp =3D g_new0(BitProperty, 1); fp->w =3D w; fp->mask =3D mask; - object_property_add(OBJECT(cpu), prop_name, "bool", + object_property_add(OBJECT(cpu), prop_name, "CPUFeatureSetting", x86_cpu_get_bit_prop, x86_cpu_set_bit_prop, x86_cpu_release_bit_prop, fp, &error_abort); diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c index 00ee8a264f..9940f4de1c 100644 --- a/tests/test-x86-cpuid-compat.c +++ b/tests/test-x86-cpuid-compat.c @@ -98,6 +98,8 @@ typedef struct FeatureTestArgs { int bitnr; /* The expected value for the bit in (X86CPUFeatureWordInfo.features) = */ bool expected_value; + /* Don't look at filtered-features when checking feature value */ + bool ignore_filtered_features; } FeatureTestArgs; =20 /* Get the value for a feature word in a X86CPUFeatureWordInfo list */ @@ -129,7 +131,9 @@ static void test_feature_flag(const void *data) present =3D qobject_to_qlist(qom_get(path, "feature-words")); filtered =3D qobject_to_qlist(qom_get(path, "filtered-features")); value =3D get_feature_word(present, args->input_eax, args->input_ecx, = args->reg); - value |=3D get_feature_word(filtered, args->input_eax, args->input_ecx= , args->reg); + if (!args->ignore_filtered_features) { + value |=3D get_feature_word(filtered, args->input_eax, args->input= _ecx, args->reg); + } qtest_end(); =20 g_assert(!!(value & (1U << args->bitnr)) =3D=3D args->expected_value); @@ -336,5 +340,13 @@ int main(int argc, char **argv) "-machine accel=3Dkvm:tcg -cpu max,mmx=3Doff", 1, 0, "EDX", 23, false); =20 + { + FeatureTestArgs *a; + a =3D add_feature_test("x86/cpuid/features/monitor-force", + "-machine accel=3Dkvm:tcg -cpu 486,monitor=3Dforc= e", + 1, 0, "ECX", 3, true); + a->ignore_filtered_features =3D true; + } + return g_test_run(); } --=20 2.11.0.259.g40922b1