[PATCH v4 18/30] qcow2: Add subcluster support to qcow2_get_host_offset()

2020-03-17 Thread Alberto Garcia
The logic of this function remains pretty much the same, except that
it uses count_contiguous_subclusters(), which combines the logic of
count_contiguous_clusters() / count_contiguous_clusters_unallocated()
and checks individual subclusters.

Signed-off-by: Alberto Garcia 
---
 block/qcow2.h |  38 +--
 block/qcow2-cluster.c | 143 +-
 2 files changed, 85 insertions(+), 96 deletions(-)

diff --git a/block/qcow2.h b/block/qcow2.h
index e6fbb7d987..031ce823b3 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -678,29 +678,6 @@ static inline QCow2ClusterType 
qcow2_get_cluster_type(BlockDriverState *bs,
 }
 }
 
-/*
- * For an image without extended L2 entries, return the
- * QCow2SubclusterType equivalent of a given QCow2ClusterType.
- */
-static inline
-QCow2SubclusterType qcow2_cluster_to_subcluster_type(QCow2ClusterType type)
-{
-switch (type) {
-case QCOW2_CLUSTER_COMPRESSED:
-return QCOW2_SUBCLUSTER_COMPRESSED;
-case QCOW2_CLUSTER_ZERO_PLAIN:
-return QCOW2_SUBCLUSTER_ZERO_PLAIN;
-case QCOW2_CLUSTER_ZERO_ALLOC:
-return QCOW2_SUBCLUSTER_ZERO_ALLOC;
-case QCOW2_CLUSTER_NORMAL:
-return QCOW2_SUBCLUSTER_NORMAL;
-case QCOW2_CLUSTER_UNALLOCATED:
-return QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN;
-default:
-g_assert_not_reached();
-}
-}
-
 /*
  * In an image without subsclusters @l2_bitmap is ignored and
  * @sc_index must be 0.
@@ -748,7 +725,20 @@ QCow2SubclusterType 
qcow2_get_subcluster_type(BlockDriverState *bs,
 g_assert_not_reached();
 }
 } else {
-return qcow2_cluster_to_subcluster_type(type);
+switch (type) {
+case QCOW2_CLUSTER_COMPRESSED:
+return QCOW2_SUBCLUSTER_COMPRESSED;
+case QCOW2_CLUSTER_ZERO_PLAIN:
+return QCOW2_SUBCLUSTER_ZERO_PLAIN;
+case QCOW2_CLUSTER_ZERO_ALLOC:
+return QCOW2_SUBCLUSTER_ZERO_ALLOC;
+case QCOW2_CLUSTER_NORMAL:
+return QCOW2_SUBCLUSTER_NORMAL;
+case QCOW2_CLUSTER_UNALLOCATED:
+return QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN;
+default:
+g_assert_not_reached();
+}
 }
 }
 
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index c6f3cc9237..6f2643ba53 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -376,66 +376,58 @@ fail:
 }
 
 /*
- * Checks how many clusters in a given L2 slice are contiguous in the image
- * file. As soon as one of the flags in the bitmask stop_flags changes compared
- * to the first cluster, the search is stopped and the cluster is not counted
- * as contiguous. (This allows it, for example, to stop at the first compressed
- * cluster which may require a different handling)
+ * Return the number of contiguous subclusters of the exact same type
+ * in a given L2 slice, starting from cluster @l2_index, subcluster
+ * @sc_index. Allocated subclusters are required to be contiguous in
+ * the image file.
+ * At most @nb_clusters are checked (note that this means clusters,
+ * not subclusters).
+ * Compressed clusters are always processed one by one but for the
+ * purpose of this count they are treated as if they were divided into
+ * subclusters of size s->subcluster_size.
  */
-static int count_contiguous_clusters(BlockDriverState *bs, int nb_clusters,
-int cluster_size, uint64_t *l2_slice, int l2_index, uint64_t 
stop_flags)
+static int count_contiguous_subclusters(BlockDriverState *bs, int nb_clusters,
+unsigned sc_index, uint64_t *l2_slice,
+int l2_index)
 {
 BDRVQcow2State *s = bs->opaque;
-int i;
-QCow2ClusterType first_cluster_type;
-uint64_t mask = stop_flags | L2E_OFFSET_MASK | QCOW_OFLAG_COMPRESSED;
-uint64_t first_entry = get_l2_entry(s, l2_slice, l2_index);
-uint64_t offset = first_entry & mask;
-
-first_cluster_type = qcow2_get_cluster_type(bs, first_entry);
-if (first_cluster_type == QCOW2_CLUSTER_UNALLOCATED) {
-return 0;
+int i, j, count = 0;
+uint64_t l2_entry = get_l2_entry(s, l2_slice, l2_index);
+uint64_t l2_bitmap = get_l2_bitmap(s, l2_slice, l2_index);
+uint64_t expected_offset = l2_entry & L2E_OFFSET_MASK;
+bool check_offset = true;
+QCow2SubclusterType type =
+qcow2_get_subcluster_type(bs, l2_entry, l2_bitmap, sc_index);
+
+assert(type != QCOW2_SUBCLUSTER_INVALID); /* The caller should check this 
*/
+
+if (type == QCOW2_SUBCLUSTER_COMPRESSED) {
+/* Compressed clusters are always processed one by one */
+return s->subclusters_per_cluster - sc_index;
 }
 
-/* must be allocated */
-assert(first_cluster_type == QCOW2_CLUSTER_NORMAL ||
-   first_cluster_type == QCOW2_CLUSTER_ZERO_ALLOC);
-
-for (i = 0; i < nb_clusters; i++) {
-uint64_t l2_entry = get_l2_entry(s, l2_slice, l2_index + i) & mask;
-if (offset 

[PATCH v4 20/30] qcow2: Add subcluster support to discard_in_l2_slice()

2020-03-17 Thread Alberto Garcia
Two changes are needed in this function:

1) A full discard deallocates a cluster so we can skip the operation if
   it is already unallocated. With extended L2 entries however if any
   of the subclusters has the 'all zeroes' bit set then we have to
   clear it.

2) Setting the QCOW_OFLAG_ZERO bit of the L2 entry is forbidden if an
   image has extended L2 entries. Instead, the individual 'all zeroes'
   bits must be used.

Signed-off-by: Alberto Garcia 
---
 block/qcow2-cluster.c | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 746006a117..824c710760 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1790,12 +1790,20 @@ static int discard_in_l2_slice(BlockDriverState *bs, 
uint64_t offset,
  * TODO We might want to use bdrv_block_status(bs) here, but we're
  * holding s->lock, so that doesn't work today.
  *
- * If full_discard is true, the sector should not read back as zeroes,
+ * If full_discard is true, the cluster should not read back as zeroes,
  * but rather fall through to the backing file.
  */
 switch (qcow2_get_cluster_type(bs, old_l2_entry)) {
 case QCOW2_CLUSTER_UNALLOCATED:
-if (full_discard || !bs->backing) {
+if (full_discard) {
+/* If the image has extended L2 entries we can only
+ * skip this operation if the L2 bitmap is zero. */
+uint64_t bitmap = has_subclusters(s) ?
+get_l2_bitmap(s, l2_slice, l2_index + i) : 0;
+if (bitmap == 0) {
+continue;
+}
+} else if (!bs->backing) {
 continue;
 }
 break;
@@ -1817,7 +1825,11 @@ static int discard_in_l2_slice(BlockDriverState *bs, 
uint64_t offset,
 
 /* First remove L2 entries */
 qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_slice);
-if (!full_discard && s->qcow_version >= 3) {
+if (has_subclusters(s)) {
+set_l2_entry(s, l2_slice, l2_index + i, 0);
+set_l2_bitmap(s, l2_slice, l2_index + i,
+  full_discard ? 0 : QCOW_L2_BITMAP_ALL_ZEROES);
+} else if (!full_discard && s->qcow_version >= 3) {
 set_l2_entry(s, l2_slice, l2_index + i, QCOW_OFLAG_ZERO);
 } else {
 set_l2_entry(s, l2_slice, l2_index + i, 0);
-- 
2.20.1




[PATCH v4 08/30] qcow2: Add dummy has_subclusters() function

2020-03-17 Thread Alberto Garcia
This function will be used by the qcow2 code to check if an image has
subclusters or not.

At the moment this simply returns false. Once all patches needed for
subcluster support are ready then QEMU will be able to create and
read images with subclusters and this function will return the actual
value.

Signed-off-by: Alberto Garcia 
Reviewed-by: Eric Blake 
Reviewed-by: Max Reitz 
---
 block/qcow2.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/block/qcow2.h b/block/qcow2.h
index 7754d9bd02..55298750bd 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -495,6 +495,12 @@ typedef enum QCow2MetadataOverlap {
 
 #define INV_OFFSET (-1ULL)
 
+static inline bool has_subclusters(BDRVQcow2State *s)
+{
+/* FIXME: Return false until this feature is complete */
+return false;
+}
+
 static inline uint64_t get_l2_entry(BDRVQcow2State *s, uint64_t *l2_slice,
 int idx)
 {
-- 
2.20.1




[PATCH v4 22/30] qcow2: Fix offset calculation in handle_dependencies()

2020-03-17 Thread Alberto Garcia
l2meta_cow_start() and l2meta_cow_end() are not necessarily
cluster-aligned if the image has subclusters, so update the
calculation of old_start and old_end to guarantee that no two requests
try to write on the same cluster.

Signed-off-by: Alberto Garcia 
Reviewed-by: Max Reitz 
---
 block/qcow2-cluster.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 824c710760..ceacd91ea3 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1306,8 +1306,8 @@ static int handle_dependencies(BlockDriverState *bs, 
uint64_t guest_offset,
 
 uint64_t start = guest_offset;
 uint64_t end = start + bytes;
-uint64_t old_start = l2meta_cow_start(old_alloc);
-uint64_t old_end = l2meta_cow_end(old_alloc);
+uint64_t old_start = start_of_cluster(s, l2meta_cow_start(old_alloc));
+uint64_t old_end = ROUND_UP(l2meta_cow_end(old_alloc), 
s->cluster_size);
 
 if (end <= old_start || start >= old_end) {
 /* No intersection */
-- 
2.20.1




[PATCH v4 12/30] qcow2: Update get/set_l2_entry() and add get/set_l2_bitmap()

2020-03-17 Thread Alberto Garcia
Extended L2 entries are 128-bit wide: 64 bits for the entry itself and
64 bits for the subcluster allocation bitmap.

In order to support them correctly get/set_l2_entry() need to be
updated so they take the entry width into account in order to
calculate the correct offset.

This patch also adds the get/set_l2_bitmap() functions that are
used to access the bitmaps. For convenience we allow calling
get_l2_bitmap() on images without subclusters, although the caller
does not need and should ignore the returned value.

Signed-off-by: Alberto Garcia 
Reviewed-by: Max Reitz 
---
 block/qcow2.h | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/block/qcow2.h b/block/qcow2.h
index 1eb4b46807..9611efbc52 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -518,15 +518,37 @@ static inline size_t l2_entry_size(BDRVQcow2State *s)
 static inline uint64_t get_l2_entry(BDRVQcow2State *s, uint64_t *l2_slice,
 int idx)
 {
+idx *= l2_entry_size(s) / sizeof(uint64_t);
 return be64_to_cpu(l2_slice[idx]);
 }
 
+static inline uint64_t get_l2_bitmap(BDRVQcow2State *s, uint64_t *l2_slice,
+ int idx)
+{
+if (has_subclusters(s)) {
+idx *= l2_entry_size(s) / sizeof(uint64_t);
+return be64_to_cpu(l2_slice[idx + 1]);
+} else {
+/* For convenience only; the caller should ignore this value. */
+return 0;
+}
+}
+
 static inline void set_l2_entry(BDRVQcow2State *s, uint64_t *l2_slice,
 int idx, uint64_t entry)
 {
+idx *= l2_entry_size(s) / sizeof(uint64_t);
 l2_slice[idx] = cpu_to_be64(entry);
 }
 
+static inline void set_l2_bitmap(BDRVQcow2State *s, uint64_t *l2_slice,
+ int idx, uint64_t bitmap)
+{
+assert(has_subclusters(s));
+idx *= l2_entry_size(s) / sizeof(uint64_t);
+l2_slice[idx + 1] = cpu_to_be64(bitmap);
+}
+
 static inline bool has_data_file(BlockDriverState *bs)
 {
 BDRVQcow2State *s = bs->opaque;
-- 
2.20.1




[PATCH v4 05/30] qcow2: Process QCOW2_CLUSTER_ZERO_ALLOC clusters in handle_copied()

2020-03-17 Thread Alberto Garcia
When writing to a qcow2 file there are two functions that take a
virtual offset and return a host offset, possibly allocating new
clusters if necessary:

   - handle_copied() looks for normal data clusters that are already
 allocated and have a reference count of 1. In those clusters we
 can simply write the data and there is no need to perform any
 copy-on-write.

   - handle_alloc() looks for clusters that do need copy-on-write,
 either because they haven't been allocated yet, because their
 reference count is != 1 or because they are ZERO_ALLOC clusters.

The ZERO_ALLOC case is a bit special because those are clusters that
are already allocated and they could perfectly be dealt with in
handle_copied() (as long as copy-on-write is performed when required).

In fact, there is extra code specifically for them in handle_alloc()
that tries to reuse the existing allocation if possible and frees them
otherwise.

This patch changes the handling of ZERO_ALLOC clusters so the
semantics of these two functions are now like this:

   - handle_copied() looks for clusters that are already allocated and
 which we can overwrite (NORMAL and ZERO_ALLOC clusters with a
 reference count of 1).

   - handle_alloc() looks for clusters for which we need a new
 allocation (all other cases).

One important difference after this change is that clusters found
in handle_copied() may now require copy-on-write, but this will be
necessary anyway once we add support for subclusters.

Signed-off-by: Alberto Garcia 
Reviewed-by: Eric Blake 
Reviewed-by: Max Reitz 
---
 block/qcow2-cluster.c | 230 --
 1 file changed, 130 insertions(+), 100 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index e251d00890..5c81046c34 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1041,13 +1041,18 @@ void qcow2_alloc_cluster_abort(BlockDriverState *bs, 
QCowL2Meta *m)
 
 /*
  * For a given write request, create a new QCowL2Meta structure, add
- * it to @m and the BDRVQcow2State.cluster_allocs list.
+ * it to @m and the BDRVQcow2State.cluster_allocs list. If the write
+ * request does not need copy-on-write or changes to the L2 metadata
+ * then this function does nothing.
  *
  * @host_cluster_offset points to the beginning of the first cluster.
  *
  * @guest_offset and @bytes indicate the offset and length of the
  * request.
  *
+ * @l2_slice contains the L2 entries of all clusters involved in this
+ * write request.
+ *
  * If @keep_old is true it means that the clusters were already
  * allocated and will be overwritten. If false then the clusters are
  * new and we have to decrease the reference count of the old ones.
@@ -1055,15 +1060,53 @@ void qcow2_alloc_cluster_abort(BlockDriverState *bs, 
QCowL2Meta *m)
 static void calculate_l2_meta(BlockDriverState *bs,
   uint64_t host_cluster_offset,
   uint64_t guest_offset, unsigned bytes,
-  QCowL2Meta **m, bool keep_old)
+  uint64_t *l2_slice, QCowL2Meta **m, bool 
keep_old)
 {
 BDRVQcow2State *s = bs->opaque;
-unsigned cow_start_from = 0;
+int l2_index = offset_to_l2_slice_index(s, guest_offset);
+uint64_t l2_entry;
+unsigned cow_start_from, cow_end_to;
 unsigned cow_start_to = offset_into_cluster(s, guest_offset);
 unsigned cow_end_from = cow_start_to + bytes;
-unsigned cow_end_to = ROUND_UP(cow_end_from, s->cluster_size);
 unsigned nb_clusters = size_to_clusters(s, cow_end_from);
 QCowL2Meta *old_m = *m;
+QCow2ClusterType type;
+
+assert(nb_clusters <= s->l2_slice_size - l2_index);
+
+/* Return if there's no COW (all clusters are normal and we keep them) */
+if (keep_old) {
+int i;
+for (i = 0; i < nb_clusters; i++) {
+l2_entry = be64_to_cpu(l2_slice[l2_index + i]);
+if (qcow2_get_cluster_type(bs, l2_entry) != QCOW2_CLUSTER_NORMAL) {
+break;
+}
+}
+if (i == nb_clusters) {
+return;
+}
+}
+
+/* Get the L2 entry of the first cluster */
+l2_entry = be64_to_cpu(l2_slice[l2_index]);
+type = qcow2_get_cluster_type(bs, l2_entry);
+
+if (type == QCOW2_CLUSTER_NORMAL && keep_old) {
+cow_start_from = cow_start_to;
+} else {
+cow_start_from = 0;
+}
+
+/* Get the L2 entry of the last cluster */
+l2_entry = be64_to_cpu(l2_slice[l2_index + nb_clusters - 1]);
+type = qcow2_get_cluster_type(bs, l2_entry);
+
+if (type == QCOW2_CLUSTER_NORMAL && keep_old) {
+cow_end_to = cow_end_from;
+} else {
+cow_end_to = ROUND_UP(cow_end_from, s->cluster_size);
+}
 
 *m = g_malloc0(sizeof(**m));
 **m = (QCowL2Meta) {
@@ -1089,18 +1132,22 @@ static void calculate_l2_meta(BlockDriverState *bs,
 QLIST_INSERT_HEAD(>cluster_allocs, *m, next_in_flight);
 }
 
-/* 

[PATCH v4 16/30] qcow2: Handle QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC

2020-03-17 Thread Alberto Garcia
When dealing with subcluster types there is a new value called
QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC that has no equivalent in
QCow2ClusterType.

This patch handles that value in all places where subcluster types
are processed.

Signed-off-by: Alberto Garcia 
Reviewed-by: Max Reitz 
---
 block/qcow2.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index f8788d6305..88daaf11a0 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1992,7 +1992,8 @@ static int coroutine_fn 
qcow2_co_block_status(BlockDriverState *bs,
 *pnum = bytes;
 
 if ((type == QCOW2_SUBCLUSTER_NORMAL ||
- type == QCOW2_SUBCLUSTER_ZERO_ALLOC) && !s->crypto) {
+ type == QCOW2_SUBCLUSTER_ZERO_ALLOC ||
+ type == QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC) && !s->crypto) {
 *map = host_offset;
 *file = s->data_file->bs;
 status |= BDRV_BLOCK_OFFSET_VALID;
@@ -2000,7 +2001,8 @@ static int coroutine_fn 
qcow2_co_block_status(BlockDriverState *bs,
 if (type == QCOW2_SUBCLUSTER_ZERO_PLAIN ||
 type == QCOW2_SUBCLUSTER_ZERO_ALLOC) {
 status |= BDRV_BLOCK_ZERO;
-} else if (type != QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN) {
+} else if (type != QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN &&
+   type != QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC) {
 status |= BDRV_BLOCK_DATA;
 }
 if (s->metadata_preallocation && (status & BDRV_BLOCK_DATA) &&
@@ -2163,6 +2165,7 @@ static coroutine_fn int 
qcow2_co_preadv_task(BlockDriverState *bs,
 g_assert_not_reached();
 
 case QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN:
+case QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC:
 assert(bs->backing); /* otherwise handled in qcow2_co_preadv_part */
 
 BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
@@ -2231,7 +2234,8 @@ static coroutine_fn int 
qcow2_co_preadv_part(BlockDriverState *bs,
 
 if (type == QCOW2_SUBCLUSTER_ZERO_PLAIN ||
 type == QCOW2_SUBCLUSTER_ZERO_ALLOC ||
-(type == QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN && !bs->backing))
+(type == QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN && !bs->backing) ||
+(type == QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC && !bs->backing))
 {
 qemu_iovec_memset(qiov, qiov_offset, 0, cur_bytes);
 } else {
@@ -3740,6 +3744,7 @@ static coroutine_fn int 
qcow2_co_pwrite_zeroes(BlockDriverState *bs,
 ret = qcow2_get_host_offset(bs, offset, , , );
 if (ret < 0 ||
 (type != QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN &&
+ type != QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC &&
  type != QCOW2_SUBCLUSTER_ZERO_PLAIN &&
  type != QCOW2_SUBCLUSTER_ZERO_ALLOC)) {
 qemu_co_mutex_unlock(>lock);
@@ -3812,6 +3817,7 @@ qcow2_co_copy_range_from(BlockDriverState *bs,
 
 switch (type) {
 case QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN:
+case QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC:
 if (bs->backing && bs->backing->bs) {
 int64_t backing_length = bdrv_getlength(bs->backing->bs);
 if (src_offset >= backing_length) {
-- 
2.20.1




[PATCH v4 15/30] qcow2: Replace QCOW2_CLUSTER_* with QCOW2_SUBCLUSTER_*

2020-03-17 Thread Alberto Garcia
In order to support extended L2 entries some functions of the qcow2
driver need to start dealing with subclusters instead of clusters.

qcow2_get_host_offset() is modified to return the subcluster type
instead of the cluster type, and all callers are updated to replace
all values of QCow2ClusterType with their QCow2SubclusterType
equivalents.

This patch only changes the data types, there are no semantic changes.

Signed-off-by: Alberto Garcia 
---
 block/qcow2.h |  2 +-
 block/qcow2-cluster.c | 10 +++
 block/qcow2.c | 70 ++-
 3 files changed, 42 insertions(+), 40 deletions(-)

diff --git a/block/qcow2.h b/block/qcow2.h
index 6b7b286b91..e6fbb7d987 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -860,7 +860,7 @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t 
sector_num,
 
 int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,
   unsigned int *bytes, uint64_t *host_offset,
-  QCow2ClusterType *cluster_type);
+  QCow2SubclusterType *subcluster_type);
 int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
unsigned int *bytes, uint64_t *host_offset,
QCowL2Meta **m);
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index acfcf8ea4c..8cdf8a23b6 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -513,15 +513,15 @@ static int coroutine_fn 
do_perform_cow_write(BlockDriverState *bs,
  * offset that we are interested in.
  *
  * On exit, *bytes is the number of bytes starting at offset that have the same
- * cluster type and (if applicable) are stored contiguously in the image file.
- * The cluster type is stored in *cluster_type.
- * Compressed clusters are always returned one by one.
+ * subcluster type and (if applicable) are stored contiguously in the image
+ * file. The subcluster type is stored in *subcluster_type.
+ * Compressed clusters are always processed one by one.
  *
  * Returns 0 on success, -errno in error cases.
  */
 int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,
   unsigned int *bytes, uint64_t *host_offset,
-  QCow2ClusterType *cluster_type)
+  QCow2SubclusterType *subcluster_type)
 {
 BDRVQcow2State *s = bs->opaque;
 unsigned int l2_index;
@@ -664,7 +664,7 @@ out:
 assert(bytes_available - offset_in_cluster <= UINT_MAX);
 *bytes = bytes_available - offset_in_cluster;
 
-*cluster_type = type;
+*subcluster_type = qcow2_cluster_to_subcluster_type(type);
 
 return 0;
 
diff --git a/block/qcow2.c b/block/qcow2.c
index 48e188152c..f8788d6305 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1971,7 +1971,7 @@ static int coroutine_fn 
qcow2_co_block_status(BlockDriverState *bs,
 BDRVQcow2State *s = bs->opaque;
 uint64_t host_offset;
 unsigned int bytes;
-QCow2ClusterType type;
+QCow2SubclusterType type;
 int ret, status = 0;
 
 qemu_co_mutex_lock(>lock);
@@ -1991,15 +1991,16 @@ static int coroutine_fn 
qcow2_co_block_status(BlockDriverState *bs,
 
 *pnum = bytes;
 
-if ((type == QCOW2_CLUSTER_NORMAL || type == QCOW2_CLUSTER_ZERO_ALLOC) &&
-!s->crypto) {
+if ((type == QCOW2_SUBCLUSTER_NORMAL ||
+ type == QCOW2_SUBCLUSTER_ZERO_ALLOC) && !s->crypto) {
 *map = host_offset;
 *file = s->data_file->bs;
 status |= BDRV_BLOCK_OFFSET_VALID;
 }
-if (type == QCOW2_CLUSTER_ZERO_PLAIN || type == QCOW2_CLUSTER_ZERO_ALLOC) {
+if (type == QCOW2_SUBCLUSTER_ZERO_PLAIN ||
+type == QCOW2_SUBCLUSTER_ZERO_ALLOC) {
 status |= BDRV_BLOCK_ZERO;
-} else if (type != QCOW2_CLUSTER_UNALLOCATED) {
+} else if (type != QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN) {
 status |= BDRV_BLOCK_DATA;
 }
 if (s->metadata_preallocation && (status & BDRV_BLOCK_DATA) &&
@@ -2096,7 +2097,7 @@ typedef struct Qcow2AioTask {
 AioTask task;
 
 BlockDriverState *bs;
-QCow2ClusterType cluster_type; /* only for read */
+QCow2SubclusterType subcluster_type; /* only for read */
 uint64_t host_offset; /* or full descriptor in compressed clusters */
 uint64_t offset;
 uint64_t bytes;
@@ -2109,7 +2110,7 @@ static coroutine_fn int 
qcow2_co_preadv_task_entry(AioTask *task);
 static coroutine_fn int qcow2_add_task(BlockDriverState *bs,
AioTaskPool *pool,
AioTaskFunc func,
-   QCow2ClusterType cluster_type,
+   QCow2SubclusterType subcluster_type,
uint64_t host_offset,
uint64_t offset,
uint64_t bytes,
@@ -2123,7 +2124,7 @@ static coroutine_fn int qcow2_add_task(BlockDriverState 

[PATCH v2] slirp: update submodule to v4.2.0 + mingw-fix

2020-03-17 Thread Marc-André Lureau
git shortlog
126c04acbabd7ad32c2b018fe10dfac2a3bc1210..7012a2c62e5b54eab88c119383022ec7ce86e9b2

5eraph (1):
  Use specific outbound IP address

Akihiro Suda (8):
  remove confusing comment that exists from ancient slirp
  add slirp_new(SlirpConfig *, SlirpCb *, void *)
  allow custom MTU
  add disable_host_loopback (prohibit connections to 127.0.0.1)
  add SlirpConfig version
  emu: remove dead code
  emu: disable by default
  fix a typo in a comment

Anders Waldenborg (1):
  state: fix loading of guestfwd state

Giuseppe Scrivano (1):
  socket: avoid getpeername after shutdown(SHUT_WR)

Jindrich Novy (1):
  Don't leak memory when reallocation fails.

Jordi Pujol Palomer (1):
  fork_exec: correctly parse command lines that contain spaces

Marc-André Lureau (54):
  Merge branch 'AkihiroSuda/libslirp-slirp4netns'
  Merge branch 'fix-typo' into 'master'
  meson: make it subproject friendly
  Merge branch 'meson' into 'master'
  misc: fix compilation warnings
  Merge branch 'fix-shutdown-wr' into 'master'
  sbuf: remove unused and undefined sbcopy() path
  sbuf: check more strictly sbcopy() bounds with offset
  sbuf: replace a comment with a runtime warning
  Replace remaining malloc/free user with glib
  tcp_attach() can no longer fail
  state: can't ENOMEM
  sbuf: use unsigned types
  sbuf: simplify sbreserve()
  dnssearch: use g_strv_length()
  vmstate: silence scan-build warning
  gitlab-ci: run scan-build
  Merge branch 'mem-cleanups' into 'master'
  libslirp.map: bind slirp_new to SLIRP_4.1 version
  meson: fix libtool versioning
  Release v4.1.0
  Merge branch '4.1.0' into 'master'
  CHANGELOG: start unreleased section
  Merge branch 'add-unix' into 'master'
  util: add G_SIZEOF_MEMBER() macro
  Check bootp_filename is not going to be truncated
  bootp: remove extra cast
  bootp: replace simple snprintf() with strcpy()
  tftp: clarify what is actually OACK m_len
  tcp_emu: add more fixme/warnings comments
  util: add slirp_fmt() helpers
  dhcpv6: use slirp_fmt()
  misc: use slirp_fmt0()
  tftp: use slirp_fmt0()
  tcp_ctl: use slirp_fmt()
  tcp_emu: fix unsafe snprintf() usages
  misc: improve error report
  Use g_snprintf()
  util: add gnuc format function attribute to slirp_fmt*
  Merge branch 'aw-guestfwd-state' into 'master'
  Merge branch 'slirp-fmt' into 'master'
  socket: remove extra label and variable
  socket: factor out sotranslate ipv4/ipv6 handling
  socket: remove need for extra scope_id variable
  socket: do not fallback on host loopback if get_dns_addr() failed
  socket: do not fallback on loopback addr for addresses in our mask/prefix
  Prepare for v4.2.0 release
  Merge branch 'translate-fix' into 'master'
  Merge branch 'release-v4.2.0' into 'master'
  changelog: post-release
  changelog: fix link
  .gitlab-ci: add --werror, treat CI build warnings as errors
  Revert "socket: remove need for extra scope_id variable"
  Merge branch 'mingw-fix' into 'master'

PanNengyuan (1):
  libslirp: fix NULL pointer dereference in tcp_sockclosed

Philippe Mathieu-Daudé (1):
  Add a git-publish configuration file

Prasad J Pandit (4):
  slirp: ncsi: compute checksum for valid data length
  slirp: use correct size while emulating IRC commands
  slirp: use correct size while emulating commands
  slirp: tftp: restrict relative path access

Renzo Davoli (2):
  Add slirp_remove_guestfwd()
  Add slirp_add_unix()

Samuel Thibault (14):
  ip_reass: explain why we should not always update the q pointer
  Merge branch 'comment' into 'master'
  Merge branch 'no-emu' into 'master'
  Fix bogus indent, no source change
  ip_reass: Fix use after free
  Merge branch 'reass2' into 'master'
  Make host receive broadcast packets
  arp: Allow 0.0.0.0 destination address
  Merge branch 'warnings' into 'master'
  Merge branch 'arp_0' into 'master'
  Merge branch 'broadcast' into 'master'
  tcp_emu: Fix oob access
  Merge branch 'oob' into 'master'
  Merge branch 'master' into 'master'

Cc: Samuel Thibault 
Signed-off-by: Marc-André Lureau 
---
 slirp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/slirp b/slirp
index 126c04acba..7012a2c62e 16
--- a/slirp
+++ b/slirp
@@ -1 +1 @@
-Subproject commit 126c04acbabd7ad32c2b018fe10dfac2a3bc1210
+Subproject commit 7012a2c62e5b54eab88c119383022ec7ce86e9b2
-- 
2.25.0.rc2.1.g09a9a1a997




[PATCH v4 02/30] qcow2: Convert qcow2_get_cluster_offset() into qcow2_get_host_offset()

2020-03-17 Thread Alberto Garcia
qcow2_get_cluster_offset() takes an (unaligned) guest offset and
returns the (aligned) offset of the corresponding cluster in the qcow2
image.

In practice none of the callers need to know where the cluster starts
so this patch makes the function calculate and return the final host
offset directly. The function is also renamed accordingly.

There is a pre-existing exception with compressed clusters: in this
case the function returns the complete cluster descriptor (containing
the offset and size of the compressed data). This does not change with
this patch but it is now documented.

Signed-off-by: Alberto Garcia 
---
 block/qcow2.h |  4 ++--
 block/qcow2-cluster.c | 38 ++
 block/qcow2.c | 24 +++-
 3 files changed, 31 insertions(+), 35 deletions(-)

diff --git a/block/qcow2.h b/block/qcow2.h
index 0942126232..f47ef6ca4e 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -679,8 +679,8 @@ int qcow2_write_l1_entry(BlockDriverState *bs, int 
l1_index);
 int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
   uint8_t *buf, int nb_sectors, bool enc, Error 
**errp);
 
-int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
- unsigned int *bytes, uint64_t *cluster_offset);
+int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,
+  unsigned int *bytes, uint64_t *host_offset);
 int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
unsigned int *bytes, uint64_t *host_offset,
QCowL2Meta **m);
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 17f1363279..95f04d12cc 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -496,10 +496,15 @@ static int coroutine_fn 
do_perform_cow_write(BlockDriverState *bs,
 
 
 /*
- * get_cluster_offset
+ * get_host_offset
  *
- * For a given offset of the virtual disk, find the cluster type and offset in
- * the qcow2 file. The offset is stored in *cluster_offset.
+ * For a given offset of the virtual disk find the equivalent host
+ * offset in the qcow2 file and store it in *host_offset. Neither
+ * offset needs to be aligned to a cluster boundary.
+ *
+ * If the cluster is unallocated then *host_offset will be 0.
+ * If the cluster is compressed then *host_offset will contain the
+ * complete compressed cluster descriptor.
  *
  * On entry, *bytes is the maximum number of contiguous bytes starting at
  * offset that we are interested in.
@@ -511,12 +516,12 @@ static int coroutine_fn 
do_perform_cow_write(BlockDriverState *bs,
  * Returns the cluster type (QCOW2_CLUSTER_*) on success, -errno in error
  * cases.
  */
-int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
- unsigned int *bytes, uint64_t *cluster_offset)
+int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,
+  unsigned int *bytes, uint64_t *host_offset)
 {
 BDRVQcow2State *s = bs->opaque;
 unsigned int l2_index;
-uint64_t l1_index, l2_offset, *l2_slice;
+uint64_t l1_index, l2_offset, *l2_slice, l2_entry;
 int c;
 unsigned int offset_in_cluster;
 uint64_t bytes_available, bytes_needed, nb_clusters;
@@ -537,7 +542,7 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t 
offset,
 bytes_needed = bytes_available;
 }
 
-*cluster_offset = 0;
+*host_offset = 0;
 
 /* seek to the l2 offset in the l1 table */
 
@@ -570,7 +575,7 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t 
offset,
 /* find the cluster offset for the given disk offset */
 
 l2_index = offset_to_l2_slice_index(s, offset);
-*cluster_offset = be64_to_cpu(l2_slice[l2_index]);
+l2_entry = be64_to_cpu(l2_slice[l2_index]);
 
 nb_clusters = size_to_clusters(s, bytes_needed);
 /* bytes_needed <= *bytes + offset_in_cluster, both of which are unsigned
@@ -578,7 +583,7 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t 
offset,
  * true */
 assert(nb_clusters <= INT_MAX);
 
-type = qcow2_get_cluster_type(bs, *cluster_offset);
+type = qcow2_get_cluster_type(bs, l2_entry);
 if (s->qcow_version < 3 && (type == QCOW2_CLUSTER_ZERO_PLAIN ||
 type == QCOW2_CLUSTER_ZERO_ALLOC)) {
 qcow2_signal_corruption(bs, true, -1, -1, "Zero cluster entry found"
@@ -599,41 +604,42 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, 
uint64_t offset,
 }
 /* Compressed clusters can only be processed one by one */
 c = 1;
-*cluster_offset &= L2E_COMPRESSED_OFFSET_SIZE_MASK;
+*host_offset = l2_entry & L2E_COMPRESSED_OFFSET_SIZE_MASK;
 break;
 case QCOW2_CLUSTER_ZERO_PLAIN:
 case QCOW2_CLUSTER_UNALLOCATED:
 /* how many empty clusters ? */
 c = count_contiguous_clusters_unallocated(bs, nb_clusters,

[PATCH v4 29/30] qcow2: Add subcluster support to qcow2_measure()

2020-03-17 Thread Alberto Garcia
Extended L2 entries are bigger than normal L2 entries so this has an
impact on the amount of metadata needed for a qcow2 file.

Signed-off-by: Alberto Garcia 
Reviewed-by: Max Reitz 
---
 block/qcow2.c | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 77b2713533..aefac85b23 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3154,28 +3154,31 @@ int64_t qcow2_refcount_metadata_size(int64_t clusters, 
size_t cluster_size,
  * @total_size: virtual disk size in bytes
  * @cluster_size: cluster size in bytes
  * @refcount_order: refcount bits power-of-2 exponent
+ * @extended_l2: true if the image has extended L2 entries
  *
  * Returns: Total number of bytes required for the fully allocated image
  * (including metadata).
  */
 static int64_t qcow2_calc_prealloc_size(int64_t total_size,
 size_t cluster_size,
-int refcount_order)
+int refcount_order,
+bool extended_l2)
 {
 int64_t meta_size = 0;
 uint64_t nl1e, nl2e;
 int64_t aligned_total_size = ROUND_UP(total_size, cluster_size);
+size_t l2e_size = extended_l2 ? L2E_SIZE_EXTENDED : L2E_SIZE_NORMAL;
 
 /* header: 1 cluster */
 meta_size += cluster_size;
 
 /* total size of L2 tables */
 nl2e = aligned_total_size / cluster_size;
-nl2e = ROUND_UP(nl2e, cluster_size / sizeof(uint64_t));
-meta_size += nl2e * sizeof(uint64_t);
+nl2e = ROUND_UP(nl2e, cluster_size / l2e_size);
+meta_size += nl2e * l2e_size;
 
 /* total size of L1 tables */
-nl1e = nl2e * sizeof(uint64_t) / cluster_size;
+nl1e = nl2e * l2e_size / cluster_size;
 nl1e = ROUND_UP(nl1e, cluster_size / sizeof(uint64_t));
 meta_size += nl1e * sizeof(uint64_t);
 
@@ -4680,6 +4683,7 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, 
BlockDriverState *in_bs,
 bool has_backing_file;
 bool has_luks;
 bool extended_l2;
+size_t l2e_size;
 
 /* Parse image creation options */
 extended_l2 = qemu_opt_get_bool_del(opts, BLOCK_OPT_EXTL2, false);
@@ -4748,8 +4752,9 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, 
BlockDriverState *in_bs,
 virtual_size = ROUND_UP(virtual_size, cluster_size);
 
 /* Check that virtual disk size is valid */
+l2e_size = extended_l2 ? L2E_SIZE_EXTENDED : L2E_SIZE_NORMAL;
 l2_tables = DIV_ROUND_UP(virtual_size / cluster_size,
- cluster_size / sizeof(uint64_t));
+ cluster_size / l2e_size);
 if (l2_tables * sizeof(uint64_t) > QCOW_MAX_L1_SIZE) {
 error_setg(_err, "The image size is too large "
"(try using a larger cluster size)");
@@ -4812,9 +4817,9 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, 
BlockDriverState *in_bs,
 }
 
 info = g_new(BlockMeasureInfo, 1);
-info->fully_allocated =
+info->fully_allocated = luks_payload_size +
 qcow2_calc_prealloc_size(virtual_size, cluster_size,
- ctz32(refcount_bits)) + luks_payload_size;
+ ctz32(refcount_bits), extended_l2);
 
 /* Remove data clusters that are not required.  This overestimates the
  * required size because metadata needed for the fully allocated file is
-- 
2.20.1




[PATCH v4 10/30] qcow2: Add offset_to_sc_index()

2020-03-17 Thread Alberto Garcia
For a given offset, return the subcluster number within its cluster
(i.e. with 32 subclusters per cluster it returns a number between 0
and 31).

Signed-off-by: Alberto Garcia 
Reviewed-by: Max Reitz 
---
 block/qcow2.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/block/qcow2.h b/block/qcow2.h
index 3052b14dc0..06929072d2 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -566,6 +566,11 @@ static inline int offset_to_l2_slice_index(BDRVQcow2State 
*s, int64_t offset)
 return (offset >> s->cluster_bits) & (s->l2_slice_size - 1);
 }
 
+static inline int offset_to_sc_index(BDRVQcow2State *s, int64_t offset)
+{
+return (offset >> s->subcluster_bits) & (s->subclusters_per_cluster - 1);
+}
+
 static inline int64_t qcow2_vm_state_offset(BDRVQcow2State *s)
 {
 return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
-- 
2.20.1




Re: [PATCH v9 15/15] s390x: Add unpack facility feature to GA1

2020-03-17 Thread Cornelia Huck
On Wed, 11 Mar 2020 09:21:51 -0400
Janosch Frank  wrote:

> From: Christian Borntraeger 
> 
> The unpack facility is an indication that diagnose 308 subcodes 8-10
> are available to the guest. That means, that the guest can put itself
> into protected mode.
> 
> Once it is in protected mode, the hardware stops any attempt of VM
> introspection by the hypervisor.
> 
> Some features are currently not supported in protected mode:
>  * Passthrough devices

s/Passthrough/vfio/ ?

>  * Migration
>  * Huge page backings
> 
> Signed-off-by: Christian Borntraeger 
> Reviewed-by: David Hildenbrand 

Btw: please add your s-o-b if you're passing on patches from others.

> ---
>  target/s390x/gen-features.c | 1 +
>  target/s390x/kvm.c  | 5 +
>  2 files changed, 6 insertions(+)
> 
> diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
> index 6278845b12b8dee8..8ddeebc54419a3e2 100644
> --- a/target/s390x/gen-features.c
> +++ b/target/s390x/gen-features.c
> @@ -562,6 +562,7 @@ static uint16_t full_GEN15_GA1[] = {
>  S390_FEAT_GROUP_MSA_EXT_9,
>  S390_FEAT_GROUP_MSA_EXT_9_PCKMO,
>  S390_FEAT_ETOKEN,
> +S390_FEAT_UNPACK,
>  };
>  
>  /* Default features (in order of release)
> diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
> index ff6027036ec2f14a..e11e895a3d9038bb 100644
> --- a/target/s390x/kvm.c
> +++ b/target/s390x/kvm.c
> @@ -2403,6 +2403,11 @@ void kvm_s390_get_host_cpu_model(S390CPUModel *model, 
> Error **errp)
>  clear_bit(S390_FEAT_BPB, model->features);
>  }
>  
> +/* we do have the IPL enhancements */

I'm more confused by that comment than educated :) Not sure what 'IPL
enhancements' means in this context.

> +if (cap_protected) {
> +set_bit(S390_FEAT_UNPACK, model->features);
> +}
> +
>  /* We emulate a zPCI bus and AEN, therefore we don't need HW support */
>  set_bit(S390_FEAT_ZPCI, model->features);
>  set_bit(S390_FEAT_ADAPTER_EVENT_NOTIFICATION, model->features);




Re: [PATCH] i386/kvm: Add CPU property to expose VMware CPUID signature

2020-03-17 Thread Paolo Bonzini
On 10/03/20 01:40, Liran Alon wrote:
> Some guests are only familiar with VMware PV interface. Therefore, in
> order for these guests to run properly on KVM, we need to be able to
> expose VMware main CPUID leaf. i.e. leaf 0x4000.
> 
> E.g. Without exposing this VMware CPUID leaf, some guests will fail to boot.
> For example, because of guest attempt to calibrate TSC.
> 
> Signed-off-by: Liran Alon 

Looks good, thanks.  It was submitted quite close to soft freeze so I
couldn't get to it quickly.  But I've queued it now, either for 5.0 or 5.1.

Paolo

> ---
>  target/i386/cpu.c |  1 +
>  target/i386/cpu.h |  1 +
>  target/i386/kvm.c | 35 +--
>  3 files changed, 31 insertions(+), 6 deletions(-)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 92fafa265914..694766d45a9b 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -7127,6 +7127,7 @@ static Property x86_cpu_properties[] = {
>  DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true),
>  DEFINE_PROP_BOOL("kvm-no-smi-migration", X86CPU, kvm_no_smi_migration,
>   false),
> +DEFINE_PROP_BOOL("vmware-cpuid", X86CPU, expose_vmware, false),
>  DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true),
>  DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
>  DEFINE_PROP_BOOL("x-migrate-smi-count", X86CPU, migrate_smi_count,
> diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> index 9c7cd7cde107..bca626963e25 100644
> --- a/target/i386/cpu.h
> +++ b/target/i386/cpu.h
> @@ -1647,6 +1647,7 @@ struct X86CPU {
>   */
>  bool force_features;
>  bool expose_kvm;
> +bool expose_vmware;
>  bool expose_tcg;
>  bool migratable;
>  bool migrate_smi_count;
> diff --git a/target/i386/kvm.c b/target/i386/kvm.c
> index 00917196dffb..2656258b96b3 100644
> --- a/target/i386/kvm.c
> +++ b/target/i386/kvm.c
> @@ -1187,6 +1187,15 @@ static int hyperv_handle_properties(CPUState *cs,
>  if (!hyperv_enabled(cpu))
>  return 0;
>  
> +/*
> + * VMware & Hyper-V conflicts in CPUID leafs.
> + * Therefore, they cannot exists together.
> + */
> +if (cpu->expose_vmware) {
> +error_report("vmware-cpuid not compatible with hyperv options");
> +return -ENOTSUP;
> +}
> +
>  if (hyperv_feat_enabled(cpu, HYPERV_FEAT_EVMCS) ||
>  cpu->hyperv_passthrough) {
>  uint16_t evmcs_version;
> @@ -1508,6 +1517,18 @@ int kvm_arch_init_vcpu(CPUState *cs)
>  has_msr_hv_hypercall = true;
>  }
>  
> +if (cpu->expose_vmware) {
> +c = _data.entries[cpuid_i++];
> +c->function = KVM_CPUID_SIGNATURE;
> +memcpy(signature, "VMwareVMware", 12);
> +c->eax = KVM_CPUID_SIGNATURE;
> +c->ebx = signature[0];
> +c->ecx = signature[1];
> +c->edx = signature[2];
> +
> +kvm_base = KVM_CPUID_SIGNATURE_NEXT;
> +}
> +
>  if (cpu->expose_kvm) {
>  memcpy(signature, "KVMKVMKVM\0\0\0", 12);
>  c = _data.entries[cpuid_i++];
> @@ -1791,11 +1812,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
>  }
>  }
>  
> -if (cpu->vmware_cpuid_freq
> -/* Guests depend on 0x4000 to detect this feature, so only expose
> - * it if KVM exposes leaf 0x4000. (Conflicts with Hyper-V) */
> -&& cpu->expose_kvm
> -&& kvm_base == KVM_CPUID_SIGNATURE
> +if (cpu->vmware_cpuid_freq &&
> +(cpu->expose_vmware ||
> + /*
> +  * Guests depend on 0x4000 to detect this feature, so only 
> expose
> +  * it if KVM exposes leaf 0x4000. (Conflicts with Hyper-V)
> +  */
> +  (cpu->expose_kvm && kvm_base == KVM_CPUID_SIGNATURE))
>  /* TSC clock must be stable and known for this feature. */
>  && tsc_is_stable_and_known(env)) {
>  
> @@ -1805,7 +1828,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
>  c->ebx = env->apic_bus_freq / 1000; /* Hz to KHz */
>  c->ecx = c->edx = 0;
>  
> -c = cpuid_find_entry(_data.cpuid, kvm_base, 0);
> +c = cpuid_find_entry(_data.cpuid, KVM_CPUID_SIGNATURE, 0);
>  c->eax = MAX(c->eax, KVM_CPUID_SIGNATURE | 0x10);
>  }
>  
> 




[PULL 28/28] gdbstub: Fix single-step issue by confirming 'vContSupported+' feature to gdb

2020-03-17 Thread Alex Bennée
From: Changbin Du 

Recently when debugging an arm32 system on qemu, I found sometimes the
single-step command (stepi) is not working. This can be reproduced by
below steps:
 1) start qemu-system-arm -s -S .. and wait for gdb connection.
 2) start gdb and connect to qemu. In my case, gdb gets a wrong value
(0x60) for PC, which is an another bug.
 3) After connected, type 'stepi' and expect it will stop at next ins.

But, it has never stopped. This because:
 1) We doesn't report ‘vContSupported’ feature to gdb explicitly and gdb
think we do not support it. In this case, gdb use a software breakpoint
to emulate single-step.
 2) Since gdb gets a wrong initial value of PC, then gdb inserts a
breakpoint to wrong place (PC+4).

Not only for the arm target, Philippe has also encountered this on MIPS.
Probably gdb has different assumption for different architectures.

Since we do support ‘vContSupported’ query command, so let's tell gdb that
we support it.

Before this change, gdb send below 'Z0' packet to implement single-step:
gdb_handle_packet: Z0,4,4

After this change, gdb send "vCont;s.." which is expected:
gdb_handle_packet: vCont?
put_packet: vCont;c;C;s;S
gdb_handle_packet: vCont;s:p1.1;c:p1.-1

Signed-off-by: Changbin Du 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20200221002559.6768-1-changbin...@gmail.com>
[AJB: fix for static gdbstub]
Signed-off-by: Alex Bennée 
Reviewed-by: Luc Michel 
Message-Id: <20200316172155.971-29-alex.ben...@linaro.org>

diff --git a/gdbstub.c b/gdbstub.c
index 9ae148cd1ff..013fb1ac0f1 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2130,7 +2130,7 @@ static void handle_query_supported(GdbCmdContext 
*gdb_ctx, void *user_ctx)
 gdbserver_state.multiprocess = true;
 }
 
-g_string_append(gdbserver_state.str_buf, ";multiprocess+");
+g_string_append(gdbserver_state.str_buf, ";vContSupported+;multiprocess+");
 put_strbuf();
 }
 
-- 
2.20.1




Re: [PATCH] build: Silence clang warning on older glib autoptr usage

2020-03-17 Thread John Snow



On 3/17/20 1:55 PM, Eric Blake wrote:
> glib's G_DEFINE_AUTOPTR_CLEANUP_FUNC() macro defines several static
> inline functions, often with some of them unused, but prior to 2.57.2
> did not mark the functions as such.  As a result, clang (but not gcc)
> fails to build with older glib unless -Wno-unused-function is enabled.
> 
> Reported-by: Peter Maydell 
> Signed-off-by: Eric Blake 
> ---
> 
> Half-tested: I proved to myself that this does NOT enable
> -Wno-unused-function on my setup of glib 2.62.5 and gcc 9.2.1 (Fedora
> 31), but would do so if I introduced an intentional compile error into
> the sample program; but Iwas unable to test that it would prevent the
> build failure encountered by Peter on John's pull request (older glib
> but exact version unknown, clang, on NetBSD).
> 
>  configure | 20 
>  1 file changed, 20 insertions(+)
> 
> diff --git a/configure b/configure
> index eb49bb6680c1..57a72f120aa9 100755
> --- a/configure
> +++ b/configure
> @@ -3832,6 +3832,26 @@ if ! compile_prog "$glib_cflags -Werror" "$glib_libs" 
> ; then
>  fi
>  fi
> 
> +# Silence clang warnings triggered by glib < 2.57.2
> +cat > $TMPC << EOF
> +#include 
> +typedef struct Foo {
> +int i;
> +} Foo;
> +static void foo_free(Foo *f)
> +{
> +g_free(f);
> +}
> +G_DEFINE_AUTOPTR_CLEANUP_FUNC(Foo, foo_free);
> +int main(void) { return 0; }
> +EOF
> +if ! compile_prog "$glib_cflags -Werror" "$glib_libs" ; then
> +if cc_has_warning_flag "-Wno-unused-function"; then
> +glib_cflags="$glib_cflags -Wno-unused-function"
> +CFLAGS="$CFLAGS -Wno-unused-function"
> +fi
> +fi
> +
>  #
>  # zlib check
> 

This looks good to me. By using the glib function under question as the
test program we disable the warning only on some very limited cases.

This might silence SOME legitimate code hygiene warnings so long as
older glib is being used, but there's simply nothing we can do to
prevent this unless glibc is updated on those machines.

Unfortunately, I do not have a NetBSD machine at present, nor do I have
enough familiarity with that platform to make any informed decisions
about if we can say:

- NetBSD is only supported when using glibc XXX and newer

because I do not know if we support any NetBSD platforms that do not
have the updated library in their package repositories.

So, given all of that, this is the most targeted fix that I am able to
reason about at present, so:

Reviewed-by: John Snow 




Re: [PATCH] build: Silence clang warning on older glib autoptr usage

2020-03-17 Thread Peter Maydell
On Tue, 17 Mar 2020 at 17:55, Eric Blake  wrote:
>
> glib's G_DEFINE_AUTOPTR_CLEANUP_FUNC() macro defines several static
> inline functions, often with some of them unused, but prior to 2.57.2
> did not mark the functions as such.  As a result, clang (but not gcc)
> fails to build with older glib unless -Wno-unused-function is enabled.
>
> Reported-by: Peter Maydell 
> Signed-off-by: Eric Blake 
> ---
>
> Half-tested: I proved to myself that this does NOT enable
> -Wno-unused-function on my setup of glib 2.62.5 and gcc 9.2.1 (Fedora
> 31), but would do so if I introduced an intentional compile error into
> the sample program; but Iwas unable to test that it would prevent the
> build failure encountered by Peter on John's pull request (older glib
> but exact version unknown, clang, on NetBSD).

This wasn't a NetBSD failure. I hit it on my clang-on-x86-64-Ubuntu
setup, and also on FreeBSD. (The latter is just the tests/vm
FreeBSD config, so you can repro that if you need to.)

The ubuntu setup is libglib 2.56.4-0ubuntu0.18.04.4 and
clang 6.0.0-1ubuntu2.

thanks
-- PMM



[PULL 17/28] target/arm: default SVE length to 64 bytes for linux-user

2020-03-17 Thread Alex Bennée
The Linux kernel chooses the default of 64 bytes for SVE registers on
the basis that it is the largest size on known hardware that won't
grow the signal frame. We still honour the sve-max-vq property and
userspace can expand the number of lanes by calling PR_SVE_SET_VL.

This should not make any difference to SVE enabled software as the SVE
is of course vector length agnostic.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 

Message-Id: <20200316172155.971-18-alex.ben...@linaro.org>

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 3623ecefbd9..0909ce86a12 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -195,9 +195,10 @@ static void arm_cpu_reset(CPUState *s)
 env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
 /* and to the SVE instructions */
 env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
-/* with maximum vector length */
-env->vfp.zcr_el[1] = cpu_isar_feature(aa64_sve, cpu) ?
- cpu->sve_max_vq - 1 : 0;
+/* with reasonable vector length */
+if (cpu_isar_feature(aa64_sve, cpu)) {
+env->vfp.zcr_el[1] = MIN(cpu->sve_max_vq - 1, 3);
+}
 /*
  * Enable TBI0 and TBI1.  While the real kernel only enables TBI0,
  * turning on both here will produce smaller code and otherwise
-- 
2.20.1




[PULL 21/28] configure: allow user to specify what gdb to use

2020-03-17 Thread Alex Bennée
This is useful, especially when testing relatively new gdbstub
features that might not be in distro packages yet.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Message-Id: <20200316172155.971-22-alex.ben...@linaro.org>

diff --git a/configure b/configure
index eb49bb6680c..057994bce69 100755
--- a/configure
+++ b/configure
@@ -303,6 +303,7 @@ libs_qga=""
 debug_info="yes"
 stack_protector=""
 use_containers="yes"
+gdb_bin=$(command -v "gdb")
 
 if test -e "$source_path/.git"
 then
@@ -1588,6 +1589,8 @@ for opt do
   ;;
   --disable-fuzzing) fuzzing=no
   ;;
+  --gdb=*) gdb_bin="$optarg"
+  ;;
   *)
   echo "ERROR: unknown option $opt"
   echo "Try '$0 --help' for more information"
@@ -1773,6 +1776,7 @@ Advanced options (experts only):
   --enable-plugins
enable plugins via shared library loading
   --disable-containers don't use containers for cross-building
+  --gdb=GDB-path   gdb to use for gdbstub tests [$gdb_bin]
 
 Optional features, enabled with --enable-FEATURE and
 disabled with --disable-FEATURE, default is enabled if available:
@@ -6734,6 +6738,7 @@ echo "libudev   $libudev"
 echo "default devices   $default_devices"
 echo "plugin support$plugins"
 echo "fuzzing support   $fuzzing"
+echo "gdb   $gdb_bin"
 
 if test "$supported_cpu" = "no"; then
 echo
@@ -7608,6 +7613,10 @@ if test "$plugins" = "yes" ; then
 fi
 fi
 
+if test -n "$gdb_bin" ; then
+echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak
+fi
+
 if test "$tcg_interpreter" = "yes"; then
   QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
 elif test "$ARCH" = "sparc64" ; then
-- 
2.20.1




[PULL 24/28] tests/tcg/aarch64: add SVE iotcl test

2020-03-17 Thread Alex Bennée
This is a fairly bare-bones test of setting the various vector sizes
for SVE which will only fail if the PR_SVE_SET_VL can't reduce the
user-space vector length by powers of 2.

However we will also be able to use it in a future test which
exercises the GDB stub.

Signed-off-by: Alex Bennée 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20200316172155.971-25-alex.ben...@linaro.org>

diff --git a/tests/tcg/aarch64/sve-ioctls.c b/tests/tcg/aarch64/sve-ioctls.c
new file mode 100644
index 000..9544dffa0ee
--- /dev/null
+++ b/tests/tcg/aarch64/sve-ioctls.c
@@ -0,0 +1,70 @@
+/*
+ * SVE ioctls tests
+ *
+ * Test the SVE width setting ioctls work and provide a base for
+ * testing the gdbstub.
+ *
+ * Copyright (c) 2019 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef HWCAP_CPUID
+#define HWCAP_CPUID (1 << 11)
+#endif
+
+#define SVE_MAX_QUADS  (2048 / 128)
+#define BYTES_PER_QUAD (128 / 8)
+
+#define get_cpu_reg(id) ({  \
+unsigned long __val;\
+asm("mrs %0, "#id : "=r" (__val));  \
+__val;  \
+})
+
+static int do_sve_ioctl_test(void)
+{
+int i, res, init_vq;
+
+res = prctl(PR_SVE_GET_VL, 0, 0, 0, 0);
+if (res < 0) {
+printf("FAILED to PR_SVE_GET_VL (%d)", res);
+return -1;
+}
+init_vq = res & PR_SVE_VL_LEN_MASK;
+
+for (i = init_vq; i > 15; i /= 2) {
+printf("Checking PR_SVE_SET_VL=%d\n", i);
+res = prctl(PR_SVE_SET_VL, i, 0, 0, 0, 0);
+if (res < 0) {
+printf("FAILED to PR_SVE_SET_VL (%d)", res);
+return -1;
+}
+asm("index z0.b, #0, #1\n"
+".global __sve_ld_done\n"
+"__sve_ld_done:\n"
+"mov z0.b, #0\n"
+: /* no outputs kept */
+: /* no inputs */
+: "memory", "z0");
+}
+printf("PASS\n");
+return 0;
+}
+
+int main(int argc, char **argv)
+{
+/* we also need to probe for the ioctl support */
+if (getauxval(AT_HWCAP) & HWCAP_SVE) {
+return do_sve_ioctl_test();
+} else {
+printf("SKIP: no HWCAP_SVE on this system\n");
+return 0;
+}
+}
diff --git a/tests/tcg/aarch64/Makefile.target 
b/tests/tcg/aarch64/Makefile.target
index b61b53e4dd1..c879932ff6c 100644
--- a/tests/tcg/aarch64/Makefile.target
+++ b/tests/tcg/aarch64/Makefile.target
@@ -47,6 +47,10 @@ ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_SVE),)
 AARCH64_TESTS += sysregs
 sysregs: CFLAGS+=-march=armv8.1-a+sve
 
+# SVE ioctl test
+AARCH64_TESTS += sve-ioctls
+sve-ioctls: CFLAGS+=-march=armv8.1-a+sve
+
 ifneq ($(HAVE_GDB_BIN),)
 GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py
 
-- 
2.20.1




[PULL 26/28] gdbstub: change GDBState.last_packet to GByteArray

2020-03-17 Thread Alex Bennée
From: Damien Hedde 

Remove the packet size upper limit by using a GByteArray
instead of a statically allocated array for last_packet.
Thus we can now send big packets.

Also remove the last_packet_len field and use last_packet->len
instead.

Signed-off-by: Damien Hedde 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20191211160514.58373-2-damien.he...@greensocs.com>
Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Message-Id: <20200316172155.971-27-alex.ben...@linaro.org>

diff --git a/gdbstub.c b/gdbstub.c
index 0bcfc47a7c5..a60ef5125eb 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -351,8 +351,7 @@ typedef struct GDBState {
 int line_buf_index;
 int line_sum; /* running checksum */
 int line_csum; /* checksum at the end of the packet */
-uint8_t last_packet[MAX_PACKET_LENGTH + 4];
-int last_packet_len;
+GByteArray *last_packet;
 int signal;
 #ifdef CONFIG_USER_ONLY
 int fd;
@@ -384,6 +383,7 @@ static void init_gdbserver_state(void)
 gdbserver_state.init = true;
 gdbserver_state.str_buf = g_string_new(NULL);
 gdbserver_state.mem_buf = g_byte_array_sized_new(MAX_PACKET_LENGTH);
+gdbserver_state.last_packet = g_byte_array_sized_new(MAX_PACKET_LENGTH + 
4);
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -626,28 +626,29 @@ static void hexdump(const char *buf, int len,
 static int put_packet_binary(const char *buf, int len, bool dump)
 {
 int csum, i;
-uint8_t *p;
-uint8_t *ps = _state.last_packet[0];
+uint8_t footer[3];
 
 if (dump && trace_event_get_state_backends(TRACE_GDBSTUB_IO_BINARYREPLY)) {
 hexdump(buf, len, trace_gdbstub_io_binaryreply);
 }
 
 for(;;) {
-p = ps;
-*(p++) = '$';
-memcpy(p, buf, len);
-p += len;
+g_byte_array_set_size(gdbserver_state.last_packet, 0);
+g_byte_array_append(gdbserver_state.last_packet,
+(const uint8_t *) "$", 1);
+g_byte_array_append(gdbserver_state.last_packet,
+(const uint8_t *) buf, len);
 csum = 0;
 for(i = 0; i < len; i++) {
 csum += buf[i];
 }
-*(p++) = '#';
-*(p++) = tohex((csum >> 4) & 0xf);
-*(p++) = tohex((csum) & 0xf);
+footer[0] = '#';
+footer[1] = tohex((csum >> 4) & 0xf);
+footer[2] = tohex((csum) & 0xf);
+g_byte_array_append(gdbserver_state.last_packet, footer, 3);
 
-gdbserver_state.last_packet_len = p - ps;
-put_buffer(ps, gdbserver_state.last_packet_len);
+put_buffer(gdbserver_state.last_packet->data,
+   gdbserver_state.last_packet->len);
 
 #ifdef CONFIG_USER_ONLY
 i = get_char();
@@ -2812,20 +2813,22 @@ static void gdb_read_byte(uint8_t ch)
 uint8_t reply;
 
 #ifndef CONFIG_USER_ONLY
-if (gdbserver_state.last_packet_len) {
+if (gdbserver_state.last_packet->len) {
 /* Waiting for a response to the last packet.  If we see the start
of a new command then abandon the previous response.  */
 if (ch == '-') {
 trace_gdbstub_err_got_nack();
-put_buffer((uint8_t *)gdbserver_state.last_packet, 
gdbserver_state.last_packet_len);
+put_buffer(gdbserver_state.last_packet->data,
+   gdbserver_state.last_packet->len);
 } else if (ch == '+') {
 trace_gdbstub_io_got_ack();
 } else {
 trace_gdbstub_io_got_unexpected(ch);
 }
 
-if (ch == '+' || ch == '$')
-gdbserver_state.last_packet_len = 0;
+if (ch == '+' || ch == '$') {
+g_byte_array_set_size(gdbserver_state.last_packet, 0);
+}
 if (ch != '$')
 return;
 }
@@ -3209,7 +3212,7 @@ static int gdb_monitor_write(Chardev *chr, const uint8_t 
*buf, int len)
 const char *p = (const char *)buf;
 int max_sz;
 
-max_sz = (sizeof(gdbserver_state.last_packet) - 2) / 2;
+max_sz = (MAX_PACKET_LENGTH / 2) + 1;
 for (;;) {
 if (len <= max_sz) {
 gdb_monitor_output(p, len);
-- 
2.20.1




[PATCH] build: Silence clang warning on older glib autoptr usage

2020-03-17 Thread Eric Blake
glib's G_DEFINE_AUTOPTR_CLEANUP_FUNC() macro defines several static
inline functions, often with some of them unused, but prior to 2.57.2
did not mark the functions as such.  As a result, clang (but not gcc)
fails to build with older glib unless -Wno-unused-function is enabled.

Reported-by: Peter Maydell 
Signed-off-by: Eric Blake 
---

Half-tested: I proved to myself that this does NOT enable
-Wno-unused-function on my setup of glib 2.62.5 and gcc 9.2.1 (Fedora
31), but would do so if I introduced an intentional compile error into
the sample program; but Iwas unable to test that it would prevent the
build failure encountered by Peter on John's pull request (older glib
but exact version unknown, clang, on NetBSD).

 configure | 20 
 1 file changed, 20 insertions(+)

diff --git a/configure b/configure
index eb49bb6680c1..57a72f120aa9 100755
--- a/configure
+++ b/configure
@@ -3832,6 +3832,26 @@ if ! compile_prog "$glib_cflags -Werror" "$glib_libs" ; 
then
 fi
 fi

+# Silence clang warnings triggered by glib < 2.57.2
+cat > $TMPC << EOF
+#include 
+typedef struct Foo {
+int i;
+} Foo;
+static void foo_free(Foo *f)
+{
+g_free(f);
+}
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(Foo, foo_free);
+int main(void) { return 0; }
+EOF
+if ! compile_prog "$glib_cflags -Werror" "$glib_libs" ; then
+if cc_has_warning_flag "-Wno-unused-function"; then
+glib_cflags="$glib_cflags -Wno-unused-function"
+CFLAGS="$CFLAGS -Wno-unused-function"
+fi
+fi
+
 #
 # zlib check

-- 
2.25.1




[PULL 18/28] target/arm: generate xml description of our SVE registers

2020-03-17 Thread Alex Bennée
We also expose a the helpers to read/write the the registers.

Signed-off-by: Alex Bennée 
Acked-by: Richard Henderson 

Message-Id: <20200316172155.971-19-alex.ben...@linaro.org>

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index fbfd73a7b5b..8b9f2961ba0 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -756,6 +756,7 @@ struct ARMCPU {
 int32_t cpreg_vmstate_array_len;
 
 DynamicGDBXMLInfo dyn_sysreg_xml;
+DynamicGDBXMLInfo dyn_svereg_xml;
 
 /* Timers used by the generic (architected) timer */
 QEMUTimer *gt_timer[NUM_GTIMERS];
@@ -977,10 +978,12 @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cpu, 
vaddr addr,
 int arm_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int arm_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
-/* Dynamically generates for gdb stub an XML description of the sysregs from
- * the cp_regs hashtable. Returns the registered sysregs number.
+/*
+ * Helpers to dynamically generates XML descriptions of the sysregs
+ * and SVE registers. Returns the number of registers in each set.
  */
 int arm_gen_dynamic_sysreg_xml(CPUState *cpu, int base_reg);
+int arm_gen_dynamic_svereg_xml(CPUState *cpu, int base_reg);
 
 /* Returns the dynamically generated XML for the gdb stub.
  * Returns a pointer to the XML contents for the specified XML file or NULL
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
index 69c35462a63..d9ef7d2187c 100644
--- a/target/arm/gdbstub.c
+++ b/target/arm/gdbstub.c
@@ -171,12 +171,146 @@ int arm_gen_dynamic_sysreg_xml(CPUState *cs, int 
base_reg)
 return cpu->dyn_sysreg_xml.num;
 }
 
+struct TypeSize {
+const char *gdb_type;
+int  size;
+const char sz, suffix;
+};
+
+static const struct TypeSize vec_lanes[] = {
+/* quads */
+{ "uint128", 128, 'q', 'u' },
+{ "int128", 128, 'q', 's' },
+/* 64 bit */
+{ "uint64", 64, 'd', 'u' },
+{ "int64", 64, 'd', 's' },
+{ "ieee_double", 64, 'd', 'f' },
+/* 32 bit */
+{ "uint32", 32, 's', 'u' },
+{ "int32", 32, 's', 's' },
+{ "ieee_single", 32, 's', 'f' },
+/* 16 bit */
+{ "uint16", 16, 'h', 'u' },
+{ "int16", 16, 'h', 's' },
+{ "ieee_half", 16, 'h', 'f' },
+/* bytes */
+{ "uint8", 8, 'b', 'u' },
+{ "int8", 8, 'b', 's' },
+};
+
+
+int arm_gen_dynamic_svereg_xml(CPUState *cs, int base_reg)
+{
+ARMCPU *cpu = ARM_CPU(cs);
+GString *s = g_string_new(NULL);
+DynamicGDBXMLInfo *info = >dyn_svereg_xml;
+g_autoptr(GString) ts = g_string_new("");
+int i, bits, reg_width = (cpu->sve_max_vq * 128);
+info->num = 0;
+g_string_printf(s, "");
+g_string_append_printf(s, "");
+g_string_append_printf(s, "");
+
+/* First define types and totals in a whole VL */
+for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
+int count = reg_width / vec_lanes[i].size;
+g_string_printf(ts, "vq%d%c%c", count,
+vec_lanes[i].sz, vec_lanes[i].suffix);
+g_string_append_printf(s,
+   "",
+   ts->str, vec_lanes[i].gdb_type, count);
+}
+/*
+ * Now define a union for each size group containing unsigned and
+ * signed and potentially float versions of each size from 128 to
+ * 8 bits.
+ */
+for (bits = 128; bits >= 8; bits /= 2) {
+int count = reg_width / bits;
+g_string_append_printf(s, "", count);
+for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
+if (vec_lanes[i].size == bits) {
+g_string_append_printf(s, "",
+   vec_lanes[i].suffix,
+   count,
+   vec_lanes[i].sz, vec_lanes[i].suffix);
+}
+}
+g_string_append(s, "");
+}
+/* And now the final union of unions */
+g_string_append(s, "");
+for (bits = 128; bits >= 8; bits /= 2) {
+int count = reg_width / bits;
+for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
+if (vec_lanes[i].size == bits) {
+g_string_append_printf(s, "",
+   vec_lanes[i].sz, count);
+break;
+}
+}
+}
+g_string_append(s, "");
+
+/* Then define each register in parts for each vq */
+for (i = 0; i < 32; i++) {
+g_string_append_printf(s,
+   "",
+   i, reg_width, base_reg++);
+info->num++;
+}
+/* fpscr & status registers */
+g_string_append_printf(s, "", base_reg++);
+g_string_append_printf(s, "", base_reg++);
+info->num += 2;
+/*
+ * Predicate registers aren't so big they are worth splitting up
+ * but we do need to define a type to hold the array of quad
+ * references.
+ */
+g_string_append_printf(s,
+   "",
+   cpu->sve_max_vq);
+for (i = 

[PULL 27/28] gdbstub: do not split gdb_monitor_write payload

2020-03-17 Thread Alex Bennée
From: Damien Hedde 

Since we can now send packets of arbitrary length:
simplify gdb_monitor_write() and send the whole payload
in one packet.

Suggested-by: Luc Michel 
Signed-off-by: Damien Hedde 
Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Message-Id: <20191211160514.58373-3-damien.he...@greensocs.com>
Message-Id: <20200316172155.971-28-alex.ben...@linaro.org>

diff --git a/gdbstub.c b/gdbstub.c
index a60ef5125eb..9ae148cd1ff 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -3200,28 +3200,11 @@ static void gdb_chr_event(void *opaque, QEMUChrEvent 
event)
 }
 }
 
-static void gdb_monitor_output(const char *msg, int len)
-{
-g_autoptr(GString) buf = g_string_new("O");
-memtohex(buf, (uint8_t *)msg, len);
-put_packet(buf->str);
-}
-
 static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
 {
-const char *p = (const char *)buf;
-int max_sz;
-
-max_sz = (MAX_PACKET_LENGTH / 2) + 1;
-for (;;) {
-if (len <= max_sz) {
-gdb_monitor_output(p, len);
-break;
-}
-gdb_monitor_output(p, max_sz);
-p += max_sz;
-len -= max_sz;
-}
+g_autoptr(GString) hex_buf = g_string_new("O");
+memtohex(hex_buf, buf, len);
+put_packet(hex_buf->str);
 return len;
 }
 
-- 
2.20.1




[PULL 22/28] tests/guest-debug: add a simple test runner

2020-03-17 Thread Alex Bennée
The test runners job is to start QEMU with guest debug enabled and
then spawn a gdb process running a test script that exercises the
functionality it wants to test.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20200316172155.971-23-alex.ben...@linaro.org>

diff --git a/tests/guest-debug/run-test.py b/tests/guest-debug/run-test.py
new file mode 100755
index 000..8c49ee2f225
--- /dev/null
+++ b/tests/guest-debug/run-test.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python3
+#
+# Run a gdbstub test case
+#
+# Copyright (c) 2019 Linaro
+#
+# Author: Alex Bennée 
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import argparse
+import subprocess
+import shutil
+import shlex
+
+def get_args():
+parser = argparse.ArgumentParser(description="A gdbstub test runner")
+parser.add_argument("--qemu", help="Qemu binary for test",
+required=True)
+parser.add_argument("--qargs", help="Qemu arguments for test")
+parser.add_argument("--binary", help="Binary to debug",
+required=True)
+parser.add_argument("--test", help="GDB test script",
+required=True)
+parser.add_argument("--gdb", help="The gdb binary to use", default=None)
+
+return parser.parse_args()
+
+if __name__ == '__main__':
+args = get_args()
+
+# Search for a gdb we can use
+if not args.gdb:
+args.gdb = shutil.which("gdb-multiarch")
+if not args.gdb:
+args.gdb = shutil.which("gdb")
+if not args.gdb:
+print("We need gdb to run the test")
+exit(-1)
+
+# Launch QEMU with binary
+if "system" in args.qemu:
+cmd = "%s %s %s -s -S" % (args.qemu, args.qargs, args.binary)
+else:
+cmd = "%s %s -g 1234 %s" % (args.qemu, args.qargs, args.binary)
+
+inferior = subprocess.Popen(shlex.split(cmd))
+
+# Now launch gdb with our test and collect the result
+gdb_cmd = "%s %s -ex 'target remote localhost:1234' -x %s" % (args.gdb, 
args.binary, args.test)
+
+result = subprocess.call(gdb_cmd, shell=True);
+
+exit(result)
-- 
2.20.1




[PULL 20/28] tests/tcg/aarch64: userspace system register test

2020-03-17 Thread Alex Bennée
This tests a bunch of registers that the kernel allows userspace to
read including the CPUID registers. We need a SVE aware compiler as we
are testing the id_aa64zfr0_el1 register in the set.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Message-Id: <20200316172155.971-21-alex.ben...@linaro.org>

diff --git a/tests/tcg/aarch64/sysregs.c b/tests/tcg/aarch64/sysregs.c
new file mode 100644
index 000..40cf8d2877e
--- /dev/null
+++ b/tests/tcg/aarch64/sysregs.c
@@ -0,0 +1,172 @@
+/*
+ * Check emulated system register access for linux-user mode.
+ *
+ * See: 
https://www.kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt
+ *
+ * Copyright (c) 2019 Linaro
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef HWCAP_CPUID
+#define HWCAP_CPUID (1 << 11)
+#endif
+
+int failed_bit_count;
+
+/* Read and print system register `id' value */
+#define get_cpu_reg(id) ({  \
+unsigned long __val = 0xdeadbeef;   \
+asm("mrs %0, "#id : "=r" (__val));  \
+printf("%-20s: 0x%016lx\n", #id, __val);\
+__val;   \
+})
+
+/* As above but also check no bits outside of `mask' are set*/
+#define get_cpu_reg_check_mask(id, mask) ({ \
+unsigned long __cval = get_cpu_reg(id); \
+unsigned long __extra = __cval & ~mask; \
+if (__extra) {  \
+printf("%-20s: 0x%016lx\n", "  !!extra bits!!", __extra);   \
+failed_bit_count++;\
+}   \
+})
+
+/* As above but check RAZ */
+#define get_cpu_reg_check_zero(id) ({   \
+unsigned long __val = 0xdeadbeef;   \
+asm("mrs %0, "#id : "=r" (__val));  \
+if (__val) {\
+printf("%-20s: 0x%016lx (not RAZ!)\n", #id, __val);\
+failed_bit_count++;\
+}   \
+})
+
+/* Chunk up mask into 63:48, 47:32, 31:16, 15:0 to ease counting */
+#define _m(a, b, c, d) (0x ## a ## b ## c ## d ##ULL)
+
+bool should_fail;
+int should_fail_count;
+int should_not_fail_count;
+uintptr_t failed_pc[10];
+
+void sigill_handler(int signo, siginfo_t *si, void *data)
+{
+ucontext_t *uc = (ucontext_t *)data;
+
+if (should_fail) {
+should_fail_count++;
+} else {
+uintptr_t pc = (uintptr_t) uc->uc_mcontext.pc;
+failed_pc[should_not_fail_count++] =  pc;
+}
+uc->uc_mcontext.pc += 4;
+}
+
+int main(void)
+{
+struct sigaction sa;
+
+/* Hook in a SIGILL handler */
+memset(, 0, sizeof(struct sigaction));
+sa.sa_flags = SA_SIGINFO;
+sa.sa_sigaction = _handler;
+sigemptyset(_mask);
+
+if (sigaction(SIGILL, , 0) != 0) {
+perror("sigaction");
+return 1;
+}
+
+/* Counter values have been exposed since Linux 4.12 */
+printf("Checking Counter registers\n");
+
+get_cpu_reg(ctr_el0);
+get_cpu_reg(cntvct_el0);
+get_cpu_reg(cntfrq_el0);
+
+/* HWCAP_CPUID indicates we can read feature registers, since Linux 4.11 */
+if (!(getauxval(AT_HWCAP) & HWCAP_CPUID)) {
+printf("CPUID registers unavailable\n");
+return 1;
+} else {
+printf("Checking CPUID registers\n");
+}
+
+/*
+ * Some registers only expose some bits to user-space. Anything
+ * that is IMPDEF is exported as 0 to user-space. The _mask checks
+ * assert no extra bits are set.
+ *
+ * This check is *not* comprehensive as some fields are set to
+ * minimum valid fields - for the purposes of this check allowed
+ * to have non-zero values.
+ */
+get_cpu_reg_check_mask(id_aa64isar0_el1, _m(00ff,,f0ff,fff0));
+get_cpu_reg_check_mask(id_aa64isar1_el1, _m(,00f0,,));
+/* TGran4 & TGran64 as pegged to -1 */
+get_cpu_reg_check_mask(id_aa64mmfr0_el1, _m(,,ff00,));
+get_cpu_reg_check_zero(id_aa64mmfr1_el1);
+/* EL1/EL0 reported as AA64 only */
+get_cpu_reg_check_mask(id_aa64pfr0_el1,  _m(000f,000f,00ff,0011));
+get_cpu_reg_check_mask(id_aa64pfr1_el1,  _m(,,,00f0));
+/* all hidden, DebugVer fixed to 0x6 (ARMv8 debug architecture) */
+get_cpu_reg_check_mask(id_aa64dfr0_el1,  _m(,,,0006));
+get_cpu_reg_check_zero(id_aa64dfr1_el1);
+get_cpu_reg_check_zero(id_aa64zfr0_el1);
+
+get_cpu_reg_check_zero(id_aa64afr0_el1);
+

[PULL 13/28] target/i386: use gdb_get_reg helpers

2020-03-17 Thread Alex Bennée
This is cleaner than poking memory directly and will make later
clean-ups easier.

Signed-off-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20200316172155.971-14-alex.ben...@linaro.org>

diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c
index 572ead641ca..e4d8cb66c00 100644
--- a/target/i386/gdbstub.c
+++ b/target/i386/gdbstub.c
@@ -98,26 +98,22 @@ int x86_cpu_gdb_read_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 return gdb_get_reg64(mem_buf,
  env->regs[gpr_map[n]] & 0xUL);
 } else {
-memset(mem_buf, 0, sizeof(target_ulong));
-return sizeof(target_ulong);
+return gdb_get_regl(mem_buf, 0);
 }
 } else {
 return gdb_get_reg32(mem_buf, env->regs[gpr_map32[n]]);
 }
 } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
-#ifdef USE_X86LDOUBLE
-/* FIXME: byteswap float values - after fixing fpregs layout. */
-memcpy(mem_buf, >fpregs[n - IDX_FP_REGS], 10);
-#else
-memset(mem_buf, 0, 10);
-#endif
-return 10;
+floatx80 *fp = (floatx80 *) >fpregs[n - IDX_FP_REGS];
+int len = gdb_get_reg64(mem_buf, cpu_to_le64(fp->low));
+len += gdb_get_reg16(mem_buf + len, cpu_to_le16(fp->high));
+return len;
 } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) {
 n -= IDX_XMM_REGS;
 if (n < CPU_NB_REGS32 || TARGET_LONG_BITS == 64) {
-stq_p(mem_buf, env->xmm_regs[n].ZMM_Q(0));
-stq_p(mem_buf + 8, env->xmm_regs[n].ZMM_Q(1));
-return 16;
+return gdb_get_reg128(mem_buf,
+  env->xmm_regs[n].ZMM_Q(0),
+  env->xmm_regs[n].ZMM_Q(1));
 }
 } else {
 switch (n) {
@@ -290,10 +286,9 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 return 4;
 }
 } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
-#ifdef USE_X86LDOUBLE
-/* FIXME: byteswap float values - after fixing fpregs layout. */
-memcpy(>fpregs[n - IDX_FP_REGS], mem_buf, 10);
-#endif
+floatx80 *fp = (floatx80 *) >fpregs[n - IDX_FP_REGS];
+fp->low = le64_to_cpu(* (uint64_t *) mem_buf);
+fp->high = le16_to_cpu(* (uint16_t *) (mem_buf + 8));
 return 10;
 } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) {
 n -= IDX_XMM_REGS;
-- 
2.20.1




[PULL 19/28] target/arm: don't bother with id_aa64pfr0_read for USER_ONLY

2020-03-17 Thread Alex Bennée
For system emulation we need to check the state of the GIC before we
report the value. However this isn't relevant to exporting of the
value to linux-user and indeed breaks the exported value as set by
modify_arm_cp_regs.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20200316172155.971-20-alex.ben...@linaro.org>

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7e560ea7db6..d2ec2c53510 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6697,6 +6697,7 @@ static uint64_t id_pfr1_read(CPUARMState *env, const 
ARMCPRegInfo *ri)
 return pfr1;
 }
 
+#ifndef CONFIG_USER_ONLY
 static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
 ARMCPU *cpu = env_archcpu(env);
@@ -6707,6 +6708,7 @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const 
ARMCPRegInfo *ri)
 }
 return pfr0;
 }
+#endif
 
 /* Shared logic between LORID and the rest of the LOR* registers.
  * Secure state has already been delt with.
@@ -7280,16 +7282,24 @@ void register_cp_regs_for_features(ARMCPU *cpu)
  * define new registers here.
  */
 ARMCPRegInfo v8_idregs[] = {
-/* ID_AA64PFR0_EL1 is not a plain ARM_CP_CONST because we don't
- * know the right value for the GIC field until after we
- * define these regs.
+/*
+ * ID_AA64PFR0_EL1 is not a plain ARM_CP_CONST in system
+ * emulation because we don't know the right value for the
+ * GIC field until after we define these regs.
  */
 { .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0,
-  .access = PL1_R, .type = ARM_CP_NO_RAW,
+  .access = PL1_R,
+#ifdef CONFIG_USER_ONLY
+  .type = ARM_CP_CONST,
+  .resetvalue = cpu->isar.id_aa64pfr0
+#else
+  .type = ARM_CP_NO_RAW,
   .accessfn = access_aa64_tid3,
   .readfn = id_aa64pfr0_read,
-  .writefn = arm_cp_write_ignore },
+  .writefn = arm_cp_write_ignore
+#endif
+},
 { .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1,
   .access = PL1_R, .type = ARM_CP_CONST,
-- 
2.20.1




Re: [PATCH v3 0/8] Misc hw/ide legacy clean up

2020-03-17 Thread John Snow



On 3/17/20 11:05 AM, BALATON Zoltan wrote:
> Avoid problems from reassigning variable in piix4_create and fix
> compilation problem with mips_r4k
> 
> BALATON Zoltan (8):
>   hw/ide: Get rid of piix3_init functions
>   hw/isa/piix4.c: Introduce variable to store devfn
>   hw/ide: Get rid of piix4_init function
>   hw/ide: Remove now unneded #include "hw/pci/pci.h" from hw/ide.h
>   hw/ide/pci.c: Coding style update to fix checkpatch errors
>   hw/ide: Do ide_drive_get() within pci_ide_create_devs()
>   hw/ide: Move MAX_IDE_DEVS define to hw/ide/internal.h
>   hw/ide: Remove unneeded inclusion of hw/ide.h
> 
>  hw/alpha/dp264.c  | 13 +++--
>  hw/hppa/hppa_sys.h|  1 -
>  hw/hppa/machine.c |  1 -
>  hw/i386/pc_piix.c | 18 +-
>  hw/ide/ahci_internal.h|  1 +
>  hw/ide/pci.c  | 11 +++
>  hw/ide/piix.c | 31 +--
>  hw/isa/piix4.c| 23 ++-
>  hw/mips/mips_fulong2e.c   |  5 +
>  hw/mips/mips_malta.c  |  2 +-
>  hw/mips/mips_r4k.c|  1 +
>  hw/ppc/mac_newworld.c |  1 -
>  hw/ppc/mac_oldworld.c |  1 -
>  hw/ppc/prep.c |  1 -
>  hw/sparc64/sun4u.c|  6 +-
>  include/hw/ide.h  |  6 --
>  include/hw/ide/internal.h |  2 ++
>  include/hw/ide/pci.h  |  3 ++-
>  include/hw/misc/macio/macio.h |  1 +
>  include/hw/southbridge/piix.h |  3 +--
>  20 files changed, 41 insertions(+), 90 deletions(-)
> 

Passed local testing. Pushed to gitlab and pending further tests.

Track here: https://gitlab.com/jsnow/qemu/pipelines/127143307




[PULL 15/28] target/arm: prepare for multiple dynamic XMLs

2020-03-17 Thread Alex Bennée
We will want to generate similar dynamic XML for gdbstub support of
SVE registers (the upstream doesn't use XML). To that end lightly
rename a few things to make the distinction.

Signed-off-by: Alex Bennée 
Acked-by: Richard Henderson 
Message-Id: <20200316172155.971-16-alex.ben...@linaro.org>

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 4ab2cbfd417..0ab82c987c3 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -128,14 +128,20 @@ enum {
 /**
  * DynamicGDBXMLInfo:
  * @desc: Contains the XML descriptions.
- * @num_cpregs: Number of the Coprocessor registers seen by GDB.
- * @cpregs_keys: Array that contains the corresponding Key of
- * a given cpreg with the same order of the cpreg in the XML description.
+ * @num: Number of the registers in this XML seen by GDB.
+ * @data: A union with data specific to the set of registers
+ *@cpregs_keys: Array that contains the corresponding Key of
+ *  a given cpreg with the same order of the cpreg
+ *  in the XML description.
  */
 typedef struct DynamicGDBXMLInfo {
 char *desc;
-int num_cpregs;
-uint32_t *cpregs_keys;
+int num;
+union {
+struct {
+uint32_t *keys;
+} cpregs;
+} data;
 } DynamicGDBXMLInfo;
 
 /* CPU state for each instance of a generic timer (in cp15 c14) */
@@ -749,7 +755,7 @@ struct ARMCPU {
 uint64_t *cpreg_vmstate_values;
 int32_t cpreg_vmstate_array_len;
 
-DynamicGDBXMLInfo dyn_xml;
+DynamicGDBXMLInfo dyn_sysreg_xml;
 
 /* Timers used by the generic (architected) timer */
 QEMUTimer *gt_timer[NUM_GTIMERS];
@@ -974,7 +980,7 @@ int arm_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, 
int reg);
 /* Dynamically generates for gdb stub an XML description of the sysregs from
  * the cp_regs hashtable. Returns the registered sysregs number.
  */
-int arm_gen_dynamic_xml(CPUState *cpu);
+int arm_gen_dynamic_sysreg_xml(CPUState *cpu);
 
 /* Returns the dynamically generated XML for the gdb stub.
  * Returns a pointer to the XML contents for the specified XML file or NULL
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
index 4557775d245..1f68ab98c3b 100644
--- a/target/arm/gdbstub.c
+++ b/target/arm/gdbstub.c
@@ -106,15 +106,15 @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 return 0;
 }
 
-static void arm_gen_one_xml_reg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml,
-ARMCPRegInfo *ri, uint32_t ri_key,
-int bitsize)
+static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml,
+   ARMCPRegInfo *ri, uint32_t ri_key,
+   int bitsize)
 {
 g_string_append_printf(s, "name);
 g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
 g_string_append_printf(s, " group=\"cp_regs\"/>");
-dyn_xml->num_cpregs++;
-dyn_xml->cpregs_keys[dyn_xml->num_cpregs - 1] = ri_key;
+dyn_xml->data.cpregs.keys[dyn_xml->num] = ri_key;
+dyn_xml->num++;
 }
 
 static void arm_register_sysreg_for_xml(gpointer key, gpointer value,
@@ -126,12 +126,12 @@ static void arm_register_sysreg_for_xml(gpointer key, 
gpointer value,
 GString *s = param->s;
 ARMCPU *cpu = ARM_CPU(param->cs);
 CPUARMState *env = >env;
-DynamicGDBXMLInfo *dyn_xml = >dyn_xml;
+DynamicGDBXMLInfo *dyn_xml = >dyn_sysreg_xml;
 
 if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_NO_GDB))) {
 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
 if (ri->state == ARM_CP_STATE_AA64) {
-arm_gen_one_xml_reg_tag(s , dyn_xml, ri, ri_key, 64);
+arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64);
 }
 } else {
 if (ri->state == ARM_CP_STATE_AA32) {
@@ -140,30 +140,30 @@ static void arm_register_sysreg_for_xml(gpointer key, 
gpointer value,
 return;
 }
 if (ri->type & ARM_CP_64BIT) {
-arm_gen_one_xml_reg_tag(s , dyn_xml, ri, ri_key, 64);
+arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64);
 } else {
-arm_gen_one_xml_reg_tag(s , dyn_xml, ri, ri_key, 32);
+arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 32);
 }
 }
 }
 }
 }
 
-int arm_gen_dynamic_xml(CPUState *cs)
+int arm_gen_dynamic_sysreg_xml(CPUState *cs)
 {
 ARMCPU *cpu = ARM_CPU(cs);
 GString *s = g_string_new(NULL);
 RegisterSysregXmlParam param = {cs, s};
 
-cpu->dyn_xml.num_cpregs = 0;
-cpu->dyn_xml.cpregs_keys = g_new(uint32_t, 
g_hash_table_size(cpu->cp_regs));
+cpu->dyn_sysreg_xml.num = 0;
+cpu->dyn_sysreg_xml.data.cpregs.keys = g_new(uint32_t, 
g_hash_table_size(cpu->cp_regs));
 g_string_printf(s, "");
 g_string_append_printf(s, "");
 g_string_append_printf(s, "");
 

[PULL 14/28] gdbstub: extend GByteArray to read register helpers

2020-03-17 Thread Alex Bennée
Instead of passing a pointer to memory now just extend the GByteArray
to all the read register helpers. They can then safely append their
data through the normal way. We don't bother with this abstraction for
write registers as we have already ensured the buffer being copied
from is the correct size.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Acked-by: David Gibson 
Reviewed-by: Damien Hedde 

Message-Id: <20200316172155.971-15-alex.ben...@linaro.org>

diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 59e366ba3af..30b909ebd27 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -68,53 +68,76 @@ void gdb_signalled(CPUArchState *, int);
 void gdbserver_fork(CPUState *);
 #endif
 /* Get or set a register.  Returns the size of the register.  */
-typedef int (*gdb_reg_cb)(CPUArchState *env, uint8_t *buf, int reg);
+typedef int (*gdb_get_reg_cb)(CPUArchState *env, GByteArray *buf, int reg);
+typedef int (*gdb_set_reg_cb)(CPUArchState *env, uint8_t *buf, int reg);
 void gdb_register_coprocessor(CPUState *cpu,
-  gdb_reg_cb get_reg, gdb_reg_cb set_reg,
+  gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
   int num_regs, const char *xml, int g_pos);
 
-/* The GDB remote protocol transfers values in target byte order.  This means
- * we can use the raw memory access routines to access the value buffer.
- * Conveniently, these also handle the case where the buffer is mis-aligned.
+/*
+ * The GDB remote protocol transfers values in target byte order. As
+ * the gdbstub may be batching up several register values we always
+ * append to the array.
  */
 
-static inline int gdb_get_reg8(uint8_t *mem_buf, uint8_t val)
+static inline int gdb_get_reg8(GByteArray *buf, uint8_t val)
 {
-stb_p(mem_buf, val);
+g_byte_array_append(buf, , 1);
 return 1;
 }
 
-static inline int gdb_get_reg16(uint8_t *mem_buf, uint16_t val)
+static inline int gdb_get_reg16(GByteArray *buf, uint16_t val)
 {
-stw_p(mem_buf, val);
+uint16_t to_word = tswap16(val);
+g_byte_array_append(buf, (uint8_t *) _word, 2);
 return 2;
 }
 
-static inline int gdb_get_reg32(uint8_t *mem_buf, uint32_t val)
+static inline int gdb_get_reg32(GByteArray *buf, uint32_t val)
 {
-stl_p(mem_buf, val);
+uint32_t to_long = tswap32(val);
+g_byte_array_append(buf, (uint8_t *) _long, 4);
 return 4;
 }
 
-static inline int gdb_get_reg64(uint8_t *mem_buf, uint64_t val)
+static inline int gdb_get_reg64(GByteArray *buf, uint64_t val)
 {
-stq_p(mem_buf, val);
+uint64_t to_quad = tswap64(val);
+g_byte_array_append(buf, (uint8_t *) _quad, 8);
 return 8;
 }
 
-static inline int gdb_get_reg128(uint8_t *mem_buf, uint64_t val_hi,
+static inline int gdb_get_reg128(GByteArray *buf, uint64_t val_hi,
  uint64_t val_lo)
 {
+uint64_t to_quad;
 #ifdef TARGET_WORDS_BIGENDIAN
-stq_p(mem_buf, val_hi);
-stq_p(mem_buf + 8, val_lo);
+to_quad = tswap64(val_hi);
+g_byte_array_append(buf, (uint8_t *) _quad, 8);
+to_quad = tswap64(val_lo);
+g_byte_array_append(buf, (uint8_t *) _quad, 8);
 #else
-stq_p(mem_buf, val_lo);
-stq_p(mem_buf + 8, val_hi);
+to_quad = tswap64(val_lo);
+g_byte_array_append(buf, (uint8_t *) _quad, 8);
+to_quad = tswap64(val_hi);
+g_byte_array_append(buf, (uint8_t *) _quad, 8);
 #endif
 return 16;
 }
 
+/**
+ * gdb_get_reg_ptr: get pointer to start of last element
+ * @len: length of element
+ *
+ * This is a helper function to extract the pointer to the last
+ * element for additional processing. Some front-ends do additional
+ * dynamic swapping of the elements based on CPU state.
+ */
+static inline uint8_t * gdb_get_reg_ptr(GByteArray *buf, int len)
+{
+return buf->data + buf->len - len;
+}
+
 #if TARGET_LONG_BITS == 64
 #define gdb_get_regl(buf, val) gdb_get_reg64(buf, val)
 #define ldtul_p(addr) ldq_p(addr)
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 73e9a869a41..e1d6ee00b40 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -195,7 +195,7 @@ typedef struct CPUClass {
 hwaddr (*get_phys_page_attrs_debug)(CPUState *cpu, vaddr addr,
 MemTxAttrs *attrs);
 int (*asidx_from_attrs)(CPUState *cpu, MemTxAttrs attrs);
-int (*gdb_read_register)(CPUState *cpu, uint8_t *buf, int reg);
+int (*gdb_read_register)(CPUState *cpu, GByteArray *buf, int reg);
 int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg);
 bool (*debug_check_watchpoint)(CPUState *cpu, CPUWatchpoint *wp);
 void (*debug_excp_handler)(CPUState *cpu);
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index 3f782c0efe4..be29bdd5301 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -280,7 +280,7 @@ void alpha_cpu_do_interrupt(CPUState *cpu);
 bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
 void 

[PULL 23/28] tests/tcg/aarch64: add a gdbstub testcase for SVE registers

2020-03-17 Thread Alex Bennée
A very simple test case which sets and reads SVE registers while
running a test case. We don't really need to compile a SVE binary for
this case but we will later so keep it simple for now.

Signed-off-by: Alex Bennée 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20200316172155.971-24-alex.ben...@linaro.org>

diff --git a/tests/.gitignore b/tests/.gitignore
index 7306866f216..d03c037d772 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -10,6 +10,7 @@ qht-bench
 rcutorture
 test-*
 !test-*.c
+!test-*.py
 !docker/test-*
 test-qapi-commands.[ch]
 test-qapi-init-commands.[ch]
diff --git a/tests/tcg/aarch64/Makefile.target 
b/tests/tcg/aarch64/Makefile.target
index a25afc071cc..b61b53e4dd1 100644
--- a/tests/tcg/aarch64/Makefile.target
+++ b/tests/tcg/aarch64/Makefile.target
@@ -46,6 +46,21 @@ ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_SVE),)
 # System Registers Tests
 AARCH64_TESTS += sysregs
 sysregs: CFLAGS+=-march=armv8.1-a+sve
+
+ifneq ($(HAVE_GDB_BIN),)
+GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py
+
+AARCH64_TESTS += gdbstub-sysregs
+
+.PHONY: gdbstub-sysregs
+run-gdbstub-sysregs: sysregs
+   $(call run-test, $@, $(GDB_SCRIPT) \
+   --gdb $(HAVE_GDB_BIN) \
+   --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
+   --bin $< --test $(AARCH64_SRC)/gdbstub/test-sve.py, \
+   "basic gdbstub SVE support")
+endif
+
 endif
 
 TESTS += $(AARCH64_TESTS)
diff --git a/tests/tcg/aarch64/gdbstub/test-sve.py 
b/tests/tcg/aarch64/gdbstub/test-sve.py
new file mode 100644
index 000..dbe7f2aa932
--- /dev/null
+++ b/tests/tcg/aarch64/gdbstub/test-sve.py
@@ -0,0 +1,84 @@
+from __future__ import print_function
+#
+# Test the SVE registers are visable and changeable via gdbstub
+#
+# This is launched via tests/guest-debug/run-test.py
+#
+
+import gdb
+import sys
+
+MAGIC = 0xDEADBEEF
+
+failcount = 0
+
+def report(cond, msg):
+"Report success/fail of test"
+if cond:
+print ("PASS: %s" % (msg))
+else:
+print ("FAIL: %s" % (msg))
+global failcount
+failcount += 1
+
+def run_test():
+"Run through the tests one by one"
+
+gdb.execute("info registers")
+report(True, "info registers")
+
+gdb.execute("info registers vector")
+report(True, "info registers vector")
+
+# Now all the zregs
+frame = gdb.selected_frame()
+for i in range(0, 32):
+rname = "z%d" % (i)
+zreg = frame.read_register(rname)
+report(True, "Reading %s" % rname)
+for j in range(0, 4):
+cmd = "set $%s.q.u[%d] = 0x%x" % (rname, j, MAGIC)
+gdb.execute(cmd)
+report(True, "%s" % cmd)
+for j in range(0, 4):
+reg = "$%s.q.u[%d]" % (rname, j)
+v = gdb.parse_and_eval(reg)
+report(str(v.type) == "uint128_t", "size of %s" % (reg))
+for j in range(0, 8):
+cmd = "set $%s.d.u[%d] = 0x%x" % (rname, j, MAGIC)
+gdb.execute(cmd)
+report(True, "%s" % cmd)
+for j in range(0, 8):
+reg = "$%s.d.u[%d]" % (rname, j)
+v = gdb.parse_and_eval(reg)
+report(str(v.type) == "uint64_t", "size of %s" % (reg))
+report(int(v) == MAGIC, "%s is 0x%x" % (reg, MAGIC))
+
+#
+# This runs as the script it sourced (via -x, via run-test.py)
+#
+try:
+inferior = gdb.selected_inferior()
+if inferior.was_attached == False:
+print("SKIPPING (failed to attach)", file=sys.stderr)
+exit(0)
+arch = inferior.architecture()
+report(arch.name() == "aarch64", "connected to aarch64")
+except (gdb.error, AttributeError):
+print("SKIPPING (not connected)", file=sys.stderr)
+exit(0)
+
+try:
+# These are not very useful in scripts
+gdb.execute("set pagination off")
+gdb.execute("set confirm off")
+
+# Run the actual tests
+run_test()
+except:
+print ("GDB Exception: %s" % (sys.exc_info()[0]))
+failcount += 1
+
+print("All tests complete: %d failures" % failcount)
+
+exit(failcount)
-- 
2.20.1




[PULL 25/28] tests/tcg/aarch64: add test-sve-ioctl guest-debug test

2020-03-17 Thread Alex Bennée
This test exercises the gdbstub while runing the sve-iotcl test. I
haven't plubmed it into make system as we need a way of verifying if
gdb has the right support for SVE.

Signed-off-by: Alex Bennée 
Message-Id: <20200316172155.971-26-alex.ben...@linaro.org>

diff --git a/tests/tcg/aarch64/Makefile.target 
b/tests/tcg/aarch64/Makefile.target
index c879932ff6c..d99b2a9eced 100644
--- a/tests/tcg/aarch64/Makefile.target
+++ b/tests/tcg/aarch64/Makefile.target
@@ -54,15 +54,22 @@ sve-ioctls: CFLAGS+=-march=armv8.1-a+sve
 ifneq ($(HAVE_GDB_BIN),)
 GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py
 
-AARCH64_TESTS += gdbstub-sysregs
+AARCH64_TESTS += gdbstub-sysregs gdbstub-sve-ioctls
 
-.PHONY: gdbstub-sysregs
+.PHONY: gdbstub-sysregs gdbstub-sve-ioctls
 run-gdbstub-sysregs: sysregs
$(call run-test, $@, $(GDB_SCRIPT) \
--gdb $(HAVE_GDB_BIN) \
--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
--bin $< --test $(AARCH64_SRC)/gdbstub/test-sve.py, \
"basic gdbstub SVE support")
+
+run-gdbstub-sve-ioctls: sve-ioctls
+   $(call run-test, $@, $(GDB_SCRIPT) \
+   --gdb $(HAVE_GDB_BIN) \
+   --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
+   --bin $< --test $(AARCH64_SRC)/gdbstub/test-sve-ioctl.py, \
+   "basic gdbstub SVE ZLEN support")
 endif
 
 endif
diff --git a/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py 
b/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py
new file mode 100644
index 000..984fbeb277e
--- /dev/null
+++ b/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py
@@ -0,0 +1,85 @@
+from __future__ import print_function
+#
+# Test the SVE ZReg reports the right amount of data. It uses the
+# sve-ioctl test and examines the register data each time the
+# __sve_ld_done breakpoint is hit.
+#
+# This is launched via tests/guest-debug/run-test.py
+#
+
+import gdb
+import sys
+
+initial_vlen = 0
+failcount = 0
+
+def report(cond, msg):
+"Report success/fail of test"
+if cond:
+print ("PASS: %s" % (msg))
+else:
+print ("FAIL: %s" % (msg))
+global failcount
+failcount += 1
+
+class TestBreakpoint(gdb.Breakpoint):
+def __init__(self, sym_name="__sve_ld_done"):
+super(TestBreakpoint, self).__init__(sym_name)
+# self.sym, ok = gdb.lookup_symbol(sym_name)
+
+def stop(self):
+val_i = gdb.parse_and_eval('i')
+global initial_vlen
+try:
+for i in range(0, int(val_i)):
+val_z = gdb.parse_and_eval("$z0.b.u[%d]" % i)
+report(int(val_z) == i, "z0.b.u[%d] == %d" % (i, i))
+for i in range(i + 1, initial_vlen):
+val_z = gdb.parse_and_eval("$z0.b.u[%d]" % i)
+report(int(val_z) == 0, "z0.b.u[%d] == 0" % (i))
+except gdb.error:
+report(False, "checking zregs (out of range)")
+
+
+def run_test():
+"Run through the tests one by one"
+
+print ("Setup breakpoint")
+bp = TestBreakpoint()
+
+global initial_vlen
+vg = gdb.parse_and_eval("$vg")
+initial_vlen = int(vg) * 8
+
+gdb.execute("c")
+
+#
+# This runs as the script it sourced (via -x, via run-test.py)
+#
+try:
+inferior = gdb.selected_inferior()
+if inferior.was_attached == False:
+print("SKIPPING (failed to attach)", file=sys.stderr)
+exit(0)
+arch = inferior.architecture()
+report(arch.name() == "aarch64", "connected to aarch64")
+except (gdb.error, AttributeError):
+print("SKIPPING (not connected)", file=sys.stderr)
+exit(0)
+
+try:
+# These are not very useful in scripts
+gdb.execute("set pagination off")
+gdb.execute("set confirm off")
+
+# Run the actual tests
+run_test()
+except:
+print ("GDB Exception: %s" % (sys.exc_info()[0]))
+failcount += 1
+import code
+code.InteractiveConsole(locals=globals()).interact()
+raise
+
+print("All tests complete: %d failures" % failcount)
+exit(failcount)
-- 
2.20.1




[PULL 09/28] gdbstub: move mem_buf to GDBState and use GByteArray

2020-03-17 Thread Alex Bennée
This is in preparation for further re-factoring of the register API
with the rest of the code. Theoretically the read register function
could overwrite the MAX_PACKET_LENGTH buffer although currently all
registers are well within the size range.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Reviewed-by: Damien Hedde 
Tested-by: Damien Hedde 

Message-Id: <20200316172155.971-10-alex.ben...@linaro.org>

diff --git a/gdbstub.c b/gdbstub.c
index f6b42825445..db537a712cc 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -367,6 +367,7 @@ typedef struct GDBState {
 char syscall_buf[256];
 gdb_syscall_complete_cb current_syscall_cb;
 GString *str_buf;
+GByteArray *mem_buf;
 } GDBState;
 
 /* By default use no IRQs and no timers while single stepping so as to
@@ -382,6 +383,7 @@ static void init_gdbserver_state(void)
 memset(_state, 0, sizeof(GDBState));
 gdbserver_state.init = true;
 gdbserver_state.str_buf = g_string_new(NULL);
+gdbserver_state.mem_buf = g_byte_array_sized_new(MAX_PACKET_LENGTH);
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -576,12 +578,13 @@ static void memtohex(GString *buf, const uint8_t *mem, 
int len)
 g_string_append_c(buf, '\0');
 }
 
-static void hextomem(uint8_t *mem, const char *buf, int len)
+static void hextomem(GByteArray *mem, const char *buf, int len)
 {
 int i;
 
 for(i = 0; i < len; i++) {
-mem[i] = (fromhex(buf[0]) << 4) | fromhex(buf[1]);
+guint8 byte = fromhex(buf[0]) << 4 | fromhex(buf[1]);
+g_byte_array_append(mem, , 1);
 buf += 2;
 }
 }
@@ -1412,7 +1415,6 @@ static int cmd_parse_params(const char *data, const char 
*schema,
 typedef struct GdbCmdContext {
 GdbCmdVariant *params;
 int num_params;
-uint8_t mem_buf[MAX_PACKET_LENGTH];
 } GdbCmdContext;
 
 typedef void (*GdbCmdHandler)(GdbCmdContext *gdb_ctx, void *user_ctx);
@@ -1503,6 +1505,7 @@ static void run_cmd_parser(const char *data, const 
GdbCmdParseEntry *cmd)
 }
 
 g_string_set_size(gdbserver_state.str_buf, 0);
+g_byte_array_set_size(gdbserver_state.mem_buf, 0);
 
 /* In case there was an error during the command parsing we must
 * send a NULL packet to indicate the command is not supported */
@@ -1715,8 +1718,8 @@ static void handle_set_reg(GdbCmdContext *gdb_ctx, void 
*user_ctx)
 }
 
 reg_size = strlen(gdb_ctx->params[1].data) / 2;
-hextomem(gdb_ctx->mem_buf, gdb_ctx->params[1].data, reg_size);
-gdb_write_register(gdbserver_state.g_cpu, gdb_ctx->mem_buf,
+hextomem(gdbserver_state.mem_buf, gdb_ctx->params[1].data, reg_size);
+gdb_write_register(gdbserver_state.g_cpu, gdbserver_state.mem_buf->data,
gdb_ctx->params[0].val_ull);
 put_packet("OK");
 }
@@ -1735,14 +1738,17 @@ static void handle_get_reg(GdbCmdContext *gdb_ctx, void 
*user_ctx)
 return;
 }
 
-reg_size = gdb_read_register(gdbserver_state.g_cpu, gdb_ctx->mem_buf,
+reg_size = gdb_read_register(gdbserver_state.g_cpu,
+ gdbserver_state.mem_buf->data,
  gdb_ctx->params[0].val_ull);
 if (!reg_size) {
 put_packet("E14");
 return;
+} else {
+g_byte_array_set_size(gdbserver_state.mem_buf, reg_size);
 }
 
-memtohex(gdbserver_state.str_buf, gdb_ctx->mem_buf, reg_size);
+memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, reg_size);
 put_strbuf();
 }
 
@@ -1759,11 +1765,11 @@ static void handle_write_mem(GdbCmdContext *gdb_ctx, 
void *user_ctx)
 return;
 }
 
-hextomem(gdb_ctx->mem_buf, gdb_ctx->params[2].data,
+hextomem(gdbserver_state.mem_buf, gdb_ctx->params[2].data,
  gdb_ctx->params[1].val_ull);
 if (target_memory_rw_debug(gdbserver_state.g_cpu, 
gdb_ctx->params[0].val_ull,
-   gdb_ctx->mem_buf,
-   gdb_ctx->params[1].val_ull, true)) {
+   gdbserver_state.mem_buf->data,
+   gdbserver_state.mem_buf->len, true)) {
 put_packet("E14");
 return;
 }
@@ -1784,14 +1790,17 @@ static void handle_read_mem(GdbCmdContext *gdb_ctx, 
void *user_ctx)
 return;
 }
 
+g_byte_array_set_size(gdbserver_state.mem_buf, gdb_ctx->params[1].val_ull);
+
 if (target_memory_rw_debug(gdbserver_state.g_cpu, 
gdb_ctx->params[0].val_ull,
-   gdb_ctx->mem_buf,
-   gdb_ctx->params[1].val_ull, false)) {
+   gdbserver_state.mem_buf->data,
+   gdbserver_state.mem_buf->len, false)) {
 put_packet("E14");
 return;
 }
 
-memtohex(gdbserver_state.str_buf, gdb_ctx->mem_buf, 
gdb_ctx->params[1].val_ull);
+memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data,
+ gdbserver_state.mem_buf->len);
 put_strbuf();
 }
 
@@ -1806,9 +1815,9 @@ static void 

[PULL 16/28] target/arm: explicitly encode regnum in our XML

2020-03-17 Thread Alex Bennée
This is described as optional but I'm not convinced of the numbering
when multiple target fragments are sent.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 

Message-Id: <20200316172155.971-17-alex.ben...@linaro.org>

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 0ab82c987c3..fbfd73a7b5b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -980,7 +980,7 @@ int arm_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, 
int reg);
 /* Dynamically generates for gdb stub an XML description of the sysregs from
  * the cp_regs hashtable. Returns the registered sysregs number.
  */
-int arm_gen_dynamic_sysreg_xml(CPUState *cpu);
+int arm_gen_dynamic_sysreg_xml(CPUState *cpu, int base_reg);
 
 /* Returns the dynamically generated XML for the gdb stub.
  * Returns a pointer to the XML contents for the specified XML file or NULL
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
index 1f68ab98c3b..69c35462a63 100644
--- a/target/arm/gdbstub.c
+++ b/target/arm/gdbstub.c
@@ -24,6 +24,7 @@
 typedef struct RegisterSysregXmlParam {
 CPUState *cs;
 GString *s;
+int n;
 } RegisterSysregXmlParam;
 
 /* Old gdb always expect FPA registers.  Newer (xml-aware) gdb only expect
@@ -108,10 +109,11 @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 
 static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml,
ARMCPRegInfo *ri, uint32_t ri_key,
-   int bitsize)
+   int bitsize, int regnum)
 {
 g_string_append_printf(s, "name);
 g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
+g_string_append_printf(s, " regnum=\"%d\"", regnum);
 g_string_append_printf(s, " group=\"cp_regs\"/>");
 dyn_xml->data.cpregs.keys[dyn_xml->num] = ri_key;
 dyn_xml->num++;
@@ -131,7 +133,8 @@ static void arm_register_sysreg_for_xml(gpointer key, 
gpointer value,
 if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_NO_GDB))) {
 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
 if (ri->state == ARM_CP_STATE_AA64) {
-arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64);
+arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64,
+   param->n++);
 }
 } else {
 if (ri->state == ARM_CP_STATE_AA32) {
@@ -140,20 +143,22 @@ static void arm_register_sysreg_for_xml(gpointer key, 
gpointer value,
 return;
 }
 if (ri->type & ARM_CP_64BIT) {
-arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64);
+arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 64,
+   param->n++);
 } else {
-arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 32);
+arm_gen_one_xml_sysreg_tag(s , dyn_xml, ri, ri_key, 32,
+   param->n++);
 }
 }
 }
 }
 }
 
-int arm_gen_dynamic_sysreg_xml(CPUState *cs)
+int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg)
 {
 ARMCPU *cpu = ARM_CPU(cs);
 GString *s = g_string_new(NULL);
-RegisterSysregXmlParam param = {cs, s};
+RegisterSysregXmlParam param = {cs, s, base_reg};
 
 cpu->dyn_sysreg_xml.num = 0;
 cpu->dyn_sysreg_xml.data.cpregs.keys = g_new(uint32_t, 
g_hash_table_size(cpu->cp_regs));
diff --git a/target/arm/helper.c b/target/arm/helper.c
index b0e2a85b005..90135731353 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7973,7 +7973,7 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
  19, "arm-vfp.xml", 0);
 }
 gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
- arm_gen_dynamic_sysreg_xml(cs),
+ arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
  "system-registers.xml", 0);
 }
 
-- 
2.20.1




[PULL 08/28] gdbstub: move str_buf to GDBState and use GString

2020-03-17 Thread Alex Bennée
Rather than having a static buffer replace str_buf with a GString
which we know can grow on demand. Convert the internal functions to
take a GString instead of a char * and length.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Reviewed-by: Damien Hedde 
Tested-by: Damien Hedde 
Message-Id: <20200316172155.971-9-alex.ben...@linaro.org>

diff --git a/gdbstub.c b/gdbstub.c
index 7243a2f7af9..f6b42825445 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -366,6 +366,7 @@ typedef struct GDBState {
 int process_num;
 char syscall_buf[256];
 gdb_syscall_complete_cb current_syscall_cb;
+GString *str_buf;
 } GDBState;
 
 /* By default use no IRQs and no timers while single stepping so as to
@@ -380,6 +381,7 @@ static void init_gdbserver_state(void)
 g_assert(!gdbserver_state.init);
 memset(_state, 0, sizeof(GDBState));
 gdbserver_state.init = true;
+gdbserver_state.str_buf = g_string_new(NULL);
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -563,17 +565,15 @@ static inline int tohex(int v)
 }
 
 /* writes 2*len+1 bytes in buf */
-static void memtohex(char *buf, const uint8_t *mem, int len)
+static void memtohex(GString *buf, const uint8_t *mem, int len)
 {
 int i, c;
-char *q;
-q = buf;
 for(i = 0; i < len; i++) {
 c = mem[i];
-*q++ = tohex(c >> 4);
-*q++ = tohex(c & 0xf);
+g_string_append_c(buf, tohex(c >> 4));
+g_string_append_c(buf, tohex(c & 0xf));
 }
-*q = '\0';
+g_string_append_c(buf, '\0');
 }
 
 static void hextomem(uint8_t *mem, const char *buf, int len)
@@ -667,25 +667,28 @@ static int put_packet(const char *buf)
 return put_packet_binary(buf, strlen(buf), false);
 }
 
+static void put_strbuf(void)
+{
+put_packet(gdbserver_state.str_buf->str);
+}
+
 /* Encode data using the encoding for 'x' packets.  */
-static int memtox(char *buf, const char *mem, int len)
+static void memtox(GString *buf, const char *mem, int len)
 {
-char *p = buf;
 char c;
 
 while (len--) {
 c = *(mem++);
 switch (c) {
 case '#': case '$': case '*': case '}':
-*(p++) = '}';
-*(p++) = c ^ 0x20;
+g_string_append_c(buf, '}');
+g_string_append_c(buf, c ^ 0x20);
 break;
 default:
-*(p++) = c;
+g_string_append_c(buf, c);
 break;
 }
 }
-return p - buf;
 }
 
 static uint32_t gdb_get_cpu_pid(CPUState *cpu)
@@ -1109,16 +1112,14 @@ static void gdb_set_cpu_pc(target_ulong pc)
 cpu_set_pc(cpu, pc);
 }
 
-static char *gdb_fmt_thread_id(CPUState *cpu, char *buf, size_t buf_size)
+static void gdb_append_thread_id(CPUState *cpu, GString *buf)
 {
 if (gdbserver_state.multiprocess) {
-snprintf(buf, buf_size, "p%02x.%02x",
- gdb_get_cpu_pid(cpu), cpu_gdb_index(cpu));
+g_string_append_printf(buf, "p%02x.%02x",
+   gdb_get_cpu_pid(cpu), cpu_gdb_index(cpu));
 } else {
-snprintf(buf, buf_size, "%02x", cpu_gdb_index(cpu));
+g_string_append_printf(buf, "%02x", cpu_gdb_index(cpu));
 }
-
-return buf;
 }
 
 typedef enum GDBThreadIdKind {
@@ -1412,7 +1413,6 @@ typedef struct GdbCmdContext {
 GdbCmdVariant *params;
 int num_params;
 uint8_t mem_buf[MAX_PACKET_LENGTH];
-char str_buf[MAX_PACKET_LENGTH + 1];
 } GdbCmdContext;
 
 typedef void (*GdbCmdHandler)(GdbCmdContext *gdb_ctx, void *user_ctx);
@@ -1502,6 +1502,8 @@ static void run_cmd_parser(const char *data, const 
GdbCmdParseEntry *cmd)
 return;
 }
 
+g_string_set_size(gdbserver_state.str_buf, 0);
+
 /* In case there was an error during the command parsing we must
 * send a NULL packet to indicate the command is not supported */
 if (process_string_cmd(NULL, data, cmd, 1)) {
@@ -1740,8 +1742,8 @@ static void handle_get_reg(GdbCmdContext *gdb_ctx, void 
*user_ctx)
 return;
 }
 
-memtohex(gdb_ctx->str_buf, gdb_ctx->mem_buf, reg_size);
-put_packet(gdb_ctx->str_buf);
+memtohex(gdbserver_state.str_buf, gdb_ctx->mem_buf, reg_size);
+put_strbuf();
 }
 
 static void handle_write_mem(GdbCmdContext *gdb_ctx, void *user_ctx)
@@ -1789,8 +1791,8 @@ static void handle_read_mem(GdbCmdContext *gdb_ctx, void 
*user_ctx)
 return;
 }
 
-memtohex(gdb_ctx->str_buf, gdb_ctx->mem_buf, gdb_ctx->params[1].val_ull);
-put_packet(gdb_ctx->str_buf);
+memtohex(gdbserver_state.str_buf, gdb_ctx->mem_buf, 
gdb_ctx->params[1].val_ull);
+put_strbuf();
 }
 
 static void handle_write_all_regs(GdbCmdContext *gdb_ctx, void *user_ctx)
@@ -1827,8 +1829,8 @@ static void handle_read_all_regs(GdbCmdContext *gdb_ctx, 
void *user_ctx)
  addr);
 }
 
-memtohex(gdb_ctx->str_buf, gdb_ctx->mem_buf, len);
-put_packet(gdb_ctx->str_buf);
+memtohex(gdbserver_state.str_buf, gdb_ctx->mem_buf, len);
+put_strbuf();
 }
 
 static void handle_file_io(GdbCmdContext *gdb_ctx, 

[PULL 12/28] target/m68k: use gdb_get_reg helpers

2020-03-17 Thread Alex Bennée
This is cleaner than poking memory directly and will make later
clean-ups easier.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Reviewed-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20200316172155.971-13-alex.ben...@linaro.org>

diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index baf7729af00..c23b70f854d 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -72,19 +72,15 @@ static int cf_fpu_gdb_get_reg(CPUM68KState *env, uint8_t 
*mem_buf, int n)
 {
 if (n < 8) {
 float_status s;
-stfq_p(mem_buf, floatx80_to_float64(env->fregs[n].d, ));
-return 8;
+return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, 
));
 }
 switch (n) {
 case 8: /* fpcontrol */
-stl_be_p(mem_buf, env->fpcr);
-return 4;
+return gdb_get_reg32(mem_buf, env->fpcr);
 case 9: /* fpstatus */
-stl_be_p(mem_buf, env->fpsr);
-return 4;
+return gdb_get_reg32(mem_buf, env->fpsr);
 case 10: /* fpiar, not implemented */
-memset(mem_buf, 0, 4);
-return 4;
+return gdb_get_reg32(mem_buf, 0);
 }
 return 0;
 }
@@ -112,21 +108,18 @@ static int cf_fpu_gdb_set_reg(CPUM68KState *env, uint8_t 
*mem_buf, int n)
 static int m68k_fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n)
 {
 if (n < 8) {
-stw_be_p(mem_buf, env->fregs[n].l.upper);
-memset(mem_buf + 2, 0, 2);
-stq_be_p(mem_buf + 4, env->fregs[n].l.lower);
-return 12;
+int len = gdb_get_reg16(mem_buf, env->fregs[n].l.upper);
+len += gdb_get_reg16(mem_buf + len, 0);
+len += gdb_get_reg64(mem_buf + len, env->fregs[n].l.lower);
+return len;
 }
 switch (n) {
 case 8: /* fpcontrol */
-stl_be_p(mem_buf, env->fpcr);
-return 4;
+return gdb_get_reg32(mem_buf, env->fpcr);
 case 9: /* fpstatus */
-stl_be_p(mem_buf, env->fpsr);
-return 4;
+return gdb_get_reg32(mem_buf, env->fpsr);
 case 10: /* fpiar, not implemented */
-memset(mem_buf, 0, 4);
-return 4;
+return gdb_get_reg32(mem_buf, 0);
 }
 return 0;
 }
-- 
2.20.1




[PULL 07/28] gdbstub: stop passing GDBState * around and use global

2020-03-17 Thread Alex Bennée
We only have one GDBState which should be allocated at the time we
process any commands. This will make further clean-up a bit easier.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Reviewed-by: Damien Hedde 
Reviewed-by: Philippe Mathieu-Daudé 

Message-Id: <20200316172155.971-8-alex.ben...@linaro.org>

diff --git a/gdbstub.c b/gdbstub.c
index 57d6e50ddfc..7243a2f7af9 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -397,21 +397,21 @@ bool gdb_has_xml;
 /* XXX: This is not thread safe.  Do we care?  */
 static int gdbserver_fd = -1;
 
-static int get_char(GDBState *s)
+static int get_char(void)
 {
 uint8_t ch;
 int ret;
 
 for(;;) {
-ret = qemu_recv(s->fd, , 1, 0);
+ret = qemu_recv(gdbserver_state.fd, , 1, 0);
 if (ret < 0) {
 if (errno == ECONNRESET)
-s->fd = -1;
+gdbserver_state.fd = -1;
 if (errno != EINTR)
 return -1;
 } else if (ret == 0) {
-close(s->fd);
-s->fd = -1;
+close(gdbserver_state.fd);
+gdbserver_state.fd = -1;
 return -1;
 } else {
 break;
@@ -449,11 +449,11 @@ int use_gdb_syscalls(void)
 }
 
 /* Resume execution.  */
-static inline void gdb_continue(GDBState *s)
+static inline void gdb_continue(void)
 {
 
 #ifdef CONFIG_USER_ONLY
-s->running_state = 1;
+gdbserver_state.running_state = 1;
 trace_gdbstub_op_continue();
 #else
 if (!runstate_needs_reset()) {
@@ -467,7 +467,7 @@ static inline void gdb_continue(GDBState *s)
  * Resume execution, per CPU actions. For user-mode emulation it's
  * equivalent to gdb_continue.
  */
-static int gdb_continue_partial(GDBState *s, char *newstates)
+static int gdb_continue_partial(char *newstates)
 {
 CPUState *cpu;
 int res = 0;
@@ -482,7 +482,7 @@ static int gdb_continue_partial(GDBState *s, char 
*newstates)
 cpu_single_step(cpu, sstep_flags);
 }
 }
-s->running_state = 1;
+gdbserver_state.running_state = 1;
 #else
 int flag = 0;
 
@@ -520,13 +520,13 @@ static int gdb_continue_partial(GDBState *s, char 
*newstates)
 return res;
 }
 
-static void put_buffer(GDBState *s, const uint8_t *buf, int len)
+static void put_buffer(const uint8_t *buf, int len)
 {
 #ifdef CONFIG_USER_ONLY
 int ret;
 
 while (len > 0) {
-ret = send(s->fd, buf, len, 0);
+ret = send(gdbserver_state.fd, buf, len, 0);
 if (ret < 0) {
 if (errno != EINTR)
 return;
@@ -538,7 +538,7 @@ static void put_buffer(GDBState *s, const uint8_t *buf, int 
len)
 #else
 /* XXX this blocks entire thread. Rewrite to use
  * qemu_chr_fe_write and background I/O callbacks */
-qemu_chr_fe_write_all(>chr, buf, len);
+qemu_chr_fe_write_all(_state.chr, buf, len);
 #endif
 }
 
@@ -620,17 +620,18 @@ static void hexdump(const char *buf, int len,
 }
 
 /* return -1 if error, 0 if OK */
-static int put_packet_binary(GDBState *s, const char *buf, int len, bool dump)
+static int put_packet_binary(const char *buf, int len, bool dump)
 {
 int csum, i;
 uint8_t *p;
+uint8_t *ps = _state.last_packet[0];
 
 if (dump && trace_event_get_state_backends(TRACE_GDBSTUB_IO_BINARYREPLY)) {
 hexdump(buf, len, trace_gdbstub_io_binaryreply);
 }
 
 for(;;) {
-p = s->last_packet;
+p = ps;
 *(p++) = '$';
 memcpy(p, buf, len);
 p += len;
@@ -642,11 +643,11 @@ static int put_packet_binary(GDBState *s, const char 
*buf, int len, bool dump)
 *(p++) = tohex((csum >> 4) & 0xf);
 *(p++) = tohex((csum) & 0xf);
 
-s->last_packet_len = p - s->last_packet;
-put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len);
+gdbserver_state.last_packet_len = p - ps;
+put_buffer(ps, gdbserver_state.last_packet_len);
 
 #ifdef CONFIG_USER_ONLY
-i = get_char(s);
+i = get_char();
 if (i < 0)
 return -1;
 if (i == '+')
@@ -659,11 +660,11 @@ static int put_packet_binary(GDBState *s, const char 
*buf, int len, bool dump)
 }
 
 /* return -1 if error, 0 if OK */
-static int put_packet(GDBState *s, const char *buf)
+static int put_packet(const char *buf)
 {
 trace_gdbstub_io_reply(buf);
 
-return put_packet_binary(s, buf, strlen(buf), false);
+return put_packet_binary(buf, strlen(buf), false);
 }
 
 /* Encode data using the encoding for 'x' packets.  */
@@ -687,37 +688,38 @@ static int memtox(char *buf, const char *mem, int len)
 return p - buf;
 }
 
-static uint32_t gdb_get_cpu_pid(const GDBState *s, CPUState *cpu)
+static uint32_t gdb_get_cpu_pid(CPUState *cpu)
 {
 /* TODO: In user mode, we should use the task state PID */
 if (cpu->cluster_index == UNASSIGNED_CLUSTER_INDEX) {
 /* Return the default process' PID */
-return s->processes[s->process_num - 1].pid;
+int index = gdbserver_state.process_num - 1;
+  

[PULL 11/28] target/arm: use gdb_get_reg helpers

2020-03-17 Thread Alex Bennée
This is cleaner than poking memory directly and will make later
clean-ups easier.

Signed-off-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 

Message-Id: <20200316172155.971-12-alex.ben...@linaro.org>

diff --git a/target/arm/helper.c b/target/arm/helper.c
index b61ee73d18a..69104fb351d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -106,21 +106,17 @@ static int aarch64_fpu_gdb_get_reg(CPUARMState *env, 
uint8_t *buf, int reg)
 {
 switch (reg) {
 case 0 ... 31:
-/* 128 bit FP register */
-{
-uint64_t *q = aa64_vfp_qreg(env, reg);
-stq_le_p(buf, q[0]);
-stq_le_p(buf + 8, q[1]);
-return 16;
-}
+{
+/* 128 bit FP register - quads are in LE order */
+uint64_t *q = aa64_vfp_qreg(env, reg);
+return gdb_get_reg128(buf, q[1], q[0]);
+}
 case 32:
 /* FPSR */
-stl_p(buf, vfp_get_fpsr(env));
-return 4;
+return gdb_get_reg32(buf, vfp_get_fpsr(env));
 case 33:
 /* FPCR */
-stl_p(buf, vfp_get_fpcr(env));
-return 4;
+return gdb_get_reg32(buf,vfp_get_fpcr(env));
 default:
 return 0;
 }
-- 
2.20.1




[PULL 06/28] gdbstub: make GDBState static and have common init function

2020-03-17 Thread Alex Bennée
Instead of allocating make this entirely static. We shall reduce the
size of the structure in later commits and dynamically allocate parts
of it. We introduce an init and reset helper function to keep all the
manipulation in one place.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
Reviewed-by: Damien Hedde 

Message-Id: <20200316172155.971-7-alex.ben...@linaro.org>

diff --git a/gdbstub.c b/gdbstub.c
index 22a2d630cdc..57d6e50ddfc 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -342,6 +342,7 @@ enum RSState {
 RS_CHKSUM2,
 };
 typedef struct GDBState {
+bool init;   /* have we been initialised? */
 CPUState *c_cpu; /* current CPU for step/continue ops */
 CPUState *g_cpu; /* current CPU for other ops */
 CPUState *query_cpu; /* for q{f|s}ThreadInfo */
@@ -372,7 +373,23 @@ typedef struct GDBState {
  */
 static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
 
-static GDBState *gdbserver_state;
+static GDBState gdbserver_state;
+
+static void init_gdbserver_state(void)
+{
+g_assert(!gdbserver_state.init);
+memset(_state, 0, sizeof(GDBState));
+gdbserver_state.init = true;
+}
+
+#ifndef CONFIG_USER_ONLY
+static void reset_gdbserver_state(void)
+{
+g_free(gdbserver_state.processes);
+gdbserver_state.processes = NULL;
+gdbserver_state.process_num = 0;
+}
+#endif
 
 bool gdb_has_xml;
 
@@ -425,8 +442,8 @@ int use_gdb_syscalls(void)
 /* -semihosting-config target=auto */
 /* On the first call check if gdb is connected and remember. */
 if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
-gdb_syscall_mode = (gdbserver_state ? GDB_SYS_ENABLED
-: GDB_SYS_DISABLED);
+gdb_syscall_mode = gdbserver_state.init ?
+GDB_SYS_ENABLED : GDB_SYS_DISABLED;
 }
 return gdb_syscall_mode == GDB_SYS_ENABLED;
 }
@@ -984,7 +1001,7 @@ static int gdb_breakpoint_insert(int type, target_ulong 
addr, target_ulong len)
 int err = 0;
 
 if (kvm_enabled()) {
-return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+return kvm_insert_breakpoint(gdbserver_state.c_cpu, addr, len, type);
 }
 
 switch (type) {
@@ -1021,7 +1038,7 @@ static int gdb_breakpoint_remove(int type, target_ulong 
addr, target_ulong len)
 int err = 0;
 
 if (kvm_enabled()) {
-return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+return kvm_remove_breakpoint(gdbserver_state.c_cpu, addr, len, type);
 }
 
 switch (type) {
@@ -1074,7 +1091,7 @@ static void gdb_breakpoint_remove_all(void)
 CPUState *cpu;
 
 if (kvm_enabled()) {
-kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
+kvm_remove_all_breakpoints(gdbserver_state.c_cpu);
 return;
 }
 
@@ -2601,7 +2618,7 @@ static int gdb_handle_packet(GDBState *s, const char 
*line_buf)
 
 void gdb_set_stop_cpu(CPUState *cpu)
 {
-GDBProcess *p = gdb_get_cpu_process(gdbserver_state, cpu);
+GDBProcess *p = gdb_get_cpu_process(_state, cpu);
 
 if (!p->attached) {
 /*
@@ -2611,14 +2628,14 @@ void gdb_set_stop_cpu(CPUState *cpu)
 return;
 }
 
-gdbserver_state->c_cpu = cpu;
-gdbserver_state->g_cpu = cpu;
+gdbserver_state.c_cpu = cpu;
+gdbserver_state.g_cpu = cpu;
 }
 
 #ifndef CONFIG_USER_ONLY
 static void gdb_vm_state_change(void *opaque, int running, RunState state)
 {
-GDBState *s = gdbserver_state;
+GDBState *s = _state;
 CPUState *cpu = s->c_cpu;
 char buf[256];
 char thread_id[16];
@@ -2722,17 +2739,16 @@ void gdb_do_syscallv(gdb_syscall_complete_cb cb, const 
char *fmt, va_list va)
 char *p_end;
 target_ulong addr;
 uint64_t i64;
-GDBState *s;
 
-s = gdbserver_state;
-if (!s)
+if (!gdbserver_state.init)
 return;
-s->current_syscall_cb = cb;
+
+gdbserver_state.current_syscall_cb = cb;
 #ifndef CONFIG_USER_ONLY
 vm_stop(RUN_STATE_DEBUG);
 #endif
-p = s->syscall_buf;
-p_end = >syscall_buf[sizeof(s->syscall_buf)];
+p = _state.syscall_buf[0];
+p_end = _state.syscall_buf[sizeof(gdbserver_state.syscall_buf)];
 *(p++) = 'F';
 while (*fmt) {
 if (*fmt == '%') {
@@ -2765,14 +2781,14 @@ void gdb_do_syscallv(gdb_syscall_complete_cb cb, const 
char *fmt, va_list va)
 }
 *p = 0;
 #ifdef CONFIG_USER_ONLY
-put_packet(s, s->syscall_buf);
+put_packet(_state, gdbserver_state.syscall_buf);
 /* Return control to gdb for it to process the syscall request.
  * Since the protocol requires that gdb hands control back to us
  * using a "here are the results" F packet, we don't need to check
  * gdb_handlesig's return value (which is the signal to deliver if
  * execution was resumed via a continue packet).
  */
-gdb_handlesig(s->c_cpu, 0);
+gdb_handlesig(gdbserver_state.c_cpu, 0);
 #else
 /* In this case wait to send the syscall packet until notification that
the CPU has 

[PULL 10/28] gdbstub: add helper for 128 bit registers

2020-03-17 Thread Alex Bennée
Signed-off-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20200316172155.971-11-alex.ben...@linaro.org>

diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 08363969c14..59e366ba3af 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -102,6 +102,19 @@ static inline int gdb_get_reg64(uint8_t *mem_buf, uint64_t 
val)
 return 8;
 }
 
+static inline int gdb_get_reg128(uint8_t *mem_buf, uint64_t val_hi,
+ uint64_t val_lo)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+stq_p(mem_buf, val_hi);
+stq_p(mem_buf + 8, val_lo);
+#else
+stq_p(mem_buf, val_lo);
+stq_p(mem_buf + 8, val_hi);
+#endif
+return 16;
+}
+
 #if TARGET_LONG_BITS == 64
 #define gdb_get_regl(buf, val) gdb_get_reg64(buf, val)
 #define ldtul_p(addr) ldq_p(addr)
-- 
2.20.1




[PULL 03/28] tests/docker: Remove obsolete VirGL --with-glx configure option

2020-03-17 Thread Alex Bennée
From: Philippe Mathieu-Daudé 

The GLX configure option has been removed in 71c75f201d [*].
We missed that when updating to v0.7.0 in commit fab3220f97.

This silents:

  configure: creating ./config.status
  config.status: creating virglrenderer.pc
  ...
  configure: WARNING: unrecognized options: --with-glx

[*] https://gitlab.freedesktop.org/virgl/virglrenderer/commit/71c75f201d

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Alex Bennée 
Message-Id: <20200212202709.12665-3-phi...@redhat.com>
Message-Id: <20200316172155.971-4-alex.ben...@linaro.org>

diff --git a/tests/docker/dockerfiles/debian-amd64.docker 
b/tests/docker/dockerfiles/debian-amd64.docker
index b67fad54cb7..a1d40a56fa1 100644
--- a/tests/docker/dockerfiles/debian-amd64.docker
+++ b/tests/docker/dockerfiles/debian-amd64.docker
@@ -29,7 +29,7 @@ RUN apt update && \
 libgbm-dev
 RUN git clone https://gitlab.freedesktop.org/virgl/virglrenderer.git 
/usr/src/virglrenderer && \
 cd /usr/src/virglrenderer && git checkout virglrenderer-0.7.0
-RUN cd /usr/src/virglrenderer && ./autogen.sh && ./configure --with-glx 
--disable-tests && make install
+RUN cd /usr/src/virglrenderer && ./autogen.sh && ./configure --disable-tests 
&& make install
 
 # netmap
 RUN apt update && \
-- 
2.20.1




[PULL 01/28] tests/docker: Install tools to cross-debug and build Linux kernels

2020-03-17 Thread Alex Bennée
From: Philippe Mathieu-Daudé 

We often run Linux kernels to test QEMU. We sometimes need
to build them manually to use non-default features. We only
miss the tiny 'bc' tool.

The ncurses library is helpful to run 'make menuconfig'.

Finally, gdb-multiarch allow us to debug a TCG guest when its
architecture is different than the host.

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Alex Bennée 
Message-Id: <20200212202738.12986-1-phi...@redhat.com>
Message-Id: <20200316172155.971-2-alex.ben...@linaro.org>

diff --git a/tests/docker/dockerfiles/debian10.docker 
b/tests/docker/dockerfiles/debian10.docker
index 5de79ae5527..2fcdc406e83 100644
--- a/tests/docker/dockerfiles/debian10.docker
+++ b/tests/docker/dockerfiles/debian10.docker
@@ -17,14 +17,17 @@ RUN apt update && \
 DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \
 DEBIAN_FRONTEND=noninteractive eatmydata \
 apt install -y --no-install-recommends \
+bc \
 bison \
 build-essential \
 ca-certificates \
 clang \
 dbus \
 flex \
+gdb-multiarch \
 gettext \
 git \
+libncurses5-dev \
 pkg-config \
 psmisc \
 python3 \
diff --git a/tests/docker/dockerfiles/debian9.docker 
b/tests/docker/dockerfiles/debian9.docker
index 8cbd742bb5f..92edbbf0f48 100644
--- a/tests/docker/dockerfiles/debian9.docker
+++ b/tests/docker/dockerfiles/debian9.docker
@@ -17,13 +17,16 @@ RUN apt update && \
 DEBIAN_FRONTEND=noninteractive apt install -yy eatmydata && \
 DEBIAN_FRONTEND=noninteractive eatmydata \
 apt install -y --no-install-recommends \
+bc \
 bison \
 build-essential \
 ca-certificates \
 clang \
 flex \
+gdb-multiarch \
 gettext \
 git \
+libncurses5-dev \
 pkg-config \
 psmisc \
 python3 \
-- 
2.20.1




[PULL 04/28] tests/docker: Update VirGL to v0.8.0

2020-03-17 Thread Alex Bennée
From: Philippe Mathieu-Daudé 

Building the qemu:debian-amd64 fails when building VirGL:

  make[2]: Entering directory '/usr/src/virglrenderer/src/gallium/auxiliary'
CC   cso_cache/cso_cache.lo
CC   cso_cache/cso_hash.lo
CC   os/os_misc.lo
CC   util/u_debug.lo
CC   util/u_debug_describe.lo
CC   util/u_format.lo
GEN  util/u_format_table.c
  Traceback (most recent call last):
File "./util/u_format_table.py", line 168, in 
  main()
File "./util/u_format_table.py", line 164, in main
  write_format_table(formats)
File "./util/u_format_table.py", line 132, in write_format_table
  print("   %s,\t/* is_array */" % (bool_map(format.is_array()),))
File "/usr/src/virglrenderer/src/gallium/auxiliary/util/u_format_parse.py", 
line 164, in is_array
  return self.array_element() != None
File "/usr/src/virglrenderer/src/gallium/auxiliary/util/u_format_parse.py", 
line 73, in __eq__
  return self.type == other.type and self.norm == other.norm and self.pure 
== other.pure and self.size == other.size
  AttributeError: 'NoneType' object has no attribute 'type'
  make[2]: Leaving directory '/usr/src/virglrenderer/src/gallium/auxiliary'
  make[2]: *** [Makefile:906: util/u_format_table.c] Error 1
  make[1]: *** [Makefile:631: install-recursive] Error 1

VirGL commits a8962eda1..a613dcc82 fix this problem.
Update to VirGL 0.8.0 which contains them.

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Alex Bennée 
Message-Id: <20200212202709.12665-4-phi...@redhat.com>
Message-Id: <20200316172155.971-5-alex.ben...@linaro.org>

diff --git a/tests/docker/dockerfiles/debian-amd64.docker 
b/tests/docker/dockerfiles/debian-amd64.docker
index a1d40a56fa1..c70c916343e 100644
--- a/tests/docker/dockerfiles/debian-amd64.docker
+++ b/tests/docker/dockerfiles/debian-amd64.docker
@@ -28,7 +28,7 @@ RUN apt update && \
 libepoxy-dev \
 libgbm-dev
 RUN git clone https://gitlab.freedesktop.org/virgl/virglrenderer.git 
/usr/src/virglrenderer && \
-cd /usr/src/virglrenderer && git checkout virglrenderer-0.7.0
+cd /usr/src/virglrenderer && git checkout virglrenderer-0.8.0
 RUN cd /usr/src/virglrenderer && ./autogen.sh && ./configure --disable-tests 
&& make install
 
 # netmap
-- 
2.20.1




[PULL 00/28 for 5.0] testing and gdbstub updates

2020-03-17 Thread Alex Bennée
The following changes since commit 6fb1603aa24d9212493e4819d7b685be9c9aad7a:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20200317' 
into staging (2020-03-17 14:44:50 +)

are available in the Git repository at:

  https://github.com/stsquad/qemu.git tags/pull-testing-and-gdbstub-170320-1

for you to fetch changes up to 3bc2609d478779be600fd66744eb4e3730ec5e33:

  gdbstub: Fix single-step issue by confirming 'vContSupported+' feature to gdb 
(2020-03-17 17:38:52 +)


Testing and gdbstub updates:

  - docker updates for VirGL
  - re-factor gdbstub for static GDBState
  - re-factor gdbstub for dynamic arrays
  - add SVE support to arm gdbstub
  - add some guest debug tests to check-tcg
  - add aarch64 userspace register tests
  - remove packet size limit to gdbstub
  - simplify gdbstub monitor code
  - report vContSupported in gdbstub to use proper single-step


Alex Bennée (20):
  gdbstub: make GDBState static and have common init function
  gdbstub: stop passing GDBState * around and use global
  gdbstub: move str_buf to GDBState and use GString
  gdbstub: move mem_buf to GDBState and use GByteArray
  gdbstub: add helper for 128 bit registers
  target/arm: use gdb_get_reg helpers
  target/m68k: use gdb_get_reg helpers
  target/i386: use gdb_get_reg helpers
  gdbstub: extend GByteArray to read register helpers
  target/arm: prepare for multiple dynamic XMLs
  target/arm: explicitly encode regnum in our XML
  target/arm: default SVE length to 64 bytes for linux-user
  target/arm: generate xml description of our SVE registers
  target/arm: don't bother with id_aa64pfr0_read for USER_ONLY
  tests/tcg/aarch64: userspace system register test
  configure: allow user to specify what gdb to use
  tests/guest-debug: add a simple test runner
  tests/tcg/aarch64: add a gdbstub testcase for SVE registers
  tests/tcg/aarch64: add SVE iotcl test
  tests/tcg/aarch64: add test-sve-ioctl guest-debug test

Changbin Du (1):
  gdbstub: Fix single-step issue by confirming 'vContSupported+' feature to 
gdb

Damien Hedde (2):
  gdbstub: change GDBState.last_packet to GByteArray
  gdbstub: do not split gdb_monitor_write payload

Philippe Mathieu-Daudé (5):
  tests/docker: Install tools to cross-debug and build Linux kernels
  tests/docker: Update VirGL git repository URL
  tests/docker: Remove obsolete VirGL --with-glx configure option
  tests/docker: Update VirGL to v0.8.0
  travis.yml: Set G_MESSAGES_DEBUG do report GLib errors

 configure|   9 +
 include/exec/gdbstub.h   |  62 +-
 include/hw/core/cpu.h|   2 +-
 target/alpha/cpu.h   |   2 +-
 target/arm/cpu.h |  31 +-
 target/cris/cpu.h|   4 +-
 target/hppa/cpu.h|   2 +-
 target/i386/cpu.h|   2 +-
 target/lm32/cpu.h|   2 +-
 target/m68k/cpu.h|   2 +-
 target/microblaze/cpu.h  |   2 +-
 target/mips/internal.h   |   2 +-
 target/openrisc/cpu.h|   2 +-
 target/ppc/cpu.h |   4 +-
 target/riscv/cpu.h   |   2 +-
 target/s390x/internal.h  |   2 +-
 target/sh4/cpu.h |   2 +-
 target/sparc/cpu.h   |   2 +-
 target/xtensa/cpu.h  |   2 +-
 gdbstub.c| 936 +--
 hw/core/cpu.c|   2 +-
 target/alpha/gdbstub.c   |   2 +-
 target/arm/cpu.c |   7 +-
 target/arm/gdbstub.c | 173 -
 target/arm/gdbstub64.c   |   2 +-
 target/arm/helper.c  | 186 +-
 target/cris/gdbstub.c|   4 +-
 target/hppa/gdbstub.c|   2 +-
 target/i386/gdbstub.c|  29 +-
 target/lm32/gdbstub.c|   2 +-
 target/m68k/gdbstub.c|   2 +-
 target/m68k/helper.c |  33 +-
 target/microblaze/gdbstub.c  |   2 +-
 target/mips/gdbstub.c|   2 +-
 target/nios2/cpu.c   |   2 +-
 target/openrisc/gdbstub.c|   2 +-
 target/ppc/gdbstub.c |  48 +-
 target/ppc/translate_init.inc.c  |  54 +-
 target/riscv/gdbstub.c   |  20 +-
 target/s390x/gdbstub.c   |  30 +-
 target/sh4/gdbstub.c

[PULL 05/28] travis.yml: Set G_MESSAGES_DEBUG do report GLib errors

2020-03-17 Thread Alex Bennée
From: Philippe Mathieu-Daudé 

Since commit f5852efa293 we can display GLib errors with the QEMU
error reporting API. Set it to the 'error' level, as this helps
understanding failures from QEMU calls to GLib on Travis-CI.

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Alex Bennée 
Message-Id: <20200316101544.22361-1-phi...@redhat.com>
Message-Id: <20200316172155.971-6-alex.ben...@linaro.org>

diff --git a/.travis.yml b/.travis.yml
index b92798ac3b9..ccf68aa9abc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -79,6 +79,7 @@ env:
 - 
MAIN_SOFTMMU_TARGETS="aarch64-softmmu,mips64-softmmu,ppc64-softmmu,riscv64-softmmu,s390x-softmmu,x86_64-softmmu"
 - CCACHE_SLOPPINESS="include_file_ctime,include_file_mtime"
 - CCACHE_MAXSIZE=1G
+- G_MESSAGES_DEBUG=error
 
 
 git:
-- 
2.20.1




[PULL 02/28] tests/docker: Update VirGL git repository URL

2020-03-17 Thread Alex Bennée
From: Philippe Mathieu-Daudé 

freedesktop.org is moving to a GitLab instance,
use the new url.

- https://www.fooishbar.org/blog/gitlab-fdo-introduction/
- https://gitlab.freedesktop.org/freedesktop/freedesktop/-/wikis/home

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Alex Bennée 
Message-Id: <20200212202709.12665-2-phi...@redhat.com>
Message-Id: <20200316172155.971-3-alex.ben...@linaro.org>

diff --git a/tests/docker/dockerfiles/debian-amd64.docker 
b/tests/docker/dockerfiles/debian-amd64.docker
index 3b860af1068..b67fad54cb7 100644
--- a/tests/docker/dockerfiles/debian-amd64.docker
+++ b/tests/docker/dockerfiles/debian-amd64.docker
@@ -27,7 +27,7 @@ RUN apt update && \
 libegl1-mesa-dev \
 libepoxy-dev \
 libgbm-dev
-RUN git clone https://anongit.freedesktop.org/git/virglrenderer.git 
/usr/src/virglrenderer && \
+RUN git clone https://gitlab.freedesktop.org/virgl/virglrenderer.git 
/usr/src/virglrenderer && \
 cd /usr/src/virglrenderer && git checkout virglrenderer-0.7.0
 RUN cd /usr/src/virglrenderer && ./autogen.sh && ./configure --with-glx 
--disable-tests && make install
 
-- 
2.20.1




[PATCH 1/1] conf: qemu 9pfs: add 'multidevs' option

2020-03-17 Thread Christian Schoenebeck
Introduce new 'multidevs' option for filesystem.

  


  

This option prevents misbheaviours on guest if a 9pfs export
contains multiple devices, due to the potential file ID collisions
this otherwise may cause.

Signed-off-by: Christian Schoenebeck 
---
 docs/formatdomain.html.in | 47 ++-
 docs/schemas/domaincommon.rng | 10 
 src/conf/domain_conf.c| 30 ++
 src/conf/domain_conf.h| 13 ++
 src/qemu/qemu_command.c   |  7 ++
 5 files changed, 106 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 594146009d..13c506988b 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3967,7 +3967,7 @@
 source name='my-vm-template'/
 target dir='/'/
   /filesystem
-  filesystem type='mount' accessmode='passthrough'
+  filesystem type='mount' accessmode='passthrough' multidevs='remap'
 driver type='path' wrpolicy='immediate'/
 source dir='/export/to/guest'/
 target dir='/import/from/host'/
@@ -4084,13 +4084,58 @@
 
 
 
+  
   Since 5.2.0, the filesystem element
   has an optional attribute model with supported values
   "virtio-transitional", "virtio-non-transitional", or "virtio".
   See Virtio transitional devices
   for more details.
+  
+
+  
+  The filesystem element has an optional attribute multidevs
+  which specifies how to deal with a filesystem export containing more than
+  one device, in order to avoid file ID collisions on guest when using 9pfs
+  (since 6.2.0, requires QEMU 4.2).
+  This attribute is not available for virtiofs. The possible values are:
+  
+
+
+default
+
+Use QEMU's default setting (which currently is warn).
+
+remap
+
+This setting allows guest to access multiple devices per export without
+encountering misbehaviours. Inode numbers from host are automatically
+remapped on guest to actively prevent file ID collisions if guest
+accesses one export containing multiple devices.
+
+forbid
+
+Only allow to access one device per export by guest. Attempts to access
+additional devices on the same export will cause the individual
+filesystem access by guest to fail with an error and being logged 
(once)
+as error on host side.
+
+warn
+
+This setting resembles the behaviour of 9pfs prior to QEMU 4.2, that is
+no action is performed to prevent any potential file ID collisions if 
an
+export contains multiple devices, with the only exception: a warning is
+logged (once) on host side now. This setting may lead to misbehaviours
+on guest side if more than one device is exported per export, due to 
the
+potential file ID collisions this may cause on guest side in that case.
+
+
+
   
 
+  
+  The filesystem element may contain the following 
subelements:
+  
+
   driver
   
 The optional driver element allows specifying further details
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 6805420451..9b37740e30 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2676,6 +2676,16 @@
 
   
 
+
+  
+
+  default
+  remap
+  forbid
+  warn
+
+  
+
 
   
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 71535f53f5..b96f87063a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -501,6 +501,14 @@ VIR_ENUM_IMPL(virDomainFSModel,
   "virtio-non-transitional",
 );
 
+VIR_ENUM_IMPL(virDomainFSMultidevs,
+  VIR_DOMAIN_FS_MULTIDEVS_LAST,
+  "default",
+  "remap",
+  "forbid",
+  "warn",
+);
+
 VIR_ENUM_IMPL(virDomainFSCacheMode,
   VIR_DOMAIN_FS_CACHE_MODE_LAST,
   "default",
@@ -11376,6 +11384,7 @@ virDomainFSDefParseXML(virDomainXMLOptionPtr xmlopt,
 g_autofree char *usage = NULL;
 g_autofree char *units = NULL;
 g_autofree char *model = NULL;
+g_autofree char *multidevs = NULL;
 
 ctxt->node = node;
 
@@ -11414,6 +11423,17 @@ virDomainFSDefParseXML(virDomainXMLOptionPtr xmlopt,
 }
 }
 
+multidevs = virXMLPropString(node, "multidevs");
+if (multidevs) {
+if ((def->multidevs = virDomainFSMultidevsTypeFromString(multidevs)) < 
0) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _("unknown multidevs '%s'"), multidevs);
+goto error;
+}
+} else {
+def->multidevs = VIR_DOMAIN_FS_MULTIDEVS_DEFAULT;
+}
+
 if 

[PATCH 0/1] add support for QEMU 9pfs 'multidevs' option

2020-03-17 Thread Christian Schoenebeck
QEMU 4.2 added a new option 'multidevs' for 9pfs. The following patch adds
support for this new option to libvirt.

In short, what is this about: to distinguish files uniquely from each other
in general, numeric file IDs are typically used for comparison, which in
practice is the combination of a file's device ID and the file's inode
number. Unfortunately 9p protocol's QID field used for this purpose,
currently is too small to fit both the device ID and inode number in, which
hence is a problem if one 9pfs export contains multiple devices and may
thus lead to misbheaviours on guest (e.g. with SAMBA file servers) in that
case due to potential file ID collisions.

To mitigate this problem with 9pfs a 'multidevs' option was introduced in
QEMU 4.2 for defining how to deal with this, e.g. multidevs=remap will cause
QEMU's 9pfs implementation to remap all inodes from host side to different
inode numbers on guest side in a way that prevents file ID collisions.

NOTE: In the libvirt docs changes of this libvirt patch I simply assumed
"since 6.2.0". So the final libvirt version number would need to be adjusted
in that text if necessary.

See QEMU discussion with following Message-ID for details:
8a2ffe17fda3a86b9a5a437e1245276881f1e235.1567680121.git.qemu_...@crudebyte.com

Christian Schoenebeck (1):
  conf: qemu 9pfs: add 'multidevs' option

 docs/formatdomain.html.in | 47 ++-
 docs/schemas/domaincommon.rng | 10 
 src/conf/domain_conf.c| 30 ++
 src/conf/domain_conf.h| 13 ++
 src/qemu/qemu_command.c   |  7 ++
 5 files changed, 106 insertions(+), 1 deletion(-)

-- 
2.20.1




Re: [PATCH] i386/kvm: Add CPU property to expose VMware CPUID signature

2020-03-17 Thread Liran Alon

Gentle ping (A week have passed since submission).

Thanks,
-Liran

On 10/03/2020 2:40, Liran Alon wrote:

Some guests are only familiar with VMware PV interface. Therefore, in
order for these guests to run properly on KVM, we need to be able to
expose VMware main CPUID leaf. i.e. leaf 0x4000.

E.g. Without exposing this VMware CPUID leaf, some guests will fail to boot.
For example, because of guest attempt to calibrate TSC.

Signed-off-by: Liran Alon 
---
  target/i386/cpu.c |  1 +
  target/i386/cpu.h |  1 +
  target/i386/kvm.c | 35 +--
  3 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 92fafa265914..694766d45a9b 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -7127,6 +7127,7 @@ static Property x86_cpu_properties[] = {
  DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true),
  DEFINE_PROP_BOOL("kvm-no-smi-migration", X86CPU, kvm_no_smi_migration,
   false),
+DEFINE_PROP_BOOL("vmware-cpuid", X86CPU, expose_vmware, false),
  DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true),
  DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
  DEFINE_PROP_BOOL("x-migrate-smi-count", X86CPU, migrate_smi_count,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 9c7cd7cde107..bca626963e25 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1647,6 +1647,7 @@ struct X86CPU {
   */
  bool force_features;
  bool expose_kvm;
+bool expose_vmware;
  bool expose_tcg;
  bool migratable;
  bool migrate_smi_count;
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 00917196dffb..2656258b96b3 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -1187,6 +1187,15 @@ static int hyperv_handle_properties(CPUState *cs,
  if (!hyperv_enabled(cpu))
  return 0;
  
+/*

+ * VMware & Hyper-V conflicts in CPUID leafs.
+ * Therefore, they cannot exists together.
+ */
+if (cpu->expose_vmware) {
+error_report("vmware-cpuid not compatible with hyperv options");
+return -ENOTSUP;
+}
+
  if (hyperv_feat_enabled(cpu, HYPERV_FEAT_EVMCS) ||
  cpu->hyperv_passthrough) {
  uint16_t evmcs_version;
@@ -1508,6 +1517,18 @@ int kvm_arch_init_vcpu(CPUState *cs)
  has_msr_hv_hypercall = true;
  }
  
+if (cpu->expose_vmware) {

+c = _data.entries[cpuid_i++];
+c->function = KVM_CPUID_SIGNATURE;
+memcpy(signature, "VMwareVMware", 12);
+c->eax = KVM_CPUID_SIGNATURE;
+c->ebx = signature[0];
+c->ecx = signature[1];
+c->edx = signature[2];
+
+kvm_base = KVM_CPUID_SIGNATURE_NEXT;
+}
+
  if (cpu->expose_kvm) {
  memcpy(signature, "KVMKVMKVM\0\0\0", 12);
  c = _data.entries[cpuid_i++];
@@ -1791,11 +1812,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
  }
  }
  
-if (cpu->vmware_cpuid_freq

-/* Guests depend on 0x4000 to detect this feature, so only expose
- * it if KVM exposes leaf 0x4000. (Conflicts with Hyper-V) */
-&& cpu->expose_kvm
-&& kvm_base == KVM_CPUID_SIGNATURE
+if (cpu->vmware_cpuid_freq &&
+(cpu->expose_vmware ||
+ /*
+  * Guests depend on 0x4000 to detect this feature, so only expose
+  * it if KVM exposes leaf 0x4000. (Conflicts with Hyper-V)
+  */
+  (cpu->expose_kvm && kvm_base == KVM_CPUID_SIGNATURE))
  /* TSC clock must be stable and known for this feature. */
  && tsc_is_stable_and_known(env)) {
  
@@ -1805,7 +1828,7 @@ int kvm_arch_init_vcpu(CPUState *cs)

  c->ebx = env->apic_bus_freq / 1000; /* Hz to KHz */
  c->ecx = c->edx = 0;
  
-c = cpuid_find_entry(_data.cpuid, kvm_base, 0);

+c = cpuid_find_entry(_data.cpuid, KVM_CPUID_SIGNATURE, 0);
  c->eax = MAX(c->eax, KVM_CPUID_SIGNATURE | 0x10);
  }
  




Re: [PULL 06/15] configure: Enable test and libs for zstd

2020-03-17 Thread Juan Quintela
Peter Maydell  wrote:
> On Fri, 28 Feb 2020 at 09:28, Juan Quintela  wrote:
>>
>> Add it to several build systems to make testing good.
>>
>> Signed-off-by: Juan Quintela 
>> Reviewed-by: Dr. David Alan Gilbert 
>> ---
>>  .gitlab-ci.yml|  1 +
>>  .travis.yml   |  1 +
>>  configure | 30 +++
>>  tests/docker/dockerfiles/centos7.docker   |  3 +-
>>  .../dockerfiles/fedora-i386-cross.docker  |  3 +-
>>  tests/docker/dockerfiles/fedora.docker|  3 +-
>>  tests/docker/dockerfiles/ubuntu.docker|  1 +
>>  tests/docker/dockerfiles/ubuntu1804.docker|  1 +
>>  tests/vm/fedora   |  5 +++-
>>  tests/vm/freebsd  |  3 ++
>>  tests/vm/netbsd   |  3 ++
>>  tests/vm/openbsd  |  3 ++
>>  12 files changed, 53 insertions(+), 4 deletions(-)
>
> Hi; this patch changes some .docker files, but it has
> put the new line at the bottom of each package list,
> rather than at the correct point in the alphabetical
> order that the lists are in, for these 3 fedora/centos ones:

ok.

I mill send a patch for that.

Sorry, Juan.


>
>> diff --git a/tests/docker/dockerfiles/centos7.docker 
>> b/tests/docker/dockerfiles/centos7.docker
>> index 562d65be9e..cdd72de7eb 100644
>> --- a/tests/docker/dockerfiles/centos7.docker
>> +++ b/tests/docker/dockerfiles/centos7.docker
>> @@ -33,6 +33,7 @@ ENV PACKAGES \
>>  tar \
>>  vte-devel \
>>  xen-devel \
>> -zlib-devel
>> +zlib-devel \
>> +libzstd-devel
>>  RUN yum install -y $PACKAGES
>>  RUN rpm -q $PACKAGES | sort > /packages.txt
>> diff --git a/tests/docker/dockerfiles/fedora-i386-cross.docker 
>> b/tests/docker/dockerfiles/fedora-i386-cross.docker
>> index 9106cf9ebe..cd16cd1bfa 100644
>> --- a/tests/docker/dockerfiles/fedora-i386-cross.docker
>> +++ b/tests/docker/dockerfiles/fedora-i386-cross.docker
>> @@ -7,7 +7,8 @@ ENV PACKAGES \
>>  gnutls-devel.i686 \
>>  nettle-devel.i686 \
>>  pixman-devel.i686 \
>> -zlib-devel.i686
>> +zlib-devel.i686 \
>> +libzstd-devel.i686
>>
>>  RUN dnf install -y $PACKAGES
>>  RUN rpm -q $PACKAGES | sort > /packages.txt
>> diff --git a/tests/docker/dockerfiles/fedora.docker 
>> b/tests/docker/dockerfiles/fedora.docker
>> index 987a3c170a..a658c0 100644
>> --- a/tests/docker/dockerfiles/fedora.docker
>> +++ b/tests/docker/dockerfiles/fedora.docker
>> @@ -92,7 +92,8 @@ ENV PACKAGES \
>>  vte291-devel \
>>  which \
>>  xen-devel \
>> -zlib-devel
>> +zlib-devel \
>> +libzstd-devel
>>  ENV QEMU_CONFIGURE_OPTS --python=/usr/bin/python3
>>
>>  RUN dnf install -y $PACKAGES
>
> The ubuntu ones are OK though:
>
>> diff --git a/tests/docker/dockerfiles/ubuntu.docker
>> b/tests/docker/dockerfiles/ubuntu.docker
>> index 4177f33691..b6c7b41ddd 100644
>> --- a/tests/docker/dockerfiles/ubuntu.docker
>> +++ b/tests/docker/dockerfiles/ubuntu.docker
>> @@ -58,6 +58,7 @@ ENV PACKAGES flex bison \
>>  libvdeplug-dev \
>>  libvte-2.91-dev \
>>  libxen-dev \
>> +libzstd-dev \
>>  make \
>>  python3-yaml \
>>  python3-sphinx \
>> diff --git a/tests/docker/dockerfiles/ubuntu1804.docker
>> b/tests/docker/dockerfiles/ubuntu1804.docker
>> index 0766f94cf4..1efedeef99 100644
>> --- a/tests/docker/dockerfiles/ubuntu1804.docker
>> +++ b/tests/docker/dockerfiles/ubuntu1804.docker
>> @@ -44,6 +44,7 @@ ENV PACKAGES flex bison \
>>  libvdeplug-dev \
>>  libvte-2.91-dev \
>>  libxen-dev \
>> +libzstd-dev \
>>  make \
>>  python3-yaml \
>>  python3-sphinx \
>
>
> Could somebody send a patch that fixes up the ordering,
> please?
>
> thanks
> -- PMM




Re: [PULL 0/3] MIPS queue for March 17th, 2020

2020-03-17 Thread Peter Maydell
On Tue, 17 Mar 2020 at 13:04, Aleksandar Markovic
 wrote:
>
> From: Aleksandar Markovic 
>
> The following changes since commit a98135f727595382e200d04c2996e868b7925a01:
>
>   Merge remote-tracking branch 
> 'remotes/kraxel/tags/vga-20200316-pull-request' into staging (2020-03-16 
> 14:55:59 +)
>
> are available in the git repository at:
>
>   https://github.com/AMarkovic/qemu tags/mips-queue-mar-17-2020
>
> for you to fetch changes up to c0ac595b69a71fe04529b05406b7aa958b7efb99:
>
>   MAINTAINERS: Add a file to the main MIPS section (2020-03-17 13:51:37 +0100)
>
> 
>
> MIPS queue for March 17th, 2020
>
>   - maintaining and enhancing MIPS maintainership
>


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/5.0
for any user-visible changes.

-- PMM



Re: "guest-reset" and "invalid runstate transition" in COLO SVM

2020-03-17 Thread Jing-Wei Su
Hello,

I'm not sure whether the commit
(https://github.com/qemu/qemu/commit/f51d0b4178738bba87d796eba7444f6cdb3aa0fd)
can patch
to qemu-4.1.0 or qemu-4.2.0 directly.
After going through the COLO flow, the commit seems an individual
patch and to resolve  double-allocate colo_cache issue, right?
Or, it depends on other commits?

In my experiment, qemu-4.1.0/4.2.0 with the patch has a high
probability of the crash of SVM.

Thanks.
Sincerely,
JW

Jing-Wei Su  於 2020年3月17日 週二 下午5:19寫道:
>
> Hello,
>
> I'm testing  COLO in qemu-4.2.0 with the commit
> https://github.com/qemu/qemu/commit/f51d0b4178738bba87d796eba7444f6cdb3aa0fd.
>
> The qmp of SVM sometimes show the following errors ("guest-reset"
> or/and "invalid runstate transition") .
> Does any have idea about this?
>
> {"timestamp": {"seconds": 1584435907, "microseconds": 610964},
> "event": "RESUME"}
> {"timestamp": {"seconds": 1584435927, "microseconds": 553683}, "event": 
> "STOP"}
> {"timestamp": {"seconds": 1584435980, "microseconds": 533344},
> "event": "RESUME"}
> {"timestamp": {"seconds": 1584435980, "microseconds": 579256},
> "event": "RESET", "data": {"guest": true, "reason": "guest-reset"}}
> {"timestamp": {"seconds": 1584435980, "microseconds": 588350}, "event": 
> "STOP"}
> {"timestamp": {"seconds": 1584435980, "microseconds": 801483},
> "event": "RESUME"}
> {"timestamp": {"seconds": 1584435980, "microseconds": 802061}, "event": 
> "STOP"}
> {"timestamp": {"seconds": 1584435980, "microseconds": 803988},
> "event": "RESET", "data": {"guest": true, "reason": "guest-reset"}}
> qemu-system-x86_64: invalid runstate transition: 'colo' -> 'prelaunch'
> secondary-nonshared.sh: line 25: 23457 Aborted (core
> dumped) qemu-system-x86_64 -name secondary -enable-kvm -cpu
> qemu64,+kvmclock -m 2048 -global kvm-apic.vapic=false -netdev
> tap,id=hn0,vhost=off,helper=/usr/local/libexec/qemu-bridge-helper
> -device e1000,id=e0,netdev=hn0 -chardev
> socket,id=red0,host=$primary_ip,port=9003,reconnect=1 -chardev
> socket,id=red1,host=$primary_ip,port=9004,reconnect=1 -object
> filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0 -object
> filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1 -object
> filter-rewriter,id=rew0,netdev=hn0,queue=all -drive
> if=none,id=parent0,file.filename=$imagefolder/secondary.qcow2,driver=qcow2
> -drive 
> if=none,id=childs0,driver=replication,mode=secondary,file.driver=qcow2,top-id=colo-disk0,file.file.filename=$imagefolder/secondary-active.qcow2,file.backing.driver=qcow2,file.backing.file.filename=$imagefolder/secondary-hidden.qcow2,file.backing.backing=parent0
> -drive 
> if=ide,id=colo-disk0,driver=quorum,read-pattern=fifo,vote-threshold=1,children.0=childs0
> -qmp unix:/tmp/qmp-svm-sock,server,nowait -qmp stdio -vnc :5 -incoming
> tcp:0.0.0.0:9998
>
> My PVM and SVM are on the same PC.
> Here are the steps to setup my testing
> (1) Start PVM
> qemu-system-x86_64 -name primary -enable-kvm -cpu qemu64,+kvmclock -m
> 2048 -global kvm-apic.vapic=false \
> -netdev tap,id=hn0,vhost=off,helper=/usr/local/libexec/qemu-bridge-helper \
> -device e1000,id=e0,netdev=hn0 \
> -drive 
> if=ide,id=colo-disk0,driver=quorum,read-pattern=fifo,vote-threshold=1,children.0.file.filename=$imagefolder/primary.qcow2,children.0.driver=qcow2
> \
> -qmp stdio -vnc :4
>
> (2) Add chardevs to PVM via qmp
> {'execute': 'qmp_capabilities'}
> {'execute': 'chardev-add', 'arguments':{ 'id': 'mirror0', 'backend':
> {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': {
> 'host': '0.0.0.0', 'port': '9003' } }, 'server': true } } } }
> {'execute': 'chardev-add', 'arguments':{ 'id': 'compare1', 'backend':
> {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': {
> 'host': '0.0.0.0', 'port': '9004' } }, 'server': true } } } }
> {'execute': 'chardev-add', 'arguments':{ 'id': 'compare0', 'backend':
> {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': {
> 'host': '127.0.0.1', 'port': '9001' } }, 'server': true } } } }
> {'execute': 'chardev-add', 'arguments':{ 'id': 'compare0-0',
> 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet',
> 'data': { 'host': '127.0.0.1', 'port': '9001' } }, 'server': false } }
> } }
> {'execute': 'chardev-add', 'arguments':{ 'id': 'compare_out',
> 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet',
> 'data': { 'host': '127.0.0.1', 'port': '9005' } }, 'server': true } }
> } }
> {'execute': 'chardev-add', 'arguments':{ 'id': 'compare_out0',
> 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet',
> 'data': { 'host': '127.0.0.1', 'port': '9005' } }, 'server': false } }
> } }
>
> (3) Start SVM
> primary_ip=127.0.0.1
> qemu-system-x86_64 -name secondary -enable-kvm -cpu qemu64,+kvmclock
> -m 2048 -global kvm-apic.vapic=false \
> -netdev tap,id=hn0,vhost=off,helper=/usr/local/libexec/qemu-bridge-helper \
> -device e1000,id=e0,netdev=hn0 \
> -chardev socket,id=red0,host=$primary_ip,port=9003,reconnect=1 \
> -chardev 

[Bug 1867786] Re: Qemu PPC64 freezes with multi-core CPU

2020-03-17 Thread Laurent Vivier
Do you have the problem with 4.2.0?
Can you identify the commit introducing the problem?

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

Title:
  Qemu PPC64 freezes with multi-core CPU

Status in QEMU:
  New

Bug description:
  I installed Debian 10 on a Qemu PPC64 VM running with the following
  flags:

  qemu-system-ppc64 \
   -nographic -nodefaults -monitor pty -serial stdio \
   -M pseries -cpu POWER9 -smp cores=4,threads=1 -m 4G \
   -drive file=debian-ppc64el-qemu.qcow2,format=qcow2,if=virtio \
   -netdev user,id=network01,$ports -device rtl8139,netdev=network01 \

  
  Within a couple minutes on any operation (could be a Go application or simply 
changing the hostname with hostnamectl, the VM freezes and prints this on the 
console:

  ```
  root@debian:~# [  950.428255] rcu: INFO: rcu_sched self-detected stall on CPU
  [  950.428453] rcu: 3-: (5318 ticks this GP) 
idle=8e2/1/0x4004 softirq=5957/5960 fqs=2544
  [  976.244481] watchdog: BUG: soft lockup - CPU#3 stuck for 23s! [zsh:462]

  Message from syslogd@debian at Mar 17 11:35:24 ...
   kernel:[  976.244481] watchdog: BUG: soft lockup - CPU#3 stuck for 23s! 
[zsh:462]
  [  980.110018] rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: 
{ 3-... } 5276 jiffies s: 93 root: 0x8/.
  [  980.77] rcu: blocking rcu_node structures:
  [ 1013.442268] rcu: INFO: rcu_sched self-detected stall on CPU
  [ 1013.442365] rcu: 3-: (21071 ticks this GP) 
idle=8e2/1/0x4004 softirq=5957/5960 fqs=9342
  ```

  If I change to 1 core on the command line, I haven't seen these
  freezes.

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



[Bug 1867786] Re: Qemu PPC64 freezes with multi-core CPU

2020-03-17 Thread carlosedp
It's soft emulation, running Qemu 4.2.50 (from master branch) on MacOS
Mojave.

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

Title:
  Qemu PPC64 freezes with multi-core CPU

Status in QEMU:
  New

Bug description:
  I installed Debian 10 on a Qemu PPC64 VM running with the following
  flags:

  qemu-system-ppc64 \
   -nographic -nodefaults -monitor pty -serial stdio \
   -M pseries -cpu POWER9 -smp cores=4,threads=1 -m 4G \
   -drive file=debian-ppc64el-qemu.qcow2,format=qcow2,if=virtio \
   -netdev user,id=network01,$ports -device rtl8139,netdev=network01 \

  
  Within a couple minutes on any operation (could be a Go application or simply 
changing the hostname with hostnamectl, the VM freezes and prints this on the 
console:

  ```
  root@debian:~# [  950.428255] rcu: INFO: rcu_sched self-detected stall on CPU
  [  950.428453] rcu: 3-: (5318 ticks this GP) 
idle=8e2/1/0x4004 softirq=5957/5960 fqs=2544
  [  976.244481] watchdog: BUG: soft lockup - CPU#3 stuck for 23s! [zsh:462]

  Message from syslogd@debian at Mar 17 11:35:24 ...
   kernel:[  976.244481] watchdog: BUG: soft lockup - CPU#3 stuck for 23s! 
[zsh:462]
  [  980.110018] rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: 
{ 3-... } 5276 jiffies s: 93 root: 0x8/.
  [  980.77] rcu: blocking rcu_node structures:
  [ 1013.442268] rcu: INFO: rcu_sched self-detected stall on CPU
  [ 1013.442365] rcu: 3-: (21071 ticks this GP) 
idle=8e2/1/0x4004 softirq=5957/5960 fqs=9342
  ```

  If I change to 1 core on the command line, I haven't seen these
  freezes.

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



Re: [PULL 06/15] configure: Enable test and libs for zstd

2020-03-17 Thread Peter Maydell
On Fri, 28 Feb 2020 at 09:28, Juan Quintela  wrote:
>
> Add it to several build systems to make testing good.
>
> Signed-off-by: Juan Quintela 
> Reviewed-by: Dr. David Alan Gilbert 
> ---
>  .gitlab-ci.yml|  1 +
>  .travis.yml   |  1 +
>  configure | 30 +++
>  tests/docker/dockerfiles/centos7.docker   |  3 +-
>  .../dockerfiles/fedora-i386-cross.docker  |  3 +-
>  tests/docker/dockerfiles/fedora.docker|  3 +-
>  tests/docker/dockerfiles/ubuntu.docker|  1 +
>  tests/docker/dockerfiles/ubuntu1804.docker|  1 +
>  tests/vm/fedora   |  5 +++-
>  tests/vm/freebsd  |  3 ++
>  tests/vm/netbsd   |  3 ++
>  tests/vm/openbsd  |  3 ++
>  12 files changed, 53 insertions(+), 4 deletions(-)

Hi; this patch changes some .docker files, but it has
put the new line at the bottom of each package list,
rather than at the correct point in the alphabetical
order that the lists are in, for these 3 fedora/centos ones:

> diff --git a/tests/docker/dockerfiles/centos7.docker 
> b/tests/docker/dockerfiles/centos7.docker
> index 562d65be9e..cdd72de7eb 100644
> --- a/tests/docker/dockerfiles/centos7.docker
> +++ b/tests/docker/dockerfiles/centos7.docker
> @@ -33,6 +33,7 @@ ENV PACKAGES \
>  tar \
>  vte-devel \
>  xen-devel \
> -zlib-devel
> +zlib-devel \
> +libzstd-devel
>  RUN yum install -y $PACKAGES
>  RUN rpm -q $PACKAGES | sort > /packages.txt
> diff --git a/tests/docker/dockerfiles/fedora-i386-cross.docker 
> b/tests/docker/dockerfiles/fedora-i386-cross.docker
> index 9106cf9ebe..cd16cd1bfa 100644
> --- a/tests/docker/dockerfiles/fedora-i386-cross.docker
> +++ b/tests/docker/dockerfiles/fedora-i386-cross.docker
> @@ -7,7 +7,8 @@ ENV PACKAGES \
>  gnutls-devel.i686 \
>  nettle-devel.i686 \
>  pixman-devel.i686 \
> -zlib-devel.i686
> +zlib-devel.i686 \
> +libzstd-devel.i686
>
>  RUN dnf install -y $PACKAGES
>  RUN rpm -q $PACKAGES | sort > /packages.txt
> diff --git a/tests/docker/dockerfiles/fedora.docker 
> b/tests/docker/dockerfiles/fedora.docker
> index 987a3c170a..a658c0 100644
> --- a/tests/docker/dockerfiles/fedora.docker
> +++ b/tests/docker/dockerfiles/fedora.docker
> @@ -92,7 +92,8 @@ ENV PACKAGES \
>  vte291-devel \
>  which \
>  xen-devel \
> -zlib-devel
> +zlib-devel \
> +libzstd-devel
>  ENV QEMU_CONFIGURE_OPTS --python=/usr/bin/python3
>
>  RUN dnf install -y $PACKAGES

The ubuntu ones are OK though:

> diff --git a/tests/docker/dockerfiles/ubuntu.docker 
> b/tests/docker/dockerfiles/ubuntu.docker
> index 4177f33691..b6c7b41ddd 100644
> --- a/tests/docker/dockerfiles/ubuntu.docker
> +++ b/tests/docker/dockerfiles/ubuntu.docker
> @@ -58,6 +58,7 @@ ENV PACKAGES flex bison \
>  libvdeplug-dev \
>  libvte-2.91-dev \
>  libxen-dev \
> +libzstd-dev \
>  make \
>  python3-yaml \
>  python3-sphinx \
> diff --git a/tests/docker/dockerfiles/ubuntu1804.docker 
> b/tests/docker/dockerfiles/ubuntu1804.docker
> index 0766f94cf4..1efedeef99 100644
> --- a/tests/docker/dockerfiles/ubuntu1804.docker
> +++ b/tests/docker/dockerfiles/ubuntu1804.docker
> @@ -44,6 +44,7 @@ ENV PACKAGES flex bison \
>  libvdeplug-dev \
>  libvte-2.91-dev \
>  libxen-dev \
> +libzstd-dev \
>  make \
>  python3-yaml \
>  python3-sphinx \


Could somebody send a patch that fixes up the ordering,
please?

thanks
-- PMM



[PATCH v6 61/61] target/riscv: configure and turn on vector extension from command line

2020-03-17 Thread LIU Zhiwei
Vector extension is default off. The only way to use vector extension is
1. use cpu rv32 or rv64
2. turn on it by command line
"-cpu rv64,x-v=true,vlen=128,elen=64,vext_spec=v0.7.1".

vlen is the vector register length, default value is 128 bit.
elen is the max operator size in bits, default value is 64 bit.
vext_spec is the vector specification version, default value is v0.7.1.
These properties can be specified with other values.

Signed-off-by: LIU Zhiwei 
---
 target/riscv/cpu.c | 44 +++-
 target/riscv/cpu.h |  2 ++
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6e4135583d..92cbcf1a2d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -395,7 +395,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 
 set_priv_version(env, priv_version);
-set_vext_version(env, vext_version);
 set_resetvec(env, DEFAULT_RSTVEC);
 
 if (cpu->cfg.mmu) {
@@ -463,6 +462,45 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 if (cpu->cfg.ext_h) {
 target_misa |= RVH;
 }
+if (cpu->cfg.ext_v) {
+target_misa |= RVV;
+if (!is_power_of_2(cpu->cfg.vlen)) {
+error_setg(errp,
+"Vector extension VLEN must be power of 2");
+return;
+}
+if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) {
+error_setg(errp,
+"Vector extension implementation only supports VLEN "
+"in the range [128, %d]", RV_VLEN_MAX);
+return;
+}
+if (!is_power_of_2(cpu->cfg.elen)) {
+error_setg(errp,
+"Vector extension ELEN must be power of 2");
+return;
+}
+if (cpu->cfg.elen > 64 || cpu->cfg.vlen < 8) {
+error_setg(errp,
+"Vector extension implementation only supports ELEN "
+"in the range [8, 64]");
+return;
+}
+if (cpu->cfg.vext_spec) {
+if (!g_strcmp0(cpu->cfg.vext_spec, "v0.7.1")) {
+vext_version = VEXT_VERSION_0_07_1;
+} else {
+error_setg(errp,
+   "Unsupported vector spec version '%s'",
+   cpu->cfg.vext_spec);
+return;
+}
+} else {
+qemu_log("vector verison is not specified, "
+"use the default value v0.7.1\n");
+}
+set_vext_version(env, vext_version);
+}
 
 set_misa(env, RVXLEN | target_misa);
 }
@@ -500,10 +538,14 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
 /* This is experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
+DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false),
 DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
 DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
 DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
 DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
+DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
+DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
+DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
 DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
 DEFINE_PROP_END_OF_LIST(),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index f42f075024..42ab0f141a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -285,12 +285,14 @@ typedef struct RISCVCPU {
 bool ext_s;
 bool ext_u;
 bool ext_h;
+bool ext_v;
 bool ext_counters;
 bool ext_ifencei;
 bool ext_icsr;
 
 char *priv_spec;
 char *user_spec;
+char *vext_spec;
 uint16_t vlen;
 uint16_t elen;
 bool mmu;
-- 
2.23.0




[PATCH v6 60/61] target/riscv: vector compress instruction

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   |  5 +
 target/riscv/insn32.decode  |  1 +
 target/riscv/insn_trans/trans_rvv.inc.c | 28 +
 target/riscv/vector_helper.c| 28 +
 4 files changed, 62 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index d07b416c33..db4dc41781 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1144,3 +1144,8 @@ DEF_HELPER_6(vrgather_vx_b, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(vrgather_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vrgather_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vrgather_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(vcompress_vm_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vcompress_vm_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vcompress_vm_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vcompress_vm_d, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index e07ff7eff6..a37e205eb7 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -575,6 +575,7 @@ vslide1down_vx  00 . . . 110 . 1010111 @r_vm
 vrgather_vv 001100 . . . 000 . 1010111 @r_vm
 vrgather_vx 001100 . . . 100 . 1010111 @r_vm
 vrgather_vi 001100 . . . 011 . 1010111 @r_vm
+vcompress_vm010111 - . . 010 . 1010111 @r
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index f781372b50..889c7f1ca5 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2680,3 +2680,31 @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr 
*a)
 }
 return true;
 }
+
+/* Vector Compress Instruction */
+static bool vcompress_vm_check(DisasContext *s, arg_r *a)
+{
+return (vext_check_isa_ill(s) &&
+vext_check_reg(s, a->rd, false) &&
+vext_check_reg(s, a->rs2, false) &&
+vext_check_overlap_group(a->rd, 1 << s->lmul, a->rs1, 1) &&
+(a->rd != a->rs2));
+}
+
+static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
+{
+if (vcompress_vm_check(s, a)) {
+uint32_t data = 0;
+static gen_helper_gvec_4_ptr * const fns[4] = {
+gen_helper_vcompress_vm_b, gen_helper_vcompress_vm_h,
+gen_helper_vcompress_vm_w, gen_helper_vcompress_vm_d,
+};
+data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
+vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2),
+cpu_env, 0, s->vlen / 8, data, fns[s->sew]);
+return true;
+}
+return false;
+}
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 30620284cc..90f51339e8 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4898,3 +4898,31 @@ GEN_VEXT_VRGATHER_VX(vrgather_vx_b, uint8_t, H1, clearb)
 GEN_VEXT_VRGATHER_VX(vrgather_vx_h, uint16_t, H2, clearh)
 GEN_VEXT_VRGATHER_VX(vrgather_vx_w, uint32_t, H4, clearl)
 GEN_VEXT_VRGATHER_VX(vrgather_vx_d, uint64_t, H8, clearq)
+
+/* Vector Compress Instruction */
+#define GEN_VEXT_VCOMPRESS_VM(NAME, ETYPE, H, CLEAR_FN)   \
+void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2,   \
+CPURISCVState *env, uint32_t desc)\
+{ \
+uint32_t mlen = vext_mlen(desc);  \
+uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen;   \
+uint32_t vl = env->vl;\
+uint32_t num = 0, i;  \
+  \
+if (vl == 0) {\
+return;   \
+} \
+for (i = 0; i < vl; i++) {\
+if (!vext_elem_mask(vs1, mlen, i)) {  \
+continue; \
+} \
+*((ETYPE *)vd + H(num)) = *((ETYPE *)vs2 + H(i)); \
+num++;\
+} \
+CLEAR_FN(vd, num, num * sizeof(ETYPE), vlmax 

[PATCH v6 59/61] target/riscv: vector register gather instruction

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
---
 target/riscv/helper.h   |   9 ++
 target/riscv/insn32.decode  |   3 +
 target/riscv/insn_trans/trans_rvv.inc.c | 127 
 target/riscv/vector_helper.c|  64 
 4 files changed, 203 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 3b1612012c..d07b416c33 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1135,3 +1135,12 @@ DEF_HELPER_6(vslide1down_vx_b, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(vslide1down_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vslide1down_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vslide1down_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(vrgather_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrgather_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrgather_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrgather_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrgather_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vrgather_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vrgather_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vrgather_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 34ccad53a9..e07ff7eff6 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -572,6 +572,9 @@ vslide1up_vx001110 . . . 110 . 1010111 @r_vm
 vslidedown_vx   00 . . . 100 . 1010111 @r_vm
 vslidedown_vi   00 . . . 011 . 1010111 @r_vm
 vslide1down_vx  00 . . . 110 . 1010111 @r_vm
+vrgather_vv 001100 . . . 000 . 1010111 @r_vm
+vrgather_vx 001100 . . . 100 . 1010111 @r_vm
+vrgather_vi 001100 . . . 011 . 1010111 @r_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 10482fd1d4..f781372b50 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2553,3 +2553,130 @@ GEN_OPIVI_TRANS(vslideup_vi, 1, vslideup_vx, 
slideup_check)
 GEN_OPIVX_TRANS(vslidedown_vx, opivx_check)
 GEN_OPIVX_TRANS(vslide1down_vx, opivx_check)
 GEN_OPIVI_TRANS(vslidedown_vi, 1, vslidedown_vx, opivx_check)
+
+/* Vector Register Gather Instruction */
+static bool vrgather_vv_check(DisasContext *s, arg_rmrr *a)
+{
+return (vext_check_isa_ill(s) &&
+vext_check_overlap_mask(s, a->rd, a->vm, true) &&
+vext_check_reg(s, a->rd, false) &&
+vext_check_reg(s, a->rs1, false) &&
+vext_check_reg(s, a->rs2, false) &&
+(a->rd != a->rs2) && (a->rd != a->rs1));
+}
+
+GEN_OPIVV_TRANS(vrgather_vv, vrgather_vv_check)
+
+static bool vrgather_vx_check(DisasContext *s, arg_rmrr *a)
+{
+return (vext_check_isa_ill(s) &&
+vext_check_overlap_mask(s, a->rd, a->vm, true) &&
+vext_check_reg(s, a->rd, false) &&
+vext_check_reg(s, a->rs2, false) &&
+(a->rd != a->rs2));
+}
+
+static void gather_element(TCGv_i64 dest, TCGv_ptr base,
+   int ofs, int sew)
+{
+switch (sew) {
+case MO_8:
+tcg_gen_ld8u_i64(dest, base, ofs);
+break;
+case MO_16:
+tcg_gen_ld16u_i64(dest, base, ofs);
+break;
+case MO_32:
+tcg_gen_ld32u_i64(dest, base, ofs);
+break;
+default:
+tcg_gen_ld_i64(dest, base, ofs);
+break;
+}
+}
+
+static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a)
+{
+if (!vrgather_vx_check(s, a)) {
+return false;
+}
+
+if (a->vm && s->vl_eq_vlmax) {
+int vlmax = s->vlen / s->mlen;
+TCGv_i32 ofs = tcg_temp_new_i32();
+TCGv_ptr base = tcg_temp_new_ptr();
+TCGv_i64 t_vlmax, t_zero, dest = tcg_temp_new_i64();
+TCGv s1 = tcg_temp_new();
+TCGv_i64 s1_i64 = tcg_temp_new_i64();
+
+/* Expand x[rs1] to TCGv_i64 */
+gen_get_gpr(s1, a->rs1);
+tcg_gen_extu_tl_i64(s1_i64, s1);
+tcg_temp_free(s1);
+
+/*
+ * Mask the index to the length so that we do
+ * not produce an out-of-range load.
+ */
+tcg_gen_extrl_i64_i32(ofs, s1_i64);
+tcg_gen_andi_i32(ofs, ofs, vlmax - 1);
+
+/* Convert the index to an offset. */
+endian_adjust(ofs, s->sew);
+tcg_gen_shli_i32(ofs, ofs, s->sew);
+
+/* Convert the index to a pointer. */
+tcg_gen_ext_i32_ptr(base, ofs);
+tcg_gen_add_ptr(base, base, cpu_env);
+
+/* Perform the load. */
+gather_element(dest, base,
+   vreg_ofs(s, a->rs2), s->sew);
+tcg_temp_free_ptr(base);
+tcg_temp_free_i32(ofs);
+
+/* Flush out-of-range indexing to 

[PATCH v6 58/61] target/riscv: vector slide instructions

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
---
 target/riscv/helper.h   |  17 
 target/riscv/insn32.decode  |   7 ++
 target/riscv/insn_trans/trans_rvv.inc.c |  17 
 target/riscv/vector_helper.c| 128 
 4 files changed, 169 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 044538aef9..3b1612012c 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1118,3 +1118,20 @@ DEF_HELPER_3(vmv_s_x_d, void, ptr, tl, env)
 DEF_HELPER_3(vfmv_s_f_h, void, ptr, i64, env)
 DEF_HELPER_3(vfmv_s_f_w, void, ptr, i64, env)
 DEF_HELPER_3(vfmv_s_f_d, void, ptr, i64, env)
+
+DEF_HELPER_6(vslideup_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslideup_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslideup_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslideup_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslidedown_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslidedown_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslidedown_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslidedown_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslide1up_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslide1up_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslide1up_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslide1up_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslide1down_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslide1down_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslide1down_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vslide1down_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 79f9b37b29..34ccad53a9 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -72,6 +72,7 @@
 @r2_vm   .. vm:1 . . ... . ...  %rs2 %rd
 @r1_vm   .. vm:1 . . ... . ... %rd
 @r_nfvm  ... ... vm:1 . . ... . ...  %nf %rs2 %rs1 %rd
+@r2rd...   . . ... . ... %rs2 %rd
 @r_vm.. vm:1 . . ... . ...  %rs2 %rs1 %rd
 @r_vm_1  .. . . . ... . ... vm=1 %rs2 %rs1 %rd
 @r_vm_0  .. . . . ... . ... vm=0 %rs2 %rs1 %rd
@@ -565,6 +566,12 @@ vext_x_v001100 1 . . 010 . 1010111 @r
 vmv_s_x 001101 1 0 . 110 . 1010111 @r2
 vfmv_f_s001100 1 . 0 001 . 1010111 @r2rd
 vfmv_s_f001101 1 0 . 101 . 1010111 @r2
+vslideup_vx 001110 . . . 100 . 1010111 @r_vm
+vslideup_vi 001110 . . . 011 . 1010111 @r_vm
+vslide1up_vx001110 . . . 110 . 1010111 @r_vm
+vslidedown_vx   00 . . . 100 . 1010111 @r_vm
+vslidedown_vi   00 . . . 011 . 1010111 @r_vm
+vslide1down_vx  00 . . . 110 . 1010111 @r_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 07033662c3..10482fd1d4 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2536,3 +2536,20 @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f 
*a)
 }
 return false;
 }
+
+/* Vector Slide Instructions */
+static bool slideup_check(DisasContext *s, arg_rmrr *a)
+{
+return (vext_check_isa_ill(s) &&
+vext_check_overlap_mask(s, a->rd, a->vm, true) &&
+vext_check_reg(s, a->rd, false) &&
+vext_check_reg(s, a->rs2, false) &&
+(a->rd != a->rs2));
+}
+GEN_OPIVX_TRANS(vslideup_vx, slideup_check)
+GEN_OPIVX_TRANS(vslide1up_vx, slideup_check)
+GEN_OPIVI_TRANS(vslideup_vi, 1, vslideup_vx, slideup_check)
+
+GEN_OPIVX_TRANS(vslidedown_vx, opivx_check)
+GEN_OPIVX_TRANS(vslide1down_vx, opivx_check)
+GEN_OPIVI_TRANS(vslidedown_vi, 1, vslidedown_vx, opivx_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 723e15a670..b0439ac3d1 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4706,3 +4706,131 @@ void HELPER(NAME)(void *vd, uint64_t s1, CPURISCVState 
*env)\
 GEN_VEXT_VFMV_S_F(vfmv_s_f_h, uint16_t, H2, clearh)
 GEN_VEXT_VFMV_S_F(vfmv_s_f_w, uint32_t, H4, clearl)
 GEN_VEXT_VFMV_S_F(vfmv_s_f_d, uint64_t, H8, clearq)
+
+/* Vector Slide Instructions */
+#define GEN_VEXT_VSLIDEUP_VX(NAME, ETYPE, H, CLEAR_FN)\
+void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
+CPURISCVState *env, uint32_t desc)\
+{ \
+uint32_t mlen = vext_mlen(desc);  \
+uint32_t vlmax = env_archcpu(env)->cfg.vlen / 

Re: [PATCH v9] s390x: protvirt: Fence huge pages

2020-03-17 Thread Cornelia Huck
On Thu, 12 Mar 2020 12:25:10 -0400
Janosch Frank  wrote:

> Let's bail out of the protected transition if we detect that huge
> pages might be in use.
> 
> Signed-off-by: Janosch Frank 
> ---
> 
> I'd like to squash this into the unpack patch to give a proper error
> message if we try to transition into the protected mode while being
> backed by huge pages. 

Looks sane to me. Folding this into the unpack patch will probably
create less churn.

> 
> ---
>  hw/s390x/ipl.h | 16 
>  hw/s390x/s390-virtio-ccw.c |  1 -
>  target/s390x/diag.c| 23 ---
>  target/s390x/kvm-stub.c|  5 +
>  target/s390x/kvm.c |  5 +
>  target/s390x/kvm_s390x.h   |  1 +
>  6 files changed, 35 insertions(+), 16 deletions(-)




[PATCH v6 57/61] target/riscv: floating-point scalar move instructions

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
---
 target/riscv/helper.h   |  4 ++
 target/riscv/insn32.decode  |  2 +
 target/riscv/insn_trans/trans_rvv.inc.c | 72 +
 target/riscv/vector_helper.c| 15 ++
 4 files changed, 93 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 2e3bfdf1dc..044538aef9 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1114,3 +1114,7 @@ DEF_HELPER_3(vmv_s_x_b, void, ptr, tl, env)
 DEF_HELPER_3(vmv_s_x_h, void, ptr, tl, env)
 DEF_HELPER_3(vmv_s_x_w, void, ptr, tl, env)
 DEF_HELPER_3(vmv_s_x_d, void, ptr, tl, env)
+
+DEF_HELPER_3(vfmv_s_f_h, void, ptr, i64, env)
+DEF_HELPER_3(vfmv_s_f_w, void, ptr, i64, env)
+DEF_HELPER_3(vfmv_s_f_d, void, ptr, i64, env)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 0741a25540..79f9b37b29 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -563,6 +563,8 @@ viota_m 010110 . . 1 010 . 1010111 
@r2_vm
 vid_v   010110 . 0 10001 010 . 1010111 @r1_vm
 vext_x_v001100 1 . . 010 . 1010111 @r
 vmv_s_x 001101 1 0 . 110 . 1010111 @r2
+vfmv_f_s001100 1 . 0 001 . 1010111 @r2rd
+vfmv_s_f001101 1 0 . 101 . 1010111 @r2
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 4cf4e54d12..07033662c3 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2464,3 +2464,75 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x 
*a)
 }
 return false;
 }
+
+/* Floating-Point Scalar Move Instructions */
+static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a)
+{
+if (!s->vill && has_ext(s, RVF) &&
+(s->mstatus_fs != 0) && (s->sew != 0)) {
+#ifdef HOST_WORDS_BIGENDIAN
+int ofs = vreg_ofs(s, a->rs2) + ((7 >> s->sew) << s->sew);
+#else
+int ofs = vreg_ofs(s, a->rs2);
+#endif
+switch (s->sew) {
+case MO_8:
+tcg_gen_ld8u_i64(cpu_fpr[a->rd], cpu_env, ofs);
+tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd],
+0xff00ULL);
+break;
+case MO_16:
+tcg_gen_ld16u_i64(cpu_fpr[a->rd], cpu_env, ofs);
+tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd],
+0xULL);
+break;
+case MO_32:
+tcg_gen_ld32u_i64(cpu_fpr[a->rd], cpu_env, ofs);
+tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd],
+0xULL);
+break;
+default:
+if (has_ext(s, RVD)) {
+tcg_gen_ld_i64(cpu_fpr[a->rd], cpu_env, ofs);
+} else {
+tcg_gen_ld32u_i64(cpu_fpr[a->rd], cpu_env, ofs);
+tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd],
+0xULL);
+}
+break;
+}
+mark_fs_dirty(s);
+return true;
+}
+return false;
+}
+
+typedef void gen_helper_vfmv_s_f(TCGv_ptr, TCGv_i64, TCGv_env);
+static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
+{
+if (!s->vill && has_ext(s, RVF) && (s->sew != 0)) {
+TCGv_ptr dest;
+TCGv_i64 src1;
+static gen_helper_vfmv_s_f * const fns[3] = {
+gen_helper_vfmv_s_f_h,
+gen_helper_vfmv_s_f_w,
+gen_helper_vfmv_s_f_d
+};
+
+src1 = tcg_temp_new_i64();
+dest = tcg_temp_new_ptr();
+if (s->sew == MO_64 && !has_ext(s, RVD)) {
+tcg_gen_ori_i64(src1, cpu_fpr[a->rs1], 0xULL);
+} else {
+tcg_gen_mov_i64(src1, cpu_fpr[a->rs1]);
+}
+tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
+
+fns[s->sew - 1](dest, src1, cpu_env);
+
+tcg_temp_free_i64(src1);
+tcg_temp_free_ptr(dest);
+return true;
+}
+return false;
+}
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 7f67a283c9..723e15a670 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4691,3 +4691,18 @@ GEN_VEXT_VMV_S_X(vmv_s_x_b, uint8_t, H1, clearb)
 GEN_VEXT_VMV_S_X(vmv_s_x_h, uint16_t, H2, clearh)
 GEN_VEXT_VMV_S_X(vmv_s_x_w, uint32_t, H4, clearl)
 GEN_VEXT_VMV_S_X(vmv_s_x_d, uint64_t, H8, clearq)
+
+/* Floating-Point Scalar Move Instructions */
+#define GEN_VEXT_VFMV_S_F(NAME, ETYPE, H, CLEAR_FN) \
+void HELPER(NAME)(void *vd, uint64_t s1, CPURISCVState *env)\
+{   \
+if (env->vl == 0) { \
+return;

[Bug 1867786] Re: Qemu PPC64 freezes with multi-core CPU

2020-03-17 Thread Laurent Vivier
Is this with KVM or with TCG?
What is your hardware configuration?

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

Title:
  Qemu PPC64 freezes with multi-core CPU

Status in QEMU:
  New

Bug description:
  I installed Debian 10 on a Qemu PPC64 VM running with the following
  flags:

  qemu-system-ppc64 \
   -nographic -nodefaults -monitor pty -serial stdio \
   -M pseries -cpu POWER9 -smp cores=4,threads=1 -m 4G \
   -drive file=debian-ppc64el-qemu.qcow2,format=qcow2,if=virtio \
   -netdev user,id=network01,$ports -device rtl8139,netdev=network01 \

  
  Within a couple minutes on any operation (could be a Go application or simply 
changing the hostname with hostnamectl, the VM freezes and prints this on the 
console:

  ```
  root@debian:~# [  950.428255] rcu: INFO: rcu_sched self-detected stall on CPU
  [  950.428453] rcu: 3-: (5318 ticks this GP) 
idle=8e2/1/0x4004 softirq=5957/5960 fqs=2544
  [  976.244481] watchdog: BUG: soft lockup - CPU#3 stuck for 23s! [zsh:462]

  Message from syslogd@debian at Mar 17 11:35:24 ...
   kernel:[  976.244481] watchdog: BUG: soft lockup - CPU#3 stuck for 23s! 
[zsh:462]
  [  980.110018] rcu: INFO: rcu_sched detected expedited stalls on CPUs/tasks: 
{ 3-... } 5276 jiffies s: 93 root: 0x8/.
  [  980.77] rcu: blocking rcu_node structures:
  [ 1013.442268] rcu: INFO: rcu_sched self-detected stall on CPU
  [ 1013.442365] rcu: 3-: (21071 ticks this GP) 
idle=8e2/1/0x4004 softirq=5957/5960 fqs=9342
  ```

  If I change to 1 core on the command line, I haven't seen these
  freezes.

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



[PATCH v6 52/61] target/riscv: set-X-first mask bit

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   |  4 ++
 target/riscv/insn32.decode  |  3 ++
 target/riscv/insn_trans/trans_rvv.inc.c | 23 +
 target/riscv/vector_helper.c| 66 +
 4 files changed, 96 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index ec6cf7d2a2..3761b48eca 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1095,3 +1095,7 @@ DEF_HELPER_6(vmxnor_mm, void, ptr, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_4(vmpopc_m, tl, ptr, ptr, env, i32)
 
 DEF_HELPER_4(vmfirst_m, tl, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vmsbf_m, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vmsif_m, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vmsof_m, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 4c7706561a..b2bc6ab3dd 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -555,6 +555,9 @@ vmornot_mm  011100 - . . 010 . 1010111 @r
 vmxnor_mm   01 - . . 010 . 1010111 @r
 vmpopc_m010100 . . - 010 . 1010111 @r2_vm
 vmfirst_m   010101 . . - 010 . 1010111 @r2_vm
+vmsbf_m 010110 . . 1 010 . 1010111 @r2_vm
+vmsif_m 010110 . . 00011 010 . 1010111 @r2_vm
+vmsof_m 010110 . . 00010 010 . 1010111 @r2_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 3518049e68..7faaa6c51b 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2281,3 +2281,26 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
 }
 return false;
 }
+
+/* vmsbf.m set-before-first mask bit */
+/* vmsif.m set-includ-first mask bit */
+/* vmsof.m set-only-first mask bit */
+#define GEN_M_TRANS(NAME)  \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
+{  \
+if (vext_check_isa_ill(s)) {  \
+uint32_t data = 0; \
+gen_helper_gvec_3_ptr *fn = gen_helper_##NAME; \
+data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \
+data = FIELD_DP32(data, VDATA, VM, a->vm); \
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \
+vreg_ofs(s, 0), vreg_ofs(s, a->rs2),   \
+cpu_env, 0, s->vlen / 8, data, fn);\
+return true;   \
+}  \
+return false;  \
+}
+GEN_M_TRANS(vmsbf_m)
+GEN_M_TRANS(vmsif_m)
+GEN_M_TRANS(vmsof_m)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index f37bc1c0a0..0bcb05a9dd 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4550,3 +4550,69 @@ target_ulong HELPER(vmfirst_m)(void *v0, void *vs2, 
CPURISCVState *env,
 }
 return -1LL;
 }
+
+enum set_mask_type {
+ONLY_FIRST = 1,
+INCLUDE_FIRST,
+BEFORE_FIRST,
+};
+
+static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env,
+uint32_t desc, enum set_mask_type type)
+{
+uint32_t mlen = vext_mlen(desc);
+uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen;
+uint32_t vm = vext_vm(desc);
+uint32_t vl = env->vl;
+int i;
+bool first_mask_bit = false;
+
+if (vl == 0) { /* vector register writeback is cancelled when vl == 0*/
+return;
+}
+for (i = 0; i < vl; i++) {
+if (!vm && !vext_elem_mask(v0, mlen, i)) {
+continue;
+}
+/* write a zero to all following active elements */
+if (first_mask_bit) {
+vext_set_elem_mask(vd, mlen, i, 0);
+continue;
+}
+if (vext_elem_mask(vs2, mlen, i)) {
+first_mask_bit = true;
+if (type == BEFORE_FIRST) {
+vext_set_elem_mask(vd, mlen, i, 0);
+} else {
+vext_set_elem_mask(vd, mlen, i, 1);
+}
+} else {
+if (type == ONLY_FIRST) {
+vext_set_elem_mask(vd, mlen, i, 0);
+} else {
+vext_set_elem_mask(vd, mlen, i, 1);
+}
+}
+}
+for (; i < vlmax; i++) {
+vext_set_elem_mask(vd, mlen, i, 0);
+}
+}
+
+void HELPER(vmsbf_m)(void *vd, void *v0, void *vs2, CPURISCVState *env,
+uint32_t desc)
+{
+vmsetm(vd, v0, vs2, env, desc, BEFORE_FIRST);
+}
+
+void 

[PATCH v6 56/61] target/riscv: integer scalar move instruction

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   |  5 +
 target/riscv/insn32.decode  |  1 +
 target/riscv/insn_trans/trans_rvv.inc.c | 26 +
 target/riscv/vector_helper.c| 18 +
 4 files changed, 50 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 3d0e2e72bd..2e3bfdf1dc 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1109,3 +1109,8 @@ DEF_HELPER_4(vid_v_b, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vid_v_h, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vid_v_w, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vid_v_d, void, ptr, ptr, env, i32)
+
+DEF_HELPER_3(vmv_s_x_b, void, ptr, tl, env)
+DEF_HELPER_3(vmv_s_x_h, void, ptr, tl, env)
+DEF_HELPER_3(vmv_s_x_w, void, ptr, tl, env)
+DEF_HELPER_3(vmv_s_x_d, void, ptr, tl, env)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 26dd0f1b1b..0741a25540 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -562,6 +562,7 @@ vmsof_m 010110 . . 00010 010 . 1010111 
@r2_vm
 viota_m 010110 . . 1 010 . 1010111 @r2_vm
 vid_v   010110 . 0 10001 010 . 1010111 @r1_vm
 vext_x_v001100 1 . . 010 . 1010111 @r
+vmv_s_x 001101 1 0 . 110 . 1010111 @r2
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 4d7bb6b54e..4cf4e54d12 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2438,3 +2438,29 @@ static bool trans_vext_x_v(DisasContext *s, arg_r *a)
 tcg_temp_free(dest);
 return true;
 }
+
+/* Integer Scalar Move Instruction */
+typedef void gen_helper_vmv_s_x(TCGv_ptr, TCGv, TCGv_env);
+static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
+{
+if (vext_check_isa_ill(s)) {
+TCGv_ptr dest;
+TCGv src1;
+static gen_helper_vmv_s_x * const fns[4] = {
+gen_helper_vmv_s_x_b, gen_helper_vmv_s_x_h,
+gen_helper_vmv_s_x_w, gen_helper_vmv_s_x_d
+};
+
+src1 = tcg_temp_new();
+dest = tcg_temp_new_ptr();
+gen_get_gpr(src1, a->rs1);
+tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
+
+fns[s->sew](dest, src1, cpu_env);
+
+tcg_temp_free(src1);
+tcg_temp_free_ptr(dest);
+return true;
+}
+return false;
+}
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 769894c5be..7f67a283c9 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4673,3 +4673,21 @@ GEN_VEXT_VID_V(vid_v_b, uint8_t, H1, clearb)
 GEN_VEXT_VID_V(vid_v_h, uint16_t, H2, clearh)
 GEN_VEXT_VID_V(vid_v_w, uint32_t, H4, clearl)
 GEN_VEXT_VID_V(vid_v_d, uint64_t, H8, clearq)
+
+/*
+ *** Vector Permutation Instructions
+ */
+/* Integer Scalar Move Instruction */
+#define GEN_VEXT_VMV_S_X(NAME, ETYPE, H, CLEAR_FN)   \
+void HELPER(NAME)(void *vd, target_ulong s1, CPURISCVState *env) \
+{\
+if (env->vl == 0) {  \
+return;  \
+}\
+*((ETYPE *)vd + H(0)) = s1;  \
+CLEAR_FN(vd, 1, sizeof(ETYPE), env_archcpu(env)->cfg.vlen / 8);  \
+}
+GEN_VEXT_VMV_S_X(vmv_s_x_b, uint8_t, H1, clearb)
+GEN_VEXT_VMV_S_X(vmv_s_x_h, uint16_t, H2, clearh)
+GEN_VEXT_VMV_S_X(vmv_s_x_w, uint32_t, H4, clearl)
+GEN_VEXT_VMV_S_X(vmv_s_x_d, uint64_t, H8, clearq)
-- 
2.23.0




[PATCH v6 53/61] target/riscv: vector iota instruction

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   |  5 
 target/riscv/insn32.decode  |  1 +
 target/riscv/insn_trans/trans_rvv.inc.c | 22 ++
 target/riscv/vector_helper.c| 31 +
 4 files changed, 59 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 3761b48eca..8e7bef8f96 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1099,3 +1099,8 @@ DEF_HELPER_4(vmfirst_m, tl, ptr, ptr, env, i32)
 DEF_HELPER_5(vmsbf_m, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vmsif_m, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vmsof_m, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(viota_m_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(viota_m_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(viota_m_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(viota_m_d, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b2bc6ab3dd..37756fa76d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -558,6 +558,7 @@ vmfirst_m   010101 . . - 010 . 1010111 
@r2_vm
 vmsbf_m 010110 . . 1 010 . 1010111 @r2_vm
 vmsif_m 010110 . . 00011 010 . 1010111 @r2_vm
 vmsof_m 010110 . . 00010 010 . 1010111 @r2_vm
+viota_m 010110 . . 1 010 . 1010111 @r2_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 7faaa6c51b..798e7c7cff 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2304,3 +2304,25 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a)
  \
 GEN_M_TRANS(vmsbf_m)
 GEN_M_TRANS(vmsif_m)
 GEN_M_TRANS(vmsof_m)
+
+/* Vector Iota Instruction */
+static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
+{
+if (vext_check_isa_ill(s) &&
+vext_check_reg(s, a->rd, false) &&
+vext_check_overlap_group(a->rd, 1 << s->lmul, a->rs2, 1) &&
+(a->vm != 0 || a->rd != 0)) {
+uint32_t data = 0;
+data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA, VM, a->vm);
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+static gen_helper_gvec_3_ptr * const fns[4] = {
+gen_helper_viota_m_b, gen_helper_viota_m_h,
+gen_helper_viota_m_w, gen_helper_viota_m_d,
+};
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
+vreg_ofs(s, a->rs2), cpu_env, 0, s->vlen / 8, data, fns[s->sew]);
+return true;
+}
+return false;
+}
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 0bcb05a9dd..43bf61caca 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4616,3 +4616,34 @@ void HELPER(vmsof_m)(void *vd, void *v0, void *vs2, 
CPURISCVState *env,
 {
 vmsetm(vd, v0, vs2, env, desc, ONLY_FIRST);
 }
+
+/* Vector Iota Instruction */
+#define GEN_VEXT_VIOTA_M(NAME, ETYPE, H, CLEAR_FN)\
+void HELPER(NAME)(void *vd, void *v0, void *vs2, CPURISCVState *env,  \
+uint32_t desc)\
+{ \
+uint32_t mlen = vext_mlen(desc);  \
+uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen;   \
+uint32_t vm = vext_vm(desc);  \
+uint32_t vl = env->vl;\
+uint32_t sum = 0; \
+int i;\
+  \
+if (vl == 0) {\
+return;   \
+} \
+for (i = 0; i < vl; i++) {\
+if (!vm && !vext_elem_mask(v0, mlen, i)) {\
+continue; \
+} \
+*((ETYPE *)vd + H(i)) = sum;  \
+if (vext_elem_mask(vs2, mlen, i)) {   \
+sum++;\
+} \
+} \
+CLEAR_FN(vd, vl, vl * sizeof(ETYPE), vlmax * 

[PATCH v6 51/61] target/riscv: vmfirst find-first-set mask bit

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   |  2 ++
 target/riscv/insn32.decode  |  1 +
 target/riscv/insn_trans/trans_rvv.inc.c | 32 +
 target/riscv/vector_helper.c| 19 +++
 4 files changed, 54 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index e919c5e30b..ec6cf7d2a2 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1093,3 +1093,5 @@ DEF_HELPER_6(vmornot_mm, void, ptr, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_6(vmxnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
 
 DEF_HELPER_4(vmpopc_m, tl, ptr, ptr, env, i32)
+
+DEF_HELPER_4(vmfirst_m, tl, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index decb7f773f..4c7706561a 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -554,6 +554,7 @@ vmnor_mm00 - . . 010 . 1010111 @r
 vmornot_mm  011100 - . . 010 . 1010111 @r
 vmxnor_mm   01 - . . 010 . 1010111 @r
 vmpopc_m010100 . . - 010 . 1010111 @r2_vm
+vmfirst_m   010101 . . - 010 . 1010111 @r2_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index c3d6042f82..3518049e68 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2249,3 +2249,35 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
 }
 return false;
 }
+
+/* vmfirst find-first-set mask bit */
+static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
+{
+if (vext_check_isa_ill(s)) {
+TCGv_ptr src2, mask;
+TCGv dst;
+TCGv_i32 desc;
+uint32_t data = 0;
+data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA, VM, a->vm);
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+
+mask = tcg_temp_new_ptr();
+src2 = tcg_temp_new_ptr();
+dst = tcg_temp_new();
+desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+
+tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
+tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
+
+gen_helper_vmfirst_m(dst, mask, src2, cpu_env, desc);
+gen_set_gpr(a->rd, dst);
+
+tcg_temp_free_ptr(mask);
+tcg_temp_free_ptr(src2);
+tcg_temp_free(dst);
+tcg_temp_free_i32(desc);
+return true;
+}
+return false;
+}
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 829a39a8fe..f37bc1c0a0 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4531,3 +4531,22 @@ target_ulong HELPER(vmpopc_m)(void *v0, void *vs2, 
CPURISCVState *env,
 }
 return cnt;
 }
+
+/* vmfirst find-first-set mask bit*/
+target_ulong HELPER(vmfirst_m)(void *v0, void *vs2, CPURISCVState *env,
+uint32_t desc)
+{
+uint32_t mlen = vext_mlen(desc);
+uint32_t vm = vext_vm(desc);
+uint32_t vl = env->vl;
+int i;
+
+for (i = 0; i < vl; i++) {
+if (vm || vext_elem_mask(v0, mlen, i)) {
+if (vext_elem_mask(vs2, mlen, i)) {
+return i;
+}
+}
+}
+return -1LL;
+}
-- 
2.23.0




[PATCH v6 55/61] target/riscv: integer extract instruction

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
---
 target/riscv/insn32.decode  |  1 +
 target/riscv/insn_trans/trans_rvv.inc.c | 91 +
 2 files changed, 92 insertions(+)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 1231628cb2..26dd0f1b1b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -561,6 +561,7 @@ vmsif_m 010110 . . 00011 010 . 1010111 
@r2_vm
 vmsof_m 010110 . . 00010 010 . 1010111 @r2_vm
 viota_m 010110 . . 1 010 . 1010111 @r2_vm
 vid_v   010110 . 0 10001 010 . 1010111 @r1_vm
+vext_x_v001100 1 . . 010 . 1010111 @r
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index fae72acaa1..4d7bb6b54e 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2347,3 +2347,94 @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
 }
 return false;
 }
+
+/*
+ *** Vector Permutation Instructions
+ */
+/* Integer Extract Instruction */
+static void extract_element(TCGv dest, TCGv_ptr base,
+int ofs, int sew)
+{
+switch (sew) {
+case MO_8:
+tcg_gen_ld8u_tl(dest, base, ofs);
+break;
+case MO_16:
+tcg_gen_ld16u_tl(dest, base, ofs);
+break;
+default:
+tcg_gen_ld32u_tl(dest, base, ofs);
+break;
+#if TARGET_LONG_BITS == 64
+case MO_64:
+tcg_gen_ld_i64(dest, base, ofs);
+break;
+#endif
+}
+}
+
+/* offset of the idx element with base regsiter r */
+static uint32_t endian_ofs(DisasContext *s, int r, int idx)
+{
+#ifdef HOST_WORDS_BIGENDIAN
+return vreg_ofs(s, r) + ((idx ^ (7 >> s->sew)) << s->sew);
+#else
+return vreg_ofs(s, r) + (idx << s->sew);
+#endif
+}
+
+/* adjust the index according to the endian */
+static void endian_adjust(TCGv_i32 ofs, int sew)
+{
+#ifdef HOST_WORDS_BIGENDIAN
+tcg_gen_xori_i32(ofs, ofs, 7 >> sew);
+#endif
+}
+
+static bool trans_vext_x_v(DisasContext *s, arg_r *a)
+{
+TCGv dest = tcg_temp_new();
+
+if (a->rs1 == 0) {
+/* Special case vmv.x.s rd, vs2. */
+extract_element(dest, cpu_env,
+endian_ofs(s, a->rs2, 0), s->sew);
+} else {
+int vlen = s->vlen >> (3 + s->sew);
+TCGv_i32 ofs = tcg_temp_new_i32();
+TCGv_ptr  base = tcg_temp_new_ptr();
+TCGv t_vlen, t_zero;
+
+/*
+ * Mask the index to the length so that we do
+ * not produce an out-of-range load.
+ */
+tcg_gen_trunc_tl_i32(ofs, cpu_gpr[a->rs1]);
+tcg_gen_andi_i32(ofs, ofs, vlen - 1);
+
+/* Convert the index to an offset. */
+endian_adjust(ofs, s->sew);
+tcg_gen_shli_i32(ofs, ofs, s->sew);
+
+/* Convert the index to a pointer. */
+tcg_gen_ext_i32_ptr(base, ofs);
+tcg_gen_add_ptr(base, base, cpu_env);
+
+/* Perform the load. */
+extract_element(dest, base,
+vreg_ofs(s, a->rs2), s->sew);
+tcg_temp_free_ptr(base);
+tcg_temp_free_i32(ofs);
+
+/* Flush out-of-range indexing to zero.  */
+t_vlen = tcg_const_tl(vlen);
+t_zero = tcg_const_tl(0);
+tcg_gen_movcond_tl(TCG_COND_LTU, dest, cpu_gpr[a->rs1],
+   t_vlen, dest, t_zero);
+tcg_temp_free(t_vlen);
+tcg_temp_free(t_zero);
+}
+gen_set_gpr(a->rd, dest);
+tcg_temp_free(dest);
+return true;
+}
-- 
2.23.0




Re: [PATCH 4/5] ppc/spapr: Don't kill the guest if a recovered FWNMI machine check delivery fails

2020-03-17 Thread Greg Kurz
On Tue, 17 Mar 2020 15:02:14 +1000
Nicholas Piggin  wrote:

> Try to be tolerant of errors if the machine check had been recovered
> by the host.
> 
> Signed-off-by: Nicholas Piggin 
> ---

Same comment as previous patch on multi-line error strings and
warn_report() in the !recovered case.

>  hw/ppc/spapr_events.c | 25 ++---
>  1 file changed, 18 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
> index d35151eeb0..3f524cb0ca 100644
> --- a/hw/ppc/spapr_events.c
> +++ b/hw/ppc/spapr_events.c
> @@ -807,13 +807,20 @@ static void spapr_mce_dispatch_elog(PowerPCCPU *cpu, 
> bool recovered)
>  /* get rtas addr from fdt */
>  rtas_addr = spapr_get_rtas_addr();
>  if (!rtas_addr) {
> -warn_report("FWNMI: Unable to deliver machine check to guest: "
> -"rtas_addr not found.");
> -qemu_system_guest_panicked(NULL);
> +if (!recovered) {
> +warn_report("FWNMI: Unable to deliver machine check to guest: "
> +"rtas_addr not found.");
> +qemu_system_guest_panicked(NULL);
> +} else {
> +warn_report("FWNMI: Unable to deliver machine check to guest: "
> +"rtas_addr not found. Machine check recovered.");
> +}
>  g_free(ext_elog);
>  return;
>  }
>  
> +spapr->fwnmi_machine_check_interlock = cpu->vcpu_id;
> +

I don't understand this change.

>  stq_be_phys(_space_memory, rtas_addr + RTAS_ERROR_LOG_OFFSET,
>  env->gpr[3]);
>  cpu_physical_memory_write(rtas_addr + RTAS_ERROR_LOG_OFFSET +
> @@ -850,9 +857,14 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
>   * that CPU called "ibm,nmi-interlock")
>   */
>  if (spapr->fwnmi_machine_check_interlock == cpu->vcpu_id) {
> -warn_report("FWNMI: Unable to deliver machine check to guest: "
> -"nested machine check.");
> -qemu_system_guest_panicked(NULL);
> +if (!recovered) {
> +warn_report("FWNMI: Unable to deliver machine check to 
> guest: "
> +"nested machine check.");
> +qemu_system_guest_panicked(NULL);
> +} else {
> +warn_report("FWNMI: Unable to deliver machine check to 
> guest: "
> +"nested machine check. Machine check 
> recovered.");
> +}
>  return;
>  }
>  qemu_cond_wait_iothread(>fwnmi_machine_check_interlock_cond);
> @@ -880,7 +892,6 @@ void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered)
>  warn_report("Received a fwnmi while migration was in progress");
>  }
>  
> -spapr->fwnmi_machine_check_interlock = cpu->vcpu_id;
>  spapr_mce_dispatch_elog(cpu, recovered);
>  }
>  




[PATCH v6 49/61] target/riscv: vector mask-register logical instructions

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   |  9 ++
 target/riscv/insn32.decode  |  8 +
 target/riscv/insn_trans/trans_rvv.inc.c | 28 +
 target/riscv/vector_helper.c| 41 +
 4 files changed, 86 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 15569223cb..116c14f40f 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1082,3 +1082,12 @@ DEF_HELPER_6(vfredmin_vs_d, void, ptr, ptr, ptr, ptr, 
env, i32)
 
 DEF_HELPER_6(vfwredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(vmand_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmnand_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmandnot_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmxor_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmor_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmornot_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmxnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 526a964d28..a4128c26a0 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -545,6 +545,14 @@ vfredmin_vs 000101 . . . 001 . 1010111 
@r_vm
 vfredmax_vs 000111 . . . 001 . 1010111 @r_vm
 # Vector widening ordered and unordered float reduction sum
 vfwredsum_vs1100-1 . . . 001 . 1010111 @r_vm
+vmand_mm011001 - . . 010 . 1010111 @r
+vmnand_mm   011101 - . . 010 . 1010111 @r
+vmandnot_mm 011000 - . . 010 . 1010111 @r
+vmxor_mm011011 - . . 010 . 1010111 @r
+vmor_mm 011010 - . . 010 . 1010111 @r
+vmnor_mm00 - . . 010 . 1010111 @r
+vmornot_mm  011100 - . . 010 . 1010111 @r
+vmxnor_mm   01 - . . 010 . 1010111 @r
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index fd927f0959..620a73d741 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2189,3 +2189,31 @@ GEN_OPFVV_TRANS(vfredmin_vs, reduction_check)
 
 /* Vector Widening Floating-Point Reduction Instructions */
 GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, reduction_check)
+
+/*
+ *** Vector Mask Operations
+ */
+/* Vector Mask-Register Logical Instructions */
+#define GEN_MM_TRANS(NAME) \
+static bool trans_##NAME(DisasContext *s, arg_r *a)\
+{  \
+if (vext_check_isa_ill(s)) {  \
+uint32_t data = 0; \
+gen_helper_gvec_4_ptr *fn = gen_helper_##NAME; \
+data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2),  \
+cpu_env, 0, s->vlen / 8, data, fn);\
+return true;   \
+}  \
+return false;  \
+}
+GEN_MM_TRANS(vmand_mm)
+GEN_MM_TRANS(vmnand_mm)
+GEN_MM_TRANS(vmandnot_mm)
+GEN_MM_TRANS(vmxor_mm)
+GEN_MM_TRANS(vmor_mm)
+GEN_MM_TRANS(vmnor_mm)
+GEN_MM_TRANS(vmornot_mm)
+GEN_MM_TRANS(vmxnor_mm)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 57532959fb..7157ad49ea 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4470,3 +4470,44 @@ void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void 
*vs1,
 *((uint64_t *)vd) = s1;
 clearq(vd, 1, sizeof(uint64_t), tot);
 }
+
+/*
+ *** Vector Mask Operations
+ */
+/* Vector Mask-Register Logical Instructions */
+#define GEN_VEXT_MASK_VV(NAME, OP)\
+void HELPER(NAME)(void *vd, void *v0, void *vs1,  \
+void *vs2, CPURISCVState *env, uint32_t desc) \
+{ \
+uint32_t mlen = vext_mlen(desc);  \
+uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen;   \
+uint32_t vl = env->vl;\
+uint32_t i;   \
+int a, b; \
+  \
+if (vl == 0) {   

[PULL 13/13] Add rx-softmmu

2020-03-17 Thread Philippe Mathieu-Daudé
From: Yoshinori Sato 

Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Yoshinori Sato 
Signed-off-by: Richard Henderson 
[PMD: Squashed patches from Richard Henderson modifying
  qapi/common.json and tests/machine-none-test.c]
Message-Id: <20200224141923.82118-21-ys...@users.sourceforge.jp>
[PMD: Added @since 5.0 tag in SysEmuTarget]
Acked-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 configure   | 11 ++-
 default-configs/rx-softmmu.mak  |  2 ++
 qapi/machine.json   |  4 +++-
 include/exec/poison.h   |  1 +
 include/sysemu/arch_init.h  |  1 +
 arch_init.c |  2 ++
 tests/qtest/machine-none-test.c |  1 +
 7 files changed, 20 insertions(+), 2 deletions(-)
 create mode 100644 default-configs/rx-softmmu.mak

diff --git a/configure b/configure
index eb49bb6680..f9586cbc34 100755
--- a/configure
+++ b/configure
@@ -4184,7 +4184,7 @@ fi
 fdt_required=no
 for target in $target_list; do
   case $target in
-
aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu|riscv*-softmmu)
+
aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu|riscv*-softmmu|rx-softmmu)
   fdt_required=yes
 ;;
   esac
@@ -7881,6 +7881,12 @@ case "$target_name" in
 mttcg=yes
 gdb_xml_files="riscv-64bit-cpu.xml riscv-32bit-fpu.xml riscv-64bit-fpu.xml 
riscv-64bit-csr.xml riscv-64bit-virtual.xml"
   ;;
+  rx)
+TARGET_ARCH=rx
+bflt="yes"
+target_compiler=$cross_cc_rx
+gdb_xml_files="rx-core.xml"
+  ;;
   sh4|sh4eb)
 TARGET_ARCH=sh4
 bflt="yes"
@@ -8062,6 +8068,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   riscv*)
 disas_config "RISCV"
   ;;
+  rx)
+disas_config "RX"
+  ;;
   s390*)
 disas_config "S390"
   ;;
diff --git a/default-configs/rx-softmmu.mak b/default-configs/rx-softmmu.mak
new file mode 100644
index 00..7c4eb2c1a0
--- /dev/null
+++ b/default-configs/rx-softmmu.mak
@@ -0,0 +1,2 @@
+# Default configuration for rx-softmmu
+
diff --git a/qapi/machine.json b/qapi/machine.json
index 6c11e3cf3a..282d247097 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -16,6 +16,8 @@
 # individual target constants are not documented here, for the time
 # being.
 #
+# @rx: since 5.0
+#
 # Notes: The resulting QMP strings can be appended to the "qemu-system-"
 #prefix to produce the corresponding QEMU executable name. This
 #is true even for "qemu-system-x86_64".
@@ -26,7 +28,7 @@
   'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32',
  'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64',
  'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc',
- 'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4',
+ 'ppc64', 'riscv32', 'riscv64', 'rx', 's390x', 'sh4',
  'sh4eb', 'sparc', 'sparc64', 'tricore', 'unicore32',
  'x86_64', 'xtensa', 'xtensaeb' ] }
 
diff --git a/include/exec/poison.h b/include/exec/poison.h
index 955eb863ab..7b9ac361dc 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -26,6 +26,7 @@
 #pragma GCC poison TARGET_PPC
 #pragma GCC poison TARGET_PPC64
 #pragma GCC poison TARGET_ABI32
+#pragma GCC poison TARGET_RX
 #pragma GCC poison TARGET_S390X
 #pragma GCC poison TARGET_SH4
 #pragma GCC poison TARGET_SPARC
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 01392dc945..71a7a285ee 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -24,6 +24,7 @@ enum {
 QEMU_ARCH_NIOS2 = (1 << 17),
 QEMU_ARCH_HPPA = (1 << 18),
 QEMU_ARCH_RISCV = (1 << 19),
+QEMU_ARCH_RX = (1 << 20),
 
 QEMU_ARCH_NONE = (1 << 31),
 };
diff --git a/arch_init.c b/arch_init.c
index 705d0b94ad..d9eb0ec1dd 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -77,6 +77,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_PPC
 #elif defined(TARGET_RISCV)
 #define QEMU_ARCH QEMU_ARCH_RISCV
+#elif defined(TARGET_RX)
+#define QEMU_ARCH QEMU_ARCH_RX
 #elif defined(TARGET_S390X)
 #define QEMU_ARCH QEMU_ARCH_S390X
 #elif defined(TARGET_SH4)
diff --git a/tests/qtest/machine-none-test.c b/tests/qtest/machine-none-test.c
index 5953d31755..8bb54a6360 100644
--- a/tests/qtest/machine-none-test.c
+++ b/tests/qtest/machine-none-test.c
@@ -56,6 +56,7 @@ static struct arch2cpu cpus_map[] = {
 { "hppa", "hppa" },
 { "riscv64", "rv64gcsu-v1.10.0" },
 { "riscv32", "rv32gcsu-v1.9.1" },
+{ "rx", "rx62n" },
 };
 
 static const char *get_cpu_model_by_arch(const char *arch)
-- 
2.21.1




[PATCH v6 54/61] target/riscv: vector element index instruction

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   |  5 +
 target/riscv/insn32.decode  |  2 ++
 target/riscv/insn_trans/trans_rvv.inc.c | 21 
 target/riscv/vector_helper.c| 26 +
 4 files changed, 54 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 8e7bef8f96..3d0e2e72bd 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1104,3 +1104,8 @@ DEF_HELPER_5(viota_m_b, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(viota_m_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(viota_m_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(viota_m_d, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_4(vid_v_b, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vid_v_h, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vid_v_w, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vid_v_d, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 37756fa76d..1231628cb2 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -70,6 +70,7 @@
 @r2  ...   . . ... . ... %rs1 %rd
 @r2_nfvm ... ... vm:1 . . ... . ...  %nf %rs1 %rd
 @r2_vm   .. vm:1 . . ... . ...  %rs2 %rd
+@r1_vm   .. vm:1 . . ... . ... %rd
 @r_nfvm  ... ... vm:1 . . ... . ...  %nf %rs2 %rs1 %rd
 @r_vm.. vm:1 . . ... . ...  %rs2 %rs1 %rd
 @r_vm_1  .. . . . ... . ... vm=1 %rs2 %rs1 %rd
@@ -559,6 +560,7 @@ vmsbf_m 010110 . . 1 010 . 1010111 
@r2_vm
 vmsif_m 010110 . . 00011 010 . 1010111 @r2_vm
 vmsof_m 010110 . . 00010 010 . 1010111 @r2_vm
 viota_m 010110 . . 1 010 . 1010111 @r2_vm
+vid_v   010110 . 0 10001 010 . 1010111 @r1_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 798e7c7cff..fae72acaa1 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2326,3 +2326,24 @@ static bool trans_viota_m(DisasContext *s, arg_viota_m 
*a)
 }
 return false;
 }
+
+/* Vector Element Index Instruction */
+static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
+{
+if (vext_check_isa_ill(s) &&
+vext_check_reg(s, a->rd, false) &&
+vext_check_overlap_mask(s, a->rd, a->vm, false)) {
+uint32_t data = 0;
+data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA, VM, a->vm);
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+static gen_helper_gvec_2_ptr * const fns[4] = {
+gen_helper_vid_v_b, gen_helper_vid_v_h,
+gen_helper_vid_v_w, gen_helper_vid_v_d,
+};
+tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
+cpu_env, 0, s->vlen / 8, data, fns[s->sew]);
+return true;
+}
+return false;
+}
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 43bf61caca..769894c5be 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4647,3 +4647,29 @@ GEN_VEXT_VIOTA_M(viota_m_b, uint8_t, H1, clearb)
 GEN_VEXT_VIOTA_M(viota_m_h, uint16_t, H2, clearh)
 GEN_VEXT_VIOTA_M(viota_m_w, uint32_t, H4, clearl)
 GEN_VEXT_VIOTA_M(viota_m_d, uint64_t, H8, clearq)
+
+/* Vector Element Index Instruction */
+#define GEN_VEXT_VID_V(NAME, ETYPE, H, CLEAR_FN)  \
+void HELPER(NAME)(void *vd, void *v0, CPURISCVState *env, uint32_t desc)  \
+{ \
+uint32_t mlen = vext_mlen(desc);  \
+uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen;   \
+uint32_t vm = vext_vm(desc);  \
+uint32_t vl = env->vl;\
+int i;\
+  \
+if (vl == 0) {\
+return;   \
+} \
+for (i = 0; i < vl; i++) {\
+if (!vm && !vext_elem_mask(v0, mlen, i)) {\
+continue; \
+} \
+*((ETYPE *)vd + H(i)) = i;\
+} \
+

[PATCH v6 46/61] target/riscv: vector wideing integer reduction instructions

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   |  7 +++
 target/riscv/insn32.decode  |  2 ++
 target/riscv/insn_trans/trans_rvv.inc.c |  4 
 target/riscv/vector_helper.c| 11 +++
 4 files changed, 24 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 652b38f690..6bd7965a23 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1062,3 +1062,10 @@ DEF_HELPER_6(vredxor_vs_b, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(vredxor_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vredxor_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vredxor_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(vwredsumu_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vwredsumu_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vwredsumu_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vwredsum_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vwredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vwredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 773b32f0b4..b69d804fda 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -537,6 +537,8 @@ vredminu_vs 000100 . . . 010 . 1010111 @r_vm
 vredmin_vs  000101 . . . 010 . 1010111 @r_vm
 vredmaxu_vs 000110 . . . 010 . 1010111 @r_vm
 vredmax_vs  000111 . . . 010 . 1010111 @r_vm
+vwredsumu_vs11 . . . 000 . 1010111 @r_vm
+vwredsum_vs 110001 . . . 000 . 1010111 @r_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 73feac4ddd..90c7cb2d63 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2177,3 +2177,7 @@ GEN_OPIVV_TRANS(vredmin_vs, reduction_check)
 GEN_OPIVV_TRANS(vredand_vs, reduction_check)
 GEN_OPIVV_TRANS(vredor_vs, reduction_check)
 GEN_OPIVV_TRANS(vredxor_vs, reduction_check)
+
+/* Vector Widening Integer Reduction Instructions */
+GEN_OPIVV_WIDEN_TRANS(vwredsum_vs, reduction_check)
+GEN_OPIVV_WIDEN_TRANS(vwredsumu_vs, reduction_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index d539d82f97..678ede3c02 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4367,3 +4367,14 @@ GEN_VEXT_RED(vredxor_vs_b, int8_t, int8_t, H1, H1, 
DO_XOR, clearb)
 GEN_VEXT_RED(vredxor_vs_h, int16_t, int16_t, H2, H2, DO_XOR, clearh)
 GEN_VEXT_RED(vredxor_vs_w, int32_t, int32_t, H4, H4, DO_XOR, clearl)
 GEN_VEXT_RED(vredxor_vs_d, int64_t, int64_t, H8, H8, DO_XOR, clearq)
+
+/* Vector Widening Integer Reduction Instructions */
+/* signed sum reduction into double-width accumulator */
+GEN_VEXT_RED(vwredsum_vs_b, int16_t, int8_t, H2, H1, DO_ADD, clearh)
+GEN_VEXT_RED(vwredsum_vs_h, int32_t, int16_t, H4, H2, DO_ADD, clearl)
+GEN_VEXT_RED(vwredsum_vs_w, int64_t, int32_t, H8, H4, DO_ADD, clearq)
+
+/* Unsigned sum reduction into double-width accumulator */
+GEN_VEXT_RED(vwredsumu_vs_b, uint16_t, uint8_t, H2, H1, DO_ADD, clearh)
+GEN_VEXT_RED(vwredsumu_vs_h, uint32_t, uint16_t, H4, H2, DO_ADD, clearl)
+GEN_VEXT_RED(vwredsumu_vs_w, uint64_t, uint32_t, H8, H4, DO_ADD, clearq)
-- 
2.23.0




[PULL 12/13] target/rx: Dump bytes for each insn during disassembly

2020-03-17 Thread Philippe Mathieu-Daudé
From: Richard Henderson 

There are so many different forms of each RX instruction
that it will be very useful to be able to look at the bytes
to see on which path a bug may lie.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Yoshinori Sato 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Message-Id: <20190531134315.4109-24-richard.hender...@linaro.org>
Acked-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/rx/disas.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/target/rx/disas.c b/target/rx/disas.c
index dcfb7baf99..6dee7a0342 100644
--- a/target/rx/disas.c
+++ b/target/rx/disas.c
@@ -102,7 +102,21 @@ static int bdsp_s(DisasContext *ctx, int d)
 /* Include the auto-generated decoder.  */
 #include "decode.inc.c"
 
-#define prt(...) (ctx->dis->fprintf_func)((ctx->dis->stream), __VA_ARGS__)
+static void dump_bytes(DisasContext *ctx)
+{
+int i, len = ctx->len;
+
+for (i = 0; i < len; ++i) {
+ctx->dis->fprintf_func(ctx->dis->stream, "%02x ", ctx->bytes[i]);
+}
+ctx->dis->fprintf_func(ctx->dis->stream, "%*c", (8 - i) * 3, '\t');
+}
+
+#define prt(...) \
+do {\
+dump_bytes(ctx);\
+ctx->dis->fprintf_func(ctx->dis->stream, __VA_ARGS__);  \
+} while (0)
 
 #define RX_MEMORY_BYTE 0
 #define RX_MEMORY_WORD 1
-- 
2.21.1




[PATCH v6 45/61] target/riscv: vector single-width integer reduction instructions

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 33 +++
 target/riscv/insn32.decode  |  8 +++
 target/riscv/insn_trans/trans_rvv.inc.c | 17 ++
 target/riscv/vector_helper.c| 77 +
 4 files changed, 135 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 72bf084d57..652b38f690 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1029,3 +1029,36 @@ DEF_HELPER_5(vfncvt_f_x_v_h, void, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_5(vfncvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfncvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfncvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(vredsum_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredsum_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredmaxu_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredmaxu_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredmaxu_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredmaxu_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredmax_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredmax_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredmax_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredmax_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredminu_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredminu_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredminu_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredminu_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredmin_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredmin_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredmin_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredmin_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredand_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredand_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredand_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredand_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredor_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredor_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredor_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredor_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredxor_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredxor_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredxor_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vredxor_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 57ac4de1c2..773b32f0b4 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -529,6 +529,14 @@ vfncvt_x_f_v100010 . . 10001 001 . 1010111 
@r2_vm
 vfncvt_f_xu_v   100010 . . 10010 001 . 1010111 @r2_vm
 vfncvt_f_x_v100010 . . 10011 001 . 1010111 @r2_vm
 vfncvt_f_f_v100010 . . 10100 001 . 1010111 @r2_vm
+vredsum_vs  00 . . . 010 . 1010111 @r_vm
+vredand_vs  01 . . . 010 . 1010111 @r_vm
+vredor_vs   10 . . . 010 . 1010111 @r_vm
+vredxor_vs  11 . . . 010 . 1010111 @r_vm
+vredminu_vs 000100 . . . 010 . 1010111 @r_vm
+vredmin_vs  000101 . . . 010 . 1010111 @r_vm
+vredmaxu_vs 000110 . . . 010 . 1010111 @r_vm
+vredmax_vs  000111 . . . 010 . 1010111 @r_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 53984da94c..73feac4ddd 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2160,3 +2160,20 @@ GEN_OPFV_NARROW_TRANS(vfncvt_x_f_v)
 GEN_OPFV_NARROW_TRANS(vfncvt_f_xu_v)
 GEN_OPFV_NARROW_TRANS(vfncvt_f_x_v)
 GEN_OPFV_NARROW_TRANS(vfncvt_f_f_v)
+
+/*
+ *** Vector Reduction Operations
+ */
+/* Vector Single-Width Integer Reduction Instructions */
+static bool reduction_check(DisasContext *s, arg_rmrr *a)
+{
+return vext_check_isa_ill(s) && vext_check_reg(s, a->rs2, false);
+}
+GEN_OPIVV_TRANS(vredsum_vs, reduction_check)
+GEN_OPIVV_TRANS(vredmaxu_vs, reduction_check)
+GEN_OPIVV_TRANS(vredmax_vs, reduction_check)
+GEN_OPIVV_TRANS(vredminu_vs, reduction_check)
+GEN_OPIVV_TRANS(vredmin_vs, reduction_check)
+GEN_OPIVV_TRANS(vredand_vs, reduction_check)
+GEN_OPIVV_TRANS(vredor_vs, reduction_check)
+GEN_OPIVV_TRANS(vredxor_vs, reduction_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index c34f334127..d539d82f97 100644
--- 

[PULL 05/13] target/rx: CPU definitions

2020-03-17 Thread Philippe Mathieu-Daudé
From: Yoshinori Sato 

Reviewed-by: Richard Henderson 
Signed-off-by: Yoshinori Sato 
Signed-off-by: Richard Henderson 
[PMD: Use newer QOM style, split cpu-qom.h, restrict access to
 extable array, use rx_cpu_tlb_fill() extracted from patch of
 Yoshinori Sato 'Convert to CPUClass::tlb_fill', call cpu_reset
 after qemu_init_vcpu, make rx_crname a function]
Signed-off-by: Philippe Mathieu-Daudé 
Acked-by: Igor Mammedov 
Message-Id: <20200224141923.82118-7-ys...@users.sourceforge.jp>
Acked-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/rx/cpu-param.h   |  30 ++
 target/rx/cpu-qom.h |  54 ++
 target/rx/cpu.h | 180 
 target/rx/cpu.c | 226 
 target/rx/gdbstub.c | 112 
 target/rx/translate.c   |  17 ++-
 gdb-xml/rx-core.xml |  70 +
 target/rx/Makefile.objs |   1 -
 8 files changed, 684 insertions(+), 6 deletions(-)
 create mode 100644 target/rx/cpu-param.h
 create mode 100644 target/rx/cpu-qom.h
 create mode 100644 target/rx/cpu.h
 create mode 100644 target/rx/cpu.c
 create mode 100644 target/rx/gdbstub.c
 create mode 100644 gdb-xml/rx-core.xml

diff --git a/target/rx/cpu-param.h b/target/rx/cpu-param.h
new file mode 100644
index 00..b156ad1ca0
--- /dev/null
+++ b/target/rx/cpu-param.h
@@ -0,0 +1,30 @@
+/*
+ *  RX cpu parameters
+ *
+ *  Copyright (c) 2019 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#ifndef RX_CPU_PARAM_H
+#define RX_CPU_PARAM_H
+
+#define TARGET_LONG_BITS 32
+#define TARGET_PAGE_BITS 12
+
+#define TARGET_PHYS_ADDR_SPACE_BITS 32
+#define TARGET_VIRT_ADDR_SPACE_BITS 32
+
+#define NB_MMU_MODES 1
+
+#endif
diff --git a/target/rx/cpu-qom.h b/target/rx/cpu-qom.h
new file mode 100644
index 00..d64e89ca99
--- /dev/null
+++ b/target/rx/cpu-qom.h
@@ -0,0 +1,54 @@
+/*
+ * RX CPU
+ *
+ * Copyright (c) 2019 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#ifndef RX_CPU_QOM_H
+#define RX_CPU_QOM_H
+
+#include "hw/core/cpu.h"
+
+#define TYPE_RX_CPU "rx-cpu"
+
+#define TYPE_RX62N_CPU RX_CPU_TYPE_NAME("rx62n")
+
+#define RXCPU_CLASS(klass) \
+OBJECT_CLASS_CHECK(RXCPUClass, (klass), TYPE_RX_CPU)
+#define RXCPU(obj) \
+OBJECT_CHECK(RXCPU, (obj), TYPE_RX_CPU)
+#define RXCPU_GET_CLASS(obj) \
+OBJECT_GET_CLASS(RXCPUClass, (obj), TYPE_RX_CPU)
+
+/*
+ * RXCPUClass:
+ * @parent_realize: The parent class' realize handler.
+ * @parent_reset: The parent class' reset handler.
+ *
+ * A RX CPU model.
+ */
+typedef struct RXCPUClass {
+/*< private >*/
+CPUClass parent_class;
+/*< public >*/
+
+DeviceRealize parent_realize;
+void (*parent_reset)(CPUState *cpu);
+
+} RXCPUClass;
+
+#define CPUArchState struct CPURXState
+
+#endif
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
new file mode 100644
index 00..b716fc5789
--- /dev/null
+++ b/target/rx/cpu.h
@@ -0,0 +1,180 @@
+/*
+ *  RX emulation definition
+ *
+ *  Copyright (c) 2019 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#ifndef RX_CPU_H
+#define RX_CPU_H
+
+#include "qemu/bitops.h"
+#include "qemu-common.h"
+#include "hw/registerfields.h"
+#include "cpu-qom.h"
+
+#include "exec/cpu-defs.h"
+
+/* PSW 

[PATCH v6 50/61] target/riscv: vector mask population count vmpopc

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   |  2 ++
 target/riscv/insn32.decode  |  1 +
 target/riscv/insn_trans/trans_rvv.inc.c | 32 +
 target/riscv/vector_helper.c| 20 
 4 files changed, 55 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 116c14f40f..e919c5e30b 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1091,3 +1091,5 @@ DEF_HELPER_6(vmor_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmornot_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmxnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_4(vmpopc_m, tl, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index a4128c26a0..decb7f773f 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -553,6 +553,7 @@ vmor_mm 011010 - . . 010 . 1010111 @r
 vmnor_mm00 - . . 010 . 1010111 @r
 vmornot_mm  011100 - . . 010 . 1010111 @r
 vmxnor_mm   01 - . . 010 . 1010111 @r
+vmpopc_m010100 . . - 010 . 1010111 @r2_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 620a73d741..c3d6042f82 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2217,3 +2217,35 @@ GEN_MM_TRANS(vmor_mm)
 GEN_MM_TRANS(vmnor_mm)
 GEN_MM_TRANS(vmornot_mm)
 GEN_MM_TRANS(vmxnor_mm)
+
+/* Vector mask population count vmpopc */
+static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
+{
+if (vext_check_isa_ill(s)) {
+TCGv_ptr src2, mask;
+TCGv dst;
+TCGv_i32 desc;
+uint32_t data = 0;
+data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA, VM, a->vm);
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+
+mask = tcg_temp_new_ptr();
+src2 = tcg_temp_new_ptr();
+dst = tcg_temp_new();
+desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+
+tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
+tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
+
+gen_helper_vmpopc_m(dst, mask, src2, cpu_env, desc);
+gen_set_gpr(a->rd, dst);
+
+tcg_temp_free_ptr(mask);
+tcg_temp_free_ptr(src2);
+tcg_temp_free(dst);
+tcg_temp_free_i32(desc);
+return true;
+}
+return false;
+}
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 7157ad49ea..829a39a8fe 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4511,3 +4511,23 @@ GEN_VEXT_MASK_VV(vmor_mm, DO_OR)
 GEN_VEXT_MASK_VV(vmnor_mm, DO_NOR)
 GEN_VEXT_MASK_VV(vmornot_mm, DO_ORNOT)
 GEN_VEXT_MASK_VV(vmxnor_mm, DO_XNOR)
+
+/* Vector mask population count vmpopc */
+target_ulong HELPER(vmpopc_m)(void *v0, void *vs2, CPURISCVState *env,
+uint32_t desc)
+{
+target_ulong cnt = 0;
+uint32_t mlen = vext_mlen(desc);
+uint32_t vm = vext_vm(desc);
+uint32_t vl = env->vl;
+int i;
+
+for (i = 0; i < vl; i++) {
+if (vm || vext_elem_mask(v0, mlen, i)) {
+if (vext_elem_mask(vs2, mlen, i)) {
+cnt++;
+}
+}
+}
+return cnt;
+}
-- 
2.23.0




Re: [PATCH for-5.0] vl.c: fix migration failure for 3.1 and older machine types

2020-03-17 Thread Igor Mammedov
On Wed,  4 Mar 2020 12:27:48 -0500
Igor Mammedov  wrote:

> Migration from QEMU(v4.0) fails when using 3.1 or older machine
> type. For example if one attempts to migrate
> QEMU-2.12 started as
>   qemu-system-ppc64 -nodefaults -M pseries-2.12 -m 4096 -mem-path /tmp/
> to current master, it will fail with
>   qemu-system-ppc64: Unknown ramblock "ppc_spapr.ram", cannot accept migration
>   qemu-system-ppc64: error while loading state for instance 0x0 of device 
> 'ram'
>   qemu-system-ppc64: load of migration failed: Invalid argument
> 
> Caused by 900c0ba373 commit which switches main RAM allocation to
> memory backends and the fact in 3.1 and older QEMU, backends used
> full[***] QOM path as memory region name instead of backend's name.
> That was changed after 3.1 to use prefix-less names by default
> (fa0cb34d22) for new machine types.
> *** effectively makes main RAM memory region names defined by
> MachineClass::default_ram_id being altered with '/objects/' prefix
> and therefore migration fails as old QEMU sends prefix-less
> name while new QEMU expects name with prefix when using 3.1 and
> older machine types.
> 
> Fix it by forcing implicit[1] memory backend to always use
> prefix-less names for its memory region by setting
>   'x-use-canonical-path-for-ramblock-id'
> property to false.
> 
> 1) i.e. memory backend created by compat glue which maps
> -m/-mem-path/-mem-prealloc/default RAM size into
> appropriate backend type/options to match old CLI format.
> 
> Fixes: 900c0ba373
> Signed-off-by: Igor Mammedov 
> Reported-by: Lukáš Doktor 


ping,

so we don't forget to merge it

> ---
> CC: ldok...@redhat.com
> CC: marcandre.lur...@redhat.com
> CC: dgilb...@redhat.com
> ---
>  softmmu/vl.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index 5549f4b619..1101b1cb41 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -2800,6 +2800,9 @@ static void create_default_memdev(MachineState *ms, 
> const char *path)
>  object_property_set_int(obj, ms->ram_size, "size", _fatal);
>  object_property_add_child(object_get_objects_root(), mc->default_ram_id,
>obj, _fatal);
> +/* Ensure backend's memory region name is equal to mc->default_ram_id */
> +object_property_set_bool(obj, false, 
> "x-use-canonical-path-for-ramblock-id",
> + _fatal);
>  user_creatable_complete(USER_CREATABLE(obj), _fatal);
>  object_unref(obj);
>  object_property_set_str(OBJECT(ms), mc->default_ram_id, "memory-backend",




Re: [PATCH v9 13/15] s390x: protvirt: Handle SIGP store status correctly

2020-03-17 Thread Cornelia Huck
On Thu, 12 Mar 2020 17:13:10 +0100
Janosch Frank  wrote:

> On 3/12/20 4:51 PM, Christian Borntraeger wrote:
> > On 11.03.20 14:21, Janosch Frank wrote:  
> >> For protected VMs status storing is not done by QEMU anymore.
> >>
> >> Signed-off-by: Janosch Frank 
> >> Reviewed-by: Thomas Huth 
> >> Reviewed-by: David Hildenbrand   
> > 
> >   
> >> ---
> >>  target/s390x/helper.c | 6 ++
> >>  1 file changed, 6 insertions(+)
> >>
> >> diff --git a/target/s390x/helper.c b/target/s390x/helper.c
> >> index ed726849114f2f35..5022df8812d406c9 100644
> >> --- a/target/s390x/helper.c
> >> +++ b/target/s390x/helper.c
> >> @@ -25,6 +25,7 @@
> >>  #include "qemu/timer.h"
> >>  #include "qemu/qemu-print.h"
> >>  #include "hw/s390x/ioinst.h"
> >> +#include "hw/s390x/pv.h"
> >>  #include "sysemu/hw_accel.h"
> >>  #include "sysemu/runstate.h"
> >>  #ifndef CONFIG_USER_ONLY
> >> @@ -246,6 +247,11 @@ int s390_store_status(S390CPU *cpu, hwaddr addr, bool 
> >> store_arch)
> >>  hwaddr len = sizeof(*sa);
> >>  int i;
> >>  
> >> +/* Storing will occur on next SIE entry for protected VMs */  
> > 
> > Maybe ... next SIE entry of the sending CPU  
> > ?  
> 
> Well that would be the current cpu, right?
> So:
> /* For PVMs storing will occur when this cpu enters SIE again */

With that comment tweak,
Reviewed-by: Cornelia Huck 


pgpTdry6OJBZr.pgp
Description: OpenPGP digital signature


[PULL 07/13] target/rx: Disassemble rx_index_addr into a string

2020-03-17 Thread Philippe Mathieu-Daudé
From: Richard Henderson 

We were eliding all zero indexes.  It is only ld==0 that does
not have an index in the instruction.  This also allows us to
avoid breaking the final print into multiple pieces.

Reviewed-by: Yoshinori Sato 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Message-Id: <20190531134315.4109-19-richard.hender...@linaro.org>
Acked-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/rx/disas.c | 154 +-
 1 file changed, 55 insertions(+), 99 deletions(-)

diff --git a/target/rx/disas.c b/target/rx/disas.c
index 04cdfdc567..7abb53d776 100644
--- a/target/rx/disas.c
+++ b/target/rx/disas.c
@@ -107,49 +107,42 @@ static const char psw[] = {
 'i', 'u', 0, 0, 0, 0, 0, 0,
 };
 
-static uint32_t rx_index_addr(int ld, int size, DisasContext *ctx)
+static void rx_index_addr(DisasContext *ctx, char out[8], int ld, int mi)
 {
-bfd_byte buf[2];
+uint32_t addr = ctx->addr;
+uint8_t buf[2];
+uint16_t dsp;
+
 switch (ld) {
 case 0:
-return 0;
+/* No index; return empty string.  */
+out[0] = '\0';
+return;
 case 1:
-ctx->dis->read_memory_func(ctx->addr, buf, 1, ctx->dis);
 ctx->addr += 1;
-return ((uint8_t)buf[0]) << size;
+ctx->dis->read_memory_func(addr, buf, 1, ctx->dis);
+dsp = buf[0];
+break;
 case 2:
-ctx->dis->read_memory_func(ctx->addr, buf, 2, ctx->dis);
 ctx->addr += 2;
-return lduw_le_p(buf) << size;
+ctx->dis->read_memory_func(addr, buf, 2, ctx->dis);
+dsp = lduw_le_p(buf);
+break;
+default:
+g_assert_not_reached();
 }
-g_assert_not_reached();
+
+sprintf(out, "%u", dsp << (mi < 3 ? mi : 4 - mi));
 }
 
 static void operand(DisasContext *ctx, int ld, int mi, int rs, int rd)
 {
-int dsp;
 static const char sizes[][4] = {".b", ".w", ".l", ".uw", ".ub"};
+char dsp[8];
+
 if (ld < 3) {
-switch (mi) {
-case 4:
-/* dsp[rs].ub */
-dsp = rx_index_addr(ld, RX_MEMORY_BYTE, ctx);
-break;
-case 3:
-/* dsp[rs].uw */
-dsp = rx_index_addr(ld, RX_MEMORY_WORD, ctx);
-break;
-default:
-/* dsp[rs].b */
-/* dsp[rs].w */
-/* dsp[rs].l */
-dsp = rx_index_addr(ld, mi, ctx);
-break;
-}
-if (dsp > 0) {
-prt("%d", dsp);
-}
-prt("[r%d]%s", rs, sizes[mi]);
+rx_index_addr(ctx, dsp, ld, mi);
+prt("%s[r%d]%s", dsp, rs, sizes[mi]);
 } else {
 prt("r%d", rs);
 }
@@ -235,7 +228,7 @@ static bool trans_MOV_ra(DisasContext *ctx, arg_MOV_ra *a)
 /* mov.[bwl] rs,rd */
 static bool trans_MOV_mm(DisasContext *ctx, arg_MOV_mm *a)
 {
-int dsp;
+char dspd[8], dsps[8];
 
 prt("mov.%c\t", size[a->sz]);
 if (a->lds == 3 && a->ldd == 3) {
@@ -244,29 +237,15 @@ static bool trans_MOV_mm(DisasContext *ctx, arg_MOV_mm *a)
 return true;
 }
 if (a->lds == 3) {
-prt("r%d, ", a->rd);
-dsp = rx_index_addr(a->ldd, a->sz, ctx);
-if (dsp > 0) {
-prt("%d", dsp);
-}
-prt("[r%d]", a->rs);
+rx_index_addr(ctx, dspd, a->ldd, a->sz);
+prt("r%d, %s[r%d]", a->rs, dspd, a->rd);
 } else if (a->ldd == 3) {
-dsp = rx_index_addr(a->lds, a->sz, ctx);
-if (dsp > 0) {
-prt("%d", dsp);
-}
-prt("[r%d], r%d", a->rs, a->rd);
+rx_index_addr(ctx, dsps, a->lds, a->sz);
+prt("%s[r%d], r%d", dsps, a->rs, a->rd);
 } else {
-dsp = rx_index_addr(a->lds, a->sz, ctx);
-if (dsp > 0) {
-prt("%d", dsp);
-}
-prt("[r%d], ", a->rs);
-dsp = rx_index_addr(a->ldd, a->sz, ctx);
-if (dsp > 0) {
-prt("%d", dsp);
-}
-prt("[r%d]", a->rd);
+rx_index_addr(ctx, dsps, a->lds, a->sz);
+rx_index_addr(ctx, dspd, a->ldd, a->sz);
+prt("%s[r%d], %s[r%d]", dsps, a->rs, dspd, a->rd);
 }
 return true;
 }
@@ -357,12 +336,10 @@ static bool trans_PUSH_r(DisasContext *ctx, arg_PUSH_r *a)
 /* push dsp[rs] */
 static bool trans_PUSH_m(DisasContext *ctx, arg_PUSH_m *a)
 {
-prt("push\t");
-int dsp = rx_index_addr(a->ld, a->sz, ctx);
-if (dsp > 0) {
-prt("%d", dsp);
-}
-prt("[r%d]", a->rs);
+char dsp[8];
+
+rx_index_addr(ctx, dsp, a->ld, a->sz);
+prt("push\t%s[r%d]", dsp, a->rs);
 return true;
 }
 
@@ -389,17 +366,13 @@ static bool trans_XCHG_rr(DisasContext *ctx, arg_XCHG_rr 
*a)
 /* xchg dsp[rs].,rd */
 static bool trans_XCHG_mr(DisasContext *ctx, arg_XCHG_mr *a)
 {
-int dsp;
 static const char msize[][4] = {
 "b", "w", "l", "ub", "uw",
 };
+char dsp[8];
 
-prt("xchg\t");
-dsp = rx_index_addr(a->ld, a->mi, ctx);
-if (dsp > 0) {
-

[PULL 03/13] target/rx: TCG translation

2020-03-17 Thread Philippe Mathieu-Daudé
From: Yoshinori Sato 

This part only supported RXv1 instructions.

Instruction manual:
  
https://www.renesas.com/us/en/doc/products/mpumcu/doc/rx_family/r01us0032ej0120_rxsm.pdf

Reviewed-by: Richard Henderson 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Yoshinori Sato 
Signed-off-by: Richard Henderson 
Message-Id: <20200224141923.82118-5-ys...@users.sourceforge.jp>
Acked-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/rx/insns.decode  |  621 ++
 target/rx/translate.c   | 2432 +++
 target/rx/Makefile.objs |   12 +
 3 files changed, 3065 insertions(+)
 create mode 100644 target/rx/insns.decode
 create mode 100644 target/rx/translate.c
 create mode 100644 target/rx/Makefile.objs

diff --git a/target/rx/insns.decode b/target/rx/insns.decode
new file mode 100644
index 00..232a61fc8e
--- /dev/null
+++ b/target/rx/insns.decode
@@ -0,0 +1,621 @@
+#
+# Renesas RX instruction decode definitions.
+#
+# Copyright (c) 2019 Richard Henderson 
+# Copyright (c) 2019 Yoshinori Sato 
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, see .
+#
+
+  cd dsp sz
+  dsp sz
+  rs
+rd rs
+rd imm
+   rd rs rs2
+   rd imm rs2
+rd rs ld mi
+rs ld mi imm
+rs ld mi rs2
+  ld sz rd cd
+
+%b1_bdsp   24:3 !function=bdsp_s
+
+@b1_bcnd_s  cd:1 ...dsp=%b1_bdsp sz=1
+@b1_bra_s   dsp=%b1_bdsp sz=1
+
+%b2_r_016:4
+%b2_li_2   18:2 !function=li
+%b2_li_8   24:2 !function=li
+%b2_dsp5_3 23:4 19:1
+
+@b2_rds   rd:4  rs=%b2_r_0
+@b2_rds_li    rd:4  rs2=%b2_r_0 imm=%b2_li_8
+@b2_rds_uimm4    imm:4 rd:4 rs2=%b2_r_0
+@b2_rs2_uimm4    imm:4 rs2:4rd=0
+@b2_rds_imm5    ... imm:5 rd:4  rs2=%b2_r_0
+@b2_rd_rs_li     rs2:4 rd:4 imm=%b2_li_8
+@b2_rd_ld_ub    .. ld:2 rs:4 rd:4   mi=4
+@b2_ld_imm3 .. ld:2 rs:4 . imm:3mi=4
+@b2_bcnd_b  cd:4 dsp:s8 sz=2
+@b2_bra_b    dsp:s8 sz=2
+
+
+
+%b3_r_08:4
+%b3_li_10  18:2 !function=li
+%b3_dsp5_8 23:1 16:4
+%b3_bdsp   8:s8 16:8
+
+@b3_rd_rs      rs:4 rd:4   
+@b3_rs_rd      rd:4 rs:4   
+@b3_rd_li       rd:4 \
+rs2=%b3_r_0 imm=%b3_li_10
+@b3_rd_ld    mi:2  ld:2 rs:4 rd:4  
+@b3_rd_ld_ub      .. ld:2 rs:4 rd:4 mi=4
+@b3_rd_ld_ul      .. ld:2 rs:4 rd:4 mi=2
+@b3_rd_rs_rs2     rd:4 rs:4 rs2:4  
+@b3_rds_imm5     ... imm:5 rd:4 rs2=%b3_r_0
+@b3_rd_rs_imm5   ... imm:5 rs2:4 rd:4  
+@b3_bcnd_w  ... cd:1    dsp=%b3_bdsp sz=3
+@b3_bra_w       dsp=%b3_bdsp sz=3
+@b3_ld_rd_rs      .. ld:2 rs:4 rd:4 mi=0
+@b3_sz_ld_rd_cd   sz:2 ld:2 rd:4 cd:4  
+
+
+
+%b4_li_18  18:2 !function=li
+%b4_dsp_16 0:s8 8:8
+%b4_bdsp   0:s8 8:8 16:8
+
+@b4_rd_ldmi  mi:2  ld:2   rs:4 rd:4
+@b4_bra_a          \
+dsp=%b4_bdsp sz=4
+
+# ABS rd
+ABS_rr 0111 1110 0010  @b2_rds
+# ABS rs, rd
+ABS_rr  1100       @b3_rd_rs
+
+# ADC #imm, rd
+ADC_ir  1101 0111 ..00 0010    @b3_rd_li
+# ADC rs, rd
+ADC_rr  1100  1011     @b3_rd_rs
+# ADC dsp[rs].l, rd
+# Note only mi==2 allowed.
+ADC_mr  0110 ..10 00..  0010   @b4_rd_ldmi
+
+# ADD #uimm4, rd
+ADD_irr0110 0010   @b2_rds_uimm4
+# ADD #imm, rs, rd
+ADD_irr0111 00..   @b2_rd_rs_li
+# ADD dsp[rs].ub, rd
+# ADD rs, rd
+ADD_mr 0100 10..   @b2_rd_ld_ub
+# ADD dsp[rs], rd
+ADD_mr  0110 ..00 10..     @b3_rd_ld
+# ADD rs, rs2, rd
+ADD_rrr

[PATCH v6 47/61] target/riscv: vector single-width floating-point reduction instructions

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 10 +++
 target/riscv/insn32.decode  |  4 +++
 target/riscv/insn_trans/trans_rvv.inc.c |  5 
 target/riscv/vector_helper.c| 40 +
 4 files changed, 59 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 6bd7965a23..319c534ceb 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1069,3 +1069,13 @@ DEF_HELPER_6(vwredsumu_vs_w, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(vwredsum_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vwredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vwredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(vfredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfredsum_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfredmax_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfredmax_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfredmax_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfredmin_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfredmin_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfredmin_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b69d804fda..0592075167 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -539,6 +539,10 @@ vredmaxu_vs 000110 . . . 010 . 1010111 
@r_vm
 vredmax_vs  000111 . . . 010 . 1010111 @r_vm
 vwredsumu_vs11 . . . 000 . 1010111 @r_vm
 vwredsum_vs 110001 . . . 000 . 1010111 @r_vm
+# Vector ordered and unordered reduction sum
+vfredsum_vs -1 . . . 001 . 1010111 @r_vm
+vfredmin_vs 000101 . . . 001 . 1010111 @r_vm
+vfredmax_vs 000111 . . . 001 . 1010111 @r_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 90c7cb2d63..d541c78474 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2181,3 +2181,8 @@ GEN_OPIVV_TRANS(vredxor_vs, reduction_check)
 /* Vector Widening Integer Reduction Instructions */
 GEN_OPIVV_WIDEN_TRANS(vwredsum_vs, reduction_check)
 GEN_OPIVV_WIDEN_TRANS(vwredsumu_vs, reduction_check)
+
+/* Vector Single-Width Floating-Point Reduction Instructions */
+GEN_OPFVV_TRANS(vfredsum_vs, reduction_check)
+GEN_OPFVV_TRANS(vfredmax_vs, reduction_check)
+GEN_OPFVV_TRANS(vfredmin_vs, reduction_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 678ede3c02..c0ba661522 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4378,3 +4378,43 @@ GEN_VEXT_RED(vwredsum_vs_w, int64_t, int32_t, H8, H4, 
DO_ADD, clearq)
 GEN_VEXT_RED(vwredsumu_vs_b, uint16_t, uint8_t, H2, H1, DO_ADD, clearh)
 GEN_VEXT_RED(vwredsumu_vs_h, uint32_t, uint16_t, H4, H2, DO_ADD, clearl)
 GEN_VEXT_RED(vwredsumu_vs_w, uint64_t, uint32_t, H8, H4, DO_ADD, clearq)
+
+/* Vector Single-Width Floating-Point Reduction Instructions */
+#define GEN_VEXT_FRED(NAME, TD, TS2, HD, HS2, OP, CLEAR_FN)\
+void HELPER(NAME)(void *vd, void *v0, void *vs1,   \
+void *vs2, CPURISCVState *env, uint32_t desc)  \
+{  \
+uint32_t mlen = vext_mlen(desc);   \
+uint32_t vm = vext_vm(desc);   \
+uint32_t vl = env->vl; \
+uint32_t i;\
+uint32_t tot = env_archcpu(env)->cfg.vlen / 8; \
+TD s1 =  *((TD *)vs1 + HD(0)); \
+   \
+if (vl == 0) { \
+return;\
+}  \
+for (i = 0; i < vl; i++) { \
+TS2 s2 = *((TS2 *)vs2 + HS2(i));   \
+if (!vm && !vext_elem_mask(v0, mlen, i)) { \
+continue;  \
+}  \
+s1 = OP(s1, (TD)s2, >fp_status);  \
+}  \
+*((TD *)vd + HD(0)) = s1;  \
+CLEAR_FN(vd, 1, sizeof(TD), tot);  \
+}
+/* Unordered sum */
+GEN_VEXT_FRED(vfredsum_vs_h, uint16_t, uint16_t, H2, H2, float16_add, clearh)
+GEN_VEXT_FRED(vfredsum_vs_w, uint32_t, uint32_t, H4, H4, float32_add, clearl)

[PULL 02/13] MAINTAINERS: Add entry for the Renesas RX architecture

2020-03-17 Thread Philippe Mathieu-Daudé
From: Yoshinori Sato 

Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Yoshinori Sato 
Signed-off-by: Richard Henderson 
Message-Id: <20200224141923.82118-2-ys...@users.sourceforge.jp>
Acked-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS | 5 +
 1 file changed, 5 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 32867bc636..3463533aee 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -276,6 +276,11 @@ F: include/hw/riscv/
 F: linux-user/host/riscv32/
 F: linux-user/host/riscv64/
 
+RENESAS RX CPUs
+M: Yoshinori Sato 
+S: Maintained
+F: target/rx/
+
 S390 TCG CPUs
 M: Richard Henderson 
 M: David Hildenbrand 
-- 
2.21.1




[PULL 10/13] target/rx: Emit all disassembly in one prt()

2020-03-17 Thread Philippe Mathieu-Daudé
From: Richard Henderson 

Many of the multi-part prints have been eliminated by previous
patches.  Eliminate the rest of them.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Yoshinori Sato 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Message-Id: <20190531134315.4109-22-richard.hender...@linaro.org>
Acked-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/rx/disas.c | 75 ---
 1 file changed, 39 insertions(+), 36 deletions(-)

diff --git a/target/rx/disas.c b/target/rx/disas.c
index a0c444020c..814ef97480 100644
--- a/target/rx/disas.c
+++ b/target/rx/disas.c
@@ -228,24 +228,21 @@ static bool trans_MOV_ra(DisasContext *ctx, arg_MOV_ra *a)
 /* mov.[bwl] rs,rd */
 static bool trans_MOV_mm(DisasContext *ctx, arg_MOV_mm *a)
 {
-char dspd[8], dsps[8];
+char dspd[8], dsps[8], szc = size[a->sz];
 
-prt("mov.%c\t", size[a->sz]);
 if (a->lds == 3 && a->ldd == 3) {
 /* mov.[bwl] rs,rd */
-prt("r%d, r%d", a->rs, a->rd);
-return true;
-}
-if (a->lds == 3) {
+prt("mov.%c\tr%d, r%d", szc, a->rs, a->rd);
+} else if (a->lds == 3) {
 rx_index_addr(ctx, dspd, a->ldd, a->sz);
-prt("r%d, %s[r%d]", a->rs, dspd, a->rd);
+prt("mov.%c\tr%d, %s[r%d]", szc, a->rs, dspd, a->rd);
 } else if (a->ldd == 3) {
 rx_index_addr(ctx, dsps, a->lds, a->sz);
-prt("%s[r%d], r%d", dsps, a->rs, a->rd);
+prt("mov.%c\t%s[r%d], r%d", szc, dsps, a->rs, a->rd);
 } else {
 rx_index_addr(ctx, dsps, a->lds, a->sz);
 rx_index_addr(ctx, dspd, a->ldd, a->sz);
-prt("%s[r%d], %s[r%d]", dsps, a->rs, dspd, a->rd);
+prt("mov.%c\t%s[r%d], %s[r%d]", szc, dsps, a->rs, dspd, a->rd);
 }
 return true;
 }
@@ -254,8 +251,11 @@ static bool trans_MOV_mm(DisasContext *ctx, arg_MOV_mm *a)
 /* mov.[bwl] rs,[-rd] */
 static bool trans_MOV_rp(DisasContext *ctx, arg_MOV_rp *a)
 {
-prt("mov.%c\tr%d, ", size[a->sz], a->rs);
-prt((a->ad == 0) ? "[r%d+]" : "[-r%d]", a->rd);
+if (a->ad) {
+prt("mov.%c\tr%d, [-r%d]", size[a->sz], a->rs, a->rd);
+} else {
+prt("mov.%c\tr%d, [r%d+]", size[a->sz], a->rs, a->rd);
+}
 return true;
 }
 
@@ -263,9 +263,11 @@ static bool trans_MOV_rp(DisasContext *ctx, arg_MOV_rp *a)
 /* mov.[bwl] [-rd],rs */
 static bool trans_MOV_pr(DisasContext *ctx, arg_MOV_pr *a)
 {
-prt("mov.%c\t", size[a->sz]);
-prt((a->ad == 0) ? "[r%d+]" : "[-r%d]", a->rd);
-prt(", r%d", a->rs);
+if (a->ad) {
+prt("mov.%c\t[-r%d], r%d", size[a->sz], a->rd, a->rs);
+} else {
+prt("mov.%c\t[r%d+], r%d", size[a->sz], a->rd, a->rs);
+}
 return true;
 }
 
@@ -299,9 +301,11 @@ static bool trans_MOVU_ar(DisasContext *ctx, arg_MOVU_ar 
*a)
 /* movu.[bw] [-rs],rd */
 static bool trans_MOVU_pr(DisasContext *ctx, arg_MOVU_pr *a)
 {
-prt("movu.%c\t", size[a->sz]);
-prt((a->ad == 0) ? "[r%d+]" : "[-r%d]", a->rd);
-prt(", r%d", a->rs);
+if (a->ad) {
+prt("movu.%c\t[-r%d], r%d", size[a->sz], a->rd, a->rs);
+} else {
+prt("movu.%c\t[r%d+], r%d", size[a->sz], a->rd, a->rs);
+}
 return true;
 }
 
@@ -478,11 +482,11 @@ static bool trans_TST_mr(DisasContext *ctx, arg_TST_mr *a)
 /* not rs, rd */
 static bool trans_NOT_rr(DisasContext *ctx, arg_NOT_rr *a)
 {
-prt("not\t");
 if (a->rs != a->rd) {
-prt("r%d, ", a->rs);
+prt("not\tr%d, r%d", a->rs, a->rd);
+} else {
+prt("not\tr%d", a->rs);
 }
-prt("r%d", a->rd);
 return true;
 }
 
@@ -490,11 +494,11 @@ static bool trans_NOT_rr(DisasContext *ctx, arg_NOT_rr *a)
 /* neg rs, rd */
 static bool trans_NEG_rr(DisasContext *ctx, arg_NEG_rr *a)
 {
-prt("neg\t");
 if (a->rs != a->rd) {
-prt("r%d, ", a->rs);
+prt("neg\tr%d, r%d", a->rs, a->rd);
+} else {
+prt("neg\tr%d", a->rs);
 }
-prt("r%d", a->rd);
 return true;
 }
 
@@ -606,11 +610,10 @@ static bool trans_SBB_mr(DisasContext *ctx, arg_SBB_mr *a)
 /* abs rs, rd */
 static bool trans_ABS_rr(DisasContext *ctx, arg_ABS_rr *a)
 {
-prt("abs\t");
-if (a->rs == a->rd) {
-prt("r%d", a->rd);
+if (a->rs != a->rd) {
+prt("abs\tr%d, r%d", a->rs, a->rd);
 } else {
-prt("r%d, r%d", a->rs, a->rd);
+prt("abs\tr%d", a->rs);
 }
 return true;
 }
@@ -733,11 +736,11 @@ static bool trans_DIVU_mr(DisasContext *ctx, arg_DIVU_mr 
*a)
 /* shll #imm:5, rs, rd */
 static bool trans_SHLL_irr(DisasContext *ctx, arg_SHLL_irr *a)
 {
-prt("shll\t#%d, ", a->imm);
 if (a->rs2 != a->rd) {
-prt("r%d, ", a->rs2);
+prt("shll\t#%d, r%d, r%d", a->imm, a->rs2, a->rd);
+} else {
+prt("shll\t#%d, r%d", a->imm, a->rd);
 }
-prt("r%d", a->rd);
 return true;
 }
 
@@ -752,11 +755,11 @@ static bool trans_SHLL_rr(DisasContext *ctx, arg_SHLL_rr 
*a)
 /* shar #imm:5, rs, rd */
 static bool 

[PATCH v6 48/61] target/riscv: vector widening floating-point reduction instructions

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   |  3 ++
 target/riscv/insn32.decode  |  2 +
 target/riscv/insn_trans/trans_rvv.inc.c |  3 ++
 target/riscv/vector_helper.c| 52 +
 4 files changed, 60 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 319c534ceb..15569223cb 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1079,3 +1079,6 @@ DEF_HELPER_6(vfredmax_vs_d, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(vfredmin_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfredmin_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfredmin_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(vfwredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 0592075167..526a964d28 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -543,6 +543,8 @@ vwredsum_vs 110001 . . . 000 . 1010111 @r_vm
 vfredsum_vs -1 . . . 001 . 1010111 @r_vm
 vfredmin_vs 000101 . . . 001 . 1010111 @r_vm
 vfredmax_vs 000111 . . . 001 . 1010111 @r_vm
+# Vector widening ordered and unordered float reduction sum
+vfwredsum_vs1100-1 . . . 001 . 1010111 @r_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index d541c78474..fd927f0959 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2186,3 +2186,6 @@ GEN_OPIVV_WIDEN_TRANS(vwredsumu_vs, reduction_check)
 GEN_OPFVV_TRANS(vfredsum_vs, reduction_check)
 GEN_OPFVV_TRANS(vfredmax_vs, reduction_check)
 GEN_OPFVV_TRANS(vfredmin_vs, reduction_check)
+
+/* Vector Widening Floating-Point Reduction Instructions */
+GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, reduction_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index c0ba661522..57532959fb 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4418,3 +4418,55 @@ GEN_VEXT_FRED(vfredmax_vs_d, uint64_t, uint64_t, H8, H8, 
float64_maxnum, clearq)
 GEN_VEXT_FRED(vfredmin_vs_h, uint16_t, uint16_t, H2, H2, float16_minnum, 
clearh)
 GEN_VEXT_FRED(vfredmin_vs_w, uint32_t, uint32_t, H4, H4, float32_minnum, 
clearl)
 GEN_VEXT_FRED(vfredmin_vs_d, uint64_t, uint64_t, H8, H8, float64_minnum, 
clearq)
+
+/* Vector Widening Floating-Point Reduction Instructions */
+/* Unordered reduce 2*SEW = 2*SEW + sum(promote(SEW)) */
+void HELPER(vfwredsum_vs_h)(void *vd, void *v0, void *vs1,
+void *vs2, CPURISCVState *env, uint32_t desc)
+{
+uint32_t mlen = vext_mlen(desc);
+uint32_t vm = vext_vm(desc);
+uint32_t vl = env->vl;
+uint32_t i;
+uint32_t tot = env_archcpu(env)->cfg.vlen / 8;
+uint32_t s1 =  *((uint32_t *)vs1 + H4(0));
+
+if (vl == 0) {
+return;
+}
+for (i = 0; i < vl; i++) {
+uint16_t s2 = *((uint16_t *)vs2 + H2(i));
+if (!vm && !vext_elem_mask(v0, mlen, i)) {
+continue;
+}
+s1 = float32_add(s1, float16_to_float32(s2, true, >fp_status),
+>fp_status);
+}
+*((uint32_t *)vd + H4(0)) = s1;
+clearl(vd, 1, sizeof(uint32_t), tot);
+}
+
+void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void *vs1,
+void *vs2, CPURISCVState *env, uint32_t desc)
+{
+uint32_t mlen = vext_mlen(desc);
+uint32_t vm = vext_vm(desc);
+uint32_t vl = env->vl;
+uint32_t i;
+uint32_t tot = env_archcpu(env)->cfg.vlen / 8;
+uint64_t s1 =  *((uint64_t *)vs1);
+
+if (vl == 0) {
+return;
+}
+for (i = 0; i < vl; i++) {
+uint32_t s2 = *((uint32_t *)vs2 + H4(i));
+if (!vm && !vext_elem_mask(v0, mlen, i)) {
+continue;
+}
+s1 = float64_add(s1, float32_to_float64(s2, >fp_status),
+>fp_status);
+}
+*((uint64_t *)vd) = s1;
+clearq(vd, 1, sizeof(uint64_t), tot);
+}
-- 
2.23.0




[PATCH v6 44/61] target/riscv: narrowing floating-point/integer type-convert instructions

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 11 +++
 target/riscv/insn32.decode  |  5 +++
 target/riscv/insn_trans/trans_rvv.inc.c | 42 +
 target/riscv/vector_helper.c| 39 +++
 4 files changed, 97 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index b5985f78bf..72bf084d57 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1018,3 +1018,14 @@ DEF_HELPER_5(vfwcvt_f_x_v_h, void, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_5(vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vfncvt_xu_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index e0efc63ec2..57ac4de1c2 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -524,6 +524,11 @@ vfwcvt_x_f_v100010 . . 01001 001 . 1010111 
@r2_vm
 vfwcvt_f_xu_v   100010 . . 01010 001 . 1010111 @r2_vm
 vfwcvt_f_x_v100010 . . 01011 001 . 1010111 @r2_vm
 vfwcvt_f_f_v100010 . . 01100 001 . 1010111 @r2_vm
+vfncvt_xu_f_v   100010 . . 1 001 . 1010111 @r2_vm
+vfncvt_x_f_v100010 . . 10001 001 . 1010111 @r2_vm
+vfncvt_f_xu_v   100010 . . 10010 001 . 1010111 @r2_vm
+vfncvt_f_x_v100010 . . 10011 001 . 1010111 @r2_vm
+vfncvt_f_f_v100010 . . 10100 001 . 1010111 @r2_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 7e8df1c663..53984da94c 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2118,3 +2118,45 @@ GEN_OPFV_WIDEN_TRANS(vfwcvt_x_f_v)
 GEN_OPFV_WIDEN_TRANS(vfwcvt_f_xu_v)
 GEN_OPFV_WIDEN_TRANS(vfwcvt_f_x_v)
 GEN_OPFV_WIDEN_TRANS(vfwcvt_f_f_v)
+
+/* Narrowing Floating-Point/Integer Type-Convert Instructions */
+
+/*
+ * If the current SEW does not correspond to a supported IEEE floating-point
+ * type, an illegal instruction exception is raised
+ */
+static bool opfv_narrow_check(DisasContext *s, arg_rmr *a)
+{
+return (vext_check_isa_ill(s) &&
+vext_check_overlap_mask(s, a->rd, a->vm, false) &&
+vext_check_reg(s, a->rd, false) &&
+vext_check_reg(s, a->rs2, true) &&
+vext_check_overlap_group(a->rd, 1 << s->lmul, a->rs2,
+2 << s->lmul) &&
+(s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0));
+}
+
+#define GEN_OPFV_NARROW_TRANS(NAME)\
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
+{  \
+if (opfv_narrow_check(s, a)) { \
+uint32_t data = 0; \
+static gen_helper_gvec_3_ptr * const fns[2] = {\
+gen_helper_##NAME##_h, \
+gen_helper_##NAME##_w, \
+}; \
+data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \
+data = FIELD_DP32(data, VDATA, VM, a->vm); \
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+vreg_ofs(s, a->rs2), cpu_env, 0,   \
+s->vlen / 8, data, fns[s->sew - 1]);   \
+return true;   \
+}  \
+return false;  \
+}
+GEN_OPFV_NARROW_TRANS(vfncvt_xu_f_v)
+GEN_OPFV_NARROW_TRANS(vfncvt_x_f_v)
+GEN_OPFV_NARROW_TRANS(vfncvt_f_xu_v)
+GEN_OPFV_NARROW_TRANS(vfncvt_f_x_v)
+GEN_OPFV_NARROW_TRANS(vfncvt_f_f_v)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 0eb0ce02a8..c34f334127 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4251,3 +4251,42 @@ RVVCALL(OPFVV1, vfwcvt_f_f_v_h, WOP_UU_H, H4, 

[PULL 09/13] target/rx: Use prt_ldmi for XCHG_mr disassembly

2020-03-17 Thread Philippe Mathieu-Daudé
From: Richard Henderson 

Note that the ld == 3 case handled by prt_ldmi is decoded as
XCHG_rr and cannot appear here.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Yoshinori Sato 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Message-Id: <20190531134315.4109-21-richard.hender...@linaro.org>
Acked-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/rx/disas.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/target/rx/disas.c b/target/rx/disas.c
index 0c4115669d..a0c444020c 100644
--- a/target/rx/disas.c
+++ b/target/rx/disas.c
@@ -366,13 +366,7 @@ static bool trans_XCHG_rr(DisasContext *ctx, arg_XCHG_rr 
*a)
 /* xchg dsp[rs].,rd */
 static bool trans_XCHG_mr(DisasContext *ctx, arg_XCHG_mr *a)
 {
-static const char msize[][4] = {
-"b", "w", "l", "ub", "uw",
-};
-char dsp[8];
-
-rx_index_addr(ctx, dsp, a->ld, a->mi);
-prt("xchg\t%s[r%d].%s, r%d", dsp, a->rs, msize[a->mi], a->rd);
+prt_ldmi(ctx, "xchg", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
-- 
2.21.1




[PULL 06/13] target/rx: RX disassembler

2020-03-17 Thread Philippe Mathieu-Daudé
From: Yoshinori Sato 

Reviewed-by: Richard Henderson 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Yoshinori Sato 
Signed-off-by: Richard Henderson 
Message-Id: <20200224141923.82118-8-ys...@users.sourceforge.jp>
Acked-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 include/disas/dis-asm.h |5 +
 target/rx/disas.c   | 1480 +++
 2 files changed, 1485 insertions(+)
 create mode 100644 target/rx/disas.c

diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index f87f468809..c5f9fa08ab 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -226,6 +226,10 @@ enum bfd_architecture
 #define bfd_mach_nios2r22
   bfd_arch_lm32,   /* Lattice Mico32 */
 #define bfd_mach_lm32 1
+  bfd_arch_rx,   /* Renesas RX */
+#define bfd_mach_rx0x75
+#define bfd_mach_rx_v2 0x76
+#define bfd_mach_rx_v3 0x77
   bfd_arch_last
   };
 #define bfd_mach_s390_31 31
@@ -436,6 +440,7 @@ int print_insn_little_nios2 (bfd_vma, 
disassemble_info*);
 int print_insn_xtensa   (bfd_vma, disassemble_info*);
 int print_insn_riscv32  (bfd_vma, disassemble_info*);
 int print_insn_riscv64  (bfd_vma, disassemble_info*);
+int print_insn_rx(bfd_vma, disassemble_info *);
 
 #if 0
 /* Fetch the disassembler for a given BFD, if that support is available.  */
diff --git a/target/rx/disas.c b/target/rx/disas.c
new file mode 100644
index 00..04cdfdc567
--- /dev/null
+++ b/target/rx/disas.c
@@ -0,0 +1,1480 @@
+/*
+ * Renesas RX Disassembler
+ *
+ * Copyright (c) 2019 Yoshinori Sato 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "disas/dis-asm.h"
+#include "qemu/bitops.h"
+#include "cpu.h"
+
+typedef struct DisasContext {
+disassemble_info *dis;
+uint32_t addr;
+uint32_t pc;
+} DisasContext;
+
+
+static uint32_t decode_load_bytes(DisasContext *ctx, uint32_t insn,
+   int i, int n)
+{
+bfd_byte buf;
+while (++i <= n) {
+ctx->dis->read_memory_func(ctx->addr++, , 1, ctx->dis);
+insn |= buf << (32 - i * 8);
+}
+return insn;
+}
+
+static int32_t li(DisasContext *ctx, int sz)
+{
+int32_t addr;
+bfd_byte buf[4];
+addr = ctx->addr;
+
+switch (sz) {
+case 1:
+ctx->addr += 1;
+ctx->dis->read_memory_func(addr, buf, 1, ctx->dis);
+return (int8_t)buf[0];
+case 2:
+ctx->addr += 2;
+ctx->dis->read_memory_func(addr, buf, 2, ctx->dis);
+return ldsw_le_p(buf);
+case 3:
+ctx->addr += 3;
+ctx->dis->read_memory_func(addr, buf, 3, ctx->dis);
+return (int8_t)buf[2] << 16 | lduw_le_p(buf);
+case 0:
+ctx->addr += 4;
+ctx->dis->read_memory_func(addr, buf, 4, ctx->dis);
+return ldl_le_p(buf);
+default:
+g_assert_not_reached();
+}
+}
+
+static int bdsp_s(DisasContext *ctx, int d)
+{
+/*
+ * 0 -> 8
+ * 1 -> 9
+ * 2 -> 10
+ * 3 -> 3
+ * :
+ * 7 -> 7
+ */
+if (d < 3) {
+d += 8;
+}
+return d;
+}
+
+/* Include the auto-generated decoder.  */
+#include "decode.inc.c"
+
+#define prt(...) (ctx->dis->fprintf_func)((ctx->dis->stream), __VA_ARGS__)
+
+#define RX_MEMORY_BYTE 0
+#define RX_MEMORY_WORD 1
+#define RX_MEMORY_LONG 2
+
+#define RX_IM_BYTE 0
+#define RX_IM_WORD 1
+#define RX_IM_LONG 2
+#define RX_IM_UWORD 3
+
+static const char size[] = {'b', 'w', 'l'};
+static const char cond[][4] = {
+"eq", "ne", "c", "nc", "gtu", "leu", "pz", "n",
+"ge", "lt", "gt", "le", "o", "no", "ra", "f"
+};
+static const char psw[] = {
+'c', 'z', 's', 'o', 0, 0, 0, 0,
+'i', 'u', 0, 0, 0, 0, 0, 0,
+};
+
+static uint32_t rx_index_addr(int ld, int size, DisasContext *ctx)
+{
+bfd_byte buf[2];
+switch (ld) {
+case 0:
+return 0;
+case 1:
+ctx->dis->read_memory_func(ctx->addr, buf, 1, ctx->dis);
+ctx->addr += 1;
+return ((uint8_t)buf[0]) << size;
+case 2:
+ctx->dis->read_memory_func(ctx->addr, buf, 2, ctx->dis);
+ctx->addr += 2;
+return lduw_le_p(buf) << size;
+}
+g_assert_not_reached();
+}
+
+static void operand(DisasContext *ctx, int ld, int mi, int rs, int rd)
+{
+int dsp;
+static const char sizes[][4] = {".b", ".w", ".l", ".uw", ".ub"};
+if (ld < 3) {
+switch (mi) {
+ 

[PULL 08/13] target/rx: Replace operand with prt_ldmi in disassembler

2020-03-17 Thread Philippe Mathieu-Daudé
From: Richard Henderson 

This has consistency with prt_ri().  It loads all data before
beginning output.  It uses exactly one call to prt() to emit
the full instruction.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Yoshinori Sato 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Message-Id: <20190531134315.4109-20-richard.hender...@linaro.org>
Acked-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/rx/disas.c | 77 +--
 1 file changed, 27 insertions(+), 50 deletions(-)

diff --git a/target/rx/disas.c b/target/rx/disas.c
index 7abb53d776..0c4115669d 100644
--- a/target/rx/disas.c
+++ b/target/rx/disas.c
@@ -135,18 +135,18 @@ static void rx_index_addr(DisasContext *ctx, char out[8], 
int ld, int mi)
 sprintf(out, "%u", dsp << (mi < 3 ? mi : 4 - mi));
 }
 
-static void operand(DisasContext *ctx, int ld, int mi, int rs, int rd)
+static void prt_ldmi(DisasContext *ctx, const char *insn,
+ int ld, int mi, int rs, int rd)
 {
 static const char sizes[][4] = {".b", ".w", ".l", ".uw", ".ub"};
 char dsp[8];
 
 if (ld < 3) {
 rx_index_addr(ctx, dsp, ld, mi);
-prt("%s[r%d]%s", dsp, rs, sizes[mi]);
+prt("%s\t%s[r%d]%s, r%d", insn, dsp, rs, sizes[mi], rd);
 } else {
-prt("r%d", rs);
+prt("%s\tr%d, r%d", insn, rs, rd);
 }
-prt(", r%d", rd);
 }
 
 static void prt_ir(DisasContext *ctx, const char *insn, int imm, int rd)
@@ -416,8 +416,7 @@ static bool trans_AND_ir(DisasContext *ctx, arg_AND_ir *a)
 /* and rs,rd */
 static bool trans_AND_mr(DisasContext *ctx, arg_AND_mr *a)
 {
-prt("and\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "and", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -440,8 +439,7 @@ static bool trans_OR_ir(DisasContext *ctx, arg_OR_ir *a)
 /* or rs,rd */
 static bool trans_OR_mr(DisasContext *ctx, arg_OR_mr *a)
 {
-prt("or\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "or", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -463,8 +461,7 @@ static bool trans_XOR_ir(DisasContext *ctx, arg_XOR_ir *a)
 /* xor rs,rd */
 static bool trans_XOR_mr(DisasContext *ctx, arg_XOR_mr *a)
 {
-prt("xor\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "xor", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -479,8 +476,7 @@ static bool trans_TST_ir(DisasContext *ctx, arg_TST_ir *a)
 /* tst rs, rd */
 static bool trans_TST_mr(DisasContext *ctx, arg_TST_mr *a)
 {
-prt("tst\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "tst", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -548,8 +544,7 @@ static bool trans_ADD_irr(DisasContext *ctx, arg_ADD_irr *a)
 /* add dsp[rs], rd */
 static bool trans_ADD_mr(DisasContext *ctx, arg_ADD_mr *a)
 {
-prt("add\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "add", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -573,8 +568,7 @@ static bool trans_CMP_ir(DisasContext *ctx, arg_CMP_ir *a)
 /* cmp dsp[rs], rs2 */
 static bool trans_CMP_mr(DisasContext *ctx, arg_CMP_mr *a)
 {
-prt("cmp\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "cmp", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -589,8 +583,7 @@ static bool trans_SUB_ir(DisasContext *ctx, arg_SUB_ir *a)
 /* sub dsp[rs], rd */
 static bool trans_SUB_mr(DisasContext *ctx, arg_SUB_mr *a)
 {
-prt("sub\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "sub", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -611,8 +604,7 @@ static bool trans_SBB_rr(DisasContext *ctx, arg_SBB_rr *a)
 /* sbb dsp[rs], rd */
 static bool trans_SBB_mr(DisasContext *ctx, arg_SBB_mr *a)
 {
-prt("sbb\t");
-operand(ctx, a->ld, RX_IM_LONG, a->rs, a->rd);
+prt_ldmi(ctx, "sbb", a->ld, RX_IM_LONG, a->rs, a->rd);
 return true;
 }
 
@@ -640,8 +632,7 @@ static bool trans_MAX_ir(DisasContext *ctx, arg_MAX_ir *a)
 /* max dsp[rs], rd */
 static bool trans_MAX_mr(DisasContext *ctx, arg_MAX_mr *a)
 {
-prt("max\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "max", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -656,8 +647,7 @@ static bool trans_MIN_ir(DisasContext *ctx, arg_MIN_ir *a)
 /* min dsp[rs], rd */
 static bool trans_MIN_mr(DisasContext *ctx, arg_MIN_mr *a)
 {
-prt("max\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "min", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -673,8 +663,7 @@ static bool trans_MUL_ir(DisasContext *ctx, arg_MUL_ir *a)
 /* mul dsp[rs], rd */
 static bool trans_MUL_mr(DisasContext *ctx, arg_MUL_mr *a)
 {
-prt("mul\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "mul", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -696,8 +685,7 @@ static bool trans_EMUL_ir(DisasContext *ctx, arg_EMUL_ir *a)
 /* emul dsp[rs], rd */
 

[PATCH v6 43/61] target/riscv: widening floating-point/integer type-convert instructions

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 11 +++
 target/riscv/insn32.decode  |  5 +++
 target/riscv/insn_trans/trans_rvv.inc.c | 42 +
 target/riscv/vector_helper.c| 42 +
 4 files changed, 100 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 5da6b8fcfa..b5985f78bf 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1007,3 +1007,14 @@ DEF_HELPER_5(vfcvt_f_xu_v_d, void, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_5(vfcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfcvt_f_x_v_d, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vfwcvt_xu_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 53562c6663..e0efc63ec2 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -519,6 +519,11 @@ vfcvt_xu_f_v100010 . . 0 001 . 1010111 
@r2_vm
 vfcvt_x_f_v 100010 . . 1 001 . 1010111 @r2_vm
 vfcvt_f_xu_v100010 . . 00010 001 . 1010111 @r2_vm
 vfcvt_f_x_v 100010 . . 00011 001 . 1010111 @r2_vm
+vfwcvt_xu_f_v   100010 . . 01000 001 . 1010111 @r2_vm
+vfwcvt_x_f_v100010 . . 01001 001 . 1010111 @r2_vm
+vfwcvt_f_xu_v   100010 . . 01010 001 . 1010111 @r2_vm
+vfwcvt_f_x_v100010 . . 01011 001 . 1010111 @r2_vm
+vfwcvt_f_f_v100010 . . 01100 001 . 1010111 @r2_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 0aa0001f12..7e8df1c663 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2076,3 +2076,45 @@ GEN_OPFV_TRANS(vfcvt_xu_f_v, opfv_check)
 GEN_OPFV_TRANS(vfcvt_x_f_v, opfv_check)
 GEN_OPFV_TRANS(vfcvt_f_xu_v, opfv_check)
 GEN_OPFV_TRANS(vfcvt_f_x_v, opfv_check)
+
+/* Widening Floating-Point/Integer Type-Convert Instructions */
+
+/*
+ * If the current SEW does not correspond to a supported IEEE floating-point
+ * type, an illegal instruction exception is raised
+ */
+static bool opfv_widen_check(DisasContext *s, arg_rmr *a)
+{
+return (vext_check_isa_ill(s) &&
+vext_check_overlap_mask(s, a->rd, a->vm, true) &&
+vext_check_reg(s, a->rd, true) &&
+vext_check_reg(s, a->rs2, false) &&
+vext_check_overlap_group(a->rd, 2 << s->lmul, a->rs2,
+1 << s->lmul) &&
+(s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0));
+}
+
+#define GEN_OPFV_WIDEN_TRANS(NAME) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
+{  \
+if (opfv_widen_check(s, a)) {  \
+uint32_t data = 0; \
+static gen_helper_gvec_3_ptr * const fns[2] = {\
+gen_helper_##NAME##_h, \
+gen_helper_##NAME##_w, \
+}; \
+data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \
+data = FIELD_DP32(data, VDATA, VM, a->vm); \
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+vreg_ofs(s, a->rs2), cpu_env, 0,   \
+s->vlen / 8, data, fns[s->sew - 1]);   \
+return true;   \
+}  \
+return false;  \
+}
+GEN_OPFV_WIDEN_TRANS(vfwcvt_xu_f_v)
+GEN_OPFV_WIDEN_TRANS(vfwcvt_x_f_v)
+GEN_OPFV_WIDEN_TRANS(vfwcvt_f_xu_v)
+GEN_OPFV_WIDEN_TRANS(vfwcvt_f_x_v)
+GEN_OPFV_WIDEN_TRANS(vfwcvt_f_f_v)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 0de986aed5..0eb0ce02a8 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4209,3 +4209,45 @@ RVVCALL(OPFVV1, vfcvt_f_x_v_d, 

[PULL 11/13] target/rx: Collect all bytes during disassembly

2020-03-17 Thread Philippe Mathieu-Daudé
From: Richard Henderson 

Collected, to be used in the next patch.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Yoshinori Sato 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Message-Id: <20190531134315.4109-23-richard.hender...@linaro.org>
Acked-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/rx/disas.c | 62 ---
 1 file changed, 42 insertions(+), 20 deletions(-)

diff --git a/target/rx/disas.c b/target/rx/disas.c
index 814ef97480..dcfb7baf99 100644
--- a/target/rx/disas.c
+++ b/target/rx/disas.c
@@ -25,43 +25,59 @@ typedef struct DisasContext {
 disassemble_info *dis;
 uint32_t addr;
 uint32_t pc;
+uint8_t len;
+uint8_t bytes[8];
 } DisasContext;
 
 
 static uint32_t decode_load_bytes(DisasContext *ctx, uint32_t insn,
-   int i, int n)
+  int i, int n)
 {
-bfd_byte buf;
+uint32_t addr = ctx->addr;
+
+g_assert(ctx->len == i);
+g_assert(n <= ARRAY_SIZE(ctx->bytes));
+
 while (++i <= n) {
-ctx->dis->read_memory_func(ctx->addr++, , 1, ctx->dis);
-insn |= buf << (32 - i * 8);
+ctx->dis->read_memory_func(addr++, >bytes[i - 1], 1, ctx->dis);
+insn |= ctx->bytes[i - 1] << (32 - i * 8);
 }
+ctx->addr = addr;
+ctx->len = n;
+
 return insn;
 }
 
 static int32_t li(DisasContext *ctx, int sz)
 {
-int32_t addr;
-bfd_byte buf[4];
-addr = ctx->addr;
+uint32_t addr = ctx->addr;
+uintptr_t len = ctx->len;
 
 switch (sz) {
 case 1:
+g_assert(len + 1 <= ARRAY_SIZE(ctx->bytes));
 ctx->addr += 1;
-ctx->dis->read_memory_func(addr, buf, 1, ctx->dis);
-return (int8_t)buf[0];
+ctx->len += 1;
+ctx->dis->read_memory_func(addr, ctx->bytes + len, 1, ctx->dis);
+return (int8_t)ctx->bytes[len];
 case 2:
+g_assert(len + 2 <= ARRAY_SIZE(ctx->bytes));
 ctx->addr += 2;
-ctx->dis->read_memory_func(addr, buf, 2, ctx->dis);
-return ldsw_le_p(buf);
+ctx->len += 2;
+ctx->dis->read_memory_func(addr, ctx->bytes + len, 2, ctx->dis);
+return ldsw_le_p(ctx->bytes + len);
 case 3:
+g_assert(len + 3 <= ARRAY_SIZE(ctx->bytes));
 ctx->addr += 3;
-ctx->dis->read_memory_func(addr, buf, 3, ctx->dis);
-return (int8_t)buf[2] << 16 | lduw_le_p(buf);
+ctx->len += 3;
+ctx->dis->read_memory_func(addr, ctx->bytes + len, 3, ctx->dis);
+return (int8_t)ctx->bytes[len + 2] << 16 | lduw_le_p(ctx->bytes + len);
 case 0:
+g_assert(len + 4 <= ARRAY_SIZE(ctx->bytes));
 ctx->addr += 4;
-ctx->dis->read_memory_func(addr, buf, 4, ctx->dis);
-return ldl_le_p(buf);
+ctx->len += 4;
+ctx->dis->read_memory_func(addr, ctx->bytes + len, 4, ctx->dis);
+return ldl_le_p(ctx->bytes + len);
 default:
 g_assert_not_reached();
 }
@@ -110,7 +126,7 @@ static const char psw[] = {
 static void rx_index_addr(DisasContext *ctx, char out[8], int ld, int mi)
 {
 uint32_t addr = ctx->addr;
-uint8_t buf[2];
+uintptr_t len = ctx->len;
 uint16_t dsp;
 
 switch (ld) {
@@ -119,14 +135,18 @@ static void rx_index_addr(DisasContext *ctx, char out[8], 
int ld, int mi)
 out[0] = '\0';
 return;
 case 1:
+g_assert(len + 1 <= ARRAY_SIZE(ctx->bytes));
 ctx->addr += 1;
-ctx->dis->read_memory_func(addr, buf, 1, ctx->dis);
-dsp = buf[0];
+ctx->len += 1;
+ctx->dis->read_memory_func(addr, ctx->bytes + len, 1, ctx->dis);
+dsp = ctx->bytes[len];
 break;
 case 2:
+g_assert(len + 2 <= ARRAY_SIZE(ctx->bytes));
 ctx->addr += 2;
-ctx->dis->read_memory_func(addr, buf, 2, ctx->dis);
-dsp = lduw_le_p(buf);
+ctx->len += 2;
+ctx->dis->read_memory_func(addr, ctx->bytes + len, 2, ctx->dis);
+dsp = lduw_le_p(ctx->bytes + len);
 break;
 default:
 g_assert_not_reached();
@@ -1392,8 +1412,10 @@ int print_insn_rx(bfd_vma addr, disassemble_info *dis)
 DisasContext ctx;
 uint32_t insn;
 int i;
+
 ctx.dis = dis;
 ctx.pc = ctx.addr = addr;
+ctx.len = 0;
 
 insn = decode_load();
 if (!decode(, insn)) {
-- 
2.21.1




Re: [PATCH 0/3] Minor error handling cleanups

2020-03-17 Thread Markus Armbruster
Queued, including Vladimir's PATCH 4/3.  Thanks!




[PULL 00/13] target: Add the Renesas RX architecture

2020-03-17 Thread Philippe Mathieu-Daudé
This pull request adds the architectural part of the Renesas RX
architecture.  Richard Henderson temporarily handed it over for
the 5.0 release.

The following changes since commit a98135f727595382e200d04c2996e868b7925a01:

  Merge remote-tracking branch 'remotes/kraxel/tags/vga-20200316-pull-request' 
into staging (2020-03-16 14:55:59 +)

are available in the Git repository at:

  https://gitlab.com/philmd/qemu.git tags/target_renesas_rx-20200317

for you to fetch changes up to d9ecf331340137dc091bdcf3d3ef60087deac9ac:

  Add rx-softmmu (2020-03-17 16:01:58 +0100)



Introduce the architectural part of the Renesas RX
architecture emulation, developed by Yoshinori Sato.

CI jobs results:
  https://gitlab.com/philmd/qemu/pipelines/127060924
  https://travis-ci.org/github/philmd/qemu/builds/663524971



Richard Henderson (6):
  target/rx: Disassemble rx_index_addr into a string
  target/rx: Replace operand with prt_ldmi in disassembler
  target/rx: Use prt_ldmi for XCHG_mr disassembly
  target/rx: Emit all disassembly in one prt()
  target/rx: Collect all bytes during disassembly
  target/rx: Dump bytes for each insn during disassembly

Yoshinori Sato (7):
  hw/registerfields.h: Add 8bit and 16bit register macros
  MAINTAINERS: Add entry for the Renesas RX architecture
  target/rx: TCG translation
  target/rx: TCG helpers
  target/rx: CPU definitions
  target/rx: RX disassembler
  Add rx-softmmu

 configure   |   11 +-
 default-configs/rx-softmmu.mak  |2 +
 qapi/machine.json   |4 +-
 include/disas/dis-asm.h |5 +
 include/exec/poison.h   |1 +
 include/hw/registerfields.h |   30 +
 include/sysemu/arch_init.h  |1 +
 target/rx/cpu-param.h   |   30 +
 target/rx/cpu-qom.h |   54 +
 target/rx/cpu.h |  180 +++
 target/rx/helper.h  |   31 +
 target/rx/insns.decode  |  621 
 arch_init.c |2 +
 target/rx/cpu.c |  226 +++
 target/rx/disas.c   | 1446 ++
 target/rx/gdbstub.c |  112 ++
 target/rx/helper.c  |  149 ++
 target/rx/op_helper.c   |  470 ++
 target/rx/translate.c   | 2439 +++
 tests/qtest/machine-none-test.c |1 +
 MAINTAINERS |5 +
 gdb-xml/rx-core.xml |   70 +
 target/rx/Makefile.objs |   11 +
 23 files changed, 5899 insertions(+), 2 deletions(-)
 create mode 100644 default-configs/rx-softmmu.mak
 create mode 100644 target/rx/cpu-param.h
 create mode 100644 target/rx/cpu-qom.h
 create mode 100644 target/rx/cpu.h
 create mode 100644 target/rx/helper.h
 create mode 100644 target/rx/insns.decode
 create mode 100644 target/rx/cpu.c
 create mode 100644 target/rx/disas.c
 create mode 100644 target/rx/gdbstub.c
 create mode 100644 target/rx/helper.c
 create mode 100644 target/rx/op_helper.c
 create mode 100644 target/rx/translate.c
 create mode 100644 gdb-xml/rx-core.xml
 create mode 100644 target/rx/Makefile.objs

-- 
2.21.1




[PULL 4/4] hw/sd/ssi-sd: fix error handling in ssi_sd_realize

2020-03-17 Thread Markus Armbruster
From: Vladimir Sementsov-Ogievskiy 

It's wrong to use same err object as errp parameter for several
function calls without intermediate checking for error: we'll crash if
try to set err object twice. Fix that.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Message-Id: <20200317125741.15301-1-vsement...@virtuozzo.com>
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Markus Armbruster 
Signed-off-by: Markus Armbruster 
---
 hw/sd/ssi-sd.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 91db069212..829797b597 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -255,13 +255,25 @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
 carddev = qdev_create(BUS(>sdbus), TYPE_SD_CARD);
 if (dinfo) {
 qdev_prop_set_drive(carddev, "drive", blk_by_legacy_dinfo(dinfo), 
);
+if (err) {
+goto fail;
+}
 }
+
 object_property_set_bool(OBJECT(carddev), true, "spi", );
+if (err) {
+goto fail;
+}
+
 object_property_set_bool(OBJECT(carddev), true, "realized", );
 if (err) {
-error_setg(errp, "failed to init SD card: %s", error_get_pretty(err));
-return;
+goto fail;
 }
+
+return;
+
+fail:
+error_propagate_prepend(errp, err, "failed to init SD card: ");
 }
 
 static void ssi_sd_reset(DeviceState *dev)
-- 
2.21.1




[PULL 04/13] target/rx: TCG helpers

2020-03-17 Thread Philippe Mathieu-Daudé
From: Yoshinori Sato 

Reviewed-by: Richard Henderson 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Yoshinori Sato 
Signed-off-by: Richard Henderson 
[PMD: Removed tlb_fill, extracted from patch of Yoshinori Sato
 'Convert to CPUClass::tlb_fill']
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20200224141923.82118-6-ys...@users.sourceforge.jp>
Acked-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/rx/helper.h|  31 +++
 target/rx/helper.c| 149 +
 target/rx/op_helper.c | 470 ++
 3 files changed, 650 insertions(+)
 create mode 100644 target/rx/helper.h
 create mode 100644 target/rx/helper.c
 create mode 100644 target/rx/op_helper.c

diff --git a/target/rx/helper.h b/target/rx/helper.h
new file mode 100644
index 00..f0b7ebbbf7
--- /dev/null
+++ b/target/rx/helper.h
@@ -0,0 +1,31 @@
+DEF_HELPER_1(raise_illegal_instruction, noreturn, env)
+DEF_HELPER_1(raise_access_fault, noreturn, env)
+DEF_HELPER_1(raise_privilege_violation, noreturn, env)
+DEF_HELPER_1(wait, noreturn, env)
+DEF_HELPER_1(debug, noreturn, env)
+DEF_HELPER_2(rxint, noreturn, env, i32)
+DEF_HELPER_1(rxbrk, noreturn, env)
+DEF_HELPER_FLAGS_3(fadd, TCG_CALL_NO_WG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fsub, TCG_CALL_NO_WG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fmul, TCG_CALL_NO_WG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fdiv, TCG_CALL_NO_WG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_WG, void, env, f32, f32)
+DEF_HELPER_FLAGS_2(ftoi, TCG_CALL_NO_WG, i32, env, f32)
+DEF_HELPER_FLAGS_2(round, TCG_CALL_NO_WG, i32, env, f32)
+DEF_HELPER_FLAGS_2(itof, TCG_CALL_NO_WG, f32, env, i32)
+DEF_HELPER_2(set_fpsw, void, env, i32)
+DEF_HELPER_FLAGS_2(racw, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_FLAGS_2(set_psw_rte, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_FLAGS_2(set_psw, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_1(pack_psw, i32, env)
+DEF_HELPER_FLAGS_3(div, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(divu, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_1(scmpu, TCG_CALL_NO_WG, void, env)
+DEF_HELPER_1(smovu, void, env)
+DEF_HELPER_1(smovf, void, env)
+DEF_HELPER_1(smovb, void, env)
+DEF_HELPER_2(sstr, void, env, i32)
+DEF_HELPER_FLAGS_2(swhile, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_FLAGS_2(suntil, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_FLAGS_2(rmpa, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_1(satr, void, env)
diff --git a/target/rx/helper.c b/target/rx/helper.c
new file mode 100644
index 00..a6a337a311
--- /dev/null
+++ b/target/rx/helper.c
@@ -0,0 +1,149 @@
+/*
+ *  RX emulation
+ *
+ *  Copyright (c) 2019 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bitops.h"
+#include "cpu.h"
+#include "exec/log.h"
+#include "exec/cpu_ldst.h"
+#include "sysemu/sysemu.h"
+#include "hw/irq.h"
+
+void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw, int rte)
+{
+if (env->psw_pm == 0) {
+env->psw_ipl = FIELD_EX32(psw, PSW, IPL);
+if (rte) {
+/* PSW.PM can write RTE and RTFI */
+env->psw_pm = FIELD_EX32(psw, PSW, PM);
+}
+env->psw_u = FIELD_EX32(psw, PSW, U);
+env->psw_i = FIELD_EX32(psw, PSW, I);
+}
+env->psw_o = FIELD_EX32(psw, PSW, O) << 31;
+env->psw_s = FIELD_EX32(psw, PSW, S) << 31;
+env->psw_z = 1 - FIELD_EX32(psw, PSW, Z);
+env->psw_c = FIELD_EX32(psw, PSW, C);
+}
+
+#define INT_FLAGS (CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIR)
+void rx_cpu_do_interrupt(CPUState *cs)
+{
+RXCPU *cpu = RXCPU(cs);
+CPURXState *env = >env;
+int do_irq = cs->interrupt_request & INT_FLAGS;
+uint32_t save_psw;
+
+env->in_sleep = 0;
+
+if (env->psw_u) {
+env->usp = env->regs[0];
+} else {
+env->isp = env->regs[0];
+}
+save_psw = rx_cpu_pack_psw(env);
+env->psw_pm = env->psw_i = env->psw_u = 0;
+
+if (do_irq) {
+if (do_irq & CPU_INTERRUPT_FIR) {
+env->bpc = env->pc;
+env->bpsw = save_psw;
+env->pc = env->fintv;
+env->psw_ipl = 15;
+cs->interrupt_request &= ~CPU_INTERRUPT_FIR;
+qemu_set_irq(env->ack, env->ack_irq);
+qemu_log_mask(CPU_LOG_INT, "fast interrupt raised\n");
+} else if (do_irq & CPU_INTERRUPT_HARD) {
+env->isp -= 4;
+

[PULL 01/13] hw/registerfields.h: Add 8bit and 16bit register macros

2020-03-17 Thread Philippe Mathieu-Daudé
From: Yoshinori Sato 

Some RX peripheral use 8bit and 16bit registers.
Add the 8bit and 16bit APIs.

Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Signed-off-by: Yoshinori Sato 
Signed-off-by: Richard Henderson 
Message-Id: <20200224141923.82118-4-ys...@users.sourceforge.jp>
Acked-by: Richard Henderson 
Signed-off-by: Philippe Mathieu-Daudé 
---
 include/hw/registerfields.h | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
index 2659a58737..0407edb7ec 100644
--- a/include/hw/registerfields.h
+++ b/include/hw/registerfields.h
@@ -22,6 +22,14 @@
 enum { A_ ## reg = (addr) };  \
 enum { R_ ## reg = (addr) / 4 };
 
+#define REG8(reg, addr)   \
+enum { A_ ## reg = (addr) };  \
+enum { R_ ## reg = (addr) };
+
+#define REG16(reg, addr)  \
+enum { A_ ## reg = (addr) };  \
+enum { R_ ## reg = (addr) / 2 };
+
 /* Define SHIFT, LENGTH and MASK constants for a field within a register */
 
 /* This macro will define R_FOO_BAR_MASK, R_FOO_BAR_SHIFT and R_FOO_BAR_LENGTH
@@ -34,6 +42,12 @@
 MAKE_64BIT_MASK(shift, length)};
 
 /* Extract a field from a register */
+#define FIELD_EX8(storage, reg, field)\
+extract8((storage), R_ ## reg ## _ ## field ## _SHIFT,\
+  R_ ## reg ## _ ## field ## _LENGTH)
+#define FIELD_EX16(storage, reg, field)   \
+extract16((storage), R_ ## reg ## _ ## field ## _SHIFT,   \
+  R_ ## reg ## _ ## field ## _LENGTH)
 #define FIELD_EX32(storage, reg, field)   \
 extract32((storage), R_ ## reg ## _ ## field ## _SHIFT,   \
   R_ ## reg ## _ ## field ## _LENGTH)
@@ -49,6 +63,22 @@
  * Assigning values larger then the target field will result in
  * compilation warnings.
  */
+#define FIELD_DP8(storage, reg, field, val) ({\
+struct {  \
+unsigned int v:R_ ## reg ## _ ## field ## _LENGTH;\
+} v = { .v = val };   \
+uint8_t d;\
+d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT,   \
+  R_ ## reg ## _ ## field ## _LENGTH, v.v);   \
+d; })
+#define FIELD_DP16(storage, reg, field, val) ({   \
+struct {  \
+unsigned int v:R_ ## reg ## _ ## field ## _LENGTH;\
+} v = { .v = val };   \
+uint16_t d;   \
+d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT,   \
+  R_ ## reg ## _ ## field ## _LENGTH, v.v);   \
+d; })
 #define FIELD_DP32(storage, reg, field, val) ({   \
 struct {  \
 unsigned int v:R_ ## reg ## _ ## field ## _LENGTH;\
-- 
2.21.1




[PATCH v6 42/61] target/riscv: vector floating-point/integer type-convert instructions

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 13 ++
 target/riscv/insn32.decode  |  4 +++
 target/riscv/insn_trans/trans_rvv.inc.c |  6 +
 target/riscv/vector_helper.c| 33 +
 4 files changed, 56 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 3c813d23d1..5da6b8fcfa 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -994,3 +994,16 @@ DEF_HELPER_5(vfclass_v_d, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmerge_vfm_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmerge_vfm_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmerge_vfm_d, void, ptr, ptr, i64, ptr, env, i32)
+
+DEF_HELPER_5(vfcvt_xu_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfcvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfcvt_xu_f_v_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfcvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfcvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfcvt_x_f_v_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfcvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfcvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfcvt_f_xu_v_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfcvt_f_x_v_d, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 14cb4e2e66..53562c6663 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -515,6 +515,10 @@ vmford_vf   011010 . . . 101 . 1010111 
@r_vm
 vfclass_v   100011 . . 1 001 . 1010111 @r2_vm
 vfmerge_vfm 010111 0 . . 101 . 1010111 @r_vm_0
 vfmv_v_f010111 1 0 . 101 . 1010111 @r2
+vfcvt_xu_f_v100010 . . 0 001 . 1010111 @r2_vm
+vfcvt_x_f_v 100010 . . 1 001 . 1010111 @r2_vm
+vfcvt_f_xu_v100010 . . 00010 001 . 1010111 @r2_vm
+vfcvt_f_x_v 100010 . . 00011 001 . 1010111 @r2_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 7cdeec9cd0..0aa0001f12 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2070,3 +2070,9 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f 
*a)
 }
 return false;
 }
+
+/* Single-Width Floating-Point/Integer Type-Convert Instructions */
+GEN_OPFV_TRANS(vfcvt_xu_f_v, opfv_check)
+GEN_OPFV_TRANS(vfcvt_x_f_v, opfv_check)
+GEN_OPFV_TRANS(vfcvt_f_xu_v, opfv_check)
+GEN_OPFV_TRANS(vfcvt_f_x_v, opfv_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 650a17cc1c..0de986aed5 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4176,3 +4176,36 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1,   
 \
 GEN_VFMERGE_VF(vfmerge_vfm_h, int16_t, H2, clearh)
 GEN_VFMERGE_VF(vfmerge_vfm_w, int32_t, H4, clearl)
 GEN_VFMERGE_VF(vfmerge_vfm_d, int64_t, H8, clearq)
+
+/* Single-Width Floating-Point/Integer Type-Convert Instructions */
+/* vfcvt.xu.f.v vd, vs2, vm # Convert float to unsigned integer. */
+RVVCALL(OPFVV1, vfcvt_xu_f_v_h, OP_UU_H, H2, H2, float16_to_uint16)
+RVVCALL(OPFVV1, vfcvt_xu_f_v_w, OP_UU_W, H4, H4, float32_to_uint32)
+RVVCALL(OPFVV1, vfcvt_xu_f_v_d, OP_UU_D, H8, H8, float64_to_uint64)
+GEN_VEXT_V_ENV(vfcvt_xu_f_v_h, 2, 2, clearh)
+GEN_VEXT_V_ENV(vfcvt_xu_f_v_w, 4, 4, clearl)
+GEN_VEXT_V_ENV(vfcvt_xu_f_v_d, 8, 8, clearq)
+
+/* vfcvt.x.f.v vd, vs2, vm # Convert float to signed integer. */
+RVVCALL(OPFVV1, vfcvt_x_f_v_h, OP_UU_H, H2, H2, float16_to_int16)
+RVVCALL(OPFVV1, vfcvt_x_f_v_w, OP_UU_W, H4, H4, float32_to_int32)
+RVVCALL(OPFVV1, vfcvt_x_f_v_d, OP_UU_D, H8, H8, float64_to_int64)
+GEN_VEXT_V_ENV(vfcvt_x_f_v_h, 2, 2, clearh)
+GEN_VEXT_V_ENV(vfcvt_x_f_v_w, 4, 4, clearl)
+GEN_VEXT_V_ENV(vfcvt_x_f_v_d, 8, 8, clearq)
+
+/* vfcvt.f.xu.v vd, vs2, vm # Convert unsigned integer to float. */
+RVVCALL(OPFVV1, vfcvt_f_xu_v_h, OP_UU_H, H2, H2, uint16_to_float16)
+RVVCALL(OPFVV1, vfcvt_f_xu_v_w, OP_UU_W, H4, H4, uint32_to_float32)
+RVVCALL(OPFVV1, vfcvt_f_xu_v_d, OP_UU_D, H8, H8, uint64_to_float64)
+GEN_VEXT_V_ENV(vfcvt_f_xu_v_h, 2, 2, clearh)
+GEN_VEXT_V_ENV(vfcvt_f_xu_v_w, 4, 4, clearl)
+GEN_VEXT_V_ENV(vfcvt_f_xu_v_d, 8, 8, clearq)
+
+/* vfcvt.f.x.v vd, vs2, vm # Convert integer to float. */
+RVVCALL(OPFVV1, vfcvt_f_x_v_h, OP_UU_H, H2, H2, int16_to_float16)
+RVVCALL(OPFVV1, vfcvt_f_x_v_w, OP_UU_W, H4, H4, int32_to_float32)
+RVVCALL(OPFVV1, vfcvt_f_x_v_d, OP_UU_D, H8, H8, int64_to_float64)
+GEN_VEXT_V_ENV(vfcvt_f_x_v_h, 2, 2, clearh)
+GEN_VEXT_V_ENV(vfcvt_f_x_v_w, 4, 4, clearl)
+GEN_VEXT_V_ENV(vfcvt_f_x_v_d, 8, 8, clearq)
-- 

[PULL 2/4] hw/misc/ivshmem: Use one Error * variable instead of two

2020-03-17 Thread Markus Armbruster
Commit fe44dc9180 "migration: disallow migrate_add_blocker during
migration" accidentally added a second Error * variable.  Use the
first one instead.

Signed-off-by: Markus Armbruster 
Message-Id: <20200313170517.22480-3-arm...@redhat.com>
Reviewed-by: Peter Maydell 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 hw/misc/ivshmem.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 1a0fad74e1..a8dc9b377d 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -832,7 +832,6 @@ static void ivshmem_common_realize(PCIDevice *dev, Error 
**errp)
 IVShmemState *s = IVSHMEM_COMMON(dev);
 Error *err = NULL;
 uint8_t *pci_conf;
-Error *local_err = NULL;
 
 /* IRQFD requires MSI */
 if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD) &&
@@ -899,9 +898,9 @@ static void ivshmem_common_realize(PCIDevice *dev, Error 
**errp)
 if (!ivshmem_is_master(s)) {
 error_setg(>migration_blocker,
"Migration is disabled when using feature 'peer mode' in 
device 'ivshmem'");
-migrate_add_blocker(s->migration_blocker, _err);
-if (local_err) {
-error_propagate(errp, local_err);
+migrate_add_blocker(s->migration_blocker, );
+if (err) {
+error_propagate(errp, err);
 error_free(s->migration_blocker);
 return;
 }
-- 
2.21.1




[PATCH v6 41/61] target/riscv: vector floating-point merge instructions

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
---
 target/riscv/helper.h   |  4 +++
 target/riscv/insn32.decode  |  2 ++
 target/riscv/insn_trans/trans_rvv.inc.c | 34 +
 target/riscv/vector_helper.c| 30 ++
 4 files changed, 70 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 93914fc7c4..3c813d23d1 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -990,3 +990,7 @@ DEF_HELPER_6(vmford_vf_d, void, ptr, ptr, i64, ptr, env, 
i32)
 DEF_HELPER_5(vfclass_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfclass_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfclass_v_d, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(vfmerge_vfm_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfmerge_vfm_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfmerge_vfm_d, void, ptr, ptr, i64, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 23e80fe954..14cb4e2e66 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -513,6 +513,8 @@ vmfge_vf01 . . . 101 . 1010111 @r_vm
 vmford_vv   011010 . . . 001 . 1010111 @r_vm
 vmford_vf   011010 . . . 101 . 1010111 @r_vm
 vfclass_v   100011 . . 1 001 . 1010111 @r2_vm
+vfmerge_vfm 010111 0 . . 101 . 1010111 @r_vm_0
+vfmv_v_f010111 1 0 . 101 . 1010111 @r2
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index b7327a2972..7cdeec9cd0 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2036,3 +2036,37 @@ GEN_OPFVF_TRANS(vmford_vf, opfvf_cmp_check)
 
 /* Vector Floating-Point Classify Instruction */
 GEN_OPFV_TRANS(vfclass_v, opfv_check)
+
+/* Vector Floating-Point Merge Instruction */
+GEN_OPFVF_TRANS(vfmerge_vfm,  opfvf_check)
+
+static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
+{
+if (vext_check_isa_ill(s) &&
+vext_check_reg(s, a->rd, false) &&
+(s->sew != 0)) {
+
+if (s->vl_eq_vlmax) {
+tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd),
+ MAXSZ(s), MAXSZ(s), cpu_fpr[a->rs1]);
+} else {
+TCGv_ptr dest = tcg_temp_new_ptr();
+TCGv_i32 desc;
+uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
+static gen_helper_vmv_vx * const fns[3] = {
+gen_helper_vmv_v_x_h,
+gen_helper_vmv_v_x_w,
+gen_helper_vmv_v_x_d,
+};
+
+desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
+tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
+fns[s->sew - 1](dest, cpu_fpr[a->rs1], cpu_env, desc);
+
+tcg_temp_free_ptr(dest);
+tcg_temp_free_i32(desc);
+}
+return true;
+}
+return false;
+}
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index c1a0d14ea8..650a17cc1c 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4146,3 +4146,33 @@ RVVCALL(OPIVV1, vfclass_v_d, OP_UU_D, H8, H8, fclass_d)
 GEN_VEXT_V(vfclass_v_h, 2, 2, clearh)
 GEN_VEXT_V(vfclass_v_w, 4, 4, clearl)
 GEN_VEXT_V(vfclass_v_d, 8, 8, clearq)
+
+/* Vector Floating-Point Merge Instruction */
+#define GEN_VFMERGE_VF(NAME, ETYPE, H, CLEAR_FN)  \
+void HELPER(NAME)(void *vd, void *v0, uint64_t s1,\
+void *vs2, CPURISCVState *env, uint32_t desc) \
+{ \
+uint32_t mlen = vext_mlen(desc);  \
+uint32_t vm = vext_vm(desc);  \
+uint32_t vl = env->vl;\
+uint32_t esz = sizeof(ETYPE); \
+uint32_t vlmax = vext_maxsz(desc) / esz;  \
+uint32_t i;   \
+  \
+if (vl == 0) {\
+return;   \
+} \
+for (i = 0; i < vl; i++) {\
+if (!vm && !vext_elem_mask(v0, mlen, i)) {\
+ETYPE s2 = *((ETYPE *)vs2 + H(i));\
+*((ETYPE *)vd + H1(i)) = s2;  \
+} else {  \
+*((ETYPE *)vd + H(i)) = (ETYPE)s1;\
+} \
+} \
+CLEAR_FN(vd, vl, vl * esz, vlmax * esz);  \
+}
+
+GEN_VFMERGE_VF(vfmerge_vfm_h, int16_t, H2, clearh)

[PATCH v6 39/61] target/riscv: vector floating-point compare instructions

2020-03-17 Thread LIU Zhiwei
Signed-off-by: LIU Zhiwei 
---
 target/riscv/helper.h   |  37 +
 target/riscv/insn32.decode  |  12 ++
 target/riscv/insn_trans/trans_rvv.inc.c |  33 +
 target/riscv/vector_helper.c| 182 
 4 files changed, 264 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 44aefdf752..74a2ad897f 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -949,3 +949,40 @@ DEF_HELPER_6(vfsgnjn_vf_d, void, ptr, ptr, i64, ptr, env, 
i32)
 DEF_HELPER_6(vfsgnjx_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfsgnjx_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfsgnjx_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+
+DEF_HELPER_6(vmfeq_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfeq_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfeq_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfne_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfne_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfne_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmflt_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmflt_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmflt_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfle_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfle_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfle_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfeq_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfeq_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfeq_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfne_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfne_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfne_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmflt_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmflt_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmflt_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfle_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfle_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfle_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfgt_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfgt_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfgt_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfge_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfge_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfge_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmford_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmford_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmford_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmford_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmford_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmford_vf_d, void, ptr, ptr, i64, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index ce2f497ed2..b0f1c54d53 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -500,6 +500,18 @@ vfsgnjn_vv  001001 . . . 001 . 1010111 
@r_vm
 vfsgnjn_vf  001001 . . . 101 . 1010111 @r_vm
 vfsgnjx_vv  001010 . . . 001 . 1010111 @r_vm
 vfsgnjx_vf  001010 . . . 101 . 1010111 @r_vm
+vmfeq_vv011000 . . . 001 . 1010111 @r_vm
+vmfeq_vf011000 . . . 101 . 1010111 @r_vm
+vmfne_vv011100 . . . 001 . 1010111 @r_vm
+vmfne_vf011100 . . . 101 . 1010111 @r_vm
+vmflt_vv011011 . . . 001 . 1010111 @r_vm
+vmflt_vf011011 . . . 101 . 1010111 @r_vm
+vmfle_vv011001 . . . 001 . 1010111 @r_vm
+vmfle_vf011001 . . . 101 . 1010111 @r_vm
+vmfgt_vf011101 . . . 101 . 1010111 @r_vm
+vmfge_vf01 . . . 101 . 1010111 @r_vm
+vmford_vv   011010 . . . 001 . 1010111 @r_vm
+vmford_vf   011010 . . . 101 . 1010111 @r_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c 
b/target/riscv/insn_trans/trans_rvv.inc.c
index 866957fd24..6bf4bd1e98 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2000,3 +2000,36 @@ GEN_OPFVV_TRANS(vfsgnjx_vv, opfvv_check)
 GEN_OPFVF_TRANS(vfsgnj_vf, opfvf_check)
 GEN_OPFVF_TRANS(vfsgnjn_vf, opfvf_check)
 GEN_OPFVF_TRANS(vfsgnjx_vf, opfvf_check)
+
+/* Vector Floating-Point Compare Instructions */
+static bool opfvv_cmp_check(DisasContext *s, arg_rmrr *a)
+{
+return (vext_check_isa_ill(s) &&
+vext_check_reg(s, a->rs2, false) &&
+vext_check_reg(s, a->rs1, false) &&
+(s->sew != 0) &&
+

<    1   2   3   4   5   6   7   >