Re: [Qemu-devel] [PATCH] hw/isa/isa-bus: Set category of the "isabus-bridge" device

2017-01-23 Thread Thomas Huth
On 24.01.2017 08:42, Michael Tokarev wrote:
> 20.01.2017 18:53, Thomas Huth wrote:
>> It has "bridge" in its name, so it should be in the category
>> DEVICE_CATEGORY_BRIDGE.
>>
>> Signed-off-by: Thomas Huth 
>> ---
>>  hw/isa/isa-bus.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
>> index 9d07b11..0ffbc8d 100644
>> --- a/hw/isa/isa-bus.c
>> +++ b/hw/isa/isa-bus.c
>> @@ -219,6 +219,7 @@ static void isabus_bridge_class_init(ObjectClass *klass, 
>> void *data)
>>  {
>>  DeviceClass *dc = DEVICE_CLASS(klass);
>>  
>> +set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
>>  dc->fw_name = "isa";
>>  }
> 
> Does it have any effect on the guest?
> ISA is an old thing...

No, as far as I know, this is just used in qdev_print_devinfos() to
print out the devices in nice categories when you start QEMU with
"-device ?". Devices that do not have a category bit set show up in the
"Uncategorized" section - which tends to get overcrowded if the devices
are not sorted into proper categories.

 Thomas




Re: [Qemu-devel] [PATCH RFC v4 10/20] memory: add section range info for IOMMU notifier

2017-01-23 Thread Peter Xu
On Mon, Jan 23, 2017 at 12:12:44PM -0700, Alex Williamson wrote:
> On Fri, 20 Jan 2017 21:08:46 +0800
> Peter Xu  wrote:
> 
> > In this patch, IOMMUNotifier.{start|end} are introduced to store section
> > information for a specific notifier. When notification occurs, we not
> > only check the notification type (MAP|UNMAP), but also check whether the
> > notified iova is in the range of specific IOMMU notifier, and skip those
> > notifiers if not in the listened range.
> > 
> > When removing an region, we need to make sure we removed the correct
> > VFIOGuestIOMMU by checking the IOMMUNotifier.start address as well.
> > 
> > Suggested-by: David Gibson 
> > Signed-off-by: Peter Xu 
> > ---
> > changelog (start from vt-d vfio enablement series v3):
> > v4:
> > - introduce memory_region_iommu_notifier_init() [Jason]
> > ---
> >  hw/vfio/common.c  | 12 +---
> >  hw/virtio/vhost.c |  4 ++--
> >  include/exec/memory.h | 19 ++-
> >  memory.c  |  5 -
> >  4 files changed, 33 insertions(+), 7 deletions(-)
> 
> 
> Acked-by: Alex Williamson 

Thanks for the ack!

Sorry that I want to tune this patch a bit - I'll loosen the limit on
the range check. The original patch will notify if iova is inside
range (start, end), while I am tuning it to allow the notification
happen as long as (iova, size) and (start, end) has any overlapping.
The diff against this one would be (for your better reference):

--8<---

