All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion
@ 2016-12-02 21:17 Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 01/17] qmp: Report QOM type name on query-cpu-definitions Eduardo Habkost
                   ` (18 more replies)
  0 siblings, 19 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:17 UTC (permalink / raw)
  To: qemu-devel
  Cc: Cornelia Huck, Christian Borntraeger, David Hildenbrand,
	libvir-list, Jiri Denemark, Jason J. Herne, Markus Armbruster,
	Richard Henderson, Igor Mammedov, Eric Blake

This series implements query-cpu-model-expansion on target-i386.

QAPI / interface changes
------------------------

When implementing this, I have noticed that the "host" CPU model
in i386 includes some migration-unsafe features that can't be
translated to any migration-safe representation: "pmu", and
"host-cache-info".

To be able to handle the migration-unsafe features, I have
extended the query-cpu-model-expansion definition to be clear
about what happens to those features when the CPU model is
expanded (in short: static expansion removes them, full expansion
keeps them).

I also added "static" and "migration-safe" fields to the return
value of query-cpu-model-expansion, so callers can know if the
the expanded representation is static and migration-safe.

Test code
---------

I have added a Python test script for the feature, that will try
multiple combinations of the expansion operation, and see if the
returned data keeps matches some constratins.

The test script works with the s390x query-cpu-model-expansion
command, except that: 1) I couldn't test it with KVM; 2) qtest.py
error handling when QEMU refuses to run is unreliable (so the
script needs runnability information to be availble in TCG mode,
too, to skip not-runnable CPU models and avoid problems).

Future versions of the test script could run a arch-specific
CPUID-dump guest binary, and validate data seen by the guest
directly. While we don't do that, the script validates all QOM
properties on the CPU objects looking for unexpected changes. At
least in the case of x86, the QOM properties will include lots of
the CPUID data seen by the guest, giving us decent coverage.

Patches from other series
-------------------------

This series includes patches from other series, just to help on
the implementation of the test code:
* "qmp: Report QOM type name on query-cpu-definitions", that
  was already submitted for 2.9
* qemu.py, qtest.py, and tests/Makefile.include changes

---
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: libvir-list@redhat.com
Cc: Jiri Denemark <jdenemar@redhat.com>
Cc: "Jason J. Herne" <jjherne@linux.vnet.ibm.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Eric Blake <eblake@redhat.com>

Eduardo Habkost (17):
  qmp: Report QOM type name on query-cpu-definitions
  qemu.py: Make logging optional
  qtest.py: Support QTEST_LOG environment variable
  qtest.py: make logging optional
  qtest.py: Make 'binary' parameter optional
  tests: Add rules to non-gtester qtest test cases
  target-i386: Reorganize and document CPUID initialization steps
  target-i386: Support "-cpu host" on TCG too
  target-i386: Move "host" properties to base class
  target-i386: Allow short strings to be used as vendor ID
  target-i386: Remove AMD feature flag aliases from Opteron models
  target-i386: Return migration-safe field on query-cpu-definitions
  cpu: Support comma escaping when parsing -cpu
  qapi: add static/migration-safe info to query-cpu-model-expansion
  target-i386: Define static "base" CPU model
  tests: query-cpu-model-test.py test code
  target-i386: Implement query-cpu-model-expansion QMP command

 qapi-schema.json              |  30 ++-
 scripts/qemu.py               |  25 ++-
 scripts/qtest.py              |  15 +-
 target-i386/cpu-qom.h         |   8 +-
 tests/Makefile.include        |  40 +++-
 tests/query-cpu-model-test.py | 421 ++++++++++++++++++++++++++++++++++++
 tests/test-x86-cpuid-compat.c |  19 ++
 monitor.c                     |   4 +-
 qom/cpu.c                     |  32 ++-
 target-arm/helper.c           |   1 +
 target-i386/cpu.c             | 481 +++++++++++++++++++++++++++++++-----------
 target-ppc/translate_init.c   |   1 +
 target-s390x/cpu_models.c     |   5 +
 13 files changed, 928 insertions(+), 154 deletions(-)
 create mode 100755 tests/query-cpu-model-test.py

-- 
2.7.4

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 01/17] qmp: Report QOM type name on query-cpu-definitions
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 02/17] qemu.py: Make logging optional Eduardo Habkost
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel

The new typename attribute on query-cpu-definitions will be used
to help management software use device-list-properties to check
which properties can be set using -cpu or -global for the CPU
model.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Patch originally submitted as:
  From: Eduardo Habkost <ehabkost@redhat.com>
  Date: Wed, 16 Nov 2016 16:21:39 -0200
  Message-Id: <1479320499-29818-1-git-send-email-ehabkost@redhat.com>
  Subject: [PATCH for-2.9] qmp: Report QOM type name on query-cpu-definitions
---
 qapi-schema.json            | 5 ++++-
 target-arm/helper.c         | 1 +
 target-i386/cpu.c           | 1 +
 target-ppc/translate_init.c | 1 +
 target-s390x/cpu_models.c   | 1 +
 5 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index f3e9bfc..8d113f8 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3218,6 +3218,9 @@
 # @unavailable-features: #optional List of properties that prevent
 #                        the CPU model from running in the current
 #                        host. (since 2.8)
+# @typename: Type name that can be used as argument to @device-list-properties,
+#            to introspect properties configurable using -cpu or -global.
+#            (since 2.9)
 #
 # @unavailable-features is a list of QOM property names that
 # represent CPU model attributes that prevent the CPU from running.
@@ -3239,7 +3242,7 @@
 ##
 { 'struct': 'CpuDefinitionInfo',
   'data': { 'name': 'str', '*migration-safe': 'bool', 'static': 'bool',
-            '*unavailable-features': [ 'str' ] } }
+            '*unavailable-features': [ 'str' ], 'typename': 'str' } }
 
 ##
 # @query-cpu-definitions:
diff --git a/target-arm/helper.c b/target-arm/helper.c
index b5b65ca..3fc01b5 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5207,6 +5207,7 @@ static void arm_cpu_add_definition(gpointer data, gpointer user_data)
     info = g_malloc0(sizeof(*info));
     info->name = g_strndup(typename,
                            strlen(typename) - strlen("-" TYPE_ARM_CPU));
+    info->q_typename = g_strdup(typename);
 
     entry = g_malloc0(sizeof(*entry));
     entry->value = info;
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index de1f30e..93ead1a 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2234,6 +2234,7 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
     info->name = x86_cpu_class_get_model_name(cc);
     x86_cpu_class_check_missing_features(cc, &info->unavailable_features);
     info->has_unavailable_features = true;
+    info->q_typename = g_strdup(object_class_get_name(oc));
 
     entry = g_malloc0(sizeof(*entry));
     entry->value = info;
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 626e031..19ef250 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -10305,6 +10305,7 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
 
         info = g_malloc0(sizeof(*info));
         info->name = g_strdup(alias->alias);
+        info->q_typename = g_strdup(object_class_get_name(oc));
 
         entry = g_malloc0(sizeof(*entry));
         entry->value = info;
diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index c1e729d..5b66d33 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -290,6 +290,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
     info->has_migration_safe = true;
     info->migration_safe = scc->is_migration_safe;
     info->q_static = scc->is_static;
+    info->q_typename = g_strdup(object_class_get_name(klass));
 
 
     entry = g_malloc0(sizeof(*entry));
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 02/17] qemu.py: Make logging optional
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 01/17] qmp: Report QOM type name on query-cpu-definitions Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 03/17] qtest.py: Support QTEST_LOG environment variable Eduardo Habkost
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel

If a test case doesn't make QEMU generate any output, there's no
need to redirect stdout and stderr to a file. On those cases,
logging can be disabled so any errors are included on the test
case output.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Patch originally submitted as part of series:
* [RFC v2 00/20] qmp: Report bus information on 'query-machines'
---
 scripts/qemu.py | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/scripts/qemu.py b/scripts/qemu.py
index 6d1b623..1468286 100644
--- a/scripts/qemu.py
+++ b/scripts/qemu.py
@@ -24,13 +24,17 @@ class QEMUMachine(object):
     '''A QEMU VM'''
 
     def __init__(self, binary, args=[], wrapper=[], name=None, test_dir="/var/tmp",
-                 monitor_address=None, socket_scm_helper=None, debug=False):
+                 monitor_address=None, socket_scm_helper=None, debug=False,
+                 logging=True):
         if name is None:
             name = "qemu-%d" % os.getpid()
         if monitor_address is None:
             monitor_address = os.path.join(test_dir, name + "-monitor.sock")
         self._monitor_address = monitor_address
-        self._qemu_log_path = os.path.join(test_dir, name + ".log")
+        if logging:
+            self._qemu_log_path = os.path.join(test_dir, name + ".log")
+        else:
+            self._qemu_log_path = None
         self._popen = None
         self._binary = binary
         self._args = list(args) # Force copy args in case we modify them
@@ -91,6 +95,8 @@ class QEMUMachine(object):
         return self._popen.pid
 
     def _load_io_log(self):
+        if self._qemu_log_path is None:
+            return
         with open(self._qemu_log_path, "r") as fh:
             self._iolog = fh.read()
 
@@ -115,17 +121,24 @@ class QEMUMachine(object):
     def _post_shutdown(self):
         if not isinstance(self._monitor_address, tuple):
             self._remove_if_exists(self._monitor_address)
-        self._remove_if_exists(self._qemu_log_path)
+        if self._qemu_log_path is not None:
+            self._remove_if_exists(self._qemu_log_path)
 
     def launch(self):
         '''Launch the VM and establish a QMP connection'''
         devnull = open('/dev/null', 'rb')
-        qemulog = open(self._qemu_log_path, 'wb')
+        if self._qemu_log_path is not None:
+            qemulog = open(self._qemu_log_path, 'wb')
+            stdout=qemulog
+            stderr=subprocess.STDOUT
+        else:
+            stdout=None
+            stderr=None
         try:
             self._pre_launch()
             args = self._wrapper + [self._binary] + self._base_args() + self._args
-            self._popen = subprocess.Popen(args, stdin=devnull, stdout=qemulog,
-                                           stderr=subprocess.STDOUT, shell=False)
+            self._popen = subprocess.Popen(args, stdin=devnull, stdout=stdout,
+                                           stderr=stderr, shell=False)
             self._post_launch()
         except:
             if self._popen:
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 03/17] qtest.py: Support QTEST_LOG environment variable
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 01/17] qmp: Report QOM type name on query-cpu-definitions Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 02/17] qemu.py: Make logging optional Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 04/17] qtest.py: make logging optional Eduardo Habkost
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel

qtest logs everything to stderr by default, but we don't want it
to be the default behavior on test cases.

Implement the same behavior of libqtest.c, and redirect the qtest
log to /dev/null by default unless the QTEST_LOG environment
variable is set.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Patch originally submitted as part of series:
* [RFC v2 00/20] qmp: Report bus information on 'query-machines'
---
 scripts/qtest.py | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/scripts/qtest.py b/scripts/qtest.py
index d5aecb5..5ac2c69 100644
--- a/scripts/qtest.py
+++ b/scripts/qtest.py
@@ -88,8 +88,14 @@ class QEMUQtestMachine(qemu.QEMUMachine):
         self._qtest_path = os.path.join(test_dir, name + "-qtest.sock")
 
     def _base_args(self):
+        if os.getenv('QTEST_LOG'):
+            qtest_log = '/dev/fd/2'
+        else:
+            qtest_log = '/dev/null'
+
         args = super(QEMUQtestMachine, self)._base_args()
         args.extend(['-qtest', 'unix:path=' + self._qtest_path,
+                     '-qtest-log', qtest_log,
                      '-machine', 'accel=qtest'])
         return args
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 04/17] qtest.py: make logging optional
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (2 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 03/17] qtest.py: Support QTEST_LOG environment variable Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 05/17] qtest.py: Make 'binary' parameter optional Eduardo Habkost
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel

Support the 'logging' parameter on QEMUQtestMachine, for test
cases that don't require logging.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Patch originally submitted as part of series:
* [RFC v2 00/20] qmp: Report bus information on 'query-machines'
---
 scripts/qtest.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/scripts/qtest.py b/scripts/qtest.py
index 5ac2c69..0496490 100644
--- a/scripts/qtest.py
+++ b/scripts/qtest.py
@@ -80,11 +80,12 @@ class QEMUQtestMachine(qemu.QEMUMachine):
     '''A QEMU VM'''
 
     def __init__(self, binary, args=[], name=None, test_dir="/var/tmp",
-                 socket_scm_helper=None):
+                 socket_scm_helper=None, logging=True):
         if name is None:
             name = "qemu-%d" % os.getpid()
         super(QEMUQtestMachine, self).__init__(binary, args, name=name, test_dir=test_dir,
-                                               socket_scm_helper=socket_scm_helper)
+                                               socket_scm_helper=socket_scm_helper,
+                                               logging=logging)
         self._qtest_path = os.path.join(test_dir, name + "-qtest.sock")
 
     def _base_args(self):
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 05/17] qtest.py: Make 'binary' parameter optional
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (3 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 04/17] qtest.py: make logging optional Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 06/17] tests: Add rules to non-gtester qtest test cases Eduardo Habkost
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel

If the 'binary' parameter is omitted, use the $QTEST_QEMU_BINARY
environment variable.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Patch originally submitted as part of series:
* [RFC v2 00/20] qmp: Report bus information on 'query-machines'
---
 scripts/qtest.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/scripts/qtest.py b/scripts/qtest.py
index 0496490..5a37b48 100644
--- a/scripts/qtest.py
+++ b/scripts/qtest.py
@@ -79,8 +79,10 @@ class QEMUQtestProtocol(object):
 class QEMUQtestMachine(qemu.QEMUMachine):
     '''A QEMU VM'''
 
-    def __init__(self, binary, args=[], name=None, test_dir="/var/tmp",
+    def __init__(self, binary=None, args=[], name=None, test_dir="/var/tmp",
                  socket_scm_helper=None, logging=True):
+        if binary is None:
+            binary = os.getenv('QTEST_QEMU_BINARY')
         if name is None:
             name = "qemu-%d" % os.getpid()
         super(QEMUQtestMachine, self).__init__(binary, args, name=name, test_dir=test_dir,
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 06/17] tests: Add rules to non-gtester qtest test cases
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (4 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 05/17] qtest.py: Make 'binary' parameter optional Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 07/17] target-i386: Reorganize and document CPUID initialization steps Eduardo Habkost
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel

Today, simple non-gtester binaries can be run easily by a single
Makefile rule (e.g. check-tests/qemu-iotest-quick.sh), but we
don't have anything to help us automatically run the same test
binary for multiple architectures.

This add check-simpleqtest-* rules that will help us run binaries
present in $(check-simpleqtest-*-y).

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Patch originally submitted as part of series:
* [RFC v2 00/20] qmp: Report bus information on 'query-machines'
---
 tests/Makefile.include | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/tests/Makefile.include b/tests/Makefile.include
index e98d3b6..63c4347 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -791,6 +791,40 @@ check-report.html: check-report.xml
 	$(call quiet-command,gtester-report $< > $@,"GEN","$@")
 
 
+# rules for non-gtester qtest tests:
+
+SIMPLETEST_OPTIONS = $(if $(V),--verbose,--quiet)
+
+# rule dependencies are:
+#   check-simpleqtest: check-simpleqtest-$(ARCH) for each ARCH in QTEST_ARCH
+#   check-simpleqtest-$(ARCH): check-simpleqtest-$(TEST)-$(ARCH) for each
+#                                  TEST in $(check-simpleqtest-$(ARCH)-y)
+#                              (generated by qtest_target macro)
+#   check-simpleqtest-$(TEST)-$(ARCH): runs test with $(SIMPLETEST_OPTIONS)
+#                                      (generated by qtest_target macro)
+#
+# $(check-simpleqtest-$(ARCH)-y) automatically includes
+#                                $(check-simpleqtest-generic-y)
+
+define qtest-target
+
+check-simpleqtest-$(1)-y += $$(check-simpleqtest-generic-y)
+
+.PHONY: $$(patsubst %, check-simpleqtest-%-$(1), $$(check-simpleqtest-$(1)-y))
+$$(patsubst %, check-simpleqtest-%-$(1), $$(check-simpleqtest-$(1)-y)): check-simpleqtest-%-$(1): %
+	$$(call quiet-command,QTEST_QEMU_BINARY=$(1)-softmmu/qemu-system-$(1) \
+		QTEST_QEMU_IMG=qemu-img$$(EXESUF) \
+		MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$((RANDOM % 255 + 1))} \
+		$$< $$(SIMPLETEST_OPTIONS),"QTEST-$(1)", "$$<")
+
+.PHONY: check-simpleqtest-$(1)
+check-simpleqtest-$(1): $$(patsubst %, check-simpleqtest-%-$(1), $$(check-simpleqtest-$(1)-y))
+
+endef
+
+$(foreach TARGET,$(QTEST_TARGETS),$(eval $(call qtest-target,$(TARGET))))
+
+
 # Other tests
 
 QEMU_IOTESTS_HELPERS-$(CONFIG_LINUX) = tests/qemu-iotests/socket_scm_helper$(EXESUF)
@@ -818,7 +852,8 @@ $(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json
 
 .PHONY: check-qapi-schema check-qtest check-unit check check-clean
 check-qapi-schema: $(patsubst %,check-%, $(check-qapi-schema-y))
-check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS))
+check-simpleqtest: $(patsubst %,check-simpleqtest-%, $(QTEST_TARGETS))
+check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS)) check-simpleqtest
 check-unit: $(patsubst %,check-%, $(check-unit-y))
 check-block: $(patsubst %,check-%, $(check-block-y))
 check: check-qapi-schema check-unit check-qtest
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 07/17] target-i386: Reorganize and document CPUID initialization steps
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (5 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 06/17] tests: Add rules to non-gtester qtest test cases Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 08/17] target-i386: Support "-cpu host" on TCG too Eduardo Habkost
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel

CPU runnability checks and CPU model expansion have slightly
different requirements. Document the steps involved in loading a
CPU model and realizing a CPU, so their requirements and purpose
are clearly defined.

This patch doesn't change any implementation. It just add
comments, rename the x86_cpu_load_features() function for clarity
(so it won't be confused with x86_cpu_load_def()), and move
x86_cpu_filter_features() closer to it.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/cpu.c | 103 ++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 72 insertions(+), 31 deletions(-)

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 93ead1a..1a276db 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2087,7 +2087,7 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features,
     }
 }
 
-static void x86_cpu_load_features(X86CPU *cpu, Error **errp);
+static void x86_cpu_expand_features(X86CPU *cpu, Error **errp);
 static int x86_cpu_filter_features(X86CPU *cpu);
 
 /* Check for missing features that may prevent the CPU class from
@@ -2110,9 +2110,9 @@ static void x86_cpu_class_check_missing_features(X86CPUClass *xcc,
 
     xc = X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc))));
 
-    x86_cpu_load_features(xc, &err);
+    x86_cpu_expand_features(xc, &err);
     if (err) {
-        /* Errors at x86_cpu_load_features should never happen,
+        /* Errors at x86_cpu_expand_features should never happen,
          * but in case it does, just report the model as not
          * runnable at all using the "type" property.
          */
@@ -2272,31 +2272,6 @@ static uint32_t x86_cpu_get_supported_feature_word(FeatureWord w,
     return r;
 }
 
-/*
- * Filters CPU feature words based on host availability of each feature.
- *
- * Returns: 0 if all flags are supported by the host, non-zero otherwise.
- */
-static int x86_cpu_filter_features(X86CPU *cpu)
-{
-    CPUX86State *env = &cpu->env;
-    FeatureWord w;
-    int rv = 0;
-
-    for (w = 0; w < FEATURE_WORDS; w++) {
-        uint32_t host_feat =
-            x86_cpu_get_supported_feature_word(w, false);
-        uint32_t requested_features = env->features[w];
-        env->features[w] &= host_feat;
-        cpu->filtered_features[w] = requested_features & ~env->features[w];
-        if (cpu->filtered_features[w]) {
-            rv = 1;
-        }
-    }
-
-    return rv;
-}
-
 static void x86_cpu_report_filtered_features(X86CPU *cpu)
 {
     FeatureWord w;
@@ -3113,8 +3088,48 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu)
     env->features[FEAT_XSAVE_COMP_HI] = mask >> 32;
 }
 
-/* Load CPUID data based on configured features */
-static void x86_cpu_load_features(X86CPU *cpu, Error **errp)
+/***** Steps involved on loading and filtering CPUID data
+ *
+ * When initializing and realizing a CPU object, the steps
+ * involved in setting up CPUID data are:
+ *
+ * 1) Loading CPU model definition (X86CPUDefinition). This is
+ *    implemented by x86_cpu_load_def() and should be completely
+ *    transparent, as it is done automatically by instance_init.
+ *    No code should need to look at X86CPUDefinition structs
+ *    outside instance_init.
+ *
+ * 2) CPU expansion. This is done by realize before CPUID
+ *    filtering, and will make sure host/accelerator data is
+ *    loaded for CPU models that depend on host capabilities
+ *    (e.g. "host"). CPU expansion is not supposed to trigger any
+ *    errors. Done by x86_cpu_expand_features().
+ *
+ * 3) CPUID filtering. This will initialize extra data related to
+ *    CPUID, and will check if the host supports all capabilities
+ *    required by the CPU. Runnability of a CPU model is
+ *    determined at this step. Done by x86_cpu_filter_features().
+ *
+ * Some operations don't require all steps to be performed.
+ * More precisely:
+ *
+ * - CPU instance creation (instance_init) will run only CPU
+ *   model loading. CPU expansion can't run at instance_init-time
+ *   because host/accelerator data is not yet available.
+ * - CPU realization will perform both CPU model expansion and CPUID
+ *   filtering, and return an error in case one of them fails.
+ * - query-cpu-definitions needs to run all 3 steps. It needs
+ *   to run CPUID filtering, as the 'unavailable-features'
+ *   field is set based on the filtering results.
+ * - The query-cpu-model-expansion QMP command only needs to run
+ *   CPU model loading and CPU expansion. It should not filter
+ *   any CPUID data based on host capabilities.
+ */
+
+/* Expand CPU configuration data, based on configured features
+ * and host/accelerator capabilities when appropriate.
+ */
+static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
 {
     CPUX86State *env = &cpu->env;
     FeatureWord w;
@@ -3191,6 +3206,32 @@ out:
     }
 }
 
+/*
+ * Finishes initialization of CPUID data, filters CPU feature
+ * words based on host availability of each feature.
+ *
+ * Returns: 0 if all flags are supported by the host, non-zero otherwise.
+ */
+static int x86_cpu_filter_features(X86CPU *cpu)
+{
+    CPUX86State *env = &cpu->env;
+    FeatureWord w;
+    int rv = 0;
+
+    for (w = 0; w < FEATURE_WORDS; w++) {
+        uint32_t host_feat =
+            x86_cpu_get_supported_feature_word(w, false);
+        uint32_t requested_features = env->features[w];
+        env->features[w] &= host_feat;
+        cpu->filtered_features[w] = requested_features & ~env->features[w];
+        if (cpu->filtered_features[w]) {
+            rv = 1;
+        }
+    }
+
+    return rv;
+}
+
 #define IS_INTEL_CPU(env) ((env)->cpuid_vendor1 == CPUID_VENDOR_INTEL_1 && \
                            (env)->cpuid_vendor2 == CPUID_VENDOR_INTEL_2 && \
                            (env)->cpuid_vendor3 == CPUID_VENDOR_INTEL_3)
@@ -3218,7 +3259,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
         return;
     }
 
-    x86_cpu_load_features(cpu, &local_err);
+    x86_cpu_expand_features(cpu, &local_err);
     if (local_err) {
         goto out;
     }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 08/17] target-i386: Support "-cpu host" on TCG too
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (6 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 07/17] target-i386: Reorganize and document CPUID initialization steps Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 09/17] target-i386: Move "host" properties to base class Eduardo Habkost
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson

Change the meaning of "-cpu host" to "enable all features
supported by the accelerator in the current host", so that it can
be used to enable all features supported by TCG.

To make sure "host" is still at the end of the list in "-cpu
help", add a "ordering" field that will be used when sorting the
CPU model list.

Cc: Richard Henderson <rth@twiddle.net>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/cpu-qom.h |  4 ++--
 target-i386/cpu.c     | 26 +++++---------------------
 2 files changed, 7 insertions(+), 23 deletions(-)

diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 7c9a07a..93c9679 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -47,7 +47,7 @@ typedef struct X86CPUDefinition X86CPUDefinition;
 /**
  * X86CPUClass:
  * @cpu_def: CPU model definition
- * @kvm_required: Whether CPU model requires KVM to be enabled.
+ * @ordering: Ordering on the "-cpu help" CPU model list.
  * @parent_realize: The parent class' realize handler.
  * @parent_reset: The parent class' reset handler.
  *
@@ -61,7 +61,7 @@ typedef struct X86CPUClass {
     /* Should be eventually replaced by subclass-specific property defaults. */
     X86CPUDefinition *cpu_def;
 
-    bool kvm_required;
+    int ordering;
 
     /* Optional description of CPU model.
      * If unavailable, cpu_def->model_id is used */
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 1a276db..691ec5e 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1575,7 +1575,7 @@ static void host_x86_cpu_class_init(ObjectClass *oc, void *data)
     X86CPUClass *xcc = X86_CPU_CLASS(oc);
     uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
 
-    xcc->kvm_required = true;
+    xcc->ordering = 9; /* Show it last on "-cpu help" */
 
     host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
     x86_cpu_vendor_words2str(host_cpudef.vendor, ebx, edx, ecx);
@@ -1589,8 +1589,7 @@ static void host_x86_cpu_class_init(ObjectClass *oc, void *data)
 
     xcc->cpu_def = &host_cpudef;
     xcc->model_description =
-        "KVM processor with all supported host features "
-        "(only available in KVM mode)";
+        "Enables all features supported by the accelerator in the current host";
 
     /* level, xlevel, xlevel2, and the feature words are initialized on
      * instance_init, because they require KVM to be initialized.
@@ -2101,13 +2100,6 @@ static void x86_cpu_class_check_missing_features(X86CPUClass *xcc,
     Error *err = NULL;
     strList **next = missing_feats;
 
-    if (xcc->kvm_required && !kvm_enabled()) {
-        strList *new = g_new0(strList, 1);
-        new->value = g_strdup("kvm");;
-        *missing_feats = new;
-        return;
-    }
-
     xc = X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc))));
 
     x86_cpu_expand_features(xc, &err);
@@ -2155,7 +2147,7 @@ static void listflags(FILE *f, fprintf_function print, const char **featureset)
     }
 }
 
-/* Sort alphabetically by type name, listing kvm_required models last. */
+/* Sort alphabetically by type name, respecting X86CPUClass::ordering. */
 static gint x86_cpu_list_compare(gconstpointer a, gconstpointer b)
 {
     ObjectClass *class_a = (ObjectClass *)a;
@@ -2164,9 +2156,8 @@ static gint x86_cpu_list_compare(gconstpointer a, gconstpointer b)
     X86CPUClass *cc_b = X86_CPU_CLASS(class_b);
     const char *name_a, *name_b;
 
-    if (cc_a->kvm_required != cc_b->kvm_required) {
-        /* kvm_required items go last */
-        return cc_a->kvm_required ? 1 : -1;
+    if (cc_a->ordering != cc_b->ordering) {
+        return cc_a->ordering - cc_b->ordering;
     } else {
         name_a = object_class_get_name(class_a);
         name_b = object_class_get_name(class_b);
@@ -3247,13 +3238,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
     Error *local_err = NULL;
     static bool ht_warned;
 
-    if (xcc->kvm_required && !kvm_enabled()) {
-        char *name = x86_cpu_class_get_model_name(xcc);
-        error_setg(&local_err, "CPU model '%s' requires KVM", name);
-        g_free(name);
-        goto out;
-    }
-
     if (cpu->apic_id == UNASSIGNED_APIC_ID) {
         error_setg(errp, "apic-id property was not initialized properly");
         return;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 09/17] target-i386: Move "host" properties to base class
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (7 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 08/17] target-i386: Support "-cpu host" on TCG too Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 10/17] target-i386: Allow short strings to be used as vendor ID Eduardo Habkost
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel

Make the "pmu" and "host-cache-info" properties configurable on
all CPU model classes. This way, query-cpu-model-expansion will
be able to return the value of those properties when returning
expansion data using the "base" CPU model as base.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/cpu.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 691ec5e..98e1063 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1559,12 +1559,6 @@ static int cpu_x86_fill_model_id(char *str)
 
 static X86CPUDefinition host_cpudef;
 
-static Property host_x86_cpu_properties[] = {
-    DEFINE_PROP_BOOL("migratable", X86CPU, migratable, true),
-    DEFINE_PROP_BOOL("host-cache-info", X86CPU, cache_info_passthrough, false),
-    DEFINE_PROP_END_OF_LIST()
-};
-
 /* class_init for the "host" CPU model
  *
  * This function may be called before KVM is initialized.
@@ -1595,7 +1589,6 @@ static void host_x86_cpu_class_init(ObjectClass *oc, void *data)
      * instance_init, because they require KVM to be initialized.
      */
 
-    dc->props = host_x86_cpu_properties;
     /* Reason: host_x86_cpu_initfn() dies when !kvm_enabled() */
     dc->cannot_destroy_with_object_finalize_yet = true;
 }
@@ -3700,6 +3693,8 @@ static Property x86_cpu_properties[] = {
     DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
     DEFINE_PROP_BOOL("lmce", X86CPU, enable_lmce, false),
     DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true),
+    DEFINE_PROP_BOOL("host-cache-info", X86CPU, cache_info_passthrough, false),
+    DEFINE_PROP_BOOL("migratable", X86CPU, migratable, true),
     DEFINE_PROP_END_OF_LIST()
 };
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 10/17] target-i386: Allow short strings to be used as vendor ID
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (8 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 09/17] target-i386: Move "host" properties to base class Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 11/17] target-i386: Remove AMD feature flag aliases from Opteron models Eduardo Habkost
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel

If a short string is specified, it will be padded with zeroes.
Without this, "query-cpu-model-expansion model=base" would return
an expansion that would never work in the command-line.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/cpu.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 98e1063..a584c3e 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1789,19 +1789,22 @@ static void x86_cpuid_set_vendor(Object *obj, const char *value,
     X86CPU *cpu = X86_CPU(obj);
     CPUX86State *env = &cpu->env;
     int i;
+    char buf[CPUID_VENDOR_SZ] = { 0 };
 
-    if (strlen(value) != CPUID_VENDOR_SZ) {
+    if (strlen(value) > CPUID_VENDOR_SZ) {
         error_setg(errp, QERR_PROPERTY_VALUE_BAD, "", "vendor", value);
         return;
     }
 
+    strncpy(buf, value, sizeof(buf));
+
     env->cpuid_vendor1 = 0;
     env->cpuid_vendor2 = 0;
     env->cpuid_vendor3 = 0;
     for (i = 0; i < 4; i++) {
-        env->cpuid_vendor1 |= ((uint8_t)value[i    ]) << (8 * i);
-        env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
-        env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
+        env->cpuid_vendor1 |= ((uint8_t)buf[i])     << (8 * i);
+        env->cpuid_vendor2 |= ((uint8_t)buf[i + 4]) << (8 * i);
+        env->cpuid_vendor3 |= ((uint8_t)buf[i + 8]) << (8 * i);
     }
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 11/17] target-i386: Remove AMD feature flag aliases from Opteron models
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (9 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 10/17] target-i386: Allow short strings to be used as vendor ID Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 12/17] target-i386: Return migration-safe field on query-cpu-definitions Eduardo Habkost
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel

When CPU vendor is set to AMD, the AMD feature alias bits on
CPUID[0x80000001].EDX are already automatically copied from CPUID[1].EDX
on x86_cpu_realizefn(). When CPU vendor is Intel, those bits are
reserved and should be zero. On either case, those bits shouldn't be set
in the CPU model table.

Commit 726a8ff68677d8d5fba17eb0ffb85076bfb598dc removed those
bits from most CPU models, but the Opteron_* entries still have
them. Remove the alias bits from Opteron_* too.

Add an assert() to x86_register_cpudef_type() to ensure we don't
make the same mistake again.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/cpu.c | 46 ++++++++++++----------------------------------
 1 file changed, 12 insertions(+), 34 deletions(-)

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index a584c3e..76a6a30 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1338,12 +1338,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
         .features[FEAT_1_ECX] =
             CPUID_EXT_SSE3,
         .features[FEAT_8000_0001_EDX] =
-            CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
-            CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
-            CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
-            CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
-            CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
-            CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
+            CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
         .xlevel = 0x80000008,
         .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
     },
@@ -1364,13 +1359,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_EXT_CX16 | CPUID_EXT_SSE3,
         /* Missing: CPUID_EXT2_RDTSCP */
         .features[FEAT_8000_0001_EDX] =
-            CPUID_EXT2_LM | CPUID_EXT2_FXSR |
-            CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
-            CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
-            CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
-            CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
-            CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
-            CPUID_EXT2_DE | CPUID_EXT2_FPU,
+            CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
         .features[FEAT_8000_0001_ECX] =
             CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
         .xlevel = 0x80000008,
@@ -1394,13 +1383,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_EXT_SSE3,
         /* Missing: CPUID_EXT2_RDTSCP */
         .features[FEAT_8000_0001_EDX] =
-            CPUID_EXT2_LM | CPUID_EXT2_FXSR |
-            CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
-            CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
-            CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
-            CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
-            CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
-            CPUID_EXT2_DE | CPUID_EXT2_FPU,
+            CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
         .features[FEAT_8000_0001_ECX] =
             CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
             CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
@@ -1427,13 +1410,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_EXT_SSE3,
         /* Missing: CPUID_EXT2_RDTSCP */
         .features[FEAT_8000_0001_EDX] =
-            CPUID_EXT2_LM |
-            CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
-            CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
-            CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
-            CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
-            CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
-            CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
+            CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_NX |
+            CPUID_EXT2_SYSCALL,
         .features[FEAT_8000_0001_ECX] =
             CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
             CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
@@ -1463,13 +1441,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
         /* Missing: CPUID_EXT2_RDTSCP */
         .features[FEAT_8000_0001_EDX] =
-            CPUID_EXT2_LM |
-            CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
-            CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
-            CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
-            CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
-            CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
-            CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
+            CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_NX |
+            CPUID_EXT2_SYSCALL,
         .features[FEAT_8000_0001_ECX] =
             CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
             CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
@@ -2356,6 +2329,11 @@ static void x86_register_cpudef_type(X86CPUDefinition *def)
         .class_data = def,
     };
 
+    /* AMD aliases are handled at runtime based on CPUID vendor, so
+     * they shouldn't be set on the CPU model table.
+     */
+    assert(!(def->features[FEAT_8000_0001_EDX] & CPUID_EXT2_AMD_ALIASES));
+
     type_register(&ti);
     g_free(typename);
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 12/17] target-i386: Return migration-safe field on query-cpu-definitions
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (10 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 11/17] target-i386: Remove AMD feature flag aliases from Opteron models Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 13/17] cpu: Support comma escaping when parsing -cpu Eduardo Habkost
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel

Return the migration-safe field on query-cpu-definitions. All CPU
models in x86 are migration-safe except "host".

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/cpu-qom.h | 2 ++
 target-i386/cpu.c     | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 93c9679..7561891 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -48,6 +48,7 @@ typedef struct X86CPUDefinition X86CPUDefinition;
  * X86CPUClass:
  * @cpu_def: CPU model definition
  * @ordering: Ordering on the "-cpu help" CPU model list.
+ * @migration_safe: See CpuDefinitionInfo::migration_safe
  * @parent_realize: The parent class' realize handler.
  * @parent_reset: The parent class' reset handler.
  *
@@ -62,6 +63,7 @@ typedef struct X86CPUClass {
     X86CPUDefinition *cpu_def;
 
     int ordering;
+    bool migration_safe;
 
     /* Optional description of CPU model.
      * If unavailable, cpu_def->model_id is used */
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 76a6a30..78b25af 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2195,6 +2195,8 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
     x86_cpu_class_check_missing_features(cc, &info->unavailable_features);
     info->has_unavailable_features = true;
     info->q_typename = g_strdup(object_class_get_name(oc));
+    info->migration_safe = cc->migration_safe;
+    info->has_migration_safe = true;
 
     entry = g_malloc0(sizeof(*entry));
     entry->value = info;
@@ -2317,6 +2319,7 @@ static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
     X86CPUClass *xcc = X86_CPU_CLASS(oc);
 
     xcc->cpu_def = cpudef;
+    xcc->migration_safe = true;
 }
 
 static void x86_register_cpudef_type(X86CPUDefinition *def)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 13/17] cpu: Support comma escaping when parsing -cpu
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (11 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 12/17] target-i386: Return migration-safe field on query-cpu-definitions Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 14/17] qapi: add static/migration-safe info to query-cpu-model-expansion Eduardo Habkost
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: Igor Mammedov

Currently it's impossible to use commas inside any option value
in -cpu due to the simple way the parser splits the options.

Change both cpu_common_parse_features() and
x86_cpu_parse_featurestr() to use get_opt_*() parsing options,
that can handle handle ",," escaping of commas.

The ideal solution is to use QemuOpts to parse the -cpu option.
But this will require changing the CPUClass::parse_features()
interface, so it will be done later.

Cc: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 tests/test-x86-cpuid-compat.c | 19 +++++++++++++
 qom/cpu.c                     | 32 +++++++++++++++-------
 target-i386/cpu.c             | 63 ++++++++++++++++++++++---------------------
 3 files changed, 74 insertions(+), 40 deletions(-)

diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c
index 79a2e69..06caa5b 100644
--- a/tests/test-x86-cpuid-compat.c
+++ b/tests/test-x86-cpuid-compat.c
@@ -4,6 +4,7 @@
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qint.h"
 #include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qstring.h"
 #include "libqtest.h"
 
 static char *get_cpu0_qom_path(void)
@@ -52,6 +53,22 @@ typedef struct CpuidTestArgs {
     int64_t expected_value;
 } CpuidTestArgs;
 
+static void test_commas(void)
+{
+    char *path;
+    QString *value;
+
+    qtest_start("-cpu 'qemu64,fpu=on,model-id=A CPU with commas,,fpu=off'");
+    path = get_cpu0_qom_path();
+    value = qobject_to_qstring(qom_get(path, "model-id"));
+    g_assert_true(qom_get_bool(path, "fpu"));
+    g_assert_cmpstr(qstring_get_str(value), ==, "A CPU with commas,fpu=off");
+    qtest_end();
+
+    QDECREF(value);
+    g_free(path);
+}
+
 static void test_cpuid_prop(const void *data)
 {
     const CpuidTestArgs *args = data;
@@ -132,6 +149,8 @@ int main(int argc, char **argv)
     g_test_add_func("/x86/cpuid/parsing-plus-minus", test_plus_minus);
 #endif
 
+    g_test_add_func("/x86/parsing/commas", test_commas);
+
     /* Original level values for CPU models: */
     add_cpuid_test("x86/cpuid/phenom/level",
                    "-cpu phenom", "level", 5);
diff --git a/qom/cpu.c b/qom/cpu.c
index 03d9190..47d69f7 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -295,8 +295,7 @@ static ObjectClass *cpu_common_class_by_name(const char *cpu_model)
 static void cpu_common_parse_features(const char *typename, char *features,
                                       Error **errp)
 {
-    char *featurestr; /* Single "key=value" string being parsed */
-    char *val;
+    const char *featurestr;
     static bool cpu_globals_initialized;
 
     /* TODO: all callers of ->parse_features() need to be changed to
@@ -310,16 +309,26 @@ static void cpu_common_parse_features(const char *typename, char *features,
     }
     cpu_globals_initialized = true;
 
-    featurestr = features ? strtok(features, ",") : NULL;
+    if (!features) {
+        return;
+    }
 
-    while (featurestr) {
-        val = strchr(featurestr, '=');
-        if (val) {
+    /*TODO: Use QemuOpts to parse -cpu on main(), so we don't need
+     *      to manually call get_opt_*() here.
+     */
+    for (featurestr = features; *featurestr != '\0'; featurestr++) {
+        const char *pe = strchr(featurestr, '=');
+        const char *pc = strchr(featurestr, ',');
+        if (pe && (!pc || pc > pe)) {
+            char option[128], val[1024];
             GlobalProperty *prop = g_new0(typeof(*prop), 1);
-            *val = 0;
-            val++;
+
+            featurestr = get_opt_name(option, sizeof(option), featurestr, '=');
+            featurestr++;
+            featurestr = get_opt_value(val, sizeof(val), featurestr);
+
             prop->driver = typename;
-            prop->property = g_strdup(featurestr);
+            prop->property = g_strdup(option);
             prop->value = g_strdup(val);
             prop->errp = &error_fatal;
             qdev_prop_register_global(prop);
@@ -328,7 +337,10 @@ static void cpu_common_parse_features(const char *typename, char *features,
                        featurestr);
             return;
         }
-        featurestr = strtok(NULL, ",");
+
+        if (*featurestr != ',') {
+            break;
+        }
     }
 }
 
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 78b25af..3539419 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1968,7 +1968,7 @@ static gint compare_string(gconstpointer a, gconstpointer b)
 static void x86_cpu_parse_featurestr(const char *typename, char *features,
                                      Error **errp)
 {
-    char *featurestr; /* Single 'key=value" string being parsed */
+    const char *featurestr;
     static bool cpu_globals_initialized;
     bool ambiguous = false;
 
@@ -1981,36 +1981,40 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features,
         return;
     }
 
-    for (featurestr = strtok(features, ",");
-         featurestr;
-         featurestr = strtok(NULL, ",")) {
-        const char *name;
-        const char *val = NULL;
-        char *eq = NULL;
-        char num[32];
+    /*TODO: Use QemuOpts to parse -cpu on main(), so we don't need
+     *      to manually call get_opt_*() here.
+     */
+    for (featurestr = features;
+         *featurestr != '\0';
+         *featurestr == ',' ? featurestr++ : 0) {
+        char name[128], val[1024];
         GlobalProperty *prop;
-
-        /* Compatibility syntax: */
-        if (featurestr[0] == '+') {
-            plus_features = g_list_append(plus_features,
-                                          g_strdup(featurestr + 1));
-            continue;
-        } else if (featurestr[0] == '-') {
-            minus_features = g_list_append(minus_features,
-                                           g_strdup(featurestr + 1));
-            continue;
-        }
-
-        eq = strchr(featurestr, '=');
-        if (eq) {
-            *eq++ = 0;
-            val = eq;
+        const char *pe = strchr(featurestr, '=');
+        const char *pc = strchr(featurestr, ',');
+
+        if (pe && (!pc || pc > pe)) {
+            /* opt=value[,...] */
+            featurestr = get_opt_name(name, sizeof(name), featurestr, '=');
+            featurestr++;
+            featurestr = get_opt_value(val, sizeof(val), featurestr);
         } else {
-            val = "on";
+            /* opt[,...] */
+            featurestr = get_opt_name(name, sizeof(name), featurestr, ',');
+            pstrcpy(val, sizeof(val), "on");
+
+            /* Compatibility syntax: */
+            if (name[0] == '+') {
+                plus_features = g_list_append(plus_features,
+                                              g_strdup(name + 1));
+                continue;
+            } else if (name[0] == '-') {
+                minus_features = g_list_append(minus_features,
+                                               g_strdup(name + 1));
+                continue;
+            }
         }
 
-        feat2prop(featurestr);
-        name = featurestr;
+        feat2prop(name);
 
         if (g_list_find_custom(plus_features, name, compare_string)) {
             error_report("warning: Ambiguous CPU model string. "
@@ -2036,9 +2040,8 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features,
                 error_setg(errp, "bad numerical value %s", val);
                 return;
             }
-            snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
-            val = num;
-            name = "tsc-frequency";
+            snprintf(val, sizeof(val), "%" PRId64, tsc_freq);
+            pstrcpy(name, sizeof(name), "tsc-frequency");
         }
 
         prop = g_new0(typeof(*prop), 1);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 14/17] qapi: add static/migration-safe info to query-cpu-model-expansion
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (12 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 13/17] cpu: Support comma escaping when parsing -cpu Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-13  9:47   ` Markus Armbruster
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 15/17] target-i386: Define static "base" CPU model Eduardo Habkost
                   ` (4 subsequent siblings)
  18 siblings, 1 reply; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: Cornelia Huck, Christian Borntraeger, David Hildenbrand,
	libvir-list, Jiri Denemark, Jason J. Herne, Markus Armbruster,
	Eric Blake

On x86, "-cpu host" enables some features that can't be
represented by a static CPU model definition: cache info
passthrough ("host-cache-info") and PMU passthrough ("pmu"). This
means a type=static expansion of "host" can't include those
features.

A type=full expansion of "host", on the other hand, can include
those features, but then the returned data won't be a static CPU
model representation.

Add a note to the documentation explaining that when using CPU
models that include non-migration-safe features, users need to
choose being precision and safety: a precise expansion of the CPU
model (full) won't be safe (static), (because they would include
pmu=on and host-cache-info=on), and a safe (static) expansion of
the CPU model won't be precise.

Architectures where CPU model expansion is always migration-safe
(e.g. s390x) can simply do what they already do, and set
'migration-safe' and 'static' to true.

Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: libvir-list@redhat.com
Cc: Jiri Denemark <jdenemar@redhat.com>
Cc: "Jason J. Herne" <jjherne@linux.vnet.ibm.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Eric Blake <eblake@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 qapi-schema.json          | 25 ++++++++++++++++++++++++-
 target-s390x/cpu_models.c |  4 ++++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index 8d113f8..a102534 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3291,6 +3291,15 @@
 #        migration-safe, but allows tooling to get an insight and work with
 #        model details.
 #
+# Note: When a non-migration-safe CPU model is expanded in static mode, some
+# features enabled by the CPU model may be omitted, because they can't be
+# implemented by a static CPU model definition (e.g. cache info passthrough and
+# PMU passthrough in x86). If you need an accurate representation of the
+# features enabled by a non-migration-safe CPU model, use @full. If you need a
+# static representation that will keep ABI compatibility even when changing QEMU
+# version or machine-type, use @static (but keep in mind that some features may
+# be omitted).
+#
 # Since: 2.8.0
 ##
 { 'enum': 'CpuModelExpansionType',
@@ -3304,10 +3313,24 @@
 #
 # @model: the expanded CpuModelInfo.
 #
+# @migration-safe: the expanded CPU model in @model is a migration-safe
+#                  CPU model. See @CpuDefinitionInfo.migration-safe.
+#                  If expansion type was @static, this is always true.
+#                  (since 2.9)
+#
+# @static: the expanded CPU model in @model is a static CPU model.
+#          See @CpuDefinitionInfo.static. If expansion type was @static,
+#          this is always true.
+#          (since 2.9)
+#
+# query-cpu-model-expansion with static expansion type should always
+# return a static and migration-safe expansion.
+#
 # Since: 2.8.0
 ##
 { 'struct': 'CpuModelExpansionInfo',
-  'data': { 'model': 'CpuModelInfo' } }
+  'data': { 'model': 'CpuModelInfo', 'static': 'bool',
+            'migration-safe': 'bool' } }
 
 
 ##
diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
index 5b66d33..f934add 100644
--- a/target-s390x/cpu_models.c
+++ b/target-s390x/cpu_models.c
@@ -448,6 +448,10 @@ CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type
     /* convert it back to a static representation */
     expansion_info = g_malloc0(sizeof(*expansion_info));
     expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
+
+    /* We always expand to a static and migration-safe CpuModelInfo */
+    expansion_info->q_static = true;
+    expansion_info->migration_safe = true;
     cpu_info_from_model(expansion_info->model, &s390_model, delta_changes);
     return expansion_info;
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 15/17] target-i386: Define static "base" CPU model
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (13 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 14/17] qapi: add static/migration-safe info to query-cpu-model-expansion Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-05 18:18   ` David Hildenbrand
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 16/17] tests: query-cpu-model-test.py test code Eduardo Habkost
                   ` (3 subsequent siblings)
  18 siblings, 1 reply; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel

The query-cpu-model-expand QMP command needs at least one static
model, to allow the "static" expansion mode to be implemented.
Instead of defining static versions of every CPU model, define a
"base" CPU model that has absolutely no feature flag enabled.

Despite having no CPUID data set at all, "-cpu base" is even a
functional CPU:

* It can boot a Slackware Linux 1.01 image with a Linux 0.99.12
  kernel[1].
* It is even possible to boot[2] a modern Fedora x86_64 guest by
  manually enabling the following CPU features:
  -cpu base,+lm,+msr,+pae,+fpu,+cx8,+cmov,+sse,+sse2,+fxsr

[1] http://www.qemu-advent-calendar.org/2014/#day-1
[2] This is what can be seen in the guest:
    [root@localhost ~]# cat /proc/cpuinfo
    processor       : 0
    vendor_id       : unknown
    cpu family      : 0
    model           : 0
    model name      : 00/00
    stepping        : 0
    physical id     : 0
    siblings        : 1
    core id         : 0
    cpu cores       : 1
    apicid          : 0
    initial apicid  : 0
    fpu             : yes
    fpu_exception   : yes
    cpuid level     : 1
    wp              : yes
    flags           : fpu msr pae cx8 cmov fxsr sse sse2 lm nopl
    bugs            :
    bogomips        : 5832.70
    clflush size    : 64
    cache_alignment : 64
    address sizes   : 36 bits physical, 48 bits virtual
    power management:

    [root@localhost ~]# x86info -v -a
    x86info v1.30.  Dave Jones 2001-2011
    Feedback to <davej@redhat.com>.

    No TSC, MHz calculation cannot be performed.
    Unknown vendor (0)
    MP Table:

    Family: 0 Model: 0 Stepping: 0
    CPU Model (x86info's best guess):

    eax in: 0x00000000, eax = 00000001 ebx = 00000000 ecx = 00000000 edx = 00000000
    eax in: 0x00000001, eax = 00000000 ebx = 00000800 ecx = 00000000 edx = 07008161

    eax in: 0x80000000, eax = 80000001 ebx = 00000000 ecx = 00000000 edx = 00000000
    eax in: 0x80000001, eax = 00000000 ebx = 00000000 ecx = 00000000 edx = 20000000

    Feature flags:
     fpu            Onboard FPU
     msr            Model-Specific Registers
     pae            Physical Address Extensions
     cx8            CMPXCHG8 instruction
     cmov           CMOV instruction
     fxsr           FXSAVE and FXRSTOR instructions
     sse            SSE support
     sse2           SSE2 support

    Long NOPs supported: yes

    Address sizes : 0 bits physical, 0 bits virtual
    0MHz processor (estimate).

     running at an estimated 0MHz
    [root@localhost ~]#

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 target-i386/cpu-qom.h |  2 ++
 target-i386/cpu.c     | 24 +++++++++++++++++++++++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 7561891..279f327 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -49,6 +49,7 @@ typedef struct X86CPUDefinition X86CPUDefinition;
  * @cpu_def: CPU model definition
  * @ordering: Ordering on the "-cpu help" CPU model list.
  * @migration_safe: See CpuDefinitionInfo::migration_safe
+ * @static_model: See CpuDefinitionInfo::static
  * @parent_realize: The parent class' realize handler.
  * @parent_reset: The parent class' reset handler.
  *
@@ -64,6 +65,7 @@ typedef struct X86CPUClass {
 
     int ordering;
     bool migration_safe;
+    bool static_model;
 
     /* Optional description of CPU model.
      * If unavailable, cpu_def->model_id is used */
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 3539419..bf4ac09 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2200,6 +2200,7 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
     info->q_typename = g_strdup(object_class_get_name(oc));
     info->migration_safe = cc->migration_safe;
     info->has_migration_safe = true;
+    info->q_static = cc->static_model;
 
     entry = g_malloc0(sizeof(*entry));
     entry->value = info;
@@ -3592,7 +3593,9 @@ static void x86_cpu_initfn(Object *obj)
     object_property_add_alias(obj, "sse4_1", obj, "sse4.1", &error_abort);
     object_property_add_alias(obj, "sse4_2", obj, "sse4.2", &error_abort);
 
-    x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort);
+    if (xcc->cpu_def) {
+        x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort);
+    }
 }
 
 static int64_t x86_cpu_get_arch_id(CPUState *cs)
@@ -3747,6 +3750,24 @@ static const TypeInfo x86_cpu_type_info = {
     .class_init = x86_cpu_common_class_init,
 };
 
+
+/* "base" CPU model, used by query-cpu-model-expansion */
+static void x86_cpu_base_class_init(ObjectClass *oc, void *data)
+{
+    X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+    xcc->static_model = true;
+    xcc->migration_safe = true;
+    xcc->model_description = "base CPU model type with no feature enabled";
+    xcc->ordering = 8;
+}
+
+static const TypeInfo x86_base_cpu_type_info = {
+        .name = X86_CPU_TYPE_NAME("base"),
+        .parent = TYPE_X86_CPU,
+        .class_init = x86_cpu_base_class_init,
+};
+
 static void x86_cpu_register_types(void)
 {
     int i;
@@ -3755,6 +3776,7 @@ static void x86_cpu_register_types(void)
     for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
         x86_register_cpudef_type(&builtin_x86_defs[i]);
     }
+    type_register_static(&x86_base_cpu_type_info);
 #ifdef CONFIG_KVM
     type_register_static(&host_x86_cpu_type_info);
 #endif
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 16/17] tests: query-cpu-model-test.py test code
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (14 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 15/17] target-i386: Define static "base" CPU model Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 17/17] target-i386: Implement query-cpu-model-expansion QMP command Eduardo Habkost
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel

This python script will run query-cpu-model-expansion and related
commands, and sanity-check the results. It seems to work with
qemu-system-s390x, already, but I don't have a host where I can
make sure the test case work for all CPU models.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 tests/query-cpu-model-test.py | 421 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 421 insertions(+)
 create mode 100755 tests/query-cpu-model-test.py

diff --git a/tests/query-cpu-model-test.py b/tests/query-cpu-model-test.py
new file mode 100755
index 0000000..0d99242
--- /dev/null
+++ b/tests/query-cpu-model-test.py
@@ -0,0 +1,421 @@
+#!/usr/bin/env python
+#
+# query-cpu-model-* sanity checks
+#
+#  Copyright (c) 2016 Red Hat Inc
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
+#
+
+import sys, os
+sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'scripts'))
+from qtest import QEMUQtestMachine
+import unittest
+import logging
+
+UNSAFE_FEATURES = {
+    'x86_64': ['pmu', 'host-cache-info'],
+    'i386': ['pmu', 'host-cache-info'],
+}
+
+# Validation of the expanded CPU models will be based on the QOM
+# properties of CPU objects.
+# QOM properties that don't affect guest ABI can be safely ignored
+# when validating the results.
+IGNORE_QOM_PROPS = {
+    # the 'type' property just identifies the QOM class being used
+    # to build the CPU, and shouldn't affect the guest ABI
+    'x86_64': ['type'],
+    'i386': ['type'],
+    # 'static', 'migration-safe', and 'description' are just
+    # information for the user, and don't affect guest ABI
+    's390x': ['type', 'static', 'migration-safe', 'description'],
+}
+
+def toQemuOpts(*args):
+    """Convert arguments to a QemuOpts string, with appropriate escaping
+
+    Each argument can be a single string, or a dictionary.
+    """
+    logging.debug('toQemuOpts(%r)', args)
+    r = []
+    for a in args:
+        if type(a) is dict:
+            for k,v in a.items():
+                if type(v) is bool:
+                    if v:
+                        v = 'on'
+                    else:
+                        v = 'off'
+                v = str(v)
+                a = '%s=%s' % (k, v)
+                r.append(a)
+        else:
+            a = str(a)
+            r.append(a)
+    return ','.join([o.replace(',', ',,') for o in r])
+
+def cpuPath(vm, cpu_index):
+    """Return qom_path for a given CPU, using query-cpus"""
+    cpus = vm.command('query-cpus')
+    return cpus[cpu_index]['qom_path']
+
+def allProps(vm, path):
+    """Return a dictionary containing all properties for a QOM object"""
+    props = vm.command('qom-list', path=path)
+    r = {}
+    for prop in props:
+        pname = prop['name']
+        v = vm.command('qom-get', path=path, property=pname)
+        r[pname] = v
+    return r
+
+def allCpuProps(vm, cpu_index):
+    """Return all properties for a given CPU"""
+    return allProps(vm, cpuPath(vm, cpu_index))
+
+
+class CPUModelTest(unittest.TestCase):
+    longMessage = True
+    maxDiff = None
+
+    def runAndGetProps(self, model):
+        # Helper to run QEMU using a CpuModelInfo struct and get
+        # all CPU properties
+        cpu_opt = toQemuOpts(model['name'], model.get('props', {}))
+        logging.debug('cpu option: %s', cpu_opt)
+
+        vm = QEMUQtestMachine(args=['-machine', 'accel=%s' % (self.accel), '-S',
+                                    '-cpu', cpu_opt], name='qom-fetch',
+                              logging=False)
+        try:
+            vm.launch()
+            props = allCpuProps(vm, 0)
+        finally:
+            vm.shutdown()
+
+        # remove the properties we can ignore
+        for p in IGNORE_QOM_PROPS.get(self.target['arch'], []):
+            del props[p]
+
+        return props
+
+    def tryGetProps(self, model, msg):
+        """Try to get QOM props for model, if runnable"""
+        if model.get('runnable') != False:
+            logging.info("%s: maybe runnable, fetching QOM properties", msg)
+            try:
+                model['qom-props'] = self.runAndGetProps(model['model'])
+            except:
+                if model.get('runnable'):
+                    # explicitly marked as runnable, raise exception
+                    raise
+                logging.info("%s: failed to run VM, ignoring", msg)
+
+    def checkOneExpansion(self, model, type, msg):
+        """Perform one query-cpu-model-expansion operation, validate results
+
+        @model is a CpuModelExpansionInfo struct, with some extra keys:
+        * model['runnable'] will be set to True if the CPU model is
+          runnable on this host
+        * model['qom-props'] will be set to the full list of properties for the
+          CPU, if the model is runnable
+
+        Returns a new CpuModelExpansion struct like @model, with
+        the expanded CPU model data.
+        """
+        logging.info("%s: testing type=%s", msg, type)
+        logging.debug("%s: model: %r", msg, model)
+
+        expanded = self.vm.command('query-cpu-model-expansion',
+                              type=type, model=model['model'])
+
+        logging.debug("%s: expanded: %r", msg, expanded)
+
+        # static expansions are always migration-safe
+        if expanded['static']:
+            self.assertTrue(expanded['migration-safe'])
+
+        # static expansion mode should always result in static/expansion-safe
+        # expansions
+        if type == 'static':
+            self.assertTrue(expanded['static'], msg)
+            self.assertTrue(expanded['migration-safe'], msg)
+            expanded_model = self.cpu_models[expanded['model']['name']]
+            self.assertTrue(expanded_model['static'])
+            self.assertTrue(expanded_model['migration-safe'])
+        else:
+            # full expansion should not clear static and migration-safe info
+            # from # original model:
+            if model['static']:
+                self.assertTrue(expanded['static'], msg)
+            if model['migration-safe']:
+                self.assertTrue(expanded['migration-safe'], msg)
+
+        # migration-safe expansion should never enable migration-unsafe
+        # features:
+        if expanded['migration-safe']:
+            for f in UNSAFE_FEATURES.get(self.target['arch'], []):
+                self.assertFalse(expanded['model']['props'].get(f))
+
+        # Some expansions are known to be precise, and shouldn't lose any
+        # features:
+        # * full expansion
+        # * static expansion of a migration-safe model
+        precise_expansion = (type == 'full' or model['migration-safe'])
+
+        # full expansion should keep all existing explicit properties
+        # in the output:
+        if type == 'full':
+            originalprops = model['model'].get('props', {})
+            fullprops = expanded['model'].get('props', {})
+            for p in originalprops.keys():
+                self.assertEquals(originalprops[p], fullprops.get(p),
+                                  '%s: property %s lost in full expansion'
+                                  % (msg, p))
+
+        expanded['runnable'] = model.get('runnable')
+        self.tryGetProps(expanded, msg)
+        if precise_expansion:
+            self.assertEquals(model.get('qom-props'),
+                              expanded.get('qom-props'),
+                              msg)
+
+        logging.debug("%s: result: %r", msg, expanded)
+        return expanded
+
+    def checkExpansions(self, model, msg):
+        """Performe multiple expansion operations on model, validate results
+
+        @model is a CpuModelExpansionInfo struct, with some extra keys:
+        * model['runnable'] should be set to True if the CPU model is
+          runnable on this host
+        * model['qom-props'] will be set to the full list of properties for
+          the CPU, if the model is runnable
+        """
+        self.tryGetProps(model, msg)
+
+        exp_s = self.checkOneExpansion(model, 'static',
+                                       '%s.static' % (msg))
+        exp_f = self.checkOneExpansion(model, 'full',
+                                       '%s.full' % (msg))
+        exp_ss = self.checkOneExpansion(exp_s, 'static',
+                                        '%s.static.static' % (msg))
+        exp_sf = self.checkOneExpansion(exp_s, 'full',
+                                        '%s.static.full' % (msg))
+        exp_ff = self.checkOneExpansion(exp_f, 'full',
+                                        '%s.full.full' % (msg))
+
+        # static expansion twice should result in the same data:
+        self.assertEquals(exp_s, exp_ss)
+        # full expansion twice should also result in the same data:
+        self.assertEquals(exp_f, exp_ff)
+
+        # migration-safe CPU models have an extra feature:
+        # their static expansion should be equivalent to the full
+        # expansion (as static expansion is also precise)
+        if model.get('migration-safe'):
+            self.assertEquals(exp_sf, exp_f)
+
+    def tryToMakeRunnable(self, model):
+        """Try to create a runnable version of the CPU model, by disabling
+        unavailable features
+        """
+        devprops = self.vm.command('device-list-properties',
+                                   typename=model['typename'])
+        proptypes = dict((p['name'], p['type']) for p in devprops)
+
+        props = {}
+        for f in model['unavailable-features']:
+            # try to disable only boolean properties:
+            if proptypes.get(f) == 'bool':
+                props[f] = False
+
+        if not props:
+            # no property found to be disabled, there's nothing we can do
+            return None
+
+        runnable_model = {
+            'model': {
+                'name':  model['name'],
+                'props': props,
+            },
+            'static': model.get('static', False),
+            'migration-safe': model.get('migration-safe', False),
+        }
+        return runnable_model
+
+    def commandAvailable(self, command):
+        commands = self.vm.command('query-commands')
+        names = set([c['name'] for c in commands])
+        return command in names
+
+    def checkRunnability(self, model):
+        """Check runnability of a given CPU model
+
+        Use unavailable-features field, if available. Otherwise,
+        used query-cpu-model-comparison with "host" CPU model.
+
+        Fills the 'unavailable-features' field based on the results.
+        """
+        if not self.commandAvailable('query-cpu-model-comparison'):
+            logging.debug("query-cpu-model-comparison is not availabble")
+            return
+
+        comparison = self.vm.qmp('query-cpu-model-comparison',
+                                 modela=dict(name=model['name']),
+                                 modelb=dict(name='host'))
+        logging.info("comparison result: %r", comparison)
+        if not comparison.has_key('return'):
+            logging.debug("query-cpu-model-comparison failed")
+            return
+
+        comparison = comparison['return']
+
+        # if unavailable-features was already set, it must match the
+        # results of query-cpu-model-comparison
+        unavailable_features = model.get('unavailable-features')
+        if unavailable_features is not None:
+            if len(unavailable_features) == 0:
+                self.assertTrue(comparison['result'] in ['identical', 'subset'])
+            else:
+                self.assertIn(comparison['result'],
+                              ['superset', 'incompatible'])
+                self.assertEquals(comparison['responsible-properties'],
+                                  unavailable_features)
+        model['unavailable-features'] = comparison['responsible-properties']
+
+    def checkOneCPUModel(self, m):
+        """Run multiple query-cpu-model-expansion checks
+
+        * Test simple CPU model name
+        * Test CPU model with unsafe features enabled
+        * Test CPU model with unavailable features disabled,
+          if unavailable-features is set
+        """
+        msg = '%s.%s' % (self.accel, m['name'])
+        logging.info("%s: checkOneCPUModel", msg)
+
+
+        # some validations on query-cpu-definitions output:
+        if m.get('static'):
+            self.assertTrue(m['migration-safe'])
+
+        self.checkRunnability(m)
+
+        # simulate return value of query-cpu-expansion for the model:
+        model = {
+            'model': {
+                'name': m['name'],
+            },
+            'static': m.get('static', False),
+            'migration-safe': m.get('migration-safe', False),
+        }
+        if m.has_key('unavailable-features'):
+            model['runnable'] = len(m['unavailable-features']) == 0
+        self.checkExpansions(model, msg)
+
+        # explicit test to check we do the right thing when
+        # unsafe features are enabled explicitly:
+        for f in UNSAFE_FEATURES.get(self.target['arch'], []):
+            # enabled:
+            unsafe_model = {
+                'model': {
+                    'name':  m['name'],
+                    'props': { f: True },
+                },
+                'migration-safe': False,
+                'static': False,
+                'runnable': model.get('runnable'),
+            }
+            self.checkExpansions(unsafe_model, msg + ".unsafe." + f)
+
+        # Check if CPU model can be made migration-safe
+        # if we disable all known migration-unsafe features:
+        if not m.get('migration-safe'):
+            # enabled:
+            safe_model = {
+                'model': {
+                    'name':  m['name'],
+                    'props': {}
+                },
+                'migration-safe': True,
+                'static': m.get('static', False),
+                'runnable': model.get('runnable'),
+            }
+            for f in UNSAFE_FEATURES.get(self.target['arch'], []):
+                safe_model['model']['props'][f] = False
+            self.checkExpansions(safe_model, msg + ".safe")
+
+        # if not runnable, try to create a runnable version of the CPU model:
+        if m.get('unavailable-features'):
+            runnable_model = self.tryToMakeRunnable(m)
+            if runnable_model:
+                self.checkExpansions(runnable_model, msg + ".runnable")
+
+    @classmethod
+    def setUpClass(klass):
+        vm = QEMUQtestMachine(args=['-S'], logging=False)
+        try:
+            vm.launch()
+            klass.kvm = vm.command('query-kvm')
+            klass.target = vm.command('query-target')
+        finally:
+            vm.shutdown()
+
+    def setUp(self):
+        self.vm = None
+
+    def tearDown(self):
+        if self.vm:
+            self.vm.shutdown()
+
+    def checkAllCPUModels(self):
+        self.vm = QEMUQtestMachine(args=['-S', '-machine',
+                                    'accel=%s' % (self.accel)],
+                              logging=False)
+        self.vm.launch()
+        self.cpu_models = dict((m['name'], m) for m in
+                               self.vm.command('query-cpu-definitions'))
+
+        if self.accel.split(':')[0] == 'kvm':
+            if not self.vm.command('query-kvm')['enabled']:
+                self.skipTest("Failed to enable KVM")
+
+        for m in self.cpu_models.values():
+            self.checkOneCPUModel(m)
+
+    def testTCGModels(self):
+        self.accel = 'tcg'
+        self.checkAllCPUModels()
+
+    def testKVMModels(self):
+        # use kvm:tcg so QEMU won't refuse to start if KVM is unavailable
+        self.accel = 'kvm:tcg'
+        # test KVM also, if present
+        if not self.kvm['present']:
+            self.skipTest("KVM is not present")
+
+        self.checkAllCPUModels()
+
+
+
+if __name__ == '__main__':
+    if os.getenv('QTEST_LOG_LEVEL'):
+        logging.basicConfig(level=int(os.getenv('QTEST_LOG_LEVEL')))
+    elif '--verbose' in sys.argv:
+        logging.basicConfig(level=logging.INFO)
+    else:
+        logging.basicConfig(level=logging.WARN)
+    unittest.main()
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [Qemu-devel] [PATCH for-2.9 17/17] target-i386: Implement query-cpu-model-expansion QMP command
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (15 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 16/17] tests: query-cpu-model-test.py test code Eduardo Habkost
@ 2016-12-02 21:18 ` Eduardo Habkost
  2016-12-13 10:16   ` Markus Armbruster
  2016-12-05  9:09 ` [Qemu-devel] [libvirt] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion no-reply
  2016-12-05 15:15 ` [Qemu-devel] " David Hildenbrand
  18 siblings, 1 reply; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-02 21:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: libvir-list, Jiri Denemark

Implement query-cpu-model-expansion for target-i386.

The code needs to be careful to handle non-migration-safe
features ("pmu" and "host-cache-info") according to the expansion
type.

Cc: libvir-list@redhat.com
Cc: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 tests/Makefile.include |   3 +
 monitor.c              |   4 +-
 target-i386/cpu.c      | 195 ++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 200 insertions(+), 2 deletions(-)

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 63c4347..c7bbfca 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -251,6 +251,9 @@ check-qtest-x86_64-y += $(check-qtest-i386-y)
 gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
 gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
 
+check-simpleqtest-x86_64-y += $(SRC_PATH)/tests/query-cpu-model-test.py
+check-simpleqtest-i386-y += $(SRC_PATH)/tests/query-cpu-model-test.py
+
 check-qtest-alpha-y = tests/boot-serial-test$(EXESUF)
 
 check-qtest-mips-y = tests/endianness-test$(EXESUF)
diff --git a/monitor.c b/monitor.c
index 0841d43..90c12b3 100644
--- a/monitor.c
+++ b/monitor.c
@@ -983,8 +983,10 @@ static void qmp_unregister_commands_hack(void)
 #ifndef TARGET_ARM
     qmp_unregister_command("query-gic-capabilities");
 #endif
-#if !defined(TARGET_S390X)
+#if !defined(TARGET_S390X) && !defined(TARGET_I386)
     qmp_unregister_command("query-cpu-model-expansion");
+#endif
+#if !defined(TARGET_S390X)
     qmp_unregister_command("query-cpu-model-baseline");
     qmp_unregister_command("query-cpu-model-comparison");
 #endif
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index bf4ac09..198014a 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -29,10 +29,14 @@
 #include "qemu/option.h"
 #include "qemu/config-file.h"
 #include "qapi/qmp/qerror.h"
+#include "qapi/qmp/qstring.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qbool.h"
 
 #include "qapi-types.h"
 #include "qapi-visit.h"
 #include "qapi/visitor.h"
+#include "qom/qom-qobject.h"
 #include "sysemu/arch_init.h"
 
 #if defined(CONFIG_KVM)
@@ -2259,7 +2263,7 @@ static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
     }
 }
 
-/* Load data from X86CPUDefinition
+/* Load data from X86CPUDefinition into a X86CPU object
  */
 static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
 {
@@ -2268,6 +2272,11 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
     char host_vendor[CPUID_VENDOR_SZ + 1];
     FeatureWord w;
 
+    /*NOTE: any property set by this function should be returned by
+     * x86_cpu_to_dict(), so CPU model data returned by
+     * query-cpu-model-expansion is always complete.
+     */
+
     /* CPU models only set _minimum_ values for level/xlevel: */
     object_property_set_int(OBJECT(cpu), def->level, "min-level", errp);
     object_property_set_int(OBJECT(cpu), def->xlevel, "min-xlevel", errp);
@@ -2312,6 +2321,190 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
 
 }
 
+/* Convert CPU model data from X86CPU object to a property dictionary
+ * that can recreate exactly the same CPU model.
+ *
+ * This function does the opposite of x86_cpu_load_def(). Any
+ * property changed by x86_cpu_load_def() or instance_init
+ * methods should be returned by this function too.
+ */
+static void x86_cpu_to_dict(X86CPU *cpu, QDict *props, Error **errp)
+{
+    Object *obj = OBJECT(cpu);
+    FeatureWord w;
+    PropValue *pv;
+
+    /* This code could simply iterate over all writeable properties in the
+     * CPU object, and return all of them. But then the aliases properties
+     * would be returned as well. Returning only the known features
+     * is more reliable.
+     */
+    qdict_put_obj(props, "min-level",
+                  object_property_get_qobject(obj, "min-level", errp));
+    qdict_put_obj(props, "min-xlevel",
+                  object_property_get_qobject(obj, "min-xlevel", errp));
+
+    qdict_put_obj(props, "family",
+                  object_property_get_qobject(obj, "family", errp));
+    qdict_put_obj(props, "model",
+                  object_property_get_qobject(obj, "model", errp));
+    qdict_put_obj(props, "stepping",
+                  object_property_get_qobject(obj, "stepping", errp));
+    qdict_put_obj(props, "model-id",
+                  object_property_get_qobject(obj, "model-id", errp));
+
+    for (w = 0; w < FEATURE_WORDS; w++) {
+        FeatureWordInfo *fi = &feature_word_info[w];
+        int bit;
+        for (bit = 0; bit < 32; bit++) {
+            if (!fi->feat_names[bit]) {
+                continue;
+            }
+            qdict_put_obj(props, fi->feat_names[bit],
+                          object_property_get_qobject(obj, fi->feat_names[bit],
+                                                      errp));
+        }
+    }
+
+    for (pv = kvm_default_props; pv->prop; pv++) {
+        qdict_put_obj(props, pv->prop,
+                      object_property_get_qobject(obj, pv->prop, errp));
+    }
+    for (pv = tcg_default_props; pv->prop; pv++) {
+        qdict_put_obj(props, pv->prop,
+                      object_property_get_qobject(obj, pv->prop, errp));
+    }
+
+    qdict_put_obj(props, "vendor",
+                  object_property_get_qobject(obj, "vendor", errp));
+
+    /* Set by "host": */
+    qdict_put_obj(props, "lmce",
+                  object_property_get_qobject(obj, "lmce", errp));
+    qdict_put_obj(props, "pmu",
+                  object_property_get_qobject(obj, "pmu", errp));
+
+
+    /* Other properties configurable by the user: */
+    qdict_put_obj(props, "host-cache-info",
+                  object_property_get_qobject(obj, "host-cache-info", errp));
+}
+
+static void object_apply_props(Object *obj, QDict *props, Error **errp)
+{
+    const QDictEntry *prop;
+    Error *err = NULL;
+
+    for (prop = qdict_first(props); prop; prop = qdict_next(props, prop)) {
+        object_property_set_qobject(obj, qdict_entry_value(prop),
+                                         qdict_entry_key(prop), &err);
+        if (err) {
+            break;
+        }
+    }
+
+    error_propagate(errp, err);
+}
+
+static X86CPU *x86_cpu_from_model(CpuModelInfo *model, Error **errp)
+{
+    X86CPU *xc = NULL;
+    X86CPUClass *xcc;
+    Error *err = NULL;
+
+    xcc = X86_CPU_CLASS(cpu_class_by_name(TYPE_X86_CPU, model->name));
+    if (xcc == NULL) {
+        error_setg(&err, "CPU model '%s' not found", model->name);
+        goto out;
+    }
+
+    xc = X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc))));
+    if (model->has_props) {
+        QDict *d = qobject_to_qdict(model->props);
+        if (!d) {
+            error_setg(&err, "model.props must be a dictionary");
+            goto out;
+        }
+        object_apply_props(OBJECT(xc), d, &err);
+        if (err) {
+            goto out;
+        }
+    }
+
+    x86_cpu_expand_features(xc, &err);
+    if (err) {
+        goto out;
+    }
+
+out:
+    if (err) {
+        error_propagate(errp, err);
+        object_unref(OBJECT(xc));
+        xc = NULL;
+    }
+    return xc;
+}
+
+CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
+                                                      CpuModelInfo *model,
+                                                      Error **errp)
+{
+    X86CPU *xc = NULL;
+    Error *err = NULL;
+    CpuModelExpansionInfo *ret = g_new0(CpuModelExpansionInfo, 1);
+    QDict *props;
+
+    xc = x86_cpu_from_model(model, &err);
+    if (err) {
+        goto out;
+    }
+
+    /* We currently always do full expansion */
+    ret->model = g_new0(CpuModelInfo, 1);
+    ret->model->name = g_strdup("base"); /* the only static model */
+    props = qdict_new();
+    ret->model->props = QOBJECT(props);
+    ret->model->has_props = true;
+    x86_cpu_to_dict(xc, props, &err);
+
+    /* Some features (pmu, host-cache-info) are not migration-safe,
+     * and are handled differently depending on expansion type:
+     */
+    if (type ==  CPU_MODEL_EXPANSION_TYPE_STATIC) {
+        /* static expansion force migration-unsafe features off: */
+        ret->q_static = ret->migration_safe = true;
+        qdict_del(props, "pmu");
+        qdict_del(props, "host-cache-info");
+    } else if (type == CPU_MODEL_EXPANSION_TYPE_FULL) {
+        QObject *o;
+        /* full expansion clear the static/migration-safe flags
+         * to indicate migration-unsafe features are on:
+         */
+        ret->q_static = true;
+        ret->migration_safe = true;
+
+        o = qdict_get(props, "pmu");
+        if (o && qbool_get_bool(qobject_to_qbool(o))) {
+            ret->q_static = ret->migration_safe = false;
+        }
+        o = qdict_get(props, "host-cache-info");
+        if (o && qbool_get_bool(qobject_to_qbool(o))) {
+            ret->q_static = ret->migration_safe = false;
+        }
+    } else {
+        error_setg(&err, "The requested expansion type is not supported.");
+    }
+
+out:
+    object_unref(OBJECT(xc));
+    if (err) {
+        error_propagate(errp, err);
+        qapi_free_CpuModelExpansionInfo(ret);
+        ret = NULL;
+    }
+    return ret;
+}
+
 X86CPU *cpu_x86_init(const char *cpu_model)
 {
     return X86_CPU(cpu_generic_init(TYPE_X86_CPU, cpu_model));
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [libvirt] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (16 preceding siblings ...)
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 17/17] target-i386: Implement query-cpu-model-expansion QMP command Eduardo Habkost
@ 2016-12-05  9:09 ` no-reply
  2016-12-05 15:15 ` [Qemu-devel] " David Hildenbrand
  18 siblings, 0 replies; 35+ messages in thread
From: no-reply @ 2016-12-05  9:09 UTC (permalink / raw)
  To: ehabkost
  Cc: famz, qemu-devel, david, libvir-list, borntraeger, jjherne,
	cornelia.huck, imammedo, jdenemar, rth

Hi,

Your series failed automatic build test. Please find the testing commands and
their output below. If you have docker installed, you can probably reproduce it
locally.

Subject: [libvirt] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion
Type: series
Message-id: 1480713496-11213-1-git-send-email-ehabkost@redhat.com

=== TEST SCRIPT BEGIN ===
#!/bin/bash
set -e
git submodule update --init dtc
# Let docker tests dump environment info
export SHOW_ENV=1
export J=16
make docker-test-quick@centos6
make docker-test-mingw@fedora
make docker-test-build@min-glib
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
4d1059a target-i386: Implement query-cpu-model-expansion QMP command
dd455c4 tests: query-cpu-model-test.py test code
39060f6 target-i386: Define static "base" CPU model
55852af qapi: add static/migration-safe info to query-cpu-model-expansion
9d8b30c cpu: Support comma escaping when parsing -cpu
cb7c769 target-i386: Return migration-safe field on query-cpu-definitions
d2dc888 target-i386: Remove AMD feature flag aliases from Opteron models
8455bc9 target-i386: Allow short strings to be used as vendor ID
2f2feee target-i386: Move "host" properties to base class
0d425f6 target-i386: Support "-cpu host" on TCG too
a0a736b target-i386: Reorganize and document CPUID initialization steps
8db25d9 tests: Add rules to non-gtester qtest test cases
30bd85f qtest.py: Make 'binary' parameter optional
1faa31f qtest.py: make logging optional
e0fd704 qtest.py: Support QTEST_LOG environment variable
d3eda86 qemu.py: Make logging optional
008898d qmp: Report QOM type name on query-cpu-definitions

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '65cc4d2748a2c2e6f27f1cf39e07a5dbabd80ebf'
  BUILD   centos6
make[1]: Entering directory `/var/tmp/patchew-tester-tmp-vn6v5_5_/src'
  ARCHIVE qemu.tgz
  ARCHIVE dtc.tgz
  COPY    RUNNER
    RUN test-quick in qemu:centos6 
