[Qemu-devel] [PATCH 2/2] virtio-balloon: add 'available' counter

2016-02-23 Thread Denis V. Lunev
The patch for the kernel part is in linux-next already:
commit ac88e7c908b920866e529862f2b2f0129b254ab2
Author: Igor Redko 
Date:   Thu Feb 18 09:23:01 2016 +1100

virtio_balloon: export 'available' memory to balloon statistics

Add a new field, VIRTIO_BALLOON_S_AVAIL, to virtio_balloon memory
statistics protocol, corresponding to 'Available' in /proc/meminfo.

Signed-off-by: Denis V. Lunev 
CC: Igor Redko 
CC: Michael S. Tsirkin 
---
 hw/virtio/virtio-balloon.c  | 1 +
 include/standard-headers/linux/virtio_balloon.h | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 6629145..3193f44 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -53,6 +53,7 @@ static const char *balloon_stat_names[] = {
[VIRTIO_BALLOON_S_MINFLT] = "stat-minor-faults",
[VIRTIO_BALLOON_S_MEMFREE] = "stat-free-memory",
[VIRTIO_BALLOON_S_MEMTOT] = "stat-total-memory",
+   [VIRTIO_BALLOON_S_AVAIL] = "stat-available-memory",
[VIRTIO_BALLOON_S_NR] = NULL
 };
 
diff --git a/include/standard-headers/linux/virtio_balloon.h 
b/include/standard-headers/linux/virtio_balloon.h
index 2e2a6dc..0df7c2e 100644
--- a/include/standard-headers/linux/virtio_balloon.h
+++ b/include/standard-headers/linux/virtio_balloon.h
@@ -51,7 +51,8 @@ struct virtio_balloon_config {
 #define VIRTIO_BALLOON_S_MINFLT   3   /* Number of minor faults */
 #define VIRTIO_BALLOON_S_MEMFREE  4   /* Total amount of free memory */
 #define VIRTIO_BALLOON_S_MEMTOT   5   /* Total amount of memory */
-#define VIRTIO_BALLOON_S_NR   6
+#define VIRTIO_BALLOON_S_AVAIL6   /* Amount of available memory in guest */
+#define VIRTIO_BALLOON_S_NR   7
 
 /*
  * Memory statistics structure.
-- 
2.1.4




[Qemu-devel] [PATCH 1/2] virtio-balloon: export all balloon statistics

2016-02-23 Thread Denis V. Lunev
From: Igor Redko 

We are making experiments with different autoballooning strategies
based on the guest behavior. Thus we need to experiment with different
guest statistics. For now every counter change requires QEMU recompilation
and dances with Libvirt.

This patch introduces transport for unrecognized counters in virtio-balloon.
This transport can be used for measuring benefits from using new
balloon counters, before submitting any patches. Current alternative
is 'guest-exec' transport which isn't made for such delicate matters
and can influence test results.

Originally all counters with tag >= VIRTIO_BALLOON_S_NR were ignored.
Instead of this we keep first (VIRTIO_BALLOON_S_NR + 32) counters from the
queue and pass unrecognized ones with the following names: 'x-stat-',
where  is a tag number in hex. Defined counters are reported with their
regular names.

Signed-off-by: Igor Redko 
Signed-off-by: Denis V. Lunev 
CC: Michael S. Tsirkin 
---
 configure  | 12 
 hw/virtio/virtio-balloon.c | 32 ++--
 include/hw/virtio/virtio-balloon.h |  3 ++-
 3 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/configure b/configure
index 0aa249b..a51b85c 100755
--- a/configure
+++ b/configure
@@ -314,6 +314,7 @@ vhdx=""
 numa=""
 tcmalloc="no"
 jemalloc="no"
+unknown_balloon_stats="no"
 
 # parse CC options first
 for opt do
@@ -1141,6 +1142,10 @@ for opt do
   ;;
   --enable-jemalloc) jemalloc="yes"
   ;;
+  --enable-unknown-balloon-stats) unknown_balloon_stats="yes"
+  ;;
+  --disable-unknown-balloon-stats) unknown_balloon_stats="no"
+  ;;
   *)
   echo "ERROR: unknown option $opt"
   echo "Try '$0 --help' for more information"
@@ -1363,6 +1368,8 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   numalibnuma support
   tcmalloctcmalloc support
   jemallocjemalloc support
+  unknown-balloon-stats  report unknown balloon statistics counters
+  ;;
 
 NOTE: The object files are built at the place where configure is launched
 EOF
@@ -4776,6 +4783,7 @@ echo "bzip2 support $bzip2"
 echo "NUMA host support $numa"
 echo "tcmalloc support  $tcmalloc"
 echo "jemalloc support  $jemalloc"
+echo "unknown balloon stat counters support  $unknown_balloon_stats"
 
 if test "$sdl_too_old" = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -5324,6 +5332,10 @@ if test "$rdma" = "yes" ; then
   echo "CONFIG_RDMA=y" >> $config_host_mak
 fi
 
+if test "$unknown_balloon_stats" = "yes" ; then
+  echo "CONFIG_UNKNOWN_BALLOON_STATS=y" >> $config_host_mak
+fi
+
 # Hold two types of flag:
 #   CONFIG_THREAD_SETNAME_BYTHREAD  - we've got a way of setting the name on
 # a thread we have a handle to
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index a382f43..6629145 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -66,8 +66,7 @@ static const char *balloon_stat_names[] = {
  */
 static inline void reset_stats(VirtIOBalloon *dev)
 {
-int i;
-for (i = 0; i < VIRTIO_BALLOON_S_NR; dev->stats[i++] = -1);
+dev->stats_cnt = 0;
 }
 
 static bool balloon_stats_supported(const VirtIOBalloon *s)
@@ -133,12 +132,22 @@ static void balloon_stats_get_all(Object *obj, Visitor 
*v, const char *name,
 if (err) {
 goto out_end;
 }
-for (i = 0; i < VIRTIO_BALLOON_S_NR; i++) {
-visit_type_uint64(v, balloon_stat_names[i], >stats[i], );
+for (i = 0; i < s->stats_cnt; i++) {
+if (s->stats[i].tag < VIRTIO_BALLOON_S_NR) {
+visit_type_uint64(v, balloon_stat_names[s->stats[i].tag],
+  >stats[i].val, );
+} else {
+#if defined(CONFIG_UNKNOWN_BALLOON_STATS)
+gchar *str = g_strdup_printf("x-stat-%04x", s->stats[i].tag);
+visit_type_uint64(v, str, >stats[i].val, );
+g_free(str);
+#endif
+}
 if (err) {
 break;
 }
 }
+
 error_propagate(errp, err);
 err = NULL;
 visit_end_struct(v, );
@@ -273,10 +282,21 @@ static void virtio_balloon_receive_stats(VirtIODevice 
*vdev, VirtQueue *vq)
== sizeof(stat)) {
 uint16_t tag = virtio_tswap16(vdev, stat.tag);
 uint64_t val = virtio_tswap64(vdev, stat.val);
+int i;
 
 offset += sizeof(stat);
-if (tag < VIRTIO_BALLOON_S_NR)
-s->stats[tag] = val;
+for (i = 0; i < s->stats_cnt; i++) {
+if (s->stats[i].tag == tag) {
+break;
+}
+}
+if (i < ARRAY_SIZE(s->stats)) {
+s->stats[i].tag = tag;
+s->stats[i].val = val;
+if (s->stats_cnt <= i) {
+s->stats_cnt = i + 1;
+}
+}
 }
 s->stats_vq_offset = offset;
 
diff --git 

[Qemu-devel] [PATCH v3 0/2] virtio-balloon: improve balloon statistics

2016-02-23 Thread Denis V. Lunev
New counter from the Linux kernel + generic framework to pass currently
unknown counters via QMP for debug purposes.

Signed-off-by: Denis V. Lunev 
CC: Igor Redko 
CC: Michael S. Tsirkin 

Changes from v2:
- put "export unknown counters" code under ifdef

Changes from v1:
- removed !err in patch 1 by suggestion from Eric





Re: [Qemu-devel] [PATCH v2 00/15] tests: Introducing docker tests

2016-02-23 Thread Fam Zheng
On Tue, 02/16 20:39, Fam Zheng wrote:
> v2: - Fix a few coding style warnings of shellcheck and pylint.
>   [Marc-André Lureau]
> - Rename make targets:
>   docker-run => docker-test
>   docker-build => docker-image
>   docker-run-$TEST.sh@$IMAGE => docker-$TEST@$IMAGE
> - In help, document the magic makefile vars which are
>   "IMAGES=", "TESTS=", "J=" and "PAUSE="
> - Rename test-basic => test-quick
> - Move docker files to tests/docker/dockerfiles/
> - Add "test-full" that builds all targets
> - Workaround broken clang for fedora 23
> - Add commit log for .gitignore changes [Alex]
> - Add "rev-by" in patch 13. [Alex]
> - Add patch 14 to make debugging easier [Alex]
> - Adopt Alex's "git archive" idea

Alex, any comments on this?

Fam



Re: [Qemu-devel] [PATCH 2/2] hw/9pfs: fix alignment issue when host filesystem block size is larger than client msize

2016-02-23 Thread Jevon Qiao

[Removing ceph-devel alias]

Hi Aneesh,

Any further comment on my reply below?

Thanks,
Jevon
On 19/2/16 16:56, Jevon Qiao wrote:

Hi Aneesh,

I am not sure I understand the details correctly. iounit is the size
that we use in client_read to determine the  size in which
we should request I/O from the client. But we still can't do I/O in size
larger than s->msize. If you look at the client side (kernel 9p fs), you
will find

rsize = fid->iounit;
if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
rsize = clnt->msize - P9_IOHDRSZ;

Yes, I know this.

if your iounit calculation ends up zero, that should be handled
correctly by

 if (!iounit) {
 iounit = s->msize - P9_IOHDRSZ;
 }
 return iounit;


So what is the issue here. ?

This will result in an alignment issue while mapping the I/O requested by
client into pages in the function of p9_nr_pages().

   int p9_nr_pages(char *data, int len)
   {
unsigned long start_page, end_page;
start_page =  (unsigned long)data >> PAGE_SHIFT;
end_page = ((unsigned long)data + len + PAGE_SIZE - 1) >>
   PAGE_SHIFT;
return end_page - start_page;
   }

Please see the following experiment I did without the fix.

1) Start qemu with cephfs,

   $ qemu-system-x86_64 /root/CentOS---6.6-64bit---2015-03-06-a.qcow2
   -smp 4 -m 4096 -fsdev
   cephfs,security_model=passthrough,id=fsdev0,path=/ -device
   virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=cephfs --enable-kvm
   -nographic -net nic -net tap,ifname=tap0,script=no,downscript=no


2) Mount the fs in the guest.

   [root@localhost ~]# mount -t 9p -o trans=virtio,version=9p2000.L
   cephfs /mnt
   [root@localhost ~]# ls -lah /mnt/8kfile
   -rw-r--r-- 1 root root 8.0K 2016-02-19 09:37 /mnt/8kfile

In this case, I used the default msize which is 8192(in Byte). Since 
cephfs

is using 4M as the f_bsize, the iounit will be 8168 as P9_IOHDRSZ is
equal to 24.

3) Run the following systemtap script to trace the paging result,

   [root@localhost ~]# cat p9_read.stp
   probe kernel.function("p9_virtio_zc_request").call
   {
printf("p9_virtio_zc_request: inlen size is %d\n", int_arg(5));
   }

   probe kernel.function("p9_nr_pages").call
   {
printf("p9_nr_pages: start_page = %ld\n", int_arg(1) >> 12);
printf("p9_nr_pages: end_age = %ld\n", (int_arg(1) + 8168 +
   4096 -1) >> 12);
   }

4) The output I got when I copied out the file /mnt/8kfile to /tmp/ 
directory,


   p9_virtio_zc_request: inlen size is 8168
   p9_nr_pages: start_page = 34293757815
   p9_nr_pages: end_age = 34293757818

Per the text in red(start_page = 34293757815, end_page = 34293757818),
it turns out 8k data will be mapped into three pages. This could hurt the
performance.

Actually, I enabled the cephfs debug functionality added by me to see
how the data is distributed in this case, the result is as follows,

   CEPHFS_DEBUG: cephfs_preadv iov_len=4096
   CEPHFS_DEBUG: cephfs_preadv iov_len=4072
   CEPHFS_DEBUG: cephfs_preadv iov_len=24

This patch aims to fix this. And the result turns out it works quite 
well, all the

data is well aligned.

   p9_virtio_zc_request: inlen size is 4096
   p9_nr_pages: start_page = 34203171814
   p9_nr_pages: end_age = 34203171815
   p9_virtio_zc_request: inlen size is 4096
   p9_nr_pages: start_page = 34203171815
   p9_nr_pages: end_age = 34203171816

   CEPHFS_DEBUG: cephfs_preadv iov_len=4096
   CEPHFS_DEBUG: cephfs_preadv iov_len=4096

Thanks,
Jevon

-aneesh









[Qemu-devel] [PATCH V6 1/2] net/filter-mirror:Add filter-mirror

2016-02-23 Thread Zhang Chen
Filter-mirror is a netfilter plugin.
It gives qemu the ability to mirror
packets to a chardev.

usage:

-netdev tap,id=hn0
-chardev socket,id=mirror0,host=ip_primary,port=X,server,nowait
-filter-mirror,id=m0,netdev=hn0,queue=tx/rx/all,outdev=mirror0

Signed-off-by: Zhang Chen 
Signed-off-by: Wen Congyang 
Reviewed-by: Yang Hongyang 
Reviewed-by: zhanghailiang 
---
 net/Makefile.objs   |   1 +
 net/filter-mirror.c | 181 
 qemu-options.hx |   5 ++
 vl.c|   3 +-
 4 files changed, 189 insertions(+), 1 deletion(-)
 create mode 100644 net/filter-mirror.c

diff --git a/net/Makefile.objs b/net/Makefile.objs
index 5fa2f97..b7c22fd 100644
--- a/net/Makefile.objs
+++ b/net/Makefile.objs
@@ -15,3 +15,4 @@ common-obj-$(CONFIG_VDE) += vde.o
 common-obj-$(CONFIG_NETMAP) += netmap.o
 common-obj-y += filter.o
 common-obj-y += filter-buffer.o
+common-obj-y += filter-mirror.o
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
new file mode 100644
index 000..ee13d94
--- /dev/null
+++ b/net/filter-mirror.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ * Copyright (c) 2016 FUJITSU LIMITED
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Author: Zhang Chen 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later.  See the COPYING file in the top-level directory.
+ */
+
+#include "net/filter.h"
+#include "net/net.h"
+#include "qemu-common.h"
+#include "qapi/qmp/qerror.h"
+#include "qapi-visit.h"
+#include "qom/object.h"
+#include "qemu/main-loop.h"
+#include "qemu/error-report.h"
+#include "trace.h"
+#include "sysemu/char.h"
+#include "qemu/iov.h"
+#include "qemu/sockets.h"
+
+#define FILTER_MIRROR(obj) \
+OBJECT_CHECK(MirrorState, (obj), TYPE_FILTER_MIRROR)
+
+#define TYPE_FILTER_MIRROR "filter-mirror"
+
+typedef struct MirrorState {
+NetFilterState parent_obj;
+char *outdev;
+CharDriverState *chr_out;
+} MirrorState;
+
+static int filter_mirror_send(NetFilterState *nf,
+   const struct iovec *iov,
+   int iovcnt)
+{
+MirrorState *s = FILTER_MIRROR(nf);
+int ret = 0;
+ssize_t size = 0;
+uint32_t len =  0;
+char *buf;
+
+size = iov_size(iov, iovcnt);
+if (!size) {
+return 0;
+}
+
+len = htonl(size);
+ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *), sizeof(len));
+if (ret != sizeof(len)) {
+goto err;
+}
+
+buf = g_malloc(size);
+iov_to_buf(iov, iovcnt, 0, buf, size);
+ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *)buf, size);
+g_free(buf);
+if (ret != size) {
+goto err;
+}
+
+return 0;
+
+err:
+return ret < 0 ? ret : -EIO;
+}
+
+static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
+ NetClientState *sender,
+ unsigned flags,
+ const struct iovec *iov,
+ int iovcnt,
+ NetPacketSent *sent_cb)
+{
+int ret;
+
+ret = filter_mirror_send(nf, iov, iovcnt);
+if (ret) {
+error_report("filter_mirror_send failed(%s)", strerror(-ret));
+}
+
+/*
+ * we don't hope this error interrupt the normal
+ * path of net packet, so we always return zero.
+ */
+return 0;
+}
+
+static void filter_mirror_cleanup(NetFilterState *nf)
+{
+MirrorState *s = FILTER_MIRROR(nf);
+
+if (s->chr_out) {
+qemu_chr_fe_release(s->chr_out);
+}
+}
+
+static void filter_mirror_setup(NetFilterState *nf, Error **errp)
+{
+MirrorState *s = FILTER_MIRROR(nf);
+
+if (!s->outdev) {
+error_setg(errp, "filter filter mirror needs 'outdev' "
+"property set");
+return;
+}
+
+s->chr_out = qemu_chr_find(s->outdev);
+if (s->chr_out == NULL) {
+error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+  "Device '%s' not found", s->outdev);
+return;
+}
+
+if (qemu_chr_fe_claim(s->chr_out) != 0) {
+error_setg(errp, QERR_DEVICE_IN_USE, s->outdev);
+return;
+}
+}
+
+static void filter_mirror_class_init(ObjectClass *oc, void *data)
+{
+NetFilterClass *nfc = NETFILTER_CLASS(oc);
+
+nfc->setup = filter_mirror_setup;
+nfc->cleanup = filter_mirror_cleanup;
+nfc->receive_iov = filter_mirror_receive_iov;
+}
+
+static char *filter_mirror_get_outdev(Object *obj, Error **errp)
+{
+MirrorState *s = FILTER_MIRROR(obj);
+
+return g_strdup(s->outdev);
+}
+
+static void
+filter_mirror_set_outdev(Object *obj, const char *value, Error **errp)
+{
+MirrorState *s = FILTER_MIRROR(obj);
+
+g_free(s->outdev);
+s->outdev = g_strdup(value);
+if 

[Qemu-devel] [PATCH V6 0/2] net/filter-mirror:add filter-mirror and unit test

2016-02-23 Thread Zhang Chen
Filter-mirror is a netfilter plugin.
It gives qemu the ability to mirror
packets to a chardev.

v6:
 - Address Jason's comments.

v5:
 - Address Jason's comments.

v4:
 - Address Jason's comments.

v3:
 - Add filter-mirror unit test according
   to Jason's comments
 - Address zhanghailiang's comments.
 - Address Jason's comments.

v2:
 - Address zhanghailiang's comments.
 - Address Eric Blake's comments.
 - Address Yang Hongyang's comments.
 - Address Dave's comments.

v1:
 initial patch.


Zhang Chen (2):
  net/filter-mirror:Add filter-mirror
  tests/test-filter-mirror:add filter-mirror unit test

 net/Makefile.objs  |   1 +
 net/filter-mirror.c| 181 +
 qemu-options.hx|   5 ++
 tests/.gitignore   |   1 +
 tests/Makefile |   2 +
 tests/test-filter-mirror.c |  90 ++
 vl.c   |   3 +-
 7 files changed, 282 insertions(+), 1 deletion(-)
 create mode 100644 net/filter-mirror.c
 create mode 100644 tests/test-filter-mirror.c

-- 
1.9.1






[Qemu-devel] [PATCH V6 2/2] tests/test-filter-mirror:add filter-mirror unit test

2016-02-23 Thread Zhang Chen
In this unit test we will test the mirror function.

start qemu with:
 -netdev socket,id=qtest-bn0,fd=sockfd
 -device e1000,netdev=qtest-bn0,id=qtest-e0
 -chardev socket,id=mirror0,path=/tmp/filter-mirror-test.sock,server,nowait
 -object filter-mirror,id=qtest-f0,netdev=qtest-bn0,queue=tx,outdev=mirror0

We inject packet to netdev socket id = qtest-bn0,
filter-mirror will copy and mirror the packet to mirror0.
we read packet from mirror0 and then compare to what we inject.

Signed-off-by: Zhang Chen 
Signed-off-by: Wen Congyang 
---
 tests/.gitignore   |  1 +
 tests/Makefile |  2 ++
 tests/test-filter-mirror.c | 90 ++
 3 files changed, 93 insertions(+)
 create mode 100644 tests/test-filter-mirror.c

diff --git a/tests/.gitignore b/tests/.gitignore
index 787c95c..10df017 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -63,5 +63,6 @@ test-write-threshold
 test-x86-cpuid
 test-xbzrle
 test-netfilter
+test-filter-mirror
 *-test
 qapi-schema/*.test.*
diff --git a/tests/Makefile b/tests/Makefile
index 650e654..e56c514 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -212,6 +212,7 @@ ifeq ($(CONFIG_VHOST_NET_TEST_i386),)
 check-qtest-x86_64-$(CONFIG_VHOST_NET_TEST_x86_64) += 
tests/vhost-user-test$(EXESUF)
 endif
 check-qtest-i386-y += tests/test-netfilter$(EXESUF)
+check-qtest-i386-y += tests/test-filter-mirror$(EXESUF)
 check-qtest-x86_64-y = $(check-qtest-i386-y)
 gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
 gcov-files-x86_64-y = $(subst 
i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
@@ -563,6 +564,7 @@ tests/qemu-iotests/socket_scm_helper$(EXESUF): 
tests/qemu-iotests/socket_scm_hel
 tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
 tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o 
$(test-block-obj-y)
 tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y)
+tests/test-filter-mirror$(EXESUF): tests/test-filter-mirror.o $(qtest-obj-y)
 tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o 
contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y)
 tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o
 
diff --git a/tests/test-filter-mirror.c b/tests/test-filter-mirror.c
new file mode 100644
index 000..7d3b154
--- /dev/null
+++ b/tests/test-filter-mirror.c
@@ -0,0 +1,90 @@
+/*
+ * QTest testcase for filter-mirror
+ *
+ * Copyright (c) 2016 FUJITSU LIMITED
+ * Author: Zhang Chen 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later.  See the COPYING file in the top-level directory.
+ */
+
+#include 
+#include "libqtest.h"
+#include "qemu/iov.h"
+#include "qemu/sockets.h"
+#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
+
+static void test_mirror(void)
+{
+#ifndef _WIN32
+/* socketpair(PF_UNIX) which does not exist on windows */
+
+int send_sock[2], recv_sock;
+char *cmdline;
+uint32_t ret = 0, len = 0;
+char send_buf[] = "Hello! filter-mirror~";
+char template[] = "filter-mirror.XX";
+char *recv_buf;
+char *sock_path;
+uint32_t size = sizeof(send_buf);
+size = htonl(size);
+
+ret = socketpair(PF_UNIX, SOCK_STREAM, 0, send_sock);
+g_assert_cmpint(ret, !=, -1);
+
+sock_path = mktemp(template);
+g_assert(sock_path);
+
+cmdline = g_strdup_printf("-netdev socket,id=qtest-bn0,fd=%d "
+ "-device e1000,netdev=qtest-bn0,id=qtest-e0 "
+ "-chardev socket,id=mirror0,path=%s,server,nowait "
+ "-object 
filter-mirror,id=qtest-f0,netdev=qtest-bn0,queue=tx,outdev=mirror0 "
+ , send_sock[1], sock_path);
+qtest_start(cmdline);
+g_free(cmdline);
+
+recv_sock = unix_connect(sock_path, NULL);
+g_assert_cmpint(recv_sock, !=, -1);
+
+struct iovec iov[] = {
+{
+.iov_base = ,
+.iov_len = sizeof(size),
+}, {
+.iov_base = send_buf,
+.iov_len = sizeof(send_buf),
+},
+};
+ret = iov_send(send_sock[0], iov, 2, 0, sizeof(size) + sizeof(send_buf));
+g_assert_cmpint(ret, ==, sizeof(send_buf) + sizeof(size));
+close(send_sock[0]);
+
+ret = qemu_recv(recv_sock, , sizeof(len), 0);
+g_assert_cmpint(ret, ==, sizeof(len));
+len = ntohl(len);
+
+g_assert_cmpint(len, ==, sizeof(send_buf));
+recv_buf = g_malloc(len);
+ret = qemu_recv(recv_sock, recv_buf, len, 0);
+g_assert_cmpstr(recv_buf, ==, send_buf);
+
+g_free(recv_buf);
+close(recv_sock);
+unlink(sock_path);
+
+#endif
+}
+
+int main(int argc, char **argv)
+{
+int ret;
+
+g_test_init(, , NULL);
+
+qtest_add_func("/netfilter/mirror", test_mirror);
+ret = g_test_run();
+qtest_end();
+
+return ret;
+}
-- 
1.9.1






Re: [Qemu-devel] [PATCH V5 2/2] tests/test-filter-mirror:add filter-mirror unit test

2016-02-23 Thread Zhang Chen



On 02/24/2016 11:24 AM, Jason Wang wrote:


On 02/23/2016 08:00 PM, Zhang Chen wrote:

In this unit test we will test the mirror function.

start qemu with:
  -netdev socket,id=qtest-bn0,fd=sockfd
  -device e1000,netdev=qtest-bn0,id=qtest-e0
  -chardev socket,id=mirror0,path=/tmp/filter-mirror-test.sock,server,nowait
  -object filter-mirror,id=qtest-f0,netdev=qtest-bn0,queue=tx,outdev=mirror0

We inject packet to netdev socket id = qtest-bn0,
filter-mirror will copy and mirror the packet to mirror0.
we read packet from mirror0 and then compare to what we inject.

Signed-off-by: Zhang Chen 
Signed-off-by: Wen Congyang 
---
  tests/.gitignore   |  1 +
  tests/Makefile |  2 ++
  tests/test-filter-mirror.c | 87 ++
  3 files changed, 90 insertions(+)
  create mode 100644 tests/test-filter-mirror.c

diff --git a/tests/.gitignore b/tests/.gitignore
index 787c95c..10df017 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -63,5 +63,6 @@ test-write-threshold
  test-x86-cpuid
  test-xbzrle
  test-netfilter
+test-filter-mirror
  *-test
  qapi-schema/*.test.*
diff --git a/tests/Makefile b/tests/Makefile
index 650e654..e56c514 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -212,6 +212,7 @@ ifeq ($(CONFIG_VHOST_NET_TEST_i386),)
  check-qtest-x86_64-$(CONFIG_VHOST_NET_TEST_x86_64) += 
tests/vhost-user-test$(EXESUF)
  endif
  check-qtest-i386-y += tests/test-netfilter$(EXESUF)
+check-qtest-i386-y += tests/test-filter-mirror$(EXESUF)
  check-qtest-x86_64-y = $(check-qtest-i386-y)
  gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
  gcov-files-x86_64-y = $(subst 
i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
@@ -563,6 +564,7 @@ tests/qemu-iotests/socket_scm_helper$(EXESUF): 
tests/qemu-iotests/socket_scm_hel
  tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
  tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o 
$(test-block-obj-y)
  tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y)
+tests/test-filter-mirror$(EXESUF): tests/test-filter-mirror.o $(qtest-obj-y)
  tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o 
contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y)
  tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o
  
diff --git a/tests/test-filter-mirror.c b/tests/test-filter-mirror.c

new file mode 100644
index 000..23dd7c0
--- /dev/null
+++ b/tests/test-filter-mirror.c
@@ -0,0 +1,87 @@
+/*
+ * QTest testcase for filter-mirror
+ *
+ * Copyright (c) 2016 FUJITSU LIMITED
+ * Author: Zhang Chen 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later.  See the COPYING file in the top-level directory.
+ */
+
+#include 
+#include "libqtest.h"
+#include "qemu/iov.h"
+#include "qemu/sockets.h"
+#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
+
+#define SOCK_PATH "/tmp/filter-mirror-test.sock"
+
+static void test_mirror(void)
+{
+#ifndef _WIN32
+/* socketpair(PF_UNIX) which does not exist on windows */
+
+int send_sock[2], recv_sock;
+char *cmdline;
+uint32_t ret = 0, len = 0;
+char send_buf[] = "Hello! filter-mirror~";
+char *recv_buf;
+uint32_t size = sizeof(send_buf);
+size = htonl(size);
+
+ret = socketpair(PF_UNIX, SOCK_STREAM, 0, send_sock);
+g_assert_cmpint(ret, !=, -1);
+
+cmdline = g_strdup_printf("-netdev socket,id=qtest-bn0,fd=%d "
+ "-device e1000,netdev=qtest-bn0,id=qtest-e0 "
+ "-chardev socket,id=mirror0,path=%s,server,nowait "
+ "-object 
filter-mirror,id=qtest-f0,netdev=qtest-bn0,queue=tx,outdev=mirror0 "
+ , send_sock[1], SOCK_PATH);

Rethink about the hard coded "/tmp". This looks not good, we'd better
switch to use mkdtemp() instead. There're few examples in tests/ for you
reference.

Other looks good.


OK, I will fix in in next version.
Thanks
zhangchen


+qtest_start(cmdline);
+g_free(cmdline);
+
+recv_sock = unix_connect(SOCK_PATH, NULL);
+g_assert_cmpint(recv_sock, !=, -1);
+
+struct iovec iov[] = {
+{
+.iov_base = ,
+.iov_len = sizeof(size),
+}, {
+.iov_base = send_buf,
+.iov_len = sizeof(send_buf),
+},
+};
+ret = iov_send(send_sock[0], iov, 2, 0, sizeof(size) + sizeof(send_buf));
+g_assert_cmpint(ret, ==, sizeof(send_buf) + sizeof(size));
+close(send_sock[0]);
+
+ret = qemu_recv(recv_sock, , sizeof(len), 0);
+g_assert_cmpint(ret, ==, sizeof(len));
+len = ntohl(len);
+
+g_assert_cmpint(len, ==, sizeof(send_buf));
+recv_buf = g_malloc(len);
+ret = qemu_recv(recv_sock, recv_buf, len, 0);
+g_assert_cmpstr(recv_buf, ==, send_buf);
+
+g_free(recv_buf);
+close(recv_sock);
+unlink(SOCK_PATH);
+
+#endif
+}
+
+int main(int argc, char **argv)
+{
+int ret;
+
+  

[Qemu-devel] [PATCH v2] net: ne2000: check ring buffer control registers

2016-02-23 Thread P J P
From: Prasad J Pandit 

Ne2000 NIC uses ring buffer of NE2000_MEM_SIZE(49152)
bytes to process network packets. Registers PSTART & PSTOP
define ring buffer size & location. Setting these registers
to invalid values could lead to infinite loop or OOB r/w
access issues. Add check to avoid it.

Reported-by: Yang Hongke 
Signed-off-by: Prasad J Pandit 
---
 hw/net/ne2000.c | 4 
 1 file changed, 4 insertions(+)

Update per review:
  -> https://lists.gnu.org/archive/html/qemu-devel/2016-02/msg05522.html

diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index b032212..ced4666 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -154,6 +154,10 @@ static int ne2000_buffer_full(NE2000State *s)
 {
 int avail, index, boundary;
 
+if (s->stop <= s->start) {
+return 1;
+}
+
 index = s->curpag << 8;
 boundary = s->boundary << 8;
 if (index < boundary)
-- 
2.5.0




Re: [Qemu-devel] [PATCH] net: ne2000: check ring buffer control registers

2016-02-23 Thread P J P
+-- On Wed, 24 Feb 2016, Jason Wang wrote --+
| Right, but since setting STARTPG,STOPPG,BOUNDARY and CURPAG is not
| atomic. Try to limit it during value setting is hard to be correct.

  I see.
 
| Then let's return true when s->stop <= s->start?

  Okay. Though I'm not sure if it's the right place for it, because more than 
buffer is full, it says buffer does not exist.
 
| It's really hard to say there's no such driver. Which means if there's
| such a driver and it works on real hardware, we need make it work for qemu.

  I guess better would be to see if the hardware standard specifies such an 
interface for the driver. I did not find it mentioned anywhere; Even kernel 
drivers have it fixed.

I'll send a revised patch for ne2000_buffer_full().
--
 - P J P
47AF CE69 3A90 54AA 9045 1053 DD13 3D32 FE5B 041F



Re: [Qemu-devel] [GIT PULL] pseries: Update SLOF firmware image to 20160223

2016-02-23 Thread David Gibson
On Tue, Feb 23, 2016 at 07:25:13PM +1100, Alexey Kardashevskiy wrote:
> 
> This is expected to go via the powerpc tree at 
> git://github.com/dgibson/qemu.git
> 
> 
> The following changes since commit 8eb779e4223a18db9838a49ece1bc72cfdfb7761:
> 
>   Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging 
> (2016-02-22 16:55:41 +)
> 
> are available in the git repository at:
> 
>   g...@github.com:aik/qemu.git 
> 
> for you to fetch changes up to d618bd06b255fcde2111f5733f48d38f5b2532d6:
> 
>   pseries: Update SLOF firmware image to 20160223 (2016-02-23 18:11:17 +1100)

Erm.. I pulled that remote, but:

$ git show d618bd06b255fcde2111f5733f48d38f5b2532d6
fatal: bad object d618bd06b255fcde2111f5733f48d38f5b2532d6

Nor can I see these changes in any of the branches.

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH] net: check packet payload length

2016-02-23 Thread P J P
+-- On Wed, 24 Feb 2016, Jason Wang wrote --+
| > -  hw/net/virtio-net.c
| >  if (size > 27 && size < 1500) &&
| >  (buf[34] == 0 && buf[35] == 67)) {
| 
| Are we sure size of buf is >= 35 here?

  No; I'm yet to see why it checks for > 27. If (27 < size < 34) then we have 
another OOB access there.

| > +if (len < 14+20)
| > +return;
| 
| Ok.

I have sent a revised v2 of this patch.
--
Prasad J Pandit / Red Hat Product Security Team
47AF CE69 3A90 54AA 9045 1053 DD13 3D32 FE5B 041F



Re: [Qemu-devel] CPU hotplug, again

2016-02-23 Thread Bharata B Rao
On Wed, Feb 24, 2016 at 01:01:06PM +1100, David Gibson wrote:
> On Tue, Feb 23, 2016 at 12:18:59PM +0100, Igor Mammedov wrote:
> > On Tue, 23 Feb 2016 21:05:04 +1100
> > David Gibson  wrote:
> > 
> > > On Tue, Feb 23, 2016 at 03:10:26PM +0530, Bharata B Rao wrote:
> > > > On Tue, Feb 23, 2016 at 04:24:31PM +1100, David Gibson wrote:  
> > > > > Hi Andreas,
> > > > > 
> > > > > I've now found (with Thomas' help) your RFC series for socket/core
> > > > > based cpu hotplug on x86
> > > > > (https://github.com/afaerber/qemu-cpu/compare/qom-cpu-x86).  It seems
> > > > > sensible enough as far as it goes, but doesn't seem to address a bunch
> > > > > of the things that I was attempting to do with the cpu-package
> > > > > proposal - and which we absolutely need for cpu hotplug on Power.
> > > > > 
> > > > > 1) What interface do you envisage beyond cpu_add?
> > > > > 
> > > > > The patches I see just construct extra socket and core objects, but
> > > > > still control hotplug (for x86) through the cpu_add interface.  That
> > > > > interface is absolutely unusable on Power, since it operates on a
> > > > > per-thread basis, whereas the PAPR guest<->host interfaces can only
> > > > > communicate information at a per-core granularity.
> > > > > 
> > > > > 2) When hotplugging at core or socket granularity, where would the
> > > > >code to construct the individual thread objects sit?
> > > > > 
> > > > > Your series has the construction done in both the machine init path
> > > > > and the hotplug path.  The latter works because hotplug occurs at
> > > > > thread granularity.  If we're hotplugging at core or socket
> > > > > granularity what would do the construct?  The core/socket object
> > > > > itself (in instance_init?  in realize?); the hotplug handler?
> > > > > something else?
> > > > > 
> > > > > 3) How does the management layer determine what is pluggable?
> > > > > 
> > > > > Both the number of pluggable slots, and what it will need to do to
> > > > > populate them.
> > > > > 
> > > > > 4) How do we enforce that toplogies illegal for the platform can't be
> > > > >constructed?  
> > > > 
> > > > 5) QOM-links
> > > > 
> > > > Andreas, You have often talked about setting up links from machine 
> > > > object
> > > > to the CPU objects. Would the below code correctly capture that idea of
> > > > yours ?
> > > > 
> > > > #define SPAPR_MACHINE_CPU_CORE_PROP "core"
> > > > 
> > > > /* MachineClass.init for sPAPR */
> > > > static void ppc_spapr_init(MachineState *machine)
> > > > {
> > > > sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
> > > > int spapr_smp_cores = smp_cpus / smp_threads;
> > > > int spapr_max_cores = max_cpus / smp_threads;
> > > > 
> > > > ...
> > > > for (i = 0; i < spapr_max_cores; i++) {
> > > > Object *obj = object_new(TYPE_SPAPR_CPU_CORE);
> > > > sPAPRCPUCore *core = SPAPR_CPU_CORE(obj);
> > > > char name[32];
> > > > 
> > > > snprintf(name, sizeof(name), "%s[%d]", 
> > > > SPAPR_MACHINE_CPU_CORE_PROP, i);
> > > > 
> > > > /*
> > > >  * Create links from machine objects to all possible cores.
> > > >  */
> > > > object_property_add_link(OBJECT(spapr), name, 
> > > > TYPE_SPAPR_CPU_CORE,
> > > >  (Object **)>core[i],
> > > >  NULL, NULL, _abort); 
> > > > 
> > > > /*
> > > >  * Set the QOM link from machine object to core object for all
> > > >  * boot time CPUs specified with -smp. For rest of the 
> > > > hotpluggable
> > > >  * cores this is done from the core hotplug path.
> > > >  */
> > > > if (i < spapr_smp_cores) {
> > > > object_property_set_link(OBJECT(spapr), OBJECT(core),
> > > >  SPAPR_MACHINE_CPU_CORE_PROP, 
> > > > _abort);  
> > > 
> > > I hope we can at least have a helper function to both construct the
> > > core and create the links, if we can't handle the link creation in the
> > > core object itself.
> > > 
> > > Having to open-code it in each machine sounds like a recipe for subtle
> > > differences in presentation between platforms, which is exactly what
> > > we want to avoid.
> > Creating links doesn't give us much, it's just adds means for mgmt
> > to check how many CPUs could be hotplugged  without keeping that
> > state in mgmt like it's now, so links are mostly useless if one
> > care where CPU is being plugged in.
> > The rest like enumerating exiting CPUs could be done by
> > traversing QOM tree, links would just simplify finding
> > CPUs putting them at fixed namespace.
> 
> Simplifying finding CPUs is pretty much all we intended the links for.
> Well, and then I was expecting a different set of links to simplify
> enumerating all the threads in a cpu package/core/socket/whatever.

That's what child links (socket to core to thread on x86 and core to thread
on powerpc) will give 

Re: [Qemu-devel] [PATCH V5 1/2] net/filter-mirror:Add filter-mirror

2016-02-23 Thread Zhang Chen



On 02/24/2016 11:22 AM, Jason Wang wrote:


On 02/23/2016 08:00 PM, Zhang Chen wrote:

Filter-mirror is a netfilter plugin.
It gives qemu the ability to mirror
packets to a chardev.

usage:

-netdev tap,id=hn0
-chardev socket,id=mirror0,host=ip_primary,port=X,server,nowait
-filter-mirror,id=m0,netdev=hn0,queue=tx/rx/all,outdev=mirror0

Signed-off-by: Zhang Chen 
Signed-off-by: Wen Congyang 
Reviewed-by: Yang Hongyang 
Reviewed-by: zhanghailiang 
---
  net/Makefile.objs   |   1 +
  net/filter-mirror.c | 181 
  qemu-options.hx |   5 ++
  vl.c|   3 +-
  4 files changed, 189 insertions(+), 1 deletion(-)
  create mode 100644 net/filter-mirror.c

diff --git a/net/Makefile.objs b/net/Makefile.objs
index 5fa2f97..b7c22fd 100644
--- a/net/Makefile.objs
+++ b/net/Makefile.objs
@@ -15,3 +15,4 @@ common-obj-$(CONFIG_VDE) += vde.o
  common-obj-$(CONFIG_NETMAP) += netmap.o
  common-obj-y += filter.o
  common-obj-y += filter-buffer.o
+common-obj-y += filter-mirror.o
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
new file mode 100644
index 000..ad722f7
--- /dev/null
+++ b/net/filter-mirror.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ * Copyright (c) 2016 FUJITSU LIMITED
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Author: Zhang Chen 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later.  See the COPYING file in the top-level directory.
+ */
+
+#include "net/filter.h"
+#include "net/net.h"
+#include "qemu-common.h"
+#include "qapi/qmp/qerror.h"
+#include "qapi-visit.h"
+#include "qom/object.h"
+#include "qemu/main-loop.h"
+#include "qemu/error-report.h"
+#include "trace.h"
+#include "sysemu/char.h"
+#include "qemu/iov.h"
+#include "qemu/sockets.h"
+
+#define FILTER_MIRROR(obj) \
+OBJECT_CHECK(MirrorState, (obj), TYPE_FILTER_MIRROR)
+
+#define TYPE_FILTER_MIRROR "filter-mirror"
+
+typedef struct MirrorState {
+NetFilterState parent_obj;
+char *outdev;
+CharDriverState *chr_out;
+} MirrorState;
+
+static int filter_mirror_send(NetFilterState *nf,
+   const struct iovec *iov,
+   int iovcnt)
+{
+MirrorState *s = FILTER_MIRROR(nf);
+int ret = 0;
+ssize_t size = 0;
+uint32_t len =  0;
+char *buf;
+
+size = iov_size(iov, iovcnt);
+if (!size) {
+return 0;
+}
+
+len = htonl(size);
+ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *), sizeof(len));
+if (ret != sizeof(len)) {
+goto err;
+}
+
+buf = g_malloc(size);
+iov_to_buf(iov, iovcnt, 0, buf, size);
+ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *)buf, size);
+g_free(buf);
+if (ret != size) {
+goto err;
+}
+
+return 0;
+
+err:
+  return ret < 0 ? ret : -EIO;

The indentation looks odd here.

Other looks good.


Thanks~~ fix it in next version~

zhangchen


+}
+
+static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
+ NetClientState *sender,
+ unsigned flags,
+ const struct iovec *iov,
+ int iovcnt,
+ NetPacketSent *sent_cb)
+{
+int ret;
+
+ret = filter_mirror_send(nf, iov, iovcnt);
+if (ret) {
+error_report("filter_mirror_send failed(%s)", strerror(-ret));
+}
+
+/*
+ * we don't hope this error interrupt the normal
+ * path of net packet, so we always return zero.
+ */
+return 0;
+}
+
+static void filter_mirror_cleanup(NetFilterState *nf)
+{
+MirrorState *s = FILTER_MIRROR(nf);
+
+if (s->chr_out) {
+qemu_chr_fe_release(s->chr_out);
+}
+}
+
+static void filter_mirror_setup(NetFilterState *nf, Error **errp)
+{
+MirrorState *s = FILTER_MIRROR(nf);
+
+if (!s->outdev) {
+error_setg(errp, "filter filter mirror needs 'outdev' "
+"property set");
+return;
+}
+
+s->chr_out = qemu_chr_find(s->outdev);
+if (s->chr_out == NULL) {
+error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+  "Device '%s' not found", s->outdev);
+return;
+}
+
+if (qemu_chr_fe_claim(s->chr_out) != 0) {
+error_setg(errp, QERR_DEVICE_IN_USE, s->outdev);
+return;
+}
+}
+
+static void filter_mirror_class_init(ObjectClass *oc, void *data)
+{
+NetFilterClass *nfc = NETFILTER_CLASS(oc);
+
+nfc->setup = filter_mirror_setup;
+nfc->cleanup = filter_mirror_cleanup;
+nfc->receive_iov = filter_mirror_receive_iov;
+}
+
+static char *filter_mirror_get_outdev(Object *obj, Error **errp)
+{
+MirrorState *s = FILTER_MIRROR(obj);
+
+return g_strdup(s->outdev);
+}

[Qemu-devel] [PATCH] net: filter: correctly remove filter from the list during finalization

2016-02-23 Thread Jason Wang
Qemu may crash when we want to add two filters on the same netdev but
the initialization of second fails (e.g missing parameters):

./qemu-system-x86_64 -netdev user,id=un0 \
 -object filter-buffer,id=f0,netdev=un0,interval=10 \
 -object filter-buffer,id=f1,netdev=un0
Segmentation fault (core dumped)

This is because we don't check whether or not the filter was in the
list of netdev. This patch fixes this.

Cc: Yang Hongyang 
Signed-off-by: Jason Wang 
---
 net/filter.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/filter.c b/net/filter.c
index d2a514e..7cdbc6c 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -196,7 +196,8 @@ static void netfilter_finalize(Object *obj)
 nfc->cleanup(nf);
 }
 
-if (nf->netdev && !QTAILQ_EMPTY(>netdev->filters)) {
+if (nf->netdev && !QTAILQ_EMPTY(>netdev->filters) &&
+nf->next.tqe_prev) {
 QTAILQ_REMOVE(>netdev->filters, nf, next);
 }
 g_free(nf->netdev_id);
-- 
2.5.0




[Qemu-devel] [Bug 1490611] Re: Using qemu >=2.2.1 to convert raw->VHD (fixed) adds extra padding to the result file, which Microsoft Azure rejects as invalid

2016-02-23 Thread Jeff Cody
I've posted a series to qemu-devel to hopefully address this issue.
Cole, or anyone else that wants to test it out:
http://lists.nongnu.org/archive/html/qemu-devel/2016-02/msg05511.html

For the specific qemu-img convert case mentioned in this bug report, I
believe using the new "force-size" option should address it, e.g.:

# qemu-img convert -f raw -o subformat=fixed,force-size -O vpc source-
disk.img dest-disk.vhd

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

Title:
  Using qemu >=2.2.1 to convert raw->VHD (fixed) adds extra padding to
  the result file, which Microsoft Azure rejects as invalid

Status in QEMU:
  Fix Released

Bug description:
  Starting with a raw disk image, using "qemu-img convert" to convert
  from raw to VHD results in the output VHD file's virtual size being
  aligned to the nearest 516096 bytes (16 heads x 63 sectors per head x
  512 bytes per sector), instead of preserving the input file's size as
  the output VHD's virtual disk size.

  Microsoft Azure requires that disk images (VHDs) submitted for upload
  have virtual sizes aligned to a megabyte boundary. (Ex. 4096MB,
  4097MB, 4098MB, etc. are OK, 4096.5MB is rejected with an error.) This
  is reflected in Microsoft's documentation: https://azure.microsoft.com
  /en-us/documentation/articles/virtual-machines-linux-create-upload-
  vhd-generic/

  This is reproducible with the following set of commands (including the
  Azure command line tools from https://github.com/Azure/azure-xplat-
  cli). For the following example, I used qemu version 2.2.1:

  $ dd if=/dev/zero of=source-disk.img bs=1M count=4096

  $ stat source-disk.img 
File: ‘source-disk.img’
Size: 4294967296  Blocks: 798656 IO Block: 4096   regular file
  Device: fc01h/64513dInode: 13247963Links: 1
  Access: (0644/-rw-r--r--)  Uid: ( 1000/  smkent)   Gid: ( 1000/  smkent)
  Access: 2015-08-18 09:48:02.613988480 -0700
  Modify: 2015-08-18 09:48:02.825985646 -0700
  Change: 2015-08-18 09:48:02.825985646 -0700
   Birth: -

  $ qemu-img convert -f raw -o subformat=fixed -O vpc source-disk.img
  dest-disk.vhd

  $ stat dest-disk.vhd 
File: ‘dest-disk.vhd’
Size: 4296499712  Blocks: 535216 IO Block: 4096   regular file
  Device: fc01h/64513dInode: 13247964Links: 1
  Access: (0644/-rw-r--r--)  Uid: ( 1000/  smkent)   Gid: ( 1000/  smkent)
  Access: 2015-08-18 09:50:22.252077624 -0700
  Modify: 2015-08-18 09:49:24.424868868 -0700
  Change: 2015-08-18 09:49:24.424868868 -0700
   Birth: -

  $ azure vm image create testimage1 dest-disk.vhd -o linux -l "West US"
  info:Executing command vm image create
  + Retrieving storage accounts 
 
  info:VHD size : 4097 MB
  info:Uploading 4195800.5 KB
  Requested:100.0% Completed:100.0% Running:   0 Time: 1m 0s Speed:  6744 KB/s 
  info:https://[redacted].blob.core.windows.net/vm-images/dest-disk.vhd was 
uploaded successfully
  error:   The VHD 
https://[redacted].blob.core.windows.net/vm-images/dest-disk.vhd has an 
unsupported virtual size of 4296499200 bytes.  The size must be a whole number 
(in MBs).
  info:Error information has been recorded to /home/smkent/.azure/azure.err
  error:   vm image create command failed

  I also ran the above commands using qemu 2.4.0, which resulted in the
  same error as the conversion behavior is the same.

  However, qemu 2.1.1 and earlier (including qemu 2.0.0 installed by
  Ubuntu 14.04) does not pad the virtual disk size during conversion.
  Using qemu-img convert from qemu versions <=2.1.1 results in a VHD
  that is exactly the size of the raw input file plus 512 bytes (for the
  VHD footer). Those qemu versions do not attempt to realign the disk.
  As a result, Azure accepts VHD files created using those versions of
  qemu-img convert for upload.

  Is there a reason why newer qemu realigns the converted VHD file? It
  would be useful if an option were added to disable this feature, as
  current versions of qemu cannot be used to create VHD files for Azure
  using Microsoft's official instructions.

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



Re: [Qemu-devel] [PATCH] net/filter-redirector:Add filter-redirector

2016-02-23 Thread Jason Wang


On 02/18/2016 03:50 PM, Zhang Chen wrote:
>
>
> On 02/18/2016 10:41 AM, Jason Wang wrote:
>>
>> On 02/05/2016 02:50 PM, Zhang Chen wrote:
>>> From: ZhangChen 
>>>
>>> Filter-redirector is a netfilter plugin.
>>> It gives qemu the ability to redirect net packet.
>>> redirector can redirect filter's net packet to outdev.
>>> and redirect indev's packet to filter.
>>>
>>>   filter
>>> +
>>> |
>>> |
>>>redirector   |
>>> +-+
>>> |   | |
>>> |   | |
>>> |   | |
>>>indev ++ +>  outdev
>>> | |   |
>>> | |   |
>>> | |   |
>>> +-+
>>>   |
>>>   |
>>>   v
>>>filter
>
>   v
>
> change it to   filter  filter .. guest
> It's may more clearly expressed.
>
>>> usage:
>>>
>>> -netdev tap,id=hn0
>>> -chardev socket,id=s0,host=ip_primary,port=X,server,nowait
>>> -chardev socket,id=s1,host=ip_primary,port=Y,server,nowait
>>> -filter-redirector,id=r0,netdev=hn0,queue=tx/rx/all,indev=s0,outdev=s1
>>>
>>> Signed-off-by: ZhangChen 
>>> Signed-off-by: Wen Congyang 
>>> ---
>> Thanks a lot for the patch. Like mirror, let's design a unit-test for
>> this. And what's more, is there any chance to unify the codes? (At least
>> parts of the codes could be reused).
>
> We can make filter-redirector based on filter-mirror.
> if you want to use redirector ,you must open mirror before.
> like this:
>
> -netdev tap,id=hn0
> -chardev socket,id=mirror0,host=ip_primary,port=X,server,nowait
> -filter-mirror,id=m0,netdev=hn0,queue=tx/rx/all,redirector=on,outdev=mirror0
>
> -filter-redirector,id=r0,netdev=hn0,queue=tx/rx/all,indev=s0
>
> How about this?

This looks like a burden for user who just want to use redirector. Maybe
we can do :

- Still two type of filters but sharing a single state.
- Using a internal flag to differ mirrors from redirectors?

>
>
>>>   net/Makefile.objs   |   1 +
>>>   net/filter-redirector.c | 245
>>> 
>>>   qemu-options.hx |   6 ++
>>>   vl.c|   3 +-
>>>   4 files changed, 254 insertions(+), 1 deletion(-)
>>>   create mode 100644 net/filter-redirector.c
>>>
>>> diff --git a/net/Makefile.objs b/net/Makefile.objs
>>> index 5fa2f97..f4290a5 100644
>>> --- a/net/Makefile.objs
>>> +++ b/net/Makefile.objs
>>> @@ -15,3 +15,4 @@ common-obj-$(CONFIG_VDE) += vde.o
>>>   common-obj-$(CONFIG_NETMAP) += netmap.o
>>>   common-obj-y += filter.o
>>>   common-obj-y += filter-buffer.o
>>> +common-obj-y += filter-redirector.o
>>> diff --git a/net/filter-redirector.c b/net/filter-redirector.c
>>> new file mode 100644
>>> index 000..364e463
>>> --- /dev/null
>>> +++ b/net/filter-redirector.c
>>> @@ -0,0 +1,245 @@
>>> +/*
>>> + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
>>> + * Copyright (c) 2016 FUJITSU LIMITED
>>> + * Copyright (c) 2016 Intel Corporation
>>> + *
>>> + * Author: Zhang Chen 
>>> + *
>>> + * This work is licensed under the terms of the GNU GPL, version 2 or
>>> + * later.  See the COPYING file in the top-level directory.
>>> + */
>>> +
>>> +#include "net/filter.h"
>>> +#include "net/net.h"
>>> +#include "qemu-common.h"
>>> +#include "qapi/qmp/qerror.h"
>>> +#include "qapi-visit.h"
>>> +#include "qom/object.h"
>>> +#include "qemu/main-loop.h"
>>> +#include "qemu/error-report.h"
>>> +#include "trace.h"
>>> +#include "sysemu/char.h"
>>> +#include "qemu/iov.h"
>>> +#include "qemu/sockets.h"
>>> +
>>> +#define FILTER_REDIRECTOR(obj) \
>>> +OBJECT_CHECK(RedirectorState, (obj), TYPE_FILTER_REDIRECTOR)
>>> +
>>> +#define TYPE_FILTER_REDIRECTOR "filter-redirector"
>>> +#define REDIRECT_HEADER_LEN sizeof(uint32_t)
>>> +
>>> +typedef struct RedirectorState {
>>> +NetFilterState parent_obj;
>>> +NetQueue *incoming_queue;/* guest normal net queue */
>> The comment looks unless and maybe even wrong when queue=rx?
>
> We design redirector that indev's data always be passed to guest finally.
> so, It's no relation between the queue=rx/tx/all. just related to
> indev = xxx.
> we need incoming_queue to inject packet from indev.

So what happens if queue=rx or you want to forbid queue=rx for redirector?




Re: [Qemu-devel] [PATCH V5 2/2] tests/test-filter-mirror:add filter-mirror unit test

2016-02-23 Thread Jason Wang


On 02/23/2016 08:00 PM, Zhang Chen wrote:
> In this unit test we will test the mirror function.
>
> start qemu with:
>  -netdev socket,id=qtest-bn0,fd=sockfd
>  -device e1000,netdev=qtest-bn0,id=qtest-e0
>  -chardev 
> socket,id=mirror0,path=/tmp/filter-mirror-test.sock,server,nowait
>  -object 
> filter-mirror,id=qtest-f0,netdev=qtest-bn0,queue=tx,outdev=mirror0
>
> We inject packet to netdev socket id = qtest-bn0,
> filter-mirror will copy and mirror the packet to mirror0.
> we read packet from mirror0 and then compare to what we inject.
>
> Signed-off-by: Zhang Chen 
> Signed-off-by: Wen Congyang 
> ---
>  tests/.gitignore   |  1 +
>  tests/Makefile |  2 ++
>  tests/test-filter-mirror.c | 87 
> ++
>  3 files changed, 90 insertions(+)
>  create mode 100644 tests/test-filter-mirror.c
>
> diff --git a/tests/.gitignore b/tests/.gitignore
> index 787c95c..10df017 100644
> --- a/tests/.gitignore
> +++ b/tests/.gitignore
> @@ -63,5 +63,6 @@ test-write-threshold
>  test-x86-cpuid
>  test-xbzrle
>  test-netfilter
> +test-filter-mirror
>  *-test
>  qapi-schema/*.test.*
> diff --git a/tests/Makefile b/tests/Makefile
> index 650e654..e56c514 100644
> --- a/tests/Makefile
> +++ b/tests/Makefile
> @@ -212,6 +212,7 @@ ifeq ($(CONFIG_VHOST_NET_TEST_i386),)
>  check-qtest-x86_64-$(CONFIG_VHOST_NET_TEST_x86_64) += 
> tests/vhost-user-test$(EXESUF)
>  endif
>  check-qtest-i386-y += tests/test-netfilter$(EXESUF)
> +check-qtest-i386-y += tests/test-filter-mirror$(EXESUF)
>  check-qtest-x86_64-y = $(check-qtest-i386-y)
>  gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
>  gcov-files-x86_64-y = $(subst 
> i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
> @@ -563,6 +564,7 @@ tests/qemu-iotests/socket_scm_helper$(EXESUF): 
> tests/qemu-iotests/socket_scm_hel
>  tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
>  tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o 
> $(test-block-obj-y)
>  tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y)
> +tests/test-filter-mirror$(EXESUF): tests/test-filter-mirror.o $(qtest-obj-y)
>  tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o 
> contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y)
>  tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o
>  
> diff --git a/tests/test-filter-mirror.c b/tests/test-filter-mirror.c
> new file mode 100644
> index 000..23dd7c0
> --- /dev/null
> +++ b/tests/test-filter-mirror.c
> @@ -0,0 +1,87 @@
> +/*
> + * QTest testcase for filter-mirror
> + *
> + * Copyright (c) 2016 FUJITSU LIMITED
> + * Author: Zhang Chen 
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * later.  See the COPYING file in the top-level directory.
> + */
> +
> +#include 
> +#include "libqtest.h"
> +#include "qemu/iov.h"
> +#include "qemu/sockets.h"
> +#include "qemu/error-report.h"
> +#include "qemu/main-loop.h"
> +
> +#define SOCK_PATH "/tmp/filter-mirror-test.sock"
> +
> +static void test_mirror(void)
> +{
> +#ifndef _WIN32
> +/* socketpair(PF_UNIX) which does not exist on windows */
> +
> +int send_sock[2], recv_sock;
> +char *cmdline;
> +uint32_t ret = 0, len = 0;
> +char send_buf[] = "Hello! filter-mirror~";
> +char *recv_buf;
> +uint32_t size = sizeof(send_buf);
> +size = htonl(size);
> +
> +ret = socketpair(PF_UNIX, SOCK_STREAM, 0, send_sock);
> +g_assert_cmpint(ret, !=, -1);
> +
> +cmdline = g_strdup_printf("-netdev socket,id=qtest-bn0,fd=%d "
> + "-device e1000,netdev=qtest-bn0,id=qtest-e0 "
> + "-chardev socket,id=mirror0,path=%s,server,nowait "
> + "-object 
> filter-mirror,id=qtest-f0,netdev=qtest-bn0,queue=tx,outdev=mirror0 "
> + , send_sock[1], SOCK_PATH);

Rethink about the hard coded "/tmp". This looks not good, we'd better
switch to use mkdtemp() instead. There're few examples in tests/ for you
reference.

Other looks good.

> +qtest_start(cmdline);
> +g_free(cmdline);
> +
> +recv_sock = unix_connect(SOCK_PATH, NULL);
> +g_assert_cmpint(recv_sock, !=, -1);
> +
> +struct iovec iov[] = {
> +{
> +.iov_base = ,
> +.iov_len = sizeof(size),
> +}, {
> +.iov_base = send_buf,
> +.iov_len = sizeof(send_buf),
> +},
> +};
> +ret = iov_send(send_sock[0], iov, 2, 0, sizeof(size) + sizeof(send_buf));
> +g_assert_cmpint(ret, ==, sizeof(send_buf) + sizeof(size));
> +close(send_sock[0]);
> +
> +ret = qemu_recv(recv_sock, , sizeof(len), 0);
> +g_assert_cmpint(ret, ==, sizeof(len));
> +len = ntohl(len);
> +
> +g_assert_cmpint(len, ==, sizeof(send_buf));
> +recv_buf = g_malloc(len);
> +ret = qemu_recv(recv_sock, recv_buf, len, 0);
> +g_assert_cmpstr(recv_buf, ==, send_buf);
> 

Re: [Qemu-devel] [PATCH V5 1/2] net/filter-mirror:Add filter-mirror

2016-02-23 Thread Jason Wang


On 02/23/2016 08:00 PM, Zhang Chen wrote:
> Filter-mirror is a netfilter plugin.
> It gives qemu the ability to mirror
> packets to a chardev.
>
> usage:
>
> -netdev tap,id=hn0
> -chardev socket,id=mirror0,host=ip_primary,port=X,server,nowait
> -filter-mirror,id=m0,netdev=hn0,queue=tx/rx/all,outdev=mirror0
>
> Signed-off-by: Zhang Chen 
> Signed-off-by: Wen Congyang 
> Reviewed-by: Yang Hongyang 
> Reviewed-by: zhanghailiang 
> ---
>  net/Makefile.objs   |   1 +
>  net/filter-mirror.c | 181 
> 
>  qemu-options.hx |   5 ++
>  vl.c|   3 +-
>  4 files changed, 189 insertions(+), 1 deletion(-)
>  create mode 100644 net/filter-mirror.c
>
> diff --git a/net/Makefile.objs b/net/Makefile.objs
> index 5fa2f97..b7c22fd 100644
> --- a/net/Makefile.objs
> +++ b/net/Makefile.objs
> @@ -15,3 +15,4 @@ common-obj-$(CONFIG_VDE) += vde.o
>  common-obj-$(CONFIG_NETMAP) += netmap.o
>  common-obj-y += filter.o
>  common-obj-y += filter-buffer.o
> +common-obj-y += filter-mirror.o
> diff --git a/net/filter-mirror.c b/net/filter-mirror.c
> new file mode 100644
> index 000..ad722f7
> --- /dev/null
> +++ b/net/filter-mirror.c
> @@ -0,0 +1,181 @@
> +/*
> + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
> + * Copyright (c) 2016 FUJITSU LIMITED
> + * Copyright (c) 2016 Intel Corporation
> + *
> + * Author: Zhang Chen 
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or
> + * later.  See the COPYING file in the top-level directory.
> + */
> +
> +#include "net/filter.h"
> +#include "net/net.h"
> +#include "qemu-common.h"
> +#include "qapi/qmp/qerror.h"
> +#include "qapi-visit.h"
> +#include "qom/object.h"
> +#include "qemu/main-loop.h"
> +#include "qemu/error-report.h"
> +#include "trace.h"
> +#include "sysemu/char.h"
> +#include "qemu/iov.h"
> +#include "qemu/sockets.h"
> +
> +#define FILTER_MIRROR(obj) \
> +OBJECT_CHECK(MirrorState, (obj), TYPE_FILTER_MIRROR)
> +
> +#define TYPE_FILTER_MIRROR "filter-mirror"
> +
> +typedef struct MirrorState {
> +NetFilterState parent_obj;
> +char *outdev;
> +CharDriverState *chr_out;
> +} MirrorState;
> +
> +static int filter_mirror_send(NetFilterState *nf,
> +   const struct iovec *iov,
> +   int iovcnt)
> +{
> +MirrorState *s = FILTER_MIRROR(nf);
> +int ret = 0;
> +ssize_t size = 0;
> +uint32_t len =  0;
> +char *buf;
> +
> +size = iov_size(iov, iovcnt);
> +if (!size) {
> +return 0;
> +}
> +
> +len = htonl(size);
> +ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *), sizeof(len));
> +if (ret != sizeof(len)) {
> +goto err;
> +}
> +
> +buf = g_malloc(size);
> +iov_to_buf(iov, iovcnt, 0, buf, size);
> +ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *)buf, size);
> +g_free(buf);
> +if (ret != size) {
> +goto err;
> +}
> +
> +return 0;
> +
> +err:
> +  return ret < 0 ? ret : -EIO;

The indentation looks odd here.

Other looks good.

> +}
> +
> +static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
> + NetClientState *sender,
> + unsigned flags,
> + const struct iovec *iov,
> + int iovcnt,
> + NetPacketSent *sent_cb)
> +{
> +int ret;
> +
> +ret = filter_mirror_send(nf, iov, iovcnt);
> +if (ret) {
> +error_report("filter_mirror_send failed(%s)", strerror(-ret));
> +}
> +
> +/*
> + * we don't hope this error interrupt the normal
> + * path of net packet, so we always return zero.
> + */
> +return 0;
> +}
> +
> +static void filter_mirror_cleanup(NetFilterState *nf)
> +{
> +MirrorState *s = FILTER_MIRROR(nf);
> +
> +if (s->chr_out) {
> +qemu_chr_fe_release(s->chr_out);
> +}
> +}
> +
> +static void filter_mirror_setup(NetFilterState *nf, Error **errp)
> +{
> +MirrorState *s = FILTER_MIRROR(nf);
> +
> +if (!s->outdev) {
> +error_setg(errp, "filter filter mirror needs 'outdev' "
> +"property set");
> +return;
> +}
> +
> +s->chr_out = qemu_chr_find(s->outdev);
> +if (s->chr_out == NULL) {
> +error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
> +  "Device '%s' not found", s->outdev);
> +return;
> +}
> +
> +if (qemu_chr_fe_claim(s->chr_out) != 0) {
> +error_setg(errp, QERR_DEVICE_IN_USE, s->outdev);
> +return;
> +}
> +}
> +
> +static void filter_mirror_class_init(ObjectClass *oc, void *data)
> +{
> +NetFilterClass *nfc = NETFILTER_CLASS(oc);
> +
> +nfc->setup = filter_mirror_setup;
> +nfc->cleanup = 

Re: [Qemu-devel] [PATCH] net: check packet payload length

2016-02-23 Thread Jason Wang


On 02/23/2016 07:11 PM, P J P wrote:
>   Hello Jason,
>
> +-- On Tue, 23 Feb 2016, Jason Wang wrote --+
> | Let's avoid adding assert() here since it could be triggered by guest.
>
>   Okay.
>
> | I think you need audit all the callers to see if the issue mentioned by
> | Markus existed first.
>
>   Yes, I did. As mentioned earlier, some have check for minimum packet size, 
> others check for length > 0.
>
> net_checksum_calculate is called as:
>
> -  hw/net/cadence_gem.c
>  if (tx_desc_get_length(desc) == 0))
> DB_PRINT("Invalid TX descriptor @ 0x%x\n",
>  }
>  total_bytes += tx_desc_get_length(desc);
>net_checksum_calculate(tx_packet, total_bytes);
>
> -  hw/net/fsl_etsec/rings.c
>  if (etsec->tx_buffer_len != 0
>  net_checksum_calculate(etsec->tx_buffer + 8,
>   etsec->tx_buffer_len - 8);
>
> -  hw/net/virtio-net.c
>  if (size > 27 && size < 1500) &&
>  (buf[34] == 0 && buf[35] == 67)) {

Are we sure size of buf is >= 35 here?

>  net_checksum_calculate(buf, size);
>
> -  hw/net/xen_nic.c
>  if (txreq.size < 14) {  
>  xen_be_printf(>xendev, 0, "bad packet size:
>  }
>  net_checksum_calculate(tmpbuf, txreq.size);
>   
> It might be possible to send a packet with (length < 14+20), and cause an OOB 
> read in net_checksum_calculate,
>
> if ((data[14] & 0xf0) != 0x40)
> return; /* not IPv4 */
> hlen  = (data[14] & 0x0f) * 4;
> plen  = (data[16] << 8 | data[17]) - hlen;
> proto = data[23];
>
> I'll send a revised patch with a check for minimum 'data' length to include 
> complete layer-2(14) + layer-3(20) headers.
>
> +if (len < 14+20)
> +return;
>
>
> Thank you.

Ok.

> --
>  - P J P
> 47AF CE69 3A90 54AA 9045 1053 DD13 3D32 FE5B 041F
>




[Qemu-devel] [PATCH] qemu-options.hx: add missing chardev id in example of vhost-user

2016-02-23 Thread Lin Ma
Signed-off-by: Lin Ma 
---
 qemu-options.hx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index 2f0465e..6afa612 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2063,7 +2063,7 @@ Example:
 @example
 qemu -m 512 -object 
memory-backend-file,id=mem,size=512M,mem-path=/hugetlbfs,share=on \
  -numa node,memdev=mem \
- -chardev socket,path=/path/to/socket \
+ -chardev socket,id=chr0,path=/path/to/socket \
  -netdev type=vhost-user,id=net0,chardev=chr0 \
  -device virtio-net-pci,netdev=net0
 @end example
-- 
2.6.3




Re: [Qemu-devel] [PATCH v4 1/2] qmp event: Add QUORUM_FLUSH_ERROR

2016-02-23 Thread Changlong Xie

On 02/23/2016 10:05 PM, Alberto Garcia wrote:

On Tue 23 Feb 2016 02:45:49 PM CET, Eric Blake wrote:


Commit message should say why we need a third event, rather than
reusing either of the other two (my guess: because you don't have a
location, and don't want to modify the existing two to report a
location - but why not just use 'sector-num':0,
'sectors-count': to report the entire file as the
location?)


I would also be fine with that solution.


I would also be fine if we added an optional enum member to the
existing event that said which operation failed ('read', 'write',
'flush') - adding optional output members is safe, while converting
existing mandatory output members to optional may confuse existing
clients.




Hi Berto & Eric

Thanks for all your comments. Surely, this is the best option to me too
:-), will fix it in next version.

Thanks
-Xie


That might actually be the best option :-)

Berto


.







Re: [Qemu-devel] [RFC] QMP: add query-hotpluggable-cpus

2016-02-23 Thread David Gibson
On Tue, Feb 23, 2016 at 10:46:45AM +0100, Igor Mammedov wrote:
> On Mon, 22 Feb 2016 13:54:32 +1100
> David Gibson  wrote:
> 
> > On Fri, Feb 19, 2016 at 04:49:11PM +0100, Igor Mammedov wrote:
> > > On Fri, 19 Feb 2016 15:38:48 +1100
> > > David Gibson  wrote:
> > > 
> > > CCing thread a couple of libvirt guys.
> > >   
> > > > On Thu, Feb 18, 2016 at 11:37:39AM +0100, Igor Mammedov wrote:  
> > > > > On Thu, 18 Feb 2016 14:39:52 +1100
> > > > > David Gibson  wrote:
> > > > > 
> > > > > > On Tue, Feb 16, 2016 at 11:36:55AM +0100, Igor Mammedov wrote:
> > > > > > > On Mon, 15 Feb 2016 20:43:41 +0100
> > > > > > > Markus Armbruster  wrote:
> > > > > > >   
> > > > > > > > Igor Mammedov  writes:
> > > > > > > >   
> > > > > > > > > it will allow mgmt to query present and possible to hotplug 
> > > > > > > > > CPUs
> > > > > > > > > it is required from a target platform that wish to support
> > > > > > > > > command to set board specific MachineClass.possible_cpus() 
> > > > > > > > > hook,
> > > > > > > > > which will return a list of possible CPUs with options
> > > > > > > > > that would be needed for hotplugging possible CPUs.
> > > > > > > > >
> > > > > > > > > For RFC there are:
> > > > > > > > >'arch_id': 'int' - mandatory unique CPU number,
> > > > > > > > >   for x86 it's APIC ID for ARM it's MPIDR
> > > > > > > > >'type': 'str' - CPU object type for usage with device_add
> > > > > > > > >
> > > > > > > > > and a set of optional fields that would allows mgmt tools
> > > > > > > > > to know at what granularity and where a new CPU could be
> > > > > > > > > hotplugged;
> > > > > > > > > [node],[socket],[core],[thread]
> > > > > > > > > Hopefully that should cover needs for CPU hotplug porposes for
> > > > > > > > > magor targets and we can extend structure in future adding
> > > > > > > > > more fields if it will be needed.
> > > > > > > > >
> > > > > > > > > also for present CPUs there is a 'cpu_link' field which
> > > > > > > > > would allow mgmt inspect whatever object/abstraction
> > > > > > > > > the target platform considers as CPU object.
> > > > > > > > >
> > > > > > > > > For RFC purposes implements only for x86 target so far.   
> > > > > > > > >  
> > > > > > > > 
> > > > > > > > Adding ad hoc queries as we go won't scale.  Could this be 
> > > > > > > > solved by a
> > > > > > > > generic introspection interface?  
> > > > > > > Do you mean generic QOM introspection?
> > > > > > > 
> > > > > > > Using QOM we could have '/cpus' container and create QOM links
> > > > > > > for exiting (populated links) and possible (empty links) CPUs.
> > > > > > > However in that case link's name will need have a special format
> > > > > > > that will convey an information necessary for mgmt to hotplug
> > > > > > > a CPU object, at least:
> > > > > > >   - where: [node],[socket],[core],[thread] options
> > > > > > >   - optionally what CPU object to use with device_add command 
> > > > > > >  
> > > > > > 
> > > > > > Hmm.. is it not enough to follow the link and get the topology
> > > > > > information by examining the target?
> > > > > One can't follow a link if it's an empty one, hence
> > > > > CPU placement information should be provided somehow,
> > > > > either:
> > > > 
> > > > Ah, right, so the issue is determining the socket/core/thread
> > > > addresses that cpus which aren't yet present will have.
> > > >   
> > > > >  * by precreating cpu-package objects with properties that
> > > > >would describe it /could be inspected via OQM/
> > > > 
> > > > So, we could do this, but I think the natural way would be to have the
> > > > information for each potential thread in the package.  Just putting
> > > > say "core number" in the package itself assumes more than I'd like
> > > > about how packages sit in the heirarchy.  Plus, it means that
> > > > management has a bunch of cases to deal with: package has all the
> > > > information, package has just a core id, package has just a socket id,
> > > > and so forth.
> > > > 
> > > > It is a but clunky that when the package is plugged, this information
> > > > will have to sit parallel to the array of actual thread links.
> > > >
> > > > Markus or Andreas is there a natural way to present a list of (node,
> > > > socket, core, thread) tuples in the package object?  Preferably
> > > > without having to create a whole bunch of "potential thread" objects
> > > > just for the purpose.  
> > > I'm sorry but I couldn't parse above 2 paragraphs. The way I see
> > > whatever placement info QEMU will provide to mgmt, mgmt will have
> > > to deal with it in one way or another.
> > > Perhaps rephrasing and adding some examples might help to explain
> > > suggestion a bit better?  
> > 
> > Ok, so what I'm saying is that I think describing a location for the
> > package 

Re: [Qemu-devel] [Qemu-ppc] [PATCH] hw/intc: fix failure return for xics_alloc_block()

2016-02-23 Thread David Gibson
On Tue, Feb 23, 2016 at 06:46:44PM +0100, Greg Kurz wrote:
> On Wed, 10 Feb 2016 10:41:16 +0100
> Greg Kurz  wrote:
> 
> > On Mon, 8 Feb 2016 09:31:49 +0100
> > Greg Kurz  wrote:
> > 
> > > On Mon, 8 Feb 2016 11:45:19 +1000
> > > David Gibson  wrote:
> > >   
> > > > On Fri, Feb 05, 2016 at 09:43:40AM +0100, Greg Kurz wrote:
> > > > > From: Brian W. Hart 
> > > > > 
> > > > > xics_alloc_block() does not return a clear error code when it
> > > > > fails to allocate a block of interrupts. Instead it returns the
> > > > > base interrupt number minus 1. This change updates it to return a
> > > > > clear -1 in case of failure (following the example of xics_alloc()).
> > > > > 
> > > > > The two callers of xics_alloc_block() are updated to check for
> > > > > a negative return as an error. They had previously checked for
> > > > > a 0 return as an error, which wrongly treated most failures as
> > > > > successes.
> > > > > 
> > > > > Fixes: bee763dbfb8cfceea112131970da07f215f293a6
> > > > > Signed-off-by: Brian W. Hart 
> > > > > [only pass src and num to trace_xics_alloc_block_failed_no_left,
> > > > >  added trace_xics_alloc_block_failed_no_left definition to 
> > > > > trace-events]
> > > > > Signed-off-by: Greg Kurz   
> > > > 
> > > > Hrm, it would probably be better to give xics_alloc_block() an Error
> > > > ** argument so it can report errors using the new API.
> > > > 
> > > 
> > > Sure. I can rework the patch to do so.
> > >   
> > 
> > The trace_xics_alloc_block_failed_no_left trace is more a debugging thing
> > than an error to be reported to the user. Also, rtas_ibm_change_msi()
> > already has a meaningful error message:
> > 
> > error_report("Cannot allocate MSIs for device %x", config_addr);
> > 
> > So in the end, I'm not sure about the benefit of passing an Error **
> > down to xics_alloc_block().
> > 
> 
> Hi David !
> 
> Given the remarks above, do you still think we should pass Error ** ?

I still think using the Error API would be preferable, but it doesn't
make a huge difference.

> > > > TBH the whole xics_alloc_block() interface is kind of dubious, or at
> > > > least the ics_find_free_block() part of it.  Dynamically allocating
> > > > irqs to devices is basically awful for migration, so it's better to
> > > > have fixed allocations of all interrupts at the machine level.
> > > > 
> > > 
> > > I agree about the extra complexity, but isn't it the purpose of
> > > the ibm,change-msi RTAS call ? I'm not sure to understand what you
> > > are suggesting...
> > >   
> > 
> > And anyway, even if the decision is made one day to have fixed
> > allocations, shouldn't we consider fixing this bug first ?
> > 
> 
> According to the following commit changelog, the dynamic allocation was
> introduced to support PCI hot(un)plug. Maybe Alexey may explain why it
> got coded this way.
> 
> commit bee763dbfb8cfceea112131970da07f215f293a6
> Author: Alexey Kardashevskiy 
> Date:   Fri May 30 19:34:15 2014 +1000
> 
> spapr: Move interrupt allocator to xics
> 
> I'm not sure of the amount of reflexion and work needed to address your
> concern... Given the time frame, what about deferring xics rework to 2.7
> and fix the bug we currently have in 2.6 ?

Yeah, sorry, I realised after I sent that the allocation does
actually make sense in this case - these are guest triggered
allocations that we really do need an allocator for, not host setup
allocations which we have used in the past but turned out to be
dubious.

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [RFC] QMP: add query-hotpluggable-cpus

2016-02-23 Thread David Gibson
On Tue, Feb 23, 2016 at 06:26:20PM -0300, Eduardo Habkost wrote:
> On Tue, Feb 23, 2016 at 10:46:45AM +0100, Igor Mammedov wrote:
> > On Mon, 22 Feb 2016 13:54:32 +1100
> > David Gibson  wrote:
> [...]
> > > This is why Eduardo suggested - and I agreed - that it's probably
> > > better to implement the "1st layer" as an internal structure/interface
> > > only, and implement the 2nd layer on top of that.  When/if we need to
> > > we can revisit a user-accessible interface to the 1st layer.
> > We are going around QOM based CPU introspecting interface for
> > years now and that's exactly what 2nd layer is, just another
> > implementation. I've just lost hope in this approach.
> > 
> > What I'm suggesting in this RFC is to forget controversial
> > QOM approach for now and use -device/device_add + QMP introspection,
> 
> You have a point about it looking controversial, but I would like
> to understand why exactly it is controversial. Discussions seem
> to get stuck every single time we try to do something useful with
> the QOM tree, and I don't undertsand why.

Yeah, I've noticed that too, and I don't know why either.

It's pretty frustrating, since on power we don't have the option of
sticking with the old cpu hotplug interface for now.  So I really have
no idea how to move things forwards towards a workable approach.

> > i.e. completely split interface from how boards internally implement
> > CPU hotplug.
> 
> A QOM-based interface may still split the interface from how
> boards internally implement CPU hotplug. They don't need to
> affect the device tree of the machine, we just need to create QOM
> objects or links at predictable paths, that implement certain
> interfaces.

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [RFC] QMP: add query-hotpluggable-cpus

2016-02-23 Thread David Gibson
On Mon, Feb 22, 2016 at 10:05:54AM +0100, Markus Armbruster wrote:
> David Gibson  writes:
> 
> > On Fri, Feb 19, 2016 at 10:51:11AM +0100, Markus Armbruster wrote:
> >> David Gibson  writes:
> >> 
> >> > On Thu, Feb 18, 2016 at 11:37:39AM +0100, Igor Mammedov wrote:
> >> >> On Thu, 18 Feb 2016 14:39:52 +1100
> >> >> David Gibson  wrote:
> >> >> 
> >> >> > On Tue, Feb 16, 2016 at 11:36:55AM +0100, Igor Mammedov wrote:
> >> >> > > On Mon, 15 Feb 2016 20:43:41 +0100
> >> >> > > Markus Armbruster  wrote:
> >> >> > >   
> >> >> > > > Igor Mammedov  writes:
> >> >> > > >   
> >> >> > > > > it will allow mgmt to query present and possible to hotplug CPUs
> >> >> > > > > it is required from a target platform that wish to support
> >> >> > > > > command to set board specific MachineClass.possible_cpus() hook,
> >> >> > > > > which will return a list of possible CPUs with options
> >> >> > > > > that would be needed for hotplugging possible CPUs.
> >> >> > > > >
> >> >> > > > > For RFC there are:
> >> >> > > > >'arch_id': 'int' - mandatory unique CPU number,
> >> >> > > > >   for x86 it's APIC ID for ARM it's MPIDR
> >> >> > > > >'type': 'str' - CPU object type for usage with device_add
> >> >> > > > >
> >> >> > > > > and a set of optional fields that would allows mgmt tools
> >> >> > > > > to know at what granularity and where a new CPU could be
> >> >> > > > > hotplugged;
> >> >> > > > > [node],[socket],[core],[thread]
> >> >> > > > > Hopefully that should cover needs for CPU hotplug porposes for
> >> >> > > > > magor targets and we can extend structure in future adding
> >> >> > > > > more fields if it will be needed.
> >> >> > > > >
> >> >> > > > > also for present CPUs there is a 'cpu_link' field which
> >> >> > > > > would allow mgmt inspect whatever object/abstraction
> >> >> > > > > the target platform considers as CPU object.
> >> >> > > > >
> >> >> > > > > For RFC purposes implements only for x86 target so far.
> >> >> > > > 
> >> >> > > > Adding ad hoc queries as we go won't scale.  Could this be solved 
> >> >> > > > by a
> >> >> > > > generic introspection interface?  
> >> >> > > Do you mean generic QOM introspection?
> >> >> > > 
> >> >> > > Using QOM we could have '/cpus' container and create QOM links
> >> >> > > for exiting (populated links) and possible (empty links) CPUs.
> >> >> > > However in that case link's name will need have a special format
> >> >> > > that will convey an information necessary for mgmt to hotplug
> >> >> > > a CPU object, at least:
> >> >> > >   - where: [node],[socket],[core],[thread] options
> >> >> > >   - optionally what CPU object to use with device_add command  
> >> >> > 
> >> >> > Hmm.. is it not enough to follow the link and get the topology
> >> >> > information by examining the target?
> >> >> One can't follow a link if it's an empty one, hence
> >> >> CPU placement information should be provided somehow,
> >> >> either:
> >> >
> >> > Ah, right, so the issue is determining the socket/core/thread
> >> > addresses that cpus which aren't yet present will have.
> >> >
> >> >>  * by precreating cpu-package objects with properties that
> >> >>would describe it /could be inspected via OQM/
> >> >
> >> > So, we could do this, but I think the natural way would be to have the
> >> > information for each potential thread in the package.  Just putting
> >> > say "core number" in the package itself assumes more than I'd like
> >> > about how packages sit in the heirarchy.  Plus, it means that
> >> > management has a bunch of cases to deal with: package has all the
> >> > information, package has just a core id, package has just a socket id,
> >> > and so forth.
> >> >
> >> > It is a but clunky that when the package is plugged, this information
> >> > will have to sit parallel to the array of actual thread links.
> >> >
> >> > Markus or Andreas is there a natural way to present a list of (node,
> >> > socket, core, thread) tuples in the package object?  Preferably
> >> > without having to create a whole bunch of "potential thread" objects
> >> > just for the purpose.
> >> 
> >> I'm just a dabbler when it comes to QOM, but I can try.
> >> 
> >> I view a concrete cpu-package device (subtype of the abstract
> >> cpu-package device) as a composite device containing stuff like actual
> >> cores.
> >
> > So.. the idea is it's a bit more abstract than that.  My intention is
> > that the package lists - in some manner - each of the threads
> > (i.e. vcpus) it contains / can contain.  Depending on the platform it
> > *might* also have internal structure such as cores / sockets, but it
> > doesn't have to.  Either way, the contained threads will be listed in
> > a common way, as a flat array.
> >
> >> To create a composite device, you start with the outer shell, then plug
> >> in components one by one.  Components can be 

Re: [Qemu-devel] CPU hotplug, again

2016-02-23 Thread David Gibson
On Tue, Feb 23, 2016 at 12:18:59PM +0100, Igor Mammedov wrote:
> On Tue, 23 Feb 2016 21:05:04 +1100
> David Gibson  wrote:
> 
> > On Tue, Feb 23, 2016 at 03:10:26PM +0530, Bharata B Rao wrote:
> > > On Tue, Feb 23, 2016 at 04:24:31PM +1100, David Gibson wrote:  
> > > > Hi Andreas,
> > > > 
> > > > I've now found (with Thomas' help) your RFC series for socket/core
> > > > based cpu hotplug on x86
> > > > (https://github.com/afaerber/qemu-cpu/compare/qom-cpu-x86).  It seems
> > > > sensible enough as far as it goes, but doesn't seem to address a bunch
> > > > of the things that I was attempting to do with the cpu-package
> > > > proposal - and which we absolutely need for cpu hotplug on Power.
> > > > 
> > > > 1) What interface do you envisage beyond cpu_add?
> > > > 
> > > > The patches I see just construct extra socket and core objects, but
> > > > still control hotplug (for x86) through the cpu_add interface.  That
> > > > interface is absolutely unusable on Power, since it operates on a
> > > > per-thread basis, whereas the PAPR guest<->host interfaces can only
> > > > communicate information at a per-core granularity.
> > > > 
> > > > 2) When hotplugging at core or socket granularity, where would the
> > > >code to construct the individual thread objects sit?
> > > > 
> > > > Your series has the construction done in both the machine init path
> > > > and the hotplug path.  The latter works because hotplug occurs at
> > > > thread granularity.  If we're hotplugging at core or socket
> > > > granularity what would do the construct?  The core/socket object
> > > > itself (in instance_init?  in realize?); the hotplug handler?
> > > > something else?
> > > > 
> > > > 3) How does the management layer determine what is pluggable?
> > > > 
> > > > Both the number of pluggable slots, and what it will need to do to
> > > > populate them.
> > > > 
> > > > 4) How do we enforce that toplogies illegal for the platform can't be
> > > >constructed?  
> > > 
> > > 5) QOM-links
> > > 
> > > Andreas, You have often talked about setting up links from machine object
> > > to the CPU objects. Would the below code correctly capture that idea of
> > > yours ?
> > > 
> > > #define SPAPR_MACHINE_CPU_CORE_PROP "core"
> > > 
> > > /* MachineClass.init for sPAPR */
> > > static void ppc_spapr_init(MachineState *machine)
> > > {
> > > sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
> > > int spapr_smp_cores = smp_cpus / smp_threads;
> > > int spapr_max_cores = max_cpus / smp_threads;
> > > 
> > > ...
> > > for (i = 0; i < spapr_max_cores; i++) {
> > > Object *obj = object_new(TYPE_SPAPR_CPU_CORE);
> > > sPAPRCPUCore *core = SPAPR_CPU_CORE(obj);
> > > char name[32];
> > > 
> > > snprintf(name, sizeof(name), "%s[%d]", 
> > > SPAPR_MACHINE_CPU_CORE_PROP, i);
> > > 
> > > /*
> > >  * Create links from machine objects to all possible cores.
> > >  */
> > > object_property_add_link(OBJECT(spapr), name, TYPE_SPAPR_CPU_CORE,
> > >  (Object **)>core[i],
> > >  NULL, NULL, _abort); 
> > > 
> > > /*
> > >  * Set the QOM link from machine object to core object for all
> > >  * boot time CPUs specified with -smp. For rest of the 
> > > hotpluggable
> > >  * cores this is done from the core hotplug path.
> > >  */
> > > if (i < spapr_smp_cores) {
> > > object_property_set_link(OBJECT(spapr), OBJECT(core),
> > >  SPAPR_MACHINE_CPU_CORE_PROP, 
> > > _abort);  
> > 
> > I hope we can at least have a helper function to both construct the
> > core and create the links, if we can't handle the link creation in the
> > core object itself.
> > 
> > Having to open-code it in each machine sounds like a recipe for subtle
> > differences in presentation between platforms, which is exactly what
> > we want to avoid.
> Creating links doesn't give us much, it's just adds means for mgmt
> to check how many CPUs could be hotplugged  without keeping that
> state in mgmt like it's now, so links are mostly useless if one
> care where CPU is being plugged in.
> The rest like enumerating exiting CPUs could be done by
> traversing QOM tree, links would just simplify finding
> CPUs putting them at fixed namespace.

Simplifying finding CPUs is pretty much all we intended the links for.
Well, and then I was expecting a different set of links to simplify
enumerating all the threads in a cpu package/core/socket/whatever.

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] Migrating decrementer

2016-02-23 Thread David Gibson
On Tue, Feb 23, 2016 at 09:27:09PM +, Mark Cave-Ayland wrote:
> On 03/02/16 04:59, David Gibson wrote:
> 
> >> Going back to your earlier email you suggested that the host timebase is
> >> always continuously running, even when the guest is paused. But then
> >> resuming the guest then the timebase must jump in the guest regardless?
> >>
> >> If this is the case then this is the big difference between TCG and KVM
> >> guests: TCG timebase is derived from the virtual clock which solves the
> >> problem of paused guests during migration. For example with the existing
> >> migration code, what would happen if you did a migration with the guest
> >> paused on KVM? The offset would surely be wrong as it was calculated at
> >> the end of migration.
> > 
> > So there are two different cases to consider here.  Once is when the
> > guest is paused incidentally, such as during migration, the other is
> > when the guest is explicitly paused.
> > 
> > In the first case the timebase absolutely should keep running (or
> > appear to do so), since it's the primary source of real time for the
> > guest.
> 
> I'm not sure I understand this, since if the guest is paused either
> deliberately or incidentally during migration then isn't the timebase
> also frozen? Or is it external to the CPU?

I don't really understand the question.  Migration has no equivalent
in real hardware, so there's no "real" behaviour to mimic.  If we
freeze the TB during migration, then the guest's clock will get out of
sync with wall clock time, and in a production environment that's
really bad.  So no, we absolutely must not freeze the TB during
migration.

When the guest has been explicitly paused, there's a case to be made
either way.

> > In the second case, it's a bit unclear what the right thing to do is.
> > Keeping the tb running means accurate realtime, but stopping it is
> > often better for debugging, which is one of the main reasons to
> > explicitly pause.
> > 
> > I believe spapr on KVM HV will keep the TB going, but the TSC on x86
> > will be stopped.
> 
> Is this from a guest-centric view, i.e. if I pause a VM and wait 20 mins
> then when the guest resumes the timebase will jump forward by 20 mins
> worth of ticks?

Yes, that's correct.

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH] topology.h: cleanup

2016-02-23 Thread Cao jin



On 02/24/2016 05:16 AM, Eduardo Habkost wrote:

On Tue, Feb 23, 2016 at 02:51:11PM +0800, Cao jin wrote:

remove useless parameter of several functions

Signed-off-by: Cao jin 


I believe this makes the API much easier to be misused. Currently
you can safely use (smp_cores, smp_threads) every time. With this
patch, you need to always check the function definition to find
out what's the correct argument.



Yes, you do have a point here, and very interesting to me. A caller need 
to know/check how to use a api if it want to use it, seems a nature 
thing to me.


Thanks for your explanation.

--
Yours Sincerely,

Cao jin





Re: [Qemu-devel] [Bug 1548170] [NEW] qemu-kvm-spice spice server locks up when large user image is set

2016-02-23 Thread Christopher Snowhill
This does not appear to happen with 2.5, which I finally got installed
through a full distribution upgrade to the latest beta of the upcoming
LTS release. Of course, now I have another issue I didn’t notice before,
where the Windows VM, which idles at about 20% of a single core most of
the time, ends up using 80-100% of a single core on the host machine in
the qemu-system-x86_64 process, but that’s probably what it was already
doing before.

> On Feb 22, 2016, at 5:31 PM, Fam Zheng  wrote:
> 
> On Mon, 02/22 04:06, Christopher Snowhill wrote:
>> Public bug reported:
>> 
>> QEMU emulator version 2.0.0 (Debian 2.0.0+dfsg-2ubuntu1.22), Copyright
>> (c) 2003-2008 Fabrice Bellard
>> 
>> I have QEMU kvm spice installed, running a Windows 10 1511, freshly
>> installed this morning, using VirtIO root volume, Ethernet, and QXL
>> graphics through Spice. It successfully installed the latest updates,
>> and installed Visual Studio 2010 Professional plus Service Pack 1 and
>> updates.
>> 
>> Upon attempting to configure the following PNG as my account's user
>> picture in the Settings control panel applet:
>> 
>> https://static.kode54.net/pwywcomm_christopher_8bpp.png
>> 
>> It added successfully, but then I noticed that Windows does not support
>> alpha blended user pictures, and it blended it against white, so I
>> quickly replaced it with the following:
>> 
>> https://static.kode54.net/pwywcomm_christopher_blended.png
>> 
>> Upon assigning that, with the other one still in the previous image
>> buttons, Spice locked up completely. The VM was still running, as
>> evidenced by a successful Remote Desktop session.
>> 
>> Do I need to replace my entire Qemu setup with a Git or hand built
>> official version to verify that this isn't Ubuntu's fault?
> 
> I know next to nothing about graphic in QEMU but yes, it's worth to check the
> lastest release (2.5) or even better the current git master.
> 
> Fam
> 
> -- 
> You received this bug notification because you are subscribed to the bug
> report.
> https://bugs.launchpad.net/bugs/1548170
> 
> Title:
>  qemu-kvm-spice spice server locks up when large user image is set
> 
> Status in QEMU:
>  New
> 
> Bug description:
>  QEMU emulator version 2.0.0 (Debian 2.0.0+dfsg-2ubuntu1.22), Copyright
>  (c) 2003-2008 Fabrice Bellard
> 
>  I have QEMU kvm spice installed, running a Windows 10 1511, freshly
>  installed this morning, using VirtIO root volume, Ethernet, and QXL
>  graphics through Spice. It successfully installed the latest updates,
>  and installed Visual Studio 2010 Professional plus Service Pack 1 and
>  updates.
> 
>  Upon attempting to configure the following PNG as my account's user
>  picture in the Settings control panel applet:
> 
>  https://static.kode54.net/pwywcomm_christopher_8bpp.png
> 
>  It added successfully, but then I noticed that Windows does not
>  support alpha blended user pictures, and it blended it against white,
>  so I quickly replaced it with the following:
> 
>  https://static.kode54.net/pwywcomm_christopher_blended.png
> 
>  Upon assigning that, with the other one still in the previous image
>  buttons, Spice locked up completely. The VM was still running, as
>  evidenced by a successful Remote Desktop session.
> 
>  Do I need to replace my entire Qemu setup with a Git or hand built
>  official version to verify that this isn't Ubuntu's fault?
> 
> To manage notifications about this bug go to:
> https://bugs.launchpad.net/qemu/+bug/1548170/+subscriptions

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

Title:
  qemu-kvm-spice spice server locks up when large user image is set

Status in QEMU:
  New

Bug description:
  QEMU emulator version 2.0.0 (Debian 2.0.0+dfsg-2ubuntu1.22), Copyright
  (c) 2003-2008 Fabrice Bellard

  I have QEMU kvm spice installed, running a Windows 10 1511, freshly
  installed this morning, using VirtIO root volume, Ethernet, and QXL
  graphics through Spice. It successfully installed the latest updates,
  and installed Visual Studio 2010 Professional plus Service Pack 1 and
  updates.

  Upon attempting to configure the following PNG as my account's user
  picture in the Settings control panel applet:

  https://static.kode54.net/pwywcomm_christopher_8bpp.png

  It added successfully, but then I noticed that Windows does not
  support alpha blended user pictures, and it blended it against white,
  so I quickly replaced it with the following:

  https://static.kode54.net/pwywcomm_christopher_blended.png

  Upon assigning that, with the other one still in the previous image
  buttons, Spice locked up completely. The VM was still running, as
  evidenced by a successful Remote Desktop session.

  Do I need to replace my entire Qemu setup with a Git or hand built
  official version to verify that this isn't Ubuntu's fault?

To manage notifications about this bug go to:

Re: [Qemu-devel] [PATCH RESEND v2 1/2] qemu-file: Fix qemu_put_compression_data flaw

2016-02-23 Thread Li, Liang Z


On %D, %SN wrote:
%Q

%C

Liang


> -Original Message-
> From: qemu-devel-bounces+liang.z.li=intel@nongnu.org [mailto:qemu-
> devel-bounces+liang.z.li=intel@nongnu.org] On Behalf Of Juan Quintela
> Sent: Tuesday, February 23, 2016 5:57 PM
> To: Li, Liang Z
> Cc: amit.s...@redhat.com; zhang.zhanghaili...@huawei.com; qemu-
> de...@nongnu.org; dgilb...@redhat.com
> Subject: Re: [Qemu-devel] [PATCH RESEND v2 1/2] qemu-file: Fix
> qemu_put_compression_data flaw
> 
> "Li, Liang Z"  wrote:
> > Ping ...
> >
> > Liang
> 
> Hi
> 
> >> We should fix this flaw to make it works with writable QEMUFile.
> >>
> >> Signed-off-by: Liang Li 
> >> ---
> >>  migration/qemu-file.c | 23 +--
> >>  1 file changed, 21 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/migration/qemu-file.c b/migration/qemu-file.c index
> >> 0bbd257..b956ab6 100644
> >> --- a/migration/qemu-file.c
> >> +++ b/migration/qemu-file.c
> >> @@ -606,8 +606,14 @@ uint64_t qemu_get_be64(QEMUFile *f)
> >>  return v;
> >>  }
> >>
> >> -/* compress size bytes of data start at p with specific compression
> >> +/* Compress size bytes of data start at p with specific compression
> >>   * level and store the compressed data to the buffer of f.
> >> + *
> >> + * When f is not writable, return 0 if f has no space to save the
> >> + * compressed data.
> >> + * When f is wirtable and it has no space to save the compressed
> >> + data,
> >> + * do fflush first, if f still has no space to save the compressed
> >> + * data, return 0.
> >>   */
> 
> Ok, I still don't understand _why_ f can be writable on compression code, but
> well.
> 
> We return r when we are not able to write, right?
> static int do_compress_ram_page(CompressParam *param) {
> int bytes_sent, blen;
> uint8_t *p;
> RAMBlock *block = param->block;
> ram_addr_t offset = param->offset;
> 
> p = block->host + (offset & TARGET_PAGE_MASK);
> 
> bytes_sent = save_page_header(param->file, block, offset |
>   RAM_SAVE_FLAG_COMPRESS_PAGE);
> blen = qemu_put_compression_data(param->file, p, TARGET_PAGE_SIZE,
>  migrate_compress_level());
> bytes_sent += blen;
> 
> return bytes_sent;
> }
> 
> But we don't check for zero when doing the compression, shouldn't this give
> give an error?
> 
> (yes, caller of do_co_compress_ram_page() don't check for zero either).
> 

> I guess you are trying to do something different with the compression code
> (otherwise this qemu_fflush() or add_to_iovec() don't make sense), but I
> don't know what.
> 
> With current code, the only thing that we miss is the check for errors, right?
> And if we want to do something else with it, could you explain? Thanks.
> 
> Later, Juan.

I think these two threads will help to explain why I do that.

https://lists.gnu.org/archive/html/qemu-devel/2016-01/msg02675.html

https://lists.gnu.org/archive/html/qemu-devel/2016-01/msg02674.html

I just want to refine the code in the function ram_save_compressed_page(),
so as to reduce some data copy. 
In the other hand, qemu_put_compression_data() is a common function, it maybe
used by other code, but it's current implementation has some limitation, we 
should
make it robust.

Liang




Re: [Qemu-devel] [RFC PATCH v2 08/10] net/colo-proxy: Handle packet and connection

2016-02-23 Thread Zhang Chen



On 02/24/2016 01:58 AM, Dr. David Alan Gilbert wrote:

* Zhang Chen (zhangchen.f...@cn.fujitsu.com) wrote:


On 02/20/2016 04:04 AM, Dr. David Alan Gilbert wrote:

* Zhang Chen (zhangchen.f...@cn.fujitsu.com) wrote:

From: zhangchen 

In here we will handle ip packet and connection

Signed-off-by: zhangchen 
Signed-off-by: zhanghailiang 
---
  net/colo-proxy.c | 130 +++
  1 file changed, 130 insertions(+)

diff --git a/net/colo-proxy.c b/net/colo-proxy.c
index 5e5c72e..06bab80 100644
--- a/net/colo-proxy.c
+++ b/net/colo-proxy.c
@@ -167,11 +167,141 @@ static int connection_key_equal(const void *opaque1, 
const void *opaque2)
  return memcmp(opaque1, opaque2, sizeof(ConnectionKey)) == 0;
  }
+static void connection_destroy(void *opaque)
+{
+Connection *conn = opaque;
+
+g_queue_foreach(>primary_list, packet_destroy, NULL);
+g_queue_free(>primary_list);
+g_queue_foreach(>secondary_list, packet_destroy, NULL);

Be careful about these lists and which threads access them;
I found I could occasionally trigger a seg fault as two
threads tried to manipulate them at once; I just put a 'list_lock'
in the connection, which seems to fix it, but I might have to be
more careful with deadlocks.

Thanks for your work to colo.
and where can I  see your code for colo-proxy?
maybe I need it to make my code better.

Here is my latest version; it seems to just about work; but very
much still working on it:

https://github.com/orbitfp7/qemu/tree/orbit-wp4-colo-jan16
  with the wp4-colo-rdma-2016-02-23 tag.

Dave


Thanks for your work to colo~~
zhangchen


+g_queue_free(>secondary_list);
+g_slice_free(Connection, conn);
+}
+
+static Connection *connection_new(ConnectionKey *key)
+{
+Connection *conn = g_slice_new(Connection);
+
+conn->ip_proto = key->ip_proto;
+conn->processing = false;
+g_queue_init(>primary_list);
+g_queue_init(>secondary_list);
+
+return conn;
+}
+
+/*
+ * Clear hashtable, stop this hash growing really huge
+ */
+static void clear_connection_hashtable(COLOProxyState *s)
+{
+s->hashtable_size = 0;
+g_hash_table_remove_all(colo_conn_hash);
+trace_colo_proxy("clear_connection_hashtable");
+}
+
  bool colo_proxy_query_checkpoint(void)
  {
  return colo_do_checkpoint;
  }
+/* Return 0 on success, or return -1 if the pkt is corrupted */
+static int parse_packet_early(Packet *pkt, ConnectionKey *key)
+{
+int network_length;
+uint8_t *data = pkt->data;
+uint16_t l3_proto;
+uint32_t tmp_ports;
+ssize_t l2hdr_len = eth_get_l2_hdr_length(data);
+
+pkt->network_layer = data + ETH_HLEN;
+l3_proto = eth_get_l3_proto(data, l2hdr_len);
+if (l3_proto != ETH_P_IP) {
+if (l3_proto == ETH_P_ARP) {
+return -1;
+}
+return 0;
+}
+
+network_length = pkt->ip->ip_hl * 4;
+pkt->transport_layer = pkt->network_layer + network_length;
+key->ip_proto = pkt->ip->ip_p;
+key->src = pkt->ip->ip_src;
+key->dst = pkt->ip->ip_dst;
+
+switch (key->ip_proto) {
+case IPPROTO_TCP:
+case IPPROTO_UDP:
+case IPPROTO_DCCP:
+case IPPROTO_ESP:
+case IPPROTO_SCTP:
+case IPPROTO_UDPLITE:
+tmp_ports = *(uint32_t *)(pkt->transport_layer);
+key->src_port = tmp_ports & 0x;
+key->dst_port = tmp_ports >> 16;

These fields are not byteswapped; it makes it very confusing
when printing them for debug;  I added htons around every
reading of the ports from the packets.

Dave

I will fix it in colo-compare module.

Thanks
zhangchen


+break;
+case IPPROTO_AH:
+tmp_ports = *(uint32_t *)(pkt->transport_layer + 4);
+key->src_port = tmp_ports & 0x;
+key->dst_port = tmp_ports >> 16;
+break;
+default:
+break;
+}
+
+return 0;
+}
+
+static Packet *packet_new(COLOProxyState *s, void *data,
+  int size, ConnectionKey *key, NetClientState *sender)
+{
+Packet *pkt = g_slice_new(Packet);
+
+pkt->data = data;
+pkt->size = size;
+pkt->s = s;
+pkt->sender = sender;
+
+if (parse_packet_early(pkt, key)) {
+packet_destroy(pkt, NULL);
+pkt = NULL;
+}
+
+return pkt;
+}
+
+static void packet_destroy(void *opaque, void *user_data)
+{
+Packet *pkt = opaque;
+g_free(pkt->data);
+g_slice_free(Packet, pkt);
+}
+
+/* if not found, creata a new connection and add to hash table */
+static Connection *colo_proxy_get_conn(COLOProxyState *s,
+ConnectionKey *key)
+{
+/* FIXME: protect colo_conn_hash */
+Connection *conn = g_hash_table_lookup(colo_conn_hash, key);
+
+if (conn == NULL) {
+ConnectionKey *new_key = g_malloc(sizeof(*key));
+
+conn = connection_new(key);
+memcpy(new_key, key, sizeof(*key));
+
+s->hashtable_size++;
+

Re: [Qemu-devel] [PATCH] net: ne2000: check ring buffer control registers

2016-02-23 Thread Jason Wang


On 02/23/2016 04:28 PM, P J P wrote:
>Hello Jason,
>
> +-- On Tue, 23 Feb 2016, Jason Wang wrote --+
> | I mean with your patch, driver will only be allowed to set EN0_STOPPG
> | before EN0_STARTPG. So if a driver want to set STARTPG first, the check
> | 
> | +if (v < NE2000_PMEM_END && v < s->stop) {
> | 
> | will prevent the driver from working correctly since s->stop is zero here.
>
>   Before drivers could start using NIC, it'll be initialised from its ROM, 
> right? Which would set the PSTART & PSTOP registers to the default values. 
> With '-net nic,model=ne2k_pci,vlan=0' I see,
>
> s->start = 19456, s->stop = 32768

So in this case, if a driver want to do the following things:

1) set s->stop to 16384
2) set s->start to 8192

Then it won't work.

>
> | >   I think any attempts to define the ring buffer limits should reset 
> | > 'boundary' and 'curpag' registers to s->start(STARTPG). I wonder if a 
> | > driver should be allowed to fiddle with the ring buffers location inside 
> | > contorller's memory. It does not seem right.
> | 
> | Well, I think we could not assume the behavior of a driver, especially
> | consider it may be malicious.
>
>   Yes; That's why it'll help to keep drivers from fiddling with the ring 
> buffer dimensions. 

Right, but since setting STARTPG,STOPPG,BOUNDARY and CURPAG is not
atomic. Try to limit it during value setting is hard to be correct.

> IIUC, there is an upper limit to where PSTOP could 
> point[1],
>
>   "In 8 bit mode the PSTOP register should not exceed to 0x60,
> in 16 bit mode the PSTOP register should not exceed to 0x80"
>
> [1] http://www.ethernut.de/pdf/8019asds.pdf
>
> Kernel drivers too seem to have it fixed
>   -> 
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/8390/ne.c#n398
>   -> 
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/8390/ne2k-pci.c#n342
>
> | >   Check if (s->start == s->stop) at each receive call?
> | Or in ne2000_buffer_full()?
>
>   ne2000_buffer_full() too assumes that 's->stop > s->start'
>
> ...
> avail = (s->stop - s->start) - (index - boundary);

Then let's return true when s->stop <= s->start?

> Is there a case wherein drivers need to adjust ring buffer pointers? If not, 
> I 
> think it's better to convert EN0_STARTPG:, EN0_STOPPG:, EN0_BOUNDARY: and 
> EN1_CURPAG: cases into no-ops.

It's really hard to say there's no such driver. Which means if there's
such a driver and it works on real hardware, we need make it work for qemu.

>
> --
>  - P J P
> 47AF CE69 3A90 54AA 9045 1053 DD13 3D32 FE5B 041F
>




[Qemu-devel] [PATCH 2/3] target-ppc: Use 32-bit rotate instead of deposit + 64-bit rotate

2016-02-23 Thread Richard Henderson
A 32-bit rotate insn is more common on hosts than a deposit insn,
and if the host has neither the result is truely horrific.

At the same time, tidy up the temporaries within these functions,
drop the over-use of "likely", drop some checks for identity that
will also be checked by tcg-op.c functions, and special case mask
without rotate within rlwinm.

Signed-off-by: Richard Henderson 
---
 target-ppc/translate.c | 172 -
 1 file changed, 70 insertions(+), 102 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 00c9a5a..b575609 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -1609,141 +1609,109 @@ static void gen_cntlzd(DisasContext *ctx)
 /* rlwimi & rlwimi. */
 static void gen_rlwimi(DisasContext *ctx)
 {
-uint32_t mb, me, sh;
-
-mb = MB(ctx->opcode);
-me = ME(ctx->opcode);
-sh = SH(ctx->opcode);
-if (likely(sh == (31-me) && mb <= me)) {
-tcg_gen_deposit_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
-   cpu_gpr[rS(ctx->opcode)], sh, me - mb + 1);
+TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
+TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
+uint32_t sh = SH(ctx->opcode);
+uint32_t mb = MB(ctx->opcode);
+uint32_t me = ME(ctx->opcode);
+
+if (sh == (31-me) && mb <= me) {
+tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
 } else {
 target_ulong mask;
+TCGv_i32 t0;
 TCGv t1;
-TCGv t0 = tcg_temp_new();
-#if defined(TARGET_PPC64)
-tcg_gen_deposit_i64(t0, cpu_gpr[rS(ctx->opcode)],
-cpu_gpr[rS(ctx->opcode)], 32, 32);
-tcg_gen_rotli_i64(t0, t0, sh);
-#else
-tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
-#endif
+
 #if defined(TARGET_PPC64)
 mb += 32;
 me += 32;
 #endif
 mask = MASK(mb, me);
+
+t0 = tcg_temp_new_i32();
 t1 = tcg_temp_new();
-tcg_gen_andi_tl(t0, t0, mask);
-tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
-tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
-tcg_temp_free(t0);
+tcg_gen_trunc_tl_i32(t0, t_rs);
+tcg_gen_rotli_i32(t0, t0, sh);
+tcg_gen_extu_i32_tl(t1, t0);
+tcg_temp_free_i32(t0);
+
+tcg_gen_andi_tl(t1, t1, mask);
+tcg_gen_andi_tl(t_ra, t_ra, ~mask);
+tcg_gen_or_tl(t_ra, t_ra, t1);
 tcg_temp_free(t1);
 }
-if (unlikely(Rc(ctx->opcode) != 0))
-gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
+if (unlikely(Rc(ctx->opcode) != 0)) {
+gen_set_Rc0(ctx, t_ra);
+}
 }
 
 /* rlwinm & rlwinm. */
 static void gen_rlwinm(DisasContext *ctx)
 {
-uint32_t mb, me, sh;
-
-sh = SH(ctx->opcode);
-mb = MB(ctx->opcode);
-me = ME(ctx->opcode);
+TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
+TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
+uint32_t sh = SH(ctx->opcode);
+uint32_t mb = MB(ctx->opcode);
+uint32_t me = ME(ctx->opcode);
 
-if (likely(mb == 0 && me == (31 - sh))) {
-if (likely(sh == 0)) {
-tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], 
cpu_gpr[rS(ctx->opcode)]);
-} else {
-TCGv t0 = tcg_temp_new();
-tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
-tcg_gen_shli_tl(t0, t0, sh);
-tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
-tcg_temp_free(t0);
-}
-} else if (likely(sh != 0 && me == 31 && sh == (32 - mb))) {
-TCGv t0 = tcg_temp_new();
-tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
-tcg_gen_shri_tl(t0, t0, mb);
-tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
-tcg_temp_free(t0);
-} else if (likely(mb == 0 && me == 31)) {
-TCGv_i32 t0 = tcg_temp_new_i32();
-tcg_gen_trunc_tl_i32(t0, cpu_gpr[rS(ctx->opcode)]);
-tcg_gen_rotli_i32(t0, t0, sh);
-tcg_gen_extu_i32_tl(cpu_gpr[rA(ctx->opcode)], t0);
-tcg_temp_free_i32(t0);
+if (mb == 0 && me == (31 - sh)) {
+tcg_gen_shli_tl(t_ra, t_rs, sh);
+tcg_gen_ext32u_tl(t_ra, t_ra);
+} else if (sh != 0 && me == 31 && sh == (32 - mb)) {
+tcg_gen_ext32u_tl(t_ra, t_rs);
+tcg_gen_shri_tl(t_ra, t_ra, mb);
 } else {
-TCGv t0 = tcg_temp_new();
-#if defined(TARGET_PPC64)
-tcg_gen_deposit_i64(t0, cpu_gpr[rS(ctx->opcode)],
-cpu_gpr[rS(ctx->opcode)], 32, 32);
-tcg_gen_rotli_i64(t0, t0, sh);
-#else
-tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
-#endif
 #if defined(TARGET_PPC64)
 mb += 32;
 me += 32;
 #endif
-tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
-tcg_temp_free(t0);
+if (sh == 0) {
+tcg_gen_andi_tl(t_ra, t_rs, MASK(mb, me));
+} else {
+TCGv_i32 t0 = tcg_temp_new_i32();
+
+tcg_gen_trunc_tl_i32(t0, t_rs);
+tcg_gen_rotli_i32(t0, t0, sh);

[Qemu-devel] [PATCH 3/3] target-ppc: Cleanups to rldinm, rldnm, rldimi

2016-02-23 Thread Richard Henderson
Mirror the cleanups just done to rlwinm, rlwnm and rlwimi.
This adds use of deposit to rldimi.

Signed-off-by: Richard Henderson 
---
 target-ppc/translate.c | 91 +-
 1 file changed, 46 insertions(+), 45 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index b575609..72c1648 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -1746,26 +1746,24 @@ static void glue(gen_, name##3)(DisasContext *ctx)  
  \
 gen_##name(ctx, 1, 1);\
 }
 
-static inline void gen_rldinm(DisasContext *ctx, uint32_t mb, uint32_t me,
-  uint32_t sh)
+static void gen_rldinm(DisasContext *ctx, int mb, int me, int sh)
 {
-if (likely(sh != 0 && mb == 0 && me == (63 - sh))) {
-tcg_gen_shli_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 
sh);
-} else if (likely(sh != 0 && me == 63 && sh == (64 - mb))) {
-tcg_gen_shri_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 
mb);
+TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
+TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
+
+if (sh != 0 && mb == 0 && me == (63 - sh)) {
+tcg_gen_shli_tl(t_ra, t_rs, sh);
+} else if (sh != 0 && me == 63 && sh == (64 - mb)) {
+tcg_gen_shri_tl(t_ra, t_rs, mb);
 } else {
-TCGv t0 = tcg_temp_new();
-tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
-if (likely(mb == 0 && me == 63)) {
-tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
-} else {
-tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
-}
-tcg_temp_free(t0);
+tcg_gen_rotli_tl(t_ra, t_rs, sh);
+tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me));
+}
+if (unlikely(Rc(ctx->opcode) != 0)) {
+gen_set_Rc0(ctx, t_ra);
 }
-if (unlikely(Rc(ctx->opcode) != 0))
-gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
+
 /* rldicl - rldicl. */
 static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn)
 {
@@ -1776,6 +1774,7 @@ static inline void gen_rldicl(DisasContext *ctx, int mbn, 
int shn)
 gen_rldinm(ctx, mb, 63, sh);
 }
 GEN_PPC64_R4(rldicl, 0x1E, 0x00);
+
 /* rldicr - rldicr. */
 static inline void gen_rldicr(DisasContext *ctx, int men, int shn)
 {
@@ -1786,6 +1785,7 @@ static inline void gen_rldicr(DisasContext *ctx, int men, 
int shn)
 gen_rldinm(ctx, 0, me, sh);
 }
 GEN_PPC64_R4(rldicr, 0x1E, 0x02);
+
 /* rldic - rldic. */
 static inline void gen_rldic(DisasContext *ctx, int mbn, int shn)
 {
@@ -1797,21 +1797,22 @@ static inline void gen_rldic(DisasContext *ctx, int 
mbn, int shn)
 }
 GEN_PPC64_R4(rldic, 0x1E, 0x04);
 
-static inline void gen_rldnm(DisasContext *ctx, uint32_t mb, uint32_t me)
+static void gen_rldnm(DisasContext *ctx, int mb, int me)
 {
+TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
+TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
+TCGv t_rb = cpu_gpr[rB(ctx->opcode)];
 TCGv t0;
 
 t0 = tcg_temp_new();
-tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
-tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
-if (unlikely(mb != 0 || me != 63)) {
-tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
-} else {
-tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
-}
+tcg_gen_andi_tl(t0, t_rb, 0x3f);
+tcg_gen_rotl_tl(t_ra, t_rs, t0);
 tcg_temp_free(t0);
-if (unlikely(Rc(ctx->opcode) != 0))
-gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
+
+tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me));
+if (unlikely(Rc(ctx->opcode) != 0)) {
+gen_set_Rc0(ctx, t_ra);
+}
 }
 
 /* rldcl - rldcl. */
@@ -1823,6 +1824,7 @@ static inline void gen_rldcl(DisasContext *ctx, int mbn)
 gen_rldnm(ctx, mb, 63);
 }
 GEN_PPC64_R2(rldcl, 0x1E, 0x08);
+
 /* rldcr - rldcr. */
 static inline void gen_rldcr(DisasContext *ctx, int men)
 {
@@ -1832,32 +1834,31 @@ static inline void gen_rldcr(DisasContext *ctx, int men)
 gen_rldnm(ctx, 0, me);
 }
 GEN_PPC64_R2(rldcr, 0x1E, 0x09);
+
 /* rldimi - rldimi. */
-static inline void gen_rldimi(DisasContext *ctx, int mbn, int shn)
+static void gen_rldimi(DisasContext *ctx, int mbn, int shn)
 {
-uint32_t sh, mb, me;
+TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
+TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
+uint32_t sh = SH(ctx->opcode) | (shn << 5);
+uint32_t mb = MB(ctx->opcode) | (mbn << 5);
+uint32_t me = 63 - sh;
 
-sh = SH(ctx->opcode) | (shn << 5);
-mb = MB(ctx->opcode) | (mbn << 5);
-me = 63 - sh;
-if (unlikely(sh == 0 && mb == 0)) {
-tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+if (mb <= me) {
+tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
 } else {
-TCGv t0, t1;
-target_ulong mask;
+target_ulong mask = MASK(mb, me);
+TCGv t1 = tcg_temp_new();
 
-t0 = tcg_temp_new();
-tcg_gen_rotli_tl(t0, 

[Qemu-devel] [PATCH 0/3] target-ppc improvements

2016-02-23 Thread Richard Henderson
The ISEL patch was posted last year; I don't believe I ever
got around to posting these other two.


r~


Richard Henderson (3):
  target-ppc: Use movcond in isel
  target-ppc: Use 32-bit rotate instead of deposit + 64-bit rotate
  target-ppc: Cleanups to rldinm, rldnm, rldimi

 target-ppc/translate.c | 290 +
 1 file changed, 126 insertions(+), 164 deletions(-)

-- 
2.5.0




[Qemu-devel] [PATCH 1/3] target-ppc: Use movcond in isel

2016-02-23 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-ppc/translate.c | 29 +++--
 1 file changed, 11 insertions(+), 18 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index ecc85f0..00c9a5a 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -755,27 +755,20 @@ static void gen_cmpli(DisasContext *ctx)
 /* isel (PowerPC 2.03 specification) */
 static void gen_isel(DisasContext *ctx)
 {
-TCGLabel *l1, *l2;
 uint32_t bi = rC(ctx->opcode);
-uint32_t mask;
-TCGv_i32 t0;
+uint32_t mask = 0x08 >> (bi & 0x03);
+TCGv t0 = tcg_temp_new();
+TCGv zr;
 
-l1 = gen_new_label();
-l2 = gen_new_label();
+tcg_gen_extu_i32_tl(t0, cpu_crf[bi >> 2]);
+tcg_gen_andi_tl(t0, t0, mask);
 
-mask = 0x08 >> (bi & 0x03);
-t0 = tcg_temp_new_i32();
-tcg_gen_andi_i32(t0, cpu_crf[bi >> 2], mask);
-tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
-if (rA(ctx->opcode) == 0)
-tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
-else
-tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-tcg_gen_br(l2);
-gen_set_label(l1);
-tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
-gen_set_label(l2);
-tcg_temp_free_i32(t0);
+zr = tcg_const_tl(0);
+tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rD(ctx->opcode)], t0, zr,
+   rA(ctx->opcode) ? cpu_gpr[rA(ctx->opcode)] : zr,
+   cpu_gpr[rB(ctx->opcode)]);
+tcg_temp_free(zr);
+tcg_temp_free(t0);
 }
 
 /* cmpb: PowerPC 2.05 specification */
-- 
2.5.0




Re: [Qemu-devel] [PATCH v3 2/3] block/backup: avoid copying less than full target clusters

2016-02-23 Thread John Snow


On 02/23/2016 07:45 PM, Eric Blake wrote:
> On 02/23/2016 05:27 PM, Fam Zheng wrote:
>> On Tue, 02/23 19:17, John Snow wrote:
>>> During incremental backups, if the target has a cluster size that is
>>> larger than the backup cluster size and we are backing up to a target
>>> that cannot (for whichever reason) pull clusters up from a backing image,
>>> we may inadvertantly create unusable incremental backup images.
>>>
> 
>>> +/* If there is no backing file on the target, we cannot rely on COW if 
>>> our
>>> + * backup cluster size is smaller than the target cluster size. Even 
>>> for
>>> + * targets with a backing file, try to avoid COW if possible. */
>>> +ret = bdrv_get_info(job->target, );
>>> +if (ret < 0 && !target->backing) {
>>> +error_setg_errno(errp, -ret,
>>> +"Can't determine cluster size of target that has no backing 
>>> file. "
>>> +"This may create an unusable destination image. Aborting.");
>>
>> Most error messages don't end with a period, but that's not a hard rule 
>> AFAICT.
> 
> Ah, but it is:
> 
> include/qapi/error.h:
> 
>  * The resulting message should be a single phrase, with no newline or
>  * trailing punctuation.
>  * Please don't error_setg(_fatal, ...), use error_report() and
>  * exit(), because that's more obvious.
>  * Likewise, don't error_setg(_abort, ...), use assert().
>  */
> #define error_setg(errp, fmt, ...)  \
> 

":(.\n"

> The error message should be "Can't determine cluster size of target
> without backing file"; everything else should be done with
> error_append_hint(, "Aborting, since this may create an unusable
> destination image\n")
> 
> 

Tch. I decided I don't like this message anyway.

"Couldn't determine the cluster size of the target image, which has no
backing file" is more correct. The problem is not why we couldn't
determine it, but instead that we were unable to AND there is no backing
file, so our inability to determine it is a problem.

What's our policy on error message strings that eclipse 80 columns? I
was told once (at gunpoint; I live in the USA) to never split up long
strings because it makes them harder to grep for.



[Qemu-devel] [PATCH 4/4] block/vpc: add tests for image creation force_size parameter

2016-02-23 Thread Jeff Cody
Signed-off-by: Jeff Cody 
---
 tests/qemu-iotests/146 | 81 ++
 tests/qemu-iotests/146.out | 44 +
 2 files changed, 125 insertions(+)

diff --git a/tests/qemu-iotests/146 b/tests/qemu-iotests/146
index af60849..323ea8a 100755
--- a/tests/qemu-iotests/146
+++ b/tests/qemu-iotests/146
@@ -113,6 +113,87 @@ _send_qemu_cmd $h1 'qemu-io disk "map"' "sectors"
 _send_qemu_cmd $h1 'quit' ""
 
 
+_cleanup_test_img
+
+echo
+echo === Testing Image create, default ===
+echo
+
+TEST_IMG="${TEST_DIR}/vpc-create-test.vpc"
+
+_make_test_img 4G
+
+echo
+echo === Read created image, default opts 
+echo
+
+_launch_qemu -drive file="${TEST_IMG}",id=disk,format=vpc
+h1=$QEMU_HANDLE
+
+_send_qemu_cmd $h1 'qemu-io disk "map"' "sectors"
+_send_qemu_cmd $h1 'quit' ""
+
+echo
+echo === Read created image, force_size_calc=chs 
+echo
+
+_launch_qemu -drive file="${TEST_IMG}",id=disk,format=vpc,force_size_calc=chs
+h1=$QEMU_HANDLE
+
+_send_qemu_cmd $h1 'qemu-io disk "map"' "sectors"
+_send_qemu_cmd $h1 'quit' ""
+
+
+echo
+echo === Read created image, force_size_calc=current_size 
+echo
+
+_launch_qemu -drive 
file="${TEST_IMG}",id=disk,format=vpc,force_size_calc=current_size
+h1=$QEMU_HANDLE
+
+_send_qemu_cmd $h1 'qemu-io disk "map"' "sectors"
+_send_qemu_cmd $h1 'quit' ""
+
+
+echo
+echo === Testing Image create, force_size ===
+echo
+
+_make_test_img -o force_size 4G
+
+
+echo
+echo === Read created image, default opts 
+echo
+
+_launch_qemu -drive file="${TEST_IMG}",id=disk,format=vpc
+h1=$QEMU_HANDLE
+
+_send_qemu_cmd $h1 'qemu-io disk "map"' "sectors"
+_send_qemu_cmd $h1 'quit' ""
+
+echo
+echo === Read created image, force_size_calc=chs 
+echo
+
+_launch_qemu -drive file="${TEST_IMG}",id=disk,format=vpc,force_size_calc=chs
+h1=$QEMU_HANDLE
+
+_send_qemu_cmd $h1 'qemu-io disk "map"' "sectors"
+_send_qemu_cmd $h1 'quit' ""
+
+
+echo
+echo === Read created image, force_size_calc=current_size 
+echo
+
+_launch_qemu -drive 
file="${TEST_IMG}",id=disk,format=vpc,force_size_calc=current_size
+h1=$QEMU_HANDLE
+
+_send_qemu_cmd $h1 'qemu-io disk "map"' "sectors"
+_send_qemu_cmd $h1 'quit' ""
+
+
 
 echo "*** done"
 rm -f $seq.full
diff --git a/tests/qemu-iotests/146.out b/tests/qemu-iotests/146.out
index ddcfeb6..9a28a60 100644
--- a/tests/qemu-iotests/146.out
+++ b/tests/qemu-iotests/146.out
@@ -35,4 +35,48 @@ QEMU X.Y.Z monitor - type 'help' for more information
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) 
qqeqemqemuqemu-qemu-iqemu-ioqemu-io
 qemu-io dqemu-io 
diqemu-io 
disqemu-io 
diskqemu-io disk 
qemu-io disk 
"qemu-io disk 
"mqemu-io disk 
"maqemu-io disk 
"mapqemu-io disk "map"
 [   0]  266334240/ 266334240 sectors not allocated at 
offset 0 bytes (0)
+
+=== Testing Image create, default ===
+
+Formatting 'TEST_DIR/IMGFMT-create-test.IMGFMT', fmt=IMGFMT size=4294967296
+
+=== Read created image, default opts 
+
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) 
qqeqemqemuqemu-qemu-iqemu-ioqemu-io
 qemu-io dqemu-io 
diqemu-io 
disqemu-io 
diskqemu-io disk 
qemu-io disk 
"qemu-io disk 
"mqemu-io disk 
"maqemu-io disk 
"mapqemu-io disk "map"
+[   0]  8389584/ 8389584 sectors not allocated at offset 0 
bytes (0)
+
+=== Read created image, force_size_calc=chs 
+
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) 
qqeqemqemuqemu-qemu-iqemu-ioqemu-io
 qemu-io dqemu-io 
diqemu-io 
disqemu-io 
diskqemu-io disk 
qemu-io disk 
"qemu-io disk 

Re: [Qemu-devel] [RFC PATCH 00/16] Qemu Bit Map (QBM) - an overlay format for persistent dirty bitmap

2016-02-23 Thread Fam Zheng
On Tue, 02/23 18:43, Kevin Wolf wrote:
> Am 23.02.2016 um 04:40 hat Fam Zheng geschrieben:
> > (I'm Cc'ing a few more people here just in case they have different visions
> > about raw image use cases.)
> > 
> > On Mon, 02/22 15:24, Kevin Wolf wrote:
> > > Am 26.01.2016 um 11:38 hat Fam Zheng geschrieben:
> > > > This series introduces a simple format to enable support of persistence 
> > > > of
> > > > block dirty bitmaps. Block dirty bitmap is the tool to achieve 
> > > > incremental
> > > > backup, and persistence of block dirty bitmap makes incrememtal backup 
> > > > possible
> > > > across VM shutdowns, where existing in-memory dirty bitmaps cannot 
> > > > survive.
> > > > 
> > > > When user creates a "persisted" dirty bitmap, the QBM driver will 
> > > > create a
> > > > binary file and synchronize it with the existing in-memory block dirty 
> > > > bitmap
> > > > (BdrvDirtyBitmap). When the VM is powered down, the binary file has all 
> > > > the
> > > > bits saved on disk, which will be loaded and used to initialize the 
> > > > in-memory
> > > > block dirty bitmap next time the guest is started.
> > > > 
> > > > The idea of the format is to reuse as much existing infrastructure as 
> > > > possible
> > > > and avoid introducing complex data structures - it works with any image 
> > > > format,
> > > > by gluing it together plain bitmap files with a json descriptor file. 
> > > > The
> > > > advantage of this approach over extending existing formats, such as 
> > > > qcow2, is
> > > > that the new feature is implemented by an orthogonal driver, in a format
> > > > agnostic way. This way, even raw images can have their persistent dirty
> > > > bitmaps.  (And you will notice in this series, with a little forging to 
> > > > the
> > > > spec, raw images can also have backing files through a QBM overlay!)
> > > > 
> > > > Rather than superseding it, this intends to be coexistent in parallel 
> > > > with the
> > > > qcow2 bitmap extension that Vladimir is working on.  The block driver 
> > > > interface
> > > > changes in this series also try to be generic and compatible for both 
> > > > drivers.
> > > 
> > > So as I already told Fam last week, before we discuss any technical
> > > details here, we first need to discuss whether this is even the right
> > > thing to do. Currently I'm doubtful, as this is another attempt to
> > > introduce a new native image format in qemu.
> > > 
> > > Let's recap the image formats and what we tell users about them today:
> > > 
> > > * qcow2: This is the default choice for disk images. It gives you access
> > >   to all of the features in qemu at a good performance. If it doesn't
> > >   perform well in your case, we'll fix it.
> > > 
> > > * raw: Use this when you need absolute performance and don't need any
> > >   features from an image format, so you want to get any complexity just
> > >   out of the way and pass requests as directly as possible from the
> > >   guest device to the host kernel.
> > > 
> > > * Anything else: Only use them to convert into raw or qcow2.
> > > 
> > > Now using bitmaps is clearly on the "features" side, which suggests that
> > > qcow2 is the format of choice for this. If you want to introduce a new
> > > format, you need to justify it with evidence that...
> > > 
> > > 1. there is a relevant use case that qcow2 doesn't cover
> > > 2. qcow2 can't be fixed/enhanced to cover the use case
> > > 
> > > The one thing that people have claimed in the past that qcow2 can't
> > > provide is enough performance. This is where QED tried to come in and
> > > promised a compromise between performance (then a bit faster than qcow2)
> > > and features (almost none, but supports backing files). We all know that
> > > it was a failure because you had to sacrifice features and still the
> > > idea that qcow2 couldn't be fixed was wrong, so today we have a QED
> > > driver that is much slower than qcow2 despite having less features.
> > > 
> > > Now for QBM. First, let's have a look at the image format that it can be
> > > used with. qcow2 doesn't need it if we continue with Vladimir's
> > > extension. Other non-raw formats are only supposed to be used for
> > > conversion. The only thing that's really left is raw.
> > 
> > Yes, I agree with this point.
> > 
> > > Now adding a
> > > feature only for raw, as a compromise between features and performance,
> > > looks an awful lot like what QED tried. We don't want to go there.
> > > 
> > > Even if we wanted to support persistent dirty bitmaps with raw images
> > > (which has to be discussed based on use cases), it's still questionable
> > > whether we need a new image format with JSON descriptor files instead of
> > > just raw bitmaps that can be added with a QMP command.
> > > 
> > 
> > I don't think QMP interface alone is enough, in persistent backup use case,
> > when starting a guest, command line interface is more appropriate to 
> > continue
> > dirty trackings that were enabled during shutdown.
> 

[Qemu-devel] [PATCH 3/4] block/vpc: give option to force the current_size field in .bdrv_create

2016-02-23 Thread Jeff Cody
When QEMU creates a VHD image, it goes by the original spec,
calculating the current_size based on the nearest CHS geometry (with an
exception for disks > 127GB).

Apparently, Azure will only allow images that are sized to the nearest
MB, and the current_size as calculated from CHS cannot guarantee that.

Allow QEMU to create images similar to how Hyper-V creates images, by
setting current_size to the specified virtual disk size.  This
introduces an option, force_size, to be passed to the vpc format during
image creation, e.g.:

qemu-img convert -f raw -o force_size -O vpc test.img test.vhd

Bug reference: https://bugs.launchpad.net/qemu/+bug/1490611

Signed-off-by: Jeff Cody 
---
 block/vpc.c | 15 ++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/block/vpc.c b/block/vpc.c
index 54a38a7..48ef16e 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -49,6 +49,8 @@ enum vhd_type {
 #define VHD_MAX_SECTORS   (65535LL * 255 * 255)
 #define VHD_MAX_GEOMETRY  (65535LL *  16 * 255)
 
+#define VPC_OPT_FORCE_SIZE "force_size"
+
 // always big-endian
 typedef struct vhd_footer {
 charcreator[8]; // "conectix"
@@ -850,6 +852,7 @@ static int vpc_create(const char *filename, QemuOpts *opts, 
Error **errp)
 int64_t total_size;
 int disk_type;
 int ret = -EIO;
+bool force_size;
 Error *local_err = NULL;
 BlockDriverState *bs = NULL;
 
@@ -870,6 +873,8 @@ static int vpc_create(const char *filename, QemuOpts *opts, 
Error **errp)
 disk_type = VHD_DYNAMIC;
 }
 
+force_size = qemu_opt_get_bool_del(opts, VPC_OPT_FORCE_SIZE, false);
+
 ret = bdrv_create_file(filename, opts, _err);
 if (ret < 0) {
 error_propagate(errp, local_err);
@@ -896,7 +901,8 @@ static int vpc_create(const char *filename, QemuOpts *opts, 
Error **errp)
 calculate_geometry(total_sectors + i, , , _per_cyl);
 }
 
-if ((int64_t)cyls * heads * secs_per_cyl == VHD_MAX_GEOMETRY) {
+if ((int64_t)cyls * heads * secs_per_cyl == VHD_MAX_GEOMETRY ||
+force_size) {
 total_sectors = total_size / BDRV_SECTOR_SIZE;
 /* Allow a maximum disk size of approximately 2 TB */
 if (total_sectors > VHD_MAX_SECTORS) {
@@ -994,6 +1000,13 @@ static QemuOptsList vpc_create_opts = {
 "Type of virtual hard disk format. Supported formats are "
 "{dynamic (default) | fixed} "
 },
+{
+.name = VPC_OPT_FORCE_SIZE,
+.type = QEMU_OPT_BOOL,
+.help = "Force disk size calculation to use the actual size "
+"specified, rather than using the nearest CHS-based "
+"calculation"
+},
 { /* end of list */ }
 }
 };
-- 
1.9.3




[Qemu-devel] [PATCH 2/4] block/vpc: tests for auto-detecting VPC and Hyper-V VHD images

2016-02-23 Thread Jeff Cody
This tests auto-detection, and overrides, of VHD image sizes created
by Virtual PC and Hyper-V.

This adds two sample images:

hyperv2012r2-dynamic.vhd.bz2 - dynamic VHD image created with Hyper-V
virtualpc-dynamic.vhd.bz2- dynamic VHD image created with Virtual PC

Signed-off-by: Jeff Cody 
---
 tests/qemu-iotests/146 | 119 +
 tests/qemu-iotests/146.out |  38 +++
 tests/qemu-iotests/group   |   1 +
 .../sample_images/hyperv2012r2-dynamic.vhd.bz2 | Bin 0 -> 214 bytes
 .../sample_images/virtualpc-dynamic.vhd.bz2| Bin 0 -> 212 bytes
 5 files changed, 158 insertions(+)
 create mode 100755 tests/qemu-iotests/146
 create mode 100644 tests/qemu-iotests/146.out
 create mode 100644 
tests/qemu-iotests/sample_images/hyperv2012r2-dynamic.vhd.bz2
 create mode 100644 tests/qemu-iotests/sample_images/virtualpc-dynamic.vhd.bz2

diff --git a/tests/qemu-iotests/146 b/tests/qemu-iotests/146
new file mode 100755
index 000..af60849
--- /dev/null
+++ b/tests/qemu-iotests/146
@@ -0,0 +1,119 @@
+#!/bin/bash
+#
+# Test VHD image format creator detection and override
+#
+# Copyright (C) 2016 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+# creator
+owner=jc...@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1# failure is the default!
+
+_cleanup()
+{
+_cleanup_qemu
+_cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.qemu
+
+_supported_fmt vpc
+_supported_proto file
+_supported_os Linux
+
+
+qemu_comm_method="monitor"
+silent=
+
+echo
+echo === Testing VPC Autodetect ===
+echo
+_use_sample_img virtualpc-dynamic.vhd.bz2
+
+_launch_qemu -drive file="${TEST_IMG}",id=disk,format=vpc
+h1=$QEMU_HANDLE
+
+_send_qemu_cmd $h1 'qemu-io disk "map"' "sectors"
+_send_qemu_cmd $h1 'quit' ""
+
+echo
+echo === Testing VPC with current_size force ===
+echo
+
+_launch_qemu -drive 
file="${TEST_IMG}",id=disk,format=vpc,force_size_calc=current_size
+h1=$QEMU_HANDLE
+
+_send_qemu_cmd $h1 'qemu-io disk "map"' "sectors"
+_send_qemu_cmd $h1 'quit' ""
+
+echo
+echo === Testing VPC with chs force ===
+echo
+
+_launch_qemu -drive file="${TEST_IMG}",id=disk,format=vpc,force_size_calc=chs
+h1=$QEMU_HANDLE
+
+_send_qemu_cmd $h1 'qemu-io disk "map"' "sectors"
+_send_qemu_cmd $h1 'quit' ""
+
+
+_cleanup_test_img
+
+echo
+echo === Testing Hyper-V Autodetect ===
+echo
+_use_sample_img hyperv2012r2-dynamic.vhd.bz2
+
+_launch_qemu -drive file="${TEST_IMG}",id=disk,format=vpc
+h1=$QEMU_HANDLE
+
+_send_qemu_cmd $h1 'qemu-io disk "map"' "sectors"
+_send_qemu_cmd $h1 'quit' ""
+
+echo
+echo === Testing Hyper-V with current_size force ===
+echo
+
+_launch_qemu -drive 
file="${TEST_IMG}",id=disk,format=vpc,force_size_calc=current_size
+h1=$QEMU_HANDLE
+
+_send_qemu_cmd $h1 'qemu-io disk "map"' "sectors"
+_send_qemu_cmd $h1 'quit' ""
+
+echo
+echo === Testing Hyper-V with chs force ===
+echo
+
+_launch_qemu -drive file="${TEST_IMG}",id=disk,format=vpc,force_size_calc=chs
+h1=$QEMU_HANDLE
+
+_send_qemu_cmd $h1 'qemu-io disk "map"' "sectors"
+_send_qemu_cmd $h1 'quit' ""
+
+
+
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/146.out b/tests/qemu-iotests/146.out
new file mode 100644
index 000..ddcfeb6
--- /dev/null
+++ b/tests/qemu-iotests/146.out
@@ -0,0 +1,38 @@
+QA output created by 146
+
+=== Testing VPC Autodetect ===
+
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) 
qqeqemqemuqemu-qemu-iqemu-ioqemu-io
 qemu-io dqemu-io 
diqemu-io 
disqemu-io 
diskqemu-io disk 
qemu-io disk 
"qemu-io disk 
"mqemu-io disk 
"maqemu-io disk 
"mapqemu-io disk "map"
+[   0]  266334240/ 266334240 sectors not allocated at 

[Qemu-devel] [PATCH 0/4] VHD/VPC format compatibility

2016-02-23 Thread Jeff Cody
This is a long-standing issue that has come up many times, and has had
several different patches posted to fix it.  Virtual PC, and Hyper-V
calculate the disk geometry differently for VHD, leading to compatibility
issues.

We want to fix these compatibility problems, however we want to make sure
we do not break backwards compatibility.

There are two areas of compatibility addressed:

* Reading images (Patch 1)
* Creating images (Patch 3)

Please see the commit messages in Patches 1,3 for details.

Jeff Cody (4):
  block/vpc: choose size calculation method based on creator_app field
  block/vpc: tests for auto-detecting VPC and Hyper-V VHD images
  block/vpc: give option to force the current_size field in .bdrv_create
  block/vpc: add tests for image creation force_size parameter

 block/vpc.c| 102 ++-
 tests/qemu-iotests/146 | 200 +
 tests/qemu-iotests/146.out |  82 +
 tests/qemu-iotests/group   |   1 +
 .../sample_images/hyperv2012r2-dynamic.vhd.bz2 | Bin 0 -> 214 bytes
 .../sample_images/virtualpc-dynamic.vhd.bz2| Bin 0 -> 212 bytes
 6 files changed, 379 insertions(+), 6 deletions(-)
 create mode 100755 tests/qemu-iotests/146
 create mode 100644 tests/qemu-iotests/146.out
 create mode 100644 
tests/qemu-iotests/sample_images/hyperv2012r2-dynamic.vhd.bz2
 create mode 100644 tests/qemu-iotests/sample_images/virtualpc-dynamic.vhd.bz2

-- 
1.9.3




[Qemu-devel] [PATCH 1/4] block/vpc: choose size calculation method based on creator_app field

2016-02-23 Thread Jeff Cody
The VHD file format is used by both Virtual PC, and Hyper-V.  However,
how the virtual disk size is calculated varies between the two.

Virtual PC uses the CHS drive parameters to determine the drive size.
Hyper-V, on the other hand, uses the current_size field in the footer
when determining image size.

This is problematic for a few reasons:

* VHD images from Hyper-V, using CHS calculations, will likely be
  trunctated.

* If we just rely always on current_size, then QEMU may have data
  compatibility issues with Virtual PC (we may write too much data
  into a VHD file to be used by Virtual PC, for instance).

* Existing VHD images created by QEMU have used the CHS calculations,
  except for images exceeding the 127GB limit.  We want to remain
  compatible with our own generated images.

Luckily, the VHD specification defines a 'Creator App' field, that is
used to indicate what software created the VHD file.

This patch does two things:

1. Uses the 'Creator App' field to help determine how to calculate
   size, and

2. Adds a VPC format option 'force_size_calc', so that the user can
   override the 'Creator App' auto-detection, in case there exist
   VHD images with unknown or contradictory 'Creator App' entries.

N.B.: We currently use the maximum CHS value as an indication to use the
current_size field.  This patch does not change that, even with the
'force_size_calc' option.

Signed-off-by: Jeff Cody 
---
 block/vpc.c | 87 +
 1 file changed, 82 insertions(+), 5 deletions(-)

diff --git a/block/vpc.c b/block/vpc.c
index f504536..54a38a7 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -128,6 +128,8 @@ typedef struct BDRVVPCState {
 
 uint32_t block_size;
 uint32_t bitmap_size;
+bool force_use_chs;
+bool force_use_sz;
 
 #ifdef CACHE
 uint8_t *pageentry_u8;
@@ -140,6 +142,22 @@ typedef struct BDRVVPCState {
 Error *migration_blocker;
 } BDRVVPCState;
 
+#define VPC_OPT_SIZE_CALC "force_size_calc"
+static QemuOptsList vpc_runtime_opts = {
+.name = "vpc-runtime-opts",
+.head = QTAILQ_HEAD_INITIALIZER(vpc_runtime_opts.head),
+.desc = {
+{
+.name = VPC_OPT_SIZE_CALC,
+.type = QEMU_OPT_STRING,
+.help = "Force disk size calculation to use either CHS geometry, "
+"or use the disk current_size specified in the VHD footer. 
"
+"{chs, current_size}"
+},
+{ /* end of list */ }
+}
+};
+
 static uint32_t vpc_checksum(uint8_t* buf, size_t size)
 {
 uint32_t res = 0;
@@ -159,6 +177,25 @@ static int vpc_probe(const uint8_t *buf, int buf_size, 
const char *filename)
 return 0;
 }
 
+static void vpc_parse_options(BlockDriverState *bs, QemuOpts *opts,
+  Error **errp)
+{
+BDRVVPCState *s = bs->opaque;
+const char *size_calc;
+
+size_calc = qemu_opt_get(opts, VPC_OPT_SIZE_CALC);
+
+if (!size_calc) {
+   /* no override, use autodetect only */
+} else if (!strcmp(size_calc, "current_size")) {
+s->force_use_sz = true;
+} else if (!strcmp(size_calc, "chs")) {
+s->force_use_chs = true;
+} else {
+error_setg(errp, "Invalid size calculation mode: '%s'", size_calc);
+}
+}
+
 static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
 Error **errp)
 {
@@ -166,6 +203,9 @@ static int vpc_open(BlockDriverState *bs, QDict *options, 
int flags,
 int i;
 VHDFooter *footer;
 VHDDynDiskHeader *dyndisk_header;
+QemuOpts *opts = NULL;
+Error *local_err = NULL;
+bool use_chs;
 uint8_t buf[HEADER_SIZE];
 uint32_t checksum;
 uint64_t computed_size;
@@ -173,6 +213,21 @@ static int vpc_open(BlockDriverState *bs, QDict *options, 
int flags,
 int disk_type = VHD_DYNAMIC;
 int ret;
 
+opts = qemu_opts_create(_runtime_opts, NULL, 0, _abort);
+qemu_opts_absorb_qdict(opts, options, _err);
+if (local_err) {
+error_propagate(errp, local_err);
+ret = -EINVAL;
+goto fail;
+}
+
+vpc_parse_options(bs, opts, _err);
+if (local_err) {
+error_propagate(errp, local_err);
+ret = -EINVAL;
+goto fail;
+}
+
 ret = bdrv_pread(bs->file->bs, 0, s->footer_buf, HEADER_SIZE);
 if (ret < 0) {
 goto fail;
@@ -218,12 +273,34 @@ static int vpc_open(BlockDriverState *bs, QDict *options, 
int flags,
 bs->total_sectors = (int64_t)
 be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl;
 
-/* Images that have exactly the maximum geometry are probably bigger and
- * would be truncated if we adhered to the geometry for them. Rely on
- * footer->current_size for them. */
-if (bs->total_sectors == VHD_MAX_GEOMETRY) {
+/* Microsoft Virtual PC and Microsoft Hyper-V produce and read
+ * VHD image sizes differently.  VPC will rely on CHS geometry,
+ 

Re: [Qemu-devel] [PATCH v3 2/3] block/backup: avoid copying less than full target clusters

2016-02-23 Thread Eric Blake
On 02/23/2016 05:27 PM, Fam Zheng wrote:
> On Tue, 02/23 19:17, John Snow wrote:
>> During incremental backups, if the target has a cluster size that is
>> larger than the backup cluster size and we are backing up to a target
>> that cannot (for whichever reason) pull clusters up from a backing image,
>> we may inadvertantly create unusable incremental backup images.
>>

>> +/* If there is no backing file on the target, we cannot rely on COW if 
>> our
>> + * backup cluster size is smaller than the target cluster size. Even for
>> + * targets with a backing file, try to avoid COW if possible. */
>> +ret = bdrv_get_info(job->target, );
>> +if (ret < 0 && !target->backing) {
>> +error_setg_errno(errp, -ret,
>> +"Can't determine cluster size of target that has no backing 
>> file. "
>> +"This may create an unusable destination image. Aborting.");
> 
> Most error messages don't end with a period, but that's not a hard rule 
> AFAICT.

Ah, but it is:

include/qapi/error.h:

 * The resulting message should be a single phrase, with no newline or
 * trailing punctuation.
 * Please don't error_setg(_fatal, ...), use error_report() and
 * exit(), because that's more obvious.
 * Likewise, don't error_setg(_abort, ...), use assert().
 */
#define error_setg(errp, fmt, ...)  \

The error message should be "Can't determine cluster size of target
without backing file"; everything else should be done with
error_append_hint(, "Aborting, since this may create an unusable
destination image\n")


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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v3 2/3] block/backup: avoid copying less than full target clusters

2016-02-23 Thread John Snow


On 02/23/2016 07:27 PM, Fam Zheng wrote:
> On Tue, 02/23 19:17, John Snow wrote:
>> During incremental backups, if the target has a cluster size that is
>> larger than the backup cluster size and we are backing up to a target
>> that cannot (for whichever reason) pull clusters up from a backing image,
>> we may inadvertantly create unusable incremental backup images.
>>
>> For example:
>>
>> If the bitmap tracks changes at a 64KB granularity and we transmit 64KB
>> of data at a time but the target uses a 128KB cluster size, it is
>> possible that only half of a target cluster will be recognized as dirty
>> by the backup block job. When the cluster is allocated on the target
>> image but only half populated with data, we lose the ability to
>> distinguish between zero padding and uninitialized data.
>>
>> This does not happen if the target image has a backing file that points
>> to the last known good backup.
>>
>> Even if we have a backing file, though, it's likely going to be faster
>> to just buffer the redundant data ourselves from the live image than
>> fetching it from the backing file, so let's just always round up to the
>> target granularity.
>>
>> The same logic applies to backup modes top, none, and full. Copying
>> fractional clusters without the guarantee of COW is dangerous, but even
>> if we can rely on COW, it's likely better to just re-copy the data.
>>
>> Reported-by: Fam Zheng 
>> Signed-off-by: John Snow 
>> ---
>>  block/backup.c | 23 ---
>>  1 file changed, 20 insertions(+), 3 deletions(-)
>>
>> diff --git a/block/backup.c b/block/backup.c
>> index 76addef..6e9f53d 100644
>> --- a/block/backup.c
>> +++ b/block/backup.c
>> @@ -501,6 +501,8 @@ void backup_start(BlockDriverState *bs, BlockDriverState 
>> *target,
>>BlockJobTxn *txn, Error **errp)
>>  {
>>  int64_t len;
>> +BlockDriverInfo bdi;
>> +int ret;
>>  
>>  assert(bs);
>>  assert(target);
>> @@ -570,15 +572,30 @@ void backup_start(BlockDriverState *bs, 
>> BlockDriverState *target,
>>  goto error;
>>  }
>>  
>> -bdrv_op_block_all(target, job->common.blocker);
>> -
>>  job->on_source_error = on_source_error;
>>  job->on_target_error = on_target_error;
>>  job->target = target;
>>  job->sync_mode = sync_mode;
>>  job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ?
>> sync_bitmap : NULL;
>> -job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
>> +
>> +/* If there is no backing file on the target, we cannot rely on COW if 
>> our
>> + * backup cluster size is smaller than the target cluster size. Even for
>> + * targets with a backing file, try to avoid COW if possible. */
>> +ret = bdrv_get_info(job->target, );
>> +if (ret < 0 && !target->backing) {
>> +error_setg_errno(errp, -ret,
>> +"Can't determine cluster size of target that has no backing 
>> file. "
>> +"This may create an unusable destination image. Aborting.");
> 
> Most error messages don't end with a period, but that's not a hard rule 
> AFAICT.

If that's the only problem, Jeff can touch it up.

I want to ask, though:

"Are there any cases where we will have no backing file and no
bdrv_get_info implementation, but backup should still succeed?"

I think the answer is /no/ since everything we claim to support for use
with QEMU (instead of qemu-img only) should implement bdrv_get_info.

> 
>> +goto error;
>> +} else if (ret < 0 && target->backing) {
>> +/* Not fatal; just trudge on ahead. */
>> +job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
>> +} else {
>> +job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, 
>> bdi.cluster_size);
>> +}
>> +
>> +bdrv_op_block_all(target, job->common.blocker);
>>  job->common.len = len;
>>  job->common.co = qemu_coroutine_create(backup_run);
>>  block_job_txn_add_job(txn, >common);
>> -- 
>> 2.4.3
>>
> 
> Reviewed-by: Fam Zheng 
> 

Thanks.



Re: [Qemu-devel] [PATCH] aio-posix: Change CONFIG_EPOLL to CONFIG_EPOLL_CREATE1

2016-02-23 Thread Fam Zheng
On Tue, 02/23 15:42, Matthew Fortune wrote:
> CONFIG_EPOLL was being used to guard epoll_create1 which results
> in build failures on CentOS 5.
> 
> Signed-off-by: Matthew Fortune 
> ---
>  aio-posix.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/aio-posix.c b/aio-posix.c
> index fa7f8ab..7fd565f 100644
> --- a/aio-posix.c
> +++ b/aio-posix.c
> @@ -18,7 +18,7 @@
>  #include "block/block.h"
>  #include "qemu/queue.h"
>  #include "qemu/sockets.h"
> -#ifdef CONFIG_EPOLL
> +#ifdef CONFIG_EPOLL_CREATE1
>  #include 
>  #endif
>  
> @@ -33,7 +33,7 @@ struct AioHandler
>  QLIST_ENTRY(AioHandler) node;
>  };
>  
> -#ifdef CONFIG_EPOLL
> +#ifdef CONFIG_EPOLL_CREATE1
>  
>  /* The fd number threashold to switch to epoll */
>  #define EPOLL_ENABLE_THRESHOLD 64
> @@ -483,7 +483,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
>  
>  void aio_context_setup(AioContext *ctx, Error **errp)
>  {
> -#ifdef CONFIG_EPOLL
> +#ifdef CONFIG_EPOLL_CREATE1
>  assert(!ctx->epollfd);
>  ctx->epollfd = epoll_create1(EPOLL_CLOEXEC);
>  if (ctx->epollfd == -1) {
> -- 
> 2.2.1
> 

Reviewed-by: Fam Zheng 




Re: [Qemu-devel] [PATCH v3 2/3] block/backup: avoid copying less than full target clusters

2016-02-23 Thread Fam Zheng
On Tue, 02/23 19:17, John Snow wrote:
> During incremental backups, if the target has a cluster size that is
> larger than the backup cluster size and we are backing up to a target
> that cannot (for whichever reason) pull clusters up from a backing image,
> we may inadvertantly create unusable incremental backup images.
> 
> For example:
> 
> If the bitmap tracks changes at a 64KB granularity and we transmit 64KB
> of data at a time but the target uses a 128KB cluster size, it is
> possible that only half of a target cluster will be recognized as dirty
> by the backup block job. When the cluster is allocated on the target
> image but only half populated with data, we lose the ability to
> distinguish between zero padding and uninitialized data.
> 
> This does not happen if the target image has a backing file that points
> to the last known good backup.
> 
> Even if we have a backing file, though, it's likely going to be faster
> to just buffer the redundant data ourselves from the live image than
> fetching it from the backing file, so let's just always round up to the
> target granularity.
> 
> The same logic applies to backup modes top, none, and full. Copying
> fractional clusters without the guarantee of COW is dangerous, but even
> if we can rely on COW, it's likely better to just re-copy the data.
> 
> Reported-by: Fam Zheng 
> Signed-off-by: John Snow 
> ---
>  block/backup.c | 23 ---
>  1 file changed, 20 insertions(+), 3 deletions(-)
> 
> diff --git a/block/backup.c b/block/backup.c
> index 76addef..6e9f53d 100644
> --- a/block/backup.c
> +++ b/block/backup.c
> @@ -501,6 +501,8 @@ void backup_start(BlockDriverState *bs, BlockDriverState 
> *target,
>BlockJobTxn *txn, Error **errp)
>  {
>  int64_t len;
> +BlockDriverInfo bdi;
> +int ret;
>  
>  assert(bs);
>  assert(target);
> @@ -570,15 +572,30 @@ void backup_start(BlockDriverState *bs, 
> BlockDriverState *target,
>  goto error;
>  }
>  
> -bdrv_op_block_all(target, job->common.blocker);
> -
>  job->on_source_error = on_source_error;
>  job->on_target_error = on_target_error;
>  job->target = target;
>  job->sync_mode = sync_mode;
>  job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ?
> sync_bitmap : NULL;
> -job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
> +
> +/* If there is no backing file on the target, we cannot rely on COW if 
> our
> + * backup cluster size is smaller than the target cluster size. Even for
> + * targets with a backing file, try to avoid COW if possible. */
> +ret = bdrv_get_info(job->target, );
> +if (ret < 0 && !target->backing) {
> +error_setg_errno(errp, -ret,
> +"Can't determine cluster size of target that has no backing 
> file. "
> +"This may create an unusable destination image. Aborting.");

Most error messages don't end with a period, but that's not a hard rule AFAICT.

> +goto error;
> +} else if (ret < 0 && target->backing) {
> +/* Not fatal; just trudge on ahead. */
> +job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
> +} else {
> +job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, 
> bdi.cluster_size);
> +}
> +
> +bdrv_op_block_all(target, job->common.blocker);
>  job->common.len = len;
>  job->common.co = qemu_coroutine_create(backup_run);
>  block_job_txn_add_job(txn, >common);
> -- 
> 2.4.3
> 

Reviewed-by: Fam Zheng 



Re: [Qemu-devel] [PATCH qemu] memory: Fix IOMMU replay base address

2016-02-23 Thread Alexey Kardashevskiy

On 02/23/2016 08:56 PM, Paolo Bonzini wrote:



On 23/02/2016 10:00, Alexey Kardashevskiy wrote:


   tce = tcet->table[addr >> tcet->page_shift];
-ret.iova = addr & page_mask;
+ret.iova = (addr + iommu->addr) & page_mask;
   ret.translated_addr = tce & page_mask;


I wondered about that change, but I'd have to look closer to see if
the iova field here is expected to be relative to the MR as well.  It
would be oddly inconsistent if it wasn't.


It is relative and it does not make sense as there is no source MR/AS in
iotlb (only target AS) so there is no use in such iova.


ret.iova should be relative to the source AS (i.e. even if a 32-bit
IOMMU region translates between 4GB and 8GB, ret.iova should have bits
32-63 set to 0).



In my test branch with 2 DMA windows I have such PHB AS:

address-space: pci@8002000
  - (prio 0, RW): 
pci@8002000.iommu-root

- (prio 0, RW): tce-root-8001
  0800-0800 (prio 0, RW): tce-iommu-8001
- (prio 0, RW): tce-root-8000
  -3fff (prio 0, RW): tce-iommu-8000
0400-0400 (prio 0, RW): msi


The source AS is 0..(u64)-1. iotlb.iova from 
spapr_tce_translate_iommu(tce-root-8001) will be relative to 
0800 which is not source AS.


What do I miss here?



So there is a problem in vfio_iommu_map_notify:

 ret = vfio_dma_map(container, iotlb->iova,
iotlb->addr_mask + 1, vaddr,
!(iotlb->perm & IOMMU_WO) || mr->readonly);

I think that, in vfio_listener_region_add, the iova variable should be
stored in VFIOGuestIOMMU for use in vfio_iommu_map_notify.

ret.translated_addr should be relative to the target AS, which VFIO
assumes to be address_space_memory.


That is perfectly fine - there is iotlb.target_as.



--
Alexey



[Qemu-devel] [PATCH v3 1/3] block/backup: make backup cluster size configurable

2016-02-23 Thread John Snow
64K might not always be appropriate, make this a runtime value.

Signed-off-by: John Snow 
Reviewed-by: Fam Zheng 
---
 block/backup.c | 64 +-
 1 file changed, 36 insertions(+), 28 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 00cafdb..76addef 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -21,10 +21,7 @@
 #include "qemu/ratelimit.h"
 #include "sysemu/block-backend.h"
 
-#define BACKUP_CLUSTER_BITS 16
-#define BACKUP_CLUSTER_SIZE (1 << BACKUP_CLUSTER_BITS)
-#define BACKUP_SECTORS_PER_CLUSTER (BACKUP_CLUSTER_SIZE / BDRV_SECTOR_SIZE)
-
+#define BACKUP_CLUSTER_SIZE_DEFAULT (1 << 16)
 #define SLICE_TIME 1ULL /* ns */
 
 typedef struct CowRequest {
@@ -46,9 +43,16 @@ typedef struct BackupBlockJob {
 CoRwlock flush_rwlock;
 uint64_t sectors_read;
 HBitmap *bitmap;
+int64_t cluster_size;
 QLIST_HEAD(, CowRequest) inflight_reqs;
 } BackupBlockJob;
 
+/* Size of a cluster in sectors, instead of bytes. */
+static inline int64_t cluster_size_sectors(BackupBlockJob *job)
+{
+  return job->cluster_size / BDRV_SECTOR_SIZE;
+}
+
 /* See if in-flight requests overlap and wait for them to complete */
 static void coroutine_fn wait_for_overlapping_requests(BackupBlockJob *job,
int64_t start,
@@ -97,13 +101,14 @@ static int coroutine_fn backup_do_cow(BlockDriverState *bs,
 QEMUIOVector bounce_qiov;
 void *bounce_buffer = NULL;
 int ret = 0;
+int64_t sectors_per_cluster = cluster_size_sectors(job);
 int64_t start, end;
 int n;
 
 qemu_co_rwlock_rdlock(>flush_rwlock);
 
-start = sector_num / BACKUP_SECTORS_PER_CLUSTER;
-end = DIV_ROUND_UP(sector_num + nb_sectors, BACKUP_SECTORS_PER_CLUSTER);
+start = sector_num / sectors_per_cluster;
+end = DIV_ROUND_UP(sector_num + nb_sectors, sectors_per_cluster);
 
 trace_backup_do_cow_enter(job, start, sector_num, nb_sectors);
 
@@ -118,12 +123,12 @@ static int coroutine_fn backup_do_cow(BlockDriverState 
*bs,
 
 trace_backup_do_cow_process(job, start);
 
-n = MIN(BACKUP_SECTORS_PER_CLUSTER,
+n = MIN(sectors_per_cluster,
 job->common.len / BDRV_SECTOR_SIZE -
-start * BACKUP_SECTORS_PER_CLUSTER);
+start * sectors_per_cluster);
 
 if (!bounce_buffer) {
-bounce_buffer = qemu_blockalign(bs, BACKUP_CLUSTER_SIZE);
+bounce_buffer = qemu_blockalign(bs, job->cluster_size);
 }
 iov.iov_base = bounce_buffer;
 iov.iov_len = n * BDRV_SECTOR_SIZE;
@@ -131,10 +136,10 @@ static int coroutine_fn backup_do_cow(BlockDriverState 
*bs,
 
 if (is_write_notifier) {
 ret = bdrv_co_readv_no_serialising(bs,
-   start * BACKUP_SECTORS_PER_CLUSTER,
+   start * sectors_per_cluster,
n, _qiov);
 } else {
-ret = bdrv_co_readv(bs, start * BACKUP_SECTORS_PER_CLUSTER, n,
+ret = bdrv_co_readv(bs, start * sectors_per_cluster, n,
 _qiov);
 }
 if (ret < 0) {
@@ -147,11 +152,11 @@ static int coroutine_fn backup_do_cow(BlockDriverState 
*bs,
 
 if (buffer_is_zero(iov.iov_base, iov.iov_len)) {
 ret = bdrv_co_write_zeroes(job->target,
-   start * BACKUP_SECTORS_PER_CLUSTER,
+   start * sectors_per_cluster,
n, BDRV_REQ_MAY_UNMAP);
 } else {
 ret = bdrv_co_writev(job->target,
- start * BACKUP_SECTORS_PER_CLUSTER, n,
+ start * sectors_per_cluster, n,
  _qiov);
 }
 if (ret < 0) {
@@ -322,21 +327,22 @@ static int coroutine_fn 
backup_run_incremental(BackupBlockJob *job)
 int64_t cluster;
 int64_t end;
 int64_t last_cluster = -1;
+int64_t sectors_per_cluster = cluster_size_sectors(job);
 BlockDriverState *bs = job->common.bs;
 HBitmapIter hbi;
 
 granularity = bdrv_dirty_bitmap_granularity(job->sync_bitmap);
-clusters_per_iter = MAX((granularity / BACKUP_CLUSTER_SIZE), 1);
+clusters_per_iter = MAX((granularity / job->cluster_size), 1);
 bdrv_dirty_iter_init(job->sync_bitmap, );
 
 /* Find the next dirty sector(s) */
 while ((sector = hbitmap_iter_next()) != -1) {
-cluster = sector / BACKUP_SECTORS_PER_CLUSTER;
+cluster = sector / sectors_per_cluster;
 
 /* Fake progress updates for any clusters we skipped */
 if (cluster != last_cluster + 1) {
 job->common.offset += ((cluster - last_cluster - 1) *
-   BACKUP_CLUSTER_SIZE);
+   

[Qemu-devel] [PATCH v3 3/3] iotests/124: Add cluster_size mismatch test

2016-02-23 Thread John Snow
If a backing file isn't specified in the target image and the
cluster_size is larger than the bitmap granularity, we run the risk of
creating bitmaps with allocated clusters but empty/no data which will
prevent the proper reading of the backup in the future.

Signed-off-by: John Snow 
Reviewed-by: Fam Zheng 
---
 tests/qemu-iotests/124 | 58 ++
 tests/qemu-iotests/124.out |  4 ++--
 2 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/tests/qemu-iotests/124 b/tests/qemu-iotests/124
index 7d33422..de7cdbe 100644
--- a/tests/qemu-iotests/124
+++ b/tests/qemu-iotests/124
@@ -132,14 +132,16 @@ class TestIncrementalBackupBase(iotests.QMPTestCase):
 
 
 def img_create(self, img, fmt=iotests.imgfmt, size='64M',
-   parent=None, parentFormat=None):
+   parent=None, parentFormat=None, **kwargs):
+optargs = []
+for k,v in kwargs.iteritems():
+optargs = optargs + ['-o', '%s=%s' % (k,v)]
+args = ['create', '-f', fmt] + optargs + [img, size]
 if parent:
 if parentFormat is None:
 parentFormat = fmt
-iotests.qemu_img('create', '-f', fmt, img, size,
- '-b', parent, '-F', parentFormat)
-else:
-iotests.qemu_img('create', '-f', fmt, img, size)
+args = args + ['-b', parent, '-F', parentFormat]
+iotests.qemu_img(*args)
 self.files.append(img)
 
 
@@ -307,6 +309,52 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
 return self.do_incremental_simple(granularity=131072)
 
 
+def test_larger_cluster_target(self):
+'''
+Test: Create and verify backups made to a larger cluster size target.
+
+With a default granularity of 64KiB, verify that backups made to a
+larger cluster size target of 128KiB without a backing file works.
+'''
+drive0 = self.drives[0]
+
+# Create a cluster_size=128k full backup / "anchor" backup
+self.img_create(drive0['backup'], cluster_size='128k')
+self.assertTrue(self.do_qmp_backup(device=drive0['id'], sync='full',
+   format=drive0['fmt'],
+   target=drive0['backup'],
+   mode='existing'))
+
+# Create bitmap and dirty it with some new writes.
+# overwrite [32736, 32799] which will dirty bitmap clusters at
+# 32M-64K and 32M. 32M+64K will be left undirtied.
+bitmap0 = self.add_bitmap('bitmap0', drive0)
+self.hmp_io_writes(drive0['id'],
+   (('0xab', 0, 512),
+('0xfe', '16M', '256k'),
+('0x64', '32736k', '64k')))
+
+
+# Prepare a cluster_size=128k backup target without a backing file.
+(target, _) = bitmap0.new_target()
+self.img_create(target, bitmap0.drive['fmt'], cluster_size='128k')
+
+# Perform Incremental Backup
+self.assertTrue(self.do_qmp_backup(device=bitmap0.drive['id'],
+   sync='incremental',
+   bitmap=bitmap0.name,
+   format=bitmap0.drive['fmt'],
+   target=target,
+   mode='existing'))
+self.make_reference_backup(bitmap0)
+
+# Add the backing file, then compare and exit.
+iotests.qemu_img('rebase', '-f', drive0['fmt'], '-u', '-b',
+ drive0['backup'], '-F', drive0['fmt'], target)
+self.vm.shutdown()
+self.check_backups()
+
+
 def test_incremental_transaction(self):
 '''Test: Verify backups made from transactionally created bitmaps.
 
diff --git a/tests/qemu-iotests/124.out b/tests/qemu-iotests/124.out
index dae404e..36376be 100644
--- a/tests/qemu-iotests/124.out
+++ b/tests/qemu-iotests/124.out
@@ -1,5 +1,5 @@
-.
+..
 --
-Ran 9 tests
+Ran 10 tests
 
 OK
-- 
2.4.3




[Qemu-devel] [PATCH v3 0/3] blockjob: correct backup cluster size for backups

2016-02-23 Thread John Snow
Backups sometimes need a non-64KiB transfer cluster size.
See patch #2 for the detailed justificaton.

===
v3:
===

01: +R-B
02: Added failure mode for bdrv_get_info, including critical failure for when
we don't have a backing file but couldn't retrieve the cluster_size info.

===
v2:
===

01: Removed "sectors_per_cluster" as a cached property of the Backup Block Job,
In favor of recomputing it with a small function where needed.
(I like v1 more. Thoughts?)
02: Expand correction to all backup modes instead of just incremental.
Added credit: Thanks to Fam Z for noticing this problem!
03: Minor phrasing change in a comment.
Added r-b.



For convenience, this branch is available at:
https://github.com/jnsnow/qemu.git branch incremental-granularity-fix
https://github.com/jnsnow/qemu/tree/incremental-granularity-fix

This version is tagged incremental-granularity-fix-v3:
https://github.com/jnsnow/qemu/releases/tag/incremental-granularity-fix-v3

John Snow (3):
  block/backup: make backup cluster size configurable
  block/backup: avoid copying less than full target clusters
  iotests/124: Add cluster_size mismatch test

 block/backup.c | 85 ++
 tests/qemu-iotests/124 | 58 ---
 tests/qemu-iotests/124.out |  4 +--
 3 files changed, 110 insertions(+), 37 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH v3 2/3] block/backup: avoid copying less than full target clusters

2016-02-23 Thread John Snow
During incremental backups, if the target has a cluster size that is
larger than the backup cluster size and we are backing up to a target
that cannot (for whichever reason) pull clusters up from a backing image,
we may inadvertantly create unusable incremental backup images.

For example:

If the bitmap tracks changes at a 64KB granularity and we transmit 64KB
of data at a time but the target uses a 128KB cluster size, it is
possible that only half of a target cluster will be recognized as dirty
by the backup block job. When the cluster is allocated on the target
image but only half populated with data, we lose the ability to
distinguish between zero padding and uninitialized data.

This does not happen if the target image has a backing file that points
to the last known good backup.

Even if we have a backing file, though, it's likely going to be faster
to just buffer the redundant data ourselves from the live image than
fetching it from the backing file, so let's just always round up to the
target granularity.

The same logic applies to backup modes top, none, and full. Copying
fractional clusters without the guarantee of COW is dangerous, but even
if we can rely on COW, it's likely better to just re-copy the data.

Reported-by: Fam Zheng 
Signed-off-by: John Snow 
---
 block/backup.c | 23 ---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 76addef..6e9f53d 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -501,6 +501,8 @@ void backup_start(BlockDriverState *bs, BlockDriverState 
*target,
   BlockJobTxn *txn, Error **errp)
 {
 int64_t len;
+BlockDriverInfo bdi;
+int ret;
 
 assert(bs);
 assert(target);
@@ -570,15 +572,30 @@ void backup_start(BlockDriverState *bs, BlockDriverState 
*target,
 goto error;
 }
 
-bdrv_op_block_all(target, job->common.blocker);
-
 job->on_source_error = on_source_error;
 job->on_target_error = on_target_error;
 job->target = target;
 job->sync_mode = sync_mode;
 job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ?
sync_bitmap : NULL;
-job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
+
+/* If there is no backing file on the target, we cannot rely on COW if our
+ * backup cluster size is smaller than the target cluster size. Even for
+ * targets with a backing file, try to avoid COW if possible. */
+ret = bdrv_get_info(job->target, );
+if (ret < 0 && !target->backing) {
+error_setg_errno(errp, -ret,
+"Can't determine cluster size of target that has no backing file. "
+"This may create an unusable destination image. Aborting.");
+goto error;
+} else if (ret < 0 && target->backing) {
+/* Not fatal; just trudge on ahead. */
+job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
+} else {
+job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);
+}
+
+bdrv_op_block_all(target, job->common.blocker);
 job->common.len = len;
 job->common.co = qemu_coroutine_create(backup_run);
 block_job_txn_add_job(txn, >common);
-- 
2.4.3




[Qemu-devel] [Bug 1546445] Re: support vhost user without specifying vhostforce

2016-02-23 Thread Mathew Hodson
** Changed in: qemu (Ubuntu)
   Importance: Undecided => Medium

** Changed in: qemu (Ubuntu Vivid)
   Importance: Undecided => Medium

** Changed in: qemu (Ubuntu Wily)
   Importance: Undecided => Medium

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

Title:
  support vhost user without specifying vhostforce

Status in Ubuntu Cloud Archive:
  New
Status in QEMU:
  In Progress
Status in qemu package in Ubuntu:
  New
Status in qemu source package in Vivid:
  Won't Fix
Status in qemu source package in Wily:
  Fix Released

Bug description:
  [Impact]

   * vhost-user falls back to virtio-net which causes performance lose
  without specifying the vhostforce option. But it should be the default
  behavior for vhost-user, since guests using PMD doesn't support msi-x.

  [Test Case]

create a vhost-user virtio backend without specifying the vhostforce 
option, i.e. -netdev 
type=vhost-user,id=mynet1,chardev=
start the VM
vhost-user is not enabled

  [Regression Potential]

   * none

  vhost user nic doesn't support non msi guests(like pxe stage) by default.
  Vhost user nic can't fall back to qemu like normal vhost net nic does. So we 
should
  enable it for non msi guests.

  The problem has been fix in qemu upstream  -
  
http://git.qemu.org/?p=qemu.git;a=commitdiff;h=24f938a682d934b133863eb421aac33592f7a09e.
  And the patch needs to be backported to 1:2.2+dfsg-5expubuntu9.8 .

To manage notifications about this bug go to:
https://bugs.launchpad.net/cloud-archive/+bug/1546445/+subscriptions



Re: [Qemu-devel] [PATCH v8 1/4] firmware: introduce sysfs driver for QEMU's fw_cfg device

2016-02-23 Thread Gabriel L. Somlo
On Tue, Feb 23, 2016 at 04:14:46PM +0200, Michael S. Tsirkin wrote:
> On Tue, Feb 23, 2016 at 08:47:00AM -0500, Gabriel L. Somlo wrote:
> > On Tue, Feb 23, 2016 at 07:07:36AM +0200, Michael S. Tsirkin wrote:
> > > On Mon, Feb 22, 2016 at 03:26:23PM -0500, Gabriel L. Somlo wrote:
> > > > On Mon, Feb 22, 2016 at 10:14:50PM +0200, Michael S. Tsirkin wrote:
> > > > > On Sun, Feb 21, 2016 at 08:06:17AM -0500, Gabriel L. Somlo wrote:
> > > > > > > > +static void fw_cfg_io_cleanup(void)
> > > > > > > > +{
> > > > > > > > +   if (fw_cfg_is_mmio) {
> > > > > > > > +   iounmap(fw_cfg_dev_base);
> > > > > > > > +   release_mem_region(fw_cfg_p_base, 
> > > > > > > > fw_cfg_p_size);
> > > > > > > > +   } else {
> > > > > > > > +   ioport_unmap(fw_cfg_dev_base);
> > > > > > > > +   release_region(fw_cfg_p_base, fw_cfg_p_size);
> > > > > > > > +   }
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +/* arch-specific ctrl & data register offsets are not 
> > > > > > > > available in ACPI, DT */
> > > > > > > 
> > > > > > > So for all arches which support ACPI, I think this driver
> > > > > > > should just rely on ACPI.
> > > > > > 
> > > > > > There was a discussion about that a few versions ago, and IIRC the
> > > > > > conclusion was not to expect the firmware to contend for fw_cfg 
> > > > > > access
> > > > > > after the guest kernel boots:
> > > > > > 
> > > > > > https://lkml.org/lkml/2015/10/5/283
> > > > > > 
> > > > > 
> > > > > So it looks like NVDIMM at least wants to pass label data to guest -
> > > > > for which fw cfg might be a reasonable choice.
> > > > > 
> > > > > I suspect things changed - fw cfg used to be very slow but we now have
> > > > > DMA interface which makes it useful for a range of applications.
> > > 
> > > Comment on this? I'm really worried we'll release linux
> > > without a way to access fw cfg from aml.
> > > How about taking acpi lock around all accesses?
> > 
> > You mean something like this (haven't tried compiling it yet, so it
> > might be a bit more complicated, but just for the purpose of this
> > conversation):
> > 
> > diff --git a/drivers/firmware/qemu_fw_cfg.c
> > b/drivers/firmware/qemu_fw_cfg.c
> > index fedbff5..3462a2c 100644
> > --- a/drivers/firmware/qemu_fw_cfg.c
> > +++ b/drivers/firmware/qemu_fw_cfg.c
> > @@ -77,12 +77,18 @@ static inline u16 fw_cfg_sel_endianness(u16 key)
> >  static inline void fw_cfg_read_blob(u16 key,
> > void *buf, loff_t pos, size_t
> > count)
> >  {
> > +#ifdef CONFIG_ACPI
> > +   acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
> > +#endif
> > mutex_lock(_cfg_dev_lock);
> > iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl);
> > while (pos-- > 0)
> > ioread8(fw_cfg_reg_data);
> > ioread8_rep(fw_cfg_reg_data, buf, count);
> > mutex_unlock(_cfg_dev_lock);
> > +#ifdef CONFIG_ACPI
> > +   acpi_os_release_mutex(acpi_gbl_osi_mutex);
> > +#endif
> >  }
> >  
> >  /* clean up fw_cfg device i/o */
> 
> Fundamentally yes.
> 
> > I wouldn't particularly *mind* doing that, but I'd still like to hear
> > from other QEMU devs on whether it's really necessary.
> 
> It seems like a prudent thing to do IMHO, before this
> goes out to users.
> 
> [...]
> 
> On balance, I think locking ACPI solves most problems so
> if we just do that, I think what you did here is fine.

Only trouble is, acpi_gbl_osi_mutex seems to be "private" to the acpi
subsystem, and I'm not sure how well a patch to allow some random
module to lock/unlock ACPI at its convenience would be received...

So unless I'm missing something obvious (wouldn't be the first time),
I think we're back to where *if* we *have* to do this [*], providing an
AML blob-reader method in ACPI and punting to it from the guest-side
kernel module (via #ifdef CONFIG_ACPI) would be the less painful
alternative.

[*] that is, mutual exclusion between kernel and firmware regarding
fw_cfg is (back) on the table, for real this time...

It would be good to know that it's the new consensus among QEMU
folks, since I have a strong feeling I'd no longer be "Keeping It Simple"
by moving in this direction.

Thanks,
--Gabriel




Re: [Qemu-devel] [PATCH v2] qmp-shell: fix pretty printing of JSON responses

2016-02-23 Thread John Snow


On 02/23/2016 05:51 AM, Daniel P. Berrange wrote:
> Pretty printing of JSON responses is important to be able to understand
> large responses from query commands in particular. Unfortunately this
> was broken during the addition of the verbose flag in
> 
>   commit 1ceca07e48ead0dd2e41576c81d40e6a91cafefd
>   Author: John Snow 
>   Date:   Wed Apr 29 15:14:04 2015 -0400
> 
> scripts: qmp-shell: Add verbose flag
> 
> This is because that change turned the python data structure into a
> formatted JSON string before the pretty print was given it. So we're
> just pretty printing a string, which is a no-op.
> 

Mea Culpa.

> The original pretty printer would output python objects.
> 
> (QEMU) query-chardev
> {   u'return': [   {   u'filename': u'vc',
>u'frontend-open': False,
>u'label': u'parallel0'},
>{   u'filename': u'vc',
>u'frontend-open': True,
>u'label': u'serial0'},
>{   u'filename': u'unix:/tmp/qemp,server',
>u'frontend-open': True,
>u'label': u'compat_monitor0'}]}
> 
> This fixes the problem by switching to outputting pretty formatted JSON
> text instead. This has the added benefit that the pretty printed output
> is now valid JSON text. Due to the way the verbose flag was handled, the
> pretty printing now applies to the command sent, as well as its response:
> 
> (QEMU) query-chardev
> {
> "execute": "query-chardev",
> "arguments": {}
> }
> {
> "return": [
> {
> "frontend-open": false,
> "label": "parallel0",
> "filename": "vc"
> },
> {
> "frontend-open": true,
> "label": "serial0",
> "filename": "vc"
> },
> {
> "frontend-open": true,
> "label": "compat_monitor0",
> "filename": "unix:/tmp/qmp,server"
> }
> ]
> }
> 

That's good news as far as I am concerned.

> Signed-off-by: Daniel P. Berrange 
> ---
>  scripts/qmp/qmp-shell | 23 ++-
>  1 file changed, 10 insertions(+), 13 deletions(-)
> 
> diff --git a/scripts/qmp/qmp-shell b/scripts/qmp/qmp-shell
> index 7a402ed..0373b24 100755
> --- a/scripts/qmp/qmp-shell
> +++ b/scripts/qmp/qmp-shell
> @@ -70,7 +70,6 @@ import json
>  import ast
>  import readline
>  import sys
> -import pprint
>  
>  class QMPCompleter(list):
>  def complete(self, text, state):
> @@ -103,11 +102,11 @@ class FuzzyJSON(ast.NodeTransformer):
>  # TODO: QMPShell's interface is a bit ugly (eg. _fill_completion() and
>  #   _execute_cmd()). Let's design a better one.

^ Heh ^

>  class QMPShell(qmp.QEMUMonitorProtocol):
> -def __init__(self, address, pp=None):
> +def __init__(self, address, pretty=False):
>  qmp.QEMUMonitorProtocol.__init__(self, self.__get_address(address))
>  self._greeting = None
>  self._completer = None
> -self._pp = pp
> +self._pretty = pretty
>  self._transmode = False
>  self._actions = list()
>  
> @@ -231,11 +230,11 @@ class QMPShell(qmp.QEMUMonitorProtocol):
>  return qmpcmd
>  
>  def _print(self, qmp):
> -jsobj = json.dumps(qmp)
> -if self._pp is not None:
> -self._pp.pprint(jsobj)
> -else:
> -print str(jsobj)
> +indent = None
> +if self._pretty:
> +indent = 4
> +jsobj = json.dumps(qmp, indent=indent)
> +print str(jsobj)
>  
>  def _execute_cmd(self, cmdline):
>  try:
> @@ -377,7 +376,7 @@ def main():
>  addr = ''
>  qemu = None
>  hmp = False
> -pp = None
> +pretty = False
>  verbose = False
>  
>  try:
> @@ -387,9 +386,7 @@ def main():
>  fail_cmdline(arg)
>  hmp = True
>  elif arg == "-p":
> -if pp is not None:
> -fail_cmdline(arg)
> -pp = pprint.PrettyPrinter(indent=4)
> +pretty = True

We now accept any number of -p arguments. That's probably fine.

>  elif arg == "-v":
>  verbose = True
>  else:
> @@ -398,7 +395,7 @@ def main():
>  if hmp:
>  qemu = HMPShell(arg)
>  else:
> -qemu = QMPShell(arg, pp)
> +qemu = QMPShell(arg, pretty)
>  addr = arg
>  
>  if qemu is None:
> 

Reviewed-by: John Snow 



Re: [Qemu-devel] [PATCH] qga: implement the guest-set-vcpus for windows

2016-02-23 Thread Michael Roth
Quoting Gal Hammer (2015-11-02 08:49:48)
> Signed-off-by: Gal Hammer 
> ---
>  qga/commands-win32.c | 66 
> ++--
>  1 file changed, 64 insertions(+), 2 deletions(-)
> 
> diff --git a/qga/commands-win32.c b/qga/commands-win32.c
> index d9de23b..a8eb4a0 100644
> --- a/qga/commands-win32.c
> +++ b/qga/commands-win32.c
> @@ -1181,7 +1181,69 @@ void qmp_guest_set_time(bool has_time, int64_t 
> time_ns, Error **errp)
> 
>  GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp)
>  {
> -error_setg(errp, QERR_UNSUPPORTED);
> +PSYSTEM_LOGICAL_PROCESSOR_INFORMATION pslpi, ptr;
> +DWORD length;
> +GuestLogicalProcessorList *head, **link;
> +Error *local_err = NULL;
> +int64_t current;
> +
> +ptr = pslpi = NULL;
> +length = 0;
> +current = 0;
> +head = NULL;
> +link = 
> +
> +if ((GetLogicalProcessorInformation(pslpi, ) == FALSE) &&
> +(GetLastError() == ERROR_INSUFFICIENT_BUFFER) &&
> +(length > sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION))) {
> +ptr = pslpi = g_malloc0(length);
> +if (GetLogicalProcessorInformation(pslpi, ) == FALSE) {
> +error_setg(_err, "Failed to get processor information: %d",
> +   (int)GetLastError());
> +}
> +} else {
> +error_setg(_err,
> +   "Failed to get processor information buffer length: %d",
> +   (int)GetLastError());
> +}
> +
> +while ((local_err == NULL) && (length > 0)) {
> +if (pslpi->Relationship == RelationProcessorCore) {
> +ULONG_PTR cpu_bits = pslpi->ProcessorMask;
> +
> +while (cpu_bits > 0) {
> +if (!!(cpu_bits & 1)) {
> +GuestLogicalProcessor *vcpu;
> +GuestLogicalProcessorList *entry;
> +
> +vcpu = g_malloc0(sizeof *vcpu);
> +vcpu->logical_id = current++;
> +vcpu->online = true;
> +vcpu->has_can_offline = false;
> +
> +entry = g_malloc0(sizeof *entry);
> +entry->value = vcpu;
> +
> +*link = entry;
> +link = >next;
> +}
> +cpu_bits >>= 1;
> +}
> +}
> +length -= sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
> +pslpi++; /* next entry */
> +}
> +
> +g_free(ptr);
> +
> +if (local_err == NULL) {
> +/* there's no guest with zero VCPUs */
> +g_assert(head != NULL);

I think we should report that via error_setg() rather than assert.

Since it's a minor I can fix that up on my end though:

Reviewed-by: Michael Roth 

Sorry for the delay in getting to this. Need to test, but plan on pulling
this in for 2.6.

> +return head;
> +}
> +
> +qapi_free_GuestLogicalProcessorList(head);
> +error_propagate(errp, local_err);
>  return NULL;
>  }
> 
> @@ -1295,7 +1357,7 @@ GList *ga_command_blacklist_init(GList *blacklist)
>  {
>  const char *list_unsupported[] = {
>  "guest-suspend-hybrid",
> -"guest-get-vcpus", "guest-set-vcpus",
> +"guest-set-vcpus",
>  "guest-get-memory-blocks", "guest-set-memory-blocks",
>  "guest-get-memory-block-size",
>  "guest-fsfreeze-freeze-list",
> -- 
> 2.1.0
> 



Re: [Qemu-devel] [PATCH 2/2] s390x/pci: use PCI_MSIX_FLAGS on retrieving the MSIX entries

2016-02-23 Thread Wei Yang
On Tue, Feb 23, 2016 at 02:17:11PM +0800, Yi Min Zhao wrote:
>于 Mon, 22 Feb 2016 14:15:07 +0100
>Christian Borntraeger  写道:
>
>> On 02/19/2016 04:18 PM, Wei Yang wrote:
>> > Even PCI_CAP_FLAGS has the same value as PCI_MSIX_FLAGS, the later one is
>> > the more proper on retrieving MSIX entries.
>> > 
>> > This patch uses PCI_MSIX_FLAGS to retrieve the MSIX entries.
>> > 
>> > Signed-off-by: Wei Yang 
>> > CC: Cornelia Huck 
>> > CC: Christian Borntraeger 
>> > ---
>> >  hw/s390x/s390-pci-bus.c |2 +-
>> >  1 file changed, 1 insertion(+), 1 deletion(-)
>> > 
>> > diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
>> > index 132588b..9d40039 100644
>> > --- a/hw/s390x/s390-pci-bus.c
>> > +++ b/hw/s390x/s390-pci-bus.c
>> > @@ -523,7 +523,7 @@ static int s390_pcihost_setup_msix(S390PCIBusDevice 
>> > *pbdev)
>> >  return 0;
>> >  }
>> > 
>> > -ctrl = pci_host_config_read_common(pbdev->pdev, pos + PCI_CAP_FLAGS,
>> > +ctrl = pci_host_config_read_common(pbdev->pdev, pos + PCI_MSIX_FLAGS,
>> >   pci_config_size(pbdev->pdev), sizeof(ctrl));
>> >  table = pci_host_config_read_common(pbdev->pdev, pos + PCI_MSIX_TABLE,
>> >   pci_config_size(pbdev->pdev), sizeof(table));
>> > 
>> 
>> looks sane.
>> Yi Min, can you ack/nack?
>> 
>> 
>
>It looks sane to me. A little change.

Thanks Yi Min and Christian.

So someone would pick it up?

-- 
Wei Yang
Help you, Help me



Re: [Qemu-devel] [PATCH v3 2/8] cpu: introduce possible-cpus interface

2016-02-23 Thread Eduardo Habkost
On Tue, Feb 23, 2016 at 05:05:54PM +0100, Igor Mammedov wrote:
> on x86 currently range 0..max_cpus is used to generate
> architecture-dependent CPU ID (APIC Id) for each present
> and possible CPUs. However architecture-dependent CPU IDs
> list could be sparse and code that needs to enumerate
> all IDs (ACPI) ended up doing guess work enumerating all
> possible and impossible IDs up to
>   apic_id_limit = x86_cpu_apic_id_from_index(max_cpus).
> 
> That leads to creation of MADT/SRAT entries and Processor
> objects in ACPI tables for not possible CPUs.
> Fix it by allowing board specify a concrete list of
> CPU IDs accourding its own rules (which for x86 depends
> on topology). So that code that needs this list could
> request it from board instead of trying to figure out
> what IDs are correct on its own.
> 
> This interface will also allow to help making AML
> part of CPU hotplug target independent so it could
> be reused for ARM target.

Do you expect any non-TYPE_MACHINE class to implement this
interface? If not, why not just make it a simple MachineClass
field? Machines that don't implement the get_possible_cpus_list()
method would just have it set to NULL.

-- 
Eduardo



Re: [Qemu-devel] [RFC] QMP: add query-hotpluggable-cpus

2016-02-23 Thread Eduardo Habkost
On Tue, Feb 23, 2016 at 10:46:45AM +0100, Igor Mammedov wrote:
> On Mon, 22 Feb 2016 13:54:32 +1100
> David Gibson  wrote:
[...]
> > This is why Eduardo suggested - and I agreed - that it's probably
> > better to implement the "1st layer" as an internal structure/interface
> > only, and implement the 2nd layer on top of that.  When/if we need to
> > we can revisit a user-accessible interface to the 1st layer.
> We are going around QOM based CPU introspecting interface for
> years now and that's exactly what 2nd layer is, just another
> implementation. I've just lost hope in this approach.
> 
> What I'm suggesting in this RFC is to forget controversial
> QOM approach for now and use -device/device_add + QMP introspection,

You have a point about it looking controversial, but I would like
to understand why exactly it is controversial. Discussions seem
to get stuck every single time we try to do something useful with
the QOM tree, and I don't undertsand why.

> i.e. completely split interface from how boards internally implement
> CPU hotplug.

A QOM-based interface may still split the interface from how
boards internally implement CPU hotplug. They don't need to
affect the device tree of the machine, we just need to create QOM
objects or links at predictable paths, that implement certain
interfaces.

-- 
Eduardo



[Qemu-devel] [PATCH 3/3] qapi: Update docs to match recent generator changes

2016-02-23 Thread Eric Blake
Several commits have been changing the generator, but not updating
the docs to match:
- The implicit tag member is named "type", not "kind".  Screwed up in
commit 39a1815.
- Commit 9f08c8ec made list types lazy, and thereby dropped
UserDefOneList if nothing explicitly uses the list type.
- Commit 51e72bc1 switched the parameter order with 'name' occurring
earlier.
- Commit e65d89bf changed the layout of UserDefOneList.
- We now expose visit_type_FOO_fields() for objects.
- etc.

Rework the examples to show slightly more output (we don't want to
show too much; that's what the testsuite is for), and regenerate the
output to match all recent changes.  Also, rearrange output to show
.h files before .c (understanding the interface first often makes
the implementation easier to follow).

Reported-by: Marc-André Lureau 
Signed-off-by: Eric Blake 
Signed-off-by: Markus Armbruster 

---
Some content from Markus, hence his S-o-b.
A former version of this patch was posted with subset E v9.
---
 docs/qapi-code-gen.txt | 308 ++---
 1 file changed, 162 insertions(+), 146 deletions(-)

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index 999f3b9..e1dde87 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -1,7 +1,7 @@
 = How to use the QAPI code generator =

 Copyright IBM Corp. 2011
-Copyright (C) 2012-2015 Red Hat, Inc.
+Copyright (C) 2012-2016 Red Hat, Inc.

 This work is licensed under the terms of the GNU GPL, version 2 or
 later. See the COPYING file in the top-level directory.
@@ -656,7 +656,7 @@ Union types

 { "name": "BlockdevOptions", "meta-type": "object",
   "members": [
-  { "name": "kind", "type": "BlockdevOptionsKind" } ],
+  { "name": "type", "type": "BlockdevOptionsKind" } ],
   "tag": "type",
   "variants": [
   { "case": "file", "type": ":obj-FileOptions-wrapper" },
@@ -722,33 +722,39 @@ the names of built-in types.  Clients should examine 
member

 == Code generation ==

-Schemas are fed into four scripts to generate all the code/files that,
+Schemas are fed into five scripts to generate all the code/files that,
 paired with the core QAPI libraries, comprise everything required to
 take JSON commands read in by a Client JSON Protocol server, unmarshal
 the arguments into the underlying C types, call into the corresponding
-C function, and map the response back to a Client JSON Protocol
-response to be returned to the user.
+C function, map the response back to a Client JSON Protocol response
+to be returned to the user, and introspect the commands.

-As an example, we'll use the following schema, which describes a single
-complex user-defined type (which will produce a C struct, along with a list
-node structure that can be used to chain together a list of such types in
-case we want to accept/return a list of this type with a command), and a
-command which takes that type as a parameter and returns the same type:
+As an example, we'll use the following schema, which describes a
+single complex user-defined type, along with command which takes a
+list of that type as a parameter, and returns a single element of that
+type.  The user is responsible for writing the implementation of
+qmp_my_command(); everything else is produced by the generator.

 $ cat example-schema.json
 { 'struct': 'UserDefOne',
-  'data': { 'integer': 'int', 'string': 'str' } }
+  'data': { 'integer': 'int', '*string': 'str' } }

 { 'command': 'my-command',
-  'data':{'arg1': 'UserDefOne'},
+  'data':{ 'arg1': ['UserDefOne'] },
   'returns': 'UserDefOne' }

 { 'event': 'MY_EVENT' }

+For a more thorough look at generated code, the testsuite includes
+tests/qapi-schema/qapi-schema-tests.json that covers more examples of
+what the generator will accept, and compiles the resulting C code as
+part of 'make check-unit'.
+
 === scripts/qapi-types.py ===

-Used to generate the C types defined by a schema. The following files are
-created:
+Used to generate the C types defined by a schema, as well as the
+functions for recursively cleaning up their resources, as
+qapi_free_FOO(). The following files are created:

 $(prefix)qapi-types.h - C types corresponding to types defined in
 the schema you pass in
@@ -763,38 +769,6 @@ Example:

 $ python scripts/qapi-types.py --output-dir="qapi-generated" \
 --prefix="example-" example-schema.json
-$ cat qapi-generated/example-qapi-types.c
-[Uninteresting stuff omitted...]
-
-void qapi_free_UserDefOne(UserDefOne *obj)
-{
-QapiDeallocVisitor *qdv;
-Visitor *v;
-
-if (!obj) {
-return;
-}
-
-qdv = qapi_dealloc_visitor_new();
-v = qapi_dealloc_get_visitor(qdv);
-visit_type_UserDefOne(v, , NULL, NULL);
-qapi_dealloc_visitor_cleanup(qdv);
-}
-
-void 

[Qemu-devel] [PATCH 1/3] qapi-dealloc: Reduce use outside of generated code

2016-02-23 Thread Eric Blake
No need to roll our own use of the dealloc visitors when we can
just directly use the qapi_free_FOO() functions that do what we
want in one line.

In net.c, inline net_visit() into its remaining lone caller.

After this patch, test-visitor-serialization.c is the only
non-generated file that needs to use a dealloc visitor, because
it is testing low level aspects of the visitor interface.

Signed-off-by: Eric Blake 
---
 hw/acpi/core.c| 11 +--
 net/net.c | 31 ++-
 numa.c|  9 +
 tests/test-opts-visitor.c | 10 +-
 4 files changed, 13 insertions(+), 48 deletions(-)

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index 3a14e90..3d9e5c4 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -26,7 +26,6 @@
 #include "hw/nvram/fw_cfg.h"
 #include "qemu/config-file.h"
 #include "qapi/opts-visitor.h"
-#include "qapi/dealloc-visitor.h"
 #include "qapi-visit.h"
 #include "qapi-event.h"

@@ -297,15 +296,7 @@ void acpi_table_add(const QemuOpts *opts, Error **errp)
 out:
 g_free(blob);
 g_strfreev(pathnames);
-
-if (hdrs != NULL) {
-QapiDeallocVisitor *dv;
-
-dv = qapi_dealloc_visitor_new();
-visit_type_AcpiTableOptions(qapi_dealloc_get_visitor(dv), NULL, ,
-NULL);
-qapi_dealloc_visitor_cleanup(dv);
-}
+qapi_free_AcpiTableOptions(hdrs);

 error_propagate(errp, err);
 }
diff --git a/net/net.c b/net/net.c
index aebf753..b0c832e 100644
--- a/net/net.c
+++ b/net/net.c
@@ -42,7 +42,6 @@
 #include "qemu/main-loop.h"
 #include "qapi-visit.h"
 #include "qapi/opts-visitor.h"
-#include "qapi/dealloc-visitor.h"
 #include "sysemu/sysemu.h"
 #include "net/filter.h"
 #include "qapi/string-output-visitor.h"
@@ -1043,38 +1042,28 @@ static int net_client_init1(const void *object, int 
is_netdev, Error **errp)
 }


-static void net_visit(Visitor *v, int is_netdev, void **object, Error **errp)
-{
-if (is_netdev) {
-visit_type_Netdev(v, NULL, (Netdev **)object, errp);
-} else {
-visit_type_NetLegacy(v, NULL, (NetLegacy **)object, errp);
-}
-}
-
-
 int net_client_init(QemuOpts *opts, int is_netdev, Error **errp)
 {
 void *object = NULL;
 Error *err = NULL;
 int ret = -1;
+OptsVisitor *ov = opts_visitor_new(opts);
+Visitor *v = opts_get_visitor(ov);

-{
-OptsVisitor *ov = opts_visitor_new(opts);
-
-net_visit(opts_get_visitor(ov), is_netdev, , );
-opts_visitor_cleanup(ov);
+if (is_netdev) {
+visit_type_Netdev(v, NULL, (Netdev **), );
+} else {
+visit_type_NetLegacy(v, NULL, (NetLegacy **), );
 }

 if (!err) {
 ret = net_client_init1(object, is_netdev, );
 }

-if (object) {
-QapiDeallocVisitor *dv = qapi_dealloc_visitor_new();
-
-net_visit(qapi_dealloc_get_visitor(dv), is_netdev, , NULL);
-qapi_dealloc_visitor_cleanup(dv);
+if (is_netdev) {
+qapi_free_Netdev(object);
+} else {
+qapi_free_NetLegacy(object);
 }

 error_propagate(errp, err);
diff --git a/numa.c b/numa.c
index 4c4f7f5..da27bf8 100644
--- a/numa.c
+++ b/numa.c
@@ -31,7 +31,6 @@
 #include "include/exec/cpu-common.h" /* for RAM_ADDR_FMT */
 #include "qapi-visit.h"
 #include "qapi/opts-visitor.h"
-#include "qapi/dealloc-visitor.h"
 #include "hw/boards.h"
 #include "sysemu/hostmem.h"
 #include "qmp-commands.h"
@@ -243,13 +242,7 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error 
**errp)

 error:
 error_report_err(err);
-
-if (object) {
-QapiDeallocVisitor *dv = qapi_dealloc_visitor_new();
-visit_type_NumaOptions(qapi_dealloc_get_visitor(dv), NULL, ,
-   NULL);
-qapi_dealloc_visitor_cleanup(dv);
-}
+qapi_free_NumaOptions(object);

 return -1;
 }
diff --git a/tests/test-opts-visitor.c b/tests/test-opts-visitor.c
index b7acf7d..297a02d 100644
--- a/tests/test-opts-visitor.c
+++ b/tests/test-opts-visitor.c
@@ -17,7 +17,6 @@
 #include "qemu/option.h"  /* qemu_opts_parse() */
 #include "qapi/opts-visitor.h"/* opts_visitor_new() */
 #include "test-qapi-visit.h"  /* visit_type_UserDefOptions() */
-#include "qapi/dealloc-visitor.h" /* qapi_dealloc_visitor_new() */

 static QemuOptsList userdef_opts = {
 .name = "userdef",
@@ -55,14 +54,7 @@ setup_fixture(OptsVisitorFixture *f, gconstpointer test_data)
 static void
 teardown_fixture(OptsVisitorFixture *f, gconstpointer test_data)
 {
-if (f->userdef != NULL) {
-QapiDeallocVisitor *dv;
-
-dv = qapi_dealloc_visitor_new();
-visit_type_UserDefOptions(qapi_dealloc_get_visitor(dv), NULL,
-  >userdef, NULL);
-qapi_dealloc_visitor_cleanup(dv);
-}
+qapi_free_UserDefOptions(f->userdef);
 error_free(f->err);
 }

-- 
2.5.0




[Qemu-devel] [PATCH v2 11/24] target-sparc: Use defines from asi.h

2016-02-23 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-sparc/ldst_helper.c | 459 +++--
 target-sparc/translate.c   |   6 +-
 2 files changed, 235 insertions(+), 230 deletions(-)

diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index b0600fd..249923e 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -21,6 +21,7 @@
 #include "cpu.h"
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"
+#include "asi.h"
 
 //#define DEBUG_MMU
 //#define DEBUG_MXCC
@@ -437,7 +438,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
addr, int asi, int size,
 
 helper_check_align(env, addr, size - 1);
 switch (asi) {
-case 2: /* SuperSparc MXCC registers and Leon3 cache control */
+case ASI_M_MXCC: /* SuperSparc MXCC registers, or... */
+/* case ASI_LEON_CACHEREGS:  Leon3 cache control */
 switch (addr) {
 case 0x00:  /* Leon3 Cache Control */
 case 0x08:  /* Leon3 Instruction Cache config */
@@ -496,8 +498,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
addr, int asi, int size,
 dump_mxcc(env);
 #endif
 break;
-case 3: /* MMU probe */
-case 0x18: /* LEON3 MMU probe */
+case ASI_M_FLUSH_PROBE: /* SuperSparc MMU probe */
+case ASI_LEON_MMUFLUSH: /* LEON3 MMU probe */
 {
 int mmulev;
 
@@ -511,8 +513,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
addr, int asi, int size,
 addr, mmulev, ret);
 }
 break;
-case 4: /* read MMU regs */
-case 0x19: /* LEON3 read MMU regs */
+case ASI_M_MMUREGS: /* SuperSparc MMU regs */
+case ASI_LEON_MMUREGS: /* LEON3 MMU regs */
 {
 int reg = (addr >> 8) & 0x1f;
 
@@ -527,11 +529,11 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
addr, int asi, int size,
 DPRINTF_MMU("mmu_read: reg[%d] = 0x%08" PRIx64 "\n", reg, ret);
 }
 break;
-case 5: /* Turbosparc ITLB Diagnostic */
-case 6: /* Turbosparc DTLB Diagnostic */
-case 7: /* Turbosparc IOTLB Diagnostic */
+case ASI_M_TLBDIAG: /* Turbosparc ITLB Diagnostic */
+case ASI_M_DIAGS:   /* Turbosparc DTLB Diagnostic */
+case ASI_M_IODIAG:  /* Turbosparc IOTLB Diagnostic */
 break;
-case 9: /* Supervisor code access */
+case ASI_KERNELTXT: /* Supervisor code access */
 switch (size) {
 case 1:
 ret = cpu_ldub_code(env, addr);
@@ -548,7 +550,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
addr, int asi, int size,
 break;
 }
 break;
-case 0xa: /* User data access */
+case ASI_USERDATA: /* User data access */
 switch (size) {
 case 1:
 ret = cpu_ldub_user(env, addr);
@@ -565,8 +567,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
addr, int asi, int size,
 break;
 }
 break;
-case 0xb: /* Supervisor data access */
-case 0x80:
+case ASI_KERNELDATA: /* Supervisor data access */
+case ASI_P: /* Implicit primary context data access (v9 only?) */
 switch (size) {
 case 1:
 ret = cpu_ldub_kernel(env, addr);
@@ -583,13 +585,13 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
addr, int asi, int size,
 break;
 }
 break;
-case 0xc: /* I-cache tag */
-case 0xd: /* I-cache data */
-case 0xe: /* D-cache tag */
-case 0xf: /* D-cache data */
+case ASI_M_TXTC_TAG:   /* SparcStation 5 I-cache tag */
+case ASI_M_TXTC_DATA:  /* SparcStation 5 I-cache data */
+case ASI_M_DATAC_TAG:  /* SparcStation 5 D-cache tag */
+case ASI_M_DATAC_DATA: /* SparcStation 5 D-cache data */
 break;
-case 0x20: /* MMU passthrough */
-case 0x1c: /* LEON MMU passthrough */
+case ASI_M_BYPASS:/* MMU passthrough */
+case ASI_LEON_BYPASS: /* LEON MMU passthrough */
 switch (size) {
 case 1:
 ret = ldub_phys(cs->as, addr);
@@ -668,7 +670,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
addr, int asi, int size,
 case 0x4c: /* SuperSPARC MMU Breakpoint Action */
 ret = env->mmubpaction;
 break;
-case 8: /* User code access, XXX */
+case ASI_USERTXT: /* User code access, XXX */
 default:
 cpu_unassigned_access(cs, addr, false, false, asi, size);
 ret = 0;
@@ -703,7 +705,8 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, 
uint64_t val, int asi,
 
 helper_check_align(env, addr, size - 1);
 switch (asi) {
-case 2: /* SuperSparc MXCC registers and Leon3 cache control */
+case ASI_M_MXCC: /* SuperSparc MXCC registers, or... */
+/* case ASI_LEON_CACHEREGS:  Leon3 cache control */
 switch (addr) {
 case 0x00:  /* Leon3 Cache Control */
 case 0x08:  /* Leon3 Instruction Cache 

Re: [Qemu-devel] Migrating decrementer

2016-02-23 Thread Mark Cave-Ayland
On 03/02/16 04:59, David Gibson wrote:

>> Going back to your earlier email you suggested that the host timebase is
>> always continuously running, even when the guest is paused. But then
>> resuming the guest then the timebase must jump in the guest regardless?
>>
>> If this is the case then this is the big difference between TCG and KVM
>> guests: TCG timebase is derived from the virtual clock which solves the
>> problem of paused guests during migration. For example with the existing
>> migration code, what would happen if you did a migration with the guest
>> paused on KVM? The offset would surely be wrong as it was calculated at
>> the end of migration.
> 
> So there are two different cases to consider here.  Once is when the
> guest is paused incidentally, such as during migration, the other is
> when the guest is explicitly paused.
> 
> In the first case the timebase absolutely should keep running (or
> appear to do so), since it's the primary source of real time for the
> guest.

I'm not sure I understand this, since if the guest is paused either
deliberately or incidentally during migration then isn't the timebase
also frozen? Or is it external to the CPU?

> In the second case, it's a bit unclear what the right thing to do is.
> Keeping the tb running means accurate realtime, but stopping it is
> often better for debugging, which is one of the main reasons to
> explicitly pause.
> 
> I believe spapr on KVM HV will keep the TB going, but the TSC on x86
> will be stopped.

Is this from a guest-centric view, i.e. if I pause a VM and wait 20 mins
then when the guest resumes the timebase will jump forward by 20 mins
worth of ticks?


ATB,

Mark.




[Qemu-devel] [PATCH v2 15/24] target-sparc: Directly implement easy ldd/std asis

2016-02-23 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-sparc/translate.c | 111 +--
 1 file changed, 98 insertions(+), 13 deletions(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 008b07b..5fd096f 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1976,6 +1976,7 @@ typedef enum {
 GET_ASI_HELPER,
 GET_ASI_EXCP,
 GET_ASI_DIRECT,
+GET_ASI_DTWINX,
 } ASIType;
 
 typedef struct {
@@ -2034,18 +2035,26 @@ static DisasASI get_asi(DisasContext *dc, int insn, 
TCGMemOp memop)
 switch (asi) {
 case ASI_N:  /* Nucleus */
 case ASI_NL: /* Nucleus LE */
+case ASI_TWINX_N:
+case ASI_TWINX_NL:
 mem_idx = MMU_NUCLEUS_IDX;
 break;
 case ASI_AIUP:  /* As if user primary */
 case ASI_AIUPL: /* As if user primary LE */
+case ASI_TWINX_AIUP:
+case ASI_TWINX_AIUP_L:
 mem_idx = MMU_USER_IDX;
 break;
 case ASI_AIUS:  /* As if user secondary */
 case ASI_AIUSL: /* As if user secondary LE */
+case ASI_TWINX_AIUS:
+case ASI_TWINX_AIUS_L:
 mem_idx = MMU_USER_SECONDARY_IDX;
 break;
 case ASI_S:  /* Secondary */
 case ASI_SL: /* Secondary LE */
+case ASI_TWINX_S:
+case ASI_TWINX_SL:
 if (mem_idx == MMU_USER_IDX) {
 mem_idx = MMU_USER_SECONDARY_IDX;
 } else if (mem_idx == MMU_KERNEL_IDX) {
@@ -2054,6 +2063,8 @@ static DisasASI get_asi(DisasContext *dc, int insn, 
TCGMemOp memop)
 break;
 case ASI_P:  /* Primary */
 case ASI_PL: /* Primary LE */
+case ASI_TWINX_P:
+case ASI_TWINX_PL:
 break;
 }
 switch (asi) {
@@ -2069,6 +2080,18 @@ static DisasASI get_asi(DisasContext *dc, int insn, 
TCGMemOp memop)
 case ASI_PL:
 type = GET_ASI_DIRECT;
 break;
+case ASI_TWINX_N:
+case ASI_TWINX_NL:
+case ASI_TWINX_AIUP:
+case ASI_TWINX_AIUP_L:
+case ASI_TWINX_AIUS:
+case ASI_TWINX_AIUS_L:
+case ASI_TWINX_P:
+case ASI_TWINX_PL:
+case ASI_TWINX_S:
+case ASI_TWINX_SL:
+type = GET_ASI_DTWINX;
+break;
 }
 /* The little-endian asis all have bit 3 set.  */
 if (asi & 8) {
@@ -2088,6 +2111,9 @@ static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv 
addr,
 switch (da.type) {
 case GET_ASI_EXCP:
 break;
+case GET_ASI_DTWINX: /* Reserved for ldda.  */
+gen_exception(dc, TT_ILL_INSN);
+break;
 case GET_ASI_DIRECT:
 tcg_gen_qemu_ld_tl(dst, addr, da.mem_idx, da.memop);
 break;
@@ -2124,6 +2150,9 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv 
addr,
 switch (da.type) {
 case GET_ASI_EXCP:
 break;
+case GET_ASI_DTWINX: /* Reserved for stda.  */
+gen_exception(dc, TT_ILL_INSN);
+break;
 case GET_ASI_DIRECT:
 tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop);
 break;
@@ -2289,32 +2318,57 @@ static void gen_stf_asi(DisasContext *dc, TCGv addr,
 }
 }
 
-static void gen_ldda_asi(DisasContext *dc, TCGv hi, TCGv addr,
- int insn, int rd)
+static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
 {
 DisasASI da = get_asi(dc, insn, MO_TEQ);
+TCGv_i64 hi = gen_dest_gpr(dc, rd);
+TCGv_i64 lo = gen_dest_gpr(dc, rd + 1);
 
 switch (da.type) {
 case GET_ASI_EXCP:
+return;
+
+case GET_ASI_DTWINX:
+gen_check_align(addr, 15);
+tcg_gen_qemu_ld_i64(hi, addr, da.mem_idx, da.memop);
+tcg_gen_addi_tl(addr, addr, 8);
+tcg_gen_qemu_ld_i64(lo, addr, da.mem_idx, da.memop);
 break;
+
+case GET_ASI_DIRECT:
+{
+TCGv_i64 tmp = tcg_temp_new_i64();
+
+tcg_gen_qemu_ld_i64(tmp, addr, da.mem_idx, da.memop);
+
+/* Note that LE ldda acts as if each 32-bit register
+   result is byte swapped.  Having just performed one
+   64-bit bswap, we need now to swap the writebacks.  */
+if ((da.memop & MO_BSWAP) == MO_TE) {
+tcg_gen_extr32_i64(lo, hi, tmp);
+} else {
+tcg_gen_extr32_i64(hi, lo, tmp);
+}
+tcg_temp_free_i64(tmp);
+}
+break;
+
 default:
 {
 TCGv_i32 r_asi = tcg_const_i32(da.asi);
-TCGv_i64 tmp;
 
 save_state(dc);
 gen_helper_ldda_asi(cpu_env, addr, r_asi);
 tcg_temp_free_i32(r_asi);
 
-tmp = gen_dest_gpr(dc, rd);
-tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUSPARCState, qt0.high));
-gen_store_gpr(dc, rd, tmp);
-tmp = gen_dest_gpr(dc, rd + 1);
-tcg_gen_ld_i64(tmp, cpu_env, 

[Qemu-devel] [PATCH 0/3] qapi: Easier unboxed visits of subset of union type

2016-02-23 Thread Eric Blake
Dan Berrange rightly pointed out that now that commit 544a373
unboxes the variants of unions, we will need a way for his pending
LUKS patches to access the fields of those variants without also
allocating wasted memory.

Patch 1 is a cleanup I noticed along the way, although in writing
this email, I now see it is only tangentially related.
Patch 2 provides the fix Dan needs, and patch 3 documents it,
along with other recent changes.

Note that this series has a conflict with my other pending series
(https://lists.gnu.org/archive/html/qemu-devel/2016-02/msg04703.html);
but as it is shorter and is blocking Dan's patches, it may be easier
to review these first.  Depending on which series lands first, I don't
mind posting a rebased version of the other series.

Also available as a tag at this location:
git fetch git://repo.or.cz/qemu/ericb.git qapi-exportv1

and will soon be part of my branch at:
http://repo.or.cz/qemu/ericb.git/shortlog/refs/heads/qapi

Eric Blake (3):
  qapi-dealloc: Reduce use outside of generated code
  qapi-visit: Expose visit_type_FOO_fields()
  qapi: Update docs to match recent generator changes

 scripts/qapi-visit.py |  47 ++-
 hw/acpi/core.c|  11 +-
 net/net.c |  31 ++---
 numa.c|   9 +-
 tests/test-opts-visitor.c |  10 +-
 docs/qapi-code-gen.txt| 308 --
 6 files changed, 188 insertions(+), 228 deletions(-)

-- 
2.5.0




[Qemu-devel] [PATCH v2 13/24] target-sparc: Use QT0 to return results from ldda

2016-02-23 Thread Richard Henderson
Also implement a few more twinx asis.

Signed-off-by: Richard Henderson 
---
 target-sparc/helper.h  |   2 +-
 target-sparc/ldst_helper.c | 156 -
 target-sparc/translate.c   |  12 +++-
 3 files changed, 120 insertions(+), 50 deletions(-)

diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index 14712cc..66abf83 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -17,7 +17,7 @@ DEF_HELPER_1(rdcwp, tl, env)
 DEF_HELPER_2(wrcwp, void, env, tl)
 DEF_HELPER_FLAGS_2(array8, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 DEF_HELPER_FLAGS_1(popc, TCG_CALL_NO_RWG_SE, tl, tl)
-DEF_HELPER_4(ldda_asi, void, env, tl, int, int)
+DEF_HELPER_FLAGS_3(ldda_asi, TCG_CALL_NO_WG, void, env, tl, int)
 DEF_HELPER_5(ldf_asi, void, env, tl, int, int, int)
 DEF_HELPER_FLAGS_5(stf_asi, TCG_CALL_NO_WG, void, env, tl, int, int, int)
 DEF_HELPER_FLAGS_5(casx_asi, TCG_CALL_NO_WG, tl, env, tl, tl, tl, i32)
diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 249923e..1eff8b4 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -1328,8 +1328,6 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
addr, int asi, int size,
 case ASI_S:  /* Secondary */
 case ASI_PL: /* Primary LE */
 case ASI_SL: /* Secondary LE */
-case ASI_BLK_INIT_QUAD_LDD_P: /* UA2007 Primary block init */
-case ASI_BLK_INIT_QUAD_LDD_S: /* UA2007 Secondary block init */
 if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
 if (cpu_hypervisor_mode(env)) {
 switch (size) {
@@ -1442,11 +1440,6 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
addr, int asi, int size,
 }
 break;
 }
-case ASI_NUCLEUS_QUAD_LDD:   /* Nucleus quad LDD 128 bit atomic */
-case ASI_NUCLEUS_QUAD_LDD_L: /* Nucleus quad LDD 128 bit atomic LE */
-/* Only ldda allowed */
-helper_raise_exception(env, TT_ILL_INSN);
-return 0;
 case ASI_N:  /* Nucleus */
 case ASI_NL: /* Nucleus Little Endian (LE) */
 {
@@ -1594,6 +1587,25 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
addr, int asi, int size,
 cpu_unassigned_access(cs, addr, false, false, 1, size);
 ret = 0;
 break;
+
+case ASI_NUCLEUS_QUAD_LDD:   /* Nucleus quad LDD 128 bit atomic */
+case ASI_NUCLEUS_QUAD_LDD_L: /* Nucleus quad LDD 128 bit atomic LE */
+case ASI_TWINX_AIUP:   /* As if user primary, twinx */
+case ASI_TWINX_AIUS:   /* As if user secondary, twinx */
+case ASI_TWINX_REAL:   /* Real address, twinx */
+case ASI_TWINX_AIUP_L: /* As if user primary, twinx, LE */
+case ASI_TWINX_AIUS_L: /* As if user secondary, twinx, LE */
+case ASI_TWINX_REAL_L: /* Real address, twinx, LE */
+case ASI_TWINX_N:  /* Nucleus, twinx */
+case ASI_TWINX_NL: /* Nucleus, twinx, LE */
+/* ??? From the UA2011 document; overlaps BLK_INIT_QUAD_LDD_* */
+case ASI_TWINX_P:  /* Primary, twinx */
+case ASI_TWINX_PL: /* Primary, twinx, LE */
+case ASI_TWINX_S:  /* Secondary, twinx */
+case ASI_TWINX_SL: /* Secondary, twinx, LE */
+/* These are all 128-bit atomic; only ldda (now ldtxa) allowed */
+helper_raise_exception(env, TT_ILL_INSN);
+return 0;
 }
 
 /* Convert from little endian */
@@ -1701,8 +1713,6 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, 
target_ulong val,
 case ASI_S:  /* Secondary */
 case ASI_PL: /* Primary LE */
 case ASI_SL: /* Secondary LE */
-case ASI_BLK_INIT_QUAD_LDD_P: /* UA2007 Primary block init */
-case ASI_BLK_INIT_QUAD_LDD_S: /* UA2007 Secondary block init */
 if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
 if (cpu_hypervisor_mode(env)) {
 switch (size) {
@@ -1815,11 +1825,6 @@ void helper_st_asi(CPUSPARCState *env, target_ulong 
addr, target_ulong val,
 }
 }
 return;
-case ASI_NUCLEUS_QUAD_LDD:   /* Nucleus quad LDD 128 bit atomic */
-case ASI_NUCLEUS_QUAD_LDD_L: /* Nucleus quad LDD 128 bit atomic LE */
-/* Only ldda allowed */
-helper_raise_exception(env, TT_ILL_INSN);
-return;
 case ASI_N:  /* Nucleus */
 case ASI_NL: /* Nucleus Little Endian (LE) */
 {
@@ -2000,6 +2005,24 @@ void helper_st_asi(CPUSPARCState *env, target_ulong 
addr, target_ulong val,
 case ASI_INTR_RECEIVE: /* Interrupt data receive */
 env->ivec_status = val & 0x20;
 return;
+case ASI_NUCLEUS_QUAD_LDD:   /* Nucleus quad LDD 128 bit atomic */
+case ASI_NUCLEUS_QUAD_LDD_L: /* Nucleus quad LDD 128 bit atomic LE */
+case ASI_TWINX_AIUP:   /* As if user primary, twinx */
+case ASI_TWINX_AIUS:   /* As if user secondary, twinx */
+case ASI_TWINX_REAL:   /* Real address, twinx */
+case ASI_TWINX_AIUP_L: /* As if user primary, twinx, LE */
+case ASI_TWINX_AIUS_L: /* As if user secondary, twinx, LE */
+

[Qemu-devel] [PATCH v2 24/24] target-sparc: Elide duplicate updates to fprs

2016-02-23 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-sparc/translate.c | 45 +++--
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 688594d..e296dca 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -81,6 +81,7 @@ typedef struct DisasContext {
 int n_t32;
 int n_ttl;
 #ifdef TARGET_SPARC64
+int fprs_dirty;
 int asi;
 #endif
 } DisasContext;
@@ -138,10 +139,16 @@ static inline TCGv get_temp_tl(DisasContext *dc)
 return t;
 }
 
-static inline void gen_update_fprs_dirty(int rd)
+static inline void gen_update_fprs_dirty(DisasContext *dc, int rd)
 {
 #if defined(TARGET_SPARC64)
-tcg_gen_ori_i32(cpu_fprs, cpu_fprs, (rd < 32) ? 1 : 2);
+int bit = (rd < 32) ? 1 : 2;
+/* If we know we've already set this bit within the TB,
+   we can avoid setting it again.  */
+if (!(dc->fprs_dirty & bit)) {
+dc->fprs_dirty |= bit;
+tcg_gen_ori_i32(cpu_fprs, cpu_fprs, bit);
+}
 #endif
 }
 
@@ -183,7 +190,7 @@ static void gen_store_fpr_F(DisasContext *dc, unsigned int 
dst, TCGv_i32 v)
 tcg_gen_deposit_i64(cpu_fpr[dst / 2], cpu_fpr[dst / 2], t,
 (dst & 1 ? 0 : 32), 32);
 #endif
-gen_update_fprs_dirty(dst);
+gen_update_fprs_dirty(dc, dst);
 }
 
 static TCGv_i32 gen_dest_fpr_F(DisasContext *dc)
@@ -201,7 +208,7 @@ static void gen_store_fpr_D(DisasContext *dc, unsigned int 
dst, TCGv_i64 v)
 {
 dst = DFPREG(dst);
 tcg_gen_mov_i64(cpu_fpr[dst / 2], v);
-gen_update_fprs_dirty(dst);
+gen_update_fprs_dirty(dc, dst);
 }
 
 static TCGv_i64 gen_dest_fpr_D(DisasContext *dc, unsigned int dst)
@@ -234,14 +241,14 @@ static void gen_op_store_QT0_fpr(unsigned int dst)
 }
 
 #ifdef TARGET_SPARC64
-static void gen_move_Q(unsigned int rd, unsigned int rs)
+static void gen_move_Q(DisasContext *dc, unsigned int rd, unsigned int rs)
 {
 rd = QFPREG(rd);
 rs = QFPREG(rs);
 
 tcg_gen_mov_i64(cpu_fpr[rd / 2], cpu_fpr[rs / 2]);
 tcg_gen_mov_i64(cpu_fpr[rd / 2 + 1], cpu_fpr[rs / 2 + 1]);
-gen_update_fprs_dirty(rd);
+gen_update_fprs_dirty(dc, rd);
 }
 #endif
 
@@ -1822,7 +1829,7 @@ static inline void gen_fop_QQ(DisasContext *dc, int rd, 
int rs,
 gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
 gen_op_store_QT0_fpr(QFPREG(rd));
-gen_update_fprs_dirty(QFPREG(rd));
+gen_update_fprs_dirty(dc, QFPREG(rd));
 }
 
 #ifdef TARGET_SPARC64
@@ -1834,7 +1841,7 @@ static inline void gen_ne_fop_QQ(DisasContext *dc, int 
rd, int rs,
 gen(cpu_env);
 
 gen_op_store_QT0_fpr(QFPREG(rd));
-gen_update_fprs_dirty(QFPREG(rd));
+gen_update_fprs_dirty(dc, QFPREG(rd));
 }
 #endif
 
@@ -1848,7 +1855,7 @@ static inline void gen_fop_QQQ(DisasContext *dc, int rd, 
int rs1, int rs2,
 gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
 gen_op_store_QT0_fpr(QFPREG(rd));
-gen_update_fprs_dirty(QFPREG(rd));
+gen_update_fprs_dirty(dc, QFPREG(rd));
 }
 
 static inline void gen_fop_DFF(DisasContext *dc, int rd, int rs1, int rs2,
@@ -1879,7 +1886,7 @@ static inline void gen_fop_QDD(DisasContext *dc, int rd, 
int rs1, int rs2,
 gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
 gen_op_store_QT0_fpr(QFPREG(rd));
-gen_update_fprs_dirty(QFPREG(rd));
+gen_update_fprs_dirty(dc, QFPREG(rd));
 }
 
 #ifdef TARGET_SPARC64
@@ -1966,7 +1973,7 @@ static inline void gen_ne_fop_QF(DisasContext *dc, int 
rd, int rs,
 gen(cpu_env, src);
 
 gen_op_store_QT0_fpr(QFPREG(rd));
-gen_update_fprs_dirty(QFPREG(rd));
+gen_update_fprs_dirty(dc, QFPREG(rd));
 }
 
 static inline void gen_ne_fop_QD(DisasContext *dc, int rd, int rs,
@@ -1979,7 +1986,7 @@ static inline void gen_ne_fop_QD(DisasContext *dc, int 
rd, int rs,
 gen(cpu_env, src);
 
 gen_op_store_QT0_fpr(QFPREG(rd));
-gen_update_fprs_dirty(QFPREG(rd));
+gen_update_fprs_dirty(dc, QFPREG(rd));
 }
 
 /* asi moves */
@@ -2749,7 +2756,7 @@ static void gen_fmovq(DisasContext *dc, DisasCompare 
*cmp, int rd, int rs)
 tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2 + 1], cmp->c1, cmp->c2,
 cpu_fpr[qs / 2 + 1], cpu_fpr[qd / 2 + 1]);
 
-gen_update_fprs_dirty(qd);
+gen_update_fprs_dirty(dc, qd);
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -3547,7 +3554,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned 
int insn)
 break;
 case 0x3: /* V9 fmovq */
 CHECK_FPU_FEATURE(dc, FLOAT128);
-gen_move_Q(rd, rs2);
+gen_move_Q(dc, rd, rs2);
 break;
 case 0x6: /* V9 fnegd */
 gen_ne_fop_DD(dc, rd, rs2, gen_helper_fnegd);
@@ -4097,6 +4104,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned 
int insn)
 case 0x6: /* V9 wrfprs */
 tcg_gen_xor_tl(cpu_tmp0, 

[Qemu-devel] [PATCH v2 12/24] target-sparc: Directly implement easy ld/st asis

2016-02-23 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-sparc/translate.c | 102 ---
 1 file changed, 88 insertions(+), 14 deletions(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 44091ee..fda7b75 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1968,17 +1968,21 @@ static inline void gen_ne_fop_QD(DisasContext *dc, int 
rd, int rs,
 typedef enum {
 GET_ASI_HELPER,
 GET_ASI_EXCP,
+GET_ASI_DIRECT,
 } ASIType;
 
 typedef struct {
 ASIType type;
 int asi;
+int mem_idx;
+TCGMemOp memop;
 } DisasASI;
 
-static DisasASI get_asi(DisasContext *dc, int insn)
+static DisasASI get_asi(DisasContext *dc, int insn, TCGMemOp memop)
 {
 int asi = GET_FIELD(insn, 19, 26);
 ASIType type = GET_ASI_HELPER;
+int mem_idx = dc->mem_idx;
 
 #ifndef TARGET_SPARC64
 /* Before v9, all asis are immediate and privileged.  */
@@ -1992,6 +1996,16 @@ static DisasASI get_asi(DisasContext *dc, int insn)
   for LEON, which is incorrect.  */
|| (asi == ASI_USERDATA
&& (dc->def->features & CPU_FEATURE_CASA))) {
+switch (asi) {
+case ASI_USERDATA:   /* User data access */
+mem_idx = MMU_USER_IDX;
+type = GET_ASI_DIRECT;
+break;
+case ASI_KERNELDATA: /* Supervisor data access */
+mem_idx = MMU_KERNEL_IDX;
+type = GET_ASI_DIRECT;
+break;
+}
 } else {
 gen_exception(dc, TT_PRIV_INSN);
 type = GET_ASI_EXCP;
@@ -2000,19 +2014,76 @@ static DisasASI get_asi(DisasContext *dc, int insn)
 if (IS_IMM) {
 asi = dc->asi;
 }
+/* With v9, all asis below 0x80 are privileged.  */
+/* ??? We ought to check cpu_has_hypervisor, but we didn't copy
+   down that bit into DisasContext.  For the moment that's ok,
+   since the direct implementations below doesn't have any ASIs
+   in the restricted [0x30, 0x7f] range, and the check will be
+   done properly in the helper.  */
+if (!supervisor(dc) && asi < 0x80) {
+gen_exception(dc, TT_PRIV_ACT);
+type = GET_ASI_EXCP;
+} else {
+switch (asi) {
+case ASI_N:  /* Nucleus */
+case ASI_NL: /* Nucleus LE */
+mem_idx = MMU_NUCLEUS_IDX;
+break;
+case ASI_AIUP:  /* As if user primary */
+case ASI_AIUPL: /* As if user primary LE */
+mem_idx = MMU_USER_IDX;
+break;
+case ASI_AIUS:  /* As if user secondary */
+case ASI_AIUSL: /* As if user secondary LE */
+mem_idx = MMU_USER_SECONDARY_IDX;
+break;
+case ASI_S:  /* Secondary */
+case ASI_SL: /* Secondary LE */
+if (mem_idx == MMU_USER_IDX) {
+mem_idx = MMU_USER_SECONDARY_IDX;
+} else if (mem_idx == MMU_KERNEL_IDX) {
+mem_idx = MMU_KERNEL_SECONDARY_IDX;
+}
+break;
+case ASI_P:  /* Primary */
+case ASI_PL: /* Primary LE */
+break;
+}
+switch (asi) {
+case ASI_N:
+case ASI_NL:
+case ASI_AIUP:
+case ASI_AIUPL:
+case ASI_AIUS:
+case ASI_AIUSL:
+case ASI_S:
+case ASI_SL:
+case ASI_P:
+case ASI_PL:
+type = GET_ASI_DIRECT;
+break;
+}
+/* The little-endian asis all have bit 3 set.  */
+if (asi & 8) {
+memop ^= MO_BSWAP;
+}
+}
 #endif
 
-return (DisasASI){ type, asi };
+return (DisasASI){ type, asi, mem_idx, memop };
 }
 
 static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr,
int insn, TCGMemOp memop)
 {
-DisasASI da = get_asi(dc, insn);
+DisasASI da = get_asi(dc, insn, memop);
 
 switch (da.type) {
 case GET_ASI_EXCP:
 break;
+case GET_ASI_DIRECT:
+tcg_gen_qemu_ld_tl(dst, addr, da.mem_idx, da.memop);
+break;
 default:
 {
 TCGv_i32 r_asi = tcg_const_i32(da.asi);
@@ -2041,11 +2112,14 @@ static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv 
addr,
 static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
int insn, TCGMemOp memop)
 {
-DisasASI da = get_asi(dc, insn);
+DisasASI da = get_asi(dc, insn, memop);
 
 switch (da.type) {
 case GET_ASI_EXCP:
 break;
+case GET_ASI_DIRECT:
+tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop);
+break;
 default:
 {
 TCGv_i32 r_asi = tcg_const_i32(da.asi);
@@ -2075,7 +2149,7 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv 
addr,
 static void gen_swap_asi(DisasContext *dc, TCGv dst, TCGv src,
  TCGv addr, int insn)
 {
-DisasASI da = get_asi(dc, insn);
+DisasASI da = get_asi(dc, insn, MO_TEUL);
 
 switch (da.type) {

[Qemu-devel] [PATCH v2 22/24] target-sparc: Use cpu_fsr in stfsr

2016-02-23 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-sparc/translate.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index ab5b0b6..5874571 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5359,17 +5359,14 @@ static void disas_sparc_insn(DisasContext * dc, 
unsigned int insn)
 break;
 case 0x25: /* stfsr, V9 stxfsr */
 {
-TCGv t = get_temp_tl(dc);
-
-tcg_gen_ld_tl(t, cpu_env, offsetof(CPUSPARCState, 
fsr));
 #ifdef TARGET_SPARC64
 gen_address_mask(dc, cpu_addr);
 if (rd == 1) {
-tcg_gen_qemu_st64(t, cpu_addr, dc->mem_idx);
+tcg_gen_qemu_st64(cpu_fsr, cpu_addr, dc->mem_idx);
 break;
 }
 #endif
-tcg_gen_qemu_st32(t, cpu_addr, dc->mem_idx);
+tcg_gen_qemu_st32(cpu_fsr, cpu_addr, dc->mem_idx);
 }
 break;
 case 0x26:
-- 
2.5.0




[Qemu-devel] [PATCH 2/3] qapi-visit: Expose visit_type_FOO_fields()

2016-02-23 Thread Eric Blake
Dan Berrange reported a case where he needs to work with a
QCryptoBlockOptions union type using the OptsVisitor, but only
visit one of the branches of that type (the discriminator is not
visited directly, but learned externally).  When things were
boxed, it was easy: just visit the variant directly, which took
care of both allocating the variant and visiting its fields.  But
now that things are unboxed, we need a way to visit the fields
without allocation, done by exposing visit_type_FOO_fields() to
the user.  Of course, this should only be done for objects, not
lists, so we need another flag to gen_visit_decl().

Since the function is now public, we no longer need to preserve
topological ordering via struct_fields_seen.

Signed-off-by: Eric Blake 

---
Minor conflicts with pending series "qapi implicit types"; I can
rebase whichever series gets reviewed second.
---
 scripts/qapi-visit.py | 47 +--
 1 file changed, 13 insertions(+), 34 deletions(-)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 2308268..35efe7c 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -15,52 +15,33 @@
 from qapi import *
 import re

-# visit_type_FOO_fields() is always emitted; track if a forward declaration
-# or implementation has already been output.
-struct_fields_seen = set()

-
-def gen_visit_decl(name, scalar=False):
+def gen_visit_decl(name, scalar=False, list=False):
+ret = ''
 c_type = c_name(name) + ' *'
 if not scalar:
+if not list:
+ret += mcgen('''
+void visit_type_%(c_name)s_fields(Visitor *v, %(c_type)sobj, Error **errp);
+''',
+ c_name=c_name(name), c_type=c_type)
 c_type += '*'
-return mcgen('''
+ret += mcgen('''
 void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_type)sobj, Error 
**errp);
 ''',
  c_name=c_name(name), c_type=c_type)
-
-
-def gen_visit_fields_decl(typ):
-if typ.name in struct_fields_seen:
-return ''
-struct_fields_seen.add(typ.name)
-return mcgen('''
-
-static void visit_type_%(c_type)s_fields(Visitor *v, %(c_type)s *obj, Error 
**errp);
-''',
- c_type=typ.c_name())
+return ret


 def gen_visit_struct_fields(name, base, members, variants):
-ret = ''
+ret = mcgen('''

-if base:
-ret += gen_visit_fields_decl(base)
-if variants:
-for var in variants.variants:
-# Ugly special case for simple union TODO get rid of it
-if not var.simple_union_type():
-ret += gen_visit_fields_decl(var.type)
-
-struct_fields_seen.add(name)
-ret += mcgen('''
-
-static void visit_type_%(c_name)s_fields(Visitor *v, %(c_name)s *obj, Error 
**errp)
+void visit_type_%(c_name)s_fields(Visitor *v, %(c_name)s *obj, Error **errp)
 {
 Error *err = NULL;

 ''',
- c_name=c_name(name))
+c_name=c_name(name))

 if base:
 ret += mcgen('''
@@ -173,8 +154,6 @@ def gen_visit_alternate(name, variants):
 for var in variants.variants:
 if var.type.alternate_qtype() == 'QTYPE_QINT':
 promote_int = 'false'
-if isinstance(var.type, QAPISchemaObjectType):
-ret += gen_visit_fields_decl(var.type)

 ret += mcgen('''

@@ -305,7 +284,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
 self.defn += gen_visit_enum(name)

 def visit_array_type(self, name, info, element_type):
-decl = gen_visit_decl(name)
+decl = gen_visit_decl(name, list=True)
 defn = gen_visit_list(name, element_type)
 if isinstance(element_type, QAPISchemaBuiltinType):
 self._btin += decl
-- 
2.5.0




[Qemu-devel] [PATCH v2 08/24] target-sparc: Pass TCGMemOp to gen_ld/st_asi

2016-02-23 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-sparc/translate.c | 32 
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index c9ec885..c1cb1e1 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -2004,7 +2004,7 @@ static DisasASI get_asi(DisasContext *dc, int insn)
 }
 
 static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr,
-   int insn, int size, int sign)
+   int insn, TCGMemOp memop)
 {
 DisasASI da = get_asi(dc, insn);
 
@@ -2014,8 +2014,8 @@ static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv 
addr,
 default:
 {
 TCGv_i32 r_asi = tcg_const_i32(da.asi);
-TCGv_i32 r_size = tcg_const_i32(size);
-TCGv_i32 r_sign = tcg_const_i32(sign);
+TCGv_i32 r_size = tcg_const_i32(1 << (memop & MO_SIZE));
+TCGv_i32 r_sign = tcg_const_i32(!!(memop & MO_SIGN));
 
 save_state(dc);
 #ifdef TARGET_SPARC64
@@ -2037,7 +2037,7 @@ static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv 
addr,
 }
 
 static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
-   int insn, int size)
+   int insn, TCGMemOp memop)
 {
 DisasASI da = get_asi(dc, insn);
 
@@ -2047,7 +2047,7 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv 
addr,
 default:
 {
 TCGv_i32 r_asi = tcg_const_i32(da.asi);
-TCGv_i32 r_size = tcg_const_i32(size);
+TCGv_i32 r_size = tcg_const_i32(1 << (memop & MO_SIZE));
 
 save_state(dc);
 #ifdef TARGET_SPARC64
@@ -4815,13 +4815,13 @@ static void disas_sparc_insn(DisasContext * dc, 
unsigned int insn)
 break;
 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
 case 0x10:  /* lda, V9 lduwa, load word alternate */
-gen_ld_asi(dc, cpu_val, cpu_addr, insn, 4, 0);
+gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
 break;
 case 0x11:  /* lduba, load unsigned byte alternate */
-gen_ld_asi(dc, cpu_val, cpu_addr, insn, 1, 0);
+gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_UB);
 break;
 case 0x12:  /* lduha, load unsigned halfword alternate */
-gen_ld_asi(dc, cpu_val, cpu_addr, insn, 2, 0);
+gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUW);
 break;
 case 0x13:  /* ldda, load double word alternate */
 if (rd & 1) {
@@ -4830,10 +4830,10 @@ static void disas_sparc_insn(DisasContext * dc, 
unsigned int insn)
 gen_ldda_asi(dc, cpu_val, cpu_addr, insn, rd);
 goto skip_move;
 case 0x19:  /* ldsba, load signed byte alternate */
-gen_ld_asi(dc, cpu_val, cpu_addr, insn, 1, 1);
+gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_SB);
 break;
 case 0x1a:  /* ldsha, load signed halfword alternate */
-gen_ld_asi(dc, cpu_val, cpu_addr, insn, 2, 1);
+gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESW);
 break;
 case 0x1d:  /* ldstuba -- XXX: should be atomically */
 gen_ldstub_asi(dc, cpu_val, cpu_addr, insn);
@@ -4862,10 +4862,10 @@ static void disas_sparc_insn(DisasContext * dc, 
unsigned int insn)
 tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
 break;
 case 0x18: /* V9 ldswa */
-gen_ld_asi(dc, cpu_val, cpu_addr, insn, 4, 1);
+gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESL);
 break;
 case 0x1b: /* V9 ldxa */
-gen_ld_asi(dc, cpu_val, cpu_addr, insn, 8, 0);
+gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEQ);
 break;
 case 0x2d: /* V9 prefetch, no effect */
 goto skip_move;
@@ -4997,13 +4997,13 @@ static void disas_sparc_insn(DisasContext * dc, 
unsigned int insn)
 break;
 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
 case 0x14: /* sta, V9 stwa, store word alternate */
-gen_st_asi(dc, cpu_val, cpu_addr, insn, 4);
+gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
 break;
 case 0x15: /* stba, store byte alternate */
-gen_st_asi(dc, cpu_val, cpu_addr, insn, 1);
+gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_UB);
 break;
 case 0x16: /* stha, store halfword alternate */
-gen_st_asi(dc, cpu_val, cpu_addr, 

[Qemu-devel] [PATCH v2 18/24] target-sparc: Directly implement easy ldf/stf asis

2016-02-23 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-sparc/translate.c | 43 +++
 1 file changed, 43 insertions(+)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index a023754..0621c06 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -2268,10 +2268,32 @@ static void gen_ldf_asi(DisasContext *dc, TCGv addr,
 int insn, int size, int rd)
 {
 DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEQ));
+TCGv_i32 d32;
 
 switch (da.type) {
 case GET_ASI_EXCP:
 break;
+
+case GET_ASI_DIRECT:
+switch (size) {
+case 4:
+d32 = gen_dest_fpr_F(dc);
+tcg_gen_qemu_ld_i32(d32, addr, da.mem_idx, da.memop);
+gen_store_fpr_F(dc, rd, d32);
+break;
+case 8:
+tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
+break;
+case 16:
+tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
+tcg_gen_addi_tl(addr, addr, 8);
+tcg_gen_qemu_ld_i64(cpu_fpr[rd/2+1], addr, da.mem_idx, da.memop);
+break;
+default:
+g_assert_not_reached();
+}
+break;
+
 default:
 {
 TCGv_i32 r_asi = tcg_const_i32(da.asi);
@@ -2292,10 +2314,31 @@ static void gen_stf_asi(DisasContext *dc, TCGv addr,
 int insn, int size, int rd)
 {
 DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEQ));
+TCGv_i32 d32;
 
 switch (da.type) {
 case GET_ASI_EXCP:
 break;
+
+case GET_ASI_DIRECT:
+switch (size) {
+case 4:
+d32 = gen_load_fpr_F(dc, rd);
+tcg_gen_qemu_st_i32(d32, addr, da.mem_idx, da.memop);
+break;
+case 8:
+tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
+break;
+case 16:
+tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
+tcg_gen_addi_tl(addr, addr, 8);
+tcg_gen_qemu_st_i64(cpu_fpr[rd/2+1], addr, da.mem_idx, da.memop);
+break;
+default:
+g_assert_not_reached();
+}
+break;
+
 default:
 {
 TCGv_i32 r_asi = tcg_const_i32(da.asi);
-- 
2.5.0




[Qemu-devel] [PATCH v2 19/24] target-sparc: Directly implement block and short ldf/stf asis

2016-02-23 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-sparc/translate.c | 106 +++
 1 file changed, 106 insertions(+)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 0621c06..017c3c1 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1977,6 +1977,8 @@ typedef enum {
 GET_ASI_EXCP,
 GET_ASI_DIRECT,
 GET_ASI_DTWINX,
+GET_ASI_BLOCK,
+GET_ASI_SHORT,
 } ASIType;
 
 typedef struct {
@@ -2043,18 +2045,32 @@ static DisasASI get_asi(DisasContext *dc, int insn, 
TCGMemOp memop)
 case ASI_AIUPL: /* As if user primary LE */
 case ASI_TWINX_AIUP:
 case ASI_TWINX_AIUP_L:
+case ASI_BLK_AIUP_4V:
+case ASI_BLK_AIUP_L_4V:
+case ASI_BLK_AIUP:
+case ASI_BLK_AIUPL:
 mem_idx = MMU_USER_IDX;
 break;
 case ASI_AIUS:  /* As if user secondary */
 case ASI_AIUSL: /* As if user secondary LE */
 case ASI_TWINX_AIUS:
 case ASI_TWINX_AIUS_L:
+case ASI_BLK_AIUS_4V:
+case ASI_BLK_AIUS_L_4V:
+case ASI_BLK_AIUS:
+case ASI_BLK_AIUSL:
 mem_idx = MMU_USER_SECONDARY_IDX;
 break;
 case ASI_S:  /* Secondary */
 case ASI_SL: /* Secondary LE */
 case ASI_TWINX_S:
 case ASI_TWINX_SL:
+case ASI_BLK_S:
+case ASI_BLK_SL:
+case ASI_FL8_S:
+case ASI_FL8_SL:
+case ASI_FL16_S:
+case ASI_FL16_SL:
 if (mem_idx == MMU_USER_IDX) {
 mem_idx = MMU_USER_SECONDARY_IDX;
 } else if (mem_idx == MMU_KERNEL_IDX) {
@@ -2065,6 +2081,12 @@ static DisasASI get_asi(DisasContext *dc, int insn, 
TCGMemOp memop)
 case ASI_PL: /* Primary LE */
 case ASI_TWINX_P:
 case ASI_TWINX_PL:
+case ASI_BLK_P:
+case ASI_BLK_PL:
+case ASI_FL8_P:
+case ASI_FL8_PL:
+case ASI_FL16_P:
+case ASI_FL16_PL:
 break;
 }
 switch (asi) {
@@ -2092,6 +2114,34 @@ static DisasASI get_asi(DisasContext *dc, int insn, 
TCGMemOp memop)
 case ASI_TWINX_SL:
 type = GET_ASI_DTWINX;
 break;
+case ASI_BLK_AIUP_4V:
+case ASI_BLK_AIUP_L_4V:
+case ASI_BLK_AIUP:
+case ASI_BLK_AIUPL:
+case ASI_BLK_AIUS_4V:
+case ASI_BLK_AIUS_L_4V:
+case ASI_BLK_AIUS:
+case ASI_BLK_AIUSL:
+case ASI_BLK_S:
+case ASI_BLK_SL:
+case ASI_BLK_P:
+case ASI_BLK_PL:
+type = GET_ASI_BLOCK;
+break;
+case ASI_FL8_S:
+case ASI_FL8_SL:
+case ASI_FL8_P:
+case ASI_FL8_PL:
+memop = MO_UB;
+type = GET_ASI_SHORT;
+break;
+case ASI_FL16_S:
+case ASI_FL16_SL:
+case ASI_FL16_P:
+case ASI_FL16_PL:
+memop = MO_TEUW;
+type = GET_ASI_SHORT;
+break;
 }
 /* The little-endian asis all have bit 3 set.  */
 if (asi & 8) {
@@ -2294,6 +2344,34 @@ static void gen_ldf_asi(DisasContext *dc, TCGv addr,
 }
 break;
 
+case GET_ASI_BLOCK:
+/* Valid for lddfa on aligned registers only.  */
+if (size == 8 && (rd & 7) == 0) {
+int i;
+
+gen_check_align(addr, 0x3f);
+for (i = 0; ; ++i) {
+tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2 + i], addr,
+da.mem_idx, da.memop);
+if (i == 7) {
+break;
+}
+tcg_gen_addi_tl(addr, addr, 8);
+}
+} else {
+gen_exception(dc, TT_ILL_INSN);
+}
+break;
+
+case GET_ASI_SHORT:
+/* Valid for lddfa only.  */
+if (size == 8) {
+tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
+} else {
+gen_exception(dc, TT_ILL_INSN);
+}
+break;
+
 default:
 {
 TCGv_i32 r_asi = tcg_const_i32(da.asi);
@@ -2339,6 +2417,34 @@ static void gen_stf_asi(DisasContext *dc, TCGv addr,
 }
 break;
 
+case GET_ASI_BLOCK:
+/* Valid for stdfa on aligned registers only.  */
+if (size == 8 && (rd & 7) == 0) {
+int i;
+
+gen_check_align(addr, 0x3f);
+for (i = 0; ; ++i) {
+tcg_gen_qemu_st_i64(cpu_fpr[rd / 2 + i], addr,
+da.mem_idx, da.memop);
+if (i == 7) {
+break;
+}
+tcg_gen_addi_tl(addr, addr, 8);
+}
+} else {
+gen_exception(dc, TT_ILL_INSN);
+}
+break;
+
+case GET_ASI_SHORT:
+/* Valid for stdfa only.  */
+if (size == 8) {
+tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx, 

[Qemu-devel] [PATCH v2 10/24] target-sparc: Add UA2005 defines to asi.h

2016-02-23 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-sparc/asi.h | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/target-sparc/asi.h b/target-sparc/asi.h
index aace6f3..c9a1849 100644
--- a/target-sparc/asi.h
+++ b/target-sparc/asi.h
@@ -144,24 +144,36 @@
  * ASIs, "(4V)" designates SUN4V specific ASIs.  "(NG4)" designates SPARC-T4
  * and later ASIs.
  */
+#define ASI_REAL0x14 /* Real address, cachable  */
 #define ASI_PHYS_USE_EC0x14 /* PADDR, E-cachable   
*/
+#define ASI_REAL_IO 0x15 /* Real address, non-cachable  */
 #define ASI_PHYS_BYPASS_EC_E   0x15 /* PADDR, E-bit*/
 #define ASI_BLK_AIUP_4V0x16 /* (4V) Prim, user, block ld/st
*/
 #define ASI_BLK_AIUS_4V0x17 /* (4V) Sec, user, block ld/st 
*/
+#define ASI_REAL_L  0x1c /* Real address, cachable, LE  */
 #define ASI_PHYS_USE_EC_L  0x1c /* PADDR, E-cachable, little endian*/
+#define ASI_REAL_IO_L   0x1d /* Real address, non-cachable, LE  */
 #define ASI_PHYS_BYPASS_EC_E_L 0x1d /* PADDR, E-bit, little endian */
 #define ASI_BLK_AIUP_L_4V  0x1e /* (4V) Prim, user, block, l-endian*/
 #define ASI_BLK_AIUS_L_4V  0x1f /* (4V) Sec, user, block, l-endian */
 #define ASI_SCRATCHPAD 0x20 /* (4V) Scratch Pad Registers  */
 #define ASI_MMU0x21 /* (4V) MMU Context Registers  
*/
+#define ASI_TWINX_AIUP  0x22 /* twin load, primary user */
+#define ASI_TWINX_AIUS  0x23 /* twin load, secondary user   */
 #define ASI_BLK_INIT_QUAD_LDD_AIUS 0x23 /* (NG) init-store, twin load,
 * secondary, user
 */
 #define ASI_NUCLEUS_QUAD_LDD   0x24 /* Cachable, qword load*/
 #define ASI_QUEUE  0x25 /* (4V) Interrupt Queue Registers  */
+#define ASI_TWINX_REAL  0x26 /* twin load, real, cachable   */
 #define ASI_QUAD_LDD_PHYS_4V   0x26 /* (4V) Physical, qword load   */
+#define ASI_TWINX_N 0x27 /* twin load, nucleus  */
+#define ASI_TWINX_AIUP_L0x2a /* twin load, primary user, LE */
+#define ASI_TWINX_AIUS_L0x2b /* twin load, secondary user, LE   */
 #define ASI_NUCLEUS_QUAD_LDD_L 0x2c /* Cachable, qword load, l-endian  */
+#define ASI_TWINX_REAL_L0x2e /* twin load, real, cachable, LE   */
 #define ASI_QUAD_LDD_PHYS_L_4V 0x2e /* (4V) Phys, qword load, l-endian */
+#define ASI_TWINX_NL0x2f /* twin load, nucleus, LE  */
 #define ASI_PCACHE_DATA_STATUS 0x30 /* (III) PCache data stat RAM diag */
 #define ASI_PCACHE_DATA0x31 /* (III) PCache data RAM diag  
*/
 #define ASI_PCACHE_TAG 0x32 /* (III) PCache tag RAM diag   */
@@ -267,12 +279,14 @@
 #define ASI_FL16_SL0xdb /* Secondary, 1 16-bit, fpu ld/st,L*/
 #define ASI_BLK_COMMIT_P   0xe0 /* Primary, blk store commit   */
 #define ASI_BLK_COMMIT_S   0xe1 /* Secondary, blk store commit */
+#define ASI_TWINX_P 0xe2 /* twin load, primary implicit */
 #define ASI_BLK_INIT_QUAD_LDD_P0xe2 /* (NG) init-store, twin load,
- * primary, implicit
- */
+ * primary, implicit */
+#define ASI_TWINX_S 0xe3 /* twin load, secondary implicit   */
 #define ASI_BLK_INIT_QUAD_LDD_S0xe3 /* (NG) init-store, twin load,
- * secondary, implicit
- */
+ * secondary, implicit */
+#define ASI_TWINX_PL0xea /* twin load, primary implicit, LE */
+#define ASI_TWINX_SL0xeb /* twin load, secondary implicit, LE */
 #define ASI_BLK_P  0xf0 /* Primary, blk ld/st  */
 #define ASI_BLK_S  0xf1 /* Secondary, blk ld/st*/
 #define ASI_ST_BLKINIT_MRU_P   0xf2 /* (NG4) init-store, twin load,
-- 
2.5.0




[Qemu-devel] [PATCH v2 01/24] target-sparc: Mark more flags for helpers

2016-02-23 Thread Richard Henderson
Quite a few helpers do not modify tcg globals but did not so indicate.

Signed-off-by: Richard Henderson 
---
 target-sparc/helper.h | 48 
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index 4374f0d..366d4d1 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -4,34 +4,34 @@ DEF_HELPER_2(wrpsr, void, env, tl)
 DEF_HELPER_1(rdpsr, tl, env)
 DEF_HELPER_1(power_down, void, env)
 #else
-DEF_HELPER_2(wrpil, void, env, tl)
+DEF_HELPER_FLAGS_2(wrpil, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_2(wrpstate, void, env, tl)
 DEF_HELPER_1(done, void, env)
 DEF_HELPER_1(retry, void, env)
-DEF_HELPER_1(flushw, void, env)
-DEF_HELPER_1(saved, void, env)
-DEF_HELPER_1(restored, void, env)
+DEF_HELPER_FLAGS_1(flushw, TCG_CALL_NO_WG, void, env)
+DEF_HELPER_FLAGS_1(saved, TCG_CALL_NO_RWG, void, env)
+DEF_HELPER_FLAGS_1(restored, TCG_CALL_NO_RWG, void, env)
 DEF_HELPER_1(rdccr, tl, env)
 DEF_HELPER_2(wrccr, void, env, tl)
 DEF_HELPER_1(rdcwp, tl, env)
 DEF_HELPER_2(wrcwp, void, env, tl)
 DEF_HELPER_FLAGS_2(array8, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_1(popc, tl, tl)
+DEF_HELPER_FLAGS_1(popc, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_4(ldda_asi, void, env, tl, int, int)
 DEF_HELPER_5(ldf_asi, void, env, tl, int, int, int)
-DEF_HELPER_5(stf_asi, void, env, tl, int, int, int)
-DEF_HELPER_5(casx_asi, tl, env, tl, tl, tl, i32)
+DEF_HELPER_FLAGS_5(stf_asi, TCG_CALL_NO_WG, void, env, tl, int, int, int)
+DEF_HELPER_FLAGS_5(casx_asi, TCG_CALL_NO_WG, tl, env, tl, tl, tl, i32)
 DEF_HELPER_2(set_softint, void, env, i64)
 DEF_HELPER_2(clear_softint, void, env, i64)
 DEF_HELPER_2(write_softint, void, env, i64)
-DEF_HELPER_2(tick_set_count, void, ptr, i64)
-DEF_HELPER_3(tick_get_count, i64, env, ptr, int)
-DEF_HELPER_2(tick_set_limit, void, ptr, i64)
+DEF_HELPER_FLAGS_2(tick_set_count, TCG_CALL_NO_RWG, void, ptr, i64)
+DEF_HELPER_FLAGS_3(tick_get_count, TCG_CALL_NO_WG, i64, env, ptr, int)
+DEF_HELPER_FLAGS_2(tick_set_limit, TCG_CALL_NO_RWG, void, ptr, i64)
 #endif
 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
-DEF_HELPER_5(cas_asi, tl, env, tl, tl, tl, i32)
+DEF_HELPER_FLAGS_5(cas_asi, TCG_CALL_NO_WG, tl, env, tl, tl, tl, i32)
 #endif
-DEF_HELPER_3(check_align, void, env, tl, i32)
+DEF_HELPER_FLAGS_3(check_align, TCG_CALL_NO_WG, void, env, tl, i32)
 DEF_HELPER_1(debug, void, env)
 DEF_HELPER_1(save, void, env)
 DEF_HELPER_1(restore, void, env)
@@ -42,14 +42,14 @@ DEF_HELPER_3(sdiv_cc, tl, env, tl, tl)
 DEF_HELPER_3(taddcctv, tl, env, tl, tl)
 DEF_HELPER_3(tsubcctv, tl, env, tl, tl)
 #ifdef TARGET_SPARC64
-DEF_HELPER_3(sdivx, s64, env, s64, s64)
-DEF_HELPER_3(udivx, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(sdivx, TCG_CALL_NO_WG, s64, env, s64, s64)
+DEF_HELPER_FLAGS_3(udivx, TCG_CALL_NO_WG, i64, env, i64, i64)
 #endif
-DEF_HELPER_3(ldqf, void, env, tl, int)
-DEF_HELPER_3(stqf, void, env, tl, int)
+DEF_HELPER_FLAGS_3(ldqf, TCG_CALL_NO_WG, void, env, tl, int)
+DEF_HELPER_FLAGS_3(stqf, TCG_CALL_NO_WG, void, env, tl, int)
 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
-DEF_HELPER_5(ld_asi, i64, env, tl, int, int, int)
-DEF_HELPER_5(st_asi, void, env, tl, i64, int, int)
+DEF_HELPER_FLAGS_5(ld_asi, TCG_CALL_NO_WG, i64, env, tl, int, int, int)
+DEF_HELPER_FLAGS_5(st_asi, TCG_CALL_NO_WG, void, env, tl, i64, int, int)
 #endif
 DEF_HELPER_2(ldfsr, void, env, i32)
 DEF_HELPER_FLAGS_1(fabss, TCG_CALL_NO_RWG_SE, f32, f32)
@@ -77,7 +77,7 @@ DEF_HELPER_3(fcmpes_fcc3, void, env, f32, f32)
 DEF_HELPER_3(fcmped_fcc1, void, env, f64, f64)
 DEF_HELPER_3(fcmped_fcc2, void, env, f64, f64)
 DEF_HELPER_3(fcmped_fcc3, void, env, f64, f64)
-DEF_HELPER_1(fabsq, void, env)
+DEF_HELPER_FLAGS_1(fabsq, TCG_CALL_NO_RWG, void, env)
 DEF_HELPER_1(fcmpq_fcc1, void, env)
 DEF_HELPER_1(fcmpq_fcc2, void, env)
 DEF_HELPER_1(fcmpq_fcc3, void, env)
@@ -106,17 +106,17 @@ DEF_HELPER_3(fsmuld, f64, env, f32, f32)
 DEF_HELPER_3(fdmulq, void, env, f64, f64)
 
 DEF_HELPER_FLAGS_1(fnegs, TCG_CALL_NO_RWG_SE, f32, f32)
-DEF_HELPER_2(fitod, f64, env, s32)
-DEF_HELPER_2(fitoq, void, env, s32)
+DEF_HELPER_FLAGS_2(fitod, TCG_CALL_NO_RWG_SE, f64, env, s32)
+DEF_HELPER_FLAGS_2(fitoq, TCG_CALL_NO_RWG, void, env, s32)
 
 DEF_HELPER_2(fitos, f32, env, s32)
 
 #ifdef TARGET_SPARC64
 DEF_HELPER_FLAGS_1(fnegd, TCG_CALL_NO_RWG_SE, f64, f64)
-DEF_HELPER_1(fnegq, void, env)
+DEF_HELPER_FLAGS_1(fnegq, TCG_CALL_NO_RWG, void, env)
 DEF_HELPER_2(fxtos, f32, env, s64)
 DEF_HELPER_2(fxtod, f64, env, s64)
-DEF_HELPER_2(fxtoq, void, env, s64)
+DEF_HELPER_FLAGS_2(fxtoq, TCG_CALL_NO_RWG, void, env, s64)
 #endif
 DEF_HELPER_2(fdtos, f32, env, f64)
 DEF_HELPER_2(fstod, f64, env, f32)
@@ -172,4 +172,4 @@ VIS_CMPHELPER(cmpne)
 #undef VIS_HELPER
 #undef VIS_CMPHELPER
 DEF_HELPER_1(compute_psr, void, env)
-DEF_HELPER_1(compute_C_icc, i32, env)
+DEF_HELPER_FLAGS_1(compute_C_icc, TCG_CALL_NO_WG_SE, i32, env)
-- 
2.5.0




Re: [Qemu-devel] [PATCH] topology.h: cleanup

2016-02-23 Thread Eduardo Habkost
On Tue, Feb 23, 2016 at 02:51:11PM +0800, Cao jin wrote:
> remove useless parameter of several functions
> 
> Signed-off-by: Cao jin 

I believe this makes the API much easier to be misused. Currently
you can safely use (smp_cores, smp_threads) every time. With this
patch, you need to always check the function definition to find
out what's the correct argument.

> ---
>  include/hw/i386/topology.h | 17 -
>  1 file changed, 8 insertions(+), 9 deletions(-)
> 
> diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
> index 148cc1b..d0f473c 100644
> --- a/include/hw/i386/topology.h
> +++ b/include/hw/i386/topology.h
> @@ -64,32 +64,31 @@ static unsigned apicid_bitwidth_for_count(unsigned count)
>  
>  /* Bit width of the SMT_ID (thread ID) field on the APIC ID
>   */
> -static inline unsigned apicid_smt_width(unsigned nr_cores, unsigned 
> nr_threads)
> +static inline unsigned apicid_smt_width(unsigned nr_threads)
>  {
>  return apicid_bitwidth_for_count(nr_threads);
>  }
>  
>  /* Bit width of the Core_ID field
>   */
> -static inline unsigned apicid_core_width(unsigned nr_cores, unsigned 
> nr_threads)
> +static inline unsigned apicid_core_width(unsigned nr_cores)
>  {
>  return apicid_bitwidth_for_count(nr_cores);
>  }
>  
> -/* Bit offset of the Core_ID field
> +/* Bit offset of the Core_ID field, equals bit width of SMT_ID
>   */
> -static inline unsigned apicid_core_offset(unsigned nr_cores,
> -  unsigned nr_threads)
> +static inline unsigned apicid_core_offset(unsigned nr_threads)
>  {
> -return apicid_smt_width(nr_cores, nr_threads);
> +return apicid_smt_width(nr_threads);
>  }
>  
>  /* Bit offset of the Pkg_ID (socket ID) field
>   */
>  static inline unsigned apicid_pkg_offset(unsigned nr_cores, unsigned 
> nr_threads)
>  {
> -return apicid_core_offset(nr_cores, nr_threads) +
> -   apicid_core_width(nr_cores, nr_threads);
> +return apicid_core_offset(nr_threads) +
> +   apicid_core_width(nr_cores);
>  }
>  
>  /* Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID
> @@ -101,7 +100,7 @@ static inline apic_id_t apicid_from_topo_ids(unsigned 
> nr_cores,
>   const X86CPUTopoInfo *topo)
>  {
>  return (topo->pkg_id  << apicid_pkg_offset(nr_cores, nr_threads)) |
> -   (topo->core_id << apicid_core_offset(nr_cores, nr_threads)) |
> +   (topo->core_id << apicid_core_offset(nr_threads)) |
> topo->smt_id;
>  }
>  
> -- 
> 2.1.0
> 
> 
> 

-- 
Eduardo



[Qemu-devel] [PATCH v2 20/24] target-sparc: Remove helper_ldf_asi, helper_stf_asi

2016-02-23 Thread Richard Henderson
We've now implemented all fp asis inline, except for the no-fault
memory reads.  The latter can be passed directly to helper_ld_asi.

Signed-off-by: Richard Henderson 
---
 target-sparc/helper.h  |   2 -
 target-sparc/ldst_helper.c | 148 -
 target-sparc/translate.c   |  48 ++-
 3 files changed, 32 insertions(+), 166 deletions(-)

diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index f5afc8d..b506706 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -18,8 +18,6 @@ DEF_HELPER_2(wrcwp, void, env, tl)
 DEF_HELPER_FLAGS_2(array8, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 DEF_HELPER_FLAGS_1(popc, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_3(ldda_asi, TCG_CALL_NO_WG, void, env, tl, int)
-DEF_HELPER_5(ldf_asi, void, env, tl, int, int, int)
-DEF_HELPER_FLAGS_5(stf_asi, TCG_CALL_NO_WG, void, env, tl, int, int, int)
 DEF_HELPER_FLAGS_5(casx_asi, TCG_CALL_NO_WG, tl, env, tl, tl, tl, i32)
 DEF_HELPER_FLAGS_2(set_softint, TCG_CALL_NO_RWG, void, env, i64)
 DEF_HELPER_FLAGS_2(clear_softint, TCG_CALL_NO_RWG, void, env, i64)
diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index d110d9e..35b4159 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -2160,154 +2160,6 @@ void helper_ldda_asi(CPUSPARCState *env, target_ulong 
addr, int asi)
 QT0.low = l;
 }
 
-void helper_ldf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
-int rd)
-{
-unsigned int i;
-target_ulong val;
-
-helper_check_align(env, addr, 3);
-addr = asi_address_mask(env, asi, addr);
-
-switch (asi) {
-case ASI_BLK_P:  /* UA2007/JPS1 Block load primary */
-case ASI_BLK_S:  /* UA2007/JPS1 Block load secondary */
-case ASI_BLK_PL: /* UA2007/JPS1 Block load primary LE */
-case ASI_BLK_SL: /* UA2007/JPS1 Block load secondary LE */
-if (rd & 7) {
-helper_raise_exception(env, TT_ILL_INSN);
-return;
-}
-helper_check_align(env, addr, 0x3f);
-for (i = 0; i < 8; i++, rd += 2, addr += 8) {
-env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi & 0x8f, MO_Q);
-}
-return;
-
-case ASI_BLK_AIUP_4V:   /* UA2007 Block load primary, user privilege */
-case ASI_BLK_AIUS_4V:   /* UA2007 Block load secondary, user privilege */
-case ASI_BLK_AIUP_L_4V: /* UA2007 Block load primary LE, user privilege */
-case ASI_BLK_AIUS_L_4V: /* UA2007 Block load secondary LE, user privilege 
*/
-case ASI_BLK_AIUP:  /* JPS1 Block load primary, user privilege */
-case ASI_BLK_AIUS:  /* JPS1 Block load secondary, user privilege */
-case ASI_BLK_AIUPL: /* JPS1 Block load primary LE, user privilege */
-case ASI_BLK_AIUSL: /* JPS1 Block load secondary LE, user privilege */
-if (rd & 7) {
-helper_raise_exception(env, TT_ILL_INSN);
-return;
-}
-helper_check_align(env, addr, 0x3f);
-for (i = 0; i < 8; i++, rd += 2, addr += 8) {
-env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi & 0x19, MO_Q);
-}
-return;
-
-default:
-break;
-}
-
-switch (size) {
-default:
-case 4:
-val = helper_ld_asi(env, addr, asi, MO_UL);
-if (rd & 1) {
-env->fpr[rd / 2].l.lower = val;
-} else {
-env->fpr[rd / 2].l.upper = val;
-}
-break;
-case 8:
-env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi, MO_Q);
-break;
-case 16:
-env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi, MO_Q);
-env->fpr[rd / 2 + 1].ll = helper_ld_asi(env, addr + 8, asi, MO_Q);
-break;
-}
-}
-
-void helper_stf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
-int rd)
-{
-unsigned int i;
-target_ulong val;
-
-addr = asi_address_mask(env, asi, addr);
-
-switch (asi) {
-case ASI_BLK_COMMIT_P: /* UA2007/JPS1 Block store primary (cache flush) */
-case ASI_BLK_COMMIT_S: /* UA2007/JPS1 Block store secondary (cache flush) 
*/
-case ASI_BLK_P: /* UA2007/JPS1 Block store primary */
-case ASI_BLK_S: /* UA2007/JPS1 Block store secondary */
-case ASI_BLK_PL: /* UA2007/JPS1 Block store primary LE */
-case ASI_BLK_SL: /* UA2007/JPS1 Block store secondary LE */
-if (rd & 7) {
-helper_raise_exception(env, TT_ILL_INSN);
-return;
-}
-helper_check_align(env, addr, 0x3f);
-for (i = 0; i < 8; i++, rd += 2, addr += 8) {
-helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi & 0x8f, MO_Q);
-}
-
-return;
-case ASI_BLK_AIUP_4V: /* UA2007 Block load primary, user privilege */
-case ASI_BLK_AIUS_4V: /* UA2007 Block load secondary, user privilege */
-case ASI_BLK_AIUP_L_4V: /* UA2007 Block load primary LE, user privilege */
-case ASI_BLK_AIUS_L_4V: /* UA2007 Block load secondary LE, 

[Qemu-devel] [PATCH v2 07/24] target-sparc: Introduce get_asi

2016-02-23 Thread Richard Henderson
Replace gen_get_asi, and use it for both 32-bit and 64-bit.
For v8, do supervisor and immediate checks here.

Also, move save_state and TB ending into the respective
subroutines, out of disas_sparc_insn.

Signed-off-by: Richard Henderson 
---
 target-sparc/translate.c | 508 +--
 1 file changed, 273 insertions(+), 235 deletions(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 7de5777..c9ec885 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1964,97 +1964,161 @@ static inline void gen_ne_fop_QD(DisasContext *dc, int 
rd, int rs,
 
 /* asi moves */
 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
-static TCGv_i32 gen_get_asi(DisasContext *dc, int insn)
-{
+typedef enum {
+GET_ASI_HELPER,
+GET_ASI_EXCP,
+} ASIType;
+
+typedef struct {
+ASIType type;
 int asi;
+} DisasASI;
 
+static DisasASI get_asi(DisasContext *dc, int insn)
+{
+int asi = GET_FIELD(insn, 19, 26);
+ASIType type = GET_ASI_HELPER;
+
+#ifndef TARGET_SPARC64
+/* Before v9, all asis are immediate and privileged.  */
 if (IS_IMM) {
-#ifdef TARGET_SPARC64
-asi = dc->asi;
-#else
 gen_exception(dc, TT_ILL_INSN);
-asi = 0;
-#endif
+type = GET_ASI_EXCP;
+} else if (supervisor(dc)
+   /* Note that LEON accepts ASI_USERDATA in user mode, for
+  use with CASA.  Also note that previous versions of
+  QEMU allowed ASI_P for LEON, which is incorrect.  */
+   || (asi == 0xa
+   && (dc->def->features & CPU_FEATURE_CASA))) {
 } else {
-asi = GET_FIELD(insn, 19, 26);
+gen_exception(dc, TT_PRIV_INSN);
+type = GET_ASI_EXCP;
+}
+#else
+if (IS_IMM) {
+asi = dc->asi;
 }
-return tcg_const_i32(asi);
+#endif
+
+return (DisasASI){ type, asi };
 }
 
 static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr,
int insn, int size, int sign)
 {
-TCGv_i32 r_asi, r_size, r_sign;
+DisasASI da = get_asi(dc, insn);
+
+switch (da.type) {
+case GET_ASI_EXCP:
+break;
+default:
+{
+TCGv_i32 r_asi = tcg_const_i32(da.asi);
+TCGv_i32 r_size = tcg_const_i32(size);
+TCGv_i32 r_sign = tcg_const_i32(sign);
 
-r_asi = gen_get_asi(dc, insn);
-r_size = tcg_const_i32(size);
-r_sign = tcg_const_i32(sign);
+save_state(dc);
 #ifdef TARGET_SPARC64
-gen_helper_ld_asi(dst, cpu_env, addr, r_asi, r_size, r_sign);
+gen_helper_ld_asi(dst, cpu_env, addr, r_asi, r_size, r_sign);
 #else
-{
-TCGv_i64 t64 = tcg_temp_new_i64();
-gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_size, r_sign);
-tcg_gen_trunc_i64_tl(dst, t64);
-tcg_temp_free_i64(t64);
-}
+{
+TCGv_i64 t64 = tcg_temp_new_i64();
+gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_size, r_sign);
+tcg_gen_trunc_i64_tl(dst, t64);
+tcg_temp_free_i64(t64);
+}
 #endif
-tcg_temp_free_i32(r_sign);
-tcg_temp_free_i32(r_size);
-tcg_temp_free_i32(r_asi);
+tcg_temp_free_i32(r_sign);
+tcg_temp_free_i32(r_size);
+tcg_temp_free_i32(r_asi);
+}
+break;
+}
 }
 
 static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
int insn, int size)
 {
-TCGv_i32 r_asi, r_size;
+DisasASI da = get_asi(dc, insn);
 
-r_asi = gen_get_asi(dc, insn);
-r_size = tcg_const_i32(size);
+switch (da.type) {
+case GET_ASI_EXCP:
+break;
+default:
+{
+TCGv_i32 r_asi = tcg_const_i32(da.asi);
+TCGv_i32 r_size = tcg_const_i32(size);
+
+save_state(dc);
 #ifdef TARGET_SPARC64
-gen_helper_st_asi(cpu_env, addr, src, r_asi, r_size);
+gen_helper_st_asi(cpu_env, addr, src, r_asi, r_size);
 #else
-{
-TCGv_i64 t64 = tcg_temp_new_i64();
-tcg_gen_extu_tl_i64(t64, src);
-gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_size);
-tcg_temp_free_i64(t64);
-}
+{
+TCGv_i64 t64 = tcg_temp_new_i64();
+tcg_gen_extu_tl_i64(t64, src);
+gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_size);
+tcg_temp_free_i64(t64);
+}
 #endif
-tcg_temp_free_i32(r_size);
-tcg_temp_free_i32(r_asi);
+tcg_temp_free_i32(r_size);
+tcg_temp_free_i32(r_asi);
+
+/* A write to a TLB register may alter page maps.  End the TB. */
+dc->npc = DYNAMIC_PC;
+}
+break;
+}
 }
 
 static void gen_swap_asi(DisasContext *dc, TCGv dst, TCGv src,
  TCGv addr, int insn)
 {
-TCGv_i32 r_asi, r_size, r_sign;
-TCGv_i64 s64, t64 = tcg_temp_new_i64();
+DisasASI da = get_asi(dc, 

[Qemu-devel] [PATCH v2 16/24] target-sparc: Fix obvious error in ASI_M_BFILL

2016-02-23 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-sparc/ldst_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 1eff8b4..9bedac9 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -988,7 +988,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, 
uint64_t val, int asi,
 /* addr = dst
fill 32 bytes with val */
 unsigned int i;
-uint32_t dst = addr & 7;
+uint32_t dst = addr & ~7;
 
 for (i = 0; i < 32; i += 8, dst += 8) {
 cpu_stq_kernel(env, dst, val);
-- 
2.5.0




[Qemu-devel] [PATCH v2 04/24] target-sparc: Create gen_exception

2016-02-23 Thread Richard Henderson
This unifies quite a few duplicate code fragments.

Signed-off-by: Richard Henderson 
---
 target-sparc/translate.c | 75 +---
 1 file changed, 20 insertions(+), 55 deletions(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 98cd62f..3e2851c 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1031,6 +1031,17 @@ static inline void save_state(DisasContext *dc)
 save_npc(dc);
 }
 
+static void gen_exception(DisasContext *dc, int which)
+{
+TCGv_i32 t;
+
+save_state(dc);
+t = tcg_const_i32(which);
+gen_helper_raise_exception(cpu_env, t);
+tcg_temp_free_i32(t);
+dc->is_br = 1;
+}
+
 static inline void gen_mov_pc_npc(DisasContext *dc)
 {
 if (dc->npc == JUMP_PC) {
@@ -1621,28 +1632,18 @@ static inline void gen_op_fcmpeq(int fccno)
 }
 #endif
 
-static inline void gen_op_fpexception_im(int fsr_flags)
+static void gen_op_fpexception_im(DisasContext *dc, int fsr_flags)
 {
-TCGv_i32 r_const;
-
 tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
 tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
-r_const = tcg_const_i32(TT_FP_EXCP);
-gen_helper_raise_exception(cpu_env, r_const);
-tcg_temp_free_i32(r_const);
+gen_exception(dc, TT_FP_EXCP);
 }
 
 static int gen_trap_ifnofpu(DisasContext *dc)
 {
 #if !defined(CONFIG_USER_ONLY)
 if (!dc->fpu_enabled) {
-TCGv_i32 r_const;
-
-save_state(dc);
-r_const = tcg_const_i32(TT_NFPU_INSN);
-gen_helper_raise_exception(cpu_env, r_const);
-tcg_temp_free_i32(r_const);
-dc->is_br = 1;
+gen_exception(dc, TT_NFPU_INSN);
 return 1;
 }
 #endif
@@ -5140,63 +5141,27 @@ static void disas_sparc_insn(DisasContext * dc, 
unsigned int insn)
  jmp_insn:
 goto egress;
  illegal_insn:
-{
-TCGv_i32 r_const;
-
-save_state(dc);
-r_const = tcg_const_i32(TT_ILL_INSN);
-gen_helper_raise_exception(cpu_env, r_const);
-tcg_temp_free_i32(r_const);
-dc->is_br = 1;
-}
+gen_exception(dc, TT_ILL_INSN);
 goto egress;
  unimp_flush:
-{
-TCGv_i32 r_const;
-
-save_state(dc);
-r_const = tcg_const_i32(TT_UNIMP_FLUSH);
-gen_helper_raise_exception(cpu_env, r_const);
-tcg_temp_free_i32(r_const);
-dc->is_br = 1;
-}
+gen_exception(dc, TT_UNIMP_FLUSH);
 goto egress;
 #if !defined(CONFIG_USER_ONLY)
  priv_insn:
-{
-TCGv_i32 r_const;
-
-save_state(dc);
-r_const = tcg_const_i32(TT_PRIV_INSN);
-gen_helper_raise_exception(cpu_env, r_const);
-tcg_temp_free_i32(r_const);
-dc->is_br = 1;
-}
+gen_exception(dc, TT_PRIV_INSN);
 goto egress;
 #endif
  nfpu_insn:
-save_state(dc);
-gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
-dc->is_br = 1;
+gen_op_fpexception_im(dc, FSR_FTT_UNIMPFPOP);
 goto egress;
 #if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
  nfq_insn:
-save_state(dc);
-gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
-dc->is_br = 1;
+gen_op_fpexception_im(dc, FSR_FTT_SEQ_ERROR);
 goto egress;
 #endif
 #ifndef TARGET_SPARC64
  ncp_insn:
-{
-TCGv r_const;
-
-save_state(dc);
-r_const = tcg_const_i32(TT_NCP_INSN);
-gen_helper_raise_exception(cpu_env, r_const);
-tcg_temp_free(r_const);
-dc->is_br = 1;
-}
+gen_exception(dc, TT_NCP_INSN);
 goto egress;
 #endif
  egress:
-- 
2.5.0




[Qemu-devel] [PATCH v2 17/24] target-sparc: Pass TCGMemOp constants to helper_ld/st_asi

2016-02-23 Thread Richard Henderson
Reduces the argument count for helper_ld_asi; do helper_st_asi
for consistency.

Signed-off-by: Richard Henderson 
---
 target-sparc/helper.h  |  4 +--
 target-sparc/ldst_helper.c | 73 ++
 target-sparc/translate.c   | 58 
 3 files changed, 69 insertions(+), 66 deletions(-)

diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index 66abf83..f5afc8d 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -48,8 +48,8 @@ DEF_HELPER_FLAGS_3(udivx, TCG_CALL_NO_WG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_3(ldqf, TCG_CALL_NO_WG, void, env, tl, int)
 DEF_HELPER_FLAGS_3(stqf, TCG_CALL_NO_WG, void, env, tl, int)
 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
-DEF_HELPER_FLAGS_5(ld_asi, TCG_CALL_NO_WG, i64, env, tl, int, int, int)
-DEF_HELPER_FLAGS_5(st_asi, TCG_CALL_NO_WG, void, env, tl, i64, int, int)
+DEF_HELPER_FLAGS_4(ld_asi, TCG_CALL_NO_WG, i64, env, tl, int, i32)
+DEF_HELPER_FLAGS_5(st_asi, TCG_CALL_NO_WG, void, env, tl, i64, int, i32)
 #endif
 DEF_HELPER_2(ldfsr, void, env, i32)
 DEF_HELPER_FLAGS_1(fabss, TCG_CALL_NO_RWG_SE, f32, f32)
diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 9bedac9..d110d9e 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -19,6 +19,7 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
+#include "tcg.h"
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"
 #include "asi.h"
@@ -427,9 +428,11 @@ static uint64_t leon3_cache_control_ld(CPUSPARCState *env, 
target_ulong addr,
 return ret;
 }
 
-uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int 
size,
-   int sign)
+uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
+   int asi, uint32_t memop)
 {
+int size = 1 << (memop & MO_SIZE);
+int sign = memop & MO_SIGN;
 CPUState *cs = CPU(sparc_env_get_cpu(env));
 uint64_t ret = 0;
 #if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
@@ -697,9 +700,10 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
addr, int asi, int size,
 return ret;
 }
 
-void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val, int 
asi,
-   int size)
+void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
+   int asi, uint32_t memop)
 {
+int size = 1 << (memop & MO_SIZE);
 SPARCCPU *cpu = sparc_env_get_cpu(env);
 CPUState *cs = CPU(cpu);
 
@@ -1096,9 +1100,11 @@ void helper_st_asi(CPUSPARCState *env, target_ulong 
addr, uint64_t val, int asi,
 #else /* TARGET_SPARC64 */
 
 #ifdef CONFIG_USER_ONLY
-uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int 
size,
-   int sign)
+uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
+   int asi, uint32_t memop)
 {
+int size = 1 << (memop & MO_SIZE);
+int sign = memop & MO_SIGN;
 uint64_t ret = 0;
 #if defined(DEBUG_ASI)
 target_ulong last_addr = addr;
@@ -1204,8 +1210,9 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
addr, int asi, int size,
 }
 
 void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
-   int asi, int size)
+   int asi, uint32_t memop)
 {
+int size = 1 << (memop & MO_SIZE);
 #ifdef DEBUG_ASI
 dump_asi("write", addr, asi, size, val);
 #endif
@@ -1275,9 +1282,11 @@ void helper_st_asi(CPUSPARCState *env, target_ulong 
addr, target_ulong val,
 
 #else /* CONFIG_USER_ONLY */
 
-uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int 
size,
-   int sign)
+uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
+   int asi, uint32_t memop)
 {
+int size = 1 << (memop & MO_SIZE);
+int sign = memop & MO_SIGN;
 CPUState *cs = CPU(sparc_env_get_cpu(env));
 uint64_t ret = 0;
 #if defined(DEBUG_ASI)
@@ -1657,8 +1666,9 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong 
addr, int asi, int size,
 }
 
 void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
-   int asi, int size)
+   int asi, uint32_t memop)
 {
+int size = 1 << (memop & MO_SIZE);
 SPARCCPU *cpu = sparc_env_get_cpu(env);
 CPUState *cs = CPU(cpu);
 
@@ -2137,8 +2147,8 @@ void helper_ldda_asi(CPUSPARCState *env, target_ulong 
addr, int asi)
a single 64-bit load.  However, LE asis *are* treated
as two 32-bit loads individually byte swapped.  */
 helper_check_align(env, addr, 0x7);
-QT0.high = (uint32_t)helper_ld_asi(env, addr, asi, 4, 0);
-QT0.low = (uint32_t)helper_ld_asi(env, addr + 4, asi, 4, 0);
+QT0.high = (uint32_t)helper_ld_asi(env, addr, asi, MO_UL);
+QT0.low = (uint32_t)helper_ld_asi(env, addr + 4, asi, MO_UL);
 return;
 }
 
@@ -2170,7 +2180,7 @@ void 

[Qemu-devel] [PATCH v2 21/24] target-sparc: Use explicit writes to cpu_fsr

2016-02-23 Thread Richard Henderson
By arranging for explicit writes to cpu_fsr after floating point
operations, we are able to mark the helpers as not writing to
tcg globals, which means that we don't need to invalidate the
integer register set across said calls.

Signed-off-by: Richard Henderson 
---
 target-sparc/fop_helper.c | 223 +++---
 target-sparc/helper.h | 112 +++
 target-sparc/translate.c  |  76 +---
 3 files changed, 174 insertions(+), 237 deletions(-)

diff --git a/target-sparc/fop_helper.c b/target-sparc/fop_helper.c
index 0830643..cdc58ea 100644
--- a/target-sparc/fop_helper.c
+++ b/target-sparc/fop_helper.c
@@ -24,43 +24,46 @@
 #define QT0 (env->qt0)
 #define QT1 (env->qt1)
 
-static void check_ieee_exceptions(CPUSPARCState *env)
+target_ulong helper_check_ieee_exceptions(CPUSPARCState *env)
 {
-target_ulong status;
+target_ulong status = get_float_exception_flags(>fp_status);
+target_ulong fsr = env->fsr;
+
+if (unlikely(status)) {
+/* Keep exception flags clear for next time.  */
+set_float_exception_flags(0, >fp_status);
 
-status = get_float_exception_flags(>fp_status);
-if (status) {
 /* Copy IEEE 754 flags into FSR */
 if (status & float_flag_invalid) {
-env->fsr |= FSR_NVC;
+fsr |= FSR_NVC;
 }
 if (status & float_flag_overflow) {
-env->fsr |= FSR_OFC;
+fsr |= FSR_OFC;
 }
 if (status & float_flag_underflow) {
-env->fsr |= FSR_UFC;
+fsr |= FSR_UFC;
 }
 if (status & float_flag_divbyzero) {
-env->fsr |= FSR_DZC;
+fsr |= FSR_DZC;
 }
 if (status & float_flag_inexact) {
-env->fsr |= FSR_NXC;
+fsr |= FSR_NXC;
 }
 
-if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23)) {
-/* Unmasked exception, generate a trap */
-env->fsr |= FSR_FTT_IEEE_EXCP;
+if ((fsr & FSR_CEXC_MASK) & ((fsr & FSR_TEM_MASK) >> 23)) {
+/* Unmasked exception, generate a trap.  Note that while
+   the helper is marked as NO_WG, we can get away with
+   writing to cpu state along the exception path, since
+   TCG generated code will never see the write.  */
+env->fsr = fsr | FSR_FTT_IEEE_EXCP;
 helper_raise_exception(env, TT_FP_EXCP);
 } else {
 /* Accumulate exceptions */
-env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5;
+fsr |= (fsr & FSR_CEXC_MASK) << 5;
 }
 }
-}
 
-static inline void clear_float_exceptions(CPUSPARCState *env)
-{
-set_float_exception_flags(0, >fp_status);
+return fsr;
 }
 
 #define F_HELPER(name, p) void helper_f##name##p(CPUSPARCState *env)
@@ -69,26 +72,16 @@ static inline void clear_float_exceptions(CPUSPARCState 
*env)
 float32 helper_f ## name ## s (CPUSPARCState *env, float32 src1, \
float32 src2)\
 {   \
-float32 ret;\
-clear_float_exceptions(env);\
-ret = float32_ ## name (src1, src2, >fp_status);   \
-check_ieee_exceptions(env); \
-return ret; \
+return float32_ ## name (src1, src2, >fp_status);  \
 }   \
 float64 helper_f ## name ## d (CPUSPARCState * env, float64 src1,\
float64 src2)\
 {   \
-float64 ret;\
-clear_float_exceptions(env);\
-ret = float64_ ## name (src1, src2, >fp_status);   \
-check_ieee_exceptions(env); \
-return ret; \
+return float64_ ## name (src1, src2, >fp_status);  \
 }   \
 F_HELPER(name, q)   \
 {   \
-clear_float_exceptions(env);\
 QT0 = float128_ ## name (QT0, QT1, >fp_status);\
-check_ieee_exceptions(env); \
 }
 
 F_BINOP(add);
@@ -99,22 +92,16 @@ F_BINOP(div);
 
 float64 helper_fsmuld(CPUSPARCState *env, float32 src1, float32 src2)
 {
-float64 ret;
-clear_float_exceptions(env);
-ret = float64_mul(float32_to_float64(src1, >fp_status),
-  float32_to_float64(src2, >fp_status),
-  >fp_status);
-check_ieee_exceptions(env);
-  

[Qemu-devel] [PATCH v2 06/24] target-sparc: Store %asi in TB flags

2016-02-23 Thread Richard Henderson
Knowing the value of %asi at translation time means that we
can handle the common settings without a function call.

The steady state appears to be %asi == ASI_P, so that sparcv9
code can use offset forms of lda/sta.  The %asi register gets
pushed and popped on entry to certain functions, but it rarely
takes on values other than ASI_P or ASI_AIUP.  Therefore we're
unlikely to be expanding the set of TBs created.

Signed-off-by: Richard Henderson 
---
 target-sparc/cpu.h   |  2 ++
 target-sparc/translate.c | 29 -
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 66c0ee9..3db6a67 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -687,6 +687,7 @@ trap_state* cpu_tsptr(CPUSPARCState* env);
 #define TB_FLAG_MMU_MASK 7
 #define TB_FLAG_FPU_ENABLED  (1 << 4)
 #define TB_FLAG_AM_ENABLED   (1 << 5)
+#define TB_FLAG_ASI_SHIFT24
 
 static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, target_ulong *pc,
 target_ulong *cs_base, int *pflags)
@@ -704,6 +705,7 @@ static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, 
target_ulong *pc,
 && (env->fprs & FPRS_FEF)) {
 flags |= TB_FLAG_FPU_ENABLED;
 }
+flags |= env->asi << TB_FLAG_ASI_SHIFT;
 #else
 if ((env->def->features & CPU_FEATURE_FLOAT) && env->psref) {
 flags |= TB_FLAG_FPU_ENABLED;
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 62dde3e..7de5777 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -51,7 +51,7 @@ static TCGv cpu_tbr;
 #endif
 static TCGv cpu_cond;
 #ifdef TARGET_SPARC64
-static TCGv_i32 cpu_xcc, cpu_asi, cpu_fprs;
+static TCGv_i32 cpu_xcc, cpu_fprs;
 static TCGv cpu_gsr;
 static TCGv cpu_tick_cmpr, cpu_stick_cmpr, cpu_hstick_cmpr;
 static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
@@ -79,6 +79,9 @@ typedef struct DisasContext {
 TCGv ttl[5];
 int n_t32;
 int n_ttl;
+#ifdef TARGET_SPARC64
+int asi;
+#endif
 } DisasContext;
 
 typedef struct {
@@ -1963,19 +1966,19 @@ static inline void gen_ne_fop_QD(DisasContext *dc, int 
rd, int rs,
 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
 static TCGv_i32 gen_get_asi(DisasContext *dc, int insn)
 {
-TCGv_i32 r_asi = tcg_temp_new_i32();
+int asi;
 
 if (IS_IMM) {
 #ifdef TARGET_SPARC64
-tcg_gen_mov_i32(r_asi, cpu_asi);
+asi = dc->asi;
 #else
 gen_exception(dc, TT_ILL_INSN);
-tcg_gen_movi_i32(r_asi, 0);
+asi = 0;
 #endif
 } else {
-tcg_gen_movi_i32(r_asi, GET_FIELD(insn, 19, 26));
+asi = GET_FIELD(insn, 19, 26);
 }
-return r_asi;
+return tcg_const_i32(asi);
 }
 
 static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr,
@@ -2676,7 +2679,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned 
int insn)
 gen_store_gpr(dc, rd, cpu_dst);
 break;
 case 0x3: /* V9 rdasi */
-tcg_gen_ext_i32_tl(cpu_dst, cpu_asi);
+tcg_gen_movi_tl(cpu_dst, dc->asi);
 gen_store_gpr(dc, rd, cpu_dst);
 break;
 case 0x4: /* V9 rdtick */
@@ -3602,7 +3605,13 @@ static void disas_sparc_insn(DisasContext * dc, unsigned 
int insn)
 case 0x3: /* V9 wrasi */
 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xff);
-tcg_gen_trunc_tl_i32(cpu_asi, cpu_tmp0);
+tcg_gen_st32_tl(cpu_tmp0, cpu_env,
+offsetof(CPUSPARCState, asi));
+/* End TB to notice changed ASI.  */
+save_state(dc);
+gen_op_next_insn();
+tcg_gen_exit_tb(0);
+dc->is_br = 1;
 break;
 case 0x6: /* V9 wrfprs */
 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
@@ -5180,6 +5189,9 @@ void gen_intermediate_code(CPUSPARCState * env, 
TranslationBlock * tb)
 dc->fpu_enabled = tb_fpu_enabled(tb->flags);
 dc->address_mask_32bit = tb_am_enabled(tb->flags);
 dc->singlestep = (cs->singlestep_enabled || singlestep);
+#ifdef TARGET_SPARC64
+dc->asi = (tb->flags >> TB_FLAG_ASI_SHIFT) & 0xff;
+#endif
 
 num_insns = 0;
 max_insns = tb->cflags & CF_COUNT_MASK;
@@ -5288,7 +5300,6 @@ void gen_intermediate_code_init(CPUSPARCState *env)
 static const struct { TCGv_i32 *ptr; int off; const char *name; } r32[] = {
 #ifdef TARGET_SPARC64
 { _xcc, offsetof(CPUSPARCState, xcc), "xcc" },
-{ _asi, offsetof(CPUSPARCState, asi), "asi" },
 { _fprs, 

[Qemu-devel] [PATCH v2 03/24] target-sparc: Store mmu index in TB flags

2016-02-23 Thread Richard Henderson
Doing this instead of saving the raw PS_PRIV and TL.  This means
that all nucleus mode TBs (TL > 0) can be shared.  This fixes a
bug in that we didn't include HS_PRIV in the TB flags, and so could
produce incorrect TB matches for hypervisor state.

The LSU and DMMU states were unused by the translator.  Including
them in TB flags meant unnecessary mismatches from tb_find_fast.

Signed-off-by: Richard Henderson 
---
 target-sparc/cpu.h   | 26 --
 target-sparc/translate.c |  2 +-
 2 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index dc46122..66c0ee9 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -684,34 +684,32 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit);
 trap_state* cpu_tsptr(CPUSPARCState* env);
 #endif
 
-#define TB_FLAG_FPU_ENABLED (1 << 4)
-#define TB_FLAG_AM_ENABLED (1 << 5)
+#define TB_FLAG_MMU_MASK 7
+#define TB_FLAG_FPU_ENABLED  (1 << 4)
+#define TB_FLAG_AM_ENABLED   (1 << 5)
 
 static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, target_ulong *pc,
-target_ulong *cs_base, int *flags)
+target_ulong *cs_base, int *pflags)
 {
+int flags;
 *pc = env->pc;
 *cs_base = env->npc;
+flags = cpu_mmu_index(env, false);
 #ifdef TARGET_SPARC64
-// AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
-*flags = (env->pstate & PS_PRIV)   /* 2 */
-| ((env->lsu & (DMMU_E | IMMU_E)) >> 2)/* 1, 0 */
-| ((env->tl & 0xff) << 8)
-| (env->dmmu.mmu_primary_context << 16);   /* 16... */
 if (env->pstate & PS_AM) {
-*flags |= TB_FLAG_AM_ENABLED;
+flags |= TB_FLAG_AM_ENABLED;
 }
-if ((env->def->features & CPU_FEATURE_FLOAT) && (env->pstate & PS_PEF)
+if ((env->def->features & CPU_FEATURE_FLOAT)
+&& (env->pstate & PS_PEF)
 && (env->fprs & FPRS_FEF)) {
-*flags |= TB_FLAG_FPU_ENABLED;
+flags |= TB_FLAG_FPU_ENABLED;
 }
 #else
-// FPU enable . Supervisor
-*flags = env->psrs;
 if ((env->def->features & CPU_FEATURE_FLOAT) && env->psref) {
-*flags |= TB_FLAG_FPU_ENABLED;
+flags |= TB_FLAG_FPU_ENABLED;
 }
 #endif
+*pflags = flags;
 }
 
 static inline bool tb_fpu_enabled(int tb_flags)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 964735b..98cd62f 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5233,7 +5233,7 @@ void gen_intermediate_code(CPUSPARCState * env, 
TranslationBlock * tb)
 last_pc = dc->pc;
 dc->npc = (target_ulong) tb->cs_base;
 dc->cc_op = CC_OP_DYNAMIC;
-dc->mem_idx = cpu_mmu_index(env, false);
+dc->mem_idx = tb->flags & TB_FLAG_MMU_MASK;
 dc->def = env->def;
 dc->fpu_enabled = tb_fpu_enabled(tb->flags);
 dc->address_mask_32bit = tb_am_enabled(tb->flags);
-- 
2.5.0




[Qemu-devel] [PATCH v2 00/24] target-sparc improvements

2016-02-23 Thread Richard Henderson
The primary focus of this patch set is to reduce the number of
helpers that modify TCG globals, and thus increase the lifetime
of those globals within each TB, and thus decrease the number
of times that tcg must spill and fill them from backing store.

As a byproduct, I also implement the bulk of the interesting v9 ASIs
inline, thus exposing e.g. the little-endian loads and stores as
simple tcg operations.

The patch set is relative to my outstanding tcg pull request.
For reference, the complete tree can be found at

  git://github.com/rth7680/qemu.git tgt-sparc

Changes from v1 to v2:
  * Commit message refers to UA2005 instead of UA2011 when
introducing new asi.h defines. (Artyom)
  * Drop the MMU_REAL_IDX, and inline handling of ASI_REAL_*.
This appears to be the source of the regression that Artyom
identified wrt ss5 emulation.


r~


Richard Henderson (24):
  target-sparc: Mark more flags for helpers
  target-sparc: Remove softint as a TCG global
  target-sparc: Store mmu index in TB flags
  target-sparc: Create gen_exception
  target-sparc: Unify asi handling between 32 and 64-bit
  target-sparc: Store %asi in TB flags
  target-sparc: Introduce get_asi
  target-sparc: Pass TCGMemOp to gen_ld/st_asi
  target-sparc: Import linux/arch/sparc/include/uapi/asm/asi.h
  target-sparc: Add UA2005 defines to asi.h
  target-sparc: Use defines from asi.h
  target-sparc: Directly implement easy ld/st asis
  target-sparc: Use QT0 to return results from ldda
  target-sparc: Introduce gen_check_align
  target-sparc: Directly implement easy ldd/std asis
  target-sparc: Fix obvious error in ASI_M_BFILL
  target-sparc: Pass TCGMemOp constants to helper_ld/st_asi
  target-sparc: Directly implement easy ldf/stf asis
  target-sparc: Directly implement block and short ldf/stf asis
  target-sparc: Remove helper_ldf_asi, helper_stf_asi
  target-sparc: Use explicit writes to cpu_fsr
  target-sparc: Use cpu_fsr in stfsr
  target-sparc: Use cpu_loop_exit_restore from
helper_check_ieee_exceptions
  target-sparc: Elide duplicate updates to fprs

 target-sparc/asi.h |  311 +++
 target-sparc/cpu.h |   28 +-
 target-sparc/fop_helper.c  |  229 +++-
 target-sparc/helper.h  |  168 +++---
 target-sparc/ldst_helper.c |  696 +++-
 target-sparc/translate.c   | 1250 +++-
 6 files changed, 1580 insertions(+), 1102 deletions(-)
 create mode 100644 target-sparc/asi.h

-- 
2.5.0




[Qemu-devel] [PATCH v2 14/24] target-sparc: Introduce gen_check_align

2016-02-23 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-sparc/translate.c | 48 +---
 1 file changed, 13 insertions(+), 35 deletions(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 2163261..008b07b 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1046,6 +1046,13 @@ static void gen_exception(DisasContext *dc, int which)
 dc->is_br = 1;
 }
 
+static void gen_check_align(TCGv addr, int mask)
+{
+TCGv_i32 r_mask = tcg_const_i32(mask);
+gen_helper_check_align(cpu_env, addr, r_mask);
+tcg_temp_free_i32(r_mask);
+}
+
 static inline void gen_mov_pc_npc(DisasContext *dc)
 {
 if (dc->npc == JUMP_PC) {
@@ -4679,8 +4686,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned 
int insn)
 #endif
 #ifdef TARGET_SPARC64
 } else if (xop == 0x39) { /* V9 return */
-TCGv_i32 r_const;
-
 save_state(dc);
 cpu_src1 = get_src1(dc, insn);
 cpu_tmp0 = get_temp_tl(dc);
@@ -4698,9 +4703,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned 
int insn)
 }
 gen_helper_restore(cpu_env);
 gen_mov_pc_npc(dc);
-r_const = tcg_const_i32(3);
-gen_helper_check_align(cpu_env, cpu_tmp0, r_const);
-tcg_temp_free_i32(r_const);
+gen_check_align(cpu_tmp0, 3);
 tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
 dc->npc = DYNAMIC_PC;
 goto jmp_insn;
@@ -4723,16 +4726,12 @@ static void disas_sparc_insn(DisasContext * dc, 
unsigned int insn)
 switch (xop) {
 case 0x38:  /* jmpl */
 {
-TCGv t;
-TCGv_i32 r_const;
-
-t = gen_dest_gpr(dc, rd);
+TCGv t = gen_dest_gpr(dc, rd);
 tcg_gen_movi_tl(t, dc->pc);
 gen_store_gpr(dc, rd, t);
+
 gen_mov_pc_npc(dc);
-r_const = tcg_const_i32(3);
-gen_helper_check_align(cpu_env, cpu_tmp0, r_const);
-tcg_temp_free_i32(r_const);
+gen_check_align(cpu_tmp0, 3);
 gen_address_mask(dc, cpu_tmp0);
 tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
 dc->npc = DYNAMIC_PC;
@@ -4741,14 +4740,10 @@ static void disas_sparc_insn(DisasContext * dc, 
unsigned int insn)
 #if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
 case 0x39:  /* rett, V9 return */
 {
-TCGv_i32 r_const;
-
 if (!supervisor(dc))
 goto priv_insn;
 gen_mov_pc_npc(dc);
-r_const = tcg_const_i32(3);
-gen_helper_check_align(cpu_env, cpu_tmp0, r_const);
-tcg_temp_free_i32(r_const);
+gen_check_align(cpu_tmp0, 3);
 tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
 dc->npc = DYNAMIC_PC;
 gen_helper_rett(cpu_env);
@@ -4844,14 +4839,8 @@ static void disas_sparc_insn(DisasContext * dc, unsigned 
int insn)
 if (rd & 1)
 goto illegal_insn;
 else {
-TCGv_i32 r_const;
 TCGv_i64 t64;
 
-save_state(dc);
-r_const = tcg_const_i32(7);
-/* XXX remove alignment check */
-gen_helper_check_align(cpu_env, cpu_addr, r_const);
-tcg_temp_free_i32(r_const);
 gen_address_mask(dc, cpu_addr);
 t64 = tcg_temp_new_i64();
 tcg_gen_qemu_ld64(t64, cpu_addr, dc->mem_idx);
@@ -5059,18 +5048,11 @@ static void disas_sparc_insn(DisasContext * dc, 
unsigned int insn)
 if (rd & 1)
 goto illegal_insn;
 else {
-TCGv_i32 r_const;
 TCGv_i64 t64;
 TCGv lo;
 
-save_state(dc);
 gen_address_mask(dc, cpu_addr);
-r_const = tcg_const_i32(7);
-/* XXX remove alignment check */
-gen_helper_check_align(cpu_env, cpu_addr, r_const);
-tcg_temp_free_i32(r_const);
 lo = gen_load_gpr(dc, rd + 1);
-
 t64 = tcg_temp_new_i64();
 tcg_gen_concat_tl_i64(t64, lo, cpu_val);
 tcg_gen_qemu_st64(t64, cpu_addr, dc->mem_idx);
@@ -5183,15 +5165,11 @@ static void 

[Qemu-devel] [PATCH v2 23/24] target-sparc: Use cpu_loop_exit_restore from helper_check_ieee_exceptions

2016-02-23 Thread Richard Henderson
This avoids needing to save state before every FP operation.

Signed-off-by: Richard Henderson 
---
 target-sparc/fop_helper.c | 16 
 target-sparc/translate.c  |  6 +-
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/target-sparc/fop_helper.c b/target-sparc/fop_helper.c
index cdc58ea..02fbf86 100644
--- a/target-sparc/fop_helper.c
+++ b/target-sparc/fop_helper.c
@@ -24,7 +24,7 @@
 #define QT0 (env->qt0)
 #define QT1 (env->qt1)
 
-target_ulong helper_check_ieee_exceptions(CPUSPARCState *env)
+static target_ulong do_check_ieee_exceptions(CPUSPARCState *env, uintptr_t ra)
 {
 target_ulong status = get_float_exception_flags(>fp_status);
 target_ulong fsr = env->fsr;
@@ -51,12 +51,15 @@ target_ulong helper_check_ieee_exceptions(CPUSPARCState 
*env)
 }
 
 if ((fsr & FSR_CEXC_MASK) & ((fsr & FSR_TEM_MASK) >> 23)) {
+CPUState *cs = CPU(sparc_env_get_cpu(env));
+
 /* Unmasked exception, generate a trap.  Note that while
the helper is marked as NO_WG, we can get away with
writing to cpu state along the exception path, since
TCG generated code will never see the write.  */
 env->fsr = fsr | FSR_FTT_IEEE_EXCP;
-helper_raise_exception(env, TT_FP_EXCP);
+cs->exception_index = TT_FP_EXCP;
+cpu_loop_exit_restore(cs, ra);
 } else {
 /* Accumulate exceptions */
 fsr |= (fsr & FSR_CEXC_MASK) << 5;
@@ -66,6 +69,11 @@ target_ulong helper_check_ieee_exceptions(CPUSPARCState *env)
 return fsr;
 }
 
+target_ulong helper_check_ieee_exceptions(CPUSPARCState *env)
+{
+return do_check_ieee_exceptions(env, GETPC());
+}
+
 #define F_HELPER(name, p) void helper_f##name##p(CPUSPARCState *env)
 
 #define F_BINOP(name)   \
@@ -262,7 +270,7 @@ void helper_fsqrtq(CPUSPARCState *env)
 ret = glue(size, _compare_quiet)(reg1, reg2,\
  >fp_status);  \
 }   \
-fsr = helper_check_ieee_exceptions(env);\
+fsr = do_check_ieee_exceptions(env, GETPC());   \
 switch (ret) {  \
 case float_relation_unordered:  \
 fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \
@@ -293,7 +301,7 @@ void helper_fsqrtq(CPUSPARCState *env)
 ret = glue(size, _compare_quiet)(src1, src2,\
  >fp_status);  \
 }   \
-fsr = helper_check_ieee_exceptions(env);\
+fsr = do_check_ieee_exceptions(env, GETPC());   \
 switch (ret) {  \
 case float_relation_unordered:  \
 fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 5874571..688594d 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -3423,7 +3423,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned 
int insn)
 rs1 = GET_FIELD(insn, 13, 17);
 rs2 = GET_FIELD(insn, 27, 31);
 xop = GET_FIELD(insn, 18, 26);
-save_state(dc);
+
 switch (xop) {
 case 0x1: /* fmovs */
 cpu_src1_32 = gen_load_fpr_F(dc, rs2);
@@ -3598,7 +3598,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned 
int insn)
 rs1 = GET_FIELD(insn, 13, 17);
 rs2 = GET_FIELD(insn, 27, 31);
 xop = GET_FIELD(insn, 18, 26);
-save_state(dc);
 
 #ifdef TARGET_SPARC64
 #define FMOVR(sz)  \
@@ -5232,7 +5231,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned 
int insn)
 if (gen_trap_ifnofpu(dc)) {
 goto jmp_insn;
 }
-save_state(dc);
 switch (xop) {
 case 0x20:  /* ldf, load fpreg */
 gen_address_mask(dc, cpu_addr);
@@ -5346,7 +5344,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned 
int insn)
 if (gen_trap_ifnofpu(dc)) {
 goto jmp_insn;
 }
-save_state(dc);
 switch (xop) {
 case 0x24: /* stf, store fpreg */
 {
@@ -5405,7 +5402,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned 
int insn)
 goto illegal_insn;
 }
 } else if (xop > 0x33 

[Qemu-devel] [PATCH v2 05/24] target-sparc: Unify asi handling between 32 and 64-bit

2016-02-23 Thread Richard Henderson
We now have a single copy of gen_ld_asi, gen_st_asi,
gen_swap_asi, and everything uses gen_get_asi.

Signed-off-by: Richard Henderson 
---
 target-sparc/translate.c | 285 ++-
 1 file changed, 131 insertions(+), 154 deletions(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 3e2851c..62dde3e 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1960,111 +1960,175 @@ static inline void gen_ne_fop_QD(DisasContext *dc, 
int rd, int rs,
 }
 
 /* asi moves */
-#ifdef TARGET_SPARC64
-static inline TCGv_i32 gen_get_asi(int insn, TCGv r_addr)
+#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
+static TCGv_i32 gen_get_asi(DisasContext *dc, int insn)
 {
-int asi;
-TCGv_i32 r_asi;
+TCGv_i32 r_asi = tcg_temp_new_i32();
 
 if (IS_IMM) {
-r_asi = tcg_temp_new_i32();
+#ifdef TARGET_SPARC64
 tcg_gen_mov_i32(r_asi, cpu_asi);
+#else
+gen_exception(dc, TT_ILL_INSN);
+tcg_gen_movi_i32(r_asi, 0);
+#endif
 } else {
-asi = GET_FIELD(insn, 19, 26);
-r_asi = tcg_const_i32(asi);
+tcg_gen_movi_i32(r_asi, GET_FIELD(insn, 19, 26));
 }
 return r_asi;
 }
 
-static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
-  int sign)
+static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr,
+   int insn, int size, int sign)
 {
 TCGv_i32 r_asi, r_size, r_sign;
 
-r_asi = gen_get_asi(insn, addr);
+r_asi = gen_get_asi(dc, insn);
 r_size = tcg_const_i32(size);
 r_sign = tcg_const_i32(sign);
+#ifdef TARGET_SPARC64
 gen_helper_ld_asi(dst, cpu_env, addr, r_asi, r_size, r_sign);
+#else
+{
+TCGv_i64 t64 = tcg_temp_new_i64();
+gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_size, r_sign);
+tcg_gen_trunc_i64_tl(dst, t64);
+tcg_temp_free_i64(t64);
+}
+#endif
 tcg_temp_free_i32(r_sign);
 tcg_temp_free_i32(r_size);
 tcg_temp_free_i32(r_asi);
 }
 
-static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
+static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
+   int insn, int size)
 {
 TCGv_i32 r_asi, r_size;
 
-r_asi = gen_get_asi(insn, addr);
+r_asi = gen_get_asi(dc, insn);
 r_size = tcg_const_i32(size);
+#ifdef TARGET_SPARC64
 gen_helper_st_asi(cpu_env, addr, src, r_asi, r_size);
+#else
+{
+TCGv_i64 t64 = tcg_temp_new_i64();
+tcg_gen_extu_tl_i64(t64, src);
+gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_size);
+tcg_temp_free_i64(t64);
+}
+#endif
 tcg_temp_free_i32(r_size);
 tcg_temp_free_i32(r_asi);
 }
 
-static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
+static void gen_swap_asi(DisasContext *dc, TCGv dst, TCGv src,
+ TCGv addr, int insn)
 {
-TCGv_i32 r_asi, r_size, r_rd;
+TCGv_i32 r_asi, r_size, r_sign;
+TCGv_i64 s64, t64 = tcg_temp_new_i64();
 
-r_asi = gen_get_asi(insn, addr);
-r_size = tcg_const_i32(size);
-r_rd = tcg_const_i32(rd);
-gen_helper_ldf_asi(cpu_env, addr, r_asi, r_size, r_rd);
-tcg_temp_free_i32(r_rd);
+r_asi = gen_get_asi(dc, insn);
+r_size = tcg_const_i32(4);
+r_sign = tcg_const_i32(0);
+gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_size, r_sign);
+tcg_temp_free_i32(r_sign);
+
+s64 = tcg_temp_new_i64();
+tcg_gen_extu_tl_i64(s64, src);
+gen_helper_st_asi(cpu_env, addr, s64, r_asi, r_size);
+tcg_temp_free_i64(s64);
 tcg_temp_free_i32(r_size);
 tcg_temp_free_i32(r_asi);
+
+tcg_gen_trunc_i64_tl(dst, t64);
+tcg_temp_free_i64(t64);
 }
 
-static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
+static void gen_cas_asi(DisasContext *dc, TCGv addr, TCGv val2,
+int insn, int rd)
+{
+TCGv val1 = gen_load_gpr(dc, rd);
+TCGv dst = gen_dest_gpr(dc, rd);
+TCGv_i32 r_asi = gen_get_asi(dc, insn);
+
+gen_helper_cas_asi(dst, cpu_env, addr, val1, val2, r_asi);
+tcg_temp_free_i32(r_asi);
+gen_store_gpr(dc, rd, dst);
+}
+
+static void gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn)
+{
+TCGv_i32 r_asi, r_size, r_sign;
+TCGv_i64 s64, d64 = tcg_temp_new_i64();
+
+r_asi = gen_get_asi(dc, insn);
+r_size = tcg_const_i32(1);
+r_sign = tcg_const_i32(0);
+gen_helper_ld_asi(d64, cpu_env, addr, r_asi, r_size, r_sign);
+tcg_temp_free_i32(r_sign);
+
+s64 = tcg_const_i64(0xff);
+gen_helper_st_asi(cpu_env, addr, s64, r_asi, r_size);
+tcg_temp_free_i64(s64);
+tcg_temp_free_i32(r_size);
+tcg_temp_free_i32(r_asi);
+
+tcg_gen_trunc_i64_tl(dst, d64);
+tcg_temp_free_i64(d64);
+}
+#endif
+
+#ifdef TARGET_SPARC64
+static void gen_ldf_asi(DisasContext *dc, TCGv addr,
+int insn, int size, int rd)
 {
 TCGv_i32 r_asi, r_size, r_rd;
 
-r_asi = 

[Qemu-devel] [PATCH v2 02/24] target-sparc: Remove softint as a TCG global

2016-02-23 Thread Richard Henderson
The global is only ever read for one insn; we can just as well
use a load from env instead and generate the same code.  This
also allows us to indicate the the associated helpers do not
touch TCG globals.

Signed-off-by: Richard Henderson 
---
 target-sparc/helper.h| 6 +++---
 target-sparc/translate.c | 5 ++---
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index 366d4d1..14712cc 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -21,9 +21,9 @@ DEF_HELPER_4(ldda_asi, void, env, tl, int, int)
 DEF_HELPER_5(ldf_asi, void, env, tl, int, int, int)
 DEF_HELPER_FLAGS_5(stf_asi, TCG_CALL_NO_WG, void, env, tl, int, int, int)
 DEF_HELPER_FLAGS_5(casx_asi, TCG_CALL_NO_WG, tl, env, tl, tl, tl, i32)
-DEF_HELPER_2(set_softint, void, env, i64)
-DEF_HELPER_2(clear_softint, void, env, i64)
-DEF_HELPER_2(write_softint, void, env, i64)
+DEF_HELPER_FLAGS_2(set_softint, TCG_CALL_NO_RWG, void, env, i64)
+DEF_HELPER_FLAGS_2(clear_softint, TCG_CALL_NO_RWG, void, env, i64)
+DEF_HELPER_FLAGS_2(write_softint, TCG_CALL_NO_RWG, void, env, i64)
 DEF_HELPER_FLAGS_2(tick_set_count, TCG_CALL_NO_RWG, void, ptr, i64)
 DEF_HELPER_FLAGS_3(tick_get_count, TCG_CALL_NO_WG, i64, env, ptr, int)
 DEF_HELPER_FLAGS_2(tick_set_limit, TCG_CALL_NO_RWG, void, ptr, i64)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 00d61ee..964735b 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -55,7 +55,6 @@ static TCGv_i32 cpu_xcc, cpu_asi, cpu_fprs;
 static TCGv cpu_gsr;
 static TCGv cpu_tick_cmpr, cpu_stick_cmpr, cpu_hstick_cmpr;
 static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
-static TCGv_i32 cpu_softint;
 #else
 static TCGv cpu_wim;
 #endif
@@ -2742,7 +2741,8 @@ static void disas_sparc_insn(DisasContext * dc, unsigned 
int insn)
 gen_store_gpr(dc, rd, cpu_gsr);
 break;
 case 0x16: /* Softint */
-tcg_gen_ext_i32_tl(cpu_dst, cpu_softint);
+tcg_gen_ld32s_tl(cpu_dst, cpu_env,
+ offsetof(CPUSPARCState, softint));
 gen_store_gpr(dc, rd, cpu_dst);
 break;
 case 0x17: /* Tick compare */
@@ -5348,7 +5348,6 @@ void gen_intermediate_code_init(CPUSPARCState *env)
 { _xcc, offsetof(CPUSPARCState, xcc), "xcc" },
 { _asi, offsetof(CPUSPARCState, asi), "asi" },
 { _fprs, offsetof(CPUSPARCState, fprs), "fprs" },
-{ _softint, offsetof(CPUSPARCState, softint), "softint" },
 #else
 { _wim, offsetof(CPUSPARCState, wim), "wim" },
 #endif
-- 
2.5.0




[Qemu-devel] [PATCH v2 09/24] target-sparc: Import linux/arch/sparc/include/uapi/asm/asi.h

2016-02-23 Thread Richard Henderson
Copied from tag v4.2, 64291f7db5bd8150a74ad2036f1037e6a0428df2.

Signed-off-by: Richard Henderson 
---
 target-sparc/asi.h | 297 +
 1 file changed, 297 insertions(+)
 create mode 100644 target-sparc/asi.h

diff --git a/target-sparc/asi.h b/target-sparc/asi.h
new file mode 100644
index 000..aace6f3
--- /dev/null
+++ b/target-sparc/asi.h
@@ -0,0 +1,297 @@
+#ifndef _SPARC_ASI_H
+#define _SPARC_ASI_H
+
+/* asi.h:  Address Space Identifier values for the sparc.
+ *
+ * Copyright (C) 1995,1996 David S. Miller (da...@caip.rutgers.edu)
+ *
+ * Pioneer work for sun4m: Paul Hatchman (p...@sfe.com.au)
+ * Joint edition for sun4c+sun4m: Pete A. Zaitcev 
+ */
+
+/* The first batch are for the sun4c. */
+
+#define ASI_NULL1   0x00
+#define ASI_NULL2   0x01
+
+/* sun4c and sun4 control registers and mmu/vac ops */
+#define ASI_CONTROL 0x02
+#define ASI_SEGMAP  0x03
+#define ASI_PTE 0x04
+#define ASI_HWFLUSHSEG  0x05
+#define ASI_HWFLUSHPAGE 0x06
+#define ASI_REGMAP  0x06
+#define ASI_HWFLUSHCONTEXT  0x07
+
+#define ASI_USERTXT 0x08
+#define ASI_KERNELTXT   0x09
+#define ASI_USERDATA0x0a
+#define ASI_KERNELDATA  0x0b
+
+/* VAC Cache flushing on sun4c and sun4 */
+#define ASI_FLUSHSEG0x0c
+#define ASI_FLUSHPG 0x0d
+#define ASI_FLUSHCTX0x0e
+
+/* SPARCstation-5: only 6 bits are decoded. */
+/* wo = Write Only, rw = Read Write;*/
+/* ss = Single Size, as = All Sizes;*/
+#define ASI_M_RES00 0x00   /* Don't touch... */
+#define ASI_M_UNA01 0x01   /* Same here... */
+#define ASI_M_MXCC  0x02   /* Access to TI VIKING MXCC registers */
+#define ASI_M_FLUSH_PROBE   0x03   /* Reference MMU Flush/Probe; rw, ss */
+#define ASI_M_MMUREGS   0x04   /* MMU Registers; rw, ss */
+#define ASI_M_TLBDIAG   0x05   /* MMU TLB only Diagnostics */
+#define ASI_M_DIAGS 0x06   /* Reference MMU Diagnostics */
+#define ASI_M_IODIAG0x07   /* MMU I/O TLB only Diagnostics */
+#define ASI_M_USERTXT   0x08   /* Same as ASI_USERTXT; rw, as */
+#define ASI_M_KERNELTXT 0x09   /* Same as ASI_KERNELTXT; rw, as */
+#define ASI_M_USERDATA  0x0A   /* Same as ASI_USERDATA; rw, as */
+#define ASI_M_KERNELDATA0x0B   /* Same as ASI_KERNELDATA; rw, as */
+#define ASI_M_TXTC_TAG  0x0C   /* Instruction Cache Tag; rw, ss */
+#define ASI_M_TXTC_DATA 0x0D   /* Instruction Cache Data; rw, ss */
+#define ASI_M_DATAC_TAG 0x0E   /* Data Cache Tag; rw, ss */
+#define ASI_M_DATAC_DATA0x0F   /* Data Cache Data; rw, ss */
+
+/* The following cache flushing ASIs work only with the 'sta'
+ * instruction. Results are unpredictable for 'swap' and 'ldstuba',
+ * so don't do it.
+ */
+
+/* These ASI flushes affect external caches too. */
+#define ASI_M_FLUSH_PAGE0x10   /* Flush I Cache Line (page); wo, ss */
+#define ASI_M_FLUSH_SEG 0x11   /* Flush I Cache Line (seg); wo, ss */
+#define ASI_M_FLUSH_REGION  0x12   /* Flush I Cache Line (region); wo, ss */
+#define ASI_M_FLUSH_CTX 0x13   /* Flush I Cache Line (context); wo, ss */
+#define ASI_M_FLUSH_USER0x14   /* Flush I Cache Line (user); wo, ss */
+
+/* Block-copy operations are available only on certain V8 cpus. */
+#define ASI_M_BCOPY 0x17   /* Block copy */
+
+/* These affect only the ICACHE and are Ross HyperSparc and TurboSparc 
specific. */
+#define ASI_M_IFLUSH_PAGE   0x18   /* Flush I Cache Line (page); wo, ss */
+#define ASI_M_IFLUSH_SEG0x19   /* Flush I Cache Line (seg); wo, ss */
+#define ASI_M_IFLUSH_REGION 0x1A   /* Flush I Cache Line (region); wo, ss */
+#define ASI_M_IFLUSH_CTX0x1B   /* Flush I Cache Line (context); wo, ss */
+#define ASI_M_IFLUSH_USER   0x1C   /* Flush I Cache Line (user); wo, ss */
+
+/* Block-fill operations are available on certain V8 cpus */
+#define ASI_M_BFILL 0x1F
+
+/* This allows direct access to main memory, actually 0x20 to 0x2f are
+ * the available ASI's for physical ram pass-through, but I don't have
+ * any idea what the other ones do
+ */
+
+#define ASI_M_BYPASS   0x20   /* Reference MMU bypass; rw, as */
+#define ASI_M_FBMEM0x29   /* Graphics card frame buffer access */
+#define ASI_M_VMEUS0x2A   /* VME user 16-bit access */
+#define ASI_M_VMEPS0x2B   /* VME priv 16-bit access */
+#define ASI_M_VMEUT0x2C   /* VME user 32-bit access */
+#define ASI_M_VMEPT0x2D   /* VME priv 32-bit access */
+#define ASI_M_SBUS 0x2E   /* Direct SBus access */
+#define ASI_M_CTL  0x2F   /* Control Space (ECC and MXCC are here) */
+
+
+/* This is ROSS HyperSparc only. */
+#define ASI_M_FLUSH_IWHOLE 0x31   /* Flush entire ICACHE; wo, ss */
+
+/* Tsunami/Viking/TurboSparc i/d cache flash clear. */
+#define ASI_M_IC_FLCLEAR   0x36
+#define ASI_M_DC_FLCLEAR   0x37
+
+#define ASI_M_DCDR 0x39   /* Data Cache 

Re: [Qemu-devel] [RFC 0/1] riscv: Add full-system emulation support for the RISC-V Instruction Set Architecture (RV64G)

2016-02-23 Thread Richard Henderson
On 02/18/2016 05:02 PM, Sagar Karandikar wrote:
> Some notes/questions:
> - This provides support only for the 64-bit version of the ISA and full 
> system 
>   emulation (no user-mode)
> - This currently applies to the 2.5.0 release version. I will bump the
>   underlying codebase, split this into multiple patches, apply style checks 
>   before submitting real patches

Good.

> - The code in target-riscv/fpu-custom-riscv is an updated/modified version of 
>   softfloat. Is it okay to submodule this until the FPU behavior in RISC-V
>   is stabilized?

No.

I suspect that the version of softfloat from which this is branched is quite
old.  You'll find that many bugs have been fixed, and many guest portability
knobs have been added since then.

You appear to have a good set of unit tests whereby you can determine what
knobs need to be tweaked for this target.

Things that jump out at me right away:

target-riscv/cpu-qom.h should be merged into cpu.h.
The separation was artificial for old targets; new targets shouldn't do that.

> +#define get_field(reg, mask) (((reg) & (target_ulong)(mask)) / ((mask) & 
> ~((mask) << 1)))
> +#define set_field(reg, mask, val) (((reg) & ~(target_ulong)(mask)) | 
> (((target_ulong)(val) * ((mask) & ~((mask) << 1))) & (target_ulong)(mask)))

See extract{32,tl,64} and deposit{32,tl,64}.
Though the field mask is curious...

> +struct TCState {
> +target_ulong gpr[32];
> +target_ulong fpr[32];
> +target_ulong PC;
> +target_ulong load_reservation;
> +};
> +
> +typedef struct CPURISCVState CPURISCVState;
> +struct CPURISCVState {
> +TCState active_tc;
> +uint32_t current_tc;

Don't replicate this bit of "active_tc" silliness from target-mips.

Nor riscv-defs.h.

> +// TODO I think this is related to VMState stuff
> +// commenting it out breaks stuff, and there's an #ifdef CPU_SAVE_VERSION
> +// in include/qemu-common.h
> +#define CPU_SAVE_VERSION 3

VMState stuff is now required.

> +DEF_HELPER_3(mulhsu, tl, env, tl, tl)

Use tcg_gen_muls2_i64, with the low part being assigned to a dummy.

> +DEF_HELPER_5(fmadd_s, tl, env, tl, tl, tl, tl)
> +DEF_HELPER_5(fmadd_d, tl, env, tl, tl, tl, tl)

Use DEF_HELPER_FLAGS_*.  None of these fp functions write to TCG registers.

> +static inline void generate_exception (DisasContext *ctx, int excp)

Don't overdo the inline markers.  Particularly with unlikely exceptional cases.
 In fact, begin by not using any at all and let the compiler decide what needs
to be optimized.

> +case OPC_RISC_DIV:
> +{
> +TCGv spec_source1, spec_source2;
> +TCGv cond1, cond2;
> +TCGLabel* handle_zero = gen_new_label();
> +TCGLabel* handle_overflow = gen_new_label();
> +TCGLabel* done = gen_new_label();

See how Aurelien changed the mips port to use movcond to avoid branches here.
Although, with this many special cases for return values it might be better
simply to use a helper function instead.

> +inline static void gen_arith_imm(DisasContext *ctx, uint32_t opc, 
> +  int rd, int rs1, int16_t imm)
...
> +inline static void gen_arith_imm_w(DisasContext *ctx, uint32_t opc, 
> +  int rd, int rs1, int16_t imm)

Surely these can be combined, such that one switch handles both; a final bit
test of opcode & 0x10 should suffice to handle the final sign-extension for the
W instructions.

> +inline static void gen_arith(DisasContext *ctx, uint32_t opc, 
> +  int rd, int rs1, int rs2)
...
> +inline static void gen_arith_w(DisasContext *ctx, uint32_t opc, 
> +  int rd, int rs1, int rs2)

Likewise.

> +case OPC_RISC_LB:
> +tcg_gen_qemu_ld8s(t1, t0, ctx->mem_idx);
> +break;

Update to use tcg_gen_qemu_ld_tl(..., MO_SB) etc.



r~



[Qemu-devel] [Bug 1546445] Re: support vhost user without specifying vhostforce

2016-02-23 Thread Louis Bouchard
** Changed in: qemu (Ubuntu Vivid)
   Status: New => Won't Fix

** No longer affects: qemu (Ubuntu Trusty)

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

Title:
  support vhost user without specifying vhostforce

Status in Ubuntu Cloud Archive:
  New
Status in QEMU:
  In Progress
Status in qemu package in Ubuntu:
  New
Status in qemu source package in Vivid:
  Won't Fix
Status in qemu source package in Wily:
  Fix Released

Bug description:
  [Impact]

   * vhost-user falls back to virtio-net which causes performance lose
  without specifying the vhostforce option. But it should be the default
  behavior for vhost-user, since guests using PMD doesn't support msi-x.

  [Test Case]

create a vhost-user virtio backend without specifying the vhostforce 
option, i.e. -netdev 
type=vhost-user,id=mynet1,chardev=
start the VM
vhost-user is not enabled

  [Regression Potential]

   * none

  vhost user nic doesn't support non msi guests(like pxe stage) by default.
  Vhost user nic can't fall back to qemu like normal vhost net nic does. So we 
should
  enable it for non msi guests.

  The problem has been fix in qemu upstream  -
  
http://git.qemu.org/?p=qemu.git;a=commitdiff;h=24f938a682d934b133863eb421aac33592f7a09e.
  And the patch needs to be backported to 1:2.2+dfsg-5expubuntu9.8 .

To manage notifications about this bug go to:
https://bugs.launchpad.net/cloud-archive/+bug/1546445/+subscriptions



[Qemu-devel] [Bug 1546445] Re: support vhost user without specifying vhostforce

2016-02-23 Thread Edward Hope-Morley
** Also affects: qemu (Ubuntu)
   Importance: Undecided
   Status: New

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

Title:
  support vhost user without specifying vhostforce

Status in QEMU:
  In Progress
Status in qemu package in Ubuntu:
  New
Status in qemu source package in Trusty:
  New
Status in qemu source package in Vivid:
  New
Status in qemu source package in Wily:
  New

Bug description:
  [Impact]

   * vhost-user falls back to virtio-net which causes performance lose
  without specifying the vhostforce option. But it should be the default
  behavior for vhost-user, since guests using PMD doesn't support msi-x.

  [Test Case]

create a vhost-user virtio backend without specifying the vhostforce 
option, i.e. -netdev 
type=vhost-user,id=mynet1,chardev=
start the VM
vhost-user is not enabled

  [Regression Potential]

   * none

  vhost user nic doesn't support non msi guests(like pxe stage) by default.
  Vhost user nic can't fall back to qemu like normal vhost net nic does. So we 
should
  enable it for non msi guests.

  The problem has been fix in qemu upstream  -
  
http://git.qemu.org/?p=qemu.git;a=commitdiff;h=24f938a682d934b133863eb421aac33592f7a09e.
  And the patch needs to be backported to 1:2.2+dfsg-5expubuntu9.8 .

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



[Qemu-devel] [Bug 1546445] Re: support vhost user without specifying vhostforce

2016-02-23 Thread Louis Bouchard
** Also affects: qemu (Ubuntu Wily)
   Importance: Undecided
   Status: New

** Also affects: qemu (Ubuntu Vivid)
   Importance: Undecided
   Status: New

** Also affects: qemu (Ubuntu Trusty)
   Importance: Undecided
   Status: New

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

Title:
  support vhost user without specifying vhostforce

Status in QEMU:
  In Progress
Status in qemu package in Ubuntu:
  New
Status in qemu source package in Trusty:
  New
Status in qemu source package in Vivid:
  New
Status in qemu source package in Wily:
  New

Bug description:
  [Impact]

   * vhost-user falls back to virtio-net which causes performance lose
  without specifying the vhostforce option. But it should be the default
  behavior for vhost-user, since guests using PMD doesn't support msi-x.

  [Test Case]

create a vhost-user virtio backend without specifying the vhostforce 
option, i.e. -netdev 
type=vhost-user,id=mynet1,chardev=
start the VM
vhost-user is not enabled

  [Regression Potential]

   * none

  vhost user nic doesn't support non msi guests(like pxe stage) by default.
  Vhost user nic can't fall back to qemu like normal vhost net nic does. So we 
should
  enable it for non msi guests.

  The problem has been fix in qemu upstream  -
  
http://git.qemu.org/?p=qemu.git;a=commitdiff;h=24f938a682d934b133863eb421aac33592f7a09e.
  And the patch needs to be backported to 1:2.2+dfsg-5expubuntu9.8 .

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



[Qemu-devel] [Bug 1546445] Re: support vhost user without specifying vhostforce

2016-02-23 Thread Liang Chen
** Also affects: cloud-archive
   Importance: Undecided
   Status: New

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

Title:
  support vhost user without specifying vhostforce

Status in Ubuntu Cloud Archive:
  New
Status in QEMU:
  In Progress
Status in qemu package in Ubuntu:
  New
Status in qemu source package in Vivid:
  Won't Fix
Status in qemu source package in Wily:
  Fix Released

Bug description:
  [Impact]

   * vhost-user falls back to virtio-net which causes performance lose
  without specifying the vhostforce option. But it should be the default
  behavior for vhost-user, since guests using PMD doesn't support msi-x.

  [Test Case]

create a vhost-user virtio backend without specifying the vhostforce 
option, i.e. -netdev 
type=vhost-user,id=mynet1,chardev=
start the VM
vhost-user is not enabled

  [Regression Potential]

   * none

  vhost user nic doesn't support non msi guests(like pxe stage) by default.
  Vhost user nic can't fall back to qemu like normal vhost net nic does. So we 
should
  enable it for non msi guests.

  The problem has been fix in qemu upstream  -
  
http://git.qemu.org/?p=qemu.git;a=commitdiff;h=24f938a682d934b133863eb421aac33592f7a09e.
  And the patch needs to be backported to 1:2.2+dfsg-5expubuntu9.8 .

To manage notifications about this bug go to:
https://bugs.launchpad.net/cloud-archive/+bug/1546445/+subscriptions



[Qemu-devel] [Bug 1546445] Re: support vhost user without specifying vhostforce

2016-02-23 Thread Ubuntu Foundations Team Bug Bot
The attachment "debian patch for qemu 1:2.2+dfsg" seems to be a debdiff.
The ubuntu-sponsors team has been subscribed to the bug report so that
they can review and hopefully sponsor the debdiff.  If the attachment
isn't a patch, please remove the "patch" flag from the attachment,
remove the "patch" tag, and if you are member of the ~ubuntu-sponsors,
unsubscribe the team.

[This is an automated message performed by a Launchpad user owned by
~brian-murray, for any issue please contact him.]

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

Title:
  support vhost user without specifying vhostforce

Status in Ubuntu Cloud Archive:
  New
Status in QEMU:
  In Progress
Status in qemu package in Ubuntu:
  New
Status in qemu source package in Vivid:
  Won't Fix
Status in qemu source package in Wily:
  Fix Released

Bug description:
  [Impact]

   * vhost-user falls back to virtio-net which causes performance lose
  without specifying the vhostforce option. But it should be the default
  behavior for vhost-user, since guests using PMD doesn't support msi-x.

  [Test Case]

create a vhost-user virtio backend without specifying the vhostforce 
option, i.e. -netdev 
type=vhost-user,id=mynet1,chardev=
start the VM
vhost-user is not enabled

  [Regression Potential]

   * none

  vhost user nic doesn't support non msi guests(like pxe stage) by default.
  Vhost user nic can't fall back to qemu like normal vhost net nic does. So we 
should
  enable it for non msi guests.

  The problem has been fix in qemu upstream  -
  
http://git.qemu.org/?p=qemu.git;a=commitdiff;h=24f938a682d934b133863eb421aac33592f7a09e.
  And the patch needs to be backported to 1:2.2+dfsg-5expubuntu9.8 .

To manage notifications about this bug go to:
https://bugs.launchpad.net/cloud-archive/+bug/1546445/+subscriptions



[Qemu-devel] [Bug 1546445] Re: support vhost user without specifying vhostforce

2016-02-23 Thread Liang Chen
** Changed in: qemu (Ubuntu Wily)
   Status: New => Fix Released

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

Title:
  support vhost user without specifying vhostforce

Status in Ubuntu Cloud Archive:
  New
Status in QEMU:
  In Progress
Status in qemu package in Ubuntu:
  New
Status in qemu source package in Vivid:
  Won't Fix
Status in qemu source package in Wily:
  Fix Released

Bug description:
  [Impact]

   * vhost-user falls back to virtio-net which causes performance lose
  without specifying the vhostforce option. But it should be the default
  behavior for vhost-user, since guests using PMD doesn't support msi-x.

  [Test Case]

create a vhost-user virtio backend without specifying the vhostforce 
option, i.e. -netdev 
type=vhost-user,id=mynet1,chardev=
start the VM
vhost-user is not enabled

  [Regression Potential]

   * none

  vhost user nic doesn't support non msi guests(like pxe stage) by default.
  Vhost user nic can't fall back to qemu like normal vhost net nic does. So we 
should
  enable it for non msi guests.

  The problem has been fix in qemu upstream  -
  
http://git.qemu.org/?p=qemu.git;a=commitdiff;h=24f938a682d934b133863eb421aac33592f7a09e.
  And the patch needs to be backported to 1:2.2+dfsg-5expubuntu9.8 .

To manage notifications about this bug go to:
https://bugs.launchpad.net/cloud-archive/+bug/1546445/+subscriptions



Re: [Qemu-devel] [Qemu-ppc] [PATCH] hw/intc: fix failure return for xics_alloc_block()

2016-02-23 Thread Greg Kurz
Just pinging Alexey as well. :)

On Tue, 23 Feb 2016 18:46:44 +0100
Greg Kurz  wrote:

> On Wed, 10 Feb 2016 10:41:16 +0100
> Greg Kurz  wrote:
> 
> > On Mon, 8 Feb 2016 09:31:49 +0100
> > Greg Kurz  wrote:
> >   
> > > On Mon, 8 Feb 2016 11:45:19 +1000
> > > David Gibson  wrote:
> > > 
> > > > On Fri, Feb 05, 2016 at 09:43:40AM +0100, Greg Kurz wrote:  
> > > > > From: Brian W. Hart 
> > > > > 
> > > > > xics_alloc_block() does not return a clear error code when it
> > > > > fails to allocate a block of interrupts. Instead it returns the
> > > > > base interrupt number minus 1. This change updates it to return a
> > > > > clear -1 in case of failure (following the example of xics_alloc()).
> > > > > 
> > > > > The two callers of xics_alloc_block() are updated to check for
> > > > > a negative return as an error. They had previously checked for
> > > > > a 0 return as an error, which wrongly treated most failures as
> > > > > successes.
> > > > > 
> > > > > Fixes: bee763dbfb8cfceea112131970da07f215f293a6
> > > > > Signed-off-by: Brian W. Hart 
> > > > > [only pass src and num to trace_xics_alloc_block_failed_no_left,
> > > > >  added trace_xics_alloc_block_failed_no_left definition to 
> > > > > trace-events]
> > > > > Signed-off-by: Greg Kurz 
> > > > 
> > > > Hrm, it would probably be better to give xics_alloc_block() an Error
> > > > ** argument so it can report errors using the new API.
> > > >   
> > > 
> > > Sure. I can rework the patch to do so.
> > > 
> > 
> > The trace_xics_alloc_block_failed_no_left trace is more a debugging thing
> > than an error to be reported to the user. Also, rtas_ibm_change_msi()
> > already has a meaningful error message:
> > 
> > error_report("Cannot allocate MSIs for device %x", config_addr);
> > 
> > So in the end, I'm not sure about the benefit of passing an Error **
> > down to xics_alloc_block().
> >   
> 
> Hi David !
> 
> Given the remarks above, do you still think we should pass Error ** ?
> 
> > > > TBH the whole xics_alloc_block() interface is kind of dubious, or at
> > > > least the ics_find_free_block() part of it.  Dynamically allocating
> > > > irqs to devices is basically awful for migration, so it's better to
> > > > have fixed allocations of all interrupts at the machine level.
> > > >   
> > > 
> > > I agree about the extra complexity, but isn't it the purpose of
> > > the ibm,change-msi RTAS call ? I'm not sure to understand what you
> > > are suggesting...
> > > 
> > 
> > And anyway, even if the decision is made one day to have fixed
> > allocations, shouldn't we consider fixing this bug first ?
> >   
> 
> According to the following commit changelog, the dynamic allocation was
> introduced to support PCI hot(un)plug. Maybe Alexey may explain why it
> got coded this way.
> 
> commit bee763dbfb8cfceea112131970da07f215f293a6
> Author: Alexey Kardashevskiy 
> Date:   Fri May 30 19:34:15 2014 +1000
> 
> spapr: Move interrupt allocator to xics
> 
> I'm not sure of the amount of reflexion and work needed to address your
> concern... Given the time frame, what about deferring xics rework to 2.7
> and fix the bug we currently have in 2.6 ?
> 
> Thanks !
> 
> --
> Greg
> 
> > Cheers.
> > 
> > --
> > Greg
> >   
> > > >   
> > > > > ---
> > > > >  hw/intc/xics.c |   10 ++
> > > > >  hw/ppc/spapr_pci.c |9 +
> > > > >  trace-events   |1 +
> > > > >  3 files changed, 12 insertions(+), 8 deletions(-)
> > > > > 
> > > > > diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> > > > > index cd91ddc4d1d9..3bb77ff96e7b 100644
> > > > > --- a/hw/intc/xics.c
> > > > > +++ b/hw/intc/xics.c
> > > > > @@ -763,11 +763,13 @@ int xics_alloc_block(XICSState *icp, int src, 
> > > > > int num, bool lsi, bool align)
> > > > >  } else {
> > > > >  first = ics_find_free_block(ics, num, 1);
> > > > >  }
> > > > > +if (first < 0) {
> > > > > +trace_xics_alloc_block_failed_no_left(src, num);
> > > > > +return -1;
> > > > > +}
> > > > >  
> > > > > -if (first >= 0) {
> > > > > -for (i = first; i < first + num; ++i) {
> > > > > -ics_set_irq_type(ics, i, lsi);
> > > > > -}
> > > > > +for (i = first; i < first + num; ++i) {
> > > > > +ics_set_irq_type(ics, i, lsi);
> > > > >  }
> > > > >  first += ics->offset;
> > > > >  
> > > > > diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> > > > > index cca9257fecc5..ba33cee2a465 100644
> > > > > --- a/hw/ppc/spapr_pci.c
> > > > > +++ b/hw/ppc/spapr_pci.c
> > > > > @@ -275,7 +275,8 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, 
> > > > > sPAPRMachineState *spapr,
> > > > >  unsigned int req_num = rtas_ld(args, 4); /* 0 == remove all */
> > > > >  unsigned int seq_num = 

  1   2   3   4   >