diff --git a/memory.c b/memory.c
index 89104b1..80ab3c1 100644
--- a/memory.c
+++ b/memory.c
@@ -1672,9 +1672,15 @@ void memory_region_notify_iommu(MemoryRegion *mr,
 }

 QLIST_FOREACH(iommu_notifier, >iommu_notify, node) {
-if (iommu_notifier->notifier_flags & request_flags &&
-iommu_notifier->start <= entry.iova &&
-iommu_notifier->end >= entry.iova) {
+/*
+ * Skip the notification if the notification does not overlap
+ * with registered range.
+ */
+if (iommu_notifier->start > entry.iova + entry.addr_mask + 1 ||
+iommu_notifier->end < entry.iova) {
+continue;
+}
+if (iommu_notifier->notifier_flags & request_flags) {
 iommu_notifier->notify(iommu_notifier, );
 }
 }

-->8---

I'll post with the complete patch along with the series's next post.

Thanks,

-- peterx



Re: [Qemu-devel] [PATCH] 9pfs: fix offset error in v9fs_xattr_read()

2017-01-23 Thread Greg Kurz
On Mon, 23 Jan 2017 12:20:57 -0800 (PST)
Stefano Stabellini  wrote:

> On Sat, 21 Jan 2017, Greg Kurz wrote:
> > The current code tries to copy `read_count' bytes starting at offset
> > `offset' from a `read_count`-sized iovec. This causes v9fs_pack() to
> > fail with ENOBUFS.
> > 
> > Since the PDU iovec is already partially filled with `offset' bytes,
> > let's skip them when creating `qiov_full' and have v9fs_pack() to
> > copy the whole of it. Moreover, this is consistent with the other
> > places where v9fs_init_qiov_from_pdu() is called.
> > 
> > This fixes commit "bcb8998fac16 9pfs: call v9fs_init_qiov_from_pdu
> > before v9fs_pack".  
> 
> Sorry about that!
> 
> 
> > Signed-off-by: Greg Kurz 
> > ---
> >  hw/9pfs/9p.c |4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
> > index fa58877570f6..f0eef1a3ef53 100644
> > --- a/hw/9pfs/9p.c
> > +++ b/hw/9pfs/9p.c
> > @@ -1685,8 +1685,8 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU 
> > *pdu, V9fsFidState *fidp,
> >  }
> >  offset += err;
> >  
> > -v9fs_init_qiov_from_pdu(_full, pdu, 0, read_count, false);
> > -err = v9fs_pack(qiov_full.iov, qiov_full.niov, offset,
> > +v9fs_init_qiov_from_pdu(_full, pdu, offset, read_count, false);  
> 
> v9fs_init_qiov_from_pdu calls init_in_iov_from_pdu passing read_count as
> size argument. offset is not passed to init_in_iov_from_pdu, it is only
> used to initialized qiov_full.
> 
> In other words, don't we need to:
> 
> v9fs_init_qiov_from_pdu(_full, pdu, offset, read_count + offset, 
> false);
> 
> To make sure that qiov_full has "read_count + offset" bytes in it, and
> qiov_full is initialized skipping the first "offset" bytes?
> 

If we do that then qemu_iovec_concat() will skip offset bytes and then copy
read_count + offset bytes or am I missing something ?

> 
> > +err = v9fs_pack(qiov_full.iov, qiov_full.niov, 0,
> >  ((char *)fidp->fs.xattr.value) + off,
> >  read_count);
> >  qemu_iovec_destroy(_full);
> >   




Re: [Qemu-devel] [PATCH v7 00/14] replay additions

2017-01-23 Thread no-reply
Hi,

Your series seems to have some coding style problems. See output below for
more information:

Type: series
Subject: [Qemu-devel] [PATCH v7 00/14] replay additions
Message-id: 20170124071654.4572.41407.stgit@PASHA-ISP

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  
patchew/1485207141-1941-1-git-send-email-quint...@redhat.com -> 
patchew/1485207141-1941-1-git-send-email-quint...@redhat.com
 - [tag update]  patchew/20160908145158.30720-1-paul.bur...@imgtec.com -> 
patchew/20160908145158.30720-1-paul.bur...@imgtec.com
 * [new tag] patchew/20170124071654.4572.41407.stgit@PASHA-ISP -> 
patchew/20170124071654.4572.41407.stgit@PASHA-ISP
Switched to a new branch 'test'
0191b3c replay: add record/replay for audio passthrough
ca532c5 audio: make audio poll timer deterministic
8690408 replay: disable default snapshot for record/replay
2d11131 blkreplay: create temporary overlay for underlaying devices
7d471b1 block: implement bdrv_snapshot_goto for blkreplay
eab8ef5 replay: save/load initial state
870fbf1 savevm: add public save_vmstate function
aff7d02 integratorcp: adding vmstate for save/restore
f604803 replay: don't use rtc clock on loadvm phase
b01b9f2 apic: save apic_delivered flag
06b4384 icount: exit cpu loop on expire
8995a01 replay: exception replay fix
1de2b63 replay: improve interrupt handling
84b9049 icount: update instruction counter on apic patching

=== OUTPUT BEGIN ===
Checking PATCH 1/14: icount: update instruction counter on apic patching...
Checking PATCH 2/14: replay: improve interrupt handling...
Checking PATCH 3/14: replay: exception replay fix...
Checking PATCH 4/14: icount: exit cpu loop on expire...
Checking PATCH 5/14: apic: save apic_delivered flag...
Checking PATCH 6/14: replay: don't use rtc clock on loadvm phase...
Checking PATCH 7/14: integratorcp: adding vmstate for save/restore...
Checking PATCH 8/14: savevm: add public save_vmstate function...
Checking PATCH 9/14: replay: save/load initial state...
Checking PATCH 10/14: block: implement bdrv_snapshot_goto for blkreplay...
Checking PATCH 11/14: blkreplay: create temporary overlay for underlaying 
devices...
Checking PATCH 12/14: replay: disable default snapshot for record/replay...
Checking PATCH 13/14: audio: make audio poll timer deterministic...
ERROR: space prohibited between function name and open parenthesis '('
#23: FILE: audio/audio.c:1116:
+timer_mod (s->ts,

total: 1 errors, 0 warnings, 12 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 14/14: replay: add record/replay for audio passthrough...
ERROR: space prohibited between function name and open parenthesis '('
#41: FILE: audio/audio.c:1460:
+captured = hw->pcm_ops->run_in (hw);

total: 1 errors, 0 warnings, 190 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


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

Re: [Qemu-devel] [PATCH] hw/isa/isa-bus: Set category of the "isabus-bridge" device

2017-01-23 Thread Michael Tokarev
20.01.2017 18:53, Thomas Huth wrote:
> It has "bridge" in its name, so it should be in the category
> DEVICE_CATEGORY_BRIDGE.
> 
> Signed-off-by: Thomas Huth 
> ---
>  hw/isa/isa-bus.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
> index 9d07b11..0ffbc8d 100644
> --- a/hw/isa/isa-bus.c
> +++ b/hw/isa/isa-bus.c
> @@ -219,6 +219,7 @@ static void isabus_bridge_class_init(ObjectClass *klass, 
> void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  
> +set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
>  dc->fw_name = "isa";
>  }

Does it have any effect on the guest?
ISA is an old thing...

Thanks,

/mjt



Re: [Qemu-devel] [PATCH RFC v4 00/20] VT-d: vfio enablement and misc enhances

2017-01-23 Thread Peter Xu
On Mon, Jan 23, 2017 at 05:55:51PM +0200, Michael S. Tsirkin wrote:
> On Fri, Jan 20, 2017 at 09:08:36PM +0800, Peter Xu wrote:
> > This is v4 of vt-d vfio enablement series.
> > 
> > Sorry that v4 growed to 20 patches. Some newly added patches (which
> > are quite necessary):
> > 
> > [01/20] vfio: trace map/unmap for notify as well
> > [02/20] vfio: introduce vfio_get_vaddr()
> > [03/20] vfio: allow to notify unmap for very large region
> > 
> >   Patches from RFC series:
> > 
> >   "[PATCH RFC 0/3] vfio: allow to notify unmap for very big region"
> > 
> >   Which is required by patch [19/20].
> > 
> > [11/20] memory: provide IOMMU_NOTIFIER_FOREACH macro
> > 
> >   A helper only.
> > 
> > [19/20] intel_iommu: unmap existing pages before replay
> > 
> >   This solves Alex's concern that there might have existing mappings
> >   in previous domain when replay happens.
> > 
> > [20/20] intel_iommu: replay even with DSI/GLOBAL inv desc
> > 
> >   This solves Jason/Kevin's concern by handling DSI/GLOBAL
> >   invalidations as well.
> > 
> > Each individual patch will have more detailed explanation on itself.
> > Please refer to each of them.
> > 
> > Here I did separate work on patch 19/20 rather than squashing them
> > into patch 18 for easier modification and review. I prefer we have
> > them separately so we can see each problem separately, after all,
> > patch 18 survives in most use cases. Please let me know if we want to
> > squash them in some way. I can respin when necessary.
> > 
> > Besides the big things, lots of tiny tweaks as well. Here's the
> > changelog.
> 
> It would be nice to add to the log
> - known issues / missing features, if any

Sure. Will add them in next post.

> - are there patches ready to be merged here?
>   if yes pls post them without the rfc tag

The series (since V1) should have passed compilation test and simple
functional test (though only with my tiny C program to torture it).
Since I have got lots of review comments, and looks like the whole
thing is acceptable in general, I'll repost with a non-rfc version
with some tweaks upon this one.

Michael, please feel free to pick any of them which you think are
applicable and safe (e.g., the iommu cleanups).

Thanks,

-- peterx



[Qemu-devel] [PATCH v7 14/14] replay: add record/replay for audio passthrough

2017-01-23 Thread Pavel Dovgalyuk
This patch adds recording and replaying audio data. Is saves synchronization
information for audio out and inputs from the microphone.

Signed-off-by: Pavel Dovgalyuk 
---
 audio/audio.c|9 -
 audio/audio.h|5 +++
 audio/mixeng.c   |   31 ++
 docs/replay.txt  |7 
 include/sysemu/replay.h  |7 
 replay/Makefile.objs |1 +
 replay/replay-audio.c|   79 ++
 replay/replay-internal.h |4 ++
 8 files changed, 141 insertions(+), 2 deletions(-)
 create mode 100644 replay/replay-audio.c

diff --git a/audio/audio.c b/audio/audio.c
index 1ee95a5..415ee1b 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -28,6 +28,7 @@
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
 #include "qemu/cutils.h"
+#include "sysemu/replay.h"
 
 #define AUDIO_CAP "audio"
 #include "audio_int.h"
@@ -1389,6 +1390,7 @@ static void audio_run_out (AudioState *s)
 
 prev_rpos = hw->rpos;
 played = hw->pcm_ops->run_out (hw, live);
+replay_audio_out();
 if (audio_bug (AUDIO_FUNC, hw->rpos >= hw->samples)) {
 dolog ("hw->rpos=%d hw->samples=%d played=%d\n",
hw->rpos, hw->samples, played);
@@ -1452,9 +1454,12 @@ static void audio_run_in (AudioState *s)
 
 while ((hw = audio_pcm_hw_find_any_enabled_in (hw))) {
 SWVoiceIn *sw;
-int captured, min;
+int captured = 0, min;
 
-captured = hw->pcm_ops->run_in (hw);
+if (replay_mode != REPLAY_MODE_PLAY) {
+captured = hw->pcm_ops->run_in (hw);
+}
+replay_audio_in(, hw->conv_buf, >wpos, hw->samples);
 
 min = audio_pcm_hw_find_min_in (hw);
 hw->total_samples_captured += captured - min;
diff --git a/audio/audio.h b/audio/audio.h
index c3c5198..f4339a1 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -166,4 +166,9 @@ int wav_start_capture (CaptureState *s, const char *path, 
int freq,
 bool audio_is_cleaning_up(void);
 void audio_cleanup(void);
 
+void audio_sample_to_uint64(void *samples, int pos,
+uint64_t *left, uint64_t *right);
+void audio_sample_from_uint64(void *samples, int pos,
+uint64_t left, uint64_t right);
+
 #endif /* QEMU_AUDIO_H */
diff --git a/audio/mixeng.c b/audio/mixeng.c
index 66c0328..c23508e 100644
--- a/audio/mixeng.c
+++ b/audio/mixeng.c
@@ -267,6 +267,37 @@ f_sample *mixeng_clip[2][2][2][3] = {
 }
 };
 
+
+void audio_sample_to_uint64(void *samples, int pos,
+uint64_t *left, uint64_t *right)
+{
+struct st_sample *sample = samples;
+sample += pos;
+#ifdef FLOAT_MIXENG
+error_report(
+"Coreaudio and floating point samples are not supported by replay 
yet");
+abort();
+#else
+*left = sample->l;
+*right = sample->r;
+#endif
+}
+
+void audio_sample_from_uint64(void *samples, int pos,
+uint64_t left, uint64_t right)
+{
+struct st_sample *sample = samples;
+sample += pos;
+#ifdef FLOAT_MIXENG
+error_report(
+"Coreaudio and floating point samples are not supported by replay 
yet");
+abort();
+#else
+sample->l = left;
+sample->r = right;
+#endif
+}
+
 /*
  * August 21, 1998
  * Copyright 1998 Fabrice Bellard.
diff --git a/docs/replay.txt b/docs/replay.txt
index 03e1931..486c1e0 100644
--- a/docs/replay.txt
+++ b/docs/replay.txt
@@ -225,3 +225,10 @@ recording the virtual machine this filter puts all packets 
coming from
 the outer world into the log. In replay mode packets from the log are
 injected into the network device. All interactions with network backend
 in replay mode are disabled.
+
+Audio devices
+-
+
+Audio data is recorded and replay automatically. The command line for recording
+and replaying must contain identical specifications of audio hardware, e.g.:
+ -soundhw ac97
diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index 740b425..073ec59 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -152,6 +152,13 @@ void replay_unregister_net(ReplayNetState *rns);
 void replay_net_packet_event(ReplayNetState *rns, unsigned flags,
  const struct iovec *iov, int iovcnt);
 
+/* Audio */
+
+/*! Saves/restores number of played samples of audio out operation. */
+void replay_audio_out(int *played);
+/*! Saves/restores recorded samples of audio in operation. */
+void replay_audio_in(int *recorded, void *samples, int *wpos, int size);
+
 /* VM state operations */
 
 /*! Called at the start of execution.
diff --git a/replay/Makefile.objs b/replay/Makefile.objs
index b2afd40..cee6539 100644
--- a/replay/Makefile.objs
+++ b/replay/Makefile.objs
@@ -6,3 +6,4 @@ common-obj-y += replay-input.o
 common-obj-y += replay-char.o
 common-obj-y += replay-snapshot.o
 common-obj-y += replay-net.o
+common-obj-y += replay-audio.o
\ No newline at end of 

[Qemu-devel] [PATCH v7 11/14] blkreplay: create temporary overlay for underlaying devices

2017-01-23 Thread Pavel Dovgalyuk
This patch allows using '-snapshot' behavior in record/replay mode.
blkreplay layer creates temporary overlays on top of underlaying
disk images. It is needed, because creating an overlay over blkreplay
breaks the determinism.

Signed-off-by: Pavel Dovgalyuk 
---
 block/blkreplay.c |   76 +
 stubs/replay.c|1 +
 vl.c  |2 +
 3 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/block/blkreplay.c b/block/blkreplay.c
index 8a03d62..172642f 100644
--- a/block/blkreplay.c
+++ b/block/blkreplay.c
@@ -14,12 +14,76 @@
 #include "block/block_int.h"
 #include "sysemu/replay.h"
 #include "qapi/error.h"
+#include "qapi/qmp/qstring.h"
 
 typedef struct Request {
 Coroutine *co;
 QEMUBH *bh;
 } Request;
 
+static BlockDriverState *blkreplay_append_snapshot(BlockDriverState *bs,
+   Error **errp)
+{
+int ret;
+BlockDriverState *bs_snapshot;
+int64_t total_size;
+QemuOpts *opts = NULL;
+char tmp_filename[PATH_MAX + 1];
+QDict *snapshot_options = qdict_new();
+
+/* Prepare options QDict for the overlay file */
+qdict_put(snapshot_options, "file.driver",
+  qstring_from_str("file"));
+qdict_put(snapshot_options, "driver",
+  qstring_from_str("qcow2"));
+
+/* Create temporary file */
+ret = get_tmp_filename(tmp_filename, PATH_MAX + 1);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "Could not get temporary filename");
+goto out;
+}
+qdict_put(snapshot_options, "file.filename",
+  qstring_from_str(tmp_filename));
+
+/* Get the required size from the image */
+total_size = bdrv_getlength(bs);
+if (total_size < 0) {
+error_setg_errno(errp, -total_size, "Could not get image size");
+goto out;
+}
+
+opts = qemu_opts_create(bdrv_qcow2.create_opts, NULL, 0, _abort);
+qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size, _abort);
+ret = bdrv_create(_qcow2, tmp_filename, opts, errp);
+qemu_opts_del(opts);
+if (ret < 0) {
+error_prepend(errp, "Could not create temporary overlay '%s': ",
+  tmp_filename);
+goto out;
+}
+
+bs_snapshot = bdrv_open(NULL, NULL, snapshot_options,
+BDRV_O_RDWR | BDRV_O_TEMPORARY, errp);
+snapshot_options = NULL;
+if (!bs_snapshot) {
+ret = -EINVAL;
+goto out;
+}
+
+/* bdrv_append() consumes a strong reference to bs_snapshot (i.e. it will
+ * call bdrv_unref() on it), so in order to be able to return one, we have
+ * to increase bs_snapshot's refcount here */
+bdrv_ref(bs_snapshot);
+bdrv_append(bs_snapshot, bs);
+
+return bs_snapshot;
+
+out:
+QDECREF(snapshot_options);
+return NULL;
+}
+
 static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags,
   Error **errp)
 {
@@ -35,6 +99,14 @@ static int blkreplay_open(BlockDriverState *bs, QDict 
*options, int flags,
 goto fail;
 }
 
+/* Add temporary snapshot to preserve the image */
+if (!replay_snapshot
+&& !blkreplay_append_snapshot(bs->file->bs, _err)) {
+ret = -EINVAL;
+error_propagate(errp, local_err);
+goto fail;
+}
+
 ret = 0;
 fail:
 if (ret < 0) {
@@ -45,6 +117,10 @@ fail:
 
 static void blkreplay_close(BlockDriverState *bs)
 {
+if (!replay_snapshot) {
+/* Unref created snapshot file */
+bdrv_unref(bs->file->bs);
+}
 }
 
 static int64_t blkreplay_getlength(BlockDriverState *bs)
diff --git a/stubs/replay.c b/stubs/replay.c
index d9a6da9..e43e467 100644
--- a/stubs/replay.c
+++ b/stubs/replay.c
@@ -3,6 +3,7 @@
 #include "sysemu/sysemu.h"
 
 ReplayMode replay_mode;
+char *replay_snapshot;
 
 int64_t replay_save_clock(unsigned int kind, int64_t clock)
 {
diff --git a/vl.c b/vl.c
index 52a6ac8..def0520 100644
--- a/vl.c
+++ b/vl.c
@@ -4474,7 +4474,7 @@ int main(int argc, char **argv, char **envp)
 }
 
 /* open the virtual block devices */
-if (snapshot || replay_mode != REPLAY_MODE_NONE) {
+if (snapshot) {
 qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot,
   NULL, NULL);
 }




[Qemu-devel] [PATCH v7 08/14] savevm: add public save_vmstate function

2017-01-23 Thread Pavel Dovgalyuk
This patch introduces save_vmstate function to allow saving and loading
vmstates from the replay module.

Signed-off-by: Pavel Dovgalyuk 
---
 include/sysemu/sysemu.h |1 +
 migration/savevm.c  |   33 ++---
 2 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index cccde56..4cdba34 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -75,6 +75,7 @@ void qemu_add_machine_init_done_notifier(Notifier *notify);
 void qemu_remove_machine_init_done_notifier(Notifier *notify);
 
 void hmp_savevm(Monitor *mon, const QDict *qdict);
+int save_vmstate(Monitor *mon, const char *name);
 int load_vmstate(const char *name);
 void hmp_delvm(Monitor *mon, const QDict *qdict);
 void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
diff --git a/migration/savevm.c b/migration/savevm.c
index f9c06e9..1e69225 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2039,38 +2039,40 @@ int qemu_loadvm_state(QEMUFile *f)
 return ret;
 }
 
-void hmp_savevm(Monitor *mon, const QDict *qdict)
+int save_vmstate(Monitor *mon, const char *name)
 {
 BlockDriverState *bs, *bs1;
 QEMUSnapshotInfo sn1, *sn = , old_sn1, *old_sn = _sn1;
-int ret;
+int ret = -1;
 QEMUFile *f;
 int saved_vm_running;
 uint64_t vm_state_size;
 qemu_timeval tv;
 struct tm tm;
-const char *name = qdict_get_try_str(qdict, "name");
 Error *local_err = NULL;
 AioContext *aio_context;
 
 if (!bdrv_all_can_snapshot()) {
 monitor_printf(mon, "Device '%s' is writable but does not "
"support snapshots.\n", bdrv_get_device_name(bs));
-return;
+return ret;
 }
 
 /* Delete old snapshots of the same name */
-if (name && bdrv_all_delete_snapshot(name, , _err) < 0) {
-error_reportf_err(local_err,
-  "Error while deleting snapshot on device '%s': ",
-  bdrv_get_device_name(bs1));
-return;
+if (name) {
+ret = bdrv_all_delete_snapshot(name, , _err);
+if (ret < 0) {
+error_reportf_err(local_err,
+  "Error while deleting snapshot on device '%s': ",
+  bdrv_get_device_name(bs1));
+return ret;
+}
 }
 
 bs = bdrv_all_find_vmstate_bs();
 if (bs == NULL) {
 monitor_printf(mon, "No block device can accept snapshots\n");
-return;
+return ret;
 }
 aio_context = bdrv_get_aio_context(bs);
 
@@ -2079,7 +2081,7 @@ void hmp_savevm(Monitor *mon, const QDict *qdict)
 ret = global_state_store();
 if (ret) {
 monitor_printf(mon, "Error saving global state\n");
-return;
+return ret;
 }
 vm_stop(RUN_STATE_SAVE_VM);
 
@@ -2125,13 +2127,22 @@ void hmp_savevm(Monitor *mon, const QDict *qdict)
 if (ret < 0) {
 monitor_printf(mon, "Error while creating snapshot on '%s'\n",
bdrv_get_device_name(bs));
+goto the_end;
 }
 
+ret = 0;
+
  the_end:
 aio_context_release(aio_context);
 if (saved_vm_running) {
 vm_start();
 }
+return ret;
+}
+
+void hmp_savevm(Monitor *mon, const QDict *qdict)
+{
+save_vmstate(mon, qdict_get_try_str(qdict, "name"));
 }
 
 void qmp_xen_save_devices_state(const char *filename, Error **errp)




[Qemu-devel] [PATCH v7 07/14] integratorcp: adding vmstate for save/restore

2017-01-23 Thread Pavel Dovgalyuk
From: Pavel Dovgalyuk 

VMState added by this patch preserves correct
loading of the integratorcp device state.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/arm/integratorcp.c |   62 +
 1 file changed, 62 insertions(+)

diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index 039812a..ca06e1b 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -53,6 +53,27 @@ static uint8_t integrator_spd[128] = {
0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
 };
 
+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 uint64_t integratorcm_read(void *opaque, hwaddr offset,
   unsigned size)
 {
@@ -309,6 +330,19 @@ typedef struct icp_pic_state {
 qemu_irq parent_fiq;
 } icp_pic_state;
 
+static const VMStateDescription vmstate_icp_pic = {
+.name = "icp_pic",
+.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;
@@ -438,6 +472,17 @@ typedef struct ICPCtrlRegsState {
 #define ICP_INTREG_WPROT(1 << 0)
 #define ICP_INTREG_CARDIN   (1 << 3)
 
+static const VMStateDescription vmstate_icp_control = {
+.name = "icp_control",
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields  = (VMStateField[]) {
+VMSTATE_UINT32(intreg_state, ICPCtrlRegsState),
+VMSTATE_END_OF_LIST()
+}
+};
+
 static uint64_t icp_control_read(void *opaque, hwaddr offset,
  unsigned size)
 {
@@ -640,6 +685,21 @@ static void core_class_init(ObjectClass *klass, void *data)
 
 dc->props = core_properties;
 dc->realize = integratorcm_realize;
+dc->vmsd = _integratorcm;
+}
+
+static void icp_pic_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->vmsd = _icp_pic;
+}
+
+static void icp_control_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->vmsd = _icp_control;
 }
 
 static const TypeInfo core_info = {
@@ -655,6 +715,7 @@ static const TypeInfo icp_pic_info = {
 .parent= TYPE_SYS_BUS_DEVICE,
 .instance_size = sizeof(icp_pic_state),
 .instance_init = icp_pic_init,
+.class_init= icp_pic_class_init,
 };
 
 static const TypeInfo icp_ctrl_regs_info = {
@@ -662,6 +723,7 @@ static const TypeInfo icp_ctrl_regs_info = {
 .parent= TYPE_SYS_BUS_DEVICE,
 .instance_size = sizeof(ICPCtrlRegsState),
 .instance_init = icp_control_init,
+.class_init= icp_control_class_init,
 };
 
 static void integratorcp_register_types(void)




Re: [Qemu-devel] [PATCH RFC v4 19/20] intel_iommu: unmap existing pages before replay

2017-01-23 Thread Peter Xu
On Mon, Jan 23, 2017 at 06:40:12PM +0800, Jason Wang wrote:
> 
> 
> On 2017年01月20日 21:08, Peter Xu wrote:
> >  static int vtd_replay_hook(IOMMUTLBEntry *entry, void *private)
> >  {
> >  memory_region_notify_one((IOMMUNotifier *)private, entry);
> >@@ -2711,13 +2768,16 @@ static void vtd_iommu_replay(MemoryRegion *mr, 
> >IOMMUNotifier *n)
> >  if (vtd_dev_to_context_entry(s, bus_n, vtd_as->devfn, ) == 0) {
> >  /*
> >- * Scanned a valid context entry, walk over the pages and
> >- * notify when needed.
> >+ * Scanned a valid context entry, we first make sure to remove
> >+ * all existing mappings in old domain, by sending UNMAP to
> >+ * all the notifiers. Then, we walk over the pages and notify
> >+ * with existing mapped new entries in the new domain.
> >   */
> 
> A question is what if the context cache was invalidated but the device were
> not moved to a new domain. Then the code here does not do anything I
> believe?

Yes, it'll unmap all the stuffs and remap them all. I think that's my
intention, and can we really avoid this?

> I think we should move vtd_address_space_unmap() in the context
> entry invalidation processing.

IMHO we need this "whole umap" thing not only for context entry
invalidation, but all the places that need this replay, no? For
example, when we receive domain flush.

Thanks,

-- peterx



Re: [Qemu-devel] [PATCH 03/21] backup: improve non-dirty bits progress processing

2017-01-23 Thread Fam Zheng
On Fri, 12/23 17:28, Vladimir Sementsov-Ogievskiy wrote:
> Set fake progress for non-dirty clusters in copy_bitmap initialization,
> to:
> 1. set progress in the same place where corresponding clusters are
> consumed from copy_bitmap (or not initialized, as here)
> 2. earlier progress information for user
> 3. simplify the code
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>  block/backup.c | 18 +++---
>  1 file changed, 3 insertions(+), 15 deletions(-)
> 
> diff --git a/block/backup.c b/block/backup.c
> index 621b1c0..f1f87f6 100644
> --- a/block/backup.c
> +++ b/block/backup.c
> @@ -383,7 +383,6 @@ static int coroutine_fn 
> backup_run_incremental(BackupBlockJob *job)
>  int64_t sector;
>  int64_t cluster;
>  int64_t end;
> -int64_t last_cluster = -1;
>  int64_t sectors_per_cluster = cluster_size_sectors(job);
>  BdrvDirtyBitmapIter *dbi;
>  
> @@ -395,12 +394,6 @@ static int coroutine_fn 
> backup_run_incremental(BackupBlockJob *job)
>  while ((sector = bdrv_dirty_iter_next(dbi)) != -1) {
>  cluster = sector / sectors_per_cluster;
>  
> -/* Fake progress updates for any clusters we skipped */
> -if (cluster != last_cluster + 1) {
> -job->common.offset += ((cluster - last_cluster - 1) *
> -   job->cluster_size);
> -}
> -
>  for (end = cluster + clusters_per_iter; cluster < end; cluster++) {
>  do {
>  if (yield_and_check(job)) {
> @@ -422,14 +415,6 @@ static int coroutine_fn 
> backup_run_incremental(BackupBlockJob *job)
>  if (granularity < job->cluster_size) {
>  bdrv_set_dirty_iter(dbi, cluster * sectors_per_cluster);
>  }
> -
> -last_cluster = cluster - 1;
> -}
> -
> -/* Play some final catchup with the progress meter */
> -end = DIV_ROUND_UP(job->common.len, job->cluster_size);
> -if (last_cluster + 1 < end) {
> -job->common.offset += ((end - last_cluster - 1) * job->cluster_size);
>  }
>  
>  out:
> @@ -462,6 +447,9 @@ static void 
> backup_incremental_init_copy_bitmap(BackupBlockJob *job)
>  bdrv_set_dirty_iter(dbi, (cluster + cl_gran) * sectors_per_cluster);
>  }
>  
> +job->common.offset = job->common.len -
> + hbitmap_count(job->copy_bitmap) * job->cluster_size;
> +
>  bdrv_dirty_iter_free(dbi);
>  }

Is this effectively moving the progress reporting from cluster copying to dirty
bitmap initialization? If so the progress will stay "100%" once
backup_incremental_init_copy_bitmap returns, but the backup has merely started.
I don't think this is a good idea.

Fam



[Qemu-devel] [PATCH v7 12/14] replay: disable default snapshot for record/replay

2017-01-23 Thread Pavel Dovgalyuk
This patch disables setting '-snapshot' option on by default
in record/replay mode. This is needed for creating vmstates in record
and replay modes.

Signed-off-by: Pavel Dovgalyuk 
---
 vl.c |8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/vl.c b/vl.c
index def0520..bddb2bc 100644
--- a/vl.c
+++ b/vl.c
@@ -3198,7 +3198,13 @@ int main(int argc, char **argv, char **envp)
 drive_add(IF_PFLASH, -1, optarg, PFLASH_OPTS);
 break;
 case QEMU_OPTION_snapshot:
-snapshot = 1;
+{
+Error *blocker = NULL;
+snapshot = 1;
+error_setg(, QERR_REPLAY_NOT_SUPPORTED,
+   "-snapshot");
+replay_add_blocker(blocker);
+}
 break;
 case QEMU_OPTION_hdachs:
 {




Re: [Qemu-devel] [PATCH RFC v4 18/20] intel_iommu: enable vfio devices

2017-01-23 Thread Peter Xu
On Mon, Jan 23, 2017 at 11:03:08AM -0700, Alex Williamson wrote:
> On Mon, 23 Jan 2017 11:34:29 +0800
> Peter Xu  wrote:
> 
> > On Mon, Jan 23, 2017 at 09:55:39AM +0800, Jason Wang wrote:
> > > 
> > > 
> > > On 2017年01月22日 17:04, Peter Xu wrote:  
> > > >On Sun, Jan 22, 2017 at 04:08:04PM +0800, Jason Wang wrote:
> > > >
> > > >[...]
> > > >  
> > > >>>+static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,
> > > >>>+   uint16_t domain_id, hwaddr 
> > > >>>addr,
> > > >>>+   uint8_t am)
> > > >>>+{
> > > >>>+IntelIOMMUNotifierNode *node;
> > > >>>+VTDContextEntry ce;
> > > >>>+int ret;
> > > >>>+
> > > >>>+QLIST_FOREACH(node, &(s->notifiers_list), next) {
> > > >>>+VTDAddressSpace *vtd_as = node->vtd_as;
> > > >>>+ret = vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),
> > > >>>+   vtd_as->devfn, );
> > > >>>+if (!ret && domain_id == VTD_CONTEXT_ENTRY_DID(ce.hi)) {
> > > >>>+vtd_page_walk(, addr, addr + (1 << am) * VTD_PAGE_SIZE,
> > > >>>+  vtd_page_invalidate_notify_hook,
> > > >>>+  (void *)_as->iommu, true);  
> > > >>Why not simply trigger the notifier here? (or is this vfio required?)  
> > > >Because we may only want to notify part of the region - we are with
> > > >mask here, but not exact size.
> > > >
> > > >Consider this: guest (with caching mode) maps 12K memory (4K*3 pages),
> > > >the mask will be extended to 16K in the guest. In that case, we need
> > > >to explicitly go over the page entry to know that the 4th page should
> > > >not be notified.  
> > > 
> > > I see. Then it was required by vfio only, I think we can add a fast path 
> > > for
> > > !CM in this case by triggering the notifier directly.  
> > 
> > I noted this down (to be further investigated in my todo), but I don't
> > know whether this can work, due to the fact that I think it is still
> > legal that guest merge more than one PSIs into one. For example, I
> > don't know whether below is legal:
> > 
> > - guest invalidate page (0, 4k)
> > - guest map new page (4k, 8k)
> > - guest send single PSI of (0, 8k)
> > 
> > In that case, it contains both map/unmap, and looks like it didn't
> > disobay the spec as well?
> 
> The topic of mapping and invalidation granularity also makes me
> slightly concerned with the abstraction we use for the type1 IOMMU
> backend.  With the "v2" type1 configuration we currently use in QEMU,
> the user may only unmap with the same minimum granularity with which
> the original mapping was created.  For instance if an iommu notifier
> map request gets to vfio with an 8k range, the resulting mapping can
> only be removed by an invalidation covering the full range.  Trying to
> bisect that original mapping by only invalidating 4k of the range will
> generate an error.

I see. Then this will be an strict requirement that we cannot do
coalescing during page walk, at least for mappings.

I didn't notice this before, but luckily current series is following
the rule above - we are basically doing the mapping in the unit of
pages. Normally, we should always be mapping with 4K pages, only if
guest provides huge pages in the VT-d page table, would we notify map
with >4K, though of course it can be either 2M/1G but never other
values.

The point is, guest should be aware of the existance of the above huge
pages, so it won't unmap (for example) a single 4k region within a 2M
huge page range. It'll either keep the huge page, or unmap the whole
huge page. In that sense, we are quite safe.

(for my own curiousity and out of topic: could I ask why we can't do
 that? e.g., we map 4K*2 pages, then we unmap the first 4K page?)

> 
> I would think (but please confirm), that when we're only tracking
> mappings generated by the guest OS that this works.  If the guest OS
> maps with 4k pages, we get map notifies for each of those 4k pages.  If
> they use 2MB pages, we get 2MB ranges and invalidations will come in
> the same granularity.

I would agree (I haven't thought of a case that this might be a
problem).

> 
> An area of concern though is the replay mechanism in QEMU, I'll need to
> look for it in the code, but replaying an IOMMU domain into a new
> container *cannot* coalesce mappings or else it limits the granularity
> with which we can later accept unmaps. Take for instance a guest that
> has mapped a contiguous 2MB range with 4K pages.  They can unmap any 4K
> page within that range.  However if vfio gets a single 2MB mapping
> rather than 512 4K mappings, then the host IOMMU may use a hugepage
> mapping where our granularity is now 2MB.  Thanks,

Is this the answer of my above question (which is for my own
curiosity)? If so, that'll kind of explain.

If it's just because vfio is smart enough on automatically using huge
pages when applicable (I believe it's for 

[Qemu-devel] [PATCH v7 09/14] replay: save/load initial state

2017-01-23 Thread Pavel Dovgalyuk
This patch implements initial vmstate creation or loading at the start
of record/replay. It is needed for rewinding the execution in the replay mode.

v4 changes:
 - snapshots are not created by default anymore

v3 changes:
 - added rrsnapshot option

Signed-off-by: Pavel Dovgalyuk 
---
 docs/replay.txt  |   16 
 include/sysemu/replay.h  |9 +
 qemu-options.hx  |8 ++--
 replay/replay-snapshot.c |   17 +
 replay/replay.c  |5 +
 vl.c |7 ++-
 6 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/docs/replay.txt b/docs/replay.txt
index 347b2ff..03e1931 100644
--- a/docs/replay.txt
+++ b/docs/replay.txt
@@ -196,6 +196,22 @@ is recorded to the log. In replay phase the queue is 
matched with
 events read from the log. Therefore block devices requests are processed
 deterministically.
 
+Snapshotting
+
+
+New VM snapshots may be created in replay mode. They can be used later
+to recover the desired VM state. All VM states created in replay mode
+are associated with the moment of time in the replay scenario.
+After recovering the VM state replay will start from that position.
+
+Default starting snapshot name may be specified with icount field
+rrsnapshot as follows:
+ -icount shift=7,rr=record,rrfile=replay.bin,rrsnapshot=snapshot_name
+
+This snapshot is created at start of recording and restored at start
+of replaying. It also can be loaded while replaying to roll back
+the execution.
+
 Network devices
 ---
 
diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index abb35ca..740b425 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -43,6 +43,9 @@ typedef struct ReplayNetState ReplayNetState;
 
 extern ReplayMode replay_mode;
 
+/* Name of the initial VM snapshot */
+extern char *replay_snapshot;
+
 /* Replay process control functions */
 
 /*! Enables recording or saving event log with specified parameters */
@@ -149,4 +152,10 @@ void replay_unregister_net(ReplayNetState *rns);
 void replay_net_packet_event(ReplayNetState *rns, unsigned flags,
  const struct iovec *iov, int iovcnt);
 
+/* VM state operations */
+
+/*! Called at the start of execution.
+Loads or saves initial vmstate depending on execution mode. */
+void replay_vmstate_init(void);
+
 #endif
diff --git a/qemu-options.hx b/qemu-options.hx
index c534a2f..32c7d2b 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3390,12 +3390,12 @@ re-inject them.
 ETEXI
 
 DEF("icount", HAS_ARG, QEMU_OPTION_icount, \
-"-icount 
[shift=N|auto][,align=on|off][,sleep=on|off,rr=record|replay,rrfile=]\n"
 \
+"-icount 
[shift=N|auto][,align=on|off][,sleep=on|off,rr=record|replay,rrfile=,rrsnapshot=]\n"
 \
 "enable virtual instruction counter with 2^N clock ticks 
per\n" \
 "instruction, enable aligning the host and virtual 
clocks\n" \
 "or disable real time cpu sleeping\n", QEMU_ARCH_ALL)
 STEXI
-@item -icount [shift=@var{N}|auto][,rr=record|replay,rrfile=@var{filename}]
+@item -icount 
[shift=@var{N}|auto][,rr=record|replay,rrfile=@var{filename},rrsnapshot=@var{snapshot}]
 @findex -icount
 Enable virtual instruction counter.  The virtual cpu will execute one
 instruction every 2^@var{N} ns of virtual time.  If @code{auto} is specified
@@ -3428,6 +3428,10 @@ when the shift value is high (how high depends on the 
host machine).
 When @option{rr} option is specified deterministic record/replay is enabled.
 Replay log is written into @var{filename} file in record mode and
 read from this file in replay mode.
+
+Option rrsnapshot is used to create new vm snapshot named @var{snapshot}
+at the start of execution recording. In replay mode this option is used
+to load the initial VM state.
 ETEXI
 
 DEF("watchdog", HAS_ARG, QEMU_OPTION_watchdog, \
diff --git a/replay/replay-snapshot.c b/replay/replay-snapshot.c
index 4980597..f2cf748 100644
--- a/replay/replay-snapshot.c
+++ b/replay/replay-snapshot.c
@@ -59,3 +59,20 @@ void replay_vmstate_register(void)
 {
 vmstate_register(NULL, 0, _replay, _state);
 }
+
+void replay_vmstate_init(void)
+{
+if (replay_snapshot) {
+if (replay_mode == REPLAY_MODE_RECORD) {
+if (save_vmstate(cur_mon, replay_snapshot) != 0) {
+error_report("Could not create snapshot for icount record");
+exit(1);
+}
+} else if (replay_mode == REPLAY_MODE_PLAY) {
+if (load_vmstate(replay_snapshot) != 0) {
+error_report("Could not load snapshot for icount replay");
+exit(1);
+}
+}
+}
+}
diff --git a/replay/replay.c b/replay/replay.c
index 7f27cf1..1835b99 100644
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -26,6 +26,7 @@
 #define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t))
 
 ReplayMode 

[Qemu-devel] [PATCH v7 04/14] icount: exit cpu loop on expire

2017-01-23 Thread Pavel Dovgalyuk
This patch adds check to break cpu loop when icount expires without
setting the TB_EXIT_ICOUNT_EXPIRED flag. It happens when there is no
available translated blocks and all instructions were executed.
In icount replay mode unnecessary tb_find will be called (which may
cause an exception) and execution will be non-deterministic.

Signed-off-by: Pavel Dovgalyuk 
---
 cpu-exec.c |   15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 79a2167..e603da4 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -582,9 +582,6 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, 
TranslationBlock *tb,
 cpu_exec_nocache(cpu, insns_left, *last_tb, false);
 align_clocks(sc, cpu);
 }
-cpu->exception_index = EXCP_INTERRUPT;
-*last_tb = NULL;
-cpu_loop_exit(cpu);
 }
 break;
 #endif
@@ -638,6 +635,18 @@ int cpu_exec(CPUState *cpu)
 
 for(;;) {
 cpu_handle_interrupt(cpu, _tb);
+/* icount has expired, we need to break the execution loop.
+   This check is needed before tb_find to make execution
+   deterministic - tb_find may cause an exception
+   while translating the code from non-mapped page. */
+if (use_icount && ((cpu->icount_extra == 0
+&& cpu->icount_decr.u16.low == 0)
+|| (int32_t)cpu->icount_decr.u32 < 0)) {
+if (cpu->exception_index == -1) {
+cpu->exception_index = EXCP_INTERRUPT;
+}
+cpu_loop_exit(cpu);
+}
 tb = tb_find(cpu, last_tb, tb_exit);
 cpu_loop_exec_tb(cpu, tb, _tb, _exit, );
 /* Try to align the host and virtual clocks




[Qemu-devel] [PATCH v7 13/14] audio: make audio poll timer deterministic

2017-01-23 Thread Pavel Dovgalyuk
This patch changes resetting strategy of the audio polling timer.
It does not change expiration time if the timer is already set.

Signed-off-by: Pavel Dovgalyuk 
---
 audio/audio.c |6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index c845a44..1ee95a5 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1112,8 +1112,10 @@ static int audio_is_timer_needed (void)
 static void audio_reset_timer (AudioState *s)
 {
 if (audio_is_timer_needed ()) {
-timer_mod (s->ts,
-qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + conf.period.ticks);
+if (!timer_pending(s->ts)) {
+timer_mod (s->ts,
+qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + conf.period.ticks);
+}
 }
 else {
 timer_del (s->ts);




[Qemu-devel] [PATCH v7 05/14] apic: save apic_delivered flag

2017-01-23 Thread Pavel Dovgalyuk
This patch implements saving/restoring of static apic_delivered variable.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/intc/apic_common.c   |   32 
 include/hw/i386/apic_internal.h |2 ++
 2 files changed, 34 insertions(+)

diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index d78c885..ac6cc67 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -384,6 +384,24 @@ static bool apic_common_sipi_needed(void *opaque)
 return s->wait_for_sipi != 0;
 }
 
+static bool apic_irq_delivered_needed(void *opaque)
+{
+return true;
+}
+
+static void apic_irq_delivered_pre_save(void *opaque)
+{
+APICCommonState *s = APIC_COMMON(opaque);
+s->apic_irq_delivered = apic_irq_delivered;
+}
+
+static int apic_irq_delivered_post_load(void *opaque, int version_id)
+{
+APICCommonState *s = APIC_COMMON(opaque);
+apic_irq_delivered = s->apic_irq_delivered;
+return 0;
+}
+
 static const VMStateDescription vmstate_apic_common_sipi = {
 .name = "apic_sipi",
 .version_id = 1,
@@ -396,6 +414,19 @@ static const VMStateDescription vmstate_apic_common_sipi = 
{
 }
 };
 
+static const VMStateDescription vmstate_apic_irq_delivered = {
+.name = "apic_irq_delivered",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = apic_irq_delivered_needed,
+.pre_save = apic_irq_delivered_pre_save,
+.post_load = apic_irq_delivered_post_load,
+.fields = (VMStateField[]) {
+VMSTATE_INT32(apic_irq_delivered, APICCommonState),
+VMSTATE_END_OF_LIST()
+}
+};
+
 static const VMStateDescription vmstate_apic_common = {
 .name = "apic",
 .version_id = 3,
@@ -430,6 +461,7 @@ static const VMStateDescription vmstate_apic_common = {
 },
 .subsections = (const VMStateDescription*[]) {
 _apic_common_sipi,
+_apic_irq_delivered,
 NULL
 }
 };
diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h
index 1209eb4..20ad28c 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -189,6 +189,8 @@ struct APICCommonState {
 DeviceState *vapic;
 hwaddr vapic_paddr; /* note: persistence via kvmvapic */
 bool legacy_instance_id;
+
+int apic_irq_delivered; /* for saving static variable */
 };
 
 typedef struct VAPICState {




[Qemu-devel] [PATCH v7 06/14] replay: don't use rtc clock on loadvm phase

2017-01-23 Thread Pavel Dovgalyuk
This patch disables the update of the periodic timer of mc146818rtc
in record/replay mode. State of this timer is saved and therefore does
not need to be updated in record/replay mode.
Read of RTC breaks the replay because all rtc reads have to be the same
as in record mode.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/timer/mc146818rtc.c |   14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index da209d0..5638777 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -27,6 +27,7 @@
 #include "hw/hw.h"
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/replay.h"
 #include "hw/timer/mc146818rtc.h"
 #include "qapi/visitor.h"
 #include "qapi-event.h"
@@ -734,10 +735,15 @@ static int rtc_post_load(void *opaque, int version_id)
 check_update_timer(s);
 }
 
-uint64_t now = qemu_clock_get_ns(rtc_clock);
-if (now < s->next_periodic_time ||
-now > (s->next_periodic_time + get_max_clock_jump())) {
-periodic_timer_update(s, qemu_clock_get_ns(rtc_clock));
+/* Periodic timer is deterministic in record/replay mode.
+   No need to update it after loading the vmstate.
+   Reading RTC here may break the execution. */
+if (replay_mode == REPLAY_MODE_NONE) {
+uint64_t now = qemu_clock_get_ns(rtc_clock);
+if (now < s->next_periodic_time ||
+now > (s->next_periodic_time + get_max_clock_jump())) {
+periodic_timer_update(s, qemu_clock_get_ns(rtc_clock));
+}
 }
 
 #ifdef TARGET_I386




[Qemu-devel] [PATCH v7 02/14] replay: improve interrupt handling

2017-01-23 Thread Pavel Dovgalyuk
This patch improves interrupt handling in record/replay mode.
Now "interrupt" event is saved only when cc->cpu_exec_interrupt returns true.
This patch also adds missing return to cpu_exec_interrupt function.

Signed-off-by: Pavel Dovgalyuk 
---
 cpu-exec.c   |2 +-
 target/i386/seg_helper.c |1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 4188fed..fa08c73 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -508,8 +508,8 @@ static inline void cpu_handle_interrupt(CPUState *cpu,
True when it is, and we should restart on a new TB,
and via longjmp via cpu_loop_exit.  */
 else {
-replay_interrupt();
 if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {
+replay_interrupt();
 *last_tb = NULL;
 }
 /* The target hook may have updated the 'cpu->interrupt_request';
diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c
index fb79f31..d24574d 100644
--- a/target/i386/seg_helper.c
+++ b/target/i386/seg_helper.c
@@ -1331,6 +1331,7 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 #endif
 if (interrupt_request & CPU_INTERRUPT_SIPI) {
 do_cpu_sipi(cpu);
+ret = true;
 } else if (env->hflags2 & HF2_GIF_MASK) {
 if ((interrupt_request & CPU_INTERRUPT_SMI) &&
 !(env->hflags & HF_SMM_MASK)) {




[Qemu-devel] [PATCH v7 10/14] block: implement bdrv_snapshot_goto for blkreplay

2017-01-23 Thread Pavel Dovgalyuk
This patch enables making snapshots with blkreplay used in
block devices.

Signed-off-by: Pavel Dovgalyuk 
---
 block/blkreplay.c |8 
 1 file changed, 8 insertions(+)

diff --git a/block/blkreplay.c b/block/blkreplay.c
index a741654..8a03d62 100644
--- a/block/blkreplay.c
+++ b/block/blkreplay.c
@@ -130,6 +130,12 @@ static int coroutine_fn 
blkreplay_co_flush(BlockDriverState *bs)
 return ret;
 }
 
+static int blkreplay_snapshot_goto(BlockDriverState *bs,
+   const char *snapshot_id)
+{
+return bdrv_snapshot_goto(bs->file->bs, snapshot_id);
+}
+
 static BlockDriver bdrv_blkreplay = {
 .format_name= "blkreplay",
 .protocol_name  = "blkreplay",
@@ -145,6 +151,8 @@ static BlockDriver bdrv_blkreplay = {
 .bdrv_co_pwrite_zeroes  = blkreplay_co_pwrite_zeroes,
 .bdrv_co_pdiscard   = blkreplay_co_pdiscard,
 .bdrv_co_flush  = blkreplay_co_flush,
+
+.bdrv_snapshot_goto = blkreplay_snapshot_goto,
 };
 
 static void bdrv_blkreplay_init(void)




[Qemu-devel] [PATCH v7 00/14] replay additions

2017-01-23 Thread Pavel Dovgalyuk
This set of patches includes several fixes for replay and vmstate.

This patches add rrsnapshot option for icount. rrshapshot option creates
start snapshot at record and loads it at replay. It allows preserving
the state of disk images used by virtual machine. This vm state can also
use used to roll back the execution while replaying.

With these patches operations with audio devices can also be recorded
and replayed. All interactions with passthrough audio (including
microphone input) are recorded automatically when -soundhw is specified
at the command line.

This set of patches includes fixes and additions for icount and
record/replay implementation:
 - VM start/stop in replay mode
 - overlay creation for blkreplay filter
 - rrsnapshot option for record/replay
 - vmstate fix for integratorcp ARM platform
 - vmstate fixes for apic and rtc
 - fixes for icount record/replay mode
 - record/replay for audio devices

v7 changes:
 - Fixed exception replaying when TB cache is full and
   when tb_find is called when there are no instructions about to execute
 - Added record/replay for audio devices

v6 changes:
 - Added overlay creation for blkreplay driver
 - Fixed vmstate loading for apic and rtc
 - Fixed instruction counting for apic instruction patching

v5 changes:
 - Recording is stopped when initial snapshot cannot be created
 - Minor changes

v4 changes:
 - Overlay option is removed from blkreplay driver (as suggested by Paolo 
Bonzini)
 - Minor changes

v3 changes:
 - Added rrsnapshot option for specifying the initial snapshot name (as 
suggested by Paolo Bonzini)
 - Minor changes

---

Pavel Dovgalyuk (14):
  icount: update instruction counter on apic patching
  replay: improve interrupt handling
  replay: exception replay fix
  icount: exit cpu loop on expire
  apic: save apic_delivered flag
  replay: don't use rtc clock on loadvm phase
  integratorcp: adding vmstate for save/restore
  savevm: add public save_vmstate function
  replay: save/load initial state
  block: implement bdrv_snapshot_goto for blkreplay
  blkreplay: create temporary overlay for underlaying devices
  replay: disable default snapshot for record/replay
  audio: make audio poll timer deterministic
  replay: add record/replay for audio passthrough


 audio/audio.c   |   15 +--
 audio/audio.h   |5 ++
 audio/mixeng.c  |   31 ++
 block/blkreplay.c   |   84 +++
 cpu-exec.c  |   21 --
 docs/replay.txt |   23 +++
 hw/arm/integratorcp.c   |   62 +
 hw/i386/kvmvapic.c  |6 +++
 hw/intc/apic_common.c   |   32 +++
 hw/timer/mc146818rtc.c  |   14 +--
 include/hw/i386/apic_internal.h |2 +
 include/sysemu/replay.h |   16 +++
 include/sysemu/sysemu.h |1 
 migration/savevm.c  |   33 ++-
 qemu-options.hx |8 +++-
 replay/Makefile.objs|1 
 replay/replay-audio.c   |   79 +
 replay/replay-internal.h|4 ++
 replay/replay-snapshot.c|   17 
 replay/replay.c |5 ++
 stubs/replay.c  |1 
 target/i386/seg_helper.c|1 
 vl.c|   17 +++-
 23 files changed, 450 insertions(+), 28 deletions(-)
 create mode 100644 replay/replay-audio.c

-- 
Pavel Dovgalyuk



[Qemu-devel] [PATCH v7 03/14] replay: exception replay fix

2017-01-23 Thread Pavel Dovgalyuk
This patch fixes replaying the exception when TB cache is full.
It breaks cpu loop execution through setting exception_index
to process such queued work as TB flush.

Signed-off-by: Pavel Dovgalyuk 
---
 cpu-exec.c |4 
 1 file changed, 4 insertions(+)

diff --git a/cpu-exec.c b/cpu-exec.c
index fa08c73..79a2167 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -451,6 +451,10 @@ static inline bool cpu_handle_exception(CPUState *cpu, int 
*ret)
 #ifndef CONFIG_USER_ONLY
 } else if (replay_has_exception()
&& cpu->icount_decr.u16.low + cpu->icount_extra == 0) {
+/* Break the execution loop in case of running out of TB cache.
+   This is needed to make flushing of the TB cache, because
+   real flush is queued to be executed outside the cpu loop. */
+cpu->exception_index = EXCP_INTERRUPT;
 /* try to cause an exception pending in the log */
 cpu_exec_nocache(cpu, 1, tb_find(cpu, NULL, 0), true);
 *ret = -1;




[Qemu-devel] [PATCH v7 01/14] icount: update instruction counter on apic patching

2017-01-23 Thread Pavel Dovgalyuk
kvmvapic patches the code when some instructions are executed.
E.g. mov 0xff, 0xfffe0080 is interpreted as push 0xff/call ...
This patching is also followed by some side effects (changing apic
and guest memory state). Therefore deterministic execution should take
this operation into account. This patch decreases icount when original
mov instruction is trying to execute. Therefore patching becomes
deterministic and can be replayed correctly.

Signed-off-by: Pavel Dovgalyuk 
---
 hw/i386/kvmvapic.c |6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index b30d1b9..146d47c 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -412,6 +412,12 @@ static void patch_instruction(VAPICROMState *s, X86CPU 
*cpu, target_ulong ip)
 if (!kvm_enabled()) {
 cpu_get_tb_cpu_state(env, _pc, _cs_base,
  _flags);
+/* Account this instruction, because we will exit the tb.
+   This is the first instruction in the block. Therefore
+   there is no need in restoring CPU state. */
+if (use_icount) {
+--cs->icount_decr.u16.low;
+}
 }
 
 pause_all_vcpus();




Re: [Qemu-devel] [PATCH 02/21] backup: init copy_bitmap from sync_bitmap for incremental

2017-01-23 Thread Fam Zheng
On Fri, 12/23 17:28, Vladimir Sementsov-Ogievskiy wrote:
> We should not copy non-dirty clusters in write notifiers. So,
> initialize copy_bitmap from sync_bitmap.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>  block/backup.c | 32 +++-
>  1 file changed, 31 insertions(+), 1 deletion(-)
> 
> diff --git a/block/backup.c b/block/backup.c
> index 6b27e55..621b1c0 100644
> --- a/block/backup.c
> +++ b/block/backup.c
> @@ -437,6 +437,34 @@ out:
>  return ret;
>  }
>  
> +/* init copy_bitmap from sync_bitmap */
> +static void backup_incremental_init_copy_bitmap(BackupBlockJob *job)
> +{
> +int64_t sector;
> +BdrvDirtyBitmapIter *dbi;
> +uint32_t sect_gran =
> +bdrv_dirty_bitmap_granularity(job->sync_bitmap) >> BDRV_SECTOR_BITS;
> +int64_t sz = bdrv_dirty_bitmap_size(job->sync_bitmap);
> +int64_t sectors_per_cluster = cluster_size_sectors(job);
> +uint32_t cl_gran = MAX(1, sect_gran / sectors_per_cluster);
> +
> +dbi = bdrv_dirty_iter_new(job->sync_bitmap, 0);
> +while ((sector = bdrv_dirty_iter_next(dbi)) != -1) {
> +int64_t cluster = sector / sectors_per_cluster;
> +int64_t next_sector = (cluster + cl_gran) * sectors_per_cluster;
> +
> +hbitmap_set(job->copy_bitmap, cluster, cl_gran);
> +
> +if (next_sector >= sz) {
> +break;
> +}
> +
> +bdrv_set_dirty_iter(dbi, (cluster + cl_gran) * sectors_per_cluster);
> +}
> +
> +bdrv_dirty_iter_free(dbi);
> +}
> +
>  static void coroutine_fn backup_run(void *opaque)
>  {
>  BackupBlockJob *job = opaque;
> @@ -453,20 +481,22 @@ static void coroutine_fn backup_run(void *opaque)
>  end = DIV_ROUND_UP(job->common.len, job->cluster_size);
>  
>  job->copy_bitmap = hbitmap_alloc(end, 0);
> -hbitmap_set(job->copy_bitmap, 0, end);
>  
>  job->before_write.notify = backup_before_write_notify;
>  bdrv_add_before_write_notifier(bs, >before_write);
>  
>  if (job->sync_mode == MIRROR_SYNC_MODE_NONE) {
> +hbitmap_set(job->copy_bitmap, 0, end);

This is confusing. It seems job->copy_bitmap is actually a superset of clusters
to copy instead of the exact one?  Because "none" mode doesn't need blanket copy
- only overwritten clusters are copied...

>  while (!block_job_is_cancelled(>common)) {
>  /* Yield until the job is cancelled.  We just let our 
> before_write
>   * notify callback service CoW requests. */
>  block_job_yield(>common);
>  }
>  } else if (job->sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
> +backup_incremental_init_copy_bitmap(job);

... But here you are only marking bits in sync_bitmap.

Fam

>  ret = backup_run_incremental(job);
>  } else {
> +hbitmap_set(job->copy_bitmap, 0, end);
>  /* Both FULL and TOP SYNC_MODE's require copying.. */
>  for (; start < end; start++) {
>  bool error_is_read;
> -- 
> 1.8.3.1
> 



Re: [Qemu-devel] [PATCH v2 0/2] POWER9 TCG enablements - part12

2017-01-23 Thread Nikunj A Dadhania
Nikunj A Dadhania  writes:

> This series contains 5 new instructions for POWER9 ISA3.0
> VSX Scalar Test Data Class
> VSX Vector Test Data Class
>
> Changelog:
> v1:
> * Zero the match variable in the element loops
>
> v0:
> * Concise logic for identifying data class in Scalar/Vector 
>   test data class instructions
>
> Nikunj A Dadhania (2):
>   target-ppc: Add xvtstdc[sp,dp] instructions
>   target-ppc: Add xststdc[sp, dp, qp] instructions

Ping?

Regards
Nikunj




Re: [Qemu-devel] [PATCH RFC v4 16/20] intel_iommu: do replay when context invalidate

2017-01-23 Thread Peter Xu
On Mon, Jan 23, 2017 at 06:36:17PM +0800, Jason Wang wrote:
> 
> 
> On 2017年01月20日 21:08, Peter Xu wrote:
> >Before this one we only invalidate context cache when we receive context
> >entry invalidations. However it's possible that the invalidation also
> >contains a domain switch (only if cache-mode is enabled for vIOMMU). In
> >that case we need to notify all the registered components about the new
> >mapping.
> >
> >Signed-off-by: Peter Xu 
> >---
> >  hw/i386/intel_iommu.c | 10 ++
> >  1 file changed, 10 insertions(+)
> >
> >diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
> >index f9c5142..4b08b4d 100644
> >--- a/hw/i386/intel_iommu.c
> >+++ b/hw/i386/intel_iommu.c
> >@@ -1146,6 +1146,16 @@ static void 
> >vtd_context_device_invalidate(IntelIOMMUState *s,
> >  trace_vtd_inv_desc_cc_device(bus_n, VTD_PCI_SLOT(devfn_it),
> >   VTD_PCI_FUNC(devfn_it));
> >  vtd_as->context_cache_entry.context_cache_gen = 0;
> >+/*
> >+ * So a device is moving out of (or moving into) a
> >+ * domain, a replay() suites here to notify all the
> >+ * IOMMU_NOTIFIER_MAP registers about this change.
> >+ * This won't bring bad even if we have no such
> >+ * notifier registered - the IOMMU notification
> >+ * framework will skip MAP notifications if that
> >+ * happened.
> >+ */
> >+memory_region_iommu_replay_all(_as->iommu);
> 
> DSI and GLOBAL questions come back again or no need to care about them :) ?

DSI/GLOBAL hanldings are in patch 20 (though it'll be squashed into 18
in my next post). Is that what you mean above?

Thanks!

-- peterx



Re: [Qemu-devel] [PATCH RFC v4 18/20] intel_iommu: enable vfio devices

2017-01-23 Thread Peter Xu
On Mon, Jan 23, 2017 at 06:23:44PM +0800, Jason Wang wrote:
> 
> 
> On 2017年01月23日 11:34, Peter Xu wrote:
> >On Mon, Jan 23, 2017 at 09:55:39AM +0800, Jason Wang wrote:
> >>
> >>On 2017年01月22日 17:04, Peter Xu wrote:
> >>>On Sun, Jan 22, 2017 at 04:08:04PM +0800, Jason Wang wrote:
> >>>
> >>>[...]
> >>>
> >+static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,
> >+   uint16_t domain_id, hwaddr 
> >addr,
> >+   uint8_t am)
> >+{
> >+IntelIOMMUNotifierNode *node;
> >+VTDContextEntry ce;
> >+int ret;
> >+
> >+QLIST_FOREACH(node, &(s->notifiers_list), next) {
> >+VTDAddressSpace *vtd_as = node->vtd_as;
> >+ret = vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),
> >+   vtd_as->devfn, );
> >+if (!ret && domain_id == VTD_CONTEXT_ENTRY_DID(ce.hi)) {
> >+vtd_page_walk(, addr, addr + (1 << am) * VTD_PAGE_SIZE,
> >+  vtd_page_invalidate_notify_hook,
> >+  (void *)_as->iommu, true);
> Why not simply trigger the notifier here? (or is this vfio required?)
> >>>Because we may only want to notify part of the region - we are with
> >>>mask here, but not exact size.
> >>>
> >>>Consider this: guest (with caching mode) maps 12K memory (4K*3 pages),
> >>>the mask will be extended to 16K in the guest. In that case, we need
> >>>to explicitly go over the page entry to know that the 4th page should
> >>>not be notified.
> >>I see. Then it was required by vfio only, I think we can add a fast path for
> >>!CM in this case by triggering the notifier directly.
> >I noted this down (to be further investigated in my todo), but I don't
> >know whether this can work, due to the fact that I think it is still
> >legal that guest merge more than one PSIs into one. For example, I
> >don't know whether below is legal:
> >
> >- guest invalidate page (0, 4k)
> >- guest map new page (4k, 8k)
> >- guest send single PSI of (0, 8k)
> >
> >In that case, it contains both map/unmap, and looks like it didn't
> >disobay the spec as well?
> 
> Not sure I get your meaning, you mean just send single PSI instead of two?

Yes, and looks like that still doesn't violate the spec?

Actually for now, I think the best way to do with this series is that,
we can first let it in (so that advanced users can start to use it and
play with it). Then, we can get more feedback and solve critical
issues that may matter to customers and users.

For the above, I think per-page walk is the safest one for now. And I
can do investigate (as I mentioned) in the future to see whether we
can make it faster, according to your suggestion. However that'll be
nice we do it after we have some real use cases for this series, then
we can make sure the enhancement won't break anything besides boosting
the performance.

But of course I would like to listen to the maintainer's opinion on
this...

> 
> >
> >>Another possible issue is, consider (with CM) a 16K contiguous iova with the
> >>last page has already been mapped. In this case, if we want to map first
> >>three pages, when handling IOTLB invalidation, am would be 16K, then the
> >>last page will be mapped twice. Can this lead some issue?
> >I don't know whether guest has special handling of this kind of
> >request.
> 
> This seems quite usual I think? E.g iommu_flush_iotlb_psi() did:
> 
> static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
>   struct dmar_domain *domain,
>   unsigned long pfn, unsigned int pages,
>   int ih, int map)
> {
> unsigned int mask = ilog2(__roundup_pow_of_two(pages));
> uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
> u16 did = domain->iommu_did[iommu->seq_id];
> ...

Yes, do rounding up should be the only thing to do when we have
unaligned size.

> 
> 
> >
> >Besides, imho to completely solve this problem, we still need that
> >per-domain tree. Considering that currently the tree is inside vfio, I
> >see this not a big issue as well.
> 
> Another issue I found is: with this series, VFIO_IOMMU_MAP_DMA seems become
> guest trigger-able. And since VFIO allocate its own structure to record dma
> mapping, this seems open a window for evil guest to exhaust host memory
> which is even worse.

(I see Alex replied in another email, so will skip this one)

> 
> >  In that case, the last page mapping
> >request will fail (we might see one error line from QEMU stderr),
> >however that'll not affect too much since currently vfio allows that
> >failure to happen (ioctl fail, but that page is still mapped, which is
> >what we wanted).
> 
> Works but sub-optimal or maybe even buggy.

Again, to finally solve this, I think we need a tree. But I don't
think that's a good idea for this series, considering that we have
already had one in the kernel. But I see 

[Qemu-devel] update-linux-headers.sh fails on clean kernel dir

2017-01-23 Thread Sam Bobroff
Hi QEMU developers,

If I run scripts/update-linux-headers.sh from a clean checkout of QEMU
and point it at a clean checkout of a recent linux kernel (4.10-rc1 or
later), it fails:

$ scripts/update-linux-headers.sh ~/tmp/linux/

...

scripts/Makefile.headersinst:62: *** Missing generated UAPI file 
./arch/arm/include/generated/uapi/asm/unistd-common.h.  Stop.

This seems to be because the script passes the arch to the kernel
makefile using "SRCARCH" rather than "ARCH".

(SRCARCH seems to be intended as an internal value, and setting it does
not propagate the setting to ARCH. Because ARCH is left empty, the
prerequisites that should generate unistd-common.h fail. If ARCH is set,
SRCARCH is set automatically and everything works.)

Changing the script to use "ARCH" seems to fixe the problem.

(Note: when testing this be careful: unistd-common.h is not removed by
"make clean" in the kernel directory.)

Does this seem correct?

Should I send a patch even though it's a very small change?

Cheers,
Sam.




Re: [Qemu-devel] [PATCH RFC v4 02/20] vfio: introduce vfio_get_vaddr()

2017-01-23 Thread Alex Williamson
On Tue, 24 Jan 2017 11:28:18 +0800
Peter Xu  wrote:

> On Mon, Jan 23, 2017 at 11:49:05AM -0700, Alex Williamson wrote:
> > On Fri, 20 Jan 2017 21:08:38 +0800
> > Peter Xu  wrote:
> >   
> > > A cleanup for vfio_iommu_map_notify(). Should have no functional change,
> > > just to make the function shorter and easier to understand.
> > > 
> > > Signed-off-by: Peter Xu 
> > > ---
> > >  hw/vfio/common.c | 58 
> > > +---
> > >  1 file changed, 38 insertions(+), 20 deletions(-)
> > > 
> > > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > > index 174f351..ce55dff 100644
> > > --- a/hw/vfio/common.c
> > > +++ b/hw/vfio/common.c
> > > @@ -294,25 +294,14 @@ static bool 
> > > vfio_listener_skipped_section(MemoryRegionSection *section)
> > > section->offset_within_address_space & (1ULL << 63);
> > >  }
> > >  
> > > -static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
> > > +static bool vfio_get_vaddr(IOMMUTLBEntry *iotlb, void **vaddr,
> > > +   bool *read_only)
> > >  {
> > > -VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n);
> > > -VFIOContainer *container = giommu->container;
> > > -hwaddr iova = iotlb->iova + giommu->iommu_offset;
> > >  MemoryRegion *mr;
> > >  hwaddr xlat;
> > >  hwaddr len = iotlb->addr_mask + 1;
> > > -void *vaddr;
> > > -int ret;
> > > -
> > > -trace_vfio_iommu_map_notify(iotlb->perm == IOMMU_NONE ? "UNMAP" : 
> > > "MAP",
> > > -iova, iova + iotlb->addr_mask);
> > > -
> > > -if (iotlb->target_as != _space_memory) {
> > > -error_report("Wrong target AS \"%s\", only system memory is 
> > > allowed",
> > > - iotlb->target_as->name ? iotlb->target_as->name : 
> > > "none");
> > > -return;
> > > -}
> > > +bool ret = false;
> > > +bool writable = iotlb->perm & IOMMU_WO;
> > >  
> > >  /*
> > >   * The IOMMU TLB entry we have just covers translation through
> > > @@ -322,12 +311,13 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, 
> > > IOMMUTLBEntry *iotlb)
> > >  rcu_read_lock();
> > >  mr = address_space_translate(_space_memory,
> > >   iotlb->translated_addr,
> > > - , , iotlb->perm & IOMMU_WO);
> > > + , , writable);
> > >  if (!memory_region_is_ram(mr)) {
> > >  error_report("iommu map to non memory area %"HWADDR_PRIx"",
> > >   xlat);
> > >  goto out;
> > >  }
> > > +
> > >  /*
> > >   * Translation truncates length to the IOMMU page size,
> > >   * check that it did not truncate too much.
> > > @@ -337,11 +327,41 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, 
> > > IOMMUTLBEntry *iotlb)
> > >  goto out;
> > >  }
> > >  
> > > +*vaddr = memory_region_get_ram_ptr(mr) + xlat;
> > > +*read_only = !writable || mr->readonly;
> > > +ret = true;
> > > +
> > > +out:
> > > +rcu_read_unlock();
> > > +return ret;
> > > +}
> > > +
> > > +static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
> > > +{
> > > +VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n);
> > > +VFIOContainer *container = giommu->container;
> > > +hwaddr iova = iotlb->iova + giommu->iommu_offset;
> > > +bool read_only;
> > > +void *vaddr;
> > > +int ret;
> > > +
> > > +trace_vfio_iommu_map_notify(iotlb->perm == IOMMU_NONE ? "UNMAP" : 
> > > "MAP",
> > > +iova, iova + iotlb->addr_mask);
> > > +
> > > +if (iotlb->target_as != _space_memory) {
> > > +error_report("Wrong target AS \"%s\", only system memory is 
> > > allowed",
> > > + iotlb->target_as->name ? iotlb->target_as->name : 
> > > "none");
> > > +return;
> > > +}
> > > +
> > > +if (!vfio_get_vaddr(iotlb, , _only)) {
> > > +return;
> > > +}
> > > +
> > >  if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
> > > -vaddr = memory_region_get_ram_ptr(mr) + xlat;
> > >  ret = vfio_dma_map(container, iova,
> > > iotlb->addr_mask + 1, vaddr,
> > > -   !(iotlb->perm & IOMMU_WO) || mr->readonly);
> > > +   read_only);  
> > 
> > Is it really valid to move the map ioctl out of the rcu read lock?
> > We're making use of vaddr, which is directly a property of a
> > MemoryRegion which may have now disappeared.  With the lock released,
> > could an unmap race the map resulting in the wrong ordering?  As noted
> > previously, there are some subtle changes here, we do the
> > memory_region_get_ram_ptr() translation on both map and unmap (fixed in
> > next patch) and then pull map out of the rcu lock.  I'm not sure the
> > extra function is 

Re: [Qemu-devel] [Bug 1658634] Re: Can't get correct display with latest QEMU and OVMF BIOS

2017-01-23 Thread Kai Cong
Splash screen and UEFI shell were displayed correctly. Grub2 menu and
Ubuntu login screen also appeared, however the display didn't seem right. I
got very blurry output.

[image: Inline image 1]

With QEMU 2.7.0 and the same OVMF.fd, everything works well.

Please let me know if anything is not clear.

Thanks,
Kai

On Mon, Jan 23, 2017 at 4:50 AM, Laszlo Ersek (Red Hat) 
wrote:

> (1) What phase of the guest do you get invalid video output in? Do you
> see the TianoCore splash screen? Does the grub2 menu appear?
>
> (2) I cannot reproduce the issue (with a different guest OS anyway); I
> just tried QEMU (at d1c82f7cc344) and OVMF (built from edk2 at
> 7cf59c854f35), with stdvga; this combo works fine.
>
> (3) Can you bisect QEMU from 2.7 through 2.8, using the same OVMF
> binary?
>
> (4) Side point: please *never* use "-bios OVMF.fd"; use two pflash chips
> instead. Libvirt (strongly recommended) will do this for you.
>
> Thanks.
>
> --
> You received this bug notification because you are subscribed to the bug
> report.
> https://bugs.launchpad.net/bugs/1658634
>
> Title:
>   Can't get correct display with latest QEMU and OVMF BIOS
>
> Status in QEMU:
>   New
>
> Bug description:
>   I tried to install a Ubuntu 16.04.1 Desktop 64bits with latest QEMU and
> OVMF UEFI BIOS, however I can't get correct display output with default vga
> configuration (-vga std). However, qemu works with a couple of different
> configurations:
>   1. "-vga cirrus" + "-bios OVMF.fd": works
>   2. "-vga std" + non-UEFI bios: works
>
>   The same error with QEMU 2.8.0 release. Everything works well on
>   2.7.0/1.
>
> To manage notifications about this bug go to:
> https://bugs.launchpad.net/qemu/+bug/1658634/+subscriptions
>


** Attachment added: "image.png"
   https://bugs.launchpad.net/bugs/1658634/+attachment/4808338/+files/image.png

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

Title:
  Can't get correct display with latest QEMU and OVMF BIOS

Status in QEMU:
  New

Bug description:
  I tried to install a Ubuntu 16.04.1 Desktop 64bits with latest QEMU and OVMF 
UEFI BIOS, however I can't get correct display output with default vga 
configuration (-vga std). However, qemu works with a couple of different 
configurations:
  1. "-vga cirrus" + "-bios OVMF.fd": works
  2. "-vga std" + non-UEFI bios: works

  The same error with QEMU 2.8.0 release. Everything works well on
  2.7.0/1.

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



Re: [Qemu-devel] [PATCH RFC v4 15/20] intel_iommu: provide its own replay() callback

2017-01-23 Thread Peter Xu
On Mon, Jan 23, 2017 at 12:34:29PM -0700, Alex Williamson wrote:
> On Mon, 23 Jan 2017 10:54:49 +0800
> Peter Xu  wrote:
> 
> > On Mon, Jan 23, 2017 at 09:48:48AM +0800, Jason Wang wrote:
> > > 
> > > 
> > > On 2017年01月22日 16:51, Peter Xu wrote:  
> > > >On Sun, Jan 22, 2017 at 03:56:10PM +0800, Jason Wang wrote:
> > > >
> > > >[...]
> > > >  
> > > >>>+/**
> > > >>>+ * vtd_page_walk_level - walk over specific level for IOVA range
> > > >>>+ *
> > > >>>+ * @addr: base GPA addr to start the walk
> > > >>>+ * @start: IOVA range start address
> > > >>>+ * @end: IOVA range end address (start <= addr < end)
> > > >>>+ * @hook_fn: hook func to be called when detected page
> > > >>>+ * @private: private data to be passed into hook func
> > > >>>+ * @read: whether parent level has read permission
> > > >>>+ * @write: whether parent level has write permission
> > > >>>+ * @skipped: accumulated skipped ranges  
> > > >>What's the usage for this parameter? Looks like it was never used in 
> > > >>this
> > > >>series.  
> > > >This was for debugging purpose before, and I kept it in case one day
> > > >it can be used again, considering that will not affect much on the
> > > >overall performance.  
> > > 
> > > I think we usually do not keep debugging codes outside debug macros.  
> > 
> > I'll remove it.
> 
> While you're at it, what's the value in using a void* private rather
> than just passing around an IOMMUNotifier*.  Seems like unnecessary
> abstraction.  Thanks,

When handling PSIs (in continuous patches, not this one), we were
passing in MemoryRegion* rather than IOMMUNotifier*:

vtd_page_walk(, addr, addr + (1 << am) * VTD_PAGE_SIZE,
vtd_page_invalidate_notify_hook,
(void *)_as->iommu, true);

So a void* might still be required. Thanks,

-- peterx



Re: [Qemu-devel] [PATCH RFC v4 02/20] vfio: introduce vfio_get_vaddr()

2017-01-23 Thread Peter Xu
On Mon, Jan 23, 2017 at 11:49:05AM -0700, Alex Williamson wrote:
> On Fri, 20 Jan 2017 21:08:38 +0800
> Peter Xu  wrote:
> 
> > A cleanup for vfio_iommu_map_notify(). Should have no functional change,
> > just to make the function shorter and easier to understand.
> > 
> > Signed-off-by: Peter Xu 
> > ---
> >  hw/vfio/common.c | 58 
> > +---
> >  1 file changed, 38 insertions(+), 20 deletions(-)
> > 
> > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > index 174f351..ce55dff 100644
> > --- a/hw/vfio/common.c
> > +++ b/hw/vfio/common.c
> > @@ -294,25 +294,14 @@ static bool 
> > vfio_listener_skipped_section(MemoryRegionSection *section)
> > section->offset_within_address_space & (1ULL << 63);
> >  }
> >  
> > -static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
> > +static bool vfio_get_vaddr(IOMMUTLBEntry *iotlb, void **vaddr,
> > +   bool *read_only)
> >  {
> > -VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n);
> > -VFIOContainer *container = giommu->container;
> > -hwaddr iova = iotlb->iova + giommu->iommu_offset;
> >  MemoryRegion *mr;
> >  hwaddr xlat;
> >  hwaddr len = iotlb->addr_mask + 1;
> > -void *vaddr;
> > -int ret;
> > -
> > -trace_vfio_iommu_map_notify(iotlb->perm == IOMMU_NONE ? "UNMAP" : 
> > "MAP",
> > -iova, iova + iotlb->addr_mask);
> > -
> > -if (iotlb->target_as != _space_memory) {
> > -error_report("Wrong target AS \"%s\", only system memory is 
> > allowed",
> > - iotlb->target_as->name ? iotlb->target_as->name : 
> > "none");
> > -return;
> > -}
> > +bool ret = false;
> > +bool writable = iotlb->perm & IOMMU_WO;
> >  
> >  /*
> >   * The IOMMU TLB entry we have just covers translation through
> > @@ -322,12 +311,13 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, 
> > IOMMUTLBEntry *iotlb)
> >  rcu_read_lock();
> >  mr = address_space_translate(_space_memory,
> >   iotlb->translated_addr,
> > - , , iotlb->perm & IOMMU_WO);
> > + , , writable);
> >  if (!memory_region_is_ram(mr)) {
> >  error_report("iommu map to non memory area %"HWADDR_PRIx"",
> >   xlat);
> >  goto out;
> >  }
> > +
> >  /*
> >   * Translation truncates length to the IOMMU page size,
> >   * check that it did not truncate too much.
> > @@ -337,11 +327,41 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, 
> > IOMMUTLBEntry *iotlb)
> >  goto out;
> >  }
> >  
> > +*vaddr = memory_region_get_ram_ptr(mr) + xlat;
> > +*read_only = !writable || mr->readonly;
> > +ret = true;
> > +
> > +out:
> > +rcu_read_unlock();
> > +return ret;
> > +}
> > +
> > +static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
> > +{
> > +VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n);
> > +VFIOContainer *container = giommu->container;
> > +hwaddr iova = iotlb->iova + giommu->iommu_offset;
> > +bool read_only;
> > +void *vaddr;
> > +int ret;
> > +
> > +trace_vfio_iommu_map_notify(iotlb->perm == IOMMU_NONE ? "UNMAP" : 
> > "MAP",
> > +iova, iova + iotlb->addr_mask);
> > +
> > +if (iotlb->target_as != _space_memory) {
> > +error_report("Wrong target AS \"%s\", only system memory is 
> > allowed",
> > + iotlb->target_as->name ? iotlb->target_as->name : 
> > "none");
> > +return;
> > +}
> > +
> > +if (!vfio_get_vaddr(iotlb, , _only)) {
> > +return;
> > +}
> > +
> >  if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
> > -vaddr = memory_region_get_ram_ptr(mr) + xlat;
> >  ret = vfio_dma_map(container, iova,
> > iotlb->addr_mask + 1, vaddr,
> > -   !(iotlb->perm & IOMMU_WO) || mr->readonly);
> > +   read_only);
> 
> Is it really valid to move the map ioctl out of the rcu read lock?
> We're making use of vaddr, which is directly a property of a
> MemoryRegion which may have now disappeared.  With the lock released,
> could an unmap race the map resulting in the wrong ordering?  As noted
> previously, there are some subtle changes here, we do the
> memory_region_get_ram_ptr() translation on both map and unmap (fixed in
> next patch) and then pull map out of the rcu lock.  I'm not sure the
> extra function is worthwhile or really has no functional change.
> Thanks,

Thanks for raising this question up.

IIUC this function can be triggered by three cases (this is for x86, I
suppose the rule should be same for all platforms):

- memory hot add/remove
- a PSI (page selective invalidation) for a newly mapped io page
- a domain switch 

Re: [Qemu-devel] [PATCH 01/17] migration: transform remained DPRINTF into trace_

2017-01-23 Thread Eric Blake
On 01/23/2017 03:32 PM, Juan Quintela wrote:

In the subject: s/remained/remaining/

> So we can remove DPRINTF() macro
> 
> Signed-off-by: Juan Quintela 
> ---
>  migration/ram.c| 18 --
>  migration/trace-events |  4 
>  2 files changed, 8 insertions(+), 14 deletions(-)
> 
> diff --git a/migration/ram.c b/migration/ram.c
> index a1c8089..ef8fadf 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -45,14 +45,6 @@
>  #include "qemu/rcu_queue.h"
>  #include "migration/colo.h"
> 
> -#ifdef DEBUG_MIGRATION_RAM
> -#define DPRINTF(fmt, ...) \
> -do { fprintf(stdout, "migration_ram: " fmt, ## __VA_ARGS__); } while (0)
> -#else
> -#define DPRINTF(fmt, ...) \
> -do { } while (0)

Yay - you're getting rid of the bitrot pattern in this file!

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 for-2.9 0/2] hbitmap: Add hbitmap_is_serializable()

2017-01-23 Thread Fam Zheng
On Tue, 11/15 23:57, Max Reitz wrote:
> This series is a follow-up for "hbitmap: Fix shifts of constants by
> granularity".
> 
> So far, adding the assertion in hbitmap_serialization_granularity() (as
> done by said previous patch) is enough and we know that it will always
> hold true since bitmaps are only serialized as part of a test for now.
> 
> However, in the future we need some other way than a failed assertion to
> tell the user that they cannot serialize a certain bitmap. This series
> adds a function that can be called to tell whether a bitmap can be
> (de-)serialized.

Queued, thanks. I'll send a pull request before the holidays.

Fam



[Qemu-devel] [Bug 1626972] Re: QEMU memfd_create fallback mechanism change for security drivers

2017-01-23 Thread Rafael David Tinoco
For me we had enough tests already. Upstream development/tests, Zesty,
Yakkety. Christian, could you please move Xenial for me ? I have some
end users waiting for this. Thank you very much.

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

Title:
  QEMU memfd_create fallback mechanism change for security drivers

Status in Ubuntu Cloud Archive:
  Invalid
Status in Ubuntu Cloud Archive mitaka series:
  Fix Committed
Status in QEMU:
  Fix Released
Status in qemu package in Ubuntu:
  Fix Released
Status in qemu source package in Xenial:
  Fix Committed
Status in qemu source package in Yakkety:
  Fix Released
Status in qemu source package in Zesty:
  Fix Released

Bug description:
  [Impact]

   * Updated QEMU (from UCA) live migration doesn't work with 3.13 kernels.
   * QEMU code checks if it can create /tmp/memfd-XXX files wrongly.
   * Apparmor will block access to /tmp/ and QEMU will fail migrating.

  [Test Case]

   * Install 2 Ubuntu Trusty (3.13) + UCA Mitaka + apparmor rules.
   * Try to live-migration from one to another. 
   * Apparmor will block creation of /tmp/memfd-XXX files.

  [Regression Potential]

   Pros:
   * Exhaustively tested this.
   * Worked with upstream on this fix. 
   * I'm implementing new vhost log mechanism for upstream.
   * One line change to a blocker that is already broken.

   Cons:
   * To break live migration in other circumstances. 

  [Other Info]

   * Christian Ehrhardt has been following this.

  ORIGINAL DESCRIPTION:

  When libvirt starts using apparmor, and creating apparmor profiles for
  every virtual machine created in the compute nodes, mitaka qemu (2.5 -
  and upstream also) uses a fallback mechanism for creating shared
  memory for live-migrations. This fall back mechanism, on kernels 3.13
  - that don't have memfd_create() system-call, try to create files on
  /tmp/ directory and fails.. causing live-migration not to work.

  Trusty with kernel 3.13 + Mitaka with qemu 2.5 + apparmor capability =
  can't live migrate.

  From qemu 2.5, logic is on :

  void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals, int 
*fd)
  {
  if (memfd_create)... ### only works with HWE kernels

  else ### 3.13 kernels, gets blocked by apparmor
     tmpdir = g_get_tmp_dir
     ...
     mfd = mkstemp(fname)
  }

  And you can see the errors:

  From the host trying to send the virtual machine:

  2016-08-15 16:36:26.160 1974 ERROR nova.virt.libvirt.driver 
[req-0cac612b-8d53-4610-b773-d07ad6bacb91 691a581cfa7046278380ce82b1c38ddd 
133ebc3585c041aebaead8c062cd6511 - - -] [instance: 
2afa1131-bc8c-43d2-9c4a-962c1bf7723e] Migration operation has aborted
  2016-08-15 16:36:26.248 1974 ERROR nova.virt.libvirt.driver 
[req-0cac612b-8d53-4610-b773-d07ad6bacb91 691a581cfa7046278380ce82b1c38ddd 
133ebc3585c041aebaead8c062cd6511 - - -] [instance: 
2afa1131-bc8c-43d2-9c4a-962c1bf7723e] Live Migration failure: internal error: 
unable to execute QEMU command 'migrate': Migration disabled: failed to 
allocate shared memory

  From the host trying to receive the virtual machine:

  Aug 15 16:36:19 tkcompute01 kernel: [ 1194.356794] type=1400 
audit(1471289779.791:72): apparmor="STATUS" operation="profile_load" 
profile="unconfined" name="libvirt-2afa1131-bc8c-43d2-9c4a-962c1bf7723e" 
pid=12565 comm="apparmor_parser"
  Aug 15 16:36:19 tkcompute01 kernel: [ 1194.357048] type=1400 
audit(1471289779.791:73): apparmor="STATUS" operation="profile_load" 
profile="unconfined" name="qemu_bridge_helper" pid=12565 comm="apparmor_parser"
  Aug 15 16:36:20 tkcompute01 kernel: [ 1194.877027] type=1400 
audit(1471289780.311:74): apparmor="STATUS" operation="profile_replace" 
profile="unconfined" name="libvirt-2afa1131-bc8c-43d2-9c4a-962c1bf7723e" 
pid=12613 comm="apparmor_parser"
  Aug 15 16:36:20 tkcompute01 kernel: [ 1194.904407] type=1400 
audit(1471289780.343:75): apparmor="STATUS" operation="profile_replace" 
profile="unconfined" name="qemu_bridge_helper" pid=12613 comm="apparmor_parser"
  Aug 15 16:36:20 tkcompute01 kernel: [ 1194.973064] type=1400 
audit(1471289780.407:76): apparmor="DENIED" operation="mknod" 
profile="libvirt-2afa1131-bc8c-43d2-9c4a-962c1bf7723e" name="/tmp/memfd-tNpKSj" 
pid=12625 comm="qemu-system-x86" requested_mask="c" denied_mask="c" fsuid=107 
ouid=107
  Aug 15 16:36:20 tkcompute01 kernel: [ 1194.979871] type=1400 
audit(1471289780.411:77): apparmor="DENIED" operation="open" 
profile="libvirt-2afa1131-bc8c-43d2-9c4a-962c1bf7723e" name="/tmp/" pid=12625 
comm="qemu-system-x86" requested_mask="r" denied_mask="r" fsuid=107 ouid=0
  Aug 15 16:36:20 tkcompute01 kernel: [ 1194.979881] type=1400 
audit(1471289780.411:78): apparmor="DENIED" operation="open" 
profile="libvirt-2afa1131-bc8c-43d2-9c4a-962c1bf7723e" name="/var/tmp/" 
pid=12625 comm="qemu-system-x86" requested_mask="r" denied_mask="r" fsuid=107 
ouid=0

  When leaving libvirt 

[Qemu-devel] [Bug 1622547] Re: qemu-system-sparc fatal error Trap 0x29 on Solaris 2.6

2017-01-23 Thread m...@papersolve.com
Just confirmed that it works in QEMU 2.7.1, which is strange, since
2.8.0 does not list any SPARC changes!

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

Title:
  qemu-system-sparc fatal error Trap 0x29 on Solaris 2.6

Status in QEMU:
  New

Bug description:
  When trying to install Solaris 2.6 from original CDROM, qemu fail with
  the following error :

  qemu: fatal: Trap 0x29 while interrupts disabled, Error state
  pc: f0041280  npc: f0041284
  %g0-7:  f0281800 0800   f0243b88 0001 f0244020
  %o0-7: 40400ce2 40400ce2  404000e2 f0243b88  f023ffd8 
f0057914 
  %l0-7: 4cc2 f009645c f0096460 0002 0209 0004 0007 
f023ff90 
  %i0-7: 0042 404000e3  404000e3 e000 f028192a f0240038 
f0096448 
  %f00:     
  %f08:     
  %f16:     
  %f24:     
  psr: 40400cc2 (icc: -Z-- SPE: SP-) wim: 0002
  fsr:  y: 

  The command line was :

  qemu-system-sparc -nographic -bios ./openbios-sparc32 -M SS-20 -hda
  ./36G.disk -m 512 -cdrom Solaris_2.6_Software_05_98.img -boot d
  -serial telnet:0.0.0.0:3000,server -smp 2,cores=2 -monitor null

  It fails with a similar output when using bios ss20_v2.25_rom.

  ▶ qemu-system-sparc --version
  QEMU emulator version 2.7.0, Copyright (c) 2003-2016 Fabrice Bellard and the 
QEMU Project developers

  ▶ uname -a
  Linux xxx 4.7.1-1-ARCH #1 SMP PREEMPT Wed Aug 17 08:13:35 CEST 2016 x86_64 
GNU/Linux

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



Re: [Qemu-devel] [PATCH v2 8/8] hw/mips: MIPS Boston board support

2017-01-23 Thread Yongbok Kim


On 08/09/2016 15:51, Paul Burton wrote:
> Introduce support for emulating the MIPS Boston development board. The
> Boston board is built around an FPGA & 3 PCIe controllers, one of which
> is connected to an Intel EG20T Platform Controller Hub. It is used
> during the development & debug of new CPUs and the software intended to
> run on them, and is essentially the successor to the older MIPS Malta
> board.
> 
> This patch does not implement the EG20T, instead connecting an already
> supported ICH-9 AHCI controller. Whilst this isn't accurate it's enough
> for typical stock Boston software (eg. Linux kernels) to work with hard
> disks given that both the ICH-9 & EG20T implement the AHCI
> specification.
> 
> Boston boards typically boot kernels in the FIT image format, and this
> patch will treat kernels provided to QEMU as such. When loading a kernel
> directly, the board code will generate minimal firmware much as the
> Malta board code does. This firmware will set up the CM, CPC & GIC
> register base addresses then set argument registers & jump to the kernel
> entry point. Alternatively, bootloader code may be loaded using the bios
> argument in which case no firmware will be generated & execution will
> proceed from the start of the boot code at the default MIPS boot
> exception vector (offset 0x1fc0 into (c)kseg1).
> 
> Currently real Boston boards are always used with FPGA bitfiles that
> include a Global Interrupt Controller (GIC), so the interrupt
> configuration is only defined for such cases. Therefore the board will
> only allow use of CPUs which implement the CPS components, including the
> GIC, and will otherwise exit with a message.
> 
> Signed-off-by: Paul Burton 
> ---
> Changes in v2:
> - Require libfdt for mips*-softmmu builds, so that the FIT loader can be used.
> ---
>  configure   |   2 +-
>  default-configs/mips-softmmu-common.mak |   2 +
>  hw/mips/Makefile.objs   |   1 +
>  hw/mips/boston.c| 526 
> 
>  4 files changed, 530 insertions(+), 1 deletion(-)
>  create mode 100644 hw/mips/boston.c
> 
> diff --git a/configure b/configure
> index 1c4e117..242a113 100755
> --- a/configure
> +++ b/configure
> @@ -3308,7 +3308,7 @@ fi
>  fdt_required=no
>  for target in $target_list; do
>case $target in
> -aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu)
> +
> aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips*-softmmu)

As I mentioned earlier email, bigendian target doesn't work correctly. it
has be little endian only for now.

>fdt_required=yes
>  ;;
>esac
> diff --git a/default-configs/mips-softmmu-common.mak 
> b/default-configs/mips-softmmu-common.mak
> index 0394514..09b7334 100644
> --- a/default-configs/mips-softmmu-common.mak
> +++ b/default-configs/mips-softmmu-common.mak
> @@ -32,3 +32,5 @@ CONFIG_ISA_TESTDEV=y
>  CONFIG_EMPTY_SLOT=y
>  CONFIG_MIPS_CPS=y
>  CONFIG_MIPS_ITU=y
> +CONFIG_MIPS_BOSTON=y
> +CONFIG_PCI_XILINX=y
> diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs
> index 9352a1c..48cd2ef 100644
> --- a/hw/mips/Makefile.objs
> +++ b/hw/mips/Makefile.objs
> @@ -4,3 +4,4 @@ obj-$(CONFIG_JAZZ) += mips_jazz.o
>  obj-$(CONFIG_FULONG) += mips_fulong2e.o
>  obj-y += gt64xxx_pci.o
>  obj-$(CONFIG_MIPS_CPS) += cps.o
> +obj-$(CONFIG_MIPS_BOSTON) += boston.o
> diff --git a/hw/mips/boston.c b/hw/mips/boston.c
> new file mode 100644
> index 000..4e02907
> --- /dev/null
> +++ b/hw/mips/boston.c
> @@ -0,0 +1,526 @@
> +/*
> + * MIPS Boston development board emulation.
> + *
> + * Copyright (c) 2016 Imagination Technologies
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see 
> .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu-common.h"
> +
> +#include "exec/address-spaces.h"
> +#include "hw/boards.h"
> +#include "hw/char/serial.h"
> +#include "hw/hw.h"
> +#include "hw/ide/pci.h"
> +#include "hw/ide/ahci.h"
> +#include "hw/loader.h"
> +#include "hw/loader-fit.h"
> +#include "hw/mips/cps.h"
> +#include "hw/mips/cpudevs.h"
> +#include "hw/pci-host/xilinx-pcie.h"
> +#include "qapi/error.h"
> +#include "qemu/cutils.h"
> +#include "qemu/error-report.h"
> +#include "qemu/log.h"
> +#include "sysemu/char.h"
> +#include "sysemu/device_tree.h"
> 

[Qemu-devel] [Bug 1622547] Re: qemu-system-sparc fatal error Trap 0x29 on Solaris 2.6

2017-01-23 Thread m...@papersolve.com
** Changed in: qemu
   Status: Invalid => New

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

Title:
  qemu-system-sparc fatal error Trap 0x29 on Solaris 2.6

Status in QEMU:
  New

Bug description:
  When trying to install Solaris 2.6 from original CDROM, qemu fail with
  the following error :

  qemu: fatal: Trap 0x29 while interrupts disabled, Error state
  pc: f0041280  npc: f0041284
  %g0-7:  f0281800 0800   f0243b88 0001 f0244020
  %o0-7: 40400ce2 40400ce2  404000e2 f0243b88  f023ffd8 
f0057914 
  %l0-7: 4cc2 f009645c f0096460 0002 0209 0004 0007 
f023ff90 
  %i0-7: 0042 404000e3  404000e3 e000 f028192a f0240038 
f0096448 
  %f00:     
  %f08:     
  %f16:     
  %f24:     
  psr: 40400cc2 (icc: -Z-- SPE: SP-) wim: 0002
  fsr:  y: 

  The command line was :

  qemu-system-sparc -nographic -bios ./openbios-sparc32 -M SS-20 -hda
  ./36G.disk -m 512 -cdrom Solaris_2.6_Software_05_98.img -boot d
  -serial telnet:0.0.0.0:3000,server -smp 2,cores=2 -monitor null

  It fails with a similar output when using bios ss20_v2.25_rom.

  ▶ qemu-system-sparc --version
  QEMU emulator version 2.7.0, Copyright (c) 2003-2016 Fabrice Bellard and the 
QEMU Project developers

  ▶ uname -a
  Linux xxx 4.7.1-1-ARCH #1 SMP PREEMPT Wed Aug 17 08:13:35 CEST 2016 x86_64 
GNU/Linux

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



[Qemu-devel] [PULL 12/13] kvm: Simplify invtsc check

2017-01-23 Thread Eduardo Habkost
Instead of searching the table we have just built, we can check
the env->features field directly.

Reviewed-by: Marcelo Tosatti 
Signed-off-by: Eduardo Habkost 
Message-Id: <20170108173234.25721-2-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 target/i386/kvm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index e6c4f754ab..9744552b8a 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -963,8 +963,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
 has_msr_mcg_ext_ctl = has_msr_feature_control = true;
 }
 
-c = cpuid_find_entry(_data.cpuid, 0x8007, 0);
-if (c && (c->edx & 1<<8) && invtsc_mig_blocker == NULL) {
+if ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC) &&
+invtsc_mig_blocker == NULL) {
 /* for migration */
 error_setg(_mig_blocker,
"State blocked by non-migratable CPU device"
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 11/13] hw/core/null-machine: Add the possibility to instantiate a CPU and RAM

2017-01-23 Thread Eduardo Habkost
From: Thomas Huth 

Sometimes it is useful to have just a machine with CPU and RAM, without
any further hardware in it, e.g. if you just want to do some instruction
debugging for TCG with a remote GDB attached to QEMU, or run some embedded
code with the "-semihosting" QEMU parameter. qemu-system-m68k already
features a "dummy" machine, and xtensa a "sim" machine for exactly this
purpose.
All target architectures have nowadays also a "none" machine, which would
be a perfect match for this, too - but it currently does not allow to add
CPU and RAM yet. Thus let's add these possibilities in a generic way to the
"none" machine, too, so that we hopefully do not need additional "dummy"
machines in the future anymore (and maybe can also get rid of the already
existing "dummy"/"sim" machines one day).
Note that the default behaviour of the "none" machine is not changed, i.e.
no CPU and no RAM is instantiated by default. You have explicitely got to
specify the CPU model with "-cpu" and the amount of RAM with "-m" to get
these new features.

Signed-off-by: Thomas Huth 
Message-Id: <1484743490-24721-1-git-send-email-th...@redhat.com>
Reviewed-by: Eduardo Habkost 
Reviewed-by: Alistair Francis 
Signed-off-by: Eduardo Habkost 
---
 hw/core/null-machine.c | 27 +--
 hw/core/Makefile.objs  |  2 +-
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c
index 0351ba7828..27c8369b57 100644
--- a/hw/core/null-machine.c
+++ b/hw/core/null-machine.c
@@ -13,18 +13,41 @@
 
 #include "qemu/osdep.h"
 #include "qemu-common.h"
+#include "qemu/error-report.h"
 #include "hw/hw.h"
 #include "hw/boards.h"
+#include "sysemu/sysemu.h"
+#include "exec/address-spaces.h"
+#include "cpu.h"
 
-static void machine_none_init(MachineState *machine)
+static void machine_none_init(MachineState *mch)
 {
+CPUState *cpu = NULL;
+
+/* Initialize CPU (if a model has been specified) */
+if (mch->cpu_model) {
+cpu = cpu_init(mch->cpu_model);
+if (!cpu) {
+error_report("Unable to initialize CPU");
+exit(1);
+}
+}
+
+/* RAM at address zero */
+if (mch->ram_size) {
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+
+memory_region_allocate_system_memory(ram, NULL, "ram", mch->ram_size);
+memory_region_add_subregion(get_system_memory(), 0, ram);
+}
 }
 
 static void machine_none_machine_init(MachineClass *mc)
 {
 mc->desc = "empty machine";
 mc->init = machine_none_init;
-mc->max_cpus = 0;
+mc->max_cpus = 1;
+mc->default_ram_size = 0;
 }
 
 DEFINE_MACHINE("none", machine_none_machine_init)
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index 833fd46897..7f8c9dc659 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -12,7 +12,6 @@ common-obj-$(CONFIG_XILINX_AXI) += stream.o
 common-obj-$(CONFIG_PTIMER) += ptimer.o
 common-obj-$(CONFIG_SOFTMMU) += sysbus.o
 common-obj-$(CONFIG_SOFTMMU) += machine.o
-common-obj-$(CONFIG_SOFTMMU) += null-machine.o
 common-obj-$(CONFIG_SOFTMMU) += loader.o
 common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
 common-obj-$(CONFIG_SOFTMMU) += register.o
@@ -20,3 +19,4 @@ common-obj-$(CONFIG_SOFTMMU) += or-irq.o
 common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
 
 obj-$(CONFIG_SOFTMMU) += generic-loader.o
+obj-$(CONFIG_SOFTMMU) += null-machine.o
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 08/13] machine: Make possible_cpu_arch_ids() return const pointer

2017-01-23 Thread Eduardo Habkost
From: Igor Mammedov 

make sure that external callers won't try to modify
possible_cpus and owner of possible_cpus can access
it directly when it modifies it.

Signed-off-by: Igor Mammedov 
Message-Id: <1484759609-264075-5-git-send-email-imamm...@redhat.com>
Reviewed-by: Eduardo Habkost 
Signed-off-by: Eduardo Habkost 
---
 include/hw/acpi/acpi_dev_interface.h |  2 +-
 include/hw/boards.h  |  2 +-
 include/hw/i386/pc.h |  2 +-
 hw/acpi/cpu.c|  6 ++
 hw/acpi/cpu_hotplug.c|  4 +---
 hw/i386/acpi-build.c |  8 +++-
 hw/i386/pc.c | 10 +++---
 stubs/pc_madt_cpu_entry.c|  2 +-
 8 files changed, 13 insertions(+), 23 deletions(-)

diff --git a/include/hw/acpi/acpi_dev_interface.h 
b/include/hw/acpi/acpi_dev_interface.h
index 901a4ae876..71d3c48e7d 100644
--- a/include/hw/acpi/acpi_dev_interface.h
+++ b/include/hw/acpi/acpi_dev_interface.h
@@ -57,6 +57,6 @@ typedef struct AcpiDeviceIfClass {
 void (*ospm_status)(AcpiDeviceIf *adev, ACPIOSTInfoList ***list);
 void (*send_event)(AcpiDeviceIf *adev, AcpiEventStatusBits ev);
 void (*madt_cpu)(AcpiDeviceIf *adev, int uid,
- CPUArchIdList *apic_ids, GArray *entry);
+ const CPUArchIdList *apic_ids, GArray *entry);
 } AcpiDeviceIfClass;
 #endif
diff --git a/include/hw/boards.h b/include/hw/boards.h
index a51da9c440..ac891a828b 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -135,7 +135,7 @@ struct MachineClass {
 HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
DeviceState *dev);
 unsigned (*cpu_index_to_socket_id)(unsigned cpu_index);
-CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine);
+const CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine);
 HotpluggableCPUList *(*query_hotpluggable_cpus)(MachineState *machine);
 };
 
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 738bfd6c60..5a20c5e38e 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -361,7 +361,7 @@ uint16_t pvpanic_port(void);
 
 /* acpi-build.c */
 void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
-   CPUArchIdList *apic_ids, GArray *entry);
+   const CPUArchIdList *apic_ids, GArray *entry);
 
 /* e820 types */
 #define E820_RAM1
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 5ac89fefaf..6017ca04bf 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -190,7 +190,7 @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
 {
 MachineState *machine = MACHINE(qdev_get_machine());
 MachineClass *mc = MACHINE_GET_CLASS(machine);
-CPUArchIdList *id_list;
+const CPUArchIdList *id_list;
 int i;
 
 assert(mc->possible_cpu_arch_ids);
@@ -201,7 +201,6 @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
 state->devs[i].cpu =  id_list->cpus[i].cpu;
 state->devs[i].arch_id = id_list->cpus[i].arch_id;
 }
-g_free(id_list);
 memory_region_init_io(>ctrl_reg, owner, _hotplug_ops, state,
   "acpi-mem-hotplug", ACPI_CPU_HOTPLUG_REG_LEN);
 memory_region_add_subregion(as, base_addr, >ctrl_reg);
@@ -325,7 +324,7 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 Aml *one = aml_int(1);
 Aml *sb_scope = aml_scope("_SB");
 MachineClass *mc = MACHINE_GET_CLASS(machine);
-CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine);
+const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine);
 char *cphp_res_path = g_strdup_printf("%s." CPUHP_RES_DEVICE, res_root);
 Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, NULL);
 AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj);
@@ -574,5 +573,4 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 aml_append(table, method);
 
 g_free(cphp_res_path);
-g_free(arch_ids);
 }
diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index f15a2402fc..5243918125 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -128,7 +128,7 @@ void build_legacy_cpu_hotplug_aml(Aml *ctx, MachineState 
*machine,
 Aml *zero = aml_int(0);
 Aml *one = aml_int(1);
 MachineClass *mc = MACHINE_GET_CLASS(machine);
-CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine);
+const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine);
 PCMachineState *pcms = PC_MACHINE(machine);
 
 /*
@@ -329,8 +329,6 @@ void build_legacy_cpu_hotplug_aml(Aml *ctx, MachineState 
*machine,
 apic_idx = apic_id + 1;
 }
 aml_append(sb_scope, aml_name_decl(CPU_ON_BITMAP, pkg));
-g_free(apic_ids);
-
 aml_append(ctx, sb_scope);
 
 method = aml_method("\\_GPE._E02", 0, AML_NOTSERIALIZED);

[Qemu-devel] [PULL 05/13] arch_init: Remove unnecessary default_config_files table

2017-01-23 Thread Eduardo Habkost
The existing default_config_files table in arch_init.c has a
single entry, making it completely unnecessary. The whole code
can be replaced by a single qemu_read_config_file() call in vl.c.

Signed-off-by: Eduardo Habkost 
Message-Id: <20170117180051.11958-1-ehabk...@redhat.com>
Reviewed-by: Paolo Bonzini 
Signed-off-by: Eduardo Habkost 
---
 include/qemu/config-file.h |  4 
 arch_init.c| 27 ---
 vl.c   | 18 ++
 3 files changed, 14 insertions(+), 35 deletions(-)

diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
index 8d4b2b6d94..c80d5c8a33 100644
--- a/include/qemu/config-file.h
+++ b/include/qemu/config-file.h
@@ -23,8 +23,4 @@ int qemu_read_config_file(const char *filename);
 void qemu_config_parse_qdict(QDict *options, QemuOptsList **lists,
  Error **errp);
 
-/* Read default QEMU config files
- */
-int qemu_read_default_config_files(bool userconfig);
-
 #endif /* QEMU_CONFIG_FILE_H */
diff --git a/arch_init.c b/arch_init.c
index 6c4e287d57..c316ae1023 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -83,33 +83,6 @@ int graphic_depth = 32;
 
 const uint32_t arch_type = QEMU_ARCH;
 
-static struct defconfig_file {
-const char *filename;
-/* Indicates it is an user config file (disabled by -no-user-config) */
-bool userconfig;
-} default_config_files[] = {
-{ CONFIG_QEMU_CONFDIR "/qemu.conf",   true },
-{ NULL }, /* end of list */
-};
-
-int qemu_read_default_config_files(bool userconfig)
-{
-int ret;
-struct defconfig_file *f;
-
-for (f = default_config_files; f->filename; f++) {
-if (!userconfig && f->userconfig) {
-continue;
-}
-ret = qemu_read_config_file(f->filename);
-if (ret < 0 && ret != -ENOENT) {
-return ret;
-}
-}
-
-return 0;
-}
-
 struct soundhw {
 const char *name;
 const char *descr;
diff --git a/vl.c b/vl.c
index ed1cbe9c73..abb0900fe4 100644
--- a/vl.c
+++ b/vl.c
@@ -2950,6 +2950,18 @@ static int global_init_func(void *opaque, QemuOpts 
*opts, Error **errp)
 return 0;
 }
 
+static int qemu_read_default_config_file(void)
+{
+int ret;
+
+ret = qemu_read_config_file(CONFIG_QEMU_CONFDIR "/qemu.conf");
+if (ret < 0 && ret != -ENOENT) {
+return ret;
+}
+
+return 0;
+}
+
 int main(int argc, char **argv, char **envp)
 {
 int i;
@@ -3077,10 +3089,8 @@ int main(int argc, char **argv, char **envp)
 }
 }
 
-if (defconfig) {
-int ret;
-ret = qemu_read_default_config_files(userconfig);
-if (ret < 0) {
+if (defconfig && userconfig) {
+if (qemu_read_default_config_file() < 0) {
 exit(1);
 }
 }
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 07/13] pc: don't return cpu pointer from pc_new_cpu() as it's not needed anymore

2017-01-23 Thread Eduardo Habkost
From: Igor Mammedov 

Signed-off-by: Igor Mammedov 
Message-Id: <1484759609-264075-4-git-send-email-imamm...@redhat.com>
Reviewed-by: Eduardo Habkost 
Signed-off-by: Eduardo Habkost 
---
 hw/i386/pc.c | 24 
 1 file changed, 8 insertions(+), 16 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c0d0d2c6a1..079346ac5d 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1092,28 +1092,24 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int 
level)
 }
 }
 
