[Qemu-devel] [PATCH v7 08/20] dirty-bitmap: Change bdrv_dirty_bitmap_*serialize*() to take bytes

2017-09-12 Thread Eric Blake
Right now, the dirty-bitmap code exposes the fact that we use
a scale of sector granularity in the underlying hbitmap to anything
that wants to serialize a dirty bitmap.  It's nicer to uniformly
expose bytes as our dirty-bitmap interface, matching the previous
change to bitmap size.  The only caller to serialization is currently
qcow2-cluster.c, which becomes a bit more verbose because it is still
tracking sectors for other reasons, but a later patch will fix that
to more uniformly use byte offsets everywhere.  Likewise, within
dirty-bitmap, we have to add more assertions that we are not
truncating incorrectly, which can go away once the internal hbitmap
is byte-based rather than sector-based.

Signed-off-by: Eric Blake 
Reviewed-by: John Snow 

---
v5: no change
v4: new patch
---
 include/block/dirty-bitmap.h | 14 +++---
 block/dirty-bitmap.c | 37 -
 block/qcow2-bitmap.c | 22 ++
 3 files changed, 45 insertions(+), 28 deletions(-)

diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
index 15101b59d5..cd32149db6 100644
--- a/include/block/dirty-bitmap.h
+++ b/include/block/dirty-bitmap.h
@@ -49,19 +49,19 @@ BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap 
*bitmap,
 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter);

 uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
-  uint64_t start, uint64_t count);
+  uint64_t offset, uint64_t bytes);
 uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap);
 void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
-  uint8_t *buf, uint64_t start,
-  uint64_t count);
+  uint8_t *buf, uint64_t offset,
+  uint64_t bytes);
 void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
-uint8_t *buf, uint64_t start,
-uint64_t count, bool finish);
+uint8_t *buf, uint64_t offset,
+uint64_t bytes, bool finish);
 void bdrv_dirty_bitmap_deserialize_zeroes(BdrvDirtyBitmap *bitmap,
-  uint64_t start, uint64_t count,
+  uint64_t offset, uint64_t bytes,
   bool finish);
 void bdrv_dirty_bitmap_deserialize_ones(BdrvDirtyBitmap *bitmap,
-uint64_t start, uint64_t count,
+uint64_t offset, uint64_t bytes,
 bool finish);
 void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap);

diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index ec4fc0e1ad..dbf5a53044 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -573,42 +573,53 @@ void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap 
*bitmap, HBitmap *in)
 }

 uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
-  uint64_t start, uint64_t count)
+  uint64_t offset, uint64_t bytes)
 {
-return hbitmap_serialization_size(bitmap->bitmap, start, count);
+assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
+return hbitmap_serialization_size(bitmap->bitmap,
+  offset >> BDRV_SECTOR_BITS,
+  bytes >> BDRV_SECTOR_BITS);
 }

 uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap)
 {
-return hbitmap_serialization_align(bitmap->bitmap);
+return hbitmap_serialization_align(bitmap->bitmap) * BDRV_SECTOR_SIZE;
 }

 void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,
-  uint8_t *buf, uint64_t start,
-  uint64_t count)
+  uint8_t *buf, uint64_t offset,
+  uint64_t bytes)
 {
-hbitmap_serialize_part(bitmap->bitmap, buf, start, count);
+assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
+hbitmap_serialize_part(bitmap->bitmap, buf, offset >> BDRV_SECTOR_BITS,
+   bytes >> BDRV_SECTOR_BITS);
 }

 void bdrv_dirty_bitmap_deserialize_part(BdrvDirtyBitmap *bitmap,
-uint8_t *buf, uint64_t start,
-uint64_t count, bool finish)
+uint8_t *buf, uint64_t offset,
+uint64_t bytes, bool finish)
 {
-hbitmap_deserialize_part(bitmap->bitmap, buf, start, count, finish);
+

[Qemu-devel] [PATCH v7 09/20] qcow2: Switch sectors_covered_by_bitmap_cluster() to byte-based

2017-09-12 Thread Eric Blake
We are gradually converting to byte-based interfaces, as they are
easier to reason about than sector-based.  Change the qcow2 bitmap
helper function sectors_covered_by_bitmap_cluster(), renaming it
to bytes_covered_by_bitmap_cluster() in the process.

Signed-off-by: Eric Blake 
Reviewed-by: John Snow 

---
v5: no change
v4: new patch
---
 block/qcow2-bitmap.c | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index 92098bfa49..4475273d8c 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -269,18 +269,16 @@ static int free_bitmap_clusters(BlockDriverState *bs, 
Qcow2BitmapTable *tb)
 return 0;
 }

-/* This function returns the number of disk sectors covered by a single qcow2
- * cluster of bitmap data. */
-static uint64_t sectors_covered_by_bitmap_cluster(const BDRVQcow2State *s,
-  const BdrvDirtyBitmap 
*bitmap)
+/* Return the disk size covered by a single qcow2 cluster of bitmap data. */
+static uint64_t bytes_covered_by_bitmap_cluster(const BDRVQcow2State *s,
+const BdrvDirtyBitmap *bitmap)
 {
-uint64_t sector_granularity =
-bdrv_dirty_bitmap_granularity(bitmap) >> BDRV_SECTOR_BITS;
-uint64_t sbc = sector_granularity * (s->cluster_size << 3);
+uint64_t granularity = bdrv_dirty_bitmap_granularity(bitmap);
+uint64_t limit = granularity * (s->cluster_size << 3);

-assert(QEMU_IS_ALIGNED(sbc << BDRV_SECTOR_BITS,
+assert(QEMU_IS_ALIGNED(limit,
bdrv_dirty_bitmap_serialization_align(bitmap)));
-return sbc;
+return limit;
 }

 /* load_bitmap_data
@@ -293,7 +291,7 @@ static int load_bitmap_data(BlockDriverState *bs,
 {
 int ret = 0;
 BDRVQcow2State *s = bs->opaque;
-uint64_t sector, sbc;
+uint64_t sector, limit, sbc;
 uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
 uint64_t bm_sectors = DIV_ROUND_UP(bm_size, BDRV_SECTOR_SIZE);
 uint8_t *buf = NULL;
@@ -306,7 +304,8 @@ static int load_bitmap_data(BlockDriverState *bs,
 }

 buf = g_malloc(s->cluster_size);
-sbc = sectors_covered_by_bitmap_cluster(s, bitmap);
+limit = bytes_covered_by_bitmap_cluster(s, bitmap);
+sbc = limit >> BDRV_SECTOR_BITS;
 for (i = 0, sector = 0; i < tab_size; ++i, sector += sbc) {
 uint64_t count = MIN(bm_sectors - sector, sbc);
 uint64_t entry = bitmap_table[i];
@@ -1080,7 +1079,7 @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
 int ret;
 BDRVQcow2State *s = bs->opaque;
 int64_t sector;
-uint64_t sbc;
+uint64_t limit, sbc;
 uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
 uint64_t bm_sectors = DIV_ROUND_UP(bm_size, BDRV_SECTOR_SIZE);
 const char *bm_name = bdrv_dirty_bitmap_name(bitmap);
@@ -1106,8 +1105,9 @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,

 dbi = bdrv_dirty_iter_new(bitmap, 0);
 buf = g_malloc(s->cluster_size);
-sbc = sectors_covered_by_bitmap_cluster(s, bitmap);
-assert(DIV_ROUND_UP(bm_sectors, sbc) == tb_size);
+limit = bytes_covered_by_bitmap_cluster(s, bitmap);
+sbc = limit >> BDRV_SECTOR_BITS;
+assert(DIV_ROUND_UP(bm_size, limit) == tb_size);

 while ((sector = bdrv_dirty_iter_next(dbi)) != -1) {
 uint64_t cluster = sector / sbc;
-- 
2.13.5




[Qemu-devel] [PATCH v7 07/20] dirty-bitmap: Track bitmap size by bytes

2017-09-12 Thread Eric Blake
We are still using an internal hbitmap that tracks a size in sectors,
with the granularity scaled down accordingly, because it lets us
use a shortcut for our iterators which are currently sector-based.
But there's no reason we can't track the dirty bitmap size in bytes,
since it is (mostly) an internal-only variable (remember, the size
is how many bytes are covered by the bitmap, not how many bytes the
bitmap occupies).  A later cleanup will convert dirty bitmap
internals to be entirely byte-based, eliminating the intermediate
sector rounding added here; and technically, since bdrv_getlength()
already rounds up to sectors, our use of DIV_ROUND_UP is more for
theoretical completeness than for any actual rounding.

Use is_power_of_2() while at it, instead of open-coding that.

Signed-off-by: Eric Blake 

---
v7: split external from internal [Kevin], drop R-b
v6: no change
v5: fix bdrv_dirty_bitmap_truncate [John], drop R-b
v4: retitle from "Track size in bytes", rebase to persistent bitmaps,
round up when converting bytes to sectors
v3: no change
v2: tweak commit message, no code change
---
 block/dirty-bitmap.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index 56a01699e9..ec4fc0e1ad 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -42,7 +42,7 @@ struct BdrvDirtyBitmap {
 HBitmap *meta;  /* Meta dirty bitmap */
 BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
 char *name; /* Optional non-empty unique ID */
-int64_t size;   /* Size of the bitmap (Number of sectors) */
+int64_t size;   /* Size of the bitmap, in bytes */
 bool disabled;  /* Bitmap is disabled. It ignores all writes to
the device */
 int active_iterators;   /* How many iterators are active */
@@ -115,17 +115,14 @@ BdrvDirtyBitmap 
*bdrv_create_dirty_bitmap(BlockDriverState *bs,
 {
 int64_t bitmap_size;
 BdrvDirtyBitmap *bitmap;
-uint32_t sector_granularity;

-assert((granularity & (granularity - 1)) == 0);
+assert(is_power_of_2(granularity) && granularity >= BDRV_SECTOR_SIZE);

 if (name && bdrv_find_dirty_bitmap(bs, name)) {
 error_setg(errp, "Bitmap already exists: %s", name);
 return NULL;
 }
-sector_granularity = granularity >> BDRV_SECTOR_BITS;
-assert(sector_granularity);
-bitmap_size = bdrv_nb_sectors(bs);
+bitmap_size = bdrv_getlength(bs);
 if (bitmap_size < 0) {
 error_setg_errno(errp, -bitmap_size, "could not get length of device");
 errno = -bitmap_size;
@@ -133,7 +130,12 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState 
*bs,
 }
 bitmap = g_new0(BdrvDirtyBitmap, 1);
 bitmap->mutex = &bs->dirty_bitmap_mutex;
-bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(sector_granularity));
+/*
+ * TODO - let hbitmap track full granularity. For now, it is tracking
+ * only sector granularity, as a shortcut for our iterators.
+ */
+bitmap->bitmap = hbitmap_alloc(DIV_ROUND_UP(bitmap_size, BDRV_SECTOR_SIZE),
+   ctz32(granularity) - BDRV_SECTOR_BITS);
 bitmap->size = bitmap_size;
 bitmap->name = g_strdup(name);
 bitmap->disabled = false;
@@ -175,7 +177,7 @@ void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)

 int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap)
 {
-return bitmap->size * BDRV_SECTOR_SIZE;
+return bitmap->size;
 }

 const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap *bitmap)
@@ -305,7 +307,7 @@ BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState 
*bs,
 int bdrv_dirty_bitmap_truncate(BlockDriverState *bs)
 {
 BdrvDirtyBitmap *bitmap;
-int64_t size = bdrv_nb_sectors(bs);
+int64_t size = bdrv_getlength(bs);

 if (size < 0) {
 return size;
@@ -314,7 +316,7 @@ int bdrv_dirty_bitmap_truncate(BlockDriverState *bs)
 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
 assert(!bdrv_dirty_bitmap_frozen(bitmap));
 assert(!bitmap->active_iterators);
-hbitmap_truncate(bitmap->bitmap, size);
+hbitmap_truncate(bitmap->bitmap, DIV_ROUND_UP(size, BDRV_SECTOR_SIZE));
 bitmap->size = size;
 }
 bdrv_dirty_bitmaps_unlock(bs);
@@ -553,7 +555,8 @@ void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, 
HBitmap **out)
 hbitmap_reset_all(bitmap->bitmap);
 } else {
 HBitmap *backup = bitmap->bitmap;
-bitmap->bitmap = hbitmap_alloc(bitmap->size,
+bitmap->bitmap = hbitmap_alloc(DIV_ROUND_UP(bitmap->size,
+BDRV_SECTOR_SIZE),
hbitmap_granularity(backup));
 *out = backup;
 }
-- 
2.13.5




[Qemu-devel] [PATCH v7 18/20] qcow2: Switch store_bitmap_data() to byte-based iteration

2017-09-12 Thread Eric Blake
Now that we have adjusted the majority of the calls this function
makes to be byte-based, it is easier to read the code if it makes
passes over the image using bytes rather than sectors.

Signed-off-by: Eric Blake 
Reviewed-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 

---
v7: rebase to earlier change, make rounding of offset obvious (no semantic
change, so R-b kept) [Kevin]
v5-v6: no change
v4: new patch
---
 block/qcow2-bitmap.c | 26 +++---
 1 file changed, 11 insertions(+), 15 deletions(-)

diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index 692ce0de88..302fffd6e1 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -1072,10 +1072,9 @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
 {
 int ret;
 BDRVQcow2State *s = bs->opaque;
-int64_t sector;
-uint64_t limit, sbc;
+int64_t offset;
+uint64_t limit;
 uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
-uint64_t bm_sectors = DIV_ROUND_UP(bm_size, BDRV_SECTOR_SIZE);
 const char *bm_name = bdrv_dirty_bitmap_name(bitmap);
 uint8_t *buf = NULL;
 BdrvDirtyBitmapIter *dbi;
@@ -1100,18 +1099,17 @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
 dbi = bdrv_dirty_iter_new(bitmap);
 buf = g_malloc(s->cluster_size);
 limit = bytes_covered_by_bitmap_cluster(s, bitmap);
-sbc = limit >> BDRV_SECTOR_BITS;
 assert(DIV_ROUND_UP(bm_size, limit) == tb_size);

-while ((sector = bdrv_dirty_iter_next(dbi) >> BDRV_SECTOR_BITS) >= 0) {
-uint64_t cluster = sector / sbc;
+while ((offset = bdrv_dirty_iter_next(dbi)) >= 0) {
+uint64_t cluster = offset / limit;
 uint64_t end, write_size;
 int64_t off;

-sector = cluster * sbc;
-end = MIN(bm_sectors, sector + sbc);
-write_size = bdrv_dirty_bitmap_serialization_size(bitmap,
-sector * BDRV_SECTOR_SIZE, (end - sector) * BDRV_SECTOR_SIZE);
+offset = QEMU_ALIGN_DOWN(offset, limit);
+end = MIN(bm_size, offset + limit);
+write_size = bdrv_dirty_bitmap_serialization_size(bitmap, offset,
+  end - offset);
 assert(write_size <= s->cluster_size);

 off = qcow2_alloc_clusters(bs, s->cluster_size);
@@ -1123,9 +1121,7 @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
 }
 tb[cluster] = off;

-bdrv_dirty_bitmap_serialize_part(bitmap, buf,
- sector * BDRV_SECTOR_SIZE,
- (end - sector) * BDRV_SECTOR_SIZE);
+bdrv_dirty_bitmap_serialize_part(bitmap, buf, offset, end - offset);
 if (write_size < s->cluster_size) {
 memset(buf + write_size, 0, s->cluster_size - write_size);
 }
@@ -1143,11 +1139,11 @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
 goto fail;
 }

-if (end >= bm_sectors) {
+if (end >= bm_size) {
 break;
 }

-bdrv_set_dirty_iter(dbi, end * BDRV_SECTOR_SIZE);
+bdrv_set_dirty_iter(dbi, end);
 }

 *bitmap_table_size = tb_size;
-- 
2.13.5




[Qemu-devel] [PATCH v7 10/20] dirty-bitmap: Set iterator start by offset, not sector

2017-09-12 Thread Eric Blake
All callers to bdrv_dirty_iter_new() passed 0 for their initial
starting point, drop that parameter.

Most callers to bdrv_set_dirty_iter() were scaling a byte offset to
a sector number; the exception qcow2-bitmap will be converted later
to use byte rather than sector iteration.  Move the scaling to occur
internally to dirty bitmap code instead, so that callers now pass
in bytes.

Signed-off-by: Eric Blake 
Reviewed-by: John Snow 

---
v5: no change
v4: rebase to persistent bitmaps
v3: no change
v2: no change
---
 include/block/dirty-bitmap.h | 5 ++---
 block/backup.c   | 5 ++---
 block/dirty-bitmap.c | 9 -
 block/mirror.c   | 4 ++--
 block/qcow2-bitmap.c | 4 ++--
 5 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
index cd32149db6..842e57416c 100644
--- a/include/block/dirty-bitmap.h
+++ b/include/block/dirty-bitmap.h
@@ -44,8 +44,7 @@ void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
  int64_t cur_sector, int64_t nr_sectors);
 BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap);
-BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
- uint64_t first_sector);
+BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap);
 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter);

 uint64_t bdrv_dirty_bitmap_serialization_size(const BdrvDirtyBitmap *bitmap,
@@ -80,7 +79,7 @@ void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
 void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
 int64_t cur_sector, int64_t nr_sectors);
 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter);
-void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t sector_num);
+void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t offset);
 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
 int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap);
 int bdrv_dirty_bitmap_truncate(BlockDriverState *bs);
diff --git a/block/backup.c b/block/backup.c
index 517c300a49..ac9c018717 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -372,7 +372,7 @@ static int coroutine_fn 
backup_run_incremental(BackupBlockJob *job)

 granularity = bdrv_dirty_bitmap_granularity(job->sync_bitmap);
 clusters_per_iter = MAX((granularity / job->cluster_size), 1);
-dbi = bdrv_dirty_iter_new(job->sync_bitmap, 0);
+dbi = bdrv_dirty_iter_new(job->sync_bitmap);

 /* Find the next dirty sector(s) */
 while ((offset = bdrv_dirty_iter_next(dbi) * BDRV_SECTOR_SIZE) >= 0) {
@@ -403,8 +403,7 @@ static int coroutine_fn 
backup_run_incremental(BackupBlockJob *job)
 /* If the bitmap granularity is smaller than the backup granularity,
  * we need to advance the iterator pointer to the next cluster. */
 if (granularity < job->cluster_size) {
-bdrv_set_dirty_iter(dbi,
-cluster * job->cluster_size / 
BDRV_SECTOR_SIZE);
+bdrv_set_dirty_iter(dbi, cluster * job->cluster_size);
 }

 last_cluster = cluster - 1;
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index dbf5a53044..d50c46621d 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -478,11 +478,10 @@ uint32_t bdrv_dirty_bitmap_granularity(const 
BdrvDirtyBitmap *bitmap)
 return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
 }

-BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
- uint64_t first_sector)
+BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
 {
 BdrvDirtyBitmapIter *iter = g_new(BdrvDirtyBitmapIter, 1);
-hbitmap_iter_init(&iter->hbi, bitmap->bitmap, first_sector);
+hbitmap_iter_init(&iter->hbi, bitmap->bitmap, 0);
 iter->bitmap = bitmap;
 bitmap->active_iterators++;
 return iter;
@@ -650,9 +649,9 @@ void bdrv_set_dirty(BlockDriverState *bs, int64_t 
cur_sector,
 /**
  * Advance a BdrvDirtyBitmapIter to an arbitrary offset.
  */
-void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t sector_num)
+void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t offset)
 {
-hbitmap_iter_init(&iter->hbi, iter->hbi.hb, sector_num);
+hbitmap_iter_init(&iter->hbi, iter->hbi.hb, offset >> BDRV_SECTOR_BITS);
 }

 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
diff --git a/block/mirror.c b/block/mirror.c
index 6531652d73..0b063b3c20 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -373,7 +373,7 @@ static uint64_t coroutine_fn 
mirror_iteration(MirrorBlockJob *s)
 next_dirty = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
 if (next_dirty > next_offset || next_dirty < 0) {
 /* The bitmap iterator's cache is stale, refresh it */
-bdrv_set_dirty_iter(s->dbi, next_offset >> BDRV_SECTOR_BITS)

[Qemu-devel] [PATCH v7 11/20] dirty-bitmap: Change bdrv_dirty_iter_next() to report byte offset

2017-09-12 Thread Eric Blake
Thanks to recent cleanups, most callers were scaling a return value
of sectors into bytes (the exception, in qcow2-bitmap, will be
converted to byte-based iteration later).  Update the interface to
do the scaling internally instead.

In qcow2-bitmap, the code was specifically checking for an error
to be -1; it is more robust to treat all negative values as an
error, but at the same time it is also easy enough to ensure we
return -1 (and not -512) on error.

Signed-off-by: Eric Blake 

---
v7: return -1, not -512; and fix qcow2-bitmap to check all negatives [Kevin]
v5-v6: no change
v4: rebase to persistent bitmap
v3: no change
v2: no change
---
 block/backup.c   | 2 +-
 block/dirty-bitmap.c | 3 ++-
 block/mirror.c   | 8 
 block/qcow2-bitmap.c | 2 +-
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index ac9c018717..06ddbfd03d 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -375,7 +375,7 @@ static int coroutine_fn 
backup_run_incremental(BackupBlockJob *job)
 dbi = bdrv_dirty_iter_new(job->sync_bitmap);

 /* Find the next dirty sector(s) */
-while ((offset = bdrv_dirty_iter_next(dbi) * BDRV_SECTOR_SIZE) >= 0) {
+while ((offset = bdrv_dirty_iter_next(dbi)) >= 0) {
 cluster = offset / job->cluster_size;

 /* Fake progress updates for any clusters we skipped */
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index d50c46621d..49229fd501 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -508,7 +508,8 @@ void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)

 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
 {
-return hbitmap_iter_next(&iter->hbi);
+int64_t ret = hbitmap_iter_next(&iter->hbi);
+return ret < 0 ? -1 : ret * BDRV_SECTOR_SIZE;
 }

 /* Called within bdrv_dirty_bitmap_lock..unlock */
diff --git a/block/mirror.c b/block/mirror.c
index 0b063b3c20..77bf5aa3a4 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -336,10 +336,10 @@ static uint64_t coroutine_fn 
mirror_iteration(MirrorBlockJob *s)
 int max_io_bytes = MAX(s->buf_size / MAX_IN_FLIGHT, MAX_IO_BYTES);

 bdrv_dirty_bitmap_lock(s->dirty_bitmap);
-offset = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
+offset = bdrv_dirty_iter_next(s->dbi);
 if (offset < 0) {
 bdrv_set_dirty_iter(s->dbi, 0);
-offset = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
+offset = bdrv_dirty_iter_next(s->dbi);
 trace_mirror_restart_iter(s, bdrv_get_dirty_count(s->dirty_bitmap) *
   BDRV_SECTOR_SIZE);
 assert(offset >= 0);
@@ -370,11 +370,11 @@ static uint64_t coroutine_fn 
mirror_iteration(MirrorBlockJob *s)
 break;
 }

-next_dirty = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
+next_dirty = bdrv_dirty_iter_next(s->dbi);
 if (next_dirty > next_offset || next_dirty < 0) {
 /* The bitmap iterator's cache is stale, refresh it */
 bdrv_set_dirty_iter(s->dbi, next_offset);
-next_dirty = bdrv_dirty_iter_next(s->dbi) * BDRV_SECTOR_SIZE;
+next_dirty = bdrv_dirty_iter_next(s->dbi);
 }
 assert(next_dirty == next_offset);
 nb_chunks++;
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index 44329fc74f..b09010b1d3 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -1109,7 +1109,7 @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
 sbc = limit >> BDRV_SECTOR_BITS;
 assert(DIV_ROUND_UP(bm_size, limit) == tb_size);

-while ((sector = bdrv_dirty_iter_next(dbi)) != -1) {
+while ((sector = bdrv_dirty_iter_next(dbi) >> BDRV_SECTOR_BITS) >= 0) {
 uint64_t cluster = sector / sbc;
 uint64_t end, write_size;
 int64_t off;
-- 
2.13.5




[Qemu-devel] [PATCH v7 12/20] dirty-bitmap: Change bdrv_get_dirty_count() to report bytes

2017-09-12 Thread Eric Blake
Thanks to recent cleanups, all callers were scaling a return value
of sectors into bytes; do the scaling internally instead.

Signed-off-by: Eric Blake 

---
v7: fix one more trace caller [Kevin]
v4-v6: no change
v3: no change, add R-b
v2: no change
---
 block/dirty-bitmap.c |  4 ++--
 block/mirror.c   | 16 ++--
 migration/block.c|  2 +-
 3 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index 49229fd501..ee0afb5e1a 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -428,7 +428,7 @@ BlockDirtyInfoList 
*bdrv_query_dirty_bitmaps(BlockDriverState *bs)
 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
 BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1);
 BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1);
-info->count = bdrv_get_dirty_count(bm) << BDRV_SECTOR_BITS;
+info->count = bdrv_get_dirty_count(bm);
 info->granularity = bdrv_dirty_bitmap_granularity(bm);
 info->has_name = !!bm->name;
 info->name = g_strdup(bm->name);
@@ -657,7 +657,7 @@ void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *iter, int64_t 
offset)

 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap)
 {
-return hbitmap_count(bitmap->bitmap);
+return hbitmap_count(bitmap->bitmap) << BDRV_SECTOR_BITS;
 }

 int64_t bdrv_get_meta_dirty_count(BdrvDirtyBitmap *bitmap)
diff --git a/block/mirror.c b/block/mirror.c
index 77bf5aa3a4..7113d47db4 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -340,8 +340,7 @@ static uint64_t coroutine_fn 
mirror_iteration(MirrorBlockJob *s)
 if (offset < 0) {
 bdrv_set_dirty_iter(s->dbi, 0);
 offset = bdrv_dirty_iter_next(s->dbi);
-trace_mirror_restart_iter(s, bdrv_get_dirty_count(s->dirty_bitmap) *
-  BDRV_SECTOR_SIZE);
+trace_mirror_restart_iter(s, bdrv_get_dirty_count(s->dirty_bitmap));
 assert(offset >= 0);
 }
 bdrv_dirty_bitmap_unlock(s->dirty_bitmap);
@@ -811,11 +810,10 @@ static void coroutine_fn mirror_run(void *opaque)

 cnt = bdrv_get_dirty_count(s->dirty_bitmap);
 /* s->common.offset contains the number of bytes already processed so
- * far, cnt is the number of dirty sectors remaining and
+ * far, cnt is the number of dirty bytes remaining and
  * s->bytes_in_flight is the number of bytes currently being
  * processed; together those are the current total operation length */
-s->common.len = s->common.offset + s->bytes_in_flight +
-cnt * BDRV_SECTOR_SIZE;
+s->common.len = s->common.offset + s->bytes_in_flight + cnt;

 /* Note that even when no rate limit is applied we need to yield
  * periodically with no pending I/O so that bdrv_drain_all() returns.
@@ -827,8 +825,7 @@ static void coroutine_fn mirror_run(void *opaque)
 s->common.iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
 if (s->in_flight >= MAX_IN_FLIGHT || s->buf_free_count == 0 ||
 (cnt == 0 && s->in_flight > 0)) {
-trace_mirror_yield(s, cnt * BDRV_SECTOR_SIZE,
-   s->buf_free_count, s->in_flight);
+trace_mirror_yield(s, cnt, s->buf_free_count, s->in_flight);
 mirror_wait_for_io(s);
 continue;
 } else if (cnt != 0) {
@@ -869,7 +866,7 @@ static void coroutine_fn mirror_run(void *opaque)
  * whether to switch to target check one last time if I/O has
  * come in the meanwhile, and if not flush the data to disk.
  */
-trace_mirror_before_drain(s, cnt * BDRV_SECTOR_SIZE);
+trace_mirror_before_drain(s, cnt);

 bdrv_drained_begin(bs);
 cnt = bdrv_get_dirty_count(s->dirty_bitmap);
@@ -888,8 +885,7 @@ static void coroutine_fn mirror_run(void *opaque)
 }

 ret = 0;
-trace_mirror_before_sleep(s, cnt * BDRV_SECTOR_SIZE,
-  s->synced, delay_ns);
+trace_mirror_before_sleep(s, cnt, s->synced, delay_ns);
 if (!s->synced) {
 block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
 if (block_job_is_cancelled(&s->common)) {
diff --git a/migration/block.c b/migration/block.c
index 9171f60028..a3512945da 100644
--- a/migration/block.c
+++ b/migration/block.c
@@ -667,7 +667,7 @@ static int64_t get_remaining_dirty(void)
 aio_context_release(blk_get_aio_context(bmds->blk));
 }

-return dirty << BDRV_SECTOR_BITS;
+return dirty;
 }


-- 
2.13.5




[Qemu-devel] [PATCH v7 20/20] dirty-bitmap: Convert internal hbitmap size/granularity

2017-09-12 Thread Eric Blake
Now that all callers are using byte-based interfaces, there's no
reason for our internal hbitmap to remain with sector-based
granularity.  It also simplifies our internal scaling, since we
already know that hbitmap widens requests out to granularity
boundaries.

Signed-off-by: Eric Blake 
Reviewed-by: John Snow 

---
v7: rebase to dirty_iter_next cleanup (no semantic change, R-b kept)
v6: no change
v5: fix bdrv_dirty_bitmap_truncate [John]
v4: rebase to earlier changes, include serialization, R-b dropped
v3: no change
v2: no change
---
 block/dirty-bitmap.c | 62 +++-
 1 file changed, 18 insertions(+), 44 deletions(-)

diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index dd91f56b94..c2322c2619 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -38,7 +38,7 @@
  */
 struct BdrvDirtyBitmap {
 QemuMutex *mutex;
-HBitmap *bitmap;/* Dirty sector bitmap implementation */
+HBitmap *bitmap;/* Dirty bitmap implementation */
 HBitmap *meta;  /* Meta dirty bitmap */
 BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
 char *name; /* Optional non-empty unique ID */
@@ -130,12 +130,7 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState 
*bs,
 }
 bitmap = g_new0(BdrvDirtyBitmap, 1);
 bitmap->mutex = &bs->dirty_bitmap_mutex;
-/*
- * TODO - let hbitmap track full granularity. For now, it is tracking
- * only sector granularity, as a shortcut for our iterators.
- */
-bitmap->bitmap = hbitmap_alloc(DIV_ROUND_UP(bitmap_size, BDRV_SECTOR_SIZE),
-   ctz32(granularity) - BDRV_SECTOR_BITS);
+bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(granularity));
 bitmap->size = bitmap_size;
 bitmap->name = g_strdup(name);
 bitmap->disabled = false;
@@ -316,7 +311,7 @@ int bdrv_dirty_bitmap_truncate(BlockDriverState *bs)
 QLIST_FOREACH(bitmap, &bs->dirty_bitmaps, list) {
 assert(!bdrv_dirty_bitmap_frozen(bitmap));
 assert(!bitmap->active_iterators);
-hbitmap_truncate(bitmap->bitmap, DIV_ROUND_UP(size, BDRV_SECTOR_SIZE));
+hbitmap_truncate(bitmap->bitmap, size);
 bitmap->size = size;
 }
 bdrv_dirty_bitmaps_unlock(bs);
@@ -447,7 +442,7 @@ bool bdrv_get_dirty_locked(BlockDriverState *bs, 
BdrvDirtyBitmap *bitmap,
int64_t offset)
 {
 if (bitmap) {
-return hbitmap_get(bitmap->bitmap, offset >> BDRV_SECTOR_BITS);
+return hbitmap_get(bitmap->bitmap, offset);
 } else {
 return false;
 }
@@ -475,7 +470,7 @@ uint32_t 
bdrv_get_default_bitmap_granularity(BlockDriverState *bs)

 uint32_t bdrv_dirty_bitmap_granularity(const BdrvDirtyBitmap *bitmap)
 {
-return BDRV_SECTOR_SIZE << hbitmap_granularity(bitmap->bitmap);
+return 1U << hbitmap_granularity(bitmap->bitmap);
 }

 BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap)
@@ -508,20 +503,16 @@ void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter)

 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)
 {
-int64_t ret = hbitmap_iter_next(&iter->hbi);
-return ret < 0 ? -1 : ret * BDRV_SECTOR_SIZE;
+return hbitmap_iter_next(&iter->hbi);
 }

 /* Called within bdrv_dirty_bitmap_lock..unlock */
 void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
   int64_t offset, int64_t bytes)
 {
-int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
-
 assert(bdrv_dirty_bitmap_enabled(bitmap));
 assert(!bdrv_dirty_bitmap_readonly(bitmap));
-hbitmap_set(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
-end_sector - (offset >> BDRV_SECTOR_BITS));
+hbitmap_set(bitmap->bitmap, offset, bytes);
 }

 void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
@@ -536,12 +527,9 @@ void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
 void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
 int64_t offset, int64_t bytes)
 {
-int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
-
 assert(bdrv_dirty_bitmap_enabled(bitmap));
 assert(!bdrv_dirty_bitmap_readonly(bitmap));
-hbitmap_reset(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
-  end_sector - (offset >> BDRV_SECTOR_BITS));
+hbitmap_reset(bitmap->bitmap, offset, bytes);
 }

 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
@@ -561,8 +549,7 @@ void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, 
HBitmap **out)
 hbitmap_reset_all(bitmap->bitmap);
 } else {
 HBitmap *backup = bitmap->bitmap;
-bitmap->bitmap = hbitmap_alloc(DIV_ROUND_UP(bitmap->size,
-BDRV_SECTOR_SIZE),
+bitmap->bitmap = hbitmap_alloc(bitmap->size,
hbitmap_granularity(backup));
 *out = backup;
 }
@@ -581,51 +

[Qemu-devel] [PATCH v7 14/20] dirty-bitmap: Change bdrv_[re]set_dirty_bitmap() to use bytes

2017-09-12 Thread Eric Blake
Some of the callers were already scaling bytes to sectors; others
can be easily converted to pass byte offsets, all in our shift
towards a consistent byte interface everywhere.  Making the change
will also make it easier to write the hold-out callers to use byte
rather than sectors for their iterations; it also makes it easier
for a future dirty-bitmap patch to offload scaling over to the
internal hbitmap.  Although all callers happen to pass
sector-aligned values, make the internal scaling robust to any
sub-sector requests.

Signed-off-by: Eric Blake 
Reviewed-by: John Snow 

---
v5: only context change
v4: only context change, due to rebasing to persistent bitmaps
v3: rebase to addition of _locked interfaces; complex enough that I
dropped R-b
v2: no change
---
 include/block/dirty-bitmap.h |  8 
 block/dirty-bitmap.c | 22 ++
 block/mirror.c   | 16 
 migration/block.c|  7 +--
 4 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
index 94a8d76f26..252bb25c8e 100644
--- a/include/block/dirty-bitmap.h
+++ b/include/block/dirty-bitmap.h
@@ -40,9 +40,9 @@ const char *bdrv_dirty_bitmap_name(const BdrvDirtyBitmap 
*bitmap);
 int64_t bdrv_dirty_bitmap_size(const BdrvDirtyBitmap *bitmap);
 DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap);
 void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
-   int64_t cur_sector, int64_t nr_sectors);
+   int64_t offset, int64_t bytes);
 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
- int64_t cur_sector, int64_t nr_sectors);
+ int64_t offset, int64_t bytes);
 BdrvDirtyBitmapIter *bdrv_dirty_meta_iter_new(BdrvDirtyBitmap *bitmap);
 BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap);
 void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter);
@@ -75,9 +75,9 @@ void bdrv_dirty_bitmap_unlock(BdrvDirtyBitmap *bitmap);
 bool bdrv_get_dirty_locked(BlockDriverState *bs, BdrvDirtyBitmap *bitmap,
int64_t offset);
 void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
-  int64_t cur_sector, int64_t nr_sectors);
+  int64_t offset, int64_t bytes);
 void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
-int64_t cur_sector, int64_t nr_sectors);
+int64_t offset, int64_t bytes);
 int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter);
 void bdrv_set_dirty_iter(BdrvDirtyBitmapIter *hbi, int64_t offset);
 int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index 96b15d232a..b1bbb98653 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -514,35 +514,41 @@ int64_t bdrv_dirty_iter_next(BdrvDirtyBitmapIter *iter)

 /* Called within bdrv_dirty_bitmap_lock..unlock */
 void bdrv_set_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
-  int64_t cur_sector, int64_t nr_sectors)
+  int64_t offset, int64_t bytes)
 {
+int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
+
 assert(bdrv_dirty_bitmap_enabled(bitmap));
 assert(!bdrv_dirty_bitmap_readonly(bitmap));
-hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
+hbitmap_set(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
+end_sector - (offset >> BDRV_SECTOR_BITS));
 }

 void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
-   int64_t cur_sector, int64_t nr_sectors)
+   int64_t offset, int64_t bytes)
 {
 bdrv_dirty_bitmap_lock(bitmap);
-bdrv_set_dirty_bitmap_locked(bitmap, cur_sector, nr_sectors);
+bdrv_set_dirty_bitmap_locked(bitmap, offset, bytes);
 bdrv_dirty_bitmap_unlock(bitmap);
 }

 /* Called within bdrv_dirty_bitmap_lock..unlock */
 void bdrv_reset_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
-int64_t cur_sector, int64_t nr_sectors)
+int64_t offset, int64_t bytes)
 {
+int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
+
 assert(bdrv_dirty_bitmap_enabled(bitmap));
 assert(!bdrv_dirty_bitmap_readonly(bitmap));
-hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors);
+hbitmap_reset(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
+  end_sector - (offset >> BDRV_SECTOR_BITS));
 }

 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