Packages installed:
SDL-devel-1.2.14-7.el6_7.1.x86_64
ccache-3.1.6-2.el6.x86_64
epel-release-6-8.noarch
gcc-4.4.7-17.el6.x86_64
git-1.7.1-4.el6_7.1.x86_64
glib2-devel-2.28.8-5.el6.x86_64
libfdt-devel-1.4.0-1.el6.x86_64
make-3.81-23.el6.x86_64
package g++ is not installed
pixman-devel-0.32.8-1.el6.x86_64
tar-1.23-15.el6_8.x86_64
zlib-devel-1.2.3-29.el6.x86_64

Environment variables:
PACKAGES=libfdt-devel ccache     tar git make gcc g++     zlib-devel glib2-devel SDL-devel pixman-devel     epel-release
HOSTNAME=716135605a0c
TERM=xterm
MAKEFLAGS= -j16
HISTSIZE=1000
J=16
USER=root
CCACHE_DIR=/var/tmp/ccache
EXTRA_CONFIGURE_OPTS=
V=
SHOW_ENV=1
MAIL=/var/spool/mail/root
PATH=/usr/lib/ccache:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
LANG=en_US.UTF-8
TARGET_LIST=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
TEST_DIR=/tmp/qemu-test
LOGNAME=root
LESSOPEN=||/usr/bin/lesspipe.sh %s
FEATURES= dtc
DEBUG=
G_BROKEN_FILENAMES=1
CCACHE_HASHDIR=
_=/usr/bin/env