-static X86CPU *pc_new_cpu(const char *typename, int64_t apic_id,
-  Error **errp)
+static void pc_new_cpu(const char *typename, int64_t apic_id, Error **errp)
 {
-X86CPU *cpu = NULL;
+Object *cpu = NULL;
 Error *local_err = NULL;
 
-cpu = X86_CPU(object_new(typename));
+cpu = object_new(typename);
 
-object_property_set_int(OBJECT(cpu), apic_id, "apic-id", _err);
-object_property_set_bool(OBJECT(cpu), true, "realized", _err);
+object_property_set_int(cpu, apic_id, "apic-id", _err);
+object_property_set_bool(cpu, true, "realized", _err);
 
+object_unref(cpu);
 if (local_err) {
 error_propagate(errp, local_err);
-object_unref(OBJECT(cpu));
-cpu = NULL;
 }
-return cpu;
 }
 
 void pc_hot_add_cpu(const int64_t id, Error **errp)
 {
-X86CPU *cpu;
 ObjectClass *oc;
 PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
 int64_t apic_id = x86_cpu_apic_id_from_index(id);
@@ -1133,12 +1129,11 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
 
 assert(pcms->possible_cpus->cpus[0].cpu); /* BSP is always present */
 oc = OBJECT_CLASS(CPU_GET_CLASS(pcms->possible_cpus->cpus[0].cpu));
-cpu = pc_new_cpu(object_class_get_name(oc), apic_id, _err);
+pc_new_cpu(object_class_get_name(oc), apic_id, _err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
 }
-object_unref(OBJECT(cpu));
 }
 
 void pc_cpus_init(PCMachineState *pcms)
