[Qemu-devel] [PULL 3/3] hw/input/hid.c Fix capslock hid code

2015-01-22 Thread Gerd Hoffmann
From: Dinar Valeev dval...@suse.com

When ever USB keyboard is used, e.g. '-usbdevice keyboard' pressing
caps lock key send 0x32 hid code, which is treated as backslash.
Instead it should be 0x39 code. This affects sending uppercase keys,
as they typed whith caps lock active.

While on x86 this can be workarounded by using ps/2 protocol. On
Power it is crusial as we don't have anything else than USB.

This is fixes guest automation tasts over vnc.

Signed-off-by: Dinar Valeev dval...@suse.com
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/input/hid.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/input/hid.c b/hw/input/hid.c
index ad18555..6841cb8 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -41,7 +41,7 @@ static const uint8_t hid_usage_keys[0x100] = {
 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
-0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
+0xe2, 0x2c, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44,
-- 
1.8.3.1




[Qemu-devel] [PULL 2/3] hid: handle full ptr queues in post_load

2015-01-22 Thread Gerd Hoffmann
Cc: Dr. David Alan Gilbert dgilb...@redhat.com
Signed-off-by: Gerd Hoffmann kra...@redhat.com
Tested-by: Gonglei arei.gong...@huawei.com
Reviewed-by: Gonglei arei.gong...@huawei.com
---
 hw/input/hid.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/hw/input/hid.c b/hw/input/hid.c
index 148c003..ad18555 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -514,6 +514,27 @@ static int hid_post_load(void *opaque, int version_id)
 HIDState *s = opaque;
 
 hid_set_next_idle(s);
+
+if (s-n == QUEUE_LENGTH  (s-kind == HID_TABLET ||
+ s-kind == HID_MOUSE)) {
+/*
+ * Handle ptr device migration from old qemu with full queue.
+ *
+ * Throw away everything but the last event, so we propagate
+ * at least the current button state to the guest.  Also keep
+ * current position for the tablet, signal no motion for the
+ * mouse.
+ */
+HIDPointerEvent evt;
+evt = s-ptr.queue[(s-head+s-n)  QUEUE_MASK];
+if (s-kind == HID_MOUSE) {
+evt.xdx = 0;
+evt.ydy = 0;
+}
+s-ptr.queue[0] = evt;
+s-head = 0;
+s-n = 1;
+}
 return 0;
 }
 
-- 
1.8.3.1




[Qemu-devel] [PULL 0/3] input: misc fixes.

2015-01-22 Thread Gerd Hoffmann
  Hi,

A few input layer fixes.

pleaase pull,
  Gerd

The following changes since commit 699eae17b841e6784dc3864bf357e26bff1e9dfe:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-misc-20150120' into 
staging (2015-01-20 16:19:58 +)

are available in the git repository at:


  git://git.kraxel.org/qemu tags/pull-input-20150122-1

for you to fetch changes up to 0ee4de5840ccc1072459ec68062bfb63c888a94d:

  hw/input/hid.c Fix capslock hid code (2015-01-22 12:19:48 +0100)


input: misc fixes.


Dinar Valeev (1):
  hw/input/hid.c Fix capslock hid code

Gerd Hoffmann (2):
  input: improve docs for input-send-event qmp command
  hid: handle full ptr queues in post_load

 hw/input/hid.c   | 23 ++-
 qapi-schema.json | 12 
 2 files changed, 34 insertions(+), 1 deletion(-)



Re: [Qemu-devel] [PATCH v2 3/6] block: qapi - move string allocation from stack to the heap

2015-01-22 Thread Stefan Hajnoczi
On Tue, Jan 20, 2015 at 12:31:30PM -0500, Jeff Cody wrote:
 Rather than declaring 'backing_filename2' on the stack in
 bdrv_quiery_image_info(), dynamically allocate it on the heap.

s/quiery/query/

 
 Signed-off-by: Jeff Cody jc...@redhat.com
 ---
  block/qapi.c | 8 +---
  1 file changed, 5 insertions(+), 3 deletions(-)
 
 diff --git a/block/qapi.c b/block/qapi.c
 index a6fd6f7..e51bade 100644
 --- a/block/qapi.c
 +++ b/block/qapi.c
 @@ -175,7 +175,7 @@ void bdrv_query_image_info(BlockDriverState *bs,
  {
  int64_t size;
  const char *backing_filename;
 -char backing_filename2[1024];
 +char *backing_filename2 = NULL;
  BlockDriverInfo bdi;
  int ret;
  Error *err = NULL;
 @@ -211,13 +211,14 @@ void bdrv_query_image_info(BlockDriverState *bs,
  
  backing_filename = bs-backing_file;
  if (backing_filename[0] != '\0') {
 +backing_filename2 = g_malloc0(1024);

backing_filename2 is only used inside the body of this if statement.
Please move the declaration in here to avoid initializing with NULL
(that value is never used but I had to check the surrounding code to
figure that out).


pgp_rlmP7IxKY.pgp
Description: PGP signature


[Qemu-devel] acpi tcg test errors when compiled with clang

2015-01-22 Thread Marc Marí
While I was searching for other errors in make check, I set up a few
machines on top of virtualbox to compile and check qemu master, and
make check failed in a few of them when compiling with clang ( 3.5)
(gcc works perfectly). I found two errors in acpi/tcg test in
tests/bios-tables-test.c

--- Error 1 ---
Log (sometimes the first, sometimes the second):
/i386/acpi/tcg: [I 1421766735.433486] OPENED
{QMP: {version: {qemu: {micro: 50, minor: 2, major: 2},
package: }, capabilities: []}}{execute: qmp_capabilities}
{return: {}}[R +0.027951] readb 0x7c10
[S +0.028104] OK 0x
[R +0.028267] readb 0x7c11
[S +0.028290] OK 0x
Broken pipe

/i386/acpi/tcg: [I 1421766738.230861] OPENED
{QMP: {version: {qemu: {micro: 50, minor: 2, major: 2},
package: }, capabilities: []}}{execute: qmp_capabilities}
{return: {}}Broken pipe

Platforms it failed (all on top of Virtualbox):
 - Ubuntu 14.04.1 Linux 3.13.0 i386 Clang 3.4. Had to configure with
   -disable-werror because of clang: error: argument unused during
   compilation: '-nopie'.

--- Error 2 ---
Log:
/i386/acpi/tcg: [I 1421845839.538638] OPENED
{QMP: {version: {qemu: {micro: 50, minor: 2, major: 2},
package: }, capabilities: []}}{execute: qmp_capabilities}
{return: {}}[R +0.025626] readb 0x7c10 [S +0.025858] OK
0x [R +0.026287] readb 0x7c11
[S +0.026506] OK 0x
/home/markmb/qemu/cpu-exec.c:550:: Object 0xb84dc1a0 is not an
instance of type 8�@�x�@�h@�h@�

Platforms it failed (all on top of Virtualbox):
 - Debian 7.8.0 Linux 3.2.0 i386 Clang 3.0-6
 - Ubuntu 12.04 Linux 3.13.0 i386 Clang 3.0-6

I tried in other setups with Clang 3.5 and no errors. I tried with
x86_64 virtualized systems and no errors. I tried in a native x86_64
(host for all tests. Debian 7 Linux 3.2.65 clang 3.0-6) and did not
fail. I could not test in a native i386.

Maybe it's not important as it just happens with old clangs, or maybe
you want to give it a look.

Thanks
Marc



Re: [Qemu-devel] [PATCH v2 5/6] block: mirror - change string allocation to 2-bytes

2015-01-22 Thread Stefan Hajnoczi
On Tue, Jan 20, 2015 at 12:31:32PM -0500, Jeff Cody wrote:
 The backing_filename string in mirror_run() is only used to check
 for a NULL string, so we don't need to allocate 1024 bytes (or, later,
 PATH_MAX bytes), when we only need to copy the first 2 characters.
 
 We technically only need 1 byte, as we are just checking for NULL, but
 since backing_filename[] is populated by bdrv_get_backing_filename(), a
 string size of 1 will always only return '\0';
 
 Signed-off-by: Jeff Cody jc...@redhat.com
 ---
  block/mirror.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

Reviewed-by: Stefan Hajnoczi stefa...@redhat.com


pgpcDXzK7TJwe.pgp
Description: PGP signature


[Qemu-devel] [PULL 1/1] sb16: fix interrupt acknowledgement

2015-01-22 Thread Gerd Hoffmann
From: Paolo Bonzini pbonz...@redhat.com

SoundBlaster 16 emulation is very broken and consumes a lot of CPU, but a
small fix was suggested offlist and it is enough to fix some games.  I
got Epic Pinball to work with the SoundBlaster Clone option.

The processing of the interrupt register is wrong due to two missing
nots.  This causes the interrupt flag to remain set even after the
Acknowledge ports have been read (0x0e and 0x0f).

The line was introduced by commit 85571bc (audio merge (malc), 2004-11-07),
but the code might have been broken before because I did not look closely
at the huge patches from 10 years ago.

Reported-by: Joshua Bair j_b...@bellsouth.net
Cc: Gerd Hoffmann kra...@redhat.com
Cc: qemu-sta...@nongnu.org
Signed-off-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/audio/sb16.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index bda26d0..444eb9e 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -999,7 +999,7 @@ static IO_READ_PROTO (dsp_read)
 retval = (!s-out_data_len || s-highspeed) ? 0 : 0x80;
 if (s-mixer_regs[0x82]  1) {
 ack = 1;
-s-mixer_regs[0x82] = 1;
+s-mixer_regs[0x82] = ~1;
 qemu_irq_lower (s-pic);
 }
 break;
@@ -1008,7 +1008,7 @@ static IO_READ_PROTO (dsp_read)
 retval = 0xff;
 if (s-mixer_regs[0x82]  2) {
 ack = 1;
-s-mixer_regs[0x82] = 2;
+s-mixer_regs[0x82] = ~2;
 qemu_irq_lower (s-pic);
 }
 break;
-- 
1.8.3.1




Re: [Qemu-devel] [RFC PATCH v3] tests: rtl8139: test timers and interrupt

2015-01-22 Thread Paolo Bonzini


On 22/01/2015 13:33, Frediano Ziglio wrote:
 Hi,
sorry I didn't get everything. Was my patch/test fine or should I
 change something?

Your patch is ok as far as I'm concerned.

 I saw you posted a patch for timer. Was your patch
 tested with my code and you find some problems or was my patch that
 had some problems?

I found bugs in an earlier version of my patch, thanks to your test.  (I
hadn't submitted that patch because indeed I wasn't confident that it
worked).  So now that I tested it, I could submit it in good conscience!

Paolo



[Qemu-devel] [PATCH v3 0/6] Update filename string sizes in block layer

2015-01-22 Thread Jeff Cody
The block layer uses a mixture of 'PATH_MAX' and '1024' string sizes
for filenames (and backing filenames).

This series consolidates all that usage to 'PATH_MAX'.  Since most platforms
(especially the most common platforms for QEMU) have a PATH_MAX larger than
1024 bytes, this series also changes stack allocations of PATH_MAX to be
dynamically allocated.

Note: checkpatch.pl complains about an extra space in a printf in
  patches 1  2.  The lines complained about are in the diff context and
  not the actual changes, so I did not fix them up to satisfy checkpatch.

Changes from v3:
- simplified extent_path handling in vmdk_parse_extents() (Thanks Stefan)
- moved declaration of backing_filename2 to inside if
  statement in bdrv_query_image_info() (Thanks Stefan)
- removed zombie variable in bdrv_commit (Thanks Stefan)
- fixed typo in commit message (Thanks Stefan)

Changes from v2:

- Change stack allocations to dybnamic (Thanks Kevin)
- Update qcow/qcow2 ti perform safety checks for platforms that
  have a PATH_MAX  1024 (thanks John, Kevin).

Jeff Cody (6):
  block: vmdk - make ret variable usage clear
  block: vmdk - move string allocations from stack to the heap
  block: qapi - move string allocation from stack to the heap
  block: remove unused variable in bdrv_commit
  block: mirror - change string allocation to 2-bytes
  block: update string sizes for filename,backing_file,exact_filename

 block.c   |  3 ---
 block/mirror.c|  3 ++-
 block/qapi.c  |  7 ---
 block/qcow.c  |  2 +-
 block/qcow2.c |  3 ++-
 block/vmdk.c  | 51 ---
 block/vvfat.c |  4 ++--
 include/block/block_int.h |  8 
 qemu-img.c|  4 ++--
 9 files changed, 47 insertions(+), 38 deletions(-)

-- 
1.9.3




[Qemu-devel] [PATCH v3 2/6] block: vmdk - move string allocations from stack to the heap

2015-01-22 Thread Jeff Cody
Functions 'vmdk_parse_extents' and 'vmdk_create' allocate several
PATH_MAX sized arrays on the stack.  Make these dynamically allocated.

Signed-off-by: Jeff Cody jc...@redhat.com
---
 block/vmdk.c | 39 +++
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index dc6459c..7d079ad 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -792,12 +792,11 @@ static int vmdk_parse_extents(const char *desc, 
BlockDriverState *bs,
 const char *p = desc;
 int64_t sectors = 0;
 int64_t flat_offset;
-char extent_path[PATH_MAX];
+char *extent_path;
 BlockDriverState *extent_file;
 BDRVVmdkState *s = bs-opaque;
 VmdkExtent *extent;
 
-
 while (*p) {
 /* parse extent line in one of below formats:
  *
@@ -843,11 +842,13 @@ static int vmdk_parse_extents(const char *desc, 
BlockDriverState *bs,
 return -EINVAL;
 }
 
+extent_path = g_malloc0(PATH_MAX);
 path_combine(extent_path, sizeof(extent_path),
 desc_file_path, fname);
 extent_file = NULL;
 ret = bdrv_open(extent_file, extent_path, NULL, NULL,
 bs-open_flags | BDRV_O_PROTOCOL, NULL, errp);
+g_free(extent_path);
 if (ret) {
 return ret;
 }
@@ -1797,10 +1798,15 @@ static int vmdk_create(const char *filename, QemuOpts 
*opts, Error **errp)
 int ret = 0;
 bool flat, split, compress;
 GString *ext_desc_lines;
-char path[PATH_MAX], prefix[PATH_MAX], postfix[PATH_MAX];
+char *path = g_malloc0(PATH_MAX);
+char *prefix = g_malloc0(PATH_MAX);
+char *postfix = g_malloc0(PATH_MAX);
+char *desc_line = g_malloc0(BUF_SIZE);
+char *ext_filename = g_malloc0(PATH_MAX);
+char *desc_filename = g_malloc0(PATH_MAX);
 const int64_t split_size = 0x8000;  /* VMDK has constant split size */
 const char *desc_extent_line;
-char parent_desc_line[BUF_SIZE] = ;
+char *parent_desc_line = g_malloc0(BUF_SIZE);
 uint32_t parent_cid = 0x;
 uint32_t number_heads = 16;
 bool zeroed_grain = false;
@@ -1916,33 +1922,27 @@ static int vmdk_create(const char *filename, QemuOpts 
*opts, Error **errp)
 }
 parent_cid = vmdk_read_cid(bs, 0);
 bdrv_unref(bs);
-snprintf(parent_desc_line, sizeof(parent_desc_line),
+snprintf(parent_desc_line, BUF_SIZE,
 parentFileNameHint=\%s\, backing_file);
 }
 
 /* Create extents */
 filesize = total_size;
 while (filesize  0) {
-char desc_line[BUF_SIZE];
-char ext_filename[PATH_MAX];
-char desc_filename[PATH_MAX];
 int64_t size = filesize;
 
 if (split  size  split_size) {
 size = split_size;
 }
 if (split) {
-snprintf(desc_filename, sizeof(desc_filename), %s-%c%03d%s,
+snprintf(desc_filename, PATH_MAX, %s-%c%03d%s,
 prefix, flat ? 'f' : 's', ++idx, postfix);
 } else if (flat) {
-snprintf(desc_filename, sizeof(desc_filename), %s-flat%s,
-prefix, postfix);
+snprintf(desc_filename, PATH_MAX, %s-flat%s, prefix, postfix);
 } else {
-snprintf(desc_filename, sizeof(desc_filename), %s%s,
-prefix, postfix);
+snprintf(desc_filename, PATH_MAX, %s%s, prefix, postfix);
 }
-snprintf(ext_filename, sizeof(ext_filename), %s%s,
-path, desc_filename);
+snprintf(ext_filename, PATH_MAX, %s%s, path, desc_filename);
 
 if (vmdk_create_extent(ext_filename, size,
flat, compress, zeroed_grain, opts, errp)) {
@@ -1952,7 +1952,7 @@ static int vmdk_create(const char *filename, QemuOpts 
*opts, Error **errp)
 filesize -= size;
 
 /* Format description line */
-snprintf(desc_line, sizeof(desc_line),
+snprintf(desc_line, BUF_SIZE,
 desc_extent_line, size / BDRV_SECTOR_SIZE, desc_filename);
 g_string_append(ext_desc_lines, desc_line);
 }
@@ -2007,6 +2007,13 @@ exit:
 g_free(backing_file);
 g_free(fmt);
 g_free(desc);
+g_free(path);
+g_free(prefix);
+g_free(postfix);
+g_free(desc_line);
+g_free(ext_filename);
+g_free(desc_filename);
+g_free(parent_desc_line);
 g_string_free(ext_desc_lines, true);
 return ret;
 }
-- 
1.9.3




Re: [Qemu-devel] [PATCHv2 7/7] openpic: fix up loadvm under -M mac99

2015-01-22 Thread Alexander Graf


On 21.01.15 17:01, Mark Cave-Ayland wrote:
 Issuing loadvm under -M mac99 would fail for two reasons: firstly an incorrect
 version number for openpic would cause openpic_load() to abort, and secondly
 a cut/paste error when restoring the IVPR and IDR registers caused subsequent
 vmstate sections to become misaligned and abort early.
 
 Signed-off-by: Mark Cave-Ayland mark.cave-ayl...@ilande.co.uk

Thanks a lot for all the work you put into this. Do you think you
understand enough to the OpenPIC code by now to be able to convert it to
VMState instead?

That would get rid of the whole class of problems altogether and make
sure we didn't overlook something subtle somewhere else in the code.


Alex



Re: [Qemu-devel] [PATCH 2/4] target-tricore: Add instructions of RR2 opcode format

2015-01-22 Thread Bastian Koppelmann


On 01/21/2015 06:16 PM, Richard Henderson wrote:

On 01/21/2015 10:04 AM, Bastian Koppelmann wrote:

+case OPC2_32_RR2_MUL_32:
+gen_mul_i32s(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+break;
+case OPC2_32_RR2_MUL_64:
+gen_mul_i64s(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r2]);
+break;

What happend to flags computation?
If you are talking about the PSW flags, they are computed in their 
respective functions: gen_mul_i32s and

gen_mul_i64s.

Cheers,
Bastian


r~





Re: [Qemu-devel] [PULL 00/10] vnc: add support for multiple vnc displays

2015-01-22 Thread Peter Maydell
On 22 January 2015 at 11:03, Gerd Hoffmann kra...@redhat.com wrote:
   Hi,

 No changes, no objections since posting ten days ago.
 Time for the pull req ;)

 please pull,
   Gerd

 The following changes since commit 699eae17b841e6784dc3864bf357e26bff1e9dfe:

   Merge remote-tracking branch 'remotes/pmaydell/tags/pull-misc-20150120' 
 into staging (2015-01-20 16:19:58 +)

 are available in the git repository at:


   git://git.kraxel.org/qemu tags/pull-vnc-20150122-1

 for you to fetch changes up to 4478aa768ccefcc5b234c23d035435fd71b932f6:

   monitor: add vnc websockets (2015-01-22 11:18:47 +0100)

 
 vnc: add support for multiple vnc displays

 

Applied, thanks.

-- PMM



[Qemu-devel] [PATCH v4 4/4] Add migration stream analyzation script

2015-01-22 Thread Alexander Graf
This patch adds a python tool to the scripts directory that can read
a dumped migration stream if it contains the JSON description of the
device states. I constructs a human readable JSON stream out of it.

It's very simple to use:

  $ qemu-system-x86_64
(qemu) migrate exec:cat  mig
  $ ./scripts/analyze_migration.py -f mig

Signed-off-by: Alexander Graf ag...@suse.de

---

v1 - v2:

  - Remove support for multiple vmsd versions
  - Add support for HTAB
  - Add support for array_len
  - Move to new naming schema for fields
  - Use dynamic page size

v2 - v3:

  - Add tell function to MigrationFile
  - Report where subsections were not found
  - Print ram sections with size
  - Remove foreign desc file
  - Add memory dump support (-m option)
  - Add -x option to extract all sections into files

v3 - v4:

  - Change copyright date to 2015
---
 scripts/analyze-migration.py | 592 +++
 1 file changed, 592 insertions(+)
 create mode 100755 scripts/analyze-migration.py

diff --git a/scripts/analyze-migration.py b/scripts/analyze-migration.py
new file mode 100755
index 000..b8b9968
--- /dev/null
+++ b/scripts/analyze-migration.py
@@ -0,0 +1,592 @@
+#!/usr/bin/env python
+#
+#  Migration Stream Analyzer
+#
+#  Copyright (c) 2015 Alexander Graf ag...@suse.de
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, see http://www.gnu.org/licenses/.
+
+import numpy as np
+import json
+import os
+import argparse
+import collections
+import pprint
+
+def mkdir_p(path):
+try:
+os.makedirs(path)
+except OSError:
+pass
+
+class MigrationFile(object):
+def __init__(self, filename):
+self.filename = filename
+self.file = open(self.filename, rb)
+
+def read64(self):
+return np.asscalar(np.fromfile(self.file, count=1, dtype='i8')[0])
+
+def read32(self):
+return np.asscalar(np.fromfile(self.file, count=1, dtype='i4')[0])
+
+def read16(self):
+return np.asscalar(np.fromfile(self.file, count=1, dtype='i2')[0])
+
+def read8(self):
+return np.asscalar(np.fromfile(self.file, count=1, dtype='i1')[0])
+
+def readstr(self, len = None):
+if len is None:
+len = self.read8()
+if len == 0:
+return 
+return np.fromfile(self.file, count=1, dtype=('S%d' % len))[0]
+
+def readvar(self, size = None):
+if size is None:
+size = self.read8()
+if size == 0:
+return 
+value = self.file.read(size)
+if len(value) != size:
+raise Exception(Unexpected end of %s at 0x%x % (self.filename, 
self.file.tell()))
+return value
+
+def tell(self):
+return self.file.tell()
+
+# The VMSD description is at the end of the file, after EOF. Look for
+# the last NULL byte, then for the beginning brace of JSON.
+def read_migration_debug_json(self):
+QEMU_VM_VMDESCRIPTION = 0x06
+
+# Remember the offset in the file when we started
+entrypos = self.file.tell()
+
+# Read the last 10MB
+self.file.seek(0, os.SEEK_END)
+endpos = self.file.tell()
+self.file.seek(max(-endpos, -10 * 1024 * 1024), os.SEEK_END)
+datapos = self.file.tell()
+data = self.file.read()
+# The full file read closed the file as well, reopen it
+self.file = open(self.filename, rb)
+
+# Find the last NULL byte, then the first brace after that. This should
+# be the beginning of our JSON data.
+nulpos = data.rfind(\0)
+jsonpos = data.find({, nulpos)
+
+# Check backwards from there and see whether we guessed right
+self.file.seek(datapos + jsonpos - 5, 0)
+if self.read8() != QEMU_VM_VMDESCRIPTION:
+raise Exception(No Debug Migration device found)
+
+jsonlen = self.read32()
+
+# Seek back to where we were at the beginning
+self.file.seek(entrypos, 0)
+
+return data[jsonpos:jsonpos + jsonlen]
+
+def close(self):
+self.file.close()
+
+class RamSection(object):
+RAM_SAVE_FLAG_COMPRESS = 0x02
+RAM_SAVE_FLAG_MEM_SIZE = 0x04
+RAM_SAVE_FLAG_PAGE = 0x08
+RAM_SAVE_FLAG_EOS  = 0x10
+RAM_SAVE_FLAG_CONTINUE = 0x20
+RAM_SAVE_FLAG_XBZRLE   = 0x40
+RAM_SAVE_FLAG_HOOK = 0x80
+
+def __init__(self, file, version_id, ramargs, 

[Qemu-devel] [PATCH v4 2/4] qemu-file: Add fast ftell code path

2015-01-22 Thread Alexander Graf
For ftell we flush the output buffer to ensure that we don't have anything
lingering in our internal buffers. This is a very safe thing to do.

However, with the dynamic size measurement that the dynamic vmstate
description will bring this would turn out quite slow.

Instead, we can fast path this specific measurement and just take the
internal buffers into account when telling the kernel our position.

I'm sure I overlooked some corner cases where this doesn't work, so
instead of tuning the safe, existing version, this patch adds a fast
variant of ftell that gets used by the dynamic vmstate description code
which isn't critical when it fails.

Signed-off-by: Alexander Graf ag...@suse.de
Reviewed-by: Eric Blake ebl...@redhat.com

---

v2 - v3:

  - improve ftell_fast, now works with bdrv too
---
 include/migration/qemu-file.h |  1 +
 migration/qemu-file.c | 16 
 2 files changed, 17 insertions(+)

diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h
index d843c00..a923cec 100644
--- a/include/migration/qemu-file.h
+++ b/include/migration/qemu-file.h
@@ -121,6 +121,7 @@ QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer 
*input);
 int qemu_get_fd(QEMUFile *f);
 int qemu_fclose(QEMUFile *f);
 int64_t qemu_ftell(QEMUFile *f);
+int64_t qemu_ftell_fast(QEMUFile *f);
 void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
 void qemu_put_byte(QEMUFile *f, int v);
 /*
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
index edc2830..e66e557 100644
--- a/migration/qemu-file.c
+++ b/migration/qemu-file.c
@@ -452,6 +452,22 @@ int qemu_get_byte(QEMUFile *f)
 return result;
 }
 
+int64_t qemu_ftell_fast(QEMUFile *f)
+{
+int64_t ret = f-pos;
+int i;
+
+if (f-ops-writev_buffer) {
+for (i = 0; i  f-iovcnt; i++) {
+ret += f-iov[i].iov_len;
+}
+} else {
+ret += f-buf_index;
+}
+
+return ret;
+}
+
 int64_t qemu_ftell(QEMUFile *f)
 {
 qemu_fflush(f);
-- 
1.7.12.4




[Qemu-devel] [PATCH v4 3/4] migration: Append JSON description of migration stream

2015-01-22 Thread Alexander Graf
One of the annoyances of the current migration format is the fact that
it's not self-describing. In fact, it's not properly describing at all.
Some code randomly scattered throughout QEMU elaborates roughly how to
read and write a stream of bytes.

We discussed an idea during KVM Forum 2013 to add a JSON description of
the migration protocol itself to the migration stream. This patch
adds a section after the VM_END migration end marker that contains
description data on what the device sections of the stream are composed of.

This approach is backwards compatible with any QEMU version reading the
stream, because QEMU just stops reading after the VM_END marker and ignores
any data following it.

With an additional external program this allows us to decipher the
contents of any migration stream and hopefully make migration bugs easier
to track down.

Signed-off-by: Alexander Graf ag...@suse.de

---

v2 - v3:

  - Dont compress objects with subsections
  - Destroy QJSON object

v3 - v4:

  - Update patch description
---
 hw/pci/pci.c  |   2 +-
 hw/scsi/spapr_vscsi.c |   2 +-
 hw/virtio/virtio.c|   2 +-
 include/migration/migration.h |   1 +
 include/migration/vmstate.h   |   3 +-
 migration/vmstate.c   | 186 --
 savevm.c  |  54 ++--
 tests/test-vmstate.c  |   6 +-
 8 files changed, 237 insertions(+), 19 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 371699c..38d0b7b 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -512,7 +512,7 @@ void pci_device_save(PCIDevice *s, QEMUFile *f)
  * This makes us compatible with old devices
  * which never set or clear this bit. */
 s-config[PCI_STATUS] = ~PCI_STATUS_INTERRUPT;
-vmstate_save_state(f, pci_get_vmstate(s), s);
+vmstate_save_state(f, pci_get_vmstate(s), s, NULL);
 /* Restore the interrupt status bit. */
 pci_update_irq_status(s);
 }
diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
index 20b20f0..3639235 100644
--- a/hw/scsi/spapr_vscsi.c
+++ b/hw/scsi/spapr_vscsi.c
@@ -630,7 +630,7 @@ static void vscsi_save_request(QEMUFile *f, SCSIRequest 
*sreq)
 vscsi_req *req = sreq-hba_private;
 assert(req-active);
 
-vmstate_save_state(f, vmstate_spapr_vscsi_req, req);
+vmstate_save_state(f, vmstate_spapr_vscsi_req, req, NULL);
 
 DPRINTF(VSCSI: saving tag=%u, current desc#%d, offset=%x\n,
 req-qtag, req-cur_desc_num, req-cur_desc_offset);
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 013979a..d735343 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -955,7 +955,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
 }
 
 /* Subsections */
-vmstate_save_state(f, vmstate_virtio, vdev);
+vmstate_save_state(f, vmstate_virtio, vdev, NULL);
 }
 
 int virtio_set_features(VirtIODevice *vdev, uint32_t val)
diff --git a/include/migration/migration.h b/include/migration/migration.h
index 3cb5ba8..f37348b 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -33,6 +33,7 @@
 #define QEMU_VM_SECTION_END  0x03
 #define QEMU_VM_SECTION_FULL 0x04
 #define QEMU_VM_SUBSECTION   0x05
+#define QEMU_VM_VMDESCRIPTION0x06
 
 struct MigrationParams {
 bool blk;
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index d712a65..42cc27e 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -29,6 +29,7 @@
 #ifndef CONFIG_USER_ONLY
 #include migration/qemu-file.h
 #endif
+#include qjson.h
 
 typedef void SaveStateHandler(QEMUFile *f, void *opaque);
 typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
@@ -779,7 +780,7 @@ extern const VMStateInfo vmstate_info_bitmap;
 int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, int version_id);
 void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
-void *opaque);
+void *opaque, QJSON *vmdesc);
 
 int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
const VMStateDescription *vmsd,
diff --git a/migration/vmstate.c b/migration/vmstate.c
index 3dde574..2a91f1f 100644
--- a/migration/vmstate.c
+++ b/migration/vmstate.c
@@ -4,9 +4,10 @@
 #include migration/vmstate.h
 #include qemu/bitops.h
 #include trace.h
+#include qjson.h
 
 static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription 
*vmsd,
-void *opaque);
+void *opaque, QJSON *vmdesc);
 static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque);
 
@@ -138,32 +139,181 @@ int vmstate_load_state(QEMUFile *f, const 
VMStateDescription *vmsd,
 return 0;
 }
 
+static int vmfield_name_num(VMStateField *start, VMStateField *search)

[Qemu-devel] [PATCH v4 0/4] Migration Deciphering aid

2015-01-22 Thread Alexander Graf
Migration is a black hole to most people. One of the biggest reasons for
this is that its protocol is a secret, undocumented sauce of code rolling
around random parts of the QEMU code base.

But what if we simply exposed the description of how the format looks like
alongside the actual migration stream? This is what this patch set does.

It adds a new section that comes after the end of stream marker (so that it
doesn't slow down migration) that contains a JSON description of the device
state description.

Along with this patch set also comes a python script that can read said JSON
from a migration dump and decipher the device state and ram contents of the
migration dump using it.

With this, you can now fully examine all glorious details that go over the
wire when virtual machine state gets dumped, such as during live migration.

We discussed the approach taken here during KVM Forum 2013. Originally, my idea
was to include a special device that contains the JSON data which can be enabled
on demand. Anthony suggested however to just always include the description data
after the end marker which I think is a great idea.

  Example decoded migration: http://csgraf.de/mig/mig.txt
  Example migration description: http://csgraf.de/mig/mig.desc.txt
  Presentation: https://www.youtube.com/watch?v=iq1x40Qsrew
  Slides: https://www.dropbox.com/s/otp2pk2n3g087zp/Live%20Migration.pdf

v1 - v2:

  - a lot, v1 was from 2013

v2 - v3:

  - QOMify the QJSON object, makes for easier destruction
  - improve ftell_fast, now works with bdrv too
  - Dont compress objects with subsections
  - Destroy QJSON object
  - Add tell function to MigrationFile
  - Report where subsections were not found
  - Print ram sections with size
  - Remove foreign desc file support
  - Add memory dump support (-m option)
  - Add -x option to extract all sections into files

v3 - v4:

  - Squash properly
  - Remove unused field from struct
  - Update patch description
  - Change copyright date to 2015

Alexander Graf (4):
  QJSON: Add JSON writer
  qemu-file: Add fast ftell code path
  migration: Append JSON description of migration stream
  Add migration stream analyzation script

 Makefile.objs |   1 +
 hw/pci/pci.c  |   2 +-
 hw/scsi/spapr_vscsi.c |   2 +-
 hw/virtio/virtio.c|   2 +-
 include/migration/migration.h |   1 +
 include/migration/qemu-file.h |   1 +
 include/migration/vmstate.h   |   3 +-
 include/qjson.h   |  29 +++
 migration/qemu-file.c |  16 ++
 migration/vmstate.c   | 186 -
 qjson.c   | 129 +
 savevm.c  |  54 +++-
 scripts/analyze-migration.py  | 592 ++
 tests/test-vmstate.c  |   6 +-
 14 files changed, 1005 insertions(+), 19 deletions(-)
 create mode 100644 include/qjson.h
 create mode 100644 qjson.c
 create mode 100755 scripts/analyze-migration.py

-- 
1.7.12.4




[Qemu-devel] [PULL 01/10] vnc: remove vnc_display global

2015-01-22 Thread Gerd Hoffmann
Replace with a vnc_displays list, so we can have multiple vnc server
instances.  Add vnc_server_find function to lookup a display by id.
With no id supplied return the first vnc server, for backward
compatibility reasons.

It is not possible (yet) to actually create multiple vnc server
instances.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
Reviewed-by: Gonglei arei.gong...@huawei.com
---
 ui/vnc.c | 63 +--
 ui/vnc.h |  2 ++
 2 files changed, 43 insertions(+), 22 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 0385160..27e4d26 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -46,7 +46,8 @@ static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
 #include vnc_keysym.h
 #include d3des.h
 
-static VncDisplay *vnc_display; /* needed for info vnc */
+static QTAILQ_HEAD(, VncDisplay) vnc_displays =
+QTAILQ_HEAD_INITIALIZER(vnc_displays);
 
 static int vnc_cursor_define(VncState *vs);
 static void vnc_release_modifiers(VncState *vs);
@@ -226,10 +227,10 @@ static const char *vnc_auth_name(VncDisplay *vd) {
 return unknown;
 }
 
-static VncServerInfo *vnc_server_info_get(void)
+static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
 {
 VncServerInfo *info;
-VncBasicInfo *bi = vnc_basic_info_get_from_server_addr(vnc_display-lsock);
+VncBasicInfo *bi = vnc_basic_info_get_from_server_addr(vd-lsock);
 if (!bi) {
 return NULL;
 }
@@ -237,7 +238,7 @@ static VncServerInfo *vnc_server_info_get(void)
 info = g_malloc(sizeof(*info));
 info-base = bi;
 info-has_auth = true;
-info-auth = g_strdup(vnc_auth_name(vnc_display));
+info-auth = g_strdup(vnc_auth_name(vd));
 return info;
 }
 
@@ -282,7 +283,7 @@ static void vnc_qmp_event(VncState *vs, QAPIEvent event)
 }
 g_assert(vs-info-base);
 