- int64_t cur_sector, int64_t nr_sectors)
+ int64_t offset, int64_t bytes)
 {
 bdrv_dirty_bitmap_lock(bitmap);
-bdrv_reset_dirty_bitmap_locked(bitmap, cur_sector, nr_sectors);
+bdrv_reset_dirty_bitmap_locked(bitmap, offset, bytes);
 bdrv_dir

[Qemu-devel] [PATCH v7 16/20] qcow2: Switch qcow2_measure() to byte-based iteration

2017-09-12 Thread Eric Blake
This is new code, but it is easier to read if it makes passes over
the image using bytes rather than sectors (and will get easier in
the future when bdrv_get_block_status is converted to byte-based).

Signed-off-by: Eric Blake 
Reviewed-by: John Snow 

---
v7: tweak constant given to MIN (no semantic change, R-b kept) [Kevin]
v6: separate bug fix to earlier patch
v5: new patch
---
 block/qcow2.c | 22 ++
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index bae5893327..64dcd98a91 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3647,20 +3647,19 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, 
BlockDriverState *in_bs,
  */
 required = virtual_size;
 } else {
-int cluster_sectors = cluster_size / BDRV_SECTOR_SIZE;
-int64_t sector_num;
+int64_t offset;
 int pnum = 0;

-for (sector_num = 0;
- sector_num < ssize / BDRV_SECTOR_SIZE;
- sector_num += pnum) {
-int nb_sectors = MIN(ssize / BDRV_SECTOR_SIZE - sector_num,
- BDRV_REQUEST_MAX_SECTORS);
+for (offset = 0; offset < ssize;
+ offset += pnum * BDRV_SECTOR_SIZE) {
+int nb_sectors = MIN(ssize - offset,
+ BDRV_REQUEST_MAX_BYTES) / 
BDRV_SECTOR_SIZE;
 BlockDriverState *file;
 int64_t ret;

 ret = bdrv_get_block_status_above(in_bs, NULL,
-  sector_num, nb_sectors,
+  offset >> BDRV_SECTOR_BITS,
+  nb_sectors,
   &pnum, &file);
 if (ret < 0) {
 error_setg_errno(&local_err, -ret,
@@ -3673,12 +3672,11 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, 
BlockDriverState *in_bs,
 } else if ((ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) ==
(BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) {
 /* Extend pnum to end of cluster for next iteration */
-pnum = ROUND_UP(sector_num + pnum, cluster_sectors) -
-   sector_num;
+pnum = (ROUND_UP(offset + pnum * BDRV_SECTOR_SIZE,
+ cluster_size) - offset) >> BDRV_SECTOR_BITS;

 /* Count clusters we've seen */
-required += (sector_num % cluster_sectors + pnum) *
-BDRV_SECTOR_SIZE;
+required += offset % cluster_size + pnum * 
BDRV_SECTOR_SIZE;
 }
 }
 }
-- 
2.13.5




[Qemu-devel] [PATCH v7 15/20] mirror: Switch mirror_dirty_init() to byte-based iteration

2017-09-12 Thread Eric Blake
Now that we have adjusted the majority of the calls this function
makes to be byte-based, it is easier to read the code if it makes
passes over the image using bytes rather than sectors.

Signed-off-by: Eric Blake 
Reviewed-by: John Snow 

---
v6: no change
v5: rebase to earlier changes
v2-v4: no change
---
 block/mirror.c | 38 ++
 1 file changed, 14 insertions(+), 24 deletions(-)

diff --git a/block/mirror.c b/block/mirror.c
index c2f73c91c5..5cdaaed7be 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -612,15 +612,13 @@ static void mirror_throttle(MirrorBlockJob *s)

 static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
 {
-int64_t sector_num, end;
+int64_t offset;
 BlockDriverState *base = s->base;
 BlockDriverState *bs = s->source;
 BlockDriverState *target_bs = blk_bs(s->target);
-int ret, n;
+int ret;
 int64_t count;

-end = s->bdev_length / BDRV_SECTOR_SIZE;
-
 if (base == NULL && !bdrv_has_zero_init(target_bs)) {
 if (!bdrv_can_write_zeroes_with_unmap(target_bs)) {
 bdrv_set_dirty_bitmap(s->dirty_bitmap, 0, s->bdev_length);
@@ -628,9 +626,9 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
 }

 s->initial_zeroing_ongoing = true;
-for (sector_num = 0; sector_num < end; ) {
-int nb_sectors = MIN(end - sector_num,
-QEMU_ALIGN_DOWN(INT_MAX, s->granularity) >> BDRV_SECTOR_BITS);
+for (offset = 0; offset < s->bdev_length; ) {
+int bytes = MIN(s->bdev_length - offset,
+QEMU_ALIGN_DOWN(INT_MAX, s->granularity));

 mirror_throttle(s);

@@ -646,9 +644,8 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
 continue;
 }

-mirror_do_zero_or_discard(s, sector_num * BDRV_SECTOR_SIZE,
-  nb_sectors * BDRV_SECTOR_SIZE, false);
-sector_num += nb_sectors;
+mirror_do_zero_or_discard(s, offset, bytes, false);
+offset += bytes;
 }

 mirror_wait_for_all_io(s);
@@ -656,10 +653,10 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob 
*s)
 }

 /* First part, loop on the sectors and initialize the dirty bitmap.  */
-for (sector_num = 0; sector_num < end; ) {
+for (offset = 0; offset < s->bdev_length; ) {
 /* Just to make sure we are not exceeding int limit. */
-int nb_sectors = MIN(INT_MAX >> BDRV_SECTOR_BITS,
- end - sector_num);
+int bytes = MIN(s->bdev_length - offset,
+QEMU_ALIGN_DOWN(INT_MAX, s->granularity));

 mirror_throttle(s);

@@ -667,23 +664,16 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob 
*s)
 return 0;
 }

-ret = bdrv_is_allocated_above(bs, base, sector_num * BDRV_SECTOR_SIZE,
-  nb_sectors * BDRV_SECTOR_SIZE, &count);
+ret = bdrv_is_allocated_above(bs, base, offset, bytes, &count);
 if (ret < 0) {
 return ret;
 }

-/* TODO: Relax this once bdrv_is_allocated_above and dirty
- * bitmaps no longer require sector alignment. */
-assert(QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE));
-n = count >> BDRV_SECTOR_BITS;
-assert(n > 0);
+assert(count);
 if (ret == 1) {
-bdrv_set_dirty_bitmap(s->dirty_bitmap,
-  sector_num * BDRV_SECTOR_SIZE,
-  n * BDRV_SECTOR_SIZE);
+bdrv_set_dirty_bitmap(s->dirty_bitmap, offset, count);
 }
-sector_num += n;
+offset += count;
 }
 return 0;
 }
-- 
2.13.5




Re: [Qemu-devel] [PATCH 02/10] qemu-iotests: get rid of AWK_PROG

2017-09-12 Thread Eric Blake
On 09/12/2017 09:44 AM, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini 
> ---
>  tests/qemu-iotests/check | 4 ++--
>  tests/qemu-iotests/common| 2 +-
>  tests/qemu-iotests/common.config | 3 ---
>  3 files changed, 3 insertions(+), 6 deletions(-)

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v7 17/20] qcow2: Switch load_bitmap_data() to byte-based iteration

2017-09-12 Thread Eric Blake
Now that we have adjusted the majority of the calls this function
makes to be byte-based, it is easier to read the code if it makes
passes over the image using bytes rather than sectors.

Signed-off-by: Eric Blake 
Reviewed-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 

---
v5: no change
v4: new patch
---
 block/qcow2-bitmap.c | 22 --
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index b09010b1d3..692ce0de88 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -291,9 +291,8 @@ static int load_bitmap_data(BlockDriverState *bs,
 {
 int ret = 0;
 BDRVQcow2State *s = bs->opaque;
-uint64_t sector, limit, sbc;
+uint64_t offset, limit;
 uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
-uint64_t bm_sectors = DIV_ROUND_UP(bm_size, BDRV_SECTOR_SIZE);
 uint8_t *buf = NULL;
 uint64_t i, tab_size =
 size_to_clusters(s,
@@ -305,32 +304,27 @@ static int load_bitmap_data(BlockDriverState *bs,

 buf = g_malloc(s->cluster_size);
 limit = bytes_covered_by_bitmap_cluster(s, bitmap);
-sbc = limit >> BDRV_SECTOR_BITS;
-for (i = 0, sector = 0; i < tab_size; ++i, sector += sbc) {
-uint64_t count = MIN(bm_sectors - sector, sbc);
+for (i = 0, offset = 0; i < tab_size; ++i, offset += limit) {
+uint64_t count = MIN(bm_size - offset, limit);
 uint64_t entry = bitmap_table[i];
-uint64_t offset = entry & BME_TABLE_ENTRY_OFFSET_MASK;
+uint64_t data_offset = entry & BME_TABLE_ENTRY_OFFSET_MASK;

 assert(check_table_entry(entry, s->cluster_size) == 0);

-if (offset == 0) {
+if (data_offset == 0) {
 if (entry & BME_TABLE_ENTRY_FLAG_ALL_ONES) {
-bdrv_dirty_bitmap_deserialize_ones(bitmap,
-   sector * BDRV_SECTOR_SIZE,
-   count * BDRV_SECTOR_SIZE,
+bdrv_dirty_bitmap_deserialize_ones(bitmap, offset, count,
false);
 } else {
 /* No need to deserialize zeros because the dirty bitmap is
  * already cleared */
 }
 } else {
-ret = bdrv_pread(bs->file, offset, buf, s->cluster_size);
+ret = bdrv_pread(bs->file, data_offset, buf, s->cluster_size);
 if (ret < 0) {
 goto finish;
 }
-bdrv_dirty_bitmap_deserialize_part(bitmap, buf,
-   sector * BDRV_SECTOR_SIZE,
-   count * BDRV_SECTOR_SIZE,
+bdrv_dirty_bitmap_deserialize_part(bitmap, buf, offset, count,
false);
 }
 }
-- 
2.13.5




[Qemu-devel] [PATCH v7 19/20] dirty-bitmap: Switch bdrv_set_dirty() to bytes

2017-09-12 Thread Eric Blake
Both callers already had bytes available, but were scaling to
sectors.  Move the scaling to internal code.  In the case of
bdrv_aligned_pwritev(), we are now passing the exact offset
rather than a rounded sector-aligned value, but that's okay
as long as dirty bitmap widens start/bytes to granularity
boundaries.

Signed-off-by: Eric Blake 
Reviewed-by: John Snow 

---
v4: only context changes
v3: rebase to lock context changes, R-b kept
v2: no change
---
 include/block/block_int.h | 2 +-
 block/io.c| 6 ++
 block/dirty-bitmap.c  | 7 ---
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/include/block/block_int.h b/include/block/block_int.h
index ba4c383393..55c5d573d4 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -1021,7 +1021,7 @@ void blk_dev_eject_request(BlockBackend *blk, bool force);
 bool blk_dev_is_tray_open(BlockBackend *blk);
 bool blk_dev_is_medium_locked(BlockBackend *blk);

-void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector, int64_t nr_sect);
+void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes);
 bool bdrv_requests_pending(BlockDriverState *bs);

 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out);
diff --git a/block/io.c b/block/io.c
index 4378ae4c7d..8a0cd8835a 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1334,7 +1334,6 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild 
*child,
 bool waited;
 int ret;

-int64_t start_sector = offset >> BDRV_SECTOR_BITS;
 int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);
 uint64_t bytes_remaining = bytes;
 int max_transfer;
@@ -1409,7 +1408,7 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild 
*child,
 bdrv_debug_event(bs, BLKDBG_PWRITEV_DONE);

 atomic_inc(&bs->write_gen);
-bdrv_set_dirty(bs, start_sector, end_sector - start_sector);
+bdrv_set_dirty(bs, offset, bytes);

 stat64_max(&bs->wr_highest_offset, offset + bytes);

@@ -2438,8 +2437,7 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *bs, 
int64_t offset,
 ret = 0;
 out:
 atomic_inc(&bs->write_gen);
-bdrv_set_dirty(bs, req.offset >> BDRV_SECTOR_BITS,
-   req.bytes >> BDRV_SECTOR_BITS);
+bdrv_set_dirty(bs, req.offset, req.bytes);
 tracked_request_end(&req);
 bdrv_dec_in_flight(bs);
 return ret;
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index b1bbb98653..dd91f56b94 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -633,10 +633,10 @@ void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap 
*bitmap)
 hbitmap_deserialize_finish(bitmap->bitmap);
 }

-void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
-int64_t nr_sectors)
+void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes)
 {
 BdrvDirtyBitmap *bitmap;
+int64_t end_sector = DIV_ROUND_UP(offset + bytes, BDRV_SECTOR_SIZE);

 if (QLIST_EMPTY(&bs->dirty_bitmaps)) {
 return;
@@ -648,7 +648,8 @@ void bdrv_set_dirty(BlockDriverState *bs, int64_t 
cur_sector,
 continue;
 }
 assert(!bdrv_dirty_bitmap_readonly(bitmap));
-hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
+hbitmap_set(bitmap->bitmap, offset >> BDRV_SECTOR_BITS,
+end_sector - (offset >> BDRV_SECTOR_BITS));
 }
 bdrv_dirty_bitmaps_unlock(bs);
 }
-- 
2.13.5




Re: [Qemu-devel] [PATCH 01/10] qemu-iotests: remove dead code

2017-09-12 Thread Eric Blake
On 09/12/2017 09:44 AM, Paolo Bonzini wrote:
> This includes shell function, shell variables and command line options
> (randomize.awk does not exist).
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  tests/qemu-iotests/check | 28 -
>  tests/qemu-iotests/common| 23 --
>  tests/qemu-iotests/common.config | 26 ---
>  tests/qemu-iotests/common.rc | 68 
> 
>  4 files changed, 145 deletions(-)

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v2 07/16] target/arm: Align vector registers

2017-09-12 Thread Philippe Mathieu-Daudé

-    float64 regs[64];
+    float64 regs[64] __attribute__((aligned(16)));


I understand this should be aligned to the biggest vector register the 
host support, i.e. for AVX-512 this would be QEMU_ALIGNED(64), is it 
correct?




checking datashits:

"INTEL® ADVANCED VECTOR EXTENSIONS"

2.5 MEMORY ALIGNMENT

With the exception of explicitly aligned 16 or 32 byte SIMD load/store 
instructions, most VEX-encoded, arithmetic and data processing 
instructions operate in a flexible environment regarding memory address 
alignment, i.e. VEX-encoded instruction with 32-byte or 16-byte load 
semantics will support unaligned load operation by default. Memory 
arguments for most instructions with VEX prefix operate normally without 
causing #GP(0) on any byte-granularity alignment (unlike Legacy SSE 
instructions). The instructions that require explicit memory alignment 
requirements are listed in Table 2-4.


Table 2-4. Instructions Requiring Explicitly Aligned Memory

Require 32-byte alignment:
  VMOVDQA ymm, m256
  VMOVDQA m256, ymm
  VMOVAPS ymm, m256
  VMOVAPS m256, ymm
  VMOVAPD ymm, m256
  VMOVAPD m256, ymm
  VMOVNTPS m256, ymm
  VMOVNTPD m256, ymm
  VMOVNTDQ m256, ymm
  VMOVNTDQA ymm, m256

General Protection, #GP(0):
  VEX.256: Memory operand is not 32-byte aligned
  VEX.128: Memory operand is not 16-byte aligned
  Legacy SSE: Memory operand is not 16-byte aligned

--

"Intel® Architecture Instruction Set Extensions Programming Reference"

2.6 MEMORY ALIGNMENT

Memory alignment requirements on EVEX-encoded SIMD instructions are 
similar to VEX-encoded SIMD instructions. Memory alignment applies to 
EVEX-encoded SIMD instructions in three categories:
• Explicitly-aligned SIMD load and store instructions accessing 64 bytes 
of memory with EVEX prefix encoded vector length of 512 bits (e.g., 
VMOVAPD, VMOVAPS, VMOVDQA, etc.). These instructions always require

memory address to be aligned on 64-byte boundary.
• Explicitly-unaligned SIMD load and store instructions accessing 64 
bytes or less of data from memory (e.g. VMOVUPD, VMOVUPS, VMOVDQU, 
VMOVQ, VMOVD, etc.). These instructions do not require memory address

to be aligned on natural vector-length byte boundary.
• Most arithmetic and data processing instructions encoded using EVEX 
support memory access semantics. When these instructions access from 
memory, there are no alignment restrictions.

[...]
AVX-512 instructions may generate an #AC(0) fault on misaligned 4 or 
8-byte memory references in Ring-3 when CR0.AM=1. 16, 32 and 64-byte 
memory references will not generate #AC(0) fault. See Table 2-7 for details.
Certain AVX-512 Foundation instructions always require 64-byte alignment 
(see the complete list of VEX and EVEX encoded instructions in Table 
2-6). These instructions will #GP(0) if not aligned to 64-byte boundaries.




Re: [Qemu-devel] [PATCH] tcg/ppc: disable atomic write check on ppc32

2017-09-12 Thread Philippe Mathieu-Daudé

On 09/12/2017 02:01 PM, Richard Henderson wrote:

On 09/11/2017 01:49 PM, Philippe Mathieu-Daudé wrote:

-atomic_set((uint64_t *)jmp_addr, pair);
+atomic_set__nocheck((uint64_t *)jmp_addr, pair);
  flush_icache_range(jmp_addr, jmp_addr + 8);
  } else {
  intptr_t diff = addr - jmp_addr;



Queued, thanks.


Thanks Richard for adding the comment requested by Peter!



Re: [Qemu-devel] [PATCH v4 0/8] More warning reporting fixed

2017-09-12 Thread Paolo Bonzini
On 11/09/2017 21:52, Alistair Francis wrote:
> This series expands on my previous series by converting more existing
> prints to use warn_report() instead of error_report() or fprintf().
> 
> As discussed with Paolo and Markus this series combines libqemustub.a into
> libqemuutil.a to avoid circular dependencies.
> 
> V4:
>  - Improve some extra MIPs messages
>  - Fix build issues
>  - Fix i386 print message
> V3:
>  - Small corrections as reported by Markus
>  - Rename patch 3 and 5 so they don't have the same name
>  - Combine libqemustub.a into libqemuutil.a
>  - Add an extra patch with general cleanups
> 
> V2:
>  - Fixup auto CC logic so everyone is CCed
> 
> 
> 
> Alistair Francis (8):
>   hw/i386: Improve some of the warning messages
>   Convert remaining error_report() to warn_report()
>   Convert single line fprintf(.../n) to warn_report()
>   Convert multi-line fprintf() to warn_report()
>   General warn report fixups
>   target/mips: Convert VM clock update prints to warn_report
>   Makefile: Remove libqemustub.a
>   Convert remaining single line fprintf() to warn_report()
> 
>  Makefile|  7 +++
>  Makefile.target |  2 +-
>  accel/kvm/kvm-all.c |  7 +++
>  block/qcow2.c   |  9 +
>  block/vvfat.c   |  7 ---
>  docs/devel/build-system.txt | 16 +++-
>  hw/acpi/core.c  | 10 +-
>  hw/arm/vexpress.c   |  4 ++--
>  hw/i386/acpi-build.c| 15 ++-
>  hw/i386/pc.c|  9 -
>  hw/i386/pc_q35.c|  8 +---
>  hw/i386/xen/xen-mapcache.c  |  5 +++--
>  hw/mips/mips_malta.c|  4 ++--
>  hw/mips/mips_r4k.c  |  5 ++---
>  hw/misc/applesmc.c  |  2 +-
>  hw/s390x/s390-virtio.c  | 18 ++
>  hw/usb/hcd-ehci.c   |  5 +++--
>  hw/virtio/virtio-balloon.c  |  3 ++-
>  net/hub.c   | 10 --
>  net/net.c   | 15 ---
>  qga/vss-win32.c |  2 +-
>  target/i386/cpu.c   | 12 ++--
>  target/i386/hax-mem.c   |  6 +++---
>  target/mips/kvm.c   | 10 +-
>  target/ppc/translate_init.c | 17 -
>  target/s390x/kvm.c  |  4 ++--
>  tests/Makefile.include  |  8 
>  trace/control.c |  4 ++--
>  trace/simple.c  |  3 ++-
>  ui/keymaps.c| 10 +-
>  ui/spice-display.c  |  2 +-
>  util/cutils.c   |  3 ++-
>  util/main-loop.c|  6 +++---
>  33 files changed, 128 insertions(+), 120 deletions(-)
> 

Queued, thanks.

Paolo



[Qemu-devel] [PATCH v5 00/22] instrument: Add basic event instrumentation

2017-09-12 Thread Lluís Vilanova
This series adds an API to add instrumentation events.

It also provides additional APIs for:
* Controlling tracing events.
* Peek/poke guest memory.

TODO:
* Replace qi_event_gen_* with generating calls to arbitrary functions (e.g.,
  qi_event_gen_call(num_args, va_list)).
* Flush all TBs when an execution-time event is unset (to ensure it won't be
  called in the future).
* Flush all TBs when a translation-time event is set (to ensure no future events
  will be lost).

Undecided:
* Alternatively to the two last points above, provide an API to request a TB
  flush (much more flexible and can be more efficient, but requires instrumentor
  to clearly know differences between translation and execution).
* Pass a user-provided pointer to events (i.e., to avoid using global
  variables).
* Provide something like tracing's per-vCPU trace states (i.e., so that each
  vCPU can have different instrumentation code). Useful mainly for sampling
  (enable/disable instrumentation multiple times without re-translating guest
  code) and more complex use cases like tracing a guest process in softmmu mode.
  It's still not clear to me if we should extend the per-vCPU bitmap with
  instrumentation events, or otherwise somehow reuse the bits in tracing events
  (since they're currently limited).
* Allow multiple callbacks per event (both to support multiple callbacks
  installed by a library, and multiple libraries at the same time).
* Allow instr libraries to iterate on the list of guest CPUs (info is already
  available through guest_cpu_enter/guest_cpu_exit, but forces libs to be
  prepared for hot-plugging guest CPUs).

Future APIs (for later series):
* Peek/poke guest registers.
* Add breakpoints to trigger instrumentation functions.
* Trigger instrumentation functions from guest code (former hypertrace).
* Add events for guest code translation/execution (once the respective tracing
  events are accepted upstream).
* Add events for exceptions/syscalls.
* Add events for TB invalidation (necessary for libraries to deallocate any data
  they might have allocated for the TBs they instrumented).

The instrumentation code is dynamically loaded as a library into QEMU either
when it starts or later using its remote control interfaces. The loaded code
only has access to function explicitly exported through the QI_VPUBLIC macro.

This series is branch 'devel-instrument' in
https://code.gso.ac.upc.edu/git/qemu-dbi.

Signed-off-by: Lluís Vilanova 
---

Changes in v5
=

* Rebase on fcea73709b.
* Minor changes to pass checkpatch.
* Fix symbol availability to external libraries by adding missing default symbol
  visibility flag.
* Use a string to identify instrumentation handles [Markus Armbruster].
* Use stubs for command line initialization.
* Use stubs to signal unsupported QAPI commands [Markus Armbruster].
* Use error messages instead of codes in QAPI commands [Markus Armbruster].
* Move symbol visibility macros to internal "qemu/compiler.h" header.
* Trigger event 'guest_cpu_enter' when library is loaded.
* Trigger event 'guest_cpu_exit' and flush TBs when library is unloaded.
* Rename instr_cpu_get/instr_cpu_set into clearer
  instr_cpu_to_qicpu/instr_cpu_from_qicpu.
* Rename handle_get/handle_put to clearer handle_new/handle_destroy.
* Ensure qi_event_set_* are called only on the proper mode and targets.


Changes in v4
=

* Add missing stub function.


Changes in v3
=

* Use a separate event set for instrumentation (i.e., do not instrument tracing
  events) [Stefan Hajnoczi].
* Add API for peek/poke guest memory.


Changes in v2
=

* Update QEMU version in QAPI [Eric Blake].
* Clarify 'msg' result in QAPI is for humans only.
* Make 'msg' and 'handle' results optional in QAPI.
* Use a list of 'str' in 'instr-load' QAPI command.
* Update MAINTAINERS.
* Add macros for error-reporting in API.


Lluís Vilanova (22):
  instrument: Add documentation
  instrument: Add configure-time flag
  instrument: Add generic library loader
  instrument: [linux-user] Add command line library loader
  instrument: [bsd-user] Add command line library loader
  instrument: [softmmu] Add command line library loader
  instrument: [qapi] Add library loader
  instrument: [hmp] Add library loader
  instrument: Add basic control interface
  instrument: Add support for tracing events
  instrument: Track vCPUs
  instrument: Add event 'guest_cpu_enter'
  instrument: Support synchronous modification of vCPU state
  exec: Add function to synchronously flush TB on a stopped vCPU
  instrument: Add event 'guest_cpu_exit'
  instrument: Add event 'guest_cpu_reset'
  trace: Introduce a proper structure to describe memory accesses
  instrument: Add event 'guest_mem_before_trans'
  instrument: Add event 'guest_mem_before_exec'
  instrument: Add event 'guest_user_syscall'
  instrument: Add event 'guest_user_syscall_ret'
  instrument: Add

Re: [Qemu-devel] [PATCH 03/10] qemu-iotests: move "check" code out of common.rc

2017-09-12 Thread Eric Blake
On 09/12/2017 09:44 AM, Paolo Bonzini wrote:
> Some functions in common.rc are never used by the tests.  Move
> them out of that file and into common, which is already included
> only by "check".
> 
> Code that actually *is* common to "check" and tests can be placed in
> common.config.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  tests/qemu-iotests/common| 25 -
>  tests/qemu-iotests/common.config | 12 
>  tests/qemu-iotests/common.rc | 40 
> 
>  3 files changed, 36 insertions(+), 41 deletions(-)
> 
Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH] tcg/ppc: disable atomic write check on ppc32

2017-09-12 Thread Paolo Bonzini
On 11/09/2017 23:37, Peter Maydell wrote:
> On 11 September 2017 at 21:49, Philippe Mathieu-Daudé  wrote:
>> this fixes building for ppc64 on ppc32 (changed in 5964fca8a12c):
>>
>>   qemu/tcg/ppc/tcg-target.inc.c: In function 'tb_target_set_jmp_target':
>>   qemu/include/qemu/compiler.h:86:30: error: static assertion failed: "not 
>> expecting: sizeof(*(uint64_t *)jmp_addr) > ATOMIC_REG_SIZE"
>>QEMU_BUILD_BUG_ON(sizeof(*ptr) > ATOMIC_REG_SIZE); \
>>^
>>   qemu/tcg/ppc/tcg-target.inc.c:1377:9: note: in expansion of macro 
>> 'atomic_set'
>>atomic_set((uint64_t *)jmp_addr, pair);
>>^
>>
>> Suggested-by: Richard Henderson 
>> Signed-off-by: Philippe Mathieu-Daudé 
>> ---
>> This fixes Shippable builds, see:
>> https://app.shippable.com/github/qemu/qemu/runs/434/10/console
>>
>>  tcg/ppc/tcg-target.inc.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c
>> index 21d764c102..0417901289 100644
>> --- a/tcg/ppc/tcg-target.inc.c
>> +++ b/tcg/ppc/tcg-target.inc.c
>> @@ -1374,7 +1374,7 @@ void tb_target_set_jmp_target(uintptr_t tc_ptr, 
>> uintptr_t jmp_addr,
>>  pair = (uint64_t)i2 << 32 | i1;
>>  #endif
>>
>> -atomic_set((uint64_t *)jmp_addr, pair);
>> +atomic_set__nocheck((uint64_t *)jmp_addr, pair);
>>  flush_icache_range(jmp_addr, jmp_addr + 8);
>>  } else {
>>  intptr_t diff = addr - jmp_addr;
> 
> Can you explain why this is the right thing? On the
> face of it it looks correct to insist that we don't
> try to do an atomic set of something that's bigger
> than the host can actually handle...

Probably because this code is guarded by "if (TCG_TARGET_REG_BITS ==
64)", so actually it only ever runs with 64-bit targets.

I wonder if QEMU_BUILD_BUG_ON (at least in atomics) should not use a
static assertion, but rather the 'error ("MESSAGE")' attribute instead.
This way, if the code is dead it does not cause a build failure.

Paolo



[Qemu-devel] [PATCH v5 01/22] instrument: Add documentation

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 MAINTAINERS |6 ++
 docs/instrument.txt |  173 +++
 2 files changed, 179 insertions(+)
 create mode 100644 docs/instrument.txt

diff --git a/MAINTAINERS b/MAINTAINERS
index 36eeb42d19..fb0eaee06a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1486,6 +1486,12 @@ F: scripts/tracetool/
 F: docs/tracing.txt
 T: git git://github.com/stefanha/qemu.git tracing
 
+Event instrumentation
+M: Lluís Vilanova 
+M: Stefan Hajnoczi 
+S: Maintained
+F: docs/instrument.txt
+
 TPM
 S: Orphan
 F: tpm.c
diff --git a/docs/instrument.txt b/docs/instrument.txt
new file mode 100644
index 00..24a0d21fc7
--- /dev/null
+++ b/docs/instrument.txt
@@ -0,0 +1,173 @@
+= Event instrumentation =
+
+== Introduction ==
+
+Event instrumentation allows users to execute their own host-native code on a
+set of pre-defined events provided by QEMU. QEMU also exposes other
+functionality to peek/poke at the guest state (e.g., memory or registers), as
+well as interacting with tracing events. For those familiar with the term, this
+provides dynamic binary instrumentation, works on all QEMU-supported
+architectures, as well as works in both 'user' (standalone application) and
+'system' (full-system emulation) modes.
+
+Look at the headers installed by QEMU on the "qemu-instr" directory for further
+information beyond this document.
+
+
+== Loading an instrumentation library ==
+
+Instrumentation code can be bundled into a dynamic library, which can be later
+loaded into QEMU:
+
+* Using the command-line "-instr" argument.
+
+* Using the "instr-load" and "instr-unload" commands in the HMP and QMP
+  interfaces.
+
+
+== Example ==
+
+1. Configure QEMU with event instrumentation:
+
+# instrument guest_cpu_enter and guest_mem_before
+mkdir -p /path/to/qemu-build
+cd /path/to/qemu-build
+/path/to/qemu-source/configure \
+  --enable-instrument \
+  --prefix=/path/to/qemu-install
+
+2. Build and install QEMU:
+
+make install
+
+3. Create the "Makefile" to build the instrumentation library:
+
+mkdir -p /tmp/my-instrument
+
+cat > /tmp/my-instrument/Makefile < /tmp/my-instrument/instrument.c <
+#include 
+
+#include  /* manipulate events */
+#include/* manipulate tracing */
+
+/* the address for the memory access is not known at translation time */
+void guest_mem_before_trans(QICPU vcpu_trans, QITCGv_cpu vcpu_exec,
+QITCGv vaddr, QIMemInfo info)
+{
+printf("%s: %p %p %p %d %d %d %d\n", __func__, vcpu_trans, vcpu_exec, 
vaddr,
+   1 << info.size_shift, info.sign_extend, info.endianness, 
info.store);
+if (info.store) {
+/* generate at execution time only for memory writes */
+qi_event_gen_guest_mem_before_exec(vcpu_exec, vaddr, info);
+}
+}
+
+/* called when QEMU executes a memory access */
+void guest_mem_before_exec(QICPU vcpu, uint64_t vaddr, QIMemInfo info)
+{
+if (info.store) {
+/* if called by TCG code, we'll only get writes (see above) */
+printf("%s: %p %lx %d %d %d %d\n", __func__, vcpu, vaddr,
+   1 << info.size_shift, info.sign_extend, info.endianness, 
info.store);
+}
+}
+
+/* called every time QEMU hotplugs a CPU */
+void guest_cpu_enter(QICPU vcpu)
+{
+printf("%s: %p\n", __func__, vcpu);
+
+/* disable instrumentation and tracing after the first call */
+static bool found = false;
+if (found) {
+qi_event_set_guest_cpu_enter(NULL);
+QITraceEvent *ev = qi_trace_event_name("guest_cpu_enter");
+assert(ev);
+qi_trace_event_set_state_dynamic(ev, true);
+} else {
+found = true;
+}
+}
+
+static void fini(void *data)
+{
+/* diable all tracing events */
+QITraceEventIter iter;
+qi_trace_event_iter_init(&iter, NULL);
+QITraceEvent *ev;
+while ((ev = qi_trace_event_iter_next(&iter)) != NULL) {
+if (qi_trace_event_get_state_static(ev)) {
+qi_trace_event_set_state_dynamic(ev, false);
+}
+}
+
+/* instrumentation callbacks are automatically reset by QEMU */
+}
+
+/* mandatory initialization function */
+int main(int argc, const char **argv)
+{
+int i;
+printf("init!\n");
+printf("argc :: %d\n", argc);
+for (i = 0; i < argc; i++) {
+printf("-> %s\n", argv[i]);
+}
+
+qi_set_fini(fini, NULL);
+
+/* instrument and trace events */
+QITraceEvent *ev;
+
+qi_event_set_guest_cpu_enter(guest_cpu_enter);
+ev = qi_trace_event_name("guest_cpu_enter");
+assert(ev);
+qi_trace_event_set_state_dynamic(ev, true);
+
+   

[Qemu-devel] [PATCH v5 02/22] instrument: Add configure-time flag

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 configure |9 +
 1 file changed, 9 insertions(+)

diff --git a/configure b/configure
index fd7e3a5e81..a21d1bceb9 100755
--- a/configure
+++ b/configure
@@ -356,6 +356,7 @@ pie=""
 qom_cast_debug="yes"
 trace_backends="log"
 trace_file="trace"
+instrument="no"
 spice=""
 rbd=""
 smartcard=""
@@ -886,6 +887,8 @@ for opt do
   ;;
   --with-trace-file=*) trace_file="$optarg"
   ;;
+  --enable-instrument) instrument="yes"
+  ;;
   --enable-gprof) gprof="yes"
   ;;
   --enable-gcov) gcov="yes"
@@ -1436,6 +1439,7 @@ Advanced options (experts only):
Available backends: $trace_backend_list
   --with-trace-file=NAME   Full PATH,NAME of file to store traces
Default:trace-
+  --enable-instrument  enable event instrumentation
   --disable-slirp  disable SLIRP userspace network connectivity
   --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI)
   --oss-libpath to OSS library
@@ -5366,6 +5370,7 @@ echo "Trace backends$trace_backends"
 if have_backend "simple"; then
 echo "Trace output file $trace_file-"
 fi
+echo "instrumentation   $instrument"
 echo "spice support $spice $(echo_version $spice 
$spice_protocol_version/$spice_server_version)"
 echo "rbd support   $rbd"
 echo "xfsctl support$xfs"
@@ -6019,6 +6024,10 @@ if have_backend "syslog"; then
 fi
 echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
 
+if test "$instrument" = "yes"; then
+  echo "CONFIG_INSTRUMENT=y" >> $config_host_mak
+fi
+
 if test "$rdma" = "yes" ; then
   echo "CONFIG_RDMA=y" >> $config_host_mak
 fi




[Qemu-devel] [Bug 1716767] [NEW] file(1) fails with "Invalid argument" on qemu-sh4-user

2017-09-12 Thread John Paul Adrian Glaubitz
Public bug reported:

We recently discovered that file(1) fails on qemu-sh4-user when running
on an ELF file:

(sid_sh4)root@vs94:/# file /bin/bash
/bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) error 
reading (Invalid argument)
(sid_sh4)root@vs94:/#

Running with "-d" yields more output:

(sid_sh4)root@vs94:/# file -d /bin/bash 2>&1 | tail
322: >> 7 byte&,=97,"(ARM)"]
0 == 97 = 0
mget(type=1, flag=0, offset=7, o=0, nbytes=863324, il=0, nc=1)
mget/96 @7: 
\000\000\000\000\000\000\000\000\000\002\000*\000\001\000\000\000\250\317A\0004\000\000\000L(\r\000\027\000\000\0004\000
 
\000\n\000(\000\032\000\031\000\006\000\000\0004\000\000\0004\000@\0004\000@\000@\001\000\000@\001\000\000\005\000\000\000\004\000\000\000\003\000\000\000t\001\000\000t\001@\000t\001@\000\023\000\000

323: >> 7 byte&,=-1,"(embedded)"]
0 == 18446744073709551615 = 0
[try softmagic 1]
[try elf -1]
/bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) error 
reading (Invalid argument)
(sid_sh4)root@vs94:/#

It seems that the comparison above has a bogus (overflown?) value.

On actual hardware, it works:

root@tirpitz:~> file /bin/bash
/bin/bash: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV), dynamically 
linked, interpreter /lib/ld-linux.so.2, 
BuildID[sha1]=4dd0e4281755827d8bb6686fd481f8c80ea73e9a, for GNU/Linux 3.2.0, 
stripped
root@tirpitz:~>

I have uploaded a chroot with Debian unstable which allows to reproduce
the issue:

> https://people.debian.org/~glaubitz/sid-sh4-sbuild.tar.gz

** Affects: qemu
 Importance: Undecided
 Status: New

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

Title:
  file(1) fails with "Invalid argument" on qemu-sh4-user

Status in QEMU:
  New

Bug description:
  We recently discovered that file(1) fails on qemu-sh4-user when
  running on an ELF file:

  (sid_sh4)root@vs94:/# file /bin/bash
  /bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) 
error reading (Invalid argument)
  (sid_sh4)root@vs94:/#

  Running with "-d" yields more output:

  (sid_sh4)root@vs94:/# file -d /bin/bash 2>&1 | tail
  322: >> 7 byte&,=97,"(ARM)"]
  0 == 97 = 0
  mget(type=1, flag=0, offset=7, o=0, nbytes=863324, il=0, nc=1)
  mget/96 @7: 