@@ -1148,7 +1143,6 @@ void pc_cpus_init(PCMachineState *pcms)
 ObjectClass *oc;
 const char *typename;
 gchar **model_pieces;
-X86CPU *cpu = NULL;
 MachineState *machine = MACHINE(pcms);
 
 /* init CPUs */
@@ -1190,9 +1184,7 @@ void pc_cpus_init(PCMachineState *pcms)
 pcms->possible_cpus->cpus[i].arch_id = x86_cpu_apic_id_from_index(i);
 pcms->possible_cpus->len++;
 if (i < smp_cpus) {
-cpu = pc_new_cpu(typename, x86_cpu_apic_id_from_index(i),
- _fatal);
-object_unref(OBJECT(cpu));
+pc_new_cpu(typename, x86_cpu_apic_id_from_index(i), _fatal);
 }
 }
 }
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 13/13] kvm: Allow invtsc migration if tsc-khz is set explicitly

2017-01-23 Thread Eduardo Habkost
We can safely allow a VM to be migrated with invtsc enabled if
tsc-khz is set explicitly, because:
* QEMU already refuses to start if it can't set the TSC frequency
  to the configured value.
* Management software is already required to keep device
  configuration (including CPU configuration) the same on
  migration source and destination.

Signed-off-by: Eduardo Habkost 
Message-Id: <20170108173234.25721-3-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 target/i386/kvm.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 9744552b8a..3b5282186c 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -963,15 +963,17 @@ int kvm_arch_init_vcpu(CPUState *cs)
 has_msr_mcg_ext_ctl = has_msr_feature_control = true;
 }
 
-if ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC) &&
-invtsc_mig_blocker == NULL) {
-/* for migration */
-error_setg(_mig_blocker,
-   "State blocked by non-migratable CPU device"
-   " (invtsc flag)");
-migrate_add_blocker(invtsc_mig_blocker);
-/* for savevm */
-vmstate_x86_cpu.unmigratable = 1;
+if (!env->user_tsc_khz) {
+if ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC) &&
+invtsc_mig_blocker == NULL) {
+/* for migration */
+error_setg(_mig_blocker,
+   "State blocked by non-migratable CPU device"
+   " (invtsc flag)");
+migrate_add_blocker(invtsc_mig_blocker);
+/* for savevm */
+vmstate_x86_cpu.unmigratable = 1;
+}
 }
 
 cpuid_data.cpuid.padding = 0;
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 02/13] i386: Remove AMD feature flag aliases from Opteron models

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

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

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

Signed-off-by: Eduardo Habkost 
Message-Id: <20170113190057.6327-1-ehabk...@redhat.com>
Reviewed-by: Igor Mammedov 
Signed-off-by: Eduardo Habkost 
---
 target/i386/cpu.c | 46 --
 1 file changed, 12 insertions(+), 34 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b6c8c5d65b..0e5ecb3a0f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1339,12 +1339,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
 .features[FEAT_1_ECX] =
 CPUID_EXT_SSE3,
 .features[FEAT_8000_0001_EDX] =
-CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
-CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
-CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
-CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
-CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
-CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
+CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
 .xlevel = 0x8008,
 .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
 },
@@ -1365,13 +1360,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
 CPUID_EXT_CX16 | CPUID_EXT_SSE3,
 /* Missing: CPUID_EXT2_RDTSCP */
 .features[FEAT_8000_0001_EDX] =
-CPUID_EXT2_LM | CPUID_EXT2_FXSR |
-CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
-CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
-CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
-CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
-CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
-CPUID_EXT2_DE | CPUID_EXT2_FPU,
+CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
 .features[FEAT_8000_0001_ECX] =
 CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
 .xlevel = 0x8008,
@@ -1395,13 +1384,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
 CPUID_EXT_SSE3,
 /* Missing: CPUID_EXT2_RDTSCP */
 .features[FEAT_8000_0001_EDX] =
-CPUID_EXT2_LM | CPUID_EXT2_FXSR |
-CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
-CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
-CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
-CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
-CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
-CPUID_EXT2_DE | CPUID_EXT2_FPU,
+CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
 .features[FEAT_8000_0001_ECX] =
 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
 CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
@@ -1428,13 +1411,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
 CPUID_EXT_SSE3,
 /* Missing: CPUID_EXT2_RDTSCP */
 .features[FEAT_8000_0001_EDX] =
-CPUID_EXT2_LM |
-CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
-CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
-CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
-CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
-CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
-CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
+CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_NX |
+CPUID_EXT2_SYSCALL,
 .features[FEAT_8000_0001_ECX] =
 CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
@@ -1464,13 +1442,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
 CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
 /* Missing: CPUID_EXT2_RDTSCP */
 .features[FEAT_8000_0001_EDX] =
-CPUID_EXT2_LM |
-CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
-CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
-CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
-CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
-CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
-CPUID_EXT2_TSC | 

[Qemu-devel] [PULL 06/13] pc: cleanup: move smbios_set_cpuid() into pc_build_smbios()

2017-01-23 Thread Eduardo Habkost
From: Igor Mammedov 

move smbios_set_cpuid() close to the rest of smbios init code
where it belongs to instead of calling it from pc_cpus_init().

Signed-off-by: Igor Mammedov 
Message-Id: <1484759609-264075-3-git-send-email-imamm...@redhat.com>
Reviewed-by: Eduardo Habkost 
Signed-off-by: Eduardo Habkost 
---
 hw/i386/pc.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index f721fde0c2..c0d0d2c6a1 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -701,16 +701,20 @@ static uint32_t x86_cpu_apic_id_from_index(unsigned int 
cpu_index)
 }
 }
 
-static void pc_build_smbios(FWCfgState *fw_cfg)
+static void pc_build_smbios(PCMachineState *pcms)
 {
 uint8_t *smbios_tables, *smbios_anchor;
 size_t smbios_tables_len, smbios_anchor_len;
 struct smbios_phys_mem_area *mem_array;
 unsigned i, array_count;
+X86CPU *cpu = X86_CPU(pcms->possible_cpus->cpus[0].cpu);
+
+/* tell smbios about cpuid version and features */
+smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
 
 smbios_tables = smbios_get_table_legacy(_tables_len);
 if (smbios_tables) {
-fw_cfg_add_bytes(fw_cfg, FW_CFG_SMBIOS_ENTRIES,
+fw_cfg_add_bytes(pcms->fw_cfg, FW_CFG_SMBIOS_ENTRIES,
  smbios_tables, smbios_tables_len);
 }
 
@@ -731,9 +735,9 @@ static void pc_build_smbios(FWCfgState *fw_cfg)
 g_free(mem_array);
 
 if (smbios_anchor) {
-fw_cfg_add_file(fw_cfg, "etc/smbios/smbios-tables",
+fw_cfg_add_file(pcms->fw_cfg, "etc/smbios/smbios-tables",
 smbios_tables, smbios_tables_len);
-fw_cfg_add_file(fw_cfg, "etc/smbios/smbios-anchor",
+fw_cfg_add_file(pcms->fw_cfg, "etc/smbios/smbios-anchor",
 smbios_anchor, smbios_anchor_len);
 }
 }
@@ -1191,9 +1195,6 @@ void pc_cpus_init(PCMachineState *pcms)
 object_unref(OBJECT(cpu));
 }
 }
-
-/* tell smbios about cpuid version and features */
-smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);
 }
 
 static void pc_build_feature_control_file(PCMachineState *pcms)
@@ -1266,7 +1267,7 @@ void pc_machine_done(Notifier *notifier, void *data)
 
 acpi_setup();
 if (pcms->fw_cfg) {
-pc_build_smbios(pcms->fw_cfg);
+pc_build_smbios(pcms);
 pc_build_feature_control_file(pcms);
 /* update FW_CFG_NB_CPUS to account for -device added CPUs */
 fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus);
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 10/13] qemu-options: Rename variables on the -numa "cpus" option

2017-01-23 Thread Eduardo Habkost
Use @var{firstcpu} and @var{lastcpu} to make the metasyntatic
variables a bit clearer. While doing this, use @var only around
the metasyntatic variables, not including the square brackets and
hyphen.

The semantics of the "cpus" option will be clarified by rewriting
the whole -numa documentation in a follow-up patch.

Reported-by: Peter Maydell 
Signed-off-by: Eduardo Habkost 
Message-Id: <20170123180632.28942-2-ehabk...@redhat.com>
Reviewed-by: Peter Maydell 
Signed-off-by: Eduardo Habkost 
---
 qemu-options.hx | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index 80df52651a..780528d6ad 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -119,11 +119,11 @@ specifies the maximum number of hotpluggable CPUs.
 ETEXI
 
 DEF("numa", HAS_ARG, QEMU_OPTION_numa,
-"-numa node[,mem=size][,cpus=cpu[-cpu]][,nodeid=node]\n"
-"-numa node[,memdev=id][,cpus=cpu[-cpu]][,nodeid=node]\n", QEMU_ARCH_ALL)
+"-numa node[,mem=size][,cpus=firstcpu[-lastcpu]][,nodeid=node]\n"
+"-numa node[,memdev=id][,cpus=firstcpu[-lastcpu]][,nodeid=node]\n", 
QEMU_ARCH_ALL)
 STEXI
-@item -numa node[,mem=@var{size}][,cpus=@var{cpu[-cpu]}][,nodeid=@var{node}]
-@itemx -numa node[,memdev=@var{id}][,cpus=@var{cpu[-cpu]}][,nodeid=@var{node}]
+@item -numa 
node[,mem=@var{size}][,cpus=@var{firstcpu}[-@var{lastcpu}]][,nodeid=@var{node}]
+@itemx -numa 
node[,memdev=@var{id}][,cpus=@var{firstcpu}[-@var{lastcpu}]][,nodeid=@var{node}]
 @findex -numa
 Simulate a multi node NUMA system. If @samp{mem}, @samp{memdev}
 and @samp{cpus} are omitted, resources are split equally. Also, note
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 00/13] x86, machine, numa queue (2017-01-23)

2017-01-23 Thread Eduardo Habkost
The following changes since commit 3879284d6517dc22529395bdb259f4183b589127:

  Merge remote-tracking branch 'remotes/berrange/tags/pull-qio-2017-01-23-2' 
into staging (2017-01-23 15:59:09 +)

are available in the git repository at:

  git://github.com/ehabkost/qemu.git tags/x86-and-machine-pull-request

for you to fetch changes up to d99569d9d8562c480e0befab601756b0b7b5d0e0:

  kvm: Allow invtsc migration if tsc-khz is set explicitly (2017-01-23 21:26:27 
-0200)


x86, machine, numa queue (2017-01-23)



Dou Liyang (1):
  vl: Ensure the numa_post_machine_init func in the appropriate location

Eduardo Habkost (6):
  i386: Remove AMD feature flag aliases from Opteron models
  i386: Return migration-safe field on query-cpu-definitions
  arch_init: Remove unnecessary default_config_files table
  qemu-options: Rename variables on the -numa "cpus" option
  kvm: Simplify invtsc check
  kvm: Allow invtsc migration if tsc-khz is set explicitly

He Chen (1):
  x86: add AVX512_VPOPCNTDQ features

Igor Mammedov (3):
  pc: cleanup: move smbios_set_cpuid() into pc_build_smbios()
  pc: don't return cpu pointer from pc_new_cpu() as it's not needed
anymore
  machine: Make possible_cpu_arch_ids() return const pointer

Thomas Huth (2):
  MAINTAINERS: Add an entry for hw/core/null-machine.c
  hw/core/null-machine: Add the possibility to instantiate a CPU and RAM

 include/hw/acpi/acpi_dev_interface.h |  2 +-
 include/hw/boards.h  |  2 +-
 include/hw/i386/pc.h |  2 +-
 include/qemu/config-file.h   |  4 ---
 target/i386/cpu-qom.h|  2 ++
 target/i386/cpu.h|  1 +
 arch_init.c  | 27 ---
 hw/acpi/cpu.c|  6 ++---
 hw/acpi/cpu_hotplug.c|  4 +--
 hw/core/null-machine.c   | 27 +--
 hw/i386/acpi-build.c |  8 +++---
 hw/i386/pc.c | 51 ++--
 stubs/pc_madt_cpu_entry.c|  2 +-
 target/i386/cpu.c| 51 +++-
 target/i386/kvm.c| 20 +++---
 vl.c | 23 +++-
 MAINTAINERS  |  1 +
 hw/core/Makefile.objs|  2 +-
 qemu-options.hx  |  8 +++---
 19 files changed, 108 insertions(+), 135 deletions(-)

-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 09/13] MAINTAINERS: Add an entry for hw/core/null-machine.c

2017-01-23 Thread Eduardo Habkost
From: Thomas Huth 

The "Machine core" section sounds like a good match for this file.

Signed-off-by: Thomas Huth 
Message-Id: <1485150895-19753-1-git-send-email-th...@redhat.com>
Reviewed-by: Marcel Apfelbaum 
Signed-off-by: Eduardo Habkost 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ad1000415d..57bd0276e3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -813,6 +813,7 @@ M: Eduardo Habkost 
 M: Marcel Apfelbaum 
 S: Supported
 F: hw/core/machine.c
+F: hw/core/null-machine.c
 F: include/hw/boards.h
 
 Xtensa Machines
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 04/13] vl: Ensure the numa_post_machine_init func in the appropriate location

2017-01-23 Thread Eduardo Habkost
From: Dou Liyang 

In the numa_post_machine_init(), we use CPU_FOREACH macro to set all
CPUs' namu_node. So, we should make sure that we call it after Qemu
has already initialied all the CPUs.

As we all know, the CPUs can be created by "-smp"(pc_new_cpu) or
"-device"(qdev_device_add) command. But, before the device init,
Qemu execute the numa_post_machine_init earlier. It makes the mapping
of NUMA nodes and CPUs incorrect.

The patch move the numa_post_machine_init func in the appropriate
location.

Signed-off-by: Dou Liyang 
Message-Id: <1484664152-24446-2-git-send-email-douly.f...@cn.fujitsu.com>
Reviewed-by: Eduardo Habkost 
Signed-off-by: Eduardo Habkost 
---
 vl.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/vl.c b/vl.c
index a260f30974..ed1cbe9c73 100644
--- a/vl.c
+++ b/vl.c
@@ -4513,8 +4513,6 @@ int main(int argc, char **argv, char **envp)
 
 cpu_synchronize_all_post_init();
 
-numa_post_machine_init();
-
 if (hax_enabled()) {
 hax_sync_vcpus();
 }
@@ -4539,6 +4537,9 @@ int main(int argc, char **argv, char **envp)
   device_init_func, NULL, NULL)) {
 exit(1);
 }
+
+numa_post_machine_init();
+
 rom_reset_order_override();
 
 /* Did we create any drives that we failed to create a device for? */
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 03/13] i386: Return migration-safe field on query-cpu-definitions

2017-01-23 Thread Eduardo Habkost
Return the migration-safe field on query-cpu-definitions. All CPU
models in x86 are migration-safe except "host".

Signed-off-by: Eduardo Habkost 
Message-Id: <20170116181212.31565-1-ehabk...@redhat.com>
Acked-by: David Hildenbrand 
Signed-off-by: Eduardo Habkost 
---
 target/i386/cpu-qom.h | 2 ++
 target/i386/cpu.c | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/target/i386/cpu-qom.h b/target/i386/cpu-qom.h
index 7c9a07ae65..8cd607e9a2 100644
--- a/target/i386/cpu-qom.h
+++ b/target/i386/cpu-qom.h
@@ -48,6 +48,7 @@ typedef struct X86CPUDefinition X86CPUDefinition;
  * X86CPUClass:
  * @cpu_def: CPU model definition
  * @kvm_required: Whether CPU model requires KVM to be enabled.
+ * @migration_safe: See CpuDefinitionInfo::migration_safe
  * @parent_realize: The parent class' realize handler.
  * @parent_reset: The parent class' reset handler.
  *
@@ -62,6 +63,7 @@ typedef struct X86CPUClass {
 X86CPUDefinition *cpu_def;
 
 bool kvm_required;
+bool migration_safe;
 
 /* Optional description of CPU model.
  * If unavailable, cpu_def->model_id is used */
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 0e5ecb3a0f..cff23e129d 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2209,6 +2209,8 @@ static void x86_cpu_definition_entry(gpointer data, 
gpointer user_data)
 x86_cpu_class_check_missing_features(cc, >unavailable_features);
 info->has_unavailable_features = true;
 info->q_typename = g_strdup(object_class_get_name(oc));
+info->migration_safe = cc->migration_safe;
+info->has_migration_safe = true;
 
 entry = g_malloc0(sizeof(*entry));
 entry->value = info;
@@ -2356,6 +2358,7 @@ static void x86_cpu_cpudef_class_init(ObjectClass *oc, 
void *data)
 X86CPUClass *xcc = X86_CPU_CLASS(oc);
 
 xcc->cpu_def = cpudef;
+xcc->migration_safe = true;
 }
 
 static void x86_register_cpudef_type(X86CPUDefinition *def)
-- 
2.11.0.259.g40922b1




[Qemu-devel] [PULL 01/13] x86: add AVX512_VPOPCNTDQ features

2017-01-23 Thread Eduardo Habkost
From: He Chen 

AVX512_VPOPCNTDQ: Vector POPCNT instructions for word and qwords.
variable precision.

Signed-off-by: He Chen 
Message-Id: <1484272411-28073-1-git-send-email-he.c...@linux.intel.com>
Reviewed-by: Eduardo Habkost 
Signed-off-by: Eduardo Habkost 
---
 target/i386/cpu.h | 1 +
 target/i386/cpu.c | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 6c1902b36e..10c5a3538d 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -630,6 +630,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_7_0_ECX_UMIP (1U << 2)
 #define CPUID_7_0_ECX_PKU  (1U << 3)
 #define CPUID_7_0_ECX_OSPKE(1U << 4)
+#define CPUID_7_0_ECX_AVX512_VPOPCNTDQ (1U << 14) /* POPCNT for vectors of 
DW/QW */
 #define CPUID_7_0_ECX_LA57 (1U << 16)
 #define CPUID_7_0_ECX_RDPID(1U << 22)
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index aba11ae171..b6c8c5d65b 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -435,7 +435,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 NULL, "avx512vbmi", "umip", "pku",
 "ospke", NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
+NULL, NULL, "avx512-vpopcntdq", NULL,
 "la57", NULL, NULL, NULL,
 NULL, NULL, "rdpid", NULL,
 NULL, NULL, NULL, NULL,
-- 
2.11.0.259.g40922b1




Re: [Qemu-devel] [Bug 645662] Re: Python 3.1.2 math errors with Qemu 0.12.5

2017-01-23 Thread Arno Wagner
I had a brief look at softfloat. In principle, it should fix the 
issue, but only if the FPU uses 80-bit double-extended-precision
internally. I guess the qemu FPU is still stuck at 64 bit double
internally and that does not cut it for some calculations.

Just to be sure, I re-tested the code from comment 1 and it does
work as expected with a real FPU.

Regards,
Arno


On Mon, Jan 23, 2017 at 22:20:18 CET, Thomas Huth wrote:
> Looks like your test code from comment #1 still prints out a wrong
> value, so the bug has apparently not been fixed by the FPU updates...
> 
> ** Changed in: qemu
>Status: Incomplete => Triaged
> 
> -- 
> You received this bug notification because you are subscribed to the bug
> report.
> https://bugs.launchpad.net/bugs/645662
> 
> Title:
>   Python 3.1.2 math errors with Qemu 0.12.5
> 
> Status in QEMU:
>   Triaged
> 
> Bug description:
>   When doing the regression tests for Python 3.1.2 with Qemu 0.12.5, (Linux 
> version 2.6.26-2-686 (Debian 2.6.26-25lenny1)),
>   gcc (Debian 4.3.2-1.1) 4.3.2, Python compiled from sources within qemu,
>   3 math tests fail, apparently because the floating point unit is buggy. 
> Qmeu was compiled from original sources
>   on Debian Lenny with kernel  2.6.34.6 from kernel.org, gcc  (Debian 
> 4.3.2-1.1) 4.3. 
> 
>   Regression testing errors:
> 
>   test_cmath
>   test test_cmath failed -- Traceback (most recent call last):
> File "/root/tools/python3/Python-3.1.2/Lib/test/test_cmath.py", line 364, 
> in
>   self.fail(error_message)
>   AssertionError: acos0034: acos(complex(-1.0002, 0.0))
>   Expected: complex(3.141592653589793, -2.1073424255447014e-08)
>   Received: complex(3.141592653589793, -2.1073424338879928e-08)
>   Received value insufficiently close to expected value.
> 
>   
>   test_float
>   test test_float failed -- Traceback (most recent call last):
> File "/root/tools/python3/Python-3.1.2/Lib/test/test_float.py", line 479, 
> in
>   self.assertEqual(s, repr(float(s)))
>   AssertionError: '8.72293771110361e+25' != '8.722937711103609e+25'
> 
>   
>   test_math
>   test test_math failed -- multiple errors occurred; run in verbose mode for 
> deta
> 
>   =>
> 
>   runtests.sh -v test_math
> 
>   le01:~/tools/python3/Python-3.1.2# ./runtests.sh -v test_math
>   test_math BAD
>1 BAD
>0 GOOD
>0 SKIPPED
>1 total
>   le01:~/tools/python3/Python-3.1.2#
> 
> To manage notifications about this bug go to:
> https://bugs.launchpad.net/qemu/+bug/645662/+subscriptions

-- 
Arno Wagner, Dr. sc. techn., Dipl. Inform.,Email: a...@wagner.name
GnuPG: ID: CB5D9718  FP: 12D6 C03B 1B30 33BB 13CF  B774 E35C 5FA1 CB5D 9718

A good decision is based on knowledge and not on numbers. -- Plato

If it's in the news, don't worry about it.  The very definition of 
"news" is "something that hardly ever happens." -- Bruce Schneier

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

Title:
  Python 3.1.2 math errors with Qemu 0.12.5

Status in QEMU:
  Triaged

Bug description:
  When doing the regression tests for Python 3.1.2 with Qemu 0.12.5, (Linux 
version 2.6.26-2-686 (Debian 2.6.26-25lenny1)),
  gcc (Debian 4.3.2-1.1) 4.3.2, Python compiled from sources within qemu,
  3 math tests fail, apparently because the floating point unit is buggy. Qmeu 
was compiled from original sources
  on Debian Lenny with kernel  2.6.34.6 from kernel.org, gcc  (Debian 
4.3.2-1.1) 4.3. 

  Regression testing errors:

  test_cmath
  test test_cmath failed -- Traceback (most recent call last):
File "/root/tools/python3/Python-3.1.2/Lib/test/test_cmath.py", line 364, in
  self.fail(error_message)
  AssertionError: acos0034: acos(complex(-1.0002, 0.0))
  Expected: complex(3.141592653589793, -2.1073424255447014e-08)
  Received: complex(3.141592653589793, -2.1073424338879928e-08)
  Received value insufficiently close to expected value.

  
  test_float
  test test_float failed -- Traceback (most recent call last):
File "/root/tools/python3/Python-3.1.2/Lib/test/test_float.py", line 479, in
  self.assertEqual(s, repr(float(s)))
  AssertionError: '8.72293771110361e+25' != '8.722937711103609e+25'

  
  test_math
  test test_math failed -- multiple errors occurred; run in verbose mode for 
deta

  =>

  runtests.sh -v test_math

  le01:~/tools/python3/Python-3.1.2# ./runtests.sh -v test_math
  test_math BAD
   1 BAD
   0 GOOD
   0 SKIPPED
   1 total
  le01:~/tools/python3/Python-3.1.2#

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



Re: [Qemu-devel] [PATCH 1/2] niagara: fail if a firmware file is missing

