[Qemu-devel] [PATCH] libvhost-user: introduce and use vu_has_protocol_feature()

2019-09-03 Thread Johannes Berg
From: Johannes Berg 

This simplifies the various has_feature() checks, we already
have vu_has_feature() but it checks features, not protocol
features.

Signed-off-by: Johannes Berg 
---
 contrib/libvhost-user/libvhost-user.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/contrib/libvhost-user/libvhost-user.c 
b/contrib/libvhost-user/libvhost-user.c
index fcf4a8a00ed2..fba291c13db4 100644
--- a/contrib/libvhost-user/libvhost-user.c
+++ b/contrib/libvhost-user/libvhost-user.c
@@ -94,6 +94,11 @@ bool vu_has_feature(VuDev *dev,
 return has_feature(dev->features, fbit);
 }
 
+static inline bool vu_has_protocol_feature(VuDev *dev, unsigned int fbit)
+{
+return has_feature(dev->protocol_features, fbit);
+}
+
 static const char *
 vu_request_to_string(unsigned int req)
 {
@@ -951,8 +956,7 @@ vu_check_queue_inflights(VuDev *dev, VuVirtq *vq)
 {
 int i = 0;
 
-if (!has_feature(dev->protocol_features,
-VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) {
+if (!vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) {
 return 0;
 }
 
@@ -1097,8 +1101,7 @@ bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, 
int fd,
 
 vmsg.fd_num = fd_num;
 
-if (!has_feature(dev->protocol_features,
- VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD)) {
+if (!vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD)) {
 return false;
 }
 
@@ -2199,8 +2202,7 @@ vu_queue_map_desc(VuDev *dev, VuVirtq *vq, unsigned int 
idx, size_t sz)
 static int
 vu_queue_inflight_get(VuDev *dev, VuVirtq *vq, int desc_idx)
 {
-if (!has_feature(dev->protocol_features,
-VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) {
+if (!vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) {
 return 0;
 }
 
@@ -2217,8 +2219,7 @@ vu_queue_inflight_get(VuDev *dev, VuVirtq *vq, int 
desc_idx)
 static int
 vu_queue_inflight_pre_put(VuDev *dev, VuVirtq *vq, int desc_idx)
 {
-if (!has_feature(dev->protocol_features,
-VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) {
+if (!vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) {
 return 0;
 }
 
@@ -2234,8 +2235,7 @@ vu_queue_inflight_pre_put(VuDev *dev, VuVirtq *vq, int 
desc_idx)
 static int
 vu_queue_inflight_post_put(VuDev *dev, VuVirtq *vq, int desc_idx)
 {
-if (!has_feature(dev->protocol_features,
-VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) {
+if (!vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) {
 return 0;
 }
 
-- 
2.23.0




[Qemu-devel] [PULL 5/5] multifd: Use number of channels as listen backlog

2019-09-03 Thread Juan Quintela
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Juan Quintela 
---
 migration/socket.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/migration/socket.c b/migration/socket.c
index e63f5e1612..97c9efde59 100644
--- a/migration/socket.c
+++ b/migration/socket.c
@@ -178,10 +178,15 @@ static void socket_start_incoming_migration(SocketAddress 
*saddr,
 {
 QIONetListener *listener = qio_net_listener_new();
 size_t i;
+int num = 1;
 
 qio_net_listener_set_name(listener, "migration-socket-listener");
 
-if (qio_net_listener_open_sync(listener, saddr, 1, errp) < 0) {
+if (migrate_use_multifd()) {
+num = migrate_multifd_channels();
+}
+
+if (qio_net_listener_open_sync(listener, saddr, num, errp) < 0) {
 object_unref(OBJECT(listener));
 return;
 }
-- 
2.21.0




[Qemu-devel] [PULL 2/5] socket: Add num connections to qio_channel_socket_sync()

2019-09-03 Thread Juan Quintela
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Juan Quintela 
---
 include/io/channel-socket.h| 2 ++
 io/channel-socket.c| 7 ---
 io/net-listener.c  | 2 +-
 io/trace-events| 2 +-
 scsi/qemu-pr-helper.c  | 3 ++-
 tests/test-char.c  | 4 ++--
 tests/test-io-channel-socket.c | 2 +-
 tests/tpm-emu.c| 2 +-
 8 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/include/io/channel-socket.h b/include/io/channel-socket.h
index d7134d2cd6..ed88e5b8c1 100644
--- a/include/io/channel-socket.h
+++ b/include/io/channel-socket.h
@@ -123,6 +123,7 @@ void qio_channel_socket_connect_async(QIOChannelSocket *ioc,
  * qio_channel_socket_listen_sync:
  * @ioc: the socket channel object
  * @addr: the address to listen to
+ * @num: the expected ammount of connections
  * @errp: pointer to a NULL-initialized error object
  *
  * Attempt to listen to the address @addr. This method
@@ -132,6 +133,7 @@ void qio_channel_socket_connect_async(QIOChannelSocket *ioc,
  */
 int qio_channel_socket_listen_sync(QIOChannelSocket *ioc,
SocketAddress *addr,
+   int num,
Error **errp);
 
 /**
diff --git a/io/channel-socket.c b/io/channel-socket.c
index a533c8bc11..6258c25983 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -197,12 +197,13 @@ void qio_channel_socket_connect_async(QIOChannelSocket 
*ioc,
 
 int qio_channel_socket_listen_sync(QIOChannelSocket *ioc,
SocketAddress *addr,
+   int num,
Error **errp)
 {
 int fd;
 
-trace_qio_channel_socket_listen_sync(ioc, addr);
-fd = socket_listen(addr, 1, errp);
+trace_qio_channel_socket_listen_sync(ioc, addr, num);
+fd = socket_listen(addr, num, errp);
 if (fd < 0) {
 trace_qio_channel_socket_listen_fail(ioc);
 return -1;
@@ -226,7 +227,7 @@ static void qio_channel_socket_listen_worker(QIOTask *task,
 SocketAddress *addr = opaque;
 Error *err = NULL;
 
-qio_channel_socket_listen_sync(ioc, addr, &err);
+qio_channel_socket_listen_sync(ioc, addr, 1, &err);
 
 qio_task_set_error(task, err);
 }
diff --git a/io/net-listener.c b/io/net-listener.c
index d8cfe52673..dc81150318 100644
--- a/io/net-listener.c
+++ b/io/net-listener.c
@@ -82,7 +82,7 @@ int qio_net_listener_open_sync(QIONetListener *listener,
 for (i = 0; i < nresaddrs; i++) {
 QIOChannelSocket *sioc = qio_channel_socket_new();
 
-if (qio_channel_socket_listen_sync(sioc, resaddrs[i],
+if (qio_channel_socket_listen_sync(sioc, resaddrs[i], 1,
err ? NULL : &err) == 0) {
 success = true;
 
diff --git a/io/trace-events b/io/trace-events
index 378390521e..2e6aa1d749 100644
--- a/io/trace-events
+++ b/io/trace-events
@@ -17,7 +17,7 @@ qio_channel_socket_connect_sync(void *ioc, void *addr) 
"Socket connect sync ioc=
 qio_channel_socket_connect_async(void *ioc, void *addr) "Socket connect async 
ioc=%p addr=%p"
 qio_channel_socket_connect_fail(void *ioc) "Socket connect fail ioc=%p"
 qio_channel_socket_connect_complete(void *ioc, int fd) "Socket connect 
complete ioc=%p fd=%d"
-qio_channel_socket_listen_sync(void *ioc, void *addr) "Socket listen sync 
ioc=%p addr=%p"
+qio_channel_socket_listen_sync(void *ioc, void *addr, int num) "Socket listen 
sync ioc=%p addr=%p num=%d"
 qio_channel_socket_listen_async(void *ioc, void *addr) "Socket listen async 
ioc=%p addr=%p"
 qio_channel_socket_listen_fail(void *ioc) "Socket listen fail ioc=%p"
 qio_channel_socket_listen_complete(void *ioc, int fd) "Socket listen complete 
ioc=%p fd=%d"
diff --git a/scsi/qemu-pr-helper.c b/scsi/qemu-pr-helper.c
index a256ce490b..a8a74d1dba 100644
--- a/scsi/qemu-pr-helper.c
+++ b/scsi/qemu-pr-helper.c
@@ -1005,7 +1005,8 @@ int main(int argc, char **argv)
 .u.q_unix.path = socket_path,
 };
 server_ioc = qio_channel_socket_new();
-if (qio_channel_socket_listen_sync(server_ioc, &saddr, &local_err) < 
0) {
+if (qio_channel_socket_listen_sync(server_ioc, &saddr,
+   1, &local_err) < 0) {
 object_unref(OBJECT(server_ioc));
 error_report_err(local_err);
 return 1;
diff --git a/tests/test-char.c b/tests/test-char.c
index b56e43c1eb..f3ebdffd87 100644
--- a/tests/test-char.c
+++ b/tests/test-char.c
@@ -667,7 +667,7 @@ char_socket_addr_to_opt_str(SocketAddress *addr, bool 
fd_pass,
 char *optstr;
 g_assert(!reconnect);
 if (is_listen) {
-qio_channel_socket_listen_sync(ioc, addr, &error_abort);
+qio_channel_socket_listen_sync(ioc, addr, 1, &error_abort);
 } else {
 qio_channel_socket_connect_sync(ioc, addr, &error_abort);
 }
@@ -892,7 +892,7 @@ stat

[Qemu-devel] [PULL 4/5] socket: Add num connections to qio_net_listener_open_sync()

2019-09-03 Thread Juan Quintela
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Juan Quintela 
---
 blockdev-nbd.c| 2 +-
 chardev/char-socket.c | 2 +-
 include/io/net-listener.h | 2 ++
 io/net-listener.c | 3 ++-
 migration/socket.c| 2 +-
 qemu-nbd.c| 2 +-
 ui/vnc.c  | 4 ++--
 7 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 7a71da447f..c621686131 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -101,7 +101,7 @@ void nbd_server_start(SocketAddress *addr, const char 
*tls_creds,
 qio_net_listener_set_name(nbd_server->listener,
   "nbd-listener");
 
-if (qio_net_listener_open_sync(nbd_server->listener, addr, errp) < 0) {
+if (qio_net_listener_open_sync(nbd_server->listener, addr, 1, errp) < 0) {
 goto error;
 }
 
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 03f03407b0..185fe38dda 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -1170,7 +1170,7 @@ static int qmp_chardev_open_socket_server(Chardev *chr,
 qio_net_listener_set_name(s->listener, name);
 g_free(name);
 
-if (qio_net_listener_open_sync(s->listener, s->addr, errp) < 0) {
+if (qio_net_listener_open_sync(s->listener, s->addr, 1, errp) < 0) {
 object_unref(OBJECT(s->listener));
 s->listener = NULL;
 return -1;
diff --git a/include/io/net-listener.h b/include/io/net-listener.h
index 8081ac58a2..fb101703e3 100644
--- a/include/io/net-listener.h
+++ b/include/io/net-listener.h
@@ -95,6 +95,7 @@ void qio_net_listener_set_name(QIONetListener *listener,
  * qio_net_listener_open_sync:
  * @listener: the network listener object
  * @addr: the address to listen on
+ * @num: the amount of expected connections
  * @errp: pointer to a NULL initialized error object
  *
  * Synchronously open a listening connection on all
@@ -104,6 +105,7 @@ void qio_net_listener_set_name(QIONetListener *listener,
  */
 int qio_net_listener_open_sync(QIONetListener *listener,
SocketAddress *addr,
+   int num,
Error **errp);
 
 /**
diff --git a/io/net-listener.c b/io/net-listener.c
index dc81150318..5d8a226872 100644
--- a/io/net-listener.c
+++ b/io/net-listener.c
@@ -62,6 +62,7 @@ static gboolean qio_net_listener_channel_func(QIOChannel *ioc,
 
 int qio_net_listener_open_sync(QIONetListener *listener,
SocketAddress *addr,
+   int num,
Error **errp)
 {
 QIODNSResolver *resolver = qio_dns_resolver_get_instance();
@@ -82,7 +83,7 @@ int qio_net_listener_open_sync(QIONetListener *listener,
 for (i = 0; i < nresaddrs; i++) {
 QIOChannelSocket *sioc = qio_channel_socket_new();
 
-if (qio_channel_socket_listen_sync(sioc, resaddrs[i], 1,
+if (qio_channel_socket_listen_sync(sioc, resaddrs[i], num,
err ? NULL : &err) == 0) {
 success = true;
 
diff --git a/migration/socket.c b/migration/socket.c
index 98efdc0286..e63f5e1612 100644
--- a/migration/socket.c
+++ b/migration/socket.c
@@ -181,7 +181,7 @@ static void socket_start_incoming_migration(SocketAddress 
*saddr,
 
 qio_net_listener_set_name(listener, "migration-socket-listener");
 
-if (qio_net_listener_open_sync(listener, saddr, errp) < 0) {
+if (qio_net_listener_open_sync(listener, saddr, 1, errp) < 0) {
 object_unref(OBJECT(listener));
 return;
 }
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 049645491d..83b6c32d73 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -1054,7 +1054,7 @@ int main(int argc, char **argv)
 server = qio_net_listener_new();
 if (socket_activation == 0) {
 saddr = nbd_build_socket_address(sockpath, bindto, port);
-if (qio_net_listener_open_sync(server, saddr, &local_err) < 0) {
+if (qio_net_listener_open_sync(server, saddr, 1, &local_err) < 0) {
 object_unref(OBJECT(server));
 error_report_err(local_err);
 exit(EXIT_FAILURE);
diff --git a/ui/vnc.c b/ui/vnc.c
index 649ce93cd2..bd16746022 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3765,7 +3765,7 @@ static int vnc_display_listen(VncDisplay *vd,
 qio_net_listener_set_name(vd->listener, "vnc-listen");
 for (i = 0; i < nsaddr; i++) {
 if (qio_net_listener_open_sync(vd->listener,
-   saddr[i],
+   saddr[i], 1,
errp) < 0)  {
 return -1;
 }
@@ -3780,7 +3780,7 @@ static int vnc_display_listen(VncDisplay *vd,
 qio_net_listener_set_name(vd->wslistener, "vnc-ws-listen");
 for (i = 0; i < nwsaddr; i++) {
 if (qio_net_listener_open_sync(vd->wslistener,
-   wsaddr[i],
+ 

[Qemu-devel] [PULL 3/5] socket: Add num connections to qio_channel_socket_async()

2019-09-03 Thread Juan Quintela
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Juan Quintela 
---
 include/io/channel-socket.h|  2 ++
 io/channel-socket.c| 30 +++---
 io/trace-events|  2 +-
 tests/test-io-channel-socket.c |  2 +-
 4 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/include/io/channel-socket.h b/include/io/channel-socket.h
index ed88e5b8c1..777ff5954e 100644
--- a/include/io/channel-socket.h
+++ b/include/io/channel-socket.h
@@ -140,6 +140,7 @@ int qio_channel_socket_listen_sync(QIOChannelSocket *ioc,
  * qio_channel_socket_listen_async:
  * @ioc: the socket channel object
  * @addr: the address to listen to
+ * @num: the expected ammount of connections
  * @callback: the function to invoke on completion
  * @opaque: user data to pass to @callback
  * @destroy: the function to free @opaque
@@ -155,6 +156,7 @@ int qio_channel_socket_listen_sync(QIOChannelSocket *ioc,
  */
 void qio_channel_socket_listen_async(QIOChannelSocket *ioc,
  SocketAddress *addr,
+ int num,
  QIOTaskFunc callback,
  gpointer opaque,
  GDestroyNotify destroy,
diff --git a/io/channel-socket.c b/io/channel-socket.c
index 6258c25983..b74f5b92a0 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -220,14 +220,27 @@ int qio_channel_socket_listen_sync(QIOChannelSocket *ioc,
 }
 
 
+struct QIOChannelListenWorkerData {
+SocketAddress *addr;
+int num; /* amount of expected connections */
+};
+
+static void qio_channel_listen_worker_free(gpointer opaque)
+{
+struct QIOChannelListenWorkerData *data = opaque;
+
+qapi_free_SocketAddress(data->addr);
+g_free(data);
+}
+
 static void qio_channel_socket_listen_worker(QIOTask *task,
  gpointer opaque)
 {
 QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
-SocketAddress *addr = opaque;
+struct QIOChannelListenWorkerData *data = opaque;
 Error *err = NULL;
 
-qio_channel_socket_listen_sync(ioc, addr, 1, &err);
+qio_channel_socket_listen_sync(ioc, data->addr, data->num, &err);
 
 qio_task_set_error(task, err);
 }
@@ -235,6 +248,7 @@ static void qio_channel_socket_listen_worker(QIOTask *task,
 
 void qio_channel_socket_listen_async(QIOChannelSocket *ioc,
  SocketAddress *addr,
+ int num,
  QIOTaskFunc callback,
  gpointer opaque,
  GDestroyNotify destroy,
@@ -242,16 +256,18 @@ void qio_channel_socket_listen_async(QIOChannelSocket 
*ioc,
 {
 QIOTask *task = qio_task_new(
 OBJECT(ioc), callback, opaque, destroy);
-SocketAddress *addrCopy;
+struct QIOChannelListenWorkerData *data;
 
-addrCopy = QAPI_CLONE(SocketAddress, addr);
+data = g_new0(struct QIOChannelListenWorkerData, 1);
+data->addr = QAPI_CLONE(SocketAddress, addr);
+data->num = num;
 
 /* socket_listen() blocks in DNS lookups, so we must use a thread */
-trace_qio_channel_socket_listen_async(ioc, addr);
+trace_qio_channel_socket_listen_async(ioc, addr, num);
 qio_task_run_in_thread(task,
qio_channel_socket_listen_worker,
-   addrCopy,
-   (GDestroyNotify)qapi_free_SocketAddress,
+   data,
+   qio_channel_listen_worker_free,
context);
 }
 
diff --git a/io/trace-events b/io/trace-events
index 2e6aa1d749..d7bc70b966 100644
--- a/io/trace-events
+++ b/io/trace-events
@@ -18,7 +18,7 @@ qio_channel_socket_connect_async(void *ioc, void *addr) 
"Socket connect async io
 qio_channel_socket_connect_fail(void *ioc) "Socket connect fail ioc=%p"
 qio_channel_socket_connect_complete(void *ioc, int fd) "Socket connect 
complete ioc=%p fd=%d"
 qio_channel_socket_listen_sync(void *ioc, void *addr, int num) "Socket listen 
sync ioc=%p addr=%p num=%d"
-qio_channel_socket_listen_async(void *ioc, void *addr) "Socket listen async 
ioc=%p addr=%p"
+qio_channel_socket_listen_async(void *ioc, void *addr, int num) "Socket listen 
async ioc=%p addr=%p num=%d"
 qio_channel_socket_listen_fail(void *ioc) "Socket listen fail ioc=%p"
 qio_channel_socket_listen_complete(void *ioc, int fd) "Socket listen complete 
ioc=%p fd=%d"
 qio_channel_socket_dgram_sync(void *ioc, void *localAddr, void *remoteAddr) 
"Socket dgram sync ioc=%p localAddr=%p remoteAddr=%p"
diff --git a/tests/test-io-channel-socket.c b/tests/test-io-channel-socket.c
index 613ada32c0..d43083a766 100644
--- a/tests/test-io-channel-socket.c
+++ b/tests/test-io-channel-socket.c
@@ -113,7 +113,7 @@ static void test_io_channel_setup_async(SocketAddress 
*listen_addr,
 
 lioc = qio_channel_

[Qemu-devel] [PULL 1/5] socket: Add backlog parameter to socket_listen

2019-09-03 Thread Juan Quintela
Current parameter was always one.  We continue with that value for now
in all callers.

Signed-off-by: Juan Quintela 
Reviewed-by: Daniel P. Berrangé 
---
Moved trace to socket_listen
---
 include/qemu/sockets.h|  2 +-
 io/channel-socket.c   |  2 +-
 qga/channel-posix.c   |  2 +-
 tests/test-util-sockets.c | 12 ++--
 util/qemu-sockets.c   | 33 ++---
 util/trace-events |  3 +++
 6 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index 8140fea685..57cd049d6e 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -41,7 +41,7 @@ int unix_connect(const char *path, Error **errp);
 
 SocketAddress *socket_parse(const char *str, Error **errp);
 int socket_connect(SocketAddress *addr, Error **errp);
-int socket_listen(SocketAddress *addr, Error **errp);
+int socket_listen(SocketAddress *addr, int num, Error **errp);
 void socket_listen_cleanup(int fd, Error **errp);
 int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp);
 
diff --git a/io/channel-socket.c b/io/channel-socket.c
index bec3d931d1..a533c8bc11 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -202,7 +202,7 @@ int qio_channel_socket_listen_sync(QIOChannelSocket *ioc,
 int fd;
 
 trace_qio_channel_socket_listen_sync(ioc, addr);
-fd = socket_listen(addr, errp);
+fd = socket_listen(addr, 1, errp);
 if (fd < 0) {
 trace_qio_channel_socket_listen_fail(ioc);
 return -1;
diff --git a/qga/channel-posix.c b/qga/channel-posix.c
index 5a925a9818..8fc205ad21 100644
--- a/qga/channel-posix.c
+++ b/qga/channel-posix.c
@@ -215,7 +215,7 @@ static gboolean ga_channel_open(GAChannel *c, const gchar 
*path,
 return false;
 }
 
-fd = socket_listen(addr, &local_err);
+fd = socket_listen(addr, 1, &local_err);
 qapi_free_SocketAddress(addr);
 if (local_err != NULL) {
 g_critical("%s", error_get_pretty(local_err));
diff --git a/tests/test-util-sockets.c b/tests/test-util-sockets.c
index e2a3a8a093..8ce55efe70 100644
--- a/tests/test-util-sockets.c
+++ b/tests/test-util-sockets.c
@@ -93,7 +93,7 @@ static void test_socket_fd_pass_name_good(void)
 g_assert_cmpint(fd, !=, mon_fd);
 close(fd);
 
-fd = socket_listen(&addr, &error_abort);
+fd = socket_listen(&addr, 1, &error_abort);
 g_assert_cmpint(fd, !=, -1);
 g_assert_cmpint(fd, !=, mon_fd);
 close(fd);
@@ -124,7 +124,7 @@ static void test_socket_fd_pass_name_bad(void)
 g_assert_cmpint(fd, ==, -1);
 error_free_or_abort(&err);
 
-fd = socket_listen(&addr, &err);
+fd = socket_listen(&addr, 1, &err);
 g_assert_cmpint(fd, ==, -1);
 error_free_or_abort(&err);
 
@@ -151,7 +151,7 @@ static void test_socket_fd_pass_name_nomon(void)
 g_assert_cmpint(fd, ==, -1);
 error_free_or_abort(&err);
 
-fd = socket_listen(&addr, &err);
+fd = socket_listen(&addr, 1, &err);
 g_assert_cmpint(fd, ==, -1);
 error_free_or_abort(&err);
 
@@ -174,7 +174,7 @@ static void test_socket_fd_pass_num_good(void)
 fd = socket_connect(&addr, &error_abort);
 g_assert_cmpint(fd, ==, sfd);
 
-fd = socket_listen(&addr, &error_abort);
+fd = socket_listen(&addr, 1, &error_abort);
 g_assert_cmpint(fd, ==, sfd);
 
 g_free(addr.u.fd.str);
@@ -197,7 +197,7 @@ static void test_socket_fd_pass_num_bad(void)
 g_assert_cmpint(fd, ==, -1);
 error_free_or_abort(&err);
 
-fd = socket_listen(&addr, &err);
+fd = socket_listen(&addr, 1, &err);
 g_assert_cmpint(fd, ==, -1);
 error_free_or_abort(&err);
 
@@ -220,7 +220,7 @@ static void test_socket_fd_pass_num_nocli(void)
 g_assert_cmpint(fd, ==, -1);
 error_free_or_abort(&err);
 
-fd = socket_listen(&addr, &err);
+fd = socket_listen(&addr, 1, &err);
 g_assert_cmpint(fd, ==, -1);
 error_free_or_abort(&err);
 
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index e3a1666578..98ff3a1cce 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -31,6 +31,7 @@
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/qobject-output-visitor.h"
 #include "qemu/cutils.h"
+#include "trace.h"
 
 #ifndef AI_ADDRCONFIG
 # define AI_ADDRCONFIG 0
@@ -207,6 +208,7 @@ static int try_bind(int socket, InetSocketAddress *saddr, 
struct addrinfo *e)
 
 static int inet_listen_saddr(InetSocketAddress *saddr,
  int port_offset,
+ int num,
  Error **errp)
 {
 struct addrinfo ai,*res,*e;
@@ -309,7 +311,7 @@ static int inet_listen_saddr(InetSocketAddress *saddr,
 goto listen_failed;
 }
 } else {
-if (!listen(slisten, 1)) {
+if (!listen(slisten, num)) {
 goto listen_ok;
 }
 if (errno != EADDRINUSE) {
@@ -

[Qemu-devel] [PULL 0/5] Fail patches

2019-09-03 Thread Juan Quintela
The following changes since commit 3483534ec314f6057e66966bfceaa9df02c28fbf:

  Merge remote-tracking branch 'remotes/cleber/tags/python-next-pull-request' 
into staging (2019-09-03 16:48:37 +0100)

are available in the Git repository at:

  https://github.com/juanquintela/qemu.git tags/fail-pull-request

for you to fetch changes up to 0705e56496d2b155b5796c6b28d4110e5bcbd5d8:

  multifd: Use number of channels as listen backlog (2019-09-03 23:24:42 +0200)


Fix multifd with big number of channels

As all of it is migration, danp told me to do the pull myself.



Juan Quintela (5):
  socket: Add backlog parameter to socket_listen
  socket: Add num connections to qio_channel_socket_sync()
  socket: Add num connections to qio_channel_socket_async()
  socket: Add num connections to qio_net_listener_open_sync()
  multifd: Use number of channels as listen backlog

 blockdev-nbd.c |  2 +-
 chardev/char-socket.c  |  2 +-
 include/io/channel-socket.h|  4 
 include/io/net-listener.h  |  2 ++
 include/qemu/sockets.h |  2 +-
 io/channel-socket.c| 35 +-
 io/net-listener.c  |  3 ++-
 io/trace-events|  4 ++--
 migration/socket.c |  7 ++-
 qemu-nbd.c |  2 +-
 qga/channel-posix.c|  2 +-
 scsi/qemu-pr-helper.c  |  3 ++-
 tests/test-char.c  |  4 ++--
 tests/test-io-channel-socket.c |  4 ++--
 tests/test-util-sockets.c  | 12 ++--
 tests/tpm-emu.c|  2 +-
 ui/vnc.c   |  4 ++--
 util/qemu-sockets.c| 33 +---
 util/trace-events  |  3 +++
 19 files changed, 87 insertions(+), 43 deletions(-)

-- 
2.21.0




Re: [Qemu-devel] [PATCH] numa: Introduce MachineClass::auto_enable_numa for implicit NUMA node

2019-09-03 Thread Tao Xu

On 9/4/2019 1:52 AM, Eduardo Habkost wrote:

On Mon, Aug 05, 2019 at 03:13:02PM +0800, Tao Xu wrote:

Add MachineClass::auto_enable_numa field. When it is true, a NUMA node
is expected to be created implicitly.

Acked-by: David Gibson 
Suggested-by: Igor Mammedov 
Suggested-by: Eduardo Habkost 
Signed-off-by: Tao Xu 


This introduces spurious warnings when running qemu-system-ppc64.
See: 
https://lore.kernel.org/qemu-devel/CAFEAcA-AvFS2cbDH-t5SxgY9hA=lgl81_8dn-vh193vtv9w...@mail.gmail.com/

To reproduce it, just run 'qemu-system-ppc64 -machine pseries'
without any -numa arguments.

I have removed this patch from machine-next so it won't block the
existing pull request.


I got it. If default splitting of RAM between nodes is
deprecated, this patch can't reuse the splitting code. I agree with 
droping this patch.




Re: [Qemu-devel] [PATCH v4 3/3] qcow2: add zstd cluster compression

2019-09-03 Thread Denis Plotnikov
Kevin, thanks for commenting. I'll resend the series shortly.

Denis

On 03.09.2019 17:12, Kevin Wolf wrote:
> Am 28.08.2019 um 14:56 hat Denis Plotnikov geschrieben:
>> zstd significantly reduces cluster compression time.
>> It provides better compression performance maintaining
>> the same level of compression ratio in comparison with
>> zlib, which, at the moment, has been the only compression
>> method available.
>>
>> The performance test results:
>> Test compresses and decompresses qemu qcow2 image with just
>> installed rhel-7.6 guest.
>> Image cluster size: 64K. Image on disk size: 2.2G
>>
>> The test was conducted with brd disk to reduce the influence
>> of disk subsystem to the test results.
>> The results is given in seconds.
>>
>> compress cmd:
>>time ./qemu-img convert -O qcow2 -c -o compression_type=[zlib|zstd]
>>src.img [zlib|zstd]_compressed.img
>> decompress cmd
>>time ./qemu-img convert -O qcow2
>>[zlib|zstd]_compressed.img uncompressed.img
>>
>> compression   decompression
>>   zlib   zstd   zlib zstd
>> 
>> real 65.5   16.3 (-75 %)1.9  1.6 (-16 %)
>> user 65.0   15.85.3  2.5
>> sys   3.30.22.0  2.0
>>
>> Both ZLIB and ZSTD gave the same compression ratio: 1.57
>> compressed image size in both cases: 1.4G
>>
>> Signed-off-by: Denis Plotnikov 
>> ---
>>   block/qcow2-threads.c  | 107 +
>>   block/qcow2.c  |   7 +++
>>   configure  |  34 +
>>   docs/interop/qcow2.txt |  20 
>>   qapi/block-core.json   |   3 +-
>>   5 files changed, 170 insertions(+), 1 deletion(-)
>>
>> diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c
>> index 14b5bd76fb..f6643976f4 100644
>> --- a/block/qcow2-threads.c
>> +++ b/block/qcow2-threads.c
>> @@ -28,6 +28,11 @@
>>   #define ZLIB_CONST
>>   #include 
>>   
>> +#ifdef CONFIG_ZSTD
>> +#include 
>> +#include 
>> +#endif
>> +
>>   #include "qcow2.h"
>>   #include "block/thread-pool.h"
>>   #include "crypto.h"
>> @@ -165,6 +170,98 @@ static ssize_t qcow2_zlib_decompress(void *dest, size_t 
>> dest_size,
>>   return ret;
>>   }
>>   
>> +#ifdef CONFIG_ZSTD
>> +/*
>> + * qcow2_zstd_compress()
>> + *
>> + * Compress @src_size bytes of data using zstd compression method
>> + *
>> + * @dest - destination buffer, @dest_size bytes
>> + * @src - source buffer, @src_size bytes
>> + *
>> + * Returns: compressed size on success
>> + *  -ENOMEM destination buffer is not enough to store compressed 
>> data
>> + *  -EIOon any other error
>> + */
>> +
>> +static ssize_t qcow2_zstd_compress(void *dest, size_t dest_size,
>> +   const void *src, size_t src_size)
>> +{
>> +ssize_t ret;
>> +uint32_t *c_size = dest;
>> +/* steal some bytes to store compressed chunk size */
>> +char *d_buf = ((char *) dest) + sizeof(*c_size);
>> +
>> +/* snaity check that we can store the compressed data length */
> sanity
>
>> +if (dest_size < sizeof(*c_size)) {
>> +return -ENOMEM;
>> +}
>> +
>> +dest_size -= sizeof(*c_size);
>> +
>> +ret = ZSTD_compress(d_buf, dest_size, src, src_size, 5);
>> +
>> +if (ZSTD_isError(ret)) {
>> +if (ZSTD_getErrorCode(ret) == ZSTD_error_dstSize_tooSmall) {
>> +return -ENOMEM;
>> +} else {
>> +return -EIO;
>> +}
>> +}
>> +
>> +/* store the compressed chunk size in the very beginning of the buffer 
>> */
>> +*c_size = cpu_to_be32(ret);
>> +
>> +return ret + sizeof(*c_size);
>> +}
>> +
>> +/*
>> + * qcow2_zstd_decompress()
>> + *
>> + * Decompress some data (not more than @src_size bytes) to produce exactly
>> + * @dest_size bytes using zstd compression method
>> + *
>> + * @dest - destination buffer, @dest_size bytes
>> + * @src - source buffer, @src_size bytes
>> + *
>> + * Returns: 0 on success
>> + *  -EIO on any error
>> + */
>> +
>> +static ssize_t qcow2_zstd_decompress(void *dest, size_t dest_size,
>> + const void *src, size_t src_size)
>> +{
>> +ssize_t ret;
>> +/*
>> + * zstd decompress wants to know the exact length of the data
>> + * for that purpose, on the compression the length is stored in
>> + * the very beginning of the compressed buffer
>> + */
>> +uint32_t s_size;
>> +const char *s_buf = ((const char *) src) + sizeof(s_size);
>> +
>> +/* sanity check that we can read the content length */
>> +if (src_size < sizeof(s_size)) {
>> +return -EIO;
>> +}
>> +
>> +s_size = be32_to_cpu( *(const uint32_t *) src);
>> +
>> +/* sanity check that the buffer is big enough to read the content */
>> +if (src_size - sizeof(s_size) < s_size) {
>> +return -EIO;
>> +}
>> +

Re: [Qemu-devel] [PATCH] memory: Set notdirty_mem_ops validator

2019-09-03 Thread Tony Nguyen
On Tue, Sep 03, 2019 at 05:50:56PM +0100, Peter Maydell wrote:
> Do you have a backtrace of QEMU from the segfault? I'm having trouble
> thinking of what the situation is when we'd try to invoke the
> read handler on io_mem_notdirty...

Using tcg-next 
https://github.com/rth7680/qemu/commit/c25c283df0f08582df29f1d5d7be1516b851532d.

#0  0x in  ()
#1  0x55a694329099 in memory_region_read_with_attrs_accessor 
(mr=0x55a69503c6c0 , addr=3874654208, value=0x7fdac32c40e8, 
size=4, shift=0, mask=4294967295, attrs=...)
at /home/tony/dev/qemu/memory.c:461
#2  0x55a6943293fd in access_with_adjusted_size (addr=3874654208, 
value=0x7fdac32c40e8, size=4, access_size_min=1, access_size_max=8, access_fn=
0x55a69432903d , mr=0x55a69503c6c0 
, attrs=...) at /home/tony/dev/qemu/memory.c:559
#3  0x55a69432c239 in memory_region_dispatch_read1 (mr=0x55a69503c6c0 
, addr=3874654208, pval=0x7fdac32c40e8, size=4, attrs=...) at 
/home/tony/dev/qemu/memory.c:1429
#4  0x55a69432c2c9 in memory_region_dispatch_read (mr=0x55a69503c6c0 
, addr=3874654208, pval=0x7fdac32c40e8, op=MO_32, attrs=...) 
at /home/tony/dev/qemu/memory.c:1451
#5  0x55a694341e4f in io_readx (env=0x55a695942da0, iotl=0x7fdabcdee440, 
mmu_idx=2, addr=3298570569728, retaddr=14057764820, 
access_type=MMU_DATA_LOAD, op=MO_32)
at /home/tony/dev/qemu/accel/tcg/cputlb.c:923
#6  0x55a69434493e in full_be_ldul_mmu (full_load=0x55a69434458a 
, code_read=false, op=MO_BEUL, retaddr=14057764820, 
oi=162, addr=3298570569728, env=0x55a695942da0)
at /home/tony/dev/qemu/accel/tcg/cputlb.c:1346
#7  0x55a69434493e in full_be_ldul_mmu (env=0x55a695942da0, 
addr=3298570569728, oi=162, retaddr=14057764820) at 
/home/tony/dev/qemu/accel/tcg/cputlb.c:1469
#8  0x55a694344bd5 in helper_be_ldul_mmu (env=0x55a695942da0, 
addr=3298570569728, oi=162, retaddr=14057764820) at 
/home/tony/dev/qemu/accel/tcg/cputlb.c:1476
#9  0x7fdac8ce3639 in  ()
#10 0x0400 in  ()
#11 0x7fdabc000a10 in  ()
#12 0x7fdac32c42a0 in  ()
#13 0x55a6942d8795 in tcg_temp_free_internal (ts=0x7fdabc0652e0)
at /home/tony/dev/qemu/tcg/tcg.c:1330

In frame 5 iotlbentry->addr is 18446740779013636097. Perhaps not a sane value?

Defines in target/sparc/cpu-params.h and include/exec/cpu-all.h:
TARGET_PAGE_BITS 13
TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)

iotlb_to_section resolves (iotlbentry->addr & ~TARGET_PAGE_MASK) to 1,
which is io_mem_notdirty.

(gdb) frame 5
#5  0x55a694341e4f inv=0x55a695942da0, iotlbentry=0x7fdabcdee440, 
mmu_idx=2, 
addr=3298570569728, retaddr=14057764820, access_type=MMU_DATA_LOAD, 
op=MO_32)
at /home/tony/dev/qemu/accel/tcg/cputlb.c:923
(gdb) print iotlbentry->addr
$1 = 18446740779013636097
(gdb) print iotlbentry->attrs
$2 = {unspecified = 0, secure = 0, user = 0, requester_id = 0, byte_swap = 1, 
  target_tlb_bit0 = 0, target_tlb_bit1 = 0, target_tlb_bit2 = 0}
(gdb) print cpu->cpu_ases[0]->memory_dispatch->map.sections[1]
$3 = {mr = 0x55a69503c6c0 , fv = 0x7fdabc86ca00, 
offset_within_region = 0, 
  size = 0x0001, offset_within_address_space = 0, 
  readonly = false, nonvolatile = false}

Watching sun4u Solaris 10 boot messages, it occurs when sunhme PCI device is
configured.



[Qemu-devel] [PATCH] vnc: fix websocket field in events

2019-09-03 Thread Gerd Hoffmann
Just need to fill VncClientInfo.websocket in vnc_client_cache_addr().

Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1748175
Signed-off-by: Gerd Hoffmann 
---
 ui/vnc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/ui/vnc.c b/ui/vnc.c
index 649ce93cd24c..e318bfc1ed2f 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -278,6 +278,7 @@ static void vnc_client_cache_addr(VncState *client)
 vnc_init_basic_info_from_remote_addr(client->sioc,
  qapi_VncClientInfo_base(client->info),
  &err);
+client->info->websocket = client->websocket;
 if (err) {
 qapi_free_VncClientInfo(client->info);
 client->info = NULL;
-- 
2.18.1




Re: [Qemu-devel] [PATCH for-4.2 v10 08/15] virtio-iommu: Implement map/unmap

2019-09-03 Thread Tian, Kevin
> From: Peter Xu [mailto:pet...@redhat.com]
> Sent: Wednesday, September 4, 2019 1:37 PM
> 
> On Wed, Sep 04, 2019 at 04:23:50AM +, Tian, Kevin wrote:
> > > From: Peter Xu [mailto:pet...@redhat.com]
> > > Sent: Wednesday, September 4, 2019 9:44 AM
> > >
> > > On Tue, Sep 03, 2019 at 01:37:11PM +0200, Auger Eric wrote:
> > > > Hi Peter,
> > > >
> > > > On 8/19/19 10:11 AM, Peter Xu wrote:
> > > > > On Tue, Jul 30, 2019 at 07:21:30PM +0200, Eric Auger wrote:
> > > > >
> > > > > [...]
> > > > >
> > > > >> +mapping = g_tree_lookup(domain->mappings,
> (gpointer)(&interval));
> > > > >> +
> > > > >> +while (mapping) {
> > > > >> +viommu_interval current;
> > > > >> +uint64_t low  = mapping->virt_addr;
> > > > >> +uint64_t high = mapping->virt_addr + mapping->size - 1;
> > > > >> +
> > > > >> +current.low = low;
> > > > >> +current.high = high;
> > > > >> +
> > > > >> +if (low == interval.low && size >= mapping->size) {
> > > > >> +g_tree_remove(domain->mappings, (gpointer)(¤t));
> > > > >> +interval.low = high + 1;
> > > > >> +trace_virtio_iommu_unmap_left_interval(current.low,
> > > current.high,
> > > > >> +interval.low, interval.high);
> > > > >> +} else if (high == interval.high && size >= mapping->size) {
> > > > >> +trace_virtio_iommu_unmap_right_interval(current.low,
> > > current.high,
> > > > >> +interval.low, interval.high);
> > > > >> +g_tree_remove(domain->mappings, (gpointer)(¤t));
> > > > >> +interval.high = low - 1;
> > > > >> +} else if (low > interval.low && high < interval.high) {
> > > > >> +trace_virtio_iommu_unmap_inc_interval(current.low,
> > > current.high);
> > > > >> +g_tree_remove(domain->mappings, (gpointer)(¤t));
> > > > >> +} else {
> > > > >> +break;
> > > > >> +}
> > > > >> +if (interval.low >= interval.high) {
> > > > >> +return VIRTIO_IOMMU_S_OK;
> > > > >> +} else {
> > > > >> +mapping = g_tree_lookup(domain->mappings,
> > > (gpointer)(&interval));
> > > > >> +}
> > > > >> +}
> > > > >> +
> > > > >> +if (mapping) {
> > > > >> +qemu_log_mask(LOG_GUEST_ERROR,
> > > > >> +  "** %s: Unmap 0x%"PRIx64" size=0x%"PRIx64
> > > > >> + " from 0x%"PRIx64" size=0x%"PRIx64" is not 
> > > > >> supported\n",
> > > > >> + __func__, interval.low, size,
> > > > >> + mapping->virt_addr, mapping->size);
> > > > >> +} else {
> > > > >> +return VIRTIO_IOMMU_S_OK;
> > > > >> +}
> > > > >> +
> > > > >> +return VIRTIO_IOMMU_S_INVAL;
> > > > >
> > > > > Could the above chunk be simplified as something like below?
> > > > >
> > > > >   while ((mapping = g_tree_lookup(domain->mappings, &interval))) {
> > > > > g_tree_remove(domain->mappings, mapping);
> > > > >   }
> > > > Indeed the code could be simplified. I only need to make sure I don't
> > > > split an existing mapping.
> > >
> > > Hmm... Do we need to still split an existing mapping if necessary?
> > > For example when with this mapping:
> > >
> > >   iova=0x1000, size=0x2000, phys=ADDR1, flags=FLAGS1
> > >
> > > And if we want to unmap the range (iova=0, size=0x2000), then we
> > > should split the existing mappping and leave this one:
> > >
> > >   iova=0x2000, size=0x1000, phys=(ADDR1+0x1000), flags=FLAGS1
> > >
> > > Right?
> > >
> >
> > virtio-iommu spec explicitly disallows partial unmap.
> >
> > 5.11.6.6.1 Driver Requirements: UNMAP request
> >
> > The first address of a range MUST either be the first address of a
> > mapping or be outside any mapping. The last address of a range
> > MUST either be the last address of a mapping or be outside any
> > mapping.
> >
> > 5.11.6.6.2 Device Requirements: UNMAP request
> >
> > If a mapping affected by the range is not covered in its entirety
> > by the range (the UNMAP request would split the mapping),
> > then the device SHOULD set the request status to VIRTIO_IOMMU
> > _S_RANGE, and SHOULD NOT remove any mapping.
> 
> I see, thanks Kevin.
> 
> Though why so strict?  (Sorry if I missed some discussions
> ... pointers welcomed...)
> 
> What I'm thinking is when we want to allocate a bunch of buffers
> (e.g., 1M) while we will also need to be able to free them with
> smaller chunks (e.g., 4K), then it would be even better that we allow
> to allocate a whole 1M buffer within the guest and map it as a whole,
> then we can selectively unmap the pages after used.  If with the
> strict rule, we'll need to map one by one, that can be a total of
> 1M/4K roundtrips.
> 

Sorry I forgot the original discussion. Need Jean to respond. :-)

A possible reason is that no such usage exists today, thus simplification
was made? 

Thanks
Kevin


Re: [Qemu-devel] [PATCH for-4.2 v10 08/15] virtio-iommu: Implement map/unmap

2019-09-03 Thread Peter Xu
On Wed, Sep 04, 2019 at 04:23:50AM +, Tian, Kevin wrote:
> > From: Peter Xu [mailto:pet...@redhat.com]
> > Sent: Wednesday, September 4, 2019 9:44 AM
> > 
> > On Tue, Sep 03, 2019 at 01:37:11PM +0200, Auger Eric wrote:
> > > Hi Peter,
> > >
> > > On 8/19/19 10:11 AM, Peter Xu wrote:
> > > > On Tue, Jul 30, 2019 at 07:21:30PM +0200, Eric Auger wrote:
> > > >
> > > > [...]
> > > >
> > > >> +mapping = g_tree_lookup(domain->mappings, (gpointer)(&interval));
> > > >> +
> > > >> +while (mapping) {
> > > >> +viommu_interval current;
> > > >> +uint64_t low  = mapping->virt_addr;
> > > >> +uint64_t high = mapping->virt_addr + mapping->size - 1;
> > > >> +
> > > >> +current.low = low;
> > > >> +current.high = high;
> > > >> +
> > > >> +if (low == interval.low && size >= mapping->size) {
> > > >> +g_tree_remove(domain->mappings, (gpointer)(¤t));
> > > >> +interval.low = high + 1;
> > > >> +trace_virtio_iommu_unmap_left_interval(current.low,
> > current.high,
> > > >> +interval.low, interval.high);
> > > >> +} else if (high == interval.high && size >= mapping->size) {
> > > >> +trace_virtio_iommu_unmap_right_interval(current.low,
> > current.high,
> > > >> +interval.low, interval.high);
> > > >> +g_tree_remove(domain->mappings, (gpointer)(¤t));
> > > >> +interval.high = low - 1;
> > > >> +} else if (low > interval.low && high < interval.high) {
> > > >> +trace_virtio_iommu_unmap_inc_interval(current.low,
> > current.high);
> > > >> +g_tree_remove(domain->mappings, (gpointer)(¤t));
> > > >> +} else {
> > > >> +break;
> > > >> +}
> > > >> +if (interval.low >= interval.high) {
> > > >> +return VIRTIO_IOMMU_S_OK;
> > > >> +} else {
> > > >> +mapping = g_tree_lookup(domain->mappings,
> > (gpointer)(&interval));
> > > >> +}
> > > >> +}
> > > >> +
> > > >> +if (mapping) {
> > > >> +qemu_log_mask(LOG_GUEST_ERROR,
> > > >> +  "** %s: Unmap 0x%"PRIx64" size=0x%"PRIx64
> > > >> + " from 0x%"PRIx64" size=0x%"PRIx64" is not 
> > > >> supported\n",
> > > >> + __func__, interval.low, size,
> > > >> + mapping->virt_addr, mapping->size);
> > > >> +} else {
> > > >> +return VIRTIO_IOMMU_S_OK;
> > > >> +}
> > > >> +
> > > >> +return VIRTIO_IOMMU_S_INVAL;
> > > >
> > > > Could the above chunk be simplified as something like below?
> > > >
> > > >   while ((mapping = g_tree_lookup(domain->mappings, &interval))) {
> > > > g_tree_remove(domain->mappings, mapping);
> > > >   }
> > > Indeed the code could be simplified. I only need to make sure I don't
> > > split an existing mapping.
> > 
> > Hmm... Do we need to still split an existing mapping if necessary?
> > For example when with this mapping:
> > 
> >   iova=0x1000, size=0x2000, phys=ADDR1, flags=FLAGS1
> > 
> > And if we want to unmap the range (iova=0, size=0x2000), then we
> > should split the existing mappping and leave this one:
> > 
> >   iova=0x2000, size=0x1000, phys=(ADDR1+0x1000), flags=FLAGS1
> > 
> > Right?
> > 
> 
> virtio-iommu spec explicitly disallows partial unmap.
> 
> 5.11.6.6.1 Driver Requirements: UNMAP request
> 
> The first address of a range MUST either be the first address of a 
> mapping or be outside any mapping. The last address of a range 
> MUST either be the last address of a mapping or be outside any 
> mapping.
> 
> 5.11.6.6.2 Device Requirements: UNMAP request
> 
> If a mapping affected by the range is not covered in its entirety 
> by the range (the UNMAP request would split the mapping), 
> then the device SHOULD set the request status to VIRTIO_IOMMU
> _S_RANGE, and SHOULD NOT remove any mapping.

I see, thanks Kevin.

Though why so strict?  (Sorry if I missed some discussions
... pointers welcomed...)

What I'm thinking is when we want to allocate a bunch of buffers
(e.g., 1M) while we will also need to be able to free them with
smaller chunks (e.g., 4K), then it would be even better that we allow
to allocate a whole 1M buffer within the guest and map it as a whole,
then we can selectively unmap the pages after used.  If with the
strict rule, we'll need to map one by one, that can be a total of
1M/4K roundtrips.

Regards,

-- 
Peter Xu



[Qemu-devel] [PATCH] Replace '-machine accel=xyz' with '-accel xyz'

2019-09-03 Thread Thomas Huth
We've got a separate option to configure the accelerator nowadays, which
is shorter to type and the preferred way of specifying an accelerator.
Use it in the source and examples to show that it is the favored option.
(However, do not touch the places yet which also specify other machine
options or multiple accelerators - these are currently still better
handled with one single "-machine" statement instead)

Signed-off-by: Thomas Huth 
---
 python/qemu/qtest.py| 2 +-
 qemu-deprecated.texi| 3 +--
 qemu-options.hx | 2 +-
 tests/libqtest.c| 2 +-
 tests/migration/guestperf/engine.py | 2 +-
 tests/qemu-iotests/172  | 2 +-
 6 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/python/qemu/qtest.py b/python/qemu/qtest.py
index eebcc233ed..3f1d2cb325 100644
--- a/python/qemu/qtest.py
+++ b/python/qemu/qtest.py
@@ -96,7 +96,7 @@ class QEMUQtestMachine(QEMUMachine):
 def _base_args(self):
 args = super(QEMUQtestMachine, self)._base_args()
 args.extend(['-qtest', 'unix:path=' + self._qtest_path,
- '-machine', 'accel=qtest'])
+ '-accel', 'qtest'])
 return args
 
 def _pre_launch(self):
diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi
index 00a4b6f350..0982e41698 100644
--- a/qemu-deprecated.texi
+++ b/qemu-deprecated.texi
@@ -26,8 +26,7 @@ The @option{enforce-config-section} parameter is replaced by 
the
 
 @subsection -no-kvm (since 1.3.0)
 
-The ``-no-kvm'' argument is now a synonym for setting
-``-machine accel=tcg''.
+The ``-no-kvm'' argument is now a synonym for setting ``-accel tcg''.
 
 @subsection -usbdevice (since 2.10.0)
 
diff --git a/qemu-options.hx b/qemu-options.hx
index 09e6439646..e0bba2abd1 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4156,7 +4156,7 @@ STEXI
 Enable FIPS 140-2 compliance mode.
 ETEXI
 
-HXCOMM Deprecated by -machine accel=tcg property
+HXCOMM Deprecated by -accel tcg
 DEF("no-kvm", 0, QEMU_OPTION_no_kvm, "", QEMU_ARCH_I386)
 
 DEF("msg", HAS_ARG, QEMU_OPTION_msg,
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 2713b86cf7..67e39c59e7 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -238,7 +238,7 @@ QTestState *qtest_init_without_qmp_handshake(const char 
*extra_args)
   "-qtest-log %s "
   "-chardev socket,path=%s,id=char0 "
   "-mon chardev=char0,mode=control "
-  "-machine accel=qtest "
+  "-accel qtest "
   "-display none "
   "%s", qemu_binary, socket_path,
   getenv("QTEST_LOG") ? "/dev/fd/2" : "/dev/null",
diff --git a/tests/migration/guestperf/engine.py 
b/tests/migration/guestperf/engine.py
index f13dbea800..1dd04ce33b 100644
--- a/tests/migration/guestperf/engine.py
+++ b/tests/migration/guestperf/engine.py
@@ -287,7 +287,7 @@ class Engine(object):
 cmdline = "'" + cmdline + "'"
 
 argv = [
-"-machine", "accel=kvm",
+"-accel", "kvm",
 "-cpu", "host",
 "-kernel", self._kernel,
 "-initrd", self._initrd,
diff --git a/tests/qemu-iotests/172 b/tests/qemu-iotests/172
index ba7dad9057..d67997e5f6 100755
--- a/tests/qemu-iotests/172
+++ b/tests/qemu-iotests/172
@@ -55,7 +55,7 @@ do_run_qemu()
 done
 fi
 echo quit
-) | $QEMU -machine accel=qtest -nographic -monitor stdio -serial none "$@"
+) | $QEMU -accel qtest -nographic -monitor stdio -serial none "$@"
 echo
 }
 
-- 
2.18.1




Re: [Qemu-devel] [PATCH] linux-user: Support gdb 'qOffsets' query for ELF

2019-09-03 Thread Laurent Vivier
Le 03/09/2019 à 21:19, Josh Kunz a écrit :
> The `Data` and `Code` flags in `qOffsets` are actually section offsets
> rather than segment offsets. GDB relocates the symbols in those sections
> relative to their location in the binary. So we have to use `load_bias`.
> 
> See here for a more detailed
> description: 
> https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#General-Query-Packets
> 

Thank you for the details.

Reviewed-by: Laurent Vivier 



Re: [Qemu-devel] [PATCH] Fedora images: use URLs from stable "archives.fedoraproject.org"

2019-09-03 Thread Yash Mankad



On 9/3/19 8:52 PM, Cleber Rosa wrote:
> The LinuxInitrd.test_with_2gib_file_should_work_with_linux_v4_16 test,
> from tests/acceptance/linux_initrd.py, is currently failing to fetch
> the "vmlinuz" file.  The reason for the failure is that the Fedora
> project retires older versions from the "dl.fedoraproject.org" URL,
> and keeps them in "archives.fedoraproject.org".  As an added note,
> that test uses a Fedora 28 image, because of the specific Linux kernel
> version requirements of the test.
>
> For the sake of stability, let's use URLs from the archived and
> supposedely ever stable URLs.  The good news is that the currently
> supported versions are also hosted on the later.  This change limits
> itself to change the URLs, while keeping the fetched files the same
> (as can be evidenced by the unchanged hashes).
>
> Documentation and the "vm tests" fedora definition were also updated.
>
> Signed-off-by: Cleber Rosa 
> ---
>  qemu-doc.texi  |  6 +++---
>  tests/acceptance/boot_linux_console.py | 25 +++--
>  tests/acceptance/linux_initrd.py   |  5 +++--
>  tests/vm/fedora|  2 +-
>  4 files changed, 22 insertions(+), 16 deletions(-)
>
> diff --git a/qemu-doc.texi b/qemu-doc.texi
> index 577d1e8376..37795f86fb 100644
> --- a/qemu-doc.texi
> +++ b/qemu-doc.texi
> @@ -440,15 +440,15 @@ of .
>  
>  Example: boot from a remote Fedora 20 live ISO image
>  @example
> -qemu-system-x86_64 --drive 
> media=cdrom,file=http://dl.fedoraproject.org/pub/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
> +qemu-system-x86_64 --drive 
> media=cdrom,file=https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
>  
> -qemu-system-x86_64 --drive 
> media=cdrom,file.driver=http,file.url=http://dl.fedoraproject.org/pub/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
> +qemu-system-x86_64 --drive 
> media=cdrom,file.driver=http,file.url=http://archives.fedoraproject.org/pub/archive/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
>  @end example
>  
>  Example: boot from a remote Fedora 20 cloud image using a local overlay for
>  writes, copy-on-read, and a readahead of 64k
>  @example
> -qemu-img create -f qcow2 -o backing_file='json:@{"file.driver":"http",, 
> "file.url":"https://dl.fedoraproject.org/pub/fedora/linux/releases/20/Images/x86_64/Fedora-x86_64-20-20131211.1-sda.qcow2";,,
>  "file.readahead":"64k"@}' /tmp/Fedora-x86_64-20-20131211.1-sda.qcow2
> +qemu-img create -f qcow2 -o backing_file='json:@{"file.driver":"http",, 
> "file.url":"http://archives.fedoraproject.org/pub/archive/fedora/linux/releases/20/Images/x86_64/Fedora-x86_64-20-20131211.1-sda.qcow2";,,
>  "file.readahead":"64k"@}' /tmp/Fedora-x86_64-20-20131211.1-sda.qcow2
>  
>  qemu-system-x86_64 -drive 
> file=/tmp/Fedora-x86_64-20-20131211.1-sda.qcow2,copy-on-read=on
>  @end example
> diff --git a/tests/acceptance/boot_linux_console.py 
> b/tests/acceptance/boot_linux_console.py
> index 2504ef0150..8a9a314ab4 100644
> --- a/tests/acceptance/boot_linux_console.py
> +++ b/tests/acceptance/boot_linux_console.py
> @@ -76,8 +76,9 @@ class BootLinuxConsole(Test):
>  :avocado: tags=arch:x86_64
>  :avocado: tags=machine:pc
>  """
> -kernel_url = ('https://download.fedoraproject.org/pub/fedora/linux/'
> -  
> 'releases/29/Everything/x86_64/os/images/pxeboot/vmlinuz')
> +kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
> +  
> '/linux/releases/29/Everything/x86_64/os/images/pxeboot'
> +  '/vmlinuz')
>  kernel_hash = '23bebd2680757891cf7adedb033532163a792495'
>  kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
>  
> @@ -250,8 +251,9 @@ class BootLinuxConsole(Test):
>  :avocado: tags=arch:aarch64
>  :avocado: tags=machine:virt
>  """
> -kernel_url = ('https://download.fedoraproject.org/pub/fedora/linux/'
> -  
> 'releases/29/Everything/aarch64/os/images/pxeboot/vmlinuz')
> +kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
> +  
> '/linux/releases/29/Everything/aarch64/os/images/pxeboot'
> +  '/vmlinuz')
>  kernel_hash = '8c73e469fc6ea06a58dc83a628fc695b693b8493'
>  kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
>  
> @@ -271,8 +273,9 @@ class BootLinuxConsole(Test):
>  :avocado: tags=arch:arm
>  :avocado: tags=machine:virt
>  """
> -kernel_url = ('https://download.fedoraproject.org/pub/fedora/linux/'
> -  
> 'releases/29/Everything/armhfp/os/images/pxeboot/vmlinuz')
> +kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
> +  
>

Re: [Qemu-devel] [PATCH v1 2/2] hw/pvrdma: add live migration support

2019-09-03 Thread Yuval Shaia
On Wed, Sep 04, 2019 at 03:03:20AM +0530, Sukrit Bhatnagar wrote:
> On Thu, 29 Aug 2019 at 18:23, Yuval Shaia  wrote:
> >
> > On Wed, Aug 28, 2019 at 07:53:28PM +0530, Sukrit Bhatnagar wrote:
> > > vmstate_pvrdma describes the PCI and MSIX states as well as the dma
> > > address for dsr and the gid table of device.
> > > vmstate_pvrdma_gids describes each gid in the gid table.
> > >
> > > pvrdma_post_save() does the job of unregistering gid entries from the
> > > backend device in the source host.
> > >
> > > pvrdma_post_load() maps to dsr using the loaded dma address, registers
> > > each loaded gid into the backend device, and finally calls load_dsr()
> > > to perform other mappings and ring init operations.
> >
> > I think it worth to mention that the dma address is kept in driver/device
> > shared memory (dsr->dma) which is migrated as part of memory migration and
> > it is out of the scope of this change and so we do not need to save/load
> > the dma address during migration.
> >
> > Also you should specifically comment that this migration-support does not
> > includes QP migration. This means that support for life migration *during*
> > traffic is not yet supported.
> >
> > >
> > > Cc: Marcel Apfelbaum 
> > > Cc: Yuval Shaia 
> > > Signed-off-by: Sukrit Bhatnagar 
> > > ---
> > >  hw/rdma/vmw/pvrdma_main.c | 77 +++
> > >  1 file changed, 77 insertions(+)
> > >
> > > diff --git a/hw/rdma/vmw/pvrdma_main.c b/hw/rdma/vmw/pvrdma_main.c
> > > index 6c90db96f9..6f8b56dea3 100644
> > > --- a/hw/rdma/vmw/pvrdma_main.c
> > > +++ b/hw/rdma/vmw/pvrdma_main.c
> > > @@ -28,6 +28,7 @@
> > >  #include "sysemu/sysemu.h"
> > >  #include "monitor/monitor.h"
> > >  #include "hw/rdma/rdma.h"
> > > +#include "migration/register.h"
> > >
> > >  #include "../rdma_rm.h"
> > >  #include "../rdma_backend.h"
> > > @@ -593,6 +594,81 @@ static void pvrdma_shutdown_notifier(Notifier *n, 
> > > void *opaque)
> > >  pvrdma_fini(pci_dev);
> > >  }
> > >
> > > +static int pvrdma_post_save(void *opaque)
> > > +{
> > > +int i, rc;
> > > +PVRDMADev *dev = opaque;
> > > +
> > > +for (i = 0; i < MAX_GIDS; i++) {
> > > +
> >
> > Empty line is redundant here.
> >
> > > +if (!dev->rdma_dev_res.port.gid_tbl[i].gid.global.interface_id) {
> > > +continue;
> > > +}
> > > +rc = rdma_backend_del_gid(&dev->backend_dev,
> > > +   dev->backend_eth_device_name,
> > > +   
> > > &dev->rdma_dev_res.port.gid_tbl[i].gid);
> > > +if (rc) {
> > > +return -EINVAL;
> >
> > Some error report will help here i guess.
> 
> rdma_backend_del_gid() already generates an error report
> when rc isn't 0.
> 
> Adding another statement for the same seems redundant.

Sure, make sense.

> 
> > > +}
> > > +}
> > > +
> > > +return 0;
> > > +}
> > > +
> > > +static int pvrdma_post_load(void *opaque, int version_id)
> > > +{
> > > +int i, rc;
> > > +PVRDMADev *dev = opaque;
> > > +PCIDevice *pci_dev = PCI_DEVICE(dev);
> > > +DSRInfo *dsr_info = &dev->dsr_info;
> > > +
> > > +dsr_info->dsr = rdma_pci_dma_map(pci_dev, dsr_info->dma,
> > > +sizeof(struct 
> > > pvrdma_device_shared_region));
> > > +if (!dsr_info->dsr) {
> > > +rdma_error_report("Failed to map to DSR");
> > > +return -ENOMEM;
> > > +}
> > > +
> > > +for (i = 0; i < MAX_GIDS; i++) {
> > > +
> >
> > Empty line is redundant here.
> >
> > > +if (!dev->rdma_dev_res.port.gid_tbl[i].gid.global.interface_id) {
> > > +continue;
> > > +}
> > > +
> > > +rc = rdma_backend_add_gid(&dev->backend_dev,
> > > +  dev->backend_eth_device_name,
> > > +  
> > > &dev->rdma_dev_res.port.gid_tbl[i].gid);
> > > +if (rc) {
> > > +return -EINVAL;
> > > +}
> > > +}
> > > +
> > > +return load_dsr(dev);
> 
> Now that I will move load_dsr() before the del_gid loop,

You probably meant before add_gid loop.

> I can use goto jumps on exit/error paths, so that I can
> undo load_dsr if any del_gid fails.

Yeah, it will be easier to undo load_dsr than add_gid.

> 
> > > +}
> > > +
> > > +static const VMStateDescription vmstate_pvrdma_gids = {
> > > +.name = "pvrdma-gids",
> > > +.fields = (VMStateField[]) {
> > > +VMSTATE_UINT8_ARRAY_V(gid.raw, RdmaRmGid, 16, 0),
> > > +VMSTATE_END_OF_LIST()
> > > +}
> > > +};
> > > +
> > > +static const VMStateDescription vmstate_pvrdma = {
> > > +.name = PVRDMA_HW_NAME,
> > > +.post_save = pvrdma_post_save,
> > > +.post_load = pvrdma_post_load,
> > > +.fields = (VMStateField[]) {
> > > +VMSTATE_PCI_DEVICE(parent_obj, PVRDMADev),
> > > +VMSTATE_MSIX(parent_obj, PVRDMADev),
> > > +VMSTATE_UINT64(dsr_info.dma, PVRDMADev),
> > > +  

Re: [Qemu-devel] [PATCH for-4.2 v10 08/15] virtio-iommu: Implement map/unmap

2019-09-03 Thread Tian, Kevin
> From: Peter Xu [mailto:pet...@redhat.com]
> Sent: Wednesday, September 4, 2019 9:44 AM
> 
> On Tue, Sep 03, 2019 at 01:37:11PM +0200, Auger Eric wrote:
> > Hi Peter,
> >
> > On 8/19/19 10:11 AM, Peter Xu wrote:
> > > On Tue, Jul 30, 2019 at 07:21:30PM +0200, Eric Auger wrote:
> > >
> > > [...]
> > >
> > >> +mapping = g_tree_lookup(domain->mappings, (gpointer)(&interval));
> > >> +
> > >> +while (mapping) {
> > >> +viommu_interval current;
> > >> +uint64_t low  = mapping->virt_addr;
> > >> +uint64_t high = mapping->virt_addr + mapping->size - 1;
> > >> +
> > >> +current.low = low;
> > >> +current.high = high;
> > >> +
> > >> +if (low == interval.low && size >= mapping->size) {
> > >> +g_tree_remove(domain->mappings, (gpointer)(¤t));
> > >> +interval.low = high + 1;
> > >> +trace_virtio_iommu_unmap_left_interval(current.low,
> current.high,
> > >> +interval.low, interval.high);
> > >> +} else if (high == interval.high && size >= mapping->size) {
> > >> +trace_virtio_iommu_unmap_right_interval(current.low,
> current.high,
> > >> +interval.low, interval.high);
> > >> +g_tree_remove(domain->mappings, (gpointer)(¤t));
> > >> +interval.high = low - 1;
> > >> +} else if (low > interval.low && high < interval.high) {
> > >> +trace_virtio_iommu_unmap_inc_interval(current.low,
> current.high);
> > >> +g_tree_remove(domain->mappings, (gpointer)(¤t));
> > >> +} else {
> > >> +break;
> > >> +}
> > >> +if (interval.low >= interval.high) {
> > >> +return VIRTIO_IOMMU_S_OK;
> > >> +} else {
> > >> +mapping = g_tree_lookup(domain->mappings,
> (gpointer)(&interval));
> > >> +}
> > >> +}
> > >> +
> > >> +if (mapping) {
> > >> +qemu_log_mask(LOG_GUEST_ERROR,
> > >> +  "** %s: Unmap 0x%"PRIx64" size=0x%"PRIx64
> > >> + " from 0x%"PRIx64" size=0x%"PRIx64" is not 
> > >> supported\n",
> > >> + __func__, interval.low, size,
> > >> + mapping->virt_addr, mapping->size);
> > >> +} else {
> > >> +return VIRTIO_IOMMU_S_OK;
> > >> +}
> > >> +
> > >> +return VIRTIO_IOMMU_S_INVAL;
> > >
> > > Could the above chunk be simplified as something like below?
> > >
> > >   while ((mapping = g_tree_lookup(domain->mappings, &interval))) {
> > > g_tree_remove(domain->mappings, mapping);
> > >   }
> > Indeed the code could be simplified. I only need to make sure I don't
> > split an existing mapping.
> 
> Hmm... Do we need to still split an existing mapping if necessary?
> For example when with this mapping:
> 
>   iova=0x1000, size=0x2000, phys=ADDR1, flags=FLAGS1
> 
> And if we want to unmap the range (iova=0, size=0x2000), then we
> should split the existing mappping and leave this one:
> 
>   iova=0x2000, size=0x1000, phys=(ADDR1+0x1000), flags=FLAGS1
> 
> Right?
> 

virtio-iommu spec explicitly disallows partial unmap.

5.11.6.6.1 Driver Requirements: UNMAP request

The first address of a range MUST either be the first address of a 
mapping or be outside any mapping. The last address of a range 
MUST either be the last address of a mapping or be outside any 
mapping.

5.11.6.6.2 Device Requirements: UNMAP request

If a mapping affected by the range is not covered in its entirety 
by the range (the UNMAP request would split the mapping), 
then the device SHOULD set the request status to VIRTIO_IOMMU
_S_RANGE, and SHOULD NOT remove any mapping.

Thanks
Kevin


Re: [Qemu-devel] [PATCH v2 2/3] tests/libqtest: Allow setting expected exit status

2019-09-03 Thread Thomas Huth
On 03/09/2019 18.22, Yury Kotov wrote:
> Add qtest_set_expected_status function to set expected exit status of
> child process. By default expected exit status is 0.
> 
> Signed-off-by: Yury Kotov 
> ---
>  tests/libqtest.c | 36 +---
>  tests/libqtest.h |  9 +
>  2 files changed, 30 insertions(+), 15 deletions(-)
> 
> diff --git a/tests/libqtest.c b/tests/libqtest.c
> index 2713b86cf7..a79d4887ae 100644
> --- a/tests/libqtest.c
> +++ b/tests/libqtest.c
> @@ -43,6 +43,7 @@ struct QTestState
>  int qmp_fd;
>  pid_t qemu_pid;  /* our child QEMU process */
>  int wstatus;
> +int expected_status;
>  bool big_endian;
>  bool irq_level[MAX_IRQ];
>  GString *rx;
> @@ -113,6 +114,11 @@ bool qtest_probe_child(QTestState *s)
>  return false;
>  }
>  
> +void qtest_set_expected_status(QTestState *s, int status)
> +{
> +s->expected_status = status;
> +}
> +
>  static void kill_qemu(QTestState *s)
>  {
>  pid_t pid = s->qemu_pid;
> @@ -126,24 +132,23 @@ static void kill_qemu(QTestState *s)
>  }
>  
>  /*
> - * We expect qemu to exit with status 0; anything else is
> + * Check whether qemu exited with expected exit status; anything else is
>   * fishy and should be logged with as much detail as possible.
>   */
>  wstatus = s->wstatus;
> -if (wstatus) {
> -if (WIFEXITED(wstatus)) {
> -fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU "
> -"process but encountered exit status %d\n",
> -__FILE__, __LINE__, WEXITSTATUS(wstatus));
> -} else if (WIFSIGNALED(wstatus)) {
> -int sig = WTERMSIG(wstatus);
> -const char *signame = strsignal(sig) ?: "unknown ???";
> -const char *dump = WCOREDUMP(wstatus) ? " (core dumped)" : "";
> -
> -fprintf(stderr, "%s:%d: kill_qemu() detected QEMU death "
> -"from signal %d (%s)%s\n",
> -__FILE__, __LINE__, sig, signame, dump);
> -}
> +if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != s->expected_status) {
> +fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU "
> +"process but encountered exit status %d (expected %d)\n",
> +__FILE__, __LINE__, WEXITSTATUS(wstatus), 
> s->expected_status);
> +abort();
> +} else if (WIFSIGNALED(wstatus)) {
> +int sig = WTERMSIG(wstatus);
> +const char *signame = strsignal(sig) ?: "unknown ???";
> +const char *dump = WCOREDUMP(wstatus) ? " (core dumped)" : "";
> +
> +fprintf(stderr, "%s:%d: kill_qemu() detected QEMU death "
> +"from signal %d (%s)%s\n",
> +__FILE__, __LINE__, sig, signame, dump);
>  abort();
>  }
>  }
> @@ -248,6 +253,7 @@ QTestState *qtest_init_without_qmp_handshake(const char 
> *extra_args)
>  g_test_message("starting QEMU: %s", command);
>  
>  s->wstatus = 0;
> +s->expected_status = 0;
>  s->qemu_pid = fork();
>  if (s->qemu_pid == 0) {
>  setenv("QEMU_AUDIO_DRV", "none", true);
> diff --git a/tests/libqtest.h b/tests/libqtest.h
> index 07ea35867c..c00bca94af 100644
> --- a/tests/libqtest.h
> +++ b/tests/libqtest.h
> @@ -997,4 +997,13 @@ void qmp_assert_error_class(QDict *rsp, const char 
> *class);
>   */
>  bool qtest_probe_child(QTestState *s);
>  
> +/**
> + * qtest_set_expected_status:
> + * @s: QTestState instance to operate on.
> + * @status: an expected exit status.
> + *
> + * Set expected exit status of the child.
> + */
> +void qtest_set_expected_status(QTestState *s, int status);
> +
>  #endif
> 

Acked-by: Thomas Huth 



Re: [Qemu-devel] [Qemu-riscv] [PATCH] riscv: sifive_e: Correct various SoC IP block sizes

2019-09-03 Thread Bin Meng
Palmer,

On Wed, Aug 14, 2019 at 5:34 PM Bin Meng  wrote:
>
> Hi Palmer,
>
> On Wed, Aug 7, 2019 at 10:53 AM Bin Meng  wrote:
> >
> > On Wed, Aug 7, 2019 at 5:06 AM Philippe Mathieu-Daudé  
> > wrote:
> > >
> > > On 8/5/19 8:43 AM, Bin Meng wrote:
> > > > On Mon, Aug 5, 2019 at 2:14 PM Chih-Min Chao  
> > > > wrote:
> > > >> On Sat, Aug 3, 2019 at 8:27 AM Bin Meng  wrote:
> > > >>>
> > > >>> Some of the SoC IP block sizes are wrong. Correct them according
> > > >>> to the FE310 manual.
> > > >>>
> > > >>> Signed-off-by: Bin Meng 
> > > >>> ---
> > > >>>
> > > >>>  hw/riscv/sifive_e.c | 6 +++---
> > > >>>  1 file changed, 3 insertions(+), 3 deletions(-)
> > > >>>
> > > >>> diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
> > > >>> index 2a499d8..9655847 100644
> > > >>> --- a/hw/riscv/sifive_e.c
> > > >>> +++ b/hw/riscv/sifive_e.c
> > > >>> @@ -53,13 +53,13 @@ static const struct MemmapEntry {
> > > >>>  hwaddr base;
> > > >>>  hwaddr size;
> > > >>>  } sifive_e_memmap[] = {
> > > >>> -[SIFIVE_E_DEBUG] ={0x0,  0x100 },
> > > >>> +[SIFIVE_E_DEBUG] ={0x0, 0x1000 },
> > > >>>  [SIFIVE_E_MROM] = { 0x1000, 0x2000 },
> > > >>>  [SIFIVE_E_OTP] =  {0x2, 0x2000 },
> > > >>>  [SIFIVE_E_CLINT] ={  0x200,0x1 },
> > > >>>  [SIFIVE_E_PLIC] = {  0xc00,  0x400 },
> > > >>> -[SIFIVE_E_AON] =  { 0x1000, 0x8000 },
> > > >>> -[SIFIVE_E_PRCI] = { 0x10008000, 0x8000 },
> > > >>> +[SIFIVE_E_AON] =  { 0x1000, 0x1000 },
> > > >>> +[SIFIVE_E_PRCI] = { 0x10008000, 0x1000 },
> > > >>>  [SIFIVE_E_OTP_CTRL] = { 0x1001, 0x1000 },
> > > >>>  [SIFIVE_E_GPIO0] ={ 0x10012000, 0x1000 },
> > > >>>  [SIFIVE_E_UART0] ={ 0x10013000, 0x1000 },
> > > >>> --
> > > >>> 2.7.4
> > > >>>
> > > >>
> > > >> It seems the modification follows  E310-G002(Hifive1 Rev B) spec and 
> > > >> the origin is for E310-G000(Hifive1) spec.
> > > >> There should be some way to specify different board version with 
> > > >> different memory map or we have policy, always support the latest spec.
> > >
> > > I agree with Chao, it would be cleaner to have two different boards
> > > (machines).
> > > Since the SoCs are very similar, you could add a 'revision' property and
> > > use it to select the correct map.
> > >
> >
> > I am not sure if adding two different machines will bring us a lot of
> > benefits, since the only difference is the SoC revision with different
> > block sizes.
> >
> > > >>
> > > >
> > > > Yes, I checked both specs. The older spec says these bigger sizes,
> > > > however their register sizes fit well in the smaller range as well. So
> > > > I think the modification works well for both.
> > >
> > > This is OK for the PRCI, since sifive_prci_create() does not use
> > > memmap[SIFIVE_E_PRCI].size.
> > >
> > > However the AON case is borderline, since you shrink it from 32KiB to 
> > > 4KiB.
> > >
> >
> > AON is not implemented anyway currently. And I checked the FE310 old
> > spec, its register block size is still within the 4KiB range, so
> > shrinking the size should be fine for both old and new SoC.
> >
> > > BTW (not related to this patch) it is odd a function named
> > > sifive_mmio_emulate() creates a RAM region with memory_region_init_ram()
> > > and does not use the UnimplementedDevice (see make_unimp_dev() in
> > > hw/arm/musca.c).
> > >
>
> What's your suggestion regarding this patch?

Ping?

Regards,
Bin



Re: [Qemu-devel] QEMU as ISS (Instruction Set Simulator)

2019-09-03 Thread Libo Zhou
Hi Aleksandar,


I have spent some time looking at your MXU ASE patch. It's super helpful. I 
need to do exactly the same thing as you did.


Now I just need a way to observe the memory and register file contents to debug 
my instruction set simulator. I played with the "-d" switch to log a bunch of 
information, but it seems that none of the items is of my interest. The "-d 
cpu_reset" option displays all zeros in the GPR log.



Please take your time, as I fully understand you need to work on Qemu while 
answering all my questions. Again, thank you very much for your help!



Cheers,
Libo



-- Original --
From:  "Aleksandar Markovic";;
Send time: Tuesday, Sep 3, 2019 3:07 PM
To: "Libo Zhou"; 
Cc: "qemu-devel"; 
Subject:  Re: [Qemu-devel] QEMU as ISS (Instruction Set Simulator)



30.08.2019. 11.14, "Libo Zhou"  wrote:
>
> Hi Aleksandar,
>
> Thanks for explaining helper functions for me. Before getting my hands
dirty, I have some more questions. After figuring them out, I can get
started.
>
> I need to add some new registers to the CPU. In "translate.c", I found
that the registers are declared as static TCGv array (e.g. cpu_gpr[32]).
Then, in function mips_tcg_init(), cpu_gpr[i] is created one by one with
tcg_global_mem_new(...) in a for loop. Is that all I need to do to add new
registers to the CPU? I noticed another file "cpu.h", do I also need to add
my new registers, say, "my_gpr[32]" in "cpu.h"?
>
> My new instructions also include some load & stores. I see I can
implement them with tcg_gen_qemu_ld/st_tl(...) in the decode function's
switch-case statements, but I don't see how the *target* memory is created.
Shouldn't they be created with tcg_global_mem_new(...), just like how the
registers are created? I can hack the memory by creating a *super* larger
register file, and hack the loads & stores with register moves, but that
just sounds too sketchy.
>

For register definition, load/store instruction, take a look at details of
this series:

https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg06028.html

Don't mix register and memory initialization. For memory, the existing code
should be sufficient.

What you need to additionally do (and you didn't mention it) is to define a
CPU that will have some base instruction set (it could be, for example,
mips32r2) + your additional instructions. This is done in file by adding a
corresponding item in translate_init.inc.c (if you choose mips32r2 as base
ISA, you could base your new CPU on existing CPU 24Kf). And then you start
QEMU with switch "-cpu ".

I may add more explanation later on.

> On the other hand, I would like to get it running first, without doing
any modification to the source code. I can build the user space emulation
on Linux.
>
> ./configure --target-list=mips-linux-user
>
> Then I will write a testprogram.c, cross compile it on x86 into MIPS
using gcc(I am not clear on how to do it, but my team has the compiler for
our new ISA, I just want to try the MIPS version first), and run the test
program.
>
> ./qemu testprogram
>
> How do I look at the contents in the target registers and memory? I saw
that function "mips_cpu_dump_state" in "translate.c" does what I need, but
I don't know how to call it in this process. Should I use gdb?
>
> I am really sorry for asking you so many questions, but I think after
getting them figured out, I can start my project. Thank you very much in
advance, and have a good weekend!
>

The questions are always fine and welcome, just we are typically very busy,
and can't always promptly reply.

Aleksandar

> Cheers,
> Libo
>
>
> -- Original --
> From:  "Aleksandar Markovic";;
> Send time: Thursday, Aug 29, 2019 10:22 PM
> To: "Libo Zhou";
> Cc: "qemu-devel";
> Subject:  Re: [Qemu-devel] QEMU as ISS (Instruction Set Simulator)
>
> On Wed, Aug 28, 2019 at 5:54 AM Libo Zhou  wrote:
>
> > Hi Aleksandar,
> >
> > Thank you for the link to Loongson2F documentation. It has been very
> > useful:)
> >
> > I have spent several days immersing myself in the source code, now I
think
> > I have a more solid understanding about it. Just like Loongson
Multimedia
> > Instructions, I need to implement some sort of complex vector
instructions,
> > and I need to write some helper functions (e.g. my_helper.c).
> >
> > The QEMU wiki website has very thorough explanation on TCG, but I
haven't
> > found any explanation on the port-specific helpers. Is there any
> > documentation on how the helper functions are generated? I think now I
> > *might* know how to write a working helper function, but I just don't
know
> > how it works.
> >
> >
> Hello, Libo,
>
> Prerequisite for writing a helper is that you have a clear definition of
> new instruction functionality, in the sense, what operation is done on
what
> resources. "Resources" are registers - they could be general-purpose MIPS
> registers, or some special additional registers. Did you use existing
> registers, or did you de

Re: [Qemu-devel] [PATCH] memory: Set notdirty_mem_ops validator

2019-09-03 Thread Peter Xu
On Tue, Sep 03, 2019 at 05:50:56PM +0100, Peter Maydell wrote:
> On Tue, 3 Sep 2019 at 17:47, Tony Nguyen  wrote:
> >
> > On Tue, Sep 03, 2019 at 11:25:28AM +0100, Peter Maydell wrote:
> > > On Mon, 2 Sep 2019 at 02:36, Tony Nguyen  wrote:
> > > >
> > > > Existing read rejecting validator was mistakenly cleared.
> > > >
> > > > Reads dispatched to io_mem_notdirty then segfaults as there is no read
> > > > handler.
> > >
> > > Do you have the commit hash for where we introduced the
> > > bug that this is fixing?
> > >
> > > thanks
> > > -- PMM
> > >
> >
> > ad52878f97610757390148fe5d5b4cc5ad15c585.
> >
> > Please feel free to amend my commit message.
> 
> Thanks.
> 
> > I do not understand why sun4u booting Solaris 10 triggers the bug.
> 
> Do you have a backtrace of QEMU from the segfault? I'm having trouble
> thinking of what the situation is when we'd try to invoke the
> read handler on io_mem_notdirty...

I've no good understanding of how PHYS_SECTION_NOTDIRTY is used
yet... though from what I understand that's the thing this patch wants
to fix.  Because after the broken commit, this line will be
overwritten:

.valid.accepts = notdirty_mem_accepts,

and accept() will be reset to NULL.

With that, memory_region_access_valid(is_write=false) could return
valid now (so a read could happen), while it should never, logically?

Regards,

-- 
Peter Xu



Re: [Qemu-devel] [Qemu-block] [PATCH] cutils: Move size_to_str() from "qemu-common.h" to "qemu/cutils.h"

2019-09-03 Thread Peter Xu
On Tue, Sep 03, 2019 at 02:57:31PM -0400, John Snow wrote:

[...]

> Seems proper. It must be an oversight to begin with that we declared it
> in qemu-common but defined it in cutils.

Porbably true..

> 
> Reviewed-by: John Snow 

Reviewed-by: Peter Xu 

Thanks,

-- 
Peter Xu



[Qemu-devel] [Bug 1842530] [NEW] ich6 and ich9 sound card has noisy(murmur)

2019-09-03 Thread cpw
Public bug reported:

[root@localhost1 qemu]# lscpu
Architecture:  x86_64
CPU op-mode(s):32-bit, 64-bit
Byte Order:Little Endian
CPU(s):6
On-line CPU(s) list:   0-5
Thread(s) per core:1
Core(s) per socket:6
Socket(s): 1
NUMA node(s):  1
Vendor ID: GenuineIntel
CPU family:6
Model: 158
Model name:Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
Stepping:  10
CPU MHz:   899.951
CPU max MHz:   4000.
CPU min MHz:   800.
BogoMIPS:  5616.00
Virtualization:VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache:  256K
L3 cache:  9216K
NUMA node0 CPU(s): 0-5
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca 
cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx 
pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl 
xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl 
vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe 
popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch 
epb intel_pt ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid 
fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap 
clflushopt xsaveopt xsavec xgetbv1 dtherm ida arat pln pts hwp hwp_notify 
hwp_act_window hwp_epp spec_ctrl intel_stibp flush_l1d


[root@localhost1 qemu]# lsb_release -a
LSB Version::core-4.1-amd64:core-4.1-noarch
Distributor ID: CentOS
Description:CentOS Linux release 7.6.1810 (Core)
Release:7.6.1810
Codename:   Core

Installed as Virtualization Server (qemuV1.5);
create win7-32 or 64 GuestOS by virt-manager,and select default sound card ich6;


  
  


  


  
  



but obvious noise found when login guest os to play music. :(

And the problem remains after I update qemu to 2.12.0-18 , 3.1.0 &etc.


[root@localhost1 qemu]# /usr/bin/qemu-system-x86_64 --version
QEMU emulator version 3.1.0
Copyright (c) 2003-2018 Fabrice Bellard and the QEMU Project developers

** Affects: qemu
 Importance: Undecided
 Status: New

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

Title:
  ich6 and ich9 sound card has noisy(murmur)

Status in QEMU:
  New

Bug description:
  [root@localhost1 qemu]# lscpu
  Architecture:  x86_64
  CPU op-mode(s):32-bit, 64-bit
  Byte Order:Little Endian
  CPU(s):6
  On-line CPU(s) list:   0-5
  Thread(s) per core:1
  Core(s) per socket:6
  Socket(s): 1
  NUMA node(s):  1
  Vendor ID: GenuineIntel
  CPU family:6
  Model: 158
  Model name:Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
  Stepping:  10
  CPU MHz:   899.951
  CPU max MHz:   4000.
  CPU min MHz:   800.
  BogoMIPS:  5616.00
  Virtualization:VT-x
  L1d cache: 32K
  L1i cache: 32K
  L2 cache:  256K
  L3 cache:  9216K
  NUMA node0 CPU(s): 0-5
  Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge 
mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx 
pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl 
xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl 
vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe 
popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch 
epb intel_pt ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid 
fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap 
clflushopt xsaveopt xsavec xgetbv1 dtherm ida arat pln pts hwp hwp_notify 
hwp_act_window hwp_epp spec_ctrl intel_stibp flush_l1d

  
  [root@localhost1 qemu]# lsb_release -a
  LSB Version::core-4.1-amd64:core-4.1-noarch
  Distributor ID: CentOS
  Description:CentOS Linux release 7.6.1810 (Core)
  Release:7.6.1810
  Codename:   Core

  Installed as Virtualization Server (qemuV1.5);
  create win7-32 or 64 GuestOS by virt-manager,and select default sound card 
ich6;

  


  
  

  
  


  

  
  but obvious noise found when login guest os to play music. :(

  And the problem remains after I update qemu to 2.12.0-18 , 3.1.0 &etc.

  
  [root@localhost1 qemu]# /usr/bin/qemu-system-x86_64 --version
  QEMU emulator version 3.1.0
  Copyright (c) 2003-2018 Fabrice Bellard and the QEMU Project developers

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



Re: [Qemu-devel] [PATCH v2] libvhost-user: fix SLAVE_SEND_FD handling

2019-09-03 Thread Tiwei Bie
On Tue, Sep 03, 2019 at 11:04:22PM +0300, Johannes Berg wrote:
> From: Johannes Berg 
> 
> It doesn't look like this could possibly work properly since
> VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD is defined to 10, but the
> dev->protocol_features has a bitmap. I suppose the peer this
> was tested with also supported VHOST_USER_PROTOCOL_F_LOG_SHMFD,
> in which case the test would always be false, but nevertheless
> the code seems wrong.

Ooops.. I tested `tests/vhost-user-bridge -H`. But as you
said it worked because VHOST_USER_PROTOCOL_F_LOG_SHMFD has
been negotiated. Thanks for spotting this!

> 
> Use has_feature() to fix this.
> 
> Fixes: d84599f56c82 ("libvhost-user: support host notifier")

Cc: qemu-sta...@nongnu.org

> Signed-off-by: Johannes Berg 
> ---
>  contrib/libvhost-user/libvhost-user.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/contrib/libvhost-user/libvhost-user.c 
> b/contrib/libvhost-user/libvhost-user.c
> index 6a02eaffc672..fcf4a8a00ed2 100644
> --- a/contrib/libvhost-user/libvhost-user.c
> +++ b/contrib/libvhost-user/libvhost-user.c
> @@ -1097,7 +1097,8 @@ bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq 
> *vq, int fd,
>  
>  vmsg.fd_num = fd_num;
>  
> -if ((dev->protocol_features & VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) == 0) 
> {
> +if (!has_feature(dev->protocol_features,
> + VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD)) {

We have both of has_feature() and vu_has_feature() called by
other code in this file directly. Not sure which one is preferred..
Personally, I think vu_has_feature() might be better.

Thanks!
Tiwei

>  return false;
>  }
>  
> -- 
> 2.23.0
> 



Re: [Qemu-devel] [PATCH for-4.2 v10 09/15] virtio-iommu: Implement translate

2019-09-03 Thread Peter Xu
On Tue, Sep 03, 2019 at 01:45:22PM +0200, Auger Eric wrote:
> Hi Peter,
> 
> On 8/19/19 10:24 AM, Peter Xu wrote:
> > On Tue, Jul 30, 2019 at 07:21:31PM +0200, Eric Auger wrote:
> >> @@ -464,19 +464,75 @@ static IOMMUTLBEntry 
> >> virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr,
> >>  int iommu_idx)
> >>  {
> >>  IOMMUDevice *sdev = container_of(mr, IOMMUDevice, iommu_mr);
> >> +VirtIOIOMMU *s = sdev->viommu;
> >>  uint32_t sid;
> >> +viommu_endpoint *ep;
> >> +viommu_mapping *mapping;
> >> +viommu_interval interval;
> >> +bool bypass_allowed;
> >> +
> >> +interval.low = addr;
> >> +interval.high = addr + 1;
> >>  
> >>  IOMMUTLBEntry entry = {
> >>  .target_as = &address_space_memory,
> >>  .iova = addr,
> >>  .translated_addr = addr,
> >> -.addr_mask = ~(hwaddr)0,
> >> +.addr_mask = (1 << ctz32(s->config.page_size_mask)) - 1,
> >>  .perm = IOMMU_NONE,
> >>  };
> >>  
> >> +bypass_allowed = virtio_has_feature(s->acked_features,
> >> +VIRTIO_IOMMU_F_BYPASS);
> >> +
> >>  sid = virtio_iommu_get_sid(sdev);
> >>  
> >>  trace_virtio_iommu_translate(mr->parent_obj.name, sid, addr, flag);
> >> +qemu_mutex_lock(&s->mutex);
> >> +
> >> +ep = g_tree_lookup(s->endpoints, GUINT_TO_POINTER(sid));
> >> +if (!ep) {
> >> +if (!bypass_allowed) {
> >> +error_report("%s sid=%d is not known!!", __func__, sid);
> > 
> > Maybe use error_report_once() to avoid DOS attack?  Also would it be
> > good to unify the debug prints?  I see both error_report() and
> > qemu_log_mask() are used in the whole patchset.  Or is that attempted?
> 
> I switched to error_report_once()
> 
> I understand that qemu_log_mask() should be used whenever the root cause
> is a bad action of the guest OS (in below case, the EP was not attached
> to any domain). Above, there is an EP that attempts to talk through the
> IOMMU and this was not expected (rather a platform description issue or
> a qemu bug).

I see. It's a bit unclear at least to me on how to use these.  I have
seen, and used error_report*() to report guest misbehaves as well just
for the debugging and triaging simply because error_report*() will
always be there even without "-d" (because when issue happens most
users are without it...).  Then with these information captured by
either libvirt or direct QEMU users we can triage guest bugs easier.
I hope I'm not severly wrong, and please feel free to use
qemu_log_mask() no matter what.

Regards,

-- 
Peter Xu



Re: [Qemu-devel] [PATCH for-4.2 v10 08/15] virtio-iommu: Implement map/unmap

2019-09-03 Thread Peter Xu
On Tue, Sep 03, 2019 at 01:37:11PM +0200, Auger Eric wrote:
> Hi Peter,
> 
> On 8/19/19 10:11 AM, Peter Xu wrote:
> > On Tue, Jul 30, 2019 at 07:21:30PM +0200, Eric Auger wrote:
> > 
> > [...]
> > 
> >> +mapping = g_tree_lookup(domain->mappings, (gpointer)(&interval));
> >> +
> >> +while (mapping) {
> >> +viommu_interval current;
> >> +uint64_t low  = mapping->virt_addr;
> >> +uint64_t high = mapping->virt_addr + mapping->size - 1;
> >> +
> >> +current.low = low;
> >> +current.high = high;
> >> +
> >> +if (low == interval.low && size >= mapping->size) {
> >> +g_tree_remove(domain->mappings, (gpointer)(¤t));
> >> +interval.low = high + 1;
> >> +trace_virtio_iommu_unmap_left_interval(current.low, 
> >> current.high,
> >> +interval.low, interval.high);
> >> +} else if (high == interval.high && size >= mapping->size) {
> >> +trace_virtio_iommu_unmap_right_interval(current.low, 
> >> current.high,
> >> +interval.low, interval.high);
> >> +g_tree_remove(domain->mappings, (gpointer)(¤t));
> >> +interval.high = low - 1;
> >> +} else if (low > interval.low && high < interval.high) {
> >> +trace_virtio_iommu_unmap_inc_interval(current.low, 
> >> current.high);
> >> +g_tree_remove(domain->mappings, (gpointer)(¤t));
> >> +} else {
> >> +break;
> >> +}
> >> +if (interval.low >= interval.high) {
> >> +return VIRTIO_IOMMU_S_OK;
> >> +} else {
> >> +mapping = g_tree_lookup(domain->mappings, 
> >> (gpointer)(&interval));
> >> +}
> >> +}
> >> +
> >> +if (mapping) {
> >> +qemu_log_mask(LOG_GUEST_ERROR,
> >> +  "** %s: Unmap 0x%"PRIx64" size=0x%"PRIx64
> >> + " from 0x%"PRIx64" size=0x%"PRIx64" is not 
> >> supported\n",
> >> + __func__, interval.low, size,
> >> + mapping->virt_addr, mapping->size);
> >> +} else {
> >> +return VIRTIO_IOMMU_S_OK;
> >> +}
> >> +
> >> +return VIRTIO_IOMMU_S_INVAL;
> > 
> > Could the above chunk be simplified as something like below?
> > 
> >   while ((mapping = g_tree_lookup(domain->mappings, &interval))) {
> > g_tree_remove(domain->mappings, mapping);
> >   }
> Indeed the code could be simplified. I only need to make sure I don't
> split an existing mapping.

Hmm... Do we need to still split an existing mapping if necessary?
For example when with this mapping:

  iova=0x1000, size=0x2000, phys=ADDR1, flags=FLAGS1

And if we want to unmap the range (iova=0, size=0x2000), then we
should split the existing mappping and leave this one:

  iova=0x2000, size=0x1000, phys=(ADDR1+0x1000), flags=FLAGS1

Right?

> 
> Also I needed to use g_tree_lookup_extended to retrieve the actual key
> to remove. The usage of g_tree_lookup_extended() allows me to remove the
> virt_addr and size fields from the mapping value value struct as those
> info can be retrieved from the key.

True.  Thanks,

-- 
Peter Xu



[Qemu-devel] [PATCH] Fedora images: use URLs from stable "archives.fedoraproject.org"

2019-09-03 Thread Cleber Rosa
The LinuxInitrd.test_with_2gib_file_should_work_with_linux_v4_16 test,
from tests/acceptance/linux_initrd.py, is currently failing to fetch
the "vmlinuz" file.  The reason for the failure is that the Fedora
project retires older versions from the "dl.fedoraproject.org" URL,
and keeps them in "archives.fedoraproject.org".  As an added note,
that test uses a Fedora 28 image, because of the specific Linux kernel
version requirements of the test.

For the sake of stability, let's use URLs from the archived and
supposedely ever stable URLs.  The good news is that the currently
supported versions are also hosted on the later.  This change limits
itself to change the URLs, while keeping the fetched files the same
(as can be evidenced by the unchanged hashes).

Documentation and the "vm tests" fedora definition were also updated.

Signed-off-by: Cleber Rosa 
---
 qemu-doc.texi  |  6 +++---
 tests/acceptance/boot_linux_console.py | 25 +++--
 tests/acceptance/linux_initrd.py   |  5 +++--
 tests/vm/fedora|  2 +-
 4 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/qemu-doc.texi b/qemu-doc.texi
index 577d1e8376..37795f86fb 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -440,15 +440,15 @@ of .
 
 Example: boot from a remote Fedora 20 live ISO image
 @example
-qemu-system-x86_64 --drive 
media=cdrom,file=http://dl.fedoraproject.org/pub/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
+qemu-system-x86_64 --drive 
media=cdrom,file=https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
 
-qemu-system-x86_64 --drive 
media=cdrom,file.driver=http,file.url=http://dl.fedoraproject.org/pub/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
+qemu-system-x86_64 --drive 
media=cdrom,file.driver=http,file.url=http://archives.fedoraproject.org/pub/archive/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso,readonly
 @end example
 
 Example: boot from a remote Fedora 20 cloud image using a local overlay for
 writes, copy-on-read, and a readahead of 64k
 @example
-qemu-img create -f qcow2 -o backing_file='json:@{"file.driver":"http",, 
"file.url":"https://dl.fedoraproject.org/pub/fedora/linux/releases/20/Images/x86_64/Fedora-x86_64-20-20131211.1-sda.qcow2";,,
 "file.readahead":"64k"@}' /tmp/Fedora-x86_64-20-20131211.1-sda.qcow2
+qemu-img create -f qcow2 -o backing_file='json:@{"file.driver":"http",, 
"file.url":"http://archives.fedoraproject.org/pub/archive/fedora/linux/releases/20/Images/x86_64/Fedora-x86_64-20-20131211.1-sda.qcow2";,,
 "file.readahead":"64k"@}' /tmp/Fedora-x86_64-20-20131211.1-sda.qcow2
 
 qemu-system-x86_64 -drive 
file=/tmp/Fedora-x86_64-20-20131211.1-sda.qcow2,copy-on-read=on
 @end example
diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 2504ef0150..8a9a314ab4 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -76,8 +76,9 @@ class BootLinuxConsole(Test):
 :avocado: tags=arch:x86_64
 :avocado: tags=machine:pc
 """
-kernel_url = ('https://download.fedoraproject.org/pub/fedora/linux/'
-  
'releases/29/Everything/x86_64/os/images/pxeboot/vmlinuz')
+kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
+  '/linux/releases/29/Everything/x86_64/os/images/pxeboot'
+  '/vmlinuz')
 kernel_hash = '23bebd2680757891cf7adedb033532163a792495'
 kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
 
@@ -250,8 +251,9 @@ class BootLinuxConsole(Test):
 :avocado: tags=arch:aarch64
 :avocado: tags=machine:virt
 """
-kernel_url = ('https://download.fedoraproject.org/pub/fedora/linux/'
-  
'releases/29/Everything/aarch64/os/images/pxeboot/vmlinuz')
+kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
+  '/linux/releases/29/Everything/aarch64/os/images/pxeboot'
+  '/vmlinuz')
 kernel_hash = '8c73e469fc6ea06a58dc83a628fc695b693b8493'
 kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
 
@@ -271,8 +273,9 @@ class BootLinuxConsole(Test):
 :avocado: tags=arch:arm
 :avocado: tags=machine:virt
 """
-kernel_url = ('https://download.fedoraproject.org/pub/fedora/linux/'
-  
'releases/29/Everything/armhfp/os/images/pxeboot/vmlinuz')
+kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
+  '/linux/releases/29/Everything/armhfp/os/images/pxeboot'
+  '/vmlinuz')
 kernel_hash = 'e9826d741b4fb04cadba8d4824d1ed3b7fb8b4d4'
 kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
 
@

Re: [Qemu-devel] [RFC PATCH v2 01/35] multi-process: memory: alloc RAM from file at offset

2019-09-03 Thread Jag Raman




On 6/18/2019 1:12 AM, Gerd Hoffmann wrote:

On Mon, Jun 17, 2019 at 11:14:59AM -0700, elena.ufimts...@oracle.com wrote:

From: Jagannathan Raman 

Allow RAM MemoryRegion to be created from an offset in a file, instead
of allocating at offset of 0 by default. This is needed to synchronize
RAM between QEMU & remote process.
This will be needed for the following patches.


Details please.   vhost-user works fine without this ...


Hi Gerd,

Sorry for the delayed response.

vhost-user doesn't use qemu_ram_alloc_from_fd(), it directly calls
mmap() to map the RAM onto the remote process.

Secondly, vhost-user uses its own functions (like vu_gpa_to_va()) for
address translation, whereas multi-process uses QEMU's existing
functions (address_space_rw()). Therefore, multi-process needs to use
qemu_ram_alloc_from_fd().

Lastly, updates to the system memory (received via MemoryListener) are
often in segments and not contiguous. Therefore, mapping these segments
in the remote process is possible only if we are able to allocate a
MemoryRegion at an offset in the memory backend.

Thanks!
--
Jag



cheers,
   Gerd






Re: [Qemu-devel] [PATCH v7 15/30] riscv: hart: Add a "hartid-base" property to RISC-V hart array

2019-09-03 Thread Alistair Francis
On Sat, Aug 31, 2019 at 7:58 PM Bin Meng  wrote:
>
> At present each hart's hartid in a RISC-V hart array is assigned
> the same value of its index in the hart array. But for a system
> that has multiple hart arrays, this is not the case any more.
>
> Add a new "hartid-base" property so that hartid number can be
> assigned based on the property value.
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

>
> ---
>
> Changes in v7:
> - use `s->hartid_base + idx` directly
>
> Changes in v6:
> - use s->hartid_base directly, instead of an extra variable
>
> Changes in v5: None
> Changes in v4:
> - new patch to add a "hartid-base" property to RISC-V hart array
>
> Changes in v3: None
> Changes in v2: None
>
>  hw/riscv/riscv_hart.c | 3 ++-
>  include/hw/riscv/riscv_hart.h | 1 +
>  2 files changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
> index 9deef869..e28db80 100644
> --- a/hw/riscv/riscv_hart.c
> +++ b/hw/riscv/riscv_hart.c
> @@ -27,6 +27,7 @@
>
>  static Property riscv_harts_props[] = {
>  DEFINE_PROP_UINT32("num-harts", RISCVHartArrayState, num_harts, 1),
> +DEFINE_PROP_UINT32("hartid-base", RISCVHartArrayState, hartid_base, 0),
>  DEFINE_PROP_STRING("cpu-type", RISCVHartArrayState, cpu_type),
>  DEFINE_PROP_END_OF_LIST(),
>  };
> @@ -45,7 +46,7 @@ static void riscv_hart_realize(RISCVHartArrayState *s, int 
> idx,
>  object_initialize_child(OBJECT(s), "harts[*]", &s->harts[idx],
>  sizeof(RISCVCPU), cpu_type,
>  &error_abort, NULL);
> -s->harts[idx].env.mhartid = idx;
> +s->harts[idx].env.mhartid = s->hartid_base + idx;
>  qemu_register_reset(riscv_harts_cpu_reset, &s->harts[idx]);
>  object_property_set_bool(OBJECT(&s->harts[idx]), true,
>   "realized", &err);
> diff --git a/include/hw/riscv/riscv_hart.h b/include/hw/riscv/riscv_hart.h
> index 0671d88..1984e30 100644
> --- a/include/hw/riscv/riscv_hart.h
> +++ b/include/hw/riscv/riscv_hart.h
> @@ -32,6 +32,7 @@ typedef struct RISCVHartArrayState {
>
>  /*< public >*/
>  uint32_t num_harts;
> +uint32_t hartid_base;
>  char *cpu_type;
>  RISCVCPU *harts;
>  } RISCVHartArrayState;
> --
> 2.7.4
>
>



Re: [Qemu-devel] [PATCH v2 3/5] hw/arm: Restrict pre-ARMv7 cpus to TCG

2019-09-03 Thread Alistair Francis
On Tue, Sep 3, 2019 at 4:48 AM Philippe Mathieu-Daudé  wrote:
>
> A KVM-only build won't be able to run pre-ARMv7 cpus, disable them.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
> v2: - "depends on !KVM" -> "depends on TCG" (rth)
> - do not modify default-configs/arm-softmmu.mak (thuth)
> ---
>  hw/arm/Kconfig | 23 +++
>  1 file changed, 23 insertions(+)
>
> diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> index 76a2a6bcbf..1c359a6f47 100644
> --- a/hw/arm/Kconfig
> +++ b/hw/arm/Kconfig
> @@ -1,3 +1,15 @@
> +config ARM_V4
> +depends on TCG
> +bool
> +
> +config ARM_V5
> +depends on TCG
> +bool
> +
> +config ARM_V6
> +depends on TCG
> +bool
> +
>  config ARM_VIRT
>  bool
>  imply PCI_DEVICES
> @@ -23,6 +35,7 @@ config ARM_VIRT
>
>  config CHEETAH
>  bool
> +select ARM_V4
>  select OMAP
>  select TSC210X
>
> @@ -32,6 +45,7 @@ config CUBIEBOARD
>
>  config DIGIC
>  bool
> +select ARM_V5
>  select PTIMER
>  select PFLASH_CFI02
>
> @@ -61,6 +75,7 @@ config HIGHBANK
>
>  config INTEGRATOR
>  bool
> +select ARM_V5
>  select ARM_TIMER
>  select INTEGRATOR_DEBUG
>  select PL011 # UART
> @@ -86,6 +101,7 @@ config MUSCA
>
>  config MUSICPAL
>  bool
> +select ARM_V5
>  select BITBANG_I2C
>  select MARVELL_88W8618
>  select PTIMER
> @@ -99,6 +115,7 @@ config NETDUINO2
>
>  config NSERIES
>  bool
> +select ARM_V6
>  select OMAP
>  select TMP105   # tempature sensor
>  select BLIZZARD # LCD/TV controller
> @@ -121,6 +138,7 @@ config OMAP
>
>  config PXA2XX
>  bool
> +select ARM_V5
>  select FRAMEBUFFER
>  select I2C
>  select SERIAL
> @@ -232,10 +250,12 @@ config COLLIE
>
>  config SX1
>  bool
> +select ARM_V4
>  select OMAP
>
>  config VERSATILE
>  bool
> +select ARM_V5
>  select ARM_TIMER # sp804
>  select PFLASH_CFI01
>  select LSI_SCSI_PCI
> @@ -327,6 +347,7 @@ config XLNX_VERSAL
>
>  config FSL_IMX25
>  bool
> +select ARM_V5
>  select IMX
>  select IMX_FEC
>  select IMX_I2C
> @@ -334,6 +355,7 @@ config FSL_IMX25
>
>  config FSL_IMX31
>  bool
> +select ARM_V6
>  select SERIAL
>  select IMX
>  select IMX_I2C
> @@ -349,6 +371,7 @@ config FSL_IMX6
>
>  config ASPEED_SOC
>  bool
> +select ARM_V5
>  select DS1338
>  select FTGMAC100
>  select I2C
> --
> 2.20.1
>
>



Re: [Qemu-devel] Cryptic errors from PIP install if missing openssl-devel

2019-09-03 Thread Cleber Rosa
On Tue, Sep 03, 2019 at 02:27:58PM -0300, Eduardo Habkost wrote:
> This would stop working as soon as a file named 'p@ssw0rD' gets
> created.  Can the API be more explicit somehow?
> 
> Is there anything that prevents us from using keyword arguments?
> e.g.:
> 
>   Session(..., username='root', password='p@ssw0rD')
>

OK, we have enough fair criticism of the approach that would keep the
API compatible, so let's implement a better, not non-backwards
compatible version, like suggested here.

Thanks for the feedback!
- Cleber.



Re: [Qemu-devel] [PATCH 0/2] tests: cpu-plug-test: fix x86 device_add cpu-foo test cases

2019-09-03 Thread Eduardo Habkost
On Fri, Aug 30, 2019 at 07:07:21AM -0400, Igor Mammedov wrote:
> Fixes bc1fb850a3 (vl.c deprecate incorrect CPUs topology) that introduced
> regression.

Queued on machine-next.  Thanks!

-- 
Eduardo



Re: [Qemu-devel] [PATCH v1 2/2] hw/pvrdma: add live migration support

2019-09-03 Thread Sukrit Bhatnagar
On Thu, 29 Aug 2019 at 18:23, Yuval Shaia  wrote:
>
> On Wed, Aug 28, 2019 at 07:53:28PM +0530, Sukrit Bhatnagar wrote:
> > vmstate_pvrdma describes the PCI and MSIX states as well as the dma
> > address for dsr and the gid table of device.
> > vmstate_pvrdma_gids describes each gid in the gid table.
> >
> > pvrdma_post_save() does the job of unregistering gid entries from the
> > backend device in the source host.
> >
> > pvrdma_post_load() maps to dsr using the loaded dma address, registers
> > each loaded gid into the backend device, and finally calls load_dsr()
> > to perform other mappings and ring init operations.
>
> I think it worth to mention that the dma address is kept in driver/device
> shared memory (dsr->dma) which is migrated as part of memory migration and
> it is out of the scope of this change and so we do not need to save/load
> the dma address during migration.
>
> Also you should specifically comment that this migration-support does not
> includes QP migration. This means that support for life migration *during*
> traffic is not yet supported.
>
> >
> > Cc: Marcel Apfelbaum 
> > Cc: Yuval Shaia 
> > Signed-off-by: Sukrit Bhatnagar 
> > ---
> >  hw/rdma/vmw/pvrdma_main.c | 77 +++
> >  1 file changed, 77 insertions(+)
> >
> > diff --git a/hw/rdma/vmw/pvrdma_main.c b/hw/rdma/vmw/pvrdma_main.c
> > index 6c90db96f9..6f8b56dea3 100644
> > --- a/hw/rdma/vmw/pvrdma_main.c
> > +++ b/hw/rdma/vmw/pvrdma_main.c
> > @@ -28,6 +28,7 @@
> >  #include "sysemu/sysemu.h"
> >  #include "monitor/monitor.h"
> >  #include "hw/rdma/rdma.h"
> > +#include "migration/register.h"
> >
> >  #include "../rdma_rm.h"
> >  #include "../rdma_backend.h"
> > @@ -593,6 +594,81 @@ static void pvrdma_shutdown_notifier(Notifier *n, void 
> > *opaque)
> >  pvrdma_fini(pci_dev);
> >  }
> >
> > +static int pvrdma_post_save(void *opaque)
> > +{
> > +int i, rc;
> > +PVRDMADev *dev = opaque;
> > +
> > +for (i = 0; i < MAX_GIDS; i++) {
> > +
>
> Empty line is redundant here.
>
> > +if (!dev->rdma_dev_res.port.gid_tbl[i].gid.global.interface_id) {
> > +continue;
> > +}
> > +rc = rdma_backend_del_gid(&dev->backend_dev,
> > +   dev->backend_eth_device_name,
> > +   &dev->rdma_dev_res.port.gid_tbl[i].gid);
> > +if (rc) {
> > +return -EINVAL;
>
> Some error report will help here i guess.

rdma_backend_del_gid() already generates an error report
when rc isn't 0.

Adding another statement for the same seems redundant.

> > +}
> > +}
> > +
> > +return 0;
> > +}
> > +
> > +static int pvrdma_post_load(void *opaque, int version_id)
> > +{
> > +int i, rc;
> > +PVRDMADev *dev = opaque;
> > +PCIDevice *pci_dev = PCI_DEVICE(dev);
> > +DSRInfo *dsr_info = &dev->dsr_info;
> > +
> > +dsr_info->dsr = rdma_pci_dma_map(pci_dev, dsr_info->dma,
> > +sizeof(struct 
> > pvrdma_device_shared_region));
> > +if (!dsr_info->dsr) {
> > +rdma_error_report("Failed to map to DSR");
> > +return -ENOMEM;
> > +}
> > +
> > +for (i = 0; i < MAX_GIDS; i++) {
> > +
>
> Empty line is redundant here.
>
> > +if (!dev->rdma_dev_res.port.gid_tbl[i].gid.global.interface_id) {
> > +continue;
> > +}
> > +
> > +rc = rdma_backend_add_gid(&dev->backend_dev,
> > +  dev->backend_eth_device_name,
> > +  &dev->rdma_dev_res.port.gid_tbl[i].gid);
> > +if (rc) {
> > +return -EINVAL;
> > +}
> > +}
> > +
> > +return load_dsr(dev);

Now that I will move load_dsr() before the del_gid loop,
I can use goto jumps on exit/error paths, so that I can
undo load_dsr if any del_gid fails.

> > +}
> > +
> > +static const VMStateDescription vmstate_pvrdma_gids = {
> > +.name = "pvrdma-gids",
> > +.fields = (VMStateField[]) {
> > +VMSTATE_UINT8_ARRAY_V(gid.raw, RdmaRmGid, 16, 0),
> > +VMSTATE_END_OF_LIST()
> > +}
> > +};
> > +
> > +static const VMStateDescription vmstate_pvrdma = {
> > +.name = PVRDMA_HW_NAME,
> > +.post_save = pvrdma_post_save,
> > +.post_load = pvrdma_post_load,
> > +.fields = (VMStateField[]) {
> > +VMSTATE_PCI_DEVICE(parent_obj, PVRDMADev),
> > +VMSTATE_MSIX(parent_obj, PVRDMADev),
> > +VMSTATE_UINT64(dsr_info.dma, PVRDMADev),
> > +VMSTATE_STRUCT_ARRAY(rdma_dev_res.port.gid_tbl, PVRDMADev,
> > + MAX_PORT_GIDS, 0, vmstate_pvrdma_gids,
> > + RdmaRmGid),
> > +VMSTATE_END_OF_LIST()
> > +}
> > +};
> > +
> >  static void pvrdma_realize(PCIDevice *pdev, Error **errp)
> >  {
> >  int rc = 0;
> > @@ -688,6 +764,7 @@ static void pvrdma_class_init(ObjectClass *klass, void 
> > *data)
> >
> >  dc->desc = "RDMA Devic

[Qemu-devel] [PULL v2 10/13] hostmem-file: fix pmem file size check

2019-09-03 Thread Eduardo Habkost
From: Stefan Hajnoczi 

Commit 314aec4a6e06844937f1677f6cba21981005f389 ("hostmem-file: reject
invalid pmem file sizes") added a file size check that verifies the
hostmem object's size parameter against the actual devdax pmem file.
This is useful because getting the size wrong results in confusing
errors inside the guest.

However, the code doesn't work properly for files where struct
stat::st_size is zero.  Hostmem-file's ->alloc() function returns early
without setting an Error, causing the following assertion failure:

  qemu/memory.c:2215: memory_region_get_ram_ptr: Assertion `mr->ram_block' 
failed.

This patch handles the case where qemu_get_pmem_size() returns 0 but
there is no error.

Fixes: 314aec4a6e06844937f1677f6cba21981005f389
Signed-off-by: Stefan Hajnoczi 
Message-Id: <20190823135632.25010-1-stefa...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 backends/hostmem-file.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index 29e55c9195..ecc15e3eb0 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -67,12 +67,12 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error 
**errp)
 uint64_t size;
 
 size = qemu_get_pmem_size(fb->mem_path, &local_err);
-if (!size) {
+if (local_err) {
 error_propagate(errp, local_err);
 return;
 }
 
-if (backend->size > size) {
+if (size && backend->size > size) {
 error_setg(errp, "size property %" PRIu64 " is larger than "
"pmem file \"%s\" size %" PRIu64, backend->size,
fb->mem_path, size);
-- 
2.21.0




[Qemu-devel] [PULL v2 08/13] pc: Don't make die-id mandatory unless necessary

2019-09-03 Thread Eduardo Habkost
We have this issue reported when using libvirt to hotplug CPUs:
https://bugzilla.redhat.com/show_bug.cgi?id=1741451

Basically, libvirt is not copying die-id from
query-hotpluggable-cpus, but die-id is now mandatory.

We could blame libvirt and say it is not following the documented
interface, because we have this buried in the QAPI schema
documentation:

> Note: currently there are 5 properties that could be present
> but management should be prepared to pass through other
> properties with device_add command to allow for future
> interface extension. This also requires the filed names to be kept in
> sync with the properties passed to -device/device_add.

But I don't think this would be reasonable from us.  We can just
make QEMU more flexible and let die-id to be omitted when there's
no ambiguity.  This will allow us to keep compatibility with
existing libvirt versions.

Test case included to ensure we don't break this again.

Fixes: commit 176d2cda0dee ("i386/cpu: Consolidate die-id validity in smp 
context")
Signed-off-by: Eduardo Habkost 
Message-Id: <20190816170750.23910-1-ehabk...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 hw/i386/pc.c |  8 ++
 tests/acceptance/pc_cpu_hotplug_props.py | 35 
 2 files changed, 43 insertions(+)
 create mode 100644 tests/acceptance/pc_cpu_hotplug_props.py

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 3494423d63..c7200b0b54 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2421,6 +2421,14 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 int max_socket = (ms->smp.max_cpus - 1) /
 smp_threads / smp_cores / pcms->smp_dies;
 
+/*
+ * die-id was optional in QEMU 4.0 and older, so keep it optional
+ * if there's only one die per socket.
+ */
+if (cpu->die_id < 0 && pcms->smp_dies == 1) {
+cpu->die_id = 0;
+}
+
 if (cpu->socket_id < 0) {
 error_setg(errp, "CPU socket-id is not set");
 return;
diff --git a/tests/acceptance/pc_cpu_hotplug_props.py 
b/tests/acceptance/pc_cpu_hotplug_props.py
new file mode 100644
index 00..08b7e632c6
--- /dev/null
+++ b/tests/acceptance/pc_cpu_hotplug_props.py
@@ -0,0 +1,35 @@
+#
+# Ensure CPU die-id can be omitted on -device
+#
+#  Copyright (c) 2019 Red Hat Inc
+#
+# Author:
+#  Eduardo Habkost 
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, see .
+#
+
+from avocado_qemu import Test
+
+class OmittedCPUProps(Test):
+"""
+:avocado: tags=arch:x86_64
+"""
+def test_no_die_id(self):
+self.vm.add_args('-nodefaults', '-S')
+self.vm.add_args('-smp', '1,sockets=2,cores=2,threads=2,maxcpus=8')
+self.vm.add_args('-cpu', 'qemu64')
+self.vm.add_args('-device', 
'qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0')
+self.vm.launch()
+self.assertEquals(len(self.vm.command('query-cpus')), 2)
-- 
2.21.0




[Qemu-devel] [PULL v2 12/13] x86: do not advertise die-id in query-hotpluggbale-cpus if '-smp dies' is not set

2019-09-03 Thread Eduardo Habkost
From: Igor Mammedov 

Commit 176d2cda0 (i386/cpu: Consolidate die-id validity in smp context) added
new 'die-id' topology property to CPUs and exposed it via QMP command
query-hotpluggable-cpus, which broke -device/device_add cpu-foo for existing
users that do not support die-id/dies yet. That's would be fine if it happened
to new machine type only but it also happened to old machine types,
which breaks migration from old QEMU to the new one, for example following CLI:

  OLD-QEMU -M pc-i440fx-4.0 -smp 1,max_cpus=2 \
   -device qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id
is not able to start with new QEMU, complaining about invalid die-id.

After discovering regression, the patch
   "pc: Don't make die-id mandatory unless necessary"
makes die-id optional so old CLI would work.

However it's not enough as new QEMU still exposes die-id via 
query-hotpluggbale-cpus
QMP command, so the users that started old machine type on new QEMU, using all
properties (including die-id) received from QMP command (as required), won't be
able to start old QEMU using the same properties since it doesn't support 
die-id.

Fix it by hiding die-id in query-hotpluggbale-cpus for all machine types in case
'-smp dies' is not provided on CLI or -smp dies = 1', in which case smp_dies == 
1
and APIC ID is calculated in default way (as it was before DIE support) so we 
won't
need compat code as in both cases the topology provided to guest via CPUID is 
the same.

Signed-off-by: Igor Mammedov 
Message-Id: <20190902120222.6179-1-imamm...@redhat.com>
Reviewed-by: Eduardo Habkost 
Signed-off-by: Eduardo Habkost 
---
 hw/i386/pc.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c7200b0b54..bad866fe44 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2916,8 +2916,10 @@ static const CPUArchIdList 
*pc_possible_cpu_arch_ids(MachineState *ms)
  ms->smp.threads, &topo);
 ms->possible_cpus->cpus[i].props.has_socket_id = true;
 ms->possible_cpus->cpus[i].props.socket_id = topo.pkg_id;
-ms->possible_cpus->cpus[i].props.has_die_id = true;
-ms->possible_cpus->cpus[i].props.die_id = topo.die_id;
+if (pcms->smp_dies > 1) {
+ms->possible_cpus->cpus[i].props.has_die_id = true;
+ms->possible_cpus->cpus[i].props.die_id = topo.die_id;
+}
 ms->possible_cpus->cpus[i].props.has_core_id = true;
 ms->possible_cpus->cpus[i].props.core_id = topo.core_id;
 ms->possible_cpus->cpus[i].props.has_thread_id = true;
-- 
2.21.0




[Qemu-devel] [PULL v2 11/13] i386/vmmouse: Properly reset state

2019-09-03 Thread Eduardo Habkost
From: Jan Kiszka 

nb_queue was not zeroed so that we no longer delivered events if a
previous guest left the device in an overflow state.

The state of absolute does not matter as the next vmmouse_update_handler
call will align it again.

Signed-off-by: Jan Kiszka 
Message-Id: 
Reviewed-by: Eduardo Habkost 
Signed-off-by: Eduardo Habkost 
---
 hw/i386/vmmouse.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/i386/vmmouse.c b/hw/i386/vmmouse.c
index 012ab90396..41ad91ad53 100644
--- a/hw/i386/vmmouse.c
+++ b/hw/i386/vmmouse.c
@@ -258,6 +258,7 @@ static void vmmouse_reset(DeviceState *d)
 VMMouseState *s = VMMOUSE(d);
 
 s->queue_size = VMMOUSE_QUEUE_SIZE;
+s->nb_queue = 0;
 
 vmmouse_disable(s);
 }
-- 
2.21.0




[Qemu-devel] [PULL v2 03/13] numa: move numa global variable nb_numa_nodes into MachineState

2019-09-03 Thread Eduardo Habkost
From: Tao Xu 

Add struct NumaState in MachineState and move existing numa global
nb_numa_nodes(renamed as "num_nodes") into NumaState. And add variable
numa_support into MachineClass to decide which submachines support NUMA.

Reviewed-by: Igor Mammedov 
Suggested-by: Igor Mammedov 
Suggested-by: Eduardo Habkost 
Signed-off-by: Tao Xu 
Message-Id: <20190809065731.9097-3-tao3...@intel.com>
[ehabkost: include hw/boards.h again to fix build failures]
Signed-off-by: Eduardo Habkost 
---
 include/hw/acpi/aml-build.h |  2 +-
 include/hw/boards.h |  1 +
 include/sysemu/numa.h   | 10 -
 exec.c  |  5 ++-
 hw/acpi/aml-build.c |  4 +-
 hw/arm/boot.c   |  4 +-
 hw/arm/sbsa-ref.c   |  4 +-
 hw/arm/virt-acpi-build.c| 10 +++--
 hw/arm/virt.c   |  4 +-
 hw/core/machine-hmp-cmds.c  | 13 +--
 hw/core/machine.c   | 14 +--
 hw/core/numa.c  | 60 +
 hw/i386/acpi-build.c|  2 +-
 hw/i386/pc.c|  9 +++--
 hw/mem/pc-dimm.c|  2 +
 hw/pci-bridge/pci_expander_bridge.c |  9 -
 hw/ppc/spapr.c  | 19 -
 17 files changed, 113 insertions(+), 59 deletions(-)

diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 1a563ad756..991cf05134 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -414,7 +414,7 @@ build_append_gas_from_struct(GArray *table, const struct 
AcpiGenericAddress *s)
 void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
uint64_t len, int node, MemoryAffinityFlags flags);
 
-void build_slit(GArray *table_data, BIOSLinker *linker);
+void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms);
 
 void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f,
 const char *oem_id, const char *oem_table_id);
diff --git a/include/hw/boards.h b/include/hw/boards.h
index ced86109ec..2289536e48 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -299,6 +299,7 @@ struct MachineState {
 CPUArchIdList *possible_cpus;
 CpuTopology smp;
 struct NVDIMMState *nvdimms_state;
+struct NumaState *numa_state;
 };
 
 #define DEFINE_MACHINE(namestr, machine_initfn) \
diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h
index 7a4ce89765..1786e861d0 100644
--- a/include/sysemu/numa.h
+++ b/include/sysemu/numa.h
@@ -14,7 +14,6 @@ struct CPUArchId;
 #define NUMA_DISTANCE_MAX 254
 #define NUMA_DISTANCE_UNREACHABLE 255
 
-extern int nb_numa_nodes;   /* Number of NUMA nodes */
 extern bool have_numa_distance;
 
 struct NodeInfo {
@@ -31,10 +30,17 @@ struct NumaNodeMem {
 
 extern NodeInfo numa_info[MAX_NODES];
 
+struct NumaState {
+/* Number of NUMA nodes */
+int num_nodes;
+
+};
+typedef struct NumaState NumaState;
+
 void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp);
 void parse_numa_opts(MachineState *ms);
 void numa_complete_configuration(MachineState *ms);
-void query_numa_node_mem(NumaNodeMem node_mem[]);
+void query_numa_node_mem(NumaNodeMem node_mem[], MachineState *ms);
 extern QemuOptsList qemu_numa_opts;
 void numa_legacy_auto_assign_ram(MachineClass *mc, NodeInfo *nodes,
  int nb_nodes, ram_addr_t size);
diff --git a/exec.c b/exec.c
index 1df966d17a..e813058b05 100644
--- a/exec.c
+++ b/exec.c
@@ -1750,6 +1750,7 @@ long qemu_minrampagesize(void)
 long hpsize = LONG_MAX;
 long mainrampagesize;
 Object *memdev_root;
+MachineState *ms = MACHINE(qdev_get_machine());
 
 mainrampagesize = qemu_mempath_getpagesize(mem_path);
 
@@ -1777,7 +1778,9 @@ long qemu_minrampagesize(void)
  * so if its page size is smaller we have got to report that size instead.
  */
 if (hpsize > mainrampagesize &&
-(nb_numa_nodes == 0 || numa_info[0].node_memdev == NULL)) {
+(ms->numa_state == NULL ||
+ ms->numa_state->num_nodes == 0 ||
+ numa_info[0].node_memdev == NULL)) {
 static bool warned;
 if (!warned) {
 error_report("Huge page support disabled (n/a for main memory).");
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 555c24f21d..043b47694c 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -25,6 +25,7 @@
 #include "qemu/bswap.h"
 #include "qemu/bitops.h"
 #include "sysemu/numa.h"
+#include "hw/boards.h"
 
 static GArray *build_alloc_array(void)
 {
@@ -1726,10 +1727,11 @@ void build_srat_memory(AcpiSratMemoryAffinity *numamem, 
uint64_t base,
  * ACPI spec 5.2.17 System Locality Distance Information Table
  * (Revision 2.0 or later)
  */
-void build_slit(GArray *table_data, BIOSLinker *linker)
+void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms)
 {
 int slit_start, i, j;
 slit_

[Qemu-devel] [PULL v2 09/13] qapi: report the default CPU type for each machine

2019-09-03 Thread Eduardo Habkost
From: Daniel P. Berrangé 

When user doesn't request any explicit CPU model with libvirt or QEMU,
a machine type specific CPU model is picked. Currently there is no way
to determine what this QEMU built-in default is, so libvirt cannot
report this back to the user in the XML config.

This extends the "query-machines" QMP command so that it reports the
default CPU model typename for each machine.

Reviewed-by: Eric Blake 
Signed-off-by: Daniel P. Berrangé 
Message-Id: <20190822100412.23746-1-berra...@redhat.com>
Signed-off-by: Eduardo Habkost 
---
 qapi/machine.json  | 5 -
 hw/core/machine-qmp-cmds.c | 4 
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/qapi/machine.json b/qapi/machine.json
index de5c742d72..ca26779f1a 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -348,13 +348,16 @@
 #  in future versions of QEMU according to the QEMU deprecation
 #  policy (since 4.1.0)
 #
+# @default-cpu-type: default CPU model typename if none is requested via
+#the -cpu argument. (since 4.2)
+#
 # Since: 1.2.0
 ##
 { 'struct': 'MachineInfo',
   'data': { 'name': 'str', '*alias': 'str',
 '*is-default': 'bool', 'cpu-max': 'int',
 'hotpluggable-cpus': 'bool',  'numa-mem-supported': 'bool',
-'deprecated': 'bool' } }
+'deprecated': 'bool', '*default-cpu-type': 'str' } }
 
 ##
 # @query-machines:
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index 15cf7c62e3..eed5aeb2f7 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -230,6 +230,10 @@ MachineInfoList *qmp_query_machines(Error **errp)
 info->hotpluggable_cpus = mc->has_hotpluggable_cpus;
 info->numa_mem_supported = mc->numa_mem_supported;
 info->deprecated = !!mc->deprecation_reason;
+if (mc->default_cpu_type) {
+info->default_cpu_type = g_strdup(mc->default_cpu_type);
+info->has_default_cpu_type = true;
+}
 
 entry = g_malloc0(sizeof(*entry));
 entry->value = info;
-- 
2.21.0




[Qemu-devel] [PULL v2 05/13] numa: move numa global variable numa_info into MachineState

2019-09-03 Thread Eduardo Habkost
From: Tao Xu 

Move existing numa global numa_info (renamed as "nodes") into NumaState.

Reviewed-by: Igor Mammedov 
Suggested-by: Igor Mammedov 
Suggested-by: Eduardo Habkost 
Signed-off-by: Tao Xu 
Message-Id: <20190809065731.9097-5-tao3...@intel.com>
Signed-off-by: Eduardo Habkost 
---
 include/sysemu/numa.h|  5 +++--
 exec.c   |  2 +-
 hw/acpi/aml-build.c  |  6 --
 hw/arm/boot.c|  2 +-
 hw/arm/sbsa-ref.c|  3 ++-
 hw/arm/virt-acpi-build.c |  7 ---
 hw/arm/virt.c|  3 ++-
 hw/core/numa.c   | 15 +--
 hw/i386/pc.c |  4 ++--
 hw/ppc/spapr.c   | 10 +-
 hw/ppc/spapr_pci.c   |  4 +++-
 11 files changed, 36 insertions(+), 25 deletions(-)

diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h
index bfe04b514c..ae9c41d02b 100644
--- a/include/sysemu/numa.h
+++ b/include/sysemu/numa.h
@@ -26,14 +26,15 @@ struct NumaNodeMem {
 uint64_t node_plugged_mem;
 };
 
-extern NodeInfo numa_info[MAX_NODES];
-
 struct NumaState {
 /* Number of NUMA nodes */
 int num_nodes;
 
 /* Allow setting NUMA distance for different NUMA nodes */
 bool have_numa_distance;
+
+/* NUMA nodes information */
+NodeInfo nodes[MAX_NODES];
 };
 typedef struct NumaState NumaState;
 
diff --git a/exec.c b/exec.c
index e813058b05..0d47788f5f 100644
--- a/exec.c
+++ b/exec.c
@@ -1780,7 +1780,7 @@ long qemu_minrampagesize(void)
 if (hpsize > mainrampagesize &&
 (ms->numa_state == NULL ||
  ms->numa_state->num_nodes == 0 ||
- numa_info[0].node_memdev == NULL)) {
+ ms->numa_state->nodes[0].node_memdev == NULL)) {
 static bool warned;
 if (!warned) {
 error_report("Huge page support disabled (n/a for main memory).");
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 043b47694c..78aee1a2f9 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1738,8 +1738,10 @@ void build_slit(GArray *table_data, BIOSLinker *linker, 
MachineState *ms)
 build_append_int_noprefix(table_data, nb_numa_nodes, 8);
 for (i = 0; i < nb_numa_nodes; i++) {
 for (j = 0; j < nb_numa_nodes; j++) {
-assert(numa_info[i].distance[j]);
-build_append_int_noprefix(table_data, numa_info[i].distance[j], 1);
+assert(ms->numa_state->nodes[i].distance[j]);
+build_append_int_noprefix(table_data,
+  ms->numa_state->nodes[i].distance[j],
+  1);
 }
 }
 
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index d3e88626c4..bf97ef3e33 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -601,7 +601,7 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info 
*binfo,
 if (ms->numa_state != NULL && ms->numa_state->num_nodes > 0) {
 mem_base = binfo->loader_start;
 for (i = 0; i < ms->numa_state->num_nodes; i++) {
-mem_len = numa_info[i].node_mem;
+mem_len = ms->numa_state->nodes[i].node_mem;
 rc = fdt_add_memory_node(fdt, acells, mem_base,
  scells, mem_len, i);
 if (rc < 0) {
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index 7d7bb9fd96..27046cc284 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -170,7 +170,8 @@ static void create_fdt(SBSAMachineState *sms)
 idx = (i * nb_numa_nodes + j) * 3;
 matrix[idx + 0] = cpu_to_be32(i);
 matrix[idx + 1] = cpu_to_be32(j);
-matrix[idx + 2] = cpu_to_be32(numa_info[i].distance[j]);
+matrix[idx + 2] =
+cpu_to_be32(ms->numa_state->nodes[i].distance[j]);
 }
 }
 
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index b1deb76a53..6cdf156cf5 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -535,11 +535,12 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
 
 mem_base = vms->memmap[VIRT_MEM].base;
 for (i = 0; i < ms->numa_state->num_nodes; ++i) {
-if (numa_info[i].node_mem > 0) {
+if (ms->numa_state->nodes[i].node_mem > 0) {
 numamem = acpi_data_push(table_data, sizeof(*numamem));
-build_srat_memory(numamem, mem_base, numa_info[i].node_mem, i,
+build_srat_memory(numamem, mem_base,
+  ms->numa_state->nodes[i].node_mem, i,
   MEM_AFFINITY_ENABLED);
-mem_base += numa_info[i].node_mem;
+mem_base += ms->numa_state->nodes[i].node_mem;
 }
 }
 
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 414f7ecd02..d74538b021 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -246,7 +246,8 @@ static void create_fdt(VirtMachineState *vms)
 idx = (i * nb_numa_nodes + j) * 3;
 matrix[idx + 0] = cpu_to_be32(i);
 matrix[idx + 1] = cpu_to_

[Qemu-devel] [PULL v2 13/13] migration: Do not re-read the clock on pre_save in case of paused guest

2019-09-03 Thread Eduardo Habkost
From: "Maxiwell S. Garcia" 

The clock move makes the guest knows about the paused time between the
'stop' and 'migrate' commands. This is an issue in an already-paused
VM because some side effects, like process stalls, could happen
after migration.

So, this patch checks the runstate of guest in the pre_save handler and
do not re-reads the clock in case of paused state (cold migration).

Signed-off-by: Maxiwell S. Garcia 
Message-Id: <20190829210711.6570-1-maxiw...@linux.ibm.com>
Reviewed-by: Marcelo Tosatti 
Signed-off-by: Eduardo Habkost 
---
 hw/i386/kvm/clock.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index 80c133a724..2c59b6894b 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -41,6 +41,9 @@ typedef struct KVMClockState {
 uint64_t clock;
 bool clock_valid;
 
+/* whether the 'clock' value was obtained in the 'paused' state */
+bool runstate_paused;
+
 /* whether machine type supports reliable KVM_GET_CLOCK */
 bool mach_use_reliable_get_clock;
 
@@ -202,6 +205,8 @@ static void kvmclock_vm_state_change(void *opaque, int 
running,
 return;
 }
 
+s->runstate_paused = runstate_check(RUN_STATE_PAUSED);
+
 kvm_synchronize_all_tsc();
 
 kvm_update_clock(s);
@@ -260,9 +265,9 @@ static int kvmclock_pre_load(void *opaque)
 }
 
 /*
- * When migrating, read the clock just before migration,
- * so that the guest clock counts during the events
- * between:
+ * When migrating a running guest, read the clock just
+ * before migration, so that the guest clock counts
+ * during the events between:
  *
  *  * vm_stop()
  *  *
@@ -277,7 +282,9 @@ static int kvmclock_pre_save(void *opaque)
 {
 KVMClockState *s = opaque;
 
-kvm_update_clock(s);
+if (!s->runstate_paused) {
+kvm_update_clock(s);
+}
 
 return 0;
 }
-- 
2.21.0




[Qemu-devel] [PULL v2 07/13] pc: Improve error message when die-id is omitted

2019-09-03 Thread Eduardo Habkost
The error message when die-id is omitted doesn't make sense:

  $ qemu-system-x86_64 -smp 1,sockets=6,maxcpus=6 \
-device qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0
  qemu-system-x86_64: -device 
qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0: \
Invalid CPU die-id: 4294967295 must be in range 0:0

Fix it, so it will now read:

  qemu-system-x86_64: -device 
qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0: \
CPU die-id is not set

Signed-off-by: Eduardo Habkost 
Message-Id: <20190815183803.13346-3-ehabk...@redhat.com>
Reviewed-by: Igor Mammedov 
Reviewed-by: Vanderson M. do Rosario 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Eduardo Habkost 
---
 hw/i386/pc.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 584cd3ed0a..3494423d63 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2428,6 +2428,10 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 error_setg(errp, "Invalid CPU socket-id: %u must be in range 0:%u",
cpu->socket_id, max_socket);
 return;
+}
+if (cpu->die_id < 0) {
+error_setg(errp, "CPU die-id is not set");
+return;
 } else if (cpu->die_id > pcms->smp_dies - 1) {
 error_setg(errp, "Invalid CPU die-id: %u must be in range 0:%u",
cpu->die_id, pcms->smp_dies - 1);
-- 
2.21.0




[Qemu-devel] [PULL v2 00/13] Machine + x86 queue, 2019-09-03

2019-09-03 Thread Eduardo Habkost
Changes v1 -> v2:
* (v1 was incorrectly tagged "v6" on the subject line)
* Removed patch that caused spurious warnings ("numa: Introduce
  MachineClass::auto_enable_numa for implicit NUMA node")
* New patches:
  * Keep query-hotpluggable-cpus output compatible with older
QEMU if '-smp dies' is not set
  * migration: Do not re-read the clock on pre_save in case of
paused guest


The following changes since commit cc6613e244e86c66f83467eab5284825d7057cea:

  Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' 
into staging (2019-09-03 11:06:09 +0100)

are available in the Git repository at:

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

for you to fetch changes up to 417332494602e3edadfae3b759a29fa0bb96223f:

  migration: Do not re-read the clock on pre_save in case of paused guest 
(2019-09-03 14:39:46 -0300)


Machine + x86 queue, 2019-09-03

Bug fixes:
* Fix die-id validation regression (Eduardo Habkost)
* vmmouse: Properly reset state (Jan Kiszka)
* hostmem-file: fix pmem file size check (Stefan Hajnoczi)
* Keep query-hotpluggable-cpus output compatible with older QEMU
  if '-smp dies' is not set (Igor Mammedov)
* migration: Do not re-read the clock on pre_save in case of paused guest
  (Maxiwell S. Garcia)

Cleanups:
* NUMA code cleanups (Tao Xu)
* Remove stale externs from includes (Alex Bennée)

Features:
* qapi: report the default CPU type for each machine (Daniel P. Berrangé)



Queue for Machine Core patches


Alex Bennée (1):
  includes: remove stale [smp|max]_cpus externs

Daniel P. Berrangé (1):
  qapi: report the default CPU type for each machine

Eduardo Habkost (3):
  pc: Fix error message on die-id validation
  pc: Improve error message when die-id is omitted
  pc: Don't make die-id mandatory unless necessary

Igor Mammedov (1):
  x86: do not advertise die-id in query-hotpluggbale-cpus if '-smp dies'
is not set

Jan Kiszka (1):
  i386/vmmouse: Properly reset state

Maxiwell S. Garcia (1):
  migration: Do not re-read the clock on pre_save in case of paused
guest

Stefan Hajnoczi (1):
  hostmem-file: fix pmem file size check

Tao Xu (4):
  hw/arm: simplify arm_load_dtb
  numa: move numa global variable nb_numa_nodes into MachineState
  numa: move numa global variable have_numa_distance into MachineState
  numa: move numa global variable numa_info into MachineState

 qapi/machine.json|  5 +-
 include/hw/acpi/aml-build.h  |  2 +-
 include/hw/arm/boot.h|  4 +-
 include/hw/boards.h  |  1 +
 include/sysemu/numa.h| 17 +++--
 include/sysemu/sysemu.h  |  2 -
 backends/hostmem-file.c  |  4 +-
 exec.c   |  5 +-
 hw/acpi/aml-build.c  | 10 ++-
 hw/arm/aspeed.c  |  5 +-
 hw/arm/boot.c| 21 ---
 hw/arm/collie.c  |  8 +--
 hw/arm/cubieboard.c  |  5 +-
 hw/arm/exynos4_boards.c  |  7 +--
 hw/arm/highbank.c|  8 +--
 hw/arm/imx25_pdk.c   |  5 +-
 hw/arm/integratorcp.c|  8 +--
 hw/arm/kzm.c |  5 +-
 hw/arm/mainstone.c   |  5 +-
 hw/arm/mcimx6ul-evk.c|  5 +-
 hw/arm/mcimx7d-sabre.c   |  5 +-
 hw/arm/musicpal.c|  8 +--
 hw/arm/nseries.c |  5 +-
 hw/arm/omap_sx1.c|  5 +-
 hw/arm/palm.c| 10 +--
 hw/arm/raspi.c   |  6 +-
 hw/arm/realview.c|  5 +-
 hw/arm/sabrelite.c   |  5 +-
 hw/arm/sbsa-ref.c| 12 ++--
 hw/arm/spitz.c   |  5 +-
 hw/arm/tosa.c|  8 +--
 hw/arm/versatilepb.c |  5 +-
 hw/arm/vexpress.c|  5 +-
 hw/arm/virt-acpi-build.c | 19 +++---
 hw/arm/virt.c| 17 ++---
 hw/arm/xilinx_zynq.c |  8 +--
 hw/arm/xlnx-versal-virt.c|  7 +--
 hw/arm/xlnx-zcu102.c |  5 +-
 hw/arm/z2.c  |  8 +--
 hw/core/machine-hmp-cmds.c   | 13 +++-
 hw/core/machine-qmp-cmds.c   |  4 ++
 hw/core/machine.c| 14 +++--
 hw/core/numa.c   | 80 ++--
 hw/i386/acpi-build.c |  4 +-
 hw/i386/kvm/clock.c  | 15 +++--
 hw/i386/pc.c | 33 +++---
 hw/i386/vmmouse.c|  1 +
 hw/mem/pc-dimm.c |  2 +
 hw/pci-bridge/pci_expander_b

[Qemu-devel] [PULL v2 02/13] hw/arm: simplify arm_load_dtb

2019-09-03 Thread Eduardo Habkost
From: Tao Xu 

In struct arm_boot_info, kernel_filename, initrd_filename and
kernel_cmdline are copied from from MachineState. This patch add
MachineState as a parameter into arm_load_dtb() and move the copy chunk
of kernel_filename, initrd_filename and kernel_cmdline into
arm_load_kernel().

Reviewed-by: Igor Mammedov 
Reviewed-by: Liu Jingqi 
Suggested-by: Igor Mammedov 
Signed-off-by: Tao Xu 
Message-Id: <20190809065731.9097-2-tao3...@intel.com>
Reviewed-by: Alistair Francis 
Acked-by: Andrew Jeffery 
Acked-by: Cédric Le Goater 
[ehabkost: include hw/boards.h again to fix build failures]
Signed-off-by: Eduardo Habkost 
---
 include/hw/arm/boot.h |  4 ++--
 hw/arm/aspeed.c   |  5 +
 hw/arm/boot.c | 15 +--
 hw/arm/collie.c   |  8 +---
 hw/arm/cubieboard.c   |  5 +
 hw/arm/exynos4_boards.c   |  7 ++-
 hw/arm/highbank.c |  8 +---
 hw/arm/imx25_pdk.c|  5 +
 hw/arm/integratorcp.c |  8 +---
 hw/arm/kzm.c  |  5 +
 hw/arm/mainstone.c|  5 +
 hw/arm/mcimx6ul-evk.c |  5 +
 hw/arm/mcimx7d-sabre.c|  5 +
 hw/arm/musicpal.c |  8 +---
 hw/arm/nseries.c  |  5 +
 hw/arm/omap_sx1.c |  5 +
 hw/arm/palm.c | 10 ++
 hw/arm/raspi.c|  6 +-
 hw/arm/realview.c |  5 +
 hw/arm/sabrelite.c|  5 +
 hw/arm/sbsa-ref.c |  3 +--
 hw/arm/spitz.c|  5 +
 hw/arm/tosa.c |  8 +---
 hw/arm/versatilepb.c  |  5 +
 hw/arm/vexpress.c |  5 +
 hw/arm/virt.c |  8 +++-
 hw/arm/xilinx_zynq.c  |  8 +---
 hw/arm/xlnx-versal-virt.c |  7 ++-
 hw/arm/xlnx-zcu102.c  |  5 +
 hw/arm/z2.c   |  8 +---
 30 files changed, 44 insertions(+), 147 deletions(-)

diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
index 5714dea1a2..7f4d0ca7cd 100644
--- a/include/hw/arm/boot.h
+++ b/include/hw/arm/boot.h
@@ -131,7 +131,7 @@ struct arm_boot_info {
  * before sysbus-fdt arm_register_platform_bus_fdt_creator. Indeed the
  * machine init done notifiers are called in registration reverse order.
  */
-void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info);
+void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info 
*info);
 
 AddressSpace *arm_boot_address_space(ARMCPU *cpu,
  const struct arm_boot_info *info);
@@ -158,7 +158,7 @@ AddressSpace *arm_boot_address_space(ARMCPU *cpu,
  * Note: Must not be called unless have_dtb(binfo) is true.
  */
 int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
- hwaddr addr_limit, AddressSpace *as);
+ hwaddr addr_limit, AddressSpace *as, MachineState *ms);
 
 /* Write a secure board setup routine with a dummy handler for SMCs */
 void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 7a2e885e0b..13e208c78c 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -242,9 +242,6 @@ static void aspeed_board_init(MachineState *machine,
 write_boot_rom(drive0, FIRMWARE_ADDR, fl->size, &error_abort);
 }
 
-aspeed_board_binfo.kernel_filename = machine->kernel_filename;
-aspeed_board_binfo.initrd_filename = machine->initrd_filename;
-aspeed_board_binfo.kernel_cmdline = machine->kernel_cmdline;
 aspeed_board_binfo.ram_size = ram_size;
 aspeed_board_binfo.loader_start = sc->info->memmap[ASPEED_SDRAM];
 aspeed_board_binfo.nb_cpus = bmc->soc.num_cpus;
@@ -253,7 +250,7 @@ static void aspeed_board_init(MachineState *machine,
 cfg->i2c_init(bmc);
 }
 
-arm_load_kernel(ARM_CPU(first_cpu), &aspeed_board_binfo);
+arm_load_kernel(ARM_CPU(first_cpu), machine, &aspeed_board_binfo);
 }
 
 static void palmetto_bmc_i2c_init(AspeedBoardState *bmc)
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index eff89ab80e..b46eaefa2d 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -17,6 +17,7 @@
 #include "sysemu/kvm.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/numa.h"
+#include "hw/boards.h"
 #include "sysemu/reset.h"
 #include "hw/loader.h"
 #include "elf.h"
@@ -523,7 +524,7 @@ static void fdt_add_psci_node(void *fdt)
 }
 
 int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
- hwaddr addr_limit, AddressSpace *as)
+ hwaddr addr_limit, AddressSpace *as, MachineState *ms)
 {
 void *fdt = NULL;
 int size, rc, n = 0;
@@ -626,9 +627,9 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info 
*binfo,
 qemu_fdt_add_subnode(fdt, "/chosen");
 }
 
-if (binfo->kernel_cmdline && *binfo->kernel_cmdline) {
+if (ms->kernel_cmdline && *ms->kernel_cmdline) {
 rc = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
- binfo->kernel_cmdline);
+ ms->kernel_cmdline);
 if (rc < 0) {

[Qemu-devel] [PULL v2 06/13] pc: Fix error message on die-id validation

2019-09-03 Thread Eduardo Habkost
The error message for die-id range validation is incorrect.  Example:

  $ qemu-system-x86_64 -smp 1,sockets=6,maxcpus=6 \
-device qemu64-x86_64-cpu,socket-id=1,die-id=1,core-id=0,thread-id=0
  qemu-system-x86_64: -device 
qemu64-x86_64-cpu,socket-id=1,die-id=1,core-id=0,thread-id=0: \
Invalid CPU die-id: 1 must be in range 0:5

The actual range for die-id in this example is 0:0.

Fix the error message to use smp_dies and print the correct range.

Signed-off-by: Eduardo Habkost 
Message-Id: <20190815183803.13346-2-ehabk...@redhat.com>
Reviewed-by: Igor Mammedov 
Reviewed-by: Vanderson M. do Rosario 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Eduardo Habkost 
---
 hw/i386/pc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 985e9261b0..584cd3ed0a 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2430,7 +2430,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
 return;
 } else if (cpu->die_id > pcms->smp_dies - 1) {
 error_setg(errp, "Invalid CPU die-id: %u must be in range 0:%u",
-   cpu->die_id, max_socket);
+   cpu->die_id, pcms->smp_dies - 1);
 return;
 }
 if (cpu->core_id < 0) {
-- 
2.21.0




[Qemu-devel] [RFC v3 PATCH 10/45] multi-process: setup a machine object for remote device process

2019-09-03 Thread Jagannathan Raman
remote-machine object sets up various subsystems of the remote device
process. Instantiate PCI host bridge object and initialize RAM, IO &
PCI memory regions.

Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
Signed-off-by: Elena Ufimtseva 
---
 exec.c|   3 +-
 include/exec/address-spaces.h |   2 +
 include/remote/machine.h  |  46 
 remote/Makefile.objs  |   1 +
 remote/machine.c  | 118 ++
 remote/remote-main.c  |   7 +++
 6 files changed, 175 insertions(+), 2 deletions(-)
 create mode 100644 include/remote/machine.h
 create mode 100644 remote/machine.c

diff --git a/exec.c b/exec.c
index b3f1aa9..04d9663 100644
--- a/exec.c
+++ b/exec.c
@@ -197,7 +197,6 @@ typedef struct subpage_t {
 #define PHYS_SECTION_WATCH 3
 
 static void io_mem_init(void);
-static void memory_map_init(void);
 static void tcg_commit(MemoryListener *listener);
 
 static MemoryRegion io_mem_watch;
@@ -3165,7 +3164,7 @@ static void tcg_commit(MemoryListener *listener)
 tlb_flush(cpuas->cpu);
 }
 
-static void memory_map_init(void)
+void memory_map_init(void)
 {
 system_memory = g_malloc(sizeof(*system_memory));
 
diff --git a/include/exec/address-spaces.h b/include/exec/address-spaces.h
index db8bfa9..56a877b 100644
--- a/include/exec/address-spaces.h
+++ b/include/exec/address-spaces.h
@@ -33,6 +33,8 @@ MemoryRegion *get_system_memory(void);
  */
 MemoryRegion *get_system_io(void);
 
+void memory_map_init(void);
+
 extern AddressSpace address_space_memory;
 extern AddressSpace address_space_io;
 
diff --git a/include/remote/machine.h b/include/remote/machine.h
new file mode 100644
index 000..a00732d
--- /dev/null
+++ b/include/remote/machine.h
@@ -0,0 +1,46 @@
+/*
+ * Remote machine configuration
+ *
+ * Copyright 2019, Oracle and/or its affiliates.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef REMOTE_MACHINE_H
+#define REMOTE_MACHINE_H
+
+#include "qemu/osdep.h"
+#include "qom/object.h"
+#include "hw/boards.h"
+#include "remote/pcihost.h"
+#include "qemu/notify.h"
+
+typedef struct RemMachineState {
+MachineState parent_obj;
+
+RemPCIHost *host;
+} RemMachineState;
+
+#define TYPE_REMOTE_MACHINE "remote-machine"
+#define REMOTE_MACHINE(obj) \
+OBJECT_CHECK(RemMachineState, (obj), TYPE_REMOTE_MACHINE)
+
+void qemu_run_machine_init_done_notifiers(void);
+
+#endif
diff --git a/remote/Makefile.objs b/remote/Makefile.objs
index 2757f5a..13d4c48 100644
--- a/remote/Makefile.objs
+++ b/remote/Makefile.objs
@@ -1,2 +1,3 @@
 remote-pci-obj-$(CONFIG_MPQEMU) += remote-main.o
 remote-pci-obj-$(CONFIG_MPQEMU) += pcihost.o
+remote-pci-obj-$(CONFIG_MPQEMU) += machine.o
diff --git a/remote/machine.c b/remote/machine.c
new file mode 100644
index 000..4ce197d
--- /dev/null
+++ b/remote/machine.c
@@ -0,0 +1,118 @@
+/*
+ * Machine for remote device
+ *
+ * Copyright 2019, Oracle and/or its affiliates.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR O

[Qemu-devel] [PULL v2 01/13] includes: remove stale [smp|max]_cpus externs

2019-09-03 Thread Eduardo Habkost
From: Alex Bennée 

Commit a5e0b3311 removed these in favour of querying machine
properties. Remove the extern declarations as well.

Signed-off-by: Alex Bennée 
Cc: Like Xu 
Message-Id: <20190711130546.18578-1-alex.ben...@linaro.org>
Reviewed-by: Richard Henderson 
Reviewed-by: Like Xu 
Fixes: a5e0b331193a ("vl.c: Replace smp global variables with smp machine 
properties")
Signed-off-by: Eduardo Habkost 
---
 include/sysemu/sysemu.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d2c38f611a..44f18eb739 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -42,8 +42,6 @@ extern const char *keyboard_layout;
 extern int win2k_install_hack;
 extern int alt_grab;
 extern int ctrl_grab;
-extern int smp_cpus;
-extern unsigned int max_cpus;
 extern int cursor_hide;
 extern int graphic_rotate;
 extern int no_quit;
-- 
2.21.0




[Qemu-devel] [RFC v3 PATCH 43/45] multi-process: prevent duplicate memory initialization in remote

2019-09-03 Thread Jagannathan Raman
When multiple controllers are configured in a remote process,
it's better for the memory to be managed by only one of the proxy
objects for that process, in order to conserve file descriptors. Added
"mem_int" flag for this purpose.

Signed-off-by: Elena Ufimtseva 
Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
---
 New patch in v3

 hw/proxy/qemu-proxy.c | 13 -
 include/hw/proxy/qemu-proxy.h |  1 +
 qdev-monitor.c|  2 +-
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index c812145..8b820cf 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -363,6 +363,13 @@ static void pci_proxy_write_config(PCIDevice *d, uint32_t 
addr, uint32_t val,
PCI_PROXY_DEV(d)->dev_id, CONF_WRITE);
 }
 
+static void pci_proxy_dev_inst_init(Object *obj)
+{
+PCIProxyDev *dev = PCI_PROXY_DEV(obj);
+
+dev->mem_init = false;
+}
+
 static void pci_proxy_dev_class_init(ObjectClass *klass, void *data)
 {
 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
@@ -377,6 +384,7 @@ static const TypeInfo pci_proxy_dev_type_info = {
 .name  = TYPE_PCI_PROXY_DEV,
 .parent= TYPE_PCI_DEVICE,
 .instance_size = sizeof(PCIProxyDev),
+.instance_init = pci_proxy_dev_inst_init,
 .abstract  = true,
 .class_size= sizeof(PCIProxyDevClass),
 .class_init= pci_proxy_dev_class_init,
@@ -483,7 +491,10 @@ static void init_proxy(PCIDevice *dev, char *command, bool 
need_spawn, Error **e
 proxy_link_init_channel(pdev->proxy_link, &pdev->proxy_link->mmio,
 pdev->mmio_sock);
 
-configure_memory_sync(pdev->sync, pdev->proxy_link);
+if (!pdev->mem_init) {
+pdev->mem_init = true;
+configure_memory_sync(pdev->sync, pdev->proxy_link);
+}
 }
 
 static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
diff --git a/include/hw/proxy/qemu-proxy.h b/include/hw/proxy/qemu-proxy.h
index d88fbd4..610695f 100644
--- a/include/hw/proxy/qemu-proxy.h
+++ b/include/hw/proxy/qemu-proxy.h
@@ -51,6 +51,7 @@ typedef struct PCIProxyDev {
 ProxyLinkState *proxy_link;
 
 RemoteMemSync *sync;
+bool mem_init;
 struct kvm_irqfd irqfd;
 
 EventNotifier intr;
diff --git a/qdev-monitor.c b/qdev-monitor.c
index f1065af..3b08e23 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -712,10 +712,10 @@ DeviceState *qdev_proxy_add(const char *rid, const char 
*id, char *bus,
 pdev->socket = old_pdev->socket;
 pdev->mmio_sock = old_pdev->mmio_sock;
 pdev->remote_pid = old_pdev->remote_pid;
+pdev->mem_init = true;
 } else {
 pdev->rsocket = managed ? rsocket : -1;
 pdev->socket = managed ? rsocket : -1;
-
 }
 pdev->managed = managed;
 
-- 
1.8.3.1




[Qemu-devel] [PULL v2 04/13] numa: move numa global variable have_numa_distance into MachineState

2019-09-03 Thread Eduardo Habkost
From: Tao Xu 

Move existing numa global have_numa_distance into NumaState.

Reviewed-by: Igor Mammedov 
Reviewed-by: Liu Jingqi 
Suggested-by: Igor Mammedov 
Suggested-by: Eduardo Habkost 
Signed-off-by: Tao Xu 
Message-Id: <20190809065731.9097-4-tao3...@intel.com>
Signed-off-by: Eduardo Habkost 
---
 include/sysemu/numa.h| 4 ++--
 hw/arm/sbsa-ref.c| 2 +-
 hw/arm/virt-acpi-build.c | 2 +-
 hw/arm/virt.c| 2 +-
 hw/core/numa.c   | 5 ++---
 hw/i386/acpi-build.c | 2 +-
 6 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h
index 1786e861d0..bfe04b514c 100644
--- a/include/sysemu/numa.h
+++ b/include/sysemu/numa.h
@@ -14,8 +14,6 @@ struct CPUArchId;
 #define NUMA_DISTANCE_MAX 254
 #define NUMA_DISTANCE_UNREACHABLE 255
 
-extern bool have_numa_distance;
-
 struct NodeInfo {
 uint64_t node_mem;
 struct HostMemoryBackend *node_memdev;
@@ -34,6 +32,8 @@ struct NumaState {
 /* Number of NUMA nodes */
 int num_nodes;
 
+/* Allow setting NUMA distance for different NUMA nodes */
+bool have_numa_distance;
 };
 typedef struct NumaState NumaState;
 
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index d15e5aebbd..7d7bb9fd96 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -160,7 +160,7 @@ static void create_fdt(SBSAMachineState *sms)
 qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
 qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
 
-if (have_numa_distance) {
+if (ms->numa_state->have_numa_distance) {
 int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
 uint32_t *matrix = g_malloc0(size);
 int idx, i, j;
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 9e6cfe65b5..b1deb76a53 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -798,7 +798,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables 
*tables)
 if (ms->numa_state->num_nodes > 0) {
 acpi_add_table(table_offsets, tables_blob);
 build_srat(tables_blob, tables->linker, vms);
-if (have_numa_distance) {
+if (ms->numa_state->have_numa_distance) {
 acpi_add_table(table_offsets, tables_blob);
 build_slit(tables_blob, tables->linker, ms);
 }
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 8d36b37f8e..414f7ecd02 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -236,7 +236,7 @@ static void create_fdt(VirtMachineState *vms)
 "clk24mhz");
 qemu_fdt_setprop_cell(fdt, "/apb-pclk", "phandle", vms->clock_phandle);
 
-if (have_numa_distance) {
+if (nb_numa_nodes > 0 && ms->numa_state->have_numa_distance) {
 int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
 uint32_t *matrix = g_malloc0(size);
 int idx, i, j;
diff --git a/hw/core/numa.c b/hw/core/numa.c
index 2712c78adb..4a7adc9b98 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -55,7 +55,6 @@ static int have_mem;
 static int max_numa_nodeid; /* Highest specified NUMA node ID, plus one.
  * For all nodes, nodeid < max_numa_nodeid
  */
-bool have_numa_distance;
 NodeInfo numa_info[MAX_NODES];
 
 
@@ -173,7 +172,7 @@ void parse_numa_distance(MachineState *ms, NumaDistOptions 
*dist, Error **errp)
 }
 
 numa_info[src].distance[dst] = val;
-have_numa_distance = true;
+ms->numa_state->have_numa_distance = true;
 }
 
 void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp)
@@ -446,7 +445,7 @@ void numa_complete_configuration(MachineState *ms)
  * asymmetric. In this case, the distances for both directions
  * of all node pairs are required.
  */
-if (have_numa_distance) {
+if (ms->numa_state->have_numa_distance) {
 /* Validate enough NUMA distance information was provided. */
 validate_numa_distance(ms);
 
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 3c5868322b..e54e571a75 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2694,7 +2694,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState 
*machine)
 if (pcms->numa_nodes) {
 acpi_add_table(table_offsets, tables_blob);
 build_srat(tables_blob, tables->linker, machine);
-if (have_numa_distance) {
+if (machine->numa_state->have_numa_distance) {
 acpi_add_table(table_offsets, tables_blob);
 build_slit(tables_blob, tables->linker, machine);
 }
-- 
2.21.0




[Qemu-devel] [RFC v3 PATCH 41/45] multi-process/mon: trim HMP command set for remote storage processes

2019-09-03 Thread Jagannathan Raman
Trim down the list of HMP commands available for storage class of
remote processes.

Signed-off-by: Elena Ufimtseva 
Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
---
 New patch in v3

 Makefile.objs  |   2 +
 Makefile.target|  14 +-
 hmp-scsi-commands-info.hx  | 167 
 hmp-scsi-commands.hx   | 384 +
 monitor/misc.c |  84 +-
 monitor/monitor-internal.h |  38 +
 qom/Makefile.objs  |   2 +-
 7 files changed, 651 insertions(+), 40 deletions(-)
 create mode 100644 hmp-scsi-commands-info.hx
 create mode 100644 hmp-scsi-commands.hx

diff --git a/Makefile.objs b/Makefile.objs
index 04af900..11cd7be 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -45,6 +45,8 @@ remote-pci-obj-$(CONFIG_MPQEMU) += iothread.o
 remote-lsi-obj-$(CONFIG_MPQEMU) += hw/
 remote-lsi-obj-$(CONFIG_MPQEMU) += ui/
 
+remote-lsi-obj-$(CONFIG_MPQEMU) += device-hotplug.o
+
 ###
 # crypto-obj-y is code used by both qemu system emulation and qemu-img
 
diff --git a/Makefile.target b/Makefile.target
index 0ca832f..00a4b85 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -210,6 +210,10 @@ endif
 generated-files-y += hmp-commands.h hmp-commands-info.h
 generated-files-y += config-devices.h
 
+ifdef CONFIG_MPQEMU
+generated-files-y += hmp-scsi-commands.h hmp-scsi-commands-info.h
+endif
+
 endif # CONFIG_SOFTMMU
 
 dummy := $(call unnest-vars,,obj-y)
@@ -294,10 +298,18 @@ hmp-commands.h: $(SRC_PATH)/hmp-commands.hx 
$(SRC_PATH)/scripts/hxtool
 hmp-commands-info.h: $(SRC_PATH)/hmp-commands-info.hx 
$(SRC_PATH)/scripts/hxtool
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > 
$@,"GEN","$(TARGET_DIR)$@")
 
+ifdef CONFIG_MPQEMU
+hmp-scsi-commands.h: $(SRC_PATH)/hmp-scsi-commands.hx 
$(SRC_PATH)/scripts/hxtool
+   $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > 
$@,"GEN","$(TARGET_DIR)$@")
+
+hmp-scsi-commands-info.h: $(SRC_PATH)/hmp-scsi-commands-info.hx 
$(SRC_PATH)/scripts/hxtool
+   $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > 
$@,"GEN","$(TARGET_DIR)$@")
+endif
+
 clean: clean-target
rm -f *.a *~ $(PROGS)
rm -f $(shell find . -name '*.[od]')
-   rm -f hmp-commands.h gdbstub-xml.c
+   rm -f hmp-commands.h gdbstub-xml.c hmp-scsi-commands.h 
hmp-scsi-commands-info.h
rm -f trace/generated-helpers.c trace/generated-helpers.c-timestamp
 ifdef CONFIG_TRACE_SYSTEMTAP
rm -f *.stp
diff --git a/hmp-scsi-commands-info.hx b/hmp-scsi-commands-info.hx
new file mode 100644
index 000..315a445
--- /dev/null
+++ b/hmp-scsi-commands-info.hx
@@ -0,0 +1,167 @@
+HXCOMM Use DEFHEADING() to define headings in both help text and texi
+HXCOMM Text between STEXI and ETEXI are copied to texi version and
+HXCOMM discarded from C version
+HXCOMM DEF(command, args, callback, arg_string, help) is used to construct
+HXCOMM monitor info commands
+HXCOMM HXCOMM can be used for comments, discarded from both texi and C
+
+STEXI
+@table @option
+@item info @var{subcommand}
+@findex info
+Show various information about the system state.
+@table @option
+ETEXI
+
+{
+.name   = "version",
+.args_type  = "",
+.params = "",
+.help   = "show the version of QEMU",
+.cmd= hmp_info_version,
+.flags  = "p",
+},
+
+STEXI
+@item info version
+@findex info version
+Show the version of QEMU.
+ETEXI
+
+{
+.name   = "chardev",
+.args_type  = "",
+.params = "",
+.help   = "show the character devices",
+.cmd= hmp_info_chardev,
+.flags  = "p",
+},
+
+STEXI
+@item info chardev
+@findex info chardev
+Show the character devices.
+ETEXI
+
+{
+.name   = "block",
+.args_type  = "nodes:-n,verbose:-v,device:B?",
+.params = "[-n] [-v] [device]",
+.help   = "show info of one block device or all block devices "
+  "(-n: show named nodes; -v: show details)",
+.cmd= hmp_info_block,
+},
+
+STEXI
+@item info block
+@findex info block
+Show info of one block device or all block devices.
+ETEXI
+
+{
+.name   = "blockstats",
+.args_type  = "",
+.params = "",
+.help   = "show block device statistics",
+.cmd= hmp_info_blockstats,
+},
+
+STEXI
+@item info blockstats
+@findex info blockstats
+Show block device statistics.
+ETEXI
+
+{
+.name   = "block-jobs",
+.args_type  = "",
+.params = "",
+.help   = "show progress of ongoing block device operations",
+.cmd= hmp_info_block_jobs,
+},
+
+STEXI
+@item info block-jobs
+@findex info block-jobs
+Show progress of ongoing block device operations.
+ETEXI
+
+{
+.name   = "history",
+

Re: [Qemu-devel] [Libguestfs] [PATCH 0/1] NBD protocol change to add fast zero support

2019-09-03 Thread Eric Blake
On 8/23/19 9:34 AM, Eric Blake wrote:
> See the cross-post cover letter for details:
> https://www.redhat.com/archives/libguestfs/2019-August/msg00322.html
> 
> Eric Blake (1):
>   protocol: Add NBD_CMD_FLAG_FAST_ZERO
> 
>  doc/proto.md | 50 +-
>  1 file changed, 49 insertions(+), 1 deletion(-)

I think we've had enough review time with no major objections to this.
Therefore, I've gone ahead and incorporated the wording changes that
were mentioned in discussion on this patch, as well as Rich's URI
specification, into the NBD project.  We can still amend the
specifications if any problems turn up.

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



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [RFC v3 PATCH 42/45] multi-process/mon: Initialize QMP module for remote processes

2019-09-03 Thread Jagannathan Raman
Signed-off-by: Elena Ufimtseva 
Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
---
 New patch in v3

 remote/remote-main.c | 11 +++
 remote/remote-opts.c | 10 ++
 2 files changed, 21 insertions(+)

diff --git a/remote/remote-main.c b/remote/remote-main.c
index a6ff338..41da405 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -68,6 +68,7 @@
 
 #include "monitor/monitor.h"
 #include "sysemu/reset.h"
+#include "vl.h"
 
 static ProxyLinkState *proxy_link;
 
@@ -562,6 +563,8 @@ int main(int argc, char *argv[], char **envp)
 
 module_call_init(MODULE_INIT_QOM);
 
+monitor_init_globals();
+
 bdrv_init_with_whitelist();
 
 if (qemu_init_main_loop(&err)) {
@@ -577,6 +580,8 @@ int main(int argc, char *argv[], char **envp)
 
 qemu_add_opts(&qemu_device_opts);
 qemu_add_opts(&qemu_drive_opts);
+qemu_add_opts(&qemu_chardev_opts);
+qemu_add_opts(&qemu_mon_opts);
 qemu_add_drive_opts(&qemu_legacy_drive_opts);
 qemu_add_drive_opts(&qemu_common_drive_opts);
 qemu_add_drive_opts(&qemu_drive_opts);
@@ -609,6 +614,12 @@ int main(int argc, char *argv[], char **envp)
 
 proxy_link_set_callback(proxy_link, process_msg);
 
+qemu_opts_foreach(qemu_find_opts("chardev"),
+  chardev_init_func, NULL, &error_fatal);
+
+qemu_opts_foreach(qemu_find_opts("mon"),
+  mon_init_func, NULL, &error_fatal);
+
 start_handler(proxy_link);
 
 return 0;
diff --git a/remote/remote-opts.c b/remote/remote-opts.c
index 416ff59..7ddfe5c 100644
--- a/remote/remote-opts.c
+++ b/remote/remote-opts.c
@@ -95,6 +95,16 @@ void parse_cmdline(int argc, char **argv, char **envp)
 exit(1);
 }
 break;
+case QEMU_OPTION_qmp:
+monitor_parse(optarg, "control", false);
+break;
+case QEMU_OPTION_monitor:
+if (!strncmp(optarg, "stdio", 5)) {
+warn_report("STDIO not supported in remote process");
+} else if (strncmp(optarg, "none", 4)) {
+monitor_parse(optarg, "readline", false);
+}
+break;
 default:
 break;
 }
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 40/45] multi-process/mon: Refactor monitor/chardev functions out of vl.c

2019-09-03 Thread Jagannathan Raman
Some of the initialization helper functions w.r.t monitor & chardev
in vl.c are also used by the remote process. Therefore, these functions
are refactored into a shared file that both QEMU & remote process
could use.

Signed-off-by: Elena Ufimtseva 
Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
---
 New patch in v3

 vl-parse.c | 92 ++
 vl.c   | 91 -
 vl.h   |  4 +++
 3 files changed, 96 insertions(+), 91 deletions(-)

diff --git a/vl-parse.c b/vl-parse.c
index d3716d1..bee904d 100644
--- a/vl-parse.c
+++ b/vl-parse.c
@@ -155,3 +155,95 @@ int device_init_func(void *opaque, QemuOpts *opts, Error 
**errp)
 object_unref(OBJECT(dev));
 return 0;
 }
+
+void monitor_parse(const char *optarg, const char *mode, bool pretty)
+{
+static int monitor_device_index;
+QemuOpts *opts;
+const char *p;
+char label[32];
+
+if (strstart(optarg, "chardev:", &p)) {
+snprintf(label, sizeof(label), "%s", p);
+} else {
+snprintf(label, sizeof(label), "compat_monitor%d",
+ monitor_device_index);
+opts = qemu_chr_parse_compat(label, optarg, true);
+if (!opts) {
+error_report("parse error: %s", optarg);
+exit(1);
+}
+}
+
+opts = qemu_opts_create(qemu_find_opts("mon"), label, 1, &error_fatal);
+qemu_opt_set(opts, "mode", mode, &error_abort);
+qemu_opt_set(opts, "chardev", label, &error_abort);
+if (!strcmp(mode, "control")) {
+qemu_opt_set_bool(opts, "pretty", pretty, &error_abort);
+} else {
+assert(pretty == false);
+}
+monitor_device_index++;
+}
+
+int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)
+{
+Chardev *chr;
+bool qmp;
+bool pretty = false;
+const char *chardev;
+const char *mode;
+
+mode = qemu_opt_get(opts, "mode");
+if (mode == NULL) {
+mode = "readline";
+}
+if (strcmp(mode, "readline") == 0) {
+qmp = false;
+} else if (strcmp(mode, "control") == 0) {
+qmp = true;
+} else {
+error_setg(errp, "unknown monitor mode \"%s\"", mode);
+return -1;
+}
+
+if (!qmp && qemu_opt_get(opts, "pretty")) {
+warn_report("'pretty' is deprecated for HMP monitors, it has no effect 
"
+"and will be removed in future versions");
+}
+if (qemu_opt_get_bool(opts, "pretty", 0)) {
+pretty = true;
+}
+
+chardev = qemu_opt_get(opts, "chardev");
+if (!chardev) {
+error_report("chardev is required");
+exit(1);
+}
+chr = qemu_chr_find(chardev);
+if (chr == NULL) {
+error_setg(errp, "chardev \"%s\" not found", chardev);
+return -1;
+}
+
+if (qmp) {
+monitor_init_qmp(chr, pretty);
+} else {
+monitor_init_hmp(chr, true);
+}
+return 0;
+}
+
+int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp)
+{
+Error *local_err = NULL;
+
+if (!qemu_chr_new_from_opts(opts, NULL, &local_err)) {
+if (local_err) {
+error_propagate(errp, local_err);
+return -1;
+}
+exit(0);
+}
+return 0;
+}
diff --git a/vl.c b/vl.c
index 08e9c09..3c03405 100644
--- a/vl.c
+++ b/vl.c
@@ -2264,19 +2264,6 @@ static int device_help_func(void *opaque, QemuOpts 
*opts, Error **errp)
 return qdev_device_help(opts);
 }
 
-static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp)
-{
-Error *local_err = NULL;
-
-if (!qemu_chr_new_from_opts(opts, NULL, &local_err)) {
-if (local_err) {
-error_propagate(errp, local_err);
-return -1;
-}
-exit(0);
-}
-return 0;
-}
 
 #ifdef CONFIG_VIRTFS
 static int fsdev_init_func(void *opaque, QemuOpts *opts, Error **errp)
@@ -2285,84 +2272,6 @@ static int fsdev_init_func(void *opaque, QemuOpts *opts, 
Error **errp)
 }
 #endif
 
-static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)
-{
-Chardev *chr;
-bool qmp;
-bool pretty = false;
-const char *chardev;
-const char *mode;
-
-mode = qemu_opt_get(opts, "mode");
-if (mode == NULL) {
-mode = "readline";
-}
-if (strcmp(mode, "readline") == 0) {
-qmp = false;
-} else if (strcmp(mode, "control") == 0) {
-qmp = true;
-} else {
-error_setg(errp, "unknown monitor mode \"%s\"", mode);
-return -1;
-}
-
-if (!qmp && qemu_opt_get(opts, "pretty")) {
-warn_report("'pretty' is deprecated for HMP monitors, it has no effect 
"
-"and will be removed in future versions");
-}
-if (qemu_opt_get_bool(opts, "pretty", 0)) {
-pretty = true;
-}
-
-chardev = qemu_opt_get(opts, "chardev");
-if (!chardev) {
-error_report("chardev is required");
-exit(1);
-}
-chr = qemu_chr_f

[Qemu-devel] [RFC v3 PATCH 45/45] multi-process: add configure and usage information

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
---
Changes in v3:
 - since the changes were made to use existing device/drive options,
the document was modified to reflect this.
---
 docs/qemu-multiprocess.txt | 86 ++
 1 file changed, 86 insertions(+)
 create mode 100644 docs/qemu-multiprocess.txt

diff --git a/docs/qemu-multiprocess.txt b/docs/qemu-multiprocess.txt
new file mode 100644
index 000..c29f4df
--- /dev/null
+++ b/docs/qemu-multiprocess.txt
@@ -0,0 +1,86 @@
+Multi-process QEMU
+==
+
+This document describes how to configure and use multi-process qemu.
+For the design document refer to docs/devel/qemu-multiprocess.
+
+1) Configuration
+
+
+To enable support for multi-process add --enable-mpqemu
+to the list of options for the "configure" script.
+
+
+2) Usage
+
+
+To start qemu with devices intended to run in a separate emulation
+process without libvirtd support, the following should be used on QEMU
+command line. As of now, we only support the emulation of lsi53c895a
+in a separate process
+
+* Since parts of the RAM are shared between QEMU & remote process, a
+  memory-backend-file is required to facilitate this, as follows:
+
+  -object memory-backend-file,id=mem,mem-path=/dev/shm/,size=4096M,share=on
+
+* The devices to be emulated in the separate process are defined as
+  before with addition of "rid" suboption that serves as a remote group
+  identificator.
+
+  -device ,rid="remote process id"
+
+  For exmaple, for non multi-process qemu:
+-device lsi53c895a,id=scsi0 device
+-device scsi-hd,drive=drive0,bus=scsi0.0,scsi-id=0
+-drive id=drive0,file=data-disk.img
+
+  and for multi-process qemu and no libvirt
+  support (i.e. QEMU forks child processes):
+-device lsi53c895a,id=scsi0,rid=0
+-device scsi-hd,drive=drive0,bus=scsi0.0,scsi-id=0,rid="0"
+
+* The command-line options for the remote process is added to the "command"
+  suboption of the newly added "-remote" option. 
+
+   -remote [socket],rid=,command="..."
+
+  The drives to be emulated by the remote process are specified as part of
+  this command sub-option. The device to be used to connect to the monitor
+  is also specified as part of this suboption.
+
+  For example, the following option adds a drive and monitor to the remote
+  process:
+  -remote rid=0,command="-drive id=drive0,,file=data-disk.img -monitor 
unix:/home/qmp-sock,,server,,nowait"
+
+  Note: There's an issue with this "command" subtion which we are in the
+  process of fixing. To work around this issue, it requires additional
+  "comma" characters as illustrated above, and in the example below.
+
+* Example QEMU command-line to launch lsi53c895a in a remote process
+
+  #/bin/sh
+  qemu-system-x86_64 \
+  -name "OL7.4" \
+  -machine q35,accel=kvm \
+  -smp sockets=1,cores=1,threads=1 \
+  -cpu host \
+  -m 2048 \
+  -object memory-backend-file,id=mem,mem-path=/dev/shm/,size=2G,share=on \
+  -numa node,memdev=mem \
+  -device virtio-scsi-pci,id=virtio_scsi_pci0 \
+  -drive id=drive_image1,if=none,format=raw,file=/root/ol7.qcow2 \
+  -device scsi-hd,id=image1,drive=drive_image1,bus=virtio_scsi_pci0.0 \
+  -boot d \
+  -monitor stdio \
+  -vnc :0 \
+  -device lsi53c895a,id=lsi0,remote,rid=8,command="qemu-scsi-dev" \
+  -device 
scsi-hd,id=drive2,drive=drive_image2,bus=lsi0.0,scsi-id=0,remote,rid=8,command="qemu-scsi-dev"\
+  -remote rid=8,command="-drive 
id=drive_image2,,file=/root/remote-process-disk.img -monitor 
unix:/home/qmp-sock,,server,,nowait"
+
+  We could connect to the monitor using the following command:
+  socat /home/qmp-sock stdio
+
+  After hotplugging disks to the remote process, please execute the
+  following command in the guest to refresh the list of storage devices:
+  rescan_scsi_bus.sh -a
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 39/45] multi-process/mon: build system for QMP module in remote process

2019-09-03 Thread Jagannathan Raman
Makefile changes necessary to compile QMP module for the remote process

Signed-off-by: Elena Ufimtseva 
Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
---
 New patch in v3

 Makefile.objs |  7 +++
 Makefile.target   | 20 +++-
 hw/core/Makefile.objs |  1 +
 monitor/Makefile.objs |  3 +++
 qapi/Makefile.objs|  2 ++
 qom/Makefile.objs |  1 +
 ui/Makefile.objs  |  2 ++
 7 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/Makefile.objs b/Makefile.objs
index f817cf6..04af900 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -30,6 +30,7 @@ remote-pci-obj-$(CONFIG_MPQEMU) += backends/
 remote-pci-obj-$(CONFIG_MPQEMU) += block/
 remote-pci-obj-$(CONFIG_MPQEMU) += migration/
 remote-pci-obj-$(CONFIG_MPQEMU) += remote/
+remote-pci-obj-$(CONFIG_MPQEMU) += monitor/
 
 remote-pci-obj-$(CONFIG_MPQEMU) += cpus-common.o
 remote-pci-obj-$(CONFIG_MPQEMU) += dma-helpers.o
@@ -42,6 +43,7 @@ remote-pci-obj-$(CONFIG_MPQEMU) += iothread.o
 # remote-lsi-obj-y is code used to implement remote LSI device
 
 remote-lsi-obj-$(CONFIG_MPQEMU) += hw/
+remote-lsi-obj-$(CONFIG_MPQEMU) += ui/
 
 ###
 # crypto-obj-y is code used by both qemu system emulation and qemu-img
@@ -112,6 +114,11 @@ common-obj-y += vl-parse.o
 common-obj-y += qapi/
 endif
 
+remote-pci-obj-$(CONFIG_MPQEMU) += qapi/
+remote-pci-obj-$(CONFIG_MPQEMU) += blockdev-nbd.o
+remote-pci-obj-$(CONFIG_MPQEMU) += job-qmp.o
+remote-pci-obj-$(CONFIG_MPQEMU) += balloon.o
+
 ###
 # Target-independent parts used in system and user emulation
 common-obj-y += cpus-common.o
diff --git a/Makefile.target b/Makefile.target
index ac545fc..0ca832f 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -135,11 +135,29 @@ remote-pci-tgt-obj-$(CONFIG_MPQEMU) += 
accel/stubs/hax-stub.o
 remote-pci-tgt-obj-$(CONFIG_MPQEMU) += accel/stubs/whpx-stub.o
 remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/vl-stub.o
 remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/net-stub.o
-remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/monitor.o
 remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/replay.o
 remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/xen-mapcache.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/migration.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/ui-stub.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/gdbstub.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/qapi-target.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/qapi-misc.o
 
 remote-pci-tgt-obj-$(CONFIG_MPQEMU) += remote/memory.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += arch_init.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += monitor/misc.o
+
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += qapi/qapi-introspect.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += qapi/qapi-commands-block-core.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += qapi/qapi-commands-block.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += qapi/qapi-commands-misc.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += qapi/qapi-commands.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += qapi/qapi-commands-machine-target.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += qapi/qapi-commands-misc-target.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += qapi/qapi-visit-machine-target.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += qapi/qapi-visit-misc-target.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += qapi/qapi-types-machine-target.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += qapi/qapi-types-misc-target.o
 
 #
 # Linux user emulator target
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index 0229f4b..d2c5658 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -42,3 +42,4 @@ remote-pci-obj-$(CONFIG_MPQEMU) += nmi.o
 remote-pci-obj-$(CONFIG_MPQEMU) += qdev-properties-system.o
 remote-pci-obj-$(CONFIG_MPQEMU) += qdev-fw.o
 remote-pci-obj-$(CONFIG_MPQEMU) += numa.o
+remote-pci-obj-$(CONFIG_MPQEMU) += machine-qmp-cmds.o
diff --git a/monitor/Makefile.objs b/monitor/Makefile.objs
index e91a858..11c42ec 100644
--- a/monitor/Makefile.objs
+++ b/monitor/Makefile.objs
@@ -1,3 +1,6 @@
 obj-y += misc.o
 common-obj-y += monitor.o qmp.o hmp.o
 common-obj-y += qmp-cmds.o hmp-cmds.o
+
+remote-pci-obj-$(CONFIG_MPQEMU) += monitor.o qmp.o hmp.o
+remote-pci-obj-$(CONFIG_MPQEMU) += qmp-cmds.o hmp-cmds.o
diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs
index c5a29e8..972bdb2 100644
--- a/qapi/Makefile.objs
+++ b/qapi/Makefile.objs
@@ -30,3 +30,5 @@ obj-y += $(QAPI_TARGET_MODULES:%=qapi-events-%.o)
 obj-y += qapi-events.o
 obj-y += $(QAPI_TARGET_MODULES:%=qapi-commands-%.o)
 obj-y += qapi-commands.o
+
+remote-pci-obj-$(CONFIG_MPQEMU) += $(QAPI_COMMON_MODULES:%=qapi-commands-%.o)
diff --git a/qom/Makefile.objs b/qom/Makefile.objs
index 05da824..e42ea7a 100644
--- a/qom/Makefile.objs
+++ b/qom/Makefile.objs
@@ -7,3 +7,4 @@ common-obj-$(CONFIG_SOFTMMU) += qom-hmp-cmds.o qom-qmp-cmds.o
 remote-pci-obj-$(CONFIG_MPQEM

[Qemu-devel] [RFC v3 PATCH 36/45] multi-process: Use separate MMIO communication channel

2019-09-03 Thread Jagannathan Raman
Using a separate communication channel for MMIO helps
with improving Performance

Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
---
 New patch in v3

 hw/proxy/qemu-proxy.c | 38 ++
 include/hw/proxy/qemu-proxy.h |  1 +
 include/io/proxy-link.h   |  7 +++
 io/proxy-link.c   |  2 ++
 qdev-monitor.c|  1 +
 remote/remote-main.c  | 20 ++--
 6 files changed, 51 insertions(+), 18 deletions(-)

diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index 699a0b1..db9a208 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -205,20 +205,22 @@ static int make_argv(char *command_str, char **argv, int 
argc)
 int remote_spawn(PCIProxyDev *pdev, const char *command, Error **errp)
 {
 pid_t rpid;
-int fd[2] = {-1, -1};
+int fd[2], mmio[2];
 Error *local_error = NULL;
 char *argv[64];
 int argc = 0, _argc;
 char *sfd;
 char *exec_dir;
 int rc = -EINVAL;
+struct timeval timeout = {.tv_sec = 10, .tv_usec = 0};
 
 if (pdev->managed) {
 /* Child is forked by external program (such as libvirt). */
 return rc;
 }
 
-if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) {
+if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) ||
+socketpair(AF_UNIX, SOCK_STREAM, 0, mmio)) {
 error_setg(errp, "Unable to create unix socket.");
 return rc;
 }
@@ -226,6 +228,8 @@ int remote_spawn(PCIProxyDev *pdev, const char *command, 
Error **errp)
 argc = add_argv(exec_dir, argv, argc);
 sfd = g_strdup_printf("%d", fd[1]);
 argc = add_argv(sfd, argv, argc);
+sfd = g_strdup_printf("%d", mmio[1]);
+argc = add_argv(sfd, argv, argc);
 _argc = argc;
 argc = make_argv((char *)command, argv, argc);
 
@@ -235,22 +239,32 @@ int remote_spawn(PCIProxyDev *pdev, const char *command, 
Error **errp)
 if (rpid == -1) {
 error_setg(errp, "Unable to spawn emulation program.");
 close(fd[0]);
+close(mmio[0]);
 goto fail;
 }
 
 if (rpid == 0) {
 close(fd[0]);
+close(mmio[0]);
 execvp(argv[0], (char *const *)argv);
 exit(1);
 }
 pdev->remote_pid = rpid;
 pdev->rsocket = fd[1];
 pdev->socket = fd[0];
+pdev->mmio_sock = mmio[0];
+
+if (setsockopt(mmio[0], SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
+   sizeof(timeout)) < 0) {
+error_setg(errp, "Unable to set timeout for socket");
+goto fail;
+}
 
 rc = 0;
 
 fail:
 close(fd[1]);
+close(mmio[1]);
 
 for (int i = 0; i < _argc; i++) {
 g_free(argv[i]);
@@ -466,6 +480,9 @@ static void init_proxy(PCIDevice *dev, char *command, bool 
need_spawn, Error **e
 proxy_link_init_channel(pdev->proxy_link, &pdev->proxy_link->com,
 pdev->socket);
 
+proxy_link_init_channel(pdev->proxy_link, &pdev->proxy_link->mmio,
+pdev->mmio_sock);
+
 configure_memory_sync(pdev->sync, pdev->proxy_link);
 }
 
@@ -514,8 +531,7 @@ static void send_bar_access_msg(PCIProxyDev *dev, 
MemoryRegion *mr,
 unsigned size, bool memory)
 {
 ProxyLinkState *proxy_link;
-ProcMsg msg;
-int wait;
+ProcMsg msg, ret;
 
 proxy_link = dev->proxy_link;
 
@@ -531,11 +547,7 @@ static void send_bar_access_msg(PCIProxyDev *dev, 
MemoryRegion *mr,
 msg.cmd = BAR_WRITE;
 msg.data1.bar_access.val = *val;
 } else {
-wait = GET_REMOTE_WAIT;
-
 msg.cmd = BAR_READ;
-msg.num_fds = 1;
-msg.fds[0] = wait;
 }
 
 if (dev->dev_id) {
@@ -546,17 +558,19 @@ static void send_bar_access_msg(PCIProxyDev *dev, 
MemoryRegion *mr,
 msg.size_id = 0;
 }
 
-proxy_proc_send(proxy_link, &msg, proxy_link->com);
+proxy_proc_send(proxy_link, &msg, proxy_link->mmio);
 
-if (!write) {
-*val = wait_for_remote(wait);
-PUT_REMOTE_WAIT(wait);
+if (write) {
+return;
 }
 
 if (msg.id) {
 free(msg.id);
 }
 
+proxy_proc_recv(proxy_link, &ret, proxy_link->mmio);
+
+*val = ret.data1.mmio_ret.val;
 }
 
 void proxy_default_bar_write(PCIProxyDev *dev, MemoryRegion *mr, hwaddr addr,
diff --git a/include/hw/proxy/qemu-proxy.h b/include/hw/proxy/qemu-proxy.h
index fb408cf..a03c6cc 100644
--- a/include/hw/proxy/qemu-proxy.h
+++ b/include/hw/proxy/qemu-proxy.h
@@ -59,6 +59,7 @@ typedef struct PCIProxyDev {
 pid_t remote_pid;
 int rsocket;
 int socket;
+int mmio_sock;
 
 char *rid;
 
diff --git a/include/io/proxy-link.h b/include/io/proxy-link.h
index ae98eac..32b2c1a 100644
--- a/include/io/proxy-link.h
+++ b/include/io/proxy-link.h
@@ -75,6 +75,7 @@ typedef enum {
 DEVICE_ADD,
 DEVICE_DEL,
 PROXY_PING,
+MMIO_RETURN,
 MAX,
 } proc_cmd_t;
 
@@ -108,6 +109,10 @@ typedef struct {
 } set_irqfd_msg_t;

[Qemu-devel] [RFC v3 PATCH 44/45] multi-process: add the concept description to docs/devel/qemu-multiprocess

2019-09-03 Thread Jagannathan Raman
From: John G Johnson 

Signed-off-by: John G Johnson 
Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
---
 v2 -> v3:
   - Updated with latest design of this project

 docs/devel/qemu-multiprocess.txt | 627 +++
 1 file changed, 627 insertions(+)
 create mode 100644 docs/devel/qemu-multiprocess.txt

diff --git a/docs/devel/qemu-multiprocess.txt b/docs/devel/qemu-multiprocess.txt
new file mode 100644
index 000..5b94c8d
--- /dev/null
+++ b/docs/devel/qemu-multiprocess.txt
@@ -0,0 +1,627 @@
+Disaggregating QEMU
+
+This document describes implementation details of multi-process
+qemu.
+
+QEMU can be broadly described as providing three main services. One is a
+VM control point, where VMs can be created, migrated, re-configured, and
+destroyed. A second is to emulate the CPU instructions within the VM,
+often accelerated by HW virtualization features such as Intel’s VT
+extensions. Finally, it provides IO services to the VM by emulating HW
+IO devices, such as disk and network devices.
+
+A disaggregated QEMU
+
+A disaggregated QEMU involves separating QEMU services into separate
+host processes. Each of these processes can be given only the privileges
+it needs to provide its service, e.g., a disk service could be given
+access only the the disk images it provides, and not be allowed to
+access other files, or any network devices. An attacker who compromised
+this service would not be able to use this exploit to access files or
+devices beyond what the disk service was given access to.
+
+A QEMU control process would remain, but in disaggregated mode, it would
+be a control point that executes the processes needed to support the VM
+being created, but have no direct interfaces to the VM. During VM
+execution, it would still provide the user interface to hot-plug devices
+or live migrate the VM.
+
+A first step in creating a disaggregated QEMU is to separate IO services
+from the main QEMU program, which would continue to provide CPU
+emulation. i.e., the control process would also be the CPU emulation
+process. In a later phase, CPU emulation could be separated from the
+control process.
+
+
+Disaggregating IO services
+
+Disaggregating IO services is a good place to begin QEMU disaggregating
+for a couple of reasons. One is the sheer number of IO devices QEMU can
+emulate provides a large surface of interfaces which could potentially
+be exploited, and, indeed, have been a source of exploits in the past.
+Another is the modular nature of QEMU device emulation code provides
+interface points where the QEMU functions that perform device emulation
+can be separated from the QEMU functions that manage the emulation of
+guest CPU instructions.
+
+QEMU device emulation
+
+QEMU uses a object oriented SW architecture for device emulation code.
+Configured objects are all compiled into the QEMU binary, then objects
+are instantiated by name when used by the guest VM. For example, the
+code to emulate a device named “foo” is always present in QEMU, but its
+instantiation code is only run when the device is included in the target
+VM. (e.g., via the QEMU command line as _-device foo_)
+
+The object model is hierarchical, so device emulation code names its
+parent object (such as “pci-device” for a PCI device) and QEMU will
+instantiate a parent object before calling the device’s instantiation
+code.
+
+Current separation models
+
+In order to separate the device emulation code from the CPU emulation
+code, the device object code must run in a different process. There are
+a couple of existing QEMU features that can run emulation code
+separately from the main QEMU process. These are examined below.
+
+vhost user model
+
+Virtio guest device drivers can be connected to vhost user applications
+in order to perform their IO operations. This model uses special virtio
+device drivers in the guest and vhost user device objects in QEMU, but
+once the QEMU vhost user code has configured the vhost user application,
+mission-mode IO is performed by the application. The vhost user
+application is a daemon process that can be contacted via a known UNIX
+domain socket.
+
+vhost socket
+
+As mentioned above, one of the tasks of the vhost device object within
+QEMU is to contact the vhost application and send it configuration
+information about this device instance. As part of the configuration
+process, the application can also be sent other file descriptors over
+the socket, which then can be used by the vhost user application in
+various ways, some of which are described below.
+
+vhost MMIO store acceleration
+
+VMs are often run using HW virtualization features via the KVM kernel
+driver. This driver allows QEMU to accelerate the emulation of guest CPU
+instructions by running the guest in a virtual HW mode. When the guest
+executes instructions that cannot be executed by virtual HW mode,
+execution returns to the KVM driver so it can inform QEMU to emulate the
+instructions

[Qemu-devel] [RFC v3 PATCH 31/45] multi-process: add remote options parser

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
---
 New patch in v3

 vl.c | 117 +++
 1 file changed, 117 insertions(+)

diff --git a/vl.c b/vl.c
index dc2558c..08e9c09 100644
--- a/vl.c
+++ b/vl.c
@@ -279,6 +279,28 @@ static QemuOptsList qemu_option_rom_opts = {
 },
 };
 
+static QemuOptsList qemu_remote_opts = {
+.name = "remote",
+.head = QTAILQ_HEAD_INITIALIZER(qemu_remote_opts.head),
+.desc = {
+{
+.name = "rid",
+.type = QEMU_OPT_NUMBER,
+.help = "id of the remote process"
+},{
+.name = "socket",
+.type = QEMU_OPT_NUMBER,
+.help = "Socket for remote",
+},{
+.name = "command",
+.type = QEMU_OPT_STRING,
+.help = "command to run",
+},
+{ /* end of list */ }
+},
+};
+
+
 static QemuOptsList qemu_machine_opts = {
 .name = "machine",
 .implied_opt_name = "type",
@@ -346,6 +368,87 @@ static QemuOptsList qemu_boot_opts = {
 },
 };
 
+#if defined(CONFIG_MPQEMU)
+static int device_remote_add(void *opaque, QemuOpts *opts, Error **errp)
+{
+unsigned int rid = *(unsigned int *)opaque;
+const char *opt_rid = NULL;
+struct remote_process *p = NULL;;
+
+opt_rid = qemu_opt_get(opts, "rid");
+if (!opt_rid) {
+return 0;
+}
+
+p = get_remote_process_rid(rid);
+if (!p) {
+return -EINVAL;
+}
+
+if (atoi(opt_rid) == rid) {
+qemu_opt_set(opts, "command", p->command, errp);
+rdevice_init_func(opaque, opts, errp);
+qemu_opts_del(opts);
+}
+return 0;
+}
+
+static int parse_remote(void *opaque, QemuOpts *opts, Error **errp)
+{
+int rid;
+int socket;
+char  *c_sock;
+const char *command = NULL;
+struct remote_process r_proc;
+
+rid = atoi(qemu_opt_get(opts, "rid"));
+if (rid < 0) {
+error_setg(errp, "rid is required.");
+return -1;
+}
+if (get_remote_process_rid(rid)) {
+error_setg(errp, "There is already process with rid %d", rid);
+goto cont_devices;
+}
+
+c_sock = (char *)qemu_opt_get(opts, "socket");
+if (c_sock) {
+socket = atoi(c_sock);
+} else {
+socket = -1;
+}
+
+command = qemu_opt_get(opts, "command");
+
+if (socket <= STDERR_FILENO && socket != -1) {
+socket = -1;
+}
+
+if (!command && socket < 0) {
+error_setg(errp, "No correct  socket or command defined for remote.");
+return -1;
+}
+
+if (rid < 0) {
+error_setg(errp, "id option is required and must be non-negative");
+return -1;
+}
+r_proc.rid = rid;
+r_proc.socket = socket;
+r_proc.command = g_strdup(command);
+remote_process_register(&r_proc);
+
+ cont_devices:
+if (qemu_opts_foreach(qemu_find_opts("device"), device_remote_add,
+  &rid, NULL)) {
+error_setg(errp, "Could not process some of the remote devices.");
+}
+
+return 0;
+}
+
+#endif
+
 static QemuOptsList qemu_add_fd_opts = {
 .name = "add-fd",
 .head = QTAILQ_HEAD_INITIALIZER(qemu_add_fd_opts.head),
@@ -2861,6 +2964,7 @@ int main(int argc, char **argv, char **envp)
 qemu_add_opts(&qemu_icount_opts);
 qemu_add_opts(&qemu_semihosting_config_opts);
 qemu_add_opts(&qemu_fw_cfg_opts);
+qemu_add_opts(&qemu_remote_opts);
 module_call_init(MODULE_INIT_OPTS);
 
 runstate_init();
@@ -3697,6 +3801,14 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 #endif
 break;
+case QEMU_OPTION_remote:
+opts = qemu_opts_parse_noisily(qemu_find_opts("remote"),
+   optarg, false);
+if (!opts) {
+exit(1);
+}
+break;
+
 case QEMU_OPTION_object:
 opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
optarg, true);
@@ -4297,6 +4409,11 @@ int main(int argc, char **argv, char **envp)
 qemu_opts_foreach(qemu_find_opts("device"),
   device_init_func, NULL, &error_fatal);
 
+#ifdef CONFIG_MPQEMU
+qemu_opts_foreach(qemu_find_opts("remote"),
+  parse_remote, NULL, &error_fatal);
+#endif
+
 cpu_synchronize_all_post_init();
 
 rom_reset_order_override();
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 38/45] multi-process/mon: stub functions to enable QMP module for remote process

2019-09-03 Thread Jagannathan Raman
QMP module doesn't need some functions to run independently on the
remote processes. However, these functions are necessary for
compilation. Therefore, these functions are stub'ed out. The
stub functions raise an assert if QEMU is built in debug mode
(--enable-debug).

Signed-off-by: Elena Ufimtseva 
Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
---
 New patch in v3

 accel/stubs/tcg-stub.c |  10 +++
 configure  |   4 ++
 include/qemu-common.h  |   8 +++
 stubs/gdbstub.c|  21 +++
 stubs/migration.c  | 162 +
 stubs/monitor.c|  32 ++
 stubs/net-stub.c   |  69 +
 stubs/qapi-misc.c  |  41 +
 stubs/qapi-target.c|  49 +++
 stubs/ui-stub.c| 130 +++
 stubs/vl-stub.c|  92 
 11 files changed, 618 insertions(+)
 create mode 100644 stubs/migration.c
 create mode 100644 stubs/qapi-misc.c
 create mode 100644 stubs/qapi-target.c
 create mode 100644 stubs/ui-stub.c

diff --git a/accel/stubs/tcg-stub.c b/accel/stubs/tcg-stub.c
index 52722c7..37e035b 100644
--- a/accel/stubs/tcg-stub.c
+++ b/accel/stubs/tcg-stub.c
@@ -109,3 +109,13 @@ page_collection_lock(tb_page_addr_t start, tb_page_addr_t 
end)
 void page_collection_unlock(struct page_collection *set)
 {
 }
+
+void dump_exec_info(void)
+{
+qemu_debug_assert(0);
+}
+
+void dump_opcount_info(void)
+{
+qemu_debug_assert(0);
+}
diff --git a/configure b/configure
index b467441..5ee2438 100755
--- a/configure
+++ b/configure
@@ -7290,6 +7290,10 @@ if test "$mpqemu" = "yes" ; then
   echo "CONFIG_MPQEMU=y" >> $config_host_mak
 fi
 
+if test "$debug" = "yes" ; then
+  echo "CONFIG_DEBUG=y" >> $config_host_mak
+fi
+
 if test "$bochs" = "yes" ; then
   echo "CONFIG_BOCHS=y" >> $config_host_mak
 fi
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 0235cd3..9f33af3 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -10,6 +10,8 @@
 #ifndef QEMU_COMMON_H
 #define QEMU_COMMON_H
 
+#include 
+
 #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
 
 /* Copyright string for -version arguments, About dialogs, etc */
@@ -130,4 +132,10 @@ void page_size_init(void);
  * returned. */
 bool dump_in_progress(void);
 
+#ifdef CONFIG_DEBUG
+#define qemu_debug_assert(x) assert(x)
+#else
+#define qemu_debug_assert(x)
+#endif
+
 #endif
diff --git a/stubs/gdbstub.c b/stubs/gdbstub.c
index 2b7aee5..28c574a 100644
--- a/stubs/gdbstub.c
+++ b/stubs/gdbstub.c
@@ -1,6 +1,27 @@
 #include "qemu/osdep.h"
+#include "qemu-common.h"
 #include "exec/gdbstub.h"   /* xml_builtin */
 
 const char *const xml_builtin[][2] = {
   { NULL, NULL }
 };
+
+#ifdef CONFIG_USER_ONLY
+
+int gdbserver_start(int port)
+{
+qemu_debug_assert(0);
+
+return -ENOSYS;
+}
+
+#else
+
+int gdbserver_start(const char *device)
+{
+qemu_debug_assert(0);
+
+return -ENOSYS;
+}
+
+#endif
diff --git a/stubs/migration.c b/stubs/migration.c
new file mode 100644
index 000..28ccf80
--- /dev/null
+++ b/stubs/migration.c
@@ -0,0 +1,162 @@
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+
+#include "migration/misc.h"
+#include "migration/snapshot.h"
+#include "qapi/qapi-types-migration.h"
+#include "qapi/qapi-commands-migration.h"
+#include "qapi/qapi-types-net.h"
+
+MigrationInfo *qmp_query_migrate(Error **errp)
+{
+qemu_debug_assert(0);
+
+return NULL;
+}
+
+void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
+  Error **errp)
+{
+qemu_debug_assert(0);
+}
+
+MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
+{
+qemu_debug_assert(0);
+
+return NULL;
+}
+
+void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
+{
+qemu_debug_assert(0);
+}
+
+MigrationParameters *qmp_query_migrate_parameters(Error **errp)
+{
+qemu_debug_assert(0);
+
+return NULL;
+}
+
+void qmp_migrate_start_postcopy(Error **errp)
+{
+qemu_debug_assert(0);
+}
+
+void qmp_migrate_cancel(Error **errp)
+{
+qemu_debug_assert(0);
+}
+
+void qmp_migrate_continue(MigrationStatus state, Error **errp)
+{
+qemu_debug_assert(0);
+}
+
+void qmp_migrate_set_downtime(double value, Error **errp)
+{
+qemu_debug_assert(0);
+}
+
+void qmp_migrate_set_speed(int64_t value, Error **errp)
+{
+qemu_debug_assert(0);
+}
+
+void qmp_migrate_set_cache_size(int64_t value, Error **errp)
+{
+qemu_debug_assert(0);
+}
+
+int64_t qmp_query_migrate_cache_size(Error **errp)
+{
+qemu_debug_assert(0);
+
+return 0;
+}
+
+void qmp_migrate(const char *uri, bool has_blk, bool blk,
+ bool has_inc, bool inc, bool has_detach, bool detach,
+ bool has_resume, bool resume, Error **errp)
+{
+qemu_debug_assert(0);
+}
+
+void qmp_migrate_incoming(const char *uri, Error **errp)
+{
+qemu_debug_assert(0);
+}
+
+v

[Qemu-devel] [RFC v3 PATCH 28/45] multi-process: Introduce build flags to separate remote process code

2019-09-03 Thread Jagannathan Raman
Introduce SCSI_PROCESS & REMOTE_PROCESS build flags to separate
code that applies only to remote processes.

Signed-off-by: Elena Ufimtseva 
Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
---
 New patch in v3

 Makefile.target | 4 
 rules.mak   | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/Makefile.target b/Makefile.target
index a0c00c6..ac545fc 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -256,6 +256,10 @@ ifdef CONFIG_DARWIN
$(call quiet-command,SetFile -a C $@,"SETFILE","$(TARGET_DIR)$@")
 endif
 
+ifdef CONFIG_MPQEMU
+$(SCSI_DEV_BUILD): REMOTE_FLAGS = -DREMOTE_PROCESS -DSCSI_PROCESS
+endif
+
 $(SCSI_DEV_BUILD): $(all-remote-lsi-obj-y) $(COMMON_LDADDS)
$(call LINK, $(filter-out %.mak, $^))
 ifdef CONFIG_DARWIN
diff --git a/rules.mak b/rules.mak
index 967295d..22e0c36 100644
--- a/rules.mak
+++ b/rules.mak
@@ -67,7 +67,7 @@ expand-objs = $(strip $(sort $(filter %.o,$1)) \
 
 %.o: %.c
$(call quiet-command,$(CC) $(QEMU_LOCAL_INCLUDES) $(QEMU_INCLUDES) \
-  $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) \
+  $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) 
$(REMOTE_FLAGS) \
   -c -o $@ $<,"CC","$(TARGET_DIR)$@")
 %.o: %.rc
$(call quiet-command,$(WINDRES) -I. -o $@ $<,"RC","$(TARGET_DIR)$@")
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 32/45] multi-process: add parse_cmdline in remote process

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
---
 New patch in v3

 remote/Makefile.objs |   1 +
 remote/remote-main.c |  11 +
 remote/remote-opts.c | 113 +++
 remote/remote-opts.h |  31 ++
 4 files changed, 156 insertions(+)
 create mode 100644 remote/remote-opts.c
 create mode 100644 remote/remote-opts.h

diff --git a/remote/Makefile.objs b/remote/Makefile.objs
index c1349ad..a677fce 100644
--- a/remote/Makefile.objs
+++ b/remote/Makefile.objs
@@ -1,4 +1,5 @@
 remote-pci-obj-$(CONFIG_MPQEMU) += remote-main.o
+remote-pci-obj-$(CONFIG_MPQEMU) += remote-opts.o
 remote-pci-obj-$(CONFIG_MPQEMU) += pcihost.o
 remote-pci-obj-$(CONFIG_MPQEMU) += machine.o
 remote-pci-obj-$(CONFIG_MPQEMU) += iohub.o
diff --git a/remote/remote-main.c b/remote/remote-main.c
index 0c0e085..416b8a1 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -64,6 +64,7 @@
 #include "qapi/qmp/qlist.h"
 #include "qemu/log.h"
 #include "qemu/cutils.h"
+#include "remote-opts.h"
 
 static ProxyLinkState *proxy_link;
 PCIDevice *remote_pci_dev;
@@ -468,6 +469,13 @@ int main(int argc, char *argv[])
 
 current_machine = MACHINE(REMOTE_MACHINE(object_new(TYPE_REMOTE_MACHINE)));
 
+qemu_add_opts(&qemu_device_opts);
+qemu_add_opts(&qemu_drive_opts);
+qemu_add_drive_opts(&qemu_legacy_drive_opts);
+qemu_add_drive_opts(&qemu_common_drive_opts);
+qemu_add_drive_opts(&qemu_drive_opts);
+qemu_add_drive_opts(&bdrv_runtime_opts);
+
 proxy_link = proxy_link_create();
 if (!proxy_link) {
 printf("Could not create proxy link\n");
@@ -481,6 +489,9 @@ int main(int argc, char *argv[])
 }
 
 proxy_link_init_channel(proxy_link, &proxy_link->com, fd);
+
+parse_cmdline(argc - 2, argv + 2, NULL);
+
 proxy_link_set_callback(proxy_link, process_msg);
 
 start_handler(proxy_link);
diff --git a/remote/remote-opts.c b/remote/remote-opts.c
new file mode 100644
index 000..416ff59
--- /dev/null
+++ b/remote/remote-opts.c
@@ -0,0 +1,113 @@
+/*
+ * Remote device initialization
+ *
+ * Copyright 2019, Oracle and/or its affiliates.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu-common.h"
+
+#include "remote/pcihost.h"
+#include "remote/machine.h"
+#include "hw/boards.h"
+#include "hw/qdev-core.h"
+#include "qemu/main-loop.h"
+#include "remote/memory.h"
+#include "io/proxy-link.h"
+#include "qapi/error.h"
+#include "qemu-options.h"
+#include "sysemu/arch_init.h"
+
+#include "qapi/qmp/qjson.h"
+#include "qapi/qmp/qobject.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
+#include "monitor/qdev.h"
+#include "qapi/qmp/qdict.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/blockdev.h"
+#include "block/block.h"
+#include "remote/remote-opts.h"
+#include "include/qemu-common.h"
+
+#include "vl.h"
+/*
+ * In remote process, we parse only subset of options. The code
+ * taken from vl.c to re-use in remote command line parser.
+ */
+void parse_cmdline(int argc, char **argv, char **envp)
+{
+int optind;
+const char *optarg;
+MachineClass *mc;
+
+/* from vl.c */
+optind = 0;
+
+/* second pass of option parsing */
+
+for (;;) {
+if (optind >= argc) {
+break;
+}
+if (argv[optind][0] != '-') {
+loc_set_cmdline(argv, optind, 1);
+drive_add(IF_DEFAULT, 0, argv[optind++], HD_OPTS);
+} else {
+const QEMUOption *popt;
+
+popt = lookup_opt(argc, argv, &optarg, &optind);
+#ifndef REMOTE_PROCESS
+if (!(popt->arch_mask & arch_type)) {
+error_report("Option not supported for this target, %x 
arch_mask, %x arch_type",
+  

[Qemu-devel] [RFC v3 PATCH 01/45] multi-process: memory: alloc RAM from file at offset

2019-09-03 Thread Jagannathan Raman
Allow RAM MemoryRegion to be created from an offset in a file, instead
of allocating at offset of 0 by default. This is needed to synchronize
RAM between QEMU & remote process.
This will be needed for the following patches.

Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
Signed-off-by: Elena Ufimtseva 
---
 exec.c| 11 +++
 include/exec/ram_addr.h   |  2 +-
 include/qemu/mmap-alloc.h |  3 ++-
 memory.c  |  2 +-
 util/mmap-alloc.c |  7 ---
 util/oslib-posix.c|  2 +-
 6 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/exec.c b/exec.c
index 3e78de3..b3f1aa9 100644
--- a/exec.c
+++ b/exec.c
@@ -1885,6 +1885,7 @@ static void *file_ram_alloc(RAMBlock *block,
 ram_addr_t memory,
 int fd,
 bool truncate,
+off_t offset,
 Error **errp)
 {
 MachineState *ms = MACHINE(qdev_get_machine());
@@ -1936,7 +1937,8 @@ static void *file_ram_alloc(RAMBlock *block,
 }
 
 area = qemu_ram_mmap(fd, memory, block->mr->align,
- block->flags & RAM_SHARED, block->flags & RAM_PMEM);
+ block->flags & RAM_SHARED, block->flags & RAM_PMEM,
+ offset);
 if (area == MAP_FAILED) {
 error_setg_errno(errp, errno,
  "unable to map backing store for guest RAM");
@@ -2325,7 +2327,7 @@ static void ram_block_add(RAMBlock *new_block, Error 
**errp, bool shared)
 #ifdef CONFIG_POSIX
 RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
  uint32_t ram_flags, int fd,
- Error **errp)
+ off_t offset, Error **errp)
 {
 RAMBlock *new_block;
 Error *local_err = NULL;
@@ -2370,7 +2372,8 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, 
MemoryRegion *mr,
 new_block->used_length = size;
 new_block->max_length = size;
 new_block->flags = ram_flags;
-new_block->host = file_ram_alloc(new_block, size, fd, !file_size, errp);
+new_block->host = file_ram_alloc(new_block, size, fd, !file_size, offset,
+ errp);
 if (!new_block->host) {
 g_free(new_block);
 return NULL;
@@ -2400,7 +2403,7 @@ RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, 
MemoryRegion *mr,
 return NULL;
 }
 
-block = qemu_ram_alloc_from_fd(size, mr, ram_flags, fd, errp);
+block = qemu_ram_alloc_from_fd(size, mr, ram_flags, fd, 0, errp);
 if (!block) {
 if (created) {
 unlink(mem_path);
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index b7b2e60..15837a1 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -164,7 +164,7 @@ RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, 
MemoryRegion *mr,
Error **errp);
 RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
  uint32_t ram_flags, int fd,
- Error **errp);
+ off_t offset, Error **errp);
 
 RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
   MemoryRegion *mr, Error **errp);
diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h
index e786266..4f57985 100644
--- a/include/qemu/mmap-alloc.h
+++ b/include/qemu/mmap-alloc.h
@@ -25,7 +25,8 @@ void *qemu_ram_mmap(int fd,
 size_t size,
 size_t align,
 bool shared,
-bool is_pmem);
+bool is_pmem,
+off_t start);
 
 void qemu_ram_munmap(int fd, void *ptr, size_t size);
 
diff --git a/memory.c b/memory.c
index 5d8c9a9..debed5e 100644
--- a/memory.c
+++ b/memory.c
@@ -1622,7 +1622,7 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
 mr->destructor = memory_region_destructor_ram;
 mr->ram_block = qemu_ram_alloc_from_fd(size, mr,
share ? RAM_SHARED : 0,
-   fd, &err);
+   fd, 0, &err);
 mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
 if (err) {
 mr->size = int128_zero();
diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
index f7f177d..4b727bd 100644
--- a/util/mmap-alloc.c
+++ b/util/mmap-alloc.c
@@ -86,7 +86,8 @@ void *qemu_ram_mmap(int fd,
 size_t size,
 size_t align,
 bool shared,
-bool is_pmem)
+bool is_pmem,
+off_t start)
 {
 int flags;
 int map_sync_flags = 0;
@@ -147,7 +148,7 @@ void *qemu_ram_mmap(int fd,
 offset = QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)

[Qemu-devel] [RFC v3 PATCH 37/45] multi-process: perform device reset in the remote process

2019-09-03 Thread Jagannathan Raman
Perform device reset in the remote process when QEMU performs
device reset. This is required to reset the internal state
(like registers, etc...) of emulated devices

Signed-off-by: Elena Ufimtseva 
Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
---
 New patch in v3

 hw/proxy/proxy-lsi53c895a.c   |  6 ++
 hw/proxy/qemu-proxy.c | 14 ++
 include/hw/proxy/qemu-proxy.h |  2 ++
 include/io/proxy-link.h   |  1 +
 remote/remote-main.c  | 11 +++
 5 files changed, 34 insertions(+)

diff --git a/hw/proxy/proxy-lsi53c895a.c b/hw/proxy/proxy-lsi53c895a.c
index e8a8d36..8640749 100644
--- a/hw/proxy/proxy-lsi53c895a.c
+++ b/hw/proxy/proxy-lsi53c895a.c
@@ -128,6 +128,11 @@ static void proxy_lsi_realize(PCIProxyDev *dev, Error 
**errp)
 pci_register_bar(pci_dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_io);
 }
 
+static void proxy_lsi_reset(DeviceState *dev)
+{
+proxy_device_reset(dev);
+}
+
 static void proxy_lsi_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -145,6 +150,7 @@ static void proxy_lsi_class_init(ObjectClass *klass, void 
*data)
 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 
 dc->desc = "LSI Proxy Device";
+dc->reset = proxy_lsi_reset;
 }
 
 static const TypeInfo lsi_proxy_dev_type_info = {
diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index db9a208..c812145 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -588,3 +588,17 @@ uint64_t proxy_default_bar_read(PCIProxyDev *dev, 
MemoryRegion *mr, hwaddr addr,
 
 return val;
 }
+
+void proxy_device_reset(DeviceState *dev)
+{
+PCIProxyDev *pdev = PCI_PROXY_DEV(dev);
+ProcMsg msg;
+
+memset(&msg, 0, sizeof(ProcMsg));
+
+msg.bytestream = 0;
+msg.size = sizeof(msg.data1);
+msg.cmd = DEVICE_RESET;
+
+proxy_proc_send(pdev->proxy_link, &msg, pdev->proxy_link->com);
+}
diff --git a/include/hw/proxy/qemu-proxy.h b/include/hw/proxy/qemu-proxy.h
index a03c6cc..d88fbd4 100644
--- a/include/hw/proxy/qemu-proxy.h
+++ b/include/hw/proxy/qemu-proxy.h
@@ -100,4 +100,6 @@ void proxy_default_bar_write(PCIProxyDev *dev, MemoryRegion 
*mr, hwaddr addr,
 uint64_t proxy_default_bar_read(PCIProxyDev *dev, MemoryRegion *mr, hwaddr 
addr,
 unsigned size, bool memory);
 
+void proxy_device_reset(DeviceState *dev);
+
 #endif /* QEMU_PROXY_H */
diff --git a/include/io/proxy-link.h b/include/io/proxy-link.h
index 32b2c1a..eb51d29 100644
--- a/include/io/proxy-link.h
+++ b/include/io/proxy-link.h
@@ -76,6 +76,7 @@ typedef enum {
 DEVICE_DEL,
 PROXY_PING,
 MMIO_RETURN,
+DEVICE_RESET,
 MAX,
 } proc_cmd_t;
 
diff --git a/remote/remote-main.c b/remote/remote-main.c
index 2a9ebae..a6ff338 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -66,6 +66,9 @@
 #include "qemu/cutils.h"
 #include "remote-opts.h"
 
+#include "monitor/monitor.h"
+#include "sysemu/reset.h"
+
 static ProxyLinkState *proxy_link;
 
 typedef struct remote_pci_devs {
@@ -302,6 +305,11 @@ fail:
 del_from_pci_devs_list((const char *)msg->id);
 }
 
+static void process_device_reset_msg(ProcMsg *msg)
+{
+qemu_devices_reset();
+}
+
 static int init_drive(QDict *rqdict, Error **errp)
 {
 QemuOpts *opts;
@@ -520,6 +528,9 @@ static void process_msg(GIOCondition cond, ProcChannel 
*chan)
 notify_proxy(wait, (uint32_t)getpid());
 PUT_REMOTE_WAIT(wait);
 break;
+case DEVICE_RESET:
+process_device_reset_msg(msg);
+break;
 default:
 error_setg(&err, "Unknown command");
 goto finalize_loop;
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 29/45] multi-process: refractor vl.c code to re-use in remote

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
---
 New patch in v3

 Makefile.objs|   2 +
 remote/Makefile.objs |   1 +
 vl-parse.c   | 157 +++
 vl.c | 150 +---
 vl.h |  54 ++
 5 files changed, 215 insertions(+), 149 deletions(-)
 create mode 100644 vl-parse.c
 create mode 100644 vl.h

diff --git a/Makefile.objs b/Makefile.objs
index 0668509..f817cf6 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -104,6 +104,8 @@ qemu-seccomp.o-libs := $(SECCOMP_LIBS)
 
 common-obj-$(CONFIG_FDT) += device_tree.o
 
+common-obj-y += vl-parse.o
+
 ##
 # qapi
 
diff --git a/remote/Makefile.objs b/remote/Makefile.objs
index cbb3065..c1349ad 100644
--- a/remote/Makefile.objs
+++ b/remote/Makefile.objs
@@ -2,3 +2,4 @@ remote-pci-obj-$(CONFIG_MPQEMU) += remote-main.o
 remote-pci-obj-$(CONFIG_MPQEMU) += pcihost.o
 remote-pci-obj-$(CONFIG_MPQEMU) += machine.o
 remote-pci-obj-$(CONFIG_MPQEMU) += iohub.o
+remote-pci-obj-$(CONFIG_MPQEMU) +=../vl-parse.o
diff --git a/vl-parse.c b/vl-parse.c
new file mode 100644
index 000..d3716d1
--- /dev/null
+++ b/vl-parse.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "qemu/cutils.h"
+#include "qemu/error-report.h"
+#include "hw/qdev.h"
+#include "monitor/qdev.h"
+#include "sysemu/sysemu.h"
+#include "qemu/option.h"
+#include "qemu-options.h"
+#include "sysemu/blockdev.h"
+
+#include "chardev/char.h"
+#include "monitor/monitor.h"
+#include "qemu/config-file.h"
+
+#include "sysemu/arch_init.h"
+
+#include "vl.h"
+
+/***/
+/* QEMU Block devices */
+
+static const QEMUOption qemu_options[] = {
+{ "h", 0, QEMU_OPTION_h, QEMU_ARCH_ALL },
+#define QEMU_OPTIONS_GENERATE_OPTIONS
+#include "qemu-options-wrapper.h"
+{ NULL },
+};
+
+const QEMUOption *lookup_opt(int argc, char **argv,
+const char **poptarg, int *poptind)
+{
+const QEMUOption *popt;
+int optind = *poptind;
+char *r = argv[optind];
+const char *optarg;
+
+loc_set_cmdline(argv, optind, 1);
+optind++;
+/* Treat --foo the same as -foo.  */
+if (r[1] == '-') {
+r++;
+}
+popt = qemu_options;
+if (!popt) {
+error_report("No valide qemu_options");
+}
+for (;;) {
+if (!popt->name) {
+error_report("invalid option*");
+exit(1);
+popt++;
+continue;
+}
+if (!strcmp(popt->name, r + 1)) {
+break;
+}
+popt++;
+}
+if (popt->flags & HAS_ARG) {
+if (optind >= argc) {
+error_report("optind %d, argc %d", optind, argc);
+error_report("requires an argument");
+exit(1);
+}
+optarg = argv[optind++];
+loc_set_cmdline(argv, optind - 2, 2);
+} else {
+optarg = NULL;
+}
+
+*poptarg = optarg;
+*poptind = optind;
+
+return popt;
+}
+
+int drive_init_func(void *opaque, QemuOpts *opts, Error **errp)
+{
+BlockInterfaceType *block_default_type = opaque;
+
+if (!drive_new(opts, *block_default_type, errp)) {
+error_report_err(*errp);
+}
+
+return 0;
+}
+
+#if defined(CONFIG_MPQEMU)
+int rdrive_init_func(void *opaque, QemuOpts *opts, Error **errp)
+{
+DeviceState *dev;
+
+dev = qdev_remote_add(opts, false /* this is drive */, errp);
+if (!dev) {
+error_setg(errp, "qdev_remote_add failed for drive.");
+return -1;
+}
+object_unref(OBJECT(dev));
+return 0;
+}
+#endif
+
+#if

[Qemu-devel] [RFC v3 PATCH 03/45] multi-process: add a command line option for debug file

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Can be used with -d rdebug command options when starting qemu.

Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
---
 include/qemu/log.h | 1 +
 util/log.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/include/qemu/log.h b/include/qemu/log.h
index b097a6c..ca6f490 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -45,6 +45,7 @@ static inline bool qemu_log_separate(void)
 /* LOG_TRACE (1 << 15) is defined in log-for-trace.h */
 #define CPU_LOG_TB_OP_IND  (1 << 16)
 #define CPU_LOG_TB_FPU (1 << 17)
+#define LOG_REMOTE_DEBUG   (1 << 18)
 
 /* Lock output for a series of related logs.  Since this is not needed
  * for a single qemu_log / qemu_log_mask / qemu_log_mask_and_addr, we
diff --git a/util/log.c b/util/log.c
index 1d1b33f..78e3e82 100644
--- a/util/log.c
+++ b/util/log.c
@@ -273,6 +273,8 @@ const QEMULogItem qemu_log_items[] = {
 { CPU_LOG_TB_NOCHAIN, "nochain",
   "do not chain compiled TBs so that \"exec\" and \"cpu\" show\n"
   "complete traces" },
+{ LOG_REMOTE_DEBUG, "rdebug",
+  "log remote debug" },
 { 0, NULL, NULL },
 };
 
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 19/45] multi-process: Add LSI device proxy object

2019-09-03 Thread Jagannathan Raman
Adds proxy-lsi53c895a object, as a derivative of the pci-proxy-dev
object. This object is the proxy for the lsi53c895a object
instantiated by the remote process.

Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
Signed-off-by: Elena Ufimtseva 
---
 hw/proxy/Makefile.objs  |   1 +
 hw/proxy/proxy-lsi53c895a.c | 162 
 include/hw/proxy/proxy-lsi53c895a.h |  42 ++
 3 files changed, 205 insertions(+)
 create mode 100644 hw/proxy/proxy-lsi53c895a.c
 create mode 100644 include/hw/proxy/proxy-lsi53c895a.h

diff --git a/hw/proxy/Makefile.objs b/hw/proxy/Makefile.objs
index eb81624..f562f5a 100644
--- a/hw/proxy/Makefile.objs
+++ b/hw/proxy/Makefile.objs
@@ -1 +1,2 @@
 common-obj-$(CONFIG_MPQEMU) += qemu-proxy.o
+common-obj-$(CONFIG_MPQEMU) += proxy-lsi53c895a.o
diff --git a/hw/proxy/proxy-lsi53c895a.c b/hw/proxy/proxy-lsi53c895a.c
new file mode 100644
index 000..e8a8d36
--- /dev/null
+++ b/hw/proxy/proxy-lsi53c895a.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2019, Oracle and/or its affiliates.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include 
+
+#include "qemu/osdep.h"
+#include "hw/qdev-core.h"
+#include "qemu/bitops.h"
+#include "hw/pci/pci.h"
+#include "hw/proxy/qemu-proxy.h"
+#include "hw/proxy/proxy-lsi53c895a.h"
+#include "exec/memory.h"
+
+static uint64_t proxy_lsi_io_read(void *opaque, hwaddr addr, unsigned size)
+{
+ProxyLSIState *s = opaque;
+
+return proxy_default_bar_read(PCI_PROXY_DEV(s), &s->io_io, addr, size,
+  false);
+}
+
+static void proxy_lsi_io_write(void *opaque, hwaddr addr, uint64_t val,
+   unsigned size)
+{
+ProxyLSIState *s = opaque;
+
+proxy_default_bar_write(PCI_PROXY_DEV(s), &s->io_io, addr, val, size,
+false);
+}
+
+static const MemoryRegionOps proxy_lsi_io_ops = {
+.read = proxy_lsi_io_read,
+.write = proxy_lsi_io_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+.min_access_size = 1,
+.max_access_size = 1,
+},
+};
+
+static uint64_t proxy_lsi_ram_read(void *opaque, hwaddr addr, unsigned size)
+{
+ProxyLSIState *s = opaque;
+
+return proxy_default_bar_read(PCI_PROXY_DEV(s), &s->ram_io, addr, size,
+  true);
+}
+
+static void proxy_lsi_ram_write(void *opaque, hwaddr addr, uint64_t val,
+unsigned size)
+{
+ProxyLSIState *s = opaque;
+
+proxy_default_bar_write(PCI_PROXY_DEV(s), &s->ram_io, addr, val, size,
+true);
+}
+
+static const MemoryRegionOps proxy_lsi_ram_ops = {
+.read = proxy_lsi_ram_read,
+.write = proxy_lsi_ram_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static uint64_t proxy_lsi_mmio_read(void *opaque, hwaddr addr, unsigned size)
+{
+ProxyLSIState *s = opaque;
+
+return proxy_default_bar_read(PCI_PROXY_DEV(s), &s->mmio_io, addr, size,
+  true);
+}
+
+static void proxy_lsi_mmio_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned size)
+{
+ProxyLSIState *s = opaque;
+
+proxy_default_bar_write(PCI_PROXY_DEV(s), &s->mmio_io, addr, val, size,
+true);
+}
+
+static const MemoryRegionOps proxy_lsi_mmio_ops = {
+.read = proxy_lsi_mmio_read,
+.write = proxy_lsi_mmio_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+.min_access_size = 1,
+.max_access_size = 1,
+},
+};
+
+static void proxy_lsi_realize(PCIProxyDev *dev, Error **errp)
+{
+ProxyLSIState *s = LSI_PROXY_DEV(dev);
+PCIDevice *pci_dev = PCI_DEVICE(dev);
+uint8_t *pci_conf = pci_dev->config;
+
+pci_conf[PCI_LATENCY_TIMER] = 0xff;
+pci_conf[PCI_INTERRUPT_PIN] = 0x01;
+
+memory_region_init_io(&s->mmio_io, OBJECT(s), &proxy_lsi_mmio_ops, s,
+  

[Qemu-devel] [RFC v3 PATCH 33/45] multi-process: add support for multiple devices

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Add suport for multiple devices in one remote process.

Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
---
 New patch in v3

 remote/remote-main.c | 140 ++-
 1 file changed, 115 insertions(+), 25 deletions(-)

diff --git a/remote/remote-main.c b/remote/remote-main.c
index 416b8a1..5552712 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -67,19 +67,83 @@
 #include "remote-opts.h"
 
 static ProxyLinkState *proxy_link;
-PCIDevice *remote_pci_dev;
-bool create_done;
 
-static void process_config_write(ProcMsg *msg)
+typedef struct remote_pci_devs {
+char *id;
+DeviceState *ds;
+unsigned int created;
+QLIST_ENTRY(remote_pci_devs) next;
+} remote_pci_devs;
+typedef struct pci_devs_listhead pci_devs_listhead;
+
+QLIST_HEAD(pci_devs_listhead, remote_pci_devs) pci_devs_head;
+/* This is needed to distinguish between different devices being initialized. 
*/
+
+QemuMutex remote_ds_lock;
+static bool done_init;
+
+
+static remote_pci_devs *get_ds_from_list(const char *id, unsigned int size_id)
+{
+remote_pci_devs *d;
+
+qemu_mutex_lock(&remote_ds_lock);
+QLIST_FOREACH(d, &pci_devs_head, next) {
+if (id && d->id) {
+if (strncmp(id, d->id, size_id) == 0) {
+qemu_mutex_unlock(&remote_ds_lock);
+return d;
+}
+   }
+}
+qemu_mutex_unlock(&remote_ds_lock);
+
+return NULL;
+}
+
+static void add_to_pci_devs_list(DeviceState *dev)
+{
+   remote_pci_devs *d;
+
+   if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+d = g_malloc(sizeof(remote_pci_devs));
+d->ds = dev;
+d->id = g_strdup(dev->id);
+if (!d->id) {
+return;
+}
+qemu_mutex_lock(&remote_ds_lock);
+QLIST_INSERT_HEAD(&pci_devs_head, d, next);
+qemu_mutex_unlock(&remote_ds_lock);
+
+}
+}
+
+static void del_from_pci_devs_list(const char *id)
+{
+remote_pci_devs *d;
+
+d = get_ds_from_list((char *)id, strlen((char *)id));
+if (!d) {
+return;
+}
+g_free(d->id);
+qemu_mutex_lock(&remote_ds_lock);
+QLIST_REMOVE(d, next);
+qemu_mutex_unlock(&remote_ds_lock);
+g_free(d);
+}
+
+static void process_config_write(ProcMsg *msg, DeviceState *ds)
 {
 struct conf_data_msg *conf = (struct conf_data_msg *)msg->data2;
 
 qemu_mutex_lock_iothread();
-pci_default_write_config(remote_pci_dev, conf->addr, conf->val, conf->l);
+pci_default_write_config(PCI_DEVICE(ds), conf->addr, conf->val, conf->l);
 qemu_mutex_unlock_iothread();
 }
 
-static void process_config_read(ProcMsg *msg)
+static void process_config_read(ProcMsg *msg, DeviceState *ds)
 {
 struct conf_data_msg *conf = (struct conf_data_msg *)msg->data2;
 uint32_t val;
@@ -88,7 +152,7 @@ static void process_config_read(ProcMsg *msg)
 wait = msg->fds[0];
 
 qemu_mutex_lock_iothread();
-val = pci_default_read_config(remote_pci_dev, conf->addr, conf->l);
+val = pci_default_read_config(PCI_DEVICE(ds), conf->addr, conf->l);
 qemu_mutex_unlock_iothread();
 
 notify_proxy(wait, val);
@@ -233,6 +297,8 @@ fail:
 notify_proxy(wait, 1);
 
 PUT_REMOTE_WAIT(wait);
+
+del_from_pci_devs_list((const char *)msg->id);
 }
 
 static int init_drive(QDict *rqdict, Error **errp)
@@ -313,7 +379,7 @@ static int setup_device(ProcMsg *msg, Error **errp)
 qstr = qstring_from_str((char *)msg->data2);
 obj = qobject_from_json(qstring_get_str(qstr), &local_error);
 if (!obj) {
-error_setg(errp, "Could not get object!");
+error_setg(errp, "Could not get object");
 return rc;
 }
 
@@ -338,13 +404,12 @@ static int setup_device(ProcMsg *msg, Error **errp)
 
 dev = qdev_device_add(opts, &local_error);
 if (!dev) {
-error_setg(errp, "Could not add device %s.",
+error_setg(errp, "Could not add device %s",
qstring_get_str(qobject_to_json(QOBJECT(qdict;
 return rc;
 }
-if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
-remote_pci_dev = PCI_DEVICE(dev);
-}
+
+add_to_pci_devs_list(dev);
 qemu_opts_del(opts);
 
 return 0;
@@ -354,10 +419,13 @@ static void process_msg(GIOCondition cond, ProcChannel 
*chan)
 {
 ProcMsg *msg = NULL;
 Error *err = NULL;
+remote_pci_devs *r = NULL;
 
 if ((cond & G_IO_HUP) || (cond & G_IO_ERR)) {
 error_setg(&err, "socket closed, cond is %d", cond);
-goto finalize_loop;
+proxy_link_finalize(proxy_link);
+proxy_link = NULL;
+return;
 }
 
 msg = g_malloc0(sizeof(ProcMsg));
@@ -367,23 +435,32 @@ static void process_msg(GIOCondition cond, ProcChannel 
*chan)
 goto finalize_loop;
 }
 
+if (msg->cmd != DEV_OPTS && msg->cmd != DRIVE_OPTS &&
+msg->cmd != SYNC_SYSMEM) {
+r = get_ds_from_list((const char

[Qemu-devel] [RFC v3 PATCH 35/45] multi-process: handle heartbeat messages in remote process

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

and reply back to proxy object.

Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
Signed-off-by: Elena Ufimtseva 
---
 remote/remote-main.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/remote/remote-main.c b/remote/remote-main.c
index 5552712..f0a4de9 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -420,6 +420,7 @@ static void process_msg(GIOCondition cond, ProcChannel 
*chan)
 ProcMsg *msg = NULL;
 Error *err = NULL;
 remote_pci_devs *r = NULL;
+int wait;
 
 if ((cond & G_IO_HUP) || (cond & G_IO_ERR)) {
 error_setg(&err, "socket closed, cond is %d", cond);
@@ -513,6 +514,11 @@ static void process_msg(GIOCondition cond, ProcChannel 
*chan)
 case DEVICE_DEL:
 process_device_del_msg(msg);
 break;
+case PROXY_PING:
+wait = msg->fds[0];
+notify_proxy(wait, (uint32_t)getpid());
+PUT_REMOTE_WAIT(wait);
+break;
 default:
 error_setg(&err, "Unknown command");
 goto finalize_loop;
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 18/45] multi-process: support dev id in config read/write

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
---
 New patch in v3

 hw/proxy/qemu-proxy.c | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index 1021045..789f39a 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -151,12 +151,16 @@ static void set_proxy_sock(PCIDevice *dev, int socket)
 }
 
 static int config_op_send(PCIProxyDev *dev, uint32_t addr, uint32_t *val, int 
l,
-  unsigned int op)
+  char *id, unsigned int op)
 {
 ProcMsg msg;
 struct conf_data_msg conf_data;
 int wait;
 
+if (!id) {
+return -EINVAL;
+}
+
 memset(&msg, 0, sizeof(ProcMsg));
 conf_data.addr = addr;
 conf_data.val = (op == CONF_WRITE) ? *val : 0;
@@ -171,6 +175,8 @@ static int config_op_send(PCIProxyDev *dev, uint32_t addr, 
uint32_t *val, int l,
 msg.size = sizeof(conf_data);
 msg.cmd = op;
 msg.bytestream = 1;
+msg.id = (uint8_t *)g_strdup(dev->dev_id);
+msg.size_id = strlen(dev->dev_id) + 1;
 
 if (op == CONF_WRITE) {
 msg.num_fds = 0;
@@ -188,6 +194,7 @@ static int config_op_send(PCIProxyDev *dev, uint32_t addr, 
uint32_t *val, int l,
 }
 
 free(msg.data2);
+free(msg.id);
 
 return 0;
 }
@@ -198,7 +205,8 @@ static uint32_t pci_proxy_read_config(PCIDevice *d, 
uint32_t addr, int len)
 
 (void)pci_default_read_config(d, addr, len);
 
-config_op_send(PCI_PROXY_DEV(d), addr, &val, len, CONF_READ);
+config_op_send(PCI_PROXY_DEV(d), addr, &val, len,
+   PCI_PROXY_DEV(d)->dev_id, CONF_READ);
 
 return val;
 }
@@ -208,7 +216,8 @@ static void pci_proxy_write_config(PCIDevice *d, uint32_t 
addr, uint32_t val,
 {
 pci_default_write_config(d, addr, val, l);
 
-config_op_send(PCI_PROXY_DEV(d), addr, &val, l, CONF_WRITE);
+config_op_send(PCI_PROXY_DEV(d), addr, &val, l,
+   PCI_PROXY_DEV(d)->dev_id, CONF_WRITE);
 }
 
 static void pci_proxy_dev_class_init(ObjectClass *klass, void *data)
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 30/45] multi-process: add remote option

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
---
 New patch in v3

 qemu-options.hx | 21 +
 1 file changed, 21 insertions(+)

diff --git a/qemu-options.hx b/qemu-options.hx
index 9621e93..e2dca3d 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -27,6 +27,27 @@ STEXI
 Display version information and exit
 ETEXI
 
+DEF("remote", HAS_ARG, QEMU_OPTION_remote,
+"-remote socket[,prop[=value][,...]]\n"
+"add remote process\n"
+"prop=value,... sets driver properties\n"
+"use '-remote help' to print all possible properties\n",
+QEMU_ARCH_ALL)
+STEXI
+@table @option
+@item rid
+@findex -rid
+remote id
+@item socket
+@findex -socket
+Remote process socket
+@item command
+@findex -command
+Remote process command.
+
+@end table
+ETEXI
+
 DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
 "-machine [type=]name[,prop[=value][,...]]\n"
 "selects emulated machine ('-machine help' for list)\n"
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 26/45] multi-process: remote: add create_done condition

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Do not allow BAR,MMIO handlers and irq setup to run before
the configuration of the devices completes.

Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
Signed-off-by: Elena Ufimtseva 
---
 remote/remote-main.c | 29 -
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/remote/remote-main.c b/remote/remote-main.c
index e284d5f..0c0e085 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -67,6 +67,7 @@
 
 static ProxyLinkState *proxy_link;
 PCIDevice *remote_pci_dev;
+bool create_done;
 
 static void process_config_write(ProcMsg *msg)
 {
@@ -369,21 +370,31 @@ static void process_msg(GIOCondition cond, ProcChannel 
*chan)
 case INIT:
 break;
 case CONF_WRITE:
-process_config_write(msg);
+if (create_done) {
+process_config_write(msg);
+}
+
 break;
 case CONF_READ:
-process_config_read(msg);
+if (create_done) {
+process_config_read(msg);
+}
+
 break;
 case BAR_WRITE:
-process_bar_write(msg, &err);
-if (err) {
-goto finalize_loop;
+if (create_done) {
+process_bar_write(msg, &err);
+if (err) {
+error_report_err(err);
+}
 }
 break;
 case BAR_READ:
-process_bar_read(msg, &err);
-if (err) {
-goto finalize_loop;
+if (create_done) {
+process_bar_read(msg, &err);
+if (err) {
+error_report_err(err);
+}
 }
 break;
 case SYNC_SYSMEM:
@@ -403,7 +414,7 @@ static void process_msg(GIOCondition cond, ProcChannel 
*chan)
 qemu_mutex_lock_iothread();
 qemu_run_machine_init_done_notifiers();
 qemu_mutex_unlock_iothread();
-
+create_done = true;
 break;
 case DRIVE_OPTS:
 if (setup_drive(msg, &err)) {
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 34/45] multi-process: add heartbeat timer and signal handler

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Add a signal handler for launched remote processes and set up
the heartbeat timer for remote processes.

Signed-off-by: John G Johnson 
Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
---
 hw/proxy/qemu-proxy.c   | 101 
 include/io/proxy-link.h |   1 +
 2 files changed, 102 insertions(+)

diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index 61808c5..699a0b1 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -53,14 +53,96 @@
 #include "hw/boards.h"
 #include "include/qemu/log.h"
 
+QEMUTimer *hb_timer;
 static void pci_proxy_dev_realize(PCIDevice *dev, Error **errp);
 static void setup_irqfd(PCIProxyDev *dev);
+static void pci_dev_exit(PCIDevice *dev);
+static void start_heartbeat_timer(void);
+static void stop_heartbeat_timer(void);
+static void childsig_handler(int sig, siginfo_t *siginfo, void *ctx);
+static void broadcast_msg(ProcMsg *msg, bool need_reply);
+
+static void childsig_handler(int sig, siginfo_t *siginfo, void *ctx)
+{
+/* TODO: Add proper handler. */
+printf("Child (pid %d) is dead? Signal is %d, Exit code is %d.\n",
+   siginfo->si_pid, siginfo->si_signo, siginfo->si_code);
+}
+
+static void broadcast_msg(ProcMsg *msg, bool need_reply)
+{
+PCIProxyDev *entry;
+unsigned int pid;
+int wait;
+
+QLIST_FOREACH(entry, &proxy_dev_list.devices, next) {
+if (need_reply) {
+wait = GET_REMOTE_WAIT;
+msg->num_fds = 1;
+msg->fds[0] = wait;
+}
+
+proxy_proc_send(entry->proxy_link, msg, entry->proxy_link->com);
+if (need_reply) {
+pid = (uint32_t)wait_for_remote(wait);
+PUT_REMOTE_WAIT(wait);
+/* TODO: Add proper handling. */
+if (pid) {
+need_reply = 0;
+}
+}
+}
+}
+
+#define NOP_INTERVAL 100
+
+static void remote_ping(void *opaque)
+{
+ProcMsg msg;
+
+memset(&msg, 0, sizeof(ProcMsg));
+
+msg.num_fds = 0;
+msg.cmd = PROXY_PING;
+msg.bytestream = 0;
+msg.size = 0;
+
+broadcast_msg(&msg, true);
+timer_mod(hb_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + NOP_INTERVAL);
+
+}
+
+void start_heartbeat_timer(void)
+{
+hb_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
+remote_ping,
+&proxy_dev_list);
+timer_mod(hb_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + NOP_INTERVAL);
+
+}
+
+static void stop_heartbeat_timer(void)
+{
+timer_del(hb_timer);
+timer_free(hb_timer);
+}
+
+static void set_sigchld_handler(void)
+{
+struct sigaction sa_sigterm;
+memset(&sa_sigterm, 0, sizeof(sa_sigterm));
+sa_sigterm.sa_sigaction = childsig_handler;
+sa_sigterm.sa_flags = SA_SIGINFO | SA_NOCLDWAIT | SA_NOCLDSTOP;
+sigaction(SIGCHLD, &sa_sigterm, NULL);
+}
 
 static void proxy_ready(PCIDevice *dev)
 {
 PCIProxyDev *pdev = PCI_PROXY_DEV(dev);
 
 setup_irqfd(pdev);
+set_sigchld_handler();
+start_heartbeat_timer();
 }
 
 static void set_remote_opts(PCIDevice *dev, QDict *qdict, unsigned int cmd)
@@ -272,6 +354,7 @@ static void pci_proxy_dev_class_init(ObjectClass *klass, 
void *data)
 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
 k->realize = pci_proxy_dev_realize;
+k->exit = pci_dev_exit;
 k->config_read = pci_proxy_read_config;
 k->config_write = pci_proxy_write_config;
 }
@@ -408,6 +491,24 @@ static void pci_proxy_dev_realize(PCIDevice *device, Error 
**errp)
 dev->proxy_ready = proxy_ready;
 }
 
+static void pci_dev_exit(PCIDevice *pdev)
+{
+PCIProxyDev *entry, *sentry;
+PCIProxyDev *dev = PCI_PROXY_DEV(pdev);
+
+stop_heartbeat_timer();
+
+QLIST_FOREACH_SAFE(entry, &proxy_dev_list.devices, next, sentry) {
+if (entry->remote_pid == dev->remote_pid) {
+QLIST_REMOVE(entry, next);
+}
+}
+
+if (!QLIST_EMPTY(&proxy_dev_list.devices)) {
+start_heartbeat_timer();
+}
+}
+
 static void send_bar_access_msg(PCIProxyDev *dev, MemoryRegion *mr,
 bool write, hwaddr addr, uint64_t *val,
 unsigned size, bool memory)
diff --git a/include/io/proxy-link.h b/include/io/proxy-link.h
index 13fb312..ae98eac 100644
--- a/include/io/proxy-link.h
+++ b/include/io/proxy-link.h
@@ -74,6 +74,7 @@ typedef enum {
 DRIVE_OPTS,
 DEVICE_ADD,
 DEVICE_DEL,
+PROXY_PING,
 MAX,
 } proc_cmd_t;
 
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 23/45] multi-process: add qdev_proxy_add to create proxy devices

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

This is handled while parsing the command line options.
The parsed options are being sent to remote process
as the messgaes containing JSON strings.

Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
Signed-off-by: Elena Ufimtseva 
---
 v1 -> v2:
   - parse socket and command suboptions of drive/device commands

 hw/proxy/qemu-proxy.c |   3 +-
 include/hw/proxy/qemu-proxy.h |   7 ++
 include/monitor/qdev.h|  24 
 qdev-monitor.c| 254 ++
 4 files changed, 287 insertions(+), 1 deletion(-)

diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index dea6784..61808c5 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -360,7 +360,8 @@ static void init_proxy(PCIDevice *dev, char *command, bool 
need_spawn, Error **e
 
 if (!pdev->managed) {
 if (need_spawn) {
-if (!remote_spawn(pdev, command, &local_error)) {
+if (remote_spawn(pdev, command, &local_error)) {
+fprintf(stderr, "remote spawn failed\n");
 return;
 }
 }
diff --git a/include/hw/proxy/qemu-proxy.h b/include/hw/proxy/qemu-proxy.h
index 4312f9e..fb408cf 100644
--- a/include/hw/proxy/qemu-proxy.h
+++ b/include/hw/proxy/qemu-proxy.h
@@ -86,6 +86,13 @@ typedef struct PCIProxyDevClass {
 
 int remote_spawn(PCIProxyDev *pdev, const char *command, Error **errp);
 
+typedef struct PCIProxyDevList {
+QLIST_HEAD(, PCIProxyDev) devices;
+} proxy_dev_list_t;
+
+extern QemuMutex proxy_list_lock;
+extern proxy_dev_list_t proxy_dev_list;
+
 void proxy_default_bar_write(PCIProxyDev *dev, MemoryRegion *mr, hwaddr addr,
  uint64_t val, unsigned size, bool memory);
 
diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h
index 084799e..6b5020e 100644
--- a/include/monitor/qdev.h
+++ b/include/monitor/qdev.h
@@ -2,6 +2,7 @@
 #define MONITOR_QDEV_H
 
 #include "hw/qdev-core.h"
+#include "hw/proxy/qemu-proxy.h"
 
 /*** monitor commands ***/
 
@@ -9,7 +10,30 @@ void hmp_info_qtree(Monitor *mon, const QDict *qdict);
 void hmp_info_qdm(Monitor *mon, const QDict *qdict);
 void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp);
 
+DeviceState *qdev_remote_add(QemuOpts *opts, bool device, Error **errp);
+void qdev_proxy_fire(void);
+
 int qdev_device_help(QemuOpts *opts);
+DeviceState *qdev_proxy_add(const char *rid, const char *id, char *bus,
+char *command, int rsocket, bool managed,
+Error **errp);
+
+struct remote_process {
+int rid;
+int remote_pid;
+unsigned int type;
+int socket;
+char *command;
+QemuOpts *opts;
+
+QLIST_ENTRY(remote_process) next;
+};
+
+void remote_process_register(struct remote_process *p);
+
+struct remote_process *get_remote_process_type(unsigned int type);
+struct remote_process *get_remote_process_rid(unsigned int rid);
+
 DeviceState *qdev_device_add(QemuOpts *opts, Error **errp);
 void qdev_set_id(DeviceState *dev, const char *id);
 
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 58222c2..d6f7572 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -34,6 +34,17 @@
 #include "qemu/qemu-print.h"
 #include "sysemu/block-backend.h"
 #include "migration/misc.h"
+#include "hw/boards.h"
+#include "hw/proxy/qemu-proxy.h"
+#include "qapi/qmp/qjson.h"
+#include "qapi/qmp/qstring.h"
+#include "sysemu/sysemu.h"
+#include "hw/proxy/proxy-lsi53c895a.h"
+#include "include/qemu/cutils.h"
+#include "include/qemu/log.h"
+#include "qapi/qmp/qlist.h"
+#include "hw/proxy/qemu-proxy.h"
+#include "io/proxy-link.h"
 
 /*
  * Aliases were a bad idea from the start.  Let's keep them
@@ -46,6 +57,8 @@ typedef struct QDevAlias
 uint32_t arch_mask;
 } QDevAlias;
 
+proxy_dev_list_t proxy_dev_list;
+QemuMutex proxy_list_lock;
 /* Please keep this table sorted by typename. */
 static const QDevAlias qdev_alias_table[] = {
 { "e1000", "e1000-82540em" },
@@ -561,6 +574,247 @@ void qdev_set_id(DeviceState *dev, const char *id)
 }
 }
 
+static QLIST_HEAD(, remote_process) remote_processes;
+
+void remote_process_register(struct remote_process *p)
+{
+QLIST_INSERT_HEAD(&remote_processes, p, next);
+}
+
+struct remote_process *get_remote_process_rid(unsigned int rid)
+{
+struct remote_process *p;
+
+QLIST_FOREACH(p, &remote_processes, next) {
+if (rid == p->rid) {
+return p;
+}
+}
+return NULL;
+}
+
+struct remote_process *get_remote_process_type(unsigned int type)
+{
+struct remote_process *p;
+
+QLIST_FOREACH(p, &remote_processes, next) {
+if (type == p->type) {
+return p;
+}
+}
+return NULL;
+}
+
+#if defined(CONFIG_MPQEMU)
+
+static PCIProxyDev *get_proxy_object_rid(const char *rid)
+{
+PCIProxyDev *entry;
+if (!proxy_list_lock.initialized) {
+QLIST_INIT(&proxy_dev_list.devices);
+qemu_mutex_init(&prox

[Qemu-devel] [RFC v3 PATCH 16/45] multi-process: PCI BAR read/write handling for proxy & remote endpoints

2019-09-03 Thread Jagannathan Raman
Proxy device object implements handler for PCI BAR writes and reads. The handler
uses BAR_WRITE/BAR_READ message to communicate to the remote process with the 
BAR address and
value to be written/read.
The remote process implements handler for BAR_WRITE/BAR_READ message.

Signed-off-by: Jagannathan Raman 
Signed-off-by: Elena Ufimtseva 
Signed-off-by: John G Johnson 
---
 hw/proxy/qemu-proxy.c | 50 +
 include/hw/proxy/qemu-proxy.h |  5 +++
 include/io/proxy-link.h   | 12 +++
 remote/remote-main.c  | 73 +++
 4 files changed, 140 insertions(+)

diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index e5fd4bb..44668bf 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -287,3 +287,53 @@ static void pci_proxy_dev_realize(PCIDevice *device, Error 
**errp)
 dev->get_proxy_sock = get_proxy_sock;
 dev->init_proxy = init_proxy;
 }
+
+static void send_bar_access_msg(ProxyLinkState *proxy_link, MemoryRegion *mr,
+bool write, hwaddr addr, uint64_t *val,
+unsigned size, bool memory)
+{
+ProcMsg msg;
+int wait;
+
+memset(&msg, 0, sizeof(ProcMsg));
+
+msg.bytestream = 0;
+msg.size = sizeof(msg.data1);
+msg.data1.bar_access.addr = mr->addr + addr;
+msg.data1.bar_access.size = size;
+msg.data1.bar_access.memory = memory;
+
+if (write) {
+msg.cmd = BAR_WRITE;
+msg.data1.bar_access.val = *val;
+} else {
+wait = GET_REMOTE_WAIT;
+
+msg.cmd = BAR_READ;
+msg.num_fds = 1;
+msg.fds[0] = wait;
+}
+
+proxy_proc_send(proxy_link, &msg, proxy_link->com);
+
+if (!write) {
+*val = wait_for_remote(wait);
+PUT_REMOTE_WAIT(wait);
+}
+}
+
+void proxy_default_bar_write(PCIProxyDev *dev, MemoryRegion *mr, hwaddr addr,
+ uint64_t val, unsigned size, bool memory)
+{
+send_bar_access_msg(dev->proxy_link, mr, true, addr, &val, size, memory);
+}
+
+uint64_t proxy_default_bar_read(PCIProxyDev *dev, MemoryRegion *mr, hwaddr 
addr,
+unsigned size, bool memory)
+{
+uint64_t val;
+
+send_bar_access_msg(dev->proxy_link, mr, false, addr, &val, size, memory);
+
+return val;
+}
diff --git a/include/hw/proxy/qemu-proxy.h b/include/hw/proxy/qemu-proxy.h
index 3b37b65..a951570 100644
--- a/include/hw/proxy/qemu-proxy.h
+++ b/include/hw/proxy/qemu-proxy.h
@@ -77,5 +77,10 @@ typedef struct PCIProxyDevClass {
 
 int remote_spawn(PCIProxyDev *pdev, const char *command, Error **errp);
 
+void proxy_default_bar_write(PCIProxyDev *dev, MemoryRegion *mr, hwaddr addr,
+ uint64_t val, unsigned size, bool memory);
+
+uint64_t proxy_default_bar_read(PCIProxyDev *dev, MemoryRegion *mr, hwaddr 
addr,
+unsigned size, bool memory);
 
 #endif /* QEMU_PROXY_H */
diff --git a/include/io/proxy-link.h b/include/io/proxy-link.h
index 0785394..2c290b2 100644
--- a/include/io/proxy-link.h
+++ b/include/io/proxy-link.h
@@ -56,6 +56,8 @@ typedef struct ProxyLinkState ProxyLinkState;
  * CONF_READPCI config. space read
  * CONF_WRITE   PCI config. space write
  * SYNC_SYSMEM  Shares QEMU's RAM with remote device's RAM
+ * BAR_WRITEWrites to PCI BAR region
+ * BAR_READ Reads from PCI BAR region
  *
  */
 typedef enum {
@@ -63,6 +65,8 @@ typedef enum {
 CONF_READ,
 CONF_WRITE,
 SYNC_SYSMEM,
+BAR_WRITE,
+BAR_READ,
 MAX,
 } proc_cmd_t;
 
@@ -85,6 +89,13 @@ typedef struct {
 } sync_sysmem_msg_t;
 
 typedef struct {
+hwaddr addr;
+uint64_t val;
+unsigned size;
+bool memory;
+} bar_access_msg_t;
+
+typedef struct {
 proc_cmd_t cmd;
 int bytestream;
 size_t size;
@@ -93,6 +104,7 @@ typedef struct {
 union {
 uint64_t u64;
 sync_sysmem_msg_t sync_sysmem;
+bar_access_msg_t bar_access;
 } data1;
 
 int fds[REMOTE_MAX_FDS];
diff --git a/remote/remote-main.c b/remote/remote-main.c
index 93b2d36..43fe50a 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -45,6 +45,7 @@
 #include "qemu/config-file.h"
 #include "sysemu/sysemu.h"
 #include "block/block.h"
+#include "exec/memattrs.h"
 
 static ProxyLinkState *proxy_link;
 PCIDevice *remote_pci_dev;
@@ -75,6 +76,66 @@ static void process_config_read(ProcMsg *msg)
 PUT_REMOTE_WAIT(wait);
 }
 
+/* TODO: confirm memtx attrs. */
+static void process_bar_write(ProcMsg *msg, Error **errp)
+{
+bar_access_msg_t *bar_access = &msg->data1.bar_access;
+AddressSpace *as =
+bar_access->memory ? &address_space_memory : &address_space_io;
+MemTxResult res;
+
+res = address_space_rw(as, bar_access->addr, MEMTXATTRS_UNSPECIFIED,
+   (uint8_t *)&bar_access->val, bar_access->size, 
true);
+
+if (res != MEMTX_OK) {
+error_setg(errp, "Could not per

[Qemu-devel] [RFC v3 PATCH 24/45] multi-process: remote: add setup_devices and setup_drive msg processing

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Receive by remote side the configuration messages and build the device
object from JSON device descriptions.

Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
---
 v1 -> v2:
   - for new command line suboptions with libvirtd support, clean
 the options before creating drives/devices
   - use default pci bus/address for now

 include/hw/qdev-core.h |   2 +
 qdev-monitor.c |   2 +-
 remote/remote-main.c   | 231 +
 3 files changed, 234 insertions(+), 1 deletion(-)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 136df77..2f81894 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -360,6 +360,8 @@ BusState *qdev_get_parent_bus(DeviceState *dev);
 
 DeviceState *qdev_find_recursive(BusState *bus, const char *id);
 
+DeviceState *find_device_state(const char *id, Error **errp);
+
 /* Returns 0 to walk children, > 0 to skip walk, < 0 to terminate walk. */
 typedef int (qbus_walkerfn)(BusState *bus, void *opaque);
 typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque);
diff --git a/qdev-monitor.c b/qdev-monitor.c
index d6f7572..69e467e 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -1017,7 +1017,7 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, 
Error **errp)
 object_unref(OBJECT(dev));
 }
 
-static DeviceState *find_device_state(const char *id, Error **errp)
+DeviceState *find_device_state(const char *id, Error **errp)
 {
 Object *obj;
 
diff --git a/remote/remote-main.c b/remote/remote-main.c
index 8af284e..3e92a83 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -48,6 +48,21 @@
 #include "exec/memattrs.h"
 #include "exec/address-spaces.h"
 #include "remote/iohub.h"
+#include "qapi/qmp/qjson.h"
+#include "qapi/qmp/qobject.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
+#include "monitor/qdev.h"
+#include "qapi/qmp/qdict.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/blockdev.h"
+#include "block/block.h"
+#include "qapi/qmp/qstring.h"
+#include "hw/qdev-properties.h"
+#include "hw/scsi/scsi.h"
+#include "block/qdict.h"
+#include "qapi/qmp/qlist.h"
+#include "qemu/log.h"
 
 static ProxyLinkState *proxy_link;
 PCIDevice *remote_pci_dev;
@@ -138,6 +153,200 @@ fail:
 PUT_REMOTE_WAIT(wait);
 }
 
+static void process_device_add_msg(ProcMsg *msg)
+{
+Error *local_err = NULL;
+const char *json = (const char *)msg->data2;
+int wait = msg->fds[0];
+QObject *qobj = NULL;
+QDict *qdict = NULL;
+QemuOpts *opts = NULL;
+
+qobj = qobject_from_json(json, &local_err);
+if (local_err) {
+goto fail;
+}
+
+qdict = qobject_to(QDict, qobj);
+assert(qdict);
+
+opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &local_err);
+if (local_err) {
+goto fail;
+}
+
+(void)qdev_device_add(opts, &local_err);
+if (local_err) {
+goto fail;
+}
+
+fail:
+if (local_err) {
+error_report_err(local_err);
+/* TODO: communicate the exact error message to proxy */
+}
+
+notify_proxy(wait, 1);
+
+PUT_REMOTE_WAIT(wait);
+}
+
+static void process_device_del_msg(ProcMsg *msg)
+{
+Error *local_err = NULL;
+DeviceState *dev = NULL;
+const char *json = (const char *)msg->data2;
+int wait = msg->fds[0];
+QObject *qobj = NULL;
+QDict *qdict = NULL;
+const char *id;
+
+qobj = qobject_from_json(json, &local_err);
+if (local_err) {
+goto fail;
+}
+
+qdict = qobject_to(QDict, qobj);
+assert(qdict);
+
+id = qdict_get_try_str(qdict, "id");
+assert(id);
+
+dev = find_device_state(id, &local_err);
+if (local_err) {
+goto fail;
+}
+
+if (dev) {
+qdev_unplug(dev, &local_err);
+}
+
+fail:
+if (local_err) {
+error_report_err(local_err);
+/* TODO: communicate the exact error message to proxy */
+}
+
+notify_proxy(wait, 1);
+
+PUT_REMOTE_WAIT(wait);
+}
+
+static int init_drive(QDict *rqdict, Error **errp)
+{
+QemuOpts *opts;
+Error *local_error = NULL;
+
+if (rqdict != NULL && qdict_size(rqdict) > 0) {
+opts = qemu_opts_from_qdict(&qemu_drive_opts,
+rqdict, &local_error);
+if (!opts) {
+error_propagate(errp, local_error);
+return -EINVAL;
+}
+} else {
+return -EINVAL;
+}
+
+qemu_opt_unset(opts, "rid");
+qemu_opt_unset(opts, "socket");
+qemu_opt_unset(opts, "remote");
+qemu_opt_unset(opts, "command");
+
+if (drive_new(opts, IF_IDE, &local_error) == NULL) {
+error_propagate(errp, local_error);
+return -EINVAL;
+}
+
+return 0;
+}
+
+static int setup_drive(ProcMsg *msg, Error **errp)
+{
+QObject *obj;
+QDict *qdict;
+QString *qstr;
+Error *local_error = NULL;
+int rc = -EINVAL;
+
+if (!msg->data2) {
+return rc;
+

[Qemu-devel] [RFC v3 PATCH 27/45] multi-process: add processing of remote drive and device command line

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Add processing of command line options drive and device.
After remote devices are created along with their proxies,
signal the proxies to finish the configuration steps.

Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
Signed-off-by: Elena Ufimtseva 
---
 v1 -> v2:
   - change command line option for remote process drive/device to
 use existing -drive/-device options
   - process drive and device options only after non-remote devices
 and drives are added

 vl.c | 76 
 1 file changed, 76 insertions(+)

diff --git a/vl.c b/vl.c
index b426b32..f7dae56 100644
--- a/vl.c
+++ b/vl.c
@@ -32,6 +32,11 @@
 #include "qemu/uuid.h"
 #include "sysemu/seccomp.h"
 #include "sysemu/tcg.h"
+#include "qapi/qmp/qdict.h"
+#include "block/qdict.h"
+#include "qapi/qmp/qstring.h"
+#include "qapi/qmp/qjson.h"
+#include "qapi/qmp/qlist.h"
 
 #ifdef CONFIG_SDL
 #if defined(__APPLE__) || defined(main)
@@ -1135,11 +1140,43 @@ static int cleanup_add_fd(void *opaque, QemuOpts *opts, 
Error **errp)
 #define MTD_OPTS ""
 #define SD_OPTS ""
 
+#if defined(CONFIG_MPQEMU)
+static int rdrive_init_func(void *opaque, QemuOpts *opts, Error **errp)
+{
+DeviceState *dev;
+
+dev = qdev_remote_add(opts, false /* this is drive */, errp);
+if (!dev) {
+error_setg(errp, "qdev_remote_add failed for drive.");
+return -1;
+}
+object_unref(OBJECT(dev));
+return 0;
+}
+#endif
+
+static int pass;
+
 static int drive_init_func(void *opaque, QemuOpts *opts, Error **errp)
 {
 BlockInterfaceType *block_default_type = opaque;
 
+#if defined(CONFIG_MPQEMU)
+const char *remote;
+
+remote = qemu_opt_get(opts, "remote");
+if (pass && remote) {
+return rdrive_init_func(opaque, opts, errp);
+} else {
+if (!remote && !pass) {
+drive_new(opts, *block_default_type, errp);
+}
+}
+
+return 0;
+#else
 return drive_new(opts, *block_default_type, errp) == NULL;
+#endif
 }
 
 static int drive_enable_snapshot(void *opaque, QemuOpts *opts, Error **errp)
@@ -2184,10 +2221,35 @@ static int device_help_func(void *opaque, QemuOpts 
*opts, Error **errp)
 return qdev_device_help(opts);
 }
 
+#if defined(CONFIG_MPQEMU)
+static int rdevice_init_func(void *opaque, QemuOpts *opts, Error **errp)
+{
+DeviceState *dev;
+
+dev = qdev_remote_add(opts, true /* this is device */, errp);
+if (!dev) {
+error_setg(errp, "qdev_remote_add failed for device.");
+return -1;
+}
+object_unref(OBJECT(dev));
+return 0;
+}
+#endif
+
 static int device_init_func(void *opaque, QemuOpts *opts, Error **errp)
 {
 DeviceState *dev;
 
+#if defined(CONFIG_MPQEMU)
+const char *remote;
+
+remote = qemu_opt_get(opts, "remote");
+if (remote) {
+/* This will be a remote process */
+return rdevice_init_func(opaque, opts, errp);
+}
+#endif
+
 dev = qdev_device_add(opts, errp);
 if (!dev) {
 return -1;
@@ -4367,6 +4429,17 @@ int main(int argc, char **argv, char **envp)
 /* Check if IGD GFX passthrough. */
 igd_gfx_passthru();
 
+#if defined(CONFIG_MPQEMU)
+/*
+ * Parse the list for remote drives here as we launch PCIProxyDev here and
+ * need PCI host initialized. As a TODO: could defer init of PCIProxyDev 
instead.
+ */
+if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func,
+  &machine_class->block_default_type, &error_fatal)) {
+exit(0);
+}
+#endif
+
 /* init generic devices */
 rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE);
 qemu_opts_foreach(qemu_find_opts("device"),
@@ -4424,6 +4497,9 @@ int main(int argc, char **argv, char **envp)
 qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
 qemu_run_machine_init_done_notifiers();
 
+#if defined(CONFIG_MPQEMU)
+qdev_proxy_fire();
+#endif
 if (rom_check_and_register_reset() != 0) {
 error_report("rom check and register reset failed");
 exit(1);
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 12/45] multi-process: remote process initialization

2019-09-03 Thread Jagannathan Raman
Adds the handler to process message from QEMU,
Initialize remote process main loop, handles SYNC_SYSMEM
message by updating its "system_memory" container using
shared file descriptors received from QEMU.

Signed-off-by: John G Johnson 
Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
---
 v1 -> v2:
   - Separate thread for message processing is removed

 v2 -> v3:
   - Added multi-channel support in the remote end

 remote/remote-main.c | 81 
 1 file changed, 81 insertions(+)

diff --git a/remote/remote-main.c b/remote/remote-main.c
index 97dd832..72866ec 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -23,6 +23,8 @@
  */
 
 #include 
+#include 
+#include 
 
 #include "qemu/osdep.h"
 #include "qemu/module.h"
@@ -31,12 +33,91 @@
 #include "hw/boards.h"
 #include "hw/qdev-core.h"
 #include "qemu/main-loop.h"
+#include "remote/memory.h"
+#include "io/proxy-link.h"
+#include "qapi/error.h"
+#include "qemu/main-loop.h"
+#include "sysemu/cpus.h"
+#include "qemu-common.h"
+#include "hw/pci/pci.h"
+#include "qemu/thread.h"
+#include "qemu/main-loop.h"
+#include "qemu/config-file.h"
+#include "sysemu/sysemu.h"
+#include "block/block.h"
+
+static ProxyLinkState *proxy_link;
+PCIDevice *remote_pci_dev;
+
+static void process_msg(GIOCondition cond, ProcChannel *chan)
+{
+ProcMsg *msg = NULL;
+Error *err = NULL;
+
+if ((cond & G_IO_HUP) || (cond & G_IO_ERR)) {
+error_setg(&err, "socket closed, cond is %d", cond);
+goto finalize_loop;
+}
+
+msg = g_malloc0(sizeof(ProcMsg));
+
+if (proxy_proc_recv(proxy_link, msg, chan) < 0) {
+error_setg(&err, "Failed to receive message");
+goto finalize_loop;
+}
+
+switch (msg->cmd) {
+case INIT:
+break;
+case CONF_WRITE:
+break;
+case CONF_READ:
+break;
+default:
+error_setg(&err, "Unknown command");
+goto finalize_loop;
+}
+
+g_free(msg);
+
+return;
+
+finalize_loop:
+error_report_err(err);
+g_free(msg);
+proxy_link_finalize(proxy_link);
+proxy_link = NULL;
+}
 
 int main(int argc, char *argv[])
 {
+Error *err = NULL;
+
 module_call_init(MODULE_INIT_QOM);
 
+bdrv_init_with_whitelist();
+
+if (qemu_init_main_loop(&err)) {
+error_report_err(err);
+return -EBUSY;
+}
+
+qemu_init_cpu_loop();
+
+page_size_init();
+
 current_machine = MACHINE(REMOTE_MACHINE(object_new(TYPE_REMOTE_MACHINE)));
 
+proxy_link = proxy_link_create();
+if (!proxy_link) {
+printf("Could not create proxy link\n");
+return -1;
+}
+
+proxy_link_init_channel(proxy_link, &proxy_link->com, STDIN_FILENO);
+proxy_link_set_callback(proxy_link, process_msg);
+
+start_handler(proxy_link);
+
 return 0;
 }
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 09/45] multi-process: setup PCI host bridge for remote device

2019-09-03 Thread Jagannathan Raman
PCI host bridge is setup for the remote device process. It is
implemented using remote-pcihost object. It is an extension of the PCI
host bridge setup by QEMU.
Remote-pcihost configures a PCI bus which could be used by the remote
 PCI device to latch on to.

Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
Signed-off-by: Elena Ufimtseva 
---
 hw/pci/Makefile.objs |  2 +-
 include/remote/pcihost.h | 59 ++
 remote/Makefile.objs |  1 +
 remote/pcihost.c | 84 
 4 files changed, 145 insertions(+), 1 deletion(-)
 create mode 100644 include/remote/pcihost.h
 create mode 100644 remote/pcihost.c

diff --git a/hw/pci/Makefile.objs b/hw/pci/Makefile.objs
index 955be54..90693a7 100644
--- a/hw/pci/Makefile.objs
+++ b/hw/pci/Makefile.objs
@@ -13,6 +13,6 @@ common-obj-$(CONFIG_PCI_EXPRESS) += pcie_port.o pcie_host.o
 common-obj-$(call lnot,$(CONFIG_PCI)) += pci-stub.o
 common-obj-$(CONFIG_ALL) += pci-stub.o
 
-remote-pci-obj-$(CONFIG_MPQEMU) += pci.o pci_bridge.o
+remote-pci-obj-$(CONFIG_MPQEMU) += pci.o pci_bridge.o pci_host.o pcie_host.o
 remote-pci-obj-$(CONFIG_MPQEMU) += msi.o msix.o
 remote-pci-obj-$(CONFIG_MPQEMU) += pcie.o
diff --git a/include/remote/pcihost.h b/include/remote/pcihost.h
new file mode 100644
index 000..b3c711d
--- /dev/null
+++ b/include/remote/pcihost.h
@@ -0,0 +1,59 @@
+/*
+ * PCI Host for remote device
+ *
+ * Copyright 2019, Oracle and/or its affiliates.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef REMOTE_PCIHOST_H
+#define REMOTE_PCIHOST_H
+
+#include 
+#include 
+
+#include "exec/memory.h"
+#include "hw/pci/pcie_host.h"
+
+#define TYPE_REMOTE_HOST_DEVICE "remote-pcihost"
+#define REMOTE_HOST_DEVICE(obj) \
+OBJECT_CHECK(RemPCIHost, (obj), TYPE_REMOTE_HOST_DEVICE)
+
+typedef struct RemPCIHost {
+/*< private >*/
+PCIExpressHost parent_obj;
+/*< public >*/
+
+/*
+ * Memory Controller Hub (MCH) may not be necessary for the emulation
+ * program. The two important reasons for implementing a PCI host in the
+ * emulation program are:
+ * - Provide a PCI bus for IO devices
+ * - Enable translation of guest PA to the PCI bar regions
+ *
+ * For both the above mentioned purposes, it doesn't look like we would
+ * need the MCH
+ */
+
+MemoryRegion *mr_pci_mem;
+MemoryRegion *mr_sys_mem;
+MemoryRegion *mr_sys_io;
+} RemPCIHost;
+
+#endif
diff --git a/remote/Makefile.objs b/remote/Makefile.objs
index a9b2256..2757f5a 100644
--- a/remote/Makefile.objs
+++ b/remote/Makefile.objs
@@ -1 +1,2 @@
 remote-pci-obj-$(CONFIG_MPQEMU) += remote-main.o
+remote-pci-obj-$(CONFIG_MPQEMU) += pcihost.o
diff --git a/remote/pcihost.c b/remote/pcihost.c
new file mode 100644
index 000..bcdd214
--- /dev/null
+++ b/remote/pcihost.c
@@ -0,0 +1,84 @@
+/*
+ * Remote PCI host device
+ *
+ * Copyright 2019, Oracle and/or its affiliates.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, A

[Qemu-devel] [RFC v3 PATCH 20/45] multi-process: Synchronize remote memory

2019-09-03 Thread Jagannathan Raman
Add memory-listener object which is used to keep the view of the RAM
in sync between QEMU and remote process.
A MemoryListener is registered for system-memory AddressSpace. The
listener sends SYNC_SYSMEM message to the remote process when memory
listener commits the changes to memory, the remote process receives
the message and processes it in the handler for SYNC_SYSMEM message.

Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
Signed-off-by: Elena Ufimtseva 
---
 v2 -> v3:
   - Refactored code to obtain fd from host address, added
 get_fd_from_hostaddr().
   - Discovered a bug which results in invalid FDs (-1) being
 sent over to the remote process. Fixed this by checking
 if the FD value is valid before sending over to remote.

 Makefile.target|   1 +
 hw/proxy/memory-sync.c | 226 +
 hw/proxy/qemu-proxy.c  |   5 +
 include/hw/proxy/memory-sync.h |  51 ++
 include/hw/proxy/qemu-proxy.h  |   2 +
 remote/remote-main.c   |  11 ++
 6 files changed, 296 insertions(+)
 create mode 100644 hw/proxy/memory-sync.c
 create mode 100644 include/hw/proxy/memory-sync.h

diff --git a/Makefile.target b/Makefile.target
index 931ee80..3aa2ac8 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -125,6 +125,7 @@ obj-$(CONFIG_TCG) += fpu/softfloat.o
 obj-y += target/$(TARGET_BASE_ARCH)/
 obj-y += disas.o
 obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
+obj-$(CONFIG_MPQEMU) += hw/proxy/memory-sync.o
 LIBS := $(libs_cpu) $(LIBS)
 
 remote-pci-tgt-obj-$(CONFIG_MPQEMU) += accel/stubs/kvm-stub.o
diff --git a/hw/proxy/memory-sync.c b/hw/proxy/memory-sync.c
new file mode 100644
index 000..5e57784
--- /dev/null
+++ b/hw/proxy/memory-sync.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2019, Oracle and/or its affiliates.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+
+#include "qemu/osdep.h"
+#include "qemu/compiler.h"
+#include "qemu/int128.h"
+#include "qemu/range.h"
+#include "exec/memory.h"
+#include "exec/cpu-common.h"
+#include "cpu.h"
+#include "exec/ram_addr.h"
+#include "exec/address-spaces.h"
+#include "io/proxy-link.h"
+#include "hw/proxy/memory-sync.h"
+
+static const TypeInfo remote_mem_sync_type_info = {
+.name  = TYPE_MEMORY_LISTENER,
+.parent= TYPE_OBJECT,
+.instance_size = sizeof(RemoteMemSync),
+};
+
+static void remote_mem_sync_register_types(void)
+{
+type_register_static(&remote_mem_sync_type_info);
+}
+
+type_init(remote_mem_sync_register_types)
+
+static void proxy_ml_begin(MemoryListener *listener)
+{
+RemoteMemSync *sync = container_of(listener, RemoteMemSync, listener);
+int mrs;
+
+for (mrs = 0; mrs < sync->n_mr_sections; mrs++) {
+memory_region_unref(sync->mr_sections[mrs].mr);
+}
+
+g_free(sync->mr_sections);
+sync->mr_sections = NULL;
+sync->n_mr_sections = 0;
+}
+
+static int get_fd_from_hostaddr(uint64_t host, ram_addr_t *offset)
+{
+MemoryRegion *mr;
+ram_addr_t off;
+
+mr = memory_region_from_host((void *)(uintptr_t)host, &off);
+
+if (offset) {
+*offset = off;
+}
+
+return memory_region_get_fd(mr);
+}
+
+static bool proxy_mrs_can_merge(uint64_t host, uint64_t prev_host, size_t size)
+{
+bool merge;
+int fd1, fd2;
+
+fd1 = get_fd_from_hostaddr(host, NULL);
+
+fd2 = get_fd_from_hostaddr(prev_host, NULL);
+
+merge = (fd1 == fd2);
+
+merge &= ((prev_host + size) == host);
+
+return merge;
+}
+
+static void proxy_ml_region_addnop(MemoryListener *listener,
+   MemoryRegionSection *section)
+{
+RemoteMemSync *sync = container_of(listener, RemoteMemSync, listener);
+bool need_add = true;
+uint64_t mrs_size, mrs_gpa, mrs_page;
+uintptr_t mrs_host;
+RAMBlock *mrs_rb;
+MemoryRegionSection *prev_sec;
+
+if (!(memory_region_is_ram(section-

[Qemu-devel] [RFC v3 PATCH 25/45] multi-process: remote: use fd for socket from parent process

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
Signed-off-by: Elena Ufimtseva 
---
 remote/remote-main.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/remote/remote-main.c b/remote/remote-main.c
index 3e92a83..e284d5f 100644
--- a/remote/remote-main.c
+++ b/remote/remote-main.c
@@ -63,6 +63,7 @@
 #include "block/qdict.h"
 #include "qapi/qmp/qlist.h"
 #include "qemu/log.h"
+#include "qemu/cutils.h"
 
 static ProxyLinkState *proxy_link;
 PCIDevice *remote_pci_dev;
@@ -439,6 +440,7 @@ finalize_loop:
 int main(int argc, char *argv[])
 {
 Error *err = NULL;
+int fd = -1;
 
 module_call_init(MODULE_INIT_QOM);
 
@@ -461,7 +463,13 @@ int main(int argc, char *argv[])
 return -1;
 }
 
-proxy_link_init_channel(proxy_link, &proxy_link->com, STDIN_FILENO);
+fd = qemu_parse_fd(argv[1]);
+if (fd == -1) {
+printf("Failed to parse fd for remote process.\n");
+return -EINVAL;
+}
+
+proxy_link_init_channel(proxy_link, &proxy_link->com, fd);
 proxy_link_set_callback(proxy_link, process_msg);
 
 start_handler(proxy_link);
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 17/45] multi-process: modify BARs read/write to support dev_id

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
Reviewed-by: Liam Merwick 
---
 New patch in v3

 hw/proxy/qemu-proxy.c | 22 +++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index 44668bf..1021045 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -288,13 +288,16 @@ static void pci_proxy_dev_realize(PCIDevice *device, 
Error **errp)
 dev->init_proxy = init_proxy;
 }
 
-static void send_bar_access_msg(ProxyLinkState *proxy_link, MemoryRegion *mr,
+static void send_bar_access_msg(PCIProxyDev *dev, MemoryRegion *mr,
 bool write, hwaddr addr, uint64_t *val,
 unsigned size, bool memory)
 {
+ProxyLinkState *proxy_link;
 ProcMsg msg;
 int wait;
 
+proxy_link = dev->proxy_link;
+
 memset(&msg, 0, sizeof(ProcMsg));
 
 msg.bytestream = 0;
@@ -314,18 +317,31 @@ static void send_bar_access_msg(ProxyLinkState 
*proxy_link, MemoryRegion *mr,
 msg.fds[0] = wait;
 }
 
+if (dev->dev_id) {
+msg.size_id = strlen(dev->dev_id) + 1;
+msg.id = calloc(1, msg.size_id);
+memcpy(msg.id, dev->dev_id, msg.size_id);
+} else {
+msg.size_id = 0;
+}
+
 proxy_proc_send(proxy_link, &msg, proxy_link->com);
 
 if (!write) {
 *val = wait_for_remote(wait);
 PUT_REMOTE_WAIT(wait);
 }
+
+if (msg.id) {
+free(msg.id);
+}
+
 }
 
 void proxy_default_bar_write(PCIProxyDev *dev, MemoryRegion *mr, hwaddr addr,
  uint64_t val, unsigned size, bool memory)
 {
-send_bar_access_msg(dev->proxy_link, mr, true, addr, &val, size, memory);
+send_bar_access_msg(dev, mr, true, addr, &val, size, memory);
 }
 
 uint64_t proxy_default_bar_read(PCIProxyDev *dev, MemoryRegion *mr, hwaddr 
addr,
@@ -333,7 +349,7 @@ uint64_t proxy_default_bar_read(PCIProxyDev *dev, 
MemoryRegion *mr, hwaddr addr,
 {
 uint64_t val;
 
-send_bar_access_msg(dev->proxy_link, mr, false, addr, &val, size, memory);
+send_bar_access_msg(dev, mr, false, addr, &val, size, memory);
 
 return val;
 }
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 11/45] multi-process: setup memory manager for remote device

2019-09-03 Thread Jagannathan Raman
sync_sysmem_msg_t message format is defined. It is used to send
file descriptors of the RAM regions to remote device.
RAM on the remote device is configured with a set of file descriptors.
Old RAM regions are deleted and new regions, each with an fd, is
added to the RAM.

Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
Signed-off-by: Elena Ufimtseva 
---
 Makefile.target |  2 +
 include/io/proxy-link.h | 11 ++
 include/remote/memory.h | 34 +
 remote/memory.c | 99 +
 4 files changed, 146 insertions(+)
 create mode 100644 include/remote/memory.h
 create mode 100644 remote/memory.c

diff --git a/Makefile.target b/Makefile.target
index 42fb642..931ee80 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -137,6 +137,8 @@ remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/monitor.o
 remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/replay.o
 remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/xen-mapcache.o
 
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += remote/memory.o
+
 #
 # Linux user emulator target
 
diff --git a/include/io/proxy-link.h b/include/io/proxy-link.h
index b76c574..159c787 100644
--- a/include/io/proxy-link.h
+++ b/include/io/proxy-link.h
@@ -35,6 +35,8 @@
 #include "qemu/osdep.h"
 #include "qom/object.h"
 #include "qemu/thread.h"
+#include "exec/cpu-common.h"
+#include "exec/hwaddr.h"
 
 typedef struct ProxyLinkState ProxyLinkState;
 
@@ -53,12 +55,14 @@ typedef struct ProxyLinkState ProxyLinkState;
  * Following commands are supported:
  * CONF_READPCI config. space read
  * CONF_WRITE   PCI config. space write
+ * SYNC_SYSMEM  Shares QEMU's RAM with remote device's RAM
  *
  */
 typedef enum {
 INIT = 0,
 CONF_READ,
 CONF_WRITE,
+SYNC_SYSMEM,
 MAX,
 } proc_cmd_t;
 
@@ -75,12 +79,19 @@ typedef enum {
  *
  */
 typedef struct {
+hwaddr gpas[REMOTE_MAX_FDS];
+uint64_t sizes[REMOTE_MAX_FDS];
+ram_addr_t offsets[REMOTE_MAX_FDS];
+} sync_sysmem_msg_t;
+
+typedef struct {
 proc_cmd_t cmd;
 int bytestream;
 size_t size;
 
 union {
 uint64_t u64;
+sync_sysmem_msg_t sync_sysmem;
 } data1;
 
 int fds[REMOTE_MAX_FDS];
diff --git a/include/remote/memory.h b/include/remote/memory.h
new file mode 100644
index 000..0ffbca0
--- /dev/null
+++ b/include/remote/memory.h
@@ -0,0 +1,34 @@
+/*
+ * Memory manager for remote device
+ *
+ * Copyright 2019, Oracle and/or its affiliates.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef REMOTE_MEMORY_H
+#define REMOTE_MEMORY_H
+
+#include "qemu/osdep.h"
+#include "exec/hwaddr.h"
+#include "io/proxy-link.h"
+
+void remote_sysmem_reconfig(ProcMsg *msg, Error **errp);
+
+#endif
diff --git a/remote/memory.c b/remote/memory.c
new file mode 100644
index 000..6f87729
--- /dev/null
+++ b/remote/memory.c
@@ -0,0 +1,99 @@
+/*
+ * Memory manager for remote device
+ *
+ * Copyright 2019, Oracle and/or its affiliates.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHE

[Qemu-devel] [RFC v3 PATCH 22/45] multi-process: configure remote side devices

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Add functions to configure remote devices.

Signed-off-by: Elena Ufimtseva 
Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
---
 hw/proxy/qemu-proxy.c | 43 ++-
 include/hw/proxy/qemu-proxy.h |  2 ++
 include/io/proxy-link.h   |  4 
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index f92d29a..dea6784 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -50,8 +50,47 @@
 #include "qemu/event_notifier.h"
 #include "sysemu/kvm.h"
 #include "util/event_notifier-posix.c"
+#include "hw/boards.h"
+#include "include/qemu/log.h"
 
 static void pci_proxy_dev_realize(PCIDevice *dev, Error **errp);
+static void setup_irqfd(PCIProxyDev *dev);
+
+static void proxy_ready(PCIDevice *dev)
+{
+PCIProxyDev *pdev = PCI_PROXY_DEV(dev);
+
+setup_irqfd(pdev);
+}
+
+static void set_remote_opts(PCIDevice *dev, QDict *qdict, unsigned int cmd)
+{
+QString *qstr;
+ProcMsg msg;
+const char *str;
+PCIProxyDev *pdev;
+
+pdev = PCI_PROXY_DEV(dev);
+
+qstr = qobject_to_json(QOBJECT(qdict));
+str = qstring_get_str(qstr);
+
+memset(&msg, 0, sizeof(ProcMsg));
+
+msg.data2 = (uint8_t *)str;
+msg.cmd = cmd;
+msg.bytestream = 1;
+msg.size = qstring_get_length(qstr) + 1;
+msg.num_fds = 0;
+if (pdev->dev_id) {
+msg.id = (uint8_t *)pdev->dev_id;
+msg.size_id = strlen((char *)pdev->dev_id) + 1;
+}
+
+proxy_proc_send(pdev->proxy_link, &msg, pdev->proxy_link->com);
+
+return;
+}
 
 static int add_argv(char *command_str, char **argv, int argc)
 {
@@ -344,7 +383,6 @@ static void init_proxy(PCIDevice *dev, char *command, bool 
need_spawn, Error **e
 pdev->socket);
 
 configure_memory_sync(pdev->sync, pdev->proxy_link);
-setup_irqfd(pdev);
 }
 
 static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
@@ -364,6 +402,9 @@ static void pci_proxy_dev_realize(PCIDevice *device, Error 
**errp)
 dev->get_proxy_sock = get_proxy_sock;
 dev->init_proxy = init_proxy;
 dev->sync = REMOTE_MEM_SYNC(object_new(TYPE_MEMORY_LISTENER));
+
+dev->set_remote_opts = set_remote_opts;
+dev->proxy_ready = proxy_ready;
 }
 
 static void send_bar_access_msg(PCIProxyDev *dev, MemoryRegion *mr,
diff --git a/include/hw/proxy/qemu-proxy.h b/include/hw/proxy/qemu-proxy.h
index e73835e..4312f9e 100644
--- a/include/hw/proxy/qemu-proxy.h
+++ b/include/hw/proxy/qemu-proxy.h
@@ -28,6 +28,8 @@
 #include "io/proxy-link.h"
 #include "hw/proxy/memory-sync.h"
 #include "qemu/event_notifier.h"
+#include "hw/pci/pci.h"
+#include "block/qdict.h"
 
 #define TYPE_PCI_PROXY_DEV "pci-proxy-dev"
 
diff --git a/include/io/proxy-link.h b/include/io/proxy-link.h
index e70bf50..13fb312 100644
--- a/include/io/proxy-link.h
+++ b/include/io/proxy-link.h
@@ -70,6 +70,10 @@ typedef enum {
 BAR_WRITE,
 BAR_READ,
 SET_IRQFD,
+DEV_OPTS,
+DRIVE_OPTS,
+DEVICE_ADD,
+DEVICE_DEL,
 MAX,
 } proc_cmd_t;
 
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 21/45] multi-process: create IOHUB object to handle irq

2019-09-03 Thread Jagannathan Raman
IOHUB object is added to manage PCI IRQs. It uses KVM_IRQFD
ioctl to create irqfd to injecting PCI interrupts to the guest.
IOHUB object forwards the irqfd to the remote process. Remote process
uses this fd to directly send interrupts to the guest, bypassing QEMU.

Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
Signed-off-by: Elena Ufimtseva 
---
 Makefile.target   |   1 +
 hw/proxy/Makefile.objs|   1 -
 hw/proxy/qemu-proxy.c |  64 +
 include/hw/pci/pci_ids.h  |   3 +
 include/hw/proxy/qemu-proxy.h |   5 ++
 include/io/proxy-link.h   |   8 +++
 include/remote/iohub.h|  63 +
 include/remote/machine.h  |   2 +
 remote/Makefile.objs  |   1 +
 remote/iohub.c| 159 ++
 remote/machine.c  |  15 
 remote/remote-main.c  |   4 ++
 12 files changed, 325 insertions(+), 1 deletion(-)
 create mode 100644 include/remote/iohub.h
 create mode 100644 remote/iohub.c

diff --git a/Makefile.target b/Makefile.target
index 3aa2ac8..a0c00c6 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -126,6 +126,7 @@ obj-y += target/$(TARGET_BASE_ARCH)/
 obj-y += disas.o
 obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
 obj-$(CONFIG_MPQEMU) += hw/proxy/memory-sync.o
+obj-$(CONFIG_MPQEMU) += hw/proxy/qemu-proxy.o
 LIBS := $(libs_cpu) $(LIBS)
 
 remote-pci-tgt-obj-$(CONFIG_MPQEMU) += accel/stubs/kvm-stub.o
diff --git a/hw/proxy/Makefile.objs b/hw/proxy/Makefile.objs
index f562f5a..ca89109 100644
--- a/hw/proxy/Makefile.objs
+++ b/hw/proxy/Makefile.objs
@@ -1,2 +1 @@
-common-obj-$(CONFIG_MPQEMU) += qemu-proxy.o
 common-obj-$(CONFIG_MPQEMU) += proxy-lsi53c895a.o
diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index 158d8d7..f92d29a 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -27,6 +27,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "io/proxy-link.h"
@@ -44,6 +47,9 @@
 #include "hw/proxy/qemu-proxy.h"
 #include "hw/proxy/memory-sync.h"
 #include "qom/object.h"
+#include "qemu/event_notifier.h"
+#include "sysemu/kvm.h"
+#include "util/event_notifier-posix.c"
 
 static void pci_proxy_dev_realize(PCIDevice *dev, Error **errp);
 
@@ -251,6 +257,63 @@ static void pci_proxy_dev_register_types(void)
 
 type_init(pci_proxy_dev_register_types)
 
+static void proxy_intx_update(PCIDevice *pci_dev)
+{
+PCIProxyDev *dev = PCI_PROXY_DEV(pci_dev);
+PCIINTxRoute route;
+int pin = pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1;
+
+if (dev->irqfd.fd) {
+dev->irqfd.flags = KVM_IRQFD_FLAG_DEASSIGN;
+(void) kvm_vm_ioctl(kvm_state, KVM_IRQFD, &dev->irqfd);
+memset(&dev->irqfd, 0, sizeof(struct kvm_irqfd));
+}
+
+route = pci_device_route_intx_to_irq(pci_dev, pin);
+
+dev->irqfd.fd = event_notifier_get_fd(&dev->intr);
+dev->irqfd.resamplefd = event_notifier_get_fd(&dev->resample);
+dev->irqfd.gsi = route.irq;
+dev->irqfd.flags |= KVM_IRQFD_FLAG_RESAMPLE;
+(void) kvm_vm_ioctl(kvm_state, KVM_IRQFD, &dev->irqfd);
+}
+
+static void setup_irqfd(PCIProxyDev *dev)
+{
+PCIDevice *pci_dev = PCI_DEVICE(dev);
+ProcMsg msg;
+
+if (!dev->dev_id) {
+fprintf(stderr, "Cannot setup IRQFD. No dev_id\n");
+return;
+}
+
+event_notifier_init(&dev->intr, 0);
+event_notifier_init(&dev->resample, 0);
+
+memset(&msg, 0, sizeof(ProcMsg));
+msg.cmd = SET_IRQFD;
+msg.num_fds = 2;
+msg.fds[0] = event_notifier_get_fd(&dev->intr);
+msg.fds[1] = event_notifier_get_fd(&dev->resample);
+msg.data1.set_irqfd.intx =
+pci_get_byte(pci_dev->config + PCI_INTERRUPT_PIN) - 1;
+msg.size = sizeof(msg.data1);
+
+if (dev->dev_id) {
+msg.id = (uint8_t *)dev->dev_id;
+msg.size_id = strlen((char *)dev->dev_id) + 1;
+}
+
+proxy_proc_send(dev->proxy_link, &msg, dev->proxy_link->com);
+
+memset(&dev->irqfd, 0, sizeof(struct kvm_irqfd));
+
+proxy_intx_update(pci_dev);
+
+pci_device_set_intx_routing_notifier(pci_dev, proxy_intx_update);
+}
+
 static void init_proxy(PCIDevice *dev, char *command, bool need_spawn, Error 
**errp)
 {
 PCIProxyDev *pdev = PCI_PROXY_DEV(dev);
@@ -281,6 +344,7 @@ static void init_proxy(PCIDevice *dev, char *command, bool 
need_spawn, Error **e
 pdev->socket);
 
 configure_memory_sync(pdev->sync, pdev->proxy_link);
+setup_irqfd(pdev);
 }
 
 static void pci_proxy_dev_realize(PCIDevice *device, Error **errp)
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index 0abe27a..9cc5e28 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -191,6 +191,9 @@
 #define PCI_DEVICE_ID_SUN_SIMBA  0x5000
 #define PCI_DEVICE_ID_SUN_SABRE  0xa000
 
+#define PCI_VENDOR_ID_ORACLE 0x108e
+#define PCI_DEVICE_ID_REMOTE_IOHUB   0x

[Qemu-devel] [RFC v3 PATCH 14/45] mutli-process: build remote command line args

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
---
 New patch in v3

 hw/proxy/qemu-proxy.c | 80 +--
 include/hw/proxy/qemu-proxy.h |  2 +-
 2 files changed, 62 insertions(+), 20 deletions(-)

diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
index 0ec7bb6..e5fd4bb 100644
--- a/hw/proxy/qemu-proxy.c
+++ b/hw/proxy/qemu-proxy.c
@@ -45,47 +45,89 @@
 
 static void pci_proxy_dev_realize(PCIDevice *dev, Error **errp);
 
+static int add_argv(char *command_str, char **argv, int argc)
+{
+int max_args = 64;
+
+if (argc < max_args - 1) {
+argv[argc++] = command_str;
+argv[argc] = 0;
+} else {
+return 0;
+}
+
+return argc;
+}
+
+static int make_argv(char *command_str, char **argv, int argc)
+{
+int max_args = 64;
+
+char *p2 = strtok(command_str, " ");
+while (p2 && argc < max_args - 1) {
+argv[argc++] = p2;
+p2 = strtok(0, " ");
+}
+argv[argc] = 0;
+
+return argc;
+}
+
 int remote_spawn(PCIProxyDev *pdev, const char *command, Error **errp)
 {
-char *args[3];
 pid_t rpid;
 int fd[2] = {-1, -1};
 Error *local_error = NULL;
+char *argv[64];
+int argc = 0, _argc;
+char *sfd;
+char *exec_dir;
+int rc = -EINVAL;
 
 if (pdev->managed) {
 /* Child is forked by external program (such as libvirt). */
-return -1;
+return rc;
 }
 
 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) {
 error_setg(errp, "Unable to create unix socket.");
-return -1;
+return rc;
 }
+exec_dir = g_strdup_printf("%s/%s", qemu_get_exec_dir(), "qemu-scsi-dev");
+argc = add_argv(exec_dir, argv, argc);
+sfd = g_strdup_printf("%d", fd[1]);
+argc = add_argv(sfd, argv, argc);
+_argc = argc;
+argc = make_argv((char *)command, argv, argc);
+
 /* TODO: Restrict the forked process' permissions and capabilities. */
 rpid = qemu_fork(&local_error);
 
 if (rpid == -1) {
 error_setg(errp, "Unable to spawn emulation program.");
 close(fd[0]);
-close(fd[1]);
-return -1;
+goto fail;
 }
 
 if (rpid == 0) {
 close(fd[0]);
-
-args[0] = g_strdup(command);
-args[1] = g_strdup_printf("%d", fd[1]);
-args[2] = NULL;
-execvp(args[0], (char *const *)args);
+execvp(argv[0], (char *const *)argv);
 exit(1);
 }
 pdev->remote_pid = rpid;
-pdev->rsocket = fd[0];
+pdev->rsocket = fd[1];
+pdev->socket = fd[0];
 
+rc = 0;
+
+fail:
 close(fd[1]);
 
-return 0;
+for (int i = 0; i < _argc; i++) {
+g_free(argv[i]);
+}
+
+return rc;
 }
 
 static int get_proxy_sock(PCIDevice *dev)
@@ -94,7 +136,7 @@ static int get_proxy_sock(PCIDevice *dev)
 
 pdev = PCI_PROXY_DEV(dev);
 
-return pdev->rsocket;
+return pdev->socket;
 }
 
 static void set_proxy_sock(PCIDevice *dev, int socket)
@@ -103,7 +145,7 @@ static void set_proxy_sock(PCIDevice *dev, int socket)
 
 pdev = PCI_PROXY_DEV(dev);
 
-pdev->rsocket = socket;
+pdev->socket = socket;
 pdev->managed = true;
 
 }
@@ -198,16 +240,16 @@ static void pci_proxy_dev_register_types(void)
 
 type_init(pci_proxy_dev_register_types)
 
-static void init_proxy(PCIDevice *dev, char *command, Error **errp)
+static void init_proxy(PCIDevice *dev, char *command, bool need_spawn, Error 
**errp)
 {
 PCIProxyDev *pdev = PCI_PROXY_DEV(dev);
 Error *local_error = NULL;
 
 if (!pdev->managed) {
-if (command) {
-remote_spawn(pdev, command, &local_error);
-} else {
-return;
+if (need_spawn) {
+if (!remote_spawn(pdev, command, &local_error)) {
+return;
+}
 }
 } else {
 pdev->remote_pid = atoi(pdev->rid);
diff --git a/include/hw/proxy/qemu-proxy.h b/include/hw/proxy/qemu-proxy.h
index ee21818..3b37b65 100644
--- a/include/hw/proxy/qemu-proxy.h
+++ b/include/hw/proxy/qemu-proxy.h
@@ -63,7 +63,7 @@ typedef struct PCIProxyDev {
 
 void (*set_remote_opts) (PCIDevice *dev, QDict *qdict, unsigned int cmd);
 void (*proxy_ready) (PCIDevice *dev);
-void (*init_proxy) (PCIDevice *pdev, char *command, Error **errp);
+void (*init_proxy) (PCIDevice *dev, char *command, bool need_spawn, Error 
**errp);
 
 } PCIProxyDev;
 
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 06/45] multi-process: build system for remote device process

2019-09-03 Thread Jagannathan Raman
Modify Makefile to support the building of the remote
device process. Implements main() function of remote
device process.

Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
Signed-off-by: Elena Ufimtseva 
---
 Makefile|  2 ++
 Makefile.objs   | 22 +
 Makefile.target | 51 +++--
 backends/Makefile.objs  |  2 ++
 block/Makefile.objs |  2 ++
 hw/Makefile.objs|  7 +++
 hw/block/Makefile.objs  |  2 ++
 hw/core/Makefile.objs   | 15 +++
 hw/nvram/Makefile.objs  |  2 ++
 hw/pci/Makefile.objs|  4 
 hw/scsi/Makefile.objs   |  2 ++
 migration/Makefile.objs |  2 ++
 qom/Makefile.objs   |  4 
 remote/Makefile.objs|  1 +
 remote/remote-main.c| 35 +
 stubs/replay.c  |  4 
 16 files changed, 155 insertions(+), 2 deletions(-)
 create mode 100644 remote/Makefile.objs
 create mode 100644 remote/remote-main.c

diff --git a/Makefile b/Makefile
index 85862fb..3c9d946 100644
--- a/Makefile
+++ b/Makefile
@@ -427,6 +427,8 @@ dummy := $(call unnest-vars,, \
 qom-obj-y \
 io-obj-y \
 common-obj-y \
+remote-pci-obj-y \
+remote-lsi-obj-y \
 common-obj-m \
 ui-obj-y \
 ui-obj-m \
diff --git a/Makefile.objs b/Makefile.objs
index 6a143dc..0668509 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -21,6 +21,28 @@ block-obj-$(CONFIG_REPLICATION) += replication.o
 
 block-obj-m = block/
 
+#
+# remote-pci-obj-y is common code used by remote devices
+
+remote-pci-obj-$(CONFIG_MPQEMU) += hw/
+remote-pci-obj-$(CONFIG_MPQEMU) += qom/
+remote-pci-obj-$(CONFIG_MPQEMU) += backends/
+remote-pci-obj-$(CONFIG_MPQEMU) += block/
+remote-pci-obj-$(CONFIG_MPQEMU) += migration/
+remote-pci-obj-$(CONFIG_MPQEMU) += remote/
+
+remote-pci-obj-$(CONFIG_MPQEMU) += cpus-common.o
+remote-pci-obj-$(CONFIG_MPQEMU) += dma-helpers.o
+remote-pci-obj-$(CONFIG_MPQEMU) += blockdev.o
+remote-pci-obj-$(CONFIG_MPQEMU) += qdev-monitor.o
+remote-pci-obj-$(CONFIG_MPQEMU) += bootdevice.o
+remote-pci-obj-$(CONFIG_MPQEMU) += iothread.o
+
+##
+# remote-lsi-obj-y is code used to implement remote LSI device
+
+remote-lsi-obj-$(CONFIG_MPQEMU) += hw/
+
 ###
 # crypto-obj-y is code used by both qemu system emulation and qemu-img
 
diff --git a/Makefile.target b/Makefile.target
index 933b274..42fb642 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -36,7 +36,12 @@ QEMU_PROG_BUILD = $(QEMU_PROG)
 endif
 endif
 
-PROGS=$(QEMU_PROG) $(QEMU_PROGW)
+ifdef CONFIG_MPQEMU
+SCSI_DEV_PROG=qemu-scsi-dev
+SCSI_DEV_BUILD = $(SCSI_DEV_PROG)
+endif
+
+PROGS=$(QEMU_PROG) $(QEMU_PROGW) $(SCSI_DEV_PROG)
 STPFILES=
 
 # Makefile Tests
@@ -122,6 +127,16 @@ obj-y += disas.o
 obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
 LIBS := $(libs_cpu) $(LIBS)
 
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += accel/stubs/kvm-stub.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += accel/stubs/tcg-stub.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += accel/stubs/hax-stub.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += accel/stubs/whpx-stub.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/vl-stub.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/net-stub.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/monitor.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/replay.o
+remote-pci-tgt-obj-$(CONFIG_MPQEMU) += stubs/xen-mapcache.o
+
 #
 # Linux user emulator target
 
@@ -178,6 +193,17 @@ endif # CONFIG_SOFTMMU
 dummy := $(call unnest-vars,,obj-y)
 all-obj-y := $(obj-y)
 
+dummy := $(call unnest-vars,..,remote-pci-tgt-obj-y)
+all-remote-pci-obj-y := $(remote-pci-tgt-obj-y)
+
+all-remote-pci-obj-y += memory.o
+all-remote-pci-obj-y += exec.o
+all-remote-pci-obj-y += ioport.o
+all-remote-pci-obj-y += cpus.o
+
+remote-pci-obj-y :=
+remote-lsi-obj-y :=
+
 include $(SRC_PATH)/Makefile.objs
 dummy := $(call unnest-vars,.., \
authz-obj-y \
@@ -189,7 +215,10 @@ dummy := $(call unnest-vars,.., \
qom-obj-y \
io-obj-y \
common-obj-y \
-   common-obj-m)
+   common-obj-m \
+   remote-pci-obj-y \
+   remote-lsi-obj-y)
+
 all-obj-y += $(common-obj-y)
 all-obj-y += $(qom-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(authz-obj-y)
@@ -198,8 +227,19 @@ all-obj-$(CONFIG_USER_ONLY) += $(crypto-user-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y)
 
+all-remote-pci-obj-y += $(authz-obj-y)
+all-remote-pci-obj-y += $(block-obj-y)
+all-remote-pci-obj-y += $(crypto-obj-y)
+all-remote-pci-obj-y += $(io-obj-y)
+all-remote-pci-obj-y += $(chardev-obj-y)
+all-remo

[Qemu-devel] [RFC v3 PATCH 07/45] multi-process: define proxy-link object

2019-09-03 Thread Jagannathan Raman
Defines proxy-link object which forms the communication link between
QEMU & emulation program.
Adds functions to configure members of proxy-link object instance.
Adds functions to send and receive messages over the communication
channel.
Adds GMainLoop to handle events received on the communication channel.

Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
Signed-off-by: Elena Ufimtseva 
---
 v1 -> v2:
   - Use default context for main loop instead of a new context

 v2 -> v3:
   - Enabled multi-channel support in the communication link

 include/glib-compat.h   |   4 +
 include/io/proxy-link.h | 147 
 io/Makefile.objs|   2 +
 io/proxy-link.c | 292 
 4 files changed, 445 insertions(+)
 create mode 100644 include/io/proxy-link.h
 create mode 100644 io/proxy-link.c

diff --git a/include/glib-compat.h b/include/glib-compat.h
index 1291628..6189b9a 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -19,12 +19,16 @@
 /* Ask for warnings for anything that was marked deprecated in
  * the defined version, or before. It is a candidate for rewrite.
  */
+#ifndef GLIB_VERSION_MIN_REQUIRED
 #define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_40
+#endif
 
 /* Ask for warnings if code tries to use function that did not
  * exist in the defined version. These risk breaking builds
  */
+#ifndef GLIB_VERSION_MAX_ALLOWED
 #define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_40
+#endif
 
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
diff --git a/include/io/proxy-link.h b/include/io/proxy-link.h
new file mode 100644
index 000..ee78cdd
--- /dev/null
+++ b/include/io/proxy-link.h
@@ -0,0 +1,147 @@
+/*
+ * Communication channel between QEMU and remote device process
+ *
+ * Copyright 2019, Oracle and/or its affiliates.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef PROXY_LINK_H
+#define PROXY_LINK_H
+
+#include 
+#include 
+#include 
+#include 
+
+#include "qemu/osdep.h"
+#include "qom/object.h"
+#include "qemu/thread.h"
+
+typedef struct ProxyLinkState ProxyLinkState;
+
+#define TYPE_PROXY_LINK "proxy-link"
+#define PROXY_LINK(obj) \
+OBJECT_CHECK(ProxyLinkState, (obj), TYPE_PROXY_LINK)
+
+#define REMOTE_MAX_FDS 8
+
+#define PROC_HDR_SIZE offsetof(ProcMsg, data1.u64)
+
+/*
+ * proc_cmd_t enum type to specify the command to be executed on the remote
+ * device
+ *
+ * Following commands are supported:
+ * CONF_READPCI config. space read
+ * CONF_WRITE   PCI config. space write
+ *
+ */
+typedef enum {
+INIT = 0,
+CONF_READ,
+CONF_WRITE,
+MAX,
+} proc_cmd_t;
+
+/*
+ * ProcMsg Format of the message sent to the remote device from QEMU
+ *
+ * cmd The remote command
+ * bytestream  Indicates if the data to be shared is structured (data1)
+ * or unstructured (data2)
+ * sizeSize of the data to be shared
+ * data1   Structured data
+ * fds File descriptors to be shared with remote device
+ * data2   Unstructured data
+ *
+ */
+typedef struct {
+proc_cmd_t cmd;
+int bytestream;
+size_t size;
+
+union {
+uint64_t u64;
+} data1;
+
+int fds[REMOTE_MAX_FDS];
+int num_fds;
+
+uint8_t *data2;
+} ProcMsg;
+
+struct conf_data_msg {
+uint32_t addr;
+uint32_t val;
+int l;
+};
+
+/*
+ * ProcChannel defines the channel that make up the communication link
+ * between QEMU and remote process
+ *
+ * gsrc   GSource object to be used by loop
+ * gpfd   GPollFD object containing the socket & events to monitor
+ * sock   Socket to send/receive communication, same as the one in gpfd
+ * lock   Mutex to synchronize access to the channel
+ */
+
+typedef struct ProcChannel {
+GSource gsrc;
+GPollFD gpfd;
+int sock;
+QemuMutex lock;
+} ProcChannel;
+
+typedef void (*proxy_link_callback)(GIOCondition co

[Qemu-devel] [RFC v3 PATCH 00/45] Initial support of multi-process qemu

2019-09-03 Thread Jagannathan Raman
Started with the presentation in October 2017 made by Marc-Andre (Red Hat)
and Konrad Wilk (Oracle) [1], and continued by Jag's BoF at KVM Forum 2018,
the multi-process project is now a prototype and presented in this patchset.

This first series enables the emulation of lsi53c895a in a separate process.

We posted the Proof Of Concept patches [2] before the BoF session in 2018.
Subsequently, we posted RFC v1 [3] & RFC v2 [4] of this series. 

Thanks to the v1 & v2 review, we were able to incorporate the feedback into
our goals.

In the summer of 2019, we participated in a conference with folks at RedHat,
who provided us with feedback to improve the design of this project. 

We want to present version 3 of this series which incorporates the feedback
we received for v2 & the enhancements suggested in the conference. Following
are the improvements made in this series:
  - The command-line arguments are Orchestrator friendly. A new option
named "-remote" carries the command-line of the emulation process.
Added "rid" suboption to the "-device" option and moved "-drive"
option to the emulation process's command-line.
  - Redesigned Monitor interface allows direct access to the remote process,
thereby making it more scalable, maintainable & Orchestrator friendly.
We also enabled more monitor commands for the remote process.
  - Enabled the remote process to run multiple LSI controllers
  - Redesigned the communication link to support multiple channels. MMIO
transactions are carried out in a separate channel.
  - Fixed the bugs discovered during testing. Individual patches provide
the details of these fixes.

Following people contributed to this patchset:

John G Johnson 
Jagannathan Raman 
Elena Ufimtseva 
Kanth Ghatraju 

For full concept writeup about QEMU disaggregation refer to
docs/devel/qemu-multiprocess.txt. Please refer to 
docs/qemu-multiprocess.txt for usage information.

We are planning on making the following improvements in the future:
  - Live migration
  - Performance improvements
  - Libvirt support
  - Enforcement of security policies
  - blockdev support

We welcome all your ideas, concerns, and questions for this patchset.

Thank you!

[1]: 
http://events17.linuxfoundation.org/sites/events/files/slides/KVM%20FORUM%20multi-process.pdf
[1]: https://www.youtube.com/watch?v=Kq1-coHh7lg
[2]: https://www.mail-archive.com/qemu-devel@nongnu.org/msg566538.html
[3]: https://www.mail-archive.com/qemu-devel@nongnu.org/msg602285.html
[4]: https://www.mail-archive.com/qemu-devel@nongnu.org/msg624877.html

Elena Ufimtseva (20):
  multi-process: add a command line option for debug file
  multi-process: introduce proxy object
  mutli-process: build remote command line args
  multi-process: add support of device id to communication channel
  multi-process: modify BARs read/write to support dev_id
  multi-process: support dev id in config read/write
  multi-process: configure remote side devices
  multi-process: add qdev_proxy_add to create proxy devices
  multi-process: remote: add setup_devices and setup_drive msg
processing
  multi-process: remote: use fd for socket from parent process
  multi-process: remote: add create_done condition
  multi-process: add processing of remote drive and device command line
  multi-process: refractor vl.c code to re-use in remote
  multi-process: add remote option
  multi-process: add remote options parser
  multi-process: add parse_cmdline in remote process
  multi-process: add support for multiple devices
  multi-process: add heartbeat timer and signal handler
  multi-process: handle heartbeat messages in remote process
  multi-process: add configure and usage information

Jagannathan Raman (24):
  multi-process: memory: alloc RAM from file at offset
  multi-process: util: Add qemu_thread_cancel() to cancel running thread
  multi-process: Add stub functions to facilate build of multi-process
  multi-process: Add config option for multi-process QEMU
  multi-process: build system for remote device process
  multi-process: define proxy-link object
  multi-process: add functions to synchronize proxy and remote endpoints
  multi-process: setup PCI host bridge for remote device
  multi-process: setup a machine object for remote device process
  multi-process: setup memory manager for remote device
  multi-process: remote process initialization
  multi-process: PCI BAR read/write handling for proxy & remote
endpoints
  multi-process: Add LSI device proxy object
  multi-process: Synchronize remote memory
  multi-process: create IOHUB object to handle irq
  multi-process: Introduce build flags to separate remote process code
  multi-process: Use separate MMIO communication channel
  multi-process: perform device reset in the remote process
  multi-process/mon: stub functions to enable QMP module for remote
process
  multi-process/mon: build system for QMP module in remote process
  multi-process/mon: Refactor monitor/chardev functions out of vl

[Qemu-devel] [RFC v3 PATCH 15/45] multi-process: add support of device id to communication channel

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
---
 New patch in v3

 include/io/proxy-link.h |  3 +++
 io/proxy-link.c | 37 -
 2 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/include/io/proxy-link.h b/include/io/proxy-link.h
index 159c787..0785394 100644
--- a/include/io/proxy-link.h
+++ b/include/io/proxy-link.h
@@ -88,6 +88,7 @@ typedef struct {
 proc_cmd_t cmd;
 int bytestream;
 size_t size;
+size_t size_id;
 
 union {
 uint64_t u64;
@@ -98,6 +99,8 @@ typedef struct {
 int num_fds;
 
 uint8_t *data2;
+uint8_t *id;
+
 } ProcMsg;
 
 struct conf_data_msg {
diff --git a/io/proxy-link.c b/io/proxy-link.c
index 381a38e..6f60117 100644
--- a/io/proxy-link.c
+++ b/io/proxy-link.c
@@ -81,7 +81,7 @@ void proxy_link_finalize(ProxyLinkState *s)
 void proxy_proc_send(ProxyLinkState *s, ProcMsg *msg, ProcChannel *chan)
 {
 int rc;
-uint8_t *data;
+uint8_t *data, *buf = NULL;
 union {
 char control[CMSG_SPACE(REMOTE_MAX_FDS * sizeof(int))];
 struct cmsghdr align;
@@ -140,10 +140,19 @@ void proxy_proc_send(ProxyLinkState *s, ProcMsg *msg, 
ProcChannel *chan)
 data = (uint8_t *)msg + PROC_HDR_SIZE;
 }
 
+if (msg->size_id > 0) {
+buf = calloc(1, msg->size + msg->size_id);
+assert(buf);
+memcpy(buf, data, msg->size);
+memcpy(buf + msg->size, msg->id, msg->size_id);
+data = buf;
+}
 do {
-rc = write(sock, data, msg->size);
+rc = write(sock, data, msg->size + msg->size_id);
 } while (rc < 0 && (errno == EINTR || errno == EAGAIN));
 
+free(buf);
+
 qemu_mutex_unlock(lock);
 }
 
@@ -151,7 +160,7 @@ void proxy_proc_send(ProxyLinkState *s, ProcMsg *msg, 
ProcChannel *chan)
 int proxy_proc_recv(ProxyLinkState *s, ProcMsg *msg, ProcChannel *chan)
 {
 int rc;
-uint8_t *data;
+uint8_t *data, *buf = NULL;
 union {
 char control[CMSG_SPACE(REMOTE_MAX_FDS * sizeof(int))];
 struct cmsghdr align;
@@ -207,10 +216,28 @@ int proxy_proc_recv(ProxyLinkState *s, ProcMsg *msg, 
ProcChannel *chan)
 data = (uint8_t *)&msg->data1;
 }
 
-if (msg->size) {
+ if (msg->size) {
+if (msg->size_id > 0) {
+buf = calloc(1, msg->size + msg->size_id);
+data = buf;
+}
 do {
-rc = read(sock, data, msg->size);
+rc = read(sock, data, msg->size + msg->size_id);
 } while (rc < 0 && (errno == EINTR || errno == EAGAIN));
+if (rc < 0) {
+fprintf(stderr, "Read sock is an error!\n");
+return rc;
+}
+}
+if (msg->size && msg->bytestream) {
+memcpy(msg->data2, data, msg->size);
+} else {
+memcpy((uint8_t *)&msg->data1, data, msg->size);
+}
+
+if (msg->size_id > 0) {
+msg->id = calloc(1, msg->size_id);
+memcpy(msg->id, data + msg->size, msg->size_id);
 }
 
 qemu_mutex_unlock(lock);
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 13/45] multi-process: introduce proxy object

2019-09-03 Thread Jagannathan Raman
From: Elena Ufimtseva 

Defines a PCI Device proxy object as a parent of TYPE_PCI_DEVICE.
PCI Proxy Object is responsible for registering PCI BARs,i
MemoryRegionOps to handle access to the BARs and forwarding those
to the remote device.
PCI Proxy object intercepts config space reads and writes. In case
of pci config write it forwards it to the remote device using
communication channel set by proxy-link object.

Signed-off-by: Elena Ufimtseva 
Signed-off-by: Jagannathan Raman 
Signed-off-by: John G Johnson 
---
 hw/Makefile.objs  |   2 +
 hw/proxy/Makefile.objs|   1 +
 hw/proxy/qemu-proxy.c | 247 ++
 include/hw/proxy/qemu-proxy.h |  81 ++
 remote/remote-main.c  |  28 +
 5 files changed, 359 insertions(+)
 create mode 100644 hw/proxy/Makefile.objs
 create mode 100644 hw/proxy/qemu-proxy.c
 create mode 100644 include/hw/proxy/qemu-proxy.h

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 4e28053..e016100 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -44,6 +44,8 @@ endif
 common-obj-y += $(devices-dirs-y)
 obj-y += $(devices-dirs-y)
 
+common-obj-$(CONFIG_MPQEMU) += proxy/
+
 remote-pci-obj-$(CONFIG_MPQEMU) += core/
 remote-pci-obj-$(CONFIG_MPQEMU) += block/
 remote-pci-obj-$(CONFIG_MPQEMU) += pci/
diff --git a/hw/proxy/Makefile.objs b/hw/proxy/Makefile.objs
new file mode 100644
index 000..eb81624
--- /dev/null
+++ b/hw/proxy/Makefile.objs
@@ -0,0 +1 @@
+common-obj-$(CONFIG_MPQEMU) += qemu-proxy.o
diff --git a/hw/proxy/qemu-proxy.c b/hw/proxy/qemu-proxy.c
new file mode 100644
index 000..0ec7bb6
--- /dev/null
+++ b/hw/proxy/qemu-proxy.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2019, Oracle and/or its affiliates.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "io/proxy-link.h"
+#include "exec/memory.h"
+#include "exec/cpu-common.h"
+#include "exec/address-spaces.h"
+#include "qemu/int128.h"
+#include "qemu/range.h"
+#include "hw/pci/pci.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
+#include "qapi/qmp/qjson.h"
+#include "qapi/qmp/qstring.h"
+#include "sysemu/sysemu.h"
+#include "hw/proxy/qemu-proxy.h"
+
+static void pci_proxy_dev_realize(PCIDevice *dev, Error **errp);
+
+int remote_spawn(PCIProxyDev *pdev, const char *command, Error **errp)
+{
+char *args[3];
+pid_t rpid;
+int fd[2] = {-1, -1};
+Error *local_error = NULL;
+
+if (pdev->managed) {
+/* Child is forked by external program (such as libvirt). */
+return -1;
+}
+
+if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) {
+error_setg(errp, "Unable to create unix socket.");
+return -1;
+}
+/* TODO: Restrict the forked process' permissions and capabilities. */
+rpid = qemu_fork(&local_error);
+
+if (rpid == -1) {
+error_setg(errp, "Unable to spawn emulation program.");
+close(fd[0]);
+close(fd[1]);
+return -1;
+}
+
+if (rpid == 0) {
+close(fd[0]);
+
+args[0] = g_strdup(command);
+args[1] = g_strdup_printf("%d", fd[1]);
+args[2] = NULL;
+execvp(args[0], (char *const *)args);
+exit(1);
+}
+pdev->remote_pid = rpid;
+pdev->rsocket = fd[0];
+
+close(fd[1]);
+
+return 0;
+}
+
+static int get_proxy_sock(PCIDevice *dev)
+{
+PCIProxyDev *pdev;
+
+pdev = PCI_PROXY_DEV(dev);
+
+return pdev->rsocket;
+}
+
+static void set_proxy_sock(PCIDevice *dev, int socket)
+{
+PCIProxyDev *pdev;
+
+pdev = PCI_PROXY_DEV(dev);
+
+pdev->rsocket = socket;
+pdev->managed = true;
+
+}
+
+static int config_op_send(PCIProxyDev *dev, uint32_t addr, uint32_t *val, int 
l,
+  unsigned int op)
+{
+ProcMsg msg;
+struct conf_data_msg conf_data;
+int wait;
+
+memset(

[Qemu-devel] [RFC v3 PATCH 02/45] multi-process: util: Add qemu_thread_cancel() to cancel running thread

2019-09-03 Thread Jagannathan Raman
qemu_thread_cancel() added to destroy a given running thread.
This will be needed in the following patches.

Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
Signed-off-by: Elena Ufimtseva 
---
 include/qemu/thread.h|  1 +
 util/qemu-thread-posix.c | 10 ++
 2 files changed, 11 insertions(+)

diff --git a/include/qemu/thread.h b/include/qemu/thread.h
index 55d83a9..78791be 100644
--- a/include/qemu/thread.h
+++ b/include/qemu/thread.h
@@ -156,6 +156,7 @@ void qemu_thread_create(QemuThread *thread, const char 
*name,
 void *(*start_routine)(void *),
 void *arg, int mode);
 void *qemu_thread_join(QemuThread *thread);
+void qemu_thread_cancel(QemuThread *thread);
 void qemu_thread_get_self(QemuThread *thread);
 bool qemu_thread_is_self(QemuThread *thread);
 void qemu_thread_exit(void *retval);
diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
index 1bf5e65..7c89071 100644
--- a/util/qemu-thread-posix.c
+++ b/util/qemu-thread-posix.c
@@ -573,3 +573,13 @@ void *qemu_thread_join(QemuThread *thread)
 }
 return ret;
 }
+
+void qemu_thread_cancel(QemuThread *thread)
+{
+int err;
+
+err = pthread_cancel(thread->thread);
+if (err) {
+error_exit(err, __func__);
+}
+}
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 08/45] multi-process: add functions to synchronize proxy and remote endpoints

2019-09-03 Thread Jagannathan Raman
In some cases, for example MMIO read, QEMU has to wait for the remote to
complete a command before proceeding. An eventfd based mechanism is
added to synchronize QEMU & remote process.

Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
Signed-off-by: Elena Ufimtseva 
---
 v1 -> v2:
   - Added timeout to synchronization functions

 include/io/proxy-link.h |  8 
 io/proxy-link.c | 42 ++
 2 files changed, 50 insertions(+)

diff --git a/include/io/proxy-link.h b/include/io/proxy-link.h
index ee78cdd..b76c574 100644
--- a/include/io/proxy-link.h
+++ b/include/io/proxy-link.h
@@ -28,7 +28,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 
 #include "qemu/osdep.h"
 #include "qom/object.h"
@@ -133,11 +135,17 @@ struct ProxyLinkState {
 proxy_link_callback callback;
 };
 
+#define GET_REMOTE_WAIT eventfd(0, 0)
+#define PUT_REMOTE_WAIT(wait) close(wait)
+#define PROXY_LINK_WAIT_DONE 1
+
 ProxyLinkState *proxy_link_create(void);
 void proxy_link_finalize(ProxyLinkState *s);
 
 void proxy_proc_send(ProxyLinkState *s, ProcMsg *msg, ProcChannel *chan);
 int proxy_proc_recv(ProxyLinkState *s, ProcMsg *msg, ProcChannel *chan);
+uint64_t wait_for_remote(int efd);
+void notify_proxy(int fd, uint64_t val);
 
 void proxy_link_init_channel(ProxyLinkState *s, ProcChannel **chan, int fd);
 void proxy_link_destroy_channel(ProcChannel *chan);
diff --git a/io/proxy-link.c b/io/proxy-link.c
index 5eb9718..381a38e 100644
--- a/io/proxy-link.c
+++ b/io/proxy-link.c
@@ -31,6 +31,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include "qemu/module.h"
 #include "io/proxy-link.h"
@@ -216,6 +218,46 @@ int proxy_proc_recv(ProxyLinkState *s, ProcMsg *msg, 
ProcChannel *chan)
 return rc;
 }
 
+uint64_t wait_for_remote(int efd)
+{
+struct pollfd pfd = { .fd = efd, .events = POLLIN };
+uint64_t val;
+int ret;
+
+ret = poll(&pfd, 1, 1000);
+
+switch (ret) {
+case 0:
+qemu_log_mask(LOG_REMOTE_DEBUG, "Error wait_for_remote: Timed out\n");
+/* TODO: Kick-off error recovery */
+return ULLONG_MAX;
+case -1:
+qemu_log_mask(LOG_REMOTE_DEBUG, "Poll error wait_for_remote: %s\n",
+  strerror(errno));
+return ULLONG_MAX;
+default:
+if (read(efd, &val, sizeof(val)) == -1) {
+qemu_log_mask(LOG_REMOTE_DEBUG, "Error wait_for_remote: %s\n",
+  strerror(errno));
+return ULLONG_MAX;
+}
+}
+
+val = (val == ULLONG_MAX) ? val : (val - 1);
+
+return val;
+}
+
+void notify_proxy(int efd, uint64_t val)
+{
+val = (val == ULLONG_MAX) ? val : (val + 1);
+
+if (write(efd, &val, sizeof(val)) == -1) {
+qemu_log_mask(LOG_REMOTE_DEBUG, "Error notify_proxy: %s\n",
+  strerror(errno));
+}
+}
+
 static gboolean proxy_link_handler_prepare(GSource *gsrc, gint *timeout)
 {
 g_assert(timeout);
-- 
1.8.3.1




[Qemu-devel] [RFC v3 PATCH 04/45] multi-process: Add stub functions to facilate build of multi-process

2019-09-03 Thread Jagannathan Raman
Add stub functions that are needed during compile time but not in
runtime.

Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
Signed-off-by: Elena Ufimtseva 
---
 accel/stubs/kvm-stub.c|  5 +++
 accel/stubs/tcg-stub.c| 85 +++
 stubs/machine-init-done.c |  4 +++
 stubs/monitor.c   | 33 ++
 stubs/net-stub.c  | 31 +
 stubs/replay.c| 14 
 stubs/vl-stub.c   | 77 ++
 stubs/vmstate.c   | 20 +++
 stubs/xen-mapcache.c  | 22 
 9 files changed, 291 insertions(+)
 create mode 100644 stubs/net-stub.c
 create mode 100644 stubs/vl-stub.c
 create mode 100644 stubs/xen-mapcache.c

diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c
index 6feb66e..f129dfb 100644
--- a/accel/stubs/kvm-stub.c
+++ b/accel/stubs/kvm-stub.c
@@ -31,6 +31,7 @@ bool kvm_allowed;
 bool kvm_readonly_mem_allowed;
 bool kvm_ioeventfd_any_length_allowed;
 bool kvm_msi_use_devid;
+bool kvm_halt_in_kernel_allowed;
 
 int kvm_destroy_vcpu(CPUState *cpu)
 {
@@ -58,6 +59,10 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu)
 {
 }
 
+void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu)
+{
+}
+
 int kvm_cpu_exec(CPUState *cpu)
 {
 abort();
diff --git a/accel/stubs/tcg-stub.c b/accel/stubs/tcg-stub.c
index 76ae461..52722c7 100644
--- a/accel/stubs/tcg-stub.c
+++ b/accel/stubs/tcg-stub.c
@@ -16,11 +16,96 @@
 #include "tcg/tcg.h"
 #include "exec/cpu-common.h"
 #include "exec/exec-all.h"
+#include "translate-all.h"
+#include "exec/ram_addr.h"
+
+bool parallel_cpus;
 
 void tb_flush(CPUState *cpu)
 {
 }
 
+void tb_check_watchpoint(CPUState *cpu)
+{
+}
+
+void tb_invalidate_phys_range(ram_addr_t start, ram_addr_t end)
+{
+}
+
+void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
+   int is_cpu_write_access)
+{
+}
+
+void tb_invalidate_phys_page_fast(struct page_collection *pages,
+  tb_page_addr_t start, int len)
+{
+}
+
+void tlb_init(CPUState *cpu)
+{
+}
+
 void tlb_set_dirty(CPUState *cpu, target_ulong vaddr)
 {
 }
+
+void tlb_flush(CPUState *cpu)
+{
+}
+
+void tlb_flush_page(CPUState *cpu, target_ulong addr)
+{
+}
+
+void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length)
+{
+}
+
+void tcg_region_init(void)
+{
+}
+
+void tcg_register_thread(void)
+{
+}
+
+void tcg_flush_softmmu_tlb(CPUState *cs)
+{
+}
+
+void cpu_loop_exit_noexc(CPUState *cpu)
+{
+cpu->exception_index = -1;
+cpu_loop_exit(cpu);
+}
+
+void cpu_loop_exit(CPUState *cpu)
+{
+cpu->can_do_io = 1;
+siglongjmp(cpu->jmp_env, 1);
+}
+
+void cpu_reloading_memory_map(void)
+{
+}
+
+int cpu_exec(CPUState *cpu)
+{
+return 0;
+}
+
+void cpu_exec_step_atomic(CPUState *cpu)
+{
+}
+
+struct page_collection *
+page_collection_lock(tb_page_addr_t start, tb_page_addr_t end)
+{
+return NULL;
+}
+
+void page_collection_unlock(struct page_collection *set)
+{
+}
diff --git a/stubs/machine-init-done.c b/stubs/machine-init-done.c
index cd8e813..3deabc9 100644
--- a/stubs/machine-init-done.c
+++ b/stubs/machine-init-done.c
@@ -6,3 +6,7 @@ bool machine_init_done = true;
 void qemu_add_machine_init_done_notifier(Notifier *notify)
 {
 }
+
+void qemu_remove_machine_init_done_notifier(Notifier *notify)
+{
+}
diff --git a/stubs/monitor.c b/stubs/monitor.c
index c3e9a2e..75dafce 100644
--- a/stubs/monitor.c
+++ b/stubs/monitor.c
@@ -2,6 +2,12 @@
 #include "qapi/error.h"
 #include "qapi/qapi-emit-events.h"
 #include "monitor/monitor.h"
+#include "qapi/qapi-types-misc.h"
+#include "qapi/qapi-commands-misc.h"
+#include "qapi/qapi-types-qom.h"
+#include "qapi/qapi-commands-qdev.h"
+#include "hw/qdev-core.h"
+#include "sysemu/sysemu.h"
 
 __thread Monitor *cur_mon;
 
@@ -27,3 +33,30 @@ void monitor_init_hmp(Chardev *chr, bool use_readline)
 void qapi_event_emit(QAPIEvent event, QDict *qdict)
 {
 }
+
+int monitor_get_cpu_index(void)
+{
+return -ENOSYS;
+}
+int monitor_printf(Monitor *mon, const char *fmt, ...)
+{
+return -ENOSYS;
+}
+
+bool monitor_cur_is_qmp(void)
+{
+return false;
+}
+
+ObjectPropertyInfoList *qmp_device_list_properties(const char *typename,
+   Error **errp)
+{
+return NULL;
+}
+
+VMChangeStateEntry *qdev_add_vm_change_state_handler(DeviceState *dev,
+ VMChangeStateHandler *cb,
+ void *opaque)
+{
+return NULL;
+}
diff --git a/stubs/net-stub.c b/stubs/net-stub.c
new file mode 100644
index 000..cb2274b
--- /dev/null
+++ b/stubs/net-stub.c
@@ -0,0 +1,31 @@
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "net/net.h"
+
+int qemu_find_net_clients_except(const char *id, NetClientState **ncs,
+ NetClientDriver type, int max)
+{
+return -ENOSYS;
+}
+
+N

[Qemu-devel] [RFC v3 PATCH 05/45] multi-process: Add config option for multi-process QEMU

2019-09-03 Thread Jagannathan Raman
Add a configuration option to separate multi-process code

Signed-off-by: John G Johnson 
Signed-off-by: Jagannathan Raman 
Signed-off-by: Elena Ufimtseva 
---
 configure | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/configure b/configure
index 714e7fb..b467441 100755
--- a/configure
+++ b/configure
@@ -499,6 +499,7 @@ docker="no"
 debug_mutex="no"
 libpmem=""
 default_devices="yes"
+mpqemu="no"
 
 # cross compilers defaults, can be overridden with --cross-cc-ARCH
 cross_cc_aarch64="aarch64-linux-gnu-gcc"
@@ -1543,6 +1544,10 @@ for opt do
   ;;
   --disable-libpmem) libpmem=no
   ;;
+  --enable-mpqemu) mpqemu=yes
+  ;;
+  --disable-mpqemu) mpqemu=no
+  ;;
   *)
   echo "ERROR: unknown option $opt"
   echo "Try '$0 --help' for more information"
@@ -1842,6 +1847,7 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   capstonecapstone disassembler support
   debug-mutex mutex debugging support
   libpmem libpmem support
+  mpqemu  multi-process QEMU support
 
 NOTE: The object files are built at the place where configure is launched
 EOF
@@ -6481,6 +6487,7 @@ echo "docker$docker"
 echo "libpmem support   $libpmem"
 echo "libudev   $libudev"
 echo "default devices   $default_devices"
+echo "multiprocess QEMU $mpqemu"
 
 if test "$supported_cpu" = "no"; then
 echo
@@ -7279,6 +7286,10 @@ if test "$libpmem" = "yes" ; then
   echo "CONFIG_LIBPMEM=y" >> $config_host_mak
 fi
 
+if test "$mpqemu" = "yes" ; then
+  echo "CONFIG_MPQEMU=y" >> $config_host_mak
+fi
+
 if test "$bochs" = "yes" ; then
   echo "CONFIG_BOCHS=y" >> $config_host_mak
 fi
-- 
1.8.3.1




[Qemu-devel] [PATCH v2] libvhost-user: fix SLAVE_SEND_FD handling

2019-09-03 Thread Johannes Berg
From: Johannes Berg 

It doesn't look like this could possibly work properly since
VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD is defined to 10, but the
dev->protocol_features has a bitmap. I suppose the peer this
was tested with also supported VHOST_USER_PROTOCOL_F_LOG_SHMFD,
in which case the test would always be false, but nevertheless
the code seems wrong.

Use has_feature() to fix this.

Fixes: d84599f56c82 ("libvhost-user: support host notifier")
Signed-off-by: Johannes Berg 
---
 contrib/libvhost-user/libvhost-user.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/contrib/libvhost-user/libvhost-user.c 
b/contrib/libvhost-user/libvhost-user.c
index 6a02eaffc672..fcf4a8a00ed2 100644
--- a/contrib/libvhost-user/libvhost-user.c
+++ b/contrib/libvhost-user/libvhost-user.c
@@ -1097,7 +1097,8 @@ bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, 
int fd,
 
 vmsg.fd_num = fd_num;
 
-if ((dev->protocol_features & VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) == 0) {
+if (!has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD)) {
 return false;
 }
 
-- 
2.23.0




Re: [Qemu-devel] [PATCH] libvhost-user: fix SLAVE_SEND_FD handling

2019-09-03 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20190903195442.11199-1-johan...@sipsolutions.net/



Hi,

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

Type: series
Message-id: 20190903195442.11199-1-johan...@sipsolutions.net
Subject: [Qemu-devel] [PATCH] libvhost-user: fix SLAVE_SEND_FD handling

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
9da584f libvhost-user: fix SLAVE_SEND_FD handling

=== OUTPUT BEGIN ===
ERROR: code indent should never use tabs
#30: FILE: contrib/libvhost-user/libvhost-user.c:1101:
+^I^I VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD)) {$

total: 1 errors, 0 warnings, 9 lines checked

Commit 9da584f52360 (libvhost-user: fix SLAVE_SEND_FD handling) has style 
problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20190903195442.11199-1-johan...@sipsolutions.net/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[Qemu-devel] [PATCH] libvhost-user: fix SLAVE_SEND_FD handling

2019-09-03 Thread Johannes Berg
From: Johannes Berg 

It doesn't look like this could possibly work properly since
VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD is defined to 10, but the
dev->protocol_features has a bitmap. I suppose the peer this
was tested with also supported VHOST_USER_PROTOCOL_F_LOG_SHMFD,
in which case the test would always be false, but nevertheless
the code seems wrong.

Use has_feature() to fix this.

Fixes: d84599f56c82 ("libvhost-user: support host notifier")
Signed-off-by: Johannes Berg 
---
 contrib/libvhost-user/libvhost-user.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/contrib/libvhost-user/libvhost-user.c 
b/contrib/libvhost-user/libvhost-user.c
index 6a02eaffc672..e250e69abec9 100644
--- a/contrib/libvhost-user/libvhost-user.c
+++ b/contrib/libvhost-user/libvhost-user.c
@@ -1097,7 +1097,8 @@ bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, 
int fd,
 
 vmsg.fd_num = fd_num;
 
-if ((dev->protocol_features & VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) == 0) {
+if (!has_feature(dev->protocol_features,
+VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD)) {
 return false;
 }
 
-- 
2.23.0




Re: [Qemu-devel] [PATCH] block/nfs: add support for nfs_umount

2019-09-03 Thread Peter Lieven



> Am 03.09.2019 um 16:56 schrieb Kevin Wolf :
> 
> Am 03.09.2019 um 15:44 hat Peter Lieven geschrieben:
>> libnfs recently added support for unmounting. Add support
>> in Qemu too.
>> 
>> Signed-off-by: Peter Lieven 
> 
> Looks trivial enough to review even for me. :-)
> 
> Thanks, applied to the block branch.
> 
> Kevin


I am not sure what the reason is, but with this patch I sometimes run into 
nfs_process_read being called for a cdrom mounted from nfs after I ejected it 
(and the whole nfs client context is already destroyed).

It seems that the following fixes the issue. It might be that the nfs_umount 
call just reveals this bug. nfs_close is also doing sync I/O with the libnfs 
library. If we mount a nfs share we are doing everything with sync calls and 
then set up the aio stuff with nfs_set_events. I think that we need to stop the 
aio before we are executing the sync calls to nfs_close and nfs_umount.
Also not sure if holding the mutex is necessary here.

diff --git a/block/nfs.c b/block/nfs.c
index ffa6484c1a..cb2e0d375a 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -389,6 +389,10 @@ static void nfs_attach_aio_context(BlockDriverState *bs,
 static void nfs_client_close(NFSClient *client)
 {
 if (client->context) {
+qemu_mutex_lock(&client->mutex);
+aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
+   false, NULL, NULL, NULL, NULL);
+qemu_mutex_unlock(&client->mutex);
 if (client->fh) {
 nfs_close(client->context, client->fh);
 client->fh = NULL;
@@ -396,8 +400,6 @@ static void nfs_client_close(NFSClient *client)
 #ifdef LIBNFS_FEATURE_UMOUNT
 nfs_umount(client->context);
 #endif
-aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
-   false, NULL, NULL, NULL, NULL);
 nfs_destroy_context(client->context);
 client->context = NULL;
 }


Peter





Re: [Qemu-devel] [PATCH v6 0/4] 9p: Fix file ID collisions

2019-09-03 Thread Eric Blake
On 9/2/19 5:29 PM, Christian Schoenebeck via Qemu-devel wrote:

> === OUTPUT BEGIN ===
> 1/4 Checking commit bb69de63f788 (9p: Treat multiple devices on one
> export
> as an error) ERROR: Author email address is mangled by the mailing
> list
> #2:
> Author: Christian Schoenebeck via Qemu-devel 

 This is problematic since it ends up in the Author: field in git. Please
 find a way to fix that.
>>>
>>> Like in which way do you imagine that? And where is the actual practical
>>> problem? I mean every patch still has my signed-off-by tag with the
>>> correct
>>> email address ending up in git history.
>>
>> Yes, this only breaks Author: if the patch is applied from the list.

Except that many maintainers DO apply mail from the list (thanks to 'git
am').  Fixing patchew to unmunge things is an appealing idea, but would
not fix the problem for maintainers not cloning from patchew, so even if
patchew avoids the problem locally, it should still continue to warn
about the problem.

>>
>>> The cause for this issue is that the domain is configured to require DKIM
>>> signatures for all outgoing emails. That's why mailman replaces my address
>>> by "Christian Schoenebeck via Qemu-devel "
>>> placeholder since it could not provide a valid signature.

And when you know that mailman is going to munge your address, the fix
is to configure git to output 'From: correct name '
as the first line of the BODY of the message, since 'git am' favors the
unmunged From: from the body over the munged From: from the headers.


> 
>> So, this means that patchew will complain each time you post if we can't
>> find a proper way to address that... :-\
> 
> Well, mailman is handling this correctly. It replaces the "From:" field with 
> a 
> placeholder and instead adds my actual email address as "Reply-To:" field. 
> That's the common way to handle this on mailing lists, as also mentioned here:
> https://en.wikipedia.org/wiki/DMARC#From:_rewriting
> 
> So IMO patchew should automatically use the value of "Reply-To:" in that case 
> as author of patches instead.
> 
> Reducing security cannot be the solution.

No, there's no need to reduce security.  Just change your local git
configuration to produce a 'From:' line in the commit body..

>> How are you sending patches ? With git send-email ? If so, maybe you can
>> pass something like --from='"Christian Schoenebeck"
>> '. Since this is a different string, git will
>> assume you're sending someone else's patch : it will automatically add an
>> extra From: made out of the commit Author as recorded in the git tree.

I think it is probably as simple as a 'git config' command to tell git
to always put a 'From:' in the body of self-authored patches when using
git format-patch; however, as I don't suffer from munged emails, I
haven't actually tested what that setting would be.

> 
> I use "git format-patch ..." to dump the invidiual emails as raw email 
> sources 
> and then I'll send those raw emails from the command line. So I have even 
> more 
> control of what is exactly sent out and could of course also add custom email 
> header fields if required, if that would solve the situation somehow, i.e. 
> manually as first test and later in automated way. That's not the issue here.

Working around the problem does not require munging email headers, but
adding a line to the email body.

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



signature.asc
Description: OpenPGP digital signature


  1   2   3   4   >