Configure options:
--enable-werror --target-list=x86_64-softmmu,aarch64-softmmu --prefix=/var/tmp/qemu-build/install
No C++ compiler available; disabling C++ specific optional code
Install prefix    /var/tmp/qemu-build/install
BIOS directory    /var/tmp/qemu-build/install/share/qemu
binary directory  /var/tmp/qemu-build/install/bin
library directory /var/tmp/qemu-build/install/lib
module directory  /var/tmp/qemu-build/install/lib/qemu
libexec directory /var/tmp/qemu-build/install/libexec
include directory /var/tmp/qemu-build/install/include
config directory  /var/tmp/qemu-build/install/etc
local state directory   /var/tmp/qemu-build/install/var
Manual directory  /var/tmp/qemu-build/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path       /tmp/qemu-test/src
C compiler        cc
Host C compiler   cc
C++ compiler      
Objective-C compiler cc
ARFLAGS           rv
CFLAGS            -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g 
QEMU_CFLAGS       -I/usr/include/pixman-1    -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include   -fPIE -DPIE -m64 -mcx16 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv  -Wendif-labels -Wmissing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-all
LDFLAGS           -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g 
make              make
install           install
python            python -B
smbd              /usr/sbin/smbd
module support    no
host CPU          x86_64
host big endian   no
target list       x86_64-softmmu aarch64-softmmu
tcg debug enabled no
gprof enabled     no
sparse enabled    no
strip binaries    yes
profiler          no
static build      no
pixman            system
SDL support       yes (1.2.14)
GTK support       no 
GTK GL support    no
VTE support       no 
TLS priority      NORMAL
GNUTLS support    no
GNUTLS rnd        no
libgcrypt         no
libgcrypt kdf     no
nettle            no 
nettle kdf        no
libtasn1          no
curses support    no
virgl support     no
curl support      no
mingw32 support   no
Audio drivers     oss
Block whitelist (rw) 
Block whitelist (ro) 
VirtFS support    no
VNC support       yes
VNC SASL support  no
VNC JPEG support  no
VNC PNG support   no
xen support       no
brlapi support    no
bluez  support    no
Documentation     no
PIE               yes
vde support       no
netmap support    no
Linux AIO support no
ATTR/XATTR support yes
Install blobs     yes
KVM support       yes
COLO support      yes
RDMA support      no
TCG interpreter   no
fdt support       yes
preadv support    yes
fdatasync         yes
madvise           yes
posix_madvise     yes
libcap-ng support no
vhost-net support yes
vhost-scsi support yes
vhost-vsock support yes
Trace backends    log
spice support     no 
rbd support       no
xfsctl support    no
smartcard support no
libusb            no
usb net redir     no
OpenGL support    no
OpenGL dmabufs    no
libiscsi support  no
libnfs support    no
build guest agent yes
QGA VSS support   no
QGA w32 disk info no
QGA MSI support   no
seccomp support   no
coroutine backend ucontext
coroutine pool    yes
debug stack usage no
GlusterFS support no
Archipelago support no
gcov              gcov
gcov enabled      no
TPM support       yes
libssh2 support   no
TPM passthrough   yes
QOM debugging     yes
lzo support       no
snappy support    no
bzip2 support     no
NUMA host support no
tcmalloc support  no
jemalloc support  no
avx2 optimization no
replication support yes
  GEN     x86_64-softmmu/config-devices.mak.tmp
  GEN     aarch64-softmmu/config-devices.mak.tmp
  GEN     config-host.h
  GEN     qemu-options.def
  GEN     qmp-commands.h
  GEN     qapi-visit.h
  GEN     qapi-types.h
  GEN     qapi-event.h
  GEN     qmp-introspect.h
  GEN     module_block.h
  GEN     x86_64-softmmu/config-devices.mak
  GEN     aarch64-softmmu/config-devices.mak
  GEN     tests/test-qapi-types.h
  GEN     tests/test-qapi-visit.h
  GEN     tests/test-qmp-commands.h
  GEN     tests/test-qapi-event.h
  GEN     tests/test-qmp-introspect.h
  GEN     trace/generated-tracers.h
  GEN     trace/generated-tcg-tracers.h
  GEN     trace/generated-helpers-wrappers.h
  GEN     trace/generated-helpers.h
  GEN     config-all-devices.mak
  CC      tests/qemu-iotests/socket_scm_helper.o
  GEN     qga/qapi-generated/qga-qmp-commands.h
  GEN     qga/qapi-generated/qga-qapi-types.h
  GEN     qga/qapi-generated/qga-qapi-visit.h
  GEN     qga/qapi-generated/qga-qapi-types.c
  GEN     qga/qapi-generated/qga-qapi-visit.c
  GEN     qga/qapi-generated/qga-qmp-marshal.c
  GEN     qmp-introspect.c
  GEN     qapi-types.c
  GEN     qapi-visit.c
  GEN     qapi-event.c
  CC      qapi/qapi-visit-core.o
  CC      qapi/qapi-dealloc-visitor.o
  CC      qapi/qobject-input-visitor.o
  CC      qapi/qobject-output-visitor.o
  CC      qapi/qmp-registry.o
  CC      qapi/qmp-dispatch.o
  CC      qapi/string-input-visitor.o
  CC      qapi/string-output-visitor.o
  CC      qapi/opts-visitor.o
  CC      qapi/qapi-clone-visitor.o
  CC      qapi/qmp-event.o
  CC      qapi/qapi-util.o
  CC      qobject/qnull.o
  CC      qobject/qint.o
  CC      qobject/qstring.o
  CC      qobject/qdict.o
  CC      qobject/qlist.o
  CC      qobject/qfloat.o
  CC      qobject/qbool.o
  CC      qobject/qjson.o
  CC      qobject/qobject.o
  CC      qobject/json-lexer.o
  CC      qobject/json-streamer.o
  CC      qobject/json-parser.o
  GEN     trace/generated-tracers.c
  CC      trace/control.o
  CC      trace/qmp.o
  CC      util/osdep.o
  CC      util/cutils.o
  CC      util/unicode.o
  CC      util/qemu-timer-common.o
  CC      util/bufferiszero.o
  CC      util/compatfd.o
  CC      util/event_notifier-posix.o
  CC      util/mmap-alloc.o
  CC      util/oslib-posix.o
  CC      util/qemu-openpty.o
  CC      util/qemu-thread-posix.o
  CC      util/memfd.o
  CC      util/envlist.o
  CC      util/path.o
  CC      util/module.o
  CC      util/bitmap.o
  CC      util/bitops.o
  CC      util/hbitmap.o
  CC      util/fifo8.o
  CC      util/acl.o
  CC      util/error.o
  CC      util/qemu-error.o
  CC      util/id.o
  CC      util/iov.o
  CC      util/qemu-config.o
  CC      util/qemu-sockets.o
  CC      util/uri.o
  CC      util/notify.o
  CC      util/qemu-option.o
  CC      util/qemu-progress.o
  CC      util/hexdump.o
  CC      util/crc32c.o
  CC      util/uuid.o
  CC      util/throttle.o
  CC      util/getauxval.o
  CC      util/readline.o
  CC      util/rcu.o
  CC      util/qemu-coroutine.o
  CC      util/qemu-coroutine-lock.o
  CC      util/qemu-coroutine-io.o
  CC      util/qemu-coroutine-sleep.o
  CC      util/coroutine-ucontext.o
  CC      util/buffer.o
  CC      util/timed-average.o
  CC      util/base64.o
  CC      util/log.o
  CC      util/qdist.o
  CC      util/qht.o
  CC      util/range.o
  CC      crypto/pbkdf-stub.o
  CC      stubs/arch-query-cpu-def.o
  CC      stubs/arch-query-cpu-model-expansion.o
  CC      stubs/arch-query-cpu-model-comparison.o
  CC      stubs/arch-query-cpu-model-baseline.o
  CC      stubs/bdrv-next-monitor-owned.o
  CC      stubs/blk-commit-all.o
  CC      stubs/blockdev-close-all-bdrv-states.o
  CC      stubs/clock-warp.o
  CC      stubs/cpu-get-clock.o
  CC      stubs/cpu-get-icount.o
  CC      stubs/dump.o
  CC      stubs/error-printf.o
  CC      stubs/fdset-add-fd.o
  CC      stubs/fdset-find-fd.o
  CC      stubs/fdset-get-fd.o
  CC      stubs/fdset-remove-fd.o
  CC      stubs/get-next-serial.o
  CC      stubs/gdbstub.o
  CC      stubs/get-fd.o
  CC      stubs/get-vm-name.o
  CC      stubs/iothread.o
  CC      stubs/iothread-lock.o
  CC      stubs/is-daemonized.o
  CC      stubs/machine-init-done.o
  CC      stubs/migr-blocker.o
  CC      stubs/mon-is-qmp.o
  CC      stubs/monitor-init.o
  CC      stubs/notify-event.o
  CC      stubs/qtest.o
  CC      stubs/replay.o
  CC      stubs/replay-user.o
  CC      stubs/reset.o
  CC      stubs/runstate-check.o
  CC      stubs/set-fd-handler.o
  CC      stubs/slirp.o
  CC      stubs/sysbus.o
  CC      stubs/trace-control.o
  CC      stubs/uuid.o
  CC      stubs/vm-stop.o
  CC      stubs/vmstate.o
  CC      stubs/cpus.o
  CC      stubs/kvm.o
  CC      stubs/qmp_pc_dimm_device_list.o
  CC      stubs/target-monitor-defs.o
  CC      stubs/target-get-monitor-def.o
  CC      stubs/vhost.o
  CC      stubs/iohandler.o
  CC      stubs/smbios_type_38.o
  CC      stubs/ipmi.o
  CC      stubs/pc_madt_cpu_entry.o
  CC      stubs/migration-colo.o
  CC      contrib/ivshmem-client/ivshmem-client.o
  CC      contrib/ivshmem-client/main.o
  CC      contrib/ivshmem-server/ivshmem-server.o
  CC      contrib/ivshmem-server/main.o
  CC      qemu-nbd.o
  CC      async.o
  CC      thread-pool.o
  CC      block.o
  CC      blockjob.o
  CC      main-loop.o
  CC      iohandler.o
  CC      qemu-timer.o
  CC      aio-posix.o
  CC      qemu-io-cmds.o
  CC      replication.o
  CC      block/raw_bsd.o
  CC      block/qcow.o
  CC      block/vdi.o
  CC      block/vmdk.o
  CC      block/cloop.o
  CC      block/bochs.o
  CC      block/vpc.o
  CC      block/vvfat.o
  CC      block/dmg.o
  CC      block/qcow2.o
  CC      block/qcow2-refcount.o
  CC      block/qcow2-cluster.o
  CC      block/qcow2-snapshot.o
  CC      block/qcow2-cache.o
  CC      block/qed.o
  CC      block/qed-gencb.o
  CC      block/qed-l2-cache.o
  CC      block/qed-table.o
  CC      block/qed-cluster.o
  CC      block/qed-check.o
  CC      block/vhdx.o
  CC      block/vhdx-endian.o
  CC      block/vhdx-log.o
  CC      block/quorum.o
  CC      block/parallels.o
  CC      block/blkdebug.o
  CC      block/blkverify.o
  CC      block/blkreplay.o
  CC      block/block-backend.o
  CC      block/snapshot.o
  CC      block/qapi.o
  CC      block/raw-posix.o
  CC      block/null.o
  CC      block/mirror.o
  CC      block/commit.o
  CC      block/io.o
  CC      block/throttle-groups.o
  CC      block/nbd.o
  CC      block/nbd-client.o
  CC      block/sheepdog.o
  CC      block/accounting.o
  CC      block/dirty-bitmap.o
  CC      block/write-threshold.o
  CC      block/backup.o
  CC      block/replication.o
  CC      block/crypto.o
  CC      nbd/server.o
  CC      nbd/client.o
  CC      nbd/common.o
  CC      crypto/init.o
  CC      crypto/hash.o
  CC      crypto/hash-glib.o
  CC      crypto/aes.o
  CC      crypto/desrfb.o
  CC      crypto/cipher.o
  CC      crypto/tlscreds.o
  CC      crypto/tlscredsanon.o
  CC      crypto/tlscredsx509.o
  CC      crypto/tlssession.o
  CC      crypto/secret.o
  CC      crypto/random-platform.o
  CC      crypto/pbkdf.o
  CC      crypto/ivgen.o
  CC      crypto/ivgen-essiv.o
  CC      crypto/ivgen-plain.o
  CC      crypto/ivgen-plain64.o
  CC      crypto/afsplit.o
  CC      crypto/xts.o
  CC      crypto/block.o
  CC      crypto/block-qcow.o
  CC      crypto/block-luks.o
  CC      io/channel.o
  CC      io/channel-buffer.o
  CC      io/channel-command.o
  CC      io/channel-file.o
  CC      io/channel-socket.o
  CC      io/channel-tls.o
  CC      io/channel-watch.o
  CC      io/channel-websock.o
  CC      io/channel-util.o
  CC      io/task.o
  CC      qom/object.o
  CC      qom/container.o
  CC      qom/qom-qobject.o
  CC      qom/object_interfaces.o
  GEN     qemu-img-cmds.h
  CC      qemu-io.o
  CC      qemu-bridge-helper.o
  CC      blockdev.o
  CC      blockdev-nbd.o
  CC      iothread.o
  CC      qdev-monitor.o
  CC      device-hotplug.o
  CC      os-posix.o
  CC      qemu-char.o
  CC      page_cache.o
  CC      accel.o
  CC      bt-host.o
  CC      bt-vhci.o
  CC      dma-helpers.o
  CC      vl.o
  CC      tpm.o
  CC      device_tree.o
  GEN     qmp-marshal.c
  CC      qmp.o
  CC      hmp.o
  CC      cpus-common.o
  CC      audio/audio.o
  CC      audio/noaudio.o
  CC      audio/wavaudio.o
  CC      audio/sdlaudio.o
  CC      audio/mixeng.o
  CC      audio/ossaudio.o
  CC      audio/wavcapture.o
  CC      backends/rng.o
  CC      backends/rng-egd.o
  CC      backends/rng-random.o
  CC      backends/msmouse.o
  CC      backends/testdev.o
  CC      backends/tpm.o
  CC      backends/hostmem.o
  CC      backends/hostmem-ram.o
  CC      backends/hostmem-file.o
  CC      backends/cryptodev.o
  CC      backends/cryptodev-builtin.o
  CC      block/stream.o
  CC      disas/arm.o
  CC      disas/i386.o
  CC      fsdev/qemu-fsdev-dummy.o
  CC      fsdev/qemu-fsdev-opts.o
  CC      hw/acpi/core.o
  CC      hw/acpi/piix4.o
  CC      hw/acpi/pcihp.o
  CC      hw/acpi/ich9.o
  CC      hw/acpi/tco.o
  CC      hw/acpi/cpu_hotplug.o
  CC      hw/acpi/memory_hotplug.o
  CC      hw/acpi/memory_hotplug_acpi_table.o
  CC      hw/acpi/cpu.o
  CC      hw/acpi/nvdimm.o
  CC      hw/acpi/acpi_interface.o
  CC      hw/acpi/bios-linker-loader.o
  CC      hw/acpi/aml-build.o
  CC      hw/acpi/ipmi.o
  CC      hw/audio/sb16.o
  CC      hw/audio/es1370.o
  CC      hw/audio/ac97.o
  CC      hw/audio/fmopl.o
  CC      hw/audio/adlib.o
  CC      hw/audio/gusemu_hal.o
  CC      hw/audio/gus.o
  CC      hw/audio/gusemu_mixer.o
  CC      hw/audio/cs4231a.o
  CC      hw/audio/intel-hda.o
  CC      hw/audio/hda-codec.o
  CC      hw/audio/pcspk.o
  CC      hw/audio/wm8750.o
  CC      hw/audio/pl041.o
  CC      hw/audio/lm4549.o
  CC      hw/audio/marvell_88w8618.o
  CC      hw/block/block.o
  CC      hw/block/cdrom.o
  CC      hw/block/hd-geometry.o
  CC      hw/block/fdc.o
  CC      hw/block/m25p80.o
  CC      hw/block/nand.o
  CC      hw/block/pflash_cfi01.o
  CC      hw/block/pflash_cfi02.o
  CC      hw/block/ecc.o
  CC      hw/block/onenand.o
  CC      hw/block/nvme.o
  CC      hw/bt/core.o
  CC      hw/bt/l2cap.o
  CC      hw/bt/sdp.o
  CC      hw/bt/hid.o
  CC      hw/bt/hci.o
  CC      hw/bt/hci-csr.o
  CC      hw/char/ipoctal232.o
  CC      hw/char/parallel.o
  CC      hw/char/pl011.o
  CC      hw/char/serial.o
  CC      hw/char/serial-isa.o
  CC      hw/char/serial-pci.o
  CC      hw/char/virtio-console.o
  CC      hw/char/cadence_uart.o
  CC      hw/char/debugcon.o
  CC      hw/char/imx_serial.o
  CC      hw/core/qdev.o
  CC      hw/core/qdev-properties.o
  CC      hw/core/bus.o
  CC      hw/core/fw-path-provider.o
  CC      hw/core/irq.o
  CC      hw/core/hotplug.o
  CC      hw/core/ptimer.o
  CC      hw/core/sysbus.o
  CC      hw/core/machine.o
  CC      hw/core/null-machine.o
  CC      hw/core/loader.o
  CC      hw/core/qdev-properties-system.o
  CC      hw/core/register.o
  CC      hw/core/or-irq.o
  CC      hw/core/platform-bus.o
  CC      hw/display/ads7846.o
  CC      hw/display/cirrus_vga.o
  CC      hw/display/pl110.o
  CC      hw/display/ssd0303.o
  CC      hw/display/ssd0323.o
  CC      hw/display/vga-pci.o
  CC      hw/display/vga-isa.o
  CC      hw/display/vmware_vga.o
  CC      hw/display/blizzard.o
  CC      hw/display/exynos4210_fimd.o
  CC      hw/display/framebuffer.o
  CC      hw/display/tc6393xb.o
  CC      hw/dma/pl080.o
  CC      hw/dma/pl330.o
  CC      hw/dma/i8257.o
  CC      hw/dma/xlnx-zynq-devcfg.o
  CC      hw/gpio/max7310.o
  CC      hw/gpio/pl061.o
  CC      hw/gpio/zaurus.o
  CC      hw/gpio/gpio_key.o
  CC      hw/i2c/core.o
  CC      hw/i2c/smbus.o
  CC      hw/i2c/smbus_eeprom.o
  CC      hw/i2c/i2c-ddc.o
  CC      hw/i2c/versatile_i2c.o
  CC      hw/i2c/smbus_ich9.o
  CC      hw/i2c/pm_smbus.o
  CC      hw/i2c/bitbang_i2c.o
  CC      hw/i2c/exynos4210_i2c.o
  CC      hw/i2c/imx_i2c.o
  CC      hw/i2c/aspeed_i2c.o
  CC      hw/ide/core.o
  CC      hw/ide/atapi.o
  CC      hw/ide/qdev.o
  CC      hw/ide/pci.o
  CC      hw/ide/isa.o
  CC      hw/ide/piix.o
  CC      hw/ide/microdrive.o
  CC      hw/ide/ahci.o
  CC      hw/ide/ich.o
  CC      hw/input/hid.o
  CC      hw/input/lm832x.o
  CC      hw/input/pckbd.o
  CC      hw/input/pl050.o
  CC      hw/input/ps2.o
  CC      hw/input/stellaris_input.o
  CC      hw/input/tsc2005.o
  CC      hw/input/vmmouse.o
  CC      hw/input/virtio-input.o
  CC      hw/input/virtio-input-hid.o
  CC      hw/input/virtio-input-host.o
  CC      hw/intc/i8259_common.o
  CC      hw/intc/i8259.o
  CC      hw/intc/pl190.o
  CC      hw/intc/imx_avic.o
  CC      hw/intc/realview_gic.o
  CC      hw/intc/ioapic_common.o
  CC      hw/intc/arm_gic.o
  CC      hw/intc/arm_gic_common.o
  CC      hw/intc/arm_gicv3_common.o
  CC      hw/intc/arm_gicv2m.o
  CC      hw/intc/arm_gicv3.o
  CC      hw/intc/arm_gicv3_dist.o
  CC      hw/intc/arm_gicv3_redist.o
  CC      hw/intc/arm_gicv3_its_common.o
  CC      hw/intc/intc.o
  CC      hw/ipack/ipack.o
  CC      hw/ipack/tpci200.o
  CC      hw/ipmi/ipmi.o
  CC      hw/ipmi/ipmi_bmc_sim.o
  CC      hw/ipmi/ipmi_bmc_extern.o
  CC      hw/ipmi/isa_ipmi_kcs.o
  CC      hw/ipmi/isa_ipmi_bt.o
  CC      hw/isa/isa-bus.o
  CC      hw/isa/apm.o
  CC      hw/mem/pc-dimm.o
  CC      hw/mem/nvdimm.o
  CC      hw/misc/applesmc.o
  CC      hw/misc/max111x.o
  CC      hw/misc/tmp105.o
  CC      hw/misc/debugexit.o
  CC      hw/misc/sga.o
  CC      hw/misc/pc-testdev.o
  CC      hw/misc/pci-testdev.o
  CC      hw/misc/arm_l2x0.o
  CC      hw/misc/arm_integrator_debug.o
  CC      hw/misc/a9scu.o
  CC      hw/misc/arm11scu.o
  CC      hw/net/ne2000.o
  CC      hw/net/eepro100.o
  CC      hw/net/pcnet-pci.o
  CC      hw/net/pcnet.o
  CC      hw/net/e1000.o
  CC      hw/net/e1000x_common.o
  CC      hw/net/net_tx_pkt.o
  CC      hw/net/net_rx_pkt.o
  CC      hw/net/e1000e.o
  CC      hw/net/e1000e_core.o
  CC      hw/net/rtl8139.o
  CC      hw/net/vmxnet3.o
  CC      hw/net/smc91c111.o
  CC      hw/net/lan9118.o
  CC      hw/net/ne2000-isa.o
  CC      hw/net/xgmac.o
  CC      hw/net/allwinner_emac.o
  CC      hw/net/imx_fec.o
  CC      hw/net/cadence_gem.o
  CC      hw/net/stellaris_enet.o
  CC      hw/net/rocker/rocker.o
  CC      hw/net/rocker/rocker_fp.o
  CC      hw/net/rocker/rocker_desc.o
  CC      hw/net/rocker/rocker_world.o
  CC      hw/net/rocker/rocker_of_dpa.o
  CC      hw/nvram/eeprom93xx.o
  CC      hw/nvram/fw_cfg.o
  CC      hw/nvram/chrp_nvram.o
  CC      hw/pci-bridge/pci_bridge_dev.o
  CC      hw/pci-bridge/pci_expander_bridge.o
  CC      hw/pci-bridge/xio3130_upstream.o
  CC      hw/pci-bridge/xio3130_downstream.o
  CC      hw/pci-bridge/ioh3420.o
  CC      hw/pci-bridge/i82801b11.o
  CC      hw/pci-host/pam.o
  CC      hw/pci-host/versatile.o
  CC      hw/pci-host/piix.o
  CC      hw/pci-host/q35.o
  CC      hw/pci-host/gpex.o
  CC      hw/pci/pci.o
  CC      hw/pci/pci_bridge.o
  CC      hw/pci/msix.o
  CC      hw/pci/shpc.o
  CC      hw/pci/msi.o
  CC      hw/pci/slotid_cap.o
  CC      hw/pci/pci_host.o
  CC      hw/pci/pcie_host.o
  CC      hw/pci/pcie.o
  CC      hw/pci/pcie_aer.o
  CC      hw/pci/pcie_port.o
  CC      hw/pci/pci-stub.o