2017-01-23 Thread Peter Maydell
On 23 January 2017 at 21:21, Artyom Tarasenko  wrote:
> Suggested-by: Peter Maydell 
> Signed-off-by: Artyom Tarasenko 
> ---
>  hw/sparc64/niagara.c | 22 +++---
>  1 file changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/hw/sparc64/niagara.c b/hw/sparc64/niagara.c
> index b55d4bb..e945b5a 100644
> --- a/hw/sparc64/niagara.c
> +++ b/hw/sparc64/niagara.c
> @@ -35,6 +35,7 @@
>  #include "hw/timer/sun4v-rtc.h"
>  #include "exec/address-spaces.h"
>  #include "sysemu/block-backend.h"
> +#include "qemu/error-report.h"
>
>
>  typedef struct NiagaraBoardState {
> @@ -85,6 +86,14 @@ typedef struct NiagaraBoardState {
>  #define NIAGARA_OBP_OFFSET  0x8ULL
>  #define PROM_SIZE_MAX   (4 * 1024 * 1024)
>
> +static void add_rom_or_fail(const char *file, const hwaddr addr)
> +{
> +if (rom_add_file_fixed(file, addr, -1)) {
> +error_report("Unable to load a firmware for -M niagara");
> +exit(1);

It would be nice to include the name of the file in the
error message -- or is that reported already inside
rom_add_file_fixed() somehow?

thanks
-- PMM



Re: [Qemu-devel] [PATCH 1/2] niagara: fail if a firmware file is missing

2017-01-23 Thread Peter Maydell
On 23 January 2017 at 22:17, Peter Maydell  wrote:
> On 23 January 2017 at 21:21, Artyom Tarasenko  wrote:
>> Suggested-by: Peter Maydell 
>> Signed-off-by: Artyom Tarasenko 
>> ---
>>  hw/sparc64/niagara.c | 22 +++---
>>  1 file changed, 15 insertions(+), 7 deletions(-)
>>
>> diff --git a/hw/sparc64/niagara.c b/hw/sparc64/niagara.c
>> index b55d4bb..e945b5a 100644
>> --- a/hw/sparc64/niagara.c
>> +++ b/hw/sparc64/niagara.c
>> @@ -35,6 +35,7 @@
>>  #include "hw/timer/sun4v-rtc.h"
>>  #include "exec/address-spaces.h"
>>  #include "sysemu/block-backend.h"
>> +#include "qemu/error-report.h"
>>
>>
>>  typedef struct NiagaraBoardState {
>> @@ -85,6 +86,14 @@ typedef struct NiagaraBoardState {
>>  #define NIAGARA_OBP_OFFSET  0x8ULL
>>  #define PROM_SIZE_MAX   (4 * 1024 * 1024)
>>
>> +static void add_rom_or_fail(const char *file, const hwaddr addr)
>> +{
>> +if (rom_add_file_fixed(file, addr, -1)) {
>> +error_report("Unable to load a firmware for -M niagara");
>> +exit(1);
>
> It would be nice to include the name of the file in the
> error message -- or is that reported already inside
> rom_add_file_fixed() somehow?

PS: doesn't this break 'make check' if the rom files
are missing?

thanks
-- PMM



[Qemu-devel] [PULL 7/7] nios2: Add support for Nios-II R1

2017-01-23 Thread Richard Henderson
From: Marek Vasut 

Add remaining bits of the Altera NiosII R1 support into qemu, which
is documentation, MAINTAINERS file entry, configure bits, arch_init
and configuration files for both linux-user (userland binaries) and
softmmu (hardware emulation).

Signed-off-by: Marek Vasut 
Cc: Chris Wulff 
Cc: Jeff Da Silva 
Cc: Ley Foon Tan 
Cc: Sandra Loosemore 
Cc: Yves Vandervennet 
Reviewed-by: Alexander Graf 
Message-Id: <20170118220146.489-8-ma...@denx.de>
Signed-off-by: Richard Henderson 
---
 MAINTAINERS  | 8 
 arch_init.c  | 2 ++
 configure| 5 +
 default-configs/nios2-linux-user.mak | 1 +
 default-configs/nios2-softmmu.mak| 6 ++
 include/sysemu/arch_init.h   | 1 +
 qemu-doc.texi| 3 +++
 7 files changed, 26 insertions(+)
 create mode 100644 default-configs/nios2-linux-user.mak
 create mode 100644 default-configs/nios2-softmmu.mak

diff --git a/MAINTAINERS b/MAINTAINERS
index ad10004..69047e0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -181,6 +181,14 @@ F: disas/moxie.c
 F: hw/moxie/
 F: default-configs/moxie-softmmu.mak
 
+NiosII
+M: Chris Wulff 
+M: Marek Vasut 
+S: Maintained
+F: target/nios2/
+F: hw/nios2/
+F: disas/nios2.c
+
 OpenRISC
 M: Jia Liu 
 S: Maintained
diff --git a/arch_init.c b/arch_init.c
index 6c4e287..828a271 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -63,6 +63,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_MIPS
 #elif defined(TARGET_MOXIE)
 #define QEMU_ARCH QEMU_ARCH_MOXIE
+#elif defined(TARGET_NIOS2)
+#define QEMU_ARCH QEMU_ARCH_NIOS2
 #elif defined(TARGET_OPENRISC)
 #define QEMU_ARCH QEMU_ARCH_OPENRISC
 #elif defined(TARGET_PPC)
diff --git a/configure b/configure
index 53a39ba..baacbb0 100755
--- a/configure
+++ b/configure
@@ -5933,6 +5933,8 @@ case "$target_name" in
   ;;
   moxie)
   ;;
+  nios2)
+  ;;
   or32)
 TARGET_ARCH=openrisc
 TARGET_BASE_ARCH=openrisc
@@ -6135,6 +6137,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   moxie*)
 disas_config "MOXIE"
   ;;
+  nios2)
+disas_config "NIOS2"
+  ;;
   or32)
 disas_config "OPENRISC"
   ;;
diff --git a/default-configs/nios2-linux-user.mak 
b/default-configs/nios2-linux-user.mak
new file mode 100644
index 000..5be3eb7
--- /dev/null
+++ b/default-configs/nios2-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for nios2-linux-user
diff --git a/default-configs/nios2-softmmu.mak 
b/default-configs/nios2-softmmu.mak
new file mode 100644
index 000..74dc70c
--- /dev/null
+++ b/default-configs/nios2-softmmu.mak
@@ -0,0 +1,6 @@
+# Default configuration for nios2-softmmu
+
+CONFIG_NIOS2=y
+CONFIG_SERIAL=y
+CONFIG_PTIMER=y
+CONFIG_ALTERA_TIMER=y
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 20b01e3..2bf16b2 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -23,6 +23,7 @@ enum {
 QEMU_ARCH_UNICORE32 = (1 << 14),
 QEMU_ARCH_MOXIE = (1 << 15),
 QEMU_ARCH_TRICORE = (1 << 16),
+QEMU_ARCH_NIOS2 = (1 << 17),
 };
 
 extern const uint32_t arch_type;
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 0b2746f..fe7b69b 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2901,6 +2901,9 @@ The binary format is detected automatically.
 @command{qemu-mips} TODO.
 @command{qemu-mipsel} TODO.
 
+@cindex user mode (NiosII)
+@command{qemu-nios2} TODO.
+
 @cindex user mode (PowerPC)
 @command{qemu-ppc64abi32} TODO.
 @command{qemu-ppc64} TODO.
-- 
2.9.3




[Qemu-devel] [PULL 2/7] nios2: Add disas entries

2017-01-23 Thread Richard Henderson
From: Marek Vasut 

Add nios2 disassembler support. This patch is composed from binutils files
from commit "Opcodes and assembler support for Nios II R2". The files from
binutils used in this patch are:

include/opcode/nios2.h
include/opcode/nios2r1.h
include/opcode/nios2r2.h
opcodes/nios2-opc.c
opcodes/nios2-dis.c

Checkpatch says total: 114 errors, 0 warnings, 3609 lines checked , which
is caused by a different coding style in those files. These warnings and
errors are not addressed To let these files be easily synchronized between
binutils and qemu.

Signed-off-by: Marek Vasut 
Cc: Chris Wulff 
Cc: Jeff Da Silva 
Cc: Ley Foon Tan 
Cc: Sandra Loosemore 
Cc: Yves Vandervennet 
Reviewed-by: Alexander Graf 
Message-Id: <20170118220146.489-2-ma...@denx.de>
Signed-off-by: Richard Henderson 
---
 disas/Makefile.objs |1 +
 disas/nios2.c   | 3534 +++
 include/disas/bfd.h |6 +
 3 files changed, 3541 insertions(+)
 create mode 100644 disas/nios2.c

diff --git a/disas/Makefile.objs b/disas/Makefile.objs
index 09bc992..ac79d16 100644
--- a/disas/Makefile.objs
+++ b/disas/Makefile.objs
@@ -14,6 +14,7 @@ common-obj-$(CONFIG_IA64_DIS) += ia64.o
 common-obj-$(CONFIG_M68K_DIS) += m68k.o
 common-obj-$(CONFIG_MICROBLAZE_DIS) += microblaze.o
 common-obj-$(CONFIG_MIPS_DIS) += mips.o
+common-obj-$(CONFIG_NIOS2_DIS) += nios2.o
 common-obj-$(CONFIG_MOXIE_DIS) += moxie.o
 common-obj-$(CONFIG_PPC_DIS) += ppc.o
 common-obj-$(CONFIG_S390_DIS) += s390.o
diff --git a/disas/nios2.c b/disas/nios2.c
new file mode 100644
index 000..b342936
--- /dev/null
+++ b/disas/nios2.c
@@ -0,0 +1,3534 @@
+/* Nios II opcode library for QEMU.
+   Copyright (C) 2012-2016 Free Software Foundation, Inc.
+   Contributed by Nigel Gray (ng...@altera.com).
+   Contributed by Mentor Graphics, Inc.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; either version 2
+   of the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA  02110-1301, USA.  */
+
+/* This file resembles a concatenation of the following files from
+   binutils:
+
+   include/opcode/nios2.h
+   include/opcode/nios2r1.h
+   include/opcode/nios2r2.h
+   opcodes/nios2-opc.c
+   opcodes/nios2-dis.c
+
+   It has been derived from the original patches which have been
+   relicensed by the contributors as GPL version 2 for inclusion
+   in QEMU.  */
+
+#ifndef _NIOS2_H_
+#define _NIOS2_H_
+
+/*#include "bfd.h"*/
+#include "qemu/osdep.h"
+#include "disas/bfd.h"
+
+
+/
+ * This file contains structures, bit masks and shift counts used
+ * by the GNU toolchain to define the Nios II instruction set and
+ * access various opcode fields.
+ /
+
+/* Instruction encoding formats.  */
+enum iw_format_type {
+  /* R1 formats.  */
+  iw_i_type,
+  iw_r_type,
+  iw_j_type,
+  iw_custom_type,
+
+  /* 32-bit R2 formats.  */
+  iw_L26_type,
+  iw_F2I16_type,
+  iw_F2X4I12_type,
+  iw_F1X4I12_type,
+  iw_F1X4L17_type,
+  iw_F3X6L5_type,
+  iw_F2X6L10_type,
+  iw_F3X6_type,
+  iw_F3X8_type,
+
+  /* 16-bit R2 formats.  */
+  iw_I10_type,
+  iw_T1I7_type,
+  iw_T2I4_type,
+  iw_T1X1I6_type,
+  iw_X1I7_type,
+  iw_L5I4X1_type,
+  iw_T2X1L3_type,
+  iw_T2X1I3_type,
+  iw_T3X1_type,
+  iw_T2X3_type,
+  iw_F1X1_type,
+  iw_X2L5_type,
+  iw_F1I5_type,
+  iw_F2_type
+};
+
+/* Identify different overflow situations for error messages.  */
+enum overflow_type
+{
+  call_target_overflow = 0,
+  branch_target_overflow,
+  address_offset_overflow,
+  signed_immed16_overflow,
+  unsigned_immed16_overflow,
+  unsigned_immed5_overflow,
+  signed_immed12_overflow,
+  custom_opcode_overflow,
+  enumeration_overflow,
+  no_overflow
+};
+
+/* This structure holds information for a particular instruction. 
+
+   The args field is a string describing the operands.  The following
+   letters can appear in the args:
+ c - a 5-bit control register index
+ d - a 5-bit destination register index
+ s - a 5-bit left source register index
+ t - a 5-bit right source register index
+ D - a 3-bit encoded destination register
+ S - a 3-bit encoded left 

[Qemu-devel] [PULL 5/7] nios2: Add periodic timer emulation

2017-01-23 Thread Richard Henderson
From: Chris Wulff 

Add the Altera timer model.

Signed-off-by: Marek Vasut 
Cc: Chris Wulff 
Cc: Jeff Da Silva 
Cc: Ley Foon Tan 
Cc: Sandra Loosemore 
Cc: Yves Vandervennet 
Reviewed-by: Alexander Graf 
Message-Id: <20170118220146.489-6-ma...@denx.de>
Signed-off-by: Richard Henderson 
---
 hw/timer/Makefile.objs  |   1 +
 hw/timer/altera_timer.c | 237 
 2 files changed, 238 insertions(+)
 create mode 100644 hw/timer/altera_timer.c

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index c1e93a3..71994f2 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -18,6 +18,7 @@ common-obj-$(CONFIG_IMX) += imx_gpt.o
 common-obj-$(CONFIG_LM32) += lm32_timer.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o
 
+obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_mct.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_pwm.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
diff --git a/hw/timer/altera_timer.c b/hw/timer/altera_timer.c
new file mode 100644
index 000..6d48626
--- /dev/null
+++ b/hw/timer/altera_timer.c
@@ -0,0 +1,237 @@
+/*
+ * QEMU model of the Altera timer.
+ *
+ * Copyright (c) 2012 Chris Wulff 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
+
+#include "hw/sysbus.h"
+#include "sysemu/sysemu.h"
+#include "hw/ptimer.h"
+
+#define R_STATUS  0
+#define R_CONTROL 1
+#define R_PERIODL 2
+#define R_PERIODH 3
+#define R_SNAPL   4
+#define R_SNAPH   5
+#define R_MAX 6
+
+#define STATUS_TO 0x0001
+#define STATUS_RUN0x0002
+
+#define CONTROL_ITO   0x0001
+#define CONTROL_CONT  0x0002
+#define CONTROL_START 0x0004
+#define CONTROL_STOP  0x0008
+
+#define TYPE_ALTERA_TIMER "ALTR.timer"
+#define ALTERA_TIMER(obj) \
+OBJECT_CHECK(AlteraTimer, (obj), TYPE_ALTERA_TIMER)
+
+typedef struct AlteraTimer {
+SysBusDevice  busdev;
+MemoryRegion  mmio;
+qemu_irq  irq;
+uint32_t  freq_hz;
+QEMUBH   *bh;
+ptimer_state *ptimer;
+uint32_t  regs[R_MAX];
+} AlteraTimer;
+
+static int timer_irq_state(AlteraTimer *t)
+{
+bool irq = (t->regs[R_STATUS] & STATUS_TO) &&
+   (t->regs[R_CONTROL] & CONTROL_ITO);
+return irq;
+}
+
+static uint64_t timer_read(void *opaque, hwaddr addr,
+   unsigned int size)
+{
+AlteraTimer *t = opaque;
+uint64_t r = 0;
+
+addr >>= 2;
+
+switch (addr) {
+case R_CONTROL:
+r = t->regs[R_CONTROL] & (CONTROL_ITO | CONTROL_CONT);
+break;
+
+default:
+if (addr < ARRAY_SIZE(t->regs)) {
+r = t->regs[addr];
+}
+break;
+}
+
+return r;
+}
+
+static void timer_write(void *opaque, hwaddr addr,
+uint64_t value, unsigned int size)
+{
+AlteraTimer *t = opaque;
+uint64_t tvalue;
+uint32_t count = 0;
+int irqState = timer_irq_state(t);
+
+addr >>= 2;
+
+switch (addr) {
+case R_STATUS:
+/* The timeout bit is cleared by writing the status register. */
+t->regs[R_STATUS] &= ~STATUS_TO;
+break;
+
+case R_CONTROL:
+t->regs[R_CONTROL] = value & (CONTROL_ITO | CONTROL_CONT);
+if ((value & CONTROL_START) &&
+!(t->regs[R_STATUS] & STATUS_RUN)) {
+ptimer_run(t->ptimer, 1);
+t->regs[R_STATUS] |= STATUS_RUN;
+}
+if ((value & CONTROL_STOP) && (t->regs[R_STATUS] & STATUS_RUN)) {
+ptimer_stop(t->ptimer);
+t->regs[R_STATUS] &= ~STATUS_RUN;
+}
+break;
+
+case R_PERIODL:
+case R_PERIODH:
+t->regs[addr] = value & 0x;
+if (t->regs[R_STATUS] & STATUS_RUN) {
+ptimer_stop(t->ptimer);
+t->regs[R_STATUS] &= ~STATUS_RUN;
+}
+tvalue = (t->regs[R_PERIODH] << 16) | t->regs[R_PERIODL];
+ptimer_set_limit(t->ptimer, tvalue + 1, 1);
+break;
+
+case R_SNAPL:
+case R_SNAPH:
+count = ptimer_get_count(t->ptimer);
+t->regs[R_SNAPL] = count & 0x;
+

[Qemu-devel] [PULL 6/7] nios2: Add Altera 10M50 GHRD emulation

2017-01-23 Thread Richard Henderson
From: Marek Vasut 

Add the Altera 10M50 Nios2 GHRD model. This allows emulating the
10M50 development kit with the Nios2 GHRD loaded in the FPGA. It
is possible to boot Linux kernel and run userspace, thus far only
from initrd as storage support is not yet implemented.

Signed-off-by: Marek Vasut 
Cc: Chris Wulff 
Cc: Jeff Da Silva 
Cc: Ley Foon Tan 
Cc: Sandra Loosemore 
Cc: Yves Vandervennet 
Reviewed-by: Alexander Graf 
Message-Id: <20170118220146.489-7-ma...@denx.de>
Signed-off-by: Richard Henderson 
---
 hw/nios2/10m50_devboard.c | 126 ++
 hw/nios2/Makefile.objs|   1 +
 hw/nios2/boot.c   | 223 ++
 hw/nios2/boot.h   |  11 +++
 hw/nios2/cpu_pic.c|  70 +++
 5 files changed, 431 insertions(+)
 create mode 100644 hw/nios2/10m50_devboard.c
 create mode 100644 hw/nios2/Makefile.objs
 create mode 100644 hw/nios2/boot.c
 create mode 100644 hw/nios2/boot.h
 create mode 100644 hw/nios2/cpu_pic.c

diff --git a/hw/nios2/10m50_devboard.c b/hw/nios2/10m50_devboard.c
new file mode 100644
index 000..62e5738
--- /dev/null
+++ b/hw/nios2/10m50_devboard.c
@@ -0,0 +1,126 @@
+/*
+ * Altera 10M50 Nios2 GHRD
+ *
+ * Copyright (c) 2016 Marek Vasut 
+ *
+ * Based on LabX device code
+ *
+ * Copyright (c) 2012 Chris Wulff 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+
+#include "hw/sysbus.h"
+#include "hw/hw.h"
+#include "hw/char/serial.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
+#include "qemu/config-file.h"
+
+#include "boot.h"
+
+#define BINARY_DEVICE_TREE_FILE"10m50-devboard.dtb"
+
+static void nios2_10m50_ghrd_init(MachineState *machine)
+{
+Nios2CPU *cpu;
+DeviceState *dev;
+MemoryRegion *address_space_mem = get_system_memory();
+MemoryRegion *phys_tcm = g_new(MemoryRegion, 1);
+MemoryRegion *phys_tcm_alias = g_new(MemoryRegion, 1);
+MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
+MemoryRegion *phys_ram_alias = g_new(MemoryRegion, 1);
+ram_addr_t tcm_base = 0x0;
+ram_addr_t tcm_size = 0x1000;/* 1 kiB, but QEMU limit is 4 kiB */
+ram_addr_t ram_base = 0x0800;
+ram_addr_t ram_size = 0x0800;
+qemu_irq *cpu_irq, irq[32];
+int i;
+
+/* Physical TCM (tb_ram_1k) with alias at 0xc000 */
+memory_region_init_ram(phys_tcm, NULL, "nios2.tcm", tcm_size, 
_abort);
+memory_region_init_alias(phys_tcm_alias, NULL, "nios2.tcm.alias",
+ phys_tcm, 0, tcm_size);
+vmstate_register_ram_global(phys_tcm);
+memory_region_add_subregion(address_space_mem, tcm_base, phys_tcm);
+memory_region_add_subregion(address_space_mem, 0xc000 + tcm_base,
+phys_tcm_alias);
+
+/* Physical DRAM with alias at 0xc000 */
+memory_region_init_ram(phys_ram, NULL, "nios2.ram", ram_size, 
_abort);
+memory_region_init_alias(phys_ram_alias, NULL, "nios2.ram.alias",
+ phys_ram, 0, ram_size);
+vmstate_register_ram_global(phys_ram);
+memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
+memory_region_add_subregion(address_space_mem, 0xc000 + ram_base,
+phys_ram_alias);
+
+/* Create CPU -- FIXME */
+cpu = cpu_nios2_init("nios2");
+
+/* Register: CPU interrupt controller (PIC) */
+cpu_irq = nios2_cpu_pic_init(cpu);
+
+/* Register: Internal Interrupt Controller (IIC) */
+dev = qdev_create(NULL, "altera,iic");
+qdev_prop_set_ptr(dev, "cpu", cpu);
+qdev_init_nofail(dev);
+sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, cpu_irq[0]);
+for (i = 0; i < 32; i++) {
+irq[i] = qdev_get_gpio_in(dev, i);
+}
+
+/* Register: Altera 16550 UART */
+serial_mm_init(address_space_mem, 0xf8001600, 2, irq[1], 115200,
+   serial_hds[0], DEVICE_NATIVE_ENDIAN);
+
+/* Register: Timer sys_clk_timer  */
+dev = qdev_create(NULL, 

[Qemu-devel] [PULL 4/7] nios2: Add IIC interrupt controller emulation

2017-01-23 Thread Richard Henderson
From: Chris Wulff 

Add the Altera Nios2 internal interrupt controller model.

Signed-off-by: Marek Vasut 
Cc: Chris Wulff 
Cc: Jeff Da Silva 
Cc: Ley Foon Tan 
Cc: Sandra Loosemore 
Cc: Yves Vandervennet 
Reviewed-by: Alexander Graf 
Message-Id: <20170118220146.489-5-ma...@denx.de>
Signed-off-by: Richard Henderson 
---
 hw/intc/Makefile.objs |   1 +
 hw/intc/nios2_iic.c   | 103 ++
 2 files changed, 104 insertions(+)
 create mode 100644 hw/intc/nios2_iic.c

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 2f44a2d..8948106 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -41,3 +41,4 @@ obj-$(CONFIG_S390_FLIC_KVM) += s390_flic_kvm.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_vic.o
 obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpuif.o
 obj-$(CONFIG_MIPS_CPS) += mips_gic.o
+obj-$(CONFIG_NIOS2) += nios2_iic.o
diff --git a/hw/intc/nios2_iic.c b/hw/intc/nios2_iic.c
new file mode 100644
index 000..818ab1b
--- /dev/null
+++ b/hw/intc/nios2_iic.c
@@ -0,0 +1,103 @@
+/*
+ * QEMU Altera Internal Interrupt Controller.
+ *
+ * Copyright (c) 2012 Chris Wulff 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
+
+#include "hw/sysbus.h"
+#include "cpu.h"
+
+#define TYPE_ALTERA_IIC "altera,iic"
+#define ALTERA_IIC(obj) \
+OBJECT_CHECK(AlteraIIC, (obj), TYPE_ALTERA_IIC)
+
+typedef struct AlteraIIC {
+SysBusDevice  parent_obj;
+void *cpu;
+qemu_irq  parent_irq;
+} AlteraIIC;
+
+static void update_irq(AlteraIIC *pv)
+{
+CPUNios2State *env = &((Nios2CPU *)(pv->cpu))->env;
+
+qemu_set_irq(pv->parent_irq,
+ env->regs[CR_IPENDING] & env->regs[CR_IENABLE]);
+}
+
+static void irq_handler(void *opaque, int irq, int level)
+{
+AlteraIIC *pv = opaque;
+CPUNios2State *env = &((Nios2CPU *)(pv->cpu))->env;
+
+env->regs[CR_IPENDING] &= ~(1 << irq);
+env->regs[CR_IPENDING] |= !!level << irq;
+
+update_irq(pv);
+}
+
+static void altera_iic_init(Object *obj)
+{
+AlteraIIC *pv = ALTERA_IIC(obj);
+
+qdev_init_gpio_in(DEVICE(pv), irq_handler, 32);
+sysbus_init_irq(SYS_BUS_DEVICE(obj), >parent_irq);
+}
+
+static Property altera_iic_properties[] = {
+DEFINE_PROP_PTR("cpu", AlteraIIC, cpu),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void altera_iic_realize(DeviceState *dev, Error **errp)
+{
+struct AlteraIIC *pv = ALTERA_IIC(dev);
+
+if (!pv->cpu) {
+error_setg(errp, "altera,iic: CPU not connected");
+return;
+}
+}
+
+static void altera_iic_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->props = altera_iic_properties;
+/* Reason: pointer property "cpu" */
+dc->cannot_instantiate_with_device_add_yet = true;
+dc->realize = altera_iic_realize;
+}
+
+static TypeInfo altera_iic_info = {
+.name  = "altera,iic",
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(AlteraIIC),
+.instance_init = altera_iic_init,
+.class_init= altera_iic_class_init,
+};
+
+static void altera_iic_register(void)
+{
+type_register_static(_iic_info);
+}
+
+type_init(altera_iic_register)
-- 
2.9.3




[Qemu-devel] [PULL 3/7] nios2: Add usermode binaries emulation

2017-01-23 Thread Richard Henderson
From: Marek Vasut 

Add missing bits for qemu-user required for emulating Altera Nios2
userspace binaries.

Signed-off-by: Marek Vasut 
Cc: Chris Wulff 
Cc: Jeff Da Silva 
Cc: Ley Foon Tan 
Cc: Sandra Loosemore 
Cc: Yves Vandervennet 
Reviewed-by: Alexander Graf 
Message-Id: <20170118220146.489-4-ma...@denx.de>
Signed-off-by: Richard Henderson 
---
 include/elf.h |   2 +
 linux-user/elfload.c  |  57 +++
 linux-user/main.c | 140 +++-
 linux-user/nios2/syscall_nr.h | 329 ++
 linux-user/nios2/target_cpu.h |  39 +
 linux-user/nios2/target_signal.h  |  26 +++
 linux-user/nios2/target_structs.h |  58 +++
 linux-user/nios2/target_syscall.h |  37 +
 linux-user/nios2/termbits.h   | 220 +
 linux-user/signal.c   | 238 ++-
 linux-user/syscall_defs.h |   8 +-
 11 files changed, 1147 insertions(+), 7 deletions(-)
 create mode 100644 linux-user/nios2/syscall_nr.h
 create mode 100644 linux-user/nios2/target_cpu.h
 create mode 100644 linux-user/nios2/target_signal.h
 create mode 100644 linux-user/nios2/target_structs.h
 create mode 100644 linux-user/nios2/target_syscall.h
 create mode 100644 linux-user/nios2/termbits.h

diff --git a/include/elf.h b/include/elf.h
index 1c2975d..0dbd3e9 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -126,6 +126,8 @@ typedef int64_t  Elf64_Sxword;
  */
 #define EM_S390_OLD 0xA390
 
+#define EM_ALTERA_NIOS2 113 /* Altera Nios II soft-core processor */
+
 #define EM_MICROBLAZE  189
 #define EM_MICROBLAZE_OLD  0xBAAB
 
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 547053c..17f7766 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -967,6 +967,63 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, 
const CPUMBState *env
 
 #endif /* TARGET_MICROBLAZE */
 
+#ifdef TARGET_NIOS2
+
+#define ELF_START_MMAP 0x8000
+
+#define elf_check_arch(x) ((x) == EM_ALTERA_NIOS2)
+
+#define ELF_CLASS   ELFCLASS32
+#define ELF_ARCHEM_ALTERA_NIOS2
+
+static void init_thread(struct target_pt_regs *regs, struct image_info *infop)
+{
+regs->ea = infop->entry;
+regs->sp = infop->start_stack;
+regs->estatus = 0x3;
+}
+
+#define ELF_EXEC_PAGESIZE4096
+
+#define USE_ELF_CORE_DUMP
+#define ELF_NREG 49
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
+
+/* See linux kernel: arch/mips/kernel/process.c:elf_dump_regs.  */
+static void elf_core_copy_regs(target_elf_gregset_t *regs,
+   const CPUNios2State *env)
+{
+int i;
+
+(*regs)[0] = -1;
+for (i = 1; i < 8; i++)/* r0-r7 */
+(*regs)[i] = tswapreg(env->regs[i + 7]);
+
+for (i = 8; i < 16; i++)   /* r8-r15 */
+(*regs)[i] = tswapreg(env->regs[i - 8]);
+
+for (i = 16; i < 24; i++)  /* r16-r23 */
+(*regs)[i] = tswapreg(env->regs[i + 7]);
+(*regs)[24] = -1;/* R_ET */
+(*regs)[25] = -1;/* R_BT */
+(*regs)[26] = tswapreg(env->regs[R_GP]);
+(*regs)[27] = tswapreg(env->regs[R_SP]);
+(*regs)[28] = tswapreg(env->regs[R_FP]);
+(*regs)[29] = tswapreg(env->regs[R_EA]);
+(*regs)[30] = -1;/* R_SSTATUS */
+(*regs)[31] = tswapreg(env->regs[R_RA]);
+
+(*regs)[32] = tswapreg(env->regs[R_PC]);
+
+(*regs)[33] = -1; /* R_STATUS */
+(*regs)[34] = tswapreg(env->regs[CR_ESTATUS]);
+
+for (i = 35; i < 49; i++)/* ... */
+(*regs)[i] = -1;
+}
+
+#endif /* TARGET_NIOS2 */
+
 #ifdef TARGET_OPENRISC
 
 #define ELF_START_MMAP 0x0800
diff --git a/linux-user/main.c b/linux-user/main.c
index 94a636f..90ef97c 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -68,8 +68,11 @@ do { 
   \
  * This way we will never overlap with our own libraries or binaries or stack
  * or anything else that QEMU maps.
  */
-# ifdef TARGET_MIPS
-/* MIPS only supports 31 bits of virtual address space for user space */
+# if defined(TARGET_MIPS) || defined(TARGET_NIOS2)
+/*
+ * MIPS only supports 31 bits of virtual address space for user space.
+ * Nios2 also only supports 31 bits.
+ */
 unsigned long reserved_va = 0x7700;
 # else
 unsigned long reserved_va = 0xf700;
@@ -2462,6 +2465,109 @@ error:
 }
 #endif
 
+#ifdef TARGET_NIOS2
+
+void cpu_loop(CPUNios2State *env)
+{
+CPUState *cs = ENV_GET_CPU(env);
+Nios2CPU *cpu = NIOS2_CPU(cs);
+target_siginfo_t info;
+int trapnr, gdbsig, ret;
+
+for (;;) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+gdbsig = 0;
+
+switch (trapnr) {
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+

[Qemu-devel] [PULL 1/7] nios2: Add architecture emulation support

2017-01-23 Thread Richard Henderson
From: Chris Wulff 

Add support for emulating Altera NiosII R1 architecture into qemu.
This patch is based on previous work by Chris Wulff from 2012 and
updated to latest mainline QEMU.

Signed-off-by: Marek Vasut 
Cc: Chris Wulff 
Cc: Jeff Da Silva 
Cc: Ley Foon Tan 
Cc: Sandra Loosemore 
Cc: Yves Vandervennet 
Cc: Alexander Graf 
Message-Id: <20170118220146.489-3-ma...@denx.de>
[rth: Remove tlb_flush from nios2_cpu_reset.]
Signed-off-by: Richard Henderson 
---
 target/nios2/Makefile.objs |   4 +
 target/nios2/cpu.c | 237 +++
 target/nios2/cpu.h | 272 +
 target/nios2/helper.c  | 313 +++
 target/nios2/helper.h  |  27 ++
 target/nios2/mmu.c | 296 ++
 target/nios2/mmu.h |  50 +++
 target/nios2/monitor.c |  35 ++
 target/nios2/op_helper.c   |  47 +++
 target/nios2/translate.c   | 958 +
 10 files changed, 2239 insertions(+)
 create mode 100644 target/nios2/Makefile.objs
 create mode 100644 target/nios2/cpu.c
 create mode 100644 target/nios2/cpu.h
 create mode 100644 target/nios2/helper.c
 create mode 100644 target/nios2/helper.h
 create mode 100644 target/nios2/mmu.c
 create mode 100644 target/nios2/mmu.h
 create mode 100644 target/nios2/monitor.c
 create mode 100644 target/nios2/op_helper.c
 create mode 100644 target/nios2/translate.c

diff --git a/target/nios2/Makefile.objs b/target/nios2/Makefile.objs
new file mode 100644
index 000..2a11c5c
--- /dev/null
+++ b/target/nios2/Makefile.objs
@@ -0,0 +1,4 @@
+obj-y += translate.o op_helper.o helper.o cpu.o mmu.o
+obj-$(CONFIG_SOFTMMU) += monitor.o
+
+$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
new file mode 100644
index 000..d56bb72
--- /dev/null
+++ b/target/nios2/cpu.c
@@ -0,0 +1,237 @@
+/*
+ * QEMU Nios II CPU
+ *
+ * Copyright (c) 2012 Chris Wulff 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "exec/log.h"
+#include "exec/gdbstub.h"
+#include "hw/qdev-properties.h"
+
+static void nios2_cpu_set_pc(CPUState *cs, vaddr value)
+{
+Nios2CPU *cpu = NIOS2_CPU(cs);
+CPUNios2State *env = >env;
+
+env->regs[R_PC] = value;
+}
+
+static bool nios2_cpu_has_work(CPUState *cs)
+{
+return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
+}
+
+/* CPUClass::reset() */
+static void nios2_cpu_reset(CPUState *cs)
+{
+Nios2CPU *cpu = NIOS2_CPU(cs);
+Nios2CPUClass *ncc = NIOS2_CPU_GET_CLASS(cpu);
+CPUNios2State *env = >env;
+
+if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+qemu_log("CPU Reset (CPU %d)\n", cs->cpu_index);
+log_cpu_state(cs, 0);
+}
+
+ncc->parent_reset(cs);
+
+memset(env->regs, 0, sizeof(uint32_t) * NUM_CORE_REGS);
+env->regs[R_PC] = cpu->reset_addr;
+
+#if defined(CONFIG_USER_ONLY)
+/* Start in user mode with interrupts enabled. */
+env->regs[CR_STATUS] = CR_STATUS_U | CR_STATUS_PIE;
+#else
+env->regs[CR_STATUS] = 0;
+#endif
+}
+
+static void nios2_cpu_initfn(Object *obj)
+{
+CPUState *cs = CPU(obj);
+Nios2CPU *cpu = NIOS2_CPU(obj);
+CPUNios2State *env = >env;
+static bool tcg_initialized;
+
+cs->env_ptr = env;
+
+#if !defined(CONFIG_USER_ONLY)
+mmu_init(env);
+#endif
+
+if (tcg_enabled() && !tcg_initialized) {
+tcg_initialized = true;
+nios2_tcg_init();
+}
+}
+
+Nios2CPU *cpu_nios2_init(const char *cpu_model)
+{
+Nios2CPU *cpu = NIOS2_CPU(object_new(TYPE_NIOS2_CPU));
+
+object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
+
+return cpu;
+}
+
+static void nios2_cpu_realizefn(DeviceState *dev, Error **errp)
+{
+CPUState *cs = CPU(dev);
+Nios2CPUClass *ncc = NIOS2_CPU_GET_CLASS(dev);
+Error *local_err = NULL;
+
+cpu_exec_realizefn(cs, _err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
+return;
+}
+
+qemu_init_vcpu(cs);
+cpu_reset(cs);
+
+ncc->parent_realize(dev, errp);
+}
+
+static bool 

[Qemu-devel] [PULL 0/7] Nios2 architecture support

2017-01-23 Thread Richard Henderson
This is me acking this new target.  Hopefully Chris and/or Marek
will be able to get some gpg keys signed relatively soon.

I had to make one change for the target, updating to rely on the
common tlb_flush during reset.


r~


The following changes since commit 3879284d6517dc22529395bdb259f4183b589127:

  Merge remote-tracking branch 'remotes/berrange/tags/pull-qio-2017-01-23-2' 
into staging (2017-01-23 15:59:09 +)

are available in the git repository at:

  git://github.com/rth7680/qemu.git tags/pull-nios-20170123

for you to fetch changes up to 9a6aa7cc59b7ff0535392241e19c73cde146c506:

  nios2: Add support for Nios-II R1 (2017-01-23 13:54:58 -0800)


nios2 target support


Chris Wulff (3):
  nios2: Add architecture emulation support
  nios2: Add IIC interrupt controller emulation
  nios2: Add periodic timer emulation

Marek Vasut (4):
  nios2: Add disas entries
  nios2: Add usermode binaries emulation
  nios2: Add Altera 10M50 GHRD emulation
  nios2: Add support for Nios-II R1

 MAINTAINERS  |8 +
 arch_init.c  |2 +
 configure|5 +
 default-configs/nios2-linux-user.mak |1 +
 default-configs/nios2-softmmu.mak|6 +
 disas/Makefile.objs  |1 +
 disas/nios2.c| 3534 ++
 hw/intc/Makefile.objs|1 +
 hw/intc/nios2_iic.c  |  103 +
 hw/nios2/10m50_devboard.c|  126 ++
 hw/nios2/Makefile.objs   |1 +
 hw/nios2/boot.c  |  223 +++
 hw/nios2/boot.h  |   11 +
 hw/nios2/cpu_pic.c   |   70 +
 hw/timer/Makefile.objs   |1 +
 hw/timer/altera_timer.c  |  237 +++
 include/disas/bfd.h  |6 +
 include/elf.h|2 +
 include/sysemu/arch_init.h   |1 +
 linux-user/elfload.c |   57 +
 linux-user/main.c|  140 +-
 linux-user/nios2/syscall_nr.h|  329 
 linux-user/nios2/target_cpu.h|   39 +
 linux-user/nios2/target_signal.h |   26 +
 linux-user/nios2/target_structs.h|   58 +
 linux-user/nios2/target_syscall.h|   37 +
 linux-user/nios2/termbits.h  |  220 +++
 linux-user/signal.c  |  238 ++-
 linux-user/syscall_defs.h|8 +-
 qemu-doc.texi|3 +
 target/nios2/Makefile.objs   |4 +
 target/nios2/cpu.c   |  237 +++
 target/nios2/cpu.h   |  272 +++
 target/nios2/helper.c|  313 +++
 target/nios2/helper.h|   27 +
 target/nios2/mmu.c   |  296 +++
 target/nios2/mmu.h   |   50 +
 target/nios2/monitor.c   |   35 +
 target/nios2/op_helper.c |   47 +
 target/nios2/translate.c |  958 +
 40 files changed, 7726 insertions(+), 7 deletions(-)
 create mode 100644 default-configs/nios2-linux-user.mak
 create mode 100644 default-configs/nios2-softmmu.mak
 create mode 100644 disas/nios2.c
 create mode 100644 hw/intc/nios2_iic.c
 create mode 100644 hw/nios2/10m50_devboard.c
 create mode 100644 hw/nios2/Makefile.objs
 create mode 100644 hw/nios2/boot.c
 create mode 100644 hw/nios2/boot.h
 create mode 100644 hw/nios2/cpu_pic.c
 create mode 100644 hw/timer/altera_timer.c
 create mode 100644 linux-user/nios2/syscall_nr.h
 create mode 100644 linux-user/nios2/target_cpu.h
 create mode 100644 linux-user/nios2/target_signal.h
 create mode 100644 linux-user/nios2/target_structs.h
 create mode 100644 linux-user/nios2/target_syscall.h
 create mode 100644 linux-user/nios2/termbits.h
 create mode 100644 target/nios2/Makefile.objs
 create mode 100644 target/nios2/cpu.c
 create mode 100644 target/nios2/cpu.h
 create mode 100644 target/nios2/helper.c
 create mode 100644 target/nios2/helper.h
 create mode 100644 target/nios2/mmu.c
 create mode 100644 target/nios2/mmu.h
 create mode 100644 target/nios2/monitor.c
 create mode 100644 target/nios2/op_helper.c
 create mode 100644 target/nios2/translate.c



Re: [Qemu-devel] [PATCH 00/17] multifd v3

2017-01-23 Thread no-reply
Hi,

Your series seems to have some coding style problems. See output below for
more information:

Type: series
Subject: [Qemu-devel] [PATCH 00/17] multifd v3
Message-id: 1485207141-1941-1-git-send-email-quint...@redhat.com

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
977ae47 migration: flush receive queue
94cd0ed migration: [HACK]Transfer pages over new channels
403e546 migration: Test new fd infrastructure
1b26e24 migration: Create thread infrastructure for multifd recv side
20ead0e migration: Send the fd number which we are going to use for this page
24b9a1c migration: really use multiple pages at a time
d97ec5e migration: Create thread infrastructure for multifd send side
b2952e8 migration: create ram_multifd_page
62325d2 migration: Start of multiple fd work
8734a27 migration: create multifd migration threads
7723249 migration: Create x-multifd-group parameter
9b1abf5 migration: Create x-multifd-threads parameter
d9ec656 migration: Add multifd capability
bb058af migration: Don't create decompression threads if not enabled
3bb5588 migration: Test for disabled features on reception
cefb07a migration: create Migration Incoming State at init time
ce46b29 migration: transform remained DPRINTF into trace_

=== OUTPUT BEGIN ===
Checking PATCH 1/17: migration: transform remained DPRINTF into trace_...
Checking PATCH 2/17: migration: create Migration Incoming State at init time...
Checking PATCH 3/17: migration: Test for disabled features on reception...
Checking PATCH 4/17: migration: Don't create decompression threads if not 
enabled...
Checking PATCH 5/17: migration: Add multifd capability...
Checking PATCH 6/17: migration: Create x-multifd-threads parameter...
WARNING: line over 80 characters
#93: FILE: migration/migration.c:862:
+(params->x_multifd_threads < 1 || params->x_multifd_threads > 
255)) {

total: 0 errors, 1 warnings, 130 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 7/17: migration: Create x-multifd-group parameter...
Checking PATCH 8/17: migration: create multifd migration threads...
ERROR: space required before the open brace '{'
#104: FILE: migration/ram.c:402:
+while (!params->quit){

ERROR: trailing whitespace
#177: FILE: migration/ram.c:475:
+ $

ERROR: space required before the open brace '{'
#179: FILE: migration/ram.c:477:
+while (!params->quit){

total: 3 errors, 0 warnings, 208 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 9/17: migration: Start of multiple fd work...
ERROR: space required before the open parenthesis '('
#83: FILE: migration/ram.c:467:
+if(!multifd_send[i].c) {

ERROR: space required before the open parenthesis '('
#140: FILE: migration/ram.c:563:
+if(!multifd_recv[i].c) {

ERROR: do not use C99 // comments
#186: FILE: migration/socket.c:50:
+// Remove channel

ERROR: do not use C99 // comments
#203: FILE: migration/socket.c:67:
+// Remove channel

ERROR: do not use C99 // comments
#238: FILE: migration/socket.c:209:
+//qio_channel_close(ioc, NULL);

total: 5 errors, 0 warnings, 209 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 10/17: migration: create ram_multifd_page...
Checking PATCH 11/17: migration: Create thread infrastructure for multifd send 
side...
Checking PATCH 12/17: migration: really use multiple pages at a time...
ERROR: do not initialise statics to 0 or NULL
#80: FILE: migration/ram.c:531:
+static bool once = false;

ERROR: space required before the open parenthesis '('
#102: FILE: migration/ram.c:562:
+for(j = 0; j < pages.size; j++) {

total: 2 errors, 0 warnings, 87 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 13/17: migration: Send the fd number which we are going to use 
for this page...
Checking PATCH 14/17: migration: Create thread infrastructure for multifd recv 
side...
ERROR: do not initialise statics to 0 or NULL
#103: FILE: migration/ram.c:693:
+static bool once = false;

ERROR: space 

[Qemu-devel] [Bug 1622547] Re: qemu-system-sparc fatal error Trap 0x29 on Solaris 2.6

2017-01-23 Thread m...@papersolve.com
This still fails for me even when using that CPU option.  But it only
fails with my just-compiled QEMU 2.8.0, NOT my distribution-provided
QEMU 2.6.1.

mike@ossy ~/qemu> sudo /usr/local/bin/qemu-system-sparc -bios ./ss20_v2.25_rom 
-M SS-20 -nographic -boot d -hda ./sol26_36G.disk -m 512 -cdrom /mymedia/Disk\ 
Sets/Solaris_2.6_SPARC/Solaris_2.6_Software_05_98.iso -serial 
telnet:0.0.0.0:3000,server -smp 2,cores=2 -cpu "TI SuperSparc 60" -net nic -net 
bridge,br=br0
QEMU 2.8.0 monitor - type 'help' for more information
(qemu) QEMU waiting for connection on: disconnected:telnet:0.0.0.0:3000,server
qemu: fatal: Trap 0x29 while interrupts disabled, Error state
pc: e754  npc: e758
%g0-7:  00010d88      
%o0-7: f1201e20       00011a38 
%l0-7: f1201e20 e754 e758 0029 0300 3c1c   
%i0-7: 00013848 0029 0099  0edfe200  ff40 00011a38 
%f00:     
%f08:     
%f16:     
%f24:     
psr: 404010c5 (icc: -Z-- SPE: SP-) wim: 
fsr:  y: 

fish: “sudo /usr/local/bin/qemu-system…” terminated by signal SIGABRT
(Abort)


In the other window:
mike@ossy ~/qemu> telnet localhost 3000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

Power-ON Reset
Connection closed by foreign host.

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

Title:
  qemu-system-sparc fatal error Trap 0x29 on Solaris 2.6

Status in QEMU:
  Invalid

Bug description:
  When trying to install Solaris 2.6 from original CDROM, qemu fail with
  the following error :

  qemu: fatal: Trap 0x29 while interrupts disabled, Error state
  pc: f0041280  npc: f0041284
  %g0-7:  f0281800 0800   f0243b88 0001 f0244020
  %o0-7: 40400ce2 40400ce2  404000e2 f0243b88  f023ffd8 
f0057914 
  %l0-7: 4cc2 f009645c f0096460 0002 0209 0004 0007 
f023ff90 
  %i0-7: 0042 404000e3  404000e3 e000 f028192a f0240038 
f0096448 
  %f00:     
  %f08:     
  %f16:     
  %f24:     
  psr: 40400cc2 (icc: -Z-- SPE: SP-) wim: 0002
  fsr:  y: 

  The command line was :

  qemu-system-sparc -nographic -bios ./openbios-sparc32 -M SS-20 -hda
  ./36G.disk -m 512 -cdrom Solaris_2.6_Software_05_98.img -boot d
  -serial telnet:0.0.0.0:3000,server -smp 2,cores=2 -monitor null

  It fails with a similar output when using bios ss20_v2.25_rom.

  ▶ qemu-system-sparc --version
  QEMU emulator version 2.7.0, Copyright (c) 2003-2016 Fabrice Bellard and the 
QEMU Project developers

  ▶ uname -a
  Linux xxx 4.7.1-1-ARCH #1 SMP PREEMPT Wed Aug 17 08:13:35 CEST 2016 x86_64 
GNU/Linux

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



[Qemu-devel] [PATCH 17/17] migration: flush receive queue

2017-01-23 Thread Juan Quintela
Each time that we sync the bitmap, it is a possiblity that we receive
a page that is being processed by a different thread.  We fix this
problem just making sure that we wait for all receiving threads to
finish its work before we procedeed with the next stage.

We are low on page flags, so we use a combination that is not valid to
emit that message:  MULTIFD_PAGE and COMPRESSED.

I tried to make a migration command for it, but it don't work because
we sync the bitmap sometimes when we have already sent the beggining
of the section, so I just added a new page flag.

Signed-off-by: Juan Quintela 
---
 include/migration/migration.h |  1 +
 migration/ram.c   | 46 +++
 2 files changed, 47 insertions(+)

diff --git a/include/migration/migration.h b/include/migration/migration.h
index b3e4f31..1bd6bc0 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -259,6 +259,7 @@ void migrate_multifd_send_threads_create(void);
 void migrate_multifd_send_threads_join(void);
 void migrate_multifd_recv_threads_create(void);
 void migrate_multifd_recv_threads_join(void);
+void qemu_savevm_send_multifd_flush(QEMUFile *f);

 void migrate_compress_threads_create(void);
 void migrate_compress_threads_join(void);
diff --git a/migration/ram.c b/migration/ram.c
index 28d099f..3baead8 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -63,6 +63,13 @@ static uint64_t bitmap_sync_count;
 #define RAM_SAVE_FLAG_COMPRESS_PAGE0x100
 #define RAM_SAVE_FLAG_MULTIFD_PAGE 0x200

+/* We are getting low on pages flags, so we start using combinations 
+   When we need to flush a page, we sent it as
+   RAM_SAVE_FLAG_MULTIFD_PAGE | RAM_SAVE_FLAG_COMPRESS_PAGE
+   We don't allow that combination
+*/
+
+
 static uint8_t *ZERO_TARGET_PAGE;

 static inline bool is_zero_range(uint8_t *p, uint64_t size)
@@ -391,6 +398,9 @@ void migrate_compress_threads_create(void)

 /* Multiple fd's */

+/* Indicates if we have synced the bitmap and we need to assure that
+   target has processeed all previous pages */
+bool multifd_needs_flush = false;

 typedef struct {
 int num;
@@ -752,6 +762,25 @@ static void multifd_recv_page(uint8_t *address, uint16_t 
fd_num)
 qemu_mutex_unlock(>mutex);
 }

+
+static int multifd_flush(void)
+{
+int i, thread_count;
+
+if (!migrate_use_multifd()) {
+return 0;
+}
+thread_count = migrate_multifd_threads();
+qemu_mutex_lock(_recv_mutex);
+for (i = 0; i < thread_count; i++) {
+while(!multifd_recv[i].done) {
+qemu_cond_wait(_recv_cond, _recv_mutex);
+}
+}
+qemu_mutex_unlock(_recv_mutex);
+return 0;
+}
+
 /**
  * save_page_header: Write page header to wire
  *
@@ -768,6 +797,12 @@ static size_t save_page_header(QEMUFile *f, RAMBlock 
*block, ram_addr_t offset)
 {
 size_t size, len;

+if (multifd_needs_flush &&
+(offset & RAM_SAVE_FLAG_MULTIFD_PAGE)) {
+offset |= RAM_SAVE_FLAG_COMPRESS;
+multifd_needs_flush = false;
+}
+
 qemu_put_be64(f, offset);
 size = 8;

@@ -2450,6 +2485,9 @@ static int ram_save_complete(QEMUFile *f, void *opaque)

 if (!migration_in_postcopy(migrate_get_current())) {
 migration_bitmap_sync();
+if (migrate_use_multifd()) {
+multifd_needs_flush = true;
+}
 }

 ram_control_before_iterate(f, RAM_CONTROL_FINISH);
@@ -2491,6 +2529,9 @@ static void ram_save_pending(QEMUFile *f, void *opaque, 
uint64_t max_size,
 qemu_mutex_lock_iothread();
 rcu_read_lock();
 migration_bitmap_sync();
+if (migrate_use_multifd()) {
+multifd_needs_flush = true;
+}
 rcu_read_unlock();
 qemu_mutex_unlock_iothread();
 remaining_size = ram_save_remaining() * TARGET_PAGE_SIZE;
@@ -2930,6 +2971,11 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 break;
 }

+if ((flags & (RAM_SAVE_FLAG_MULTIFD_PAGE|RAM_SAVE_FLAG_COMPRESS))
+  == (RAM_SAVE_FLAG_MULTIFD_PAGE|RAM_SAVE_FLAG_COMPRESS)) {
+multifd_flush();
+flags = flags & ~RAM_SAVE_FLAG_COMPRESS;
+}
 if (flags & (RAM_SAVE_FLAG_COMPRESS | RAM_SAVE_FLAG_PAGE |
  RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE |
  RAM_SAVE_FLAG_MULTIFD_PAGE)) {
-- 
2.9.3




[Qemu-devel] [Bug 645662] Re: Python 3.1.2 math errors with Qemu 0.12.5

2017-01-23 Thread Thomas Huth
Looks like your test code from comment #1 still prints out a wrong
value, so the bug has apparently not been fixed by the FPU updates...

** Changed in: qemu
   Status: Incomplete => Triaged

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

Title:
  Python 3.1.2 math errors with Qemu 0.12.5

Status in QEMU:
  Triaged

Bug description:
  When doing the regression tests for Python 3.1.2 with Qemu 0.12.5, (Linux 
version 2.6.26-2-686 (Debian 2.6.26-25lenny1)),
  gcc (Debian 4.3.2-1.1) 4.3.2, Python compiled from sources within qemu,
  3 math tests fail, apparently because the floating point unit is buggy. Qmeu 
was compiled from original sources
  on Debian Lenny with kernel  2.6.34.6 from kernel.org, gcc  (Debian 
4.3.2-1.1) 4.3. 

  Regression testing errors:

  test_cmath
  test test_cmath failed -- Traceback (most recent call last):
File "/root/tools/python3/Python-3.1.2/Lib/test/test_cmath.py", line 364, in
  self.fail(error_message)
  AssertionError: acos0034: acos(complex(-1.0002, 0.0))
  Expected: complex(3.141592653589793, -2.1073424255447014e-08)
  Received: complex(3.141592653589793, -2.1073424338879928e-08)
  Received value insufficiently close to expected value.

  
  test_float
  test test_float failed -- Traceback (most recent call last):
File "/root/tools/python3/Python-3.1.2/Lib/test/test_float.py", line 479, in
  self.assertEqual(s, repr(float(s)))
  AssertionError: '8.72293771110361e+25' != '8.722937711103609e+25'

  
  test_math
  test test_math failed -- multiple errors occurred; run in verbose mode for 
deta

  =>

  runtests.sh -v test_math

  le01:~/tools/python3/Python-3.1.2# ./runtests.sh -v test_math
  test_math BAD
   1 BAD
   0 GOOD
   0 SKIPPED
   1 total
  le01:~/tools/python3/Python-3.1.2#

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



[Qemu-devel] [PATCH 13/17] migration: Send the fd number which we are going to use for this page

2017-01-23 Thread Juan Quintela
We are still sending the page through the main channel, that would
change later in the series

Signed-off-by: Juan Quintela 
---
 migration/ram.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index 1267730..ca94704 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -566,7 +566,7 @@ static int multifd_send_page(uint8_t *address)
 qemu_cond_signal(_send[i].cond);
 qemu_mutex_unlock(_send[i].mutex);

-return 0;
+return i;
 }

 struct MultiFDRecvParams {
@@ -1083,6 +1083,7 @@ static int ram_multifd_page(QEMUFile *f, PageSearchStatus 
*pss,
 bool last_stage, uint64_t *bytes_transferred)
 {
 int pages;
+uint16_t fd_num;
 uint8_t *p;
 RAMBlock *block = pss->block;
 ram_addr_t offset = pss->offset;
@@ -1096,8 +1097,10 @@ static int ram_multifd_page(QEMUFile *f, 
PageSearchStatus *pss,
 if (pages == -1) {
 *bytes_transferred +=
 save_page_header(f, block, offset | RAM_SAVE_FLAG_MULTIFD_PAGE);
+fd_num = multifd_send_page(p);
+qemu_put_be16(f, fd_num);
+*bytes_transferred += 2; /* size of fd_num */
 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
-multifd_send_page(p);
 *bytes_transferred += TARGET_PAGE_SIZE;
 pages = 1;
 acct_info.norm_pages++;
@@ -2815,6 +2818,7 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 while (!postcopy_running && !ret && !(flags & RAM_SAVE_FLAG_EOS)) {
 ram_addr_t addr, total_ram_bytes;
 void *host = NULL;
+uint16_t fd_num;
 uint8_t ch;

 addr = qemu_get_be64(f);
@@ -2915,6 +2919,11 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 break;

 case RAM_SAVE_FLAG_MULTIFD_PAGE:
+fd_num = qemu_get_be16(f);
+if (fd_num != 0) {
+/* this is yet an unused variable, changed later */
+fd_num = fd_num;
+}
 qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
 break;

-- 
2.9.3




[Qemu-devel] [PATCH 15/17] migration: Test new fd infrastructure

2017-01-23 Thread Juan Quintela
We just send the address through the alternate channels and test that it
is ok.

Signed-off-by: Juan Quintela 
---
 migration/ram.c | 36 
 1 file changed, 36 insertions(+)

diff --git a/migration/ram.c b/migration/ram.c
index 4e530ea..95af694 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -432,8 +432,22 @@ static void *multifd_send_thread(void *opaque)
 qemu_mutex_lock(>mutex);
 while (!params->quit){
 if (params->pages.num) {
+int i;
+int num;
+
+num = params->pages.num;
 params->pages.num = 0;
 qemu_mutex_unlock(>mutex);
+
+for(i=0; i < num; i++) {
+if (qio_channel_write(params->c,
+  (const char *)>pages.address[i],
+  sizeof(uint8_t *), _abort)
+!= sizeof(uint8_t*)) {
+/* Shuoudn't ever happen */
+exit(-1);
+}
+}
 qemu_mutex_lock(_send_mutex);
 params->done = true;
 qemu_cond_signal(_send_cond);
@@ -594,6 +608,7 @@ QemuCond  multifd_recv_cond;
 static void *multifd_recv_thread(void *opaque)
 {
 MultiFDRecvParams *params = opaque;
+uint8_t *recv_address;
 char start;

 qio_channel_read(params->c, , 1, _abort);
@@ -605,8 +620,29 @@ static void *multifd_recv_thread(void *opaque)
 qemu_mutex_lock(>mutex);
 while (!params->quit){
 if (params->pages.num) {
+int i;
+int num;
+
+num = params->pages.num;
 params->pages.num = 0;
 qemu_mutex_unlock(>mutex);
+
+for(i = 0; i < num; i++) {
+if (qio_channel_read(params->c,
+ (char *)_address,
+ sizeof(uint8_t*), _abort)
+!= sizeof(uint8_t *)) {
+/* shouldn't ever happen */
+exit(-1);
+}
+if (recv_address != params->pages.address[i]) {
+printf("We received %p what we were expecting %p (%d)\n",
+   recv_address,
+   params->pages.address[i], i);
+exit(-1);
+}
+}
+
 qemu_mutex_lock(_recv_mutex);
 params->done = true;
 qemu_cond_signal(_recv_cond);
-- 
2.9.3




[Qemu-devel] [PATCH 12/17] migration: really use multiple pages at a time

2017-01-23 Thread Juan Quintela
We now send several pages at a time each time that we wakeup a thread.

Signed-off-by: Juan Quintela 
---
 migration/ram.c | 44 ++--
 1 file changed, 38 insertions(+), 6 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index 9d7bc64..1267730 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -391,6 +391,13 @@ void migrate_compress_threads_create(void)

 /* Multiple fd's */

+
+typedef struct {
+int num;
+int size;
+uint8_t **address;
+} multifd_pages_t;
+
 struct MultiFDSendParams {
 /* not changed */
 QemuThread thread;
@@ -400,7 +407,7 @@ struct MultiFDSendParams {
 /* protected by param mutex */
 bool quit;
 bool started;
-uint8_t *address;
+multifd_pages_t pages;
 /* protected by multifd mutex */
 bool done;
 };
@@ -424,8 +431,8 @@ static void *multifd_send_thread(void *opaque)

 qemu_mutex_lock(>mutex);
 while (!params->quit){
-if (params->address) {
-params->address = 0;
+if (params->pages.num) {
+params->pages.num = 0;
 qemu_mutex_unlock(>mutex);
 qemu_mutex_lock(_send_mutex);
 params->done = true;
@@ -473,6 +480,13 @@ void migrate_multifd_send_threads_join(void)
 multifd_send = NULL;
 }

+static void multifd_init_group(multifd_pages_t *pages)
+{
+pages->num = 0;
+pages->size = migrate_multifd_group();
+pages->address = g_malloc0(pages->size * sizeof(uint8_t *));
+}
+
 void migrate_multifd_send_threads_create(void)
 {
 int i, thread_count;
@@ -491,7 +505,7 @@ void migrate_multifd_send_threads_create(void)
 multifd_send[i].quit = false;
 multifd_send[i].started = false;
 multifd_send[i].done = true;
-multifd_send[i].address = 0;
+multifd_init_group(_send[i].pages);
 multifd_send[i].c = socket_send_channel_create();
 if(!multifd_send[i].c) {
 error_report("Error creating a send channel");
@@ -511,8 +525,22 @@ void migrate_multifd_send_threads_create(void)

 static int multifd_send_page(uint8_t *address)
 {
-int i, thread_count;
+int i, j, thread_count;
 bool found = false;
+static multifd_pages_t pages;
+static bool once = false;
+
+if (!once) {
+multifd_init_group();
+once = true;
+}
+
+pages.address[pages.num] = address;
+pages.num++;
+
+if (pages.num < (pages.size - 1)) {
+return UINT16_MAX;
+}

 thread_count = migrate_multifd_threads();
 qemu_mutex_lock(_send_mutex);
@@ -530,7 +558,11 @@ static int multifd_send_page(uint8_t *address)
 }
 qemu_mutex_unlock(_send_mutex);
 qemu_mutex_lock(_send[i].mutex);
-multifd_send[i].address = address;
+multifd_send[i].pages.num = pages.num;
+for(j = 0; j < pages.size; j++) {
+multifd_send[i].pages.address[j] = pages.address[j];
+}
+pages.num = 0;
 qemu_cond_signal(_send[i].cond);
 qemu_mutex_unlock(_send[i].mutex);

-- 
2.9.3




[Qemu-devel] [PATCH 16/17] migration: [HACK]Transfer pages over new channels

2017-01-23 Thread Juan Quintela
We switch for sending the page number to send real pages.

[HACK]
How we calculate the bandwidth is beyond repair, there is a hack there
that would work for x86 and archs that have 4kb pages.

If you are having a nice day just go to migration/ram.c and look at
acct_update_position().  Now you are depressed, right?

Signed-off-by: Juan Quintela 
---
 migration/migration.c | 15 +++
 migration/ram.c   | 25 +
 2 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 1d62b91..cbbf2a3 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1839,7 +1839,8 @@ static void *migration_thread(void *opaque)
 /* Used by the bandwidth calcs, updated later */
 int64_t initial_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
 int64_t setup_start = qemu_clock_get_ms(QEMU_CLOCK_HOST);
-int64_t initial_bytes = 0;
+int64_t qemu_file_bytes = 0;
+int64_t multifd_pages = 0;
 int64_t max_size = 0;
 int64_t start_time = initial_time;
 int64_t end_time;
@@ -1923,9 +1924,14 @@ static void *migration_thread(void *opaque)
 }
 current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
 if (current_time >= initial_time + BUFFER_DELAY) {
-uint64_t transferred_bytes = qemu_ftell(s->to_dst_file) -
- initial_bytes;
 uint64_t time_spent = current_time - initial_time;
+uint64_t qemu_file_bytes_now = qemu_ftell(s->to_dst_file);
+uint64_t multifd_pages_now = multifd_mig_pages_transferred();
+/* Hack ahead.  Why the hell we don't have a function to now the
+   target_page_size.  Hard coding it to 4096 */
+uint64_t transferred_bytes =
+(qemu_file_bytes_now - qemu_file_bytes) +
+(multifd_pages_now - multifd_pages) * 4096;
 double bandwidth = (double)transferred_bytes / time_spent;
 max_size = bandwidth * s->parameters.downtime_limit;

@@ -1942,7 +1948,8 @@ static void *migration_thread(void *opaque)

 qemu_file_reset_rate_limit(s->to_dst_file);
 initial_time = current_time;
-initial_bytes = qemu_ftell(s->to_dst_file);
+qemu_file_bytes = qemu_file_bytes_now;
+multifd_pages = multifd_pages_now;
 }
 if (qemu_file_rate_limit(s->to_dst_file)) {
 /* usleep expects microseconds */
diff --git a/migration/ram.c b/migration/ram.c
index 95af694..28d099f 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -441,9 +441,9 @@ static void *multifd_send_thread(void *opaque)

 for(i=0; i < num; i++) {
 if (qio_channel_write(params->c,
-  (const char *)>pages.address[i],
-  sizeof(uint8_t *), _abort)
-!= sizeof(uint8_t*)) {
+  (const char *)params->pages.address[i],
+  TARGET_PAGE_SIZE, _abort)
+!= TARGET_PAGE_SIZE) {
 /* Shuoudn't ever happen */
 exit(-1);
 }
@@ -608,7 +608,6 @@ QemuCond  multifd_recv_cond;
 static void *multifd_recv_thread(void *opaque)
 {
 MultiFDRecvParams *params = opaque;
-uint8_t *recv_address;
 char start;

 qio_channel_read(params->c, , 1, _abort);
@@ -629,20 +628,13 @@ static void *multifd_recv_thread(void *opaque)

 for(i = 0; i < num; i++) {
 if (qio_channel_read(params->c,
- (char *)_address,
- sizeof(uint8_t*), _abort)
-!= sizeof(uint8_t *)) {
+ (char *)params->pages.address[i],
+ TARGET_PAGE_SIZE, _abort)
+!= TARGET_PAGE_SIZE) {
 /* shouldn't ever happen */
 exit(-1);
 }
-if (recv_address != params->pages.address[i]) {
-printf("We received %p what we were expecting %p (%d)\n",
-   recv_address,
-   params->pages.address[i], i);
-exit(-1);
-}
 }
-
 qemu_mutex_lock(_recv_mutex);
 params->done = true;
 qemu_cond_signal(_recv_cond);
@@ -1195,8 +1187,10 @@ static int ram_multifd_page(QEMUFile *f, 
PageSearchStatus *pss,
 save_page_header(f, block, offset | RAM_SAVE_FLAG_MULTIFD_PAGE);
 fd_num = multifd_send_page(p, migration_dirty_pages == 1);
 qemu_put_be16(f, fd_num);
+if (fd_num != UINT16_MAX) {
+qemu_fflush(f);
+}
 *bytes_transferred += 2; /* size of fd_num */
-qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
 

[Qemu-devel] [PATCH 09/17] migration: Start of multiple fd work

2017-01-23 Thread Juan Quintela
We create new channels for each new thread created. We only send through
them a character to be sure that we are creating the channels in the
right order.

Note: Reference count/freeing of channels is not done

Signed-off-by: Juan Quintela 
---
 include/migration/migration.h |  6 +
 migration/ram.c   | 45 +-
 migration/socket.c| 56 +--
 3 files changed, 104 insertions(+), 3 deletions(-)

diff --git a/include/migration/migration.h b/include/migration/migration.h
index f119ba0..3989bd6 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -22,6 +22,7 @@
 #include "qapi-types.h"
 #include "exec/cpu-common.h"
 #include "qemu/coroutine_int.h"
+#include "io/channel.h"

 #define QEMU_VM_FILE_MAGIC   0x5145564d
 #define QEMU_VM_FILE_VERSION_COMPAT  0x0002
@@ -218,6 +219,11 @@ void tcp_start_incoming_migration(const char *host_port, 
Error **errp);

 void tcp_start_outgoing_migration(MigrationState *s, const char *host_port, 
Error **errp);

+QIOChannel *socket_recv_channel_create(void);
+int socket_recv_channel_destroy(QIOChannel *recv);
+QIOChannel *socket_send_channel_create(void);
+int socket_send_channel_destroy(QIOChannel *send);
+
 void unix_start_incoming_migration(const char *path, Error **errp);

 void unix_start_outgoing_migration(MigrationState *s, const char *path, Error 
**errp);
diff --git a/migration/ram.c b/migration/ram.c
index 939f364..5ad7cb3 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -386,9 +386,11 @@ void migrate_compress_threads_create(void)

 struct MultiFDSendParams {
 QemuThread thread;
+QIOChannel *c;
 QemuCond cond;
 QemuMutex mutex;
 bool quit;
+bool started;
 };
 typedef struct MultiFDSendParams MultiFDSendParams;

@@ -397,6 +399,13 @@ static MultiFDSendParams *multifd_send;
 static void *multifd_send_thread(void *opaque)
 {
 MultiFDSendParams *params = opaque;
+char start = 's';
+
+qio_channel_write(params->c, , 1, _abort);
+qemu_mutex_lock(>mutex);
+params->started = true;
+qemu_cond_signal(>cond);
+qemu_mutex_unlock(>mutex);

 qemu_mutex_lock(>mutex);
 while (!params->quit){
@@ -433,6 +442,7 @@ void migrate_multifd_send_threads_join(void)
 qemu_thread_join(_send[i].thread);
 qemu_mutex_destroy(_send[i].mutex);
 qemu_cond_destroy(_send[i].cond);
+socket_send_channel_destroy(multifd_send[i].c);
 }
 g_free(multifd_send);
 multifd_send = NULL;
@@ -452,18 +462,31 @@ void migrate_multifd_send_threads_create(void)
 qemu_mutex_init(_send[i].mutex);
 qemu_cond_init(_send[i].cond);
 multifd_send[i].quit = false;
+multifd_send[i].started = false;
+multifd_send[i].c = socket_send_channel_create();
+if(!multifd_send[i].c) {
+error_report("Error creating a send channel");
+exit(0);
+}
 snprintf(thread_name, 15, "multifd_send_%d", i);
 qemu_thread_create(_send[i].thread, thread_name,
multifd_send_thread, _send[i],
QEMU_THREAD_JOINABLE);
+qemu_mutex_lock(_send[i].mutex);
+while (!multifd_send[i].started) {
+qemu_cond_wait(_send[i].cond, _send[i].mutex);
+}
+qemu_mutex_unlock(_send[i].mutex);
 }
 }

 struct MultiFDRecvParams {
 QemuThread thread;
+QIOChannel *c;
 QemuCond cond;
 QemuMutex mutex;
 bool quit;
+bool started;
 };
 typedef struct MultiFDRecvParams MultiFDRecvParams;

@@ -472,7 +495,14 @@ static MultiFDRecvParams *multifd_recv;
 static void *multifd_recv_thread(void *opaque)
 {
 MultiFDRecvParams *params = opaque;
- 
+char start;
+
+qio_channel_read(params->c, , 1, _abort);
+qemu_mutex_lock(>mutex);
+params->started = true;
+qemu_cond_signal(>cond);
+qemu_mutex_unlock(>mutex);
+
 qemu_mutex_lock(>mutex);
 while (!params->quit){
 qemu_cond_wait(>cond, >mutex);
@@ -508,6 +538,7 @@ void migrate_multifd_recv_threads_join(void)
 qemu_thread_join(_recv[i].thread);
 qemu_mutex_destroy(_recv[i].mutex);
 qemu_cond_destroy(_recv[i].cond);
+socket_send_channel_destroy(multifd_recv[i].c);
 }
 g_free(multifd_recv);
 multifd_recv = NULL;
@@ -526,9 +557,21 @@ void migrate_multifd_recv_threads_create(void)
 qemu_mutex_init(_recv[i].mutex);
 qemu_cond_init(_recv[i].cond);
 multifd_recv[i].quit = false;
+multifd_recv[i].started = false;
+multifd_recv[i].c = socket_recv_channel_create();
+
+if(!multifd_recv[i].c) {
+error_report("Error creating a recv channel");
+exit(0);
+}
 qemu_thread_create(_recv[i].thread, "multifd_recv",
multifd_recv_thread, _recv[i],
QEMU_THREAD_JOINABLE);
+

[Qemu-devel] [PATCH 14/17] migration: Create thread infrastructure for multifd recv side

2017-01-23 Thread Juan Quintela
We make the locking and the transfer of information specific, even if we
are still receiving things through the main thread.

Signed-off-by: Juan Quintela 
---
 migration/ram.c | 77 +
 1 file changed, 67 insertions(+), 10 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index ca94704..4e530ea 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -523,7 +523,7 @@ void migrate_multifd_send_threads_create(void)
 }
 }

-static int multifd_send_page(uint8_t *address)
+static uint16_t multifd_send_page(uint8_t *address, bool last_page)
 {
 int i, j, thread_count;
 bool found = false;
@@ -538,8 +538,10 @@ static int multifd_send_page(uint8_t *address)
 pages.address[pages.num] = address;
 pages.num++;

-if (pages.num < (pages.size - 1)) {
-return UINT16_MAX;
+if (!last_page) {
+if (pages.num < (pages.size - 1)) {
+return UINT16_MAX;
+}
 }

 thread_count = migrate_multifd_threads();
@@ -570,17 +572,25 @@ static int multifd_send_page(uint8_t *address)
 }

 struct MultiFDRecvParams {
+/* not changed */
 QemuThread thread;
 QIOChannel *c;
 QemuCond cond;
 QemuMutex mutex;
+/* proteced by param mutex */
 bool quit;
 bool started;
+multifd_pages_t pages;
+/* proteced by multifd mutex */
+bool done;
 };
 typedef struct MultiFDRecvParams MultiFDRecvParams;

 static MultiFDRecvParams *multifd_recv;

+QemuMutex multifd_recv_mutex;
+QemuCond  multifd_recv_cond;
+
 static void *multifd_recv_thread(void *opaque)
 {
 MultiFDRecvParams *params = opaque;
@@ -594,7 +604,17 @@ static void *multifd_recv_thread(void *opaque)

 qemu_mutex_lock(>mutex);
 while (!params->quit){
-qemu_cond_wait(>cond, >mutex);
+if (params->pages.num) {
+params->pages.num = 0;
+qemu_mutex_unlock(>mutex);
+qemu_mutex_lock(_recv_mutex);
+params->done = true;
+qemu_cond_signal(_recv_cond);
+qemu_mutex_unlock(_recv_mutex);
+qemu_mutex_lock(>mutex);
+} else {
+qemu_cond_wait(>cond, >mutex);
+}
 }
 qemu_mutex_unlock(>mutex);

@@ -647,8 +667,9 @@ void migrate_multifd_recv_threads_create(void)
 qemu_cond_init(_recv[i].cond);
 multifd_recv[i].quit = false;
 multifd_recv[i].started = false;
+multifd_recv[i].done = true;
+multifd_init_group(_recv[i].pages);
 multifd_recv[i].c = socket_recv_channel_create();
-
 if(!multifd_recv[i].c) {
 error_report("Error creating a recv channel");
 exit(0);
@@ -664,6 +685,45 @@ void migrate_multifd_recv_threads_create(void)
 }
 }

+static void multifd_recv_page(uint8_t *address, uint16_t fd_num)
+{
+int i, thread_count;
+MultiFDRecvParams *params;
+static multifd_pages_t pages;
+static bool once = false;
+
+if (!once) {
+multifd_init_group();
+once = true;
+}
+
+pages.address[pages.num] = address;
+pages.num++;
+
+if (fd_num == UINT16_MAX) {
+return;
+}
+
+thread_count = migrate_multifd_threads();
+assert(fd_num < thread_count);
+params = _recv[fd_num];
+
+qemu_mutex_lock(_recv_mutex);
+while (!params->done) {
+qemu_cond_wait(_recv_cond, _recv_mutex);
+}
+params->done = false;
+qemu_mutex_unlock(_recv_mutex);
+qemu_mutex_lock(>mutex);
+for(i = 0; i < pages.num; i++) {
+params->pages.address[i] = pages.address[i];
+}
+params->pages.num = pages.num;
+pages.num = 0;
+qemu_cond_signal(>cond);
+qemu_mutex_unlock(>mutex);
+}
+
 /**
  * save_page_header: Write page header to wire
  *
@@ -1097,7 +1157,7 @@ static int ram_multifd_page(QEMUFile *f, PageSearchStatus 
*pss,
 if (pages == -1) {
 *bytes_transferred +=
 save_page_header(f, block, offset | RAM_SAVE_FLAG_MULTIFD_PAGE);
-fd_num = multifd_send_page(p);
+fd_num = multifd_send_page(p, migration_dirty_pages == 1);
 qemu_put_be16(f, fd_num);
 *bytes_transferred += 2; /* size of fd_num */
 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
@@ -2920,10 +2980,7 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)

 case RAM_SAVE_FLAG_MULTIFD_PAGE:
 fd_num = qemu_get_be16(f);
-if (fd_num != 0) {
-/* this is yet an unused variable, changed later */
-fd_num = fd_num;
-}
+multifd_recv_page(host, fd_num);
 qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
 break;

-- 
2.9.3




[Qemu-devel] [PATCH 06/17] migration: Create x-multifd-threads parameter

2017-01-23 Thread Juan Quintela
Indicates the number of threads that we would create.  By default we
create 2 threads.

Signed-off-by: Juan Quintela 
Reviewed-by: Dr. David Alan Gilbert 
---
 hmp.c |  8 
 include/migration/migration.h |  2 ++
 migration/migration.c | 23 +++
 qapi-schema.json  | 13 +++--
 4 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/hmp.c b/hmp.c
index 8522efe..8c7e302 100644
--- a/hmp.c
+++ b/hmp.c
@@ -322,6 +322,9 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict 
*qdict)
 monitor_printf(mon, " %s: %" PRId64,
 MigrationParameter_lookup[MIGRATION_PARAMETER_X_CHECKPOINT_DELAY],
 params->x_checkpoint_delay);
+monitor_printf(mon, " %s: %" PRId64,
+MigrationParameter_lookup[MIGRATION_PARAMETER_X_MULTIFD_THREADS],
+params->x_multifd_threads);
 monitor_printf(mon, "\n");
 }

@@ -1394,6 +1397,10 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict 
*qdict)
 p.has_x_checkpoint_delay = true;
 use_int_value = true;
 break;
+case MIGRATION_PARAMETER_X_MULTIFD_THREADS:
+p.has_x_multifd_threads = true;
+use_int_value = true;
+break;
 }

 if (use_int_value) {
@@ -1411,6 +1418,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict 
*qdict)
 p.cpu_throttle_increment = valueint;
 p.downtime_limit = valueint;
 p.x_checkpoint_delay = valueint;
+p.x_multifd_threads = valueint;
 }

 qmp_migrate_set_parameters(, );
diff --git a/include/migration/migration.h b/include/migration/migration.h
index 19245d6..b35044c 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -247,6 +247,8 @@ bool migration_in_postcopy(MigrationState *);
 bool migration_in_postcopy_after_devices(MigrationState *);
 MigrationState *migrate_get_current(void);

+int migrate_multifd_threads(void);
+
 void migrate_compress_threads_create(void);
 void migrate_compress_threads_join(void);
 void migrate_decompress_threads_create(void);
diff --git a/migration/migration.c b/migration/migration.c
index 1669e41..2fe03d8 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -67,6 +67,7 @@
  * Note: Please change this default value to 1 when we support hybrid mode.
  */
 #define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY 200
+#define DEFAULT_MIGRATE_MULTIFD_THREADS 2

 static NotifierList migration_state_notifiers =
 NOTIFIER_LIST_INITIALIZER(migration_state_notifiers);
@@ -101,6 +102,7 @@ MigrationState *migrate_get_current(void)
 .max_bandwidth = MAX_THROTTLE,
 .downtime_limit = DEFAULT_MIGRATE_SET_DOWNTIME,
 .x_checkpoint_delay = DEFAULT_MIGRATE_X_CHECKPOINT_DELAY,
+.x_multifd_threads = DEFAULT_MIGRATE_MULTIFD_THREADS,
 },
 };

@@ -591,6 +593,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error 
**errp)
 params->downtime_limit = s->parameters.downtime_limit;
 params->has_x_checkpoint_delay = true;
 params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
+params->has_x_multifd_threads = true;
+params->x_multifd_threads = s->parameters.x_multifd_threads;

 return params;
 }
@@ -854,6 +858,13 @@ void qmp_migrate_set_parameters(MigrationParameters 
*params, Error **errp)
 "x_checkpoint_delay",
 "is invalid, it should be positive");
 }
+if (params->has_x_multifd_threads &&
+(params->x_multifd_threads < 1 || params->x_multifd_threads > 
255)) {
+error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+   "multifd_threads",
+   "is invalid, it should be in the range of 1 to 255");
+return;
+}

 if (params->has_compress_level) {
 s->parameters.compress_level = params->compress_level;
@@ -892,6 +903,9 @@ void qmp_migrate_set_parameters(MigrationParameters 
*params, Error **errp)
 if (params->has_x_checkpoint_delay) {
 s->parameters.x_checkpoint_delay = params->x_checkpoint_delay;
 }
+if (params->has_x_multifd_threads) {
+s->parameters.x_multifd_threads = params->x_multifd_threads;
+}
 }


@@ -1328,6 +1342,15 @@ bool migrate_use_multifd(void)
 return s->enabled_capabilities[MIGRATION_CAPABILITY_X_MULTIFD];
 }

+int migrate_multifd_threads(void)
+{
+MigrationState *s;
+
+s = migrate_get_current();
+
+return s->parameters.x_multifd_threads;
+}
+
 int migrate_use_xbzrle(void)
 {
 MigrationState *s;
diff --git a/qapi-schema.json b/qapi-schema.json
index d34632e..2273864 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -981,13 +981,17 @@
 # @x-checkpoint-delay: The delay time (in ms) between two COLO checkpoints in
 #  

[Qemu-devel] [PATCH 11/17] migration: Create thread infrastructure for multifd send side

2017-01-23 Thread Juan Quintela
We make the locking and the transfer of information specific, even if we
are still transmiting things through the main thread.

Signed-off-by: Juan Quintela 
---
 migration/ram.c | 53 -
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/migration/ram.c b/migration/ram.c
index c71929e..9d7bc64 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -392,17 +392,25 @@ void migrate_compress_threads_create(void)
 /* Multiple fd's */

 struct MultiFDSendParams {
+/* not changed */
 QemuThread thread;
 QIOChannel *c;
 QemuCond cond;
 QemuMutex mutex;
+/* protected by param mutex */
 bool quit;
 bool started;
+uint8_t *address;
+/* protected by multifd mutex */
+bool done;
 };
 typedef struct MultiFDSendParams MultiFDSendParams;

 static MultiFDSendParams *multifd_send;

+QemuMutex multifd_send_mutex;
+QemuCond multifd_send_cond;
+
 static void *multifd_send_thread(void *opaque)
 {
 MultiFDSendParams *params = opaque;
@@ -416,7 +424,17 @@ static void *multifd_send_thread(void *opaque)

 qemu_mutex_lock(>mutex);
 while (!params->quit){
-qemu_cond_wait(>cond, >mutex);
+if (params->address) {
+params->address = 0;
+qemu_mutex_unlock(>mutex);
+qemu_mutex_lock(_send_mutex);
+params->done = true;
+qemu_cond_signal(_send_cond);
+qemu_mutex_unlock(_send_mutex);
+qemu_mutex_lock(>mutex);
+} else {
+qemu_cond_wait(>cond, >mutex);
+}
 }
 qemu_mutex_unlock(>mutex);

@@ -464,12 +482,16 @@ void migrate_multifd_send_threads_create(void)
 }
 thread_count = migrate_multifd_threads();
 multifd_send = g_new0(MultiFDSendParams, thread_count);
+qemu_mutex_init(_send_mutex);
+qemu_cond_init(_send_cond);
 for (i = 0; i < thread_count; i++) {
 char thread_name[15];
 qemu_mutex_init(_send[i].mutex);
 qemu_cond_init(_send[i].cond);
 multifd_send[i].quit = false;
 multifd_send[i].started = false;
+multifd_send[i].done = true;
+multifd_send[i].address = 0;
 multifd_send[i].c = socket_send_channel_create();
 if(!multifd_send[i].c) {
 error_report("Error creating a send channel");
@@ -487,6 +509,34 @@ void migrate_multifd_send_threads_create(void)
 }
 }

+static int multifd_send_page(uint8_t *address)
+{
+int i, thread_count;
+bool found = false;
+
+thread_count = migrate_multifd_threads();
+qemu_mutex_lock(_send_mutex);
+while (!found) {
+for (i = 0; i < thread_count; i++) {
+if (multifd_send[i].done) {
+multifd_send[i].done = false;
+found = true;
+break;
+}
+}
+if (!found) {
+qemu_cond_wait(_send_cond, _send_mutex);
+}
+}
+qemu_mutex_unlock(_send_mutex);
+qemu_mutex_lock(_send[i].mutex);
+multifd_send[i].address = address;
+qemu_cond_signal(_send[i].cond);
+qemu_mutex_unlock(_send[i].mutex);
+
+return 0;
+}
+
 struct MultiFDRecvParams {
 QemuThread thread;
 QIOChannel *c;
@@ -1015,6 +1065,7 @@ static int ram_multifd_page(QEMUFile *f, PageSearchStatus 
*pss,
 *bytes_transferred +=
 save_page_header(f, block, offset | RAM_SAVE_FLAG_MULTIFD_PAGE);
 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
+multifd_send_page(p);
 *bytes_transferred += TARGET_PAGE_SIZE;
 pages = 1;
 acct_info.norm_pages++;
-- 
2.9.3




[Qemu-devel] [PATCH 07/17] migration: Create x-multifd-group parameter

2017-01-23 Thread Juan Quintela
Indicates how many pages we are going to send in each bach to a multifd
thread.

Signed-off-by: Juan Quintela 
---
 hmp.c |  8 
 include/migration/migration.h |  1 +
 migration/migration.c | 23 +++
 qapi-schema.json  | 11 +--
 4 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/hmp.c b/hmp.c
index 8c7e302..e579766 100644
--- a/hmp.c
+++ b/hmp.c
@@ -325,6 +325,9 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict 
*qdict)
 monitor_printf(mon, " %s: %" PRId64,
 MigrationParameter_lookup[MIGRATION_PARAMETER_X_MULTIFD_THREADS],
 params->x_multifd_threads);
+monitor_printf(mon, " %s: %" PRId64,
+MigrationParameter_lookup[MIGRATION_PARAMETER_X_MULTIFD_GROUP],
+params->x_multifd_group);
 monitor_printf(mon, "\n");
 }

@@ -1401,6 +1404,10 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict 
*qdict)
 p.has_x_multifd_threads = true;
 use_int_value = true;
 break;
+case MIGRATION_PARAMETER_X_MULTIFD_GROUP:
+p.has_x_multifd_group = true;
+use_int_value = true;
+break;
 }

 if (use_int_value) {
@@ -1419,6 +1426,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict 
*qdict)
 p.downtime_limit = valueint;
 p.x_checkpoint_delay = valueint;
 p.x_multifd_threads = valueint;
+p.x_multifd_group = valueint;
 }

 qmp_migrate_set_parameters(, );
diff --git a/include/migration/migration.h b/include/migration/migration.h
index b35044c..515569d 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -248,6 +248,7 @@ bool migration_in_postcopy_after_devices(MigrationState *);
 MigrationState *migrate_get_current(void);

 int migrate_multifd_threads(void);
+int migrate_multifd_group(void);

 void migrate_compress_threads_create(void);
 void migrate_compress_threads_join(void);
diff --git a/migration/migration.c b/migration/migration.c
index 2fe03d8..9bde01b 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -68,6 +68,7 @@
  */
 #define DEFAULT_MIGRATE_X_CHECKPOINT_DELAY 200
 #define DEFAULT_MIGRATE_MULTIFD_THREADS 2
+#define DEFAULT_MIGRATE_MULTIFD_GROUP 16

 static NotifierList migration_state_notifiers =
 NOTIFIER_LIST_INITIALIZER(migration_state_notifiers);
@@ -103,6 +104,7 @@ MigrationState *migrate_get_current(void)
 .downtime_limit = DEFAULT_MIGRATE_SET_DOWNTIME,
 .x_checkpoint_delay = DEFAULT_MIGRATE_X_CHECKPOINT_DELAY,
 .x_multifd_threads = DEFAULT_MIGRATE_MULTIFD_THREADS,
+.x_multifd_group = DEFAULT_MIGRATE_MULTIFD_GROUP,
 },
 };

