Re: [Qemu-devel] [PATCH RFC v7 7/7] qemu-iotests-s390x-fix-test-130

2015-05-04 Thread tu bo

Hi Kevin:

On 04/28/2015 04:23 PM, Kevin Wolf wrote:

Am 28.04.2015 um 04:59 hat tu bo geschrieben:

Hi Kevin:

On 04/27/2015 07:34 PM, Kevin Wolf wrote:

 Am 27.04.2015 um 13:24 hat Max Reitz geschrieben:

 On 27.04.2015 09:15, tu bo wrote:

 Hi Max:

 On 04/24/2015 01:07 AM, Max Reitz wrote:

 Well, that's a peculiar commit title. :-)

 I guess it's supposed to be qemu-iotests: s390x: fix test 
130?

 You're right. I will change it in the next version :-)


 On 23.04.2015 04:42, Xiao Guang Chen wrote:

 From: Bo Tu t...@linux.vnet.ibm.com

 The tests for device type ide_cd should only be tested 
for the pc
 platform.
 The default device id of hard disk on the s390 platform 
differs to
 that
 of the x86 platform. A new variable device_id is defined 
and
 virtio0
 set for the s390 platform. A x86 platform specific output 
file is
 also
 needed.

 Signed-off-by: Bo Tu t...@linux.vnet.ibm.com
 ---
   tests/qemu-iotests/130| 13 +++--
   tests/qemu-iotests/130.out|  4 ++--
   tests/qemu-iotests/130.pc.out | 43
 +++
   3 files changed, 56 insertions(+), 4 deletions(-)
   create mode 100644 tests/qemu-iotests/130.pc.out

 diff --git a/tests/qemu-iotests/130 
b/tests/qemu-iotests/130
 index bc26247..de40c7b 100755
 --- a/tests/qemu-iotests/130
 +++ b/tests/qemu-iotests/130
 @@ -58,9 +58,18 @@ echo === HMP commit ===
   echo
   # bdrv_make_empty() involves a header update for qcow2
   +case $QEMU_DEFAULT_MACHINE in
 +pc)
 +device_id=ide0-hd0
 +;;
 +s390)
 +device_id=virtio0
 +;;


 I think I mentioned before that I don't really like not taking 
the fact
 into account that there are other machine types, too. I'm still
 accepting it based on the fact that I think those machine 
types won't
 pass the tests right now anyway, so not caring for them in 
these case
 blocks won't break any tests, but it still feels like 
something we can
 avoid (like defaulting to virtio0 for any non-pc platform).

 Anyway, because I seem to remember I accepted it before:

 With the commit title fixed:

 Reviewed-by: Max Reitz mre...@redhat.com

 I guess you discussed with Xiao Guang Chen and accepted it in 
[PATCH RFC
 v5 6/7] qemu-iotests s390x fix test-051,  because test 130 and 
051 are
 using the same fix solution, and test 051 was fixed in v5. Seeing 
section
 of v5 in cover letter as below:


 Indeed we discussed it. Just for clarification, I disliked having only 
cases
 for pc and s390 -- there are other platforms, too, which will 
simply break
 by not including them in these case statements. We could try to avoid 
this by
 defaulting to virtio0 for every non-pc platform, and it will probably 
work for
 most without having to do further work here.

 However, I did accept it because all those non-PC (and non-s390) 
platforms
 won't pass the tests before this patch set either (because these test 
cases try
 to use IDE devices which will not be available there). So the series 
will not
 break them because they didn't work before either.

 Bottom line: I'm fine with this solution as it is.

 Maybe I'm missing the obvious, but why don't you just specify an
 explicit ID instead of guessing the default ID that qemu will use
 depending on the platform?

Please forgive me that I'm very sure about the meaning of default ID  you
mentioned. Maybe you mean default device ID? If I'm wrong, please correct me
:-)

The default device id of hard disk on the s390 platform differs to the device
id on the x86 platform,  so we need to use different device id for different
platform. For instance,  using virtio0 for s390x, and using ide0-hd0 for
x86 as below:
+_send_qemu_cmd $QEMU_HANDLE commit   virtio0 (qemu)
+_send_qemu_cmd $QEMU_HANDLE commit   ide0-hd0 (qemu)

Any why not use this?

qemu -drive id=testdisk,...
(qemu) commit testdisk
I tried and it works fine,  which is a more easier solution for test 
130.  I'll use your solution in patch v8.   

Re: [Qemu-devel] [PATCH RFC 19/19] qapi: New QMP command query-schema for QMP schema introspection

2015-05-04 Thread Markus Armbruster
Eric Blake ebl...@redhat.com writes:

 On 04/02/2015 11:29 AM, Markus Armbruster wrote:

 
 * Implicit type definitions are made explicit, and given
   auto-generated names.  These names start with ':' so they don't
   clash with the user's names.
 
   Example: a simple union implicitly defines an enumeration type for
   its discriminator.

 Given that I just tripped over a bug in my series where I failed to
 consider that '*name' and 'name' should be considered the same, I'm
 wondering if we should first update the parse engine to flatten
 shorthand into a canonical form (that is, get to a point where we have a
 list of all names and their C counterparts), rather than having to tweak
 lots of places in the backends to repeatedly make the same translations
 over and over again (stripping off leading '*', converting qapi
 'default' into C 'q_default', converting qapi 'a-b' into C 'a_b', etc.).

 I bet some of the backend generator gets simpler if the front end reuses
 your work to get into a canonical form on initial parse.

Agree:

 The schema generation proper is pretty trivial.  Much of the
 qapi-introspect.py's code actually does something else: convert the
 output of parse_schema() into a more usable data structure, lowering
 away uninteresting stuff.  This should really be done in qapi.py, so
 the other generators can use it, too.

However, we can't simply rebase your series onto mine, because mine is
already based on yours.  I really, really want to base on your tests,
simplifications and bug fixes.

Rearranging everything now doesn't sound appealing to me.

Let's get our combined work in, except for this PATCH 19, which isn't
ready, yet.

 +++ b/scripts/qapi-introspect.py
 @@ -0,0 +1,430 @@

 +
 +def make_implicit_enum_type(name, role, values):
 +name = ':enum-%s-%s' % (name, role)

 Evidence of my python newbie-ness:

 Here, you are using string formatting (as in 'pattern' % arguments), in
 other patches, I've seen you use concatenation (would look like ':enum-'
 + name + '-' + role).  Is there any rhyme or reason why one form should
 be considered over the other?

I'm no Pythonista, either.  I use whatever feels more readable.



Re: [Qemu-devel] [PATCH v7 25/39] qapi: Require valid names

2015-05-04 Thread Markus Armbruster
Eric Blake ebl...@redhat.com writes:

 On 04/29/2015 07:06 AM, Eric Blake wrote:
 Previous commits demonstrated that the generator overlooked various
 bad naming situations:
 - types, commands, and events need a valid name
 - enum members must be valid names, when combined with prefix
 - union and alternate branches cannot be marked optional
 

 regex, this patch just uses a broader combination that allows both
 upstream and downstream names, as well as a small hack that
 realizes that any enum name is merely a suffix to an already valid
 name prefix (that is, any enum name is valid if prepending _ fits
 the normal rules).
 

 +# Enum members can start with a digit, because the generated C
 +# code always prefixes it with the enum name
 +if enum_member:
 +membername = _%s %membername
 +if not valid_name.match(membername):
 +raise QAPIExprError(expr_info,

 Python question: Would it be any simpler to write:

 membername = '_' + membername

 and if so, do I need to squash anything in?

I find + easier to read here, even when compare to a correctly spaced
_%s % membername.

I think we have enough squash candidates to justify a quick v8.  I'd
prefer that, as I I haven't checked v7 anyway :)



Re: [Qemu-devel] [PATCH v7 36/39] qapi: Drop support for inline nested types

2015-05-04 Thread Markus Armbruster
Eric Blake ebl...@redhat.com writes:

 On 04/29/2015 07:06 AM, Eric Blake wrote:
 A future patch will be using a 'name':{dictionary} entry in the
 QAPI schema to specify a default value for an optional argument
 (see previous commit messages for more details why); but existing
 use of inline nested structs conflicts with that goal. Now that
 all commands have been changed to avoid inline nested structs,
 nuke support for them, and turn it into a hard error. Update the
 testsuite to reflect tighter parsing rules.
 
 Signed-off-by: Eric Blake ebl...@redhat.com
 Reviewed-by: Markus Armbruster arm...@redhat.com
 ---
  scripts/qapi-commands.py |  8 +++---
  scripts/qapi-event.py|  4 +--
  scripts/qapi-types.py|  9 ++-
  scripts/qapi-visit.py| 37 
 
  scripts/qapi.py  | 20 ++-

 +++ b/scripts/qapi-visit.py
 @@ -51,27 +51,6 @@ def generate_visit_struct_fields(name, field_prefix, 
 fn_prefix, members, base =
  else:
  full_name = %s_%s % (name, fn_prefix)
 
 -for argname, argentry, optional, structured in parse_args(members):
 -if structured:
 -if not fn_prefix:
 -nested_fn_prefix = argname
 -else:
 -nested_fn_prefix = %s_%s % (fn_prefix, argname)
 -
 -nested_field_prefix = %s%s. % (field_prefix, argname)
 -ret += generate_visit_struct_fields(name, nested_field_prefix,
 -nested_fn_prefix, argentry)

 This is the only place that calls generate_visit_struct_fields with a
 non-empty string for prefix arguments; I've got a cleanup patch that we
 can either squash into this patch or leave as standalone.

Squash vs. separate patch: your choice.



Re: [Qemu-devel] [PATCH] hw/sd: Don't pass BlockBackend to sd_reset()

2015-05-04 Thread Markus Armbruster
Peter Maydell peter.mayd...@linaro.org writes:

 The only valid BlockBackend to pass to sd_reset() is the one for
 the SD card, which is sd-blk. Drop the second argument from this
 function in favour of having it just use sd-blk.

 Signed-off-by: Peter Maydell peter.mayd...@linaro.org
 ---
 A minor cleanup that was lurking in the omap3 tree (where it's
 used to allow SD card controllers to reset the card, which is
 something I haven't yet figured out the legitimacy of...)

Reviewed-by: Markus Armbruster arm...@redhat.com



Re: [Qemu-devel] driver enhancement for Intel IGD passthrough

2015-05-04 Thread Tian, Kevin
 From: Alex Williamson [mailto:alex.william...@redhat.com]
 Sent: Tuesday, April 21, 2015 2:13 AM
 On Thu, 2015-04-16 at 17:24 +, Tian, Kevin wrote:
  ping...
 
   From: Tian, Kevin
   Sent: Friday, April 10, 2015 10:33 AM
  
   Hi,
  
   We are working on Linux/Windows graphics driver enhancement to
   remove those non-standard PCI resource accesses, e.g. to PCH/MCH
   registers, in parallel with the ongoing effort from Tiejun on current
   driver support.
  
   When the goal is to make IGD passthrough like a standard PCI
   passthrough w/o IGD specific patches, there is one open about VBT
   table which contains important display information (resolution,
   timing, etc.) for embedded panels (e.g. on laptop) which may not
   be detected through normal EDID query interface. Lacking of VBT
   may lead to a suboptimal display quality and other tricky issues.
  
   So we want to hear your opinions whether it makes sense to you
   to only maintain one IGD specific logic by exposing VBT through
   OpRegion to the guest. Except it all current IGD specific tweaks
   will not be required in the future w/ planned driver enhancements.
 
 Hi Kevin,
 
 I found the VBT in chapter 4 here:
 
 https://01.org/linuxgraphics/sites/default/files/documentation/acpi_igd_opre
 gion_spec.pdf
 
 How ASL/Driver use it:
 
 The system BIOS during, POST, decompresses (if necessary) the
 video BIOS image to physical RAM, scans VBIOS image, and copies
 ONLY the VBT block (all of the VBT data including its header) to
 OpRegion memory. This must be done whether IGD is primary or
 secondary VGA, and after VBIOS POST. The driver, during
 initialization, reads this data, validates it, and uses it.
 
 So this sounds like a simple extension required in SeaBIOS and OVMF to
 perform this additional operation to create this opregion in guest
 memory, right?  I'm not really seeing why this needs to be anything
 special beyond some guest BIOS code and maybe some procedure to extract
 the VBIOS from the host or expose it through sysfs.  I'd expect we need
 a VBIOS to initialize the card in the guest anyway.  There isn't really
 any requirement to pass through the host VBT, is there?  Seems like we
 can recreate it ourselves once we have the VBIOS.  If that's the case,
 it seems fairly agreeable to me, especially if it's more of an
 optimization than a requirement.  Thanks,
 
 Alex

either presenting VBT in guest BIOS or in guest OpRegion is OK because
guest driver will try another if one is lacking. You can even create a new
VBT with filtered information. 

Here the background of this ask, is that we initially plan to make IGD 
passthru exactly same as normal PCI passthru w/o IGD specific patches, 
by providing driver enhancements, however w/o a valid VBT presented 
there will be feature/quality impact on some platforms. 

So we want to know whether keeping this very IGD specific logic only for
VBT is acceptable to the community, after removing other hacks on
MCH/ICH, etc.

Looks from your feedback it should be fine. :-)

Thanks
Kevin



Re: [Qemu-devel] Patch for 64 bit mingw compilation

2015-05-04 Thread Joseph Hindin
Hi
   The changes appear to be necessary. I was building Windows QEMU GA on
Fedora 21, MINGW cross-compiler v. 4.9.2, build 20141030, Fedora MinGW
4.9.2-1.fc21 and before the changes, linking failed.

Below is the building log for qga-vss.dll before the changes:

-
$ make qga/vss-win32/qga-vss.dll
CHK version_gen.h
  CXX   qga/vss-win32/requester.o
qga/vss-win32/requester.cpp:1:0: warning: -fPIC ignored for target (all
code is position independent)
 /*
 ^
qga/vss-win32/requester.cpp:1:0: warning: -fPIC ignored for target (all
code is position independent)
 /*
 ^
In file included from qga/vss-win32/requester.cpp:17:0:
./inc/win2003/vswriter.h:39:2: warning: 'typedef' was ignored in this
declaration
  };
  ^
./inc/win2003/vswriter.h:47:2: warning: 'typedef' was ignored in this
declaration
  };
  ^
./inc/win2003/vswriter.h:59:2: warning: 'typedef' was ignored in this
declaration
  };
  ^
./inc/win2003/vswriter.h:67:2: warning: 'typedef' was ignored in this
declaration
  };
  ^
./inc/win2003/vswriter.h:75:2: warning: 'typedef' was ignored in this
declaration
  };
  ^
./inc/win2003/vswriter.h:83:5: warning: 'typedef' was ignored in this
declaration
 };
 ^
./inc/win2003/vswriter.h:93:5: warning: 'typedef' was ignored in this
declaration
 };
 ^
./inc/win2003/vswriter.h:103:2: warning: 'typedef' was ignored in this
declaration
  };
  ^
./inc/win2003/vswriter.h:112:2: warning: 'typedef' was ignored in this
declaration
  };
  ^
./inc/win2003/vswriter.h:119:2: warning: 'typedef' was ignored in this
declaration
  };
  ^
  CXX   qga/vss-win32/provider.o
qga/vss-win32/provider.cpp:1:0: warning: -fPIC ignored for target (all code
is position independent)
 /*
 ^
qga/vss-win32/provider.cpp:1:0: warning: -fPIC ignored for target (all code
is position independent)
 /*
 ^
  CXX   qga/vss-win32/install.o
qga/vss-win32/install.cpp:1:0: warning: -fPIC ignored for target (all code
is position independent)
 /*
 ^
qga/vss-win32/install.cpp:1:0: warning: -fPIC ignored for target (all code
is position independent)
 /*
 ^
  LINK  qga/vss-win32/qga-vss.dll
qga/vss-win32/requester.o: In function `WaitForAsync':
/home/jhindin/development/qemu_upstream/qga/vss-win32/requester.cpp:148:
undefined reference to `__stack_chk_fail'
qga/vss-win32/requester.o: In function `requester_freeze':
/home/jhindin/development/qemu_upstream/qga/vss-win32/requester.cpp:435:
undefined reference to `__stack_chk_fail'
qga/vss-win32/requester.o: In function `requester_thaw':
/home/jhindin/development/qemu_upstream/qga/vss-win32/requester.cpp:503:
undefined reference to `__stack_chk_fail'
qga/vss-win32/requester.o: In function `fprintf(_iobuf*, char const*, ...)':
/usr/x86_64-w64-mingw32/sys-root/mingw/include/stdio.h:292: undefined
reference to `__stack_chk_fail'
qga/vss-win32/requester.o:requester.cpp:(.rdata$.refptr.__stack_chk_guard[.refptr.__stack_chk_guard]+0x0):
undefined reference to `__stack_chk_guard'
qga/vss-win32/install.o: In function `errmsg_dialog':
/home/jhindin/development/qemu_upstream/qga/vss-win32/install.cpp:65:
undefined reference to `__stack_chk_fail'
qga/vss-win32/install.o: In function `CreateRegistryKey':
/home/jhindin/development/qemu_upstream/qga/vss-win32/install.cpp:349:
undefined reference to `__stack_chk_fail'
qga/vss-win32/install.o: In function `errmsg(unsigned long, char const*)':
/home/jhindin/development/qemu_upstream/qga/vss-win32/install.cpp:52:
undefined reference to `__stack_chk_fail'
qga/vss-win32/install.o: In function `QGAProviderFind':
/home/jhindin/development/qemu_upstream/qga/vss-win32/install.cpp:175:
undefined reference to `__stack_chk_fail'
qga/vss-win32/install.o: In function `DllUnregisterServer':
/home/jhindin/development/qemu_upstream/qga/vss-win32/install.cpp:445:
undefined reference to `__stack_chk_fail'
qga/vss-win32/install.o:/home/jhindin/development/qemu_upstream/qga/vss-win32/install.cpp:422:
more undefined references to `__stack_chk_fail' follow
collect2: error: ld returned 1 exit status
/home/jhindin/development/qemu_upstream/qga/vss-win32/Makefile.objs:10:
recipe for target 'qga/vss-win32/qga-vss.dll' failed
make: *** [qga/vss-win32/qga-vss.dll] Error 1
--




   Regards,
  Joseph Hindin

On Sun, May 3, 2015 at 11:33 AM, Olga Krishtal okrish...@parallels.com
wrote:

 On 11/03/15 17:51, Joseph Hindin wrote:

 Hi

 When compiling the QEMU Guest Agent with 64-bit MinGW toolchain
 version
 4.9.2, I run into the following problem: qga-vss.dll linking failed as
 linker reported a lot of unresolved symbol __stack_chk_fail errors
 stemming
 from the stack protection. The attached patch solves the problem by adding
 libssp to the qga-vss.dll libraries list.

 Regards,
Joseph Hindin

  Are you sure that it is necessary?
 I worked with VSS-provider in order to check it on 64 bit platform (Win
 Server 2008) , and I did not have such
 problems.



Re: [Qemu-devel] [PATCH 4/4] qemu-ga: Building Windows MSI installation with configure/Makefile

2015-05-04 Thread Paolo Bonzini


On 26/04/2015 09:04, Yossi Hindin wrote:
 +ifdef QEMU_GA_MSI_WITH_VSS
 +${QEMU_GA_MSI}: qga/vss-win32/qga-vss.dll qemu-ga.exe

Shouldn't the qemu-ga.exe dependency be unconditional?

 +endif
 +
 +${QEMU_GA_MSI}: config-host.mak
 +
 +${QEMU_GA_MSI}:  qga/installer/qemu-ga.wxs
 + $(call quiet-command,QEMU_GA_VERSION=$(QEMU_GA_VERSION) 
 QEMU_GA_MANUFACTURER=$(QEMU_GA_MANUFACTURER) 
 QEMU_GA_DISTRO=$(QEMU_GA_DISTRO) \
 + wixl -o $@ ${QEMU_GA_MSI_ARCH} ${QEMU_GA_MSI_WITH_VSS} 
 ${QEMU_GA_MSI_MINGW_DLL_PATH} $,   WIXL  $@)

Please use $(...) instead of ${...} for consistency.

 +
  clean:
  # avoid old build problems by removing potentially incorrect old files
   rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h 
 gen-op-arm.h
   rm -f qemu-options.def
 + rm -f *.msi
   find . \( -name '*.l[oa]' -o -name '*.so' -o -name '*.dll' -o -name 
 '*.mo' -o -name '*.[oda]' \) -type f -exec rm {} +
   rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga TAGS cscope.* 
 *.pod *~ */*~
   rm -f fsdev/*.pod
 diff --git a/configure b/configure
 index 6969f6f..0aa79bb 100755
 --- a/configure
 +++ b/configure
 @@ -316,6 +316,7 @@ snappy=
  bzip2=
  guest_agent=
  guest_agent_with_vss=no
 +guest_msi=
  vss_win32_sdk=
  win_sdk=no
  want_tools=yes
 @@ -1069,6 +1070,10 @@ for opt do
;;
--disable-guest-agent) guest_agent=no
;;
 +  --enable-guest-msi) guest_msi=yes
 +  ;;
 +  --disable-guest-msi) guest_msi=no
 +  ;;
--with-vss-sdk) vss_win32_sdk=
;;
--with-vss-sdk=*) vss_win32_sdk=$optarg
 @@ -1407,6 +1412,8 @@ Advanced options (experts only):
--enable-quorum  enable quorum block filter support
--disable-numa   disable libnuma support
--enable-numaenable libnuma support
 +  --enable-guest-msi   enable building guest agent Windows MSI 
 installation package
 +  --disable-guest-msi  disable building guest agent Windows MSI 
 installation package

--enable-guest-agent-msi?

Also, please keep the guest agent options together.

  
  NOTE: The object files are built at the place where configure is launched
  EOF
 @@ -3832,6 +3839,54 @@ if test $mingw32 = yes -a $guest_agent != no 
 -a $guest_agent_with_vss
  fi
  
  ##
 +# Guest agent Window MSI  package
 +
 +if test $guest_msi = yes; then

Since building the MSI is on-demand anyway (make msi), we might as well
treat it similar to other configure options:

- --enable-foo causes an error if the feature is not available
- --disable-foo forcibly disable the feature
- the default is to configure the feature if available, otherwise disable it

This would be something like this:

if test $guest_agent != yes; then
  if test $guest_msi = yes; then
error_exit MSI guest agent package requires guest agent enabled
  fi
  guest_msi=no
elif test $mingw32 != yes; then
  if test $guest_msi = yes; then
error_exit MSI guest agent package is available only for MinGW Windows 
cross-compilation
  fi
  guest_msi=no
elif test ! has_wixl; then
  if test $guest_msi = yes; then
error_exit wixl not found, required for building MSI guest agent package
  fi
  guest_msi=no
fi

if test $guest_msi != no; then
  ...
fi

 +
 +
 +  if test $guest_agent_with_vss = yes; then
 +QEMU_GA_MSI_WITH_VSS=-D InstallVss
 +  fi
 +
 +  if test $QEMU_GA_MANUFACTURER = ; then
 +QEMU_GA_MANUFACTURER=QEMU
 +  fi
 +
 +  if test $QEMU_GA_DISTRO = ; then
 +QEMU_GA_DISTRO=Linux
 +  fi
 +
 +  if test $QEMU_GA_VERSION = ; then
 +  QEMU_GA_VERSION=`cat $source_path/VERSION`
 +  fi
 +
 +  case $cpu in
 +  x86_64)
 +QEMU_GA_MSI_ARCH=-a x64 -D Arch=64
 +;;
 +  i386)
 +QEMU_GA_MSI_ARCH=-D Arch=32
 +;;
 +  *)
 +error_exit CPU $cpu not supported for building installation package
 +;;
 +  esac
 +
 +fi
 +
 +##
  
  ##
  # check if we have fdatasync
 @@ -4500,6 +4555,14 @@ if test $mingw32 = yes ; then
  echo CONFIG_QGA_VSS=y  $config_host_mak
  echo WIN_SDK=\$win_sdk\  $config_host_mak
fi
 +  if test $guest_msi = yes; then

Similarly, != no here.

 +echo QEMU_GA_MSI_MINGW_DLL_PATH=-D Mingw_dlls=`$pkg_config 
 --variable=prefix glib-2.0`/bin  $config_host_mak

Why not set up the variable above?

Paolo

 +echo QEMU_GA_MSI_WITH_VSS=${QEMU_GA_MSI_WITH_VSS}  $config_host_mak
 +echo QEMU_GA_MSI_ARCH=${QEMU_GA_MSI_ARCH}  $config_host_mak
 +echo QEMU_GA_MANUFACTURER=${QEMU_GA_MANUFACTURER}  $config_host_mak
 +echo QEMU_GA_DISTRO=${QEMU_GA_DISTRO}  $config_host_mak
 +echo QEMU_GA_VERSION=${QEMU_GA_VERSION}  $config_host_mak
 +  fi
  else
echo CONFIG_POSIX=y  $config_host_mak
  fi
 



Re: [Qemu-devel] [PATCH 3/4] qemu-ga: Introduce Windows MSI script

2015-05-04 Thread Paolo Bonzini


On 26/04/2015 09:04, Yossi Hindin wrote:
 +  ?ifndef env.QEMU_GA_VERSION ?
 +?error Environemtn variable QEMU_GA_VERSION undefined?
 +  ?endif?
 +

Environment

Ironically, msitools was started exactly to build an installer with
qemu-ga (the idea was to do it with raw tables, that was a few months
before Marc-Andre wrote wixl).  It only took 2.5 years...

Paolo



Re: [Qemu-devel] [PATCH 0/5] Extend TPM support with a QEMU-external TPM

2015-05-04 Thread Igor Mammedov
On Wed, 29 Apr 2015 12:42:21 -0400
Stefan Berger stef...@linux.vnet.ibm.com wrote:

 On 04/29/2015 05:06 AM, Igor Mammedov wrote:
  On Wed, 22 Apr 2015 14:18:55 -0400
  Stefan Berger stef...@linux.vnet.ibm.com wrote:
 
  On 04/22/2015 03:00 AM, Igor Mammedov wrote:
  On Thu, 16 Apr 2015 10:05:35 -0400
  Stefan Berger stef...@linux.vnet.ibm.com wrote:
 
  On 04/16/2015 09:35 AM, Igor Mammedov wrote:
  On Wed, 15 Apr 2015 18:38:43 -0400
  [...]
  Is it possible to use MMIO region instead of allocating tpm_ppi_anchor
  and tpm_ppi in BIOS memory?
  MMIO region of what? Of the TIS? The TIS doesn't have memory locations
  'just to keep bytes' and they would be cleared upon machine reset / 
  reboot.
 
  The purpose of the PPI interface is to leave an opcode for the BIOS to
  act upon after a reset. So we have to write it into memory that doesn't
  get cleared upon reboot. Also, the BIOS leaves a result in memory so we
  can read the result code in the OS via sysfs entry.
  it doesn't matter where opcodes are stored though, they could be stored
  on QEMU's TPM device (i.e. inside TPM owned MMIO region). That way QEMU
  will know in advance where opcodes are stored and build ACPI tables
  with correct address without any need for scanning memory.
  It only matters that these opcodes survive a machine reboot. Some
  devices get reset on the way
  and the choices of suitable NVRAM are limited.
 
  Ok, so we could extend the TPM TIS model with a buffer that can hold
  these opcodes.
  At the moment I think I need 3 bytes. Future specifications may require
  more. We can
  make room for this in the TIS from offset 0xf90-0xfff where we can put
  vendor
  specific extensions. Maybe we just stick it into locality 4 - 0xfed4
  4f90 to 0xfed4 4fff
  and don't reset that memory area ?
  yep
 
 
 So we can do it this way ...
 
 
 
  The only thing that speaks against this is that this would not work if
  SeaBIOS was not
  running on QEMU but on bare metal -- if that was to be a concern at all.
  The current
  solution tried to address this as well, but it would require coreboot
  support and the
  last time I tested this on my Chromebook it looks like an anchor created
  but SeaBIOS
  is not found after a reboot anymore, so it would require some form of
  cooperation
  from coreboot to enable this. So if we ditch this, we can go with a
  buffer in the MMIO.
  Coreboot would probably require different ACPI buffer read/write functions,
  the rest could stay the same.
 
 Yes, understood.
 
 
 
  Although it's just another workaround around split brain problem where
  QEMU owned ACPI tables have to know about guest (BIOS) provided address.
 
 
  I had previously tried using NVRAM of the TPM to leave that opcode (and
  result) , but this doesn't work well due to protection restrictions of
  the TPM's NVRAM locations and using the Linux TSS for example non-root
  users could then write an opcode into the NVRAM of the TPM (there are
  TPM commands to write to the TPM's NVRAM locations and tpm-tools has
  tools to write to these locations) that the machine then ends up acting
  upon without the admin of the machine wanting that. So, that's not a
  choice, either.
 
 
  That would simplify BIOS part a bit and significantly simplify ACPI code
  as most of it is dealing with figuring out address of tpm_ppi.
  Wished it would, but I don't see a way to make it easier.
  Since ACPI implementation for handling opcodes doesn't interface/depend
  on TPM device and interfaces only with BIOS it should also be BIOS owned.
  Cleaner way could be installing an additional BIOS generated table
  (with correct ADDR) to QEMU provided ACPI tables set.
  Would that be a custom table? Do we need changes for this in the OS
  or can that table be found via ACPI?
  It would be just additional SSDT, no OS changes are required.
  what you'll need to do is to extend QEMU supplied RSDT to include
  pointer to additional SSDT.
  I'm not sure where ACPI tables come from in case of coreboot though.
 
  That also would be reusable with coreboot since you will have shared
  ACPI impl. in SeaBIOS without need to duplicate it in QEMU/coreboot.
  Can you sketch the ACPI code necessary to convey the SeaBIOS / coreboot
  allocated memory address ? How do we write the SeaBIOS allocated
  address into the ACPI code?
  grep for acpi_pci64_start in SeaBIOS code,
  it should give rough idea how to do it.
 
  [...]
 
 
 ... or we can do it this way. Which way now ? My preference is the TIS 
 path, because it seems easier.
 
 
 Now what I am seeing in SeaBIOS is that another SSDT is being built. 
 Would this then be an
 additional SSDT or would it replace the TPM's SSDT that we're now 
 supplying from QEMU.
perhaps an additional SSDT that has only Seabios specific AML which
doesn't interact with TIS device.

 
 2 choices now -- which one to take?
I'd try installing extra SSDT table first as a cleanest way (seabios only)
and if it fails fallback to TIS path.

 
  Stefan
 

Re: [Qemu-devel] [PATCH v5 13/20] hw/acpi/aml-build: Add ToUUID macro

2015-05-04 Thread Igor Mammedov
On Wed, 29 Apr 2015 21:41:39 +0800
Shannon Zhao shannon.z...@linaro.org wrote:

 
 
 On 2015/4/28 17:48, Shannon Zhao wrote:
  On 2015/4/28 17:35, Igor Mammedov wrote:
  On Tue, 28 Apr 2015 16:52:19 +0800
  Shannon Zhao zhaoshengl...@huawei.com wrote:
 
  On 2015/4/28 16:15, Igor Mammedov wrote:
  btw:
  whole thing might be simpler if an intermediate conversion is 
  avoided,
  just pack buffer as in spec byte by byte:
 
  /* format: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp */
  assert(strlen(uuid) == ...);
  build_append_byte(var-buf, HEX2BYTE(uuid[3]); /* dd */
 
  use build_append_byte(var-buf, HEX2BYTE(uuid + 7); ?
 
  build_append_byte(var-buf, HEX2BYTE(uuid[2]); /* cc */
 
  use build_append_byte(var-buf, HEX2BYTE(uuid + 5); ?
  if you mean hyphens /-/ then they are not encoded,
  but you surely can add checks for them to make sure that
  UUID format is as expected.
 
 
  I mean uuid[3] points to b not dd. Maybe use following way:
 
  static uint8_t Hex2Byte(char *src)
  or even better:
  Hex2Byte(char *src, byte_idx)
 and do pointer arithmetic inside
 
  [...]
  build_append_byte(var-buf, Hex2Byte(uuid + (3 * 2))); /* dd */
  build_append_byte(var-buf, Hex2Byte(uuid, 3)); /* dd - at offset 00 */
  build_append_byte(var-buf, Hex2Byte(uuid, 2)); /* cc - at offset 01 */
  ...
 
  Yes, it's better to first four bytes. But there are hyphens /-/, for
  offset 04, 05 and etc it doesn't work. We can't use following expression:
 
  build_append_byte(var-buf, Hex2Byte(uuid, 5)); /* ff - at offset 04 */
  build_append_byte(var-buf, Hex2Byte(uuid, 4)); /* ee - at offset 05 */
  ...
 
 
 
 So about the implementation of this macro, I think I'd like to use 
 following approach. This lets Hex2Byte do what it should only do and 
 still has a clear look of UUID. What do you think about?
 
 static uint8_t Hex2Byte(char *src)
 {
  int hi = Hex2Digit(*src++);
  int lo = Hex2Digit(*src);
 
  if ((hi  0) || (lo  0))
  return -1;
just make Hex2Digit() assert on wrong input.

 
  return (hi  4) | lo;
 }
 
 g_assert((strlen(uuid) == 36)  (uuid[8] == '-')  (uuid[13] == '-')
 (uuid[18] == '-')  (uuid[23] == '-'));
 
 build_append_byte(var-buf, Hex2Byte(uuid + (3 * 2))); /* dd */
   ^
I'd make it one number, instead of forcing reader to do math
every time he/she looks at this code.


 build_append_byte(var-buf, Hex2Byte(uuid + (2 * 2))); /* cc */
 build_append_byte(var-buf, Hex2Byte(uuid + (1 * 2))); /* bb */
 build_append_byte(var-buf, Hex2Byte(uuid + (0 * 2))); /* aa */
 
 build_append_byte(var-buf, Hex2Byte(uuid + (5 * 2 + 1))); /* ff */
 build_append_byte(var-buf, Hex2Byte(uuid + (4 * 2 + 1))); /* ee */
 
 build_append_byte(var-buf, Hex2Byte(uuid + (7 * 2 + 2))); /* hh */
 build_append_byte(var-buf, Hex2Byte(uuid + (6 * 2 + 2))); /* gg */
 
 build_append_byte(var-buf, Hex2Byte(uuid + (8 * 2 + 3))); /* ii */
 build_append_byte(var-buf, Hex2Byte(uuid + (9 * 2 + 3))); /* jj */
 
 build_append_byte(var-buf, Hex2Byte(uuid + (10 * 2 + 4))); /* kk */
 build_append_byte(var-buf, Hex2Byte(uuid + (11 * 2 + 4))); /* ll */
 build_append_byte(var-buf, Hex2Byte(uuid + (12 * 2 + 4))); /* mm */
 build_append_byte(var-buf, Hex2Byte(uuid + (13 * 2 + 4))); /* nn */
 build_append_byte(var-buf, Hex2Byte(uuid + (14 * 2 + 4))); /* oo */
 build_append_byte(var-buf, Hex2Byte(uuid + (15 * 2 + 4))); /* pp */




Re: [Qemu-devel] [PATCH v1 1/1] hw/ptimer: Do not artificially limit timers when using icount

2015-05-04 Thread Paolo Bonzini


On 04/05/2015 05:18, Edgar E. Iglesias wrote:
 From: Edgar E. Iglesias edgar.igles...@xilinx.com
 
 Signed-off-by: Edgar E. Iglesias edgar.igles...@xilinx.com
 ---
  hw/core/ptimer.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c
 index 2abad1f..8437bd6 100644
 --- a/hw/core/ptimer.c
 +++ b/hw/core/ptimer.c
 @@ -189,7 +189,7 @@ void ptimer_set_limit(ptimer_state *s, uint64_t limit, 
 int reload)
   * on the current generation of host machines.
   */
  
 -if (limit * s-period  1  s-period) {
 +if (!use_icount  limit * s-period  1  s-period) {
  limit = 1 / s-period;
  }
  
 

Reviewed-by: Paolo Bonzini pbonz...@redhat.com



Re: [Qemu-devel] [RFC PATCH 05/15] spapr_pci: add PHB unrealize

2015-05-04 Thread Paolo Bonzini


On 01/05/2015 03:18, Michael Roth wrote:
 Sorry, I mixed up memory regions with memory region alias. Memory region
 aliases do a memory_region_ref() on the original MR, similar to
 memory_region_add_subregion(), so that's what ends up creating the
 reference to the owner/PHB.
 
 So I think I do need to object_unparent() the 2 MR aliases in realize
 (otherwise the PHB doesn't get finalized), but everything else can
 get moved to instance_finalize() as you suggested and that seems to
 do the trick.

Yes, unparenting the aliases in unrealize is okay and in fact may be
required to avoid a leak.  Patching docs/memory.txt to point it out
would be great. :)

Paolo



Re: [Qemu-devel] [PATCH v5 13/20] hw/acpi/aml-build: Add ToUUID macro

2015-05-04 Thread Shannon Zhao


On 2015/5/4 17:22, Igor Mammedov wrote:
 On Wed, 29 Apr 2015 21:41:39 +0800
 Shannon Zhao shannon.z...@linaro.org wrote:
 


 On 2015/4/28 17:48, Shannon Zhao wrote:
 On 2015/4/28 17:35, Igor Mammedov wrote:
 On Tue, 28 Apr 2015 16:52:19 +0800
 Shannon Zhao zhaoshengl...@huawei.com wrote:

 On 2015/4/28 16:15, Igor Mammedov wrote:
 btw:
 whole thing might be simpler if an intermediate conversion is 
 avoided,
 just pack buffer as in spec byte by byte:

 /* format: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp */
 assert(strlen(uuid) == ...);
 build_append_byte(var-buf, HEX2BYTE(uuid[3]); /* dd */

 use build_append_byte(var-buf, HEX2BYTE(uuid + 7); ?

 build_append_byte(var-buf, HEX2BYTE(uuid[2]); /* cc */

 use build_append_byte(var-buf, HEX2BYTE(uuid + 5); ?
 if you mean hyphens /-/ then they are not encoded,
 but you surely can add checks for them to make sure that
 UUID format is as expected.


 I mean uuid[3] points to b not dd. Maybe use following way:

 static uint8_t Hex2Byte(char *src)
 or even better:
 Hex2Byte(char *src, byte_idx)
and do pointer arithmetic inside

 [...]
 build_append_byte(var-buf, Hex2Byte(uuid + (3 * 2))); /* dd */
 build_append_byte(var-buf, Hex2Byte(uuid, 3)); /* dd - at offset 00 */
 build_append_byte(var-buf, Hex2Byte(uuid, 2)); /* cc - at offset 01 */
 ...

 Yes, it's better to first four bytes. But there are hyphens /-/, for
 offset 04, 05 and etc it doesn't work. We can't use following expression:

 build_append_byte(var-buf, Hex2Byte(uuid, 5)); /* ff - at offset 04 */
 build_append_byte(var-buf, Hex2Byte(uuid, 4)); /* ee - at offset 05 */
 ...



 So about the implementation of this macro, I think I'd like to use 
 following approach. This lets Hex2Byte do what it should only do and 
 still has a clear look of UUID. What do you think about?

 static uint8_t Hex2Byte(char *src)
 {
  int hi = Hex2Digit(*src++);
  int lo = Hex2Digit(*src);

  if ((hi  0) || (lo  0))
  return -1;
 just make Hex2Digit() assert on wrong input.
 

Ok.


  return (hi  4) | lo;
 }

 g_assert((strlen(uuid) == 36)  (uuid[8] == '-')  (uuid[13] == '-')
 (uuid[18] == '-')  (uuid[23] == '-'));

 build_append_byte(var-buf, Hex2Byte(uuid + (3 * 2))); /* dd */
^
 I'd make it one number, instead of forcing reader to do math
 every time he/she looks at this code.
 

Ok, will do this. And about other patches in this series could you offer
your comments?

Thanks,
Shannon

 
 build_append_byte(var-buf, Hex2Byte(uuid + (2 * 2))); /* cc */
 build_append_byte(var-buf, Hex2Byte(uuid + (1 * 2))); /* bb */
 build_append_byte(var-buf, Hex2Byte(uuid + (0 * 2))); /* aa */

 build_append_byte(var-buf, Hex2Byte(uuid + (5 * 2 + 1))); /* ff */
 build_append_byte(var-buf, Hex2Byte(uuid + (4 * 2 + 1))); /* ee */

 build_append_byte(var-buf, Hex2Byte(uuid + (7 * 2 + 2))); /* hh */
 build_append_byte(var-buf, Hex2Byte(uuid + (6 * 2 + 2))); /* gg */

 build_append_byte(var-buf, Hex2Byte(uuid + (8 * 2 + 3))); /* ii */
 build_append_byte(var-buf, Hex2Byte(uuid + (9 * 2 + 3))); /* jj */

 build_append_byte(var-buf, Hex2Byte(uuid + (10 * 2 + 4))); /* kk */
 build_append_byte(var-buf, Hex2Byte(uuid + (11 * 2 + 4))); /* ll */
 build_append_byte(var-buf, Hex2Byte(uuid + (12 * 2 + 4))); /* mm */
 build_append_byte(var-buf, Hex2Byte(uuid + (13 * 2 + 4))); /* nn */
 build_append_byte(var-buf, Hex2Byte(uuid + (14 * 2 + 4))); /* oo */
 build_append_byte(var-buf, Hex2Byte(uuid + (15 * 2 + 4))); /* pp */
 



Re: [Qemu-devel] [PATCH 2/2] spice-char: notify the server when chardev is writable

2015-05-04 Thread Amit Shah
Hi Gerd,

On (Mon) 27 Oct 2014 [12:57:57], Gerd Hoffmann wrote:
 On Mo, 2014-10-27 at 12:45 +0100, Marc-André Lureau wrote:
  Hi
  
  
  On Mon, Oct 27, 2014 at 9:08 AM, Gerd Hoffmann kra...@redhat.com
  wrote:
   +static void spice_chr_accept_input(struct CharDriverState
  *chr)
   +{
   +SpiceCharDriver *s = chr-opaque;
   +
   +spice_server_char_device_wakeup(s-sin);
  
  
  Does this build on older spice versions?  I'd suspect this
  needs #if
  SPICE_SERVER_VERSION too ...
  
  
  There is already a spice_server_char_device_wakeup() call there. On
  older servers, this additional call will trigger just a read try. With
  the proposed patch in Spice server, it will do read  write try (I
  didn't see the need to create a new function to do only read or write,
  both should be fine)
 
 Ok then.  Added to spice queue.  Fails to build, but that looks like
 just being the dependency on amits patch and should go away once that
 one is upstream.

The dependency patch is now in tree, please pick this series up.

Thanks,


Amit



Re: [Qemu-devel] [RFC PATCH 02/15] qdev: store DeviceState's canonical path to use when unparenting

2015-05-04 Thread Paolo Bonzini


On 02/05/2015 00:54, Michael Roth wrote:
  
  What about unparenting children devices in the device's unrealize
  callback?  It sucks that you have to do it manually, but using stale
  canonical paths isn't the nicest thing either.
 That does seems to do the trick. It felt wrong when I first looked at
 it because in some cases the children attach themselves to the parent
 without making making the parent aware,

Can you point to an example?  The parent owns its property namespace,
so it would be wrong for a child to attach itself unbeknownst to the parent.

There are a couple cases where an object adds a property to another
object, e.g. the rtc-time property of /machine, but in that case the
property is a well-known name whose setting is outsourced by /machine
to the device.

Paolo



Re: [Qemu-devel] [PATCH v2 3/3] TPM2 ACPI table support

2015-05-04 Thread Igor Mammedov
On Thu, 30 Apr 2015 22:44:08 -0400
Stefan Berger stef...@linux.vnet.ibm.com wrote:

 Add a TPM2 ACPI table if a TPM 2 is used in the backend.
 
 Rename tpm_find() to tpm_get_version() and have this function
 return the version of the TPM found, TPMVersion_Unspec if
 no TPM is found. Use the version number to build version
 specific ACPI tables.
 
 Signed-off-by: Stefan Berger stef...@linux.vnet.ibm.com
 ---
  hw/i386/acpi-build.c  | 34 ++
  hw/i386/acpi-defs.h   | 18 ++
  hw/tpm/tpm_tis.c  | 11 +++
  include/hw/acpi/tpm.h |  5 +
  include/sysemu/tpm.h  | 11 +--
  5 files changed, 73 insertions(+), 6 deletions(-)
 
 diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
 index e761005..fa64646 100644
 --- a/hw/i386/acpi-build.c
 +++ b/hw/i386/acpi-build.c
 @@ -42,6 +42,7 @@
  #include hw/acpi/memory_hotplug.h
  #include sysemu/tpm.h
  #include hw/acpi/tpm.h
 +#include sysemu/tpm_backend.h
  
  /* Supported chipsets: */
  #include hw/acpi/piix4.h
 @@ -111,7 +112,7 @@ typedef struct AcpiPmInfo {
  
  typedef struct AcpiMiscInfo {
  bool has_hpet;
 -bool has_tpm;
 +TPMVersion tpm_version;
  const unsigned char *dsdt_code;
  unsigned dsdt_size;
  uint16_t pvpanic_port;
 @@ -239,7 +240,7 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
  static void acpi_get_misc_info(AcpiMiscInfo *info)
  {
  info-has_hpet = hpet_find();
 -info-has_tpm = tpm_find();
 +info-tpm_version = tpm_get_version();
  info-pvpanic_port = pvpanic_port();
  info-applesmc_io_base = applesmc_port();
  }
 @@ -1065,6 +1066,21 @@ build_tpm_ssdt(GArray *table_data, GArray *linker)
  memcpy(tpm_ptr, ssdt_tpm_aml, sizeof(ssdt_tpm_aml));
  }
  
 +static void
 +build_tpm2(GArray *table_data, GArray *linker)
 +{
 +Acpi20TPM2 *tpm2_ptr;
 +
 +tpm2_ptr = acpi_data_push(table_data, sizeof *tpm2_ptr);
 +
 +tpm2_ptr-platform_class = cpu_to_le16(TPM2_ACPI_CLASS_CLIENT);
 +tpm2_ptr-control_area_address = cpu_to_le64(0);
 +tpm2_ptr-start_method = cpu_to_le32(TPM2_START_METHOD_MMIO);
 +
 +build_header(linker, table_data,
 + (void *)tpm2_ptr, TPM2, sizeof(*tpm2_ptr), 4);
 +}
 +
  typedef enum {
  MEM_AFFINITY_NOFLAGS  = 0,
  MEM_AFFINITY_ENABLED  = (1  0),
 @@ -1428,12 +1444,22 @@ void acpi_build(PcGuestInfo *guest_info, 
 AcpiBuildTables *tables)
  acpi_add_table(table_offsets, tables_blob);
  build_hpet(tables_blob, tables-linker);
  }
 -if (misc.has_tpm) {
 +if (misc.tpm_version != TPM_VERSION_UNSPEC) {
  acpi_add_table(table_offsets, tables_blob);
  build_tpm_tcpa(tables_blob, tables-linker, tables-tcpalog);
  
  acpi_add_table(table_offsets, tables_blob);
 -build_tpm_ssdt(tables_blob, tables-linker);
 +switch (misc.tpm_version) {
 +case TPM_VERSION_1_2:
 +build_tpm_ssdt(tables_blob, tables-linker);
 +break;
 +case TPM_VERSION_2_0:
 +build_tpm2(tables_blob, tables-linker);
 +break;
 +case TPM_VERSION_UNSPEC:
 +/* not possible */
 +break;
s/case TPM_VERSION_UNSPEC/default: +assert()/

 +}
  }
  if (guest_info-numa_nodes) {
  acpi_add_table(table_offsets, tables_blob);
 diff --git a/hw/i386/acpi-defs.h b/hw/i386/acpi-defs.h
 index c4468f8..79ee9b1 100644
 --- a/hw/i386/acpi-defs.h
 +++ b/hw/i386/acpi-defs.h
 @@ -316,6 +316,9 @@ typedef struct AcpiTableMcfg AcpiTableMcfg;
  
  /*
   * TCPA Description Table
 + *
 + * Following Level 00, Rev 00.37 of specs:
 + * http://www.trustedcomputinggroup.org/resources/tcg_acpi_specification
   */
  struct Acpi20Tcpa {
  ACPI_TABLE_HEADER_DEF/* ACPI common table header */
 @@ -325,6 +328,21 @@ struct Acpi20Tcpa {
  } QEMU_PACKED;
  typedef struct Acpi20Tcpa Acpi20Tcpa;
  
 +/*
 + * TPM2
 + *
 + * Following Level 00, Rev 00.37 of specs:
 + * http://www.trustedcomputinggroup.org/resources/tcg_acpi_specification
 + */
 +struct Acpi20TPM2 {
 +ACPI_TABLE_HEADER_DEF
 +uint16_t platform_class;
 +uint16_t reserved;
 +uint64_t control_area_address;
 +uint32_t start_method;
 +} QEMU_PACKED;
 +typedef struct Acpi20TPM2 Acpi20TPM2;
 +
  /* DMAR - DMA Remapping table r2.2 */
  struct AcpiTableDmar {
  ACPI_TABLE_HEADER_DEF
 diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
 index 636e6d3..be7e61f 100644
 --- a/hw/tpm/tpm_tis.c
 +++ b/hw/tpm/tpm_tis.c
 @@ -32,6 +32,7 @@
  #include tpm_tis.h
  #include qemu-common.h
  #include qemu/main-loop.h
 +#include sysemu/tpm_backend.h
  
  #define DEBUG_TIS 0
  
 @@ -963,6 +964,16 @@ static int tpm_tis_do_startup_tpm(TPMState *s)
  }
  
  /*
 + * Get the TPMVersion of the backend device being used
 + */
 +TPMVersion tpm_tis_get_tpm_version(Object *obj)
 +{
 +TPMState *s = TPM(obj);
 +
 +return tpm_backend_get_tpm_version(s-be_driver);
 +}
 +
 +/*
   * This function is called when the 

Re: [Qemu-devel] [PATCH] cpu: Register QOM links at /machine/cpus/index

2015-05-04 Thread Igor Mammedov
On Thu, 30 Apr 2015 16:19:07 -0300
Eduardo Habkost ehabk...@redhat.com wrote:

 This will provide a predictable path for the CPU objects, and a more
 powerful alternative for the query-cpus QMP command, as now every QOM
 property on CPU objects can be easily queried.
provided the way cpu_index is generated, path won't be predictable/stable
with CPU unplug. I'd rather use DEVICE-id instead of cpu_index.


 
 Signed-off-by: Eduardo Habkost ehabk...@redhat.com
 ---
 Note that this doesn't replace any future topology enumeration
 mechanisms we may choose to implement. It just replaces the existing
 topology-unaware VCPU enumeration mechanism that is query-cpus.
 
 Reference to previous discussion:
 
   Date: Thu, 23 Apr 2015 10:17:36 -0300
   From: Eduardo Habkost ehabk...@redhat.com
   Subject: Re: [Qemu-devel] cpu modelling and hotplug (was: [PATCH RFC 0/4] 
 target-i386: PC socket/core/thread modeling, part 1)
   Message-ID: 20150423131736.ga17...@thinpad.lan.raisama.net
 ---
  exec.c| 16 
  include/qom/cpu.h |  3 +++
  2 files changed, 19 insertions(+)
 
 diff --git a/exec.c b/exec.c
 index ae37b98..8bdfa65 100644
 --- a/exec.c
 +++ b/exec.c
 @@ -519,6 +519,20 @@ void tcg_cpu_address_space_init(CPUState *cpu, 
 AddressSpace *as)
  }
  #endif
  
 +static void cpu_add_qom_link(CPUState *cpu)
 +{
 +#if !defined(CONFIG_USER_ONLY)
 +Object *cobj = OBJECT(cpu);
 +Object *cpu_container = container_get(OBJECT(current_machine), /cpus);
 +char *path = g_strdup_printf(%d, cpu-cpu_index);
 +
 +cpu-self = cobj;
 +object_property_add_link(cpu_container, path, TYPE_CPU, cpu-self, NULL,
 + OBJ_PROP_LINK_UNREF_ON_RELEASE, error_abort);
 +g_free(path);
 +#endif
 +}
 +
  void cpu_exec_init(CPUArchState *env)
  {
  CPUState *cpu = ENV_GET_CPU(env);
 @@ -558,6 +572,8 @@ void cpu_exec_init(CPUArchState *env)
  if (cc-vmsd != NULL) {
  vmstate_register(NULL, cpu_index, cc-vmsd, cpu);
  }
 +
 +cpu_add_qom_link(cpu);
  }
  
  #if defined(CONFIG_USER_ONLY)
 diff --git a/include/qom/cpu.h b/include/qom/cpu.h
 index 39f0f19..c253420 100644
 --- a/include/qom/cpu.h
 +++ b/include/qom/cpu.h
 @@ -246,6 +246,9 @@ struct CPUState {
  DeviceState parent_obj;
  /* public */
  
 +/* Needed for the /machine/cpus/index link */
 +Object *self;
 +
  int nr_cores;
  int nr_threads;
  int numa_node;




Re: [Qemu-devel] [PATCH 2/2] balloon: add a feature bit to let Guest OS deflate balloon on oom

2015-05-04 Thread Denis V. Lunev

On 01/04/15 13:18, Michael S. Tsirkin wrote:

On Wed, Apr 01, 2015 at 12:51:42PM +0300, James Bottomley wrote:

On Wed, 2015-04-01 at 11:50 +0200, Michael S. Tsirkin wrote:

On Wed, Apr 01, 2015 at 12:44:28PM +0300, James Bottomley wrote:

On Fri, 2015-02-27 at 09:57 +0300, Denis V. Lunev wrote:

Excessive virtio_balloon inflation can cause invocation of OOM-killer,
when Linux is under severe memory pressure. Various mechanisms are
responsible for correct virtio_balloon memory management. Nevertheless it
is often the case that these control tools does not have enough time to
react on fast changing memory load. As a result OS runs out of memory and
invokes OOM-killer. The balancing of memory by use of the virtio balloon
should not cause the termination of processes while there are pages in the
balloon. Now there is no way for virtio balloon driver to free memory at
the last moment before some process get killed by OOM-killer.

This does not provide a security breach as balloon itself is running
inside Guest OS and is working in the cooperation with the host. Thus
some improvements from Guest side should be considered as normal.

To solve the problem, introduce a virtio_balloon callback which is
expected to be called from the oom notifier call chain in out_of_memory()
function. If virtio balloon could release some memory, it will make the
system return and retry the allocation that forced the out of memory
killer to run.

This behavior should be enabled if and only if appropriate feature bit
is set on the device. It is off by default.

This functionality was recently merged into vanilla Linux.

   commit 5a10b7dbf904bfe01bb9fcc6298f7df09eed77d5
   Author: Raushaniya Maksudova rmaksud...@parallels.com
   Date:   Mon Nov 10 09:36:29 2014 +1030

This patch adds respective control bits into QEMU. It introduces
deflate-on-oom option for balloon device which does the trick.

What's the status on this, please?  It's been over a month since this
was posted with no further review feedback, so I think it's ready.
Getting this into qemu is blocking our next step which would be adding
the feature bit to the virtio spec.

James

This was posted after soft feature freeze for 2.3, so it'll have to go
into 2.4.  I don't see why would this block your work on the spec: you
should make progress on this meanwhile.

I can do that ... I just thought the spec was trailing edge, so I was
waiting to have the patch accepted, which confirms the implementation.
I didn't want to write it into the spec and have the actual
implementation changed by review later.

James


It's up to you really, I would just like to point out two things:
- spec process is a long one, assuming we accept a spec change,
   we go though a public review period, multiple votes etc.
   About half a year to release a spec revision with
   new features.
   So time enough to make minor changes.
- oasis process works like this (roughly):
spec is written
spec goes through a public review process
community standard is published
3 implementations are reported
spec becomes an oasis standard
   so implementations aren't required at early stages

2.3 is done, 2.4 window is opened

The patch is applicable for both
git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git
and vanilla qemu.

How can we proceed?



Re: [Qemu-devel] [RFC 5/5] arm: Simplify cycle counter

2015-05-04 Thread Paolo Bonzini


On 01/05/2015 00:02, Peter Maydell wrote:
 On 30 April 2015 at 22:33, Christopher Covington
 christopher.coving...@linaro.org wrote:
 On Apr 30, 2015 2:28 PM, Peter Maydell peter.mayd...@linaro.org wrote:
 Are you really really sure the _raw function is the correct one?
 Nowhere else in the codebase calls it except the other wrappers
 in cpu.c which provide a sane view of the instruction count...
 (I suspect cpu_get_icount_raw() should really be static.)

 I thought it wasn't being used because it was new, having been introduced by
 Pavel Dovgalyuk's determinism patches.

 When you talk about sanity, what would this patch make insane?

The right function is cpu_get_ticks().  This one works without icount as
well.

At the top there is:

if (use_icount) {
return cpu_get_icount();
}

and perhaps it would be correct to use cpu_get_icount_raw() if you do
not want the cycle counter to increase in halted state.  But at least
x86 wants it to increase.

Paolo

 The
 instructions per second and cycles per second that would result? If so, what
 if seconds/timer ticks were changed in the same patch to be derived from the
 instruction count. All of this could potentially only apply with -icount
 specified.
 
 I don't really know for certain how the code here works, but
 it makes me very dubious when I see a function that is being
 used literally nowhere else in any other target CPU, and
 where every other code path to it goes via taking a lock.
 
 Paolo: can you suggest what the right function to call to implement
 a cycle counter is?
 
 thanks
 -- PMM
 



Re: [Qemu-devel] [PATCH v5 06/20] hw/arm/virt-acpi-build: Generation of DSDT table for virt devices

2015-05-04 Thread Igor Mammedov
On Wed, 15 Apr 2015 21:24:55 +0800
Shannon Zhao zhaoshengl...@huawei.com wrote:

 From: Shannon Zhao shannon.z...@linaro.org
 
 DSDT consists of the usual common table header plus a definition
 block in AML encoding which describes all devices in the platform.
 
 After initializing DSDT with header information the namespace is
 created which is followed by the device encodings. The devices are
 described using the Resource Template for the 32-Bit Fixed Memory
 Range and the Extended Interrupt Descriptors.
 
 Signed-off-by: Shannon Zhao zhaoshengl...@huawei.com
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  hw/arm/virt-acpi-build.c | 128 
 +++
  1 file changed, 128 insertions(+)
 
 diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
 index c5a3cf9..d044880 100644
 --- a/hw/arm/virt-acpi-build.c
 +++ b/hw/arm/virt-acpi-build.c
 @@ -50,6 +50,130 @@
  #include qom/qom-qobject.h
  #include exec/ram_addr.h
  
 +static void acpi_dsdt_add_cpus(Aml *scope, int max_cpus)
 +{
 +uint16_t i;
 +
 +for (i = 0; i  max_cpus; i++) {
 +Aml *dev = aml_device(C%03x, i);
 +aml_append(dev, aml_name_decl(_HID, aml_string(ACPI0007)));
 +aml_append(dev, aml_name_decl(_UID, aml_int(i)));
 +Aml *crs = aml_resource_template();
 +aml_append(dev, aml_name_decl(_CRS, crs));
 +aml_append(scope, dev);
 +}
 +}
Is maxcpus a correct here? Usually maxcpus includes non present CPUs
as well but there is no STA method that tells whether it's present or not.

 +
 +static void acpi_dsdt_add_uart(Aml *scope, const MemMap *uart_memmap,
 +   const int *uart_irq)
 +{
 +Aml *dev = aml_device(COM0);
 +aml_append(dev, aml_name_decl(_HID, aml_string(ARMH0011)));
 +aml_append(dev, aml_name_decl(_UID, aml_int(0)));
 +
 +Aml *crs = aml_resource_template();
 +aml_append(crs, aml_memory32_fixed(uart_memmap-addr,
 +   uart_memmap-size, aml_ReadWrite));
 +aml_append(crs,
 +   aml_interrupt(aml_consumer, aml_level, aml_active_high,
 +   aml_exclusive, aml_not_wake_capable, *uart_irq + 32));
 +aml_append(dev, aml_name_decl(_CRS, crs));
 +aml_append(scope, dev);
 +}
 +
 +static void acpi_dsdt_add_rtc(Aml *scope, const MemMap *rtc_memmap,
 +  const int *rtc_irq)
 +{
 +Aml *dev = aml_device(RTC0);
 +aml_append(dev, aml_name_decl(_HID, aml_string(LNRO0013)));
 +aml_append(dev, aml_name_decl(_UID, aml_int(0)));
 +
 +Aml *crs = aml_resource_template();
 +aml_append(crs, aml_memory32_fixed(rtc_memmap-addr,
 +   rtc_memmap-size, aml_ReadWrite));
 +aml_append(crs,
 +   aml_interrupt(aml_consumer, aml_level, aml_active_high,
 +   aml_exclusive, aml_not_wake_capable, *rtc_irq + 32));
 +aml_append(dev, aml_name_decl(_CRS, crs));
 +aml_append(scope, dev);
 +}
 +
 +static void acpi_dsdt_add_flash(Aml *scope, const MemMap *flash_memmap)
 +{
 +Aml *dev, *crs;
 +hwaddr base = flash_memmap-addr;
 +hwaddr size = flash_memmap-size;
 +
 +dev = aml_device(FLS0);
 +aml_append(dev, aml_name_decl(_HID, aml_string(LNRO0015)));
 +aml_append(dev, aml_name_decl(_UID, aml_int(0)));
 +
 +crs = aml_resource_template();
 +aml_append(crs, aml_memory32_fixed(base, size, aml_ReadWrite));
 +aml_append(dev, aml_name_decl(_CRS, crs));
 +aml_append(scope, dev);
 +
 +dev = aml_device(FLS1);
 +aml_append(dev, aml_name_decl(_HID, aml_string(LNRO0015)));
 +aml_append(dev, aml_name_decl(_UID, aml_int(1)));
 +crs = aml_resource_template();
 +aml_append(crs, aml_memory32_fixed(base + size, size, aml_ReadWrite));
 +aml_append(dev, aml_name_decl(_CRS, crs));
 +aml_append(scope, dev);
 +}
 +
 +static void acpi_dsdt_add_virtio(Aml *scope, const MemMap 
 *virtio_mmio_memmap,
 + const int *mmio_irq, int num)
 +{
 +hwaddr base = virtio_mmio_memmap-addr;
 +hwaddr size = virtio_mmio_memmap-size;
 +int irq = *mmio_irq + 32;
 +int i;
 +
 +for (i = 0; i  num; i++) {
 +Aml *dev = aml_device(VR%02u, i);
 +aml_append(dev, aml_name_decl(_HID, aml_string(LNRO0005)));
 +aml_append(dev, aml_name_decl(_UID, aml_int(i)));
 +
 +Aml *crs = aml_resource_template();
 +aml_append(crs, aml_memory32_fixed(base, size, aml_ReadWrite));
 +aml_append(crs,
 +   aml_interrupt(aml_consumer, aml_level, aml_active_high,
 +   aml_exclusive, aml_not_wake_capable, irq + i));
 +aml_append(dev, aml_name_decl(_CRS, crs));
 +aml_append(scope, dev);
 +base += size;
 +}
 +}
 +
 +/* DSDT */
 +static void
 +build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
 +{
 +Aml *scope, *dsdt;
 +AcpiDsdtInfo *info = 

Re: [Qemu-devel] [PATCH] cpu: Register QOM links at /machine/cpus/index

2015-05-04 Thread Paolo Bonzini


On 04/05/2015 11:47, Igor Mammedov wrote:
 On Thu, 30 Apr 2015 16:19:07 -0300
 Eduardo Habkost ehabk...@redhat.com wrote:
 
  This will provide a predictable path for the CPU objects, and a more
  powerful alternative for the query-cpus QMP command, as now every QOM
  property on CPU objects can be easily queried.
 
 provided the way cpu_index is generated, path won't be predictable/stable
 with CPU unplug. I'd rather use DEVICE-id instead of cpu_index.

Can we use the APIC id then?  Perhaps wrapped with a CPUState-level
method get_stable_processor_id()?

Paolo



[Qemu-devel] .gitignore contains .c and .h ?

2015-05-04 Thread Guillaume Le Louët

Hello.

The .gitignore in the master branch contains the following lines :
/qapi-types.[ch]
/qapi-visit.[ch]
/qapi-event.[ch]

Why is it so ? Are they generated automatically each time I compile the 
project ?

I am modifying qapi-types.h and qapi-types.c , am I doing wrong ?

regards, Guillaume



Re: [Qemu-devel] [PATCH v5 08/20] hw/arm/virt-acpi-build: Generate MADT table

2015-05-04 Thread Igor Mammedov
On Wed, 15 Apr 2015 21:24:57 +0800
Shannon Zhao zhaoshengl...@huawei.com wrote:

 From: Shannon Zhao shannon.z...@linaro.org
 
 MADT describes GIC enabled ARM platforms. The GICC and GICD
 subtables are used to define the GIC regions.
 
 Signed-off-by: Shannon Zhao zhaoshengl...@huawei.com
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 Reviewed-by: Alex Bennée alex.ben...@linaro.org
 ---
  hw/arm/virt-acpi-build.c | 61 
 
  include/hw/acpi/acpi-defs.h  | 38 -
  include/hw/arm/virt-acpi-build.h |  2 ++
  3 files changed, 100 insertions(+), 1 deletion(-)
 
 diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
 index c72a9c8..94cced0 100644
 --- a/hw/arm/virt-acpi-build.c
 +++ b/hw/arm/virt-acpi-build.c
 @@ -50,6 +50,20 @@
  #include qom/qom-qobject.h
  #include exec/ram_addr.h
  
 +typedef struct VirtAcpiCpuInfo {
 +DECLARE_BITMAP(found_cpus, VIRT_ACPI_CPU_ID_LIMIT);
 +} VirtAcpiCpuInfo;
 +
 +static void virt_acpi_get_cpu_info(VirtAcpiCpuInfo *cpuinfo)
 +{
 +CPUState *cpu;
 +
 +memset(cpuinfo-found_cpus, 0, sizeof cpuinfo-found_cpus);
 +CPU_FOREACH(cpu) {
 +set_bit(cpu-cpu_index, cpuinfo-found_cpus);
 +}
 +}
 +
  static void acpi_dsdt_add_cpus(Aml *scope, int max_cpus)
  {
  uint16_t i;
 @@ -146,6 +160,47 @@ static void acpi_dsdt_add_virtio(Aml *scope, const 
 MemMap *virtio_mmio_memmap,
  }
  }
  
 +/* MADT */
 +static void
 +build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
 +   VirtAcpiCpuInfo *cpuinfo)
 +{
 +int madt_start = table_data-len;
 +const struct AcpiMadtInfo *info = guest_info-madt_info;
 +AcpiMultipleApicTable *madt;
 +AcpiMadtGenericDistributor *gicd;
 +int i;
 +
 +madt = acpi_data_push(table_data, sizeof *madt);
 +madt-local_apic_address = info-gic_cpu_memmap-addr;
should be safe to drop this since OSPM must ignore this field if
gicc provides base_address.

 +madt-flags = cpu_to_le32(1);
is it correct?
Looking at 5.1 spec it's x86 specific PCAT_COMPAT flag,
why do you use it for ARM?

 +
 +for (i = 0; i  guest_info-max_cpus; i++) {
 +AcpiMadtGenericInterrupt *gicc = acpi_data_push(table_data,
 + sizeof *gicc);
 +gicc-type = ACPI_APIC_GENERIC_INTERRUPT;
 +gicc-length = sizeof(*gicc);
 +gicc-base_address = info-gic_cpu_memmap-addr;
 +gicc-cpu_interface_number = i;
 +gicc-arm_mpidr = i;
 +gicc-uid = i;
 +if (test_bit(i, cpuinfo-found_cpus)) {
 +gicc-flags = cpu_to_le32(1);
#define ACPI_GICC_ENABLED 1

 +} else {
 +gicc-flags = cpu_to_le32(0);
 +}
not necessary else clause, field is zeroed by default.

 +}
 +
 +gicd = acpi_data_push(table_data, sizeof *gicd);
 +gicd-type = ACPI_APIC_GENERIC_DISTRIBUTOR;
 +gicd-length = sizeof(*gicd);
 +gicd-base_address = info-gic_dist_memmap-addr;
 +
 +build_header(linker, table_data,
 + (void *)(table_data-data + madt_start), APIC,
 + table_data-len - madt_start, 1);
wrong revision?

 +}
 +
  /* FADT */
  static void
  build_fadt(GArray *table_data, GArray *linker, unsigned dsdt)
 @@ -215,8 +270,11 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
 AcpiBuildTables *tables)
  {
  GArray *table_offsets;
  unsigned dsdt;
 +VirtAcpiCpuInfo cpuinfo;
  GArray *tables_blob = tables-table_data;
  
 +virt_acpi_get_cpu_info(cpuinfo);
 +
  table_offsets = g_array_new(false, true /* clear */,
  sizeof(uint32_t));
  
 @@ -241,6 +299,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
 AcpiBuildTables *tables)
  acpi_add_table(table_offsets, tables_blob);
  build_fadt(tables_blob, tables-linker, dsdt);
  
 +acpi_add_table(table_offsets, tables_blob);
 +build_madt(tables_blob, tables-linker, guest_info, cpuinfo);
 +
  /* Cleanup memory that's no longer used. */
  g_array_free(table_offsets, true);
  }
 diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
 index bac981d..4092dc3 100644
 --- a/include/hw/acpi/acpi-defs.h
 +++ b/include/hw/acpi/acpi-defs.h
 @@ -236,7 +236,13 @@ typedef struct AcpiMultipleApicTable 
 AcpiMultipleApicTable;
  #define ACPI_APIC_IO_SAPIC   6
  #define ACPI_APIC_LOCAL_SAPIC7
  #define ACPI_APIC_XRUPT_SOURCE   8
 -#define ACPI_APIC_RESERVED   9   /* 9 and greater are 
 reserved */
 +#define ACPI_APIC_LOCAL_X2APIC   9
 +#define ACPI_APIC_LOCAL_X2APIC_NMI  10
 +#define ACPI_APIC_GENERIC_INTERRUPT 11
 +#define ACPI_APIC_GENERIC_DISTRIBUTOR   12
 +#define ACPI_APIC_GENERIC_MSI_FRAME 13
 +#define ACPI_APIC_GENERIC_REDISTRIBUTOR 14
 +#define ACPI_APIC_RESERVED  15   /* 15 and greater are reserved 
 */
  
  /*
   * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
 @@ 

Re: [Qemu-devel] [PATCH v5 13/20] hw/acpi/aml-build: Add ToUUID macro

2015-05-04 Thread Igor Mammedov
On Mon, 04 May 2015 17:30:20 +0800
Shannon Zhao shannon.z...@linaro.org wrote:

 
 
 On 2015/5/4 17:22, Igor Mammedov wrote:
  On Wed, 29 Apr 2015 21:41:39 +0800
  Shannon Zhao shannon.z...@linaro.org wrote:
  
 
 
  On 2015/4/28 17:48, Shannon Zhao wrote:
  On 2015/4/28 17:35, Igor Mammedov wrote:
  On Tue, 28 Apr 2015 16:52:19 +0800
  Shannon Zhao zhaoshengl...@huawei.com wrote:
 
  On 2015/4/28 16:15, Igor Mammedov wrote:
  btw:
  whole thing might be simpler if an intermediate conversion is 
  avoided,
  just pack buffer as in spec byte by byte:
 
  /* format: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp */
  assert(strlen(uuid) == ...);
  build_append_byte(var-buf, HEX2BYTE(uuid[3]); /* dd */
 
  use build_append_byte(var-buf, HEX2BYTE(uuid + 7); ?
 
  build_append_byte(var-buf, HEX2BYTE(uuid[2]); /* cc */
 
  use build_append_byte(var-buf, HEX2BYTE(uuid + 5); ?
  if you mean hyphens /-/ then they are not encoded,
  but you surely can add checks for them to make sure that
  UUID format is as expected.
 
 
  I mean uuid[3] points to b not dd. Maybe use following way:
 
  static uint8_t Hex2Byte(char *src)
  or even better:
  Hex2Byte(char *src, byte_idx)
 and do pointer arithmetic inside
 
  [...]
  build_append_byte(var-buf, Hex2Byte(uuid + (3 * 2))); /* dd */
  build_append_byte(var-buf, Hex2Byte(uuid, 3)); /* dd - at offset 00 */
  build_append_byte(var-buf, Hex2Byte(uuid, 2)); /* cc - at offset 01 */
  ...
 
  Yes, it's better to first four bytes. But there are hyphens /-/, for
  offset 04, 05 and etc it doesn't work. We can't use following expression:
 
  build_append_byte(var-buf, Hex2Byte(uuid, 5)); /* ff - at offset 04 */
  build_append_byte(var-buf, Hex2Byte(uuid, 4)); /* ee - at offset 05 */
  ...
 
 
 
  So about the implementation of this macro, I think I'd like to use 
  following approach. This lets Hex2Byte do what it should only do and 
  still has a clear look of UUID. What do you think about?
 
  static uint8_t Hex2Byte(char *src)
  {
   int hi = Hex2Digit(*src++);
   int lo = Hex2Digit(*src);
 
   if ((hi  0) || (lo  0))
   return -1;
  just make Hex2Digit() assert on wrong input.
  
 
 Ok.
 
 
   return (hi  4) | lo;
  }
 
  g_assert((strlen(uuid) == 36)  (uuid[8] == '-')  (uuid[13] == '-')
  (uuid[18] == '-')  (uuid[23] == '-'));
 
  build_append_byte(var-buf, Hex2Byte(uuid + (3 * 2))); /* dd */
 ^
  I'd make it one number, instead of forcing reader to do math
  every time he/she looks at this code.
  
 
 Ok, will do this. And about other patches in this series could you offer
 your comments?
the rest of AML patches looks good, I'll give them RB on next respin.

 
 Thanks,
 Shannon
 
  
  build_append_byte(var-buf, Hex2Byte(uuid + (2 * 2))); /* cc */
  build_append_byte(var-buf, Hex2Byte(uuid + (1 * 2))); /* bb */
  build_append_byte(var-buf, Hex2Byte(uuid + (0 * 2))); /* aa */
 
  build_append_byte(var-buf, Hex2Byte(uuid + (5 * 2 + 1))); /* ff */
  build_append_byte(var-buf, Hex2Byte(uuid + (4 * 2 + 1))); /* ee */
 
  build_append_byte(var-buf, Hex2Byte(uuid + (7 * 2 + 2))); /* hh */
  build_append_byte(var-buf, Hex2Byte(uuid + (6 * 2 + 2))); /* gg */
 
  build_append_byte(var-buf, Hex2Byte(uuid + (8 * 2 + 3))); /* ii */
  build_append_byte(var-buf, Hex2Byte(uuid + (9 * 2 + 3))); /* jj */
 
  build_append_byte(var-buf, Hex2Byte(uuid + (10 * 2 + 4))); /* kk */
  build_append_byte(var-buf, Hex2Byte(uuid + (11 * 2 + 4))); /* ll */
  build_append_byte(var-buf, Hex2Byte(uuid + (12 * 2 + 4))); /* mm */
  build_append_byte(var-buf, Hex2Byte(uuid + (13 * 2 + 4))); /* nn */
  build_append_byte(var-buf, Hex2Byte(uuid + (14 * 2 + 4))); /* oo */
  build_append_byte(var-buf, Hex2Byte(uuid + (15 * 2 + 4))); /* pp */
  
 




Re: [Qemu-devel] [Qemu-block] [PATCH 1/6] qcow2: use one single memory block for the L2/refcount cache tables

2015-05-04 Thread Kevin Wolf
Am 01.05.2015 um 16:23 hat Stefan Hajnoczi geschrieben:
 On Thu, Apr 30, 2015 at 01:11:40PM +0300, Alberto Garcia wrote:
   Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables)
   {
   BDRVQcowState *s = bs-opaque;
   Qcow2Cache *c;
  -int i;
   
   c = g_new0(Qcow2Cache, 1);
   c-size = num_tables;
  +c-table_size = s-cluster_size;
 
 This assumes c-table_size meets bs' memory alignment requirements.  The
 following would be safer:
 
 c-table_size = QEMU_ALIGN_UP(c-table_size, bdrv_opt_mem_align(bs-file));

You can't just access more than one cluster. You might be caching data
and later write it back when it's stale.

If you can't do I/O in chunks as small as the cluster size (which is
rather unlikely), relying on bdrv_pwrite(), like Berto's patch does, is
the correct solution.

Kevin


pgpj5Wnce450q.pgp
Description: PGP signature


Re: [Qemu-devel] .gitignore contains .c and .h ?

2015-05-04 Thread Thomas Huth
On Mon, 04 May 2015 09:47:11 +0200
Guillaume Le Louët guillaume.lelo...@gmail.com wrote:

 Hello.
 
 The .gitignore in the master branch contains the following lines :
 /qapi-types.[ch]
 /qapi-visit.[ch]
 /qapi-event.[ch]
 
 Why is it so ? Are they generated automatically each time I compile the 
 project ?
 I am modifying qapi-types.h and qapi-types.c , am I doing wrong ?

Yes, they are created automatically and you should not edit them
manually. Just have a look at the main Makefile:

qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
   $(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \
   $(SRC_PATH)/qapi/event.json

qapi-types.c qapi-types.h :\
$(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
$(gen-out-type) -o . -b -i $, \
  GEN   $@)

So if you want to change something in this area, you likely have to
touch the *.json files instead.

 Thomas



Re: [Qemu-devel] [PATCH 1/1] vl.c: Since the help says that 'disk_image' is a raw hard disk image, pass format=raw

2015-05-04 Thread Kevin Wolf
Am 01.05.2015 um 01:28 hat Don Slutz geschrieben:
 On 04/30/15 16:15, Kevin Wolf wrote:
  Am 30.04.2015 um 21:15 hat Eric Blake geschrieben:
  [adding qemu-block]
  
  On 04/30/2015 12:23 PM, Don Slutz wrote:
  ~/qemu/out/master/x86_64-softmmu/qemu-system-x86_64 -h | head 
  QEMU emulator version 2.3.50, Copyright (c) 2003-2008 Fabrice
  Bellard usage: qemu-system-x86_64 [options] [disk_image]
  
  'disk_image' is a raw hard disk image for IDE hard disk 0
  
  Standard options: ...
  
  Signed-off-by: Don Slutz dsl...@verizon.com --- vl.c | 3 ++- 
  1 file changed, 2 insertions(+), 1 deletion(-)
  
  Reviewed-by: Eric Blake ebl...@redhat.com
  
  Without this, qemu will try to probe formats.  It is  arguably is
  more convenient when using the shorthand of supplying a disk
  image to let qemu pick the format; but as the --help text says
  the image is raw, it's better to be explicit and avoid probing.
  Besides, we can always use longhand to specify actual format
  and/or probing if we don't like the shorthand.
  
  I don't think you can take an outdated help text as a justification
  for breaking backwards compatibility.
  
 
 Is this a hard no, soft no, or TBD?
 
 The following is what prompted this:
 
 WARNING: Image format was not specified for '/dev/etherd/e500.1' and
 probing guessed raw.
  Automatically detecting the format is dangerous for raw
 images, write operations on block 0 will be restricted.
  Specify the 'raw' format explicitly to remove the restrictions.
 
 
 which I would say also breaks backwards compatibility.

It doesn't, except if you consider an additional warning as breakage.

Only some corner cases that you probably wouldn't ever hit intentionally
changed their failure mode from 'image is opened in the wrong format
when restarting qemu' to 'write to sector 0 failed'.

If you don't hit the restrictions and you never specify the format
explicitly, you can just ignore the warning.

 However I do
 agree that this is the right change to have done.  However there
 currently is no way to specify that the 'disk_image' is raw.
 
 Also the old options (-hda, -hdb, -hdc, and -hdd) all have similar issues.

Yes, you need to use -drive for that currently.

 So do you want a more complex patch that allows the format to be
 specified?
 
 Only for 'disk_image'?
 
 Include -hd* ?

I'm afraid that there is no nice way to improve the plain 'disk_image'
case. You would have to add another option, and then it's not any better
than -hda and friends any more.

-hda in turn could be extended to take additional options (i.e. it
becomes something like -drive with implied index=0), but then there's
little reason not to use -drive.

We might actually want to extent -hd* at some point, but we would
probably use this as a chance to clean up the interface and remove
legacy options that -drive has to maintain for compatibility.

 Change the help message also?

Yes, this definitely. If the help message states that it's a raw image,
the help text is wrong.

Kevin



Re: [Qemu-devel] [PATCH v5 06/20] hw/arm/virt-acpi-build: Generation of DSDT table for virt devices

2015-05-04 Thread Shannon Zhao


On 2015/5/4 17:58, Igor Mammedov wrote:
 On Wed, 15 Apr 2015 21:24:55 +0800
 Shannon Zhao zhaoshengl...@huawei.com wrote:
 
 From: Shannon Zhao shannon.z...@linaro.org

 DSDT consists of the usual common table header plus a definition
 block in AML encoding which describes all devices in the platform.

 After initializing DSDT with header information the namespace is
 created which is followed by the device encodings. The devices are
 described using the Resource Template for the 32-Bit Fixed Memory
 Range and the Extended Interrupt Descriptors.

 Signed-off-by: Shannon Zhao zhaoshengl...@huawei.com
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 ---
  hw/arm/virt-acpi-build.c | 128 
 +++
  1 file changed, 128 insertions(+)

 diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
 index c5a3cf9..d044880 100644
 --- a/hw/arm/virt-acpi-build.c
 +++ b/hw/arm/virt-acpi-build.c
 @@ -50,6 +50,130 @@
  #include qom/qom-qobject.h
  #include exec/ram_addr.h
  
 +static void acpi_dsdt_add_cpus(Aml *scope, int max_cpus)
 +{
 +uint16_t i;
 +
 +for (i = 0; i  max_cpus; i++) {
 +Aml *dev = aml_device(C%03x, i);
 +aml_append(dev, aml_name_decl(_HID, aml_string(ACPI0007)));
 +aml_append(dev, aml_name_decl(_UID, aml_int(i)));
 +Aml *crs = aml_resource_template();
 +aml_append(dev, aml_name_decl(_CRS, crs));
 +aml_append(scope, dev);
 +}
 +}
 Is maxcpus a correct here? Usually maxcpus includes non present CPUs
 as well but there is no STA method that tells whether it's present or not.
 
5.2.12.14 GICC Structure
In the GICC interrupt model, logical processors are required to have a
Processor Device object in the DSDT

Here we create Processor Device object for all possible CPUs and in MADT
the gicc-flags tells whether it's present or not. And this flags is for
kernel booting initialization, not for dynamic configuration.

BTW, ARM doesn't support vCPU hotplug now. If we want to support hotplug
later, we should add _STA method for each Processor.

 +
 +static void acpi_dsdt_add_uart(Aml *scope, const MemMap *uart_memmap,
 +   const int *uart_irq)
 +{
 +Aml *dev = aml_device(COM0);
 +aml_append(dev, aml_name_decl(_HID, aml_string(ARMH0011)));
 +aml_append(dev, aml_name_decl(_UID, aml_int(0)));
 +
 +Aml *crs = aml_resource_template();
 +aml_append(crs, aml_memory32_fixed(uart_memmap-addr,
 +   uart_memmap-size, aml_ReadWrite));
 +aml_append(crs,
 +   aml_interrupt(aml_consumer, aml_level, aml_active_high,
 +   aml_exclusive, aml_not_wake_capable, *uart_irq + 32));
 +aml_append(dev, aml_name_decl(_CRS, crs));
 +aml_append(scope, dev);
 +}
 +
 +static void acpi_dsdt_add_rtc(Aml *scope, const MemMap *rtc_memmap,
 +  const int *rtc_irq)
 +{
 +Aml *dev = aml_device(RTC0);
 +aml_append(dev, aml_name_decl(_HID, aml_string(LNRO0013)));
 +aml_append(dev, aml_name_decl(_UID, aml_int(0)));
 +
 +Aml *crs = aml_resource_template();
 +aml_append(crs, aml_memory32_fixed(rtc_memmap-addr,
 +   rtc_memmap-size, aml_ReadWrite));
 +aml_append(crs,
 +   aml_interrupt(aml_consumer, aml_level, aml_active_high,
 +   aml_exclusive, aml_not_wake_capable, *rtc_irq + 32));
 +aml_append(dev, aml_name_decl(_CRS, crs));
 +aml_append(scope, dev);
 +}
 +
 +static void acpi_dsdt_add_flash(Aml *scope, const MemMap *flash_memmap)
 +{
 +Aml *dev, *crs;
 +hwaddr base = flash_memmap-addr;
 +hwaddr size = flash_memmap-size;
 +
 +dev = aml_device(FLS0);
 +aml_append(dev, aml_name_decl(_HID, aml_string(LNRO0015)));
 +aml_append(dev, aml_name_decl(_UID, aml_int(0)));
 +
 +crs = aml_resource_template();
 +aml_append(crs, aml_memory32_fixed(base, size, aml_ReadWrite));
 +aml_append(dev, aml_name_decl(_CRS, crs));
 +aml_append(scope, dev);
 +
 +dev = aml_device(FLS1);
 +aml_append(dev, aml_name_decl(_HID, aml_string(LNRO0015)));
 +aml_append(dev, aml_name_decl(_UID, aml_int(1)));
 +crs = aml_resource_template();
 +aml_append(crs, aml_memory32_fixed(base + size, size, aml_ReadWrite));
 +aml_append(dev, aml_name_decl(_CRS, crs));
 +aml_append(scope, dev);
 +}
 +
 +static void acpi_dsdt_add_virtio(Aml *scope, const MemMap 
 *virtio_mmio_memmap,
 + const int *mmio_irq, int num)
 +{
 +hwaddr base = virtio_mmio_memmap-addr;
 +hwaddr size = virtio_mmio_memmap-size;
 +int irq = *mmio_irq + 32;
 +int i;
 +
 +for (i = 0; i  num; i++) {
 +Aml *dev = aml_device(VR%02u, i);
 +aml_append(dev, aml_name_decl(_HID, aml_string(LNRO0005)));
 +aml_append(dev, aml_name_decl(_UID, aml_int(i)));
 +
 +Aml *crs = aml_resource_template();
 +

Re: [Qemu-devel] Comparison of virtual disks?

2015-05-04 Thread Max Reitz

On 03.05.2015 10:16, Erik Rull wrote:

Hi all,

is there a comparison chart of the different disk formats supported by 
QEMU? Especially throughput, latencies and robustness against 
unexpected power loss on the host would be interesting.


Thanks a lot.

Best regards,

Erik


Hi Erik,

I'm sorry, but I don't know whether such a chart exists (the closest 
thing I know is http://en.wikipedia.org/wiki/Category:Disk_images - 
which is not very close...). However, the general assumption we as 
developers are working with is that if the user's top priority is 
performance, they should use raw; and if they want to use all of the 
features qemu's block layer provides, they should use qcow2. All other 
formats are implemented merely for compatibility and ideally they should 
not be used for running VMs, but only for converting them to qcow2 using 
qemu-img convert.


Especially considering performance (throughput and latency), qcow2 will 
probably be the only format that we are really willing to work on. For 
the other drivers, the general idea is that reasonably fast is enough, 
but we probably won't go out of our way to make the implementations as 
fast as possible.


On the other hand, other formats may support special raw-like operating 
modes (e.g. vpc does), making them potentially automatically as fast as 
raw is, if configured appropriately.


Finally, there is robustness: raw will be as robust as it gets, because 
it should behave just like a real disk. For qcow2, we took special care 
to make sure the image will not be corrupted if qemu or the host crash. 
There are options like cache=unsafe and lazy-refcounts=on, which may 
corrupt the image in case of a crash, but at least the latter results in 
a special flag being set which makes qemu check and, if need be, repair 
the image the next time it is used. Speaking of checking and repairing, 
that's something that is only really implemented for qcow2, too. From 
what I can see, qed supports it, too; vdi and vmdk only support checking 
(I don't know how thorough it is); and vhdx has a journal which I guess 
means it is pretty safe against unexpected crashes, too.


We are trying to make all formats resistent against unexpected crashes 
(by flushing metadata whenever necessary), but I think it is safe to say 
here too we are paying special attention to qcow2.


So, all in all, raw is the format of choice if all you need is 
performance; if you do need features not offered by raw, qcow2 (the 
QEMU image format) is the recommended choice. Or, to quote qemu-img's 
manpage: For running VMs, it is recommended to convert the disk images 
to either raw or qcow2 in order to achieve good performance.


Again, sorry I don't have a full chart to present to you.

Max
Konsole output


Re: [Qemu-devel] [PATCH v5 08/20] hw/arm/virt-acpi-build: Generate MADT table

2015-05-04 Thread Shannon Zhao


On 2015/5/4 18:21, Igor Mammedov wrote:
 On Wed, 15 Apr 2015 21:24:57 +0800
 Shannon Zhao zhaoshengl...@huawei.com wrote:
 
 From: Shannon Zhao shannon.z...@linaro.org

 MADT describes GIC enabled ARM platforms. The GICC and GICD
 subtables are used to define the GIC regions.

 Signed-off-by: Shannon Zhao zhaoshengl...@huawei.com
 Signed-off-by: Shannon Zhao shannon.z...@linaro.org
 Reviewed-by: Alex Bennée alex.ben...@linaro.org
 ---
  hw/arm/virt-acpi-build.c | 61 
 
  include/hw/acpi/acpi-defs.h  | 38 -
  include/hw/arm/virt-acpi-build.h |  2 ++
  3 files changed, 100 insertions(+), 1 deletion(-)

 diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
 index c72a9c8..94cced0 100644
 --- a/hw/arm/virt-acpi-build.c
 +++ b/hw/arm/virt-acpi-build.c
 @@ -50,6 +50,20 @@
  #include qom/qom-qobject.h
  #include exec/ram_addr.h
  
 +typedef struct VirtAcpiCpuInfo {
 +DECLARE_BITMAP(found_cpus, VIRT_ACPI_CPU_ID_LIMIT);
 +} VirtAcpiCpuInfo;
 +
 +static void virt_acpi_get_cpu_info(VirtAcpiCpuInfo *cpuinfo)
 +{
 +CPUState *cpu;
 +
 +memset(cpuinfo-found_cpus, 0, sizeof cpuinfo-found_cpus);
 +CPU_FOREACH(cpu) {
 +set_bit(cpu-cpu_index, cpuinfo-found_cpus);
 +}
 +}
 +
  static void acpi_dsdt_add_cpus(Aml *scope, int max_cpus)
  {
  uint16_t i;
 @@ -146,6 +160,47 @@ static void acpi_dsdt_add_virtio(Aml *scope, const 
 MemMap *virtio_mmio_memmap,
  }
  }
  
 +/* MADT */
 +static void
 +build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
 +   VirtAcpiCpuInfo *cpuinfo)
 +{
 +int madt_start = table_data-len;
 +const struct AcpiMadtInfo *info = guest_info-madt_info;
 +AcpiMultipleApicTable *madt;
 +AcpiMadtGenericDistributor *gicd;
 +int i;
 +
 +madt = acpi_data_push(table_data, sizeof *madt);
 +madt-local_apic_address = info-gic_cpu_memmap-addr;
 should be safe to drop this since OSPM must ignore this field if
 gicc provides base_address.
 

Ok.
 +madt-flags = cpu_to_le32(1);
 is it correct?
 Looking at 5.1 spec it's x86 specific PCAT_COMPAT flag,
 why do you use it for ARM?
 

Oh, will fix. Thanks.

 +
 +for (i = 0; i  guest_info-max_cpus; i++) {
 +AcpiMadtGenericInterrupt *gicc = acpi_data_push(table_data,
 + sizeof *gicc);
 +gicc-type = ACPI_APIC_GENERIC_INTERRUPT;
 +gicc-length = sizeof(*gicc);
 +gicc-base_address = info-gic_cpu_memmap-addr;
 +gicc-cpu_interface_number = i;
 +gicc-arm_mpidr = i;
 +gicc-uid = i;
 +if (test_bit(i, cpuinfo-found_cpus)) {
 +gicc-flags = cpu_to_le32(1);
 #define ACPI_GICC_ENABLED 1
 
 +} else {
 +gicc-flags = cpu_to_le32(0);
 +}
 not necessary else clause, field is zeroed by default.
 

Ok, will remove.

 +}
 +
 +gicd = acpi_data_push(table_data, sizeof *gicd);
 +gicd-type = ACPI_APIC_GENERIC_DISTRIBUTOR;
 +gicd-length = sizeof(*gicd);
 +gicd-base_address = info-gic_dist_memmap-addr;
 +
 +build_header(linker, table_data,
 + (void *)(table_data-data + madt_start), APIC,
 + table_data-len - madt_start, 1);
 wrong revision?
 

Thanks, will fix this including other patches.

 +}
 +
  /* FADT */
  static void
  build_fadt(GArray *table_data, GArray *linker, unsigned dsdt)
 @@ -215,8 +270,11 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
 AcpiBuildTables *tables)
  {
  GArray *table_offsets;
  unsigned dsdt;
 +VirtAcpiCpuInfo cpuinfo;
  GArray *tables_blob = tables-table_data;
  
 +virt_acpi_get_cpu_info(cpuinfo);
 +
  table_offsets = g_array_new(false, true /* clear */,
  sizeof(uint32_t));
  
 @@ -241,6 +299,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
 AcpiBuildTables *tables)
  acpi_add_table(table_offsets, tables_blob);
  build_fadt(tables_blob, tables-linker, dsdt);
  
 +acpi_add_table(table_offsets, tables_blob);
 +build_madt(tables_blob, tables-linker, guest_info, cpuinfo);
 +
  /* Cleanup memory that's no longer used. */
  g_array_free(table_offsets, true);
  }
 diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
 index bac981d..4092dc3 100644
 --- a/include/hw/acpi/acpi-defs.h
 +++ b/include/hw/acpi/acpi-defs.h
 @@ -236,7 +236,13 @@ typedef struct AcpiMultipleApicTable 
 AcpiMultipleApicTable;
  #define ACPI_APIC_IO_SAPIC   6
  #define ACPI_APIC_LOCAL_SAPIC7
  #define ACPI_APIC_XRUPT_SOURCE   8
 -#define ACPI_APIC_RESERVED   9   /* 9 and greater are 
 reserved */
 +#define ACPI_APIC_LOCAL_X2APIC   9
 +#define ACPI_APIC_LOCAL_X2APIC_NMI  10
 +#define ACPI_APIC_GENERIC_INTERRUPT 11
 +#define ACPI_APIC_GENERIC_DISTRIBUTOR   12
 +#define ACPI_APIC_GENERIC_MSI_FRAME 13
 +#define ACPI_APIC_GENERIC_REDISTRIBUTOR 14
 +#define 

[Qemu-devel] [Bug 1450891] Re: VM will not resume on GlusterFS

2015-05-04 Thread Kevin Wolf
We can't just reopen files, we don't know what state they are in. Any
data that has been written to the image between the last flush and the
point where gluster made the fd invalid may be there or may be missing.
If any data is missing, we can't continue the guest or you'll get data
corruption.

The correct fix for resuming after I/O errors is on gluster. As long as
it invalidates the fd, without a way to resume, there is no way for qemu
to correctly continue after an error.

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

Title:
  VM will not resume on GlusterFS

Status in QEMU:
  New

Bug description:
  oVirt uses libvirt to run QEMU.
  Images are passed to QEMU as files, not file descriptors.
  When running images from a GlusterFS, the file descriptors may get 
invalidated because of network problems or the glusterfs process being 
restarted.
  In this case, the VM goes into paused state.
  When trying to resume the VM ('cont' command), QEMU uses the same invalidated 
file descriptors throwing a:
  block I/O error in device 'drive-virtio-disk0': Transport endpoint is not 
connected (107).

  Please check file-descriptors and reopen image file on 'cont' event in QEMU.
  Thanks.

  References:

  [1] http://lists.nongnu.org/archive/html/qemu-devel/2015-03/msg01269.html
  [2] https://bugzilla.redhat.com/show_bug.cgi?id=1058300

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



Re: [Qemu-devel] .gitignore contains .c and .h ?

2015-05-04 Thread Guillaume Le Louët
You're right, I noticed that compiling with make was removing my 
modifications.

I ended up modifying the qapi-schema.json .

May I advise to move the generated .c and .h files into a generated/ 
folder ?


Thank you Thomas.

Le 04/05/2015 13:01, Thomas Huth a écrit :

On Mon, 04 May 2015 09:47:11 +0200
Guillaume Le Louët guillaume.lelo...@gmail.com wrote:


Hello.

The .gitignore in the master branch contains the following lines :
/qapi-types.[ch]
/qapi-visit.[ch]
/qapi-event.[ch]

Why is it so ? Are they generated automatically each time I compile the
project ?
I am modifying qapi-types.h and qapi-types.c , am I doing wrong ?

Yes, they are created automatically and you should not edit them
manually. Just have a look at the main Makefile:

qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
$(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \
$(SRC_PATH)/qapi/event.json

qapi-types.c qapi-types.h :\
$(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
 $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
 $(gen-out-type) -o . -b -i $, \
   GEN   $@)

So if you want to change something in this area, you likely have to
touch the *.json files instead.

  Thomas





Re: [Qemu-devel] .gitignore contains .c and .h ?

2015-05-04 Thread Peter Maydell
On 4 May 2015 at 12:37, Guillaume Le Louët guillaume.lelo...@gmail.com wrote:
 You're right, I noticed that compiling with make was removing my
 modifications.
 I ended up modifying the qapi-schema.json .

 May I advise to move the generated .c and .h files into a generated/ folder
 ?

If you want to keep generated files out of your source tree
I would recommend using a separate build tree:
 mkdir build/whatever  (cd build/whatever  ../../configure [args here])
 make -C build/whatever

(You'll need to distclean your tree first if you've been doing
in-source-tree builds.)

-- PMM



Re: [Qemu-devel] [Qemu-block] [PATCH v3 3/9] libqos: Add migration helpers

2015-05-04 Thread Kevin Wolf
Am 30.04.2015 um 20:07 hat John Snow geschrieben:
 libqos.c:
 -set_context for addressing which commands go where
 -migrate performs the actual migration
 
 malloc.c:
 - Structure of the allocator is adjusted slightly with
   a second-tier malloc to make swapping around the allocators
   easy when we migrate the lists from the source to the destination.
 
 Signed-off-by: John Snow js...@redhat.com
 ---
  tests/libqos/libqos.c | 84 
 +++
  tests/libqos/libqos.h |  2 ++
  tests/libqos/malloc.c | 74 ++---
  tests/libqos/malloc.h |  1 +
  4 files changed, 144 insertions(+), 17 deletions(-)
 
 diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
 index 7e72078..ac1bae1 100644
 --- a/tests/libqos/libqos.c
 +++ b/tests/libqos/libqos.c
 @@ -1,5 +1,6 @@
  #include stdio.h
  #include stdlib.h
 +#include string.h
  #include glib.h
  #include unistd.h
  #include fcntl.h
 @@ -62,6 +63,89 @@ void qtest_shutdown(QOSState *qs)
  g_free(qs);
  }
  
 +void set_context(QOSState *s)
 +{
 +global_qtest = s-qts;
 +}
 +
 +static QDict *qmp_execute(const char *command)
 +{
 +char *fmt;
 +QDict *rsp;
 +
 +fmt = g_strdup_printf({ 'execute': '%s' }, command);
 +rsp = qmp(fmt);
 +g_free(fmt);
 +
 +return rsp;
 +}
 +
 +void migrate(QOSState *from, QOSState *to, const char *uri)
 +{
 +const char *st;
 +char *s;
 +QDict *rsp, *sub;
 +bool running;
 +
 +set_context(from);
 +
 +/* Is the machine currently running? */
 +rsp = qmp_execute(query-status);
 +g_assert(qdict_haskey(rsp, return));
 +sub = qdict_get_qdict(rsp, return);
 +g_assert(qdict_haskey(sub, running));
 +running = qdict_get_bool(sub, running);
 +QDECREF(rsp);
 +
 +/* Issue the migrate command. */
 +s = g_strdup_printf({ 'execute': 'migrate',
 +'arguments': { 'uri': '%s' } },
 +uri);
 +rsp = qmp(s);
 +g_free(s);
 +g_assert(qdict_haskey(rsp, return));
 +QDECREF(rsp);
 +
 +/* Wait for STOP event, but only if we were running: */
 +if (running) {
 +qmp_eventwait(STOP);
 +}
 +
 +/* If we were running, we can wait for an event. */
 +if (running) {
 +migrate_allocator(from-alloc, to-alloc);
 +set_context(to);
 +qmp_eventwait(RESUME);
 +return;
 +}
 +
 +/* Otherwise, we need to wait: poll until migration is completed. */
 +while (1) {
 +rsp = qmp_execute(query-migrate);
 +g_assert(qdict_haskey(rsp, return));
 +sub = qdict_get_qdict(rsp, return);
 +g_assert(qdict_haskey(sub, status));
 +st = qdict_get_str(sub, status);
 +
 +/* setup, active, completed, failed, cancelled */
 +if (strcmp(st, completed) == 0) {
 +QDECREF(rsp);
 +break;
 +}
 +
 +if ((strcmp(st, setup) == 0) || (strcmp(st, active) == 0)) {
 +QDECREF(rsp);
 +continue;

Wouldn't it be nicer to sleep a bit before retrying?

 +}
 +
 +fprintf(stderr, Migration did not complete, status: %s\n, st);
 +g_assert_not_reached();
 +}
 +
 +migrate_allocator(from-alloc, to-alloc);
 +set_context(to);
 +}

Kevin



[Qemu-devel] [PATCH] coverity: fix address_space_rw model

2015-05-04 Thread Paolo Bonzini
If the is_write argument is true, address_space_rw writes to memory
and thus reads from the buffer.  The opposite holds if is_write is
false.  Fix the model.

Cc: Markus Armbruster arm...@redhat.com
Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 scripts/coverity-model.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/scripts/coverity-model.c b/scripts/coverity-model.c
index 224d2d1..617f67d 100644
--- a/scripts/coverity-model.c
+++ b/scripts/coverity-model.c
@@ -49,7 +49,7 @@ typedef uint64_t hwaddr;
 typedef uint32_t MemTxResult;
 typedef uint64_t MemTxAttrs;
 
-static void __write(uint8_t *buf, ssize_t len)
+static void __bufwrite(uint8_t *buf, ssize_t len)
 {
 int first, last;
 __coverity_negative_sink__(len);
@@ -59,7 +59,7 @@ static void __write(uint8_t *buf, ssize_t len)
 __coverity_writeall__(buf);
 }
 
-static void __read(uint8_t *buf, ssize_t len)
+static void __bufread(uint8_t *buf, ssize_t len)
 {
 __coverity_negative_sink__(len);
 if (len == 0) return;
@@ -74,7 +74,7 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, 
MemTxAttrs attrs,
 
 // TODO: investigate impact of treating reads as producing
 // tainted data, with __coverity_tainted_data_argument__(buf).
-if (is_write) __write(buf, len); else __read(buf, len);
+if (is_write) __bufread(buf, len); else __bufwrite(buf, len);
 
 return result;
 }
-- 
2.3.5




[Qemu-devel] [PATCH v6 1/6] Qemu-Xen-vTPM: Support for Xen stubdom vTPM command line options

2015-05-04 Thread Quan Xu
Signed-off-by: Quan Xu quan...@intel.com

--Changes in v6:
 -Remove stray insertion.
---
 configure| 14 ++
 hmp.c|  2 ++
 qapi-schema.json | 16 ++--
 qemu-options.hx  | 13 +++--
 tpm.c|  7 ++-
 5 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/configure b/configure
index 09c9225..8c9411d 100755
--- a/configure
+++ b/configure
@@ -3010,6 +3010,16 @@ else
 fi
 
 ##
+# TPM xenstubdoms is only on x86 Linux
+
+if test $targetos = Linux  test $cpu = i386 -o $cpu = x86_64  \
+   test $xen = yes; then
+  tpm_xenstubdoms=$tpm
+else
+  tpm_xenstubdoms=no
+fi
+
+##
 # attr probe
 
 if test $attr != no ; then
@@ -4432,6 +4442,7 @@ echo gcov  $gcov_tool
 echo gcov enabled  $gcov
 echo TPM support   $tpm
 echo libssh2 support   $libssh2
+echo TPM xenstubdoms   $tpm_xenstubdoms
 echo TPM passthrough   $tpm_passthrough
 echo QOM debugging $qom_cast_debug
 echo vhdx  $vhdx
@@ -4919,6 +4930,9 @@ if test $tpm = yes; then
   if test $tpm_passthrough = yes; then
 echo CONFIG_TPM_PASSTHROUGH=y  $config_host_mak
   fi
+  if test $tpm_xenstubdoms = yes; then
+echo CONFIG_TPM_XENSTUBDOMS=y  $config_host_mak
+  fi
 fi
 
 echo TRACE_BACKENDS=$trace_backends  $config_host_mak
diff --git a/hmp.c b/hmp.c
index f31ae27..c10b6f7 100644
--- a/hmp.c
+++ b/hmp.c
@@ -813,6 +813,8 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
tpo-has_cancel_path ? ,cancel-path= : ,
tpo-has_cancel_path ? tpo-cancel_path : );
 break;
+case TPM_TYPE_OPTIONS_KIND_XENSTUBDOMS:
+break;
 case TPM_TYPE_OPTIONS_KIND_MAX:
 break;
 }
diff --git a/qapi-schema.json b/qapi-schema.json
index ac9594d..9bdb15e 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2975,9 +2975,11 @@
 #
 # @passthrough: TPM passthrough type
 #
+# @xenstubdoms: TPM xenstubdoms type (since 2.4)
+#
 # Since: 1.5
 ##
-{ 'enum': 'TpmType', 'data': [ 'passthrough' ] }
+{ 'enum': 'TpmType', 'data': [ 'passthrough', 'xenstubdoms' ] }
 
 ##
 # @query-tpm-types:
@@ -3006,6 +3008,15 @@
  '*cancel-path' : 'str'} }
 
 ##
+# @TPMXenstubdomsOptions:
+#
+# Information about the TPM xenstubdoms type
+#
+# Since: 2.4
+##
+{ 'type': 'TPMXenstubdomsOptions', 'data': {  } }
+
+##
 # @TpmTypeOptions:
 #
 # A union referencing different TPM backend types' configuration options
@@ -3015,7 +3026,8 @@
 # Since: 1.5
 ##
 { 'union': 'TpmTypeOptions',
-   'data': { 'passthrough' : 'TPMPassthroughOptions' } }
+  'data': { 'passthrough' : 'TPMPassthroughOptions',
+'xenstubdoms' : 'TPMXenstubdomsOptions' } }
 
 ##
 # @TpmInfo:
diff --git a/qemu-options.hx b/qemu-options.hx
index 319d971..9254902 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2539,7 +2539,8 @@ DEF(tpmdev, HAS_ARG, QEMU_OPTION_tpmdev, \
 -tpmdev passthrough,id=id[,path=path][,cancel-path=path]\n
 use path to provide path to a character device; default 
is /dev/tpm0\n
 use cancel-path to provide path to TPM's cancel sysfs 
entry; if\n
-not provided it will be searched for in 
/sys/class/misc/tpm?/device\n,
+not provided it will be searched for in 
/sys/class/misc/tpm?/device\n
+-tpmdev xenstubdoms,id=id\n,
 QEMU_ARCH_ALL)
 STEXI
 
@@ -2549,7 +2550,8 @@ The general form of a TPM device option is:
 @item -tpmdev @var{backend} ,id=@var{id} [,@var{options}]
 @findex -tpmdev
 Backend type must be:
-@option{passthrough}.
+@option{passthrough}, or
+@option{xenstubdoms}.
 
 The specific backend type will determine the applicable options.
 The @code{-tpmdev} option creates the TPM backend and requires a
@@ -2599,6 +2601,13 @@ To create a passthrough TPM use the following two 
options:
 Note that the @code{-tpmdev} id is @code{tpm0} and is referenced by
 @code{tpmdev=tpm0} in the device option.
 
+To create a xenstubdoms TPM use the following two options:
+@example
+-tpmdev xenstubdoms,id=tpm0 -device tpm-tis,tpmdev=tpm0
+@end example
+Note that the @code{-tpmdev} id is @code{tpm0} and is referenced by
+@code{tpmdev=tpm0} in the device option.
+
 @end table
 
 ETEXI
diff --git a/tpm.c b/tpm.c
index 963b7ee..30643fd 100644
--- a/tpm.c
+++ b/tpm.c
@@ -25,7 +25,7 @@ static QLIST_HEAD(, TPMBackend) tpm_backends =
 
 
 #define TPM_MAX_MODELS  1
-#define TPM_MAX_DRIVERS 1
+#define TPM_MAX_DRIVERS 2
 
 static TPMDriverOps const *be_drivers[TPM_MAX_DRIVERS] = {
 NULL,
@@ -254,6 +254,7 @@ static TPMInfo *qmp_query_tpm_inst(TPMBackend *drv)
 {
 TPMInfo *res = g_new0(TPMInfo, 1);
 TPMPassthroughOptions *tpo;
+TPMXenstubdomsOptions *txo;
 
 res-id = g_strdup(drv-id);
 res-model = drv-fe_model;
@@ -273,6 +274,10 @@ static TPMInfo *qmp_query_tpm_inst(TPMBackend *drv)
  

[Qemu-devel] [PATCH v6 0/6] QEMU:Xen stubdom vTPM for HVM virtual machine(QEMU Part)

2015-05-04 Thread Quan Xu
*INTRODUCTION*
The goal of virtual Trusted Platform Module (vTPM) is to provide a TPM 
functionality to virtual machines (Fedora, Ubuntu, Redhat, Windows .etc). This 
allows programs to interact with a TPM in a virtual machine the same way they 
interact with a TPM on the physical system. Each virtual machine gets its own 
unique, emulated, software TPM. Each major component of vTPM is implemented as 
a stubdom, providing secure separation guaranteed by the hypervisor.

The vTPM stubdom is a Xen mini-OS domain that emulates a TPM for the virtual 
machine to use. It is a small wrapper around the Berlios TPM emulator. TPM 
commands are passed from mini-os TPM backend driver.

*ARCHITECTURE*
The architecture of stubdom vTPM for HVM virtual machine:

++
| Windows/Linux DomU | ...
||  ^|
|v  ||
|  Qemu tpm1.2 Tis   |
||  ^|
|v  ||
| XenStubdoms backend|
++
 |  ^
 v  |
++
|  XenDevOps |
++
 |  ^
 v  |
++
|  mini-os/tpmback   |
||  ^|
|v  ||
|   vtpm-stubdom | ...
||  ^|
|v  ||
|  mini-os/tpmfront  |
++
 |  ^
 v  |
++
|  mini-os/tpmback   |
||  ^|
|v  ||
|  vtpmmgr-stubdom   |
||  ^|
|v  ||
|  mini-os/tpm_tis   |
++
 |  ^
 v  |
++
|Hardware TPM|
++

 * Windows/Linux DomU:
The HVM based guest that wants to use a vTPM. There may be
more than one of these.

 * Qemu tpm1.2 Tis:
Implementation of the tpm1.2 Tis interface for HVM virtual
machines. It is Qemu emulation device.

 * vTPM xenstubdoms driver:
Qemu vTPM driver. This driver provides vtpm initialization
and sending data and commends to a para-virtualized vtpm
stubdom.

 * XenDevOps:
Register Xen stubdom vTPM frontend driver, and transfer any
request/repond between TPM xenstubdoms driver and Xen vTPM
stubdom. Facilitate communications between Xen vTPM stubdom
and vTPM xenstubdoms driver.

 * mini-os/tpmback:
Mini-os TPM backend driver. The Linux frontend driver connects
to this backend driver to facilitate communications between the
Linux DomU and its vTPM. This driver is also used by vtpmmgr
stubdom to communicate with vtpm-stubdom.

 * vtpm-stubdom:
A mini-os stub domain that implements a vTPM. There is a
one to one mapping between running vtpm-stubdom instances and
logical vtpms on the system. The vTPM Platform Configuration
Registers (PCRs) are all initialized to zero.

 * mini-os/tpmfront:
Mini-os TPM frontend driver. The vTPM mini-os domain vtpm
stubdom uses this driver to communicate with vtpmmgr-stubdom.
This driver could also be used separately to implement a mini-os
domain that wishes to use a vTPM of its own.

 * vtpmmgr-stubdom:
A mini-os domain that implements the vTPM manager. There is only
one vTPM manager and it should be running during the entire lifetime
of the machine. vtpmmgr domain securely stores encryption keys for
each of the vtpms and accesses to the hardware TPM to get the root of
trust for the entire system.

 * mini-os/tpm_tis:
Mini-os TPM version 1.2 TPM Interface Specification (TIS) driver.
This driver used by vtpmmgr-stubdom to talk directly to the hardware
TPM. Communication is facilitated by mapping hardware memory pages
into vtpmmgr stubdom.

 * Hardware TPM: The physical TPM 1.2 that is soldered onto the motherboard.


--Changes in v6:
 -Add a parameter indicating whether the command that was a selftest,
  and whether it completed successfully.
 -Remove the redundant copy right.
 -Reduce the includes to its minimum.
 -Replace buf_size with PAGE_SIZE and use length rather than
  shr-length.
 -Remove stray insertion.

Quan Xu (6):
  Qemu-Xen-vTPM: Support for Xen stubdom vTPM command line options
  Qemu-Xen-vTPM: Xen frontend driver infrastructure
  Qemu-Xen-vTPM: Xen frontend driver infrastructure
  Qemu-Xen-vTPM: Move tpm_passthrough_is_selftest() into tpm_util.c
  Qemu-Xen-vTPM: Qemu vTPM xenstubdoms backen.
  Qemu-Xen-vTPM: QEMU machine class is initialized before tpm_init()

 configure|  14 ++
 hmp.c  

[Qemu-devel] [PATCH v6 4/6] Qemu-Xen-vTPM: Move tpm_passthrough_is_selftest() into tpm_util.c

2015-05-04 Thread Quan Xu
and rename it to tpm_util_is_selftest().

Signed-off-by: Quan Xu quan...@intel.com

--Changes in v6:
 -Remove the redundant copy right.
 -Reduce the includes to its minimum.
---
 hw/tpm/Makefile.objs |  2 +-
 hw/tpm/tpm_passthrough.c | 13 +
 hw/tpm/tpm_util.c| 39 +++
 include/sysemu/tpm_backend_int.h |  1 +
 4 files changed, 42 insertions(+), 13 deletions(-)
 create mode 100644 hw/tpm/tpm_util.c

diff --git a/hw/tpm/Makefile.objs b/hw/tpm/Makefile.objs
index 57919fa..e8fca65 100644
--- a/hw/tpm/Makefile.objs
+++ b/hw/tpm/Makefile.objs
@@ -1,3 +1,3 @@
-common-obj-$(CONFIG_TPM_TIS) += tpm_tis.o
+common-obj-$(CONFIG_TPM_TIS) += tpm_tis.o tpm_util.o
 common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
 common-obj-$(CONFIG_TPM_XENSTUBDOMS) += xen_vtpm_frontend.o
diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index 2a45071..ff08e15 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -112,17 +112,6 @@ static void tpm_write_fatal_error_response(uint8_t *out, 
uint32_t out_len)
 }
 }
 
-static bool tpm_passthrough_is_selftest(const uint8_t *in, uint32_t in_len)
-{
-struct tpm_req_hdr *hdr = (struct tpm_req_hdr *)in;
-
-if (in_len = sizeof(*hdr)) {
-return (be32_to_cpu(hdr-ordinal) == TPM_ORD_ContinueSelfTest);
-}
-
-return false;
-}
-
 static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
 const uint8_t *in, uint32_t in_len,
 uint8_t *out, uint32_t out_len,
@@ -136,7 +125,7 @@ static int tpm_passthrough_unix_tx_bufs(TPMPassthruState 
*tpm_pt,
 tpm_pt-tpm_executing = true;
 *selftest_done = false;
 
-is_selftest = tpm_passthrough_is_selftest(in, in_len);
+is_selftest = tpm_util_is_selftest(in, in_len);
 
 ret = tpm_passthrough_unix_write(tpm_pt-tpm_fd, in, in_len);
 if (ret != in_len) {
diff --git a/hw/tpm/tpm_util.c b/hw/tpm/tpm_util.c
new file mode 100644
index 000..73be8c5
--- /dev/null
+++ b/hw/tpm/tpm_util.c
@@ -0,0 +1,39 @@
+/*
+ *  TPM util functions
+ *
+ * *  Copyright (c) 2015 Intel Corporation
+ *  Authors:
+ *Quan Xu quan...@intel.com
+ *
+ *  Copyright (c) 2010 - 2013 IBM Corporation
+ *  Authors:
+ *Stefan Berger stef...@us.ibm.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see http://www.gnu.org/licenses/
+ */
+
+#include sysemu/tpm_backend.h
+#include tpm_int.h
+#include sysemu/tpm_backend_int.h
+
+bool tpm_util_is_selftest(const uint8_t *in, uint32_t in_len)
+{
+struct tpm_req_hdr *hdr = (struct tpm_req_hdr *)in;
+
+if (in_len = sizeof(*hdr)) {
+return (be32_to_cpu(hdr-ordinal) == TPM_ORD_ContinueSelfTest);
+}
+
+return false;
+}
diff --git a/include/sysemu/tpm_backend_int.h b/include/sysemu/tpm_backend_int.h
index 05d94d0..e18acab 100644
--- a/include/sysemu/tpm_backend_int.h
+++ b/include/sysemu/tpm_backend_int.h
@@ -34,6 +34,7 @@ void tpm_backend_thread_create(TPMBackendThread *tbt,
 void tpm_backend_thread_end(TPMBackendThread *tbt);
 void tpm_backend_thread_tpm_reset(TPMBackendThread *tbt,
   GFunc func, gpointer user_data);
+bool tpm_util_is_selftest(const uint8_t *in, uint32_t in_len);
 
 typedef enum TPMBackendCmd {
 TPM_BACKEND_CMD_INIT = 1,
-- 
1.8.3.2




[Qemu-devel] [PATCH v6 5/6] Qemu-Xen-vTPM: Qemu vTPM xenstubdoms backen.

2015-05-04 Thread Quan Xu
This Patch provides the glue for the TPM_TIS(Qemu frontend) to Xen
stubdom vTPM domain that provides the actual TPM functionality. It
sends data and TPM commends with xen_vtpm_frontend. It is similar as
another two vTPM backens:
  *vTPM passthrough backen Since QEMU 1.5.
  *vTPM libtpms-based backen.

Some details:
This part of the patch provides support for the spawning of a thread
that will interact with stubdom vTPM domain by the xen_vtpm_frontend.
It expects a signal from the frontend to wake and pick up the TPM
command that is supposed to be processed and delivers the response
packet using a callback function provided by the frontend.

The backend connects itself to the frontend by filling out an interface
structure with pointers to the function implementing support for various
operations.

(QEMU) vTPM XenStubdoms backen is initialized by Qemu command line options,
  -tpmdev xenstubdoms,id=xenvtpm0 -device tpm-tis,tpmdev=xenvtpm0

Signed-off-by: Quan Xu quan...@intel.com

--Changes in v6:
 -Add a parameter indicating whether the command that was a selftest,
  and whether it completed successfully.
---
 hw/tpm/Makefile.objs |   2 +-
 hw/tpm/tpm_xenstubdoms.c | 277 +++
 2 files changed, 278 insertions(+), 1 deletion(-)
 create mode 100644 hw/tpm/tpm_xenstubdoms.c

diff --git a/hw/tpm/Makefile.objs b/hw/tpm/Makefile.objs
index e8fca65..698b9e6 100644
--- a/hw/tpm/Makefile.objs
+++ b/hw/tpm/Makefile.objs
@@ -1,3 +1,3 @@
 common-obj-$(CONFIG_TPM_TIS) += tpm_tis.o tpm_util.o
 common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
-common-obj-$(CONFIG_TPM_XENSTUBDOMS) += xen_vtpm_frontend.o
+common-obj-$(CONFIG_TPM_XENSTUBDOMS) += xen_vtpm_frontend.o tpm_xenstubdoms.o
diff --git a/hw/tpm/tpm_xenstubdoms.c b/hw/tpm/tpm_xenstubdoms.c
new file mode 100644
index 000..f461323
--- /dev/null
+++ b/hw/tpm/tpm_xenstubdoms.c
@@ -0,0 +1,277 @@
+/*
+ * Xen Stubdom vTPM driver
+ *
+ *  Copyright (c) 2015 Intel Corporation
+ *  Authors:
+ *Quan Xu quan...@intel.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see http://www.gnu.org/licenses/
+ */
+
+#include dirent.h
+#include qemu-common.h
+#include qapi/error.h
+#include qemu/sockets.h
+#include qemu/log.h
+#include sysemu/tpm_backend.h
+#include tpm_int.h
+#include hw/hw.h
+#include hw/i386/pc.h
+#include hw/xen/xen_backend.h
+#include sysemu/tpm_backend_int.h
+#include tpm_tis.h
+
+#ifdef DEBUG_TPM
+#define DPRINTF(fmt, ...) \
+do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+do { } while (0)
+#endif
+
+#define TYPE_TPM_XENSTUBDOMS tpm-xenstubdoms
+#define TPM_XENSTUBDOMS(obj) \
+OBJECT_CHECK(TPMXenstubdomsState, (obj), TYPE_TPM_XENSTUBDOMS)
+
+static const TPMDriverOps tpm_xenstubdoms_driver;
+
+/* Data structures */
+typedef struct TPMXenstubdomsThreadParams {
+TPMState *tpm_state;
+TPMRecvDataCB *recv_data_callback;
+TPMBackend *tb;
+} TPMXenstubdomsThreadParams;
+
+struct TPMXenstubdomsState {
+TPMBackend parent;
+TPMBackendThread tbt;
+TPMXenstubdomsThreadParams tpm_thread_params;
+bool had_startup_error;
+};
+
+typedef struct TPMXenstubdomsState TPMXenstubdomsState;
+
+/* Functions */
+static void tpm_xenstubdoms_cancel_cmd(TPMBackend *tb);
+
+static int tpm_xenstubdoms_unix_transfer(const TPMLocality *locty_data,
+ bool *selftest_done)
+{
+size_t rlen;
+struct XenDevice *xendev;
+int ret;
+bool is_selftest;
+const struct tpm_resp_hdr *hdr;
+
+is_selftest = tpm_util_is_selftest(locty_data-w_buffer.buffer,
+   locty_data-w_buffer.size);
+
+xendev = xen_find_xendev(vtpm, xen_domid, xenstore_dev);
+if (xendev == NULL) {
+xen_be_printf(xendev, 0, Can not find vtpm device.\n);
+return -1;
+}
+
+ret = vtpm_send(xendev, locty_data-w_buffer.buffer,
+locty_data-w_offset);
+if (ret  0) {
+xen_be_printf(xendev, 0, Can not send vtpm command.\n);
+goto err_exit;
+}
+
+ret = vtpm_recv(xendev, locty_data-r_buffer.buffer, rlen);
+if (ret  0) {
+xen_be_printf(xendev, 0, vtpm reception command error.\n);
+goto err_exit;
+}
+
+if (is_selftest  (ret = sizeof(struct tpm_resp_hdr))) {
+hdr = (struct tpm_resp_hdr 

[Qemu-devel] [PATCH v6 2/6] Qemu-Xen-vTPM: Xen frontend driver infrastructure

2015-05-04 Thread Quan Xu
This patch adds infrastructure for xen front drivers living in qemu,
so drivers don't need to implement common stuff on their own.  It's
mostly xenbus management stuff: some functions to access XenStore,
setting up XenStore watches, callbacks on device discovery and state
changes, and handle event channel between the virtual machines.

Call xen_fe_register() function to register XenDevOps, and make sure,
XenDevOps's flags is DEVOPS_FLAG_FE, which is flag bit to point out
the XenDevOps is Xen frontend.

Create a new file xen_pvdev.c for some common part of xen frontend
and backend, such as xendevs queue and xenstore update functions.

Signed-off-by: Quan Xu quan...@intel.com
---
 hw/display/xenfb.c   |   4 +-
 hw/xen/Makefile.objs |   2 +-
 hw/xen/xen_backend.c | 353 ---
 hw/xen/xen_frontend.c| 345 +++
 hw/xen/xen_pvdev.c   | 481 +++
 include/hw/xen/xen_backend.h |  22 +-
 6 files changed, 850 insertions(+), 357 deletions(-)
 create mode 100644 hw/xen/xen_frontend.c
 create mode 100644 hw/xen/xen_pvdev.c

diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index 5e324ef..10751df 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -988,8 +988,8 @@ void xen_init_display(int domid)
 wait_more:
 i++;
 main_loop_wait(true);
-xfb = xen_be_find_xendev(vfb, domid, 0);
-xin = xen_be_find_xendev(vkbd, domid, 0);
+xfb = xen_find_xendev(vfb, domid, 0);
+xin = xen_find_xendev(vkbd, domid, 0);
 if (!xfb || !xin) {
 if (i  256) {
 usleep(1);
diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
index a0ca0aa..95eb9d0 100644
--- a/hw/xen/Makefile.objs
+++ b/hw/xen/Makefile.objs
@@ -1,5 +1,5 @@
 # xen backend driver support
-common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o
+common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o 
xen_frontend.o xen_pvdev.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_msi.o
diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
index b2cb22b..844f918 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen_backend.c
@@ -44,86 +44,11 @@
 /* - */
 
 /* public */
-XenXC xen_xc = XC_HANDLER_INITIAL_VALUE;
-struct xs_handle *xenstore = NULL;
 const char *xen_protocol;
 
 /* private */
-static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = 
QTAILQ_HEAD_INITIALIZER(xendevs);
 static int debug = 0;
 
-/* - */
-
-int xenstore_write_str(const char *base, const char *node, const char *val)
-{
-char abspath[XEN_BUFSIZE];
-
-snprintf(abspath, sizeof(abspath), %s/%s, base, node);
-if (!xs_write(xenstore, 0, abspath, val, strlen(val))) {
-return -1;
-}
-return 0;
-}
-
-char *xenstore_read_str(const char *base, const char *node)
-{
-char abspath[XEN_BUFSIZE];
-unsigned int len;
-char *str, *ret = NULL;
-
-snprintf(abspath, sizeof(abspath), %s/%s, base, node);
-str = xs_read(xenstore, 0, abspath, len);
-if (str != NULL) {
-/* move to qemu-allocated memory to make sure
- * callers can savely g_free() stuff. */
-ret = g_strdup(str);
-free(str);
-}
-return ret;
-}
-
-int xenstore_write_int(const char *base, const char *node, int ival)
-{
-char val[12];
-
-snprintf(val, sizeof(val), %d, ival);
-return xenstore_write_str(base, node, val);
-}
-
-int xenstore_write_int64(const char *base, const char *node, int64_t ival)
-{
-char val[21];
-
-snprintf(val, sizeof(val), %PRId64, ival);
-return xenstore_write_str(base, node, val);
-}
-
-int xenstore_read_int(const char *base, const char *node, int *ival)
-{
-char *val;
-int rc = -1;
-
-val = xenstore_read_str(base, node);
-if (val  1 == sscanf(val, %d, ival)) {
-rc = 0;
-}
-g_free(val);
-return rc;
-}
-
-int xenstore_read_uint64(const char *base, const char *node, uint64_t *uval)
-{
-char *val;
-int rc = -1;
-
-val = xenstore_read_str(base, node);
-if (val  1 == sscanf(val, %SCNu64, uval)) {
-rc = 0;
-}
-g_free(val);
-return rc;
-}
-
 int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const 
char *val)
 {
 return xenstore_write_str(xendev-be, node, val);
@@ -195,183 +120,6 @@ int xen_be_set_state(struct XenDevice *xendev, enum 
xenbus_state state)
 }
 
 /* - */
-
-struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev)
-{
-struct XenDevice *xendev;
-
-QTAILQ_FOREACH(xendev, xendevs, next) {
-if (xendev-dom != dom) {
-continue;
-}
-if (xendev-dev != dev) {
-continue;
-}
-if 

[Qemu-devel] [PATCH v6 3/6] Qemu-Xen-vTPM: Xen frontend driver infrastructure

2015-05-04 Thread Quan Xu
This patch adds infrastructure for xen front drivers living in qemu,
so drivers don't need to implement common stuff on their own.  It's
mostly xenbus management stuff: some functions to access XenStore,
setting up XenStore watches, callbacks on device discovery and state
changes, and handle event channel between the virtual machines.

Call xen_fe_register() function to register XenDevOps, and make sure,
 [...]
3 = 
 [...]
 device =  (frontend device, the backend is running in QEMU/.etc)
  vkbd = 
   [...]
  vif = 
   [...]

 ..

(QEMU) xen_vtpmdev_ops is initialized with the following process:
  xen_hvm_init()
[...]
--xen_fe_register(vtpm, ...)
  --xenstore_fe_scan()
--xen_fe_try_init(ops)
  -- XenDevOps.init()
--xen_fe_get_xendev()
  -- XenDevOps.alloc()
--xen_fe_check()
  --xen_fe_try_initialise()
-- XenDevOps.initialise()
  --xen_fe_try_connected()
-- XenDevOps.connected()
--xs_watch()
[...]

Signed-off-by: Quan Xu quan...@intel.com

--Changes in v6:
 -Replace buf_size with PAGE_SIZE and use length rather than
  shr-length.
---
 hw/tpm/Makefile.objs |   1 +
 hw/tpm/xen_vtpm_frontend.c   | 315 +++
 hw/xen/xen_frontend.c|  20 +++
 include/hw/xen/xen_backend.h |   5 +
 include/hw/xen/xen_common.h  |   6 +
 xen-hvm.c|   5 +
 6 files changed, 352 insertions(+)
 create mode 100644 hw/tpm/xen_vtpm_frontend.c

diff --git a/hw/tpm/Makefile.objs b/hw/tpm/Makefile.objs
index 99f5983..57919fa 100644
--- a/hw/tpm/Makefile.objs
+++ b/hw/tpm/Makefile.objs
@@ -1,2 +1,3 @@
 common-obj-$(CONFIG_TPM_TIS) += tpm_tis.o
 common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
+common-obj-$(CONFIG_TPM_XENSTUBDOMS) += xen_vtpm_frontend.o
diff --git a/hw/tpm/xen_vtpm_frontend.c b/hw/tpm/xen_vtpm_frontend.c
new file mode 100644
index 000..d6e7cc6
--- /dev/null
+++ b/hw/tpm/xen_vtpm_frontend.c
@@ -0,0 +1,315 @@
+/*
+ * Connect to Xen vTPM stubdom domain
+ *
+ *  Copyright (c) 2015 Intel Corporation
+ *  Authors:
+ *Quan Xu quan...@intel.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see http://www.gnu.org/licenses/
+ */
+
+#include stdio.h
+#include stdlib.h
+#include stdarg.h
+#include string.h
+#include unistd.h
+#include signal.h
+#include inttypes.h
+#include time.h
+#include fcntl.h
+#include errno.h
+#include sys/ioctl.h
+#include sys/types.h
+#include sys/stat.h
+#include sys/mman.h
+#include sys/uio.h
+
+#include hw/hw.h
+#include block/aio.h
+#include hw/xen/xen_backend.h
+
+#ifndef XS_STUBDOM_VTPM_ENABLE
+#define XS_STUBDOM_VTPM_ENABLE1
+#endif
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE  4096
+#endif
+
+enum tpmif_state {
+/* No contents, vTPM idle, cancel complete */
+TPMIF_STATE_IDLE,
+/* Request ready or vTPM working */
+TPMIF_STATE_SUBMIT,
+/* Response ready or vTPM idle */
+TPMIF_STATE_FINISH,
+/* Cancel requested or vTPM working */
+TPMIF_STATE_CANCEL,
+};
+
+static AioContext *vtpm_aio_ctx;
+
+enum status_bits {
+VTPM_STATUS_RUNNING  = 0x1,
+VTPM_STATUS_IDLE = 0x2,
+VTPM_STATUS_RESULT   = 0x4,
+VTPM_STATUS_CANCELED = 0x8,
+};
+
+struct tpmif_shared_page {
+/* Request and response length in bytes */
+uint32_t length;
+/* Enum tpmif_state */
+uint8_t  state;
+/* For the current request */
+uint8_t  locality;
+/* Should be zero */
+uint8_t  pad;
+/* Extra pages for long packets; may be zero */
+uint8_t  nr_extra_pages;
+/*
+ * Grant IDs, the length is actually nr_extra_pages.
+ * beyond the extra_pages entries is the actual request
+ * and response.
+ */
+uint32_t extra_pages[0];
+};
+
+struct xen_vtpm_dev {
+struct XenDevice xendev;  /* must be first */
+struct   tpmif_shared_page *shr;
+xc_gntshr*xen_xcs;
+int  ring_ref;
+int  bedomid;
+QEMUBH   *sr_bh;
+};
+
+static uint8_t vtpm_status(struct xen_vtpm_dev *vtpmdev)
+{
+switch (vtpmdev-shr-state) {
+case TPMIF_STATE_IDLE:
+case TPMIF_STATE_FINISH:
+return VTPM_STATUS_IDLE;
+case TPMIF_STATE_SUBMIT:
+case TPMIF_STATE_CANCEL:
+return VTPM_STATUS_RUNNING;
+default:
+return 0;
+}
+}
+
+static bool 

[Qemu-devel] [PATCH v6 6/6] Qemu-Xen-vTPM: QEMU machine class is initialized before tpm_init()

2015-05-04 Thread Quan Xu
make sure QEMU machine class is initialized and QEMU has registered
Xen stubdom vTPM driver when call tpm_init()

Signed-off-by: Quan Xu quan...@intel.com
Reviewed-by: Stefan Berger stef...@linux.vnet.ibm.com
---
 vl.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/vl.c b/vl.c
index 74c2681..7bc87f1 100644
--- a/vl.c
+++ b/vl.c
@@ -4131,12 +4131,6 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 }
 
-#ifdef CONFIG_TPM
-if (tpm_init()  0) {
-exit(1);
-}
-#endif
-
 /* init the bluetooth world */
 if (foreach_device_config(DEV_BT, bt_parse))
 exit(1);
@@ -4239,6 +4233,17 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 }
 
+/*
+ * For compatible with Xen stubdom vTPM driver, make
+ * sure QEMU machine class is initialized and QEMU has
+ * registered Xen stubdom vTPM driver.
+ */
+#ifdef CONFIG_TPM
+if (tpm_init()  0) {
+exit(1);
+}
+#endif
+
 /* init generic devices */
 if (qemu_opts_foreach(qemu_find_opts(device), device_init_func, NULL, 1) 
!= 0)
 exit(1);
-- 
1.8.3.2




Re: [Qemu-devel] Comparison of virtual disks?

2015-05-04 Thread Paolo Bonzini


On 04/05/2015 13:14, Max Reitz wrote:
 I'm sorry, but I don't know whether such a chart exists (the closest
 thing I know is http://en.wikipedia.org/wiki/Category:Disk_images -
 which is not very close...). However, the general assumption we as
 developers are working with is that if the user's top priority is
 performance, they should use raw; and if they want to use all of the
 features qemu's block layer provides, they should use qcow2. All other
 formats are implemented merely for compatibility and ideally they should
 not be used for running VMs, but only for converting them to qcow2 using
 qemu-img convert.

In addition to this, there are a bunch of image formats that have good
read performance: I can think of vhdx, vmdk, vdi.  These can be used as
backing images for qcow2, for example the virt-v2v tool uses this trick
to convert Hyper-V and VMware images without copying them first.

Paolo



Re: [Qemu-devel] [Qemu-block] [PATCH v3 0/9] ahci: enable migration

2015-05-04 Thread Kevin Wolf
Am 30.04.2015 um 20:07 hat John Snow geschrieben:
 The day we all feared is here, and I am proposing we allow the migration
 of the AHCI device tentatively for the 2.4 development window.
 
 There are some more NCQ migration tests are needed, but I felt that it was
 important to get migration enabled as close to the start of the 2.4
 development window as possible.
 
 If the NCQ patches don't pan out by the time the 2.4 freeze occurs, we can
 revert the migration boolean and add a conditional around the ahci tests
 that rely on the migration feature being enabled.
 
 I am justifying this checkin based on a series of ping-pong
 migration tests I ran under heavy load (using google's stressapptest)
 and saw over 300 successful migrations without a single failure.
 
 This series does a few things:
 (1) Add migration facilities to libqos
 (2) Enable AHCI and ICH9 migration
 (3) Add a series of migration tests to ahci-test

Reviewed-by: Kevin Wolf kw...@redhat.com

I think besides the NCQ tests, we'll definitely also want to test
migration with READ DMA in flight (this series tests only WRITE DMA and
FLUSH CACHE). Probably also discard.

Nice to have, but less important, would be the other variants that
exist, like the EXT version of each command, and READ/WRITE SECTOR.

But all of that can be added in a follow-up series, it's not a reason to
hold up what's already there.

Kevin



[Qemu-devel] [RFC v2 0/4] VFIO Platform device featuring IRQ forwarding

2015-05-04 Thread Eric Auger
This series adds IRQ forwarding support in the VFIO platform device.

The VFIO platform device uses the KVM-VFIO device to enable IRQ forwarding.

Dependency List:
- QEMU KVM platform device passthrough and its dependencies
  see https://lists.gnu.org/archive/html/qemu-devel/2015-04/msg04379.html
- kernel forwarding series:
  see (https://www.mail-archive.com/kvm@vger.kernel.org/msg115253.html)

Repos:
- QEMU pieces can be found at:
  http://git.linaro.org/people/eric.auger/qemu.git
  (branch vfio_integ_v15_fwd)
- kernel pieces can be found at:
  http://git.linaro.org/people/eric.auger/linux.git
  (branch 4.1-rc1_forward)

The patch series was tested on Calxeda Midway (ARMv7) where one xgmac
is assigned to KVM host while the second one is assigned to the guest.
Reworked PCI device is not tested.

Wiki for Calxeda Midway setup:
https://wiki.linaro.org/LEG/Engineering/Virtualization/Platform_Device_Passthrough_on_Midway

History:

v1 - v2:
- update following
  x introduction of kvm qemu_irq/gsi hash table
  x new irq connect notifier
  x 2 stage eventfd/irqfd setup which complexifies irq forwarding setup

v1:
- that code originally was in KVM platform device passthrough series (v8),
  now moved in a separate RFC since dependent on many RFCs.

Best Regards

Eric


Eric Auger (4):
  linux-headers: Update KVM header for KVM-VFIO FORWARD/UNFORWARD
  hw/vfio/common: vfio_kvm_device_fd moved in the common header
  kvm: add kvm_vfio_get_device_irq
  hw/vfio/platform: add forwarded irq support

 hw/vfio/common.c|   2 +-
 hw/vfio/platform.c  | 103 +---
 include/hw/vfio/vfio-common.h   |   4 ++
 include/hw/vfio/vfio-platform.h |   3 ++
 include/sysemu/kvm.h|   5 ++
 kvm-all.c   |  32 +
 linux-headers/linux/kvm.h   |  12 +
 trace-events|   1 +
 8 files changed, 154 insertions(+), 8 deletions(-)

-- 
1.8.3.2




[Qemu-devel] [RFC v2 3/4] kvm: add kvm_vfio_get_device_irq

2015-05-04 Thread Eric Auger
Since the introduction of the qemu_irq/gsi hash table in kvm,
the gsi information is stored in kvm. New functions are introduced
to allocate/populate a kvm_vfio_dev_irq struct pointer from a
qemu_irq object and free it.

Signed-off-by: Eric Auger eric.au...@linaro.org
---
 include/sysemu/kvm.h |  5 +
 kvm-all.c| 32 
 2 files changed, 37 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index bc3f230..42cc6c4 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -423,6 +423,11 @@ int kvm_irqchip_add_irqfd_notifier(KVMState *s, 
EventNotifier *n,
 int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n,
   qemu_irq irq);
 void kvm_irqchip_set_qemuirq_gsi(KVMState *s, qemu_irq irq, int gsi);
+struct kvm_vfio_dev_irq;
+int kvm_vfio_get_device_irq(KVMState *s, int fd, int index,
+int start, int count, qemu_irq irq,
+struct kvm_vfio_dev_irq **vfio_dev_irq);
+void kvm_vfio_put_device_irq(struct kvm_vfio_dev_irq *vfio_dev_irq);
 void kvm_pc_gsi_handler(void *opaque, int n, int level);
 void kvm_pc_setup_irq_routing(bool pci_enabled);
 void kvm_init_irq_routing(KVMState *s);
diff --git a/kvm-all.c b/kvm-all.c
index d2cb7ed..83a9689 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1454,6 +1454,38 @@ static int kvm_irqchip_create(MachineState *machine, 
KVMState *s)
 return 0;
 }
 
+int kvm_vfio_get_device_irq(KVMState *s, int fd, int index,
+int start, int count, qemu_irq irq,
+struct kvm_vfio_dev_irq **vfio_dev_irq)
+{
+gpointer key, gsi;
+gboolean found = g_hash_table_lookup_extended(s-gsimap, irq, key, gsi);
+struct kvm_vfio_dev_irq *pirq;
+__u32 *pgsi;
+int argsz;
+
+if (!found) {
+return -ENXIO;
+}
+
+argsz = sizeof(*pirq) + sizeof(*pgsi);
+pirq = g_malloc0(argsz);
+pirq-argsz = argsz;
+pirq-fd = fd;
+pirq-index = index;
+pirq-start = start;
+pirq-count = count;
+pgsi = (__u32 *)pirq-gsi;
+*pgsi = GPOINTER_TO_INT(gsi);
+*vfio_dev_irq = pirq;
+return 0;
+}
+
+void kvm_vfio_put_device_irq(struct kvm_vfio_dev_irq *vfio_dev_irq)
+{
+g_free(vfio_dev_irq);
+}
+
 /* Find number of supported CPUs using the recommended
  * procedure from the kernel API documentation to cope with
  * older kernels that may be missing capabilities.
-- 
1.8.3.2




[Qemu-devel] [RFC v2 4/4] hw/vfio/platform: add forwarded irq support

2015-05-04 Thread Eric Auger
Tests whether the forwarded IRQ modality is available.
In the positive device IRQs are forwarded. This control is
achieved with KVM-VFIO device. with such a modality injection
still is handled through irqfds. However end of interrupt is
not trapped anymore. As soon as the guest completes its virtual
IRQ, the corresponding physical IRQ is completed and the same
physical IRQ can hit again.

A new x-forward property enables to force forwarding off although
enabled by the kernel.

Signed-off-by: Eric Auger eric.au...@linaro.org

---

v1 - v2:
- use kvm_vfio_get|put_device_irq, new irq connect notifier and
  integrate with 2 stage eventfd/irqfd setup

v1:
- moved in a separate series

v8 - v9 (KVM platform device passthrough series):
- use new kvm_vfio_dev_irq struct

Signed-off-by: Eric Auger eric.au...@linaro.org
---
 hw/vfio/platform.c  | 103 +---
 include/hw/vfio/vfio-platform.h |   3 ++
 trace-events|   1 +
 3 files changed, 100 insertions(+), 7 deletions(-)

diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
index 901b98e..52c6d59 100644
--- a/hw/vfio/platform.c
+++ b/hw/vfio/platform.c
@@ -411,6 +411,88 @@ fail_irqfd:
 return;
 }
 
+/*
+ * Functions used with forwarding capability
+ */
+
+static bool has_kvm_vfio_forward_capability(void)
+{
+struct kvm_device_attr attr = {
+ .group = KVM_DEV_VFIO_DEVICE,
+ .attr = KVM_DEV_VFIO_DEVICE_FORWARD_IRQ};
+
+if (ioctl(vfio_kvm_device_fd, KVM_HAS_DEVICE_ATTR, attr) == 0) {
+return true;
+} else {
+return false;
+}
+}
+
+static void vfio_start_forward_injection(SysBusDevice *sbdev, qemu_irq irq)
+{
+VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
+VFIOINTp *intp;
+bool found = false;
+struct kvm_device_attr attr = {
+ .group = KVM_DEV_VFIO_DEVICE,
+ .attr = KVM_DEV_VFIO_DEVICE_FORWARD_IRQ};
+
+QLIST_FOREACH(intp, vdev-intp_list, next) {
+if (intp-qemuirq == irq) {
+found  = true;
+break;
+}
+}
+assert(found);
+
+if (intp-forwarded) {
+return;
+}
+
+/*
+ * stop VFIO signaling and unmask the physical IRQ since
+ * forwarding cannot be set if the IRQ is active or vfio masked
+ */
+vfio_disable_irqindex(intp-vdev-vbasedev, intp-pin);
+vfio_unmask_single_irqindex(intp-vdev-vbasedev, intp-pin);
+
+kvm_vfio_get_device_irq(kvm_state, intp-vdev-vbasedev.fd,
+intp-pin, 0, 1, intp-qemuirq, intp-fwd_irq);
+
+attr.addr = (uint64_t)(unsigned long)intp-fwd_irq;
+
+if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, attr)  0) {
+error_report(vfio: failed to forward irq %d, do standard irqfd,
+ intp-pin);
+kvm_vfio_put_device_irq(intp-fwd_irq);
+} else {
+trace_vfio_platform_start_fwd_injection(intp-pin);
+intp-forwarded = true;
+}
+
+if (kvm_irqchip_add_irqfd_notifier(kvm_state, intp-interrupt,
+   intp-unmask, irq)  0) {
+goto fail_irqfd;
+}
+
+if (vfio_set_trigger_eventfd(intp, NULL)  0) {
+goto fail_vfio;
+}
+/* only used if forwarding setup failed */
+if (vfio_set_resample_eventfd(intp)  0) {
+goto fail_vfio;
+}
+
+intp-kvm_accel = true;
+return;
+fail_vfio:
+kvm_irqchip_remove_irqfd_notifier(kvm_state, intp-interrupt, irq);
+fail_irqfd:
+vfio_start_eventfd_injection(intp);
+vfio_unmask_single_irqindex(vdev-vbasedev, intp-pin);
+return;
+}
+
 #endif /* CONFIG_KVM */
 
 /* VFIO skeleton */
@@ -655,13 +737,6 @@ static void vfio_platform_realize(DeviceState *dev, Error 
**errp)
 vbasedev-type = VFIO_DEVICE_TYPE_PLATFORM;
 vbasedev-ops = vfio_platform_ops;
 
-#ifdef CONFIG_KVM
-if (kvm_irqfds_enabled()  kvm_resamplefds_enabled() 
-vdev-irqfd_allowed) {
-sbc-connect_irq_notifier = vfio_start_irqfd_injection;
-}
-#endif
-
 trace_vfio_platform_realize(vbasedev-name, vdev-compat);
 
 ret = vfio_base_device_init(vbasedev);
@@ -679,6 +754,19 @@ static void vfio_platform_realize(DeviceState *dev, Error 
**errp)
 QLIST_FOREACH(intp, vdev-intp_list, next) {
 vfio_start_eventfd_injection(intp);
 }
+
+#ifdef CONFIG_KVM
+if (kvm_irqfds_enabled()  kvm_resamplefds_enabled() 
+vdev-irqfd_allowed) {
+if (has_kvm_vfio_forward_capability() 
+ vdev-forward_allowed) {
+sbc-connect_irq_notifier = vfio_start_forward_injection;
+} else {
+sbc-connect_irq_notifier = vfio_start_irqfd_injection;
+}
+}
+#endif
+
 }
 
 static const VMStateDescription vfio_platform_vmstate = {
@@ -692,6 +780,7 @@ static Property vfio_platform_dev_properties[] = {
 DEFINE_PROP_UINT32(mmap-timeout-ms, VFIOPlatformDevice,
mmap_timeout, 1100),
 DEFINE_PROP_BOOL(x-irqfd, VFIOPlatformDevice, irqfd_allowed, true),

[Qemu-devel] [RFC v2 1/4] linux-headers: Update KVM header for KVM-VFIO FORWARD/UNFORWARD

2015-05-04 Thread Eric Auger
Integrate updated KVM-VFIO API related to forwarded IRQ

Update the kvm header according to the header found in
http://git.linaro.org/people/eric.auger/linux.git
branch 4.1-rc1_forward

Signed-off-by: Eric Auger eric.au...@linaro.org
---
 linux-headers/linux/kvm.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index b96d978..95fea92 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -999,6 +999,9 @@ struct kvm_device_attr {
 #define  KVM_DEV_VFIO_GROUP1
 #define   KVM_DEV_VFIO_GROUP_ADD   1
 #define   KVM_DEV_VFIO_GROUP_DEL   2
+#define  KVM_DEV_VFIO_DEVICE   2
+#define   KVM_DEV_VFIO_DEVICE_FORWARD_IRQ  1
+#define   KVM_DEV_VFIO_DEVICE_UNFORWARD_IRQ2
 
 enum kvm_device_type {
KVM_DEV_TYPE_FSL_MPIC_20= 1,
@@ -1018,6 +1021,15 @@ enum kvm_device_type {
KVM_DEV_TYPE_MAX,
 };
 
+struct kvm_vfio_dev_irq {
+   __u32   argsz;  /* structure length */
+   __u32   fd; /* file descriptor of the VFIO device */
+   __u32   index;  /* VFIO device IRQ index */
+   __u32   start;  /* start of subindex range */
+   __u32   count;  /* size of subindex range */
+   __u32   gsi[];  /* gsi, ie. virtual IRQ number */
+};
+
 /*
  * ioctls for VM fds
  */
-- 
1.8.3.2




[Qemu-devel] [RFC v2 2/4] hw/vfio/common: vfio_kvm_device_fd moved in the common header

2015-05-04 Thread Eric Auger
the device is now used in platform for forwarded IRQ setup

Signed-off-by: Eric Auger eric.au...@linaro.org
---
 hw/vfio/common.c  | 2 +-
 include/hw/vfio/vfio-common.h | 4 
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index b012620..18ad67c 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -44,7 +44,7 @@ struct vfio_as_head vfio_address_spaces =
  * initialized, this file descriptor is only released on QEMU exit and
  * we'll re-use it should another vfio device be attached before then.
  */
-static int vfio_kvm_device_fd = -1;
+int vfio_kvm_device_fd = -1;
 #endif
 
 /*
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 59a321d..53d0e68 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -40,6 +40,10 @@
 #define VFIO_ALLOW_KVM_MSI 1
 #define VFIO_ALLOW_KVM_MSIX 1
 
+#ifdef CONFIG_KVM
+extern int vfio_kvm_device_fd;
+#endif
+
 enum {
 VFIO_DEVICE_TYPE_PCI = 0,
 VFIO_DEVICE_TYPE_PLATFORM = 1,
-- 
1.8.3.2




Re: [Qemu-devel] [PATCH v6 3/6] Qemu-Xen-vTPM: Xen frontend driver infrastructure

2015-05-04 Thread Xu, Quan
I find out the subject is wrong in v5/v6. Just update the subject as below. 

Subject: [PATCH v6 3/6] Qemu-Xen-vTPM: Register Xen stubdom vTPM frontend
 driver

This drvier transfers any request/repond between TPM xenstubdoms
driver and Xen vTPM stubdom, and facilitates communications between
Xen vTPM stubdom domain and vTPM xenstubdoms driver. It is a glue for
the TPM xenstubdoms driver and Xen stubdom vTPM domain that provides
the actual TPM functionality.

(Xen) Xen backend driver should run before running this frontend, and
initialize XenStore as the following for communication.

[XenStore]

for example:

Domain 0: runs QEMU for guest A
Domain 1: vtpmmgr
Domain 2: vTPM for guest A
Domain 3: HVM guest A

[...]
 local = 
   domain = 
0 = 
 frontend = 
  vtpm = 
   2 = 
0 = 
 backend = /local/domain/2/backend/vtpm/0/0
 backend-id = 2
 state = *
 handle = 0
 domain = Domain3's name
 ring-ref = *
 event-channel = *
 feature-protocol-v2 = 1
 backend = 
  qdisk = 
   [...]
  console = 
  vif = 
   [...]
2 = 
 [...]
 backend = 
  vtpm = 
   0 = 
0 = 
 frontend = /local/domain/0/frontend/vtpm/2/0
 frontend-id = 0 ('0', frontend is running in Domain-0)
 [...]
3 = 
 [...]
 device =  (frontend device, the backend is running in QEMU/.etc)
  vkbd = 
   [...]
  vif = 
   [...]

 ..

(QEMU) xen_vtpmdev_ops is initialized with the following process:
  xen_hvm_init()
[...]
--xen_fe_register(vtpm, ...)
  --xenstore_fe_scan()
--xen_fe_try_init(ops)
  -- XenDevOps.init()
--xen_fe_get_xendev()
  -- XenDevOps.alloc()
--xen_fe_check()
  --xen_fe_try_initialise()
-- XenDevOps.initialise()
  --xen_fe_try_connected()
-- XenDevOps.connected()
--xs_watch()
[...]

-Quan

 -Original Message-
 From: Xu, Quan
 Sent: Monday, May 04, 2015 3:23 PM
 To: stefano.stabell...@eu.citrix.com; stef...@linux.vnet.ibm.com;
 ebl...@redhat.com
 Cc: qemu-devel@nongnu.org; wei.l...@citrix.com; dgde...@tycho.nsa.gov;
 xen-de...@lists.xen.org; Xu, Quan
 Subject: [PATCH v6 3/6] Qemu-Xen-vTPM: Xen frontend driver infrastructure
 
 This patch adds infrastructure for xen front drivers living in qemu, so 
 drivers don't
 need to implement common stuff on their own.  It's mostly xenbus
 management stuff: some functions to access XenStore, setting up XenStore
 watches, callbacks on device discovery and state changes, and handle event
 channel between the virtual machines.
 
 Call xen_fe_register() function to register XenDevOps, and make sure,
  [...]
 3 = 
  [...]
  device =  (frontend device, the backend is running in QEMU/.etc)
   vkbd = 
[...]
   vif = 
[...]
 
  ..
 
 (QEMU) xen_vtpmdev_ops is initialized with the following process:
   xen_hvm_init()
 [...]
 --xen_fe_register(vtpm, ...)
   --xenstore_fe_scan()
 --xen_fe_try_init(ops)
   -- XenDevOps.init()
 --xen_fe_get_xendev()
   -- XenDevOps.alloc()
 --xen_fe_check()
   --xen_fe_try_initialise()
 -- XenDevOps.initialise()
   --xen_fe_try_connected()
 -- XenDevOps.connected()
 --xs_watch()
 [...]
 
 Signed-off-by: Quan Xu quan...@intel.com
 
 --Changes in v6:
  -Replace buf_size with PAGE_SIZE and use length rather than
   shr-length.
 ---
  hw/tpm/Makefile.objs |   1 +
  hw/tpm/xen_vtpm_frontend.c   | 315
 +++
  hw/xen/xen_frontend.c|  20 +++
  include/hw/xen/xen_backend.h |   5 +
  include/hw/xen/xen_common.h  |   6 +
  xen-hvm.c|   5 +
  6 files changed, 352 insertions(+)
  create mode 100644 hw/tpm/xen_vtpm_frontend.c
 
 diff --git a/hw/tpm/Makefile.objs b/hw/tpm/Makefile.objs index
 99f5983..57919fa 100644
 --- a/hw/tpm/Makefile.objs
 +++ b/hw/tpm/Makefile.objs
 @@ -1,2 +1,3 @@
  common-obj-$(CONFIG_TPM_TIS) += tpm_tis.o
  common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
 +common-obj-$(CONFIG_TPM_XENSTUBDOMS) += xen_vtpm_frontend.o
 diff --git a/hw/tpm/xen_vtpm_frontend.c b/hw/tpm/xen_vtpm_frontend.c
 new file mode 100644 index 000..d6e7cc6
 --- /dev/null
 +++ b/hw/tpm/xen_vtpm_frontend.c
 @@ -0,0 +1,315 @@
 +/*
 + * Connect to Xen vTPM stubdom domain
 + *
 + *  Copyright (c) 2015 Intel Corporation
 + *  Authors:
 + *Quan Xu quan...@intel.com
 + *
 + * This library is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2 of the License, or (at your option) any later version.
 + *
 + * This library is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * 

Re: [Qemu-devel] [PATCH v5 06/20] hw/arm/virt-acpi-build: Generation of DSDT table for virt devices

2015-05-04 Thread Igor Mammedov
On Mon, 04 May 2015 19:11:39 +0800
Shannon Zhao shannon.z...@linaro.org wrote:

 
 
 On 2015/5/4 17:58, Igor Mammedov wrote:
  On Wed, 15 Apr 2015 21:24:55 +0800
  Shannon Zhao zhaoshengl...@huawei.com wrote:
  
  From: Shannon Zhao shannon.z...@linaro.org
 
  DSDT consists of the usual common table header plus a definition
  block in AML encoding which describes all devices in the platform.
 
  After initializing DSDT with header information the namespace is
  created which is followed by the device encodings. The devices are
  described using the Resource Template for the 32-Bit Fixed Memory
  Range and the Extended Interrupt Descriptors.
 
  Signed-off-by: Shannon Zhao zhaoshengl...@huawei.com
  Signed-off-by: Shannon Zhao shannon.z...@linaro.org
  ---
   hw/arm/virt-acpi-build.c | 128
  +++ 1 file changed,
  128 insertions(+)
 
  diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
  index c5a3cf9..d044880 100644
  --- a/hw/arm/virt-acpi-build.c
  +++ b/hw/arm/virt-acpi-build.c
  @@ -50,6 +50,130 @@
   #include qom/qom-qobject.h
   #include exec/ram_addr.h
   
  +static void acpi_dsdt_add_cpus(Aml *scope, int max_cpus)
  +{
  +uint16_t i;
  +
  +for (i = 0; i  max_cpus; i++) {
  +Aml *dev = aml_device(C%03x, i);
  +aml_append(dev, aml_name_decl(_HID,
  aml_string(ACPI0007)));
  +aml_append(dev, aml_name_decl(_UID, aml_int(i)));
  +Aml *crs = aml_resource_template();
  +aml_append(dev, aml_name_decl(_CRS, crs));
  +aml_append(scope, dev);
  +}
  +}
  Is maxcpus a correct here? Usually maxcpus includes non present CPUs
  as well but there is no STA method that tells whether it's present
  or not.
  
 5.2.12.14 GICC Structure
 In the GICC interrupt model, logical processors are required to have
 a Processor Device object in the DSDT
 
 Here we create Processor Device object for all possible CPUs and in
 MADT the gicc-flags tells whether it's present or not. And this
 flags is for kernel booting initialization, not for dynamic
 configuration.

 BTW, ARM doesn't support vCPU hotplug now. If we want to support
 hotplug later, we should add _STA method for each Processor.
lack of _STA in current code implicitly means present, while flag
in MADT could say not present.

Since currently cpu hotplug is not supported for ARM,
pls use smp_cpus instead of max_cpus and create only device objects
and MADT entries only for present CPUs.


 
  +
  +static void acpi_dsdt_add_uart(Aml *scope, const MemMap
  *uart_memmap,
  +   const int *uart_irq)
  +{
  +Aml *dev = aml_device(COM0);
  +aml_append(dev, aml_name_decl(_HID,
  aml_string(ARMH0011)));
  +aml_append(dev, aml_name_decl(_UID, aml_int(0)));
  +
  +Aml *crs = aml_resource_template();
  +aml_append(crs, aml_memory32_fixed(uart_memmap-addr,
  +   uart_memmap-size,
  aml_ReadWrite));
  +aml_append(crs,
  +   aml_interrupt(aml_consumer, aml_level,
  aml_active_high,
  +   aml_exclusive, aml_not_wake_capable, *uart_irq +
  32));
  +aml_append(dev, aml_name_decl(_CRS, crs));
  +aml_append(scope, dev);
  +}
  +
  +static void acpi_dsdt_add_rtc(Aml *scope, const MemMap
  *rtc_memmap,
  +  const int *rtc_irq)
  +{
  +Aml *dev = aml_device(RTC0);
  +aml_append(dev, aml_name_decl(_HID,
  aml_string(LNRO0013)));
  +aml_append(dev, aml_name_decl(_UID, aml_int(0)));
  +
  +Aml *crs = aml_resource_template();
  +aml_append(crs, aml_memory32_fixed(rtc_memmap-addr,
  +   rtc_memmap-size,
  aml_ReadWrite));
  +aml_append(crs,
  +   aml_interrupt(aml_consumer, aml_level,
  aml_active_high,
  +   aml_exclusive, aml_not_wake_capable, *rtc_irq +
  32));
  +aml_append(dev, aml_name_decl(_CRS, crs));
  +aml_append(scope, dev);
  +}
  +
  +static void acpi_dsdt_add_flash(Aml *scope, const MemMap
  *flash_memmap) +{
  +Aml *dev, *crs;
  +hwaddr base = flash_memmap-addr;
  +hwaddr size = flash_memmap-size;
  +
  +dev = aml_device(FLS0);
  +aml_append(dev, aml_name_decl(_HID,
  aml_string(LNRO0015)));
  +aml_append(dev, aml_name_decl(_UID, aml_int(0)));
  +
  +crs = aml_resource_template();
  +aml_append(crs, aml_memory32_fixed(base, size,
  aml_ReadWrite));
  +aml_append(dev, aml_name_decl(_CRS, crs));
  +aml_append(scope, dev);
  +
  +dev = aml_device(FLS1);
  +aml_append(dev, aml_name_decl(_HID,
  aml_string(LNRO0015)));
  +aml_append(dev, aml_name_decl(_UID, aml_int(1)));
  +crs = aml_resource_template();
  +aml_append(crs, aml_memory32_fixed(base + size, size,
  aml_ReadWrite));
  +aml_append(dev, aml_name_decl(_CRS, crs));
  +aml_append(scope, dev);
  +}
  +
  +static void acpi_dsdt_add_virtio(Aml *scope, const MemMap
  *virtio_mmio_memmap,
  +  

Re: [Qemu-devel] [PATCH] cpu: Register QOM links at /machine/cpus/index

2015-05-04 Thread Igor Mammedov
On Mon, 04 May 2015 11:59:52 +0200
Paolo Bonzini pbonz...@redhat.com wrote:

 
 
 On 04/05/2015 11:47, Igor Mammedov wrote:
  On Thu, 30 Apr 2015 16:19:07 -0300
  Eduardo Habkost ehabk...@redhat.com wrote:
  
   This will provide a predictable path for the CPU objects, and a
   more powerful alternative for the query-cpus QMP command, as now
   every QOM property on CPU objects can be easily queried.
  
  provided the way cpu_index is generated, path won't be
  predictable/stable with CPU unplug. I'd rather use DEVICE-id
  instead of cpu_index.
 
 Can we use the APIC id then?  Perhaps wrapped with a CPUState-level
 method get_stable_processor_id()?
We have CPUClass-get_arch_id() which results in APIC id for
target-i386.
But I'd rather see an arbitrary DEVICE-id as index/name, that way
when -device cpu-foo,id=cpuXXX becomes functional we would have
1:1 mapping between CLI and /machine/cpus/ view.

 
 Paolo




Re: [Qemu-devel] [PATCH] cpu: Register QOM links at /machine/cpus/index

2015-05-04 Thread Paolo Bonzini


On 04/05/2015 15:16, Igor Mammedov wrote:
  Can we use the APIC id then?  Perhaps wrapped with a CPUState-level
  method get_stable_processor_id()?
 We have CPUClass-get_arch_id() which results in APIC id for
 target-i386.
 But I'd rather see an arbitrary DEVICE-id as index/name, that way
 when -device cpu-foo,id=cpuXXX becomes functional we would have
 1:1 mapping between CLI and /machine/cpus/ view.

CPUs would already be available at /machine/peripheral.  I think aliases
should provide alternative indexing whenever possible---not simply
filter by device type.

Paolo



Re: [Qemu-devel] [PATCH] cpu: Register QOM links at /machine/cpus/index

2015-05-04 Thread Eduardo Habkost
On Mon, May 04, 2015 at 03:16:16PM +0200, Igor Mammedov wrote:
 On Mon, 04 May 2015 11:59:52 +0200
 Paolo Bonzini pbonz...@redhat.com wrote:
 
  
  
  On 04/05/2015 11:47, Igor Mammedov wrote:
   On Thu, 30 Apr 2015 16:19:07 -0300
   Eduardo Habkost ehabk...@redhat.com wrote:
   
This will provide a predictable path for the CPU objects, and a
more powerful alternative for the query-cpus QMP command, as now
every QOM property on CPU objects can be easily queried.
   
   provided the way cpu_index is generated, path won't be
   predictable/stable with CPU unplug. I'd rather use DEVICE-id
   instead of cpu_index.
  
  Can we use the APIC id then?  Perhaps wrapped with a CPUState-level
  method get_stable_processor_id()?
 We have CPUClass-get_arch_id() which results in APIC id for
 target-i386.
 But I'd rather see an arbitrary DEVICE-id as index/name, that way
 when -device cpu-foo,id=cpuXXX becomes functional we would have
 1:1 mapping between CLI and /machine/cpus/ view.

An arbitrary device ID sounds better to me, because it allows us to
change guest-visible behavior without breaking QMP client expectations.

The only question is what should be the default device ID for the CPUs
created by -smp and cpu-add. I was going to suggest get_arch_id(), but
cpu_index may be a better candidate for the same reason above: it is
truly an arbitrary ID that doesn't depend on guest-visible bits.

-- 
Eduardo



Re: [Qemu-devel] [PATCH 1/1] vl.c: Since the help says that 'disk_image' is a raw hard disk image, pass format=raw

2015-05-04 Thread Markus Armbruster
Kevin Wolf kw...@redhat.com writes:

 Am 01.05.2015 um 01:28 hat Don Slutz geschrieben:
[...]
 So do you want a more complex patch that allows the format to be
 specified?
 
 Only for 'disk_image'?
 
 Include -hd* ?

 I'm afraid that there is no nice way to improve the plain 'disk_image'
 case. You would have to add another option, and then it's not any better
 than -hda and friends any more.

 -hda in turn could be extended to take additional options (i.e. it
 becomes something like -drive with implied index=0), but then there's
 little reason not to use -drive.

Would likely break images with ',' in their name.

[...]



[Qemu-devel] [PATCH 1/2] block: minimal bounce buffer alignment

2015-05-04 Thread Denis V. Lunev
The patch introduces new concept: minimal memory alignment for bounce
buffers. Original so called optimal value is actually minimal required
value for aligment. It should be used for validation that the IOVec
is properly aligned and bounce buffer is not required.

Though, from the performance point of view, it would be better if
bounce buffer or IOVec allocated by QEMU will be aligned stricter.

The patch does not change any alignment value yet.

Signed-off-by: Denis V. Lunev d...@openvz.org
CC: Paolo Bonzini pbonz...@redhat.com
CC: Kevin Wolf kw...@redhat.com
CC: Stefan Hajnoczi stefa...@redhat.com
---
 block.c   | 11 +++
 block/io.c|  7 ++-
 block/raw-posix.c |  1 +
 include/block/block.h |  2 ++
 include/block/block_int.h |  3 +++
 5 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/block.c b/block.c
index 7904098..e293907 100644
--- a/block.c
+++ b/block.c
@@ -113,6 +113,16 @@ size_t bdrv_opt_mem_align(BlockDriverState *bs)
 return bs-bl.opt_mem_alignment;
 }
 
+size_t bdrv_min_mem_align(BlockDriverState *bs)
+{
+if (!bs || !bs-drv) {
+/* 4k should be on the safe side */
+return 4096;
+}
+
+return bs-bl.min_mem_alignment;
+}
+
 /* check if the path starts with protocol: */
 int path_has_protocol(const char *path)
 {
@@ -890,6 +900,7 @@ static int bdrv_open_common(BlockDriverState *bs, 
BlockDriverState *file,
 }
 
 assert(bdrv_opt_mem_align(bs) != 0);
+assert(bdrv_min_mem_align(bs) != 0);
 assert((bs-request_alignment != 0) || bs-sg);
 return 0;
 
diff --git a/block/io.c b/block/io.c
index 1ce62c4..908a3d1 100644
--- a/block/io.c
+++ b/block/io.c
@@ -201,8 +201,10 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error 
**errp)
 }
 bs-bl.opt_transfer_length = bs-file-bl.opt_transfer_length;
 bs-bl.max_transfer_length = bs-file-bl.max_transfer_length;
+bs-bl.min_mem_alignment = bs-file-bl.min_mem_alignment;
 bs-bl.opt_mem_alignment = bs-file-bl.opt_mem_alignment;
 } else {
+bs-bl.min_mem_alignment = 512;
 bs-bl.opt_mem_alignment = 512;
 }
 
@@ -221,6 +223,9 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
 bs-bl.opt_mem_alignment =
 MAX(bs-bl.opt_mem_alignment,
 bs-backing_hd-bl.opt_mem_alignment);
+bs-bl.min_mem_alignment =
+MAX(bs-bl.min_mem_alignment,
+bs-backing_hd-bl.min_mem_alignment);
 }
 
 /* Then let the driver override it */
@@ -2489,7 +2494,7 @@ void *qemu_try_blockalign0(BlockDriverState *bs, size_t 
size)
 bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
 {
 int i;
-size_t alignment = bdrv_opt_mem_align(bs);
+size_t alignment = bdrv_min_mem_align(bs);
 
 for (i = 0; i  qiov-niov; i++) {
 if ((uintptr_t) qiov-iov[i].iov_base % alignment) {
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 24d8582..7083924 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -725,6 +725,7 @@ static void raw_refresh_limits(BlockDriverState *bs, Error 
**errp)
 BDRVRawState *s = bs-opaque;
 
 raw_probe_alignment(bs, s-fd, errp);
+bs-bl.min_mem_alignment = s-buf_align;
 bs-bl.opt_mem_alignment = s-buf_align;
 }
 
diff --git a/include/block/block.h b/include/block/block.h
index 7d1a717..c1c963e 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -440,6 +440,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
 
 /* Returns the alignment in bytes that is required so that no bounce buffer
  * is required throughout the stack */
+size_t bdrv_min_mem_align(BlockDriverState *bs);
+/* Returns optimal alignment in bytes for bounce buffer */
 size_t bdrv_opt_mem_align(BlockDriverState *bs);
 void bdrv_set_guest_block_size(BlockDriverState *bs, int align);
 void *qemu_blockalign(BlockDriverState *bs, size_t size);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index db29b74..f004378 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -313,6 +313,9 @@ typedef struct BlockLimits {
 int max_transfer_length;
 
 /* memory alignment so that no bounce buffer is needed */
+size_t min_mem_alignment;
+
+/* memory alignment for bounce buffer */
 size_t opt_mem_alignment;
 } BlockLimits;
 
-- 
1.9.1




[Qemu-devel] [PATCH v5 0/2] block: enforce minimal 4096 alignment in qemu_blockalign

2015-05-04 Thread Denis V. Lunev
The following sequence
int fd = open(argv[1], O_RDWR | O_CREAT | O_DIRECT, 0644);
for (i = 0; i  10; i++)
write(fd, buf, 4096);
iperforms 5% better if buf is aligned to 4096 bytes rather then to
512 bytes.

I have used the following program to test
#define _GNU_SOURCE

#include stdio.h
#include unistd.h
#include fcntl.h
#include sys/types.h
#include malloc.h
#include string.h

int main(int argc, char *argv[])
{
int fd = open(argv[1], O_RDWR | O_CREAT | O_DIRECT, 0644);
void *buf;
int i = 0, align = atoi(argv[2]);

do {
buf = memalign(align, 4096);
if (align = 4096)
break;
if ((unsigned long)buf  4095)
break;
i++;
} while (1);
printf(%d %p\n, i, buf);

memset(buf, 0x11, 4096);

for (i = 0; i  10; i++) {
lseek(fd, SEEK_CUR, 4096);
write(fd, buf, 4096);
}

close(fd);
return 0;
}
for in in `seq 1 30` ; do a.out aa ; done

The file was placed into 8 GB partition on HDD below to avoid speed
change due to different offset on disk. Results are reliable:
- 189 vs 180 seconds on Linux 3.16

The following setups have been tested:
1) ext4 with block size equals to 1024 over 512/512 physical/logical
   sector size SSD disk
2) ext4 with block size equals to 4096 over 512/512 physical/logical
   sector size SSD disk
3) ext4 with block size equals to 4096 over 512/4096 physical/logical
   sector size rotational disk (WDC WD20EZRX)
4) xfs with block size equals to 4096 over 512/512 physical/logical
   sector size SSD disk

The difference is quite reliable and the same 5%.
  qemu-io -n -c 'write -P 0xaa 0 1G' 1.img
for image in qcow2 format is 1% faster.

Changes from v4:
- patches reordered
- dropped conversion from 512 to BDRV_SECTOR_SIZE
- getpagesize() is replaced with MAX(4096, getpagesize()) as suggested by
  Kevin

Changes from v3:
- portable way to calculate system page size used
- 512/4096 values are replaced with proper macros/values

Changes from v2:
- opt_mem_alignment is split to opt_mem_alignment for bounce buffering
  and min_mem_alignment to check buffers coming from guest.

Changes from v1:
- enforces 4096 alignment in qemu_(try_)blockalign, avoid touching of
  bdrv_qiov_is_aligned path not to enforce additional bounce buffering
  as suggested by Paolo
- reduces 10% to 5% in patch description to better fit 180 vs 189
  difference

Signed-off-by: Denis V. Lunev d...@openvz.org
CC: Paolo Bonzini pbonz...@redhat.com
CC: Kevin Wolf kw...@redhat.com
CC: Stefan Hajnoczi stefa...@redhat.com




[Qemu-devel] [PATCH 2/2] block: align bounce buffers to page

2015-05-04 Thread Denis V. Lunev
The following sequence
int fd = open(argv[1], O_RDWR | O_CREAT | O_DIRECT, 0644);
for (i = 0; i  10; i++)
write(fd, buf, 4096);
performs 5% better if buf is aligned to 4096 bytes.

The difference is quite reliable.

On the other hand we do not want at the moment to enforce bounce
buffering if guest request is aligned to 512 bytes.

The patch changes default bounce buffer optimal alignment to
MAX(page size, 4k). 4k is chosen as maximal known sector size on real
HDD.

Signed-off-by: Denis V. Lunev d...@openvz.org
CC: Paolo Bonzini pbonz...@redhat.com
CC: Kevin Wolf kw...@redhat.com
CC: Stefan Hajnoczi stefa...@redhat.com
---
 block.c   |  8 
 block/io.c|  2 +-
 block/raw-posix.c | 14 --
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/block.c b/block.c
index e293907..325f727 100644
--- a/block.c
+++ b/block.c
@@ -106,8 +106,8 @@ int is_windows_drive(const char *filename)
 size_t bdrv_opt_mem_align(BlockDriverState *bs)
 {
 if (!bs || !bs-drv) {
-/* 4k should be on the safe side */
-return 4096;
+/* page size or 4k (hdd sector size) should be on the safe side */
+return MAX(4096, getpagesize());
 }
 
 return bs-bl.opt_mem_alignment;
@@ -116,8 +116,8 @@ size_t bdrv_opt_mem_align(BlockDriverState *bs)
 size_t bdrv_min_mem_align(BlockDriverState *bs)
 {
 if (!bs || !bs-drv) {
-/* 4k should be on the safe side */
-return 4096;
+/* page size or 4k (hdd sector size) should be on the safe side */
+return MAX(4096, getpagesize());
 }
 
 return bs-bl.min_mem_alignment;
diff --git a/block/io.c b/block/io.c
index 908a3d1..071652c 100644
--- a/block/io.c
+++ b/block/io.c
@@ -205,7 +205,7 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
 bs-bl.opt_mem_alignment = bs-file-bl.opt_mem_alignment;
 } else {
 bs-bl.min_mem_alignment = 512;
-bs-bl.opt_mem_alignment = 512;
+bs-bl.opt_mem_alignment = getpagesize();
 }
 
 if (bs-backing_hd) {
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 7083924..04f3d4e 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -301,6 +301,7 @@ static void raw_probe_alignment(BlockDriverState *bs, int 
fd, Error **errp)
 {
 BDRVRawState *s = bs-opaque;
 char *buf;
+size_t max_align = MAX(MAX_BLOCKSIZE, getpagesize());
 
 /* For /dev/sg devices the alignment is not really used.
With buffered I/O, we don't have any restrictions. */
@@ -330,9 +331,9 @@ static void raw_probe_alignment(BlockDriverState *bs, int 
fd, Error **errp)
 /* If we could not get the sizes so far, we can only guess them */
 if (!s-buf_align) {
 size_t align;
-buf = qemu_memalign(MAX_BLOCKSIZE, 2 * MAX_BLOCKSIZE);
-for (align = 512; align = MAX_BLOCKSIZE; align = 1) {
-if (raw_is_io_aligned(fd, buf + align, MAX_BLOCKSIZE)) {
+buf = qemu_memalign(max_align, 2 * max_align);
+for (align = 512; align = max_align; align = 1) {
+if (raw_is_io_aligned(fd, buf + align, max_align)) {
 s-buf_align = align;
 break;
 }
@@ -342,8 +343,8 @@ static void raw_probe_alignment(BlockDriverState *bs, int 
fd, Error **errp)
 
 if (!bs-request_alignment) {
 size_t align;
-buf = qemu_memalign(s-buf_align, MAX_BLOCKSIZE);
-for (align = 512; align = MAX_BLOCKSIZE; align = 1) {
+buf = qemu_memalign(s-buf_align, max_align);
+for (align = 512; align = max_align; align = 1) {
 if (raw_is_io_aligned(fd, buf, align)) {
 bs-request_alignment = align;
 break;
@@ -726,7 +727,8 @@ static void raw_refresh_limits(BlockDriverState *bs, Error 
**errp)
 
 raw_probe_alignment(bs, s-fd, errp);
 bs-bl.min_mem_alignment = s-buf_align;
-bs-bl.opt_mem_alignment = s-buf_align;
+if (bs-bl.min_mem_alignment  bs-bl.opt_mem_alignment)
+bs-bl.opt_mem_alignment = bs-bl.min_mem_alignment;
 }
 
 static int check_for_dasd(int fd)
-- 
1.9.1




Re: [Qemu-devel] [PATCH] coverity: fix address_space_rw model

2015-05-04 Thread Markus Armbruster
Paolo Bonzini pbonz...@redhat.com writes:

 If the is_write argument is true, address_space_rw writes to memory
 and thus reads from the buffer.  The opposite holds if is_write is
 false.  Fix the model.

 Cc: Markus Armbruster arm...@redhat.com
 Signed-off-by: Paolo Bonzini pbonz...@redhat.com
 ---
  scripts/coverity-model.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

 diff --git a/scripts/coverity-model.c b/scripts/coverity-model.c
 index 224d2d1..617f67d 100644
 --- a/scripts/coverity-model.c
 +++ b/scripts/coverity-model.c
 @@ -49,7 +49,7 @@ typedef uint64_t hwaddr;
  typedef uint32_t MemTxResult;
  typedef uint64_t MemTxAttrs;
  
 -static void __write(uint8_t *buf, ssize_t len)
 +static void __bufwrite(uint8_t *buf, ssize_t len)
  {
  int first, last;
  __coverity_negative_sink__(len);
 @@ -59,7 +59,7 @@ static void __write(uint8_t *buf, ssize_t len)
  __coverity_writeall__(buf);
  }
  
 -static void __read(uint8_t *buf, ssize_t len)
 +static void __bufread(uint8_t *buf, ssize_t len)
  {
  __coverity_negative_sink__(len);
  if (len == 0) return;
 @@ -74,7 +74,7 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, 
 MemTxAttrs attrs,
  
  // TODO: investigate impact of treating reads as producing
  // tainted data, with __coverity_tainted_data_argument__(buf).
 -if (is_write) __write(buf, len); else __read(buf, len);
 +if (is_write) __bufread(buf, len); else __bufwrite(buf, len);
  
  return result;
  }

Good one :)

I can take this through my tree.  Thanks!



Re: [Qemu-devel] [PATCH] cpu: Register QOM links at /machine/cpus/index

2015-05-04 Thread Eduardo Habkost
On Mon, May 04, 2015 at 03:19:32PM +0200, Paolo Bonzini wrote:
 
 
 On 04/05/2015 15:16, Igor Mammedov wrote:
   Can we use the APIC id then?  Perhaps wrapped with a CPUState-level
   method get_stable_processor_id()?
  We have CPUClass-get_arch_id() which results in APIC id for
  target-i386.
  But I'd rather see an arbitrary DEVICE-id as index/name, that way
  when -device cpu-foo,id=cpuXXX becomes functional we would have
  1:1 mapping between CLI and /machine/cpus/ view.
 
 CPUs would already be available at /machine/peripheral.  I think aliases
 should provide alternative indexing whenever possible---not simply
 filter by device type.

Could you clarify what you mean by alternative indexing?

All I am trying to provide right now is having a predictable path for
CPUs, it doesn't matter if using -device, device_add, -smp, or cpu-add.
Filtering by device type is not what I need, here. If we can make the
CPU QOM path predictable inside /machine/peripheral or anywhere else,
that would be enough to me[1].

device IDs are predictable when using -device because they are in the
command-line. And they are predictable for -smp CPUs if we use cpu_index
as default ID.

Making the path depend on guest-visible bits that can change depending
on the architeture or machine would make the path less predictable.

I have an alternative patch that simply adds a qom-path field to
query-cpus. If we find out that making commitments about QOM paths is
too hard, I can submit it instead.

[1] Is there anybody or any document that can explain to me what all the
containers inside /machine mean? I see /machine/peripheral,
/machine/peripheral-anon, /machine/unattached, here, and I don't
know what they mean.

-- 
Eduardo



Re: [Qemu-devel] [PATCH 1/1] vl.c: Since the help says that 'disk_image' is a raw hard disk image, pass format=raw

2015-05-04 Thread Kevin Wolf
Am 04.05.2015 um 15:39 hat Markus Armbruster geschrieben:
 Kevin Wolf kw...@redhat.com writes:
 
  Am 01.05.2015 um 01:28 hat Don Slutz geschrieben:
 [...]
  So do you want a more complex patch that allows the format to be
  specified?
  
  Only for 'disk_image'?
  
  Include -hd* ?
 
  I'm afraid that there is no nice way to improve the plain 'disk_image'
  case. You would have to add another option, and then it's not any better
  than -hda and friends any more.
 
  -hda in turn could be extended to take additional options (i.e. it
  becomes something like -drive with implied index=0), but then there's
  little reason not to use -drive.
 
 Would likely break images with ',' in their name.

A possible justification would be that -hda is a convenience option
that, similar to HMP, is meant only for human users and if you use it in
scripts and it changes, you get to keep both pieces. In addition, while
some use cases would be affected, most of them wouldn't, even in
scripts.

Whether or not this justification is valid might be controversial.

Kevin



Re: [Qemu-devel] [PATCH] ps2 keyboard:fix can't use ps2 keyboard if typing many times After leaving grub and before finishing linux kernel ps2 driver initialization

2015-05-04 Thread Eric Blake
On 05/03/2015 10:32 AM, penghao...@sina.com wrote:

Poor subject line.  Please try to keep subjects under 65 characters in
length (see 'git shortlog -30' for good examples).  Maybe:

keyboard: handle ps2 typing buffer overrun

 Starting  a linux guest with ps2 keyboard ,if you type many times during 
 leaving grub and into linux kernel ,then you can't use keyboard after linux 
 initialization finished.

Also, wrap your commit body messages to fit with 78 columns or so.

Spacing is wrong: s/Starting  a/Staring a/; s/keyboard ,if/keyboard,
if/; s/kernel ,then/kernel, then/

 during grub,the work method of ps2 keyboard is like this:
 first ,ps2 keyboard driver send command KBD_CCMD_KBD_ENABLE,
 second,if there is a keyboard input,then  ps2 keyboard driver read data.
 third ,ps2 keyboard driver send command KBD_CCMD_KBD_ENABLE,

Again, in English, no space before comma, but space afterwards.

 ...
 this is diffrent method of linux kernel .

s/diffrent/different/; s/ ././

 After leaving  grub and before finishing linux kernel ps2 driver 
 initialization,if you type many times,the input data keep saving the ps2 
 queue in qemu .Before linux kernel initialize ps2 keyboard,linux call 
 i8042_init-i8042_controller_check,if i8042_controller_check return fail,then 
 linux kernel ps2 keyboard driver will never initialize. 

More spacing errors; no trailing space, long line.

 (linux kernel 2.6.32 i8042.c)
 static int i8042_controller_check(void)
 {
  if (i8042_flush() == I8042_BUFFER_SIZE)
   return -ENODEV;
  return 0;
 }
 static int i8042_flush(void)
 {...
 while (((str = i8042_read_status())  I8042_STR_OBF)  (i  
 I8042_BUFFER_SIZE)) {
   udelay(50);
   data = i8042_read_data();
   i++;
   }
 return i;
 }

Indentation is weird.

  
 during calling i8042_flush it is full in qemu queue .
 ps_read_data:
s-update_irq(s-update_arg, 0);
s-update_irq(s-update_arg, q-count != 0);
 because q-count!=0, kbd_update_irq can set I8042_STR_OBF.Then i8042_flush()  
 will return I8042_BUFFER_SIZE.
 Signed-off-by: Hao Pengpenghao...@sina.co
 --- ps2.c.orig 2015-04-25 09:44:38.865777168 -0400

Missing the usual '---' separator between the commit body and the patch
proper; also missing the diffstat.  Life is easier if you use 'git
format-patch' and/or 'git send-email' to format your patch messages.

More hints at:
http://wiki.qemu.org/Contribute/SubmitAPatch

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [RFC PATCH v3 05/24] spapr: Reorganize CPU dt generation code

2015-05-04 Thread David Gibson
On Mon, Apr 27, 2015 at 11:06:07AM +0530, Bharata B Rao wrote:
 On Sun, Apr 26, 2015 at 05:17:48PM +0530, Bharata B Rao wrote:
  On Fri, Apr 24, 2015 at 12:17:27PM +0530, Bharata B Rao wrote:
   Reorganize CPU device tree generation code so that it be reused from
   hotplug path. CPU dt entries are now generated from spapr_finalize_fdt()
   instead of spapr_create_fdt_skel().
  
  Creating CPU DT entries from spapr_finalize_fdt() instead of
  spapr_create_fdt_skel() has an interesting side effect.
  
  snip 
  
  In both the cases, I am adding CPU DT nodes from QEMU in the same order,
  but not sure why the guest kernel discovers them in different orders in
  each case.
 
 Nikunj and I tracked this down to the difference in device tree APIs that
 we are using in two cases.
 
 When CPU DT nodes are created from spapr_create_fdt_skel(), we are using
 fdt_begin_node() API which does sequential write and hence CPU DT nodes
 end up in the same order in which they are created.
 
 However in my patch when I create CPU DT entries in spapr_finalize_fdt(),
 I am using fdt_add_subnode() which ends up writing the CPU DT node at the
 same parent offset for all the CPUs. This results in CPU DT nodes being
 generated in reverse order in FDT.
 
  
   +static void spapr_populate_cpus_dt_node(void *fdt, sPAPREnvironment 
   *spapr)
   +{
   +CPUState *cs;
   +int cpus_offset;
   +char *nodename;
   +int smt = kvmppc_smt_threads();
   +
   +cpus_offset = fdt_add_subnode(fdt, 0, cpus);
   +_FDT(cpus_offset);
   +_FDT((fdt_setprop_cell(fdt, cpus_offset, #address-cells, 0x1)));
   +_FDT((fdt_setprop_cell(fdt, cpus_offset, #size-cells, 0x0)));
   +
   +CPU_FOREACH(cs) {
   +PowerPCCPU *cpu = POWERPC_CPU(cs);
   +int index = ppc_get_vcpu_dt_id(cpu);
   +DeviceClass *dc = DEVICE_GET_CLASS(cs);
   +int offset;
   +
   +if ((index % smt) != 0) {
   +continue;
   +}
   +
   +nodename = g_strdup_printf(%s@%x, dc-fw_name, index);
   +offset = fdt_add_subnode(fdt, cpus_offset, nodename);
   +g_free(nodename);
   +_FDT(offset);
   +spapr_populate_cpu_dt(cs, fdt, offset);
   +}
  
  I can simply fix this by walking the CPUs in reverse order in the above
  code which makes the guest kernel to discover the CPU DT nodes in the
  right order.
  
  s/CPU_FOREACH(cs)/CPU_FOREACH_REVERSE(cs) will solve this problem. Would 
  this
  be the right approach or should we just leave it to the guest kernel to
  discover and enumerate CPUs in whatever order it finds the DT nodes in FDT ?
 
 So using CPU_FOREACH_REVERSE(cs) appears to be right way to handle this.

Yes, I think so.  In theory it shouldn't matter, but I think it's
safer to retain the device tree order.

-- 
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


pgpo6LKENe_VG.pgp
Description: PGP signature


Re: [Qemu-devel] [RFC PATCH v3 02/24] spapr: Add DRC dt entries for CPUs

2015-05-04 Thread David Gibson
On Fri, Apr 24, 2015 at 12:17:24PM +0530, Bharata B Rao wrote:
 Advertise CPU DR-capability to the guest via device tree.
 
 Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com
 Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
[spapr_drc_reset implementation]
 ---
  hw/ppc/spapr.c | 29 +
  1 file changed, 29 insertions(+)
 
 diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
 index 981814d..9ea3a38 100644
 --- a/hw/ppc/spapr.c
 +++ b/hw/ppc/spapr.c
 @@ -807,6 +807,15 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
  spapr_populate_chosen_stdout(fdt, spapr-vio_bus);
  }
  
 +if (spapr-dr_cpu_enabled) {
 +int offset = fdt_path_offset(fdt, /cpus);
 +ret = spapr_drc_populate_dt(fdt, offset, NULL,
 +SPAPR_DR_CONNECTOR_TYPE_CPU);
 +if (ret  0) {
 +fprintf(stderr, Couldn't set up CPU DR device tree 
 properties\n);
 +}
 +}
 +
  _FDT((fdt_pack(fdt)));
  
  if (fdt_totalsize(fdt)  FDT_MAX_SIZE) {
 @@ -1393,6 +1402,16 @@ static SaveVMHandlers savevm_htab_handlers = {
  .load_state = htab_load,
  };
  
 +static void spapr_drc_reset(void *opaque)
 +{
 +sPAPRDRConnector *drc = opaque;
 +DeviceState *d = DEVICE(drc);
 +
 +if (d) {
 +device_reset(d);
 +}
 +}

Why do these need an explicit reset, rather than having their reset
hook automatically called by the qdev infrastructure?

I'm guessing it's something to do with how these are linked into the
qdev tree, but it could do with a comment clarifying this.

  /* pSeries LPAR / sPAPR hardware init */
  static void ppc_spapr_init(MachineState *machine)
  {
 @@ -1418,6 +1437,7 @@ static void ppc_spapr_init(MachineState *machine)
  long load_limit, fw_size;
  bool kernel_le = false;
  char *filename;
 +int smt = kvmppc_smt_threads();
  
  msi_supported = true;
  
 @@ -1482,6 +1502,15 @@ static void ppc_spapr_init(MachineState *machine)
  spapr-dr_cpu_enabled = smc-dr_cpu_enabled;
  spapr-dr_lmb_enabled = smc-dr_lmb_enabled;
  
 +if (spapr-dr_cpu_enabled) {
 +for (i = 0; i  max_cpus/smp_threads; i++) {
 +sPAPRDRConnector *drc =
 +spapr_dr_connector_new(OBJECT(machine),
 +   SPAPR_DR_CONNECTOR_TYPE_CPU, i * smt);
 +qemu_register_reset(spapr_drc_reset, drc);
 +}
 +}
 +
  /* init CPUs */
  if (cpu_model == NULL) {
  cpu_model = kvm_enabled() ? host : POWER7;

-- 
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


pgpGFRxlyMeny.pgp
Description: PGP signature


Re: [Qemu-devel] [RFC PATCH v3 05/24] spapr: Reorganize CPU dt generation code

2015-05-04 Thread David Gibson
On Fri, Apr 24, 2015 at 12:17:27PM +0530, Bharata B Rao wrote:
 Reorganize CPU device tree generation code so that it be reused from
 hotplug path. CPU dt entries are now generated from spapr_finalize_fdt()
 instead of spapr_create_fdt_skel().
 
 Note: This is how the split-up looks like now:
 
 Boot path
 -
 spapr_finalize_fdt
  spapr_populate_cpus_dt_node
   spapr_populate_cpu_dt
spapr_fixup_cpu_numa_dt
spapr_fixup_cpu_smt_dt
 
 Hotplug path
 
 spapr_cpu_plug
  spapr_populate_hotplug_cpu_dt
   spapr_populate_cpu_dt
spapr_fixup_cpu_numa_dt
spapr_fixup_cpu_smt_dt
 
 ibm,cas path
 
 spapr_h_cas_compose_response
  spapr_fixup_cpu_dt
   spapr_fixup_cpu_numa_dt
   spapr_fixup_cpu_smt_dt
 
 Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com

Reviewed-by: David Gibson da...@gibson.dropbear.id.au

-- 
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


pgp17UGy3PQaz.pgp
Description: PGP signature


[Qemu-devel] [PATCH v8 04/40] qapi: Fix generation of 'size' builtin type

2015-05-04 Thread Eric Blake
We were missing the 'size' builtin type (which means that QAPI using
[ 'size' ] would fail to compile).

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 scripts/qapi.py | 1 +
 tests/qapi-schema/qapi-schema-test.json | 3 ++-
 tests/qapi-schema/qapi-schema-test.out  | 2 +-
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 2b5775d..d470347 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -29,6 +29,7 @@ builtin_types = {
 'uint16':   'QTYPE_QINT',
 'uint32':   'QTYPE_QINT',
 'uint64':   'QTYPE_QINT',
+'size': 'QTYPE_QINT',
 }

 def error_path(parent):
diff --git a/tests/qapi-schema/qapi-schema-test.json 
b/tests/qapi-schema/qapi-schema-test.json
index d43b5fd..84f0f07 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -74,7 +74,8 @@
 'u64': ['uint64'],
 'number': ['number'],
 'boolean': ['bool'],
-'string': ['str'] } }
+'string': ['str'],
+'sizes': ['size'] } }

 # testing commands
 { 'command': 'user_def_cmd', 'data': {} }
diff --git a/tests/qapi-schema/qapi-schema-test.out 
b/tests/qapi-schema/qapi-schema-test.out
index 08d7304..915a61b 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -12,7 +12,7 @@
  OrderedDict([('union', 'UserDefFlatUnion'), ('base', 'UserDefUnionBase'), 
('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefA'), 
('value2', 'UserDefB'), ('value3', 'UserDefB')]))]),
  OrderedDict([('union', 'UserDefFlatUnion2'), ('base', 'UserDefUnionBase'), 
('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefC'), 
('value2', 'UserDefB'), ('value3', 'UserDefA')]))]),
  OrderedDict([('union', 'UserDefAnonUnion'), ('discriminator', OrderedDict()), 
('data', OrderedDict([('uda', 'UserDefA'), ('s', 'str'), ('i', 'int')]))]),
- OrderedDict([('union', 'UserDefNativeListUnion'), ('data', 
OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), 
('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), 
('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', 
['bool']), ('string', ['str'])]))]),
+ OrderedDict([('union', 'UserDefNativeListUnion'), ('data', 
OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), 
('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), 
('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', 
['bool']), ('string', ['str']), ('sizes', ['size'])]))]),
  OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
  OrderedDict([('command', 'user_def_cmd1'), ('data', OrderedDict([('ud1a', 
'UserDefOne')]))]),
  OrderedDict([('command', 'user_def_cmd2'), ('data', OrderedDict([('ud1a', 
'UserDefOne'), ('*ud1b', 'UserDefOne')])), ('returns', 'UserDefTwo')]),
-- 
2.1.0




[Qemu-devel] [PATCH v8 03/40] qapi: Simplify builtin type handling

2015-05-04 Thread Eric Blake
There was some redundancy between builtin_types[] and
builtin_type_qtypes{}.  Merge them into one.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 scripts/qapi-types.py | 10 +-
 scripts/qapi-visit.py |  6 +++---
 scripts/qapi.py   |  8 +---
 3 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index db87218..e400b03 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -182,8 +182,8 @@ const int %(name)s_qtypes[QTYPE_MAX] = {

 for key in members:
 qapi_type = members[key]
-if builtin_type_qtypes.has_key(qapi_type):
-qtype = builtin_type_qtypes[qapi_type]
+if builtin_types.has_key(qapi_type):
+qtype = builtin_types[qapi_type]
 elif find_struct(qapi_type):
 qtype = QTYPE_QDICT
 elif find_union(qapi_type):
@@ -398,7 +398,7 @@ exprs = parse_schema(input_file)
 exprs = filter(lambda expr: not expr.has_key('gen'), exprs)

 fdecl.write(guardstart(QAPI_TYPES_BUILTIN_STRUCT_DECL))
-for typename in builtin_types:
+for typename in builtin_types.keys():
 fdecl.write(generate_fwd_struct(typename, None, builtin_type=True))
 fdecl.write(guardend(QAPI_TYPES_BUILTIN_STRUCT_DECL))

@@ -426,7 +426,7 @@ for expr in exprs:
 # to avoid header dependency hell, we always generate declarations
 # for built-in types in our header files and simply guard them
 fdecl.write(guardstart(QAPI_TYPES_BUILTIN_CLEANUP_DECL))
-for typename in builtin_types:
+for typename in builtin_types.keys():
 fdecl.write(generate_type_cleanup_decl(typename + List))
 fdecl.write(guardend(QAPI_TYPES_BUILTIN_CLEANUP_DECL))

@@ -435,7 +435,7 @@ fdecl.write(guardend(QAPI_TYPES_BUILTIN_CLEANUP_DECL))
 # over these cases
 if do_builtins:
 fdef.write(guardstart(QAPI_TYPES_BUILTIN_CLEANUP_DEF))
-for typename in builtin_types:
+for typename in builtin_types.keys():
 fdef.write(generate_type_cleanup(typename + List))
 fdef.write(guardend(QAPI_TYPES_BUILTIN_CLEANUP_DEF))

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 1be4d67..41596bb 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -261,7 +261,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const 
char *name, Error **e
 disc_type = '%sKind' % (name)

 for key in members:
-assert (members[key] in builtin_types
+assert (members[key] in builtin_types.keys()
 or find_struct(members[key])
 or find_union(members[key])
 or find_enum(members[key])), Invalid anonymous union member
@@ -538,7 +538,7 @@ exprs = parse_schema(input_file)
 # to avoid header dependency hell, we always generate declarations
 # for built-in types in our header files and simply guard them
 fdecl.write(guardstart(QAPI_VISIT_BUILTIN_VISITOR_DECL))
-for typename in builtin_types:
+for typename in builtin_types.keys():
 fdecl.write(generate_declaration(typename, None, builtin_type=True))
 fdecl.write(guardend(QAPI_VISIT_BUILTIN_VISITOR_DECL))

@@ -546,7 +546,7 @@ fdecl.write(guardend(QAPI_VISIT_BUILTIN_VISITOR_DECL))
 # have the functions defined, so we use -b option to provide control
 # over these cases
 if do_builtins:
-for typename in builtin_types:
+for typename in builtin_types.keys():
 fdef.write(generate_visit_list(typename, None))

 for expr in exprs:
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 77d46aa..2b5775d 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -16,13 +16,7 @@ from ordereddict import OrderedDict
 import os
 import sys

-builtin_types = [
-'str', 'int', 'number', 'bool',
-'int8', 'int16', 'int32', 'int64',
-'uint8', 'uint16', 'uint32', 'uint64'
-]
-
-builtin_type_qtypes = {
+builtin_types = {
 'str':  'QTYPE_QSTRING',
 'int':  'QTYPE_QINT',
 'number':   'QTYPE_QFLOAT',
-- 
2.1.0




[Qemu-devel] [PATCH v8 15/40] qapi: Document new 'alternate' meta-type

2015-05-04 Thread Eric Blake
The next patch will quit special-casing 'union':'Foo',
'discriminator':{} and instead use 'alternate':'Foo'.

Separating docs from implementation makes it easier to focus
on wording without holding up code.  In particular, making
alternate a separate type makes for a nice type hierarchy:

  / meta-type --\
 /  |\
simple typesalternate complex types
| |   |   |
 built-in   enum type(struct)   union
 |   \//\
numeric  string simple  flat

A later patch will then clean up 'type' vs. 'struct'
confusion.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 docs/qapi-code-gen.txt | 57 +++---
 1 file changed, 36 insertions(+), 21 deletions(-)

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 6404a2d..588b110 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -85,11 +85,12 @@ the definition of complex structs that can have mutually 
recursive
 types, and allows for indefinite nesting of QMP that satisfies the
 schema.  A type name should not be defined more than once.

-There are six top-level expressions recognized by the parser:
-'include', 'command', 'type', 'enum', 'union', and 'event'.  There are
-several built-in types, such as 'int' and 'str'; additionally, the
-top-level expressions can define complex types, enumeration types, and
-several flavors of union types.  The 'command' and 'event' expressions
+There are seven top-level expressions recognized by the parser:
+'include', 'command', 'type', 'enum', 'union', 'alternate', and
+'event'.  There are several groups of types: simple types (a number of
+built-in types, such as 'int' and 'str'; as well as enumerations),
+complex types (structs and two flavors of unions), and alternate types
+(a choice between other types).  The 'command' and 'event' expressions
 can refer to existing types by name, or list an anonymous type as a
 dictionary. Listing a type name inside an array refers to a
 single-dimension array of that type; multi-dimension arrays are not
@@ -261,14 +262,12 @@ open-coding the field to be type 'str'.
 Usage: { 'union': STRING, 'data': DICT }
 or:{ 'union': STRING, 'data': DICT, 'base': COMPLEX-TYPE-NAME,
  'discriminator': ENUM-MEMBER-OF-BASE }
-or:{ 'union': STRING, 'data': DICT, 'discriminator': {} }

 Union types are used to let the user choose between several different
-variants for an object.  There are three flavors: simple (no
-discriminator or base), flat (both base and discriminator are
-strings), and anonymous (discriminator is an empty dictionary).  A
-union type is defined using a data dictionary as explained in the
-following paragraphs.
+variants for an object.  There are two flavors: simple (no
+discriminator or base), flat (both discriminator and base).  A union
+type is defined using a data dictionary as explained in the following
+paragraphs.

 A simple union type defines a mapping from automatic discriminator
 values to data types like in this example:
@@ -350,20 +349,36 @@ is identical on the wire to:
'data': { 'one': 'Branch1', 'two': 'Branch2' } }


-The final flavor of unions is an anonymous union. While the other two
-union types are always passed as a JSON object in the wire format, an
-anonymous union instead allows the direct use of different types in
-its place. Anonymous unions are declared using an empty dictionary as
-their discriminator. The discriminator values never appear on the
-wire, they are only used in the generated C code. Anonymous unions
-cannot have a base type.
+=== Alternate types ===

- { 'union': 'BlockRef',
-   'discriminator': {},
+Usage: { 'alternate': STRING, 'data': DICT }
+
+An alternate type is one that allows a choice between two or more JSON
+data types (string, integer, number, or object, but currently not
+array) on the wire.  The definition is similar to a simple union type,
+where each branch of the union names a QAPI type.  For example:
+
+ { 'alternate': 'BlockRef',
'data': { 'definition': 'BlockdevOptions',
  'reference': 'str' } }

-This example allows using both of the following example objects:
+Just like for a simple union, an implicit C enum 'NameKind' is created
+to enumerate the branches for the alternate 'Name'.
+
+Unlike a union, the discriminator string is never passed on the wire
+for QMP.  Instead, the value's JSON type serves as an implicit
+discriminator, which in turn means that an alternate can only express
+a choice between types represented differently in JSON.  If a branch
+is typed as the 'bool' built-in, the alternate accepts true and false;
+if it is typed as any of the various numeric built-ins, it accepts a
+JSON number; if it is typed as a 'str' built-in or named enum type, it
+accepts a JSON string; and if it is typed as a 

[Qemu-devel] [PATCH v8 11/40] qapi: Tighten checking of unions

2015-05-04 Thread Eric Blake
Previous commits demonstrated that the generator had several
flaws with less-than-perfect unions:
- a simple union that listed the same branch twice (or two variant
names that map to the same C enumerator, including the implicit
MAX sentinel) ended up generating invalid C code
- an anonymous union that listed two branches with the same qtype
ended up generating invalid C code
- the generator crashed on anonymous union attempts to use an
array type
- the generator was silently ignoring a base type for anonymous
unions
- the generator allowed unknown types or nested anonymous unions
as a branch in an anonymous union

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com

---

v7: improved comments in alternate-array
---
 scripts/qapi-types.py  | 13 +---
 scripts/qapi.py| 89 +-
 tests/qapi-schema/alternate-array.err  |  1 +
 tests/qapi-schema/alternate-array.exit |  2 +-
 tests/qapi-schema/alternate-array.json |  2 +-
 tests/qapi-schema/alternate-array.out  |  4 -
 tests/qapi-schema/alternate-base.err   |  1 +
 tests/qapi-schema/alternate-base.exit  |  2 +-
 tests/qapi-schema/alternate-base.json  |  2 +-
 tests/qapi-schema/alternate-base.out   |  4 -
 tests/qapi-schema/alternate-clash.err  |  1 +
 tests/qapi-schema/alternate-clash.exit |  2 +-
 tests/qapi-schema/alternate-clash.json |  2 +-
 tests/qapi-schema/alternate-clash.out  |  3 -
 tests/qapi-schema/alternate-conflict-dict.err  |  1 +
 tests/qapi-schema/alternate-conflict-dict.exit |  2 +-
 tests/qapi-schema/alternate-conflict-dict.json |  2 +-
 tests/qapi-schema/alternate-conflict-dict.out  |  6 --
 tests/qapi-schema/alternate-conflict-string.err|  1 +
 tests/qapi-schema/alternate-conflict-string.exit   |  2 +-
 tests/qapi-schema/alternate-conflict-string.json   |  2 +-
 tests/qapi-schema/alternate-conflict-string.out|  5 --
 tests/qapi-schema/alternate-nested.err |  1 +
 tests/qapi-schema/alternate-nested.exit|  2 +-
 tests/qapi-schema/alternate-nested.json|  2 +-
 tests/qapi-schema/alternate-nested.out |  5 --
 tests/qapi-schema/alternate-unknown.err|  1 +
 tests/qapi-schema/alternate-unknown.exit   |  2 +-
 tests/qapi-schema/alternate-unknown.json   |  2 +-
 tests/qapi-schema/alternate-unknown.out|  3 -
 tests/qapi-schema/flat-union-bad-base.err  |  2 +-
 tests/qapi-schema/flat-union-bad-base.json |  2 +-
 tests/qapi-schema/flat-union-bad-discriminator.err |  1 +
 .../qapi-schema/flat-union-bad-discriminator.exit  |  2 +-
 .../qapi-schema/flat-union-bad-discriminator.json  |  2 +-
 tests/qapi-schema/flat-union-bad-discriminator.out | 10 ---
 tests/qapi-schema/flat-union-inline.err|  2 +-
 tests/qapi-schema/flat-union-inline.json   |  2 +-
 tests/qapi-schema/flat-union-no-base.err   |  2 +-
 tests/qapi-schema/flat-union-no-base.json  |  2 +-
 tests/qapi-schema/union-bad-branch.err |  1 +
 tests/qapi-schema/union-bad-branch.exit|  2 +-
 tests/qapi-schema/union-bad-branch.json|  2 +-
 tests/qapi-schema/union-bad-branch.out |  6 --
 tests/qapi-schema/union-max.err|  1 +
 tests/qapi-schema/union-max.exit   |  2 +-
 tests/qapi-schema/union-max.json   |  2 +-
 tests/qapi-schema/union-max.out|  3 -
 48 files changed, 110 insertions(+), 103 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index f6fb930..2390887 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -181,17 +181,8 @@ const int %(name)s_qtypes[QTYPE_MAX] = {
 name=name)

 for key in members:
-qapi_type = members[key]
-if builtin_types.has_key(qapi_type):
-qtype = builtin_types[qapi_type]
-elif find_struct(qapi_type):
-qtype = QTYPE_QDICT
-elif find_union(qapi_type):
-qtype = QTYPE_QDICT
-elif find_enum(qapi_type):
-qtype = QTYPE_QSTRING
-else:
-assert False, Invalid anonymous union member
+qtype = find_anonymous_member_qtype(members[key])
+assert qtype, Invalid anonymous union member

 ret += mcgen('''
 [ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s,
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 438468e..5f0f699 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -224,6 +224,23 @@ def find_base_fields(base):
 return None
 return base_struct_define['data']

+# Return the qtype of an anonymous union branch, or None on error.
+def find_anonymous_member_qtype(qapi_type):
+if builtin_types.has_key(qapi_type):
+return builtin_types[qapi_type]
+elif 

[Qemu-devel] [PATCH v8 05/40] qapi: Require ASCII in schema

2015-05-04 Thread Eric Blake
Python 2 and Python 3 have a wild history of whether strings
default to ascii or unicode, where Python 3 requires checking
isinstance(foo, basestr) to cover all strings, but where that
code is not portable to Python 2.  It's simpler to just state
that we don't care about Unicode strings, and to just always
use the simpler isinstance(foo, str) everywhere.

I'm no python expert, so I'm basing it on this conversation:
https://lists.gnu.org/archive/html/qemu-devel/2014-09/msg05278.html

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 scripts/qapi.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index d470347..20ee505 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -2,7 +2,7 @@
 # QAPI helper library
 #
 # Copyright IBM, Corp. 2011
-# Copyright (c) 2013 Red Hat Inc.
+# Copyright (c) 2013-2015 Red Hat Inc.
 #
 # Authors:
 #  Anthony Liguori aligu...@us.ibm.com
@@ -354,7 +354,7 @@ def parse_schema(input_file):
 return exprs

 def parse_args(typeinfo):
-if isinstance(typeinfo, basestring):
+if isinstance(typeinfo, str):
 struct = find_struct(typeinfo)
 assert struct != None
 typeinfo = struct['data']
-- 
2.1.0




[Qemu-devel] [PATCH v8 07/40] qapi: Better error messages for bad enums

2015-05-04 Thread Eric Blake
The previous commit demonstrated that the generator had several
flaws with less-than-perfect enums:
- an enum that listed the same string twice (or two variant
strings that map to the same C enumerator) ended up generating
an invalid C enum
- because the generator adds a _MAX terminator to each enum,
the use of an enum member 'max' can also cause this clash
- if an enum omits 'data', the generator left a python stack
trace rather than a graceful message
- an enum that used a non-array 'data' was silently accepted by
the parser
- an enum that used non-string members in the 'data' member
was silently accepted by the parser

Add check_enum to cover these situations, and update testcases
to match.  While valid .json files won't trigger any of these
cases, we might as well be nicer to developers that make a typo
while trying to add new QAPI code.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com

---

v7: double the fix in enum-max-member comment
---
 scripts/qapi.py  | 34 +++-
 tests/qapi-schema/enum-clash-member.err  |  1 +
 tests/qapi-schema/enum-clash-member.exit |  2 +-
 tests/qapi-schema/enum-clash-member.json |  2 +-
 tests/qapi-schema/enum-clash-member.out  |  3 ---
 tests/qapi-schema/enum-dict-member.err   |  1 +
 tests/qapi-schema/enum-dict-member.exit  |  2 +-
 tests/qapi-schema/enum-dict-member.json  |  2 +-
 tests/qapi-schema/enum-dict-member.out   |  3 ---
 tests/qapi-schema/enum-max-member.err|  1 +
 tests/qapi-schema/enum-max-member.exit   |  2 +-
 tests/qapi-schema/enum-max-member.json   |  2 +-
 tests/qapi-schema/enum-max-member.out|  3 ---
 tests/qapi-schema/enum-missing-data.err  |  7 +--
 tests/qapi-schema/enum-missing-data.json |  2 +-
 tests/qapi-schema/enum-wrong-data.err|  1 +
 tests/qapi-schema/enum-wrong-data.exit   |  2 +-
 tests/qapi-schema/enum-wrong-data.json   |  2 +-
 tests/qapi-schema/enum-wrong-data.out|  3 ---
 19 files changed, 43 insertions(+), 32 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 20ee505..3ce8c33 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -311,13 +311,37 @@ def check_union(expr, expr_info):
 # Todo: add checking for values. Key is checked as above, value can be
 # also checked here, but we need more functions to handle array case.

+def check_enum(expr, expr_info):
+name = expr['enum']
+members = expr.get('data')
+values = { 'MAX': '(automatic)' }
+
+if not isinstance(members, list):
+raise QAPIExprError(expr_info,
+Enum '%s' requires an array for 'data' % name)
+for member in members:
+if not isinstance(member, str):
+raise QAPIExprError(expr_info,
+Enum '%s' member '%s' is not a string
+% (name, member))
+key = _generate_enum_string(member)
+if key in values:
+raise QAPIExprError(expr_info,
+Enum '%s' member '%s' clashes with '%s'
+% (name, member, values[key]))
+values[key] = member
+
 def check_exprs(schema):
 for expr_elem in schema.exprs:
 expr = expr_elem['expr']
-if expr.has_key('union'):
-check_union(expr, expr_elem['info'])
-if expr.has_key('event'):
-check_event(expr, expr_elem['info'])
+info = expr_elem['info']
+
+if expr.has_key('enum'):
+check_enum(expr, info)
+elif expr.has_key('union'):
+check_union(expr, info)
+elif expr.has_key('event'):
+check_event(expr, info)

 def parse_schema(input_file):
 try:
@@ -331,7 +355,7 @@ def parse_schema(input_file):
 for expr_elem in schema.exprs:
 expr = expr_elem['expr']
 if expr.has_key('enum'):
-add_enum(expr['enum'], expr['data'])
+add_enum(expr['enum'], expr.get('data'))
 elif expr.has_key('union'):
 add_union(expr)
 elif expr.has_key('type'):
diff --git a/tests/qapi-schema/enum-clash-member.err 
b/tests/qapi-schema/enum-clash-member.err
index e69de29..48bd136 100644
--- a/tests/qapi-schema/enum-clash-member.err
+++ b/tests/qapi-schema/enum-clash-member.err
@@ -0,0 +1 @@
+tests/qapi-schema/enum-clash-member.json:2: Enum 'MyEnum' member 'ONE' clashes 
with 'one'
diff --git a/tests/qapi-schema/enum-clash-member.exit 
b/tests/qapi-schema/enum-clash-member.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/enum-clash-member.exit
+++ b/tests/qapi-schema/enum-clash-member.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/enum-clash-member.json 
b/tests/qapi-schema/enum-clash-member.json
index 99d442a..b7dc02a 100644
--- a/tests/qapi-schema/enum-clash-member.json
+++ b/tests/qapi-schema/enum-clash-member.json
@@ -1,2 +1,2 @@
-# FIXME: we should reject enums where members will clash when mapped to C enum
+# we 

[Qemu-devel] [PATCH v8 31/40] qapi: Forbid 'type' in schema

2015-05-04 Thread Eric Blake
Referring to type as both a meta-type (built-in, enum, union,
alternate, or struct) and a specific type (the name that the
schema uses for declaring structs) is confusing.  Finish up the
conversion to using struct in qapi schema by removing the hack
in the generator that allowed 'type'.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com

---

v7: split from the previous patch
---
 scripts/qapi.py | 14 --
 1 file changed, 14 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index ff337c2..ff53360 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -617,20 +617,6 @@ def parse_schema(input_file):
 for expr_elem in schema.exprs:
 expr = expr_elem['expr']
 info = expr_elem['info']
-
-# back-compat hack until all schemas have been converted;
-# preserve the ordering of the original expression
-if expr.has_key('type'):
-seen_type = False
-for (key, value) in expr.items():
-if key == 'type':
-seen_type = True
-del expr['type']
-expr['struct'] = value
-elif seen_type:
-del expr[key]
-expr[key] = value
-
 if expr.has_key('enum'):
 check_keys(expr_elem, 'enum', ['data'])
 add_enum(expr['enum'], info, expr['data'])
-- 
2.1.0




[Qemu-devel] [PATCH v8 10/40] qapi: Forbid base without discriminator in unions

2015-05-04 Thread Eric Blake
None of the existing QMP or QGA interfaces uses a union with a
base type but no discriminator; it is easier to avoid this in the
generator to save room for other future extensions more likely to
be useful.  An earlier commit added a union-base-no-discriminator
test to ensure that we eventually give a decent error message;
likewise, removing UserDefUnion outright is okay, because we moved
all the tests we wish to keep into the tests of the simple union
UserDefNativeListUnion in the previous commit.  Now is the time to
actually forbid simple union with base, and remove the last
vestiges from the testsuite.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com

---

v7: improve commit message
---
 scripts/qapi-types.py  |  7 ++---
 scripts/qapi-visit.py  | 11 +++
 scripts/qapi.py| 20 ++--
 tests/qapi-schema/qapi-schema-test.json|  4 ---
 tests/qapi-schema/qapi-schema-test.out |  2 --
 tests/qapi-schema/union-base-no-discriminator.err  |  1 +
 tests/qapi-schema/union-base-no-discriminator.exit |  2 +-
 tests/qapi-schema/union-base-no-discriminator.json |  2 +-
 tests/qapi-schema/union-base-no-discriminator.out  |  8 -
 tests/test-qmp-input-visitor.c | 19 
 tests/test-qmp-output-visitor.c| 36 --
 11 files changed, 21 insertions(+), 91 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index e400b03..f6fb930 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -242,10 +242,9 @@ struct %(name)s
 ''')

 if base:
-base_fields = find_struct(base)['data']
-if discriminator:
-base_fields = base_fields.copy()
-del base_fields[discriminator]
+assert discriminator
+base_fields = find_struct(base)['data'].copy()
+del base_fields[discriminator]
 ret += generate_struct_fields(base_fields)
 else:
 assert not discriminator
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 41596bb..dbf0101 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -310,16 +310,15 @@ def generate_visit_union(expr):
 ret = 
 disc_type = enum_define['enum_name']
 else:
-# There will always be a discriminator in the C switch code, by 
default it
-# is an enum type generated silently as '%sKind' % (name)
+# There will always be a discriminator in the C switch code, by default
+# it is an enum type generated silently as '%sKind' % (name)
 ret = generate_visit_enum('%sKind' % name, members.keys())
 disc_type = '%sKind' % (name)

 if base:
-base_fields = find_struct(base)['data']
-if discriminator:
-base_fields = base_fields.copy()
-del base_fields[discriminator]
+assert discriminator
+base_fields = find_struct(base)['data'].copy()
+del base_fields[discriminator]
 ret += generate_visit_struct_fields(name, , , base_fields)

 if discriminator:
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 3ce8c33..438468e 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -259,22 +259,22 @@ def check_union(expr, expr_info):
 discriminator = expr.get('discriminator')
 members = expr['data']

-# If the object has a member 'base', its value must name a complex type.
-if base:
+# If the object has a member 'base', its value must name a complex type,
+# and there must be a discriminator.
+if base is not None:
+if discriminator is None:
+raise QAPIExprError(expr_info,
+Union '%s' requires a discriminator to go 
+along with base %name)
 base_fields = find_base_fields(base)
 if not base_fields:
 raise QAPIExprError(expr_info,
 Base '%s' is not a valid type
 % base)

-# If the union object has no member 'discriminator', it's an
-# ordinary union.
-if not discriminator:
-enum_define = None
-
-# Else if the value of member 'discriminator' is {}, it's an
-# anonymous union.
-elif discriminator == {}:
+# If the union object has no member 'discriminator', it's a
+# simple union. If 'discriminator' is {}, it is an anonymous union.
+if not discriminator or discriminator == {}:
 enum_define = None

 # Else, it's a flat union.
diff --git a/tests/qapi-schema/qapi-schema-test.json 
b/tests/qapi-schema/qapi-schema-test.json
index 84f0f07..b134f3f 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -36,10 +36,6 @@
 { 'type': 'UserDefC',
   'data': { 'string1': 'str', 'string2': 'str' } }

-{ 'union': 'UserDefUnion',
-  'base': 'UserDefZero',
-  

[Qemu-devel] [PATCH v8 09/40] qapi: Clean up test coverage of simple unions

2015-05-04 Thread Eric Blake
The tests of UserDefNativeListUnion serve to validate code
generation of simple unions without a base type, except that it
did not have full coverage in the strict test.  The next commits
will remove tests and support for simple unions with a base type,
so there is no real loss at repurposing that test here as
opposed to churn of adding a new test then deleting the old one.

Fix some indentation and long lines while at it.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 tests/test-qmp-input-strict.c   | 57 +++---
 tests/test-qmp-input-visitor.c  | 61 +
 tests/test-qmp-output-visitor.c | 38 -
 3 files changed, 86 insertions(+), 70 deletions(-)

diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index d5360c6..486848e 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -1,7 +1,7 @@
 /*
  * QMP Input Visitor unit-tests (strict mode).
  *
- * Copyright (C) 2011-2012 Red Hat Inc.
+ * Copyright (C) 2011-2012, 2015 Red Hat Inc.
  *
  * Authors:
  *  Luiz Capitulino lcapitul...@redhat.com
@@ -141,18 +141,18 @@ static void test_validate_list(TestInputVisitorData *data,
 qapi_free_UserDefOneList(head);
 }

-static void test_validate_union(TestInputVisitorData *data,
- const void *unused)
+static void test_validate_union_native_list(TestInputVisitorData *data,
+const void *unused)
 {
-UserDefUnion *tmp = NULL;
+UserDefNativeListUnion *tmp = NULL;
 Visitor *v;
 Error *err = NULL;

-v = validate_test_init(data, { 'type': 'b', 'integer': 41, 'data' : { 
'integer': 42 } });
+v = validate_test_init(data, { 'type': 'integer', 'data' : [ 1, 2 ] });

-visit_type_UserDefUnion(v, tmp, NULL, err);
+visit_type_UserDefNativeListUnion(v, tmp, NULL, err);
 g_assert(!err);
-qapi_free_UserDefUnion(tmp);
+qapi_free_UserDefNativeListUnion(tmp);
 }

 static void test_validate_union_flat(TestInputVisitorData *data,
@@ -232,18 +232,19 @@ static void test_validate_fail_list(TestInputVisitorData 
*data,
 qapi_free_UserDefOneList(head);
 }

-static void test_validate_fail_union(TestInputVisitorData *data,
-  const void *unused)
+static void test_validate_fail_union_native_list(TestInputVisitorData *data,
+ const void *unused)
 {
-UserDefUnion *tmp = NULL;
+UserDefNativeListUnion *tmp = NULL;
 Error *err = NULL;
 Visitor *v;

-v = validate_test_init(data, { 'type': 'b', 'data' : { 'integer': 42 } 
});
+v = validate_test_init(data,
+   { 'type': 'integer', 'data' : [ 'string' ] });

-visit_type_UserDefUnion(v, tmp, NULL, err);
+visit_type_UserDefNativeListUnion(v, tmp, NULL, err);
 g_assert(err);
-qapi_free_UserDefUnion(tmp);
+qapi_free_UserDefNativeListUnion(tmp);
 }

 static void test_validate_fail_union_flat(TestInputVisitorData *data,
@@ -304,31 +305,31 @@ int main(int argc, char **argv)
 g_test_init(argc, argv, NULL);

 validate_test_add(/visitor/input-strict/pass/struct,
-   testdata, test_validate_struct);
+  testdata, test_validate_struct);
 validate_test_add(/visitor/input-strict/pass/struct-nested,
-   testdata, test_validate_struct_nested);
+  testdata, test_validate_struct_nested);
 validate_test_add(/visitor/input-strict/pass/list,
-   testdata, test_validate_list);
-validate_test_add(/visitor/input-strict/pass/union,
-   testdata, test_validate_union);
+  testdata, test_validate_list);
 validate_test_add(/visitor/input-strict/pass/union-flat,
-   testdata, test_validate_union_flat);
+  testdata, test_validate_union_flat);
 validate_test_add(/visitor/input-strict/pass/union-anon,
-   testdata, test_validate_union_anon);
+  testdata, test_validate_union_anon);
+validate_test_add(/visitor/input-strict/pass/union-native-list,
+  testdata, test_validate_union_native_list);
 validate_test_add(/visitor/input-strict/fail/struct,
-   testdata, test_validate_fail_struct);
+  testdata, test_validate_fail_struct);
 validate_test_add(/visitor/input-strict/fail/struct-nested,
-   testdata, test_validate_fail_struct_nested);
+  testdata, test_validate_fail_struct_nested);
 validate_test_add(/visitor/input-strict/fail/list,
-   testdata, test_validate_fail_list);
-validate_test_add(/visitor/input-strict/fail/union,
-   testdata, test_validate_fail_union);
+ 

[Qemu-devel] [PATCH v8 27/40] qapi: More rigorous checking for type safety bypass

2015-05-04 Thread Eric Blake
Now that we have a way to validate every type, we can also be
stricter about enforcing that callers that want to bypass
type safety in generated code.  Prior to this patch, it didn't
matter what value was associated with the key 'gen', but it
looked odd that 'gen':'yes' could result in bypassing the
generated code.  These changes also enforce the changes made
earlier in the series for documentation and consolidation of
using '**' as the wildcard type, as well as 'gen':false as the
canonical spelling for requesting type bypass.

Note that 'gen':false is a one-way switch away from the default;
we do not support 'gen':true (similar for 'success-response').
In practice, this doesn't matter.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com

---

v7: fix typo in commit message
---
 scripts/qapi.py| 22 +-
 tests/qapi-schema/type-bypass-bad-gen.err  |  1 +
 tests/qapi-schema/type-bypass-bad-gen.exit |  2 +-
 tests/qapi-schema/type-bypass-bad-gen.json |  2 +-
 tests/qapi-schema/type-bypass-bad-gen.out  |  3 ---
 tests/qapi-schema/type-bypass-no-gen.err   |  1 +
 tests/qapi-schema/type-bypass-no-gen.exit  |  2 +-
 tests/qapi-schema/type-bypass-no-gen.json  |  2 +-
 tests/qapi-schema/type-bypass-no-gen.out   |  3 ---
 9 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index b218ee5..07ae141 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -324,14 +324,15 @@ def check_name(expr_info, source, name, allow_optional = 
False,
 %s uses invalid name '%s' % (source, name))

 def check_type(expr_info, source, value, allow_array = False,
-   allow_dict = False, allow_optional = False, allow_metas = []):
+   allow_dict = False, allow_optional = False,
+   allow_star = False, allow_metas = []):
 global all_names
 orig_value = value

 if value is None:
 return

-if value == '**':
+if allow_star and value == '**':
 return

 # Check if array type for value is okay
@@ -348,6 +349,10 @@ def check_type(expr_info, source, value, allow_array = 
False,

 # Check if type name for value is okay
 if isinstance(value, str):
+if value == '**':
+raise QAPIExprError(expr_info,
+%s uses '**' but did not request 'gen':false
+% source)
 if not value in all_names:
 raise QAPIExprError(expr_info,
 %s uses unknown type '%s'
@@ -371,19 +376,22 @@ def check_type(expr_info, source, value, allow_array = 
False,
 check_type(expr_info, Member '%s' of %s % (key, source), arg,
allow_array=True, allow_dict=True, allow_optional=True,
allow_metas=['built-in', 'union', 'alternate', 'struct',
-'enum'])
+'enum'], allow_star=allow_star)

 def check_command(expr, expr_info):
 name = expr['command']
+allow_star = expr.has_key('gen')
+
 check_type(expr_info, 'data' for command '%s' % name,
expr.get('data'), allow_dict=True, allow_optional=True,
-   allow_metas=['union', 'struct'])
+   allow_metas=['union', 'struct'], allow_star=allow_star)
 returns_meta = ['union', 'struct']
 if name in returns_whitelist:
 returns_meta += ['built-in', 'alternate', 'enum']
 check_type(expr_info, 'returns' for command '%s' % name,
expr.get('returns'), allow_array=True, allow_dict=True,
-   allow_optional=True, allow_metas=returns_meta)
+   allow_optional=True, allow_metas=returns_meta,
+   allow_star=allow_star)

 def check_event(expr, expr_info):
 global events
@@ -579,6 +587,10 @@ def check_keys(expr_elem, meta, required, optional=[]):
 raise QAPIExprError(info,
 Unknown key '%s' in %s '%s'
 % (key, meta, name))
+if (key == 'gen' or key == 'success-response') and value != False:
+raise QAPIExprError(info,
+'%s' of %s '%s' should only use false value
+% (key, meta, name))
 for key in required:
 if not expr.has_key(key):
 raise QAPIExprError(info,
diff --git a/tests/qapi-schema/type-bypass-bad-gen.err 
b/tests/qapi-schema/type-bypass-bad-gen.err
index e69de29..a83c3c6 100644
--- a/tests/qapi-schema/type-bypass-bad-gen.err
+++ b/tests/qapi-schema/type-bypass-bad-gen.err
@@ -0,0 +1 @@
+tests/qapi-schema/type-bypass-bad-gen.json:2: 'gen' of command 'foo' should 
only use false value
diff --git a/tests/qapi-schema/type-bypass-bad-gen.exit 
b/tests/qapi-schema/type-bypass-bad-gen.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/type-bypass-bad-gen.exit
+++ 

[Qemu-devel] [PATCH v8 28/40] qapi: Prefer 'struct' over 'type' in generator

2015-05-04 Thread Eric Blake
Referring to type as both a meta-type (built-in, enum, union,
alternate, or struct) and a specific type (the name that the
schema uses for declaring structs) is confusing.  The confusion
is only made worse by the fact that the generator mostly already
refers to struct even when dealing with expr['type'].  This
commit changes the generator to consistently refer to it as
struct everywhere, plus a single back-compat tweak that allows
accepting the existing .json files as-is, so that the meat of
this change is separate from the mindless churn of that change.

Fix the testsuite fallout for error messages that change, and
in some cases, become more legible.  Improve comments to better
match our intentions where a struct (rather than any complex
type) is required.  Note that in some cases, an error message
now refers to 'struct' while the schema still refers to 'type';
that will be cleaned up in the later commit to the schema.

Signed-off-by: Eric Blake ebl...@redhat.com

---

v7: enhance commit message; change check_struct() to refer to 'struct'
rather than 'type'; update a few more comments at this point (enough
fallout that I dropped Markus' R-b)
---
 scripts/qapi-types.py  | 16 
 scripts/qapi-visit.py  |  8 ++--
 scripts/qapi.py| 46 ++
 tests/qapi-schema/alternate-good.out   |  4 +-
 tests/qapi-schema/bad-base.err |  2 +-
 tests/qapi-schema/bad-ident.err|  2 +-
 tests/qapi-schema/bad-type-bool.err|  2 +-
 tests/qapi-schema/data-member-array.out|  4 +-
 tests/qapi-schema/double-type.err  |  2 +-
 tests/qapi-schema/flat-union-bad-base.json |  2 +-
 tests/qapi-schema/flat-union-base-star.err |  2 +-
 tests/qapi-schema/flat-union-base-star.json|  2 +-
 tests/qapi-schema/flat-union-base-union.err|  2 +-
 tests/qapi-schema/flat-union-base-union.json   |  2 +-
 tests/qapi-schema/flat-union-branch-clash.out  | 12 +++---
 tests/qapi-schema/flat-union-inline.json   |  2 +-
 tests/qapi-schema/flat-union-int-branch.json   |  2 +-
 .../flat-union-invalid-discriminator.err   |  2 +-
 tests/qapi-schema/flat-union-reverse-define.out| 12 +++---
 tests/qapi-schema/qapi-schema-test.out | 44 ++---
 tests/qapi-schema/union-invalid-base.err   |  2 +-
 tests/qapi-schema/unknown-expr-key.err |  2 +-
 22 files changed, 93 insertions(+), 81 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 9c8d68c..a429d9e 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -83,7 +83,7 @@ def generate_struct_fields(members):

 def generate_struct(expr):

-structname = expr.get('type', )
+structname = expr.get('struct', )
 fieldname = expr.get('field', )
 members = expr['data']
 base = expr.get('base')
@@ -394,8 +394,8 @@ fdecl.write(guardend(QAPI_TYPES_BUILTIN_STRUCT_DECL))

 for expr in exprs:
 ret = \n
-if expr.has_key('type'):
-ret += generate_fwd_struct(expr['type'], expr['data'])
+if expr.has_key('struct'):
+ret += generate_fwd_struct(expr['struct'], expr['data'])
 elif expr.has_key('enum'):
 ret += generate_enum(expr['enum'], expr['data']) + \n
 ret += generate_fwd_enum_struct(expr['enum'], expr['data'])
@@ -435,12 +435,12 @@ if do_builtins:

 for expr in exprs:
 ret = \n
-if expr.has_key('type'):
+if expr.has_key('struct'):
 ret += generate_struct(expr) + \n
-ret += generate_type_cleanup_decl(expr['type'] + List)
-fdef.write(generate_type_cleanup(expr['type'] + List) + \n)
-ret += generate_type_cleanup_decl(expr['type'])
-fdef.write(generate_type_cleanup(expr['type']) + \n)
+ret += generate_type_cleanup_decl(expr['struct'] + List)
+fdef.write(generate_type_cleanup(expr['struct'] + List) + \n)
+ret += generate_type_cleanup_decl(expr['struct'])
+fdef.write(generate_type_cleanup(expr['struct']) + \n)
 elif expr.has_key('union'):
 ret += generate_union(expr, 'union')
 ret += generate_type_cleanup_decl(expr['union'] + List)
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 9222671..c739a95 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -178,7 +178,7 @@ def generate_visit_struct_body(field_prefix, name, members):

 def generate_visit_struct(expr):

-name = expr['type']
+name = expr['struct']
 members = expr['data']
 base = expr.get('base')

@@ -545,12 +545,12 @@ if do_builtins:
 fdef.write(generate_visit_list(typename, None))

 for expr in exprs:
-if expr.has_key('type'):
+if expr.has_key('struct'):
 ret = generate_visit_struct(expr)
-ret += generate_visit_list(expr['type'], expr['data'])
+ret += 

[Qemu-devel] [PATCH v8 21/40] qapi: Allow true, false and null in schema json

2015-05-04 Thread Eric Blake
From: Fam Zheng f...@redhat.com

In the near term, we will use it for a sensible-looking
'gen':false inside command declarations, instead of the
current ugly 'gen':'no'.

In the long term, it will allow conversion from shorthand
with defaults mentioned only in side-band documentation:
 'data':{'*flag':'bool', '*string':'str'}
into an explicit default value documentation, as in:
 'data':{'flag':{'type':'bool', 'optional':true, 'default':true},
 'string':{'type':'str', 'optional':true, 'default':null}}

We still don't parse integer values (also necessary before
we can allow explicit defaults), but that can come in a later
series.

Update the testsuite to match an improved error message.

Signed-off-by: Fam Zheng f...@redhat.com
Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 scripts/qapi.py  | 21 ++---
 tests/qapi-schema/bad-type-bool.err  |  2 +-
 tests/qapi-schema/bad-type-bool.json |  1 -
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index eea0976..686bc86 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -158,6 +158,20 @@ class QAPISchema:
 return
 else:
 string += ch
+elif self.tok in tfn:
+val = self.src[self.cursor - 1:]
+if val.startswith(true):
+self.val = True
+self.cursor += 3
+return
+elif val.startswith(false):
+self.val = False
+self.cursor += 4
+return
+elif val.startswith(null):
+self.val = None
+self.cursor += 3
+return
 elif self.tok == '\n':
 if self.cursor == len(self.src):
 self.tok = None
@@ -197,8 +211,9 @@ class QAPISchema:
 if self.tok == ']':
 self.accept()
 return expr
-if not self.tok in [ '{', '[', ' ]:
-raise QAPISchemaError(self, 'Expected {, [, ] or string')
+if not self.tok in {['tfn:
+raise QAPISchemaError(self, 'Expected {, [, ], string, '
+  'boolean or null')
 while True:
 expr.append(self.get_expr(True))
 if self.tok == ']':
@@ -217,7 +232,7 @@ class QAPISchema:
 elif self.tok == '[':
 self.accept()
 expr = self.get_values()
-elif self.tok == ':
+elif self.tok in 'tfn:
 expr = self.val
 self.accept()
 else:
diff --git a/tests/qapi-schema/bad-type-bool.err 
b/tests/qapi-schema/bad-type-bool.err
index badb7c2..de6168c 100644
--- a/tests/qapi-schema/bad-type-bool.err
+++ b/tests/qapi-schema/bad-type-bool.err
@@ -1 +1 @@
-tests/qapi-schema/bad-type-bool.json:3:11: Stray t
+tests/qapi-schema/bad-type-bool.json:2: 'type' key must have a string value
diff --git a/tests/qapi-schema/bad-type-bool.json 
b/tests/qapi-schema/bad-type-bool.json
index 22d6369..e1e9fb0 100644
--- a/tests/qapi-schema/bad-type-bool.json
+++ b/tests/qapi-schema/bad-type-bool.json
@@ -1,3 +1,2 @@
 # we reject an expression with a metatype that is not a string
-# FIXME: once the parser understands bool inputs, improve the error message
 { 'type': true, 'data': { } }
-- 
2.1.0




[Qemu-devel] [PATCH v8 36/40] qapi: Drop support for inline nested types

2015-05-04 Thread Eric Blake
A future patch will be using a 'name':{dictionary} entry in the
QAPI schema to specify a default value for an optional argument
(see previous commit messages for more details why); but existing
use of inline nested structs conflicts with that goal. Now that
all commands have been changed to avoid inline nested structs,
nuke support for them, and turn it into a hard error. Update the
testsuite to reflect tighter parsing rules.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 scripts/qapi-commands.py |  8 +++---
 scripts/qapi-event.py|  4 +--
 scripts/qapi-types.py|  9 ++-
 scripts/qapi-visit.py| 37 
 scripts/qapi.py  | 20 ++-
 tests/qapi-schema/event-nest-struct.err  |  2 +-
 tests/qapi-schema/nested-struct-data.err |  1 +
 tests/qapi-schema/nested-struct-data.exit|  2 +-
 tests/qapi-schema/nested-struct-data.json|  2 +-
 tests/qapi-schema/nested-struct-data.out |  3 ---
 tests/qapi-schema/nested-struct-returns.err  |  1 +
 tests/qapi-schema/nested-struct-returns.exit |  2 +-
 tests/qapi-schema/nested-struct-returns.json |  2 +-
 tests/qapi-schema/nested-struct-returns.out  |  3 ---
 14 files changed, 27 insertions(+), 69 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index cb78682..93e43f0 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -28,7 +28,7 @@ def type_visitor(name):

 def generate_command_decl(name, args, ret_type):
 arglist=
-for argname, argtype, optional, structured in parse_args(args):
+for argname, argtype, optional in parse_args(args):
 argtype = c_type(argtype, is_param=True)
 if optional:
 arglist += bool has_%s,  % c_var(argname)
@@ -53,7 +53,7 @@ def gen_sync_call(name, args, ret_type, indent=0):
 retval=
 if ret_type:
 retval = retval = 
-for argname, argtype, optional, structured in parse_args(args):
+for argname, argtype, optional in parse_args(args):
 if optional:
 arglist += has_%s,  % c_var(argname)
 arglist += %s,  % (c_var(argname))
@@ -96,7 +96,7 @@ Visitor *v;
 def gen_visitor_input_vars_decl(args):
 ret = 
 push_indent()
-for argname, argtype, optional, structured in parse_args(args):
+for argname, argtype, optional in parse_args(args):
 if optional:
 ret += mcgen('''
 bool has_%(argname)s = false;
@@ -139,7 +139,7 @@ v = qapi_dealloc_get_visitor(md);
 v = qmp_input_get_visitor(mi);
 ''')

-for argname, argtype, optional, structured in parse_args(args):
+for argname, argtype, optional in parse_args(args):
 if optional:
 ret += mcgen('''
 visit_optional(v, has_%(c_name)s, %(name)s, %(errp)s);
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 601e307..47dc041 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -21,7 +21,7 @@ def _generate_event_api_name(event_name, params):
 l = len(api_name)

 if params:
-for argname, argentry, optional, structured in parse_args(params):
+for argname, argentry, optional in parse_args(params):
 if optional:
 api_name += bool has_%s,\n % c_var(argname)
 api_name += .ljust(l)
@@ -93,7 +93,7 @@ def generate_event_implement(api_name, event_name, params):
 ,
 event_name = event_name)

-for argname, argentry, optional, structured in parse_args(params):
+for argname, argentry, optional in parse_args(params):
 if optional:
 ret += mcgen(
 if (has_%(var)s) {
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index a429d9e..2bf8145 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -63,18 +63,13 @@ typedef struct %(name)sList
 def generate_struct_fields(members):
 ret = ''

-for argname, argentry, optional, structured in parse_args(members):
+for argname, argentry, optional in parse_args(members):
 if optional:
 ret += mcgen('''
 bool has_%(c_name)s;
 ''',
  c_name=c_var(argname))
-if structured:
-push_indent()
-ret += generate_struct({ field: argname, data: argentry})
-pop_indent()
-else:
-ret += mcgen('''
+ret += mcgen('''
 %(c_type)s %(c_name)s;
 ''',
  c_type=c_type(argentry), c_name=c_var(argname))
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index c739a95..6156162 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -51,27 +51,6 @@ def generate_visit_struct_fields(name, field_prefix, 
fn_prefix, members, base =
 else:
 full_name = %s_%s % (name, fn_prefix)

-for argname, argentry, optional, structured in parse_args(members):
-

[Qemu-devel] [PATCH v8 14/40] qapi: Rename anonymous union type in test

2015-05-04 Thread Eric Blake
Reduce churn in the future patch that replaces anonymous unions
with a new metatype 'alternate' by changing 'AnonUnion' to
'Alternate'.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 tests/qapi-schema/qapi-schema-test.json |  2 +-
 tests/qapi-schema/qapi-schema-test.out  |  4 ++--
 tests/test-qmp-input-strict.c   | 28 ++--
 tests/test-qmp-input-visitor.c  | 16 
 tests/test-qmp-output-visitor.c | 16 
 5 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/tests/qapi-schema/qapi-schema-test.json 
b/tests/qapi-schema/qapi-schema-test.json
index b134f3f..e1d35e1 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -53,7 +53,7 @@
   'discriminator': 'enum1',
   'data': { 'value1' : 'UserDefC', 'value2' : 'UserDefB', 'value3' : 
'UserDefA' } }

-{ 'union': 'UserDefAnonUnion',
+{ 'union': 'UserDefAlternate',
   'discriminator': {},
   'data': { 'uda': 'UserDefA', 's': 'str', 'i': 'int' } }

diff --git a/tests/qapi-schema/qapi-schema-test.out 
b/tests/qapi-schema/qapi-schema-test.out
index 664ae7b..b55ab8d 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -10,7 +10,7 @@
  OrderedDict([('type', 'UserDefUnionBase'), ('data', OrderedDict([('string', 
'str'), ('enum1', 'EnumOne')]))]),
  OrderedDict([('union', 'UserDefFlatUnion'), ('base', 'UserDefUnionBase'), 
('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefA'), 
('value2', 'UserDefB'), ('value3', 'UserDefB')]))]),
  OrderedDict([('union', 'UserDefFlatUnion2'), ('base', 'UserDefUnionBase'), 
('discriminator', 'enum1'), ('data', OrderedDict([('value1', 'UserDefC'), 
('value2', 'UserDefB'), ('value3', 'UserDefA')]))]),
- OrderedDict([('union', 'UserDefAnonUnion'), ('discriminator', OrderedDict()), 
('data', OrderedDict([('uda', 'UserDefA'), ('s', 'str'), ('i', 'int')]))]),
+ OrderedDict([('union', 'UserDefAlternate'), ('discriminator', OrderedDict()), 
('data', OrderedDict([('uda', 'UserDefA'), ('s', 'str'), ('i', 'int')]))]),
  OrderedDict([('union', 'UserDefNativeListUnion'), ('data', 
OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), 
('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), 
('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', 
['bool']), ('string', ['str']), ('sizes', ['size'])]))]),
  OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
  OrderedDict([('command', 'user_def_cmd1'), ('data', OrderedDict([('ud1a', 
'UserDefOne')]))]),
@@ -23,7 +23,7 @@
  OrderedDict([('event', 'EVENT_C'), ('data', OrderedDict([('*a', 'int'), 
('*b', 'UserDefOne'), ('c', 'str')]))]),
  OrderedDict([('event', 'EVENT_D'), ('data', OrderedDict([('a', 
'EventStructOne'), ('b', 'str'), ('*c', 'str'), ('*enum3', 'EnumOne')]))])]
 [{'enum_name': 'EnumOne', 'enum_values': ['value1', 'value2', 'value3']},
- {'enum_name': 'UserDefAnonUnionKind', 'enum_values': None},
+ {'enum_name': 'UserDefAlternateKind', 'enum_values': None},
  {'enum_name': 'UserDefNativeListUnionKind', 'enum_values': None}]
 [OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 
'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 
'EnumOne')]))]),
  OrderedDict([('type', 'UserDefZero'), ('data', OrderedDict([('integer', 
'int')]))]),
diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index 486848e..a5f7bf3 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -173,18 +173,18 @@ static void test_validate_union_flat(TestInputVisitorData 
*data,
 qapi_free_UserDefFlatUnion(tmp);
 }

-static void test_validate_union_anon(TestInputVisitorData *data,
- const void *unused)
+static void test_validate_alternate(TestInputVisitorData *data,
+const void *unused)
 {
-UserDefAnonUnion *tmp = NULL;
+UserDefAlternate *tmp = NULL;
 Visitor *v;
 Error *err = NULL;

 v = validate_test_init(data, 42);

-visit_type_UserDefAnonUnion(v, tmp, NULL, err);
+visit_type_UserDefAlternate(v, tmp, NULL, err);
 g_assert(!err);
-qapi_free_UserDefAnonUnion(tmp);
+qapi_free_UserDefAlternate(tmp);
 }

 static void test_validate_fail_struct(TestInputVisitorData *data,
@@ -276,18 +276,18 @@ static void 
test_validate_fail_union_flat_no_discrim(TestInputVisitorData *data,
 qapi_free_UserDefFlatUnion2(tmp);
 }

-static void test_validate_fail_union_anon(TestInputVisitorData *data,
-  const void *unused)
+static void test_validate_fail_alternate(TestInputVisitorData *data,
+ const void *unused)
 {
-UserDefAnonUnion *tmp = NULL;
+UserDefAlternate *tmp = NULL;
 Visitor *v;
 Error *err = NULL;

 v = 

[Qemu-devel] [PATCH v8 29/40] qapi: Document 'struct' metatype

2015-05-04 Thread Eric Blake
Referring to type as both a meta-type (built-in, enum, union,
alternate, or struct) and a specific type (the name that the
schema uses for declaring structs) is confusing.  Now that the
generator accepts 'struct' as a synonym for 'type', update all
documentation to use saner wording.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com

---

v7: fix typo in commit message, s/complex type/struct/ in documenting
relation of simple union to flat union
---
 docs/qapi-code-gen.txt | 58 +-
 1 file changed, 29 insertions(+), 29 deletions(-)

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 588b110..a874a6d 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -72,7 +72,7 @@ x.y.z)' comment.  For example:
 #
 # Since: 0.14.0
 ##
-{ 'type': 'BlockStats',
+{ 'struct': 'BlockStats',
   'data': {'*device': 'str', 'stats': 'BlockDeviceStats',
'*parent': 'BlockStats',
'*backing': 'BlockStats'} }
@@ -86,7 +86,7 @@ types, and allows for indefinite nesting of QMP that 
satisfies the
 schema.  A type name should not be defined more than once.

 There are seven top-level expressions recognized by the parser:
-'include', 'command', 'type', 'enum', 'union', 'alternate', and
+'include', 'command', 'struct', 'enum', 'union', 'alternate', and
 'event'.  There are several groups of types: simple types (a number of
 built-in types, such as 'int' and 'str'; as well as enumerations),
 complex types (structs and two flavors of unions), and alternate types
@@ -128,9 +128,9 @@ In the rest of this document, usage lines are given for each
 expression type, with literal strings written in lower case and
 placeholders written in capitals.  If a literal string includes a
 prefix of '*', that key/value pair can be omitted from the expression.
-For example, a usage statement that includes '*base':COMPLEX-TYPE-NAME
+For example, a usage statement that includes '*base':STRUCT-NAME
 means that an expression has an optional key 'base', which if present
-must have a value that forms a complex type name.
+must have a value that forms a struct name.


 === Built-in Types ===
@@ -168,17 +168,17 @@ an outer file.  The parser may be made stricter in the 
future to
 prevent incomplete include files.


-=== Complex types ===
+=== Struct types ===

-Usage: { 'type': STRING, 'data': DICT, '*base': COMPLEX-TYPE-NAME }
+Usage: { 'struct': STRING, 'data': DICT, '*base': STRUCT-NAME }

-A complex type is a dictionary containing a single 'data' key whose
+A struct is a dictionary containing a single 'data' key whose
 value is a dictionary.  This corresponds to a struct in C or an Object
 in JSON. Each value of the 'data' dictionary must be the name of a
 type, or a one-element array containing a type name.  An example of a
-complex type is:
+struct is:

- { 'type': 'MyType',
+ { 'struct': 'MyType',
'data': { 'member1': 'str', 'member2': 'int', '*member3': 'str' } }

 The use of '*' as a prefix to the name means the member is optional in
@@ -211,13 +211,13 @@ A structure that is used in both input and output of 
various commands
 must consider the backwards compatibility constraints of both directions
 of use.

-A complex type definition can specify another complex type as its base.
+A struct definition can specify another struct as its base.
 In this case, the fields of the base type are included as top-level fields
-of the new complex type's dictionary in the QMP wire format. An example
+of the new struct's dictionary in the QMP wire format. An example
 definition is:

- { 'type': 'BlockdevOptionsGenericFormat', 'data': { 'file': 'str' } }
- { 'type': 'BlockdevOptionsGenericCOWFormat',
+ { 'struct': 'BlockdevOptionsGenericFormat', 'data': { 'file': 'str' } }
+ { 'struct': 'BlockdevOptionsGenericCOWFormat',
'base': 'BlockdevOptionsGenericFormat',
'data': { '*backing': 'str' } }

@@ -252,7 +252,7 @@ converting between strings and enum values.  Since the wire 
format
 always passes by name, it is acceptable to reorder or add new
 enumeration members in any location without breaking QMP clients;
 however, removing enum values would break compatibility.  For any
-complex type that has a field that will only contain a finite set of
+struct that has a field that will only contain a finite set of
 string values, using an enum type for that field is better than
 open-coding the field to be type 'str'.

@@ -260,7 +260,7 @@ open-coding the field to be type 'str'.
 === Union types ===

 Usage: { 'union': STRING, 'data': DICT }
-or:{ 'union': STRING, 'data': DICT, 'base': COMPLEX-TYPE-NAME,
+or:{ 'union': STRING, 'data': DICT, 'base': STRUCT-NAME,
  'discriminator': ENUM-MEMBER-OF-BASE }

 Union types are used to let the user choose between several different
@@ -272,8 +272,8 @@ paragraphs.
 A simple union type defines a mapping from automatic discriminator
 values to data 

[Qemu-devel] [PATCH v8 13/40] qapi: Segregate anonymous unions into alternates in generator

2015-05-04 Thread Eric Blake
Special-casing 'discriminator == {}' for handling anonymous unions
is getting awkward; since this particular type is not always a
dictionary on the wire, it is easier to treat it as a completely
different class of type, alternate, so that if a type is listed
in the union_types array, we know it is not an anonymous union.

This patch just further segregates union handling, to make sure that
anonymous unions are not stored in union_types, and splitting up
check_union() into separate functions.  A future patch will change
the qapi grammar, and having the segregation already in place will
make it easier to deal with the distinct meta-type.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 scripts/qapi-types.py |  6 +--
 scripts/qapi-visit.py |  4 +-
 scripts/qapi.py   | 88 ++-
 tests/qapi-schema/alternate-base.err  |  2 +-
 tests/qapi-schema/alternate-clash.err |  2 +-
 5 files changed, 62 insertions(+), 40 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 2390887..c9e0201 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -170,7 +170,7 @@ typedef enum %(name)s

 return lookup_decl + enum_decl

-def generate_anon_union_qtypes(expr):
+def generate_alternate_qtypes(expr):

 name = expr['union']
 members = expr['data']
@@ -181,7 +181,7 @@ const int %(name)s_qtypes[QTYPE_MAX] = {
 name=name)

 for key in members:
-qtype = find_anonymous_member_qtype(members[key])
+qtype = find_alternate_member_qtype(members[key])
 assert qtype, Invalid anonymous union member

 ret += mcgen('''
@@ -408,7 +408,7 @@ for expr in exprs:
 fdef.write(generate_enum_lookup('%sKind' % expr['union'],
 expr['data'].keys()))
 if expr.get('discriminator') == {}:
-fdef.write(generate_anon_union_qtypes(expr))
+fdef.write(generate_alternate_qtypes(expr))
 else:
 continue
 fdecl.write(ret)
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index dbf0101..6bd2b6b 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -237,7 +237,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s *obj, const 
char *name, Error **er
 ''',
  name=name)

-def generate_visit_anon_union(name, members):
+def generate_visit_alternate(name, members):
 ret = mcgen('''

 void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error 
**errp)
@@ -302,7 +302,7 @@ def generate_visit_union(expr):

 if discriminator == {}:
 assert not base
-return generate_visit_anon_union(name, members)
+return generate_visit_alternate(name, members)

 enum_define = discriminator_find_enum_define(expr)
 if enum_define:
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 0c3459b..0b88325 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -224,21 +224,16 @@ def find_base_fields(base):
 return None
 return base_struct_define['data']

-# Return the qtype of an anonymous union branch, or None on error.
-def find_anonymous_member_qtype(qapi_type):
+# Return the qtype of an alternate branch, or None on error.
+def find_alternate_member_qtype(qapi_type):
 if builtin_types.has_key(qapi_type):
 return builtin_types[qapi_type]
 elif find_struct(qapi_type):
 return QTYPE_QDICT
 elif find_enum(qapi_type):
 return QTYPE_QSTRING
-else:
-union = find_union(qapi_type)
-if union:
-discriminator = union.get('discriminator')
-if discriminator == {}:
-return None
-return QTYPE_QDICT
+elif find_union(qapi_type):
+return QTYPE_QDICT
 return None

 # Return the discriminator enum define if discriminator is specified as an
@@ -276,7 +271,6 @@ def check_union(expr, expr_info):
 discriminator = expr.get('discriminator')
 members = expr['data']
 values = { 'MAX': '(automatic)' }
-types_seen = {}

 # If the object has a member 'base', its value must name a complex type,
 # and there must be a discriminator.
@@ -286,13 +280,15 @@ def check_union(expr, expr_info):
 Union '%s' requires a discriminator to go 
 along with base %name)

-# If the union object has no member 'discriminator', it's a
-# simple union. If 'discriminator' is {}, it is an anonymous union.
-if discriminator is None or discriminator == {}:
+# Two types of unions, determined by discriminator.
+assert discriminator != {}
+
+# With no discriminator it is a simple union.
+if discriminator is None:
 enum_define = None
 if base is not None:
 raise QAPIExprError(expr_info,
-Union '%s' must not have a base
+

[Qemu-devel] [PATCH v8 25/40] qapi: Require valid names

2015-05-04 Thread Eric Blake
Previous commits demonstrated that the generator overlooked various
bad naming situations:
- types, commands, and events need a valid name
- enum members must be valid names, when combined with prefix
- union and alternate branches cannot be marked optional

Valid upstream names match [a-zA-Z][a-zA-Z0-9_-]*; valid downstream
names match __[a-zA-Z][a-zA-Z0-9._-]*.  Enumerations match the
weaker [a-zA-Z0-9._-]+ (in part thanks to QKeyCode picking an enum
that starts with a digit, which we can't change now due to
backwards compatibility).  Rather than call out three separate
regex, this patch just uses a broader combination that allows both
upstream and downstream names, as well as a small hack that
realizes that any enum name is merely a suffix to an already valid
name prefix (that is, any enum name is valid if prepending _ fits
the normal rules).

We could reject new enumeration names beginning with a digit by
whitelisting existing exceptions.  We could also be stricter
about the distinction between upstream names (no leading
underscore, no use of dot) and downstream (mandatory leading
double underscore), but it is probably not worth the bother.

Signed-off-by: Eric Blake ebl...@redhat.com

---

v7: improve commit message
v8: Prefer '_' + name over _%s % name (drop R-b)
---
 scripts/qapi.py| 63 --
 tests/qapi-schema/bad-ident.err|  1 +
 tests/qapi-schema/bad-ident.exit   |  2 +-
 tests/qapi-schema/bad-ident.json   |  2 +-
 tests/qapi-schema/bad-ident.out|  3 --
 tests/qapi-schema/enum-bad-name.err|  1 +
 tests/qapi-schema/enum-bad-name.exit   |  2 +-
 tests/qapi-schema/enum-bad-name.json   |  2 +-
 tests/qapi-schema/enum-bad-name.out|  3 --
 tests/qapi-schema/enum-dict-member.err |  2 +-
 tests/qapi-schema/flat-union-bad-discriminator.err |  2 +-
 .../flat-union-optional-discriminator.err  |  1 +
 .../flat-union-optional-discriminator.exit |  2 +-
 .../flat-union-optional-discriminator.json |  2 +-
 .../flat-union-optional-discriminator.out  |  7 ---
 tests/qapi-schema/union-optional-branch.err|  1 +
 tests/qapi-schema/union-optional-branch.exit   |  2 +-
 tests/qapi-schema/union-optional-branch.json   |  2 +-
 tests/qapi-schema/union-optional-branch.out|  3 --
 19 files changed, 60 insertions(+), 43 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 61e1c43..f627126 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -276,8 +276,31 @@ def discriminator_find_enum_define(expr):

 return find_enum(discriminator_type)

+valid_name = re.compile('^[a-zA-Z_][a-zA-Z0-9_.-]*$')
+def check_name(expr_info, source, name, allow_optional = False,
+   enum_member = False):
+global valid_name
+membername = name
+
+if not isinstance(name, str):
+raise QAPIExprError(expr_info,
+%s requires a string name % source)
+if name.startswith('*'):
+membername = name[1:]
+if not allow_optional:
+raise QAPIExprError(expr_info,
+%s does not allow optional name '%s'
+% (source, name))
+# Enum members can start with a digit, because the generated C
+# code always prefixes it with the enum name
+if enum_member:
+membername = '_' + membername
+if not valid_name.match(membername):
+raise QAPIExprError(expr_info,
+%s uses invalid name '%s' % (source, name))
+
 def check_type(expr_info, source, value, allow_array = False,
-   allow_dict = False, allow_metas = []):
+   allow_dict = False, allow_optional = False, allow_metas = []):
 global all_names
 orig_value = value

@@ -319,18 +342,21 @@ def check_type(expr_info, source, value, allow_array = 
False,
 raise QAPIExprError(expr_info,
 %s should be a type name % source)
 for (key, arg) in value.items():
+check_name(expr_info, Member of %s % source, key,
+   allow_optional=allow_optional)
 check_type(expr_info, Member '%s' of %s % (key, source), arg,
-   allow_array=True, allow_dict=True,
+   allow_array=True, allow_dict=True, allow_optional=True,
allow_metas=['built-in', 'union', 'alternate', 'struct',
 'enum'])

 def check_command(expr, expr_info):
 name = expr['command']
 check_type(expr_info, 'data' for command '%s' % name,
-   expr.get('data'), allow_dict=True,
+   expr.get('data'), allow_dict=True, allow_optional=True,
allow_metas=['union', 'struct'])
 check_type(expr_info, 'returns' for command '%s' % name,
expr.get('returns'), allow_array=True, 

[Qemu-devel] [PATCH v8 17/40] qapi: Add some expr tests

2015-05-04 Thread Eric Blake
Demonstrate that the qapi generator doesn't deal well with
expressions that aren't up to par. Later patches will improve
the expected results as the generator is made stricter.  Only
a few of the the added tests actually behave sanely at
rejecting obvious problems or demonstrating success.

Note that in some cases, we reject bad QAPI merely because our
pseudo-JSON parser does not yet know how to parse numbers.  This
series does not address that, but when a later series adds support
for numeric defaults of integer fields, the testsuite will ensure
that we don't lose the error (and hopefully that the error
message quality is improved).

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com

---

v7: fix commit typo
---
 tests/Makefile   | 8 +---
 tests/qapi-schema/bad-base.err   | 0
 tests/qapi-schema/bad-base.exit  | 1 +
 tests/qapi-schema/bad-base.json  | 3 +++
 tests/qapi-schema/bad-base.out   | 4 
 tests/qapi-schema/bad-ident.err  | 0
 tests/qapi-schema/bad-ident.exit | 1 +
 tests/qapi-schema/bad-ident.json | 2 ++
 tests/qapi-schema/bad-ident.out  | 3 +++
 tests/qapi-schema/bad-type-bool.err  | 1 +
 tests/qapi-schema/bad-type-bool.exit | 1 +
 tests/qapi-schema/bad-type-bool.json | 3 +++
 tests/qapi-schema/bad-type-bool.out  | 0
 tests/qapi-schema/bad-type-dict.err  | 0
 tests/qapi-schema/bad-type-dict.exit | 1 +
 tests/qapi-schema/bad-type-dict.json | 2 ++
 tests/qapi-schema/bad-type-dict.out  | 3 +++
 tests/qapi-schema/bad-type-int.err   | 1 +
 tests/qapi-schema/bad-type-int.exit  | 1 +
 tests/qapi-schema/bad-type-int.json  | 3 +++
 tests/qapi-schema/bad-type-int.out   | 0
 tests/qapi-schema/double-data.err| 1 +
 tests/qapi-schema/double-data.exit   | 1 +
 tests/qapi-schema/double-data.json   | 2 ++
 tests/qapi-schema/double-data.out| 0
 tests/qapi-schema/double-type.err| 0
 tests/qapi-schema/double-type.exit   | 1 +
 tests/qapi-schema/double-type.json   | 2 ++
 tests/qapi-schema/double-type.out| 3 +++
 tests/qapi-schema/event-case.err | 0
 tests/qapi-schema/event-case.exit| 1 +
 tests/qapi-schema/event-case.json| 3 +++
 tests/qapi-schema/event-case.out | 3 +++
 tests/qapi-schema/ident-with-escape.err  | 0
 tests/qapi-schema/ident-with-escape.exit | 1 +
 tests/qapi-schema/ident-with-escape.json | 4 
 tests/qapi-schema/ident-with-escape.out  | 3 +++
 tests/qapi-schema/missing-type.err   | 0
 tests/qapi-schema/missing-type.exit  | 1 +
 tests/qapi-schema/missing-type.json  | 2 ++
 tests/qapi-schema/missing-type.out   | 3 +++
 tests/qapi-schema/unknown-expr-key.err   | 0
 tests/qapi-schema/unknown-expr-key.exit  | 1 +
 tests/qapi-schema/unknown-expr-key.json  | 2 ++
 tests/qapi-schema/unknown-expr-key.out   | 3 +++
 45 files changed, 72 insertions(+), 3 deletions(-)
 create mode 100644 tests/qapi-schema/bad-base.err
 create mode 100644 tests/qapi-schema/bad-base.exit
 create mode 100644 tests/qapi-schema/bad-base.json
 create mode 100644 tests/qapi-schema/bad-base.out
 create mode 100644 tests/qapi-schema/bad-ident.err
 create mode 100644 tests/qapi-schema/bad-ident.exit
 create mode 100644 tests/qapi-schema/bad-ident.json
 create mode 100644 tests/qapi-schema/bad-ident.out
 create mode 100644 tests/qapi-schema/bad-type-bool.err
 create mode 100644 tests/qapi-schema/bad-type-bool.exit
 create mode 100644 tests/qapi-schema/bad-type-bool.json
 create mode 100644 tests/qapi-schema/bad-type-bool.out
 create mode 100644 tests/qapi-schema/bad-type-dict.err
 create mode 100644 tests/qapi-schema/bad-type-dict.exit
 create mode 100644 tests/qapi-schema/bad-type-dict.json
 create mode 100644 tests/qapi-schema/bad-type-dict.out
 create mode 100644 tests/qapi-schema/bad-type-int.err
 create mode 100644 tests/qapi-schema/bad-type-int.exit
 create mode 100644 tests/qapi-schema/bad-type-int.json
 create mode 100644 tests/qapi-schema/bad-type-int.out
 create mode 100644 tests/qapi-schema/double-data.err
 create mode 100644 tests/qapi-schema/double-data.exit
 create mode 100644 tests/qapi-schema/double-data.json
 create mode 100644 tests/qapi-schema/double-data.out
 create mode 100644 tests/qapi-schema/double-type.err
 create mode 100644 tests/qapi-schema/double-type.exit
 create mode 100644 tests/qapi-schema/double-type.json
 create mode 100644 tests/qapi-schema/double-type.out
 create mode 100644 tests/qapi-schema/event-case.err
 create mode 100644 tests/qapi-schema/event-case.exit
 create mode 100644 tests/qapi-schema/event-case.json
 create mode 100644 tests/qapi-schema/event-case.out
 create mode 100644 tests/qapi-schema/ident-with-escape.err
 create mode 100644 tests/qapi-schema/ident-with-escape.exit
 create mode 100644 tests/qapi-schema/ident-with-escape.json
 create mode 100644 tests/qapi-schema/ident-with-escape.out
 create mode 100644 

[Qemu-devel] [PATCH v8 12/40] qapi: Prepare for catching more semantic parse errors

2015-05-04 Thread Eric Blake
This patch widens the scope of a try block (with the attending
reindentation required by Python) in preparation for a future
patch adding more instances of QAPIExprError inside the block.
It's easier to separate indentation from semantic changes, so
this patch has no real behavior change.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 scripts/qapi.py | 37 -
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 5f0f699..0c3459b 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -399,6 +399,7 @@ def check_exprs(schema):
 check_event(expr, info)

 def parse_schema(input_file):
+# First pass: read entire file into memory
 try:
 schema = QAPISchema(open(input_file, r))
 except (QAPISchemaError, QAPIExprError), e:
@@ -407,24 +408,26 @@ def parse_schema(input_file):

 exprs = []

-for expr_elem in schema.exprs:
-expr = expr_elem['expr']
-if expr.has_key('enum'):
-add_enum(expr['enum'], expr.get('data'))
-elif expr.has_key('union'):
-add_union(expr)
-elif expr.has_key('type'):
-add_struct(expr)
-exprs.append(expr)
-
-# Try again for hidden UnionKind enum
-for expr_elem in schema.exprs:
-expr = expr_elem['expr']
-if expr.has_key('union'):
-if not discriminator_find_enum_define(expr):
-add_enum('%sKind' % expr['union'])
-
 try:
+# Next pass: learn the types.
+for expr_elem in schema.exprs:
+expr = expr_elem['expr']
+if expr.has_key('enum'):
+add_enum(expr['enum'], expr.get('data'))
+elif expr.has_key('union'):
+add_union(expr)
+elif expr.has_key('type'):
+add_struct(expr)
+exprs.append(expr)
+
+# Try again for hidden UnionKind enum
+for expr_elem in schema.exprs:
+expr = expr_elem['expr']
+if expr.has_key('union'):
+if not discriminator_find_enum_define(expr):
+add_enum('%sKind' % expr['union'])
+
+# Final pass - validate that exprs make sense
 check_exprs(schema)
 except QAPIExprError, e:
 print sys.stderr, e
-- 
2.1.0




[Qemu-devel] [PATCH v8 39/40] qapi: Support (subset of) \u escapes in strings

2015-05-04 Thread Eric Blake
The handling of \ inside QAPI strings was less than ideal, and
really only worked JSON's \/, \\, \, and our extension of \'
(an obvious extension, when you realize we use '' instead of 
for strings).  For other things, like '\n', it resulted in a
literal 'n' instead of a newline.

Of course, at the moment, we really have no use for escaped
characters, as QAPI has to map to C identifiers, and we currently
support ASCII only for that.  But down the road, we may add
support for default values for string parameters to a command
or struct; if that happens, it would be nice to correctly support
all JSON escape sequences, such as \n or \u.  This gets us
closer, by supporting Unicode escapes in the ASCII range.

Since JSON does not require \OCTAL or \xXX escapes, and our QMP
implementation does not understand them either, I intentionally
reject it here, but it would be an easy addition if we desired it.
Likewise, intentionally refusing the NUL byte means we don't have
to worry about C strings being shorter than the qapi input.

Signed-off-by: Eric Blake ebl...@redhat.com

---

v7: add escape-outside-string, unknown-escape, and tighten parser
to reject unknown escapes and \u
---
 scripts/qapi.py  | 36 +++-
 tests/Makefile   |  2 ++
 tests/qapi-schema/escape-outside-string.err  |  1 +
 tests/qapi-schema/escape-outside-string.exit |  1 +
 tests/qapi-schema/escape-outside-string.json |  3 +++
 tests/qapi-schema/escape-outside-string.out  |  0
 tests/qapi-schema/escape-too-big.err |  1 +
 tests/qapi-schema/escape-too-big.exit|  1 +
 tests/qapi-schema/escape-too-big.json|  3 +++
 tests/qapi-schema/escape-too-big.out |  0
 tests/qapi-schema/escape-too-short.err   |  1 +
 tests/qapi-schema/escape-too-short.exit  |  1 +
 tests/qapi-schema/escape-too-short.json  |  3 +++
 tests/qapi-schema/escape-too-short.out   |  0
 tests/qapi-schema/ident-with-escape.err  |  1 -
 tests/qapi-schema/ident-with-escape.exit |  2 +-
 tests/qapi-schema/ident-with-escape.json |  2 +-
 tests/qapi-schema/ident-with-escape.out  |  3 +++
 tests/qapi-schema/unicode-str.err|  1 +
 tests/qapi-schema/unicode-str.exit   |  1 +
 tests/qapi-schema/unicode-str.json   |  2 ++
 tests/qapi-schema/unicode-str.out|  0
 tests/qapi-schema/unknown-escape.err |  1 +
 tests/qapi-schema/unknown-escape.exit|  1 +
 tests/qapi-schema/unknown-escape.json|  3 +++
 tests/qapi-schema/unknown-escape.out |  0
 26 files changed, 66 insertions(+), 4 deletions(-)
 create mode 100644 tests/qapi-schema/escape-outside-string.err
 create mode 100644 tests/qapi-schema/escape-outside-string.exit
 create mode 100644 tests/qapi-schema/escape-outside-string.json
 create mode 100644 tests/qapi-schema/escape-outside-string.out
 create mode 100644 tests/qapi-schema/escape-too-big.err
 create mode 100644 tests/qapi-schema/escape-too-big.exit
 create mode 100644 tests/qapi-schema/escape-too-big.json
 create mode 100644 tests/qapi-schema/escape-too-big.out
 create mode 100644 tests/qapi-schema/escape-too-short.err
 create mode 100644 tests/qapi-schema/escape-too-short.exit
 create mode 100644 tests/qapi-schema/escape-too-short.json
 create mode 100644 tests/qapi-schema/escape-too-short.out
 create mode 100644 tests/qapi-schema/unicode-str.err
 create mode 100644 tests/qapi-schema/unicode-str.exit
 create mode 100644 tests/qapi-schema/unicode-str.json
 create mode 100644 tests/qapi-schema/unicode-str.out
 create mode 100644 tests/qapi-schema/unknown-escape.err
 create mode 100644 tests/qapi-schema/unknown-escape.exit
 create mode 100644 tests/qapi-schema/unknown-escape.json
 create mode 100644 tests/qapi-schema/unknown-escape.out

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 3c8ce45..14468ba 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -173,7 +173,41 @@ class QAPISchema:
 raise QAPISchemaError(self,
   'Missing terminating \'')
 if esc:
-string += ch
+if ch == 'b':
+string += '\b'
+elif ch == 'f':
+string += '\f'
+elif ch == 'n':
+string += '\n'
+elif ch == 'r':
+string += '\r'
+elif ch == 't':
+string += '\t'
+elif ch == 'u':
+value = 0
+for x in range(0, 4):
+ch = self.src[self.cursor]
+self.cursor += 1
+if ch not in 0123456789abcdefABCDEF:
+raise QAPISchemaError(self,
+ 

[Qemu-devel] [PATCH v8 19/40] qapi: Add tests of redefined expressions

2015-05-04 Thread Eric Blake
Demonstrate that the qapi generator doesn't deal very well with
redefined expressions.  At the parse level, they are silently
accepted; and while the testsuite just stops at parsing, I've
further tested that many of them cause generator crashes or
invalid C code if they were appended to qapi-schema-test.json.
A later patch will tighten things up and adjust the testsuite
to match.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 tests/Makefile   | 2 ++
 tests/qapi-schema/command-int.err| 0
 tests/qapi-schema/command-int.exit   | 1 +
 tests/qapi-schema/command-int.json   | 3 +++
 tests/qapi-schema/command-int.out| 3 +++
 tests/qapi-schema/event-max.err  | 0
 tests/qapi-schema/event-max.exit | 1 +
 tests/qapi-schema/event-max.json | 2 ++
 tests/qapi-schema/event-max.out  | 3 +++
 tests/qapi-schema/redefined-builtin.err  | 0
 tests/qapi-schema/redefined-builtin.exit | 1 +
 tests/qapi-schema/redefined-builtin.json | 2 ++
 tests/qapi-schema/redefined-builtin.out  | 3 +++
 tests/qapi-schema/redefined-command.err  | 0
 tests/qapi-schema/redefined-command.exit | 1 +
 tests/qapi-schema/redefined-command.json | 3 +++
 tests/qapi-schema/redefined-command.out  | 4 
 tests/qapi-schema/redefined-event.err| 0
 tests/qapi-schema/redefined-event.exit   | 1 +
 tests/qapi-schema/redefined-event.json   | 3 +++
 tests/qapi-schema/redefined-event.out| 4 
 tests/qapi-schema/redefined-type.err | 0
 tests/qapi-schema/redefined-type.exit| 1 +
 tests/qapi-schema/redefined-type.json| 3 +++
 tests/qapi-schema/redefined-type.out | 4 
 25 files changed, 45 insertions(+)
 create mode 100644 tests/qapi-schema/command-int.err
 create mode 100644 tests/qapi-schema/command-int.exit
 create mode 100644 tests/qapi-schema/command-int.json
 create mode 100644 tests/qapi-schema/command-int.out
 create mode 100644 tests/qapi-schema/event-max.err
 create mode 100644 tests/qapi-schema/event-max.exit
 create mode 100644 tests/qapi-schema/event-max.json
 create mode 100644 tests/qapi-schema/event-max.out
 create mode 100644 tests/qapi-schema/redefined-builtin.err
 create mode 100644 tests/qapi-schema/redefined-builtin.exit
 create mode 100644 tests/qapi-schema/redefined-builtin.json
 create mode 100644 tests/qapi-schema/redefined-builtin.out
 create mode 100644 tests/qapi-schema/redefined-command.err
 create mode 100644 tests/qapi-schema/redefined-command.exit
 create mode 100644 tests/qapi-schema/redefined-command.json
 create mode 100644 tests/qapi-schema/redefined-command.out
 create mode 100644 tests/qapi-schema/redefined-event.err
 create mode 100644 tests/qapi-schema/redefined-event.exit
 create mode 100644 tests/qapi-schema/redefined-event.json
 create mode 100644 tests/qapi-schema/redefined-event.out
 create mode 100644 tests/qapi-schema/redefined-type.err
 create mode 100644 tests/qapi-schema/redefined-type.exit
 create mode 100644 tests/qapi-schema/redefined-type.json
 create mode 100644 tests/qapi-schema/redefined-type.out

diff --git a/tests/Makefile b/tests/Makefile
index 835ec9c..c27940c 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -214,6 +214,8 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
missing-type.json bad-ident.json ident-with-escape.json \
double-type.json bad-base.json bad-type-bool.json bad-type-int.json \
bad-type-dict.json double-data.json unknown-expr-key.json \
+   redefined-type.json redefined-command.json redefined-builtin.json \
+   redefined-event.json command-int.json event-max.json \
missing-colon.json missing-comma-list.json \
missing-comma-object.json non-objects.json \
qapi-schema-test.json quoted-structural-chars.json \
diff --git a/tests/qapi-schema/command-int.err 
b/tests/qapi-schema/command-int.err
new file mode 100644
index 000..e69de29
diff --git a/tests/qapi-schema/command-int.exit 
b/tests/qapi-schema/command-int.exit
new file mode 100644
index 000..573541a
--- /dev/null
+++ b/tests/qapi-schema/command-int.exit
@@ -0,0 +1 @@
+0
diff --git a/tests/qapi-schema/command-int.json 
b/tests/qapi-schema/command-int.json
new file mode 100644
index 000..fcbb643
--- /dev/null
+++ b/tests/qapi-schema/command-int.json
@@ -0,0 +1,3 @@
+# FIXME: we should reject collisions between commands and types
+{ 'command': 'int', 'data': { 'character': 'str' },
+  'returns': { 'value': 'int' } }
diff --git a/tests/qapi-schema/command-int.out 
b/tests/qapi-schema/command-int.out
new file mode 100644
index 000..d8e1854
--- /dev/null
+++ b/tests/qapi-schema/command-int.out
@@ -0,0 +1,3 @@
+[OrderedDict([('command', 'int'), ('data', OrderedDict([('character', 
'str')])), ('returns', OrderedDict([('value', 'int')]))])]
+[]
+[]
diff --git a/tests/qapi-schema/event-max.err b/tests/qapi-schema/event-max.err
new file mode 100644
index 000..e69de29
diff --git 

[Qemu-devel] [PATCH v8 26/40] qapi: Whitelist commands that don't return dictionary

2015-05-04 Thread Eric Blake
...or an array of dictionaries.  Although we have to cater to
existing commands, returning a non-dictionary means the command
is not extensible (no new name/value pairs can be added if more
information must be returned in parallel).  By making the
whitelist explicit, any new command that falls foul of this
practice will have to be self-documenting, which will encourage
developers to either justify the action or rework the design to
use a dictionary after all.

It's a little bit sloppy that we share a single whitelist among
three clients (it's too permissive for each).  If this is a
problem, a future patch could tighten things by having the
generator take the whitelist as an argument (as in
scripts/qapi-commands.py --legacy-returns=...), or by having
the generator output C code that requires explicit use of the
whitelist (as in:
 #ifndef FROBNICATE_LEGACY_RETURN_OK
 # error Command 'frobnicate' should return a dictionary
 #endif
then having the callers define appropriate macros).  But until
we need such fine-grained separation (if ever), this patch does
the job just fine.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 scripts/qapi.py  | 31 ---
 tests/qapi-schema/returns-alternate.err  |  1 +
 tests/qapi-schema/returns-alternate.exit |  2 +-
 tests/qapi-schema/returns-alternate.json |  2 +-
 tests/qapi-schema/returns-alternate.out  |  4 
 tests/qapi-schema/returns-int.json   |  3 ++-
 tests/qapi-schema/returns-int.out|  2 +-
 tests/qapi-schema/returns-whitelist.err  |  1 +
 tests/qapi-schema/returns-whitelist.exit |  2 +-
 tests/qapi-schema/returns-whitelist.json |  2 +-
 tests/qapi-schema/returns-whitelist.out  |  7 ---
 11 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index f627126..b218ee5 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -32,6 +32,30 @@ builtin_types = {
 'size': 'QTYPE_QINT',
 }

+# Whitelist of commands allowed to return a non-dictionary
+returns_whitelist = [
+# From QMP:
+'human-monitor-command',
+'query-migrate-cache-size',
+'query-tpm-models',
+'query-tpm-types',
+'ringbuf-read',
+
+# From QGA:
+'guest-file-open',
+'guest-fsfreeze-freeze',
+'guest-fsfreeze-freeze-list',
+'guest-fsfreeze-status',
+'guest-fsfreeze-thaw',
+'guest-get-time',
+'guest-set-vcpus',
+'guest-sync',
+'guest-sync-delimited',
+
+# From qapi-schema-test:
+'user_def_cmd3',
+]
+
 enum_types = []
 struct_types = []
 union_types = []
@@ -354,11 +378,12 @@ def check_command(expr, expr_info):
 check_type(expr_info, 'data' for command '%s' % name,
expr.get('data'), allow_dict=True, allow_optional=True,
allow_metas=['union', 'struct'])
+returns_meta = ['union', 'struct']
+if name in returns_whitelist:
+returns_meta += ['built-in', 'alternate', 'enum']
 check_type(expr_info, 'returns' for command '%s' % name,
expr.get('returns'), allow_array=True, allow_dict=True,
-   allow_optional=True,
-   allow_metas=['built-in', 'union', 'alternate', 'struct',
-'enum'])
+   allow_optional=True, allow_metas=returns_meta)

 def check_event(expr, expr_info):
 global events
diff --git a/tests/qapi-schema/returns-alternate.err 
b/tests/qapi-schema/returns-alternate.err
index e69de29..dfbb419 100644
--- a/tests/qapi-schema/returns-alternate.err
+++ b/tests/qapi-schema/returns-alternate.err
@@ -0,0 +1 @@
+tests/qapi-schema/returns-alternate.json:3: 'returns' for command 'oops' 
cannot use alternate type 'Alt'
diff --git a/tests/qapi-schema/returns-alternate.exit 
b/tests/qapi-schema/returns-alternate.exit
index 573541a..d00491f 100644
--- a/tests/qapi-schema/returns-alternate.exit
+++ b/tests/qapi-schema/returns-alternate.exit
@@ -1 +1 @@
-0
+1
diff --git a/tests/qapi-schema/returns-alternate.json 
b/tests/qapi-schema/returns-alternate.json
index b3b91fd..972390c 100644
--- a/tests/qapi-schema/returns-alternate.json
+++ b/tests/qapi-schema/returns-alternate.json
@@ -1,3 +1,3 @@
-# FIXME: we should reject returns if it is an alternate type
+# we reject returns if it is an alternate type
 { 'alternate': 'Alt', 'data': { 'a': 'int', 'b': 'str' } }
 { 'command': 'oops', 'returns': 'Alt' }
diff --git a/tests/qapi-schema/returns-alternate.out 
b/tests/qapi-schema/returns-alternate.out
index 8a03ed3..e69de29 100644
--- a/tests/qapi-schema/returns-alternate.out
+++ b/tests/qapi-schema/returns-alternate.out
@@ -1,4 +0,0 @@
-[OrderedDict([('alternate', 'Alt'), ('data', OrderedDict([('a', 'int'), ('b', 
'str')]))]),
- OrderedDict([('command', 'oops'), ('returns', 'Alt')])]
-[{'enum_name': 'AltKind', 'enum_values': None}]
-[]
diff --git a/tests/qapi-schema/returns-int.json 
b/tests/qapi-schema/returns-int.json
index 7888fb1..870ec63 100644
--- 

[Qemu-devel] [PATCH v8 16/40] qapi: Use 'alternate' to replace anonymous union

2015-05-04 Thread Eric Blake
Previous patches have led up to the point where I create the
new meta-type 'alternate':'Foo'.  See the previous patches
for documentation; I intentionally split as much work into
earlier patches to minimize the size of this patch, but a lot
of it is churn due to testsuite fallout after updating to the
new type.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com

---

v7: rebase to earlier changes, move flat-union-bsae-union comment
change to correct commit
---
 qapi/block-core.json   |  6 ++--
 scripts/qapi-types.py  | 26 --
 scripts/qapi-visit.py  | 17 
 scripts/qapi.py| 32 ++
 tests/qapi-schema/alternate-array.err  |  2 +-
 tests/qapi-schema/alternate-array.json |  5 ++--
 tests/qapi-schema/alternate-base.err   |  2 +-
 tests/qapi-schema/alternate-base.json  |  5 ++--
 tests/qapi-schema/alternate-clash.err  |  2 +-
 tests/qapi-schema/alternate-clash.json |  5 ++--
 tests/qapi-schema/alternate-conflict-dict.err  |  2 +-
 tests/qapi-schema/alternate-conflict-dict.json |  5 ++--
 tests/qapi-schema/alternate-conflict-string.err|  2 +-
 tests/qapi-schema/alternate-conflict-string.json   |  5 ++--
 tests/qapi-schema/alternate-good.json  |  5 ++--
 tests/qapi-schema/alternate-good.out   |  4 +--
 tests/qapi-schema/alternate-nested.err |  2 +-
 tests/qapi-schema/alternate-nested.json| 10 +++
 tests/qapi-schema/alternate-unknown.err|  2 +-
 tests/qapi-schema/alternate-unknown.json   |  5 ++--
 tests/qapi-schema/flat-union-bad-discriminator.err |  2 +-
 .../qapi-schema/flat-union-bad-discriminator.json  |  3 +-
 tests/qapi-schema/qapi-schema-test.json|  3 +-
 tests/qapi-schema/qapi-schema-test.out |  2 +-
 24 files changed, 77 insertions(+), 77 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index 1c17224..3d20e61 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1503,8 +1503,7 @@
 #
 # Since: 2.2
 ##
-{ 'union': 'Qcow2OverlapChecks',
-  'discriminator': {},
+{ 'alternate': 'Qcow2OverlapChecks',
   'data': { 'flags': 'Qcow2OverlapCheckFlags',
 'mode':  'Qcow2OverlapCheckMode' } }

@@ -1795,8 +1794,7 @@
 #
 # Since: 1.7
 ##
-{ 'union': 'BlockdevRef',
-  'discriminator': {},
+{ 'alternate': 'BlockdevRef',
   'data': { 'definition': 'BlockdevOptions',
 'reference': 'str' } }

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index c9e0201..9c8d68c 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -172,7 +172,7 @@ typedef enum %(name)s

 def generate_alternate_qtypes(expr):

-name = expr['union']
+name = expr['alternate']
 members = expr['data']

 ret = mcgen('''
@@ -182,7 +182,7 @@ const int %(name)s_qtypes[QTYPE_MAX] = {

 for key in members:
 qtype = find_alternate_member_qtype(members[key])
-assert qtype, Invalid anonymous union member
+assert qtype, Invalid alternate member

 ret += mcgen('''
 [ %(qtype)s ] = %(abbrev)s_KIND_%(enum)s,
@@ -197,9 +197,9 @@ const int %(name)s_qtypes[QTYPE_MAX] = {
 return ret


-def generate_union(expr):
+def generate_union(expr, meta):

-name = expr['union']
+name = expr[meta]
 typeinfo = expr['data']

 base = expr.get('base')
@@ -243,7 +243,7 @@ struct %(name)s
 ret += mcgen('''
 };
 ''')
-if discriminator == {}:
+if meta == 'alternate':
 ret += mcgen('''
 extern const int %(name)s_qtypes[];
 ''',
@@ -407,8 +407,12 @@ for expr in exprs:
 ret += generate_enum('%sKind' % expr['union'], expr['data'].keys())
 fdef.write(generate_enum_lookup('%sKind' % expr['union'],
 expr['data'].keys()))
-if expr.get('discriminator') == {}:
-fdef.write(generate_alternate_qtypes(expr))
+elif expr.has_key('alternate'):
+ret += generate_fwd_struct(expr['alternate'], expr['data']) + \n
+ret += generate_enum('%sKind' % expr['alternate'], expr['data'].keys())
+fdef.write(generate_enum_lookup('%sKind' % expr['alternate'],
+expr['data'].keys()))
+fdef.write(generate_alternate_qtypes(expr))
 else:
 continue
 fdecl.write(ret)
@@ -438,11 +442,17 @@ for expr in exprs:
 ret += generate_type_cleanup_decl(expr['type'])
 fdef.write(generate_type_cleanup(expr['type']) + \n)
 elif expr.has_key('union'):
-ret += generate_union(expr)
+ret += generate_union(expr, 'union')
 ret += generate_type_cleanup_decl(expr['union'] + List)
 fdef.write(generate_type_cleanup(expr['union'] + List) + \n)
 ret += 

Re: [Qemu-devel] [RFC PATCH v3 08/24] ppc: Prepare CPU socket/core abstraction

2015-05-04 Thread Thomas Huth
On Fri, 24 Apr 2015 12:17:30 +0530
Bharata B Rao bhar...@linux.vnet.ibm.com wrote:

 Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com
 Signed-off-by: Andreas Färber afaer...@suse.de

Not sure if QEMU is fully following the kernel Sob-process, but if
that's the case, I think your Sob should be below the one of Andreas in
case you're the last person who touched the patch (and I think that's
the case here since you've sent it out)?

Also a short patch description would be really nice.

 Thomas



[Qemu-devel] [PATCH v8 18/40] qapi: Better error messages for bad expressions

2015-05-04 Thread Eric Blake
The previous commit demonstrated that the generator overlooked some
fairly basic broken expressions:
- missing metataype
- metatype key has a non-string value
- unknown key in relation to the metatype
- conflicting metatype (this patch treats the second metatype as an
unknown key of the first key visited, which is not necessarily the
first key the user typed)

Add check_keys to cover these situations, and update testcases to
match.  A couple other tests (enum-missing-data, indented-expr) had
to change since the validation added here occurs so early.
Conversely, changes to ident-with-escape results show that we still
have problems where our handling of escape sequences differs from
true JSON, which will matter down the road if we allow arbitrary
default string values for optional parameters (but for now is not
too bad, as we currently can avoid unicode escaping as we don't
need to represent anything beyond C identifier material).

While valid .json files won't trigger any of these cases, we might
as well be nicer to developers that make a typo while trying to add
new QAPI code.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 scripts/qapi.py  | 44 +++-
 tests/qapi-schema/alternate-base.err |  2 +-
 tests/qapi-schema/bad-type-dict.err  |  1 +
 tests/qapi-schema/bad-type-dict.exit |  2 +-
 tests/qapi-schema/bad-type-dict.json |  2 +-
 tests/qapi-schema/bad-type-dict.out  |  3 ---
 tests/qapi-schema/double-type.err|  1 +
 tests/qapi-schema/double-type.exit   |  2 +-
 tests/qapi-schema/double-type.json   |  2 +-
 tests/qapi-schema/double-type.out|  3 ---
 tests/qapi-schema/enum-missing-data.err  |  2 +-
 tests/qapi-schema/ident-with-escape.err  |  1 +
 tests/qapi-schema/ident-with-escape.exit |  2 +-
 tests/qapi-schema/ident-with-escape.out  |  3 ---
 tests/qapi-schema/indented-expr.json |  4 +--
 tests/qapi-schema/indented-expr.out  |  2 +-
 tests/qapi-schema/missing-type.err   |  1 +
 tests/qapi-schema/missing-type.exit  |  2 +-
 tests/qapi-schema/missing-type.json  |  2 +-
 tests/qapi-schema/missing-type.out   |  3 ---
 tests/qapi-schema/unknown-expr-key.err   |  1 +
 tests/qapi-schema/unknown-expr-key.exit  |  2 +-
 tests/qapi-schema/unknown-expr-key.json  |  2 +-
 tests/qapi-schema/unknown-expr-key.out   |  3 ---
 24 files changed, 56 insertions(+), 36 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 05c38c5..868f08b 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -348,11 +348,6 @@ def check_alternate(expr, expr_info):
 values = { 'MAX': '(automatic)' }
 types_seen = {}

-if expr.get('base') is not None:
-raise QAPIExprError(expr_info,
-Alternate '%s' must not have a base
-% name)
-
 # Check every branch
 for (key, value) in members.items():
 # Check for conflicts in the generated enum
@@ -414,6 +409,26 @@ def check_exprs(schema):
 elif expr.has_key('event'):
 check_event(expr, info)

+def check_keys(expr_elem, meta, required, optional=[]):
+expr = expr_elem['expr']
+info = expr_elem['info']
+name = expr[meta]
+if not isinstance(name, str):
+raise QAPIExprError(info,
+'%s' key must have a string value % meta)
+required = required + [ meta ]
+for (key, value) in expr.items():
+if not key in required and not key in optional:
+raise QAPIExprError(info,
+Unknown key '%s' in %s '%s'
+% (key, meta, name))
+for key in required:
+if not expr.has_key(key):
+raise QAPIExprError(info,
+Key '%s' is missing from %s '%s'
+% (key, meta, name))
+
+
 def parse_schema(input_file):
 # First pass: read entire file into memory
 try:
@@ -425,15 +440,30 @@ def parse_schema(input_file):
 exprs = []

 try:
-# Next pass: learn the types.
+# Next pass: learn the types and check for valid expression keys. At
+# this point, top-level 'include' has already been flattened.
 for expr_elem in schema.exprs:
 expr = expr_elem['expr']
 if expr.has_key('enum'):
-add_enum(expr['enum'], expr.get('data'))
+check_keys(expr_elem, 'enum', ['data'])
+add_enum(expr['enum'], expr['data'])
 elif expr.has_key('union'):
+check_keys(expr_elem, 'union', ['data'],
+   ['base', 'discriminator'])
 add_union(expr)
+elif expr.has_key('alternate'):
+check_keys(expr_elem, 'alternate', ['data'])
 elif expr.has_key('type'):
+check_keys(expr_elem, 'type', ['data'], ['base'])
 

[Qemu-devel] [PATCH v8 32/40] qapi: Merge UserDefTwo and UserDefNested in tests

2015-05-04 Thread Eric Blake
In the testsuite, UserDefTwo and UserDefNested were identical
structs other than the member names.  Reduce code duplication by
having just one type, and choose names that also favor reuse.
This will also make it easier for a later patch to get rid of
inline nested types in QAPI.  When touching code related to
allocations, convert g_malloc0(sizeof(Type)) to the more typesafe
g_new0(Type, 1).

Ensure that 'make check-qapi-schema check-unit' still passes.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 tests/qapi-schema/qapi-schema-test.json | 10 +
 tests/qapi-schema/qapi-schema-test.out  |  6 +--
 tests/test-qmp-commands.c   | 34 +++
 tests/test-qmp-input-strict.c   | 17 
 tests/test-qmp-input-visitor.c  | 17 
 tests/test-qmp-output-visitor.c | 48 +++---
 tests/test-visitor-serialization.c  | 73 +
 7 files changed, 102 insertions(+), 103 deletions(-)

diff --git a/tests/qapi-schema/qapi-schema-test.json 
b/tests/qapi-schema/qapi-schema-test.json
index f10efe2..a6be983 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -15,16 +15,10 @@
   'data': { 'string': 'str', '*enum1': 'EnumOne' } }

 { 'struct': 'UserDefTwo',
-  'data': { 'string': 'str',
-'dict': { 'string': 'str',
-  'dict': { 'userdef': 'UserDefOne', 'string': 'str' },
-  '*dict2': { 'userdef': 'UserDefOne', 'string': 'str' } } 
} }
-
-{ 'struct': 'UserDefNested',
   'data': { 'string0': 'str',
 'dict1': { 'string1': 'str',
-   'dict2': { 'userdef1': 'UserDefOne', 'string2': 'str' },
-   '*dict3': { 'userdef2': 'UserDefOne', 'string3': 'str' 
} } } }
+   'dict2': { 'userdef': 'UserDefOne', 'string': 'str' },
+   '*dict3': { 'userdef': 'UserDefOne', 'string': 'str' } 
} } }

 # for testing unions
 { 'struct': 'UserDefA',
diff --git a/tests/qapi-schema/qapi-schema-test.out 
b/tests/qapi-schema/qapi-schema-test.out
index 83ab1a5..48f8f0e 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -2,8 +2,7 @@
  OrderedDict([('struct', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 
'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 
'EnumOne')]))]),
  OrderedDict([('struct', 'UserDefZero'), ('data', OrderedDict([('integer', 
'int')]))]),
  OrderedDict([('struct', 'UserDefOne'), ('base', 'UserDefZero'), ('data', 
OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
- OrderedDict([('struct', 'UserDefTwo'), ('data', OrderedDict([('string', 
'str'), ('dict', OrderedDict([('string', 'str'), ('dict', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')])), ('*dict2', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]))]))]),
- OrderedDict([('struct', 'UserDefNested'), ('data', OrderedDict([('string0', 
'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', 
OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', 
OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
+ OrderedDict([('struct', 'UserDefTwo'), ('data', OrderedDict([('string0', 
'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')])), ('*dict3', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]))]))]),
  OrderedDict([('struct', 'UserDefA'), ('data', OrderedDict([('boolean', 
'bool')]))]),
  OrderedDict([('struct', 'UserDefB'), ('data', OrderedDict([('integer', 
'int')]))]),
  OrderedDict([('struct', 'UserDefC'), ('data', OrderedDict([('string1', 
'str'), ('string2', 'str')]))]),
@@ -28,8 +27,7 @@
 [OrderedDict([('struct', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 
'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 
'EnumOne')]))]),
  OrderedDict([('struct', 'UserDefZero'), ('data', OrderedDict([('integer', 
'int')]))]),
  OrderedDict([('struct', 'UserDefOne'), ('base', 'UserDefZero'), ('data', 
OrderedDict([('string', 'str'), ('*enum1', 'EnumOne')]))]),
- OrderedDict([('struct', 'UserDefTwo'), ('data', OrderedDict([('string', 
'str'), ('dict', OrderedDict([('string', 'str'), ('dict', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')])), ('*dict2', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]))]))]),
- OrderedDict([('struct', 'UserDefNested'), ('data', OrderedDict([('string0', 
'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', 
OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', 
OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
+ OrderedDict([('struct', 'UserDefTwo'), ('data', OrderedDict([('string0', 
'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', 
OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')])), 

[Qemu-devel] [PATCH v8 20/40] qapi: Better error messages for duplicated expressions

2015-05-04 Thread Eric Blake
The previous commit demonstrated that the generator overlooked
duplicate expressions:
- a complex type or command reusing a built-in type name
- redeclaration of a type name, whether by the same or different
metatype
- redeclaration of a command or event
- collision of a type with implicit 'Kind' enum for a union
- collision with an implicit MAX enum constant

Since the c_type() function in the generator treats all names
as being in the same namespace, this patch adds a global array
to track all known names and their source, to prevent collisions
before it can cause further problems.  While valid .json files
won't trigger any of these cases, we might as well be nicer to
developers that make a typo while trying to add new QAPI code.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 scripts/qapi.py  | 63 +---
 tests/qapi-schema/command-int.err|  1 +
 tests/qapi-schema/command-int.exit   |  2 +-
 tests/qapi-schema/command-int.json   |  2 +-
 tests/qapi-schema/command-int.out|  3 --
 tests/qapi-schema/enum-union-clash.err   |  1 +
 tests/qapi-schema/enum-union-clash.exit  |  2 +-
 tests/qapi-schema/enum-union-clash.json  |  2 +-
 tests/qapi-schema/enum-union-clash.out   |  5 ---
 tests/qapi-schema/event-max.err  |  1 +
 tests/qapi-schema/event-max.exit |  2 +-
 tests/qapi-schema/event-max.json |  2 +-
 tests/qapi-schema/event-max.out  |  3 --
 tests/qapi-schema/redefined-builtin.err  |  1 +
 tests/qapi-schema/redefined-builtin.exit |  2 +-
 tests/qapi-schema/redefined-builtin.json |  2 +-
 tests/qapi-schema/redefined-builtin.out  |  3 --
 tests/qapi-schema/redefined-command.err  |  1 +
 tests/qapi-schema/redefined-command.exit |  2 +-
 tests/qapi-schema/redefined-command.json |  2 +-
 tests/qapi-schema/redefined-command.out  |  4 --
 tests/qapi-schema/redefined-event.err|  1 +
 tests/qapi-schema/redefined-event.exit   |  2 +-
 tests/qapi-schema/redefined-event.json   |  2 +-
 tests/qapi-schema/redefined-event.out|  4 --
 tests/qapi-schema/redefined-type.err |  1 +
 tests/qapi-schema/redefined-type.exit|  2 +-
 tests/qapi-schema/redefined-type.json|  2 +-
 tests/qapi-schema/redefined-type.out |  4 --
 29 files changed, 70 insertions(+), 54 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 868f08b..eea0976 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -32,6 +32,12 @@ builtin_types = {
 'size': 'QTYPE_QINT',
 }

+enum_types = []
+struct_types = []
+union_types = []
+events = []
+all_names = {}
+
 def error_path(parent):
 res = 
 while parent:
@@ -256,7 +262,14 @@ def discriminator_find_enum_define(expr):
 return find_enum(discriminator_type)

 def check_event(expr, expr_info):
+global events
+name = expr['event']
 params = expr.get('data')
+
+if name.upper() == 'MAX':
+raise QAPIExprError(expr_info, Event name 'MAX' cannot be created)
+events.append(name)
+
 if params:
 for argname, argentry, optional, structured in parse_args(params):
 if structured:
@@ -430,6 +443,9 @@ def check_keys(expr_elem, meta, required, optional=[]):


 def parse_schema(input_file):
+global all_names
+exprs = []
+
 # First pass: read entire file into memory
 try:
 schema = QAPISchema(open(input_file, r))
@@ -437,30 +453,34 @@ def parse_schema(input_file):
 print sys.stderr, e
 exit(1)

-exprs = []
-
 try:
 # Next pass: learn the types and check for valid expression keys. At
 # this point, top-level 'include' has already been flattened.
+for builtin in builtin_types.keys():
+all_names[builtin] = 'built-in'
 for expr_elem in schema.exprs:
 expr = expr_elem['expr']
+info = expr_elem['info']
 if expr.has_key('enum'):
 check_keys(expr_elem, 'enum', ['data'])
-add_enum(expr['enum'], expr['data'])
+add_enum(expr['enum'], info, expr['data'])
 elif expr.has_key('union'):
 check_keys(expr_elem, 'union', ['data'],
['base', 'discriminator'])
-add_union(expr)
+add_union(expr, info)
 elif expr.has_key('alternate'):
 check_keys(expr_elem, 'alternate', ['data'])
+add_name(expr['alternate'], info, 'alternate')
 elif expr.has_key('type'):
 check_keys(expr_elem, 'type', ['data'], ['base'])
-add_struct(expr)
+add_struct(expr, info)
 elif expr.has_key('command'):
 check_keys(expr_elem, 'command', [],
['data', 'returns', 'gen', 'success-response'])
+add_name(expr['command'], info, 'command')
 elif expr.has_key('event'):
 

[Qemu-devel] [PATCH v8 22/40] qapi: Unify type bypass and add tests

2015-05-04 Thread Eric Blake
For a few QMP commands, we are forced to pass an arbitrary type
without tracking it properly in QAPI.  Among the existing clients,
this unnamed type was spelled 'dict', 'visitor', and '**'; this
patch standardizes on '**', matching the documentation changes
earlier in the series.

Meanwhile, for the 'gen' key, we have been ignoring the value,
although the schema consistently used 'no' ('success-response'
was hard-coded to checking for 'no').  But now that we can support
a literal false in the schema, we might as well use that rather
than ignoring the value or special-casing a random string.  Note
that these are one-way switches (use of 'gen':true is not the same
as omitting 'gen'). Also, the use of '**' requires 'gen':false,
but the use of 'gen':false does not mandate the use of '**'.

There is no difference to the generated code.  Add some tests on
what we'd like to guarantee, although it will take later patches
to clean up test results and actually enforce the use of a bool
parameter.

Signed-off-by: Eric Blake ebl...@redhat.com

---

v8: Drop R-b, due to additional change to scripts to avoid
regression in success-response handling
---
 qapi-schema.json   | 14 +++---
 qga/qapi-schema.json   |  8 
 scripts/qapi-commands.py   |  9 ++---
 tests/Makefile |  1 +
 tests/qapi-schema/type-bypass-bad-gen.err  |  0
 tests/qapi-schema/type-bypass-bad-gen.exit |  1 +
 tests/qapi-schema/type-bypass-bad-gen.json |  2 ++
 tests/qapi-schema/type-bypass-bad-gen.out  |  3 +++
 tests/qapi-schema/type-bypass-no-gen.err   |  0
 tests/qapi-schema/type-bypass-no-gen.exit  |  1 +
 tests/qapi-schema/type-bypass-no-gen.json  |  2 ++
 tests/qapi-schema/type-bypass-no-gen.out   |  3 +++
 tests/qapi-schema/type-bypass.err  |  0
 tests/qapi-schema/type-bypass.exit |  1 +
 tests/qapi-schema/type-bypass.json |  2 ++
 tests/qapi-schema/type-bypass.out  |  3 +++
 16 files changed, 32 insertions(+), 18 deletions(-)
 create mode 100644 tests/qapi-schema/type-bypass-bad-gen.err
 create mode 100644 tests/qapi-schema/type-bypass-bad-gen.exit
 create mode 100644 tests/qapi-schema/type-bypass-bad-gen.json
 create mode 100644 tests/qapi-schema/type-bypass-bad-gen.out
 create mode 100644 tests/qapi-schema/type-bypass-no-gen.err
 create mode 100644 tests/qapi-schema/type-bypass-no-gen.exit
 create mode 100644 tests/qapi-schema/type-bypass-no-gen.json
 create mode 100644 tests/qapi-schema/type-bypass-no-gen.out
 create mode 100644 tests/qapi-schema/type-bypass.err
 create mode 100644 tests/qapi-schema/type-bypass.exit
 create mode 100644 tests/qapi-schema/type-bypass.json
 create mode 100644 tests/qapi-schema/type-bypass.out

diff --git a/qapi-schema.json b/qapi-schema.json
index ac9594d..7f4cf86 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1561,8 +1561,8 @@
 ##
 { 'command': 'qom-get',
   'data': { 'path': 'str', 'property': 'str' },
-  'returns': 'visitor',
-  'gen': 'no' }
+  'returns': '**',
+  'gen': false }

 ##
 # @qom-set:
@@ -1579,8 +1579,8 @@
 # Since: 1.2
 ##
 { 'command': 'qom-set',
-  'data': { 'path': 'str', 'property': 'str', 'value': 'visitor' },
-  'gen': 'no' }
+  'data': { 'path': 'str', 'property': 'str', 'value': '**' },
+  'gen': false }

 ##
 # @set_password:
@@ -1943,7 +1943,7 @@
 ##
 { 'command': 'netdev_add',
   'data': {'type': 'str', 'id': 'str', '*props': '**'},
-  'gen': 'no' }
+  'gen': false }

 ##
 # @netdev_del:
@@ -1976,8 +1976,8 @@
 # Since: 2.0
 ##
 { 'command': 'object-add',
-  'data': {'qom-type': 'str', 'id': 'str', '*props': 'dict'},
-  'gen': 'no' }
+  'data': {'qom-type': 'str', 'id': 'str', '*props': '**'},
+  'gen': false }

 ##
 # @object-del:
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 5c4cd40..fecc442 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -195,7 +195,7 @@
 # Since: 0.15.0
 ##
 { 'command': 'guest-shutdown', 'data': { '*mode': 'str' },
-  'success-response': 'no' }
+  'success-response': false }

 ##
 # @guest-file-open:
@@ -470,7 +470,7 @@
 #
 # Since: 1.1
 ##
-{ 'command': 'guest-suspend-disk', 'success-response': 'no' }
+{ 'command': 'guest-suspend-disk', 'success-response': false }

 ##
 # @guest-suspend-ram
@@ -502,7 +502,7 @@
 #
 # Since: 1.1
 ##
-{ 'command': 'guest-suspend-ram', 'success-response': 'no' }
+{ 'command': 'guest-suspend-ram', 'success-response': false }

 ##
 # @guest-suspend-hybrid
@@ -529,7 +529,7 @@
 #
 # Since: 1.1
 ##
-{ 'command': 'guest-suspend-hybrid', 'success-response': 'no' }
+{ 'command': 'guest-suspend-hybrid', 'success-response': false }

 ##
 # @GuestIpAddressType:
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 053ba85..cb78682 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -2,7 +2,7 @@
 # QAPI command marshaller generator
 #
 # Copyright IBM, Corp. 2011
-# Copyright (C) 2014 Red Hat, Inc.
+# Copyright (C) 2014-2015 Red 

[Qemu-devel] [PATCH v8 30/40] qapi: Use 'struct' instead of 'type' in schema

2015-05-04 Thread Eric Blake
Referring to type as both a meta-type (built-in, enum, union,
alternate, or struct) and a specific type (the name that the
schema uses for declaring structs) is confusing.  Do the bulk of
the conversion to struct in qapi schema, with a fairly
mechanical:

for f in `find -name '*.json'; do sed -i s/'type'/'struct'/; done

followed by manually filtering out the places where we have a
'type' embedded in 'data'.  Then tweak a couple of tests whose
output changes slightly due to longer lines.

I also verified that the generated files for QMP and QGA (such
as qmp-commands.h) are the same before and after, as assurance
that I didn't leave in any accidental member name changes.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com

---

v7: rebase on top of commit a113534, split out trailing cleanups
to separate commit to make this even more mechanical
---
 qapi-schema.json   | 166 ++---
 qapi/block-core.json   |  66 
 qapi/block.json|   2 +-
 qapi/common.json   |   4 +-
 qapi/trace.json|   2 +-
 qga/qapi-schema.json   |  28 ++--
 tests/qapi-schema/alternate-array.json |   2 +-
 tests/qapi-schema/alternate-base.json  |   2 +-
 tests/qapi-schema/alternate-conflict-dict.json |   4 +-
 tests/qapi-schema/alternate-good.json  |   2 +-
 tests/qapi-schema/bad-base.json|   2 +-
 tests/qapi-schema/bad-ident.json   |   2 +-
 tests/qapi-schema/bad-type-bool.json   |   2 +-
 tests/qapi-schema/bad-type-int.err |   2 +-
 tests/qapi-schema/bad-type-int.json|   2 +-
 tests/qapi-schema/data-member-array.json   |   2 +-
 tests/qapi-schema/double-data.err  |   2 +-
 tests/qapi-schema/double-data.json |   2 +-
 tests/qapi-schema/double-type.json |   2 +-
 tests/qapi-schema/flat-union-bad-base.json |   4 +-
 .../qapi-schema/flat-union-bad-discriminator.json  |   6 +-
 tests/qapi-schema/flat-union-base-star.json|   4 +-
 tests/qapi-schema/flat-union-base-union.json   |   4 +-
 tests/qapi-schema/flat-union-branch-clash.json |   6 +-
 tests/qapi-schema/flat-union-inline.json   |   2 +-
 tests/qapi-schema/flat-union-int-branch.json   |   4 +-
 .../qapi-schema/flat-union-invalid-branch-key.json |   6 +-
 .../flat-union-invalid-discriminator.json  |   6 +-
 tests/qapi-schema/flat-union-no-base.json  |   4 +-
 .../flat-union-optional-discriminator.json |   4 +-
 tests/qapi-schema/flat-union-reverse-define.json   |   6 +-
 .../flat-union-string-discriminator.json   |   6 +-
 tests/qapi-schema/qapi-schema-test.json|  22 +--
 tests/qapi-schema/redefined-builtin.json   |   2 +-
 tests/qapi-schema/redefined-type.json  |   2 +-
 tests/qapi-schema/union-bad-branch.json|   4 +-
 tests/qapi-schema/union-base-no-discriminator.json |   6 +-
 tests/qapi-schema/union-invalid-base.json  |   4 +-
 tests/qapi-schema/unknown-expr-key.json|   2 +-
 39 files changed, 200 insertions(+), 200 deletions(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index 7f4cf86..6a4e0df 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -71,7 +71,7 @@
 #
 # Since 0.14.0
 ##
-{ 'type': 'NameInfo', 'data': {'*name': 'str'} }
+{ 'struct': 'NameInfo', 'data': {'*name': 'str'} }

 ##
 # @query-name:
@@ -95,7 +95,7 @@
 #
 # Since: 0.14.0
 ##
-{ 'type': 'KvmInfo', 'data': {'enabled': 'bool', 'present': 'bool'} }
+{ 'struct': 'KvmInfo', 'data': {'enabled': 'bool', 'present': 'bool'} }

 ##
 # @query-kvm:
@@ -170,7 +170,7 @@
 #
 # Notes: @singlestep is enabled through the GDB stub
 ##
-{ 'type': 'StatusInfo',
+{ 'struct': 'StatusInfo',
   'data': {'running': 'bool', 'singlestep': 'bool', 'status': 'RunState'} }

 ##
@@ -195,7 +195,7 @@
 #
 # Notes: If no UUID was specified for the guest, a null UUID is returned.
 ##
-{ 'type': 'UuidInfo', 'data': {'UUID': 'str'} }
+{ 'struct': 'UuidInfo', 'data': {'UUID': 'str'} }

 ##
 # @query-uuid:
@@ -226,7 +226,7 @@
 #
 # Since: 0.14.0
 ##
-{ 'type': 'ChardevInfo', 'data': {'label': 'str',
+{ 'struct': 'ChardevInfo', 'data': {'label': 'str',
   'filename': 'str',
   'frontend-open': 'bool'} }

@@ -250,7 +250,7 @@
 #
 # Since: 2.0
 ##
-{ 'type': 'ChardevBackendInfo', 'data': {'name': 'str'} }
+{ 'struct': 'ChardevBackendInfo', 'data': {'name': 'str'} }

 ##
 # @query-chardev-backends:
@@ -339,7 +339,7 @@
 #
 # Since: 1.2.0
 ##
-{ 'type': 'EventInfo', 'data': {'name': 'str'} }
+{ 'struct': 'EventInfo', 'data': {'name': 'str'} }

 ##
 # @query-events:
@@ -380,7 +380,7 @@
 #
 # Since: 0.14.0
 ##
-{ 'type': 'MigrationStats',

[Qemu-devel] [PATCH v8 35/40] qapi: Drop inline nested structs in query-pci

2015-05-04 Thread Eric Blake
A future patch will be using a 'name':{dictionary} entry in the
QAPI schema to specify a default value for an optional argument
(see previous commit message for more details why); but existing
use of inline nested structs conflicts with that goal. This patch
fixes one of only two commands relying on nested types, by
breaking the nesting into an explicit type; it means that the
type is now boxed instead of unboxed in C code, but the QMP wire
format is unaffected by this change.

Prefer the safer g_new0() while making the conversion, and reduce
some long lines.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 hmp.c| 26 
 hw/pci/pci.c | 42 ++
 qapi-schema.json | 90 ++--
 3 files changed, 98 insertions(+), 60 deletions(-)

diff --git a/hmp.c b/hmp.c
index 97d9c2c..3010d04 100644
--- a/hmp.c
+++ b/hmp.c
@@ -648,14 +648,14 @@ static void hmp_info_pci_device(Monitor *mon, const 
PciDeviceInfo *dev)
dev-slot, dev-function);
 monitor_printf(mon, );

-if (dev-class_info.has_desc) {
-monitor_printf(mon, %s, dev-class_info.desc);
+if (dev-class_info-has_desc) {
+monitor_printf(mon, %s, dev-class_info-desc);
 } else {
-monitor_printf(mon, Class %04 PRId64, dev-class_info.q_class);
+monitor_printf(mon, Class %04 PRId64, dev-class_info-q_class);
 }

 monitor_printf(mon, : PCI device %04 PRIx64 :%04 PRIx64 \n,
-   dev-id.vendor, dev-id.device);
+   dev-id-vendor, dev-id-device);

 if (dev-has_irq) {
 monitor_printf(mon,   IRQ % PRId64 .\n, dev-irq);
@@ -663,25 +663,25 @@ static void hmp_info_pci_device(Monitor *mon, const 
PciDeviceInfo *dev)

 if (dev-has_pci_bridge) {
 monitor_printf(mon,   BUS % PRId64 .\n,
-   dev-pci_bridge-bus.number);
+   dev-pci_bridge-bus-number);
 monitor_printf(mon,   secondary bus % PRId64 .\n,
-   dev-pci_bridge-bus.secondary);
+   dev-pci_bridge-bus-secondary);
 monitor_printf(mon,   subordinate bus % PRId64 .\n,
-   dev-pci_bridge-bus.subordinate);
+   dev-pci_bridge-bus-subordinate);

 monitor_printf(mon,   IO range [0x%04PRIx64, 0x%04PRIx64]\n,
-   dev-pci_bridge-bus.io_range-base,
-   dev-pci_bridge-bus.io_range-limit);
+   dev-pci_bridge-bus-io_range-base,
+   dev-pci_bridge-bus-io_range-limit);

 monitor_printf(mon,
  memory range [0x%08PRIx64, 0x%08PRIx64]\n,
-   dev-pci_bridge-bus.memory_range-base,
-   dev-pci_bridge-bus.memory_range-limit);
+   dev-pci_bridge-bus-memory_range-base,
+   dev-pci_bridge-bus-memory_range-limit);

 monitor_printf(mon,   prefetchable memory range 
[0x%08PRIx64, 0x%08PRIx64]\n,
-   dev-pci_bridge-bus.prefetchable_range-base,
-   dev-pci_bridge-bus.prefetchable_range-limit);
+   dev-pci_bridge-bus-prefetchable_range-base,
+   dev-pci_bridge-bus-prefetchable_range-limit);
 }

 for (region = dev-regions; region; region = region-next) {
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index b3d5100..f5c7a99 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1456,24 +1456,26 @@ static PciBridgeInfo *qmp_query_pci_bridge(PCIDevice 
*dev, PCIBus *bus,
int bus_num)
 {
 PciBridgeInfo *info;
+PciMemoryRange *range;

-info = g_malloc0(sizeof(*info));
+info = g_new0(PciBridgeInfo, 1);

-info-bus.number = dev-config[PCI_PRIMARY_BUS];
-info-bus.secondary = dev-config[PCI_SECONDARY_BUS];
-info-bus.subordinate = dev-config[PCI_SUBORDINATE_BUS];
+info-bus = g_new0(PciBusInfo, 1);
+info-bus-number = dev-config[PCI_PRIMARY_BUS];
+info-bus-secondary = dev-config[PCI_SECONDARY_BUS];
+info-bus-subordinate = dev-config[PCI_SUBORDINATE_BUS];

-info-bus.io_range = g_malloc0(sizeof(*info-bus.io_range));
-info-bus.io_range-base = pci_bridge_get_base(dev, 
PCI_BASE_ADDRESS_SPACE_IO);
-info-bus.io_range-limit = pci_bridge_get_limit(dev, 
PCI_BASE_ADDRESS_SPACE_IO);
+range = info-bus-io_range = g_new0(PciMemoryRange, 1);
+range-base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO);
+range-limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);

-info-bus.memory_range = g_malloc0(sizeof(*info-bus.memory_range));
-info-bus.memory_range-base = pci_bridge_get_base(dev, 
PCI_BASE_ADDRESS_SPACE_MEMORY);
-info-bus.memory_range-limit = pci_bridge_get_limit(dev, 
PCI_BASE_ADDRESS_SPACE_MEMORY);
+range = 

[Qemu-devel] [PATCH v8 34/40] qapi: Drop inline nested struct in query-version

2015-05-04 Thread Eric Blake
A future patch will be using a 'name':{dictionary} entry in the
QAPI schema to specify a default value for an optional argument
(see previous commit message for more details why); but existing
use of inline nested structs conflicts with that goal. This patch
fixes one of only two commands relying on nested types, by
breaking the nesting into an explicit type; it means that the
type is now boxed instead of unboxed in C code, but the QMP wire
format is unaffected by this change.

Prefer the safer g_new0() while making the conversion.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com
---
 hmp.c|  2 +-
 qapi/common.json | 26 +++---
 qmp.c|  9 +
 3 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/hmp.c b/hmp.c
index d85d913..97d9c2c 100644
--- a/hmp.c
+++ b/hmp.c
@@ -60,7 +60,7 @@ void hmp_info_version(Monitor *mon, const QDict *qdict)
 info = qmp_query_version(NULL);

 monitor_printf(mon, % PRId64 .% PRId64 .% PRId64 %s\n,
-   info-qemu.major, info-qemu.minor, info-qemu.micro,
+   info-qemu-major, info-qemu-minor, info-qemu-micro,
info-package);

 qapi_free_VersionInfo(info);
diff --git a/qapi/common.json b/qapi/common.json
index 12431c6..bad56bf 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -29,15 +29,28 @@
 'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap' ] }

 ##
+# @VersionTriple
+#
+# A three-part version number.
+#
+# @qemu.major:  The major version number.
+#
+# @qemu.minor:  The minor version number.
+#
+# @qemu.micro:  The micro version number.
+#
+# Since: 2.4
+##
+{ 'struct': 'VersionTriple',
+  'data': {'major': 'int', 'minor': 'int', 'micro': 'int'} }
+
+
+##
 # @VersionInfo:
 #
 # A description of QEMU's version.
 #
-# @qemu.major:  The major version of QEMU
-#
-# @qemu.minor:  The minor version of QEMU
-#
-# @qemu.micro:  The micro version of QEMU.  By current convention, a micro
+# @qemu:The version of QEMU.  By current convention, a micro
 #   version of 50 signifies a development branch.  A micro version
 #   greater than or equal to 90 signifies a release candidate for
 #   the next minor version.  A micro version of less than 50
@@ -51,8 +64,7 @@
 # Since: 0.14.0
 ##
 { 'struct': 'VersionInfo',
-  'data': {'qemu': {'major': 'int', 'minor': 'int', 'micro': 'int'},
-   'package': 'str'} }
+  'data': {'qemu': 'VersionTriple', 'package': 'str'} }

 ##
 # @query-version:
diff --git a/qmp.c b/qmp.c
index e6c7050..3f5dfe3 100644
--- a/qmp.c
+++ b/qmp.c
@@ -45,15 +45,16 @@ NameInfo *qmp_query_name(Error **errp)

 VersionInfo *qmp_query_version(Error **errp)
 {
-VersionInfo *info = g_malloc0(sizeof(*info));
+VersionInfo *info = g_new0(VersionInfo, 1);
 const char *version = QEMU_VERSION;
 char *tmp;

-info-qemu.major = strtol(version, tmp, 10);
+info-qemu = g_new0(VersionTriple, 1);
+info-qemu-major = strtol(version, tmp, 10);
 tmp++;
-info-qemu.minor = strtol(tmp, tmp, 10);
+info-qemu-minor = strtol(tmp, tmp, 10);
 tmp++;
-info-qemu.micro = strtol(tmp, tmp, 10);
+info-qemu-micro = strtol(tmp, tmp, 10);
 info-package = g_strdup(QEMU_PKGVERSION);

 return info;
-- 
2.1.0




[Qemu-devel] [PATCH v8 01/40] qapi: Add copyright declaration on docs

2015-05-04 Thread Eric Blake
While our top-level COPYING with its GPLv2+ license applies to
any documentation file that omits explicit instructions, these
days it's better to be a good example of calling out our
intentions.  Correct use of GPL requires the use of a copyright
statement, so I'm adding notice to two QAPI documents, by
attributing these files to the initial authors and major
contributors.  I used:

$ git blame --line-porcelain $file \
  | sed -n 's/^author //p' | sort | uniq -c | sort -rn

to determine authorship of these two files.  qmp-spec.txt blames
entirely to Red Hat (easy, since my contribution falls in that
category); while qapi-code-gen.txt has multiple contributors
representing multiple entities.  But since it was originally
supplied by Michael Roth, the notice I added there copies the
notice he has used in other files.  As there is no intended
change in license from the implicit one previously present from
the top level, I have not bothered to CC other contributors;
if we want to weaken things to something looser (such as LGPL)
so that there is no question that someone re-implementing the
spec is not forced to use GPL, that would be a different commit.

CC: Michael Roth mdr...@linux.vnet.ibm.com
Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com

---

v7: Drop date stamp that is too likely to go stale [Markus]
---
 docs/qapi-code-gen.txt | 8 
 docs/qmp/qmp-spec.txt  | 8 
 2 files changed, 16 insertions(+)

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 8313ba6..e8bbaf8 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -1,5 +1,13 @@
 = How to use the QAPI code generator =

+Copyright IBM Corp. 2011
+Copyright (C) 2012-2015 Red Hat, Inc.
+
+This work is licensed under the terms of the GNU GPL, version 2 or
+later. See the COPYING file in the top-level directory.
+
+== Introduction ==
+
 QAPI is a native C API within QEMU which provides management-level
 functionality to internal/external users. For external
 users/processes, this interface is made available by a JSON-based
diff --git a/docs/qmp/qmp-spec.txt b/docs/qmp/qmp-spec.txt
index 22568c6..cb1600a 100644
--- a/docs/qmp/qmp-spec.txt
+++ b/docs/qmp/qmp-spec.txt
@@ -1,5 +1,13 @@
   QEMU Machine Protocol Specification

+0. About This Document
+==
+
+Copyright (C) 2009-2015 Red Hat, Inc.
+
+This work is licensed under the terms of the GNU GPL, version 2 or
+later. See the COPYING file in the top-level directory.
+
 1. Introduction
 ===

-- 
2.1.0




[Qemu-devel] [PATCH v8 40/40] qapi: Check for member name conflicts with a base class

2015-05-04 Thread Eric Blake
Our type inheritance for both 'struct' and for flat 'union' merges
key/value pairs from the base class with those from the type in
question.  Although the C code currently boxes things so that there
is a distinction between which member is referred to, the QMP wire
format does not allow passing a key more than once in a single
object.  Besides, if we ever change the generated C code to not be
quite so boxy, we'd want to avoid duplicate member names there,
too.

Fix a testsuite entry added in an earlier patch, as well as adding
a couple more tests to ensure we have appropriate coverage.  Ensure
that collisions are detected, regardless of whether there is a
difference in opinion on whether the member name is optional.

Signed-off-by: Eric Blake ebl...@redhat.com

---

v7: rebase to earlier changes, reuse base instead of expr['base']
v8: dectect collision in mis-matched optional names (drop R-b)
---
 scripts/qapi.py| 23 ++-
 tests/Makefile |  3 ++-
 tests/qapi-schema/flat-union-branch-clash.err  |  1 +
 tests/qapi-schema/flat-union-branch-clash.exit |  2 +-
 tests/qapi-schema/flat-union-branch-clash.json |  4 ++--
 tests/qapi-schema/flat-union-branch-clash.out  |  9 -
 tests/qapi-schema/struct-base-clash-deep.err   |  1 +
 tests/qapi-schema/struct-base-clash-deep.exit  |  1 +
 tests/qapi-schema/struct-base-clash-deep.json  |  9 +
 tests/qapi-schema/struct-base-clash-deep.out   |  0
 tests/qapi-schema/struct-base-clash.err|  1 +
 tests/qapi-schema/struct-base-clash.exit   |  1 +
 tests/qapi-schema/struct-base-clash.json   |  6 ++
 tests/qapi-schema/struct-base-clash.out|  0
 14 files changed, 47 insertions(+), 14 deletions(-)
 create mode 100644 tests/qapi-schema/struct-base-clash-deep.err
 create mode 100644 tests/qapi-schema/struct-base-clash-deep.exit
 create mode 100644 tests/qapi-schema/struct-base-clash-deep.json
 create mode 100644 tests/qapi-schema/struct-base-clash-deep.out
 create mode 100644 tests/qapi-schema/struct-base-clash.err
 create mode 100644 tests/qapi-schema/struct-base-clash.exit
 create mode 100644 tests/qapi-schema/struct-base-clash.json
 create mode 100644 tests/qapi-schema/struct-base-clash.out

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 14468ba..edfaf9e 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -414,6 +414,20 @@ def check_type(expr_info, source, value, allow_array = 
False,
allow_metas=['built-in', 'union', 'alternate', 'struct',
 'enum'])

+def check_member_clash(expr_info, base_name, data, source = ):
+base = find_struct(base_name)
+assert base
+base_members = base['data']
+for key in data.keys():
+if key.startswith('*'):
+key = key[1:]
+if key in base_members or *%s %key in base_members:
+raise QAPIExprError(expr_info,
+Member name '%s'%s clashes with base '%s'
+%(key, source, base_name))
+if base.get('base'):
+check_member_clash(expr_info, base['base'], data, source)
+
 def check_command(expr, expr_info):
 name = expr['command']
 allow_star = expr.has_key('gen')
@@ -503,9 +517,14 @@ def check_union(expr, expr_info):
 check_name(expr_info, Member of union '%s' % name, key)

 # Each value must name a known type; furthermore, in flat unions,
-# branches must be a struct
+# branches must be a struct with no overlapping member names
 check_type(expr_info, Member '%s' of union '%s' % (key, name),
value, allow_array=True, allow_metas=allow_metas)
+if base:
+branch_struct = find_struct(value)
+assert branch_struct
+check_member_clash(expr_info, base, branch_struct['data'],
+of branch '%s' %key)

 # If the discriminator names an enum type, then all members
 # of 'data' must also be members of the enum type.
@@ -582,6 +601,8 @@ def check_struct(expr, expr_info):
allow_dict=True, allow_optional=True)
 check_type(expr_info, 'base' for struct '%s' % name, expr.get('base'),
allow_metas=['struct'])
+if expr.get('base'):
+check_member_clash(expr_info, expr['base'], expr['data'])

 def check_exprs(schema):
 for expr_elem in schema.exprs:
diff --git a/tests/Makefile b/tests/Makefile
index 547a249..666aee2 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -243,7 +243,8 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
include-simple.json include-relpath.json include-format-err.json \
include-non-file.json include-no-file.json include-before-err.json \
include-nested-err.json include-self-cycle.json include-cycle.json \
-   include-repetition.json event-nest-struct.json event-case.json)
+   include-repetition.json 

[Qemu-devel] [PATCH v8 24/40] qapi: More rigourous checking of types

2015-05-04 Thread Eric Blake
Now that we know every expression is valid with regards to
its keys, we can add further tests that those keys refer to
valid types.  With this patch, all uses of a type (the 'data':
of command, type, union, alternate, and event; the 'returns':
of command; the 'base': of type and union) must resolve to an
appropriate subset of metatypes  declared by the current qapi
parse; this includes recursing into each member of a data
dictionary.  Dealing with '**' and nested anonymous structs
will be done in later patches.

Update the testsuite to match improved output.

Signed-off-by: Eric Blake ebl...@redhat.com
Reviewed-by: Markus Armbruster arm...@redhat.com

---

v7: typo fix for 'furthermore'
---
 scripts/qapi.py  | 96 +---
 tests/qapi-schema/alternate-array.err|  2 +-
 tests/qapi-schema/alternate-nested.err   |  2 +-
 tests/qapi-schema/alternate-unknown.err  |  2 +-
 tests/qapi-schema/bad-base.err   |  1 +
 tests/qapi-schema/bad-base.exit  |  2 +-
 tests/qapi-schema/bad-base.json  |  2 +-
 tests/qapi-schema/bad-base.out   |  4 --
 tests/qapi-schema/bad-data.err   |  1 +
 tests/qapi-schema/bad-data.exit  |  2 +-
 tests/qapi-schema/bad-data.json  |  2 +-
 tests/qapi-schema/bad-data.out   |  3 -
 tests/qapi-schema/data-array-empty.err   |  1 +
 tests/qapi-schema/data-array-empty.exit  |  2 +-
 tests/qapi-schema/data-array-empty.json  |  2 +-
 tests/qapi-schema/data-array-empty.out   |  3 -
 tests/qapi-schema/data-array-unknown.err |  1 +
 tests/qapi-schema/data-array-unknown.exit|  2 +-
 tests/qapi-schema/data-array-unknown.json|  2 +-
 tests/qapi-schema/data-array-unknown.out |  3 -
 tests/qapi-schema/data-int.err   |  1 +
 tests/qapi-schema/data-int.exit  |  2 +-
 tests/qapi-schema/data-int.json  |  2 +-
 tests/qapi-schema/data-int.out   |  3 -
 tests/qapi-schema/data-member-array-bad.err  |  1 +
 tests/qapi-schema/data-member-array-bad.exit |  2 +-
 tests/qapi-schema/data-member-array-bad.json |  2 +-
 tests/qapi-schema/data-member-array-bad.out  |  3 -
 tests/qapi-schema/data-member-unknown.err|  1 +
 tests/qapi-schema/data-member-unknown.exit   |  2 +-
 tests/qapi-schema/data-member-unknown.json   |  2 +-
 tests/qapi-schema/data-member-unknown.out|  3 -
 tests/qapi-schema/data-unknown.err   |  1 +
 tests/qapi-schema/data-unknown.exit  |  2 +-
 tests/qapi-schema/data-unknown.json  |  2 +-
 tests/qapi-schema/data-unknown.out   |  3 -
 tests/qapi-schema/flat-union-int-branch.err  |  1 +
 tests/qapi-schema/flat-union-int-branch.exit |  2 +-
 tests/qapi-schema/flat-union-int-branch.json |  2 +-
 tests/qapi-schema/flat-union-int-branch.out  |  7 --
 tests/qapi-schema/returns-array-bad.err  |  1 +
 tests/qapi-schema/returns-array-bad.exit |  2 +-
 tests/qapi-schema/returns-array-bad.json |  2 +-
 tests/qapi-schema/returns-array-bad.out  |  3 -
 tests/qapi-schema/returns-unknown.err|  1 +
 tests/qapi-schema/returns-unknown.exit   |  2 +-
 tests/qapi-schema/returns-unknown.json   |  2 +-
 tests/qapi-schema/returns-unknown.out|  3 -
 tests/qapi-schema/union-unknown.err  |  1 +
 tests/qapi-schema/union-unknown.exit |  2 +-
 tests/qapi-schema/union-unknown.json |  2 +-
 tests/qapi-schema/union-unknown.out  |  3 -
 52 files changed, 126 insertions(+), 77 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 686bc86..61e1c43 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -276,6 +276,64 @@ def discriminator_find_enum_define(expr):

 return find_enum(discriminator_type)

+def check_type(expr_info, source, value, allow_array = False,
+   allow_dict = False, allow_metas = []):
+global all_names
+orig_value = value
+
+if value is None:
+return
+
+if value == '**':
+return
+
+# Check if array type for value is okay
+if isinstance(value, list):
+if not allow_array:
+raise QAPIExprError(expr_info,
+%s cannot be an array % source)
+if len(value) != 1 or not isinstance(value[0], str):
+raise QAPIExprError(expr_info,
+%s: array type must contain single type name
+% source)
+value = value[0]
+orig_value = array of %s %value
+
+# Check if type name for value is okay
+if isinstance(value, str):
+if not value in all_names:
+raise QAPIExprError(expr_info,
+%s uses unknown type '%s'
+% (source, orig_value))
+if not all_names[value] in allow_metas:
+raise QAPIExprError(expr_info,
+%s cannot use %s type '%s'
+  

  1   2   3   >