Re: [Qemu-devel] [PATCH v3 0/5] kvm "virtio pmem" device

2019-01-13 Thread Dave Chinner
On Sun, Jan 13, 2019 at 03:38:21PM -0800, Matthew Wilcox wrote:
> On Mon, Jan 14, 2019 at 10:29:02AM +1100, Dave Chinner wrote:
> > Until you have images (and hence host page cache) shared between
> > multiple guests. People will want to do this, because it means they
> > only need a single set of pages in host memory for executable
> > binaries rather than a set of pages per guest. Then you have
> > multiple guests being able to detect residency of the same set of
> > pages. If the guests can then, in any way, control eviction of the
> > pages from the host cache, then we have a guest-to-guest information
> > leak channel.
> 
> I don't think we should ever be considering something that would allow a
> guest to evict page's from the host's pagecache [1].  The guest should
> be able to kick its own references to the host's pagecache out of its
> own pagecache, but not be able to influence whether the host or another
> guest has a read-only mapping cached.
> 
> [1] Unless the guest is allowed to modify the host's file; obviously
> truncation, holepunching, etc are going to evict pages from the host's
> page cache.

Right, and that's exactly what I mean by "we need to be real careful
with functionality like this".

To be honest, I really don't think I've even touched the surface
here.

e.g. Filesystems and storage can share logical and physical extents.
Which means that image files that share storage (e.g.  because they
are all cloned from the same master image and/or there's in-line
deduplication running on the storage) and can be directly accessed
by guests may very well be susceptible to detection of host side
deduplication and subsequent copy-on-write operations.

This really doesn't seem much different to me from the guest being
able to infer host side KSM page deduplication and COW operation in
the guest side page cache.  The only difference is that DAX is being
used to probe the host side page cache and storage rather than the
guest side.

IOWs, I suspect there's a world of pain waiting for us if we punch
huge holes through the virtual machine abstractions like this.

Improving performance is a laudible goal, but at what price?

Cheers,

Dave.
-- 
Dave Chinner
da...@fromorbit.com



Re: [Qemu-devel] [PATCH 0/9] target/mips: Limited support for R5900 multimedia instructions

2019-01-13 Thread no-reply
Patchew URL: https://patchew.org/QEMU/cover.1547403692.git.nor...@nocrew.org/



Hi,

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

Message-id: cover.1547403692.git.nor...@nocrew.org
Subject: [Qemu-devel] [PATCH 0/9] target/mips: Limited support for R5900 
multimedia instructions
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
de6a446 tests/tcg/mips: Test R5900 multimedia instruction SQ
0088bfa tests/tcg/mips: Test R5900 multimedia instruction LQ
6ff0c3e tests/tcg/mips: Test R5900 multimedia instructions PCPYUD and PCPYLD
9339214 target/mips: Support the R5900 SQ multimedia instruction
fa1b66f target/mips: Support the R5900 LQ multimedia instruction
4d02b79 target/mips: Support the R5900 PCPYUD multimedia instruction
5f97931 target/mips: Support the R5900 PCPYLD multimedia instruction
7788cd9 target/mips: Introduce 32 R5900 128-bit multimedia registers
bfb6880 target/mips: Require TARGET_MIPS64 for R5900 multimedia instructions

=== OUTPUT BEGIN ===
1/9 Checking commit bfb6880b6968 (target/mips: Require TARGET_MIPS64 for R5900 
multimedia instructions)
2/9 Checking commit 7788cd938432 (target/mips: Introduce 32 R5900 128-bit 
multimedia registers)
3/9 Checking commit 5f97931d64fa (target/mips: Support the R5900 PCPYLD 
multimedia instruction)
4/9 Checking commit 4d02b79ee4cc (target/mips: Support the R5900 PCPYUD 
multimedia instruction)
5/9 Checking commit fa1b66faf41f (target/mips: Support the R5900 LQ multimedia 
instruction)
6/9 Checking commit 933921419413 (target/mips: Support the R5900 SQ multimedia 
instruction)
7/9 Checking commit 6ff0c3e10ea7 (tests/tcg/mips: Test R5900 multimedia 
instructions PCPYUD and PCPYLD)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#11: 
new file mode 100644

total: 0 errors, 1 warnings, 71 lines checked

Patch 7/9 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
8/9 Checking commit 0088bfa895fb (tests/tcg/mips: Test R5900 multimedia 
instruction LQ)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#25: 
new file mode 100644

ERROR: "(foo*)" should be "(foo *)"
#77: FILE: tests/tcg/mips/mipsn32r5900/lq.c:48:
+const void *a = (const void*)((unsigned long)o & ~0xFUL);

ERROR: spaces required around that '=' (ctx:VxE)
#96: FILE: tests/tcg/mips/mipsn32r5900/lq.c:67:
+static const char data[] __attribute__((aligned(16)))=
  ^

total: 2 errors, 1 warnings, 120 lines checked

Patch 8/9 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

9/9 Checking commit de6a44645c76 (tests/tcg/mips: Test R5900 multimedia 
instruction SQ)
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#23: 
new file mode 100644

ERROR: "(foo*)" should be "(foo *)"
#61: FILE: tests/tcg/mips/mipsn32r5900/sq.c:34:
+const uint8_t *a = (const uint8_t*)((unsigned long)o & ~0xFUL);

total: 1 errors, 1 warnings, 112 lines checked

Patch 9/9 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/cover.1547403692.git.nor...@nocrew.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [Qemu-devel] [PULLv2 00/65] slirp updates

2019-01-13 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20190114000326.29847-1-samuel.thiba...@ens-lyon.org/



Hi,

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

=== TEST SCRIPT BEGIN ===
#!/bin/bash
time make docker-test-mingw@fedora SHOW_ENV=1 J=14
=== TEST SCRIPT END ===




The full log is available at
http://patchew.org/logs/20190114000326.29847-1-samuel.thiba...@ens-lyon.org/testing.docker-mingw@fedora/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [Qemu-devel] [PATCH] ftgmac100: implement the new MDIO interface on Aspeed SoC

2019-01-13 Thread Joel Stanley
On Fri, 11 Jan 2019 at 23:58, Cédric Le Goater  wrote:
>
> The PHY behind the MAC of an Aspeed SoC can be controlled using two
> different MDC/MDIO interfaces. The same registers PHYCR (MAC60) and
> PHYDATA (MAC64) are involved but they have a different layout.
>
> BIT31 of the Feature Register (MAC40) controls which MDC/MDIO
> interface is active.
>
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/net/ftgmac100.c | 80 +++---
>  1 file changed, 68 insertions(+), 12 deletions(-)

> @@ -269,9 +281,9 @@ static void phy_reset(FTGMAC100State *s)
>  s->phy_int = 0;
>  }
>
> -static uint32_t do_phy_read(FTGMAC100State *s, int reg)
> +static uint16_t do_phy_read(FTGMAC100State *s, uint8_t reg)
>  {
> -uint32_t val;
> +uint16_t val;

Unrelated?

> @@ -336,7 +348,7 @@ static uint32_t do_phy_read(FTGMAC100State *s, int reg)
> MII_BMCR_FD | MII_BMCR_CTST)
>  #define MII_ANAR_MASK 0x2d7f
>
> -static void do_phy_write(FTGMAC100State *s, int reg, uint32_t val)
> +static void do_phy_write(FTGMAC100State *s, uint8_t reg, uint16_t val)

Also unrelated?

> @@ -711,14 +771,11 @@ static void ftgmac100_write(void *opaque, hwaddr addr,
>  break;
>
>  case FTGMAC100_PHYCR:  /* PHY Device control */
> -reg = FTGMAC100_PHYCR_REG(value);
>  s->phycr = value;
> -if (value & FTGMAC100_PHYCR_MIIWR) {
> -do_phy_write(s, reg, s->phydata & 0x);
> -s->phycr &= ~FTGMAC100_PHYCR_MIIWR;
> +if (s->revr & FTGMAC100_REVR_NEW_MDIO_INTERFACE) {
> +do_phy_new_ctl(s);
>  } else {
> -s->phydata = do_phy_read(s, reg) << 16;
> -s->phycr &= ~FTGMAC100_PHYCR_MIIRD;
> +do_phy_ctl(s);

I assume the guest code programs the correct phy mode so this will
work fine. This change appears to keep the existing default of the old
mode.

Did you give this a go with both -kernel and a u-boot mtd image?

Looks good to me. If you feel like splitting out the unrelated changes
do that, but I'm not fussed either way.

Reviewed-by: Joel Stanley 

Cheers,

Joel



Re: [Qemu-devel] [PATCH v3 0/5] kvm "virtio pmem" device

2019-01-13 Thread Matthew Wilcox
On Mon, Jan 14, 2019 at 10:29:02AM +1100, Dave Chinner wrote:
> Until you have images (and hence host page cache) shared between
> multiple guests. People will want to do this, because it means they
> only need a single set of pages in host memory for executable
> binaries rather than a set of pages per guest. Then you have
> multiple guests being able to detect residency of the same set of
> pages. If the guests can then, in any way, control eviction of the
> pages from the host cache, then we have a guest-to-guest information
> leak channel.

I don't think we should ever be considering something that would allow a
guest to evict page's from the host's pagecache [1].  The guest should
be able to kick its own references to the host's pagecache out of its
own pagecache, but not be able to influence whether the host or another
guest has a read-only mapping cached.

[1] Unless the guest is allowed to modify the host's file; obviously
truncation, holepunching, etc are going to evict pages from the host's
page cache.



Re: [Qemu-devel] [PATCH 0/4] Add ignore-external migration capability

2019-01-13 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20190110120120.9943-1-yury-ko...@yandex-team.ru/



Hi,

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

=== TEST SCRIPT BEGIN ===
#!/bin/bash
time make docker-test-mingw@fedora SHOW_ENV=1 J=14
=== TEST SCRIPT END ===

  CC  aarch64-softmmu/balloon.o
  CC  x86_64-softmmu/hw/block/virtio-blk.o
/tmp/qemu-test/src/migration/ram.c: In function 'ram_load':
/tmp/qemu-test/src/migration/ram.c:4159:42: error: format '%lld' expects 
argument of type 'long long int', but argument 3 has type 'ram_addr_t {aka 
unsigned int}' [-Werror=format=]
 error_report("Mismatched RAM block offset %s "
  ^
In file included from 
/usr/i686-w64-mingw32/sys-root/mingw/include/inttypes.h:299:0,
---
  CC  aarch64-softmmu/hw/cpu/a15mpcore.o
  CC  aarch64-softmmu/hw/display/omap_dss.o
/tmp/qemu-test/src/migration/ram.c: In function 'ram_load':
/tmp/qemu-test/src/migration/ram.c:4159:42: error: format '%lld' expects 
argument of type 'long long int', but argument 3 has type 'ram_addr_t {aka 
unsigned int}' [-Werror=format=]
 error_report("Mismatched RAM block offset %s "
  ^
In file included from 
/usr/i686-w64-mingw32/sys-root/mingw/include/inttypes.h:299:0,


The full log is available at
http://patchew.org/logs/20190110120120.9943-1-yury-ko...@yandex-team.ru/testing.docker-mingw@fedora/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[Qemu-devel] [PULL 07/65] slirp: move internal function declarations

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Clarify that those functions are internal to slirp.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/libslirp.h | 3 ---
 slirp/slirp.h| 3 +++
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 3e88dbaa01..a4f390ee89 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -7,9 +7,6 @@ typedef struct Slirp Slirp;
 
 typedef void (*slirp_output)(void *opaque, const uint8_t *pkt, int pkt_len);
 
-int get_dns_addr(struct in_addr *pdns_addr);
-int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id);
-
 Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
   struct in_addr vnetmask, struct in_addr vhost,
   bool in6_enabled,
diff --git a/slirp/slirp.h b/slirp/slirp.h
index e3d65d68ec..de299aa36c 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -232,6 +232,9 @@ extern Slirp *slirp_instance;
 
 void if_start(Slirp *);
 
+int get_dns_addr(struct in_addr *pdns_addr);
+int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id);
+
 /* ncsi.c */
 void ncsi_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
 
-- 
2.20.1




[Qemu-devel] [PULL 11/65] slirp: remove dead declarations

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

An overdue cleanup. Remaining declarations could probably be moved in
other headers, such as slirp.h.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/main.h | 29 -
 1 file changed, 29 deletions(-)

diff --git a/slirp/main.h b/slirp/main.h
index 90053ce5ec..e04677944f 100644
--- a/slirp/main.h
+++ b/slirp/main.h
@@ -12,38 +12,9 @@
 #include 
 #endif
 
-#define TOWRITEMAX 512
-
-extern int slirp_socket;
-extern int slirp_socket_unit;
-extern int slirp_socket_port;
-extern uint32_t slirp_socket_addr;
-extern char *slirp_socket_passwd;
-extern int ctty_closed;
-
-/*
- * Get the difference in 2 times from updtim()
- * Allow for wraparound times, "just in case"
- * x is the greater of the 2 (current time) and y is
- * what it's being compared against.
- */
-#define TIME_DIFF(x,y) (x)-(y) < 0 ? ~0-(y)+(x) : (x)-(y)
-
-extern char *slirp_tty;
-extern char *exec_shell;
 extern u_int curtime;
 extern struct in_addr loopback_addr;
 extern unsigned long loopback_mask;
-extern char *username;
-extern char *socket_path;
-extern int towrite_max;
-extern int ppp_exit;
-extern int tcp_keepintvl;
-
-#define PROTO_SLIP 0x1
-#ifdef USE_PPP
-#define PROTO_PPP 0x2
-#endif
 
 int if_encap(Slirp *slirp, struct mbuf *ifm);
 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags);
-- 
2.20.1




[Qemu-devel] [PULLv2 00/65] slirp updates

2019-01-13 Thread Samuel Thibault
The following changes since commit 27df21ca3886fff4dd3d70e515517667963a52f1:

  Merge remote-tracking branch 'remotes/kraxel/tags/misc-20190111-pull-request' 
into staging (2019-01-11 16:45:59 +)

are available in the Git repository at:

  https://people.debian.org/~sthibault/qemu.git tags/samuel-thibault

for you to fetch changes up to 341cb5fd7a15ebdaa821ff068b517e120f22c412:

  slirp: check data length while emulating ident function (2019-01-14 00:44:29 
+0100)


slirp updates

Gerd Hoffmann (1):
  slirp: add tftp tracing

Marc-André Lureau (61):
  slirp: associate slirp_output callback with the Slirp context
  slirp: remove do_pty from fork_exec()
  slirp: replace ex_pty with ex_chardev
  slirp: use a dedicated field for chardev pointer
  slirp: remove unused EMU_RSH
  slirp: rename /extra/chardev
  slirp: move internal function declarations
  slirp: remove Monitor dependency, return a string for info
  slirp: fix slirp_add_exec() leaks
  slirp: replace the poor-man string split with g_strsplit()
  slirp: remove dead declarations
  slirp: move socket pair creation in helper function
  slirp: remove unused M_TRAILINGSPACE
  slirp: use a callback structure to interface with qemu
  slirp: remove PROBE_CONN dead-code
  slirp: remove FULL_BOLT
  slirp: remove the disabled readv()/writev() code path
  slirp: remove HAVE_SYS_SIGNAL_H
  slirp: remove unused HAVE_SYS_BITYPES_H
  slirp: remove NO_UNIX_SOCKETS
  slirp: remove unused HAVE_SYS_STROPTS_H
  slirp: remove unused HAVE_ARPA_INET_H
  slirp: remove unused HAVE_SYS_WAIT_H
  slirp: remove unused HAVE_SYS_SELECT_H
  slirp: remove HAVE_SYS_IOCTL_H
  slirp: remove HAVE_SYS_FILIO_H
  slirp: remove unused DECLARE_IOVEC
  slirp: remove unused HAVE_INET_ATON
  slirp: replace HOST_WORDS_BIGENDIAN with glib equivalent
  slirp: replace SIZEOF_CHAR_P with glib equivalent
  slirp: replace compile time DO_KEEPALIVE
  slirp: remove unused global slirp_instance
  slirp: replace error_report() with g_critical()
  slirp: improve a bit the debug macros
  slirp: add a callback to log guest errors
  slirp: remove #if notdef dead code
  slirp: remove unused sbflush()
  slirp: NULL is defined by stddef.h
  slirp: remove dead TCP_ACK_HACK code
  slirp: replace ARRAY_SIZE with G_N_ELEMENTS
  net: do not depend on slirp internals
  glib-compat: add g_spawn_async_with_fds() fallback
  slirp: simplify fork_exec()
  slirp: replace error_report() with g_critical()
  slirp: drop 

[Qemu-devel] [PULL 02/65] slirp: remove do_pty from fork_exec()

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

QEMU uses fork_exec() with do_pty values 0 or 3.
Let's clean up some unused code.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/misc.c | 55 ++--
 slirp/misc.h |  2 +-
 slirp/tcp_subr.c |  4 +---
 3 files changed, 18 insertions(+), 43 deletions(-)

diff --git a/slirp/misc.c b/slirp/misc.c
index 57bdd808e2..e69d5f42c3 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -63,7 +63,7 @@ int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec,
 #ifdef _WIN32
 
 int
-fork_exec(struct socket *so, const char *ex, int do_pty)
+fork_exec(struct socket *so, const char *ex)
 {
 /* not implemented */
 return 0;
@@ -77,13 +77,9 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
  * process, which connects to this socket, after which we
  * exec the wanted program.  If something (strange) happens,
  * the accept() call could block us forever.
- *
- * do_pty = 0   Fork/exec inetd style
- * do_pty = 1   Fork/exec using slirp.telnetd
- * do_ptr = 2   Fork/exec using pty
  */
 int
-fork_exec(struct socket *so, const char *ex, int do_pty)
+fork_exec(struct socket *so, const char *ex)
 {
 int s, cs;
 struct sockaddr_in addr, csaddr;
@@ -100,26 +96,20 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
DEBUG_CALL("fork_exec");
DEBUG_ARG("so = %p", so);
DEBUG_ARG("ex = %p", ex);
-   DEBUG_ARG("do_pty = %x", do_pty);
-
-   if (do_pty == 2) {
-return 0;
-   } else {
-   addr.sin_family = AF_INET;
-   addr.sin_port = 0;
-   addr.sin_addr.s_addr = INADDR_ANY;
 
-   if ((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
-   bind(s, (struct sockaddr *), addrlen) < 0 ||
-   listen(s, 1) < 0) {
-   error_report("Error: inet socket: %s", strerror(errno));
-   if (s >= 0) {
-   closesocket(s);
-   }
+addr.sin_family = AF_INET;
+addr.sin_port = 0;
+addr.sin_addr.s_addr = INADDR_ANY;
 
-   return 0;
-   }
-   }
+s = qemu_socket(AF_INET, SOCK_STREAM, 0);
+if (s < 0 || bind(s, (struct sockaddr *), addrlen) < 0 ||
+listen(s, 1) < 0) {
+error_report("Error: inet socket: %s", strerror(errno));
+if (s >= 0) {
+closesocket(s);
+}
+return 0;
+}
 
 if (getsockname(s, (struct sockaddr *), ) < 0) {
 closesocket(s);
@@ -166,13 +156,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
 
i = 0;
bptr = g_strdup(ex); /* No need to free() this */
-   if (do_pty == 1) {
-   /* Setup "slirp.telnetd -x" */
-   argv[i++] = "slirp.telnetd";
-   argv[i++] = "-x";
-   argv[i++] = bptr;
-   } else
-  do {
+do {
/* Change the string into argv[] */
curarg = bptr;
while (*bptr != ' ' && *bptr != (char)0)
@@ -180,7 +164,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
c = *bptr;
*bptr++ = (char)0;
argv[i++] = g_strdup(curarg);
-  } while (c);
+} while (c);
 
 argv[i] = NULL;
execvp(argv[0], (char **)argv);
@@ -206,13 +190,6 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
 opt = 1;
 qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, , 
sizeof(int));
qemu_set_nonblock(so->s);
-
-   /* Append the telnet options now */
-if (so->so_m != NULL && do_pty == 1)  {
-   sbappend(so, so->so_m);
-so->so_m = NULL;
-   }
-
return 1;
}
 }
diff --git a/slirp/misc.h b/slirp/misc.h
index 5211bbd30a..897650aea1 100644
--- a/slirp/misc.h
+++ b/slirp/misc.h
@@ -53,6 +53,6 @@ struct slirp_quehead {
 void slirp_insque(void *, void *);
 void slirp_remque(void *);
 int add_exec(struct ex_list **, int, char *, struct in_addr, int);
-int fork_exec(struct socket *so, const char *ex, int do_pty);
+int fork_exec(struct socket *so, const char *ex);
 
 #endif
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index fa61349cbb..0ccd8e1a96 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -951,7 +951,6 @@ int tcp_ctl(struct socket *so)
 Slirp *slirp = so->slirp;
 struct sbuf *sb = >so_snd;
 struct ex_list *ex_ptr;
-int do_pty;
 
 DEBUG_CALL("tcp_ctl");
 DEBUG_ARG("so = %p", so);
@@ -966,9 +965,8 @@ int tcp_ctl(struct socket *so)
 so->extra = (void *)ex_ptr->ex_exec;
 return 1;
 }
-  

[Qemu-devel] [PULL 05/65] slirp: remove unused EMU_RSH

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

EMU_RSH handling was dropped in commit
0d62c4cfe21752df4c1d6e2c2398f15d5eaa794a.

The assignment, and subsequent free() of ex_ptr->ex_exec to so->extra
looks unsafe (double free is likely to occur).

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/misc.h | 1 -
 slirp/slirp.c| 2 --
 slirp/socket.c   | 4 
 slirp/tcp_subr.c | 1 -
 4 files changed, 8 deletions(-)

diff --git a/slirp/misc.h b/slirp/misc.h
index 64ca88c3b7..94829722cd 100644
--- a/slirp/misc.h
+++ b/slirp/misc.h
@@ -26,7 +26,6 @@ struct ex_list {
 #define EMU_REALAUDIO 0x5
 #define EMU_RLOGIN 0x6
 #define EMU_IDENT 0x7
-#define EMU_RSH 0x8
 
 #define EMU_NOCONNECT 0x10 /* Don't connect */
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 0de46084c0..fac7849195 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -1499,8 +1499,6 @@ static int slirp_state_load(QEMUFile *f, void *opaque, 
int version_id)
 }
 if (!ex_ptr)
 return -EINVAL;
-
-so->extra = (void *)ex_ptr->ex_exec;
 }
 
 return vmstate_load_state(f, _slirp, slirp, version_id);
diff --git a/slirp/socket.c b/slirp/socket.c
index c01d8696af..041ec5061a 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -89,10 +89,6 @@ sofree(struct socket *so)
   soqfree(so, >if_fastq);
   soqfree(so, >if_batchq);
 
-  if (so->so_emu==EMU_RSH && so->extra) {
-   sofree(so->extra);
-   so->extra=NULL;
-  }
   if (so == slirp->tcp_last_so) {
   slirp->tcp_last_so = >tcb;
   } else if (so == slirp->udp_last_so) {
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index e7b2baa087..fd7521854e 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -541,7 +541,6 @@ static const struct tos_t tcptos[] = {
  {0, 23, IPTOS_LOWDELAY, 0},   /* telnet */
  {0, 80, IPTOS_THROUGHPUT, 0}, /* WWW */
  {0, 513, IPTOS_LOWDELAY, EMU_RLOGIN|EMU_NOCONNECT},   /* rlogin */
- {0, 514, IPTOS_LOWDELAY, EMU_RSH|EMU_NOCONNECT},  /* shell */
  {0, 544, IPTOS_LOWDELAY, EMU_KSH},/* kshell */
  {0, 543, IPTOS_LOWDELAY, 0},  /* klogin */
  {0, 6667, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC */
-- 
2.20.1




[Qemu-devel] [PULL 01/65] slirp: associate slirp_output callback with the Slirp context

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Let's make the slirp interface a bit more library-like.
Associate the slirp_output() with a Slirp context.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c  |  5 +++--
 slirp/libslirp.h |  9 +
 slirp/ncsi.c |  2 +-
 slirp/slirp.c| 11 +++
 slirp/slirp.h|  1 +
 5 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index 38ae65e4a9..dd06b0189e 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -99,7 +99,7 @@ static void slirp_smb_cleanup(SlirpState *s);
 static inline void slirp_smb_cleanup(SlirpState *s) { }
 #endif
 
-void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
+static void net_slirp_output(void *opaque, const uint8_t *pkt, int pkt_len)
 {
 SlirpState *s = opaque;
 
@@ -378,7 +378,8 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
   ipv6, ip6_prefix, vprefix6_len, ip6_host,
   vhostname, tftp_server_name,
   tftp_export, bootfile, dhcp,
-  dns, ip6_dns, dnssearch, vdomainname, s);
+  dns, ip6_dns, dnssearch, vdomainname,
+  net_slirp_output, s);
 QTAILQ_INSERT_TAIL(_stacks, s, entry);
 
 for (config = slirp_configs; config; config = config->next) {
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 42e42e9a2a..52dbb9feb5 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -5,6 +5,8 @@
 
 typedef struct Slirp Slirp;
 
+typedef void (*slirp_output)(void *opaque, const uint8_t *pkt, int pkt_len);
+
 int get_dns_addr(struct in_addr *pdns_addr);
 int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t *scope_id);
 
@@ -17,7 +19,9 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct 
in_addr vnetwork,
   const char *tftp_path, const char *bootfile,
   struct in_addr vdhcp_start, struct in_addr vnameserver,
   struct in6_addr vnameserver6, const char **vdnssearch,
-  const char *vdomainname, void *opaque);
+  const char *vdomainname,
+  slirp_output output,
+  void *opaque);
 void slirp_cleanup(Slirp *slirp);
 
 void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout);
@@ -26,9 +30,6 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error);
 
 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
 
-/* you must provide the following functions: */
-void slirp_output(void *opaque, const uint8_t *pkt, int pkt_len);
-
 int slirp_add_hostfwd(Slirp *slirp, int is_udp,
   struct in_addr host_addr, int host_port,
   struct in_addr guest_addr, int guest_port);
diff --git a/slirp/ncsi.c b/slirp/ncsi.c
index 7116034afc..d7701f7785 100644
--- a/slirp/ncsi.c
+++ b/slirp/ncsi.c
@@ -163,5 +163,5 @@ void ncsi_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len)
 *pchecksum = htonl(checksum);
 ncsi_rsp_len += 4;
 
-slirp_output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
+slirp->output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
 }
diff --git a/slirp/slirp.c b/slirp/slirp.c
index ab2fc4eb8b..4d4c2c13b5 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -287,12 +287,15 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct 
in_addr vnetwork,
   const char *tftp_path, const char *bootfile,
   struct in_addr vdhcp_start, struct in_addr vnameserver,
   struct in6_addr vnameserver6, const char **vdnssearch,
-  const char *vdomainname, void *opaque)
+  const char *vdomainname,
+  slirp_output output,
+  void *opaque)
 {
 Slirp *slirp = g_malloc0(sizeof(Slirp));
 
 slirp_init_once();
 
+slirp->output = output;
 slirp->grand = g_rand_new();
 slirp->restricted = restricted;
 
@@ -832,7 +835,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len)
 rah->ar_sip = ah->ar_tip;
 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
 rah->ar_tip = ah->ar_sip;
-slirp_output(slirp->opaque, arp_reply, sizeof(arp_reply));
+slirp->output(slirp->opaque, arp_reply, sizeof(arp_reply));
 }
 break;
 case ARPOP_REPLY:
@@ -932,7 +935,7 @@ static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct 
ethhdr *eh,
 /* 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));
+slirp->output(slirp->opaque, arp_req, sizeof(arp_req));
 ifm->resolution_requested = true;
 
 /* Expire request and drop outgoing packet after 1 second */
@@ -1018,7 +1021,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
 eh->h_dest[0], eh->h_dest[1], 

[Qemu-devel] [PULL 14/65] slirp: remove unused M_TRAILINGSPACE

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/mbuf.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/slirp/mbuf.h b/slirp/mbuf.h
index bfdf8c4577..cbf17e136b 100644
--- a/slirp/mbuf.h
+++ b/slirp/mbuf.h
@@ -72,7 +72,6 @@
  * How much free room there is
  */
 #define M_FREEROOM(m) (M_ROOM(m) - (m)->m_len)
-#define M_TRAILINGSPACE M_FREEROOM
 
 struct mbuf {
/* XXX should union some of these! */
-- 
2.20.1




[Qemu-devel] [PULL 12/65] slirp: add tftp tracing

2019-01-13 Thread Samuel Thibault
From: Gerd Hoffmann 

Useful when debugging pxeboot, to see what the guest tries to do.

Signed-off-by: Gerd Hoffmann 
Reviewed-by: Liam Merwick 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Samuel Thibault 
---
 Makefile.objs  | 1 +
 slirp/tftp.c   | 3 +++
 slirp/trace-events | 5 +
 3 files changed, 9 insertions(+)
 create mode 100644 slirp/trace-events

diff --git a/Makefile.objs b/Makefile.objs
index 456115992a..2121120492 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -193,6 +193,7 @@ trace-events-subdirs += net
 trace-events-subdirs += qapi
 trace-events-subdirs += qom
 trace-events-subdirs += scsi
+trace-events-subdirs += slirp
 trace-events-subdirs += target/arm
 trace-events-subdirs += target/i386
 trace-events-subdirs += target/mips
diff --git a/slirp/tftp.c b/slirp/tftp.c
index a9bc4bb1b6..735b57aa55 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -26,6 +26,7 @@
 #include "slirp.h"
 #include "qemu-common.h"
 #include "qemu/cutils.h"
+#include "trace.h"
 
 static inline int tftp_session_in_use(struct tftp_session *spt)
 {
@@ -204,6 +205,7 @@ static void tftp_send_error(struct tftp_session *spt,
   struct mbuf *m;
   struct tftp_t *tp;
 
+  trace_slirp_tftp_error(msg);
   m = m_get(spt->slirp);
 
   if (!m) {
@@ -323,6 +325,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct 
sockaddr_storage *srcsas,
   break;
 }
   }
+  trace_slirp_tftp_rrq(req_fname);
 
   /* check mode */
   if ((pktlen - k) < 6) {
diff --git a/slirp/trace-events b/slirp/trace-events
new file mode 100644
index 00..ff8f656e8c
--- /dev/null
+++ b/slirp/trace-events
@@ -0,0 +1,5 @@
+# See docs/devel/tracing.txt for syntax documentation.
+
+# slirp/tftp.c
+slirp_tftp_rrq(const char *file) "file: %s"
+slirp_tftp_error(const char *file) "msg: %s"
-- 
2.20.1




[Qemu-devel] [PULL 10/65] slirp: replace the poor-man string split with g_strsplit()

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Use the glib function for the work, fix a potential crash on >256 words.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/misc.c | 21 +++--
 1 file changed, 3 insertions(+), 18 deletions(-)

diff --git a/slirp/misc.c b/slirp/misc.c
index ce323ef92e..4840187750 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -88,11 +88,8 @@ fork_exec(struct socket *so, const char *ex)
socklen_t addrlen = sizeof(addr);
 socklen_t csaddrlen = sizeof(csaddr);
int opt;
-   const char *argv[256];
-   /* don't want to clobber the original */
-   char *bptr;
-   const char *curarg;
-   int c, i, ret;
+   char **argv;
+   int ret;
pid_t pid;
 
DEBUG_CALL("fork_exec");
@@ -156,19 +153,7 @@ fork_exec(struct socket *so, const char *ex)
for (s = getdtablesize() - 1; s >= 3; s--)
   close(s);
 
-   i = 0;
-   bptr = g_strdup(ex); /* No need to free() this */
-do {
-   /* Change the string into argv[] */
-   curarg = bptr;
-   while (*bptr != ' ' && *bptr != (char)0)
-  bptr++;
-   c = *bptr;
-   *bptr++ = (char)0;
-   argv[i++] = g_strdup(curarg);
-} while (c);
-
-argv[i] = NULL;
+argv = g_strsplit(ex, " ", -1);
execvp(argv[0], (char **)argv);
 
/* Ooops, failed, let's tell the user why */
-- 
2.20.1




[Qemu-devel] [PULL 21/65] slirp: remove NO_UNIX_SOCKETS

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.h| 3 ---
 slirp/slirp_config.h | 6 --
 2 files changed, 9 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 57955a8965..fba77d0c3d 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -28,9 +28,6 @@ typedef char *caddr_t;
 #include 
 #endif
 
-#ifndef NO_UNIX_SOCKETS
-#include 
-#endif
 #ifndef _WIN32
 #include 
 #endif
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index a205dc8c28..4417b05d1c 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -58,9 +58,3 @@
 #ifndef _WIN32
 #define HAVE_INET_ATON
 #endif
-
-/* Define if you DON'T have unix-domain sockets */
-#undef NO_UNIX_SOCKETS
-#ifdef _WIN32
-#define NO_UNIX_SOCKETS
-#endif
-- 
2.20.1




[Qemu-devel] [PULL 15/65] slirp: use a callback structure to interface with qemu

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

This will bring slirp a bit forward to the state of an independent
project.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c  |  6 +-
 slirp/libslirp.h | 13 +++--
 slirp/ncsi.c |  2 +-
 slirp/slirp.c| 10 +-
 slirp/slirp.h|  2 +-
 5 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index b7319ca6b2..031c324f02 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -140,6 +140,10 @@ static NetClientInfo net_slirp_info = {
 .cleanup = net_slirp_cleanup,
 };
 
+static const SlirpCb slirp_cb = {
+.output = net_slirp_output,
+};
+
 static int net_slirp_init(NetClientState *peer, const char *model,
   const char *name, int restricted,
   bool ipv4, const char *vnetwork, const char *vhost,
@@ -379,7 +383,7 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
   vhostname, tftp_server_name,
   tftp_export, bootfile, dhcp,
   dns, ip6_dns, dnssearch, vdomainname,
-  net_slirp_output, s);
+  _cb, s);
 QTAILQ_INSERT_TAIL(_stacks, s, entry);
 
 for (config = slirp_configs; config; config = config->next) {
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 04b6db9f49..a5d1b27b5e 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -5,7 +5,16 @@
 
 typedef struct Slirp Slirp;
 
-typedef void (*slirp_output)(void *opaque, const uint8_t *pkt, int pkt_len);
+/*
+ * Callbacks from slirp
+ *
+ * The opaque parameter comes from the opaque parameter given to slirp_init().
+ */
+typedef struct SlirpCb {
+/* Send an ethernet frame to the guest network.  */
+void (*output)(void *opaque, const uint8_t *pkt, int pkt_len);
+} SlirpCb;
+
 
 Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
   struct in_addr vnetmask, struct in_addr vhost,
@@ -17,7 +26,7 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct 
in_addr vnetwork,
   struct in_addr vdhcp_start, struct in_addr vnameserver,
   struct in6_addr vnameserver6, const char **vdnssearch,
   const char *vdomainname,
-  slirp_output output,
+  const SlirpCb *callbacks,
   void *opaque);
 void slirp_cleanup(Slirp *slirp);
 
diff --git a/slirp/ncsi.c b/slirp/ncsi.c
index d7701f7785..10decfb5ef 100644
--- a/slirp/ncsi.c
+++ b/slirp/ncsi.c
@@ -163,5 +163,5 @@ void ncsi_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len)
 *pchecksum = htonl(checksum);
 ncsi_rsp_len += 4;
 
-slirp->output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
+slirp->cb->output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
 }
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 1627436e7d..bab49e83e3 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -288,14 +288,14 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct 
in_addr vnetwork,
   struct in_addr vdhcp_start, struct in_addr vnameserver,
   struct in6_addr vnameserver6, const char **vdnssearch,
   const char *vdomainname,
