[Qemu-devel] [PULL v2 for-1.7] Trivial patches for 2013-11-17

2013-11-17 Thread Michael Tokarev
Here's another pull request for the trivial-patches queue.
Since the previous pull request (which weren't pulled), I
removed a few patches which weren't marked for-1.7, and added
two more bugfixes on top (fixing python invocations).

What's left are either trivial stuff not affecting anything else,
or trivial bugfixes.

I'm not sending individual patches this time, because I've already
included them in the previous pull request (except of the 2 new
patches, for which I added Cc to sw@).

Please pull.

/mjt

The following changes since commit 964668b03d26f0b5baa5e5aff0c966f4fcb76e9e:

  Update version for 1.7.0-rc0 release (2013-11-06 21:49:39 -0800)

are available in the git repository at:

  git://git.corpit.ru/qemu.git trivial-patches

for you to fetch changes up to 0478f37ce258438d74164dd182b0ae125f174ec6:

  hw/i386/Makefile.obj: use $(PYTHON) to run .py scripts consistently 
(2013-11-17 00:30:14 +0400)


Alex Benn??e (1):
  .travis.yml: basic compile and check recipes

Antony Pavlov (1):
  vl: fix build when configured with no graphic support

Cole Robinson (1):
  pci-assign: Fix error_report of pci-stub message

Fam Zheng (1):
  qapi: Fix comment for create-type to match code.

Jan Krupa (4):
  qemu-char: add Czech characters to VNC keysyms
  qemu-char: add Czech keymap file
  qemu-char: add support for U-prefixed symbols
  qemu-char: add missing characters used in keymaps

Michael Tokarev (1):
  hw/i386/Makefile.obj: use $(PYTHON) to run .py scripts consistently

Stefan Hajnoczi (1):
  usb: drop unused USBNetState.inpkt field

Stefan Weil (3):
  qga: Fix compilation for old versions of MinGW
  console: Remove unused debug code
  configure: Use -B switch only for Python versions which support it

whitearchey (1):
  qga: Fix shutdown command of guest agent to work with SysV

 .travis.yml   |   71 +
 Makefile  |2 +-
 configure |9 +-
 hw/i386/Makefile.objs |2 +-
 hw/i386/kvm/pci-assign.c  |   36 ++---
 hw/usb/dev-network.c  |1 -
 pc-bios/keymaps/cz|   94 
 qapi-schema.json  |2 +-
 qga/commands-posix.c  |2 +-
 qga/vss-win32/requester.h |1 +
 ui/console.c  |   33 
 ui/keymaps.c  |6 +
 ui/vnc_keysym.h   |  373 +
 vl.c  |1 +
 14 files changed, 574 insertions(+), 59 deletions(-)
 create mode 100644 .travis.yml
 create mode 100644 pc-bios/keymaps/cz



[Qemu-devel] [PATCH 0/4] qcow2: Fixes for invalid images

2013-11-17 Thread Max Reitz
This series contains patches for broken images.

Max Reitz (4):
  qcow2: Move reading nb_snapshots in qcow2_open
  qcow2-refcount: Sanitize refcount table size
  qcow2: Sanitize refcount table size
  qcow2: Check validity of backing file name length

 block/qcow2-refcount.c |  4 
 block/qcow2.c  | 17 +++--
 2 files changed, 19 insertions(+), 2 deletions(-)

-- 
1.8.4.2




[Qemu-devel] [PATCH 1/4] qcow2: Move reading nb_snapshots in qcow2_open

2013-11-17 Thread Max Reitz
Any goto fail between having read nb_snapshots (returning a non-zero
value) and allocating s-snapshots (through qcow2_read_snapshots())
results in qcow2_free_snapshots() being called, dereferencing
s-snapshots which is still NULL.

Fix this by moving the reading of nb_snapshots right before the call to
qcow2_read_snapshots().

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/qcow2.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 6e5d98d..3e612a8 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -558,9 +558,6 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, 
int flags,
 s-refcount_table_size =
 header.refcount_table_clusters  (s-cluster_bits - 3);
 
-s-snapshots_offset = header.snapshots_offset;
-s-nb_snapshots = header.nb_snapshots;
-
 /* read the level 1 table */
 s-l1_size = header.l1_size;
 
@@ -637,6 +634,9 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, 
int flags,
 bs-backing_file[len] = '\0';
 }
 