\000\000\000\000\000\000\000\000\000\002\000*\000\001\000\000\000\250\317A\0004\000\000\000L(\r\000\027\000\000\0004\000
 
\000\n\000(\000\032\000\031\000\006\000\000\0004\000\000\0004\000@\0004\000@\000@\001\000\000@\001\000\000\005\000\000\000\004\000\000\000\003\000\000\000t\001\000\000t\001@\000t\001@\000\023\000\000

  323: >> 7 byte&,=-1,"(embedded)"]
  0 == 18446744073709551615 = 0
  [try softmagic 1]
  [try elf -1]
  /bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) 
error reading (Invalid argument)
  (sid_sh4)root@vs94:/#

  It seems that the comparison above has a bogus (overflown?) value.

  On actual hardware, it works:

  root@tirpitz:~> file /bin/bash
  /bin/bash: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV), 
dynamically linked, interpreter /lib/ld-linux.so.2, 
BuildID[sha1]=4dd0e4281755827d8bb6686fd481f8c80ea73e9a, for GNU/Linux 3.2.0, 
stripped
  root@tirpitz:~>

  I have uploaded a chroot with Debian unstable which allows to
  reproduce the issue:

  > https://people.debian.org/~glaubitz/sid-sh4-sbuild.tar.gz

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



Re: [Qemu-devel] [PATCH 04/10] qemu-iotests: cleanup and fix search for programs

2017-09-12 Thread Eric Blake
On 09/12/2017 09:44 AM, Paolo Bonzini wrote:
> Instead of ./check failing when a binary is missing, we try each test
> case now and each one fails with tons of test case diffs.  Also, all the
> variables were initialized by "check" prior to "common" being sourced,
> and then (uselessly) checked for emptiness again in "check".
> 
> Centralize the search for programs in "common" (which will soon be
> one with "check"), including the "realpath" invocation which can be done
> just once in "check" rather than in the tests.
> 
> For qnio_server, move the detection to "common", simplifying
> set_prog_path to stop handling the unused second argument, and
> embedding the "realpath" pass.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  tests/qemu-iotests/check | 41 -
>  tests/qemu-iotests/common| 77 
> +---
>  tests/qemu-iotests/common.config | 61 +--
>  3 files changed, 73 insertions(+), 106 deletions(-)
> 

> +++ b/tests/qemu-iotests/common
> @@ -37,6 +37,17 @@ _full_platform_details()
>  echo "$os/$platform $host $kernel"
>  }
>  
> +# $1 = prog to look for
> +set_prog_path()
> +{
> +p=`command -v $1 2> /dev/null`

Are we sure that $1 will always respond to -v sanely?

> +if [ -n "$p" -a -x "$p" ]; then

[ ... -a ... ] should never be used; there are cases where it is
inherently ambiguous (even if it happens to work here, because we know
our shell is bash and because $p is not likely to contain text that
throws off the parser).  Please spell that either:

if [ -n "$p" ] && [ -x "$p" ]; then
if [[ -n $p && -x $p ]]; then

(that is, I don't mind if you rely on bash's [[]] in which case you can
use less typing, but if you stick to [], then you should use code that
can be pasted to other shells)

> +then
> +if [ -x "$build_iotests/qemu" ]; then
> +export QEMU_PROG="$build_iotests/qemu"
> +elif [ -x "$build_root/$arch-softmmu/qemu-system-$arch" ]; then
> +export QEMU_PROG="$build_root/$arch-softmmu/qemu-system-$arch"
> +else
> +pushd "$build_root" > /dev/null

Shouldn't you check for failure to change directories?

> +++ b/tests/qemu-iotests/common.config
> @@ -22,6 +22,7 @@ export LANG=C
>  PATH=".:$PATH"
>  
>  HOSTOS=`uname -s`
> +arch=`uname -m`

As long as we're touching this, should we prefer $() instead of ``?

>  
>  export PWD=`pwd`
>  
> @@ -30,28 +31,6 @@ export _QEMU_HANDLE=0
>  # make sure we have a standard umask
>  umask 022
>  
> -# $1 = prog to look for, $2* = default pathnames if not found in $PATH
> -set_prog_path()
> -{
> -p=`command -v $1 2> /dev/null`
> -if [ -n "$p" -a -x "$p" ]; then

Urrgh - your use of [ -a ] was pre-existing, and you just moved it.
Still worth fixing, though (either here or in a separate cleanup patch).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v5 03/22] instrument: Add generic library loader

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 MAINTAINERS  |1 
 Makefile.objs|4 +
 configure|3 +
 instrument/Makefile.objs |4 +
 instrument/cmdline.c |  128 +++
 instrument/cmdline.h |   51 ++
 instrument/load.c|  166 ++
 instrument/load.h|   88 
 stubs/Makefile.objs  |1 
 stubs/instrument.c   |   18 +
 10 files changed, 464 insertions(+)
 create mode 100644 instrument/Makefile.objs
 create mode 100644 instrument/cmdline.c
 create mode 100644 instrument/cmdline.h
 create mode 100644 instrument/load.c
 create mode 100644 instrument/load.h
 create mode 100644 stubs/instrument.c

diff --git a/MAINTAINERS b/MAINTAINERS
index fb0eaee06a..6c0b12a69a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1491,6 +1491,7 @@ M: Lluís Vilanova 
 M: Stefan Hajnoczi 
 S: Maintained
 F: docs/instrument.txt
+F: instrument/
 
 TPM
 S: Orphan
diff --git a/Makefile.objs b/Makefile.objs
index 24a4ea08b8..81a9218e14 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -97,6 +97,10 @@ version-obj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.o
 util-obj-y +=  trace/
 target-obj-y += trace/
 
+##
+# instrument
+target-obj-y += instrument/
+
 ##
 # guest agent
 
diff --git a/configure b/configure
index a21d1bceb9..5175151317 100755
--- a/configure
+++ b/configure
@@ -6025,6 +6025,9 @@ fi
 echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
 
 if test "$instrument" = "yes"; then
+  LDFLAGS="-rdynamic $LDFLAGS"  # limit symbols available to clients
+  QEMU_CFLAGS="-fvisibility=hidden $QEMU_CFLAGS"
+  LIBS="-ldl $LIBS"
   echo "CONFIG_INSTRUMENT=y" >> $config_host_mak
 fi
 
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
new file mode 100644
index 00..71994a4c85
--- /dev/null
+++ b/instrument/Makefile.objs
@@ -0,0 +1,4 @@
+# -*- mode: makefile -*-
+
+target-obj-$(CONFIG_INSTRUMENT) += cmdline.o
+target-obj-$(CONFIG_INSTRUMENT) += load.o
diff --git a/instrument/cmdline.c b/instrument/cmdline.c
new file mode 100644
index 00..da7a7cbceb
--- /dev/null
+++ b/instrument/cmdline.c
@@ -0,0 +1,128 @@
+/*
+ * Control instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include 
+#include "instrument/cmdline.h"
+#include "instrument/load.h"
+#include "qemu/config-file.h"
+#include "qemu/error-report.h"
+
+
+QemuOptsList qemu_instr_opts = {
+.name = "instrument",
+.implied_opt_name = "file",
+.merge_lists = true,
+.head = QTAILQ_HEAD_INITIALIZER(qemu_instr_opts.head),
+.desc = {
+{
+.name = "file",
+.type = QEMU_OPT_STRING,
+},{
+.name = "arg",
+.type = QEMU_OPT_STRING,
+},
+{ /* end of list */ }
+},
+};
+
+void instr_opt_parse(const char *optarg, char **path,
+ int *argc, const char ***argv)
+{
+const char *arg;
+QemuOptsIter iter;
+QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("instrument"),
+ optarg, true);
+if (!opts) {
+exit(1);
+} else {
+#if !defined(CONFIG_INSTRUMENT)
+error_report("instrumentation not enabled on this build");
+exit(1);
+#endif
+}
+
+
+arg = qemu_opt_get(opts, "file");
+if (arg != NULL) {
+g_free(*path);
+*path = g_strdup(arg);
+}
+
+qemu_opt_iter_init(&iter, opts, "arg");
+while ((arg = qemu_opt_iter_next(&iter)) != NULL) {
+*argv = realloc(*argv, sizeof(**argv) * (*argc + 1));
+(*argv)[*argc] = g_strdup(arg);
+(*argc)++;
+}
+
+qemu_opts_del(opts);
+}
+
+void instr_init(const char *path, int argc, const char **argv)
+{
+#if defined(CONFIG_INSTRUMENT)
+InstrLoadError err;
+
+if (path == NULL) {
+return;
+}
+
+if (atexit(instr_fini) != 0) {
+fprintf(stderr, "error: atexit: %s\n", strerror(errno));
+abort();
+}
+
+const char *id = "cmdline";
+err = instr_load(path, argc, argv, &id);
+switch (err) {
+case INSTR_LOAD_OK:
+error_report("instrument: loaded library with ID '%s'", id);
+return;
+case INSTR_LOAD_TOO_MANY:
+error_report("instrument: tried to load too many libraries");
+break;
+case INSTR_LOAD_ID_EXISTS:
+g_assert_not_reached();
+break;
+case INSTR_LOAD_ERROR:
+error_report("instrument: library initialization returned non-zero");
+break;
+case INSTR_LOAD_DLERROR:
+error_report("instrument: error loading library: 

Re: [Qemu-devel] [PATCH 05/10] qemu-iotests: limit non-_PROG-suffixed variables to common.rc

2017-09-12 Thread Eric Blake
On 09/12/2017 09:44 AM, Paolo Bonzini wrote:
> These are never used by "check", with one exception that does not need
> $QEMU_OPTIONS.  Keep them in common.rc, which will be soon included only
> by the tests.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  tests/qemu-iotests/039.out   | 10 +++---
>  tests/qemu-iotests/061.out   |  4 +--
>  tests/qemu-iotests/137.out   |  2 +-
>  tests/qemu-iotests/common.config | 69 
> ++--
>  tests/qemu-iotests/common.rc | 65 +
>  5 files changed, 75 insertions(+), 75 deletions(-)

It may be worth tweaking scripts/git.orderfile to prioritize
tests/qemu-iotests/common* above the rest of tests/qemu-iotests (I have
that tweak locally, at any rate).  But that's a separate issue.

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH 06/10] qemu-iotests: do not include common.rc in "check"

2017-09-12 Thread Eric Blake
On 09/12/2017 09:44 AM, Paolo Bonzini wrote:
> It only provides functions used by the test programs.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  tests/qemu-iotests/check |  6 --
>  tests/qemu-iotests/common.rc | 13 +
>  2 files changed, 5 insertions(+), 14 deletions(-)
> 

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v5 04/22] instrument: [linux-user] Add command line library loader

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 linux-user/main.c|   21 +
 linux-user/syscall.c |4 
 2 files changed, 25 insertions(+)

diff --git a/linux-user/main.c b/linux-user/main.c
index 03666ef657..ac5c30c1fb 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -36,6 +36,7 @@
 #include "exec/log.h"
 #include "trace/control.h"
 #include "glib-compat.h"
+#include "instrument/cmdline.h"
 
 char *exec_path;
 
@@ -4017,6 +4018,17 @@ static void handle_arg_trace(const char *arg)
 trace_file = trace_opt_parse(arg);
 }
 
+static char *instrument_path;
+static int instrument_argc;
+static const char **instrument_argv;
+#if defined(CONFIG_INSTRUMENT)
+static void handle_arg_instrument(const char *arg)
+{
+instr_opt_parse(arg, &instrument_path,
+&instrument_argc, &instrument_argv);
+}
+#endif
+
 struct qemu_argument {
 const char *argv;
 const char *env;
@@ -4066,6 +4078,10 @@ static const struct qemu_argument arg_table[] = {
  "",   "Seed for pseudo-random number generator"},
 {"trace",  "QEMU_TRACE",   true,  handle_arg_trace,
  "",   "[[enable=]][,events=][,file=]"},
+#if defined(CONFIG_INSTRUMENT)
+{"instr",  "QEMU_INSTR",   true,  handle_arg_instrument,
+ "",   "[file=][,arg=]"},
+#endif
 {"version","QEMU_VERSION", false, handle_arg_version,
  "",   "display version information and exit"},
 {NULL, NULL, false, NULL, NULL, NULL}
@@ -4257,6 +4273,9 @@ int main(int argc, char **argv, char **envp)
 srand(time(NULL));
 
 qemu_add_opts(&qemu_trace_opts);
+#if defined(CONFIG_INSTRUMENT)
+qemu_add_opts(&qemu_instr_opts);
+#endif
 
 optind = parse_args(argc, argv);
 
@@ -4265,6 +4284,8 @@ int main(int argc, char **argv, char **envp)
 }
 trace_init_file(trace_file);
 
+instr_init(instrument_path, instrument_argc, instrument_argv);
+
 /* Zero out regs */
 memset(regs, 0, sizeof(struct target_pt_regs));
 
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9b6364a266..e73a07fa6f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -115,6 +115,8 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 #include "uname.h"
 
 #include "qemu.h"
+#include "instrument/cmdline.h"
+
 
 #ifndef CLONE_IO
 #define CLONE_IO0x8000  /* Clone io context */
@@ -7765,6 +7767,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 _mcleanup();
 #endif
 gdb_exit(cpu_env, arg1);
+instr_fini();
 _exit(arg1);
 ret = 0; /* avoid warning */
 break;
@@ -9821,6 +9824,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 _mcleanup();
 #endif
 gdb_exit(cpu_env, arg1);
+instr_fini();
 ret = get_errno(exit_group(arg1));
 break;
 #endif




[Qemu-devel] [PATCH] accel/tcg: move USER code to user-exec.c

2017-09-12 Thread Philippe Mathieu-Daudé
Suggested-by: Paolo Bonzini 
Signed-off-by: Philippe Mathieu-Daudé 
---
Based-on: 20170911213328.9701-5-f4...@amsat.org

 accel/tcg/tcg-runtime.c | 54 -
 accel/tcg/user-exec.c   | 52 +++
 2 files changed, 52 insertions(+), 54 deletions(-)

diff --git a/accel/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c
index 3e23649dd7..aafb171294 100644
--- a/accel/tcg/tcg-runtime.c
+++ b/accel/tcg/tcg-runtime.c
@@ -178,57 +178,3 @@ void HELPER(exit_atomic)(CPUArchState *env)
 {
 cpu_loop_exit_atomic(ENV_GET_CPU(env), GETPC());
 }