-  slirp_output output,
+  const SlirpCb *callbacks,
   void *opaque)
 {
 Slirp *slirp = g_malloc0(sizeof(Slirp));
 
 slirp_init_once();
 
-slirp->output = output;
+slirp->cb = callbacks;
 slirp->grand = g_rand_new();
 slirp->restricted = restricted;
 
@@ -843,7 +843,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len)
 rah->ar_sip = ah->ar_tip;
 memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN);
 rah->ar_tip = ah->ar_sip;
-slirp->output(slirp->opaque, arp_reply, sizeof(arp_reply));
+slirp->cb->output(slirp->opaque, arp_reply, sizeof(arp_reply));
 }
 break;
 case ARPOP_REPLY:
@@ -943,7 +943,7 @@ static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct 
ethhdr *eh,
 /* 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));
+slirp->cb->output(slirp->opaque, arp_req, sizeof(arp_req));
 ifm->resolution_requested = true;
 
 /* Expire request and drop outgoing packet after 1 second */
@@ -1029,7 +1029,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
 eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
 eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]));
 memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len);
-slirp->output(slirp->opaque, buf, ifm->m_len + ETH_HLEN);
+slirp->cb->output(slirp->opaque, buf, ifm->m_len + ETH_HLEN);
 return 1;
 }
 
diff --git a/slirp/slirp.h 

[Qemu-devel] [PULL 13/65] slirp: move socket pair creation in helper function

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Originally, the patch was fixing a bunch of issues, but Peter beat me
to it with earlier commit "slirp: fork_exec(): create and connect
child socket before fork()".

Factor out socket pair creation, to simplify the fork_exec() code.
Use the name socketpair_with_oob() since the code is actually similar
to what socketpair() would do, except that it uses TCP sockets, for
SLIRP to be able to call send with MSG_OOB (since SO_OOBINLINE is set,
this could probably be faked instead on regular unix sockets though).

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/misc.c | 142 +--
 1 file changed, 71 insertions(+), 71 deletions(-)

diff --git a/slirp/misc.c b/slirp/misc.c
index 4840187750..7362e14339 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -73,85 +73,92 @@ fork_exec(struct socket *so, const char *ex)
 
 #else
 