-si = vnc_server_info_get();
+si = vnc_server_info_get(vs-vd);
 if (!si) {
 return;
 }
@@ -345,11 +346,27 @@ static VncClientInfo *qmp_query_vnc_client(const VncState 
*client)
 return info;
 }
 
+static VncDisplay *vnc_display_find(const char *id)
+{
+VncDisplay *vd;
+
+if (id == NULL) {
+return QTAILQ_FIRST(vnc_displays);
+}
+QTAILQ_FOREACH(vd, vnc_displays, next) {
+if (strcmp(id, vd-id) == 0) {
+return vd;
+}
+}
+return NULL;
+}
+
 VncInfo *qmp_query_vnc(Error **errp)
 {
 VncInfo *info = g_malloc0(sizeof(*info));
+VncDisplay *vd = vnc_display_find(NULL);
 
-if (vnc_display == NULL || vnc_display-display == NULL) {
+if (vd == NULL || vd-display == NULL) {
 info-enabled = false;
 } else {
 VncClientInfoList *cur_item = NULL;
@@ -364,7 +381,7 @@ VncInfo *qmp_query_vnc(Error **errp)
 /* for compatibility with the original command */
 info-has_clients = true;
 
-QTAILQ_FOREACH(client, vnc_display-clients, next) {
+QTAILQ_FOREACH(client, vd-clients, next) {
 VncClientInfoList *cinfo = g_malloc0(sizeof(*info));
 cinfo-value = qmp_query_vnc_client(client);
 
@@ -377,11 +394,11 @@ VncInfo *qmp_query_vnc(Error **errp)
 }
 }
 
-if (vnc_display-lsock == -1) {
+if (vd-lsock == -1) {
 return info;
 }
 
-if (getsockname(vnc_display-lsock, (struct sockaddr *)sa,
+if (getsockname(vd-lsock, (struct sockaddr *)sa,
 salen) == -1) {
 error_set(errp, QERR_UNDEFINED_ERROR);
 goto out_error;
@@ -405,7 +422,7 @@ VncInfo *qmp_query_vnc(Error **errp)
 info-family = inet_netfamily(sa.ss_family);
 
 info-has_auth = true;
-info-auth = g_strdup(vnc_auth_name(vnc_display));
+info-auth = g_strdup(vnc_auth_name(vd));
 }
 
 return info;
@@ -853,7 +870,7 @@ static int vnc_cursor_define(VncState *vs)
 static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
   QEMUCursor *c)
 {
-VncDisplay *vd = vnc_display;
+VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
 VncState *vs;
 
 cursor_put(vd-cursor);
@@ -2818,6 +2835,7 @@ static void vnc_connect(VncDisplay *vd, int csock,
 int i;
 
 vs-csock = csock;
+vs-vd = vd;
 
 if (skipauth) {
vs-auth = VNC_AUTH_NONE;
@@ -2862,8 +2880,6 @@ static void vnc_connect(VncDisplay *vd, int csock,
 vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
 vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
 
-vs-vd = vd;
-
 #ifdef CONFIG_VNC_WS
 if (!vs-websocket)
 #endif
@@ -2956,7 +2972,7 @@ void vnc_display_init(DisplayState *ds)
 {
 VncDisplay *vs = g_malloc0(sizeof(*vs));
 
-vnc_display = vs;
+QTAILQ_INSERT_TAIL(vnc_displays, vs, next);
 
 vs-lsock = -1;
 #ifdef CONFIG_VNC_WS
@@ -2986,7 +3002,7 @@ void vnc_display_init(DisplayState *ds)
 
 static void vnc_display_close(DisplayState *ds)
 {
-VncDisplay *vs = vnc_display;
+VncDisplay *vs = vnc_display_find(NULL);
 
 if 

Re: [Qemu-devel] [PULL] qemu-sparc update

2015-01-22 Thread Peter Maydell
On 21 January 2015 at 17:06, Mark Cave-Ayland
mark.cave-ayl...@ilande.co.uk wrote:
 Hi Peter,

 This is mainly to apply your outstanding clang warning patches. Please pull.


 ATB,

 Mark.


 The following changes since commit 699eae17b841e6784dc3864bf357e26bff1e9dfe:

   Merge remote-tracking branch 'remotes/pmaydell/tags/pull-misc-20150120' 
 into staging (2015-01-20 16:19:58 +)

 are available in the git repository at:


   https://github.com/mcayland/qemu.git tags/qemu-sparc-signed

 for you to fetch changes up to 7230818a2b54df826e5ecdd83bd20632c9a8b07c:

   disas/sparc: Remove unused data sparc_opcode_archs[] (2015-01-21 16:18:01 
 +)

 
 qemu-sparc update

 

Applied, thanks.

-- PMM



Re: [Qemu-devel] [PATCH v2 4/6] block: move string allocation from stack to the heap

2015-01-22 Thread Jeff Cody
On Thu, Jan 22, 2015 at 11:37:54AM +, Stefan Hajnoczi wrote:
 On Tue, Jan 20, 2015 at 12:31:31PM -0500, Jeff Cody wrote:
  Rather than allocate PATH_MAX bytes on the stack, use g_strndup() to
  dynamically allocate the string, and add an exit label for cleanup.
  
  Signed-off-by: Jeff Cody jc...@redhat.com
  ---
   block.c | 11 +++
   1 file changed, 7 insertions(+), 4 deletions(-)
 
 Zombie alert!
 
 This is a funny:
 
 Since September 2012 in commit 0bce597d6ec34b2af802799eb53ebc863c704d05
 (block: convert bdrv_commit() to use bdrv_reopen()) the filename
 variable has not been used.
 
 We continued to maintain this variable faithfully, for example, to fix a
 buffer overflow in commit c2cba3d9314f972dfaf724d0ec2d018eb54c95f1
 (block: avoid buffer overrun by using pstrcpy, not strncpy).
 
 Please kill the zombie filename variable instead of switching to heap
 allocation :-).

Ha! OK, will kill the zombie :)



[Qemu-devel] [PATCH v3 1/6] block: vmdk - make ret variable usage clear

2015-01-22 Thread Jeff Cody
Keep the variable 'ret' something that is returned by the function it is
defined in.  For the return value of 'sscanf', use a more meaningful
variable name.

Reviewed-by: Stefan Hajnoczi stefa...@redhat.com
Reviewed-by: John Snow js...@redhat.com
Signed-off-by: Jeff Cody jc...@redhat.com
---
 block/vmdk.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 52cb888..dc6459c 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -785,6 +785,7 @@ static int vmdk_parse_extents(const char *desc, 
BlockDriverState *bs,
   const char *desc_file_path, Error **errp)
 {
 int ret;
+int matches;
 char access[11];
 char type[11];
 char fname[512];
@@ -796,6 +797,7 @@ static int vmdk_parse_extents(const char *desc, 
BlockDriverState *bs,
 BDRVVmdkState *s = bs-opaque;
 VmdkExtent *extent;
 
+
 while (*p) {
 /* parse extent line in one of below formats:
  *
@@ -805,23 +807,23 @@ static int vmdk_parse_extents(const char *desc, 
BlockDriverState *bs,
  * RW [size in sectors] VMFSSPARSE file-name.vmdk
  */
 flat_offset = -1;
-ret = sscanf(p, %10s % SCNd64  %10s \%511[^\n\r\]\ % SCNd64,
-access, sectors, type, fname, flat_offset);
-if (ret  4 || strcmp(access, RW)) {
+matches = sscanf(p, %10s % SCNd64  %10s \%511[^\n\r\]\ % SCNd64,
+ access, sectors, type, fname, flat_offset);
+if (matches  4 || strcmp(access, RW)) {
 goto next_line;
 } else if (!strcmp(type, FLAT)) {
-if (ret != 5 || flat_offset  0) {
+if (matches != 5 || flat_offset  0) {
 error_setg(errp, Invalid extent lines: \n%s, p);
 return -EINVAL;
 }
 } else if (!strcmp(type, VMFS)) {
-if (ret == 4) {
+if (matches == 4) {
 flat_offset = 0;
 } else {
 error_setg(errp, Invalid extent lines:\n%s, p);
 return -EINVAL;
 }
-} else if (ret != 4) {
+} else if (matches != 4) {
 error_setg(errp, Invalid extent lines:\n%s, p);
 return -EINVAL;
 }
-- 
1.9.3




[Qemu-devel] [PATCH v4 1/4] QJSON: Add JSON writer

2015-01-22 Thread Alexander Graf
To support programmatic JSON assembly while keeping the code that generates it
readable, this patch introduces a simple JSON writer. It emits JSON serially
into a buffer in memory.

The nice thing about this writer is its simplicity and low memory overhead.
Unlike the QMP JSON writer, this one does not need to spawn QObjects for every
element it wants to represent.

This is a prerequisite for the migration stream format description generator.

Signed-off-by: Alexander Graf ag...@suse.de

---

v2 - v3:

  - QOMify the QJSON object, makes for easier destruction

v3 - v4:

  - Squash properly
  - remove unused field from struct
---
 Makefile.objs   |   1 +
 include/qjson.h |  29 +
 qjson.c | 129 
 3 files changed, 159 insertions(+)
 create mode 100644 include/qjson.h
 create mode 100644 qjson.c

diff --git a/Makefile.objs b/Makefile.objs
index abeb902..28999d3 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -51,6 +51,7 @@ common-obj-$(CONFIG_LINUX) += fsdev/
 common-obj-y += migration/
 common-obj-y += qemu-char.o #aio.o
 common-obj-y += page_cache.o
+common-obj-y += qjson.o
 
 common-obj-$(CONFIG_SPICE) += spice-qemu-char.o
 
diff --git a/include/qjson.h b/include/qjson.h
new file mode 100644
index 000..7c54fdf
--- /dev/null
+++ b/include/qjson.h
@@ -0,0 +1,29 @@
+/*
+ * QEMU JSON writer
+ *
+ * Copyright Alexander Graf
+ *
+ * Authors:
+ *  Alexander Graf ag...@suse.de
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+#ifndef QEMU_QJSON_H
+#define QEMU_QJSON_H
+
+#define TYPE_QJSON QJSON
+typedef struct QJSON QJSON;
+
+QJSON *qjson_new(void);
+void json_prop_str(QJSON *json, const char *name, const char *str);
+void json_prop_int(QJSON *json, const char *name, int64_t val);
+void json_end_array(QJSON *json);
+void json_start_array(QJSON *json, const char *name);
+void json_end_object(QJSON *json);
+void json_start_object(QJSON *json, const char *name);
+const char *qjson_get_str(QJSON *json);
+void qjson_finish(QJSON *json);
+
+#endif /* QEMU_QJSON_H */
diff --git a/qjson.c b/qjson.c
new file mode 100644
index 000..b24
--- /dev/null
+++ b/qjson.c
@@ -0,0 +1,129 @@
+/*
+ * QEMU JSON writer
+ *
+ * Copyright Alexander Graf
+ *
+ * Authors:
+ *  Alexander Graf ag...@suse.de
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include qapi/qmp/qstring.h
+#include stdbool.h
+#include glib.h
+#include qjson.h
+#include qemu/module.h
+#include qom/object.h
+
+struct QJSON {
+Object obj;
+QString *str;
+bool omit_comma;
+};
+
+static void json_emit_element(QJSON *json, const char *name)
+{
+/* Check whether we need to print a , before an element */
+if (json-omit_comma) {
+json-omit_comma = false;
+} else {
+qstring_append(json-str, , );
+}
+
+if (name) {
+qstring_append(json-str, \);
+qstring_append(json-str, name);
+qstring_append(json-str, \ : );
+}
+}
+
+void json_start_object(QJSON *json, const char *name)
+{
+json_emit_element(json, name);
+qstring_append(json-str, { );
+json-omit_comma = true;
+}
+
+void json_end_object(QJSON *json)
+{
+qstring_append(json-str,  });
+json-omit_comma = false;
+}
+
+void json_start_array(QJSON *json, const char *name)
+{
+json_emit_element(json, name);
+qstring_append(json-str, [ );
+json-omit_comma = true;
+}
+
+void json_end_array(QJSON *json)
+{
+qstring_append(json-str,  ]);
+json-omit_comma = false;
+}
+
+void json_prop_int(QJSON *json, const char *name, int64_t val)
+{
+json_emit_element(json, name);
+qstring_append_int(json-str, val);
+}
+
+void json_prop_str(QJSON *json, const char *name, const char *str)
+{
+json_emit_element(json, name);
+qstring_append_chr(json-str, '');
+qstring_append(json-str, str);
+qstring_append_chr(json-str, '');
+}
+
+const char *qjson_get_str(QJSON *json)
+{
+return qstring_get_str(json-str);
+}
+
+QJSON *qjson_new(void)
+{
+QJSON *json = (QJSON *)object_new(TYPE_QJSON);
+return json;
+}
+
+void qjson_finish(QJSON *json)
+{
+json_end_object(json);
+}
+
+static void qjson_initfn(Object *obj)
+{
+QJSON *json = (QJSON *)object_dynamic_cast(obj, TYPE_QJSON);
+assert(json);
+
+json-str = qstring_from_str({ );
+json-omit_comma = true;
+}
+
+static void qjson_finalizefn(Object *obj)
+{
+QJSON *json = (QJSON *)object_dynamic_cast(obj, TYPE_QJSON);
+
+assert(json);
+qobject_decref(QOBJECT(json-str));
+}
+
+static const TypeInfo qjson_type_info = {
+.name = TYPE_QJSON,
+.parent = TYPE_OBJECT,
+.instance_size = sizeof(QJSON),
+.instance_init = qjson_initfn,
+.instance_finalize = qjson_finalizefn,
+};
+
+static void qjson_register_types(void)
+{
+

[Qemu-devel] [PULL 00/10] vnc: add support for multiple vnc displays

2015-01-22 Thread Gerd Hoffmann
  Hi,

No changes, no objections since posting ten days ago.
Time for the pull req ;)

please pull,
  Gerd

The following changes since commit 699eae17b841e6784dc3864bf357e26bff1e9dfe:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-misc-20150120' into 
staging (2015-01-20 16:19:58 +)

are available in the git repository at:


  git://git.kraxel.org/qemu tags/pull-vnc-20150122-1

for you to fetch changes up to 4478aa768ccefcc5b234c23d035435fd71b932f6:

  monitor: add vnc websockets (2015-01-22 11:18:47 +0100)


vnc: add support for multiple vnc displays


Gerd Hoffmann (10):
  vnc: remove vnc_display global
  vnc: remove unused DisplayState parameter, add id instead.
  vnc: add display id to acl names
  vnc: switch to QemuOpts, allow multiple servers
  vnc: allow binding servers to qemu consoles
  vnc: update docs/multiseat.txt
  vnc: track  limit connections
  vnc: factor out qmp_query_client_list
  monitor: add query-vnc-servers command
  monitor: add vnc websockets

 docs/multiseat.txt   |  18 +-
 include/ui/console.h |  18 +-
 qapi-schema.json |  73 +-
 qmp-commands.hx  |   5 +
 qmp.c|  15 +-
 ui/vnc.c | 634 ++-
 ui/vnc.h |   5 +
 vl.c |  41 ++--
 8 files changed, 611 insertions(+), 198 deletions(-)



Re: [Qemu-devel] [PATCH v2 2/6] block: vmdk - move string allocations from stack to the heap

2015-01-22 Thread Stefan Hajnoczi
On Tue, Jan 20, 2015 at 12:31:29PM -0500, Jeff Cody wrote:
 @@ -792,12 +792,11 @@ static int vmdk_parse_extents(const char *desc, 
 BlockDriverState *bs,
  const char *p = desc;
  int64_t sectors = 0;
  int64_t flat_offset;
 -char extent_path[PATH_MAX];
 +char *extent_path = g_malloc0(PATH_MAX);

Simpler alternative that has no risk of memory leaks:

  extent_path = g_malloc0(PATH_MAX);
  path_combine(extent_path, sizeof(extent_path),
  desc_file_path, fname);
  extent_file = NULL;
  ret = bdrv_open(extent_file, extent_path, NULL, NULL,
  bs-open_flags | BDRV_O_PROTOCOL, NULL, errp);
  g_free(extent_path);
  if (ret) {
  goto exit;
  }


pgpUS9cSCN3Be.pgp
Description: PGP signature


[Qemu-devel] [PULL 0/1] sb16: fix interrupt acknowledgement

2015-01-22 Thread Gerd Hoffmann
  Hi,

Pretty short audio queue, with a single soundblaster bugfix.

please pull,
  Gerd

The following changes since commit 699eae17b841e6784dc3864bf357e26bff1e9dfe:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-misc-20150120' into 
staging (2015-01-20 16:19:58 +)

are available in the git repository at:


  git://git.kraxel.org/qemu tags/pull-audio-20150122-1

for you to fetch changes up to 9939375c282a0f97afa69dc6799d3c77aaf7d544:

  sb16: fix interrupt acknowledgement (2015-01-22 11:04:18 +0100)


b16: fix interrupt acknowledgement


Paolo Bonzini (1):
  sb16: fix interrupt acknowledgement

 hw/audio/sb16.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)



Re: [Qemu-devel] Running read-only internal snapshot (loadvm)

2015-01-22 Thread Stefan Hajnoczi
On Wed, Jan 21, 2015 at 01:53:15PM +0200, Jarkko Turkulainen wrote:
 Is it possible to do -loadvm with a read-only image? What I'm trying to do
 is running already booted OS but discarding all the changes. So basically,
 I'd like to combine -loadvm and -snapshot. The image needs to be read-only
 because there are multiple simultaneous instances running. As a workaround,
 I've been doing the -loadvm on a temporary copy of the image, but that is
 not really effective, it takes time (or memory) to copy the image around.

If the host file system supports reflink then cp(1) can make a cheap
(shared) copy.  See the cp(1) man page.

I looked at QEMU's load_vmstate() function, which is used to load an
internal snapshot.

Unfortunately it checks that the drive is writable since loading a qcow2
internal snapshot involves writes to the image file.

Instead of qcow2 internal snapshots, you could look at migrating to
file:

1. Create the master image by migrating to file:
   
http://www.linux-kvm.org/page/Migration#savevm.2Floadvm_to_an_external_state_file_.28using_pseudo-migration.29

2. Instantiate a new guest:
   qemu -incoming 'exec:gzip -d master.vmstate.gz' \
-drive if=virtio,snapshot=on,file=master.img,format=raw \
...

I haven't tested it or looked for the optimal syntax/sequence of
commands.  Still, I think that's your best bet.

Stefan


pgpkbs4F0ahk6.pgp
Description: PGP signature


[Qemu-devel] [PATCH v3 6/6] block: update string sizes for filename, backing_file, exact_filename

2015-01-22 Thread Jeff Cody
The string field entries 'filename', 'backing_file', and
'exact_filename' in the BlockDriverState struct are defined as 1024
bytes.

However, many places that use these values accept a maximum of PATH_MAX
bytes, so we have a mixture of 1024 byte and PATH_MAX byte allocations.
This patch makes the BlockDriverStruct field string sizes match usage.

This patch also does a few fixes related to the size that needs to
happen now:

* the block qapi driver is updated to use PATH_MAX bytes
* the qcow and qcow2 drivers have an additional safety check
* the block vvfat driver is updated to use PATH_MAX bytes
  for the size of backing_file, for systems where PATH_MAX is  1024
  bytes.
* qemu-img uses PATH_MAX rather than 1024.  These instances were not
  changed to be dynamically allocated, however, as the extra
  temporary 3K in stack usage for qemu-img does not seem worrisome.

Reviewed-by: Stefan Hajnoczi stefa...@redhat.com
Reviewed-by: John Snow js...@redhat.com
Signed-off-by: Jeff Cody jc...@redhat.com
---
 block/qapi.c  | 4 ++--
 block/qcow.c  | 2 +-
 block/qcow2.c | 3 ++-
 block/vvfat.c | 4 ++--
 include/block/block_int.h | 8 
 qemu-img.c| 4 ++--
 6 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/block/qapi.c b/block/qapi.c
index dec9f60..75c388e 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -210,10 +210,10 @@ void bdrv_query_image_info(BlockDriverState *bs,
 
 backing_filename = bs-backing_file;
 if (backing_filename[0] != '\0') {
-char *backing_filename2 = g_malloc0(1024);
+char *backing_filename2 = g_malloc0(PATH_MAX);
 info-backing_filename = g_strdup(backing_filename);
 info-has_backing_filename = true;
-bdrv_get_full_backing_filename(bs, backing_filename2, 1024, err);
+bdrv_get_full_backing_filename(bs, backing_filename2, PATH_MAX, err);
 if (err) {
 error_propagate(errp, err);
 qapi_free_ImageInfo(info);
diff --git a/block/qcow.c b/block/qcow.c
index ece2269..ccbe9e0 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -215,7 +215,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, 
int flags,
 /* read the backing file name */
 if (header.backing_file_offset != 0) {
 len = header.backing_file_size;
-if (len  1023) {
+if (len  1023 || len  sizeof(bs-backing_file)) {
 error_setg(errp, Backing file name too long);
 ret = -EINVAL;
 goto fail;
diff --git a/block/qcow2.c b/block/qcow2.c
index e4e690a..dbaf016 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -868,7 +868,8 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, 
int flags,
 /* read the backing file name */
 if (header.backing_file_offset != 0) {
 len = header.backing_file_size;
-if (len  MIN(1023, s-cluster_size - header.backing_file_offset)) {
+if (len  MIN(1023, s-cluster_size - header.backing_file_offset) ||
+len  sizeof(bs-backing_file)) {
 error_setg(errp, Backing file name too long);
 ret = -EINVAL;
 goto fail;
diff --git a/block/vvfat.c b/block/vvfat.c
index e34a789..a1a44f0 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2909,8 +2909,8 @@ static int enable_write_target(BDRVVVFATState *s, Error 
**errp)
 
 array_init((s-commits), sizeof(commit_t));
 
-s-qcow_filename = g_malloc(1024);
-ret = get_tmp_filename(s-qcow_filename, 1024);
+s-qcow_filename = g_malloc(PATH_MAX);
+ret = get_tmp_filename(s-qcow_filename, PATH_MAX);
 if (ret  0) {
 error_setg_errno(errp, -ret, can't create temporary file);
 goto err;
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 06a21dd..e264be9 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -339,13 +339,13 @@ struct BlockDriverState {
  * regarding this BDS's context */
 QLIST_HEAD(, BdrvAioNotifier) aio_notifiers;
 
-char filename[1024];
-char backing_file[1024]; /* if non zero, the image is a diff of
-this file image */
+char filename[PATH_MAX];
+char backing_file[PATH_MAX]; /* if non zero, the image is a diff of
+this file image */
 char backing_format[16]; /* if non-zero and backing_file exists */
 
 QDict *full_open_options;
-char exact_filename[1024];
+char exact_filename[PATH_MAX];
 
 BlockDriverState *backing_hd;
 BlockDriverState *file;
diff --git a/qemu-img.c b/qemu-img.c
index 7876258..4e9a7f5 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2556,7 +2556,7 @@ static int img_rebase(int argc, char **argv)
 
 /* For safe rebasing we need to compare old and new backing file */
 if (!unsafe) {
-char backing_name[1024];
+char backing_name[PATH_MAX];
 
 blk_old_backing = blk_new_with_bs(old_backing, 

[Qemu-devel] [PULL 09/10] monitor: add query-vnc-servers command

2015-01-22 Thread Gerd Hoffmann
Add new query vnc qmp command, for the lack of better ideas just name it
query-vnc-servers.  Changes over query-vnc:

 * It returns a list of vnc servers, so multiple vnc server instances
   are covered.
 * Each vnc server returns a list of server sockets.  Followup patch
   will use that to also report websockets.  In case we add support for
   multiple server sockets server sockets (to better support ipv4+ipv6
   dualstack) we can add them to the list too.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 qapi-schema.json |  68 
 qmp-commands.hx  |   5 +++
 ui/vnc.c | 133 +++
 3 files changed, 206 insertions(+)

diff --git a/qapi-schema.json b/qapi-schema.json
index fbfc52f..24f62a4 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -751,6 +751,63 @@
'*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} }
 
 ##
+# @VncPriAuth:
+#
+# vnc primary authentication method.
+#
+# Since: 2.3
+##
+{ 'enum': 'VncPrimaryAuth',
+  'data': [ 'none', 'vnc', 'ra2', 'ra2ne', 'tight', 'ultra',
+'tls', 'vencrypt', 'sasl' ] }
+
+##
+# @VncVencryptSubAuth:
+#
+# vnc sub authentication method with vencrypt.
+#
+# Since: 2.3
+##
+{ 'enum': 'VncVencryptSubAuth',
+  'data': [ 'plain',
+'tls-none',  'x509-none',
+'tls-vnc',   'x509-vnc',
+'tls-plain', 'x509-plain',
+'tls-sasl',  'x509-sasl' ] }
+
+##
+# @VncInfo2:
+#
+# Information about a vnc server
+#
+# @id: vnc server name.
+#
+# @server: A list of @VncBasincInfo describing all listening sockets.
+#  The list can be empty (in case the vnc server is disabled).
+#  It also may have multiple entries: normal + websocket,
+#  possibly also ipv4 + ipv6 in the future.
+#
+# @clients: A list of @VncClientInfo of all currently connected clients.
+#   The list can be empty, for obvious reasons.
+#
+# @auth: The current authentication type used by the server
+#
+# @vencrypt: #optional The vencrypt sub authentication type used by the server,
+#only specified in case auth == vencrypt.
+#
+# @display: #optional The display device the vnc server is linked to.
+#
+# Since: 2.3
+##
+{ 'type': 'VncInfo2',
+  'data': { 'id': 'str',
+'server': ['VncBasicInfo'],
+'clients'   : ['VncClientInfo'],
+'auth'  : 'VncPrimaryAuth',
+'*vencrypt' : 'VncVencryptSubAuth',
+'*display'  : 'str' } }
+
+##
 # @query-vnc:
 #
 # Returns information about the current VNC server
@@ -762,6 +819,17 @@
 { 'command': 'query-vnc', 'returns': 'VncInfo' }
 
 ##
+# @query-vnc-servers:
+#
+# Returns a list of vnc servers.  The list can be empty.
+#
+# Returns: a list of @VncInfo2
+#
+# Since: 2.3
+##
+{ 'command': 'query-vnc-servers', 'returns': ['VncInfo2'] }
+
+##
 # @SpiceBasicInfo
 #
 # The basic information for SPICE network connection
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 8957201..c5f16dd 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2867,6 +2867,11 @@ EQMP
 .args_type  = ,
 .mhandler.cmd_new = qmp_marshal_input_query_vnc,
 },
+{
+.name   = query-vnc-servers,
+.args_type  = ,
+.mhandler.cmd_new = qmp_marshal_input_query_vnc_servers,
+},
 
 SQMP
 query-spice
diff --git a/ui/vnc.c b/ui/vnc.c
index cd757a3..c85d9c3 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -456,6 +456,139 @@ out_error:
 return NULL;
 }
 
+static VncBasicInfoList *qmp_query_server_entry(int socket,
+VncBasicInfoList *prev)
+{
+VncBasicInfoList *list;
+VncBasicInfo *info;
+struct sockaddr_storage sa;
+socklen_t salen = sizeof(sa);
+char host[NI_MAXHOST];
+char serv[NI_MAXSERV];
+
+if (getsockname(socket, (struct sockaddr *)sa, salen)  0 ||
+getnameinfo((struct sockaddr *)sa, salen,
+host, sizeof(host), serv, sizeof(serv),
+NI_NUMERICHOST | NI_NUMERICSERV)  0) {
+return prev;
+}
+
+info = g_new0(VncBasicInfo, 1);
+info-host = g_strdup(host);
+info-service = g_strdup(serv);
+info-family = inet_netfamily(sa.ss_family);
+
+list = g_new0(VncBasicInfoList, 1);
+list-value = info;
+list-next = prev;
+return list;
+}
+
+static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
+{
+switch (vd-auth) {
+case VNC_AUTH_VNC:
+info-auth = VNC_PRIMARY_AUTH_VNC;
+break;
+case VNC_AUTH_RA2:
+info-auth = VNC_PRIMARY_AUTH_RA2;
+break;
+case VNC_AUTH_RA2NE:
+info-auth = VNC_PRIMARY_AUTH_RA2NE;
+break;
+case VNC_AUTH_TIGHT:
+info-auth = VNC_PRIMARY_AUTH_TIGHT;
+break;
+case VNC_AUTH_ULTRA:
+info-auth = VNC_PRIMARY_AUTH_ULTRA;
+break;
+case VNC_AUTH_TLS:
+info-auth = VNC_PRIMARY_AUTH_TLS;
+break;
+case 

[Qemu-devel] [PULL 08/10] vnc: factor out qmp_query_client_list

2015-01-22 Thread Gerd Hoffmann
so we can reuse it for the new vnc query command.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 ui/vnc.c | 30 +++---
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 8c40c8f..cd757a3 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -385,6 +385,20 @@ static VncDisplay *vnc_display_find(const char *id)
 return NULL;
 }
 
+static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
+{
+VncClientInfoList *cinfo, *prev = NULL;
+VncState *client;
+
+QTAILQ_FOREACH(client, vd-clients, next) {
+cinfo = g_new0(VncClientInfoList, 1);
+cinfo-value = qmp_query_vnc_client(client);
+cinfo-next = prev;
+prev = cinfo;
+}
+return prev;
+}
+
 VncInfo *qmp_query_vnc(Error **errp)
 {
 VncInfo *info = g_malloc0(sizeof(*info));
@@ -393,30 +407,16 @@ VncInfo *qmp_query_vnc(Error **errp)
 if (vd == NULL || vd-display == NULL) {
 info-enabled = false;
 } else {
-VncClientInfoList *cur_item = NULL;
 struct sockaddr_storage sa;
 socklen_t salen = sizeof(sa);
 char host[NI_MAXHOST];
 char serv[NI_MAXSERV];
-VncState *client;
 
 info-enabled = true;
 
 /* for compatibility with the original command */
 info-has_clients = true;
-
-QTAILQ_FOREACH(client, vd-clients, next) {
-VncClientInfoList *cinfo = g_malloc0(sizeof(*info));
-cinfo-value = qmp_query_vnc_client(client);
-
-/* XXX: waiting for the qapi to support GSList */
-if (!cur_item) {
-info-clients = cur_item = cinfo;
-} else {
-cur_item-next = cinfo;
-cur_item = cinfo;
-}
-}
+info-clients = qmp_query_client_list(vd);
 
 if (vd-lsock == -1) {
 return info;
-- 
1.8.3.1




[Qemu-devel] [PULL 06/10] vnc: update docs/multiseat.txt

2015-01-22 Thread Gerd Hoffmann
vnc joins the party ;)
Also some s/head/seat/ to clarify.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 docs/multiseat.txt | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/docs/multiseat.txt b/docs/multiseat.txt
index 67151e0..b963665 100644
--- a/docs/multiseat.txt
+++ b/docs/multiseat.txt
@@ -7,7 +7,7 @@ host side
 
 First you must compile qemu with a user interface supporting
 multihead/multiseat and input event routing.  Right now this
-list includes sdl2 and gtk (both 2+3):
+list includes sdl2, gtk (both 2+3) and vnc:
 
   ./configure --enable-sdl --with-sdlabi=2.0
 
@@ -16,16 +16,16 @@ or
   ./configure --enable-gtk
 
 
-Next put together the qemu command line:
+Next put together the qemu command line (sdk/gtk):
 
 qemu   -enable-kvm -usb $memory $disk $whatever \
-display [ sdl | gtk ] \
-vga std \
-device usb-tablet
 
-That is it for the first head, which will use the standard vga, the
+That is it for the first seat, which will use the standard vga, the
 standard ps/2 keyboard (implicitly there) and the usb-tablet.  Now the
-additional switches for the second head:
+additional switches for the second seat:
 
-device pci-bridge,addr=12.0,chassis_nr=2,id=head.2 \
-device secondary-vga,bus=head.2,addr=02.0,id=video.2 \
@@ -47,6 +47,16 @@ in a separate tab.  You can either simply switch tabs to 
switch heads,
 or use the View / Detach tab menu item to move one of the displays
 to its own window so you can see both display devices side-by-side.
 
+For vnc some additional configuration on the command line is needed.
+We'll create two vnc server instances, and bind the second one to the
+second seat, simliar to input devices:
+
+   -display vnc=:1,id=primary \
+   -display vnc=:2,id=secondary,display=video.2
+
+Connecting to vnc display :1 gives you access to the first seat, and
+likewise connecting to vnc display :2 shows the second seat.
+
 Note on spice: Spice handles multihead just fine.  But it can't do
 multiseat.  For tablet events the event source is sent to the spice
 agent.  But qemu can't figure it, so it can't do input routing.
-- 
1.8.3.1




[Qemu-devel] [PULL 05/10] vnc: allow binding servers to qemu consoles

2015-01-22 Thread Gerd Hoffmann
This patch adds a display= parameter to the vnc options.  This allows to
bind a vnc server instance to a specific display, allowing to create a
multiseat setup with a vnc server for each seat.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 ui/vnc.c | 50 +++---
 1 file changed, 43 insertions(+), 7 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 24cf08b..091e809 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -27,6 +27,7 @@
 #include vnc.h
 #include vnc-jobs.h
 #include trace.h
+#include hw/qdev.h
 #include sysemu/sysemu.h
 #include qemu/sockets.h
 #include qemu/timer.h
@@ -1665,7 +1666,8 @@ static void do_key_event(VncState *vs, int down, int 
keycode, int sym)
 vs-modifiers_state[keycode] = 0;
 break;
 case 0x02 ... 0x0a: /* '1' to '9' keys */
-if (down  vs-modifiers_state[0x1d]  vs-modifiers_state[0x38]) {
+if (vs-vd-dcl.con == NULL 
+down  vs-modifiers_state[0x1d]  vs-modifiers_state[0x38]) {
 /* Reset the modifiers sent to the current console */
 reset_keys(vs);
 console_select(keycode - 0x02);
@@ -2073,8 +2075,8 @@ static void set_pixel_format(VncState *vs,
 
 set_pixel_conversion(vs);
 
-graphic_hw_invalidate(NULL);
-graphic_hw_update(NULL);
+graphic_hw_invalidate(vs-vd-dcl.con);
+graphic_hw_update(vs-vd-dcl.con);
 }
 
 static void pixel_format_message (VncState *vs) {
@@ -2801,7 +2803,7 @@ static void vnc_refresh(DisplayChangeListener *dcl)
 return;
 }
 
-graphic_hw_update(NULL);
+graphic_hw_update(vd-dcl.con);
 
 if (vnc_trylock_display(vd)) {
 update_displaychangelistener(vd-dcl, VNC_REFRESH_INTERVAL_BASE);
@@ -2907,7 +2909,7 @@ void vnc_init_state(VncState *vs)
 
 QTAILQ_INSERT_HEAD(vd-clients, vs, next);
 
-graphic_hw_update(NULL);
+graphic_hw_update(vd-dcl.con);
 
 vnc_write(vs, RFB 003.008\n, 12);
 vnc_flush(vs);
@@ -2930,7 +2932,7 @@ static void vnc_listen_read(void *opaque, bool websocket)
 int csock;
 
 /* Catch-up */
-graphic_hw_update(NULL);
+graphic_hw_update(vs-dcl.con);
 #ifdef CONFIG_VNC_WS
 if (websocket) {
 csock = qemu_accept(vs-lwebsock, (struct sockaddr *)addr, addrlen);
@@ -3090,6 +3092,12 @@ static QemuOptsList qemu_vnc_opts = {
 .name = share,
 .type = QEMU_OPT_STRING,
 },{
+.name = display,
+.type = QEMU_OPT_STRING,
+},{
+.name = head,
+.type = QEMU_OPT_NUMBER,
+},{
 .name = password,
 .type = QEMU_OPT_BOOL,
 },{
@@ -3125,7 +3133,8 @@ void vnc_display_open(const char *id, Error **errp)
 {
 VncDisplay *vs = vnc_display_find(id);
 QemuOpts *opts = qemu_opts_find(qemu_vnc_opts, id);
-const char *display, *websocket, *share;
+const char *display, *websocket, *share, *device_id;
+QemuConsole *con;
 int password = 0;
 int reverse = 0;
 #ifdef CONFIG_VNC_TLS
@@ -3354,6 +3363,33 @@ void vnc_display_open(const char *id, Error **errp)
 #endif
 vs-lock_key_sync = lock_key_sync;
 
+device_id = qemu_opt_get(opts, display);
+if (device_id) {
+DeviceState *dev;
+int head = qemu_opt_get_number(opts, head, 0);
+
+dev = qdev_find_recursive(sysbus_get_default(), device_id);
+if (dev == NULL) {
+error_set(errp, QERR_DEVICE_NOT_FOUND, device_id);
+goto fail;
+}
+
+con = qemu_console_lookup_by_device(dev, head);
+if (con == NULL) {
+error_setg(errp, Device %s is not bound to a QemuConsole,
+   device_id);
+goto fail;
+}
+} else {
+con = NULL;
+}
+
+if (con != vs-dcl.con) {
+unregister_displaychangelistener(vs-dcl);
+vs-dcl.con = con;
+register_displaychangelistener(vs-dcl);
+}
+
 if (reverse) {
 /* connect to viewer */
 int csock;
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v2 4/6] block: move string allocation from stack to the heap

2015-01-22 Thread Stefan Hajnoczi
On Tue, Jan 20, 2015 at 12:31:31PM -0500, Jeff Cody wrote:
 Rather than allocate PATH_MAX bytes on the stack, use g_strndup() to
 dynamically allocate the string, and add an exit label for cleanup.
 
 Signed-off-by: Jeff Cody jc...@redhat.com
 ---
  block.c | 11 +++
  1 file changed, 7 insertions(+), 4 deletions(-)

Zombie alert!

This is a funny:

Since September 2012 in commit 0bce597d6ec34b2af802799eb53ebc863c704d05
(block: convert bdrv_commit() to use bdrv_reopen()) the filename
variable has not been used.

We continued to maintain this variable faithfully, for example, to fix a
buffer overflow in commit c2cba3d9314f972dfaf724d0ec2d018eb54c95f1
(block: avoid buffer overrun by using pstrcpy, not strncpy).

Please kill the zombie filename variable instead of switching to heap
allocation :-).


pgpm2gtd2DAUH.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH v2 6/6] block: update string sizes for filename, backing_file, exact_filename

2015-01-22 Thread Stefan Hajnoczi
On Tue, Jan 20, 2015 at 12:31:33PM -0500, Jeff Cody wrote:
 The string field entries 'filename', 'backing_file', and
 'exact_filename' in the BlockDriverState struct are defined as 1024
 bytes.
 
 However, many places that use these values accept a maximum of PATH_MAX
 bytes, so we have a mixture of 1024 byte and PATH_MAX byte allocations.
 This patch makes the BlockDriverStruct field string sizes match usage.
 
 This patch also does a few fixes related to the size that needs to
 happen now:
 
 * the block qapi driver is updated to use PATH_MAX bytes
 * the qcow and qcow2 drivers have an additional safety check
 * the block vvfat driver is updated to use PATH_MAX bytes
   for the size of backing_file, for systems where PATH_MAX is  1024
   bytes.
 * qemu-img uses PATH_MAX rather than 1024.  These instances were not
   changed to be dynamically allocated, however, as the extra
   temporary 3K in stack usage for qemu-img does not seem worrisome.
 
 Signed-off-by: Jeff Cody jc...@redhat.com
 ---
  block/qapi.c  | 4 ++--
  block/qcow.c  | 2 +-
  block/qcow2.c | 3 ++-
  block/vvfat.c | 4 ++--
  include/block/block_int.h | 8 
  qemu-img.c| 4 ++--
  6 files changed, 13 insertions(+), 12 deletions(-)

Reviewed-by: Stefan Hajnoczi stefa...@redhat.com


pgpt5a6r039zv.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCHv2 5/7] target-ppc: force update of msr bits in cpu_post_load

2015-01-22 Thread Alexander Graf


On 21.01.15 17:01, Mark Cave-Ayland wrote:
 Since env-msr has already been restored by the time cpu_post_load is called,
 make sure that ppc_store_msr() is explicitly called with all msr bits except
 MSR_TGPR marked as invalid.
 
 This solves the issue where MSR flags aren't set correctly when restoring a VM
 snapshot, in particular the internal env-excp_prefix value when MSR_EP has
 been altered by a guest.
 
 Signed-off-by: Mark Cave-Ayland mark.cave-ayl...@ilande.co.uk
 ---
  target-ppc/machine.c |8 +++-
  1 file changed, 7 insertions(+), 1 deletion(-)
 
 diff --git a/target-ppc/machine.c b/target-ppc/machine.c
 index c801b82..fc8ddcd 100644
 --- a/target-ppc/machine.c
 +++ b/target-ppc/machine.c
 @@ -159,6 +159,7 @@ static int cpu_post_load(void *opaque, int version_id)
  PowerPCCPU *cpu = opaque;
  CPUPPCState *env = cpu-env;
  int i;
 +target_ulong msr;
  
  /*
   * We always ignore the source PVR. The user or management
 @@ -190,7 +191,12 @@ static int cpu_post_load(void *opaque, int version_id)
  /* Restore htab_base and htab_mask variables */
  ppc_store_sdr1(env, env-spr[SPR_SDR1]);
  }
 -hreg_compute_hflags(env);
 +
 +/* Mark msr bits except MSR_TGPR invalid before restoring */
 +msr = env-msr;
 +env-msr ^= ~(1  MSR_TGPR);

Doesn't this need to be 1ULL?


Alex

 +ppc_store_msr(env, msr);
 +
  hreg_compute_mem_idx(env);
  
  return 0;
 



Re: [Qemu-devel] [PATCH] sparse: Fix build with sparse on .S files

2015-01-22 Thread Paolo Bonzini


On 22/01/2015 10:53, Christian Borntraeger wrote:
 rules.mak has a rule for .S files using CPP. This will result in
 errors like
   CPP   s390-ccw/start.asm
  cc: error: unrecognized command line option '-Wbitwise'
 
 Lets also redefine CPP in case of --enable-sparse.
 
 Signed-off-by: Christian Borntraeger borntrae...@de.ibm.com
 ---
  configure | 1 +
  1 file changed, 1 insertion(+)
 
 diff --git a/configure b/configure
 index 47048f0..3bdda2e 100755
 --- a/configure
 +++ b/configure
 @@ -4909,6 +4909,7 @@ echo QEMU_CFLAGS=$QEMU_CFLAGS  $config_host_mak
  echo QEMU_INCLUDES=$QEMU_INCLUDES  $config_host_mak
  if test $sparse = yes ; then
echo CC   := REAL_CC=\\$(CC)\ cgcc$config_host_mak
 +  echo CPP  := REAL_CC=\\$(CPP)\ cgcc   $config_host_mak
echo CXX  := REAL_CC=\\$(CXX)\ cgcc   $config_host_mak
echo HOST_CC  := REAL_CC=\\$(HOST_CC)\ cgcc   $config_host_mak
echo QEMU_CFLAGS  += -Wbitwise -Wno-transparent-union 
 -Wno-old-initializer -Wno-non-pointer-null  $config_host_mak
 

Queued, thanks.

Paolo



[Qemu-devel] [PULL 02/10] vnc: remove unused DisplayState parameter, add id instead.

2015-01-22 Thread Gerd Hoffmann
DisplayState isn't used anywhere, drop it.  Add the vnc server ID as
parameter instead, so it is possible to specify the server instance.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
Reviewed-by: Gonglei arei.gong...@huawei.com
---
 include/ui/console.h | 16 
 ui/vnc.c | 29 ++---
 vl.c |  7 ---
 3 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/include/ui/console.h b/include/ui/console.h
index 047b6da..03358b4 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -331,19 +331,19 @@ void sdl_display_init(DisplayState *ds, int full_screen, 
int no_frame);
 void cocoa_display_init(DisplayState *ds, int full_screen);
 
 /* vnc.c */
-void vnc_display_init(DisplayState *ds);
-void vnc_display_open(DisplayState *ds, const char *display, Error **errp);
-void vnc_display_add_client(DisplayState *ds, int csock, bool skipauth);
-char *vnc_display_local_addr(DisplayState *ds);
+void vnc_display_init(const char *id);
+void vnc_display_open(const char *id, const char *display, Error **errp);
+void vnc_display_add_client(const char *id, int csock, bool skipauth);
+char *vnc_display_local_addr(const char *id);
 #ifdef CONFIG_VNC
-int vnc_display_password(DisplayState *ds, const char *password);
-int vnc_display_pw_expire(DisplayState *ds, time_t expires);
+int vnc_display_password(const char *id, const char *password);
+int vnc_display_pw_expire(const char *id, time_t expires);
 #else
-static inline int vnc_display_password(DisplayState *ds, const char *password)
+static inline int vnc_display_password(const char *id, const char *password)
 {
 return -ENODEV;
 }
-static inline int vnc_display_pw_expire(DisplayState *ds, time_t expires)
+static inline int vnc_display_pw_expire(const char *id, time_t expires)
 {
 return -ENODEV;
 };
diff --git a/ui/vnc.c b/ui/vnc.c
index 27e4d26..d988275 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2968,10 +2968,11 @@ static const DisplayChangeListenerOps dcl_ops = {
 .dpy_cursor_define= vnc_dpy_cursor_define,
 };
 
-void vnc_display_init(DisplayState *ds)
+void vnc_display_init(const char *id)
 {
 VncDisplay *vs = g_malloc0(sizeof(*vs));
 
+vs-id = strdup(id);
 QTAILQ_INSERT_TAIL(vnc_displays, vs, next);
 
 vs-lsock = -1;
@@ -3000,10 +3001,8 @@ void vnc_display_init(DisplayState *ds)
 }
 
 
-static void vnc_display_close(DisplayState *ds)
+static void vnc_display_close(VncDisplay *vs)
 {
-VncDisplay *vs = vnc_display_find(NULL);
-
 if (!vs)
 return;
 g_free(vs-display);
@@ -3029,9 +3028,9 @@ static void vnc_display_close(DisplayState *ds)
 #endif
 }
 
-int vnc_display_password(DisplayState *ds, const char *password)
+int vnc_display_password(const char *id, const char *password)
 {
-VncDisplay *vs = vnc_display_find(NULL);
+VncDisplay *vs = vnc_display_find(id);
 
 if (!vs) {
 return -EINVAL;
@@ -3048,9 +3047,9 @@ int vnc_display_password(DisplayState *ds, const char 
*password)
 return 0;
 }
 
-int vnc_display_pw_expire(DisplayState *ds, time_t expires)
+int vnc_display_pw_expire(const char *id, time_t expires)
 {
-VncDisplay *vs = vnc_display_find(NULL);
+VncDisplay *vs = vnc_display_find(id);
 
 if (!vs) {
 return -EINVAL;
@@ -3060,16 +3059,16 @@ int vnc_display_pw_expire(DisplayState *ds, time_t 
expires)
 return 0;
 }
 
-char *vnc_display_local_addr(DisplayState *ds)
+char *vnc_display_local_addr(const char *id)
 {
-VncDisplay *vs = vnc_display_find(NULL);
+VncDisplay *vs = vnc_display_find(id);
 
 return vnc_socket_local_addr(%s:%s, vs-lsock);
 }
 
-void vnc_display_open(DisplayState *ds, const char *display, Error **errp)
+void vnc_display_open(const char *id, const char *display, Error **errp)
 {
-VncDisplay *vs = vnc_display_find(NULL);
+VncDisplay *vs = vnc_display_find(id);
 const char *options;
 int password = 0;
 int reverse = 0;
@@ -3089,7 +3088,7 @@ void vnc_display_open(DisplayState *ds, const char 
*display, Error **errp)
 error_setg(errp, VNC display not active);
 return;
 }
-vnc_display_close(ds);
+vnc_display_close(vs);
 if (strcmp(display, none) == 0)
 return;
 
@@ -3382,9 +3381,9 @@ fail:
 #endif /* CONFIG_VNC_WS */
 }
 
-void vnc_display_add_client(DisplayState *ds, int csock, bool skipauth)
+void vnc_display_add_client(const char *id, int csock, bool skipauth)
 {
-VncDisplay *vs = vnc_display_find(NULL);
+VncDisplay *vs = vnc_display_find(id);
 
 if (!vs) {
 return;
diff --git a/vl.c b/vl.c
index fbf4240..9fb32c1 100644
--- a/vl.c
+++ b/vl.c
@@ -4288,8 +4288,9 @@ int main(int argc, char **argv, char **envp)
 /* init remote displays */
 if (vnc_display) {
 Error *local_err = NULL;
-vnc_display_init(ds);
-vnc_display_open(ds, vnc_display, local_err);
+const char *id = default;
+vnc_display_init(id);
+vnc_display_open(id, 

[Qemu-devel] [PULL 10/10] monitor: add vnc websockets

2015-01-22 Thread Gerd Hoffmann
Add websockets bool to VncBasicInfo, report websocket server sockets,
flag websocket client connections.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 qapi-schema.json |  5 -
 ui/vnc.c | 15 ---
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index 24f62a4..eec1d22 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -672,12 +672,15 @@
 #
 # @family: address family
 #
+# @websocket: true in case the socket is a websocket (since 2.3).
+#
 # Since: 2.1
 ##
 { 'type': 'VncBasicInfo',
   'data': { 'host': 'str',
 'service': 'str',
-'family': 'NetworkAddressFamily' } }
+'family': 'NetworkAddressFamily',
+'websocket': 'bool' } }
 
 ##
 # @VncServerInfo
diff --git a/ui/vnc.c b/ui/vnc.c
index c85d9c3..a742c90 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -353,6 +353,9 @@ static VncClientInfo *qmp_query_vnc_client(const VncState 
*client)
 info-base-host = g_strdup(host);
 info-base-service = g_strdup(serv);
 info-base-family = inet_netfamily(sa.ss_family);
+#ifdef CONFIG_VNC_WS
+info-base-websocket = client-websocket;
+#endif
 
 #ifdef CONFIG_VNC_TLS
 if (client-tls.session  client-tls.dname) {
@@ -457,6 +460,7 @@ out_error:
 }
 
 static VncBasicInfoList *qmp_query_server_entry(int socket,
+bool websocket,
 VncBasicInfoList *prev)
 {
 VncBasicInfoList *list;
@@ -477,6 +481,7 @@ static VncBasicInfoList *qmp_query_server_entry(int socket,
 info-host = g_strdup(host);
 info-service = g_strdup(serv);
 info-family = inet_netfamily(sa.ss_family);
+info-websocket = websocket;
 
 list = g_new0(VncBasicInfoList, 1);
 list-value = info;
@@ -572,12 +577,13 @@ VncInfo2List *qmp_query_vnc_servers(Error **errp)
 info-display = g_strdup(dev-id);
 }
 if (vd-lsock != -1) {
-info-server = qmp_query_server_entry(vd-lsock,
+info-server = qmp_query_server_entry(vd-lsock, false,
   info-server);
 }
 #ifdef CONFIG_VNC_WS
 if (vd-lwebsock != -1) {
-/* TODO */
+info-server = qmp_query_server_entry(vd-lwebsock, true,
+  info-server);
 }
 #endif
 
@@ -3305,10 +3311,13 @@ void vnc_display_open(const char *id, Error **errp)
 {
 VncDisplay *vs = vnc_display_find(id);
 QemuOpts *opts = qemu_opts_find(qemu_vnc_opts, id);
-const char *display, *websocket, *share, *device_id;
+const char *display, *share, *device_id;
 QemuConsole *con;
 int password = 0;
 int reverse = 0;
+#ifdef CONFIG_VNC_WS
+const char *websocket;
+#endif
 #ifdef CONFIG_VNC_TLS
 int tls = 0, x509 = 0;
 const char *path;
-- 
1.8.3.1




[Qemu-devel] [PULL 07/10] vnc: track limit connections

2015-01-22 Thread Gerd Hoffmann
Also track the number of connections in connecting and shared state
(in addition to the exclusive state).  Apply a configurable limit to
these connections.

The logic to apply the limit to connections in shared state is pretty
simple:  When the limit is reached no new connections are allowed.

The logic to apply the limit to connections in connecting state (this
is the state you are in *before* successful authentication) is
slightly different:  A new connect kicks out the oldest client which is
still in connecting state.  This avoids a easy DoS by unauthenticated
users by simply opening connections until the limit is reached.

Cc: Dr. David Alan Gilbert dgilb...@redhat.com
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 ui/vnc.c | 46 +++---
 ui/vnc.h |  3 +++
 2 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 091e809..8c40c8f 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -68,12 +68,34 @@ static void vnc_set_share_mode(VncState *vs, VncShareMode 
mode)
 vs-csock, mn[vs-share_mode], mn[mode]);
 #endif
 
-if (vs-share_mode == VNC_SHARE_MODE_EXCLUSIVE) {
+switch (vs-share_mode) {
+case VNC_SHARE_MODE_CONNECTING:
+vs-vd-num_connecting--;
+break;
+case VNC_SHARE_MODE_SHARED:
+vs-vd-num_shared--;
+break;
+case VNC_SHARE_MODE_EXCLUSIVE:
 vs-vd-num_exclusive--;
+break;
+default:
+break;
 }
+
 vs-share_mode = mode;
-if (vs-share_mode == VNC_SHARE_MODE_EXCLUSIVE) {
+
+switch (vs-share_mode) {
+case VNC_SHARE_MODE_CONNECTING:
+vs-vd-num_connecting++;
+break;
+case VNC_SHARE_MODE_SHARED:
+vs-vd-num_shared++;
+break;
+case VNC_SHARE_MODE_EXCLUSIVE:
 vs-vd-num_exclusive++;
+break;
+default:
+break;
 }
 }
 
@@ -2337,6 +2359,11 @@ static int protocol_client_init(VncState *vs, uint8_t 
*data, size_t len)
 }
 vnc_set_share_mode(vs, mode);
 
+if (vs-vd-num_shared  vs-vd-connections_limit) {
+vnc_disconnect_start(vs);
+return 0;
+}
+
 vs-client_width = pixman_image_get_width(vs-vd-server);
 vs-client_height = pixman_image_get_height(vs-vd-server);
 vnc_write_u16(vs, vs-client_width);
@@ -2889,6 +2916,15 @@ static void vnc_connect(VncDisplay *vd, int csock,
 {
 vnc_init_state(vs);
 }
+
+if (vd-num_connecting  vd-connections_limit) {
+QTAILQ_FOREACH(vs, vd-clients, next) {
+if (vs-share_mode == VNC_SHARE_MODE_CONNECTING) {
+vnc_disconnect_start(vs);
+return;
+}
+}
+}
 }
 
 void vnc_init_state(VncState *vs)
@@ -2907,7 +2943,7 @@ void vnc_init_state(VncState *vs)
 qemu_mutex_init(vs-output_mutex);
 vs-bh = qemu_bh_new(vnc_jobs_bh, vs);
 
-QTAILQ_INSERT_HEAD(vd-clients, vs, next);
+QTAILQ_INSERT_TAIL(vd-clients, vs, next);
 
 graphic_hw_update(vd-dcl.con);
 
@@ -3098,6 +3134,9 @@ static QemuOptsList qemu_vnc_opts = {
 .name = head,
 .type = QEMU_OPT_NUMBER,
 },{
+.name = connections,
+.type = QEMU_OPT_NUMBER,
+},{
 .name = password,
 .type = QEMU_OPT_BOOL,
 },{
@@ -3211,6 +3250,7 @@ void vnc_display_open(const char *id, Error **errp)
 } else {
 vs-share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
 }
+vs-connections_limit = qemu_opt_get_number(opts, connections, 32);
 
  #ifdef CONFIG_VNC_WS
 websocket = qemu_opt_get(opts, websocket);
diff --git a/ui/vnc.h b/ui/vnc.h
index 6fe8278..5e2b1a5 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -150,7 +150,10 @@ typedef enum VncSharePolicy {
 struct VncDisplay
 {
 QTAILQ_HEAD(, VncState) clients;
+int num_connecting;
+int num_shared;
 int num_exclusive;
+int connections_limit;
 VncSharePolicy share_policy;
 int lsock;
 #ifdef CONFIG_VNC_WS
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 3/6] block: qapi - move string allocation from stack to the heap

2015-01-22 Thread Jeff Cody
Rather than declaring 'backing_filename2' on the stack in
bdrv_query_image_info(), dynamically allocate it on the heap.

Reviewed-by: John Snow js...@redhat.com
Signed-off-by: Jeff Cody jc...@redhat.com
---
 block/qapi.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/block/qapi.c b/block/qapi.c
index a6fd6f7..dec9f60 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -175,7 +175,6 @@ void bdrv_query_image_info(BlockDriverState *bs,
 {
 int64_t size;
 const char *backing_filename;
-char backing_filename2[1024];
 BlockDriverInfo bdi;
 int ret;
 Error *err = NULL;
@@ -211,13 +210,14 @@ void bdrv_query_image_info(BlockDriverState *bs,
 
 backing_filename = bs-backing_file;
 if (backing_filename[0] != '\0') {
+char *backing_filename2 = g_malloc0(1024);
 info-backing_filename = g_strdup(backing_filename);
 info-has_backing_filename = true;
-bdrv_get_full_backing_filename(bs, backing_filename2,
-   sizeof(backing_filename2), err);
+bdrv_get_full_backing_filename(bs, backing_filename2, 1024, err);
 if (err) {
 error_propagate(errp, err);
 qapi_free_ImageInfo(info);
+g_free(backing_filename2);
 return;
 }
 
@@ -231,6 +231,7 @@ void bdrv_query_image_info(BlockDriverState *bs,
 info-backing_filename_format = g_strdup(bs-backing_format);
 info-has_backing_filename_format = true;
 }
+g_free(backing_filename2);
 }
 
 ret = bdrv_query_snapshot_info_list(bs, info-snapshots, err);
-- 
1.9.3




Re: [Qemu-devel] [PATCH V11 2/3] i386: Add a Virtual Machine Generation ID device

2015-01-22 Thread Igor Mammedov
On Tue, 16 Dec 2014 17:50:43 +0200
Gal Hammer gham...@redhat.com wrote:

 Based on Microsoft's sepecifications (paper can be dowloaded from
 http://go.microsoft.com/fwlink/?LinkId=260709), add a device
 description to the SSDT ACPI table and its implementation.
 
 The GUID is set using a global vmgenid.uuid parameter.
 
 Signed-off-by: Gal Hammer gham...@redhat.com
 

 --- a/hw/i386/acpi-build.c
 +++ b/hw/i386/acpi-build.c
 @@ -257,6 +257,7 @@ static void acpi_get_pci_info(PcPciInfo *info)
  #define ACPI_BUILD_TABLE_FILE etc/acpi/tables
  #define ACPI_BUILD_RSDP_FILE etc/acpi/rsdp
  #define ACPI_BUILD_TPMLOG_FILE etc/tpm/log
 +#define ACPI_BUILD_VMGENID_FILE etc/vm-generation-id
  
  static void
  build_header(GArray *linker, GArray *table_data,
 @@ -1068,6 +1069,8 @@ build_ssdt(GArray *table_data, GArray *linker,
  {
  MachineState *machine = MACHINE(qdev_get_machine());
  uint32_t nr_mem = machine-ram_slots;
 +uint32_t vm_gid_physical_address;
 +uint32_t vm_gid_offset = 0;
  unsigned acpi_cpus = guest_info-apic_id_limit;
  int ssdt_start = table_data-len;
  uint8_t *ssdt_ptr;
 @@ -1096,6 +1099,21 @@ build_ssdt(GArray *table_data, GArray *linker,
  ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml),
ssdt_isa_pest[0], 16, misc-pvpanic_port);
  
 +if (vm_generation_id_set()) {
 +vm_gid_physical_address = ssdt_start + ssdt_acpi_vm_gid_addr[0];
 +bios_linker_loader_alloc(linker, ACPI_BUILD_VMGENID_FILE, 8, true);
 +bios_linker_loader_add_pointer(linker, ACPI_BUILD_VMGENID_FILE,
 +   ACPI_BUILD_TABLE_FILE,
 +   table_data,
 +   vm_gid_offset,
 +   sizeof(vm_gid_offset));
could some explain how this pointer magic works,
From my weak understanding it seems broken.
Lets see:

 [1] vm_gid_offset - must be pointer inside of dest_file blob 
(ACPI_BUILD_VMGENID_FILE)
 [2] vm_gid_offset - should hold offset of the place inside of src_file  
(ACPI_BUILD_TABLE_FILE) where to pointer inside of 
dest_file should point to

now:
  vm_gid_physical_address - holds [2] i.e. offset of VGIA constant in inside 
SSDT in ACPI_BUILD_TABLE_FILE.

 +ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml),
 +  ssdt_acpi_vm_gid_addr[0], 32, vm_gid_physical_address);
Then we write this offset into VGIA in ACPI_BUILD_TABLE_FILE.

After BIOS loads tables it's going to patch at
 [3] ACPI_BUILD_VMGENID_FILE + (vm_gid_offset - table_data-data) /* only god 
knows where it will be/

and on top of it write in it value:
 *(ACPI_BUILD_TABLE_FILE +  *[3])

This approach in general of patching arbitrary place in AML blob
to get PHY addr of buffer with UUID, is quite a hack, especially
in light of that we are trying to hide all direct access to AML
blobs with related pointer arithmetic and manual patching.

Why not reserve some potion of RAM and pass to BIOS/guest
a reservation so it won't be part of AddressRangeMemory or
AddressRangeACPI as MS spec requires? Then you won't need
jump all above hoops to just get buffer's PHY addr.


[...]
  typedef
 @@ -1790,6 +1811,11 @@ void acpi_setup(PcGuestInfo *guest_info)
  fw_cfg_add_file(guest_info-fw_cfg, ACPI_BUILD_TPMLOG_FILE,
  tables.tcpalog-data, acpi_data_len(tables.tcpalog));
  
 +/* Add a 128-bit fw cfg file which stores the VM generation id. */
 +g_array_set_size(tables.vmgenid, 16);
 +fw_cfg_add_file(guest_info-fw_cfg, ACPI_BUILD_VMGENID_FILE,
 +tables.vmgenid-data, tables.vmgenid-len);
shouldn't it be migratable? /i.e. acpi_add_rom_blob(...)/



Re: [Qemu-devel] [PATCH] Add trace messages to input.c.

2015-01-22 Thread Don Koch
On Thu, 22 Jan 2015 11:01:14 +0100
Gerd Hoffmann kra...@redhat.com wrote:

   Hi,
 
  I believe this was used for debugging vmware mouse support we've been
  working on.
 
 Wouldn't it be more useful to trace qemu_input_handler_* calls for that,
 especially qemu_input_handler_activate?  So you also see changes
 triggered by the guest, such as enabling vmmouse, or initializing the
 usb-tablet?

Could be. This was for an effort done in the past; so, I've forgetten the
context. We can drop this change, if you want.

Thanks,
-d

 cheers,
   Gerd
 
 



[Qemu-devel] [PULL 04/10] vnc: switch to QemuOpts, allow multiple servers

2015-01-22 Thread Gerd Hoffmann
This patch switches vnc over to QemuOpts, and it (more or less
as side effect) allows multiple vnc server instances.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 include/ui/console.h |   4 +-
 qmp.c|  15 ++-
 ui/vnc.c | 270 ---
 vl.c |  42 +++-
 4 files changed, 199 insertions(+), 132 deletions(-)

diff --git a/include/ui/console.h b/include/ui/console.h
index 03358b4..8a4d671 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -332,12 +332,14 @@ void cocoa_display_init(DisplayState *ds, int 
full_screen);
 
 /* vnc.c */
 void vnc_display_init(const char *id);
-void vnc_display_open(const char *id, const char *display, Error **errp);
+void vnc_display_open(const char *id, Error **errp);
 void vnc_display_add_client(const char *id, int csock, bool skipauth);
 char *vnc_display_local_addr(const char *id);
 #ifdef CONFIG_VNC
 int vnc_display_password(const char *id, const char *password);
 int vnc_display_pw_expire(const char *id, time_t expires);
+QemuOpts *vnc_parse_func(const char *str);
+int vnc_init_func(QemuOpts *opts, void *opaque);
 #else
 static inline int vnc_display_password(const char *id, const char *password)
 {
diff --git a/qmp.c b/qmp.c
index 0b4f131..963305c 100644
--- a/qmp.c
+++ b/qmp.c
@@ -368,7 +368,20 @@ void qmp_change_vnc_password(const char *password, Error 
**errp)
 
 static void qmp_change_vnc_listen(const char *target, Error **errp)
 {
-vnc_display_open(NULL, target, errp);
+QemuOptsList *olist = qemu_find_opts(vnc);
+QemuOpts *opts;
+
+if (strstr(target, id=)) {
+error_setg(errp, id not supported);
+return;
+}
+
+opts = qemu_opts_find(olist, default);
+if (opts) {
+qemu_opts_del(opts);
+}
+opts = vnc_parse_func(target);
+vnc_display_open(default, errp);
 }
 
 static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
diff --git a/ui/vnc.c b/ui/vnc.c
index 24b5540..24cf08b 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -31,6 +31,7 @@
 #include qemu/sockets.h
 #include qemu/timer.h
 #include qemu/acl.h
+#include qemu/config-file.h
 #include qapi/qmp/types.h
 #include qmp-commands.h
 #include qemu/osdep.h
@@ -2970,7 +2971,12 @@ static const DisplayChangeListenerOps dcl_ops = {
 
 void vnc_display_init(const char *id)
 {
-VncDisplay *vs = g_malloc0(sizeof(*vs));
+VncDisplay *vs;
+
+if (vnc_display_find(id) != NULL) {
+return;
+}
+vs = g_malloc0(sizeof(*vs));
 
 vs-id = strdup(id);
 QTAILQ_INSERT_TAIL(vnc_displays, vs, next);
@@ -3066,14 +3072,65 @@ char *vnc_display_local_addr(const char *id)
 return vnc_socket_local_addr(%s:%s, vs-lsock);
 }
 
-void vnc_display_open(const char *id, const char *display, Error **errp)
+static QemuOptsList qemu_vnc_opts = {
+.name = vnc,
+.head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
+.implied_opt_name = vnc,
+.desc = {
+{
+.name = vnc,
+.type = QEMU_OPT_STRING,
+},{
+.name = websocket,
+.type = QEMU_OPT_STRING,
+},{
+.name = x509,
+.type = QEMU_OPT_STRING,
+},{
+.name = share,
+.type = QEMU_OPT_STRING,
+},{
+.name = password,
+.type = QEMU_OPT_BOOL,
+},{
+.name = reverse,
+.type = QEMU_OPT_BOOL,
+},{
+.name = lock-key-sync,
+.type = QEMU_OPT_BOOL,
+},{
+.name = sasl,
+.type = QEMU_OPT_BOOL,
+},{
+.name = tls,
+.type = QEMU_OPT_BOOL,
+},{
+.name = x509verify,
+.type = QEMU_OPT_BOOL,
+},{
+.name = acl,
+.type = QEMU_OPT_BOOL,
+},{
+.name = lossy,
+.type = QEMU_OPT_BOOL,
+},{
+.name = non-adaptive,
+.type = QEMU_OPT_BOOL,
+},
+{ /* end of list */ }
+},
+};
+
+void vnc_display_open(const char *id, Error **errp)
 {
 VncDisplay *vs = vnc_display_find(id);
-const char *options;
+QemuOpts *opts = qemu_opts_find(qemu_vnc_opts, id);
+const char *display, *websocket, *share;
 int password = 0;
 int reverse = 0;
 #ifdef CONFIG_VNC_TLS
 int tls = 0, x509 = 0;
+const char *path;
 #endif
 #ifdef CONFIG_VNC_SASL
 int sasl = 0;
@@ -3089,115 +3146,86 @@ void vnc_display_open(const char *id, const char 
*display, Error **errp)
 return;
 }
 vnc_display_close(vs);
-if (strcmp(display, none) == 0)
-return;
 
+if (!opts) {
+return;
+}
+display = qemu_opt_get(opts, vnc);
+if (!display || strcmp(display, none) == 0) {
+return;
+}
 vs-display = g_strdup(display);
-vs-share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
-
-options = display;
-while ((options = strchr(options, ','))) {
- 

[Qemu-devel] [PULL 03/10] vnc: add display id to acl names

2015-01-22 Thread Gerd Hoffmann
In case the display id is default (which is the one you get if you
don't explicitly assign one) we keep the old name scheme, without
display, for backward compatibility reasons.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
Reviewed-by: Gonglei arei.gong...@huawei.com
---
 ui/vnc.c | 22 --
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index d988275..24b5540 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3207,18 +3207,36 @@ void vnc_display_open(const char *id, const char 
*display, Error **errp)
 
 #ifdef CONFIG_VNC_TLS
 if (acl  x509  vs-tls.x509verify) {
-if (!(vs-tls.acl = qemu_acl_init(vnc.x509dname))) {
+char *aclname;
+
+if (strcmp(vs-id, default) == 0) {
+aclname = g_strdup(vnc.x509dname);
+} else {
+aclname = g_strdup_printf(vnc.%s.x509dname, vs-id);
+}
+vs-tls.acl = qemu_acl_init(aclname);
+if (!vs-tls.acl) {
 fprintf(stderr, Failed to create x509 dname ACL\n);
 exit(1);
 }
+g_free(aclname);
 }
 #endif
 #ifdef CONFIG_VNC_SASL
 if (acl  sasl) {
-if (!(vs-sasl.acl = qemu_acl_init(vnc.username))) {
+char *aclname;
+
+if (strcmp(vs-id, default) == 0) {
+aclname = g_strdup(vnc.username);
+} else {
+aclname = g_strdup_printf(vnc.%s.username, vs-id);
+}
+vs-sasl.acl = qemu_acl_init(aclname);
+if (!vs-sasl.acl) {
 fprintf(stderr, Failed to create username ACL\n);
 exit(1);
 }
+g_free(aclname);
 }
 #endif
 
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v2 2/6] block: vmdk - move string allocations from stack to the heap

2015-01-22 Thread Daniel P. Berrange
On Thu, Jan 22, 2015 at 11:17:35AM +, Stefan Hajnoczi wrote:
 On Tue, Jan 20, 2015 at 12:31:29PM -0500, Jeff Cody wrote:
  @@ -792,12 +792,11 @@ static int vmdk_parse_extents(const char *desc, 
  BlockDriverState *bs,
   const char *p = desc;
   int64_t sectors = 0;
   int64_t flat_offset;
  -char extent_path[PATH_MAX];
  +char *extent_path = g_malloc0(PATH_MAX);
 
 Simpler alternative that has no risk of memory leaks:
 
   extent_path = g_malloc0(PATH_MAX);
   path_combine(extent_path, sizeof(extent_path),
   desc_file_path, fname);
   extent_file = NULL;
   ret = bdrv_open(extent_file, extent_path, NULL, NULL,
   bs-open_flags | BDRV_O_PROTOCOL, NULL, errp);
   g_free(extent_path);

Much better would be to change path_combine so it doesn't need to have
the destination alloc done by the caller. Just have it allocate the
right sized string buffer directly  return that and avoid the madness
of PATH_MAX entirely.

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



Re: [Qemu-devel] [RFC PATCH v3] tests: rtl8139: test timers and interrupt

2015-01-22 Thread Frediano Ziglio
2015-01-20 13:36 GMT+00:00 Paolo Bonzini pbonz...@redhat.com:


 On 08/01/2015 19:38, Frediano Ziglio wrote:
 Test behaviour of timers and interrupts related to timeouts.

 Signed-off-by: Frediano Ziglio fredd...@gmail.com
 ---
  tests/Makefile   |   2 +-
  tests/rtl8139-test.c | 181 
 +++
  2 files changed, 182 insertions(+), 1 deletion(-)

 This patch was derived from a test I did while implementing timer in
 rtl8139 code. Now that there is support for integrated testing I converted
 it. The test was tested on a real NIC.

 As if it's the first test I wrote I don't know if syntax and details are
 fine. For instance should I remove nop test? Should I split my test?

 Respectively, no and if you want.

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

 As the last person who touched the rtl8139 timer code, I'm glad I didn't
 break anything. :)

 Paolo


Hi,
   sorry I didn't get everything. Was my patch/test fine or should I
change something? I saw you posted a patch for timer. Was your patch
tested with my code and you find some problems or was my patch that
had some problems?

Regards,
   Frediano


 Changed from v2:
 - style (variable declaration, Perl script not able to spot it)

 Changed from v1:
 - style

 diff --git a/tests/Makefile b/tests/Makefile
 index e4ddb6a..8858407 100644
 --- a/tests/Makefile
 +++ b/tests/Makefile
 @@ -320,7 +320,7 @@ tests/tmp105-test$(EXESUF): tests/tmp105-test.o 
 $(libqos-omap-obj-y)
  tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
  tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
  tests/e1000-test$(EXESUF): tests/e1000-test.o
 -tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o
 +tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o $(libqos-pc-obj-y)
  tests/pcnet-test$(EXESUF): tests/pcnet-test.o
  tests/eepro100-test$(EXESUF): tests/eepro100-test.o
  tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
 diff --git a/tests/rtl8139-test.c b/tests/rtl8139-test.c
 index f6a1be3..4e0bf02 100644
 --- a/tests/rtl8139-test.c
 +++ b/tests/rtl8139-test.c
 @@ -10,19 +10,200 @@
  #include glib.h
  #include string.h
  #include libqtest.h
 +#include libqos/pci-pc.h
  #include qemu/osdep.h
 +#include qemu-common.h

  /* Tests only initialization so far. TODO: Replace with functional tests */
  static void nop(void)
  {
  }

 +#define CLK 3300
 +#define NS_PER_SEC 10ULL
 +
 +static QPCIBus *pcibus;
 +static QPCIDevice *dev;
 +static void *dev_base;
 +
 +static void save_fn(QPCIDevice *dev, int devfn, void *data)
 +{
 +QPCIDevice **pdev = (QPCIDevice **) data;
 +
 +*pdev = dev;
 +}
 +
 +static QPCIDevice *get_device(void)
 +{
 +QPCIDevice *dev;
 +
 +pcibus = qpci_init_pc();
 +qpci_device_foreach(pcibus, 0x10ec, 0x8139, save_fn, dev);
 +g_assert(dev != NULL);
 +
 +return dev;
 +}
 +
 +#define PORT(name, len, val) \
 +static unsigned __attribute__((unused)) in_##name(void) \
 +{ \
 +unsigned res = qpci_io_read##len(dev, dev_base+(val)); \
 +g_test_message(*%s - %x\n, #name, res); \
 +return res; \
 +} \
 +static void out_##name(unsigned v) \
 +{ \
 +g_test_message(%x - *%s\n, v, #name); \
 +qpci_io_write##len(dev, dev_base+(val), v); \
 +}
 +
 +PORT(Timer, l, 0x48)
 +PORT(IntrMask, w, 0x3c)
 +PORT(IntrStatus, w, 0x3E)
 +PORT(TimerInt, l, 0x54)
 +
 +#define fatal(...) do { g_test_message(__VA_ARGS__); g_assert(0); } while 
 (0)
 +
 +static void test_timer(void)
 +{
 +const unsigned from = 0.95 * CLK;
 +const unsigned to = 1.6 * CLK;
 +unsigned prev, curr, next;
 +unsigned cnt, diff;
 +
 +out_IntrMask(0);
 +
 +in_IntrStatus();
 +in_Timer();
 +in_Timer();
 +
 +/* Test 1. test counter continue and continue */
 +out_TimerInt(0); /* disable timer */
 +out_IntrStatus(0x4000);
 +out_Timer(12345); /* reset timer to 0 */
 +curr = in_Timer();
 +if (curr  0.1 * CLK) {
 +fatal(time too big %u\n, curr);
 +}
 +for (cnt = 0; ; ) {
 +clock_step(1 * NS_PER_SEC);
 +prev = curr;
 +curr = in_Timer();
 +
 +/* test skip is in a specific range */
 +diff = (curr-prev)  0xu;
 +if (diff  from || diff  to) {
 +fatal(Invalid diff %u (%u-%u)\n, diff, from, to);
 +}
 +if (curr  prev  ++cnt == 3) {
 +break;
 +}
 +}
 +
 +/* Test 2. Check we didn't get an interrupt with TimerInt == 0 */
 +if (in_IntrStatus()  0x4000) {
 +fatal(got an interrupt\n);
 +}
 +
 +/* Test 3. Setting TimerInt to 1 and Timer to 0 get interrupt */
 +out_TimerInt(1);
 +out_Timer(0);
 +clock_step(40);
 +if ((in_IntrStatus()  0x4000) == 0) {
 +fatal(we should have an interrupt here!\n);
 +}
 +
 +/* Test 3. Check acknowledge */
 +out_IntrStatus(0x4000);
 +if (in_IntrStatus()  0x4000) {
 +fatal(got an interrupt\n);
 +}
 +
 +/* Test. Status set after 

Re: [Qemu-devel] [PATCH 2/3] kvm_stat: Update exit reasons to the latest defintion

2015-01-22 Thread Paolo Bonzini


On 21/01/2015 22:15, Wei Huang wrote:
 +56: 'ACPI_WRITE',

APIC_WRITE. :)

Will fix when committing.

Paolo

 +58: 'INVPCID',
  }
  



[Qemu-devel] [PATCH v3 5/6] block: mirror - change string allocation to 2-bytes

2015-01-22 Thread Jeff Cody
The backing_filename string in mirror_run() is only used to check
for a NULL string, so we don't need to allocate 1024 bytes (or, later,
PATH_MAX bytes), when we only need to copy the first 2 characters.

We technically only need 1 byte, as we are just checking for NULL, but
since backing_filename[] is populated by bdrv_get_backing_filename(), a
string size of 1 will always only return '\0';

Reviewed-by: Stefan Hajnoczi stefa...@redhat.com
Reviewed-by: John Snow js...@redhat.com
Signed-off-by: Jeff Cody jc...@redhat.com
---
 block/mirror.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/block/mirror.c b/block/mirror.c
index 9019d1b..4056164 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -378,7 +378,8 @@ static void coroutine_fn mirror_run(void *opaque)
 int64_t sector_num, end, sectors_per_chunk, length;
 uint64_t last_pause_ns;
 BlockDriverInfo bdi;
-char backing_filename[1024];
+char backing_filename[2]; /* we only need 2 characters because we are only
+ checking for a NULL string */
 int ret = 0;
 int n;
 
-- 
1.9.3




[Qemu-devel] [PATCH v5 05/10] pci: add network device class 'other' for network switches

2015-01-22 Thread sfeldma
From: Scott Feldman sfel...@gmail.com

Rocker is an ethernet switch device, so add 'other' network device class as
defined by PCI to cover these types of devices.

Signed-off-by: Scott Feldman sfel...@gmail.com
Signed-off-by: Jiri Pirko j...@resnulli.us
---
 include/hw/pci/pci_ids.h |1 +
 1 file changed, 1 insertion(+)

diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index d7be386..c6de710 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -23,6 +23,7 @@
 #define PCI_CLASS_STORAGE_OTHER  0x0180
 
 #define PCI_CLASS_NETWORK_ETHERNET   0x0200
+#define PCI_CLASS_NETWORK_OTHER  0x0280
 
 #define PCI_CLASS_DISPLAY_VGA0x0300
 #define PCI_CLASS_DISPLAY_OTHER  0x0380
-- 
1.7.10.4




[Qemu-devel] [PATCH 1/1] edu: fix license information

2015-01-22 Thread Jiri Slaby
Signed-off-by: Jiri Slaby jsl...@suse.cz
---
 docs/specs/edu.txt | 4 
 hw/misc/edu.c  | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/docs/specs/edu.txt b/docs/specs/edu.txt
index 360af27ec8b1..1a23df9d21f6 100644
--- a/docs/specs/edu.txt
+++ b/docs/specs/edu.txt
@@ -2,6 +2,10 @@
 EDU device
 ==
 
+Copyleft (c) 2014-2015 Jiri Slaby
+
+This document is licensed under the GPLv2 (or later).
+
 This is an educational device for writing (kernel) drivers. Its original
 intention was to support the Linux kernel lectures taught at the Masaryk
 University. Students are given this virtual device and are expected to write a
diff --git a/hw/misc/edu.c b/hw/misc/edu.c
index c74f9b64540d..9a8088c6898d 100644
--- a/hw/misc/edu.c
+++ b/hw/misc/edu.c
@@ -1,7 +1,7 @@
 /*
  * QEMU educational PCI device
  *
- * Copyright (c) 2012-2014 Jiri Slaby
+ * Copyright (c) 2012-2015 Jiri Slaby
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the Software),
-- 
2.2.1




[Qemu-devel] [PATCH v5 01/10] net: add MAC address string printer

2015-01-22 Thread sfeldma
From: Scott Feldman sfel...@gmail.com

We can use this in virtio-net code as well as new Rocker driver code, so
up-level this.

Signed-off-by: Scott Feldman sfel...@gmail.com
---
 include/net/net.h |1 +
 net/net.c |7 +++
 2 files changed, 8 insertions(+)

diff --git a/include/net/net.h b/include/net/net.h
index 008d610..90742f0 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -97,6 +97,7 @@ typedef struct NICState {
 bool peer_deleted;
 } NICState;
 
+char *qemu_mac_strdup_printf(const uint8_t *macaddr);
 NetClientState *qemu_find_netdev(const char *id);
 int qemu_find_net_clients_except(const char *id, NetClientState **ncs,
  NetClientOptionsKind type, int max);
diff --git a/net/net.c b/net/net.c
index 7acc162..2387616 100644
--- a/net/net.c
+++ b/net/net.c
@@ -151,6 +151,13 @@ int parse_host_port(struct sockaddr_in *saddr, const char 
*str)
 return 0;
 }
 
+char *qemu_mac_strdup_printf(const uint8_t *macaddr)
+{
+return g_strdup_printf(%.2x:%.2x:%.2x:%.2x:%.2x:%.2x,
+   macaddr[0], macaddr[1], macaddr[2],
+   macaddr[3], macaddr[4], macaddr[5]);
+}
+
 void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6])
 {
 snprintf(nc-info_str, sizeof(nc-info_str),
-- 
1.7.10.4




[Qemu-devel] [PATCH v5 08/10] rocker: add tests

2015-01-22 Thread sfeldma
From: Scott Feldman sfel...@gmail.com

Add some basic test for rocker to test L2/L3/L4 functionality.  Requires an
external test environment, simp, located here:

https://github.com/scottfeldman/simp

To run tests, simp environment must be installed and a suitable VM image built
and installed with a Linux 3.18 (or greater) kernel with rocker driver support
enabled.

Signed-off-by: Scott Feldman sfel...@gmail.com
---
 hw/net/rocker/test/README  |5 +++
 hw/net/rocker/test/all |   19 +++
 hw/net/rocker/test/bridge  |   43 
 hw/net/rocker/test/bridge-stp  |   52 +
 hw/net/rocker/test/bridge-vlan |   52 +
 hw/net/rocker/test/bridge-vlan-stp |   64 
 hw/net/rocker/test/port|   22 +
 hw/net/rocker/test/tut.dot |8 +
 8 files changed, 265 insertions(+)
 create mode 100644 hw/net/rocker/test/README
 create mode 100755 hw/net/rocker/test/all
 create mode 100755 hw/net/rocker/test/bridge
 create mode 100755 hw/net/rocker/test/bridge-stp
 create mode 100755 hw/net/rocker/test/bridge-vlan
 create mode 100755 hw/net/rocker/test/bridge-vlan-stp
 create mode 100755 hw/net/rocker/test/port
 create mode 100644 hw/net/rocker/test/tut.dot

diff --git a/hw/net/rocker/test/README b/hw/net/rocker/test/README
new file mode 100644
index 000..531e673
--- /dev/null
+++ b/hw/net/rocker/test/README
@@ -0,0 +1,5 @@
+Tests require simp (simple network simulator) found here:
+
+https://github.com/scottfeldman/simp
+
+Run 'all' to run all tests.
diff --git a/hw/net/rocker/test/all b/hw/net/rocker/test/all
new file mode 100755
index 000..d5ae963
--- /dev/null
+++ b/hw/net/rocker/test/all
@@ -0,0 +1,19 @@
+echo -n Running port test...  
+./port
+if [ $? -eq 0 ]; then echo pass; else echo FAILED; exit 1; fi
+
+echo -n Running bridge test...
+./bridge
+if [ $? -eq 0 ]; then echo pass; else echo FAILED; exit 1; fi
+
+echo -n Running bridge STP test...
+./bridge-stp
+if [ $? -eq 0 ]; then echo pass; else echo FAILED; exit 1; fi
+
+echo -n Running bridge VLAN test...   
+./bridge-vlan
+if [ $? -eq 0 ]; then echo pass; else echo FAILED; exit 1; fi
+
+echo -n Running bridge VLAN STP test...   
+./bridge-vlan-stp
+if [ $? -eq 0 ]; then echo pass; else echo FAILED; exit 1; fi
diff --git a/hw/net/rocker/test/bridge b/hw/net/rocker/test/bridge
new file mode 100755
index 000..f1f555a
--- /dev/null
+++ b/hw/net/rocker/test/bridge
@@ -0,0 +1,43 @@
+simp destroy .*
+simp create -o sw1:rocker:sw1 tut tut.dot
+simp start tut
+sleep 10
+while ! simp ssh tut sw1 --cmd ping -c 1 localhost /dev/null; do sleep 1; 
done
+while ! simp ssh tut h1 --cmd ping -c 1 localhost /dev/null; do sleep 1; 
done
+while ! simp ssh tut h2 --cmd ping -c 1 localhost /dev/null; do sleep 1; 
done
+
+# configure a 2-port bridge
+
+simp ssh tut sw1 --cmd sudo /sbin/ip link add name br0 type bridge
+simp ssh tut sw1 --cmd sudo /sbin/ip link set dev swp1 master br0
+simp ssh tut sw1 --cmd sudo /sbin/ip link set dev swp2 master br0
+
+# turn off vlan default_pvid on br0
+
+simp ssh tut sw1 --cmd echo 0 | sudo dd 
of=/sys/class/net/br0/bridge/default_pvid 2 /dev/null
+
+# turn off learning and flooding in SW
+
+simp ssh tut sw1 --cmd sudo /sbin/bridge link set dev swp1 learning off
+simp ssh tut sw1 --cmd sudo /sbin/bridge link set dev swp2 learning off
+
+simp ssh tut sw1 --cmd sudo /sbin/bridge link set dev swp1 flood off
+simp ssh tut sw1 --cmd sudo /sbin/bridge link set dev swp2 flood off
+
+# bring up bridge and ports
+
+simp ssh tut sw1 --cmd sudo ifconfig br0 up
+simp ssh tut sw1 --cmd sudo ifconfig swp1 up
+simp ssh tut sw1 --cmd sudo ifconfig swp2 up
+simp ssh tut sw1 --cmd sudo ifconfig br0 11.0.0.3/24
+
+# config IP on hosts
+
+simp ssh tut h1 --cmd sudo ifconfig swp1 11.0.0.1/24
+simp ssh tut h2 --cmd sudo ifconfig swp1 11.0.0.2/24
+
+# test...
+
+simp ssh tut h1 --cmd ping -c10 11.0.0.2 /dev/null
+if [ $? -ne 0 ]; then exit 1; fi
+simp ssh tut h1 --cmd ping -c10 11.0.0.3 /dev/null
diff --git a/hw/net/rocker/test/bridge-stp b/hw/net/rocker/test/bridge-stp
new file mode 100755
index 000..60f4483
--- /dev/null
+++ b/hw/net/rocker/test/bridge-stp
@@ -0,0 +1,52 @@
+simp destroy .*
+simp create -o sw1:rocker:sw1 tut tut.dot
+simp start tut
+sleep 10
+while ! simp ssh tut sw1 --cmd ping -c 1 localhost /dev/null; do sleep 1; 
done
+while ! simp ssh tut h1 --cmd ping -c 1 localhost /dev/null; do sleep 1; 
done
+while ! simp ssh tut h2 --cmd ping -c 1 localhost /dev/null; do sleep 1; 
done
+
+# configure a 2-port bridge
+
+simp ssh tut sw1 --cmd sudo /sbin/ip link add name br0 type bridge
+simp ssh tut sw1 --cmd sudo brctl stp br0 on
+simp ssh tut sw1 --cmd sudo /sbin/ip link set dev swp1 master br0
+simp ssh tut sw1 --cmd sudo /sbin/ip link set dev swp2 master br0
+
+# turn off vlan default_pvid on br0
+
+simp ssh tut sw1 --cmd echo 

[Qemu-devel] [PATCH v5 04/10] pci: add rocker device ID

2015-01-22 Thread sfeldma
From: Scott Feldman sfel...@gmail.com

Signed-off-by: Scott Feldman sfel...@gmail.com
Signed-off-by: Jiri Pirko j...@resnulli.us
---
 docs/specs/pci-ids.txt |1 +
 include/hw/pci/pci.h   |1 +
 2 files changed, 2 insertions(+)

diff --git a/docs/specs/pci-ids.txt b/docs/specs/pci-ids.txt
index c6732fe..e4a4490 100644
--- a/docs/specs/pci-ids.txt
+++ b/docs/specs/pci-ids.txt
@@ -45,6 +45,7 @@ PCI devices (other than virtio):
 1b36:0003  PCI Dual-port 16550A adapter (docs/specs/pci-serial.txt)
 1b36:0004  PCI Quad-port 16550A adapter (docs/specs/pci-serial.txt)
 1b36:0005  PCI test device (docs/specs/pci-testdev.txt)
+1b36:0006  PCI Rocker Ethernet switch device
 1b36:0007  PCI SD Card Host Controller Interface (SDHCI)
 
 All these devices are documented in docs/specs.
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 97a83d3..2c58bf2 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -88,6 +88,7 @@
 #define PCI_DEVICE_ID_REDHAT_SERIAL2 0x0003
 #define PCI_DEVICE_ID_REDHAT_SERIAL4 0x0004
 #define PCI_DEVICE_ID_REDHAT_TEST0x0005
+#define PCI_DEVICE_ID_REDHAT_ROCKER  0x0006
 #define PCI_DEVICE_ID_REDHAT_SDHCI   0x0007
 #define PCI_DEVICE_ID_REDHAT_QXL 0x0100
 
-- 
1.7.10.4




[Qemu-devel] [PATCH v5 10/10] rocker: timestamp on the debug logs helps correlate with events in the VM

2015-01-22 Thread sfeldma
From: David Ahern dsah...@gmail.com

Signed-off-by: David Ahern dsah...@gmail.com
Signed-off-by: Scott Feldman sfel...@gmail.com
---
 hw/net/rocker/rocker.h |   11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/net/rocker/rocker.h b/hw/net/rocker/rocker.h
index ef77487..5ae8aff 100644
--- a/hw/net/rocker/rocker.h
+++ b/hw/net/rocker/rocker.h
@@ -25,7 +25,16 @@
 
 #if defined(DEBUG_ROCKER)
 #  define DPRINTF(fmt, ...) \
-do { fprintf(stderr, ROCKER:  fmt, ## __VA_ARGS__); } while (0)
+do {   \
+struct timeval tv; \
+char timestr[64];  \
+time_t now;\
+gettimeofday(tv, NULL);   \
+now = tv.tv_sec;   \
+strftime(timestr, sizeof(timestr), %T, localtime(now)); \
+fprintf(stderr, %s.%06ld , timestr, tv.tv_usec); \
+fprintf(stderr, ROCKER:  fmt, ## __VA_ARGS__);   \
+} while (0)
 #else
 static inline GCC_FMT_ATTR(1, 2) int DPRINTF(const char *fmt, ...)
 {
-- 
1.7.10.4




Re: [Qemu-devel] [snabb-devel] Re: [PATCH] vhost-user: multiqueue support

2015-01-22 Thread Nikolay Nikolaev
On Wed, Jan 21, 2015 at 4:25 PM, Michael S. Tsirkin m...@redhat.com wrote:

 On Sat, Dec 06, 2014 at 06:52:56PM +0200, Nikolay Nikolaev wrote:
  Vhost-user will implement the multiqueueu support in a similar way to what
  vhost already has - a separate thread for each queue.
 
  To enable multiquue funcionality - a new command line parameter
  queues is introduced for the vhost-user netdev.
 
  Signed-off-by: Nikolay Nikolaev n.nikol...@virtualopensystems.com

 Nikolay - plan to repost addressing comments?


I can send v2 with the small polishing fixes.

However we currently don't have he resources to fix sending
VHOST_USER_SET_OWNER, VHOST_USER_SET_FEATURES, VHOST_SET_MEM_TABLE
messages per virtq. It work like this as it follows the tap backend
behavior, which AFAIK assigns a different tap device per virtq and
initializes them separately. At least I don't see an obvious and quick
patch around this.




  ---
   docs/specs/vhost-user.txt |7 +++
   hw/virtio/vhost-user.c|6 +-
   net/vhost-user.c  |   35 +++
   qapi-schema.json  |5 -
   qemu-options.hx   |5 +++--
   5 files changed, 42 insertions(+), 16 deletions(-)
 
  diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt
  index 650bb18..d3857f5 100644
  --- a/docs/specs/vhost-user.txt
  +++ b/docs/specs/vhost-user.txt
  @@ -127,6 +127,13 @@ in the ancillary data:
   If Master is unable to send the full message or receives a wrong reply it 
  will
   close the connection. An optional reconnection mechanism can be 
  implemented.
 
  +Multi queue suport
  +-
  +The protocol supports multiple queues by setting all index fields in the 
  sent
  +messages to a value calculated by the following formula:
  +queue idx + vring idx
  +The queue idx is increased by 2.
  +
   Message types
   -
 

 How is the support negotiated though?
Not negotiated. Will a version bump be enough ?
 What if I set queues=N with a legacy backend that
 does not support multiqueue?
It is supposed that the device that does not support MQ won't
advertise VIRTIO_NET_F_MQ, thus not utilising more than 1 queue. Still
the initialisation of the multiple virtqs will happen.

regards,
Nikolay Nikolaev


  diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
  index aefe0bb..83ebcaa 100644
  --- a/hw/virtio/vhost-user.c
  +++ b/hw/virtio/vhost-user.c
  @@ -253,17 +253,20 @@ static int vhost_user_call(struct vhost_dev *dev, 
  unsigned long int request,
   case VHOST_SET_VRING_NUM:
   case VHOST_SET_VRING_BASE:
   memcpy(msg.state, arg, sizeof(struct vhost_vring_state));
  +msg.state.index += dev-vq_index;
   msg.size = sizeof(m.state);
   break;
 
   case VHOST_GET_VRING_BASE:
   memcpy(msg.state, arg, sizeof(struct vhost_vring_state));
  +msg.state.index += dev-vq_index;
   msg.size = sizeof(m.state);
   need_reply = 1;
   break;
 
   case VHOST_SET_VRING_ADDR:
   memcpy(msg.addr, arg, sizeof(struct vhost_vring_addr));
  +msg.addr.index += dev-vq_index;
   msg.size = sizeof(m.addr);
   break;
 
  @@ -271,7 +274,7 @@ static int vhost_user_call(struct vhost_dev *dev, 
  unsigned long int request,
   case VHOST_SET_VRING_CALL:
   case VHOST_SET_VRING_ERR:
   file = arg;
  -msg.u64 = file-index  VHOST_USER_VRING_IDX_MASK;
  +msg.u64 = (file-index + dev-vq_index)  
  VHOST_USER_VRING_IDX_MASK;
   msg.size = sizeof(m.u64);
   if (ioeventfd_enabled()  file-fd  0) {
   fds[fd_num++] = file-fd;
  @@ -313,6 +316,7 @@ static int vhost_user_call(struct vhost_dev *dev, 
  unsigned long int request,
   error_report(Received bad msg size.\n);
   return -1;
   }
  +msg.state.index -= dev-vq_index;
   memcpy(arg, msg.state, sizeof(struct vhost_vring_state));
   break;
   default:
  diff --git a/net/vhost-user.c b/net/vhost-user.c
  index 24e050c..1ea2f98 100644
  --- a/net/vhost-user.c
  +++ b/net/vhost-user.c
  @@ -134,25 +134,27 @@ static void net_vhost_user_event(void *opaque, int 
  event)
 
   static int net_vhost_user_init(NetClientState *peer, const char *device,
  const char *name, CharDriverState *chr,
  -   bool vhostforce)
  +   bool vhostforce, uint32_t queues)
   {
   NetClientState *nc;
   VhostUserState *s;
  +int i;
 
  -nc = qemu_new_net_client(net_vhost_user_info, peer, device, name);
  +for (i = 0; i  queues; i++) {
  +nc = qemu_new_net_client(net_vhost_user_info, peer, device, name);
 
  -snprintf(nc-info_str, sizeof(nc-info_str), vhost-user to %s,
  - chr-label);
  +snprintf(nc-info_str, sizeof(nc-info_str), vhost-user%d to %s,
  + i, 

Re: [Qemu-devel] [PATCH] hw/input/hid.c Fix capslock hid code

2015-01-22 Thread Dinar Valeev



On 01/22/2015 08:20 AM, Gerd Hoffmann wrote:

On Mi, 2015-01-21 at 23:48 +0100, dval...@suse.de wrote:

From: Dinar Valeev dval...@suse.com

When ever USB keyboard is used, e.g. '-usbdevice keyboard' pressing
caps lock key send 0x32 hid code, which is treated as backslash.
Instead it should be 0x39 code. This affects sending uppercase keys,
as they typed whith caps lock active.

While on x86 this can be workarounded by using ps/2 protocol. On
Power it is crusial as we don't have anything else than USB.

This is fixes guest automation tasts over vnc.


That probably happens because your test automation vnc client sends
uppercase letters without also sending shift-down/up events.  The qemu
vnc server logic which is supposed to sync up capslock state between
guest and host thinks capslock is pressed on the host then and injects
some synthetic capslock key events.

Just say'ing FYI, that doesn't render the fix invalid, but you may have
wondered why you are not seeing this with a normal vnc client ;)
Yeah, I thought about sending shift+letter. It become better, but not 
really. Sending shift-b would print |B.


I've seen this behaviour with a home grown perl vnc client, ruby-vnc as 
well as with manual vncviewer client, vnc and SDL ui.


The reproducer is simple: qemu-system-x86_64 -enable-kvm -cdrom 
SLE-12-Server-MINI-ISO-x86_64-GM-DVD.iso -usbdevice keyboard -m 1024


Pressing caps lock produces \. showkey says backslash is pressed.

Dinar,


Added to input queue.

Thanks


thanks,
   Gerd






[Qemu-devel] [PATCH v5 03/10] rocker: add register programming guide

2015-01-22 Thread sfeldma
From: Scott Feldman sfel...@gmail.com

This is the register programming guide for the Rocker device.  It's intended
for driver writers and device writers.  It covers the device's PCI space,
the register set, DMA interface, and interrupts.

Signed-off-by: Scott Feldman sfel...@gmail.com
Signed-off-by: Jiri Pirko j...@resnulli.us
---
 docs/specs/rocker.txt | 1006 +
 1 file changed, 1006 insertions(+)
 create mode 100644 docs/specs/rocker.txt

diff --git a/docs/specs/rocker.txt b/docs/specs/rocker.txt
new file mode 100644
index 000..d07ccc0
--- /dev/null
+++ b/docs/specs/rocker.txt
@@ -0,0 +1,1006 @@
+Rocker Network Switch Register Programming Guide
+Copyright (c) Scott Feldman sfel...@gmail.com
+Copyright (c) Neil Horman nhor...@tuxdriver.com
+Version 0.11, 12/29/2014
+
+LICENSE
+===
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program 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 General Public License for more details.
+
+SECTION 1: Introduction
+===
+
+Overview
+
+
+This document describes the hardware/software interface for the Rocker switch
+device.  The intended audience is authors of OS drivers and device emulation
+software.
+
+Notations and Conventions
+-
+
+o In register descriptions, [n:m] indicates a range from bit n to bit m,
+inclusive.
+o Use of leading 0x indicates a hexadecimal number.
+o Use of leading 0b indicates a binary number.
+o The use of RSVD or Reserved indicates that a bit or field is reserved for
+future use.
+o Field width is in bytes, unless otherwise noted.
+o Register are (R) read-only, (R/W) read/write, (W) write-only, or (COR) clear
+on read
+o TLV values in network-byte-order are designated with (N).
+
+
+SECTION 2: PCI Configuration Registers
+==
+
+PCI Configuration Space
+---
+
+Each switch instance registers as a PCI device with PCI configuration space:
+
+   offset  width   description value
+   -
+   0x0 2   Vendor ID   0x1b36
+   0x2 2   Device ID   0x0006
+   0x4 4   Command/Status
+   0x8 1   Revision ID 0x01
+   0x9 3   Class code  0x2800
+   0xC 1   Cache line size
+   0xD 1   Latency timer
+   0xE 1   Header type
+   0xF 1   Built-in self test
+   0x104   Base address low
+   0x144   Base address high
+   0x18-28 Reserved
+   0x2C2   Subsystem vendor ID *
+   0x2E2   Subsystem ID*
+   0x30-38 Reserved
+   0x3C1   Interrupt line
+   0x3D1   Interrupt pin   0x00
+   0x3E1   Min grant   0x00
+   0x3D1   Max latency 0x00
+   0x401   TRDY timeout
+   0x411   Retry count
+   0x422   Reserved
+
+
+* Assigned by sub-system implementation
+
+SECTION 3: Memory-Mapped Register Space
+===
+
+There are two memory-mapped BARs.  BAR0 maps device register space and is
+0x2000 in size.  BAR1 maps MSI-X vector and PBA tables and is also 0x2000 in
+size, allowing for 256 MSI-X vectors.
+
+All registers are 4 or 8 bytes long.  It is assumed host software will access 4
+byte registers with one 4-byte access, and 8 byte registers with either two
+4-byte accesses or a single 8-byte access.  In the case of two 4-byte accesses,
+access must be lower and then upper 4-bytes, in that order.
+
+BAR0 device register space is organized as follows:
+
+   offset  description
+   --
+   0x-0x000f   Bogus registers to catch misbehaving
+   drivers.  Writes do nothing.  Reads
+   back as 0xDEADBABE.
+   0x0010-0x00ff   Test registers
+   0x0300-0x03ff   General purpose registers
+   0x1000-0x1fff   Descriptor control
+
+Holes in register space are reserved.  Writes to reserved registers do nothing.
+Reads to reserved registers read back as 0.
+
+No fancy stuff like write-combining is enabled on any of the registers.
+
+BAR1 MSI-X register space is organized as follows:
+
+   offset  description
+   --
+   0x-0x0fff   MSI-X vector table (256 vectors total)
+   0x1000-0x1fff   MSI-X PBA table
+
+
+SECTION 4: Interrupts, DMA, and Endianess

[Qemu-devel] [PATCH v5 07/10] qmp: add rocker device support

2015-01-22 Thread sfeldma
From: Scott Feldman sfel...@gmail.com

Add QMP/HMP support for rocker devices.  This is mostly for debugging purposes
to see inside the device's tables and port configurations.  Some examples:

(qemu) info rocker sw1
name: sw1
id: 0x013512005452
ports: 4

(qemu) info rocker-ports sw1
ena/speed/ auto
  port  linkduplex neg?
 sw1.1  up 10G  FD  No
 sw1.2  up 10G  FD  No
 sw1.3  !ena   10G  FD  No
 sw1.4  !ena   10G  FD  No

(qemu) info rocker-of-dpa-flows sw1
prio tbl hits key(mask) -- actions
260   lport 1 vlan 1 LLDP src 00:02:00:00:02:00 dst 01:80:c2:00:00:0e
260   lport 1 vlan 1 ARP src 00:02:00:00:02:00 dst 00:02:00:00:03:00
260   lport 2 vlan 2 IPv6 src 00:02:00:00:03:00 dst 33:33:ff:00:00:02 
proto 58
350   vlan 2 dst 33:33:ff:00:00:02 -- write group 0x3201 goto tbl 
60
260   lport 2 vlan 2 IPv6 src 00:02:00:00:03:00 dst 33:33:ff:00:03:00 
proto 58
350  1vlan 2 dst 33:33:ff:00:03:00 -- write group 0x3201 goto tbl 
60
260   lport 2 vlan 2 ARP src 00:02:00:00:03:00 dst 00:02:00:00:02:00
350  2vlan 2 dst 00:02:00:00:02:00 -- write group 0x0201 goto tbl 
60
260  1lport 2 vlan 2 IP src 00:02:00:00:03:00 dst 00:02:00:00:02:00 
proto 1
350  2vlan 1 dst 00:02:00:00:03:00 -- write group 0x0102 goto tbl 
60
260  1lport 1 vlan 1 IP src 00:02:00:00:02:00 dst 00:02:00:00:03:00 
proto 1
260   lport 1 vlan 1 IPv6 src 00:02:00:00:02:00 dst 33:33:ff:00:00:01 
proto 58
350   vlan 1 dst 33:33:ff:00:00:01 -- write group 0x3100 goto tbl 
60
260   lport 1 vlan 1 IPv6 src 00:02:00:00:02:00 dst 33:33:ff:00:02:00 
proto 58
350  1vlan 1 dst 33:33:ff:00:02:00 -- write group 0x3100 goto tbl 
60
160  173  lport 2 vlan 2 LLDP src any dst 01:80:c2:00:00:0e -- write 
group 0x0200
160  6lport 2 vlan 2 IPv6 src any dst any -- write group 0x0200
160  174  lport 1 vlan 1 LLDP src any dst 01:80:c2:00:00:0e -- write 
group 0x0100
160  174  lport 2 vlan 2 IP src any dst any -- write group 0x0200
160  6lport 1 vlan 1 IPv6 src any dst any -- write group 0x0100
160  181  lport 2 vlan 2 ARP src any dst any -- write group 0x0200
110  715  lport 2 -- apply new vlan 2 goto tbl 20
160  177  lport 1 vlan 1 ARP src any dst any -- write group 0x0100
160  174  lport 1 vlan 1 IP src any dst any -- write group 0x0100
110  717  lport 1 -- apply new vlan 1 goto tbl 20
10   1432 lport 0(0x) -- goto tbl 10

(qemu) info rocker-of-dpa-groups sw1
id (decode) -- buckets
0x3201 (type L2 multicast vlan 2 index 1) -- groups [0x0201,0x0200]
0x0201 (type L2 interface vlan 2 lport 1) -- pop vlan out lport 1
0x0102 (type L2 interface vlan 1 lport 2) -- pop vlan out lport 2
0x0200 (type L2 interface vlan 2 lport 0) -- pop vlan out lport 0
0x0100 (type L2 interface vlan 1 lport 0) -- pop vlan out lport 0
0x3100 (type L2 multicast vlan 1 index 0) -- groups [0x0102,0x0100]

Signed-off-by: Scott Feldman sfel...@gmail.com
Signed-off-by: Jiri Pirko j...@resnulli.us
---
 hmp-commands.hx   |   24 
 hmp.c |  303 
 hmp.h |4 +
 hw/net/rocker/rocker.c|   45 ++
 hw/net/rocker/rocker_fp.c |   10 ++
 hw/net/rocker/rocker_fp.h |1 +
 hw/net/rocker/rocker_of_dpa.c |  308 +
 monitor.c |   28 
 qapi-schema.json  |3 +
 qapi/rocker.json  |  259 ++
 qmp-commands.hx   |   97 +
 11 files changed, 1082 insertions(+)
 create mode 100644 qapi/rocker.json

diff --git a/hmp-commands.hx b/hmp-commands.hx
index e37bc8b..6873a3a 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1787,5 +1787,29 @@ show available trace events and their state
 ETEXI
 
 STEXI
+@item rocker @var{name}
+@findex rocker
+Show Rocker(s)
+ETEXI
+
+STEXI
+@item rocker_ports @var{name}
+@findex rocker_ports
+Show Rocker ports
+ETEXI
+
+STEXI
+@item rocker_of_dpa_flows @var{name} [@var{tbl_id}]
+@findex rocker_of_dpa_flows
+Show Rocker OF-DPA flow tables
+ETEXI
+
+STEXI
+@item rocker_of_dpa_groups @var{name} [@var{type}]
+@findex rocker_of_dpa_groups
+Show Rocker OF-DPA groups
+ETEXI
+
+STEXI
 @end table
 ETEXI
diff --git a/hmp.c b/hmp.c
index 481be80..949d43c 100644
--- a/hmp.c
+++ b/hmp.c
@@ -15,6 +15,7 @@
 
 #include hmp.h
 #include net/net.h
+#include net/eth.h
 #include sysemu/char.h
 #include qemu/option.h
 #include qemu/timer.h
@@ -1813,3 +1814,305 @@ void hmp_info_memory_devices(Monitor *mon, const QDict 
*qdict)
 
 qapi_free_MemoryDeviceInfoList(info_list);
 }
+
+void hmp_rocker(Monitor *mon, const QDict *qdict)
+{
+const char *name = qdict_get_str(qdict, name);
+RockerSwitch *rocker;
+Error *errp = NULL;
+

[Qemu-devel] [PATCH v5 00/10] rocker: add new rocker ethernet switch device

2015-01-22 Thread sfeldma
From: Scott Feldman sfel...@gmail.com

v5:

 - Per Jason Wang review:
 - Fix some missing/wrong references in the rocker.txt spec
 - mark rocker as unmigratable.

v4:

 - Per Paolo Bonzini review:
 - move reg_guide.txt to docs/specs/rocker.txt
 - fix some spelling/grammer mistakes in the rocker.txt doc
 - fix some misleading/wrong statements in rocker.txt
 - add double 4-byte access for 64-bit registers
 - define new ROCKER_Exxx to replace usage of errno.h return codes
 - Add patch from David Ahern to timestamp debug output

v3:

 - Per Stefan Hajnoczi review:
 - move HMP rocker cmds to info rocker
 - prefix QMP rocker cmds with query-
 - tag QMP cmds as Since 2.3
 - convert structs to typedef with CamelCase naming
 - Remove SDHCI device ID move patch...Paolo Bonzini is addressing
   SDHCI move is separate patch.

v2:

 - Address reg_guide.txt review comments from Eric Blake
 - Address QMP review comments from Eric Blake

v1:

[This is a collaboration between myself and Jiri Pirko].

This patch set adds a new ethernet switch device, called rocker.  Rocker is
intended to emulate HW features of switch ASICs found in today's
data-center-class switch/routers.  The original motivation in creating a new
device is to accelerate device driver development for ethernet switches in the
Linux kernel.  A device driver for rocker already exists in the Linux 3.18
kernel and loads against this device.  Basic L2 switching (bridging)
functionality is offloaded to the device.  Work continues to enable offloading
of L3 routing functions and ACLs, as well as support for a flow-based modes,
such as OpenVSwitch with OpenFlow.  Future support for terminating L2-over-L3
tunnels is also planned.

The core network processing functions are based on the spec of a real device:
Broadcom's OF-DPA.  Specifically, rocker borrows OF-DPA's network processing
pipeline comprised of flow match and action tables.  Only the OF-DPA spec was
used in constructing rocker.  The rocker developers do not have access to the
real OF-DPA's software source code, so this is a clean-room, ground-up
development.

Each rocker device is a PCI device with a memory-mapped register space and
MSI-X interrupts for command and event processing, as well as CPU-bound I/O.
Each device can support up to 62 front-panel ports, which present themselves
as -netdev attachment points.  The device is programmed using OF-DPA flow and
group tables to setup the flow pipeline.  The programming defines the
forwarding path for packets ingressing on 'front-panel' ports.  The forwarding
path can look at L2/L3/L4 packet header to forward the packet to its
destination.  For the performance path, packets would ingress and egress only
on the device, and not be passed up to the device driver (or host OS).  The
slow path for control packets will forward packets to the CPU via the device
driver for host OS processing.

A QMP/HMP interface is added to give inside into the device's internal port
configuration and flow/group tables.

A test directory is included with some basic sanity tests to verify the device
and driver.

David Ahern (1):
  rocker: timestamp on the debug logs helps correlate with events in
the VM

Scott Feldman (9):
  net: add MAC address string printer
  virtio-net: use qemu_mac_strdup_printf
  rocker: add register programming guide
  pci: add rocker device ID
  pci: add network device class 'other' for network switches
  rocker: add new rocker switch device
  qmp: add rocker device support
  rocker: add tests
  MAINTAINERS: add rocker

 MAINTAINERS|6 +
 default-configs/pci.mak|1 +
 docs/specs/pci-ids.txt |1 +
 docs/specs/rocker.txt  | 1006 ++
 hmp-commands.hx|   24 +
 hmp.c  |  303 +
 hmp.h  |4 +
 hw/net/Makefile.objs   |3 +
 hw/net/rocker/rocker.c | 1517 +
 hw/net/rocker/rocker.h |   85 ++
 hw/net/rocker/rocker_desc.c|  379 ++
 hw/net/rocker/rocker_desc.h|   57 +
 hw/net/rocker/rocker_fp.c  |  242 
 hw/net/rocker/rocker_fp.h  |   54 +
 hw/net/rocker/rocker_hw.h  |  491 +++
 hw/net/rocker/rocker_of_dpa.c  | 2622 
 hw/net/rocker/rocker_of_dpa.h  |   25 +
 hw/net/rocker/rocker_tlv.h |  244 
 hw/net/rocker/rocker_world.c   |  108 ++
 hw/net/rocker/rocker_world.h   |   63 +
 hw/net/rocker/test/README  |5 +
 hw/net/rocker/test/all |   19 +
 hw/net/rocker/test/bridge  |   43 +
 hw/net/rocker/test/bridge-stp  |   52 +
 hw/net/rocker/test/bridge-vlan |   52 +
 hw/net/rocker/test/bridge-vlan-stp |   64 +
 hw/net/rocker/test/port|   22 +
 hw/net/rocker/test/tut.dot |8 +
 hw/net/virtio-net.c|   12 +-
 include/hw/pci/pci.h  

[Qemu-devel] [PATCH v5 02/10] virtio-net: use qemu_mac_strdup_printf

2015-01-22 Thread sfeldma
From: Scott Feldman sfel...@gmail.com

Signed-off-by: Scott Feldman sfel...@gmail.com
---
 hw/net/virtio-net.c |   12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 45da34a..698156f 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -226,12 +226,6 @@ static void rxfilter_notify(NetClientState *nc)
 }
 }
 
-static char *mac_strdup_printf(const uint8_t *mac)
-{
-return g_strdup_printf(%.2x:%.2x:%.2x:%.2x:%.2x:%.2x, mac[0],
-mac[1], mac[2], mac[3], mac[4], mac[5]);
-}
-
 static intList *get_vlan_table(VirtIONet *n)
 {
 intList *list, *entry;
@@ -284,12 +278,12 @@ static RxFilterInfo 
*virtio_net_query_rxfilter(NetClientState *nc)
 info-multicast_overflow = n-mac_table.multi_overflow;
 info-unicast_overflow = n-mac_table.uni_overflow;
 
-info-main_mac = mac_strdup_printf(n-mac);
+info-main_mac = qemu_mac_strdup_printf(n-mac);
 
 str_list = NULL;
 for (i = 0; i  n-mac_table.first_multi; i++) {
 entry = g_malloc0(sizeof(*entry));
-entry-value = mac_strdup_printf(n-mac_table.macs + i * ETH_ALEN);
+entry-value = qemu_mac_strdup_printf(n-mac_table.macs + i * 
ETH_ALEN);
 entry-next = str_list;
 str_list = entry;
 }
@@ -298,7 +292,7 @@ static RxFilterInfo 
*virtio_net_query_rxfilter(NetClientState *nc)
 str_list = NULL;
 for (i = n-mac_table.first_multi; i  n-mac_table.in_use; i++) {
 entry = g_malloc0(sizeof(*entry));
-entry-value = mac_strdup_printf(n-mac_table.macs + i * ETH_ALEN);
+entry-value = qemu_mac_strdup_printf(n-mac_table.macs + i * 
ETH_ALEN);
 entry-next = str_list;
 str_list = entry;
 }
-- 
1.7.10.4




[Qemu-devel] [PATCH v5 09/10] MAINTAINERS: add rocker

2015-01-22 Thread sfeldma
From: Scott Feldman sfel...@gmail.com

Signed-off-by: Scott Feldman sfel...@gmail.com
Signed-off-by: Jiri Pirko j...@resnulli.us
---
 MAINTAINERS |6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 430688d..8b6f8d4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -736,6 +736,12 @@ S: Maintained
 F: hw/net/vmxnet*
 F: hw/scsi/vmw_pvscsi*
 
+Rocker
+M: Scott Feldman sfel...@gmail.com
+M: Jiri Pirko j...@resnulli.us
+S: Maintained
+F: hw/net/rocker/
+
 Subsystems
 --
 Audio
-- 
1.7.10.4




Re: [Qemu-devel] [PATCH] vfio: fix wrong initialize vfio_group_list

2015-01-22 Thread Eric Auger
Hi Chen,

thanks for correcting this mistake I introduced when moving code from
pci to common.

Best Regards

Eric

On 01/22/2015 04:50 AM, Chen Fan wrote:
 Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com
 ---
  hw/vfio/common.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/hw/vfio/common.c b/hw/vfio/common.c
 index cf483ff..e71385e 100644
 --- a/hw/vfio/common.c
 +++ b/hw/vfio/common.c
 @@ -32,7 +32,7 @@
  #include trace.h
  
  struct vfio_group_head vfio_group_list =
 -QLIST_HEAD_INITIALIZER(vfio_address_spaces);
 +QLIST_HEAD_INITIALIZER(vfio_group_list);
  struct vfio_as_head vfio_address_spaces =
  QLIST_HEAD_INITIALIZER(vfio_address_spaces);
  
 




Re: [Qemu-devel] [PATCH v5 10/10] rocker: timestamp on the debug logs helps correlate with events in the VM

2015-01-22 Thread Jiri Pirko
Thu, Jan 22, 2015 at 09:03:59AM CET, sfel...@gmail.com wrote:
From: David Ahern dsah...@gmail.com

Signed-off-by: David Ahern dsah...@gmail.com
Signed-off-by: Scott Feldman sfel...@gmail.com

Signed-off-by: Jiri Pirko j...@resnulli.us


---
 hw/net/rocker/rocker.h |   11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/net/rocker/rocker.h b/hw/net/rocker/rocker.h
index ef77487..5ae8aff 100644
--- a/hw/net/rocker/rocker.h
+++ b/hw/net/rocker/rocker.h
@@ -25,7 +25,16 @@
 
 #if defined(DEBUG_ROCKER)
 #  define DPRINTF(fmt, ...) \
-do { fprintf(stderr, ROCKER:  fmt, ## __VA_ARGS__); } while (0)
+do {   \
+struct timeval tv; \
+char timestr[64];  \
+time_t now;\
+gettimeofday(tv, NULL);   \
+now = tv.tv_sec;   \
+strftime(timestr, sizeof(timestr), %T, localtime(now)); \
+fprintf(stderr, %s.%06ld , timestr, tv.tv_usec); \
+fprintf(stderr, ROCKER:  fmt, ## __VA_ARGS__);   \
+} while (0)
 #else
 static inline GCC_FMT_ATTR(1, 2) int DPRINTF(const char *fmt, ...)
 {
-- 
1.7.10.4




Re: [Qemu-devel] [RFC PATCH v7 15/21] replay: checkpoints

2015-01-22 Thread Pavel Dovgaluk
 From: Paolo Bonzini [mailto:pbonz...@redhat.com]
 On 13/01/2015 10:15, Pavel Dovgaluk wrote:
  The numbers have no meaning. They just have to be distinct in different 
  places.
 
 This is easier to achieve if you give a name to each place.
 
  Sorry, missed one thing.
  run_all is used to distinguish timers processed in AIO by calling of
 timerlistgroup_run_timers function
  and in main loop by calling qemu_clock_run_all_timers.
 
 Should you instead distinguish which TimerListGroup is being run?  Then
 main loop would checkpoint once for every TimerListGroup (which means
 twice).

I checked that. We should distinguish only run_all_timers and all other calls.
Distinguishing the TimerListGroups does not work - replay hangs.

Pavel Dovgalyuk




Re: [Qemu-devel] [PATCH] sb16: fix interrupt acknowledgement

2015-01-22 Thread Gerd Hoffmann
On Di, 2015-01-20 at 17:23 +0100, Paolo Bonzini wrote:
 SoundBlaster 16 emulation is very broken and consumes a lot of CPU, but a
 small fix was suggested offlist and it is enough to fix some games.  I
 got Epic Pinball to work with the SoundBlaster Clone option.
 
 The processing of the interrupt register is wrong due to two missing
 nots.  This causes the interrupt flag to remain set even after the
 Acknowledge ports have been read (0x0e and 0x0f).
 
 The line was introduced by commit 85571bc (audio merge (malc), 2004-11-07),
 but the code might have been broken before because I did not look closely
 at the huge patches from 10 years ago.

Looks sane, picked up.

thanks,
  Gerd




Re: [Qemu-devel] [PATCH] Add trace messages to input.c.

2015-01-22 Thread Gerd Hoffmann
  Hi,

 I believe this was used for debugging vmware mouse support we've been
 working on.

Wouldn't it be more useful to trace qemu_input_handler_* calls for that,
especially qemu_input_handler_activate?  So you also see changes
triggered by the guest, such as enabling vmmouse, or initializing the
usb-tablet?

cheers,
  Gerd





Re: [Qemu-devel] [PATCH v2 4/4] linux-user: initialize progname with error_set_progname()

2015-01-22 Thread Peter Maydell
On 22 January 2015 at 09:08, Hitoshi Mitake
mitake.hito...@lab.ntt.co.jp wrote:
 Calling error_get_progname() in the context of qemu-x86_64 can cause
 segmentation fault because linux-user/main.c doesn't initialize its
 progname with error_set_progname(). This patch adds the
 initialization.

 Currently, the missing call of error_set_progname() doesn't cause any
 problems because qemu-x86_64 doesn't use error_get_progname(). This
 patch is a proactive action.

I don't think this patch is right. The *-user binaries don't
(and should not) use the qemu-error infrastructure (they don't
have the monitor or any of the other stuff that uses). Code
which tries to use error_get_progname() in *-user would be
broken.

thanks
-- PMM



[Qemu-devel] [RFC PATCH v8 00/21] Deterministic replay core

2015-01-22 Thread Pavel Dovgalyuk
This set of patches is related to the reverse execution and deterministic 
replay of qemu execution  This implementation of deterministic replay can 
be used for deterministic debugging of guest code through gdb remote
interface.

These patches include only core function of the replay,
excluding the support for replaying serial, audio, network, and USB devices'
operations. Reverse debugging and monitor commands were also excluded to
be submitted later as separate patches.

Execution recording writes non-deterministic events log, which can be later 
used for replaying the execution anywhere and for unlimited number of times. 
It also supports checkpointing for faster rewinding during reverse debugging. 
Execution replaying reads the log and replays all non-deterministic events 
including external input, hardware clocks, and interrupts.

Deterministic replay has the following features:
 * Deterministically replays whole system execution and all contents of the 
memory,
   state of the hadrware devices, clocks, and screen of the VM.
 * Writes execution log into the file for latter replaying for multiple times 
   on different machines.
 * Supports i386, x86_64, and ARM hardware platforms.
 * Performs deterministic replay of all operations with keyboard and mouse
   input devices.
 * Supports auto-checkpointing for convenient reverse debugging.

Usage of the record/replay:
 * First, record the execution, by adding the following string to the command 
line:
   '-record fname=replay.bin -icount 7 -net none'. Block devices' images are not
   actually changed in the recording mode, because all of the changes are
   written to the temporary overlay file.
 * Then you can replay it for the multiple times by using another command
   line option: '-replay fname=replay.bin -icount 7 -net none'
 * '-net none' option should also be specified if network replay patches
   are not applied.

Paper with short description of deterministic replay implementation:
http://www.computer.org/csdl/proceedings/csmr/2012/4666/00/4666a553-abs.html

Modifications of qemu include:
 * wrappers for clock and time functions to save their return values in the log
 * saving different asynchronous events (e.g. system shutdown) into the log
 * synchronization of the bottom halves execution
 * synchronization of the threads from thread pool
 * recording/replaying user input (mouse and keyboard)
 * adding internal events for cpu and io synchronization

v8 changes:
 * Simplified processing of the shutdown event (as suggested by Paolo Bonzini)
 * Replaced stack of bottom halves in AIO context with QSIMPLEQ (as suggested 
by Paolo Bonzini)
 * Moved replay_submode out of the series (as suggested by Paolo Bonzini)
 * Moved suffix option out of the series
 * Converted some of the defines into enums (as suggested by Paolo Bonzini)
 * Encapsulated save_tm/read_tm calls into the single function (as suggested by 
Paolo Bonzini)
 * Moved record/replay options to icount group (as suggested by Paolo Bonzini)
 * Updated mutex protection for the events queue (as suggested by Paolo Bonzini)
 * Added mutex to protect replay log file (as suggested by Paolo Bonzini)
 * Minor cleanups

v7 changes:
 * Removed patches that were applied to upstream.

v6 changes:
 * Fixed replay stub return value (as suggested by Eric Blake)
 * Fixed icount warping.
 * Virtual rt clock now uses cpu_get_clock() (as suggested by Paolo Bonzini)
 * Replated get_clock_realtime and get_clock calls with qemu clock requests (as 
suggested by Paolo Bonzini)
 * Modified can_do_io logic to allow requesting icount from cpu_exec function 
(as suggested by Paolo Bonzini)
 * Removed applied patches.

v5 changes:
 * Minor changes.
 * Used fixed-width integer types for read/write functions (as suggested by 
Alex Bennee)
 * Moved savevm-related code out of the core.
 * Added new traced clock for deterministic virtual clock warping (as suggested 
by Paolo Bonzini)
 * Fixed exception_index reset for user mode (as suggested by Paolo Bonzini)
 * Adopted Paolo's icount patches
 * Fixed hardware interrupts replaying

v4 changes:
 * Updated block drivers to support new bdrv_open interface.
 * Moved migration patches into separate series (as suggested by Paolo Bonzini)
 * Fixed a bug in replay_break operation.
 * Fixed rtl8139 migration for replay.
 * Fixed 'period' parameter processing for record mode.
 * Fixed bug in 'reverse-stepi' implementation.
 * Fixed replay without making any snapshots (even the starting one).
 * Moved core replay patches into the separate series.
 * Fixed reverse step and reverse continue support.
 * Fixed several bugs in icount subsystem.
 * Reusing native qemu icount for replay instructions counting.
 * Separated core patches into their own series.

v3 changes:
 * Fixed bug with replay of the aio write operations.
 * Added virtual clock based on replay icount.
 * Removed duplicated saving of interrupt_request CPU field.
 * Fixed some coding style issues.
 * Renamed QMP commands for 

[Qemu-devel] [RFC PATCH v8 02/21] replay: global variables and function stubs

2015-01-22 Thread Pavel Dovgalyuk
This patch adds global variables, defines, functions declarations,
and function stubs for deterministic VM replay used by external modules.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 Makefile.target  |1 +
 qapi-schema.json |   18 ++
 replay/Makefile.objs |1 +
 replay/replay.c  |   14 ++
 replay/replay.h  |   19 +++
 stubs/Makefile.objs  |1 +
 stubs/replay.c   |3 +++
 7 files changed, 57 insertions(+), 0 deletions(-)
 create mode 100755 replay/Makefile.objs
 create mode 100755 replay/replay.c
 create mode 100755 replay/replay.h
 create mode 100755 stubs/replay.c

diff --git a/Makefile.target b/Makefile.target
index e9ff1ee..a45378f 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -83,6 +83,7 @@ all: $(PROGS) stap
 #
 # cpu emulator library
 obj-y = exec.o translate-all.o cpu-exec.o
+obj-y += replay/
 obj-y += tcg/tcg.o tcg/optimize.o
 obj-$(CONFIG_TCG_INTERPRETER) += tci.o
 obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
diff --git a/qapi-schema.json b/qapi-schema.json
index fbfc52f..7e3177f 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3523,3 +3523,21 @@
 # Since: 2.1
 ##
 { 'command': 'rtc-reset-reinjection' }
+
+##
+# ReplayMode:
+#
+# Mode of the replay subsystem.
+#
+# @none: normal execution mode. Replay or record are not enabled.
+#
+# @record: record mode. All non-deterministic data is written into the
+#  replay log.
+#
+# @play: replay mode. Non-deterministic data required for system execution
+#is read from the log.
+#
+# Since: 2.3
+##
+{ 'enum': 'ReplayMode',
+  'data': [ 'none', 'record', 'play' ] }
diff --git a/replay/Makefile.objs b/replay/Makefile.objs
new file mode 100755
index 000..7ea860f
--- /dev/null
+++ b/replay/Makefile.objs
@@ -0,0 +1 @@
+obj-y += replay.o
diff --git a/replay/replay.c b/replay/replay.c
new file mode 100755
index 000..5ce066f
--- /dev/null
+++ b/replay/replay.c
@@ -0,0 +1,14 @@
+/*
+ * replay.c
+ *
+ * Copyright (c) 2010-2015 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include replay.h
+
+ReplayMode replay_mode = REPLAY_MODE_NONE;
diff --git a/replay/replay.h b/replay/replay.h
new file mode 100755
index 000..d6b73c3
--- /dev/null
+++ b/replay/replay.h
@@ -0,0 +1,19 @@
+#ifndef REPLAY_H
+#define REPLAY_H
+
+/*
+ * replay.h
+ *
+ * Copyright (c) 2010-2015 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include qapi-types.h
+
+extern ReplayMode replay_mode;
+
+#endif
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 5e347d0..45a6c71 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -27,6 +27,7 @@ stub-obj-y += notify-event.o
 stub-obj-y += pci-drive-hot-add.o
 stub-obj-$(CONFIG_SPICE) += qemu-chr-open-spice.o
 stub-obj-y += qtest.o
+stub-obj-y += replay.o
 stub-obj-y += reset.o
 stub-obj-y += runstate-check.o
 stub-obj-y += set-fd-handler.o
diff --git a/stubs/replay.c b/stubs/replay.c
new file mode 100755
index 000..563c777
--- /dev/null
+++ b/stubs/replay.c
@@ -0,0 +1,3 @@
+#include replay/replay.h
+
+ReplayMode replay_mode;




[Qemu-devel] [RFC PATCH v8 01/21] i386: partial revert of interrupt poll fix

2015-01-22 Thread Pavel Dovgalyuk
Processing CPU_INTERRUPT_POLL requests in cpu_has_work functions
break the determinism of cpu_exec. This patch is required to make
interrupts processing deterministic.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 cpu-exec.c|6 ++
 target-i386/cpu.c |   10 ++
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index a4f0eff..0a485bb 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -338,6 +338,12 @@ int cpu_exec(CPUArchState *env)
 volatile bool have_tb_lock = false;
 
 if (cpu-halted) {
+#ifdef TARGET_I386
+if (cpu-interrupt_request  CPU_INTERRUPT_POLL) {
+apic_poll_irq(x86_cpu-apic_state);
+cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
+}
+#endif
 if (!cpu_has_work(cpu)) {
 return EXCP_HALTED;
 }
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index b81ac5c..8f1f7aa 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2970,14 +2970,8 @@ static bool x86_cpu_has_work(CPUState *cs)
 X86CPU *cpu = X86_CPU(cs);
 CPUX86State *env = cpu-env;
 
-#if !defined(CONFIG_USER_ONLY)
-if (cs-interrupt_request  CPU_INTERRUPT_POLL) {
-apic_poll_irq(cpu-apic_state);
-cpu_reset_interrupt(cs, CPU_INTERRUPT_POLL);
-}
-#endif
-
-return ((cs-interrupt_request  CPU_INTERRUPT_HARD) 
+return ((cs-interrupt_request  (CPU_INTERRUPT_HARD |
+  CPU_INTERRUPT_POLL)) 
 (env-eflags  IF_MASK)) ||
(cs-interrupt_request  (CPU_INTERRUPT_NMI |
  CPU_INTERRUPT_INIT |




[Qemu-devel] [RFC PATCH v8 07/21] cpu-exec: allow temporary disabling icount

2015-01-22 Thread Pavel Dovgalyuk
This patch is required for deterministic replay to generate an exception
by trying executing an instruction without changing icount.
It adds new flag to TB for disabling icount while translating it.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 cpu-exec.c  |7 ---
 include/exec/exec-all.h |1 +
 translate-all.c |2 +-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 0a485bb..49f01f5 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -200,7 +200,7 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, 
uint8_t *tb_ptr)
 /* Execute the code without caching the generated code. An interpreter
could be used if available. */
 static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
- TranslationBlock *orig_tb)
+ TranslationBlock *orig_tb, bool ignore_icount)
 {
 CPUState *cpu = ENV_GET_CPU(env);
 TranslationBlock *tb;
@@ -216,7 +216,8 @@ static void cpu_exec_nocache(CPUArchState *env, int 
max_cycles,
 /* tb_gen_code can flush our orig_tb, invalidate it now */
 tb_phys_invalidate(orig_tb, -1);
 tb = tb_gen_code(cpu, pc, cs_base, flags,
- max_cycles | CF_NOCACHE);
+ max_cycles | CF_NOCACHE
+ | (ignore_icount ? CF_IGNORE_ICOUNT : 0));
 cpu-current_tb = tb;
 /* execute the generated code */
 trace_exec_tb_nocache(tb, tb-pc);
@@ -525,7 +526,7 @@ int cpu_exec(CPUArchState *env)
 } else {
 if (insns_left  0) {
 /* Execute remaining instructions.  */
-cpu_exec_nocache(env, insns_left, tb);
+cpu_exec_nocache(env, insns_left, tb, false);
 align_clocks(sc, cpu);
 }
 cpu-exception_index = EXCP_INTERRUPT;
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 63fb1a3..48a7541 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -148,6 +148,7 @@ struct TranslationBlock {
 #define CF_LAST_IO 0x8000 /* Last insn may be an IO access.  */
 #define CF_NOCACHE 0x1 /* To be freed after execution */
 #define CF_USE_ICOUNT  0x2
+#define CF_IGNORE_ICOUNT 0x4 /* Do not generate icount code */
 
 void *tc_ptr;/* pointer to the translated code */
 /* next matching tb for physical address. */
diff --git a/translate-all.c b/translate-all.c
index c0cba7d..49b3403 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1053,7 +1053,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
 int code_gen_size;
 
 phys_pc = get_page_addr_code(env, pc);
-if (use_icount) {
+if (use_icount  !(cflags  CF_IGNORE_ICOUNT)) {
 cflags |= CF_USE_ICOUNT;
 }
 tb = tb_alloc(pc);




[Qemu-devel] [RFC PATCH v8 17/21] replay: replay aio requests

2015-01-22 Thread Pavel Dovgalyuk
This patch adds identifier to aio requests. ID is used for creating bottom
halves and identifying them while replaying.
The patch also introduces several functions that make possible replaying
of the aio requests.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 block.c|   81 
 block/block-backend.c  |   30 ++-
 block/qcow2.c  |4 ++
 dma-helpers.c  |6 ++-
 hw/block/virtio-blk.c  |   10 ++---
 hw/ide/atapi.c |   10 +++--
 hw/ide/core.c  |   14 ---
 include/block/block.h  |   15 +++
 include/qemu-common.h  |2 +
 include/sysemu/block-backend.h |   10 +
 qemu-io-cmds.c |2 -
 stubs/replay.c |5 ++
 trace-events   |2 +
 util/iov.c |4 ++
 14 files changed, 167 insertions(+), 28 deletions(-)

diff --git a/block.c b/block.c
index a4f45c3..7f6fa8b 100644
--- a/block.c
+++ b/block.c
@@ -83,7 +83,8 @@ static BlockAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
  BdrvRequestFlags flags,
  BlockCompletionFunc *cb,
  void *opaque,
- bool is_write);
+ bool is_write,
+ bool aio_replay);
 static void coroutine_fn bdrv_co_do_rw(void *opaque);
 static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
 int64_t sector_num, int nb_sectors, BdrvRequestFlags flags);
@@ -4425,7 +4426,19 @@ BlockAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t 
sector_num,
 trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
 
 return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 0,
- cb, opaque, false);
+ cb, opaque, false, false);
+}
+
+BlockAIOCB *bdrv_aio_readv_replay(BlockDriverState *bs,
+  int64_t sector_num,
+  QEMUIOVector *qiov, int nb_sectors,
+  BlockCompletionFunc *cb,
+  void *opaque)
+{
+trace_bdrv_aio_readv_replay(bs, sector_num, nb_sectors, opaque);
+
+return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 0,
+ cb, opaque, false, true);
 }
 
 BlockAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
@@ -4435,7 +4448,19 @@ BlockAIOCB *bdrv_aio_writev(BlockDriverState *bs, 
int64_t sector_num,
 trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
 
 return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 0,
- cb, opaque, true);
+ cb, opaque, true, false);
+}
+
+BlockAIOCB *bdrv_aio_writev_replay(BlockDriverState *bs,
+   int64_t sector_num,
+   QEMUIOVector *qiov, int nb_sectors,
+   BlockCompletionFunc *cb,
+   void *opaque)
+{
+trace_bdrv_aio_writev_replay(bs, sector_num, nb_sectors, opaque);
+
+return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, 0,
+ cb, opaque, true, true);
 }
 
 BlockAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs,
@@ -4446,7 +4471,7 @@ BlockAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs,
 
 return bdrv_co_aio_rw_vector(bs, sector_num, NULL, nb_sectors,
  BDRV_REQ_ZERO_WRITE | flags,
- cb, opaque, true);
+ cb, opaque, true, true);
 }
 
 
@@ -4593,7 +4618,8 @@ static int multiwrite_merge(BlockDriverState *bs, 
BlockRequest *reqs,
  * requests. However, the fields opaque and error are left unmodified as they
  * are used to signal failure for a single request to the caller.
  */
-int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
+int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs,
+bool replay)
 {
 MultiwriteCB *mcb;
 int i;
@@ -4631,7 +4657,7 @@ int bdrv_aio_multiwrite(BlockDriverState *bs, 
BlockRequest *reqs, int num_reqs)
 bdrv_co_aio_rw_vector(bs, reqs[i].sector, reqs[i].qiov,
   reqs[i].nb_sectors, reqs[i].flags,
   multiwrite_cb, mcb,
-  true);
+  true, replay);
 }
 
 return 0;
@@ -4776,7 +4802,12 @@ static void coroutine_fn bdrv_co_do_rw(void *opaque)
 acb-req.nb_sectors, acb-req.qiov, acb-req.flags);
 }
 
-acb-bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_co_em_bh, acb);
+if 

[Qemu-devel] [RFC PATCH v8 15/21] aio: replace stack of bottom halves with queue

2015-01-22 Thread Pavel Dovgalyuk
Bottom halves in AIO context are stored and removes
in LIFO order. It makes their execution non-deterministic.
This patch replaces the stack with queue to preserve the
order of bottom halves processing.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 async.c  |   25 +
 include/block/aio.h  |4 ++--
 include/qemu/queue.h |7 +++
 3 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/async.c b/async.c
index 2be88cc..bc6e83b 100644
--- a/async.c
+++ b/async.c
@@ -35,7 +35,7 @@ struct QEMUBH {
 AioContext *ctx;
 QEMUBHFunc *cb;
 void *opaque;
-QEMUBH *next;
+QSIMPLEQ_ENTRY(QEMUBH) next;
 bool scheduled;
 bool idle;
 bool deleted;
@@ -51,10 +51,7 @@ QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void 
*opaque)
 .opaque = opaque,
 };
 qemu_mutex_lock(ctx-bh_lock);
-bh-next = ctx-first_bh;
-/* Make sure that the members are ready before putting bh into list */
-smp_wmb();
-ctx-first_bh = bh;
+QSIMPLEQ_INSERT_TAIL_RCU(ctx-bh_queue, bh, next);
 qemu_mutex_unlock(ctx-bh_lock);
 return bh;
 }
@@ -62,16 +59,15 @@ QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void 
*opaque)
 /* Multiple occurrences of aio_bh_poll cannot be called concurrently */
 int aio_bh_poll(AioContext *ctx)
 {
-QEMUBH *bh, **bhp, *next;
+QEMUBH *bh, *next;
 int ret;
 
 ctx-walking_bh++;
 
 ret = 0;
-for (bh = ctx-first_bh; bh; bh = next) {
+QSIMPLEQ_FOREACH_SAFE(bh, ctx-bh_queue, next, next) {
 /* Make sure that fetching bh happens before accessing its members */
 smp_read_barrier_depends();
-next = bh-next;
 if (!bh-deleted  bh-scheduled) {
 bh-scheduled = 0;
 /* Paired with write barrier in bh schedule to ensure reading for
@@ -90,14 +86,10 @@ int aio_bh_poll(AioContext *ctx)
 /* remove deleted bhs */
 if (!ctx-walking_bh) {
 qemu_mutex_lock(ctx-bh_lock);
-bhp = ctx-first_bh;
-while (*bhp) {
-bh = *bhp;
+QSIMPLEQ_FOREACH_SAFE(bh, ctx-bh_queue, next, next) {
 if (bh-deleted) {
-*bhp = bh-next;
+QSIMPLEQ_REMOVE(ctx-bh_queue, bh, QEMUBH, next);
 g_free(bh);
-} else {
-bhp = bh-next;
 }
 }
 qemu_mutex_unlock(ctx-bh_lock);
@@ -161,7 +153,7 @@ aio_compute_timeout(AioContext *ctx)
 int timeout = -1;
 QEMUBH *bh;
 
-for (bh = ctx-first_bh; bh; bh = bh-next) {
+QSIMPLEQ_FOREACH(bh, ctx-bh_queue, next) {
 if (!bh-deleted  bh-scheduled) {
 if (bh-idle) {
 /* idle bottom halves will be polled at least
@@ -204,7 +196,7 @@ aio_ctx_check(GSource *source)
 AioContext *ctx = (AioContext *) source;
 QEMUBH *bh;
 
-for (bh = ctx-first_bh; bh; bh = bh-next) {
+QSIMPLEQ_FOREACH(bh, ctx-bh_queue, next) {
 if (!bh-deleted  bh-scheduled) {
 return true;
}
@@ -311,6 +303,7 @@ AioContext *aio_context_new(Error **errp)
 qemu_mutex_init(ctx-bh_lock);
 rfifolock_init(ctx-lock, aio_rfifolock_cb, ctx);
 timerlistgroup_init(ctx-tlg, aio_timerlist_notify, ctx);
+QSIMPLEQ_INIT(ctx-bh_queue);
 
 return ctx;
 }
diff --git a/include/block/aio.h b/include/block/aio.h
index 7d1e26b..82cdf78 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -71,8 +71,8 @@ struct AioContext {
 /* lock to protect between bh's adders and deleter */
 QemuMutex bh_lock;
 
-/* Anchor of the list of Bottom Halves belonging to the context */
-struct QEMUBH *first_bh;
+/* List of Bottom Halves belonging to the context */
+QSIMPLEQ_HEAD(, QEMUBH) bh_queue;
 
 /* A simple lock used to protect the first_bh list, and ensure that
  * no callbacks are removed while we're walking and dispatching callbacks.
diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index a98eb3a..b94c4d4 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -268,6 +268,13 @@ struct {   
 \
 (head)-sqh_last = (elm)-field.sqe_next;  \
 } while (/*CONSTCOND*/0)
 
+#define QSIMPLEQ_INSERT_TAIL_RCU(head, elm, field) do { \
+(elm)-field.sqe_next = NULL;   \
+*(head)-sqh_last = (elm);  \
+(head)-sqh_last = (elm)-field.sqe_next;  \
+smp_wmb();  \
+} while (/*CONSTCOND*/0)
+
 #define QSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {   \
 if (((elm)-field.sqe_next = (listelm)-field.sqe_next) == NULL)\
 (head)-sqh_last = (elm)-field.sqe_next;  \




[Qemu-devel] [RFC PATCH v8 20/21] replay: command line options

2015-01-22 Thread Pavel Dovgalyuk
This patch introduces command line options for enabling recording or replaying
virtual machine behavior. -record option starts recording of the execution
and saves it into the log, specified with fname parameter. -replay option
is intended for replaying previously saved log.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 cpus.c  |3 ++-
 qemu-options.hx |8 ++--
 vl.c|   27 ++-
 3 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/cpus.c b/cpus.c
index 9c32491..7689cec 100644
--- a/cpus.c
+++ b/cpus.c
@@ -912,9 +912,10 @@ static void qemu_wait_io_event_common(CPUState *cpu)
 static void qemu_tcg_wait_io_event(void)
 {
 CPUState *cpu;
+GMainContext *context = g_main_context_default();
 
 while (all_cpu_threads_idle()) {
-   /* Start accounting real time to the virtual clock if the CPUs
+/* Start accounting real time to the virtual clock if the CPUs
   are idle.  */
 qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
 qemu_cond_wait(tcg_halt_cond, qemu_global_mutex);
diff --git a/qemu-options.hx b/qemu-options.hx
index 10b9568..cb4b577 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3037,11 +3037,11 @@ re-inject them.
 ETEXI
 
 DEF(icount, HAS_ARG, QEMU_OPTION_icount, \
--icount [shift=N|auto][,align=on|off]\n \
+-icount 
[shift=N|auto][,align=on|off][,rr=record|replay,rrfname=filename]\n \
 enable virtual instruction counter with 2^N clock ticks 
per\n \
 instruction and enable aligning the host and virtual 
clocks\n, QEMU_ARCH_ALL)
 STEXI
-@item -icount [shift=@var{N}|auto]
+@item -icount [shift=@var{N}|auto][,rr=record|replay,rrfname=@var{filename}]
 @findex -icount
 Enable virtual instruction counter.  The virtual cpu will execute one
 instruction every 2^@var{N} ns of virtual time.  If @code{auto} is specified
@@ -3063,6 +3063,10 @@ Currently this option does not work when @option{shift} 
is @code{auto}.
 Note: The sync algorithm will work for those shift values for which
 the guest clock runs ahead of the host clock. Typically this happens
 when the shift value is high (how high depends on the host machine).
+
+When @option{rr} option is specified deterministic record/replay is enabled.
+Replay log is written into @var{filename} file in record mode and
+read from this file in replay mode.
 ETEXI
 
 DEF(watchdog, HAS_ARG, QEMU_OPTION_watchdog, \
diff --git a/vl.c b/vl.c
index ae3e97e..39d9024 100644
--- a/vl.c
+++ b/vl.c
@@ -475,6 +475,12 @@ static QemuOptsList qemu_icount_opts = {
 }, {
 .name = align,
 .type = QEMU_OPT_BOOL,
+}, {
+.name = rr,
+.type = QEMU_OPT_STRING,
+}, {
+.name = rrfname,
+.type = QEMU_OPT_STRING,
 },
 { /* end of list */ }
 },
@@ -2752,6 +2758,8 @@ int main(int argc, char **argv, char **envp)
 {
 int i;
 int snapshot, linux_boot;
+int not_compatible_replay_param = 0;
+const char *icount_option = NULL;
 const char *initrd_filename;
 const char *kernel_filename, *kernel_cmdline;
 const char *boot_order;
@@ -2949,6 +2957,7 @@ int main(int argc, char **argv, char **envp)
 break;
 case QEMU_OPTION_pflash:
 drive_add(IF_PFLASH, -1, optarg, PFLASH_OPTS);
+not_compatible_replay_param++;
 break;
 case QEMU_OPTION_snapshot:
 snapshot = 1;
@@ -3105,6 +3114,7 @@ int main(int argc, char **argv, char **envp)
 #endif
 case QEMU_OPTION_bt:
 add_device_config(DEV_BT, optarg);
+not_compatible_replay_param++;
 break;
 case QEMU_OPTION_audio_help:
 AUD_help ();
@@ -3244,6 +3254,7 @@ int main(int argc, char **argv, char **envp)
 if (!opts) {
 exit(1);
 }
+not_compatible_replay_param++;
 break;
 case QEMU_OPTION_fsdev:
 olist = qemu_find_opts(fsdev);
@@ -3372,6 +3383,7 @@ int main(int argc, char **argv, char **envp)
 if (strncmp(optarg, mon:, 4) == 0) {
 default_monitor = 0;
 }
+not_compatible_replay_param++;
 break;
 case QEMU_OPTION_debugcon:
 add_device_config(DEV_DEBUGCON, optarg);
@@ -3489,6 +3501,7 @@ int main(int argc, char **argv, char **envp)
 if (!qemu_opts_parse(qemu_find_opts(smp-opts), optarg, 1)) {
 exit(1);
 }
+not_compatible_replay_param++;
 break;
 case QEMU_OPTION_vnc:
 #ifdef CONFIG_VNC
@@ -3628,6 +3641,7 @@ int main(int argc, char **argv, char **envp)
 if (!icount_opts) {
 exit(1);
 }
+

[Qemu-devel] [RFC PATCH v8 19/21] replay: initialization and deinitialization

2015-01-22 Thread Pavel Dovgalyuk
This patch introduces the functions for enabling the record/replay and for
freeing the resources when simulator closes.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 block.c  |2 -
 exec.c   |1 
 replay/replay-internal.c |1 
 replay/replay-internal.h |4 +
 replay/replay.c  |  140 ++
 replay/replay.h  |   13 
 stubs/replay.c   |1 
 vl.c |5 ++
 8 files changed, 165 insertions(+), 2 deletions(-)

diff --git a/block.c b/block.c
index 7f6fa8b..9923a80 100644
--- a/block.c
+++ b/block.c
@@ -2010,7 +2010,7 @@ void bdrv_drain_all(void)
 aio_context_release(aio_context);
 }
 }
-if (replay_mode == REPLAY_MODE_PLAY) {
+if (replay_mode == REPLAY_MODE_PLAY  replay_checkpoints) {
 /* Skip checkpoints from the log */
 while (replay_checkpoint(CHECKPOINT_BDRV_DRAIN)) {
 /* Nothing */
diff --git a/exec.c b/exec.c
index 410371d..f70f03d 100644
--- a/exec.c
+++ b/exec.c
@@ -783,6 +783,7 @@ void cpu_abort(CPUState *cpu, const char *fmt, ...)
 }
 va_end(ap2);
 va_end(ap);
+replay_finish();
 #if defined(CONFIG_USER_ONLY)
 {
 struct sigaction act;
diff --git a/replay/replay-internal.c b/replay/replay-internal.c
index 49b37a6..d608b71 100755
--- a/replay/replay-internal.c
+++ b/replay/replay-internal.c
@@ -33,6 +33,7 @@ void replay_put_byte(uint8_t byte)
 
 void replay_put_event(uint8_t event)
 {
+assert(event = EVENT_END);
 replay_put_byte(event);
 }
 
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index 4d242aa..1e5d037 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -34,7 +34,9 @@ enum ReplayEvents {
 EVENT_CLOCK,
 /* for checkpoint event */
 /* some of grteater codes are reserved for checkpoints */
-EVENT_CHECKPOINT = EVENT_CLOCK + REPLAY_CLOCK_COUNT
+EVENT_CHECKPOINT = EVENT_CLOCK + REPLAY_CLOCK_COUNT,
+/* end of log event */
+EVENT_END = EVENT_CHECKPOINT + CHECKPOINT_COUNT
 };
 
 /* Asynchronous events IDs */
diff --git a/replay/replay.c b/replay/replay.c
index 7c4a801..fa738c2 100755
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -15,9 +15,18 @@
 #include qemu/timer.h
 #include sysemu/sysemu.h
 
+/* Current version of the replay mechanism.
+   Increase it when file format changes. */
+#define REPLAY_VERSION  0xe02002
+/* Size of replay log header */
+#define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t))
+
 ReplayMode replay_mode = REPLAY_MODE_NONE;
 
+/* Name of replay file  */
+static char *replay_filename;
 ReplayState replay_state;
+bool replay_checkpoints;
 
 bool skip_async_events(int stop_event)
 {
@@ -167,6 +176,10 @@ void replay_shutdown_request(void)
 bool replay_checkpoint(ReplayCheckpoint checkpoint)
 {
 bool res = false;
+if (!replay_checkpoints) {
+return true;
+}
+
 replay_save_instructions();
 
 if (replay_file) {
@@ -199,3 +212,130 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint)
 
 return true;
 }
+
+static void replay_enable(const char *fname, int mode)
+{
+const char *fmode = NULL;
+if (replay_file) {
+fprintf(stderr,
+Replay: some record/replay operation is already started\n);
+return;
+}
+
+switch (mode) {
+case REPLAY_MODE_RECORD:
+fmode = wb;
+break;
+case REPLAY_MODE_PLAY:
+fmode = rb;
+break;
+default:
+fprintf(stderr, Replay: internal error: invalid replay mode\n);
+exit(1);
+}
+
+atexit(replay_finish);
+
+replay_mutex_init();
+
+replay_file = fopen(fname, fmode);
+if (replay_file == NULL) {
+fprintf(stderr, Replay: open %s: %s\n, fname, strerror(errno));
+exit(1);
+}
+
+replay_filename = g_strdup(fname);
+
+replay_mode = mode;
+replay_has_unread_data = 0;
+replay_data_kind = -1;
+replay_state.instructions_count = 0;
+replay_state.current_step = 0;
+
+/* skip file header for RECORD and check it for PLAY */
+if (replay_mode == REPLAY_MODE_RECORD) {
+fseek(replay_file, HEADER_SIZE, SEEK_SET);
+} else if (replay_mode == REPLAY_MODE_PLAY) {
+unsigned int version = replay_get_dword();
+uint64_t offset = replay_get_qword();
+if (version != REPLAY_VERSION) {
+fprintf(stderr, Replay: invalid input log file version\n);
+exit(1);
+}
+/* go to the beginning */
+fseek(replay_file, 12, SEEK_SET);
+}
+
+replay_init_events();
+}
+
+void replay_configure(QemuOpts *opts)
+{
+const char *fname;
+const char *rr;
+ReplayMode mode = REPLAY_MODE_NONE;
+
+rr = qemu_opt_get(opts, rr);
+if (!rr) {
+/* Just enabling icount */
+return;
+} else if (!strcmp(rr, record)) {
+mode = REPLAY_MODE_RECORD;
+} else if 

[Qemu-devel] [RFC PATCH v8 08/21] cpu: replay instructions sequence

2015-01-22 Thread Pavel Dovgalyuk
This patch adds calls to replay functions into the icount setup block.
In record mode number of executed instructions is written to the log.
In replay mode number of istructions to execute is taken from the replay log.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 cpu-exec.c  |1 +
 cpus.c  |   28 ++--
 replay/replay.c |   24 
 replay/replay.h |4 
 4 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 49f01f5..99a0993 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -531,6 +531,7 @@ int cpu_exec(CPUArchState *env)
 }
 cpu-exception_index = EXCP_INTERRUPT;
 next_tb = 0;
+qemu_notify_event();
 cpu_loop_exit(cpu);
 }
 break;
diff --git a/cpus.c b/cpus.c
index c513275..8787277 100644
--- a/cpus.c
+++ b/cpus.c
@@ -41,6 +41,7 @@
 #include qemu/seqlock.h
 #include qapi-event.h
 #include hw/nmi.h
+#include replay/replay.h
 
 #ifndef _WIN32
 #include qemu/compatfd.h
@@ -1342,18 +1343,22 @@ static int tcg_cpu_exec(CPUArchState *env)
 + cpu-icount_extra);
 cpu-icount_decr.u16.low = 0;
 cpu-icount_extra = 0;
-deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+if (replay_mode != REPLAY_MODE_PLAY) {
+deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
 
-/* Maintain prior (possibly buggy) behaviour where if no deadline
- * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than
- * INT32_MAX nanoseconds ahead, we still use INT32_MAX
- * nanoseconds.
- */
-if ((deadline  0) || (deadline  INT32_MAX)) {
-deadline = INT32_MAX;
-}
+/* Maintain prior (possibly buggy) behaviour where if no deadline
+ * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more 
than
+ * INT32_MAX nanoseconds ahead, we still use INT32_MAX
+ * nanoseconds.
+ */
+if ((deadline  0) || (deadline  INT32_MAX)) {
+deadline = INT32_MAX;
+}
 
-count = qemu_icount_round(deadline);
+count = qemu_icount_round(deadline);
+} else {
+count = replay_get_instructions();
+}
 timers_state.qemu_icount += count;
 decr = (count  0x) ? 0x : count;
 count -= decr;
@@ -1371,6 +1376,9 @@ static int tcg_cpu_exec(CPUArchState *env)
 + cpu-icount_extra);
 cpu-icount_decr.u32 = 0;
 cpu-icount_extra = 0;
+if (replay_mode == REPLAY_MODE_PLAY) {
+replay_exec_instructions();
+}
 }
 return ret;
 }
diff --git a/replay/replay.c b/replay/replay.c
index a43bbbc..d6f5c4b 100755
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -58,3 +58,27 @@ uint64_t replay_get_current_step(void)
 {
 return cpu_get_icount_raw();
 }
+
+int replay_get_instructions(void)
+{
+int res = 0;
+replay_mutex_lock();
+if (skip_async_events(EVENT_INSTRUCTION)) {
+res = replay_state.instructions_count;
+}
+replay_mutex_unlock();
+return res;
+}
+
+void replay_exec_instructions(void)
+{
+if (replay_state.instructions_count  0) {
+int count = (int)(replay_get_current_step()
+  - replay_state.current_step);
+replay_state.instructions_count -= count;
+replay_state.current_step += count;
+if (replay_state.instructions_count == 0  count != 0) {
+replay_has_unread_data = 0;
+}
+}
+}
diff --git a/replay/replay.h b/replay/replay.h
index a03c748..e425dea 100755
--- a/replay/replay.h
+++ b/replay/replay.h
@@ -22,5 +22,9 @@ extern ReplayMode replay_mode;
 
 /*! Returns number of executed instructions. */
 uint64_t replay_get_current_step(void);
+/*! Returns number of instructions to execute in replay mode. */
+int replay_get_instructions(void);
+/*! Updates instructions counter in replay mode. */
+void replay_exec_instructions(void);
 
 #endif




[Qemu-devel] [RFC PATCH v8 16/21] replay: bottom halves

2015-01-22 Thread Pavel Dovgalyuk
This patch introduces bottom half event for replay queue. It saves the events
into the queue and process them at the checkpoints and instructions execution.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 async.c  |   24 +++-
 dma-helpers.c|4 +++-
 hw/ide/ahci.c|4 +++-
 hw/ide/core.c|4 +++-
 hw/timer/arm_timer.c |2 +-
 hw/usb/hcd-uhci.c|2 +-
 include/block/aio.h  |   18 ++
 include/qemu/main-loop.h |1 +
 main-loop.c  |5 +
 replay/replay-events.c   |   16 
 replay/replay-internal.h |1 +
 replay/replay.h  |2 ++
 stubs/replay.c   |4 
 13 files changed, 81 insertions(+), 6 deletions(-)

diff --git a/async.c b/async.c
index bc6e83b..0c02ae2 100644
--- a/async.c
+++ b/async.c
@@ -27,6 +27,7 @@
 #include block/thread-pool.h
 #include qemu/main-loop.h
 #include qemu/atomic.h
+#include replay/replay.h
 
 /***/
 /* bottom halves (can be seen as timers which expire ASAP) */
@@ -39,6 +40,8 @@ struct QEMUBH {
 bool scheduled;
 bool idle;
 bool deleted;
+bool replay;
+uint64_t id;
 };
 
 QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
@@ -56,6 +59,21 @@ QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void 
*opaque)
 return bh;
 }
 
+QEMUBH *aio_bh_new_replay(AioContext *ctx, QEMUBHFunc *cb, void *opaque,
+  uint64_t id)
+{
+QEMUBH *bh = aio_bh_new(ctx, cb, opaque);
+bh-replay = true;
+bh-id = id;
+return bh;
+}
+
+void aio_bh_call(void *opaque)
+{
+QEMUBH *bh = (QEMUBH *)opaque;
+bh-cb(bh-opaque);
+}
+
 /* Multiple occurrences of aio_bh_poll cannot be called concurrently */
 int aio_bh_poll(AioContext *ctx)
 {
@@ -77,7 +95,11 @@ int aio_bh_poll(AioContext *ctx)
 if (!bh-idle)
 ret = 1;
 bh-idle = 0;
-bh-cb(bh-opaque);
+if (!bh-replay) {
+aio_bh_call(bh);
+} else {
+replay_add_bh_event(bh, bh-id);
+}
 }
 }
 
diff --git a/dma-helpers.c b/dma-helpers.c
index 6918572..357d7e9 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -13,6 +13,7 @@
 #include qemu/range.h
 #include qemu/thread.h
 #include qemu/main-loop.h
+#include replay/replay.h
 
 /* #define DEBUG_IOMMU */
 
@@ -96,7 +97,8 @@ static void continue_after_map_failure(void *opaque)
 {
 DMAAIOCB *dbs = (DMAAIOCB *)opaque;
 
-dbs-bh = qemu_bh_new(reschedule_dma, dbs);
+dbs-bh = qemu_bh_new_replay(reschedule_dma, dbs,
+ replay_get_current_step());
 qemu_bh_schedule(dbs-bh);
 }
 
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 5651372..13d7f84 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -33,6 +33,7 @@
 #include internal.h
 #include hw/ide/pci.h
 #include hw/ide/ahci.h
+#include replay/replay.h
 
 #define DEBUG_AHCI 0
 
@@ -1243,7 +1244,8 @@ static void ahci_cmd_done(IDEDMA *dma)
 
 if (!ad-check_bh) {
 /* maybe we still have something to process, check later */
-ad-check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);
+ad-check_bh = qemu_bh_new_replay(ahci_check_cmd_bh, ad,
+  replay_get_current_step());
 qemu_bh_schedule(ad-check_bh);
 }
 }
diff --git a/hw/ide/core.c b/hw/ide/core.c
index d4af5e2..d76244a 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -32,6 +32,7 @@
 #include sysemu/dma.h
 #include hw/block/block.h
 #include sysemu/block-backend.h
+#include replay/replay.h
 
 #include hw/ide/internal.h
 
@@ -448,7 +449,8 @@ BlockAIOCB *ide_issue_trim(BlockBackend *blk,
 
 iocb = blk_aio_get(trim_aiocb_info, blk, cb, opaque);
 iocb-blk = blk;
-iocb-bh = qemu_bh_new(ide_trim_bh_cb, iocb);
+iocb-bh = qemu_bh_new_replay(ide_trim_bh_cb, iocb,
+  replay_get_current_step());
 iocb-ret = 0;
 iocb-qiov = qiov;
 iocb-i = -1;
diff --git a/hw/timer/arm_timer.c b/hw/timer/arm_timer.c
index 1452910..97784a0 100644
--- a/hw/timer/arm_timer.c
+++ b/hw/timer/arm_timer.c
@@ -168,7 +168,7 @@ static arm_timer_state *arm_timer_init(uint32_t freq)
 s-freq = freq;
 s-control = TIMER_CTRL_IE;
 
-bh = qemu_bh_new(arm_timer_tick, s);
+bh = qemu_bh_new_replay(arm_timer_tick, s, 0);
 s-timer = ptimer_init(bh);
 vmstate_register(NULL, -1, vmstate_arm_timer, s);
 return s;
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 4a4215d..0d94143 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1221,7 +1221,7 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
   USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
 }
 }
-s-bh = qemu_bh_new(uhci_bh, s);
+s-bh = qemu_bh_new_replay(uhci_bh, s, 0);
 s-frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 

[Qemu-devel] [RFC PATCH v8 21/21] replay: recording of the user input

2015-01-22 Thread Pavel Dovgalyuk
This records user input (keyboard and mouse events) in record mode and replays
these input events in replay mode.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 include/ui/input.h   |2 +
 replay/Makefile.objs |1 
 replay/replay-events.c   |   55 +++
 replay/replay-input.c|  130 ++
 replay/replay-internal.h |   13 +
 replay/replay.h  |5 ++
 ui/input.c   |   68 +---
 7 files changed, 255 insertions(+), 19 deletions(-)
 create mode 100755 replay/replay-input.c

diff --git a/include/ui/input.h b/include/ui/input.h
index 5d5ac00..d06a12d 100644
--- a/include/ui/input.h
+++ b/include/ui/input.h
@@ -33,7 +33,9 @@ void qemu_input_handler_bind(QemuInputHandlerState *s,
  const char *device_id, int head,
  Error **errp);
 void qemu_input_event_send(QemuConsole *src, InputEvent *evt);
+void qemu_input_event_send_impl(QemuConsole *src, InputEvent *evt);
 void qemu_input_event_sync(void);
+void qemu_input_event_sync_impl(void);
 
 InputEvent *qemu_input_event_new_key(KeyValue *key, bool down);
 void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down);
diff --git a/replay/Makefile.objs b/replay/Makefile.objs
index 257c320..3936296 100755
--- a/replay/Makefile.objs
+++ b/replay/Makefile.objs
@@ -2,3 +2,4 @@ obj-y += replay.o
 obj-y += replay-internal.o
 obj-y += replay-events.o
 obj-y += replay-time.o
+obj-y += replay-input.o
diff --git a/replay/replay-events.c b/replay/replay-events.c
index f4ec702..2b599e2 100755
--- a/replay/replay-events.c
+++ b/replay/replay-events.c
@@ -13,6 +13,7 @@
 #include replay.h
 #include replay-internal.h
 #include block/thread-pool.h
+#include ui/input.h
 
 typedef struct Event {
 ReplayAsyncEventKind event_kind;
@@ -43,6 +44,16 @@ static void replay_run_event(Event *event)
 case REPLAY_ASYNC_EVENT_THREAD:
 thread_pool_work((ThreadPool *)event-opaque, event-opaque2);
 break;
+case REPLAY_ASYNC_EVENT_INPUT:
+qemu_input_event_send_impl(NULL, (InputEvent *)event-opaque);
+/* Using local variables, when replaying. Do not free them. */
+if (replay_mode == REPLAY_MODE_RECORD) {
+qapi_free_InputEvent((InputEvent *)event-opaque);
+}
+break;
+case REPLAY_ASYNC_EVENT_INPUT_SYNC:
+qemu_input_event_sync_impl();
+break;
 default:
 fprintf(stderr, Replay: invalid async event ID (%d) in the queue\n,
 event-event_kind);
@@ -139,6 +150,16 @@ void replay_add_thread_event(void *opaque, void *opaque2, 
uint64_t id)
 replay_add_event_internal(REPLAY_ASYNC_EVENT_THREAD, opaque, opaque2, id);
 }
 
+void replay_add_input_event(struct InputEvent *event)
+{
+replay_add_event_internal(REPLAY_ASYNC_EVENT_INPUT, event, NULL, 0);
+}
+
+void replay_add_input_sync_event(void)
+{
+replay_add_event_internal(REPLAY_ASYNC_EVENT_INPUT_SYNC, NULL, NULL, 0);
+}
+
 /* Called with replay mutex locked */
 void replay_save_events(int opt)
 {
@@ -157,6 +178,9 @@ void replay_save_events(int opt)
 case REPLAY_ASYNC_EVENT_THREAD:
 replay_put_qword(event-id);
 break;
+case REPLAY_ASYNC_EVENT_INPUT:
+replay_save_input_event(event-opaque);
+break;
 }
 }
 
@@ -187,6 +211,7 @@ void replay_read_events(int opt)
 break;
 }
 /* Execute some events without searching them in the queue */
+Event e;
 switch (read_event_kind) {
 case REPLAY_ASYNC_EVENT_BH:
 case REPLAY_ASYNC_EVENT_THREAD:
@@ -194,6 +219,36 @@ void replay_read_events(int opt)
 read_id = replay_get_qword();
 }
 break;
+case REPLAY_ASYNC_EVENT_INPUT:
+e.event_kind = read_event_kind;
+e.opaque = replay_read_input_event();
+
+replay_has_unread_data = 0;
+read_event_kind = -1;
+read_opt = -1;
+
+replay_mutex_unlock();
+replay_run_event(e);
+replay_mutex_lock();
+
+replay_fetch_data_kind();
+/* continue with the next event */
+continue;
+case REPLAY_ASYNC_EVENT_INPUT_SYNC:
+e.event_kind = read_event_kind;
+e.opaque = 0;
+
+replay_has_unread_data = 0;
+read_event_kind = -1;
+read_opt = -1;
+
+replay_mutex_unlock();
+replay_run_event(e);
+replay_mutex_lock();
+
+replay_fetch_data_kind();
+/* continue with the next event */
+continue;
 default:
 fprintf(stderr, Unknown ID %d of replay event\n, 
read_event_kind);
 exit(1);
diff --git a/replay/replay-input.c b/replay/replay-input.c
new file mode 100755
index 000..c1cbcda
--- 

[Qemu-devel] [PATCH 2/3] virtio-pci: use bar0 for non-transitional devices

2015-01-22 Thread Gerd Hoffmann
---
 hw/virtio/virtio-pci.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 407063c..ca325fb 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -966,8 +966,6 @@ static void virtio_pci_add_mem_cap(VirtIOPCIProxy *proxy,
 PCIDevice *dev = proxy-pci_dev;
 int offset;
 
-cap-bar = 2;
-
 offset = pci_add_capability(dev, PCI_CAP_ID_VNDR, 0, cap-cap_len);
 assert(offset  0);
 
@@ -1236,6 +1234,7 @@ static void virtio_pci_device_plugged(DeviceState *d)
 VirtioBusState *bus = proxy-bus;
 bool legacy = !(proxy-flags  VIRTIO_PCI_FLAG_DISABLE_LEGACY);
 bool modern = !(proxy-flags  VIRTIO_PCI_FLAG_DISABLE_MODERN);
+int modern_mem_bar;
 uint8_t *config;
 uint32_t size;
 
@@ -1249,6 +1248,7 @@ static void virtio_pci_device_plugged(DeviceState *d)
 pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
  pci_get_word(config + PCI_VENDOR_ID));
 pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus));
+modern_mem_bar = 2;
 } else {
 /* pure virtio-1.0 */
 pci_set_word(config + PCI_VENDOR_ID,
@@ -1256,6 +1256,7 @@ static void virtio_pci_device_plugged(DeviceState *d)
 pci_set_word(config + PCI_DEVICE_ID,
  0x1040 + virtio_bus_get_vdev_id(bus));
 pci_config_set_revision(config, 1);
+modern_mem_bar = 0;
 }
 config[PCI_INTERRUPT_PIN] = 1;
 
@@ -1264,24 +1265,28 @@ static void virtio_pci_device_plugged(DeviceState *d)
 struct virtio_pci_cap common = {
 .cfg_type = VIRTIO_PCI_CAP_COMMON_CFG,
 .cap_len = sizeof common,
+.bar = modern_mem_bar,
 .offset = cpu_to_le32(0x0),
 .length = cpu_to_le32(0x1000),
 };
 struct virtio_pci_cap isr = {
 .cfg_type = VIRTIO_PCI_CAP_ISR_CFG,
 .cap_len = sizeof isr,
+.bar = modern_mem_bar,
 .offset = cpu_to_le32(0x1000),
 .length = cpu_to_le32(0x1000),
 };
 struct virtio_pci_cap device = {
 .cfg_type = VIRTIO_PCI_CAP_DEVICE_CFG,
 .cap_len = sizeof device,
+.bar = modern_mem_bar,
 .offset = cpu_to_le32(0x2000),
 .length = cpu_to_le32(0x1000),
 };
 struct virtio_pci_notify_cap notify = {
 .cap.cfg_type = VIRTIO_PCI_CAP_NOTIFY_CFG,
 .cap.cap_len = sizeof notify,
+.cap.bar = modern_mem_bar,
 .cap.offset = cpu_to_le32(0x3000),
 .cap.length = cpu_to_le32(QEMU_VIRTIO_PCI_QUEUE_MEM_MULT *
   VIRTIO_PCI_QUEUE_MAX),
@@ -1360,7 +1365,8 @@ static void virtio_pci_device_plugged(DeviceState *d)
   QEMU_VIRTIO_PCI_QUEUE_MEM_MULT *
   VIRTIO_PCI_QUEUE_MAX);
 memory_region_add_subregion(proxy-modern_bar, 0x3000, 
proxy-notify);
-pci_register_bar(proxy-pci_dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY,
+pci_register_bar(proxy-pci_dev, modern_mem_bar,
+ PCI_BASE_ADDRESS_SPACE_MEMORY,
  proxy-modern_bar);
 }
 
-- 
1.8.3.1




[Qemu-devel] [RFC PATCH v8 10/21] replay: asynchronous events infrastructure

2015-01-22 Thread Pavel Dovgalyuk
This patch adds module for saving and replaying asynchronous events.
These events include network packets, keyboard and mouse input,
USB packets, thread pool and bottom halves callbacks.
All events are stored in the queue to be processed at synchronization points
such as beginning of TB execution, or checkpoint in the iothread.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 replay/Makefile.objs |1 
 replay/replay-events.c   |  228 ++
 replay/replay-internal.h |   33 ++-
 replay/replay.h  |4 +
 4 files changed, 265 insertions(+), 1 deletions(-)
 create mode 100755 replay/replay-events.c

diff --git a/replay/Makefile.objs b/replay/Makefile.objs
index 1148f45..56da09c 100755
--- a/replay/Makefile.objs
+++ b/replay/Makefile.objs
@@ -1,2 +1,3 @@
 obj-y += replay.o
 obj-y += replay-internal.o
+obj-y += replay-events.o
diff --git a/replay/replay-events.c b/replay/replay-events.c
new file mode 100755
index 000..dfd5efd
--- /dev/null
+++ b/replay/replay-events.c
@@ -0,0 +1,228 @@
+/*
+ * replay-events.c
+ *
+ * Copyright (c) 2010-2015 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include qemu-common.h
+#include replay.h
+#include replay-internal.h
+
+typedef struct Event {
+ReplayAsyncEventKind event_kind;
+void *opaque;
+void *opaque2;
+uint64_t id;
+
+QTAILQ_ENTRY(Event) events;
+} Event;
+
+static QTAILQ_HEAD(, Event) events_list = QTAILQ_HEAD_INITIALIZER(events_list);
+/* Mutex to protect events_list modifications */
+static QemuMutex lock;
+static unsigned int read_event_kind = -1;
+static uint64_t read_id = -1;
+static int read_opt = -1;
+
+static bool replay_events_enabled = false;
+
+/* Functions */
+
+static void replay_run_event(Event *event)
+{
+switch (event-event_kind) {
+default:
+fprintf(stderr, Replay: invalid async event ID (%d) in the queue\n,
+event-event_kind);
+exit(1);
+break;
+}
+}
+
+void replay_enable_events(void)
+{
+replay_events_enabled = true;
+}
+
+bool replay_has_events(void)
+{
+return !QTAILQ_EMPTY(events_list);
+}
+
+void replay_flush_events(void)
+{
+qemu_mutex_lock(lock);
+while (!QTAILQ_EMPTY(events_list)) {
+Event *event = QTAILQ_FIRST(events_list);
+qemu_mutex_unlock(lock);
+replay_run_event(event);
+qemu_mutex_lock(lock);
+QTAILQ_REMOVE(events_list, event, events);
+g_free(event);
+}
+qemu_mutex_unlock(lock);
+}
+
+void replay_disable_events(void)
+{
+replay_events_enabled = false;
+/* Flush events queue before waiting of completion */
+replay_flush_events();
+}
+
+void replay_clear_events(void)
+{
+qemu_mutex_lock(lock);
+while (!QTAILQ_EMPTY(events_list)) {
+Event *event = QTAILQ_FIRST(events_list);
+QTAILQ_REMOVE(events_list, event, events);
+
+g_free(event);
+}
+qemu_mutex_unlock(lock);
+}
+
+static void replay_add_event_internal(ReplayAsyncEventKind event_kind,
+  void *opaque,
+  void *opaque2, uint64_t id)
+{
+if (event_kind = REPLAY_ASYNC_COUNT) {
+fprintf(stderr, Replay: invalid async event ID (%d)\n, event_kind);
+exit(1);
+}
+if (!replay_file || replay_mode == REPLAY_MODE_NONE
+|| !replay_events_enabled) {
+Event e;
+e.event_kind = event_kind;
+e.opaque = opaque;
+e.opaque2 = opaque2;
+e.id = id;
+replay_run_event(e);
+return;
+}
+
+Event *event = g_malloc0(sizeof(Event));
+event-event_kind = event_kind;
+event-opaque = opaque;
+event-opaque2 = opaque2;
+event-id = id;
+
+qemu_mutex_lock(lock);
+QTAILQ_INSERT_TAIL(events_list, event, events);
+qemu_mutex_unlock(lock);
+}
+
+void replay_add_event(ReplayAsyncEventKind event_kind, void *opaque)
+{
+replay_add_event_internal(event_kind, opaque, NULL, 0);
+}
+
+/* Called with replay mutex locked */
+void replay_save_events(int opt)
+{
+qemu_mutex_lock(lock);
+while (!QTAILQ_EMPTY(events_list)) {
+Event *event = QTAILQ_FIRST(events_list);
+if (replay_mode != REPLAY_MODE_PLAY) {
+/* put the event into the file */
+replay_put_event(EVENT_ASYNC);
+replay_put_byte(opt);
+replay_put_byte(event-event_kind);
+
+/* save event-specific data */
+switch (event-event_kind) {
+}
+}
+
+qemu_mutex_unlock(lock);
+replay_mutex_unlock();
+replay_run_event(event);
+replay_mutex_lock();
+qemu_mutex_lock(lock);
+QTAILQ_REMOVE(events_list, event, events);
+g_free(event);
+}
+

[Qemu-devel] [RFC PATCH v8 18/21] replay: thread pool

2015-01-22 Thread Pavel Dovgalyuk
This patch modifies thread pool to allow replaying asynchronous thread tasks
synchronously in replay mode.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 block/raw-posix.c   |6 -
 block/raw-win32.c   |4 +++-
 include/block/thread-pool.h |4 +++-
 replay/replay-events.c  |   11 ++
 replay/replay-internal.h|1 +
 replay/replay.h |2 ++
 stubs/replay.c  |4 
 tests/test-thread-pool.c|7 --
 thread-pool.c   |   49 ++-
 9 files changed, 66 insertions(+), 22 deletions(-)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index e51293a..f878e06 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1073,7 +1073,9 @@ static BlockAIOCB *paio_submit(BlockDriverState *bs, int 
fd,
 
 trace_paio_submit(acb, opaque, sector_num, nb_sectors, type);
 pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
-return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);
+return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque,
+  qiov ? qiov-replay : false,
+  qiov ? qiov-replay_step : 0);
 }
 
 static BlockAIOCB *raw_aio_submit(BlockDriverState *bs,
@@ -1986,7 +1988,7 @@ static BlockAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
 acb-aio_ioctl_buf = buf;
 acb-aio_ioctl_cmd = req;
 pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
-return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);
+return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque, false, 0);
 }
 
 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
diff --git a/block/raw-win32.c b/block/raw-win32.c
index 06243d7..7ac693b 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -158,7 +158,9 @@ static BlockAIOCB *paio_submit(BlockDriverState *bs, HANDLE 
hfile,
 
 trace_paio_submit(acb, opaque, sector_num, nb_sectors, type);
 pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
-return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);
+return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque,
+  qiov ? qiov-replay : false,
+  qiov ? qiov-replay_step : 0);
 }
 
 int qemu_ftruncate64(int fd, int64_t length)
diff --git a/include/block/thread-pool.h b/include/block/thread-pool.h
index 42eb5e8..801ac00 100644
--- a/include/block/thread-pool.h
+++ b/include/block/thread-pool.h
@@ -29,9 +29,11 @@ void thread_pool_free(ThreadPool *pool);
 
 BlockAIOCB *thread_pool_submit_aio(ThreadPool *pool,
 ThreadPoolFunc *func, void *arg,
-BlockCompletionFunc *cb, void *opaque);
+BlockCompletionFunc *cb, void *opaque,
+bool replay, uint64_t replay_step);
 int coroutine_fn thread_pool_submit_co(ThreadPool *pool,
 ThreadPoolFunc *func, void *arg);
 void thread_pool_submit(ThreadPool *pool, ThreadPoolFunc *func, void *arg);
+void thread_pool_work(ThreadPool *pool, void *r);
 
 #endif
diff --git a/replay/replay-events.c b/replay/replay-events.c
index 7e82b61..f4ec702 100755
--- a/replay/replay-events.c
+++ b/replay/replay-events.c
@@ -12,6 +12,7 @@
 #include qemu-common.h
 #include replay.h
 #include replay-internal.h
+#include block/thread-pool.h
 
 typedef struct Event {
 ReplayAsyncEventKind event_kind;
@@ -39,6 +40,9 @@ static void replay_run_event(Event *event)
 case REPLAY_ASYNC_EVENT_BH:
 aio_bh_call(event-opaque);
 break;
+case REPLAY_ASYNC_EVENT_THREAD:
+thread_pool_work((ThreadPool *)event-opaque, event-opaque2);
+break;
 default:
 fprintf(stderr, Replay: invalid async event ID (%d) in the queue\n,
 event-event_kind);
@@ -130,6 +134,11 @@ void replay_add_bh_event(void *bh, uint64_t id)
 replay_add_event_internal(REPLAY_ASYNC_EVENT_BH, bh, NULL, id);
 }
 
+void replay_add_thread_event(void *opaque, void *opaque2, uint64_t id)
+{
+replay_add_event_internal(REPLAY_ASYNC_EVENT_THREAD, opaque, opaque2, id);
+}
+
 /* Called with replay mutex locked */
 void replay_save_events(int opt)
 {
@@ -145,6 +154,7 @@ void replay_save_events(int opt)
 /* save event-specific data */
 switch (event-event_kind) {
 case REPLAY_ASYNC_EVENT_BH:
+case REPLAY_ASYNC_EVENT_THREAD:
 replay_put_qword(event-id);
 break;
 }
@@ -179,6 +189,7 @@ void replay_read_events(int opt)
 /* Execute some events without searching them in the queue */
 switch (read_event_kind) {
 case REPLAY_ASYNC_EVENT_BH:
+case REPLAY_ASYNC_EVENT_THREAD:
 if (read_id == -1) {
 read_id = replay_get_qword();
 }
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index 0e6ba2a..4d242aa 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h

Re: [Qemu-devel] [PATCH 1/1] edu: fix license information

2015-01-22 Thread Markus Armbruster
Jiri Slaby jsl...@suse.cz writes:

 On 01/22/2015, 10:04 AM, Markus Armbruster wrote:
 Jiri Slaby jsl...@suse.cz writes:
 
 Signed-off-by: Jiri Slaby jsl...@suse.cz
 ---
  docs/specs/edu.txt | 4 
  hw/misc/edu.c  | 2 +-
  2 files changed, 5 insertions(+), 1 deletion(-)

 diff --git a/docs/specs/edu.txt b/docs/specs/edu.txt
 index 360af27ec8b1..1a23df9d21f6 100644
 --- a/docs/specs/edu.txt
 +++ b/docs/specs/edu.txt
 @@ -2,6 +2,10 @@
  EDU device
  ==
  
 +Copyleft (c) 2014-2015 Jiri Slaby
 
 IANAL, but I'm afraid you have to spell this Copyright to carry legal
 weight.

 Not quite as (c) is enough. GPLv2 is a copyleft license.

Quoting https://www.gnu.org/licenses/gpl-howto.en.html:

Always use the English word “Copyright”; by international
convention, this is used worldwide, even for material in other
languages. The copyright symbol “©” can be included if you wish (and
your character set supports it), but it's not necessary. There is no
legal significance to using the three-character sequence “(C)”,
although it does no harm.



Re: [Qemu-devel] [PATCH v2 0/4] initialize progname with error_set_progname()

2015-01-22 Thread Markus Armbruster
Hitoshi Mitake mitake.hito...@lab.ntt.co.jp writes:

 In the context of some subcommands of QEMU, error_get_progname() can
 be used for obtaining argv[0]. The function is useful for the commands
 because it is possible to detect a name of executable file and switch
 behavior based on the function like busybox. e.g. block drivers can
 switch behavior based on the name (qemu itself, qemu-img, or qemu-io).

Changing behavior based on argv[0] is usually a bad idea.

Current use of error_get_progname() is limited to error messages and
such.  That's a good idea.

 But calling error_get_progname() in some commands causes segmentation
 fault because initialization, calling error_set_progname(), isn't
 done. This patchset adds the initialization to the commands which
 lacks it but linked to util/qemu-error.o (one exception is bsd-user, because I
 don't have an environment which can build and test it).

 Currently, the missing call of error_set_progname() doesn't cause any
 problems because the changed commands don't use error_get_progname(). This
 patchset is a proactive action (but sheepdog driver will use it soon).

I'm fine with calling error_set_progname() in all programs linking with
qemu-error.c.

I'm reserving judgement on its use in block drivers.  Please cc me on
that patch.

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



[Qemu-devel] [RFC PATCH v8 11/21] replay: recording and replaying clock ticks

2015-01-22 Thread Pavel Dovgalyuk
Clock ticks are considered as the sources of non-deterministic data for
virtual machine. This patch implements saving the clock values when they
are acquired (virtual, host clock, rdtsc, and some other timers).
When replaying the execution corresponding values are read from log and
transfered to the module, which wants to read the values.
Such a design required the clock polling to be synchronized. Sometimes
it is not true - e.g. when timeouts for timer lists are checked. In this case
we use a cached value of the clock, passing it to the client code.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 cpus.c   |3 +-
 include/qemu/timer.h |   10 +
 qemu-timer.c |7 ++--
 replay/Makefile.objs |1 +
 replay/replay-internal.h |   13 +++
 replay/replay-time.c |   84 ++
 replay/replay.h  |   25 ++
 stubs/replay.c   |9 +
 8 files changed, 147 insertions(+), 5 deletions(-)
 create mode 100755 replay/replay-time.c

diff --git a/cpus.c b/cpus.c
index 8787277..01d89aa 100644
--- a/cpus.c
+++ b/cpus.c
@@ -353,7 +353,8 @@ static void icount_warp_rt(void *opaque)
 
 seqlock_write_lock(timers_state.vm_clock_seqlock);
 if (runstate_is_running()) {
-int64_t clock = cpu_get_clock_locked();
+int64_t clock = REPLAY_CLOCK(REPLAY_CLOCK_VIRTUAL_RT,
+ cpu_get_clock_locked());
 int64_t warp_delta;
 
 warp_delta = clock - vm_clock_warp_start;
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 0666920..0c2472c 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -4,6 +4,7 @@
 #include qemu/typedefs.h
 #include qemu-common.h
 #include qemu/notify.h
+#include replay/replay.h
 
 /* timers */
 
@@ -760,6 +761,8 @@ int64_t cpu_icount_to_ns(int64_t icount);
 /***/
 /* host CPU ticks (if available) */
 
+#define cpu_get_real_ticks cpu_get_real_ticks_impl
+
 #if defined(_ARCH_PPC)
 
 static inline int64_t cpu_get_real_ticks(void)
@@ -913,6 +916,13 @@ static inline int64_t cpu_get_real_ticks (void)
 }
 #endif
 
+#undef cpu_get_real_ticks
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+return REPLAY_CLOCK(REPLAY_CLOCK_REAL_TICKS, cpu_get_real_ticks_impl());
+}
+
 #ifdef CONFIG_PROFILER
 static inline int64_t profile_getclock(void)
 {
diff --git a/qemu-timer.c b/qemu-timer.c
index 98d9d1b..bc981a2 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -25,6 +25,7 @@
 #include sysemu/sysemu.h
 #include monitor/monitor.h
 #include ui/console.h
+#include replay/replay.h
 
 #include hw/hw.h
 
@@ -566,15 +567,15 @@ int64_t qemu_clock_get_ns(QEMUClockType type)
 return cpu_get_clock();
 }
 case QEMU_CLOCK_HOST:
-now = get_clock_realtime();
+now = REPLAY_CLOCK(REPLAY_CLOCK_HOST, get_clock_realtime());
 last = clock-last;
 clock-last = now;
-if (now  last) {
+if (now  last  replay_mode == REPLAY_MODE_NONE) {
 notifier_list_notify(clock-reset_notifiers, now);
 }
 return now;
 case QEMU_CLOCK_VIRTUAL_RT:
-return cpu_get_clock();
+return REPLAY_CLOCK(REPLAY_CLOCK_VIRTUAL_RT, cpu_get_clock());
 }
 }
 
diff --git a/replay/Makefile.objs b/replay/Makefile.objs
index 56da09c..257c320 100755
--- a/replay/Makefile.objs
+++ b/replay/Makefile.objs
@@ -1,3 +1,4 @@
 obj-y += replay.o
 obj-y += replay-internal.o
 obj-y += replay-events.o
+obj-y += replay-time.o
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index 1666d6e..e906ec3 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -22,7 +22,10 @@ enum ReplayEvents {
 /* for emulated exceptions */
 EVENT_EXCEPTION,
 /* for async events */
-EVENT_ASYNC
+EVENT_ASYNC,
+/* for clock read/writes */
+/* some of grteater codes are reserved for clocks */
+EVENT_CLOCK
 };
 
 /* Asynchronous events IDs */
@@ -34,6 +37,8 @@ enum ReplayAsyncEventKind {
 typedef enum ReplayAsyncEventKind ReplayAsyncEventKind;
 
 typedef struct ReplayState {
+/*! Cached clock values. */
+int64_t cached_clock[REPLAY_CLOCK_COUNT];
 /*! Current step - number of processed instructions and timer events. */
 uint64_t current_step;
 /*! Number of instructions to be executed before other events happen. */
@@ -88,6 +93,12 @@ bool skip_async_events(int stop_event);
 reports an error and stops the execution. */
 void skip_async_events_until(unsigned int kind);
 
+/*! Reads next clock value from the file.
+If clock kind read from the file is different from the parameter,
+the value is not used.
+If the parameter is -1, the clock value is read to the cache anyway. */
+void replay_read_next_clock(unsigned int kind);
+
 /* Asynchronous events queue */
 
 /*! Initializes events' processing internals */
diff --git a/replay/replay-time.c 

[Qemu-devel] [RFC PATCH v8 06/21] replay: introduce icount event

2015-01-22 Thread Pavel Dovgalyuk
This patch adds icount event to the replay subsystem. This event corresponds
to execution of several instructions and used to synchronize input events
in the replay phase.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 replay/replay-internal.c |   16 
 replay/replay-internal.h |   20 
 replay/replay.c  |   46 ++
 replay/replay.h  |7 +++
 4 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/replay/replay-internal.c b/replay/replay-internal.c
index f552dad..49b37a6 100755
--- a/replay/replay-internal.c
+++ b/replay/replay-internal.c
@@ -10,6 +10,7 @@
  */
 
 #include qemu-common.h
+#include replay.h
 #include replay-internal.h
 
 unsigned int replay_data_kind = -1;
@@ -164,3 +165,18 @@ void replay_mutex_unlock(void)
 {
 qemu_mutex_unlock(lock);
 }
+
+/*! Saves cached instructions. */
+void replay_save_instructions(void)
+{
+if (replay_file  replay_mode == REPLAY_MODE_RECORD) {
+int diff = (int)(replay_get_current_step() - 
replay_state.current_step);
+if (first_cpu != NULL  diff  0) {
+replay_mutex_lock();
+replay_put_event(EVENT_INSTRUCTION);
+replay_put_dword(diff);
+replay_state.current_step += diff;
+replay_mutex_unlock();
+}
+}
+}
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index 50ce29b..4d661a1 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -14,6 +14,19 @@
 
 #include stdio.h
 
+enum ReplayEvents {
+/* for instruction event */
+EVENT_INSTRUCTION
+};
+
+typedef struct ReplayState {
+/*! Current step - number of processed instructions and timer events. */
+uint64_t current_step;
+/*! Number of instructions to be executed before other events happen. */
+int instructions_count;
+} ReplayState;
+extern ReplayState replay_state;
+
 extern unsigned int replay_data_kind;
 extern unsigned int replay_has_unread_data;
 
@@ -54,4 +67,11 @@ void replay_save_instructions(void);
 Terminates the program in case of error. */
 void validate_data_kind(int kind);
 
+/*! Skips async events until some sync event will be found. */
+bool skip_async_events(int stop_event);
+/*! Skips async events invocations from the input,
+until required data kind is found. If the requested data is not found
+reports an error and stops the execution. */
+void skip_async_events_until(unsigned int kind);
+
 #endif
diff --git a/replay/replay.c b/replay/replay.c
index 5ce066f..a43bbbc 100755
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -9,6 +9,52 @@
  *
  */
 
+#include qemu-common.h
 #include replay.h
+#include replay-internal.h
+#include qemu/timer.h
 
 ReplayMode replay_mode = REPLAY_MODE_NONE;
+
+ReplayState replay_state;
+
+bool skip_async_events(int stop_event)
+{
+bool res = false;
+
+/* nothing to skip - not all instructions used */
+if (replay_state.instructions_count != 0
+ replay_has_unread_data) {
+return stop_event == EVENT_INSTRUCTION;
+}
+
+while (true) {
+replay_fetch_data_kind();
+if (stop_event == replay_data_kind) {
+res = true;
+}
+switch (replay_data_kind) {
+case EVENT_INSTRUCTION:
+replay_state.instructions_count = replay_get_dword();
+return res;
+default:
+/* clock, time_t, checkpoint and other events */
+return res;
+}
+}
+return res;
+}
+
+void skip_async_events_until(unsigned int kind)
+{
+if (!skip_async_events(kind)) {
+fprintf(stderr, %PRId64: Read data kind %d instead of expected 
%d\n,
+replay_get_current_step(), replay_data_kind, kind);
+exit(1);
+}
+}
+
+uint64_t replay_get_current_step(void)
+{
+return cpu_get_icount_raw();
+}
diff --git a/replay/replay.h b/replay/replay.h
index d6b73c3..a03c748 100755
--- a/replay/replay.h
+++ b/replay/replay.h
@@ -12,8 +12,15 @@
  *
  */
 
+#include stdbool.h
+#include stdint.h
 #include qapi-types.h
 
 extern ReplayMode replay_mode;
 
+/* Processing the instructions */
+
+/*! Returns number of executed instructions. */
+uint64_t replay_get_current_step(void);
+
 #endif




[Qemu-devel] [RFC PATCH v8 03/21] sysemu: system functions for replay

2015-01-22 Thread Pavel Dovgalyuk
This patch removes static specifier from several qemu function to make
them visible to the replay module. It also invents several system functions
that will be used by replay.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 cpus.c  |4 ++--
 include/exec/exec-all.h |1 +
 include/qom/cpu.h   |   10 ++
 include/sysemu/cpus.h   |1 +
 translate-all.c |8 
 5 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/cpus.c b/cpus.c
index 3a5323b..c513275 100644
--- a/cpus.c
+++ b/cpus.c
@@ -88,7 +88,7 @@ static bool cpu_thread_is_idle(CPUState *cpu)
 return true;
 }
 
-static bool all_cpu_threads_idle(void)
+bool all_cpu_threads_idle(void)
 {
 CPUState *cpu;
 
@@ -1121,7 +1121,7 @@ bool qemu_cpu_is_self(CPUState *cpu)
 return qemu_thread_is_self(cpu-thread);
 }
 
-static bool qemu_in_vcpu_thread(void)
+bool qemu_in_vcpu_thread(void)
 {
 return current_cpu  qemu_cpu_is_self(current_cpu);
 }
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 4a6237f..63fb1a3 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -214,6 +214,7 @@ static inline unsigned int tb_phys_hash_func(tb_page_addr_t 
pc)
 
 void tb_free(TranslationBlock *tb);
 void tb_flush(CPUArchState *env);
+void tb_flush_all(void);
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
 
 #if defined(USE_DIRECT_JUMP)
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 2098f1c..5afb44c 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -480,6 +480,16 @@ static inline bool cpu_has_work(CPUState *cpu)
 bool qemu_cpu_is_self(CPUState *cpu);
 
 /**
+ * qemu_in_vcpu_thread:
+ *
+ * Checks whether the caller is executing on the vCPU thread
+ * of the current vCPU.
+ *
+ * Returns: %true if called from vCPU's thread, %false otherwise.
+ */
+bool qemu_in_vcpu_thread(void);
+
+/**
  * qemu_cpu_kick:
  * @cpu: The vCPU to kick.
  *
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index 3f162a9..86ae556 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -6,6 +6,7 @@ void qemu_init_cpu_loop(void);
 void resume_all_vcpus(void);
 void pause_all_vcpus(void);
 void cpu_stop_current(void);
+bool all_cpu_threads_idle(void);
 
 void cpu_synchronize_all_states(void);
 void cpu_synchronize_all_post_reset(void);
diff --git a/translate-all.c b/translate-all.c
index 4a1b64f..c0cba7d 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -812,6 +812,14 @@ void tb_flush(CPUArchState *env1)
 tcg_ctx.tb_ctx.tb_flush_count++;
 }
 
+void tb_flush_all(void)
+{
+CPUState *cpu;
+for (cpu = first_cpu ; cpu != NULL ; cpu = CPU_NEXT(cpu)) {
+tb_flush(cpu-env_ptr);
+}
+}
+
 #ifdef DEBUG_TB_CHECK
 
 static void tb_invalidate_check(target_ulong address)




[Qemu-devel] [RFC PATCH v8 05/21] replay: introduce mutex to protect the replay log

2015-01-22 Thread Pavel Dovgalyuk
This mutex will protect read/write operations for replay log.
Using mutex is necessary because most of the events consist of
several fields stored in the log. The mutex will help to avoid races.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 replay/replay-internal.c |   25 +
 replay/replay-internal.h |7 +++
 2 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/replay/replay-internal.c b/replay/replay-internal.c
index 3865fa5..f552dad 100755
--- a/replay/replay-internal.c
+++ b/replay/replay-internal.c
@@ -15,6 +15,11 @@
 unsigned int replay_data_kind = -1;
 unsigned int replay_has_unread_data;
 
+/* Mutex to protect reading and writing events to the log.
+   replay_data_kind and replay_has_unread_data are also protected
+   by this mutex. */
+static QemuMutex lock;
+
 /* File for replay writing */
 FILE *replay_file;
 
@@ -139,3 +144,23 @@ void replay_fetch_data_kind(void)
 }
 }
 }
+
+void replay_mutex_init(void)
+{
+qemu_mutex_init(lock);
+}
+
+void replay_mutex_destroy(void)
+{
+qemu_mutex_destroy(lock);
+}
+
+void replay_mutex_lock(void)
+{
+qemu_mutex_lock(lock);
+}
+
+void replay_mutex_unlock(void)
+{
+qemu_mutex_unlock(lock);
+}
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index dad5bc8..50ce29b 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -34,6 +34,13 @@ int64_t replay_get_qword(void);
 void replay_get_array(uint8_t *buf, size_t *size);
 void replay_get_array_alloc(uint8_t **buf, size_t *size);
 
+/* Mutex functions for protecting replay log file */
+
+void replay_mutex_init(void);
+void replay_mutex_destroy(void);
+void replay_mutex_lock(void);
+void replay_mutex_unlock(void);
+
 /*! Checks error status of the file. */
 void replay_check_error(void);
 




[Qemu-devel] [RFC PATCH v8 12/21] replay: recording and replaying different timers

2015-01-22 Thread Pavel Dovgalyuk
This patch introduces functions for recording and replaying realtime sources,
that do not use qemu-clock interface. These include return value of time()
function in time_t and struct tm forms. Patch also adds warning to
get_timedate function to prevent its usage in recording mode, because it may
lead to non-determinism.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 hw/timer/mc146818rtc.c   |3 +
 hw/timer/pl031.c |3 +
 include/qemu-common.h|1 
 replay/replay-internal.h |4 +
 replay/replay-time.c |  132 ++
 replay/replay.h  |8 +++
 vl.c |   17 +-
 7 files changed, 163 insertions(+), 5 deletions(-)

diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index f18d128..92295fb 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -28,6 +28,7 @@
 #include qapi/visitor.h
 #include qapi-event.h
 #include qmp-commands.h
+#include replay/replay.h
 
 #ifdef TARGET_I386
 #include hw/i386/apic.h
@@ -703,7 +704,7 @@ static void rtc_set_date_from_host(ISADevice *dev)
 RTCState *s = MC146818_RTC(dev);
 struct tm tm;
 
-qemu_get_timedate(tm, 0);
+replay_get_timedate(tm);
 
 s-base_rtc = mktimegm(tm);
 s-last_update = qemu_clock_get_ns(rtc_clock);
diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c
index 34d9b44..b02d288 100644
--- a/hw/timer/pl031.c
+++ b/hw/timer/pl031.c
@@ -14,6 +14,7 @@
 #include hw/sysbus.h
 #include qemu/timer.h
 #include sysemu/sysemu.h
+#include replay/replay.h
 
 //#define DEBUG_PL031
 
@@ -200,7 +201,7 @@ static int pl031_init(SysBusDevice *dev)
 sysbus_init_mmio(dev, s-iomem);
 
 sysbus_init_irq(dev, s-irq);
-qemu_get_timedate(tm, 0);
+replay_get_timedate(tm);
 s-tick_offset = mktimegm(tm) -
 qemu_clock_get_ns(rtc_clock) / get_ticks_per_sec();
 
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 644b46d..8c9957e 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -129,6 +129,7 @@ void dump_drift_info(FILE *f, fprintf_function cpu_fprintf);
 int qemu_main(int argc, char **argv, char **envp);
 #endif
 
+void qemu_get_timedate_no_warning(struct tm *tm, int offset);
 void qemu_get_timedate(struct tm *tm, int offset);
 int qemu_timedate_diff(struct tm *tm);
 
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index e906ec3..be71e6f 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -23,6 +23,10 @@ enum ReplayEvents {
 EVENT_EXCEPTION,
 /* for async events */
 EVENT_ASYNC,
+/* for time_t event */
+EVENT_TIME_T,
+/* for tm event */
+EVENT_TM,
 /* for clock read/writes */
 /* some of grteater codes are reserved for clocks */
 EVENT_CLOCK
diff --git a/replay/replay-time.c b/replay/replay-time.c
index 5f5bc6a..282d00e 100755
--- a/replay/replay-time.c
+++ b/replay/replay-time.c
@@ -82,3 +82,135 @@ int64_t replay_read_clock(ReplayClockKind kind)
 fprintf(stderr, REPLAY INTERNAL ERROR %d\n, __LINE__);
 exit(1);
 }
+
+/*! Saves time_t value to the log */
+static void replay_save_time_t(time_t tm)
+{
+replay_save_instructions();
+
+if (replay_file) {
+replay_mutex_lock();
+replay_put_event(EVENT_TIME_T);
+if (sizeof(tm) == 4) {
+replay_put_dword(tm);
+} else if (sizeof(tm) == 8) {
+replay_put_qword(tm);
+} else {
+fprintf(stderr, invalid time_t sizeof: %u\n,
+(unsigned)sizeof(tm));
+exit(1);
+}
+replay_mutex_unlock();
+}
+}
+
+/*! Reads time_t value from the log. Stops execution in case of error */
+static time_t replay_read_time_t(void)
+{
+replay_exec_instructions();
+
+if (replay_file) {
+time_t tm;
+
+replay_mutex_lock();
+skip_async_events_until(EVENT_TIME_T);
+
+if (sizeof(tm) == 4) {
+tm = replay_get_dword();
+} else if (sizeof(tm) == 8) {
+tm = replay_get_qword();
+} else {
+fprintf(stderr, invalid time_t sizeof: %u\n,
+(unsigned)sizeof(tm));
+exit(1);
+}
+
+replay_check_error();
+
+replay_has_unread_data = 0;
+replay_mutex_unlock();
+
+return tm;
+}
+
+fprintf(stderr, REPLAY INTERNAL ERROR %d\n, __LINE__);
+exit(1);
+}
+
+static void replay_save_tm(struct tm *tm)
+{
+replay_save_instructions();
+
+if (replay_file) {
+replay_mutex_lock();
+replay_put_event(EVENT_TM);
+
+replay_put_dword(tm-tm_sec);
+replay_put_dword(tm-tm_min);
+replay_put_dword(tm-tm_hour);
+replay_put_dword(tm-tm_mday);
+replay_put_dword(tm-tm_mon);
+replay_put_dword(tm-tm_year);
+replay_put_dword(tm-tm_wday);
+replay_put_dword(tm-tm_yday);
+replay_put_dword(tm-tm_isdst);
+replay_mutex_unlock();
+}
+}
+
+static void 

[Qemu-devel] [RFC PATCH v8 13/21] replay: shutdown event

2015-01-22 Thread Pavel Dovgalyuk
This patch records and replays simulator shutdown event.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 replay/replay-internal.h |2 ++
 replay/replay.c  |   12 
 replay/replay.h  |5 +
 vl.c |1 +
 4 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index be71e6f..68b2d45 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -27,6 +27,8 @@ enum ReplayEvents {
 EVENT_TIME_T,
 /* for tm event */
 EVENT_TM,
+/* for shutdown request */
+EVENT_SHUTDOWN,
 /* for clock read/writes */
 /* some of grteater codes are reserved for clocks */
 EVENT_CLOCK
diff --git a/replay/replay.c b/replay/replay.c
index 307ac4b..cfa69fa 100755
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -13,6 +13,7 @@
 #include replay.h
 #include replay-internal.h
 #include qemu/timer.h
+#include sysemu/sysemu.h
 
 ReplayMode replay_mode = REPLAY_MODE_NONE;
 
@@ -34,6 +35,10 @@ bool skip_async_events(int stop_event)
 res = true;
 }
 switch (replay_data_kind) {
+case EVENT_SHUTDOWN:
+replay_has_unread_data = 0;
+qemu_system_shutdown_request();
+break;
 case EVENT_INSTRUCTION:
 replay_state.instructions_count = replay_get_dword();
 return res;
@@ -151,3 +156,10 @@ bool replay_has_interrupt(void)
 }
 return res;
 }
+
+void replay_shutdown_request(void)
+{
+if (replay_mode == REPLAY_MODE_RECORD) {
+replay_put_event(EVENT_SHUTDOWN);
+}
+}
diff --git a/replay/replay.h b/replay/replay.h
index 2f1402c..e1c5fcf 100755
--- a/replay/replay.h
+++ b/replay/replay.h
@@ -76,6 +76,11 @@ time_t replay_time(void);
 In replay mode it just read from the log. */
 void replay_get_timedate(struct tm *tm);
 
+/* Events */
+
+/*! Called when qemu shutdown is requested. */
+void replay_shutdown_request(void);
+
 /* Asynchronous events queue */
 
 /*! Disables storing events in the queue */
diff --git a/vl.c b/vl.c
index baff3b5..905ea8a 100644
--- a/vl.c
+++ b/vl.c
@@ -1720,6 +1720,7 @@ void qemu_system_killed(int signal, pid_t pid)
 void qemu_system_shutdown_request(void)
 {
 trace_qemu_system_shutdown_request();
+replay_shutdown_request();
 shutdown_requested = 1;
 qemu_notify_event();
 }




[Qemu-devel] [RFC PATCH v8 04/21] replay: internal functions for replay log

2015-01-22 Thread Pavel Dovgalyuk
This patch adds functions to perform read and write operations
with replay log.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 replay/Makefile.objs |1 
 replay/replay-internal.c |  141 ++
 replay/replay-internal.h |   50 
 3 files changed, 192 insertions(+), 0 deletions(-)
 create mode 100755 replay/replay-internal.c
 create mode 100755 replay/replay-internal.h

diff --git a/replay/Makefile.objs b/replay/Makefile.objs
index 7ea860f..1148f45 100755
--- a/replay/Makefile.objs
+++ b/replay/Makefile.objs
@@ -1 +1,2 @@
 obj-y += replay.o
+obj-y += replay-internal.o
diff --git a/replay/replay-internal.c b/replay/replay-internal.c
new file mode 100755
index 000..3865fa5
--- /dev/null
+++ b/replay/replay-internal.c
@@ -0,0 +1,141 @@
+/*
+ * replay-internal.c
+ *
+ * Copyright (c) 2010-2015 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include qemu-common.h
+#include replay-internal.h
+
+unsigned int replay_data_kind = -1;
+unsigned int replay_has_unread_data;
+
+/* File for replay writing */
+FILE *replay_file;
+
+void replay_put_byte(uint8_t byte)
+{
+if (replay_file) {
+fwrite(byte, sizeof(byte), 1, replay_file);
+}
+}
+
+void replay_put_event(uint8_t event)
+{
+replay_put_byte(event);
+}
+
+
+void replay_put_word(uint16_t word)
+{
+if (replay_file) {
+fwrite(word, sizeof(word), 1, replay_file);
+}
+}
+
+void replay_put_dword(uint32_t dword)
+{
+if (replay_file) {
+fwrite(dword, sizeof(dword), 1, replay_file);
+}
+}
+
+void replay_put_qword(int64_t qword)
+{
+if (replay_file) {
+fwrite(qword, sizeof(qword), 1, replay_file);
+}
+}
+
+void replay_put_array(const uint8_t *buf, size_t size)
+{
+if (replay_file) {
+fwrite(size, sizeof(size), 1, replay_file);
+fwrite(buf, 1, size, replay_file);
+}
+}
+
+uint8_t replay_get_byte(void)
+{
+uint8_t byte;
+if (replay_file) {
+fread(byte, sizeof(byte), 1, replay_file);
+}
+return byte;
+}
+
+uint16_t replay_get_word(void)
+{
+uint16_t word;
+if (replay_file) {
+fread(word, sizeof(word), 1, replay_file);
+}
+
+return word;
+}
+
+uint32_t replay_get_dword(void)
+{
+uint32_t dword;
+if (replay_file) {
+fread(dword, sizeof(dword), 1, replay_file);
+}
+
+return dword;
+}
+
+int64_t replay_get_qword(void)
+{
+int64_t qword;
+if (replay_file) {
+fread(qword, sizeof(qword), 1, replay_file);
+}
+
+return qword;
+}
+
+void replay_get_array(uint8_t *buf, size_t *size)
+{
+if (replay_file) {
+fread(size, sizeof(*size), 1, replay_file);
+fread(buf, 1, *size, replay_file);
+}
+}
+
+void replay_get_array_alloc(uint8_t **buf, size_t *size)
+{
+if (replay_file) {
+fread(size, sizeof(*size), 1, replay_file);
+*buf = g_malloc(*size);
+fread(*buf, 1, *size, replay_file);
+}
+}
+
+void replay_check_error(void)
+{
+if (replay_file) {
+if (feof(replay_file)) {
+fprintf(stderr, replay file is over\n);
+exit(1);
+} else if (ferror(replay_file)) {
+fprintf(stderr, replay file is over or something goes wrong\n);
+exit(1);
+}
+}
+}
+
+void replay_fetch_data_kind(void)
+{
+if (replay_file) {
+if (!replay_has_unread_data) {
+replay_data_kind = replay_get_byte();
+replay_check_error();
+replay_has_unread_data = 1;
+}
+}
+}
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
new file mode 100755
index 000..dad5bc8
--- /dev/null
+++ b/replay/replay-internal.h
@@ -0,0 +1,50 @@
+#ifndef REPLAY_INTERNAL_H
+#define REPLAY_INTERNAL_H
+
+/*
+ * replay-internal.h
+ *
+ * Copyright (c) 2010-2015 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include stdio.h
+
+extern unsigned int replay_data_kind;
+extern unsigned int replay_has_unread_data;
+
+/* File for replay writing */
+extern FILE *replay_file;
+
+void replay_put_byte(uint8_t byte);
+void replay_put_event(uint8_t event);
+void replay_put_word(uint16_t word);
+void replay_put_dword(uint32_t dword);
+void replay_put_qword(int64_t qword);
+void replay_put_array(const uint8_t *buf, size_t size);
+
+uint8_t replay_get_byte(void);
+uint16_t replay_get_word(void);
+uint32_t replay_get_dword(void);
+int64_t replay_get_qword(void);
+void replay_get_array(uint8_t *buf, size_t *size);
+void replay_get_array_alloc(uint8_t **buf, size_t *size);
+
+/*! Checks error status of the file. */
+void 

[Qemu-devel] [PATCH 1/3] virtio-pci: add flags to enable/disable legacy/modern

2015-01-22 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/virtio/virtio-pci.c | 46 +-
 hw/virtio/virtio-pci.h |  6 ++
 2 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index a6ce3fe..407063c 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1234,6 +1234,8 @@ static void virtio_pci_device_plugged(DeviceState *d)
 {
 VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
 VirtioBusState *bus = proxy-bus;
+bool legacy = !(proxy-flags  VIRTIO_PCI_FLAG_DISABLE_LEGACY);
+bool modern = !(proxy-flags  VIRTIO_PCI_FLAG_DISABLE_MODERN);
 uint8_t *config;
 uint32_t size;
 
@@ -1241,13 +1243,24 @@ static void virtio_pci_device_plugged(DeviceState *d)
 if (proxy-class_code) {
 pci_config_set_class(config, proxy-class_code);
 }
-pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
- pci_get_word(config + PCI_VENDOR_ID));
-pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus));
+
+if (legacy) {
+/* legacy and transitional */
+pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
+ pci_get_word(config + PCI_VENDOR_ID));
+pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus));
+} else {
+/* pure virtio-1.0 */
+pci_set_word(config + PCI_VENDOR_ID,
+ PCI_VENDOR_ID_REDHAT_QUMRANET);
+pci_set_word(config + PCI_DEVICE_ID,
+ 0x1040 + virtio_bus_get_vdev_id(bus));
+pci_config_set_revision(config, 1);
+}
 config[PCI_INTERRUPT_PIN] = 1;
 
 
-if (1) { /* TODO: Make this optional, dependent on virtio 1.0 */
+if (modern) {
 struct virtio_pci_cap common = {
 .cfg_type = VIRTIO_PCI_CAP_COMMON_CFG,
 .cap_len = sizeof common,
@@ -1360,17 +1373,20 @@ static void virtio_pci_device_plugged(DeviceState *d)
 
 proxy-pci_dev.config_write = virtio_write_config;
 
-size = VIRTIO_PCI_REGION_SIZE(proxy-pci_dev)
- + virtio_bus_get_vdev_config_len(bus);
-if (size  (size - 1)) {
-size = 1  qemu_fls(size);
-}
+if (legacy) {
+size = VIRTIO_PCI_REGION_SIZE(proxy-pci_dev)
++ virtio_bus_get_vdev_config_len(bus);
+if (size  (size - 1)) {
+size = 1  qemu_fls(size);
+}
 
-memory_region_init_io(proxy-bar, OBJECT(proxy), virtio_pci_config_ops,
-  proxy, virtio-pci, size);
+memory_region_init_io(proxy-bar, OBJECT(proxy),
+  virtio_pci_config_ops,
+  proxy, virtio-pci, size);
 
-pci_register_bar(proxy-pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
- proxy-bar);
+pci_register_bar(proxy-pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
+ proxy-bar);
+}
 
 if (!kvm_has_many_ioeventfds()) {
 proxy-flags = ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
@@ -1417,6 +1433,10 @@ static void virtio_pci_reset(DeviceState *qdev)
 static Property virtio_pci_properties[] = {
 DEFINE_PROP_BIT(virtio-pci-bus-master-bug-migration, VirtIOPCIProxy, 
flags,
 VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT, false),
+DEFINE_PROP_BIT(disable-legacy, VirtIOPCIProxy, flags,
+VIRTIO_PCI_FLAG_DISABLE_LEGACY_BIT, false),
+DEFINE_PROP_BIT(disable-modern, VirtIOPCIProxy, flags,
+VIRTIO_PCI_FLAG_DISABLE_MODERN_BIT, false),
 DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
 DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 271a73a..938eeff 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -68,6 +68,12 @@ typedef struct VirtioBusClass VirtioPCIBusClass;
 #define VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT 1
 #define VIRTIO_PCI_FLAG_USE_IOEVENTFD   (1  
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT)
 
+/* virtio version flags */
+#define VIRTIO_PCI_FLAG_DISABLE_LEGACY_BIT 2
+#define VIRTIO_PCI_FLAG_DISABLE_MODERN_BIT 3
+#define VIRTIO_PCI_FLAG_DISABLE_LEGACY (1  
VIRTIO_PCI_FLAG_DISABLE_LEGACY_BIT)
+#define VIRTIO_PCI_FLAG_DISABLE_MODERN (1  
VIRTIO_PCI_FLAG_DISABLE_MODERN_BIT)
+
 typedef struct {
 MSIMessage msg;
 int virq;
-- 
1.8.3.1




[Qemu-devel] [RFC PATCH v8 09/21] replay: interrupts and exceptions

2015-01-22 Thread Pavel Dovgalyuk
This patch includes modifications of common cpu files. All interrupts and
exceptions occured during recording are written into the replay log.
These events allow correct replaying the execution by kicking cpu thread
when one of these events is found in the log.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 cpu-exec.c   |   48 +---
 replay/replay-internal.h |6 +++-
 replay/replay.c  |   69 ++
 replay/replay.h  |   17 +++
 target-i386/seg_helper.c |4 +++
 5 files changed, 132 insertions(+), 12 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 99a0993..16d1faa 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -24,6 +24,7 @@
 #include qemu/atomic.h
 #include sysemu/qtest.h
 #include qemu/timer.h
+#include replay/replay.h
 
 /* -icount align implementation. */
 
@@ -338,22 +339,25 @@ int cpu_exec(CPUArchState *env)
 /* This must be volatile so it is not trashed by longjmp() */
 volatile bool have_tb_lock = false;
 
+/* replay_interrupt may need current_cpu */
+current_cpu = cpu;
+
 if (cpu-halted) {
 #ifdef TARGET_I386
-if (cpu-interrupt_request  CPU_INTERRUPT_POLL) {
+if ((cpu-interrupt_request  CPU_INTERRUPT_POLL)
+ replay_interrupt()) {
 apic_poll_irq(x86_cpu-apic_state);
 cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
 }
 #endif
 if (!cpu_has_work(cpu)) {
+current_cpu = NULL;
 return EXCP_HALTED;
 }
 
 cpu-halted = 0;
 }
 
-current_cpu = cpu;
-
 /* As long as current_cpu is null, up to the assignment just above,
  * requests by other threads to exit the execution loop are expected to
  * be issued using the exit_request global. We must make sure that our
@@ -400,10 +404,21 @@ int cpu_exec(CPUArchState *env)
 cpu-exception_index = -1;
 break;
 #else
-cc-do_interrupt(cpu);
-cpu-exception_index = -1;
+if (replay_exception()) {
+cc-do_interrupt(cpu);
+cpu-exception_index = -1;
+} else if (!replay_has_interrupt()) {
+/* give a chance to iothread in replay mode */
+ret = EXCP_INTERRUPT;
+break;
+}
 #endif
 }
+} else if (replay_has_exception()
+cpu-icount_decr.u16.low + cpu-icount_extra == 0) {
+/* try to cause an exception pending in the log */
+cpu_exec_nocache(env, 1, tb_find_fast(env), true);
+break;
 }
 
 next_tb = 0; /* force lookup of first TB */
@@ -419,30 +434,40 @@ int cpu_exec(CPUArchState *env)
 cpu-exception_index = EXCP_DEBUG;
 cpu_loop_exit(cpu);
 }
-if (interrupt_request  CPU_INTERRUPT_HALT) {
+if (replay_mode == REPLAY_MODE_PLAY
+ !replay_has_interrupt()) {
+/* Do nothing */
+} else if (interrupt_request  CPU_INTERRUPT_HALT) {
+replay_interrupt();
 cpu-interrupt_request = ~CPU_INTERRUPT_HALT;
 cpu-halted = 1;
 cpu-exception_index = EXCP_HLT;
 cpu_loop_exit(cpu);
 }
 #if defined(TARGET_I386)
-if (interrupt_request  CPU_INTERRUPT_INIT) {
+else if (interrupt_request  CPU_INTERRUPT_INIT) {
+replay_interrupt();
 cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0);
 do_cpu_init(x86_cpu);
 cpu-exception_index = EXCP_HALTED;
 cpu_loop_exit(cpu);
 }
 #else
-if (interrupt_request  CPU_INTERRUPT_RESET) {
+else if (interrupt_request  CPU_INTERRUPT_RESET) {
+replay_interrupt();
 cpu_reset(cpu);
+cpu_loop_exit(cpu);
 }
 #endif
 /* The target hook has 3 exit conditions:
False when the interrupt isn't processed,
True when it is, and we should restart on a new TB,
and via longjmp via cpu_loop_exit.  */
-if (cc-cpu_exec_interrupt(cpu, interrupt_request)) {
-next_tb = 0;
+else {
+replay_interrupt();
+if (cc-cpu_exec_interrupt(cpu, interrupt_request)) {
+next_tb = 0;
+}
 }
 

[Qemu-devel] [PATCH 3/3] virtio-pci: make QEMU_VIRTIO_PCI_QUEUE_MEM_MULT smaller

2015-01-22 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/virtio/virtio-pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index ca325fb..01f8bb7 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -974,7 +974,7 @@ static void virtio_pci_add_mem_cap(VirtIOPCIProxy *proxy,
cap-cap_len - PCI_CAP_FLAGS);
 }
 
-#define QEMU_VIRTIO_PCI_QUEUE_MEM_MULT 0x1
+#define QEMU_VIRTIO_PCI_QUEUE_MEM_MULT 0x1000
 
 static uint64_t virtio_pci_common_read(void *opaque, hwaddr addr,
unsigned size)
-- 
1.8.3.1




[Qemu-devel] [RFC PATCH v8 14/21] replay: checkpoints

2015-01-22 Thread Pavel Dovgalyuk
This patch introduces checkpoints that synchronize cpu thread and iothread.
When checkpoint is met in the code all asynchronous events from the queue
are executed.

Signed-off-by: Pavel Dovgalyuk pavel.dovga...@ispras.ru
---
 block.c  |   11 ++
 cpus.c   |7 ++-
 include/qemu/timer.h |6 --
 main-loop.c  |5 +
 qemu-timer.c |   49 ++
 replay/replay-internal.h |5 -
 replay/replay.c  |   36 ++
 replay/replay.h  |   21 
 stubs/replay.c   |   11 ++
 vl.c |4 +++-
 10 files changed, 142 insertions(+), 13 deletions(-)

diff --git a/block.c b/block.c
index cbe4a32..a4f45c3 100644
--- a/block.c
+++ b/block.c
@@ -1994,6 +1994,11 @@ void bdrv_drain_all(void)
 BlockDriverState *bs;
 
 while (busy) {
+if (!replay_checkpoint(CHECKPOINT_BDRV_DRAIN)) {
+/* Do not wait anymore, we stopped at some place in
+   the middle of execution during replay */
+return;
+}
 busy = false;
 
 QTAILQ_FOREACH(bs, bdrv_states, device_list) {
@@ -2004,6 +2009,12 @@ void bdrv_drain_all(void)
 aio_context_release(aio_context);
 }
 }
+if (replay_mode == REPLAY_MODE_PLAY) {
+/* Skip checkpoints from the log */
+while (replay_checkpoint(CHECKPOINT_BDRV_DRAIN)) {
+/* Nothing */
+}
+}
 }
 
 /* make a BlockDriverState anonymous by removing from bdrv_state and
diff --git a/cpus.c b/cpus.c
index 01d89aa..9c32491 100644
--- a/cpus.c
+++ b/cpus.c
@@ -388,7 +388,7 @@ void qtest_clock_warp(int64_t dest)
 timers_state.qemu_icount_bias += warp;
 seqlock_write_unlock(timers_state.vm_clock_seqlock);
 
-qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
+qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL, false);
 clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 }
 qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
@@ -408,6 +408,11 @@ void qemu_clock_warp(QEMUClockType type)
 return;
 }
 
+/* warp clock deterministically in record/replay mode */
+if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP)) {
+return;
+}
+
 /*
  * If the CPUs have been sleeping, advance QEMU_CLOCK_VIRTUAL timer now.
  * This ensures that the deadline for the timer is computed correctly 
below.
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 0c2472c..26927b0 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -240,13 +240,14 @@ void qemu_clock_unregister_reset_notifier(QEMUClockType 
type,
 /**
  * qemu_clock_run_timers:
  * @type: clock on which to operate
+ * @run_all: true, when called from qemu_clock_run_all_timers
  *
  * Run all the timers associated with the default timer list
  * of a clock.
  *
  * Returns: true if any timer ran.
  */
-bool qemu_clock_run_timers(QEMUClockType type);
+bool qemu_clock_run_timers(QEMUClockType type, bool run_all);
 
 /**
  * qemu_clock_run_all_timers:
@@ -337,12 +338,13 @@ QEMUClockType timerlist_get_clock(QEMUTimerList 
*timer_list);
 /**
  * timerlist_run_timers:
  * @timer_list: the timer list to use
+ * @run_all: true, when called from qemu_clock_run_all_timers
  *
  * Call all expired timers associated with the timer list.
  *
  * Returns: true if any timer expired
  */
-bool timerlist_run_timers(QEMUTimerList *timer_list);
+bool timerlist_run_timers(QEMUTimerList *timer_list, bool run_all);
 
 /**
  * timerlist_notify:
diff --git a/main-loop.c b/main-loop.c
index 981bcb5..d6e93c3 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -497,6 +497,11 @@ int main_loop_wait(int nonblocking)
 slirp_pollfds_poll(gpollfds, (ret  0));
 #endif
 
+/* CPU thread can infinitely wait for event after
+   missing the warp */
+if (replay_mode == REPLAY_MODE_PLAY) {
+qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
+}
 qemu_clock_run_all_timers();
 
 return ret;
diff --git a/qemu-timer.c b/qemu-timer.c
index bc981a2..b6eb7b3 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -465,7 +465,7 @@ bool timer_expired(QEMUTimer *timer_head, int64_t 
current_time)
 return timer_expired_ns(timer_head, current_time * timer_head-scale);
 }
 
-bool timerlist_run_timers(QEMUTimerList *timer_list)
+bool timerlist_run_timers(QEMUTimerList *timer_list, bool run_all)
 {
 QEMUTimer *ts;
 int64_t current_time;
@@ -473,6 +473,32 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
 QEMUTimerCB *cb;
 void *opaque;
 
+switch (timer_list-clock-type) {
+case QEMU_CLOCK_REALTIME:
+break;
+default:
+case QEMU_CLOCK_VIRTUAL:
+if ((replay_mode != REPLAY_MODE_NONE  !runstate_is_running())
+|| !replay_checkpoint(run_all ? CHECKPOINT_CLOCK_VIRTUAL_ALL
+  : CHECKPOINT_CLOCK_VIRTUAL)) {
+return 

Re: [Qemu-devel] [PATCH 1/1] edu: fix license information

2015-01-22 Thread Jiri Slaby
On 01/22/2015, 10:04 AM, Markus Armbruster wrote:
 Jiri Slaby jsl...@suse.cz writes:
 
 Signed-off-by: Jiri Slaby jsl...@suse.cz
 ---
  docs/specs/edu.txt | 4 
  hw/misc/edu.c  | 2 +-
  2 files changed, 5 insertions(+), 1 deletion(-)

 diff --git a/docs/specs/edu.txt b/docs/specs/edu.txt
 index 360af27ec8b1..1a23df9d21f6 100644
 --- a/docs/specs/edu.txt
 +++ b/docs/specs/edu.txt
 @@ -2,6 +2,10 @@
  EDU device
  ==
  
 +Copyleft (c) 2014-2015 Jiri Slaby
 
 IANAL, but I'm afraid you have to spell this Copyright to carry legal
 weight.

Not quite as (c) is enough. GPLv2 is a copyleft license.

-- 
js
suse labs



[Qemu-devel] [PATCH 0/3] virtio-pci: 1.0 tweaks

2015-01-22 Thread Gerd Hoffmann
  Hi,

Continued to look at virtio-1.0.  Added flags to turn off legacy/modern
mode for virtio devices.

Figured notification seems to not be adapted to virtio 1.0 yet:  Apply
this patchset, boot with -device virtio-net-pci,disable-legacy=on, watch
qemu blow up in virtio_pci_set_host_notifier_internal, because it uses
uninitialited proxy-bar without checking.  Looked closer, seems the
virtio 1.0 notification memory region isn't wired up yet ...

Gerd Hoffmann (3):
  virtio-pci: add flags to enable/disable legacy/modern
  virtio-pci: use bar0 for non-transitional devices
  virtio-pci: make QEMU_VIRTIO_PCI_QUEUE_MEM_MULT smaller

 hw/virtio/virtio-pci.c | 60 --
 hw/virtio/virtio-pci.h |  6 +
 2 files changed, 49 insertions(+), 17 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH v2 0/4] initialize progname with error_set_progname()

2015-01-22 Thread Hitoshi Mitake
In the context of some subcommands of QEMU, error_get_progname() can
be used for obtaining argv[0]. The function is useful for the commands
because it is possible to detect a name of executable file and switch
behavior based on the function like busybox. e.g. block drivers can
switch behavior based on the name (qemu itself, qemu-img, or qemu-io).

But calling error_get_progname() in some commands causes segmentation
fault because initialization, calling error_set_progname(), isn't
done. This patchset adds the initialization to the commands which
lacks it but linked to util/qemu-error.o (one exception is bsd-user, because I
don't have an environment which can build and test it).

Currently, the missing call of error_set_progname() doesn't cause any
problems because the changed commands don't use error_get_progname(). This
patchset is a proactive action (but sheepdog driver will use it soon).

v2:
 - pass argv[0] directly to error_set_progname() without calling basename
 - add initialization to commands other than qemu-io

The thread of v1 can be found here:
http://lists.gnu.org/archive/html/qemu-devel/2014-08/msg01502.html

Hitoshi Mitake (4):
  qemu-io: initialize progname with error_set_progname()
  qemu-nbd: initialize progname with error_set_progname()
  qga: initialize progname with error_set_progname()
  linux-user: initialize progname with error_set_progname()

 linux-user/main.c | 2 ++
 qemu-io.c | 1 +
 qemu-nbd.c| 1 +
 qga/main.c| 1 +
 4 files changed, 5 insertions(+)

-- 
1.9.1




Re: [Qemu-devel] [PATCH 1/1] edu: fix license information

2015-01-22 Thread Markus Armbruster
Jiri Slaby jsl...@suse.cz writes:

 Signed-off-by: Jiri Slaby jsl...@suse.cz
 ---
  docs/specs/edu.txt | 4 
  hw/misc/edu.c  | 2 +-
  2 files changed, 5 insertions(+), 1 deletion(-)

 diff --git a/docs/specs/edu.txt b/docs/specs/edu.txt
 index 360af27ec8b1..1a23df9d21f6 100644
 --- a/docs/specs/edu.txt
 +++ b/docs/specs/edu.txt
 @@ -2,6 +2,10 @@
  EDU device
  ==
  
 +Copyleft (c) 2014-2015 Jiri Slaby

IANAL, but I'm afraid you have to spell this Copyright to carry legal
weight.

 +
 +This document is licensed under the GPLv2 (or later).
 +
  This is an educational device for writing (kernel) drivers. Its original
  intention was to support the Linux kernel lectures taught at the Masaryk
  University. Students are given this virtual device and are expected to write 
 a
 diff --git a/hw/misc/edu.c b/hw/misc/edu.c
 index c74f9b64540d..9a8088c6898d 100644
 --- a/hw/misc/edu.c
 +++ b/hw/misc/edu.c
 @@ -1,7 +1,7 @@
  /*
   * QEMU educational PCI device
   *
 - * Copyright (c) 2012-2014 Jiri Slaby
 + * Copyright (c) 2012-2015 Jiri Slaby
   *
   * Permission is hereby granted, free of charge, to any person obtaining a
   * copy of this software and associated documentation files (the Software),



[Qemu-devel] [PATCH v2 2/4] qemu-nbd: initialize progname with error_set_progname()

2015-01-22 Thread Hitoshi Mitake
Calling error_get_progname() in the context of qemu-nbd can cause
segmentation fault because qemu-nbd doesn't initialize its progname
with error_set_progname(). This patch adds the initialization.

Currently, the missing call of error_set_progname() doesn't cause any
problems because qemu-nbd doesn't use error_get_progname(). This patch
is a proactive action.

Cc: Paolo Bonzini pbonz...@redhat.com
Cc: Markus Armbruster arm...@redhat.com
Signed-off-by: Hitoshi Mitake mitake.hito...@lab.ntt.co.jp
---
 qemu-nbd.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/qemu-nbd.c b/qemu-nbd.c
index d222512..fad5634 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -449,6 +449,7 @@ int main(int argc, char **argv)
 sa_sigterm.sa_handler = termsig_handler;
 sigaction(SIGTERM, sa_sigterm, NULL);
 qemu_init_exec_dir(argv[0]);
+error_set_progname(argv[0]);
 
 while ((ch = getopt_long(argc, argv, sopt, lopt, opt_ind)) != -1) {
 switch (ch) {
-- 
1.9.1




[Qemu-devel] [PATCH v2 4/4] linux-user: initialize progname with error_set_progname()

2015-01-22 Thread Hitoshi Mitake
Calling error_get_progname() in the context of qemu-x86_64 can cause
segmentation fault because linux-user/main.c doesn't initialize its
progname with error_set_progname(). This patch adds the
initialization.

Currently, the missing call of error_set_progname() doesn't cause any
problems because qemu-x86_64 doesn't use error_get_progname(). This
patch is a proactive action.

Cc: Riku Voipio riku.voi...@iki.fi
Cc: Markus Armbruster arm...@redhat.com
Signed-off-by: Hitoshi Mitake mitake.hito...@lab.ntt.co.jp
---
 linux-user/main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/linux-user/main.c b/linux-user/main.c
index 8c70be4..4610b20 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -33,6 +33,7 @@
 #include qemu/timer.h
 #include qemu/envlist.h
 #include elf.h
+#include qemu/error-report.h
 
 char *exec_path;
 
@@ -3835,6 +3836,7 @@ int main(int argc, char **argv, char **envp)
 int ret;
 int execfd;
 
+error_set_progname(argv[0]);
 module_call_init(MODULE_INIT_QOM);
 
 if ((envlist = envlist_create()) == NULL) {
-- 
1.9.1




[Qemu-devel] [PATCH v2 1/4] qemu-io: initialize progname with error_set_progname()

2015-01-22 Thread Hitoshi Mitake
Calling error_get_progname() in the context of qemu-io can cause
segmentation fault because qemu-io doesn't initialize its progname
with error_set_progname(). This patch adds the initialization.

Currently, the missing call of error_set_progname() doesn't cause any
problems because qemu-io doesn't use error_get_progname(). This patch
is a proactive action.

Cc: Kevin Wolf kw...@redhat.com
Cc: Stefan Hajnoczi stefa...@redhat.com
Cc: Markus Armbruster arm...@redhat.com
Signed-off-by: Hitoshi Mitake mitake.hito...@lab.ntt.co.jp
---
 qemu-io.c | 1 +
 1 file changed, 1 insertion(+)

v2:
 - pass argv[0] directly to error_set_progname() without calling basename

diff --git a/qemu-io.c b/qemu-io.c
index 91a445a..0e7d7d4 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -396,6 +396,7 @@ int main(int argc, char **argv)
 
 progname = basename(argv[0]);
 qemu_init_exec_dir(argv[0]);
+error_set_progname(argv[0]);
 
 bdrv_init();
 
-- 
1.9.1




  1   2   3   >