/tmp/qemu-test/src/hw/nvram/fw_cfg.c: In function ‘fw_cfg_dma_transfer’:
/tmp/qemu-test/src/hw/nvram/fw_cfg.c:329: warning: ‘read’ may be used uninitialized in this function
  CC      hw/pcmcia/pcmcia.o
  CC      hw/scsi/scsi-disk.o
  CC      hw/scsi/scsi-generic.o
  CC      hw/scsi/scsi-bus.o
  CC      hw/scsi/lsi53c895a.o
  CC      hw/scsi/mptsas.o
  CC      hw/scsi/mptconfig.o
  CC      hw/scsi/mptendian.o
  CC      hw/scsi/megasas.o
  CC      hw/scsi/vmw_pvscsi.o
  CC      hw/scsi/esp.o
  CC      hw/scsi/esp-pci.o
  CC      hw/sd/pl181.o
  CC      hw/sd/ssi-sd.o
  CC      hw/sd/sd.o
  CC      hw/sd/core.o
  CC      hw/sd/sdhci.o
  CC      hw/smbios/smbios.o
  CC      hw/smbios/smbios_type_38.o
  CC      hw/ssi/pl022.o
  CC      hw/ssi/ssi.o
  CC      hw/ssi/xilinx_spips.o
  CC      hw/ssi/aspeed_smc.o
  CC      hw/ssi/stm32f2xx_spi.o
  CC      hw/timer/arm_timer.o
  CC      hw/timer/arm_mptimer.o
  CC      hw/timer/a9gtimer.o
  CC      hw/timer/cadence_ttc.o
  CC      hw/timer/ds1338.o
  CC      hw/timer/hpet.o
  CC      hw/timer/i8254_common.o
  CC      hw/timer/i8254.o
  CC      hw/timer/pl031.o
  CC      hw/timer/twl92230.o
  CC      hw/timer/imx_epit.o
  CC      hw/timer/imx_gpt.o
  CC      hw/timer/stm32f2xx_timer.o
  CC      hw/timer/aspeed_timer.o
  CC      hw/tpm/tpm_tis.o
  CC      hw/tpm/tpm_passthrough.o
  CC      hw/tpm/tpm_util.o
  CC      hw/usb/core.o
  CC      hw/usb/combined-packet.o
  CC      hw/usb/bus.o
  CC      hw/usb/libhw.o
  CC      hw/usb/desc.o
  CC      hw/usb/desc-msos.o
  CC      hw/usb/hcd-uhci.o
  CC      hw/usb/hcd-ohci.o
  CC      hw/usb/hcd-ehci.o
  CC      hw/usb/hcd-ehci-pci.o
  CC      hw/usb/hcd-ehci-sysbus.o
  CC      hw/usb/hcd-xhci.o
  CC      hw/usb/hcd-musb.o
  CC      hw/usb/dev-hub.o
  CC      hw/usb/dev-hid.o
  CC      hw/usb/dev-wacom.o
  CC      hw/usb/dev-storage.o
  CC      hw/usb/dev-uas.o
  CC      hw/usb/dev-audio.o
  CC      hw/usb/dev-serial.o
  CC      hw/usb/dev-network.o
  CC      hw/usb/dev-bluetooth.o
  CC      hw/usb/dev-smartcard-reader.o
  CC      hw/usb/dev-mtp.o
  CC      hw/virtio/virtio-rng.o
  CC      hw/usb/host-stub.o
  CC      hw/virtio/virtio-pci.o
  CC      hw/virtio/virtio-bus.o
  CC      hw/virtio/virtio-mmio.o
  CC      hw/watchdog/watchdog.o
  CC      hw/watchdog/wdt_i6300esb.o
  CC      hw/watchdog/wdt_ib700.o
  CC      migration/migration.o
  CC      migration/socket.o
  CC      migration/fd.o
  CC      migration/exec.o
  CC      migration/tls.o
  CC      migration/colo-comm.o
  CC      migration/colo.o
  CC      migration/colo-failover.o
  CC      migration/vmstate.o
  CC      migration/qemu-file.o
  CC      migration/qemu-file-channel.o
  CC      migration/xbzrle.o
  CC      migration/postcopy-ram.o
  CC      migration/qjson.o
  CC      migration/block.o
  CC      net/net.o
  CC      net/queue.o
  CC      net/checksum.o
  CC      net/util.o
  CC      net/hub.o
  CC      net/socket.o
  CC      net/dump.o
  CC      net/eth.o
  CC      net/l2tpv3.o
  CC      net/tap.o
  CC      net/vhost-user.o
  CC      net/tap-linux.o
  CC      net/slirp.o
  CC      net/filter.o
  CC      net/filter-buffer.o
  CC      net/filter-mirror.o
  CC      net/colo-compare.o
  CC      net/colo.o
  CC      net/filter-rewriter.o
  CC      qom/cpu.o
  CC      replay/replay.o
  CC      replay/replay-internal.o
  CC      replay/replay-events.o
  CC      replay/replay-time.o
  CC      replay/replay-input.o
  CC      replay/replay-char.o
/tmp/qemu-test/src/replay/replay-internal.c: In function ‘replay_put_array’:
/tmp/qemu-test/src/replay/replay-internal.c:65: warning: ignoring return value of ‘fwrite’, declared with attribute warn_unused_result
  CC      replay/replay-snapshot.o
  CC      slirp/cksum.o
  CC      slirp/if.o
  CC      slirp/ip_icmp.o
  CC      slirp/ip6_icmp.o
  CC      slirp/ip6_input.o
  CC      slirp/ip6_output.o
  CC      slirp/ip_input.o
  CC      slirp/ip_output.o
  CC      slirp/dnssearch.o
  CC      slirp/dhcpv6.o
  CC      slirp/slirp.o
  CC      slirp/mbuf.o
  CC      slirp/misc.o
  CC      slirp/sbuf.o
  CC      slirp/socket.o
  CC      slirp/tcp_input.o
  CC      slirp/tcp_output.o
  CC      slirp/tcp_timer.o
  CC      slirp/tcp_subr.o
  CC      slirp/udp.o
  CC      slirp/udp6.o
  CC      slirp/bootp.o
  CC      slirp/tftp.o
  CC      slirp/arp_table.o
  CC      slirp/ndp_table.o
  CC      ui/keymaps.o
  CC      ui/console.o
  CC      ui/cursor.o
  CC      ui/qemu-pixman.o
  CC      ui/input.o
  CC      ui/input-keymap.o
  CC      ui/input-legacy.o
  CC      ui/input-linux.o
  CC      ui/sdl.o
  CC      ui/sdl_zoom.o
  CC      ui/x_keymap.o
  CC      ui/vnc.o
  CC      ui/vnc-enc-zlib.o
  CC      ui/vnc-enc-hextile.o
  CC      ui/vnc-enc-tight.o
  CC      ui/vnc-palette.o
/tmp/qemu-test/src/slirp/tcp_input.c: In function ‘tcp_input’:
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_p’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_len’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_tos’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_id’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_off’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_ttl’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_sum’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_src.s_addr’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_dst.s_addr’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:220: warning: ‘save_ip6.ip_nh’ may be used uninitialized in this function
  CC      ui/vnc-enc-zrle.o
  CC      ui/vnc-auth-vencrypt.o
  CC      ui/vnc-ws.o
  CC      ui/vnc-jobs.o
  LINK    tests/qemu-iotests/socket_scm_helper
  AS      optionrom/multiboot.o
  CC      qga/commands.o
  CC      qga/guest-agent-command-state.o
  AS      optionrom/linuxboot.o
  CC      qga/main.o
  CC      optionrom/linuxboot_dma.o