@@ -595,6 +597,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error 
**errp)
 params->x_checkpoint_delay = s->parameters.x_checkpoint_delay;
 params->has_x_multifd_threads = true;
 params->x_multifd_threads = s->parameters.x_multifd_threads;
+params->has_x_multifd_group = true;
+params->x_multifd_group = s->parameters.x_multifd_group;

 return params;
 }
@@ -865,6 +869,13 @@ void qmp_migrate_set_parameters(MigrationParameters 
*params, Error **errp)
"is invalid, it should be in the range of 1 to 255");
 return;
 }
+if (params->has_x_multifd_group &&
+(params->x_multifd_group < 1 || params->x_multifd_group > 1)) {
+error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+   "multifd_group",
+   "is invalid, it should be in the range of 1 to 1");
+return;
+}

 if (params->has_compress_level) {
 s->parameters.compress_level = params->compress_level;
@@ -906,6 +917,9 @@ void qmp_migrate_set_parameters(MigrationParameters 
*params, Error **errp)
 if (params->has_x_multifd_threads) {
 s->parameters.x_multifd_threads = params->x_multifd_threads;
 }
+if (params->has_x_multifd_group) {
+s->parameters.x_multifd_group = params->x_multifd_group;
+}
 }


@@ -1351,6 +1365,15 @@ int migrate_multifd_threads(void)
 return s->parameters.x_multifd_threads;
 }

