Re: [Qemu-devel] [PATCH v2 02/19] spapr: introduce a skeleton for the XIVE interrupt controller

2018-02-11 Thread David Gibson
On Thu, Jan 18, 2018 at 08:27:52AM +1100, Benjamin Herrenschmidt wrote:
> On Wed, 2018-01-17 at 15:39 +0100, Cédric Le Goater wrote:
> > Migration is a problem. We will need both backend QEMU objects to be 
> > available anyhow if we want to migrate. So we are back to the current 
> > solution creating both QEMU objects but we can try to defer some of the 
> > KVM inits and create the KVM device on demand at CAS time.
> 
> Do we have a way to migrate a piece of info from the machine *first*
> that indicate what type of XICS/XIVE to instanciate ?

Nope.  qemu migration doesn't work like that.  Yes, it should, and
everyone knows it, but changing it is a really long term project.

> 
> > The next problem is the ICP object that currently needs the KVM device 
> > fd to connect the vcpus ... So, we will need to change that also. 
> > That is probably the biggest problem today. We need a way to disconnect 
> > the vpcu from the KVM device and see how we can defer the connection.
> > I need to make sure this is possible, I can check that without XIVE
> 
> Ben.
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


[Qemu-devel] [PATCH v2 04/29] qapi: Rename variable holding the QAPISchemaGenFOOVisitor

2018-02-11 Thread Markus Armbruster
Rename the variable holding the QAPISchemaGenFOOVisitor from gen to
vis, to avoid confusion in the next commit.

Signed-off-by: Markus Armbruster 
---
 scripts/qapi-commands.py   | 8 
 scripts/qapi-event.py  | 8 
 scripts/qapi-introspect.py | 8 
 scripts/qapi-types.py  | 8 
 scripts/qapi-visit.py  | 8 
 5 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 84a980d882..c3aa52fce1 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -291,9 +291,9 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
   prefix=prefix, c_prefix=c_name(prefix, protect=False)))
 
 schema = QAPISchema(input_file)
-gen = QAPISchemaGenCommandVisitor()
-schema.visit(gen)
-fdef.write(gen.defn)
-fdecl.write(gen.decl)
+vis = QAPISchemaGenCommandVisitor()
+schema.visit(vis)
+fdef.write(vis.defn)
+fdecl.write(vis.decl)
 
 close_output(fdef, fdecl)
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 0a098803e2..edb9ddb650 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -203,9 +203,9 @@ fdecl.write(mcgen('''
 event_enum_name = c_name(prefix + 'QAPIEvent', protect=False)
 
 schema = QAPISchema(input_file)
-gen = QAPISchemaGenEventVisitor()
-schema.visit(gen)
-fdef.write(gen.defn)
-fdecl.write(gen.decl)
+vis = QAPISchemaGenEventVisitor()
+schema.visit(vis)
+fdef.write(vis.defn)
+fdecl.write(vis.decl)
 
 close_output(fdef, fdecl)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index bd9253a172..ebe8706f41 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -193,9 +193,9 @@ fdef.write(mcgen('''
  prefix=prefix))
 
 schema = QAPISchema(input_file)
-gen = QAPISchemaGenIntrospectVisitor(opt_unmask)
-schema.visit(gen)
-fdef.write(gen.defn)
-fdecl.write(gen.decl)
+vis = QAPISchemaGenIntrospectVisitor(opt_unmask)
+schema.visit(vis)
+fdef.write(vis.defn)
+fdecl.write(vis.decl)
 
 close_output(fdef, fdecl)
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 1103dbda2d..4db8424da1 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -273,9 +273,9 @@ fdecl.write(mcgen('''
 '''))
 
 schema = QAPISchema(input_file)