cc: unrecognized option '-no-integrated-as'
cc: unrecognized option '-no-integrated-as'
  CC      qga/commands-posix.o
  AS      optionrom/kvmvapic.o
  CC      qga/channel-posix.o
  BUILD   optionrom/multiboot.img
  BUILD   optionrom/linuxboot.img
  BUILD   optionrom/linuxboot_dma.img
  BUILD   optionrom/kvmvapic.img
  BUILD   optionrom/multiboot.raw
  BUILD   optionrom/linuxboot.raw
  BUILD   optionrom/linuxboot_dma.raw
  BUILD   optionrom/kvmvapic.raw
  SIGN    optionrom/multiboot.bin
  SIGN    optionrom/linuxboot.bin
  SIGN    optionrom/linuxboot_dma.bin
  CC      qga/qapi-generated/qga-qapi-types.o
  SIGN    optionrom/kvmvapic.bin
  CC      qga/qapi-generated/qga-qapi-visit.o
  CC      qga/qapi-generated/qga-qmp-marshal.o
  CC      qmp-introspect.o
  CC      qapi-types.o
  CC      qapi-visit.o
  CC      qapi-event.o
  AR      libqemustub.a
  CC      qemu-img.o
  CC      qmp-marshal.o
  CC      trace/generated-tracers.o
  AR      libqemuutil.a
  LINK    qemu-ga
  LINK    ivshmem-client
  LINK    ivshmem-server
  LINK    qemu-nbd
  LINK    qemu-img
  LINK    qemu-io
  LINK    qemu-bridge-helper
  GEN     aarch64-softmmu/hmp-commands.h
  GEN     aarch64-softmmu/hmp-commands-info.h
  GEN     aarch64-softmmu/config-target.h
  GEN     x86_64-softmmu/hmp-commands-info.h
  GEN     x86_64-softmmu/hmp-commands.h
  GEN     x86_64-softmmu/config-target.h
  CC      aarch64-softmmu/exec.o
  CC      aarch64-softmmu/translate-all.o
  CC      aarch64-softmmu/cpu-exec.o
  CC      aarch64-softmmu/translate-common.o
  CC      aarch64-softmmu/cpu-exec-common.o
  CC      aarch64-softmmu/tcg/tcg.o
  CC      aarch64-softmmu/tcg/tcg-op.o
  CC      aarch64-softmmu/tcg/optimize.o
  CC      aarch64-softmmu/fpu/softfloat.o
  CC      aarch64-softmmu/tcg/tcg-common.o
  CC      aarch64-softmmu/disas.o
  CC      aarch64-softmmu/tcg-runtime.o
  GEN     aarch64-softmmu/gdbstub-xml.c
  CC      aarch64-softmmu/kvm-stub.o
  CC      aarch64-softmmu/arch_init.o
  CC      aarch64-softmmu/cpus.o
  CC      x86_64-softmmu/exec.o
  CC      aarch64-softmmu/monitor.o
  CC      aarch64-softmmu/gdbstub.o
  CC      aarch64-softmmu/balloon.o
  CC      x86_64-softmmu/translate-all.o
  CC      x86_64-softmmu/cpu-exec.o
  CC      aarch64-softmmu/ioport.o
  CC      x86_64-softmmu/translate-common.o
  CC      x86_64-softmmu/cpu-exec-common.o
  CC      aarch64-softmmu/numa.o
  CC      x86_64-softmmu/tcg/tcg.o
  CC      aarch64-softmmu/qtest.o
  CC      x86_64-softmmu/tcg/tcg-op.o
  CC      x86_64-softmmu/tcg/optimize.o
  CC      x86_64-softmmu/tcg/tcg-common.o
  CC      aarch64-softmmu/bootdevice.o
  CC      x86_64-softmmu/fpu/softfloat.o
  CC      x86_64-softmmu/disas.o
  CC      aarch64-softmmu/memory.o
  CC      aarch64-softmmu/cputlb.o
  CC      aarch64-softmmu/memory_mapping.o
  CC      aarch64-softmmu/dump.o
  CC      x86_64-softmmu/tcg-runtime.o
  CC      aarch64-softmmu/migration/ram.o
  CC      x86_64-softmmu/arch_init.o
  CC      x86_64-softmmu/cpus.o
  CC      aarch64-softmmu/migration/savevm.o
  CC      x86_64-softmmu/monitor.o
  CC      x86_64-softmmu/gdbstub.o
  CC      aarch64-softmmu/xen-common-stub.o
  CC      aarch64-softmmu/xen-hvm-stub.o
  CC      x86_64-softmmu/balloon.o
  CC      aarch64-softmmu/hw/adc/stm32f2xx_adc.o
  CC      x86_64-softmmu/ioport.o
  CC      aarch64-softmmu/hw/block/virtio-blk.o
  CC      aarch64-softmmu/hw/block/dataplane/virtio-blk.o
  CC      x86_64-softmmu/numa.o
  CC      x86_64-softmmu/qtest.o
  CC      x86_64-softmmu/bootdevice.o
  CC      x86_64-softmmu/kvm-all.o
  CC      x86_64-softmmu/memory.o
  CC      x86_64-softmmu/cputlb.o
  CC      x86_64-softmmu/memory_mapping.o
  CC      x86_64-softmmu/dump.o
  CC      x86_64-softmmu/migration/ram.o
  CC      x86_64-softmmu/migration/savevm.o
  CC      x86_64-softmmu/xen-common-stub.o
  CC      x86_64-softmmu/xen-hvm-stub.o
  CC      aarch64-softmmu/hw/char/exynos4210_uart.o
  CC      aarch64-softmmu/hw/char/omap_uart.o
  CC      aarch64-softmmu/hw/char/digic-uart.o
  CC      x86_64-softmmu/hw/block/virtio-blk.o
  CC      aarch64-softmmu/hw/char/stm32f2xx_usart.o
  CC      x86_64-softmmu/hw/block/dataplane/virtio-blk.o
  CC      aarch64-softmmu/hw/char/bcm2835_aux.o
  CC      x86_64-softmmu/hw/char/virtio-serial-bus.o
  CC      x86_64-softmmu/hw/core/nmi.o
  CC      x86_64-softmmu/hw/core/generic-loader.o
  CC      aarch64-softmmu/hw/char/virtio-serial-bus.o
  CC      aarch64-softmmu/hw/core/nmi.o
  CC      aarch64-softmmu/hw/core/generic-loader.o
  CC      aarch64-softmmu/hw/cpu/arm11mpcore.o
  CC      aarch64-softmmu/hw/cpu/realview_mpcore.o
  CC      x86_64-softmmu/hw/cpu/core.o
  CC      x86_64-softmmu/hw/display/vga.o
  CC      x86_64-softmmu/hw/display/virtio-gpu.o
  CC      aarch64-softmmu/hw/cpu/a9mpcore.o
  CC      x86_64-softmmu/hw/display/virtio-gpu-3d.o
  CC      x86_64-softmmu/hw/display/virtio-gpu-pci.o
  CC      x86_64-softmmu/hw/display/virtio-vga.o
  CC      x86_64-softmmu/hw/intc/apic.o
  CC      x86_64-softmmu/hw/intc/apic_common.o
  CC      aarch64-softmmu/hw/cpu/a15mpcore.o
  CC      aarch64-softmmu/hw/cpu/core.o
  CC      aarch64-softmmu/hw/display/omap_dss.o
  CC      aarch64-softmmu/hw/display/omap_lcdc.o
  CC      aarch64-softmmu/hw/display/pxa2xx_lcd.o
  CC      x86_64-softmmu/hw/intc/ioapic.o
  CC      x86_64-softmmu/hw/isa/lpc_ich9.o
  CC      aarch64-softmmu/hw/display/bcm2835_fb.o
  CC      aarch64-softmmu/hw/display/vga.o
  CC      aarch64-softmmu/hw/display/virtio-gpu.o
  CC      aarch64-softmmu/hw/display/virtio-gpu-3d.o
  CC      x86_64-softmmu/hw/misc/vmport.o
  CC      aarch64-softmmu/hw/display/virtio-gpu-pci.o
  CC      aarch64-softmmu/hw/display/dpcd.o
  CC      x86_64-softmmu/hw/misc/pvpanic.o
  CC      aarch64-softmmu/hw/display/xlnx_dp.o
  CC      x86_64-softmmu/hw/misc/ivshmem.o
  CC      x86_64-softmmu/hw/misc/edu.o
  CC      x86_64-softmmu/hw/misc/hyperv_testdev.o
  CC      aarch64-softmmu/hw/dma/xlnx_dpdma.o
  CC      aarch64-softmmu/hw/dma/omap_dma.o
  CC      x86_64-softmmu/hw/net/virtio-net.o
  CC      aarch64-softmmu/hw/dma/soc_dma.o
  CC      x86_64-softmmu/hw/net/vhost_net.o
  CC      aarch64-softmmu/hw/dma/pxa2xx_dma.o
  CC      aarch64-softmmu/hw/dma/bcm2835_dma.o
  CC      aarch64-softmmu/hw/gpio/omap_gpio.o
  CC      aarch64-softmmu/hw/gpio/imx_gpio.o
  CC      x86_64-softmmu/hw/scsi/virtio-scsi.o
  CC      x86_64-softmmu/hw/scsi/virtio-scsi-dataplane.o
  CC      aarch64-softmmu/hw/i2c/omap_i2c.o
  CC      aarch64-softmmu/hw/input/pxa2xx_keypad.o
  CC      aarch64-softmmu/hw/input/tsc210x.o
  CC      aarch64-softmmu/hw/intc/armv7m_nvic.o
  CC      aarch64-softmmu/hw/intc/exynos4210_gic.o
  CC      aarch64-softmmu/hw/intc/exynos4210_combiner.o
  CC      x86_64-softmmu/hw/scsi/vhost-scsi.o
  CC      aarch64-softmmu/hw/intc/omap_intc.o
  CC      x86_64-softmmu/hw/timer/mc146818rtc.o
  CC      aarch64-softmmu/hw/intc/bcm2835_ic.o
  CC      x86_64-softmmu/hw/vfio/common.o
  CC      aarch64-softmmu/hw/intc/bcm2836_control.o
  CC      aarch64-softmmu/hw/intc/allwinner-a10-pic.o
  CC      x86_64-softmmu/hw/vfio/pci.o
  CC      x86_64-softmmu/hw/vfio/pci-quirks.o
  CC      x86_64-softmmu/hw/vfio/platform.o
  CC      x86_64-softmmu/hw/vfio/calxeda-xgmac.o
  CC      x86_64-softmmu/hw/vfio/amd-xgbe.o
  CC      aarch64-softmmu/hw/intc/aspeed_vic.o
  CC      aarch64-softmmu/hw/intc/arm_gicv3_cpuif.o
  CC      aarch64-softmmu/hw/misc/ivshmem.o
  CC      x86_64-softmmu/hw/vfio/spapr.o
  CC      x86_64-softmmu/hw/virtio/virtio.o
  CC      x86_64-softmmu/hw/virtio/virtio-balloon.o
  CC      aarch64-softmmu/hw/misc/arm_sysctl.o
  CC      aarch64-softmmu/hw/misc/cbus.o
  CC      x86_64-softmmu/hw/virtio/vhost.o
  CC      aarch64-softmmu/hw/misc/exynos4210_pmu.o
  CC      x86_64-softmmu/hw/virtio/vhost-backend.o
  CC      x86_64-softmmu/hw/virtio/vhost-user.o
  CC      aarch64-softmmu/hw/misc/imx_ccm.o
  CC      x86_64-softmmu/hw/virtio/vhost-vsock.o
  CC      x86_64-softmmu/hw/virtio/virtio-crypto.o
  CC      aarch64-softmmu/hw/misc/imx31_ccm.o
  CC      aarch64-softmmu/hw/misc/imx25_ccm.o
  CC      x86_64-softmmu/hw/virtio/virtio-crypto-pci.o
  CC      aarch64-softmmu/hw/misc/imx6_ccm.o
  CC      aarch64-softmmu/hw/misc/imx6_src.o
  CC      x86_64-softmmu/hw/i386/multiboot.o
  CC      aarch64-softmmu/hw/misc/mst_fpga.o
  CC      x86_64-softmmu/hw/i386/pc.o
  CC      x86_64-softmmu/hw/i386/pc_piix.o
  CC      x86_64-softmmu/hw/i386/pc_q35.o
  CC      aarch64-softmmu/hw/misc/omap_clk.o
  CC      x86_64-softmmu/hw/i386/pc_sysfw.o
  CC      aarch64-softmmu/hw/misc/omap_gpmc.o
  CC      aarch64-softmmu/hw/misc/omap_l4.o
  CC      x86_64-softmmu/hw/i386/x86-iommu.o
  CC      aarch64-softmmu/hw/misc/omap_sdrc.o
  CC      x86_64-softmmu/hw/i386/intel_iommu.o
  CC      aarch64-softmmu/hw/misc/omap_tap.o
  CC      aarch64-softmmu/hw/misc/bcm2835_mbox.o
  CC      x86_64-softmmu/hw/i386/amd_iommu.o
  CC      aarch64-softmmu/hw/misc/bcm2835_property.o
  CC      x86_64-softmmu/hw/i386/kvmvapic.o
  CC      aarch64-softmmu/hw/misc/zynq_slcr.o
  CC      aarch64-softmmu/hw/misc/zynq-xadc.o
  CC      x86_64-softmmu/hw/i386/acpi-build.o
  CC      aarch64-softmmu/hw/misc/stm32f2xx_syscfg.o
  CC      aarch64-softmmu/hw/misc/edu.o
  CC      x86_64-softmmu/hw/i386/pci-assign-load-rom.o
  CC      x86_64-softmmu/hw/i386/kvm/clock.o
  CC      x86_64-softmmu/hw/i386/kvm/apic.o
  CC      aarch64-softmmu/hw/misc/auxbus.o
  CC      x86_64-softmmu/hw/i386/kvm/i8259.o
  CC      x86_64-softmmu/hw/i386/kvm/ioapic.o
  CC      x86_64-softmmu/hw/i386/kvm/i8254.o
  CC      x86_64-softmmu/hw/i386/kvm/pci-assign.o
  CC      aarch64-softmmu/hw/misc/aspeed_scu.o
/tmp/qemu-test/src/hw/i386/pc_piix.c: In function ‘igd_passthrough_isa_bridge_create’:
/tmp/qemu-test/src/hw/i386/pc_piix.c:1046: warning: ‘pch_rev_id’ may be used uninitialized in this function
  CC      aarch64-softmmu/hw/misc/aspeed_sdmc.o
  CC      x86_64-softmmu/target-i386/translate.o
  CC      aarch64-softmmu/hw/net/virtio-net.o
  CC      aarch64-softmmu/hw/net/vhost_net.o
  CC      aarch64-softmmu/hw/pcmcia/pxa2xx.o
  CC      x86_64-softmmu/target-i386/helper.o
  CC      x86_64-softmmu/target-i386/cpu.o
  CC      aarch64-softmmu/hw/scsi/virtio-scsi.o
  CC      aarch64-softmmu/hw/scsi/virtio-scsi-dataplane.o
  CC      aarch64-softmmu/hw/scsi/vhost-scsi.o
  CC      x86_64-softmmu/target-i386/bpt_helper.o
  CC      x86_64-softmmu/target-i386/excp_helper.o
  CC      aarch64-softmmu/hw/sd/omap_mmc.o
  CC      aarch64-softmmu/hw/sd/pxa2xx_mmci.o
  CC      x86_64-softmmu/target-i386/fpu_helper.o
/tmp/qemu-test/src/hw/i386/acpi-build.c: In function ‘build_append_pci_bus_devices’:
/tmp/qemu-test/src/hw/i386/acpi-build.c:501: warning: ‘notify_method’ may be used uninitialized in this function
  CC      x86_64-softmmu/target-i386/cc_helper.o
  CC      aarch64-softmmu/hw/ssi/omap_spi.o
  CC      aarch64-softmmu/hw/ssi/imx_spi.o
  CC      x86_64-softmmu/target-i386/int_helper.o
  CC      x86_64-softmmu/target-i386/svm_helper.o
  CC      x86_64-softmmu/target-i386/smm_helper.o
  CC      x86_64-softmmu/target-i386/misc_helper.o
  CC      x86_64-softmmu/target-i386/mem_helper.o
  CC      x86_64-softmmu/target-i386/seg_helper.o
  CC      x86_64-softmmu/target-i386/mpx_helper.o
  CC      aarch64-softmmu/hw/timer/exynos4210_mct.o
  CC      aarch64-softmmu/hw/timer/exynos4210_pwm.o
  CC      aarch64-softmmu/hw/timer/exynos4210_rtc.o
  CC      aarch64-softmmu/hw/timer/omap_gptimer.o
  CC      aarch64-softmmu/hw/timer/omap_synctimer.o
  CC      x86_64-softmmu/target-i386/gdbstub.o
  CC      x86_64-softmmu/target-i386/machine.o
  CC      aarch64-softmmu/hw/timer/pxa2xx_timer.o
  CC      aarch64-softmmu/hw/timer/digic-timer.o
  CC      aarch64-softmmu/hw/timer/allwinner-a10-pit.o
  CC      aarch64-softmmu/hw/usb/tusb6010.o
  CC      aarch64-softmmu/hw/vfio/common.o
  CC      x86_64-softmmu/target-i386/arch_memory_mapping.o
  CC      x86_64-softmmu/target-i386/arch_dump.o
  CC      x86_64-softmmu/target-i386/monitor.o
  CC      x86_64-softmmu/target-i386/kvm.o
  CC      aarch64-softmmu/hw/vfio/pci.o
  CC      aarch64-softmmu/hw/vfio/pci-quirks.o
  CC      aarch64-softmmu/hw/vfio/platform.o
  CC      x86_64-softmmu/target-i386/hyperv.o
  GEN     trace/generated-helpers.c
  CC      aarch64-softmmu/hw/vfio/calxeda-xgmac.o
  CC      aarch64-softmmu/hw/vfio/amd-xgbe.o
  CC      aarch64-softmmu/hw/vfio/spapr.o
  CC      aarch64-softmmu/hw/virtio/virtio.o
  CC      aarch64-softmmu/hw/virtio/virtio-balloon.o
  CC      aarch64-softmmu/hw/virtio/vhost.o
  CC      x86_64-softmmu/trace/control-target.o
  CC      aarch64-softmmu/hw/virtio/vhost-backend.o
  CC      aarch64-softmmu/hw/virtio/vhost-user.o
  CC      aarch64-softmmu/hw/virtio/vhost-vsock.o
  CC      aarch64-softmmu/hw/virtio/virtio-crypto.o
  CC      x86_64-softmmu/trace/generated-helpers.o
  CC      aarch64-softmmu/hw/virtio/virtio-crypto-pci.o
  CC      aarch64-softmmu/hw/arm/boot.o
  CC      aarch64-softmmu/hw/arm/collie.o
  CC      aarch64-softmmu/hw/arm/exynos4_boards.o
  CC      aarch64-softmmu/hw/arm/gumstix.o
  CC      aarch64-softmmu/hw/arm/highbank.o
  CC      aarch64-softmmu/hw/arm/digic_boards.o
  CC      aarch64-softmmu/hw/arm/integratorcp.o
  CC      aarch64-softmmu/hw/arm/mainstone.o
  CC      aarch64-softmmu/hw/arm/musicpal.o
  CC      aarch64-softmmu/hw/arm/nseries.o
  CC      aarch64-softmmu/hw/arm/omap_sx1.o
  CC      aarch64-softmmu/hw/arm/palm.o
  CC      aarch64-softmmu/hw/arm/realview.o
  CC      aarch64-softmmu/hw/arm/spitz.o
  CC      aarch64-softmmu/hw/arm/stellaris.o
  CC      aarch64-softmmu/hw/arm/tosa.o
  CC      aarch64-softmmu/hw/arm/versatilepb.o
  CC      aarch64-softmmu/hw/arm/vexpress.o
  CC      aarch64-softmmu/hw/arm/virt.o
  CC      aarch64-softmmu/hw/arm/xilinx_zynq.o
  CC      aarch64-softmmu/hw/arm/z2.o
  CC      aarch64-softmmu/hw/arm/virt-acpi-build.o
  CC      aarch64-softmmu/hw/arm/netduino2.o
  CC      aarch64-softmmu/hw/arm/sysbus-fdt.o
  CC      aarch64-softmmu/hw/arm/armv7m.o
  CC      aarch64-softmmu/hw/arm/exynos4210.o
  CC      aarch64-softmmu/hw/arm/pxa2xx.o
  CC      aarch64-softmmu/hw/arm/pxa2xx_gpio.o
  CC      aarch64-softmmu/hw/arm/pxa2xx_pic.o
  CC      aarch64-softmmu/hw/arm/digic.o
  CC      aarch64-softmmu/hw/arm/omap1.o
  CC      aarch64-softmmu/hw/arm/omap2.o
  CC      aarch64-softmmu/hw/arm/strongarm.o
  CC      aarch64-softmmu/hw/arm/allwinner-a10.o
  CC      aarch64-softmmu/hw/arm/cubieboard.o
  CC      aarch64-softmmu/hw/arm/bcm2835_peripherals.o
  CC      aarch64-softmmu/hw/arm/bcm2836.o
  CC      aarch64-softmmu/hw/arm/raspi.o
  CC      aarch64-softmmu/hw/arm/stm32f205_soc.o
  CC      aarch64-softmmu/hw/arm/xlnx-zynqmp.o
  CC      aarch64-softmmu/hw/arm/xlnx-ep108.o
  CC      aarch64-softmmu/hw/arm/fsl-imx25.o
  CC      aarch64-softmmu/hw/arm/imx25_pdk.o
  CC      aarch64-softmmu/hw/arm/fsl-imx31.o
  CC      aarch64-softmmu/hw/arm/kzm.o
  CC      aarch64-softmmu/hw/arm/fsl-imx6.o
  CC      aarch64-softmmu/hw/arm/sabrelite.o
  CC      aarch64-softmmu/hw/arm/aspeed_soc.o
  CC      aarch64-softmmu/hw/arm/aspeed.o
  CC      aarch64-softmmu/target-arm/arm-semi.o
  CC      aarch64-softmmu/target-arm/machine.o
  CC      aarch64-softmmu/target-arm/psci.o
  CC      aarch64-softmmu/target-arm/arch_dump.o
  CC      aarch64-softmmu/target-arm/monitor.o
  CC      aarch64-softmmu/target-arm/kvm-stub.o
  CC      aarch64-softmmu/target-arm/translate.o
  CC      aarch64-softmmu/target-arm/op_helper.o
  CC      aarch64-softmmu/target-arm/helper.o
  CC      aarch64-softmmu/target-arm/cpu.o
  CC      aarch64-softmmu/target-arm/neon_helper.o
  CC      aarch64-softmmu/target-arm/iwmmxt_helper.o
  CC      aarch64-softmmu/target-arm/gdbstub.o
  CC      aarch64-softmmu/target-arm/cpu64.o
  LINK    x86_64-softmmu/qemu-system-x86_64
  CC      aarch64-softmmu/target-arm/translate-a64.o
  CC      aarch64-softmmu/target-arm/helper-a64.o
  CC      aarch64-softmmu/target-arm/gdbstub64.o
  CC      aarch64-softmmu/target-arm/crypto_helper.o
  CC      aarch64-softmmu/target-arm/arm-powerctl.o
  GEN     trace/generated-helpers.c
  CC      aarch64-softmmu/trace/control-target.o
  CC      aarch64-softmmu/gdbstub-xml.o
  CC      aarch64-softmmu/trace/generated-helpers.o
/tmp/qemu-test/src/target-arm/translate-a64.c: In function ‘handle_shri_with_rndacc’:
/tmp/qemu-test/src/target-arm/translate-a64.c:6395: warning: ‘tcg_src_hi’ may be used uninitialized in this function
/tmp/qemu-test/src/target-arm/translate-a64.c: In function ‘disas_simd_scalar_two_reg_misc’:
/tmp/qemu-test/src/target-arm/translate-a64.c:8122: warning: ‘rmode’ may be used uninitialized in this function
  LINK    aarch64-softmmu/qemu-system-aarch64
  TEST    tests/qapi-schema/alternate-any.out
  TEST    tests/qapi-schema/alternate-array.out
  TEST    tests/qapi-schema/alternate-base.out
  TEST    tests/qapi-schema/alternate-clash.out
  TEST    tests/qapi-schema/alternate-conflict-dict.out
  TEST    tests/qapi-schema/alternate-conflict-string.out
  TEST    tests/qapi-schema/alternate-empty.out
  TEST    tests/qapi-schema/alternate-unknown.out
  TEST    tests/qapi-schema/alternate-nested.out
  TEST    tests/qapi-schema/args-alternate.out
  TEST    tests/qapi-schema/args-any.out
  TEST    tests/qapi-schema/args-array-empty.out
  TEST    tests/qapi-schema/args-array-unknown.out
  TEST    tests/qapi-schema/args-bad-boxed.out
  TEST    tests/qapi-schema/args-boxed-anon.out
  TEST    tests/qapi-schema/args-boxed-empty.out
  TEST    tests/qapi-schema/args-boxed-string.out
  TEST    tests/qapi-schema/args-int.out
  TEST    tests/qapi-schema/args-invalid.out
  TEST    tests/qapi-schema/args-member-array-bad.out
  TEST    tests/qapi-schema/args-member-case.out
  TEST    tests/qapi-schema/args-member-unknown.out
  TEST    tests/qapi-schema/args-name-clash.out
  TEST    tests/qapi-schema/args-union.out
  TEST    tests/qapi-schema/args-unknown.out
  TEST    tests/qapi-schema/bad-base.out
  TEST    tests/qapi-schema/bad-data.out
  TEST    tests/qapi-schema/bad-ident.out
  TEST    tests/qapi-schema/bad-type-bool.out
  TEST    tests/qapi-schema/bad-type-dict.out
  TEST    tests/qapi-schema/bad-type-int.out
  TEST    tests/qapi-schema/base-cycle-direct.out
  TEST    tests/qapi-schema/base-cycle-indirect.out
  TEST    tests/qapi-schema/command-int.out
  TEST    tests/qapi-schema/comments.out
  TEST    tests/qapi-schema/double-data.out
  TEST    tests/qapi-schema/double-type.out
  TEST    tests/qapi-schema/duplicate-key.out
  TEST    tests/qapi-schema/empty.out
  TEST    tests/qapi-schema/enum-bad-name.out
  TEST    tests/qapi-schema/enum-bad-prefix.out
  TEST    tests/qapi-schema/enum-clash-member.out
  TEST    tests/qapi-schema/enum-dict-member.out
  TEST    tests/qapi-schema/enum-int-member.out
  TEST    tests/qapi-schema/enum-member-case.out
  TEST    tests/qapi-schema/enum-missing-data.out
  TEST    tests/qapi-schema/enum-wrong-data.out
  TEST    tests/qapi-schema/escape-outside-string.out
  TEST    tests/qapi-schema/escape-too-big.out
  TEST    tests/qapi-schema/escape-too-short.out
  TEST    tests/qapi-schema/event-boxed-empty.out
  TEST    tests/qapi-schema/event-case.out
  TEST    tests/qapi-schema/event-nest-struct.out
  TEST    tests/qapi-schema/flat-union-array-branch.out
  TEST    tests/qapi-schema/flat-union-bad-discriminator.out
  TEST    tests/qapi-schema/flat-union-bad-base.out
  TEST    tests/qapi-schema/flat-union-base-any.out
  TEST    tests/qapi-schema/flat-union-base-union.out
  TEST    tests/qapi-schema/flat-union-clash-member.out
  TEST    tests/qapi-schema/flat-union-empty.out
  TEST    tests/qapi-schema/flat-union-incomplete-branch.out
  TEST    tests/qapi-schema/flat-union-int-branch.out
  TEST    tests/qapi-schema/flat-union-inline.out
  TEST    tests/qapi-schema/flat-union-invalid-discriminator.out
  TEST    tests/qapi-schema/flat-union-invalid-branch-key.out
  TEST    tests/qapi-schema/flat-union-no-base.out
  TEST    tests/qapi-schema/flat-union-optional-discriminator.out
  TEST    tests/qapi-schema/flat-union-string-discriminator.out
  TEST    tests/qapi-schema/funny-char.out
  TEST    tests/qapi-schema/ident-with-escape.out
  TEST    tests/qapi-schema/include-before-err.out
  TEST    tests/qapi-schema/include-cycle.out
  TEST    tests/qapi-schema/include-format-err.out
  TEST    tests/qapi-schema/include-no-file.out
  TEST    tests/qapi-schema/include-nested-err.out
  TEST    tests/qapi-schema/include-non-file.out
  TEST    tests/qapi-schema/include-repetition.out
  TEST    tests/qapi-schema/include-relpath.out
  TEST    tests/qapi-schema/include-self-cycle.out
  TEST    tests/qapi-schema/include-simple.out
  TEST    tests/qapi-schema/indented-expr.out
  TEST    tests/qapi-schema/leading-comma-list.out
  TEST    tests/qapi-schema/leading-comma-object.out
  TEST    tests/qapi-schema/missing-colon.out
  TEST    tests/qapi-schema/missing-comma-list.out
  TEST    tests/qapi-schema/missing-comma-object.out
  TEST    tests/qapi-schema/missing-type.out
  TEST    tests/qapi-schema/nested-struct-data.out
  TEST    tests/qapi-schema/non-objects.out
  TEST    tests/qapi-schema/qapi-schema-test.out
  TEST    tests/qapi-schema/quoted-structural-chars.out
  TEST    tests/qapi-schema/redefined-builtin.out
  TEST    tests/qapi-schema/redefined-command.out
  TEST    tests/qapi-schema/redefined-event.out
  TEST    tests/qapi-schema/redefined-type.out
  TEST    tests/qapi-schema/reserved-command-q.out
  TEST    tests/qapi-schema/reserved-enum-q.out
  TEST    tests/qapi-schema/reserved-member-has.out
  TEST    tests/qapi-schema/reserved-member-q.out
  TEST    tests/qapi-schema/reserved-member-u.out
  TEST    tests/qapi-schema/reserved-member-underscore.out
  TEST    tests/qapi-schema/reserved-type-kind.out
  TEST    tests/qapi-schema/reserved-type-list.out
  TEST    tests/qapi-schema/returns-alternate.out
  TEST    tests/qapi-schema/returns-array-bad.out
  TEST    tests/qapi-schema/returns-dict.out
  TEST    tests/qapi-schema/returns-unknown.out
  TEST    tests/qapi-schema/returns-whitelist.out
  TEST    tests/qapi-schema/struct-base-clash-deep.out
  TEST    tests/qapi-schema/struct-base-clash.out
  TEST    tests/qapi-schema/struct-data-invalid.out
  TEST    tests/qapi-schema/struct-member-invalid.out
  TEST    tests/qapi-schema/trailing-comma-object.out
  TEST    tests/qapi-schema/trailing-comma-list.out
  TEST    tests/qapi-schema/type-bypass-bad-gen.out
  TEST    tests/qapi-schema/unclosed-list.out
  TEST    tests/qapi-schema/unclosed-object.out
  TEST    tests/qapi-schema/unclosed-string.out
  TEST    tests/qapi-schema/unicode-str.out
  TEST    tests/qapi-schema/union-branch-case.out
  TEST    tests/qapi-schema/union-base-no-discriminator.out
  TEST    tests/qapi-schema/union-clash-branches.out
  TEST    tests/qapi-schema/union-empty.out
  TEST    tests/qapi-schema/union-invalid-base.out
  TEST    tests/qapi-schema/union-optional-branch.out
  TEST    tests/qapi-schema/union-unknown.out
  TEST    tests/qapi-schema/unknown-escape.out
  TEST    tests/qapi-schema/unknown-expr-key.out
  CC      tests/check-qdict.o
  CC      tests/test-char.o
  CC      tests/check-qfloat.o
  CC      tests/check-qint.o
  CC      tests/check-qstring.o
  CC      tests/check-qlist.o
  CC      tests/check-qnull.o
  CC      tests/check-qjson.o
  GEN     tests/test-qapi-visit.c
  CC      tests/test-qobject-output-visitor.o
  GEN     tests/test-qapi-types.c
  GEN     tests/test-qapi-event.c
  GEN     tests/test-qmp-introspect.c
  CC      tests/test-clone-visitor.o
  CC      tests/test-qobject-input-visitor.o
  CC      tests/test-qobject-input-strict.o
  CC      tests/test-qmp-commands.o
  GEN     tests/test-qmp-marshal.c
  CC      tests/test-string-input-visitor.o
  CC      tests/test-string-output-visitor.o
  CC      tests/test-qmp-event.o
  CC      tests/test-opts-visitor.o
  CC      tests/test-coroutine.o
  CC      tests/test-visitor-serialization.o
  CC      tests/test-iov.o
  CC      tests/test-aio.o
  CC      tests/test-throttle.o
  CC      tests/test-thread-pool.o
  CC      tests/test-hbitmap.o
  CC      tests/test-blockjob.o
  CC      tests/test-blockjob-txn.o
  CC      tests/test-xbzrle.o
  CC      tests/test-x86-cpuid.o
  CC      tests/test-vmstate.o
  CC      tests/test-cutils.o
  CC      tests/test-mul64.o
  CC      tests/test-int128.o
  CC      tests/rcutorture.o
  CC      tests/test-rcu-list.o
/tmp/qemu-test/src/tests/test-int128.c:180: warning: ‘__noclone__’ attribute directive ignored
  CC      tests/test-qdist.o
  CC      tests/test-qht.o
  CC      tests/test-qht-par.o
  CC      tests/qht-bench.o
  CC      tests/test-bitops.o
  CC      tests/check-qom-interface.o
  CC      tests/check-qom-proplist.o
  CC      tests/test-qemu-opts.o
  CC      tests/test-write-threshold.o
  CC      tests/test-crypto-hash.o
  CC      tests/test-crypto-cipher.o
  CC      tests/test-crypto-secret.o
  CC      tests/test-qga.o
  CC      tests/libqtest.o
  CC      tests/test-timed-average.o
  CC      tests/test-io-task.o
  CC      tests/test-io-channel-socket.o
  CC      tests/io-channel-helpers.o
  CC      tests/test-io-channel-file.o
  CC      tests/test-io-channel-command.o
  CC      tests/test-io-channel-buffer.o
  CC      tests/test-base64.o
  CC      tests/test-crypto-ivgen.o
  CC      tests/test-crypto-afsplit.o
  CC      tests/test-crypto-xts.o
  CC      tests/test-crypto-block.o
  CC      tests/test-logging.o
  CC      tests/test-replication.o
  CC      tests/test-bufferiszero.o
  CC      tests/test-uuid.o
  CC      tests/ptimer-test.o
  CC      tests/ptimer-test-stubs.o
  CC      tests/vhost-user-test.o
  CC      tests/libqos/pci.o
  CC      tests/libqos/fw_cfg.o
  CC      tests/libqos/malloc.o
  CC      tests/libqos/i2c.o
  CC      tests/libqos/libqos.o
  CC      tests/libqos/malloc-spapr.o
  CC      tests/libqos/libqos-spapr.o
  CC      tests/libqos/rtas.o
  CC      tests/libqos/pci-spapr.o
  CC      tests/libqos/pci-pc.o
  CC      tests/libqos/malloc-pc.o
  CC      tests/libqos/libqos-pc.o
  CC      tests/libqos/ahci.o
  CC      tests/libqos/virtio.o
  CC      tests/libqos/virtio-pci.o
  CC      tests/libqos/virtio-mmio.o
  CC      tests/libqos/malloc-generic.o
  CC      tests/endianness-test.o
  CC      tests/fdc-test.o
  CC      tests/ide-test.o
  CC      tests/ahci-test.o
  CC      tests/hd-geo-test.o
  CC      tests/boot-order-test.o
  CC      tests/bios-tables-test.o
  CC      tests/boot-sector.o
  CC      tests/boot-serial-test.o
  CC      tests/pxe-test.o
  CC      tests/rtc-test.o
  CC      tests/ipmi-kcs-test.o
  CC      tests/ipmi-bt-test.o
  CC      tests/i440fx-test.o
  CC      tests/fw_cfg-test.o
  CC      tests/drive_del-test.o
  CC      tests/wdt_ib700-test.o
  CC      tests/tco-test.o
  CC      tests/e1000-test.o
