[Qemu-devel] [question] how to check if savevm is completed?

2014-07-17 Thread Zhang Haoyu
Hi, all
I run savevm by qemu-monitor, but how to check if savevm is completed? I 
haven't find the query interface.

Thanks,
Zhang Haoyu




Re: [Qemu-devel] [PATCH] Tap: fix vcpu long time io blocking on tap

2014-07-17 Thread Wangkai (Kevin,C)


> -Original Message-
> From: Jason Wang [mailto:jasow...@redhat.com]
> Sent: Thursday, July 17, 2014 1:37 PM
> To: Wangkai (Kevin,C); Stefan Hajnoczi
> Cc: Lee yang; qemu-devel@nongnu.org; Stefan Hajnoczi;
> aligu...@amazon.com; Michael S. Tsirkin
> Subject: Re: [Qemu-devel] [PATCH] Tap: fix vcpu long time io blocking
> on tap
> 
> On 07/17/2014 11:43 AM, Wangkai (Kevin,C) wrote:
> >
> >> -Original Message-
> >> From: Stefan Hajnoczi [mailto:stefa...@gmail.com]
> >> Sent: Tuesday, July 15, 2014 11:00 PM
> >> To: Wangkai (Kevin,C)
> >> Cc: Stefan Hajnoczi; Lee yang; qemu-devel@nongnu.org;
> >> aligu...@amazon.com
> >> Subject: Re: [Qemu-devel] [PATCH] Tap: fix vcpu long time io
> blocking
> >> on tap
> >>
> >> On Mon, Jul 14, 2014 at 10:44:58AM +, Wangkai (Kevin,C) wrote:
> >>> Here the detail network:
> >>>
> >>> ++
> >>> | The host add tap1 and eth10 to bridge 'br1'|
> +-
> >> ---+
> >>> | ++ |
> |
> >> send  |
> >>> | |   VM  eth1-+-tap1 --- bridge --- eth10 --+-
> +
> >>> | | packets|
> >>> | ++ |
> |
> >> |
> >>> ++
> >>> ++ ++
> >>>
> >>> Qemu start vm by virtio, use tap interface, option is:
> >>> -net nic,vlan=101, model=virtio -net
> >>> tap,vlan=101,ifname=tap1,script=no,downscript=no
> >> Use the newer -netdev/-device syntax to get offload support and
> >> slightly better performance:
> >>
> >> -netdev tap,id=tap0,ifname=tap1,script=no,downscript=no \ -device
> >> virtio-net-pci,netdev=tap0
> >>
> >>> And add tap1 and eth10 to bridge br1 in the host:
> >>> Brctl addif br1 tap1
> >>> Brctl addif br1 eth10
> >>>
> >>> total recv 505387 time 2000925 us:
> >>> means call tap_send once dealing 505387 packets, the packet payload
> >>> was 300 bytes, and time use for tap_send() was 2,000,925
> >>> micro-seconds, time was measured by record time stamp at function
> >> tap_send() start and end.
> >>> We just test the performance of VM.
> >> That is 150 MB of incoming packets in a single tap_send().  Network
> >> rx queues are maybe a few 1000 packets so I wonder what is going on
> here.
> >>
> >> Maybe more packets are arriving while QEMU is reading them and we
> >> keep looping.  That's strange though because the virtio-net rx
> >> virtqueue should fill up (it only has 256 entries).
> >>
> >> Can you investigate more and find out exactly what is going on?
> It's
> >> not clear yet that adding a budget is the solution or just hiding a
> >> deeper problem.
> >>
> >> Stefan
> > [Wangkai (Kevin,C)]
> >
> > Hi Stefan,
> >
> > I think I have found the problem, why 256 entries virtqueue cannot
> > prevent packets receiving.
> >
> > I have start one SMP guest, which have 2 cores, one core was pending
> > on Io, and the other core was receiving the packets, and QEMU filling
> > the virtqueue while the guest kernel was moving the packets out from
> > the queue and process.
> >
> > They were racing, only if the guest got enough packets and receive
> > slower than QEMU sending, the virtqueue full, then finish once
> receive.
> I hit the similar issue in the past. Using pktgen to inject packets
> from tap to guest directly, then guest was slow to respond any other io
> event.
> 
> This is similar to the tx and we have tx_burst or tx_timer to solve it.
> But for rx, probably we could do some limitation in tap_send() like
> this patch since e1000 may have the same issue.
> 
> Generically, we need some mechanism to guarantee the fairness between
> devices to prevent one from starving the others.
[Wangkai (Kevin,C)] 

Yes, the QEMU io shared one thread, and locked, fairness should be 
guaranteed between io events and the io lock should be as small as
possible.

> >
> > And I have tried -netdev/-device syntax start guest again, got very
> > few Improvement.
> >
> > Regards
> > Wangkai
> >



[Qemu-devel] [Bug 1307473] Re: guest hang due to missing clock interrupt

2014-07-17 Thread Jan Müller
dup of #1332409?

seems to be a 3.13 only bug.

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

Title:
  guest hang due to missing clock interrupt

Status in QEMU:
  New
Status in “linux” package in Ubuntu:
  Confirmed
Status in “qemu” package in Ubuntu:
  Confirmed

Bug description:
  
  I noticed on 2 different systems that after upgrade from precise to latest 
trusty VMs are crashing:

  - in case of Windows VMs I'm getting BSOD with error message: "A clock 
interrupt was not received on a secondary processor within the allocated time 
interval."
  - On linux VMs I'm noticing "hrtimer: interrupt took 2992229 ns" messages 
  - On some proprietary virtual appliances I'm noticing crashes an due to 
missing timer interrupts

  QEMU version is:
  QEMU emulator version 1.7.91 (Debian 2.0.0~rc1+dfsg-0ubuntu3)

  Full command line:

  qemu-system-x86_64 -enable-kvm -name win7eval -S -machine pc-
  i440fx-1.7,accel=kvm,usb=off -cpu host -m 4096 -realtime mlock=off
  -smp 4,sockets=1,cores=4,threads=1 -uuid 05e5089a-
  4aa1-6bb2-ef06-ab4d020a -no-user-config -nodefaults -chardev
  
socket,id=charmonitor,path=/var/lib/libvirt/qemu/win7eval.monitor,server,nowait
  -mon chardev=charmonitor,id=monitor,mode=control -rtc base=localtime
  -no-shutdown -boot strict=on -device piix3-usb-
  uhci,id=usb,bus=pci.0,addr=0x1.0x2 -drive
  file=/var/vm/win7eval.qcow2,if=none,id=drive-virtio-disk0,format=qcow2
  -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=drive-virtio-
  disk0,id=virtio-disk0,bootindex=1 -drive
  file=/home/damarion/iso/7600.16385.090713-1255_x86fre_enterprise_en-
  us_EVAL_Eval_Enterprise-GRMCENEVAL_EN_DVD.iso,if=none,id=drive-
  ide0-0-0,readonly=on,format=raw -device ide-cd,bus=ide.0,unit=0,drive
  =drive-ide0-0-0,id=ide0-0-0 -drive file=/home/damarion/iso/virtio-
  win-0.1-74.iso,if=none,id=drive-ide0-1-0,readonly=on,format=raw
  -device ide-cd,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
  -netdev tap,fd=24,id=hostnet0 -device
  e1000,netdev=hostnet0,id=net0,mac=52:54:00:38:31:0a,bus=pci.0,addr=0x3
  -chardev pty,id=charserial0 -device isa-
  serial,chardev=charserial0,id=serial0 -device usb-tablet,id=input0
  -vnc 127.0.0.1:1 -device VGA,id=video0,bus=pci.0,addr=0x2 -device
  virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5

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



[Qemu-devel] [PATCH for-2.1] qcow2: Fix error path for unknown incompatible features

2014-07-17 Thread Kevin Wolf
qcow2's report_unsupported_feature() had two bugs: A 32 bit truncation
would prevent feature table entries for bits 32-63 from being used, and
it could assign errp multiple times if there was more than one unknown
feature, resulting in an error_set() assertion failure.

Fix the truncation, make sure to set the error exactly once and add a
qemu-iotests case for it.

This fixes https://bugs.launchpad.net/qemu/+bug/1342704/

Reported-by: Maria Kustova 
Signed-off-by: Kevin Wolf 
---
 block/qcow2.c   | 21 +-
 tests/qemu-iotests/036  | 52 -
 tests/qemu-iotests/036.out  | 35 ++
 tests/qemu-iotests/qcow2.py | 15 -
 4 files changed, 112 insertions(+), 11 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 445ead4..1e3ab6b 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -210,20 +210,31 @@ static void GCC_FMT_ATTR(3, 4) 