-gen = QAPISchemaGenTypeVisitor()
-schema.visit(gen)
-fdef.write(gen.defn)
-fdecl.write(gen.decl)
+vis = QAPISchemaGenTypeVisitor()
+schema.visit(vis)
+fdef.write(vis.defn)
+fdecl.write(vis.decl)
 
 close_output(fdef, fdecl)
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index e56b3c1256..3c1a0e2544 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -360,9 +360,9 @@ fdecl.write(mcgen('''
   prefix=prefix))
 
 schema = QAPISchema(input_file)
-gen = QAPISchemaGenVisitVisitor()
-schema.visit(gen)
-fdef.write(gen.defn)
-fdecl.write(gen.decl)
+vis = QAPISchemaGenVisitVisitor()
+schema.visit(vis)
+fdef.write(vis.defn)
+fdecl.write(vis.decl)
 
 close_output(fdef, fdecl)
-- 
2.13.6




[Qemu-devel] [PATCH v2 12/29] qapi/common: Eliminate QAPISchema.exprs

2018-02-11 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Marc-André Lureau 
---
 scripts/qapi/common.py | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 3e92b38ade..d72c339ad5 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1461,13 +1461,13 @@ class QAPISchema(object):
 def __init__(self, fname):
 try:
 parser = QAPISchemaParser(open(fname, 'r'))
-self.exprs = check_exprs(parser.exprs)
+exprs = check_exprs(parser.exprs)
 self.docs = parser.docs
 self._entity_dict = {}
 self._predefining = True
 self._def_predefineds()
 self._predefining = False
-self._def_exprs()
+self._def_exprs(exprs)
 self.check()
 except QAPIError as err:
 print(err, file=sys.stderr)
@@ -1652,8 +1652,8 @@ class QAPISchema(object):
 name, info, doc, 'arg', self._make_members(data, info))
 self._def_entity(QAPISchemaEvent(name, info, doc, data, boxed))
 
-def _def_exprs(self):
-for expr_elem in self.exprs:
+def _def_exprs(self, exprs):
+for expr_elem in exprs:
 expr = expr_elem['expr']
 info = expr_elem['info']
 doc = expr_elem.get('doc')
-- 
2.13.6




[Qemu-devel] [PATCH v2 03/29] qapi: Generate up-to-date copyright notice

2018-02-11 Thread Markus Armbruster
Each generator carries a copyright notice for the generator itself,
and another one for the files it generates.  Only the former have been
updated along the way, the latter have not, and are all out of date.

Fix by copying the generator's copyright notice to the generated files
instead.  Note that the fix doesn't copy the "Authors:" part; the
generated files' outdated Authors list goes away without replacement.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Marc-André Lureau 
---
 scripts/qapi-commands.py   | 34 +++---
 scripts/qapi-event.py  | 32 ++--
 scripts/qapi-introspect.py | 25 -
 scripts/qapi-types.py  | 32 ++--
 scripts/qapi-visit.py  | 34 +++---
 scripts/qapi.py|  7 +--
 6 files changed, 75 insertions(+), 89 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 8e8da7c796..84a980d882 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -1,16 +1,17 @@
-#
-# QAPI command marshaller generator
-#
-# Copyright IBM, Corp. 2011
-# Copyright (C) 2014-2016 Red Hat, Inc.
-#
-# Authors:
-#  Anthony Liguori 
-#  Michael Roth
-#  Markus Armbruster 
-#
-# This work is licensed under the terms of the GNU GPL, version 2.
-# See the COPYING file in the top-level directory.
+"""
+QAPI command marshaller generator
+
+Copyright IBM, Corp. 2011
+Copyright (C) 2014-2018 Red Hat, Inc.
+
+Authors:
+ Anthony Liguori 
+ Michael Roth 
+ Markus Armbruster 
+
+This work is licensed under the terms of the GNU GPL, version 2.
+See the COPYING file in the top-level directory.
+"""
 
 from qapi import *
 
@@ -257,16 +258,11 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
 
 blurb = '''
  * Schema-defined QAPI/QMP commands
- *
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- *  Anthony Liguori   
 '''
 
 (fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
 'qmp-marshal.c', 'qmp-commands.h',
-blurb)
+blurb, __doc__)
 
 fdef.write(mcgen('''
 
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 2b7d720c08..0a098803e2 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -1,15 +1,16 @@
-#
-# QAPI event generator
-#
-# Copyright (c) 2014 Wenchao Xia
-# Copyright (c) 2015-2016 Red Hat Inc.
-#
-# Authors:
-#  Wenchao Xia 
-#  Markus Armbruster 
-#
-# This work is licensed under the terms of the GNU GPL, version 2.
-# See the COPYING file in the top-level directory.
+"""
+QAPI event generator
+
+Copyright (c) 2014 Wenchao Xia
+Copyright (c) 2015-2018 Red Hat Inc.
+
+Authors:
+ Wenchao Xia 
+ Markus Armbruster 
+
+This work is licensed under the terms of the GNU GPL, version 2.
+See the COPYING file in the top-level directory.
+"""
 
 from qapi import *
 
@@ -173,16 +174,11 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
 
 blurb = '''
  * Schema-defined QAPI/QMP events
- *
- * Copyright (c) 2014 Wenchao Xia
- *
- * Authors:
- *  Wenchao Xia   
 '''
 
 (fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
 'qapi-event.c', 'qapi-event.h',
-blurb)
+blurb, __doc__)
 
 fdef.write(mcgen('''
 #include "qemu/osdep.h"
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 83da2bdb94..bd9253a172 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -1,13 +1,14 @@
-#
-# QAPI introspection generator
-#
-# Copyright (C) 2015-2016 Red Hat, Inc.
-#
-# Authors:
-#  Markus Armbruster 
-#
-# This work is licensed under the terms of the GNU GPL, version 2.
-# See the COPYING file in the top-level directory.
+"""
+QAPI introspection generator
+
+Copyright (C) 2015-2018 Red Hat, Inc.
+
+Authors:
+ Markus Armbruster 
+
+This work is licensed under the terms of the GNU GPL, version 2.
+See the COPYING file in the top-level directory.
+"""
 
 from qapi import *
 
@@ -178,13 +179,11 @@ for o, a in opts:
 
 blurb = '''
  * QAPI/QMP schema introspection
- *
- * Copyright (C) 2015 Red Hat, Inc.
 '''
 
 (fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
 'qmp-introspect.c', 'qmp-introspect.h',
-blurb)
+blurb, __doc__)
 
 fdef.write(mcgen('''
 #include "qemu/osdep.h"
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 86afc57f92..1103dbda2d 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -1,15 +1,17 @@
-#
-# QAPI types generator
-#
-# Copyright IBM, Corp. 2011
-# Copyright (c) 2013-2016 Red Hat Inc.
-#
-# Authors:
-#  Anthony Liguori 
-#  Markus Armbruster 
-#
-# This work is licensed under the terms of the GNU GPL, version 2.
+"""
+QAPI types generator
+
+Copyright IBM, Corp. 2011
+Copyright (c) 2013-2018 Red Hat Inc.
+
+Authors:
+ Anthony Ligu

[Qemu-devel] [PATCH v2 25/29] docs/devel/writing-qmp-commands: Update for modular QAPI

2018-02-11 Thread Markus Armbruster
With modular code generation, putting stuff right into
qapi-schema.json is a bad idea.  Update writing-qmp-commands.txt
accordingly.

Signed-off-by: Markus Armbruster 
---
 docs/devel/writing-qmp-commands.txt | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/docs/devel/writing-qmp-commands.txt 
b/docs/devel/writing-qmp-commands.txt
index 4f5b24c0c4..776b3b41ca 100644
--- a/docs/devel/writing-qmp-commands.txt
+++ b/docs/devel/writing-qmp-commands.txt
@@ -15,8 +15,8 @@ start with docs/interop/qmp-intro.txt.
 Generally speaking, the following steps should be taken in order to write a
 new QMP command.
 
-1. Write the command's and type(s) specification in the QAPI schema file
-   (qapi-schema.json in the root source directory)
+1. Define the command and any types it needs in the appropriate QAPI
+   schema module.
 
 2. Write the QMP command itself, which is a regular C function. Preferably,
the command should be exported by some QEMU subsystem. But it can also be
@@ -88,8 +88,9 @@ command carries some meaningful action in QEMU but here it 
will just print
 Our command will be called "hello-world". It takes no arguments, nor does it
 return any data.
 
-The first step is to add the following line to the bottom of the
-qapi-schema.json file:
+The first step is defining the command in the appropriate QAPI schema
+module.  We pick module qapi/misc.json, and add the following line at
+the bottom:
 
 { 'command': 'hello-world' }
 
@@ -245,7 +246,7 @@ This is very important. No QMP command will be accepted in 
QEMU without proper
 documentation.
 
 There are many examples of such documentation in the schema file already, but
-here goes "hello-world"'s new entry for the qapi-schema.json file:
+here goes "hello-world"'s new entry for qapi/misc.json:
 
 ##
 # @hello-world
@@ -425,8 +426,7 @@ There are a number of things to be noticed:
allocated by the implementation. This is so because the QAPI also generates
a function to free its types and it cannot distinguish between dynamically
or statically allocated strings
-6. You have to include the "qmp-commands.h" header file in qemu-timer.c,
-   otherwise qemu won't build
+6. You have to include "qapi/qmp-commands-misc.h" in qemu-timer.c
 
 Time to test the new command. Build qemu, run it as described in the "Testing"
 section and try this:
-- 
2.13.6




[Qemu-devel] [PATCH v2 14/29] qapi: Concentrate QAPISchemaParser.exprs updates in .__init__()

2018-02-11 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Marc-André Lureau 
---
 scripts/qapi/common.py | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index dce289ae21..cc5a5941dd 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -290,8 +290,12 @@ class QAPISchemaParser(object):
 if not isinstance(include, str):
 raise QAPISemError(info,
"Value of 'include' must be a string")
-self._include(include, info, os.path.dirname(self.fname),
-  previously_included)
+exprs_include = self._include(include, info,
+  os.path.dirname(self.fname),
+  previously_included)
+if exprs_include:
+self.exprs.extend(exprs_include.exprs)
+self.docs.extend(exprs_include.docs)
 elif "pragma" in expr:
 self.reject_expr_doc(cur_doc)
 if len(expr) != 1:
@@ -334,14 +338,13 @@ class QAPISchemaParser(object):
 
 # skip multiple include of the same file
 if incl_abs_fname in previously_included:
-return
+return None
+
 try:
 fobj = open(incl_fname, 'r')
 except IOError as e:
 raise QAPISemError(info, '%s: %s' % (e.strerror, incl_fname))
-exprs_include = QAPISchemaParser(fobj, previously_included, info)
-self.exprs.extend(exprs_include.exprs)
-self.docs.extend(exprs_include.docs)
+return QAPISchemaParser(fobj, previously_included, info)
 
 def _pragma(self, name, value, info):
 global doc_required, returns_whitelist, name_case_whitelist
-- 
2.13.6




[Qemu-devel] [PATCH v2 21/29] qapi/common: Fix guardname() for funny filenames

2018-02-11 Thread Markus Armbruster
guardname() fails to return a valid C identifier for arguments
containing anything but [A-Za-z0-9_.-'].  Fix that.  Don't bother
protecting ticklish identifiers; header guards are all-caps, and no
ticklish identifiers are.

Signed-off-by: Markus Armbruster 
Reviewed-by: Marc-André Lureau 
Reviewed-by: Eric Blake 
---
 scripts/qapi/common.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index de12f8469a..6e5152b173 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1867,7 +1867,7 @@ def mcgen(code, **kwds):
 
 
 def guardname(filename):
-return c_name(filename, protect=False).upper()
+return re.sub(r'[^A-Za-z0-9_]', '_', filename).upper()
 
 
 def guardstart(name):
-- 
2.13.6




[Qemu-devel] [PATCH v2 10/29] qapi: Touch generated files only when they change

2018-02-11 Thread Markus Armbruster
A massive number of objects depends on QAPI-generated headers.  In my
"build everything" tree, it's roughly 4800 out of 5100.  This is
particularly annoying when only some of the generated files change,
say for a doc fix.

Improve qapi-gen.py to touch its output files only if they actually
change.  Rebuild time for a QAPI doc fix drops from many minutes to a
few seconds.  Rebuilds get faster for certain code changes, too.  For
instance, adding a simple QMP event now recompiles less than 200
instead of 4800 objects.  But adding a QAPI type is as bad as ever;
we've clearly got more work to do.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 scripts/qapi/common.py | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 8290795dc1..2e58573a39 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1951,9 +1951,16 @@ class QAPIGen(object):
 except os.error as e:
 if e.errno != errno.EEXIST:
 raise
-f = open(os.path.join(output_dir, fname), 'w')
-f.write(self._top(fname) + self._preamble + self._body
+fd = os.open(os.path.join(output_dir, fname),
+ os.O_RDWR | os.O_CREAT, 0666)
+f = os.fdopen(fd, 'r+')
+text = (self._top(fname) + self._preamble + self._body
 + self._bottom(fname))
+oldtext = f.read(len(text) + 1)
+if text != oldtext:
+f.seek(0)
+f.truncate(0)
+f.write(text)
 f.close()
 
 
-- 
2.13.6




[Qemu-devel] [PATCH v2 28/29] Fix up dangling references to qmp-commands.* in comment and doc

2018-02-11 Thread Markus Armbruster
Fix up the reference to qmp-commands.hx in qmp.c.  Missed in commit
5032a16d1d.

Fix up the reference to qmp-commands.txt in
docs/xen-save-devices-state.txt.  Missed in commit 4d8bb958fa.

Signed-off-by: Markus Armbruster 
---
 docs/xen-save-devices-state.txt |  3 +--
 qmp.c   | 14 +++---
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/docs/xen-save-devices-state.txt b/docs/xen-save-devices-state.txt
index a72ecc8081..1912ecad25 100644
--- a/docs/xen-save-devices-state.txt
+++ b/docs/xen-save-devices-state.txt
@@ -8,8 +8,7 @@ These operations are normally used with migration (see 
migration.txt),
 however it is also possible to save the state of all devices to file,
 without saving the RAM or the block devices of the VM.
 
-This operation is called "xen-save-devices-state" (see
-qmp-commands.txt)
+The save operation is available as QMP command xen-save-devices-state.
 
 
 The binary format used in the file is the following:
diff --git a/qmp.c b/qmp.c
index a8d4eba973..ba82e1df9f 100644
--- a/qmp.c
+++ b/qmp.c
@@ -147,13 +147,13 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp)
 
 #ifndef CONFIG_SPICE
 /*
- * qmp-commands.hx ensures that QMP command query-spice exists only
- * #ifdef CONFIG_SPICE.  Necessary for an accurate query-commands
- * result.  However, the QAPI schema is blissfully unaware of that,
- * and the QAPI code generator happily generates a dead
- * qmp_marshal_query_spice() that calls qmp_query_spice().  Provide it
- * one, or else linking fails.  FIXME Educate the QAPI schema on
- * CONFIG_SPICE.
+ * qmp_unregister_commands_hack() ensures that QMP command query-spice
+ * exists only #ifdef CONFIG_SPICE.  Necessary for an accurate
+ * query-commands result.  However, the QAPI schema is blissfully
+ * unaware of that, and the QAPI code generator happily generates a
+ * dead qmp_marshal_query_spice() that calls qmp_query_spice().
+ * Provide it one, or else linking fails.  FIXME Educate the QAPI
+ * schema on CONFIG_SPICE.
  */
 SpiceInfo *qmp_query_spice(Error **errp)
 {
-- 
2.13.6




[Qemu-devel] [PATCH v2 26/29] docs: Correct outdated information on QAPI

2018-02-11 Thread Markus Armbruster
* Fix guidance on error classes

* Point to generated documentation

* Drop plea for documentation, because the QAPI code generator
  enforces it since commit 3313b6124b

* Minor tweaks here and there

Signed-off-by: Markus Armbruster 
---
 docs/devel/writing-qmp-commands.txt | 25 +
 docs/interop/qmp-intro.txt  |  3 ++-
 2 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/docs/devel/writing-qmp-commands.txt 
b/docs/devel/writing-qmp-commands.txt
index 776b3b41ca..50385eff27 100644
--- a/docs/devel/writing-qmp-commands.txt
+++ b/docs/devel/writing-qmp-commands.txt
@@ -36,9 +36,9 @@ very simple and get more complex as we progress.
 For all the examples in the next sections, the test setup is the same and is
 shown here.
 
-First, QEMU should be started as:
+First, QEMU should be started like this:
 
-# /path/to/your/source/qemu [...] \
+# qemu-system-TARGET [...] \
 -chardev socket,id=qmp,port=,host=localhost,server \
 -mon chardev=qmp,mode=control,pretty=on
 
@@ -179,7 +179,7 @@ described in the "Testing" section and then send two 
commands:
 }
 }
 
-You should see "Hello, world" and "we love qemu" in the terminal running qemu,
+You should see "Hello, world" and "We love qemu" in the terminal running qemu,
 if you don't see these strings, then something went wrong.
 
 === Errors ===
@@ -221,30 +221,23 @@ The QMP server's response should be:
 }
 }
 
-As a general rule, all QMP errors should use ERROR_CLASS_GENERIC_ERROR
-(done by default when using error_setg()). There are two exceptions to
-this rule:
+Note that error_setg() produces a "GenericError" class.  In general,
+all QMP errors should have that error class.  There are two exceptions
+to this rule:
 
- 1. A non-generic ErrorClass value exists* for the failure you want to report
-(eg. DeviceNotFound)
+ 1. To support a management application's need to recognize a specific
+error for special handling
 
- 2. Management applications have to take special action on the failure you
-want to report, hence you have to add a new ErrorClass value so that they
-can check for it
+ 2. Backward compatibility
 
 If the failure you want to report falls into one of the two cases above,
 use error_set() with a second argument of an ErrorClass value.
 
- * All existing ErrorClass values are defined in the qapi-schema.json file
-
 === Command Documentation ===
 
 There's only one step missing to make "hello-world"'s implementation complete,
 and that's its documentation in the schema file.
 
-This is very important. No QMP command will be accepted in QEMU without proper
-documentation.
-
 There are many examples of such documentation in the schema file already, but
 here goes "hello-world"'s new entry for qapi/misc.json:
 
diff --git a/docs/interop/qmp-intro.txt b/docs/interop/qmp-intro.txt
index adbc94abb1..430fe1b747 100644
--- a/docs/interop/qmp-intro.txt
+++ b/docs/interop/qmp-intro.txt
@@ -78,7 +78,8 @@ Escape character is '^]'.
 }
 }
 
-Please, refer to the qapi-schema.json file for a complete command reference.
+Please refer to docs/interop/qemu-qmp-ref.* for a complete command
+reference, generated from qapi-schema.json.
 
 QMP wiki page
 -
-- 
2.13.6




[Qemu-devel] [PATCH v2 17/29] qapi: Record 'include' directives in intermediate representation

2018-02-11 Thread Markus Armbruster
The include directive permits modular QAPI schemata, but the generated
code is monolithic all the same.  To permit generating modular code,
the front end needs to pass more information on inclusions to the back
ends.  The commit before last added the necessary information to the
parse tree.  This commit adds it to the intermediate representation
and its QAPISchemaVisitor.  A later commit will use this to to
generate modular code.

New entity QAPISchemaInclude represents inclusions.  Call new visitor
method visit_include() for it, so visitors can see the sub-modules a
module includes.

Note that unlike other entities, QAPISchemaInclude has no name, and is
therefore not added to entity_dict.

New QAPISchemaEntity attribute @module names the entity's source file.
Call new visitor method visit_module() when it changes during a visit,
so visitors can keep track of the module being visited.

Signed-off-by: Markus Armbruster 
Reviewed-by: Marc-André Lureau 
---
 scripts/qapi/common.py   | 44 
 tests/qapi-schema/comments.out   |  1 +
 tests/qapi-schema/doc-bad-section.out|  1 +
 tests/qapi-schema/doc-good.out   |  1 +
 tests/qapi-schema/event-case.out |  1 +
 tests/qapi-schema/ident-with-escape.out  |  1 +
 tests/qapi-schema/include-relpath.out|  5 
 tests/qapi-schema/include-repetition.out | 10 
 tests/qapi-schema/include-simple.out |  3 +++
 tests/qapi-schema/indented-expr.out  |  1 +
 tests/qapi-schema/qapi-schema-test.out   |  1 +
 tests/qapi-schema/test-qapi.py   |  7 +
 12 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index b531ab519f..29d98ca934 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -985,8 +985,9 @@ def check_exprs(exprs):
 
 class QAPISchemaEntity(object):
 def __init__(self, name, info, doc):
-assert isinstance(name, str)
+assert name is None or isinstance(name, str)
 self.name = name
+self.module = None
 # For explicitly defined entities, info points to the (explicit)
 # definition.  For builtins (and their arrays), info is None.
 # For implicitly defined entities, info points to a place that
@@ -1015,10 +1016,16 @@ class QAPISchemaVisitor(object):
 def visit_end(self):
 pass
 
+def visit_module(self, fname):
+pass
+
 def visit_needed(self, entity):
 # Default to visiting everything
 return True
 
+def visit_include(self, fname, info):
+pass
+
 def visit_builtin_type(self, name, info, json_type):
 pass
 
@@ -1045,6 +1052,16 @@ class QAPISchemaVisitor(object):
 pass
 
 
+class QAPISchemaInclude(QAPISchemaEntity):
+
+def __init__(self, fname, info):
+QAPISchemaEntity.__init__(self, None, info, None)
+self.fname = fname
+
+def visit(self, visitor):
+visitor.visit_include(self.fname, self.info)
+
+
 class QAPISchemaType(QAPISchemaEntity):
 # Return the C type for common use.
 # For the types we commonly box, this is a pointer type.
@@ -1472,6 +1489,7 @@ class QAPISchemaEvent(QAPISchemaEntity):
 
 class QAPISchema(object):
 def __init__(self, fname):
+self._fname = fname
 parser = QAPISchemaParser(open(fname, 'r'))
 exprs = check_exprs(parser.exprs)
 self.docs = parser.docs
@@ -1479,16 +1497,19 @@ class QAPISchema(object):
 self._entity_dict = {}
 self._predefining = True
 self._def_predefineds()
-self._predefining = False
 self._def_exprs(exprs)
 self.check()
 
 def _def_entity(self, ent):
 # Only the predefined types are allowed to not have info
 assert ent.info or self._predefining
-assert ent.name not in self._entity_dict
+assert ent.name is None or ent.name not in self._entity_dict
 self._entity_list.append(ent)
-self._entity_dict[ent.name] = ent
+if ent.name is not None:
+self._entity_dict[ent.name] = ent
+if ent.info:
+ent.module = os.path.relpath(ent.info['file'],
+ os.path.dirname(self._fname))
 
 def lookup_entity(self, name, typ=None):
 ent = self._entity_dict.get(name)
@@ -1499,6 +1520,15 @@ class QAPISchema(object):
 def lookup_type(self, name):
 return self.lookup_entity(name, QAPISchemaType)
 
+def _def_include(self, expr, info, doc):
+include = expr['include']
+assert doc is None
+main_info = info
+while main_info['parent']:
+main_info = main_info['parent']
+fname = os.path.relpath(include, os.path.dirname(main_info['file']))
+self._def_entity(QAPISchemaInclude(fname, info))
+
 def _def_builtin_type(self, name, json_type, c_type):
 self._def_entity(QAPISchemaBuiltinType(name, json_type, c_type))
 # TO

[Qemu-devel] [PATCH v2 02/29] qapi: Streamline boilerplate comment generation

2018-02-11 Thread Markus Armbruster
Every generator has separate boilerplate for .h and .c, and their
differences are boring.  All of them repeat the license note.

Reduce the repetition as follows.  Move common text like the license
note to common open_output(), next to the existing common text there.
For each generator, replace the two separate descriptions by a single
one.

While there, emit an "automatically generated" note into generated
documentation, too.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Marc-André Lureau 
---
 scripts/qapi-commands.py| 26 +++---
 scripts/qapi-event.py   | 26 +++---
 scripts/qapi-introspect.py  | 21 ++---
 scripts/qapi-types.py   | 26 +++---
 scripts/qapi-visit.py   | 26 +++---
 scripts/qapi.py | 31 ++-
 scripts/qapi2texi.py|  3 ++-
 tests/qapi-schema/doc-good.texi |  3 ++-
 8 files changed, 36 insertions(+), 126 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index f89d748ba4..8e8da7c796 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -255,38 +255,18 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
 
 (input_file, output_dir, do_c, do_h, prefix, opts) = parse_command_line()
 
-c_comment = '''
-/*
- * schema-defined QMP->QAPI command dispatch
+blurb = '''
+ * Schema-defined QAPI/QMP commands
  *
  * Copyright IBM, Corp. 2011
  *
  * Authors:
  *  Anthony Liguori   
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-'''
-h_comment = '''
-/*
- * schema-defined QAPI function prototypes
- *
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- *  Anthony Liguori   
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
 '''
 
 (fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
 'qmp-marshal.c', 'qmp-commands.h',
-c_comment, h_comment)
+blurb)
 
 fdef.write(mcgen('''
 
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index c710968dc2..2b7d720c08 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -171,38 +171,18 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
 
 (input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
 
-c_comment = '''
-/*
- * schema-defined QAPI event functions
+blurb = '''
+ * Schema-defined QAPI/QMP events
  *
  * Copyright (c) 2014 Wenchao Xia
  *
  * Authors:
  *  Wenchao Xia   
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-'''
-h_comment = '''
-/*
- * schema-defined QAPI event functions
- *
- * Copyright (c) 2014 Wenchao Xia
- *
- * Authors:
- *  Wenchao Xia  
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
 '''
 
 (fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
 'qapi-event.c', 'qapi-event.h',
-c_comment, h_comment)
+blurb)
 
 fdef.write(mcgen('''
 #include "qemu/osdep.h"
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 032bcea491..83da2bdb94 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -176,32 +176,15 @@ for o, a in opts:
 if o in ('-u', '--unmask-non-abi-names'):
 opt_unmask = True
 
-c_comment = '''
-/*
+blurb = '''
  * QAPI/QMP schema introspection
  *
  * Copyright (C) 2015 Red Hat, Inc.
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-'''
-h_comment = '''
-/*
- * QAPI/QMP schema introspection
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
 '''
 
 (fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
 'qmp-introspect.c', 'qmp-introspect.h',
-c_comment, h_comment)
+blurb)
 
 fdef.write(mcgen('''
 #include "qemu/osdep.h"
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 7e3051dbb9..86afc57f92 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -250,39 +250,19 @@ for o, a in opts:
 if o in ('-b', '--builtins'):
 do_builtins = True
 
-c_comment = '''
-/*
- * deallocation functions for schema-defined QAPI types
+blurb = '''
+ * Schema-defined QAPI types
  *
  * Copyright IBM, Corp. 2011
  *
  * Authors:
  *  Anthony Liguori   
  *  Michael Roth   

[Qemu-devel] [PATCH v2 01/29] Include qapi/qmp/qerror.h exactly where needed

2018-02-11 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 block.c | 1 -
 block/qcow2.c   | 1 -
 chardev/char-fe.c   | 1 +
 chardev/char.c  | 1 +
 qom/object_interfaces.c | 1 +
 scripts/qapi-visit.py   | 2 +-
 6 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/block.c b/block.c
index f94585b230..05a484b4b8 100644
--- a/block.c
+++ b/block.c
@@ -32,7 +32,6 @@
 #include "qemu/module.h"
 #include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qerror.h"
 #include "qapi/qmp/qjson.h"
 #include "qapi/qmp/qstring.h"
 #include "sysemu/block-backend.h"
diff --git a/block/qcow2.c b/block/qcow2.c
index a64a572785..9245deac19 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -30,7 +30,6 @@
 #include "block/qcow2.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
-#include "qapi/qmp/qerror.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qstring.h"
 #include "qapi-event.h"
diff --git a/chardev/char-fe.c b/chardev/char-fe.c
index c611b3fa3e..e5f870e4d2 100644
--- a/chardev/char-fe.c
+++ b/chardev/char-fe.c
@@ -24,6 +24,7 @@
 #include "qemu/osdep.h"
 #include "qemu/error-report.h"
 #include "qapi/error.h"
+#include "qapi/qmp/qerror.h"
 #include "qapi-visit.h"
 #include "sysemu/replay.h"
 
diff --git a/chardev/char.c b/chardev/char.c
index 01d979a1da..c9a4da5516 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -32,6 +32,7 @@
 #include "qmp-commands.h"
 #include "qapi-visit.h"
 #include "qapi/error.h"
+#include "qapi/qmp/qerror.h"
 #include "sysemu/replay.h"
 #include "qemu/help_option.h"
 #include "qemu/option.h"
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 80d09139be..43d9aa0946 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -1,6 +1,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qerror.h"
 #include "qom/object_interfaces.h"
 #include "qemu/module.h"
 #include "qemu/option.h"
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 7e1cfc13f0..bc2b8b581a 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -371,13 +371,13 @@ fdef.write(mcgen('''
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qapi/error.h"
+#include "qapi/qmp/qerror.h"
 #include "%(prefix)sqapi-visit.h"
 ''',
  prefix=prefix))
 
 fdecl.write(mcgen('''
 #include "qapi/visitor.h"
-#include "qapi/qmp/qerror.h"
 #include "%(prefix)sqapi-types.h"
 
 ''',
-- 
2.13.6




[Qemu-devel] [PATCH v2 29/29] qapi: Don't create useless directory qapi-generated

2018-02-11 Thread Markus Armbruster
We used to generate first test and later QGA QAPI code into
qapi-generated/.  Commit b93b63f574 moved the test code to tests/.
Commit 54c2e50205 moved the QGA code to qga/qapi-generated/.  The
directory has been unused since.

Signed-off-by: Markus Armbruster 
---
 .gitignore | 1 -
 Makefile   | 1 -
 configure  | 1 -
 3 files changed, 3 deletions(-)

diff --git a/.gitignore b/.gitignore
index dabfe6bea8..4055e12ee8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,7 +27,6 @@
 /libuser
 /linux-headers/asm
 /qga/qapi-generated
-/qapi-generated
 /qapi-gen-timestamp
 /qapi/qapi-builtin-types.[ch]
 /qapi/qapi-builtin-visit.[ch]
diff --git a/Makefile b/Makefile
index 84411ee6ab..7eb1ede6f4 100644
--- a/Makefile
+++ b/Makefile
@@ -726,7 +726,6 @@ clean:
rm -f trace/generated-tracers-dtrace.h*
rm -f $(foreach f,$(GENERATED_FILES),$(f) $(f)-timestamp)
rm -f qapi-gen-timestamp
-   rm -rf qapi-generated
rm -rf qga/qapi-generated
for d in $(ALL_SUBDIRS); do \
if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
diff --git a/configure b/configure
index 62562f08cf..f564a1639e 100755
--- a/configure
+++ b/configure
@@ -7015,7 +7015,6 @@ DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 
tests/libqos tests/qapi-sche
 DIRS="$DIRS docs docs/interop fsdev scsi"
 DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw"
 DIRS="$DIRS roms/seabios roms/vgabios"
-DIRS="$DIRS qapi-generated"
 FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
 FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
 FILES="$FILES tests/tcg/lm32/Makefile tests/tcg/xtensa/Makefile po/Makefile"
-- 
2.13.6




[Qemu-devel] [PATCH v2 09/29] qapi-gen: Convert from getopt to argparse

2018-02-11 Thread Markus Armbruster
argparse is nicer to use than getopt, and gives us --help almost for
free.

Signed-off-by: Markus Armbruster 
---
 scripts/qapi-gen.py| 48 ++--
 scripts/qapi/common.py | 43 ---
 2 files changed, 30 insertions(+), 61 deletions(-)

diff --git a/scripts/qapi-gen.py b/scripts/qapi-gen.py
index 2100ca1145..e5be484e3e 100755
--- a/scripts/qapi-gen.py
+++ b/scripts/qapi-gen.py
@@ -4,8 +4,11 @@
 # This work is licensed under the terms of the GNU GPL, version 2 or later.
 # See the COPYING file in the top-level directory.
 
+from __future__ import print_function
+import argparse
+import re
 import sys
-from qapi.common import parse_command_line, QAPISchema
+from qapi.common import QAPISchema
 from qapi.types import gen_types
 from qapi.visit import gen_visit
 from qapi.commands import gen_commands
@@ -15,26 +18,35 @@ from qapi.doc import gen_doc
 
 
 def main(argv):
-(input_file, output_dir, prefix, opts) = \
-parse_command_line('bu', ['builtins', 'unmask-non-abi-names'])
+parser = argparse.ArgumentParser(
+description='Generate code from a QAPI schema')
+parser.add_argument('-b', '--builtins', action='store_true',
+help="generate code for built-in types")
+parser.add_argument('-o', '--output_dir', action='store', default='',
+help="write output to directory OUTPUT_DIR")
+parser.add_argument('-p', '--prefix', action='store', default='',
+help="prefix for symbols")
+parser.add_argument('-u', '--unmask-non-abi-names', action='store_true',
+dest='unmask',
+help="expose non-ABI names in introspection")
+parser.add_argument('schema', action='store')
+args = parser.parse_args()
 
-opt_builtins = False
-opt_unmask = False
+match = re.match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', args.prefix)
+if match.end() != len(args.prefix):
+print("%s: 'funny character '%s' in argument of --prefix"
+  % (sys.argv[0], args.prefix[match.end()]),
+  file=sys.stderr)
+sys.exit(1)
 
-for o, a in opts:
-if o in ('-b', '--builtins'):
-opt_builtins = True
-if o in ('-u', '--unmask-non-abi-names'):
-opt_unmask = True
+schema = QAPISchema(args.schema)
 
-schema = QAPISchema(input_file)
-
-gen_types(schema, output_dir, prefix, opt_builtins)
-gen_visit(schema, output_dir, prefix, opt_builtins)
-gen_commands(schema, output_dir, prefix)
-gen_events(schema, output_dir, prefix)
-gen_introspect(schema, output_dir, prefix, opt_unmask)
-gen_doc(schema, output_dir, prefix)
+gen_types(schema, args.output_dir, args.prefix, args.builtins)
+gen_visit(schema, args.output_dir, args.prefix, args.builtins)
+gen_commands(schema, args.output_dir, args.prefix)
+gen_events(schema, args.output_dir, args.prefix)
+gen_introspect(schema, args.output_dir, args.prefix, args.unmask)
+gen_doc(schema, args.output_dir, args.prefix)
 
 
 if __name__ == '__main__':
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 868ec25deb..8290795dc1 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -13,7 +13,6 @@
 
 from __future__ import print_function
 import errno
-import getopt
 import os
 import re
 import string
@@ -1924,48 +1923,6 @@ def build_params(arg_type, boxed, extra):
 
 
 #
-# Common command line parsing
-#
-
-
-def parse_command_line(extra_options='', extra_long_options=[]):
-
-try:
-opts, args = getopt.gnu_getopt(sys.argv[1:],
-   'p:o:' + extra_options,
-   ['prefix=', 'output-dir=']
-   + extra_long_options)
-except getopt.GetoptError as err:
-print("%s: %s" % (sys.argv[0], str(err)), file=sys.stderr)
-sys.exit(1)
-
-output_dir = ''
-prefix = ''
-extra_opts = []
-
-for oa in opts:
-o, a = oa
-if o in ('-p', '--prefix'):
-match = re.match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', a)
-if match.end() != len(a):
-print("%s: 'funny character '%s' in argument of --prefix" \
-  % (sys.argv[0], a[match.end()]), file=sys.stderr)
-sys.exit(1)
-prefix = a
-elif o in ('-o', '--output-dir'):
-output_dir = a + '/'
-else:
-extra_opts.append(oa)
-
-if len(args) != 1:
-print("%s: need exactly one argument" % sys.argv[0], file=sys.stderr)
-sys.exit(1)
-fname = args[0]
-
-return (fname, output_dir, prefix, extra_opts)
-
-
-#
 # Accumulate and write output
 #
 
-- 
2.13.6




[Qemu-devel] [PATCH v2 18/29] qapi: Rename generated qmp-marshal.c to qmp-commands.c

2018-02-11 Thread Markus Armbruster
All generated .c are named like their .h, except for qmp-marshal.c and
qmp-commands.h.  To add to the confusion, tests-qmp-commands.c falsely
matches generated test-qmp-commands.h.

Get rid of this unnecessary complication.

Signed-off-by: Markus Armbruster 
---
 .gitignore |  3 +--
 Makefile   |  6 +++---
 Makefile.objs  |  2 +-
 docs/devel/qapi-code-gen.txt   |  6 +++---
 qga/Makefile.objs  |  2 +-
 scripts/qapi/commands.py   |  2 +-
 tests/.gitignore   |  5 ++---
 tests/Makefile.include | 10 +-
 tests/{test-qmp-commands.c => test-qmp-cmds.c} |  0
 9 files changed, 17 insertions(+), 19 deletions(-)
 rename tests/{test-qmp-commands.c => test-qmp-cmds.c} (100%)

diff --git a/.gitignore b/.gitignore
index 2f9a92f6cc..7d783e6e66 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,9 +33,8 @@
 /qapi-visit.[ch]
 /qapi-event.[ch]
 /qapi-doc.texi
-/qmp-commands.h
+/qmp-commands.[ch]
 /qmp-introspect.[ch]
-/qmp-marshal.c
 /qemu-doc.html
 /qemu-doc.info
 /qemu-doc.txt
diff --git a/Makefile b/Makefile
index bd781c6aad..164a38578e 100644
--- a/Makefile
+++ b/Makefile
@@ -91,7 +91,7 @@ include $(SRC_PATH)/rules.mak
 
 GENERATED_FILES = qemu-version.h config-host.h qemu-options.def
 GENERATED_FILES += qmp-commands.h qapi-types.h qapi-visit.h qapi-event.h
-GENERATED_FILES += qmp-marshal.c qapi-types.c qapi-visit.c qapi-event.c
+GENERATED_FILES += qmp-commands.c qapi-types.c qapi-visit.c qapi-event.c
 GENERATED_FILES += qmp-introspect.h
 GENERATED_FILES += qmp-introspect.c
 GENERATED_FILES += qapi-doc.texi
@@ -496,7 +496,7 @@ $(SRC_PATH)/scripts/qapi-gen.py
 
 qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h \
 qga/qapi-generated/qga-qapi-visit.c qga/qapi-generated/qga-qapi-visit.h \
-qga/qapi-generated/qga-qmp-commands.h qga/qapi-generated/qga-qmp-marshal.c \
+qga/qapi-generated/qga-qmp-commands.h qga/qapi-generated/qga-qmp-commands.c \
 qga/qapi-generated/qga-qapi-doc.texi: \
 qga/qapi-generated/qapi-gen-timestamp ;
 qga/qapi-generated/qapi-gen-timestamp: $(SRC_PATH)/qga/qapi-schema.json 
$(qapi-py)
@@ -522,7 +522,7 @@ qapi-modules = $(SRC_PATH)/qapi-schema.json 
$(SRC_PATH)/qapi/common.json \
 
 qapi-types.c qapi-types.h \
 qapi-visit.c qapi-visit.h \
-qmp-commands.h qmp-marshal.c \
+qmp-commands.h qmp-commands.c \
 qapi-event.c qapi-event.h \
 qmp-introspect.h qmp-introspect.c \
 qapi-doc.texi: \
diff --git a/Makefile.objs b/Makefile.objs
index 2efba6d768..d255aaf194 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -78,7 +78,7 @@ common-obj-$(CONFIG_FDT) += device_tree.o
 ##
 # qapi
 
-common-obj-y += qmp-marshal.o
+common-obj-y += qmp-commands.o
 common-obj-y += qmp-introspect.o
 common-obj-y += qmp.o hmp.o
 endif
diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
index 1a1cbaea7b..ba1dc73298 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -1147,8 +1147,8 @@ declares qmp_COMMAND() that the user must implement.
 
 The following files are generated:
 
-$(prefix)qmp-marshal.c: Command marshal/dispatch functions for each
-QMP command defined in the schema
+$(prefix)qmp-commands.c: Command marshal/dispatch functions for each
+ QMP command defined in the schema
 
 $(prefix)qmp-commands.h: Function prototypes for the QMP commands
  specified in the schema
@@ -1170,7 +1170,7 @@ Example:
 void qmp_marshal_my_command(QDict *args, QObject **ret, Error **errp);
 
 #endif
-$ cat qapi-generated/example-qmp-marshal.c
+$ cat qapi-generated/example-qmp-commands.c
 [Uninteresting stuff omitted...]
 
 static void qmp_marshal_output_UserDefOne(UserDefOne *ret_in, QObject 
**ret_out, Error **errp)
diff --git a/qga/Makefile.objs b/qga/Makefile.objs
index 1c5986c0bb..6151378ae4 100644
--- a/qga/Makefile.objs
+++ b/qga/Makefile.objs
@@ -3,6 +3,6 @@ qga-obj-$(CONFIG_POSIX) += commands-posix.o channel-posix.o
 qga-obj-$(CONFIG_WIN32) += commands-win32.o channel-win32.o service-win32.o
 qga-obj-$(CONFIG_WIN32) += vss-win32.o
 qga-obj-y += qapi-generated/qga-qapi-types.o qapi-generated/qga-qapi-visit.o
-qga-obj-y += qapi-generated/qga-qmp-marshal.o
+qga-obj-y += qapi-generated/qga-qmp-commands.o
 
 qga-vss-dll-obj-$(CONFIG_QGA_VSS) += vss-win32/
diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
index a744611d58..05fe33a03b 100644
--- a/scripts/qapi/commands.py
+++ b/scripts/qapi/commands.py
@@ -289,5 +289,5 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
 schema.visit(vis)
 genc.add(vis.defn)
 genh.add(vis.decl)
-genc.write(output_dir, prefix + 'qmp-marshal.c')
+genc.write(output_dir, prefix + 'qmp-commands.c')
 genh.write(output_dir, prefi

[Qemu-devel] [PATCH v2 27/29] qapi: Move qapi-schema.json to qapi/, rename generated files

2018-02-11 Thread Markus Armbruster
Move qapi-schema.json to qapi/, so it's next to its modules, and all
files get generated to qapi/, not just the ones generated for modules.

Consistently name the generated files qapi-MODULE.EXT:
qmp-commands.[ch] become qapi-commands.[ch], qapi-event.[ch] become
qapi-events.[ch], and qmp-introspect.[ch] become qapi-introspect.[ch].
This gets rid of the temporary hacks in scripts/qapi/commands.py and
scripts/qapi/events.py.

Signed-off-by: Markus Armbruster 
---
 .gitignore| 16 ++--
 Makefile  | 42 +++
 Makefile.objs | 21 
 backends/hostmem.c|  2 +-
 docs/devel/qapi-code-gen.txt  | 30 +++---
 docs/devel/writing-qmp-commands.txt   |  2 +-
 docs/interop/qmp-intro.txt|  2 +-
 hmp.c |  2 +-
 include/qapi/qmp/qobject.h|  2 +-
 include/qapi/visitor.h|  2 +-
 include/qom/object.h  |  2 +-
 monitor.c |  6 ++---
 net/filter-buffer.c   |  2 +-
 qapi/misc.json|  4 +--
 qapi-schema.json => qapi/qapi-schema.json | 32 +++
 qga/Makefile.objs |  2 +-
 qga/commands-posix.c  |  2 +-
 qga/commands-win32.c  |  2 +-
 qga/commands.c|  2 +-
 qga/main.c|  2 +-
 qom/object.c  |  2 +-
 scripts/qapi/commands.py  |  7 --
 scripts/qapi/events.py|  9 +--
 scripts/qapi/introspect.py|  4 +--
 scripts/qapi/types.py |  6 ++---
 scripts/qapi/visit.py |  6 ++---
 tests/.gitignore  |  6 ++---
 tests/Makefile.include| 14 +--
 tests/test-qmp-cmds.c |  2 +-
 tests/test-qmp-event.c|  2 +-
 tests/test-qobject-input-visitor.c|  6 ++---
 tpm.c |  1 -
 ui/cocoa.m|  2 +-
 ui/vnc.c  |  2 +-
 34 files changed, 116 insertions(+), 130 deletions(-)
 rename qapi-schema.json => qapi/qapi-schema.json (85%)

diff --git a/.gitignore b/.gitignore
index 7f162e862f..dabfe6bea8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,8 +29,8 @@
 /qga/qapi-generated
 /qapi-generated
 /qapi-gen-timestamp
-/qapi-builtin-types.[ch]
-/qapi-builtin-visit.[ch]
+/qapi/qapi-builtin-types.[ch]
+/qapi/qapi-builtin-visit.[ch]
 /qapi/qapi-commands-block-core.[ch]
 /qapi/qapi-commands-block.[ch]
 /qapi/qapi-commands-char.[ch]
@@ -47,6 +47,7 @@
 /qapi/qapi-commands-trace.[ch]
 /qapi/qapi-commands-transaction.[ch]
 /qapi/qapi-commands-ui.[ch]
+/qapi/qapi-commands.[ch]
 /qapi/qapi-events-block-core.[ch]
 /qapi/qapi-events-block.[ch]
 /qapi/qapi-events-char.[ch]
@@ -63,6 +64,8 @@
 /qapi/qapi-events-trace.[ch]
 /qapi/qapi-events-transaction.[ch]
 /qapi/qapi-events-ui.[ch]
+/qapi/qapi-events.[ch]
+/qapi/qapi-introspect.[ch]
 /qapi/qapi-types-block-core.[ch]
 /qapi/qapi-types-block.[ch]
 /qapi/qapi-types-char.[ch]
@@ -79,7 +82,7 @@
 /qapi/qapi-types-trace.[ch]
 /qapi/qapi-types-transaction.[ch]
 /qapi/qapi-types-ui.[ch]
-/qapi-types.[ch]
+/qapi/qapi-types.[ch]
 /qapi/qapi-visit-block-core.[ch]
 /qapi/qapi-visit-block.[ch]
 /qapi/qapi-visit-char.[ch]
@@ -96,11 +99,8 @@
 /qapi/qapi-visit-trace.[ch]
 /qapi/qapi-visit-transaction.[ch]
 /qapi/qapi-visit-ui.[ch]
-/qapi-visit.[ch]
-/qapi-event.[ch]
-/qapi-doc.texi
-/qmp-commands.[ch]
-/qmp-introspect.[ch]
+/qapi/qapi-visit.[ch]
+/qapi/qapi-doc.texi
 /qemu-doc.html
 /qemu-doc.info
 /qemu-doc.txt
diff --git a/Makefile b/Makefile
index 50eb194877..84411ee6ab 100644
--- a/Makefile
+++ b/Makefile
@@ -90,8 +90,8 @@ endif
 include $(SRC_PATH)/rules.mak
 
 GENERATED_FILES = qemu-version.h config-host.h qemu-options.def
-GENERATED_FILES += qapi-builtin-types.h qapi-builtin-types.c
-GENERATED_FILES += qapi-types.h qapi-types.c
+GENERATED_FILES += qapi/qapi-builtin-types.h qapi/qapi-builtin-types.c
+GENERATED_FILES += qapi/qapi-types.h qapi/qapi-types.c
 GENERATED_FILES += qapi/qapi-types-block-core.h qapi/qapi-types-block-core.c
 GENERATED_FILES += qapi/qapi-types-block.h qapi/qapi-types-block.c
 GENERATED_FILES += qapi/qapi-types-char.h qapi/qapi-types-char.c
@@ -108,8 +108,8 @@ GENERATED_FILES += qapi/qapi-types-tpm.h 
qapi/qapi-types-tpm.c
 GENERATED_FILES += qapi/qapi-types-trace.h qapi/qapi-types-trace.c
 GENERATED_FILES += qapi/qapi-types-transaction.h qapi/qapi-types-transaction.c
 GENERATED_FILES += qapi/qapi-types-ui.h qapi/qapi-types-ui.c
-GENERATED_FILES += qapi-builtin-visit.h qapi-builtin-visit.c
-GENERATED_FILES += qapi-visit.h qapi-visit.c
+GENERATED_FILES += qapi/qapi-builtin-visit.h qapi/qapi-builtin-

[Qemu-devel] [PATCH v2 05/29] qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc

2018-02-11 Thread Markus Armbruster
These classes encapsulate accumulating and writing output.

Convert C code generation to QAPIGenC and QAPIGenH.  The conversion is
rather shallow: most of the output accumulation is not converted.
Left for later.

The indentation machinery uses a single global variable indent_level,
even though we generally interleave creation of a .c and its .h.  It
should become instance variable of QAPIGenC.  Also left for later.

Documentation generation isn't converted, and QAPIGenDoc isn't used.
This will change shortly.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Marc-André Lureau 
---
 scripts/qapi-commands.py   | 23 +--
 scripts/qapi-event.py  | 22 ++-
 scripts/qapi-introspect.py | 18 +
 scripts/qapi-types.py  | 22 ++-
 scripts/qapi-visit.py  | 22 ++-
 scripts/qapi.py| 99 +-
 6 files changed, 112 insertions(+), 94 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index c3aa52fce1..8d38ade076 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -260,12 +260,10 @@ blurb = '''
  * Schema-defined QAPI/QMP commands
 '''
 
-(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
-'qmp-marshal.c', 'qmp-commands.h',
-blurb, __doc__)
-
-fdef.write(mcgen('''
+genc = QAPIGenC(blurb, __doc__)
+genh = QAPIGenH(blurb, __doc__)
 
+genc.add(mcgen('''
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qemu/module.h"
@@ -280,20 +278,23 @@ fdef.write(mcgen('''
 #include "%(prefix)sqmp-commands.h"
 
 ''',
- prefix=prefix))
+   prefix=prefix))
 
-fdecl.write(mcgen('''
+genh.add(mcgen('''
 #include "%(prefix)sqapi-types.h"
 #include "qapi/qmp/dispatch.h"
 
 void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
 ''',
-  prefix=prefix, c_prefix=c_name(prefix, protect=False)))
+   prefix=prefix, c_prefix=c_name(prefix, protect=False)))
 
 schema = QAPISchema(input_file)
 vis = QAPISchemaGenCommandVisitor()
 schema.visit(vis)
-fdef.write(vis.defn)
-fdecl.write(vis.decl)
+genc.add(vis.defn)
+genh.add(vis.decl)
 
-close_output(fdef, fdecl)
+if do_c:
+genc.write(output_dir, prefix + 'qmp-marshal.c')
+if do_h:
+genh.write(output_dir, prefix + 'qmp-commands.h')
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index edb9ddb650..bd7a9be3dc 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -176,11 +176,10 @@ blurb = '''
  * Schema-defined QAPI/QMP events
 '''
 
-(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
-'qapi-event.c', 'qapi-event.h',
-blurb, __doc__)
+genc = QAPIGenC(blurb, __doc__)
+genh = QAPIGenH(blurb, __doc__)
 
-fdef.write(mcgen('''
+genc.add(mcgen('''
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "%(prefix)sqapi-event.h"
@@ -191,21 +190,24 @@ fdef.write(mcgen('''
 #include "qapi/qmp-event.h"
 
 ''',
- prefix=prefix))
+   prefix=prefix))
 
-fdecl.write(mcgen('''
+genh.add(mcgen('''
 #include "qapi/util.h"
 #include "%(prefix)sqapi-types.h"
 
 ''',
-  prefix=prefix))
+   prefix=prefix))
 
 event_enum_name = c_name(prefix + 'QAPIEvent', protect=False)
 
 schema = QAPISchema(input_file)
 vis = QAPISchemaGenEventVisitor()
 schema.visit(vis)
-fdef.write(vis.defn)
-fdecl.write(vis.decl)
+genc.add(vis.defn)
+genh.add(vis.decl)
 
-close_output(fdef, fdecl)
+if do_c:
+genc.write(output_dir, prefix + 'qapi-event.c')
+if do_h:
+genh.write(output_dir, prefix + 'qapi-event.h')
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index ebe8706f41..3d65690fe3 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -181,21 +181,23 @@ blurb = '''
  * QAPI/QMP schema introspection
 '''
 
-(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
-'qmp-introspect.c', 'qmp-introspect.h',
-blurb, __doc__)
+genc = QAPIGenC(blurb, __doc__)
+genh = QAPIGenH(blurb, __doc__)
 
-fdef.write(mcgen('''
+genc.add(mcgen('''
 #include "qemu/osdep.h"
 #include "%(prefix)sqmp-introspect.h"
 
 ''',
- prefix=prefix))
+   prefix=prefix))
 
 schema = QAPISchema(input_file)
 vis = QAPISchemaGenIntrospectVisitor(opt_unmask)
 schema.visit(vis)
-fdef.write(vis.defn)
-fdecl.write(vis.decl)
+genc.add(vis.defn)
+genh.add(vis.decl)
 
-close_output(fdef, fdecl)
+if do_c:
+genc.write(output_dir, prefix + 'qmp-introspect.c')
+if do_h:
+genh.write(output_dir, prefix + 'qmp-introspect.h')
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 4db8424da1..c0ac879beb 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -180,7 +180,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
 self.decl = ''
 self.defn = ''
 self._fw

[Qemu-devel] [PATCH v2 20/29] qapi/types qapi/visit: Generate built-in stuff into separate files

2018-02-11 Thread Markus Armbruster
Linking code from multiple separate QAPI schemata into the same
program is possible, but involves some weirdness around built-in
types:

* We generate code for built-in types into .c only with option
  --builtins.  The user is responsible for generating code for exactly
  one QAPI schema per program with --builtins.

* We generate code for built-in types into .h regardless of
  --builtins, but guarded by #ifndef QAPI_VISIT_BUILTIN.  Because all
  copies of this code are exactly the same, including any combination
  of these headers works.

Replace this contraption by something more conventional: generate code
for built-in types into their very own files: qapi-builtin-types.c,
qapi-builtin-visit.c, qapi-builtin-types.h, qapi-builtin-visit.h, but
only with --builtins.  Obey --output-dir, but ignore --prefix for
them.

Make qapi-types.h include qapi-builtin-types.h.  With multiple
schemata you now have multiple qapi-types.[ch], but only one
qapi-builtin-types.[ch].  Same for qapi-visit.[ch] and
qapi-builtin-visit.[ch].

Bonus: if all you need is built-in stuff, you can include a much
smaller header.  To be exploited shortly.

Signed-off-by: Markus Armbruster 
---
 .gitignore |  2 ++
 Makefile   | 13 ++
 Makefile.objs  |  2 ++
 scripts/qapi/common.py | 61 ---
 scripts/qapi/types.py  | 61 +++
 scripts/qapi/visit.py  | 64 +-
 6 files changed, 116 insertions(+), 87 deletions(-)

diff --git a/.gitignore b/.gitignore
index 7d783e6e66..9477a08b6b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,6 +29,8 @@
 /qga/qapi-generated
 /qapi-generated
 /qapi-gen-timestamp
+/qapi-builtin-types.[ch]
+/qapi-builtin-visit.[ch]
 /qapi-types.[ch]
 /qapi-visit.[ch]
 /qapi-event.[ch]
diff --git a/Makefile b/Makefile
index 164a38578e..60ddc9c945 100644
--- a/Makefile
+++ b/Makefile
@@ -90,10 +90,13 @@ endif
 include $(SRC_PATH)/rules.mak
 
 GENERATED_FILES = qemu-version.h config-host.h qemu-options.def
-GENERATED_FILES += qmp-commands.h qapi-types.h qapi-visit.h qapi-event.h
-GENERATED_FILES += qmp-commands.c qapi-types.c qapi-visit.c qapi-event.c
-GENERATED_FILES += qmp-introspect.h
-GENERATED_FILES += qmp-introspect.c
+GENERATED_FILES += qapi-builtin-types.h qapi-builtin-types.c
+GENERATED_FILES += qapi-types.h qapi-types.c
+GENERATED_FILES += qapi-builtin-visit.h qapi-builtin-visit.c
+GENERATED_FILES += qapi-visit.h qapi-visit.c
+GENERATED_FILES += qmp-commands.h qmp-commands.c
+GENERATED_FILES += qapi-event.h qapi-event.c
+GENERATED_FILES += qmp-introspect.c qmp-introspect.h
 GENERATED_FILES += qapi-doc.texi
 
 GENERATED_FILES += trace/generated-tcg-tracers.h
@@ -520,7 +523,9 @@ qapi-modules = $(SRC_PATH)/qapi-schema.json 
$(SRC_PATH)/qapi/common.json \
$(SRC_PATH)/qapi/transaction.json \
$(SRC_PATH)/qapi/ui.json
 
+qapi-builtin-types.c qapi-builtin-types.h \
 qapi-types.c qapi-types.h \
+qapi-builtin-visit.c qapi-builtin-visit.h \
 qapi-visit.c qapi-visit.h \
 qmp-commands.h qmp-commands.c \
 qapi-event.c qapi-event.h \
diff --git a/Makefile.objs b/Makefile.objs
index d255aaf194..2813e984fd 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -2,6 +2,8 @@
 # Common libraries for tools and emulators
 stub-obj-y = stubs/ crypto/
 util-obj-y = util/ qobject/ qapi/
+util-obj-y += qapi-builtin-types.o
+util-obj-y += qapi-builtin-visit.o
 util-obj-y += qmp-introspect.o qapi-types.o qapi-visit.o qapi-event.o
 
 chardev-obj-y = chardev/
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 31d2f73e7e..de12f8469a 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1531,11 +1531,10 @@ class QAPISchema(object):
 
 def _def_builtin_type(self, name, json_type, c_type):
 self._def_entity(QAPISchemaBuiltinType(name, json_type, c_type))
-# TODO As long as we have QAPI_TYPES_BUILTIN to share multiple
-# qapi-types.h from a single .c, all arrays of builtins must be
-# declared in the first file whether or not they are used.  Nicer
-# would be to use lazy instantiation, while figuring out how to
-# avoid compilation issues with multiple qapi-types.h.
+# Instantiating only the arrays that are actually used would
+# be nice, but we can't as long as their generated code
+# (qapi-builtin-types.[ch]) may be shared by some other
+# schema.
 self._make_array_type(name, None)
 
 def _def_predefineds(self):
@@ -1992,14 +1991,15 @@ class QAPIGen(object):
 return ''
 
 def write(self, output_dir, fname):
-if output_dir:
+pathname = os.path.join(output_dir, fname)
+dir = os.path.dirname(pathname)
+if dir:
 try:
-os.makedirs(output_dir)
+os.makedirs(dir)
 except os.error as e:
 if e.errno != errno.EEXIST:

[Qemu-devel] [PATCH v2 19/29] qapi: Make code-generating visitors use QAPIGen more

2018-02-11 Thread Markus Armbruster
The use of QAPIGen is rather shallow so far: most of the output
accumulation is not converted.  Take the next step: convert output
accumulation in the code-generating visitor classes.  Helper functions
outside these classes are not converted.

Signed-off-by: Markus Armbruster 
---
 scripts/qapi/commands.py   | 71 
 scripts/qapi/common.py | 13 
 scripts/qapi/doc.py| 74 --
 scripts/qapi/events.py | 55 ---
 scripts/qapi/introspect.py | 56 +---
 scripts/qapi/types.py  | 81 +++---
 scripts/qapi/visit.py  | 80 +++--
 7 files changed, 188 insertions(+), 242 deletions(-)

diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
index 05fe33a03b..46757db771 100644
--- a/scripts/qapi/commands.py
+++ b/scripts/qapi/commands.py
@@ -223,44 +223,15 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds)
 return ret
 
 
-class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
+class QAPISchemaGenCommandVisitor(QAPISchemaMonolithicCVisitor):
+
 def __init__(self, prefix):
-self._prefix = prefix
-self.decl = None
-self.defn = None
-self._regy = None
-self._visited_ret_types = None
-
-def visit_begin(self, schema):
-self.decl = ''
-self.defn = ''
+QAPISchemaMonolithicCVisitor.__init__(
+self, prefix, 'qmp-commands',
+' * Schema-defined QAPI/QMP commands', __doc__)
 self._regy = ''
 self._visited_ret_types = set()
-
-def visit_end(self):
-self.defn += gen_registry(self._regy, self._prefix)
-self._regy = None
-self._visited_ret_types = None
-
-def visit_command(self, name, info, arg_type, ret_type,
-  gen, success_response, boxed):
-if not gen:
-return
-self.decl += gen_command_decl(name, arg_type, boxed, ret_type)
-if ret_type and ret_type not in self._visited_ret_types:
-self._visited_ret_types.add(ret_type)
-self.defn += gen_marshal_output(ret_type)
-self.decl += gen_marshal_decl(name)
-self.defn += gen_marshal(name, arg_type, boxed, ret_type)
-self._regy += gen_register_command(name, success_response)
-
-
-def gen_commands(schema, output_dir, prefix):
-blurb = ' * Schema-defined QAPI/QMP commands'
-genc = QAPIGenC(blurb, __doc__)
-genh = QAPIGenH(blurb, __doc__)
-
-genc.add(mcgen('''
+self._genc.add(mcgen('''
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qemu/module.h"
@@ -275,19 +246,33 @@ def gen_commands(schema, output_dir, prefix):
 #include "%(prefix)sqmp-commands.h"
 
 ''',
-   prefix=prefix))
-
-genh.add(mcgen('''
+ prefix=prefix))
+self._genh.add(mcgen('''
 #include "%(prefix)sqapi-types.h"
 #include "qapi/qmp/dispatch.h"
 
 void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
 ''',
-   prefix=prefix, c_prefix=c_name(prefix, protect=False)))
+ prefix=prefix,
+ c_prefix=c_name(prefix, protect=False)))
 
+def visit_end(self):
+self._genc.add(gen_registry(self._regy, self._prefix))
+
+def visit_command(self, name, info, arg_type, ret_type,
+  gen, success_response, boxed):
+if not gen:
+return
+self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type))
+if ret_type and ret_type not in self._visited_ret_types:
+self._visited_ret_types.add(ret_type)
+self._genc.add(gen_marshal_output(ret_type))
+self._genh.add(gen_marshal_decl(name))
+self._genc.add(gen_marshal(name, arg_type, boxed, ret_type))
+self._regy += gen_register_command(name, success_response)
+
+
+def gen_commands(schema, output_dir, prefix):
 vis = QAPISchemaGenCommandVisitor(prefix)
 schema.visit(vis)
-genc.add(vis.defn)
-genh.add(vis.decl)
-genc.write(output_dir, prefix + 'qmp-commands.c')
-genh.write(output_dir, prefix + 'qmp-commands.h')
+vis.write(output_dir)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 29d98ca934..31d2f73e7e 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -2049,3 +2049,16 @@ class QAPIGenDoc(QAPIGen):
 def _top(self, fname):
 return (QAPIGen._top(self, fname)
 + '@c AUTOMATICALLY GENERATED, DO NOT MODIFY\n\n')
+
+
+class QAPISchemaMonolithicCVisitor(QAPISchemaVisitor):
+
+def __init__(self, prefix, what, blurb, pydoc):
+self._prefix = prefix
+self._what = what
+self._genc = QAPIGenC(blurb, pydoc)
+self._genh = QAPIGenH(blurb, pydoc)
+
+def write(self, output_dir):
+self._genc.write(output_dir, self.

[Qemu-devel] [PATCH v2 23/29] Include less of the generated modular QAPI headers

2018-02-11 Thread Markus Armbruster
In my "build everything" tree, a change to the types in
qapi-schema.json triggers a recompile of about 4800 out of 5100
objects.

The previous commit split up qmp-commands.h, qmp-event.h, qmp-visit.h,
qapi-types.h.  Each of these headers still includes all its shards.
Reduce compile time by including just the shards we actually need.

To illustrate the benefits: adding a type to qapi/migration.json now
recompiles some 2300 instead of 4800 objects.  The next commit will
improve it further.

Signed-off-by: Markus Armbruster 
---
 backends/cryptodev.c |  1 -
 backends/hostmem.c   |  3 ++-
 block.c  |  1 -
 block/block-backend.c|  2 +-
 block/crypto.c   |  2 +-
 block/nbd.c  |  2 +-
 block/nfs.c  |  2 +-
 block/qapi.c |  4 ++--
 block/qcow2.c|  3 +--
 block/quorum.c   |  2 +-
 block/sheepdog.c |  2 +-
 block/ssh.c  |  2 +-
 block/throttle-groups.c  |  2 +-
 block/write-threshold.c  |  4 ++--
 blockdev-nbd.c   |  2 +-
 blockdev.c   |  5 +++--
 blockjob.c   |  2 +-
 chardev/char-fe.c|  1 -
 chardev/char-ringbuf.c   |  2 +-
 chardev/char-socket.c|  1 +
 chardev/char.c   |  3 +--
 cpus.c   |  2 +-
 crypto/cipherpriv.h  |  2 +-
 hmp.c|  2 +-
 hw/acpi/core.c   |  2 +-
 hw/block/block.c |  1 +
 hw/block/hd-geometry.c   |  1 +
 hw/char/virtio-console.c |  2 +-
 hw/core/machine.c|  2 +-
 hw/i386/pc.c |  2 +-
 hw/mem/nvdimm.c  |  1 -
 hw/net/rocker/qmp-norocker.c |  2 +-
 hw/net/rocker/rocker.c   |  2 +-
 hw/net/rocker/rocker_fp.c|  2 +-
 hw/net/rocker/rocker_of_dpa.c|  2 +-
 hw/net/virtio-net.c  |  2 +-
 hw/ppc/spapr_rtas.c  |  1 -
 hw/tpm/tpm_emulator.c|  1 +
 hw/tpm/tpm_passthrough.c |  1 +
 hw/watchdog/watchdog.c   |  2 +-
 include/block/block.h|  2 +-
 include/block/dirty-bitmap.h |  2 +-
 include/block/nbd.h  |  2 +-
 include/chardev/char.h   |  1 +
 include/crypto/cipher.h  |  2 +-
 include/crypto/hash.h|  2 +-
 include/crypto/hmac.h|  2 +-
 include/crypto/secret.h  |  1 +
 include/crypto/tlscreds.h|  1 +
 include/hw/block/block.h |  2 +-
 include/hw/block/fdc.h   |  2 +-
 include/hw/ppc/spapr_drc.h   |  1 +
 include/hw/qdev-properties.h |  1 +
 include/io/dns-resolver.h|  1 +
 include/migration/colo.h |  2 +-
 include/migration/failover.h |  2 +-
 include/migration/global_state.h |  1 +
 include/monitor/monitor.h|  1 +
 include/net/filter.h |  1 +
 include/net/net.h|  2 +-
 include/qapi/clone-visitor.h |  1 -
 include/qapi/error.h |  2 +-
 include/qapi/qmp/qobject.h   |  2 +-
 include/qapi/visitor.h   |  2 +-
 include/qemu/sockets.h   |  2 +-
 include/qemu/throttle.h  |  2 +-
 include/qom/cpu.h|  1 +
 include/qom/object.h |  2 +-
 include/sysemu/dump.h|  2 ++
 include/sysemu/hostmem.h |  1 +
 include/sysemu/replay.h  |  1 +
 include/sysemu/sysemu.h  |  1 +
 include/sysemu/tpm.h |  1 +
 include/sysemu/watchdog.h|  2 +-
 include/ui/input.h   |  2 +-
 io/channel-socket.c  |  1 +
 io/dns-resolver.c|  1 +
 migration/colo-failover.c|  2 +-
 migration/colo.c |  2 +-
 migration/migration.c|  4 ++--
 migration/migration.h|  1 +
 migration/ram.c  |  2 +-
 migration/ram.h  |  2 +-
 net/colo-compare.c   |  1 -
 net/filter-buffer.c  |  2 +-
 net/filter-mirror.c  |  1 -
 net/filter-rewriter.c|  1 -
 net/net.c|  4 ++--
 net/tap_int.h|  2 +-
 net/vhost-user.c |  2 +-
 qemu-img.c   |  2 +-
 qom/object.c |  2 +-
 qom/object_interfaces.c  |  1 -
 replay/replay-input.c|  1 +
 replication.h|  1 +
 scripts/qapi/commands.py | 14 --
 scripts/qapi/events.py   | 10 ++
 scripts/qapi/types.py|  8 +---
 scripts/qapi/visit.py| 10 ++
 stubs/tpm.c  |  3 ++-
 target/s390x/kvm.c   |  1 -
 tests/test-char.c|  2 +-
 tests/test-qmp-event.c   |  1 -
 tpm.c|  2 +-
 trace/qmp.c  |  2 +-
 ui/console.c |  2 +-
 

[Qemu-devel] [PATCH v2 11/29] qapi: Improve include file name reporting in error messages

2018-02-11 Thread Markus Armbruster
Error messages print absolute file names of included files even if the
user gave a relative one on the command line:

$ PYTHONPATH=scripts python -B tests/qapi-schema/test-qapi.py 
tests/qapi-schema/include-cycle.json
In file included from tests/qapi-schema/include-cycle.json:1:
In file included from 
/work/armbru/qemu/tests/qapi-schema/include-cycle-b.json:1:
/work/armbru/qemu/tests/qapi-schema/include-cycle-c.json:1: Inclusion loop 
for include-cycle.json

Improve this to

In file included from tests/qapi-schema/include-cycle.json:1:
In file included from tests/qapi-schema/include-cycle-b.json:1:
tests/qapi-schema/include-cycle-c.json:1: Inclusion loop for 
include-cycle.json

The error message when an include file can't be opened prints the
include directive's file name, which is relative to the including
file.  Change this to print the file name relative to the working
directory.  Visible in tests/qapi-schema/include-no-file.err.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Marc-André Lureau 
---
 scripts/qapi/common.py| 12 ++--
 tests/qapi-schema/include-no-file.err |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 2e58573a39..3e92b38ade 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -259,9 +259,8 @@ class QAPIDoc(object):
 class QAPISchemaParser(object):
 
 def __init__(self, fp, previously_included=[], incl_info=None):
-abs_fname = os.path.abspath(fp.name)
 self.fname = fp.name
-previously_included.append(abs_fname)
+previously_included.append(os.path.abspath(fp.name))
 self.incl_info = incl_info
 self.src = fp.read()
 if self.src == '' or self.src[-1] != '\n':
@@ -292,7 +291,7 @@ class QAPISchemaParser(object):
 if not isinstance(include, str):
 raise QAPISemError(info,
"Value of 'include' must be a string")
-self._include(include, info, os.path.dirname(abs_fname),
+self._include(include, info, os.path.dirname(self.fname),
   previously_included)
 elif "pragma" in expr:
 self.reject_expr_doc(cur_doc)
@@ -325,7 +324,8 @@ class QAPISchemaParser(object):
 % doc.symbol)
 
 def _include(self, include, info, base_dir, previously_included):
-incl_abs_fname = os.path.join(base_dir, include)
+incl_fname = os.path.join(base_dir, include)
+incl_abs_fname = os.path.abspath(incl_fname)
 # catch inclusion cycle
 inf = info
 while inf:
@@ -337,9 +337,9 @@ class QAPISchemaParser(object):
 if incl_abs_fname in previously_included:
 return
 try:
-fobj = open(incl_abs_fname, 'r')
+fobj = open(incl_fname, 'r')
 except IOError as e:
-raise QAPISemError(info, '%s: %s' % (e.strerror, include))
+raise QAPISemError(info, '%s: %s' % (e.strerror, incl_fname))
 exprs_include = QAPISchemaParser(fobj, previously_included, info)
 self.exprs.extend(exprs_include.exprs)
 self.docs.extend(exprs_include.docs)
diff --git a/tests/qapi-schema/include-no-file.err 
b/tests/qapi-schema/include-no-file.err
index d5b9b22d85..e42bcf4bc1 100644
--- a/tests/qapi-schema/include-no-file.err
+++ b/tests/qapi-schema/include-no-file.err
@@ -1 +1 @@
-tests/qapi-schema/include-no-file.json:1: No such file or directory: 
include-no-file-sub.json
+tests/qapi-schema/include-no-file.json:1: No such file or directory: 
tests/qapi-schema/include-no-file-sub.json
-- 
2.13.6




[Qemu-devel] [PATCH v2 13/29] qapi: Lift error reporting from QAPISchema.__init__() to callers

2018-02-11 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Marc-André Lureau 
---
 scripts/qapi-gen.py|  8 ++--
 scripts/qapi/common.py | 23 +--
 tests/qapi-schema/test-qapi.py | 10 --
 3 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/scripts/qapi-gen.py b/scripts/qapi-gen.py
index e5be484e3e..fea7d4589b 100755
--- a/scripts/qapi-gen.py
+++ b/scripts/qapi-gen.py
@@ -8,7 +8,7 @@ from __future__ import print_function
 import argparse
 import re
 import sys
-from qapi.common import QAPISchema
+from qapi.common import QAPIError, QAPISchema
 from qapi.types import gen_types
 from qapi.visit import gen_visit
 from qapi.commands import gen_commands
@@ -39,7 +39,11 @@ def main(argv):
   file=sys.stderr)
 sys.exit(1)
 
-schema = QAPISchema(args.schema)
+try:
+schema = QAPISchema(args.schema)
+except QAPIError as err:
+print(err, file=sys.stderr)
+exit(1)
 
 gen_types(schema, args.output_dir, args.prefix, args.builtins)
 gen_visit(schema, args.output_dir, args.prefix, args.builtins)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index d72c339ad5..dce289ae21 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -16,7 +16,6 @@ import errno
 import os
 import re
 import string
-import sys
 try:
 from collections import OrderedDict
 except:
@@ -1459,19 +1458,15 @@ class QAPISchemaEvent(QAPISchemaEntity):
 
 class QAPISchema(object):
 def __init__(self, fname):
-try:
-parser = QAPISchemaParser(open(fname, 'r'))
-exprs = check_exprs(parser.exprs)
-self.docs = parser.docs
-self._entity_dict = {}
-self._predefining = True
-self._def_predefineds()
-self._predefining = False
-self._def_exprs(exprs)
-self.check()
-except QAPIError as err:
-print(err, file=sys.stderr)
-exit(1)
+parser = QAPISchemaParser(open(fname, 'r'))
+exprs = check_exprs(parser.exprs)
+self.docs = parser.docs
+self._entity_dict = {}
+self._predefining = True
+self._def_predefineds()
+self._predefining = False
+self._def_exprs(exprs)
+self.check()
 
 def _def_entity(self, ent):
 # Only the predefined types are allowed to not have info
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index bb1b6dd297..4da14b43af 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -12,7 +12,7 @@
 
 from __future__ import print_function
 import sys
-from qapi.common import QAPISchema, QAPISchemaVisitor
+from qapi.common import QAPIError, QAPISchema, QAPISchemaVisitor
 
 
 class QAPISchemaTestVisitor(QAPISchemaVisitor):
@@ -52,7 +52,13 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
 for v in variants.variants:
 print('case %s: %s' % (v.name, v.type.name))
 
-schema = QAPISchema(sys.argv[1])
+
+try:
+schema = QAPISchema(sys.argv[1])
+except QAPIError as err:
+print(err, file=sys.stderr)
+exit(1)
+
 schema.visit(QAPISchemaTestVisitor())
 
 for doc in schema.docs:
-- 
2.13.6




[Qemu-devel] [PATCH v2 00/29] Modularize generated QAPI code

2018-02-11 Thread Markus Armbruster
Our qapi-schema.json is composed of modules connected by include
directives, but the generated code is monolithic all the same: one
qapi-types.h with all the types, one qapi-visit.h with all the
visitors, and so forth.  These monolithic headers get included all
over the place.  In my "build everything" tree, adding a QAPI type
recompiles about 4800 out of 5100 objects.

We wouldn't write such monolithic headers by hand.  It stands to
reason that we shouldn't generate them, either.

This series' basic idea is to split up generated headers to mirror the
schema's modular structure: one header per module.  That way, you can
include just what you need.

The compile-time improvements can be massive.  Before this series, any
QAPI schema change recompiles some 4800 out of 5100 objects in my
"build everything" tree.  Afterwards, adding a type to
qapi/migration.json recompiles a bit over 100, and a documentation
change no longer recompiles anything.

Related: Marc-André's 'unit' pragma proposal.  That's a different way
to split off parts of the generated code, motivated by the desire to
use poisoned identifiers such as TARGET_I386.  I noted in my review of
v3 that I "can either accept it, or come up with a better solution."
This is my attempt at a better solution.  It's a bit more ambitious,
and thus more useful (I hope).  The pragma has one theoretical
advantage, though: you can modularize the generated output in
different ways than the input.  The patches using don't do that,
however.

v2:
* Rebased, annoying conflicts due to the Python 2 rigmarole
* PATCH 01: New
* PATCH 02-03,08,10-11,17,19-24: Commit messages improved
  [Eric, Marc-André]
* PATCH 04: Split off the next patch [Eric]
* PATCH 05,07-08,10,19: QAPIGen methods renamed [Marc-André]
* PATCH 08,20,22: fix missing .gitignore updates
* PATCH 08:
  - generated doc renamed to qapi-doc.texi
  - qapi-code-gen.txt updated
  - useless options -c, -h dropped
* PATCH 09: New, replacing old PATCH 07
* PATCH 16: Latent bug in QAPISchema.check() fixed
* PATCH 18: New
* PATCH 19-20,22-24:
  - Common code factored out into QAPISchemaMonolithicCVisitor
and QAPISchemaModularCVisitor
  - All code-generating visitors covered
  - Consistent parameter order prefix, opt_builtins
  - R-bys dropped
* PATCH 25-29: New

Markus Armbruster (29):
  Include qapi/qmp/qerror.h exactly where needed
  qapi: Streamline boilerplate comment generation
  qapi: Generate up-to-date copyright notice
  qapi: Rename variable holding the QAPISchemaGenFOOVisitor
  qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc
  qapi: Reduce use of global variables in generators some
  qapi: Turn generators into modules
  qapi-gen: New common driver for code and doc generators
  qapi-gen: Convert from getopt to argparse
  qapi: Touch generated files only when they change
  qapi: Improve include file name reporting in error messages
  qapi/common: Eliminate QAPISchema.exprs
  qapi: Lift error reporting from QAPISchema.__init__() to callers
  qapi: Concentrate QAPISchemaParser.exprs updates in .__init__()
  qapi: Record 'include' directives in parse tree
  qapi: Generate in source order
  qapi: Record 'include' directives in intermediate representation
  qapi: Rename generated qmp-marshal.c to qmp-commands.c
  qapi: Make code-generating visitors use QAPIGen more
  qapi/types qapi/visit: Generate built-in stuff into separate files
  qapi/common: Fix guardname() for funny filenames
  qapi: Generate separate .h, .c for each module
  Include less of the generated modular QAPI headers
  qapi: Empty out qapi-schema.json
  docs/devel/writing-qmp-commands: Update for modular QAPI
  docs: Correct outdated information on QAPI
  qapi: Move qapi-schema.json to qapi/, rename generated files
  Fix up dangling references to qmp-commands.* in comment and doc
  qapi: Don't create useless directory qapi-generated

 .gitignore |  80 -
 Makefile   | 233 ++
 Makefile.objs  |  80 -
 arch_init.c|   2 +-
 backends/cryptodev.c   |   1 -
 backends/hostmem.c |   3 +-
 balloon.c  |   2 +-
 block.c|   2 -
 block/block-backend.c  |   2 +-
 block/crypto.c |   2 +-
 block/iscsi.c  |   2 +-
 block/nbd.c|   2 +-
 block/nfs.c|   2 +-
 block/qapi.c   |   4 +-
 block/qcow2.c  |   4 +-
 block/quorum.c |   2 +-
 block/sheepdog.c   |   2 +-
 block/ssh.c|   2 +-
 block/throttle-group

[Qemu-devel] [PATCH v2 15/29] qapi: Record 'include' directives in parse tree

2018-02-11 Thread Markus Armbruster
The parse tree is a list of expressions.  Except include expressions
currently get replaced by the included file's parse tree.

Instead of throwing away the include expression, keep it with the file
name expanded so you don't have to track the including file's
directory to make sense of it.

A future commit will put this include expression to use.

Signed-off-by: Markus Armbruster 
Reviewed-by: Marc-André Lureau 
---
 scripts/qapi/common.py | 21 +
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index cc5a5941dd..6d49709784 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -290,8 +290,11 @@ class QAPISchemaParser(object):
 if not isinstance(include, str):
 raise QAPISemError(info,
"Value of 'include' must be a string")
-exprs_include = self._include(include, info,
-  os.path.dirname(self.fname),
+incl_fname = os.path.join(os.path.dirname(self.fname),
+  include)
+self.exprs.append({'expr': {'include': incl_fname},
+   'info': info})
+exprs_include = self._include(include, info, incl_fname,
   previously_included)
 if exprs_include:
 self.exprs.extend(exprs_include.exprs)
@@ -326,8 +329,7 @@ class QAPISchemaParser(object):
 "Documentation for '%s' is not followed by the definition"
 % doc.symbol)
 
-def _include(self, include, info, base_dir, previously_included):
-incl_fname = os.path.join(base_dir, include)
+def _include(self, include, info, incl_fname, previously_included):
 incl_abs_fname = os.path.abspath(incl_fname)
 # catch inclusion cycle
 inf = info
@@ -893,6 +895,9 @@ def check_exprs(exprs):
 info = expr_elem['info']
 doc = expr_elem.get('doc')
 
+if 'include' in expr:
+continue
+
 if not doc and doc_required:
 raise QAPISemError(info,
"Expression missing documentation comment")
@@ -931,6 +936,9 @@ def check_exprs(exprs):
 
 # Try again for hidden UnionKind enum
 for expr_elem in exprs:
+if 'include' in expr:
+continue
+
 expr = expr_elem['expr']
 if 'union' in expr and not discriminator_find_enum_define(expr):
 name = '%sKind' % expr['union']
@@ -943,6 +951,9 @@ def check_exprs(exprs):
 
 # Validate that exprs make sense
 for expr_elem in exprs:
+if 'include' in expr:
+continue
+
 expr = expr_elem['expr']
 info = expr_elem['info']
 doc = expr_elem.get('doc')
@@ -1667,6 +1678,8 @@ class QAPISchema(object):
 self._def_command(expr, info, doc)
 elif 'event' in expr:
 self._def_event(expr, info, doc)
+elif 'include' in expr:
+pass
 else:
 assert False
 
-- 
2.13.6




Re: [Qemu-devel] [PATCH 0/3] QAPI file renames

2018-02-11 Thread Markus Armbruster
Eric Blake  writes:

> This has been mentioned on list before as a possible improvement,
> so I went ahead and did some renames to figure out how it would
> look.  Patch 1 is something I hit on the way while debugging
> patch 2 and 3; patch 2 is rather non-controversial, and patch 3
> may or may not be worth doing (but if we do it, it is going
> to cause a lot of rebase churn to anyone editing files in the
> meantime, although git rename detection will probably get things
> right more often than not).

Conflicts with my "[PATCH v2 00/29] Modularize generated QAPI code".
Your series is much smaller.  Would you mind rebasing it?



[Qemu-devel] [PATCH v2 16/29] qapi: Generate in source order

2018-02-11 Thread Markus Armbruster
The generators' conversion to visitors (merge commit 9e72681d16)
changed the processing order of entities from source order to
alphabetical order.  The next commit needs source order, so change it
back.

Signed-off-by: Markus Armbruster 
Reviewed-by: Marc-André Lureau 
---
 scripts/qapi/common.py   |   6 +-
 tests/qapi-schema/comments.out   |   2 +-
 tests/qapi-schema/doc-bad-section.out|   4 +-
 tests/qapi-schema/doc-good.out   |  32 ++--
 tests/qapi-schema/empty.out  |   2 +-
 tests/qapi-schema/event-case.out |   2 +-
 tests/qapi-schema/ident-with-escape.out  |   6 +-
 tests/qapi-schema/include-relpath.out|   2 +-
 tests/qapi-schema/include-repetition.out |   2 +-
 tests/qapi-schema/include-simple.out |   2 +-
 tests/qapi-schema/indented-expr.out  |   2 +-
 tests/qapi-schema/qapi-schema-test.out   | 320 +++
 12 files changed, 192 insertions(+), 190 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 6d49709784..b531ab519f 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1475,6 +1475,7 @@ class QAPISchema(object):
 parser = QAPISchemaParser(open(fname, 'r'))
 exprs = check_exprs(parser.exprs)
 self.docs = parser.docs
+self._entity_list = []
 self._entity_dict = {}
 self._predefining = True
 self._def_predefineds()
@@ -1486,6 +1487,7 @@ class QAPISchema(object):
 # Only the predefined types are allowed to not have info
 assert ent.info or self._predefining
 assert ent.name not in self._entity_dict
+self._entity_list.append(ent)
 self._entity_dict[ent.name] = ent
 
 def lookup_entity(self, name, typ=None):
@@ -1684,12 +1686,12 @@ class QAPISchema(object):
 assert False
 
 def check(self):
-for (name, ent) in sorted(self._entity_dict.items()):
+for ent in self._entity_list:
 ent.check(self)
 
 def visit(self, visitor):
 visitor.visit_begin(self)
-for (name, entity) in sorted(self._entity_dict.items()):
+for entity in self._entity_list:
 if visitor.visit_needed(entity):
 entity.visit(visitor)
 visitor.visit_end()
diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out
index 17e652535c..0261ddf202 100644
--- a/tests/qapi-schema/comments.out
+++ b/tests/qapi-schema/comments.out
@@ -1,4 +1,4 @@
+object q_empty
 enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
 prefix QTYPE
 enum Status ['good', 'bad', 'ugly']
-object q_empty
diff --git a/tests/qapi-schema/doc-bad-section.out 
b/tests/qapi-schema/doc-bad-section.out
index 089bde1381..23bf8c71ab 100644
--- a/tests/qapi-schema/doc-bad-section.out
+++ b/tests/qapi-schema/doc-bad-section.out
@@ -1,7 +1,7 @@
-enum Enum ['one', 'two']
+object q_empty
 enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
 prefix QTYPE
-object q_empty
+enum Enum ['one', 'two']
 doc symbol=Enum
 body=
 == Produces *invalid* texinfo
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index 1d2c250527..0c07301f07 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -1,35 +1,35 @@
+object q_empty
+enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+prefix QTYPE
+enum Enum ['one', 'two']
 object Base
 member base1: Enum optional=False
-enum Enum ['one', 'two']
+object Variant1
+member var1: str optional=False
+object Variant2
 object Object
 base Base
 tag base1
 case one: Variant1
 case two: Variant2
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
-prefix QTYPE
+object q_obj_Variant1-wrapper
+member data: Variant1 optional=False
+object q_obj_Variant2-wrapper
+member data: Variant2 optional=False
+enum SugaredUnionKind ['one', 'two']
 object SugaredUnion
 member type: SugaredUnionKind optional=False
 tag type
 case one: q_obj_Variant1-wrapper
 case two: q_obj_Variant2-wrapper
-enum SugaredUnionKind ['one', 'two']
-object Variant1
-member var1: str optional=False
-object Variant2
-command cmd q_obj_cmd-arg -> Object
-   gen=True success_response=True boxed=False
-command cmd-boxed Object -> None
-   gen=True success_response=True boxed=True
-object q_empty
-object q_obj_Variant1-wrapper
-member data: Variant1 optional=False
-object q_obj_Variant2-wrapper
-member data: Variant2 optional=False
 object q_obj_cmd-arg
 member arg1: int optional=False
 member arg2: str optional=True
 member arg3: bool optional=False
+command cmd q_obj_cmd-arg -> Object
+   gen=True success_response=True boxed=False
+command cmd-boxed Object -> None
+   gen=True success_response=True boxed=True
 doc freeform
 body=
 = Section
diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out
in

[Qemu-devel] [PATCH v2 06/29] qapi: Reduce use of global variables in generators some

2018-02-11 Thread Markus Armbruster
In preparation of the next commit, which will turn the generators into
modules.  These global variables will become local to main() then.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Marc-André Lureau 
---
 scripts/qapi-commands.py   |  9 +
 scripts/qapi-event.py  | 15 +++
 scripts/qapi-introspect.py |  7 ---
 scripts/qapi-types.py  | 17 +
 scripts/qapi-visit.py  | 17 +
 5 files changed, 34 insertions(+), 31 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 8d38ade076..e97e16e828 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -207,7 +207,7 @@ def gen_register_command(name, success_response):
 return ret
 
 
-def gen_registry(registry):
+def gen_registry(registry, prefix):
 ret = mcgen('''
 
 void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds)
@@ -224,7 +224,8 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds)
 
 
 class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
-def __init__(self):
+def __init__(self, prefix):
+self._prefix = prefix
 self.decl = None
 self.defn = None
 self._regy = None
@@ -237,7 +238,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
 self._visited_ret_types = set()
 
 def visit_end(self):
-self.defn += gen_registry(self._regy)
+self.defn += gen_registry(self._regy, self._prefix)
 self._regy = None
 self._visited_ret_types = None
 
@@ -289,7 +290,7 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
prefix=prefix, c_prefix=c_name(prefix, protect=False)))
 
 schema = QAPISchema(input_file)
-vis = QAPISchemaGenCommandVisitor()
+vis = QAPISchemaGenCommandVisitor(prefix)
 schema.visit(vis)
 genc.add(vis.defn)
 genh.add(vis.decl)
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index bd7a9be3dc..3f98e2491a 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -58,7 +58,7 @@ def gen_param_var(typ):
 return ret
 
 
-def gen_event_send(name, arg_type, boxed):
+def gen_event_send(name, arg_type, boxed, event_enum_name):
 # FIXME: Our declaration of local variables (and of 'errp' in the
 # parameter list) can collide with exploded members of the event's
 # data type passed in as parameters.  If this collision ever hits in
@@ -149,7 +149,8 @@ out:
 
 
 class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
-def __init__(self):
+def __init__(self, prefix):
+self._enum_name = c_name(prefix + 'QAPIEvent', protect=False)
 self.decl = None
 self.defn = None
 self._event_names = None
@@ -160,13 +161,13 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
 self._event_names = []
 
 def visit_end(self):
-self.decl += gen_enum(event_enum_name, self._event_names)
-self.defn += gen_enum_lookup(event_enum_name, self._event_names)
+self.decl += gen_enum(self._enum_name, self._event_names)
+self.defn += gen_enum_lookup(self._enum_name, self._event_names)
 self._event_names = None
 
 def visit_event(self, name, info, arg_type, boxed):
 self.decl += gen_event_send_decl(name, arg_type, boxed)
-self.defn += gen_event_send(name, arg_type, boxed)
+self.defn += gen_event_send(name, arg_type, boxed, self._enum_name)
 self._event_names.append(name)
 
 
@@ -199,10 +200,8 @@ genh.add(mcgen('''
 ''',
prefix=prefix))
 
-event_enum_name = c_name(prefix + 'QAPIEvent', protect=False)
-
 schema = QAPISchema(input_file)
-vis = QAPISchemaGenEventVisitor()
+vis = QAPISchemaGenEventVisitor(prefix)
 schema.visit(vis)
 genc.add(vis.defn)
 genh.add(vis.decl)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 3d65690fe3..2418b80a82 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -41,7 +41,8 @@ def to_c_string(string):
 
 
 class QAPISchemaGenIntrospectVisitor(QAPISchemaVisitor):
-def __init__(self, unmask):
+def __init__(self, prefix, unmask):
+self._prefix = prefix
 self._unmask = unmask
 self.defn = None
 self.decl = None
@@ -65,7 +66,7 @@ class QAPISchemaGenIntrospectVisitor(QAPISchemaVisitor):
 # generate C
 # TODO can generate awfully long lines
 jsons.extend(self._jsons)
-name = c_name(prefix, protect=False) + 'qmp_schema_json'
+name = c_name(self._prefix, protect=False) + 'qmp_schema_json'
 self.decl = mcgen('''
 extern const char %(c_name)s[];
 ''',
@@ -192,7 +193,7 @@ genc.add(mcgen('''
prefix=prefix))
 
 schema = QAPISchema(input_file)
-vis = QAPISchemaGenIntrospectVisitor(opt_unmask)
+vis = QAPISchemaGenIntrospectVisitor(prefix, opt_unmask)
 schema.visit(vis)
 genc.add(vis.defn)
 genh.add(vis.decl)
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index c0ac879beb..5ff2bfcf41 100644
--- a/script

Re: [Qemu-devel] [PATCH 2/3] qapi: Rename QMP and QGA schema files

2018-02-11 Thread Markus Armbruster
Eric Blake  writes:

> Having two files in the tree both named qapi-schema.json just adds
> confusion.  Rename these files, and relocate them into the common
> qapi/ subdirectory.  Update all build rules that refer to the file
> names, and adjust other documentation and comment references to
> either track the new name or be rewritten so as to not mention
> the file name.
>
> Maintainer-wise, this means that qapi/qga-schema.json continues
> to belong to Michael as QGA maintainer, but now also notifies
> Markus and Eric as QAPI maintainers, alongside all the other
> QMP QAPI files, matching how other .json QAPI modules belong
> to multiple maintainer blurbs.
>
> Signed-off-by: Eric Blake 
> ---
>  docs/devel/writing-qmp-commands.txt  | 13 ++-
>  docs/interop/qmp-intro.txt   |  3 ++-
>  Makefile | 10 
>  qga/qapi-schema.json => qapi/qga-schema.json |  0

This move is up to the QGA maintainer.  My usual argument for keeping
the schema in one place is weak for the QGA schema: it's maintained
separately, and ususuall grepped separately, too.

>  qapi-schema.json => qapi/qmp-schema.json | 34 
> ++--

While it was certainly created for QMP, it's now used for non-QMP stuff,
too.  Do we mind?

>  tpm.c|  2 +-
>  MAINTAINERS  |  2 +-
>  7 files changed, 33 insertions(+), 31 deletions(-)
>  rename qga/qapi-schema.json => qapi/qga-schema.json (100%)
>  rename qapi-schema.json => qapi/qmp-schema.json (99%)



[Qemu-devel] [PATCH v2 07/29] qapi: Turn generators into modules

2018-02-11 Thread Markus Armbruster
The next commit will introduce a common driver program for all
generators.  The generators need to be modules for that.  qapi2texi.py
already is.  Make the other generators follow suit.

The changes are actually trivial.  Obvious in the diffs once you view
them with whitespace changes ignored.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Marc-André Lureau 
---
 scripts/qapi-commands.py   | 43 ++--
 scripts/qapi-event.py  | 43 ++--
 scripts/qapi-introspect.py | 54 ++--
 scripts/qapi-types.py  | 56 ++---
 scripts/qapi-visit.py  | 62 +-
 5 files changed, 143 insertions(+), 115 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index e97e16e828..8584cb5873 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -255,16 +255,17 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
 self._regy += gen_register_command(name, success_response)
 
 
-(input_file, output_dir, do_c, do_h, prefix, opts) = parse_command_line()
+def main(argv):
+(input_file, output_dir, do_c, do_h, prefix, opts) = parse_command_line()
 
-blurb = '''
+blurb = '''
  * Schema-defined QAPI/QMP commands
 '''
 
-genc = QAPIGenC(blurb, __doc__)
-genh = QAPIGenH(blurb, __doc__)
+genc = QAPIGenC(blurb, __doc__)
+genh = QAPIGenH(blurb, __doc__)
 
-genc.add(mcgen('''
+genc.add(mcgen('''
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qemu/module.h"
@@ -279,23 +280,27 @@ genc.add(mcgen('''
 #include "%(prefix)sqmp-commands.h"
 
 ''',
-   prefix=prefix))
+   prefix=prefix))
 
-genh.add(mcgen('''
+genh.add(mcgen('''
 #include "%(prefix)sqapi-types.h"
 #include "qapi/qmp/dispatch.h"
 
 void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
 ''',
-   prefix=prefix, c_prefix=c_name(prefix, protect=False)))
-
-schema = QAPISchema(input_file)
-vis = QAPISchemaGenCommandVisitor(prefix)
-schema.visit(vis)
-genc.add(vis.defn)
-genh.add(vis.decl)
-
-if do_c:
-genc.write(output_dir, prefix + 'qmp-marshal.c')
-if do_h:
-genh.write(output_dir, prefix + 'qmp-commands.h')
+   prefix=prefix, c_prefix=c_name(prefix, protect=False)))
+
+schema = QAPISchema(input_file)
+vis = QAPISchemaGenCommandVisitor(prefix)
+schema.visit(vis)
+genc.add(vis.defn)
+genh.add(vis.decl)
+
+if do_c:
+genc.write(output_dir, prefix + 'qmp-marshal.c')
+if do_h:
+genh.write(output_dir, prefix + 'qmp-commands.h')
+
+
+if __name__ == '__main__':
+main(sys.argv)
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 3f98e2491a..e7e07f0055 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -171,16 +171,17 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
 self._event_names.append(name)
 
 
-(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
+def main(argv):
+(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
 
-blurb = '''
+blurb = '''
  * Schema-defined QAPI/QMP events
 '''
 
-genc = QAPIGenC(blurb, __doc__)
-genh = QAPIGenH(blurb, __doc__)
+genc = QAPIGenC(blurb, __doc__)
+genh = QAPIGenH(blurb, __doc__)
 
-genc.add(mcgen('''
+genc.add(mcgen('''
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "%(prefix)sqapi-event.h"
@@ -191,22 +192,26 @@ genc.add(mcgen('''
 #include "qapi/qmp-event.h"
 
 ''',
-   prefix=prefix))
+   prefix=prefix))
 
-genh.add(mcgen('''
+genh.add(mcgen('''
 #include "qapi/util.h"
 #include "%(prefix)sqapi-types.h"
 
 ''',
-   prefix=prefix))
-
-schema = QAPISchema(input_file)
-vis = QAPISchemaGenEventVisitor(prefix)
-schema.visit(vis)
-genc.add(vis.defn)
-genh.add(vis.decl)
-
-if do_c:
-genc.write(output_dir, prefix + 'qapi-event.c')
-if do_h:
-genh.write(output_dir, prefix + 'qapi-event.h')
+   prefix=prefix))
+
+schema = QAPISchema(input_file)
+vis = QAPISchemaGenEventVisitor(prefix)
+schema.visit(vis)
+genc.add(vis.defn)
+genh.add(vis.decl)
+
+if do_c:
+genc.write(output_dir, prefix + 'qapi-event.c')
+if do_h:
+genh.write(output_dir, prefix + 'qapi-event.h')
+
+
+if __name__ == '__main__':
+main(sys.argv)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 2418b80a82..b098b95053 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -167,38 +167,44 @@ const char %(c_name)s[] = %(c_string)s;
 arg_type = arg_type or self._schema.the_empty_object_type
 self._gen_json(name, 'event', {'arg-type': self._use_type(arg_type)})
 
-# Debugging aid: unmask QAPI schema's type names
-# We normally mask them, because they're not QMP wire ABI
-opt_unmask = False
 
-(input_file, output_dir,

[Qemu-devel] [PATCH v2 22/29] qapi: Generate separate .h, .c for each module

2018-02-11 Thread Markus Armbruster
Our qapi-schema.json is composed of modules connected by include
directives, but the generated code is monolithic all the same: one
qapi-types.h with all the types, one qapi-visit.h with all the
visitors, and so forth.  These monolithic headers get included all
over the place.  In my "build everything" tree, adding a QAPI type
recompiles about 4800 out of 5100 objects.

We wouldn't write such monolithic headers by hand.  It stands to
reason that we shouldn't generate them, either.

Split up generated qapi-types.h to mirror the schema's modular
structure: one header per module.  Name the main module's header
qapi-types.h, and sub-module D/B.json's header D/qapi-types-B.h.

Mirror the schema's includes in the headers, so that qapi-types.h gets
you everything exactly as before.  If you need less, you can include
one or more of the sub-module headers.  To be exploited shortly.

Split up qapi-types.c, qapi-visit.h, qapi-visit.c, qmp-commands.h,
qmp-commands.c, qapi-event.h, qapi-event.c the same way.
qmp-introspect.h, qmp-introspect.c and qapi.texi remain monolithic.

The split of qmp-commands.c duplicates static helper function
qmp_marshal_output_str() in qapi-commands-char.c and
qapi-commands-misc.c.  This happens when commands returning the same
type occur in multiple modules.  Not worth avoiding.

Since I'm going to rename qapi-event.[ch] to qapi-events.[ch], and
qmp-commands.[ch] to qapi-commands.[ch], name the shards that way
already, to reduce churn.  This requires temporary hacks in
commands.py and events.py.  They'll go away with the rename.

Signed-off-by: Markus Armbruster 
---
 .gitignore   |  60 
 Makefile | 120 +++
 Makefile.objs|  65 -
 scripts/qapi/commands.py |  35 +-
 scripts/qapi/common.py   |  21 +++--
 scripts/qapi/events.py   |  19 ++--
 6 files changed, 300 insertions(+), 20 deletions(-)

diff --git a/.gitignore b/.gitignore
index 9477a08b6b..42c57998fd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,7 +31,67 @@
 /qapi-gen-timestamp
 /qapi-builtin-types.[ch]
 /qapi-builtin-visit.[ch]
+/qapi/qapi-commands-block-core.[ch]
+/qapi/qapi-commands-block.[ch]
+/qapi/qapi-commands-char.[ch]
+/qapi/qapi-commands-common.[ch]
+/qapi/qapi-commands-crypto.[ch]
+/qapi/qapi-commands-introspect.[ch]
+/qapi/qapi-commands-migration.[ch]
+/qapi/qapi-commands-net.[ch]
+/qapi/qapi-commands-rocker.[ch]
+/qapi/qapi-commands-run-state.[ch]
+/qapi/qapi-commands-sockets.[ch]
+/qapi/qapi-commands-tpm.[ch]
+/qapi/qapi-commands-trace.[ch]
+/qapi/qapi-commands-transaction.[ch]
+/qapi/qapi-commands-ui.[ch]
+/qapi/qapi-events-block-core.[ch]
+/qapi/qapi-events-block.[ch]
+/qapi/qapi-events-char.[ch]
+/qapi/qapi-events-common.[ch]
+/qapi/qapi-events-crypto.[ch]
+/qapi/qapi-events-introspect.[ch]
+/qapi/qapi-events-migration.[ch]
+/qapi/qapi-events-net.[ch]
+/qapi/qapi-events-rocker.[ch]
+/qapi/qapi-events-run-state.[ch]
+/qapi/qapi-events-sockets.[ch]
+/qapi/qapi-events-tpm.[ch]
+/qapi/qapi-events-trace.[ch]
+/qapi/qapi-events-transaction.[ch]
+/qapi/qapi-events-ui.[ch]
+/qapi/qapi-types-block-core.[ch]
+/qapi/qapi-types-block.[ch]
+/qapi/qapi-types-char.[ch]
+/qapi/qapi-types-common.[ch]
+/qapi/qapi-types-crypto.[ch]
+/qapi/qapi-types-introspect.[ch]
+/qapi/qapi-types-migration.[ch]
+/qapi/qapi-types-net.[ch]
+/qapi/qapi-types-rocker.[ch]
+/qapi/qapi-types-run-state.[ch]
+/qapi/qapi-types-sockets.[ch]
+/qapi/qapi-types-tpm.[ch]
+/qapi/qapi-types-trace.[ch]
+/qapi/qapi-types-transaction.[ch]
+/qapi/qapi-types-ui.[ch]
 /qapi-types.[ch]
+/qapi/qapi-visit-block-core.[ch]
+/qapi/qapi-visit-block.[ch]
+/qapi/qapi-visit-char.[ch]
+/qapi/qapi-visit-common.[ch]
+/qapi/qapi-visit-crypto.[ch]
+/qapi/qapi-visit-introspect.[ch]
+/qapi/qapi-visit-migration.[ch]
+/qapi/qapi-visit-net.[ch]
+/qapi/qapi-visit-rocker.[ch]
+/qapi/qapi-visit-run-state.[ch]
+/qapi/qapi-visit-sockets.[ch]
+/qapi/qapi-visit-tpm.[ch]
+/qapi/qapi-visit-trace.[ch]
+/qapi/qapi-visit-transaction.[ch]
+/qapi/qapi-visit-ui.[ch]
 /qapi-visit.[ch]
 /qapi-event.[ch]
 /qapi-doc.texi
diff --git a/Makefile b/Makefile
index 60ddc9c945..ac9a7627a2 100644
--- a/Makefile
+++ b/Makefile
@@ -92,10 +92,70 @@ include $(SRC_PATH)/rules.mak
 GENERATED_FILES = qemu-version.h config-host.h qemu-options.def
 GENERATED_FILES += qapi-builtin-types.h qapi-builtin-types.c
 GENERATED_FILES += qapi-types.h qapi-types.c
+GENERATED_FILES += qapi/qapi-types-block-core.h qapi/qapi-types-block-core.c
+GENERATED_FILES += qapi/qapi-types-block.h qapi/qapi-types-block.c
+GENERATED_FILES += qapi/qapi-types-char.h qapi/qapi-types-char.c
+GENERATED_FILES += qapi/qapi-types-common.h qapi/qapi-types-common.c
+GENERATED_FILES += qapi/qapi-types-crypto.h qapi/qapi-types-crypto.c
+GENERATED_FILES += qapi/qapi-types-introspect.h qapi/qapi-types-introspect.c
+GENERATED_FILES += qapi/qapi-types-migration.h qapi/qapi-types-migration.c
+GENERATED_FILES += qapi/qap

[Qemu-devel] [PATCH v2 08/29] qapi-gen: New common driver for code and doc generators

2018-02-11 Thread Markus Armbruster
Whenever qapi-schema.json changes, we run six programs eleven times to
update eleven files.  Similar for qga/qapi-schema.json.  This is
silly.  Replace the six programs by a single program that spits out
all eleven files.

The programs become modules in new Python package qapi, along with the
helper library.  This requires moving them to scripts/qapi/.

Signed-off-by: Markus Armbruster 
Reviewed-by: Marc-André Lureau 
---
 .gitignore |  2 +
 Makefile   | 86 +--
 docs/devel/qapi-code-gen.txt   | 97 ++
 monitor.c  |  2 +-
 qapi-schema.json   |  2 +-
 scripts/qapi-gen.py| 41 +
 scripts/qapi/__init__.py   |  0
 scripts/{qapi-commands.py => qapi/commands.py} | 23 ++---
 scripts/{qapi.py => qapi/common.py}| 18 +---
 scripts/{qapi2texi.py => qapi/doc.py}  | 29 ++-
 scripts/{qapi-event.py => qapi/events.py}  | 23 ++---
 scripts/{qapi-introspect.py => qapi/introspect.py} | 32 ++-
 scripts/{qapi-types.py => qapi/types.py}   | 34 ++--
 scripts/{qapi-visit.py => qapi/visit.py}   | 34 ++--
 tests/Makefile.include | 56 ++---
 tests/qapi-schema/test-qapi.py |  4 +-
 16 files changed, 193 insertions(+), 290 deletions(-)
 create mode 100755 scripts/qapi-gen.py
 create mode 100644 scripts/qapi/__init__.py
 rename scripts/{qapi-commands.py => qapi/commands.py} (94%)
 rename scripts/{qapi.py => qapi/common.py} (99%)
 rename scripts/{qapi2texi.py => qapi/doc.py} (92%)
 mode change 100755 => 100644
 rename scripts/{qapi-event.py => qapi/events.py} (92%)
 rename scripts/{qapi-introspect.py => qapi/introspect.py} (90%)
 rename scripts/{qapi-types.py => qapi/types.py} (90%)
 rename scripts/{qapi-visit.py => qapi/visit.py} (92%)

diff --git a/.gitignore b/.gitignore
index 704b22285d..2f9a92f6cc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,9 +28,11 @@
 /linux-headers/asm
 /qga/qapi-generated
 /qapi-generated
+/qapi-gen-timestamp
 /qapi-types.[ch]
 /qapi-visit.[ch]
 /qapi-event.[ch]
+/qapi-doc.texi
 /qmp-commands.h
 /qmp-introspect.[ch]
 /qmp-marshal.c
diff --git a/Makefile b/Makefile
index 4ec7a3cb82..bd781c6aad 100644
--- a/Makefile
+++ b/Makefile
@@ -94,6 +94,7 @@ GENERATED_FILES += qmp-commands.h qapi-types.h qapi-visit.h 
qapi-event.h
 GENERATED_FILES += qmp-marshal.c qapi-types.c qapi-visit.c qapi-event.c
 GENERATED_FILES += qmp-introspect.h
 GENERATED_FILES += qmp-introspect.c
+GENERATED_FILES += qapi-doc.texi
 
 GENERATED_FILES += trace/generated-tcg-tracers.h
 
@@ -483,25 +484,26 @@ qemu-ga$(EXESUF): QEMU_CFLAGS += -I qga/qapi-generated
 qemu-keymap$(EXESUF): LIBS += $(XKBCOMMON_LIBS)
 qemu-keymap$(EXESUF): QEMU_CFLAGS += $(XKBCOMMON_CFLAGS)
 
-gen-out-type = $(subst .,-,$(suffix $@))
+qapi-py = $(SRC_PATH)/scripts/qapi/commands.py \
+$(SRC_PATH)/scripts/qapi/events.py \
+$(SRC_PATH)/scripts/qapi/introspect.py \
+$(SRC_PATH)/scripts/qapi/types.py \
+$(SRC_PATH)/scripts/qapi/visit.py \
+$(SRC_PATH)/scripts/qapi/common.py \
+$(SRC_PATH)/scripts/qapi/doc.py \
+$(SRC_PATH)/scripts/ordereddict.py \
+$(SRC_PATH)/scripts/qapi-gen.py
 
-qapi-py = $(SRC_PATH)/scripts/qapi.py $(SRC_PATH)/scripts/ordereddict.py
-
-qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h :\
-$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
-   $(call quiet-command,$(PYTHON_UTF8) $(SRC_PATH)/scripts/qapi-types.py \
-   $(gen-out-type) -o qga/qapi-generated -p "qga-" $<, \
-   "GEN","$@")
-qga/qapi-generated/qga-qapi-visit.c qga/qapi-generated/qga-qapi-visit.h :\
-$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
-   $(call quiet-command,$(PYTHON_UTF8) $(SRC_PATH)/scripts/qapi-visit.py \
-   $(gen-out-type) -o qga/qapi-generated -p "qga-" $<, \
-   "GEN","$@")
-qga/qapi-generated/qga-qmp-commands.h qga/qapi-generated/qga-qmp-marshal.c :\
-$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py 
$(qapi-py)
-   $(call quiet-command,$(PYTHON_UTF8) 
$(SRC_PATH)/scripts/qapi-commands.py \
-   $(gen-out-type) -o qga/qapi-generated -p "qga-" $<, \
-   "GEN","$@")
+qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h \
+qga/qapi-generated/qga-qapi-visit.c qga/qapi-generated/qga-qapi-visit.h \
+qga/qapi-generated/qga-qmp-commands.h qga/qapi-generated/qga-qmp-marshal.c \
+qga/qapi-generated/qga-qapi-doc.texi: \
+qga/qapi-generated/qapi-gen-timestamp ;
+qga/qapi-generated/qapi-gen-timestamp: $(SRC_PATH)/qga/qapi-schema.json 
$(qapi-py)
+   $(call quiet-command,$(PYTHON_UTF8) $(SRC_PATH)/scripts/qapi-gen.py \
+   -o qga/qapi-generated -p "qga-" $<, \
+   "GEN

Re: [Qemu-devel] [PATCH v2 00/29] Modularize generated QAPI code

2018-02-11 Thread no-reply
Hi,

This series failed docker-mingw@fedora build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

Type: series
Message-id: 20180211093607.27351-1-arm...@redhat.com
Subject: [Qemu-devel] [PATCH v2 00/29] Modularize generated QAPI code

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
88c36fed50 qapi: Don't create useless directory qapi-generated
8695c58a23 Fix up dangling references to qmp-commands.* in comment and doc
cb0173d2de qapi: Move qapi-schema.json to qapi/, rename generated files
0163832937 docs: Correct outdated information on QAPI
0e8593c3cc docs/devel/writing-qmp-commands: Update for modular QAPI
610c107fba qapi: Empty out qapi-schema.json
978b56117d Include less of the generated modular QAPI headers
b9fbec1f14 qapi: Generate separate .h, .c for each module
349f60fd78 qapi/common: Fix guardname() for funny filenames
7d0c330c11 qapi/types qapi/visit: Generate built-in stuff into separate files
6be749acd0 qapi: Make code-generating visitors use QAPIGen more
26fb1118b1 qapi: Rename generated qmp-marshal.c to qmp-commands.c
3373ff0b73 qapi: Record 'include' directives in intermediate representation
992e298bed qapi: Generate in source order
27ec87b85b qapi: Record 'include' directives in parse tree
704eb94f85 qapi: Concentrate QAPISchemaParser.exprs updates in .__init__()
679e456092 qapi: Lift error reporting from QAPISchema.__init__() to callers
b6747d37d3 qapi/common: Eliminate QAPISchema.exprs
12c8bc8c3c qapi: Improve include file name reporting in error messages
15d87d797d qapi: Touch generated files only when they change
c1fb7b93d8 qapi-gen: Convert from getopt to argparse
8174e1f7f9 qapi-gen: New common driver for code and doc generators
76b229359e qapi: Turn generators into modules
e9687814c8 qapi: Reduce use of global variables in generators some
df03d3d345 qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc
8dcb95864b qapi: Rename variable holding the QAPISchemaGenFOOVisitor
176807c729 qapi: Generate up-to-date copyright notice
57f04f7bcd qapi: Streamline boilerplate comment generation
dc8f4505cb Include qapi/qmp/qerror.h exactly where needed

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into '/var/tmp/patchew-tester-tmp-7cnnoaxn/src/dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
  BUILD   fedora
  GEN 
/var/tmp/patchew-tester-tmp-7cnnoaxn/src/docker-src.2018-02-11-05.15.21.19660/qemu.tar
Cloning into 
'/var/tmp/patchew-tester-tmp-7cnnoaxn/src/docker-src.2018-02-11-05.15.21.19660/qemu.tar.vroot'...
done.
Your branch is up-to-date with 'origin/test'.
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into 
'/var/tmp/patchew-tester-tmp-7cnnoaxn/src/docker-src.2018-02-11-05.15.21.19660/qemu.tar.vroot/dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
Submodule 'ui/keycodemapdb' (git://git.qemu.org/keycodemapdb.git) registered 
for path 'ui/keycodemapdb'
Cloning into 
'/var/tmp/patchew-tester-tmp-7cnnoaxn/src/docker-src.2018-02-11-05.15.21.19660/qemu.tar.vroot/ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out 
'6b3d716e2b6472eb7189d3220552280ef3d832ce'
  COPYRUNNER
RUN test-mingw in qemu:fedora 
Packages installed:
PyYAML-3.12-5.fc27.x86_64
SDL-devel-1.2.15-29.fc27.x86_64
bc-1.07.1-3.fc27.x86_64
bison-3.0.4-8.fc27.x86_64
bzip2-1.0.6-24.fc27.x86_64
ccache-3.3.5-1.fc27.x86_64
clang-5.0.1-1.fc27.x86_64
findutils-4.6.0-14.fc27.x86_64
flex-2.6.1-5.fc27.x86_64
gcc-7.3.1-2.fc27.x86_64
gcc-c++-7.3.1-2.fc27.x86_64
gettext-0.19.8.1-12.fc27.x86_64
git-2.14.3-2.fc27.x86_64
glib2-devel-2.54.3-2.fc27.x86_64
hostname-3.18-4.fc27.x86_64
libaio-devel-0.3.110-9.fc27.x86_64
libasan-7.3.1-2.fc27.x86_64
libfdt-devel-1.4.6-1.fc27.x86_64
libubsan-7.3.1-2.fc27.x86_64
make-4.2.1-4.fc27.x86_64
mingw32-SDL-1.2.15-9.fc27.noarch
mingw32-bzip2-1.0.6-9.fc27.noarch
mingw32-curl-7.54.1-2.fc27.noarch
mingw32-glib2-2.54.1-1.fc27.noarch
mingw32-gmp-6.1.2-2.fc27.noarch
mingw32-gnutls-3.5.13-2.fc27.noarch
mingw32-gtk2-2.24.31-4.fc27.noarch
mingw32-gtk3-3.22.16-1.fc27.noarch
mingw32-libjpeg-turbo-1.5.1-3.fc27.noarch
mingw32-libpng-1.6.29-2.fc27.noarch
mingw32-libssh2-1.8.0-3.fc27.noarch
mingw32-libtasn1-4.13-1.fc27.noarch
mingw32-nettle-3.3-3.fc27.noarch
mingw32-pixman-0.34.0-3.fc27.noarch
mingw32-pkg-config-0.28-9.fc27.x86_64
mingw64-SDL-1.2.15-9.fc27.noarch
mingw64-bzip2-1.0.6-9.fc27.noarch
mingw64-curl-7.54.1-2.fc27.noarch
mingw64-glib2-2.54.1-1.fc27.noarch
mingw64-gmp-6.1.2-2.fc27.noarch
mingw64-gnutls-3.5.13-2.fc27.noarch
mingw64-gtk2-2.24.31-4.fc27.noarch
mingw64-gtk3-3.22.16-1.fc27.noarch
mingw64-libjpeg-turbo-1.5

Re: [Qemu-devel] [PATCHv2 05/12] cuda: rename frequency property to tb_frequency

2018-02-11 Thread Mark Cave-Ayland

On 10/02/18 23:11, David Gibson wrote:


On Sun, Feb 11, 2018 at 09:32:14AM +1100, David Gibson wrote:

On Fri, Feb 09, 2018 at 06:51:35PM +, Mark Cave-Ayland wrote:

This allows us to more easily differentiate between the timebase frequency used
to calibrate the MacOS timers and the actual frequency of the hardware clock as
indicated by CUDA_TIMER_FREQ.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 


Applied, thanks.


Actually, this patch doesn't compile, because you've changed
ti->frequency in a couple of places where you should only be changing
s->frequency.  I've fixed it up in my tree.


Ah apologies there - this was a mistake I made quite early on in the 
patchset which I must have accidentally brought back in during a 
subsequent rebase :(


I've just done a check on patch 7 ("cuda: set timer 1 frequency property 
to CUDA_TIMER_FREQ") and confirmed that the cuda.c version in your 
ppc-for-2.12 branch matches that in my local branch, so your fixups are 
good.


Any thoughts on the last few patches? I know Philippe had a question for 
Stefan re: the trace-events patch, however it would be useful for 
patches 10/11 to be applied as they complete the transition from CUDA 
over to using the mos6522 device (also providing an initial example as 
to how it can be used).



ATB,

Mark.



Re: [Qemu-devel] [PATCHv2 05/12] cuda: rename frequency property to tb_frequency

2018-02-11 Thread David Gibson
On Sun, Feb 11, 2018 at 10:59:05AM +, Mark Cave-Ayland wrote:
> On 10/02/18 23:11, David Gibson wrote:
> 
> > On Sun, Feb 11, 2018 at 09:32:14AM +1100, David Gibson wrote:
> > > On Fri, Feb 09, 2018 at 06:51:35PM +, Mark Cave-Ayland wrote:
> > > > This allows us to more easily differentiate between the timebase 
> > > > frequency used
> > > > to calibrate the MacOS timers and the actual frequency of the hardware 
> > > > clock as
> > > > indicated by CUDA_TIMER_FREQ.
> > > > 
> > > > Signed-off-by: Mark Cave-Ayland 
> > > > Reviewed-by: Philippe Mathieu-Daudé 
> > > 
> > > Applied, thanks.
> > 
> > Actually, this patch doesn't compile, because you've changed
> > ti->frequency in a couple of places where you should only be changing
> > s->frequency.  I've fixed it up in my tree.
> 
> Ah apologies there - this was a mistake I made quite early on in the
> patchset which I must have accidentally brought back in during a subsequent
> rebase :(
> 
> I've just done a check on patch 7 ("cuda: set timer 1 frequency property to
> CUDA_TIMER_FREQ") and confirmed that the cuda.c version in your ppc-for-2.12
> branch matches that in my local branch, so your fixups are good.

Ok, great.

> Any thoughts on the last few patches? I know Philippe had a question for
> Stefan re: the trace-events patch, however it would be useful for patches
> 10/11 to be applied as they complete the transition from CUDA over to using
> the mos6522 device (also providing an initial example as to how it can be
> used).

Haven't had a chance to look at them yet.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH] net: fix misaligned member access

2018-02-11 Thread Marc-André Lureau
Hi

On Fri, Feb 9, 2018 at 8:50 PM, Philippe Mathieu-Daudé  wrote:
> Hi Marc-André,
>
> On 02/09/2018 04:03 PM, Marc-André Lureau wrote:
>> Fixes the following ASAN warnings:
>>
>> /home/elmarco/src/qemu/hw/net/net_tx_pkt.c:201:27: runtime error: member 
>> access within misaligned address 0x63128846 for type 'struct ip_header', 
>> which requires 4 byte alignment
>> 0x63128846: note: pointer points here
>>  01 00 00 00 45 00  01 a9 01 00 00 00 40 11  78 45 00 00 00 00 ff ff  ff ff 
>> 00 00 00 00 00 00  00 00
>>  ^
>> /home/elmarco/src/qemu/hw/net/net_tx_pkt.c:208:63: runtime error: member 
>> access within misaligned address 0x63128846 for type 'struct ip_header', 
>> which requires 4 byte alignment
>> 0x63128846: note: pointer points here
>>  01 00 00 00 45 00  01 a9 01 00 00 00 40 11  78 45 00 00 00 00 ff ff  ff ff 
>> 00 00 00 00 00 00  00 00
>>  ^
>> /home/elmarco/src/qemu/hw/net/net_tx_pkt.c:210:13: runtime error: member 
>> access within misaligned address 0x63128846 for type 'struct ip_header', 
>> which requires 4 byte alignment
>> 0x63128846: note: pointer points here
>>  01 00 00 00 45 00  01 a9 01 00 00 00 40 11  78 45 00 00 00 00 ff ff  ff ff 
>> 00 00 00 00 00 00  00 00
>>
>> Signed-off-by: Marc-André Lureau 
>> ---
>>  include/net/eth.h   | 4 +++-
>>  hw/net/net_tx_pkt.c | 2 +-
>>  2 files changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/net/eth.h b/include/net/eth.h
>> index 09054a506d..e6dc8a7ba0 100644
>> --- a/include/net/eth.h
>> +++ b/include/net/eth.h
>> @@ -194,7 +194,9 @@ struct tcp_hdr {
>>  #define PKT_GET_IP_HDR(p) \
>>  ((struct ip_header *)(((uint8_t *)(p)) + eth_get_l2_hdr_length(p)))
>>  #define IP_HDR_GET_LEN(p) \
>> -struct ip_header *)(p))->ip_ver_len & 0x0F) << 2)
>> +((ldub_p(p + offsetof(struct ip_header, ip_ver_len)) & 0x0F) << 2)
>
> I like the idea of using the ldst API and offsetof() macro,
> however I think it would be cleaner to use inlined static functions.

Could be a different patch. I don't see much reason to mix this with
the alignment fix.

Then you need to review the rest of the define too.

Thanks

>
>> +#define IP_HDR_GET_P(p)   \
>> +(ldub_p(p + offsetof(struct ip_header, ip_p)))
>>  #define PKT_GET_IP_HDR_LEN(p) \
>>  (IP_HDR_GET_LEN(PKT_GET_IP_HDR(p)))
>>  #define PKT_GET_IP6_HDR(p)\
>> diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
>> index e29c881bc2..162f802dd7 100644
>> --- a/hw/net/net_tx_pkt.c
>> +++ b/hw/net/net_tx_pkt.c
>> @@ -205,7 +205,7 @@ static bool net_tx_pkt_parse_headers(struct NetTxPkt 
>> *pkt)
>>  return false;
>>  }
>>
>> -pkt->l4proto = ((struct ip_header *) l3_hdr->iov_base)->ip_p;
>> +pkt->l4proto = IP_HDR_GET_P(l3_hdr->iov_base);
>>
>>  if (IP_HDR_GET_LEN(l3_hdr->iov_base) != sizeof(struct ip_header)) {
>>  /* copy optional IPv4 header data if any*/
>>
>



-- 
Marc-André Lureau



Re: [Qemu-devel] [PATCH 1/3] qapi: Pass '-u' when doing non-silent diff

2018-02-11 Thread Markus Armbruster
Eric Blake  writes:

> Ed-script diffs are awful compared to context diffs.  Fix another
> 'diff -q' while in the area (if the files are different, being
> noisy makes it easier to diagnose why).
>
> Fixes: 46ec4fce
> Signed-off-by: Eric Blake 
> ---
>  tests/Makefile.include | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index f41da235aef..375f31b5bc0 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -919,14 +919,14 @@ $(patsubst %, check-%, $(check-qapi-schema-y)): 
> check-%.json: $(SRC_PATH)/%.json
>   $^ >$*.test.out 2>$*.test.err; \
>   echo $$? >$*.test.exit, \
>   "TEST","$*.out")
> - @diff $(SRC_PATH)/$*.out $*.test.out
> + @diff -u $(SRC_PATH)/$*.out $*.test.out
>   @# Sanitize error messages (make them independent of build directory)
> - @perl -p -e 's|\Q$(SRC_PATH)\E/||g' $*.test.err | diff 
> $(SRC_PATH)/$*.err -
> - @diff $(SRC_PATH)/$*.exit $*.test.exit
> + @perl -p -e 's|\Q$(SRC_PATH)\E/||g' $*.test.err | diff -u 
> $(SRC_PATH)/$*.err -
> + @diff -u $(SRC_PATH)/$*.exit $*.test.exit

Let's diff .err before .out, because when .err differs, .out is usually
useless.

>
>  .PHONY: check-tests/qapi-schema/doc-good.texi
>  check-tests/qapi-schema/doc-good.texi: tests/qapi-schema/doc-good.test.texi
> - @diff -q $(SRC_PATH)/tests/qapi-schema/doc-good.texi $<
> + @diff -u $(SRC_PATH)/tests/qapi-schema/doc-good.texi $<
>
>  # Consolidated targets



[Qemu-devel] [Bug 1748756] [NEW] [Feature request] Support of TI AM1808 for Lego EV3

2018-02-11 Thread Sturov Fedor
Public bug reported:

It would be great if emulating TI AM1808 would be possible. It will be a
big step towards Lego Mindstorms EV3 emulation.

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1748756

Title:
  [Feature request] Support of TI AM1808 for Lego EV3

Status in QEMU:
  New

Bug description:
  It would be great if emulating TI AM1808 would be possible. It will be
  a big step towards Lego Mindstorms EV3 emulation.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1748756/+subscriptions



[Qemu-devel] [PATCHv2] linux-user: Fix sched_getaffinity mask size

2018-02-11 Thread Samuel Thibault
We properly computed the capped mask size to be put to the application
buffer, but didn't actually used it. Also, we need to return the capped mask
size instead of 0 on success.

Signed-off-by: Samuel Thibault 

---
Difference from v1:
- simplify fix
---
 linux-user/syscall.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 82b35a6bdf..bcda3362fc 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -10493,7 +10493,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 ret = arg2;
 }
 
-ret = host_to_target_cpu_mask(mask, mask_size, arg3, arg2);
+if (host_to_target_cpu_mask(mask, mask_size, arg3, ret)) {
+goto efault;
+}
 }
 }
 break;
-- 
2.15.1




[Qemu-devel] Fan mail

2018-02-11 Thread Per Gunnarsson via Qemu-devel
Thanks a lot for this software!

Now I can make Windows tutorials without having to buy a new hard drive.

(I asked Microsoft support how to install Windows on a hard drive with
other operating systems on it. Their reply was to start diskpart, select
a drive and type the command "clean".)

Regards,

Per Gunnarsson





[Qemu-devel] [PATCH] tcg: Improve tcg_gen_muli_i32/i64

2018-02-11 Thread Richard Henderson
Convert multiplication by power of two to left shift.

Signed-off-by: Richard Henderson 
---
 tcg/tcg-op.c | 24 ++--
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 3467787323..34b96d68f3 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -277,9 +277,15 @@ void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret,
 
 void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
 {
-TCGv_i32 t0 = tcg_const_i32(arg2);
-tcg_gen_mul_i32(ret, arg1, t0);
-tcg_temp_free_i32(t0);
+if (arg2 == 0) {
+tcg_gen_movi_i32(ret, 0);
+} else if (is_power_of_2(arg2)) {
+tcg_gen_shli_i32(ret, arg1, ctz32(arg2));
+} else {
+TCGv_i32 t0 = tcg_const_i32(arg2);
+tcg_gen_mul_i32(ret, arg1, t0);
+tcg_temp_free_i32(t0);
+}
 }
 
 void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
@@ -1430,9 +1436,15 @@ void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret,
 
 void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
 {
-TCGv_i64 t0 = tcg_const_i64(arg2);
-tcg_gen_mul_i64(ret, arg1, t0);
-tcg_temp_free_i64(t0);
+if (arg2 == 0) {
+tcg_gen_movi_i64(ret, 0);
+} else if (is_power_of_2(arg2)) {
+tcg_gen_shli_i64(ret, arg1, ctz64(arg2));
+} else {
+TCGv_i64 t0 = tcg_const_i64(arg2);
+tcg_gen_mul_i64(ret, arg1, t0);
+tcg_temp_free_i64(t0);
+}
 }
 
 void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
-- 
2.14.3




[Qemu-devel] [PATCH v2 1/7] target/arm: Remove ARM_CP_64BIT from ZCR_EL registers

2018-02-11 Thread Richard Henderson
Because they are ARM_CP_STATE_AA64, ARM_CP_64BIT is implied.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 180ab75458..4b102ec356 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4357,7 +4357,7 @@ static void zcr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 static const ARMCPRegInfo zcr_el1_reginfo = {
 .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
-.access = PL1_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
+.access = PL1_RW, .accessfn = zcr_access,
 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
 .writefn = zcr_write, .raw_writefn = raw_write
 };
@@ -4365,7 +4365,7 @@ static const ARMCPRegInfo zcr_el1_reginfo = {
 static const ARMCPRegInfo zcr_el2_reginfo = {
 .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
-.access = PL2_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
+.access = PL2_RW, .accessfn = zcr_access,
 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
 .writefn = zcr_write, .raw_writefn = raw_write
 };
@@ -4373,14 +4373,14 @@ static const ARMCPRegInfo zcr_el2_reginfo = {
 static const ARMCPRegInfo zcr_no_el2_reginfo = {
 .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
-.access = PL2_RW, .type = ARM_CP_64BIT,
+.access = PL2_RW,
 .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
 };
 
 static const ARMCPRegInfo zcr_el3_reginfo = {
 .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
-.access = PL3_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
+.access = PL3_RW, .accessfn = zcr_access,
 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
 .writefn = zcr_write, .raw_writefn = raw_write
 };
-- 
2.14.3




[Qemu-devel] [PATCH v2 0/7] target/arm: More SVE prep work

2018-02-11 Thread Richard Henderson
Changes for v2:
Include signal frames and PR_SVE_SET/GET_VL.


Blurb for v1:
First, we had noted that ARM_CP_64BIT needed to be removed from
the ZCR_EL registers, but the patch set was applied without
actually fixing that.

Second, there's an existing bug by which the FPCR/FPSR registers
are not properly trapped when FP is disabled.  Fix that with a
translation-time check.

Third, my attempt at using .accessfn for ZCR_EL fails to take
into account the two different exception syndromes that must be
raised.  Although they probably aren't as important as FPCR/FPSR,
handle them at translation time too.

Fourth, when writing to an AdvSIMD register, zero the rest of
the SVE register.


r~


Richard Henderson (7):
  target/arm: Remove ARM_CP_64BIT from ZCR_EL registers
  target/arm: Enforce FP access to FPCR/FPSR
  target/arm: Suppress TB end for FPCR/FPSR
  target/arm: Enforce access to ZCR_EL at translation
  target/arm: Handle SVE registers when using clear_vec_high
  linux-user: Support SVE in aarch64 signal frames
  linux-user: Implement aarch64 PR_SVE_SET/GET_VL

 target/arm/cpu.h   |  38 ++---
 target/arm/internals.h |   6 +
 linux-user/signal.c| 348 -
 linux-user/syscall.c   |  20 +++
 target/arm/cpu64.c |  61 
 target/arm/helper.c|  28 ++--
 target/arm/translate-a64.c | 181 +++
 7 files changed, 480 insertions(+), 202 deletions(-)

-- 
2.14.3




[Qemu-devel] [PATCH v2 3/7] target/arm: Suppress TB end for FPCR/FPSR

2018-02-11 Thread Richard Henderson
Nothing in either register affects the TB.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index d41fb8371f..e0184c7162 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3356,11 +3356,11 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
   .writefn = aa64_daif_write, .resetfn = arm_cp_reset_ignore },
 { .name = "FPCR", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4,
-  .access = PL0_RW, .type = ARM_CP_FPU,
+  .access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END,
   .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
 { .name = "FPSR", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4,
-  .access = PL0_RW, .type = ARM_CP_FPU,
+  .access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END,
   .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write },
 { .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0,
-- 
2.14.3




[Qemu-devel] [PATCH v2 5/7] target/arm: Handle SVE registers when using clear_vec_high

2018-02-11 Thread Richard Henderson
When storing to an AdvSIMD FP register, all of the high
bits of the SVE register are zeroed.  Therefore, call it
more often with is_q as a parameter.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 162 +
 1 file changed, 62 insertions(+), 100 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index e3881d4999..1c88539d62 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -602,13 +602,30 @@ static TCGv_i32 read_fp_sreg(DisasContext *s, int reg)
 return v;
 }
 
+/* Clear the bits above an N-bit vector, for N = (is_q ? 128 : 64).
+ * If SVE is not enabled, then there are only 128 bits in the vector.
+ */
+static void clear_vec_high(DisasContext *s, bool is_q, int rd)
+{
+unsigned ofs = fp_reg_offset(s, rd, MO_64);
+unsigned vsz = vec_full_reg_size(s);
+
+if (!is_q) {
+TCGv_i64 tcg_zero = tcg_const_i64(0);
+tcg_gen_st_i64(tcg_zero, cpu_env, ofs + 8);
+tcg_temp_free_i64(tcg_zero);
+}
+if (vsz > 16) {
+tcg_gen_gvec_dup8i(ofs + 16, vsz - 16, vsz - 16, 0);
+}
+}
+
 static void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v)
 {
-TCGv_i64 tcg_zero = tcg_const_i64(0);
+unsigned ofs = fp_reg_offset(s, reg, MO_64);
 
-tcg_gen_st_i64(v, cpu_env, fp_reg_offset(s, reg, MO_64));
-tcg_gen_st_i64(tcg_zero, cpu_env, fp_reg_hi_offset(s, reg));
-tcg_temp_free_i64(tcg_zero);
+tcg_gen_st_i64(v, cpu_env, ofs);
+clear_vec_high(s, false, reg);
 }
 
 static void write_fp_sreg(DisasContext *s, int reg, TCGv_i32 v)
@@ -1009,6 +1026,8 @@ static void do_fp_ld(DisasContext *s, int destidx, 
TCGv_i64 tcg_addr, int size)
 
 tcg_temp_free_i64(tmplo);
 tcg_temp_free_i64(tmphi);
+
+clear_vec_high(s, true, destidx);
 }
 
 /*
@@ -1124,17 +1143,6 @@ static void write_vec_element_i32(DisasContext *s, 
TCGv_i32 tcg_src,
 }
 }
 
-/* Clear the high 64 bits of a 128 bit vector (in general non-quad
- * vector ops all need to do this).
- */
-static void clear_vec_high(DisasContext *s, int rd)
-{
-TCGv_i64 tcg_zero = tcg_const_i64(0);
-
-write_vec_element(s, tcg_zero, rd, 1, MO_64);
-tcg_temp_free_i64(tcg_zero);
-}
-
 /* Store from vector register to memory */
 static void do_vec_st(DisasContext *s, int srcidx, int element,
   TCGv_i64 tcg_addr, int size)
@@ -2794,12 +2802,13 @@ static void disas_ldst_multiple_struct(DisasContext *s, 
uint32_t insn)
 /* For non-quad operations, setting a slice of the low
  * 64 bits of the register clears the high 64 bits (in
  * the ARM ARM pseudocode this is implicit in the fact
- * that 'rval' is a 64 bit wide variable). We optimize
- * by noticing that we only need to do this the first
- * time we touch a register.
+ * that 'rval' is a 64 bit wide variable).
+ * For quad operations, we might still need to zero the
+ * high bits of SVE.  We optimize by noticing that we only
+ * need to do this the first time we touch a register.
  */
-if (!is_q && e == 0 && (r == 0 || xs == selem - 1)) {
-clear_vec_high(s, tt);
+if (e == 0 && (r == 0 || xs == selem - 1)) {
+clear_vec_high(s, is_q, tt);
 }
 }
 tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
@@ -2942,10 +2951,9 @@ static void disas_ldst_single_struct(DisasContext *s, 
uint32_t insn)
 write_vec_element(s, tcg_tmp, rt, 0, MO_64);
 if (is_q) {
 write_vec_element(s, tcg_tmp, rt, 1, MO_64);
-} else {
-clear_vec_high(s, rt);
 }
 tcg_temp_free_i64(tcg_tmp);
+clear_vec_high(s, is_q, rt);
 } else {
 /* Load/store one element per register */
 if (is_load) {
@@ -6718,7 +6726,6 @@ static void handle_vec_simd_sqshrn(DisasContext *s, bool 
is_scalar, bool is_q,
 }
 
 if (!is_q) {
-clear_vec_high(s, rd);
 write_vec_element(s, tcg_final, rd, 0, MO_64);
 } else {
 write_vec_element(s, tcg_final, rd, 1, MO_64);
@@ -6731,7 +6738,8 @@ static void handle_vec_simd_sqshrn(DisasContext *s, bool 
is_scalar, bool is_q,
 tcg_temp_free_i64(tcg_rd);
 tcg_temp_free_i32(tcg_rd_narrowed);
 tcg_temp_free_i64(tcg_final);
-return;
+
+clear_vec_high(s, is_q, rd);
 }
 
 /* SQSHLU, UQSHL, SQSHL: saturating left shifts */
@@ -6795,10 +6803,7 @@ static void handle_simd_qshl(DisasContext *s, bool 
scalar, bool is_q,
 tcg_temp_free_i64(tcg_op);
 }
 tcg_temp_free_i64(tcg_shift);
-
-if (!is_q) {
-clear_vec_high(s, rd);
-}
+clear_vec_high(s, is_q, rd);
  

[Qemu-devel] [PATCH v2 2/7] target/arm: Enforce FP access to FPCR/FPSR

2018-02-11 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h   | 35 ++-
 target/arm/helper.c|  6 --
 target/arm/translate-a64.c |  3 +++
 3 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 521444a5a1..e966a57f8a 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1714,7 +1714,7 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
 }
 
 /* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
- * special-behaviour cp reg and bits [15..8] indicate what behaviour
+ * special-behaviour cp reg and bits [11..8] indicate what behaviour
  * it has. Otherwise it is a simple cp reg, where CONST indicates that
  * TCG can assume the value to be constant (ie load at translate time)
  * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
@@ -1735,24 +1735,25 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
  * need to be surrounded by gen_io_start()/gen_io_end(). In particular,
  * registers which implement clocks or timers require this.
  */
-#define ARM_CP_SPECIAL 1
-#define ARM_CP_CONST 2
-#define ARM_CP_64BIT 4
-#define ARM_CP_SUPPRESS_TB_END 8
-#define ARM_CP_OVERRIDE 16
-#define ARM_CP_ALIAS 32
-#define ARM_CP_IO 64
-#define ARM_CP_NO_RAW 128
-#define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8))
-#define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
-#define ARM_CP_NZCV (ARM_CP_SPECIAL | (3 << 8))
-#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | (4 << 8))
-#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | (5 << 8))
-#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
+#define ARM_CP_SPECIAL   0x0001
+#define ARM_CP_CONST 0x0002
+#define ARM_CP_64BIT 0x0004
+#define ARM_CP_SUPPRESS_TB_END   0x0008
+#define ARM_CP_OVERRIDE  0x0010
+#define ARM_CP_ALIAS 0x0020
+#define ARM_CP_IO0x0040
+#define ARM_CP_NO_RAW0x0080
+#define ARM_CP_NOP   (ARM_CP_SPECIAL | 0x0100)
+#define ARM_CP_WFI   (ARM_CP_SPECIAL | 0x0200)
+#define ARM_CP_NZCV  (ARM_CP_SPECIAL | 0x0300)
+#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | 0x0400)
+#define ARM_CP_DC_ZVA(ARM_CP_SPECIAL | 0x0500)
+#define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
+#define ARM_CP_FPU   0x1000
 /* Used only as a terminator for ARMCPRegInfo lists */
-#define ARM_CP_SENTINEL 0x
+#define ARM_CP_SENTINEL  0x
 /* Mask of only the flag bits in a type field */
-#define ARM_CP_FLAG_MASK 0xff
+#define ARM_CP_FLAG_MASK 0x10ff
 
 /* Valid values for ARMCPRegInfo state field, indicating which of
  * the AArch32 and AArch64 execution states this register is visible in.
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 4b102ec356..d41fb8371f 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3356,10 +3356,12 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
   .writefn = aa64_daif_write, .resetfn = arm_cp_reset_ignore },
 { .name = "FPCR", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4,
-  .access = PL0_RW, .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
+  .access = PL0_RW, .type = ARM_CP_FPU,
+  .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
 { .name = "FPSR", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4,
-  .access = PL0_RW, .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write },
+  .access = PL0_RW, .type = ARM_CP_FPU,
+  .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write },
 { .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0,
   .access = PL0_R, .type = ARM_CP_NO_RAW,
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index fb1a4cb532..89f50558a7 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1631,6 +1631,9 @@ static void handle_sys(DisasContext *s, uint32_t insn, 
bool isread,
 default:
 break;
 }
+if ((ri->type & ARM_CP_FPU) && !fp_access_check(s)) {
+return;
+}
 
 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
 gen_io_start();
-- 
2.14.3




[Qemu-devel] [PATCH v2 4/7] target/arm: Enforce access to ZCR_EL at translation

2018-02-11 Thread Richard Henderson
This also makes sure that we get the correct ordering of
SVE vs FP exceptions.

Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h   |  3 ++-
 target/arm/internals.h |  6 ++
 target/arm/helper.c| 22 --
 target/arm/translate-a64.c | 16 
 4 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index e966a57f8a..51a3e16275 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1750,10 +1750,11 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
 #define ARM_CP_DC_ZVA(ARM_CP_SPECIAL | 0x0500)
 #define ARM_LAST_SPECIAL ARM_CP_DC_ZVA
 #define ARM_CP_FPU   0x1000
+#define ARM_CP_SVE   0x2000
 /* Used only as a terminator for ARMCPRegInfo lists */
 #define ARM_CP_SENTINEL  0x
 /* Mask of only the flag bits in a type field */
-#define ARM_CP_FLAG_MASK 0x10ff
+#define ARM_CP_FLAG_MASK 0x30ff
 
 /* Valid values for ARMCPRegInfo state field, indicating which of
  * the AArch32 and AArch64 execution states this register is visible in.
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 89f5d2fe12..47cc224a46 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -243,6 +243,7 @@ enum arm_exception_class {
 EC_AA64_HVC   = 0x16,
 EC_AA64_SMC   = 0x17,
 EC_SYSTEMREGISTERTRAP = 0x18,
+EC_SVEACCESSTRAP  = 0x19,
 EC_INSNABORT  = 0x20,
 EC_INSNABORT_SAME_EL  = 0x21,
 EC_PCALIGNMENT= 0x22,
@@ -381,6 +382,11 @@ static inline uint32_t syn_fp_access_trap(int cv, int 
cond, bool is_16bit)
 | (cv << 24) | (cond << 20);
 }
 
+static inline uint32_t syn_sve_access_trap(void)
+{
+return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
+}
+
 static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
 {
 return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index e0184c7162..550dc3d290 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4335,20 +4335,6 @@ static int sve_exception_el(CPUARMState *env)
 return 0;
 }
 
-static CPAccessResult zcr_access(CPUARMState *env, const ARMCPRegInfo *ri,
- bool isread)
-{
-switch (sve_exception_el(env)) {
-case 3:
-return CP_ACCESS_TRAP_EL3;
-case 2:
-return CP_ACCESS_TRAP_EL2;
-case 1:
-return CP_ACCESS_TRAP;
-}
-return CP_ACCESS_OK;
-}
-
 static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
   uint64_t value)
 {
@@ -4359,7 +4345,7 @@ static void zcr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 static const ARMCPRegInfo zcr_el1_reginfo = {
 .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
-.access = PL1_RW, .accessfn = zcr_access,
+.access = PL1_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
 .writefn = zcr_write, .raw_writefn = raw_write
 };
@@ -4367,7 +4353,7 @@ static const ARMCPRegInfo zcr_el1_reginfo = {
 static const ARMCPRegInfo zcr_el2_reginfo = {
 .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
-.access = PL2_RW, .accessfn = zcr_access,
+.access = PL2_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
 .writefn = zcr_write, .raw_writefn = raw_write
 };
@@ -4375,14 +4361,14 @@ static const ARMCPRegInfo zcr_el2_reginfo = {
 static const ARMCPRegInfo zcr_no_el2_reginfo = {
 .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
-.access = PL2_RW,
+.access = PL2_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
 .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
 };
 
 static const ARMCPRegInfo zcr_el3_reginfo = {
 .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
-.access = PL3_RW, .accessfn = zcr_access,
+.access = PL3_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
 .writefn = zcr_write, .raw_writefn = raw_write
 };
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 89f50558a7..e3881d4999 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1182,6 +1182,19 @@ static inline bool fp_access_check(DisasContext *s)
 return false;
 }
 
+/* Check that SVE access is enabled.  If it is, return true.
+ * If not, emit code to generate an appropriate exception and return false.
+ */
+static inline bool sve_access_check(DisasContext *s)
+{
+if (s->sve_excp_el) {
+gen_exception_insn(s, 4, EXCP_UDEF, syn_sve_access_trap(),
+   s->sve_excp_el);
+return false;
+}
+ret

[Qemu-devel] [PATCH v2 7/7] linux-user: Implement aarch64 PR_SVE_SET/GET_VL

2018-02-11 Thread Richard Henderson
As an implementation choice, widening VL has zeroed the
previously inaccessible portion of the sve registers.

Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h |  2 ++
 linux-user/syscall.c | 20 +
 target/arm/cpu64.c   | 61 
 3 files changed, 83 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 51a3e16275..8e1016cfd6 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -842,6 +842,8 @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, 
CPUState *cs,
 #ifdef TARGET_AARCH64
 int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+unsigned aarch64_get_sve_vlen(CPUARMState *env);
+unsigned aarch64_set_sve_vlen(CPUARMState *env, unsigned vlen);
 #endif
 
 target_ulong do_arm_semihosting(CPUARMState *env);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 82b35a6bdf..4840bf502f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -10659,6 +10659,26 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 break;
 }
 #endif
+#ifdef TARGET_AARCH64
+case 50: /* PR_SVE_SET_VL */
+/* We cannot support either PR_SVE_SET_VL_ONEXEC
+   or PR_SVE_VL_INHERIT.  Therefore, anything above
+   ARM_MAX_VQ results in EINVAL.  */
+if (!arm_feature(cpu_env, ARM_FEATURE_SVE)
+|| arg2 > ARM_MAX_VQ * 16 || arg2 & 15) {
+ret = -TARGET_EINVAL;
+} else {
+ret = aarch64_set_sve_vlen(cpu_env, arg2);
+}
+break;
+case 51: /* PR_SVE_GET_VL */
+if (arm_feature(cpu_env, ARM_FEATURE_SVE)) {
+ret = aarch64_get_sve_vlen(cpu_env);
+} else {
+ret = -TARGET_EINVAL;
+}
+break;
+#endif /* AARCH64 */
 case PR_GET_SECCOMP:
 case PR_SET_SECCOMP:
 /* Disable seccomp to prevent the target disabling syscalls we
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 1c330adc28..6dee78f006 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -363,3 +363,64 @@ static void aarch64_cpu_register_types(void)
 }
 
 type_init(aarch64_cpu_register_types)
+
+/* Return the current cumulative SVE VLEN.  */
+unsigned aarch64_get_sve_vlen(CPUARMState *env)
+{
+return ((env->vfp.zcr_el[1] & 0xf) + 1) * 16;
+}
+
+/* Set the cumulative ZCR.EL to VLEN, or the nearest supported value.
+   Return the new value.  */
+unsigned aarch64_set_sve_vlen(CPUARMState *env, unsigned vl)
+{
+unsigned vq = vl / 16;
+unsigned old_vq = (env->vfp.zcr_el[1] & 0xf) + 1;
+
+if (vq < 1) {
+vq = 1;
+} else if (vq > ARM_MAX_VQ) {
+vq = ARM_MAX_VQ;
+}
+env->vfp.zcr_el[1] = vq - 1;
+
+/* The manual sez that when SVE is enabled and VL is widened the
+ * implementation is allowed to zero the previously inaccessible
+ * portion of the registers.  The corollary to that is that when
+ * SVE is enabled and VL is narrowed we are also allowed to zero
+ * the now inaccessible portion of the registers.
+ *
+ * The intent of this is that no predicate bit beyond VL is ever set.
+ * Which means that some operations on predicate registers themselves
+ * may operate on full uint64_t or even unrolled across the maximum
+ * uint64_t[4].  Performing 4 bits of host arithmetic unconditionally
+ * may well be cheaper than conditionals to restrict to the operation
+ * to the relevant portion of a uint16_t[16].
+ *
+ * ??? Need to move this somewhere else, so that it applies to
+ * changes to the real system registers and EL state changes.
+ */
+if (vq < old_vq) {
+unsigned i, j;
+uint64_t pmask;
+
+/* Zap the high bits of the zregs.  */
+for (i = 0; i < 32; i++) {
+memset(&env->vfp.zregs[i].d[2 * vq], 0, 16 * (ARM_MAX_VQ - vq));
+}
+
+/* Zap the high bits of the pregs and ffr.  */
+pmask = 0;
+if (vq & 3) {
+pmask = ~(-1ULL << (16 * (vq & 3)));
+}
+for (j = vq / 4; j < ARM_MAX_VQ / 4; j++) {
+for (i = 0; i < 17; ++i) {
+env->vfp.pregs[i].p[j] &= pmask;
+}
+pmask = 0;
+}
+}
+
+return vq * 16;
+}
-- 
2.14.3




[Qemu-devel] [PATCH v2 6/7] linux-user: Support SVE in aarch64 signal frames

2018-02-11 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/signal.c | 348 ++--
 1 file changed, 283 insertions(+), 65 deletions(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 9a380b9e31..af953175db 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -1443,35 +1443,61 @@ struct target_fpsimd_context {
 uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
 };
 
-/*
- * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
- * user space as it will change with the addition of new context. User space
- * should check the magic/size information.
- */
-struct target_aux_context {
-struct target_fpsimd_context fpsimd;
-/* additional context to be added before "end" */
-struct target_aarch64_ctx end;
+#define TARGET_EXTRA_MAGIC  0x45585401
+
+struct target_extra_context {
+struct target_aarch64_ctx head;
+uint64_t datap; /* 16-byte aligned pointer to extra space cast to __u64 */
+uint32_t size; /* size in bytes of the extra space */
+uint32_t reserved[3];
+};
+
+#define TARGET_SVE_MAGIC0x53564501
+
+struct target_sve_context {
+struct target_aarch64_ctx head;
+uint16_t vl;
+uint16_t reserved[3];
 };
 
+#define TARGET_SVE_VQ_BYTES  16
+
+#define TARGET_SVE_SIG_ZREG_SIZE(VQ)  ((VQ) * TARGET_SVE_VQ_BYTES)
+#define TARGET_SVE_SIG_PREG_SIZE(VQ)  ((VQ) * (TARGET_SVE_VQ_BYTES / 8))
+
+#define TARGET_SVE_SIG_REGS_OFFSET \
+QEMU_ALIGN_UP(sizeof(struct target_sve_context), TARGET_SVE_VQ_BYTES)
+#define TARGET_SVE_SIG_ZREG_OFFSET(VQ, N) \
+(TARGET_SVE_SIG_REGS_OFFSET + TARGET_SVE_SIG_ZREG_SIZE(VQ) * (N))
+#define TARGET_SVE_SIG_PREG_OFFSET(VQ, N) \
+(TARGET_SVE_SIG_ZREG_OFFSET(VQ, 32) + TARGET_SVE_SIG_PREG_SIZE(VQ) * (N))
+#define TARGET_SVE_SIG_FFR_OFFSET(VQ) \
+(TARGET_SVE_SIG_PREG_OFFSET(VQ, 16))
+#define TARGET_SVE_SIG_CONTEXT_SIZE(VQ) \
+(TARGET_SVE_SIG_PREG_OFFSET(VQ, 17))
+
 struct target_rt_sigframe {
 struct target_siginfo info;
 struct target_ucontext uc;
+};
+
+struct target_rt_frame_record {
 uint64_t fp;
 uint64_t lr;
 uint32_t tramp[2];
 };
 
-static int target_setup_sigframe(struct target_rt_sigframe *sf,
- CPUARMState *env, target_sigset_t *set)
+static void target_setup_general_frame(struct target_rt_sigframe *sf,
+   CPUARMState *env, target_sigset_t *set)
 {
 int i;
-struct target_aux_context *aux =
-(struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
 
-/* set up the stack frame for unwinding */
-__put_user(env->xregs[29], &sf->fp);
-__put_user(env->xregs[30], &sf->lr);
+__put_user(0, &sf->uc.tuc_flags);
+__put_user(0, &sf->uc.tuc_link);
+
+__put_user(target_sigaltstack_used.ss_sp, &sf->uc.tuc_stack.ss_sp);
+__put_user(sas_ss_flags(env->xregs[31]), &sf->uc.tuc_stack.ss_flags);
+__put_user(target_sigaltstack_used.ss_size, &sf->uc.tuc_stack.ss_size);
 
 for (i = 0; i < 31; i++) {
 __put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
@@ -1485,39 +1511,79 @@ static int target_setup_sigframe(struct 
target_rt_sigframe *sf,
 for (i = 0; i < TARGET_NSIG_WORDS; i++) {
 __put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
 }
+}
+
+static void target_setup_end_record(struct target_aarch64_ctx *end)
+{
+__put_user(0, &end->magic);
+__put_user(0, &end->size);
+}
+
+static void target_setup_fpsimd_record(struct target_fpsimd_context *fpsimd,
+   CPUARMState *env)
+{
+int i;
+
+__put_user(TARGET_FPSIMD_MAGIC, &fpsimd->head.magic);
+__put_user(sizeof(struct target_fpsimd_context), &fpsimd->head.size);
+__put_user(vfp_get_fpsr(env), &fpsimd->fpsr);
+__put_user(vfp_get_fpcr(env), &fpsimd->fpcr);
 
 for (i = 0; i < 32; i++) {
 uint64_t *q = aa64_vfp_qreg(env, i);
 #ifdef TARGET_WORDS_BIGENDIAN
-__put_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
-__put_user(q[1], &aux->fpsimd.vregs[i * 2]);
+__put_user(q[0], &fpsimd->vregs[i * 2 + 1]);
+__put_user(q[1], &fpsimd->vregs[i * 2]);
 #else
-__put_user(q[0], &aux->fpsimd.vregs[i * 2]);
-__put_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
+__put_user(q[0], &fpsimd->vregs[i * 2]);
+__put_user(q[1], &fpsimd->vregs[i * 2 + 1]);
 #endif
 }
-__put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
-__put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr);
-__put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
-__put_user(sizeof(struct target_fpsimd_context),
-&aux->fpsimd.head.size);
+}
 
-/* set the "end" magic */
-__put_user(0, &aux->end.magic);
-__put_user(0, &aux->end.size);
+static void target_setup_extra_record(struct target_extra_context *extra,
+  uint64_t datap, uint32_t extra_size)
+{
+__put_user(TARGET_EXTRA_MAGIC, &extra->head.magic);
+   

[Qemu-devel] [PATCH v2] scripts: Add decodetree.py

2018-02-11 Thread Richard Henderson
To be used to decode ARM SVE, but could be used for any fixed-width ISA.

Signed-off-by: Richard Henderson 
---

Changes since v1:
  * Pass pycodestyle-{2,3}.
  * Support 16-bit and 32-bit insns (I have a def file for thumb1).
  * Testsuite (only negative tests so far).
  * Called translate functions default to static.
  * Notice duplicate assignments and missing assignments to fields.
  * Use '-' to indicate a non-decoded bit, as opposed to '.' which
must be filled in elsewhere by a format or a field.

---
 scripts/decodetree.py | 1026 +
 tests/Makefile.include|9 +-
 tests/decode/check.sh |   16 +
 tests/decode/err_argset1.def  |1 +
 tests/decode/err_argset2.def  |1 +
 tests/decode/err_field1.def   |1 +
 tests/decode/err_field2.def   |1 +
 tests/decode/err_field3.def   |1 +
 tests/decode/err_field4.def   |2 +
 tests/decode/err_field5.def   |1 +
 tests/decode/err_init1.def|2 +
 tests/decode/err_init2.def|2 +
 tests/decode/err_init3.def|3 +
 tests/decode/err_init4.def|3 +
 tests/decode/err_overlap1.def |2 +
 tests/decode/err_overlap2.def |2 +
 tests/decode/err_overlap3.def |2 +
 tests/decode/err_overlap4.def |2 +
 tests/decode/err_overlap5.def |1 +
 tests/decode/err_overlap6.def |2 +
 tests/decode/err_overlap7.def |2 +
 21 files changed, 1081 insertions(+), 1 deletion(-)
 create mode 100755 scripts/decodetree.py
 create mode 100755 tests/decode/check.sh
 create mode 100644 tests/decode/err_argset1.def
 create mode 100644 tests/decode/err_argset2.def
 create mode 100644 tests/decode/err_field1.def
 create mode 100644 tests/decode/err_field2.def
 create mode 100644 tests/decode/err_field3.def
 create mode 100644 tests/decode/err_field4.def
 create mode 100644 tests/decode/err_field5.def
 create mode 100644 tests/decode/err_init1.def
 create mode 100644 tests/decode/err_init2.def
 create mode 100644 tests/decode/err_init3.def
 create mode 100644 tests/decode/err_init4.def
 create mode 100644 tests/decode/err_overlap1.def
 create mode 100644 tests/decode/err_overlap2.def
 create mode 100644 tests/decode/err_overlap3.def
 create mode 100644 tests/decode/err_overlap4.def
 create mode 100644 tests/decode/err_overlap5.def
 create mode 100644 tests/decode/err_overlap6.def
 create mode 100644 tests/decode/err_overlap7.def

diff --git a/scripts/decodetree.py b/scripts/decodetree.py
new file mode 100755
index 00..3c20acf700
--- /dev/null
+++ b/scripts/decodetree.py
@@ -0,0 +1,1026 @@
+#!/usr/bin/env python
+#
+# Generate a decoding tree from a specification file.
+#
+# The tree is built from instruction "patterns".  A pattern may represent
+# a single architectural instruction or a group of same, depending on what
+# is convenient for further processing.
+#
+# Each pattern has "fixedbits" & "fixedmask", the combination of which
+# describes the condition under which the pattern is matched:
+#
+#   (insn & fixedmask) == fixedbits
+#
+# Each pattern may have "fields", which are extracted from the insn and
+# passed along to the translator.  Examples of such are registers,
+# immediates, and sub-opcodes.
+#
+# In support of patterns, one may declare fields, argument sets, and
+# formats, each of which may be re-used to simplify further definitions.
+#
+# *** Field syntax:
+#
+# field_def := '%' identifier ( unnamed_field )+ ( !function=identifier )?
+# unnamed_field := number ':' ( 's' ) number
+#
+# For unnamed_field, the first number is the least-significant bit position of
+# the field and the second number is the length of the field.  If the 's' is
+# present, the field is considered signed.  If multiple unnamed_fields are
+# present, they are concatenated.  In this way one can define disjoint fields.
+#
+# If !function is specified, the concatenated result is passed through the
+# named function, taking and returning an integral value.
+#
+# FIXME: the fields of the structure into which this result will be stored
+# is restricted to "int".  Which means that we cannot expand 64-bit items.
+#
+# Field examples:
+#
+#   %disp   0:s16  -- sextract(i, 0, 16)
+#   %imm9   16:6 10:3  -- extract(i, 16, 6) << 3 | extract(i, 10, 3)
+#   %disp12 0:s1 1:1 2:10  -- sextract(i, 0, 1) << 11
+# | extract(i, 1, 1) << 10
+# | extract(i, 2, 10)
+#   %shimm8 5:s8 13:1 !function=expand_shimm8
+#  -- expand_shimm8(sextract(i, 5, 8) << 1
+#   | extract(i, 13, 1))
+#
+# *** Argument set syntax:
+#
+# args_def:= '&' identifier ( args_elt )+
+# args_elt:= identifier
+#
+# Each args_elt defines an argument within the argument set.
+# Each argument set will be rendered as a C structure "arg_$name"
+# with each of the fields being one of the member arguments.
+#
+# Argument set examples:
+#
+#   ®3   ra rb rc
+#   &loadstore  reg base 

Re: [Qemu-devel] [PATCH v2 02/19] spapr: introduce a skeleton for the XIVE interrupt controller

2018-02-11 Thread Benjamin Herrenschmidt
On Sun, 2018-02-11 at 19:08 +1100, David Gibson wrote:
> On Thu, Jan 18, 2018 at 08:27:52AM +1100, Benjamin Herrenschmidt wrote:
> > On Wed, 2018-01-17 at 15:39 +0100, Cédric Le Goater wrote:
> > > Migration is a problem. We will need both backend QEMU objects to be 
> > > available anyhow if we want to migrate. So we are back to the current 
> > > solution creating both QEMU objects but we can try to defer some of the 
> > > KVM inits and create the KVM device on demand at CAS time.
> > 
> > Do we have a way to migrate a piece of info from the machine *first*
> > that indicate what type of XICS/XIVE to instanciate ?
> 
> Nope.  qemu migration doesn't work like that.  Yes, it should, and
> everyone knows it, but changing it is a really long term project.

Well, we have a problem then. It looks like Qemu broken migration is
fundamentally incompatible with PAPR and CAS design...

I know we don't migrate the configuration, that's not exactly what I
had in mind tho... Can we have some piece of *data* from the machine be
migrated first, and use it on the target to reconfigure the interrupt
controller before the stream arrives ?

Otherwise, we have indeed no much choice but the horrible wart of
creating both interrupt controllers with only one "active".

> > 
> > > The next problem is the ICP object that currently needs the KVM device 
> > > fd to connect the vcpus ... So, we will need to change that also. 
> > > That is probably the biggest problem today. We need a way to disconnect 
> > > the vpcu from the KVM device and see how we can defer the connection.
> > > I need to make sure this is possible, I can check that without XIVE
> > 
> > Ben.
> > 
> 
> 



Re: [Qemu-devel] [PATCH v2] scripts: Add decodetree.py

2018-02-11 Thread Richard Henderson
> Changes since v1:
>   * Pass pycodestyle-{2,3}.
>   * Support 16-bit and 32-bit insns (I have a def file for thumb1).

For the record, here's the thumb1 definition.

./scripts/decodetree.py -w16 thumb1.def


r~
%reg_0_77:1 0:3

@rd_rs  ..  rs:3 rd:3
@rt_rn_rm    ... rm:3 rn:3 rt:3
@rd_rn_rm    ... rm:3 rn:3 rd:3
@rd_rn_i3    ... imm:3 rn:3 rd:3
@rt_rn_i5   . imm:5 rn:3 rt:3
@rd_i8  . rd:3 imm:8
@rn_reglist . rn:3 reglist:8

 Data Processing (two low registers)

AND 01  ... ... @rd_rs
EOR 01 0001 ... ... @rd_rs
MOV_lsl 01 0010 ... ... @rd_rs
MOV_lsr 01 0011 ... ... @rd_rs
MOV_asr 01 0100 ... ... @rd_rs
ADC 01 0101 ... ... @rd_rs
SBC 01 0110 ... ... @rd_rs
MOV_ror 01 0111 ... ... @rd_rs
TST 01 1000 ... ... @rd_rs
RSB 01 1001 ... ... @rd_rs
CMP_rr  01 1010 ... ... @rd_rs
CMN 01 1011 ... ... @rd_rs
ORR 01 1100 ... ... @rd_rs
MUL 01 1101 ... ... @rd_rs
BIC 01 1110 ... ... @rd_rs
MVN 01  ... ... @rd_rs

 Load/store (register offset)

STR_rr  0101 000 ... ... ...@rt_rn_rm
STRH_rr 0101 001 ... ... ...@rt_rn_rm
STRB_rr 0101 010 ... ... ...@rt_rn_rm
LDRSB_rr0101 011 ... ... ...@rt_rn_rm
LDR_rr  0101 100 ... ... ...@rt_rn_rm
LDRH_rr 0101 101 ... ... ...@rt_rn_rm
LDRB_rr 0101 110 ... ... ...@rt_rn_rm
LDRSH_rr0101 111 ... ... ...@rt_rn_rm

 Load/store word/byte (immediate offset)

STR_ri  01100 . ... ... @rt_rn_i5
LDR_ri  01101 . ... ... @rt_rn_i5
STRB_ri 01110 . ... ... @rt_rn_i5
LDRB_ri 0 . ... ... @rt_rn_i5

 Load/store halfword (immediate offset)

STRH_ri 1 . ... ... @rt_rn_i5
LDRH_ri 10001 . ... ... @rt_rn_i5

 Add PC/SP (immediate)

ADR 10100 ...   @rd_i8
ADD_sp  10101 ...   @rd_i8

 Load/store multiple

STM 11000 ...   @rn_reglist
LDM 11001 ...   @rn_reglist

 Add/subtract (three low registers)

ADD_rrr 0001100 ... ... ... @rd_rn_rm
SUB_rrr 0001101 ... ... ... @rd_rn_rm

 Add/subtract (two low registers and immediate)

ADD_rri 0001 110 ... ... ...@rd_rn_i3
SUB_rri 0001 111 ... ... ...@rd_rn_i3

 Add, subtract, compare, move (one low register and immediate)

MOV_ri  00100 ...   @rd_i8
CMP_ri  00101 ...   @rd_i8
ADD_ri  00110 ...   @rd_i8
SUB_ri  00111 ...   @rd_i8

 Branch and exchange

BX  0100 0111 0 rm:4 000
BLX 0100 0111 1 rm:4 000

 Add, subtract, compare, move (two high registers)

ADD_rrr 0100 0100 . rm:4 ...rd=%reg_0_7 rn=%reg_0_7
CMP_rr  0100 0101 . rs:4 ...rd=%reg_0_7
MOV_rr  0100 0110 . rs:4 ...rd=%reg_0_7

 Adjust SP (immediate)

ADD_rri 1011  0 imm:7   rd=13 rn=13
SUB_rri 1011  1 imm:7   rd=13 rn=13

 Extend

SXTH1011 0010 00 ... ...@rd_rs
SXTB1011 0010 01 ... ...@rd_rs
UXTH1011 0010 10 ... ...@rd_rs
UXTB1011 0010 11 ... ...@rd_rs

 Change processor state

SETEND  1011 0110 010 flags:5
CPS 1011 0110 011 flags:5

 Reverse bytes

REV 1011 1010 00 ... ...@rd_rs
REV16   1011 1010 01 ... ...@rd_rs
REVSH   1011 1010 11 ... ...@rd_rs

 Hints

NOP 1011   
YIELD   1011  0001 
WFE 1011  0010 
WFI 1011  0011 
SEV 1011  0100 
SEVL1011  0101 
NOP 1011  011-  # Reserved hint
NOP 1011  1---  # Reserved hint

 Push and Pop

PUSH1011 010 reglist:9
POP 1011 110 reglist:9

 Conditional branches

Bcond   1101 0 cond:3 imm:8
Bcond   1101 1000 imm:8 cond=8
Bcond   1101 1001 imm:8 cond=9
Bcond   1101 1010 imm:8 cond=10
Bcond   1101 1011 imm:8 cond=11
Bcond   1101 1100 imm:8 cond=12
Bcond   1101 1101 imm:8 cond=13

 Exception generation

UDF 1101 1110 imm:8
SVC 1101  imm:8


Re: [Qemu-devel] [PATCH v2] scripts: Add decodetree.py

2018-02-11 Thread no-reply
Hi,

This series failed docker-quick@centos6 build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

Type: series
Message-id: 20180211224656.12767-1-richard.hender...@linaro.org
Subject: [Qemu-devel] [PATCH v2] scripts: Add decodetree.py

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
1d531c8d23 scripts: Add decodetree.py

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into '/var/tmp/patchew-tester-tmp-_dti_j7r/src/dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
  BUILD   centos6
  GEN 
/var/tmp/patchew-tester-tmp-_dti_j7r/src/docker-src.2018-02-11-17.56.03.1101/qemu.tar
Cloning into 
'/var/tmp/patchew-tester-tmp-_dti_j7r/src/docker-src.2018-02-11-17.56.03.1101/qemu.tar.vroot'...
done.
Checking out files:  50% (2923/5827)   
Checking out files:  51% (2972/5827)   
Checking out files:  52% (3031/5827)   
Checking out files:  53% (3089/5827)   
Checking out files:  54% (3147/5827)   
Checking out files:  55% (3205/5827)   
Checking out files:  56% (3264/5827)   
Checking out files:  57% (3322/5827)   
Checking out files:  58% (3380/5827)   
Checking out files:  59% (3438/5827)   
Checking out files:  60% (3497/5827)   
Checking out files:  61% (3555/5827)   
Checking out files:  62% (3613/5827)   
Checking out files:  63% (3672/5827)   
Checking out files:  64% (3730/5827)   
Checking out files:  65% (3788/5827)   
Checking out files:  66% (3846/5827)   
Checking out files:  67% (3905/5827)   
Checking out files:  68% (3963/5827)   
Checking out files:  69% (4021/5827)   
Checking out files:  70% (4079/5827)   
Checking out files:  71% (4138/5827)   
Checking out files:  72% (4196/5827)   
Checking out files:  73% (4254/5827)   
Checking out files:  74% (4312/5827)   
Checking out files:  75% (4371/5827)   
Checking out files:  76% (4429/5827)   
Checking out files:  77% (4487/5827)   
Checking out files:  78% (4546/5827)   
Checking out files:  79% (4604/5827)   
Checking out files:  80% (4662/5827)   
Checking out files:  81% (4720/5827)   
Checking out files:  82% (4779/5827)   
Checking out files:  83% (4837/5827)   
Checking out files:  84% (4895/5827)   
Checking out files:  85% (4953/5827)   
Checking out files:  86% (5012/5827)   
Checking out files:  87% (5070/5827)   
Checking out files:  88% (5128/5827)   
Checking out files:  89% (5187/5827)   
Checking out files:  90% (5245/5827)   
Checking out files:  91% (5303/5827)   
Checking out files:  92% (5361/5827)   
Checking out files:  93% (5420/5827)   
Checking out files:  94% (5478/5827)   
Checking out files:  95% (5536/5827)   
Checking out files:  96% (5594/5827)   
Checking out files:  97% (5653/5827)   
Checking out files:  97% (5659/5827)   
Checking out files:  98% (5711/5827)   
Checking out files:  99% (5769/5827)   
Checking out files: 100% (5827/5827)   
Checking out files: 100% (5827/5827), done.
Your branch is up-to-date with 'origin/test'.
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into 
'/var/tmp/patchew-tester-tmp-_dti_j7r/src/docker-src.2018-02-11-17.56.03.1101/qemu.tar.vroot/dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
Submodule 'ui/keycodemapdb' (git://git.qemu.org/keycodemapdb.git) registered 
for path 'ui/keycodemapdb'
Cloning into 
'/var/tmp/patchew-tester-tmp-_dti_j7r/src/docker-src.2018-02-11-17.56.03.1101/qemu.tar.vroot/ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out 
'6b3d716e2b6472eb7189d3220552280ef3d832ce'
  COPYRUNNER
RUN test-quick in qemu:centos6 
Packages installed:
SDL-devel-1.2.14-7.el6_7.1.x86_64
bison-2.4.1-5.el6.x86_64
bzip2-devel-1.0.5-7.el6_0.x86_64
ccache-3.1.6-2.el6.x86_64
csnappy-devel-0-6.20150729gitd7bc683.el6.x86_64
flex-2.5.35-9.el6.x86_64
gcc-4.4.7-18.el6.x86_64
gettext-0.17-18.el6.x86_64
git-1.7.1-9.el6_9.x86_64
glib2-devel-2.28.8-9.el6.x86_64
libepoxy-devel-1.2-3.el6.x86_64
libfdt-devel-1.4.0-1.el6.x86_64
librdmacm-devel-1.0.21-0.el6.x86_64
lzo-devel-2.03-3.1.el6_5.1.x86_64
make-3.81-23.el6.x86_64
mesa-libEGL-devel-11.0.7-4.el6.x86_64
mesa-libgbm-devel-11.0.7-4.el6.x86_64
package g++ is not installed
pixman-devel-0.32.8-1.el6.x86_64
spice-glib-devel-0.26-8.el6.x86_64
spice-server-devel-0.12.4-16.el6.x86_64
tar-1.23-15.el6_8.x86_64
vte-devel-0.25.1-9.el6.x86_64
xen-devel-4.6.6-2.el6.x86_64
zlib-devel-1.2.3-29.el6.x86_64

Environment variables:
PACKAGES=bison bzip2-devel ccache csnappy-devel flex g++
 gcc gettext git glib2-devel libepoxy-devel libfdt-devel
 librdmacm-devel lzo-devel make mesa-libEGL-devel 
m

Re: [Qemu-devel] [PATCH v2 1/2] hw/arm/aspeed: directly map the serial device to the system address space

2018-02-11 Thread Andrew Jeffery
On Fri, 2018-02-09 at 05:57 -0300, Philippe Mathieu-Daudé wrote:
> (qemu) info mtree
>  address-space: cpu-memory-0
>- (prio 0, i/o): system
>  -07ff (prio 0, rom): aspeed.boot_rom
>  1e60-1e7f (prio -1, i/o): aspeed_soc.io
> -  1e784000-1e78401f (prio 0, i/o): serial
>  1e62-1e6200ff (prio 0, i/o):
> aspeed.smc.ast2500-fmc
>  1e63-1e6300ff (prio 0, i/o):
> aspeed.smc.ast2500-spi1
>  [...]
>  1e72-1e728fff (prio 0, ram): aspeed.sram
>  1e782000-1e782fff (prio 0, i/o): aspeed.timer
> +1e784000-1e78401f (prio 0, i/o): serial
>  1e785000-1e78501f (prio 0, i/o): aspeed.wdt
>  1e785020-1e78503f (prio 0, i/o): aspeed.wdt
> 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Andrew Jeffery 

> ---
>  hw/arm/aspeed_soc.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index c83b7e207b..2a5d041b3b 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -257,7 +257,8 @@ static void aspeed_soc_realize(DeviceState *dev,
> Error **errp)
>  /* UART - attach an 8250 to the IO space as our UART5 */
>  if (serial_hds[0]) {
>  qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic),
> uart_irqs[4]);
> -serial_mm_init(&s->iomem, ASPEED_SOC_UART_5_BASE, 2,
> +serial_mm_init(get_system_memory(),
> +   ASPEED_SOC_IOMEM_BASE +
> ASPEED_SOC_UART_5_BASE, 2,
> uart5, 38400, serial_hds[0],
> DEVICE_LITTLE_ENDIAN);
>  }
>  

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v2 2/2] hw/arm/aspeed: simplify using the 'unimplemented device' for aspeed_soc.io

2018-02-11 Thread Andrew Jeffery
On Fri, 2018-02-09 at 05:57 -0300, Philippe Mathieu-Daudé wrote:
> (qemu) info mtree
>  address-space: cpu-memory-0
>- (prio 0, i/o): system
>  -07ff (prio 0, rom): aspeed.boot_rom
> -1e60-1e7f (prio -1, i/o): aspeed_soc.io
> +1e60-1e7f (prio -1000, i/o): aspeed_soc.io
>  1e62-1e6200ff (prio 0, i/o): aspeed.smc.ast2500-fmc
>  1e63-1e6300ff (prio 0, i/o): aspeed.smc.ast2500-spi1
>  1e631000-1e6310ff (prio 0, i/o): aspeed.smc.ast2500-spi2
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> Reviewed-by: Cédric Le Goater 

Reviewed-by: Andrew Jeffery 

> ---
>  include/hw/arm/aspeed_soc.h |  1 -
>  hw/arm/aspeed_soc.c | 32 +++-
>  2 files changed, 3 insertions(+), 30 deletions(-)
> 
> diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
> index f26914a2b9..11ec0179db 100644
> --- a/include/hw/arm/aspeed_soc.h
> +++ b/include/hw/arm/aspeed_soc.h
> @@ -31,7 +31,6 @@ typedef struct AspeedSoCState {
>  
>  /*< public >*/
>  ARMCPU cpu;
> -MemoryRegion iomem;
>  MemoryRegion sram;
>  AspeedVICState vic;
>  AspeedTimerCtrlState timerctrl;
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index 2a5d041b3b..30d25f8b06 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -15,6 +15,7 @@
>  #include "qemu-common.h"
>  #include "cpu.h"
>  #include "exec/address-spaces.h"
> +#include "hw/misc/unimp.h"
>  #include "hw/arm/aspeed_soc.h"
>  #include "hw/char/serial.h"
>  #include "qemu/log.h"
> @@ -99,31 +100,6 @@ static const AspeedSoCInfo aspeed_socs[] = {
>  },
>  };
>  
> -/*
> - * IO handlers: simply catch any reads/writes to IO addresses that aren't
> - * handled by a device mapping.
> - */
> -
> -static uint64_t aspeed_soc_io_read(void *p, hwaddr offset, unsigned size)
> -{
> -qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
> -  __func__, offset, size);
> -return 0;
> -}
> -
> -static void aspeed_soc_io_write(void *opaque, hwaddr offset, uint64_t value,
> -unsigned size)
> -{
> -qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " 
> [%u]\n",
> -  __func__, offset, value, size);
> -}
> -
> -static const MemoryRegionOps aspeed_soc_io_ops = {
> -.read = aspeed_soc_io_read,
> -.write = aspeed_soc_io_write,
> -.endianness = DEVICE_LITTLE_ENDIAN,
> -};
> -
>  static void aspeed_soc_init(Object *obj)
>  {
>  AspeedSoCState *s = ASPEED_SOC(obj);
> @@ -199,10 +175,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
> **errp)
>  Error *err = NULL, *local_err = NULL;
>  
>  /* IO space */
> -memory_region_init_io(&s->iomem, NULL, &aspeed_soc_io_ops, NULL,
> -"aspeed_soc.io", ASPEED_SOC_IOMEM_SIZE);
> -memory_region_add_subregion_overlap(get_system_memory(),
> -ASPEED_SOC_IOMEM_BASE, &s->iomem, 
> -1);
> +create_unimplemented_device("aspeed_soc.io",
> +ASPEED_SOC_IOMEM_BASE, 
> ASPEED_SOC_IOMEM_SIZE);
>  
>  /* CPU */
>  object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH v6 00/28] Migration: postcopy failure recovery

2018-02-11 Thread no-reply
Hi,

This series failed build test on ppc host. Please find the details below.

Type: series
Message-id: 20180208103132.28452-1-pet...@redhat.com
Subject: [Qemu-devel] [PATCH v6 00/28] Migration: postcopy failure recovery

=== TEST SCRIPT BEGIN ===
#!/bin/bash
# Testing script will be invoked under the git checkout with
# HEAD pointing to a commit that has the patches applied on top of "base"
# branch
set -e
echo "=== ENV ==="
env
echo "=== PACKAGES ==="
rpm -qa
echo "=== TEST BEGIN ==="
INSTALL=$PWD/install
BUILD=$PWD/build
mkdir -p $BUILD $INSTALL
SRC=$PWD
cd $BUILD
$SRC/configure --prefix=$INSTALL
make -j100
# XXX: we need reliable clean up
# make check -j100 V=1
make install
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Submodule 'capstone' (git://git.qemu.org/capstone.git) registered for path 
'capstone'
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Submodule 'roms/QemuMacDrivers' (git://git.qemu.org/QemuMacDrivers.git) 
registered for path 'roms/QemuMacDrivers'
Submodule 'roms/SLOF' (git://git.qemu-project.org/SLOF.git) registered for path 
'roms/SLOF'
Submodule 'roms/ipxe' (git://git.qemu-project.org/ipxe.git) registered for path 
'roms/ipxe'
Submodule 'roms/openbios' (git://git.qemu-project.org/openbios.git) registered 
for path 'roms/openbios'
Submodule 'roms/openhackware' (git://git.qemu-project.org/openhackware.git) 
registered for path 'roms/openhackware'
Submodule 'roms/qemu-palcode' (git://github.com/rth7680/qemu-palcode.git) 
registered for path 'roms/qemu-palcode'
Submodule 'roms/seabios' (git://git.qemu-project.org/seabios.git/) registered 
for path 'roms/seabios'
Submodule 'roms/seabios-hppa' (git://github.com/hdeller/seabios-hppa.git) 
registered for path 'roms/seabios-hppa'
Submodule 'roms/sgabios' (git://git.qemu-project.org/sgabios.git) registered 
for path 'roms/sgabios'
Submodule 'roms/skiboot' (git://git.qemu.org/skiboot.git) registered for path 
'roms/skiboot'
Submodule 'roms/u-boot' (git://git.qemu-project.org/u-boot.git) registered for 
path 'roms/u-boot'
Submodule 'roms/vgabios' (git://git.qemu-project.org/vgabios.git/) registered 
for path 'roms/vgabios'
Submodule 'ui/keycodemapdb' (git://git.qemu.org/keycodemapdb.git) registered 
for path 'ui/keycodemapdb'
Cloning into 'capstone'...
Submodule path 'capstone': checked out 
'22ead3e0bfdb87516656453336160e0a37b066bf'
Cloning into 'dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
Cloning into 'roms/QemuMacDrivers'...
Submodule path 'roms/QemuMacDrivers': checked out 
'd4e7d7ac663fcb55f1b93575445fcbca372f17a7'
Cloning into 'roms/SLOF'...
Submodule path 'roms/SLOF': checked out 
'fa981320a1e0968d6fc1b8de319723ff8212b337'
Cloning into 'roms/ipxe'...
Submodule path 'roms/ipxe': checked out 
'0600d3ae94f93efd10fc6b3c7420a9557a3a1670'
Cloning into 'roms/openbios'...
Submodule path 'roms/openbios': checked out 
'b5c93acd14b7b3886c2c81d84cd18e666984a4c8'
Cloning into 'roms/openhackware'...
Submodule path 'roms/openhackware': checked out 
'c559da7c8eec5e45ef1f67978827af6f0b9546f5'
Cloning into 'roms/qemu-palcode'...
Submodule path 'roms/qemu-palcode': checked out 
'f3c7e44c70254975df2a00af39701eafbac4d471'
Cloning into 'roms/seabios'...
Submodule path 'roms/seabios': checked out 
'63451fca13c75870e1703eb3e20584d91179aebc'
Cloning into 'roms/seabios-hppa'...
Submodule path 'roms/seabios-hppa': checked out 
'649e6202b8d65d46c69f542b1380f840fbe8ab13'
Cloning into 'roms/sgabios'...
Submodule path 'roms/sgabios': checked out 
'cbaee52287e5f32373181cff50a00b6c4ac9015a'
Cloning into 'roms/skiboot'...
Submodule path 'roms/skiboot': checked out 
'e0ee24c27a172bcf482f6f2bc905e6211c134bcc'
Cloning into 'roms/u-boot'...
Submodule path 'roms/u-boot': checked out 
'd85ca029f257b53a96da6c2fb421e78a003a9943'
Cloning into 'roms/vgabios'...
Submodule path 'roms/vgabios': checked out 
'19ea12c230ded95928ecaef0db47a82231c2e485'
Cloning into 'ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out 
'6b3d716e2b6472eb7189d3220552280ef3d832ce'
Switched to a new branch 'test'
9fef7a4 migration/hmp: add migrate_pause command
e5bc884 migration/qmp: add command migrate-pause
ae62f07 hmp/migration: add migrate_recover command
b6a9d72 qmp/migration: new command migrate-recover
9903aa7 io: let watcher of the channel run in same ctx
ef37cc9 migration: init dst in migration_object_init too
b9a7a63 migration: final handshake for the resume
40d1c0e migration: setup ramstate for resume
4faada9 migration: synchronize dirty bitmap for resume
1c86b22 migration: introduce SaveVMHandlers.resume_prepare
99d5d3e migration: new message MIG_RP_MSG_RESUME_ACK
011a3e5 migration: new cmd MIG_CMD_POSTCOPY_RESUME
e8ea13a migration: new message MIG_RP_MSG_RECV_BITMAP
0527218 migration: new cmd MIG_CMD_RECV_BITMAP
060b476 migration: wakeup dst ram-load-thread for recover
5c512af migration: new state "postcopy-recover"
3c817a2 migration: rebuild channel on source
498feb3 migration: pa

Re: [Qemu-devel] [PATCH v2 02/19] spapr: introduce a skeleton for the XIVE interrupt controller

2018-02-11 Thread Alexey Kardashevskiy
On 12/02/18 09:55, Benjamin Herrenschmidt wrote:
> On Sun, 2018-02-11 at 19:08 +1100, David Gibson wrote:
>> On Thu, Jan 18, 2018 at 08:27:52AM +1100, Benjamin Herrenschmidt wrote:
>>> On Wed, 2018-01-17 at 15:39 +0100, Cédric Le Goater wrote:
 Migration is a problem. We will need both backend QEMU objects to be 
 available anyhow if we want to migrate. So we are back to the current 
 solution creating both QEMU objects but we can try to defer some of the 
 KVM inits and create the KVM device on demand at CAS time.
>>>
>>> Do we have a way to migrate a piece of info from the machine *first*
>>> that indicate what type of XICS/XIVE to instanciate ?
>>
>> Nope.  qemu migration doesn't work like that.  Yes, it should, and
>> everyone knows it, but changing it is a really long term project.
> 
> Well, we have a problem then. It looks like Qemu broken migration is
> fundamentally incompatible with PAPR and CAS design...
> 
> I know we don't migrate the configuration, that's not exactly what I
> had in mind tho... Can we have some piece of *data* from the machine be
> migrated first, and use it on the target to reconfigure the interrupt
> controller before the stream arrives ?


These days this is done via libvirt - it reads properties it needs via QMP,
then sends an XML with everything (the interrupt controller type may be one
of such properties), and starts the destination QEMU with the explicit
interrupt controller (like -machine pseries,intrc=xive).

Hacking QEMU to do all of this is still in a distant TODO...


> Otherwise, we have indeed no much choice but the horrible wart of
> creating both interrupt controllers with only one "active".
> 
>>>
 The next problem is the ICP object that currently needs the KVM device 
 fd to connect the vcpus ... So, we will need to change that also. 
 That is probably the biggest problem today. We need a way to disconnect 
 the vpcu from the KVM device and see how we can defer the connection.
 I need to make sure this is possible, I can check that without XIVE



-- 
Alexey



Re: [Qemu-devel] [PATCH RFC/D] docs: document our stable process

2018-02-11 Thread Michael Roth
Quoting Cornelia Huck (2018-02-09 07:11:12)
> Some pointers on how to get a patch into stable.

Thanks for putting this together. I made some minor suggestions below
that might help clarify some points.

> 
> Signed-off-by: Cornelia Huck 
> ---
> 
> This probably needs more love, but I'd like to have at least _some_
> kind of documentation.
> 
> Maybe this should also go into the wiki?

We can probably add a reference to it in:

  https://wiki.qemu.org/Contribute/SubmitAPatch

I should probably add a MAINTAINERS entry for stable that references
it too.

> 
> ---
>  docs/stable-process.rst | 57 
> +
>  1 file changed, 57 insertions(+)
>  create mode 100644 docs/stable-process.rst
> 
> diff --git a/docs/stable-process.rst b/docs/stable-process.rst
> new file mode 100644
> index 00..2502823dc5
> --- /dev/null
> +++ b/docs/stable-process.rst
> @@ -0,0 +1,57 @@
> +QEMU and the stable process
> +===
> +
> +QEMU stable releases
> +
> +
> +QEMU stable releases are based upon the last released QEMU version
> +and marked by an additional version number, e.g. 2.10.1. Occasionally,
> +a four-number version is released, if a single urgent fix needs to go
> +on top.
> +
> +Usually, a stable release is only done for the last released version.

Maybe:

"Usually, stable releases are only provided for the last major QEMU
release. For example, when QEMU 2.11.0 is released, 2.11.x or 2.11.x.y
stable releases are only produced until QEMU 2.12.0 is released, at
which the stable process moves to producing 2.12.x/2.12.x.y releases."


> +
> +What should go into a stable release?
> +-
> +
> +Generally, the following patches are considered stable material:
> +- Patches that fix severe issues, like fixes for CVEs
> +- Patches that fix regressions
> +
> +If you think the patch would be important for users of the current release
> +(or for a distribution picking fixes), it is usually a good candidate
> +for stable.
> +
> +
> +How to get a patch into QEMU stable
> +---
> +
> +There are various ways to get a patch into stable:
> +
> +* Preferred: Make sure that the stable maintainers are on copy when you send
> +  the patch by adding
> +
> +  .. code::
> +
> + Cc: qemu-sta...@nongnu.org
> +
> +   to the patch description. This will make git add the stable maintainers
> +   on copy when your patch is sent out.

"By default, this will send the patch to qemu-sta...@nongnu.org if you use
git send-email, which is where patches that are stable candidates are
tracked by the maintainers."

"You can also reply to a patch and Cc: qemu-sta...@nongnu.org directly with
your mail client if you think a previously submitted patch should be
considered for a stable release."

> +
> +* If a maintainer judges the patch appropriate for stable later on (or you
> +  notify them), they will add the same line to your patch, meaning that

"to the patch" (in case the Cc'er isn't the author)

> +  the stable maintainers will be on copy on the maintainer's pull request.
> +
> +* If you judge an already merged patch suitable for stable, send a mail

(preferably as a reply to the most recent patch submission)

> +  to ``qemu-sta...@nongnu.org`` with ``qemu-devel@nongnu.org`` and 
> appropriate

"along with"

> +  other people (like the patch author or the relevant maintainer) on copy.
> +
> +Stable release process
> +--
> +
> +When the stable maintainers prepare a new stable release, they will prepare
> +a git branch with a release candidate and send the patches out to
> +``qemu-devel@nongnu.org`` for review. If any of your patches are included,

"qemu-devel@nongnu.org and qemu-sta...@nongnu.org"

> +please verify that they look fine. You may also nominate other patches that
> +you think are suitable for inclusion. After review is complete (may involve
> +more release candidates), a new stable release is made available.
> -- 
> 2.13.6
> 




[Qemu-devel] [PULL 00/12] ppc-for-2.12 queue 20180212

2018-02-11 Thread David Gibson
The following changes since commit c7b02d7d032d6022060e4b393827c963c93ce63f:

  Merge remote-tracking branch 
'remotes/stsquad/tags/pull-travis-speedup-090218-1' into staging (2018-02-09 
16:12:34 +)

are available in the Git repository at:

  git://github.com/dgibson/qemu.git tags/ppc-for-2.12-20180212

for you to fetch changes up to 51f233ec92cdab7030cb7407dd7f009911c805b0:

  misc: introduce new mos6522 VIA device and enable it for ppc builds 
(2018-02-11 10:18:52 +1100)


ppc patch queue 2018-02-12

Here's the accumulatead ppc and pseries related patches for the last
while.  Highlights are:
* A number of Macintosh / CUDA cleanups from Mark Cave-Ayland
* An important bug fix (missing "break;") for
  H_GET_CPU_CHARACTERISTICS
* Yet another fix for SMT mode handling
* Assorted other cleanups and fixes


Daniel Henrique Barboza (1):
  hw/ppc: rename functions in comments

Greg Kurz (1):
  spapr: add missing break in h_get_cpu_characteristics()

Laurent Vivier (1):
  spapr: set vsmt to MAX(8, smp_threads)

Mark Cave-Ayland (9):
  cuda: do not use old_mmio accesses
  cuda: don't allow writes to port output pins
  cuda: introduce CUDAState parameter to get_counter()
  cuda: rename frequency property to tb_frequency
  cuda: minor cosmetic tidy-ups to get_next_irq_time()
  cuda: don't call cuda_update() when writing to ACR register
  cuda: set timer 1 frequency property to CUDA_TIMER_FREQ
  cuda: factor out timebase-derived counter value and load time
  misc: introduce new mos6522 VIA device and enable it for ppc builds

 default-configs/ppc-softmmu.mak |   1 +
 hw/misc/Makefile.objs   |   3 +
 hw/misc/macio/cuda.c| 111 -
 hw/misc/macio/macio.c   |   2 +-
 hw/misc/mos6522.c   | 505 
 hw/misc/trace-events|   7 +
 hw/ppc/mac.h|   2 +-
 hw/ppc/spapr.c  |   5 +-
 hw/ppc/spapr_hcall.c|   3 +-
 include/hw/misc/mos6522.h   | 152 
 10 files changed, 722 insertions(+), 69 deletions(-)
 create mode 100644 hw/misc/mos6522.c
 create mode 100644 include/hw/misc/mos6522.h



[Qemu-devel] [PULL 04/12] cuda: don't allow writes to port output pins

2018-02-11 Thread David Gibson
From: Mark Cave-Ayland 

Use the direction registers as a mask to ensure that only input pins are
updated upon write.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: David Gibson 
---
 hw/misc/macio/cuda.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 6631017ca2..eaa8924f49 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -359,11 +359,11 @@ static void cuda_write(void *opaque, hwaddr addr, 
uint64_t val, unsigned size)
 
 switch(addr) {
 case CUDA_REG_B:
-s->b = val;
+s->b = (s->b & ~s->dirb) | (val & s->dirb);
 cuda_update(s);
 break;
 case CUDA_REG_A:
-s->a = val;
+s->a = (s->a & ~s->dira) | (val & s->dira);
 break;
 case CUDA_REG_DIRB:
 s->dirb = val;
-- 
2.14.3




[Qemu-devel] [PULL 05/12] spapr: set vsmt to MAX(8, smp_threads)

2018-02-11 Thread David Gibson
From: Laurent Vivier 

We ignore silently the value of smp_threads when we set
the default VSMT value, and if smp_threads is greater than VSMT
kernel is going into trouble later.

Fixes: 8904e5a750
("spapr: Adjust default VSMT value for better migration compatibility")

Signed-off-by: Laurent Vivier 
Reviewed-by: Greg Kurz 
Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 96515036e6..9f29434819 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2310,7 +2310,7 @@ static void spapr_set_vsmt_mode(sPAPRMachineState *spapr, 
Error **errp)
  * the value that we'd get with KVM on POWER8, the
  * overwhelmingly common case in production systems.
  */
-spapr->vsmt = 8;
+spapr->vsmt = MAX(8, smp_threads);
 }
 
 /* KVM: If necessary, set the SMT mode: */
-- 
2.14.3




[Qemu-devel] [PULL 02/12] hw/ppc: rename functions in comments

2018-02-11 Thread David Gibson
From: Daniel Henrique Barboza 

Commit bcb5ce08cf ("spapr: Rename machine init functions for clarity")
renamed ppc_spapr_reset to spapr_machine_reset and ppc_spapr_init
to spapr_machine_init. Let's also rename the references in
comments.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c   | 3 ++-
 hw/ppc/spapr_hcall.c | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 659be6b746..96515036e6 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -464,7 +464,8 @@ static int spapr_populate_memory(sPAPRMachineState *spapr, 
void *fdt)
 }
 }
 if (!mem_start) {
-/* ppc_spapr_init() checks for rma_size <= node0_size already */
+/* spapr_machine_init() checks for rma_size <= node0_size
+ * already */
 spapr_populate_memory_node(fdt, i, 0, spapr->rma_size);
 mem_start += spapr->rma_size;
 node_size -= spapr->rma_size;
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 596f58378a..76422cfac1 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1635,7 +1635,7 @@ static target_ulong 
h_client_architecture_support(PowerPCCPU *cpu,
 spapr->cas_legacy_guest_workaround = !spapr_ovec_test(ov1_guest,
   OV1_PPC_3_00);
 if (!spapr->cas_reboot) {
-/* If ppc_spapr_reset() did not set up a HPT but one is necessary
+/* If spapr_machine_reset() did not set up a HPT but one is necessary
  * (because the guest isn't going to use radix) then set it up here. */
 if ((spapr->patb_entry & PATBE1_GR) && !guest_radix) {
 /* legacy hash or new hash: */
-- 
2.14.3




[Qemu-devel] [PULL 01/12] spapr: add missing break in h_get_cpu_characteristics()

2018-02-11 Thread David Gibson
From: Greg Kurz 

Detected by Coverity (CID 1385702). This fixes the recently added hypercall
to let guests properly apply Spectre and Meltdown workarounds.

Fixes: c59704b25473 "target/ppc/spapr: Add H-Call H_GET_CPU_CHARACTERISTICS"
Reported-by: Paolo Bonzini 
Signed-off-by: Greg Kurz 
Reviewed-by: Suraj Jitindar Singh 
Signed-off-by: David Gibson 
---
 hw/ppc/spapr_hcall.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 4d0e6eb0cf..596f58378a 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1697,6 +1697,7 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU 
*cpu,
 switch (safe_indirect_branch) {
 case SPAPR_CAP_FIXED:
 characteristics |= H_CPU_CHAR_BCCTRL_SERIALISED;
+break;
 default: /* broken */
 assert(safe_indirect_branch == SPAPR_CAP_BROKEN);
 break;
-- 
2.14.3




[Qemu-devel] [PULL 07/12] cuda: rename frequency property to tb_frequency

2018-02-11 Thread David Gibson
From: Mark Cave-Ayland 

This allows us to more easily differentiate between the timebase frequency used
to calibrate the MacOS timers and the actual frequency of the hardware clock as
indicated by CUDA_TIMER_FREQ.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
[dwg: Revert some extraneous changes which break compile]
Signed-off-by: David Gibson 
---
 hw/misc/macio/cuda.c  | 6 +++---
 hw/misc/macio/macio.c | 2 +-
 hw/ppc/mac.h  | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index fa10b6d0c1..d4a52fbddb 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -179,7 +179,7 @@ static void set_counter(CUDAState *s, CUDATimer *ti, 
unsigned int val)
 {
 CUDA_DPRINTF("T%d.counter=%d\n", 1 + ti->index, val);
 ti->load_time = get_tb(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
-   s->frequency);
+   s->tb_frequency);
 ti->counter_value = val;
 cuda_timer_update(s, ti, ti->load_time);
 }
@@ -879,7 +879,7 @@ static void cuda_realizefn(DeviceState *dev, Error **errp)
 struct tm tm;
 
 s->timers[0].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_timer1, s);
-s->timers[0].frequency = s->frequency;
+s->timers[0].frequency = s->tb_frequency;
 s->timers[1].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_timer2, s);
 s->timers[1].frequency = (SCALE_US * 6000) / 4700;
 
@@ -910,7 +910,7 @@ static void cuda_initfn(Object *obj)
 }
 
 static Property cuda_properties[] = {
-DEFINE_PROP_UINT64("frequency", CUDAState, frequency, 0),
+DEFINE_PROP_UINT64("timebase-frequency", CUDAState, tb_frequency, 0),
 DEFINE_PROP_END_OF_LIST()
 };
 
diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index 44f91d1e7f..a639b09e00 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -451,7 +451,7 @@ void macio_init(PCIDevice *d,
 macio_state->escc_mem = escc_mem;
 /* Note: this code is strongly inspirated from the corresponding code
in PearPC */
-qdev_prop_set_uint64(DEVICE(&macio_state->cuda), "frequency",
+qdev_prop_set_uint64(DEVICE(&macio_state->cuda), "timebase-frequency",
  macio_state->frequency);
 
 qdev_init_nofail(DEVICE(d));
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index b501af1653..fa78115c95 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -99,7 +99,7 @@ typedef struct CUDAState {
 CUDATimer timers[2];
 
 uint32_t tick_offset;
-uint64_t frequency;
+uint64_t tb_frequency;
 
 uint8_t last_b;
 uint8_t last_acr;
-- 
2.14.3




[Qemu-devel] [PULL 09/12] cuda: don't call cuda_update() when writing to ACR register

2018-02-11 Thread David Gibson
From: Mark Cave-Ayland 

The wire protocol for reading data to/from the VIA is triggered by changing
inputs on port B rather than changing the timer configuration via the ACR.

Signed-off-by: Mark Cave-Ayland 
Signed-off-by: David Gibson 
---
 hw/misc/macio/cuda.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 729905236c..355a2f2262 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -407,7 +407,6 @@ static void cuda_write(void *opaque, hwaddr addr, uint64_t 
val, unsigned size)
 case CUDA_REG_ACR:
 s->acr = val;
 cuda_timer_update(s, &s->timers[0], 
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
-cuda_update(s);
 break;
 case CUDA_REG_PCR:
 s->pcr = val;
-- 
2.14.3




[Qemu-devel] [PULL 08/12] cuda: minor cosmetic tidy-ups to get_next_irq_time()

2018-02-11 Thread David Gibson
From: Mark Cave-Ayland 

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: David Gibson 
---
 hw/misc/macio/cuda.c | 23 ---
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index d4a52fbddb..729905236c 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -184,36 +184,37 @@ static void set_counter(CUDAState *s, CUDATimer *ti, 
unsigned int val)
 cuda_timer_update(s, ti, ti->load_time);
 }
 
-static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time)
+static int64_t get_next_irq_time(CUDATimer *ti, int64_t current_time)
 {
 int64_t d, next_time;
 unsigned int counter;
 
 /* current counter value */
-d = muldiv64(current_time - s->load_time,
+d = muldiv64(current_time - ti->load_time,
  CUDA_TIMER_FREQ, NANOSECONDS_PER_SECOND);
 /* the timer goes down from latch to -1 (period of latch + 2) */
-if (d <= (s->counter_value + 1)) {
-counter = (s->counter_value - d) & 0x;
+if (d <= (ti->counter_value + 1)) {
+counter = (ti->counter_value - d) & 0x;
 } else {
-counter = (d - (s->counter_value + 1)) % (s->latch + 2);
-counter = (s->latch - counter) & 0x;
+counter = (d - (ti->counter_value + 1)) % (ti->latch + 2);
+counter = (ti->latch - counter) & 0x;
 }
 
 /* Note: we consider the irq is raised on 0 */
 if (counter == 0x) {
-next_time = d + s->latch + 1;
+next_time = d + ti->latch + 1;
 } else if (counter == 0) {
-next_time = d + s->latch + 2;
+next_time = d + ti->latch + 2;
 } else {
 next_time = d + counter;
 }
 CUDA_DPRINTF("latch=%d counter=%" PRId64 " delta_next=%" PRId64 "\n",
- s->latch, d, next_time - d);
+ ti->latch, d, next_time - d);
 next_time = muldiv64(next_time, NANOSECONDS_PER_SECOND, CUDA_TIMER_FREQ) +
-s->load_time;
-if (next_time <= current_time)
+ ti->load_time;
+if (next_time <= current_time) {
 next_time = current_time + 1;
+}
 return next_time;
 }
 
-- 
2.14.3




[Qemu-devel] [PULL 11/12] cuda: factor out timebase-derived counter value and load time

2018-02-11 Thread David Gibson
From: Mark Cave-Ayland 

Commit b981289c49 "PPC: Cuda: Use cuda timer to expose tbfreq to guest" altered
the timer calculations from those based upon the hardware CUDA clock frequency
to those based upon the CPU timebase frequency.

In fact we can isolate the differences to 2 simple changes: one to the counter
read value and another to the counter load time. Move these changes into
separate functions so the implementation can be swapped later.

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: David Gibson 
---
 hw/misc/macio/cuda.c | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index e00df4a21a..a185252144 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -145,21 +145,29 @@ static void cuda_update_irq(CUDAState *s)
 }
 }
 
-static uint64_t get_tb(uint64_t time, uint64_t freq)
+static uint64_t get_counter_value(CUDAState *s, CUDATimer *ti)
 {
-return muldiv64(time, freq, NANOSECONDS_PER_SECOND);
+/* Reverse of the tb calculation algorithm that Mac OS X uses on bootup */
+uint64_t tb_diff = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+s->tb_frequency, NANOSECONDS_PER_SECOND) -
+   ti->load_time;
+
+return (tb_diff * 0xBF401675E5DULL) / (s->tb_frequency << 24);
+}
+
+static uint64_t get_counter_load_time(CUDAState *s, CUDATimer *ti)
+{
+uint64_t load_time = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+  s->tb_frequency, NANOSECONDS_PER_SECOND);
+return load_time;
 }
 
 static unsigned int get_counter(CUDAState *s, CUDATimer *ti)
 {
 int64_t d;
 unsigned int counter;
-uint64_t tb_diff;
-uint64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
-/* Reverse of the tb calculation algorithm that Mac OS X uses on bootup. */
-tb_diff = get_tb(current_time, s->tb_frequency) - ti->load_time;
-d = (tb_diff * 0xBF401675E5DULL) / (s->tb_frequency << 24);
+d = get_counter_value(s, ti);
 
 if (ti->index == 0) {
 /* the timer goes down from latch to -1 (period of latch + 2) */
@@ -178,8 +186,7 @@ static unsigned int get_counter(CUDAState *s, CUDATimer *ti)
 static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val)
 {
 CUDA_DPRINTF("T%d.counter=%d\n", 1 + ti->index, val);
-ti->load_time = get_tb(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
-   s->tb_frequency);
+ti->load_time = get_counter_load_time(s, ti);
 ti->counter_value = val;
 cuda_timer_update(s, ti, ti->load_time);
 }
-- 
2.14.3




[Qemu-devel] [PULL 03/12] cuda: do not use old_mmio accesses

2018-02-11 Thread David Gibson
From: Mark Cave-Ayland 

Signed-off-by: Mark Cave-Ayland 
Signed-off-by: David Gibson 
---
 hw/misc/macio/cuda.c | 40 
 1 file changed, 8 insertions(+), 32 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 008d8bd4d5..6631017ca2 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -275,7 +275,7 @@ static void cuda_delay_set_sr_int(CUDAState *s)
 timer_mod(s->sr_delay_timer, expire);
 }
 
-static uint32_t cuda_readb(void *opaque, hwaddr addr)
+static uint64_t cuda_read(void *opaque, hwaddr addr, unsigned size)
 {
 CUDAState *s = opaque;
 uint32_t val;
@@ -350,7 +350,7 @@ static uint32_t cuda_readb(void *opaque, hwaddr addr)
 return val;
 }
 
-static void cuda_writeb(void *opaque, hwaddr addr, uint32_t val)
+static void cuda_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
 {
 CUDAState *s = opaque;
 
@@ -780,38 +780,14 @@ static void cuda_receive_packet_from_host(CUDAState *s,
 }
 }
 
-static void cuda_writew (void *opaque, hwaddr addr, uint32_t value)
-{
-}
-
-static void cuda_writel (void *opaque, hwaddr addr, uint32_t value)
-{
-}
-
-static uint32_t cuda_readw (void *opaque, hwaddr addr)
-{
-return 0;
-}
-
-static uint32_t cuda_readl (void *opaque, hwaddr addr)
-{
-return 0;
-}
-
 static const MemoryRegionOps cuda_ops = {
-.old_mmio = {
-.write = {
-cuda_writeb,
-cuda_writew,
-cuda_writel,
-},
-.read = {
-cuda_readb,
-cuda_readw,
-cuda_readl,
-},
+.read = cuda_read,
+.write = cuda_write,
+.endianness = DEVICE_BIG_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 1,
 },
-.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static bool cuda_timer_exist(void *opaque, int version_id)
-- 
2.14.3




[Qemu-devel] [PULL 10/12] cuda: set timer 1 frequency property to CUDA_TIMER_FREQ

2018-02-11 Thread David Gibson
From: Mark Cave-Ayland 

Now that we have successfully decoupled the timebase frequency and the hardware
timer frequency, set the timer 1 frequency property to CUDA_TIMER_FREQ and alter
get_next_irq_time() to use it rather than the hard-coded constant.

In addition to this we must now switch the tb_diff calculation over to use the
timebase frequency now that the hardware clock frequency and the timebase
frequency are different.

Signed-off-by: Mark Cave-Ayland 
[dwg: Correct a conflict due to a bug in an earlier patch]
Signed-off-by: David Gibson 
---
 hw/misc/macio/cuda.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 355a2f2262..e00df4a21a 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -158,8 +158,8 @@ static unsigned int get_counter(CUDAState *s, CUDATimer *ti)
 uint64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
 /* Reverse of the tb calculation algorithm that Mac OS X uses on bootup. */
-tb_diff = get_tb(current_time, ti->frequency) - ti->load_time;
-d = (tb_diff * 0xBF401675E5DULL) / (ti->frequency << 24);
+tb_diff = get_tb(current_time, s->tb_frequency) - ti->load_time;
+d = (tb_diff * 0xBF401675E5DULL) / (s->tb_frequency << 24);
 
 if (ti->index == 0) {
 /* the timer goes down from latch to -1 (period of latch + 2) */
@@ -191,7 +191,7 @@ static int64_t get_next_irq_time(CUDATimer *ti, int64_t 
current_time)
 
 /* current counter value */
 d = muldiv64(current_time - ti->load_time,
- CUDA_TIMER_FREQ, NANOSECONDS_PER_SECOND);
+ ti->frequency, NANOSECONDS_PER_SECOND);
 /* the timer goes down from latch to -1 (period of latch + 2) */
 if (d <= (ti->counter_value + 1)) {
 counter = (ti->counter_value - d) & 0x;
@@ -210,7 +210,7 @@ static int64_t get_next_irq_time(CUDATimer *ti, int64_t 
current_time)
 }
 CUDA_DPRINTF("latch=%d counter=%" PRId64 " delta_next=%" PRId64 "\n",
  ti->latch, d, next_time - d);
-next_time = muldiv64(next_time, NANOSECONDS_PER_SECOND, CUDA_TIMER_FREQ) +
+next_time = muldiv64(next_time, NANOSECONDS_PER_SECOND, ti->frequency) +
  ti->load_time;
 if (next_time <= current_time) {
 next_time = current_time + 1;
@@ -879,7 +879,7 @@ static void cuda_realizefn(DeviceState *dev, Error **errp)
 struct tm tm;
 
 s->timers[0].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_timer1, s);
-s->timers[0].frequency = s->tb_frequency;
+s->timers[0].frequency = CUDA_TIMER_FREQ;
 s->timers[1].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_timer2, s);
 s->timers[1].frequency = (SCALE_US * 6000) / 4700;
 
-- 
2.14.3




[Qemu-devel] [PULL 06/12] cuda: introduce CUDAState parameter to get_counter()

2018-02-11 Thread David Gibson
From: Mark Cave-Ayland 

This will be required shortly and also happens to match nicely with the
corresponding signature for set_counter().

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: David Gibson 
---
 hw/misc/macio/cuda.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index eaa8924f49..fa10b6d0c1 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -150,7 +150,7 @@ static uint64_t get_tb(uint64_t time, uint64_t freq)
 return muldiv64(time, freq, NANOSECONDS_PER_SECOND);
 }
 
-static unsigned int get_counter(CUDATimer *ti)
+static unsigned int get_counter(CUDAState *s, CUDATimer *ti)
 {
 int64_t d;
 unsigned int counter;
@@ -295,12 +295,12 @@ static uint64_t cuda_read(void *opaque, hwaddr addr, 
unsigned size)
 val = s->dira;
 break;
 case CUDA_REG_T1CL:
-val = get_counter(&s->timers[0]) & 0xff;
+val = get_counter(s, &s->timers[0]) & 0xff;
 s->ifr &= ~T1_INT;
 cuda_update_irq(s);
 break;
 case CUDA_REG_T1CH:
-val = get_counter(&s->timers[0]) >> 8;
+val = get_counter(s, &s->timers[0]) >> 8;
 cuda_update_irq(s);
 break;
 case CUDA_REG_T1LL:
@@ -311,12 +311,12 @@ static uint64_t cuda_read(void *opaque, hwaddr addr, 
unsigned size)
 val = (s->timers[0].latch >> 8) & 0xff;
 break;
 case CUDA_REG_T2CL:
-val = get_counter(&s->timers[1]) & 0xff;
+val = get_counter(s, &s->timers[1]) & 0xff;
 s->ifr &= ~T2_INT;
 cuda_update_irq(s);
 break;
 case CUDA_REG_T2CH:
-val = get_counter(&s->timers[1]) >> 8;
+val = get_counter(s, &s->timers[1]) >> 8;
 break;
 case CUDA_REG_SR:
 val = s->sr;
-- 
2.14.3




[Qemu-devel] [PULL 12/12] misc: introduce new mos6522 VIA device and enable it for ppc builds

2018-02-11 Thread David Gibson
From: Mark Cave-Ayland 

The MOS6522 VIA forms the bridge part of several Mac devices, including the
Mac via-cuda and via-pmu devices. Introduce a standard mos6522 device that
can be shared amongst multiple implementations.

This is effectively taking the 6522 parts out of cuda.c and turning them
into a separate device whilst also applying some style tidy-ups and including
a conversion to trace-events.

Signed-off-by: Mark Cave-Ayland 
Signed-off-by: David Gibson 
---
 default-configs/ppc-softmmu.mak |   1 +
 hw/misc/Makefile.objs   |   3 +
 hw/misc/mos6522.c   | 505 
 hw/misc/trace-events|   7 +
 include/hw/misc/mos6522.h   | 152 
 5 files changed, 668 insertions(+)
 create mode 100644 hw/misc/mos6522.c
 create mode 100644 include/hw/misc/mos6522.h

diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index 65680d85bc..76e29cfa14 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -30,6 +30,7 @@ CONFIG_MAC=y
 CONFIG_ESCC=y
 CONFIG_MACIO=y
 CONFIG_SUNGEM=y
+CONFIG_MOS6522=y
 CONFIG_CUDA=y
 CONFIG_ADB=y
 CONFIG_MAC_NVRAM=y
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index fce426eb75..f33b37a8e5 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -17,6 +17,9 @@ common-obj-$(CONFIG_INTEGRATOR_DEBUG) += 
arm_integrator_debug.o
 common-obj-$(CONFIG_A9SCU) += a9scu.o
 common-obj-$(CONFIG_ARM11SCU) += arm11scu.o
 
+# Mac devices
+common-obj-$(CONFIG_MOS6522) += mos6522.o
+
 # PKUnity SoC devices
 common-obj-$(CONFIG_PUV3) += puv3_pm.o
 
diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
new file mode 100644
index 00..8ad9fc831e
--- /dev/null
+++ b/hw/misc/mos6522.c
@@ -0,0 +1,505 @@
+/*
+ * QEMU MOS6522 VIA emulation
+ *
+ * Copyright (c) 2004-2007 Fabrice Bellard
+ * Copyright (c) 2007 Jocelyn Mayer
+ * Copyright (c) 2018 Mark Cave-Ayland
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/input/adb.h"
+#include "hw/misc/mos6522.h"
+#include "qemu/timer.h"
+#include "sysemu/sysemu.h"
+#include "qemu/cutils.h"
+#include "qemu/log.h"
+#include "trace.h"
+
+/* XXX: implement all timer modes */
+
+static void mos6522_timer_update(MOS6522State *s, MOS6522Timer *ti,
+ int64_t current_time);
+
+static void mos6522_update_irq(MOS6522State *s)
+{
+if (s->ifr & s->ier & (SR_INT | T1_INT | T2_INT)) {
+qemu_irq_raise(s->irq);
+} else {
+qemu_irq_lower(s->irq);
+}
+}
+
+static uint64_t get_counter_value(MOS6522State *s, MOS6522Timer *ti)
+{
+MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(s);
+
+if (ti->index == 0) {
+return mdc->get_timer1_counter_value(s, ti);
+} else {
+return mdc->get_timer2_counter_value(s, ti);
+}
+}
+
+static uint64_t get_load_time(MOS6522State *s, MOS6522Timer *ti)
+{
+MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(s);
+
+if (ti->index == 0) {
+return mdc->get_timer1_load_time(s, ti);
+} else {
+return mdc->get_timer2_load_time(s, ti);
+}
+}
+
+static unsigned int get_counter(MOS6522State *s, MOS6522Timer *ti)
+{
+int64_t d;
+unsigned int counter;
+
+d = get_counter_value(s, ti);
+
+if (ti->index == 0) {
+/* the timer goes down from latch to -1 (period of latch + 2) */
+if (d <= (ti->counter_value + 1)) {
+counter = (ti->counter_value - d) & 0x;
+} else {
+counter = (d - (ti->counter_value + 1)) % (ti->latch + 2);
+counter = (ti->latch - counter) & 0x;
+}
+} else {
+counter = (ti->counter_value - d) & 0x;
+}
+return counter;
+}
+
+static void set_counter(MOS6522State *s, MOS6522Timer *ti, unsigned int val)
+{
+trace_mos6522_set_counter(1 + ti->index, val);
+ti->load_time = get_load_t

Re: [Qemu-devel] [PATCH qemu v7 2/4] vfio/pci: Relax DMA map errors for MMIO regions

2018-02-11 Thread David Gibson
On Fri, Feb 09, 2018 at 06:55:01PM +1100, Alexey Kardashevskiy wrote:
> At the moment if vfio_memory_listener is registered in the system memory
> address space, it maps/unmaps every RAM memory region for DMA.
> It expects system page size aligned memory sections so vfio_dma_map
> would not fail and so far this has been the case. A mapping failure
> would be fatal. A side effect of such behavior is that some MMIO pages
> would not be mapped silently.
> 
> However we are going to change MSIX BAR handling so we will end having
> non-aligned sections in vfio_memory_listener (more details is in
> the next patch) and vfio_dma_map will exit QEMU.
> 
> In order to avoid fatal failures on what previously was not a failure and
> was just silently ignored, this checks the section alignment to
> the smallest supported IOMMU page size and prints an error if not aligned;
> it also prints an error if vfio_dma_map failed despite the page size check.
> Both errors are not fatal; only MMIO RAM regions are checked
> (aka "RAM device" regions).
> 
> If the amount of errors printed is overwhelming, the MSIX relocation
> could be used to avoid excessive error output.
> 
> This is unlikely to cause any behavioral change.
> 
> Signed-off-by: Alexey Kardashevskiy 

There are some relatively superficial problems noted below.

But more fundamentally, this feels like it's extending an existing
hack past the point of usefulness.

The explicit check for is_ram_device() here has always bothered me -
it's not like a real bus bridge magically knows whether a target
address maps to RAM or not.

What I think is really going on is that even for systems without an
IOMMU, it's not really true to say that the PCI address space maps
directly onto address_space_memory.  Instead, there's a large, but
much less than 2^64 sized, "upstream window" at address 0 on the PCI
bus, which is identity mapped to the system bus.  Details will vary
with the system, but in practice we expect nothing but RAM to be in
that window.  Addresses not within that window won't be mapped to the
system bus but will just be broadcast on the PCI bus and might be
picked up as a p2p transaction.  Actually on classic PC, I suspect
there may be two windows, below and above the "ISA IO hole".

With PCIe it gets more complicated, of course.  I still suspect
there's some sort of upstream window to the host, but whether things
outside the window get reflected back down the PCIe heirarchy will
depend on those p2p relevant configuration parameters.

Maybe it's time we had a detailed look at what really happens in
physical bridges, rather than faking it with the is_ram_device()
check?

Anyway, that said, the patch below might still be a reasonable interim
hack, once the smaller problems are fixed.

> ---
>  hw/vfio/common.c | 55 +--
>  1 file changed, 49 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> index f895e3c..736f271 100644
> --- a/hw/vfio/common.c
> +++ b/hw/vfio/common.c
> @@ -544,18 +544,40 @@ static void vfio_listener_region_add(MemoryListener 
> *listener,
>  
>  llsize = int128_sub(llend, int128_make64(iova));
>  
> +if (memory_region_is_ram_device(section->mr)) {
> +hwaddr pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1;
> +
> +if ((iova & pgmask) || (llsize & pgmask)) {
> +error_report("Region 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx
> + " is not aligned to 0x%"HWADDR_PRIx
> + " and cannot be mapped for DMA",
> + section->offset_within_region,
> + int128_getlo(section->size),
> + pgmask + 1);
> +return;
> +}
> +}
> +
>  ret = vfio_dma_map(container, iova, int128_get64(llsize),
> vaddr, section->readonly);
>  if (ret) {
>  error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", "
>   "0x%"HWADDR_PRIx", %p) = %d (%m)",
>   container, iova, int128_get64(llsize), vaddr, ret);
> +if (memory_region_is_ram_device(section->mr)) {
> +/* Allow unexpected mappings not to be fatal for RAM devices */
> +return;
> +}
>  goto fail;
>  }
>  
>  return;
>  
>  fail:
> +if (memory_region_is_ram_device(section->mr)) {
> +error_report("failed to vfio_dma_map. pci p2p may not work");

Isn't this logic exactly backwards?  p2p will be affected when a *non
RAM* device (itself probably a PCI MMIO window) can't be mapped in.

> +return;
> +}
>  /*
>   * On the initfn path, store the first error in the container so we
>   * can gracefully fail.  Runtime, there's not much we can do other
> @@ -577,6 +599,7 @@ static void vfio_listener_region_del(MemoryListener 
> *listener,
>  hwaddr iova, end;
>  Int128 llend, llsize;
>  int ret;
> +bool try_unmap = true;
>

Re: [Qemu-devel] [RFC PATCH v6 00/20] replay additions

2018-02-11 Thread Pavel Dovgalyuk
I tested ARM only with –kernel and –initrd.

Can you provide the full command line and the disk image?

 

Pavel Dovgalyuk

 

From: Ciro Santilli [mailto:ciro.santi...@gmail.com] 
Sent: Saturday, February 10, 2018 3:09 AM
To: Pavel Dovgalyuk
Cc: Pavel Dovgalyuk; qemu-devel@nongnu.org; kw...@redhat.com; Peter Maydell; 
war2jor...@live.com; Igor R; quint...@redhat.com; jasow...@redhat.com; 
m...@redhat.com; Aleksandr Bezzubikov; maria.klimushenk...@ispras.ru; 
kra...@redhat.com; Thomas Dullien; pbonz...@redhat.com; Alex Bennée
Subject: Re: [RFC PATCH v6 00/20] replay additions

 

Also, what command do you use to test on ARM? I'm a bit stuck to get the drive 
part right, e.g.:

 

-drive 
file=./buildroot/output.arm~/images/rootfs.ext2,if=scsi,id=img-direct,format=raw
 \

-drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay \

-device scsi-hd,drive=img-blkreplay \

 

fails with: qemu-system-arm: -device scsi-hd,drive=img-blkreplay: Conflicts 
with use by img-direct as 'root', which does not allow 'write' on #block968

 



[Qemu-devel] [Bug 1748756] Re: [Feature request] Support of TI AM1808 for Lego EV3

2018-02-11 Thread Thomas Huth
** Changed in: qemu
   Importance: Undecided => Wishlist

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1748756

Title:
  [Feature request] Support of TI AM1808 for Lego EV3

Status in QEMU:
  New

Bug description:
  It would be great if emulating TI AM1808 would be possible. It will be
  a big step towards Lego Mindstorms EV3 emulation.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1748756/+subscriptions



Re: [Qemu-devel] [RFC PATCH v6 00/20] replay additions

2018-02-11 Thread Pavel Dovgalyuk
> From: Ciro Santilli [mailto:ciro.santi...@gmail.com] 
> Awesome! This worked with my test procedure described at: 
> https://stackoverflow.com/questions/46970215/how-to-use-qemus-deterministic-record-and-replay-feature-for-a-linux-kernel-boo
> While we are a it, can we clarify the following points the docs?
> 1) Usage of the record/replay: mentions that `-net none` is required, unless 
> a network patch is applied.
> But the network section that follows explains how to record network requests, 
> and I've tested it, so I think the `-net none` / patch requirement is just 
> outdated and should be removed.
> 2) There are mentions of "reverse execution" and "reverse debugging" on the 
> "Record/replay" section.
> Are those supported? If yes, explain there how to use them. Otherwise, remove 
> the mentions.
> I would love to see that feature!

Not yet, but they are the next to apply after this series.
I'll update the docs.

> 3) Is the snapshot feature mentioned in the "Snapshotting" section something 
> specific to record and replay?
> If yes, can we detail further how to use it besides passing 
> `rrsnapshot=snapshot_name`? How to create and restore the snapshots?
> If not, why does the `rrsnapshot=snapshot_name` option exist?
> 4) Maybe give the required disk and network commands under "Usage of the 
> record/replay:"
> -drive file=disk.qcow,if=none,id=img-direct
> -drive driver=blkreplay,if=none,image=img-direct,id=img-blkreplay
> -device ide-hd,drive=img-blkreplay
> -netdev user,id=net1 -device rtl8139,netdev=net1
> -object filter-replay,id=replay,netdev=net1
> People likely always want those, but it currently requires reading through 
> the whole doc file to put everything together.

Thanks for reviewing, I'll add the documentation update to the series.


Pavel Dovgalyuk




Re: [Qemu-devel] [PATCH qemu v7 2/4] vfio/pci: Relax DMA map errors for MMIO regions

2018-02-11 Thread Alexey Kardashevskiy
On 12/02/18 16:19, David Gibson wrote:
> On Fri, Feb 09, 2018 at 06:55:01PM +1100, Alexey Kardashevskiy wrote:
>> At the moment if vfio_memory_listener is registered in the system memory
>> address space, it maps/unmaps every RAM memory region for DMA.
>> It expects system page size aligned memory sections so vfio_dma_map
>> would not fail and so far this has been the case. A mapping failure
>> would be fatal. A side effect of such behavior is that some MMIO pages
>> would not be mapped silently.
>>
>> However we are going to change MSIX BAR handling so we will end having
>> non-aligned sections in vfio_memory_listener (more details is in
>> the next patch) and vfio_dma_map will exit QEMU.
>>
>> In order to avoid fatal failures on what previously was not a failure and
>> was just silently ignored, this checks the section alignment to
>> the smallest supported IOMMU page size and prints an error if not aligned;
>> it also prints an error if vfio_dma_map failed despite the page size check.
>> Both errors are not fatal; only MMIO RAM regions are checked
>> (aka "RAM device" regions).
>>
>> If the amount of errors printed is overwhelming, the MSIX relocation
>> could be used to avoid excessive error output.
>>
>> This is unlikely to cause any behavioral change.
>>
>> Signed-off-by: Alexey Kardashevskiy 
> 
> There are some relatively superficial problems noted below.
> 
> But more fundamentally, this feels like it's extending an existing
> hack past the point of usefulness.
> 
> The explicit check for is_ram_device() here has always bothered me -
> it's not like a real bus bridge magically knows whether a target
> address maps to RAM or not.
> 
> What I think is really going on is that even for systems without an
> IOMMU, it's not really true to say that the PCI address space maps
> directly onto address_space_memory.  Instead, there's a large, but
> much less than 2^64 sized, "upstream window" at address 0 on the PCI
> bus, which is identity mapped to the system bus.  Details will vary
> with the system, but in practice we expect nothing but RAM to be in
> that window.  Addresses not within that window won't be mapped to the
> system bus but will just be broadcast on the PCI bus and might be
> picked up as a p2p transaction.

Currently this p2p works only via the IOMMU, direct p2p is not possible as
the guest needs to know physical MMIO addresses to make p2p work and it
does not.


> Actually on classic PC, I suspect
> there may be two windows, below and above the "ISA IO hole".
> 
> With PCIe it gets more complicated, of course.  I still suspect
> there's some sort of upstream window to the host, but whether things
> outside the window get reflected back down the PCIe heirarchy will
> depend on those p2p relevant configuration parameters.
> 
> Maybe it's time we had a detailed look at what really happens in
> physical bridges, rather than faking it with the is_ram_device()
> check?
> 
> Anyway, that said, the patch below might still be a reasonable interim
> hack, once the smaller problems are fixed.
> 
>> ---
>>  hw/vfio/common.c | 55 
>> +--
>>  1 file changed, 49 insertions(+), 6 deletions(-)
>>
>> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
>> index f895e3c..736f271 100644
>> --- a/hw/vfio/common.c
>> +++ b/hw/vfio/common.c
>> @@ -544,18 +544,40 @@ static void vfio_listener_region_add(MemoryListener 
>> *listener,
>>  
>>  llsize = int128_sub(llend, int128_make64(iova));
>>  
>> +if (memory_region_is_ram_device(section->mr)) {
>> +hwaddr pgmask = (1ULL << ctz64(hostwin->iova_pgsizes)) - 1;
>> +
>> +if ((iova & pgmask) || (llsize & pgmask)) {
>> +error_report("Region 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx
>> + " is not aligned to 0x%"HWADDR_PRIx
>> + " and cannot be mapped for DMA",
>> + section->offset_within_region,
>> + int128_getlo(section->size),
>> + pgmask + 1);
>> +return;
>> +}
>> +}
>> +
>>  ret = vfio_dma_map(container, iova, int128_get64(llsize),
>> vaddr, section->readonly);
>>  if (ret) {
>>  error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", "
>>   "0x%"HWADDR_PRIx", %p) = %d (%m)",
>>   container, iova, int128_get64(llsize), vaddr, ret);
>> +if (memory_region_is_ram_device(section->mr)) {
>> +/* Allow unexpected mappings not to be fatal for RAM devices */
>> +return;
>> +}
>>  goto fail;
>>  }
>>  
>>  return;
>>  
>>  fail:
>> +if (memory_region_is_ram_device(section->mr)) {
>> +error_report("failed to vfio_dma_map. pci p2p may not work");
> 
> Isn't this logic exactly backwards?  p2p will be affected when a *non
> RAM* device (itself probably a PCI MMIO window) can't be mapped in.


"RAM device MR" == "mapped MMIO MR

Re: [Qemu-devel] [PATCH v2 02/19] spapr: introduce a skeleton for the XIVE interrupt controller

2018-02-11 Thread Cédric Le Goater
On 02/11/2018 11:55 PM, Benjamin Herrenschmidt wrote:
> On Sun, 2018-02-11 at 19:08 +1100, David Gibson wrote:
>> On Thu, Jan 18, 2018 at 08:27:52AM +1100, Benjamin Herrenschmidt wrote:
>>> On Wed, 2018-01-17 at 15:39 +0100, Cédric Le Goater wrote:
 Migration is a problem. We will need both backend QEMU objects to be 
 available anyhow if we want to migrate. So we are back to the current 
 solution creating both QEMU objects but we can try to defer some of the 
 KVM inits and create the KVM device on demand at CAS time.
>>>
>>> Do we have a way to migrate a piece of info from the machine *first*
>>> that indicate what type of XICS/XIVE to instanciate ?
>>
>> Nope.  qemu migration doesn't work like that.  Yes, it should, and
>> everyone knows it, but changing it is a really long term project.
> 
> Well, we have a problem then. It looks like Qemu broken migration is
> fundamentally incompatible with PAPR and CAS design...
> 
> I know we don't migrate the configuration, that's not exactly what I
> had in mind tho... Can we have some piece of *data* from the machine be
> migrated first, and use it on the target to reconfigure the interrupt
> controller before the stream arrives ?
> 
> Otherwise, we have indeed no much choice but the horrible wart of
> creating both interrupt controllers with only one "active".

Well, both QEMU model objects would be created, yes, but one only KVM 
associated device. It's a bit ugly from a QEMU point of view because  
the KVM initialization is deferred at reset but, in the pratice, it 
results in a couple of calls to : 

  - disconnect the VCPU from the KVM interrupt device
  - destroy the previous KVM interrupt device (new ioctl)
  - create the new KVM interrupt device
  - reconnect the VCPU to the KVM interrupt device

I don't think it will be a major problem.

What I am unease with currently, is how to share the same XIVE objects 
when under KVM and when not. The only difference is in the nature of
the MMIO region and the qemu_irq handler. Work in progress.

And we have four interrupt modes to support : XICS-KVM, XICS, XIVE-KVM, 
XIVE.

Thanks,

C. 
 

 The next problem is the ICP object that currently needs the KVM device 
 fd to connect the vcpus ... So, we will need to change that also. 
 That is probably the biggest problem today. We need a way to disconnect 
 the vpcu from the KVM device and see how we can defer the connection.
 I need to make sure this is possible, I can check that without XIVE
>>>
>>> Ben.
>>>
>>
>>




[Qemu-devel] [PATCH RFC 12/14] qapi-introspect: modify to_qlit() to append ', ' on level > 0

2018-02-11 Thread Markus Armbruster
From: Marc-André Lureau 

The following patch is going to break list entries with #if/#endif, so
they should have the trailing ',' as suffix.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Markus Armbruster 
---
 scripts/qapi/introspect.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index e5c491d936..c02df95e72 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -29,7 +29,7 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
 for elt in obj]
 elts.append(indent(level + 1) + "{}")
 ret = 'QLIT_QLIST(((QLitObject[]) {\n'
-ret += ',\n'.join(elts) + '\n'
+ret += '\n'.join(elts) + '\n'
 ret += indent(level) + '}))'
 elif isinstance(obj, dict):
 elts = []
@@ -42,6 +42,8 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
 ret += indent(level) + '}))'
 else:
 assert False# not implemented
+if level > 0:
+ret += ','
 return ret
 
 
-- 
2.13.6




[Qemu-devel] [PATCH RFC 10/14] qapi: mcgen() shouldn't indent # lines

2018-02-11 Thread Markus Armbruster
From: Marc-André Lureau 

Skip preprocessor lines when adding indentation, since that would
likely result in invalid code.

Signed-off-by: Marc-André Lureau 
---
 scripts/qapi/common.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 692a7ec7c2..1b254d5b32 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1940,8 +1940,8 @@ def cgen(code, **kwds):
 if indent_level:
 indent = genindent(indent_level)
 # re.subn() lacks flags support before Python 2.7, use re.compile()
-raw = re.subn(re.compile(r'^.', re.MULTILINE),
-  indent + r'\g<0>', raw)
+raw = re.subn(re.compile(r'^(?!(#|$))', re.MULTILINE),
+  indent, raw)
 raw = raw[0]
 return re.sub(re.escape(eatspace) + r' *', '', raw)
 
-- 
2.13.6




[Qemu-devel] [PATCH RFC 14/14] qapi: Add #if conditions to commands, events, types, visitors

2018-02-11 Thread Markus Armbruster
Example change to generated code:

diff -rup test-qapi-events.h.old test-qapi-events.h
--- test-qapi-events.h.old  2018-02-12 07:02:45.672737544 +0100
+++ test-qapi-events.h  2018-02-12 07:03:01.128517669 +0100
@@ -30,8 +30,10 @@ void qapi_event_send_event_e(UserDefZero
 void qapi_event_send_event_f(UserDefAlternate *arg, Error **errp);

 void qapi_event_send___org_qemu_x_event(__org_qemu_x_Enum 
__org_qemu_x_member1, const char *__org_qemu_x_member2, bool has_q_wchar_t, 
int64_t q_wchar_t, Error **errp);
+#if defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)

 void qapi_event_send_testifevent(TestIfStruct *foo, Error **errp);
+#endif /* defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT) */

 typedef enum test_QAPIEvent {
 TEST_QAPI_EVENT_EVENT_A = 0,

TODO nice blank lines before #if and after #endif
FIXME unclean access of protected members in commands.py

Signed-off-by: Markus Armbruster 
---
 scripts/qapi/commands.py |  7 ++-
 scripts/qapi/common.py   | 37 +
 tests/test-qmp-cmds.c|  4 ++--
 3 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
index 21a7e0dbe6..439a8714e2 100644
--- a/scripts/qapi/commands.py
+++ b/scripts/qapi/commands.py
@@ -276,8 +276,13 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
 self._visited_ret_types[self._genc].add(ret_type)
 self._genc.add(gen_marshal_output(ret_type))
 self._genh.add(gen_marshal_decl(name))
-self._genc.add(gen_marshal(name, arg_type, boxed, ret_type))
+self._genc.add(gen_marshal(name, arg_type, boxed, ret_type,))
+# FIXME unclean access of protected members
+if self._genc._open_ifcond:
+self._regy += gen_if(self._genc._open_ifcond)
 self._regy += gen_register_command(name, success_response)
+if self._genc._open_ifcond:
+self._regy += gen_endif(self._genc._open_ifcond)
 
 
 def gen_commands(schema, output_dir, prefix):
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 1a78dfaf3f..164d3e2daa 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -2122,6 +2122,9 @@ class QAPIGenC(QAPIGen):
 self._blurb = blurb.strip('\n')
 self._copyright = '\n * '.join(re.findall(r'^Copyright .*', pydoc,
   re.MULTILINE))
+self._open_ifcond = None
+self._preamble_needs_ifcond = False
+self._body_needs_ifcond = False
 
 def _top(self, fname):
 return mcgen('''
@@ -2139,6 +2142,36 @@ class QAPIGenC(QAPIGen):
 ''',
  blurb=self._blurb, copyright=self._copyright)
 
+def ifcond(self, ifcond, begin):
+if begin:
+assert not self._open_ifcond
+self._open_ifcond = ifcond
+self._preamble_needs_ifcond = True
+self._body_needs_ifcond = True
+else:
+assert self._open_ifcond == ifcond
+if not self._preamble_needs_ifcond:
+QAPIGen.preamble_add(self, gen_endif(ifcond))
+# TODO emit blank line
+if not self._body_needs_ifcond:
+QAPIGen.add(self, gen_endif(ifcond))
+# TODO emit blank line
+self._open_ifcond = None
+
+def preamble_add(self, text):
+if self._open_ifcond and self._preamble_needs_ifcond:
+# TODO emit blank line
+QAPIGen.preamble_add(self, gen_if(self._open_ifcond))
+self._preamble_needs_ifcond = False
+QAPIGen.preamble_add(self, text)
+
+def add(self, text):
+if self._open_ifcond and self._body_needs_ifcond:
+# TODO emit blank line
+QAPIGen.add(self, gen_if(self._open_ifcond))
+self._body_needs_ifcond = False
+QAPIGen.add(self, text)
+
 
 class QAPIGenH(QAPIGenC):
 
@@ -2224,3 +2257,7 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor):
 #include "%(basename)s.h"
 ''',
   basename=basename))
+
+def visit_ifcond(self, ifcond, begin):
+self._genc.ifcond(ifcond, begin)
+self._genh.ifcond(ifcond, begin)
diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c
index c0a3c46439..b709a1fa3a 100644
--- a/tests/test-qmp-cmds.c
+++ b/tests/test-qmp-cmds.c
@@ -12,11 +12,11 @@
 
 static QmpCommandList qmp_commands;
 
-/* #if defined(TEST_IF_CMD) */
+#if defined(TEST_IF_CMD)
 void qmp_TestIfCmd(TestIfStruct *foo, Error **errp)
 {
 }
-/* #endif */
+#endif
 
 void qmp_user_def_cmd(Error **errp)
 {
-- 
2.13.6




[Qemu-devel] [PATCH RFC 11/14] qapi: add #if/#endif helpers

2018-02-11 Thread Markus Armbruster
From: Marc-André Lureau 

Add helpers to wrap generated code with #if/#endif lines.

Signed-off-by: Marc-André Lureau 
---
 scripts/qapi/common.py | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 1b254d5b32..1a78dfaf3f 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1973,6 +1973,24 @@ def guardend(name):
  name=guardname(name))
 
 
+def gen_if(ifcond):
+ret = ''
+for ifc in ifcond:
+ret += mcgen('''
+#if %(cond)s
+''', cond=ifc)
+return ret
+
+
+def gen_endif(ifcond):
+ret = ''
+for ifc in reversed(ifcond):
+ret += mcgen('''
+#endif /* %(cond)s */
+''', cond=ifc)
+return ret
+
+
 def gen_enum_lookup(name, values, prefix=None):
 ret = mcgen('''
 
-- 
2.13.6




[Qemu-devel] [PATCH RFC 03/14] qapi/introspect: Simplify WIP

2018-02-11 Thread Markus Armbruster
---
 scripts/qapi/introspect.py | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index f66c397fb0..6c86673a09 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -51,36 +51,32 @@ class 
QAPISchemaGenIntrospectVisitor(QAPISchemaMonolithicCVisitor):
 self._jsons = []
 self._used_types = []
 self._name_map = {}
+var = c_name(self._prefix, protect=False) + 'qmp_schema_json'
 self._genc.add(mcgen('''
 #include "qemu/osdep.h"
 #include "%(prefix)sqapi-introspect.h"
 
+const char %(var)s[] = ''',
+ var=var, prefix=prefix))
+self._genh.add(mcgen('''
+extern const char %(var)s[];
 ''',
- prefix=prefix))
+ var=var))
 
 def visit_begin(self, schema):
 self._schema = schema
 
 def visit_end(self):
 # visit the types that are actually used
-jsons = self._jsons
-self._jsons = []
 for typ in self._used_types:
 typ.visit(self)
 # generate C
 # TODO can generate awfully long lines
-jsons.extend(self._jsons)
-name = c_name(self._prefix, protect=False) + 'qmp_schema_json'
-self._genh.add(mcgen('''
-extern const char %(c_name)s[];
-''',
- c_name=c_name(name)))
-lines = to_json(jsons).split('\n')
+lines = to_json(self._jsons).split('\n')
 c_string = '\n'.join([to_c_string(line) for line in lines])
 self._genc.add(mcgen('''
-const char %(c_name)s[] = %(c_string)s;
+%(c_string)s;
 ''',
- c_name=c_name(name),
  c_string=c_string))
 self._schema = None
 self._jsons = []
-- 
2.13.6




[Qemu-devel] [PATCH RFC 05/14] qapi2texi: minor python code simplification

2018-02-11 Thread Markus Armbruster
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Markus Armbruster 
---
 scripts/qapi/doc.py | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py
index 0ea68bf813..79d11bbe9b 100644
--- a/scripts/qapi/doc.py
+++ b/scripts/qapi/doc.py
@@ -134,10 +134,9 @@ def texi_enum_value(value):
 def texi_member(member, suffix=''):
 """Format a table of members item for an object type member"""
 typ = member.type.doc_type()
-return '@item @code{%s%s%s}%s%s\n' % (
-member.name,
-': ' if typ else '',
-typ if typ else '',
+membertype = ': ' + typ if typ else ''
+return '@item @code{%s%s}%s%s\n' % (
+member.name, membertype,
 ' (optional)' if member.optional else '',
 suffix)
 
-- 
2.13.6




[Qemu-devel] [PATCH RFC 08/14] qapi: leave the ifcond attribute undefined until check()

2018-02-11 Thread Markus Armbruster
From: Marc-André Lureau 

We commonly initialize attributes to None in .init(), then set their
real value in .check().  Accessing the attribute before .check()
yields None.  If we're lucky, the code that accesses the attribute
prematurely chokes on None.

It won't for .ifcond, because None is a legitimate value.

Leave the ifcond attribute undefined until check().

Suggested-by: Markus Armbruster 
Signed-off-by: Marc-André Lureau 
---
 scripts/qapi/common.py | 21 +
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 789c77f11f..78aeec785e 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1028,13 +1028,19 @@ class QAPISchemaEntity(object):
 # such place).
 self.info = info
 self.doc = doc
-self.ifcond = listify_cond(ifcond)
+self._ifcond = ifcond  # self.ifcond is set after check()
 
 def c_name(self):
 return c_name(self.name)
 
 def check(self, schema):
-pass
+if isinstance(self._ifcond, QAPISchemaType):
+# inherit the condition from a type
+typ = self._ifcond
+typ.check(schema)
+self.ifcond = typ.ifcond
+else:
+self.ifcond = listify_cond(self._ifcond)
 
 def is_implicit(self):
 return not self.info
@@ -1171,6 +1177,7 @@ class QAPISchemaEnumType(QAPISchemaType):
 self.prefix = prefix
 
 def check(self, schema):
+QAPISchemaType.check(self, schema)
 seen = {}
 for v in self.values:
 v.check_clash(self.info, seen)
@@ -1203,8 +1210,10 @@ class QAPISchemaArrayType(QAPISchemaType):
 self.element_type = None
 
 def check(self, schema):
+QAPISchemaType.check(self, schema)
 self.element_type = schema.lookup_type(self._element_type_name)
 assert self.element_type
+self.element_type.check(schema)
 self.ifcond = self.element_type.ifcond
 
 def is_implicit(self):
@@ -1247,6 +1256,7 @@ class QAPISchemaObjectType(QAPISchemaType):
 self.members = None
 
 def check(self, schema):
+QAPISchemaType.check(self, schema)
 if self.members is False:   # check for cycles
 raise QAPISemError(self.info,
"Object %s contains itself" % self.name)
@@ -1429,6 +1439,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
 self.variants = variants
 
 def check(self, schema):
+QAPISchemaType.check(self, schema)
 self.variants.tag_member.check(schema)
 # Not calling self.variants.check_clash(), because there's nothing
 # to clash with
@@ -1471,6 +1482,7 @@ class QAPISchemaCommand(QAPISchemaEntity):
 self.boxed = boxed
 
 def check(self, schema):
+QAPISchemaEntity.check(self, schema)
 if self._arg_type_name:
 self.arg_type = schema.lookup_type(self._arg_type_name)
 assert (isinstance(self.arg_type, QAPISchemaObjectType) or
@@ -1504,6 +1516,7 @@ class QAPISchemaEvent(QAPISchemaEntity):
 self.boxed = boxed
 
 def check(self, schema):
+QAPISchemaEntity.check(self, schema)
 if self._arg_type_name:
 self.arg_type = schema.lookup_type(self._arg_type_name)
 assert (isinstance(self.arg_type, QAPISchemaObjectType) or
@@ -1632,7 +1645,7 @@ class QAPISchema(object):
 # But it's not tight: the disjunction need not imply it.  We
 # may end up compiling useless wrapper types.
 # TODO kill simple unions or implement the disjunction
-assert ifcond == typ.ifcond
+assert ifcond == typ._ifcond
 else:
 self._def_entity(QAPISchemaObjectType(name, info, doc, ifcond,
   None, members, None))
@@ -1678,7 +1691,7 @@ class QAPISchema(object):
 assert len(typ) == 1
 typ = self._make_array_type(typ[0], info)
 typ = self._make_implicit_object_type(
-typ, info, None, self.lookup_type(typ).ifcond,
+typ, info, None, self.lookup_type(typ),
 'wrapper', [self._make_member('data', typ, info)])
 return QAPISchemaObjectTypeVariant(case, typ)
 
-- 
2.13.6




[Qemu-devel] [PATCH RFC 01/14] qlit: use QType instead of int

2018-02-11 Thread Markus Armbruster
From: Marc-André Lureau 

Suggested-by: Markus Armbruster 
Signed-off-by: Marc-André Lureau 
---
 include/qapi/qmp/qlit.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index 56f9d97bd9..f1ed082df8 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -20,7 +20,7 @@ typedef struct QLitDictEntry QLitDictEntry;
 typedef struct QLitObject QLitObject;
 
 struct QLitObject {
-int type;
+QType type;
 union {
 bool qbool;
 int64_t qnum;
-- 
2.13.6




[Qemu-devel] [PATCH RFC 02/14] qlit: add qobject_from_qlit()

2018-02-11 Thread Markus Armbruster
From: Marc-André Lureau 

Instantiate a QObject* from a literal QLitObject.

LitObject only supports int64_t for now.  uint64_t and double aren't
implemented.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Markus Armbruster 
---
 include/qapi/qmp/qlit.h |  2 ++
 qobject/qlit.c  | 37 +
 tests/check-qlit.c  | 28 
 3 files changed, 67 insertions(+)

diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index f1ed082df8..c0676d5daf 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qapi/qmp/qlit.h
@@ -50,4 +50,6 @@ struct QLitDictEntry {
 
 bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs);
 
+QObject *qobject_from_qlit(const QLitObject *qlit);
+
 #endif /* QLIT_H */
diff --git a/qobject/qlit.c b/qobject/qlit.c
index 948e0b860c..a921abf84a 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -18,6 +18,7 @@
 #include "qapi/qmp/qlit.h"
 #include "qapi/qmp/qbool.h"
 #include "qapi/qmp/qlist.h"
+#include "qapi/qmp/qnull.h"
 #include "qapi/qmp/qnum.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qstring.h"
@@ -86,3 +87,39 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject 
*rhs)
 
 return false;
 }
+
+QObject *qobject_from_qlit(const QLitObject *qlit)
+{
+switch (qlit->type) {
+case QTYPE_QNULL:
+return QOBJECT(qnull());
+case QTYPE_QNUM:
+return QOBJECT(qnum_from_int(qlit->value.qnum));
+case QTYPE_QSTRING:
+return QOBJECT(qstring_from_str(qlit->value.qstr));
+case QTYPE_QDICT: {
+QDict *qdict = qdict_new();
+QLitDictEntry *e;
+
+for (e = qlit->value.qdict; e->key; e++) {
+qdict_put_obj(qdict, e->key, qobject_from_qlit(&e->value));
+}
+return QOBJECT(qdict);
+}
+case QTYPE_QLIST: {
+QList *qlist = qlist_new();
+QLitObject *e;
+
+for (e = qlit->value.qlist; e->type != QTYPE_NONE; e++) {
+qlist_append_obj(qlist, qobject_from_qlit(e));
+}
+return QOBJECT(qlist);
+}
+case QTYPE_QBOOL:
+return QOBJECT(qbool_from_bool(qlit->value.qbool));
+default:
+assert(0);
+}
+
+return NULL;
+}
diff --git a/tests/check-qlit.c b/tests/check-qlit.c
index 5d0f65b9c7..836f4a3090 100644
--- a/tests/check-qlit.c
+++ b/tests/check-qlit.c
@@ -9,9 +9,11 @@
 
 #include "qemu/osdep.h"
 
+#include "qapi/qmp/qbool.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qlist.h"
 #include "qapi/qmp/qlit.h"
+#include "qapi/qmp/qnum.h"
 #include "qapi/qmp/qstring.h"
 
 static QLitObject qlit = QLIT_QDICT(((QLitDictEntry[]) {
@@ -63,11 +65,37 @@ static void qlit_equal_qobject_test(void)
 qobject_decref(qobj);
 }
 
+static void qobject_from_qlit_test(void)
+{
+QObject *obj, *qobj = qobject_from_qlit(&qlit);
+QDict *qdict;
+QList *bee;
+
+qdict = qobject_to_qdict(qobj);
+g_assert_cmpint(qdict_get_int(qdict, "foo"), ==, 42);
+g_assert_cmpstr(qdict_get_str(qdict, "bar"), ==, "hello world");
+g_assert(qobject_type(qdict_get(qdict, "baz")) == QTYPE_QNULL);
+
+bee = qdict_get_qlist(qdict, "bee");
+obj = qlist_pop(bee);
+g_assert_cmpint(qnum_get_int(qobject_to_qnum(obj)), ==, 43);
+qobject_decref(obj);
+obj = qlist_pop(bee);
+g_assert_cmpint(qnum_get_int(qobject_to_qnum(obj)), ==, 44);
+qobject_decref(obj);
+obj = qlist_pop(bee);
+g_assert(qbool_get_bool(qobject_to_qbool(obj)));
+qobject_decref(obj);
+
+qobject_decref(qobj);
+}
+
 int main(int argc, char **argv)
 {
 g_test_init(&argc, &argv, NULL);
 
 g_test_add_func("/qlit/equal_qobject", qlit_equal_qobject_test);
+g_test_add_func("/qlit/qobject_from_qlit", qobject_from_qlit_test);
 
 return g_test_run();
 }
-- 
2.13.6




Re: [Qemu-devel] [PATCHv2] linux-user: Fix sched_getaffinity mask size

2018-02-11 Thread Laurent Vivier
Le 11/02/2018 à 18:47, Samuel Thibault a écrit :
> We properly computed the capped mask size to be put to the application
> buffer, but didn't actually used it. Also, we need to return the capped mask
> size instead of 0 on success.
> 
> Signed-off-by: Samuel Thibault 
> 
> ---
> Difference from v1:
> - simplify fix
> ---
>  linux-user/syscall.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 82b35a6bdf..bcda3362fc 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -10493,7 +10493,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
> arg1,
>  ret = arg2;
>  }
>  
> -ret = host_to_target_cpu_mask(mask, mask_size, arg3, arg2);
> +if (host_to_target_cpu_mask(mask, mask_size, arg3, ret)) {
> +goto efault;
> +}
>  }
>  }
>  break;
> 

Reviewed-by: Laurent Vivier 




[Qemu-devel] [PATCH RFC 13/14] qapi-introspect: Add #if conditions to introspection value

2018-02-11 Thread Markus Armbruster
Generated tests/test-qapi-introspect.c changes as follows:

--- test-qapi-introspect.c.old  2018-02-11 17:36:15.039696522 +0100
+++ tests/test-qapi-introspect.c2018-02-11 17:36:34.455419852 +0100
@@ -118,6 +118,9 @@ QLIT_QDICT(((QLitDictEntry[]) {
 { "ret-type", QLIT_QSTR("14"), },
 {}
 })),
+#if defined(TEST_IF_CMD)
+#if defined(TEST_IF_STRUCT)
+
 QLIT_QDICT(((QLitDictEntry[]) {
 { "arg-type", QLIT_QSTR("15"), },
 { "meta-type", QLIT_QSTR("command"), },
@@ -125,12 +128,19 @@ QLIT_QDICT(((QLitDictEntry[]) {
 { "ret-type", QLIT_QSTR("1"), },
 {}
 })),
+#endif /* defined(TEST_IF_STRUCT) */
+#endif /* defined(TEST_IF_CMD) */
+
+#if defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)
+
 QLIT_QDICT(((QLitDictEntry[]) {
 { "arg-type", QLIT_QSTR("16"), },
 { "meta-type", QLIT_QSTR("event"), },
 { "name", QLIT_QSTR("TestIfEvent"), },
 {}
 })),
+#endif /* defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT) */
+
 QLIT_QDICT(((QLitDictEntry[]) {
 { "members", QLIT_QLIST(((QLitObject[]) {
 {}

Signed-off-by: Markus Armbruster 
---
 scripts/qapi/introspect.py | 9 +
 1 file changed, 9 insertions(+)

diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index c02df95e72..342ae09422 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -40,6 +40,12 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
 ret = 'QLIT_QDICT(((QLitDictEntry[]) {\n'
 ret += ',\n'.join(elts) + '\n'
 ret += indent(level) + '}))'
+elif isinstance(obj, tuple):
+# Use of tuples for conditionals is a bit of a hack
+ifcond, begin = obj
+if begin:
+return gen_if(ifcond)
+return gen_endif(ifcond)
 else:
 assert False# not implemented
 if level > 0:
@@ -101,6 +107,9 @@ extern const QLitObject %(var)s;
 # Ignore types on first pass; visit_end() will pick up used types
 return not isinstance(entity, QAPISchemaType)
 
+def visit_ifcond(self, ifcond, begin):
+self._qlits.append((ifcond, begin))
+
 def _name(self, name):
 if self._unmask:
 return name
-- 
2.13.6




[Qemu-devel] [PATCH RFC 09/14] qapi: Pass ifcond to visitors

2018-02-11 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
---
 scripts/qapi/common.py | 15 +++
 tests/qapi-schema/qapi-schema-test.out |  9 +
 tests/qapi-schema/test-qapi.py | 19 +++
 3 files changed, 43 insertions(+)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 78aeec785e..692a7ec7c2 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1066,6 +1066,9 @@ class QAPISchemaVisitor(object):
 def visit_include(self, fname, info):
 pass
 
+def visit_ifcond(self, ifcond, begin):
+pass
+
 def visit_builtin_type(self, name, info, json_type):
 pass
 
@@ -1792,12 +1795,24 @@ class QAPISchema(object):
 def visit(self, visitor):
 visitor.visit_begin(self)
 module = None
+ifcond = None
 for entity in self._entity_list:
 if visitor.visit_needed(entity):
 if entity.module != module:
+if ifcond:
+visitor.visit_ifcond(ifcond, False)
+ifcond = None
 module = entity.module
 visitor.visit_module(module)
+if entity.ifcond != ifcond:
+if ifcond:
+visitor.visit_ifcond(ifcond, False)
+ifcond = entity.ifcond
+if ifcond:
+visitor.visit_ifcond(ifcond, True)
 entity.visit(visitor)
+if ifcond:
+visitor.visit_ifcond(ifcond, False)
 visitor.visit_end()
 
 
diff --git a/tests/qapi-schema/qapi-schema-test.out 
b/tests/qapi-schema/qapi-schema-test.out
index b11682314c..8fe9d7a3a8 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -232,23 +232,32 @@ command __org.qemu_x-command 
q_obj___org.qemu_x-command-arg -> __org.qemu_x-Unio
gen=True success_response=True boxed=False
 object TestIfStruct
 member foo: int optional=False
+if ['defined(TEST_IF_STRUCT)']
 enum TestIfEnum ['foo', 'bar']
+if ['defined(TEST_IF_ENUM)']
 object q_obj_TestStruct-wrapper
 member data: TestStruct optional=False
 enum TestIfUnionKind ['foo']
+if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)']
 object TestIfUnion
 member type: TestIfUnionKind optional=False
 tag type
 case foo: q_obj_TestStruct-wrapper
+if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)']
 alternate TestIfAlternate
 tag type
 case foo: int
 case bar: TestStruct
+if ['defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)']
 object q_obj_TestIfCmd-arg
 member foo: TestIfStruct optional=False
+if ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)']
 command TestIfCmd q_obj_TestIfCmd-arg -> None
gen=True success_response=True boxed=False
+if ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)']
 object q_obj_TestIfEvent-arg
 member foo: TestIfStruct optional=False
+if ['defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)']
 event TestIfEvent q_obj_TestIfEvent-arg
boxed=False
+if ['defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)']
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 67e417e298..fcdbb5b1ea 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -17,16 +17,26 @@ from qapi.common import QAPIError, QAPISchema, 
QAPISchemaVisitor
 
 class QAPISchemaTestVisitor(QAPISchemaVisitor):
 
+def __init__(self):
+self._ifcond = None
+
 def visit_module(self, name):
 print('module %s' % name)
 
 def visit_include(self, name, info):
 print('include %s' % name)
 
+def visit_ifcond(self, ifcond, begin):
+if begin:
+self._ifcond = ifcond
+else:
+self._ifcond = None
+
 def visit_enum_type(self, name, info, values, prefix):
 print('enum %s %s' % (name, values))
 if prefix:
 print('prefix %s' % prefix)
+self._print_if(self._ifcond)
 
 def visit_object_type(self, name, info, base, members, variants):
 print('object %s' % name)
@@ -36,10 +46,12 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
 print('member %s: %s optional=%s' % \
   (m.name, m.type.name, m.optional))
 self._print_variants(variants)
+self._print_if(self._ifcond)
 
 def visit_alternate_type(self, name, info, variants):
 print('alternate %s' % name)
 self._print_variants(variants)
+self._print_if(self._ifcond)
 
 def visit_command(self, name, info, arg_type, ret_type,
   gen, success_response, boxed):
@@ -47,10 +59,12 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
   (name, arg_type and arg_type.name, ret_type and ret_type.name))
 print('   gen=%s success_response=%s boxed=%s' % \
   (gen, success_response, boxed))
+self._print_if(self._ifco

[Qemu-devel] [PATCH RFC 04/14] qapi: generate a literal qobject for introspection

2018-02-11 Thread Markus Armbruster
From: Marc-André Lureau 

Replace the generated json string with a literal qobject. The later is
easier to deal with, at run time as well as compile time: adding #if
conditionals will be easier than in a json string.

Signed-off-by: Marc-André Lureau 

FIXME doc diffs

Signed-off-by: Markus Armbruster 
---
 docs/devel/qapi-code-gen.txt   | 29 +-
 monitor.c  |  2 +-
 scripts/qapi/introspect.py | 80 ++
 tests/test-qobject-input-visitor.c | 11 --
 4 files changed, 73 insertions(+), 49 deletions(-)

diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
index 0c4fc342fe..cb6175ba4d 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -1318,18 +1318,27 @@ Example:
 #ifndef EXAMPLE_QMP_INTROSPECT_H
 #define EXAMPLE_QMP_INTROSPECT_H
 
-extern const char example_qmp_schema_json[];
+extern const QLitObject qmp_schema_qlit;
 
 #endif
 $ cat qapi-generated/example-qapi-introspect.c
 [Uninteresting stuff omitted...]
 
-const char example_qmp_schema_json[] = "["
-"{\"arg-type\": \"0\", \"meta-type\": \"event\", \"name\": 
\"MY_EVENT\"}, "
-"{\"arg-type\": \"1\", \"meta-type\": \"command\", \"name\": 
\"my-command\", \"ret-type\": \"2\"}, "
-"{\"members\": [], \"meta-type\": \"object\", \"name\": \"0\"}, "
-"{\"members\": [{\"name\": \"arg1\", \"type\": \"[2]\"}], 
\"meta-type\": \"object\", \"name\": \"1\"}, "
-"{\"members\": [{\"name\": \"integer\", \"type\": \"int\"}, 
{\"default\": null, \"name\": \"string\", \"type\": \"str\"}], \"meta-type\": 
\"object\", \"name\": \"2\"}, "
-"{\"element-type\": \"2\", \"meta-type\": \"array\", \"name\": 
\"[2]\"}, "
-"{\"json-type\": \"int\", \"meta-type\": \"builtin\", \"name\": 
\"int\"}, "
-"{\"json-type\": \"string\", \"meta-type\": \"builtin\", \"name\": 
\"str\"}]";
+const QLitObject example_qmp_schema_qlit = QLIT_QLIST(((QLitObject[]) {
+QLIT_QDICT(((QLitDictEntry[]) {
+{ "arg-type", QLIT_QSTR("0") },
+{ "meta-type", QLIT_QSTR("event") },
+{ "name", QLIT_QSTR("Event") },
+{ }
+})),
+QLIT_QDICT(((QLitDictEntry[]) {
+{ "members", QLIT_QLIST(((QLitObject[]) {
+{ }
+})) },
+{ "meta-type", QLIT_QSTR("object") },
+{ "name", QLIT_QSTR("0") },
+{ }
+})),
+...
+{ }
+}));
diff --git a/monitor.c b/monitor.c
index d0e8d350fd..877b90f16d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -956,7 +956,7 @@ EventInfoList *qmp_query_events(Error **errp)
 static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
  Error **errp)
 {
-*ret_data = qobject_from_json(qmp_schema_json, &error_abort);
+*ret_data = qobject_from_qlit(&qmp_schema_qlit);
 }
 
 /*
diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 6c86673a09..e5c491d936 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -13,26 +13,35 @@ See the COPYING file in the top-level directory.
 from qapi.common import *
 
 
-# Caveman's json.dumps() replacement (we're stuck at Python 2.4)
-# TODO try to use json.dumps() once we get unstuck
-def to_json(obj, level=0):
+def to_qlit(obj, level=0, suppress_first_indent=False):
+
+def indent(level):
+return level * 4 * ' '
+
+if not suppress_first_indent:
+ret = indent(level)
 if obj is None:
-ret = 'null'
+ret = 'QLIT_QNULL'
 elif isinstance(obj, str):
-ret = '"' + obj.replace('"', r'\"') + '"'
+ret = 'QLIT_QSTR(' + to_c_string(obj) + ')'
 elif isinstance(obj, list):
-elts = [to_json(elt, level + 1)
+elts = [to_qlit(elt, level + 1)
 for elt in obj]
-ret = '[' + ', '.join(elts) + ']'
+elts.append(indent(level + 1) + "{}")
+ret = 'QLIT_QLIST(((QLitObject[]) {\n'
+ret += ',\n'.join(elts) + '\n'
+ret += indent(level) + '}))'
 elif isinstance(obj, dict):
-elts = ['"%s": %s' % (key.replace('"', r'\"'),
-  to_json(obj[key], level + 1))
-for key in sorted(obj.keys())]
-ret = '{' + ', '.join(elts) + '}'
+elts = []
+for key, value in sorted(obj.iteritems()):
+elts.append(indent(level + 1) + '{ %s, %s }' %
+(to_c_string(key), to_qlit(value, level + 1, True)))
+elts.append(indent(level + 1) + '{}')
+ret = 'QLIT_QDICT(((QLitDictEntry[]) {\n'
+ret += ',\n'.join(elts) + '\n'
+ret += indent(level) + '}))'
 else:
 assert False# not implemented
-if level == 1:
-ret = '\n' + ret
 return ret
 
 
@@ -48,38 +57,41 @@ class 
QAPISchemaGenIntrospectVisitor(QAPISchemaMonolithicCVisitor):
 ' * QAPI/QMP s

[Qemu-devel] [PATCH RFC 07/14] qapi: pass 'if' condition into QAPISchemaEntity objects

2018-02-11 Thread Markus Armbruster
From: Marc-André Lureau 

Built-in objects remain unconditional.  Explicitly defined objects
use the condition specified in the schema.  Implicitly defined
objects inherit their condition from their users.  For most of them,
there is exactly one user, so the condition to use is obvious.  The
exception is the wrapped type's generated for simple union variants,
which can be shared by any number of simple unions.  The tight
condition would be the disjunction of the conditions of these simple
unions.  For now, use wrapped type's condition instead.  Much
simpler and good enough for now.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Markus Armbruster 
---
 scripts/qapi/common.py | 98 +-
 1 file changed, 66 insertions(+), 32 deletions(-)

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 0254b9e1ef..789c77f11f 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1007,8 +1007,17 @@ def check_exprs(exprs):
 # Schema compiler frontend
 #
 
+def listify_cond(ifcond):
+if not ifcond:
+return []
+elif not isinstance(ifcond, list):
+return [ifcond]
+else:
+return ifcond
+
+
 class QAPISchemaEntity(object):
-def __init__(self, name, info, doc):
+def __init__(self, name, info, doc, ifcond=None):
 assert name is None or isinstance(name, str)
 self.name = name
 self.module = None
@@ -1019,6 +1028,7 @@ class QAPISchemaEntity(object):
 # such place).
 self.info = info
 self.doc = doc
+self.ifcond = listify_cond(ifcond)
 
 def c_name(self):
 return c_name(self.name)
@@ -1151,8 +1161,8 @@ class QAPISchemaBuiltinType(QAPISchemaType):
 
 
 class QAPISchemaEnumType(QAPISchemaType):
-def __init__(self, name, info, doc, values, prefix):
-QAPISchemaType.__init__(self, name, info, doc)
+def __init__(self, name, info, doc, ifcond, values, prefix):
+QAPISchemaType.__init__(self, name, info, doc, ifcond)
 for v in values:
 assert isinstance(v, QAPISchemaMember)
 v.set_owner(name)
@@ -1187,7 +1197,7 @@ class QAPISchemaEnumType(QAPISchemaType):
 
 class QAPISchemaArrayType(QAPISchemaType):
 def __init__(self, name, info, element_type):
-QAPISchemaType.__init__(self, name, info, None)
+QAPISchemaType.__init__(self, name, info, None, None)
 assert isinstance(element_type, str)
 self._element_type_name = element_type
 self.element_type = None
@@ -1195,6 +1205,7 @@ class QAPISchemaArrayType(QAPISchemaType):
 def check(self, schema):
 self.element_type = schema.lookup_type(self._element_type_name)
 assert self.element_type
+self.ifcond = self.element_type.ifcond
 
 def is_implicit(self):
 return True
@@ -1216,11 +1227,12 @@ class QAPISchemaArrayType(QAPISchemaType):
 
 
 class QAPISchemaObjectType(QAPISchemaType):
-def __init__(self, name, info, doc, base, local_members, variants):
+def __init__(self, name, info, doc, ifcond,
+ base, local_members, variants):
 # struct has local_members, optional base, and no variants
 # flat union has base, variants, and no local_members
 # simple union has local_members, variants, and no base
-QAPISchemaType.__init__(self, name, info, doc)
+QAPISchemaType.__init__(self, name, info, doc, ifcond)
 assert base is None or isinstance(base, str)
 for m in local_members:
 assert isinstance(m, QAPISchemaObjectTypeMember)
@@ -1408,8 +1420,8 @@ class 
QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
 
 
 class QAPISchemaAlternateType(QAPISchemaType):
-def __init__(self, name, info, doc, variants):
-QAPISchemaType.__init__(self, name, info, doc)
+def __init__(self, name, info, doc, ifcond, variants):
+QAPISchemaType.__init__(self, name, info, doc, ifcond)
 assert isinstance(variants, QAPISchemaObjectTypeVariants)
 assert variants.tag_member
 variants.set_owner(name)
@@ -1445,9 +1457,9 @@ class QAPISchemaAlternateType(QAPISchemaType):
 
 
 class QAPISchemaCommand(QAPISchemaEntity):
-def __init__(self, name, info, doc, arg_type, ret_type,
+def __init__(self, name, info, doc, ifcond, arg_type, ret_type,
  gen, success_response, boxed):
-QAPISchemaEntity.__init__(self, name, info, doc)
+QAPISchemaEntity.__init__(self, name, info, doc, ifcond)
 assert not arg_type or isinstance(arg_type, str)
 assert not ret_type or isinstance(ret_type, str)
 self._arg_type_name = arg_type
@@ -1484,8 +1496,8 @@ class QAPISchemaCommand(QAPISchemaEntity):
 
 
 class QAPISchemaEvent(QAPISchemaEntity):
-def __init__(self, name, info, doc, arg_type, boxed):
-QAPISchemaEntity.__init__(self, name, info, doc)
+def __init__(self, name, info, doc, ifcond, arg_type, boxed):
+QAPISchemaEntity.

[Qemu-devel] [PATCH RFC 06/14] qapi: add 'if' to top-level expressions

2018-02-11 Thread Markus Armbruster
From: Marc-André Lureau 

Accept 'if' key in top-level elements, accepted as string or list of
string type. The following patches will modify the test visitor to
check the value is correctly saved, and generate #if/#endif code (as a
single #if/endif line or a series for a list).

Example of 'if' key:
{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
  'if': 'defined(TEST_IF_STRUCT)' }

The generated code is for now *unconditional*. Later patches generate
the conditionals.

A following patch for qapi-code-gen.txt will provide more complete
documentation for 'if' usage.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Markus Armbruster 
---
 scripts/qapi/common.py   | 36 ++--
 tests/Makefile.include   |  4 
 tests/qapi-schema/bad-if-empty-list.err  |  1 +
 tests/qapi-schema/bad-if-empty-list.exit |  1 +
 tests/qapi-schema/bad-if-empty-list.json |  3 +++
 tests/qapi-schema/bad-if-empty-list.out  |  0
 tests/qapi-schema/bad-if-empty.err   |  1 +
 tests/qapi-schema/bad-if-empty.exit  |  1 +
 tests/qapi-schema/bad-if-empty.json  |  3 +++
 tests/qapi-schema/bad-if-empty.out   |  0
 tests/qapi-schema/bad-if-list.err|  1 +
 tests/qapi-schema/bad-if-list.exit   |  1 +
 tests/qapi-schema/bad-if-list.json   |  3 +++
 tests/qapi-schema/bad-if-list.out|  0
 tests/qapi-schema/bad-if.err |  1 +
 tests/qapi-schema/bad-if.exit|  1 +
 tests/qapi-schema/bad-if.json|  3 +++
 tests/qapi-schema/bad-if.out |  0
 tests/qapi-schema/qapi-schema-test.json  | 20 ++
 tests/qapi-schema/qapi-schema-test.out   | 22 +++
 tests/test-qmp-cmds.c|  6 ++
 21 files changed, 102 insertions(+), 6 deletions(-)
 create mode 100644 tests/qapi-schema/bad-if-empty-list.err
 create mode 100644 tests/qapi-schema/bad-if-empty-list.exit
 create mode 100644 tests/qapi-schema/bad-if-empty-list.json
 create mode 100644 tests/qapi-schema/bad-if-empty-list.out
 create mode 100644 tests/qapi-schema/bad-if-empty.err
 create mode 100644 tests/qapi-schema/bad-if-empty.exit
 create mode 100644 tests/qapi-schema/bad-if-empty.json
 create mode 100644 tests/qapi-schema/bad-if-empty.out
 create mode 100644 tests/qapi-schema/bad-if-list.err
 create mode 100644 tests/qapi-schema/bad-if-list.exit
 create mode 100644 tests/qapi-schema/bad-if-list.json
 create mode 100644 tests/qapi-schema/bad-if-list.out
 create mode 100644 tests/qapi-schema/bad-if.err
 create mode 100644 tests/qapi-schema/bad-if.exit
 create mode 100644 tests/qapi-schema/bad-if.json
 create mode 100644 tests/qapi-schema/bad-if.out

diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index b9a52e820d..0254b9e1ef 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -637,6 +637,27 @@ def add_name(name, info, meta, implicit=False):
 all_names[name] = meta
 
 
+def check_if(expr, info):
+
+def check_if_str(ifcond, info):
+if not isinstance(ifcond, str):
+raise QAPISemError(
+info, "'if' condition must be a string or a list of strings")
+if ifcond == '':
+raise QAPISemError(info, "'if' condition '' makes no sense")
+
+ifcond = expr.get('if')
+if ifcond is None:
+return
+elif isinstance(ifcond, list):
+if ifcond == []:
+raise QAPISemError(info, "'if' condition [] is useless")
+for elt in ifcond:
+check_if_str(elt, info)
+else:
+check_if_str(ifcond, info)
+
+
 def check_type(info, source, value, allow_array=False,
allow_dict=False, allow_optional=False,
allow_metas=[]):
@@ -876,6 +897,8 @@ def check_keys(expr_elem, meta, required, optional=[]):
 raise QAPISemError(info,
"'%s' of %s '%s' should only use true value"
% (key, meta, name))
+if key == 'if':
+check_if(expr, info)
 for key in required:
 if key not in expr:
 raise QAPISemError(info, "Key '%s' is missing from %s '%s'"
@@ -904,27 +927,28 @@ def check_exprs(exprs):
 
 if 'enum' in expr:
 meta = 'enum'
-check_keys(expr_elem, 'enum', ['data'], ['prefix'])
+check_keys(expr_elem, 'enum', ['data'], ['if', 'prefix'])
 enum_types[expr[meta]] = expr
 elif 'union' in expr:
 meta = 'union'
 check_keys(expr_elem, 'union', ['data'],
-   ['base', 'discriminator'])
+   ['base', 'discriminator', 'if'])
 union_types[expr[meta]] = expr
 elif 'alternate' in expr:
 meta = 'alternate'
-check_keys(expr_elem, 'alternate', ['data'])
+check_keys(expr_elem, 'alternate', ['data'], ['if'])
 elif 'struct' in expr:
 meta = 'struct'
-check_keys(expr_elem, 'struct'

Re: [Qemu-devel] [PATCH 2/2] 9p: fix leak in synth_name_to_path()

2018-02-11 Thread Greg Kurz
On Fri,  9 Feb 2018 19:29:20 +0100
Marc-André Lureau  wrote:

> Leak found thanks to ASAN:
> 
> Direct leak of 8 byte(s) in 1 object(s) allocated from:
> #0 0x55995789ac90 in __interceptor_malloc 
> (/home/elmarco/src/qemu/build/x86_64-softmmu/qemu-system-x86_64+0x1510c90)
> #1 0x7f0a91190f0c in g_malloc 
> /home/elmarco/src/gnome/glib/builddir/../glib/gmem.c:94
> #2 0x5599580a281c in v9fs_path_copy 
> /home/elmarco/src/qemu/hw/9pfs/9p.c:196:17
> #3 0x559958f9ec5d in coroutine_trampoline 
> /home/elmarco/src/qemu/util/coroutine-ucontext.c:116:9
> #4 0x7f0a8766ebbf  (/lib64/libc.so.6+0x50bbf)
> 
> Signed-off-by: Marc-André Lureau 
> ---
>  hw/9pfs/9p-synth.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c
> index 18082dffe8..54239c9bbf 100644
> --- a/hw/9pfs/9p-synth.c
> +++ b/hw/9pfs/9p-synth.c
> @@ -495,6 +495,7 @@ static int synth_name_to_path(FsContext *ctx, V9fsPath 
> *dir_path,
>  }
>  out:
>  /* Copy the node pointer to fid */
> +g_free(target->data);
>  target->data = g_memdup(&node, sizeof(void *));
>  target->size = sizeof(void *);
>  return 0;

Applied both patches.

Cheers,

--
Greg



Re: [Qemu-devel] [PATCHv2 10/12] cuda: convert to use the shared mos6522 device

2018-02-11 Thread David Gibson
On Fri, Feb 09, 2018 at 06:51:40PM +, Mark Cave-Ayland wrote:
> Add the relevant hooks as required for the MacOS timer calibration and delayed
> SR interrupt.
> 
> Signed-off-by: Mark Cave-Ayland 

Applied, thanks.

> ---
>  hw/misc/macio/cuda.c | 606 
> ++-
>  hw/ppc/mac.h |  87 
>  2 files changed, 204 insertions(+), 489 deletions(-)
> 
> diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
> index a185252144..54c02aeffb 100644
> --- a/hw/misc/macio/cuda.c
> +++ b/hw/misc/macio/cuda.c
> @@ -26,15 +26,14 @@
>  #include "hw/hw.h"
>  #include "hw/ppc/mac.h"
>  #include "hw/input/adb.h"
> +#include "hw/misc/mos6522.h"
>  #include "qemu/timer.h"
>  #include "sysemu/sysemu.h"
>  #include "qemu/cutils.h"
>  #include "qemu/log.h"
>  
> -/* XXX: implement all timer modes */
> -
> -/* debug CUDA */
> -//#define DEBUG_CUDA
> +/* debug CUDA packets */
> +//#define DEBUG_CUDA_PACKET
>  
>  /* debug CUDA packets */
>  //#define DEBUG_CUDA_PACKET
> @@ -47,426 +46,114 @@
>  #endif
>  
>  /* Bits in B data register: all active low */
> -#define TREQ 0x08/* Transfer request (input) */
> -#define TACK 0x10/* Transfer acknowledge (output) */
> -#define TIP  0x20/* Transfer in progress (output) */
> -
> -/* Bits in ACR */
> -#define SR_CTRL  0x1c/* Shift register control bits 
> */
> -#define SR_EXT   0x0c/* Shift on external clock */
> -#define SR_OUT   0x10/* Shift out if 1 */
> -
> -/* Bits in IFR and IER */
> -#define IER_SET  0x80/* set bits in IER */
> -#define IER_CLR  0   /* clear bits in IER */
> -#define SR_INT   0x04/* Shift register full/empty */
> -#define SR_DATA_INT  0x08
> -#define SR_CLOCK_INT 0x10
> -#define T1_INT  0x40/* Timer 1 interrupt */
> -#define T2_INT  0x20/* Timer 2 interrupt */
> -
> -/* Bits in ACR */
> -#define T1MODE  0xc0/* Timer 1 mode */
> -#define T1MODE_CONT 0x40/*  continuous interrupts */
> +#define TREQ0x08/* Transfer request (input) */
> +#define TACK0x10/* Transfer acknowledge (output) */
> +#define TIP 0x20/* Transfer in progress (output) */
>  
>  /* commands (1st byte) */
> -#define ADB_PACKET   0
> -#define CUDA_PACKET  1
> -#define ERROR_PACKET 2
> -#define TIMER_PACKET 3
> -#define POWER_PACKET 4
> -#define MACIIC_PACKET5
> -#define PMU_PACKET   6
> -
> -
> -/* CUDA commands (2nd byte) */
> -#define CUDA_WARM_START  0x0
> -#define CUDA_AUTOPOLL0x1
> -#define CUDA_GET_6805_ADDR   0x2
> -#define CUDA_GET_TIME0x3
> -#define CUDA_GET_PRAM0x7
> -#define CUDA_SET_6805_ADDR   0x8
> -#define CUDA_SET_TIME0x9
> -#define CUDA_POWERDOWN   0xa
> -#define CUDA_POWERUP_TIME0xb
> -#define CUDA_SET_PRAM0xc
> -#define CUDA_MS_RESET0xd
> -#define CUDA_SEND_DFAC   0xe
> -#define CUDA_BATTERY_SWAP_SENSE  0x10
> -#define CUDA_RESET_SYSTEM0x11
> -#define CUDA_SET_IPL 0x12
> -#define CUDA_FILE_SERVER_FLAG0x13
> -#define CUDA_SET_AUTO_RATE   0x14
> -#define CUDA_GET_AUTO_RATE   0x16
> -#define CUDA_SET_DEVICE_LIST 0x19
> -#define CUDA_GET_DEVICE_LIST 0x1a
> -#define CUDA_SET_ONE_SECOND_MODE 0x1b
> -#define CUDA_SET_POWER_MESSAGES  0x21
> -#define CUDA_GET_SET_IIC 0x22
> -#define CUDA_WAKEUP  0x23
> -#define CUDA_TIMER_TICKLE0x24
> -#define CUDA_COMBINED_FORMAT_IIC 0x25
> +#define ADB_PACKET  0
> +#define CUDA_PACKET 1
> +#define ERROR_PACKET2
> +#define TIMER_PACKET3
> +#define POWER_PACKET4
> +#define MACIIC_PACKET   5
> +#define PMU_PACKET  6
>  
>  #define CUDA_TIMER_FREQ (470 / 6)
>  
>  /* CUDA returns time_t's offset from Jan 1, 1904, not 1970 */
>  #define RTC_OFFSET  2082844800
>  
> -/* CUDA registers */
> -#define CUDA_REG_B   0x00
> -#define CUDA_REG_A   0x01
> -#define CUDA_REG_DIRB0x02
> -#define CUDA_REG_DIRA0x03
> -#define CUDA_REG_T1CL0x04
> -#define CUDA_REG_T1CH0x05
> -#define CUDA_REG_T1LL0x06
> -#define CUDA_REG_T1LH0x07
> -#define CUDA_REG_T2CL0x08
> -#define CUDA_REG_T2CH0x09
> -#define CUDA_REG_SR  0x0a
> -#define CUDA_REG_ACR 0x0b
> -#define CUDA_REG_PCR 0x0c
> -#define CUDA_REG_IFR 0x0d
> -#define CUDA_REG_IER 0x0e
> -#define CUDA_REG_ANH 0x0f
> -
> -static void cuda_update(CUDAState *s);
>  static void cuda_receive_packet_from_host(CUDAState *s,
>co