/tmp/qemu-test/src/tests/ide-test.c: In function ‘cdrom_pio_impl’:
/tmp/qemu-test/src/tests/ide-test.c:791: warning: ignoring return value of ‘fwrite’, declared with attribute warn_unused_result
/tmp/qemu-test/src/tests/ide-test.c: In function ‘test_cdrom_dma’:
/tmp/qemu-test/src/tests/ide-test.c:886: warning: ignoring return value of ‘fwrite’, declared with attribute warn_unused_result
  CC      tests/e1000e-test.o
  CC      tests/rtl8139-test.o
  CC      tests/pcnet-test.o
  CC      tests/eepro100-test.o
  CC      tests/ne2000-test.o
  CC      tests/nvme-test.o
  CC      tests/ac97-test.o
  CC      tests/es1370-test.o
  CC      tests/virtio-net-test.o
  CC      tests/virtio-balloon-test.o
  CC      tests/virtio-blk-test.o
  CC      tests/virtio-rng-test.o
  CC      tests/virtio-scsi-test.o
  CC      tests/virtio-serial-test.o
  CC      tests/virtio-console-test.o
  CC      tests/tpci200-test.o
  CC      tests/ipoctal232-test.o
  CC      tests/display-vga-test.o
  CC      tests/intel-hda-test.o
  CC      tests/ivshmem-test.o
  CC      tests/vmxnet3-test.o
  CC      tests/pvpanic-test.o
  CC      tests/i82801b11-test.o
  CC      tests/ioh3420-test.o
  CC      tests/usb-hcd-ohci-test.o
  CC      tests/libqos/usb.o
  CC      tests/usb-hcd-uhci-test.o
  CC      tests/usb-hcd-ehci-test.o
  CC      tests/usb-hcd-xhci-test.o
  CC      tests/pc-cpu-test.o
  CC      tests/q35-test.o
  CC      tests/test-netfilter.o
  CC      tests/test-filter-mirror.o
  CC      tests/test-filter-redirector.o
  CC      tests/postcopy-test.o
  CC      tests/test-x86-cpuid-compat.o
  CC      tests/device-introspect-test.o
  CC      tests/qom-test.o
  QTEST-x86_64 /tmp/qemu-test/src/tests/query-cpu-model-test.py
  LINK    tests/check-qdict
  LINK    tests/test-char
  LINK    tests/check-qfloat
  LINK    tests/check-qint
  LINK    tests/check-qstring
/tmp/qemu-test/src/tests/test-x86-cpuid-compat.c: In function ‘test_commas’:
/tmp/qemu-test/src/tests/test-x86-cpuid-compat.c:64: warning: implicit declaration of function ‘qom_get_bool’
/tmp/qemu-test/src/tests/test-x86-cpuid-compat.c:64: warning: nested extern declaration of ‘qom_get_bool’
  LINK    tests/check-qlist
  LINK    tests/check-qnull
  LINK    tests/check-qjson
  CC      tests/test-qapi-visit.o
  CC      tests/test-qapi-types.o
  CC      tests/test-qapi-event.o
  CC      tests/test-qmp-introspect.o
  CC      tests/test-qmp-marshal.o
  LINK    tests/test-coroutine
  LINK    tests/test-iov
  LINK    tests/test-aio
  LINK    tests/test-throttle
  LINK    tests/test-thread-pool
  LINK    tests/test-hbitmap
  LINK    tests/test-blockjob
======================================================================
ERROR: testKVMModels (__main__.CPUModelTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/qemu-test/src/tests/query-cpu-model-test.py", line 407, in testKVMModels
    if not self.kvm['present']:
AttributeError: 'CPUModelTest' object has no attribute 'kvm'

======================================================================
ERROR: testTCGModels (__main__.CPUModelTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/qemu-test/src/tests/query-cpu-model-test.py", line 401, in testTCGModels
    self.checkAllCPUModels()
  File "/tmp/qemu-test/src/tests/query-cpu-model-test.py", line 397, in checkAllCPUModels
    self.checkOneCPUModel(m)
  File "/tmp/qemu-test/src/tests/query-cpu-model-test.py", line 327, in checkOneCPUModel
    self.checkExpansions(model, msg)
  File "/tmp/qemu-test/src/tests/query-cpu-model-test.py", line 207, in checkExpansions
    self.tryGetProps(model, msg)
  File "/tmp/qemu-test/src/tests/query-cpu-model-test.py", line 119, in tryGetProps
    model['qom-props'] = self.runAndGetProps(model['model'])
  File "/tmp/qemu-test/src/tests/query-cpu-model-test.py", line 109, in runAndGetProps
    for p in IGNORE_QOM_PROPS.get(self.target['arch'], []):
AttributeError: 'CPUModelTest' object has no attribute 'target'

----------------------------------------------------------------------
Ran 2 tests in 0.696s

FAILED (errors=2)
make: *** [check-simpleqtest-/tmp/qemu-test/src/tests/query-cpu-model-test.py-x86_64] Error 1
make: *** Waiting for unfinished jobs....
make[1]: *** [docker-run] Error 2
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-vn6v5_5_/src'
make: *** [docker-run-test-quick@centos6] Error 2
=== OUTPUT END ===

Test command exited with code: 2


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion
  2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
                   ` (17 preceding siblings ...)
  2016-12-05  9:09 ` [Qemu-devel] [libvirt] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion no-reply
@ 2016-12-05 15:15 ` David Hildenbrand
  2016-12-05 17:11   ` Eduardo Habkost
  18 siblings, 1 reply; 35+ messages in thread
From: David Hildenbrand @ 2016-12-05 15:15 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: libvir-list, Markus Armbruster, Christian Borntraeger,
	Jason J. Herne, Cornelia Huck, Igor Mammedov, Jiri Denemark,
	Richard Henderson

Am 02.12.2016 um 22:17 schrieb Eduardo Habkost:
> This series implements query-cpu-model-expansion on target-i386.
>
> QAPI / interface changes
> ------------------------
>
> When implementing this, I have noticed that the "host" CPU model
> in i386 includes some migration-unsafe features that can't be
> translated to any migration-safe representation: "pmu", and
> "host-cache-info".
>
> To be able to handle the migration-unsafe features, I have
> extended the query-cpu-model-expansion definition to be clear
> about what happens to those features when the CPU model is
> expanded (in short: static expansion removes them, full expansion
> keeps them).

I think this makes sense. The important part is to really keep static 
expansion static :)

>
> I also added "static" and "migration-safe" fields to the return
> value of query-cpu-model-expansion, so callers can know if the
> the expanded representation is static and migration-safe.

Is static really needed? I can understand why migration-safe might be
of interest, but can't see how "static" could help (I mean we have
static expansion for this purpose). Do you have anything special in
mind regarding exposing "static"?

>
> Test code
> ---------
>
> I have added a Python test script for the feature, that will try
> multiple combinations of the expansion operation, and see if the
> returned data keeps matches some constratins.
>
> The test script works with the s390x query-cpu-model-expansion
> command, except that: 1) I couldn't test it with KVM; 2) qtest.py
> error handling when QEMU refuses to run is unreliable (so the
> script needs runnability information to be availble in TCG mode,
> too, to skip not-runnable CPU models and avoid problems).

Everything except "host" should behave completely the same on s390x
with or without KVM being active. So with !KVM tests we can already
cover most of the interesting parts. Thanks for taking care of s390x.

>
> Future versions of the test script could run a arch-specific
> CPUID-dump guest binary, and validate data seen by the guest
> directly. While we don't do that, the script validates all QOM
> properties on the CPU objects looking for unexpected changes. At
> least in the case of x86, the QOM properties will include lots of
> the CPUID data seen by the guest, giving us decent coverage.

Something like that would be cool. Unfortunately, e.g. on s390x some 
CPUID-like data (e.g. STFL(E) and SCP info) is only available from
kernel space. So we can't simply run a user space script. However,
something like a kernel module would be possible (or even something like 
the s390x pc-bios to simply read and dump the data).


-- 

David

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion
  2016-12-05 15:15 ` [Qemu-devel] " David Hildenbrand
@ 2016-12-05 17:11   ` Eduardo Habkost
  2016-12-05 18:13     ` David Hildenbrand
  0 siblings, 1 reply; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-05 17:11 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: qemu-devel, libvir-list, Markus Armbruster,
	Christian Borntraeger, Jason J. Herne, Cornelia Huck,
	Igor Mammedov, Jiri Denemark, Richard Henderson

On Mon, Dec 05, 2016 at 04:15:38PM +0100, David Hildenbrand wrote:
> Am 02.12.2016 um 22:17 schrieb Eduardo Habkost:
> > This series implements query-cpu-model-expansion on target-i386.
> > 
> > QAPI / interface changes
> > ------------------------
> > 
> > When implementing this, I have noticed that the "host" CPU model
> > in i386 includes some migration-unsafe features that can't be
> > translated to any migration-safe representation: "pmu", and
> > "host-cache-info".
> > 
> > To be able to handle the migration-unsafe features, I have
> > extended the query-cpu-model-expansion definition to be clear
> > about what happens to those features when the CPU model is
> > expanded (in short: static expansion removes them, full expansion
> > keeps them).
> 
> I think this makes sense. The important part is to really keep static
> expansion static :)
> 
> > 
> > I also added "static" and "migration-safe" fields to the return
> > value of query-cpu-model-expansion, so callers can know if the
> > the expanded representation is static and migration-safe.
> 
> Is static really needed? I can understand why migration-safe might be
> of interest, but can't see how "static" could help (I mean we have
> static expansion for this purpose). Do you have anything special in
> mind regarding exposing "static"?

I didn't have any specific use case in mind. My main worry is to
avoid letting management software make any assumptions about the
returned data. If we don't add an explicit "static" field, a
client might make some wrong assumptions just because some
conditions are known to be always true on existing
implementations. e.g.: a client could incorrectly assume that
"query-cpu-model-expansion type=full" of a migration-safe model
would always be static.


> 
> > 
> > Test code
> > ---------
> > 
> > I have added a Python test script for the feature, that will try
> > multiple combinations of the expansion operation, and see if the
> > returned data keeps matches some constratins.
> > 
> > The test script works with the s390x query-cpu-model-expansion
> > command, except that: 1) I couldn't test it with KVM; 2) qtest.py
> > error handling when QEMU refuses to run is unreliable (so the
> > script needs runnability information to be availble in TCG mode,
> > too, to skip not-runnable CPU models and avoid problems).
> 
> Everything except "host" should behave completely the same on s390x
> with or without KVM being active. So with !KVM tests we can already
> cover most of the interesting parts. Thanks for taking care of s390x.
> 
> > 
> > Future versions of the test script could run a arch-specific
> > CPUID-dump guest binary, and validate data seen by the guest
> > directly. While we don't do that, the script validates all QOM
> > properties on the CPU objects looking for unexpected changes. At
> > least in the case of x86, the QOM properties will include lots of
> > the CPUID data seen by the guest, giving us decent coverage.
> 
> Something like that would be cool. Unfortunately, e.g. on s390x some
> CPUID-like data (e.g. STFL(E) and SCP info) is only available from
> kernel space. So we can't simply run a user space script. However,
> something like a kernel module would be possible (or even something like the
> s390x pc-bios to simply read and dump the data).

I meant a kernel binary, above. On x86, there are existing test
cases on the autotest repository that run a very small kernel[1]
that simply dumps CPUID data to the serial console. We could
reuse it, or we could add a CPUID command to the qtest protocol.
I'm not sure what's the best solution.

We can try to use a similar approach on s390x to reuse code in
the test script, but we can add arch-specific code to it if
necessary.

[1] https://github.com/autotest/tp-qemu/tree/master/qemu/deps/cpuid/src

-- 
Eduardo

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion
  2016-12-05 17:11   ` Eduardo Habkost
@ 2016-12-05 18:13     ` David Hildenbrand
  2016-12-05 23:45       ` Eduardo Habkost
  0 siblings, 1 reply; 35+ messages in thread
From: David Hildenbrand @ 2016-12-05 18:13 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: qemu-devel, libvir-list, Markus Armbruster,
	Christian Borntraeger, Jason J. Herne, Cornelia Huck,
	Igor Mammedov, Jiri Denemark, Richard Henderson


>> Is static really needed? I can understand why migration-safe might be
>> of interest, but can't see how "static" could help (I mean we have
>> static expansion for this purpose). Do you have anything special in
>> mind regarding exposing "static"?
>
> I didn't have any specific use case in mind. My main worry is to
> avoid letting management software make any assumptions about the
> returned data. If we don't add an explicit "static" field, a
> client might make some wrong assumptions just because some
> conditions are known to be always true on existing
> implementations. e.g.: a client could incorrectly assume that
> "query-cpu-model-expansion type=full" of a migration-safe model
> would always be static.

I think "migration-safe" makes sense, as the doc currently states for
"@full": "The produced model is not guaranteed to be migration-safe".

For static expansion, this information is somewhat superfluous, as
"static CPU models are migration-safe", but it doesn't hurt. (and this
is also what you properly documented :) )

But I don't think that "static" will be of any use. If you want a
static model, go for "static" expansion. (I don't really see any use
case here, but if you do, keep it)


>> Something like that would be cool. Unfortunately, e.g. on s390x some
>> CPUID-like data (e.g. STFL(E) and SCP info) is only available from
>> kernel space. So we can't simply run a user space script. However,
>> something like a kernel module would be possible (or even something like the
>> s390x pc-bios to simply read and dump the data).
>
> I meant a kernel binary, above. On x86, there are existing test
> cases on the autotest repository that run a very small kernel[1]
> that simply dumps CPUID data to the serial console. We could
> reuse it, or we could add a CPUID command to the qtest protocol.
> I'm not sure what's the best solution.
>
> We can try to use a similar approach on s390x to reuse code in
> the test script, but we can add arch-specific code to it if
> necessary.

Ah, alright, so I wasn't aware of that because there is no autotest for
s390x (at least not that I know of ;) ). Thanks for the hint.

>
> [1] https://github.com/autotest/tp-qemu/tree/master/qemu/deps/cpuid/src
>


-- 

David

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 15/17] target-i386: Define static "base" CPU model
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 15/17] target-i386: Define static "base" CPU model Eduardo Habkost
@ 2016-12-05 18:18   ` David Hildenbrand
  2016-12-05 23:57     ` Eduardo Habkost
  0 siblings, 1 reply; 35+ messages in thread
From: David Hildenbrand @ 2016-12-05 18:18 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel

Am 02.12.2016 um 22:18 schrieb Eduardo Habkost:
> The query-cpu-model-expand QMP command needs at least one static
> model, to allow the "static" expansion mode to be implemented.
> Instead of defining static versions of every CPU model, define a
> "base" CPU model that has absolutely no feature flag enabled.
>

Introducing separate ones makes feature lists presented to the user much 
shorter (and therefore easier to maintain). But I don't know how libvirt 
wants to deal with models on x86 in the future.

How long is the static expansion on a recent intel CPU?


-- 

David

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion
  2016-12-05 18:13     ` David Hildenbrand
@ 2016-12-05 23:45       ` Eduardo Habkost
  0 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-05 23:45 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: qemu-devel, libvir-list, Markus Armbruster,
	Christian Borntraeger, Jason J. Herne, Cornelia Huck,
	Igor Mammedov, Jiri Denemark, Richard Henderson

On Mon, Dec 05, 2016 at 07:13:36PM +0100, David Hildenbrand wrote:
> 
> > > Is static really needed? I can understand why migration-safe might be
> > > of interest, but can't see how "static" could help (I mean we have
> > > static expansion for this purpose). Do you have anything special in
> > > mind regarding exposing "static"?
> > 
> > I didn't have any specific use case in mind. My main worry is to
> > avoid letting management software make any assumptions about the
> > returned data. If we don't add an explicit "static" field, a
> > client might make some wrong assumptions just because some
> > conditions are known to be always true on existing
> > implementations. e.g.: a client could incorrectly assume that
> > "query-cpu-model-expansion type=full" of a migration-safe model
> > would always be static.
> 
> I think "migration-safe" makes sense, as the doc currently states for
> "@full": "The produced model is not guaranteed to be migration-safe".
> 
> For static expansion, this information is somewhat superfluous, as
> "static CPU models are migration-safe", but it doesn't hurt. (and this
> is also what you properly documented :) )
> 
> But I don't think that "static" will be of any use. If you want a
> static model, go for "static" expansion. (I don't really see any use
> case here, but if you do, keep it)

Your point is valid, and the field is probably not strictly
necessary. But considering that the interface is not trivial, I
think it is a good thing to have extra metadata that can help
clients validate their assumptions. Even if it's useful in
practice only for debugging, it would be a good reason to add it,
IMO.

I first considered only updating the documentation to make the
guarantees explicit (so people won't assume that type=full
expansion is always a superset of static, or that type=static
expansion is always precise/ABI-compatible and will never lose
any features). But then I thought that returning extra metadata
would help people using the interface (and help us validate the
implementation on the test script).

Anyway, the next version of this series will have the new fields
added by a separate patch. This way we can evaluate and discuss
the interface changes separately.

-- 
Eduardo

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 15/17] target-i386: Define static "base" CPU model
  2016-12-05 18:18   ` David Hildenbrand
@ 2016-12-05 23:57     ` Eduardo Habkost
  2016-12-06  9:32       ` David Hildenbrand
  2016-12-16 16:02       ` Jiri Denemark
  0 siblings, 2 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-05 23:57 UTC (permalink / raw)
  To: David Hildenbrand; +Cc: qemu-devel, libvir-list, Jiri Denemark

On Mon, Dec 05, 2016 at 07:18:47PM +0100, David Hildenbrand wrote:
> Am 02.12.2016 um 22:18 schrieb Eduardo Habkost:
> > The query-cpu-model-expand QMP command needs at least one static
> > model, to allow the "static" expansion mode to be implemented.
> > Instead of defining static versions of every CPU model, define a
> > "base" CPU model that has absolutely no feature flag enabled.
> > 
> 
> Introducing separate ones makes feature lists presented to the user much
> shorter (and therefore easier to maintain). But I don't know how libvirt
> wants to deal with models on x86 in the future.

I understand that having a larger set of static models would make
expansions shorter. But I worry that by defining a complete set
of static models on x86 would require extra maintenance work on
the QEMU side with no visible benefit for libvirt.

I would like to hear from libvirt developers what they think. I
still don't know what they plan to use the type=static expansion
results for.

> 
> How long is the static expansion on a recent intel CPU?

CPU model "Broadwell" returns 165 entries on return.model.props:

(QEMU) query-cpu-model-expansion type=static model={"name":"Broadwell"}
{"return": {"migration-safe": true, "model": {"name": "base", "props": {"pfthreshold": false, "pku": false, "rtm": true, "tsc-deadline": true, "xstore-en": false, "tsc-scale": false, "abm": true, "ia64": false, "kvm-mmu": false, "xsaveopt": true, "tce": false, "smep": true, "fpu": true, "xcrypt": false, "clflush": true, "flushbyasid": false, "kvm-steal-time": false, "lm": true, "tsc": true, "adx": true, "fxsr": true, "tm": false, "xgetbv1": false, "xstore": false, "vme": false, "vendor": "GenuineIntel", "arat": true, "de": true, "aes": true, "pse": true, "ds-cpl": false, "tbm": false, "sse": true, "phe-en": false, "f16c": true, "ds": false, "mpx": false, "tsc-adjust": false, "avx512f": false, "avx2": true, "pbe": false, "cx16": true, "avx512pf": false, "movbe": true, "perfctr-nb": false, "ospke": false, "avx512ifma": false, "stepping": 2, "sep": true, "sse4a": false, "avx512dq": false, "avx512-4vnniw": false, "xsave": true, "pmm": false, "hle": true, "est": false, "xop": false, "smx": false, "monitor": false, "avx512er": false, "apic": true, "sse4.1": true, "sse4.2": true, "pause-filter": false, "lahf-lm": true, "kvm-nopiodelay": false, "acpi": false, "mmx": true, "osxsave": false, "pcommit": false, "mtrr": true, "clwb": false, "dca": false, "pdcm": false, "xcrypt-en": false, "3dnow": false, "invtsc": false, "tm2": false, "hypervisor": true, "kvmclock-stable-bit": false, "fxsr-opt": false, "pcid": true, "lbrv": false, "avx512-4fmaps": false, "svm-lock": false, "popcnt": true, "nrip-save": false, "avx512vl": false, "x2apic": true, "kvmclock": false, "smap": true, "family": 6, "min-level": 13, "dtes64": false, "ace2": false, "fma4": false, "xtpr": false, "avx512bw": false, "nx": true, "lwp": false, "msr": true, "ace2-en": false, "decodeassists": false, "perfctr-core": false, "pge": true, "pn": false, "fma": true, "nodeid-msr": false, "cx8": true, "mce": true, "avx512cd": false, "cr8legacy": false, "mca": true, "pni": true, "rdseed": true, "osvw": false, "fsgsbase": true, "model-id": "Intel Core Processor (Broadwell)", "cmp-legacy": false, "kvm-pv-unhalt": false, "rdtscp": true, "mmxext": false, "cid": false, "vmx": false, "ssse3": true, "extapic": false, "pse36": true, "min-xlevel": 2147483656, "ibs": false, "avx": true, "syscall": true, "umip": false, "invpcid": true, "bmi1": true, "bmi2": true, "vmcb-clean": false, "erms": true, "cmov": true, "misalignsse": false, "clflushopt": false, "pat": true, "3dnowprefetch": true, "rdpid": false, "pae": true, "wdt": false, "skinit": false, "pmm-en": false, "phe": false, "3dnowext": false, "lmce": false, "ht": false, "pdpe1gb": false, "kvm-pv-eoi": false, "npt": false, "xsavec": false, "pclmulqdq": true, "svm": false, "sse2": true, "ss": false, "topoext": false, "rdrand": true, "avx512vbmi": false, "kvm-asyncpf": false, "xsaves": false, "model": 61}}, "static": true}}


-- 
Eduardo

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 15/17] target-i386: Define static "base" CPU model
  2016-12-05 23:57     ` Eduardo Habkost
@ 2016-12-06  9:32       ` David Hildenbrand
  2016-12-06 12:43         ` Eduardo Habkost
  2016-12-16 16:02       ` Jiri Denemark
  1 sibling, 1 reply; 35+ messages in thread
From: David Hildenbrand @ 2016-12-06  9:32 UTC (permalink / raw)
  To: Eduardo Habkost; +Cc: qemu-devel, libvir-list, Jiri Denemark

Am 06.12.2016 um 00:57 schrieb Eduardo Habkost:
> On Mon, Dec 05, 2016 at 07:18:47PM +0100, David Hildenbrand wrote:
>> Am 02.12.2016 um 22:18 schrieb Eduardo Habkost:
>>> The query-cpu-model-expand QMP command needs at least one static
>>> model, to allow the "static" expansion mode to be implemented.
>>> Instead of defining static versions of every CPU model, define a
>>> "base" CPU model that has absolutely no feature flag enabled.
>>>
>>
>> Introducing separate ones makes feature lists presented to the user much
>> shorter (and therefore easier to maintain). But I don't know how libvirt
>> wants to deal with models on x86 in the future.
>
> I understand that having a larger set of static models would make
> expansions shorter. But I worry that by defining a complete set
> of static models on x86 would require extra maintenance work on
> the QEMU side with no visible benefit for libvirt.

As static models will never change (theory) the maintenance work should 
be pretty much down to zero. But the initial implementation and comming 
up with the models requires work (my experience ;) ).

I am not against the "base" model (actually it is really pretty nice to 
have). Using only that somehow smells like the "user" cpu model 
discussion. Which might be ok for x86.

>
> I would like to hear from libvirt developers what they think. I
> still don't know what they plan to use the type=static expansion
> results for.
>
>>
>> How long is the static expansion on a recent intel CPU?
>
> CPU model "Broadwell" returns 165 entries on return.model.props:
>
> (QEMU) query-cpu-model-expansion type=static model={"name":"Broadwell"}

> {"return": {"migration-safe": true, "model": {"name": "base", "props": {"pfthreshold": false, "pku": false, "rtm": true, "tsc-deadline": true, "xstore-en": false, "tsc-scale": false, "abm": true, "ia64": false, "kvm-mmu": false, "xsaveopt": true, "tce": false, "smep": true, "fpu": true, "xcrypt": false, "clflush": true, "flushbyasid": false, "kvm-steal-time": false, "lm": true, "tsc": true, "adx": true, "fxsr": true, "tm": false, "xgetbv1": false, "xstore": false, "vme": false, "vendor": "GenuineIntel", "arat": true, "de": true, "aes": true, "pse": true, "ds-cpl": false, "tbm": false, "sse": true, "phe-en": false, "f16c": true, "ds": false, "mpx": false, "tsc-adjust": false, "avx512f": false, "avx2": true, "pbe": false, "cx16": true, "avx512pf": false, "movbe": true, "perfctr-nb": false, "ospke": false, "avx512ifma": false, "stepping": 2, "sep": true, "sse4a": false, "avx512dq": false, "avx512-4vnniw": false, "xsave": true, "pmm": false, "hle": true, "est": false, "xop": false, "smx": false, "monitor": false, "avx512er": false, "apic": true, "sse4.1": true, "sse4.2": true, "pause-filter": false, "lahf-lm": true, "kvm-nopiodelay": false, "acpi": false, "mmx": true, "osxsave": false, "pcommit": false, "mtrr": true, "clwb": false, "dca": false, "pdcm": false, "xcrypt-en": false, "3dnow": false, "invtsc": false, "tm2": false, "hypervisor": true, "kvmclock-stable-bit": false, "fxsr-opt": false, "pcid": true, "lbrv": false, "avx512-4fmaps": false, "svm-lock": false, "popcnt": true, "nrip-save": false, "avx512vl": false, "x2apic": true, "kvmclock": false, "smap": true, "family": 6, "min-level": 13, "dtes64": false, "ace2": false, "fma4": false, "xtpr": false, "avx512bw": false, "nx": true, "lwp": false, "msr": true, "ace2-en": false, "decodeassists": false, "perfctr-core": false, "pge": true, "pn": false, "fma": true, "nodeid-msr": false, "cx8": true, "mce": true, "avx512cd": false, "cr8legacy": false, "mca": true, "pni": true, "rdseed": true, "osvw": false, "fsgsbase": true, "model-id": "Intel Core Processor (Broadwell)", "cmp-legacy": false, "kvm-pv-unhalt": false, "rdtscp": true, "mmxext": false, "cid": false, "vmx": false, "ssse3": true, "extapic": false, "pse36": true, "min-xlevel": 2147483656, "ibs": false, "avx": true, "syscall": true, "umip": false, "invpcid": true, "bmi1": true, "bmi2": true, "vmcb-clean": false, "erms": true, "cmov": true, "misalignsse": false, "clflushopt": false, "pat": true, "3dnowprefetch": true, "rdpid": false, "pae": true, "wdt": false, "skinit": false, "pmm-en": false, "phe": false, "3dnowext": false, "lmce": false, "ht": false, "pdpe1gb": false, "kvm-pv-eoi": false, "npt": false, "xsavec": false, "pclmulqdq": true, "svm": false, "sse2": true, "ss": false, "topoext": false, "rdrand": true, "avx512vbmi": false, "kvm-asyncpf": false, "xsaves": false, "model": 61}}, "static": true}}
>
>

Wow, yes that was the reason for me to introduce abstractions on s390x. 
But here the plan was to use the epansion directly when indication the
"host" model to the user. Having something like "Broadwell-base"+/- a 
handful of features is just easier to handle than "base" with 165 
feature flags. But as we don't know what libvirt plans are (they could 
use that interface on x86 to do feature detection only and convert to 
models themselves), I also have no idea what would be best in the 
context of x86 cpu models.

-- 

David

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 15/17] target-i386: Define static "base" CPU model
  2016-12-06  9:32       ` David Hildenbrand
@ 2016-12-06 12:43         ` Eduardo Habkost
  0 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-06 12:43 UTC (permalink / raw)
  To: David Hildenbrand; +Cc: qemu-devel, libvir-list, Jiri Denemark

On Tue, Dec 06, 2016 at 10:32:48AM +0100, David Hildenbrand wrote:
[...]
> > 
> > I would like to hear from libvirt developers what they think. I
> > still don't know what they plan to use the type=static expansion
> > results for.
> > 
> > > 
> > > How long is the static expansion on a recent intel CPU?
> > 
> > CPU model "Broadwell" returns 165 entries on return.model.props:
> > 
> > (QEMU) query-cpu-model-expansion type=static model={"name":"Broadwell"}
> 
> > {"return": {"migration-safe": true, "model": {"name": "base", "props": {"pfthreshold": false, "pku": false, "rtm": true, "tsc-deadline": true, "xstore-en": false, "tsc-scale": false, "abm": true, "ia64": false, "kvm-mmu": false, "xsaveopt": true, "tce": false, "smep": true, "fpu": true, "xcrypt": false, "clflush": true, "flushbyasid": false, "kvm-steal-time": false, "lm": true, "tsc": true, "adx": true, "fxsr": true, "tm": false, "xgetbv1": false, "xstore": false, "vme": false, "vendor": "GenuineIntel", "arat": true, "de": true, "aes": true, "pse": true, "ds-cpl": false, "tbm": false, "sse": true, "phe-en": false, "f16c": true, "ds": false, "mpx": false, "tsc-adjust": false, "avx512f": false, "avx2": true, "pbe": false, "cx16": true, "avx512pf": false, "movbe": true, "perfctr-nb": false, "ospke": false, "avx512ifma": false, "stepping": 2, "sep": true, "sse4a": false, "avx512dq": false, "avx512-4vnniw": false, "xsave": true, "pmm": false, "hle": true, "est": false, "xop": false, "smx": false, "monitor": false, "avx512er": false, "apic": true, "sse4.1": true, "sse4.2": true, "pause-filter": false, "lahf-lm": true, "kvm-nopiodelay": false, "acpi": false, "mmx": true, "osxsave": false, "pcommit": false, "mtrr": true, "clwb": false, "dca": false, "pdcm": false, "xcrypt-en": false, "3dnow": false, "invtsc": false, "tm2": false, "hypervisor": true, "kvmclock-stable-bit": false, "fxsr-opt": false, "pcid": true, "lbrv": false, "avx512-4fmaps": false, "svm-lock": false, "popcnt": true, "nrip-save": false, "avx512vl": false, "x2apic": true, "kvmclock": false, "smap": true, "family": 6, "min-level": 13, "dtes64": false, "ace2": false, "fma4": false, "xtpr": false, "avx512bw": false, "nx": true, "lwp": false, "msr": true, "ace2-en": false, "decodeassists": false, "perfctr-core": false, "pge": true, "pn": false, "fma": true, "nodeid-msr": false, "cx8": true, "mce": true, "avx512cd": false, "cr8legacy": false, "mca": true, "pni": true, "rdseed": true, "osvw": false, "fsgsbase": true, "model-id": "Intel Core Processor (Broadwell)", "cmp-legacy": false, "kvm-pv-unhalt": false, "rdtscp": true, "mmxext": false, "cid": false, "vmx": false, "ssse3": true, "extapic": false, "pse36": true, "min-xlevel": 2147483656, "ibs": false, "avx": true, "syscall": true, "umip": false, "invpcid": true, "bmi1": true, "bmi2": true, "vmcb-clean": false, "erms": true, "cmov": true, "misalignsse": false, "clflushopt": false, "pat": true, "3dnowprefetch": true, "rdpid": false, "pae": true, "wdt": false, "skinit": false, "pmm-en": false, "phe": false, "3dnowext": false, "lmce": false, "ht": false, "pdpe1gb": false, "kvm-pv-eoi": false, "npt": false, "xsavec": false, "pclmulqdq": true, "svm": false, "sse2": true, "ss": false, "topoext": false, "rdrand": true, "avx512vbmi": false, "kvm-asyncpf": false, "xsaves": false, "model": 61}}, "static": true}}
> > 
> > 
> 
> Wow, yes that was the reason for me to introduce abstractions on s390x. But
> here the plan was to use the epansion directly when indication the
> "host" model to the user. Having something like "Broadwell-base"+/- a
> handful of features is just easier to handle than "base" with 165 feature
> flags. But as we don't know what libvirt plans are (they could use that
> interface on x86 to do feature detection only and convert to models
> themselves), I also have no idea what would be best in the context of x86
> cpu models.