+int migrate_multifd_group(void)
+{
+MigrationState *s;
+
+s = migrate_get_current();
+
+return s->parameters.x_multifd_group;
+}
+
 int migrate_use_xbzrle(void)
 {
 MigrationState *s;
diff --git a/qapi-schema.json b/qapi-schema.json
index 2273864..54232ee 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -984,6 +984,9 @@
 # @x-multifd-threads: Number of threads used to migrate data in parallel
 # The default value is 2 (since 2.9)
 #
+# @x-multifd-group: Number of pages sent together to a thread
+# The default value is 32 (since 2.9)
+#
 # Since: 2.4
 ##
 { 'enum': 'MigrationParameter',
@@ 

[Qemu-devel] [PATCH 10/17] migration: create ram_multifd_page

2017-01-23 Thread Juan Quintela
The function still don't use multifd, but we have simplified
ram_save_page, xbzrle and RDMA stuff is gone.  We have added a new
counter and a new flag for this type of pages.

Signed-off-by: Juan Quintela 
---
 hmp.c |  2 ++
 include/migration/migration.h |  1 +
 migration/migration.c |  1 +
 migration/ram.c   | 51 ++-
 qapi-schema.json  |  4 +++-
 5 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/hmp.c b/hmp.c
index e579766..76bc8c7 100644
--- a/hmp.c
+++ b/hmp.c
@@ -222,6 +222,8 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
 monitor_printf(mon, "postcopy request count: %" PRIu64 "\n",
info->ram->postcopy_requests);
 }
+monitor_printf(mon, "multifd: %" PRIu64 " pages\n",
+   info->ram->multifd);
 }

 if (info->has_disk) {
diff --git a/include/migration/migration.h b/include/migration/migration.h
index 3989bd6..b3e4f31 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -282,6 +282,7 @@ uint64_t xbzrle_mig_pages_transferred(void);
 uint64_t xbzrle_mig_pages_overflow(void);
 uint64_t xbzrle_mig_pages_cache_miss(void);
 double xbzrle_mig_cache_miss_rate(void);
+uint64_t multifd_mig_pages_transferred(void);

 void ram_handle_compressed(void *host, uint8_t ch, uint64_t size);
 void ram_debug_dump_bitmap(unsigned long *todump, bool expected);
diff --git a/migration/migration.c b/migration/migration.c
index ab48f06..1d62b91 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -652,6 +652,7 @@ static void populate_ram_info(MigrationInfo *info, 
MigrationState *s)
 info->ram->mbps = s->mbps;
 info->ram->dirty_sync_count = s->dirty_sync_count;
 info->ram->postcopy_requests = s->postcopy_requests;
+info->ram->multifd = multifd_mig_pages_transferred();

 if (s->state != MIGRATION_STATUS_COMPLETED) {
 info->ram->remaining = ram_bytes_remaining();
diff --git a/migration/ram.c b/migration/ram.c
index 5ad7cb3..c71929e 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -61,6 +61,7 @@ static uint64_t bitmap_sync_count;
 #define RAM_SAVE_FLAG_XBZRLE   0x40
 /* 0x80 is reserved in migration.h start with 0x100 next */
 #define RAM_SAVE_FLAG_COMPRESS_PAGE0x100
+#define RAM_SAVE_FLAG_MULTIFD_PAGE 0x200

 static uint8_t *ZERO_TARGET_PAGE;

@@ -141,6 +142,7 @@ typedef struct AccountingInfo {
 uint64_t dup_pages;
 uint64_t skipped_pages;
 uint64_t norm_pages;
+uint64_t multifd_pages;
 uint64_t iterations;
 uint64_t xbzrle_bytes;
 uint64_t xbzrle_pages;
@@ -211,6 +213,11 @@ uint64_t xbzrle_mig_pages_overflow(void)
 return acct_info.xbzrle_overflows;
 }

+uint64_t multifd_mig_pages_transferred(void)
+{
+return acct_info.multifd_pages;
+}
+
 /* This is the last block that we have visited serching for dirty pages
  */
 static RAMBlock *last_seen_block;
@@ -990,6 +997,33 @@ static int ram_save_page(QEMUFile *f, PageSearchStatus 
*pss,
 return pages;
 }

+static int ram_multifd_page(QEMUFile *f, PageSearchStatus *pss,
+bool last_stage, uint64_t *bytes_transferred)
+{
+int pages;
+uint8_t *p;
+RAMBlock *block = pss->block;
+ram_addr_t offset = pss->offset;
+
+p = block->host + offset;
+
+if (block == last_sent_block) {
+offset |= RAM_SAVE_FLAG_CONTINUE;
+}
+pages = save_zero_page(f, block, offset, p, bytes_transferred);
+if (pages == -1) {
+*bytes_transferred +=
+save_page_header(f, block, offset | RAM_SAVE_FLAG_MULTIFD_PAGE);
+qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
+*bytes_transferred += TARGET_PAGE_SIZE;
+pages = 1;
+acct_info.norm_pages++;
+acct_info.multifd_pages++;
+}
+
+return pages;
+}
+
 static int do_compress_ram_page(QEMUFile *f, RAMBlock *block,
 ram_addr_t offset)
 {
@@ -1427,6 +1461,8 @@ static int ram_save_target_page(MigrationState *ms, 
QEMUFile *f,
 res = ram_save_compressed_page(f, pss,
last_stage,
bytes_transferred);
+} else if (migrate_use_multifd()) {
+res = ram_multifd_page(f, pss, last_stage, bytes_transferred);
 } else {
 res = ram_save_page(f, pss, last_stage,
 bytes_transferred);
@@ -2678,6 +2714,10 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 if (!migrate_use_compression()) {
 invalid_flags |= RAM_SAVE_FLAG_COMPRESS_PAGE;
 }
+
+if (!migrate_use_multifd()) {
+invalid_flags |= RAM_SAVE_FLAG_MULTIFD_PAGE;
+}
 /* This RCU critical section can be very long running.
  * When RCU reclaims in the code start to become numerous,
  * it will be necessary to reduce the 

[Qemu-devel] [PATCH 03/17] migration: Test for disabled features on reception

2017-01-23 Thread Juan Quintela
Right now, if we receive a compressed page or a xbzrle page while this
features are disabled, Bad Things (TM) can happen.  Just add a test for
them.

Signed-off-by: Juan Quintela 
---
 migration/ram.c | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/migration/ram.c b/migration/ram.c
index ef8fadf..4ad814a 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2455,7 +2455,7 @@ static int ram_load_postcopy(QEMUFile *f)

 static int ram_load(QEMUFile *f, void *opaque, int version_id)
 {
-int flags = 0, ret = 0;
+int flags = 0, ret = 0, invalid_flags;
 static uint64_t seq_iter;
 int len = 0;
 /*
@@ -2470,6 +2470,15 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 ret = -EINVAL;
 }

+invalid_flags = 0;
+
+if (!migrate_use_xbzrle()) {
+invalid_flags |= RAM_SAVE_FLAG_XBZRLE;
+}
+
+if (!migrate_use_compression()) {
+invalid_flags |= RAM_SAVE_FLAG_COMPRESS_PAGE;
+}
 /* This RCU critical section can be very long running.
  * When RCU reclaims in the code start to become numerous,
  * it will be necessary to reduce the granularity of this
@@ -2490,6 +2499,18 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 flags = addr & ~TARGET_PAGE_MASK;
 addr &= TARGET_PAGE_MASK;

+if (flags & invalid_flags) {
+if (flags & invalid_flags  & RAM_SAVE_FLAG_XBZRLE) {
+error_report("Received an unexpected XBRLE page");
+}
+if (flags & invalid_flags  & RAM_SAVE_FLAG_COMPRESS_PAGE) {
+error_report("Received an unexpected compressed page");
+}
+
+ret = -EINVAL;
+break;
+}
+
 if (flags & (RAM_SAVE_FLAG_COMPRESS | RAM_SAVE_FLAG_PAGE |
  RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) {
 RAMBlock *block = ram_block_from_stream(f, flags);
-- 
2.9.3




[Qemu-devel] [PATCH 05/17] migration: Add multifd capability

2017-01-23 Thread Juan Quintela
Signed-off-by: Juan Quintela 
Reviewed-by: Dr. David Alan Gilbert 
---
 include/migration/migration.h | 1 +
 migration/migration.c | 9 +
 qapi-schema.json  | 5 +++--
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/migration/migration.h b/include/migration/migration.h
index a184509..19245d6 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -297,6 +297,7 @@ bool migrate_postcopy_ram(void);
 bool migrate_zero_blocks(void);

 bool migrate_auto_converge(void);
+bool migrate_use_multifd(void);

 int xbzrle_encode_buffer(uint8_t *old_buf, uint8_t *new_buf, int slen,
  uint8_t *dst, int dlen);
diff --git a/migration/migration.c b/migration/migration.c
index 77d7b84..1669e41 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1319,6 +1319,15 @@ bool migrate_use_events(void)
 return s->enabled_capabilities[MIGRATION_CAPABILITY_EVENTS];
 }

+bool migrate_use_multifd(void)
+{
+MigrationState *s;
+
+s = migrate_get_current();
+
+return s->enabled_capabilities[MIGRATION_CAPABILITY_X_MULTIFD];
+}
+
 int migrate_use_xbzrle(void)
 {
 MigrationState *s;
diff --git a/qapi-schema.json b/qapi-schema.json
index ddc8783..d34632e 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -865,12 +865,13 @@
 #side, this process is called COarse-Grain LOck Stepping (COLO) for
 #Non-stop Service. (since 2.8)
 #
+# @x-multifd: Use more than one fd for migration (since 2.9)
+#
 # Since: 1.2
 ##
 { 'enum': 'MigrationCapability',
   'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks',
-   'compress', 'events', 'postcopy-ram', 'x-colo'] }
-
+   'compress', 'events', 'postcopy-ram', 'x-colo', 'x-multifd'] }
 ##
 # @MigrationCapabilityStatus:
 #
-- 
2.9.3




[Qemu-devel] [PATCH 04/17] migration: Don't create decompression threads if not enabled

2017-01-23 Thread Juan Quintela
Signed-off-by: Juan Quintela 

--

I removed the [HACK] part because previous patch just check that
compression pages are not received.

Signed-off-by: Juan Quintela 
---
 migration/ram.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/migration/ram.c b/migration/ram.c
index 4ad814a..cea213e 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2251,6 +2251,9 @@ void migrate_decompress_threads_create(void)
 {
 int i, thread_count;

+if (!migrate_use_compression()) {
+return;
+}
 thread_count = migrate_decompress_threads();
 decompress_threads = g_new0(QemuThread, thread_count);
 decomp_param = g_new0(DecompressParam, thread_count);
@@ -2272,6 +2275,9 @@ void migrate_decompress_threads_join(void)
 {
 int i, thread_count;

+if (!migrate_use_compression()) {
+return;
+}
 thread_count = migrate_decompress_threads();
 for (i = 0; i < thread_count; i++) {
 qemu_mutex_lock(_param[i].mutex);
-- 
2.9.3




[Qemu-devel] [PATCH 08/17] migration: create multifd migration threads

2017-01-23 Thread Juan Quintela
Creation of the threads, nothing inside yet.

Signed-off-by: Juan Quintela 
Reviewed-by: Dr. David Alan Gilbert 
---
 include/migration/migration.h |   4 ++
 migration/migration.c |   6 ++
 migration/ram.c   | 150 ++
 3 files changed, 160 insertions(+)

diff --git a/include/migration/migration.h b/include/migration/migration.h
index 515569d..f119ba0 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -249,6 +249,10 @@ MigrationState *migrate_get_current(void);

 int migrate_multifd_threads(void);
 int migrate_multifd_group(void);
+void migrate_multifd_send_threads_create(void);
+void migrate_multifd_send_threads_join(void);
+void migrate_multifd_recv_threads_create(void);
+void migrate_multifd_recv_threads_join(void);

 void migrate_compress_threads_create(void);
 void migrate_compress_threads_join(void);
diff --git a/migration/migration.c b/migration/migration.c
index 9bde01b..ab48f06 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -344,6 +344,7 @@ static void process_incoming_migration_bh(void *opaque)
   MIGRATION_STATUS_FAILED);
 error_report_err(local_err);
 migrate_decompress_threads_join();
+migrate_multifd_recv_threads_join();
 exit(EXIT_FAILURE);
 }

@@ -368,6 +369,7 @@ static void process_incoming_migration_bh(void *opaque)
 runstate_set(global_state_get_runstate());
 }
 migrate_decompress_threads_join();
+migrate_multifd_recv_threads_join();
 /*
  * This must happen after any state changes since as soon as an external
  * observer sees this event they might start to prod at the VM assuming
@@ -433,6 +435,7 @@ static void process_incoming_migration_co(void *opaque)
   MIGRATION_STATUS_FAILED);
 error_report("load of migration failed: %s", strerror(-ret));
 migrate_decompress_threads_join();
+migrate_multifd_recv_threads_join();
 exit(EXIT_FAILURE);
 }

@@ -445,6 +448,7 @@ void migration_fd_process_incoming(QEMUFile *f)
 Coroutine *co = qemu_coroutine_create(process_incoming_migration_co, f);

 migrate_decompress_threads_create();
+migrate_multifd_recv_threads_create();
 qemu_file_set_blocking(f, false);
 qemu_coroutine_enter(co);
 }
@@ -974,6 +978,7 @@ static void migrate_fd_cleanup(void *opaque)
 qemu_mutex_lock_iothread();

 migrate_compress_threads_join();
+migrate_multifd_send_threads_join();
 qemu_fclose(s->to_dst_file);
 s->to_dst_file = NULL;
 }
@@ -2020,6 +2025,7 @@ void migrate_fd_connect(MigrationState *s)
 }

 migrate_compress_threads_create();
+migrate_multifd_send_threads_create();
 qemu_thread_create(>thread, "migration", migration_thread, s,
QEMU_THREAD_JOINABLE);
 s->migration_thread_running = true;
diff --git a/migration/ram.c b/migration/ram.c
index cea213e..939f364 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -382,6 +382,156 @@ void migrate_compress_threads_create(void)
 }
 }

+/* Multiple fd's */
+
+struct MultiFDSendParams {
+QemuThread thread;
+QemuCond cond;
+QemuMutex mutex;
+bool quit;
+};
+typedef struct MultiFDSendParams MultiFDSendParams;
+
+static MultiFDSendParams *multifd_send;
+
+static void *multifd_send_thread(void *opaque)
+{
+MultiFDSendParams *params = opaque;
+
+qemu_mutex_lock(>mutex);
+while (!params->quit){
+qemu_cond_wait(>cond, >mutex);
+}
+qemu_mutex_unlock(>mutex);
+
+return NULL;
+}
+
+static void terminate_multifd_send_threads(void)
+{
+int i, thread_count;
+
+thread_count = migrate_multifd_threads();
+for (i = 0; i < thread_count; i++) {
+qemu_mutex_lock(_send[i].mutex);
+multifd_send[i].quit = true;
+qemu_cond_signal(_send[i].cond);
+qemu_mutex_unlock(_send[i].mutex);
+}
+}
+
+void migrate_multifd_send_threads_join(void)
+{
+int i, thread_count;
+
+if (!migrate_use_multifd()) {
+return;
+}
+terminate_multifd_send_threads();
+thread_count = migrate_multifd_threads();
+for (i = 0; i < thread_count; i++) {
+qemu_thread_join(_send[i].thread);
+qemu_mutex_destroy(_send[i].mutex);
+qemu_cond_destroy(_send[i].cond);
+}
+g_free(multifd_send);
+multifd_send = NULL;
+}
+
+void migrate_multifd_send_threads_create(void)
+{
+int i, thread_count;
+
+if (!migrate_use_multifd()) {
+return;
+}
+thread_count = migrate_multifd_threads();
+multifd_send = g_new0(MultiFDSendParams, thread_count);
+for (i = 0; i < thread_count; i++) {
+char thread_name[15];
+qemu_mutex_init(_send[i].mutex);
+qemu_cond_init(_send[i].cond);
+multifd_send[i].quit = false;
+snprintf(thread_name, 15, "multifd_send_%d", i);
+

[Qemu-devel] [PATCH 01/17] migration: transform remained DPRINTF into trace_

2017-01-23 Thread Juan Quintela
So we can remove DPRINTF() macro

Signed-off-by: Juan Quintela 
---
 migration/ram.c| 18 --
 migration/trace-events |  4 
 2 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index a1c8089..ef8fadf 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -45,14 +45,6 @@
 #include "qemu/rcu_queue.h"
 #include "migration/colo.h"

-#ifdef DEBUG_MIGRATION_RAM
-#define DPRINTF(fmt, ...) \
-do { fprintf(stdout, "migration_ram: " fmt, ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...) \
-do { } while (0)
-#endif
-
 static int dirty_rate_high_cnt;

 static uint64_t bitmap_sync_count;
@@ -507,10 +499,10 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t 
**current_data,
TARGET_PAGE_SIZE, XBZRLE.encoded_buf,
TARGET_PAGE_SIZE);
 if (encoded_len == 0) {
-DPRINTF("Skipping unmodified page\n");
+trace_save_xbzrle_page_skipping();
 return 0;
 } else if (encoded_len == -1) {
-DPRINTF("Overflow\n");
+trace_save_xbzrle_page_overflow();
 acct_info.xbzrle_overflows++;
 /* update data in the cache */
 if (!last_stage) {
@@ -2020,8 +2012,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
 if ((i & 63) == 0) {
 uint64_t t1 = (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - t0) / 
100;
 if (t1 > MAX_WAIT) {
-DPRINTF("big wait: %" PRIu64 " milliseconds, %d iterations\n",
-t1, i);
+trace_ram_save_iterate_big_wait(t1, i);
 break;
 }
 }
@@ -2594,8 +2585,7 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)

 wait_for_decompress_done();
 rcu_read_unlock();
-DPRINTF("Completed load of VM with exit code %d seq iteration "
-"%" PRIu64 "\n", ret, seq_iter);
+trace_ram_load_complete(ret, seq_iter);
 return ret;
 }

diff --git a/migration/trace-events b/migration/trace-events
index 94134f7..6d781cf 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -186,6 +186,10 @@ postcopy_ram_incoming_cleanup_closeuf(void) ""
 postcopy_ram_incoming_cleanup_entry(void) ""
 postcopy_ram_incoming_cleanup_exit(void) ""
 postcopy_ram_incoming_cleanup_join(void) ""
+save_xbzrle_page_skipping(void) ""
+save_xbzrle_page_overflow(void) ""
+ram_save_iterate_big_wait(uint64_t milliconds, int iterations) "big wait: %" 
PRIu64 " milliseconds, %d iterations"
+ram_load_complete(int ret, uint64_t seq_iter) "exit_code %d seq iteration %" 
PRIu64

 # migration/exec.c
 migration_exec_outgoing(const char *cmd) "cmd=%s"
-- 
2.9.3




[Qemu-devel] [PATCH 00/17] multifd v3

2017-01-23 Thread Juan Quintela
Hi

This is the 3rd version of multifd. Changes:
- comments for previous verion addressed
- lots of bugs fixed
- remove DPRINTF from ram.c

- add multifd-group parameter, it gives how many pages we sent each
  time to the worker threads.  I am open to better names.
- Better flush support.
- with migration_set_speed 2G it is able to migrate "stress -vm 2
  -vm-bytes 512M" over loopback.

Please review.

Thanks, Juan.

[v2]

This is a version against current code.  It is based on top of QIO
work. It improves the thread synchronization and fixes the problem
when we could have two threads handing the same page.

Please comment, Juan.

Juan Quintela (17):
  migration: transform remained DPRINTF into trace_
  migration: create Migration Incoming State at init time
  migration: Test for disabled features on reception
  migration: Don't create decompression threads if not enabled
  migration: Add multifd capability
  migration: Create x-multifd-threads parameter
  migration: Create x-multifd-group parameter
  migration: create multifd migration threads
  migration: Start of multiple fd work
  migration: create ram_multifd_page
  migration: Create thread infrastructure for multifd send side
  migration: really use multiple pages at a time
  migration: Send the fd number which we are going to use for this page
  migration: Create thread infrastructure for multifd recv side
  migration: Test new fd infrastructure
  migration: [HACK]Transfer pages over new channels
  migration: flush receive queue

 hmp.c |  18 ++
 include/migration/migration.h |  17 +-
 migration/migration.c | 115 --
 migration/ram.c   | 515 --
 migration/savevm.c|   4 +-
 migration/socket.c|  56 -
 migration/trace-events|   4 +
 qapi-schema.json  |  29 ++-
 8 files changed, 707 insertions(+), 51 deletions(-)

-- 
2.9.3




[Qemu-devel] [PATCH 02/17] migration: create Migration Incoming State at init time

2017-01-23 Thread Juan Quintela
Signed-off-by: Juan Quintela 
Reviewed-by: Dr. David Alan Gilbert 
---
 include/migration/migration.h |  1 -
 migration/migration.c | 38 +-
 migration/savevm.c|  4 ++--
 3 files changed, 19 insertions(+), 24 deletions(-)

diff --git a/include/migration/migration.h b/include/migration/migration.h
index c309d23..a184509 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -119,7 +119,6 @@ struct MigrationIncomingState {
 };

 MigrationIncomingState *migration_incoming_get_current(void);
-MigrationIncomingState *migration_incoming_state_new(QEMUFile *f);
 void migration_incoming_state_destroy(void);

 /*
diff --git a/migration/migration.c b/migration/migration.c
index f498ab8..77d7b84 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -111,32 +111,28 @@ MigrationState *migrate_get_current(void)
 return _migration;
 }

-/* For incoming */
-static MigrationIncomingState *mis_current;
-
 MigrationIncomingState *migration_incoming_get_current(void)
 {
-return mis_current;
-}
+static bool once;
+static MigrationIncomingState mis_current;

-MigrationIncomingState *migration_incoming_state_new(QEMUFile* f)
-{
-mis_current = g_new0(MigrationIncomingState, 1);
-mis_current->from_src_file = f;
-mis_current->state = MIGRATION_STATUS_NONE;
-QLIST_INIT(_current->loadvm_handlers);
-qemu_mutex_init(_current->rp_mutex);
-qemu_event_init(_current->main_thread_load_event, false);
-
-return mis_current;
+if (!once) {
+mis_current.state = MIGRATION_STATUS_NONE;
+memset(_current, 0, sizeof(MigrationIncomingState));
+QLIST_INIT(_current.loadvm_handlers);
+qemu_mutex_init(_current.rp_mutex);
+qemu_event_init(_current.main_thread_load_event, false);
+once = true;
+}
+return _current;
 }

 void migration_incoming_state_destroy(void)
 {
-qemu_event_destroy(_current->main_thread_load_event);
-loadvm_free_handlers(mis_current);
-g_free(mis_current);
-mis_current = NULL;
+struct MigrationIncomingState *mis = migration_incoming_get_current();
+
+qemu_event_destroy(>main_thread_load_event);
+loadvm_free_handlers(mis);
 }


@@ -382,11 +378,11 @@ static void process_incoming_migration_bh(void *opaque)
 static void process_incoming_migration_co(void *opaque)
 {
 QEMUFile *f = opaque;
-MigrationIncomingState *mis;
+MigrationIncomingState *mis = migration_incoming_get_current();
 PostcopyState ps;
 int ret;

-mis = migration_incoming_state_new(f);
+mis->from_src_file = f;
 postcopy_state_set(POSTCOPY_INCOMING_NONE);
 migrate_set_state(>state, MIGRATION_STATUS_NONE,
   MIGRATION_STATUS_ACTIVE);
diff --git a/migration/savevm.c b/migration/savevm.c
index f9c06e9..41a2506 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2185,7 +2185,6 @@ void qmp_xen_load_devices_state(const char *filename, 
Error **errp)
 qio_channel_set_name(QIO_CHANNEL(ioc), "migration-xen-load-state");
 f = qemu_fopen_channel_input(QIO_CHANNEL(ioc));

-migration_incoming_state_new(f);
 ret = qemu_loadvm_state(f);
 qemu_fclose(f);
 if (ret < 0) {
@@ -2201,6 +2200,7 @@ int load_vmstate(const char *name)
 QEMUFile *f;
 int ret;
 AioContext *aio_context;
+MigrationIncomingState *mis = migration_incoming_get_current();

 if (!bdrv_all_can_snapshot()) {
 error_report("Device '%s' is writable but does not support snapshots.",
@@ -2251,7 +2251,7 @@ int load_vmstate(const char *name)
 }

 qemu_system_reset(VMRESET_SILENT);
-migration_incoming_state_new(f);
+mis->from_src_file = f;

 aio_context_acquire(aio_context);
 ret = qemu_loadvm_state(f);
-- 
2.9.3




[Qemu-devel] [PATCH 2/2] niagara: check if a serial port is available

2017-01-23 Thread Artyom Tarasenko
Reported-by:Markus Armbruster 
Signed-off-by: Artyom Tarasenko 
---
 hw/sparc64/niagara.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/sparc64/niagara.c b/hw/sparc64/niagara.c
index e945b5a..a14724f 100644
--- a/hw/sparc64/niagara.c
+++ b/hw/sparc64/niagara.c
@@ -154,9 +154,10 @@ static void niagara_init(MachineState *machine)
 exit(1);
 }
 }
-serial_mm_init(sysmem, NIAGARA_UART_BASE, 0, NULL, 115200,
-   serial_hds[0], DEVICE_BIG_ENDIAN);
-
+if (serial_hds[0]) {
+serial_mm_init(sysmem, NIAGARA_UART_BASE, 0, NULL, 115200,
+   serial_hds[0], DEVICE_BIG_ENDIAN);
+}
 empty_slot_init(NIAGARA_IOBBASE, NIAGARA_IOBSIZE);
 sun4v_rtc_init(NIAGARA_RTC_BASE);
 }
-- 
2.7.2




[Qemu-devel] [PATCH 1/2] niagara: fail if a firmware file is missing

2017-01-23 Thread Artyom Tarasenko
Suggested-by: Peter Maydell 
Signed-off-by: Artyom Tarasenko 
---
 hw/sparc64/niagara.c | 22 +++---
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/hw/sparc64/niagara.c b/hw/sparc64/niagara.c
index b55d4bb..e945b5a 100644
--- a/hw/sparc64/niagara.c
+++ b/hw/sparc64/niagara.c
@@ -35,6 +35,7 @@
 #include "hw/timer/sun4v-rtc.h"
 #include "exec/address-spaces.h"
 #include "sysemu/block-backend.h"
+#include "qemu/error-report.h"
 
 
 typedef struct NiagaraBoardState {
@@ -85,6 +86,14 @@ typedef struct NiagaraBoardState {
 #define NIAGARA_OBP_OFFSET  0x8ULL
 #define PROM_SIZE_MAX   (4 * 1024 * 1024)
 
+static void add_rom_or_fail(const char *file, const hwaddr addr)
+{
+if (rom_add_file_fixed(file, addr, -1)) {
+error_report("Unable to load a firmware for -M niagara");
+exit(1);
+}
+
+}
 /* Niagara hardware initialisation */
 static void niagara_init(MachineState *machine)
 {
@@ -119,14 +128,13 @@ static void niagara_init(MachineState *machine)
  "sun4v.prom", PROM_SIZE_MAX);
 memory_region_add_subregion(sysmem, NIAGARA_PROM_BASE, >prom);
 
-rom_add_file_fixed("nvram1", NIAGARA_NVRAM_BASE, -1);
-rom_add_file_fixed("1up-md.bin", NIAGARA_MD_ROM_BASE, -1);
-rom_add_file_fixed("1up-hv.bin", NIAGARA_HV_ROM_BASE, -1);
+add_rom_or_fail("nvram1", NIAGARA_NVRAM_BASE);
+add_rom_or_fail("1up-md.bin", NIAGARA_MD_ROM_BASE);
+add_rom_or_fail("1up-hv.bin", NIAGARA_HV_ROM_BASE);
 
-rom_add_file_fixed("reset.bin", NIAGARA_PROM_BASE, -1);
-rom_add_file_fixed("q.bin", NIAGARA_PROM_BASE + NIAGARA_Q_OFFSET, -1);
-rom_add_file_fixed("openboot.bin", NIAGARA_PROM_BASE + NIAGARA_OBP_OFFSET,
-   -1);
+add_rom_or_fail("reset.bin", NIAGARA_PROM_BASE);
+add_rom_or_fail("q.bin", NIAGARA_PROM_BASE + NIAGARA_Q_OFFSET);
+add_rom_or_fail("openboot.bin", NIAGARA_PROM_BASE + NIAGARA_OBP_OFFSET);
 
 /* the virtual ramdisk is kind of initrd, but it resides
outside of the partition RAM */
-- 
2.7.2




[Qemu-devel] [PATCH 0/2] niagara fixes

2017-01-23 Thread Artyom Tarasenko
Niagara bugfixes

Artyom Tarasenko (2):
  niagara: fail if a firmware file is missing
  niagara: check if a serial port is available

 hw/sparc64/niagara.c | 29 +++--
 1 file changed, 19 insertions(+), 10 deletions(-)

-- 
2.7.2




Re: [Qemu-devel] [Bug 1253777] Re: OpenBSD VM running on OpenBSD host has sleep calls taking twice as long as they should

2017-01-23 Thread Martin van den Nieuwelaar
I hadn't seen comment #5.  Not sure how that affects qemu.  
Unfortunately I'm not in a position to set up a system any time soon 
with the latest versions of everything to see if the bug is still present.


On 24/01/17 08:32, Thomas Huth wrote:
> What does comment #5 mean? Is this issue now fixed with the latest
> version of QEMU?
>
> ** Changed in: qemu
> Status: New => Incomplete
>


-- 
R A Ward Ltd. | We take the privacy of our customers seriously.
Christchurch  | All sensitive E-Mail attachments MUST be encrypted.
New Zealand

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

Title:
  OpenBSD VM running on OpenBSD host has sleep calls taking twice as
  long as they should

Status in QEMU:
  Incomplete

Bug description:
  Running a script like

  while [ 1 ]
  do
date
sleep 1
  done

  on the VM will result in the (correct) date being displayed, but it is
  displayed only every two (!) seconds.  We have also noticed that if we
  connect to the VM's console using VNC, and move the mouse pointer
  constantly in the VNC window, the script runs normally with updates
  every second!  Note that the script doesn't have to be running on the
  VM's console - it's also possible to (say) ssh to the VM from a
  separate machine and run the script and it will display the '2 second'
  issue, but as soon as you move the mouse pointer constantly in the VNC
  console window the script starts behaving normally with updates every
  second.

  I have only seen this bug when running an OpenBSD VM on an OpenBSD
  host.  Running an OpenBSD VM on a Linux host does not exhibit the
  problem for me.  I also belive (am told) that a Linux VM running on an
  OpenBSD host does not exhibit the problem.

  I have been using the OpenBSD 5.4 64 bit distro which comes with qemu
  1.5.1 in a package, however I tried compiling qemu 1.6.1 and that has
  the same bug.  In fact older OpenBSD distros have the same issue -
  going back to OpenBSD distros from two years ago still have the
  problem.  This is not a 'new' bug recently introduced.

  Initially I wondered if it could be traced to an incorrectly set
  command line option, but I've since gone through many of the options
  in the man page simply trying different values (eg. different CPU
  types ( -cpu) , different emulated PC (-M)) but so far the problem
  remains.

  I'm quite happy to run tests in order to track this bug down better.
  We use qemu running on OpenBSD extensively and find it very useful!

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



Re: [Qemu-devel] [PATCH] 9pfs: fix offset error in v9fs_xattr_read()

2017-01-23 Thread Stefano Stabellini
On Sat, 21 Jan 2017, Greg Kurz wrote:
> The current code tries to copy `read_count' bytes starting at offset
> `offset' from a `read_count`-sized iovec. This causes v9fs_pack() to
> fail with ENOBUFS.
> 
> Since the PDU iovec is already partially filled with `offset' bytes,
> let's skip them when creating `qiov_full' and have v9fs_pack() to
> copy the whole of it. Moreover, this is consistent with the other
> places where v9fs_init_qiov_from_pdu() is called.
> 
> This fixes commit "bcb8998fac16 9pfs: call v9fs_init_qiov_from_pdu
> before v9fs_pack".

Sorry about that!


> Signed-off-by: Greg Kurz 
> ---
>  hw/9pfs/9p.c |4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
> index fa58877570f6..f0eef1a3ef53 100644
> --- a/hw/9pfs/9p.c
> +++ b/hw/9pfs/9p.c
> @@ -1685,8 +1685,8 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, 
> V9fsFidState *fidp,
>  }
>  offset += err;
>  
> -v9fs_init_qiov_from_pdu(_full, pdu, 0, read_count, false);
> -err = v9fs_pack(qiov_full.iov, qiov_full.niov, offset,
> +v9fs_init_qiov_from_pdu(_full, pdu, offset, read_count, false);

v9fs_init_qiov_from_pdu calls init_in_iov_from_pdu passing read_count as
size argument. offset is not passed to init_in_iov_from_pdu, it is only
used to initialized qiov_full.

In other words, don't we need to:

v9fs_init_qiov_from_pdu(_full, pdu, offset, read_count + offset, 
false);

To make sure that qiov_full has "read_count + offset" bytes in it, and
qiov_full is initialized skipping the first "offset" bytes?


> +err = v9fs_pack(qiov_full.iov, qiov_full.niov, 0,
>  ((char *)fidp->fs.xattr.value) + off,
>  read_count);
>  qemu_iovec_destroy(_full);
> 



Re: [Qemu-devel] changeset b0cb0a66d broken - missing QEMU_OPTION_enable_hax

2017-01-23 Thread James Hanley
That did it - Thanks, and my apologies to Vincent for the false alarm.
-Jim

On Mon, Jan 23, 2017 at 2:41 PM, Peter Maydell 
wrote:

> On 23 January 2017 at 19:32, James Hanley  wrote:
> > Changeset fails to compile:
> >
> > qemu/vl.c:3683:18: error: ‘QEMU_OPTION_enable_hax’ undeclared (first use
> in
> > this function)
> >  case QEMU_OPTION_enable_hax:
> >   ^
> > I assume that there is details in
> >
> > ./qemu-options.def
> > ./qemu-options.hx
> >
> > that were not included with the commit?
>
> Your source tree probably has a stale qemu-options.def in it
> from an attempt to do an in-tree build at some point in the
> past (and now you are doing out-of-tree builds). If you do a
> 'make distclean' in the source tree this will get rid of the
> stale junk and the build should work. (Or you can just git
> clone a fresh tree; or attempt to more carefully remove
> individual stale stuff, but that risks leaving some other
> stale file around.)
>
> (The change to qemu-options.hx is sufficient, because we
> generate qemu-options.def from it in the build tree; but
> if you have a stale .def file in the source tree then
> gcc will pick that one up before the one in the build tree;
> which works until something requires a change that postdates
> the stale stuff.)
>
> thanks
> -- PMM
>


[Qemu-devel] [Bug 1253777] Re: OpenBSD VM running on OpenBSD host has sleep calls taking twice as long as they should

2017-01-23 Thread Thomas Huth
What does comment #5 mean? Is this issue now fixed with the latest
version of QEMU?

** Changed in: qemu
   Status: New => Incomplete

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

Title:
  OpenBSD VM running on OpenBSD host has sleep calls taking twice as
  long as they should

Status in QEMU:
  Incomplete

Bug description:
  Running a script like

  while [ 1 ]
  do
date
sleep 1
  done

  on the VM will result in the (correct) date being displayed, but it is
  displayed only every two (!) seconds.  We have also noticed that if we
  connect to the VM's console using VNC, and move the mouse pointer
  constantly in the VNC window, the script runs normally with updates
  every second!  Note that the script doesn't have to be running on the
  VM's console - it's also possible to (say) ssh to the VM from a
  separate machine and run the script and it will display the '2 second'
  issue, but as soon as you move the mouse pointer constantly in the VNC
  console window the script starts behaving normally with updates every
  second.

  I have only seen this bug when running an OpenBSD VM on an OpenBSD
  host.  Running an OpenBSD VM on a Linux host does not exhibit the
  problem for me.  I also belive (am told) that a Linux VM running on an
  OpenBSD host does not exhibit the problem.

  I have been using the OpenBSD 5.4 64 bit distro which comes with qemu
  1.5.1 in a package, however I tried compiling qemu 1.6.1 and that has
  the same bug.  In fact older OpenBSD distros have the same issue -
  going back to OpenBSD distros from two years ago still have the
  problem.  This is not a 'new' bug recently introduced.

  Initially I wondered if it could be traced to an incorrectly set
  command line option, but I've since gone through many of the options
  in the man page simply trying different values (eg. different CPU
  types ( -cpu) , different emulated PC (-M)) but so far the problem
  remains.

  I'm quite happy to run tests in order to track this bug down better.
  We use qemu running on OpenBSD extensively and find it very useful!

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



Re: [Qemu-devel] changeset b0cb0a66d broken - missing QEMU_OPTION_enable_hax

2017-01-23 Thread Peter Maydell
On 23 January 2017 at 19:32, James Hanley  wrote:
> Changeset fails to compile:
>
> qemu/vl.c:3683:18: error: ‘QEMU_OPTION_enable_hax’ undeclared (first use in
> this function)
>  case QEMU_OPTION_enable_hax:
>   ^
> I assume that there is details in
>
> ./qemu-options.def
> ./qemu-options.hx
>
> that were not included with the commit?

Your source tree probably has a stale qemu-options.def in it
from an attempt to do an in-tree build at some point in the
past (and now you are doing out-of-tree builds). If you do a
'make distclean' in the source tree this will get rid of the
stale junk and the build should work. (Or you can just git
clone a fresh tree; or attempt to more carefully remove
individual stale stuff, but that risks leaving some other
stale file around.)

(The change to qemu-options.hx is sufficient, because we
generate qemu-options.def from it in the build tree; but
if you have a stale .def file in the source tree then
gcc will pick that one up before the one in the build tree;
which works until something requires a change that postdates
the stale stuff.)

thanks
-- PMM



Re: [Qemu-devel] [PATCH RFC v4 18/20] intel_iommu: enable vfio devices

2017-01-23 Thread Alex Williamson
On Mon, 23 Jan 2017 18:23:44 +0800
Jason Wang  wrote:

> On 2017年01月23日 11:34, Peter Xu wrote:
> > On Mon, Jan 23, 2017 at 09:55:39AM +0800, Jason Wang wrote:  
> >>
> >> On 2017年01月22日 17:04, Peter Xu wrote:  
> >>> On Sun, Jan 22, 2017 at 04:08:04PM +0800, Jason Wang wrote:
> >>>
> >>> [...]
> >>>  
> > +static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,
> > +   uint16_t domain_id, hwaddr 
> > addr,
> > +   uint8_t am)
> > +{
> > +IntelIOMMUNotifierNode *node;
> > +VTDContextEntry ce;
> > +int ret;
> > +
> > +QLIST_FOREACH(node, &(s->notifiers_list), next) {
> > +VTDAddressSpace *vtd_as = node->vtd_as;
> > +ret = vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),
> > +   vtd_as->devfn, );
> > +if (!ret && domain_id == VTD_CONTEXT_ENTRY_DID(ce.hi)) {
> > +vtd_page_walk(, addr, addr + (1 << am) * VTD_PAGE_SIZE,
> > +  vtd_page_invalidate_notify_hook,
> > +  (void *)_as->iommu, true);  
>  Why not simply trigger the notifier here? (or is this vfio required?)  
> >>> Because we may only want to notify part of the region - we are with
> >>> mask here, but not exact size.
> >>>
> >>> Consider this: guest (with caching mode) maps 12K memory (4K*3 pages),
> >>> the mask will be extended to 16K in the guest. In that case, we need
> >>> to explicitly go over the page entry to know that the 4th page should
> >>> not be notified.  
> >> I see. Then it was required by vfio only, I think we can add a fast path 
> >> for
> >> !CM in this case by triggering the notifier directly.  
> > I noted this down (to be further investigated in my todo), but I don't
> > know whether this can work, due to the fact that I think it is still
> > legal that guest merge more than one PSIs into one. For example, I
> > don't know whether below is legal:
> >
> > - guest invalidate page (0, 4k)
> > - guest map new page (4k, 8k)
> > - guest send single PSI of (0, 8k)
> >
> > In that case, it contains both map/unmap, and looks like it didn't
> > disobay the spec as well?  
> 
> Not sure I get your meaning, you mean just send single PSI instead of two?
> 
> >  
> >> Another possible issue is, consider (with CM) a 16K contiguous iova with 
> >> the
> >> last page has already been mapped. In this case, if we want to map first
> >> three pages, when handling IOTLB invalidation, am would be 16K, then the
> >> last page will be mapped twice. Can this lead some issue?  
> > I don't know whether guest has special handling of this kind of
> > request.  
> 
> This seems quite usual I think? E.g iommu_flush_iotlb_psi() did:
> 
> static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
>struct dmar_domain *domain,
>unsigned long pfn, unsigned int pages,
>int ih, int map)
> {
>  unsigned int mask = ilog2(__roundup_pow_of_two(pages));
>  uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT;
>  u16 did = domain->iommu_did[iommu->seq_id];
> ...
> 
> 
> >
> > Besides, imho to completely solve this problem, we still need that
> > per-domain tree. Considering that currently the tree is inside vfio, I
> > see this not a big issue as well.  
> 
> Another issue I found is: with this series, VFIO_IOMMU_MAP_DMA seems 
> become guest trigger-able. And since VFIO allocate its own structure to 
> record dma mapping, this seems open a window for evil guest to exhaust 
> host memory which is even worse.

You're thinking of pci-assign, vfio does page accounting such that a
user can only lock pages up to their locked memory limit.  Exposing the
mapping ioctl within the guest is not a different problem from exposing
the ioctl to the host user from a vfio perspective.  Thanks,

Alex



[Qemu-devel] [Bug 1626972] Re: QEMU memfd_create fallback mechanism change for security drivers

2017-01-23 Thread ChristianEhrhardt
Ping - we have the next fix for Xenial in the queue - all others are
released now, has this one "baked" enough for Xenial SRU to migrate?

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

Title:
  QEMU memfd_create fallback mechanism change for security drivers

Status in Ubuntu Cloud Archive:
  Invalid
Status in Ubuntu Cloud Archive mitaka series:
  Fix Committed
Status in QEMU:
  Fix Released
Status in qemu package in Ubuntu:
  Fix Released
Status in qemu source package in Xenial:
  Fix Committed
Status in qemu source package in Yakkety:
  Fix Released
Status in qemu source package in Zesty:
  Fix Released

Bug description:
  [Impact]

   * Updated QEMU (from UCA) live migration doesn't work with 3.13 kernels.
   * QEMU code checks if it can create /tmp/memfd-XXX files wrongly.
   * Apparmor will block access to /tmp/ and QEMU will fail migrating.

  [Test Case]

   * Install 2 Ubuntu Trusty (3.13) + UCA Mitaka + apparmor rules.
   * Try to live-migration from one to another. 
   * Apparmor will block creation of /tmp/memfd-XXX files.

  [Regression Potential]

   Pros:
   * Exhaustively tested this.
   * Worked with upstream on this fix. 
   * I'm implementing new vhost log mechanism for upstream.
   * One line change to a blocker that is already broken.

   Cons:
   * To break live migration in other circumstances. 

  [Other Info]

   * Christian Ehrhardt has been following this.

  ORIGINAL DESCRIPTION:

  When libvirt starts using apparmor, and creating apparmor profiles for
  every virtual machine created in the compute nodes, mitaka qemu (2.5 -
  and upstream also) uses a fallback mechanism for creating shared
  memory for live-migrations. This fall back mechanism, on kernels 3.13
  - that don't have memfd_create() system-call, try to create files on
  /tmp/ directory and fails.. causing live-migration not to work.

  Trusty with kernel 3.13 + Mitaka with qemu 2.5 + apparmor capability =
  can't live migrate.

  From qemu 2.5, logic is on :

  void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals, int 
*fd)
  {
  if (memfd_create)... ### only works with HWE kernels

  else ### 3.13 kernels, gets blocked by apparmor
     tmpdir = g_get_tmp_dir
     ...
     mfd = mkstemp(fname)
  }

  And you can see the errors:

  From the host trying to send the virtual machine:

  2016-08-15 16:36:26.160 1974 ERROR nova.virt.libvirt.driver 
[req-0cac612b-8d53-4610-b773-d07ad6bacb91 691a581cfa7046278380ce82b1c38ddd 
133ebc3585c041aebaead8c062cd6511 - - -] [instance: 
2afa1131-bc8c-43d2-9c4a-962c1bf7723e] Migration operation has aborted
  2016-08-15 16:36:26.248 1974 ERROR nova.virt.libvirt.driver 
[req-0cac612b-8d53-4610-b773-d07ad6bacb91 691a581cfa7046278380ce82b1c38ddd 
133ebc3585c041aebaead8c062cd6511 - - -] [instance: 
2afa1131-bc8c-43d2-9c4a-962c1bf7723e] Live Migration failure: internal error: 
unable to execute QEMU command 'migrate': Migration disabled: failed to 
allocate shared memory

  From the host trying to receive the virtual machine:

  Aug 15 16:36:19 tkcompute01 kernel: [ 1194.356794] type=1400 
audit(1471289779.791:72): apparmor="STATUS" operation="profile_load" 
profile="unconfined" name="libvirt-2afa1131-bc8c-43d2-9c4a-962c1bf7723e" 
pid=12565 comm="apparmor_parser"
  Aug 15 16:36:19 tkcompute01 kernel: [ 1194.357048] type=1400 
audit(1471289779.791:73): apparmor="STATUS" operation="profile_load" 
profile="unconfined" name="qemu_bridge_helper" pid=12565 comm="apparmor_parser"
  Aug 15 16:36:20 tkcompute01 kernel: [ 1194.877027] type=1400 
audit(1471289780.311:74): apparmor="STATUS" operation="profile_replace" 
profile="unconfined" name="libvirt-2afa1131-bc8c-43d2-9c4a-962c1bf7723e" 
pid=12613 comm="apparmor_parser"
  Aug 15 16:36:20 tkcompute01 kernel: [ 1194.904407] type=1400 
audit(1471289780.343:75): apparmor="STATUS" operation="profile_replace" 
profile="unconfined" name="qemu_bridge_helper" pid=12613 comm="apparmor_parser"
  Aug 15 16:36:20 tkcompute01 kernel: [ 1194.973064] type=1400 
audit(1471289780.407:76): apparmor="DENIED" operation="mknod" 
profile="libvirt-2afa1131-bc8c-43d2-9c4a-962c1bf7723e" name="/tmp/memfd-tNpKSj" 
pid=12625 comm="qemu-system-x86" requested_mask="c" denied_mask="c" fsuid=107 
ouid=107
  Aug 15 16:36:20 tkcompute01 kernel: [ 1194.979871] type=1400 
audit(1471289780.411:77): apparmor="DENIED" operation="open" 
profile="libvirt-2afa1131-bc8c-43d2-9c4a-962c1bf7723e" name="/tmp/" pid=12625 
comm="qemu-system-x86" requested_mask="r" denied_mask="r" fsuid=107 ouid=0
  Aug 15 16:36:20 tkcompute01 kernel: [ 1194.979881] type=1400 
audit(1471289780.411:78): apparmor="DENIED" operation="open" 
profile="libvirt-2afa1131-bc8c-43d2-9c4a-962c1bf7723e" name="/var/tmp/" 
pid=12625 comm="qemu-system-x86" requested_mask="r" denied_mask="r" fsuid=107 
ouid=0

  When leaving libvirt without apparmor capabilities (thus not confining
  

Re: [Qemu-devel] [PATCH RFC v4 15/20] intel_iommu: provide its own replay() callback

2017-01-23 Thread Alex Williamson
On Mon, 23 Jan 2017 10:54:49 +0800
Peter Xu  wrote:

> On Mon, Jan 23, 2017 at 09:48:48AM +0800, Jason Wang wrote:
> > 
> > 
> > On 2017年01月22日 16:51, Peter Xu wrote:  
> > >On Sun, Jan 22, 2017 at 03:56:10PM +0800, Jason Wang wrote:
> > >
> > >[...]
> > >  
> > >>>+/**
> > >>>+ * vtd_page_walk_level - walk over specific level for IOVA range
> > >>>+ *
> > >>>+ * @addr: base GPA addr to start the walk
> > >>>+ * @start: IOVA range start address
> > >>>+ * @end: IOVA range end address (start <= addr < end)
> > >>>+ * @hook_fn: hook func to be called when detected page
> > >>>+ * @private: private data to be passed into hook func
> > >>>+ * @read: whether parent level has read permission
> > >>>+ * @write: whether parent level has write permission
> > >>>+ * @skipped: accumulated skipped ranges  
> > >>What's the usage for this parameter? Looks like it was never used in this
> > >>series.  
> > >This was for debugging purpose before, and I kept it in case one day
> > >it can be used again, considering that will not affect much on the
> > >overall performance.  
> > 
> > I think we usually do not keep debugging codes outside debug macros.  
> 
> I'll remove it.

While you're at it, what's the value in using a void* private rather
than just passing around an IOMMUNotifier*.  Seems like unnecessary
abstraction.  Thanks,

Alex



Re: [Qemu-devel] [PATCH RFC v4 15/20] intel_iommu: provide its own replay() callback

2017-01-23 Thread Alex Williamson
On Sun, 22 Jan 2017 16:51:18 +0800
Peter Xu  wrote:

> On Sun, Jan 22, 2017 at 03:56:10PM +0800, Jason Wang wrote:
> >   
> > >+trace_vtd_page_walk_one(level, entry.iova, 
> > >entry.translated_addr,
> > >+entry.addr_mask, entry.perm);
> > >+if (hook_fn) {
> > >+ret = hook_fn(, private);  
> > 
> > For better performance, we could try to merge adjacent mappings here. I
> > think both vfio and vhost support this and it can save a lot of ioctls.  
> 
> Looks so, and this is in my todo list.
> 
> Do you mind I do it later after this series merged? I would really
> appreciate if we can have this codes settled down first (considering
> that this series has been dangling for half a year, or more, startint
> from Aviv's series), and I am just afraid this will led to
> unconvergence of this series (and I believe there are other places
> that can be enhanced in the future as well).

NAK, we can't merge mappings per my comment on 18/20.  You're looking
at an entirely new or at best revised version of the vfio IOMMU
interface to do so.  vfio does not support invalidations at a smaller
granularity than the original mapping.  Thanks,

Alex




[Qemu-devel] changeset b0cb0a66d broken - missing QEMU_OPTION_enable_hax

2017-01-23 Thread James Hanley
Changeset fails to compile:

qemu/vl.c:3683:18: error: ‘QEMU_OPTION_enable_hax’ undeclared (first use in
this function)
 case QEMU_OPTION_enable_hax:
  ^
I assume that there is details in

./qemu-options.def
./qemu-options.hx

that were not included with the commit?

http://git.qemu.org/?p=qemu.git;a=commit;h=b0cb0a66d6d535112aa513568ef21dcb1ad283ed

-Jim


Re: [Qemu-devel] [PATCH v7 18/27] cputlb: introduce tlb_flush_*_all_cpus

2017-01-23 Thread Richard Henderson
On 01/19/2017 09:04 AM, Alex Bennée wrote:
> +/* flush_all_helper: run fn across all cpus
> + *
> + * If the wait flag is set then the src cpu's helper will be queued as
> + * "safe" work and the loop exited creating a synchronisation point
> + * where all queued work will be finished before execution starts
> + * again.
> + */
> +static void flush_all_helper(CPUState *src, bool wait,
> + run_on_cpu_func fn, run_on_cpu_data d)
> +{
> +CPUState *cpu;
> +
> +if (!wait) {
> +CPU_FOREACH(cpu) {
> +if (cpu != src) {
> +async_run_on_cpu(cpu, fn, d);
> +} else {
> +g_assert(qemu_cpu_is_self(src));
> +fn(src, d);
> +}
> +}
> +} else {
> +CPU_FOREACH(cpu) {
> +if (cpu != src) {
> +async_run_on_cpu(cpu, fn, d);
> +} else {
> +async_safe_run_on_cpu(cpu, fn, d);
> +}
> +
> +}
> +cpu_loop_exit(src);
> +}
> +}

What's the rationale for not having the target do the exit itself?  Surely it
can tell, and simple end the TB after the insn.


r~



[Qemu-devel] [PATCH V3 2/3] hw/ioh3420: derive from PCI Express Root Port base class

2017-01-23 Thread Marcel Apfelbaum
Preserve only Intel specific details.

Signed-off-by: Marcel Apfelbaum 
---
 hw/pci-bridge/ioh3420.c | 121 ++--
 1 file changed, 15 insertions(+), 106 deletions(-)

diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c
index 84b7946..571ffe5 100644
--- a/hw/pci-bridge/ioh3420.c
+++ b/hw/pci-bridge/ioh3420.c
@@ -61,119 +61,28 @@ static uint8_t ioh3420_aer_vector(const PCIDevice *d)
 return 0;
 }
 
-static void ioh3420_aer_vector_update(PCIDevice *d)
+static int ioh3420_interrupts_init(PCIDevice *d, Error **errp)
 {
-pcie_aer_root_set_vector(d, ioh3420_aer_vector(d));
-}
-
-static void ioh3420_write_config(PCIDevice *d,
-   uint32_t address, uint32_t val, int len)
-{
-uint32_t root_cmd =
-pci_get_long(d->config + d->exp.aer_cap + PCI_ERR_ROOT_COMMAND);
-
-pci_bridge_write_config(d, address, val, len);
-ioh3420_aer_vector_update(d);
-pcie_cap_slot_write_config(d, address, val, len);
-pcie_aer_write_config(d, address, val, len);
-pcie_aer_root_write_config(d, address, val, len, root_cmd);
-}
-
-static void ioh3420_reset(DeviceState *qdev)
-{
-PCIDevice *d = PCI_DEVICE(qdev);
-
-ioh3420_aer_vector_update(d);
-pcie_cap_root_reset(d);
-pcie_cap_deverr_reset(d);
-pcie_cap_slot_reset(d);
-pcie_cap_arifwd_reset(d);
-pcie_aer_root_reset(d);
-pci_bridge_reset(qdev);
-pci_bridge_disable_base_limit(d);
-}
-
-static int ioh3420_initfn(PCIDevice *d)
-{
-PCIEPort *p = PCIE_PORT(d);
-PCIESlot *s = PCIE_SLOT(d);
 int rc;
-Error *err = NULL;
-
-pci_config_set_interrupt_pin(d->config, 1);
-pci_bridge_initfn(d, TYPE_PCIE_BUS);
-pcie_port_init_reg(d);
-
-rc = pci_bridge_ssvid_init(d, IOH_EP_SSVID_OFFSET,
-   IOH_EP_SSVID_SVID, IOH_EP_SSVID_SSID);
-if (rc < 0) {
-goto err_bridge;
-}
+Error *local_err = NULL;
 
 rc = msi_init(d, IOH_EP_MSI_OFFSET, IOH_EP_MSI_NR_VECTOR,
   IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
-  IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT, );
+  IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT,
+  _err);
 if (rc < 0) {
 assert(rc == -ENOTSUP);
-error_report_err(err);
-goto err_bridge;
+error_propagate(errp, local_err);
 }
 
-rc = pcie_cap_init(d, IOH_EP_EXP_OFFSET, PCI_EXP_TYPE_ROOT_PORT, p->port);
-if (rc < 0) {
-goto err_msi;
-}
-
-pcie_cap_arifwd_init(d);
-pcie_cap_deverr_init(d);
-pcie_cap_slot_init(d, s->slot);
-pcie_cap_root_init(d);
-
-pcie_chassis_create(s->chassis);
-rc = pcie_chassis_add_slot(s);
-if (rc < 0) {
-goto err_pcie_cap;
-}
-
-rc = pcie_aer_init(d, PCI_ERR_VER, IOH_EP_AER_OFFSET,
-   PCI_ERR_SIZEOF, );
-if (rc < 0) {
-error_report_err(err);
-goto err;
-}
-pcie_aer_root_init(d);
-ioh3420_aer_vector_update(d);
-
-return 0;
-
-err:
-pcie_chassis_del_slot(s);
-err_pcie_cap:
-pcie_cap_exit(d);
-err_msi:
-msi_uninit(d);
-err_bridge:
-pci_bridge_exitfn(d);
 return rc;
 }
 
-static void ioh3420_exitfn(PCIDevice *d)
+static void ioh3420_interrupts_uninit(PCIDevice *d)
 {
-PCIESlot *s = PCIE_SLOT(d);
-
-pcie_aer_exit(d);
-pcie_chassis_del_slot(s);
-pcie_cap_exit(d);
 msi_uninit(d);
-pci_bridge_exitfn(d);
 }
 
-static Property ioh3420_props[] = {
-DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present,
-QEMU_PCIE_SLTCAP_PCP_BITNR, true),
-DEFINE_PROP_END_OF_LIST()
-};
-
 static const VMStateDescription vmstate_ioh3420 = {
 .name = "ioh-3240-express-root-port",
 .version_id = 1,
@@ -191,25 +100,25 @@ static void ioh3420_class_init(ObjectClass *klass, void 
*data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass);
 
-k->is_express = 1;
-k->is_bridge = 1;
-k->config_write = ioh3420_write_config;
-k->init = ioh3420_initfn;
-k->exit = ioh3420_exitfn;
 k->vendor_id = PCI_VENDOR_ID_INTEL;
 k->device_id = PCI_DEVICE_ID_IOH_EPORT;
 k->revision = PCI_DEVICE_ID_IOH_REV;
-set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 dc->desc = "Intel IOH device id 3420 PCIE Root Port";
-dc->reset = ioh3420_reset;
 dc->vmsd = _ioh3420;
-dc->props = ioh3420_props;
+rpc->aer_vector = ioh3420_aer_vector;
+rpc->interrupts_init = ioh3420_interrupts_init;
+rpc->interrupts_uninit = ioh3420_interrupts_uninit;
+rpc->exp_offset = IOH_EP_EXP_OFFSET;
+rpc->aer_offset = IOH_EP_AER_OFFSET;
+rpc->ssvid_offset = IOH_EP_SSVID_OFFSET;
+rpc->ssid = IOH_EP_SSVID_SSID;
 }
 
 static const TypeInfo ioh3420_info = {
 .name  = "ioh3420",
-.parent= TYPE_PCIE_SLOT,
+

  1   2   3   4   >