-/*
- * XXX This is ugly
- * We create and bind a socket, then fork off to another
- * process, which connects to this socket, after which we
- * exec the wanted program.  If something (strange) happens,
- * the accept() call could block us forever.
- */
+static int
+slirp_socketpair_with_oob(int sv[2])
+{
+struct sockaddr_in addr = {
+.sin_family = AF_INET,
+.sin_port = 0,
+.sin_addr.s_addr = INADDR_ANY,
+};
+socklen_t addrlen = sizeof(addr);
+int ret, s;
+
+sv[1] = -1;
+s = qemu_socket(AF_INET, SOCK_STREAM, 0);
+if (s < 0 || bind(s, (struct sockaddr *), addrlen) < 0 ||
+listen(s, 1) < 0 ||
+getsockname(s, (struct sockaddr *), ) < 0) {
+goto err;
+}
+
+sv[1] = qemu_socket(AF_INET, SOCK_STREAM, 0);
+if (sv[1] < 0) {
+goto err;
+}
+/*
+ * This connect won't block because we've already listen()ed on
+ * the server end (even though we won't accept() the connection
+ * until later on).
+ */
+do {
+ret = connect(sv[1], (struct sockaddr *), addrlen);
+} while (ret < 0 && errno == EINTR);
+if (ret < 0) {
+goto err;
+}
+
+do {
+sv[0] = accept(s, (struct sockaddr *), );
+} while (sv[0] < 0 && errno == EINTR);
+if (sv[0] < 0) {
+goto err;
+}
+
+closesocket(s);
+return 0;
+
+err:
+error_report("Error: slirp_socketpair(): %s", strerror(errno));
+if (s >= 0) {
+closesocket(s);
+}
+if (sv[1] >= 0) {
+closesocket(sv[1]);
+}
+return -1;
+}
+
 int
 fork_exec(struct socket *so, const char *ex)
 {
-int s, cs;
-struct sockaddr_in addr, csaddr;
-   socklen_t addrlen = sizeof(addr);
-socklen_t csaddrlen = sizeof(csaddr);
-   int opt;
char **argv;
-   int ret;
+   int opt, c, sp[2];
pid_t pid;
 
DEBUG_CALL("fork_exec");
DEBUG_ARG("so = %p", so);
DEBUG_ARG("ex = %p", ex);
 
-addr.sin_family = AF_INET;
-addr.sin_port = 0;
-addr.sin_addr.s_addr = INADDR_ANY;
-
-s = qemu_socket(AF_INET, SOCK_STREAM, 0);
-if (s < 0 || bind(s, (struct sockaddr *), addrlen) < 0 ||
-listen(s, 1) < 0) {
-error_report("Error: inet socket: %s", strerror(errno));
-if (s >= 0) {
-closesocket(s);
-}
+if (slirp_socketpair_with_oob(sp) < 0) {
 return 0;
 }
 
-if (getsockname(s, (struct sockaddr *), ) < 0) {
-closesocket(s);
-return 0;
-}
-cs = qemu_socket(AF_INET, SOCK_STREAM, 0);
-if (cs < 0) {
-closesocket(s);
-return 0;
-}
-csaddr.sin_addr = loopback_addr;
-/*
- * This connect won't block because we've already listen()ed on
- * the server end (even though we won't accept() the connection
- * until later on).
- */
-do {
-ret = connect(cs, (struct sockaddr *), csaddrlen);
-} while (ret < 0 && errno == EINTR);
-if (ret < 0) {
-closesocket(s);
-closesocket(cs);
-return 0;
-}
-
pid = fork();
switch(pid) {
 case -1:
error_report("Error: fork failed: %s", strerror(errno));
-closesocket(cs);
-   close(s);
+   closesocket(sp[0]);
+   closesocket(sp[1]);
return 0;
 
 case 0:
-setsid();
-
-   /* Set the DISPLAY */
-close(s);
-dup2(cs, 0);
-dup2(cs, 1);
-dup2(cs, 2);
-   for (s = getdtablesize() - 1; s >= 3; s--)
-  close(s);
+   setsid();
+   dup2(sp[1], 0);
+   dup2(sp[1], 1);
+   dup2(sp[1], 2);
+   for (c = getdtablesize() - 1; c >= 3; c--)
+  close(c);
 
 argv = g_strsplit(ex, " ", -1);
execvp(argv[0], (char **)argv);
@@ 

[Qemu-devel] [PULL 27/65] slirp: remove HAVE_SYS_FILIO_H

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.h| 2 +-
 slirp/slirp_config.h | 6 --
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 226bced429..4a046e 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -36,7 +36,7 @@ typedef char *caddr_t;
 # include 
 #endif
 
-#ifdef HAVE_SYS_FILIO_H
+#ifdef __APPLE__
 # include 
 #endif
 
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index 0e78e92d94..f1ee927c15 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -11,12 +11,6 @@
  * You shouldn't need to touch any of these
  */
 
-/* Define if you have sys/filio.h */
-#undef HAVE_SYS_FILIO_H
-#ifdef __APPLE__
-#define HAVE_SYS_FILIO_H
-#endif
-
 /* Define if the machine is big endian */
 //#undef HOST_WORDS_BIGENDIAN
 
-- 
2.20.1




[Qemu-devel] [PULL 22/65] slirp: remove unused HAVE_SYS_STROPTS_H

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.h| 5 -
 slirp/slirp_config.h | 3 ---
 2 files changed, 8 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index fba77d0c3d..400f585cec 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -54,11 +54,6 @@ typedef char *caddr_t;
 #define remque slirp_remque
 #define quehead slirp_quehead
 
-#ifdef HAVE_SYS_STROPTS_H
-#include 
-#endif
-
-
 #include "debug.h"
 
 #include "qemu/queue.h"
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index 4417b05d1c..47811e36dc 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -47,9 +47,6 @@
 #define HAVE_ARPA_INET_H
 #endif
 
-/* Define if you have sys/stropts.h */
-#undef HAVE_SYS_STROPTS_H
-
 /* Define to sizeof(char *) */
 #define SIZEOF_CHAR_P (HOST_LONG_BITS / 8)
 
-- 
2.20.1




[Qemu-devel] [PULL 31/65] slirp: replace SIZEOF_CHAR_P with glib equivalent

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Samuel Thibault 
---
 slirp/ip.h   | 2 +-
 slirp/slirp_config.h | 3 ---
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/slirp/ip.h b/slirp/ip.h
index 83fc9cdfbf..243b6c8b24 100644
--- a/slirp/ip.h
+++ b/slirp/ip.h
@@ -177,7 +177,7 @@ struct  ip_timestamp {
 
 #defineIP_MSS  576 /* default maximum segment size 
*/
 
-#if SIZEOF_CHAR_P == 4
+#if GLIB_SIZEOF_VOID_P == 4
 struct mbuf_ptr {
struct mbuf *mptr;
uint32_t dummy;
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index b2def6d20c..7147e0de04 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -10,6 +10,3 @@
  * Autoconf defined configuration options
  * You shouldn't need to touch any of these
  */
-
-/* Define to sizeof(char *) */
-#define SIZEOF_CHAR_P (HOST_LONG_BITS / 8)
-- 
2.20.1




[Qemu-devel] [PULL 30/65] slirp: replace HOST_WORDS_BIGENDIAN with glib equivalent

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

One more step towards making the project independent from QEMU.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/ip.h   | 8 +---
 slirp/ip6.h  | 3 ++-
 slirp/ip6_icmp.h | 6 +++---
 slirp/slirp_config.h | 3 ---
 slirp/tcp.h  | 4 +++-
 5 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/slirp/ip.h b/slirp/ip.h
index 59cf4aa918..83fc9cdfbf 100644
--- a/slirp/ip.h
+++ b/slirp/ip.h
@@ -33,7 +33,9 @@
 #ifndef IP_H
 #define IP_H
 
-#ifdef HOST_WORDS_BIGENDIAN
+#include 
+
+#if G_BYTE_ORDER == G_BIG_ENDIAN
 # undef NTOHL
 # undef NTOHS
 # undef HTONL
@@ -69,7 +71,7 @@ typedef uint32_t n_long; /* long as received 
from the net */
  * Structure of an internet header, naked of options.
  */
 struct ip {
-#ifdef HOST_WORDS_BIGENDIAN
+#if G_BYTE_ORDER == G_BIG_ENDIAN
uint8_t ip_v:4, /* version */
ip_hl:4;/* header length */
 #else
@@ -135,7 +137,7 @@ struct  ip_timestamp {
uint8_t ipt_code;   /* IPOPT_TS */
uint8_t ipt_len;/* size of structure (variable) */
uint8_t ipt_ptr;/* index of current entry */
-#ifdef HOST_WORDS_BIGENDIAN
+#if G_BYTE_ORDER == G_BIG_ENDIAN
uint8_t ipt_oflw:4, /* overflow counter */
ipt_flg:4;  /* flags, see below */
 #else
diff --git a/slirp/ip6.h b/slirp/ip6.h
index b1bea43b3c..14e9c78735 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -6,6 +6,7 @@
 #ifndef SLIRP_IP6_H
 #define SLIRP_IP6_H
 
+#include 
 #include "net/eth.h"
 
 #define ALLNODES_MULTICAST  { .s6_addr = \
@@ -113,7 +114,7 @@ static inline void in6_compute_ethaddr(struct in6_addr ip,
  * Structure of an internet header, naked of options.
  */
 struct ip6 {
-#ifdef HOST_WORDS_BIGENDIAN
+#if G_BYTE_ORDER == G_BIG_ENDIAN
 uint32_t
 ip_v:4, /* version */
 ip_tc_hi:4, /* traffic class */
diff --git a/slirp/ip6_icmp.h b/slirp/ip6_icmp.h
index b3378b17b5..32b0914055 100644
--- a/slirp/ip6_icmp.h
+++ b/slirp/ip6_icmp.h
@@ -34,7 +34,7 @@ struct ndp_rs { /* Router Solicitation Message */
 
 struct ndp_ra { /* Router Advertisement Message */
 uint8_t chl;/* Cur Hop Limit */
-#ifdef HOST_WORDS_BIGENDIAN
+#if G_BYTE_ORDER == G_BIG_ENDIAN
 uint8_t
 M:1,
 O:1,
@@ -56,7 +56,7 @@ struct ndp_ns { /* Neighbor Solicitation Message */
 } QEMU_PACKED;
 
 struct ndp_na { /* Neighbor Advertisement Message */
-#ifdef HOST_WORDS_BIGENDIAN
+#if G_BYTE_ORDER == G_BIG_ENDIAN
 uint32_t
 R:1,/* Router Flag */
 S:1,/* Solicited Flag */
@@ -125,7 +125,7 @@ struct ndpopt {
 #define ndpopt_linklayer ndpopt_body.linklayer_addr
 struct prefixinfo { /* Prefix Information */
 uint8_t prefix_length;
-#ifdef HOST_WORDS_BIGENDIAN
+#if G_BYTE_ORDER == G_BIG_ENDIAN
 uint8_t L:1, A:1, reserved1:6;
 #else
 uint8_t reserved1:6, A:1, L:1;
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index 5126711849..b2def6d20c 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -11,8 +11,5 @@
  * You shouldn't need to touch any of these
  */
 
-/* Define if the machine is big endian */
-//#undef HOST_WORDS_BIGENDIAN
-
 /* Define to sizeof(char *) */
 #define SIZEOF_CHAR_P (HOST_LONG_BITS / 8)
diff --git a/slirp/tcp.h b/slirp/tcp.h
index 174d3d960c..47aaea6c5b 100644
--- a/slirp/tcp.h
+++ b/slirp/tcp.h
@@ -33,6 +33,8 @@
 #ifndef TCP_H
 #define TCP_H
 
+#include 
+
 typedefuint32_t tcp_seq;
 
 #define  PR_SLOWHZ   2   /* 2 slow timeouts per second 
(approx) */
@@ -51,7 +53,7 @@ struct tcphdr {
uint16_t th_dport;  /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
-#ifdef HOST_WORDS_BIGENDIAN
+#if G_BYTE_ORDER == G_BIG_ENDIAN
uint8_t th_off:4,   /* data offset */
th_x2:4;/* (unused) */
 #else
-- 
2.20.1




[Qemu-devel] [PULL 45/65] slirp: replace error_report() with g_critical()

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Reduce dependency on QEMU. QEMU could use a custom log handler if it
wants to redirect/filter it.

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

diff --git a/slirp/misc.c b/slirp/misc.c
index 753b3da25b..b141446319 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -162,7 +162,7 @@ fork_exec(struct socket *so, const char *ex)
 g_strfreev(argv);
 
 if (err) {
-error_report("%s", err->message);
+g_critical("fork_exec: %s", err->message);
 g_error_free(err);
 closesocket(sp[0]);
 closesocket(sp[1]);
-- 
2.20.1




[Qemu-devel] [PULL 16/65] slirp: remove PROBE_CONN dead-code

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Nobody cares for over 14y. Somebody can revert or rewrite if
interested by that.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.c| 41 -
 slirp/slirp_config.h |  4 
 2 files changed, 45 deletions(-)

diff --git a/slirp/slirp.c b/slirp/slirp.c
index bab49e83e3..76e94eb1cd 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -699,47 +699,6 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
 }
 }
 }
-
-/*
- * Probe a still-connecting, non-blocking socket
- * to check if it's still alive
- */
-#ifdef PROBE_CONN
-if (so->so_state & SS_ISFCONNECTING) {
-ret = qemu_recv(so->s, , 0, 0);
-
-if (ret < 0) {
-/* XXX */
-if (errno == EAGAIN || errno == EWOULDBLOCK ||
-errno == EINPROGRESS || errno == ENOTCONN) {
-continue; /* Still connecting, continue */
-}
-
-/* else failed */
-so->so_state &= SS_PERSISTENT_MASK;
-so->so_state |= SS_NOFDREF;
-
-/* tcp_input will take care of it */
-} else {
-ret = send(so->s, , 0, 0);
-if (ret < 0) {
-/* XXX */
-if (errno == EAGAIN || errno == EWOULDBLOCK ||
-errno == EINPROGRESS || errno == ENOTCONN) {
-continue;
-}
-/* else failed */
-so->so_state &= SS_PERSISTENT_MASK;
-so->so_state |= SS_NOFDREF;
-} else {
-so->so_state &= ~SS_ISFCONNECTING;
-}
-
-}
-tcp_input((struct mbuf *)NULL, sizeof(struct ip), so,
-  so->so_ffamily);
-} /* SS_ISFCONNECTING */
-#endif
 }
 
 /*
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index c59f655207..721667e3ef 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -2,10 +2,6 @@
  * User definable configuration options
  */
 
-/* Define if you want the connection to be probed */
-/* XXX Not working yet, so ignore this for now */
-#undef PROBE_CONN
-
 /* Define to 1 if you want KEEPALIVE timers */
 #define DO_KEEPALIVE 0
 
-- 
2.20.1




[Qemu-devel] [PULL 25/65] slirp: remove unused HAVE_SYS_SELECT_H

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/main.h | 4 
 slirp/slirp.h| 4 
 slirp/slirp_config.h | 6 --
 3 files changed, 14 deletions(-)

diff --git a/slirp/main.h b/slirp/main.h
index e04677944f..4bc05fb904 100644
--- a/slirp/main.h
+++ b/slirp/main.h
@@ -8,10 +8,6 @@
 #ifndef SLIRP_MAIN_H
 #define SLIRP_MAIN_H
 
-#ifdef HAVE_SYS_SELECT_H
-#include 
-#endif
-
 extern u_int curtime;
 extern struct in_addr loopback_addr;
 extern unsigned long loopback_mask;
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 1f47848271..7606de962f 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -36,10 +36,6 @@ typedef char *caddr_t;
 # include 
 #endif
 
-#ifdef HAVE_SYS_SELECT_H
-# include 
-#endif
-
 #ifdef HAVE_SYS_FILIO_H
 # include 
 #endif
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index 9becb98e11..68e75f3873 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -32,12 +32,6 @@
 #define DECLARE_IOVEC
 #endif
 
-/* Define if you have sys/select.h */
-#undef HAVE_SYS_SELECT_H
-#ifndef _WIN32
-#define HAVE_SYS_SELECT_H
-#endif
-
 /* Define to sizeof(char *) */
 #define SIZEOF_CHAR_P (HOST_LONG_BITS / 8)
 
-- 
2.20.1




[Qemu-devel] [PULL 42/65] net: do not depend on slirp internals

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Only slirp/libslirp.h should be included.

Instead of using some slirp declarations and utility functions directly,
let's copy them in net/util.h.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Samuel Thibault 
---
 net/colo-compare.c| 11 +
 net/colo.c|  1 +
 net/colo.h|  7 +++---
 net/filter-rewriter.c |  9 +++
 net/slirp.c   |  2 +-
 net/util.h| 55 +++
 stubs/slirp.c |  2 +-
 7 files changed, 72 insertions(+), 15 deletions(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index 9156ab3349..3e515f3023 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -30,6 +30,7 @@
 #include "net/colo-compare.h"
 #include "migration/colo.h"
 #include "migration/migration.h"
+#include "util.h"
 
 #define TYPE_COLO_COMPARE "colo-compare"
 #define COLO_COMPARE(obj) \
@@ -129,19 +130,19 @@ static int compare_chr_send(CompareState *s,
 
 static gint seq_sorter(Packet *a, Packet *b, gpointer data)
 {
-struct tcphdr *atcp, *btcp;
+struct tcp_hdr *atcp, *btcp;
 
-atcp = (struct tcphdr *)(a->transport_header);
-btcp = (struct tcphdr *)(b->transport_header);
+atcp = (struct tcp_hdr *)(a->transport_header);
+btcp = (struct tcp_hdr *)(b->transport_header);
 return ntohl(atcp->th_seq) - ntohl(btcp->th_seq);
 }
 
 static void fill_pkt_tcp_info(void *data, uint32_t *max_ack)
 {
 Packet *pkt = data;
-struct tcphdr *tcphd;
+struct tcp_hdr *tcphd;
 
-tcphd = (struct tcphdr *)pkt->transport_header;
+tcphd = (struct tcp_hdr *)pkt->transport_header;
 
 pkt->tcp_seq = ntohl(tcphd->th_seq);
 pkt->tcp_ack = ntohl(tcphd->th_ack);
diff --git a/net/colo.c b/net/colo.c
index 49176bf07b..8196b35837 100644
--- a/net/colo.c
+++ b/net/colo.c
@@ -15,6 +15,7 @@
 #include "qemu/osdep.h"
 #include "trace.h"
 #include "colo.h"
+#include "util.h"
 
 uint32_t connection_key_hash(const void *opaque)
 {
diff --git a/net/colo.h b/net/colo.h
index 11c5226488..b21c6830b5 100644
--- a/net/colo.h
+++ b/net/colo.h
@@ -15,10 +15,9 @@
 #ifndef QEMU_COLO_PROXY_H
 #define QEMU_COLO_PROXY_H
 
-#include "slirp/slirp.h"
 #include "qemu/jhash.h"
 #include "qemu/timer.h"
-#include "slirp/tcp.h"
+#include "net/eth.h"
 
 #define HASHTABLE_MAX_SIZE 16384
 
@@ -81,10 +80,10 @@ typedef struct Connection {
 /* the maximum of acknowledgement number in secondary_list queue */
 uint32_t sack;
 /* offset = secondary_seq - primary_seq */
-tcp_seq  offset;
+uint32_t  offset;
 
 int tcp_state; /* TCP FSM state */
-tcp_seq fin_ack_seq; /* the seq of 'fin=1,ack=1' */
+uint32_t fin_ack_seq; /* the seq of 'fin=1,ack=1' */
 } Connection;
 
 uint32_t connection_key_hash(const void *opaque);
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
index 2e26839bc2..b464abe5e8 100644
--- a/net/filter-rewriter.c
+++ b/net/filter-rewriter.c
@@ -22,6 +22,7 @@
 #include "net/checksum.h"
 #include "net/colo.h"
 #include "migration/colo.h"
+#include "util.h"
 
 #define FILTER_COLO_REWRITER(obj) \
 OBJECT_CHECK(RewriterState, (obj), TYPE_FILTER_REWRITER)
@@ -73,9 +74,9 @@ static int handle_primary_tcp_pkt(RewriterState *rf,
   Connection *conn,
   Packet *pkt, ConnectionKey *key)
 {
-struct tcphdr *tcp_pkt;
+struct tcp_hdr *tcp_pkt;
 
-tcp_pkt = (struct tcphdr *)pkt->transport_header;
+tcp_pkt = (struct tcp_hdr *)pkt->transport_header;
 if (trace_event_get_state_backends(TRACE_COLO_FILTER_REWRITER_DEBUG)) {
 trace_colo_filter_rewriter_pkt_info(__func__,
 inet_ntoa(pkt->ip->ip_src), inet_ntoa(pkt->ip->ip_dst),
@@ -176,9 +177,9 @@ static int handle_secondary_tcp_pkt(RewriterState *rf,
 Connection *conn,
 Packet *pkt, ConnectionKey *key)
 {
-struct tcphdr *tcp_pkt;
+struct tcp_hdr *tcp_pkt;
 
-tcp_pkt = (struct tcphdr *)pkt->transport_header;
+tcp_pkt = (struct tcp_hdr *)pkt->transport_header;
 
 if (trace_event_get_state_backends(TRACE_COLO_FILTER_REWRITER_DEBUG)) {
 trace_colo_filter_rewriter_pkt_info(__func__,
diff --git a/net/slirp.c b/net/slirp.c
index ea8b04e007..b1c98b9470 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -38,12 +38,12 @@
 #include "qemu/error-report.h"
 #include "qemu/sockets.h"
 #include "slirp/libslirp.h"
-#include "slirp/ip6.h"
 #include "chardev/char-fe.h"
 #include "sysemu/sysemu.h"
 #include "qemu/cutils.h"
 #include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
+#include "util.h"
 
 static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
 {
diff --git a/net/util.h b/net/util.h
index 60b73d372d..358185fd50 100644
--- a/net/util.h
+++ b/net/util.h
@@ -26,6 +26,61 @@
 #define QEMU_NET_UTIL_H
 
 
+/*
+ * Structure of an internet header, naked of 

[Qemu-devel] [PULL 39/65] slirp: NULL is defined by stddef.h

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.h | 4 
 1 file changed, 4 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index d1b6bcefbb..fdf397256b 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -199,10 +199,6 @@ struct Slirp {
 void *opaque;
 };
 
-#ifndef NULL
-#define NULL (void *)0
-#endif
-
 void if_start(Slirp *);
 
 int get_dns_addr(struct in_addr *pdns_addr);
-- 
2.20.1




[Qemu-devel] [PULL 23/65] slirp: remove unused HAVE_ARPA_INET_H

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp_config.h | 6 --
 1 file changed, 6 deletions(-)

diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index 47811e36dc..e95284071a 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -41,12 +41,6 @@
 #define HAVE_SYS_SELECT_H
 #endif
 
-/* Define if you have arpa/inet.h */
-#undef HAVE_ARPA_INET_H
-#ifndef _WIN32
-#define HAVE_ARPA_INET_H
-#endif
-
 /* Define to sizeof(char *) */
 #define SIZEOF_CHAR_P (HOST_LONG_BITS / 8)
 
-- 
2.20.1




[Qemu-devel] [PULL 49/65] slirp: use virtual time for packet expiration

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Make all packets expiration time based on virtual clock.

Suggested-by: Paolo Bonzini 
Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/if.c| 2 +-
 slirp/slirp.c | 7 ---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/slirp/if.c b/slirp/if.c
index aa88cc4e76..ce4f5fac53 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -148,7 +148,7 @@ diddit:
  */
 void if_start(Slirp *slirp)
 {
-uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 bool from_batchq = false;
 struct mbuf *ifm, *ifm_next, *ifqt;
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index e860750f72..7091c3998a 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -582,7 +582,7 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
 return;
 }
 
-curtime = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+curtime = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
 
 QTAILQ_FOREACH(slirp, _instances, entry) {
 /*
@@ -909,7 +909,8 @@ static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct 
ethhdr *eh,
 ifm->resolution_requested = true;
 
 /* Expire request and drop outgoing packet after 1 second */
-ifm->expiration_date = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + 
10ULL;
+ifm->expiration_date =
+qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 10ULL;
 }
 return 0;
 } else {
@@ -936,7 +937,7 @@ static int if_encap6(Slirp *slirp, struct mbuf *ifm, struct 
ethhdr *eh,
 ndp_send_ns(slirp, ip6h->ip_dst);
 ifm->resolution_requested = true;
 ifm->expiration_date =
-qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + 10ULL;
+qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 10ULL;
 }
 return 0;
 } else {
-- 
2.20.1




[Qemu-devel] [PULL 59/65] slirp: factor out guestfwd addition checks

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

This will allow reusing the function in a following patch.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/misc.c  |  7 ---
 slirp/slirp.c | 23 +--
 2 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/slirp/misc.c b/slirp/misc.c
index a0f104be5e..eae9596a55 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -37,13 +37,6 @@ int add_exec(struct gfwd_list **ex_ptr, void *chardev, const 
char *cmdline,
 {
struct gfwd_list *tmp_ptr;
 
-   /* First, check if the port is "bound" */
-   for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
-   if (port == tmp_ptr->ex_fport &&
-   addr.s_addr == tmp_ptr->ex_addr.s_addr)
-   return -1;
-   }
-
tmp_ptr = *ex_ptr;
*ex_ptr = g_new0(struct gfwd_list, 1);
(*ex_ptr)->ex_fport = port;
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 851462a4cd..882d28a4de 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -1046,9 +1046,11 @@ int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct 
in_addr host_addr,
 return 0;
 }
 
-int slirp_add_exec(Slirp *slirp, void *chardev, const char *cmdline,
-   struct in_addr *guest_addr, int guest_port)
+static bool
+check_guestfwd(Slirp *slirp, struct in_addr *guest_addr, int guest_port)
 {
+struct gfwd_list *tmp_ptr;
+
 if (!guest_addr->s_addr) {
 guest_addr->s_addr = slirp->vnetwork_addr.s_addr |
 (htonl(0x0204) & ~slirp->vnetwork_mask.s_addr);
@@ -1057,6 +1059,23 @@ int slirp_add_exec(Slirp *slirp, void *chardev, const 
char *cmdline,
 slirp->vnetwork_addr.s_addr ||
 guest_addr->s_addr == slirp->vhost_addr.s_addr ||
 guest_addr->s_addr == slirp->vnameserver_addr.s_addr) {
+return false;
+}
+
+/* check if the port is "bound" */
+for (tmp_ptr = slirp->guestfwd_list; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
+if (guest_port == tmp_ptr->ex_fport &&
+guest_addr->s_addr == tmp_ptr->ex_addr.s_addr)
+return false;
+}
+
+return true;
+}
+
+int slirp_add_exec(Slirp *slirp, void *chardev, const char *cmdline,
+   struct in_addr *guest_addr, int guest_port)
+{
+if (!check_guestfwd(slirp, guest_addr, guest_port)) {
 return -1;
 }
 
-- 
2.20.1




[Qemu-devel] [PULL 55/65] slirp: introduce SLIRP_DEBUG environment variable

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Learn to read SLIRP_DEBUG=call,misc,error (all or help also handled)
to set the slirp_debug flags.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/misc.c  |  8 
 slirp/slirp.c | 15 +++
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/slirp/misc.c b/slirp/misc.c
index e30d2ceb2a..a0f104be5e 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -11,14 +11,6 @@
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
 
-#ifdef DEBUG
-#define SLIRP_DEBUG (DBG_CALL | DBG_MISC | DBG_ERROR)
-#else
-#define SLIRP_DEBUG 0
-#endif
-
-int slirp_debug = SLIRP_DEBUG;
-
 inline void
 insque(void *a, void *b)
 {
diff --git a/slirp/slirp.c b/slirp/slirp.c
index ce5f571d0f..0b70cb9fb6 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -35,6 +35,8 @@
 #include 
 #endif
 
+int slirp_debug;
+
 /* Define to 1 if you want KEEPALIVE timers */
 bool slirp_do_keepalive;
 
@@ -250,6 +252,7 @@ int get_dns6_addr(struct in6_addr *pdns6_addr, uint32_t 
*scope_id)
 static void slirp_init_once(void)
 {
 static int initialized;
+const char *debug;
 #ifdef _WIN32
 WSADATA Data;
 #endif
@@ -266,6 +269,18 @@ static void slirp_init_once(void)
 
 loopback_addr.s_addr = htonl(INADDR_LOOPBACK);
 loopback_mask = htonl(IN_CLASSA_NET);
+
+debug = g_getenv("SLIRP_DEBUG");
+if (debug) {
+const GDebugKey keys[] = {
+{ "call", DBG_CALL },
+{ "misc", DBG_MISC },
+{ "error", DBG_ERROR },
+};
+slirp_debug = g_parse_debug_string(debug, keys, G_N_ELEMENTS(keys));
+}
+
+
 }
 
 static void slirp_state_save(QEMUFile *f, void *opaque);
-- 
2.20.1




[Qemu-devel] [PULL 50/65] slirp: replace a fprintf with g_critical()

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Reduce dependency on QEMU. QEMU could use a custom glib log handler if
it wants to redirect/filter it.

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

diff --git a/slirp/socket.c b/slirp/socket.c
index 677fd20c9d..08a065f6a7 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -285,7 +285,7 @@ err:
 
 sofcantrcvmore(so);
 tcp_sockclosed(sototcpcb(so));
-fprintf(stderr, "soreadbuf buffer to small");
+g_critical("soreadbuf buffer too small");
 return -1;
 }
 
-- 
2.20.1




[Qemu-devel] [PULL 63/65] slirp: call into g_debug() for DEBUG macros

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Make slirp use GLib logging, instead of fprintf(), so that
applications can filter log, process it etc.

With recent versions of glib, G_MESSAGES_DEBUG must be set to "all" or
"Slirp" to see slirp debug messages.

Reformat DEBUG_MISC & DEBUG_ERROR calls to not need \n ending.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/cksum.c  |  4 ++--
 slirp/debug.h  | 17 -
 slirp/dhcpv6.c |  6 +++---
 slirp/ip_icmp.c| 10 +-
 slirp/slirp.c  | 10 --
 slirp/socket.c | 24 
 slirp/tcp_input.c  |  7 +++
 slirp/tcp_output.c |  2 +-
 slirp/tcp_subr.c   |  2 +-
 slirp/udp.c|  5 ++---
 slirp/udp6.c   |  5 ++---
 11 files changed, 39 insertions(+), 53 deletions(-)

diff --git a/slirp/cksum.c b/slirp/cksum.c
index 0a988b845d..84c858fafb 100644
--- a/slirp/cksum.c
+++ b/slirp/cksum.c
@@ -121,8 +121,8 @@ int cksum(struct mbuf *m, int len)
 
 cont:
if (len) {
-   DEBUG_ERROR("cksum: out of data\n");
-   DEBUG_ERROR(" len = %d\n", len);
+   DEBUG_ERROR("cksum: out of data");
+   DEBUG_ERROR(" len = %d", len);
}
if (mlen == -1) {
/* The last mbuf has odd # of bytes. Follow the
diff --git a/slirp/debug.h b/slirp/debug.h
index 50f30898fb..25a5d59439 100644
--- a/slirp/debug.h
+++ b/slirp/debug.h
@@ -12,38 +12,29 @@
 #define DBG_MISC 0x2
 #define DBG_ERROR 0x4
 
-#define dfd stderr
-
 extern int slirp_debug;
 
 #define DEBUG_CALL(fmt, ...) do {   \
 if (slirp_debug & DBG_CALL) {   \
-fprintf(dfd, fmt, ##__VA_ARGS__);   \
-fprintf(dfd, "...\n");  \
-fflush(dfd);\
+g_debug(fmt "...", ##__VA_ARGS__);  \
 }   \
 } while (0)
 
 #define DEBUG_ARG(fmt, ...) do {\
 if (slirp_debug & DBG_CALL) {   \
-fputc(' ', dfd);\
-fprintf(dfd, fmt, ##__VA_ARGS__);   \
-fputc('\n', dfd);   \
-fflush(dfd);\
+g_debug(" " fmt, ##__VA_ARGS__);\
 }   \
 } while (0)
 
 #define DEBUG_MISC(fmt, ...) do {   \
 if (slirp_debug & DBG_MISC) {   \
-fprintf(dfd, fmt, ##__VA_ARGS__);   \
-fflush(dfd);\
+g_debug(fmt, ##__VA_ARGS__);\
 }   \
 } while (0)
 
 #define DEBUG_ERROR(fmt, ...) do {  \
 if (slirp_debug & DBG_ERROR) {  \
-fprintf(dfd, fmt, ##__VA_ARGS__);   \
-fflush(dfd);\
+g_debug(fmt, ##__VA_ARGS__);\
 }   \
 } while (0)
 
diff --git a/slirp/dhcpv6.c b/slirp/dhcpv6.c
index 5d703e8ae6..752df40536 100644
--- a/slirp/dhcpv6.c
+++ b/slirp/dhcpv6.c
@@ -92,13 +92,13 @@ static int dhcpv6_parse_info_request(Slirp *slirp, uint8_t 
*odata, int olen,
 ri->want_boot_url = true;
 break;
 default:
-DEBUG_MISC("dhcpv6: Unsupported option request %d\n",
+DEBUG_MISC("dhcpv6: Unsupported option request %d",
req_opt);
 }
 }
 break;
 default:
-DEBUG_MISC("dhcpv6 info req: Unsupported option %d, len=%d\n",
+DEBUG_MISC("dhcpv6 info req: Unsupported option %d, len=%d",
option, len);
 }
 
@@ -203,6 +203,6 @@ void dhcpv6_input(struct sockaddr_in6 *srcsas, struct mbuf 
*m)
 dhcpv6_info_request(m->slirp, srcsas, xid, [4], data_len - 4);
 break;
 default:
-DEBUG_MISC("dhcpv6_input: Unsupported message type 0x%x\n", data[0]);
+DEBUG_MISC("dhcpv6_input: Unsupported message type 0x%x", data[0]);
 }
 }
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index cd2faeacb6..7c7e042049 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -103,7 +103,7 @@ static int icmp_send(struct socket *so, struct mbuf *m, int 
hlen)
 
 if (sendto(so->s, m->m_data + hlen, m->m_len - hlen, 0,
(struct sockaddr *), sizeof(addr)) == -1) {
-DEBUG_MISC("icmp_input icmp sendto tx errno = %d-%s\n",
+DEBUG_MISC("icmp_input icmp sendto tx errno = %d-%s",
errno, strerror(errno));
 icmp_send_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno));
 icmp_detach(so);
@@ -169,7 +169,7 @@ icmp_input(struct mbuf *m, int hlen)
 return;
   }
   if (udp_attach(so, AF_INET) == -1) {
-   DEBUG_MISC("icmp_input udp_attach errno = %d-%s\n",
+   DEBUG_MISC("icmp_input udp_attach errno = %d-%s",

Re: [Qemu-devel] [PATCH 3/4] accel/tcg: Add cluster number to TCG TB hash

2019-01-13 Thread Aleksandar Markovic
On Tuesday, January 8, 2019, Peter Maydell  wrote:

> Include the cluster number in the hash we use to look
> up TBs. This is important because a TB that is valid
> for one cluster at a given physical address and set
> of CPU flags is not necessarily valid for another:
> the two clusters may have different views of physical
> memory, or may have different CPU features (eg FPU
> present or absent).
>
>
Hi, Peter.

I do understand the definition of cluster_index in the sense of this
series. However, it looks to me that the term "cluster" is generally
overused in areas where we work. This may lead to some confusion for future
developers, and let me suggest some other name, like "tcg_cluster_index" or
"tcg_group_id", or "translation_group_id". Admitedly, they all sound ugly
to me too. But having the name that would clearly separate this id from too
generic "cluster_index" IMHO would save lots of time during potential
related future development.

(Needled to say that,  for example, we in MIPS, for multi-core sustems,
group cores in clusters, that actually do not have anything to do with
clusters in TCG sense...)

Sincerely,

Aleksandar



> We put the cluster number in the high 8 bits of the
> TB cflags. This gives us up to 256 clusters, which should
> be enough for anybody. If we ever need more, or need
> more bits in cflags for other purposes, we could make
> tb_hash_func() take more data (and expand qemu_xxhash7()
> to qemu_xxhash8()).
>
> Signed-off-by: Peter Maydell 
> ---
>  include/exec/exec-all.h   | 4 +++-
>  accel/tcg/cpu-exec.c  | 4 
>  accel/tcg/translate-all.c | 3 +++
>  3 files changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
> index 815e5b1e838..aa7b81aaf01 100644
> --- a/include/exec/exec-all.h
> +++ b/include/exec/exec-all.h
> @@ -351,9 +351,11 @@ struct TranslationBlock {
>  #define CF_USE_ICOUNT  0x0002
>  #define CF_INVALID 0x0004 /* TB is stale. Set with @jmp_lock held
> */
>  #define CF_PARALLEL0x0008 /* Generate code for a parallel context
> */
> +#define CF_CLUSTER_MASK 0xff00 /* Top 8 bits are cluster ID */
> +#define CF_CLUSTER_SHIFT 24
>  /* cflags' mask for hashing/comparison */
>  #define CF_HASH_MASK   \
> -(CF_COUNT_MASK | CF_LAST_IO | CF_USE_ICOUNT | CF_PARALLEL)
> +(CF_COUNT_MASK | CF_LAST_IO | CF_USE_ICOUNT | CF_PARALLEL |
> CF_CLUSTER_MASK)
>
>  /* Per-vCPU dynamic tracing state used to generate this TB */
>  uint32_t trace_vcpu_dstate;
> diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
> index 870027d4359..e578a1a3aee 100644
> --- a/accel/tcg/cpu-exec.c
> +++ b/accel/tcg/cpu-exec.c
> @@ -336,6 +336,10 @@ TranslationBlock *tb_htable_lookup(CPUState *cpu,
> target_ulong pc,
>  return NULL;
>  }
>  desc.phys_page1 = phys_pc & TARGET_PAGE_MASK;
> +
> +cf_mask &= ~CF_CLUSTER_MASK;
> +cf_mask |= cpu->cluster_index << CF_CLUSTER_SHIFT;
> +
>  h = tb_hash_func(phys_pc, pc, flags, cf_mask, *cpu->trace_dstate);
>  return qht_lookup_custom(_ctx.htable, , h, tb_lookup_cmp);
>  }
> diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
> index 639f0b27287..ba27f5acc8c 100644
> --- a/accel/tcg/translate-all.c
> +++ b/accel/tcg/translate-all.c
> @@ -1692,6 +1692,9 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
>  cflags |= CF_NOCACHE | 1;
>  }
>
> +cflags &= ~CF_CLUSTER_MASK;
> +cflags |= cpu->cluster_index << CF_CLUSTER_SHIFT;
> +
>   buffer_overflow:
>  tb = tb_alloc(pc);
>  if (unlikely(!tb)) {
> --
> 2.19.2
>
>
>


[Qemu-devel] [PATCH 01/17] target/arm: Add MTE_ACTIVE to tb_flags

2019-01-13 Thread Richard Henderson
When MTE is fully enabled, i.e. access to tags are enabled and
tag checks affect the PE, then arrange to perform the check
while stripping the TBI.

The check is not yet implemented, just the plumbing to that point.

Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h   | 13 +++
 target/arm/helper-a64.h|  2 ++
 target/arm/internals.h | 18 +++
 target/arm/translate.h |  2 ++
 target/arm/helper.c| 45 --
 target/arm/mte_helper.c| 32 +++
 target/arm/translate-a64.c |  9 +++-
 target/arm/Makefile.objs   |  2 +-
 8 files changed, 110 insertions(+), 13 deletions(-)
 create mode 100644 target/arm/mte_helper.c

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index f2ff52f287..22163c9c3f 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1164,6 +1164,7 @@ void pmccntr_sync(CPUARMState *env);
 #define PSTATE_BTYPE (3U << 10)
 #define PSTATE_IL (1U << 20)
 #define PSTATE_SS (1U << 21)
+#define PSTATE_TCO (1U << 25)
 #define PSTATE_V (1U << 28)
 #define PSTATE_C (1U << 29)
 #define PSTATE_Z (1U << 30)
@@ -1640,6 +1641,7 @@ FIELD(ID_AA64PFR0, SVE, 32, 4)
 
 FIELD(ID_AA64PFR1, BT, 0, 4)
 FIELD(ID_AA64PFR1, SBSS, 4, 4)
+FIELD(ID_AA64PFR1, MTE, 8, 4)
 
 FIELD(ID_AA64MMFR0, PARANGE, 0, 4)
 FIELD(ID_AA64MMFR0, ASIDBITS, 4, 4)
@@ -3003,6 +3005,7 @@ FIELD(TBFLAG_A64, PAUTH_ACTIVE, 8, 1)
 FIELD(TBFLAG_A64, BT, 9, 1)
 FIELD(TBFLAG_A64, BTYPE, 10, 2)
 FIELD(TBFLAG_A64, TBID, 12, 2)
+FIELD(TBFLAG_A64, MTE_ACTIVE, 14, 1)
 
 static inline bool bswap_code(bool sctlr_b)
 {
@@ -3293,6 +3296,16 @@ static inline bool isar_feature_aa64_bti(const 
ARMISARegisters *id)
 return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
 }
 
+static inline bool isar_feature_aa64_mte_insn_reg(const ARMISARegisters *id)
+{
+return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) != 0;
+}
+
+static inline bool isar_feature_aa64_mte(const ARMISARegisters *id)
+{
+return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 2;
+}
+
 /*
  * Forward to the above feature tests given an ARMCPU pointer.
  */
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
index a915c1247f..fa4c371a47 100644
--- a/target/arm/helper-a64.h
+++ b/target/arm/helper-a64.h
@@ -102,3 +102,5 @@ DEF_HELPER_FLAGS_3(autda, TCG_CALL_NO_WG, i64, env, i64, 
i64)
 DEF_HELPER_FLAGS_3(autdb, TCG_CALL_NO_WG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_2(xpaci, TCG_CALL_NO_RWG_SE, i64, env, i64)
 DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, i64)
+
+DEF_HELPER_FLAGS_2(mte_check, TCG_CALL_NO_WG, i64, env, i64)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 587a1ddf58..6c018e773c 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -983,4 +983,22 @@ static inline int exception_target_el(CPUARMState *env)
 return target_el;
 }
 
+/* Determine if allocation tags are available.  */
+static inline bool allocation_tag_access_enabled(CPUARMState *env, int el,
+ uint64_t sctlr)
+{
+if (el < 3
+&& arm_feature(env, ARM_FEATURE_EL3)
+&& !(env->cp15.scr_el3 & SCR_ATA)) {
+return false;
+}
+if (el < 2
+&& arm_feature(env, ARM_FEATURE_EL2)
+&& !(arm_hcr_el2_eff(env) & HCR_ATA)) {
+return false;
+}
+sctlr &= (el == 0 ? SCTLR_ATA0 : SCTLR_ATA);
+return sctlr != 0;
+}
+
 #endif
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 33af50a13f..5a101e1c6d 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -70,6 +70,8 @@ typedef struct DisasContext {
 bool ss_same_el;
 /* True if v8.3-PAuth is active.  */
 bool pauth_active;
+/* True if v8.5-MTE tag checks affect the PE.  */
+bool mte_active;
 /* True with v8.5-BTI and SCTLR_ELx.BT* set.  */
 bool bt;
 /*
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 6b7b639da5..038e52af4b 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -3465,22 +3465,31 @@ static void sctlr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 {
 ARMCPU *cpu = arm_env_get_cpu(env);
 
-if (raw_read(env, ri) == value) {
-/* Skip the TLB flush if nothing actually changed; Linux likes
- * to do a lot of pointless SCTLR writes.
- */
-return;
-}
-
 if (arm_feature(env, ARM_FEATURE_PMSA) && !cpu->has_mpu) {
 /* M bit is RAZ/WI for PMSA with no MPU implemented */
 value &= ~SCTLR_M;
 }
 
-raw_write(env, ri, value);
+if (!cpu_isar_feature(aa64_mte, cpu)) {
+if (ri->opc1 == 6) { /* SCTLR_EL3 */
+value &= ~(SCTLR_ITFSB | SCTLR_TCF | SCTLR_ATA);
+} else {
+value &= ~(SCTLR_ITFSB | SCTLR_TCF0 | SCTLR_TCF |
+   SCTLR_ATA0 | SCTLR_ATA);
+}
+}
+
 /* ??? Lots of these bits are not implemented.  */
-/* This may enable/disable the MMU, so do a TLB flush.  */
-

[Qemu-devel] [PATCH 00/17] target/arm: Implement ARMv8.5-MemTag

2019-01-13 Thread Richard Henderson
Based-on: 20190110124951.15473-1-richard.hender...@linaro.org
aka the TBID patch set, which itself is based on the BTI patch set.

The full tree is available at

  https://github.org/rth7680/qemu.git tgt-arm-mte

This extension isl also spelled MTE in the ARM.

This patch set only attempts to implement linux-user emulation.
For system emulation, I still miss the new cache flushing insns (easy)
and the out-of-band physical memory for the allocation tags (harder).

>From a few mis-steps in writing the test cases for the extension,
I might suggest that some future kernel's userland ABI for this have
TCR.TCMA0 = 1, so that legacy code that is *not* MTE aware can use
a frame pointer without accidentally tripping left over stack tags.
(As seen in patch 5, SP+OFF is unchecked per the ISA but FP+OFF is not.)

OTOH, depending on the application, that does make it easier for an
attack vector to clean the tag off the top of a pointer to bypass
store checking.  So, tricky.


r~


Cc: Ramana Radhakrishnan 
Cc: Will Deacon 
Cc: dave.mar...@arm.com
Cc: szabolcs.n...@arm.com
Cc: catalin.mari...@arm.com
Cc: mark.rutl...@arm.com

Richard Henderson (17):
  target/arm: Add MTE_ACTIVE to tb_flags
  target/arm: Extract TCMA with ARMVAParameters
  target/arm: Add MTE system registers
  target/arm: Fill in helper_mte_check
  target/arm: Suppress tag check for sp+offset
  target/arm: Implement the IRG instruction
  target/arm: Implement ADDG, SUBG instructions
  target/arm: Implement the GMI instruction
  target/arm: Implement the SUBP instruction
  target/arm: Implement LDG, STG, ST2G instructions
  target/arm: Implement the STGP instruction
  target/arm: Implement the LDGV and STGV instructions
  target/arm: Set PSTATE.TCO on exception entry
  tcg: Introduce target-specific page data for user-only
  target/arm: Add allocation tag storage for user-only
  target/arm: Enable MTE
  tests/tcg/aarch64: Add mte smoke tests

 include/exec/cpu-all.h|  10 +-
 target/arm/cpu.h  |  18 ++
 target/arm/helper-a64.h   |  11 +
 target/arm/internals.h|  22 ++
 target/arm/translate.h|  13 ++
 accel/tcg/translate-all.c |  28 +++
 linux-user/mmap.c |  10 +-
 linux-user/syscall.c  |   4 +-
 target/arm/cpu.c  |  10 +
 target/arm/cpu64.c|   1 +
 target/arm/helper.c   |  99 ++--
 target/arm/mte_helper.c   | 369 ++
 target/arm/translate-a64.c| 305 
 tests/tcg/aarch64/mte-1.c |  27 +++
 tests/tcg/aarch64/mte-2.c |  39 
 target/arm/Makefile.objs  |   2 +-
 tests/tcg/aarch64/Makefile.target |   4 +
 17 files changed, 907 insertions(+), 65 deletions(-)
 create mode 100644 target/arm/mte_helper.c
 create mode 100644 tests/tcg/aarch64/mte-1.c
 create mode 100644 tests/tcg/aarch64/mte-2.c

-- 
2.17.2




[Qemu-devel] [PATCH 02/17] target/arm: Extract TCMA with ARMVAParameters

2019-01-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/internals.h | 1 +
 target/arm/helper.c| 8 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 6c018e773c..2922324f63 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -959,6 +959,7 @@ typedef struct ARMVAParameters {
 bool tbid   : 1;
 bool epd: 1;
 bool hpd: 1;
+bool tcma   : 1;
 bool using16k   : 1;
 bool using64k   : 1;
 } ARMVAParameters;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 038e52af4b..5a59fc4315 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -9789,7 +9789,7 @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, 
uint64_t va,
 {
 uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
 uint32_t el = regime_el(env, mmu_idx);
-bool tbi, tbid, epd, hpd, using16k, using64k;
+bool tbi, tbid, epd, hpd, tcma, using16k, using64k;
 int select, tsz;
 
 /* Bit 55 is always between the two regions, and is canonical for
@@ -9803,11 +9803,12 @@ ARMVAParameters aa64_va_parameters_both(CPUARMState 
*env, uint64_t va,
 using16k = extract32(tcr, 15, 1);
 if (mmu_idx == ARMMMUIdx_S2NS) {
 /* VTCR_EL2 */
-tbi = tbid = hpd = false;
+tbi = tbid = hpd = tcma = false;
 } else {
 tbi = extract32(tcr, 20, 1);
 hpd = extract32(tcr, 24, 1);
 tbid = extract32(tcr, 29, 1);
+tcma = extract32(tcr, 30, 1);
 }
 epd = false;
 } else if (!select) {
@@ -9818,6 +9819,7 @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, 
uint64_t va,
 tbi = extract64(tcr, 37, 1);
 hpd = extract64(tcr, 41, 1);
 tbid = extract64(tcr, 51, 1);
+tcma = extract64(tcr, 57, 1);
 } else {
 int tg = extract32(tcr, 30, 2);
 using16k = tg == 1;
@@ -9827,6 +9829,7 @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, 
uint64_t va,
 tbi = extract64(tcr, 38, 1);
 hpd = extract64(tcr, 42, 1);
 tbid = extract64(tcr, 52, 1);
+tcma = extract64(tcr, 58, 1);
 }
 tsz = MIN(tsz, 39);  /* TODO: ARMv8.4-TTST */
 tsz = MAX(tsz, 16);  /* TODO: ARMv8.2-LVA  */
@@ -9838,6 +9841,7 @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, 
uint64_t va,
 .tbid = tbid,
 .epd = epd,
 .hpd = hpd,
+.tcma = tcma,
 .using16k = using16k,
 .using64k = using64k,
 };
-- 
2.17.2




[Qemu-devel] [PATCH 12/17] target/arm: Implement the LDGV and STGV instructions

2019-01-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper-a64.h|  2 ++
 target/arm/mte_helper.c| 51 ++
 target/arm/translate-a64.c | 34 -
 3 files changed, 81 insertions(+), 6 deletions(-)

diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
index ff37c8975a..5bbfe43c13 100644
--- a/target/arm/helper-a64.h
+++ b/target/arm/helper-a64.h
@@ -111,3 +111,5 @@ DEF_HELPER_FLAGS_2(gmi, TCG_CALL_NO_RWG_SE, i64, i64, i64)
 DEF_HELPER_FLAGS_2(ldg, TCG_CALL_NO_WG, i64, env, i64)
 DEF_HELPER_FLAGS_2(stg, TCG_CALL_NO_WG, i64, env, i64)
 DEF_HELPER_FLAGS_2(st2g, TCG_CALL_NO_WG, i64, env, i64)
+DEF_HELPER_FLAGS_2(ldgv, TCG_CALL_NO_WG, i64, env, i64)
+DEF_HELPER_FLAGS_3(stgv, TCG_CALL_NO_WG, void, env, i64, i64)
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index 06fd9c18f9..b125f49258 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -256,3 +256,54 @@ uint64_t HELPER(st2g)(CPUARMState *env, uint64_t ptr)
 /* ??? Do we need a more precise TBI here?  */
 return sextract64(ptr, 0, 55);
 }
+
+uint64_t HELPER(ldgv)(CPUARMState *env, uint64_t ptr)
+{
+int el = arm_current_el(env);
+uint64_t sctlr = arm_sctlr(env, el);
+uint64_t ret;
+int rtag, i;
+
+if (!allocation_tag_access_enabled(env, el, sctlr)) {
+return 0;
+}
+
+ptr = QEMU_ALIGN_DOWN(ptr, 1 << LOG2_TAG_GRANULE);
+rtag = get_allocation_tag(env, ptr);
+if (rtag < 0) {
+/* The entire page does not have tags.  */
+return 0;
+}
+
+i = extract32(ptr, LOG2_TAG_GRANULE, 4);
+ret = (uint64_t)rtag << i;
+for (i++; i < 16; i++) {
+rtag = get_allocation_tag(env, ptr + (i << LOG2_TAG_GRANULE));
+ret |= (uint64_t)rtag << i;
+}
+
+return ret;
+}
+
+void HELPER(stgv)(CPUARMState *env, uint64_t ptr, uint64_t val)
+{
+int el = arm_current_el(env);
+uint64_t sctlr = arm_sctlr(env, el);
+int rtag, i;
+
+if (!allocation_tag_access_enabled(env, el, sctlr)) {
+return;
+}
+
+rtag = allocation_tag_from_addr(ptr);
+ptr = QEMU_ALIGN_DOWN(ptr, 1 << LOG2_TAG_GRANULE);
+if (!set_allocation_tag(env, ptr, rtag)) {
+/* The entire page does not have tags.  */
+return;
+}
+
+i = extract32(ptr, LOG2_TAG_GRANULE, 4);
+for (i++; i < 16; i++) {
+set_allocation_tag(env, ptr + (i << LOG2_TAG_GRANULE), rtag);
+}
+}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 911d6f06b3..b4226def40 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -3612,7 +3612,7 @@ static void disas_ldst_tag(DisasContext *s, uint32_t insn)
 uint64_t offset = sextract64(insn, 12, 9) << LOG2_TAG_GRANULE;
 int op2 = extract32(insn, 10, 3);
 int op1 = extract32(insn, 22, 2);
-bool is_load = false, is_pair = false, is_zero = false;
+bool is_load = false, is_pair = false, is_zero = false, is_tagv = false;
 int index = 0;
 TCGv_i64 dirty_addr, clean_addr;
 
@@ -3644,17 +3644,29 @@ static void disas_ldst_tag(DisasContext *s, uint32_t 
insn)
 /* ST2G */
 is_pair = true;
 index = op2 - 2;
-break;
+} else {
+/* STGV */
+if (s->current_el == 0 || offset != 0) {
+goto do_unallocated;
+}
+is_tagv = true;
+index = 1;
 }
-goto do_unallocated;
+break;
 case 3:
 if (op2 != 0) {
 /* STZ2G */
 is_pair = is_zero = true;
 index = op2 - 2;
-break;
+} else {
+/* LDGV */
+if (s->current_el == 0 || offset != 0 || rt == rn) {
+goto do_unallocated;
+}
+is_load = is_tagv = true;
+index = 1;
 }
-goto do_unallocated;
+break;
 
 default:
 do_unallocated:
@@ -3669,7 +3681,17 @@ static void disas_ldst_tag(DisasContext *s, uint32_t 
insn)
 }
 
 clean_addr = tcg_temp_new_i64();
-if (is_load) {
+if (is_tagv) {
+if (is_load) {
+gen_helper_ldgv(cpu_reg(s, rt), cpu_env, dirty_addr);
+} else {
+gen_helper_stgv(cpu_env, dirty_addr, cpu_reg(s, rt));
+}
+
+/* Post-increment with dirty = align_up(dirty, 16*TAG_GRANULE).  */
+tcg_gen_ori_i64(dirty_addr, dirty_addr, (16 << LOG2_TAG_GRANULE) - 1);
+tcg_gen_addi_i64(dirty_addr, dirty_addr, 1);
+} else if (is_load) {
 gen_helper_ldg(cpu_reg(s, rt), cpu_env, dirty_addr);
 } else if (is_pair) {
 gen_helper_st2g(clean_addr, cpu_env, dirty_addr);
-- 
2.17.2




[Qemu-devel] [PATCH 10/17] target/arm: Implement LDG, STG, ST2G instructions

2019-01-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper-a64.h|   3 ++
 target/arm/mte_helper.c|  53 +++
 target/arm/translate-a64.c | 106 +
 3 files changed, 162 insertions(+)

diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
index ef340cb6f9..ff37c8975a 100644
--- a/target/arm/helper-a64.h
+++ b/target/arm/helper-a64.h
@@ -108,3 +108,6 @@ DEF_HELPER_FLAGS_3(irg, TCG_CALL_NO_RWG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_4(addg, TCG_CALL_NO_RWG_SE, i64, env, i64, i32, i32)
 DEF_HELPER_FLAGS_4(subg, TCG_CALL_NO_RWG_SE, i64, env, i64, i32, i32)
 DEF_HELPER_FLAGS_2(gmi, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(ldg, TCG_CALL_NO_WG, i64, env, i64)
+DEF_HELPER_FLAGS_2(stg, TCG_CALL_NO_WG, i64, env, i64)
+DEF_HELPER_FLAGS_2(st2g, TCG_CALL_NO_WG, i64, env, i64)
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index 2f6ac45150..06fd9c18f9 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -31,6 +31,12 @@ static int get_allocation_tag(CPUARMState *env, uint64_t ptr)
 return -1;
 }
 
+static bool set_allocation_tag(CPUARMState *env, uint64_t ptr, int tag)
+{
+/* Tag storage not implemented.  */
+return false;
+}
+
 static int allocation_tag_from_addr(uint64_t ptr)
 {
 return (extract64(ptr, 56, 4) + extract64(ptr, 55, 1)) & 15;
@@ -203,3 +209,50 @@ uint64_t HELPER(gmi)(uint64_t ptr, uint64_t mask)
 int tag = allocation_tag_from_addr(ptr);
 return mask | (1ULL << tag);
 }
+
+uint64_t HELPER(ldg)(CPUARMState *env, uint64_t ptr)
+{
+int el = arm_current_el(env);
+uint64_t sctlr = arm_sctlr(env, el);
+int rtag = 0;
+
+if (allocation_tag_access_enabled(env, el, sctlr)) {
+rtag = get_allocation_tag(env, ptr);
+if (rtag < 0) {
+rtag = 0;
+}
+}
+return address_with_allocation_tag(ptr, rtag);
+}
+
+uint64_t HELPER(stg)(CPUARMState *env, uint64_t ptr)
+{
+int el = arm_current_el(env);
+uint64_t sctlr = arm_sctlr(env, el);
+
+if (allocation_tag_access_enabled(env, el, sctlr)) {
+int tag = allocation_tag_from_addr(ptr);
+set_allocation_tag(env, ptr, tag);
+}
+
+/* Clean the pointer for use by stgz.  */
+/* ??? Do we need a more precise TBI here?  */
+return sextract64(ptr, 0, 55);
+}
+
+uint64_t HELPER(st2g)(CPUARMState *env, uint64_t ptr)
+{
+int el = arm_current_el(env);
+uint64_t sctlr = arm_sctlr(env, el);
+
+if (allocation_tag_access_enabled(env, el, sctlr)) {
+int tag = allocation_tag_from_addr(ptr);
+if (set_allocation_tag(env, ptr, tag)) {
+set_allocation_tag(env, ptr + (1 << LOG2_TAG_GRANULE), tag);
+}
+}
+
+/* Clean the pointer for use by stgz.  */
+/* ??? Do we need a more precise TBI here?  */
+return sextract64(ptr, 0, 55);
+}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 98ff60c161..60865945e4 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -3583,6 +3583,109 @@ static void disas_ldst_single_struct(DisasContext *s, 
uint32_t insn)
 }
 }
 
+/*
+ * Load/Store memory tags
+ *
+ *  31 30 29 24 22  21 1210  5  0
+ * +-+-+-+---+--+-+--+--+
+ * | 1 1 | 0 1 1 0 0 1 | op1 | 1 | imm9 | op2 |  Rn  |  Rt  |
+ * +-+-+-+---+--+-+--+--+
+ */
+static void disas_ldst_tag(DisasContext *s, uint32_t insn)
+{
+int rt = extract32(insn, 0, 5);
+int rn = extract32(insn, 5, 5);
+uint64_t offset = sextract64(insn, 12, 9) << LOG2_TAG_GRANULE;
+int op2 = extract32(insn, 10, 3);
+int op1 = extract32(insn, 22, 2);
+bool is_load = false, is_pair = false, is_zero = false;
+int index = 0;
+TCGv_i64 dirty_addr, clean_addr;
+
+if ((insn & 0xff20) != 0xd920
+|| !dc_isar_feature(aa64_mte_insn_reg, s)) {
+goto do_unallocated;
+}
+
+switch (op1) {
+case 0: /* STG */
+if (op2 != 0) {
+/* STG */
+index = op2 - 2;
+break;
+}
+goto do_unallocated;
+case 1:
+if (op2 != 0) {
+/* STZG */
+is_zero = true;
+index = op2 - 2;
+} else {
+/* LDG */
+is_load = true;
+}
+break;
+case 2:
+if (op2 != 0) {
+/* ST2G */
+is_pair = true;
+index = op2 - 2;
+break;
+}
+goto do_unallocated;
+case 3:
+if (op2 != 0) {
+/* STZ2G */
+is_pair = is_zero = true;
+index = op2 - 2;
+break;
+}
+goto do_unallocated;
+
+default:
+do_unallocated:
+unallocated_encoding(s);
+return;
+}
+
+dirty_addr = read_cpu_reg_sp(s, rn, true);
+if (index <= 0) {
+/* pre-index or signed offset */
+

[Qemu-devel] [PATCH 06/17] target/arm: Implement the IRG instruction

2019-01-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper-a64.h|  1 +
 target/arm/mte_helper.c| 55 ++
 target/arm/translate-a64.c |  7 +
 3 files changed, 63 insertions(+)

diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
index fa4c371a47..7a6051fdab 100644
--- a/target/arm/helper-a64.h
+++ b/target/arm/helper-a64.h
@@ -104,3 +104,4 @@ DEF_HELPER_FLAGS_2(xpaci, TCG_CALL_NO_RWG_SE, i64, env, i64)
 DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, i64)
 
 DEF_HELPER_FLAGS_2(mte_check, TCG_CALL_NO_WG, i64, env, i64)
+DEF_HELPER_FLAGS_3(irg, TCG_CALL_NO_RWG, i64, env, i64, i64)
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index 6f4bc0aa04..1878393fc4 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -36,6 +36,48 @@ static int allocation_tag_from_addr(uint64_t ptr)
 return (extract64(ptr, 56, 4) + extract64(ptr, 55, 1)) & 15;
 }
 
+/* Like ChooseNonExcludedTag, except that GCR_EL1 is already in.  */
+static int choose_nonexcluded_tag(int tag, int offset, uint16_t exclude)
+{
+if (exclude != 0x) {
+int i;
+for (i = 0; i < offset; ++i) {
+do {
+tag = (tag + 1) & 15;
+} while (exclude & (1 << tag));
+}
+}
+return tag;
+}
+
+static int choose_random_nonexcluded_tag(CPUARMState *env, uint16_t exclude)
+{
+/* Ignore GCR_EL1.RRND.  Always produce deterministic results.  */
+int start = extract32(env->cp15.rgsr_el1, 0, 4);
+int seed = extract32(env->cp15.rgsr_el1, 8, 16);
+int offset, rtag, i;
+
+/* RandomTag */
+for (i = offset = 0; i < 4; ++i) {
+/* NextRandomTagBit */
+int top = (extract32(seed, 5, 1) ^ extract32(seed, 3, 1) ^
+   extract32(seed, 2, 1) ^ extract32(seed, 0, 1));
+seed = (top << 15) | (seed >> 1);
+offset |= top << i;
+}
+rtag = choose_nonexcluded_tag(start, offset, exclude);
+
+env->cp15.rgsr_el1 = rtag | (seed << 8);
+
+return rtag;
+}
+
+static uint64_t address_with_allocation_tag(uint64_t ptr, int rtag)
+{
+rtag -= extract64(ptr, 55, 1);
+return deposit64(ptr, 56, 4, rtag);
+}
+
 uint64_t HELPER(mte_check)(CPUARMState *env, uint64_t ptr)
 {
 ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
@@ -108,3 +150,16 @@ uint64_t HELPER(mte_check)(CPUARMState *env, uint64_t ptr)
 /* Unchecked, or tag check pass.  Ignore the top byte.  */
 return sextract64(ptr, 0, 55);
 }
+
+uint64_t HELPER(irg)(CPUARMState *env, uint64_t rn, uint64_t rm)
+{
+int el = arm_current_el(env);
+uint64_t sctlr = arm_sctlr(env, el);
+int rtag = 0;
+
+if (allocation_tag_access_enabled(env, el, sctlr)) {
+uint16_t exclude = rm | env->cp15.gcr_el1;
+rtag = choose_random_nonexcluded_tag(env, exclude);
+}
+return address_with_allocation_tag(rn, rtag);
+}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index ee95ba7165..b0349bffc4 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -5105,6 +5105,13 @@ static void disas_data_proc_2src(DisasContext *s, 
uint32_t insn)
 case 3: /* SDIV */
 handle_div(s, true, sf, rm, rn, rd);
 break;
+case 4: /* IRG */
+if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) {
+goto do_unallocated;
+}
+gen_helper_irg(cpu_reg_sp(s, rd), cpu_env,
+   cpu_reg_sp(s, rn), cpu_reg(s, rm));
+break;
 case 8: /* LSLV */
 handle_shift_reg(s, A64_SHIFT_TYPE_LSL, sf, rm, rn, rd);
 break;
-- 
2.17.2




[Qemu-devel] [PATCH 11/17] target/arm: Implement the STGP instruction

2019-01-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 60865945e4..911d6f06b3 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -2696,7 +2696,7 @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
  * +-+---+---+---+---+---+---+---+--+--+
  *
  * opc: LDP/STP/LDNP/STNP00 -> 32 bit, 10 -> 64 bit
- *  LDPSW01
+ *  LDPSW/STGP   01
  *  LDP/STP/LDNP/STNP (SIMD) 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit
  *   V: 0 -> GPR, 1 -> Vector
  * idx: 00 -> signed offset with non-temporal hint, 01 -> post-index,
@@ -2721,6 +2721,7 @@ static void disas_ldst_pair(DisasContext *s, uint32_t 
insn)
 bool is_signed = false;
 bool postindex = false;
 bool wback = false;
+bool set_tag = false;
 
 TCGv_i64 clean_addr, dirty_addr;
 
@@ -2733,6 +2734,14 @@ static void disas_ldst_pair(DisasContext *s, uint32_t 
insn)
 
 if (is_vector) {
 size = 2 + opc;
+} else if (opc == 1 && !is_load) {
+/* STGP */
+if (!dc_isar_feature(aa64_mte_insn_reg, s) || index == 0) {
+unallocated_encoding(s);
+return;
+}
+size = 3;
+set_tag = true;
 } else {
 size = 2 + extract32(opc, 1, 1);
 is_signed = extract32(opc, 0, 1);
@@ -2783,7 +2792,12 @@ static void disas_ldst_pair(DisasContext *s, uint32_t 
insn)
 if (!postindex) {
 tcg_gen_addi_i64(dirty_addr, dirty_addr, offset);
 }
-clean_addr = clean_data_tbi(s, dirty_addr, rn == 31);
+if (set_tag) {
+clean_addr = new_tmp_a64(s);
+gen_helper_stg(clean_addr, cpu_env, dirty_addr);
+} else {
+clean_addr = clean_data_tbi(s, dirty_addr, rn == 31);
+}
 
 if (is_vector) {
 if (is_load) {
-- 
2.17.2




[Qemu-devel] [PATCH 08/17] target/arm: Implement the GMI instruction

2019-01-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper-a64.h| 1 +
 target/arm/mte_helper.c| 6 ++
 target/arm/translate-a64.c | 6 ++
 3 files changed, 13 insertions(+)

diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
index 47577207b2..ef340cb6f9 100644
--- a/target/arm/helper-a64.h
+++ b/target/arm/helper-a64.h
@@ -107,3 +107,4 @@ DEF_HELPER_FLAGS_2(mte_check, TCG_CALL_NO_WG, i64, env, i64)
 DEF_HELPER_FLAGS_3(irg, TCG_CALL_NO_RWG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_4(addg, TCG_CALL_NO_RWG_SE, i64, env, i64, i32, i32)
 DEF_HELPER_FLAGS_4(subg, TCG_CALL_NO_RWG_SE, i64, env, i64, i32, i32)
+DEF_HELPER_FLAGS_2(gmi, TCG_CALL_NO_RWG_SE, i64, i64, i64)
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index e2b1a5dd40..2f6ac45150 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -197,3 +197,9 @@ uint64_t HELPER(subg)(CPUARMState *env, uint64_t ptr,
 offset <<= LOG2_TAG_GRANULE;
 return address_with_allocation_tag(ptr - offset, rtag);
 }
+
+uint64_t HELPER(gmi)(uint64_t ptr, uint64_t mask)
+{
+int tag = allocation_tag_from_addr(ptr);
+return mask | (1ULL << tag);
+}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 879d6b8d46..6583ad93b1 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -5137,6 +5137,12 @@ static void disas_data_proc_2src(DisasContext *s, 
uint32_t insn)
 gen_helper_irg(cpu_reg_sp(s, rd), cpu_env,
cpu_reg_sp(s, rn), cpu_reg(s, rm));
 break;
+case 5: /* GMI */
+if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) {
+goto do_unallocated;
+}
+gen_helper_gmi(cpu_reg(s, rd), cpu_reg_sp(s, rn), cpu_reg(s, rm));
+break;
 case 8: /* LSLV */
 handle_shift_reg(s, A64_SHIFT_TYPE_LSL, sf, rm, rn, rd);
 break;
-- 
2.17.2




[Qemu-devel] [PATCH 14/17] tcg: Introduce target-specific page data for user-only

2019-01-13 Thread Richard Henderson
At the same time, remember MAP_SHARED as PAGE_SHARED.  When mapping
new pages, make sure that old target-specific page data is removed.

Signed-off-by: Richard Henderson 
---
 include/exec/cpu-all.h| 10 --
 accel/tcg/translate-all.c | 28 
 linux-user/mmap.c | 10 --
 linux-user/syscall.c  |  4 ++--
 4 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 117d2fbbca..92ec47dc79 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -244,10 +244,14 @@ extern intptr_t qemu_host_page_mask;
 #define PAGE_WRITE_ORG 0x0010
 /* Invalidate the TLB entry immediately, helpful for s390x
  * Low-Address-Protection. Used with PAGE_WRITE in tlb_set_page_with_attrs() */
-#define PAGE_WRITE_INV 0x0040
+#define PAGE_WRITE_INV 0x0020
+/* Page is mapped shared.  */
+#define PAGE_SHARED0x0040
+/* For use with page_set_flags: page is being replaced; target_data cleared. */
+#define PAGE_RESET 0x0080
 #if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
 /* FIXME: Code that sets/uses this is broken and needs to go away.  */
-#define PAGE_RESERVED  0x0020
+#define PAGE_RESERVED  0x0100
 #endif
 
 #if defined(CONFIG_USER_ONLY)
@@ -260,6 +264,8 @@ int walk_memory_regions(void *, walk_memory_regions_fn);
 int page_get_flags(target_ulong address);
 void page_set_flags(target_ulong start, target_ulong end, int flags);
 int page_check_range(target_ulong start, target_ulong len, int flags);
+void *page_get_target_data(target_ulong address);
+void *page_alloc_target_data(target_ulong address, size_t size);
 #endif
 
 CPUArchState *cpu_copy(CPUArchState *env);
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 639f0b2728..047cd2f50d 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -111,6 +111,7 @@ typedef struct PageDesc {
 unsigned int code_write_count;
 #else
 unsigned long flags;
+void *target_data;
 #endif
 #ifndef CONFIG_USER_ONLY
 QemuSpin lock;
@@ -2477,6 +2478,7 @@ int page_get_flags(target_ulong address)
 void page_set_flags(target_ulong start, target_ulong end, int flags)
 {
 target_ulong addr, len;
+bool reset_target_data;
 
 /* This function should never be called with addresses outside the
guest address space.  If this assert fires, it probably indicates
@@ -2493,6 +2495,8 @@ void page_set_flags(target_ulong start, target_ulong end, 
int flags)
 if (flags & PAGE_WRITE) {
 flags |= PAGE_WRITE_ORG;
 }
+reset_target_data = !(flags & PAGE_VALID) || (flags & PAGE_RESET);
+flags &= ~PAGE_RESET;
 
 for (addr = start, len = end - start;
  len != 0;
@@ -2506,10 +2510,34 @@ void page_set_flags(target_ulong start, target_ulong 
end, int flags)
 p->first_tb) {
 tb_invalidate_phys_page(addr, 0);
 }
+if (reset_target_data && p->target_data) {
+g_free(p->target_data);
+p->target_data = NULL;
+}
 p->flags = flags;
 }
 }
 
+void *page_get_target_data(target_ulong address)
+{
+PageDesc *p = page_find(address >> TARGET_PAGE_BITS);
+return p ? p->target_data : NULL;
+}
+
+void *page_alloc_target_data(target_ulong address, size_t size)
+{
+PageDesc *p = page_find(address >> TARGET_PAGE_BITS);
+void *ret = NULL;
+
+if (p) {
+ret = p->target_data;
+if (!ret && (p->flags & PAGE_VALID)) {
+p->target_data = ret = g_malloc0(size);
+}
+}
+return ret;
+}
+
 int page_check_range(target_ulong start, target_ulong len, int flags)
 {
 PageDesc *p;
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 41e0983ce8..f83874b8c1 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -562,7 +562,11 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int 
prot,
 }
 }
  the_end1:
-page_set_flags(start, start + len, prot | PAGE_VALID);
+if ((flags & MAP_TYPE) == MAP_SHARED) {
+prot |= PAGE_SHARED;
+}
+prot |= PAGE_RESET | PAGE_VALID;
+page_set_flags(start, start + len, prot);
  the_end:
 #ifdef DEBUG_MMAP
 printf("ret=0x" TARGET_ABI_FMT_lx "\n", start);
@@ -754,9 +758,11 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong 
old_size,
 new_addr = -1;
 } else {
 new_addr = h2g(host_addr);
+/* FIXME: Move page flags (and target_data?) for each page.  */
 prot = page_get_flags(old_addr);
 page_set_flags(old_addr, old_addr + old_size, 0);
-page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID);
+page_set_flags(new_addr, new_addr + new_size,
+   prot | PAGE_VALID | PAGE_RESET);
 }
 tb_invalidate_phys_range(new_addr, new_addr + new_size);
 mmap_unlock();
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 280137da8c..715101816d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3845,8 

[Qemu-devel] [PATCH 07/17] target/arm: Implement ADDG, SUBG instructions

2019-01-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper-a64.h|  2 ++
 target/arm/internals.h |  3 ++
 target/arm/mte_helper.c| 34 ++
 target/arm/translate-a64.c | 71 ++
 4 files changed, 87 insertions(+), 23 deletions(-)

diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
index 7a6051fdab..47577207b2 100644
--- a/target/arm/helper-a64.h
+++ b/target/arm/helper-a64.h
@@ -105,3 +105,5 @@ DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, i64)
 
 DEF_HELPER_FLAGS_2(mte_check, TCG_CALL_NO_WG, i64, env, i64)
 DEF_HELPER_FLAGS_3(irg, TCG_CALL_NO_RWG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_4(addg, TCG_CALL_NO_RWG_SE, i64, env, i64, i32, i32)
+DEF_HELPER_FLAGS_4(subg, TCG_CALL_NO_RWG_SE, i64, env, i64, i32, i32)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 2922324f63..a5a249b001 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1002,4 +1002,7 @@ static inline bool 
allocation_tag_access_enabled(CPUARMState *env, int el,
 return sctlr != 0;
 }
 
+/* We associate one allocation tag per 16 bytes, the minimum.  */
+#define LOG2_TAG_GRANULE 4
+
 #endif
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index 1878393fc4..e2b1a5dd40 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -163,3 +163,37 @@ uint64_t HELPER(irg)(CPUARMState *env, uint64_t rn, 
uint64_t rm)
 }
 return address_with_allocation_tag(rn, rtag);
 }
+
+uint64_t HELPER(addg)(CPUARMState *env, uint64_t ptr,
+  uint32_t offset, uint32_t tag_offset)
+{
+int el = arm_current_el(env);
+uint64_t sctlr = arm_sctlr(env, el);
+int rtag = 0;
+
+if (allocation_tag_access_enabled(env, el, sctlr)) {
+int start_tag = allocation_tag_from_addr(ptr);
+uint16_t exclude = env->cp15.gcr_el1;
+rtag = choose_nonexcluded_tag(start_tag, tag_offset, exclude);
+}
+
+offset <<= LOG2_TAG_GRANULE;
+return address_with_allocation_tag(ptr + offset, rtag);
+}
+
+uint64_t HELPER(subg)(CPUARMState *env, uint64_t ptr,
+  uint32_t offset, uint32_t tag_offset)
+{
+int el = arm_current_el(env);
+uint64_t sctlr = arm_sctlr(env, el);
+int rtag = 0;
+
+if (allocation_tag_access_enabled(env, el, sctlr)) {
+int start_tag = allocation_tag_from_addr(ptr);
+uint16_t exclude = env->cp15.gcr_el1;
+rtag = choose_nonexcluded_tag(start_tag, tag_offset, exclude);
+}
+
+offset <<= LOG2_TAG_GRANULE;
+return address_with_allocation_tag(ptr - offset, rtag);
+}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index b0349bffc4..879d6b8d46 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -3652,7 +3652,9 @@ static void disas_pc_rel_adr(DisasContext *s, uint32_t 
insn)
  *sf: 0 -> 32bit, 1 -> 64bit
  *op: 0 -> add  , 1 -> sub
  * S: 1 -> set flags
- * shift: 00 -> LSL imm by 0, 01 -> LSL imm by 12
+ * shift: 00 -> LSL imm by 0,
+ *01 -> LSL imm by 12
+ *10 -> ADDG, SUBG
  */
 static void disas_add_sub_imm(DisasContext *s, uint32_t insn)
 {
@@ -3663,10 +3665,10 @@ static void disas_add_sub_imm(DisasContext *s, uint32_t 
insn)
 bool setflags = extract32(insn, 29, 1);
 bool sub_op = extract32(insn, 30, 1);
 bool is_64bit = extract32(insn, 31, 1);
+bool is_tag = false;
 
 TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
 TCGv_i64 tcg_rd = setflags ? cpu_reg(s, rd) : cpu_reg_sp(s, rd);
-TCGv_i64 tcg_result;
 
 switch (shift) {
 case 0x0:
@@ -3674,35 +3676,58 @@ static void disas_add_sub_imm(DisasContext *s, uint32_t 
insn)
 case 0x1:
 imm <<= 12;
 break;
+case 0x2:
+/* ADDG, SUBG */
+if (!is_64bit || setflags || (imm & 0x30) ||
+!dc_isar_feature(aa64_mte_insn_reg, s)) {
+goto do_unallocated;
+}
+is_tag = true;
+break;
 default:
+do_unallocated:
 unallocated_encoding(s);
 return;
 }
 
-tcg_result = tcg_temp_new_i64();
-if (!setflags) {
-if (sub_op) {
-tcg_gen_subi_i64(tcg_result, tcg_rn, imm);
-} else {
-tcg_gen_addi_i64(tcg_result, tcg_rn, imm);
-}
-} else {
-TCGv_i64 tcg_imm = tcg_const_i64(imm);
-if (sub_op) {
-gen_sub_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
-} else {
-gen_add_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
-}
-tcg_temp_free_i64(tcg_imm);
-}
+if (is_tag) {
+TCGv_i32 tag_offset = tcg_const_i32(imm & 15);
+TCGv_i32 offset = tcg_const_i32(imm >> 6);
 
-if (is_64bit) {
-tcg_gen_mov_i64(tcg_rd, tcg_result);
+if (sub_op) {
+gen_helper_subg(tcg_rd, cpu_env, tcg_rn, offset, tag_offset);
+} else {
+gen_helper_addg(tcg_rd, cpu_env, tcg_rn, offset, tag_offset);
+}
+

[Qemu-devel] [PATCH 16/17] target/arm: Enable MTE

2019-01-13 Thread Richard Henderson
??? It does not yet work for system mode.

Signed-off-by: Richard Henderson 
---
 target/arm/cpu.c   | 10 ++
 target/arm/cpu64.c |  1 +
 2 files changed, 11 insertions(+)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 5eff6995ee..aae30207b9 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -180,6 +180,16 @@ static void arm_cpu_reset(CPUState *s)
  * make no difference to the user-level emulation.
  */
 env->cp15.tcr_el[1].raw_tcr = (3ULL << 37);
+/* Enable MTE allocation tags.  */
+env->cp15.hcr_el2 |= HCR_ATA;
+env->cp15.scr_el3 |= SCR_ATA;
+env->cp15.sctlr_el[1] |= SCTLR_ATA0;
+/* Enable synchronous tag check failures.  */
+env->cp15.sctlr_el[1] |= 1ull << 38;
+#ifdef TARGET_AARCH64
+/* Set MTE seed to non-zero value, otherwise RandomTag fails.  */
+env->cp15.rgsr_el1 = 0x123400;
+#endif
 #else
 /* Reset into the highest available EL */
 if (arm_feature(env, ARM_FEATURE_EL3)) {
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 64fbe75eca..49fdad69ce 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -374,6 +374,7 @@ static void aarch64_max_initfn(Object *obj)
 
 t = cpu->isar.id_aa64pfr1;
 t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
+t = FIELD_DP64(t, ID_AA64PFR1, MTE, 2);
 cpu->isar.id_aa64pfr1 = t;
 
 t = cpu->isar.id_aa64mmfr1;
-- 
2.17.2




[Qemu-devel] [PATCH 13/17] target/arm: Set PSTATE.TCO on exception entry

2019-01-13 Thread Richard Henderson
R0085 specifies that exception handlers begin with tag checks overridden.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index df43deb0f8..1e9ccf0b2e 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8830,7 +8830,7 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
 qemu_log_mask(CPU_LOG_INT, "...with ELR 0x%" PRIx64 "\n",
   env->elr_el[new_el]);
 
-pstate_write(env, PSTATE_DAIF | new_mode);
+pstate_write(env, PSTATE_DAIF | PSTATE_TCO | new_mode);
 env->aarch64 = 1;
 aarch64_restore_sp(env, new_el);
 
-- 
2.17.2




Re: [Qemu-devel] [PATCH qemu v2] hmp: Print if memory section is registered with an accelerator

2019-01-13 Thread Alexey Kardashevskiy



On 04/01/2019 04:37, Dr. David Alan Gilbert wrote:
> * Alexey Kardashevskiy (a...@ozlabs.ru) wrote:
>>
>>
>> On 17/12/2018 23:47, Philippe Mathieu-Daudé wrote:
>>> On 12/17/18 2:27 AM, Alexey Kardashevskiy wrote:
 On 14/12/2018 22:07, Philippe Mathieu-Daudé wrote:
> Hi Alexey,
>
> On 12/14/18 3:58 AM, Alexey Kardashevskiy wrote:
>> This adds an accelerator name to the "into mtree -f" to tell the user if
>> a particular memory section is registered with the accelerator;
>> the primary user for this is KVM and such information is useful
>> for debugging purposes.
>>
>> This adds a has_memory() callback to the accelerator class allowing any
>> accelerator to have a label in that memory tree dump.
>>
>> Since memory sections are passed to memory listeners and get registered
>> in accelerators (rather than memory regions), this only prints new labels
>> for flatviews attached to the system address space.
>>
>> An example:
>>  Root memory region: system
>>   -002f (prio 0, ram): /objects/mem0 kvm
>>   0030-005f (prio 0, ram): /objects/mem1 kvm
>>   2020-203f (prio 1, i/o): virtio-pci
>>   20008000-2000803f (prio 0, i/o): capabilities
>>
>> Signed-off-by: Alexey Kardashevskiy 
>> ---
>>
>> This supercedes "[PATCH qemu] hmp: Print if memory section is registered 
>> in KVM"
>>
>> ---
>> Changes:
>> v2:
>> * added an accelerator callback instead of hardcoding it to kvm only
>> ---
>>  include/sysemu/accel.h |  2 ++
>>  accel/kvm/kvm-all.c| 10 ++
>>  memory.c   | 22 ++
>>  3 files changed, 34 insertions(+)
>>
>> diff --git a/include/sysemu/accel.h b/include/sysemu/accel.h
>> index 637358f..30b456d 100644
>> --- a/include/sysemu/accel.h
>> +++ b/include/sysemu/accel.h
>> @@ -25,6 +25,7 @@
>>  
>>  #include "qom/object.h"
>>  #include "hw/qdev-properties.h"
>> +#include "exec/hwaddr.h"
>>  
>>  typedef struct AccelState {
>>  /*< private >*/
>> @@ -41,6 +42,7 @@ typedef struct AccelClass {
>>  int (*available)(void);
>>  int (*init_machine)(MachineState *ms);
>>  void (*setup_post)(MachineState *ms, AccelState *accel);
>> +bool (*has_memory)(MachineState *ms, hwaddr start_addr, hwaddr 
>> size);
>>  bool *allowed;
>>  /*
>>   * Array of global properties that would be applied when specific
>> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
>> index 4880a05..634f386 100644
>> --- a/accel/kvm/kvm-all.c
>> +++ b/accel/kvm/kvm-all.c
>> @@ -2589,11 +2589,21 @@ int kvm_get_one_reg(CPUState *cs, uint64_t id, 
>> void *target)
>>  return r;
>>  }
>>  
>> +static bool kvm_accel_has_memory(MachineState *ms, hwaddr start_addr,
>> + hwaddr size)
>> +{
>> +KVMState *kvm = KVM_STATE(ms->accelerator);
>> +KVMMemoryListener *kml = >memory_listener;
>> +
>> +return NULL != kvm_lookup_matching_slot(kml, start_addr, size);
>> +}
>> +
>>  static void kvm_accel_class_init(ObjectClass *oc, void *data)
>>  {
>>  AccelClass *ac = ACCEL_CLASS(oc);
>>  ac->name = "KVM";
>>  ac->init_machine = kvm_init;
>> +ac->has_memory = kvm_accel_has_memory;
>>  ac->allowed = _allowed;
>>  }
>>  
>> diff --git a/memory.c b/memory.c
>> index d14c6de..61e758a 100644
>> --- a/memory.c
>> +++ b/memory.c
>> @@ -29,7 +29,9 @@
>>  #include "exec/ram_addr.h"
>>  #include "sysemu/kvm.h"
>>  #include "sysemu/sysemu.h"
>> +#include "sysemu/accel.h"
>>  #include "hw/qdev-properties.h"
>> +#include "hw/boards.h"
>>  #include "migration/vmstate.h"
>>  
>>  //#define DEBUG_UNASSIGNED
>> @@ -2924,6 +2926,8 @@ struct FlatViewInfo {
>>  int counter;
>>  bool dispatch_tree;
>>  bool owner;
>> +AccelClass *ac;
>> +const char *ac_name;
>>  };
>>  
>>  static void mtree_print_flatview(gpointer key, gpointer value,
>> @@ -2939,6 +2943,7 @@ static void mtree_print_flatview(gpointer key, 
>> gpointer value,
>>  int n = view->nr;
>>  int i;
>>  AddressSpace *as;
>> +bool system_as = false;
>>  
>>  p(f, "FlatView #%d\n", fvi->counter);
>>  ++fvi->counter;
>> @@ -2950,6 +2955,9 @@ static void mtree_print_flatview(gpointer key, 
>> gpointer value,
>>  p(f, ", alias %s", memory_region_name(as->root->alias));
>>  }
>>  p(f, "\n");
>> +if (as == _space_memory) {
>> +system_as = true;
>> +}
>>  }
>>  
>>  p(f, " Root memory 

[Qemu-devel] [PULL 06/65] slirp: rename /extra/chardev

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Now it's only used for the chardev pointer.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.c| 4 ++--
 slirp/socket.h   | 2 +-
 slirp/tcp_subr.c | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/slirp/slirp.c b/slirp/slirp.c
index fac7849195..ab08694e37 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -1088,10 +1088,10 @@ int slirp_add_exec(Slirp *slirp, void *chardev, const 
char *cmdline,
 
 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
 {
-if (so->s == -1 && so->extra) {
+if (so->s == -1 && so->chardev) {
 /* XXX this blocks entire thread. Rewrite to use
  * qemu_chr_fe_write and background I/O callbacks */
-qemu_chr_fe_write_all(so->extra, buf, len);
+qemu_chr_fe_write_all(so->chardev, buf, len);
 return len;
 }
 
diff --git a/slirp/socket.h b/slirp/socket.h
index 2f224bc34f..930ed95972 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -67,7 +67,7 @@ struct socket {
 
   struct sbuf so_rcv;  /* Receive buffer */
   struct sbuf so_snd;  /* Send buffer */
-  void * extra;/* Extra pointer */
+  void * chardev;
 };
 
 
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index fd7521854e..4b40850c7a 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -961,7 +961,7 @@ int tcp_ctl(struct socket *so)
 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
 if (ex_ptr->ex_chardev) {
 so->s = -1;
-so->extra = ex_ptr->ex_chardev;
+so->chardev = ex_ptr->ex_chardev;
 return 1;
 }
 DEBUG_MISC((dfd, " executing %s\n", ex_ptr->ex_exec));
-- 
2.20.1




[Qemu-devel] [PULL 03/65] slirp: replace ex_pty with ex_chardev

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

do_pty == 3 means to talk to a chardev.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/misc.c | 2 +-
 slirp/misc.h | 2 +-
 slirp/slirp.c| 4 ++--
 slirp/tcp_subr.c | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/slirp/misc.c b/slirp/misc.c
index e69d5f42c3..8f0b6004bd 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -53,7 +53,7 @@ int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec,
*ex_ptr = g_new(struct ex_list, 1);
(*ex_ptr)->ex_fport = port;
(*ex_ptr)->ex_addr = addr;
-   (*ex_ptr)->ex_pty = do_pty;
+   (*ex_ptr)->ex_chardev = do_pty == 3;
(*ex_ptr)->ex_exec = (do_pty == 3) ? exec : g_strdup(exec);
(*ex_ptr)->ex_next = tmp_ptr;
return 0;
diff --git a/slirp/misc.h b/slirp/misc.h
index 897650aea1..1f8d11def6 100644
--- a/slirp/misc.h
+++ b/slirp/misc.h
@@ -9,7 +9,7 @@
 #define MISC_H
 
 struct ex_list {
-   int ex_pty; /* Do we want a pty? */
+   int ex_chardev;
struct in_addr ex_addr; /* Server address */
int ex_fport;   /* Port to telnet to */
const char *ex_exec;/* Command line of what to exec */
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 4d4c2c13b5..0498a092b9 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -1455,7 +1455,7 @@ static void slirp_state_save(QEMUFile *f, void *opaque)
 struct ex_list *ex_ptr;
 
 for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
-if (ex_ptr->ex_pty == 3) {
+if (ex_ptr->ex_chardev) {
 struct socket *so;
 so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
ntohs(ex_ptr->ex_fport));
@@ -1490,7 +1490,7 @@ static int slirp_state_load(QEMUFile *f, void *opaque, 
int version_id)
 return -EINVAL;
 }
 for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
-if (ex_ptr->ex_pty == 3 &&
+if (ex_ptr->ex_chardev &&
 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
 so->so_fport == ex_ptr->ex_fport) {
 break;
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 0ccd8e1a96..dc19eea55a 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -960,7 +960,7 @@ int tcp_ctl(struct socket *so)
 for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
 if (ex_ptr->ex_fport == so->so_fport &&
 so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
-if (ex_ptr->ex_pty == 3) {
+if (ex_ptr->ex_chardev) {
 so->s = -1;
 so->extra = (void *)ex_ptr->ex_exec;
 return 1;
-- 
2.20.1




[Qemu-devel] [PULL 09/65] slirp: fix slirp_add_exec() leaks

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Free the list elements allocated in add_exec().

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/misc.h  | 2 +-
 slirp/slirp.c | 8 
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/slirp/misc.h b/slirp/misc.h
index 94829722cd..0bc5e74bc5 100644
--- a/slirp/misc.h
+++ b/slirp/misc.h
@@ -12,7 +12,7 @@ struct ex_list {
void *ex_chardev;
struct in_addr ex_addr; /* Server address */
int ex_fport;   /* Port to telnet to */
-   const char *ex_exec;/* Command line of what to exec */
+   char *ex_exec;  /* Command line of what to exec */
struct ex_list *ex_next;
 };
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index ab08694e37..1627436e7d 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -342,6 +342,14 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct 
in_addr vnetwork,
 
 void slirp_cleanup(Slirp *slirp)
 {
+struct ex_list *e, *next;
+
+for (e = slirp->exec_list; e; e = next) {
+next = e->ex_next;
+g_free(e->ex_exec);
+g_free(e);
+}
+
 QTAILQ_REMOVE(_instances, slirp, entry);
 
 unregister_savevm(NULL, "slirp", slirp);
-- 
2.20.1




[Qemu-devel] [PULL 17/65] slirp: remove FULL_BOLT

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Looking at git history, this looks like something from the past, when
there was a tty layer. Let's remove it.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/if.c   | 2 --
 slirp/slirp_config.h | 7 ---
 2 files changed, 9 deletions(-)

diff --git a/slirp/if.c b/slirp/if.c
index 590753c658..aa88cc4e76 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -131,12 +131,10 @@ diddit:
}
}
 
-#ifndef FULL_BOLT
/*
 * This prevents us from malloc()ing too many mbufs
 */
if_start(ifm->slirp);
-#endif
 }
 
 /*
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index 721667e3ef..f0cc1c781b 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -5,13 +5,6 @@
 /* Define to 1 if you want KEEPALIVE timers */
 #define DO_KEEPALIVE 0
 
-/* Define this if you want slirp to write to the tty as fast as it can */
-/* This should only be set if you are using load-balancing, slirp does a */
-/* pretty good job on single modems already, and seting this will make */
-/* interactive sessions less responsive */
-/* X Talk about having fast modem as unit 0 */
-#undef FULL_BOLT
-
 /*/
 /*
  * Autoconf defined configuration options
-- 
2.20.1




[Qemu-devel] [PULL 18/65] slirp: remove the disabled readv()/writev() code path

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

The soread() function may be used on datagram sockets, and would
provide different behaviour if HAVE_READV was set, on empty datagrams.
This looks like a minor optimization, that never has been a strong
goal for slirp.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp_config.h |  3 ---
 slirp/socket.c   | 15 ---
 2 files changed, 18 deletions(-)

diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index f0cc1c781b..3ce64e088e 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -29,9 +29,6 @@
 /* Define if the machine is big endian */
 //#undef HOST_WORDS_BIGENDIAN
 
-/* Define if you have readv */
-#undef HAVE_READV
-
 /* Define if iovec needs to be declared */
 #undef DECLARE_IOVEC
 #ifdef _WIN32
diff --git a/slirp/socket.c b/slirp/socket.c
index 041ec5061a..7012c7c07d 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -187,12 +187,7 @@ soread(struct socket *so)
 */
sopreprbuf(so, iov, );
 
-#ifdef HAVE_READV
-   nn = readv(so->s, (struct iovec *)iov, n);
-   DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
-#else
nn = qemu_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
-#endif
if (nn <= 0) {
if (nn < 0 && (errno == EINTR || errno == EAGAIN))
return 0;
@@ -226,7 +221,6 @@ soread(struct socket *so)
}
}
 
-#ifndef HAVE_READV
/*
 * If there was no error, try and read the second time round
 * We read again if n = 2 (ie, there's another part of the buffer)
@@ -244,7 +238,6 @@ soread(struct socket *so)
 }
 
DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
-#endif
 
/* Update fields */
sb->sb_cc += nn;
@@ -452,13 +445,7 @@ sowrite(struct socket *so)
}
/* Check if there's urgent data to send, and if so, send it */
 
-#ifdef HAVE_READV
-   nn = writev(so->s, (const struct iovec *)iov, n);
-
-   DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
-#else
nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len,0);
-#endif
/* This should never happen, but people tell me it does *shrug* */
if (nn < 0 && (errno == EAGAIN || errno == EINTR))
return 0;
@@ -467,7 +454,6 @@ sowrite(struct socket *so)
goto err_disconnected;
}
 
-#ifndef HAVE_READV
if (n == 2 && nn == iov[0].iov_len) {
 int ret;
 ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len,0);
@@ -475,7 +461,6 @@ sowrite(struct socket *so)
 nn += ret;
 }
 DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
-#endif
 
/* Update sbuf */
sb->sb_cc -= nn;
-- 
2.20.1




[Qemu-devel] [PULL 04/65] slirp: use a dedicated field for chardev pointer

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Let's not mix command line and chardev pointers.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c  |  8 
 slirp/libslirp.h |  2 +-
 slirp/misc.c | 11 +++
 slirp/misc.h |  4 ++--
 slirp/slirp.c|  5 +++--
 slirp/tcp_subr.c |  2 +-
 6 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index dd06b0189e..58d880de8d 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -709,8 +709,8 @@ static int slirp_smb(SlirpState* s, const char 
*exported_dir,
  CONFIG_SMBD_COMMAND, s->smb_dir, smb_conf);
 g_free(smb_conf);
 
-if (slirp_add_exec(s->slirp, 0, smb_cmdline, _addr, 139) < 0 ||
-slirp_add_exec(s->slirp, 0, smb_cmdline, _addr, 445) < 0) {
+if (slirp_add_exec(s->slirp, NULL, smb_cmdline, _addr, 139) < 0 ||
+slirp_add_exec(s->slirp, NULL, smb_cmdline, _addr, 445) < 0) {
 slirp_smb_cleanup(s);
 g_free(smb_cmdline);
 error_setg(errp, "Conflicting/invalid smbserver address");
@@ -774,7 +774,7 @@ static int slirp_guestfwd(SlirpState *s, const char 
*config_str, Error **errp)
 snprintf(buf, sizeof(buf), "guestfwd.tcp.%d", port);
 
 if ((strlen(p) > 4) && !strncmp(p, "cmd:", 4)) {
-if (slirp_add_exec(s->slirp, 0, [4], , port) < 0) {
+if (slirp_add_exec(s->slirp, NULL, [4], , port) < 0) {
 error_setg(errp, "Conflicting/invalid host:port in guest "
"forwarding rule '%s'", config_str);
 return -1;
@@ -801,7 +801,7 @@ static int slirp_guestfwd(SlirpState *s, const char 
*config_str, Error **errp)
 return -1;
 }
 
-if (slirp_add_exec(s->slirp, 3, >hd, , port) < 0) {
+if (slirp_add_exec(s->slirp, >hd, NULL, , port) < 0) {
 error_setg(errp, "Conflicting/invalid host:port in guest "
"forwarding rule '%s'", config_str);
 g_free(fwd);
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 52dbb9feb5..3e88dbaa01 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -35,7 +35,7 @@ int slirp_add_hostfwd(Slirp *slirp, int is_udp,
   struct in_addr guest_addr, int guest_port);
 int slirp_remove_hostfwd(Slirp *slirp, int is_udp,
  struct in_addr host_addr, int host_port);
-int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
+int slirp_add_exec(Slirp *slirp, void *chardev, const char *cmdline,
struct in_addr *guest_addr, int guest_port);
 
 void slirp_connection_info(Slirp *slirp, Monitor *mon);
diff --git a/slirp/misc.c b/slirp/misc.c
index 8f0b6004bd..2784fc420f 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -37,7 +37,7 @@ remque(void *a)
   element->qh_rlink = NULL;
 }
 
-int add_exec(struct ex_list **ex_ptr, int do_pty, char *exec,
+int add_exec(struct ex_list **ex_ptr, void *chardev, const char *cmdline,
  struct in_addr addr, int port)
 {
struct ex_list *tmp_ptr;
@@ -50,11 +50,14 @@ int add_exec(struct ex_list **ex_ptr, int do_pty, char 
*exec,
}
 
tmp_ptr = *ex_ptr;
-   *ex_ptr = g_new(struct ex_list, 1);
+   *ex_ptr = g_new0(struct ex_list, 1);
(*ex_ptr)->ex_fport = port;
(*ex_ptr)->ex_addr = addr;
-   (*ex_ptr)->ex_chardev = do_pty == 3;
-   (*ex_ptr)->ex_exec = (do_pty == 3) ? exec : g_strdup(exec);
+   if (chardev) {
+   (*ex_ptr)->ex_chardev = chardev;
+   } else {
+   (*ex_ptr)->ex_exec = g_strdup(cmdline);
+   }
(*ex_ptr)->ex_next = tmp_ptr;
return 0;
 }
diff --git a/slirp/misc.h b/slirp/misc.h
index 1f8d11def6..64ca88c3b7 100644
--- a/slirp/misc.h
+++ b/slirp/misc.h
@@ -9,7 +9,7 @@
 #define MISC_H
 
 struct ex_list {
-   int ex_chardev;
+   void *ex_chardev;
struct in_addr ex_addr; /* Server address */
int ex_fport;   /* Port to telnet to */
const char *ex_exec;/* Command line of what to exec */
@@ -52,7 +52,7 @@ struct slirp_quehead {
 
 void slirp_insque(void *, void *);
 void slirp_remque(void *);
-int add_exec(struct ex_list **, int, char *, struct in_addr, int);
+int add_exec(struct ex_list **, void *, const char *, struct in_addr, int);
 int fork_exec(struct socket *so, const char *ex);
 
 #endif
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 0498a092b9..0de46084c0 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -1068,7 +1068,7 @@ int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct 
in_addr host_addr,
 return 0;
 }
 
-int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
+int slirp_add_exec(Slirp *slirp, void *chardev, const char *cmdline,
struct in_addr *guest_addr, int guest_port)
 {
 if (!guest_addr->s_addr) {
@@ -1081,7 +1081,8 @@ int slirp_add_exec(Slirp *slirp, int do_pty, const void 
*args,
 guest_addr->s_addr == slirp->vnameserver_addr.s_addr) {
 return 

[Qemu-devel] [PULL 32/65] slirp: replace compile time DO_KEEPALIVE

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Use a global variable instead (similar to slirp_debug)

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.c|  3 +++
 slirp/slirp.h|  6 +++---
 slirp/slirp_config.h | 12 
 slirp/tcp_input.c|  2 +-
 slirp/tcp_timer.c|  2 +-
 5 files changed, 8 insertions(+), 17 deletions(-)
 delete mode 100644 slirp/slirp_config.h

diff --git a/slirp/slirp.c b/slirp/slirp.c
index 76e94eb1cd..f11f9e9e51 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -35,6 +35,9 @@
 #include 
 #endif
 
+/* Define to 1 if you want KEEPALIVE timers */
+bool slirp_do_keepalive;
+
 /* host loopback address */
 struct in_addr loopback_addr;
 /* host loopback network mask */
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 4a046e..05c203c8c7 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -1,8 +1,6 @@
 #ifndef SLIRP_H
 #define SLIRP_H
 
-#include "slirp_config.h"
-
 #ifdef _WIN32
 
 typedef char *caddr_t;
@@ -219,7 +217,9 @@ void ncsi_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len);
 #include 
 #endif
 
-#define SO_OPTIONS DO_KEEPALIVE
+
+extern bool slirp_do_keepalive;
+
 #define TCP_MAXIDLE (TCPTV_KEEPCNT * TCPTV_KEEPINTVL)
 
 /* dnssearch.c */
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
deleted file mode 100644
index 7147e0de04..00
--- a/slirp/slirp_config.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * User definable configuration options
- */
-
-/* Define to 1 if you want KEEPALIVE timers */
-#define DO_KEEPALIVE 0
-
-/*/
-/*
- * Autoconf defined configuration options
- * You shouldn't need to touch any of these
- */
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 09bdf9b482..6af63469da 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -481,7 +481,7 @@ findso:
 * Reset idle time and keep-alive timer.
 */
tp->t_idle = 0;
-   if (SO_OPTIONS)
+   if (slirp_do_keepalive)
   tp->t_timer[TCPT_KEEP] = TCPTV_KEEPINTVL;
else
   tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_IDLE;
diff --git a/slirp/tcp_timer.c b/slirp/tcp_timer.c
index dc8288b511..a843e57a2b 100644
--- a/slirp/tcp_timer.c
+++ b/slirp/tcp_timer.c
@@ -262,7 +262,7 @@ tcp_timers(register struct tcpcb *tp, int timer)
if (tp->t_state < TCPS_ESTABLISHED)
goto dropit;
 
-   if ((SO_OPTIONS) && tp->t_state <= TCPS_CLOSE_WAIT) {
+   if (slirp_do_keepalive && tp->t_state <= TCPS_CLOSE_WAIT) {
if (tp->t_idle >= TCPTV_KEEP_IDLE + TCP_MAXIDLE)
goto dropit;
/*
-- 
2.20.1




[Qemu-devel] [PULL 19/65] slirp: remove HAVE_SYS_SIGNAL_H

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.h| 3 ---
 slirp/slirp_config.h | 3 ---
 2 files changed, 6 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index f7c087456a..4c3c672ee6 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -35,9 +35,6 @@ typedef char *caddr_t;
 #ifndef NO_UNIX_SOCKETS
 #include 
 #endif
-#ifdef HAVE_SYS_SIGNAL_H
-# include 
-#endif
 #ifndef _WIN32
 #include 
 #endif
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index 3ce64e088e..2605c4222b 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -50,9 +50,6 @@
 #define HAVE_ARPA_INET_H
 #endif
 
-/* Define if you have sys/signal.h */
-#undef HAVE_SYS_SIGNAL_H
-
 /* Define if you have sys/stropts.h */
 #undef HAVE_SYS_STROPTS_H
 
-- 
2.20.1




[Qemu-devel] [PULL 20/65] slirp: remove unused HAVE_SYS_BITYPES_H

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.h| 4 
 slirp/slirp_config.h | 3 ---
 2 files changed, 7 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 4c3c672ee6..57955a8965 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -19,10 +19,6 @@ typedef char *caddr_t;
 # endif
 #endif
 
-#ifdef HAVE_SYS_BITYPES_H
-# include 
-#endif
-
 #ifndef _WIN32
 #include 
 #endif
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index 2605c4222b..a205dc8c28 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -23,9 +23,6 @@
 #define HAVE_SYS_FILIO_H
 #endif
 
-/* Define if you have sys/bitypes.h */
-#undef HAVE_SYS_BITYPES_H
-
 /* Define if the machine is big endian */
 //#undef HOST_WORDS_BIGENDIAN
 
-- 
2.20.1




[Qemu-devel] [PULL 08/65] slirp: remove Monitor dependency, return a string for info

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

There is nothing performance-sensitive in returning an allocated
string for info, and handling the monitor_printf() on the caller side.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c  |  7 ---
 slirp/libslirp.h |  2 +-
 slirp/misc.c | 23 +--
 3 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index 58d880de8d..b7319ca6b2 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -828,10 +828,11 @@ void hmp_info_usernet(Monitor *mon, const QDict *qdict)
 QTAILQ_FOREACH(s, _stacks, entry) {
 int id;
 bool got_hub_id = net_hub_id_for_client(>nc, ) == 0;
-monitor_printf(mon, "Hub %d (%s):\n",
+char *info = slirp_connection_info(s->slirp);
+monitor_printf(mon, "Hub %d (%s):\n%s",
got_hub_id ? id : -1,
-   s->nc.name);
-slirp_connection_info(s->slirp, mon);
+   s->nc.name, info);
+g_free(info);
 }
 }
 
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index a4f390ee89..04b6db9f49 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -35,7 +35,7 @@ int slirp_remove_hostfwd(Slirp *slirp, int is_udp,
 int slirp_add_exec(Slirp *slirp, void *chardev, const char *cmdline,
struct in_addr *guest_addr, int guest_port);
 
-void slirp_connection_info(Slirp *slirp, Monitor *mon);
+char *slirp_connection_info(Slirp *slirp);
 
 void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr,
int guest_port, const uint8_t *buf, int size);
diff --git a/slirp/misc.c b/slirp/misc.c
index 2784fc420f..ce323ef92e 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -8,7 +8,6 @@
 #include "qemu/osdep.h"
 #include "slirp.h"
 #include "libslirp.h"
-#include "monitor/monitor.h"
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
 
@@ -198,8 +197,9 @@ fork_exec(struct socket *so, const char *ex)
 }
 #endif
 
-void slirp_connection_info(Slirp *slirp, Monitor *mon)
+char *slirp_connection_info(Slirp *slirp)
 {
+GString *str = g_string_new(NULL);
 const char * const tcpstates[] = {
 [TCPS_CLOSED]   = "CLOSED",
 [TCPS_LISTEN]   = "LISTEN",
@@ -221,8 +221,9 @@ void slirp_connection_info(Slirp *slirp, Monitor *mon)
 const char *state;
 char buf[20];
 
-monitor_printf(mon, "  Protocol[State]FD  Source Address  Port   "
-"Dest. Address  Port RecvQ SendQ\n");
+g_string_append_printf(str,
+"  Protocol[State]FD  Source Address  Port   "
+"Dest. Address  Port RecvQ SendQ\n");
 
 for (so = slirp->tcb.so_next; so != >tcb; so = so->so_next) {
 if (so->so_state & SS_HOSTFWD) {
@@ -244,10 +245,10 @@ void slirp_connection_info(Slirp *slirp, Monitor *mon)
 dst_port = so->so_fport;
 }
 snprintf(buf, sizeof(buf), "  TCP[%s]", state);
-monitor_printf(mon, "%-19s %3d %15s %5d ", buf, so->s,
+g_string_append_printf(str, "%-19s %3d %15s %5d ", buf, so->s,
src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
ntohs(src.sin_port));
-monitor_printf(mon, "%15s %5d %5d %5d\n",
+g_string_append_printf(str, "%15s %5d %5d %5d\n",
inet_ntoa(dst_addr), ntohs(dst_port),
so->so_rcv.sb_cc, so->so_snd.sb_cc);
 }
@@ -267,10 +268,10 @@ void slirp_connection_info(Slirp *slirp, Monitor *mon)
 dst_addr = so->so_faddr;
 dst_port = so->so_fport;
 }
-monitor_printf(mon, "%-19s %3d %15s %5d ", buf, so->s,
+g_string_append_printf(str, "%-19s %3d %15s %5d ", buf, so->s,
src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
ntohs(src.sin_port));
-monitor_printf(mon, "%15s %5d %5d %5d\n",
+g_string_append_printf(str, "%15s %5d %5d %5d\n",
inet_ntoa(dst_addr), ntohs(dst_port),
so->so_rcv.sb_cc, so->so_snd.sb_cc);
 }
@@ -280,9 +281,11 @@ void slirp_connection_info(Slirp *slirp, Monitor *mon)
  (so->so_expire - curtime) / 1000);
 src.sin_addr = so->so_laddr;
 dst_addr = so->so_faddr;
-monitor_printf(mon, "%-19s %3d %15s  -", buf, so->s,
+g_string_append_printf(str, "%-19s %3d %15s  -", buf, so->s,
src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*");
-monitor_printf(mon, "%15s  -%5d %5d\n", inet_ntoa(dst_addr),
+g_string_append_printf(str, "%15s  -%5d %5d\n", 
inet_ntoa(dst_addr),
so->so_rcv.sb_cc, so->so_snd.sb_cc);
 }
+
+return g_string_free(str, FALSE);
 }
-- 
2.20.1




[Qemu-devel] [PULL 24/65] slirp: remove unused HAVE_SYS_WAIT_H

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.h| 4 
 slirp/slirp_config.h | 3 ---
 2 files changed, 7 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 400f585cec..1f47848271 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -40,10 +40,6 @@ typedef char *caddr_t;
 # include 
 #endif
 
-#ifdef HAVE_SYS_WAIT_H
-# include 
-#endif
-
 #ifdef HAVE_SYS_FILIO_H
 # include 
 #endif
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index e95284071a..9becb98e11 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -32,9 +32,6 @@
 #define DECLARE_IOVEC
 #endif
 
-/* Define if you have a POSIX.1 sys/wait.h */
-#undef HAVE_SYS_WAIT_H
-
 /* Define if you have sys/select.h */
 #undef HAVE_SYS_SELECT_H
 #ifndef _WIN32
-- 
2.20.1




[Qemu-devel] [PULL 28/65] slirp: remove unused DECLARE_IOVEC

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

It's actually qemu configure CONFIG_IOVEC that is being used.

slirp/ does not use it anyway

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp_config.h | 6 --
 1 file changed, 6 deletions(-)

diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index f1ee927c15..833f25a965 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -14,12 +14,6 @@
 /* Define if the machine is big endian */
 //#undef HOST_WORDS_BIGENDIAN
 
-/* Define if iovec needs to be declared */
-#undef DECLARE_IOVEC
-#ifdef _WIN32
-#define DECLARE_IOVEC
-#endif
-
 /* Define to sizeof(char *) */
 #define SIZEOF_CHAR_P (HOST_LONG_BITS / 8)
 
-- 
2.20.1




[Qemu-devel] [PULL 43/65] glib-compat: add g_spawn_async_with_fds() fallback

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 include/glib-compat.h | 56 +++
 1 file changed, 56 insertions(+)

diff --git a/include/glib-compat.h b/include/glib-compat.h
index fdf95a255d..8a078c5288 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -83,6 +83,62 @@ static inline gboolean g_strv_contains_qemu(const gchar 
*const *strv,
 }
 #define g_strv_contains(a, b) g_strv_contains_qemu(a, b)
 
+#if !GLIB_CHECK_VERSION(2, 58, 0)
+typedef struct QemuGSpawnFds {
+GSpawnChildSetupFunc child_setup;
+gpointer user_data;
+gint stdin_fd;
+gint stdout_fd;
+gint stderr_fd;
+} QemuGSpawnFds;
+
+static inline void
+qemu_gspawn_fds_setup(gpointer user_data)
+{
+QemuGSpawnFds *q = (QemuGSpawnFds *)user_data;
+
+dup2(q->stdin_fd, 0);
+dup2(q->stdout_fd, 1);
+dup2(q->stderr_fd, 2);
+q->child_setup(q->user_data);
+}
+#endif
+
+static inline gboolean
+g_spawn_async_with_fds_qemu(const gchar *working_directory,
+gchar **argv,
+gchar **envp,
+GSpawnFlags flags,
+GSpawnChildSetupFunc child_setup,
+gpointer user_data,
+GPid *child_pid,
+gint stdin_fd,
+gint stdout_fd,
+gint stderr_fd,
+GError **error)
+{
+#if GLIB_CHECK_VERSION(2, 58, 0)
+return g_spawn_async_with_fds(working_directory, argv, envp, flags,
+  child_setup, user_data,
+  child_pid, stdin_fd, stdout_fd, stderr_fd,
+  error);
+#else
+QemuGSpawnFds setup = {
+.child_setup = child_setup,
+.user_data = user_data,
+.stdin_fd = stdin_fd,
+.stdout_fd = stdout_fd,
+.stderr_fd = stderr_fd,
+};
+
+return g_spawn_async(working_directory, argv, envp, flags,
+ qemu_gspawn_fds_setup, ,
+ child_pid, error);
+#endif
+}
+
+#define g_spawn_async_with_fds(wd, argv, env, f, c, d, p, ifd, ofd, efd, err) \
+g_spawn_async_with_fds_qemu(wd, argv, env, f, c, d, p, ifd, ofd, efd, err)
 
 #if defined(_WIN32) && !GLIB_CHECK_VERSION(2, 50, 0)
 /*
-- 
2.20.1




[Qemu-devel] [PULL 26/65] slirp: remove HAVE_SYS_IOCTL_H

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.h| 2 +-
 slirp/slirp_config.h | 6 --
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 7606de962f..226bced429 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -32,7 +32,7 @@ typedef char *caddr_t;
 #include 
 #endif
 
-#if defined(HAVE_SYS_IOCTL_H)
+#ifndef _WIN32
 # include 
 #endif
 
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index 68e75f3873..0e78e92d94 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -11,12 +11,6 @@
  * You shouldn't need to touch any of these
  */
 
-/* Define if you have sys/ioctl.h */
-#undef HAVE_SYS_IOCTL_H
-#ifndef _WIN32
-#define HAVE_SYS_IOCTL_H
-#endif
-
 /* Define if you have sys/filio.h */
 #undef HAVE_SYS_FILIO_H
 #ifdef __APPLE__
-- 
2.20.1




[Qemu-devel] [PULL 41/65] slirp: replace ARRAY_SIZE with G_N_ELEMENTS

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Do not require QEMU macro.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/ncsi.c | 2 +-
 slirp/tftp.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/slirp/ncsi.c b/slirp/ncsi.c
index 10decfb5ef..8594382270 100644
--- a/slirp/ncsi.c
+++ b/slirp/ncsi.c
@@ -128,7 +128,7 @@ void ncsi_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len)
 memset(reh->h_source, 0xff, ETH_ALEN);
 reh->h_proto = htons(ETH_P_NCSI);
 
-for (i = 0; i < ARRAY_SIZE(ncsi_rsp_handlers); i++) {
+for (i = 0; i < G_N_ELEMENTS(ncsi_rsp_handlers); i++) {
 if (ncsi_rsp_handlers[i].type == nh->type + 0x80) {
 handler = _rsp_handlers[i];
 break;
diff --git a/slirp/tftp.c b/slirp/tftp.c
index 735b57aa55..a9ba1480db 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -359,7 +359,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct 
sockaddr_storage *srcsas,
   return;
   }
 
-  while (k < pktlen && nb_options < ARRAY_SIZE(option_name)) {
+  while (k < pktlen && nb_options < G_N_ELEMENTS(option_name)) {
   const char *key, *value;
 
   key = >x.tp_buf[k];
@@ -403,7 +403,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct 
sockaddr_storage *srcsas,
   }
 
   if (nb_options > 0) {
-  assert(nb_options <= ARRAY_SIZE(option_name));
+  assert(nb_options <= G_N_ELEMENTS(option_name));
   tftp_send_oack(spt, option_name, option_value, nb_options, tp);
   return;
   }
-- 
2.20.1




[Qemu-devel] [PULL 37/65] slirp: remove #if notdef dead code

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/ip_input.c  | 200 --
 slirp/tcp_input.c |  39 -
 2 files changed, 239 deletions(-)

diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 094a807d41..d360620838 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -447,206 +447,6 @@ ip_slowtimo(Slirp *slirp)
 }
 }
 
-/*
- * Do option processing on a datagram,
- * possibly discarding it if bad options are encountered,
- * or forwarding it if source-routed.
- * Returns 1 if packet has been forwarded/freed,
- * 0 if the packet should be processed further.
- */
-
-#ifdef notdef
-
-int
-ip_dooptions(m)
-   struct mbuf *m;
-{
-   register struct ip *ip = mtod(m, struct ip *);
-   register u_char *cp;
-   register struct ip_timestamp *ipt;
-   register struct in_ifaddr *ia;
-   int opt, optlen, cnt, off, code, type, forward = 0;
-   struct in_addr *sin, dst;
-typedef uint32_t n_time;
-   n_time ntime;
-
-   dst = ip->ip_dst;
-   cp = (u_char *)(ip + 1);
-   cnt = (ip->ip_hl << 2) - sizeof (struct ip);
-   for (; cnt > 0; cnt -= optlen, cp += optlen) {
-   opt = cp[IPOPT_OPTVAL];
-   if (opt == IPOPT_EOL)
-   break;
-   if (opt == IPOPT_NOP)
-   optlen = 1;
-   else {
-   optlen = cp[IPOPT_OLEN];
-   if (optlen <= 0 || optlen > cnt) {
-   code = [IPOPT_OLEN] - (u_char *)ip;
-   goto bad;
-   }
-   }
-   switch (opt) {
-
-   default:
-   break;
-
-   /*
-* Source routing with record.
-* Find interface with current destination address.
-* If none on this machine then drop if strictly routed,
-* or do nothing if loosely routed.
-* Record interface address and bring up next address
-* component.  If strictly routed make sure next
-* address is on directly accessible net.
-*/
-   case IPOPT_LSRR:
-   case IPOPT_SSRR:
-   if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) {
-   code = [IPOPT_OFFSET] - (u_char *)ip;
-   goto bad;
-   }
-   ipaddr.sin_addr = ip->ip_dst;
-   ia = (struct in_ifaddr *)
-   ifa_ifwithaddr((struct sockaddr *));
-   if (ia == 0) {
-   if (opt == IPOPT_SSRR) {
-   type = ICMP_UNREACH;
-   code = ICMP_UNREACH_SRCFAIL;
-   goto bad;
-   }
-   /*
-* Loose routing, and not at next destination
-* yet; nothing to do except forward.
-*/
-   break;
-   }
-off--; /* 0 origin */
-   if (off > optlen - sizeof(struct in_addr)) {
-   /*
-* End of source route.  Should be for us.
-*/
-   save_rte(cp, ip->ip_src);
-   break;
-   }
-   /*
-* locate outgoing interface
-*/
-   bcopy((caddr_t)(cp + off), (caddr_t)_addr,
-   sizeof(ipaddr.sin_addr));
-   if (opt == IPOPT_SSRR) {
-#defineINA struct in_ifaddr *
-#defineSA  struct sockaddr *
-   if ((ia = (INA)ifa_ifwithdstaddr((SA))) == 0)
-   ia = (INA)ifa_ifwithnet((SA));
-   } else
-   ia = ip_rtaddr(ipaddr.sin_addr);
-   if (ia == 0) {
-   type = ICMP_UNREACH;
-   code = ICMP_UNREACH_SRCFAIL;
-   goto bad;
-   }
-   ip->ip_dst = ipaddr.sin_addr;
-   bcopy((caddr_t)&(IA_SIN(ia)->sin_addr),
-   (caddr_t)(cp + off), sizeof(struct in_addr));
-   cp[IPOPT_OFFSET] += sizeof(struct in_addr);
-   /*
-* Let ip_intr's mcast routing check handle mcast pkts
-*/
-   forward = !IN_MULTICAST(ntohl(ip->ip_dst.s_addr));

[Qemu-devel] [PULL 34/65] slirp: replace error_report() with g_critical()

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Reduce dependency on QEMU. QEMU could use a custom log handler if it
wants to redirect/filter it.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/ip6_icmp.c | 2 +-
 slirp/misc.c | 2 +-
 slirp/slirp.c| 6 +++---
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index cd1e0b9fe1..3c424df591 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -417,7 +417,7 @@ void icmp6_input(struct mbuf *m)
 icmp6_send_echoreply(m, slirp, ip, icmp);
 } else {
 /* TODO */
-error_report("external icmpv6 not supported yet");
+g_critical("external icmpv6 not supported yet");
 }
 break;
 
diff --git a/slirp/misc.c b/slirp/misc.c
index 7362e14339..ee3492a2ae 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -119,7 +119,7 @@ slirp_socketpair_with_oob(int sv[2])
 return 0;
 
 err:
-error_report("Error: slirp_socketpair(): %s", strerror(errno));
+g_critical("slirp_socketpair(): %s", strerror(errno));
 if (s >= 0) {
 closesocket(s);
 }
diff --git a/slirp/slirp.c b/slirp/slirp.c
index f11f9e9e51..8391d18faf 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -1214,8 +1214,8 @@ static int sbuf_tmp_post_load(void *opaque, int version)
 }
 if (tmp->woff >= requested_len ||
 tmp->roff >= requested_len) {
-error_report("invalid sbuf offsets r/w=%u/%u len=%u",
- tmp->roff, tmp->woff, requested_len);
+g_critical("invalid sbuf offsets r/w=%u/%u len=%u",
+   tmp->roff, tmp->woff, requested_len);
 return -EINVAL;
 }
 
@@ -1323,7 +1323,7 @@ static int ss_family_post_load(void *opaque, int 
version_id)
 tss->parent->ss.ss_family = AF_INET6;
 break;
 default:
-error_report("invalid ss_family type %x", tss->portable_family);
+g_critical("invalid ss_family type %x", tss->portable_family);
 return -EINVAL;
 }
 
-- 
2.20.1




[Qemu-devel] [PULL 38/65] slirp: remove unused sbflush()

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/sbuf.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/slirp/sbuf.h b/slirp/sbuf.h
index a722ecb629..644c201341 100644
--- a/slirp/sbuf.h
+++ b/slirp/sbuf.h
@@ -8,7 +8,6 @@
 #ifndef SBUF_H
 #define SBUF_H
 
-#define sbflush(sb) sbdrop((sb),(sb)->sb_cc)
 #define sbspace(sb) ((sb)->sb_datalen - (sb)->sb_cc)
 
 struct sbuf {
-- 
2.20.1




[Qemu-devel] [PULL 33/65] slirp: remove unused global slirp_instance

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 05c203c8c7..d1b6bcefbb 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -199,8 +199,6 @@ struct Slirp {
 void *opaque;
 };
 
-extern Slirp *slirp_instance;
-
 #ifndef NULL
 #define NULL (void *)0
 #endif
-- 
2.20.1




[Qemu-devel] [PULL 44/65] slirp: simplify fork_exec()

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Use g_spawn_async_with_fds() to setup the child.

GSpawn handles reaping the child, and closing parent file descriptors.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/misc.c | 75 +---
 1 file changed, 36 insertions(+), 39 deletions(-)

diff --git a/slirp/misc.c b/slirp/misc.c
index ee3492a2ae..753b3da25b 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -129,56 +129,53 @@ err:
 return -1;
 }
 
+static void
+fork_exec_child_setup(gpointer data)
+{
+setsid();
+}
+
 int
 fork_exec(struct socket *so, const char *ex)
 {
-   char **argv;
-   int opt, c, sp[2];
-   pid_t pid;
+GError *err = NULL;
+char **argv;
+int opt, sp[2];
 
-   DEBUG_CALL("fork_exec");
-   DEBUG_ARG("so = %p", so);
-   DEBUG_ARG("ex = %p", ex);
+DEBUG_CALL("fork_exec");
+DEBUG_ARG("so = %p", so);
+DEBUG_ARG("ex = %p", ex);
 
 if (slirp_socketpair_with_oob(sp) < 0) {
 return 0;
 }
 
-   pid = fork();
-   switch(pid) {
-case -1:
-   error_report("Error: fork failed: %s", strerror(errno));
-   closesocket(sp[0]);
-   closesocket(sp[1]);
-   return 0;
-
-case 0:
-   setsid();
-   dup2(sp[1], 0);
-   dup2(sp[1], 1);
-   dup2(sp[1], 2);
-   for (c = getdtablesize() - 1; c >= 3; c--)
-  close(c);
+argv = g_strsplit(ex, " ", -1);
+g_spawn_async_with_fds(NULL /* cwd */,
+   argv,
+   NULL /* env */,
+   G_SPAWN_SEARCH_PATH,
+   fork_exec_child_setup, NULL /* data */,
+   NULL /* child_pid */,
+   sp[1], sp[1], sp[1],
+   );
+g_strfreev(argv);
 
-argv = g_strsplit(ex, " ", -1);
-   execvp(argv[0], (char **)argv);
-
-   /* Ooops, failed, let's tell the user why */
-fprintf(stderr, "Error: execvp of %s failed: %s\n",
-argv[0], strerror(errno));
-   close(0); close(1); close(2); /* XXX */
-   exit(1);
+if (err) {
+error_report("%s", err->message);
+g_error_free(err);
+closesocket(sp[0]);
+closesocket(sp[1]);
+return 0;
+}
 
-default:
-   so->s = sp[0];
-   closesocket(sp[1]);
-   qemu_add_child_watch(pid);
-   socket_set_fast_reuse(so->s);
-   opt = 1;
-   qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, , 
sizeof(int));
-   qemu_set_nonblock(so->s);
-   return 1;
-   }
+so->s = sp[0];
+closesocket(sp[1]);
+socket_set_fast_reuse(so->s);
+opt = 1;
+qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, , sizeof(int));
+qemu_set_nonblock(so->s);
+return 1;
 }
 #endif
 
-- 
2.20.1




[Qemu-devel] [PULL 35/65] slirp: improve a bit the debug macros

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Let them accept multiple arguments. Simplify the inner argument
handling of DEBUG_ARGS/DEBUG_MISC_DEBUG_ERROR.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/arp_table.c  | 12 ++--
 slirp/bootp.c  |  3 +--
 slirp/cksum.c  |  4 ++--
 slirp/debug.h  | 47 --
 slirp/dhcpv6.c | 11 +--
 slirp/ip6_icmp.c   |  2 +-
 slirp/ip_icmp.c| 18 +-
 slirp/mbuf.c   |  2 +-
 slirp/ndp_table.c  | 18 +-
 slirp/slirp.c  | 12 ++--
 slirp/socket.c | 32 +++
 slirp/tcp_input.c  | 15 +++
 slirp/tcp_output.c |  2 +-
 slirp/tcp_subr.c   |  4 ++--
 slirp/udp.c|  6 +++---
 slirp/udp6.c   |  6 +++---
 16 files changed, 109 insertions(+), 85 deletions(-)

diff --git a/slirp/arp_table.c b/slirp/arp_table.c
index f81963bb88..ce19e6e7c0 100644
--- a/slirp/arp_table.c
+++ b/slirp/arp_table.c
@@ -34,9 +34,9 @@ void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t 
ethaddr[ETH_ALEN])
 
 DEBUG_CALL("arp_table_add");
 DEBUG_ARG("ip = %s", inet_ntoa((struct in_addr){.s_addr = ip_addr}));
-DEBUG_ARGS((dfd, " hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
-ethaddr[0], ethaddr[1], ethaddr[2],
-ethaddr[3], ethaddr[4], ethaddr[5]));
+DEBUG_ARGS(" hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
+   ethaddr[0], ethaddr[1], ethaddr[2],
+   ethaddr[3], ethaddr[4], ethaddr[5]);
 
 if (ip_addr == 0 || ip_addr == 0x || ip_addr == broadcast_addr) {
 /* Do not register broadcast addresses */
@@ -79,9 +79,9 @@ bool arp_table_search(Slirp *slirp, uint32_t ip_addr,
 for (i = 0; i < ARP_TABLE_SIZE; i++) {
 if (arptbl->table[i].ar_sip == ip_addr) {
 memcpy(out_ethaddr, arptbl->table[i].ar_sha,  ETH_ALEN);
-DEBUG_ARGS((dfd, " found hw addr = 
%02x:%02x:%02x:%02x:%02x:%02x\n",
-out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
-out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]));
+DEBUG_ARGS(" found hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
+   out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
+   out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]);
 return 1;
 }
 }
diff --git a/slirp/bootp.c b/slirp/bootp.c
index 7b1af73c95..5ab6692038 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -37,8 +37,7 @@
 static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE };
 
 #ifdef DEBUG
-#define DPRINTF(fmt, ...) \
-do if (slirp_debug & DBG_CALL) { fprintf(dfd, fmt, ##  __VA_ARGS__); 
fflush(dfd); } while (0)
+#define DPRINTF(fmt, ...) DEBUG_CALL(fmt, ##__VA_ARGS__)
 #else
 #define DPRINTF(fmt, ...) do{}while(0)
 #endif
diff --git a/slirp/cksum.c b/slirp/cksum.c
index 6d73abf4a0..b9466485b5 100644
--- a/slirp/cksum.c
+++ b/slirp/cksum.c
@@ -124,8 +124,8 @@ int cksum(struct mbuf *m, int len)
 cont:
 #ifdef DEBUG
if (len) {
-   DEBUG_ERROR((dfd, "cksum: out of data\n"));
-   DEBUG_ERROR((dfd, " len = %d\n", len));
+   DEBUG_ERROR("cksum: out of data\n");
+   DEBUG_ERROR(" len = %d\n", len);
}
 #endif
if (mlen == -1) {
diff --git a/slirp/debug.h b/slirp/debug.h
index 6cfa61edb3..ca3a4b04da 100644
--- a/slirp/debug.h
+++ b/slirp/debug.h
@@ -17,18 +17,45 @@
 
 extern int slirp_debug;
 
-#define DEBUG_CALL(x) if (slirp_debug & DBG_CALL) { fprintf(dfd, "%s...\n", 
x); fflush(dfd); }
-#define DEBUG_ARG(x, y) if (slirp_debug & DBG_CALL) { fputc(' ', dfd); 
fprintf(dfd, x, y); fputc('\n', dfd); fflush(dfd); }
-#define DEBUG_ARGS(x) if (slirp_debug & DBG_CALL) { fprintf x ; fflush(dfd); }
-#define DEBUG_MISC(x) if (slirp_debug & DBG_MISC) { fprintf x ; fflush(dfd); }
-#define DEBUG_ERROR(x) if (slirp_debug & DBG_ERROR) {fprintf x ; fflush(dfd); }
+#define DEBUG_CALL(fmt, ...) do {   \
+if (slirp_debug & DBG_CALL) {   \
+fprintf(dfd, fmt, ##__VA_ARGS__);   \
+fprintf(dfd, "...\n");  \
+fflush(dfd);\
+}   \
+} while (0)
+
+#define DEBUG_ARG(fmt, ...) do {\
+if (slirp_debug & DBG_CALL) {   \
+fputc(' ', dfd);\
+fprintf(dfd, fmt, ##__VA_ARGS__);   \
+fputc('\n', dfd);   \
+fflush(dfd);\
+}   \
+} while (0)
+
+#define DEBUG_ARGS(fmt, ...) DEBUG_ARG(fmt, ##__VA_ARGS__)
+
+#define DEBUG_MISC(fmt, ...) do {   \
+if (slirp_debug & DBG_MISC) {   \
+fprintf(dfd, fmt, ##__VA_ARGS__);   \
+fflush(dfd);\
+}   \
+} while 

[Qemu-devel] [PULL 54/65] slirp: always build with debug statements

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Make debug statements condiitonal only on slirp_debug flags, instead
of the pre-processor DEBUG blocks, as it may introduce breakage
easily, since the debug code isn't always compiled.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/debug.h | 15 +++
 slirp/misc.c  |  6 +-
 2 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/slirp/debug.h b/slirp/debug.h
index ca3a4b04da..ff920f0b87 100644
--- a/slirp/debug.h
+++ b/slirp/debug.h
@@ -5,9 +5,8 @@
  * terms and conditions of the copyright.
  */
 
-//#define DEBUG 1
-
-#ifdef DEBUG
+#ifndef DEBUG_H_
+#define DEBUG_H_
 
 #define DBG_CALL 0x1
 #define DBG_MISC 0x2
@@ -50,12 +49,4 @@ extern int slirp_debug;
 }   \
 } while (0)
 
-#else
-
-#define DEBUG_CALL(fmt, ...)
-#define DEBUG_ARG(fmt, ...)
-#define DEBUG_ARGS(fmt, ...)
-#define DEBUG_MISC(fmt, ...)
-#define DEBUG_ERROR(fmt, ...)
-
-#endif
+#endif /* DEBUG_H_ */
diff --git a/slirp/misc.c b/slirp/misc.c
index 526cefa0f1..e30d2ceb2a 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -12,9 +12,13 @@
 #include "qemu/main-loop.h"
 
 #ifdef DEBUG
-int slirp_debug = DBG_CALL|DBG_MISC|DBG_ERROR;
+#define SLIRP_DEBUG (DBG_CALL | DBG_MISC | DBG_ERROR)
+#else
+#define SLIRP_DEBUG 0
 #endif
 
+int slirp_debug = SLIRP_DEBUG;
+
 inline void
 insque(void *a, void *b)
 {
-- 
2.20.1




[Qemu-devel] [PULL 53/65] slirp: no need to make DPRINTF conditional on DEBUG

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

DEBUG_CALL is already handled conditionally.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/bootp.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/slirp/bootp.c b/slirp/bootp.c
index 5ab6692038..4c9a77eb98 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -36,11 +36,7 @@
 
 static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE };
 
-#ifdef DEBUG
 #define DPRINTF(fmt, ...) DEBUG_CALL(fmt, ##__VA_ARGS__)
-#else
-#define DPRINTF(fmt, ...) do{}while(0)
-#endif
 
 static BOOTPClient *get_new_addr(Slirp *slirp, struct in_addr *paddr,
  const uint8_t *macaddr)
@@ -166,8 +162,9 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t 
*bp)
 DPRINTF("bootp packet op=%d msgtype=%d", bp->bp_op, dhcp_msg_type);
 if (preq_addr.s_addr != htonl(0L))
 DPRINTF(" req_addr=%08" PRIx32 "\n", ntohl(preq_addr.s_addr));
-else
+else {
 DPRINTF("\n");
+}
 
 if (dhcp_msg_type == 0)
 dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */
-- 
2.20.1




[Qemu-devel] [PULL 60/65] slirp: add clock_get_ns() callback

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c  |  6 ++
 slirp/if.c   |  2 +-
 slirp/ip6_icmp.c |  4 ++--
 slirp/libslirp.h |  2 ++
 slirp/slirp.c| 12 +---
 5 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index 2d5337da04..f98425ee9f 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -146,9 +146,15 @@ static void net_slirp_guest_error(const char *msg)
 qemu_log_mask(LOG_GUEST_ERROR, "%s", msg);
 }
 
+static int64_t net_slirp_clock_get_ns(void)
+{
+return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+}
+
 static const SlirpCb slirp_cb = {
 .output = net_slirp_output,
 .guest_error = net_slirp_guest_error,
+.clock_get_ns = net_slirp_clock_get_ns,
 };
 
 static int net_slirp_init(NetClientState *peer, const char *model,
diff --git a/slirp/if.c b/slirp/if.c
index ce4f5fac53..73e3705740 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -148,7 +148,7 @@ diddit:
  */
 void if_start(Slirp *slirp)
 {
-uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+uint64_t now = slirp->cb->clock_get_ns();
 bool from_batchq = false;
 struct mbuf *ifm, *ifm_next, *ifqt;
 
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index 97304a9dd9..5261baae27 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -17,7 +17,7 @@ static void ra_timer_handler(void *opaque)
 {
 Slirp *slirp = opaque;
 timer_mod(slirp->ra_timer,
-  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + NDP_Interval);
+  slirp->cb->clock_get_ns() / SCALE_MS + NDP_Interval);
 ndp_send_ra(slirp);
 }
 
@@ -31,7 +31,7 @@ void icmp6_init(Slirp *slirp)
  SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL,
  ra_timer_handler, slirp);
 timer_mod(slirp->ra_timer,
-  qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + NDP_Interval);
+  slirp->cb->clock_get_ns() / SCALE_MS + NDP_Interval);
 }
 
 void icmp6_cleanup(Slirp *slirp)
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 3e0aa19f4b..4611a7447b 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -15,6 +15,8 @@ typedef struct SlirpCb {
 void (*output)(void *opaque, const uint8_t *pkt, int pkt_len);
 /* Print a message for an error due to guest misbehavior.  */
 void (*guest_error)(const char *msg);
+/* Return the virtual clock value in nanoseconds */
+int64_t (*clock_get_ns)(void);
 } SlirpCb;
 
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 882d28a4de..535c8ad5f9 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -581,15 +581,15 @@ void slirp_pollfds_fill(GArray *pollfds, uint32_t 
*timeout)
 
 void slirp_pollfds_poll(GArray *pollfds, int select_error)
 {
-Slirp *slirp;
+Slirp *slirp = QTAILQ_FIRST(_instances);
 struct socket *so, *so_next;
 int ret;
 
-if (QTAILQ_EMPTY(_instances)) {
+if (!slirp) {
 return;
 }
 
-curtime = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
+curtime = slirp->cb->clock_get_ns() / SCALE_MS;
 
 QTAILQ_FOREACH(slirp, _instances, entry) {
 /*
@@ -916,8 +916,7 @@ static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct 
ethhdr *eh,
 ifm->resolution_requested = true;
 
 /* Expire request and drop outgoing packet after 1 second */
-ifm->expiration_date =
-qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 10ULL;
+ifm->expiration_date = slirp->cb->clock_get_ns() + 10ULL;
 }
 return 0;
 } else {
@@ -943,8 +942,7 @@ static int if_encap6(Slirp *slirp, struct mbuf *ifm, struct 
ethhdr *eh,
 if (!ifm->resolution_requested) {
 ndp_send_ns(slirp, ip6h->ip_dst);
 ifm->resolution_requested = true;
-ifm->expiration_date =
-qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 10ULL;
+ifm->expiration_date = slirp->cb->clock_get_ns() + 10ULL;
 }
 return 0;
 } else {
-- 
2.20.1




[Qemu-devel] [PULL 29/65] slirp: remove unused HAVE_INET_ATON

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp_config.h | 6 --
 1 file changed, 6 deletions(-)

diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index 833f25a965..5126711849 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -16,9 +16,3 @@
 
 /* Define to sizeof(char *) */
 #define SIZEOF_CHAR_P (HOST_LONG_BITS / 8)
-
-/* Define if you have inet_aton */
-#undef HAVE_INET_ATON
-#ifndef _WIN32
-#define HAVE_INET_ATON
-#endif
-- 
2.20.1




[Qemu-devel] [PULL 47/65] slirp: drop

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Since commit 12f8def0e02232d7c6416ad9b66640f973c531d1 (v2.9), qemu
requires Vista. Let's remove some conditional code.

Note that this introduces a missing declaration warning with mingw.
warning: implicit declaration of function 'inet_ntop'

See also: https://sourceforge.net/p/mingw-w64/mailman/message/36473782/

We could workaround it by declaring it ourself depending on __MINGW64_VERSION_*:
WINSOCK_API_LINKAGE INT WSAAPI inet_pton(int Family, PCTSTR pszAddrString, 
PVOID pAddrBuf);

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c   | 22 --
 slirp/ip6_icmp.c  | 10 --
 slirp/ndp_table.c | 14 ++
 3 files changed, 10 insertions(+), 36 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index b1c98b9470..2d5337da04 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -290,17 +290,6 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 }
 #endif
 
-#if defined(_WIN32) && (_WIN32_WINNT < 0x0600)
-/* No inet_pton helper before Vista... */
-if (vprefix6) {
-/* Unsupported */
-error_setg(errp, "IPv6 prefix not supported");
-return -1;
-}
-memset(_prefix, 0, sizeof(ip6_prefix));
-ip6_prefix.s6_addr[0] = 0xfe;
-ip6_prefix.s6_addr[1] = 0xc0;
-#else
 if (!vprefix6) {
 vprefix6 = "fec0::";
 }
@@ -308,7 +297,6 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 error_setg(errp, "Failed to parse IPv6 prefix");
 return -1;
 }
-#endif
 
 if (!vprefix6_len) {
 vprefix6_len = 64;
@@ -320,10 +308,6 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 }
 
 if (vhost6) {
-#if defined(_WIN32) && (_WIN32_WINNT < 0x0600)
-error_setg(errp, "IPv6 host not supported");
-return -1;
-#else
 if (!inet_pton(AF_INET6, vhost6, _host)) {
 error_setg(errp, "Failed to parse IPv6 host");
 return -1;
@@ -332,17 +316,12 @@ static int net_slirp_init(NetClientState *peer, const 
char *model,
 error_setg(errp, "IPv6 Host doesn't belong to network");
 return -1;
 }
-#endif
 } else {
 ip6_host = ip6_prefix;
 ip6_host.s6_addr[15] |= 2;
 }
 
 if (vnameserver6) {
-#if defined(_WIN32) && (_WIN32_WINNT < 0x0600)
-error_setg(errp, "IPv6 DNS not supported");
-return -1;
-#else
 if (!inet_pton(AF_INET6, vnameserver6, _dns)) {
 error_setg(errp, "Failed to parse IPv6 DNS");
 return -1;
@@ -351,7 +330,6 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 error_setg(errp, "IPv6 DNS doesn't belong to network");
 return -1;
 }
-#endif
 } else {
 ip6_dns = ip6_prefix;
 ip6_dns.s6_addr[15] |= 3;
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index 3f74d172f4..595a62c8d4 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -74,6 +74,7 @@ void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t 
code)
 Slirp *slirp = m->slirp;
 struct mbuf *t;
 struct ip6 *ip = mtod(m, struct ip6 *);
+char addrstr[INET6_ADDRSTRLEN];
 
 DEBUG_CALL("icmp6_send_error");
 DEBUG_ARGS(" type = %d, code = %d\n", type, code);
@@ -90,11 +91,8 @@ void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t 
code)
 struct ip6 *rip = mtod(t, struct ip6 *);
 rip->ip_src = (struct in6_addr)LINKLOCAL_ADDR;
 rip->ip_dst = ip->ip_src;
-#if !defined(_WIN32) || (_WIN32_WINNT >= 0x0600)
-char addrstr[INET6_ADDRSTRLEN];
 inet_ntop(AF_INET6, >ip_dst, addrstr, INET6_ADDRSTRLEN);
 DEBUG_ARG("target = %s", addrstr);
-#endif
 
 rip->ip_nh = IPPROTO_ICMPV6;
 const int error_data_len = MIN(m->m_len,
@@ -222,12 +220,12 @@ void ndp_send_ra(Slirp *slirp)
  */
 void ndp_send_ns(Slirp *slirp, struct in6_addr addr)
 {
-DEBUG_CALL("ndp_send_ns");
-#if !defined(_WIN32) || (_WIN32_WINNT >= 0x0600)
 char addrstr[INET6_ADDRSTRLEN];
+
 inet_ntop(AF_INET6, , addrstr, INET6_ADDRSTRLEN);
+
+DEBUG_CALL("ndp_send_ns");
 DEBUG_ARG("target = %s", addrstr);
-#endif
 
 /* Build IPv6 packet */
 struct mbuf *t = m_get(slirp);
diff --git a/slirp/ndp_table.c b/slirp/ndp_table.c
index a4e6421fd3..1401e1b322 100644
--- a/slirp/ndp_table.c
+++ b/slirp/ndp_table.c
@@ -10,15 +10,14 @@
 void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr,
 uint8_t ethaddr[ETH_ALEN])
 {
+char addrstr[INET6_ADDRSTRLEN];
 NdpTable *ndp_table = >ndp_table;
 int i;
 
-DEBUG_CALL("ndp_table_add");
-#if !defined(_WIN32) || (_WIN32_WINNT >= 0x0600)
-char addrstr[INET6_ADDRSTRLEN];
 inet_ntop(AF_INET6, &(ip_addr), addrstr, INET6_ADDRSTRLEN);
+
+DEBUG_CALL("ndp_table_add");
 DEBUG_ARG("ip = %s", addrstr);
-#endif
 DEBUG_ARGS(" hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
ethaddr[0], ethaddr[1], ethaddr[2],
   

[Qemu-devel] [PULL 36/65] slirp: add a callback to log guest errors

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c  | 7 +++
 slirp/dhcpv6.c   | 6 +++---
 slirp/ip6_icmp.c | 7 +++
 slirp/libslirp.h | 2 ++
 4 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index 031c324f02..ea8b04e007 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -23,6 +23,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/log.h"
 #include "net/slirp.h"
 
 
@@ -140,8 +141,14 @@ static NetClientInfo net_slirp_info = {
 .cleanup = net_slirp_cleanup,
 };
 
+static void net_slirp_guest_error(const char *msg)
+{
+qemu_log_mask(LOG_GUEST_ERROR, "%s", msg);
+}
+
 static const SlirpCb slirp_cb = {
 .output = net_slirp_output,
+.guest_error = net_slirp_guest_error,
 };
 
 static int net_slirp_init(NetClientState *peer, const char *model,
diff --git a/slirp/dhcpv6.c b/slirp/dhcpv6.c
index 943a13bca8..5d703e8ae6 100644
--- a/slirp/dhcpv6.c
+++ b/slirp/dhcpv6.c
@@ -50,7 +50,7 @@ struct requested_infos {
  * the odata region, thus the caller must keep odata valid as long as it
  * needs to access the requested_infos struct.
  */
-static int dhcpv6_parse_info_request(uint8_t *odata, int olen,
+static int dhcpv6_parse_info_request(Slirp *slirp, uint8_t *odata, int olen,
  struct requested_infos *ri)
 {
 int i, req_opt;
@@ -61,7 +61,7 @@ static int dhcpv6_parse_info_request(uint8_t *odata, int olen,
 int len = odata[2] << 8 | odata[3];
 
 if (len + 4 > olen) {
-qemu_log_mask(LOG_GUEST_ERROR, "Guest sent bad DHCPv6 packet!\n");
+slirp->cb->guest_error("Guest sent bad DHCPv6 packet!");
 return -E2BIG;
 }
 
@@ -121,7 +121,7 @@ static void dhcpv6_info_request(Slirp *slirp, struct 
sockaddr_in6 *srcsas,
 struct mbuf *m;
 uint8_t *resp;
 
-if (dhcpv6_parse_info_request(odata, olen, ) < 0) {
+if (dhcpv6_parse_info_request(slirp, odata, olen, ) < 0) {
 return;
 }
 
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index 595647b1b1..3f74d172f4 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -342,8 +342,7 @@ static void ndp_input(struct mbuf *m, Slirp *slirp, struct 
ip6 *ip,
 
 case ICMP6_NDP_RA:
 DEBUG_CALL(" type = Router Advertisement");
-qemu_log_mask(LOG_GUEST_ERROR,
-"Warning: guest sent NDP RA, but shouldn't");
+slirp->cb->guest_error("Warning: guest sent NDP RA, but shouldn't");
 break;
 
 case ICMP6_NDP_NS:
@@ -376,8 +375,8 @@ static void ndp_input(struct mbuf *m, Slirp *slirp, struct 
ip6 *ip,
 
 case ICMP6_NDP_REDIRECT:
 DEBUG_CALL(" type = Redirect");
-qemu_log_mask(LOG_GUEST_ERROR,
-"Warning: guest sent NDP REDIRECT, but shouldn't");
+slirp->cb->guest_error(
+"Warning: guest sent NDP REDIRECT, but shouldn't");
 break;
 }
 }
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index a5d1b27b5e..3e0aa19f4b 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -13,6 +13,8 @@ typedef struct Slirp Slirp;
 typedef struct SlirpCb {
 /* Send an ethernet frame to the guest network.  */
 void (*output)(void *opaque, const uint8_t *pkt, int pkt_len);
+/* Print a message for an error due to guest misbehavior.  */
+void (*guest_error)(const char *msg);
 } SlirpCb;
 
 
-- 
2.20.1




[Qemu-devel] [PULL 56/65] slirp: use %p for pointers format

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

This fixes some compilation warnings on mingw64.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/ip6_icmp.c   | 2 +-
 slirp/ip6_input.c  | 2 +-
 slirp/ip6_output.c | 4 ++--
 slirp/udp6.c   | 6 +++---
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index 595a62c8d4..bce075913c 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -390,7 +390,7 @@ void icmp6_input(struct mbuf *m)
 int hlen = sizeof(struct ip6);
 
 DEBUG_CALL("icmp6_input");
-DEBUG_ARG("m = %lx", (long) m);
+DEBUG_ARG("m = %p", m);
 DEBUG_ARG("m_len = %d", m->m_len);
 
 if (ntohs(ip->ip_pl) < ICMP6_MINLEN) {
diff --git a/slirp/ip6_input.c b/slirp/ip6_input.c
index ac2e3ea882..ab656a0a9d 100644
--- a/slirp/ip6_input.c
+++ b/slirp/ip6_input.c
@@ -31,7 +31,7 @@ void ip6_input(struct mbuf *m)
 }
 
 DEBUG_CALL("ip6_input");
-DEBUG_ARG("m = %lx", (long)m);
+DEBUG_ARG("m = %p", m);
 DEBUG_ARG("m_len = %d", m->m_len);
 
 if (m->m_len < sizeof(struct ip6)) {
diff --git a/slirp/ip6_output.c b/slirp/ip6_output.c
index 762cbfe89c..52c88ad691 100644
--- a/slirp/ip6_output.c
+++ b/slirp/ip6_output.c
@@ -19,8 +19,8 @@ int ip6_output(struct socket *so, struct mbuf *m, int fast)
 struct ip6 *ip = mtod(m, struct ip6 *);
 
 DEBUG_CALL("ip6_output");
-DEBUG_ARG("so = %lx", (long)so);
-DEBUG_ARG("m = %lx", (long)m);
+DEBUG_ARG("so = %p", so);
+DEBUG_ARG("m = %p", m);
 
 /* Fill IPv6 header */
 ip->ip_v = IP6VERSION;
diff --git a/slirp/udp6.c b/slirp/udp6.c
index 473ba1586e..8cdb1892e2 100644
--- a/slirp/udp6.c
+++ b/slirp/udp6.c
@@ -20,7 +20,7 @@ void udp6_input(struct mbuf *m)
 struct sockaddr_in6 lhost;
 
 DEBUG_CALL("udp6_input");
-DEBUG_ARG("m = %lx", (long)m);
+DEBUG_ARG("m = %p", m);
 
 if (slirp->restricted) {
 goto bad;
@@ -144,8 +144,8 @@ int udp6_output(struct socket *so, struct mbuf *m,
 struct udphdr *uh;
 
 DEBUG_CALL("udp6_output");
-DEBUG_ARG("so = %lx", (long)so);
-DEBUG_ARG("m = %lx", (long)m);
+DEBUG_ARG("so = %p", so);
+DEBUG_ARG("m = %p", m);
 
 /* adjust for header */
 m->m_data -= sizeof(struct udphdr);
-- 
2.20.1




[Qemu-devel] [PULL 51/65] slirp: replace some fprintf() with DEBUG_MISC

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Remove some clutter, and avoids direct call to fprintf().

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/slirp/slirp.c b/slirp/slirp.c
index 7091c3998a..ce5f571d0f 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -164,9 +164,7 @@ static int get_dns_addr_resolv_conf(int af, void 
*pdns_addr, void *cached_addr,
 if (!f)
 return -1;
 
-#ifdef DEBUG
-fprintf(stderr, "IP address of your DNS(s): ");
-#endif
+DEBUG_MISC("IP address of your DNS(s): ");
 while (fgets(buff, 512, f) != NULL) {
 if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
 char *c = strchr(buff2, '%');
@@ -188,15 +186,12 @@ static int get_dns_addr_resolv_conf(int af, void 
*pdns_addr, void *cached_addr,
 *scope_id = if_index;
 }
 *cached_time = curtime;
+} else {
+DEBUG_MISC(", ");
 }
-#ifdef DEBUG
-else
-fprintf(stderr, ", ");
-#endif
+
 if (++found > 3) {
-#ifdef DEBUG
-fprintf(stderr, "(more)");
-#endif
+DEBUG_MISC("(more)");
 break;
 }
 #ifdef DEBUG
@@ -206,7 +201,7 @@ static int get_dns_addr_resolv_conf(int af, void 
*pdns_addr, void *cached_addr,
 if (!res) {
 res = "(string conversion error)";
 }
-fprintf(stderr, "%s", res);
+DEBUG_MISC("%s", res);
 }
 #endif
 }
-- 
2.20.1




[Qemu-devel] [PULL 46/65] slirp: Enable fork_exec support on Windows

2019-01-13 Thread Samuel Thibault
g_spawn_async_with_fds is portable on Windows, so we can now enable
fork_exec support there.

Thanks Daniel P. Berrangé for the notice!

Signed-off-by: Samuel Thibault 
Reviewed-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
---
 slirp/misc.c | 14 ++
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/slirp/misc.c b/slirp/misc.c
index b141446319..2d092624d3 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -62,17 +62,6 @@ int add_exec(struct ex_list **ex_ptr, void *chardev, const 
char *cmdline,
 }
 
 
-#ifdef _WIN32
-
-int
-fork_exec(struct socket *so, const char *ex)
-{
-/* not implemented */
-return 0;
-}
-
-#else
-
 static int
 slirp_socketpair_with_oob(int sv[2])
 {
@@ -132,7 +121,9 @@ err:
 static void
 fork_exec_child_setup(gpointer data)
 {
+#ifndef _WIN32
 setsid();
+#endif
 }
 
 int
@@ -177,7 +168,6 @@ fork_exec(struct socket *so, const char *ex)
 qemu_set_nonblock(so->s);
 return 1;
 }
-#endif
 
 char *slirp_connection_info(Slirp *slirp)
 {
-- 
2.20.1




[Qemu-devel] [PULL 57/65] slirp: remove remaining DEBUG blocks

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Instead, rely on slirp_debug flags, or compile unconditionally (the
substraction in cksum is unlikely to affect any benchmark result).

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/cksum.c   | 4 
 slirp/ip_icmp.c | 5 ++---
 slirp/slirp.c   | 5 +
 3 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/slirp/cksum.c b/slirp/cksum.c
index b9466485b5..0a988b845d 100644
--- a/slirp/cksum.c
+++ b/slirp/cksum.c
@@ -70,9 +70,7 @@ int cksum(struct mbuf *m, int len)
 
if (len < mlen)
   mlen = len;
-#ifdef DEBUG
len -= mlen;
-#endif
/*
 * Force to even boundary.
 */
@@ -122,12 +120,10 @@ int cksum(struct mbuf *m, int len)
   s_util.c[0] = *(uint8_t *)w;
 
 cont:
-#ifdef DEBUG
if (len) {
DEBUG_ERROR("cksum: out of data\n");
DEBUG_ERROR(" len = %d\n", len);
}
-#endif
if (mlen == -1) {
/* The last mbuf has odd # of bytes. Follow the
 standard (the odd byte may be shifted left by 8 bits
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 6c7e375ff8..cd2faeacb6 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -257,13 +257,12 @@ icmp_send_error(struct mbuf *msrc, u_char type, u_char 
code, int minsize,
   /* check msrc */
   if(!msrc) goto end_error;
   ip = mtod(msrc, struct ip *);
-#ifdef DEBUG
-  { char bufa[20], bufb[20];
+  if (slirp_debug & DBG_MISC) {
+char bufa[20], bufb[20];
 strcpy(bufa, inet_ntoa(ip->ip_src));
 strcpy(bufb, inet_ntoa(ip->ip_dst));
 DEBUG_MISC(" %.16s to %.16s\n", bufa, bufb);
   }
-#endif
   if(ip->ip_off & IP_OFFMASK) goto end_error;/* Only reply to fragment 0 */
 
   /* Do not reply to source-only IPs */
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 0b70cb9fb6..6c732cd15b 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -195,9 +195,7 @@ static int get_dns_addr_resolv_conf(int af, void 
*pdns_addr, void *cached_addr,
 if (++found > 3) {
 DEBUG_MISC("(more)");
 break;
-}
-#ifdef DEBUG
-else {
+} else if (slirp_debug & DBG_MISC) {
 char s[INET6_ADDRSTRLEN];
 const char *res = inet_ntop(af, tmp_addr, s, sizeof(s));
 if (!res) {
@@ -205,7 +203,6 @@ static int get_dns_addr_resolv_conf(int af, void 
*pdns_addr, void *cached_addr,
 }
 DEBUG_MISC("%s", res);
 }
-#endif
 }
 }
 fclose(f);
-- 
2.20.1




Re: [Qemu-devel] [PATCH v2 09/12] tests/tcg/mips: Test R5900 three-operand MADDU1

2019-01-13 Thread Aleksandar Markovic
On Sunday, January 13, 2019, Fredrik Noring  wrote:

> Hi Aleksandar,
>
> > - Suggestion: The next MIPS pull request is scehuled for Friday,
> > Jan 18, 2018. It would be fantastic if you could prepare the
> > following by Jan 14:
> >
> >   * Add 32 TCGv_i64 registers that would represent higher halves
> >   of R5900 general purpose registers.
>
> Done!


Awesome!

I am especially happy with your choice of naming "mmr" (MultiMedia
Registers) for these fieilds, since that is what they really are (and they
are certainly not "gprs"). Right on the money!


>
> >   * Add TCGv_i32 register SA (shift amount).
>
> See notes below.
>
> >   * Perhaps consider adding higher halves of registers HI an LO
> >   independently on HI/LO array used by DSP.
>
> For HI1 and LO1 only? I'm asking since HI0 and LO0 are implemented with
> the DSP array anyway, for all ISAs.
>
>
I leave it to your judgement. If you are not sure (or you find the current
implementation too sensitive or contrieved to touch), you can leave HI1/LO1
fields implementation as it is now. My motivation was avoiding usage of the
same data fields for two relatively independant purposes.


> >   * It is customary to implement R/W access while introducing
> >   such registers:
> > * Implement R/W access instructions to higher halves of
> > R5900 GPRs:
> >   * LQ
>
> Done, including PCPYUD and PCPYLD for proper testing!
>
>
Outstanding! I salute your including PCPYUD and PCPYLD in this group - they
too can be considered "basic R/W access to mmr".


> >   * SQ
>
> Done, including testing!
>
>
Perfect!


> > * Implement R/W access instructions to SA register:
> >   * MFSA
>
> The TX79 manual says that "the sole purpose of this instruction is to
> permit the shift amount to be saved during a context switch" and that
> "the shift amount is encoded in SA in an implementation-defined manner"
> so it seems to make more sense for system mode rather than user mode?
>
> One may want to choose an implementation that matches the actual R5900
> hardware, even though the manual says it's arbitrary.
>
> >   * MTSA
>
> Likewise.
>
> >   * MTSAH
> >   * MTSAB
>
> These instructions do not appear to be usable unless the corresponding
> shift instructions are implemented as well?
>
>
The goal right now is to prepare basic stuff related to SA register, even
though there is possibly no immediate any application use case. However,
this will make potential future development considerably easier, so please
include handling of this register and these instructions.


> I will post an R5900 multimedia instruction patch series shortly.
>
>
Yes, go ahead, please!

I unfortunatelly will not have enough time for detailed review before
Tuesday, but I have a relatively simple hint right now:

Regarding segments:

+int rs = extract32(ctx->opcode, 21, 5);
+int rt = extract32(ctx->opcode, 16, 5);
+int rd = extract32(ctx->opcode, 11, 5);

Please include them in gen_XXX() functions, rather than in decode_XXX()
functions. This will leave decode_XXX() functions with a single
responsibility of detecting what instruction is about to be processed,
which is cleaner from logical decomposition point of view (even if it would
sometimes result in the repetition of some code segments - logical
decomposition is of far greater importance).

Thanks for all efforts!!

Aleksandar




> Fredrik
>
>


[Qemu-devel] [PULL 40/65] slirp: remove dead TCP_ACK_HACK code

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

Untouched since original introduction in 2004.

Signed-off-by: Marc-André Lureau 
Reviewed-by: Daniel P. Berrangé 
Signed-off-by: Samuel Thibault 
---
 slirp/tcp_input.c | 23 +--
 1 file changed, 1 insertion(+), 22 deletions(-)

diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 0f073d4b38..c4d7abf1fa 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -60,27 +60,6 @@
  * Set DELACK for segments received in order, but ack immediately
  * when segments are out of order (so fast retransmit can work).
  */
-#ifdef TCP_ACK_HACK
-#define TCP_REASS(tp, ti, m, so, flags) {\
-   if ((ti)->ti_seq == (tp)->rcv_nxt && \
-   tcpfrag_list_empty(tp) && \
-   (tp)->t_state == TCPS_ESTABLISHED) {\
-   if (ti->ti_flags & TH_PUSH) \
-   tp->t_flags |= TF_ACKNOW; \
-   else \
-   tp->t_flags |= TF_DELACK; \
-   (tp)->rcv_nxt += (ti)->ti_len; \
-   flags = (ti)->ti_flags & TH_FIN; \
-   if (so->so_emu) { \
-  if (tcp_emu((so),(m))) sbappend((so), (m)); \
-  } else \
-  sbappend((so), (m)); \
-   } else {\
-   (flags) = tcp_reass((tp), (ti), (m)); \
-   tp->t_flags |= TF_ACKNOW; \
-   } \
-}
-#else
 #defineTCP_REASS(tp, ti, m, so, flags) { \
if ((ti)->ti_seq == (tp)->rcv_nxt && \
 tcpfrag_list_empty(tp) && \
@@ -97,7 +76,7 @@
tp->t_flags |= TF_ACKNOW; \
} \
 }
-#endif
+
 static void tcp_dooptions(struct tcpcb *tp, u_char *cp, int cnt,
   struct tcpiphdr *ti);
 static void tcp_xmit_timer(register struct tcpcb *tp, int rtt);
-- 
2.20.1




[Qemu-devel] [PULL 62/65] slirp: set G_LOG_DOMAIN

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

We are moving to g_log() facilities to log errors and probably debug
messages too. Let's have the "Slirp" prefix on messages slirp produces.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/Makefile.objs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 21653f69e9..959558c732 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -28,3 +28,5 @@ slirp.mo-objs = \
udp.o \
udp6.o \
$(NULL)
+
+slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\"
-- 
2.20.1




[Qemu-devel] [PULL 48/65] slirp: rename exec_list

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

This list is not only used to handle command to execute on guest
connection, it can also redirect to an arbitrary object, such as a
chardev. Let's rename the struct and the field to "guestfwd".

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/misc.c  |  6 +++---
 slirp/misc.h  |  6 +++---
 slirp/slirp.c | 18 +-
 slirp/slirp.h |  2 +-
 slirp/tcp_input.c |  6 +++---
 slirp/tcp_subr.c  |  4 ++--
 6 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/slirp/misc.c b/slirp/misc.c
index 2d092624d3..526cefa0f1 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -36,10 +36,10 @@ remque(void *a)
   element->qh_rlink = NULL;
 }
 
-int add_exec(struct ex_list **ex_ptr, void *chardev, const char *cmdline,
+int add_exec(struct gfwd_list **ex_ptr, void *chardev, const char *cmdline,
  struct in_addr addr, int port)
 {
-   struct ex_list *tmp_ptr;
+   struct gfwd_list *tmp_ptr;
 
/* First, check if the port is "bound" */
for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
@@ -49,7 +49,7 @@ int add_exec(struct ex_list **ex_ptr, void *chardev, const 
char *cmdline,
}
 
tmp_ptr = *ex_ptr;
-   *ex_ptr = g_new0(struct ex_list, 1);
+   *ex_ptr = g_new0(struct gfwd_list, 1);
(*ex_ptr)->ex_fport = port;
(*ex_ptr)->ex_addr = addr;
if (chardev) {
diff --git a/slirp/misc.h b/slirp/misc.h
index 0bc5e74bc5..1df707c052 100644
--- a/slirp/misc.h
+++ b/slirp/misc.h
@@ -8,12 +8,12 @@
 #ifndef MISC_H
 #define MISC_H
 
-struct ex_list {
+struct gfwd_list {
void *ex_chardev;
struct in_addr ex_addr; /* Server address */
int ex_fport;   /* Port to telnet to */
char *ex_exec;  /* Command line of what to exec */
-   struct ex_list *ex_next;
+   struct gfwd_list *ex_next;
 };
 
 #define EMU_NONE 0x0
@@ -51,7 +51,7 @@ struct slirp_quehead {
 
 void slirp_insque(void *, void *);
 void slirp_remque(void *);
-int add_exec(struct ex_list **, void *, const char *, struct in_addr, int);
+int add_exec(struct gfwd_list **, void *, const char *, struct in_addr, int);
 int fork_exec(struct socket *so, const char *ex);
 
 #endif
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 591dd1fcb4..e860750f72 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -345,9 +345,9 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct 
in_addr vnetwork,
 
 void slirp_cleanup(Slirp *slirp)
 {
-struct ex_list *e, *next;
+struct gfwd_list *e, *next;
 
-for (e = slirp->exec_list; e; e = next) {
+for (e = slirp->guestfwd_list; e; e = next) {
 next = e->ex_next;
 g_free(e->ex_exec);
 g_free(e);
@@ -760,7 +760,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len)
 struct ethhdr *reh = (struct ethhdr *)arp_reply;
 struct slirp_arphdr *rah = (struct slirp_arphdr *)(arp_reply + ETH_HLEN);
 int ar_op;
-struct ex_list *ex_ptr;
+struct gfwd_list *ex_ptr;
 
 if (!slirp->in_enabled) {
 return;
@@ -780,7 +780,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len)
 if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
 ah->ar_tip == slirp->vhost_addr.s_addr)
 goto arp_ok;
-for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
+for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = 
ex_ptr->ex_next) {
 if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
 goto arp_ok;
 }
@@ -1052,7 +1052,7 @@ int slirp_add_exec(Slirp *slirp, void *chardev, const 
char *cmdline,
 return -1;
 }
 
-return add_exec(>exec_list, chardev, cmdline, *guest_addr,
+return add_exec(>guestfwd_list, chardev, cmdline, *guest_addr,
 htons(guest_port));
 }
 
@@ -1423,9 +1423,9 @@ static const VMStateDescription vmstate_slirp = {
 static void slirp_state_save(QEMUFile *f, void *opaque)
 {
 Slirp *slirp = opaque;
-struct ex_list *ex_ptr;
+struct gfwd_list *ex_ptr;
 
-for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
+for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
 if (ex_ptr->ex_chardev) {
 struct socket *so;
 so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
@@ -1445,7 +1445,7 @@ static void slirp_state_save(QEMUFile *f, void *opaque)
 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
 {
 Slirp *slirp = opaque;
-struct ex_list *ex_ptr;
+struct gfwd_list *ex_ptr;
 
 while (qemu_get_byte(f)) {
 int ret;
@@ -1460,7 +1460,7 @@ static int slirp_state_load(QEMUFile *f, void *opaque, 
int version_id)
 slirp->vnetwork_addr.s_addr) {
 return -EINVAL;
 }
-for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
+

[Qemu-devel] [PULL 64/65] slirp: Mark debugging calls as unlikely

2019-01-13 Thread Samuel Thibault
to get them out of the hot path.

Signed-off-by: Samuel Thibault 
Reviewed-by: Marc-André Lureau 
---
 slirp/debug.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/slirp/debug.h b/slirp/debug.h
index 25a5d59439..269d97d807 100644
--- a/slirp/debug.h
+++ b/slirp/debug.h
@@ -15,25 +15,25 @@
 extern int slirp_debug;
 
 #define DEBUG_CALL(fmt, ...) do {   \
-if (slirp_debug & DBG_CALL) {   \
+if (G_UNLIKELY(slirp_debug & DBG_CALL)) {   \
 g_debug(fmt "...", ##__VA_ARGS__);  \
 }   \
 } while (0)
 
 #define DEBUG_ARG(fmt, ...) do {\
-if (slirp_debug & DBG_CALL) {   \
+if (G_UNLIKELY(slirp_debug & DBG_CALL)) {   \
 g_debug(" " fmt, ##__VA_ARGS__);\
 }   \
 } while (0)
 
 #define DEBUG_MISC(fmt, ...) do {   \
-if (slirp_debug & DBG_MISC) {   \
+if (G_UNLIKELY(slirp_debug & DBG_MISC)) {   \
 g_debug(fmt, ##__VA_ARGS__);\
 }   \
 } while (0)
 
 #define DEBUG_ERROR(fmt, ...) do {  \
-if (slirp_debug & DBG_ERROR) {  \
+if (G_UNLIKELY(slirp_debug & DBG_ERROR)) {  \
 g_debug(fmt, ##__VA_ARGS__);\
 }   \
 } while (0)
-- 
2.20.1




[Qemu-devel] [PULL 58/65] slirp: replace DEBUG_ARGS with DEBUG_ARG

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

There is no clear benefit in calling an alias DEBUG_ARGS(). Replace
calls with DEBUG_ARG(), and fix the white-spacing while at it.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/arp_table.c | 12 ++--
 slirp/debug.h |  2 --
 slirp/ip6_icmp.c  |  2 +-
 slirp/ndp_table.c | 18 +-
 slirp/slirp.c | 12 ++--
 slirp/tcp_input.c |  6 +++---
 6 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/slirp/arp_table.c b/slirp/arp_table.c
index ce19e6e7c0..bf71b984ad 100644
--- a/slirp/arp_table.c
+++ b/slirp/arp_table.c
@@ -34,9 +34,9 @@ void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t 
ethaddr[ETH_ALEN])
 
 DEBUG_CALL("arp_table_add");
 DEBUG_ARG("ip = %s", inet_ntoa((struct in_addr){.s_addr = ip_addr}));
-DEBUG_ARGS(" hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
-   ethaddr[0], ethaddr[1], ethaddr[2],
-   ethaddr[3], ethaddr[4], ethaddr[5]);
+DEBUG_ARG("hw addr = %02x:%02x:%02x:%02x:%02x:%02x",
+  ethaddr[0], ethaddr[1], ethaddr[2],
+  ethaddr[3], ethaddr[4], ethaddr[5]);
 
 if (ip_addr == 0 || ip_addr == 0x || ip_addr == broadcast_addr) {
 /* Do not register broadcast addresses */
@@ -79,9 +79,9 @@ bool arp_table_search(Slirp *slirp, uint32_t ip_addr,
 for (i = 0; i < ARP_TABLE_SIZE; i++) {
 if (arptbl->table[i].ar_sip == ip_addr) {
 memcpy(out_ethaddr, arptbl->table[i].ar_sha,  ETH_ALEN);
-DEBUG_ARGS(" found hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
-   out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
-   out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]);
+DEBUG_ARG("found hw addr = %02x:%02x:%02x:%02x:%02x:%02x",
+  out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
+  out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]);
 return 1;
 }
 }
diff --git a/slirp/debug.h b/slirp/debug.h
index ff920f0b87..50f30898fb 100644
--- a/slirp/debug.h
+++ b/slirp/debug.h
@@ -33,8 +33,6 @@ extern int slirp_debug;
 }   \
 } while (0)
 
-#define DEBUG_ARGS(fmt, ...) DEBUG_ARG(fmt, ##__VA_ARGS__)
-
 #define DEBUG_MISC(fmt, ...) do {   \
 if (slirp_debug & DBG_MISC) {   \
 fprintf(dfd, fmt, ##__VA_ARGS__);   \
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index bce075913c..97304a9dd9 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -77,7 +77,7 @@ void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t 
code)
 char addrstr[INET6_ADDRSTRLEN];
 
 DEBUG_CALL("icmp6_send_error");
-DEBUG_ARGS(" type = %d, code = %d\n", type, code);
+DEBUG_ARG("type = %d, code = %d", type, code);
 
 if (IN6_IS_ADDR_MULTICAST(>ip_src) ||
 in6_zero(>ip_src)) {
diff --git a/slirp/ndp_table.c b/slirp/ndp_table.c
index 1401e1b322..b7b73722f7 100644
--- a/slirp/ndp_table.c
+++ b/slirp/ndp_table.c
@@ -18,9 +18,9 @@ void ndp_table_add(Slirp *slirp, struct in6_addr ip_addr,
 
 DEBUG_CALL("ndp_table_add");
 DEBUG_ARG("ip = %s", addrstr);
-DEBUG_ARGS(" hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
-   ethaddr[0], ethaddr[1], ethaddr[2],
-   ethaddr[3], ethaddr[4], ethaddr[5]);
+DEBUG_ARG("hw addr = %02x:%02x:%02x:%02x:%02x:%02x",
+  ethaddr[0], ethaddr[1], ethaddr[2],
+  ethaddr[3], ethaddr[4], ethaddr[5]);
 
 if (IN6_IS_ADDR_MULTICAST(_addr) || in6_zero(_addr)) {
 /* Do not register multicast or unspecified addresses */
@@ -67,18 +67,18 @@ bool ndp_table_search(Slirp *slirp, struct in6_addr ip_addr,
 out_ethaddr[3] = ip_addr.s6_addr[13];
 out_ethaddr[4] = ip_addr.s6_addr[14];
 out_ethaddr[5] = ip_addr.s6_addr[15];
-DEBUG_ARGS(" multicast addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
-   out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
-   out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]);
+DEBUG_ARG("multicast addr = %02x:%02x:%02x:%02x:%02x:%02x",
+  out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
+  out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]);
 return 1;
 }
 
 for (i = 0; i < NDP_TABLE_SIZE; i++) {
 if (in6_equal(_table->table[i].ip_addr, _addr)) {
 memcpy(out_ethaddr, ndp_table->table[i].eth_addr,  ETH_ALEN);
-DEBUG_ARGS(" found hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
-   out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
-   out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]);
+DEBUG_ARG("found hw addr = %02x:%02x:%02x:%02x:%02x:%02x",
+  out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
+  out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]);
 return 1;
 }
 }
diff --git 

[Qemu-devel] [PULL 52/65] slirp: replace a DEBUG block with WITH_ICMP_ERROR_MSG

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

icmp_send_error() doesnt actually log messages when DEBUG is enabled.
Let's use a different define that describes better the tweaked
behaviour of the function, and avoid uncompiled code.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 slirp/ip_icmp.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index af11cfcefe..6c7e375ff8 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -34,6 +34,10 @@
 #include "slirp.h"
 #include "ip_icmp.h"
 
+#ifndef WITH_ICMP_ERROR_MSG
+#define WITH_ICMP_ERROR_MSG 0
+#endif
+
 /* The message sent when emulating PING */
 /* Be nice and tell them it's just a pseudo-ping packet */
 static const char icmp_ping_msg[] = "This is a pseudo-PING packet used by 
Slirp to emulate ICMP ECHO-REQUEST packets.\n";
@@ -319,8 +323,7 @@ icmp_send_error(struct mbuf *msrc, u_char type, u_char 
code, int minsize,
   HTONS(icp->icmp_ip.ip_id);
   HTONS(icp->icmp_ip.ip_off);
 
-#ifdef DEBUG
-  if(message) {   /* DEBUG : append message to ICMP packet */
+  if (message && WITH_ICMP_ERROR_MSG) { /* append message to ICMP packet */
 int message_len;
 char *cpnt;
 message_len=strlen(message);
@@ -329,7 +332,6 @@ icmp_send_error(struct mbuf *msrc, u_char type, u_char 
code, int minsize,
 memcpy(cpnt, message, message_len);
 m->m_len+=message_len;
   }
-#endif
 
   icp->icmp_cksum = 0;
   icp->icmp_cksum = cksum(m, m->m_len);
-- 
2.20.1




[Qemu-devel] [PULL 65/65] slirp: check data length while emulating ident function

2019-01-13 Thread Samuel Thibault
From: Prasad J Pandit 

While emulating identification protocol, tcp_emu() does not check
available space in the 'sc_rcv->sb_data' buffer. It could lead to
heap buffer overflow issue. Add check to avoid it.

Reported-by: Kira <864786...@qq.com>
Signed-off-by: Prasad J Pandit 
Signed-off-by: Samuel Thibault 
---
 slirp/tcp_subr.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 4a9a5b5edc..23a841f26e 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -634,6 +634,11 @@ tcp_emu(struct socket *so, struct mbuf *m)
socklen_t addrlen = sizeof(struct sockaddr_in);
struct sbuf *so_rcv = >so_rcv;
 
+   if (m->m_len > so_rcv->sb_datalen
+   - (so_rcv->sb_wptr - so_rcv->sb_data)) {
+   return 1;
+   }
+
memcpy(so_rcv->sb_wptr, m->m_data, m->m_len);
so_rcv->sb_wptr += m->m_len;
so_rcv->sb_rptr += m->m_len;
-- 
2.20.1




[Qemu-devel] [PULL 61/65] build-sys: use a seperate slirp-obj-y && slirp.mo

2019-01-13 Thread Samuel Thibault
From: Marc-André Lureau 

This will allow to have cflags for the whole slirp.mo -objs.
It makes it possible to build tests that links only with
slirp-obj-y (and not the whole common-obj).

It is also a step towards building slirp as a shared library, although
this requires a bit more thoughts to build with
net/slirp.o (CONFIG_SLIRP would need to be 'm') and other build issues.

Signed-off-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 Makefile.objs   |  3 +--
 Makefile.target |  5 -
 slirp/Makefile.objs | 35 ++-
 3 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/Makefile.objs b/Makefile.objs
index 2121120492..67a054b08a 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -17,6 +17,7 @@ util-obj-y += $(QAPI_MODULES:%=qapi/qapi-events-%.o)
 util-obj-y += qapi/qapi-introspect.o
 
 chardev-obj-y = chardev/
+slirp-obj-$(CONFIG_SLIRP) = slirp/
 
 ###
 # block-obj-y is code used by both qemu system emulation and qemu-img
@@ -79,8 +80,6 @@ common-obj-y += vl.o
 vl.o-cflags := $(GPROF_CFLAGS) $(SDL_CFLAGS)
 common-obj-$(CONFIG_TPM) += tpm.o
 
-common-obj-$(CONFIG_SLIRP) += slirp/
-
 common-obj-y += backends/
 common-obj-y += chardev/
 
diff --git a/Makefile.target b/Makefile.target
index 44ec4b630c..39f72e81be 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -165,6 +165,7 @@ target-obj-y :=
 block-obj-y :=
 common-obj-y :=
 chardev-obj-y :=
+slirp-obj-y :=
 include $(SRC_PATH)/Makefile.objs
 dummy := $(call unnest-vars,,target-obj-y)
 target-obj-y-save := $(target-obj-y)
@@ -177,7 +178,8 @@ dummy := $(call unnest-vars,.., \
qom-obj-y \
io-obj-y \
common-obj-y \
-   common-obj-m)
+   common-obj-m \
+   slirp-obj-y)
 target-obj-y := $(target-obj-y-save)
 all-obj-y += $(common-obj-y)
 all-obj-y += $(target-obj-y)
@@ -186,6 +188,7 @@ all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) $(chardev-obj-y)
 all-obj-$(CONFIG_USER_ONLY) += $(crypto-aes-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y)
+all-obj-$(CONFIG_SOFTMMU) += $(slirp-obj-y)
 
 $(QEMU_PROG_BUILD): config-devices.mak
 
diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 28049b03cd..21653f69e9 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -1,5 +1,30 @@
-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 dhcpv6.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 udp6.o bootp.o tftp.o arp_table.o 
\
-ndp_table.o ncsi.o
+slirp-obj-y = slirp.mo
+
+slirp.mo-objs = \
+   arp_table.o \
+   bootp.o \
+   cksum.o \
+   dhcpv6.o \
+   dnssearch.o \
+   if.o \
+   ip6_icmp.o \
+   ip6_input.o \
+   ip6_output.o \
+   ip_icmp.o \
+   ip_input.o \
+   ip_output.o \
+   mbuf.o \
+   misc.o \
+   ncsi.o \
+   ndp_table.o \
+   sbuf.o \
+   slirp.o \
+   socket.o \
+   tcp_input.o \
+   tcp_output.o \
+   tcp_subr.o \
+   tcp_timer.o \
+   tftp.o \
+   udp.o \
+   udp6.o \
+   $(NULL)
-- 
2.20.1




[Qemu-devel] [PATCH 04/17] target/arm: Fill in helper_mte_check

2019-01-13 Thread Richard Henderson
Implements the rules of "PE generation of Checked and
Unchecked accesses" which aren't already covered by XXX.
Implements the rules of "PE handling of Tag Check Failure".

Does not implement tag physical address space, so all
operations reduce to unchecked so far.

Signed-off-by: Richard Henderson 
---
 target/arm/mte_helper.c | 80 -
 1 file changed, 79 insertions(+), 1 deletion(-)

diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index a3226c44a4..6f4bc0aa04 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -25,8 +25,86 @@
 #include "exec/helper-proto.h"
 
 
+static int get_allocation_tag(CPUARMState *env, uint64_t ptr)
+{
+/* Tag storage not implemented.  */
+return -1;
+}
+
+static int allocation_tag_from_addr(uint64_t ptr)
+{
+return (extract64(ptr, 56, 4) + extract64(ptr, 55, 1)) & 15;
+}
+
 uint64_t HELPER(mte_check)(CPUARMState *env, uint64_t ptr)
 {
-/* Only unchecked implemented so far.  */
+ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
+ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, true);
+int ptr_tag, mem_tag;
+
+/*
+ * If TBI is disabled, then the access is unchecked.
+ * While we filtered out TBI0==0 && TBI1==0 in cpu_get_tb_cpu_state,
+ * we did not save separate bits for TBI0 != TBI1.
+ */
+if (!param.tbi) {
+/* Do not ignore the top byte.  */
+return ptr;
+}
+
+/*
+ * If TCMA is enabled, then physical tag 0 is unchecked.
+ * Note the rules R0076 & R0077 are written with logical tags,
+ * and we need the physical tag below anyway.
+ */
+ptr_tag = allocation_tag_from_addr(ptr);
+if (param.tcma && ptr_tag == 0) {
+goto pass;
+}
+
+/*
+ * If an access is made to an address that does not provide tag storage,
+ * the result is implementation defined (R0006).  We choose to treat the
+ * access as unchecked.
+ * This is similar to MemAttr != Tagged, which are also unchecked.
+ */
+mem_tag = get_allocation_tag(env, ptr);
+if (mem_tag < 0) {
+goto pass;
+}
+
+/* If the tags do not match, the tag check operation fails.  */
+if (ptr_tag != mem_tag) {
+int el = arm_current_el(env);
+int tcf;
+
+/* Indicate the tag check fail, both async and sync reporting.  */
+env->cp15.tfsr_el[el] |= 1 << param.select;
+
+if (el == 0) {
+/* FIXME: ARMv8.1-VHE S2 translation regime.  */
+tcf = extract64(env->cp15.sctlr_el[1], 38, 2);
+} else {
+tcf = extract64(env->cp15.sctlr_el[el], 40, 2);
+}
+if (tcf == 1) {
+/* Tag check fail causes a synchronous exception.  */
+CPUState *cs = ENV_GET_CPU(env);
+
+/*
+ * In restore_state_to_opc, we set the exception syndrome
+ * for the load or store operation.  Do that first so we
+ * may overwrite that with the syndrome for the tag check.
+ */
+cpu_restore_state(cs, GETPC(), true);
+env->exception.vaddress = ptr;
+raise_exception(env, EXCP_DATA_ABORT,
+syn_data_abort_no_iss(el != 0, 0, 0, 0, 0, 0x11),
+exception_target_el(env));
+}
+}
+
+ pass:
+/* Unchecked, or tag check pass.  Ignore the top byte.  */
 return sextract64(ptr, 0, 55);
 }
-- 
2.17.2




[Qemu-devel] [PATCH 09/17] target/arm: Implement the SUBP instruction

2019-01-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 24 ++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 6583ad93b1..98ff60c161 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -5111,19 +5111,39 @@ static void handle_crc32(DisasContext *s,
  */
 static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
 {
-unsigned int sf, rm, opcode, rn, rd;
+unsigned int sf, rm, opcode, rn, rd, setflag;
 sf = extract32(insn, 31, 1);
+setflag = extract32(insn, 29, 1);
 rm = extract32(insn, 16, 5);
 opcode = extract32(insn, 10, 6);
 rn = extract32(insn, 5, 5);
 rd = extract32(insn, 0, 5);
 
-if (extract32(insn, 29, 1)) {
+if (setflag && opcode != 0) {
 unallocated_encoding(s);
 return;
 }
 
 switch (opcode) {
+case 0: /* SUBP(S) */
+if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) {
+goto do_unallocated;
+} else {
+TCGv_i64 tcg_n, tcg_m, tcg_d;
+
+tcg_n = read_cpu_reg_sp(s, rn, true);
+tcg_m = read_cpu_reg_sp(s, rm, true);
+tcg_gen_sextract_i64(tcg_n, tcg_n, 0, 55);
+tcg_gen_sextract_i64(tcg_m, tcg_m, 0, 55);
+tcg_d = cpu_reg(s, rd);
+
+if (setflag) {
+gen_sub_CC(true, tcg_d, tcg_n, tcg_m);
+} else {
+tcg_gen_sub_i64(tcg_d, tcg_n, tcg_m);
+}
+}
+break;
 case 2: /* UDIV */
 handle_div(s, false, sf, rm, rn, rd);
 break;
-- 
2.17.2




[Qemu-devel] [PATCH 05/17] target/arm: Suppress tag check for sp+offset

2019-01-13 Thread Richard Henderson
R0078 specifies that base register, or base register plus immediate
offset, is unchecked when the base register is SP.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 37 ++---
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 5c2577a9ac..ee95ba7165 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -336,12 +336,11 @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
  * This is always a fresh temporary, as we need to be able to
  * increment this independently of a dirty write-back address.
  */
-static TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr)
+static TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr, bool sp_off)
 {
 TCGv_i64 clean = new_tmp_a64(s);
 
-/* FIXME: SP+OFS is always unchecked.  */
-if (s->tbid && s->mte_active) {
+if (s->tbid && s->mte_active && !sp_off) {
 gen_helper_mte_check(clean, cpu_env, addr);
 } else {
 gen_top_byte_ignore(s, clean, addr, s->tbid);
@@ -2374,7 +2373,7 @@ static void gen_compare_and_swap(DisasContext *s, int rs, 
int rt,
 if (rn == 31) {
 gen_check_sp_alignment(s);
 }
-clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
+clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn), rn == 31);
 tcg_gen_atomic_cmpxchg_i64(tcg_rs, clean_addr, tcg_rs, tcg_rt, memidx,
size | MO_ALIGN | s->be_data);
 }
@@ -2392,7 +2391,7 @@ static void gen_compare_and_swap_pair(DisasContext *s, 
int rs, int rt,
 if (rn == 31) {
 gen_check_sp_alignment(s);
 }
-clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
+clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn), rn == 31);
 
 if (size == 2) {
 TCGv_i64 cmp = tcg_temp_new_i64();
@@ -2517,7 +2516,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t 
insn)
 if (is_lasr) {
 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
 }
-clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
+clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn), rn == 31);
 gen_store_exclusive(s, rs, rt, rt2, clean_addr, size, false);
 return;
 
@@ -2526,7 +2525,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t 
insn)
 if (rn == 31) {
 gen_check_sp_alignment(s);
 }
-clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
+clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn), rn == 31);
 s->is_ldex = true;
 gen_load_exclusive(s, rt, rt2, clean_addr, size, false);
 if (is_lasr) {
@@ -2546,7 +2545,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t 
insn)
 gen_check_sp_alignment(s);
 }
 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
-clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
+clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn), rn == 31);
 do_gpr_st(s, cpu_reg(s, rt), clean_addr, size, true, rt,
   disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
 return;
@@ -2562,7 +2561,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t 
insn)
 if (rn == 31) {
 gen_check_sp_alignment(s);
 }
-clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
+clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn), rn == 31);
 do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, false, true, rt,
   disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
@@ -2576,7 +2575,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t 
insn)
 if (is_lasr) {
 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
 }
-clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
+clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn), rn == 31);
 gen_store_exclusive(s, rs, rt, rt2, clean_addr, size, true);
 return;
 }
@@ -2594,7 +2593,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t 
insn)
 if (rn == 31) {
 gen_check_sp_alignment(s);
 }
-clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
+clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn), rn == 31);
 s->is_ldex = true;
 gen_load_exclusive(s, rt, rt2, clean_addr, size, true);
 if (is_lasr) {
@@ -2784,7 +2783,7 @@ static void disas_ldst_pair(DisasContext *s, uint32_t 
insn)
 if (!postindex) {
 tcg_gen_addi_i64(dirty_addr, dirty_addr, offset);
 }
-clean_addr = clean_data_tbi(s, dirty_addr);
+clean_addr = clean_data_tbi(s, dirty_addr, rn == 31);
 
 if (is_vector) {
 if (is_load) {
@@ -2922,7 +2921,7 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t 
insn,
 if (!post_index) {
 tcg_gen_addi_i64(dirty_addr, dirty_addr, imm9);
 }
-

[Qemu-devel] [PATCH 03/17] target/arm: Add MTE system registers

2019-01-13 Thread Richard Henderson
This is TFSRE0_EL1, TFSR_EL1, TFSR_EL2, TFSR_EL3,
RGSR_EL1, GCR_EL1, and PSTATE.TCO.

Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h   |  5 +
 target/arm/translate.h | 11 ++
 target/arm/helper.c| 45 ++
 target/arm/translate-a64.c | 11 ++
 4 files changed, 72 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 22163c9c3f..c8b447e30a 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -482,6 +482,11 @@ typedef struct CPUARMState {
 uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
 uint64_t vpidr_el2; /* Virtualization Processor ID Register */
 uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */
+#ifdef TARGET_AARCH64
+uint64_t tfsr_el[4]; /* tfsrel0_el1 is index 0.  */
+uint64_t gcr_el1;
+uint64_t rgsr_el1;
+#endif
 } cp15;
 
 struct {
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 5a101e1c6d..a24757d3d7 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -204,6 +204,17 @@ static inline TCGv_i32 get_ahp_flag(void)
 return ret;
 }
 
+/* Set bits within PSTATE.  */
+static inline void set_pstate_bits(uint32_t bits)
+{
+TCGv_i32 p = tcg_temp_new_i32();
+
+tcg_gen_ld_i32(p, cpu_env, offsetof(CPUARMState, pstate));
+tcg_gen_ori_i32(p, p, bits);
+tcg_gen_st_i32(p, cpu_env, offsetof(CPUARMState, pstate));
+tcg_temp_free_i32(p);
+}
+
 /* Clear bits within PSTATE.  */
 static inline void clear_pstate_bits(uint32_t bits)
 {
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 5a59fc4315..df43deb0f8 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5132,6 +5132,48 @@ static const ARMCPRegInfo pauth_reginfo[] = {
   .fieldoffset = offsetof(CPUARMState, apib_key.hi) },
 REGINFO_SENTINEL
 };
+
+static uint64_t tco_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+return env->pstate & PSTATE_TCO;
+}
+
+static void tco_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
+{
+env->pstate = (env->pstate & ~PSTATE_TCO) | (val & PSTATE_TCO);
+}
+
+static const ARMCPRegInfo mte_reginfo[] = {
+{ .name = "TFSRE0_EL1", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 0, .crn = 6, .crm = 6, .opc2 = 1,
+  .access = PL1_RW,
+  .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[0]) },
+{ .name = "TFSR_EL1", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 0, .crn = 6, .crm = 5, .opc2 = 0,
+  .access = PL1_RW,
+  .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[1]) },
+{ .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 5, .opc2 = 0,
+  .access = PL2_RW,
+  .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[2]) },
+{ .name = "TFSR_EL3", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 6, .opc2 = 0,
+  .access = PL3_RW,
+  .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[3]) },
+{ .name = "RGSR_EL1", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 5,
+  .access = PL1_RW,
+  .fieldoffset = offsetof(CPUARMState, cp15.rgsr_el1) },
+{ .name = "GCR_EL1", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 6,
+  .access = PL1_RW,
+  .fieldoffset = offsetof(CPUARMState, cp15.gcr_el1) },
+{ .name = "TCO", .state = ARM_CP_STATE_AA64,
+  .opc0 = 0, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7,
+  .type = ARM_CP_NO_RAW,
+  .access = PL0_RW, .readfn = tco_read, .writefn = tco_write },
+REGINFO_SENTINEL
+};
 #endif
 
 void register_cp_regs_for_features(ARMCPU *cpu)
@@ -5923,6 +5965,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
 if (cpu_isar_feature(aa64_pauth, cpu)) {
 define_arm_cp_regs(cpu, pauth_reginfo);
 }
+if (cpu_isar_feature(aa64_mte_insn_reg, cpu)) {
+define_arm_cp_regs(cpu, mte_reginfo);
+}
 #endif
 }
 
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 0286507bae..5c2577a9ac 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1668,6 +1668,17 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
 s->base.is_jmp = DISAS_UPDATE;
 break;
 
+case 0x1c: /* TCO */
+if (!dc_isar_feature(aa64_mte_insn_reg, s)) {
+goto do_unallocated;
+}
+if (crm & 1) {
+set_pstate_bits(PSTATE_TCO);
+} else {
+clear_pstate_bits(PSTATE_TCO);
+}
+break;
+
 default:
 do_unallocated:
 unallocated_encoding(s);
-- 
2.17.2




[Qemu-devel] [PATCH 17/17] tests/tcg/aarch64: Add mte smoke tests

2019-01-13 Thread Richard Henderson
??? Requires a quite recent aarch64 assembler.  Use .inst instead?

Signed-off-by: Richard Henderson 
---
 tests/tcg/aarch64/mte-1.c | 27 +
 tests/tcg/aarch64/mte-2.c | 39 +++
 tests/tcg/aarch64/Makefile.target |  4 
 3 files changed, 70 insertions(+)
 create mode 100644 tests/tcg/aarch64/mte-1.c
 create mode 100644 tests/tcg/aarch64/mte-2.c

diff --git a/tests/tcg/aarch64/mte-1.c b/tests/tcg/aarch64/mte-1.c
new file mode 100644
index 00..740bf506f1
--- /dev/null
+++ b/tests/tcg/aarch64/mte-1.c
@@ -0,0 +1,27 @@
+/*
+ * Memory tagging, basic pass cases.
+ */
+
+#include 
+
+asm(".arch armv8.5-a+memtag");
+
+int data[16 / sizeof(int)] __attribute__((aligned(16)));
+
+int main(int ac, char **av)
+{
+int *p0 = data;
+int *p1, *p2;
+long c;
+
+asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(1));
+assert(p1 != p0);
+asm("subp %0,%1,%2" : "=r"(c) : "r"(p0), "r"(p1));
+assert(c == 0);
+
+asm("stg [%0]" : : "r"(p1));
+asm("ldg %0, [%1]" : "=r"(p2) : "r"(p0));
+assert(p1 == p2);
+
+return 0;
+}
diff --git a/tests/tcg/aarch64/mte-2.c b/tests/tcg/aarch64/mte-2.c
new file mode 100644
index 00..4d2004ab41
--- /dev/null
+++ b/tests/tcg/aarch64/mte-2.c
@@ -0,0 +1,39 @@
+/*
+ * Memory tagging, basic fail cases.
+ */
+
+#include 
+#include 
+#include 
+
+asm(".arch armv8.5-a+memtag");
+
+int data[16 / sizeof(int)] __attribute__((aligned(16)));
+
+void pass(int sig)
+{
+exit(0);
+}
+
+int main(int ac, char **av)
+{
+int *p0 = data;
+int *p1, *p2;
+long excl = 1;
+
+/* Create two differently tagged pointers.  */
+asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(excl));
+asm("gmi %0,%1,%0" : "+r"(excl) : "r" (p1));
+assert(excl != 1);
+asm("irg %0,%1,%2" : "=r"(p2) : "r"(p0), "r"(excl));
+assert(p1 != p2);
+
+/* Store the tag from the first pointer.  */
+asm("stg [%0]" : : "r"(p1));
+
+*p1 = 0;
+signal(SIGSEGV, pass);
+*p2 = 0;
+
+assert(0);
+}
diff --git a/tests/tcg/aarch64/Makefile.target 
b/tests/tcg/aarch64/Makefile.target
index 3d56e7c6ea..1c4ebe894c 100644
--- a/tests/tcg/aarch64/Makefile.target
+++ b/tests/tcg/aarch64/Makefile.target
@@ -19,4 +19,8 @@ AARCH64_TESTS += bti-1
 bti-1: LDFLAGS += -nostartfiles -nodefaultlibs -nostdlib
 run-bti-1: QEMU += -cpu max,guarded_pages=on
 
+AARCH64_TESTS += mte-1 mte-2
+mte-%: CFLAGS += -O -g
+run-mte-%: QEMU += -cpu max
+
 TESTS:=$(AARCH64_TESTS)
-- 
2.17.2




[Qemu-devel] [PATCH 15/17] target/arm: Add allocation tag storage for user-only

2019-01-13 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/mte_helper.c | 82 +++--
 1 file changed, 71 insertions(+), 11 deletions(-)

diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
index b125f49258..87328c7a9a 100644
--- a/target/arm/mte_helper.c
+++ b/target/arm/mte_helper.c
@@ -25,16 +25,72 @@
 #include "exec/helper-proto.h"
 
 
-static int get_allocation_tag(CPUARMState *env, uint64_t ptr)
+static int get_allocation_tag(CPUARMState *env, uint64_t ptr, uintptr_t ra)
 {
+#ifdef CONFIG_USER_ONLY
+uint64_t clean_ptr = extract64(ptr, 0, 56);
+uint8_t *tags = page_get_target_data(clean_ptr);
+
+if (tags != NULL) {
+uintptr_t index = extract64(clean_ptr, LOG2_TAG_GRANULE + 1,
+TARGET_PAGE_BITS - LOG2_TAG_GRANULE - 1);
+return extract32(tags[index], (clean_ptr & 1) * 4, 4);
+} else {
+int flags = page_get_flags(clean_ptr);
+
+if (flags & PAGE_SHARED) {
+/* There may be multiple mappings; pretend not implemented.  */
+return -1;
+} else if (flags & PAGE_VALID) {
+/* Page is good, but no tags have been written: all are 0.  */
+return 0;
+} else {
+/* Page is invalid: SIGSEGV.  */
+env->exception.vaddress = ptr;
+cpu_restore_state(ENV_GET_CPU(env), ra, true);
+raise_exception(env, EXCP_DATA_ABORT, 0, 1);
+}
+}
+#else
 /* Tag storage not implemented.  */
 return -1;
+#endif
 }
 
-static bool set_allocation_tag(CPUARMState *env, uint64_t ptr, int tag)
+static bool set_allocation_tag(CPUARMState *env, uint64_t ptr,
+   int tag, uintptr_t ra)
 {
+#ifdef CONFIG_USER_ONLY
+uint64_t clean_ptr = extract64(ptr, 0, 56);
+uint8_t *tags = page_get_target_data(clean_ptr);
+uintptr_t index;
+
+if (tags == NULL) {
+int flags = page_get_flags(clean_ptr);
+size_t alloc_size;
+
+if (flags & PAGE_SHARED) {
+/* There may be multiple mappings; pretend not implemented.  */
+return false;
+} else if (!(flags & PAGE_VALID)) {
+/* Page is invalid: SIGSEGV.  */
+env->exception.vaddress = ptr;
+cpu_restore_state(ENV_GET_CPU(env), ra, true);
+raise_exception(env, EXCP_DATA_ABORT, 0, 1);
+}
+
+alloc_size = TARGET_PAGE_SIZE >> (LOG2_TAG_GRANULE + 1);
+tags = page_alloc_target_data(clean_ptr, alloc_size);
+assert(tags != NULL);
+}
+index = extract64(clean_ptr, LOG2_TAG_GRANULE + 1,
+  TARGET_PAGE_BITS - LOG2_TAG_GRANULE - 1);
+tags[index] = deposit32(tags[index], (clean_ptr & 1) * 4, 4, tag);
+return true;
+#else
 /* Tag storage not implemented.  */
 return false;
+#endif
 }
 
 static int allocation_tag_from_addr(uint64_t ptr)
@@ -116,7 +172,7 @@ uint64_t HELPER(mte_check)(CPUARMState *env, uint64_t ptr)
  * access as unchecked.
  * This is similar to MemAttr != Tagged, which are also unchecked.
  */
-mem_tag = get_allocation_tag(env, ptr);
+mem_tag = get_allocation_tag(env, ptr, GETPC());
 if (mem_tag < 0) {
 goto pass;
 }
@@ -217,7 +273,7 @@ uint64_t HELPER(ldg)(CPUARMState *env, uint64_t ptr)
 int rtag = 0;
 
 if (allocation_tag_access_enabled(env, el, sctlr)) {
-rtag = get_allocation_tag(env, ptr);
+rtag = get_allocation_tag(env, ptr, GETPC());
 if (rtag < 0) {
 rtag = 0;
 }
@@ -232,7 +288,7 @@ uint64_t HELPER(stg)(CPUARMState *env, uint64_t ptr)
 
 if (allocation_tag_access_enabled(env, el, sctlr)) {
 int tag = allocation_tag_from_addr(ptr);
-set_allocation_tag(env, ptr, tag);
+set_allocation_tag(env, ptr, tag, GETPC());
 }
 
 /* Clean the pointer for use by stgz.  */
@@ -247,8 +303,10 @@ uint64_t HELPER(st2g)(CPUARMState *env, uint64_t ptr)
 
 if (allocation_tag_access_enabled(env, el, sctlr)) {
 int tag = allocation_tag_from_addr(ptr);
-if (set_allocation_tag(env, ptr, tag)) {
-set_allocation_tag(env, ptr + (1 << LOG2_TAG_GRANULE), tag);
+uintptr_t ra = GETPC();
+
+if (set_allocation_tag(env, ptr, tag, ra)) {
+set_allocation_tag(env, ptr + (1 << LOG2_TAG_GRANULE), tag, ra);
 }
 }
 
@@ -261,6 +319,7 @@ uint64_t HELPER(ldgv)(CPUARMState *env, uint64_t ptr)
 {
 int el = arm_current_el(env);
 uint64_t sctlr = arm_sctlr(env, el);
+uintptr_t ra = GETPC();
 uint64_t ret;
 int rtag, i;
 
@@ -269,7 +328,7 @@ uint64_t HELPER(ldgv)(CPUARMState *env, uint64_t ptr)
 }
 
 ptr = QEMU_ALIGN_DOWN(ptr, 1 << LOG2_TAG_GRANULE);
-rtag = get_allocation_tag(env, ptr);
+rtag = get_allocation_tag(env, ptr, ra);
 if (rtag < 0) {
 /* The entire page does not have tags.  */
 return 0;
@@ -278,7 +337,7 @@ uint64_t HELPER(ldgv)(CPUARMState 

Re: [Qemu-devel] [PATCH] hw/misc/edu: add msi_uninit() for pci_edu_uninit()

2019-01-13 Thread Peter Xu
On Sun, Jan 13, 2019 at 10:36:41PM +0800, Fei Li wrote:
> From: Fei Li 
> 
> Let's supplement the msi_uninit() when failing to realize
> the pci edu device.
> 
> Cc: Markus Armbruster 
> Cc: Peter Xu 
> Cc: Michael S. Tsirkin 
> Cc: Marcel Apfelbaum 
> Signed-off-by: Fei Li 
> ---
>  hw/misc/edu.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/misc/edu.c b/hw/misc/edu.c
> index cdcf550dd7..4feb7503de 100644
> --- a/hw/misc/edu.c
> +++ b/hw/misc/edu.c
> @@ -367,6 +367,7 @@ static void pci_edu_uninit(PCIDevice *pdev)
>  {
>  EduState *edu = EDU(pdev);
>  
> +msi_uninit(pdev);

It would be cleaner to me to call this after the join() since
edu_fact_thread() could potentially use msi_*() helpers then the
destructions follow the reverse order of init.

Reviewed-by: Peter Xu 

>  qemu_mutex_lock(>thr_mutex);
>  edu->stopping = true;
>  qemu_mutex_unlock(>thr_mutex);
> -- 
> 2.17.2 (Apple Git-113)
> 

Regards,

-- 
Peter Xu



Re: [Qemu-devel] [PATCH v4] tests: vm: auto_install OpenBSD

2019-01-13 Thread Fam Zheng



> On Jan 9, 2019, at 21:59, Daniel P. Berrangé  wrote:
> 
> On Wed, Jan 09, 2019 at 01:55:04PM +, Daniel P. Berrangé wrote:
>> On Wed, Nov 14, 2018 at 05:58:07PM +0800, Fam Zheng wrote:
>>> On Sun, 11/11 18:20, Brad Smith wrote:
 ping.
>>> 
>>> Queued. Will send a pull request soon.
>> 
>> ping, this seems to have got lost, and is blocking us deleting SDL 1.2
>> support from QEMU.
> 
> Sigh, never mind, I found the PR is here:
> 
> https://lists.gnu.org/archive/html/qemu-devel/2019-01/msg00732.html

I had to drop it from the queue because Peter didn’t like the QEMU version 
requirement (for the slirp tftp parameters). :(

What is the blocker for delete SDL 1.2? Is it breaking tests/vm/openbsd? If so 
maybe we can add —disable-sdl to its configure command.

Fam

> 
> Regards,
> Daniel
> -- 
> |: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o-https://fstop138.berrange.com :|
> |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|
> 





[Qemu-devel] [Bug 1802150] Re: Guest undefined when destroyed on host after migration

2019-01-13 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

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

Title:
  Guest undefined when destroyed on host after migration

Status in QEMU:
  Expired

Bug description:
  After a live migration, guest VMs are being undefined from the host
  they were migrated to after shutdown. I have experienced this at two
  (2) separate locations on more than one hardware configuration.  This
  happens when utilizing virt-manager to view current allocations on
  hosts, and virsh on the CLI to migrate guests.  When the guest is
  migrated from one host to another, no errors are thrown, and only lose
  1 packet from infinite ping. Shutting guest down *from* the guest OS
  results in the Guest VM being undefined on the residing host, and XML
  config lost.  If needed, I can provide a recorded session of this
  happening.

  Thanks,
Dan

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



[Qemu-devel] [PATCH v1 2/5] vl.c: add -smp, dies=* command line support

2019-01-13 Thread Like Xu
This patch updates the check rules on legeacy -smp parse from user command
and it's designed to obey the same restrictions as socket/core/thread model.

Signed-off-by: Like Xu 
---
 hmp.c |  3 +++
 hw/core/machine.c | 12 
 vl.c  | 33 -
 3 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/hmp.c b/hmp.c
index 80aa5ab..05ac133 100644
--- a/hmp.c
+++ b/hmp.c
@@ -3013,6 +3013,9 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict 
*qdict)
 if (c->has_socket_id) {
 monitor_printf(mon, "socket-id: \"%" PRIu64 "\"\n", 
c->socket_id);
 }
+if (c->has_die_id) {
+monitor_printf(mon, "die-id: \"%" PRIu64 "\"\n", c->die_id);
+}
 if (c->has_core_id) {
 monitor_printf(mon, "core-id: \"%" PRIu64 "\"\n", c->core_id);
 }
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 95dc7c3..05bc545 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -601,6 +601,11 @@ void machine_set_cpu_numa_node(MachineState *machine,
 return;
 }
 
+if (props->has_die_id && !slot->props.has_die_id) {
+error_setg(errp, "die-id is not supported");
+return;
+}
+
 if (props->has_socket_id && !slot->props.has_socket_id) {
 error_setg(errp, "socket-id is not supported");
 return;
@@ -615,6 +620,10 @@ void machine_set_cpu_numa_node(MachineState *machine,
 continue;
 }
 
+if (props->has_die_id && props->die_id != slot->props.die_id) {
+continue;
+}
+
 if (props->has_socket_id && props->socket_id != slot->props.socket_id) 
{
 continue;
 }
@@ -849,6 +858,9 @@ static char *cpu_slot_to_string(const CPUArchId *cpu)
 if (cpu->props.has_socket_id) {
 g_string_append_printf(s, "socket-id: %"PRId64, cpu->props.socket_id);
 }
+if (cpu->props.has_die_id) {
+g_string_append_printf(s, "die-id: %"PRId64, cpu->props.die_id);
+}
 if (cpu->props.has_core_id) {
 if (s->len) {
 g_string_append_printf(s, ", ");
diff --git a/vl.c b/vl.c
index 9b8ea3f..72be689 100644
--- a/vl.c
+++ b/vl.c
@@ -169,6 +169,7 @@ int win2k_install_hack = 0;
 int singlestep = 0;
 int smp_cpus;
 unsigned int max_cpus;
+int smp_dies = 1;
 int smp_cores = 1;
 int smp_threads = 1;
 int acpi_enabled = 1;
@@ -1208,6 +1209,9 @@ static QemuOptsList qemu_smp_opts = {
 .name = "sockets",
 .type = QEMU_OPT_NUMBER,
 }, {
+ .name = "dies",
+.type = QEMU_OPT_NUMBER,
+}, {
 .name = "cores",
 .type = QEMU_OPT_NUMBER,
 }, {
@@ -1226,32 +1230,34 @@ static void smp_parse(QemuOpts *opts)
 if (opts) {
 unsigned cpus= qemu_opt_get_number(opts, "cpus", 0);
 unsigned sockets = qemu_opt_get_number(opts, "sockets", 0);
+unsigned dies = qemu_opt_get_number(opts, "dies", 0);
 unsigned cores   = qemu_opt_get_number(opts, "cores", 0);
 unsigned threads = qemu_opt_get_number(opts, "threads", 0);
 
 /* compute missing values, prefer sockets over cores over threads */
+dies = dies > 0 ? dies : 1;
 if (cpus == 0 || sockets == 0) {
 cores = cores > 0 ? cores : 1;
 threads = threads > 0 ? threads : 1;
 if (cpus == 0) {
 sockets = sockets > 0 ? sockets : 1;
-cpus = cores * threads * sockets;
+cpus = cores * threads * dies * sockets;
 } else {
 max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus);
-sockets = max_cpus / (cores * threads);
+sockets = max_cpus / (cores * threads * dies);
 }
 } else if (cores == 0) {
 threads = threads > 0 ? threads : 1;
-cores = cpus / (sockets * threads);
+cores = cpus / (sockets * dies * threads);
 cores = cores > 0 ? cores : 1;
 } else if (threads == 0) {
-threads = cpus / (cores * sockets);
+threads = cpus / (cores * dies * sockets);
 threads = threads > 0 ? threads : 1;
-} else if (sockets * cores * threads < cpus) {
+} else if (sockets * dies * cores * threads < cpus) {
 error_report("cpu topology: "
- "sockets (%u) * cores (%u) * threads (%u) < "
+ "sockets (%u) * dies (%u) * cores (%u) * threads (%u) 
< "
  "smp_cpus (%u)",
- sockets, cores, threads, cpus);
+ sockets, dies, cores, threads, cpus);
 exit(1);
 }
 
@@ -1262,22 +1268,23 @@ static void smp_parse(QemuOpts *opts)
 exit(1);
 }
 
-if (sockets * cores * threads > max_cpus) {
+if (sockets * dies * cores * 

[Qemu-devel] [PATCH v1 5/5] i386: add CPUID.1F to cpuid_data with host_cpuid check

2019-01-13 Thread Like Xu
When cs->nr_dies is larger than 1, the CPUID.1F should be generated
and is added to cpuid_data.entries for guest awareness. This patch
provides a return option in kvm_has_cpuid_1f for default choice.

Signed-off-by: Like Xu 
---
 target/i386/kvm.c  | 34 +-
 target/i386/kvm_i386.h |  1 +
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 739cf8c..eb0d1ee 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -120,6 +120,17 @@ bool kvm_has_smm(void)
 return kvm_check_extension(kvm_state, KVM_CAP_X86_SMM);
 }
 
+bool kvm_has_cpuid_1f(void)
+{
+uint32_t eax = 0x1f, ecx = 1, ebx = 0, edx = 0;
+host_cpuid(0x1f, 0, , , , );
+if (eax != 0) {
+printf("It's recommended to disable CPUID.1F emulation \
+on Intel non-MCP platform.\n");
+}
+return true;
+}
+
 bool kvm_has_adjust_clock_stable(void)
 {
 int ret = kvm_check_extension(kvm_state, KVM_CAP_ADJUST_CLOCK);
@@ -1035,7 +1046,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
 }
 
 cpu_x86_cpuid(env, 0, 0, , , , );
-
 for (i = 0; i <= limit; i++) {
 if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
 fprintf(stderr, "unsupported level value: 0x%x\n", limit);
@@ -1127,6 +1137,28 @@ int kvm_arch_init_vcpu(CPUState *cs)
 }
 }
 
+cpu->enable_cpuid_0x1f =  kvm_has_cpuid_1f();
+if (cs->nr_dies > 1) {
+i = 0x1f;
+for (j = 0; ; j++) {
+c->function = i;
+c->flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
+c->index = j;
+cpu_x86_cpuid(env, i, j, >eax, >ebx, >ecx, >edx);
+if (i == 0x1f && j == 3) {
+break;
+}
+if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
+fprintf(stderr, "cpuid_data is full, no space for "
+"cpuid(eax:0x%x,ecx:0x%x)\n", i, j);
+abort();
+}
+c = _data.entries[cpuid_i++];
+if (!cpu->enable_cpuid_0x1f)
+break;
+}
+}
+
 if (limit >= 0x0a) {
 uint32_t eax, edx;
 
diff --git a/target/i386/kvm_i386.h b/target/i386/kvm_i386.h
index 3057ba4..ef9d41e 100644
--- a/target/i386/kvm_i386.h
+++ b/target/i386/kvm_i386.h
@@ -38,6 +38,7 @@ bool kvm_has_adjust_clock_stable(void);
 void kvm_synchronize_all_tsc(void);
 void kvm_arch_reset_vcpu(X86CPU *cs);
 void kvm_arch_do_init_vcpu(X86CPU *cs);
+bool kvm_has_cpuid_1f(void);
 
 int kvm_device_pci_assign(KVMState *s, PCIHostDeviceAddress *dev_addr,
   uint32_t flags, uint32_t *dev_id);
-- 
1.8.3.1




[Qemu-devel] [PATCH v1 1/5] cpu: introduce die, the new cpu toppolgy emulation level

2019-01-13 Thread Like Xu
Following codes on smp_cores, the smp_dies/nr_dies/die-id is added to
machine and CPUState. In addition to enable_cpuid_0xb, enable_cpuid_0x1f
is introduced to track wether host is a new MCP macine or just ignored.
The number for die level_type on Intel is 5 while core type keeps 2.

Signed-off-by: Like Xu 
---
 cpus.c| 1 +
 include/qom/cpu.h | 1 +
 include/sysemu/cpus.h | 1 +
 qapi/misc.json| 1 +
 target/i386/cpu.h | 5 +
 5 files changed, 9 insertions(+)

diff --git a/cpus.c b/cpus.c
index b09b702..503558d 100644
--- a/cpus.c
+++ b/cpus.c
@@ -2066,6 +2066,7 @@ static void qemu_dummy_start_vcpu(CPUState *cpu)
 
 void qemu_init_vcpu(CPUState *cpu)
 {
+cpu->nr_dies = smp_dies;
 cpu->nr_cores = smp_cores;
 cpu->nr_threads = smp_threads;
 cpu->stopped = true;
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 16bbed1..ee53862 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -332,6 +332,7 @@ struct CPUState {
 DeviceState parent_obj;
 /*< public >*/
 
+int nr_dies;
 int nr_cores;
 int nr_threads;
 
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index 731756d..4243c8f 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -34,6 +34,7 @@ void qtest_clock_warp(int64_t dest);
 #ifndef CONFIG_USER_ONLY
 /* vl.c */
 /* *-user doesn't have configurable SMP topology */
+extern int smp_dies;
 extern int smp_cores;
 extern int smp_threads;
 #endif
diff --git a/qapi/misc.json b/qapi/misc.json
index 24d20a8..a01a9fe 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -3229,6 +3229,7 @@
 { 'struct': 'CpuInstanceProperties',
   'data': { '*node-id': 'int',
 '*socket-id': 'int',
+'*die-id': 'int',
 '*core-id': 'int',
 '*thread-id': 'int'
   }
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index ef41a03..aa2ee8a 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -732,6 +732,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_TOPOLOGY_LEVEL_INVALID  (0U << 8)
 #define CPUID_TOPOLOGY_LEVEL_SMT  (1U << 8)
 #define CPUID_TOPOLOGY_LEVEL_CORE (2U << 8)
+#define CPUID_TOPOLOGY_LEVEL_DIE  (5U << 8)
 
 /* MSR Feature Bits */
 #define MSR_ARCH_CAP_RDCL_NO(1U << 0)
@@ -1450,6 +1451,9 @@ struct X86CPU {
 /* Compatibility bits for old machine types: */
 bool enable_cpuid_0xb;
 
+/* Compatibility bits for new machine types: */
+bool enable_cpuid_0x1f;
+
 /* Enable auto level-increase for all CPUID leaves */
 bool full_cpuid_auto_level;
 
@@ -1475,6 +1479,7 @@ struct X86CPU {
 
 int32_t node_id; /* NUMA node this CPU belongs to */
 int32_t socket_id;
+int32_t die_id;
 int32_t core_id;
 int32_t thread_id;
 
-- 
1.8.3.1




[Qemu-devel] [PATCH v1 0/5] Introduce cpu die topology and enable CPUID.1F for i386

2019-01-13 Thread Like Xu
As we know, die is a rectangular piece of a semiconductor wafer. It's very 
common
that chip manufacturers put a multi-core die in one package and one die always 
has
a one-to-one relationship with one socket. Inside the die, it cotains 
multi-cores
and core contains threads topologically. We apply this socket/core/thread model 
to
the qemu -smp configurable space and save it into APIC_IDs for identification.

The undercurrent Is surging. Multi-chip packaging technology allows for 
integration
of multi-die devices in a single package, for example Intel CLX-AP or AMD EPYC.
Integration can be enabled by high-performance, heterogeneous, multi-dies 
interconnect
technology, providing a more cost-effective manner. QEMU and guests may take 
advantages
of multi-dies host for such as guest placing or energy efficiency management...

This patch series extend the CPU topology to the socket/dies/core/thread model,
allowing the setting of dies number per one socket on -smp qemu command. For
i386, it upgrades APIC_IDs generation and reversion functions with a new exposed
leaf called CPUID.1F, which is a preferred superset to leaf 0BH. The CPUID.1F
spec is on https://software.intel.com/en-us/articles/intel-sdm, 3-190 Vol 2A.

E.g. we use -smp 4,dies=2,cores=2,threads=1 to run an MCP kvm-guest,
check raw cpuid data and the expected output from guest is following:
0x001f 0x00: eax=0x ebx=0x0001 ecx=0x0100 edx=0x0002
0x001f 0x01: eax=0x0001 ebx=0x0002 ecx=0x0201 edx=0x0001
0x001f 0x02: eax=0x0002 ebx=0x0004 ecx=0x0502 edx=0x0003
0x001f 0x03: eax=0x ebx=0x ecx=0x0003 edx=0x0001

Like Xu (5):
  cpu: introduce die, the new cpu toppolgy emulation level
  vl.c: add -smp,dies=* command line support
  i386: extend x86_apicid_* functions for smp_dies support
  i386: enable CPUID.1F leaf generation based on spec
  i386: add CPUID.1F to cpuid_data with host_cpuid check

 cpus.c |  1 +
 hmp.c  |  3 ++
 hw/core/machine.c  | 12 +++
 hw/i386/pc.c   | 37 +++---
 include/hw/i386/topology.h | 79 ++
 include/qom/cpu.h  |  1 +
 include/sysemu/cpus.h  |  1 +
 qapi/misc.json |  1 +
 target/i386/cpu.c  | 57 +
 target/i386/cpu.h  |  5 +++
 target/i386/kvm.c  | 34 +++-
 target/i386/kvm_i386.h |  1 +
 vl.c   | 33 +++
 13 files changed, 213 insertions(+), 52 deletions(-)

-- 
1.8.3.1




  1   2   >