report_unsupported(BlockDriverState *bs,
 static void report_unsupported_feature(BlockDriverState *bs,
 Error **errp, Qcow2Feature *table, uint64_t mask)
 {
+char *features = g_strdup("");
+char *old;
+
 while (table && table->name[0] != '\0') {
 if (table->type == QCOW2_FEAT_TYPE_INCOMPATIBLE) {
-if (mask & (1 << table->bit)) {
-report_unsupported(bs, errp, "%.46s", table->name);
-mask &= ~(1 << table->bit);
+if (mask & (1ULL << table->bit)) {
+old = features;
+features = g_strdup_printf("%s%s%.46s", old, *old ? ", " : "",
+   table->name);
+g_free(old);
+mask &= ~(1ULL << table->bit);
 }
 }
 table++;
 }
 
 if (mask) {
-report_unsupported(bs, errp, "Unknown incompatible feature: %" PRIx64,
-   mask);
+old = features;
+features = g_strdup_printf("%s%sUnknown incompatible feature: %" 
PRIx64,
+   old, *old ? ", " : "", mask);
+g_free(old);
 }
+
+report_unsupported(bs, errp, "%s", features);
+g_free(features);
 }
 
 /*
diff --git a/tests/qemu-iotests/036 b/tests/qemu-iotests/036
index a773653..392f1ef 100755
--- a/tests/qemu-iotests/036
+++ b/tests/qemu-iotests/036
@@ -1,6 +1,6 @@
 #!/bin/bash
 #
-# Test that qcow2 unknown autoclear feature bits are cleared
+# Test qcow2 feature bits
 #
 # Copyright (C) 2011 Red Hat, Inc.
 # Copyright IBM, Corp. 2010
@@ -50,6 +50,56 @@ _supported_os Linux
 # Only qcow2v3 and later supports feature bits
 IMGOPTS="compat=1.1"
 
+echo
+echo === Image with unknown incompatible feature bit ===
+echo
+_make_test_img 64M
+$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 63
+
+# Without feature table
+$PYTHON qcow2.py "$TEST_IMG" dump-header
+_img_info
+
+# With feature table containing bit 63
+printf "\x00\x3f%s" "Test feature" | $PYTHON qcow2.py "$TEST_IMG" 
add-header-ext-stdio 0x6803f857
+_img_info
+
+echo
+echo === Image with multiple incompatible feature bits ===
+echo
+_make_test_img 64M
+$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 61
+$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 62
+$PYTHON qcow2.py "$TEST_IMG" set-feature-bit incompatible 63
+
+# Without feature table
+_img_info
+
+# With feature table containing bit 63
+printf "\x00\x3f%s" "Test feature" | $PYTHON qcow2.py "$TEST_IMG" 
add-header-ext-stdio 0x6803f857
+_img_info
+
+# With feature table containing bit 61
+$PYTHON qcow2.py "$TEST_IMG" del-header-ext 0x6803f857
+printf "\x00\x3d%s" "Test feature" | $PYTHON qcow2.py "$TEST_IMG" 
add-header-ext-stdio 0x6803f857
+_img_info
+
+# With feature table containing bits 61 and 62
+$PYTHON qcow2.py "$TEST_IMG" del-header-ext 0x6803f857
+printf "\x00\x3d%s\x00%40s\x00\x3e%s\x00%40s" "test1" "" "test2" "" | $PYTHON 
qcow2.py "$TEST_IMG" add-header-ext-stdio 0x6803f857
+_img_info
+
+# With feature table containing all bits
+$PYTHON qcow2.py "$TEST_IMG" del-header-ext 0x6803f857
+printf "\x00\x3d%s\x00%40s\x00\x3e%s\x00%40s\x00\x3f%s\x00%40s" "test1" "" 
"test2" "" "test3" "" | $PYTHON qcow2.py "$TEST_IMG" add-header-ext-stdio 
0x6803f857
+_img_info
+
+# With feature table containing unrelated bits, including compatible/autoclear
+$PYTHON qcow2.py "$TEST_IMG" del-header-ext 0x6803f857
+printf 
"\x01\x3d%s\x00%40s\x00\x3e%s\x00%40s\x02\x3f%s\x00%40s\x00\x3c%s\x00%40s" 
"test1" "" "test2" "" "test3" "" "test4" "" | $PYTHON qcow2.py "$TEST_IMG" 
add-header-ext-stdio 0x6803f857
+_img_info
+
+
 echo === Create image with unknown autoclear feature bit ===
 echo
 _make_test_img 64M
diff --git a/tests/qemu-iotests/036.out b/tests/qemu-iotests/036.out
index 55a3e6e..720bd89 100644
--- a/tests/qemu-iotests/036.out
+++ b/tests/qemu-iotests/036.out
@@ -1,4 +1,39 @@
 QA output created by 036
+
+=== Image with unknown incompatible feature bit ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 

Re: [Qemu-devel] [Intel-gfx] ResettRe: [Xen-devel] [v5][PATCH 0/5] xen: add Intel IGD passthrough support

2014-07-17 Thread Chen, Tiejun



On 2014/7/16 22:20, Konrad Rzeszutek Wilk wrote:

On Thu, Jul 03, 2014 at 11:27:40PM +0300, Michael S. Tsirkin wrote:

On Thu, Jul 03, 2014 at 12:09:28PM -0700, Jesse Barnes wrote:

On Thu, 3 Jul 2014 14:26:12 -0400
Konrad Rzeszutek Wilk  wrote:


On Thu, Jul 03, 2014 at 10:32:12AM +0300, Michael S. Tsirkin wrote:

On Wed, Jul 02, 2014 at 12:23:37PM -0400, Konrad Rzeszutek Wilk wrote:

On Wed, Jul 02, 2014 at 04:50:15PM +0200, Paolo Bonzini wrote:

Il 02/07/2014 16:00, Konrad Rzeszutek Wilk ha scritto:

With this long thread I lost a bit context about the challenges
that exists. But let me try summarizing it here - which will hopefully
get some consensus.

1). Fix IGD hardware to not use Southbridge magic addresses.
We can moan and moan but I doubt it is going to change.


There are two problems:

- Northbridge (i.e. MCH i.e. PCI host bridge) configuration space addresses


Right. So in  drivers/gpu/drm/i915/i915_dma.c:
1135 #define MCHBAR_I915 0x44
1136 #define MCHBAR_I965 0x48

1147 int reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915;
1152 if (INTEL_INFO(dev)->gen >= 4)
1153 pci_read_config_dword(dev_priv->bridge_dev, reg + 4, 
&temp_hi);
1154 pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo);
1155 mchbar_addr = ((u64)temp_hi << 32) | temp_lo;

and

1139 #define DEVEN_REG 0x54

1193 int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : 
MCHBAR_I915;
1202 if (IS_I915G(dev) || IS_I915GM(dev)) {
1203 pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, 
&temp);
1204 enabled = !!(temp & DEVEN_MCHBAR_EN);
1205 } else {
1206 pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, 
&temp);
1207 enabled = temp & 1;
1208 }


- Southbridge (i.e. PCH i.e. ISA bridge) vendor/device ID; some versions of
the driver identify it by class, some versions identify it by slot (1f.0).


Right, So in  drivers/gpu/drm/i915/i915_drv.c the giant intel_detect_pch
which sets the pch_type based on :

  432 if (pch->vendor == PCI_VENDOR_ID_INTEL) {
  433 unsigned short id = pch->device & 
INTEL_PCH_DEVICE_ID_MASK;
  434 dev_priv->pch_id = id;
  435
  436 if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {

It checks for 0x3b00, 0x1c00, 0x1e00, 0x8c00 and 0x9c00.
The INTEL_PCH_DEVICE_ID_MASK is 0xff00


To solve the first, make a new machine type, PIIX4-based, and pass through
the registers you need.  The patch must document _exactly_ why the registers
are safe to pass.  If they are not reserved on PIIX4, the patch must
document what the same offsets mean on PIIX4, and why it's sensible to
assume that firmware for virtual machine will not read/write them.  Bonus
point for also documenting the same for Q35.


OK. They look to be related to setting up an MBAR , but I don't understand
why it is needed. Hopefully some of the i915 folks CC-ed here can answer.


In particular, I think setting up MBAR should move out of i915 and become
the bridge driver tweak on linux and windows.


That is an excellent idea.

However I am still curious to _why_ it has to be done in the first place.


The display part of the GPU is partly on the PCH, and it's possible to
mix & match them a bit, so we have this detection code to figure things
out.  In some cases, the PCH display portion may not even be present,
so we look for that too.

Practically speaking, we could probably assume specific CPU/PCH combos,
as I don't think they're generally mixed across generations, though SNB
and IVB did have compatible sockets, so there is the possibility of
mixing CPT and PPT PCHs, but those are register identical as far as the
graphics driver is concerned, so even that should be safe.

Beyond that, the other MCH data we need to look at is mirrored into the
GPU's MMIO space on current gens.  On older gens, we do need to poke at
the memory controller a bit to get some info (see
intel_setup_mchbar()), but that's not true of newer stuff.  Looks like
we only short circuit that on VLV though; we could probably do it on
SNB+.


That sounds great. Tiejun could you confirm that with
windows driver guys too?


ping?


Allen,

Could you reply this?

Thanks
Tiejun



[Qemu-devel] status for rc3/release

2014-07-17 Thread Peter Maydell
So we just released rc2. The proposed schedule has
rc3 next Tuesday, with final release the Tuesday after.

My thought is that we should aim for rc3 to add only
a fairly small number of focussed and "safe" bugfixes,
with the intention of making the final release be the
same as rc3 if no showstopper bugs are discovered.
If there are any showstoppers in rc3 we have a week
to fix them and roll and test an rc4.

Does it seem to other people like we're on track for that?
I don't do the level of testing that I think Anthony had
access to, so I'm reliant on those of you doing testing
of the rc tarballs to report problems...

thanks
-- PMM



Re: [Qemu-devel] latest rc: virtio-blk hangs forever after migration

2014-07-17 Thread Marcin Gibuła

I'm using both of them applied on top of 2.0 in production and have no
problems with them. I'm using NFS exclusively with cache=none.

So, I shall test vm-migration and drive-migration with 2.1.0-rc2 with no
extra patches applied or reverted, on VM that is running fio, am I correct?



Yes, exactly. ISCSI-based setup can take some minutes to deploy, given
prepared image, and I have one hundred percent hit rate for the
original issue with it.


I've reproduced your IO hang with 2.0 and both 
9b1786829aefb83f37a8f3135e3ea91c56001b56 and 
a096b3a6732f846ec57dc28b47ee9435aa0609bf applied.


Reverting 9b1786829aefb83f37a8f3135e3ea91c56001b56 indeed fixes the 
problem (but reintroduces block-migration hang). It's seems like qemu 
bug rather than guest problem, as no-kvmclock parameters makes no 
difference. IO just stops, all qemu IO threads die off. Almost like it 
forgets to migrate them:-)


I'm attaching backtrace from guest kernel and qemu and qemu command line.

Going to compile 2.1-rc.

--
mg
[  254.634525] SysRq : Show Blocked State
[  254.635041]   taskPC stack   pid father
[  254.635304] kworker/0:2 D 88013fc145c0 083  2 0x
[  254.635304] Workqueue: xfs-log/vdb xfs_log_worker [xfs]
[  254.635304]  880136bdfa58 0046 880136bdffd8 
000145c0
[  254.635304]  880136bdffd8 000145c0 880136ad8000 
88013fc14e88
[  254.635304]  880037bd4380 880037bc5068 880037bd43b0 
880037bd4380
[  254.635304] Call Trace:
[  254.635304]  [] io_schedule+0x9d/0x140
[  254.635304]  [] get_request+0x1b5/0x790
[  254.635304]  [] ? wake_up_bit+0x30/0x30
[  254.635304]  [] blk_queue_bio+0x96/0x390
[  254.635304]  [] generic_make_request+0xe2/0x130
[  254.635304]  [] submit_bio+0x71/0x150
[  254.635304]  [] ? bio_alloc_bioset+0x1e8/0x2e0
[  254.635304]  [] _xfs_buf_ioapply+0x2bb/0x3d0 [xfs]
[  254.635304]  [] ? xlog_bdstrat+0x1f/0x50 [xfs]
[  254.635304]  [] xfs_buf_iorequest+0x46/0xa0 [xfs]
[  254.635304]  [] xlog_bdstrat+0x1f/0x50 [xfs]
[  254.635304]  [] xlog_sync+0x265/0x450 [xfs]
[  254.635304]  [] xlog_state_release_iclog+0x92/0xb0 [xfs]
[  254.635304]  [] _xfs_log_force+0x15a/0x290 [xfs]
[  254.635304]  [] ? __switch_to+0x136/0x490
[  254.635304]  [] xfs_log_force+0x26/0x80 [xfs]
[  254.635304]  [] xfs_log_worker+0x24/0x50 [xfs]
[  254.635304]  [] process_one_work+0x17b/0x460
[  254.635304]  [] worker_thread+0x11b/0x400
[  254.635304]  [] ? rescuer_thread+0x400/0x400
[  254.635304]  [] kthread+0xcf/0xe0
[  254.635304]  [] ? kthread_create_on_node+0x140/0x140
[  254.635304]  [] ret_from_fork+0x7c/0xb0
[  254.635304]  [] ? kthread_create_on_node+0x140/0x140
[  254.635304] fio D 88013fc145c0 0   772770 0x
[  254.635304]  8800bba4b8c8 0082 8800bba4bfd8 
000145c0
[  254.635304]  8800bba4bfd8 000145c0 8801376ff1c0 
88013fc14e88
[  254.635304]  880037bd4380 880037baba90 880037bd43b0 
880037bd4380
[  254.635304] Call Trace:
[  254.635304]  [] io_schedule+0x9d/0x140
[  254.635304]  [] get_request+0x1b5/0x790
[  254.635304]  [] ? wake_up_bit+0x30/0x30
[  254.635304]  [] blk_queue_bio+0x96/0x390
[  254.635304]  [] generic_make_request+0xe2/0x130
[  254.635304]  [] submit_bio+0x71/0x150
[  254.635304]  [] do_blockdev_direct_IO+0x14bc/0x2620
[  254.635304]  [] ? xfs_get_blocks+0x20/0x20 [xfs]
[  254.635304]  [] __blockdev_direct_IO+0x55/0x60
[  254.635304]  [] ? xfs_get_blocks+0x20/0x20 [xfs]
[  254.635304]  [] xfs_vm_direct_IO+0x15c/0x180 [xfs]
[  254.635304]  [] ? xfs_get_blocks+0x20/0x20 [xfs]
[  254.635304]  [] generic_file_aio_read+0x6d3/0x750
[  254.635304]  [] ? ktime_get_ts+0x48/0xe0
[  254.635304]  [] ? delayacct_end+0x8f/0xb0
[  254.635304]  [] ? down_read+0x12/0x30
[  254.635304]  [] xfs_file_aio_read+0x154/0x2e0 [xfs]
[  254.635304]  [] ? xfs_file_splice_read+0x140/0x140 [xfs]
[  254.635304]  [] do_io_submit+0x3b8/0x840
[  254.635304]  [] SyS_io_submit+0x10/0x20
[  254.635304]  [] system_call_fastpath+0x16/0x1b

Thread 3 (Thread 0x7f4250f50700 (LWP 11955)):
#0  0x7f4253d1a897 in ioctl () from /lib64/libc.so.6
#1  0x7f4257f8adf9 in kvm_vcpu_ioctl (cpu=cpu@entry=0x7f4258e2aa90, 
type=type@entry=44672)
at 
/var/tmp/portage/app-emulation/qemu-2.0.0_rc2/work/qemu-2.0.0-rc2/kvm-all.c:1796
#2  0x7f4257f8af35 in kvm_cpu_exec (cpu=cpu@entry=0x7f4258e2aa90) at 
/var/tmp/portage/app-emulation/qemu-2.0.0_rc2/work/qemu-2.0.0-rc2/kvm-all.c:1681
#3  0x7f4257f3071c in qemu_kvm_cpu_thread_fn (arg=0x7f4258e2aa90) at 
/var/tmp/portage/app-emulation/qemu-2.0.0_rc2/work/qemu-2.0.0-rc2/cpus.c:873
#4  0x7f4253fe8f3a in start_thread () from /lib64/libpthread.so.0
#5  0x7f4253d22dad in clone () from /lib64/libc.so.6

Thread 2 (Thread 0x7f424b5ff700 (LWP 11957)):
#0  0x7f4253fecd0c in pthread_cond_wait@@GLIBC_2.3.2 () from 
/lib64/libpthread.so.0
#1  0x7f425802c019 in qemu_cond_wait (cond=cond@entry=0x7f4258f0cf

Re: [Qemu-devel] [PULL for-2.1] virtio-serial: bugfix for virtconsole port unplug

2014-07-17 Thread Peter Maydell
On 16 July 2014 10:09, Amit Shah  wrote:
> Hi,
>
> This is a small bugfix to prevent port unplug causing port 0 getting
> unreserved for virtconsole use.
>
> Patch has been on-list for a few days and has been reviewed.
>
> Please pull.
>
>
> The following changes since commit 5a7348045091a2bc15d85bb177e5956aa6114e5a:
>
>   Update version for v2.1.0-rc2 release (2014-07-15 18:55:37 +0100)
>
> are available in the git repository at:
>
>   git://git.kernel.org/pub/scm/virt/qemu/amit/virtio-serial.git for-2.1
>
> for you to fetch changes up to 57d84cf35302fe51789c18354bf09a521bb603df:
>
>   virtio-serial-bus: keep port 0 reserved for virtconsole even on unplug 
> (2014-07-16 14:32:40 +0530)
>
> 
> Amit Shah (1):
>   virtio-serial-bus: keep port 0 reserved for virtconsole even on unplug
>
>  hw/char/virtio-serial-bus.c | 14 +++---
>  1 file changed, 11 insertions(+), 3 deletions(-)

Applied, thanks.

-- PMM



Re: [Qemu-devel] latest rc: virtio-blk hangs forever after migration

2014-07-17 Thread Marcin Gibuła

I've reproduced your IO hang with 2.0 and both
9b1786829aefb83f37a8f3135e3ea91c56001b56 and
a096b3a6732f846ec57dc28b47ee9435aa0609bf applied.

Reverting 9b1786829aefb83f37a8f3135e3ea91c56001b56 indeed fixes the
problem (but reintroduces block-migration hang). It's seems like qemu
bug rather than guest problem, as no-kvmclock parameters makes no
difference. IO just stops, all qemu IO threads die off. Almost like it
forgets to migrate them:-)


Some more info:

a) 2.0 + 9b1786829aefb83f37a8f3135e3ea91c56001b56 + 
a096b3a6732f846ec57dc28b47ee9435aa0609bf = hangs


b) 2.0 + 9b1786829aefb83f37a8f3135e3ea91c56001b56 = works

c) 2.0 + 9b1786829aefb83f37a8f3135e3ea91c56001b56 + move 
cpu_synchronize_state to migration.c = works


Tested with NFS (qcow2) + cache=none.

IO is dead only for disk that was being written to during migration.
I.e. if my test VM has two disks: vda and vdb, and I'm running fio on 
vdb and it hangs after migration, I can still issue writes to vda.


Recreation steps:
1. Create VM
2. Run fio (Andrey's config)
3. Live migrate VM couple of times.

--
mg



[Qemu-devel] [PATCH v4 0/8] Obtain dirty bitmap via VM logging

2014-07-17 Thread Sanidhya Kashyap
Hi,

The following patches introduce the support of the dirty bitmap logging and
dumping to a specified file. This patch addresses the previous issues raised
by David and Juan. Since, I have not received any comments on the runstates,
I'll keep them in the patch series.

v3 --> v4
* Added new qmp interface for information extraction from the bitmap process

v2 --> v3
* Reformatted the code and removed some unnecessary parts.
* Printing block info along with length and offset.
* Changed the functions that were directly using RUN_STATE_RUNNING as state.

v1 --> v2:
* Added two new run states to avoid simultaneous execution of both migration and
  bitmap dump process.
* Removed FILE pointer usage.
* Dumping the data only in machine-readable format.
* Tried to rectify mistakes of the previous version.



Sanidhya Kashyap (8):
  enable sharing of the function between migration and bitmap dump
  RunState: added two new flags for bitmap dump and migration process
  BitmapLog: bitmap dump code via QAPI framework with runstates
  BitmapLog: hmp interface for dirty bitmap dump
  BitmapLog: cancel mechanism for an already running dump bitmap process
  BitmapLog: set the frequency of the dump bitmap process
  BitmapLog: get the information about the parameters
  BitmapLog: python script for extracting bitmap from a binary file

 arch_init.c   |  19 ++-
 hmp-commands.hx   |  45 ++
 hmp.c |  33 
 hmp.h |   3 +
 hw/usb/hcd-ehci.c |   2 +-
 hw/usb/redirect.c |   6 +-
 include/exec/cpu-all.h|   4 +-
 include/exec/ram_addr.h   |   4 +
 migration.c   |   7 +
 qapi-schema.json  |  77 +-
 qmp-commands.hx   |  99 
 savevm.c  | 384 ++
 scripts/extract-bitmap.py |  97 
 vl.c  |  29 +++-
 14 files changed, 794 insertions(+), 15 deletions(-)
 create mode 100755 scripts/extract-bitmap.py

-- 
1.9.3




[Qemu-devel] [PATCH v4 2/8] RunState: added two new flags for bitmap dump and migration process

2014-07-17 Thread Sanidhya Kashyap
Changed those files that were directly using the RUN_STATE_RUNNING flag. Now,
they have been replaced by the runstate_is_running() function.

Signed-off-by: Sanidhya Kashyap 
---
 hw/usb/hcd-ehci.c |  2 +-
 hw/usb/redirect.c |  6 +++---
 qapi-schema.json  |  7 ++-
 vl.c  | 29 -
 4 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index a00a93c..5487edc 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2393,7 +2393,7 @@ static void usb_ehci_vm_state_change(void *opaque, int 
running, RunState state)
  * USB-devices which have async handled packages have a packet in the
  * ep queue to match the completion with.
  */
-if (state == RUN_STATE_RUNNING) {
+if (runstate_is_running()) {
 ehci_advance_async_state(ehci);
 }
 
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 44522d9..2c16ad5 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -283,7 +283,7 @@ static int usbredir_write(void *priv, uint8_t *data, int 
count)
 }
 
 /* Don't send new data to the chardev until our state is fully synced */
-if (!runstate_check(RUN_STATE_RUNNING)) {
+if (!runstate_is_running()) {
 return 0;
 }
 
@@ -1290,7 +1290,7 @@ static int usbredir_chardev_can_read(void *opaque)
 }
 
 /* Don't read new data from the chardev until our state is fully synced */
-if (!runstate_check(RUN_STATE_RUNNING)) {
+if (!runstate_is_running()) {
 return 0;
 }
 
@@ -1340,7 +1340,7 @@ static void usbredir_vm_state_change(void *priv, int 
running, RunState state)
 {
 USBRedirDevice *dev = priv;
 
-if (state == RUN_STATE_RUNNING && dev->parser != NULL) {
+if (runstate_is_running() && dev->parser != NULL) {
 usbredirparser_do_write(dev->parser); /* Flush any pending writes */
 }
 }
diff --git a/qapi-schema.json b/qapi-schema.json
index b11aad2..501b8d0 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -145,12 +145,17 @@
 # @watchdog: the watchdog action is configured to pause and has been triggered
 #
 # @guest-panicked: guest has been panicked as a result of guest OS panic
+#
+# @migrate: migration process is being executed
+#
+# @dump-bitmap: dump the writable working set of the guest
+#
 ##
 { 'enum': 'RunState',
   'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
 'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
 'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',
-'guest-panicked' ] }
+'guest-panicked', 'migrate', 'dump-bitmap' ] }
 
 ##
 # @StatusInfo:
diff --git a/vl.c b/vl.c
index 6e084c2..30d6fb7 100644
--- a/vl.c
+++ b/vl.c
@@ -593,31 +593,39 @@ static const RunStateTransition 
runstate_transitions_def[] = {
 /* from  -> to  */
 { RUN_STATE_DEBUG, RUN_STATE_RUNNING },
 { RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
+{ RUN_STATE_DEBUG, RUN_STATE_MIGRATE },
 
 { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING },
 { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED },
 
 { RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED },
 { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
+{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_MIGRATE },
 
 { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING },
 { RUN_STATE_IO_ERROR, RUN_STATE_FINISH_MIGRATE },
+{ RUN_STATE_IO_ERROR, RUN_STATE_MIGRATE },
 
 { RUN_STATE_PAUSED, RUN_STATE_RUNNING },
 { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
+{ RUN_STATE_PAUSED, RUN_STATE_MIGRATE },
 
 { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
 { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
+{ RUN_STATE_POSTMIGRATE, RUN_STATE_MIGRATE },
 
 { RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING },
 { RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE },
 { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
+{ RUN_STATE_PRELAUNCH, RUN_STATE_MIGRATE },
 
 { RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING },
 { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE },
 
 { RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING },
 
+{ RUN_STATE_DUMP_BITMAP, RUN_STATE_RUNNING},
+
 { RUN_STATE_RUNNING, RUN_STATE_DEBUG },
 { RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
 { RUN_STATE_RUNNING, RUN_STATE_IO_ERROR },
@@ -628,6 +636,8 @@ static const RunStateTransition runstate_transitions_def[] 
= {
 { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
 { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
 { RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
+{ RUN_STATE_RUNNING, RUN_STATE_DUMP_BITMAP },
+{ RUN_STATE_RUNNING, RUN_STATE_MIGRATE },
 
 { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
 
@@ -638,12 +648,27 @@ static const RunStateTransition 
runstate_transitions_def[] = {
 { RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
 { RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
 { RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
+{ RUN_STATE_SUSPENDED, RUN_STATE_MIGRATE },
 

[Qemu-devel] [PATCH v4 1/8] enable sharing of the function between migration and bitmap dump

2014-07-17 Thread Sanidhya Kashyap
Added prefix qemu_ to the function as pointed out by Juan.

Signed-off-by: Sanidhya Kashyap 
---
 arch_init.c | 19 +++
 include/exec/ram_addr.h |  4 
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index 8ddaf35..9ac4602 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -434,20 +434,22 @@ ram_addr_t 
migration_bitmap_find_and_reset_dirty(MemoryRegion *mr,
 return (next - base) << TARGET_PAGE_BITS;
 }
 
-static inline bool migration_bitmap_set_dirty(ram_addr_t addr)
+static inline bool qemu_bitmap_set_dirty(ram_addr_t addr, unsigned long 
*bitmap,
+ bool migration_flag)
 {
 bool ret;
 int nr = addr >> TARGET_PAGE_BITS;
 
-ret = test_and_set_bit(nr, migration_bitmap);
+ret = test_and_set_bit(nr, bitmap);
 
-if (!ret) {
+if (!ret && migration_flag) {
 migration_dirty_pages++;
 }
 return ret;
 }
 
-static void migration_bitmap_sync_range(ram_addr_t start, ram_addr_t length)
+void qemu_bitmap_sync_range(ram_addr_t start, ram_addr_t length,
+  unsigned long *bitmap, bool migration_flag)
 {
 ram_addr_t addr;
 unsigned long page = BIT_WORD(start >> TARGET_PAGE_BITS);
@@ -461,8 +463,8 @@ static void migration_bitmap_sync_range(ram_addr_t start, 
ram_addr_t length)
 for (k = page; k < page + nr; k++) {
 if (src[k]) {
 unsigned long new_dirty;
-new_dirty = ~migration_bitmap[k];
-migration_bitmap[k] |= src[k];
+new_dirty = ~bitmap[k];
+bitmap[k] |= src[k];
 new_dirty &= src[k];
 migration_dirty_pages += ctpopl(new_dirty);
 src[k] = 0;
@@ -476,7 +478,7 @@ static void migration_bitmap_sync_range(ram_addr_t start, 
ram_addr_t length)
 cpu_physical_memory_reset_dirty(start + addr,
 TARGET_PAGE_SIZE,
 DIRTY_MEMORY_MIGRATION);
-migration_bitmap_set_dirty(start + addr);
+qemu_bitmap_set_dirty(start + addr, bitmap, migration_flag);
 }
 }
 }
@@ -512,7 +514,8 @@ static void migration_bitmap_sync(void)
 address_space_sync_dirty_bitmap(&address_space_memory);
 
 QTAILQ_FOREACH(block, &ram_list.blocks, next) {
-migration_bitmap_sync_range(block->mr->ram_addr, block->length);
+qemu_bitmap_sync_range(block->mr->ram_addr, block->length,
+  migration_bitmap, true);
 }
 trace_migration_bitmap_sync_end(migration_dirty_pages
 - num_dirty_pages_init);
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index e9eb831..a5809b4 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -151,5 +151,9 @@ static inline void 
cpu_physical_memory_clear_dirty_range(ram_addr_t start,
 void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t length,
  unsigned client);
 
+
+void qemu_bitmap_sync_range(ram_addr_t start, ram_addr_t length,
+  unsigned long *bitmap, bool migration_flag);
+
 #endif
 #endif
-- 
1.9.3




[Qemu-devel] [PATCH v4 3/8] BitmapLog: bitmap dump code via QAPI framework with runstates

2014-07-17 Thread Sanidhya Kashyap
Reformatted the code and added the functionality of dumping the blocks' info
which can be read by the user when required. I have also made the block name
length global.
Some minor modification to the structure which is now storing all the
information.

Signed-off-by: Sanidhya Kashyap 
---
 include/exec/cpu-all.h |   4 +-
 migration.c|   7 ++
 qapi-schema.json   |  18 +++
 qmp-commands.hx|  30 +
 savevm.c   | 325 +
 5 files changed, 383 insertions(+), 1 deletion(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index f91581f..b459301 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -297,13 +297,15 @@ CPUArchState *cpu_copy(CPUArchState *env);
 
 /* memory API */
 
+#define RAMBLOCK_NAME_LENGTH (1<<8)
+
 typedef struct RAMBlock {
 struct MemoryRegion *mr;
 uint8_t *host;
 ram_addr_t offset;
 ram_addr_t length;
 uint32_t flags;
-char idstr[256];
+char idstr[RAMBLOCK_NAME_LENGTH];
 /* Reads can take either the iothread or the ramlist lock.
  * Writes must take both locks.
  */
diff --git a/migration.c b/migration.c
index 8d675b3..e2e313c 100644
--- a/migration.c
+++ b/migration.c
@@ -436,6 +436,13 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
 return;
 }
 
+if (runstate_check(RUN_STATE_DUMP_BITMAP)) {
+error_setg(errp, "bitmap dump in progress");
+return;
+}
+
+runstate_set(RUN_STATE_MIGRATE);
+
 s = migrate_init(¶ms);
 
 if (strstart(uri, "tcp:", &p)) {
diff --git a/qapi-schema.json b/qapi-schema.json
index 501b8d0..924d6bc 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3485,3 +3485,21 @@
 # Since: 2.1
 ##
 { 'command': 'rtc-reset-reinjection' }
+
+##
+# @log-dirty-bitmap
+#
+# dumps the dirty bitmap to a file by logging the
+# memory for a specified number of times with a
+# a defined time differnce
+#
+# @filename: name of the file in which the bitmap will be saved.
+# @epochs: number of times the memory will be logged (optional).
+# @frequency: time difference in milliseconds between each epoch (optional).
+#
+# Since 2.2
+##
+{ 'command' : 'log-dirty-bitmap',
+  'data': { 'filename'  : 'str',
+'*epochs'   : 'int',
+'*frequency': 'int' } }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 4be4765..200f57e 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3753,5 +3753,35 @@ Example:
 
 -> { "execute": "rtc-reset-reinjection" }
 <- { "return": {} }
+EQMP
+
+{
+.name   = "log-dirty-bitmap",
+.args_type  = "filename:s,epochs:i?,frequency:i?,readable:-r?",
+.mhandler.cmd_new = qmp_marshal_input_log_dirty_bitmap,
+},
+
+SQMP
+log-dirty-bitmap
+
+
+start logging the memory of the VM for writable working set
+
+Arguments:
+
+- "filename": name of the file, in which the bitmap will be saved
+- "epochs": number of times, the memory will be logged
+- "frequency": time difference in milliseconds between each epoch
+
+Examples:
+-> { "execute" : "log-dirty-bitmap",
+ "arguments" : {
+ "filename" : "/tmp/fileXXX",
+ "epochs" : 3,
+ "frequency" : 10 } }
+
+<- { "return": {} }
 
+Note: The epochs, frequency and readable are optional. epochs default
+value is 3 while that of frequency is 10.
 EQMP
diff --git a/savevm.c b/savevm.c
index e19ae0a..ecb334e 100644
--- a/savevm.c
+++ b/savevm.c
@@ -42,6 +42,9 @@
 #include "qemu/iov.h"
 #include "block/snapshot.h"
 #include "block/qapi.h"
+#include "exec/address-spaces.h"
+#include "exec/ram_addr.h"
+#include "qemu/bitmap.h"
 
 
 #ifndef ETH_P_RARP
@@ -1137,6 +1140,328 @@ void do_savevm(Monitor *mon, const QDict *qdict)
 }
 }
 
+/*
+ * Adding the functionality of continuous logging of the
+ * dirty bitmap which is almost similar to the migration
+ * thread
+ */
+
+enum {
+LOG_BITMAP_STATE_ERROR = -1,
+LOG_BITMAP_STATE_NONE,
+LOG_BITMAP_STATE_SETUP,
+LOG_BITMAP_STATE_ACTIVE,
+LOG_BITMAP_STATE_CANCELING,
+LOG_BITMAP_STATE_COMPLETED
+};
+
+typedef struct BitmapLogState BitmapLogState;
+static unsigned long *logging_bitmap;
+static int64_t MIN_EPOCH_VALUE = 3;
+static int64_t MIN_FREQUENCY_VALUE = 10;
+static int64_t MAX_EPOCH_VALUE = 10;
+static int64_t MAX_FREQUENCY_VALUE = 10;
+
+struct BitmapLogState {
+int state;
+int fd;
+int64_t current_frequency;
+int64_t current_epoch;
+int64_t total_epochs;
+QemuThread thread;
+};
+
+/*
+ * helper functions
+ */
+
+static inline void logging_lock(void)
+{
+qemu_mutex_lock_iothread();
+qemu_mutex_lock_ramlist();
+}
+
+static inline void logging_unlock(void)
+{
+qemu_mutex_unlock_ramlist();
+qemu_mutex_unlock_iothread();
+}
+
+static inline void logging_bitmap_set_dirty(ram_addr_t addr)
+{
+int nr  = addr >> TARGET_PAGE_BITS;
+set_bit(nr, logging_bitmap);
+}
+
+static bool logging_state_set_s

[Qemu-devel] [PATCH v4 4/8] BitmapLog: hmp interface for dirty bitmap dump

2014-07-17 Thread Sanidhya Kashyap
Signed-off-by: Sanidhya Kashyap 
---
 hmp-commands.hx | 16 
 hmp.c   | 16 
 hmp.h   |  1 +
 3 files changed, 33 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index d0943b1..575df78 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1788,6 +1788,22 @@ STEXI
 show available trace events and their state
 ETEXI
 
+ {
+.name   = "ldb|log-dirty-bitmap",
+.args_type  = "filename:s,epochs:i?,frequency:i?",
+.params = "filename epochs frequency",
+.help   = "dumps the memory's dirty bitmap to file\n\t\t\t"
+ "filename: name of the file in which the bitmap will be 
saved\n\t\t\t"
+  "epochs: number of times, the memory will be 
logged\n\t\t\t"
+  "frequency: time difference in milliseconds between each 
epoch",
+.mhandler.cmd = hmp_log_dirty_bitmap,
+},
+STEXI
+@item ldb or log-dirty-bitmap @var{filename}
+@findex log-dirty-bitmap
+dumps the writable working set of a VM's memory to a file
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/hmp.c b/hmp.c
index 4d1838e..3c8e56d 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1318,6 +1318,22 @@ void hmp_device_del(Monitor *mon, const QDict *qdict)
 hmp_handle_error(mon, &err);
 }
 
+void hmp_log_dirty_bitmap(Monitor *mon, const QDict *qdict)
+{
+const char *filename = qdict_get_str(qdict, "filename");
+int64_t epochs = qdict_get_try_int(qdict, "epochs", 3);
+int64_t frequency = qdict_get_try_int(qdict, "frequency", 10);
+Error *err = NULL;
+
+qmp_log_dirty_bitmap(filename, !!epochs, epochs, !!frequency,
+ frequency, &err);
+if (err) {
+monitor_printf(mon, "log-dirty-bitmap: %s\n", error_get_pretty(err));
+error_free(err);
+return;
+}
+}
+
 void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
 {
 Error *err = NULL;
diff --git a/hmp.h b/hmp.h
index 4fd3c4a..0895182 100644
--- a/hmp.h
+++ b/hmp.h
@@ -94,6 +94,7 @@ void hmp_cpu_add(Monitor *mon, const QDict *qdict);
 void hmp_object_add(Monitor *mon, const QDict *qdict);
 void hmp_object_del(Monitor *mon, const QDict *qdict);
 void hmp_info_memdev(Monitor *mon, const QDict *qdict);
+void hmp_log_dirty_bitmap(Monitor *mon, const QDict *qdict);
 void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
-- 
1.9.3




[Qemu-devel] [PATCH v4 5/8] BitmapLog: cancel mechanism for an already running dump bitmap process

2014-07-17 Thread Sanidhya Kashyap
Signed-off-by: Sanidhya Kashyap 
---
 hmp-commands.hx  | 14 ++
 hmp.c|  5 +
 hmp.h|  1 +
 qapi-schema.json |  8 
 qmp-commands.hx  | 21 +
 savevm.c | 19 +++
 6 files changed, 68 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 575df78..61eca66 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1804,6 +1804,20 @@ STEXI
 dumps the writable working set of a VM's memory to a file
 ETEXI
 
+   {
+   .name   = "ldbc|log-dirty-bitmap-cancel",
+   .args_type  = "",
+   .params = "",
+   .help   = "cancel the current bitmap dump process",
+   .mhandler.cmd = hmp_log_dirty_bitmap_cancel,
+},
+
+STEXI
+@item ldbc or log-dirty-bitmap-cancel
+@findex log-dirty-bitmap-cancel
+Cancel the current bitmap dump process
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/hmp.c b/hmp.c
index 3c8e56d..782f788 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1334,6 +1334,11 @@ void hmp_log_dirty_bitmap(Monitor *mon, const QDict 
*qdict)
 }
 }
 
+void hmp_log_dirty_bitmap_cancel(Monitor *mon, const QDict *qdict)
+{
+qmp_log_dirty_bitmap_cancel(NULL);
+}
+
 void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
 {
 Error *err = NULL;
diff --git a/hmp.h b/hmp.h
index 0895182..12691f9 100644
--- a/hmp.h
+++ b/hmp.h
@@ -95,6 +95,7 @@ void hmp_object_add(Monitor *mon, const QDict *qdict);
 void hmp_object_del(Monitor *mon, const QDict *qdict);
 void hmp_info_memdev(Monitor *mon, const QDict *qdict);
 void hmp_log_dirty_bitmap(Monitor *mon, const QDict *qdict);
+void hmp_log_dirty_bitmap_cancel(Monitor *mon, const QDict *qdict);
 void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
diff --git a/qapi-schema.json b/qapi-schema.json
index 924d6bc..70e07e9 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3503,3 +3503,11 @@
   'data': { 'filename'  : 'str',
 '*epochs'   : 'int',
 '*frequency': 'int' } }
+##
+# @log-dirty-bitmap-cancel
+#
+# cancel the dirty bitmap logging process
+#
+# Since 2.2
+##
+{ 'command': 'log-dirty-bitmap-cancel' }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 200f57e..69d4a07 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3785,3 +3785,24 @@ Examples:
 Note: The epochs, frequency and readable are optional. epochs default
 value is 3 while that of frequency is 10.
 EQMP
+
+   {
+.name   = "log-dirty-bitmap-cancel",
+.args_type  = "",
+.mhandler.cmd_new = qmp_marshal_input_log_dirty_bitmap_cancel,
+},
+
+SQMP
+log_bitmap_cancel
+--
+
+Cancel the current bitmap dump process.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "log-dirty-bitmap-cancel" }
+<- { "return": {} }
+
+EQMP
diff --git a/savevm.c b/savevm.c
index ecb334e..b1b0421 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1462,6 +1462,25 @@ void qmp_log_dirty_bitmap(const char *filename, bool 
has_epochs,
 return;
 }
 
+static void logging_bitmap_cancel(BitmapLogState *b)
+{
+int old_state;
+do {
+old_state = b->state;
+if (old_state != LOG_BITMAP_STATE_SETUP &&
+old_state != LOG_BITMAP_STATE_ACTIVE) {
+break;
+}
+logging_state_set_status(b, old_state,
+ LOG_BITMAP_STATE_CANCELING);
+} while (b->state != LOG_BITMAP_STATE_CANCELING);
+}
+
+void qmp_log_dirty_bitmap_cancel(Error **errp)
+{
+logging_bitmap_cancel(logging_current_state());
+}
+
 void qmp_xen_save_devices_state(const char *filename, Error **errp)
 {
 QEMUFile *f;
-- 
1.9.3




[Qemu-devel] [PATCH v4 6/8] BitmapLog: set the frequency of the dump bitmap process

2014-07-17 Thread Sanidhya Kashyap
Rectified the example mistake in qmp-commands.hx.

Signed-off-by: Sanidhya Kashyap 
---
 hmp-commands.hx  | 15 +++
 hmp.c| 12 
 hmp.h|  1 +
 qapi-schema.json | 13 +
 qmp-commands.hx  | 24 
 savevm.c | 14 ++
 6 files changed, 79 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 61eca66..9f940ab 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1818,6 +1818,21 @@ STEXI
 Cancel the current bitmap dump process
 ETEXI
 
+{
+.name   = "ldbsf|log-dirty-bitmap-set-frequency",
+.args_type  = "frequency:i",
+.params = "frequency",
+.help   = "set the frequency for bitmap dump process\n\t\t\t"
+  "frequency: the new frequency value to replace the 
existing",
+.mhandler.cmd = hmp_log_dirty_bitmap_set_frequency,
+},
+
+STEXI
+@item ldbsf or log-dirty-bitmap-set-frequency @var{frequency}
+@findex log-dirty-bitmap-set-frequency
+Set the frequency to @var{frequency} (int) for bitmap dump process.
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/hmp.c b/hmp.c
index 782f788..3408709 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1339,6 +1339,18 @@ void hmp_log_dirty_bitmap_cancel(Monitor *mon, const 
QDict *qdict)
 qmp_log_dirty_bitmap_cancel(NULL);
 }
 
+void hmp_log_dirty_bitmap_set_frequency(Monitor *mon, const QDict *qdict)
+{
+int64_t frequency = qdict_get_int(qdict, "frequency");
+Error *err = NULL;
+qmp_log_dirty_bitmap_set_frequency(frequency, &err);
+if (err) {
+monitor_printf(mon, "log-dirty-bitmap-set-frequency: %s\n",
+   error_get_pretty(err));
+error_free(err);
+}
+}
+
 void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
 {
 Error *err = NULL;
diff --git a/hmp.h b/hmp.h
index 12691f9..33a2c64 100644
--- a/hmp.h
+++ b/hmp.h
@@ -96,6 +96,7 @@ void hmp_object_del(Monitor *mon, const QDict *qdict);
 void hmp_info_memdev(Monitor *mon, const QDict *qdict);
 void hmp_log_dirty_bitmap(Monitor *mon, const QDict *qdict);
 void hmp_log_dirty_bitmap_cancel(Monitor *mon, const QDict *qdict);
+void hmp_log_dirty_bitmap_set_frequency(Monitor *mon, const QDict *qdict);
 void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
diff --git a/qapi-schema.json b/qapi-schema.json
index 70e07e9..90977eb 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3511,3 +3511,16 @@
 # Since 2.2
 ##
 { 'command': 'log-dirty-bitmap-cancel' }
+
+##
+# @log-dirty-bitmap-set-frequency
+#
+# sets the frequency of the dirty bitmap logging process
+# @frequency: the updated frequency value (in milliseconds).
+# The min and max values are 10 and 10 respectively.
+#
+# Since 2.2
+##
+{ 'command': 'log-dirty-bitmap-set-frequency',
+  'data': {'frequency': 'int' } }
+
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 69d4a07..0a13b74 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3806,3 +3806,27 @@ Example:
 <- { "return": {} }
 
 EQMP
+
+{
+.name   = "log-dirty-bitmap-set-frequency",
+.args_type  = "frequency:i",
+.mhandler.cmd_new = qmp_marshal_input_log_dirty_bitmap_set_frequency,
+},
+
+SQMP
+log-dirty-bitmap-set-frequency
+
+
+Update the frequency for the remaining epochs.
+
+Arguments:
+
+- "frequency": the updated frequency (json-int) (in milliseconds)
+
+Example:
+
+-> { "execute": "log-dirty-bitmap-set-frequency", "arguments": { "frequency": 
1024 } }
+<- { "return": {} }
+
+EQMP
+
diff --git a/savevm.c b/savevm.c
index b1b0421..d22771c 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1481,6 +1481,20 @@ void qmp_log_dirty_bitmap_cancel(Error **errp)
 logging_bitmap_cancel(logging_current_state());
 }
 
+void qmp_log_dirty_bitmap_set_frequency(int64_t frequency, Error **errp)
+{
+BitmapLogState *b = logging_current_state();
+Error *local_err = NULL;
+if (value_in_range(frequency, MIN_FREQUENCY_VALUE,
+   MAX_FREQUENCY_VALUE, "frequency", &local_err)) {
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+}
+b->current_frequency = frequency;
+}
+
 void qmp_xen_save_devices_state(const char *filename, Error **errp)
 {
 QEMUFile *f;
-- 
1.9.3




[Qemu-devel] [PATCH v4 8/8] BitmapLog: python script for extracting bitmap from a binary file

2014-07-17 Thread Sanidhya Kashyap
Signed-off-by: Sanidhya Kashyap 
---
 scripts/extract-bitmap.py | 97 +++
 1 file changed, 97 insertions(+)
 create mode 100755 scripts/extract-bitmap.py

diff --git a/scripts/extract-bitmap.py b/scripts/extract-bitmap.py
new file mode 100755
index 000..5edc49d
--- /dev/null
+++ b/scripts/extract-bitmap.py
@@ -0,0 +1,97 @@
+#!/usr/bin/python
+# This python script helps in extracting the dirty bitmap present
+# in the file after executing the log-dirty-bitmap command either
+# from the qmp or hmp interface. This file only processes binary
+# file obtained via command.
+#
+# Copyright (C) 2014 Sanidhya Kashyap 
+#
+# Authors:
+#   Sanidhya Kashyap
+#
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+
+import struct
+import argparse
+from functools import partial
+
+long_bytes = 8
+byte_size = 8
+int_bytes = 4
+string_bytes = 256
+complete_bitmap_list = []
+block_list = []
+
+def get_unsigned_long_integer(value):
+   return struct.unpack('

[Qemu-devel] [PATCH v4 7/8] BitmapLog: get the information about the parameters

2014-07-17 Thread Sanidhya Kashyap
Added the qmp interface to know about the information of the bitmap dump
process. When the command is executed, one can know about the current epoch
value in which the process is in, the total iterations value and the current
frequency value.

Currently, I do not think that that one needs to modify the other values
except frequency, so that is why I have not added the generic set-tuning
interface. If required, I will add it.

Signed-off-by: Sanidhya Kashyap 
---
 qapi-schema.json | 31 +++
 qmp-commands.hx  | 24 
 savevm.c | 26 ++
 3 files changed, 81 insertions(+)

diff --git a/qapi-schema.json b/qapi-schema.json
index 90977eb..1b09235d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3487,6 +3487,24 @@
 { 'command': 'rtc-reset-reinjection' }
 
 ##
+# @BitmapLogStateInfo
+#
+# Provides information for the bitmap logging process
+#
+# @currepoch: provides the value of the running epoch value
+#
+# @epochs: provides the information about the actual epoch
+#
+# @frequency: the time difference in milliseconds between each epcoh
+#
+# Since 2.2
+##
+{ 'type': 'BitmapLogStateInfo',
+  'data': { 'currepoch': 'int',
+'epochs':'int',
+'frequency': 'int' } }
+
+##
 # @log-dirty-bitmap
 #
 # dumps the dirty bitmap to a file by logging the
@@ -3524,3 +3542,16 @@
 { 'command': 'log-dirty-bitmap-set-frequency',
   'data': {'frequency': 'int' } }
 
+##
+# @log-dirty-bitmap-get-tuning
+#
+# Get the current values of the parameters involved in  bitmap logging process
+#
+# This command returns the following elements in the form of 
BitmapLogStateInfo:
+# - currepoch: current epoch value
+# - epochs: total epochs for which the bitmap dumping will continue
+# - frequently: the current sleep interval between each epoch
+#
+# Since 2.2
+##
+{ 'command': 'log-dirty-bitmap-get-tuning', 'returns': 'BitmapLogStateInfo' }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 0a13b74..3bd60e1 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3830,3 +3830,27 @@ Example:
 
 EQMP
 
+{
+.name   = "log-dirty-bitmap-get-tuning",
+.args_type  = "",
+.mhandler.cmd_new = qmp_marshal_input_log_dirty_bitmap_get_tuning,
+},
+
+SQMP
+log-dirty-bitmap-get-tuning
+
+
+Get the parameters information
+
+- "currepoch": the current epoch going on
+- "epochs" the total number of assigned epochs
+- "frequency": the sleep interval between each epoch (in milliseconds)
+
+Example:
+
+-> { "execute": "log-dirty-bitmap-get-tuning" }
+<- { "return": {
+"currepoch": 3
+"epochs": 100
+"frequency": 100 } }
+EQMP
diff --git a/savevm.c b/savevm.c
index d22771c..260c919 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1495,6 +1495,32 @@ void qmp_log_dirty_bitmap_set_frequency(int64_t 
frequency, Error **errp)
 b->current_frequency = frequency;
 }
 
+BitmapLogStateInfo *qmp_log_dirty_bitmap_get_tuning(Error **errp)
+{
+BitmapLogState *b = logging_current_state();
+BitmapLogStateInfo *info = NULL;
+
+if (!runstate_check(RUN_STATE_DUMP_BITMAP) ||
+b->state != LOG_BITMAP_STATE_ACTIVE) {
+return info;
+}
+
+info = g_malloc0(sizeof(BitmapLogStateInfo));
+info->currepoch = b->current_epoch;
+info->epochs = b->total_epochs;
+info->frequency = b->current_frequency;
+
+if (!runstate_check(RUN_STATE_DUMP_BITMAP) ||
+b->state != LOG_BITMAP_STATE_ACTIVE) {
+g_free(info);
+info = NULL;
+error_setg(errp, "Dirty bitmap dump process is not running\n");
+return info;
+};
+
+return info;
+}
+
 void qmp_xen_save_devices_state(const char *filename, Error **errp)
 {
 QEMUFile *f;
-- 
1.9.3




[Qemu-devel] [PATCH] block/quorum: implement .bdrv_co_get_block_status

2014-07-17 Thread Liu Yuan
- allow drive-mirror to create sprase mirror on images like qcow2
- allow qemu-img map to work as expected on quorum driver

Cc: Benoit Canet 
Cc: Kevin Wolf 
Cc: Stefan Hajnoczi 
Signed-off-by: Liu Yuan 
---
 block/quorum.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/block/quorum.c b/block/quorum.c
index ebf5c71..f0d0a98 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -780,6 +780,21 @@ static coroutine_fn int quorum_co_flush(BlockDriverState 
*bs)
 return result;
 }
 
+static int64_t coroutine_fn quorum_co_get_block_status(BlockDriverState *bs,
+   int64_t sector_num,
+   int nb_sectors,
+   int *pnum)
+{
+BDRVQuorumState *s = bs->opaque;
+BlockDriverState *child_bs = s->bs[0];
+
+if (child_bs->drv->bdrv_co_get_block_status)
+return child_bs->drv->bdrv_co_get_block_status(child_bs, sector_num,
+   nb_sectors, pnum);
+
+return bdrv_get_block_status(child_bs, sector_num, nb_sectors, pnum);
+}
+
 static bool quorum_recurse_is_first_non_filter(BlockDriverState *bs,
BlockDriverState *candidate)
 {
@@ -1038,6 +1053,7 @@ static BlockDriver bdrv_quorum = {
 .bdrv_close = quorum_close,
 
 .bdrv_co_flush_to_disk  = quorum_co_flush,
+.bdrv_co_get_block_status   = quorum_co_get_block_status,
 
 .bdrv_getlength = quorum_getlength,
 
-- 
1.9.1




Re: [Qemu-devel] latest rc: virtio-blk hangs forever after migration

2014-07-17 Thread Marcin Gibuła

Yes, exactly. ISCSI-based setup can take some minutes to deploy, given
prepared image, and I have one hundred percent hit rate for the
original issue with it.


I've reproduced your IO hang with 2.0 and both
9b1786829aefb83f37a8f3135e3ea91c56001b56 and
a096b3a6732f846ec57dc28b47ee9435aa0609bf applied.

Reverting 9b1786829aefb83f37a8f3135e3ea91c56001b56 indeed fixes the
problem (but reintroduces block-migration hang). It's seems like qemu
bug rather than guest problem, as no-kvmclock parameters makes no
difference. IO just stops, all qemu IO threads die off. Almost like it
forgets to migrate them:-)

I'm attaching backtrace from guest kernel and qemu and qemu command line.

Going to compile 2.1-rc.


2.1-rc2 behaves exactly the same.

Interestingly enough, reseting guest system causes I/O to work again. So 
it's not qemu that hangs on IO, rather it fails to notify guest about 
completed operations that were issued during migration.


And its somehow caused by calling cpu_synchronize_all_states() inside 
kvmclock_vm_state_change().




As for testing with cache=writeback, I'll try to setup some iscsi to 
test it.


--
mg



Re: [Qemu-devel] latest rc: virtio-blk hangs forever after migration

2014-07-17 Thread Andrey Korolyov
On Thu, Jul 17, 2014 at 3:54 PM, Marcin Gibuła  wrote:
>>> Yes, exactly. ISCSI-based setup can take some minutes to deploy, given
>>> prepared image, and I have one hundred percent hit rate for the
>>> original issue with it.
>>
>>
>> I've reproduced your IO hang with 2.0 and both
>> 9b1786829aefb83f37a8f3135e3ea91c56001b56 and
>> a096b3a6732f846ec57dc28b47ee9435aa0609bf applied.
>>
>> Reverting 9b1786829aefb83f37a8f3135e3ea91c56001b56 indeed fixes the
>> problem (but reintroduces block-migration hang). It's seems like qemu
>> bug rather than guest problem, as no-kvmclock parameters makes no
>> difference. IO just stops, all qemu IO threads die off. Almost like it
>> forgets to migrate them:-)
>>
>> I'm attaching backtrace from guest kernel and qemu and qemu command line.
>>
>> Going to compile 2.1-rc.
>
>
> 2.1-rc2 behaves exactly the same.
>
> Interestingly enough, reseting guest system causes I/O to work again. So
> it's not qemu that hangs on IO, rather it fails to notify guest about
> completed operations that were issued during migration.
>
> And its somehow caused by calling cpu_synchronize_all_states() inside
> kvmclock_vm_state_change().
>
>
>
> As for testing with cache=writeback, I'll try to setup some iscsi to test
> it.

Awesome, thanks! AFAIK you`ll not be able to use write cache with
iscsi for migration. VM which had a reset before hangs always when
freshly launched have a chance to be migrated successfully. And yes,
it looks like lower layer forgetting to notify driver about some
operations at a glance.

>
> --
> mg



Re: [Qemu-devel] status for rc3/release

2014-07-17 Thread Paolo Bonzini
Il 17/07/2014 11:45, Peter Maydell ha scritto:
> So we just released rc2. The proposed schedule has
> rc3 next Tuesday, with final release the Tuesday after.
> 
> My thought is that we should aim for rc3 to add only
> a fairly small number of focussed and "safe" bugfixes,
> with the intention of making the final release be the
> same as rc3 if no showstopper bugs are discovered.

Here is my queue:

Andreas Färber (2):
  module: Simplify module_load()
  module: Don't complain when a module is absent

==> you already acked these

Nikolay Nikolaev (2):
  vhost-user: Fix VHOST_SET_MEM_TABLE processing
  qtest: Adapt vhost-user-test to latest vhost-user changes

==> fix for a feature in 2.1

Paolo Bonzini (3):
  qtest: new test for wdt_ib700

==> are more tests welcome at this stage?

  Revert "kvmclock: Ensure proper env->tsc value for kvmclock_current_nsec 
calculation"
  Revert "kvmclock: Ensure time in migration never goes backward"

==> revert a buggy fix introduced in 2.1

Ricky Zhou (1):
  target-i386: Allow execute from user mode when SMEP is enabled.

==> fix for a 2.1 regression



Re: [Qemu-devel] [PULL for-2.1] migration: detect section renames in vmstate static checker script

2014-07-17 Thread Peter Maydell
On 16 July 2014 10:11, Amit Shah  wrote:
> Hi,
>
> A minor enhancement to the static checker script that detects section
> renames.  One such rename was added recently (ICH9-LPC -> ICH9 LPC).
>
> This doesn't affect the qemu code, and enhances a test program, so I
> recommend we pull it for 2.1.  Patch has been on list for a few days.
>
> The following changes since commit 5a7348045091a2bc15d85bb177e5956aa6114e5a:
>
>   Update version for v2.1.0-rc2 release (2014-07-15 18:55:37 +0100)
>
> are available in the git repository at:
>
>   git://git.kernel.org/pub/scm/virt/qemu/amit/migration.git for-2.1
>
> for you to fetch changes up to 79fe16c0489ca658f53796206067a551fc915ba2:
>
>   vmstate static checker: detect section renames (2014-07-16 14:29:34 +0530)
>
> 
> Amit Shah (1):
>   vmstate static checker: detect section renames
>
>  scripts/vmstate-static-checker.py | 27 ++-
>  1 file changed, 22 insertions(+), 5 deletions(-)

Applied, thanks.

PS: if you're sending pull requests you need to actively
edit out the '---' and following comments from your commit
messages, since they won't get deleted as they would for
somebody applying a patch from email. (I didn't bother
asking you to fix and resend as the commentary in this
case is pretty minor.)

thanks
-- PMM



Re: [Qemu-devel] [PULL for-2.1] virtio-rng: Fix abort on invalid input

2014-07-17 Thread Peter Maydell
On 16 July 2014 10:13, Amit Shah  wrote:
> Hi,
>
> This patch returns an error instead of aborting, which is desirable
> not just for cmdline invocation, but prevents an abort in case of
> device hotplug.
>
> Patch is small, and reviewed on-list.
>
> Please pull,
>
> The following changes since commit 5a7348045091a2bc15d85bb177e5956aa6114e5a:
>
>   Update version for v2.1.0-rc2 release (2014-07-15 18:55:37 +0100)
>
> are available in the git repository at:
>
>   git://git.kernel.org/pub/scm/virt/qemu/amit/virtio-rng.git for-2.1
>
> for you to fetch changes up to 9ef6be93250e46d35062c84d5c75c7cb515dc27c:
>
>   virtio-rng: Add human-readable error message for negative max-bytes 
> parameter (2014-07-16 14:25:29 +0530)

Hi. I'm afraid this doesn't build on 32-bit hosts:

CC hw/virtio/virtio-rng.o
/root/qemu/hw/virtio/virtio-rng.c: In function 'virtio_rng_device_realize':
/root/qemu/hw/virtio/virtio-rng.c:186:19: error: format '%lld' expects
argument of type 'long long int', but argument 7 has type 'long int'
[-Werror=format]
cc1: all warnings being treated as errors

I think you want "(int64_t)0" rather than "0L".

thanks
-- PMM



Re: [Qemu-devel] [PATCH] Tap: fix vcpu long time io blocking on tap

2014-07-17 Thread Stefan Hajnoczi
On Fri, Jul 11, 2014 at 01:05:30AM +, Wangkai (Kevin,C) wrote:
> When used a tap as net driver for vm, if too many packets was delivered to 
> the 
> guest os via tap interface, the guest os will be blocked on io events for a 
> long
> time, while tap driver was busying process packets.

Please tweak this description to explain clearly that the tap_send()
loop can execute for a very long time if more packets are received by
the host during tap_send().

It seems that the guest does not require the QEMU global mutex often
during virtio-net receive, otherwise the rx virtqueue would fill up and
tap_send() would return.

> diff --git a/net/tap.c b/net/tap.c
> index a40f7f0..df9a0eb 100644
> --- a/net/tap.c
> +++ b/net/tap.c
> @@ -189,6 +189,7 @@ static void tap_send(void *opaque)
>  {
>  TAPState *s = opaque;
>  int size;
> +int pkt = 0;
>  
>  while (qemu_can_send_packet(&s->nc)) {
>  uint8_t *buf = s->buf;
> @@ -210,6 +211,11 @@ static void tap_send(void *opaque)
>  } else if (size < 0) {
>  break;
>  }
> +
> +/* limit io block time slice for 50 packets */
> +pkt++;
> +if (pkt >= 50)
> +break;

Please use scripts/checkpatch.pl to check coding style.  QEMU always
uses curlies around if statement bodies, even when they are only one
line.


pgpzx6epjOO7a.pgp
Description: PGP signature


[Qemu-devel] [PATCH for-2.1] scsi: fix scsi disk symbol confusion in guest os

2014-07-17 Thread arei.gonglei
From: Gonglei 

Assuming that we hotplug three virtio-scsi disk as follow steps:
1. start vm with virtio-scsi as system disk (guest os: suse11 sp3 ).
2. hotplug disk 1 (as lun2)
 -drive 
file=/Images/TestImg/kvm-disk-scsi_001,if=none,id=drive-scsi0-0-0-2,format=raw, 
\
 cache=none,aio=native -device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=2, \
 drive=drive-scsi0-0-0-2,id=scsi0-0-0-2
2. hotplug disk 2 (as lun3)
 -drive 
file=/Images/TestImg/kvm-disk-scsi_002,if=none,id=drive-scsi0-0-0-3,format=raw,\
 cache=none,aio=native -device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=3,\
 drive=drive-scsi0-0-0-3,id=scsi0-0-0-3
3. hotplug disk 3 (as lun4)
 -drive 
file=/Images/TestImg/kvm-disk-scsi_003,if=none,id=drive-scsi0-0-0-4,format=raw,\
 cache=none,aio=native -device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=4,\
 drive=drive-scsi0-0-0-4,id=scsi0-0-0-4

We can see lun2 as sdb, lun3 as sdc, lun4 as sdd in the guest os.
But after rebootint the guest, the scsi disk symbol will changed,
lun2 change to sdd, lun3 as sdc, lun4 as sdb.

Lun2 -> sdb   rebootlun2 -> sdd
Lun3 -> sdc   -->   lun3 -> sdc
Lun4 -> sdd lun4 -> sdb

In Linux os, the scsi_scan_host() will scan scsi host adapter's lun, firstly 
scan lun 0
and add into system, secondly send REPORT_LUNS command to qurey the other luns.

In QEMU, the scsi_target_emulate_report_luns() emulate the REPORT_LUNS command.
The function will scan virtio-scsi-bus's children and report to guest os 
finally.
 QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) {

The step of attaching device in QEMU:
 qdev_device_add
   qdev_set_parent_bus
  bus_add_child
  QTAILQ_INSERT_HEAD(&bus->children, kid, sibling); // insert list head

The latest hotplugged disk is at the head of bus->children list.

Finally those cause the disk symbol confusion in the guest os.

Fix the issue by QTAILQ_FOREACH_REVERSE replace QTAILQ_FOREACH in
scsi_target_emulate_report_luns(), which follow the FIFO principle for
scsi disks hotplugging.

Signed-off-by: Gonglei 
---
 hw/scsi/scsi-bus.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 4341754..b6671ea 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -371,7 +371,8 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq 
*r)
 memset(r->buf, 0, len);
 stl_be_p(&r->buf[0], n);
 i = found_lun0 ? 8 : 16;
-QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) {
+QTAILQ_FOREACH_REVERSE(kid, &r->req.bus->qbus.children,
+   ChildrenHead, sibling) {
 DeviceState *qdev = kid->child;
 SCSIDevice *dev = SCSI_DEVICE(qdev);
 
-- 
1.7.12.4





Re: [Qemu-devel] [PATCH for-2.1? 2/2] thread-pool: avoid deadlock in nested aio_poll() calls

2014-07-17 Thread Stefan Hajnoczi
On Tue, Jul 15, 2014 at 05:21:21PM +0200, Paolo Bonzini wrote:
> Il 15/07/2014 16:37, Stefan Hajnoczi ha scritto:
> >>> This is of course missing here:
> >>>
> >>>   break;
> >Let's keep goto restart so we don't use the BH for each completion
> >callback.  We just need the BH scheduled once to protect against the
> >deadlock.
> 
> Ah, I missed this remark.
> 
> Then you could add qemu_bh_cancel at the end of the BH handler.

No, because a worker thread could be completing a work item just as we
leave the BH handler.  Then the BH would be cancelled and the work item
completion would never get executed (until the next work item
completes).

This is why I needed the atomic completion_token.  That way I could
check whether more requests completed while we were in the BH handler.

Stefan


pgphqlnHvw5VO.pgp
Description: PGP signature


[Qemu-devel] [Bug 1307473] Re: guest hang due to missing clock interrupt

2014-07-17 Thread Paolo Bonzini
** No longer affects: qemu

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

Title:
  guest hang due to missing clock interrupt

Status in “linux” package in Ubuntu:
  Confirmed
Status in “qemu” package in Ubuntu:
  Confirmed

Bug description:
  
  I noticed on 2 different systems that after upgrade from precise to latest 
trusty VMs are crashing:

  - in case of Windows VMs I'm getting BSOD with error message: "A clock 
interrupt was not received on a secondary processor within the allocated time 
interval."
  - On linux VMs I'm noticing "hrtimer: interrupt took 2992229 ns" messages 
  - On some proprietary virtual appliances I'm noticing crashes an due to 
missing timer interrupts

  QEMU version is:
  QEMU emulator version 1.7.91 (Debian 2.0.0~rc1+dfsg-0ubuntu3)

  Full command line:

  qemu-system-x86_64 -enable-kvm -name win7eval -S -machine pc-
  i440fx-1.7,accel=kvm,usb=off -cpu host -m 4096 -realtime mlock=off
  -smp 4,sockets=1,cores=4,threads=1 -uuid 05e5089a-
  4aa1-6bb2-ef06-ab4d020a -no-user-config -nodefaults -chardev
  
socket,id=charmonitor,path=/var/lib/libvirt/qemu/win7eval.monitor,server,nowait
  -mon chardev=charmonitor,id=monitor,mode=control -rtc base=localtime
  -no-shutdown -boot strict=on -device piix3-usb-
  uhci,id=usb,bus=pci.0,addr=0x1.0x2 -drive
  file=/var/vm/win7eval.qcow2,if=none,id=drive-virtio-disk0,format=qcow2
  -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=drive-virtio-
  disk0,id=virtio-disk0,bootindex=1 -drive
  file=/home/damarion/iso/7600.16385.090713-1255_x86fre_enterprise_en-
  us_EVAL_Eval_Enterprise-GRMCENEVAL_EN_DVD.iso,if=none,id=drive-
  ide0-0-0,readonly=on,format=raw -device ide-cd,bus=ide.0,unit=0,drive
  =drive-ide0-0-0,id=ide0-0-0 -drive file=/home/damarion/iso/virtio-
  win-0.1-74.iso,if=none,id=drive-ide0-1-0,readonly=on,format=raw
  -device ide-cd,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
  -netdev tap,fd=24,id=hostnet0 -device
  e1000,netdev=hostnet0,id=net0,mac=52:54:00:38:31:0a,bus=pci.0,addr=0x3
  -chardev pty,id=charserial0 -device isa-
  serial,chardev=charserial0,id=serial0 -device usb-tablet,id=input0
  -vnc 127.0.0.1:1 -device VGA,id=video0,bus=pci.0,addr=0x2 -device
  virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1307473/+subscriptions



Re: [Qemu-devel] status for rc3/release

2014-07-17 Thread Frederic Konrad

On 17/07/2014 11:45, Peter Maydell wrote:

So we just released rc2. The proposed schedule has
rc3 next Tuesday, with final release the Tuesday after.

My thought is that we should aim for rc3 to add only
a fairly small number of focussed and "safe" bugfixes,
with the intention of making the final release be the
same as rc3 if no showstopper bugs are discovered.
If there are any showstoppers in rc3 we have a week
to fix them and roll and test an rc4.

Does it seem to other people like we're on track for that?
I don't do the level of testing that I think Anthony had
access to, so I'm reliant on those of you doing testing
of the rc tarballs to report problems...

thanks
-- PMM


Hi,

Is it possible to include the "cadence_uart: check serial backend before 
using it."

bug fix.

I think it's relatively safe.

Thanks,
Fred



Re: [Qemu-devel] [PATCH for-2.1] qcow2: Fix error path for unknown incompatible features

2014-07-17 Thread Eric Blake
On 07/17/2014 03:41 AM, Kevin Wolf wrote:
> qcow2's report_unsupported_feature() had two bugs: A 32 bit truncation
> would prevent feature table entries for bits 32-63 from being used, and
> it could assign errp multiple times if there was more than one unknown
> feature, resulting in an error_set() assertion failure.
> 
> Fix the truncation, make sure to set the error exactly once and add a
> qemu-iotests case for it.
> 
> This fixes https://bugs.launchpad.net/qemu/+bug/1342704/
> 
> Reported-by: Maria Kustova 
> Signed-off-by: Kevin Wolf 
> ---
>  block/qcow2.c   | 21 +-
>  tests/qemu-iotests/036  | 52 
> -
>  tests/qemu-iotests/036.out  | 35 ++
>  tests/qemu-iotests/qcow2.py | 15 -
>  4 files changed, 112 insertions(+), 11 deletions(-)

Reviewed-by: Eric Blake 

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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH RESEND] ui/gtk: Restore keyboard focus after Page change

2014-07-17 Thread Stefan Hajnoczi
On Tue, Jul 08, 2014 at 02:28:57PM -0400, John Snow wrote:
> (Resending for correct email addresses via MAINTAINERS ...)
> 
> In the GTK UI, after changing focus to the qemu monitor Notebook Page,
> when restoring focus to the virtual machine page, the keyboard focus is lost
> to a hidden GTK widget. Focus can only be restored to the virtual machine by
> pressing "tab" or any of the four directional arrow keys.
> 
> Clicking in the window or grabbing/ungrabbing input does not restore keyboard
> focus to the child widget.
> 
> This patch adjusts the Notebook page switching callback to automatically
> steal keyboard focus on the Page switch event, so that keyboard input
> does not appear to break or disappear after tabbing to the QEMU monitor.
> 
> Signed-off-by: John Snow 
> ---
>  ui/gtk.c | 9 ++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/ui/gtk.c b/ui/gtk.c
> index b02fcd6..2345d7e 100644
> --- a/ui/gtk.c
> +++ b/ui/gtk.c
> @@ -992,13 +992,16 @@ static void gd_menu_switch_vc(GtkMenuItem *item, void 
> *opaque)
>  {
>  GtkDisplayState *s = opaque;
>  VirtualConsole *vc = gd_vc_find_by_menu(s);
> +GtkNotebook *nb = GTK_NOTEBOOK(s->notebook);
> +GtkWidget *child;
>  gint page;
>  
>  gtk_release_modifiers(s);
>  if (vc) {
> -page = gtk_notebook_page_num(GTK_NOTEBOOK(s->notebook),
> - vc->tab_item);
> -gtk_notebook_set_current_page(GTK_NOTEBOOK(s->notebook), page);
> +page = gtk_notebook_page_num(nb, vc->tab_item);
> +gtk_notebook_set_current_page(nb, page);
> +child = gtk_notebook_get_nth_page(nb, page);
> +gtk_widget_grab_focus(child);
>  }
>  }
>  
> -- 
> 1.9.3

Ping?


pgpwRi77kCtlX.pgp
Description: PGP signature


Re: [Qemu-devel] latest rc: virtio-blk hangs forever after migration

2014-07-17 Thread Marcin Gibuła

2.1-rc2 behaves exactly the same.

Interestingly enough, reseting guest system causes I/O to work again. So
it's not qemu that hangs on IO, rather it fails to notify guest about
completed operations that were issued during migration.

And its somehow caused by calling cpu_synchronize_all_states() inside
kvmclock_vm_state_change().



As for testing with cache=writeback, I'll try to setup some iscsi to test
it.


Awesome, thanks! AFAIK you`ll not be able to use write cache with
iscsi for migration. VM which had a reset before hangs always when
freshly launched have a chance to be migrated successfully. And yes,
it looks like lower layer forgetting to notify driver about some
operations at a glance.


Andrey,

could you try attached patch? It's an incredibly ugly workaround that 
calls cpu_synchronize_all_states() in a way that bypasses lazy execution 
logic.


But it works for me. If that works for you as well, its somehow related 
to lazy execution of cpu_synchronize_all_states.


--
mg
diff -ru qemu-2.1.0-rc2/cpus.c qemu-2.1.0-rc2-fixed/cpus.c
--- qemu-2.1.0-rc2/cpus.c	2014-07-15 23:49:14.0 +0200
+++ qemu-2.1.0-rc2-fixed/cpus.c	2014-07-17 15:09:09.306696284 +0200
@@ -505,6 +505,15 @@
 }
 }
 
+void cpu_synchronize_all_states_always(void)
+{
+CPUState *cpu;
+
+CPU_FOREACH(cpu) {
+cpu_synchronize_state_always(cpu);
+}
+}
+
 void cpu_synchronize_all_post_reset(void)
 {
 CPUState *cpu;
diff -ru qemu-2.1.0-rc2/hw/i386/kvm/clock.c qemu-2.1.0-rc2-fixed/hw/i386/kvm/clock.c
--- qemu-2.1.0-rc2/hw/i386/kvm/clock.c	2014-07-15 23:49:14.0 +0200
+++ qemu-2.1.0-rc2-fixed/hw/i386/kvm/clock.c	2014-07-17 15:08:25.627063756 +0200
@@ -126,7 +126,7 @@
 return;
 }
 
-cpu_synchronize_all_states();
+cpu_synchronize_all_states_always();
 ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data);
 if (ret < 0) {
 fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret));
diff -ru qemu-2.1.0-rc2/include/sysemu/cpus.h qemu-2.1.0-rc2-fixed/include/sysemu/cpus.h
--- qemu-2.1.0-rc2/include/sysemu/cpus.h	2014-07-15 23:49:14.0 +0200
+++ qemu-2.1.0-rc2-fixed/include/sysemu/cpus.h	2014-07-17 15:09:23.256578916 +0200
@@ -7,6 +7,7 @@
 void pause_all_vcpus(void);
 void cpu_stop_current(void);
 
+void cpu_synchronize_all_states_always(void);
 void cpu_synchronize_all_states(void);
 void cpu_synchronize_all_post_reset(void);
 void cpu_synchronize_all_post_init(void);
diff -ru qemu-2.1.0-rc2/include/sysemu/kvm.h qemu-2.1.0-rc2-fixed/include/sysemu/kvm.h
--- qemu-2.1.0-rc2/include/sysemu/kvm.h	2014-07-15 23:49:14.0 +0200
+++ qemu-2.1.0-rc2-fixed/include/sysemu/kvm.h	2014-07-17 15:11:54.855303171 +0200
@@ -346,9 +346,11 @@
 #endif /* NEED_CPU_H */
 
 void kvm_cpu_synchronize_state(CPUState *cpu);
+void kvm_cpu_synchronize_state_always(CPUState *cpu);
 void kvm_cpu_synchronize_post_reset(CPUState *cpu);
 void kvm_cpu_synchronize_post_init(CPUState *cpu);
 
+
 /* generic hooks - to be moved/refactored once there are more users */
 
 static inline void cpu_synchronize_state(CPUState *cpu)
@@ -358,6 +360,13 @@
 }
 }
 
+static inline void cpu_synchronize_state_always(CPUState *cpu)
+{
+if (kvm_enabled()) {
+kvm_cpu_synchronize_state_always(cpu);
+}
+}
+
 static inline void cpu_synchronize_post_reset(CPUState *cpu)
 {
 if (kvm_enabled()) {
diff -ru qemu-2.1.0-rc2/kvm-all.c qemu-2.1.0-rc2-fixed/kvm-all.c
--- qemu-2.1.0-rc2/kvm-all.c	2014-07-15 23:49:14.0 +0200
+++ qemu-2.1.0-rc2-fixed/kvm-all.c	2014-07-17 15:14:04.884208826 +0200
@@ -1652,6 +1652,13 @@
 s->coalesced_flush_in_progress = false;
 }
 
+static void do_kvm_cpu_synchronize_state_always(void *arg)
+{
+CPUState *cpu = arg;
+
+kvm_arch_get_registers(cpu);
+}
+
 static void do_kvm_cpu_synchronize_state(void *arg)
 {
 CPUState *cpu = arg;
@@ -1669,6 +1676,11 @@
 }
 }
 
+void kvm_cpu_synchronize_state_always(CPUState *cpu)
+{
+run_on_cpu(cpu, do_kvm_cpu_synchronize_state_always, cpu);
+}
+
 void kvm_cpu_synchronize_post_reset(CPUState *cpu)
 {
 kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE);



Re: [Qemu-devel] [PATCH 01/28] blkdebug: report errors on flush too

2014-07-17 Thread Stefan Hajnoczi
On Mon, Jul 07, 2014 at 02:17:42PM -0400, John Snow wrote:
> From: Paolo Bonzini 
> 
> Signed-off-by: Paolo Bonzini 
> Signed-off-by: John Snow 
> ---
>  block/blkdebug.c | 20 
>  1 file changed, 20 insertions(+)

Assuming this doesn't break existing qemu-iotests that use blkdebug:

Reviewed-by: Stefan Hajnoczi 


pgpdzTQtGe5mf.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH 02/28] libqtest: add QTEST_LOG for debugging qtest testcases

2014-07-17 Thread Stefan Hajnoczi
On Mon, Jul 07, 2014 at 02:17:43PM -0400, John Snow wrote:
>  QDict *qtest_qmp_receive(QTestState *s)
>  {
>  QMPResponseParser qmp;
> +bool log = getenv("QTEST_LOG") != NULL;
>  
>  qmp.response = NULL;
>  json_message_parser_init(&qmp.parser, qmp_response);
> @@ -375,6 +377,9 @@ QDict *qtest_qmp_receive(QTestState *s)
>  exit(1);
>  }
>  
> +if (log) {
> +len = write(2, &c, 1);
> +}
>  json_message_parser_feed(&qmp.parser, &c, 1);
>  }

Is the QMP command also logged or are we just logging the response?

Stefan


pgpDDNLwNgXSR.pgp
Description: PGP signature


[Qemu-devel] [Bug 1335444] Re: qemu loses serial console data on EAGAIN

2014-07-17 Thread Kirill Batuzov
v2.1.0-rc2 has both patches.

** Changed in: qemu
   Status: New => Fix Committed

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

Title:
  qemu loses serial console data on EAGAIN

Status in QEMU:
  Fix Committed

Bug description:
  When running a guest OS with a serial console under "qemu-system-i386
  -nographic", parts of the serial console output are sometimes lost.

  This happens when a write() to standard output by qemu returns EAGAIN,
  as may be the case when the guest is generating console output faster
  than the tty (or pty/pipe/socket, etc.) connected to qemu's standard
  output accepts it.  The bug affects all releases of qemu since 1.5,
  which was the first version to set stdout to O_NONBLOCK mode.  Version
  1.4.2 and earlier work correctly.

  To reproduce the bug, you will need a guest OS configured with a
  serial console, and a host with a slow tty.  Two different methods
  of setting this up are outlined below.

  
  Method 1

  This fully automated test uses the "pexpect" Python module to run qemu
  under a pty, with an Aboriginal Linux guest.  A "seq" command is sent
  to the guest to generate 100,000 lines of output containing sequential
  integers, and the output is checked for gaps.  The script limits the
  tty output rate by occasionally sleeping for 1/10 of a second.

  Run the following commands in a Bourne shell:

  wget 
http://landley.net/aboriginal/downloads/binaries/system-image-i686.tar.bz2
  bunzip2 test.py
  #!/usr/bin/python
  import sys
  import time
  import pexpect
  n = 10
  child = pexpect.spawn('./run-emulator.sh', logfile = sys.stderr)
  child.expect("/home #")
  child.send("seq -f '<%%08.0f>' 0 %d\r" % (n - 1))
  for i in range(n):
  child.expect("<([0-9]+)>", timeout = 5)
  got = int(child.match.group(1))
  if got != i:
  print >>sys.stderr, "\nFAIL: expected %d, got %d" % (i, got)
  sys.exit(1)
  if i % 100 == 0:
  time.sleep(0.1)
  child.send("exit")
  print >>sys.stderr, "\nPASS"
  sys.exit(0)
  END
  python test.py

  This will output PASS if the console output contains the 100,000
  sequential integers as expected, or FAIL if parts of the output
  are missing due to the bug.

  
  Method 2

  This method does not require Python or pexpect.  Instead, the qemu source
  is modified to simulate a simulate a slow tty by forcing an EAGAIN return
  from every other write().  If qemu were working correctly, this
  change would not cause any data loss, because the writes would be
  retried, but in actuality, they are not retried, and the end result is
  that every other character in the guest output will be missing.

  Apply the following patch to the qemu source (this is against 2.0.0):

  --- ../qemu-2.0.0.orig/qemu-char.c  2014-04-17 16:44:45.0 +0300
  +++ ./qemu-char.c   2014-06-20 16:47:18.0 +0300
  @@ -779,6 +779,17 @@
   size_t offset = 0;
   GIOStatus status = G_IO_STATUS_NORMAL;

  +/*
  + * Simulate a tty with a limited output buffer by returning
  + * EAGAIN on every second call.
  + */
  +static unsigned int toggle = 0;
  +toggle++;
  +if (toggle & 1) {
  +   errno = EAGAIN;
  +   return -1;
  +}
  +
   while (offset < len && status == G_IO_STATUS_NORMAL) {
   gsize bytes_written = 0;

  Build and install qemu.

  Run any serial console guest.  You could use the same Aboriginal Linux image
  as in Method 1, or for example the PLD RescueCD:

wget http://rescuecd.pld-linux.org/download/2011-02-12/x86/RCDx86_11_02.iso
qemu-system-i386 -nographic -cdrom RCDx86_11_02.iso

  If this command is run with an unmodified qemu, a set of boot messages
  will appear, starting with:

ISOLINUX 4.03 2010-10-22  Copyright (C) 1994-2010 H. Peter Anvin et
  al

  When qemu has been patched to simulate EAGAIN returns, every other
  character in the boot messages will be missing, so that the first line
  of output will instead read:

SLNX40 001-2 oyih C 9421 .PtrAvne l

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



[Qemu-devel] [RFC PATCH v2 03/49] pcspk: adding vmstate for save/restore

2014-07-17 Thread Pavel Dovgalyuk
VMState added by this patch preserves correct
loading of the PC speaker device state.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/audio/pcspk.c |   19 +--
 1 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c
index 1d81bbe..2afcffb 100644
--- a/hw/audio/pcspk.c
+++ b/hw/audio/pcspk.c
@@ -50,8 +50,8 @@ typedef struct {
 unsigned int pit_count;
 unsigned int samples;
 unsigned int play_pos;
-int data_on;
-int dummy_refresh_clock;
+uint8_t data_on;
+uint8_t dummy_refresh_clock;
 } PCSpkState;
 
 static const char *s_spk = "pcspk";
@@ -163,6 +163,19 @@ static const MemoryRegionOps pcspk_io_ops = {
 },
 };
 
+static const VMStateDescription vmstate_spk = {
+.name = "pcspk",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields  = (VMStateField []) {
+//VMSTATE_UINT32(play_pos, PCSpkState),
+VMSTATE_UINT8(data_on, PCSpkState),
+VMSTATE_UINT8(dummy_refresh_clock, PCSpkState),
+VMSTATE_END_OF_LIST()
+}
+};
+
 static void pcspk_initfn(Object *obj)
 {
 PCSpkState *s = PC_SPEAKER(obj);
@@ -175,6 +188,8 @@ static void pcspk_realizefn(DeviceState *dev, Error **errp)
 ISADevice *isadev = ISA_DEVICE(dev);
 PCSpkState *s = PC_SPEAKER(dev);
 
+vmstate_register(NULL, 0, &vmstate_spk, s);
+
 isa_register_ioport(isadev, &s->ioport, s->iobase);
 
 pcspk_state = s;




[Qemu-devel] [RFC PATCH v2 04/49] fdc: adding vmstate for save/restore

2014-07-17 Thread Pavel Dovgalyuk
VMState added by this patch preserves correct
loading of the FDC device state.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/block/fdc.c |   11 +--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 490d127..132310a 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -697,12 +697,17 @@ static const VMStateDescription vmstate_fdrive_media_rate 
= {
 
 static const VMStateDescription vmstate_fdrive = {
 .name = "fdrive",
-.version_id = 1,
+.version_id = 2,
 .minimum_version_id = 1,
 .fields = (VMStateField[]) {
 VMSTATE_UINT8(head, FDrive),
 VMSTATE_UINT8(track, FDrive),
 VMSTATE_UINT8(sect, FDrive),
+VMSTATE_UINT8_V(last_sect, FDrive, 2),
+VMSTATE_UINT8_V(max_track, FDrive, 2),
+VMSTATE_UINT16_V(bps, FDrive, 2),
+VMSTATE_UINT8_V(ro, FDrive, 2),
+VMSTATE_UINT8_V(perpendicular, FDrive, 2),
 VMSTATE_END_OF_LIST()
 },
 .subsections = (VMStateSubsection[]) {
@@ -736,7 +741,7 @@ static int fdc_post_load(void *opaque, int version_id)
 
 static const VMStateDescription vmstate_fdc = {
 .name = "fdc",
-.version_id = 2,
+.version_id = 3,
 .minimum_version_id = 2,
 .pre_save = fdc_pre_save,
 .post_load = fdc_post_load,
@@ -769,6 +774,8 @@ static const VMStateDescription vmstate_fdc = {
 VMSTATE_UINT8_EQUAL(num_floppies, FDCtrl),
 VMSTATE_STRUCT_ARRAY(drives, FDCtrl, MAX_FD, 1,
  vmstate_fdrive, FDrive),
+VMSTATE_INT32_V(reset_sensei, FDCtrl, 3),
+VMSTATE_TIMER_V(result_timer, FDCtrl, 3),
 VMSTATE_END_OF_LIST()
 }
 };




[Qemu-devel] [RFC PATCH v2 01/49] acpi: accurate overflow check

2014-07-17 Thread Pavel Dovgalyuk
Compare clock in ns, because acpi_pm_tmr_update uses rounded
to ns value instead of ticks.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/acpi/core.c |7 +--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index a7368fb..f7272b4 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -376,8 +376,11 @@ static void acpi_notify_wakeup(Notifier *notifier, void 
*data)
 /* ACPI PM1a EVT */
 uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar)
 {
-int64_t d = acpi_pm_tmr_get_clock();
-if (d >= ar->tmr.overflow_time) {
+/* Compare ns-clock, not PM timer ticks, because 
+   acpi_pm_tmr_update function uses ns for setting the timer. */
+int64_t d = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+if (d >= muldiv64(ar->tmr.overflow_time, 
+  get_ticks_per_sec(), PM_TIMER_FREQUENCY)) {
 ar->pm1.evt.sts |= ACPI_BITMASK_TIMER_STATUS;
 }
 return ar->pm1.evt.sts;




[Qemu-devel] [RFC PATCH v2 00/49] Series short description

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

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.

Reverse execution 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, mouse, 
network adapters,
   audio devices, serial interfaces, and physical USB devices connected to the 
emulator.
 * Provides support for gdb reverse debugging commands like reverse-step and 
reverse-continue.
 * Supports auto-checkpointing for convenient reverse debugging.

Usage of the record/replay:
 * First, record the execution, by adding '-record fname=replay.bin' to the
   command line.
 * Then you can replay it for the multiple times by using another command
   line option: '-replay fname=replay.bin'
 * Virtual machine should have at least one virtual disk, which is used to
   store checkpoints. If you want to enable automatic checkpointing, simply
   add ',period=XX' to record options, where XX is the checkpointing period
   in seconds.
 * Using of the network adapters in record/replay mode is possible with 
   the following command-line options:
   - '-net user' (or another host adapter) in record mode
   - '-net replay' in replay mode. Every host network adapter should be
 replaced by 'replay' when replaying the execution.
 * Reverse debugging can be used through gdb remote interface.
   reverse-stepi and reverse-continue commands are supported. Other reverse
   commands should also work, because they reuse these ones.
 * Monitor is extended by the following commands:
   - replay_info - prints information about replay mode and current step
 (number of instructions executed)
   - replay_break - sets "breakpoint" at the specified instructions count.
   - replay_seek - rewinds (using the checkpoints, if possible) to the
 specified step of replay log.

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:
 * adding missed fields of the virtual devices' states to the vmstate 
   structures to allow deterministic saving and restoring the VM state
 * adding virtual clock-based timers to vmstate structures, because virtual 
   clock is the part of the virtual machine state
 * modification of block layer to support automatic creation of the overlay
   files to store the changes and snapshots while recording
 * disabling of system reset while loading VM state to avoid generating of
   interrupts by reset handlers
 * adding warpers 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), input from virtual
   serial ports, incoming network packets, input from connected USB devices
 * adding HMP/QMP commands to monitor for controlling replay execution

v2 changes:
 * Patches are split to be reviewable and bisectable (as suggested by Kirill 
Batuzov)
 * Added QMP versions of replay commands (as suggested by Eric Blake)
 * Removed some optional features of replay to make patches cleaner
 * Minor changes and code cleanup were made

---

Pavel Dovgalyuk (49):
  acpi: accurate overflow check
  integratorcp: adding vmstate for save/restore
  pcspk: adding vmstate for save/restore
  fdc: adding vmstate for save/restore
  parallel: adding vmstate for save/restore
  serial: fixing vmstate for save/restore
  kvmapic: fixing loading vmstate
  hpet: fixing saving and loading process
  pckbd: adding new fields to vmstate
  rtl8139: adding new fields to vmstate
  piix: do not raise irq while loading vmstate
  mc146818rtc: add missed field to vmstate
  pl031: add missed field to vmstate
  ide pci: reset status field before loading the vmstate
  softmmu: fixing usage of cpu_st/ld* from helpers
  target: save cpu state fields
  target-i386: update fp status fix
  migration: add vmstate for int8 and char arrays
  replay: global variables and function stubs
   

[Qemu-devel] [RFC PATCH v2 09/49] pckbd: adding new fields to vmstate

2014-07-17 Thread Pavel Dovgalyuk
This patch adds outport to VMState to allow correct saving and restoring
the state of PC keyboard controller.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/input/pckbd.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
index ca1cffc..19f6658 100644
--- a/hw/input/pckbd.c
+++ b/hw/input/pckbd.c
@@ -371,13 +371,14 @@ static void kbd_reset(void *opaque)
 
 static const VMStateDescription vmstate_kbd = {
 .name = "pckbd",
-.version_id = 3,
+.version_id = 4,
 .minimum_version_id = 3,
 .fields = (VMStateField[]) {
 VMSTATE_UINT8(write_cmd, KBDState),
 VMSTATE_UINT8(status, KBDState),
 VMSTATE_UINT8(mode, KBDState),
 VMSTATE_UINT8(pending, KBDState),
+VMSTATE_UINT8_V(outport, KBDState, 4),
 VMSTATE_END_OF_LIST()
 }
 };




[Qemu-devel] [RFC PATCH v2 06/49] serial: fixing vmstate for save/restore

2014-07-17 Thread Pavel Dovgalyuk
Some fields were added to VMState by this patch to preserve correct
loading of the serial port controller state.
Updating FCR value while loading was also modified to disable generating
an interrupt by loadvm.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/char/serial.c |  115 --
 1 files changed, 69 insertions(+), 46 deletions(-)

diff --git a/hw/char/serial.c b/hw/char/serial.c
index 54180a9..1969723 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -267,6 +267,61 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition 
cond, void *opaque)
 }
 
 
+/* Setter for FCR.
+   is_load flag means, that value is set while loading VM state
+   and interrupt should not be invoked */
+static void serial_write_fcr(void *opaque, uint32_t val, int is_load)
+{
+SerialState *s = opaque;
+val = val & 0xFF;
+
+if (s->fcr == val)
+return;
+
+/* Did the enable/disable flag change? If so, make sure FIFOs get flushed 
*/
+if ((val ^ s->fcr) & UART_FCR_FE)
+val |= UART_FCR_XFR | UART_FCR_RFR;
+
+/* FIFO clear */
+
+if (val & UART_FCR_RFR) {
+timer_del(s->fifo_timeout_timer);
+s->timeout_ipending=0;
+fifo8_reset(&s->recv_fifo);
+}
+
+if (val & UART_FCR_XFR) {
+fifo8_reset(&s->xmit_fifo);
+}
+
+if (val & UART_FCR_FE) {
+s->iir |= UART_IIR_FE;
+/* Set recv_fifo trigger Level */
+switch (val & 0xC0) {
+case UART_FCR_ITL_1:
+s->recv_fifo_itl = 1;
+break;
+case UART_FCR_ITL_2:
+s->recv_fifo_itl = 4;
+break;
+case UART_FCR_ITL_3:
+s->recv_fifo_itl = 8;
+break;
+case UART_FCR_ITL_4:
+s->recv_fifo_itl = 14;
+break;
+}
+} else
+s->iir &= ~UART_IIR_FE;
+
+/* Set fcr - or at least the bits in it that are supposed to "stick" */
+s->fcr = val & 0xC9;
+
+if (!is_load) {
+serial_update_irq(s);
+}
+}
+
 static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
 unsigned size)
 {
@@ -320,50 +375,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, 
uint64_t val,
 }
 break;
 case 2:
-val = val & 0xFF;
-
-if (s->fcr == val)
-break;
-
-/* Did the enable/disable flag change? If so, make sure FIFOs get 
flushed */
-if ((val ^ s->fcr) & UART_FCR_FE)
-val |= UART_FCR_XFR | UART_FCR_RFR;
-
-/* FIFO clear */
-
-if (val & UART_FCR_RFR) {
-timer_del(s->fifo_timeout_timer);
-s->timeout_ipending=0;
-fifo8_reset(&s->recv_fifo);
-}
-
-if (val & UART_FCR_XFR) {
-fifo8_reset(&s->xmit_fifo);
-}
-
-if (val & UART_FCR_FE) {
-s->iir |= UART_IIR_FE;
-/* Set recv_fifo trigger Level */
-switch (val & 0xC0) {
-case UART_FCR_ITL_1:
-s->recv_fifo_itl = 1;
-break;
-case UART_FCR_ITL_2:
-s->recv_fifo_itl = 4;
-break;
-case UART_FCR_ITL_3:
-s->recv_fifo_itl = 8;
-break;
-case UART_FCR_ITL_4:
-s->recv_fifo_itl = 14;
-break;
-}
-} else
-s->iir &= ~UART_IIR_FE;
-
-/* Set fcr - or at least the bits in it that are supposed to "stick" */
-s->fcr = val & 0xC9;
-serial_update_irq(s);
+serial_write_fcr(s, val, 0);
 break;
 case 3:
 {
@@ -591,20 +603,22 @@ static int serial_post_load(void *opaque, int version_id)
 s->fcr_vmstate = 0;
 }
 /* Initialize fcr via setter to perform essential side-effects */
-serial_ioport_write(s, 0x02, s->fcr_vmstate, 1);
+serial_write_fcr(s, s->fcr_vmstate, 1);
 serial_update_parameters(s);
 return 0;
 }
 
 const VMStateDescription vmstate_serial = {
 .name = "serial",
-.version_id = 3,
+.version_id = 4,
 .minimum_version_id = 2,
 .pre_save = serial_pre_save,
 .post_load = serial_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_UINT16_V(divider, SerialState, 2),
 VMSTATE_UINT8(rbr, SerialState),
+VMSTATE_UINT8_V(thr, SerialState, 4),
+VMSTATE_UINT8_V(tsr, SerialState, 4),
 VMSTATE_UINT8(ier, SerialState),
 VMSTATE_UINT8(iir, SerialState),
 VMSTATE_UINT8(lcr, SerialState),
@@ -613,6 +627,15 @@ const VMStateDescription vmstate_serial = {
 VMSTATE_UINT8(msr, SerialState),
 VMSTATE_UINT8(scr, SerialState),
 VMSTATE_UINT8_V(fcr_vmstate, SerialState, 3),
+VMSTATE_INT32_V(thr_ipending, SerialState, 4),
+VMSTATE_INT32_V(last_break_enable, SerialState, 4),
+VMSTATE_INT32_V(tsr_retry, SerialState, 4),
+VMSTATE_STRUCT(recv_fifo, SerialState

[Qemu-devel] [RFC PATCH v2 07/49] kvmapic: fixing loading vmstate

2014-07-17 Thread Pavel Dovgalyuk
vapic state should not be synchronized with APIC while loading,
because APIC state could be not loaded yet at that moment.
We just save vapic_paddr in APIC VMState instead of synchronization.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/i386/kvmvapic.c|   22 +-
 hw/intc/apic_common.c |5 -
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index cb855c7..417ab6a 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -351,6 +351,24 @@ static int get_kpcr_number(X86CPU *cpu)
 return kpcr.number;
 }
 
+static int vapic_enable_post_load(VAPICROMState *s, X86CPU *cpu)
+{
+int cpu_number = get_kpcr_number(cpu);
+hwaddr vapic_paddr;
+static const uint8_t enabled = 1;
+
+if (cpu_number < 0) {
+return -1;
+}
+vapic_paddr = s->vapic_paddr +
+(((hwaddr)cpu_number) << VAPIC_CPU_SHIFT);
+cpu_physical_memory_rw(vapic_paddr + offsetof(VAPICState, enabled),
+   (void *)&enabled, sizeof(enabled), 1);
+s->state = VAPIC_ACTIVE;
+
+return 0;
+}
+
 static int vapic_enable(VAPICROMState *s, X86CPU *cpu)
 {
 int cpu_number = get_kpcr_number(cpu);
@@ -731,7 +749,9 @@ static void do_vapic_enable(void *data)
 VAPICROMState *s = data;
 X86CPU *cpu = X86_CPU(first_cpu);
 
-vapic_enable(s, cpu);
+/* Do not synchronize with APIC, because it was not loaded yet.
+   Just call the enable function which does not have synchronization. */
+vapic_enable_post_load(s, cpu);
 }
 
 static int vapic_post_load(void *opaque, int version_id)
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index ce3d903..9d75ee0 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -347,7 +347,7 @@ static int apic_dispatch_post_load(void *opaque, int 
version_id)
 
 static const VMStateDescription vmstate_apic_common = {
 .name = "apic",
-.version_id = 3,
+.version_id = 4,
 .minimum_version_id = 3,
 .minimum_version_id_old = 1,
 .load_state_old = apic_load_old,
@@ -374,6 +374,9 @@ static const VMStateDescription vmstate_apic_common = {
 VMSTATE_INT64(next_time, APICCommonState),
 VMSTATE_INT64(timer_expiry,
   APICCommonState), /* open-coded timer state */
+VMSTATE_INT32_V(sipi_vector, APICCommonState, 4),
+VMSTATE_INT32_V(wait_for_sipi, APICCommonState, 4),
+VMSTATE_UINT64_V(vapic_paddr, APICCommonState, 4),
 VMSTATE_END_OF_LIST()
 }
 };




[Qemu-devel] [RFC PATCH v2 02/49] integratorcp: adding vmstate for save/restore

2014-07-17 Thread Pavel Dovgalyuk
VMState added by this patch preserves correct
loading of the integratorcp device state.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/arm/integratorcp.c |   38 +-
 1 files changed, 37 insertions(+), 1 deletions(-)

diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index 0e476c3..496f84e 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -42,6 +42,27 @@ typedef struct IntegratorCMState {
 uint32_t fiq_enabled;
 } IntegratorCMState;
 
+static const VMStateDescription vmstate_integratorcm = {
+.name = "integratorcm",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields  = (VMStateField []) {
+VMSTATE_UINT32(cm_osc, IntegratorCMState),
+VMSTATE_UINT32(cm_ctrl, IntegratorCMState),
+VMSTATE_UINT32(cm_lock, IntegratorCMState),
+VMSTATE_UINT32(cm_auxosc, IntegratorCMState),
+VMSTATE_UINT32(cm_sdram, IntegratorCMState),
+VMSTATE_UINT32(cm_init, IntegratorCMState),
+VMSTATE_UINT32(cm_flags, IntegratorCMState),
+VMSTATE_UINT32(cm_nvflags, IntegratorCMState),
+VMSTATE_UINT32(int_level, IntegratorCMState),
+VMSTATE_UINT32(irq_enabled, IntegratorCMState),
+VMSTATE_UINT32(fiq_enabled, IntegratorCMState),
+VMSTATE_END_OF_LIST()
+}
+};
+
 static uint8_t integrator_spd[128] = {
128, 8, 4, 11, 9, 1, 64, 0,  2, 0xa0, 0xa0, 0, 0, 8, 0, 1,
0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
@@ -272,7 +293,7 @@ static int integratorcm_init(SysBusDevice *dev)
 sysbus_init_mmio(dev, &s->iomem);
 
 integratorcm_do_remap(s);
-/* ??? Save/restore.  */
+vmstate_register(NULL, -1, &vmstate_integratorcm, s);
 return 0;
 }
 
@@ -296,6 +317,20 @@ typedef struct icp_pic_state {
 qemu_irq parent_fiq;
 } icp_pic_state;
 
+
+static const VMStateDescription vmstate_icp_pic = {
+.name = "icp_pic_state",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields  = (VMStateField []) {
+VMSTATE_UINT32(level, icp_pic_state),
+VMSTATE_UINT32(irq_enabled, icp_pic_state),
+VMSTATE_UINT32(fiq_enabled, icp_pic_state),
+VMSTATE_END_OF_LIST()
+}
+};
+
 static void icp_pic_update(icp_pic_state *s)
 {
 uint32_t flags;
@@ -399,6 +434,7 @@ static int icp_pic_init(SysBusDevice *sbd)
 memory_region_init_io(&s->iomem, OBJECT(s), &icp_pic_ops, s,
   "icp-pic", 0x0080);
 sysbus_init_mmio(sbd, &s->iomem);
+vmstate_register(NULL, -1, &vmstate_icp_pic, s);
 return 0;
 }
 




[Qemu-devel] [RFC PATCH v2 45/49] replay: USB passthrough

2014-07-17 Thread Pavel Dovgalyuk
It writes all external data, returned by libusb,
to the log. This data is read in replay mode instead of calling
libusb functions.
Command line option for connecting USB device to simulator should be
specified in both record and replay modes. In replay mode only log file
is read and USB device could be not connected to the host machine.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/usb/host-libusb.c |  525 ++
 include/hw/host-libusb.h |  105 +
 replay/Makefile.objs |1 
 replay/replay-events.c   |   49 
 replay/replay-internal.h |   21 ++
 replay/replay-usb.c  |  188 
 replay/replay.c  |   29 +++
 replay/replay.h  |   30 +++
 8 files changed, 765 insertions(+), 183 deletions(-)
 create mode 100755 include/hw/host-libusb.h
 create mode 100755 replay/replay-usb.c

diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index c189147..5283c64 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -40,98 +40,15 @@
 #include "monitor/monitor.h"
 #include "sysemu/sysemu.h"
 #include "trace.h"
+#include "qemu/log.h"
+#include "replay/replay.h"
 
 #include "hw/usb.h"
+#include "hw/host-libusb.h"
 
 /*  */
 
-#define TYPE_USB_HOST_DEVICE "usb-host"
-#define USB_HOST_DEVICE(obj) \
- OBJECT_CHECK(USBHostDevice, (obj), TYPE_USB_HOST_DEVICE)
-
-typedef struct USBHostDevice USBHostDevice;
-typedef struct USBHostRequest USBHostRequest;
-typedef struct USBHostIsoXfer USBHostIsoXfer;
-typedef struct USBHostIsoRing USBHostIsoRing;
-
-struct USBAutoFilter {
-uint32_t bus_num;
-uint32_t addr;
-char *port;
-uint32_t vendor_id;
-uint32_t product_id;
-};
-
-enum USBHostDeviceOptions {
-USB_HOST_OPT_PIPELINE,
-};
-
-struct USBHostDevice {
-USBDevice parent_obj;
-
-/* properties */
-struct USBAutoFilter match;
-int32_t  bootindex;
-uint32_t iso_urb_count;
-uint32_t iso_urb_frames;
-uint32_t options;
-uint32_t loglevel;
-
-/* state */
-QTAILQ_ENTRY(USBHostDevice)  next;
-int  seen, errcount;
-int  bus_num;
-int  addr;
-char port[16];
-
-libusb_device*dev;
-libusb_device_handle *dh;
-struct libusb_device_descriptor  ddesc;
-
-struct {
-bool detached;
-bool claimed;
-} ifs[USB_MAX_INTERFACES];
-
-/* callbacks & friends */
-QEMUBH   *bh_nodev;
-QEMUBH   *bh_postld;
-Notifier exit;
-
-/* request queues */
-QTAILQ_HEAD(, USBHostRequest)requests;
-QTAILQ_HEAD(, USBHostIsoRing)isorings;
-};
-
-struct USBHostRequest {
-USBHostDevice*host;
-USBPacket*p;
-bool in;
-struct libusb_transfer   *xfer;
-unsigned char*buffer;
-unsigned char*cbuf;
-unsigned int clen;
 bool usb3ep0quirk;
-QTAILQ_ENTRY(USBHostRequest) next;
-};
-
-struct USBHostIsoXfer {
-USBHostIsoRing   *ring;
-struct libusb_transfer   *xfer;
-bool copy_complete;
-unsigned int packet;
-QTAILQ_ENTRY(USBHostIsoXfer) next;
-};
-
-struct USBHostIsoRing {
-USBHostDevice*host;
-USBEndpoint  *ep;
-QTAILQ_HEAD(, USBHostIsoXfer)unused;
-QTAILQ_HEAD(, USBHostIsoXfer)inflight;
-QTAILQ_HEAD(, USBHostIsoXfer)copy;
-QTAILQ_ENTRY(USBHostIsoRing) next;
-};
-
 static QTAILQ_HEAD(, USBHostDevice) hostdevs =
 QTAILQ_HEAD_INITIALIZER(hostdevs);
 
@@ -143,6 +60,24 @@ static void usb_host_attach_kernel(USBHostDevice *s);
 
 /*  */
 
+typedef struct USBHostTimer {
+QEMUTimer *timer;
+} USBHostTimer;
+
+USBHostTimer usb_auto_timer;
+static int submitted_xfers = 0;
+
+static const VMStateDescription vmstate_usb_host_timer = {
+.name = "usb-host-timer",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_TIMER(timer, USBHostTimer),
+VMSTATE_END_OF_LIST()
+}
+};
+
+
 #define CONTROL_TIMEOUT  1/* 10 sec*/
 #define BULK_TIMEOUT 0/* unlimited */
 #define INTR_TIMEOUT 0/* unlimited */
@@ -214,6 +149,11 @@ static void usb_host_del_fd(int fd, void *user_data)
 qemu_set_fd_handler(fd, NULL, NULL, NULL);
 }
 
+bool usb_

[Qemu-devel] [RFC PATCH v2 42/49] replay: network packets record/replay

2014-07-17 Thread Pavel Dovgalyuk
This patch implements passing network packets to replay module in
record mode. New virtual network adapter is implemented to replay the
packets when they are read from the log file.

Signed-off-by: Pavel Dovgalyuk 
---
 net/Makefile.objs|1 
 net/clients.h|3 +
 net/dump.c   |6 +
 net/hub.c|1 
 net/net-replay.c |   66 
 net/net.c|7 +-
 net/slirp.c  |   14 +++
 net/socket.c |   35 
 net/tap-win32.c  |   14 +++
 net/tap.c|   23 +-
 net/vde.c|   14 +++
 qapi-schema.json |   13 +++
 replay/Makefile.objs |1 
 replay/replay-events.c   |   17 
 replay/replay-internal.h |   21 +
 replay/replay-net.c  |  190 ++
 replay/replay.c  |5 +
 replay/replay.h  |   10 ++
 slirp/slirp.c|9 ++
 19 files changed, 436 insertions(+), 14 deletions(-)
 create mode 100755 net/net-replay.c
 create mode 100755 replay/replay-net.c

diff --git a/net/Makefile.objs b/net/Makefile.objs
index ec19cb3..def44e3 100644
--- a/net/Makefile.objs
+++ b/net/Makefile.objs
@@ -2,6 +2,7 @@ common-obj-y = net.o queue.o checksum.o util.o hub.o
 common-obj-y += socket.o
 common-obj-y += dump.o
 common-obj-y += eth.o
+common-obj-y += net-replay.o
 common-obj-$(CONFIG_L2TPV3) += l2tpv3.o
 common-obj-$(CONFIG_POSIX) += tap.o vhost-user.o
 common-obj-$(CONFIG_LINUX) += tap-linux.o
diff --git a/net/clients.h b/net/clients.h
index 2e8feda..f75f43b 100644
--- a/net/clients.h
+++ b/net/clients.h
@@ -62,4 +62,7 @@ int net_init_netmap(const NetClientOptions *opts, const char 
*name,
 int net_init_vhost_user(const NetClientOptions *opts, const char *name,
 NetClientState *peer);
 
+int net_init_replay(const NetClientOptions *opts, const char *name,
+NetClientState *peer);
+
 #endif /* QEMU_NET_CLIENTS_H */
diff --git a/net/dump.c b/net/dump.c
index 9d3a09e..962f2cd 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -28,6 +28,7 @@
 #include "qemu/log.h"
 #include "qemu/timer.h"
 #include "hub.h"
+#include "replay/replay.h"
 
 typedef struct DumpState {
 NetClientState nc;
@@ -158,6 +159,11 @@ int net_init_dump(const NetClientOptions *opts, const char 
*name,
 
 assert(peer);
 
+if (replay_mode == REPLAY_SAVE) {
+fprintf(stderr, "-net dump is not permitted in replay mode\n");
+exit(1);
+}
+
 if (dump->has_file) {
 file = dump->file;
 } else {
diff --git a/net/hub.c b/net/hub.c
index 7e0f2d6..91fdfb6 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -323,6 +323,7 @@ void net_hub_check_clients(void)
 case NET_CLIENT_OPTIONS_KIND_SOCKET:
 case NET_CLIENT_OPTIONS_KIND_VDE:
 case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
+case NET_CLIENT_OPTIONS_KIND_REPLAY:
 has_host_dev = 1;
 break;
 default:
diff --git a/net/net-replay.c b/net/net-replay.c
new file mode 100755
index 000..b184b22
--- /dev/null
+++ b/net/net-replay.c
@@ -0,0 +1,66 @@
+/*
+ * net-replay.c
+ *
+ * Copyright (c) 2010-2014 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 "net/net.h"
+#include "clients.h"
+#include "qemu-common.h"
+#include "sysemu/sysemu.h"
+#include "replay/replay.h"
+
+typedef struct NetReplayState {
+NetClientState nc;
+} NetReplayState;
+
+static ssize_t net_replay_receive(NetClientState *nc, const uint8_t *buf, 
size_t size)
+{
+return size;
+}
+
+static void net_replay_cleanup(NetClientState *nc)
+{
+}
+
+static NetClientInfo net_replay_info = {
+.type = NET_CLIENT_OPTIONS_KIND_REPLAY,
+.size = sizeof(NetReplayState),
+.receive = net_replay_receive,
+.cleanup = net_replay_cleanup,
+};
+
+static int net_replay_init(NetClientState *vlan, const char *device,
+ const char *name)
+{
+NetClientState *nc;
+
+nc = qemu_new_net_client(&net_replay_info, vlan, device, name);
+
+snprintf(nc->info_str, sizeof(nc->info_str), "replayer");
+
+if (replay_mode == REPLAY_SAVE) {
+fprintf(stderr, "-net replay is not permitted in record mode\n");
+exit(1);
+} else if (replay_mode == REPLAY_PLAY) {
+replay_add_network_client(nc);
+} else {
+fprintf(stderr, "-net replay is not permitted without replay\n");
+exit(1);
+}
+
+return 0;
+}
+
+int net_init_replay(const NetClientOptions *opts, const char *name, 
NetClientState *peer)
+{
+assert(peer);
+assert(opts->kind == NET_CLIENT_OPTIONS_KIND_REPLAY);
+
+return net_replay_init(peer, "replay", name);
+}
diff --git a/net/net.c b/net/net.c
index 6d930ea..62067f5 100644
--- a/net/net

[Qemu-devel] [RFC PATCH v2 05/49] parallel: adding vmstate for save/restore

2014-07-17 Thread Pavel Dovgalyuk
VMState added by this patch preserves correct
loading of the parallel port controller state.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/char/parallel.c |   22 ++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index 7ac90a5..bc34e55 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -477,6 +477,26 @@ static const MemoryRegionPortio 
isa_parallel_portio_sw_list[] = {
 PORTIO_END_OF_LIST(),
 };
 
+
+static const VMStateDescription vmstate_parallel_isa = {
+.name = "parallel_isa",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields  = (VMStateField []) {
+VMSTATE_UINT8(state.dataw, ISAParallelState),
+VMSTATE_UINT8(state.datar, ISAParallelState),
+VMSTATE_UINT8(state.status, ISAParallelState),
+VMSTATE_UINT8(state.control, ISAParallelState),
+VMSTATE_INT32(state.irq_pending, ISAParallelState),
+VMSTATE_INT32(state.hw_driver, ISAParallelState),
+VMSTATE_INT32(state.epp_timeout, ISAParallelState),
+VMSTATE_INT32(state.it_shift, ISAParallelState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+
 static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
 {
 static int index;
@@ -518,6 +538,8 @@ static void parallel_isa_realizefn(DeviceState *dev, Error 
**errp)
   ? &isa_parallel_portio_hw_list[0]
   : &isa_parallel_portio_sw_list[0]),
  s, "parallel");
+
+vmstate_register(NULL, -1, &vmstate_parallel_isa, isa);
 }
 
 /* Memory mapped interface */




[Qemu-devel] [RFC PATCH v2 44/49] replay: serial port

2014-07-17 Thread Pavel Dovgalyuk
This patch implements record and replay of serial ports.
In record mode serial port can be connected to the source of the data:
-serial tcp:127.0.0.1:23,nowait,server
In replay mode it should not be connected to any data source, but should be
initialized with null: -serial null

Signed-off-by: Pavel Dovgalyuk 
---
 include/sysemu/char.h|   25 
 qemu-char.c  |   55 +++---
 replay/Makefile.objs |1 
 replay/replay-char.c |   99 ++
 replay/replay-events.c   |   18 
 replay/replay-internal.h |   14 ++-
 replay/replay.c  |   14 +++
 replay/replay.h  |   13 ++
 vl.c |4 +-
 9 files changed, 236 insertions(+), 7 deletions(-)
 create mode 100755 replay/replay-char.c

diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index 0bbd631..a7eb578 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -85,6 +85,7 @@ struct CharDriverState {
 int is_mux;
 guint fd_in_tag;
 QemuOpts *opts;
+bool replay;
 QTAILQ_ENTRY(CharDriverState) next;
 };
 
@@ -126,6 +127,21 @@ CharDriverState *qemu_chr_new(const char *label, const 
char *filename,
   void (*init)(struct CharDriverState *s));
 
 /**
+ * @qemu_chr_new_replay:
+ *
+ * Create a new character backend from a URI.
+ * All recieved data will be logged by replay module.
+ *
+ * @label the name of the backend
+ * @filename the URI
+ * @init not sure..
+ *
+ * Returns: a new character backend
+ */
+CharDriverState *qemu_chr_new_replay(const char *label, const char *filename,
+ void (*init)(struct CharDriverState *s));
+
+/**
  * @qemu_chr_delete:
  *
  * Destroy a character backend.
@@ -320,6 +336,15 @@ int qemu_chr_be_can_write(CharDriverState *s);
  */
 void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
 
+/**
+ * @qemu_chr_be_write_impl:
+ *
+ * Implementation of back end writing. Used by replay module.
+ *
+ * @buf a buffer to receive data from the front end
+ * @len the number of bytes to receive from the front end
+ */
+void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len);
 
 /**
  * @qemu_chr_be_event:
diff --git a/qemu-char.c b/qemu-char.c
index 55e372c..80d4809 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -28,6 +28,7 @@
 #include "sysemu/char.h"
 #include "hw/usb.h"
 #include "qmp-commands.h"
+#include "replay/replay.h"
 
 #include 
 #include 
@@ -126,6 +127,9 @@ int qemu_chr_fe_write(CharDriverState *s, const uint8_t 
*buf, int len)
 
 qemu_mutex_lock(&s->chr_write_lock);
 ret = s->chr_write(s, buf, len);
+if (s->replay) {
+replay_data_int(&ret);
+}
 qemu_mutex_unlock(&s->chr_write_lock);
 return ret;
 }
@@ -195,9 +199,18 @@ int qemu_chr_fe_read_all(CharDriverState *s, uint8_t *buf, 
int len)
 
 int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg)
 {
-if (!s->chr_ioctl)
-return -ENOTSUP;
-return s->chr_ioctl(s, cmd, arg);
+int res;
+if (!s->chr_ioctl) {
+res = -ENOTSUP;
+} else {
+res = s->chr_ioctl(s, cmd, arg);
+if (s->replay) {
+fprintf(stderr, "Replay: ioctl is not supported for serial devices 
yet\n");
+exit(1);
+}
+}
+
+return res;
 }
 
 int qemu_chr_be_can_write(CharDriverState *s)
@@ -207,17 +220,34 @@ int qemu_chr_be_can_write(CharDriverState *s)
 return s->chr_can_read(s->handler_opaque);
 }
 
-void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
+void qemu_chr_be_write_impl(CharDriverState *s, uint8_t *buf, int len)
 {
 if (s->chr_read) {
 s->chr_read(s->handler_opaque, buf, len);
 }
 }
 
+void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
+{
+if (s->replay) {
+if (replay_mode == REPLAY_PLAY) {
+fprintf(stderr, "Replay: calling qemu_chr_be_write in play 
mode\n");
+exit(1);
+}
+replay_chr_be_write(s, buf, len);
+} else {
+qemu_chr_be_write_impl(s, buf, len);
+}
+}
+
 int qemu_chr_fe_get_msgfd(CharDriverState *s)
 {
 int fd;
-return (qemu_chr_fe_get_msgfds(s, &fd, 1) == 1) ? fd : -1;
+int res = (qemu_chr_fe_get_msgfds(s, &fd, 1) == 1) ? fd : -1;
+if (s->replay) {
+replay_data_int(&res);
+}
+return res;
 }
 
 int qemu_chr_fe_get_msgfds(CharDriverState *s, int *fds, int len)
@@ -3609,6 +3639,21 @@ CharDriverState *qemu_chr_new(const char *label, const 
char *filename, void (*in
 return chr;
 }
 
+CharDriverState *qemu_chr_new_replay(const char *label, const char *filename,
+ void (*init)(struct CharDriverState *s))
+{   
+if (replay_mode == REPLAY_PLAY && (strcmp(filename, "null")
+&& strcmp(filename, "vc:80Cx24C"))) {
+fprintf(stderr, "Only \"-serial null\" can be used with replay\n");
+exit(1);
+}
+CharDriverState 

[Qemu-devel] [RFC PATCH v2 15/49] softmmu: fixing usage of cpu_st/ld* from helpers

2014-07-17 Thread Pavel Dovgalyuk
MMU helper functions are called from generated code and other helper
functions. In both cases they try to get function's return address for
using it while restoring virtual CPU state.

When MMU helper is called from some other helper function
(like helper_maskmov_xmm) through cpu_st* function, the return address
will point to that helper. That is why CPU state cannot be restored in
the case of MMU fault.

This patch introduces several inline helpers to load return address
which points to the right place.

Signed-off-by: Pavel Dovgalyuk 
---
 include/exec/cpu_ldst_template.h |   28 
 include/exec/exec-all.h  |   27 +++
 softmmu_template.h   |   18 ++
 3 files changed, 69 insertions(+), 4 deletions(-)

diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
index 006093a..10d9f8f 100644
--- a/include/exec/cpu_ldst_template.h
+++ b/include/exec/cpu_ldst_template.h
@@ -61,6 +61,16 @@
 #define MMUSUFFIX _mmu
 #endif
 
+/* inline helper ld function */
+
+static inline DATA_TYPE
+glue(glue(helper_inline_ld, SUFFIX), MEMSUFFIX)(CPUArchState *env, 
target_ulong addr,
+ int mmu_idx)
+{
+return glue(glue(helper_call_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx,
+ GETRA());
+}
+
 /* generic load/store macros */
 
 static inline RES_TYPE
@@ -76,7 +86,7 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, 
target_ulong ptr)
 mmu_idx = CPU_MMU_INDEX;
 if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1) {
-res = glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx);
+res = glue(glue(helper_inline_ld, SUFFIX), MEMSUFFIX)(env, addr, 
mmu_idx);
 } else {
 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
 res = glue(glue(ld, USUFFIX), _raw)(hostaddr);
@@ -97,8 +107,8 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, 
target_ulong ptr)
 mmu_idx = CPU_MMU_INDEX;
 if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1) {
-res = (DATA_STYPE)glue(glue(helper_ld, SUFFIX),
-   MMUSUFFIX)(env, addr, mmu_idx);
+res = (DATA_STYPE)glue(glue(helper_inline_ld, SUFFIX),
+   MEMSUFFIX)(env, addr, mmu_idx);
 } else {
 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
 res = glue(glue(lds, SUFFIX), _raw)(hostaddr);
@@ -109,6 +119,16 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, 
target_ulong ptr)
 
 #ifndef SOFTMMU_CODE_ACCESS
 
+/* inline helper st function */
+
+static inline void
+glue(glue(helper_inline_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, 
target_ulong addr,
+ DATA_TYPE val, int mmu_idx)
+{
+glue(glue(helper_call_st, SUFFIX), MMUSUFFIX)(env, addr, val, mmu_idx,
+  GETRA());
+}
+
 /* generic store macro */
 
 static inline void
@@ -124,7 +144,7 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, 
target_ulong ptr,
 mmu_idx = CPU_MMU_INDEX;
 if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1) {
-glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx);
+glue(glue(helper_inline_st, SUFFIX), MEMSUFFIX)(env, addr, v, mmu_idx);
 } else {
 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
 glue(glue(st, SUFFIX), _raw)(hostaddr, v);
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 5e5d86e..528928f 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -344,6 +344,33 @@ bool io_mem_write(struct MemoryRegion *mr, hwaddr addr,
 void tlb_fill(CPUState *cpu, target_ulong addr, int is_write, int mmu_idx,
   uintptr_t retaddr);
 
+uint8_t helper_call_ldb_cmmu(CPUArchState *env, target_ulong addr,
+ int mmu_idx, uintptr_t retaddr);
+uint16_t helper_call_ldw_cmmu(CPUArchState *env, target_ulong addr,
+  int mmu_idx, uintptr_t retaddr);
+uint32_t helper_call_ldl_cmmu(CPUArchState *env, target_ulong addr,
+  int mmu_idx, uintptr_t retaddr);
+uint64_t helper_call_ldq_cmmu(CPUArchState *env, target_ulong addr,
+  int mmu_idx, uintptr_t retaddr);
+
+uint8_t helper_call_ldb_mmu(CPUArchState *env, target_ulong addr,
+int mmu_idx, uintptr_t retaddr);
+uint16_t helper_call_ldw_mmu(CPUArchState *env, target_ulong addr,
+ int mmu_idx, uintptr_t retaddr);
+uint32_t helper_call_ldl_mmu(CPUArchState *env, target_ulong addr,
+   

[Qemu-devel] [RFC PATCH v2 46/49] replay: replay_info command

2014-07-17 Thread Pavel Dovgalyuk
This patch adds support for replay_info monitor command. This command
returns the information about replay execution (replay mode and current step).

Signed-off-by: Pavel Dovgalyuk 
---
 hmp-commands.hx  |   13 +
 monitor.c|   17 +
 qapi-schema.json |   27 +++
 qmp-commands.hx  |   14 ++
 replay/Makefile.objs |1 +
 replay/replay-qmp.c  |   29 +
 replay/replay.c  |   25 +
 replay/replay.h  |4 
 8 files changed, 130 insertions(+), 0 deletions(-)
 create mode 100755 replay/replay-qmp.c

diff --git a/hmp-commands.hx b/hmp-commands.hx
index d0943b1..19174f1 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1788,6 +1788,19 @@ STEXI
 show available trace events and their state
 ETEXI
 
+{
+.name   = "replay_info",
+.args_type  = "",
+.params = "",
+.help   = "show replay info",
+.mhandler.cmd = do_replay_info,
+},
+
+STEXI
+@item replay_info
+Shows information about replay process.
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/monitor.c b/monitor.c
index 5bc70a6..f336b91 100644
--- a/monitor.c
+++ b/monitor.c
@@ -73,6 +73,7 @@
 #include "block/qapi.h"
 #include "qapi/qmp-event.h"
 #include "qapi-event.h"
+#include "replay/replay.h"
 
 /* for pic/irq_info */
 #if defined(TARGET_SPARC)
@@ -1173,6 +1174,22 @@ static void do_watchdog_action(Monitor *mon, const QDict 
*qdict)
 }
 }
 
+static void do_replay_info(Monitor *mon, const QDict *qdict)
+{
+switch (replay_mode) {
+case REPLAY_NONE:
+monitor_printf(mon, "Replay is not enabled\n");
+break;
+default:
+monitor_printf(mon, "Replay mode: %s ", replay_get_mode_name());
+if (replay_mode == REPLAY_PLAY) {
+monitor_printf(mon, "(%s)", replay_get_play_submode_name());
+}
+monitor_printf(mon, "\n\tcurrent step: %" PRId64 "\n", 
replay_get_current_step());
+break;
+}
+}
+
 static void monitor_printc(Monitor *mon, int c)
 {
 monitor_printf(mon, "'");
diff --git a/qapi-schema.json b/qapi-schema.json
index fee541a..c45f795 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3491,3 +3491,30 @@
 # Since: 2.1
 ##
 { 'command': 'rtc-reset-reinjection' }
+
+##
+# @ReplayInfo:
+#
+# Information about replay process
+#
+# @mode: replay mode (none, play, record)
+#
+# @submode: play submode
+#
+# @step: current step of record or play
+#
+# Since:  2.2
+##
+{ 'type': 'ReplayInfo',
+  'data': {'mode': 'str', 'submode': 'str', 'step': 'uint64'} }
+
+##
+# @replay_info
+#
+# Query the status of replay engine
+#
+# Returns: @ReplayInfo reflecting the status
+#
+# Since:  2.2
+##
+{ 'command': 'replay_info', 'returns': 'ReplayInfo' }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 4be4765..d475633 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3755,3 +3755,17 @@ Example:
 <- { "return": {} }
 
 EQMP
+
+{
+.name   = "replay_info",
+.args_type  = "",
+.mhandler.cmd_new = qmp_marshal_input_replay_info,
+},
+
+SQMP
+replay_info
+---
+
+Shows information about replay process.
+
+EQMP
diff --git a/replay/Makefile.objs b/replay/Makefile.objs
index f2e3bdc..1bc9621 100755
--- a/replay/Makefile.objs
+++ b/replay/Makefile.objs
@@ -7,3 +7,4 @@ obj-y += replay-net.o
 obj-y += replay-audio.o
 obj-y += replay-char.o
 obj-y += replay-usb.o
+obj-y += replay-qmp.o
diff --git a/replay/replay-qmp.c b/replay/replay-qmp.c
new file mode 100755
index 000..966bd4d
--- /dev/null
+++ b/replay/replay-qmp.c
@@ -0,0 +1,29 @@
+/*
+ * replay-qmp.c
+ *
+ * Copyright (c) 2010-2014 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 "sysemu/sysemu.h"
+#include "qmp-commands.h"
+#include "qapi/qmp/qobject.h"
+#include "qapi/qmp-input-visitor.h"
+#include "replay/replay.h"
+#include "replay/replay-internal.h"
+
+ReplayInfo *qmp_replay_info(Error **errp)
+{
+ReplayInfo *info = g_malloc0(sizeof(*info));
+
+info->mode = g_strdup(replay_get_mode_name());
+info->submode = g_strdup(replay_get_play_submode_name());
+info->step = replay_get_current_step();
+
+return info;
+}
diff --git a/replay/replay.c b/replay/replay.c
index a89ba91..f711c26 100755
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -638,3 +638,28 @@ void replay_data_buffer(unsigned char *data, size_t size)
 replay_put_array(data, size);
 }
 }
+
+const char *replay_get_mode_name(void)
+{
+switch (replay_mode) {
+case REPLAY_NONE:
+return "none";
+case REPLAY_PLAY:
+return "replay";
+case REPLAY_SAVE:
+return "record";
+default:
+return "unknown";
+}
+}
+
+const char *replay_get_play

[Qemu-devel] [RFC PATCH v2 48/49] replay: replay_seek_step command

2014-07-17 Thread Pavel Dovgalyuk
This patch adds support for replay_seek_step monitor command. This command
loads one of the snapshots and replays the execution until the specified
step is met.

Signed-off-by: Pavel Dovgalyuk 
---
 hmp-commands.hx  |   14 ++
 monitor.c|   17 +
 qapi-schema.json |   11 +++
 qmp-commands.hx  |   23 +++
 replay/replay-internal.h |3 +++
 replay/replay-qmp.c  |   15 +++
 replay/replay.c  |   43 +++
 replay/replay.h  |4 
 8 files changed, 130 insertions(+), 0 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 3eaa80e..57ce5da 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1815,6 +1815,20 @@ Stops replaying at the specified @var{step}.
 
 ETEXI
 
+{
+.name   = "replay_seek",
+.args_type  = "step:l",
+.params = "step",
+.help   = "seeks the replay log to the specified step",
+.mhandler.cmd = do_replay_seek,
+},
+
+STEXI
+@item replay_seek @var{step}
+Seeks the replay log to the specified @var{step}.
+
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/monitor.c b/monitor.c
index 4710a59..031decf 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1205,6 +1205,23 @@ static void do_replay_break(Monitor *mon, const QDict 
*qdict)
 }
 }
 
+static void do_replay_seek(Monitor *mon, const QDict *qdict)
+{
+if (replay_mode == REPLAY_PLAY) {
+uint64_t step = qdict_get_int(qdict, "step");
+if (replay_seek_step(step)) {
+monitor_printf(mon, "Seeking for step: %" PRId64 "\n", step);
+if (!runstate_is_running()) {
+vm_start();
+}
+} else {
+monitor_printf(mon, "Cannot seek to the specified step.\n");
+}
+} else {
+monitor_printf(mon, "You can go to the specific step only in PLAY 
mode.\n");
+}
+}
+
 static void monitor_printc(Monitor *mon, int c)
 {
 monitor_printf(mon, "'");
diff --git a/qapi-schema.json b/qapi-schema.json
index d0a4651..9d3fda3 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3529,3 +3529,14 @@
 # Since:  2.2
 ##
 { 'command': 'replay_break', 'data': { 'step': 'uint64' } }
+
+##
+# @replay_seek
+#
+# Seeks the replay log to the specified step
+#
+# @step: destination replay step 
+#
+# Since:  2.2
+##
+{ 'command': 'replay_seek', 'data': { 'step': 'uint64' } }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 575db76..a144327 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3792,3 +3792,26 @@ Example:
 <- { "return": {} }
 
 EQMP
+
+{
+.name   = "replay_seek",
+.args_type  = "step:l",
+.mhandler.cmd_new = qmp_marshal_input_replay_seek,
+},
+
+SQMP
+replay_seek
+---
+
+Seeks the replay log to the specified step.
+
+Arguments:
+
+- "step": destination replay step
+
+Example:
+
+-> { "execute": "replay_seek", "arguments": { "step": 1024 } }
+<- { "return": {} }
+
+EQMP
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index 56b6ad9..c7655e7 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -135,6 +135,9 @@ void skip_async_events_until(unsigned int kind);
 If the parameter is -1, the clock value is read to the cache anyway. */
 void replay_read_next_clock(unsigned int kind);
 
+/*! Finds saved state info which is nearest before the specified step. */
+SavedStateInfo *find_nearest_state(uint64_t step);
+
 /* Asynchronous events queue */
 
 /*! Initializes events' processing internals */
diff --git a/replay/replay-qmp.c b/replay/replay-qmp.c
index a9f30da..5cb04fb 100755
--- a/replay/replay-qmp.c
+++ b/replay/replay-qmp.c
@@ -40,3 +40,18 @@ void qmp_replay_break(uint64_t step, Error **errp)
 error_setg(errp, "replay_break can be used only in PLAY mode");
 }
 }
+
+void qmp_replay_seek(uint64_t step, Error **errp)
+{
+if (replay_mode == REPLAY_PLAY) {
+if (replay_seek_step(step)) {
+if (!runstate_is_running()) {
+vm_start();
+}
+} else {
+error_setg(errp, "Cannot seek to the specified step");
+}
+} else {
+error_setg(errp, "replay_seek can be used only in PLAY mode");
+}
+}
diff --git a/replay/replay.c b/replay/replay.c
index d6949d6..e6b3e39 100755
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -685,3 +685,46 @@ void replay_set_break(uint64_t step)
 {
 replay_break_step = step;
 }
+
+SavedStateInfo *find_nearest_state(uint64_t step)
+{
+SavedStateInfo *first = saved_states;
+SavedStateInfo *last = saved_states + saved_states_count;
+while (first < last - 1) {
+SavedStateInfo *next = first + (last - first) / 2;
+if (next->step > step) {
+last = next;
+} else {
+first = next;
+}
+}
+
+return first;
+}
+
+int replay_seek_step(uint64_t step)
+{
+if (replay_mode

[Qemu-devel] [RFC PATCH v2 08/49] hpet: fixing saving and loading process

2014-07-17 Thread Pavel Dovgalyuk
VM clock does not run while saving, so there is no need for saving the ticks
in HPET. Also added saving of hpet_offset field.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/timer/hpet.c |   13 +
 1 files changed, 1 insertions(+), 12 deletions(-)

diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index e160e8f..73401b9 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -222,14 +222,6 @@ static void update_irq(struct HPETTimer *timer, int set)
 }
 }
 
-static void hpet_pre_save(void *opaque)
-{
-HPETState *s = opaque;
-
-/* save current counter value */
-s->hpet_counter = hpet_get_ticks(s);
-}
-
 static int hpet_pre_load(void *opaque)
 {
 HPETState *s = opaque;
@@ -255,9 +247,6 @@ static int hpet_post_load(void *opaque, int version_id)
 {
 HPETState *s = opaque;
 
-/* Recalculate the offset between the main counter and guest time */
-s->hpet_offset = ticks_to_ns(s->hpet_counter) - 
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-
 /* Push number of timers into capability returned via HPET_ID */
 s->capability &= ~HPET_ID_NUM_TIM_MASK;
 s->capability |= (s->num_timers - 1) << HPET_ID_NUM_TIM_SHIFT;
@@ -308,13 +297,13 @@ static const VMStateDescription vmstate_hpet = {
 .name = "hpet",
 .version_id = 2,
 .minimum_version_id = 1,
-.pre_save = hpet_pre_save,
 .pre_load = hpet_pre_load,
 .post_load = hpet_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_UINT64(config, HPETState),
 VMSTATE_UINT64(isr, HPETState),
 VMSTATE_UINT64(hpet_counter, HPETState),
+VMSTATE_UINT64(hpet_offset, HPETState),
 VMSTATE_UINT8_V(num_timers, HPETState, 2),
 VMSTATE_VALIDATE("num_timers in range", hpet_validate_num_timers),
 VMSTATE_STRUCT_VARRAY_UINT8(timer, HPETState, num_timers, 0,




[Qemu-devel] [RFC PATCH v2 10/49] rtl8139: adding new fields to vmstate

2014-07-17 Thread Pavel Dovgalyuk
This patch adds virtual clock-dependent timers to VMState to allow correct
saving and restoring the state of RTL8139 network controller.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/net/rtl8139.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 90bc5ec..992caf0 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -3289,7 +3289,7 @@ static void rtl8139_pre_save(void *opaque)
 
 static const VMStateDescription vmstate_rtl8139 = {
 .name = "rtl8139",
-.version_id = 4,
+.version_id = 5,
 .minimum_version_id = 3,
 .post_load = rtl8139_post_load,
 .pre_save  = rtl8139_pre_save,
@@ -3363,6 +3363,9 @@ static const VMStateDescription vmstate_rtl8139 = {
 VMSTATE_STRUCT(tally_counters, RTL8139State, 0,
vmstate_tally_counters, RTL8139TallyCounters),
 
+VMSTATE_TIMER_V(timer, RTL8139State, 5),
+VMSTATE_INT64_V(TimerExpire, RTL8139State, 5),
+
 VMSTATE_UINT32_V(cplus_enabled, RTL8139State, 4),
 VMSTATE_END_OF_LIST()
 },




[Qemu-devel] [RFC PATCH v2 47/49] replay: replay_break command

2014-07-17 Thread Pavel Dovgalyuk
This patch adds support for replay_break monitor command. This command
sets the step (measured in executed instructions) where replay should be
stopped.

Signed-off-by: Pavel Dovgalyuk 
---
 hmp-commands.hx |   14 ++
 monitor.c   |   15 +++
 qapi-schema.json|   11 +++
 qmp-commands.hx |   23 +++
 replay/replay-qmp.c |   13 +
 replay/replay.c |   24 +++-
 replay/replay.h |2 ++
 7 files changed, 101 insertions(+), 1 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 19174f1..3eaa80e 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1801,6 +1801,20 @@ STEXI
 Shows information about replay process.
 ETEXI
 
+{
+.name   = "replay_break",
+.args_type  = "step:l",
+.params = "step",
+.help   = "stop replaying at the specified replay step",
+.mhandler.cmd = do_replay_break,
+},
+
+STEXI
+@item replay_break @var{step}
+Stops replaying at the specified @var{step}.
+
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/monitor.c b/monitor.c
index f336b91..4710a59 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1190,6 +1190,21 @@ static void do_replay_info(Monitor *mon, const QDict 
*qdict)
 }
 }
 
+static void do_replay_break(Monitor *mon, const QDict *qdict)
+{
+if (replay_mode == REPLAY_PLAY) {
+uint64_t step = qdict_get_int(qdict, "step");
+if (step >= replay_get_current_step()) {
+monitor_printf(mon, "Setting break at step: %" PRId64 "\n", step);
+replay_set_break(step);
+} else {
+monitor_printf(mon, "Cannot stop on the preceding step.\n");
+}
+} else {
+monitor_printf(mon, "You can stop at the specific step only in PLAY 
mode.\n");
+}
+}
+
 static void monitor_printc(Monitor *mon, int c)
 {
 monitor_printf(mon, "'");
diff --git a/qapi-schema.json b/qapi-schema.json
index c45f795..d0a4651 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3518,3 +3518,14 @@
 # Since:  2.2
 ##
 { 'command': 'replay_info', 'returns': 'ReplayInfo' }
+
+##
+# @replay_break
+#
+# Sets breakpoint at the specified step of replaying
+#
+# @step: step where breakpoint should be set
+#
+# Since:  2.2
+##
+{ 'command': 'replay_break', 'data': { 'step': 'uint64' } }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index d475633..575db76 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3769,3 +3769,26 @@ replay_info
 Shows information about replay process.
 
 EQMP
+
+{
+.name   = "replay_break",
+.args_type  = "step:l",
+.mhandler.cmd_new = qmp_marshal_input_replay_break,
+},
+
+SQMP
+replay_break
+
+
+Sets breakpoint at the specified replay step.
+
+Arguments:
+
+- "step": step where breakpoint should be set
+
+Example:
+
+-> { "execute": "replay_break", "arguments": { "step": 1024 } }
+<- { "return": {} }
+
+EQMP
diff --git a/replay/replay-qmp.c b/replay/replay-qmp.c
index 966bd4d..a9f30da 100755
--- a/replay/replay-qmp.c
+++ b/replay/replay-qmp.c
@@ -27,3 +27,16 @@ ReplayInfo *qmp_replay_info(Error **errp)
 
 return info;
 }
+
+void qmp_replay_break(uint64_t step, Error **errp)
+{
+if (replay_mode == REPLAY_PLAY) {
+if (step >= replay_get_current_step()) {
+replay_set_break(step);
+} else {
+error_setg(errp, "Cannot stop on the preceding step");
+}
+} else {
+error_setg(errp, "replay_break can be used only in PLAY mode");
+}
+}
diff --git a/replay/replay.c b/replay/replay.c
index f711c26..d6949d6 100755
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -31,6 +31,8 @@ static char *replay_filename;
 char *replay_image_suffix;
 
 ReplayState replay_state;
+/*! Step for stopping execution at. */
+static uint64_t replay_break_step = -1;
 
 /* 
 Auto-saving for VM states data 
@@ -284,6 +286,19 @@ void replay_instruction(int process_events)
 } else if (replay_mode == REPLAY_PLAY) {
 skip_async_events_until(EVENT_INSTRUCTION);
 if (first_cpu->instructions_count >= 1) {
+if (replay_get_current_step() == replay_break_step) {
+replay_break_step = -1;
+
+/* for stopping VM */
+if (play_submode == REPLAY_PLAY_NORMAL) {
+first_cpu->exception_index = EXCP_DEBUG;
+monitor_printf(default_mon, "Execution has 
stopped.\n");
+vm_stop(EXCP_DEBUG);
+}
+/* for breaking execution loop */
+cpu_exit(first_cpu);
+return;
+}
 ++replay_state.current_step;
 --first_cpu->instructions_count;
 if (first_cpu->instructions_count == 0) {
@@ -312,7 +327,8 @@ bool replay_has_async_request(void)
 }
 
 if (replay_mode == REPLAY_PLAY) {
-

[Qemu-devel] [RFC PATCH v2 49/49] gdbstub: reverse debugging

2014-07-17 Thread Pavel Dovgalyuk
This patch introduces support of reverse debugging through the gdb remote
protocol. Patch adds reverse-stepi and reverse-continue commands support
to qemu. Other reverse commands should also work, because they reuse these ones.

Signed-off-by: Pavel Dovgalyuk 
---
 exec.c  |7 ++
 gdbstub.c   |   79 ++-
 replay/Makefile.objs|1 
 replay/replay-debug.c   |  148 +++
 replay/replay-internal.h|4 +
 replay/replay.c |5 +
 replay/replay.h |   13 
 target-arm/helper.h |1 
 target-arm/replay_helper.c  |5 +
 target-arm/translate.c  |   14 +++-
 target-i386/helper.h|1 
 target-i386/replay_helper.c |5 +
 target-i386/translate.c |   12 ++-
 13 files changed, 269 insertions(+), 26 deletions(-)
 create mode 100755 replay/replay-debug.c

diff --git a/exec.c b/exec.c
index 050e0a8..8255d96 100644
--- a/exec.c
+++ b/exec.c
@@ -1613,6 +1613,13 @@ static void check_watchpoint(int offset, int len_mask, 
int flags)
 QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
 if ((vaddr == (wp->vaddr & len_mask) ||
  (vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {
+/* Don't actually process a watchpoint, it will be processed,
+   when reverse execution stops. */
+if (replay_get_play_submode() == REPLAY_PLAY_REVERSE) {
+wp->flags &= ~BP_WATCHPOINT_HIT;
+replay_reverse_breakpoint();
+continue;
+}
 wp->flags |= BP_WATCHPOINT_HIT;
 if (!cpu->watchpoint_hit) {
 cpu->watchpoint_hit = wp;
diff --git a/gdbstub.c b/gdbstub.c
index 8afe0b7..756b846 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -40,6 +40,7 @@
 #include "cpu.h"
 #include "qemu/sockets.h"
 #include "sysemu/kvm.h"
+#include "replay/replay.h"
 
 static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
  uint8_t *buf, int len, bool is_write)
@@ -313,6 +314,19 @@ typedef struct GDBState {
  */
 static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
 
+/*! Retrieves flags for single step mode. */
+static int get_sstep_flags(void)
+{
+/* In replay mode all events written into the log should be replayed.
+ * That is why NOIRQ flag is removed in this mode.
+ */
+if (replay_mode != REPLAY_NONE) {
+return SSTEP_ENABLE;
+} else {
+return sstep_flags;
+}
+}
+
 static GDBState *gdbserver_state;
 
 bool gdb_has_xml;
@@ -835,7 +849,7 @@ static int gdb_handle_packet(GDBState *s, const char 
*line_buf)
 s->c_cpu = cpu;
 }
 if (res == 's') {
-cpu_single_step(s->c_cpu, sstep_flags);
+cpu_single_step(s->c_cpu, get_sstep_flags());
 }
 s->signal = res_signal;
 gdb_continue(s);
@@ -863,9 +877,29 @@ static int gdb_handle_packet(GDBState *s, const char 
*line_buf)
 addr = strtoull(p, (char **)&p, 16);
 gdb_set_cpu_pc(s, addr);
 }
-cpu_single_step(s->c_cpu, sstep_flags);
+cpu_single_step(s->c_cpu, get_sstep_flags());
 gdb_continue(s);
return RS_IDLE;
+case 'b':
+/* backward debugging commands */
+if (replay_mode == REPLAY_PLAY
+&& replay_get_play_submode() == REPLAY_PLAY_NORMAL) {
+switch (*p) {
+case 's':
+replay_reverse_step();
+gdb_continue(s);
+   return RS_IDLE;
+case 'c':
+replay_reverse_continue();
+gdb_continue(s);
+   return RS_IDLE;
+default:
+goto unknown_command;
+}
+} else {
+put_packet (s, "E22");
+}
+goto unknown_command;
 case 'F':
 {
 target_ulong ret;
@@ -937,8 +971,6 @@ static int gdb_handle_packet(GDBState *s, const char 
*line_buf)
 if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len,
true) != 0) {
 put_packet(s, "E14");
-} else {
-put_packet(s, "OK");
 }
 break;
 case 'p':
@@ -1035,18 +1067,23 @@ static int gdb_handle_packet(GDBState *s, const char 
*line_buf)
 put_packet(s, buf);
 break;
 } else if (strncmp(p,"qemu.sstep",10) == 0) {
-/* Display or change the sstep_flags */
-p += 10;
-if (*p != '=') {
-/* Display current setting */
-snprintf(buf, sizeof(buf), "0x%x", sstep_flags);
-put_packet(s, buf);
-break;
+if (replay_mode == REPLAY_NONE) {
+/* Display or change the sstep_flags */
+p += 10;
+ 

[Qemu-devel] [RFC PATCH v2 26/49] replay: interrupts and exceptions

2014-07-17 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 
---
 cpu-exec.c   |   14 +++---
 replay/replay-internal.h |4 
 replay/replay.c  |   42 ++
 replay/replay.h  |   14 ++
 4 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 13c0ec6..fcde7ce 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -23,6 +23,7 @@
 #include "qemu/atomic.h"
 #include "sysemu/qtest.h"
 #include "qemu/main-loop.h"
+#include "replay/replay.h"
 
 void cpu_loop_exit(CPUState *cpu)
 {
@@ -314,8 +315,14 @@ int cpu_exec(CPUArchState *env)
 ret = cpu->exception_index;
 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_REPLAY;
+break;
+}
 #endif
 }
 }
@@ -323,7 +330,8 @@ int cpu_exec(CPUArchState *env)
 next_tb = 0; /* force lookup of first TB */
 for(;;) {
 interrupt_request = cpu->interrupt_request;
-if (unlikely(interrupt_request)) {
+if (unlikely((interrupt_request & CPU_INTERRUPT_DEBUG)
+ || (interrupt_request && replay_interrupt( {
 if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {
 /* Mask out external interrupts for this step. */
 interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index 9ebfa83..019ae20 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -15,6 +15,10 @@
 #include 
 #include "sysemu/sysemu.h"
 
+/* for software interrupt */
+#define EVENT_INTERRUPT 15
+/* for emulated exceptions */
+#define EVENT_EXCEPTION 23
 /* for async events */
 #define EVENT_ASYNC 24
 /* for instruction event */
diff --git a/replay/replay.c b/replay/replay.c
index 8a9826e..41a27a9 100755
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -159,3 +159,45 @@ uint64_t replay_get_current_step(void)
 }
 return replay_state.current_step;
 }
+
+bool replay_exception(void)
+{
+if (replay_mode == REPLAY_SAVE) {
+replay_save_instructions();
+replay_put_event(EVENT_EXCEPTION);
+return true;
+} else if (replay_mode == REPLAY_PLAY) {
+if (skip_async_events(EVENT_EXCEPTION)) {
+replay_has_unread_data = 0;
+return true;
+}
+return false;
+}
+
+return true;
+}
+
+bool replay_interrupt(void)
+{
+if (replay_mode == REPLAY_SAVE) {
+replay_save_instructions();
+replay_put_event(EVENT_INTERRUPT);
+return true;
+} else if (replay_mode == REPLAY_PLAY) {
+if (skip_async_events(EVENT_INTERRUPT)) {
+replay_has_unread_data = 0;
+return true;
+}
+return false;
+}
+
+return true;
+}
+
+bool replay_has_interrupt(void)
+{
+if (replay_mode == REPLAY_PLAY) {
+return skip_async_events(EVENT_INTERRUPT);
+}
+return false;
+}
diff --git a/replay/replay.h b/replay/replay.h
index 1ce7f78..10e6681 100755
--- a/replay/replay.h
+++ b/replay/replay.h
@@ -45,4 +45,18 @@ bool replay_has_async_request(void);
 /*! Returns non-zero if next event is instruction. */
 bool replay_has_instruction(void);
 
+/* Interrupts and exceptions */
+
+/*! Called by exception handler to write or read
+exception processing events. */
+bool replay_exception(void);
+/*! Called by interrupt handlers to write or read
+interrupt processing events.
+\return true if interrupt should be processed */
+bool replay_interrupt(void);
+/*! Tries to read interrupt event from the file.
+Returns true, when interrupt request is pending */
+bool replay_has_interrupt(void);
+
+
 #endif




[Qemu-devel] [RFC PATCH v2 41/49] tap-win32: destroy the thread at exit

2014-07-17 Thread Pavel Dovgalyuk
This patch fixes resource leak caused by created thread which is not destroyed
at exit.

Signed-off-by: Pavel Dovgalyuk 
---
 net/tap-win32.c |   11 ++-
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/net/tap-win32.c b/net/tap-win32.c
index 8aee611..efd1c75 100644
--- a/net/tap-win32.c
+++ b/net/tap-win32.c
@@ -99,6 +99,7 @@ typedef struct tap_win32_overlapped {
 HANDLE output_queue_semaphore;
 HANDLE free_list_semaphore;
 HANDLE tap_semaphore;
+HANDLE hThread;
 CRITICAL_SECTION output_queue_cs;
 CRITICAL_SECTION free_list_cs;
 OVERLAPPED read_overlapped;
@@ -625,8 +626,9 @@ static int tap_win32_open(tap_win32_overlapped_t **phandle,
 
 *phandle = &tap_overlapped;
 
-CreateThread(NULL, 0, tap_win32_thread_entry,
- (LPVOID)&tap_overlapped, 0, &idThread);
+tap_overlapped.hThread = CreateThread(NULL, 0, tap_win32_thread_entry,
+  (LPVOID)&tap_overlapped,
+  0, &idThread);
 return 0;
 }
 
@@ -643,9 +645,8 @@ static void tap_cleanup(NetClientState *nc)
 
 qemu_del_wait_object(s->handle->tap_semaphore, NULL, NULL);
 
-/* FIXME: need to kill thread and close file handle:
-   tap_win32_close(s);
-*/
+TerminateThread(s->handle->hThread, 0);
+CloseHandle(s->handle->handle);
 }
 
 static ssize_t tap_receive(NetClientState *nc, const uint8_t *buf, size_t size)




[Qemu-devel] [RFC PATCH v2 17/49] target-i386: update fp status fix

2014-07-17 Thread Pavel Dovgalyuk
This patch adds calls to update_fp_status() function from several
places where FPU state is changed.

Signed-off-by: Pavel Dovgalyuk 
---
 target-i386/cpu.c|1 +
 target-i386/cpu.h|1 +
 target-i386/fpu_helper.c |5 -
 target-i386/machine.c|2 +-
 4 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 45c662d..27269ad 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2573,6 +2573,7 @@ static void x86_cpu_reset(CPUState *s)
 env->fptags[i] = 1;
 }
 env->fpuc = 0x37f;
+update_fp_status(env);
 
 env->mxcsr = 0x1f80;
 env->xstate_bv = XSTATE_FP | XSTATE_SSE;
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index e634d83..42bda46 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1249,6 +1249,7 @@ void QEMU_NORETURN raise_interrupt(CPUX86State *nenv, int 
intno, int is_int,
 /* cc_helper.c */
 extern const uint8_t parity_table[256];
 uint32_t cpu_cc_compute_all(CPUX86State *env1, int op);
+void update_fp_status(CPUX86State *env);
 
 static inline uint32_t cpu_compute_eflags(CPUX86State *env)
 {
diff --git a/target-i386/fpu_helper.c b/target-i386/fpu_helper.c
index 1b2900d..a8ffba9 100644
--- a/target-i386/fpu_helper.c
+++ b/target-i386/fpu_helper.c
@@ -537,7 +537,7 @@ uint32_t helper_fnstcw(CPUX86State *env)
 return env->fpuc;
 }
 
-static void update_fp_status(CPUX86State *env)
+void update_fp_status(CPUX86State *env)
 {
 int rnd_type;
 
@@ -1006,6 +1006,7 @@ void helper_fstenv(CPUX86State *env, target_ulong ptr, 
int data32)
 cpu_stw_data(env, ptr + 10, 0);
 cpu_stw_data(env, ptr + 12, 0);
 }
+update_fp_status(env);
 }
 
 void helper_fldenv(CPUX86State *env, target_ulong ptr, int data32)
@@ -1055,6 +1056,7 @@ void helper_fsave(CPUX86State *env, target_ulong ptr, int 
data32)
 env->fptags[5] = 1;
 env->fptags[6] = 1;
 env->fptags[7] = 1;
+update_fp_status(env);
 }
 
 void helper_frstor(CPUX86State *env, target_ulong ptr, int data32)
@@ -1158,6 +1160,7 @@ void helper_fxrstor(CPUX86State *env, target_ulong ptr, 
int data64)
 }
 
 env->fpuc = cpu_lduw_data(env, ptr);
+update_fp_status(env);
 fpus = cpu_lduw_data(env, ptr + 2);
 fptag = cpu_lduw_data(env, ptr + 4);
 env->fpstt = (fpus >> 11) & 7;
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 9dfac33..b8f3467 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -315,13 +315,13 @@ static int cpu_post_load(void *opaque, int version_id)
 env->hflags &= ~HF_CPL_MASK;
 env->hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
 
-/* XXX: restore FPU round state */
 env->fpstt = (env->fpus_vmstate >> 11) & 7;
 env->fpus = env->fpus_vmstate & ~0x3800;
 env->fptag_vmstate ^= 0xff;
 for(i = 0; i < 8; i++) {
 env->fptags[i] = (env->fptag_vmstate >> i) & 1;
 }
+update_fp_status(env);
 
 cpu_breakpoint_remove_all(cs, BP_CPU);
 cpu_watchpoint_remove_all(cs, BP_CPU);




[Qemu-devel] [RFC PATCH v2 43/49] replay: audio data record/replay

2014-07-17 Thread Pavel Dovgalyuk
This patch adds deterministic replay for audio adapter. Replay module saves
data from the microphone and "end-of-playback" events.
Support of audio record and replay is implemented only for Win32 hosts.

Signed-off-by: Pavel Dovgalyuk 
---
 audio/audio.c|   14 ++-
 audio/audio_win_int.h|3 +
 audio/winwaveaudio.c |  167 ++
 replay/Makefile.objs |1 
 replay/replay-audio.c|  228 ++
 replay/replay-internal.c |4 +
 replay/replay-internal.h |   14 +++
 replay/replay.h  |   20 
 8 files changed, 408 insertions(+), 43 deletions(-)
 create mode 100755 replay/replay-audio.c

diff --git a/audio/audio.c b/audio/audio.c
index 9d018e9..7b272b7 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -26,6 +26,7 @@
 #include "monitor/monitor.h"
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
+#include "replay/replay.h"
 
 #define AUDIO_CAP "audio"
 #include "audio_int.h"
@@ -1201,7 +1202,9 @@ void AUD_set_active_out (SWVoiceOut *sw, int on)
 if (!hw->enabled) {
 hw->enabled = 1;
 if (s->vm_running) {
-hw->pcm_ops->ctl_out (hw, VOICE_ENABLE, conf.try_poll_out);
+hw->pcm_ops->ctl_out(hw, VOICE_ENABLE,
+ replay_mode == REPLAY_NONE
+ ? conf.try_poll_out : 0);
 audio_reset_timer (s);
 }
 }
@@ -1763,11 +1766,13 @@ static void audio_vm_change_state_handler (void 
*opaque, int running,
 
 s->vm_running = running;
 while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
-hwo->pcm_ops->ctl_out (hwo, op, conf.try_poll_out);
+hwo->pcm_ops->ctl_out(hwo, op, replay_mode == REPLAY_NONE
+   ? conf.try_poll_out : 0);
 }
 
 while ((hwi = audio_pcm_hw_find_any_enabled_in (hwi))) {
-hwi->pcm_ops->ctl_in (hwi, op, conf.try_poll_in);
+hwi->pcm_ops->ctl_in(hwi, op, replay_mode == REPLAY_NONE
+  ? conf.try_poll_in : 0);
 }
 audio_reset_timer (s);
 }
@@ -1810,9 +1815,10 @@ static void audio_atexit (void)
 
 static const VMStateDescription vmstate_audio = {
 .name = "audio",
-.version_id = 1,
+.version_id = 2,
 .minimum_version_id = 1,
 .fields = (VMStateField[]) {
+VMSTATE_TIMER_V(ts, AudioState, 2),
 VMSTATE_END_OF_LIST()
 }
 };
diff --git a/audio/audio_win_int.h b/audio/audio_win_int.h
index fa5b3cb..0525ae6 100644
--- a/audio/audio_win_int.h
+++ b/audio/audio_win_int.h
@@ -7,4 +7,7 @@ int waveformat_from_audio_settings (WAVEFORMATEX *wfx,
 int waveformat_to_audio_settings (WAVEFORMATEX *wfx,
   struct audsettings *as);
 
+void winwave_callback_out_impl(void *dwInstance, WAVEHDR *h);
+void winwave_callback_in_impl(void *dwInstance, WAVEHDR *h);
+
 #endif /* AUDIO_WIN_INT_H */
diff --git a/audio/winwaveaudio.c b/audio/winwaveaudio.c
index 8dbd145..f7325a8 100644
--- a/audio/winwaveaudio.c
+++ b/audio/winwaveaudio.c
@@ -2,7 +2,9 @@
 
 #include "qemu-common.h"
 #include "sysemu/sysemu.h"
+#include "migration/vmstate.h"
 #include "audio.h"
+#include "replay/replay.h"
 
 #define AUDIO_CAP "winwave"
 #include "audio_int.h"
@@ -47,6 +49,7 @@ typedef struct {
 int paused;
 int rpos;
 int avail;
+int non_added;
 CRITICAL_SECTION crit_sect;
 } WaveVoiceIn;
 
@@ -124,6 +127,24 @@ static void winwave_anal_close_out (WaveVoiceOut *wave)
 wave->hwo = NULL;
 }
 
+void winwave_callback_out_impl(void *dwInstance, WAVEHDR *h)
+{
+WaveVoiceOut *wave = (WaveVoiceOut *)dwInstance;
+if (!h->dwUser) {
+h->dwUser = 1;
+EnterCriticalSection(&wave->crit_sect);
+{
+wave->avail += conf.dac_samples;
+}
+LeaveCriticalSection(&wave->crit_sect);
+if (wave->hw.poll_mode) {
+if (!SetEvent(wave->event)) {
+dolog("DAC SetEvent failed %lx\n", GetLastError());
+}
+}
+}
+}
+
 static void CALLBACK winwave_callback_out (
 HWAVEOUT hwo,
 UINT msg,
@@ -132,24 +153,16 @@ static void CALLBACK winwave_callback_out (
 DWORD_PTR dwParam2
 )
 {
-WaveVoiceOut *wave = (WaveVoiceOut *) dwInstance;
-
 switch (msg) {
 case WOM_DONE:
 {
-WAVEHDR *h = (WAVEHDR *) dwParam1;
-if (!h->dwUser) {
-h->dwUser = 1;
-EnterCriticalSection (&wave->crit_sect);
-{
-wave->avail += conf.dac_samples;
-}
-LeaveCriticalSection (&wave->crit_sect);
-if (wave->hw.poll_mode) {
-if (!SetEvent (wave->event)) {
-dolog ("DAC SetEvent failed %lx\n", GetLastError ());
-}
-}
+if (r

[Qemu-devel] [RFC PATCH v2 27/49] vga: do not use virtual clock for blinking cursor

2014-07-17 Thread Pavel Dovgalyuk
This patch changes virtual clock to realtime one in vga_draw_text and
vga_update_display functions. Display update process depends on realtime
clock. If we read virtual clock there, virtual machine becomes
non-deterministic, because every read to virtual clock is written to the
replay log.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/display/vga.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/display/vga.c b/hw/display/vga.c
index 4b089a3..02d3be3 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1304,7 +1304,7 @@ static void vga_draw_text(VGACommonState *s, int 
full_update)
 uint32_t *ch_attr_ptr;
 vga_draw_glyph8_func *vga_draw_glyph8;
 vga_draw_glyph9_func *vga_draw_glyph9;
-int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
+int64_t now = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
 
 /* compute font data address (in plane 2) */
 v = s->sr[VGA_SEQ_CHARACTER_MAP];
@@ -1906,7 +1906,7 @@ static void vga_update_display(void *opaque)
 }
 if (graphic_mode != s->graphic_mode) {
 s->graphic_mode = graphic_mode;
-s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
+s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
 full_update = 1;
 }
 switch(graphic_mode) {




[Qemu-devel] [RFC PATCH v2 14/49] ide pci: reset status field before loading the vmstate

2014-07-17 Thread Pavel Dovgalyuk
This patch resets status field before loading the state of IDE BMDMA device.
Resetting status is needed for replay, because it does not reset whole virtual
machine before loading state of the VM.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/ide/pci.c |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 6257a21..47ab24d 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -382,6 +382,15 @@ static bool ide_bmdma_status_needed(void *opaque)
 return ((bm->status & abused_bits) != 0);
 }
 
+static int ide_bmdma_pre_load(void *opaque)
+{
+BMDMAState *bm = opaque;
+/* Reset is not performed in replay mode,
+   so reset status manually to allow ide_bmdma_post_load function 
initialize it. */
+bm->status = 0;
+return 0;
+}
+
 static void ide_bmdma_pre_save(void *opaque)
 {
 BMDMAState *bm = opaque;
@@ -434,6 +443,7 @@ static const VMStateDescription vmstate_bmdma = {
 .name = "ide bmdma",
 .version_id = 3,
 .minimum_version_id = 0,
+.pre_load  = ide_bmdma_pre_load,
 .pre_save  = ide_bmdma_pre_save,
 .fields = (VMStateField[]) {
 VMSTATE_UINT8(cmd, BMDMAState),




[Qemu-devel] [RFC PATCH v2 36/49] pl031: vmstate in replay mode

2014-07-17 Thread Pavel Dovgalyuk
This patch modifies vmstate for PL031 RTC. It removes querying of the rtc
and virtual clocks while saving and restoring VM state, because in replay
mode these clocks are stopped while saving. And reading the clock while
restoring the VM state may lead to read of the incorrect values, because
clocks cache in replay module could not be loaded yet.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/timer/pl031.c |   22 +++---
 1 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c
index 02c814f..017b1ce 100644
--- a/hw/timer/pl031.c
+++ b/hw/timer/pl031.c
@@ -220,19 +220,27 @@ static void pl031_pre_save(void *opaque)
 {
 PL031State *s = opaque;
 
-/* tick_offset is base_time - rtc_clock base time.  Instead, we want to
- * store the base time relative to the QEMU_CLOCK_VIRTUAL for 
backwards-compatibility.  */
-int64_t delta = qemu_clock_get_ns(rtc_clock) - 
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-s->tick_offset_vmstate = s->tick_offset + delta / get_ticks_per_sec();
+if (replay_mode == REPLAY_NONE) {
+/* tick_offset is base_time - rtc_clock base time.  Instead, we want to
+ * store the base time relative to the QEMU_CLOCK_VIRTUAL for 
backwards-compatibility.  */
+int64_t delta = qemu_clock_get_ns(rtc_clock) - 
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+s->tick_offset_vmstate = s->tick_offset + delta / get_ticks_per_sec();
+} else {
+s->tick_offset_vmstate = s->tick_offset;
+}
 }
 
 static int pl031_post_load(void *opaque, int version_id)
 {
 PL031State *s = opaque;
 
-int64_t delta = qemu_clock_get_ns(rtc_clock) - 
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-s->tick_offset = s->tick_offset_vmstate - delta / get_ticks_per_sec();
-pl031_set_alarm(s);
+if (replay_mode == REPLAY_NONE) {
+int64_t delta = qemu_clock_get_ns(rtc_clock) - 
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+s->tick_offset = s->tick_offset_vmstate - delta / get_ticks_per_sec();
+pl031_set_alarm(s);
+} else {
+s->tick_offset = s->tick_offset_vmstate;
+}
 return 0;
 }
 




[Qemu-devel] [RFC PATCH v2 25/49] target-i386: instructions counting code for replay

2014-07-17 Thread Pavel Dovgalyuk
This patch adds instructions counting into the target-specific part
of i386/x86_64 simulator. In record/replay mode it inserts replay functions
calls and instructions counter increment into the translated code.

Signed-off-by: Pavel Dovgalyuk 
---
 target-i386/Makefile.objs   |1 +
 target-i386/cpu.h   |7 
 target-i386/helper.h|2 +
 target-i386/replay_helper.c |   33 ++
 target-i386/translate.c |   79 +--
 5 files changed, 118 insertions(+), 4 deletions(-)
 create mode 100755 target-i386/replay_helper.c

diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs
index 027b94e..09a6e8a 100644
--- a/target-i386/Makefile.objs
+++ b/target-i386/Makefile.objs
@@ -2,6 +2,7 @@ obj-y += translate.o helper.o cpu.o
 obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o
 obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o
 obj-y += gdbstub.o
+obj-y += replay_helper.o
 obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
 obj-$(CONFIG_KVM) += kvm.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 42bda46..c9b92af 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -28,6 +28,13 @@
 #define TARGET_LONG_BITS 32
 #endif
 
+/* Maximum instruction code size */
+#ifdef TARGET_X86_64
+#define TARGET_MAX_INSN_SIZE 16
+#else
+#define TARGET_MAX_INSN_SIZE 16
+#endif
+
 /* target supports implicit self modifying code */
 #define TARGET_HAS_SMC
 /* support for self modifying code even if the modified instruction is
diff --git a/target-i386/helper.h b/target-i386/helper.h
index 8eb0145..058302b 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -217,3 +217,5 @@ DEF_HELPER_3(rcrl, tl, env, tl, tl)
 DEF_HELPER_3(rclq, tl, env, tl, tl)
 DEF_HELPER_3(rcrq, tl, env, tl, tl)
 #endif
+
+DEF_HELPER_1(replay_instruction, i32, env)
diff --git a/target-i386/replay_helper.c b/target-i386/replay_helper.c
new file mode 100755
index 000..8b82eee
--- /dev/null
+++ b/target-i386/replay_helper.c
@@ -0,0 +1,33 @@
+/*
+ * replay_helper.c
+ *
+ * Copyright (c) 2010-2014 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 "cpu.h"
+#include "exec/helper-proto.h"
+#include "replay/replay.h"
+
+uint32_t helper_replay_instruction(CPUX86State *env)
+{
+CPUState *cpu = ENV_GET_CPU(env);
+if (replay_mode == REPLAY_PLAY
+&& !replay_has_instruction()) {
+cpu->exception_index = EXCP_REPLAY;
+return 1;
+}
+
+if (cpu->exit_request) {
+cpu->exception_index = EXCP_REPLAY;
+return 1;
+}
+
+int timer = replay_has_async_request();
+replay_instruction(timer);
+return timer;
+}
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 6fcd824..6ae3fc3 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -28,6 +28,7 @@
 #include "disas/disas.h"
 #include "tcg-op.h"
 #include "exec/cpu_ldst.h"
+#include "replay/replay.h"
 
 #include "exec/helper-proto.h"
 #include "exec/helper-gen.h"
@@ -112,6 +113,7 @@ typedef struct DisasContext {
 int tf; /* TF cpu flag */
 int singlestep_enabled; /* "hardware" single step enabled */
 int jmp_opt; /* use direct block chaining for direct jumps */
+int repz_opt; /* optimize jumps within repz instructions */
 int mem_index; /* select memory access functions */
 uint64_t flags; /* all execution flags */
 struct TranslationBlock *tb;
@@ -1212,7 +1214,7 @@ static inline void gen_repz_ ## op(DisasContext *s, 
TCGMemOp ot,  \
 gen_op_add_reg_im(s->aflag, R_ECX, -1);   \
 /* a loop would cause two single step exceptions if ECX = 1   \
before rep string_insn */  \
-if (!s->jmp_opt)  \
+if (!s->repz_opt) \
 gen_op_jz_ecx(s->aflag, l2);  \
 gen_jmp(s, cur_eip);  \
 }
@@ -1230,7 +1232,7 @@ static inline void gen_repz_ ## op(DisasContext *s, 
TCGMemOp ot,  \
 gen_op_add_reg_im(s->aflag, R_ECX, -1);   \
 gen_update_cc_op(s);  \
 gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
-if (!s->jmp_opt)  \
+if (!s->repz_opt) \
 gen_op_jz_ecx(s->aflag, l2);  \
 gen_jmp(s, cur_eip); 

[Qemu-devel] [RFC PATCH v2 28/49] replay: asynchronous events infrastructure

2014-07-17 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 
---
 replay/replay-events.c   |  198 ++
 replay/replay-internal.h |   17 
 replay/replay.h  |4 +
 3 files changed, 218 insertions(+), 1 deletions(-)

diff --git a/replay/replay-events.c b/replay/replay-events.c
index eaffc48..eda574e 100755
--- a/replay/replay-events.c
+++ b/replay/replay-events.c
@@ -12,15 +12,211 @@
 #include "replay.h"
 #include "replay-internal.h"
 
+typedef struct Event {
+int 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);
+
+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 false;
+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);
+replay_run_event(event);
+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(int 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_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(int event_kind, void *opaque)
+{
+replay_add_event_internal(event_kind, opaque, NULL, 0);
 }
 
 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_PLAY) {
+/* put the event into the file */
+if (opt == -1) {
+replay_put_event(EVENT_ASYNC);
+} else {
+replay_put_event(EVENT_ASYNC_OPT);
+replay_put_byte(opt);
+}
+replay_put_byte(event->event_kind);
+
+/* save event-specific data */
+switch (event->event_kind) {
+}
+}
+
+replay_run_event(event);
+QTAILQ_REMOVE(&events_list, event, events);
+g_free(event);
+}
+qemu_mutex_unlock(&lock);
 }
 
 void replay_read_events(int opt)
 {
+replay_fetch_data_kind();
+while ((opt == -1 && replay_data_kind == EVENT_ASYNC)
+|| (opt != -1 && replay_data_kind == EVENT_ASYNC_OPT)) {
+
+if (read_event_kind == -1) {
+if (opt != -1) {
+read_opt = replay_get_byte();
+}
+read_event_kind = replay_get_byte();
+read_id = -1;
+replay_check_error();
+}
+
+if (opt != read_opt)
+break;
+/* Execute some events without searching them in the queue */
+switch (read_event_kind) {
+default:
+fprintf(stderr, "Unknown ID %d of replay event\n", 
read_event_kind);
+exit(1);
+break;
+}
+
+qemu_mutex_lock(&lock);
+
+Event *event = NULL;
+Event *curr = NULL;
+QT

[Qemu-devel] [RFC PATCH v2 40/49] replay: recording of the user input

2014-07-17 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 
---
 include/ui/input.h   |2 +
 replay/Makefile.objs |1 
 replay/replay-events.c   |   48 +
 replay/replay-input.c|  107 ++
 replay/replay-internal.h |   11 -
 replay/replay.h  |5 ++
 ui/input.c   |   79 ++
 7 files changed, 233 insertions(+), 20 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 f39889d..d7ed0b2 100755
--- a/replay/replay-events.c
+++ b/replay/replay-events.c
@@ -12,6 +12,7 @@
 #include "replay.h"
 #include "replay-internal.h"
 #include "block/thread-pool.h"
+#include "ui/input.h"
 
 typedef struct Event {
 int event_kind;
@@ -42,6 +43,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_SAVE) {
+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);
@@ -134,6 +145,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);
+}
+
 void replay_save_events(int opt)
 {
 qemu_mutex_lock(&lock);
@@ -155,6 +176,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;
 }
 }
 
@@ -183,6 +207,7 @@ void replay_read_events(int opt)
 if (opt != read_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:
@@ -190,6 +215,29 @@ 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_run_event(&e);
+
+replay_has_unread_data = 0;
+read_event_kind = -1;
+read_opt = -1;
+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_run_event(&e);
+
+replay_has_unread_data = 0;
+read_event_kind = -1;
+read_opt = -1;
+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..b754caf
--- /dev/null
+++ b/replay/replay-input.c
@@ -0,0 +1,107 @@
+/*
+ * replay-input.c
+ *
+ * Copyright (c) 2010-2014 Institute for System Programming 
+ *  

[Qemu-devel] [RFC PATCH v2 35/49] replay: thread pool

2014-07-17 Thread Pavel Dovgalyuk
This patch modifies thread pool to allow replaying asynchronous thread tasks
synchronously in replay mode.

Signed-off-by: Pavel Dovgalyuk 
---
 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|3 ++
 replay/replay.h |2 ++
 stubs/replay.c  |4 +++
 tests/test-thread-pool.c|7 +++---
 thread-pool.c   |   53 +--
 9 files changed, 69 insertions(+), 25 deletions(-)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index a857def..f600736 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1025,7 +1025,9 @@ static BlockDriverAIOCB *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 BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
@@ -1853,7 +1855,7 @@ static BlockDriverAIOCB *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 902eab6..212307c 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -158,7 +158,9 @@ static BlockDriverAIOCB *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 32afcdd..df74f8d 100644
--- a/include/block/thread-pool.h
+++ b/include/block/thread-pool.h
@@ -33,9 +33,11 @@ void thread_pool_free(ThreadPool *pool);
 
 BlockDriverAIOCB *thread_pool_submit_aio(ThreadPool *pool,
 ThreadPoolFunc *func, void *arg,
-BlockDriverCompletionFunc *cb, void *opaque);
+BlockDriverCompletionFunc *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 81a5a6b..f39889d 100755
--- a/replay/replay-events.c
+++ b/replay/replay-events.c
@@ -11,6 +11,7 @@
 
 #include "replay.h"
 #include "replay-internal.h"
+#include "block/thread-pool.h"
 
 typedef struct Event {
 int event_kind;
@@ -38,6 +39,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);
@@ -125,6 +129,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);
+}
+
 void replay_save_events(int opt)
 {
 qemu_mutex_lock(&lock);
@@ -143,6 +152,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;
 }
@@ -175,6 +185,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 bbb117e..3f97fd7 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -40,7 +40,8

[Qemu-devel] [RFC PATCH v2 11/49] piix: do not raise irq while loading vmstate

2014-07-17 Thread Pavel Dovgalyuk
This patch disables raising an irq while loading the state of PCI bridge.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/pci-host/piix.c |   22 --
 1 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index e0e0946..86d6d20 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -409,7 +409,7 @@ static void piix3_set_irq_pic(PIIX3State *piix3, int 
pic_irq)
  (pic_irq * PIIX_NUM_PIRQS;
 }
 
-static void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level)
+static void piix3_set_irq_level_internal(PIIX3State *piix3, int pirq, int 
level)
 {
 int pic_irq;
 uint64_t mask;
@@ -422,6 +422,18 @@ static void piix3_set_irq_level(PIIX3State *piix3, int 
pirq, int level)
 mask = 1ULL << ((pic_irq * PIIX_NUM_PIRQS) + pirq);
 piix3->pic_levels &= ~mask;
 piix3->pic_levels |= mask * !!level;
+}
+
+static void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level)
+{
+int pic_irq;
+
+pic_irq = piix3->dev.config[PIIX_PIRQC + pirq];
+if (pic_irq >= PIIX_NUM_PIC_IRQS) {
+return;
+}
+
+piix3_set_irq_level_internal(piix3, pirq, level);
 
 piix3_set_irq_pic(piix3, pic_irq);
 }
@@ -527,7 +539,13 @@ static void piix3_reset(void *opaque)
 static int piix3_post_load(void *opaque, int version_id)
 {
 PIIX3State *piix3 = opaque;
-piix3_update_irq_levels(piix3);
+int pirq;
+
+piix3->pic_levels = 0;
+for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
+piix3_set_irq_level_internal(piix3, pirq,
+pci_bus_get_irq_level(piix3->dev.bus, pirq));
+}
 return 0;
 }
 




[Qemu-devel] [RFC PATCH v2 32/49] replay: checkpoints

2014-07-17 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 
---
 block.c  |   11 +++
 cpus.c   |2 +-
 include/qemu/timer.h |6 --
 qemu-timer.c |   41 +
 replay/replay-internal.h |3 +++
 replay/replay.c  |   28 
 replay/replay.h  |6 ++
 stubs/replay.c   |   11 +++
 vl.c |3 ++-
 9 files changed, 99 insertions(+), 12 deletions(-)

diff --git a/block.c b/block.c
index 3ff1052..fb6c849 100644
--- a/block.c
+++ b/block.c
@@ -1914,6 +1914,11 @@ void bdrv_drain_all(void)
 BlockDriverState *bs;
 
 while (busy) {
+if (!replay_checkpoint(8)) {
+/* 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) {
@@ -1930,6 +1935,12 @@ void bdrv_drain_all(void)
 busy |= bs_busy;
 }
 }
+if (replay_mode == REPLAY_PLAY) {
+/* Skip checkpoints from the log */
+while (replay_checkpoint(8)) {
+/* Nothing */
+}
+}
 }
 
 /* make a BlockDriverState anonymous by removing from bdrv_state and
diff --git a/cpus.c b/cpus.c
index 15a2106..4f517ee 100644
--- a/cpus.c
+++ b/cpus.c
@@ -363,7 +363,7 @@ void qtest_clock_warp(int64_t dest)
 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);
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 9eaed56..6b00341 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -232,13 +232,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:
@@ -329,12 +330,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/qemu-timer.c b/qemu-timer.c
index 00a5d35..dcf9b14 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -457,7 +457,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;
@@ -465,6 +465,24 @@ 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_NONE && !runstate_is_running()) 
+|| !replay_checkpoint(run_all ? 2 : 3)) {
+return false;
+}
+break;
+case QEMU_CLOCK_HOST:
+if ((replay_mode != REPLAY_NONE && !runstate_is_running()) 
+|| !replay_checkpoint(run_all ? 5 : 6)) {
+return false;
+}
+break;
+}
+
 qemu_event_reset(&timer_list->timers_done_ev);
 if (!timer_list->clock->enabled) {
 goto out;
@@ -497,9 +515,9 @@ out:
 return progress;
 }
 
-bool qemu_clock_run_timers(QEMUClockType type)
+bool qemu_clock_run_timers(QEMUClockType type, bool run_all)
 {
-return timerlist_run_timers(main_loop_tlg.tl[type]);
+return timerlist_run_timers(main_loop_tlg.tl[type], run_all);
 }
 
 void timerlistgroup_init(QEMUTimerListGroup *tlg,
@@ -524,7 +542,7 @@ bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg)
 QEMUClockType type;
 bool progress = false;
 for (type = 0; type < QEMU_CLOCK_MAX; type++) {
-progress |= timerlist_run_timers(tlg->tl[type]);
+progress |= timerlist_run_timers(tlg->tl[type], false);
 }
 return progress;
 }
@@ -533,11 +551,18 @@ int64_t timerlistgroup_deadline_ns(QEMUTimerL

[Qemu-devel] [RFC PATCH v2 33/49] replay: bottom halves

2014-07-17 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 
---
 async.c  |   45 +++--
 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  |   17 +
 include/qemu/main-loop.h |1 +
 main-loop.c  |5 +
 replay/replay-events.c   |   16 
 replay/replay-internal.h |3 ++-
 replay/replay.h  |2 ++
 stubs/replay.c   |4 
 13 files changed, 97 insertions(+), 12 deletions(-)

diff --git a/async.c b/async.c
index 5b6fe6b..687cdb2 100644
--- a/async.c
+++ b/async.c
@@ -26,6 +26,7 @@
 #include "block/aio.h"
 #include "block/thread-pool.h"
 #include "qemu/main-loop.h"
+#include "replay/replay.h"
 
 /***/
 /* bottom halves (can be seen as timers which expire ASAP) */
@@ -38,24 +39,52 @@ struct QEMUBH {
 bool scheduled;
 bool idle;
 bool deleted;
+bool replay;
+uint64_t id;
 };
 
 QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
 {
-QEMUBH *bh;
+QEMUBH *bh, **last;
 bh = g_malloc0(sizeof(QEMUBH));
 bh->ctx = ctx;
 bh->cb = cb;
 bh->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;
+if (replay_mode != REPLAY_NONE) {
+/* Slower way, but this is a queue and not a stack.
+   Replay will process the BH in the same order they 
+   came into the queue. */
+last = &ctx->first_bh;
+while (*last) {
+last = &(*last)->next;
+}
+smp_wmb();
+*last = bh;
+} else {
+bh->next = ctx->first_bh;
+/* Make sure that the members are ready before putting bh into list */
+smp_wmb();
+ctx->first_bh = bh;
+}
 qemu_mutex_unlock(&ctx->bh_lock);
 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)
 {
@@ -78,7 +107,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 53cbe92..05aadea 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -12,6 +12,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 604152a..0762743 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -32,6 +32,7 @@
 #include "internal.h"
 #include 
 #include 
+#include "replay/replay.h"
 
 /* #define DEBUG_AHCI */
 
@@ -1132,7 +1133,8 @@ static int ahci_async_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 3a38f1e..3df26f0 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/blockdev.h"
+#include "replay/replay.h"
 
 #include 
 
@@ -409,7 +410,8 @@ BlockDriverAIOCB *ide_issue_trim(BlockDriverState *bs,
 TrimAIOCB *iocb;
 
 iocb = qemu_aio_get(&trim_aiocb_info, bs, cb, opaque);
-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/h

[Qemu-devel] [RFC PATCH v2 37/49] replay: initialization and deinitialization

2014-07-17 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 
---
 exec.c   |1 
 replay/replay-internal.h |2 +
 replay/replay.c  |  127 ++
 replay/replay.h  |   11 
 vl.c |5 ++
 5 files changed, 146 insertions(+), 0 deletions(-)

diff --git a/exec.c b/exec.c
index 36adb62..050e0a8 100644
--- a/exec.c
+++ b/exec.c
@@ -732,6 +732,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.h b/replay/replay-internal.h
index 3f97fd7..7e5b3af 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -36,6 +36,8 @@
 
 /* for checkpoint event */
 #define EVENT_CHECKPOINT96
+/* end of log event */
+#define EVENT_END   127
 
 /* Asynchronous events IDs */
 
diff --git a/replay/replay.c b/replay/replay.c
index 225d8ec..c583bb4 100755
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -13,10 +13,18 @@
 #include "replay.h"
 #include "replay-internal.h"
 
+/* Current version of the replay mechanism.
+   Increase it when file format changes. */
+#define REPLAY_VERSION  0xe02001
+/* Size of replay log header */
+#define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t))
+
 int replay_mode = REPLAY_NONE;
 /*! Stores current submode for PLAY mode */
 int play_submode = REPLAY_PLAY_UNKNOWN;
 
+/* Name of replay file  */
+static char *replay_filename;
 /* Suffix for the disk images filenames */
 char *replay_image_suffix;
 
@@ -240,3 +248,122 @@ int replay_checkpoint(unsigned int checkpoint)
 
 return 1;
 }
+
+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_SAVE:
+fmode = "wb";
+break;
+case REPLAY_PLAY:
+fmode = "rb";
+play_submode = REPLAY_PLAY_NORMAL;
+break;
+default:
+fprintf(stderr, "Replay: internal error: invalid replay mode\n");
+exit(1);
+}
+
+atexit(replay_finish);
+
+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.skipping_instruction = 0;
+replay_state.current_step = 0;
+
+/* skip file header for SAVE and check it for PLAY */
+if (replay_mode == REPLAY_SAVE) {
+fseek(replay_file, HEADER_SIZE, SEEK_SET);
+} else if (replay_mode == REPLAY_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, int mode)
+{
+const char *fname;
+
+fname = qemu_opt_get(opts, "fname");
+if (!fname) {
+fprintf(stderr, "File name not specified for replay\n");
+exit(1);
+}
+
+const char *suffix = qemu_opt_get(opts, "suffix");
+if (suffix) {
+replay_image_suffix = g_strdup(suffix);
+} else {
+replay_image_suffix = g_strdup("replay_qcow");
+}
+
+replay_enable(fname, mode);
+}
+
+void replay_init_timer(void)
+{
+if (replay_mode == REPLAY_NONE) {
+return;
+}
+
+replay_enable_events();
+}
+
+void replay_finish(void)
+{
+if (replay_mode == REPLAY_NONE) {
+return;
+}
+
+replay_save_instructions();
+
+/* finalize the file */
+if (replay_file) {
+if (replay_mode == REPLAY_SAVE) {
+uint64_t offset = 0;
+/* write end event */
+replay_put_event(EVENT_END);
+
+/* write header */
+fseek(replay_file, 0, SEEK_SET);
+replay_put_dword(REPLAY_VERSION);
+replay_put_qword(offset);
+}
+
+fclose(replay_file);
+replay_file = NULL;
+}
+if (replay_filename) {
+g_free(replay_filename);
+replay_filename = NULL;
+}
+if (replay_image_suffix) {
+g_free(replay_image_suffix);
+replay_image_suffix = NULL;
+}
+
+replay_finish_events();
+}
diff --git a/replay/replay.h b/replay/replay.h
index e96c74f..e066cb2 100755
--- a/replay/replay.h
+++ b/replay/replay.h
@@ -16,6 +16,8 @@
 #include 
 #include 
 
+struct QemuOpts;
+
 /* replay mod

[Qemu-devel] [RFC PATCH v2 19/49] replay: global variables and function stubs

2014-07-17 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 
---
 Makefile.target  |1 +
 replay/Makefile.objs |1 +
 replay/replay.c  |   19 +++
 replay/replay.h  |   32 
 stubs/Makefile.objs  |1 +
 stubs/replay.c   |9 +
 6 files changed, 63 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 137d0b0..9830313 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -76,6 +76,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/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..5a69465
--- /dev/null
+++ b/replay/replay.c
@@ -0,0 +1,19 @@
+/*
+ * replay.c
+ *
+ * Copyright (c) 2010-2014 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"
+
+int replay_mode = REPLAY_NONE;
+/*! Stores current submode for PLAY mode */
+int play_submode = REPLAY_PLAY_UNKNOWN;
+
+/* Suffix for the disk images filenames */
+char *replay_image_suffix;
diff --git a/replay/replay.h b/replay/replay.h
new file mode 100755
index 000..a883aa4
--- /dev/null
+++ b/replay/replay.h
@@ -0,0 +1,32 @@
+#ifndef REPLAY_H
+#define REPLAY_H
+
+/*
+ * replay.h
+ *
+ * Copyright (c) 2010-2014 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.
+ *
+ */
+
+/* replay modes */
+#define REPLAY_NONE 0
+#define REPLAY_SAVE 1
+#define REPLAY_PLAY 2
+/* replay submodes */
+#define REPLAY_PLAY_UNKNOWN 0
+/* Normal log replaying */
+#define REPLAY_PLAY_NORMAL  1
+
+extern int replay_mode;
+extern char *replay_image_suffix;
+/*! Shift value for icount based on replay or zero, if it is disabled. */
+extern int replay_icount;
+
+/*! Returns replay play submode */
+int replay_get_play_submode(void);
+
+#endif
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 528e161..b90c60a 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -26,6 +26,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..1e99ca4
--- /dev/null
+++ b/stubs/replay.c
@@ -0,0 +1,9 @@
+#include "replay/replay.h"
+
+int replay_mode;
+int replay_icount;
+
+int replay_get_play_submode(void)
+{
+return 0;
+}




[Qemu-devel] [RFC PATCH v2 16/49] target: save cpu state fields

2014-07-17 Thread Pavel Dovgalyuk
This patch adds interrupt fields to VMState for correct saving the CPU state.

Signed-off-by: Pavel Dovgalyuk 
---
 target-arm/machine.c  |5 -
 target-i386/machine.c |5 -
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/target-arm/machine.c b/target-arm/machine.c
index 3bcc7cc..29bfc10 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -218,7 +218,7 @@ static int cpu_post_load(void *opaque, int version_id)
 
 const VMStateDescription vmstate_arm_cpu = {
 .name = "cpu",
-.version_id = 20,
+.version_id = 21,
 .minimum_version_id = 20,
 .pre_save = cpu_pre_save,
 .post_load = cpu_post_load,
@@ -259,6 +259,9 @@ const VMStateDescription vmstate_arm_cpu = {
 VMSTATE_UINT64(env.exception.vaddress, ARMCPU),
 VMSTATE_TIMER(gt_timer[GTIMER_PHYS], ARMCPU),
 VMSTATE_TIMER(gt_timer[GTIMER_VIRT], ARMCPU),
+/* Fields required by replay */
+VMSTATE_UINT32_V(parent_obj.interrupt_request, ARMCPU, 21),
+VMSTATE_INT32_V(parent_obj.exception_index, ARMCPU, 21),
 VMSTATE_END_OF_LIST()
 },
 .subsections = (VMStateSubsection[]) {
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 16d2f6a..9dfac33 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -605,7 +605,7 @@ static const VMStateDescription vmstate_msr_hyperv_time = {
 
 VMStateDescription vmstate_x86_cpu = {
 .name = "cpu",
-.version_id = 12,
+.version_id = 13,
 .minimum_version_id = 3,
 .pre_save = cpu_pre_save,
 .post_load = cpu_post_load,
@@ -702,6 +702,9 @@ VMStateDescription vmstate_x86_cpu = {
 VMSTATE_UINT64_V(env.xcr0, X86CPU, 12),
 VMSTATE_UINT64_V(env.xstate_bv, X86CPU, 12),
 VMSTATE_YMMH_REGS_VARS(env.ymmh_regs, X86CPU, CPU_NB_REGS, 12),
+/* Fields required by replay */
+VMSTATE_UINT32_V(parent_obj.interrupt_request, X86CPU, 13),
+VMSTATE_INT32_V(parent_obj.exception_index, X86CPU, 13),
 VMSTATE_END_OF_LIST()
 /* The above list is not sorted /wrt version numbers, watch out! */
 },




[Qemu-devel] [RFC PATCH v2 12/49] mc146818rtc: add missed field to vmstate

2014-07-17 Thread Pavel Dovgalyuk
This patch adds irq_reinject_on_ack_count field to VMState to allow correct
saving/loading the state of MC146818 RTC.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/timer/mc146818rtc.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 9d817ca..c204abb 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -735,7 +735,7 @@ static int rtc_post_load(void *opaque, int version_id)
 
 static const VMStateDescription vmstate_rtc = {
 .name = "mc146818rtc",
-.version_id = 3,
+.version_id = 4,
 .minimum_version_id = 1,
 .post_load = rtc_post_load,
 .fields = (VMStateField[]) {
@@ -752,6 +752,7 @@ static const VMStateDescription vmstate_rtc = {
 VMSTATE_INT64_V(offset, RTCState, 3),
 VMSTATE_TIMER_V(update_timer, RTCState, 3),
 VMSTATE_UINT64_V(next_alarm_time, RTCState, 3),
+VMSTATE_UINT16_V(irq_reinject_on_ack_count, RTCState, 4),
 VMSTATE_END_OF_LIST()
 }
 };




[Qemu-devel] [RFC PATCH v2 34/49] replay: replay aio requests

2014-07-17 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 
---
 block.c   |   79 +++--
 block/qcow2.c |4 ++
 dma-helpers.c |6 ++--
 hw/block/virtio-blk.c |   10 +++---
 hw/ide/atapi.c|9 --
 hw/ide/core.c |   14 ++---
 include/block/block.h |   15 +
 include/qemu-common.h |2 +
 qemu-io-cmds.c|2 +
 stubs/replay.c|5 +++
 trace-events  |2 +
 util/iov.c|4 ++
 12 files changed, 126 insertions(+), 26 deletions(-)

diff --git a/block.c b/block.c
index fb6c849..849b75a 100644
--- a/block.c
+++ b/block.c
@@ -84,7 +84,8 @@ static BlockDriverAIOCB 
*bdrv_co_aio_rw_vector(BlockDriverState *bs,
BdrvRequestFlags flags,
BlockDriverCompletionFunc *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);
@@ -4370,7 +4371,19 @@ BlockDriverAIOCB *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);
+}
+
+BlockDriverAIOCB *bdrv_aio_readv_replay(BlockDriverState *bs,
+int64_t sector_num,
+QEMUIOVector *qiov, int nb_sectors,
+BlockDriverCompletionFunc *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);
 }
 
 BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
@@ -4380,7 +4393,19 @@ BlockDriverAIOCB *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);
+}
+
+BlockDriverAIOCB *bdrv_aio_writev_replay(BlockDriverState *bs,
+ int64_t sector_num,
+ QEMUIOVector *qiov, int nb_sectors,
+ BlockDriverCompletionFunc *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, false);
 }
 
 BlockDriverAIOCB *bdrv_aio_write_zeroes(BlockDriverState *bs,
@@ -4391,7 +4416,7 @@ BlockDriverAIOCB *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);
 }
 
 
@@ -4527,7 +4552,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;
@@ -4565,7 +4591,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;
@@ -4714,7 +4740,11 @@ 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 (acb->common.replay) {
+acb->bh = aio_bh_new_replay(bdrv_get_aio_c

[Qemu-devel] [RFC PATCH v2 38/49] replay: command line options

2014-07-17 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 
---
 cpus.c  |   15 +--
 qemu-options.hx |   27 +
 vl.c|   72 +--
 3 files changed, 109 insertions(+), 5 deletions(-)

diff --git a/cpus.c b/cpus.c
index 4f517ee..e16d8f8 100644
--- a/cpus.c
+++ b/cpus.c
@@ -829,12 +829,21 @@ 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
-  are idle.  */
+if (replay_mode == REPLAY_PLAY
+&& all_cpu_threads_idle() && first_cpu->halted) {
+/* wakeup iothread when there is no code to execute in replay mode */
 qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
+g_main_context_wakeup(context);
 qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
+} else {
+while (all_cpu_threads_idle()) {
+   /* 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); 
+}
 }
 
 while (iothread_requesting_mutex) {
diff --git a/qemu-options.hx b/qemu-options.hx
index 9e54686..7548f87 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3348,6 +3348,33 @@ Dump json-encoded vmstate information for current 
machine type to file
 in @var{file}
 ETEXI
 
+DEF("record", HAS_ARG, QEMU_OPTION_record,
+"-record fname=[,suffix=,snapshot=]\n"
+"writes replay file for latter replaying\n",
+QEMU_ARCH_ALL)
+STEXI
+@item -record fname=@var{file}[,suffix=@var{suffix},snapshot=@var{snapshot}]
+Writes compact execution trace into @var{file}.
+Changes for disk images are written
+into separate files with @var{suffix} added. If no @var{suffix} is
+specified, "replay_qcow" is used as suffix.
+If @var{snapshot} parameter is set as off, then original disk image will be
+modified. Default value is on.
+ETEXI
+
+DEF("replay", HAS_ARG, QEMU_OPTION_replay,
+"-replay fname=[,suffix=,snapshot=]\n"
+"plays saved replay file\n", QEMU_ARCH_ALL)
+STEXI
+@item -replay 
fname=@var{filename}[,suffix=@var{suffix},snapshot=@var{snapshot}]
+Plays compact execution trace from @var{filename}.
+Changes for disk images and VM states are read
+from separate files with @var{suffix} added. If no @var{suffix} is
+specified, "replay_qcow" is used as suffix.
+If @var{snapshot} parameter is set as off, then original disk image will be
+modified. Default value is on.
+ETEXI
+
 HXCOMM This is the last statement. Insert new options before this line!
 STEXI
 @end table
diff --git a/vl.c b/vl.c
index 6050faf..f8c1e9e 100644
--- a/vl.c
+++ b/vl.c
@@ -538,6 +538,42 @@ static QemuOptsList qemu_mem_opts = {
 },
 };
 
+static QemuOptsList qemu_record_opts = {
+.name = "record",
+.head = QTAILQ_HEAD_INITIALIZER(qemu_record_opts.head),
+.desc = {
+{
+.name = "fname",
+.type = QEMU_OPT_STRING,
+},{
+.name = "suffix",
+.type = QEMU_OPT_STRING,
+},{
+.name = "snapshot",
+.type = QEMU_OPT_BOOL,
+},
+{ /* end of list */ }
+},
+};
+
+static QemuOptsList qemu_replay_opts = {
+.name = "replay",
+.head = QTAILQ_HEAD_INITIALIZER(qemu_replay_opts.head),
+.desc = {
+{
+.name = "fname",
+.type = QEMU_OPT_STRING,
+},{
+.name = "suffix",
+.type = QEMU_OPT_STRING,
+},{
+.name = "snapshot",
+.type = QEMU_OPT_BOOL,
+},
+{ /* end of list */ }
+},
+};
+
 /**
  * Get machine options
  *
@@ -2914,7 +2950,8 @@ out:
 int main(int argc, char **argv, char **envp)
 {
 int i;
-int snapshot, linux_boot;
+int snapshot, linux_boot, replay_snapshot;
+int not_compatible_replay_param = 0;
 const char *icount_option = NULL;
 const char *initrd_filename;
 const char *kernel_filename, *kernel_cmdline;
@@ -2986,6 +3023,8 @@ int main(int argc, char **argv, char **envp)
 qemu_add_opts(&qemu_msg_opts);
 qemu_add_opts(&qemu_name_opts);
 qemu_add_opts(&qemu_numa_opts);
+qemu_add_opts(&qemu_replay_opts);
+qemu_add_opts(&qemu_record_opts);
 
 runstate_init();
 
@@ -2999,6 +3038,7 @@ int main(int argc, char **argv, char **envp)
 cpu_model = NULL;
 ram_size = default_ram_size;
 snapshot = 0;
+replay_snapshot = 1;
 cyls = heads = secs = 0;
 translation = BIOS_ATA_TRAN

[Qemu-devel] [RFC PATCH v2 30/49] replay: recording and replaying different timers

2014-07-17 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 
---
 hw/timer/mc146818rtc.c   |2 -
 hw/timer/pl031.c |   10 
 include/qemu-common.h|1 
 replay/replay-internal.h |7 +++
 replay/replay-time.c |  106 ++
 replay/replay.h  |8 +++
 vl.c |   16 ++-
 7 files changed, 145 insertions(+), 5 deletions(-)

diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index c204abb..b7c842f 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -703,7 +703,7 @@ static void rtc_set_date_from_host(ISADevice *dev)
 RTCState *s = MC146818_RTC(dev);
 struct tm tm;
 
-qemu_get_timedate(&tm, 0);
+qemu_get_timedate_no_warning(&tm, 0);
 
 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 f8e5abc..02c814f 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,14 @@ static int pl031_init(SysBusDevice *dev)
 sysbus_init_mmio(dev, &s->iomem);
 
 sysbus_init_irq(dev, &s->irq);
-qemu_get_timedate(&tm, 0);
+if (replay_mode == REPLAY_SAVE) {
+qemu_get_timedate_no_warning(&tm, 0);
+replay_save_tm(&tm);
+} else if (replay_mode == REPLAY_PLAY) {
+replay_read_tm(&tm);
+} else {
+qemu_get_timedate_no_warning(&tm, 0);
+}
 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 ae76197..48013ce 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -121,6 +121,7 @@ extern int use_icount;
 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 a4fbc26..79e23ee 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -15,10 +15,17 @@
 #include 
 #include "sysemu/sysemu.h"
 
+<<< current
 /* for software interrupt */
 #define EVENT_INTERRUPT 15
 /* for emulated exceptions */
 #define EVENT_EXCEPTION 23
+===
+/* for time_t event */
+#define EVENT_TIME_T1
+/* for tm event */
+#define EVENT_TM2
+>>> patched
 /* for async events */
 #define EVENT_ASYNC 24
 #define EVENT_ASYNC_OPT 25
diff --git a/replay/replay-time.c b/replay/replay-time.c
index 905d3e4..0811d22 100755
--- a/replay/replay-time.c
+++ b/replay/replay-time.c
@@ -73,3 +73,109 @@ int64_t replay_read_clock(unsigned int 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_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);
+}
+}
+}
+
+/*! Reads time_t value from the log. Stops execution in case of error */
+static time_t replay_read_time_t(void)
+{
+if (replay_file) {
+time_t tm;
+
+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;
+
+return tm;
+}
+
+fprintf(stderr, "REPLAY INTERNAL ERROR %d\n", __LINE__);
+exit(1);
+}
+
+void replay_save_tm(struct tm *tm)
+{
+replay_save_instructions();
+
+if (replay_file) {
+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);
+}
+}
+
+void replay_read_tm(struct tm *tm)
+{
+if (replay_f

[Qemu-devel] [RFC PATCH v2 31/49] replay: shutdown event

2014-07-17 Thread Pavel Dovgalyuk
This patch records and replays simulator shutdown event.

Signed-off-by: Pavel Dovgalyuk 
---
 include/sysemu/sysemu.h  |1 +
 replay/replay-internal.h |   13 ++---
 replay/replay.c  |   11 +++
 replay/replay.h  |5 +
 vl.c |8 +++-
 5 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 1ebfef9..9000feb 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -57,6 +57,7 @@ void qemu_register_suspend_notifier(Notifier *notifier);
 void qemu_system_wakeup_request(WakeupReason reason);
 void qemu_system_wakeup_enable(WakeupReason reason, bool enabled);
 void qemu_register_wakeup_notifier(Notifier *notifier);
+void qemu_system_shutdown_request_impl(void);
 void qemu_system_shutdown_request(void);
 void qemu_system_powerdown_request(void);
 void qemu_register_powerdown_notifier(Notifier *notifier);
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index 79e23ee..033dbdc 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -15,17 +15,16 @@
 #include 
 #include "sysemu/sysemu.h"
 
-<<< current
-/* for software interrupt */
-#define EVENT_INTERRUPT 15
-/* for emulated exceptions */
-#define EVENT_EXCEPTION 23
-===
 /* for time_t event */
 #define EVENT_TIME_T1
 /* for tm event */
 #define EVENT_TM2
->>> patched
+/* for software interrupt */
+#define EVENT_INTERRUPT 15
+/* for shutdown request */
+#define EVENT_SHUTDOWN  20
+/* for emulated exceptions */
+#define EVENT_EXCEPTION 23
 /* for async events */
 #define EVENT_ASYNC 24
 #define EVENT_ASYNC_OPT 25
diff --git a/replay/replay.c b/replay/replay.c
index 41a27a9..2067d6b 100755
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -43,6 +43,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_impl();
+break;
 case EVENT_INSTRUCTION:
 first_cpu->instructions_count = replay_get_dword();
 return res;
@@ -201,3 +205,10 @@ bool replay_has_interrupt(void)
 }
 return false;
 }
+
+void replay_shutdown_request(void)
+{
+if (replay_mode == REPLAY_SAVE) {
+replay_put_event(EVENT_SHUTDOWN);
+}
+}
diff --git a/replay/replay.h b/replay/replay.h
index 16e368c..a84c57c 100755
--- a/replay/replay.h
+++ b/replay/replay.h
@@ -83,6 +83,11 @@ void replay_save_tm(struct tm *tm);
 /*! Reads struct tm value from the log. Stops execution in case of error */
 void replay_read_tm(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 86aba43..1a837e6 100644
--- a/vl.c
+++ b/vl.c
@@ -1929,13 +1929,19 @@ void qemu_system_killed(int signal, pid_t pid)
 qemu_system_shutdown_request();
 }
 
-void qemu_system_shutdown_request(void)
+void qemu_system_shutdown_request_impl(void)
 {
 trace_qemu_system_shutdown_request();
 shutdown_requested = 1;
 qemu_notify_event();
 }
 
+void qemu_system_shutdown_request(void)
+{
+replay_shutdown_request();
+qemu_system_shutdown_request_impl();
+}
+
 static void qemu_system_powerdown(void)
 {
 qapi_event_send_powerdown(&error_abort);




[Qemu-devel] [RFC PATCH v2 21/49] sysemu: system functions for replay

2014-07-17 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 
---
 arch_init.c |8 
 cpu-exec.c  |6 --
 cpus.c  |4 ++--
 include/exec/exec-all.h |4 +++-
 include/sysemu/cpus.h   |1 +
 include/sysemu/sysemu.h |1 +
 savevm.c|   32 ++--
 translate-all.c |8 
 8 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index 8ddaf35..5ee33d9 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -52,6 +52,7 @@
 #include "exec/ram_addr.h"
 #include "hw/acpi/acpi.h"
 #include "qemu/host-utils.h"
+#include "replay/replay.h"
 
 #ifdef DEBUG_ARCH_INIT
 #define DPRINTF(fmt, ...) \
@@ -1092,6 +1093,13 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 
 total_ram_bytes -= length;
 }
+if (replay_mode == REPLAY_PLAY) {
+RAMBlock *block;
+/* Clear the blocks' memory instead of resetting the machine */
+QTAILQ_FOREACH(block, &ram_list.blocks, next) {
+memset(block->host, 0, block->length);
+}
+}
 } else if (flags & RAM_SAVE_FLAG_COMPRESS) {
 void *host;
 uint8_t ch;
diff --git a/cpu-exec.c b/cpu-exec.c
index 38e5f02..66a693c 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -189,12 +189,14 @@ static inline TranslationBlock *tb_find_fast(CPUArchState 
*env)
 
 static CPUDebugExcpHandler *debug_excp_handler;
 
-void cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
+CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
 {
+CPUDebugExcpHandler *old = debug_excp_handler;
 debug_excp_handler = handler;
+return old;
 }
 
-static void cpu_handle_debug_exception(CPUArchState *env)
+void cpu_handle_debug_exception(CPUArchState *env)
 {
 CPUState *cpu = ENV_GET_CPU(env);
 CPUWatchpoint *wp;
diff --git a/cpus.c b/cpus.c
index 5e7f2cf..bbad529 100644
--- a/cpus.c
+++ b/cpus.c
@@ -85,7 +85,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;
 
@@ -1033,7 +1033,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 528928f..4b7a241 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -212,6 +212,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)
@@ -385,7 +386,8 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, 
target_ulong addr);
 
 typedef void (CPUDebugExcpHandler)(CPUArchState *env);
 
-void cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);
+CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);
+void cpu_handle_debug_exception(CPUArchState *env);
 
 /* vl.c */
 extern int singlestep;
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index 4f79081..8455e0e 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/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d8539fd..1ebfef9 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -76,6 +76,7 @@ void qemu_add_machine_init_done_notifier(Notifier *notify);
 
 void do_savevm(Monitor *mon, const QDict *qdict);
 int load_vmstate(const char *name);
+int save_vmstate(Monitor *mon, const char *name);
 void do_delvm(Monitor *mon, const QDict *qdict);
 void do_info_snapshots(Monitor *mon, const QDict *qdict);
 
diff --git a/savevm.c b/savevm.c
index e19ae0a..9136778 100644
--- a/savevm.c
+++ b/savevm.c
@@ -42,7 +42,7 @@
 #include "qemu/iov.h"
 #include "block/snapshot.h"
 #include "block/qapi.h"
-
+#include "replay/replay.h"
 
 #ifndef ETH_P_RARP
 #define ETH_P_RARP 0x8035
@@ -1039,7 +1039,7 @@ static int del_existing_snapshots(Monitor *mon, const 
char *name)
 return 0;
 }
 
-void do_savevm(Monitor *mon, const QDict *qdict)
+int save_vmstate(Monitor *mon, const char *name)
 {
 BlockDriverState *bs, *bs1;
 QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
@@ -1049,7 +1049,7 @@ void do_savevm(Monitor *mon, con

[Qemu-devel] [RFC PATCH v2 20/49] block: add suffix parameter to bdrv_open functions

2014-07-17 Thread Pavel Dovgalyuk
This patch adds parameter with suffix for overlay filenames. This parameter
will be used by replay to automatically create overlay files based on
drive images supplied to VM.

Signed-off-by: Pavel Dovgalyuk 
---
 block.c   |   44 ++--
 block/blkdebug.c  |2 +-
 block/blkverify.c |4 ++--
 block/cow.c   |2 +-
 block/qcow.c  |2 +-
 block/qcow2.c |6 +++---
 block/qed.c   |2 +-
 block/sheepdog.c  |4 ++--
 block/vmdk.c  |8 
 block/vvfat.c |2 +-
 blockdev.c|   11 ++-
 include/block/block.h |6 +++---
 qemu-img.c|6 +++---
 qemu-io.c |4 ++--
 qemu-nbd.c|2 +-
 15 files changed, 61 insertions(+), 44 deletions(-)

diff --git a/block.c b/block.c
index 8800a6b..3ff1052 100644
--- a/block.c
+++ b/block.c
@@ -35,6 +35,7 @@
 #include "qmp-commands.h"
 #include "qemu/timer.h"
 #include "qapi-event.h"
+#include "replay/replay.h"
 
 #ifdef CONFIG_BSD
 #include 
@@ -1209,7 +1210,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict 
*options, Error **errp)
 assert(bs->backing_hd == NULL);
 ret = bdrv_open(&backing_hd,
 *backing_filename ? backing_filename : NULL, NULL, options,
-bdrv_backing_flags(bs->open_flags), back_drv, &local_err);
+bdrv_backing_flags(bs->open_flags), back_drv, &local_err, 
NULL);
 if (ret < 0) {
 bdrv_unref(backing_hd);
 backing_hd = NULL;
@@ -1244,7 +1245,7 @@ free_exit:
  */
 int bdrv_open_image(BlockDriverState **pbs, const char *filename,
 QDict *options, const char *bdref_key, int flags,
-bool allow_none, Error **errp)
+bool allow_none, Error **errp, const char *fname_suffix)
 {
 QDict *image_options;
 int ret;
@@ -1271,14 +1272,14 @@ int bdrv_open_image(BlockDriverState **pbs, const char 
*filename,
 goto done;
 }
 
-ret = bdrv_open(pbs, filename, reference, image_options, flags, NULL, 
errp);
+ret = bdrv_open(pbs, filename, reference, image_options, flags, NULL, 
errp, NULL);
 
 done:
 qdict_del(options, bdref_key);
 return ret;
 }
 
-int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
+int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp, 
const char *fname_suffix)
 {
 /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
 char *tmp_filename = g_malloc0(PATH_MAX + 1);
@@ -1303,17 +1304,29 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int 
flags, Error **errp)
 total_size &= BDRV_SECTOR_MASK;
 
 /* Create the temporary image */
-ret = get_tmp_filename(tmp_filename, PATH_MAX + 1);
-if (ret < 0) {
-error_setg_errno(errp, -ret, "Could not get temporary filename");
-goto out;
+/* We will not delete created file in record/replay mode */
+if (replay_mode != REPLAY_NONE && fname_suffix) {
+ret = snprintf(tmp_filename, PATH_MAX + 1, "%s.%s", bs->filename, 
fname_suffix);
+if (ret < 0) {
+goto out;
+}
+} else {
+ret = get_tmp_filename(tmp_filename, PATH_MAX + 1);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "Could not get temporary filename");
+goto out;
+}
 }
 
 bdrv_qcow2 = bdrv_find_format("qcow2");
 opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0,
 &error_abort);
 qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
-ret = bdrv_create(bdrv_qcow2, tmp_filename, opts, &local_err);
+if (replay_mode == REPLAY_PLAY) {
+ret = 0;
+} else {
+ret = bdrv_create(bdrv_qcow2, tmp_filename, opts, &local_err);
+}
 qemu_opts_del(opts);
 if (ret < 0) {
 error_setg_errno(errp, -ret, "Could not create temporary overlay "
@@ -1333,7 +1346,7 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int 
flags, Error **errp)
 bs_snapshot = bdrv_new("", &error_abort);
 
 ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
-flags, bdrv_qcow2, &local_err);
+flags, bdrv_qcow2, &local_err, NULL);
 if (ret < 0) {
 error_propagate(errp, local_err);
 goto out;
@@ -1363,7 +1376,7 @@ out:
  */
 int bdrv_open(BlockDriverState **pbs, const char *filename,
   const char *reference, QDict *options, int flags,
-  BlockDriver *drv, Error **errp)
+  BlockDriver *drv, Error **errp, const char *fname_suffix)
 {
 int ret;
 BlockDriverState *file = NULL, *bs;
@@ -1444,13 +1457,16 @@ int bdrv_open(BlockDriverState **pbs, const char 
*filename,
 }
 if (flags & BDRV_O_SNAPSHOT) {
 snapshot_flags = bdrv_temp_snapshot_flags(flags);
+if (replay_mode != REPLAY_NONE) {
+ 

[Qemu-devel] [RFC PATCH v2 22/49] replay: internal functions for replay log

2014-07-17 Thread Pavel Dovgalyuk
This patch adds functions to perform read and write operations
with replay log.

Signed-off-by: Pavel Dovgalyuk 
---
 replay/Makefile.objs |1 
 replay/replay-internal.c |  141 ++
 replay/replay-internal.h |   50 
 replay/replay.c  |6 ++
 4 files changed, 198 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..706b46b
--- /dev/null
+++ b/replay/replay-internal.c
@@ -0,0 +1,141 @@
+/*
+ * replay-internal.c
+ *
+ * Copyright (c) 2010-2014 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"
+
+volatile unsigned int replay_data_kind = -1;
+volatile unsigned int replay_has_unread_data;
+
+/* File for replay writing */
+FILE *replay_file;
+
+void replay_put_byte(unsigned char byte)
+{
+if (replay_file) {
+fwrite(&byte, sizeof(byte), 1, replay_file);
+}
+}
+
+void replay_put_event(unsigned char 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(unsigned int 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);
+}
+}
+
+unsigned char replay_get_byte(void)
+{
+unsigned char 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;
+}
+
+unsigned int replay_get_dword(void)
+{
+unsigned int 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..b959bca
--- /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-2014 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 
+
+extern volatile unsigned int replay_data_kind;
+extern volatile unsigned int replay_has_unread_data;
+
+/* File for replay writing */
+extern FILE *replay_file;
+
+void replay_put_byte(unsigned char byte);
+void replay_put_event(unsigned char event);
+void replay_put_word(uint16_t word);
+void replay_put_dword(unsigned int dword);
+void replay_put_qword(int64_t qword);
+void replay_put_array(const uint8_t *buf, size_t size);
+
+unsigned char replay_get_byte(void);
+uint16_t replay_get_word(void);
+unsigned int replay_get_dword(void);
+int64_t replay_get_qword(void);
+void replay_get_array(uint8_t *buf, size_t *siz

[Qemu-devel] [RFC PATCH v2 39/49] replay: snapshotting the virtual machine

2014-07-17 Thread Pavel Dovgalyuk
This patch adds 'period' parameter to the 'record' command line option. This
parameters turns on periodic snapshotting of the VM which could be used by
replay to move forward and backward in time.
If 'period' parameter is not specified, only one snapshot is made at the start
of the virtual machine.

Signed-off-by: Pavel Dovgalyuk 
---
 cpus.c   |   46 -
 qemu-options.hx  |3 -
 qemu-timer.c |4 +
 replay/replay-internal.h |   18 
 replay/replay.c  |  223 ++
 5 files changed, 287 insertions(+), 7 deletions(-)

diff --git a/cpus.c b/cpus.c
index e16d8f8..019cc0a 100644
--- a/cpus.c
+++ b/cpus.c
@@ -228,11 +228,22 @@ int64_t cpu_get_clock(void)
  */
 void cpu_enable_ticks(void)
 {
+int64_t ti;
 /* Here, the really thing protected by seqlock is cpu_clock_offset. */
 seqlock_write_lock(&timers_state.vm_clock_seqlock);
 if (!timers_state.cpu_ticks_enabled) {
 timers_state.cpu_ticks_offset -= cpu_get_real_ticks();
-timers_state.cpu_clock_offset -= get_clock();
+
+if (replay_mode == REPLAY_SAVE) {
+ti = get_clock();
+replay_save_clock(REPLAY_CLOCK_VIRTUAL, ti);
+} else if (replay_mode == REPLAY_PLAY) {
+ti = replay_read_clock(REPLAY_CLOCK_VIRTUAL);
+} else {
+ti = get_clock();
+}
+
+timers_state.cpu_clock_offset -= ti;
 timers_state.cpu_ticks_enabled = 1;
 }
 seqlock_write_unlock(&timers_state.vm_clock_seqlock);
@@ -437,6 +448,22 @@ void qemu_clock_warp(QEMUClockType type)
 }
 }
 
+static bool is_replay_enabled(void *opaque)
+{
+return replay_mode != REPLAY_NONE;
+}
+
+static const VMStateDescription vmstate_timers_for_replay = {
+.name = "timer for replay",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields  = (VMStateField []) {
+VMSTATE_INT64(cpu_ticks_prev, TimersState),
+VMSTATE_END_OF_LIST()
+}
+};
+
 static const VMStateDescription vmstate_timers = {
 .name = "timer",
 .version_id = 2,
@@ -446,6 +473,14 @@ static const VMStateDescription vmstate_timers = {
 VMSTATE_INT64(dummy, TimersState),
 VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2),
 VMSTATE_END_OF_LIST()
+},
+.subsections = (VMStateSubsection []) {
+{
+.vmsd = &vmstate_timers_for_replay,
+.needed = is_replay_enabled,
+}, {
+/* empty */
+}
 }
 };
 
@@ -537,9 +572,11 @@ static int do_vm_stop(RunState state)
 int ret = 0;
 
 if (runstate_is_running()) {
+runstate_set(state);
+/* Disable ticks can cause recursive call of vm_stop.
+   Stopping before calling functions prevents infinite recursion. */
 cpu_disable_ticks();
 pause_all_vcpus();
-runstate_set(state);
 vm_state_notify(0, state);
 qapi_event_send_stop(&error_abort);
 }
@@ -1320,10 +1357,9 @@ static void tcg_exec_all(void)
 CPUState *cpu = next_cpu;
 CPUArchState *env = cpu->env_ptr;
 
-qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
-  (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
-
 if (cpu_can_run(cpu)) {
+qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
+  (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
 r = tcg_cpu_exec(env);
 if (r == EXCP_DEBUG) {
 cpu_handle_guest_debug(cpu);
diff --git a/qemu-options.hx b/qemu-options.hx
index 7548f87..fcfc8d1 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3353,8 +3353,9 @@ DEF("record", HAS_ARG, QEMU_OPTION_record,
 "writes replay file for latter replaying\n",
 QEMU_ARCH_ALL)
 STEXI
-@item -record fname=@var{file}[,suffix=@var{suffix},snapshot=@var{snapshot}]
+@item -record 
fname=@var{file}[,period=@var{period},suffix=@var{suffix},snapshot=@var{snapshot}]
 Writes compact execution trace into @var{file}.
+VM state is auto saved every @var{period} second, if this parameter is 
specified.
 Changes for disk images are written
 into separate files with @var{suffix} added. If no @var{suffix} is
 specified, "replay_qcow" is used as suffix.
diff --git a/qemu-timer.c b/qemu-timer.c
index dcf9b14..0dcba4c 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -103,7 +103,9 @@ QEMUTimerList *timerlist_new(QEMUClockType type,
 QEMUClock *clock = qemu_clock_ptr(type);
 
 timer_list = g_malloc0(sizeof(QEMUTimerList));
-qemu_event_init(&timer_list->timers_done_ev, false);
+/* Create signaled event, because they should be signaled 
+   outside the timerlist_run_timers function */
+qemu_event_init(&timer_list->timers_done_ev, true);
 timer_list->clock = clock;
 timer_list->notify_cb = cb;
 timer_list->notify_opaque = opaque;
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
ind

[Qemu-devel] [RFC PATCH v2 23/49] cpu: invent instruction count for accurate replay

2014-07-17 Thread Pavel Dovgalyuk
This patch adds instructions count fields to cpu structure and
invents several functions for increasing this counter while executing
translation blocks.

Signed-off-by: Pavel Dovgalyuk 
---
 cpu-exec.c   |   14 -
 cpus.c   |5 ++
 exec.c   |4 +
 include/exec/cpu-defs.h  |1 
 include/qom/cpu.h|4 +
 replay/Makefile.objs |1 
 replay/replay-events.c   |   26 +
 replay/replay-internal.c |   14 +
 replay/replay-internal.h |   37 -
 replay/replay.c  |  136 ++
 replay/replay.h  |   16 +
 translate-all.c  |7 ++
 12 files changed, 260 insertions(+), 5 deletions(-)
 create mode 100755 replay/replay-events.c

diff --git a/cpu-exec.c b/cpu-exec.c
index 66a693c..13c0ec6 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -22,6 +22,7 @@
 #include "tcg.h"
 #include "qemu/atomic.h"
 #include "sysemu/qtest.h"
+#include "qemu/main-loop.h"
 
 void cpu_loop_exit(CPUState *cpu)
 {
@@ -283,19 +284,24 @@ int cpu_exec(CPUArchState *env)
 #else
 #error unsupported target CPU
 #endif
-cpu->exception_index = -1;
-
 /* prepare setjmp context for exception handling */
 for(;;) {
 if (sigsetjmp(cpu->jmp_env, 0) == 0) {
 /* if an exception is pending, we execute it here */
 if (cpu->exception_index >= 0) {
+if (cpu->exception_index == EXCP_REPLAY) {
+ret = cpu->exception_index;
+cpu->exception_index = -1;
+qemu_notify_event();
+break;
+}
 if (cpu->exception_index >= EXCP_INTERRUPT) {
 /* exit request from the cpu execution loop */
 ret = cpu->exception_index;
 if (ret == EXCP_DEBUG) {
 cpu_handle_debug_exception(env);
 }
+cpu->exception_index = -1;
 break;
 } else {
 #if defined(CONFIG_USER_ONLY)
@@ -601,6 +607,10 @@ int cpu_exec(CPUArchState *env)
 next_tb = 0;
 }
 }
+if (cpu->exception_index == EXCP_REPLAY) {
+/* go to exception_index checking */
+break;
+}
 if (unlikely(cpu->exit_request)) {
 cpu->exit_request = 0;
 cpu->exception_index = EXCP_INTERRUPT;
diff --git a/cpus.c b/cpus.c
index bbad529..eb2a795 100644
--- a/cpus.c
+++ b/cpus.c
@@ -937,6 +937,8 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 CPU_FOREACH(cpu) {
 cpu->thread_id = qemu_get_thread_id();
 cpu->created = true;
+/* init exception index here */
+cpu->exception_index = -1;
 }
 qemu_cond_signal(&qemu_cpu_cond);
 
@@ -1186,6 +1188,7 @@ void qemu_init_vcpu(CPUState *cpu)
 cpu->nr_cores = smp_cores;
 cpu->nr_threads = smp_threads;
 cpu->stopped = true;
+cpu->instructions_count = 0;
 if (kvm_enabled()) {
 qemu_kvm_start_vcpu(cpu);
 } else if (tcg_enabled()) {
@@ -1307,6 +1310,8 @@ static void tcg_exec_all(void)
 if (r == EXCP_DEBUG) {
 cpu_handle_guest_debug(cpu);
 break;
+} else if (r == EXCP_REPLAY) {
+break;
 }
 } else if (cpu->stop || cpu->stopped) {
 break;
diff --git a/exec.c b/exec.c
index 5a2a25e..36adb62 100644
--- a/exec.c
+++ b/exec.c
@@ -52,6 +52,7 @@
 #include "exec/ram_addr.h"
 
 #include "qemu/range.h"
+#include "replay/replay.h"
 
 //#define DEBUG_SUBPAGE
 
@@ -1615,6 +1616,9 @@ static void check_watchpoint(int offset, int len_mask, 
int flags)
 if (!cpu->watchpoint_hit) {
 cpu->watchpoint_hit = wp;
 tb_check_watchpoint(cpu);
+/* Current instruction is already processed by replay.
+   Set flags that allow skpping this events */
+replay_undo_last_instruction();
 if (wp->flags & BP_STOP_BEFORE_ACCESS) {
 cpu->exception_index = EXCP_DEBUG;
 cpu_loop_exit(cpu);
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 2dd6206..db9ae1a 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -59,6 +59,7 @@ typedef uint64_t target_ulong;
 #define EXCP_DEBUG  0x10002 /* cpu stopped after a breakpoint or 
singlestep */
 #define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) 
*/
 #define EXCP_YIELD  0x10004 /* cpu wants to yield timeslice to another */
+#define EXCP_REPLAY 0x10005 /* for breaking execution loop to make correct 
order of events */
 
 /* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for
addresses on the same page.  The top bits are the same.  This allows
diff --git a

Re: [Qemu-devel] [PATCH RESEND] ui/gtk: Restore keyboard focus after Page change

2014-07-17 Thread Gerd Hoffmann
On Do, 2014-07-17 at 14:21 +0100, Stefan Hajnoczi wrote:
> On Tue, Jul 08, 2014 at 02:28:57PM -0400, John Snow wrote:
> > (Resending for correct email addresses via MAINTAINERS ...)
> > 
> > In the GTK UI, after changing focus to the qemu monitor Notebook Page,
> > when restoring focus to the virtual machine page, the keyboard focus is lost
> > to a hidden GTK widget. Focus can only be restored to the virtual machine by
> > pressing "tab" or any of the four directional arrow keys.

> Ping?

commit e72b59fa93b68635f42cdb1b1134f60dd4040d7b

cheers,
  Gerd





Re: [Qemu-devel] [PATCH for-2.1] scsi: fix scsi disk symbol confusion in guest os

2014-07-17 Thread Paolo Bonzini

Il 17/07/2014 14:55, arei.gong...@huawei.com ha scritto:

From: Gonglei 

Assuming that we hotplug three virtio-scsi disk as follow steps:
1. start vm with virtio-scsi as system disk (guest os: suse11 sp3 ).
2. hotplug disk 1 (as lun2)
 -drive 
file=/Images/TestImg/kvm-disk-scsi_001,if=none,id=drive-scsi0-0-0-2,format=raw, 
\
 cache=none,aio=native -device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=2, \
 drive=drive-scsi0-0-0-2,id=scsi0-0-0-2
2. hotplug disk 2 (as lun3)
 -drive 
file=/Images/TestImg/kvm-disk-scsi_002,if=none,id=drive-scsi0-0-0-3,format=raw,\
 cache=none,aio=native -device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=3,\
 drive=drive-scsi0-0-0-3,id=scsi0-0-0-3
3. hotplug disk 3 (as lun4)
 -drive 
file=/Images/TestImg/kvm-disk-scsi_003,if=none,id=drive-scsi0-0-0-4,format=raw,\
 cache=none,aio=native -device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=4,\
 drive=drive-scsi0-0-0-4,id=scsi0-0-0-4

We can see lun2 as sdb, lun3 as sdc, lun4 as sdd in the guest os.
But after rebootint the guest, the scsi disk symbol will changed,
lun2 change to sdd, lun3 as sdc, lun4 as sdb.

Lun2 -> sdb   rebootlun2 -> sdd
Lun3 -> sdc   -->   lun3 -> sdc
Lun4 -> sdd lun4 -> sdb

In Linux os, the scsi_scan_host() will scan scsi host adapter's lun, firstly 
scan lun 0
and add into system, secondly send REPORT_LUNS command to qurey the other luns.

In QEMU, the scsi_target_emulate_report_luns() emulate the REPORT_LUNS command.
The function will scan virtio-scsi-bus's children and report to guest os 
finally.
 QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) {

The step of attaching device in QEMU:
 qdev_device_add
   qdev_set_parent_bus
  bus_add_child
  QTAILQ_INSERT_HEAD(&bus->children, kid, sibling); // insert list head

The latest hotplugged disk is at the head of bus->children list.

Finally those cause the disk symbol confusion in the guest os.

Fix the issue by QTAILQ_FOREACH_REVERSE replace QTAILQ_FOREACH in
scsi_target_emulate_report_luns(), which follow the FIFO principle for
scsi disks hotplugging.

Signed-off-by: Gonglei 
---
 hw/scsi/scsi-bus.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 4341754..b6671ea 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -371,7 +371,8 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq 
*r)
 memset(r->buf, 0, len);
 stl_be_p(&r->buf[0], n);
 i = found_lun0 ? 8 : 16;
-QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) {
+QTAILQ_FOREACH_REVERSE(kid, &r->req.bus->qbus.children,
+   ChildrenHead, sibling) {
 DeviceState *qdev = kid->child;
 SCSIDevice *dev = SCSI_DEVICE(qdev);




This is a change to the guest ABI, so you would have to make it only for 
the latest machine type; and this unfortunately disqualifies it already 
from 2.1 since it's very late.


Does this happen for cold-plugged disks too?  If so, I wonder if this 
would cause more pain than it fixes, because it could break machines 
when you upgrade QEMU.  In the end, /dev/sd* is not stable and people 
should use /dev/disk/* and/or partition labels instead.


Paolo



[Qemu-devel] [RFC PATCH v2 18/49] migration: add vmstate for int8 and char arrays

2014-07-17 Thread Pavel Dovgalyuk
This patch adds macros for vmstate int8 and char arrays.

Signed-off-by: Pavel Dovgalyuk 
---
 include/migration/vmstate.h |   13 +
 vmstate.c   |6 ++
 2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 9a001bd..2f7207b 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -143,6 +143,7 @@ extern const VMStateDescription vmstate_dummy;
 #endif
 
 extern const VMStateInfo vmstate_info_bool;
+extern const VMStateInfo vmstate_info_char;
 
 extern const VMStateInfo vmstate_info_int8;
 extern const VMStateInfo vmstate_info_int16;
@@ -694,6 +695,18 @@ extern const VMStateInfo vmstate_info_bitmap;
 #define VMSTATE_UINT64_ARRAY(_f, _s, _n)  \
 VMSTATE_UINT64_ARRAY_V(_f, _s, _n, 0)
 
+#define VMSTATE_INT8_ARRAY_V(_f, _s, _n, _v)  \
+VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int8, int8_t)
+
+#define VMSTATE_INT8_ARRAY(_f, _s, _n)\
+VMSTATE_INT8_ARRAY_V(_f, _s, _n, 0)
+
+#define VMSTATE_CHAR_ARRAY_V(_f, _s, _n, _v)  \
+VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_char, char)
+
+#define VMSTATE_CHAR_ARRAY(_f, _s, _n)\
+VMSTATE_CHAR_ARRAY_V(_f, _s, _n, 0)
+
 #define VMSTATE_INT16_ARRAY_V(_f, _s, _n, _v) \
 VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int16, int16_t)
 
diff --git a/vmstate.c b/vmstate.c
index ef2f87b..6a7f7c2 100644
--- a/vmstate.c
+++ b/vmstate.c
@@ -286,6 +286,12 @@ const VMStateInfo vmstate_info_int8 = {
 .put  = put_int8,
 };
 
+const VMStateInfo vmstate_info_char = {
+.name = "char",
+.get  = get_int8,
+.put  = put_int8,
+};
+
 /* 16 bit int */
 
 static int get_int16(QEMUFile *f, void *pv, size_t size)




[Qemu-devel] [RFC PATCH v2 29/49] replay: recording and replaying clock ticks

2014-07-17 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 
---
 cpus.c   |9 ++
 include/qemu/timer.h |   42 +-
 replay/Makefile.objs |1 +
 replay/replay-internal.h |   11 +++
 replay/replay-time.c |   75 ++
 replay/replay.h  |   17 ++
 stubs/replay.c   |9 ++
 7 files changed, 162 insertions(+), 2 deletions(-)
 create mode 100755 replay/replay-time.c

diff --git a/cpus.c b/cpus.c
index eb2a795..15a2106 100644
--- a/cpus.c
+++ b/cpus.c
@@ -40,6 +40,7 @@
 #include "qemu/bitmap.h"
 #include "qemu/seqlock.h"
 #include "qapi-event.h"
+#include "replay/replay.h"
 
 #ifndef _WIN32
 #include "qemu/compatfd.h"
@@ -206,11 +207,19 @@ int64_t cpu_get_clock(void)
 int64_t ti;
 unsigned start;
 
+if (replay_mode == REPLAY_PLAY) {
+return replay_read_clock(REPLAY_CLOCK_VIRTUAL);
+}
+
 do {
 start = seqlock_read_begin(&timers_state.vm_clock_seqlock);
 ti = cpu_get_clock_locked();
 } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start));
 
+if (replay_mode == REPLAY_SAVE) {
+replay_save_clock(REPLAY_CLOCK_VIRTUAL, ti);
+}
+
 return ti;
 }
 
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 7f9a074..9eaed56 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 */
 
@@ -699,8 +700,8 @@ static inline int64_t get_ticks_per_sec(void)
  * Low level clock functions
  */
 
-/* real time host monotonic timer */
-static inline int64_t get_clock_realtime(void)
+/* real time host monotonic timer implementation */
+static inline int64_t get_clock_realtime_impl(void)
 {
 struct timeval tv;
 
@@ -708,6 +709,23 @@ static inline int64_t get_clock_realtime(void)
 return tv.tv_sec * 10LL + (tv.tv_usec * 1000);
 }
 
+/* real time host monotonic timer interface */
+static inline int64_t get_clock_realtime(void)
+{
+int64_t result;
+
+if (replay_mode == REPLAY_SAVE) {
+result = get_clock_realtime_impl();
+replay_save_clock(REPLAY_CLOCK_REALTIME, result);
+} else if (replay_mode == REPLAY_PLAY) {
+result = replay_read_clock(REPLAY_CLOCK_REALTIME);
+} else {
+result = get_clock_realtime_impl();
+}
+
+return result;
+}
+
 /* Warning: don't insert tracepoints into these functions, they are
also used by simpletrace backend and tracepoints would cause
an infinite recursion! */
@@ -749,6 +767,8 @@ int64_t cpu_get_clock(void);
 /***/
 /* 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)
@@ -902,6 +922,24 @@ static inline int64_t cpu_get_real_ticks (void)
 }
 #endif
 
+#undef cpu_get_real_ticks 
+
+static inline int64_t cpu_get_real_ticks(void)
+{
+int64_t val;
+
+if (replay_mode == REPLAY_SAVE) {
+val = cpu_get_real_ticks_impl();
+replay_save_clock(REPLAY_CLOCK_REAL_TICKS, val);
+} else if (replay_mode == REPLAY_PLAY) {
+val = replay_read_clock(REPLAY_CLOCK_REAL_TICKS);
+} else {
+val = cpu_get_real_ticks_impl();
+}
+
+return val;
+}
+
 #ifdef CONFIG_PROFILER
 static inline int64_t profile_getclock(void)
 {
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 cffc4e2..a4fbc26 100755
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -24,12 +24,17 @@
 #define EVENT_ASYNC_OPT 25
 /* for instruction event */
 #define EVENT_INSTRUCTION   32
+/* for clock read/writes */
+#define EVENT_CLOCK 64
+/* some of grteater codes are reserved for clocks */
 
 /* Asynchronous events IDs */
 
 #define REPLAY_ASYNC_COUNT 0
 
 typedef struct ReplayState {
+/*! Cached clock values. */
+int64_t cached_clock[REPLAY_CLOCK_COUNT];
 /*! Nonzero, when next instruction is repeated one and was already
 processed. */
 int skipping_instruction;
@@ -78,6 

[Qemu-devel] [RFC PATCH v2 24/49] target-arm: instructions counting code for replay

2014-07-17 Thread Pavel Dovgalyuk
This patch adds instructions counting into the target-specific part
of arm simulator. In record/replay mode it inserts replay functions
calls and instructions counter increment into the translated code.

Signed-off-by: Pavel Dovgalyuk 
---
 target-arm/Makefile.objs   |1 +
 target-arm/helper.h|2 ++
 target-arm/replay_helper.c |   33 ++
 target-arm/translate.c |   48 +---
 4 files changed, 81 insertions(+), 3 deletions(-)
 create mode 100755 target-arm/replay_helper.c

diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index dcd167e..b8f61df 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -9,3 +9,4 @@ obj-y += neon_helper.o iwmmxt_helper.o
 obj-y += gdbstub.o
 obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
 obj-y += crypto_helper.o
+obj-y += replay_helper.o
diff --git a/target-arm/helper.h b/target-arm/helper.h
index facfcd2..0233b64 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -529,3 +529,5 @@ DEF_HELPER_FLAGS_2(neon_pmull_64_hi, TCG_CALL_NO_RWG_SE, 
i64, i64, i64)
 #ifdef TARGET_AARCH64
 #include "helper-a64.h"
 #endif
+
+DEF_HELPER_1(replay_instruction, i32, env)
diff --git a/target-arm/replay_helper.c b/target-arm/replay_helper.c
new file mode 100755
index 000..736cd51
--- /dev/null
+++ b/target-arm/replay_helper.c
@@ -0,0 +1,33 @@
+/*
+ * replay_helper.c
+ *
+ * Copyright (c) 2010-2014 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 "cpu.h"
+#include "exec/helper-proto.h"
+#include "replay/replay.h"
+
+uint32_t helper_replay_instruction(CPUARMState *env)
+{
+CPUState *cpu = ENV_GET_CPU(env);
+if (replay_mode == REPLAY_PLAY
+&& !replay_has_instruction()) {
+cpu->exception_index = EXCP_REPLAY;
+return 1;
+}
+
+if (cpu->exit_request) {
+cpu->exception_index = EXCP_REPLAY;
+return 1;
+}
+
+int timer = replay_has_async_request();
+replay_instruction(timer);
+return timer;
+}
diff --git a/target-arm/translate.c b/target-arm/translate.c
index cf4e767..dd40998 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -31,6 +31,7 @@
 #include "qemu/log.h"
 #include "qemu/bitops.h"
 #include "arm_ldst.h"
+#include "replay/replay.h"
 
 #include "exec/helper-proto.h"
 #include "exec/helper-gen.h"
@@ -10858,6 +10859,32 @@ undef:
 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized());
 }
 
+static void gen_instructions_count(void)
+{
+TCGv_i32 cpu_tmp_i32 = tcg_temp_new();
+tcg_gen_ld_i32(cpu_tmp_i32, cpu_env, 
+   offsetof(CPUState, instructions_count) - ENV_OFFSET);
+tcg_gen_addi_i32(cpu_tmp_i32, cpu_tmp_i32, 1);
+tcg_gen_st_i32(cpu_tmp_i32, cpu_env, 
+   offsetof(CPUState, instructions_count) - ENV_OFFSET);
+tcg_temp_free(cpu_tmp_i32);
+}
+
+static void gen_instr_replay(DisasContext *s, target_ulong pc_ptr)
+{
+int l1 = gen_new_label();
+TCGv_i32 cpu_tmp2_i32 = tcg_temp_new();
+
+gen_helper_replay_instruction(cpu_tmp2_i32, cpu_env);
+tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_tmp2_i32, 0, l1);
+
+gen_set_condexec(s);
+gen_set_pc_im(s, pc_ptr);
+tcg_gen_exit_tb(0);
+gen_set_label(l1);
+tcg_temp_free(cpu_tmp2_i32);
+}
+
 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
basic block 'tb'. If search_pc is TRUE, also generate PC
information for each intermediate instruction. */
@@ -11015,13 +11042,27 @@ static inline void 
gen_intermediate_code_internal(ARMCPU *cpu,
 tcg_ctx.gen_opc_icount[lj] = num_insns;
 }
 
-if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
+if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)
+&& replay_mode == REPLAY_NONE) {
 gen_io_start();
+}
 
 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
 tcg_gen_debug_insn_start(dc->pc);
 }
 
+if (replay_mode != REPLAY_NONE) {
+/* In PLAY mode check events at every instruction, not only at
+   the beginning of the block. This is needed, when replaying
+   has changed the bounds of translation blocks.
+ */
+if (dc->pc == pc_start || replay_mode == REPLAY_PLAY) {
+gen_instr_replay(dc, dc->pc);
+} else {
+gen_instructions_count();
+}
+}
+
 if (dc->thumb) {
 disas_thumb_insn(env, dc);
 if (dc->condexec_mask) {
@@ -11054,10 +11095,11 @@ static inline void 
gen_intermediate_code_internal(ARMCPU *cpu,
 } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
  !cs->singlestep_enab

[Qemu-devel] [RFC PATCH v2 13/49] pl031: add missed field to vmstate

2014-07-17 Thread Pavel Dovgalyuk
This patch adds timer which uses virtual clock to the VMState.
Such timers are required for saving because virtual clock is the part
of the virtual machine state.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/timer/pl031.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c
index 34d9b44..f8e5abc 100644
--- a/hw/timer/pl031.c
+++ b/hw/timer/pl031.c
@@ -230,12 +230,13 @@ static int pl031_post_load(void *opaque, int version_id)
 
 static const VMStateDescription vmstate_pl031 = {
 .name = "pl031",
-.version_id = 1,
+.version_id = 2,
 .minimum_version_id = 1,
 .pre_save = pl031_pre_save,
 .post_load = pl031_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_UINT32(tick_offset_vmstate, PL031State),
+VMSTATE_TIMER_V(timer, PL031State, 2),
 VMSTATE_UINT32(mr, PL031State),
 VMSTATE_UINT32(lr, PL031State),
 VMSTATE_UINT32(cr, PL031State),




Re: [Qemu-devel] [PATCH] machine: replace underscores in machine's property names

2014-07-17 Thread Marcel Apfelbaum
On Sun, 2014-06-29 at 14:37 +0300, Michael S. Tsirkin wrote:
> On Sun, Jun 29, 2014 at 12:09:15PM +0300, Marcel Apfelbaum wrote:
> > Replaced '_' with '-' to comply with QOM guidelines.
> > Made the conversion from HMP to QMP in vl.c
> > 
> > Signed-off-by: Marcel Apfelbaum 
> 
> Nothing to do with me, pls merge through Andrea's or Paolo's tree.
> FWIW
Ping.
I thought we want this in 2.1

Thanks,
Marcel

> 
> Acked-by: Michael S. Tsirkin 
> 
> 
> > ---
> >  hw/core/machine.c |  8 
> >  vl.c  | 12 +++-
> >  2 files changed, 15 insertions(+), 5 deletions(-)
> > 
> > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > index cbba679..7a66c57 100644
> > --- a/hw/core/machine.c
> > +++ b/hw/core/machine.c
> > @@ -239,11 +239,11 @@ static void machine_initfn(Object *obj)
> >  {
> >  object_property_add_str(obj, "accel",
> >  machine_get_accel, machine_set_accel, NULL);
> > -object_property_add_bool(obj, "kernel_irqchip",
> > +object_property_add_bool(obj, "kernel-irqchip",
> >   machine_get_kernel_irqchip,
> >   machine_set_kernel_irqchip,
> >   NULL);
> > -object_property_add(obj, "kvm_shadow_mem", "int",
> > +object_property_add(obj, "kvm-shadow-mem", "int",
> >  machine_get_kvm_shadow_mem,
> >  machine_set_kvm_shadow_mem,
> >  NULL, NULL, NULL);
> > @@ -257,11 +257,11 @@ static void machine_initfn(Object *obj)
> >  machine_get_dtb, machine_set_dtb, NULL);
> >  object_property_add_str(obj, "dumpdtb",
> >  machine_get_dumpdtb, machine_set_dumpdtb, 
> > NULL);
> > -object_property_add(obj, "phandle_start", "int",
> > +object_property_add(obj, "phandle-start", "int",
> >  machine_get_phandle_start,
> >  machine_set_phandle_start,
> >  NULL, NULL, NULL);
> > -object_property_add_str(obj, "dt_compatible",
> > +object_property_add_str(obj, "dt-compatible",
> >  machine_get_dt_compatible,
> >  machine_set_dt_compatible,
> >  NULL);
> > diff --git a/vl.c b/vl.c
> > index a1686ef..7587c97 100644
> > --- a/vl.c
> > +++ b/vl.c
> > @@ -2820,15 +2820,25 @@ static int object_set_property(const char *name, 
> > const char *value, void *opaque
> >  Object *obj = OBJECT(opaque);
> >  StringInputVisitor *siv;
> >  Error *local_err = NULL;
> > +char *c, *qom_name;
> >  
> >  if (strcmp(name, "qom-type") == 0 || strcmp(name, "id") == 0 ||
> >  strcmp(name, "type") == 0) {
> >  return 0;
> >  }
> >  
> > +qom_name = g_strdup(name);
> > +c = qom_name;
> > +while (*c++) {
> > +if (*c == '_') {
> > +*c = '-';
> > +}
> > +}
> > +
> >  siv = string_input_visitor_new(value);
> > -object_property_set(obj, string_input_get_visitor(siv), name, 
> > &local_err);
> > +object_property_set(obj, string_input_get_visitor(siv), qom_name, 
> > &local_err);
> >  string_input_visitor_cleanup(siv);
> > +free(qom_name);
> >  
> >  if (local_err) {
> >  qerror_report_err(local_err);
> > -- 
> > 1.8.3.1
> 






Re: [Qemu-devel] [PATCH] machine: replace underscores in machine's property names

2014-07-17 Thread Paolo Bonzini

Il 17/07/2014 16:15, Marcel Apfelbaum ha scritto:

On Sun, 2014-06-29 at 14:37 +0300, Michael S. Tsirkin wrote:

On Sun, Jun 29, 2014 at 12:09:15PM +0300, Marcel Apfelbaum wrote:

Replaced '_' with '-' to comply with QOM guidelines.
Made the conversion from HMP to QMP in vl.c

Signed-off-by: Marcel Apfelbaum 


Nothing to do with me, pls merge through Andrea's or Paolo's tree.
FWIW

Ping.
I thought we want this in 2.1


Renaming properties is fine according to the QOM guidelines, so I think 
it can be left for 2.2.


Sorry for the delay, this patch escaped me completely.

Paolo




Re: [Qemu-devel] [PATCH for-2.1] pc: fix qemu exiting with error when -m X < 128 with old machines types

2014-07-17 Thread Bruce Rogers
 >>> On 7/11/2014 at 12:06 PM,  wrote: 
> On Tue, Jul 08, 2014 at 03:29:46PM +0200, Igor Mammedov wrote:
>> If machine doesn't support memory hotplug then staring QEMU
>> with initial memory less than default will make QEMU exit with
>> following error message:
>> 
>> $QEMU -m 16  -M isapc
>> qemu-system-i386: "-memory 'slots|maxmem'" is not supported by: isapc
>> 
>> Set maxram_size to initial memory value before parsing
>> 'maxmem' option allows to keep maxmem in sync with initial
>> memory size if no maxmem option was specified.
>> 
>> Signed-off-by: Igor Mammedov 
>> CC: Bruce Rogers 
> 
> OK this is a regression fix so we need it for 2.1.
> 
> Applied, thanks!
> 
>> ---
>>  vl.c | 1 +
>>  1 file changed, 1 insertion(+)
>> 
>> diff --git a/vl.c b/vl.c
>> index 6e084c2..6abedcf 100644
>> --- a/vl.c
>> +++ b/vl.c
>> @@ -3315,6 +3315,7 @@ int main(int argc, char **argv, char **envp)
>>  error_report("ram size too large");
>>  exit(EXIT_FAILURE);
>>  }
>> +maxram_size = ram_size;
>>  
>>  maxmem_str = qemu_opt_get(opts, "maxmem");
>>  slots_str = qemu_opt_get(opts, "slots");
>> -- 
>> 1.8.5.2 (Apple Git-48)

Hopefully this hasn't been forgotten. This is a bad regression for
pre v2.1 pc machine types.

Bruce




Re: [Qemu-devel] [PATCH for-2.1] pc: fix qemu exiting with error when -m X < 128 with old machines types

2014-07-17 Thread Bruce Rogers
 >>> On 7/8/2014 at 07:29 AM,  wrote: 
> If machine doesn't support memory hotplug then staring QEMU
> with initial memory less than default will make QEMU exit with
> following error message:
> 
> $QEMU -m 16  -M isapc
> qemu-system-i386: "-memory 'slots|maxmem'" is not supported by: isapc
> 
> Set maxram_size to initial memory value before parsing
> 'maxmem' option allows to keep maxmem in sync with initial
> memory size if no maxmem option was specified.
> 
> Signed-off-by: Igor Mammedov 
> CC: Bruce Rogers 
> ---
>  vl.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/vl.c b/vl.c
> index 6e084c2..6abedcf 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -3315,6 +3315,7 @@ int main(int argc, char **argv, char **envp)
>  error_report("ram size too large");
>  exit(EXIT_FAILURE);
>  }
> +maxram_size = ram_size;
>  
>  maxmem_str = qemu_opt_get(opts, "maxmem");
>  slots_str = qemu_opt_get(opts, "slots");


Reviewed-By: Bruce Rogers 





Re: [Qemu-devel] [PATCH] machine: replace underscores in machine's property names

2014-07-17 Thread Andreas Färber
Am 17.07.2014 16:20, schrieb Paolo Bonzini:
> Il 17/07/2014 16:15, Marcel Apfelbaum ha scritto:
>> On Sun, 2014-06-29 at 14:37 +0300, Michael S. Tsirkin wrote:
>>> On Sun, Jun 29, 2014 at 12:09:15PM +0300, Marcel Apfelbaum wrote:
 Replaced '_' with '-' to comply with QOM guidelines.
 Made the conversion from HMP to QMP in vl.c

 Signed-off-by: Marcel Apfelbaum 
>>>
>>> Nothing to do with me, pls merge through Andrea's or Paolo's tree.
>>> FWIW
>> Ping.
>> I thought we want this in 2.1
> 
> Renaming properties is fine according to the QOM guidelines, so I think
> it can be left for 2.2.
> 
> Sorry for the delay, this patch escaped me completely.

Sorry, just seeing this patch now, too.

My argument for getting this into 2.1 had been to avoid tools picking up
these to-be-renamed property names from the start. At this point, I'm
not so sure whether it's worse to break management tools or potentially
some rarely used/tested option - if we decide for 2.2, is backporting to
2.1.1 an option if we document it in the release notes?

Regards,
Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg



Re: [Qemu-devel] [RFC PATCH 7/7] cpus: reclaim allocated vCPU objects

2014-07-17 Thread Anshul Makkar
Are we not going to introduce new command cpu_del for deleting the cpu ?

I couldn't find any patch for addition of cpu_del command. Is this
intentional and we intend to use device_del (and similarly device_add)
for cpu hot(un)plug or just skipped to be added later. I have the
patch for the same which I can release, if the intent is to add this
command.

Thanks
Anshul Makkar

On Fri, Jul 11, 2014 at 11:59 AM, Gu Zheng  wrote:
> After ACPI get a signal to eject a vCPU, the vCPU must be
> removed from CPU list,before the vCPU really removed,  then
> release the all related vCPU objects.
> But we do not close KVM vcpu fd, just record it into a list, in
> order to reuse it.
>
> Signed-off-by: Chen Fan 
> Signed-off-by: Gu Zheng 
> ---
>  cpus.c   |   37 
>  include/sysemu/kvm.h |1 +
>  kvm-all.c|   57 
> +-
>  3 files changed, 94 insertions(+), 1 deletions(-)
>
> diff --git a/cpus.c b/cpus.c
> index 4dfb889..9a73407 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -786,6 +786,24 @@ void async_run_on_cpu(CPUState *cpu, void (*func)(void 
> *data), void *data)
>  qemu_cpu_kick(cpu);
>  }
>
> +static void qemu_kvm_destroy_vcpu(CPUState *cpu)
> +{
> +CPU_REMOVE(cpu);
> +
> +if (kvm_destroy_vcpu(cpu) < 0) {
> +fprintf(stderr, "kvm_destroy_vcpu failed.\n");
> +exit(1);
> +}
> +
> +object_unparent(OBJECT(cpu));
> +}
> +
> +static void qemu_tcg_destroy_vcpu(CPUState *cpu)
> +{
> +CPU_REMOVE(cpu);
> +object_unparent(OBJECT(cpu));
> +}
> +
>  static void flush_queued_work(CPUState *cpu)
>  {
>  struct qemu_work_item *wi;
> @@ -877,6 +895,11 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
>  }
>  }
>  qemu_kvm_wait_io_event(cpu);
> +if (cpu->exit && !cpu_can_run(cpu)) {
> +qemu_kvm_destroy_vcpu(cpu);
> +qemu_mutex_unlock(&qemu_global_mutex);
> +return NULL;
> +}
>  }
>
>  return NULL;
> @@ -929,6 +952,7 @@ static void tcg_exec_all(void);
>  static void *qemu_tcg_cpu_thread_fn(void *arg)
>  {
>  CPUState *cpu = arg;
> +CPUState *remove_cpu = NULL;
>
>  qemu_tcg_init_cpu_signals();
>  qemu_thread_get_self(cpu->thread);
> @@ -961,6 +985,16 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
>  }
>  }
>  qemu_tcg_wait_io_event();
> +CPU_FOREACH(cpu) {
> +if (cpu->exit && !cpu_can_run(cpu)) {
> +remove_cpu = cpu;
> +break;
> +}
> +}
> +if (remove_cpu) {
> +qemu_tcg_destroy_vcpu(remove_cpu);
> +remove_cpu = NULL;
> +}
>  }
>
>  return NULL;
> @@ -1316,6 +1350,9 @@ static void tcg_exec_all(void)
>  break;
>  }
>  } else if (cpu->stop || cpu->stopped) {
> +if (cpu->exit) {
> +next_cpu = CPU_NEXT(cpu);
> +}
>  break;
>  }
>  }
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index 174ea36..88e2403 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -178,6 +178,7 @@ int kvm_has_intx_set_mask(void);
>
>  int kvm_init_vcpu(CPUState *cpu);
>  int kvm_cpu_exec(CPUState *cpu);
> +int kvm_destroy_vcpu(CPUState *cpu);
>
>  #ifdef NEED_CPU_H
>
> diff --git a/kvm-all.c b/kvm-all.c
> index 3ae30ee..25e2a43 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -74,6 +74,12 @@ typedef struct KVMSlot
>
>  typedef struct kvm_dirty_log KVMDirtyLog;
>
> +struct KVMParkedVcpu {
> +unsigned long vcpu_id;
> +int kvm_fd;
> +QLIST_ENTRY(KVMParkedVcpu) node;
> +};
> +
>  struct KVMState
>  {
>  KVMSlot *slots;
> @@ -108,6 +114,7 @@ struct KVMState
>  QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
>  bool direct_msi;
>  #endif
> +QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
>  };
>
>  KVMState *kvm_state;
> @@ -226,6 +233,53 @@ static int kvm_set_user_memory_region(KVMState *s, 
> KVMSlot *slot)
>  return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
>  }
>
> +int kvm_destroy_vcpu(CPUState *cpu)
> +{
> +KVMState *s = kvm_state;
> +long mmap_size;
> +struct KVMParkedVcpu *vcpu = NULL;
> +int ret = 0;
> +
> +DPRINTF("kvm_destroy_vcpu\n");
> +
> +mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
> +if (mmap_size < 0) {
> +ret = mmap_size;
> +DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n");
> +goto err;
> +}
> +
> +ret = munmap(cpu->kvm_run, mmap_size);
> +if (ret < 0) {
> +goto err;
> +}
> +
> +vcpu = g_malloc0(sizeof(*vcpu));
> +vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
> +vcpu->kvm_fd = cpu->kvm_fd;
> +QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node);
> +err:
> +return ret;
> +}
> +
> +static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
> +{
> +struct KVMParkedVcpu

Re: [Qemu-devel] [PATCH] machine: replace underscores in machine's property names

2014-07-17 Thread Michael Roth
Quoting Andreas Färber (2014-07-17 10:48:59)
> Am 17.07.2014 16:20, schrieb Paolo Bonzini:
> > Il 17/07/2014 16:15, Marcel Apfelbaum ha scritto:
> >> On Sun, 2014-06-29 at 14:37 +0300, Michael S. Tsirkin wrote:
> >>> On Sun, Jun 29, 2014 at 12:09:15PM +0300, Marcel Apfelbaum wrote:
>  Replaced '_' with '-' to comply with QOM guidelines.
>  Made the conversion from HMP to QMP in vl.c
> 
>  Signed-off-by: Marcel Apfelbaum 
> >>>
> >>> Nothing to do with me, pls merge through Andrea's or Paolo's tree.
> >>> FWIW
> >> Ping.
> >> I thought we want this in 2.1
> > 
> > Renaming properties is fine according to the QOM guidelines, so I think
> > it can be left for 2.2.
> > 
> > Sorry for the delay, this patch escaped me completely.
> 
> Sorry, just seeing this patch now, too.
> 
> My argument for getting this into 2.1 had been to avoid tools picking up
> these to-be-renamed property names from the start. At this point, I'm
> not so sure whether it's worse to break management tools or potentially
> some rarely used/tested option - if we decide for 2.2, is backporting to
> 2.1.1 an option if we document it in the release notes?

IMO, if there's some risk to breaking management or other tools, I'd
rather it be left to major releases. And if these values are already misnamed
for 2.1.0 and prior, I don't think we stop it from poliferating much more by
pushing the fix up by a few months.

I do think it makes sense to pull it in for 2.1.0-rc3, but I think that's a
priority call and this seems fairly low risk.

> 
> Regards,
> Andreas
> 
> -- 
> SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
> GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg




Re: [Qemu-devel] [PATCH for-2.1] cadence_uart: check serial backend before using it.

2014-07-17 Thread Peter Maydell
On 16 July 2014 08:42,   wrote:
> From: KONRAD Frederic 
>
> Segfault occurs when there are less than two serial backends with zynq 
> platform.
>
> This checks that s->chr is not NULL before using it.
>
> Signed-off-by: KONRAD Frederic 
> Reviewed-by: Peter Crosthwaite 
> ---
>  hw/char/cadence_uart.c | 14 ++
>  1 file changed, 10 insertions(+), 4 deletions(-)

Applied to master, thanks.

-- PMM



Re: [Qemu-devel] [PATCH] machine: replace underscores in machine's property names

2014-07-17 Thread Peter Maydell
On 29 June 2014 10:09, Marcel Apfelbaum  wrote:
> Replaced '_' with '-' to comply with QOM guidelines.
> Made the conversion from HMP to QMP in vl.c
>
> Signed-off-by: Marcel Apfelbaum 

> index a1686ef..7587c97 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -2820,15 +2820,25 @@ static int object_set_property(const char *name, 
> const char *value, void *opaque
>  Object *obj = OBJECT(opaque);
>  StringInputVisitor *siv;
>  Error *local_err = NULL;
> +char *c, *qom_name;
>
>  if (strcmp(name, "qom-type") == 0 || strcmp(name, "id") == 0 ||
>  strcmp(name, "type") == 0) {
>  return 0;
>  }
>
> +qom_name = g_strdup(name);

Memory allocated with g_strdup...

> +c = qom_name;
> +while (*c++) {
> +if (*c == '_') {
> +*c = '-';
> +}
> +}
> +
>  siv = string_input_visitor_new(value);
> -object_property_set(obj, string_input_get_visitor(siv), name, 
> &local_err);
> +object_property_set(obj, string_input_get_visitor(siv), qom_name, 
> &local_err);
>  string_input_visitor_cleanup(siv);
> +free(qom_name);

...but freed with free rather than g_free.

>
>  if (local_err) {
>  qerror_report_err(local_err);
> --
> 1.8.3.1

thanks
-- PMM



Re: [Qemu-devel] [PATCH] machine: replace underscores in machine's property names

2014-07-17 Thread Paolo Bonzini

Il 17/07/2014 18:47, Michael Roth ha scritto:

> My argument for getting this into 2.1 had been to avoid tools picking up
> these to-be-renamed property names from the start. At this point, I'm
> not so sure whether it's worse to break management tools or potentially
> some rarely used/tested option - if we decide for 2.2, is backporting to
> 2.1.1 an option if we document it in the release notes?

IMO, if there's some risk to breaking management or other tools, I'd
rather it be left to major releases. And if these values are already misnamed
for 2.1.0 and prior, I don't think we stop it from poliferating much more by
pushing the fix up by a few months.


I'm not sure in which case management could break (except for qom-get). 
 Andreas, can you explain?


Paolo



Re: [Qemu-devel] [PATCH] machine: replace underscores in machine's property names

2014-07-17 Thread Marcel Apfelbaum
On Thu, 2014-07-17 at 17:55 +0100, Peter Maydell wrote:
> On 29 June 2014 10:09, Marcel Apfelbaum  wrote:
> > Replaced '_' with '-' to comply with QOM guidelines.
> > Made the conversion from HMP to QMP in vl.c
> >
> > Signed-off-by: Marcel Apfelbaum 
> 
> > index a1686ef..7587c97 100644
> > --- a/vl.c
> > +++ b/vl.c
> > @@ -2820,15 +2820,25 @@ static int object_set_property(const char *name, 
> > const char *value, void *opaque
> >  Object *obj = OBJECT(opaque);
> >  StringInputVisitor *siv;
> >  Error *local_err = NULL;
> > +char *c, *qom_name;
> >
> >  if (strcmp(name, "qom-type") == 0 || strcmp(name, "id") == 0 ||
> >  strcmp(name, "type") == 0) {
> >  return 0;
> >  }
> >
> > +qom_name = g_strdup(name);
> 
> Memory allocated with g_strdup...
> 
> > +c = qom_name;
> > +while (*c++) {
> > +if (*c == '_') {
> > +*c = '-';
> > +}
> > +}
> > +
> >  siv = string_input_visitor_new(value);
> > -object_property_set(obj, string_input_get_visitor(siv), name, 
> > &local_err);
> > +object_property_set(obj, string_input_get_visitor(siv), qom_name, 
> > &local_err);
> >  string_input_visitor_cleanup(siv);
> > +free(qom_name);
> 
> ...but freed with free rather than g_free.
Thanks, I'll take care of that.
Marcel

> 
> >
> >  if (local_err) {
> >  qerror_report_err(local_err);
> > --
> > 1.8.3.1
> 
> thanks
> -- PMM






[Qemu-devel] Debugging live migrate failures between 1.0 and 2.0

2014-07-17 Thread Alex Bligh
I am trying to get to the bottom of a live migrate failure between qemu 1.0 
(sender) and qemu 2.0 (receiver). I think this should 'just work', correct?

What I'm seeing is the live migrate starts correctly through QMP, but the first 
query_migrate call returns a failure. On the receive side it says the peer 
aborted the send. What's the best way to debug this further?

-- 
Alex Bligh







[Qemu-devel] [PATCH for-2.1] po: Fix Makefile rules

2014-07-17 Thread Stefan Weil
Adding 'update' to the phony targets fixes this error:

$ LANG=C make -C po update
make: Entering directory `/qemu/po'
  LINK  update
/qemu/po/de_DE.po: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
make: *** [update] Error 1
make: Leaving directory `/qemu/po'

Some other phony targets (build, install) were also added, and the
existing .PHONY statement was moved to a more prominent position at
the beginning of the Makefile.

The patch also fixes a 2nd bug. The default target should be 'all',
but instead 'modules' (from rules.mak) was the default. Fix this by
adding 'all' as a target before any include statement.

Signed-off-by: Stefan Weil 
---

Hi Peter,

I suggest to apply this (trivial) fix directly for 2.1
(without pull request).

I noticed that problem when I wanted to prepare an e-mail for rc3:
could you please run "make -C po update" (and commit the updated .po files)
before releasing rc3? Or would it be better if I sent a patch which
updates the .po files for the next QEMU release?

Regards
Stefan

 po/Makefile |7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/po/Makefile b/po/Makefile
index d2c2a8e..9add20f 100644
--- a/po/Makefile
+++ b/po/Makefile
@@ -4,6 +4,11 @@
 # Set SRC_PATH for in-tree builds without configuration.
 SRC_PATH=$(shell cd .. && pwd)
 
+# The default target must come before any include statements.
+all:
+
+.PHONY:all build clean install update
+
 -include ../config-host.mak
 include $(SRC_PATH)/rules.mak
 
@@ -45,5 +50,3 @@ $(PO_PATH)/messages.po: $(SRC_PATH)/ui/gtk.c
 
 $(PO_PATH)/%.po: $(PO_PATH)/messages.po
$(call quiet-command, msgmerge -q $@ $< > $@.bak && mv $@.bak $@, "  
GEN   $@")
-
-.PHONY: clean all
-- 
1.7.10.4




  1   2   >