+s-snapshots_offset = header.snapshots_offset;
+s-nb_snapshots = header.nb_snapshots;
+
 ret = qcow2_read_snapshots(bs);
 if (ret  0) {
 error_setg_errno(errp, -ret, Could not read snapshots);
-- 
1.8.4.2




[Qemu-devel] [PATCH 4/4] qcow2: Check validity of backing file name length

2013-11-17 Thread Max Reitz
The len variable is a signed integer, therefore it may overflow when
reading the backing file name length from the qcow2 image header. This
case should be handled explicitly.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/qcow2.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/block/qcow2.c b/block/qcow2.c
index 9c29e1a..e54176e 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -630,6 +630,11 @@ static int qcow2_open(BlockDriverState *bs, QDict 
*options, int flags,
 /* read the backing file name */
 if (header.backing_file_offset != 0) {
 len = header.backing_file_size;
+if (len  0) {
+error_setg(errp, Backing file name length is negative);
+ret = -EINVAL;
+goto fail;
+}
 if (len  1023) {
 len = 1023;
 }
-- 
1.8.4.2




[Qemu-devel] [PATCH 3/4] qcow2: Sanitize refcount table size

2013-11-17 Thread Max Reitz
Make sure there were no overflows when calculating the in-memory
refcount table size from the number of its clusters in-file.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/qcow2.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/block/qcow2.c b/block/qcow2.c
index 3e612a8..9c29e1a 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -558,6 +558,14 @@ static int qcow2_open(BlockDriverState *bs, QDict 
*options, int flags,
 s-refcount_table_size =
 header.refcount_table_clusters  (s-cluster_bits - 3);
 
+if ((s-refcount_table_size  (s-cluster_bits - 3)) !=
+header.refcount_table_clusters)
+{
+error_setg(errp, Refcount table is too big);
+ret = -EINVAL;
+goto fail;
+}
+
 /* read the level 1 table */
 s-l1_size = header.l1_size;
 
-- 
1.8.4.2




[Qemu-devel] [PATCH 2/4] qcow2-refcount: Sanitize refcount table size

2013-11-17 Thread Max Reitz
Make sure the refcount table size will not overflow when multiplied by
sizeof(uint64_t) and implicitly casted to int.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/qcow2-refcount.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 1ff43d0..2912097 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -42,6 +42,10 @@ int qcow2_refcount_init(BlockDriverState *bs)
 BDRVQcowState *s = bs-opaque;
 int ret, refcount_table_size2, i;
 
+if (s-refcount_table_size = INT_MAX / sizeof(uint64_t)) {
+goto fail;
+}
+
 refcount_table_size2 = s-refcount_table_size * sizeof(uint64_t);
 s-refcount_table = g_malloc(refcount_table_size2);
 if (s-refcount_table_size  0) {
-- 
1.8.4.2




[Qemu-devel] [PATCH 06/16] slirp: Make Socket structure IPv6 compatible

2013-11-17 Thread Samuel Thibault
This patch replaces foreign and local address/port couples in Socket
structure by 2 sockaddr_storage which can be casted in sockaddr_in or
sockaddr_in6.
Direct access to address and port is still possible thanks to some
\#define, so retrocompatibility of the existing code is assured.

The ss_family field of sockaddr_storage is declared after each socket
creation.

The whole structure is also saved/restored when a Qemu session is
saved/restored.

Signed-off-by: Guillaume Subiron maet...@subiron.org
---
 slirp/ip_icmp.c   |  2 ++
 slirp/slirp.c | 48 
 slirp/socket.c| 14 +++---
 slirp/socket.h| 25 +
 slirp/tcp_input.c |  2 ++
 slirp/tcp_subr.c  |  2 ++
 slirp/udp.c   |  4 
 7 files changed, 82 insertions(+), 15 deletions(-)

diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 1808976..768ea4a 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -170,8 +170,10 @@ icmp_input(struct mbuf *m, int hlen)
goto end_error;
   }
   so-so_m = m;
+  so-so_ffamily = AF_INET;
   so-so_faddr = ip-ip_dst;
   so-so_fport = htons(7);
+  so-so_lfamily = AF_INET;
   so-so_laddr = ip-ip_src;
   so-so_lport = htons(9);
   so-so_iptos = ip-ip_tos;
diff --git a/slirp/slirp.c b/slirp/slirp.c
index f5e46fb..a78fa72 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -1056,10 +1056,26 @@ static void slirp_sbuf_save(QEMUFile *f, struct sbuf 
*sbuf)
 static void slirp_socket_save(QEMUFile *f, struct socket *so)
 {
 qemu_put_be32(f, so-so_urgc);
-qemu_put_be32(f, so-so_faddr.s_addr);
-qemu_put_be32(f, so-so_laddr.s_addr);
-qemu_put_be16(f, so-so_fport);
-qemu_put_be16(f, so-so_lport);
+qemu_put_be16(f, so-so_ffamily);
+switch (so-so_ffamily) {
+case AF_INET:
+qemu_put_be32(f, so-so_faddr.s_addr);
+qemu_put_be16(f, so-so_fport);
+break;
+default:
+fprintf(stderr,
+so_ffamily unknown, unable to save so_faddr and so_fport\n);
+}
+qemu_put_be16(f, so-so_lfamily);
+switch (so-so_lfamily) {
+case AF_INET:
+qemu_put_be32(f, so-so_laddr.s_addr);
+qemu_put_be16(f, so-so_lport);
+break;
+default:
+fprintf(stderr,
+so_ffamily unknown, unable to save so_laddr and so_lport\n);
+}
 qemu_put_byte(f, so-so_iptos);
 qemu_put_byte(f, so-so_emu);
 qemu_put_byte(f, so-so_type);
@@ -1179,10 +1195,26 @@ static int slirp_socket_load(QEMUFile *f, struct socket 
*so)
 return -ENOMEM;
 
 so-so_urgc = qemu_get_be32(f);
-so-so_faddr.s_addr = qemu_get_be32(f);
-so-so_laddr.s_addr = qemu_get_be32(f);
-so-so_fport = qemu_get_be16(f);
-so-so_lport = qemu_get_be16(f);
+so-so_ffamily = qemu_get_be16(f);
+switch (so-so_ffamily) {
+case AF_INET:
+so-so_faddr.s_addr = qemu_get_be32(f);
+so-so_fport = qemu_get_be16(f);
+break;
+default:
+fprintf(stderr,
+so_ffamily unknown, unable to restore so_faddr and 
so_lport\n);
+}
+so-so_lfamily = qemu_get_be16(f);
+switch (so-so_lfamily) {
+case AF_INET:
+so-so_laddr.s_addr = qemu_get_be32(f);
+so-so_lport = qemu_get_be16(f);
+break;
+default:
+fprintf(stderr,
+so_ffamily unknown, unable to restore so_laddr and 
so_lport\n);
+}
 so-so_iptos = qemu_get_byte(f);
 so-so_emu = qemu_get_byte(f);
 so-so_type = qemu_get_byte(f);
diff --git a/slirp/socket.c b/slirp/socket.c
index e87c70e..2f166fb 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -437,8 +437,8 @@ sowrite(struct socket *so)
 void
 sorecvfrom(struct socket *so)
 {
-   struct sockaddr_in addr;
-   socklen_t addrlen = sizeof(struct sockaddr_in);
+   struct sockaddr_storage addr;
+   socklen_t addrlen = sizeof(struct sockaddr_storage);
 
DEBUG_CALL(sorecvfrom);
DEBUG_ARG(so = %lx, (long)so);
@@ -527,7 +527,13 @@ sorecvfrom(struct socket *so)
 * If this packet was destined for CTL_ADDR,
 * make it look like that's where it came from, done by udp_output
 */
-   udp_output(so, m, addr);
+   switch (so-so_ffamily) {
+   case AF_INET:
+   udp_output(so, m, (struct sockaddr_in *) addr);
+   break;
+   default:
+   break;
+   }
  } /* rx error */
} /* if ping packet */
 }
@@ -619,6 +625,7 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, 
uint32_t laddr,
 
so-so_state = SS_PERSISTENT_MASK;
so-so_state |= (SS_FACCEPTCONN | flags);
+   so-so_lfamily = AF_INET;
so-so_lport = lport; /* Kept in network format */
so-so_laddr.s_addr = laddr; /* Ditto */
 
@@ -645,6 +652,7 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, 
uint32_t laddr,
qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, opt, sizeof(int));

[Qemu-devel] [PATCH 09/16] slirp: Make udp_attach IPv6 compatible

2013-11-17 Thread Samuel Thibault
A sa_family_t is now passed in argument to udp_attach instead of using a
hardcoded AF_INET to call qemu_socket().

Signed-off-by: Guillaume Subiron maet...@subiron.org
---
 slirp/ip_icmp.c | 2 +-
 slirp/udp.c | 7 ---
 slirp/udp.h | 2 +-
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 8787aae..c896574 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -162,7 +162,7 @@ icmp_input(struct mbuf *m, int hlen)
   if (icmp_send(so, m, hlen) == 0) {
 return;
   }
-  if(udp_attach(so) == -1) {
+  if (udp_attach(so, AF_INET) == -1) {
DEBUG_MISC((dfd,icmp_input udp_attach errno = %d-%s\n,
errno,strerror(errno)));
sofree(so);
diff --git a/slirp/udp.c b/slirp/udp.c
index 7e0f1b2..f53ee11 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -167,7 +167,7 @@ udp_input(register struct mbuf *m, int iphlen)
  if (!so) {
  goto bad;
  }
- if(udp_attach(so) == -1) {
+ if (udp_attach(so, AF_INET) == -1) {
DEBUG_MISC((dfd, udp_attach errno = %d-%s\n,
errno,strerror(errno)));
sofree(so);
@@ -276,9 +276,10 @@ int udp_output(struct socket *so, struct mbuf *m,
 }
 
 int
-udp_attach(struct socket *so)
+udp_attach(struct socket *so, sa_family_t af)
 {
-  if((so-s = qemu_socket(AF_INET,SOCK_DGRAM,0)) != -1) {
+  so-s = qemu_socket(af, SOCK_DGRAM, 0);
+  if (so-s != -1) {
 so-so_expire = curtime + SO_EXPIRE;
 insque(so, so-slirp-udb);
   }
diff --git a/slirp/udp.h b/slirp/udp.h
index a04b8ce..15e73c1 100644
--- a/slirp/udp.h
+++ b/slirp/udp.h
@@ -76,7 +76,7 @@ struct mbuf;
 void udp_init(Slirp *);
 void udp_cleanup(Slirp *);
 void udp_input(register struct mbuf *, int);
-int udp_attach(struct socket *);
+int udp_attach(struct socket *, sa_family_t af);
 void udp_detach(struct socket *);
 struct socket * udp_listen(Slirp *, uint32_t, u_int, uint32_t, u_int,
int);
-- 
1.8.4.2




[Qemu-devel] [PATCH 03/16] qemu/timer.h : Adding function to second scale

2013-11-17 Thread Samuel Thibault
This patch adds SCALE_S, timer_new_s(), and qemu_clock_get_s in qemu/timer.h to
manage second-scale timers.

Signed-off-by: Guillaume Subiron maet...@subiron.org
Signed-off-by: Samuel Thibault samuel.thiba...@ens-lyon.org
---
 include/qemu/timer.h | 32 
 1 file changed, 32 insertions(+)

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 5afcffc..7376c0a 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -7,6 +7,7 @@
 
 /* timers */
 
+#define SCALE_S  10
 #define SCALE_MS 100
 #define SCALE_US 1000
 #define SCALE_NS 1
@@ -81,6 +82,20 @@ extern QEMUTimerListGroup main_loop_tlg;
 int64_t qemu_clock_get_ns(QEMUClockType type);
 
 /**
+ * qemu_clock_get_s;
+ * @type: the clock type
+ *
+ * Get the second value of a clock with
+ * type @type
+ *
+ * Returns: the clock value in seconds
+ */
+static inline int64_t qemu_clock_get_s(QEMUClockType type)
+{
+return qemu_clock_get_ns(type) / SCALE_S;
+}
+
+/**
  * qemu_clock_get_ms;
  * @type: the clock type
  *
@@ -514,6 +529,23 @@ static inline QEMUTimer *timer_new_ms(QEMUClockType type, 
QEMUTimerCB *cb,
 }
 
 /**
+ * timer_new_s:
+ * @clock: the clock to associate with the timer
+ * @callback: the callback to call when the timer expires
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Create a new timer with second scale on the default timer list
+ * associated with the clock.
+ *
+ * Returns: a pointer to the newly created timer
+ */
+static inline QEMUTimer *timer_new_s(QEMUClockType type, QEMUTimerCB *cb,
+ void *opaque)
+{
+return timer_new(type, SCALE_S, cb, opaque);
+}
+
+/**
  * timer_free:
  * @ts: the timer
  *
-- 
1.8.4.2




[Qemu-devel] [PATCH 02/16] slirp: Generalizing and neutralizing code before adding IPv6 stuff

2013-11-17 Thread Samuel Thibault
Basically, this patch replaces arp by resolution every time arp
means mac resolution and not specifically ARP.

Some indentation problems are solved in functions that will be modified
in the next patches (ip_input…).

In if_encap, a switch is added to prepare for the IPv6 case. Some code
is factorized.

Some #define ETH_* are moved upper in slirp.h to make them accessible to
other slirp/*.h

Signed-off-by: Guillaume Subiron maet...@subiron.org
Signed-off-by: Samuel Thibault samuel.thiba...@ens-lyon.org
---
 slirp/if.c|   2 +-
 slirp/mbuf.c  |   2 +-
 slirp/mbuf.h  |   2 +-
 slirp/slirp.c | 107 ++
 slirp/slirp.h |  12 +++
 5 files changed, 71 insertions(+), 54 deletions(-)

diff --git a/slirp/if.c b/slirp/if.c
index fb7acf8..e36b9cb 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -193,7 +193,7 @@ void if_start(Slirp *slirp)
 
 /* Try to send packet unless it already expired */
 if (ifm-expiration_date = now  !if_encap(slirp, ifm)) {
-/* Packet is delayed due to pending ARP resolution */
+/* Packet is delayed due to pending ARP or NDP resolution */
 continue;
 }
 
diff --git a/slirp/mbuf.c b/slirp/mbuf.c
index 4fefb04..92c429e 100644
--- a/slirp/mbuf.c
+++ b/slirp/mbuf.c
@@ -91,7 +91,7 @@ m_get(Slirp *slirp)
m-m_len = 0;
 m-m_nextpkt = NULL;
 m-m_prevpkt = NULL;
-m-arp_requested = false;
+m-resolution_requested = false;
 m-expiration_date = (uint64_t)-1;
 end_error:
DEBUG_ARG(m = %lx, (long )m);
diff --git a/slirp/mbuf.h b/slirp/mbuf.h
index b144f1c..38fedf4 100644
--- a/slirp/mbuf.h
+++ b/slirp/mbuf.h
@@ -79,7 +79,7 @@ struct mbuf {
int m_len;  /* Amount of data in this mbuf */
 
Slirp *slirp;
-   boolarp_requested;
+   boolresolution_requested;
uint64_t expiration_date;
/* start of dynamic buffer area, must be last element */
union {
diff --git a/slirp/slirp.c b/slirp/slirp.c
index bad8dad..bfc4832 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -778,53 +778,70 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
 return 1;
 }
 
-if (!arp_table_search(slirp, iph-ip_dst.s_addr, ethaddr)) {
-uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
-struct ethhdr *reh = (struct ethhdr *)arp_req;
-struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
-
-if (!ifm-arp_requested) {
-/* If the client addr is not known, send an ARP request */
-memset(reh-h_dest, 0xff, ETH_ALEN);
-memcpy(reh-h_source, special_ethaddr, ETH_ALEN - 4);
-memcpy(reh-h_source[2], slirp-vhost_addr, 4);
-reh-h_proto = htons(ETH_P_ARP);
-rah-ar_hrd = htons(1);
-rah-ar_pro = htons(ETH_P_IP);
-rah-ar_hln = ETH_ALEN;
-rah-ar_pln = 4;
-rah-ar_op = htons(ARPOP_REQUEST);
-
-/* source hw addr */
-memcpy(rah-ar_sha, special_ethaddr, ETH_ALEN - 4);
-memcpy(rah-ar_sha[2], slirp-vhost_addr, 4);
-
-/* source IP */
-rah-ar_sip = slirp-vhost_addr.s_addr;
-
-/* target hw addr (none) */
-memset(rah-ar_tha, 0, ETH_ALEN);
-
-/* target IP */
-rah-ar_tip = iph-ip_dst.s_addr;
-slirp-client_ipaddr = iph-ip_dst;
-slirp_output(slirp-opaque, arp_req, sizeof(arp_req));
-ifm-arp_requested = true;
-
-/* Expire request and drop outgoing packet after 1 second */
-ifm-expiration_date = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + 
10ULL;
+switch (iph-ip_v) {
+case IPVERSION:
+if (!arp_table_search(slirp, iph-ip_dst.s_addr, ethaddr)) {
+uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
+struct ethhdr *reh = (struct ethhdr *)arp_req;
+struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
+
+if (!ifm-resolution_requested) {
+/* If the client addr is not known, send an ARP request */
+memset(reh-h_dest, 0xff, ETH_ALEN);
+memcpy(reh-h_source, special_ethaddr, ETH_ALEN - 4);
+memcpy(reh-h_source[2], slirp-vhost_addr, 4);
+reh-h_proto = htons(ETH_P_ARP);
+rah-ar_hrd = htons(1);
+rah-ar_pro = htons(ETH_P_IP);
+rah-ar_hln = ETH_ALEN;
+rah-ar_pln = 4;
+rah-ar_op = htons(ARPOP_REQUEST);
+
+/* source hw addr */
+memcpy(rah-ar_sha, special_ethaddr, ETH_ALEN - 4);
+memcpy(rah-ar_sha[2], slirp-vhost_addr, 4);
+
+/* source IP */
+rah-ar_sip = slirp-vhost_addr.s_addr;
+
+/* target hw addr (none) */
+memset(rah-ar_tha, 0, ETH_ALEN);
+
+/* target IP */
+   

[Qemu-devel] [PATCH 04/16] slirp: Adding IPv6, ICMPv6 Echo and NDP autoconfiguration

2013-11-17 Thread Samuel Thibault
This patch adds the functions needed to handle IPv6 packets. ICMPv6 and
NDP headers are implemented.

Slirp is now able to send NDP Router or Neighbor Advertisement when it
receives Router or Neighbor Solicitation. Using a 64bit-sized IPv6
prefix, the guest is now able to perform stateless autoconfiguration
(SLAAC) and to compute its IPv6 address.

This patch adds an ndp_table, mainly inspired by arp_table, to keep an
NDP cache and manage network address resolution.
Slirp regularly sends NDP Neighbor Advertisement, as recommended by the
RFC, to make the guest refresh its route.

This also adds ip6_cksum() to compute ICMPv6 checksums using IPv6
pseudo-header.

Signed-off-by: Guillaume Subiron maet...@subiron.org
Signed-off-by: Samuel Thibault samuel.thiba...@ens-lyon.org
---
 slirp/Makefile.objs |   4 +-
 slirp/cksum.c   |  23 
 slirp/ip6.h | 139 +
 slirp/ip6_icmp.c| 349 
 slirp/ip6_icmp.h| 248 +
 slirp/ip6_input.c   |  75 +++
 slirp/ip6_output.c  |  41 ++
 slirp/ndp_table.c   |  87 +
 slirp/slirp.c   |  47 +--
 slirp/slirp.h   |  35 ++
 10 files changed, 1038 insertions(+), 10 deletions(-)
 create mode 100644 slirp/ip6.h
 create mode 100644 slirp/ip6_icmp.c
 create mode 100644 slirp/ip6_icmp.h
 create mode 100644 slirp/ip6_input.c
 create mode 100644 slirp/ip6_output.c
 create mode 100644 slirp/ndp_table.c

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 2daa9dc..2dfe8e0 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -1,3 +1,3 @@
-common-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o dnssearch.o
+common-obj-y = cksum.o if.o ip_icmp.o ip6_icmp.o ip6_input.o ip6_output.o 
ip_input.o ip_output.o dnssearch.o
 common-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
-common-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o arp_table.o
+common-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o arp_table.o 
ndp_table.o
diff --git a/slirp/cksum.c b/slirp/cksum.c
index 6328660..f0a1398 100644
--- a/slirp/cksum.c
+++ b/slirp/cksum.c
@@ -137,3 +137,26 @@ cont:
REDUCE;
return (~sum  0x);
 }
+
+int ip6_cksum(struct mbuf *m)
+{
+struct ip6 save_ip, *ip = mtod(m, struct ip6 *);
+struct ip6_pseudohdr *ih = mtod(m, struct ip6_pseudohdr *);
+int sum;
+
+save_ip = *ip;
+
+ih-ih_src = save_ip.ip_src;
+ih-ih_dst = save_ip.ip_dst;
+ih-ih_pl = htonl((uint32_t)ntohs(save_ip.ip_pl));
+ih-ih_zero_hi = 0;
+ih-ih_zero_lo = 0;
+ih-ih_nh = save_ip.ip_nh;
+
+sum = cksum(m, ((int)sizeof(struct ip6_pseudohdr))
++ ntohl(ih-ih_pl));
+
+*ip = save_ip;
+
+return sum;
+}
diff --git a/slirp/ip6.h b/slirp/ip6.h
new file mode 100644
index 000..16124ec
--- /dev/null
+++ b/slirp/ip6.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2013
+ * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
+ *
+ * Please read the file COPYRIGHT for the
+ * terms and conditions of the copyright.
+ */
+
+#ifndef _IP6_H_
+#define _IP6_H_
+
+#define in6_multicast(a) IN6_IS_ADDR_MULTICAST((a))
+#define in6_linklocal(a) IN6_IS_ADDR_LINKLOCAL((a))
+#define in6_unspecified(a) IN6_IS_ADDR_UNSPECIFIED((a))
+
+#define ALLNODES_MULTICAST  { .s6_addr = \
+{ 0xff, 0x02, 0x00, 0x00,\
+0x00, 0x00, 0x00, 0x00,\
+0x00, 0x00, 0x00, 0x00,\
+0x00, 0x00, 0x00, 0x01 } }
+
+#define SOLICITED_NODE_PREFIX { .s6_addr = \
+{ 0xff, 0x02, 0x00, 0x00,\
+0x00, 0x00, 0x00, 0x00,\
+0x00, 0x00, 0x00, 0x01,\
+0xff, 0x00, 0x00, 0x00 } }
+
+#define LINKLOCAL_ADDR  { .s6_addr = \
+{ 0xfe, 0x80, 0x00, 0x00,\
+0x00, 0x00, 0x00, 0x00,\
+0x00, 0x00, 0x00, 0x00,\
+0x00, 0x00, 0x00, 0x01 } }
+
+static inline int in6_equal(struct in6_addr a, struct in6_addr b)
+{
+return memcmp(a, b, sizeof(a)) == 0;
+}
+
+static inline int in6_equal_net(struct in6_addr a, struct in6_addr b,
+int prefix_len)
+{
+if (memcmp(a, b, prefix_len / 8) != 0) {
+return 0;
+}
+
+if (prefix_len % 8 == 0) {
+return 1;
+}
+
+return (a.s6_addr[prefix_len / 8]  (8 - (prefix_len % 8)))
+== (b.s6_addr[prefix_len / 8]  (8 - (prefix_len % 8)));
+}
+
+static inline int in6_equal_mach(struct in6_addr a, struct in6_addr b,
+int prefix_len)
+{
+if (memcmp((a.s6_addr[(prefix_len + 7) / 8]),
+(b.s6_addr[(prefix_len + 7) / 8]),
+16 - (prefix_len + 7) / 8) != 0) {
+return 0;
+}
+
+if (prefix_len % 8 == 0) {
+return 1;
+}
+
+return (a.s6_addr[prefix_len / 8]  ((1U  (8 - (prefix_len % 8))) 

[Qemu-devel] [PATCH 08/16] slirp: Factorizing and cleaning solookup()

2013-11-17 Thread Samuel Thibault
This patch makes solookup() compatible with all address family. Also,
this function was only compatible with TCP. Having the socket list in
argument, it is now compatible with UDP too. Finally, some optimization
code is factorized inside the function (the function look at the last
returned result before browsing the complete socket list).

This also adds a sockaddr_equal() function to compare two
sockaddr_storage.

Signed-off-by: Guillaume Subiron maet...@subiron.org
---
 slirp/socket.c| 30 --
 slirp/socket.h| 30 +-
 slirp/tcp_input.c | 27 +++
 slirp/udp.c   | 25 ++---
 4 files changed, 62 insertions(+), 50 deletions(-)

diff --git a/slirp/socket.c b/slirp/socket.c
index 375281c..f333fcf 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -15,24 +15,26 @@
 static void sofcantrcvmore(struct socket *so);
 static void sofcantsendmore(struct socket *so);
 
-struct socket *
-solookup(struct socket *head, struct in_addr laddr, u_int lport,
- struct in_addr faddr, u_int fport)
+struct socket *solookup(struct socket **last, struct socket *head,
+struct sockaddr_storage *lhost, struct sockaddr_storage *fhost)
 {
-   struct socket *so;
+struct socket *so = *last;
 
-   for (so = head-so_next; so != head; so = so-so_next) {
-   if (so-so_lport == lport 
-   so-so_laddr.s_addr == laddr.s_addr 
-   so-so_faddr.s_addr == faddr.s_addr 
-   so-so_fport == fport)
-  break;
-   }
+/* Optimisation */
+if (sockaddr_equal((so-lhost.ss), lhost)
+ (!fhost || sockaddr_equal((so-fhost.ss), fhost))) {
+return so;
+}
 
-   if (so == head)
-  return (struct socket *)NULL;
-   return so;
+for (so = head-so_next; so != head; so = so-so_next) {
+if (sockaddr_equal((so-lhost.ss), lhost)
+ (!fhost || sockaddr_equal((so-fhost.ss), fhost))) {
+*last = so;
+return so;
+}
+}
 
+return (struct socket *)NULL;
 }
 
 /*
diff --git a/slirp/socket.h b/slirp/socket.h
index 50059be..ad509b9 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -93,7 +93,35 @@ struct socket {
 #define SS_HOSTFWD 0x1000  /* Socket describes host-guest 
forwarding */
 #define SS_INCOMING0x2000  /* Connection was initiated by a host 
on the internet */
 
-struct socket * solookup(struct socket *, struct in_addr, u_int, struct 
in_addr, u_int);
+static inline int sockaddr_equal(struct sockaddr_storage *a,
+struct sockaddr_storage *b)
+{
+if (a-ss_family != b-ss_family) {
+return 0;
+} else {
+switch (a-ss_family) {
+case AF_INET:
+{
+struct sockaddr_in *a4 = (struct sockaddr_in *) a;
+struct sockaddr_in *b4 = (struct sockaddr_in *) b;
+return (a4-sin_addr.s_addr == b4-sin_addr.s_addr
+ a4-sin_port == b4-sin_port);
+}
+case AF_INET6:
+{
+struct sockaddr_in6 *a6 = (struct sockaddr_in6 *) a;
+struct sockaddr_in6 *b6 = (struct sockaddr_in6 *) b;
+return (in6_equal(a6-sin6_addr, b6-sin6_addr)
+ a6-sin6_port == b6-sin6_port);
+}
+default:
+return 0;
+}
+}
+}
+
+struct socket *solookup(struct socket **, struct socket *,
+struct sockaddr_storage *, struct sockaddr_storage *);
 struct socket * socreate(Slirp *);
 void sofree(struct socket *);
 int soread(struct socket *);
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 70ef376..f7a8d49 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -227,6 +227,7 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
int iss = 0;
u_long tiwin;
int ret;
+   struct sockaddr_storage lhost, fhost;
 struct ex_list *ex_ptr;
 Slirp *slirp;
 
@@ -320,16 +321,14 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
 * Locate pcb for segment.
 */
 findso:
-   so = slirp-tcp_last_so;
-   if (so-so_fport != ti-ti_dport ||
-   so-so_lport != ti-ti_sport ||
-   so-so_laddr.s_addr != ti-ti_src.s_addr ||
-   so-so_faddr.s_addr != ti-ti_dst.s_addr) {
-   so = solookup(slirp-tcb, ti-ti_src, ti-ti_sport,
-  ti-ti_dst, ti-ti_dport);
-   if (so)
-   slirp-tcp_last_so = so;
-   }
+   lhost.ss_family = AF_INET;
+   ((struct sockaddr_in *)lhost)-sin_addr = ti-ti_src;
+   ((struct sockaddr_in *)lhost)-sin_port = ti-ti_sport;
+   fhost.ss_family = AF_INET;
+   ((struct sockaddr_in *)fhost)-sin_addr = ti-ti_dst;
+   ((struct sockaddr_in *)fhost)-sin_port = ti-ti_dport;
+
+   so = solookup(slirp-tcp_last_so, slirp-tcb, lhost, fhost);
 
/*
 * If the state is 

[Qemu-devel] [PATCH 11/16] slirp: Adding family argument to tcp_fconnect()

2013-11-17 Thread Samuel Thibault
This patch simply adds a sa_family_t argument to remove the hardcoded
AF_INET in the call of qemu_socket().

Signed-off-by: Guillaume Subiron maet...@subiron.org
---
 slirp/slirp.h | 2 +-
 slirp/tcp_input.c | 3 ++-
 slirp/tcp_subr.c  | 5 +++--
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index ec9cbed..d16400b 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -369,7 +369,7 @@ void tcp_respond(struct tcpcb *, register struct tcpiphdr 
*, register struct mbu
 struct tcpcb * tcp_newtcpcb(struct socket *);
 struct tcpcb * tcp_close(register struct tcpcb *);
 void tcp_sockclosed(struct tcpcb *);
-int tcp_fconnect(struct socket *);
+int tcp_fconnect(struct socket *, sa_family_t af);
 void tcp_connect(struct socket *);
 int tcp_attach(struct socket *);
 uint8_t tcp_tos(struct socket *);
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index f7a8d49..25929bd 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -581,7 +581,8 @@ findso:
goto cont_input;
  }
 
- if((tcp_fconnect(so) == -1)  (errno != EINPROGRESS)  (errno != 
EWOULDBLOCK)) {
+ if ((tcp_fconnect(so, so-so_ffamily) == -1)
+ (errno != EINPROGRESS)  (errno != EWOULDBLOCK)) {
u_char code=ICMP_UNREACH_NET;
DEBUG_MISC((dfd,  tcp fconnect errno = %d-%s\n,
errno,strerror(errno)));
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 4791c0c..3558115 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -324,14 +324,15 @@ tcp_sockclosed(struct tcpcb *tp)
  * nonblocking.  Connect returns after the SYN is sent, and does
  * not wait for ACK+SYN.
  */
-int tcp_fconnect(struct socket *so)
+int tcp_fconnect(struct socket *so, sa_family_t af)
 {
   int ret=0;
 
   DEBUG_CALL(tcp_fconnect);
   DEBUG_ARG(so = %lx, (long )so);
 
-  if( (ret = so-s = qemu_socket(AF_INET,SOCK_STREAM,0)) = 0) {
+  ret = so-s = qemu_socket(af, SOCK_STREAM, 0);
+  if (ret = 0) {
 int opt, s=so-s;
 struct sockaddr_storage addr;
 
-- 
1.8.4.2




[Qemu-devel] [PATCH 01/16] slirp: goto bad in udp_input if sosendto fails

2013-11-17 Thread Samuel Thibault
Before this patch, if sosendto fails, udp_input is executed as if the
packet was sent. This could cause memory leak.
This patch adds a goto bad to cut the execution of this function.

Signed-off-by: Guillaume Subiron maet...@subiron.org
---
 slirp/udp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/slirp/udp.c b/slirp/udp.c
index 8cc6cb6..fd2446a 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -218,6 +218,7 @@ udp_input(register struct mbuf *m, int iphlen)
  *ip=save_ip;
  DEBUG_MISC((dfd,udp tx errno = %d-%s\n,errno,strerror(errno)));
  icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno));
+ goto bad;
}
 
m_free(so-so_m);   /* used for ICMP if error on sorecvfrom */
-- 
1.8.4.2




[Qemu-devel] [PATCH 14/16] slirp: Handle IPv6 in TCP functions

2013-11-17 Thread Samuel Thibault
This patch adds IPv6 case in TCP functions refactored by the last
patches.
This also adds IPv6 pseudo-header in tcpiphdr structure.
Finally, tcp_input() is called by ip6_input().

Signed-off-by: Guillaume Subiron maet...@subiron.org
Signed-off-by: Samuel Thibault samuel.thiba...@ens-lyon.org
---
 slirp/ip6_input.c  |  4 ++--
 slirp/tcp.h|  2 ++
 slirp/tcp_input.c  | 58 +-
 slirp/tcp_output.c | 16 +++
 slirp/tcp_subr.c   | 36 +
 slirp/tcpip.h  |  9 +
 6 files changed, 105 insertions(+), 20 deletions(-)

diff --git a/slirp/ip6_input.c b/slirp/ip6_input.c
index 3290af8..b03b795 100644
--- a/slirp/ip6_input.c
+++ b/slirp/ip6_input.c
@@ -58,8 +58,8 @@ void ip6_input(struct mbuf *m)
  */
 switch (ip6-ip_nh) {
 case IPPROTO_TCP:
-/* :TODO:maethor:130307: TCP */
-icmp6_send_error(m, ICMP6_UNREACH, ICMP6_UNREACH_NO_ROUTE);
+NTOHS(ip6-ip_pl);
+tcp_input(m, sizeof(struct ip6), (struct socket *)NULL, AF_INET6);
 break;
 case IPPROTO_UDP:
 udp6_input(m);
diff --git a/slirp/tcp.h b/slirp/tcp.h
index 2e2b403..61befcd 100644
--- a/slirp/tcp.h
+++ b/slirp/tcp.h
@@ -106,6 +106,8 @@ struct tcphdr {
  */
 #undef TCP_MSS
 #defineTCP_MSS 1460
+#undef TCP6_MSS
+#define TCP6_MSS 1440
 
 #undef TCP_MAXWIN
 #defineTCP_MAXWIN  65535   /* largest value for (unscaled) window 
*/
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 3409557..e5056f8 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -215,7 +215,8 @@ present:
 void
 tcp_input(struct mbuf *m, int iphlen, struct socket *inso, sa_family_t af)
 {
-   struct ip save_ip, *ip;
+   struct ip save_ip, *ip;
+   struct ip6 save_ip6, *ip6;
register struct tcpiphdr *ti;
caddr_t optp = NULL;
int optlen = 0;
@@ -254,6 +255,11 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso, 
sa_family_t af)
}
slirp = m-slirp;
 
+   ip = mtod(m, struct ip *);
+   ip6 = mtod(m, struct ip6 *);
+   save_ip = *ip;
+   save_ip6 = *ip6;
+
switch (af) {
case AF_INET:
if (iphlen  sizeof(struct ip)) {
@@ -262,13 +268,6 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso, 
sa_family_t af)
}
/* XXX Check if too short */
 
-
-   /*
-* Save a copy of the IP header in case we want restore it
-* for sending an ICMP error message in response.
-*/
-   ip = mtod(m, struct ip *);
-   save_ip = *ip;
save_ip.ip_len += iphlen;
 
/*
@@ -293,16 +292,35 @@ tcp_input(struct mbuf *m, int iphlen, struct socket 
*inso, sa_family_t af)
ti-ti_dst = save_ip.ip_dst;
ti-ti_pr = save_ip.ip_p;
ti-ti_len = htons((uint16_t)tlen);
-   len = ((sizeof(struct tcpiphdr) - sizeof(struct tcphdr)) + tlen);
-   if (cksum(m, len)) {
-   goto drop;
-   }
+   break;
+
+   case AF_INET6:
+   m-m_data -= sizeof(struct tcpiphdr) - (sizeof(struct ip6)
++ sizeof(struct tcphdr));
+   m-m_len  += sizeof(struct tcpiphdr) - (sizeof(struct ip6)
++ sizeof(struct tcphdr));
+   ti = mtod(m, struct tcpiphdr *);
+
+   tlen = ip6-ip_pl;
+   tcpiphdr2qlink(ti)-next = tcpiphdr2qlink(ti)-prev = NULL;
+   memset(ti-ih_mbuf, 0 , sizeof(struct mbuf_ptr));
+   memset(ti-ti, 0, sizeof(ti-ti));
+   ti-ti_x0 = 0;
+   ti-ti_src6 = save_ip6.ip_src;
+   ti-ti_dst6 = save_ip6.ip_dst;
+   ti-ti_nh6 = save_ip6.ip_nh;
+   ti-ti_len = htons((uint16_t)tlen);
break;
 
default:
goto drop;
}
 
+   len = ((sizeof(struct tcpiphdr) - sizeof(struct tcphdr)) + tlen);
+   if (cksum(m, len)) {
+   goto drop;
+   }
+
/*
 * Check that TCP offset makes sense,
 * pull out TCP options and adjust length.  XXX
@@ -346,6 +364,12 @@ findso:
((struct sockaddr_in *)fhost)-sin_addr = ti-ti_dst;
((struct sockaddr_in *)fhost)-sin_port = ti-ti_dport;
break;
+   case AF_INET6:
+   ((struct sockaddr_in6 *)lhost)-sin6_addr = ti-ti_src6;
+   ((struct sockaddr_in6 *)lhost)-sin6_port = ti-ti_sport;
+   ((struct sockaddr_in6 *)fhost)-sin6_addr = ti-ti_dst6;
+   ((struct sockaddr_in6 *)fhost)-sin6_port = ti-ti_dport;
+   break;
default:
goto drop;
}
@@ -405,7 +429,6 @@ findso:
  so-so_iptos = ((struct ip *)ti)-ip_tos;
  break;
  default:
- goto drop;
  break;
  }
  }
@@ -634,6 +657,9 @@ findso:
  case AF_INET:
   

[Qemu-devel] [PATCH 10/16] slirp: Adding IPv6 UDP support

2013-11-17 Thread Samuel Thibault
This patch adds udp6_input() and udp6_output().
It also adds the IPv6 case in sorecvfrom().
Finally, udp_input() is called by ip6_input().

Signed-off-by: Guillaume Subiron maet...@subiron.org
---
 slirp/Makefile.objs |   2 +-
 slirp/ip6_input.c   |   3 +-
 slirp/socket.c  |   7 ++-
 slirp/udp.h |   5 ++
 slirp/udp6.c| 149 
 5 files changed, 162 insertions(+), 4 deletions(-)
 create mode 100644 slirp/udp6.c

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 2dfe8e0..faa32b6 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -1,3 +1,3 @@
 common-obj-y = cksum.o if.o ip_icmp.o ip6_icmp.o ip6_input.o ip6_output.o 
ip_input.o ip_output.o dnssearch.o
 common-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
-common-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o arp_table.o 
ndp_table.o
+common-obj-y += tcp_subr.o tcp_timer.o udp.o udp6.o bootp.o tftp.o arp_table.o 
ndp_table.o
diff --git a/slirp/ip6_input.c b/slirp/ip6_input.c
index af098a5..3290af8 100644
--- a/slirp/ip6_input.c
+++ b/slirp/ip6_input.c
@@ -62,8 +62,7 @@ void ip6_input(struct mbuf *m)
 icmp6_send_error(m, ICMP6_UNREACH, ICMP6_UNREACH_NO_ROUTE);
 break;
 case IPPROTO_UDP:
-/* :TODO:maethor:130312: UDP */
-icmp6_send_error(m, ICMP6_UNREACH, ICMP6_UNREACH_NO_ROUTE);
+udp6_input(m);
 break;
 case IPPROTO_ICMPV6:
 icmp6_input(m);
diff --git a/slirp/socket.c b/slirp/socket.c
index f333fcf..31bbb7e 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -540,8 +540,13 @@ sorecvfrom(struct socket *so)
   (struct sockaddr_in *) daddr,
   so-so_iptos);
break;
-   default:
+   case AF_INET6:
+   udp6_output(so, m, (struct sockaddr_in6 *) saddr,
+   (struct sockaddr_in6 *) daddr);
break;
+   default:
+  assert(0);
+  break;
}
  } /* rx error */
} /* if ping packet */
diff --git a/slirp/udp.h b/slirp/udp.h
index 15e73c1..8a4d9f5 100644
--- a/slirp/udp.h
+++ b/slirp/udp.h
@@ -83,4 +83,9 @@ struct socket * udp_listen(Slirp *, uint32_t, u_int, 
uint32_t, u_int,
 int udp_output(struct socket *so, struct mbuf *m,
 struct sockaddr_in *saddr, struct sockaddr_in *daddr,
 int iptos);
+
+void udp6_input(register struct mbuf *);
+int udp6_output(struct socket *so, struct mbuf *m,
+struct sockaddr_in6 *saddr, struct sockaddr_in6 *daddr);
+
 #endif
diff --git a/slirp/udp6.c b/slirp/udp6.c
new file mode 100644
index 000..3940959
--- /dev/null
+++ b/slirp/udp6.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2013
+ * Guillaume Subiron
+ *
+ * Please read the file COPYRIGHT for the
+ * terms and conditions of the copyright.
+ */
+
+#include slirp.h
+#include udp.h
+
+void udp6_input(struct mbuf *m)
+{
+Slirp *slirp = m-slirp;
+struct ip6 *ip, save_ip;
+struct udphdr *uh;
+int hlen = sizeof(struct ip6);
+int len;
+struct socket *so;
+struct sockaddr_storage lhost;
+
+DEBUG_CALL(udp6_input);
+DEBUG_ARG(m = %lx, (long)m);
+
+if (slirp-restricted) {
+goto bad;
+}
+
+ip = mtod(m, struct ip6 *);
+m-m_len -= hlen;
+m-m_data += hlen;
+uh = mtod(m, struct udphdr *);
+m-m_len += hlen;
+m-m_data -= hlen;
+
+if (ip6_cksum(m)) {
+goto bad;
+}
+
+len = ntohs((uint16_t)uh-uh_ulen);
+
+/*
+ * Make mbuf data length reflect UDP length.
+ * If not enough data to reflect UDP length, drop.
+ */
+if (ntohs(ip-ip_pl) != len) {
+if (len  ntohs(ip-ip_pl)) {
+goto bad;
+}
+m_adj(m, len - ntohs(ip-ip_pl));
+ip-ip_pl = htons(len);
+}
+
+/* TODO handle DHCP/BOOTP */
+/* TODO handle TFTP */
+
+/* Locate pcb for datagram. */
+lhost.ss_family = AF_INET6;
+((struct sockaddr_in6 *)lhost)-sin6_addr = ip-ip_src;
+((struct sockaddr_in6 *)lhost)-sin6_port = uh-uh_sport;
+
+so = solookup(slirp-udp_last_so, slirp-udb, lhost, NULL);
+
+if (so == NULL) {
+/* If there's no socket for this packet, create one. */
+so = socreate(slirp);
+if (!so) {
+goto bad;
+}
+if (udp_attach(so, AF_INET6) == -1) {
+DEBUG_MISC((dfd,  udp6_attach errno = %d-%s\n,
+errno, strerror(errno)));
+sofree(so);
+goto bad;
+}
+
+/* Setup fields */
+so-so_lfamily = AF_INET6;
+so-so_laddr6 = ip-ip_src;
+so-so_lport6 = uh-uh_sport;
+}
+
+so-so_ffamily = AF_INET6;
+so-so_faddr6 = ip-ip_dst; /* XXX */
+so-so_fport6 = uh-uh_dport; /* XXX */
+
+hlen += sizeof(struct udphdr);
+m-m_len -= hlen;
+m-m_data += hlen;
+
+/*
+ * Now we sendto() the packet.
+ */
+

[Qemu-devel] [PATCH 05/16] slirp: Adding ICMPv6 error sending

2013-11-17 Thread Samuel Thibault
Disambiguation : icmp_error is renamed into icmp_send_error, since it
doesn't manage errors, but only sends ICMP Error messages.

Adding icmp6_send_error to send ICMPv6 Error messages. This function is
simpler than the v4 version.
Adding some calls in various functions to send ICMP errors, when a
received packet is too big, or when its hop limit is 0.

Signed-off-by: Yann Bordenave m...@meowstars.org
---
 slirp/ip6_icmp.c  | 60 +++
 slirp/ip6_icmp.h  | 10 ++
 slirp/ip6_input.c | 16 ---
 slirp/ip_icmp.c   | 12 +--
 slirp/ip_icmp.h   |  4 ++--
 slirp/ip_input.c  |  8 
 slirp/socket.c|  4 ++--
 slirp/tcp_input.c |  2 +-
 slirp/udp.c   |  3 ++-
 9 files changed, 96 insertions(+), 23 deletions(-)

diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index 4538bfd..8952bbc 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -64,6 +64,66 @@ static void icmp6_send_echoreply(struct mbuf *m, Slirp 
*slirp, struct ip6 *ip,
 ip6_output(NULL, t, 0);
 }
 
+void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code)
+{
+Slirp *slirp = m-slirp;
+struct mbuf *t = m_get(slirp);
+struct ip6 *ip = mtod(m, struct ip6 *);
+
+char addrstr[INET6_ADDRSTRLEN];
+DEBUG_CALL(icmp_send_error);
+DEBUG_ARGS((dfd,  type = %d, code = %d\n, type, code));
+
+/* IPv6 packet */
+struct ip6 *rip = mtod(t, struct ip6 *);
+rip-ip_src = (struct in6_addr)LINKLOCAL_ADDR;
+if (in6_multicast(ip-ip_src) || in6_unspecified(ip-ip_src)) {
+/* :TODO:maethor:130317: icmp error? */
+return;
+}
+rip-ip_dst = ip-ip_src;
+inet_ntop(AF_INET6, rip-ip_dst, addrstr, INET6_ADDRSTRLEN);
+DEBUG_ARG(target = %s, addrstr);
+
+rip-ip_nh = IPPROTO_ICMPV6;
+const int error_data_len = min(m-m_len,
+IF_MTU - (sizeof(struct ip6) + ICMP6_ERROR_MINLEN));
+rip-ip_pl = htons(ICMP6_ERROR_MINLEN + error_data_len);
+t-m_len = sizeof(struct ip6) + ntohs(rip-ip_pl);
+
+/* ICMPv6 packet */
+t-m_data += sizeof(struct ip6);
+struct icmp6 *ricmp = mtod(t, struct icmp6 *);
+ricmp-icmp6_type = type;
+ricmp-icmp6_code = code;
+ricmp-icmp6_cksum = 0;
+
+switch (type) {
+case ICMP6_UNREACH:
+case ICMP6_TIMXCEED:
+ricmp-icmp6_err.unused = 0;
+break;
+case ICMP6_TOOBIG:
+ricmp-icmp6_err.mtu = htonl(IF_MTU);
+break;
+case ICMP6_PARAMPROB:
+/* :TODO:Meow:130316: Handle this case */
+break;
+default:
+assert(0);
+break;
+}
+t-m_data += ICMP6_ERROR_MINLEN;
+memcpy(t-m_data, m-m_data, error_data_len);
+
+/* Checksum */
+t-m_data -= ICMP6_ERROR_MINLEN;
+t-m_data -= sizeof(struct ip6);
+ricmp-icmp6_cksum = ip6_cksum(t);
+
+ip6_output(NULL, t, 0);
+}
+
 /*
  * Process a NDP message
  */
diff --git a/slirp/ip6_icmp.h b/slirp/ip6_icmp.h
index bd9d3d9..deae1a1 100644
--- a/slirp/ip6_icmp.h
+++ b/slirp/ip6_icmp.h
@@ -22,6 +22,12 @@ struct icmp6_echo { /* Echo Messages */
 uint16_t seq_num;
 };
 
+union icmp6_error_body {
+uint32_t unused;
+uint32_t pointer;
+uint32_t mtu;
+};
+
 /*
  * NDP Messages
  */
@@ -85,6 +91,7 @@ struct icmp6 {
 uint8_t icmp6_code; /* type sub code */
 uint16_ticmp6_cksum;/* ones complement cksum of struct */
 union {
+union icmp6_error_body error_body;
 struct icmp6_echo echo;
 struct ndp_rs ndp_rs;
 struct ndp_ra ndp_ra;
@@ -92,6 +99,7 @@ struct icmp6 {
 struct ndp_na ndp_na;
 struct ndp_redirect ndp_redirect;
 } icmp6_body;
+#define icmp6_err icmp6_body.error_body
 #define icmp6_echo icmp6_body.echo
 #define icmp6_nrs icmp6_body.ndp_rs
 #define icmp6_nra icmp6_body.ndp_ra
@@ -101,6 +109,7 @@ struct icmp6 {
 } QEMU_PACKED;
 
 #define ICMP6_MINLEN4
+#define ICMP6_ERROR_MINLEN  8
 #define ICMP6_ECHO_MINLEN   8
 #define ICMP6_NDP_RS_MINLEN 8
 #define ICMP6_NDP_RA_MINLEN 16
@@ -242,6 +251,7 @@ void icmp6_input(struct mbuf *);
 void icmp6_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
 const char *message);
 */
+void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code);
 void ndp_send_ra(Slirp *slirp);
 void ndp_send_ns(Slirp *slirp, struct in6_addr addr);
 
diff --git a/slirp/ip6_input.c b/slirp/ip6_input.c
index 9663c42..af098a5 100644
--- a/slirp/ip6_input.c
+++ b/slirp/ip6_input.c
@@ -33,7 +33,7 @@ void ip6_input(struct mbuf *m)
 DEBUG_ARG(m_len = %d, m-m_len);
 
 if (m-m_len  sizeof(struct ip6)) {
-return;
+goto bad;
 }
 
 ip6 = mtod(m, struct ip6 *);
@@ -42,10 +42,14 @@ void ip6_input(struct mbuf *m)
 goto bad;
 }
 
+if (ntohs(ip6-ip_pl)  IF_MTU) {
+icmp6_send_error(m, ICMP6_TOOBIG, 0);
+goto bad;
+}
+
 /* check ip_ttl for a correct ICMP reply */
 if (ip6-ip_hl == 0) {
-/* :TODO:maethor:130307: icmp6_error 

[Qemu-devel] [PATCH 07/16] slirp: Factorizing address translation

2013-11-17 Thread Samuel Thibault
This patch factorizes some duplicate code into a new function,
sotranslate_out(). This function perform the address translation when a
packet is transmitted to the host network. If the paquet is destinated
to the host, the loopback address is used, and if the paquet is
destinated to the virtual DNS, the real DNS address is used. This code
is just a copy of the existant, but factorized and ready to manage the
IPv6 case.

On the same model, the major part of udp_output() code is moved into a
new sotranslate_in(). This function is directly used in sorecvfrom(),
like sotranslate_out() in sosendto().
udp_output() becoming useless, it is removed and udp_output2() is
renamed into udp_output(). This adds consistency with the udp6_output()
function introduced by further patches.

Signed-off-by: Guillaume Subiron maet...@subiron.org
---
 slirp/bootp.c|  2 +-
 slirp/ip_icmp.c  | 19 +++-
 slirp/socket.c   | 93 
 slirp/socket.h   |  3 ++
 slirp/tcp_subr.c | 24 +++
 slirp/tftp.c |  6 ++--
 slirp/udp.c  | 27 +---
 slirp/udp.h  |  3 +-
 8 files changed, 91 insertions(+), 86 deletions(-)

diff --git a/slirp/bootp.c b/slirp/bootp.c
index b7db9fa..03e2e42 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -319,7 +319,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t 
*bp)
 
 m-m_len = sizeof(struct bootp_t) -
 sizeof(struct ip) - sizeof(struct udphdr);
-udp_output2(NULL, m, saddr, daddr, IPTOS_LOWDELAY);
+udp_output(NULL, m, saddr, daddr, IPTOS_LOWDELAY);
 }
 
 void bootp_input(struct mbuf *m)
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 768ea4a..8787aae 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -157,7 +157,7 @@ icmp_input(struct mbuf *m, int hlen)
 goto freeit;
 } else {
   struct socket *so;
-  struct sockaddr_in addr;
+  struct sockaddr_storage addr;
   if ((so = socreate(slirp)) == NULL) goto freeit;
   if (icmp_send(so, m, hlen) == 0) {
 return;
@@ -181,20 +181,9 @@ icmp_input(struct mbuf *m, int hlen)
   so-so_state = SS_ISFCONNECTED;
 
   /* Send the packet */
-  addr.sin_family = AF_INET;
-  if ((so-so_faddr.s_addr  slirp-vnetwork_mask.s_addr) ==
-  slirp-vnetwork_addr.s_addr) {
-   /* It's an alias */
-   if (so-so_faddr.s_addr == slirp-vnameserver_addr.s_addr) {
- if (get_dns_addr(addr.sin_addr)  0)
-   addr.sin_addr = loopback_addr;
-   } else {
- addr.sin_addr = loopback_addr;
-   }
-  } else {
-   addr.sin_addr = so-so_faddr;
-  }
-  addr.sin_port = so-so_fport;
+  addr = so-fhost.ss;
+  sotranslate_out(so, addr);
+
   if(sendto(so-s, icmp_ping_msg, strlen(icmp_ping_msg), 0,
(struct sockaddr *)addr, sizeof(addr)) == -1) {
DEBUG_MISC((dfd,icmp_input udp sendto tx errno = %d-%s\n,
diff --git a/slirp/socket.c b/slirp/socket.c
index 2f166fb..375281c 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -438,6 +438,7 @@ void
 sorecvfrom(struct socket *so)
 {
struct sockaddr_storage addr;
+   struct sockaddr_storage saddr, daddr;
socklen_t addrlen = sizeof(struct sockaddr_storage);
 
DEBUG_CALL(sorecvfrom);
@@ -525,11 +526,17 @@ sorecvfrom(struct socket *so)
 
/*
 * If this packet was destined for CTL_ADDR,
-* make it look like that's where it came from, done by udp_output
+* make it look like that's where it came from
 */
+   saddr = addr;
+   sotranslate_in(so, saddr);
+   daddr = so-lhost.ss;
+
switch (so-so_ffamily) {
case AF_INET:
-   udp_output(so, m, (struct sockaddr_in *) addr);
+   udp_output(so, m, (struct sockaddr_in *) saddr,
+  (struct sockaddr_in *) daddr,
+  so-so_iptos);
break;
default:
break;
@@ -544,33 +551,20 @@ sorecvfrom(struct socket *so)
 int
 sosendto(struct socket *so, struct mbuf *m)
 {
-   Slirp *slirp = so-slirp;
int ret;
-   struct sockaddr_in addr;
+   struct sockaddr_storage addr;
 
DEBUG_CALL(sosendto);
DEBUG_ARG(so = %lx, (long)so);
DEBUG_ARG(m = %lx, (long)m);
 
-addr.sin_family = AF_INET;
-   if ((so-so_faddr.s_addr  slirp-vnetwork_mask.s_addr) ==
-   slirp-vnetwork_addr.s_addr) {
- /* It's an alias */
- if (so-so_faddr.s_addr == slirp-vnameserver_addr.s_addr) {
-   if (get_dns_addr(addr.sin_addr)  0)
- addr.sin_addr = loopback_addr;
- } else {
-   addr.sin_addr = loopback_addr;
- }
-   } else
- addr.sin_addr = so-so_faddr;
-   addr.sin_port = so-so_fport;
-
-   DEBUG_MISC((dfd,  sendto()ing, addr.sin_port=%d, 
addr.sin_addr.s_addr=%.16s\n, ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));

[Qemu-devel] [PATCH 16/16] qapi-schema, qemu-options slirp: Adding Qemu options for IPv6 addresses

2013-11-17 Thread Samuel Thibault
This patchs adds parameters to manage some new options in the qemu -net
command.
Slirp IPv6 address, network prefix, and DNS IPv6 address can be given in
argument to the qemu command.
Defaults parameters are respectively fc00::2, fc00::, /64 and fc00::3.

Signed-off-by: Yann Bordenave m...@meowstars.org
Signed-off-by: Samuel Thibault samuel.thiba...@ens-lyon.org
---
 net/net.c| 30 ++
 net/slirp.c  | 46 --
 qapi-schema.json | 40 ++--
 qemu-options.hx  | 18 --
 slirp/libslirp.h |  8 +---
 slirp/slirp.c| 20 +---
 6 files changed, 126 insertions(+), 36 deletions(-)

diff --git a/net/net.c b/net/net.c
index 0a88e68..6c48b71 100644
--- a/net/net.c
+++ b/net/net.c
@@ -814,6 +814,36 @@ int net_client_init(QemuOpts *opts, int is_netdev, Error 
**errp)
 int ret = -1;
 
 {
+/* Parse convenience option format ip6-net=fc00::0[/64] */
+const char *ip6_net = qemu_opt_get(opts, ip6-net);
+
+if (ip6_net) {
+char buf[strlen(ip6_net)+1];
+
+if (get_str_sep(buf, sizeof(buf), ip6_net, '/')  0) {
+/* Default 64bit prefix length.  */
+qemu_opt_set(opts, ip6-prefix, ip6_net);
+qemu_opt_set_number(opts, ip6-prefixlen, 64);
+} else {
+/* User-specified prefix length.  */
+int len;
+char *end;
+
+qemu_opt_set(opts, ip6-prefix, buf);
+len = strtol(ip6_net, end, 10);
+
+if (*end != '\0') {
+error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+  ip6-prefix, a number);
+} else {
+qemu_opt_set_number(opts, ip6-prefixlen, len);
+}
+}
+qemu_opt_unset(opts, ip6-net);
+}
+}
+
+{
 OptsVisitor *ov = opts_visitor_new(opts);
 
 net_visit(opts_get_visitor(ov), is_netdev, object, err);
diff --git a/net/slirp.c b/net/slirp.c
index 124e953..01f81e0 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -134,17 +134,23 @@ static NetClientInfo net_slirp_info = {
 static int net_slirp_init(NetClientState *peer, const char *model,
   const char *name, int restricted,
   const char *vnetwork, const char *vhost,
+  const char *vprefix6, int vprefix6_len,
+  const char *vhost6,
   const char *vhostname, const char *tftp_export,
   const char *bootfile, const char *vdhcp_start,
-  const char *vnameserver, const char *smb_export,
-  const char *vsmbserver, const char **dnssearch)
+  const char *vnameserver, const char *vnameserver6,
+  const char *smb_export, const char *vsmbserver,
+  const char **dnssearch)
 {
 /* default settings according to historic slirp */
 struct in_addr net  = { .s_addr = htonl(0x0a000200) }; /* 10.0.2.0 */
 struct in_addr mask = { .s_addr = htonl(0xff00) }; /* 255.255.255.0 */
 struct in_addr host = { .s_addr = htonl(0x0a000202) }; /* 10.0.2.2 */
+struct in6_addr ip6_prefix;
+struct in6_addr ip6_host;
 struct in_addr dhcp = { .s_addr = htonl(0x0a00020f) }; /* 10.0.2.15 */
 struct in_addr dns  = { .s_addr = htonl(0x0a000203) }; /* 10.0.2.3 */
+struct in6_addr ip6_dns;
 #ifndef _WIN32
 struct in_addr smbsrv = { .s_addr = 0 };
 #endif
@@ -212,6 +218,24 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 return -1;
 }
 
+if (!vprefix6)
+vprefix6 = fc00::;
+if (!inet_pton(AF_INET6, vprefix6, ip6_prefix)) {
+return -1;
+}
+
+if (!vprefix6_len)
+vprefix6_len = 64;
+if (vprefix6_len  0 || vprefix6_len  128) {
+return -1;
+}
+
+if (!vhost6)
+vhost6 = fc00::2;
+if (!inet_pton(AF_INET6, vhost6, ip6_host)) {
+return -1;
+}
+
 if (vnameserver  !inet_aton(vnameserver, dns)) {
 return -1;
 }
@@ -220,6 +244,12 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 return -1;
 }
 
+if (!vnameserver6)
+vnameserver6 = fc00::3;
+if (!inet_pton(AF_INET6, vnameserver6, ip6_dns)) {
+return -1;
+}
+
 if (vdhcp_start  !inet_aton(vdhcp_start, dhcp)) {
 return -1;
 }
@@ -242,8 +272,10 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 
 s = DO_UPCAST(SlirpState, nc, nc);
 
-s-slirp = slirp_init(restricted, net, mask, host, vhostname,
-  tftp_export, bootfile, dhcp, dns, dnssearch, s);
+s-slirp = slirp_init(restricted, net, mask, host,
+  ip6_prefix, vprefix6_len, 

[Qemu-devel] [PATCH 15/16] slirp: Adding IPv6 address for DNS relay

2013-11-17 Thread Samuel Thibault
This patch adds an IPv6 address to the DNS relay. in6_equal_dns() is
developed using this Slirp attribute.
sotranslate_in/out() are also updated to manage the IPv6 case so the
guest can be able to join the host using one of the Slirp addresses.

Signed-off-by: Guillaume Subiron maet...@subiron.org
---
 slirp/ip6.h|  5 -
 slirp/slirp.c  |  2 ++
 slirp/slirp.h  |  1 +
 slirp/socket.c | 26 --
 4 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/slirp/ip6.h b/slirp/ip6.h
index 16124ec..b88456d 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -74,7 +74,10 @@ static inline int in6_equal_mach(struct in6_addr a, struct 
in6_addr b,
   || (in6_equal_net(a, (struct in6_addr)LINKLOCAL_ADDR, 64)\
in6_equal_mach(a, slirp-vhost_addr6, 64)))
 
-#define in6_equal_dns(a) 0
+#define in6_equal_dns(a)\
+((in6_equal_net(a, slirp-vprefix_addr6, slirp-vprefix_len)\
+ || in6_equal_net(a, (struct in6_addr)LINKLOCAL_ADDR, 64))\
+  in6_equal_mach(a, slirp-vnameserver_addr6, slirp-vprefix_len))
 
 #define in6_equal_host(a)\
 (in6_equal_router(a) || in6_equal_dns(a))
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 9bee487..35c2665 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -236,6 +236,8 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
 slirp-bootp_filename = g_strdup(bootfile);
 slirp-vdhcp_startaddr = vdhcp_start;
 slirp-vnameserver_addr = vnameserver;
+/* :TODO:maethor:130311: Use a parameter passed to the function */
+inet_pton(AF_INET6, fc00::3, slirp-vnameserver_addr6);
 
 if (vdnssearch) {
 translate_dnssearch(slirp, vdnssearch);
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 3cdf984..57fe17e 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -236,6 +236,7 @@ struct Slirp {
 struct in6_addr vhost_addr6;
 struct in_addr vdhcp_startaddr;
 struct in_addr vnameserver_addr;
+struct in6_addr vnameserver_addr6;
 
 struct in_addr client_ipaddr;
 char client_hostname[33];
diff --git a/slirp/socket.c b/slirp/socket.c
index 567f9bc..a9b3957 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -741,12 +741,12 @@ sofwdrain(struct socket *so)
 
 /*
  * Translate addr in host addr when it is a virtual address
- * :TODO:maethor:130314: Manage IPv6
  */
 void sotranslate_out(struct socket *so, struct sockaddr_storage *addr)
 {
 Slirp *slirp = so-slirp;
 struct sockaddr_in *sin = (struct sockaddr_in *)addr;
+struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
 
 switch (addr-ss_family) {
 case AF_INET:
@@ -767,16 +767,29 @@ void sotranslate_out(struct socket *so, struct 
sockaddr_storage *addr)
 ntohs(sin-sin_port), inet_ntoa(sin-sin_addr)));
 break;
 
+case AF_INET6:
+if (in6_equal_net(so-so_faddr6, slirp-vprefix_addr6,
+slirp-vprefix_len)) {
+if (in6_equal(so-so_faddr6, slirp-vnameserver_addr6)) {
+/*if (get_dns_addr(addr)  0) {*/ /* TODO */
+sin6-sin6_addr = in6addr_loopback;
+/*}*/
+} else {
+sin6-sin6_addr = in6addr_loopback;
+}
+}
+break;
+
 default:
 break;
 }
 }
 
-/* :TODO:maethor:130314: IPv6 */
 void sotranslate_in(struct socket *so, struct sockaddr_storage *addr)
 {
 Slirp *slirp = so-slirp;
 struct sockaddr_in *sin = (struct sockaddr_in *)addr;
+struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
 
 switch (addr-ss_family) {
 case AF_INET:
@@ -793,6 +806,15 @@ void sotranslate_in(struct socket *so, struct 
sockaddr_storage *addr)
 }
 break;
 
+case AF_INET6:
+if (in6_equal_net(so-so_faddr6, slirp-vprefix_addr6,
+slirp-vprefix_len)) {
+if (in6_equal(sin6-sin6_addr, in6addr_loopback)
+|| !in6_equal(so-so_faddr6, slirp-vhost_addr6)) {
+sin6-sin6_addr = so-so_faddr6;
+}
+}
+
 default:
 break;
 }
-- 
1.8.4.2




[Qemu-devel] [PATCH 13/16] slirp: Generalizing and neutralizing various TCP functions before adding IPv6 stuff

2013-11-17 Thread Samuel Thibault
Basically, this patch adds some switch in various TCP functions to
prepare them for the IPv6 case.

To have something to switch in tcp_input() and tcp_respond(), a new
argument is used to give them the sa_family of the addresses they are
working on.

Signed-off-by: Guillaume Subiron maet...@subiron.org
---
 slirp/ip_input.c   |   2 +-
 slirp/slirp.c  |   6 ++-
 slirp/slirp.h  |   5 +-
 slirp/tcp_input.c  | 142 +
 slirp/tcp_output.c |  43 +---
 slirp/tcp_subr.c   |  94 +--
 slirp/tcp_timer.c  |   3 +-
 7 files changed, 181 insertions(+), 114 deletions(-)

diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 1925cdc..9aa8909 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -199,7 +199,7 @@ ip_input(struct mbuf *m)
 */
switch (ip-ip_p) {
 case IPPROTO_TCP:
-   tcp_input(m, hlen, (struct socket *)NULL);
+   tcp_input(m, hlen, (struct socket *)NULL, AF_INET);
break;
 case IPPROTO_UDP:
udp_input(m, hlen);
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 79025cd..9bee487 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -576,7 +576,8 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
 /*
  * Continue tcp_input
  */
-tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
+tcp_input((struct mbuf *)NULL, sizeof(struct ip), so,
+so-so_ffamily);
 /* continue; */
 } else {
 ret = sowrite(so);
@@ -625,7 +626,8 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
 }
 
 }
-tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
+tcp_input((struct mbuf *)NULL, sizeof(struct ip), so,
+so-so_ffamily);
 } /* SS_ISFCONNECTING */
 #endif
 }
diff --git a/slirp/slirp.h b/slirp/slirp.h
index d16400b..3cdf984 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -354,7 +354,7 @@ void ip6_input(struct mbuf *);
 int ip6_output(struct socket *, struct mbuf *, int fast);
 
 /* tcp_input.c */
-void tcp_input(register struct mbuf *, int, struct socket *);
+void tcp_input(register struct mbuf *, int, struct socket *, sa_family_t af);
 int tcp_mss(register struct tcpcb *, u_int);
 
 /* tcp_output.c */
@@ -365,7 +365,8 @@ void tcp_setpersist(register struct tcpcb *);
 void tcp_init(Slirp *);
 void tcp_cleanup(Slirp *);
 void tcp_template(struct tcpcb *);
-void tcp_respond(struct tcpcb *, register struct tcpiphdr *, register struct 
mbuf *, tcp_seq, tcp_seq, int);
+void tcp_respond(struct tcpcb *, register struct tcpiphdr *,
+register struct mbuf *, tcp_seq, tcp_seq, int, sa_family_t);
 struct tcpcb * tcp_newtcpcb(struct socket *);
 struct tcpcb * tcp_close(register struct tcpcb *);
 void tcp_sockclosed(struct tcpcb *);
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index dde89b6..3409557 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -213,7 +213,7 @@ present:
  * protocol specification dated September, 1981 very closely.
  */
 void
-tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
+tcp_input(struct mbuf *m, int iphlen, struct socket *inso, sa_family_t af)
 {
struct ip save_ip, *ip;
register struct tcpiphdr *ti;
@@ -254,46 +254,53 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
}
slirp = m-slirp;
 
-   if (iphlen  sizeof(struct ip )) {
- ip_stripoptions(m, (struct mbuf *)0);
- iphlen=sizeof(struct ip );
-   }
-   /* XXX Check if too short */
+   switch (af) {
+   case AF_INET:
+   if (iphlen  sizeof(struct ip)) {
+   ip_stripoptions(m, (struct mbuf *)0);
+   iphlen = sizeof(struct ip);
+   }
+   /* XXX Check if too short */
 
 
-   /*
-* Save a copy of the IP header in case we want restore it
-* for sending an ICMP error message in response.
-*/
-   ip=mtod(m, struct ip *);
-   save_ip = *ip;
-   save_ip.ip_len+= iphlen;
+   /*
+* Save a copy of the IP header in case we want restore it
+* for sending an ICMP error message in response.
+*/
+   ip = mtod(m, struct ip *);
+   save_ip = *ip;
+   save_ip.ip_len += iphlen;
 
-   /*
-* Get IP and TCP header together in first mbuf.
-* Note: IP leaves IP header in first mbuf.
-*/
-   m-m_data -= sizeof(struct tcpiphdr) - (sizeof(struct ip)
-+ sizeof(struct tcphdr));
-   m-m_len += sizeof(struct tcpiphdr) - (sizeof(struct ip)
-   + sizeof(struct 

[Qemu-devel] [PATCH 12/16] slirp: Factorizing tcpiphdr structure with an union

2013-11-17 Thread Samuel Thibault
This patch factorizes the tcpiphdr structure to put the IPv4 fields in
an union, for addition of version 6 in further patch.
Using some macros, retrocompatibility of the existing code is assured.

This patch also fixes the SLIRP_MSIZE and margin computation in various
functions, and makes them compatible with the new tcpiphdr structure,
whose size will be bigger than sizeof(struct tcphdr) + sizeof(struct ip)

Signed-off-by: Guillaume Subiron maet...@subiron.org
Signed-off-by: Samuel Thibault samuel.thiba...@ens-lyon.org
---
 slirp/if.h |  4 ++--
 slirp/mbuf.c   |  3 ++-
 slirp/slirp.c  | 15 ---
 slirp/socket.c | 13 -
 slirp/tcp_input.c  | 31 ---
 slirp/tcp_output.c | 18 +-
 slirp/tcp_subr.c   | 31 ++-
 slirp/tcpip.h  | 31 +++
 8 files changed, 102 insertions(+), 44 deletions(-)

diff --git a/slirp/if.h b/slirp/if.h
index 3327023..c7a5c57 100644
--- a/slirp/if.h
+++ b/slirp/if.h
@@ -17,7 +17,7 @@
 #define IF_MRU 1500
 #defineIF_COMP IF_AUTOCOMP /* Flags for compression */
 
-/* 2 for alignment, 14 for ethernet, 40 for TCP/IP */
-#define IF_MAXLINKHDR (2 + 14 + 40)
+/* 2 for alignment, 14 for ethernet */
+#define IF_MAXLINKHDR (2 + ETH_HLEN)
 
 #endif
diff --git a/slirp/mbuf.c b/slirp/mbuf.c
index 92c429e..87ee550 100644
--- a/slirp/mbuf.c
+++ b/slirp/mbuf.c
@@ -23,7 +23,8 @@
  * Find a nice value for msize
  * XXX if_maxlinkhdr already in mtu
  */
-#define SLIRP_MSIZE (IF_MTU + IF_MAXLINKHDR + offsetof(struct mbuf, m_dat) + 6)
+#define SLIRP_MSIZE\
+(offsetof(struct mbuf, m_dat) + IF_MAXLINKHDR + TCPIPHDR_DELTA + IF_MTU)
 
 void
 m_init(Slirp *slirp)
diff --git a/slirp/slirp.c b/slirp/slirp.c
index a78fa72..79025cd 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -756,15 +756,16 @@ void slirp_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len)
 m = m_get(slirp);
 if (!m)
 return;
-/* Note: we add to align the IP header */
-if (M_FREEROOM(m)  pkt_len + 2) {
-m_inc(m, pkt_len + 2);
+/* Note: we add 2 to align the IP header on 4 bytes,
+ * and add the margin for the tcpiphdr overhead  */
+if (M_FREEROOM(m)  pkt_len + TCPIPHDR_DELTA + 2) {
+m_inc(m, pkt_len + TCPIPHDR_DELTA + 2);
 }
-m-m_len = pkt_len + 2;
-memcpy(m-m_data + 2, pkt, pkt_len);
+m-m_len = pkt_len + TCPIPHDR_DELTA + 2;
+memcpy(m-m_data + TCPIPHDR_DELTA + 2, pkt, pkt_len);
 
-m-m_data += 2 + ETH_HLEN;
-m-m_len -= 2 + ETH_HLEN;
+m-m_data += TCPIPHDR_DELTA + 2 + ETH_HLEN;
+m-m_len -= TCPIPHDR_DELTA + 2 + ETH_HLEN;
 
 if (proto == ETH_P_IP) {
 ip_input(m);
diff --git a/slirp/socket.c b/slirp/socket.c
index 31bbb7e..567f9bc 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -482,7 +482,18 @@ sorecvfrom(struct socket *so)
  if (!m) {
  return;
  }
- m-m_data += IF_MAXLINKHDR;
+ switch (so-so_ffamily) {
+ case AF_INET:
+ m-m_data += IF_MAXLINKHDR + sizeof(struct udpiphdr);
+ break;
+ case AF_INET6:
+ m-m_data += IF_MAXLINKHDR + sizeof(struct ip6)
++ sizeof(struct udphdr);
+ break;
+ default:
+ assert(0);
+ break;
+ }
 
  /*
   * XXX Shouldn't FIONREAD packets destined for port 53,
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 25929bd..dde89b6 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -254,11 +254,6 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
}
slirp = m-slirp;
 
-   /*
-* Get IP and TCP header together in first mbuf.
-* Note: IP leaves IP header in first mbuf.
-*/
-   ti = mtod(m, struct tcpiphdr *);
if (iphlen  sizeof(struct ip )) {
  ip_stripoptions(m, (struct mbuf *)0);
  iphlen=sizeof(struct ip );
@@ -275,14 +270,28 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
save_ip.ip_len+= iphlen;
 
/*
+* Get IP and TCP header together in first mbuf.
+* Note: IP leaves IP header in first mbuf.
+*/
+   m-m_data -= sizeof(struct tcpiphdr) - (sizeof(struct ip)
++ sizeof(struct tcphdr));
+   m-m_len += sizeof(struct tcpiphdr) - (sizeof(struct ip)
+   + sizeof(struct tcphdr));
+   ti = mtod(m, struct tcpiphdr *);
+
+   /*
 * Checksum extended TCP header and data.
 */
-   tlen = ((struct ip *)ti)-ip_len;
-tcpiphdr2qlink(ti)-next = tcpiphdr2qlink(ti)-prev = NULL;
-memset(ti-ti_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr));
-   ti-ti_x1 = 0;
+   tlen = ip-ip_len;
+   tcpiphdr2qlink(ti)-next = 

Re: [Qemu-devel] Ping [PATCH] qemu-ga: vss-win32: Install VSS provider COM+ application service

2013-11-17 Thread Yan Vugenfirer

On Nov 15, 2013, at 7:39 PM, Tomoki Sekiyama tomoki.sekiy...@hds.com wrote:

 On 11/3/13 3:59 , Gal Hammer gham...@redhat.com wrote:
 Reviewed-by: Gal Hammer gham...@redhat.com
 
 On 01/11/2013 23:47, Tomoki Sekiyama wrote:
 Currently, qemu-ga for Windows fails to execute guset-fsfreeze-freeze
 when
 no user is logging in to Windows, with an error message:
   {error:{class:GenericError,
 desc:failed to add C:\\ to snapshotset:  (error:
 8004230f)}}
 
 To enable guest-fsfreeze-freeze/thaw without logging in users, this
 installs
 a service to execute qemu-ga VSS provider COM+ application that has full
 access privileges to the local system. The service will automatically be
 removed when the COM+ application is deregistered.
 
 This patch replaces ICOMAdminCatalog interface with ICOMAdminCatalog2
 interface that contains CreateServiceForApplication() method in
 addition.
 
 Signed-off-by: Tomoki Sekiyama tomoki.sekiy...@hds.com
 ---
  qga/vss-win32/install.cpp |   16 ++--
  1 file changed, 10 insertions(+), 6 deletions(-)
 
 diff --git a/qga/vss-win32/install.cpp b/qga/vss-win32/install.cpp
 index 37731a7..b791a6c 100644
 --- a/qga/vss-win32/install.cpp
 +++ b/qga/vss-win32/install.cpp
 @@ -25,8 +25,8 @@ extern HINSTANCE g_hinstDll;
 
  const GUID CLSID_COMAdminCatalog = { 0xF618C514, 0xDFB8, 0x11d1,
  {0xA2, 0xCF, 0x00, 0x80, 0x5F, 0xC7, 0x92, 0x35} };
 -const GUID IID_ICOMAdminCatalog = { 0xDD662187, 0xDFC2, 0x11d1,
 -{0xA2, 0xCF, 0x00, 0x80, 0x5F, 0xC7, 0x92, 0x35} };
 +const GUID IID_ICOMAdminCatalog2 = { 0x790C6E0B, 0x9194, 0x4cc9,
 +{0x94, 0x26, 0xA4, 0x8A, 0x63, 0x18, 0x56, 0x96} };
  const GUID CLSID_WbemLocator = { 0x4590f811, 0x1d3a, 0x11d0,
  {0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24} };
  const GUID IID_IWbemLocator = { 0xdc12a687, 0x737f, 0x11cf,
 @@ -141,7 +141,7 @@ static HRESULT QGAProviderFind(
  HRESULT hr;
  COMInitializer initializer;
  COMPointerIUnknown pUnknown;
 -COMPointerICOMAdminCatalog pCatalog;
 +COMPointerICOMAdminCatalog2 pCatalog;
  COMPointerICatalogCollection pColl;
  COMPointerICatalogObject pObj;
  _variant_t var;
 @@ -149,7 +149,7 @@ static HRESULT QGAProviderFind(
 
  chk(CoCreateInstance(CLSID_COMAdminCatalog, NULL,
 CLSCTX_INPROC_SERVER,
   IID_IUnknown, (void **)pUnknown.replace()));
 -chk(pUnknown-QueryInterface(IID_ICOMAdminCatalog,
 +chk(pUnknown-QueryInterface(IID_ICOMAdminCatalog2,
   (void **)pCatalog.replace()));
  chk(pCatalog-GetCollection(_bstr_t(LApplications),
  (IDispatch **)pColl.replace()));
 @@ -206,7 +206,7 @@ STDAPI COMRegister(void)
  HRESULT hr;
  COMInitializer initializer;
  COMPointerIUnknown pUnknown;
 -COMPointerICOMAdminCatalog pCatalog;
 +COMPointerICOMAdminCatalog2 pCatalog;
  COMPointerICatalogCollection pApps, pRoles, pUsersInRole;
  COMPointerICatalogObject pObj;
  long n;
 @@ -229,7 +229,7 @@ STDAPI COMRegister(void)
 
  chk(CoCreateInstance(CLSID_COMAdminCatalog, NULL,
 CLSCTX_INPROC_SERVER,
   IID_IUnknown, (void **)pUnknown.replace()));
 -chk(pUnknown-QueryInterface(IID_ICOMAdminCatalog,
 +chk(pUnknown-QueryInterface(IID_ICOMAdminCatalog2,
   (void **)pCatalog.replace()));
 
  /* Install COM+ Component */
 @@ -273,6 +273,10 @@ STDAPI COMRegister(void)
  goto out;
  }
 
 +chk(pCatalog-CreateServiceForApplication(
 +_bstr_t(QGA_PROVIDER_LNAME), _bstr_t(QGA_PROVIDER_LNAME),
 +_bstr_t(LSERVICE_AUTO_START),
 _bstr_t(LSERVICE_ERROR_NORMAL),
 +_bstr_t(L), _bstr_t(L.\\localsystem), _bstr_t(L),
 FALSE));
  chk(pCatalog-InstallComponent(_bstr_t(QGA_PROVIDER_LNAME),
 _bstr_t(dllPath), _bstr_t(tlbPath),
 _bstr_t()));
 
 
 Ping?

Reviewed and tested. Please apply.

Best regards,
Yan Vugenfirer.

 -- 
 Tomoki Sekiyama
 
 




[Qemu-devel] [PATCHv2 00/16] slirp: Adding IPv6 support to Qemu -net user mode

2013-11-17 Thread Samuel Thibault
Hello,

This is a respin of IPv6 in Qemu -net user mode.

These patches add ICMPv6, NDP, and make UDP and TCP compatible with
IPv6. We have made some refactoring to make current code compatible with
IPv6.

Some patches, like 2 and 13, can be reviewed using
interdiff -w /dev/null patchfile
to get rid of the indentation.

Differences with version 1 are:

- the encoding of the option to specify the configured network: this is
still -net ip6-net=addr/len in the user interface, but decomposed as
ip6-prefix and ip6-prefixlen in the QAPI.
- the RA timer has been made per-slirp instead of global.
- the default host IPs have been made fc00::2 and fc00::3, coherent with
the IPv4 case.

[PATCH 01/16] slirp: goto bad in udp_input if sosendto fails
[PATCH 02/16] slirp: Generalizing and neutralizing code before adding
[PATCH 03/16] qemu/timer.h : Adding function to second scale
[PATCH 04/16] slirp: Adding IPv6, ICMPv6 Echo and NDP
[PATCH 05/16] slirp: Adding ICMPv6 error sending
[PATCH 06/16] slirp: Make Socket structure IPv6 compatible
[PATCH 07/16] slirp: Factorizing address translation
[PATCH 08/16] slirp: Factorizing and cleaning solookup()
[PATCH 09/16] slirp: Make udp_attach IPv6 compatible
[PATCH 10/16] slirp: Adding IPv6 UDP support
[PATCH 11/16] slirp: Adding family argument to tcp_fconnect()
[PATCH 12/16] slirp: Factorizing tcpiphdr structure with an union
[PATCH 13/16] slirp: Generalizing and neutralizing various TCP
[PATCH 14/16] slirp: Handle IPv6 in TCP functions
[PATCH 15/16] slirp: Adding IPv6 address for DNS relay
[PATCH 16/16] qapi-schema, qemu-options  slirp: Adding Qemu options



Re: [Qemu-devel] [PATCH v2 5/7] exec: memory radix tree page level?compression

2013-11-17 Thread Michael S. Tsirkin
On Thu, Nov 14, 2013 at 05:42:26PM +0200, Avi Kivity wrote:
 On 11/14/2013 05:37 PM, Michael S. Tsirkin wrote:
 On Thu, Nov 14, 2013 at 04:56:43PM +0200, Avi Kivity wrote:
 On 11/14/2013 04:40 PM, Michael S. Tsirkin wrote:
 On Thu, Nov 14, 2013 at 08:54:11AM +, Avi Kivity wrote:
 Michael S. Tsirkin mst at redhat.com writes:
 
 At the moment, memory radix tree is already variable width, but it can
 only skip the low bits of address.
 
 This is efficient if we have huge memory regions but inefficient if we
 are only using a tiny portion of the address space.
 
 After we have built up the map, detect
 configurations where a single L2 entry is valid.
 
 We then speed up the lookup by skipping one or more levels.
 In case any levels were skipped, we might end up in a valid section
 instead of erroring out. We handle this by checking that
 the address is in range of the resulting section.
 
 I think this is overkill.  It can be done in a simpler way as follows:
 
 
 phys_page_find(RadixTree* tr, hwaddr index, ...)
 {
 if (index  rt-invalid_index_mask) {
 // not found
 }
 lp = rt-root;
 for (i = rt-nb_levels - 1; i = 0  !lp.is_leaf; --i) {
   ...
 
 This exploits the fact the lower portion of the address space is always
 filled, at least in the cases that matter to us.
 
 
 
 
 
 Basically skip unused high bits?
 Sure.
 In fact I think both optimizations can be combined.
 Not much value in combining them -- the variable level tree check
 will be dominated by the level skip logic.
 
 IMO however skipping intermediate levels will be too rare to justify
 the complexity and the doubling of the page table size -- it can
 only happen in iommu setups that place memory in very high
 addresses.  These ought to be rare.
 
 Well maybe not very high address, but you can have a device with
 a 64 bit bar and this will add back levels (though it would not
 be slower than it is currently).
 
 I agree the simplicity is attractive.
 
 However I really would like some logic that can handle  1 leaf
 somehow.
 
 Specifically both tricks break if we add a full 64 bit io region
 in order to return -1 for reads on master abort.
 
 That can be achieved by directing a missed lookup to a catch-all region.
 
 It would be best to do this completely internally to the memory
 code, without API changes.

You mean e.g. add a catch-all region to the address space?




[Qemu-devel] [PATCH] fix initrd load failed

2013-11-17 Thread ChenQun
Here's a bug, some examples are as follows:
1.Assuming Guest's filesystem size 6M.
2.For vexpress_a15, the loader_start = 2048M.
If we set guest ram_size range from  2048M+128M to 2048M+128M+6M,
  then the initrd load failed.
3.For mach-virt, the loader_start = 128M.
If we set guest ram_size range from 256M to 256M+6M, then it is
failed too.

So,it is a bug for load initrd max mem calculation.
It should be (ram_size + loader_start - initrd_start).

Signed-off-by: ChenQun chenq...@gmail.com
---
 hw/arm/boot.c |6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 583ec79..831128d 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -415,12 +415,14 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info 
*info)
 if (info-initrd_filename) {
 initrd_size = load_ramdisk(info-initrd_filename,
info-initrd_start,
-   info-ram_size -
+   info-ram_size +
+   info-loader_start -
info-initrd_start);
 if (initrd_size  0) {
 initrd_size = load_image_targphys(info-initrd_filename,
   info-initrd_start,
-  info-ram_size -
+  info-ram_size +
+  info-loader_start -
   info-initrd_start);
 }
 if (initrd_size  0) {
-- 
1.7.9.5




Re: [Qemu-devel] [PATCH v2 5/7] exec: memory radix tree page level?compression

2013-11-17 Thread Avi Kivity

On 11/17/2013 05:37 PM, Michael S. Tsirkin wrote:

On Thu, Nov 14, 2013 at 05:42:26PM +0200, Avi Kivity wrote:

On 11/14/2013 05:37 PM, Michael S. Tsirkin wrote:

On Thu, Nov 14, 2013 at 04:56:43PM +0200, Avi Kivity wrote:

On 11/14/2013 04:40 PM, Michael S. Tsirkin wrote:

On Thu, Nov 14, 2013 at 08:54:11AM +, Avi Kivity wrote:

Michael S. Tsirkin mst at redhat.com writes:


At the moment, memory radix tree is already variable width, but it can
only skip the low bits of address.

This is efficient if we have huge memory regions but inefficient if we
are only using a tiny portion of the address space.

After we have built up the map, detect
configurations where a single L2 entry is valid.

We then speed up the lookup by skipping one or more levels.
In case any levels were skipped, we might end up in a valid section
instead of erroring out. We handle this by checking that
the address is in range of the resulting section.


I think this is overkill.  It can be done in a simpler way as follows:


phys_page_find(RadixTree* tr, hwaddr index, ...)
{
if (index  rt-invalid_index_mask) {
// not found
}
lp = rt-root;
for (i = rt-nb_levels - 1; i = 0  !lp.is_leaf; --i) {
  ...

This exploits the fact the lower portion of the address space is always
filled, at least in the cases that matter to us.






Basically skip unused high bits?
Sure.
In fact I think both optimizations can be combined.

Not much value in combining them -- the variable level tree check
will be dominated by the level skip logic.

IMO however skipping intermediate levels will be too rare to justify
the complexity and the doubling of the page table size -- it can
only happen in iommu setups that place memory in very high
addresses.  These ought to be rare.


Well maybe not very high address, but you can have a device with
a 64 bit bar and this will add back levels (though it would not
be slower than it is currently).

I agree the simplicity is attractive.

However I really would like some logic that can handle  1 leaf
somehow.

Specifically both tricks break if we add a full 64 bit io region
in order to return -1 for reads on master abort.

That can be achieved by directing a missed lookup to a catch-all region.

It would be best to do this completely internally to the memory
code, without API changes.

You mean e.g. add a catch-all region to the address space?



The API already specifies a catch-all region - the container region 
catches everything if an access doesn't hit a sub-region (though I 
wanted to discourage the practice of using the same region for both I/O 
and a container), or you can have an I/O region as a subregion with the 
lowest priority, that spans the entire space, so that any access which 
misses the other sub-regions will hit the default subregion.


So we don't need API changes, just to change the internals.

I think this can be done by looking at the address space, and finding 
out what region is mapped to the very last byte in the address space, if 
any, and using that as the default if an access misses the tree.  That 
is, this region will be the target of null pointers in the tree, or if 
(addr  addr_invalid_mask) is true.


This will ensure the tree is of the smallest possible size.

Another option is to simply give up on the tree and use 
std::binary_search() on the FlatView.  It will be more cpu intensive, 
but on the other hand more cache-friendly.  tcg already caches stuff in 
the iotlb, and maybe it makes sense to add a cache for kvm lookups too 
(the advantage of the cache is that it only needs to contain addresses 
that are actually touched, so it can be very small and fast, compared to 
the radix tree which needs to cover all addresses).





Re: [Qemu-devel] [PATCH] fix initrd load failed

2013-11-17 Thread Peter Maydell
On 17 November 2013 16:10, ChenQun chenq...@gmail.com wrote:
 Here's a bug, some examples are as follows:
 1.Assuming Guest's filesystem size 6M.
 2.For vexpress_a15, the loader_start = 2048M.
 If we set guest ram_size range from  2048M+128M to 2048M+128M+6M,
   then the initrd load failed.
 3.For mach-virt, the loader_start = 128M.
 If we set guest ram_size range from 256M to 256M+6M, then it is
 failed too.

 So,it is a bug for load initrd max mem calculation.
 It should be (ram_size + loader_start - initrd_start).

Yes, this is definitely a bug. The set of addresses/sizes we
pass to the loader is a bit of a mess, though -- we kind of
implicitly assume that loader_start means bottom of RAM,
and that all the ram is in one chunk. However for example
realview-pbx-a9 sets loader_start to 0 when the size of that
bit of RAM may be less than the total ram_size. The device
tree editing code also assumes a single contiguous block
of RAM...

thanks
-- PMM



[Qemu-devel] [PATCH for 1.7] acpi-build: Fix compiler warning (missing gnu_printf format attribute)

2013-11-17 Thread Stefan Weil
gcc 4.8.2 reports this warning when extra warnings are enabled (-Wextra):

  CCm68k-softmmu/hw/m68k/mcf5206.o
hw/i386/acpi-build.c: In function ‘build_append_nameseg’:
hw/i386/acpi-build.c:294:5: error:
 function might be possible candidate for ‘gnu_printf’ format attribute 
[-Werror=suggest-attribute=format]
 g_string_vprintf(s, format, args);
 ^

When this warning is fixed, there is a new compiler warning:

  CCi386-softmmu/hw/i386/acpi-build.o
hw/i386/acpi-build.c: In function ‘build_append_notify’:
hw/i386/acpi-build.c:632:5: error:
 format not a string literal and no format arguments [-Werror=format-security]
 build_append_nameseg(method, name);
 ^

This is fixed here, too.

Signed-off-by: Stefan Weil s...@weilnetz.de
---

Note: checkpatch.pl wrongly reports an error.

 hw/i386/acpi-build.c |5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 486e705..9fff5ba 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -285,7 +285,8 @@ static inline void build_append_array(GArray *array, GArray 
*val)
 g_array_append_vals(array, val-data, val-len);
 }
 
-static void build_append_nameseg(GArray *array, const char *format, ...)
+static void GCC_FMT_ATTR(2, 3)
+build_append_nameseg(GArray *array, const char *format, ...)
 {
 GString *s = g_string_new();
 va_list args;
@@ -628,7 +629,7 @@ build_append_notify(GArray *device, const char *name,
 GArray *method = build_alloc_array();
 uint8_t op = 0x14; /* MethodOp */
 
-build_append_nameseg(method, name);
+build_append_nameseg(method, %s, name);
 build_append_byte(method, 0x02); /* MethodFlags: ArgCount */
 for (i = skip; i  count; i++) {
 GArray *target = build_alloc_array();
-- 
1.7.10.4




[Qemu-devel] [PATCH for 1.7] qobject: Fix compiler warning (missing gnu_printf format attribute)

2013-11-17 Thread Stefan Weil
gcc 4.8.2 reports this warning when extra warnings are enabled (-Wextra):

  CCqobject/qerror.o
qobject/qerror.c: In function ‘qerror_from_info’:
qobject/qerror.c:53:5: error:
 function might be possible candidate for ‘gnu_printf’ format attribute 
[-Werror=suggest-attribute=format]
 qerr-err_msg = g_strdup_vprintf(fmt, *va);
 ^

Signed-off-by: Stefan Weil s...@weilnetz.de
---

Note: checkpatch.pl wrongly reports an error.

 qobject/qerror.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/qobject/qerror.c b/qobject/qerror.c
index 3aee1cf..fc8331a 100644
--- a/qobject/qerror.c
+++ b/qobject/qerror.c
@@ -42,8 +42,8 @@ static QError *qerror_new(void)
  *
  * Return strong reference.
  */
-static QError *qerror_from_info(ErrorClass err_class, const char *fmt,
-va_list *va)
+static QError * GCC_FMT_ATTR(2, 0)
+qerror_from_info(ErrorClass err_class, const char *fmt, va_list *va)
 {
 QError *qerr;
 
-- 
1.7.10.4




[Qemu-devel] [PATCH for 1.7] qga: Fix compiler warnings (missing gnu_printf format attribute, wrong format string)

2013-11-17 Thread Stefan Weil
gcc 4.8.2 reports this warning when extra warnings are enabled (-Wextra):

  CCqga/commands.o
qga/commands.c: In function ‘slog’:
qga/commands.c:28:5: error:
 function might be possible candidate for ‘gnu_printf’ format attribute 
[-Werror=suggest-attribute=format]
 g_logv(syslog, G_LOG_LEVEL_INFO, fmt, ap);
 ^

gcc 4.8.2 reports this warning when slog is declared with the
gnu_printf format attribute:

qga/commands-posix.c: In function ‘qmp_guest_file_open’:
qga/commands-posix.c:404:5: warning:
 format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int64_t’ 
[-Wformat=]
 slog(guest-file-open, handle: %d, handle);
 ^

Signed-off-by: Stefan Weil s...@weilnetz.de
---

Note: checkpatch.pl wrongly reports an error.

 qga/commands-posix.c   |2 +-
 qga/guest-agent-core.h |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index f453132..182279d 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -401,7 +401,7 @@ int64_t qmp_guest_file_open(const char *path, bool 
has_mode, const char *mode, E
 return -1;
 }
 
-slog(guest-file-open, handle: %d, handle);
+slog(guest-file-open, handle: % PRId64, handle);
 return handle;
 }
 
diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h
index 624a559..95721eb 100644
--- a/qga/guest-agent-core.h
+++ b/qga/guest-agent-core.h
@@ -29,7 +29,7 @@ GACommandState *ga_command_state_new(void);
 bool ga_logging_enabled(GAState *s);
 void ga_disable_logging(GAState *s);
 void ga_enable_logging(GAState *s);
-void slog(const gchar *fmt, ...);
+void GCC_FMT_ATTR(1, 2) slog(const gchar *fmt, ...);
 void ga_set_response_delimited(GAState *s);
 bool ga_is_frozen(GAState *s);
 void ga_set_frozen(GAState *s);
-- 
1.7.10.4




[Qemu-devel] [PATCH for 1.7 v2] qga: Fix compiler warnings (missing format attribute, wrong format strings)

2013-11-17 Thread Stefan Weil
gcc 4.8.2 reports this warning when extra warnings are enabled (-Wextra):

  CCqga/commands.o
qga/commands.c: In function ‘slog’:
qga/commands.c:28:5: error:
 function might be possible candidate for ‘gnu_printf’ format attribute 
[-Werror=suggest-attribute=format]
 g_logv(syslog, G_LOG_LEVEL_INFO, fmt, ap);
 ^

gcc 4.8.2 reports this warning when slog is declared with the
gnu_printf format attribute:

qga/commands-posix.c: In function ‘qmp_guest_file_open’:
qga/commands-posix.c:404:5: warning:
 format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int64_t’ 
[-Wformat=]
 slog(guest-file-open, handle: %d, handle);
 ^

On 32 bit hosts there are three more warnings which are also fixed here.

Signed-off-by: Stefan Weil s...@weilnetz.de
---

v2: Fix three more wrong format strings for 32 bit hosts.

 qga/commands-posix.c   |8 
 qga/guest-agent-core.h |2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 10682f5..8100bee 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -401,7 +401,7 @@ int64_t qmp_guest_file_open(const char *path, bool 
has_mode, const char *mode, E
 return -1;
 }
 
-slog(guest-file-open, handle: %d, handle);
+slog(guest-file-open, handle: % PRId64, handle);
 return handle;
 }
 
@@ -410,7 +410,7 @@ void qmp_guest_file_close(int64_t handle, Error **err)
 GuestFileHandle *gfh = guest_file_handle_find(handle, err);
 int ret;
 
-slog(guest-file-close called, handle: %ld, handle);
+slog(guest-file-close called, handle: % PRId64, handle);
 if (!gfh) {
 return;
 }
@@ -451,7 +451,7 @@ struct GuestFileRead *qmp_guest_file_read(int64_t handle, 
bool has_count,
 read_count = fread(buf, 1, count, fh);
 if (ferror(fh)) {
 error_setg_errno(err, errno, failed to read file);
-slog(guest-file-read failed, handle: %ld, handle);
+slog(guest-file-read failed, handle: % PRId64, handle);
 } else {
 buf[read_count] = 0;
 read_data = g_malloc0(sizeof(GuestFileRead));
@@ -496,7 +496,7 @@ GuestFileWrite *qmp_guest_file_write(int64_t handle, const 
char *buf_b64,
 write_count = fwrite(buf, 1, count, fh);
 if (ferror(fh)) {
 error_setg_errno(err, errno, failed to write to file);
-slog(guest-file-write failed, handle: %ld, handle);
+slog(guest-file-write failed, handle: % PRId64, handle);
 } else {
 write_data = g_malloc0(sizeof(GuestFileWrite));
 write_data-count = write_count;
diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h
index 624a559..e422208 100644
--- a/qga/guest-agent-core.h
+++ b/qga/guest-agent-core.h
@@ -29,7 +29,7 @@ GACommandState *ga_command_state_new(void);
 bool ga_logging_enabled(GAState *s);
 void ga_disable_logging(GAState *s);
 void ga_enable_logging(GAState *s);
-void slog(const gchar *fmt, ...);
+void GCC_FMT_ATTR(1, 2) slog(const gchar *fmt, ...);
 void ga_set_response_delimited(GAState *s);
 bool ga_is_frozen(GAState *s);
 void ga_set_frozen(GAState *s);
-- 
1.7.9.5




Re: [Qemu-devel] [PATCH for 1.7] qga: Fix compiler warnings (missing gnu_printf format attribute, wrong format string)

2013-11-17 Thread Stefan Weil
This patch is superseded by a new one.

v2 fixes three more format strings and is needed for 32 bit hosts.

Stefan


Am 17.11.2013 19:01, schrieb Stefan Weil:
 gcc 4.8.2 reports this warning when extra warnings are enabled (-Wextra):

   CCqga/commands.o
 qga/commands.c: In function ‘slog’:
 qga/commands.c:28:5: error:
  function might be possible candidate for ‘gnu_printf’ format attribute 
 [-Werror=suggest-attribute=format]
  g_logv(syslog, G_LOG_LEVEL_INFO, fmt, ap);
  ^

 gcc 4.8.2 reports this warning when slog is declared with the
 gnu_printf format attribute:

 qga/commands-posix.c: In function ‘qmp_guest_file_open’:
 qga/commands-posix.c:404:5: warning:
  format ‘%d’ expects argument of type ‘int’, but argument 2 has type 
 ‘int64_t’ [-Wformat=]
  slog(guest-file-open, handle: %d, handle);
  ^

 Signed-off-by: Stefan Weil s...@weilnetz.de
 ---

 Note: checkpatch.pl wrongly reports an error.

  qga/commands-posix.c   |2 +-
  qga/guest-agent-core.h |2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)





[Qemu-devel] [Bug 1245924] Re: mips64el magnum emulation broken

2013-11-17 Thread Darkstar
Apparently, this is the fix (althoug I haven't tested it yet)

can someone confirm if it helps, and if so, apply it?

http://virtuallyfun.superglobalmegacorp.com/?p=3245;

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

Title:
  mips64el magnum emulation broken

Status in QEMU:
  New

Bug description:
  I'm trying to run the following:
  qemu-system-mips64el --machine magnum [...]

  The qemu binaries from (k)ubuntu work fine. info version shows
  1.5.0 (Debian 1.5.0+dfsg-3ubuntu5)

  When I try qemu 1.6.1 (compiled from source .tar.bz2), however, qemu
  only shows a black screen when starting.

  I'm using the following BIOS:
  https://mega.co.nz/#!gg0WBYpJ!MqTL3AFPjf4SJipdYgRK3HtFDIxA59YwI6ay5XI3KEc
  which is the exact one linked to in the first guide below (can also be 
downloaded from there)

  I'm following these guides on installing NT4 on qemu
  http://gunkies.org/wiki/Installing_Windows_NT_4.0_on_Qemu(MIPS)
  http://virtuallyfun.superglobalmegacorp.com/?p=2255

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



[Qemu-devel] [Bug 1252011] [NEW] needs pdcurses.dll to start

2013-11-17 Thread David Brenner
Public bug reported:

QEMU version: 1.6.90.0 from 2013 11 16
Host OS: Windows XP SP3 x86
Host machine: 3.2 GHz AMD Athlon 64 dual core processor, 4 GB DDR II (3.2 seen 
by the OS) memory
Guest OS: Grub4Dos boot manager menu
Problem: it needs pdcurses.dll and it won't start without it.

** 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/1252011

Title:
  needs pdcurses.dll to start

Status in QEMU:
  New

Bug description:
  QEMU version: 1.6.90.0 from 2013 11 16
  Host OS: Windows XP SP3 x86
  Host machine: 3.2 GHz AMD Athlon 64 dual core processor, 4 GB DDR II (3.2 
seen by the OS) memory
  Guest OS: Grub4Dos boot manager menu
  Problem: it needs pdcurses.dll and it won't start without it.

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



[Qemu-devel] [Bug 1252009] [NEW] slow boot on USB drives

2013-11-17 Thread David Brenner
Public bug reported:

QEMU version: 1.6.90.0 from 2013 11 16
Host OS: Windows XP SP3 x86
Host machine: 3.2 GHz AMD Athlon 64 dual core processor, 4 GB DDR II (3.2 seen 
by the OS) memory
Guest OS: Grub4Dos boot manager menu
Problem: when I use qemu-system-i386.exe  -drive 
file=\\.\PhysicalDrive1,if=ide,index=0,media=disk,snapshot=off -m 512 it boots 
twice as slow than the 0.15.1.0 version.

** 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/1252009

Title:
  slow boot on USB drives

Status in QEMU:
  New

Bug description:
  QEMU version: 1.6.90.0 from 2013 11 16
  Host OS: Windows XP SP3 x86
  Host machine: 3.2 GHz AMD Athlon 64 dual core processor, 4 GB DDR II (3.2 
seen by the OS) memory
  Guest OS: Grub4Dos boot manager menu
  Problem: when I use qemu-system-i386.exe  -drive 
file=\\.\PhysicalDrive1,if=ide,index=0,media=disk,snapshot=off -m 512 it boots 
twice as slow than the 0.15.1.0 version.

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



[Qemu-devel] [Bug 1252010] [NEW] can't assign enough RAM to the VM

2013-11-17 Thread David Brenner
Public bug reported:

QEMU version: 1.6.90.0 from 2013 11 16
Host OS: Windows XP SP3 x86
Host machine: 3.2 GHz AMD Athlon 64 dual core processor, 4 GB DDR II (3.2 seen 
by the OS) memory
Guest OS: Grub4Dos boot manager menu
Problem: you can't assign more than 880 MB memory to the VM, although with 
0.15.1.0 version you can assign up to 1179 MB.

** 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/1252010

Title:
  can't assign enough RAM to the VM

Status in QEMU:
  New

Bug description:
  QEMU version: 1.6.90.0 from 2013 11 16
  Host OS: Windows XP SP3 x86
  Host machine: 3.2 GHz AMD Athlon 64 dual core processor, 4 GB DDR II (3.2 
seen by the OS) memory
  Guest OS: Grub4Dos boot manager menu
  Problem: you can't assign more than 880 MB memory to the VM, although with 
0.15.1.0 version you can assign up to 1179 MB.

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



Re: [Qemu-devel] [PATCH] arm_gic: Keep track of GICD_CPENDR and GICD_SPENDR

2013-11-17 Thread Christoffer Dall
On Tue, Oct 29, 2013 at 04:10:59PM +, Bhushan Bharat-R65777 wrote:
 Hi Christoffer,
 
 Not related to the patch, for edge type of interrupt, will setting bit in 
 ICD_SPENDR generate interrupt?
 
Hi Bharat,

That depends, if the interrupt was not previously pending, setting the
bit for the corresponding interrupt will cause it to be pending, if the
interrupt is also enabled and has high enough priority, then the
interrupt gets forwarded to the CPU interface and if the corresponding
CPU is not masking interrupts, it will cause an interrupt on the CPU.

The same is actually valid for level-triggered interrupts too, however,
the difference is that if the interrupt was already pending, it has no
effect whatsoever on edge-triggered interrupts, but level-triggered
interrupts will stay pending even if the external line is deasserted.

-Christoffer

 
  -Original Message-
  From: Christoffer Dall [mailto:christoffer.d...@linaro.org]
  Sent: Wednesday, October 23, 2013 8:57 PM
  To: peter.mayd...@linaro.org
  Cc: patc...@linaro.org; qemu-devel@nongnu.org; kvm...@lists.cs.columbia.edu
  Subject: [PATCH] arm_gic: Keep track of GICD_CPENDR and GICD_SPENDR
  
  If software writes to the ISPENDR and sets the pending state of a level-
  triggered interrupt, the falling edge of the hardware input must not clear 
  the
  pending state.  Conversely, if software writes to the ICPENDR, the pending 
  state
  of a level-triggered interrupt should only be cleared if the hardware input 
  is
  not asserted.
  
  This requires an extra state variable to keep track of software writes.
  
  Signed-off-by: Christoffer Dall christoffer.d...@linaro.org
  ---
   hw/intc/arm_gic.c| 20 +---
   hw/intc/arm_gic_common.c |  5 +++--
   hw/intc/gic_internal.h   |  4 
   3 files changed, 24 insertions(+), 5 deletions(-)
  
  diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index d1ddac1..db54061 
  100644
  --- a/hw/intc/arm_gic.c
  +++ b/hw/intc/arm_gic.c
  @@ -101,6 +101,12 @@ static void gic_clear_pending(GICState *s, int irq, 
  int cm,
  uint8_t src)  {
   unsigned cpu;
  
  +/* If a level-triggered interrupt has been set to pending through the
  + * GICD_SPENDR, then a falling edge does not clear the pending state.
  + */
  +if (GIC_TEST_SW_PENDING(irq, cm))
  +return;
  +
   GIC_CLEAR_PENDING(irq, cm);
   if (irq  GIC_NR_SGIS) {
   cpu = (unsigned)ffs(cm) - 1;
  @@ -177,8 +183,9 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu)
   s-last_active[new_irq][cpu] = s-running_irq[cpu];
   /* Clear pending flags for both level and edge triggered interrupts.
  Level triggered IRQs will be reasserted once they become inactive.  
  */
  -gic_clear_pending(s, new_irq, GIC_TEST_MODEL(new_irq) ? ALL_CPU_MASK : 
  cm,
  -  GIC_SGI_SRC(new_irq, cpu));
  +cm = GIC_TEST_MODEL(new_irq) ? ALL_CPU_MASK : cm;
  +GIC_CLEAR_SW_PENDING(new_irq, cm);
  +gic_clear_pending(s, new_irq, cm, GIC_SGI_SRC(new_irq, cpu));
   gic_set_running_irq(s, cpu, new_irq);
   DPRINTF(ACK %d\n, new_irq);
   return new_irq;
  @@ -445,16 +452,23 @@ static void gic_dist_writeb(void *opaque, hwaddr 
  offset,
   for (i = 0; i  8; i++) {
   if (value  (1  i)) {
   GIC_SET_PENDING(irq + i, GIC_TARGET(irq + i));
  +if (!GIC_TEST_TRIGGER(irq + i)) {
  +GIC_SET_SW_PENDING(irq + i, GIC_TARGET(irq + i));
  +}
   }
   }
   } else if (offset  0x300) {
  +int cm = (1  cpu);
   /* Interrupt Clear Pending.  */
   irq = (offset - 0x280) * 8 + GIC_BASE_IRQ;
   if (irq = s-num_irq)
   goto bad_reg;
   for (i = 0; i  8; i++, irq++) {
   if (irq  GIC_NR_SGIS  value  (1  i)) {
  -gic_clear_pending(s, irq, 1  cpu, 0);
  +GIC_CLEAR_SW_PENDING(irq, cm);
  +if (GIC_TEST_TRIGGER(irq + i) || !GIC_TEST_LEVEL(irq, cm)) 
  {
  +GIC_CLEAR_PENDING(irq, cm);
  +}
   }
   }
   } else if (offset  0x400) {
  diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c index
  1d3b738..7f0615f 100644
  --- a/hw/intc/arm_gic_common.c
  +++ b/hw/intc/arm_gic_common.c
  @@ -43,11 +43,12 @@ static int gic_post_load(void *opaque, int version_id)
  
   static const VMStateDescription vmstate_gic_irq_state = {
   .name = arm_gic_irq_state,
  -.version_id = 1,
  -.minimum_version_id = 1,
  +.version_id = 2,
  +.minimum_version_id = 2,
   .fields = (VMStateField[]) {
   VMSTATE_UINT8(enabled, gic_irq_state),
   VMSTATE_UINT8(pending, gic_irq_state),
  +VMSTATE_UINT8(sw_pending, gic_irq_state),
   VMSTATE_UINT8(active, gic_irq_state),
   VMSTATE_UINT8(level, gic_irq_state),
   VMSTATE_BOOL(model, 

Re: [Qemu-devel] [Qemu-trivial] [PATCH for 1.7] acpi-build: Fix compiler warning (missing gnu_printf format attribute)

2013-11-17 Thread Michael Tokarev
17.11.2013 22:00, Stefan Weil wrote:
 gcc 4.8.2 reports this warning when extra warnings are enabled (-Wextra):
 
   CCm68k-softmmu/hw/m68k/mcf5206.o
 hw/i386/acpi-build.c: In function ‘build_append_nameseg’:
 hw/i386/acpi-build.c:294:5: error:
  function might be possible candidate for ‘gnu_printf’ format attribute 
 [-Werror=suggest-attribute=format]
  g_string_vprintf(s, format, args);
  ^

Why are you sending for-1.7 patches which fixes issues which are not
present in 1.7?  As far as I can see, -Wextra isn't enabled in 1.7, is it?

Thanks,

/mjt



Re: [Qemu-devel] [PATCH v2] target-lm32: move model features to LM32CPU

2013-11-17 Thread Michael Walle

Am 2013-10-14 23:46, schrieb Michael Walle:

This allows us to completely remove CPULM32State from DisasContext.
Instead, copy the fields we need to DisasContext.

Cc: Andreas Färber afaer...@suse.de
Signed-off-by: Michael Walle mich...@walle.cc
---

changes since v1:
 - instead of storing a pointer to the cpu definitions, register
   individual cpu types and store features in LM32CPU.
 - cpu_list() iterates over these types now.


ping,

andreas, could you please review this patch?

--
michael




[Qemu-devel] [PATCH] libcacard/cac: Remove unused statement (value stored is never read)

2013-11-17 Thread Stefan Weil
Warning from ccc-analyzer:

libcacard/cac.c:192:13: warning: Value stored to 'ret' is never read
ret = VCARD_DONE;
^ ~~

Here 'ret' is assigned a value inside of a switch statement and also after
that switch statement.

Signed-off-by: Stefan Weil s...@weilnetz.de
---

This patch is not needed for 1.7 (although I think that it is safe).

 libcacard/cac.c |1 -
 1 file changed, 1 deletion(-)

diff --git a/libcacard/cac.c b/libcacard/cac.c
index 7a06b5a..74ef3e3 100644
--- a/libcacard/cac.c
+++ b/libcacard/cac.c
@@ -189,7 +189,6 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,
 pki_applet-sign_buffer = sign_buffer;
 pki_applet-sign_buffer_len = size;
 *response = vcard_make_response(VCARD7816_STATUS_SUCCESS);
-ret = VCARD_DONE;
 break;
 case 0x00:
 /* we now have the whole buffer, do the operation, result will be
-- 
1.7.10.4




[Qemu-devel] [PATCH] libcacard/vcard_emul_nss: Remove unused statement (value stored is never read)

2013-11-17 Thread Stefan Weil
Warning from ccc-analyzer:

libcacard/vcard_emul_nss.c:937:9: warning:
 Value stored to 'cert_count' is never read
cert_count = options-vreader[i].cert_count;
^~~

Signed-off-by: Stefan Weil s...@weilnetz.de
---
 libcacard/vcard_emul_nss.c |1 -
 1 file changed, 1 deletion(-)

diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c
index fb429b1..ee2dfae 100644
--- a/libcacard/vcard_emul_nss.c
+++ b/libcacard/vcard_emul_nss.c
@@ -934,7 +934,6 @@ vcard_emul_init(const VCardEmulOptions *options)
 vreader = vreader_new(options-vreader[i].vname, vreader_emul,
   vreader_emul_delete);
 vreader_add_reader(vreader);
-cert_count = options-vreader[i].cert_count;
 
 vcard_emul_alloc_arrays(certs, cert_len, keys,
 options-vreader[i].cert_count);
-- 
1.7.10.4




Re: [Qemu-devel] [Qemu-trivial] [PATCH for 1.7] acpi-build: Fix compiler warning (missing gnu_printf format attribute)

2013-11-17 Thread Stefan Weil
Am 17.11.2013 21:40, schrieb Michael Tokarev:
 17.11.2013 22:00, Stefan Weil wrote:
 gcc 4.8.2 reports this warning when extra warnings are enabled (-Wextra):

   CCm68k-softmmu/hw/m68k/mcf5206.o
 hw/i386/acpi-build.c: In function ‘build_append_nameseg’:
 hw/i386/acpi-build.c:294:5: error:
  function might be possible candidate for ‘gnu_printf’ format attribute 
 [-Werror=suggest-attribute=format]
  g_string_vprintf(s, format, args);
  ^
 Why are you sending for-1.7 patches which fixes issues which are not
 present in 1.7?  As far as I can see, -Wextra isn't enabled in 1.7, is it?

 Thanks,

 /mjt

We try to use format attributes for all functions with printf like
arguments.

Patch http://patchwork.ozlabs.org/patch/291873/ shows that the format
attribute
not only fixes a compiler warning (which is not shown with the default
settings)
but also uncovers real programming errors.

I use quite a lot of build environments (32 and 64 bit, Linux and
Windows cross builds)
but there still remain more which I don't cover. With the additional
format attributes
any code either is okay and compiles without warning, or it uses a wrong
format string,
so my patches will break only builds which compile broken code.

I think this kind of build breakage is good and important.

Regards,
Stefan




Re: [Qemu-devel] How does cpu_ldx_data translate virtual-physical?

2013-11-17 Thread Richard Henderson
On 11/16/2013 08:12 PM, Martin T wrote:
 So I'm thinking there must be some other place where cpu_ldq_data() gets
 defined which does something else, however, I haven't been able to find it
 searching through the sources.

It's constructed via macro glue.  See include/exec/softmmu_exec.h.


r~



Re: [Qemu-devel] [PATCH v4] ppc: introduce CPUPPCState::cpu_dt_id and CPUState::kvm_cpu_id

2013-11-17 Thread Alexey Kardashevskiy
On 11/15/2013 09:40 PM, Paolo Bonzini wrote:
 Il 15/11/2013 06:14, Alexey Kardashevskiy ha scritto:

 It does not feel that we really need CPUState::kvm_cpu_id and
 direct calling of kvm_arch_vcpu_id() would be enough.
 
 Indeed -- and it should be kvm_ppc_vcpu_id() since other architectures
 do not need it.

And ignore kvm_arch_vcpu_id() for spapr/ppc?


-- 
Alexey



[Qemu-devel] [PATCH v2] spapr: add ibm,(get|set)-system-parameter

2013-11-17 Thread Alexey Kardashevskiy
This adds very basic handlers for ibm,get-system-parameter and
ibm,set-system-parameter RTAS calls.

The only parameter handled at the moment is
platform-processor-diagnostics-run-mode which is always disabled and
does not support changing. This is expected to make
ppc64_cpu --run-mode=1 happy.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
Changes:
v2:
* addressed comments from Alex Graf
---
 hw/ppc/spapr_rtas.c | 48 
 1 file changed, 48 insertions(+)

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index eb542f2..8053a67 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -224,6 +224,50 @@ static void rtas_stop_self(PowerPCCPU *cpu, 
sPAPREnvironment *spapr,
 env-msr = 0;
 }
 
+#define DIAGNOSTICS_RUN_MODE42
+
+static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
+  sPAPREnvironment *spapr,
+  uint32_t token, uint32_t nargs,
+  target_ulong args,
+  uint32_t nret, target_ulong rets)
+{
+target_ulong papameter = rtas_ld(args, 0);
+target_ulong buffer = rtas_ld(args, 1);
+target_ulong length = rtas_ld(args, 2);
+target_ulong ret = -3; /* System parameter is not supported */
+
+switch (papameter) {
+case DIAGNOSTICS_RUN_MODE:
+if (length == 1) {
+rtas_st(buffer, 0, 0);
+ret = 0; /* Success */
+}
+break;
+}
+
+rtas_st(rets, 0, ret);
+}
+
+static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
+  sPAPREnvironment *spapr,
+  uint32_t token, uint32_t nargs,
+  target_ulong args,
+  uint32_t nret, target_ulong rets)
+{
+target_ulong papameter = rtas_ld(args, 0);
+/* target_ulong buffer = rtas_ld(args, 1); */
+target_ulong ret = -3; /* System parameter is not supported */
+
+switch (papameter) {
+case DIAGNOSTICS_RUN_MODE:
+ret = -9002; /* Setting not allowed/authorized */
+break;
+}
+
+rtas_st(rets, 0, ret);
+}
+
 static struct rtas_call {
 const char *name;
 spapr_rtas_fn fn;
@@ -345,6 +389,10 @@ static void core_rtas_register_types(void)
 rtas_query_cpu_stopped_state);
 spapr_rtas_register(start-cpu, rtas_start_cpu);
 spapr_rtas_register(stop-self, rtas_stop_self);
+spapr_rtas_register(ibm,get-system-parameter,
+rtas_ibm_get_system_parameter);
+spapr_rtas_register(ibm,set-system-parameter,
+rtas_ibm_set_system_parameter);
 }
 
 type_init(core_rtas_register_types)
-- 
1.8.4.rc4




[Qemu-devel] [PATCH v5 2/2] spapr: limit numa memory regions by ram size

2013-11-17 Thread Alexey Kardashevskiy
From: Paul Mackerras pau...@samba.org

This makes sure that all NUMA memory blocks beside within RAM or
have zero length.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---

This is a bugfix for:
-m 500
-smp 8,sockets=2,cores=2,threads=2
-numa node,nodeid=0,cpus=0-3,mem=500
-numa node,nodeid=1,cpus=4-7,mem=500
---
 hw/ppc/spapr.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 036246c..a7f6af8 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -526,12 +526,16 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, 
void *fdt)
 cpu_to_be32(0x0), cpu_to_be32(0x0),
 cpu_to_be32(0x0)};
 char mem_name[32];
-hwaddr node0_size, mem_start;
+hwaddr node0_size, mem_start, node_size;
 uint64_t mem_reg_property[2];
 int i, off;
 
 /* memory node(s) */
-node0_size = (nb_numa_nodes  1) ? node_mem[0] : ram_size;
+if (nb_numa_nodes  1  node_mem[0]  ram_size) {
+node0_size = node_mem[0];
+} else {
+node0_size = ram_size;
+}
 
 /* RMA */
 mem_reg_property[0] = 0;
@@ -563,7 +567,15 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, 
void *fdt)
 mem_start = node0_size;
 for (i = 1; i  nb_numa_nodes; i++) {
 mem_reg_property[0] = cpu_to_be64(mem_start);
-mem_reg_property[1] = cpu_to_be64(node_mem[i]);
+if (mem_start = ram_size) {
+node_size = 0;
+} else {
+node_size = node_mem[i];
+if (node_size  ram_size - mem_start) {
+node_size = ram_size - mem_start;
+}
+}
+mem_reg_property[1] = cpu_to_be64(node_size);
 associativity[3] = associativity[4] = cpu_to_be32(i);
 sprintf(mem_name, memory@ TARGET_FMT_lx, mem_start);
 off = fdt_add_subnode(fdt, 0, mem_name);
@@ -573,7 +585,7 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, 
void *fdt)
   sizeof(mem_reg_property;
 _FDT((fdt_setprop(fdt, off, ibm,associativity, associativity,
   sizeof(associativity;
-mem_start += node_mem[i];
+mem_start += node_size;
 }
 
 return 0;
-- 
1.8.4.rc4




[Qemu-devel] [PATCH v5 1/2] spapr: make sure RMA is in first mode of first memory node

2013-11-17 Thread Alexey Kardashevskiy
The SPAPR specification says that the RMA starts at the LPAR's logical
address 0 and is the first logical memory block reported in
the LPAR’s device tree.

So SLOF only maps the first block and that block needs to span
the full RMA.

This makes sure that the RMA area is where SLOF expects it.

Reviewed-by: Thomas Huth th...@linux.vnet.ibm.com
Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
---
Changes:
v4:
* fixed a bug with preallocated RMA (thanks to Thomas Huth)

v3:
* removed unnecessary RMA fixup from spapr_populate_memory()

v2:
* changed as recommended by Alex Graf
---
 hw/ppc/spapr.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 7e53a5f..036246c 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -532,9 +532,6 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, 
void *fdt)
 
 /* memory node(s) */
 node0_size = (nb_numa_nodes  1) ? node_mem[0] : ram_size;
-if (spapr-rma_size  node0_size) {
-spapr-rma_size = node0_size;
-}
 
 /* RMA */
 mem_reg_property[0] = 0;
@@ -1113,6 +1110,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
 MemoryRegion *sysmem = get_system_memory();
 MemoryRegion *ram = g_new(MemoryRegion, 1);
 hwaddr rma_alloc_size;
+hwaddr node0_size = (nb_numa_nodes  1) ? node_mem[0] : ram_size;
 uint32_t initrd_base = 0;
 long kernel_size = 0, initrd_size = 0;
 long load_limit, rtas_limit, fw_size;
@@ -1134,10 +1132,10 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
 exit(1);
 }
 
-if (rma_alloc_size  (rma_alloc_size  ram_size)) {
+if (rma_alloc_size  (rma_alloc_size  node0_size)) {
 spapr-rma_size = rma_alloc_size;
 } else {
-spapr-rma_size = ram_size;
+spapr-rma_size = node0_size;
 
 /* With KVM, we don't actually know whether KVM supports an
  * unbounded RMA (PR KVM) or is limited by the hash table size
@@ -1154,6 +1152,12 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
 }
 }
 
+if (spapr-rma_size  node0_size) {
+fprintf(stderr, Error: Numa node 0 has to span the RMA 
(%#08HWADDR_PRIx)\n,
+spapr-rma_size);
+exit(1);
+}
+
 /* We place the device tree and RTAS just below either the top of the RMA,
  * or just below 2GB, whichever is lowere, so that it can be
  * processed with 32-bit real mode code if necessary */
-- 
1.8.4.rc4




[Qemu-devel] [PATCH v5 0/2] spapr: rma and numa nodes fixes

2013-11-17 Thread Alexey Kardashevskiy
The first patch got RB from Thomas, and the second one is new but depends
on the first one so I am (re)posting them together. Thanks.


Alexey Kardashevskiy (1):
  spapr: make sure RMA is in first mode of first memory node

Paul Mackerras (1):
  spapr: limit numa memory regions by ram size

 hw/ppc/spapr.c | 32 
 1 file changed, 24 insertions(+), 8 deletions(-)

-- 
1.8.4.rc4




[Qemu-devel] dataplane, thread and gpu stuff

2013-11-17 Thread Dave Airlie
Hi,

So after talking to a few people at kvm forum I think the GPU code
should probably use the dataplane stuff from the outset,

The main advantages I think this gives me is being able to dequeue
objects from the vq from a thread and send irq vectors from there as
well.

Though since it appears the dataplane stuff is kvm specific (at least
the irq handling), I was wondering how I should deal with fallbacks
for non-kvm operation, and quite how much falling back I need to do.

Can I still use the dataplane/vring code from the normal bottom half
handlers or do I have to write separate code for both situations.

Dave.



Re: [Qemu-devel] [PATCH] qemu-img: set nocow flag to new file

2013-11-17 Thread Chunyan Liu
2013/11/15 Stefan Hajnoczi stefa...@gmail.com

 On Thu, Nov 14, 2013 at 04:15:28PM +0800, Chunyan Liu wrote:
  Set NOCOW flag to newly created images to solve performance issues on
 btrfs.
 
  Btrfs has terrible performance when hosting VM images, even more when
 the guest
  in those VM are also using btrfs as file system. One way to mitigate
 this bad
  performance is to turn off COW attributes on VM files (since having copy
 on
  write for this kind of data is not useful).
 
  Signed-off-by: Chunyan Liu cy...@suse.com
  ---
   block/raw-posix.c |6 ++
   block/vdi.c   |7 +++
   block/vmdk.c  |7 +++
   include/qemu-common.h |9 +
   4 files changed, 29 insertions(+), 0 deletions(-)
 
  diff --git a/block/raw-posix.c b/block/raw-posix.c
  index f6d48bb..4a3e9d0 100644
  --- a/block/raw-posix.c
  +++ b/block/raw-posix.c
  @@ -1072,6 +1072,12 @@ static int raw_create(const char *filename,
 QEMUOptionParameter *options,
   result = -errno;
   error_setg_errno(errp, -result, Could not create file);
   } else {
  +#ifdef __linux__
  +/* set NOCOW flag to solve performance issue on fs like btrfs */
  +int attr;
  +attr = FS_NOCOW_FL;
  +ioctl(fd, FS_IOC_SETFLAGS, attr);
  +#endif
 This should be optional and I'm not sure it should be the default.

 Rationale: If you're on btrfs you probably expect the copy-on-write and
 snapshot features of the file system.  We shouldn't silently disable
 that unless the user asks for it.


The problem is: if users want to use copy-on-write (e.g, for snapshotting)
and
don't care about performance degrade, they still be able to issue chattr
to
change it to be COW. However, if a file is created as COW, but later users
care
about performance, there is no way to switch to NOCOW per file. NOCOW
should be
set to new or empty file only on btrfs.

Chunyan

Stefan




Re: [Qemu-devel] [PATCHv2] qemu-img: set nocow flag to new file

2013-11-17 Thread Chunyan Liu
2013/11/15 Kevin Wolf kw...@redhat.com

 Am 15.11.2013 um 06:01 hat Chunyan Liu geschrieben:
  Set NOCOW flag to newly created images to solve performance issues on
 btrfs.
 
  Btrfs has terrible performance when hosting VM images, even more when
 the guest
  in those VM are also using btrfs as file system. One way to mitigate
 this bad
  performance is to turn off COW attributes on VM files (since having copy
 on
  write for this kind of data is not useful).
 
  Signed-off-by: Chunyan Liu cy...@suse.com

  diff --git a/include/qemu-common.h b/include/qemu-common.h
  index 5054836..fe7dd9b 100644
  --- a/include/qemu-common.h
  +++ b/include/qemu-common.h
  @@ -50,6 +50,15 @@
   #include sysemu/os-posix.h
   #endif
 
  +#ifdef __linux__
  +#include linux/fs.h
  +#include sys/ioctl.h
  +
  +#ifndef FS_NOCOW_FL
  +#define FS_NOCOW_FL 0x0080 /* Do not cow file */
  +#endif
  +#endif
  +
   #ifndef O_LARGEFILE
   #define O_LARGEFILE 0
   #endif

 hw/block/m25p80.c:219: Fehler: expected identifier before numeric constant

 On RHEL 6, there seems to be a naming conflict for READ, which is
 present in linux/fs.h and used as a local enum value by m25p80.c.

 Will update for this and GETFLAGS  SETFLAGS.

Thanks,
Chunyan


 Kevin




Re: [Qemu-devel] [PATCH v6 RESENT 0/2] sheepdog: add user-defined redundancy option

2013-11-17 Thread Liu Yuan
On Thu, Nov 07, 2013 at 10:56:36PM +0800, Liu Yuan wrote:
 v6:
  - update comment typo
  - remove is_number()

Anyone pick this set up?

Thanks
Yuan



[Qemu-devel] [PATCH v5 3/4] qemu-iotest: Add pause_drive and resume_drive methods

2013-11-17 Thread Fam Zheng
They wrap blkdebug break and remove_break.

Add optional argument resume to cancel_and_wait().

Signed-off-by: Fam Zheng f...@redhat.com
---
 tests/qemu-iotests/iotests.py | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index fb10ff4..10c9a99 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -107,6 +107,19 @@ class VM(object):
 self._num_drives += 1
 return self
 
+def pause_drive(self, drive, event=None):
+'''Pause drive r/w operations'''
+if not event:
+self.pause_drive(drive, read_aio)
+self.pause_drive(drive, write_aio)
+return
+self.qmp('human-monitor-command',
+command_line='qemu-io %s break %s bp_%s' % (drive, 
event, drive))
+
+def resume_drive(self, drive):
+self.qmp('human-monitor-command',
+command_line='qemu-io %s remove_break bp_%s' % (drive, 
drive))
+
 def hmp_qemu_io(self, drive, cmd):
 '''Write to a given drive using an HMP command'''
 return self.qmp('human-monitor-command',
@@ -222,11 +235,14 @@ class QMPTestCase(unittest.TestCase):
 result = self.vm.qmp('query-block-jobs')
 self.assert_qmp(result, 'return', [])
 
-def cancel_and_wait(self, drive='drive0', force=False):
+def cancel_and_wait(self, drive='drive0', force=False, resume=False):
 '''Cancel a block job and wait for it to finish, returning the event'''
 result = self.vm.qmp('block-job-cancel', device=drive, force=force)
 self.assert_qmp(result, 'return', {})
 
+if resume:
+self.vm.resume_drive(drive)
+
 cancelled = False
 result = None
 while not cancelled:
-- 
1.8.4.2




[Qemu-devel] [PATCH v5 1/4] qemu-iotests: Drop local version of cancel_and_wait from 040

2013-11-17 Thread Fam Zheng
iotests.py already has one.

Signed-off-by: Fam Zheng f...@redhat.com
---
 tests/qemu-iotests/040 | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040
index a2e18c5..0e85136 100755
--- a/tests/qemu-iotests/040
+++ b/tests/qemu-iotests/040
@@ -39,21 +39,6 @@ class ImageCommitTestCase(iotests.QMPTestCase):
 result = self.vm.qmp('query-block-jobs')
 self.assert_qmp(result, 'return', [])
 
-def cancel_and_wait(self, drive='drive0'):
-'''Cancel a block job and wait for it to finish'''
-result = self.vm.qmp('block-job-cancel', device=drive)
-self.assert_qmp(result, 'return', {})
-
-cancelled = False
-while not cancelled:
-for event in self.vm.get_qmp_events(wait=True):
-if event['event'] == 'BLOCK_JOB_CANCELLED':
-self.assert_qmp(event, 'data/type', 'commit')
-self.assert_qmp(event, 'data/device', drive)
-cancelled = True
-
-self.assert_no_active_commit()
-
 class TestSingleDrive(ImageCommitTestCase):
 image_len = 1 * 1024 * 1024
 test_len = 1 * 1024 * 256
-- 
1.8.4.2




[Qemu-devel] [PATCH v5 0/4] Use blkdebug to make test deterministic

2013-11-17 Thread Fam Zheng
This adds remove_break command to block, which removes a break point defined
with break. It is used in iotests.py to pause and resume drive in block job
cases to make the test deterministic.

v5: Addressing Max's comments (thanks for reviewing)
[02] Resume all the requests.
[03] Fix event= case. Change default value to None.
 Change resume to bool.
[04] Change resume to bool

v4: [01] Added.
[03] Add common method pair pause_drive and resume_drive.
[04] Also fix 040, 055.

Fam Zheng (4):
  qemu-iotests: Drop local version of cancel_and_wait from 040
  blkdebug: add remove_break command
  qemu-iotest: Add pause_drive and resume_drive methods
  qemu-iotests: Make test case 030, 040 and 055 deterministic

 block.c   | 13 +
 block/blkdebug.c  | 27 +++
 include/block/block.h |  1 +
 include/block/block_int.h |  2 ++
 qemu-io-cmds.c| 22 ++
 tests/qemu-iotests/030| 16 +++-
 tests/qemu-iotests/040| 19 +++
 tests/qemu-iotests/055| 15 +++
 tests/qemu-iotests/iotests.py | 18 +-
 9 files changed, 107 insertions(+), 26 deletions(-)

-- 
1.8.4.2




[Qemu-devel] [PATCH v5 2/4] blkdebug: add remove_break command

2013-11-17 Thread Fam Zheng
This adds remove_break command which is the reverse of blkdebug
command break: it removes all breakpoints with given tag and resumes
all the requests.

Signed-off-by: Fam Zheng f...@redhat.com
---
 block.c   | 13 +
 block/blkdebug.c  | 27 +++
 include/block/block.h |  1 +
 include/block/block_int.h |  2 ++
 qemu-io-cmds.c| 22 ++
 5 files changed, 65 insertions(+)

diff --git a/block.c b/block.c
index 6d5c804..70cebc2 100644
--- a/block.c
+++ b/block.c
@@ -3412,6 +3412,19 @@ int bdrv_debug_breakpoint(BlockDriverState *bs, const 
char *event,
 return -ENOTSUP;
 }
 
+int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag)
+{
+while (bs  bs-drv  !bs-drv-bdrv_debug_remove_breakpoint) {
+bs = bs-file;
+}
+
+if (bs  bs-drv  bs-drv-bdrv_debug_remove_breakpoint) {
+return bs-drv-bdrv_debug_remove_breakpoint(bs, tag);
+}
+
+return -ENOTSUP;
+}
+
 int bdrv_debug_resume(BlockDriverState *bs, const char *tag)
 {
 while (bs  bs-drv  !bs-drv-bdrv_debug_resume) {
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 16d2b91..37cf028 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -605,6 +605,31 @@ static int blkdebug_debug_resume(BlockDriverState *bs, 
const char *tag)
 return -ENOENT;
 }
 
+static int blkdebug_debug_remove_breakpoint(BlockDriverState *bs,
+const char *tag)
+{
+BDRVBlkdebugState *s = bs-opaque;
+BlkdebugSuspendedReq *r;
+BlkdebugRule *rule, *next;
+int i, ret = -ENOENT;
+
+for (i = 0; i  BLKDBG_EVENT_MAX; i++) {
+QLIST_FOREACH_SAFE(rule, s-rules[i], next, next) {
+if (rule-action == ACTION_SUSPEND 
+!strcmp(rule-options.suspend.tag, tag)) {
+remove_rule(rule);
+ret = 0;
+}
+}
+}
+QLIST_FOREACH(r, s-suspended_reqs, next) {
+if (!strcmp(r-tag, tag)) {
+qemu_coroutine_enter(r-co, NULL);
+ret = 0;
+}
+}
+return ret;
+}
 
 static bool blkdebug_debug_is_suspended(BlockDriverState *bs, const char *tag)
 {
@@ -639,6 +664,8 @@ static BlockDriver bdrv_blkdebug = {
 
 .bdrv_debug_event   = blkdebug_debug_event,
 .bdrv_debug_breakpoint  = blkdebug_debug_breakpoint,
+.bdrv_debug_remove_breakpoint
+= blkdebug_debug_remove_breakpoint,
 .bdrv_debug_resume  = blkdebug_debug_resume,
 .bdrv_debug_is_suspended= blkdebug_debug_is_suspended,
 };
diff --git a/include/block/block.h b/include/block/block.h
index 3560deb..6b17495 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -484,6 +484,7 @@ void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent 
event);
 
 int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
const char *tag);
+int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag);
 int bdrv_debug_resume(BlockDriverState *bs, const char *tag);
 bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag);
 
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 1666066..659dcf4 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -218,6 +218,8 @@ struct BlockDriver {
 /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */
 int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event,
 const char *tag);
+int (*bdrv_debug_remove_breakpoint)(BlockDriverState *bs,
+const char *tag);
 int (*bdrv_debug_resume)(BlockDriverState *bs, const char *tag);
 bool (*bdrv_debug_is_suspended)(BlockDriverState *bs, const char *tag);
 
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 667f4e4..4cab57e 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -1956,6 +1956,18 @@ static int break_f(BlockDriverState *bs, int argc, char 
**argv)
 return 0;
 }
 
+static int remove_break_f(BlockDriverState *bs, int argc, char **argv)
+{
+int ret;
+
+ret = bdrv_debug_remove_breakpoint(bs, argv[1]);
+if (ret  0) {
+printf(Could not remove breakpoint %s: %s\n, argv[1], 
strerror(-ret));
+}
+
+return 0;
+}
+
 static const cmdinfo_t break_cmd = {
.name   = break,
.argmin = 2,
@@ -1966,6 +1978,15 @@ static const cmdinfo_t break_cmd = {
  request as tag,
 };
 
+static const cmdinfo_t remove_break_cmd = {
+   .name   = remove_break,
+   .argmin = 1,
+   .argmax = 1,
+   .cfunc  = remove_break_f,
+   .args   = tag,
+   .oneline= remove a breakpoint by tag,
+};
+
 static int resume_f(BlockDriverState *bs, int argc, char **argv)
 {
 int ret;
@@ -2126,6 +2147,7 @@ static void __attribute((constructor)) 
init_qemuio_commands(void)
 qemuio_add_command(alloc_cmd);
 

[Qemu-devel] [PATCH v5 4/4] qemu-iotests: Make test case 030, 040 and 055 deterministic

2013-11-17 Thread Fam Zheng
Pause the drive and start the block job, so we won't miss the block job.

Signed-off-by: Fam Zheng f...@redhat.com
---
 tests/qemu-iotests/030 | 16 +++-
 tests/qemu-iotests/040 |  4 +++-
 tests/qemu-iotests/055 | 15 +++
 3 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
index d0f96ea..59a34f7 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -34,6 +34,7 @@ class TestSingleDrive(iotests.QMPTestCase):
 iotests.create_image(backing_img, TestSingleDrive.image_len)
 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % 
backing_img, mid_img)
 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % 
mid_img, test_img)
+qemu_io('-c', 'write -P 0x1 0 512', backing_img)
 self.vm = iotests.VM().add_drive(test_img)
 self.vm.launch()
 
@@ -69,6 +70,7 @@ class TestSingleDrive(iotests.QMPTestCase):
 def test_stream_pause(self):
 self.assert_no_active_block_jobs()
 
+self.vm.pause_drive('drive0')
 result = self.vm.qmp('block-stream', device='drive0')
 self.assert_qmp(result, 'return', {})
 
@@ -86,6 +88,7 @@ class TestSingleDrive(iotests.QMPTestCase):
 result = self.vm.qmp('block-job-resume', device='drive0')
 self.assert_qmp(result, 'return', {})
 
+self.vm.resume_drive('drive0')
 completed = False
 while not completed:
 for event in self.vm.get_qmp_events(wait=True):
@@ -391,7 +394,7 @@ class TestStreamStop(iotests.QMPTestCase):
 qemu_io('-c', 'write -P 0x1 0 32M', backing_img)
 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % 
backing_img, test_img)
 qemu_io('-c', 'write -P 0x1 32M 32M', test_img)
-self.vm = iotests.VM().add_drive(test_img)
+self.vm = iotests.VM().add_drive(blkdebug:: + test_img)
 self.vm.launch()
 
 def tearDown(self):
@@ -402,6 +405,7 @@ class TestStreamStop(iotests.QMPTestCase):
 def test_stream_stop(self):
 self.assert_no_active_block_jobs()
 
+self.vm.pause_drive('drive0')
 result = self.vm.qmp('block-stream', device='drive0')
 self.assert_qmp(result, 'return', {})
 
@@ -409,7 +413,7 @@ class TestStreamStop(iotests.QMPTestCase):
 events = self.vm.get_qmp_events(wait=False)
 self.assertEqual(events, [], 'unexpected QMP event: %s' % events)
 
-self.cancel_and_wait()
+self.cancel_and_wait(resume=True)
 
 class TestSetSpeed(iotests.QMPTestCase):
 image_len = 80 * 1024 * 1024 # MB
@@ -419,7 +423,7 @@ class TestSetSpeed(iotests.QMPTestCase):
 qemu_io('-c', 'write -P 0x1 0 32M', backing_img)
 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % 
backing_img, test_img)
 qemu_io('-c', 'write -P 0x1 32M 32M', test_img)
-self.vm = iotests.VM().add_drive(test_img)
+self.vm = iotests.VM().add_drive('blkdebug::' + test_img)
 self.vm.launch()
 
 def tearDown(self):
@@ -453,6 +457,7 @@ class TestSetSpeed(iotests.QMPTestCase):
 def test_set_speed(self):
 self.assert_no_active_block_jobs()
 
+self.vm.pause_drive('drive0')
 result = self.vm.qmp('block-stream', device='drive0')
 self.assert_qmp(result, 'return', {})
 
@@ -469,7 +474,8 @@ class TestSetSpeed(iotests.QMPTestCase):
 self.assert_qmp(result, 'return[0]/device', 'drive0')
 self.assert_qmp(result, 'return[0]/speed', 8 * 1024 * 1024)
 
-self.cancel_and_wait()
+self.cancel_and_wait(resume=True)
+self.vm.pause_drive('drive0')
 
 # Check setting speed in block-stream works
 result = self.vm.qmp('block-stream', device='drive0', speed=4 * 1024 * 
1024)
@@ -479,7 +485,7 @@ class TestSetSpeed(iotests.QMPTestCase):
 self.assert_qmp(result, 'return[0]/device', 'drive0')
 self.assert_qmp(result, 'return[0]/speed', 4 * 1024 * 1024)
 
-self.cancel_and_wait()
+self.cancel_and_wait(resume=True)
 
 def test_set_speed_invalid(self):
 self.assert_no_active_block_jobs()
diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040
index 0e85136..18dcd61 100755
--- a/tests/qemu-iotests/040
+++ b/tests/qemu-iotests/040
@@ -228,6 +228,7 @@ class TestSetSpeed(ImageCommitTestCase):
 qemu_img('create', backing_img, str(TestSetSpeed.image_len))
 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % 
backing_img, mid_img)
 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % 
mid_img, test_img)
+qemu_io('-c', 'write -P 0x1 0 512', test_img)
 self.vm = iotests.VM().add_drive(test_img)
 self.vm.launch()
 
@@ -240,6 +241,7 @@ class TestSetSpeed(ImageCommitTestCase):
 def test_set_speed(self):
 self.assert_no_active_commit()
 
+self.vm.pause_drive('drive0')
 result = 

[Qemu-devel] [PATCH 0/2] qemu-iotests: Filter out qemu-io in all tests

2013-11-17 Thread Fam Zheng


Fam Zheng (2):
  qemu-iotests: Filter qemu-io output in 025
  qemu-iotests: Filter out 'qemu-io ' prompt

 tests/qemu-iotests/013.out   | 44080 -
 tests/qemu-iotests/014.out   | 64204 ++---
 tests/qemu-iotests/017.out   |  1080 +-
 tests/qemu-iotests/018.out   |  1080 +-
 tests/qemu-iotests/019.out   |  1636 +-
 tests/qemu-iotests/020.out   |  1080 +-
 tests/qemu-iotests/022.out   |  8816 ++---
 tests/qemu-iotests/023.out   | 26800 
 tests/qemu-iotests/024.out   |   164 +-
 tests/qemu-iotests/025   | 2 +-
 tests/qemu-iotests/025.out   |18 +-
 tests/qemu-iotests/028.out   |   458 +-
 tests/qemu-iotests/032.out   |68 +-
 tests/qemu-iotests/035.out   | 2 +-
 tests/qemu-iotests/037.out   |   616 +-
 tests/qemu-iotests/038.out   |   714 +-
 tests/qemu-iotests/046.out   |   232 +-
 tests/qemu-iotests/047.out   |20 +-
 tests/qemu-iotests/048.out   |18 +-
 tests/qemu-iotests/common.filter | 3 +-
 20 files changed, 75546 insertions(+), 75545 deletions(-)

-- 
1.8.4.2




[Qemu-devel] [PATCH 1/2] qemu-iotests: Filter qemu-io output in 025

2013-11-17 Thread Fam Zheng
Signed-off-by: Fam Zheng f...@redhat.com
---
 tests/qemu-iotests/025 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/025 b/tests/qemu-iotests/025
index a7241cc..9426c93 100755
--- a/tests/qemu-iotests/025
+++ b/tests/qemu-iotests/025
@@ -56,7 +56,7 @@ _check_test_img
 
 echo
 echo === Resizing image
-$QEMU_IO $TEST_IMG EOF
+$QEMU_IO $TEST_IMG EOF | _filter_qemu_io
 length
 truncate $big_size
 length
-- 
1.8.4.2