-
-#ifndef CONFIG_SOFTMMU
-/* The softmmu versions of these helpers are in cputlb.c.  */
-
-/* Do not allow unaligned operations to proceed.  Return the host address.  */
-static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
-   int size, uintptr_t retaddr)
-{
-/* Enforce qemu required alignment.  */
-if (unlikely(addr & (size - 1))) {
-cpu_loop_exit_atomic(ENV_GET_CPU(env), retaddr);
-}
-return g2h(addr);
-}
-
-/* Macro to call the above, with local variables from the use context.  */
-#define ATOMIC_MMU_LOOKUP  atomic_mmu_lookup(env, addr, DATA_SIZE, GETPC())
-
-#define ATOMIC_NAME(X)   HELPER(glue(glue(atomic_ ## X, SUFFIX), END))
-#define EXTRA_ARGS
-
-#define DATA_SIZE 1
-#include "atomic_template.h"
-
-#define DATA_SIZE 2
-#include "atomic_template.h"
-
-#define DATA_SIZE 4
-#include "atomic_template.h"
-
-#ifdef CONFIG_ATOMIC64
-#define DATA_SIZE 8
-#include "atomic_template.h"
-#endif
-
-/* The following is only callable from other helpers, and matches up
-   with the softmmu version.  */
-
-#ifdef CONFIG_ATOMIC128
-
-#undef EXTRA_ARGS
-#undef ATOMIC_NAME
-#undef ATOMIC_MMU_LOOKUP
-
-#define EXTRA_ARGS , TCGMemOpIdx oi, uintptr_t retaddr
-#define ATOMIC_NAME(X) \
-HELPER(glue(glue(glue(atomic_ ## X, SUFFIX), END), _mmu))
-#define ATOMIC_MMU_LOOKUP  atomic_mmu_lookup(env, addr, DATA_SIZE, retaddr)
-
-#define DATA_SIZE 16
-#include "atomic_template.h"
-#endif /* CONFIG_ATOMIC128 */
-
-#endif /* !CONFIG_SOFTMMU */
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 2a975eaf69..492ea0826c 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -24,6 +24,7 @@
 #include "qemu/bitops.h"
 #include "exec/cpu_ldst.h"
 #include "translate-all.h"
+#include "exec/helper-proto.h"
 
 #undef EAX
 #undef ECX
@@ -573,3 +574,54 @@ int cpu_signal_handler(int host_signum, void *pinfo,
 #error host CPU specific signal handler needed
 
 #endif
+
+/* The softmmu versions of these helpers are in cputlb.c.  */
+
+/* Do not allow unaligned operations to proceed.  Return the host address.  */
+static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
+   int size, uintptr_t retaddr)
+{
+/* Enforce qemu required alignment.  */
+if (unlikely(addr & (size - 1))) {
+cpu_loop_exit_atomic(ENV_GET_CPU(env), retaddr);
+}
+return g2h(addr);
+}
+
+/* Macro to call the above, with local variables from the use context.  */
+#define ATOMIC_MMU_LOOKUP  atomic_mmu_lookup(env, addr, DATA_SIZE, GETPC())
+
+#define ATOMIC_NAME(X)   HELPER(glue(glue(atomic_ ## X, SUFFIX), END))
+#define EXTRA_ARGS
+
+#define DATA_SIZE 1
+#include "atomic_template.h"
+
+#define DATA_SIZE 2
+#include "atomic_template.h"
+
+#define DATA_SIZE 4
+#include "atomic_template.h"
+
+#ifdef CONFIG_ATOMIC64
+#define DATA_SIZE 8
+#include "atomic_template.h"
+#endif
+
+/* The following is only callable from other helpers, and matches up
+   with the softmmu version.  */
+
+#ifdef CONFIG_ATOMIC128
+
+#undef EXTRA_ARGS
+#undef ATOMIC_NAME
+#undef ATOMIC_MMU_LOOKUP
+
+#define EXTRA_ARGS , TCGMemOpIdx oi, uintptr_t retaddr
+#define ATOMIC_NAME(X) \
+HELPER(glue(glue(glue(atomic_ ## X, SUFFIX), END), _mmu))
+#define ATOMIC_MMU_LOOKUP  atomic_mmu_lookup(env, addr, DATA_SIZE, retaddr)
+
+#define DATA_SIZE 16
+#include "atomic_template.h"
+#endif /* CONFIG_ATOMIC128 */
-- 
2.14.1




[Qemu-devel] [PATCH v5 05/22] instrument: [bsd-user] Add command line library loader

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 bsd-user/main.c|   17 +
 bsd-user/syscall.c |5 +
 2 files changed, 22 insertions(+)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 8a6706a1c8..104844edfc 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -33,6 +33,7 @@
 #include "exec/log.h"
 #include "trace/control.h"
 #include "glib-compat.h"
+#include "instrument/cmdline.h"
 
 int singlestep;
 unsigned long mmap_min_addr;
@@ -667,6 +668,11 @@ static void usage(void)
"-B addressset guest_base address to address\n"
"-bsd type select emulated BSD type FreeBSD/NetBSD/OpenBSD 
(default)\n"
"\n"
+#if defined(CONFIG_INSTRUMENT)
+   "-instr [file=][,arg=]\n"
+   "  load an instrumentation library\n"
+   "\n"
+#endif
"Debug options:\n"
"-d item1[,...]enable logging of specified items\n"
"  (use '-d help' for a list of log items)\n"
@@ -738,6 +744,9 @@ int main(int argc, char **argv)
 envlist_t *envlist = NULL;
 char *trace_file = NULL;
 bsd_type = target_openbsd;
+char *instrument_path = NULL;
+int instrument_argc = 0;
+const char **instrument_argv = NULL;
 
 if (argc <= 1)
 usage();
@@ -756,6 +765,9 @@ int main(int argc, char **argv)
 cpu_model = NULL;
 
 qemu_add_opts(&qemu_trace_opts);
+#if defined(CONFIG_INSTRUMENT)
+qemu_add_opts(&qemu_instr_opts);
+#endif
 
 optind = 1;
 for (;;) {
@@ -843,6 +855,9 @@ int main(int argc, char **argv)
 } else if (!strcmp(r, "trace")) {
 g_free(trace_file);
 trace_file = trace_opt_parse(optarg);
+} else if (!strcmp(r, "instr")) {
+instr_opt_parse(optarg, &instrument_path,
+&instrument_argc, &instrument_argv);
 } else {
 usage();
 }
@@ -872,6 +887,8 @@ int main(int argc, char **argv)
 }
 trace_init_file(trace_file);
 
+instr_init(instrument_path, instrument_argc, instrument_argv);
+
 /* Zero out regs */
 memset(regs, 0, sizeof(struct target_pt_regs));
 
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index 66492aaf5d..3230f722f3 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -26,6 +26,8 @@
 
 #include "qemu.h"
 #include "qemu-common.h"
+#include "instrument/cmdline.h"
+
 
 //#define DEBUG
 
@@ -332,6 +334,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 _mcleanup();
 #endif
 gdb_exit(cpu_env, arg1);
+instr_fini();
 /* XXX: should free thread stack and CPU env */
 _exit(arg1);
 ret = 0; /* avoid warning */
@@ -430,6 +433,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long 
arg1,
 _mcleanup();
 #endif
 gdb_exit(cpu_env, arg1);
+instr_fini();
 /* XXX: should free thread stack and CPU env */
 _exit(arg1);
 ret = 0; /* avoid warning */
@@ -505,6 +509,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 _mcleanup();
 #endif
 gdb_exit(cpu_env, arg1);
+instr_fini();
 /* XXX: should free thread stack and CPU env */
 _exit(arg1);
 ret = 0; /* avoid warning */




Re: [Qemu-devel] [PATCH 07/10] qemu-iotests: disintegrate more parts of common.config

2017-09-12 Thread Eric Blake
On 09/12/2017 09:44 AM, Paolo Bonzini wrote:
> Split "check" parts from tests part.
> 
> For the directory setup, the actual computation of directories goes
> in "check", while the sanity checks go in the tests.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  tests/qemu-iotests/common| 24 
>  tests/qemu-iotests/common.config | 49 
> 
>  tests/qemu-iotests/common.qemu   |  1 +
>  tests/qemu-iotests/common.rc | 25 
>  4 files changed, 50 insertions(+), 49 deletions(-)
> 
> diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
> index abacc24114..ee313af92f 100644
> --- a/tests/qemu-iotests/common
> +++ b/tests/qemu-iotests/common
> @@ -48,6 +48,14 @@ set_prog_path()
>  fi
>  }
>  
> +if [ -z "$TEST_DIR" ]; then
> +TEST_DIR=`pwd`/scratch

8-space indent looks odd compared to the rest of the file.

> @@ -153,6 +158,26 @@ else
>  fi
>  ORIG_TEST_IMG="$TEST_IMG"
>  
> +if [ -z "$TEST_DIR" ]; then
> +TEST_DIR=`pwd`/scratch

We probably ought to clean things up to use $PWD instead of `pwd`
everywhere as a minor optimization (why fork, when bash already has the
right information for you?) - but that can be separate.

Split looks okay to me,
Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v5 06/22] instrument: [softmmu] Add command line library loader

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 qemu-options.hx |   19 +++
 vl.c|   15 +++
 2 files changed, 34 insertions(+)

diff --git a/qemu-options.hx b/qemu-options.hx
index 9f6e2adfff..6947388aab 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4077,6 +4077,25 @@ HXCOMM HX does not support conditional compilation of 
text.
 @findex -trace
 @include qemu-option-trace.texi
 ETEXI
+#if defined(CONFIG_INSTRUMENT)
+DEF("instr", HAS_ARG, QEMU_OPTION_instr,
+"-instr [file=][,arg=]\n"
+"load an instrumentation library\n",
+QEMU_ARCH_ALL)
+#endif
+STEXI
+@item -instr file=@var{file}[,arg=@var{string}]
+@findex -instr
+
+Load a dynamic trace instrumentation library.
+
+@table @option
+@item file=@var{file}
+Load the given dynamic trace instrumentation library.
+@item arg=@var{string}
+String argument passed as to the library's @code{qi_init} routine (can be 
given multiple times).
+@end table
+ETEXI
 
 HXCOMM Internal use
 DEF("qtest", HAS_ARG, QEMU_OPTION_qtest, "", QEMU_ARCH_ALL)
diff --git a/vl.c b/vl.c
index fb1f05b937..aea05ed4cc 100644
--- a/vl.c
+++ b/vl.c
@@ -118,6 +118,7 @@ int main(int argc, char **argv)
 
 #include "trace-root.h"
 #include "trace/control.h"
+#include "instrument/cmdline.h"
 #include "qemu/queue.h"
 #include "sysemu/arch_init.h"
 
@@ -3037,6 +3038,9 @@ int main(int argc, char **argv, char **envp)
 } BlockdevOptions_queue;
 QSIMPLEQ_HEAD(, BlockdevOptions_queue) bdo_queue
 = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
+char *instrument_path = NULL;
+int instrument_argc = 0;
+const char **instrument_argv = NULL;
 
 module_call_init(MODULE_INIT_TRACE);
 
@@ -3064,6 +3068,9 @@ int main(int argc, char **argv, char **envp)
 qemu_add_opts(&qemu_global_opts);
 qemu_add_opts(&qemu_mon_opts);
 qemu_add_opts(&qemu_trace_opts);
+#if defined(CONFIG_INSTRUMENT)
+qemu_add_opts(&qemu_instr_opts);
+#endif
 qemu_add_opts(&qemu_option_rom_opts);
 qemu_add_opts(&qemu_machine_opts);
 qemu_add_opts(&qemu_accel_opts);
@@ -4009,6 +4016,12 @@ int main(int argc, char **argv, char **envp)
 g_free(trace_file);
 trace_file = trace_opt_parse(optarg);
 break;
+#if defined(CONFIG_INSTRUMENT)
+case QEMU_OPTION_instr:
+instr_opt_parse(optarg, &instrument_path,
+&instrument_argc, &instrument_argv);
+break;
+#endif
 case QEMU_OPTION_readconfig:
 {
 int ret = qemu_read_config_file(optarg);
@@ -4196,6 +4209,8 @@ int main(int argc, char **argv, char **envp)
 }
 trace_init_file(trace_file);
 
+instr_init(instrument_path, instrument_argc, instrument_argv);
+
 /* Open the logfile at this point and set the log mask if necessary.
  */
 if (log_file) {




Re: [Qemu-devel] [PATCH 04/10] qemu-iotests: cleanup and fix search for programs

2017-09-12 Thread Paolo Bonzini


> > +then
> > +if [ -x "$build_iotests/qemu" ]; then
> > +export QEMU_PROG="$build_iotests/qemu"
> > +elif [ -x "$build_root/$arch-softmmu/qemu-system-$arch" ]; then
> > +export QEMU_PROG="$build_root/$arch-softmmu/qemu-system-$arch"
> > +else
> > +pushd "$build_root" > /dev/null
> 
> Shouldn't you check for failure to change directories?
>  
> >  export PWD=`pwd`
> >  
> > @@ -30,28 +31,6 @@ export _QEMU_HANDLE=0
> >  # make sure we have a standard umask
> >  umask 022
> >  
> > -# $1 = prog to look for, $2* = default pathnames if not found in $PATH
> > -set_prog_path()
> > -{
> > -p=`command -v $1 2> /dev/null`
> > -if [ -n "$p" -a -x "$p" ]; then
> 
> Urrgh - your use of [ -a ] was pre-existing, and you just moved it.

And same for pushd...

Paolo



Re: [Qemu-devel] [PATCH 08/10] qemu-iotests: fix uninitialized variable

2017-09-12 Thread Eric Blake
On 09/12/2017 09:44 AM, Paolo Bonzini wrote:
> The variable is used in "common" but defined only after the file
> is sourced.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  tests/qemu-iotests/check  | 2 --
>  tests/qemu-iotests/common | 2 ++
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 

Reviewed-by: Eric Blake 

> +tmp="${TEST_DIR}"/$$

Pre-existing to your code motion, but would we be any safer if $tmp also
included a use of $RANDOM?  (The $$ already protects us from collisions
with a parallel run, but it is easy to guess, so if $tmp is used to
create any file that an attacker can access, running the testsuite may
expose a machine to a symlink or other attack - but we probably have
lots of those things to audit for before we can recommend running the
testsuite in an untrusted environment).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v5 07/22] instrument: [qapi] Add library loader

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 MAINTAINERS  |1 +
 Makefile |1 +
 instrument/Makefile.objs |1 +
 instrument/qmp.c |   82 ++
 monitor.c|4 ++
 qapi-schema.json |3 ++
 qapi/instrument.json |   49 +++
 stubs/instrument.c   |   26 +++
 8 files changed, 167 insertions(+)
 create mode 100644 instrument/qmp.c
 create mode 100644 qapi/instrument.json

diff --git a/MAINTAINERS b/MAINTAINERS
index 6c0b12a69a..edddab0502 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1492,6 +1492,7 @@ M: Stefan Hajnoczi 
 S: Maintained
 F: docs/instrument.txt
 F: instrument/
+F: qapi/instrument.json
 
 TPM
 S: Orphan
diff --git a/Makefile b/Makefile
index 337a1f6f9b..3861b3f49c 100644
--- a/Makefile
+++ b/Makefile
@@ -412,6 +412,7 @@ qapi-modules = $(SRC_PATH)/qapi-schema.json 
$(SRC_PATH)/qapi/common.json \
$(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \
$(SRC_PATH)/qapi/char.json \
$(SRC_PATH)/qapi/crypto.json \
+   $(SRC_PATH)/qapi/instrument.json \
$(SRC_PATH)/qapi/introspect.json \
$(SRC_PATH)/qapi/migration.json \
$(SRC_PATH)/qapi/net.json \
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 71994a4c85..7bf4e27e3c 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -2,3 +2,4 @@
 
 target-obj-$(CONFIG_INSTRUMENT) += cmdline.o
 target-obj-$(CONFIG_INSTRUMENT) += load.o
+target-obj-$(CONFIG_INSTRUMENT) += qmp.o
diff --git a/instrument/qmp.c b/instrument/qmp.c
new file mode 100644
index 00..e4464aa5eb
--- /dev/null
+++ b/instrument/qmp.c
@@ -0,0 +1,82 @@
+/*
+ * QMP interface for instrumentation control commands.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include 
+
+#include "instrument/load.h"
+#include "qemu-common.h"
+#include "qapi/qmp/qerror.h"
+#include "qmp-commands.h"
+
+
+InstrLoadResult *qmp_instr_load(const char *path,
+bool has_id, const char *id,
+bool have_args, strList *args,
+Error **errp)
+{
+InstrLoadResult *res = g_malloc0(sizeof(*res));
+int argc = 0;
+const char **argv = NULL;
+InstrLoadError code;
+
+if (!has_id) {
+id = NULL;
+}
+
+strList *entry = have_args ? args : NULL;
+while (entry != NULL) {
+argv = realloc(argv, sizeof(*argv) * (argc + 1));
+argv[argc] = entry->value;
+argc++;
+entry = entry->next;
+}
+
+code = instr_load(path, argc, argv, &id);
+switch (code) {
+case INSTR_LOAD_OK:
+res->id = g_strdup(id);
+break;
+case INSTR_LOAD_ID_EXISTS:
+error_setg(errp, "Library ID exists");
+break;
+case INSTR_LOAD_TOO_MANY:
+error_setg(errp, "Tried to load too many libraries");
+break;
+case INSTR_LOAD_ERROR:
+error_setg(errp, "Library initialization returned non-zero");
+break;
+case INSTR_LOAD_DLERROR:
+error_setg(errp, "Error loading library: %s",
+   dlerror());
+break;
+}
+
+if (*errp) {
+g_free(res);
+res = NULL;
+}
+
+return res;
+}
+
+void qmp_instr_unload(const char *id, Error **errp)
+{
+InstrUnloadError code = instr_unload(id);
+switch (code) {
+case INSTR_UNLOAD_OK:
+break;
+case INSTR_UNLOAD_INVALID:
+error_setg(errp, "Unknown library ID");
+break;
+case INSTR_UNLOAD_DLERROR:
+error_setg(errp, "Error unloading library: %s", dlerror());
+break;
+}
+}
diff --git a/monitor.c b/monitor.c
index 9239f7adde..e031aa2687 100644
--- a/monitor.c
+++ b/monitor.c
@@ -978,6 +978,10 @@ static void qmp_unregister_commands_hack(void)
 qmp_unregister_command(&qmp_commands, "query-xen-replication-status");
 qmp_unregister_command(&qmp_commands, "xen-colo-do-checkpoint");
 #endif
+#ifndef CONFIG_INSTRUMENT
+qmp_unregister_command(&qmp_commands, "instr-load");
+qmp_unregister_command(&qmp_commands, "instr-unload");
+#endif
 #ifndef TARGET_I386
 qmp_unregister_command(&qmp_commands, "rtc-reset-reinjection");
 #endif
diff --git a/qapi-schema.json b/qapi-schema.json
index f3af2cb851..706c64659f 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -93,6 +93,9 @@
 { 'include': 'qapi/trace.json' }
 { 'include': 'qapi/introspect.json' }
 
+# Instrumentation commands
+{ 'include': 'qapi/instrument.json' }
+
 ##
 # = Miscellanea
 ##
diff --git a/qapi/instrument.json b/qapi/instrument.json
new file mode 100644
index 00..c59bee74cb
--- /dev/null
+++ b/qapi/instrument.json
@@ -0,0 +1,49 @@
+# *-*- Mode: Pyth

Re: [Qemu-devel] [PATCH 09/10] qemu-iotests: get rid of $iam

2017-09-12 Thread Eric Blake
On 09/12/2017 09:44 AM, Paolo Bonzini wrote:
> The variable is almost unused, and one of the two uses is actually
> uninitialized.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  tests/qemu-iotests/check | 5 +
>  tests/qemu-iotests/common.rc | 2 +-
>  2 files changed, 2 insertions(+), 5 deletions(-)
> 

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [Bug 1716767] Re: file(1) fails with "Invalid argument" on qemu-sh4-user

2017-09-12 Thread James Clarke
The "0 == 18446744073709551615 = 0" is actually fine, it's just printing
"-1" as a 64-bit unsigned integer. Could you please upload the fill
output of `file -d /bin/bash 2>&1`?

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

Title:
  file(1) fails with "Invalid argument" on qemu-sh4-user

Status in QEMU:
  New

Bug description:
  We recently discovered that file(1) fails on qemu-sh4-user when
  running on an ELF file:

  (sid_sh4)root@vs94:/# file /bin/bash
  /bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) 
error reading (Invalid argument)
  (sid_sh4)root@vs94:/#

  Running with "-d" yields more output:

  (sid_sh4)root@vs94:/# file -d /bin/bash 2>&1 | tail
  322: >> 7 byte&,=97,"(ARM)"]
  0 == 97 = 0
  mget(type=1, flag=0, offset=7, o=0, nbytes=863324, il=0, nc=1)
  mget/96 @7: 
\000\000\000\000\000\000\000\000\000\002\000*\000\001\000\000\000\250\317A\0004\000\000\000L(\r\000\027\000\000\0004\000
 
\000\n\000(\000\032\000\031\000\006\000\000\0004\000\000\0004\000@\0004\000@\000@\001\000\000@\001\000\000\005\000\000\000\004\000\000\000\003\000\000\000t\001\000\000t\001@\000t\001@\000\023\000\000

  323: >> 7 byte&,=-1,"(embedded)"]
  0 == 18446744073709551615 = 0
  [try softmagic 1]
  [try elf -1]
  /bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) 
error reading (Invalid argument)
  (sid_sh4)root@vs94:/#

  It seems that the comparison above has a bogus (overflown?) value.

  On actual hardware, it works:

  root@tirpitz:~> file /bin/bash
  /bin/bash: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV), 
dynamically linked, interpreter /lib/ld-linux.so.2, 
BuildID[sha1]=4dd0e4281755827d8bb6686fd481f8c80ea73e9a, for GNU/Linux 3.2.0, 
stripped
  root@tirpitz:~>

  I have uploaded a chroot with Debian unstable which allows to
  reproduce the issue:

  > https://people.debian.org/~glaubitz/sid-sh4-sbuild.tar.gz

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



Re: [Qemu-devel] [PATCH 10/10] qemu-iotests: merge "check" and "common"

2017-09-12 Thread Eric Blake
On 09/12/2017 09:44 AM, Paolo Bonzini wrote:
> "check" is full of qemu-iotests--specific details.  Separating it
> from "common" does not make much sense anymore.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  tests/qemu-iotests/check  | 533 +++-
>  tests/qemu-iotests/common | 552 
> --
>  2 files changed, 531 insertions(+), 554 deletions(-)
>  delete mode 100644 tests/qemu-iotests/common
> 

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v5 08/22] instrument: [hmp] Add library loader

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 hmp-commands.hx |   32 
 monitor.c   |   39 +++
 2 files changed, 71 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 1941e19932..2e8ebe8422 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1858,6 +1858,38 @@ ETEXI
 .sub_table  = info_cmds,
 },
 
+#ifdef CONFIG_INSTRUMENT
+{
+.name   = "instr-load",
+.args_type  = "path:F,id:s?,arg:s?",
+.params = "path [id] [arg]",
+.help   = "load an instrumentation library",
+.cmd= hmp_instr_load,
+},
+#endif
+
+STEXI
+@item instr-load @var{path} [@var{id}] [@var{arg}]
+@findex instr-load
+Load an instrumentation library.
+ETEXI
+
+#ifdef CONFIG_INSTRUMENT
+{
+.name   = "instr-unload",
+.args_type  = "id:s",
+.params = "id",
+.help   = "unload an instrumentation library",
+.cmd= hmp_instr_unload,
+},
+#endif
+
+STEXI
+@item instr-unload
+@findex instr-unload
+Unload an instrumentation library.
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/monitor.c b/monitor.c
index e031aa2687..7b80d5351f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2323,6 +2323,45 @@ int monitor_fd_param(Monitor *mon, const char *fdname, 
Error **errp)
 return fd;
 }
 
+#ifdef CONFIG_INSTRUMENT
+static void hmp_instr_load(Monitor *mon, const QDict *qdict)
+{
+Error *err = NULL;
+const char *path = qdict_get_str(qdict, "path");
+const char *id = qdict_get_try_str(qdict, "id");
+const char *str = qdict_get_try_str(qdict, "arg");
+strList args;
+
+args.value = (char *)str;
+args.next = NULL;
+
+InstrLoadResult *res = qmp_instr_load(path,
+  id != NULL, id,
+  args.value != NULL, &args,
+  &err);
+if (err) {
+error_report_err(err);
+} else {
+monitor_printf(mon, "Handle: %s\n", res->id);
+monitor_printf(mon, "OK\n");
+}
+qapi_free_InstrLoadResult(res);
+}
+
+static void hmp_instr_unload(Monitor *mon, const QDict *qdict)
+{
+Error *err = NULL;
+const char *id = qdict_get_str(qdict, "id");
+
+qmp_instr_unload(id, &err);
+if (err) {
+error_report_err(err);
+} else {
+monitor_printf(mon, "OK\n");
+}
+}
+#endif
+
 /* Please update hmp-commands.hx when adding or changing commands */
 static mon_cmd_t info_cmds[] = {
 #include "hmp-commands-info.h"




Re: [Qemu-devel] [PATCH 04/10] qemu-iotests: cleanup and fix search for programs

2017-09-12 Thread Eric Blake
On 09/12/2017 04:26 PM, Paolo Bonzini wrote:
> 
> 
>>> +then
>>> +if [ -x "$build_iotests/qemu" ]; then
>>> +export QEMU_PROG="$build_iotests/qemu"
>>> +elif [ -x "$build_root/$arch-softmmu/qemu-system-$arch" ]; then
>>> +export QEMU_PROG="$build_root/$arch-softmmu/qemu-system-$arch"
>>> +else
>>> +pushd "$build_root" > /dev/null
>>
>> Shouldn't you check for failure to change directories?
>>  
>>>  export PWD=`pwd`
>>>  
>>> @@ -30,28 +31,6 @@ export _QEMU_HANDLE=0
>>>  # make sure we have a standard umask
>>>  umask 022
>>>  
>>> -# $1 = prog to look for, $2* = default pathnames if not found in $PATH
>>> -set_prog_path()
>>> -{
>>> -p=`command -v $1 2> /dev/null`
>>> -if [ -n "$p" -a -x "$p" ]; then
>>
>> Urrgh - your use of [ -a ] was pre-existing, and you just moved it.
> 
> And same for pushd...

True - since this patch is just code motion, we can do the cleanups in a
different patch, so you can have:
Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v5 09/22] instrument: Add basic control interface

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 Makefile|4 +++
 configure   |1 +
 include/qemu/compiler.h |   19 
 instrument/Makefile.objs|1 +
 instrument/control.c|   28 
 instrument/control.h|   44 +
 instrument/control.inc.h|   25 +
 instrument/error.h  |   28 
 instrument/events.h |   37 +++
 instrument/events.inc.h |   11 +
 instrument/load.c   |   13 +++
 instrument/qemu-instr/control.h |   46 +++
 stubs/instrument.c  |4 +++
 13 files changed, 261 insertions(+)
 create mode 100644 instrument/control.c
 create mode 100644 instrument/control.h
 create mode 100644 instrument/control.inc.h
 create mode 100644 instrument/error.h
 create mode 100644 instrument/events.h
 create mode 100644 instrument/events.inc.h
 create mode 100644 instrument/qemu-instr/control.h

diff --git a/Makefile b/Makefile
index 3861b3f49c..c3d9a4bcd9 100644
--- a/Makefile
+++ b/Makefile
@@ -599,6 +599,10 @@ ifdef CONFIG_VIRTFS
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
$(INSTALL_DATA) fsdev/virtfs-proxy-helper.1 "$(DESTDIR)$(mandir)/man1"
 endif
+ifdef CONFIG_INSTRUMENT
+   $(INSTALL_DIR) "$(DESTDIR)$(includedir)/qemu-instr/"
+   $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/control.h 
"$(DESTDIR)$(includedir)/qemu-instr/"
+endif
 
 install-datadir:
$(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)"
diff --git a/configure b/configure
index 5175151317..18810eae84 100755
--- a/configure
+++ b/configure
@@ -6030,6 +6030,7 @@ if test "$instrument" = "yes"; then
   LIBS="-ldl $LIBS"
   echo "CONFIG_INSTRUMENT=y" >> $config_host_mak
 fi
+QEMU_INCLUDES="-I\$(SRC_PATH)/instrument $QEMU_INCLUDES"
 
 if test "$rdma" = "yes" ; then
   echo "CONFIG_RDMA=y" >> $config_host_mak
diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
index 340e5fdc09..e86bd34e2c 100644
--- a/include/qemu/compiler.h
+++ b/include/qemu/compiler.h
@@ -111,4 +111,23 @@
 #define GCC_FMT_ATTR(n, m)
 #endif
 
+/*
+ * Export symbol to dlopen()'ed libraries'.
+ *
+ * This code is taken from http://gcc.gnu.org/wiki/Visibility.
+ */
+#if defined _WIN32 || defined __CYGWIN__
+  #ifdef __GNUC__
+#define SYM_PUBLIC __attribute__ ((dllimport))
+  #else
+#define SYM_PUBLIC __declspec(dllimport)
+  #endif
+#else
+  #if __GNUC__ >= 4
+#define SYM_PUBLIC __attribute__ ((visibility("default")))
+  #else
+#define SYM_PUBLIC
+  #endif
+#endif
+
 #endif /* COMPILER_H */
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 7bf4e27e3c..ec76b2080b 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -3,3 +3,4 @@
 target-obj-$(CONFIG_INSTRUMENT) += cmdline.o
 target-obj-$(CONFIG_INSTRUMENT) += load.o
 target-obj-$(CONFIG_INSTRUMENT) += qmp.o
+target-obj-$(CONFIG_INSTRUMENT) += control.o
diff --git a/instrument/control.c b/instrument/control.c
new file mode 100644
index 00..3630d6b3be
--- /dev/null
+++ b/instrument/control.c
@@ -0,0 +1,28 @@
+/*
+ * Control instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "instrument/control.h"
+#include "instrument/error.h"
+#include "instrument/events.h"
+#include "instrument/load.h"
+#include "instrument/qemu-instr/control.h"
+#include "qemu/compiler.h"
+
+__thread InstrState instr_cur_state;
+
+
+qi_fini_fn instr_event__fini_fn;
+void *instr_event__fini_data;
+
+SYM_PUBLIC void qi_set_fini(qi_fini_fn fn, void *data)
+{
+ERROR_IF(!instr_get_state(), "called outside instrumentation");
+instr_set_event(fini_fn, fn);
+instr_set_event(fini_data, data);
+}
diff --git a/instrument/control.h b/instrument/control.h
new file mode 100644
index 00..f2b085f69b
--- /dev/null
+++ b/instrument/control.h
@@ -0,0 +1,44 @@
+/*
+ * Control instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef INSTRUMENT__CONTROL_H
+#define INSTRUMENT__CONTROL_H
+
+
+/**
+ * InstrState:
+ * @INSTR_STATE_DISABLE: Intrumentation API not available.
+ * @INSTR_STATE_ENABLE: Intrumentation API available.
+ *
+ * Instrumentation state of current host thread. Used to ensure instrumentation
+ * clients use QEMU's API only in expected points.
+ */
+typedef enum {
+INSTR_STATE_DISABLE,
+INSTR_STATE_ENABLE,
+} InstrState;
+
+/**
+ * instr_set_state:
+ *
+ * Set the instrumentation state of the current host thread.
+ */
+static inline void instr

[Qemu-devel] [PATCH v5 10/22] instrument: Add support for tracing events

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 .gitignore|1 
 Makefile  |3 +
 instrument/Makefile.objs  |1 
 instrument/error.h|6 ++
 instrument/qemu-instr/types.h |   51 +++
 instrument/qemu-instr/types.inc.h |   15 
 instrument/trace.c|  125 +
 trace/control.h   |1 
 8 files changed, 203 insertions(+)
 create mode 100644 instrument/qemu-instr/types.h
 create mode 100644 instrument/qemu-instr/types.inc.h
 create mode 100644 instrument/trace.c

diff --git a/.gitignore b/.gitignore
index cf65316863..5ffcb9a091 100644
--- a/.gitignore
+++ b/.gitignore
@@ -134,3 +134,4 @@ trace-dtrace-root.h
 trace-dtrace-root.dtrace
 trace-ust-all.h
 trace-ust-all.c
+!/instrument/*
diff --git a/Makefile b/Makefile
index c3d9a4bcd9..646fe2f327 100644
--- a/Makefile
+++ b/Makefile
@@ -602,6 +602,9 @@ endif
 ifdef CONFIG_INSTRUMENT
$(INSTALL_DIR) "$(DESTDIR)$(includedir)/qemu-instr/"
$(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/control.h 
"$(DESTDIR)$(includedir)/qemu-instr/"
+   $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/trace.h 
"$(DESTDIR)$(includedir)/qemu-instr/"
+   $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/types.h 
"$(DESTDIR)$(includedir)/qemu-instr/"
+   $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/types.inc.h 
"$(DESTDIR)$(includedir)/qemu-instr/"
 endif
 
 install-datadir:
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index ec76b2080b..d7e6c760c3 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -4,3 +4,4 @@ target-obj-$(CONFIG_INSTRUMENT) += cmdline.o
 target-obj-$(CONFIG_INSTRUMENT) += load.o
 target-obj-$(CONFIG_INSTRUMENT) += qmp.o
 target-obj-$(CONFIG_INSTRUMENT) += control.o
+target-obj-$(CONFIG_INSTRUMENT) += trace.o
diff --git a/instrument/error.h b/instrument/error.h
index f8d1dd4b16..7a51d62fdb 100644
--- a/instrument/error.h
+++ b/instrument/error.h
@@ -25,4 +25,10 @@
 return;  \
 }
 
+#define ERROR_IF_RET(cond, ret, msg, args...)   \
+if (unlikely(cond)) {   \
+_ERROR(msg, ##args);\
+return ret; \
+}   \
+
 #endif  /* INSTRUMENT_ERROR_H */
diff --git a/instrument/qemu-instr/types.h b/instrument/qemu-instr/types.h
new file mode 100644
index 00..ea3a032b4f
--- /dev/null
+++ b/instrument/qemu-instr/types.h
@@ -0,0 +1,51 @@
+/*
+ * QEMU-specific types for instrumentation clients.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QI__TYPES_H
+#define QI__TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * SECTION: types
+ * @section_id: qi-types
+ * @title: Common types
+ */
+
+/**
+ * QITraceEvent:
+ *
+ * Opaque structure defining a tracing event.
+ */
+typedef struct QITraceEvent QITraceEvent;
+
+/**
+ * QITraceEventIter:
+ *
+ * Opaque structure defining a tracing event iterator.
+ */
+typedef struct QITraceEventIter QITraceEventIter;
+
+/**
+ * QICPU:
+ *
+ * Opaque guest CPU pointer.
+ */
+typedef struct QICPU_d *QICPU;
+
+
+#include 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* QI__TYPES_H */
diff --git a/instrument/qemu-instr/types.inc.h 
b/instrument/qemu-instr/types.inc.h
new file mode 100644
index 00..0d99ea59a2
--- /dev/null
+++ b/instrument/qemu-instr/types.inc.h
@@ -0,0 +1,15 @@
+/*
+ * QEMU-specific types for instrumentation clients.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include 
+
+
+struct QITraceEventIter {
+char buffer[(sizeof(size_t) * 2) + sizeof(char *)];
+};
diff --git a/instrument/trace.c b/instrument/trace.c
new file mode 100644
index 00..6a437039b4
--- /dev/null
+++ b/instrument/trace.c
@@ -0,0 +1,125 @@
+/*
+ * API for QEMU's tracing events.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "instrument/error.h"
+#include "qemu/compiler.h"
+#include "qemu-instr/trace.h"
+#include "trace/control.h"
+
+
+SYM_PUBLIC
+QITraceEvent *qi_trace_event_name(const char *name)
+{
+ERROR_IF_RET(!name, NULL, "must provide a name");
+return (QITraceEvent *)trace_event_name(name);
+}
+
+SYM_PUBLIC
+void qi_trace_event_iter_init(QITraceEventIter *iter, const char *pattern)
+{
+TraceEventIter *iter_ = (TraceEventIter *)iter;
+ERROR_IF(!iter_, "must provide an iterator");
+trace_event_iter_init(iter_, pattern);
+}
+
+SYM_PUBLIC
+QITraceEvent *qi_trace_even

[Qemu-devel] [PATCH v5 11/22] instrument: Track vCPUs

2017-09-12 Thread Lluís Vilanova
Keep a translation between instrumentation's QICPU and CPUState objects to avoid
exposing QEMU's internals to instrumentation clients.

Signed-off-by: Lluís Vilanova 
---
 cpus-common.c|9 +
 instrument/control.c |   23 +++
 instrument/control.h |   36 
 instrument/control.inc.h |   23 +++
 4 files changed, 91 insertions(+)

diff --git a/cpus-common.c b/cpus-common.c
index 59f751ecf9..ec5f46cc3d 100644
--- a/cpus-common.c
+++ b/cpus-common.c
@@ -22,6 +22,9 @@
 #include "exec/cpu-common.h"
 #include "qom/cpu.h"
 #include "sysemu/cpus.h"
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/control.h"
+#endif
 
 static QemuMutex qemu_cpu_list_lock;
 static QemuCond exclusive_cond;
@@ -84,6 +87,9 @@ void cpu_list_add(CPUState *cpu)
 } else {
 assert(!cpu_index_auto_assigned);
 }
+#if defined(CONFIG_INSTRUMENT)
+instr_cpu_add(cpu);
+#endif
 QTAILQ_INSERT_TAIL(&cpus, cpu, node);
 qemu_mutex_unlock(&qemu_cpu_list_lock);
 
@@ -102,6 +108,9 @@ void cpu_list_remove(CPUState *cpu)
 assert(!(cpu_index_auto_assigned && cpu != QTAILQ_LAST(&cpus, CPUTailQ)));
 
 QTAILQ_REMOVE(&cpus, cpu, node);
+#if defined(CONFIG_INSTRUMENT)
+instr_cpu_remove(cpu);
+#endif
 cpu->cpu_index = UNASSIGNED_CPU_INDEX;
 qemu_mutex_unlock(&qemu_cpu_list_lock);
 }
diff --git a/instrument/control.c b/instrument/control.c
index 3630d6b3be..8cf2b4f967 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -13,10 +13,33 @@
 #include "instrument/load.h"
 #include "instrument/qemu-instr/control.h"
 #include "qemu/compiler.h"
+#include "qom/cpu.h"
+
 
 __thread InstrState instr_cur_state;
 
 
+unsigned int instr_cpus_count;
+CPUState **instr_cpus;
+
+void instr_cpu_add(CPUState *vcpu)
+{
+unsigned int idx = vcpu->cpu_index;
+if (idx >= instr_cpus_count) {
+instr_cpus_count = idx + 1;
+instr_cpus = realloc(instr_cpus,
+ sizeof(*instr_cpus) * instr_cpus_count);
+}
+instr_cpus[idx] = vcpu;
+}
+
+void instr_cpu_remove(CPUState *vcpu)
+{
+unsigned int idx = vcpu->cpu_index;
+instr_cpus[idx] = NULL;
+}
+
+
 qi_fini_fn instr_event__fini_fn;
 void *instr_event__fini_data;
 
diff --git a/instrument/control.h b/instrument/control.h
index f2b085f69b..57cea07fa7 100644
--- a/instrument/control.h
+++ b/instrument/control.h
@@ -10,6 +10,42 @@
 #ifndef INSTRUMENT__CONTROL_H
 #define INSTRUMENT__CONTROL_H
 
+#include "qemu/typedefs.h"
+#include "instrument/qemu-instr/types.h"
+
+
+/**
+ * instr_cpu_add:
+ *
+ * Make @vcpu available to instrumentation clients.
+ *
+ * Precondition: cpu_list_lock().
+ */
+void instr_cpu_add(CPUState *vcpu);
+
+/**
+ * instr_cpu_remove:
+ *
+ * Make @vcpu unavailable to instrumentation clients.
+ *
+ * Precondition: cpu_list_lock().
+ */
+void instr_cpu_remove(CPUState *vcpu);
+
+/**
+ * instr_cpu_to_qicpu:
+ *
+ * Get the #QICPU corresponding to the given #CPUState.
+ */
+static inline QICPU instr_cpu_to_qicpu(CPUState *vcpu);
+
+/**
+ * instr_cpu_from_qicpu:
+ *
+ * Get the #CPUState corresponding to the given #QICPU.
+ */
+static inline CPUState *instr_cpu_from_qicpu(QICPU vcpu);
+
 
 /**
  * InstrState:
diff --git a/instrument/control.inc.h b/instrument/control.inc.h
index 0f649f4caa..45daae7d1d 100644
--- a/instrument/control.inc.h
+++ b/instrument/control.inc.h
@@ -7,9 +7,32 @@
  * See the COPYING file in the top-level directory.
  */
 
+#include "qemu/osdep.h"
 #include "qemu/atomic.h"
 #include "qemu/compiler.h"
+#include "qom/cpu.h"
 #include 
+#include 
+
+
+extern unsigned int instr_cpus_count;
+extern CPUState **instr_cpus;
+
+static inline QICPU instr_cpu_to_qicpu(CPUState *vcpu)
+{
+uintptr_t idx = vcpu->cpu_index;
+return (QICPU)idx;
+}
+
+static inline CPUState *instr_cpu_from_qicpu(QICPU vcpu)
+{
+unsigned int idx = (uintptr_t)vcpu;
+if (idx >= instr_cpus_count) {
+return NULL;
+} else {
+return instr_cpus[idx];
+}
+}
 
 
 extern __thread InstrState instr_cur_state;




[Qemu-devel] [PATCH v5 12/22] instrument: Add event 'guest_cpu_enter'

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 instrument/control.c|9 
 instrument/events.h |5 
 instrument/events.inc.h |   11 +
 instrument/load.c   |9 
 instrument/qemu-instr/control.h |   46 +++
 stubs/instrument.c  |1 +
 trace/control-target.c  |2 ++
 7 files changed, 83 insertions(+)

diff --git a/instrument/control.c b/instrument/control.c
index 8cf2b4f967..c4b3ca0440 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -49,3 +49,12 @@ SYM_PUBLIC void qi_set_fini(qi_fini_fn fn, void *data)
 instr_set_event(fini_fn, fn);
 instr_set_event(fini_data, data);
 }
+
+
+void (*instr_event__guest_cpu_enter)(QICPU vcpu);
+
+SYM_PUBLIC void qi_event_set_guest_cpu_enter(void (*fn)(QICPU vcpu))
+{
+ERROR_IF(!instr_get_state(), "called outside instrumentation");
+instr_set_event(guest_cpu_enter, fn);
+}
diff --git a/instrument/events.h b/instrument/events.h
index 82ad0bd827..947f120aa9 100644
--- a/instrument/events.h
+++ b/instrument/events.h
@@ -11,6 +11,7 @@
 #define INSTRUMENT__EVENTS_H
 
 #include "instrument/qemu-instr/control.h"
+#include "instrument/qemu-instr/types.h"
 
 /**
  * instr_get_event:
@@ -32,6 +33,10 @@
 extern qi_fini_fn instr_event__fini_fn;
 extern void *instr_event__fini_data;
 
+extern void (*instr_event__guest_cpu_enter)(QICPU vcpu);
+static inline void instr_guest_cpu_enter(CPUState *vcpu);
+
+
 #include "instrument/events.inc.h"
 
 #endif  /* INSTRUMENT__EVENTS_H */
diff --git a/instrument/events.inc.h b/instrument/events.inc.h
index 8b1ce7fcb2..e3f8024716 100644
--- a/instrument/events.inc.h
+++ b/instrument/events.inc.h
@@ -7,5 +7,16 @@
  * See the COPYING file in the top-level directory.
  */
 
+#include "instrument/control.h"
 
 
+static inline void instr_guest_cpu_enter(CPUState *vcpu)
+{
+void (*cb)(QICPU vcpu) = instr_get_event(guest_cpu_enter);
+if (cb) {
+QICPU vcpu_ = instr_cpu_to_qicpu(vcpu);
+instr_set_state(INSTR_STATE_ENABLE);
+(*cb)(vcpu_);
+instr_set_state(INSTR_STATE_DISABLE);
+}
+}
diff --git a/instrument/load.c b/instrument/load.c
index a01d66a4d4..218bca74b2 100644
--- a/instrument/load.c
+++ b/instrument/load.c
@@ -11,6 +11,7 @@
 #include "qemu-common.h"
 
 #include 
+#include "exec/cpu-common.h"
 #include "instrument/control.h"
 #include "instrument/events.h"
 #include "instrument/load.h"
@@ -109,6 +110,13 @@ InstrLoadError instr_load(const char *path, int argc, 
const char **argv,
 goto err;
 }
 
+cpu_list_lock();
+CPUState *cpu;
+CPU_FOREACH(cpu) {
+instr_guest_cpu_enter(cpu);
+}
+cpu_list_unlock();
+
 res = INSTR_LOAD_OK;
 goto out;
 
@@ -138,6 +146,7 @@ InstrUnloadError instr_unload(const char *id)
 }
 
 instr_set_event(fini_fn, NULL);
+instr_set_event(guest_cpu_enter, NULL);
 
 /* this should never fail */
 if (dlclose(handle->dlhandle) < 0) {
diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/control.h
index b841afaa31..f61e7a2b6e 100644
--- a/instrument/qemu-instr/control.h
+++ b/instrument/qemu-instr/control.h
@@ -16,6 +16,7 @@ extern "C" {
 
 #include 
 #include 
+#include 
 
 
 /**
@@ -39,6 +40,51 @@ typedef void (*qi_fini_fn)(void *arg);
  */
 void qi_set_fini(qi_fini_fn fn, void *data);
 
+
+/*
+ * Set callbacks for available events. Each event has a short description and
+ * various indicators of when it can be triggered:
+ *
+ * - Mode :: user
+ *   Triggered in QEMU user application emulation (e.g., linux-user).
+ *
+ * - Mode :: softmmy
+ *   Triggered in QEMU full-system emulation.
+ *
+ *
+ * - Targets :: all
+ *   Triggered on all targets, both using TCG or native hardware virtualization
+ *   (e.g., KVM).
+ *
+ * - Targets :: TCG()
+ *   Triggered on the given guest target architectures when executing with TCG
+ *   (no native hardware virtualization).
+ *
+ *
+ * - Time :: exec
+ *   Triggered when the guest executes the described operation.
+ *
+ * - Time :: trans
+ *   Triggered when QEMU translates a guest operation. This is only available
+ *   when executing with TCG. Guest instructions are decompiled and translated
+ *   into the intermediate TCG language (when "Time: trans" events are
+ *   triggered). Then, the TCG compiler translates TCG code into the native 
host
+ *   code that QEMU will execute to emulate the guest (when "Time: exec" events
+ *   are triggered). As QEMU uses a cache of translated code, the same
+ *   instruction might be translated more than once (when the cache overflows).
+ */
+
+/*
+ * Hot-plug a new virtual (guest) CPU.
+ *
+ * Also triggered on each CPU when an instrumentation library is loaded.
+ *
+ * Mode: user, softmmu
+ * Targets: all
+ * Time: exec
+ */
+void qi_event_set_guest_cpu_enter(void (*fn)(QICPU vcpu));
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/stubs/instrument.c b/stubs/instrument.c
index 9498fcdfe5..6

Re: [Qemu-devel] [Bug 1716767] Re: file(1) fails with "Invalid argument" on qemu-sh4-user

2017-09-12 Thread John Paul Adrian Glaubitz
On 09/12/2017 11:18 PM, James Clarke wrote:
> The "0 == 18446744073709551615 = 0" is actually fine, it's just printing
> "-1" as a 64-bit unsigned integer.

Yeah, I noticed that output was the same on amd64.

> Could you please upload the fill
> output of `file -d /bin/bash 2>&1`?

> https://people.debian.org/~glaubitz/file-sh4-qemu.txt

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaub...@debian.org
`. `'   Freie Universitaet Berlin - glaub...@physik.fu-berlin.de
  `-GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

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

Title:
  file(1) fails with "Invalid argument" on qemu-sh4-user

Status in QEMU:
  New

Bug description:
  We recently discovered that file(1) fails on qemu-sh4-user when
  running on an ELF file:

  (sid_sh4)root@vs94:/# file /bin/bash
  /bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) 
error reading (Invalid argument)
  (sid_sh4)root@vs94:/#

  Running with "-d" yields more output:

  (sid_sh4)root@vs94:/# file -d /bin/bash 2>&1 | tail
  322: >> 7 byte&,=97,"(ARM)"]
  0 == 97 = 0
  mget(type=1, flag=0, offset=7, o=0, nbytes=863324, il=0, nc=1)
  mget/96 @7: 
\000\000\000\000\000\000\000\000\000\002\000*\000\001\000\000\000\250\317A\0004\000\000\000L(\r\000\027\000\000\0004\000
 
\000\n\000(\000\032\000\031\000\006\000\000\0004\000\000\0004\000@\0004\000@\000@\001\000\000@\001\000\000\005\000\000\000\004\000\000\000\003\000\000\000t\001\000\000t\001@\000t\001@\000\023\000\000

  323: >> 7 byte&,=-1,"(embedded)"]
  0 == 18446744073709551615 = 0
  [try softmagic 1]
  [try elf -1]
  /bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) 
error reading (Invalid argument)
  (sid_sh4)root@vs94:/#

  It seems that the comparison above has a bogus (overflown?) value.

  On actual hardware, it works:

  root@tirpitz:~> file /bin/bash
  /bin/bash: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV), 
dynamically linked, interpreter /lib/ld-linux.so.2, 
BuildID[sha1]=4dd0e4281755827d8bb6686fd481f8c80ea73e9a, for GNU/Linux 3.2.0, 
stripped
  root@tirpitz:~>

  I have uploaded a chroot with Debian unstable which allows to
  reproduce the issue:

  > https://people.debian.org/~glaubitz/sid-sh4-sbuild.tar.gz

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



[Qemu-devel] [PATCH v5 13/22] instrument: Support synchronous modification of vCPU state

2017-09-12 Thread Lluís Vilanova
Stops all vCPUs to allow performing management operations like TB
invalidations. These are later necessary to ensure translated code does not
reference unloaded instrumentation libraries.

Signed-off-by: Lluís Vilanova 
---
 instrument/control.c |   66 ++
 instrument/control.h |   26 ++
 instrument/control.inc.h |   11 
 3 files changed, 103 insertions(+)

diff --git a/instrument/control.c b/instrument/control.c
index c4b3ca0440..20ddffdc28 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -13,6 +13,7 @@
 #include "instrument/load.h"
 #include "instrument/qemu-instr/control.h"
 #include "qemu/compiler.h"
+#include "qemu/main-loop.h"
 #include "qom/cpu.h"
 
 
@@ -40,6 +41,71 @@ void instr_cpu_remove(CPUState *vcpu)
 }
 
 
+static void instr_cpu_stop_all__cb(CPUState *cpu, run_on_cpu_data data)
+{
+InstrCPUStop *info = data.host_ptr;
+/* run posted function */
+if (info->fun) {
+info->fun(cpu, info->data);
+}
+#if !defined(CONFIG_USER_ONLY)
+/* signal we're out of the main vCPU loop */
+unsigned int count = atomic_load_acquire(&info->count);
+atomic_store_release(&info->count, count + 1);
+atomic_store_release(&info->stopped, true);
+/* wait until we're good to go again */
+qemu_cond_wait(&info->cond, &info->mutex);
+count = atomic_load_acquire(&info->count);
+atomic_store_release(&info->count, count - 1);
+qemu_mutex_unlock(&info->mutex);
+#endif
+}
+
+void instr_cpu_stop_all_begin(InstrCPUStop *info,
+  instr_cpu_stop_fun fun, void *data)
+{
+CPUState *cpu;
+
+info->fun = fun;
+info->data = data;
+
+#if !defined(CONFIG_USER_ONLY)
+info->count = 0;
+qemu_cond_init(&info->cond);
+qemu_mutex_init(&info->mutex);
+
+/* main dispatch loop and run_on_cpu() lock the BQL */
+qemu_mutex_unlock_iothread();
+#endif
+
+CPU_FOREACH(cpu) {
+#if !defined(CONFIG_USER_ONLY)
+atomic_store_release(&info->stopped, false);
+qemu_mutex_lock(&info->mutex);
+async_run_on_cpu(cpu, instr_cpu_stop_all__cb, 
RUN_ON_CPU_HOST_PTR(info));
+while (!atomic_load_acquire(&info->stopped)) {
+/* wait for vCPU to signal it's stopped */
+}
+#else
+instr_cpu_stop_all__cb(cpu, RUN_ON_CPU_HOST_PTR(info));
+#endif
+}
+}
+
+void instr_cpu_stop_all_end(InstrCPUStop *info)
+{
+#if !defined(CONFIG_USER_ONLY)
+qemu_cond_broadcast(&info->cond);
+while (atomic_load_acquire(&info->count)) {
+/* wait for all vCPUs to continue before we can destroy info */
+}
+qemu_cond_destroy(&info->cond);
+qemu_mutex_destroy(&info->mutex);
+qemu_mutex_lock_iothread();
+#endif
+}
+
+
 qi_fini_fn instr_event__fini_fn;
 void *instr_event__fini_data;
 
diff --git a/instrument/control.h b/instrument/control.h
index 57cea07fa7..03e87b2b8f 100644
--- a/instrument/control.h
+++ b/instrument/control.h
@@ -46,6 +46,32 @@ static inline QICPU instr_cpu_to_qicpu(CPUState *vcpu);
  */
 static inline CPUState *instr_cpu_from_qicpu(QICPU vcpu);
 
+typedef struct InstrCPUStop InstrCPUStop;
+typedef void (*instr_cpu_stop_fun)(CPUState *cpu, void *data);
+
+/**
+ * instr_cpu_stop_all_begin:
+ * @info: Opaque structure describing the operation.
+ * @fun: Function to run on the context of each vCPU once stopped.
+ * @data: Pointer to pass to @fun.
+ *
+ * Ensure all vCPUs stop executing guest code, and execute @fun on their 
context
+ * in turn. Returns with all vCPUs still stopped.
+ *
+ * Assumes cpu_list_lock() and that the QBL is locked before calling.
+ */
+void instr_cpu_stop_all_begin(InstrCPUStop *info,
+  instr_cpu_stop_fun fun, void *data);
+
+/**
+ * instr_cpu_stop_all_end:
+ * @info: Opaque structure passed to a previous instr_cpu_stop_all_begin()
+ * call.
+ *
+ * Resume execution on all vCPUs stopped by instr_cpu_stop_all_begin().
+ */
+void instr_cpu_stop_all_end(InstrCPUStop *info);
+
 
 /**
  * InstrState:
diff --git a/instrument/control.inc.h b/instrument/control.inc.h
index 45daae7d1d..6d65b23ead 100644
--- a/instrument/control.inc.h
+++ b/instrument/control.inc.h
@@ -15,6 +15,17 @@
 #include 
 
 
+struct InstrCPUStop {
+instr_cpu_stop_fun fun;
+void *data;
+#if !defined(CONFIG_USER_ONLY)
+bool stopped;
+unsigned int count;
+QemuCond cond;
+QemuMutex mutex;
+#endif
+};
+
 extern unsigned int instr_cpus_count;
 extern CPUState **instr_cpus;
 




[Qemu-devel] [PATCH v5 14/22] exec: Add function to synchronously flush TB on a stopped vCPU

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 accel/stubs/tcg-stub.c|3 +++
 accel/tcg/translate-all.c |7 +++
 include/exec/exec-all.h   |1 +
 3 files changed, 11 insertions(+)

diff --git a/accel/stubs/tcg-stub.c b/accel/stubs/tcg-stub.c
index 5dd480b1a2..5226c4a8a4 100644
--- a/accel/stubs/tcg-stub.c
+++ b/accel/stubs/tcg-stub.c
@@ -20,3 +20,6 @@
 void tb_flush(CPUState *cpu)
 {
 }
+void tb_flush_sync(CPUState *cpu)
+{
+}
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 2d1ed06065..a334ac4ccb 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -929,6 +929,13 @@ done:
 tb_unlock();
 }
 
+void tb_flush_sync(CPUState *cpu)
+{
+unsigned tb_flush_count = atomic_mb_read(&tcg_ctx.tb_ctx.tb_flush_count);
+assert(cpu == current_cpu);
+do_tb_flush(cpu, RUN_ON_CPU_HOST_INT(tb_flush_count));
+}
+
 void tb_flush(CPUState *cpu)
 {
 if (tcg_enabled()) {
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 673fc066d0..3f38186a5e 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -358,6 +358,7 @@ struct TranslationBlock {
 
 void tb_free(TranslationBlock *tb);
 void tb_flush(CPUState *cpu);
+void tb_flush_sync(CPUState *cpu);
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
 TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
target_ulong cs_base, uint32_t flags);




[Qemu-devel] [Bug 1716767] Re: file(1) fails with "Invalid argument" on qemu-sh4-user

2017-09-12 Thread James Clarke
I just ran it myself inside and outside the sh4 chroot. The logging
output is the same, with the exception of the final line. Something is
happening once it's decided it's elf; looking at file_tryelf, my guess
is the fstat call is failing[0].

[0] http://sources.debian.net/src/file/1:5.31-1/src/readelf.c/#L1609

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

Title:
  file(1) fails with "Invalid argument" on qemu-sh4-user

Status in QEMU:
  New

Bug description:
  We recently discovered that file(1) fails on qemu-sh4-user when
  running on an ELF file:

  (sid_sh4)root@vs94:/# file /bin/bash
  /bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) 
error reading (Invalid argument)
  (sid_sh4)root@vs94:/#

  Running with "-d" yields more output:

  (sid_sh4)root@vs94:/# file -d /bin/bash 2>&1 | tail
  322: >> 7 byte&,=97,"(ARM)"]
  0 == 97 = 0
  mget(type=1, flag=0, offset=7, o=0, nbytes=863324, il=0, nc=1)
  mget/96 @7: 
\000\000\000\000\000\000\000\000\000\002\000*\000\001\000\000\000\250\317A\0004\000\000\000L(\r\000\027\000\000\0004\000
 
\000\n\000(\000\032\000\031\000\006\000\000\0004\000\000\0004\000@\0004\000@\000@\001\000\000@\001\000\000\005\000\000\000\004\000\000\000\003\000\000\000t\001\000\000t\001@\000t\001@\000\023\000\000

  323: >> 7 byte&,=-1,"(embedded)"]
  0 == 18446744073709551615 = 0
  [try softmagic 1]
  [try elf -1]
  /bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) 
error reading (Invalid argument)
  (sid_sh4)root@vs94:/#

  It seems that the comparison above has a bogus (overflown?) value.

  On actual hardware, it works:

  root@tirpitz:~> file /bin/bash
  /bin/bash: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV), 
dynamically linked, interpreter /lib/ld-linux.so.2, 
BuildID[sha1]=4dd0e4281755827d8bb6686fd481f8c80ea73e9a, for GNU/Linux 3.2.0, 
stripped
  root@tirpitz:~>

  I have uploaded a chroot with Debian unstable which allows to
  reproduce the issue:

  > https://people.debian.org/~glaubitz/sid-sh4-sbuild.tar.gz

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



[Qemu-devel] [PATCH v5 15/22] instrument: Add event 'guest_cpu_exit'

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 instrument/control.c|9 +
 instrument/events.h |3 +++
 instrument/events.inc.h |   11 +++
 instrument/load.c   |   17 +
 instrument/qemu-instr/control.h |   11 +++
 stubs/instrument.c  |1 +
 trace/control.c |4 +++-
 7 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/instrument/control.c b/instrument/control.c
index 20ddffdc28..0be8065409 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -124,3 +124,12 @@ SYM_PUBLIC void qi_event_set_guest_cpu_enter(void 
(*fn)(QICPU vcpu))
 ERROR_IF(!instr_get_state(), "called outside instrumentation");
 instr_set_event(guest_cpu_enter, fn);
 }
+
+
+void (*instr_event__guest_cpu_exit)(QICPU vcpu);
+
+SYM_PUBLIC void qi_event_set_guest_cpu_exit(void (*fn)(QICPU vcpu))
+{
+ERROR_IF(!instr_get_state(), "called outside instrumentation");
+instr_set_event(guest_cpu_exit, fn);
+}
diff --git a/instrument/events.h b/instrument/events.h
index 947f120aa9..c743cb8180 100644
--- a/instrument/events.h
+++ b/instrument/events.h
@@ -36,6 +36,9 @@ extern void *instr_event__fini_data;
 extern void (*instr_event__guest_cpu_enter)(QICPU vcpu);
 static inline void instr_guest_cpu_enter(CPUState *vcpu);
 
+extern void (*instr_event__guest_cpu_exit)(QICPU vcpu);
+static inline void instr_guest_cpu_exit(CPUState *vcpu);
+
 
 #include "instrument/events.inc.h"
 
diff --git a/instrument/events.inc.h b/instrument/events.inc.h
index e3f8024716..c88df7e42f 100644
--- a/instrument/events.inc.h
+++ b/instrument/events.inc.h
@@ -20,3 +20,14 @@ static inline void instr_guest_cpu_enter(CPUState *vcpu)
 instr_set_state(INSTR_STATE_DISABLE);
 }
 }
+
+static inline void instr_guest_cpu_exit(CPUState *vcpu)
+{
+void (*cb)(QICPU vcpu) = instr_get_event(guest_cpu_exit);
+if (cb) {
+QICPU vcpu_ = instr_cpu_to_qicpu(vcpu);
+instr_set_state(INSTR_STATE_ENABLE);
+(*cb)(vcpu_);
+instr_set_state(INSTR_STATE_DISABLE);
+}
+}
diff --git a/instrument/load.c b/instrument/load.c
index 218bca74b2..6808d361b5 100644
--- a/instrument/load.c
+++ b/instrument/load.c
@@ -11,7 +11,9 @@
 #include "qemu-common.h"
 
 #include 
+#include "cpu.h"
 #include "exec/cpu-common.h"
+#include "exec/exec-all.h"
 #include "instrument/control.h"
 #include "instrument/events.h"
 #include "instrument/load.h"
@@ -127,6 +129,13 @@ out:
 return res;
 }
 
+
+static void instr_unload__cb(CPUState *cpu, void *data)
+{
+tb_flush_sync(cpu);
+instr_guest_cpu_exit(cpu);
+}
+
 InstrUnloadError instr_unload(const char *id)
 {
 InstrUnloadError res;
@@ -139,6 +148,10 @@ InstrUnloadError instr_unload(const char *id)
 goto out;
 }
 
+InstrCPUStop info;
+cpu_list_lock();
+instr_cpu_stop_all_begin(&info, instr_unload__cb, NULL);
+
 qi_fini_fn fini_fn = instr_get_event(fini_fn);
 if (fini_fn) {
 void *fini_data = instr_get_event(fini_data);
@@ -147,6 +160,10 @@ InstrUnloadError instr_unload(const char *id)
 
 instr_set_event(fini_fn, NULL);
 instr_set_event(guest_cpu_enter, NULL);
+instr_set_event(guest_cpu_exit, NULL);
+
+instr_cpu_stop_all_end(&info);
+cpu_list_unlock();
 
 /* this should never fail */
 if (dlclose(handle->dlhandle) < 0) {
diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/control.h
index f61e7a2b6e..107ee8afe0 100644
--- a/instrument/qemu-instr/control.h
+++ b/instrument/qemu-instr/control.h
@@ -85,6 +85,17 @@ void qi_set_fini(qi_fini_fn fn, void *data);
  */
 void qi_event_set_guest_cpu_enter(void (*fn)(QICPU vcpu));
 
+/*
+ * Hot-unplug a virtual (guest) CPU.
+ *
+ * Also triggered on each CPU when an instrumentation library is unloaded.
+ *
+ * Mode: user, softmmu
+ * Targets: all
+ * Time: exec
+ */
+void qi_event_set_guest_cpu_exit(void (*fn)(QICPU vcpu));
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/stubs/instrument.c b/stubs/instrument.c
index 6b59ba9a7a..c4b1c791d9 100644
--- a/stubs/instrument.c
+++ b/stubs/instrument.c
@@ -47,3 +47,4 @@ void qmp_instr_unload(const char *id, Error **errp)
 
 __thread InstrState instr_cur_state;
 void (*instr_event__guest_cpu_enter)(QICPU *vcpu);
+void (*instr_event__guest_cpu_exit)(QICPU *vcpu);
diff --git a/trace/control.c b/trace/control.c
index 82d8989c4d..946a0af818 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -1,13 +1,14 @@
 /*
  * Interface for configuring and controlling the state of tracing events.
  *
- * Copyright (C) 2011-2016 Lluís Vilanova 
+ * Copyright (C) 2011-2017 Lluís Vilanova 
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
 
 #include "qemu/osdep.h"
+#include "instrument/events.h"
 #include "trace/control.h"
 #include "qemu/help_option.h"
 #ifdef CONFIG_TRACE_SIMPLE
@@ -272,6 +273,7 @@ void trace_fini_vcpu(CPUState *vcpu)
   

[Qemu-devel] [PATCH v5 16/22] instrument: Add event 'guest_cpu_reset'

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 instrument/control.c|9 +
 instrument/events.h |3 +++
 instrument/events.inc.h |   11 +++
 instrument/load.c   |1 +
 instrument/qemu-instr/control.h |9 +
 qom/cpu.c   |2 ++
 stubs/instrument.c  |1 +
 7 files changed, 36 insertions(+)

diff --git a/instrument/control.c b/instrument/control.c
index 0be8065409..401189db2e 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -133,3 +133,12 @@ SYM_PUBLIC void qi_event_set_guest_cpu_exit(void 
(*fn)(QICPU vcpu))
 ERROR_IF(!instr_get_state(), "called outside instrumentation");
 instr_set_event(guest_cpu_exit, fn);
 }
+
+
+void (*instr_event__guest_cpu_reset)(QICPU vcpu);
+
+SYM_PUBLIC void qi_event_set_guest_cpu_reset(void (*fn)(QICPU vcpu))
+{
+ERROR_IF(!instr_get_state(), "called outside instrumentation");
+instr_set_event(guest_cpu_reset, fn);
+}
diff --git a/instrument/events.h b/instrument/events.h
index c743cb8180..4a0560490a 100644
--- a/instrument/events.h
+++ b/instrument/events.h
@@ -39,6 +39,9 @@ static inline void instr_guest_cpu_enter(CPUState *vcpu);
 extern void (*instr_event__guest_cpu_exit)(QICPU vcpu);
 static inline void instr_guest_cpu_exit(CPUState *vcpu);
 
+extern void (*instr_event__guest_cpu_reset)(QICPU vcpu);
+static inline void instr_guest_cpu_reset(CPUState *vcpu);
+
 
 #include "instrument/events.inc.h"
 
diff --git a/instrument/events.inc.h b/instrument/events.inc.h
index c88df7e42f..a126ba5ae6 100644
--- a/instrument/events.inc.h
+++ b/instrument/events.inc.h
@@ -31,3 +31,14 @@ static inline void instr_guest_cpu_exit(CPUState *vcpu)
 instr_set_state(INSTR_STATE_DISABLE);
 }
 }
+
+static inline void instr_guest_cpu_reset(CPUState *vcpu)
+{
+void (*cb)(QICPU vcpu) = instr_get_event(guest_cpu_reset);
+if (cb) {
+QICPU vcpu_ = instr_cpu_to_qicpu(vcpu);
+instr_set_state(INSTR_STATE_ENABLE);
+(*cb)(vcpu_);
+instr_set_state(INSTR_STATE_DISABLE);
+}
+}
diff --git a/instrument/load.c b/instrument/load.c
index 6808d361b5..8c15a73a8c 100644
--- a/instrument/load.c
+++ b/instrument/load.c
@@ -161,6 +161,7 @@ InstrUnloadError instr_unload(const char *id)
 instr_set_event(fini_fn, NULL);
 instr_set_event(guest_cpu_enter, NULL);
 instr_set_event(guest_cpu_exit, NULL);
+instr_set_event(guest_cpu_reset, NULL);
 
 instr_cpu_stop_all_end(&info);
 cpu_list_unlock();
diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/control.h
index 107ee8afe0..322009100d 100644
--- a/instrument/qemu-instr/control.h
+++ b/instrument/qemu-instr/control.h
@@ -96,6 +96,15 @@ void qi_event_set_guest_cpu_enter(void (*fn)(QICPU vcpu));
  */
 void qi_event_set_guest_cpu_exit(void (*fn)(QICPU vcpu));
 
+/*
+ * Reset the state of a virtual (guest) CPU.
+ *
+ * Mode: user, softmmu
+ * Targets: all
+ * Time: exec
+ */
+void qi_event_set_guest_cpu_reset(void (*fn)(QICPU vcpu));
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/qom/cpu.c b/qom/cpu.c
index dc5392dbeb..6336d63f66 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -19,6 +19,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "instrument/events.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
 #include "qom/cpu.h"
@@ -275,6 +276,7 @@ void cpu_reset(CPUState *cpu)
 (*klass->reset)(cpu);
 }
 
+instr_guest_cpu_reset(cpu);
 trace_guest_cpu_reset(cpu);
 }
 
diff --git a/stubs/instrument.c b/stubs/instrument.c
index c4b1c791d9..dda2ae88c5 100644
--- a/stubs/instrument.c
+++ b/stubs/instrument.c
@@ -48,3 +48,4 @@ void qmp_instr_unload(const char *id, Error **errp)
 __thread InstrState instr_cur_state;
 void (*instr_event__guest_cpu_enter)(QICPU *vcpu);
 void (*instr_event__guest_cpu_exit)(QICPU *vcpu);
+void (*instr_event__guest_cpu_reset)(QICPU *vcpu);




Re: [Qemu-devel] [Bug 1716767] Re: file(1) fails with "Invalid argument" on qemu-sh4-user

2017-09-12 Thread Peter Maydell
On 12 September 2017 at 22:47, James Clarke  wrote:
> I just ran it myself inside and outside the sh4 chroot. The logging
> output is the same, with the exception of the final line. Something is
> happening once it's decided it's elf; looking at file_tryelf, my guess
> is the fstat call is failing[0].

strace could probably confirm or deny that. I would be unsurprised
if the linux-user definitions for the structure layouts for the
various stat structs were wrong for sh4.

thanks
-- PMM




[Qemu-devel] [PATCH v5 17/22] trace: Introduce a proper structure to describe memory accesses

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 include/exec/cpu_ldst_template.h  |   15 ++
 include/exec/cpu_ldst_useronly_template.h |   15 ++
 tcg/tcg-op.c  |   22 +
 trace/mem-internal.h  |   22 -
 trace/mem.h   |   31 +
 5 files changed, 66 insertions(+), 39 deletions(-)

diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
index 4db2302962..debbabcfb2 100644
--- a/include/exec/cpu_ldst_template.h
+++ b/include/exec/cpu_ldst_template.h
@@ -88,9 +88,8 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), 
_ra)(CPUArchState *env,
 TCGMemOpIdx oi;
 
 #if !defined(SOFTMMU_CODE_ACCESS)
-trace_guest_mem_before_exec(
-ENV_GET_CPU(env), ptr,
-trace_mem_build_info(SHIFT, false, MO_TE, false));
+TraceMemInfo meminfo = trace_mem_build_info(SHIFT, false, MO_TE, false);
+trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 
 addr = ptr;
@@ -126,9 +125,8 @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), 
_ra)(CPUArchState *env,
 TCGMemOpIdx oi;
 
 #if !defined(SOFTMMU_CODE_ACCESS)
-trace_guest_mem_before_exec(
-ENV_GET_CPU(env), ptr,
-trace_mem_build_info(SHIFT, true, MO_TE, false));
+TraceMemInfo meminfo = trace_mem_build_info(SHIFT, true, MO_TE, false);
+trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 
 addr = ptr;
@@ -168,9 +166,8 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), 
_ra)(CPUArchState *env,
 TCGMemOpIdx oi;
 
 #if !defined(SOFTMMU_CODE_ACCESS)
-trace_guest_mem_before_exec(
-ENV_GET_CPU(env), ptr,
-trace_mem_build_info(SHIFT, false, MO_TE, true));
+TraceMemInfo meminfo = trace_mem_build_info(SHIFT, false, MO_TE, true);
+trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 
 addr = ptr;
diff --git a/include/exec/cpu_ldst_useronly_template.h 
b/include/exec/cpu_ldst_useronly_template.h
index 7b8c7c506e..b0b3fc1b8d 100644
--- a/include/exec/cpu_ldst_useronly_template.h
+++ b/include/exec/cpu_ldst_useronly_template.h
@@ -61,9 +61,8 @@ static inline RES_TYPE
 glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
 {
 #if !defined(CODE_ACCESS)
-trace_guest_mem_before_exec(
-ENV_GET_CPU(env), ptr,
-trace_mem_build_info(DATA_SIZE, false, MO_TE, false));
+TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, false, MO_TE, 
false);
+trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 return glue(glue(ld, USUFFIX), _p)(g2h(ptr));
 }
@@ -81,9 +80,8 @@ static inline int
 glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
 {
 #if !defined(CODE_ACCESS)
-trace_guest_mem_before_exec(
-ENV_GET_CPU(env), ptr,
-trace_mem_build_info(DATA_SIZE, true, MO_TE, false));
+TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, true, MO_TE, false);
+trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 return glue(glue(lds, SUFFIX), _p)(g2h(ptr));
 }
@@ -103,9 +101,8 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, 
target_ulong ptr,
   RES_TYPE v)
 {
 #if !defined(CODE_ACCESS)
-trace_guest_mem_before_exec(
-ENV_GET_CPU(env), ptr,
-trace_mem_build_info(DATA_SIZE, false, MO_TE, true));
+TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, false, MO_TE, true);
+trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 glue(glue(st, SUFFIX), _p)(g2h(ptr), v);
 }
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 688d91755b..6edf70bdfc 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -2676,24 +2676,28 @@ static void tcg_gen_req_mo(TCGBar type)
 
 void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
 {
+TraceMemInfo meminfo;
 tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
 memop = tcg_canonicalize_memop(memop, 0, 0);
-trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env,
-   addr, trace_mem_get_info(memop, 0));
+meminfo = trace_mem_get_info(memop, 0);
+trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, 
meminfo.raw);
 gen_ldst_i32(INDEX_op_qemu_ld_i32, val, addr, memop, idx);
 }
 
 void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
 {
+TraceMemInfo meminfo;
 tcg_gen_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST);
 memop = tcg_canonicalize_memop(memop, 0, 1);
-trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env,
-   addr, trace_mem_get_info(memop, 1));
+meminfo = trace_mem_get_info(memop, 1);
+trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, 
meminfo.raw);
 gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx);
 }
 
 void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCG

[Qemu-devel] [PATCH v5 18/22] instrument: Add event 'guest_mem_before_trans'

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 Makefile.target |1 +
 instrument/control.c|   15 +
 instrument/control.h|   36 +-
 instrument/control.inc.h|   16 +++---
 instrument/events.h |   21 +
 instrument/events.inc.h |   20 
 instrument/load.c   |1 +
 instrument/qemu-instr/control.h |   16 ++
 instrument/qemu-instr/types.h   |   64 +++
 stubs/instrument.c  |4 ++
 tcg/tcg-op.c|5 +++
 trace/control.h |   23 ++
 trace/mem.h |   23 --
 13 files changed, 214 insertions(+), 31 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index 7f42c45db8..6997b921c9 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -196,6 +196,7 @@ $(QEMU_PROG_BUILD): config-devices.mak
 COMMON_LDADDS = ../libqemuutil.a ../libqemustub.a
 
 # build either PROG or PROGW
+$(QEMU_PROG_BUILD): CFLAGS += -DQEMU_TARGET_BUILD=1
 $(QEMU_PROG_BUILD): $(all-obj-y) $(COMMON_LDADDS)
$(call LINK, $(filter-out %.mak, $^))
 ifdef CONFIG_DARWIN
diff --git a/instrument/control.c b/instrument/control.c
index 401189db2e..0424dd57ab 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -17,7 +17,7 @@
 #include "qom/cpu.h"
 
 
-__thread InstrState instr_cur_state;
+__thread InstrInfo instr_cur_info;
 
 
 unsigned int instr_cpus_count;
@@ -142,3 +142,16 @@ SYM_PUBLIC void qi_event_set_guest_cpu_reset(void 
(*fn)(QICPU vcpu))
 ERROR_IF(!instr_get_state(), "called outside instrumentation");
 instr_set_event(guest_cpu_reset, fn);
 }
+
+
+void (*instr_event__guest_mem_before_trans)(
+QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info);
+
+SYM_PUBLIC void qi_event_set_guest_mem_before_trans(
+void (*fn)(QICPU vcpu_trans, QITCGv_cpu vcpu_exec,
+   QITCGv vaddr, QIMemInfo info))
+{
+ERROR_IF(!instr_get_state(), "called outside instrumentation");
+ERROR_IF(!tcg_enabled(), "called without TCG");
+instr_set_event(guest_mem_before_trans, fn);
+}
diff --git a/instrument/control.h b/instrument/control.h
index 03e87b2b8f..3e44702f75 100644
--- a/instrument/control.h
+++ b/instrument/control.h
@@ -86,12 +86,21 @@ typedef enum {
 INSTR_STATE_ENABLE,
 } InstrState;
 
+#define INSTR_MAX_TCG_REGS 16
+
+typedef struct InstrInfo {
+InstrState state;
+unsigned int max;
+void *tcg_regs[INSTR_MAX_TCG_REGS];
+} InstrInfo;
+
 /**
  * instr_set_state:
  *
- * Set the instrumentation state of the current host thread.
+ * Set the instrumentation state of the current host thread, and return its
+ * #InstrInfo.
  */
-static inline void instr_set_state(InstrState state);
+static inline InstrInfo *instr_set_state(InstrState state);
 
 /**
  * instr_get_state:
@@ -100,6 +109,29 @@ static inline void instr_set_state(InstrState state);
  */
 static inline InstrState instr_get_state(void);
 
+/**
+ * instr_tcg_to_qitcg:
+ * @info: Pointer to #InstrInfo.
+ * @num: Number of TCG register used by instrumentation.
+ * @arg: TCG register.
+ *
+ * Get a suitable QITCGv* from a TCGv* value.
+ */
+#define instr_tcg_to_qitcg(info, num, arg) \
+({\
+info->tcg_regs[num] = arg;\
+(void *)num;  \
+})
+
+/**
+ * instr_tcg_count:
+ * @info: Pointer to #InstrInfo.
+ * @count: Number of TCG registers used by instrumentation.
+ *
+ * Set the number of TCG registers used by instrumentation.
+ */
+static inline void instr_tcg_count(InstrInfo *info, unsigned int count);
+
 
 #include "instrument/control.inc.h"
 
diff --git a/instrument/control.inc.h b/instrument/control.inc.h
index 6d65b23ead..3eba9b7c85 100644
--- a/instrument/control.inc.h
+++ b/instrument/control.inc.h
@@ -46,14 +46,22 @@ static inline CPUState *instr_cpu_from_qicpu(QICPU vcpu)
 }
 
 
-extern __thread InstrState instr_cur_state;
+extern __thread InstrInfo instr_cur_info;
 
-static inline void instr_set_state(InstrState state)
+static inline InstrInfo *instr_set_state(InstrState state)
 {
-atomic_store_release(&instr_cur_state, state);
+InstrInfo *info = &instr_cur_info;
+atomic_store_release(&info->state, state);
+return info;
 }
 
 static inline InstrState instr_get_state(void)
 {
-return atomic_load_acquire(&instr_cur_state);
+return atomic_load_acquire(&instr_cur_info.state);
+}
+
+
+static inline void instr_tcg_count(InstrInfo *info, unsigned int count)
+{
+info->max = count;
 }
diff --git a/instrument/events.h b/instrument/events.h
index 4a0560490a..1cc4dbb052 100644
--- a/instrument/events.h
+++ b/instrument/events.h
@@ -12,6 +12,8 @@
 
 #include "instrument/qemu-instr/control.h"
 #include "instrument/qemu-instr/types.h"
+#include "trace/control.h"
+
 
 /**
  * instr_get_event:
@@ -30,6 +32,20 @@
 atomic_store_release(&instr_event__ ## name, fn)
 
 
+/*
+ 

[Qemu-devel] [PATCH v5 19/22] instrument: Add event 'guest_mem_before_exec'

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 include/exec/cpu_ldst_template.h  |4 +++
 include/exec/cpu_ldst_useronly_template.h |4 +++
 include/exec/helper-gen.h |1 +
 include/exec/helper-proto.h   |1 +
 include/exec/helper-tcg.h |1 +
 instrument/control.c  |   37 +
 instrument/control.h  |   15 
 instrument/events.h   |5 
 instrument/events.inc.h   |   18 +-
 instrument/helpers.h  |2 ++
 instrument/load.c |1 +
 instrument/qemu-instr/control.h   |   21 
 stubs/instrument.c|   19 ++-
 13 files changed, 127 insertions(+), 2 deletions(-)
 create mode 100644 instrument/helpers.h

diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
index debbabcfb2..8018e8b16a 100644
--- a/include/exec/cpu_ldst_template.h
+++ b/include/exec/cpu_ldst_template.h
@@ -28,6 +28,7 @@
 #include "trace-root.h"
 #endif
 
+#include "instrument/events.h"
 #include "trace/mem.h"
 
 #if DATA_SIZE == 8
@@ -89,6 +90,7 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), 
_ra)(CPUArchState *env,
 
 #if !defined(SOFTMMU_CODE_ACCESS)
 TraceMemInfo meminfo = trace_mem_build_info(SHIFT, false, MO_TE, false);
+instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
 trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 
@@ -126,6 +128,7 @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), 
_ra)(CPUArchState *env,
 
 #if !defined(SOFTMMU_CODE_ACCESS)
 TraceMemInfo meminfo = trace_mem_build_info(SHIFT, true, MO_TE, false);
+instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
 trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 
@@ -167,6 +170,7 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), 
_ra)(CPUArchState *env,
 
 #if !defined(SOFTMMU_CODE_ACCESS)
 TraceMemInfo meminfo = trace_mem_build_info(SHIFT, false, MO_TE, true);
+instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
 trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 
diff --git a/include/exec/cpu_ldst_useronly_template.h 
b/include/exec/cpu_ldst_useronly_template.h
index b0b3fc1b8d..c36c50ae41 100644
--- a/include/exec/cpu_ldst_useronly_template.h
+++ b/include/exec/cpu_ldst_useronly_template.h
@@ -27,6 +27,7 @@
 #include "trace-root.h"
 #endif
 
+#include "instrument/events.h"
 #include "trace/mem.h"
 
 #if DATA_SIZE == 8
@@ -62,6 +63,7 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, 
target_ulong ptr)
 {
 #if !defined(CODE_ACCESS)
 TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, false, MO_TE, 
false);
+instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
 trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 return glue(glue(ld, USUFFIX), _p)(g2h(ptr));
@@ -81,6 +83,7 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, 
target_ulong ptr)
 {
 #if !defined(CODE_ACCESS)
 TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, true, MO_TE, false);
+instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
 trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 return glue(glue(lds, SUFFIX), _p)(g2h(ptr));
@@ -102,6 +105,7 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, 
target_ulong ptr,
 {
 #if !defined(CODE_ACCESS)
 TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, false, MO_TE, true);
+instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
 trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 glue(glue(st, SUFFIX), _p)(g2h(ptr), v);
diff --git a/include/exec/helper-gen.h b/include/exec/helper-gen.h
index 8239ffc77c..f351c3d050 100644
--- a/include/exec/helper-gen.h
+++ b/include/exec/helper-gen.h
@@ -57,6 +57,7 @@ static inline void glue(gen_helper_, 
name)(dh_retvar_decl(ret)  \
 }
 
 #include "helper.h"
+#include "instrument/helpers.h"
 #include "trace/generated-helpers.h"
 #include "trace/generated-helpers-wrappers.h"
 #include "tcg-runtime.h"
diff --git a/include/exec/helper-proto.h b/include/exec/helper-proto.h
index 954bef85ce..8fdd02c132 100644
--- a/include/exec/helper-proto.h
+++ b/include/exec/helper-proto.h
@@ -27,6 +27,7 @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), 
dh_ctype(t3), \
 dh_ctype(t4), dh_ctype(t5));
 
 #include "helper.h"
+#include "instrument/helpers.h"
 #include "trace/generated-helpers.h"
 #include "tcg-runtime.h"
 
diff --git a/include/exec/helper-tcg.h b/include/exec/helper-tcg.h
index b0c5bafa99..255e73c3e6 100644
--- a/include/exec/helper-tcg.h
+++ b/include/exec/helper-tcg.h
@@ -40,6 +40,7 @@
 | dh_sizemask(t5, 5) },
 
 #include "helper.h"
+#include "instrument/helpers.h"
 #include "trace/gen

[Qemu-devel] [PATCH v5 20/22] instrument: Add event 'guest_user_syscall'

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 bsd-user/syscall.c  |6 ++
 instrument/control.c|   18 ++
 instrument/events.h |7 +++
 instrument/events.inc.h |   16 
 instrument/load.c   |1 +
 instrument/qemu-instr/control.h |   15 +++
 linux-user/syscall.c|2 ++
 stubs/instrument.c  |3 +++
 8 files changed, 68 insertions(+)

diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index 3230f722f3..0d92eaf8c4 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -324,6 +324,8 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 #ifdef DEBUG
 gemu_log("freebsd syscall %d\n", num);
 #endif
+instr_guest_user_syscall(cpu, num,
+ arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
 trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 
arg7, arg8);
 if(do_strace)
 print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
@@ -423,6 +425,8 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long 
arg1,
 #ifdef DEBUG
 gemu_log("netbsd syscall %d\n", num);
 #endif
+instr_guest_user_syscall(cpu, num,
+ arg1, arg2, arg3, arg4, arg5, arg6, 0, 0);
 trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0, 
0);
 if(do_strace)
 print_netbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
@@ -499,6 +503,8 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 #ifdef DEBUG
 gemu_log("openbsd syscall %d\n", num);
 #endif
+instr_guest_user_syscall(cpu, num,
+ arg1, arg2, arg3, arg4, arg5, arg6, 0, 0);
 trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0, 
0);
 if(do_strace)
 print_openbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
diff --git a/instrument/control.c b/instrument/control.c
index 4181e030f6..b3ef03798e 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -192,3 +192,21 @@ SYM_PUBLIC void qi_event_set_guest_mem_before_exec(
 ERROR_IF(!tcg_enabled(), "called without TCG");
 instr_set_event(guest_mem_before_exec, fn);
 }
+
+
+void (*instr_event__guest_user_syscall)(
+QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
+uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8);
+
+SYM_PUBLIC void qi_event_set_guest_user_syscall(
+void (*fn)(QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2,
+   uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6,
+   uint64_t arg7, uint64_t arg8))
+{
+ERROR_IF(!instr_get_state(), "called outside instrumentation");
+ERROR_IF(!tcg_enabled(), "called without TCG");
+#if !defined(CONFIG_USER_ONLY)
+ERROR_IF(true, "called in full-system mode");
+#endif
+instr_set_event(guest_user_syscall, fn);
+}
diff --git a/instrument/events.h b/instrument/events.h
index 6507b26867..8c944e1f91 100644
--- a/instrument/events.h
+++ b/instrument/events.h
@@ -68,6 +68,13 @@ extern void (*instr_event__guest_mem_before_exec)(
 static inline void instr_guest_mem_before_exec(
 CPUState *vcpu, uint64_t vaddr, TraceMemInfo info);
 
+extern void (*instr_event__guest_user_syscall)(
+QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
+uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8);
+static inline void instr_guest_user_syscall(
+CPUState *vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
+uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8);
+
 
 #include "instrument/events.inc.h"
 
diff --git a/instrument/events.inc.h b/instrument/events.inc.h
index ebc8020715..e2f4315fb0 100644
--- a/instrument/events.inc.h
+++ b/instrument/events.inc.h
@@ -78,3 +78,19 @@ static inline void instr_guest_mem_before_exec(
 instr_set_state(INSTR_STATE_DISABLE);
 }
 }
+
+static inline void instr_guest_user_syscall(
+CPUState *vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
+uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8)
+{
+void (*cb)(QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2,
+   uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6,
+   uint64_t arg7, uint64_t arg8)
+= instr_get_event(guest_user_syscall);
+if (cb) {
+instr_set_state(INSTR_STATE_ENABLE);
+QICPU vcpu_ = instr_cpu_to_qicpu(vcpu);
+(*cb)(vcpu_, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+instr_set_state(INSTR_STATE_DISABLE);
+}
+}
diff --git a/instrument/load.c b/instrument/load.c
index f1d769b92d..a76f76e1d1 100644
--- a/instrument/load.c
+++ b/instrument/load.c
@@ -164,6 +164,7 @@ InstrUnloadError instr_unload(const char *id)
 instr_set_event(guest_cpu_reset, NULL);
 instr_set

[Qemu-devel] [PATCH v2 0/2] spapr: fix migration with nested KVM PR

2017-09-12 Thread Greg Kurz
A guest running with KVM PR ends up irresponsive after migration most of the
time. This happens because the HPT allocated by QEMU is likely to have a
different address on the destination than it had on the source, but we push
the source address to KVM.

This v2 is a total rewrite.

Cheers,

--
Greg

---

Greg Kurz (2):
  spapr: introduce common helper to write HPT address to KVM PR
  spapr: preserve SDR1 during migration


 hw/ppc/spapr.c  |   61 +++
 hw/ppc/spapr_cpu_core.c |   15 
 hw/ppc/spapr_hcall.c|   16 +---
 include/hw/ppc/spapr.h  |1 +
 target/ppc/cpu.h|5 
 target/ppc/machine.c|   18 ++
 6 files changed, 81 insertions(+), 35 deletions(-)




[Qemu-devel] [PATCH v2 1/2] spapr: introduce common helper to write HPT address to KVM PR

2017-09-12 Thread Greg Kurz
When running with KVM PR, if a new HPT is allocated we need to inform
KVM about the HPT address and size. This is currently done with a hack
which is open-coded in several places.

This patch consolidate the code in a dedicated helper that records
the HPT address and size in the sPAPR context, and then does the
magic for KVM PR.

Note that ppc_spapr_reset() now resets all devices and CPUs before
allocating the HPT. This allows to drop the hack from spapr_cpu_reset().

Signed-off-by: Greg Kurz 
---
 hw/ppc/spapr.c  |   31 ++-
 hw/ppc/spapr_cpu_core.c |   15 ---
 hw/ppc/spapr_hcall.c|   16 +---
 include/hw/ppc/spapr.h  |1 +
 4 files changed, 28 insertions(+), 35 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f680f28a15ea..97f8afdbd7fe 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1309,6 +1309,25 @@ void spapr_free_hpt(sPAPRMachineState *spapr)
 close_htab_fd(spapr);
 }
 
+void spapr_install_hpt(sPAPRMachineState *spapr, void *htab, uint32_t shift)
+{
+assert(htab);
+
+spapr->htab = htab;
+spapr->htab_shift = shift;
+
+/*
+ * This is a hack for the benefit of KVM PR - it abuses the SDR1
+ * slot in kvm_sregs to communicate the userspace address of the
+ * HPT
+ */
+if (kvm_enabled()) {
+target_ulong sdr1 = (target_ulong)(uintptr_t)spapr->htab
+| (spapr->htab_shift - 18);
+kvmppc_update_sdr1(sdr1);
+}
+}
+
 void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
   Error **errp)
 {
@@ -1339,16 +1358,17 @@ void spapr_reallocate_hpt(sPAPRMachineState *spapr, int 
shift,
 /* kernel-side HPT not needed, allocate in userspace instead */
 size_t size = 1ULL << shift;
 int i;
+void *htab;
 
-spapr->htab = qemu_memalign(size, size);
-if (!spapr->htab) {
+htab = qemu_memalign(size, size);
+if (!htab) {
 error_setg_errno(errp, errno,
  "Could not allocate HPT of order %d", shift);
 return;
 }
 
-memset(spapr->htab, 0, size);
-spapr->htab_shift = shift;
+memset(htab, 0, size);
+spapr_install_hpt(spapr, htab, shift);
 
 for (i = 0; i < size / HASH_PTE_SIZE_64; i++) {
 DIRTY_HPTE(HPTE(spapr->htab, i));
@@ -1405,6 +1425,8 @@ static void ppc_spapr_reset(void)
 /* Check for unknown sysbus devices */
 foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
 
+qemu_devices_reset();
+
 if (kvm_enabled() && kvmppc_has_cap_mmu_radix()) {
 /* If using KVM with radix mode available, VCPUs can be started
  * without a HPT because KVM will start them in radix mode.
@@ -1414,7 +1436,6 @@ static void ppc_spapr_reset(void)
 spapr_setup_hpt_and_vrma(spapr);
 }
 
-qemu_devices_reset();
 spapr_clear_pending_events(spapr);
 
 /*
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index c08ee7571a50..c20b5c64b045 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -73,7 +73,6 @@ void spapr_cpu_parse_features(sPAPRMachineState *spapr)
 
 static void spapr_cpu_reset(void *opaque)
 {
-sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
 PowerPCCPU *cpu = opaque;
 CPUState *cs = CPU(cpu);
 CPUPPCState *env = &cpu->env;
@@ -86,20 +85,6 @@ static void spapr_cpu_reset(void *opaque)
 cs->halted = 1;
 
 env->spr[SPR_HIOR] = 0;
-
-/*
- * This is a hack for the benefit of KVM PR - it abuses the SDR1
- * slot in kvm_sregs to communicate the userspace address of the
- * HPT
- */
-if (kvm_enabled()) {
-env->spr[SPR_SDR1] = (target_ulong)(uintptr_t)spapr->htab
-| (spapr->htab_shift - 18);
-if (kvmppc_put_books_sregs(cpu) < 0) {
-error_report("Unable to update SDR1 in KVM");
-exit(1);
-}
-}
 }
 
 static void spapr_cpu_destroy(PowerPCCPU *cpu)
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 57bb411394ed..7892cd3e7ffa 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -730,15 +730,7 @@ static target_ulong h_resize_hpt_commit(PowerPCCPU *cpu,
 pending->hpt, newsize);
 if (rc == H_SUCCESS) {
 qemu_vfree(spapr->htab);
-spapr->htab = pending->hpt;
-spapr->htab_shift = pending->shift;
-
-if (kvm_enabled()) {
-/* For KVM PR, update the HPT pointer */
-target_ulong sdr1 = (target_ulong)(uintptr_t)spapr->htab
-| (spapr->htab_shift - 18);
-kvmppc_update_sdr1(sdr1);
-}
+spapr_install_hpt(spapr, pending->hpt, pending->shift);
 
 pending->hpt = NULL; /* so it's not free()d */
 }
@@ -1564,12 +1556,6 @@ static target_ulong 
h_client_architecture_support(PowerPCCPU *cpu,
  * the point this is called, nothing should have been

[Qemu-devel] [PATCH v2 2/2] spapr: preserve SDR1 during migration

2017-09-12 Thread Greg Kurz
When running with KVM PR, a pseries machine needs to allocate an HPT
in userspace and pass its address and size too KVM. This is done at
machine reset time by hijacking SDR1.

It is very likely that the destination QEMU will allocate the HPT at
a different address, ie, the SDR1 value we get from the migration
stream is wrong and the guest ends up badly broken.

Let's fix this by preserving the pre-load value of SDR1. Since this is
a spapr specific hack, this is achieved by extending the PPC virtual
hypervisor interface.

Signed-off-by: Greg Kurz 
---
 hw/ppc/spapr.c   |   30 ++
 target/ppc/cpu.h |5 +
 target/ppc/machine.c |   18 ++
 3 files changed, 53 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 97f8afdbd7fe..aa280c9d767f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1200,6 +1200,34 @@ static uint64_t spapr_get_patbe(PPCVirtualHypervisor 
*vhyp)
 return spapr->patb_entry;
 }
 
+static void spapr_cpu_pre_load(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
+{
+sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+
+/* This is a hack for KVM PR: SDR1 contains the address and size of the HPT
+ * allocated by QEMU. We must preserve it.
+ */
+if (kvm_enabled() && spapr->htab) {
+CPUPPCState *env = &cpu->env;
+
+cpu->sdr1_kvm_pr = env->spr[SPR_SDR1];
+}
+}
+
+static void spapr_cpu_post_load(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
+{
+sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+
+/* This is a hack for KVM PR: SDR1 contains the address and size of the HPT
+ * allocated by QEMU. We must preserve it.
+ */
+if (kvm_enabled() && spapr->htab) {
+CPUPPCState *env = &cpu->env;
+
+env->spr[SPR_SDR1] = cpu->sdr1_kvm_pr;
+}
+}
+
 #define HPTE(_table, _i)   (void *)(((uint64_t *)(_table)) + ((_i) * 2))
 #define HPTE_VALID(_hpte)  (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_VALID)
 #define HPTE_DIRTY(_hpte)  (tswap64(*((uint64_t *)(_hpte))) & 
HPTE64_V_HPTE_DIRTY)
@@ -3624,6 +3652,8 @@ static void spapr_machine_class_init(ObjectClass *oc, 
void *data)
 vhc->unmap_hptes = spapr_unmap_hptes;
 vhc->store_hpte = spapr_store_hpte;
 vhc->get_patbe = spapr_get_patbe;
+vhc->cpu_pre_load = spapr_cpu_pre_load;
+vhc->cpu_post_load = spapr_cpu_post_load;
 xic->ics_get = spapr_ics_get;
 xic->ics_resend = spapr_ics_resend;
 xic->icp_get = spapr_icp_get;
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index c9d3ffa89bcb..22ea2538d923 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1212,6 +1212,9 @@ struct PowerPCCPU {
 uint64_t mig_insns_flags2;
 uint32_t mig_nb_BATs;
 bool pre_2_10_migration;
+
+/* KVM PR hack to preserve SDR1 (HPT) */
+target_ulong sdr1_kvm_pr;
 };
 
 static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
@@ -1243,6 +1246,8 @@ struct PPCVirtualHypervisorClass {
 void (*store_hpte)(PPCVirtualHypervisor *vhyp, hwaddr ptex,
uint64_t pte0, uint64_t pte1);
 uint64_t (*get_patbe)(PPCVirtualHypervisor *vhyp);
+void (*cpu_pre_load)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu);
+void (*cpu_post_load)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu);
 };
 
 #define TYPE_PPC_VIRTUAL_HYPERVISOR "ppc-virtual-hypervisor"
diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index e36b7100cb66..c4d32c886367 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -218,6 +218,19 @@ static bool pvr_match(PowerPCCPU *cpu, uint32_t pvr)
 return pcc->pvr_match(pcc, pvr);
 }
 
+static int cpu_pre_load(void *opaque)
+{
+PowerPCCPU *cpu = opaque;
+
+if (cpu->vhyp) {
+PPCVirtualHypervisorClass *vhc =
+PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
+vhc->cpu_pre_load(cpu->vhyp, cpu);
+}
+
+return 0;
+}
+
 static int cpu_post_load(void *opaque, int version_id)
 {
 PowerPCCPU *cpu = opaque;
@@ -294,6 +307,10 @@ static int cpu_post_load(void *opaque, int version_id)
 
 if (!cpu->vhyp) {
 ppc_store_sdr1(env, env->spr[SPR_SDR1]);
+} else {
+PPCVirtualHypervisorClass *vhc =
+PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
+vhc->cpu_post_load(cpu->vhyp, cpu);
 }
 
 /* Invalidate all msr bits except MSR_TGPR/MSR_HVB before restoring */
@@ -650,6 +667,7 @@ const VMStateDescription vmstate_ppc_cpu = {
 .minimum_version_id_old = 4,
 .load_state_old = cpu_load_old,
 .pre_save = cpu_pre_save,
+.pre_load = cpu_pre_load,
 .post_load = cpu_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.spr[SPR_PVR]) 
*/




[Qemu-devel] [PATCH v5 21/22] instrument: Add event 'guest_user_syscall_ret'

2017-09-12 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 bsd-user/syscall.c  |3 +++
 instrument/control.c|   15 +++
 instrument/events.h |5 +
 instrument/events.inc.h |   13 +
 instrument/load.c   |1 +
 instrument/qemu-instr/control.h |   13 +
 linux-user/syscall.c|1 +
 stubs/instrument.c  |2 ++
 8 files changed, 53 insertions(+)

diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index 0d92eaf8c4..fb468c0574 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -407,6 +407,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 #endif
 if (do_strace)
 print_freebsd_syscall_ret(num, ret);
+instr_guest_user_syscall_ret(cpu, num, ret);
 trace_guest_user_syscall_ret(cpu, num, ret);
 return ret;
  efault:
@@ -485,6 +486,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long 
arg1,
 #endif
 if (do_strace)
 print_netbsd_syscall_ret(num, ret);
+instr_guest_user_syscall_ret(cpu, num, ret);
 trace_guest_user_syscall_ret(cpu, num, ret);
 return ret;
  efault:
@@ -563,6 +565,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 #endif
 if (do_strace)
 print_openbsd_syscall_ret(num, ret);
+instr_guest_user_syscall_ret(cpu, num, ret);
 trace_guest_user_syscall_ret(cpu, num, ret);
 return ret;
  efault:
diff --git a/instrument/control.c b/instrument/control.c
index b3ef03798e..b5b1e0503d 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -210,3 +210,18 @@ SYM_PUBLIC void qi_event_set_guest_user_syscall(
 #endif
 instr_set_event(guest_user_syscall, fn);
 }
+
+
+void (*instr_event__guest_user_syscall_ret)(
+QICPU vcpu, uint64_t num, uint64_t ret);
+
+SYM_PUBLIC void qi_event_set_guest_user_syscall_ret(
+void (*fn)(QICPU vcpu, uint64_t num, uint64_t ret))
+{
+ERROR_IF(!instr_get_state(), "called outside instrumentation");
+ERROR_IF(!tcg_enabled(), "called without TCG");
+#if !defined(CONFIG_USER_ONLY)
+ERROR_IF(true, "called in full-system mode");
+#endif
+instr_set_event(guest_user_syscall_ret, fn);
+}
diff --git a/instrument/events.h b/instrument/events.h
index 8c944e1f91..6197ece466 100644
--- a/instrument/events.h
+++ b/instrument/events.h
@@ -75,6 +75,11 @@ static inline void instr_guest_user_syscall(
 CPUState *vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
 uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8);
 
+extern void (*instr_event__guest_user_syscall_ret)(
+QICPU vcpu, uint64_t num, uint64_t ret);
+static inline void instr_guest_user_syscall_ret(
+CPUState *vcpu, uint64_t num, uint64_t ret);
+
 
 #include "instrument/events.inc.h"
 
diff --git a/instrument/events.inc.h b/instrument/events.inc.h
index e2f4315fb0..d31dec54b8 100644
--- a/instrument/events.inc.h
+++ b/instrument/events.inc.h
@@ -94,3 +94,16 @@ static inline void instr_guest_user_syscall(
 instr_set_state(INSTR_STATE_DISABLE);
 }
 }
+
+static inline void instr_guest_user_syscall_ret(
+CPUState *vcpu, uint64_t num, uint64_t ret)
+{
+void (*cb)(QICPU vcpu, uint64_t num, uint64_t ret)
+= instr_get_event(guest_user_syscall_ret);
+if (cb) {
+instr_set_state(INSTR_STATE_ENABLE);
+QICPU vcpu_ = instr_cpu_to_qicpu(vcpu);
+(*cb)(vcpu_, num, ret);
+instr_set_state(INSTR_STATE_DISABLE);
+}
+}
diff --git a/instrument/load.c b/instrument/load.c
index a76f76e1d1..be13a90286 100644
--- a/instrument/load.c
+++ b/instrument/load.c
@@ -165,6 +165,7 @@ InstrUnloadError instr_unload(const char *id)
 instr_set_event(guest_mem_before_trans, NULL);
 instr_set_event(guest_mem_before_exec, NULL);
 instr_set_event(guest_user_syscall, NULL);
+instr_set_event(guest_user_syscall_ret, NULL);
 
 instr_cpu_stop_all_end(&info);
 cpu_list_unlock();
diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/control.h
index 136058af4f..bc4e49bef1 100644
--- a/instrument/qemu-instr/control.h
+++ b/instrument/qemu-instr/control.h
@@ -157,6 +157,19 @@ void qi_event_set_guest_user_syscall(
uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6,
uint64_t arg7, uint64_t arg8));
 
+/*
+ * Finish executing a guest system call in syscall emulation mode.
+ *
+ * @num: System call number.
+ * @ret: System call result value.
+ *
+ * Mode: user
+ * Targets: TCG(all)
+ * Time: exec
+ */
+void qi_event_set_guest_user_syscall_ret(
+void (*fn)(QICPU vcpu, uint64_t num, uint64_t ret));
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index c9f0b9fa56..44b91e3c52 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -12398,6 +12398,7 @@ fail:
 #endif
 if(do_strace)
 print_syscall_ret(num, ret);
+instr_guest_user_syscall_ret(cpu, num, ret);
 trace_guest_

[Qemu-devel] [PATCH v5 22/22] instrument: Add API to manipulate guest memory

2017-09-12 Thread Lluís Vilanova
It includes access to the guest's memory and vCPU registers.

Signed-off-by: Lluís Vilanova 
---
 instrument/Makefile.objs  |1 
 instrument/qemu-instr/state.h |  104 +
 instrument/state.c|   73 +
 3 files changed, 178 insertions(+)
 create mode 100644 instrument/qemu-instr/state.h
 create mode 100644 instrument/state.c

diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index d7e6c760c3..ee482bdb45 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -5,3 +5,4 @@ target-obj-$(CONFIG_INSTRUMENT) += load.o
 target-obj-$(CONFIG_INSTRUMENT) += qmp.o
 target-obj-$(CONFIG_INSTRUMENT) += control.o
 target-obj-$(CONFIG_INSTRUMENT) += trace.o
+target-obj-$(CONFIG_INSTRUMENT) += state.o
diff --git a/instrument/qemu-instr/state.h b/instrument/qemu-instr/state.h
new file mode 100644
index 00..0ae6255fe5
--- /dev/null
+++ b/instrument/qemu-instr/state.h
@@ -0,0 +1,104 @@
+/*
+ * Interface for accessing guest state.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QI__STATE_H
+#define QI__STATE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include 
+
+
+/**
+ * qi_mem_read_virt:
+ * @vcpu: CPU to use for address translation.
+ * @vaddr: Starting virtual address to read from.
+ * @size: Number of bytes to read.
+ * @buf: Buffer to write into.
+ *
+ * Read contents from virtual memory.
+ *
+ * Returns: Whether the range of virtual addresses to read could be translated.
+ *
+ * Warning: Even on error, some of the destination buffer might have been
+ *  modified.
+ *
+ * Precondition: The output buffer has at least "size" bytes.
+ */
+bool qi_mem_read_virt(QICPU vcpu, uint64_t vaddr, size_t size, void *buf);
+
+/**
+ * qi_mem_write_virt:
+ * @vcpu: CPU to use for address translation.
+ * @vaddr: Starting virtual address to write into.
+ * @size: Number of bytes to write.
+ * @buf: Buffer with the contents to write from.
+ *
+ * Write contents into virtual memory.
+ *
+ * Returns: Whether the range of virtual addresses to write could be 
translated.
+ *
+ * Warning: Even on error, some of the destination memory might have been
+ *  modified.
+ * Precondition: The input buffer has at least "size" bytes.
+ */
+bool qi_mem_write_virt(QICPU vcpu, uint64_t vaddr, size_t size, void *buf);
+
+/**
+ * qi_mem_virt_to_phys:
+ * @vcpu: CPU to use for address translation.
+ * @vaddr: Virtual address to translate.
+ * @paddr: Pointer to output physical address.
+ *
+ * Translate a virtual address into a physical address.
+ *
+ * Returns: Whether the address could be translated.
+ */
+bool qi_mem_virt_to_phys(QICPU vcpu, uint64_t vaddr, uint64_t *paddr);
+
+/**
+ * qi_mem_read_phys:
+ * @paddr: Starting physical address to read from.
+ * @size: Number of bytes to read.
+ * @buf: Buffer to write into.
+ *
+ * Read contents from physical memory.
+ *
+ * Returns: Whether the range of physical addresses is valid.
+ *
+ * Warning: Even on error, some of the destination buffer might have been
+ *  modified.
+ * Precondition: The output buffer has at least "size" bytes.
+ */
+bool qi_mem_read_phys(uint64_t paddr, size_t size, void *buf);
+
+/**
+ * qi_mem_write_phys:
+ * @paddr: Starting physical address to write into.
+ * @size: Number of bytes to write.
+ * @buf: Buffer with the contents to write from.
+ *
+ * Write contents into virtual memory.
+ *
+ * Returns: Whether the range of physical addresses is valid.
+ *
+ * Warning: Even on error, some of the destination memory might have been
+ *  modified.
+ *
+ * Precondition: The input buffer has at least "size" bytes.
+ */
+bool qi_mem_write_phys(uint64_t paddr, size_t size, void *buf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* QI__STATE_H */
diff --git a/instrument/state.c b/instrument/state.c
new file mode 100644
index 00..e76fd5fbcd
--- /dev/null
+++ b/instrument/state.c
@@ -0,0 +1,73 @@
+/*
+ * Interface for accessing guest state.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "qemu/compiler.h"
+#include "cpu.h"
+#include "exec/cpu-all.h"
+#include "instrument/control.h"
+#include "instrument/error.h"
+#include "instrument/qemu-instr/state.h"
+
+
+SYM_PUBLIC bool qi_mem_read_virt(QICPU vcpu, uint64_t vaddr,
+ size_t size, void *buf)
+{
+CPUState *vcpu_ = instr_cpu_from_qicpu(vcpu);
+ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentation");
+ERROR_IF_RET(!vcpu_, false, "invalid QICPU");
+return cpu_memory_rw_debug(vcpu_, vaddr, buf, size, 0) == 0;
+}
+
+SYM_PUBLIC bool qi_mem_write_virt(QICPU vcpu, uint64_t vaddr,
+ 

Re: [Qemu-devel] [PATCH v5 00/22] instrument: Add basic event instrumentation

2017-09-12 Thread no-reply
Hi,

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

Subject: [Qemu-devel] [PATCH v5 00/22] instrument: Add basic event 
instrumentation
Message-id: 150525010239.15988.8172586618197849619.st...@frigg.lan
Type: series

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

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

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
 * [new tag]   
patchew/150525010239.15988.8172586618197849619.st...@frigg.lan -> 
patchew/150525010239.15988.8172586618197849619.st...@frigg.lan
 t [tag update]patchew/20170912144459.11359-1-pbonz...@redhat.com 
-> patchew/20170912144459.11359-1-pbonz...@redhat.com
Switched to a new branch 'test'
1ab48ae9b7 instrument: Add API to manipulate guest memory
7e0bd2cad7 instrument: Add event 'guest_user_syscall_ret'
334caef899 instrument: Add event 'guest_user_syscall'
09a1773791 instrument: Add event 'guest_mem_before_exec'
2bd64563d3 instrument: Add event 'guest_mem_before_trans'
5b344ec1c3 trace: Introduce a proper structure to describe memory accesses
04e5b883b1 instrument: Add event 'guest_cpu_reset'
7971d0f2a4 instrument: Add event 'guest_cpu_exit'
53dbc9ad88 exec: Add function to synchronously flush TB on a stopped vCPU
d8b51515d2 instrument: Support synchronous modification of vCPU state
08d492e35f instrument: Add event 'guest_cpu_enter'
0be52b1bbd instrument: Track vCPUs
7ab01f20f5 instrument: Add support for tracing events
78676cff2d instrument: Add basic control interface
00172972ae instrument: [hmp] Add library loader
34ccf831e6 instrument: [qapi] Add library loader
d1ab648b00 instrument: [softmmu] Add command line library loader
150ad4a651 instrument: [bsd-user] Add command line library loader
a064b1621a instrument: [linux-user] Add command line library loader
aa78ee9f5a instrument: Add generic library loader
f10357e313 instrument: Add configure-time flag
4d324ad619 instrument: Add documentation

=== OUTPUT BEGIN ===
Checking PATCH 1/22: instrument: Add documentation...
Checking PATCH 2/22: instrument: Add configure-time flag...
Checking PATCH 3/22: instrument: Add generic library loader...
Checking PATCH 4/22: instrument: [linux-user] Add command line library loader...
Checking PATCH 5/22: instrument: [bsd-user] Add command line library loader...
Checking PATCH 6/22: instrument: [softmmu] Add command line library loader...
Checking PATCH 7/22: instrument: [qapi] Add library loader...
ERROR: externs should be avoided in .c files
#254: FILE: stubs/instrument.c:40:
+void qmp_instr_unload(const char *id, Error **errp);

total: 1 errors, 0 warnings, 204 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 8/22: instrument: [hmp] Add library loader...
Checking PATCH 9/22: instrument: Add basic control interface...
WARNING: architecture specific defines should be avoided
#52: FILE: include/qemu/compiler.h:119:
+#if defined _WIN32 || defined __CYGWIN__

WARNING: architecture specific defines should be avoided
#53: FILE: include/qemu/compiler.h:120:
+  #ifdef __GNUC__

WARNING: architecture specific defines should be avoided
#59: FILE: include/qemu/compiler.h:126:
+  #if __GNUC__ >= 4

WARNING: architecture specific defines should be avoided
#343: FILE: instrument/qemu-instr/control.h:13:
+#ifdef __cplusplus

WARNING: architecture specific defines should be avoided
#372: FILE: instrument/qemu-instr/control.h:42:
+#ifdef __cplusplus

total: 0 errors, 5 warnings, 309 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/22: instrument: Add support for tracing events...
WARNING: architecture specific defines should be avoided
#77: FILE: instrument/qemu-instr/types.h:13:
+#ifdef __cplusplus

WARNING: architecture specific defines should be avoided
#111: FILE: instrument/qemu-instr/types.h:47:
+#ifdef __cplusplus

total: 0 errors, 2 warnings, 225 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 11/22: instrument: Track vCPUs...
Checking PATCH 12/22: instrument: Add event 'guest_cpu_enter'...
Checking PATCH 13/22: instrument: Support synchronous modification of vCPU 
state...
WARNING: line over 80 characters
#73: FILE: instrument/control.c:85:
+asyn

Re: [Qemu-devel] [PATCH v5 00/22] instrument: Add basic event instrumentation

2017-09-12 Thread no-reply
Hi,

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

Subject: [Qemu-devel] [PATCH v5 00/22] instrument: Add basic event 
instrumentation
Message-id: 150525010239.15988.8172586618197849619.st...@frigg.lan
Type: series

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
1ab48ae9b7 instrument: Add API to manipulate guest memory
7e0bd2cad7 instrument: Add event 'guest_user_syscall_ret'
334caef899 instrument: Add event 'guest_user_syscall'
09a1773791 instrument: Add event 'guest_mem_before_exec'
2bd64563d3 instrument: Add event 'guest_mem_before_trans'
5b344ec1c3 trace: Introduce a proper structure to describe memory accesses
04e5b883b1 instrument: Add event 'guest_cpu_reset'
7971d0f2a4 instrument: Add event 'guest_cpu_exit'
53dbc9ad88 exec: Add function to synchronously flush TB on a stopped vCPU
d8b51515d2 instrument: Support synchronous modification of vCPU state
08d492e35f instrument: Add event 'guest_cpu_enter'
0be52b1bbd instrument: Track vCPUs
7ab01f20f5 instrument: Add support for tracing events
78676cff2d instrument: Add basic control interface
00172972ae instrument: [hmp] Add library loader
34ccf831e6 instrument: [qapi] Add library loader
d1ab648b00 instrument: [softmmu] Add command line library loader
150ad4a651 instrument: [bsd-user] Add command line library loader
a064b1621a instrument: [linux-user] Add command line library loader
aa78ee9f5a instrument: Add generic library loader
f10357e313 instrument: Add configure-time flag
4d324ad619 instrument: Add documentation

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into '/var/tmp/patchew-tester-tmp-lf5qg9x6/src/dtc'...
Submodule path 'dtc': checked out '558cd81bdd432769b59bff01240c44f82cfb1a9d'
  BUILD   centos6
make[1]: Entering directory '/var/tmp/patchew-tester-tmp-lf5qg9x6/src'
  ARCHIVE qemu.tgz
  ARCHIVE dtc.tgz
  COPYRUNNER
RUN test-quick in qemu:centos6 
Packages installed:
SDL-devel-1.2.14-7.el6_7.1.x86_64
bison-2.4.1-5.el6.x86_64
bzip2-devel-1.0.5-7.el6_0.x86_64
ccache-3.1.6-2.el6.x86_64
csnappy-devel-0-6.20150729gitd7bc683.el6.x86_64
flex-2.5.35-9.el6.x86_64
gcc-4.4.7-18.el6.x86_64
git-1.7.1-8.el6.x86_64
glib2-devel-2.28.8-9.el6.x86_64
libepoxy-devel-1.2-3.el6.x86_64
libfdt-devel-1.4.0-1.el6.x86_64
librdmacm-devel-1.0.21-0.el6.x86_64
lzo-devel-2.03-3.1.el6_5.1.x86_64
make-3.81-23.el6.x86_64
mesa-libEGL-devel-11.0.7-4.el6.x86_64
mesa-libgbm-devel-11.0.7-4.el6.x86_64
package g++ is not installed
pixman-devel-0.32.8-1.el6.x86_64
spice-glib-devel-0.26-8.el6.x86_64
spice-server-devel-0.12.4-16.el6.x86_64
tar-1.23-15.el6_8.x86_64
vte-devel-0.25.1-9.el6.x86_64
xen-devel-4.6.3-15.el6.x86_64
zlib-devel-1.2.3-29.el6.x86_64

Environment variables:
PACKAGES=bison bzip2-devel ccache csnappy-devel flex g++
 gcc git glib2-devel libepoxy-devel libfdt-devel 
librdmacm-devel lzo-devel make mesa-libEGL-devel 
mesa-libgbm-devel pixman-devel SDL-devel spice-glib-devel 
spice-server-devel tar vte-devel xen-devel zlib-devel
HOSTNAME=fd698ce7a83b
TERM=xterm
MAKEFLAGS= -j8
HISTSIZE=1000
J=8
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
CCACHE_DIR=/var/tmp/ccache
EXTRA_CONFIGURE_OPTS=
V=
SHOW_ENV=1
MAIL=/var/spool/mail/root
PATH=/usr/lib/ccache:/usr/lib64/ccache:/us

[Qemu-devel] [PATCH v2] trace: Immediately apply per-vCPU state changes if a vCPU is being created

2017-09-12 Thread Lluís Vilanova
Right now, function trace_event_set_vcpu_state_dynamic() asynchronously enables
events in the case a vCPU is executing TCG code. If the vCPU is being created
this makes some events like "guest_cpu_enter" to not be traced.

Signed-off-by: Lluís Vilanova 
Reviewed-by: Emilio G. Cota 
---

Changes in v2
=

* Use RUN_ON_CPU_NULL [Emilio G. Cota].
* Rebase on fcea73709b.
---
 trace/control-target.c |   18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/trace/control-target.c b/trace/control-target.c
index 4e36101997..706b2cee9d 100644
--- a/trace/control-target.c
+++ b/trace/control-target.c
@@ -88,13 +88,17 @@ void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
 clear_bit(vcpu_id, vcpu->trace_dstate_delayed);
 (*ev->dstate)--;
 }
-/*
- * Delay changes until next TB; we want all TBs to be built from a
- * single set of dstate values to ensure consistency of generated
- * tracing code.
- */
-async_run_on_cpu(vcpu, trace_event_synchronize_vcpu_state_dynamic,
- RUN_ON_CPU_NULL);
+if (vcpu->created) {
+/*
+ * Delay changes until next TB; we want all TBs to be built from a
+ * single set of dstate values to ensure consistency of generated
+ * tracing code.
+ */
+async_run_on_cpu(vcpu, trace_event_synchronize_vcpu_state_dynamic,
+ RUN_ON_CPU_NULL);
+} else {
+trace_event_synchronize_vcpu_state_dynamic(vcpu, RUN_ON_CPU_NULL);
+}
 }
 }
 




[Qemu-devel] [Bug 1716767] Re: file(1) fails with "Invalid argument" on qemu-sh4-user

2017-09-12 Thread James Clarke
Ok, I was wrong, there's a whole load of code being included inside the
function from a header. The issue seems to be the pread:

20771@1505254578.94:guest_user_syscall cpu=0x62850620 
num=0x00b4 arg1=0x0003 arg2=0xf6fe6798 
arg3=0x0020 arg4=0x arg5=0x0034 
arg6=0x arg7=0x arg8=0x
20771@1505254578.940005:guest_user_syscall_ret cpu=0x62850620 
num=0x00b4 ret=0x

0xb4 (180) is pread(64) on SH, which goes via a special wrapper[0] with
a dummy argument that gets stripped. This dummy argument ensures that
the 64-bit offset is aligned. However, linux-user doesn't know about
this, and so takes (arg4, arg5) as the 64-bit value, rather than (arg5,
arg6), leading to the host kernel trying to read 0x34
bytes (and rightly returning 0 for EOF).

[0]
https://github.com/torvalds/linux/blob/e0d072250a54669dce876d8ade70e417356aae74/arch/sh/kernel/sys_sh32.c#L38

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

Title:
  file(1) fails with "Invalid argument" on qemu-sh4-user

Status in QEMU:
  New

Bug description:
  We recently discovered that file(1) fails on qemu-sh4-user when
  running on an ELF file:

  (sid_sh4)root@vs94:/# file /bin/bash
  /bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) 
error reading (Invalid argument)
  (sid_sh4)root@vs94:/#

  Running with "-d" yields more output:

  (sid_sh4)root@vs94:/# file -d /bin/bash 2>&1 | tail
  322: >> 7 byte&,=97,"(ARM)"]
  0 == 97 = 0
  mget(type=1, flag=0, offset=7, o=0, nbytes=863324, il=0, nc=1)
  mget/96 @7: 
\000\000\000\000\000\000\000\000\000\002\000*\000\001\000\000\000\250\317A\0004\000\000\000L(\r\000\027\000\000\0004\000
 
\000\n\000(\000\032\000\031\000\006\000\000\0004\000\000\0004\000@\0004\000@\000@\001\000\000@\001\000\000\005\000\000\000\004\000\000\000\003\000\000\000t\001\000\000t\001@\000t\001@\000\023\000\000

  323: >> 7 byte&,=-1,"(embedded)"]
  0 == 18446744073709551615 = 0
  [try softmagic 1]
  [try elf -1]
  /bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) 
error reading (Invalid argument)
  (sid_sh4)root@vs94:/#

  It seems that the comparison above has a bogus (overflown?) value.

  On actual hardware, it works:

  root@tirpitz:~> file /bin/bash
  /bin/bash: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV), 
dynamically linked, interpreter /lib/ld-linux.so.2, 
BuildID[sha1]=4dd0e4281755827d8bb6686fd481f8c80ea73e9a, for GNU/Linux 3.2.0, 
stripped
  root@tirpitz:~>

  I have uploaded a chroot with Debian unstable which allows to
  reproduce the issue:

  > https://people.debian.org/~glaubitz/sid-sh4-sbuild.tar.gz

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



[Qemu-devel] [Bug 1716767] Re: file(1) fails with "Invalid argument" on qemu-sh4-user

2017-09-12 Thread James Clarke
(Currently regpairs_aligned gets checked, but this, rightly, returns
false for SH; alignment is not a requirement of the SH ABI, but
p{read,write}64 are an exception for it.)

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

Title:
  file(1) fails with "Invalid argument" on qemu-sh4-user

Status in QEMU:
  New

Bug description:
  We recently discovered that file(1) fails on qemu-sh4-user when
  running on an ELF file:

  (sid_sh4)root@vs94:/# file /bin/bash
  /bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) 
error reading (Invalid argument)
  (sid_sh4)root@vs94:/#

  Running with "-d" yields more output:

  (sid_sh4)root@vs94:/# file -d /bin/bash 2>&1 | tail
  322: >> 7 byte&,=97,"(ARM)"]
  0 == 97 = 0
  mget(type=1, flag=0, offset=7, o=0, nbytes=863324, il=0, nc=1)
  mget/96 @7: 
\000\000\000\000\000\000\000\000\000\002\000*\000\001\000\000\000\250\317A\0004\000\000\000L(\r\000\027\000\000\0004\000
 
\000\n\000(\000\032\000\031\000\006\000\000\0004\000\000\0004\000@\0004\000@\000@\001\000\000@\001\000\000\005\000\000\000\004\000\000\000\003\000\000\000t\001\000\000t\001@\000t\001@\000\023\000\000

  323: >> 7 byte&,=-1,"(embedded)"]
  0 == 18446744073709551615 = 0
  [try softmagic 1]
  [try elf -1]
  /bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) 
error reading (Invalid argument)
  (sid_sh4)root@vs94:/#

  It seems that the comparison above has a bogus (overflown?) value.

  On actual hardware, it works:

  root@tirpitz:~> file /bin/bash
  /bin/bash: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV), 
dynamically linked, interpreter /lib/ld-linux.so.2, 
BuildID[sha1]=4dd0e4281755827d8bb6686fd481f8c80ea73e9a, for GNU/Linux 3.2.0, 
stripped
  root@tirpitz:~>

  I have uploaded a chroot with Debian unstable which allows to
  reproduce the issue:

  > https://people.debian.org/~glaubitz/sid-sh4-sbuild.tar.gz

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



[Qemu-devel] [Bug 1716767] Re: file(1) fails with "Invalid argument" on qemu-sh4-user

2017-09-12 Thread James Clarke
Bah, and that's "read *from an offset of* 0x34 bytes"; I
got confused between count and pos midway through that paragraph.

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

Title:
  file(1) fails with "Invalid argument" on qemu-sh4-user

Status in QEMU:
  New

Bug description:
  We recently discovered that file(1) fails on qemu-sh4-user when
  running on an ELF file:

  (sid_sh4)root@vs94:/# file /bin/bash
  /bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) 
error reading (Invalid argument)
  (sid_sh4)root@vs94:/#

  Running with "-d" yields more output:

  (sid_sh4)root@vs94:/# file -d /bin/bash 2>&1 | tail
  322: >> 7 byte&,=97,"(ARM)"]
  0 == 97 = 0
  mget(type=1, flag=0, offset=7, o=0, nbytes=863324, il=0, nc=1)
  mget/96 @7: 
\000\000\000\000\000\000\000\000\000\002\000*\000\001\000\000\000\250\317A\0004\000\000\000L(\r\000\027\000\000\0004\000
 
\000\n\000(\000\032\000\031\000\006\000\000\0004\000\000\0004\000@\0004\000@\000@\001\000\000@\001\000\000\005\000\000\000\004\000\000\000\003\000\000\000t\001\000\000t\001@\000t\001@\000\023\000\000

  323: >> 7 byte&,=-1,"(embedded)"]
  0 == 18446744073709551615 = 0
  [try softmagic 1]
  [try elf -1]
  /bin/bash: ERROR: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV) 
error reading (Invalid argument)
  (sid_sh4)root@vs94:/#

  It seems that the comparison above has a bogus (overflown?) value.

  On actual hardware, it works:

  root@tirpitz:~> file /bin/bash
  /bin/bash: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV), 
dynamically linked, interpreter /lib/ld-linux.so.2, 
BuildID[sha1]=4dd0e4281755827d8bb6686fd481f8c80ea73e9a, for GNU/Linux 3.2.0, 
stripped
  root@tirpitz:~>

  I have uploaded a chroot with Debian unstable which allows to
  reproduce the issue:

  > https://people.debian.org/~glaubitz/sid-sh4-sbuild.tar.gz

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



Re: [Qemu-devel] [Qemu devel v8 PATCH 3/5] msf2: Add Smartfusion2 SPI controller

2017-09-12 Thread Alistair Francis
On Thu, Sep 7, 2017 at 12:24 PM, Subbaraya Sundeep
 wrote:
> Modelled Microsemi's Smartfusion2 SPI controller.
>
> Signed-off-by: Subbaraya Sundeep 

Reviewed-by: Alistair Francis 

Thanks,
Alistair

> ---
>  hw/ssi/Makefile.objs |   1 +
>  hw/ssi/mss-spi.c | 404 
> +++
>  include/hw/ssi/mss-spi.h |  58 +++
>  3 files changed, 463 insertions(+)
>  create mode 100644 hw/ssi/mss-spi.c
>  create mode 100644 include/hw/ssi/mss-spi.h
>
> diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
> index 487add2..f5bcc65 100644
> --- a/hw/ssi/Makefile.objs
> +++ b/hw/ssi/Makefile.objs
> @@ -4,6 +4,7 @@ common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
>  common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
>  common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
>  common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
> +common-obj-$(CONFIG_MSF2) += mss-spi.o
>
>  obj-$(CONFIG_OMAP) += omap_spi.o
>  obj-$(CONFIG_IMX) += imx_spi.o
> diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
> new file mode 100644
> index 000..5a8e308
> --- /dev/null
> +++ b/hw/ssi/mss-spi.c
> @@ -0,0 +1,404 @@
> +/*
> + * Block model of SPI controller present in
> + * Microsemi's SmartFusion2 and SmartFusion SoCs.
> + *
> + * Copyright (C) 2017 Subbaraya Sundeep 
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a 
> copy
> + * of this software and associated documentation files (the "Software"), to 
> deal
> + * in the Software without restriction, including without limitation the 
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/ssi/mss-spi.h"
> +#include "qemu/log.h"
> +
> +#ifndef MSS_SPI_ERR_DEBUG
> +#define MSS_SPI_ERR_DEBUG   0
> +#endif
> +
> +#define DB_PRINT_L(lvl, fmt, args...) do { \
> +if (MSS_SPI_ERR_DEBUG >= lvl) { \
> +qemu_log("%s: " fmt "\n", __func__, ## args); \
> +} \
> +} while (0);
> +
> +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
> +
> +#define FIFO_CAPACITY 32
> +
> +#define R_SPI_CONTROL 0
> +#define R_SPI_DFSIZE  1
> +#define R_SPI_STATUS  2
> +#define R_SPI_INTCLR  3
> +#define R_SPI_RX  4
> +#define R_SPI_TX  5
> +#define R_SPI_CLKGEN  6
> +#define R_SPI_SS  7
> +#define R_SPI_MIS 8
> +#define R_SPI_RIS 9
> +
> +#define S_TXDONE (1 << 0)
> +#define S_RXRDY  (1 << 1)
> +#define S_RXCHOVRF   (1 << 2)
> +#define S_RXFIFOFUL  (1 << 4)
> +#define S_RXFIFOFULNXT   (1 << 5)
> +#define S_RXFIFOEMP  (1 << 6)
> +#define S_RXFIFOEMPNXT   (1 << 7)
> +#define S_TXFIFOFUL  (1 << 8)
> +#define S_TXFIFOFULNXT   (1 << 9)
> +#define S_TXFIFOEMP  (1 << 10)
> +#define S_TXFIFOEMPNXT   (1 << 11)
> +#define S_FRAMESTART (1 << 12)
> +#define S_SSEL   (1 << 13)
> +#define S_ACTIVE (1 << 14)
> +
> +#define C_ENABLE (1 << 0)
> +#define C_MODE   (1 << 1)
> +#define C_INTRXDATA  (1 << 4)
> +#define C_INTTXDATA  (1 << 5)
> +#define C_INTRXOVRFLO(1 << 6)
> +#define C_SPS(1 << 26)
> +#define C_BIGFIFO(1 << 29)
> +#define C_RESET  (1 << 31)
> +
> +#define FRAMESZ_MASK 0x1F
> +#define FMCOUNT_MASK 0x0000
> +#define FMCOUNT_SHIFT8
> +
> +static void txfifo_reset(MSSSpiState *s)
> +{
> +fifo32_reset(&s->tx_fifo);
> +
> +s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL;
> +s->regs[R_SPI_STATUS] |= S_TXFIFOEMP;
> +}
> +
> +static void rxfifo_reset(MSSSpiState *s)
> +{
> +fifo32_reset(&s->rx_fifo);
> +
> +s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
> +s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
> +}
> +
> +static void set_fifodepth(MSSSpiState *s)
> +{
> +unsigned int size = s->regs[R_SPI_DFSIZE] & FRAMESZ_MASK;
> +
> +if (size <= 8) {
> +s->fifo_depth = 32;
> +} else if (size <= 16) {
> +s->fifo_depth = 16;
> +} else if (size <= 32) {
> +s->fifo_depth = 8;
> +} else {
> +s->fif

Re: [Qemu-devel] [PATCH] mps2-an511: Fix wiring of UART overflow interrupt lines

2017-09-12 Thread Alistair Francis
On Tue, Sep 12, 2017 at 9:13 AM, Peter Maydell  wrote:
> Fix an error that meant we were wiring every UART's overflow
> interrupts into the same inputs 0 and 1 of the OR gate,
> rather than giving each its own input.
>
> Cc: qemu-sta...@nongnu.org
> Signed-off-by: Peter Maydell 

Reviewed-by: Alistair Francis 

Thanks,
Alistair

> ---
>  hw/arm/mps2.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
> index abb0ab6..769cff8 100644
> --- a/hw/arm/mps2.c
> +++ b/hw/arm/mps2.c
> @@ -287,8 +287,8 @@ static void mps2_common_init(MachineState *machine)
>  cmsdk_apb_uart_create(uartbase[i],
>qdev_get_gpio_in(txrx_orgate_dev, 0),
>qdev_get_gpio_in(txrx_orgate_dev, 1),
> -  qdev_get_gpio_in(orgate_dev, 0),
> -  qdev_get_gpio_in(orgate_dev, 1),
> +  qdev_get_gpio_in(orgate_dev, i * 2),
> +  qdev_get_gpio_in(orgate_dev, i * 2 + 1),
>NULL,
>uartchr, SYSCLK_FRQ);
>  }
> --
> 2.7.4
>
>



Re: [Qemu-devel] [PATCH] spapr_events: use QTAILQ_FOREACH_SAFE() in spapr_clear_pending_events()

2017-09-12 Thread David Gibson
On Tue, Sep 12, 2017 at 08:48:05PM +0200, Greg Kurz wrote:
> QTAILQ_FOREACH_SAFE() must be used when removing the current element
> inside the loop block.
> 
> This fixes a user-after-free error introduced by commit 56258174238eb
> and reported by Coverity (CID 1381017).
> 
> Signed-off-by: Greg Kurz 

Applied to ppc-for-2.11.

> ---
>  hw/ppc/spapr_events.c |4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
> index 66b8164f30be..e377fc7ddea2 100644
> --- a/hw/ppc/spapr_events.c
> +++ b/hw/ppc/spapr_events.c
> @@ -702,9 +702,9 @@ static void event_scan(PowerPCCPU *cpu, sPAPRMachineState 
> *spapr,
>  
>  void spapr_clear_pending_events(sPAPRMachineState *spapr)
>  {
> -sPAPREventLogEntry *entry = NULL;
> +sPAPREventLogEntry *entry = NULL, *next_entry;
>  
> -QTAILQ_FOREACH(entry, &spapr->pending_events, next) {
> +QTAILQ_FOREACH_SAFE(entry, &spapr->pending_events, next, next_entry) {
>  QTAILQ_REMOVE(&spapr->pending_events, entry, next);
>  g_free(entry->extended_log);
>  g_free(entry);
> 

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [Qemu devel v8 PATCH 3/5] msf2: Add Smartfusion2 SPI controller

2017-09-12 Thread sundeep subbaraya
Hi Alistair,

On Wed, Sep 13, 2017 at 5:20 AM, Alistair Francis 
wrote:

> On Thu, Sep 7, 2017 at 12:24 PM, Subbaraya Sundeep
>  wrote:
> > Modelled Microsemi's Smartfusion2 SPI controller.
> >
> > Signed-off-by: Subbaraya Sundeep 
>
> Reviewed-by: Alistair Francis 
>
> Thank you,
Sundeep


> Thanks,
> Alistair
>
> > ---
> >  hw/ssi/Makefile.objs |   1 +
> >  hw/ssi/mss-spi.c | 404 ++
> +
> >  include/hw/ssi/mss-spi.h |  58 +++
> >  3 files changed, 463 insertions(+)
> >  create mode 100644 hw/ssi/mss-spi.c
> >  create mode 100644 include/hw/ssi/mss-spi.h
> >
> > diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
> > index 487add2..f5bcc65 100644
> > --- a/hw/ssi/Makefile.objs
> > +++ b/hw/ssi/Makefile.objs
> > @@ -4,6 +4,7 @@ common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
> >  common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
> >  common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
> >  common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
> > +common-obj-$(CONFIG_MSF2) += mss-spi.o
> >
> >  obj-$(CONFIG_OMAP) += omap_spi.o
> >  obj-$(CONFIG_IMX) += imx_spi.o
> > diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
> > new file mode 100644
> > index 000..5a8e308
> > --- /dev/null
> > +++ b/hw/ssi/mss-spi.c
> > @@ -0,0 +1,404 @@
> > +/*
> > + * Block model of SPI controller present in
> > + * Microsemi's SmartFusion2 and SmartFusion SoCs.
> > + *
> > + * Copyright (C) 2017 Subbaraya Sundeep 
> > + *
> > + * Permission is hereby granted, free of charge, to any person
> obtaining a copy
> > + * of this software and associated documentation files (the
> "Software"), to deal
> > + * in the Software without restriction, including without limitation
> the rights
> > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or
> sell
> > + * copies of the Software, and to permit persons to whom the Software is
> > + * furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice shall be
> included in
> > + * all copies or substantial portions of the Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
> SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
> OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> ARISING FROM,
> > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> DEALINGS IN
> > + * THE SOFTWARE.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "hw/ssi/mss-spi.h"
> > +#include "qemu/log.h"
> > +
> > +#ifndef MSS_SPI_ERR_DEBUG
> > +#define MSS_SPI_ERR_DEBUG   0
> > +#endif
> > +
> > +#define DB_PRINT_L(lvl, fmt, args...) do { \
> > +if (MSS_SPI_ERR_DEBUG >= lvl) { \
> > +qemu_log("%s: " fmt "\n", __func__, ## args); \
> > +} \
> > +} while (0);
> > +
> > +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
> > +
> > +#define FIFO_CAPACITY 32
> > +
> > +#define R_SPI_CONTROL 0
> > +#define R_SPI_DFSIZE  1
> > +#define R_SPI_STATUS  2
> > +#define R_SPI_INTCLR  3
> > +#define R_SPI_RX  4
> > +#define R_SPI_TX  5
> > +#define R_SPI_CLKGEN  6
> > +#define R_SPI_SS  7
> > +#define R_SPI_MIS 8
> > +#define R_SPI_RIS 9
> > +
> > +#define S_TXDONE (1 << 0)
> > +#define S_RXRDY  (1 << 1)
> > +#define S_RXCHOVRF   (1 << 2)
> > +#define S_RXFIFOFUL  (1 << 4)
> > +#define S_RXFIFOFULNXT   (1 << 5)
> > +#define S_RXFIFOEMP  (1 << 6)
> > +#define S_RXFIFOEMPNXT   (1 << 7)
> > +#define S_TXFIFOFUL  (1 << 8)
> > +#define S_TXFIFOFULNXT   (1 << 9)
> > +#define S_TXFIFOEMP  (1 << 10)
> > +#define S_TXFIFOEMPNXT   (1 << 11)
> > +#define S_FRAMESTART (1 << 12)
> > +#define S_SSEL   (1 << 13)
> > +#define S_ACTIVE (1 << 14)
> > +
> > +#define C_ENABLE (1 << 0)
> > +#define C_MODE   (1 << 1)
> > +#define C_INTRXDATA  (1 << 4)
> > +#define C_INTTXDATA  (1 << 5)
> > +#define C_INTRXOVRFLO(1 << 6)
> > +#define C_SPS(1 << 26)
> > +#define C_BIGFIFO(1 << 29)
> > +#define C_RESET  (1 << 31)
> > +
> > +#define FRAMESZ_MASK 0x1F
> > +#define FMCOUNT_MASK 0x0000
> > +#define FMCOUNT_SHIFT8
> > +
> > +static void txfifo_reset(MSSSpiState *s)
> > +{
> > +fifo32_reset(&s->tx_fifo);
> > +
> > +s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL;
> > +s->regs[R_SPI_STATUS] |= S_TXFIFOEMP;
> > +}
> > +
> > +static void rxfifo_reset(MSSSpiState *s)
> > +{
> > +fifo32_reset(&s->rx_fifo);
> > +
> > +s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
> > +s->regs[R_

Re: [Qemu-devel] [Qemu-ppc] [PATCH 2/4] ppc: add CPU IRQ state to PPC VMStateDescription

2017-09-12 Thread Alexey Kardashevskiy
On 13/09/17 02:46, Mark Cave-Ayland wrote:
> On 12/09/17 17:41, Mark Cave-Ayland wrote:
> 
>> The commit message mentions that prior to the conversion some CPU state
>> was missing but it doesn't mention anything about dropping existing
>> fields as part of the conversion process so I suspect that this was an
>> accidental side-effect.
> 
> Actually I've clicked send a little too early here since re-reading the
> last paragraph of a90db15 I can see the inference here: "Exactly what
> needs to be saved in what configurations has been more carefully
> examined, too".
> 
> Alexey - do you recall from your analysis why these fields were no
> longer deemed necessary, and how your TCG tests were configured?

I most certainly did not do analysis (my bad. sorry) - I took the patch
from David as he left the team, fixed to compile and pushed away. I am also
very suspicions we did not try migrating TCG or anything but pseries. My
guest that things did not break (if they did not which I am not sure about,
for the TCG case) because the interrupt controller (XICS) or the
pseries-guest took care of resending an interrupt which does not seem to be
the case for mac99.


-- 
Alexey



[Qemu-devel] [PATCH v7 00/13] tests: Add VM based build tests (for non-x86_64 and/or non-Linux)

2017-09-12 Thread Fam Zheng
v7: Add Alex's rev-by to patch 2.
GPLv2 => GPLv2+ for all new files. [Peter]
Add more description in file header to archive-source.sh for the intended
usage.  [Peter]
"output tarball" in usage. [Alex]
Add quotes to "$1". [Peter]
Put generated keys in separate files. [Alex]
Use os.devnull. [Alex]
More error info when launching QEMU fails. [Alex]

v6: Add license to new file. [Philippe]
Change tests/.gitignore. [Philippe]

v5: Generate source tar file with a script.
Fix tmpdir, use pwd.
Reduce default -j to half cores.

v4: Drop unused imports and parameters. [Cleber]
Use --exclude-vcs (still no --exclude-vcs-ignores because it's too new). 
[Philippe]
Use gtar if available. [Philippe, Kamil]
/dev/ld1a -> /dev/rld1a for netbsd. [Kamil]
Only use '-enable-kvm' if /dev/kvm is there. [Kamil]
Grammar fixes of README. [Stefan]
Rename image on the server to include version and arch. [Kamil]
Just ignore *.tmp. [Philippe]

v3: Drop RFC.
Add Stefan's and Kamil's reviewed-bys.
Use optparse. [Stefan]
Drop the VGA patch. [Paolo, Stefan]
Improve exit/exit code/doc. [Stefan]
Drop unused line from basevm.py. [Stefan]
Drop "--target-list" form Makefile.
More intelligent '-j'.
Add README. [Stefan]

v2: - Add docstring. [Stefan]
- Call self._load_io_lod. [Stefan]
- Use "info usernet" and dynamic ssh_port forwarding. [Stefan]
- Add image checksum.
- Use os.rename() and os.makedirs(). [Stefan]
- Fix NetBSD URL. [Kamil]

Build tests in one 32 bit Linux guest and three BSD images are defined in this
series. This is a more managable way than the manually maintained virtual
machines in patchew. Also, one big advantage of ephemeral VMs over long running
guests is the reduced RAM usage of host, which makes it possible to have one
host test all these BSD variants and probably more.

The BSD guest templates are manually prepared following

https://wiki.qemu.org/Hosts/BSD

as it is not easy to automate. (The ideal approach is like the ubuntu.i386
script, which configures the guest on top of an official released image, fully
automatically.)

Need for help: "gmake check" in the added OpenBSD image fails with -ENOMEM
errors, even if I change "-m 2G" to "-m 8G" when starting VM. Ideas? And there
is a warning from ./configure about OpenBSD going to be unsupported in coming
releases, is it still the case?

Fam

Fam Zheng (13):
  gitignore: Ignore vm test images
  qemu.py: Add "wait()" method
  scripts: Add archive-source.sh
  tests: Add a test key pair
  tests: Add vm test lib
  tests: Add ubuntu.i386 image
  tests: Add FreeBSD image
  tests: Add NetBSD image
  tests: Add OpenBSD image
  Makefile: Add rules to run vm tests
  MAINTAINERS: Add tests/vm entry
  tests: Add README for vm tests
  docker: Use archive-source.py

 .gitignore|   1 +
 MAINTAINERS   |   1 +
 Makefile  |   2 +
 configure |   2 +-
 scripts/archive-source.sh |  33 ++
 scripts/qemu.py   |   7 ++
 tests/.gitignore  |   1 +
 tests/docker/Makefile.include |  15 +--
 tests/docker/run  |   8 +-
 tests/keys/id_rsa |  27 +
 tests/keys/id_rsa.pub |   1 +
 tests/vm/Makefile.include |  42 +++
 tests/vm/README   |  63 +++
 tests/vm/basevm.py| 256 ++
 tests/vm/freebsd  |  42 +++
 tests/vm/netbsd   |  42 +++
 tests/vm/openbsd  |  43 +++
 tests/vm/ubuntu.i386  |  88 +++
 18 files changed, 653 insertions(+), 21 deletions(-)
 create mode 100755 scripts/archive-source.sh
 create mode 100644 tests/keys/id_rsa
 create mode 100644 tests/keys/id_rsa.pub
 create mode 100644 tests/vm/Makefile.include
 create mode 100644 tests/vm/README
 create mode 100755 tests/vm/basevm.py
 create mode 100755 tests/vm/freebsd
 create mode 100755 tests/vm/netbsd
 create mode 100755 tests/vm/openbsd
 create mode 100755 tests/vm/ubuntu.i386

-- 
2.13.5




[Qemu-devel] [PATCH v7 01/13] gitignore: Ignore vm test images

2017-09-12 Thread Fam Zheng
Signed-off-by: Fam Zheng 
---
 .gitignore   | 1 +
 tests/.gitignore | 1 +
 2 files changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index cf65316863..40acfcb9e2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -52,6 +52,7 @@
 /vscclient
 /vhost-user-scsi
 /fsdev/virtfs-proxy-helper
+*.tmp
 *.[1-9]
 *.a
 *.aux
diff --git a/tests/.gitignore b/tests/.gitignore
index fed0189a5a..cf6d99c91e 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -95,3 +95,4 @@ test-filter-mirror
 test-filter-redirector
 *-test
 qapi-schema/*.test.*
+vm/*.img
-- 
2.13.5




[Qemu-devel] [PATCH v7 06/13] tests: Add ubuntu.i386 image

2017-09-12 Thread Fam Zheng
This adds a 32bit guest.

The official LTS cloud image is downloaded and initialized with
cloud-init.

Signed-off-by: Fam Zheng 
---
 tests/vm/ubuntu.i386 | 88 
 1 file changed, 88 insertions(+)
 create mode 100755 tests/vm/ubuntu.i386

diff --git a/tests/vm/ubuntu.i386 b/tests/vm/ubuntu.i386
new file mode 100755
index 00..e70dcb89ce
--- /dev/null
+++ b/tests/vm/ubuntu.i386
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+#
+# Ubuntu i386 image
+#
+# Copyright 2017 Red Hat Inc.
+#
+# Authors:
+#  Fam Zheng 
+#
+# This code is licensed under the GPL version 2 or later.  See
+# the COPYING file in the top-level directory.
+#
+
+import os
+import sys
+import subprocess
+import basevm
+import time
+
+class UbuntuX86VM(basevm.BaseVM):
+name = "ubuntu.i386"
+BUILD_SCRIPT = """
+set -e;
+cd $(mktemp -d);
+sudo chmod a+r /dev/vdb;
+tar -xf /dev/vdb;
+./configure {configure_opts};
+make -j{jobs};
+make check;
+"""
+
+def _gen_cloud_init_iso(self):
+cidir = self._tmpdir
+mdata = open(os.path.join(cidir, "meta-data"), "w")
+mdata.writelines(["instance-id: ubuntu-vm-0\n",
+ "local-hostname: ubuntu-guest\n"])
+mdata.close()
+udata = open(os.path.join(cidir, "user-data"), "w")
+udata.writelines(["#cloud-config\n",
+  "chpasswd:\n",
+  "  list: |\n",
+  "root:%s\n" % self.ROOT_PASS,
+  "%s:%s\n" % (self.GUEST_USER, self.GUEST_PASS),
+  "  expire: False\n",
+  "users:\n",
+  "  - name: %s\n" % self.GUEST_USER,
+  "sudo: ALL=(ALL) NOPASSWD:ALL\n",
+  "ssh-authorized-keys:\n",
+  "- %s\n" % basevm.SSH_PUB_KEY,
+  "  - name: root\n",
+  "ssh-authorized-keys:\n",
+  "- %s\n" % basevm.SSH_PUB_KEY])
+udata.close()
+subprocess.check_call(["genisoimage", "-output", "cloud-init.iso",
+   "-volid", "cidata", "-joliet", "-rock",
+   "user-data", "meta-data"],
+   cwd=cidir,
+   stdin=self._devnull, stdout=self._stdout,
+   stderr=self._stdout)
+return os.path.join(cidir, "cloud-init.iso")
+
+def build_image(self, img):
+cimg = 
self._download_with_cache("https://cloud-images.ubuntu.com/releases/16.04/release/ubuntu-16.04-server-cloudimg-i386-disk1.img";)
+img_tmp = img + ".tmp"
+subprocess.check_call(["cp", "-f", cimg, img_tmp])
+subprocess.check_call(["qemu-img", "resize", img_tmp, "50G"])
+self.boot(img_tmp, extra_args = ["-cdrom", self._gen_cloud_init_iso()])
+self.wait_ssh()
+self.ssh_root_check("touch /etc/cloud/cloud-init.disabled")
+self.ssh_root_check("apt-get update")
+self.ssh_root_check("apt-get install -y cloud-initramfs-growroot")
+# Don't check the status in case the guest hang up too quickly
+self.ssh_root("sync && reboot")
+time.sleep(5)
+self.wait_ssh()
+# The previous update sometimes doesn't survive a reboot, so do it 
again
+self.ssh_root_check("apt-get update")
+self.ssh_root_check("apt-get build-dep -y qemu")
+self.ssh_root_check("apt-get install -y libfdt-dev")
+self.ssh_root("poweroff")
+self.wait()
+if os.path.exists(img):
+os.remove(img)
+os.rename(img_tmp, img)
+return 0
+
+if __name__ == "__main__":
+sys.exit(basevm.main(UbuntuX86VM))
-- 
2.13.5




[Qemu-devel] [PATCH v7 02/13] qemu.py: Add "wait()" method

2017-09-12 Thread Fam Zheng
Signed-off-by: Fam Zheng 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Alex Bennée 
---
 scripts/qemu.py | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/scripts/qemu.py b/scripts/qemu.py
index 4d8ee10943..99963053a5 100644
--- a/scripts/qemu.py
+++ b/scripts/qemu.py
@@ -157,6 +157,13 @@ class QEMUMachine(object):
 self._post_shutdown()
 raise
 
+def wait(self):
+'''Wait for the VM to power off'''
+self._popen.wait()
+self._qmp.close()
+self._load_io_log()
+self._post_shutdown()
+
 def shutdown(self):
 '''Terminate the VM and clean up'''
 if self.is_running():
-- 
2.13.5




[Qemu-devel] [PATCH v7 03/13] scripts: Add archive-source.sh

2017-09-12 Thread Fam Zheng
Signed-off-by: Fam Zheng 
---
 scripts/archive-source.sh | 33 +
 1 file changed, 33 insertions(+)
 create mode 100755 scripts/archive-source.sh

diff --git a/scripts/archive-source.sh b/scripts/archive-source.sh
new file mode 100755
index 00..8b373e3090
--- /dev/null
+++ b/scripts/archive-source.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# Author: Fam Zheng 
+#
+# Archive source tree, including submodules. This is created for test code to
+# export the source files, in order to be built in a different enviornment,
+# such as in a docker instance or VM.
+#
+# This code is licensed under the GPL version 2 or later.  See
+# the COPYING file in the top-level directory.
+
+set -e
+
+if test $# -lt 1; then
+echo "Usage: $0 "
+exit 1
+fi
+
+submodules=$(git submodule foreach --recursive --quiet 'echo $name')
+
+if test -n "$submodules"; then
+{
+git ls-files
+for sm in $submodules; do
+(cd $sm; git ls-files) | sed "s:^:$sm/:"
+done
+} | grep -x -v $(for sm in $submodules; do echo "-e $sm"; done) > "$1".list
+else
+git ls-files > "$1".list
+fi
+
+tar -cf "$1" -T "$1".list
+rm "$1".list
-- 
2.13.5




[Qemu-devel] [PATCH v7 07/13] tests: Add FreeBSD image

2017-09-12 Thread Fam Zheng
The image is prepared following instructions as in:

https://wiki.qemu.org/Hosts/BSD

Signed-off-by: Fam Zheng 
---
 tests/vm/freebsd | 42 ++
 1 file changed, 42 insertions(+)
 create mode 100755 tests/vm/freebsd

diff --git a/tests/vm/freebsd b/tests/vm/freebsd
new file mode 100755
index 00..039dad8f69
--- /dev/null
+++ b/tests/vm/freebsd
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+#
+# FreeBSD VM image
+#
+# Copyright 2017 Red Hat Inc.
+#
+# Authors:
+#  Fam Zheng 
+#
+# This code is licensed under the GPL version 2 or later.  See
+# the COPYING file in the top-level directory.
+#
+
+import os
+import sys
+import subprocess
+import basevm
+
+class FreeBSDVM(basevm.BaseVM):
+name = "freebsd"
+BUILD_SCRIPT = """
+set -e;
+cd $(mktemp -d /var/tmp/qemu-test.XX);
+tar -xf /dev/vtbd1;
+./configure {configure_opts};
+gmake -j{jobs};
+gmake check;
+"""
+
+def build_image(self, img):
+cimg = 
self._download_with_cache("http://download.patchew.org/freebsd-11.1-amd64.img.xz";,
+
sha256sum='adcb771549b37bc63826c501f05121a206ed3d9f55f49145908f7e1432d65891')
+img_tmp_xz = img + ".tmp.xz"
+img_tmp = img + ".tmp"
+subprocess.check_call(["cp", "-f", cimg, img_tmp_xz])
+subprocess.check_call(["xz", "-df", img_tmp_xz])
+if os.path.exists(img):
+os.remove(img)
+os.rename(img_tmp, img)
+
+if __name__ == "__main__":
+sys.exit(basevm.main(FreeBSDVM))
-- 
2.13.5




[Qemu-devel] [PATCH v7 04/13] tests: Add a test key pair

2017-09-12 Thread Fam Zheng
This will be used by setup test user ssh.

Signed-off-by: Fam Zheng 
---
 tests/keys/id_rsa | 27 +++
 tests/keys/id_rsa.pub |  1 +
 2 files changed, 28 insertions(+)
 create mode 100644 tests/keys/id_rsa
 create mode 100644 tests/keys/id_rsa.pub

diff --git a/tests/keys/id_rsa b/tests/keys/id_rsa
new file mode 100644
index 00..3a3787154b
--- /dev/null
+++ b/tests/keys/id_rsa
@@ -0,0 +1,27 @@
+BEGIN RSA PRIVATE KEY-
+MIIEowIBAAKCAQEAopAuOlmLV6LVHdFBj8/eeOwI9CqguIJPp7eAQSZvOiB4Ag/R
+coEhl/RBbrV5Yc/SmSD4PTpJO/iM10RwliNjDb4a3I8q3sykRJu9c9PI/YsH8WN9
++NH2NjKPtJIcKTu287IM5JYxyB6nDoOzILbTyJ1TDR/xH6qYEfBAyiblggdjcvhA
+RTf93QIn39F/xLypXvT1K2O9BJEsnJ8lEUvB2UXhKo/JTfSeZF8wPBeowaP9EONk
+7b+nuJOWHGg68Ji6wVi62tjwl2Szch6lxIhZBpnV7QNRKMfYHP6eIyF4pusazzZq
+Telsq6xI2ghecWLzb/MF5A+rklsGx2FNuJSAJwIDAQABAoIBAHHi4o/8VZNivz0x
+cWXn8erzKV6tUoWQvW85Lj/2RiwJvSlsnYZDkx5af1CpEE2HA/pFT8PNRqsd+MWC
+7AEy710cVsM4BYerBFYQaYxwzblaoojo88LSjVPw3h5Z0iLM8+IMVd36nwuc9dpE
+R8TecMZ1+U4Tl6BgqkK+9xToZRdPKdjS8L5MoFhGN+xY0vRbbJbGaV9Q0IHxLBkB
+rEBV7T1mUynneCHRUQlJQEwJmKpT8MH3IjsUXlG5YvnuuvcQJSNTaW2iDLxuOKp8
+cxW8+qL88zpb1D5dppoIu6rlrugN0azSq70ruFJQPc/A8GQrDKoGgRQiagxNY3u+
+vHZzXlECgYEA0dKO3gfkSxsDBb94sQwskMScqLhcKhztEa8kPxTx6Yqh+x8/scx3
+XhJyOt669P8U1v8a/2Al+s81oZzzfQSzO1Q7gEwSrgBcRMSIoRBUw9uYcy02ngb/
+j/ng3DGivfJztjjiSJwb46FHkJ2JR8mF2UisC6UMXk3NgFY/3vWQx78CgYEAxlcG
+T3hfSWSmTgKRczMJuHQOX9ULfTBIqwP5VqkkkiavzigGRirzb5lgnmuTSPTpF0LB
+XVPjR2M4q+7gzP0Dca3pocrvLEoxjwIKnCbYKnyyvnUoE9qHv4Kr+vDbgWpa2LXG
+JbLmE7tgTCIp20jOPPT4xuDvlbzQZBJ5qCQSoZkCgYEAgrotSSihlCnAOFSTXbu4
+CHp3IKe8xIBBNENq0eK61kcJpOxTQvOha3sSsJsU4JAM6+cFaxb8kseHIqonCj1j
+bhOM/uJmwQJ4el/4wGDsbxriYOBKpyq1D38gGhDS1IW6kk3erl6VAb36WJ/OaGum
+eTpN9vNeQWM4Jj2WjdNx4QECgYAwTdd6mU1TmZCrJRL5ZG+0nYc2rbMrnQvFoqUi
+BvWiJovggHzur90zy73tNzPaq9Ls2FQxf5G1vCN8NCRJqEEjeYCR59OSDMu/EXc2
+CnvQ9SevHOdS1oEDEjcCWZCMFzPi3XpRih1gptzQDe31uuiHjf3cqcGPzTlPdfRt
+D8P92QKBgC4UaBvIRwREVJsdZzpIzm224Bpe8LOmA7DeTnjlT0b3lkGiBJ36/Q0p
+VhYh/6cjX4/iuIs7gJbGon7B+YPB8scmOi3fj0+nkJAONue1mMfBNkba6qQTc6Y2
+5mEKw2/O7/JpND7ucU3OK9plcw/qnrWDgHxl0Iz95+OzUIIagxne
+-END RSA PRIVATE KEY-
diff --git a/tests/keys/id_rsa.pub b/tests/keys/id_rsa.pub
new file mode 100644
index 00..d9888e312f
--- /dev/null
+++ b/tests/keys/id_rsa.pub
@@ -0,0 +1 @@
+ssh-rsa 
B3NzaC1yc2EDAQABAAABAQCikC46WYtXotUd0UGPz9547Aj0KqC4gk+nt4BBJm86IHgCD9FygSGX9EFutXlhz9KZIPg9Okk7+IzXRHCWI2MNvhrcjyrezKREm71z08j9iwfxY3340fY2Mo+0khwpO7bzsgzkljHIHqcOg7MgttPInVMNH/EfqpgR8EDKJuWCB2Ny+EBFN/3dAiff0X/EvKle9PUrY70EkSycnyURS8HZReEqj8lN9J5kXzA8F6jBo/0Q42Ttv6e4k5YcaDrwmLrBWLra2PCXZLNyHqXEiFkGmdXtA1Eox9gc/p4jIXim6xrPNmpN6WyrrEjaCF5xYvNv8wXkD6uSWwbHYU24lIAn
 qemu-test
-- 
2.13.5




[Qemu-devel] [PATCH v7 12/13] tests: Add README for vm tests

2017-09-12 Thread Fam Zheng
Signed-off-by: Fam Zheng 
---
 tests/vm/README | 63 +
 1 file changed, 63 insertions(+)
 create mode 100644 tests/vm/README

diff --git a/tests/vm/README b/tests/vm/README
new file mode 100644
index 00..7d2fe4ac8d
--- /dev/null
+++ b/tests/vm/README
@@ -0,0 +1,63 @@
+=== VM test suite to run build in guests ===
+
+== Intro ==
+
+This test suite contains scripts that bootstrap various guest images that have
+necessary packages to build QEMU. The basic usage is documented in Makefile
+help which is displayed with "make vm-test".
+
+== Quick start ==
+
+Run "make vm-test" to list available make targets.
+
+== Manual invocation ==
+
+Each guest script is an executable script with the same command line options.
+For example to work with the netbsd guest, use $QEMU_SRC/tests/vm/netbsd:
+
+$ cd $QEMU_SRC/tests/vm
+
+# To bootstrap the image
+$ ./netbsd --build-image --image /var/tmp/netbsd.img
+<...>
+
+# To run an arbitrary command in guest (the output will not be echoed 
unless
+# --debug is added)
+$ ./netbsd --debug --image /var/tmp/netbsd.img uname -a
+
+# To build QEMU in guest
+$ ./netbsd --debug --image /var/tmp/netbsd.img --build-qemu $QEMU_SRC
+
+# To get to an interactive shell
+$ ./netbsd --interactive --image /var/tmp/netbsd.img sh
+
+== Adding new guests ==
+
+Please look at existing guest scripts for how to add new guests.
+
+Most importantly, create a subclass of BaseVM and implement build_image()
+method and define BUILD_SCRIPT, then finally call basevm.main() from the
+script's main().
+
+  - Usually in build_image(), a template image is downloaded from a predefined
+URL. BaseVM._download_with_cache() takes care of the cache and the
+checksum, so consider using it.
+
+  - Once the image is downloaded, users, SSH server and QEMU build deps should
+be set up:
+
+* Root password set to BaseVM.ROOT_PASS
+* User BaseVM.GUEST_USER is created, and password set to BaseVM.GUEST_PASS
+* SSH service is enabled and started on boot, BaseVM.SSH_PUB_KEY is added
+  to authorized_keys of both root and the normal user
+* DHCP client service is enabled and started on boot, so that it can
+  automatically configure the virtio-net-pci NIC and communicate with QEMU
+  user net (10.0.2.2)
+* Necessary packages are installed to untar the source tarball and build
+  QEMU
+
+  - Write a proper BUILD_SCRIPT template, which should be a shell script that
+untars a raw virtio-blk block device, which is the tarball data blob of the
+QEMU source tree, then configure/build it. Running "make check" is also
+recommended.
+
-- 
2.13.5




[Qemu-devel] [PATCH v7 08/13] tests: Add NetBSD image

2017-09-12 Thread Fam Zheng
The image is prepared following instructions as in:

https://wiki.qemu.org/Hosts/BSD

Signed-off-by: Fam Zheng 
Reviewed-by: Kamil Rytarowski 
---
 tests/vm/netbsd | 42 ++
 1 file changed, 42 insertions(+)
 create mode 100755 tests/vm/netbsd

diff --git a/tests/vm/netbsd b/tests/vm/netbsd
new file mode 100755
index 00..3972d8b45c
--- /dev/null
+++ b/tests/vm/netbsd
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+#
+# NetBSD VM image
+#
+# Copyright 2017 Red Hat Inc.
+#
+# Authors:
+#  Fam Zheng 
+#
+# This code is licensed under the GPL version 2 or later.  See
+# the COPYING file in the top-level directory.
+#
+
+import os
+import sys
+import subprocess
+import basevm
+
+class NetBSDVM(basevm.BaseVM):
+name = "netbsd"
+BUILD_SCRIPT = """
+set -e;
+cd $(mktemp -d /var/tmp/qemu-test.XX);
+tar -xf /dev/rld1a;
+./configure --python=python2.7 {configure_opts};
+gmake -j{jobs};
+gmake check;
+"""
+
+def build_image(self, img):
+cimg = 
self._download_with_cache("http://download.patchew.org/netbsd-7.1-amd64.img.xz";,
+ 
sha256sum='b633d565b0eac3d02015cd0c81440bd8a7a8df8512615ac1ee05d318be015732')
+img_tmp_xz = img + ".tmp.xz"
+img_tmp = img + ".tmp"
+subprocess.check_call(["cp", "-f", cimg, img_tmp_xz])
+subprocess.check_call(["xz", "-df", img_tmp_xz])
+if os.path.exists(img):
+os.remove(img)
+os.rename(img_tmp, img)
+
+if __name__ == "__main__":
+sys.exit(basevm.main(NetBSDVM))
-- 
2.13.5




[Qemu-devel] [PATCH v7 05/13] tests: Add vm test lib

2017-09-12 Thread Fam Zheng
This is the common code to implement a "VM test" to

  1) Download and initialize a pre-defined VM that has necessary
  dependencies to build QEMU and SSH access.

  2) Archive $SRC_PATH to a .tar file.

  3) Boot the VM, and pass the source tar file to the guest.

  4) SSH into the VM, untar the source tarball, build from the source.

Signed-off-by: Fam Zheng 
---
 tests/vm/basevm.py | 256 +
 1 file changed, 256 insertions(+)
 create mode 100755 tests/vm/basevm.py

diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
new file mode 100755
index 00..e4603f3fba
--- /dev/null
+++ b/tests/vm/basevm.py
@@ -0,0 +1,256 @@
+#!/usr/bin/env python
+#
+# VM testing base class
+#
+# Copyright 2017 Red Hat Inc.
+#
+# Authors:
+#  Fam Zheng 
+#
+# This code is licensed under the GPL version 2 or later.  See
+# the COPYING file in the top-level directory.
+#
+
+import os
+import sys
+import logging
+import time
+import datetime
+sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "scripts"))
+from qemu import QEMUMachine
+import subprocess
+import hashlib
+import optparse
+import atexit
+import tempfile
+import shutil
+import multiprocessing
+import traceback
+
+SSH_KEY = open(os.path.join(od.path.dirname(__file__),
+   "..", "keys", "id_rsa")).read()
+SSH_PUB_KEY = open(os.path.join(od.path.dirname(__file__),
+   "..", "keys", "id_rsa.pub")).read()
+
+class BaseVM(object):
+GUEST_USER = "qemu"
+GUEST_PASS = "qemupass"
+ROOT_PASS = "qemupass"
+
+# The script to run in the guest that builds QEMU
+BUILD_SCRIPT = ""
+# The guest name, to be overridden by subclasses
+name = "#base"
+def __init__(self, debug=False, vcpus=None):
+self._guest = None
+self._tmpdir = tempfile.mkdtemp(prefix="vm-test-", suffix=".tmp", 
dir=".")
+atexit.register(shutil.rmtree, self._tmpdir)
+
+self._ssh_key_file = os.path.join(self._tmpdir, "id_rsa")
+open(self._ssh_key_file, "w").write(SSH_KEY)
+subprocess.check_call(["chmod", "600", self._ssh_key_file])
+
+self._ssh_pub_key_file = os.path.join(self._tmpdir, "id_rsa.pub")
+open(self._ssh_pub_key_file, "w").write(SSH_PUB_KEY)
+
+self.debug = debug
+self._stderr = sys.stderr
+self._devnull = open(os.devnull, "w")
+if self.debug:
+self._stdout = sys.stdout
+else:
+self._stdout = self._devnull
+self._args = [ \
+"-nodefaults", "-m", "2G",
+"-cpu", "host",
+"-netdev", "user,id=vnet,hostfwd=:0.0.0.0:0-:22",
+"-device", "virtio-net-pci,netdev=vnet",
+"-vnc", ":0,to=20",
+"-serial", "file:%s" % os.path.join(self._tmpdir, "serial.out")]
+if vcpus:
+self._args += ["-smp", str(vcpus)]
+if os.access("/dev/kvm", os.R_OK | os.W_OK):
+self._args += ["-enable-kvm"]
+else:
+logging.info("KVM not available, not using -enable-kvm")
+self._data_args = []
+
+def _download_with_cache(self, url, sha256sum=None):
+def check_sha256sum(fname):
+if not sha256sum:
+return True
+checksum = subprocess.check_output(["sha256sum", fname]).split()[0]
+return sha256sum == checksum
+
+cache_dir = os.path.expanduser("~/.cache/qemu-vm/download")
+if not os.path.exists(cache_dir):
+os.makedirs(cache_dir)
+fname = os.path.join(cache_dir, hashlib.sha1(url).hexdigest())
+if os.path.exists(fname) and check_sha256sum(fname):
+return fname
+logging.debug("Downloading %s to %s...", url, fname)
+subprocess.check_call(["wget", "-c", url, "-O", fname + ".download"],
+  stdout=self._stdout, stderr=self._stderr)
+os.rename(fname + ".download", fname)
+return fname
+
+def _ssh_do(self, user, cmd, check, interactive=False):
+ssh_cmd = ["ssh", "-q",
+   "-o", "StrictHostKeyChecking=no",
+   "-o", "UserKnownHostsFile=" + os.devnull,
+   "-o", "ConnectTimeout=1",
+   "-p", self.ssh_port, "-i", self._ssh_key_file]
+if interactive:
+ssh_cmd += ['-t']
+assert not isinstance(cmd, str)
+ssh_cmd += ["%s@127.0.0.1" % user] + list(cmd)
+logging.debug("ssh_cmd: %s", " ".join(ssh_cmd))
+r = subprocess.call(ssh_cmd,
+stdin=sys.stdin if interactive else self._devnull,
+stdout=sys.stdout if interactive else self._stdout,
+stderr=sys.stderr if interactive else self._stderr)
+if check and r != 0:
+raise Exception("SSH command failed: %s" % cmd)
+return r
+
+def ssh(self, *cmd):
+return self._ssh_do(self.GUEST_USER, cmd, False)
+
+def s

[Qemu-devel] [PATCH v7 09/13] tests: Add OpenBSD image

2017-09-12 Thread Fam Zheng
The image is prepared following instructions as in:

https://wiki.qemu.org/Hosts/BSD

Signed-off-by: Fam Zheng 
---
 tests/vm/openbsd | 43 +++
 1 file changed, 43 insertions(+)
 create mode 100755 tests/vm/openbsd

diff --git a/tests/vm/openbsd b/tests/vm/openbsd
new file mode 100755
index 00..6ae16d97fd
--- /dev/null
+++ b/tests/vm/openbsd
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+#
+# OpenBSD VM image
+#
+# Copyright 2017 Red Hat Inc.
+#
+# Authors:
+#  Fam Zheng 
+#
+# This code is licensed under the GPL version 2 or later.  See
+# the COPYING file in the top-level directory.
+#
+
+import os
+import sys
+import subprocess
+import basevm
+
+class OpenBSDVM(basevm.BaseVM):
+name = "openbsd"
+BUILD_SCRIPT = """
+set -e;
+cd $(mktemp -d /var/tmp/qemu-test.XX);
+tar -xf /dev/rsd1c;
+./configure --cc=x86_64-unknown-openbsd6.1-gcc-4.9.4 
--python=python2.7 {configure_opts};
+gmake -j{jobs};
+# XXX: "gmake check" seems to always hang or fail
+#gmake check;
+"""
+
+def build_image(self, img):
+cimg = 
self._download_with_cache("http://download.patchew.org/openbsd-6.1-amd64.img.xz";,
+
sha256sum='8c6cedc483e602cfee5e04f0406c64eb99138495e8ca580bc0293bcf0640c1bf')
+img_tmp_xz = img + ".tmp.xz"
+img_tmp = img + ".tmp"
+subprocess.check_call(["cp", "-f", cimg, img_tmp_xz])
+subprocess.check_call(["xz", "-df", img_tmp_xz])
+if os.path.exists(img):
+os.remove(img)
+os.rename(img_tmp, img)
+
+if __name__ == "__main__":
+sys.exit(basevm.main(OpenBSDVM))
-- 
2.13.5




[Qemu-devel] [PATCH v7 11/13] MAINTAINERS: Add tests/vm entry

2017-09-12 Thread Fam Zheng
Signed-off-by: Fam Zheng 
Reviewed-by: Stefan Hajnoczi 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 36eeb42d19..42f5454311 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1891,6 +1891,7 @@ S: Maintained
 F: .travis.yml
 F: .shippable.yml
 F: tests/docker/
+F: tests/vm/
 W: https://travis-ci.org/qemu/qemu
 W: https://app.shippable.com/github/qemu/qemu
 W: http://patchew.org/QEMU/
-- 
2.13.5




[Qemu-devel] [PATCH v7 10/13] Makefile: Add rules to run vm tests

2017-09-12 Thread Fam Zheng
Signed-off-by: Fam Zheng 
---
 Makefile  |  2 ++
 configure |  2 +-
 tests/vm/Makefile.include | 42 ++
 3 files changed, 45 insertions(+), 1 deletion(-)
 create mode 100644 tests/vm/Makefile.include

diff --git a/Makefile b/Makefile
index 337a1f6f9b..946eb2ce35 100644
--- a/Makefile
+++ b/Makefile
@@ -822,6 +822,7 @@ endif
 -include $(wildcard *.d tests/*.d)
 
 include $(SRC_PATH)/tests/docker/Makefile.include
+include $(SRC_PATH)/tests/vm/Makefile.include
 
 .PHONY: help
 help:
@@ -845,6 +846,7 @@ help:
@echo  'Test targets:'
@echo  '  check   - Run all tests (check-help for details)'
@echo  '  docker  - Help about targets running tests inside 
Docker containers'
+   @echo  '  vm-test - Help about targets running tests inside VM'
@echo  ''
@echo  'Documentation targets:'
@echo  '  html info pdf txt'
diff --git a/configure b/configure
index fd7e3a5e81..3918c47cd8 100755
--- a/configure
+++ b/configure
@@ -6546,7 +6546,7 @@ if test "$ccache_cpp2" = "yes"; then
 fi
 
 # build tree in object directory in case the source is not in the current 
directory
-DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos 
tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests"
+DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos 
tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests tests/vm"
 DIRS="$DIRS docs docs/interop fsdev"
 DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw"
 DIRS="$DIRS roms/seabios roms/vgabios"
diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include
new file mode 100644
index 00..5daa2a3b73
--- /dev/null
+++ b/tests/vm/Makefile.include
@@ -0,0 +1,42 @@
+# Makefile for VM tests
+
+.PHONY: vm-build-all
+
+IMAGES := ubuntu.i386 freebsd netbsd openbsd
+IMAGE_FILES := $(patsubst %, tests/vm/%.img, $(IMAGES))
+
+.PRECIOUS: $(IMAGE_FILES)
+
+vm-test:
+   @echo "vm-test: Test QEMU in preconfigured virtual machines"
+   @echo
+   @echo "  vm-build-ubuntu.i386- Build QEMU in ubuntu i386 VM"
+   @echo "  vm-build-freebsd- Build QEMU in FreeBSD VM"
+   @echo "  vm-build-netbsd - Build QEMU in NetBSD VM"
+   @echo "  vm-build-openbsd- Build QEMU in OpenBSD VM"
+
+vm-build-all: $(addprefix vm-build-, $(IMAGES))
+
+tests/vm/%.img: $(SRC_PATH)/tests/vm/% \
+   $(SRC_PATH)/tests/vm/basevm.py \
+   $(SRC_PATH)/tests/vm/Makefile.include
+   $(call quiet-command, \
+   $< \
+   $(if $(V)$(DEBUG), --debug) \
+   --image "$@" \
+   --force \
+   --build-image $@, \
+   "  VM-IMAGE $*")
+
+
+# Build in VM $(IMAGE)
+vm-build-%: tests/vm/%.img
+   $(call quiet-command, \
+   $(SRC_PATH)/tests/vm/$* \
+   $(if $(V)$(DEBUG), --debug) \
+   $(if $(DEBUG), --interactive) \
+   $(if $(J),--jobs $(J)) \
+   --image "$<" \
+   --build-qemu $(SRC_PATH), \
+   "  VM-BUILD $*")
+
-- 
2.13.5




[Qemu-devel] [PATCH v7 13/13] docker: Use archive-source.py

2017-09-12 Thread Fam Zheng
Signed-off-by: Fam Zheng 
---
 tests/docker/Makefile.include | 15 ++-
 tests/docker/run  |  8 +---
 2 files changed, 3 insertions(+), 20 deletions(-)

diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include
index aaab1a4208..7a027d5bd6 100644
--- a/tests/docker/Makefile.include
+++ b/tests/docker/Makefile.include
@@ -17,24 +17,13 @@ DOCKER_TOOLS := travis
 TESTS ?= %
 IMAGES ?= %
 
-# Make archive from git repo $1 to tar.gz $2
-make-archive-maybe = $(if $(wildcard $1/*), \
-   $(call quiet-command, \
-   (cd $1; if git diff-index --quiet HEAD -- &>/dev/null; then \
-   git archive -1 HEAD --format=tar.gz; \
-   else \
-   git archive -1 $$(git stash create) --format=tar.gz; \
-   fi) > $2, \
-   "ARCHIVE","$(notdir $2)"))
-
 CUR_TIME := $(shell date +%Y-%m-%d-%H.%M.%S.)
 DOCKER_SRC_COPY := docker-src.$(CUR_TIME)
 
 $(DOCKER_SRC_COPY):
@mkdir $@
-   $(call make-archive-maybe, $(SRC_PATH), $@/qemu.tgz)
-   $(call make-archive-maybe, $(SRC_PATH)/dtc, $@/dtc.tgz)
-   $(call make-archive-maybe, $(SRC_PATH)/pixman, $@/pixman.tgz)
+   $(call quiet-command, $(SRC_PATH)/scripts/archive-source.sh 
$@/qemu.tar, \
+   "GEN", "$@/qemu.tar")
$(call quiet-command, cp $(SRC_PATH)/tests/docker/run $@/run, \
"COPY","RUNNER")
 
diff --git a/tests/docker/run b/tests/docker/run
index c1e4513bce..9eb9165f76 100755
--- a/tests/docker/run
+++ b/tests/docker/run
@@ -32,13 +32,7 @@ export TEST_DIR=/tmp/qemu-test
 mkdir -p $TEST_DIR/{src,build,install}
 
 # Extract the source tarballs
-tar -C $TEST_DIR/src -xzf $BASE/qemu.tgz
-for p in dtc pixman; do
-if test -f $BASE/$p.tgz; then
-tar -C $TEST_DIR/src/$p -xzf $BASE/$p.tgz
-export FEATURES="$FEATURES $p"
-fi
-done
+tar -C $TEST_DIR/src -xf $BASE/qemu.tar
 
 if test -n "$SHOW_ENV"; then
 if test -f /packages.txt; then
-- 
2.13.5




Re: [Qemu-devel] [PATCH v7 00/13] tests: Add VM based build tests (for non-x86_64 and/or non-Linux)

2017-09-12 Thread no-reply
Hi,

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

Subject: [Qemu-devel] [PATCH v7 00/13] tests: Add VM based build tests (for 
non-x86_64 and/or non-Linux)
Message-id: 20170913030119.3957-1-f...@redhat.com
Type: series

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

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

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
 t [tag update]
patchew/1504812251-23438-1-git-send-email-sundeep.l...@gmail.com -> 
patchew/1504812251-23438-1-git-send-email-sundeep.l...@gmail.com
 t [tag update]
patchew/1505232834-20890-1-git-send-email-peter.mayd...@linaro.org -> 
patchew/1505232834-20890-1-git-send-email-peter.mayd...@linaro.org
 * [new tag]   patchew/20170913030119.3957-1-f...@redhat.com -> 
patchew/20170913030119.3957-1-f...@redhat.com
Switched to a new branch 'test'
2a093b5b91 docker: Use archive-source.py
d2593fa09c tests: Add README for vm tests
fb3acd78df MAINTAINERS: Add tests/vm entry
90ed120035 Makefile: Add rules to run vm tests
0ce88831a3 tests: Add OpenBSD image
d5f133ecf2 tests: Add NetBSD image
da78075e20 tests: Add FreeBSD image
d1f4a3a768 tests: Add ubuntu.i386 image
ecb8ea14ca tests: Add vm test lib
fb1ed69ecc tests: Add a test key pair
ab63dd9b38 scripts: Add archive-source.sh
1c4bcf6389 qemu.py: Add "wait()" method
6376f7d0bb gitignore: Ignore vm test images

=== OUTPUT BEGIN ===
Checking PATCH 1/13: gitignore: Ignore vm test images...
Checking PATCH 2/13: qemu.py: Add "wait()" method...
Checking PATCH 3/13: scripts: Add archive-source.sh...
Checking PATCH 4/13: tests: Add a test key pair...
Checking PATCH 5/13: tests: Add vm test lib...
WARNING: line over 80 characters
#71: FILE: tests/vm/basevm.py:46:
+self._tmpdir = tempfile.mkdtemp(prefix="vm-test-", suffix=".tmp", 
dir=".")

WARNING: line over 80 characters
#162: FILE: tests/vm/basevm.py:137:
+logging.debug("Creating archive %s for src_dir dir: %s", tarfile, 
src_dir)

WARNING: line over 80 characters
#167: FILE: tests/vm/basevm.py:142:
+"file=%s,if=none,id=%s,cache=writeback,format=raw" 
% \

WARNING: line over 80 characters
#170: FILE: tests/vm/basevm.py:145:
+"virtio-blk,drive=%s,serial=%s,bootindex=1" % 
(name, name)]

ERROR: line over 90 characters
#225: FILE: tests/vm/basevm.py:200:
+VM test utility.  Exit codes: 0 = success, 1 = command line error, 2 = 
environment initialization failed, 3 = test command failed""")

WARNING: line over 80 characters
#232: FILE: tests/vm/basevm.py:207:
+parser.add_option("--jobs", type=int, default=multiprocessing.cpu_count() 
/ 2,

total: 1 errors, 5 warnings, 256 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 6/13: tests: Add ubuntu.i386 image...
Checking PATCH 7/13: tests: Add FreeBSD image...
Checking PATCH 8/13: tests: Add NetBSD image...
Checking PATCH 9/13: tests: Add OpenBSD image...
Checking PATCH 10/13: Makefile: Add rules to run vm tests...
Checking PATCH 11/13: MAINTAINERS: Add tests/vm entry...
Checking PATCH 12/13: tests: Add README for vm tests...
Checking PATCH 13/13: docker: Use archive-source.py...
=== 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] [RFC v2 16/32] vhost+postcopy: Send address back to qemu

2017-09-12 Thread Peter Xu
On Tue, Sep 12, 2017 at 06:15:13PM +0100, Dr. David Alan Gilbert wrote:
> * Peter Xu (pet...@redhat.com) wrote:
> > On Thu, Aug 24, 2017 at 08:27:14PM +0100, Dr. David Alan Gilbert (git) 
> > wrote:
> > > From: "Dr. David Alan Gilbert" 
> > > 
> > > We need a better way, but at the moment we need the address of the
> > > mappings sent back to qemu so it can interpret the messages on the
> > > userfaultfd it reads.
> > > 
> > > Note: We don't ask for the default 'ack' reply since we've got our own.
> > > 
> > > Signed-off-by: Dr. David Alan Gilbert 
> > > ---
> > >  contrib/libvhost-user/libvhost-user.c | 15 -
> > >  docs/interop/vhost-user.txt   |  6 
> > >  hw/virtio/trace-events|  1 +
> > >  hw/virtio/vhost-user.c| 57 
> > > ++-
> > >  4 files changed, 77 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/contrib/libvhost-user/libvhost-user.c 
> > > b/contrib/libvhost-user/libvhost-user.c
> > > index e6ab059a03..5ec54f7d60 100644
> > > --- a/contrib/libvhost-user/libvhost-user.c
> > > +++ b/contrib/libvhost-user/libvhost-user.c
> > > @@ -477,13 +477,26 @@ vu_set_mem_table_exec(VuDev *dev, VhostUserMsg 
> > > *vmsg)
> > >  DPRINT("%s: region %d: Registered userfault for %llx + 
> > > %llx\n",
> > >  __func__, i, reg_struct.range.start, 
> > > reg_struct.range.len);
> > >  /* TODO: Stash 'zero' support flags somewhere */
> > > -/* TODO: Get address back to QEMU */
> > >  
> > > +/* TODO: We need to find a way for the qemu not to see the 
> > > virtual
> > > + * addresses of the clients, so as to keep better separation.
> > > + */
> > > +/* Return the address to QEMU so that it can translate the 
> > > ufd
> > > + * fault addresses back.
> > > + */
> > > +msg_region->userspace_addr = (uintptr_t)(mmap_addr +
> > > + 
> > > dev_region->mmap_offset);
> > >  }
> > >  
> > >  close(vmsg->fds[i]);
> > >  }
> > >  
> > > +if (dev->postcopy_listening) {
> > > +/* Need to return the addresses - send the updated message back 
> > > */
> > > +vmsg->fd_num = 0;
> > > +return true;
> > > +}
> > > +
> > >  return false;
> > >  }
> > >  
> > > diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt
> > > index 73c3dd74db..b2a548c94d 100644
> > > --- a/docs/interop/vhost-user.txt
> > > +++ b/docs/interop/vhost-user.txt
> > > @@ -413,12 +413,18 @@ Master message types
> > >Id: 5
> > >Equivalent ioctl: VHOST_SET_MEM_TABLE
> > >Master payload: memory regions description
> > > +  Slave payload: (postcopy only) memory regions description
> > >  
> > >Sets the memory map regions on the slave so it can translate the 
> > > vring
> > >addresses. In the ancillary data there is an array of file 
> > > descriptors
> > >for each memory mapped region. The size and ordering of the fds 
> > > matches
> > >the number and ordering of memory regions.
> > >  
> > > +  When postcopy-listening has been received, SET_MEM_TABLE replies 
> > > with
> > > +  the bases of the memory mapped regions to the master.  It must 
> > > have mmap'd
> > > +  the regions and enabled userfaultfd on them.  Note NEED_REPLY_MASK
> > > +  is not set in this case.
> > > +
> > >   * VHOST_USER_SET_LOG_BASE
> > >  
> > >Id: 6
> > > diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
> > > index f736c7c84f..63fd4a79cf 100644
> > > --- a/hw/virtio/trace-events
> > > +++ b/hw/virtio/trace-events
> > > @@ -2,6 +2,7 @@
> > >  
> > >  # hw/virtio/vhost-user.c
> > >  vhost_user_postcopy_listen(void) ""
> > > +vhost_user_set_mem_table_postcopy(uint64_t client_addr, uint64_t qhva, 
> > > int reply_i, int region_i) "client:0x%"PRIx64" for hva: 0x%"PRIx64" reply 
> > > %d region %d"
> > >  
> > >  # hw/virtio/virtio.c
> > >  virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned 
> > > out_num) "elem %p size %zd in_num %u out_num %u"
> > > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> > > index 9178271ab2..2e4eb0864a 100644
> > > --- a/hw/virtio/vhost-user.c
> > > +++ b/hw/virtio/vhost-user.c
> > > @@ -19,6 +19,7 @@
> > >  #include "qemu/sockets.h"
> > >  #include "migration/migration.h"
> > >  #include "migration/postcopy-ram.h"
> > > +#include "trace.h"
> > >  
> > >  #include 
> > >  #include 
> > > @@ -133,6 +134,7 @@ struct vhost_user {
> > >  int slave_fd;
> > >  NotifierWithReturn postcopy_notifier;
> > >  struct PostCopyFD  postcopy_fd;
> > > +uint64_t   postcopy_client_bases[VHOST_MEMORY_MAX_NREGIONS];
> > >  };
> > >  
> > >  static bool ioeventfd_enabled(void)
> > > @@ -300,11 +302,13 @@ static int vhost_user_set_log_base(struct vhost_dev 
> > > *dev, uint64_t base,
> > > 

Re: [Qemu-devel] [RFC v2 19/32] vhost+postcopy: Resolve client address

2017-09-12 Thread Peter Xu
On Mon, Sep 11, 2017 at 12:58:15PM +0100, Dr. David Alan Gilbert wrote:
> * Peter Xu (pet...@redhat.com) wrote:
> > On Thu, Aug 24, 2017 at 08:27:17PM +0100, Dr. David Alan Gilbert (git) 
> > wrote:
> > > From: "Dr. David Alan Gilbert" 
> > > 
> > > Resolve fault addresses read off the clients UFD into RAMBlock
> > > and offset, and call back to the postcopy code to ask for the page.
> > > 
> > > Signed-off-by: Dr. David Alan Gilbert 
> > > ---
> > >  hw/virtio/trace-events |  3 +++
> > >  hw/virtio/vhost-user.c | 30 +-
> > >  2 files changed, 32 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
> > > index 5067dee19b..f7d4b831fe 100644
> > > --- a/hw/virtio/trace-events
> > > +++ b/hw/virtio/trace-events
> > > @@ -1,6 +1,9 @@
> > >  # See docs/devel/tracing.txt for syntax documentation.
> > >  
> > >  # hw/virtio/vhost-user.c
> > > +vhost_user_postcopy_fault_handler(const char *name, uint64_t 
> > > fault_address, int nregions) "%s: @0x%"PRIx64" nregions:%d"
> > > +vhost_user_postcopy_fault_handler_loop(int i, uint64_t client_base, 
> > > uint64_t size) "%d: client 0x%"PRIx64" +0x%"PRIx64
> > > +vhost_user_postcopy_fault_handler_found(int i, uint64_t region_offset, 
> > > uint64_t rb_offset) "%d: region_offset: 0x%"PRIx64" rb_offset:0x%"PRIx64
> > >  vhost_user_postcopy_listen(void) ""
> > >  vhost_user_set_mem_table_postcopy(uint64_t client_addr, uint64_t qhva, 
> > > int reply_i, int region_i) "client:0x%"PRIx64" for hva: 0x%"PRIx64" reply 
> > > %d region %d"
> > >  vhost_user_set_mem_table_withfd(int index, const char *name, uint64_t 
> > > memory_size, uint64_t guest_phys_addr, uint64_t userspace_addr, uint64_t 
> > > offset) "%d:%s: size:0x%"PRIx64" GPA:0x%"PRIx64" 
> > > QVA/userspace:0x%"PRIx64" RB offset:0x%"PRIx64
> > > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> > > index fbe2743298..2897ff70b3 100644
> > > --- a/hw/virtio/vhost-user.c
> > > +++ b/hw/virtio/vhost-user.c
> > > @@ -816,7 +816,35 @@ out:
> > >  static int vhost_user_postcopy_fault_handler(struct PostCopyFD *pcfd,
> > >   void *ufd)
> > >  {
> > > -return 0;
> > > +struct vhost_dev *dev = pcfd->data;
> > > +struct vhost_user *u = dev->opaque;
> > > +struct uffd_msg *msg = ufd;
> > > +uint64_t faultaddr = msg->arg.pagefault.address;
> > > +RAMBlock *rb = NULL;
> > > +uint64_t rb_offset;
> > > +int i;
> > > +
> > > +trace_vhost_user_postcopy_fault_handler(pcfd->idstr, faultaddr,
> > > +dev->mem->nregions);
> > > +for (i = 0; i < MIN(dev->mem->nregions, u->region_rb_len); i++) {
> > 
> > Should dev->mem->nregions always the same as u->region_rb_len?
> 
> u->region_rb_len only gets updated when vhost_user_set_mem_table is
> called, so I think there are short periods of time when they don't
> quite match.
> (We do have to take some more care than we are at the moment during
> updates, because this address resolution happens off the postcopy
> thread)

I see, so memory layout can change along the way...

But I still doubt whether this single MIN() can work.

Say, we have these arrays already:

- array A: dev->mem->regions[]
- array B: u->region_rb[]
- array C: u->postcopy_client_bases[]

These arrays should always be aligned with each other (index "i" of
array "A/B/C" will always describe the same memory region).  But since
we can change the memory layout dynamically during postcopy, then
array A can grow/shrink/change in following path:

  vhost_region_{add|delete}
updates array A  (1)
  vhost_region_{add|delete}
updates array A  (2)
  vhost_region_{add|delete}
updates array A  (3)
  ...
  vhost_commit
vhost_set_mem_table
  align arrays B/C with A(4)

IMHO array A may not really match B/C during step (1)-(3), until step
(4) to re-align them?  And if they are not aligned with each other, I
guess a single MIN() won't help much? (Since the indexing below would
be problematic?)

(Hmm, can we just disallow memory change during postcopy for now?)

> 
> > > +trace_vhost_user_postcopy_fault_handler_loop(i,
> > > +u->postcopy_client_bases[i], 
> > > dev->mem->regions[i].memory_size);
> > > +if (faultaddr >= u->postcopy_client_bases[i]) {

Ah, wait...

postcopy_client_bases[] is now defined with static size
VHOST_MEMORY_MAX_NREGIONS.  Shouldn't it be dynamically allocated as
well with dev->mem->nregions, just like vhost_user.region_rb[]?

Maybe we want to leave the postcopy_client_bases[i] be zeros when
dev->mem->regions[i] it's not a vhost-user supported region (without
"fd")?

> > > +/* Ofset of the fault address in the vhost region */
> > > +uint64_t region_offset = faultaddr - 
> > > u->postcopy_client_bases[i];
> > > +if (region_offset <= dev->mem->regions[i].memory_size) {
> > 
> > Should be

Re: [Qemu-devel] [PATCH v2 1/2] spapr: introduce common helper to write HPT address to KVM PR

2017-09-12 Thread David Gibson
On Wed, Sep 13, 2017 at 12:24:53AM +0200, Greg Kurz wrote:
> When running with KVM PR, if a new HPT is allocated we need to inform
> KVM about the HPT address and size. This is currently done with a hack
> which is open-coded in several places.
> 
> This patch consolidate the code in a dedicated helper that records
> the HPT address and size in the sPAPR context, and then does the
> magic for KVM PR.
> 
> Note that ppc_spapr_reset() now resets all devices and CPUs before
> allocating the HPT. This allows to drop the hack from spapr_cpu_reset().
> 
> Signed-off-by: Greg Kurz 

I like this more than the previous spin, but while discussing stuff
with SamB, I thought up a different approach, which I think will be
both cleaner and simpler.

It basically doesn't make sense to put the userspace HPT pointer into
env->spr[SDR1], we only do it to make kvmppc_put_books_sregs() do the
right thing.

Instead, we can have kvmppc_put_books_sregs() populate the "SDR1"
field in kvm_sregs from a vhyp hook.  We already have the reverse side
in that kvmppc_get_books_sregs() doesn't update the internal SDR1
value if vhyp is set.

In any case the spapr hook would compute the correct value direct from
spapr->htab.

After incoming migration I'm not sure we need to do anything - I think
we already do a pretty thorough register resync with KVM.

> ---
>  hw/ppc/spapr.c  |   31 ++-
>  hw/ppc/spapr_cpu_core.c |   15 ---
>  hw/ppc/spapr_hcall.c|   16 +---
>  include/hw/ppc/spapr.h  |1 +
>  4 files changed, 28 insertions(+), 35 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index f680f28a15ea..97f8afdbd7fe 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1309,6 +1309,25 @@ void spapr_free_hpt(sPAPRMachineState *spapr)
>  close_htab_fd(spapr);
>  }
>  
> +void spapr_install_hpt(sPAPRMachineState *spapr, void *htab, uint32_t shift)
> +{
> +assert(htab);
> +
> +spapr->htab = htab;
> +spapr->htab_shift = shift;
> +
> +/*
> + * This is a hack for the benefit of KVM PR - it abuses the SDR1
> + * slot in kvm_sregs to communicate the userspace address of the
> + * HPT
> + */
> +if (kvm_enabled()) {
> +target_ulong sdr1 = (target_ulong)(uintptr_t)spapr->htab
> +| (spapr->htab_shift - 18);
> +kvmppc_update_sdr1(sdr1);
> +}
> +}
> +
>  void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
>Error **errp)
>  {
> @@ -1339,16 +1358,17 @@ void spapr_reallocate_hpt(sPAPRMachineState *spapr, 
> int shift,
>  /* kernel-side HPT not needed, allocate in userspace instead */
>  size_t size = 1ULL << shift;
>  int i;
> +void *htab;
>  
> -spapr->htab = qemu_memalign(size, size);
> -if (!spapr->htab) {
> +htab = qemu_memalign(size, size);
> +if (!htab) {
>  error_setg_errno(errp, errno,
>   "Could not allocate HPT of order %d", shift);
>  return;
>  }
>  
> -memset(spapr->htab, 0, size);
> -spapr->htab_shift = shift;
> +memset(htab, 0, size);
> +spapr_install_hpt(spapr, htab, shift);
>  
>  for (i = 0; i < size / HASH_PTE_SIZE_64; i++) {
>  DIRTY_HPTE(HPTE(spapr->htab, i));
> @@ -1405,6 +1425,8 @@ static void ppc_spapr_reset(void)
>  /* Check for unknown sysbus devices */
>  foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
>  
> +qemu_devices_reset();
> +
>  if (kvm_enabled() && kvmppc_has_cap_mmu_radix()) {
>  /* If using KVM with radix mode available, VCPUs can be started
>   * without a HPT because KVM will start them in radix mode.
> @@ -1414,7 +1436,6 @@ static void ppc_spapr_reset(void)
>  spapr_setup_hpt_and_vrma(spapr);
>  }
>  
> -qemu_devices_reset();
>  spapr_clear_pending_events(spapr);
>  
>  /*
> diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
> index c08ee7571a50..c20b5c64b045 100644
> --- a/hw/ppc/spapr_cpu_core.c
> +++ b/hw/ppc/spapr_cpu_core.c
> @@ -73,7 +73,6 @@ void spapr_cpu_parse_features(sPAPRMachineState *spapr)
>  
>  static void spapr_cpu_reset(void *opaque)
>  {
> -sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
>  PowerPCCPU *cpu = opaque;
>  CPUState *cs = CPU(cpu);
>  CPUPPCState *env = &cpu->env;
> @@ -86,20 +85,6 @@ static void spapr_cpu_reset(void *opaque)
>  cs->halted = 1;
>  
>  env->spr[SPR_HIOR] = 0;
> -
> -/*
> - * This is a hack for the benefit of KVM PR - it abuses the SDR1
> - * slot in kvm_sregs to communicate the userspace address of the
> - * HPT
> - */
> -if (kvm_enabled()) {
> -env->spr[SPR_SDR1] = (target_ulong)(uintptr_t)spapr->htab
> -| (spapr->htab_shift - 18);
> -if (kvmppc_put_books_sregs(cpu) < 0) {
> -error_report("Unable to update SDR1 in KVM");

Re: [Qemu-devel] [PATCH v3 0/3] hmp: fix "dump-quest-memory" segfault

2017-09-12 Thread David Gibson
On Tue, Sep 12, 2017 at 04:36:30PM +0100, Dr. David Alan Gilbert wrote:
> * Thomas Huth (th...@redhat.com) wrote:
> > On 12.09.2017 16:46, Greg Kurz wrote:
> > > On Tue, 12 Sep 2017 16:01:46 +0200
> > > Laurent Vivier  wrote:
> > > 
> > >> Fix aarch64 and ppc when dump-guest-memory is
> > >> used with none machine type and no CPU.
> > >>
> > >> The other machine types don't have the problem.
> > >>
> > >> Update test-hmp, to test none machine type
> > >> with (2 MB) and without memory, and add a test
> > >> to test dump-quest-memory without filter parameters
> > >> (it needs the fix from Cornelia Huck to work)
> > >>
> > >> v3:
> > >>   - remove blank line after a comment
> > >>   - forbid memory dump when there is no CPU
> > >>
> > > 
> > > So in the end, we would forbid dump on aarch64 and
> > > ppc, while it is allowed on i386... I don't really
> > > care about which behavior is more appropriate but
> > > I guess they should be consistent at least.
> > 
> > It's kind of consistent: Allow it on architectures with fixed endianess,
> > but disallow it on architectures without fixed endianess ;-)
> 
> Another way to put it is that you can dump unless you need
> information about the CPU.
> 
> It also makes me wonder what happens on those CPUs that can
> change their endianness dynamically.

We already have code for that on ppc, we actually look in on the CPU's
mode register at dump time to decide which.  Theoretically that could
still be tricked, but in the almost-always case of boot an OS which
sets the endianness then leaves it there, it should be fine.

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v3 1/3] hmp: fix "dump-quest-memory" segfault (ppc)

2017-09-12 Thread David Gibson
On Tue, Sep 12, 2017 at 04:01:47PM +0200, Laurent Vivier wrote:
> Running QEMU with
> qemu-system-ppc64 -M none -nographic -m 256
> and executing
> dump-guest-memory /dev/null 0 8192
> results in segfault
> 
> Fix by checking if we have CPU, and exit with
> error if there is no CPU:
> 
> (qemu) dump-guest-memory /dev/null
> this feature or command is not currently supported
> 
> Signed-off-by: Laurent Vivier 

Applied to ppc-for-2.11.  I'm not really sure what to do with the rest
of the series though.

> ---
>  target/ppc/arch_dump.c | 11 +--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
> index 8e9397aa58..95b9ab6f29 100644
> --- a/target/ppc/arch_dump.c
> +++ b/target/ppc/arch_dump.c
> @@ -224,8 +224,15 @@ typedef struct NoteFuncDescStruct NoteFuncDesc;
>  int cpu_get_dump_info(ArchDumpInfo *info,
>const struct GuestPhysBlockList *guest_phys_blocks)
>  {
> -PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
> -PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
> +PowerPCCPU *cpu;
> +PowerPCCPUClass *pcc;
> +
> +if (first_cpu == NULL) {
> +return -1;
> +}
> +
> +cpu = POWERPC_CPU(first_cpu);
> +pcc = POWERPC_CPU_GET_CLASS(cpu);
>  
>  info->d_machine = PPC_ELF_MACHINE;
>  info->d_class = ELFCLASS;

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [Qemu-ppc] [RFC PATCH] tests: Add a device_add/del HMP test

2017-09-12 Thread Thomas Huth
On 12.09.2017 19:37, Eduardo Habkost wrote:
> On Mon, Sep 11, 2017 at 08:13:21AM +0200, Thomas Huth wrote:
>> On 09.09.2017 22:41, Eduardo Habkost wrote:
>>> On Wed, Sep 06, 2017 at 08:59:32AM +0200, Markus Armbruster wrote:
 Thomas Huth  writes:

> On 05.09.2017 18:48, Dr. David Alan Gilbert wrote:
>> * Markus Armbruster (arm...@redhat.com) wrote:
>>> Thomas Huth  writes:
>>>
 People tend to forget to mark internal devices with "user_creatable = 
 false
 or hotpluggable = false, and these devices can crash QEMU if added via 
 the
 HMP monitor. So let's add a test to run through all devices and that 
 tries
 to add them blindly (without arguments) to see whether this could 
 crash the
 QEMU instance.
>> [...]
>>> * The device supports only cold plug with -device, not hot plug with
>>>   device_add.
>
> We've got Eduardo's scripts/device-crash-test script for that already,
> so no need to cover that here.

 Point taken.  So this test is really about hot plug / unplug.  Suggest
 to clarify the commit message: s/add them blindly/hotplug and unplug
 them blindly/.
>>>
>>> We could extend device-crash-test to test device_add too, as it
>>> already has extra code to deal with known crashes and testing
>>> multiple machine-types.  Also, any additional code we write to
>>> ensure we add mandatory arguments or plug only to valid buses
>>> would apply to both -device and device_add.  I also think Python
>>> test code is easier to maintain and extend, but that's just my
>>> personal preference.
>>
>> Adding device_add/del support to device-crash-test is certainly an
>> option. The problem is that nobody runs it by default, so this won't
>> help to avoid that new problems are being committed to the repository.
>>
>> I think we really should have a test for "make check", too. So would my
>> test be acceptable if I'd rewrite it to use QMP instead (I don't think I
>> could do the full list that Markus mentioned, but at least a basic test
>> via QMP as a start)?
> 
> We can run device-crash-test on "make check", we just need to
> choose what's the subset of tests we want to run (because testing
> all machine+device+target combinations would take too long).

Maybe we should just run it one time for every machine - and try to add
all available devices at once?

 Thomas



Re: [Qemu-devel] [PATCH] dump: do not dump non-existent guest memory

2017-09-12 Thread Peter Xu
On Tue, Sep 12, 2017 at 12:17:51PM +0200, Marc-André Lureau wrote:
> Hi Peter
> 
> On Tue, Sep 12, 2017 at 5:33 AM, Peter Xu  wrote:
> > On Mon, Sep 11, 2017 at 03:26:27PM +0200, Cornelia Huck wrote:
> >> It does not really make sense to dump memory that is not there.
> >>
> >> Moreover, that fixes a segmentation fault when calling dump-guest-memory
> >> with no filter for a machine with no memory defined.
> >>
> >> New behaviour is:
> >>
> >> (qemu) dump-guest-memory /dev/null
> >> dump: no guest memory to dump
> >> (qemu) dump-guest-memory /dev/null 0 4096
> >> dump: no guest memory to dump
> >>
> >> Signed-off-by: Cornelia Huck 
> >> ---
> >>
> >> Another unmaintained file. Joy. cc:ing some more-or-less random folks.
> >
> > I thought Marc-André had proposed to be the maintainer? But indeed I
> > didn't see the line in maintainer file.
> >
> > Anyway, if anyone think I am ok to maintain this single file
> > (considering that I haven't posted patches on it for 2 years, and I
> > haven't been working on any kind of maintainer job), please let me
> > know. I'm glad to start with it (or with Marc-André).
> >
> 
> That would be great!
> thanks

Let me try to draft a maintainer file change for this, to see whether
there are objections.  Thanks!

-- 
Peter Xu



Re: [Qemu-devel] [Qemu-ppc] [PATCH 2/4] ppc: add CPU IRQ state to PPC VMStateDescription

2017-09-12 Thread David Gibson
On Wed, Sep 13, 2017 at 12:23:13PM +1000, Alexey Kardashevskiy wrote:
> On 13/09/17 02:46, Mark Cave-Ayland wrote:
> > On 12/09/17 17:41, Mark Cave-Ayland wrote:
> > 
> >> The commit message mentions that prior to the conversion some CPU state
> >> was missing but it doesn't mention anything about dropping existing
> >> fields as part of the conversion process so I suspect that this was an
> >> accidental side-effect.
> > 
> > Actually I've clicked send a little too early here since re-reading the
> > last paragraph of a90db15 I can see the inference here: "Exactly what
> > needs to be saved in what configurations has been more carefully
> > examined, too".
> > 
> > Alexey - do you recall from your analysis why these fields were no
> > longer deemed necessary, and how your TCG tests were configured?
> 
> I most certainly did not do analysis (my bad. sorry) - I took the patch
> from David as he left the team, fixed to compile and pushed away. I am also
> very suspicions we did not try migrating TCG or anything but pseries. My
> guest that things did not break (if they did not which I am not sure about,
> for the TCG case) because the interrupt controller (XICS) or the
> pseries-guest took care of resending an interrupt which does not seem to be
> the case for mac99.

Right, that's probably true.  The main point, though, is that these
fields were dropped a *long* time ago, when migration was barely
working to begin with.  In particular I'm pretty sure most of the
non-pseries platforms were already pretty broken for migration
(amongst other things).

Polishing the mac platforms up to working again, including migration,
is a reasonable goal.  But it can't be at the expense of pseries,
which is already working, used in production, and much better tested
than mac99 or g3beige ever were.

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


signature.asc
Description: PGP signature


[Qemu-devel] [PATCH] MAINTAINERS: add DUMP entry

2017-09-12 Thread Peter Xu
Add Marc-André Lureau and Peter Xu as dump maintainers.

CC: Marc-André Lureau 
Signed-off-by: Peter Xu 
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 36eeb42..31ede5f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1248,6 +1248,12 @@ F: docs/bitmaps.md
 T: git git://github.com/famz/qemu.git bitmaps
 T: git git://github.com/jnsnow/qemu.git bitmaps
 
+DUMP
+M: Marc-André Lureau 
+M: Peter Xu 
 M: Marc-André Lureau 
-- 
2.7.4




Re: [Qemu-devel] [PATCH v2 00/10] cleanup qemu-iotests

2017-09-12 Thread Thomas Huth
On 12.09.2017 16:44, Paolo Bonzini wrote:
> The purpose of this series is to separate the "check" sources from
> the tests.  After these patches, common.config is reduced to simple
> shell initialization, and common.rc is only included by the tests.
> 
> Along the way, a lot of dead code is removed too.
> 
> In v2, the following patches:
> 
>   qemu-iotests: do not do useless search for QEMU_*_PROG
>   qemu-iotests: do not search for binaries in the current directory
>   qemu-iotests: include common.env and common.config early
> 
> have been replaced by "qemu-iotests: cleanup and fix search for programs",
> which also preserves the behavior of searching for programs as symlinks
> in the current directory.
> 
> Paolo
> 
> Paolo Bonzini (10):
>   qemu-iotests: remove dead code
>   qemu-iotests: get rid of AWK_PROG
>   qemu-iotests: move "check" code out of common.rc
>   qemu-iotests: cleanup and fix search for programs
>   qemu-iotests: limit non-_PROG-suffixed variables to common.rc
>   qemu-iotests: do not include common.rc in "check"
>   qemu-iotests: disintegrate more parts of common.config
>   qemu-iotests: fix uninitialized variable
>   qemu-iotests: get rid of $iam
>   qemu-iotests: merge "check" and "common"
> 
>  tests/qemu-iotests/039.out   |  10 +-
>  tests/qemu-iotests/061.out   |   4 +-
>  tests/qemu-iotests/137.out   |   2 +-
>  tests/qemu-iotests/check | 575 
> ++-
>  tests/qemu-iotests/common| 459 ---
>  tests/qemu-iotests/common.config | 206 +-
>  tests/qemu-iotests/common.qemu   |   1 +
>  tests/qemu-iotests/common.rc | 205 +++---

Meta comment: Could we maybe also rename "tests/qemu-iotests" to
"tests/iotests" ? The "qemu" prefix sounds always very superfluous to me
here...

 Thomas



<    1   2   3   4