In the case of x86, libvirt already has their own database of
"static" CPU models in /usr/share/libvirt/cpu_map.xml. Maybe
providing our own set of static CPU models would be helpful if
they want to get rid of their database. But I'm not sure if:
1) they want to do that in the near future; 2) how easily they
could keep compatibility with their existing model names while
doing that.

-- 
Eduardo

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 14/17] qapi: add static/migration-safe info to query-cpu-model-expansion
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 14/17] qapi: add static/migration-safe info to query-cpu-model-expansion Eduardo Habkost
@ 2016-12-13  9:47   ` Markus Armbruster
  2016-12-13 12:46     ` Eduardo Habkost
  0 siblings, 1 reply; 35+ messages in thread
From: Markus Armbruster @ 2016-12-13  9:47 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: qemu-devel, David Hildenbrand, libvir-list,
	Christian Borntraeger, Jason J. Herne, Cornelia Huck,
	Jiri Denemark

I'm not familiar with CPU model expansion, but here goes anyway.

Eduardo Habkost <ehabkost@redhat.com> writes:

> On x86, "-cpu host" enables some features that can't be
> represented by a static CPU model definition: cache info
> passthrough ("host-cache-info") and PMU passthrough ("pmu"). This
> means a type=static expansion of "host" can't include those
> features.
>
> A type=full expansion of "host", on the other hand, can include
> those features, but then the returned data won't be a static CPU
> model representation.
>
> Add a note to the documentation explaining that when using CPU
> models that include non-migration-safe features, users need to
> choose being precision and safety: a precise expansion of the CPU

s/being/between/

> model (full) won't be safe (static), (because they would include

s/they/it/

> pmu=on and host-cache-info=on), and a safe (static) expansion of
> the CPU model won't be precise.
>
> Architectures where CPU model expansion is always migration-safe
> (e.g. s390x) can simply do what they already do, and set
> 'migration-safe' and 'static' to true.

This patch does that exactly for s390x.  The next patch looks like it
does something for x86.  What about other targets?  I recommend to have
this commit message explain briefly what this patch does, what later
patches in this series do, and what's left for later (if anything).

> Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
> Cc: Christian Borntraeger <borntraeger@de.ibm.com>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: libvir-list@redhat.com
> Cc: Jiri Denemark <jdenemar@redhat.com>
> Cc: "Jason J. Herne" <jjherne@linux.vnet.ibm.com>
> Cc: Markus Armbruster <armbru@redhat.com>
> Cc: Eric Blake <eblake@redhat.com>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
>  qapi-schema.json          | 25 ++++++++++++++++++++++++-
>  target-s390x/cpu_models.c |  4 ++++
>  2 files changed, 28 insertions(+), 1 deletion(-)
>
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 8d113f8..a102534 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -3291,6 +3291,15 @@
>  #        migration-safe, but allows tooling to get an insight and work with
>  #        model details.
>  #
> +# Note: When a non-migration-safe CPU model is expanded in static mode, some
> +# features enabled by the CPU model may be omitted, because they can't be
> +# implemented by a static CPU model definition (e.g. cache info passthrough and
> +# PMU passthrough in x86). If you need an accurate representation of the
> +# features enabled by a non-migration-safe CPU model, use @full. If you need a
> +# static representation that will keep ABI compatibility even when changing QEMU
> +# version or machine-type, use @static (but keep in mind that some features may
> +# be omitted).
> +#
>  # Since: 2.8.0
>  ##
>  { 'enum': 'CpuModelExpansionType',
> @@ -3304,10 +3313,24 @@
>  #
>  # @model: the expanded CpuModelInfo.
>  #
> +# @migration-safe: the expanded CPU model in @model is a migration-safe
> +#                  CPU model. See @CpuDefinitionInfo.migration-safe.
> +#                  If expansion type was @static, this is always true.
> +#                  (since 2.9)
> +#
> +# @static: the expanded CPU model in @model is a static CPU model.
> +#          See @CpuDefinitionInfo.static. If expansion type was @static,
> +#          this is always true.
> +#          (since 2.9)
> +#
> +# query-cpu-model-expansion with static expansion type should always
> +# return a static and migration-safe expansion.
> +#
>  # Since: 2.8.0
>  ##
>  { 'struct': 'CpuModelExpansionInfo',
> -  'data': { 'model': 'CpuModelInfo' } }
> +  'data': { 'model': 'CpuModelInfo', 'static': 'bool',
> +            'migration-safe': 'bool' } }
>  
>  
>  ##
> diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
> index 5b66d33..f934add 100644
> --- a/target-s390x/cpu_models.c
> +++ b/target-s390x/cpu_models.c
> @@ -448,6 +448,10 @@ CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type
>      /* convert it back to a static representation */
>      expansion_info = g_malloc0(sizeof(*expansion_info));
>      expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
> +
> +    /* We always expand to a static and migration-safe CpuModelInfo */
> +    expansion_info->q_static = true;
> +    expansion_info->migration_safe = true;
>      cpu_info_from_model(expansion_info->model, &s390_model, delta_changes);
>      return expansion_info;
>  }

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 17/17] target-i386: Implement query-cpu-model-expansion QMP command
  2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 17/17] target-i386: Implement query-cpu-model-expansion QMP command Eduardo Habkost
@ 2016-12-13 10:16   ` Markus Armbruster
  2016-12-13 12:55     ` Eduardo Habkost
  0 siblings, 1 reply; 35+ messages in thread
From: Markus Armbruster @ 2016-12-13 10:16 UTC (permalink / raw)
  To: Eduardo Habkost; +Cc: qemu-devel, libvir-list, Jiri Denemark

Eduardo Habkost <ehabkost@redhat.com> writes:

> Implement query-cpu-model-expansion for target-i386.
>
> The code needs to be careful to handle non-migration-safe
> features ("pmu" and "host-cache-info") according to the expansion
> type.
>
> Cc: libvir-list@redhat.com
> Cc: Jiri Denemark <jdenemar@redhat.com>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
>  tests/Makefile.include |   3 +
>  monitor.c              |   4 +-
>  target-i386/cpu.c      | 195 ++++++++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 200 insertions(+), 2 deletions(-)
>
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index 63c4347..c7bbfca 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -251,6 +251,9 @@ check-qtest-x86_64-y += $(check-qtest-i386-y)
>  gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
>  gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
>  
> +check-simpleqtest-x86_64-y += $(SRC_PATH)/tests/query-cpu-model-test.py
> +check-simpleqtest-i386-y += $(SRC_PATH)/tests/query-cpu-model-test.py
> +
>  check-qtest-alpha-y = tests/boot-serial-test$(EXESUF)
>  
>  check-qtest-mips-y = tests/endianness-test$(EXESUF)
> diff --git a/monitor.c b/monitor.c
> index 0841d43..90c12b3 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -983,8 +983,10 @@ static void qmp_unregister_commands_hack(void)
>  #ifndef TARGET_ARM
>      qmp_unregister_command("query-gic-capabilities");
>  #endif
> -#if !defined(TARGET_S390X)
> +#if !defined(TARGET_S390X) && !defined(TARGET_I386)
>      qmp_unregister_command("query-cpu-model-expansion");
> +#endif
> +#if !defined(TARGET_S390X)
>      qmp_unregister_command("query-cpu-model-baseline");
>      qmp_unregister_command("query-cpu-model-comparison");
>  #endif
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index bf4ac09..198014a 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -29,10 +29,14 @@
>  #include "qemu/option.h"
>  #include "qemu/config-file.h"
>  #include "qapi/qmp/qerror.h"
> +#include "qapi/qmp/qstring.h"
> +#include "qapi/qmp/qdict.h"
> +#include "qapi/qmp/qbool.h"
>  
>  #include "qapi-types.h"
>  #include "qapi-visit.h"
>  #include "qapi/visitor.h"
> +#include "qom/qom-qobject.h"
>  #include "sysemu/arch_init.h"
>  
>  #if defined(CONFIG_KVM)
> @@ -2259,7 +2263,7 @@ static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
>      }
>  }
>  
> -/* Load data from X86CPUDefinition
> +/* Load data from X86CPUDefinition into a X86CPU object
>   */
>  static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
>  {
> @@ -2268,6 +2272,11 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
>      char host_vendor[CPUID_VENDOR_SZ + 1];
>      FeatureWord w;
>  
> +    /*NOTE: any property set by this function should be returned by

Space between /* and comment text, please.

Also, consider adding wings to both ends of multi-line comments.

> +     * x86_cpu_to_dict(), so CPU model data returned by
> +     * query-cpu-model-expansion is always complete.
> +     */
> +
>      /* CPU models only set _minimum_ values for level/xlevel: */
>      object_property_set_int(OBJECT(cpu), def->level, "min-level", errp);
>      object_property_set_int(OBJECT(cpu), def->xlevel, "min-xlevel", errp);
> @@ -2312,6 +2321,190 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
>  
>  }
>  
> +/* Convert CPU model data from X86CPU object to a property dictionary
> + * that can recreate exactly the same CPU model.
> + *
> + * This function does the opposite of x86_cpu_load_def(). Any
> + * property changed by x86_cpu_load_def() or instance_init
> + * methods should be returned by this function too.
> + */
> +static void x86_cpu_to_dict(X86CPU *cpu, QDict *props, Error **errp)
> +{
> +    Object *obj = OBJECT(cpu);
> +    FeatureWord w;
> +    PropValue *pv;
> +
> +    /* This code could simply iterate over all writeable properties in the
> +     * CPU object, and return all of them. But then the aliases properties

"alias properties"?

> +     * would be returned as well. Returning only the known features
> +     * is more reliable.
> +     */
> +    qdict_put_obj(props, "min-level",
> +                  object_property_get_qobject(obj, "min-level", errp));
> +    qdict_put_obj(props, "min-xlevel",
> +                  object_property_get_qobject(obj, "min-xlevel", errp));
> +
> +    qdict_put_obj(props, "family",
> +                  object_property_get_qobject(obj, "family", errp));
> +    qdict_put_obj(props, "model",
> +                  object_property_get_qobject(obj, "model", errp));
> +    qdict_put_obj(props, "stepping",
> +                  object_property_get_qobject(obj, "stepping", errp));
> +    qdict_put_obj(props, "model-id",
> +                  object_property_get_qobject(obj, "model-id", errp));

Incorrect use of the error API: if more than one call fails, the second
failure will trip the assertion in error_setv().

If errors should not happen here, use &error_abort.

If errors need to be handled, see "Receive and accumulate multiple
errors" in error.h.

Consider "more than four, use a for":

       static char *prop_name[] = {
           "min-level", "min-xlevel", "family", "model", "stepping",
           "model-id", NULL
       };

       for (pname = prop_name; *pname, pname++) {
           qdict_put_obj(props, *pname,
                         object_property_get_qobject(obj, *pname,
                                                     &error_abort));
       }

> +
> +    for (w = 0; w < FEATURE_WORDS; w++) {
> +        FeatureWordInfo *fi = &feature_word_info[w];
> +        int bit;
> +        for (bit = 0; bit < 32; bit++) {
> +            if (!fi->feat_names[bit]) {
> +                continue;
> +            }
> +            qdict_put_obj(props, fi->feat_names[bit],
> +                          object_property_get_qobject(obj, fi->feat_names[bit],
> +                                                      errp));
> +        }
> +    }
> +
> +    for (pv = kvm_default_props; pv->prop; pv++) {
> +        qdict_put_obj(props, pv->prop,
> +                      object_property_get_qobject(obj, pv->prop, errp));
> +    }
> +    for (pv = tcg_default_props; pv->prop; pv++) {
> +        qdict_put_obj(props, pv->prop,
> +                      object_property_get_qobject(obj, pv->prop, errp));
> +    }
> +
> +    qdict_put_obj(props, "vendor",
> +                  object_property_get_qobject(obj, "vendor", errp));
> +
> +    /* Set by "host": */
> +    qdict_put_obj(props, "lmce",
> +                  object_property_get_qobject(obj, "lmce", errp));
> +    qdict_put_obj(props, "pmu",
> +                  object_property_get_qobject(obj, "pmu", errp));
> +
> +
> +    /* Other properties configurable by the user: */
> +    qdict_put_obj(props, "host-cache-info",
> +                  object_property_get_qobject(obj, "host-cache-info", errp));
> +}
> +
> +static void object_apply_props(Object *obj, QDict *props, Error **errp)
> +{
> +    const QDictEntry *prop;
> +    Error *err = NULL;
> +
> +    for (prop = qdict_first(props); prop; prop = qdict_next(props, prop)) {
> +        object_property_set_qobject(obj, qdict_entry_value(prop),
> +                                         qdict_entry_key(prop), &err);
> +        if (err) {
> +            break;
> +        }
> +    }
> +
> +    error_propagate(errp, err);
> +}
> +
> +static X86CPU *x86_cpu_from_model(CpuModelInfo *model, Error **errp)
> +{
> +    X86CPU *xc = NULL;
> +    X86CPUClass *xcc;
> +    Error *err = NULL;
> +
> +    xcc = X86_CPU_CLASS(cpu_class_by_name(TYPE_X86_CPU, model->name));
> +    if (xcc == NULL) {
> +        error_setg(&err, "CPU model '%s' not found", model->name);
> +        goto out;
> +    }
> +
> +    xc = X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc))));
> +    if (model->has_props) {
> +        QDict *d = qobject_to_qdict(model->props);
> +        if (!d) {
> +            error_setg(&err, "model.props must be a dictionary");
> +            goto out;

How can this happen?

> +        }
> +        object_apply_props(OBJECT(xc), d, &err);
> +        if (err) {
> +            goto out;
> +        }
> +    }
> +
> +    x86_cpu_expand_features(xc, &err);
> +    if (err) {
> +        goto out;
> +    }
> +
> +out:
> +    if (err) {
> +        error_propagate(errp, err);
> +        object_unref(OBJECT(xc));
> +        xc = NULL;
> +    }
> +    return xc;
> +}
> +
> +CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
> +                                                      CpuModelInfo *model,
> +                                                      Error **errp)
> +{
> +    X86CPU *xc = NULL;
> +    Error *err = NULL;
> +    CpuModelExpansionInfo *ret = g_new0(CpuModelExpansionInfo, 1);
> +    QDict *props;
> +
> +    xc = x86_cpu_from_model(model, &err);
> +    if (err) {
> +        goto out;
> +    }
> +
> +    /* We currently always do full expansion */

This comment made me go "wait, we do full expansion even when @type is
CPU_MODEL_EXPANSION_TYPE_STATIC?"  Looks like we first to full
expansion, then correct the result according to type.

> +    ret->model = g_new0(CpuModelInfo, 1);
> +    ret->model->name = g_strdup("base"); /* the only static model */
> +    props = qdict_new();
> +    ret->model->props = QOBJECT(props);
> +    ret->model->has_props = true;
> +    x86_cpu_to_dict(xc, props, &err);
> +
> +    /* Some features (pmu, host-cache-info) are not migration-safe,
> +     * and are handled differently depending on expansion type:
> +     */
> +    if (type ==  CPU_MODEL_EXPANSION_TYPE_STATIC) {

Single space after ==, please.

> +        /* static expansion force migration-unsafe features off: */
> +        ret->q_static = ret->migration_safe = true;
> +        qdict_del(props, "pmu");
> +        qdict_del(props, "host-cache-info");
> +    } else if (type == CPU_MODEL_EXPANSION_TYPE_FULL) {
> +        QObject *o;
> +        /* full expansion clear the static/migration-safe flags
> +         * to indicate migration-unsafe features are on:
> +         */
> +        ret->q_static = true;
> +        ret->migration_safe = true;
> +
> +        o = qdict_get(props, "pmu");
> +        if (o && qbool_get_bool(qobject_to_qbool(o))) {
> +            ret->q_static = ret->migration_safe = false;
> +        }
> +        o = qdict_get(props, "host-cache-info");
> +        if (o && qbool_get_bool(qobject_to_qbool(o))) {
> +            ret->q_static = ret->migration_safe = false;
> +        }
> +    } else {
> +        error_setg(&err, "The requested expansion type is not supported.");

How can this happen?

If it can, it bombs when x86_cpu_to_dict() already set an error (see
"use of the error API" above).

> +    }
> +
> +out:
> +    object_unref(OBJECT(xc));
> +    if (err) {
> +        error_propagate(errp, err);
> +        qapi_free_CpuModelExpansionInfo(ret);
> +        ret = NULL;
> +    }
> +    return ret;
> +}
> +
>  X86CPU *cpu_x86_init(const char *cpu_model)
>  {
>      return X86_CPU(cpu_generic_init(TYPE_X86_CPU, cpu_model));

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 14/17] qapi: add static/migration-safe info to query-cpu-model-expansion
  2016-12-13  9:47   ` Markus Armbruster
@ 2016-12-13 12:46     ` Eduardo Habkost
  0 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-13 12:46 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: qemu-devel, David Hildenbrand, libvir-list,
	Christian Borntraeger, Jason J. Herne, Cornelia Huck,
	Jiri Denemark

On Tue, Dec 13, 2016 at 10:47:38AM +0100, Markus Armbruster wrote:
> I'm not familiar with CPU model expansion, but here goes anyway.
> 
> Eduardo Habkost <ehabkost@redhat.com> writes:
> 
> > On x86, "-cpu host" enables some features that can't be
> > represented by a static CPU model definition: cache info
> > passthrough ("host-cache-info") and PMU passthrough ("pmu"). This
> > means a type=static expansion of "host" can't include those
> > features.
> >
> > A type=full expansion of "host", on the other hand, can include
> > those features, but then the returned data won't be a static CPU
> > model representation.
> >
> > Add a note to the documentation explaining that when using CPU
> > models that include non-migration-safe features, users need to
> > choose being precision and safety: a precise expansion of the CPU
> 
> s/being/between/
> 
> > model (full) won't be safe (static), (because they would include
> 
> s/they/it/

Oops. Thanks!

> 
> > pmu=on and host-cache-info=on), and a safe (static) expansion of
> > the CPU model won't be precise.
> >
> > Architectures where CPU model expansion is always migration-safe
> > (e.g. s390x) can simply do what they already do, and set
> > 'migration-safe' and 'static' to true.
> 
> This patch does that exactly for s390x.  The next patch looks like it
> does something for x86.  What about other targets?  I recommend to have
> this commit message explain briefly what this patch does, what later
> patches in this series do, and what's left for later (if anything).

s390x is the only architecture implementing
query-cpu-model-expansion by now.

I will add a comment clarifying that, anyway.

> 
> > Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
> > Cc: Christian Borntraeger <borntraeger@de.ibm.com>
> > Cc: David Hildenbrand <david@redhat.com>
> > Cc: libvir-list@redhat.com
> > Cc: Jiri Denemark <jdenemar@redhat.com>
> > Cc: "Jason J. Herne" <jjherne@linux.vnet.ibm.com>
> > Cc: Markus Armbruster <armbru@redhat.com>
> > Cc: Eric Blake <eblake@redhat.com>
> > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > ---
> >  qapi-schema.json          | 25 ++++++++++++++++++++++++-
> >  target-s390x/cpu_models.c |  4 ++++
> >  2 files changed, 28 insertions(+), 1 deletion(-)
> >
> > diff --git a/qapi-schema.json b/qapi-schema.json
> > index 8d113f8..a102534 100644
> > --- a/qapi-schema.json
> > +++ b/qapi-schema.json
> > @@ -3291,6 +3291,15 @@
> >  #        migration-safe, but allows tooling to get an insight and work with
> >  #        model details.
> >  #
> > +# Note: When a non-migration-safe CPU model is expanded in static mode, some
> > +# features enabled by the CPU model may be omitted, because they can't be
> > +# implemented by a static CPU model definition (e.g. cache info passthrough and
> > +# PMU passthrough in x86). If you need an accurate representation of the
> > +# features enabled by a non-migration-safe CPU model, use @full. If you need a
> > +# static representation that will keep ABI compatibility even when changing QEMU
> > +# version or machine-type, use @static (but keep in mind that some features may
> > +# be omitted).
> > +#
> >  # Since: 2.8.0
> >  ##
> >  { 'enum': 'CpuModelExpansionType',
> > @@ -3304,10 +3313,24 @@
> >  #
> >  # @model: the expanded CpuModelInfo.
> >  #
> > +# @migration-safe: the expanded CPU model in @model is a migration-safe
> > +#                  CPU model. See @CpuDefinitionInfo.migration-safe.
> > +#                  If expansion type was @static, this is always true.
> > +#                  (since 2.9)
> > +#
> > +# @static: the expanded CPU model in @model is a static CPU model.
> > +#          See @CpuDefinitionInfo.static. If expansion type was @static,
> > +#          this is always true.
> > +#          (since 2.9)
> > +#
> > +# query-cpu-model-expansion with static expansion type should always
> > +# return a static and migration-safe expansion.
> > +#
> >  # Since: 2.8.0
> >  ##
> >  { 'struct': 'CpuModelExpansionInfo',
> > -  'data': { 'model': 'CpuModelInfo' } }
> > +  'data': { 'model': 'CpuModelInfo', 'static': 'bool',
> > +            'migration-safe': 'bool' } }
> >  
> >  
> >  ##
> > diff --git a/target-s390x/cpu_models.c b/target-s390x/cpu_models.c
> > index 5b66d33..f934add 100644
> > --- a/target-s390x/cpu_models.c
> > +++ b/target-s390x/cpu_models.c
> > @@ -448,6 +448,10 @@ CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type
> >      /* convert it back to a static representation */
> >      expansion_info = g_malloc0(sizeof(*expansion_info));
> >      expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
> > +
> > +    /* We always expand to a static and migration-safe CpuModelInfo */
> > +    expansion_info->q_static = true;
> > +    expansion_info->migration_safe = true;
> >      cpu_info_from_model(expansion_info->model, &s390_model, delta_changes);
> >      return expansion_info;
> >  }

-- 
Eduardo

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 17/17] target-i386: Implement query-cpu-model-expansion QMP command
  2016-12-13 10:16   ` Markus Armbruster
@ 2016-12-13 12:55     ` Eduardo Habkost
  2016-12-13 19:20       ` Markus Armbruster
  0 siblings, 1 reply; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-13 12:55 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, libvir-list, Jiri Denemark

On Tue, Dec 13, 2016 at 11:16:01AM +0100, Markus Armbruster wrote:
> Eduardo Habkost <ehabkost@redhat.com> writes:
> 
> > Implement query-cpu-model-expansion for target-i386.
> >
> > The code needs to be careful to handle non-migration-safe
> > features ("pmu" and "host-cache-info") according to the expansion
> > type.
> >
> > Cc: libvir-list@redhat.com
> > Cc: Jiri Denemark <jdenemar@redhat.com>
> > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > ---
> >  tests/Makefile.include |   3 +
> >  monitor.c              |   4 +-
> >  target-i386/cpu.c      | 195 ++++++++++++++++++++++++++++++++++++++++++++++++-
> >  3 files changed, 200 insertions(+), 2 deletions(-)
> >
> > diff --git a/tests/Makefile.include b/tests/Makefile.include
> > index 63c4347..c7bbfca 100644
> > --- a/tests/Makefile.include
> > +++ b/tests/Makefile.include
> > @@ -251,6 +251,9 @@ check-qtest-x86_64-y += $(check-qtest-i386-y)
> >  gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
> >  gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
> >  
> > +check-simpleqtest-x86_64-y += $(SRC_PATH)/tests/query-cpu-model-test.py
> > +check-simpleqtest-i386-y += $(SRC_PATH)/tests/query-cpu-model-test.py
> > +
> >  check-qtest-alpha-y = tests/boot-serial-test$(EXESUF)
> >  
> >  check-qtest-mips-y = tests/endianness-test$(EXESUF)
> > diff --git a/monitor.c b/monitor.c
> > index 0841d43..90c12b3 100644
> > --- a/monitor.c
> > +++ b/monitor.c
> > @@ -983,8 +983,10 @@ static void qmp_unregister_commands_hack(void)
> >  #ifndef TARGET_ARM
> >      qmp_unregister_command("query-gic-capabilities");
> >  #endif
> > -#if !defined(TARGET_S390X)
> > +#if !defined(TARGET_S390X) && !defined(TARGET_I386)
> >      qmp_unregister_command("query-cpu-model-expansion");
> > +#endif
> > +#if !defined(TARGET_S390X)
> >      qmp_unregister_command("query-cpu-model-baseline");
> >      qmp_unregister_command("query-cpu-model-comparison");
> >  #endif
> > diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> > index bf4ac09..198014a 100644
> > --- a/target-i386/cpu.c
> > +++ b/target-i386/cpu.c
> > @@ -29,10 +29,14 @@
> >  #include "qemu/option.h"
> >  #include "qemu/config-file.h"
> >  #include "qapi/qmp/qerror.h"
> > +#include "qapi/qmp/qstring.h"
> > +#include "qapi/qmp/qdict.h"
> > +#include "qapi/qmp/qbool.h"
> >  
> >  #include "qapi-types.h"
> >  #include "qapi-visit.h"
> >  #include "qapi/visitor.h"
> > +#include "qom/qom-qobject.h"
> >  #include "sysemu/arch_init.h"
> >  
> >  #if defined(CONFIG_KVM)
> > @@ -2259,7 +2263,7 @@ static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
> >      }
> >  }
> >  
> > -/* Load data from X86CPUDefinition
> > +/* Load data from X86CPUDefinition into a X86CPU object
> >   */
> >  static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
> >  {
> > @@ -2268,6 +2272,11 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
> >      char host_vendor[CPUID_VENDOR_SZ + 1];
> >      FeatureWord w;
> >  
> > +    /*NOTE: any property set by this function should be returned by
> 
> Space between /* and comment text, please.
> 
> Also, consider adding wings to both ends of multi-line comments.

Will do.

> 
> > +     * x86_cpu_to_dict(), so CPU model data returned by
> > +     * query-cpu-model-expansion is always complete.
> > +     */
> > +
> >      /* CPU models only set _minimum_ values for level/xlevel: */
> >      object_property_set_int(OBJECT(cpu), def->level, "min-level", errp);
> >      object_property_set_int(OBJECT(cpu), def->xlevel, "min-xlevel", errp);
> > @@ -2312,6 +2321,190 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
> >  
> >  }
> >  
> > +/* Convert CPU model data from X86CPU object to a property dictionary
> > + * that can recreate exactly the same CPU model.
> > + *
> > + * This function does the opposite of x86_cpu_load_def(). Any
> > + * property changed by x86_cpu_load_def() or instance_init
> > + * methods should be returned by this function too.
> > + */
> > +static void x86_cpu_to_dict(X86CPU *cpu, QDict *props, Error **errp)
> > +{
> > +    Object *obj = OBJECT(cpu);
> > +    FeatureWord w;
> > +    PropValue *pv;
> > +
> > +    /* This code could simply iterate over all writeable properties in the
> > +     * CPU object, and return all of them. But then the aliases properties
> 
> "alias properties"?

Will fix it.

> 
> > +     * would be returned as well. Returning only the known features
> > +     * is more reliable.
> > +     */
> > +    qdict_put_obj(props, "min-level",
> > +                  object_property_get_qobject(obj, "min-level", errp));
> > +    qdict_put_obj(props, "min-xlevel",
> > +                  object_property_get_qobject(obj, "min-xlevel", errp));
> > +
> > +    qdict_put_obj(props, "family",
> > +                  object_property_get_qobject(obj, "family", errp));
> > +    qdict_put_obj(props, "model",
> > +                  object_property_get_qobject(obj, "model", errp));
> > +    qdict_put_obj(props, "stepping",
> > +                  object_property_get_qobject(obj, "stepping", errp));
> > +    qdict_put_obj(props, "model-id",
> > +                  object_property_get_qobject(obj, "model-id", errp));
> 
> Incorrect use of the error API: if more than one call fails, the second
> failure will trip the assertion in error_setv().
> 
> If errors should not happen here, use &error_abort.
> 
> If errors need to be handled, see "Receive and accumulate multiple
> errors" in error.h.
> 

Oops. I will fix it.

> Consider "more than four, use a for":
> 
>        static char *prop_name[] = {
>            "min-level", "min-xlevel", "family", "model", "stepping",
>            "model-id", NULL
>        };
> 
>        for (pname = prop_name; *pname, pname++) {
>            qdict_put_obj(props, *pname,
>                          object_property_get_qobject(obj, *pname,
>                                                      &error_abort));
>        }

Good idea, I will do it.

> 
> > +
> > +    for (w = 0; w < FEATURE_WORDS; w++) {
> > +        FeatureWordInfo *fi = &feature_word_info[w];
> > +        int bit;
> > +        for (bit = 0; bit < 32; bit++) {
> > +            if (!fi->feat_names[bit]) {
> > +                continue;
> > +            }
> > +            qdict_put_obj(props, fi->feat_names[bit],
> > +                          object_property_get_qobject(obj, fi->feat_names[bit],
> > +                                                      errp));
> > +        }
> > +    }
> > +
> > +    for (pv = kvm_default_props; pv->prop; pv++) {
> > +        qdict_put_obj(props, pv->prop,
> > +                      object_property_get_qobject(obj, pv->prop, errp));
> > +    }
> > +    for (pv = tcg_default_props; pv->prop; pv++) {
> > +        qdict_put_obj(props, pv->prop,
> > +                      object_property_get_qobject(obj, pv->prop, errp));
> > +    }
> > +
> > +    qdict_put_obj(props, "vendor",
> > +                  object_property_get_qobject(obj, "vendor", errp));
> > +
> > +    /* Set by "host": */
> > +    qdict_put_obj(props, "lmce",
> > +                  object_property_get_qobject(obj, "lmce", errp));
> > +    qdict_put_obj(props, "pmu",
> > +                  object_property_get_qobject(obj, "pmu", errp));
> > +
> > +
> > +    /* Other properties configurable by the user: */
> > +    qdict_put_obj(props, "host-cache-info",
> > +                  object_property_get_qobject(obj, "host-cache-info", errp));
> > +}
> > +
> > +static void object_apply_props(Object *obj, QDict *props, Error **errp)
> > +{
> > +    const QDictEntry *prop;
> > +    Error *err = NULL;
> > +
> > +    for (prop = qdict_first(props); prop; prop = qdict_next(props, prop)) {
> > +        object_property_set_qobject(obj, qdict_entry_value(prop),
> > +                                         qdict_entry_key(prop), &err);
> > +        if (err) {
> > +            break;
> > +        }
> > +    }
> > +
> > +    error_propagate(errp, err);
> > +}
> > +
> > +static X86CPU *x86_cpu_from_model(CpuModelInfo *model, Error **errp)
> > +{
> > +    X86CPU *xc = NULL;
> > +    X86CPUClass *xcc;
> > +    Error *err = NULL;
> > +
> > +    xcc = X86_CPU_CLASS(cpu_class_by_name(TYPE_X86_CPU, model->name));
> > +    if (xcc == NULL) {
> > +        error_setg(&err, "CPU model '%s' not found", model->name);
> > +        goto out;
> > +    }
> > +
> > +    xc = X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc))));
> > +    if (model->has_props) {
> > +        QDict *d = qobject_to_qdict(model->props);
> > +        if (!d) {
> > +            error_setg(&err, "model.props must be a dictionary");
> > +            goto out;
> 
> How can this happen?

'props' is 'any' in the QAPI schema, because (it looks like) QAPI
doesn't have a 'dict' type.

> 
> > +        }
> > +        object_apply_props(OBJECT(xc), d, &err);
> > +        if (err) {
> > +            goto out;
> > +        }
> > +    }
> > +
> > +    x86_cpu_expand_features(xc, &err);
> > +    if (err) {
> > +        goto out;
> > +    }
> > +
> > +out:
> > +    if (err) {
> > +        error_propagate(errp, err);
> > +        object_unref(OBJECT(xc));
> > +        xc = NULL;
> > +    }
> > +    return xc;
> > +}
> > +
> > +CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
> > +                                                      CpuModelInfo *model,
> > +                                                      Error **errp)
> > +{
> > +    X86CPU *xc = NULL;
> > +    Error *err = NULL;
> > +    CpuModelExpansionInfo *ret = g_new0(CpuModelExpansionInfo, 1);
> > +    QDict *props;
> > +
> > +    xc = x86_cpu_from_model(model, &err);
> > +    if (err) {
> > +        goto out;
> > +    }
> > +
> > +    /* We currently always do full expansion */
> 
> This comment made me go "wait, we do full expansion even when @type is
> CPU_MODEL_EXPANSION_TYPE_STATIC?"  Looks like we first to full
> expansion, then correct the result according to type.

The comment is a leftover from a previous version where we didn't
even check expansion type. I will remove it (or clarify it).

> 
> > +    ret->model = g_new0(CpuModelInfo, 1);
> > +    ret->model->name = g_strdup("base"); /* the only static model */
> > +    props = qdict_new();
> > +    ret->model->props = QOBJECT(props);
> > +    ret->model->has_props = true;
> > +    x86_cpu_to_dict(xc, props, &err);
> > +
> > +    /* Some features (pmu, host-cache-info) are not migration-safe,
> > +     * and are handled differently depending on expansion type:
> > +     */
> > +    if (type ==  CPU_MODEL_EXPANSION_TYPE_STATIC) {
> 
> Single space after ==, please.

Will fix.

> 
> > +        /* static expansion force migration-unsafe features off: */
> > +        ret->q_static = ret->migration_safe = true;
> > +        qdict_del(props, "pmu");
> > +        qdict_del(props, "host-cache-info");
> > +    } else if (type == CPU_MODEL_EXPANSION_TYPE_FULL) {
> > +        QObject *o;
> > +        /* full expansion clear the static/migration-safe flags
> > +         * to indicate migration-unsafe features are on:
> > +         */
> > +        ret->q_static = true;
> > +        ret->migration_safe = true;
> > +
> > +        o = qdict_get(props, "pmu");
> > +        if (o && qbool_get_bool(qobject_to_qbool(o))) {
> > +            ret->q_static = ret->migration_safe = false;
> > +        }
> > +        o = qdict_get(props, "host-cache-info");
> > +        if (o && qbool_get_bool(qobject_to_qbool(o))) {
> > +            ret->q_static = ret->migration_safe = false;
> > +        }
> > +    } else {
> > +        error_setg(&err, "The requested expansion type is not supported.");
> 
> How can this happen?
> 
> If it can, it bombs when x86_cpu_to_dict() already set an error (see
> "use of the error API" above).

This can happen if we change the QAPI schema to support another
expansion type in the future.

> 
> > +    }
> > +
> > +out:
> > +    object_unref(OBJECT(xc));
> > +    if (err) {
> > +        error_propagate(errp, err);
> > +        qapi_free_CpuModelExpansionInfo(ret);
> > +        ret = NULL;
> > +    }
> > +    return ret;
> > +}
> > +
> >  X86CPU *cpu_x86_init(const char *cpu_model)
> >  {
> >      return X86_CPU(cpu_generic_init(TYPE_X86_CPU, cpu_model));

-- 
Eduardo

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 17/17] target-i386: Implement query-cpu-model-expansion QMP command
  2016-12-13 12:55     ` Eduardo Habkost
@ 2016-12-13 19:20       ` Markus Armbruster
  2016-12-13 21:11         ` Eduardo Habkost
  0 siblings, 1 reply; 35+ messages in thread
From: Markus Armbruster @ 2016-12-13 19:20 UTC (permalink / raw)
  To: Eduardo Habkost; +Cc: libvir-list, Jiri Denemark, qemu-devel

Eduardo Habkost <ehabkost@redhat.com> writes:

> On Tue, Dec 13, 2016 at 11:16:01AM +0100, Markus Armbruster wrote:
>> Eduardo Habkost <ehabkost@redhat.com> writes:
>> 
>> > Implement query-cpu-model-expansion for target-i386.
>> >
>> > The code needs to be careful to handle non-migration-safe
>> > features ("pmu" and "host-cache-info") according to the expansion
>> > type.
>> >
>> > Cc: libvir-list@redhat.com
>> > Cc: Jiri Denemark <jdenemar@redhat.com>
>> > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
>> > ---
>> >  tests/Makefile.include |   3 +
>> >  monitor.c              |   4 +-
>> >  target-i386/cpu.c      | 195 ++++++++++++++++++++++++++++++++++++++++++++++++-
>> >  3 files changed, 200 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/tests/Makefile.include b/tests/Makefile.include
>> > index 63c4347..c7bbfca 100644
>> > --- a/tests/Makefile.include
>> > +++ b/tests/Makefile.include
>> > @@ -251,6 +251,9 @@ check-qtest-x86_64-y += $(check-qtest-i386-y)
>> >  gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
>> >  gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
>> >  
>> > +check-simpleqtest-x86_64-y += $(SRC_PATH)/tests/query-cpu-model-test.py
>> > +check-simpleqtest-i386-y += $(SRC_PATH)/tests/query-cpu-model-test.py
>> > +
>> >  check-qtest-alpha-y = tests/boot-serial-test$(EXESUF)
>> >  
>> >  check-qtest-mips-y = tests/endianness-test$(EXESUF)
>> > diff --git a/monitor.c b/monitor.c
>> > index 0841d43..90c12b3 100644
>> > --- a/monitor.c
>> > +++ b/monitor.c
>> > @@ -983,8 +983,10 @@ static void qmp_unregister_commands_hack(void)
>> >  #ifndef TARGET_ARM
>> >      qmp_unregister_command("query-gic-capabilities");
>> >  #endif
>> > -#if !defined(TARGET_S390X)
>> > +#if !defined(TARGET_S390X) && !defined(TARGET_I386)
>> >      qmp_unregister_command("query-cpu-model-expansion");
>> > +#endif
>> > +#if !defined(TARGET_S390X)
>> >      qmp_unregister_command("query-cpu-model-baseline");
>> >      qmp_unregister_command("query-cpu-model-comparison");
>> >  #endif
>> > diff --git a/target-i386/cpu.c b/target-i386/cpu.c
>> > index bf4ac09..198014a 100644
>> > --- a/target-i386/cpu.c
>> > +++ b/target-i386/cpu.c
>> > @@ -29,10 +29,14 @@
>> >  #include "qemu/option.h"
>> >  #include "qemu/config-file.h"
>> >  #include "qapi/qmp/qerror.h"
>> > +#include "qapi/qmp/qstring.h"
>> > +#include "qapi/qmp/qdict.h"
>> > +#include "qapi/qmp/qbool.h"
>> >  
>> >  #include "qapi-types.h"
>> >  #include "qapi-visit.h"
>> >  #include "qapi/visitor.h"
>> > +#include "qom/qom-qobject.h"
>> >  #include "sysemu/arch_init.h"
>> >  
>> >  #if defined(CONFIG_KVM)
>> > @@ -2259,7 +2263,7 @@ static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
>> >      }
>> >  }
>> >  
>> > -/* Load data from X86CPUDefinition
>> > +/* Load data from X86CPUDefinition into a X86CPU object
>> >   */
>> >  static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
>> >  {
>> > @@ -2268,6 +2272,11 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
>> >      char host_vendor[CPUID_VENDOR_SZ + 1];
>> >      FeatureWord w;
>> >  
>> > +    /*NOTE: any property set by this function should be returned by
>> 
>> Space between /* and comment text, please.
>> 
>> Also, consider adding wings to both ends of multi-line comments.
>
> Will do.
>
>> 
>> > +     * x86_cpu_to_dict(), so CPU model data returned by
>> > +     * query-cpu-model-expansion is always complete.
>> > +     */
>> > +
>> >      /* CPU models only set _minimum_ values for level/xlevel: */
>> >      object_property_set_int(OBJECT(cpu), def->level, "min-level", errp);
>> >      object_property_set_int(OBJECT(cpu), def->xlevel, "min-xlevel", errp);
>> > @@ -2312,6 +2321,190 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp)
>> >  
>> >  }
>> >  
>> > +/* Convert CPU model data from X86CPU object to a property dictionary
>> > + * that can recreate exactly the same CPU model.
>> > + *
>> > + * This function does the opposite of x86_cpu_load_def(). Any
>> > + * property changed by x86_cpu_load_def() or instance_init
>> > + * methods should be returned by this function too.
>> > + */
>> > +static void x86_cpu_to_dict(X86CPU *cpu, QDict *props, Error **errp)
>> > +{
>> > +    Object *obj = OBJECT(cpu);
>> > +    FeatureWord w;
>> > +    PropValue *pv;
>> > +
>> > +    /* This code could simply iterate over all writeable properties in the
>> > +     * CPU object, and return all of them. But then the aliases properties
>> 
>> "alias properties"?
>
> Will fix it.
>
>> 
>> > +     * would be returned as well. Returning only the known features
>> > +     * is more reliable.
>> > +     */
>> > +    qdict_put_obj(props, "min-level",
>> > +                  object_property_get_qobject(obj, "min-level", errp));
>> > +    qdict_put_obj(props, "min-xlevel",
>> > +                  object_property_get_qobject(obj, "min-xlevel", errp));
>> > +
>> > +    qdict_put_obj(props, "family",
>> > +                  object_property_get_qobject(obj, "family", errp));
>> > +    qdict_put_obj(props, "model",
>> > +                  object_property_get_qobject(obj, "model", errp));
>> > +    qdict_put_obj(props, "stepping",
>> > +                  object_property_get_qobject(obj, "stepping", errp));
>> > +    qdict_put_obj(props, "model-id",
>> > +                  object_property_get_qobject(obj, "model-id", errp));
>> 
>> Incorrect use of the error API: if more than one call fails, the second
>> failure will trip the assertion in error_setv().
>> 
>> If errors should not happen here, use &error_abort.
>> 
>> If errors need to be handled, see "Receive and accumulate multiple
>> errors" in error.h.
>> 
>
> Oops. I will fix it.
>
>> Consider "more than four, use a for":
>> 
>>        static char *prop_name[] = {
>>            "min-level", "min-xlevel", "family", "model", "stepping",
>>            "model-id", NULL
>>        };
>> 
>>        for (pname = prop_name; *pname, pname++) {
>>            qdict_put_obj(props, *pname,
>>                          object_property_get_qobject(obj, *pname,
>>                                                      &error_abort));
>>        }
>
> Good idea, I will do it.
>
>> 
>> > +
>> > +    for (w = 0; w < FEATURE_WORDS; w++) {
>> > +        FeatureWordInfo *fi = &feature_word_info[w];
>> > +        int bit;
>> > +        for (bit = 0; bit < 32; bit++) {
>> > +            if (!fi->feat_names[bit]) {
>> > +                continue;
>> > +            }
>> > +            qdict_put_obj(props, fi->feat_names[bit],
>> > +                          object_property_get_qobject(obj, fi->feat_names[bit],
>> > +                                                      errp));
>> > +        }
>> > +    }
>> > +
>> > +    for (pv = kvm_default_props; pv->prop; pv++) {
>> > +        qdict_put_obj(props, pv->prop,
>> > +                      object_property_get_qobject(obj, pv->prop, errp));
>> > +    }
>> > +    for (pv = tcg_default_props; pv->prop; pv++) {
>> > +        qdict_put_obj(props, pv->prop,
>> > +                      object_property_get_qobject(obj, pv->prop, errp));
>> > +    }
>> > +
>> > +    qdict_put_obj(props, "vendor",
>> > +                  object_property_get_qobject(obj, "vendor", errp));
>> > +
>> > +    /* Set by "host": */
>> > +    qdict_put_obj(props, "lmce",
>> > +                  object_property_get_qobject(obj, "lmce", errp));
>> > +    qdict_put_obj(props, "pmu",
>> > +                  object_property_get_qobject(obj, "pmu", errp));
>> > +
>> > +
>> > +    /* Other properties configurable by the user: */
>> > +    qdict_put_obj(props, "host-cache-info",
>> > +                  object_property_get_qobject(obj, "host-cache-info", errp));
>> > +}
>> > +
>> > +static void object_apply_props(Object *obj, QDict *props, Error **errp)
>> > +{
>> > +    const QDictEntry *prop;
>> > +    Error *err = NULL;
>> > +
>> > +    for (prop = qdict_first(props); prop; prop = qdict_next(props, prop)) {
>> > +        object_property_set_qobject(obj, qdict_entry_value(prop),
>> > +                                         qdict_entry_key(prop), &err);
>> > +        if (err) {
>> > +            break;
>> > +        }
>> > +    }
>> > +
>> > +    error_propagate(errp, err);
>> > +}
>> > +
>> > +static X86CPU *x86_cpu_from_model(CpuModelInfo *model, Error **errp)
>> > +{
>> > +    X86CPU *xc = NULL;
>> > +    X86CPUClass *xcc;
>> > +    Error *err = NULL;
>> > +
>> > +    xcc = X86_CPU_CLASS(cpu_class_by_name(TYPE_X86_CPU, model->name));
>> > +    if (xcc == NULL) {
>> > +        error_setg(&err, "CPU model '%s' not found", model->name);
>> > +        goto out;
>> > +    }
>> > +
>> > +    xc = X86_CPU(object_new(object_class_get_name(OBJECT_CLASS(xcc))));
>> > +    if (model->has_props) {
>> > +        QDict *d = qobject_to_qdict(model->props);
>> > +        if (!d) {
>> > +            error_setg(&err, "model.props must be a dictionary");
>> > +            goto out;
>> 
>> How can this happen?
>
> 'props' is 'any' in the QAPI schema, because (it looks like) QAPI
> doesn't have a 'dict' type.

I see.

>> > +        }
>> > +        object_apply_props(OBJECT(xc), d, &err);
>> > +        if (err) {
>> > +            goto out;
>> > +        }
>> > +    }
>> > +
>> > +    x86_cpu_expand_features(xc, &err);
>> > +    if (err) {
>> > +        goto out;
>> > +    }
>> > +
>> > +out:
>> > +    if (err) {
>> > +        error_propagate(errp, err);
>> > +        object_unref(OBJECT(xc));
>> > +        xc = NULL;
>> > +    }
>> > +    return xc;
>> > +}
>> > +
>> > +CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
>> > +                                                      CpuModelInfo *model,
>> > +                                                      Error **errp)
>> > +{
>> > +    X86CPU *xc = NULL;
>> > +    Error *err = NULL;
>> > +    CpuModelExpansionInfo *ret = g_new0(CpuModelExpansionInfo, 1);
>> > +    QDict *props;
>> > +
>> > +    xc = x86_cpu_from_model(model, &err);
>> > +    if (err) {
>> > +        goto out;
>> > +    }
>> > +
>> > +    /* We currently always do full expansion */
>> 
>> This comment made me go "wait, we do full expansion even when @type is
>> CPU_MODEL_EXPANSION_TYPE_STATIC?"  Looks like we first to full
>> expansion, then correct the result according to type.
>
> The comment is a leftover from a previous version where we didn't
> even check expansion type. I will remove it (or clarify it).
>
>> 
>> > +    ret->model = g_new0(CpuModelInfo, 1);
>> > +    ret->model->name = g_strdup("base"); /* the only static model */
>> > +    props = qdict_new();
>> > +    ret->model->props = QOBJECT(props);
>> > +    ret->model->has_props = true;
>> > +    x86_cpu_to_dict(xc, props, &err);
>> > +
>> > +    /* Some features (pmu, host-cache-info) are not migration-safe,
>> > +     * and are handled differently depending on expansion type:
>> > +     */
>> > +    if (type ==  CPU_MODEL_EXPANSION_TYPE_STATIC) {
>> 
>> Single space after ==, please.
>
> Will fix.
>
>> 
>> > +        /* static expansion force migration-unsafe features off: */
>> > +        ret->q_static = ret->migration_safe = true;
>> > +        qdict_del(props, "pmu");
>> > +        qdict_del(props, "host-cache-info");
>> > +    } else if (type == CPU_MODEL_EXPANSION_TYPE_FULL) {
>> > +        QObject *o;
>> > +        /* full expansion clear the static/migration-safe flags
>> > +         * to indicate migration-unsafe features are on:
>> > +         */
>> > +        ret->q_static = true;
>> > +        ret->migration_safe = true;
>> > +
>> > +        o = qdict_get(props, "pmu");
>> > +        if (o && qbool_get_bool(qobject_to_qbool(o))) {
>> > +            ret->q_static = ret->migration_safe = false;
>> > +        }
>> > +        o = qdict_get(props, "host-cache-info");
>> > +        if (o && qbool_get_bool(qobject_to_qbool(o))) {
>> > +            ret->q_static = ret->migration_safe = false;
>> > +        }
>> > +    } else {
>> > +        error_setg(&err, "The requested expansion type is not supported.");
>> 
>> How can this happen?
>> 
>> If it can, it bombs when x86_cpu_to_dict() already set an error (see
>> "use of the error API" above).
>
> This can happen if we change the QAPI schema to support another
> expansion type in the future.

I'd make this an assertion, because it's a programming error.

>
>> 
>> > +    }
>> > +
>> > +out:
>> > +    object_unref(OBJECT(xc));
>> > +    if (err) {
>> > +        error_propagate(errp, err);
>> > +        qapi_free_CpuModelExpansionInfo(ret);
>> > +        ret = NULL;
>> > +    }
>> > +    return ret;
>> > +}
>> > +
>> >  X86CPU *cpu_x86_init(const char *cpu_model)
>> >  {
>> >      return X86_CPU(cpu_generic_init(TYPE_X86_CPU, cpu_model));

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 17/17] target-i386: Implement query-cpu-model-expansion QMP command
  2016-12-13 19:20       ` Markus Armbruster
@ 2016-12-13 21:11         ` Eduardo Habkost
  0 siblings, 0 replies; 35+ messages in thread
From: Eduardo Habkost @ 2016-12-13 21:11 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: libvir-list, Jiri Denemark, qemu-devel

On Tue, Dec 13, 2016 at 08:20:39PM +0100, Markus Armbruster wrote:
[...]
> >> > +    if (type ==  CPU_MODEL_EXPANSION_TYPE_STATIC) {
> >> > +        /* static expansion force migration-unsafe features off: */
> >> > +        ret->q_static = ret->migration_safe = true;
> >> > +        qdict_del(props, "pmu");
> >> > +        qdict_del(props, "host-cache-info");
> >> > +    } else if (type == CPU_MODEL_EXPANSION_TYPE_FULL) {
> >> > +        QObject *o;
> >> > +        /* full expansion clear the static/migration-safe flags
> >> > +         * to indicate migration-unsafe features are on:
> >> > +         */
> >> > +        ret->q_static = true;
> >> > +        ret->migration_safe = true;
> >> > +
> >> > +        o = qdict_get(props, "pmu");
> >> > +        if (o && qbool_get_bool(qobject_to_qbool(o))) {
> >> > +            ret->q_static = ret->migration_safe = false;
> >> > +        }
> >> > +        o = qdict_get(props, "host-cache-info");
> >> > +        if (o && qbool_get_bool(qobject_to_qbool(o))) {
> >> > +            ret->q_static = ret->migration_safe = false;
> >> > +        }
> >> > +    } else {
> >> > +        error_setg(&err, "The requested expansion type is not supported.");
> >> 
> >> How can this happen?
> >> 
> >> If it can, it bombs when x86_cpu_to_dict() already set an error (see
> >> "use of the error API" above).
> >
> > This can happen if we change the QAPI schema to support another
> > expansion type in the future.
> 
> I'd make this an assertion, because it's a programming error.

I don't think it's a programming error. For example, if one day
the ppc maintainers decide they need a new expansion type for
some arch-specific requirement they have, they won't need to
touch the x86 and s390x code when changing the schema.

-- 
Eduardo

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 15/17] target-i386: Define static "base" CPU model
  2016-12-05 23:57     ` Eduardo Habkost
  2016-12-06  9:32       ` David Hildenbrand
@ 2016-12-16 16:02       ` Jiri Denemark
  2016-12-20 16:49         ` David Hildenbrand
  1 sibling, 1 reply; 35+ messages in thread
From: Jiri Denemark @ 2016-12-16 16:02 UTC (permalink / raw)
  To: Eduardo Habkost; +Cc: David Hildenbrand, qemu-devel, libvir-list

On Mon, Dec 05, 2016 at 21:57:45 -0200, Eduardo Habkost wrote:
> On Mon, Dec 05, 2016 at 07:18:47PM +0100, David Hildenbrand wrote:
> > Am 02.12.2016 um 22:18 schrieb Eduardo Habkost:
> > > The query-cpu-model-expand QMP command needs at least one static
> > > model, to allow the "static" expansion mode to be implemented.
> > > Instead of defining static versions of every CPU model, define a
> > > "base" CPU model that has absolutely no feature flag enabled.
> > > 
> > 
> > Introducing separate ones makes feature lists presented to the user much
> > shorter (and therefore easier to maintain). But I don't know how libvirt
> > wants to deal with models on x86 in the future.
> 
> I understand that having a larger set of static models would make
> expansions shorter. But I worry that by defining a complete set
> of static models on x86 would require extra maintenance work on
> the QEMU side with no visible benefit for libvirt.
> 
> I would like to hear from libvirt developers what they think. I
> still don't know what they plan to use the type=static expansion
> results for.

Currently we are mostly interested in the expansion of the "host" CPU
model. We're fine with the expansion based on the "basic" static model
with no features. Returning some real model instead of "basic" would be
OK as long as it would be one of the existing CPU models. Adding special
static models, such as Broadwell-base would actually be a complication
since we would need to provide some translation to the existing models
for backward compatibility. I'd appreciate if we could avoid doing this.

Jirka

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [Qemu-devel] [PATCH for-2.9 15/17] target-i386: Define static "base" CPU model
  2016-12-16 16:02       ` Jiri Denemark
@ 2016-12-20 16:49         ` David Hildenbrand
  0 siblings, 0 replies; 35+ messages in thread
From: David Hildenbrand @ 2016-12-20 16:49 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel, libvir-list

Am 16.12.2016 um 17:02 schrieb Jiri Denemark:
> On Mon, Dec 05, 2016 at 21:57:45 -0200, Eduardo Habkost wrote:
>> On Mon, Dec 05, 2016 at 07:18:47PM +0100, David Hildenbrand wrote:
>>> Am 02.12.2016 um 22:18 schrieb Eduardo Habkost:
>>>> The query-cpu-model-expand QMP command needs at least one static
>>>> model, to allow the "static" expansion mode to be implemented.
>>>> Instead of defining static versions of every CPU model, define a
>>>> "base" CPU model that has absolutely no feature flag enabled.
>>>>
>>>
>>> Introducing separate ones makes feature lists presented to the user much
>>> shorter (and therefore easier to maintain). But I don't know how libvirt
>>> wants to deal with models on x86 in the future.
>>
>> I understand that having a larger set of static models would make
>> expansions shorter. But I worry that by defining a complete set
>> of static models on x86 would require extra maintenance work on
>> the QEMU side with no visible benefit for libvirt.
>>
>> I would like to hear from libvirt developers what they think. I
>> still don't know what they plan to use the type=static expansion
>> results for.
>
> Currently we are mostly interested in the expansion of the "host" CPU
> model. We're fine with the expansion based on the "basic" static model
> with no features. Returning some real model instead of "basic" would be
> OK as long as it would be one of the existing CPU models. Adding special
> static models, such as Broadwell-base would actually be a complication

I agree, mixing names would be confusing. So if we would want to 
introduce static CPU models for x86 in QEMU, they would have to be named
exactly like the libvirt models and contain the exact same feature set.

> since we would need to provide some translation to the existing models
> for backward compatibility. I'd appreciate if we could avoid doing this.

Right and translation would only confuse people, especially if the CPU
models in libvirt and QEMU behave differently.

>
> Jirka
>


-- 

David

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2016-12-20 16:49 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-02 21:17 [Qemu-devel] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 01/17] qmp: Report QOM type name on query-cpu-definitions Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 02/17] qemu.py: Make logging optional Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 03/17] qtest.py: Support QTEST_LOG environment variable Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 04/17] qtest.py: make logging optional Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 05/17] qtest.py: Make 'binary' parameter optional Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 06/17] tests: Add rules to non-gtester qtest test cases Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 07/17] target-i386: Reorganize and document CPUID initialization steps Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 08/17] target-i386: Support "-cpu host" on TCG too Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 09/17] target-i386: Move "host" properties to base class Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 10/17] target-i386: Allow short strings to be used as vendor ID Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 11/17] target-i386: Remove AMD feature flag aliases from Opteron models Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 12/17] target-i386: Return migration-safe field on query-cpu-definitions Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 13/17] cpu: Support comma escaping when parsing -cpu Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 14/17] qapi: add static/migration-safe info to query-cpu-model-expansion Eduardo Habkost
2016-12-13  9:47   ` Markus Armbruster
2016-12-13 12:46     ` Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 15/17] target-i386: Define static "base" CPU model Eduardo Habkost
2016-12-05 18:18   ` David Hildenbrand
2016-12-05 23:57     ` Eduardo Habkost
2016-12-06  9:32       ` David Hildenbrand
2016-12-06 12:43         ` Eduardo Habkost
2016-12-16 16:02       ` Jiri Denemark
2016-12-20 16:49         ` David Hildenbrand
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 16/17] tests: query-cpu-model-test.py test code Eduardo Habkost
2016-12-02 21:18 ` [Qemu-devel] [PATCH for-2.9 17/17] target-i386: Implement query-cpu-model-expansion QMP command Eduardo Habkost
2016-12-13 10:16   ` Markus Armbruster
2016-12-13 12:55     ` Eduardo Habkost
2016-12-13 19:20       ` Markus Armbruster
2016-12-13 21:11         ` Eduardo Habkost
2016-12-05  9:09 ` [Qemu-devel] [libvirt] [PATCH for-2.9 00/17] target-i386: Implement query-cpu-model-expansion no-reply
2016-12-05 15:15 ` [Qemu-devel] " David Hildenbrand
2016-12-05 17:11   ` Eduardo Habkost
2016-12-05 18:13     ` David Hildenbrand
2016-12-05 23:45       ` Eduardo Habkost

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.