[Qemu-devel] Guest application exit point.

2018-10-25 Thread Rafael K. V. Maeda

Hi,

I am implementing a plugin that allocates several resources. I need to 
cleanup some of these resources when QEMU finishes executing the guest 
application. Where is the best exit point to place my cleanup functions?


I have tried registering a function call "atexit" but it does not seem 
to work. Any suggestions? At the moment, I am looking for a solution for 
x86_64 (user emulation mode).


Kind regards,
Rafael



Re: [Qemu-devel] [PATCH v5 3/3] x86: define a new MSR based feature word -- FEATURE_WORDS_ARCH_CAPABILITIES

2018-10-25 Thread Robert Hoo
On Wed, 2018-10-24 at 07:06 -0300, Eduardo Habkost wrote:
> On Mon, Oct 15, 2018 at 12:47:25PM +0800, Robert Hoo wrote:
> > Note RSBA is specially treated -- no matter host support it or not,
> > qemu
> > pretends it is supported.
> > 
> > Signed-off-by: Robert Hoo 
> 
> I am now wondering what else we need to be able to remove
> CPUID_7_0_EDX_ARCH_CAPABILITIES from
> feature_word_info[FEAT_7_0_EDX].unmigratable_flags.
> 
> This series is necessary for that, be I think we still can't let
> the VM be migrated if arch-capabilities is enabled and we're
> running on a host that doesn't have MSR_IA32_ARCH_CAPABILITIES on
> kvm_feature_msrs.
> 
> Reviewed-by: Eduardo Habkost 
> 
> > ---
> >  target/i386/cpu.c | 31 ++-
> >  target/i386/cpu.h |  8 
> >  target/i386/kvm.c | 11 +++
> >  3 files changed, 49 insertions(+), 1 deletion(-)
> > 
[...]
> >  
> >  typedef struct X86RegisterInfo32 {
> > @@ -3696,7 +3717,15 @@ static uint32_t
> > x86_cpu_get_supported_feature_word(FeatureWord w,
> >  wi-
> > >cpuid.reg);
> >  break;
> >  case MSR_FEATURE_WORD:
> > -r = kvm_arch_get_supported_msr_feature(kvm_state, wi-
> > >msr.index);
> > +/* Special case:
> > + * No matter host status, IA32_ARCH_CAPABILITIES.RSBA
> > [bit 2]
> > + * is always supported in guest.
> > + */
> > +if (wi->msr.index == MSR_IA32_ARCH_CAPABILITIES) {
> > +r = MSR_ARCH_CAP_RSBA;
> > +}
> > +r |= kvm_arch_get_supported_msr_feature(kvm_state,
> > +wi->msr.index);
> >  break;
After I add the filtering out MSR feature, whose CPUID dependency fails
, in x86_cpu_filter_features(), 1 issue comes out here: 

If running on an old platform that doesn't have ARCH_CAPABILITIES MSR,
but we still pretends it here, then qemu will always print out
"warning: host doesn't support requested feature: MSR(10AH).rsba [bit
2]", with -cpu 'host', which does not look comfortable.
How about remove this hunk for now? leave it to when we fully decide
how to handle ARCH_CAPABILITIES live-migration safely. 
> >  }
> >  } else if (hvf_enabled()) {
[...]



Re: [Qemu-devel] [PULL v2 00/28] pci, pc, virtio: fixes, features

2018-10-25 Thread Michael S. Tsirkin
On Thu, Oct 25, 2018 at 08:16:44PM +0100, Peter Maydell wrote:
> On 25 October 2018 at 01:52, Michael S. Tsirkin  wrote:
> > The following changes since commit 13399aad4fa87b2878c49d02a5d3bafa6c966ba3:
> >
> >   Merge remote-tracking branch 'remotes/armbru/tags/pull-error-2018-10-22' 
> > into staging (2018-10-23 17:20:23 +0100)
> >
> > are available in the Git repository at:
> >
> >   git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
> >
> > for you to fetch changes up to 6a9fb4e1ba5594cde7739068617ad88e6117db93:
> >
> >   vhost-scsi: prevent using uninitialized vqs (2018-10-24 20:50:13 -0400)
> >
> > 
> > pci, pc, virtio: fixes, features
> >
> > AMD IOMMU VAPIC support + fixes all over the place.
> >
> > Signed-off-by: Michael S. Tsirkin 
> 
> Hi; I get some compile failures and a test assertion, I'm afraid:

OK  I fixed 32 bit issues. Could not reproduce the test issues,
could it be that it was a side effect of build issues maybe?

Could you retyr?
If it still ails I will drop the test for now.

Thanks!

-- 
MST



Re: [Qemu-devel] [PULL v2 00/28] pci, pc, virtio: fixes, features

2018-10-25 Thread Michael S. Tsirkin
On Thu, Oct 25, 2018 at 08:16:44PM +0100, Peter Maydell wrote:
> On 25 October 2018 at 01:52, Michael S. Tsirkin  wrote:
> > The following changes since commit 13399aad4fa87b2878c49d02a5d3bafa6c966ba3:
> >
> >   Merge remote-tracking branch 'remotes/armbru/tags/pull-error-2018-10-22' 
> > into staging (2018-10-23 17:20:23 +0100)
> >
> > are available in the Git repository at:
> >
> >   git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
> >
> > for you to fetch changes up to 6a9fb4e1ba5594cde7739068617ad88e6117db93:
> >
> >   vhost-scsi: prevent using uninitialized vqs (2018-10-24 20:50:13 -0400)
> >
> > 
> > pci, pc, virtio: fixes, features
> >
> > AMD IOMMU VAPIC support + fixes all over the place.
> >
> > Signed-off-by: Michael S. Tsirkin 
> Looking for expected file 'tests/acpi-test-data/q35/SRAT.mmio64'
> 
> Looking for expected file 'tests/acpi-test-data/q35/SRAT'
> **
> ERROR:/home/petmay01/linaro/qemu-for-merges/tests/bios-tables-test.c:398:load_expected_aml:
> assertion failed: (exp_sdt.aml_file)
> FAIL
> 
> 
> thanks
> -- PMM

Stumped by this one. Doesn't SRAT.mmio64 exist for you?

-- 
MST



[Qemu-devel] [PATCH RFC 4/4] net/slirp: add ipv6-hostfwd option for user netdev type

2018-10-25 Thread Maxim Samoylov
This allows forwarding TCP6 and UDP6 connections down to
netdev=user connected guests.

Signed-off-by: Maxim Samoylov 
---
 hmp-commands.hx |  31 
 include/net/slirp.h |   2 +
 net/slirp.c | 214 
 qapi/net.json   |   3 +-
 4 files changed, 249 insertions(+), 1 deletion(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index db0c681..b0e1a08 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1448,6 +1448,37 @@ STEXI
 Remove host-to-guest TCP or UDP redirection.
 ETEXI
 
+#ifdef CONFIG_SLIRP
+{
+.name   = "ipv6_hostfwd_add",
+.args_type  = "arg1:s,arg2:s?,arg3:s?",
+.params = "[hub_id name]|[netdev_id] 
[tcp|udp]:[hostaddr6]:hostport-guestaddr6:guestport",
+.help   = "redirect TCP6 or UDP6 connections from host to guest 
(requires -net user)",
+.cmd= hmp_ipv6_hostfwd_add,
+},
+#endif
+STEXI
+@item hostfwd_add
+@findex hostfwd_add
+Redirect TCP6 or UDP6 connections from host to guest (requires -net user).
+ETEXI
+
+#ifdef CONFIG_SLIRP
+{
+.name   = "ipv6_hostfwd_remove",
+.args_type  = "arg1:s,arg2:s?,arg3:s?",
+.params = "[hub_id name]|[netdev_id] 
[tcp|udp]:[hostaddr6]:hostport",
+.help   = "remove host-to-guest TCP6 or UDP6 redirection",
+.cmd= hmp_ipv6_hostfwd_remove,
+},
+
+#endif
+STEXI
+@item hostfwd_remove
+@findex hostfwd_remove
+Remove host-to-guest TCP6 or UDP6 redirection.
+ETEXI
+
 {
 .name   = "balloon",
 .args_type  = "value:M",
diff --git a/include/net/slirp.h b/include/net/slirp.h
index bad3e1e..4796a5c 100644
--- a/include/net/slirp.h
+++ b/include/net/slirp.h
@@ -29,6 +29,8 @@
 
 void hmp_hostfwd_add(Monitor *mon, const QDict *qdict);
 void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict);
+void hmp_ipv6_hostfwd_add(Monitor *mon, const QDict *qdict);
+void hmp_ipv6_hostfwd_remove(Monitor *mon, const QDict *qdict);
 
 void hmp_info_usernet(Monitor *mon, const QDict *qdict);
 
diff --git a/net/slirp.c b/net/slirp.c
index f6dc039..abe112b 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -67,6 +67,7 @@ static int get_str_sep(char *buf, int buf_size, const char 
**pp, int sep)
 /* slirp network adapter */
 
 #define SLIRP_CFG_HOSTFWD 1
+#define SLIRP_CFG_IPV6_HOSTFWD 2
 
 struct slirp_config_str {
 struct slirp_config_str *next;
@@ -89,6 +90,8 @@ static QTAILQ_HEAD(slirp_stacks, SlirpState) slirp_stacks =
 QTAILQ_HEAD_INITIALIZER(slirp_stacks);
 
 static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp);
+static int slirp_ipv6_hostfwd(SlirpState *s, const char *redir_str,
+  Error **errp);
 static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp);
 
 #ifndef _WIN32
@@ -386,6 +389,10 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 if (slirp_hostfwd(s, config->str, errp) < 0) {
 goto error;
 }
+} else if (config->flags & SLIRP_CFG_IPV6_HOSTFWD) {
+if (slirp_ipv6_hostfwd(s, config->str, errp) < 0) {
+goto error;
+}
 } else {
 if (slirp_guestfwd(s, config->str, errp) < 0) {
 goto error;
@@ -504,6 +511,73 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
 monitor_printf(mon, "invalid format\n");
 }
 
+void hmp_ipv6_hostfwd_remove(Monitor *mon, const QDict *qdict)
+{
+struct in6_addr host_addr = in6addr_any;
+int host_port;
+char buf[256];
+const char *src_str, *p;
+SlirpState *s;
+int is_udp = 0;
+int err;
+const char *arg1 = qdict_get_str(qdict, "arg1");
+const char *arg2 = qdict_get_try_str(qdict, "arg2");
+const char *arg3 = qdict_get_try_str(qdict, "arg3");
+
+if (arg2) {
+s = slirp_lookup(mon, arg1, arg2);
+src_str = arg3;
+} else {
+s = slirp_lookup(mon, NULL, NULL);
+src_str = arg1;
+}
+if (!s) {
+return;
+}
+
+p = src_str;
+if (!p || get_str_sep(buf, sizeof(buf), , ':') < 0) {
+goto fail_syntax;
+}
+
+if (!strcmp(buf, "tcp") || buf[0] == '\0') {
+is_udp = 0;
+} else if (!strcmp(buf, "udp")) {
+is_udp = 1;
+} else {
+goto fail_syntax;
+}
+
+if (*(p++) != '[') {
+goto fail_syntax;
+}
+
+if (get_str_sep(buf, sizeof(buf), , ']') < 0) {
+goto fail_syntax;
+}
+
+if (!inet_pton(AF_INET6, buf, _addr)) {
+goto fail_syntax;
+}
+
+if (get_str_sep(buf, sizeof(buf), , ':') < 0) {
+goto fail_syntax;
+}
+
+if (qemu_strtoi(p, NULL, 10, _port) < 0) {
+goto fail_syntax;
+}
+
+err = slirp_remove_ipv6_hostfwd(s->slirp, is_udp, host_addr, host_port);
+
+monitor_printf(mon, "host forwarding rule for %s %s\n", src_str,
+   err ? "not found" : "removed");
+return;
+
+ 

[Qemu-devel] [PATCH RFC 3/4] slirp: add helpers for ipv6 hostfwd manipulation

2018-10-25 Thread Maxim Samoylov
Signed-off-by: Maxim Samoylov 
---
 slirp/libslirp.h |  6 ++
 slirp/slirp.c| 43 +++
 2 files changed, 49 insertions(+)

diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 42e42e9..3710650 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -34,6 +34,12 @@ 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_ipv6_hostfwd(Slirp *slirp, int is_udp,
+   struct in6_addr host_addr, int host_port,
+   struct in6_addr guest_addr, int guest_port);
+int slirp_remove_ipv6_hostfwd(Slirp *slirp, int is_udp,
+  struct in6_addr host_addr, int host_port);
+
 int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
struct in_addr *guest_addr, int guest_port);
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 51de41f..143ddea 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -1065,6 +1065,49 @@ int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct 
in_addr host_addr,
 return 0;
 }
 
+int slirp_remove_ipv6_hostfwd(Slirp *slirp, int is_udp,
+  struct in6_addr host_addr, int host_port)
+{
+struct socket *so;
+struct socket *head = (is_udp ? >udb : >tcb);
+struct sockaddr_in6 addr;
+int port = htons(host_port);
+socklen_t addr_len;
+
+for (so = head->so_next; so != head; so = so->so_next) {
+addr_len = sizeof(addr);
+if ((so->so_state & SS_HOSTFWD) &&
+getsockname(so->s, (struct sockaddr *), _len) == 0 &&
+addr_len == sizeof(host_addr) &&
+!memcmp(_addr, , addr_len) &&
+addr.sin6_port == port) {
+
+close(so->s);
+sofree(so);
+return 0;
+}
+}
+
+return -1;
+}
+
+int slirp_add_ipv6_hostfwd(Slirp *slirp, int is_udp,
+  struct in6_addr host_addr, int host_port,
+  struct in6_addr guest_addr, int guest_port)
+{
+if (is_udp) {
+if (!udp6_listen(slirp, host_addr, htons(host_port),
+ guest_addr, htons(guest_port), SS_HOSTFWD))
+return -1;
+} else {
+if (!tcp6_listen(slirp, host_addr, htons(host_port),
+ guest_addr, htons(guest_port), SS_HOSTFWD))
+return -1;
+}
+
+return 0;
+}
+
 int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
struct in_addr *guest_addr, int guest_port)
 {
-- 
2.7.4




[Qemu-devel] [PATCH RFC 2/4] slirp: add helper for udp6 socket creation

2018-10-25 Thread Maxim Samoylov
Signed-off-by: Maxim Samoylov 
---
 slirp/udp.c | 48 
 slirp/udp.h |  2 ++
 2 files changed, 50 insertions(+)

diff --git a/slirp/udp.c b/slirp/udp.c
index e5bf065..ab24935 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -366,3 +366,51 @@ udp_listen(Slirp *slirp, uint32_t haddr, u_int hport, 
uint32_t laddr,
 
return so;
 }
+
+struct socket *
+udp6_listen(Slirp *slirp, struct in6_addr haddr, u_int hport,
+struct in6_addr laddr, u_int lport, int flags)
+{
+struct sockaddr_in6 addr;
+struct socket *so;
+socklen_t addrlen = sizeof(addr);
+
+memset(, 0, sizeof(addr));
+
+so = socreate(slirp);
+if (!so) {
+return NULL;
+}
+so->s = qemu_socket(AF_INET6, SOCK_DGRAM, 0);
+if (so->s < 0) {
+sofree(so);
+return NULL;
+}
+so->so_expire = curtime + SO_EXPIRE;
+insque(so, >udb);
+
+addr.sin6_family = AF_INET6;
+addr.sin6_addr = haddr;
+addr.sin6_port = hport;
+
+if (bind(so->s, (struct sockaddr *), addrlen) < 0) {
+udp_detach(so);
+return NULL;
+}
+socket_set_fast_reuse(so->s);
+
+getsockname(so->s, (struct sockaddr *), );
+so->fhost.sin6 = addr;
+sotranslate_accept(so);
+so->so_lfamily = AF_INET6;
+so->so_lport = lport;
+so->so_laddr6 = laddr;
+if (flags != SS_FACCEPTONCE) {
+so->so_expire = 0;
+}
+
+so->so_state &= SS_PERSISTENT_MASK;
+so->so_state |= SS_ISFCONNECTED | flags;
+
+return so;
+}
diff --git a/slirp/udp.h b/slirp/udp.h
index be657cf..862c6e8 100644
--- a/slirp/udp.h
+++ b/slirp/udp.h
@@ -80,6 +80,8 @@ int udp_attach(struct socket *, unsigned short af);
 void udp_detach(struct socket *);
 struct socket * udp_listen(Slirp *, uint32_t, u_int, uint32_t, u_int,
int);
+struct socket *udp6_listen(Slirp *slirp, struct in6_addr, u_int,
+struct in6_addr, u_int, int);
 int udp_output(struct socket *so, struct mbuf *m,
 struct sockaddr_in *saddr, struct sockaddr_in *daddr,
 int iptos);
-- 
2.7.4




[Qemu-devel] [PATCH RFC 1/4] slirp: add helper for tcp6 socket creation

2018-10-25 Thread Maxim Samoylov
Signed-off-by: Maxim Samoylov 
---
 slirp/socket.c | 73 ++
 slirp/socket.h |  2 ++
 2 files changed, 75 insertions(+)

diff --git a/slirp/socket.c b/slirp/socket.c
index 322383a..e16e6c1 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -776,6 +776,79 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, 
uint32_t laddr,
return so;
 }
 
+struct socket *
+tcp6_listen(Slirp *slirp, struct in6_addr haddr, u_int hport,
+struct in6_addr laddr, u_int lport, int flags)
+{
+struct sockaddr_in6 addr;
+struct socket *so;
+int s, opt = 1;
+socklen_t addrlen = sizeof(addr);
+memset(, 0, addrlen);
+
+/* The same flow as in tcp_listen above */
+
+so = socreate(slirp);
+if (!so) {
+return NULL;
+}
+
+so->so_tcpcb = tcp_newtcpcb(so);
+if (so->so_tcpcb == NULL) {
+free(so);
+return NULL;
+}
+
+insque(so, >tcb);
+
+if (flags & SS_FACCEPTONCE) {
+so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT * 2;
+}
+
+so->so_state &= SS_PERSISTENT_MASK;
+so->so_state |= (SS_FACCEPTCONN | flags);
+so->so_lfamily = AF_INET6;
+so->so_lport6 = lport; /* Kept in network format */
+so->so_laddr6 = laddr;
+
+addr.sin6_family = AF_INET6;
+addr.sin6_addr = haddr;
+addr.sin6_port = hport;
+
+s = qemu_socket(AF_INET6, SOCK_STREAM, 0);
+if ((s < 0) ||
+(socket_set_fast_reuse(s) < 0) ||
+(bind(s, (struct sockaddr *), sizeof(addr)) < 0) ||
+(listen(s, 1) < 0)) {
+int tmperrno = errno; /* Don't clobber the real reason we failed */
+if (s >= 0) {
+closesocket(s);
+}
+sofree(so);
+/* Restore the real errno */
+#ifdef _WIN32
+WSASetLastError(tmperrno);
+#else
+errno = tmperrno;
+#endif
+return NULL;
+}
+qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, , sizeof(int));
+
+getsockname(s, (struct sockaddr *), );
+so->fhost.sin6 = addr;
+
+if (!memcmp(_addr, _any, sizeof(in6addr_any)) ||
+!memcmp(_addr, _loopback,
+sizeof(in6addr_loopback))) {
+
+memcpy(>so_faddr6, >vhost_addr6, 
sizeof(slirp->vhost_addr6));
+}
+
+so->s = s;
+return so;
+}
+
 /*
  * Various session state calls
  * XXX Should be #define's
diff --git a/slirp/socket.h b/slirp/socket.h
index 2f224bc..b200bb6 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -144,6 +144,8 @@ void sorecvfrom(struct socket *);
 int sosendto(struct socket *, struct mbuf *);
 struct socket * tcp_listen(Slirp *, uint32_t, u_int, uint32_t, u_int,
int);
+struct socket *tcp6_listen(Slirp *, struct in6_addr, u_int,
+   struct in6_addr, u_int, int);
 void soisfconnecting(register struct socket *);
 void soisfconnected(register struct socket *);
 void sofwdrain(struct socket *);
-- 
2.7.4




[Qemu-devel] [PATCH RFC 0/4] slirp: support hostfwd for ipv6 addresses

2018-10-25 Thread Maxim Samoylov
The following patch implements ipv6 host port forwarding support
for qemu slirp net subsystem.

The slirp itself supports ipv6 communication, but
hostfwd currently does not allow listening on and forwarding
ports for ipv6 addresses.

This should be useful, when host works in v6-capable environment
and guests should be accessible there.

Turns out the only thing should be done is to properly parse 
ipv6 addresses and pass them down to listening socket create logic.

The proposed option ipv6-hostfwd syntax is the same as for the hostfwd option,
but one should enclose their ipv6 addresses into square brackets, e.g.:

ipv6-hostfwd=tcp::7255-[fec0::5054:ff:fe12:3456]:80

The guest ipv6 address intended to be specified explicitly,
because there is no dhcpv6 server in slirp.


Maxim Samoylov (4):
  slirp: add helper for tcp6 socket creation
  slirp: add helper for udp6 socket creation
  slirp: add helpers for ipv6 hostfwd manipulation
  net/slirp: add ipv6-hostfwd option for user netdev type

 hmp-commands.hx |  31 
 include/net/slirp.h |   2 +
 net/slirp.c | 214 
 qapi/net.json   |   3 +-
 slirp/libslirp.h|   6 ++
 slirp/slirp.c   |  43 +++
 slirp/socket.c  |  73 ++
 slirp/socket.h  |   2 +
 slirp/udp.c |  48 
 slirp/udp.h |   2 +
 10 files changed, 423 insertions(+), 1 deletion(-)

-- 
2.7.4




Re: [Qemu-devel] [PULL v2 00/28] pci, pc, virtio: fixes, features

2018-10-25 Thread Michael S. Tsirkin
On Thu, Oct 25, 2018 at 08:16:44PM +0100, Peter Maydell wrote:
> On 25 October 2018 at 01:52, Michael S. Tsirkin  wrote:
> > The following changes since commit 13399aad4fa87b2878c49d02a5d3bafa6c966ba3:
> >
> >   Merge remote-tracking branch 'remotes/armbru/tags/pull-error-2018-10-22' 
> > into staging (2018-10-23 17:20:23 +0100)
> >
> > are available in the Git repository at:
> >
> >   git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
> >
> > for you to fetch changes up to 6a9fb4e1ba5594cde7739068617ad88e6117db93:
> >
> >   vhost-scsi: prevent using uninitialized vqs (2018-10-24 20:50:13 -0400)
> >
> > 
> > pci, pc, virtio: fixes, features
> >
> > AMD IOMMU VAPIC support + fixes all over the place.
> >
> > Signed-off-by: Michael S. Tsirkin 
> 
> Hi; I get some compile failures and a test assertion, I'm afraid:
> 
> On 32-bit hosts (where uint64_t and size_t are not the same):
> 
> /home/peter.maydell/qemu/include/qemu/compiler.h:80:35: error: invalid
> operands to binary - (have 'uint64_t * {aka long long unsigned int *}'
> and 'size_t * {aka unsigned int *}')
>  #define type_check(t1,t2) ((t1*)0 - (t2*)0)
>^
> /home/peter.maydell/qemu/include/hw/qdev-properties.h:77:15: note: in
> expansion of macro 'type_check'
>  + type_check(_type, typeof_field(_state, _field)),  \
>^
> /home/peter.maydell/qemu/include/hw/qdev-properties.h:168:5: note: in
> expansion of macro 'DEFINE_PROP_UNSIGNED'
>  DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_size, uint64_t)
>  ^
> /home/peter.maydell/qemu/hw/misc/pci-testdev.c:322:5: note: in
> expansion of macro 'DEFINE_PROP_SIZE'
>  DEFINE_PROP_SIZE("membar", PCITestDevState, membar_size, 0),
>  ^
> /home/peter.maydell/qemu/rules.mak:69: recipe for target
> 'hw/misc/pci-testdev.o' failed
> 
> On the Windows w64 cross-compile:
> 
> In file included from /home/petmay01/qemu-for-merges/hw/i386/amd_iommu.c:26:0:
> /home/petmay01/qemu-for-merges/hw/i386/amd_iommu.c: In function
> 'amdvi_int_remap_msi':
> /home/petmay01/qemu-for-merges/hw/i386/amd_iommu.h:247:46: error: left
> shift count >= width of type [-Werror=shift-count-overflow]
>  #define AMDVI_DEV_NMI_PASS_MASK (1UL << 58)
>   ^
> /home/petmay01/qemu-for-merges/hw/i386/amd_iommu.c:1281:25: note: in
> expansion of macro 'AMDVI_DEV_NMI_PASS_MASK'
>  pass = dte[3] & AMDVI_DEV_NMI_PASS_MASK;
>  ^
> /home/petmay01/qemu-for-merges/hw/i386/amd_iommu.h:245:46: error: left
> shift count >= width of type [-Werror=shift-count-overflow]
>  #define AMDVI_DEV_INT_PASS_MASK (1UL << 56)
>   ^
> /home/petmay01/qemu-for-merges/hw/i386/amd_iommu.c:1285:25: note: in
> expansion of macro 'AMDVI_DEV_INT_PASS_MASK'
>  pass = dte[3] & AMDVI_DEV_INT_PASS_MASK;
>  ^
> /home/petmay01/qemu-for-merges/hw/i386/amd_iommu.h:246:46: error: left
> shift count >= width of type [-Werror=shift-count-overflow]
>  #define AMDVI_DEV_EINT_PASS_MASK(1UL << 57)
>   ^
> /home/petmay01/qemu-for-merges/hw/i386/amd_iommu.c:1289:25: note: in
> expansion of macro 'AMDVI_DEV_EINT_PASS_MASK'
>  pass = dte[3] & AMDVI_DEV_EINT_PASS_MASK;
>  ^
> 
> These should presumably all be "ULL". (The "UL" suffix is
> usually a bug, as it's either unnecessary or should be ULL.)

Yea.  Fixed. Brijesh could you start cleaning up that header generally?
It has all kind of weird code like using bitfields for hardware
accesses. That isn't portable - switch to full dword fields with shift
and | to operate them and proper cpu_to_le APIs or similar please.

> On various Linux hosts (aarch64, s390, x86-64, sparc)
> I get this assertion in the bios-tables-test:
> 
>   /x86_64/acpi/q35/mmio64:
> Looking for expected file 'tests/acpi-test-data/q35/DSDT.mmio64'
> 
> Looking for expected file 'tests/acpi-test-data/q35/DSDT'
> 
> Using expected file 'tests/acpi-test-data/q35/DSDT'
> 
> Looking for expected file 'tests/acpi-test-data/q35/FACP.mmio64'
> 
> Looking for expected file 'tests/acpi-test-data/q35/FACP'
> 
> Using expected file 'tests/acpi-test-data/q35/FACP'
> 
> Looking for expected file 'tests/acpi-test-data/q35/APIC.mmio64'
> 
> Looking for expected file 'tests/acpi-test-data/q35/APIC'
> 
> Using expected file 'tests/acpi-test-data/q35/APIC'
> 
> Looking for expected file 'tests/acpi-test-data/q35/HPET.mmio64'
> 
> Looking for expected file 'tests/acpi-test-data/q35/HPET'
> 
> Using expected file 'tests/acpi-test-data/q35/HPET'
> 
> Looking for expected file 'tests/acpi-test-data/q35/SRAT.mmio64'
> 
> Looking for expected file 'tests/acpi-test-data/q35/SRAT'
> **
> ERROR:/home/petmay01/linaro/qemu-for-merges/tests/bios-tables-test.c:398:load_expected_aml:
> assertion failed: 

Re: [Qemu-devel] [PATCH] lsi53c895a: check message length value

2018-10-25 Thread Paolo Bonzini
On 25/10/2018 22:09, P J P wrote:
> From: Prasad J Pandit 
> 
> While writing a message in 'lsi_do_msgin', message length value
> in msg_len could be invalid, add check to avoid OOB access issue.
> 
> Reported-by: Ameya More 
> Signed-off-by: Prasad J Pandit 
> ---
>  hw/scsi/lsi53c895a.c | 9 ++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
> index d1e6534311..a266c5a113 100644
> --- a/hw/scsi/lsi53c895a.c
> +++ b/hw/scsi/lsi53c895a.c
> @@ -205,7 +205,7 @@ typedef struct {
>  /* Action to take at the end of a MSG IN phase.
> 0 = COMMAND, 1 = disconnect, 2 = DATA OUT, 3 = DATA IN.  */
>  int msg_action;
> -int msg_len;
> +uint8_t msg_len;

Not wrong per se, but it's also not clear why it's needed.  I understand
that you want to switch from signed to unsigned, but it is not mentioned
in the commit message.

The switch to 8-bit, and below from VMSTATE_INT32 to VMSTATE_UINT8, is
wrong because it changes the format of the live migration stream.

>  uint8_t msg[LSI_MAX_MSGIN_LEN];
>  /* 0 if SCRIPTS are running or stopped.
>   * 1 if a Wait Reselect instruction has been issued.
> @@ -861,12 +861,15 @@ static void lsi_do_status(LSIState *s)
>  
>  static void lsi_do_msgin(LSIState *s)
>  {
> -int len;
> +uint8_t len;
>  trace_lsi_do_msgin(s->dbc, s->msg_len);
>  s->sfbr = s->msg[0];
>  len = s->msg_len;
>  if (len > s->dbc)
>  len = s->dbc;
> +if (len > LSI_MAX_MSGIN_LEN) {
> +len = LSI_MAX_MSGIN_LEN;
> +}

I'm not sure it's appropriate to check for out of bounds reads here,
because if s->msg_len is greater than LSI_MAX_MSGIN_LEN, then this test
doesn't exclude you've already had an out of bounds write before.
Indeed the msg_len is checked in lsi_add_msg_byte in order to avoid out
of bounds accesses in either lsi_add_msg_byte or lsi_do_msgin.  You
could assert here that the variable is in range, I guess.

However, the out of bounds s->msg_len can actually happen in one other
case: namely, if a malicious live migration stream includes a bogus
s->msg_len.  Such live migration stream should be rejected; the fix for
that is to add a lsi_post_load function, point to it in
vmstate_lsi_scsi, and check there for s->msg_len <= LSI_MAX_MSGIN_LEN.

Thanks,

Paolo

>  pci_dma_write(PCI_DEVICE(s), s->dnad, s->msg, len);
>  /* Linux drivers rely on the last byte being in the SIDL.  */
>  s->sidl = s->msg[len - 1];
> @@ -2114,7 +2117,7 @@ static const VMStateDescription vmstate_lsi_scsi = {
>  VMSTATE_INT32(carry, LSIState),
>  VMSTATE_INT32(status, LSIState),
>  VMSTATE_INT32(msg_action, LSIState),
> -VMSTATE_INT32(msg_len, LSIState),
> +VMSTATE_UINT8(msg_len, LSIState),
>  VMSTATE_BUFFER(msg, LSIState),
>  VMSTATE_INT32(waiting, LSIState),
>  
> 




[Qemu-devel] [Bug 1762707] Re: VFIO device gets DMA failures when virtio-balloon leak from highmem to lowmem

2018-10-25 Thread Alex Williamson
There are two scenarios here, if we have a regular, directly assigned
physical device (including VFs), vfio's page pinning will populate the
full memory footprint of the guest regardless of the balloon.  The
balloon is effectively fully deflated, but the balloon driver in the
guest hasn't released the pages back for guest kernel use.  In that case
marking the balloon as deflated at least allows those pages to be used
since they're allocated.  However, if the assigned device is an mdev
device, then the pages might only be pinned on usage, depending on the
vendor driver, and pages acquired by the guest balloon driver are
unlikely to be used by the in-guest driver for the device.  It's always
possible that the mdev vendor driver could pin them anyway, but there is
a chance that those pages are actually still freed to the host until
that point.  Latest QEMU will of course enable the  balloon inhibitor
for either case so further balloon inflation will no longer zap pages.

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

Title:
  VFIO device gets DMA failures when virtio-balloon leak from highmem to
  lowmem

Status in QEMU:
  Invalid

Bug description:
  Is there any known conflict between VFIO passthrough device and
  virtio-balloon?

  The VM has:
  1. 4GB system memory
  2. one VFIO passthrough device which supports high address memory DMA and 
uses GFP_HIGHUSER pages.
  3. Memory balloon device with 4GB target.

  When setting the memory balloon target to 1GB and 4GB in loop during
  runtime (I used the command "virsh qemu-monitor-command debian --hmp
  --cmd balloon 1024"), the VFIO device DMA randomly gets failure.

  More clues:
  1. configure 2GB system memory (no highmem) VM, no issue with similar 
operations
  2. setting the memory balloon to higher like 8GB, no issue with similar 
operations

  I'm also trying to narrow down this issue. It's appreciated for that
  you guys may share some thoughts.

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



[Qemu-devel] [Bug 1762707] Re: VFIO device gets DMA failures when virtio-balloon leak from highmem to lowmem

2018-10-25 Thread Jose Carlos Venegas Munoz
Alex, I see this issue is closed but I have a question, do you know if
the problem only comes the balloon is resized to return memory to the
host. I ask because we have a situation where we will start a VM with
balloon enabled, and later it maybe possible a devices is assigned via
hot-plug. So I would like to avoid this issue by doing the following:

if a vfio devices is assigned;
   resize the balloon size the the maximal guest memory
end 

Then because we know we added a vfio devices never resize the balloon to
return memory again.

More information about what we want to do: https://github.com/kata-
containers/runtime/pull/793

Regards,
Carlos

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

Title:
  VFIO device gets DMA failures when virtio-balloon leak from highmem to
  lowmem

Status in QEMU:
  Invalid

Bug description:
  Is there any known conflict between VFIO passthrough device and
  virtio-balloon?

  The VM has:
  1. 4GB system memory
  2. one VFIO passthrough device which supports high address memory DMA and 
uses GFP_HIGHUSER pages.
  3. Memory balloon device with 4GB target.

  When setting the memory balloon target to 1GB and 4GB in loop during
  runtime (I used the command "virsh qemu-monitor-command debian --hmp
  --cmd balloon 1024"), the VFIO device DMA randomly gets failure.

  More clues:
  1. configure 2GB system memory (no highmem) VM, no issue with similar 
operations
  2. setting the memory balloon to higher like 8GB, no issue with similar 
operations

  I'm also trying to narrow down this issue. It's appreciated for that
  you guys may share some thoughts.

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



Re: [Qemu-devel] [RFC 0/2] Attempt to implement the standby feature for assigned network devices

2018-10-25 Thread Michael S. Tsirkin
On Thu, Oct 25, 2018 at 05:06:29PM +0300, Sameeh Jubran wrote:
> From: Sameeh Jubran 
> 
> Hi all,
> 
> Background:
> 
> There has been a few attempts to implement the standby feature for vfio
> assigned devices which aims to enable the migration of such devices. This
> is another attempt.
> 
> The series implements an infrastructure for hiding devices from the bus
> upon boot. What it does is the following:
> 
> * In the first patch the infrastructure for hiding the device is added
>   for the qbus and qdev APIs. A "hidden" boolean is added to the device
>   state and it is set based on a callback to the standby device which
>   registers itself for handling the assessment: "should the primary device
>   be hidden?" by cross validating the ids of the devices.
> 
> * In the second patch the virtio-net uses the API to hide the vfio
>   device and unhides it when the feature is acked.
> 
> Disclaimers:
> 
> * I have only scratch tested this and from qemu side, it seems to be
>   working.
> * This is an RFC so it lacks some proper error handling in few cases
>   and proper resource freeing. I wanted to get some feedback first
>   before it is finalized.
> 
> Command line example:
> 
> /home/sameeh/Builds/failover/qemu/x86_64-softmmu/qemu-system-x86_64 \
> -netdev 
> tap,id=hostnet0,script=world_bridge_standalone.sh,downscript=no,ifname=cc1_71 
> \
> -netdev 
> tap,vhost=on,id=hostnet1,script=world_bridge_standalone.sh,downscript=no,ifname=cc1_72,queues=4
>  \
> -device 
> virtio-net,host_mtu=1500,netdev=hostnet1,id=cc1_72,vectors=10,mq=on,primary=cc1_71
>  \
> -device e1000,netdev=hostnet0,id=cc1_71,standby=cc1_72 \
> 
> Migration support:
> 
> Pre migration or during setup phase of the migration we should send an
> unplug request to the guest to unplug the primary device. I haven't had
> the chance to implement that part yet but should do soon. Do you know
> what's the best approach to do so? I wanted to have a callback to the
> virtio-net device which tries to send an unplug request to the guest and
> if succeeds then the migration continues. It needs to handle the case where
> the migration fails and then it has to replug the primary device back.
> 
> The following terms are used as interchangeable:
> standby - virtio-net
> primary - vfio-device - physical device - assigned device
> 
> Please share your thoughts and suggestions,
> Thanks!

Didn't have time to look at code yet. Could you test with a VF please?
That's the real test, isn't it?

> Sameeh Jubran (2):
>   qdev/qbus: Add hidden device support
>   virtio-net: Implement VIRTIO_NET_F_STANDBY feature
> 
>  hw/core/qdev.c | 48 +---
>  hw/net/virtio-net.c| 25 +++
>  hw/pci/pci.c   |  1 +
>  include/hw/pci/pci.h   |  2 ++
>  include/hw/qdev-core.h | 11 ++-
>  include/hw/virtio/virtio-net.h |  5 +++
>  qdev-monitor.c | 58 --
>  7 files changed, 142 insertions(+), 8 deletions(-)
> 
> -- 
> 2.17.0



Re: [Qemu-devel] Call for patches for the qemu-trivial pull request

2018-10-25 Thread Laurent Vivier
On 25/10/2018 21:13, Thomas Huth wrote:
> On 2018-10-23 11:04, Laurent Vivier wrote:
>> Hi,
>>
>> I'm going to collect patches for the next pull request for the
>> qemu-trivial I'd like to do before the softfreeze.
>>
>> As we didn't have any pull request for more than 3 months and some of
>> the patches have been pushed through another maintainer branches, it's a
>> little bit difficult to collect correctly the patches to send.
>>
>> So, it would be helpful if any of you knowing that some patches have to
>> be added to the pull request send me their list.
> 
> For June to September, I'd like to suggest:
> 
>  cpu.h: fix a typo in comment
>  https://lists.nongnu.org/archive/html/qemu-trivial/2018-09/msg00021.html

applied

> 
>  linux-user: fix comment s/atomic_write/atomic_set
>  https://lists.nongnu.org/archive/html/qemu-trivial/2018-08/msg00017.html

applied

> 
>  tests: Fix typos in comments and help message (found by codespell)
>  https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg00039.html

applied

> 
>  configure: Support pkg-config for zlib
>  https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg00032.html
>  (this had a suggestion for dropping the fallback test, but I think
>  that could be done as an additional patch after the next release instead)
> 

applied

>  qobject: Catch another straggler for use of qdict_put_str()
>  https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg6.html

applied

> 
>  xen: Use the PCI_DEVICE macro
>  https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg8.html

applied

> 
>  tests/bios-tables-test: Remove an useless cast
>  https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg9.html

applied

> 
>  hw/pci-host: Remove useless parenthesis around DIV_ROUND_UP macro
>  https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg00011.html
> 

applied

>  hw/intc/gicv3: Remove useless parenthesis around DIV_ROUND_UP macro
>  https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg00012.html

applied

> 
>  dump: fix a typo
>  https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg2.html

I don't find it in patchwork.

> 
>  milkymist-minimac2: Use qemu_log_mask(GUEST_ERROR) instead of error_report
>  https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg1.html

applied

> 
>  Makefile: Remove qemu-version.h and qemu-options.def during 'make distclean'
>  https://lists.nongnu.org/archive/html/qemu-trivial/2018-06/msg00050.html
> 

doesn't apply cleanly. not applied.

>  ppc: move at24c to its own CONFIG_ symbol
>  https://lists.nongnu.org/archive/html/qemu-trivial/2018-05/msg00118.html

applied

> 
> Additionally you could also include the reviewed patches from the the
> "use qemu_log_mask instead of fprintf" series here:
> https://lists.nongnu.org/archive/html/qemu-trivial/2018-06/msg00276.html

I'll see later for these ones...

Thanks
Laurent



Re: [Qemu-devel] [PATCH] lsi53c895a: check message length value

2018-10-25 Thread Ameya More

Hi Prasad,

Thanks for following up on this. While Mark and I reported this issue to 
you, it was actually discovered by Dejvau Security and they should 
receive credit for reporting this issue.

http://www.dejavusecurity.com

Thanks,
Ameya


On 10/25/2018 03:09 PM, P J P wrote:

From: Prasad J Pandit 

While writing a message in 'lsi_do_msgin', message length value
in msg_len could be invalid, add check to avoid OOB access issue.

Reported-by: Ameya More 
Signed-off-by: Prasad J Pandit 
---
  hw/scsi/lsi53c895a.c | 9 ++---
  1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index d1e6534311..a266c5a113 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -205,7 +205,7 @@ typedef struct {
  /* Action to take at the end of a MSG IN phase.
 0 = COMMAND, 1 = disconnect, 2 = DATA OUT, 3 = DATA IN.  */
  int msg_action;
-int msg_len;
+uint8_t msg_len;
  uint8_t msg[LSI_MAX_MSGIN_LEN];
  /* 0 if SCRIPTS are running or stopped.
   * 1 if a Wait Reselect instruction has been issued.
@@ -861,12 +861,15 @@ static void lsi_do_status(LSIState *s)
  
  static void lsi_do_msgin(LSIState *s)

  {
-int len;
+uint8_t len;
  trace_lsi_do_msgin(s->dbc, s->msg_len);
  s->sfbr = s->msg[0];
  len = s->msg_len;
  if (len > s->dbc)
  len = s->dbc;
+if (len > LSI_MAX_MSGIN_LEN) {
+len = LSI_MAX_MSGIN_LEN;
+}
  pci_dma_write(PCI_DEVICE(s), s->dnad, s->msg, len);
  /* Linux drivers rely on the last byte being in the SIDL.  */
  s->sidl = s->msg[len - 1];
@@ -2114,7 +2117,7 @@ static const VMStateDescription vmstate_lsi_scsi = {
  VMSTATE_INT32(carry, LSIState),
  VMSTATE_INT32(status, LSIState),
  VMSTATE_INT32(msg_action, LSIState),
-VMSTATE_INT32(msg_len, LSIState),
+VMSTATE_UINT8(msg_len, LSIState),
  VMSTATE_BUFFER(msg, LSIState),
  VMSTATE_INT32(waiting, LSIState),
  





Re: [Qemu-devel] [libvirt] [PATCH 2/3] adlib: mark as insecure and deprecated.

2018-10-25 Thread Daniel P . Berrangé
On Thu, Oct 25, 2018 at 04:26:16PM +0530, P J P wrote:
> +-- On Thu, 25 Oct 2018, Gerd Hoffmann wrote --+
> | We have a lovely, guest-triggerable buffer overflow in opl2 emulation.
> | 
> | Reproducer:
> | outw(0xff60, 0x220);
> | outw(0x1020, 0x220);
> | outw(0xffb0, 0x220);
> | Result:
> | Will overflow FM_OPL->AR_TABLE[] (see hw/audio/fmopl.[ch])
> 
> + Reported-by: Wangjunqing 

So you have a CVE number for this ?

If so, it should be referenced in the commit message too, even if
we can't fix the problem.

> | diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c
> | index 97b876c..fb4a29c 100644
> | --- a/hw/audio/adlib.c
> | +++ b/hw/audio/adlib.c
> | @@ -311,6 +311,7 @@ static void adlib_class_initfn (ObjectClass *klass, 
> void *data)
> |  set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
> |  dc->desc = ADLIB_DESC;
> |  dc->props = adlib_properties;
> | +dc->deprecation_reason = "insecure, buffer overflow in opl2 emulation";
> |  }
> |  
> |  static const TypeInfo adlib_info = {
> | diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi
> | index 11b870c..7951a4f 100644
> | --- a/qemu-deprecated.texi
> | +++ b/qemu-deprecated.texi
> | @@ -116,6 +116,10 @@ The @option{[hub_id name]} parameter tuple of the 
> 'hostfwd_add' and
> |  The ``ivshmem'' device type is replaced by either the ``ivshmem-plain''
> |  or ``ivshmem-doorbell`` device types.
> |  
> | +@subsection adlib (since 3.1)
> | +
> | +Has known buffer overflow.

It would be good to give a recommendation to a better choice to
replace its usage

> | +
> |  @section System emulator machines
> |  
> |  @subsection pc-0.10 and pc-0.11 (since 3.0)

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 :|



Re: [Qemu-devel] [PATCH 3/3] cirrus: mark as deprecated

2018-10-25 Thread Daniel P . Berrangé
On Thu, Oct 25, 2018 at 10:52:56AM +0200, Gerd Hoffmann wrote:
> While being at it deprecate cirrus too.
> 
> Reason (short version): use stdvga instead.
> Verbose version:
> https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful

Every single one of my guests is using cirrus. This wasn't an explicit
choice on my part, so I believe it is being used as the default in
virt-install.

I don't debate the points in the blog post above that stdvga is a
better choice, but I don't think that's enough to justify deprecating
cirrus at this point in time, because when it then gets deleted it
will break way too many existing deployments.

We need to socialize info in that blog post above more widely and
especially ensure that apps are not using that by default. I don't
see it being viable to formally deprecate it in QEMU any time soon
though given existing usage.

> 
> Signed-off-by: Gerd Hoffmann 
> ---
>  hw/display/cirrus_vga.c | 2 ++
>  hw/display/cirrus_vga_isa.c | 2 ++
>  qemu-deprecated.texi| 4 
>  3 files changed, 8 insertions(+)
> 
> diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
> index d9b854d..2f16ba9 100644
> --- a/hw/display/cirrus_vga.c
> +++ b/hw/display/cirrus_vga.c
> @@ -3024,6 +3024,8 @@ static void cirrus_vga_class_init(ObjectClass *klass, 
> void *data)
>  dc->vmsd = _pci_cirrus_vga;
>  dc->props = pci_vga_cirrus_properties;
>  dc->hotpluggable = false;
> +dc->deprecation_reason =
> +
> "https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful;;
>  }
>  
>  static const TypeInfo cirrus_vga_info = {
> diff --git a/hw/display/cirrus_vga_isa.c b/hw/display/cirrus_vga_isa.c
> index fa10b74..c2d853c 100644
> --- a/hw/display/cirrus_vga_isa.c
> +++ b/hw/display/cirrus_vga_isa.c
> @@ -81,6 +81,8 @@ static void isa_cirrus_vga_class_init(ObjectClass *klass, 
> void *data)
>  dc->realize = isa_cirrus_vga_realizefn;
>  dc->props = isa_cirrus_vga_properties;
>  set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
> +dc->deprecation_reason =
> +
> "https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful;;
>  }
>  
>  static const TypeInfo isa_cirrus_vga_info = {
> diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi
> index 7951a4f..1b1d434 100644
> --- a/qemu-deprecated.texi
> +++ b/qemu-deprecated.texi
> @@ -120,6 +120,10 @@ or ``ivshmem-doorbell`` device types.
>  
>  Has known buffer overflow.
>  
> +@subsection cirrus (since 3.1)
> +
> +Use stdvga instead (-vga std or -device VGA).
> +
>  @section System emulator machines
>  
>  @subsection pc-0.10 and pc-0.11 (since 3.0)
> -- 
> 2.9.3
> 
> 

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 :|



Re: [Qemu-devel] [PATCH] linux-user: fix comment s/atomic_write/atomic_set/

2018-10-25 Thread Laurent Vivier
On 11/08/2018 22:10, Emilio G. Cota wrote:
> Signed-off-by: Emilio G. Cota 
> ---
>  linux-user/qemu.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> index b4959e41c6..e6a8bc5867 100644
> --- a/linux-user/qemu.h
> +++ b/linux-user/qemu.h
> @@ -143,7 +143,7 @@ typedef struct TaskState {
>  /* Nonzero if process_pending_signals() needs to do something (either
>   * handle a pending signal or unblock signals).
>   * This flag is written from a signal handler so should be accessed via
> - * the atomic_read() and atomic_write() functions. (It is not accessed
> + * the atomic_read() and atomic_set() functions. (It is not accessed
>   * from multiple threads.)
>   */
>  int signal_pending;
> 

Applied

Thanks,
Laurent



Re: [Qemu-devel] [PATCH v4 01/11] hw/m68k: add via support

2018-10-25 Thread Mark Cave-Ayland
On 23/10/2018 07:22, Thomas Huth wrote:

> On 2018-10-18 19:28, Mark Cave-Ayland wrote:
>> From: Laurent Vivier 
>>
>> Co-developed-by: Mark Cave-Ayland 
>> Signed-off-by: Mark Cave-Ayland 
>> Signed-off-by: Laurent Vivier 
>> ---
> [...]
>> diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
>> new file mode 100644
>> index 00..084974a24d
>> --- /dev/null
>> +++ b/hw/misc/mac_via.c
>> @@ -0,0 +1,668 @@
>> +/*
>> + * QEMU m68k Macintosh VIA device support
>> + *
>> + * Copyright (c) 2011-2018 Laurent Vivier
> 
> Should Mark be listed here, too? (since it has been co-developed?)

I don't mind so much as I have the tag above, but FWIW I've added my copyright 
here too.

>> + *
>> + * Some parts from hw/cuda.c
> 
> That's hw/misc/macio/cuda.c now.

Fixed.

>> + *
>> + * Copyright (c) 2004-2007 Fabrice Bellard
>> + * Copyright (c) 2007 Jocelyn Mayer
>> + *
>> + * some parts from linux-2.6.29, arch/m68k/include/asm/mac_via.h
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>> + * See the COPYING file in the top-level directory.
>> + *
> 
> Maybe remove the empty line?
> 
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "hw/sysbus.h"
>> +#include "qemu/timer.h"
>> +#include "hw/misc/mac_via.h"
>> +#include "hw/misc/mos6522.h"
>> +#include "hw/input/adb.h"
>> +#include "sysemu/sysemu.h"
>> +#include "qapi/error.h"
>> +#include "qemu/cutils.h"
>> +
>> +
>> +/*
>> + * VIAs: There are two in every machine,
> 
> Remove the comma at the end. And maybe add a very short description what
> a "VIA" is (for those who don't know this chip)
> 
>> + */
>> +
>> +#define VIA_SIZE (0x2000)
>> +
>> +/*
>> + * Not all of these are true post MacII I think.
>> + * CSA: probably the ones CHRP marks as 'unused' change purposes
> 
> What is CSA?
> 
>> + * when the IWM becomes the SWIM.
>> + * http://www.rs6000.ibm.com/resource/technology/chrpio/via5.mak.html
>> + * 
>> ftp://ftp.austin.ibm.com/pub/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf
>> + *
>> + * also, http://developer.apple.com/technotes/hw/hw_09.html claims the
> 
> All three URLs seem to be dead. Use archive.org?
> 
>> + * following changes for IIfx:
>> + * VIA1A_vSccWrReq not available and that VIA1A_vSync has moved to an IOP.
>> + * Also, "All of the functionality of VIA2 has been moved to other chips".
>> + */
>> +
>> +#define VIA1A_vSccWrReq 0x80   /* SCC write. (input)
>> +* [CHRP] SCC WREQ: Reflects the state of the
>> +* Wait/Request pins from the SCC.
>> +* [Macintosh Family Hardware]
>> +* as CHRP on SE/30,II,IIx,IIcx,IIci.
>> +* on IIfx, "0 means an active request"
>> +*/
>> +#define VIA1A_vRev8 0x40   /* Revision 8 board ???
>> +* [CHRP] En WaitReqB: Lets the WaitReq_L
>> +* signal from port B of the SCC appear on
>> +* the PA7 input pin. Output.
>> +* [Macintosh Family] On the SE/30, this
>> +* is the bit to flip screen buffers.
>> +* 0=alternate, 1=main.
>> +* on II,IIx,IIcx,IIci,IIfx this is a bit
>> +* for Rev ID. 0=II,IIx, 1=IIcx,IIci,IIfx
>> +*/
>> +#define VIA1A_vHeadSel  0x20   /* Head select for IWM.
>> +* [CHRP] unused.
>> +* [Macintosh Family] "Floppy disk
>> +* state-control line SEL" on all but IIfx
>> +*/
>> +#define VIA1A_vOverlay  0x10   /* [Macintosh Family] On SE/30,II,IIx,IIcx
>> +* this bit enables the "Overlay" address
>> +* map in the address decoders as it is on
>> +* reset for mapping the ROM over the reset
>> +* vector. 1=use overlay map.
>> +* On the IIci,IIfx it is another bit of the
>> +* CPU ID: 0=normal IIci, 1=IIci with parity
>> +* feature or IIfx.
>> +* [CHRP] En WaitReqA: Lets the WaitReq_L
>> +* signal from port A of the SCC appear
>> +* on the PA7 input pin (CHRP). Output.
>> +* [MkLinux] "Drive Select"
>> +*  (with 0x20 being 'disk head select')
>> +*/
>> +#define VIA1A_vSync 0x08   /* [CHRP] Sync Modem: modem clock select:
>> +* 1: select the external serial clock to
>> +*drive the SCC's /RTxCA 

Re: [Qemu-devel] [Qemu-trivial] [PATCH] piix: use TYPE_FOO constants than string constats

2018-10-25 Thread Laurent Vivier
On 25/10/2018 16:11, Li Qiang wrote:
> Hello Laurent,
> Thanks,
> 
> This patch has been in Michael's pull request.
> Maybe you can drop it.

Removed

Thanks,
Laurent



Re: [Qemu-devel] [PATCH v2 03/29] target/riscv: Convert RVXI branch insns to decodetree

2018-10-25 Thread Palmer Dabbelt

On Sat, 20 Oct 2018 00:14:25 PDT (-0700), Bastian Koppelmann wrote:

Signed-off-by: Bastian Koppelmann 
Signed-off-by: Peer Adelt 
---
v1 -> v2:
- use ctx->env instead of current_cpu->env_ptr

 target/riscv/insn32.decode  | 19 ++
 target/riscv/insn_trans/trans_rvi.inc.c | 49 +
 target/riscv/translate.c| 19 +-
 3 files changed, 69 insertions(+), 18 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 44d4e922b6..b49913416d 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -17,14 +17,33 @@
 # this program.  If not, see .

 # Fields:
+%rs2   20:5
+%rs1   15:5
 %rd7:5

 # immediates:
+%imm_i20:s12
+%imm_b31:s1 7:1 25:6 8:4 !function=ex_shift_1
+%imm_j31:s1 12:8 20:1 21:10  !function=ex_shift_1
 %imm_u12:s20 !function=ex_shift_12

+# Argument sets:
+imm rs2 rs1
+
 # Formats 32:
+@i   . ... . ... imm=%imm_i %rs1 
%rd
+@b   ...   . . ... . ...  imm=%imm_b %rs2 %rs1
 @u     . ... imm=%imm_u  
%rd
+@j     . ... imm=%imm_j  
%rd

 # *** RV32I Base Instruction Set ***
 lui     . 0110111 @u
 auipc   . 0010111 @u
+jal     . 110 @j
+jalr  . 000 . 1100111 @i
+beq  ... .. 000 . 1100011 @b
+bne  ... .. 001 . 1100011 @b
+blt  ... .. 100 . 1100011 @b
+bge  ... .. 101 . 1100011 @b
+bltu ... .. 110 . 1100011 @b
+bgeu ... .. 111 . 1100011 @b
diff --git a/target/riscv/insn_trans/trans_rvi.inc.c 
b/target/riscv/insn_trans/trans_rvi.inc.c
index aee0d1637d..3935a80ba5 100644
--- a/target/riscv/insn_trans/trans_rvi.inc.c
+++ b/target/riscv/insn_trans/trans_rvi.inc.c
@@ -33,3 +33,52 @@ static bool trans_auipc(DisasContext *ctx, arg_auipc *a, 
uint32_t insn)
 }
 return true;
 }
+
+static bool trans_jal(DisasContext *ctx, arg_jal *a, uint32_t insn)
+{
+gen_jal(ctx->env, ctx, a->rd, a->imm);
+return true;
+}
+
+static bool trans_jalr(DisasContext *ctx, arg_jalr *a, uint32_t insn)
+{
+gen_jalr(ctx->env, ctx, OPC_RISC_JALR, a->rd, a->rs1, a->imm);
+return true;
+}
+
+static bool trans_beq(DisasContext *ctx, arg_beq *a, uint32_t insn)
+{
+gen_branch(ctx->env, ctx, OPC_RISC_BEQ, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_bne(DisasContext *ctx, arg_bne *a, uint32_t insn)
+{
+gen_branch(ctx->env, ctx, OPC_RISC_BNE, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_blt(DisasContext *ctx, arg_blt *a, uint32_t insn)
+{
+gen_branch(ctx->env, ctx, OPC_RISC_BLT, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_bge(DisasContext *ctx, arg_bge *a, uint32_t insn)
+{
+gen_branch(ctx->env, ctx, OPC_RISC_BGE, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_bltu(DisasContext *ctx, arg_bltu *a, uint32_t insn)
+{
+gen_branch(ctx->env, ctx, OPC_RISC_BLTU, a->rs1, a->rs2, a->imm);
+return true;
+}
+
+static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a, uint32_t insn)
+{
+
+gen_branch(ctx->env, ctx, OPC_RISC_BGEU, a->rs1, a->rs2, a->imm);
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 65a323a201..9b6848e666 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1672,6 +1672,7 @@ static void decode_RV32_64C(CPURISCVState *env, 
DisasContext *ctx)
 { \
 return imm << amount; \
 }
+EX_SH(1)
 EX_SH(12)

 bool decode_insn32(DisasContext *ctx, uint32_t insn);
@@ -1700,24 +1701,6 @@ static void decode_RV32_64G(CPURISCVState *env, 
DisasContext *ctx)
 imm = GET_IMM(ctx->opcode);

 switch (op) {
-case OPC_RISC_AUIPC:
-if (rd == 0) {
-break; /* NOP */
-}
-tcg_gen_movi_tl(cpu_gpr[rd], (sextract64(ctx->opcode, 12, 20) << 12) +
-   ctx->base.pc_next);
-break;


This should go with the previous patch.  I can move it if you want me to start 
merging this patch set.



-case OPC_RISC_JAL:
-imm = GET_JAL_IMM(ctx->opcode);
-gen_jal(env, ctx, rd, imm);
-break;
-case OPC_RISC_JALR:
-gen_jalr(env, ctx, MASK_OP_JALR(ctx->opcode), rd, rs1, imm);
-break;
-case OPC_RISC_BRANCH:
-gen_branch(env, ctx, MASK_OP_BRANCH(ctx->opcode), rs1, rs2,
-   GET_B_IMM(ctx->opcode));
-break;
 case OPC_RISC_LOAD:
 gen_load(ctx, MASK_OP_LOAD(ctx->opcode), rd, rs1, imm);
 break;


Reviewed-by: Palmer Dabbelt 



Re: [Qemu-devel] [PATCH v4 11/11] hw/m68k: define Macintosh Quadra 800

2018-10-25 Thread Mark Cave-Ayland
On 23/10/2018 14:16, Philippe Mathieu-Daudé wrote:

> Hi Laurent, Mark,
> 
> On 18/10/18 20:28, Mark Cave-Ayland wrote:
>> From: Laurent Vivier 
>>
>> Co-developed-by: Mark Cave-Ayland 
>> Signed-off-by: Mark Cave-Ayland 
>> Signed-off-by: Laurent Vivier 
>> ---
>>   MAINTAINERS  |  19 ++
>>   default-configs/m68k-softmmu.mak |  14 ++
>>   hw/intc/Makefile.objs    |   1 +
>>   hw/intc/q800_irq.c   |  73 
>>   hw/m68k/Makefile.objs    |   6 +-
>>   hw/m68k/bootinfo.h   | 100 +++
>>   hw/m68k/q800.c   | 367 
>> +++
>>   include/hw/intc/q800_irq.h   |  39 +
>>   8 files changed, 617 insertions(+), 2 deletions(-)
>>   create mode 100644 hw/intc/q800_irq.c
>>   create mode 100644 hw/m68k/bootinfo.h
>>   create mode 100644 hw/m68k/q800.c
>>   create mode 100644 include/hw/intc/q800_irq.h
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 40672c4eba..552c53394b 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -718,6 +718,25 @@ F: hw/char/mcf_uart.c
>>   F: hw/net/mcf_fec.c
>>   F: include/hw/m68k/mcf*.h
>>   +q800
>> +M: Laurent Vivier 
>> +S: Maintained
>> +F: hw/audio/asc.c
>> +F: hw/block/swim.c
>> +F: hw/m68k/bootinfo.h
>> +F: hw/display/macfb-template.h
>> +F: hw/display/macfb.c
>> +F: hw/intc/q800_irq.c
>> +F: hw/m68k/q800.c
>> +F: hw/misc/mac_via.c
>> +F: hw/nubus/*
>> +F: include/hw/audio/asc.h
>> +F: include/hw/block/swim.h
>> +F: include/hw/display/macfb.h
>> +F: include/hw/intc/q800_irq.h
>> +F: include/hw/misc/mac_via.h
>> +F: include/hw/nubus/*
>> +
>>   MicroBlaze Machines
>>   ---
>>   petalogix_s3adsp1800
>> diff --git a/default-configs/m68k-softmmu.mak 
>> b/default-configs/m68k-softmmu.mak
>> index 60f7cdfbf2..993644aa42 100644
>> --- a/default-configs/m68k-softmmu.mak
>> +++ b/default-configs/m68k-softmmu.mak
>> @@ -2,3 +2,17 @@
>>     CONFIG_COLDFIRE=y
>>   CONFIG_PTIMER=y
>> +CONFIG_ESCC=y
>> +CONFIG_FRAMEBUFFER=y
>> +CONFIG_ADB=y
>> +CONFIG_MOS6522=y
>> +CONFIG_MAC_VIA=y
>> +CONFIG_Q800_IRQ=y
>> +CONFIG_MAC=y
>> +CONFIG_SCSI=y
>> +CONFIG_ESP=y
>> +CONFIG_ASC=y
>> +CONFIG_MACFB=y
>> +CONFIG_NUBUS=y
>> +CONFIG_DP8393X=y
>> +CONFIG_SWIM=y
>> diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
>> index 0e9963f5ee..030967a0b3 100644
>> --- a/hw/intc/Makefile.objs
>> +++ b/hw/intc/Makefile.objs
>> @@ -46,3 +46,4 @@ obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpuif.o
>>   obj-$(CONFIG_MIPS_CPS) += mips_gic.o
>>   obj-$(CONFIG_NIOS2) += nios2_iic.o
>>   obj-$(CONFIG_OMPIC) += ompic.o
>> +obj-$(CONFIG_Q800_IRQ) += q800_irq.o
>> diff --git a/hw/intc/q800_irq.c b/hw/intc/q800_irq.c
>> new file mode 100644
>> index 00..ec9d542d2e
>> --- /dev/null
>> +++ b/hw/intc/q800_irq.c
>> @@ -0,0 +1,73 @@
>> +/*
>> + * QEMU Motorla 680x0 Macintosh hardware System Emulator
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining a 
>> copy
>> + * of this software and associated documentation files (the "Software"), to 
>> deal
>> + * in the Software without restriction, including without limitation the 
>> rights
>> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
>> + * copies of the Software, and to permit persons to whom the Software is
>> + * furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice shall be included 
>> in
>> + * all copies or substantial portions of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
>> OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
>> OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
>> FROM,
>> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
>> + * THE SOFTWARE.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "cpu.h"
>> +#include "hw/intc/q800_irq.h"
>> +
>> +
>> +static void q800_set_irq(void *opaque, int irq, int level)
>> +{
>> +    Q800IRQControllerState *s = opaque;
>> +    int i;
>> +
>> +
>> +    if (level) {
>> +    s->ipr |= 1 << irq;
>> +    } else {
>> +    s->ipr &= ~(1 << irq);
>> +    }
>> +
>> +    for (i = 7; i >= 0; i--) {
> 
> Please add definition for magic numbers,
> 
>> +    if ((s->ipr >> i) & 1) {
>> +    m68k_set_irq_level(s->cpu, i + 1, i + 25);
> 
> ditto.
> 
>> +    return;
>> +    }
>> +    }
>> +    m68k_set_irq_level(s->cpu, 0, 0);
>> +}
>> +
>> +static void q800_irq_init(Object *obj)
>> +{
>> +    Q800IRQControllerState *s = Q800_IRQC(obj);
>> +
>> +    qdev_init_gpio_in(DEVICE(obj), q800_set_irq, 8);
> 
> Ditto.

The interrupt "controller" here looks like a simple priority encoder - Laurent, 
is
this the case? If so, 

[Qemu-devel] [PULL 2/3] target/mips: Implement emulation of nanoMIPS EVA instructions

2018-10-25 Thread Aleksandar Markovic
From: Dimitrije Nikolic 

Implement emulation of nanoMIPS EVA instructions. They are all
part of P.LS.E0 instruction pool, or one of its subpools.

Reviewed-by: Stefan Markovic 
Signed-off-by: Dimitrije Nikolic 
Signed-off-by: Aleksandar Markovic 
---
 target/mips/translate.c | 128 
 1 file changed, 128 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 4338b9a..51a5488 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -2989,6 +2989,35 @@ static inline void check_nms(DisasContext *ctx)
 }
 }
 
+/*
+ * This code generates a "reserved instruction" exception if the
+ * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
+ * Config2 TL, and Config5 L2C are unset.
+ */
+static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
+{
+if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
+!(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
+!(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
+!(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
+!(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
+!(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
+{
+generate_exception_end(ctx, EXCP_RI);
+}
+}
+
+/*
+ * This code generates a "reserved instruction" exception if the
+ * Config5 EVA bit is NOT set.
+ */
+static inline void check_eva(DisasContext *ctx)
+{
+if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA {
+generate_exception_end(ctx, EXCP_RI);
+}
+}
+
 
 /* Define small wrappers for gen_load_fpr* so that we have a uniform
calling interface for 32 and 64-bit FPRs.  No sense in changing
@@ -21218,6 +21247,105 @@ static int decode_nanomips_32_48_opc(CPUMIPSState 
*env, DisasContext *ctx)
 break;
 }
 break;
+case NM_P_LS_E0:
+switch (extract32(ctx->opcode, 11, 4)) {
+case NM_LBE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_ld(ctx, OPC_LBE, rt, rs, s);
+break;
+case NM_SBE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_st(ctx, OPC_SBE, rt, rs, s);
+break;
+case NM_LBUE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_ld(ctx, OPC_LBUE, rt, rs, s);
+break;
+case NM_P_PREFE:
+if (rt == 31) {
+/* case NM_SYNCIE */
+check_eva(ctx);
+check_cp0_enabled(ctx);
+/* Break the TB to be able to sync copied instructions
+   immediately */
+ctx->base.is_jmp = DISAS_STOP;
+} else {
+/* case NM_PREFE */
+check_eva(ctx);
+check_cp0_enabled(ctx);
+/* Treat as NOP. */
+}
+break;
+case NM_LHE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_ld(ctx, OPC_LHE, rt, rs, s);
+break;
+case NM_SHE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_st(ctx, OPC_SHE, rt, rs, s);
+break;
+case NM_LHUE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_ld(ctx, OPC_LHUE, rt, rs, s);
+break;
+case NM_CACHEE:
+check_nms_dl_il_sl_tl_l2c(ctx);
+gen_cache_operation(ctx, rt, rs, s);
+break;
+case NM_LWE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_ld(ctx, OPC_LWE, rt, rs, s);
+break;
+case NM_SWE:
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_st(ctx, OPC_SWE, rt, rs, s);
+break;
+case NM_P_LLE:
+switch (extract32(ctx->opcode, 2, 2)) {
+case NM_LLE:
+check_xnp(ctx);
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_ld(ctx, OPC_LLE, rt, rs, s);
+break;
+case NM_LLWPE:
+check_xnp(ctx);
+check_eva(ctx);
+check_cp0_enabled(ctx);
+gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
+default:
+generate_exception_end(ctx, EXCP_RI);
+   

Re: [Qemu-devel] [PATCH v4 04/11] hw/m68k: add macfb video card

2018-10-25 Thread Mark Cave-Ayland
On 23/10/2018 08:13, Thomas Huth wrote:

> On 2018-10-18 19:28, Mark Cave-Ayland wrote:
>> From: Laurent Vivier 
>>
>> Co-developed-by: Mark Cave-Ayland 
>> Signed-off-by: Mark Cave-Ayland 
>> Signed-off-by: Laurent Vivier 
>> ---
>>  arch_init.c |   4 +
>>  hw/display/Makefile.objs|   1 +
>>  hw/display/macfb-template.h | 158 +++
>>  hw/display/macfb.c  | 252 
>> 
>>  include/hw/display/macfb.h  |  42 
>>  qemu-options.hx |   2 +-
>>  vl.c|   3 +-
>>  7 files changed, 460 insertions(+), 2 deletions(-)
>>  create mode 100644 hw/display/macfb-template.h
>>  create mode 100644 hw/display/macfb.c
>>  create mode 100644 include/hw/display/macfb.h
> [...]
>> +typedef void (*macfb_draw_line_func_t)(MacfbState *, uint8_t *, uint8_t *, 
>> int);
>> +
>> +static macfb_draw_line_func_t macfb_draw_line[24][32] = {
>> +[0] = { [7] = draw_line1_8, [15] = draw_line1_16,
>> +[23] = draw_line1_24, [31] = draw_line1_32 },
>> +[1] = { [7] = draw_line2_8, [15] = draw_line2_16,
>> +[23] = draw_line2_24, [31] = draw_line2_32 },
>> +[3] = { [7] = draw_line4_8, [15] = draw_line4_16,
>> +[23] = draw_line4_24, [31] = draw_line4_32 },
>> +[7] = { [7] = draw_line8_8, [15] = draw_line8_16,
>> +[23] = draw_line8_24, [31] = draw_line8_32 },
>> +[15] = { [7] = draw_line16_8, [15] = draw_line16_16,
>> + [23] = draw_line16_24, [31] = draw_line16_32 },
>> +[23] = { [7] = draw_line24_8, [15] = draw_line24_16,
>> + [23] = draw_line24_24, [31] = draw_line24_32 },
>> +};
> 
> May I suggest to define the array as macfb_draw_line[24][4] instead of
> macfb_draw_line[24][32] here...

Indeed, this is an artefact from the original implementation that can now be 
removed
given that all host surfaces are now 32-bit.

>> diff --git a/hw/display/macfb.c b/hw/display/macfb.c
>> new file mode 100644
>> index 00..54472c1cbb
>> --- /dev/null
>> +++ b/hw/display/macfb.c
>> @@ -0,0 +1,252 @@
>> +/*
>> + * QEMU Motorola 680x0 Macintosh Video Card Emulation
>> + * Copyright (c) 2012-2018 Laurent Vivier
>> + *
>> + * some parts from QEMU G364 framebuffer Emulator.
>> + * Copyright (c) 2007-2011 Herve Poussineau
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>> + * See the COPYING file in the top-level directory.
>> + *
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "hw/sysbus.h"
>> +#include "ui/console.h"
>> +#include "ui/pixel_ops.h"
>> +#include "hw/display/macfb.h"
>> +
>> +#define VIDEO_BASE 0x1000
>> +#define DAFB_BASE  0x0080
>> +
>> +#define MACFB_PAGE_SIZE 4096
>> +#define MACFB_VRAM_SIZE (4 * 1024 * 1024)
>> +
>> +#define DAFB_RESET  0x200
>> +#define DAFB_LUT0x213
>> +
>> +#include "macfb-template.h"
>> +
>> +static int macfb_check_dirty(MacfbState *s, DirtyBitmapSnapshot *snap,
>> + ram_addr_t addr, int len)
>> +{
>> +return memory_region_snapshot_get_dirty(>mem_vram, snap, addr, len);
>> +}
>> +
>> +static void macfb_draw_graphic(MacfbState *s)
>> +{
>> +DisplaySurface *surface = qemu_console_surface(s->con);
>> +DirtyBitmapSnapshot *snap = NULL;
>> +ram_addr_t page;
>> +int y, ymin;
>> +int macfb_stride = (s->depth * s->width + 7) / 8;
>> +macfb_draw_line_func_t draw_line;
>> +
>> +if (s->depth > 24) {
>> +hw_error("macfb: unknown guest depth %d", s->depth);
> 
> I think this should be checked in the realize() function instead (and
> maybe only do an assert() here).

Yes indeed - fixed in the updated version.

>> +return;
>> +}
>> +if (surface_bits_per_pixel(surface) > 32) {
>> +hw_error("macfb: unknown host depth %d",
>> + surface_bits_per_pixel(surface));
> 
> Simply assert(surface_bits_per_pixel(surface) <= 32) ?

I had a look at a few other display implementations and it seems the easiest 
thing to
do here is move this to realize similar to above.

>> +return;
>> +}
>> +draw_line = macfb_draw_line[s->depth - 
>> 1][surface_bits_per_pixel(surface)
>> +  - 1];
> 
> ... If you change func_t macfb_draw_line[24][32] to func_t
> macfb_draw_line[24][4], you could then use
> surface_bits_per_pixel(surface) / 8 - 1 here instead.
> 
> Also, do we have still to care about host bit depths < 32 at all these
> days? If not, I think the code could be simplified quite a bit.

Yes indeed. In fact, looking at the current VGA code the use of the template 
has now
been removed so I've expanded out the remaining functions within macfb.c and 
removed
macfb-template.h which is no longer required.

>> +if (draw_line == NULL) {
>> +hw_error("macfb: unknown guest/host depth combination %d/%d", 
>> s->depth,
>> + 

[Qemu-devel] [PULL 0/3] MIPS queue for October 2018 - part 3

2018-10-25 Thread Aleksandar Markovic
From: Aleksandar Markovic 

The following changes since commit 808ebd66e467f77c0d1f8c6346235f81e9c99cf2:

  Merge remote-tracking branch 'remotes/riscv/tags/riscv-for-master-3.1-sf0' 
into staging (2018-10-25 17:41:03 +0100)

are available in the git repository at:

  https://github.com/AMarkovic/qemu tags/mips-queue-oct-2018-part-3

for you to fetch changes up to 89a955e8df3dba6f96859cd0339356243b6c996f:

  target/mips: Add disassembler support for nanoMIPS (2018-10-25 22:13:33 +0200)


MIPS queue for October 2018 - part 3

  - this pull request contains three assorted nanoMIPS issues
  - three checkpatch.pl warnings are known and should be ignored


Aleksandar Markovic (2):
  target/mips: Add nanoMIPS CRC32 instruction pool
  target/mips: Add disassembler support for nanoMIPS

Dimitrije Nikolic (1):
  target/mips: Implement emulation of nanoMIPS EVA instructions

 MAINTAINERS | 2 +
 configure   | 3 +
 disas/Makefile.objs | 1 +
 disas/nanomips.cpp  | 22242 ++
 disas/nanomips.h|  1099 +++
 include/disas/bfd.h | 1 +
 include/exec/poison.h   | 1 +
 target/mips/cpu.c   |13 +-
 target/mips/translate.c |   138 +
 9 files changed, 23498 insertions(+), 2 deletions(-)
 create mode 100644 disas/nanomips.cpp
 create mode 100644 disas/nanomips.h

-- 
2.7.4




[Qemu-devel] [PULL 1/3] target/mips: Add nanoMIPS CRC32 instruction pool

2018-10-25 Thread Aleksandar Markovic
From: Aleksandar Markovic 

Add nanoMIPS CRC32 instruction pool.

Reviewed-by: Stefan Markovic 
Signed-off-by: Aleksandar Markovic 
---
 target/mips/translate.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index c44a751..4338b9a 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -17475,6 +17475,16 @@ enum {
 NM_SOV  = 0x7a,
 };
 
+/* CRC32 instruction pool */
+enum {
+NM_CRC32B   = 0x00,
+NM_CRC32H   = 0x01,
+NM_CRC32W   = 0x02,
+NM_CRC32CB  = 0x04,
+NM_CRC32CH  = 0x05,
+NM_CRC32CW  = 0x06,
+};
+
 /* POOL32A5 instruction pool */
 enum {
 NM_CMP_EQ_PH= 0x00,
-- 
2.7.4




Re: [Qemu-devel] [PATCH v4 11/11] hw/m68k: define Macintosh Quadra 800

2018-10-25 Thread Mark Cave-Ayland
On 23/10/2018 12:20, Thomas Huth wrote:

> On 2018-10-18 19:28, Mark Cave-Ayland wrote:
>> From: Laurent Vivier 
>>
>> Co-developed-by: Mark Cave-Ayland 
>> Signed-off-by: Mark Cave-Ayland 
>> Signed-off-by: Laurent Vivier 
>> ---
> [...]
>> diff --git a/hw/m68k/Makefile.objs b/hw/m68k/Makefile.objs
>> index d1f089c08a..18ebf1937a 100644
>> --- a/hw/m68k/Makefile.objs
>> +++ b/hw/m68k/Makefile.objs
>> @@ -1,2 +1,4 @@
>> -obj-y += an5206.o mcf5208.o
>> -obj-y += mcf5206.o mcf_intc.o
>> +obj-$(CONFIG_COLDFIRE) += an5206.o mcf5208.o
>> +obj-$(CONFIG_MAC) += q800.o
>> +
>> +obj-$(CONFIG_COLDFIRE) += mcf5206.o mcf_intc.o
> 
> Cosmetic nit: Keep the coldfire lines together instead of splitting them?

Cosmetic nit fixed in the latest version ;)

>> diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
>> new file mode 100644
>> index 00..bbf34262f0
>> --- /dev/null
>> +++ b/hw/m68k/q800.c
>> @@ -0,0 +1,367 @@
>> +/*
>> + * QEMU Motorla 680x0 Macintosh hardware System Emulator
>> + *
>> + * Permission is hereby granted, free of charge, to any person obtaining a 
>> copy
>> + * of this software and associated documentation files (the "Software"), to 
>> deal
>> + * in the Software without restriction, including without limitation the 
>> rights
>> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
>> + * copies of the Software, and to permit persons to whom the Software is
>> + * furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice shall be included 
>> in
>> + * all copies or substantial portions of the Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
>> OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
>> OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
>> FROM,
>> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
>> + * THE SOFTWARE.
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "sysemu/sysemu.h"
>> +#include "cpu.h"
>> +#include "hw/hw.h"
>> +#include "hw/boards.h"
>> +#include "elf.h"
>> +#include "hw/loader.h"
>> +#include "hw/display/framebuffer.h"
>> +#include "ui/console.h"
>> +#include "exec/address-spaces.h"
>> +#include "hw/char/escc.h"
>> +#include "hw/sysbus.h"
>> +#include "hw/scsi/esp.h"
>> +#include "bootinfo.h"
>> +#include "hw/misc/mac_via.h"
>> +#include "hw/input/adb.h"
>> +#include "hw/audio/asc.h"
>> +#include "hw/nubus/mac-nubus-bridge.h"
>> +#include "hw/display/macfb.h"
>> +#include "hw/intc/q800_irq.h"
>> +#include "hw/block/swim.h"
>> +#include "net/net.h"
>> +#include "qapi/error.h"
>> +#include "sysemu/qtest.h"
>> +
>> +#define MACROM_ADDR 0x4000
>> +#define MACROM_SIZE 0x0010
>> +
>> +/*
>> + *  .ident  = MAC_MODEL_Q800,
>> + *  .name   = "Quadra 800",
>> + *  .adb_type   = MAC_ADB_II,
>> + *  .via_type   = MAC_VIA_QUADRA,
>> + *  .scsi_type  = MAC_SCSI_QUADRA,
>> + *  .scc_type   = MAC_SCC_QUADRA,
>> + *  .ether_type = MAC_ETHER_SONIC,
>> + *  .nubus_type = MAC_NUBUS
>> + */
> 
> Is this comment intentional or left-over code from an older rebase?

I suspect this has come from another Linux file somewhere, but as it's nothing
related to QEMU then I've removed it for now.


ATB,

Mark.



Re: [Qemu-devel] [PATCH 2/3] adlib: mark as insecure and deprecated.

2018-10-25 Thread Thomas Huth
On 2018-10-25 09:52, Gerd Hoffmann wrote:
> We have a lovely, guest-triggerable buffer overflow in opl2 emulation.
> 
> Reproducer:
> outw(0xff60, 0x220);
> outw(0x1020, 0x220);
> outw(0xffb0, 0x220);
> Result:
> Will overflow FM_OPL->AR_TABLE[] (see hw/audio/fmopl.[ch])
> 
> The specs google finds (http://www.symphoniae.com/Yamaha/YSC/YM3812.pdf)
> are rather sparse, possibly incomplete (looks like scanned fax with a
> scrambled page at the end) and not really helpful in identifying which
> of the register writes sets some illegal value.
> 
> So, go tag the device as deprecated with a warning messge, to notify
> users and schedule it for removal according to our deprecation policy.
> 
> Signed-off-by: Gerd Hoffmann 
> ---
>  hw/audio/adlib.c | 1 +
>  qemu-deprecated.texi | 4 
>  2 files changed, 5 insertions(+)
> 
> diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c
> index 97b876c..fb4a29c 100644
> --- a/hw/audio/adlib.c
> +++ b/hw/audio/adlib.c
> @@ -311,6 +311,7 @@ static void adlib_class_initfn (ObjectClass *klass, void 
> *data)
>  set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
>  dc->desc = ADLIB_DESC;
>  dc->props = adlib_properties;
> +dc->deprecation_reason = "insecure, buffer overflow in opl2 emulation";
>  }
>  
>  static const TypeInfo adlib_info = {
> diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi
> index 11b870c..7951a4f 100644
> --- a/qemu-deprecated.texi
> +++ b/qemu-deprecated.texi
> @@ -116,6 +116,10 @@ The @option{[hub_id name]} parameter tuple of the 
> 'hostfwd_add' and
>  The ``ivshmem'' device type is replaced by either the ``ivshmem-plain''
>  or ``ivshmem-doorbell`` device types.
>  
> +@subsection adlib (since 3.1)
> +
> +Has known buffer overflow.
> +
>  @section System emulator machines
>  
>  @subsection pc-0.10 and pc-0.11 (since 3.0)
> 

Any chance you could maybe at least add an assert() to the affected code
so that it crashes instead of silently overflowing the buffer?

Anyway, with the "messge" typo fixed:

Reviewed-by: Thomas Huth 



Re: [Qemu-devel] [PATCH v4 02/11] hw/m68k: implement ADB bus support for via

2018-10-25 Thread Mark Cave-Ayland
On 23/10/2018 07:49, Thomas Huth wrote:

> On 2018-10-18 19:28, Mark Cave-Ayland wrote:
>> From: Laurent Vivier 
>>
>> Co-developed-by: Mark Cave-Ayland 
>> Signed-off-by: Mark Cave-Ayland 
>> Signed-off-by: Laurent Vivier 
>> ---
>>  hw/input/adb.c|   2 +
>>  hw/misc/mac_via.c | 166 
>> ++
>>  include/hw/misc/mac_via.h |   7 ++
>>  3 files changed, 175 insertions(+)
>>
>> diff --git a/hw/input/adb.c b/hw/input/adb.c
>> index bbb40aeef1..d69ca74364 100644
>> --- a/hw/input/adb.c
>> +++ b/hw/input/adb.c
>> @@ -25,6 +25,8 @@
>>  #include "hw/input/adb.h"
>>  #include "adb-internal.h"
>>  
>> +#define ADB_POLL_FREQ 50
> 
> A single define without a user in a .c file? Looks suspicious...
> 
> As far as I can see, this has been replace by VIA_ADB_POLL_FREQ which
> has been introduced in the previous patch already, so you can remove
> this define here.

Ooops yes, this should have been removed from my previous refactoring - I've now
fixed this.

>>  /* error codes */
>>  #define ADB_RET_NOTPRESENT (-2)
>>  
>> diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
>> index 084974a24d..1ec563a707 100644
>> --- a/hw/misc/mac_via.c
>> +++ b/hw/misc/mac_via.c
> [...]
>> +static int adb_via_send(MacVIAState *s, int state, uint8_t data)
>> +{
>> +switch (state) {
>> +case ADB_STATE_NEW:
>> +s->adb_data_out_index = 0;
>> +break;
>> +case ADB_STATE_EVEN:
>> +if ((s->adb_data_out_index & 1) == 0) {
>> +return 0;
>> +}
>> +break;
>> +case ADB_STATE_ODD:
>> +if (s->adb_data_out_index & 1) {
>> +return 0;
>> +}
>> +break;
>> +case ADB_STATE_IDLE:
>> +return 0;
>> +}
> 
> Could you please add a
> 
>  assert(s->adb_data_out_index < sizeof(s->adb_data_out) -1);
> 
> here, just in case?

Done.

>> +s->adb_data_out[s->adb_data_out_index++] = data;
>> +qemu_irq_raise(s->adb_data_ready);
>> +return 1;
>> +}
>> +
>> +static int adb_via_receive(MacVIAState *s, int state, uint8_t *data)
>> +{
>> +switch (state) {
>> +case ADB_STATE_NEW:
>> +return 0;
>> +case ADB_STATE_EVEN:
>> +if (s->adb_data_in_size <= 0) {
>> +qemu_irq_raise(s->adb_data_ready);
>> +return 0;
>> +}
>> +if (s->adb_data_in_index >= s->adb_data_in_size) {
>> +*data = 0;
>> +qemu_irq_raise(s->adb_data_ready);
>> +return 1;
>> +}
>> +if ((s->adb_data_in_index & 1) == 0) {
>> +return 0;
>> +}
>> +break;
>> +case ADB_STATE_ODD:
>> +if (s->adb_data_in_size <= 0) {
>> +qemu_irq_raise(s->adb_data_ready);
>> +return 0;
>> +}
>> +if (s->adb_data_in_index >= s->adb_data_in_size) {
>> +*data = 0;
>> +qemu_irq_raise(s->adb_data_ready);
>> +return 1;
>> +}
>> +if (s->adb_data_in_index & 1) {
>> +return 0;
>> +}
>> +break;
>> +case ADB_STATE_IDLE:
>> +if (s->adb_data_out_index == 0) {
>> +return 0;
>> +}
>> +s->adb_data_in_size = adb_request(>adb_bus, s->adb_data_in,
>> +  s->adb_data_out,
>> +  s->adb_data_out_index);
>> +s->adb_data_out_index = 0;
>> +s->adb_data_in_index = 0;
>> +if (s->adb_data_in_size < 0) {
>> +*data = 0xff;
>> +qemu_irq_raise(s->adb_data_ready);
>> +return -1;
>> +}
>> +if (s->adb_data_in_size == 0) {
>> +return 0;
>> +}
>> +break;
>> +}
> 
> Please also add an assert before the next line here - just in case...

And also done here.

>> +*data = s->adb_data_in[s->adb_data_in_index++];
>> +qemu_irq_raise(s->adb_data_ready);
>> +if (*data == 0xff || *data == 0) {
>> +return 0;
>> +}
>> +return 1;
>> +}


ATB,

Mark.



Re: [Qemu-devel] [PATCH v4 07/11] hw/m68k: add Nubus support

2018-10-25 Thread Mark Cave-Ayland
On 23/10/2018 08:36, Thomas Huth wrote:

> On 2018-10-18 19:28, Mark Cave-Ayland wrote:
>> From: Laurent Vivier 
>>
>> Co-developed-by: Mark Cave-Ayland 
>> Signed-off-by: Mark Cave-Ayland 
>> Signed-off-by: Laurent Vivier 
>> ---
> [...]
>> +static void nubus_register_format_block(NubusDevice *dev)
>> +{
>> +char fblock_name[27];
>> +
>> +sprintf(fblock_name, "nubus-slot-%d-format-block", dev->slot_nb);
> 
> Latest GCC (version 8) got very picky about possible buffer overflows
> during sprintf() ... not sure, but it might be necessary to either use a
> bigger array here, or assert(dev->slot_nb < NUBUS_SLOT_NB), or even
> better use g_strdup_printf() instead (with g_free() at the end of the
> function) instead.

Good point. I've gone for replacing sprintf() with g_strdup_printf() whenever it
occurs in this file.

>> +hwaddr fblock_offset = memory_region_size(>slot_mem) - FBLOCK_SIZE;
>> +memory_region_init_io(>fblock_io, NULL, _format_block_ops,
>> +  dev, fblock_name, FBLOCK_SIZE);
>> +memory_region_add_subregion(>slot_mem, fblock_offset,
>> +>fblock_io);
>> +}
> [...]
>> diff --git a/include/hw/display/macfb.h b/include/hw/display/macfb.h
>> index 70ea5480fe..3059f2f36a 100644
>> --- a/include/hw/display/macfb.h
>> +++ b/include/hw/display/macfb.h
>> @@ -39,4 +39,25 @@ typedef struct {
>>  MacfbState macfb;
>>  } MacfbSysBusState;
>>  
>> +#define MACFB_NUBUS_DEVICE_CLASS(class) \
>> +OBJECT_CLASS_CHECK(MacfbNubusDeviceClass, (class), TYPE_NUBUS_MACFB)
>> +#define MACFB_NUBUS_GET_CLASS(obj) \
>> +OBJECT_GET_CLASS(MacfbNubusDeviceClass, (obj), TYPE_NUBUS_MACFB)
>> +
>> +typedef struct MacfbNubusDeviceClass {
>> +DeviceClass parent_class;
>> +
>> +DeviceRealize parent_realize;> +} MacfbNubusDeviceClass;
>>
>> +#define TYPE_NUBUS_MACFB "nubus-macfb"
>> +#define NUBUS_MACFB(obj) \
>> +OBJECT_CHECK(MacfbNubusState, (obj), TYPE_NUBUS_MACFB)
>> +
>> +typedef struct {
>> +NubusDevice busdev;
>> +
>> +MacfbState macfb;
>> +} MacfbNubusState;
>> +
>>  #endif
> 
> I think this should rather be part of the next patch instead?

Ooops yes. I've fixed in the latest version of the patch series.


ATB,

Mark.



Re: [Qemu-devel] [PATCH v4 05/11] hw/m68k: Apple Sound Chip (ASC) emulation

2018-10-25 Thread Mark Cave-Ayland
On 23/10/2018 08:18, Thomas Huth wrote:

> On 2018-10-18 19:28, Mark Cave-Ayland wrote:
>> From: Laurent Vivier 
>>
>> This is broken as the linux driver seems broken too...
> 
> So is this required for the initial version, or does Linux also boot
> without this device in the emulated machine? In the first case, please
> mention it in the cover letter. In the latter case, maybe skip the patch
> for now and add it later instead, once this has been fixed...?

Hmmm I'm not sure whether or not having this device missing is enough to break 
Linux
boot? Laurent?


ATB,

Mark.



Re: [Qemu-devel] [PATCH v1] arm: check bit index before usage

2018-10-25 Thread P J P
+-- On Thu, 25 Oct 2018, Peter Maydell wrote --+
| Hi; thanks for this patch. Looking at the SA1110 manual,
| it says that writes to the reserved bits [31:28] are
| ignored. So I think that rather than doing this check
| here, we should do what the strongarm_ppc_* code in the
| same file does -- mask off the high bits for writes to
| the direction and state registers. Then it will not
| be possible for high bits to be set here that cause an
| out-of-range array access.

===
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index ec2627374d..dd8c4b1f2e 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -587,12 +587,12 @@ static void strongarm_gpio_write(void *opaque, hwaddr 
offset,
 
 switch (offset) {
 case GPDR:/* GPIO Pin-Direction registers */
-s->dir = value;
+s->dir = value & 0x3f;
 strongarm_gpio_handler_update(s);
 break;
 
 case GPSR:/* GPIO Pin-Output Set registers */
-s->olevel |= value;
+s->olevel |= value & 0x3f;
 strongarm_gpio_handler_update(s);
 break;
===

does this seem okay?
 
| Side note: this device is used only in the "collie"
| machine model, which only works via TCG, so this is
| not a security issue, just a bug (which will only be
| visible if the guest is buggy.)

Cool, thank you.
--
Prasad J Pandit / Red Hat Product Security Team
47AF CE69 3A90 54AA 9045 1053 DD13 3D32 FE5B 041F



Re: [Qemu-devel] [PATCH 3/3] cirrus: mark as deprecated

2018-10-25 Thread Thomas Huth
On 2018-10-25 09:52, Gerd Hoffmann wrote:
> While being at it deprecate cirrus too.
> 
> Reason (short version): use stdvga instead.
> Verbose version:
> https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful
> 
> Signed-off-by: Gerd Hoffmann 
> ---
>  hw/display/cirrus_vga.c | 2 ++
>  hw/display/cirrus_vga_isa.c | 2 ++
>  qemu-deprecated.texi| 4 
>  3 files changed, 8 insertions(+)
> 
> diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
> index d9b854d..2f16ba9 100644
> --- a/hw/display/cirrus_vga.c
> +++ b/hw/display/cirrus_vga.c
> @@ -3024,6 +3024,8 @@ static void cirrus_vga_class_init(ObjectClass *klass, 
> void *data)
>  dc->vmsd = _pci_cirrus_vga;
>  dc->props = pci_vga_cirrus_properties;
>  dc->hotpluggable = false;
> +dc->deprecation_reason =
> +
> "https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful;;
>  }
>  
>  static const TypeInfo cirrus_vga_info = {
> diff --git a/hw/display/cirrus_vga_isa.c b/hw/display/cirrus_vga_isa.c
> index fa10b74..c2d853c 100644
> --- a/hw/display/cirrus_vga_isa.c
> +++ b/hw/display/cirrus_vga_isa.c
> @@ -81,6 +81,8 @@ static void isa_cirrus_vga_class_init(ObjectClass *klass, 
> void *data)
>  dc->realize = isa_cirrus_vga_realizefn;
>  dc->props = isa_cirrus_vga_properties;
>  set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
> +dc->deprecation_reason =
> +
> "https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful;;
>  }
>  
>  static const TypeInfo isa_cirrus_vga_info = {
> diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi
> index 7951a4f..1b1d434 100644
> --- a/qemu-deprecated.texi
> +++ b/qemu-deprecated.texi
> @@ -120,6 +120,10 @@ or ``ivshmem-doorbell`` device types.
>  
>  Has known buffer overflow.
>  
> +@subsection cirrus (since 3.1)
> +
> +Use stdvga instead (-vga std or -device VGA).
> +
>  @section System emulator machines
>  
>  @subsection pc-0.10 and pc-0.11 (since 3.0)
> 

Reviewed-by: Thomas Huth 



Re: [Qemu-devel] Call for patches for the qemu-trivial pull request

2018-10-25 Thread Thomas Huth
On 2018-10-23 11:04, Laurent Vivier wrote:
> Hi,
> 
> I'm going to collect patches for the next pull request for the
> qemu-trivial I'd like to do before the softfreeze.
> 
> As we didn't have any pull request for more than 3 months and some of
> the patches have been pushed through another maintainer branches, it's a
> little bit difficult to collect correctly the patches to send.
> 
> So, it would be helpful if any of you knowing that some patches have to
> be added to the pull request send me their list.

For June to September, I'd like to suggest:

 cpu.h: fix a typo in comment
 https://lists.nongnu.org/archive/html/qemu-trivial/2018-09/msg00021.html

 linux-user: fix comment s/atomic_write/atomic_set
 https://lists.nongnu.org/archive/html/qemu-trivial/2018-08/msg00017.html

 tests: Fix typos in comments and help message (found by codespell)
 https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg00039.html

 configure: Support pkg-config for zlib
 https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg00032.html
 (this had a suggestion for dropping the fallback test, but I think
 that could be done as an additional patch after the next release instead)

 qobject: Catch another straggler for use of qdict_put_str()
 https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg6.html

 xen: Use the PCI_DEVICE macro
 https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg8.html

 tests/bios-tables-test: Remove an useless cast
 https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg9.html

 hw/pci-host: Remove useless parenthesis around DIV_ROUND_UP macro
 https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg00011.html

 hw/intc/gicv3: Remove useless parenthesis around DIV_ROUND_UP macro
 https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg00012.html

 dump: fix a typo
 https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg2.html

 milkymist-minimac2: Use qemu_log_mask(GUEST_ERROR) instead of error_report
 https://lists.nongnu.org/archive/html/qemu-trivial/2018-07/msg1.html

 Makefile: Remove qemu-version.h and qemu-options.def during 'make distclean'
 https://lists.nongnu.org/archive/html/qemu-trivial/2018-06/msg00050.html

 ppc: move at24c to its own CONFIG_ symbol
 https://lists.nongnu.org/archive/html/qemu-trivial/2018-05/msg00118.html

Additionally you could also include the reviewed patches from the the
"use qemu_log_mask instead of fprintf" series here:
https://lists.nongnu.org/archive/html/qemu-trivial/2018-06/msg00276.html

 Thomas



[Qemu-devel] [PATCH] lsi53c895a: check message length value

2018-10-25 Thread P J P
From: Prasad J Pandit 

While writing a message in 'lsi_do_msgin', message length value
in msg_len could be invalid, add check to avoid OOB access issue.

Reported-by: Ameya More 
Signed-off-by: Prasad J Pandit 
---
 hw/scsi/lsi53c895a.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index d1e6534311..a266c5a113 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -205,7 +205,7 @@ typedef struct {
 /* Action to take at the end of a MSG IN phase.
0 = COMMAND, 1 = disconnect, 2 = DATA OUT, 3 = DATA IN.  */
 int msg_action;
-int msg_len;
+uint8_t msg_len;
 uint8_t msg[LSI_MAX_MSGIN_LEN];
 /* 0 if SCRIPTS are running or stopped.
  * 1 if a Wait Reselect instruction has been issued.
@@ -861,12 +861,15 @@ static void lsi_do_status(LSIState *s)
 
 static void lsi_do_msgin(LSIState *s)
 {
-int len;
+uint8_t len;
 trace_lsi_do_msgin(s->dbc, s->msg_len);
 s->sfbr = s->msg[0];
 len = s->msg_len;
 if (len > s->dbc)
 len = s->dbc;
+if (len > LSI_MAX_MSGIN_LEN) {
+len = LSI_MAX_MSGIN_LEN;
+}
 pci_dma_write(PCI_DEVICE(s), s->dnad, s->msg, len);
 /* Linux drivers rely on the last byte being in the SIDL.  */
 s->sidl = s->msg[len - 1];
@@ -2114,7 +2117,7 @@ static const VMStateDescription vmstate_lsi_scsi = {
 VMSTATE_INT32(carry, LSIState),
 VMSTATE_INT32(status, LSIState),
 VMSTATE_INT32(msg_action, LSIState),
-VMSTATE_INT32(msg_len, LSIState),
+VMSTATE_UINT8(msg_len, LSIState),
 VMSTATE_BUFFER(msg, LSIState),
 VMSTATE_INT32(waiting, LSIState),
 
-- 
2.17.2




Re: [Qemu-devel] [PULL v2 00/28] pci, pc, virtio: fixes, features

2018-10-25 Thread Peter Maydell
On 25 October 2018 at 01:52, Michael S. Tsirkin  wrote:
> The following changes since commit 13399aad4fa87b2878c49d02a5d3bafa6c966ba3:
>
>   Merge remote-tracking branch 'remotes/armbru/tags/pull-error-2018-10-22' 
> into staging (2018-10-23 17:20:23 +0100)
>
> are available in the Git repository at:
>
>   git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
>
> for you to fetch changes up to 6a9fb4e1ba5594cde7739068617ad88e6117db93:
>
>   vhost-scsi: prevent using uninitialized vqs (2018-10-24 20:50:13 -0400)
>
> 
> pci, pc, virtio: fixes, features
>
> AMD IOMMU VAPIC support + fixes all over the place.
>
> Signed-off-by: Michael S. Tsirkin 

Hi; I get some compile failures and a test assertion, I'm afraid:

On 32-bit hosts (where uint64_t and size_t are not the same):

/home/peter.maydell/qemu/include/qemu/compiler.h:80:35: error: invalid
operands to binary - (have 'uint64_t * {aka long long unsigned int *}'
and 'size_t * {aka unsigned int *}')
 #define type_check(t1,t2) ((t1*)0 - (t2*)0)
   ^
/home/peter.maydell/qemu/include/hw/qdev-properties.h:77:15: note: in
expansion of macro 'type_check'
 + type_check(_type, typeof_field(_state, _field)),  \
   ^
/home/peter.maydell/qemu/include/hw/qdev-properties.h:168:5: note: in
expansion of macro 'DEFINE_PROP_UNSIGNED'
 DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_size, uint64_t)
 ^
/home/peter.maydell/qemu/hw/misc/pci-testdev.c:322:5: note: in
expansion of macro 'DEFINE_PROP_SIZE'
 DEFINE_PROP_SIZE("membar", PCITestDevState, membar_size, 0),
 ^
/home/peter.maydell/qemu/rules.mak:69: recipe for target
'hw/misc/pci-testdev.o' failed

On the Windows w64 cross-compile:

In file included from /home/petmay01/qemu-for-merges/hw/i386/amd_iommu.c:26:0:
/home/petmay01/qemu-for-merges/hw/i386/amd_iommu.c: In function
'amdvi_int_remap_msi':
/home/petmay01/qemu-for-merges/hw/i386/amd_iommu.h:247:46: error: left
shift count >= width of type [-Werror=shift-count-overflow]
 #define AMDVI_DEV_NMI_PASS_MASK (1UL << 58)
  ^
/home/petmay01/qemu-for-merges/hw/i386/amd_iommu.c:1281:25: note: in
expansion of macro 'AMDVI_DEV_NMI_PASS_MASK'
 pass = dte[3] & AMDVI_DEV_NMI_PASS_MASK;
 ^
/home/petmay01/qemu-for-merges/hw/i386/amd_iommu.h:245:46: error: left
shift count >= width of type [-Werror=shift-count-overflow]
 #define AMDVI_DEV_INT_PASS_MASK (1UL << 56)
  ^
/home/petmay01/qemu-for-merges/hw/i386/amd_iommu.c:1285:25: note: in
expansion of macro 'AMDVI_DEV_INT_PASS_MASK'
 pass = dte[3] & AMDVI_DEV_INT_PASS_MASK;
 ^
/home/petmay01/qemu-for-merges/hw/i386/amd_iommu.h:246:46: error: left
shift count >= width of type [-Werror=shift-count-overflow]
 #define AMDVI_DEV_EINT_PASS_MASK(1UL << 57)
  ^
/home/petmay01/qemu-for-merges/hw/i386/amd_iommu.c:1289:25: note: in
expansion of macro 'AMDVI_DEV_EINT_PASS_MASK'
 pass = dte[3] & AMDVI_DEV_EINT_PASS_MASK;
 ^

These should presumably all be "ULL". (The "UL" suffix is
usually a bug, as it's either unnecessary or should be ULL.)

On various Linux hosts (aarch64, s390, x86-64, sparc)
I get this assertion in the bios-tables-test:

  /x86_64/acpi/q35/mmio64:
Looking for expected file 'tests/acpi-test-data/q35/DSDT.mmio64'

Looking for expected file 'tests/acpi-test-data/q35/DSDT'

Using expected file 'tests/acpi-test-data/q35/DSDT'

Looking for expected file 'tests/acpi-test-data/q35/FACP.mmio64'

Looking for expected file 'tests/acpi-test-data/q35/FACP'

Using expected file 'tests/acpi-test-data/q35/FACP'

Looking for expected file 'tests/acpi-test-data/q35/APIC.mmio64'

Looking for expected file 'tests/acpi-test-data/q35/APIC'

Using expected file 'tests/acpi-test-data/q35/APIC'

Looking for expected file 'tests/acpi-test-data/q35/HPET.mmio64'

Looking for expected file 'tests/acpi-test-data/q35/HPET'

Using expected file 'tests/acpi-test-data/q35/HPET'

Looking for expected file 'tests/acpi-test-data/q35/SRAT.mmio64'

Looking for expected file 'tests/acpi-test-data/q35/SRAT'
**
ERROR:/home/petmay01/linaro/qemu-for-merges/tests/bios-tables-test.c:398:load_expected_aml:
assertion failed: (exp_sdt.aml_file)
FAIL


thanks
-- PMM



Re: [Qemu-devel] [PATCH v5 2/5] hw/riscv/virt: Connect the gpex PCIe

2018-10-25 Thread Peter Maydell
On 4 October 2018 at 21:06, Alistair Francis  wrote:
> Connect the gpex PCIe device based on the device tree included in the
> HiFive Unleashed ROM.
>
> Signed-off-by: Alistair Francis 
> ---
>  default-configs/riscv32-softmmu.mak |  6 ++-
>  default-configs/riscv64-softmmu.mak |  6 ++-
>  hw/riscv/virt.c | 58 +
>  include/hw/riscv/virt.h |  4 +-
>  4 files changed, 71 insertions(+), 3 deletions(-)

> +static inline DeviceState *
> +gpex_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr,
> + hwaddr cfg_base, uint64_t cfg_size,
> + hwaddr mmio_base, uint64_t mmio_size,
> + qemu_irq irq, bool link_up)
> +{
> +DeviceState *dev;
> +MemoryRegion *cfg, *mmio;
> +
> +dev = qdev_create(NULL, TYPE_GPEX_HOST);
> +
> +qdev_init_nofail(dev);
> +
> +cfg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
> +memory_region_add_subregion_overlap(sys_mem, cfg_base, cfg, 0);
> +
> +mmio = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
> +memory_region_add_subregion_overlap(sys_mem, 0, mmio, 0);

You probably also want to map the gpex's mmio region 2,
which is the PCI IO BAR window. Otherwise PCI devices
with IO BARs won't work right.

> +
> +sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);

GPEX has 4 interrupt lines, corresponding to classic PCI
IRQs A, B, C, D. You need to wire them all up, or only the
first PCI device plugged in will have a working interrupt.
You also don't look to have the bit of device-tree generation
that sets up the interrupt-map, which tells the guest about
the mapping from PCI devfns (ie, which slot the card is in) to
IRQ lines.

> +
> +return dev;
> +}
> +
>  static void riscv_virt_board_init(MachineState *machine)
>  {
>  const struct MemmapEntry *memmap = virt_memmap;
> @@ -382,6 +436,10 @@ static void riscv_virt_board_init(MachineState *machine)
>  qdev_get_gpio_in(DEVICE(s->plic), VIRTIO_IRQ + i));
>  }
>
> +gpex_pcie_init(system_memory, 0, memmap[VIRT_PCIE].base,
> +   memmap[VIRT_PCIE].size, 0x4000, 0x2000,

You could put the MMIO BAR window base and size in your memmap[] too...

> +   qdev_get_gpio_in(DEVICE(s->plic), PCIE_IRQ), 
> true);

thanks
-- PMM



Re: [Qemu-devel] [PULL] First RISC-V Patch Set for the 3.1 Soft Freeze

2018-10-25 Thread Peter Maydell
On 17 October 2018 at 22:54, Palmer Dabbelt  wrote:
> The following changes since commit 09558375a634e17cea6cfbfec883ac2376d2dc7f:
>
>   Merge remote-tracking branch 
> 'remotes/pmaydell/tags/pull-target-arm-20181016-1' into staging (2018-10-16 
> 17:42:56 +0100)
>
> are available in the Git repository at:
>
>   git://github.com/riscv/riscv-qemu.git tags/riscv-for-master-3.1-sf0
>
> for you to fetch changes up to 7c28f4da20e5585dce7d575691dac5392b7c6f78:
>
>   RISC-V: Don't add NULL bootargs to device-tree (2018-10-17 13:02:30 -0700)
>
> 
> First RISC-V Patch Set for the 3.1 Soft Freeze
>
> This pull request contains a handful of patches that have been floating
> around various trees for a while but haven't made it upstream.  These
> patches all appear quite safe.  They're all somewhat independent from
> each other:
>
> * One refactors our IRQ management function to allow multiple interrupts
>   to be raised an once.  This patch has no functional difference.
> * Cleaning up the op_helper/cpu_helper split.  This patch has no
>   functional difference.
> * Updates to various constants to keep them in sync with the latest ISA
>   specification and to remove some non-standard bits that snuck in.
> * A fix for a memory leak in the PLIC driver.
> * A fix to our device tree handling to avoid provinging a NULL string.
>
> I've given this my standard test: building the port, booting a Fedora
> root filesytem on the latest Linux tag, and then shutting down that
> image.  Essentially I'm just following the QEMU RISC-V wiki page's
> instructions.  Everything looks fine here.
>
> We have a lot more outstanding patches so I'll definately be submitting
> another PR for the soft freeze.
>
> 

Applied to master, thanks (following some off-list discussions
of what we are doing wrt who is submitting riscv upstream pullreqs).

-- PMM



Re: [Qemu-devel] Call for patches for the qemu-trivial pull request

2018-10-25 Thread Emilio G. Cota
On Tue, Oct 23, 2018 at 11:04:36 +0100, Laurent Vivier wrote:
> So, it would be helpful if any of you knowing that some patches have to
> be added to the pull request send me their list.

I sent this one in August:

 linux-user: fix comment s/atomic_write/atomic_set/
 https://lists.gnu.org/archive/html/qemu-devel/2018-08/msg01964.html

Thanks,

Emilio



Re: [Qemu-devel] [PATCH v8 00/38] target/mips: Limited support for the R5900

2018-10-25 Thread Fredrik Noring
Hi Maciej,

> > Is the membership field intended to be used? The opcodes for CLZ and CLO
> > clash with the R5900 opcodes for MADD1 and MADDU1, resulting in incorrect
> > disassembly of MADD1 and MADDU1. For example:
> > 
> > 0x70853020 madd1  a2,a0,a1  disassembles into  clz a2 or a1,a0
> > 0x70853021 maddu1 a2,a0,a1  disassembles into  clo a2 or a1,a0
> > 
> > (CLZ and CLO are members of I32|N55, whereas MADD1 and MADDU1 are EE.)
> 
>  It looks like a disassembler bug somewhere then (maybe in your patched 
> version only), because the R5900 is not supposed to match I32 (because it 
> does not implement the MIPS32 ISA; it's only MIPS I aka I1 with additions 
> or MIPS IV aka I4 with exclusions, or anything between with both additions 
> and exclusions, with I believe MIPS III aka I3 being the closest match), 
> and it is not supposed to match N55 either (because it is obviously not a 
> Vr5500 processor).

I think the "bug" is that the membership field is defined but unused, so
opcode memberships are simply ignored. OPCODE_IS_MEMBER is defined to be
always true, for all opcodes and all ISAs.

>  Overall this source file is clearly a modified copy of an ancient version 
> of the opcode table included with the opcodes library from binutils and I 
> think it would benefit from a refresh.  In particular separating an ASE 
> field and adding an exclusions field, as it has been done with opcodes, 
> would make it much easier to maintain this table.  The table in opcodes is 
> already messy due to several exceptions to the alphabetical order (and it 
> could be improved a bit I believe), but I find its QEMU version even 
> messier.

Agreed! QEMU's scripts/checkpatch.pl warns and errors on 80 and 90 column
violations, so trying avoid check breakage leaves the table unaligned too.

Fredrik



Re: [Qemu-devel] [RFC 0/2] Attempt to implement the standby feature for assigned network devices

2018-10-25 Thread Sameeh Jubran
On Thu, Oct 25, 2018 at 5:06 PM Sameeh Jubran  wrote:
>
> From: Sameeh Jubran 
>
> Hi all,
>
> Background:
>
> There has been a few attempts to implement the standby feature for vfio
> assigned devices which aims to enable the migration of such devices. This
> is another attempt.
>
> The series implements an infrastructure for hiding devices from the bus
> upon boot. What it does is the following:
>
> * In the first patch the infrastructure for hiding the device is added
>   for the qbus and qdev APIs. A "hidden" boolean is added to the device
>   state and it is set based on a callback to the standby device which
>   registers itself for handling the assessment: "should the primary device
>   be hidden?" by cross validating the ids of the devices.
>
> * In the second patch the virtio-net uses the API to hide the vfio
>   device and unhides it when the feature is acked.
>
> Disclaimers:
>
> * I have only scratch tested this and from qemu side, it seems to be
>   working.
> * This is an RFC so it lacks some proper error handling in few cases
>   and proper resource freeing. I wanted to get some feedback first
>   before it is finalized.
>
> Command line example:
>
> /home/sameeh/Builds/failover/qemu/x86_64-softmmu/qemu-system-x86_64 \
> -netdev 
> tap,id=hostnet0,script=world_bridge_standalone.sh,downscript=no,ifname=cc1_71 
> \
> -netdev 
> tap,vhost=on,id=hostnet1,script=world_bridge_standalone.sh,downscript=no,ifname=cc1_72,queues=4
>  \
> -device 
> virtio-net,host_mtu=1500,netdev=hostnet1,id=cc1_72,vectors=10,mq=on,primary=cc1_71
>  \
> -device e1000,netdev=hostnet0,id=cc1_71,standby=cc1_72 \
>
> Migration support:
>
> Pre migration or during setup phase of the migration we should send an
> unplug request to the guest to unplug the primary device. I haven't had
> the chance to implement that part yet but should do soon. Do you know
> what's the best approach to do so? I wanted to have a callback to the
> virtio-net device which tries to send an unplug request to the guest and
> if succeeds then the migration continues. It needs to handle the case where
> the migration fails and then it has to replug the primary device back.
I think that the "add_migration_state_change_notifier" API call can be used
from within the virtio-net device to achieve this, what do you think?
>
> The following terms are used as interchangeable:
> standby - virtio-net
> primary - vfio-device - physical device - assigned device
>
> Please share your thoughts and suggestions,
> Thanks!
>
> Sameeh Jubran (2):
>   qdev/qbus: Add hidden device support
>   virtio-net: Implement VIRTIO_NET_F_STANDBY feature
>
>  hw/core/qdev.c | 48 +---
>  hw/net/virtio-net.c| 25 +++
>  hw/pci/pci.c   |  1 +
>  include/hw/pci/pci.h   |  2 ++
>  include/hw/qdev-core.h | 11 ++-
>  include/hw/virtio/virtio-net.h |  5 +++
>  qdev-monitor.c | 58 --
>  7 files changed, 142 insertions(+), 8 deletions(-)
>
> --
> 2.17.0
>


-- 
Respectfully,
Sameeh Jubran
Linkedin
Software Engineer @ Daynix.



[Qemu-devel] [Bug 1799766] Re: -device does not work as -drive do

2018-10-25 Thread Yannick Duchêne
Yes, I messed up with `-device`, because I initially tried to do it with
`-device`, later rely only on automatically created device, and so had
automatically created devices.

Thanks for you rich comment, I will study it.

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

Title:
  -device does not work as -drive do

Status in QEMU:
  New

Bug description:
  Copy/paste of https://stackoverflow.com/questions/52929723/qemu-eject-
  complains-device-is-not-found-while-it-is-there , since I found this
  bug trying to find an answer to an own question on Stack Overflow.

  Below, what was my question the answer I wrote, all exposes the bug.

  

  
  I need to eject a floppy from QEmu 3.0 monitor, but the command surprisingly 
fails complaining the device is not found, while it is really there.

  Listing of devices:

  (qemu) info block
  fda: dos-6-22/Dos622-1.img (raw)
  Attached to:  /machine/unattached/device[11]
  Removable device: not locked, tray closed
  Cache mode:   writeback

  hda: hda.img (raw)
  Attached to:  /machine/peripheral-anon/device[1]
  Cache mode:   writeback

  Eject command result:

  (qemu) eject fda
  Device 'fda' not found

  This is so although this documentation says this is how I have to do:
  https://www.linux-kvm.org/page/Change_cdrom (just that I want to eject
  the floppy instead of the CD‑ROM).

  The `change` command complains the same:

  (qemu) change fda dos-6-22/Dos622-2.img raw
  Device 'fda' not found

  Is this a bug or me doing something wrong?

  I tried using different node names, with always the same result.

  

  I’m posting as an answer, but I’m not strictly sure. I can just say,
  if I understand correctly, this is a bug.

  The answer comes in two parts.

  First part, is a stripped down failing invocation:

  qemu-system-i386 \
 -monitor stdio \
 -machine type=isapc,vmport=off \
 -blockdev driver=file,node-name=fda-img,filename=fda.img \
 -blockdev driver=raw,node-name=fda,file=fda-img \
 -global isa-fdc.driveA=fda

  (qemu) info block
  ide1-cd0: [not inserted]
  Attached to:  /machine/unattached/device[19]
  Removable device: not locked, tray closed

  sd0: [not inserted]
  Removable device: not locked, tray closed

  fda: fda.img (raw)
  Attached to:  /machine/unattached/device[13]
  Removable device: not locked, tray closed
  Cache mode:   writeback
  (qemu) eject fda
  Device 'fda' not found

  Second part, is the same without the last argument `-global isa-
  fdc.driveA=fda`:

  qemu-system-i386 \
 -monitor stdio \
 -machine type=isapc,vmport=off \
 -blockdev driver=file,node-name=fda-img,filename=fda.img \
 -blockdev driver=raw,node-name=fda,file=fda-img

  (qemu) info block
  ide1-cd0: [not inserted]
  Attached to:  /machine/unattached/device[19]
  Removable device: not locked, tray closed

  floppy0: [not inserted]
  Attached to:  /machine/unattached/device[13]
  Removable device: not locked, tray closed

  sd0: [not inserted]
  Removable device: not locked, tray closed
  (qemu) eject floppy0

  There is more error when `-global isa-fdc.driveA=fda` is removed.
  However, the documentation says:

  > -global driver=driver,property=property,value=value
  > Set default value of driver’s property prop to value, e.g.:

  > qemu-system-i386 -global ide-hd.physical_block_size=4096 disk-image.img
  > In particular, you can **use this to set driver properties for devices 
which are created automatically by the machine model**. To create a device 
which is not created automatically and set properties on it, use -device.

  > -global driver.prop=value is shorthand for -global
  driver=driver,property=prop,value=value. The longhand syntax works
  even when driver contains a dot.

  What I put a stress on in the quote, suggest I’m not misusing
  `-global` and that’s most probably a bug.

  **Update for more details:**

  It seems using `-drive` instead of `-device` and `driveA` assignment,
  the result is not the same, although RedHat documentation recommands
  using `-device` instead of `-drive` and QEmu 3.0 documentation says
  `-drive` is essentially a shortcut for `-device` (“essentially”, not
  telling about the difference).

  Below, two cases, with an except of `info block` and an excerpt of
  `info qtree`.

  With this one, `eject floppy0` works:

  qemu-system-i386 \
 -monitor stdio \
 -machine type=isapc,vmport=off \
 -drive format=raw,if=floppy,media=disk,file=fda.img \

Re: [Qemu-devel] [PATCH v8 00/38] target/mips: Limited support for the R5900

2018-10-25 Thread Maciej W. Rozycki
Hi Fredrik,

> >  NB all but pipeline 1 instructions of these are also implemented by other 
> > members of the TXx9 family.  They seem to be referred to as just "multiply 
> > and multiply-add instructions" in the TX79 manual (cf Section B.3.1).
> 
> Would
> 
> ASE_TOSHIBA_MMI  -- TX79 128-bit multimedia instructions
> ASE_TOSHIBA_MAC  -- TXx9 multiply and multiply-add instructions (MADD etc.)
> ASE_TOSHIBA_MAC1 -- TX79 pipeline 1 variant of ASE_TOSHIBA_MAC
> ASE_TOSHIBA_FMA  -- R5900 FPU extensions (MADD.s etc.)
> 
> be acceptable for the currently known Toshiba extensions? (Please propose
> better names.) One complication is that it seems only 8 bits are available
> for all vendor ASEs, and Toshiba would then scoop up half of those.

 I'm not sure if every single random vendor-specific instruction (or a 
bunch of) deserves its own ASE designation, be it internal or externally 
exposed.  I think the MMI set being a substantial architectural feature 
makes sense to be shown in /proc/cpuinfo (in Linux), but I don't think 
there's much more about it.  It's limited to 2 implementations only, so 
internally I think it can well be handled with a macro or static inline 
function (as appropriate) which boil down to (CPU_R5900 || CPU_TX79).

 And if you run out of bits for ASEs regardless, then I suggest just to 
expand the field in question.  In QEMU you can rely on the presence of the 
`uint64_t' data type, so with only 8 bits exhausted you're far from 
getting into trouble.

  Maciej



[Qemu-devel] [PATCH 11/11] disas/mips: Disassemble R5900 DIV[U]1, M{F, T}{LO, HI}1 and MULT[U]1

2018-10-25 Thread Fredrik Noring
Disassemble the R5900 instructions DIV1, DIVU1, MFLO1, MTLO1, MFHI1,
MTHI1, MULT1 and MULTU1.

Signed-off-by: Fredrik Noring 
---
 disas/mips.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/disas/mips.c b/disas/mips.c
index 9f01fda8bd..eddfb59325 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -2323,6 +2323,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"div", "z,t",  0x001a, 0xffe0, RD_s|RD_t|WR_HILO,  0, 
I1  },
 {"div", "d,v,t",   0,(int) M_DIV_3,INSN_MACRO, 0,  
I1  },
 {"div", "d,v,I",   0,(int) M_DIV_3I,   INSN_MACRO, 0,  
I1  },
+{"div1","z,s,t",  0x701a, 0xfc00, RD_s | RD_t | WR_HILO, 0, EE },
+{"div1","z,t",0x701a, 0xffe0, RD_s | RD_t | WR_HILO, 0, EE },
 {"div.d",   "D,V,T",   0x4623, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,0,  
I1  },
 {"div.s",   "D,V,T",   0x4603, 0xffe0003f, WR_D|RD_S|RD_T|FP_S,0,  
I1  },
 {"div.ps",  "D,V,T",   0x46c3, 0xffe0003f, WR_D|RD_S|RD_T|FP_D,0,  
SB1 },
@@ -2331,6 +2333,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"divu","z,t",  0x001b, 0xffe0, RD_s|RD_t|WR_HILO,  0, 
I1  },
 {"divu","d,v,t",   0,(int) M_DIVU_3,   INSN_MACRO, 0,  
I1  },
 {"divu","d,v,I",   0,(int) M_DIVU_3I,  INSN_MACRO, 0,  
I1  },
+{"divu1",   "z,s,t",  0x701b, 0xfc00, RD_s | RD_t | WR_HILO, 0, EE },
+{"divu1",   "z,t",0x701b, 0xffe0, RD_s | WR_HILO   , 0, EE },
 {"dla", "t,A(b)",  0,(int) M_DLA_AB,   INSN_MACRO, 0,  
I3  },
 {"dlca","t,A(b)",  0,(int) M_DLCA_AB,  INSN_MACRO, 0,  
I3  },
 {"dli", "t,j",  0x2400, 0xffe0, WR_t,  0,  
I3  }, /* addiu */
@@ -2594,8 +2598,10 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"mfdr","t,G", 0x703d, 0xffe007ff, LCD|WR_t|RD_C0, 0,  
N5  },
 {"mfhi","d",   0x0010, 0x07ff, WR_d|RD_HI, 0,  
I1  },
 {"mfhi","d,9", 0x0010, 0xff9f07ff, WR_d|RD_HI, 0,  
D32 },
+{"mfhi1",   "d",  0x7010, 0x07ff, WR_d | RD_HI, 0, EE},
 {"mflo","d",   0x0012, 0x07ff, WR_d|RD_LO, 0,  
I1  },
 {"mflo","d,9", 0x0012, 0xff9f07ff, WR_d|RD_LO, 0,  
D32 },
+{"mflo1",   "d",  0x7012, 0x07ff, WR_d | RD_LO, 0, EE},
 {"mflhxu",  "d",   0x0052, 0x07ff, WR_d|MOD_HILO,  0,  
SMT },
 {"min.ob",  "X,Y,Q",   0x7806, 0xfc20003f, WR_D|RD_S|RD_T|FP_D,0,  
MX|SB1  },
 {"min.ob",  "D,S,T",   0x4ac6, 0xffe0003f, WR_D|RD_S|RD_T, 0,  
N54 },
@@ -2661,8 +2667,10 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"mtdr","t,G", 0x7080003d, 0xffe007ff, COD|RD_t|WR_C0, 0,  
N5  },
 {"mthi","s",   0x0011, 0xfc1f, RD_s|WR_HI, 0,  
I1  },
 {"mthi","s,7", 0x0011, 0xfc1fe7ff, RD_s|WR_HI, 0,  
D32 },
+{"mthi1",   "s",  0x7011, 0xfc1f, RD_s | WR_HI, 0, EE },
 {"mtlo","s",   0x0013, 0xfc1f, RD_s|WR_LO, 0,  
I1  },
 {"mtlo","s,7", 0x0013, 0xfc1fe7ff, RD_s|WR_LO, 0,  
D32 },
+{"mtlo1",   "s",  0x7013, 0xfc1f, RD_s | WR_LO, 0, EE },
 {"mtlhx",   "s",   0x0053, 0xfc1f, RD_s|MOD_HILO,  0,  
SMT },
 {"mttc0",   "t,G", 0x4180, 0xffe007ff, TRAP|COD|RD_t|WR_C0|WR_CC, 0,   
MT32},
 {"mttc0",   "t,+D",0x4180, 0xffe007f8, TRAP|COD|RD_t|WR_C0|WR_CC, 0,   
MT32},
@@ -2728,10 +2736,14 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"mult","s,t",  0x0018, 0xfc00, RD_s|RD_t|WR_HILO|IS_M, 0, 
I1  },
 {"mult","7,s,t",   0x0018, 0xfc00e7ff, WR_a|RD_s|RD_t, 0,  
D33 },
 {"mult","d,s,t",0x0018, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 
0,G1  },
+{"mult1",   "s,t",  0x7018, 0xfc00, RD_s | RD_t | WR_HILO | IS_M, 
0, EE },
+{"mult1",   "d,s,t", 0x7018, 0xfc0007ff, WR_d | RD_s | RD_t | WR_HILO | 
IS_M, 0, EE },
 {"multp",   "s,t", 0x0459, 0xfc00, RD_s|RD_t|MOD_HILO, 0,  
SMT },
 {"multu",   "s,t",  0x0019, 0xfc00, RD_s|RD_t|WR_HILO|IS_M, 0, 
I1  },
 {"multu",   "7,s,t",   0x0019, 0xfc00e7ff, WR_a|RD_s|RD_t, 0,  
D33 },
 {"multu",   "d,s,t",0x0019, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 
0,G1  },
+{"multu1",  "s,t",  

Re: [Qemu-devel] [PATCH v8 00/38] target/mips: Limited support for the R5900

2018-10-25 Thread Maciej W. Rozycki
Hi Fredrik,

> > > Option 3: Extend the mips_opcode::membership field.
> > 
> > It's trivial to extend the field to uint64_t.
> 
> Is the membership field intended to be used? The opcodes for CLZ and CLO
> clash with the R5900 opcodes for MADD1 and MADDU1, resulting in incorrect
> disassembly of MADD1 and MADDU1. For example:
> 
>   0x70853020 madd1  a2,a0,a1  disassembles into  clz a2 or a1,a0
>   0x70853021 maddu1 a2,a0,a1  disassembles into  clo a2 or a1,a0
> 
> (CLZ and CLO are members of I32|N55, whereas MADD1 and MADDU1 are EE.)

 It looks like a disassembler bug somewhere then (maybe in your patched 
version only), because the R5900 is not supposed to match I32 (because it 
does not implement the MIPS32 ISA; it's only MIPS I aka I1 with additions 
or MIPS IV aka I4 with exclusions, or anything between with both additions 
and exclusions, with I believe MIPS III aka I3 being the closest match), 
and it is not supposed to match N55 either (because it is obviously not a 
Vr5500 processor).

 Overall this source file is clearly a modified copy of an ancient version 
of the opcode table included with the opcodes library from binutils and I 
think it would benefit from a refresh.  In particular separating an ASE 
field and adding an exclusions field, as it has been done with opcodes, 
would make it much easier to maintain this table.  The table in opcodes is 
already messy due to several exceptions to the alphabetical order (and it 
could be improved a bit I believe), but I find its QEMU version even 
messier.

 HTH,

  Maciej



[Qemu-devel] [PATCH 01/11] target/mips: Rename ASE_MMI to ASE_TOSHIBA_MMI, with Toshiba namespace

2018-10-25 Thread Fredrik Noring
Several vendors have multimedia instruction (MMI) sets and other
extensions of various kinds. ASE vendor namespaces make it clear these
are not generic architectural features and also avoid name clashes.

Reported-by: Maciej W. Rozycki 
Signed-off-by: Fredrik Noring 
---
 target/mips/mips-defs.h  | 2 +-
 target/mips/translate.c  | 3 ++-
 target/mips/translate_init.inc.c | 2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
index 5177618615..30b07e0bde 100644
--- a/target/mips/mips-defs.h
+++ b/target/mips/mips-defs.h
@@ -68,7 +68,7 @@
 /*
  *   bits 56-63: vendor-specific ASEs
  */
-#define ASE_MMI   0x0100ULL
+#define ASE_TOSHIBA_MMI   0x0100ULL
 
 /* MIPS CPU defines. */
 #defineCPU_MIPS1   (ISA_MIPS1)
diff --git a/target/mips/translate.c b/target/mips/translate.c
index c44a751be9..8547a6e6f6 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -26092,7 +26092,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext 
*ctx)
 decode_opc_special(env, ctx);
 break;
 case OPC_SPECIAL2:
-if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
+if ((ctx->insn_flags & INSN_R5900) &&
+(ctx->insn_flags & ASE_TOSHIBA_MMI)) {
 decode_tx79_mmi(env, ctx);
 } else {
 decode_opc_special2_legacy(env, ctx);
diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c
index 85da4a269c..5cd968366b 100644
--- a/target/mips/translate_init.inc.c
+++ b/target/mips/translate_init.inc.c
@@ -466,7 +466,7 @@ const mips_def_t mips_defs[] =
 #endif /* !CONFIG_USER_ONLY */
 .SEGBITS = 32,
 .PABITS = 32,
-.insn_flags = CPU_R5900 | ASE_MMI,
+.insn_flags = CPU_R5900 | ASE_TOSHIBA_MMI,
 .mmu_type = MMU_TYPE_R4000,
 },
 {
-- 
2.18.1




[Qemu-devel] [PATCH 04/11] target/mips: Support R5900 three-operand MADD1 and MADDU1

2018-10-25 Thread Fredrik Noring
Signed-off-by: Fredrik Noring 
---
 target/mips/translate.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index add6203c5a..208a15c0c1 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -4813,7 +4813,7 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
  *
  * and
  *
- * MADD[U]rd, rs, rt
+ * MADD[U][1] rd, rs, rt
  *
  * such that
  *
@@ -4875,6 +4875,9 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
 tcg_temp_free_i32(t3);
 }
 break;
+case TX79_MMI_MADD1:
+acc = 1;
+/* Fall through */
 case TX79_MMI_MADD:
 {
 TCGv_i64 t2 = tcg_temp_new_i64();
@@ -4894,6 +4897,9 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
 tcg_temp_free_i64(t2);
 }
 break;
+case TX79_MMI_MADDU1:
+acc = 1;
+/* Fall through */
 case TX79_MMI_MADDU:
 {
 TCGv_i64 t2 = tcg_temp_new_i64();
@@ -24749,6 +24755,8 @@ static void decode_tx79_mmi(CPUMIPSState *env, 
DisasContext *ctx)
 case TX79_MMI_MULTU1:
 case TX79_MMI_MADD:
 case TX79_MMI_MADDU:
+case TX79_MMI_MADD1:
+case TX79_MMI_MADDU1:
 gen_mul_txx9(ctx, opc, rd, rs, rt);
 break;
 case TX79_MMI_DIV1:
@@ -24764,8 +24772,6 @@ static void decode_tx79_mmi(CPUMIPSState *env, 
DisasContext *ctx)
 gen_HILO(ctx, opc, 1, rd);
 break;
 case TX79_MMI_PLZCW: /* TODO: TX79_MMI_PLZCW */
-case TX79_MMI_MADD1: /* TODO: TX79_MMI_MADD1 */
-case TX79_MMI_MADDU1:/* TODO: TX79_MMI_MADDU1 */
 case TX79_MMI_PMFHL: /* TODO: TX79_MMI_PMFHL */
 case TX79_MMI_PMTHL: /* TODO: TX79_MMI_PMTHL */
 case TX79_MMI_PSLLH: /* TODO: TX79_MMI_PSLLH */
-- 
2.18.1




[Qemu-devel] [PATCH 09/11] disas/mips: Increase 'member of ISAs' flag holder size

2018-10-25 Thread Fredrik Noring
From: Philippe Mathieu-Daudé 

Increase the size of 'membership' holder size to 64 bits. This is
needed for future extensions since existing bits are almost all used.
This change is related to commit f9c9cd63e3 "target/mips: Increase
'supported ISAs/ASEs' flag holder size".

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Tested-by: Fredrik Noring 
Signed-off-by: Fredrik Noring 
---
 disas/mips.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/disas/mips.c b/disas/mips.c
index 97f661a37e..d73d4094d8 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -301,7 +301,7 @@ struct mips_opcode
   unsigned long pinfo2;
   /* A collection of bits describing the instruction sets of which this
  instruction or macro is a member. */
-  unsigned long membership;
+  uint64_t membership;
 };
 
 /* These are the characters which may appear in the args field of an
-- 
2.18.1




[Qemu-devel] [PATCH 10/11] disas/mips: Define R5900 disassembly constants

2018-10-25 Thread Fredrik Noring
Amend definition for MIPS ISAs in disassembler with R5900.

Signed-off-by: Fredrik Noring 
---
 disas/mips.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/disas/mips.c b/disas/mips.c
index d73d4094d8..9f01fda8bd 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -611,6 +611,9 @@ struct mips_opcode
 /* ST Microelectronics Loongson 2F.  */
 #define INSN_LOONGSON_2F  0x8000
 
+/* Sony/Toshiba R5900 */
+#define INSN_5900 0x1
+
 /* MIPS ISA defines, use instead of hardcoding ISA level.  */
 
 #define   ISA_UNKNOWN 0   /* Gas internal use.  */
@@ -646,6 +649,7 @@ struct mips_opcode
 #define CPU_R5000  5000
 #define CPU_VR5400 5400
 #define CPU_VR5500 5500
+#define CPU_R5900   5900
 #define CPU_R6000  6000
 #define CPU_RM7000 7000
 #define CPU_R8000  8000
@@ -1193,6 +1197,7 @@ extern const int bfd_mips16_num_opcodes;
 #define N5 (INSN_5400 | INSN_5500)
 #define N54INSN_5400
 #define N55INSN_5500
+#define EE  INSN_5900/* Emotion Engine */
 
 #define G1  (T3 \
  )
@@ -3861,6 +3866,7 @@ struct mips_arch_choice
 #define bfd_mach_mips5000  5000
 #define bfd_mach_mips5400  5400
 #define bfd_mach_mips5500  5500
+#define bfd_mach_mips5900  5900
 #define bfd_mach_mips6000  6000
 #define bfd_mach_mips7000  7000
 #define bfd_mach_mips8000  8000
@@ -3908,6 +3914,8 @@ static const struct mips_arch_choice mips_arch_choices[] =
 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
   { "vr5500",  1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4,
 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
+  { "r5900",1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3,
+mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
   { "r6000",   1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2,
 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
   { "rm7000",  1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4,
-- 
2.18.1




[Qemu-devel] [PATCH 05/11] tests/tcg/mips: Test R5900 three-operand MADD

2018-10-25 Thread Fredrik Noring
Signed-off-by: Fredrik Noring 
---
 tests/tcg/mips/mipsr5900/Makefile |  1 +
 tests/tcg/mips/mipsr5900/madd.c   | 45 +++
 2 files changed, 46 insertions(+)
 create mode 100644 tests/tcg/mips/mipsr5900/madd.c

diff --git a/tests/tcg/mips/mipsr5900/Makefile 
b/tests/tcg/mips/mipsr5900/Makefile
index a1c388bc3c..97ca2a671c 100644
--- a/tests/tcg/mips/mipsr5900/Makefile
+++ b/tests/tcg/mips/mipsr5900/Makefile
@@ -10,6 +10,7 @@ CFLAGS  = -Wall -mabi=32 -march=r5900 -static
 
 TESTCASES = div1.tst
 TESTCASES += divu1.tst
+TESTCASES += madd.tst
 TESTCASES += mflohi1.tst
 TESTCASES += mtlohi1.tst
 TESTCASES += mult.tst
diff --git a/tests/tcg/mips/mipsr5900/madd.c b/tests/tcg/mips/mipsr5900/madd.c
new file mode 100644
index 00..9ad2ea6dbb
--- /dev/null
+++ b/tests/tcg/mips/mipsr5900/madd.c
@@ -0,0 +1,45 @@
+/*
+ * Test R5900-specific three-operand MADD.
+ */
+
+#include 
+#include 
+#include 
+
+int64_t madd(int64_t a, int32_t rs, int32_t rt)
+{
+int32_t lo = a;
+int32_t hi = a >> 32;
+int32_t rd;
+int64_t r;
+
+__asm__ __volatile__ (
+"mtlo %5\n"
+"mthi %6\n"
+"madd %0, %3, %4\n"
+"mflo %1\n"
+"mfhi %2\n"
+: "=r" (rd), "=r" (lo), "=r" (hi)
+: "r" (rs), "r" (rt), "r" (lo), "r" (hi));
+r = ((int64_t)hi << 32) | (uint32_t)lo;
+
+assert(a + (int64_t)rs * rt == r);
+assert(rd == lo);
+
+return r;
+}
+
+static void verify_madd(int64_t a, int32_t rs, int32_t rt, int64_t expected)
+{
+assert(madd(a, rs, rt) == expected);
+assert(madd(a, -rs, rt) == a + a - expected);
+assert(madd(a, rs, -rt) == a + a - expected);
+assert(madd(a, -rs, -rt) == expected);
+}
+
+int main()
+{
+verify_madd(13, 17, 19, 336);
+
+return 0;
+}
-- 
2.18.1




[Qemu-devel] [RFC 00/48] Plugin support

2018-10-25 Thread Emilio G. Cota
For those of you who need some context: "plugins" are dynamic
libraries that are loaded at run-time. These plugins can
subscribe to interesting events (e.g. instruction execution)
via an API, to then do something interesting with them. This
functionality is similar to what other instrumentation tools (e.g.
Pin and DynamoRIO) provide, although since QEMU is full-system
we have some additional features.

As an example application, I've been using this plugin implementation
for the last year or so to implement a parallel computer simulator
that uses QEMU as its execution frontend.

The key features of this plugin implementation are:

- Support for an arbitrary number of plugins

- Focus on speed. "Dynamic" callbacks are used for frequent events,
  such as memory callbacks, to call the plugin code directly, i.e.
  without going through an intermediate helper. This provides
  an average 1.33x speedup for SPEC06 over using helpers with a list
  of subscribers, and it becomes more important as more subscribers
  are added. I can share more detailed numbers if you want them.

- Instruction-granularity instrumentation. Getting callbacks
  on *all* TBs/mem accesses/instructions is not flexible. Consider
  a plugin that just wants to get callbacks on the specific memory
  accesses of a set of instructions (e.g. cmpxchg); the API
  must provide a way for the plugin to subscribe to those events
  *only*, instead of giving it all events (e.g. all mem accesses)
  for the plugin to then discard 99.9% of them.

- 2-pass translation. Once a "TB translation" callback is called,
  the plugin must know the span of the TB. We should not
  force plugins to guess where the TB will end; that is strictly
  QEMU's job, and can change any time. A TB is thus a sequence
  of instructions of whatever length the particular QEMU
  implementation decides. Thus, for each TB, a 3-step process
  is followed: (1) the plugin layer keeps a copy of the contents
  of the current TB, (2) once the TB is well-defined, its
  descriptor and contents are passed to plugins, which then
  register their desired instrumentation (e.g. "call me back
  on this particular instruction", or "call me back when
  the whole TB executes"); note that plugins can use a disassembler
  like capstone to decide what to do with each instruction; they
  can also allocate memory and then get a pointer to it passed
  back from the callbacks. And finally, (3) the target translator
  is called again to generate the final instrumented translated TB.
  This is what I called the "2-pass translation", since we go
  twice over the translation loop in translator.c. Note that the
  2-pass approach has virtually no overhead (0.40% for SPEC06int);
  translation is much cheaper than execution. But anyway, if no
  plugins have subscribed to TB translation, we only do one pass.

- Support for inlining instrumentation. This is done via an
  explicit API, i.e. we do not export TCG ops, which are internal
  to QEMU. For now, I just have support for incrementing a u64
  with an immediate, e.g. to increment a counter.

- Treating the plugins as "malicious", in that we don't export
  any pointers to key QEMU data structures (CPUState, TB).
  I implemented this after a comment from Stefan, but maybe it is
  a bit overkill.

- Other features that go beyond passively getting callbacks (I need
  these for the simulator):
  + Control of the virtual clock from plugins
  + CPU lockstep execution, where plugins decide when CPUs must
synchronize to reduce their execution skew. This can be understood
as a "parallel icount" mode, although plugins can decide to
synchronize whenever they want, not whenever a certain amount of
instructions have execution. For instance, I am using this to
synchronize CPUs every X number of simulated cycles, thereby
having the ability to limit skew while maintaining parallelism.
When a CPU is idle, then we assume its "execution window" (aka
"time slice") has expired.
  + Guest hooks. Instead of using "magic" instructions, export a
PCI device and let plugins determine what encoding to follow.
I'm using this to mark regions of interest in guest programs,
so that in the simulator I start/stop recording simulation events.

- Things I haven't included here:
  + Ability to emulate devices from plugins. I'm using this to
simulate peripherals. These are devices whose timing is important
to overall performance (e.g. 'accelerators' to which the main
CPU offloads computation, e.g. a JPEG encoder).

The design I'm showing here shares nothing with the tracing infrastructure.
While it is true that some features (e.g. syscall callbacks) are
identical, some others (instruction-granularity instrumentation,
2-pass translation, lockstep execution) are not. So I'm open to
discussing where we could save code (e.g. having a single trace+plugin
generator, e.g. for syscalls), as long as performance and/or the
ability to instrument aren't 

[Qemu-devel] [PATCH 08/11] tests/tcg/mips: Test R5900 three-operand MADDU1

2018-10-25 Thread Fredrik Noring
Signed-off-by: Fredrik Noring 
---
 tests/tcg/mips/mipsr5900/maddu.c | 37 ++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/tests/tcg/mips/mipsr5900/maddu.c b/tests/tcg/mips/mipsr5900/maddu.c
index e4e552102d..30936fb2b4 100644
--- a/tests/tcg/mips/mipsr5900/maddu.c
+++ b/tests/tcg/mips/mipsr5900/maddu.c
@@ -1,5 +1,5 @@
 /*
- * Test R5900-specific three-operand MADDU.
+ * Test R5900-specific three-operand MADDU and MADDU1.
  */
 
 #include 
@@ -29,9 +29,42 @@ uint64_t maddu(uint64_t a, uint32_t rs, uint32_t rt)
 return r;
 }
 
+uint64_t maddu1(uint64_t a, uint32_t rs, uint32_t rt)
+{
+uint32_t lo = a;
+uint32_t hi = a >> 32;
+uint32_t rd;
+uint64_t r;
+
+__asm__ __volatile__ (
+"mtlo1  %5\n"
+"mthi1  %6\n"
+"maddu1 %0, %3, %4\n"
+"mflo1  %1\n"
+"mfhi1  %2\n"
+: "=r" (rd), "=r" (lo), "=r" (hi)
+: "r" (rs), "r" (rt), "r" (lo), "r" (hi));
+r = ((uint64_t)hi << 32) | (uint32_t)lo;
+
+assert(a + (uint64_t)rs * rt == r);
+assert(rd == lo);
+
+return r;
+}
+
+static int64_t maddu_variants(int64_t a, int32_t rs, int32_t rt)
+{
+int64_t rd  = maddu(a, rs, rt);
+int64_t rd1 = maddu1(a, rs, rt);
+
+assert(rd == rd1);
+
+return rd;
+}
+
 int main()
 {
-assert(maddu(13, 17, 19) == 336);
+assert(maddu_variants(13, 17, 19) == 336);
 
 return 0;
 }
-- 
2.18.1




Re: [Qemu-devel] [PULL v2 05/43] hw/timer/sun4v-rtc: Convert from DPRINTF() macro to trace events

2018-10-25 Thread David Gibson
On Thu, Oct 25, 2018 at 10:32:23AM -0300, Eduardo Habkost wrote:
> From: Philippe Mathieu-Daudé 
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> Reviewed-by: Artyom Tarasenko 
> Reviewed-by: Cédric Le Goater 
> Message-Id: <20181002212522.23303-3-f4...@amsat.org>
> Signed-off-by: Eduardo Habkost 
> ---
>  hw/timer/sun4v-rtc.c  | 13 +++--
>  hw/timer/trace-events |  4 
>  2 files changed, 7 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/timer/sun4v-rtc.c b/hw/timer/sun4v-rtc.c
> index 310523225f..13be94f8da 100644
> --- a/hw/timer/sun4v-rtc.c
> +++ b/hw/timer/sun4v-rtc.c
> @@ -14,15 +14,8 @@
>  #include "hw/sysbus.h"
>  #include "qemu/timer.h"
>  #include "hw/timer/sun4v-rtc.h"
> +#include "trace.h"
>  
> -//#define DEBUG_SUN4V_RTC
> -
> -#ifdef DEBUG_SUN4V_RTC
> -#define DPRINTF(fmt, ...)   \
> -do { printf("sun4v_rtc: " fmt , ## __VA_ARGS__); } while (0)
> -#else
> -#define DPRINTF(fmt, ...) do {} while (0)
> -#endif
>  
>  #define TYPE_SUN4V_RTC "sun4v_rtc"
>  #define SUN4V_RTC(obj) OBJECT_CHECK(Sun4vRtc, (obj), TYPE_SUN4V_RTC)
> @@ -41,14 +34,14 @@ static uint64_t sun4v_rtc_read(void *opaque, hwaddr addr,
>  /* accessing the high 32 bits */
>  val >>= 32;
>  }
> -DPRINTF("read from " TARGET_FMT_plx " val %lx\n", addr, val);
> +trace_sun4v_rtc_read(addr, val);
>  return val;
>  }
>  
>  static void sun4v_rtc_write(void *opaque, hwaddr addr,
>   uint64_t val, unsigned size)
>  {
> -DPRINTF("write 0x%x to " TARGET_FMT_plx "\n", (unsigned)val, addr);
> +trace_sun4v_rtc_read(addr, val);

Uh.. as in v1, it looks like this should be trace_sun4v_rtc_write().

>  }
>  
>  static const MemoryRegionOps sun4v_rtc_ops = {
> diff --git a/hw/timer/trace-events b/hw/timer/trace-events
> index ca9ad6321a..75bd3b1042 100644
> --- a/hw/timer/trace-events
> +++ b/hw/timer/trace-events
> @@ -66,5 +66,9 @@ cmsdk_apb_dualtimer_read(uint64_t offset, uint64_t data, 
> unsigned size) "CMSDK A
>  cmsdk_apb_dualtimer_write(uint64_t offset, uint64_t data, unsigned size) 
> "CMSDK APB dualtimer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
>  cmsdk_apb_dualtimer_reset(void) "CMSDK APB dualtimer: reset"
>  
> +# hw/timer/sun4v-rtc.c
> +sun4v_rtc_read(uint64_t addr, uint64_t value) "read: addr 0x%" PRIx64 " 
> value 0x%" PRIx64
> +sun4v_rtc_write(uint64_t addr, uint64_t value) "write: addr 0x%" PRIx64 " 
> value 0x%" PRIx64
> +
>  # hw/timer/xlnx-zynqmp-rtc.c
>  xlnx_zynqmp_rtc_gettime(int year, int month, int day, int hour, int min, int 
> sec) "Get time from host: %d-%d-%d %2d:%02d:%02d"

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


signature.asc
Description: PGP signature


[Qemu-devel] [PATCH 02/11] target/mips: R5900 LQ and SQ also belong to the Toshiba MMI ASE

2018-10-25 Thread Fredrik Noring
Signed-off-by: Fredrik Noring 
---
 target/mips/translate.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 8547a6e6f6..18167df26d 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -26100,7 +26100,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext 
*ctx)
 }
 break;
 case OPC_SPECIAL3:
-if (ctx->insn_flags & INSN_R5900) {
+if ((ctx->insn_flags & INSN_R5900) &&
+(ctx->insn_flags & ASE_TOSHIBA_MMI)) {
 decode_tx79_sq(env, ctx);/* TX79_SQ */
 } else {
 decode_opc_special3(env, ctx);
@@ -26764,7 +26765,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext 
*ctx)
 }
 break;
 case OPC_MSA: /* OPC_MDMX */
-if (ctx->insn_flags & INSN_R5900) {
+if ((ctx->insn_flags & INSN_R5900) &&
+(ctx->insn_flags & ASE_TOSHIBA_MMI)) {
 decode_tx79_lq(env, ctx);/* TX79_LQ */
 } else {
 /* MDMX: Not implemented. */
-- 
2.18.1




[Qemu-devel] [RFC 05/48] include: move exec/tb-hash-xx.h to qemu/xxhash.h

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 include/exec/tb-hash.h   | 2 +-
 include/{exec/tb-hash-xx.h => qemu/xxhash.h} | 6 +++---
 tests/qht-bench.c| 2 +-
 util/qsp.c   | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)
 rename include/{exec/tb-hash-xx.h => qemu/xxhash.h} (97%)

diff --git a/include/exec/tb-hash.h b/include/exec/tb-hash.h
index 731ba4c272..4f3a37d927 100644
--- a/include/exec/tb-hash.h
+++ b/include/exec/tb-hash.h
@@ -20,7 +20,7 @@
 #ifndef EXEC_TB_HASH_H
 #define EXEC_TB_HASH_H
 
-#include "exec/tb-hash-xx.h"
+#include "qemu/xxhash.h"
 
 #ifdef CONFIG_SOFTMMU
 
diff --git a/include/exec/tb-hash-xx.h b/include/qemu/xxhash.h
similarity index 97%
rename from include/exec/tb-hash-xx.h
rename to include/qemu/xxhash.h
index 98ce4b628a..fe35dde328 100644
--- a/include/exec/tb-hash-xx.h
+++ b/include/qemu/xxhash.h
@@ -31,8 +31,8 @@
  * - xxHash source repository : https://github.com/Cyan4973/xxHash
  */
 
-#ifndef EXEC_TB_HASH_XX_H
-#define EXEC_TB_HASH_XX_H
+#ifndef QEMU_XXHASH_H
+#define QEMU_XXHASH_H
 
 #include "qemu/bitops.h"
 
@@ -119,4 +119,4 @@ static inline uint32_t qemu_xxhash6(uint64_t ab, uint64_t 
cd, uint32_t e,
 return qemu_xxhash7(ab, cd, e, f, 0);
 }
 
-#endif /* EXEC_TB_HASH_XX_H */
+#endif /* QEMU_XXHASH_H */
diff --git a/tests/qht-bench.c b/tests/qht-bench.c
index 2ea132fe57..4d885ca303 100644
--- a/tests/qht-bench.c
+++ b/tests/qht-bench.c
@@ -9,7 +9,7 @@
 #include "qemu/atomic.h"
 #include "qemu/qht.h"
 #include "qemu/rcu.h"
-#include "exec/tb-hash-xx.h"
+#include "qemu/xxhash.h"
 
 struct thread_stats {
 size_t rd;
diff --git a/util/qsp.c b/util/qsp.c
index dc29c41fde..410f1ba004 100644
--- a/util/qsp.c
+++ b/util/qsp.c
@@ -61,7 +61,7 @@
 #include "qemu/timer.h"
 #include "qemu/qht.h"
 #include "qemu/rcu.h"
-#include "exec/tb-hash-xx.h"
+#include "qemu/xxhash.h"
 
 enum QSPType {
 QSP_MUTEX,
-- 
2.17.1




[Qemu-devel] [PATCH 07/11] tests/tcg/mips: Test R5900 three-operand MADDU

2018-10-25 Thread Fredrik Noring
Signed-off-by: Fredrik Noring 
---
 tests/tcg/mips/mipsr5900/Makefile |  1 +
 tests/tcg/mips/mipsr5900/maddu.c  | 37 +++
 2 files changed, 38 insertions(+)
 create mode 100644 tests/tcg/mips/mipsr5900/maddu.c

diff --git a/tests/tcg/mips/mipsr5900/Makefile 
b/tests/tcg/mips/mipsr5900/Makefile
index 97ca2a671c..27ee5d5f54 100644
--- a/tests/tcg/mips/mipsr5900/Makefile
+++ b/tests/tcg/mips/mipsr5900/Makefile
@@ -11,6 +11,7 @@ CFLAGS  = -Wall -mabi=32 -march=r5900 -static
 TESTCASES = div1.tst
 TESTCASES += divu1.tst
 TESTCASES += madd.tst
+TESTCASES += maddu.tst
 TESTCASES += mflohi1.tst
 TESTCASES += mtlohi1.tst
 TESTCASES += mult.tst
diff --git a/tests/tcg/mips/mipsr5900/maddu.c b/tests/tcg/mips/mipsr5900/maddu.c
new file mode 100644
index 00..e4e552102d
--- /dev/null
+++ b/tests/tcg/mips/mipsr5900/maddu.c
@@ -0,0 +1,37 @@
+/*
+ * Test R5900-specific three-operand MADDU.
+ */
+
+#include 
+#include 
+#include 
+
+uint64_t maddu(uint64_t a, uint32_t rs, uint32_t rt)
+{
+uint32_t lo = a;
+uint32_t hi = a >> 32;
+uint32_t rd;
+uint64_t r;
+
+__asm__ __volatile__ (
+"mtlo  %5\n"
+"mthi  %6\n"
+"maddu %0, %3, %4\n"
+"mflo  %1\n"
+"mfhi  %2\n"
+: "=r" (rd), "=r" (lo), "=r" (hi)
+: "r" (rs), "r" (rt), "r" (lo), "r" (hi));
+r = ((uint64_t)hi << 32) | (uint32_t)lo;
+
+assert(a + (uint64_t)rs * rt == r);
+assert(rd == lo);
+
+return r;
+}
+
+int main()
+{
+assert(maddu(13, 17, 19) == 336);
+
+return 0;
+}
-- 
2.18.1




[Qemu-devel] [RFC 08/48] tcg: export tcg_gen_runtime_helper

2018-10-25 Thread Emilio G. Cota
This takes the TCGHelperInfo directly, which will allow us to generate
helpers at run-time.

Signed-off-by: Emilio G. Cota 
---
 tcg/tcg.h |  2 ++
 tcg/tcg.c | 50 +-
 2 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/tcg/tcg.h b/tcg/tcg.h
index 9f9643b470..3fa434d891 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -1077,6 +1077,8 @@ do {\
 bool tcg_op_supported(TCGOpcode op);
 
 void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args);
+void tcg_gen_runtime_helper(const TCGHelperInfo *orig, TCGTemp *ret, int nargs,
+TCGTemp **args);
 
 TCGOp *tcg_emit_op(TCGOpcode opc);
 void tcg_op_remove(TCGContext *s, TCGOp *op);
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 08b6926894..87e02da740 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1642,15 +1642,13 @@ bool tcg_op_supported(TCGOpcode op)
 /* Note: we convert the 64 bit args to 32 bit and do some alignment
and endian swap. Maybe it would be better to do the alignment
and endian swap in tcg_reg_alloc_call(). */
-void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
+static void do_tcg_gen_callN(TCGHelperInfo *info, TCGTemp *ret, int nargs,
+ TCGTemp **args)
 {
 int i, real_args, nb_rets, pi;
 unsigned sizemask, flags;
-TCGHelperInfo *info;
-uint32_t hash = tcg_helper_func_hash(func);
 TCGOp *op;
 
-info = qht_lookup_custom(_table, func, hash, tcg_helper_lookup_cmp);
 flags = info->flags;
 sizemask = info->sizemask;
 
@@ -1774,7 +1772,7 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, 
TCGTemp **args)
 op->args[pi++] = temp_arg(args[i]);
 real_args++;
 }
-op->args[pi++] = (uintptr_t)func;
+op->args[pi++] = (uintptr_t)info->func;
 op->args[pi++] = flags;
 TCGOP_CALLI(op) = real_args;
 
@@ -1812,6 +1810,48 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, 
TCGTemp **args)
 #endif /* TCG_TARGET_EXTEND_ARGS */
 }
 
+void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args)
+{
+TCGHelperInfo *info;
+uint32_t hash = tcg_helper_func_hash(func);
+
+/*
+ * Here we can get away with tcg_helper_lookup_cmp, which only looks
+ * at the function pointer, since we have the compile-time guarantee
+ * that @func can only be in one TCGHelperInfo.
+ */
+info = qht_lookup_custom(_table, func, hash, tcg_helper_lookup_cmp);
+do_tcg_gen_callN(info, ret, nargs, args);
+}
+
+void tcg_gen_runtime_helper(const TCGHelperInfo *orig, TCGTemp *ret, int nargs,
+TCGTemp **args)
+{
+TCGHelperInfo *info;
+uint32_t hash = tcg_helper_func_hash(orig->func);
+
+/*
+ * Use the full TCGHelperInfo lookup, since there is no guarantee that func
+ * will be unique to each TCGHelperInfo. For instance, we could have the
+ * same helper function registered in several TCGHelperInfo's, each of them
+ * with different flags.
+ */
+info = qht_lookup(_table, orig, hash);
+if (info == NULL) {
+void *existing = NULL;
+
+/* @orig might be in the stack, so we need to allocate a new struct */
+info = g_new(TCGHelperInfo, 1);
+memcpy(info, orig, sizeof(TCGHelperInfo));
+qht_insert(_table, info, hash, );
+if (unlikely(existing)) {
+g_free(info);
+info = existing;
+}
+}
+do_tcg_gen_callN(info, ret, nargs, args);
+}
+
 static void tcg_reg_alloc_start(TCGContext *s)
 {
 int i, n;
-- 
2.17.1




[Qemu-devel] [PATCH 00/11] target/mips: Amend R5900 support

2018-10-25 Thread Fredrik Noring
This series amends the R5900 support with the following noncritical
features:

- The vendor-specific Application-Specific Extension (ASE) ASE_MMI is
  renamed to ASE_TOSHIBA_MMI, because several vendors have multimedia
  instruction (MMI) sets and other extensions of various kinds. ASE
  vendor namespaces make it clear these are not generic architectural
  features and also avoid name clashes.

- The R5900 LQ and SQ instructions are now also covered by the Toshiba
  MMI ASE, as per the TX79 manual[1].

- The three-operand MADD and MADDU instructions specific to the R5900
  and the Toshiba TX19, TX39 and TX79 cores are now supported and tested
  by the R5900 TCG test suite.

- The three-operand MADD1 and MADDU1 pipeline 1 instructions specific
  to the R5900 and the Toshiba TX79 core are now supported and tested
  by the R5900 TCG test suite.

- The membership field of struct mips_opcode is now uint64_t instead
  of unsigned long, that is too small in 32-bit builds.

- R5900 disassembly constants are defined.

- The R5900 instructions DIV1, DIVU1, MFLO, MTLO, MFHI, MTHI, MULT1 and
  MULTU1 are now disassembled. Unfortunately, the opcodes for MADD1 and
  MADDU1 clash with the opcodes for CLZ and CLO, resulting in incorrect
  disassembly. MADD1 and MADDU1 are therefore left undefined.

This series has been successfully built with the 16 different build
configurations

{gcc,clang} x -m{32,64} x mips{,64}el-{linux-user,softmmu}

in addition to successfully completing the R5900 test suite

cd tests/tcg/mips/mipsr5900 && make check

Reference:

[1] "Toshiba TX System RISC TX79 Core Architecture", Toshiba Corporation,
section B.3.2, p. B-4, .

Fredrik Noring (9):
  target/mips: Rename ASE_MMI to ASE_TOSHIBA_MMI, with Toshiba namespace
  target/mips: R5900 LQ and SQ also belong to the Toshiba MMI ASE
  target/mips: Support R5900 three-operand MADD1 and MADDU1
  tests/tcg/mips: Test R5900 three-operand MADD
  tests/tcg/mips: Test R5900 three-operand MADD1
  tests/tcg/mips: Test R5900 three-operand MADDU
  tests/tcg/mips: Test R5900 three-operand MADDU1
  disas/mips: Define R5900 disassembly constants
  disas/mips: Disassemble R5900 DIV[U]1, M{F,T}{LO,HI}1 and MULT[U]1

Philippe Mathieu-Daudé (2):
  target/mips: Support Toshiba specific three-operand MADD and MADDU
  disas/mips: Increase 'member of ISAs' flag holder size

 disas/mips.c  | 22 -
 target/mips/mips-defs.h   |  2 +-
 target/mips/translate.c   | 77 ++
 target/mips/translate_init.inc.c  |  2 +-
 tests/tcg/mips/mipsr5900/Makefile |  2 +
 tests/tcg/mips/mipsr5900/madd.c   | 78 +++
 tests/tcg/mips/mipsr5900/maddu.c  | 70 +++
 7 files changed, 240 insertions(+), 13 deletions(-)
 create mode 100644 tests/tcg/mips/mipsr5900/madd.c
 create mode 100644 tests/tcg/mips/mipsr5900/maddu.c

-- 
2.18.1




[Qemu-devel] [PATCH 06/11] tests/tcg/mips: Test R5900 three-operand MADD1

2018-10-25 Thread Fredrik Noring
Signed-off-by: Fredrik Noring 
---
 tests/tcg/mips/mipsr5900/madd.c | 43 +
 1 file changed, 38 insertions(+), 5 deletions(-)

diff --git a/tests/tcg/mips/mipsr5900/madd.c b/tests/tcg/mips/mipsr5900/madd.c
index 9ad2ea6dbb..f6f215e1c3 100644
--- a/tests/tcg/mips/mipsr5900/madd.c
+++ b/tests/tcg/mips/mipsr5900/madd.c
@@ -1,5 +1,5 @@
 /*
- * Test R5900-specific three-operand MADD.
+ * Test R5900-specific three-operand MADD and MADD1.
  */
 
 #include 
@@ -29,12 +29,45 @@ int64_t madd(int64_t a, int32_t rs, int32_t rt)
 return r;
 }
 
+int64_t madd1(int64_t a, int32_t rs, int32_t rt)
+{
+int32_t lo = a;
+int32_t hi = a >> 32;
+int32_t rd;
+int64_t r;
+
+__asm__ __volatile__ (
+"mtlo1 %5\n"
+"mthi1 %6\n"
+"madd1 %0, %3, %4\n"
+"mflo1 %1\n"
+"mfhi1 %2\n"
+: "=r" (rd), "=r" (lo), "=r" (hi)
+: "r" (rs), "r" (rt), "r" (lo), "r" (hi));
+r = ((int64_t)hi << 32) | (uint32_t)lo;
+
+assert(a + (int64_t)rs * rt == r);
+assert(rd == lo);
+
+return r;
+}
+
+static int64_t madd_variants(int64_t a, int32_t rs, int32_t rt)
+{
+int64_t rd  = madd(a, rs, rt);
+int64_t rd1 = madd1(a, rs, rt);
+
+assert(rd == rd1);
+
+return rd;
+}
+
 static void verify_madd(int64_t a, int32_t rs, int32_t rt, int64_t expected)
 {
-assert(madd(a, rs, rt) == expected);
-assert(madd(a, -rs, rt) == a + a - expected);
-assert(madd(a, rs, -rt) == a + a - expected);
-assert(madd(a, -rs, -rt) == expected);
+assert(madd_variants(a, rs, rt) == expected);
+assert(madd_variants(a, -rs, rt) == a + a - expected);
+assert(madd_variants(a, rs, -rt) == a + a - expected);
+assert(madd_variants(a, -rs, -rt) == expected);
 }
 
 int main()
-- 
2.18.1




[Qemu-devel] [RFC 12/48] atomic_template: define pre/post macros

2018-10-25 Thread Emilio G. Cota
In preparation for plugin support.

Signed-off-by: Emilio G. Cota 
---
 accel/tcg/atomic_template.h | 92 +++--
 1 file changed, 57 insertions(+), 35 deletions(-)

diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h
index 8d177fefef..b13318c1ce 100644
--- a/accel/tcg/atomic_template.h
+++ b/accel/tcg/atomic_template.h
@@ -59,25 +59,26 @@
 # define ABI_TYPE  uint32_t
 #endif
 
-#define ATOMIC_TRACE_RMW do {   \
-uint8_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, false); \
-\
-trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info);  \
-trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, \
-info | TRACE_MEM_ST);   \
-} while (0)
-
-#define ATOMIC_TRACE_LD do {\
-uint8_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, false); \
-\
-trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info);  \
-} while (0)
-
-# define ATOMIC_TRACE_ST do {   \
-uint8_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, true); \
-\
-trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info);  \
-} while (0)
+/* these don't depend on MEND/SHIFT, so we just define them once */
+#ifndef ATOMIC_TRACE_RMW_PRE
+# define ATOMIC_TRACE_RMW_PRE do {\
+trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info);\
+trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info | TRACE_MEM_ST); \
+} while (0)
+
+# define ATOMIC_TRACE_RMW_POST  \
+
+# define ATOMIC_TRACE_LD_PRE\
+trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info)
+
+# define ATOMIC_TRACE_LD_POST   \
+
+# define ATOMIC_TRACE_ST_PRE\
+trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info)
+
+# define ATOMIC_TRACE_ST_POST   \
+
+#endif /* ATOMIC_TRACE_RMW_PRE */
 
 /* Define host-endian atomic operations.  Note that END is used within
the ATOMIC_NAME macro, and redefined below.  */
@@ -98,14 +99,16 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, 
target_ulong addr,
 ATOMIC_MMU_DECLS;
 DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
 DATA_TYPE ret;
+uint8_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, false);
 
-ATOMIC_TRACE_RMW;
+ATOMIC_TRACE_RMW_PRE;
 #if DATA_SIZE == 16
 ret = atomic16_cmpxchg(haddr, cmpv, newv);
 #else
 ret = atomic_cmpxchg__nocheck(haddr, cmpv, newv);
 #endif
 ATOMIC_MMU_CLEANUP;
+ATOMIC_TRACE_RMW_POST;
 return ret;
 }
 
@@ -115,10 +118,12 @@ ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong 
addr EXTRA_ARGS)
 {
 ATOMIC_MMU_DECLS;
 DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
+uint8_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, false);
 
-ATOMIC_TRACE_LD;
+ATOMIC_TRACE_LD_PRE;
 val = atomic16_read(haddr);
 ATOMIC_MMU_CLEANUP;
+ATOMIC_TRACE_LD_POST;
 return val;
 }
 
@@ -127,10 +132,12 @@ void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr,
 {
 ATOMIC_MMU_DECLS;
 DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
+uint8_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, true);
 
-ATOMIC_TRACE_ST;
+ATOMIC_TRACE_ST_PRE;
 atomic16_set(haddr, val);
 ATOMIC_MMU_CLEANUP;
+ATOMIC_TRACE_ST_POST;
 }
 #endif
 #else
@@ -140,10 +147,12 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, 
target_ulong addr,
 ATOMIC_MMU_DECLS;
 DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
 DATA_TYPE ret;
+uint8_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, false);
 
-ATOMIC_TRACE_RMW;
+ATOMIC_TRACE_RMW_PRE;
 ret = atomic_xchg__nocheck(haddr, val);
 ATOMIC_MMU_CLEANUP;
+ATOMIC_TRACE_RMW_POST;
 return ret;
 }
 
@@ -154,10 +163,12 @@ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong 
addr,   \
 ATOMIC_MMU_DECLS;   \
 DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;   \
 DATA_TYPE ret;  \
+uint8_t info = glue(trace_mem_build_info_no_se, MEND)(SHIFT, false); \
 \
-ATOMIC_TRACE_RMW;   \
+ATOMIC_TRACE_RMW_PRE;   \
 ret = atomic_##X(haddr, val);   \
 ATOMIC_MMU_CLEANUP; 

[Qemu-devel] [RFC 02/48] trace: expand mem_info:size_shift to 3 bits

2018-10-25 Thread Emilio G. Cota
This will allow us to trace 16B-long memory accesses.

While at it, add some defines for the mem_info bits and simplify
trace_mem_get_info by making it a wrapper around trace_mem_build_info.

Signed-off-by: Emilio G. Cota 
---
 trace-events | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/trace-events b/trace-events
index 4fd2cb4b97..9d65d472d2 100644
--- a/trace-events
+++ b/trace-events
@@ -151,7 +151,7 @@ vcpu guest_cpu_reset(void)
 # Access information can be parsed as:
 #
 # struct mem_info {
-# uint8_t size_shift : 2; /* interpreted as "1 << size_shift" bytes */
+# uint8_t size_shift : 3; /* interpreted as "1 << size_shift" bytes */
 # boolsign_extend: 1; /* sign-extended */
 # uint8_t endianness : 1; /* 0: little, 1: big */
 # boolstore  : 1; /* wheter it's a store operation */
-- 
2.17.1




[Qemu-devel] [PATCH 03/11] target/mips: Support Toshiba specific three-operand MADD and MADDU

2018-10-25 Thread Fredrik Noring
From: Philippe Mathieu-Daudé 

The three-operand MADD and MADDU are specific to the
Toshiba TX19/TX39/TX79 cores.

The "32-Bit TX System RISC TX39 Family Architecture manual"
is available at https://wiki.qemu.org/File:DSAE0022432.pdf

Signed-off-by: Philippe Mathieu-Daudé
Signed-off-by: Fredrik Noring 
Tested-by: Fredrik Noring 
---
 target/mips/translate.c | 58 +
 1 file changed, 53 insertions(+), 5 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 18167df26d..add6203c5a 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -4801,8 +4801,8 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
 }
 
 /*
- * These MULT and MULTU instructions implemented in for example the
- * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
+ * These MULT[U] and MADD[U] instructions implemented in for example
+ * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
  * architectures are special three-operand variants with the syntax
  *
  * MULT[U][1] rd, rs, rt
@@ -4811,6 +4811,14 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
  *
  * (rd, LO, HI) <- rs * rt
  *
+ * and
+ *
+ * MADD[U]rd, rs, rt
+ *
+ * such that
+ *
+ * (rd, LO, HI) <- (LO, HI) + rs * rt
+ *
  * where the low-order 32-bits of the result is placed into both the
  * GPR rd and the special register LO. The high-order 32-bits of the
  * result is placed into the special register HI.
@@ -4867,8 +4875,48 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
 tcg_temp_free_i32(t3);
 }
 break;
+case TX79_MMI_MADD:
+{
+TCGv_i64 t2 = tcg_temp_new_i64();
+TCGv_i64 t3 = tcg_temp_new_i64();
+
+tcg_gen_ext_tl_i64(t2, t0);
+tcg_gen_ext_tl_i64(t3, t1);
+tcg_gen_mul_i64(t2, t2, t3);
+tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
+tcg_gen_add_i64(t2, t2, t3);
+tcg_temp_free_i64(t3);
+gen_move_low32(cpu_LO[acc], t2);
+gen_move_high32(cpu_HI[acc], t2);
+if (rd) {
+gen_move_low32(cpu_gpr[rd], t2);
+}
+tcg_temp_free_i64(t2);
+}
+break;
+case TX79_MMI_MADDU:
+{
+TCGv_i64 t2 = tcg_temp_new_i64();
+TCGv_i64 t3 = tcg_temp_new_i64();
+
+tcg_gen_ext32u_tl(t0, t0);
+tcg_gen_ext32u_tl(t1, t1);
+tcg_gen_extu_tl_i64(t2, t0);
+tcg_gen_extu_tl_i64(t3, t1);
+tcg_gen_mul_i64(t2, t2, t3);
+tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
+tcg_gen_add_i64(t2, t2, t3);
+tcg_temp_free_i64(t3);
+gen_move_low32(cpu_LO[acc], t2);
+gen_move_high32(cpu_HI[acc], t2);
+if (rd) {
+gen_move_low32(cpu_gpr[rd], t2);
+}
+tcg_temp_free_i64(t2);
+}
+break;
 default:
-MIPS_INVAL("mul TXx9");
+MIPS_INVAL("mul/madd TXx9");
 generate_exception_end(ctx, EXCP_RI);
 goto out;
 }
@@ -24699,6 +24747,8 @@ static void decode_tx79_mmi(CPUMIPSState *env, 
DisasContext *ctx)
 break;
 case TX79_MMI_MULT1:
 case TX79_MMI_MULTU1:
+case TX79_MMI_MADD:
+case TX79_MMI_MADDU:
 gen_mul_txx9(ctx, opc, rd, rs, rt);
 break;
 case TX79_MMI_DIV1:
@@ -24713,8 +24763,6 @@ static void decode_tx79_mmi(CPUMIPSState *env, 
DisasContext *ctx)
 case TX79_MMI_MFHI1:
 gen_HILO(ctx, opc, 1, rd);
 break;
-case TX79_MMI_MADD:  /* TODO: TX79_MMI_MADD */
-case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */
 case TX79_MMI_PLZCW: /* TODO: TX79_MMI_PLZCW */
 case TX79_MMI_MADD1: /* TODO: TX79_MMI_MADD1 */
 case TX79_MMI_MADDU1:/* TODO: TX79_MMI_MADDU1 */
-- 
2.18.1




[Qemu-devel] [RFC 20/48] *-user: notify plugin of exit

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 bsd-user/syscall.c | 3 +++
 linux-user/exit.c  | 1 +
 2 files changed, 4 insertions(+)

diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index 66492aaf5d..b7818af450 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -332,6 +332,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 _mcleanup();
 #endif
 gdb_exit(cpu_env, arg1);
+qemu_plugin_atexit_cb();
 /* XXX: should free thread stack and CPU env */
 _exit(arg1);
 ret = 0; /* avoid warning */
@@ -430,6 +431,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long 
arg1,
 _mcleanup();
 #endif
 gdb_exit(cpu_env, arg1);
+qemu_plugin_atexit_cb();
 /* XXX: should free thread stack and CPU env */
 _exit(arg1);
 ret = 0; /* avoid warning */
@@ -505,6 +507,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 _mcleanup();
 #endif
 gdb_exit(cpu_env, arg1);
+qemu_plugin_atexit_cb();
 /* XXX: should free thread stack and CPU env */
 _exit(arg1);
 ret = 0; /* avoid warning */
diff --git a/linux-user/exit.c b/linux-user/exit.c
index 14e94e28fa..768856483a 100644
--- a/linux-user/exit.c
+++ b/linux-user/exit.c
@@ -32,4 +32,5 @@ void preexit_cleanup(CPUArchState *env, int code)
 __gcov_dump();
 #endif
 gdb_exit(env, code);
+qemu_plugin_atexit_cb();
 }
-- 
2.17.1




[Qemu-devel] [RFC 09/48] tcg: reset runtime helpers when flushing the code cache

2018-10-25 Thread Emilio G. Cota
In preparation for adding plugin support. One of the clean-up
actions when uninstalling plugins will be to flush the code
cache. We'll also have to clear the runtime helpers, since
some of those runtime helpers may belong to the plugin
being uninstalled.

Signed-off-by: Emilio G. Cota 
---
 tcg/tcg.h |  1 +
 accel/tcg/translate-all.c |  1 +
 tcg/tcg.c | 21 +
 3 files changed, 23 insertions(+)

diff --git a/tcg/tcg.h b/tcg/tcg.h
index 3fa434d891..2c378415d2 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -1079,6 +1079,7 @@ bool tcg_op_supported(TCGOpcode op);
 void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args);
 void tcg_gen_runtime_helper(const TCGHelperInfo *orig, TCGTemp *ret, int nargs,
 TCGTemp **args);
+void tcg_reset_runtime_helpers(void);
 
 TCGOp *tcg_emit_op(TCGOpcode opc);
 void tcg_op_remove(TCGContext *s, TCGOp *op);
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 038d82fdb5..c8b3e0a491 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1255,6 +1255,7 @@ static void do_tb_flush(CPUState *cpu, run_on_cpu_data 
tb_flush_count)
 
 qht_reset_size(_ctx.htable, CODE_GEN_HTABLE_SIZE);
 page_flush_tb();
+tcg_reset_runtime_helpers();
 
 tcg_region_reset_all();
 /* XXX: flush processor icache at this point if cache flush is
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 87e02da740..a6824145b0 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -874,6 +874,7 @@ static const TCGHelperInfo all_helpers[] = {
 #include "exec/helper-tcg.h"
 };
 static struct qht helper_table;
+static struct qht runtime_helper_table;
 static bool helper_table_inited;
 
 static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)];
@@ -913,6 +914,22 @@ static void tcg_helper_insert(const TCGHelperInfo *info)
 g_assert(inserted);
 }
 
+static void
+rm_from_helper_table_and_free(void *p, uint32_t h, void *userp)
+{
+bool success;
+
+success = qht_remove(_table, p, h);
+g_assert(success);
+g_free(p);
+}
+
+void tcg_reset_runtime_helpers(void)
+{
+qht_iter(_helper_table, rm_from_helper_table_and_free, NULL);
+qht_reset(_helper_table);
+}
+
 void tcg_context_init(TCGContext *s)
 {
 int op, total_args, n, i;
@@ -948,6 +965,7 @@ void tcg_context_init(TCGContext *s)
 /* Register helpers.  */
 qht_init(_table, tcg_helper_cmp, ARRAY_SIZE(all_helpers),
  QHT_MODE_AUTO_RESIZE);
+qht_init(_helper_table, tcg_helper_cmp, 1, QHT_MODE_AUTO_RESIZE);
 
 for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
 tcg_helper_insert(_helpers[i]);
@@ -1847,6 +1865,9 @@ void tcg_gen_runtime_helper(const TCGHelperInfo *orig, 
TCGTemp *ret, int nargs,
 if (unlikely(existing)) {
 g_free(info);
 info = existing;
+} else {
+qht_insert(_helper_table, info, hash, );
+g_assert(existing == NULL);
 }
 }
 do_tcg_gen_callN(info, ret, nargs, args);
-- 
2.17.1




[Qemu-devel] [RFC 11/48] atomic_template: fix indentation in GEN_ATOMIC_HELPER

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 accel/tcg/atomic_template.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h
index efde12fdb2..8d177fefef 100644
--- a/accel/tcg/atomic_template.h
+++ b/accel/tcg/atomic_template.h
@@ -284,7 +284,7 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong 
addr,
 
 #define GEN_ATOMIC_HELPER(X)\
 ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr,   \
- ABI_TYPE val EXTRA_ARGS)   \
+ABI_TYPE val EXTRA_ARGS)\
 {   \
 ATOMIC_MMU_DECLS;   \
 DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;   \
-- 
2.17.1




[Qemu-devel] [RFC 43/48] linux-user: support -plugin option

2018-10-25 Thread Emilio G. Cota
From: Lluís Vilanova 

Signed-off-by: Lluís Vilanova 
[ cota: s/instrument/plugin ]
Signed-off-by: Emilio G. Cota 
---
 linux-user/main.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/linux-user/main.c b/linux-user/main.c
index 923cbb753a..0244ad736c 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -28,6 +28,7 @@
 #include "qemu/config-file.h"
 #include "qemu/cutils.h"
 #include "qemu/help_option.h"
+#include "qemu/plugin.h"
 #include "cpu.h"
 #include "exec/exec-all.h"
 #include "tcg.h"
@@ -385,6 +386,15 @@ static void handle_arg_trace(const char *arg)
 trace_file = trace_opt_parse(arg);
 }
 
+static struct qemu_plugin_list plugins = QTAILQ_HEAD_INITIALIZER(plugins);
+
+#ifdef CONFIG_PLUGINS
+static void handle_arg_plugin(const char *arg)
+{
+qemu_plugin_opt_parse(arg, );
+}
+#endif
+
 struct qemu_argument {
 const char *argv;
 const char *env;
@@ -436,6 +446,10 @@ static const struct qemu_argument arg_table[] = {
  "",   "Seed for pseudo-random number generator"},
 {"trace",  "QEMU_TRACE",   true,  handle_arg_trace,
  "",   "[[enable=]][,events=][,file=]"},
+#ifdef CONFIG_PLUGINS
+{"plugin", "QEMU_PLUGIN",  true,  handle_arg_plugin,
+ "",   "[file=][,arg=]"},
+#endif
 {"version","QEMU_VERSION", false, handle_arg_version,
  "",   "display version information and exit"},
 {NULL, NULL, false, NULL, NULL, NULL}
@@ -627,6 +641,7 @@ int main(int argc, char **argv, char **envp)
 srand(time(NULL));
 
 qemu_add_opts(_trace_opts);
+qemu_plugin_add_opts();
 
 optind = parse_args(argc, argv);
 
@@ -634,6 +649,9 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 }
 trace_init_file(trace_file);
+if (qemu_plugin_load_list()) {
+exit(1);
+}
 
 /* Zero out regs */
 memset(regs, 0, sizeof(struct target_pt_regs));
-- 
2.17.1




[Qemu-devel] [RFC 04/48] exec: introduce qemu_xxhash{2,4,5,6,7}

2018-10-25 Thread Emilio G. Cota
Before moving them all to include/qemu/xxhash.h.

Signed-off-by: Emilio G. Cota 
---
 include/exec/tb-hash-xx.h | 41 +--
 include/exec/tb-hash.h|  2 +-
 tests/qht-bench.c |  2 +-
 util/qsp.c| 12 ++--
 4 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/include/exec/tb-hash-xx.h b/include/exec/tb-hash-xx.h
index 747a9a612c..98ce4b628a 100644
--- a/include/exec/tb-hash-xx.h
+++ b/include/exec/tb-hash-xx.h
@@ -42,23 +42,23 @@
 #define PRIME32_4668265263U
 #define PRIME32_5374761393U
 
-#define TB_HASH_XX_SEED 1
+#define QEMU_XXHASH_SEED 1
 
 /*
  * xxhash32, customized for input variables that are not guaranteed to be
  * contiguous in memory.
  */
 static inline uint32_t
-tb_hash_func7(uint64_t a0, uint64_t b0, uint32_t e, uint32_t f, uint32_t g)
+qemu_xxhash7(uint64_t ab, uint64_t cd, uint32_t e, uint32_t f, uint32_t g)
 {
-uint32_t v1 = TB_HASH_XX_SEED + PRIME32_1 + PRIME32_2;
-uint32_t v2 = TB_HASH_XX_SEED + PRIME32_2;
-uint32_t v3 = TB_HASH_XX_SEED + 0;
-uint32_t v4 = TB_HASH_XX_SEED - PRIME32_1;
-uint32_t a = a0 >> 32;
-uint32_t b = a0;
-uint32_t c = b0 >> 32;
-uint32_t d = b0;
+uint32_t v1 = QEMU_XXHASH_SEED + PRIME32_1 + PRIME32_2;
+uint32_t v2 = QEMU_XXHASH_SEED + PRIME32_2;
+uint32_t v3 = QEMU_XXHASH_SEED + 0;
+uint32_t v4 = QEMU_XXHASH_SEED - PRIME32_1;
+uint32_t a = ab >> 32;
+uint32_t b = ab;
+uint32_t c = cd >> 32;
+uint32_t d = cd;
 uint32_t h32;
 
 v1 += a * PRIME32_2;
@@ -98,4 +98,25 @@ tb_hash_func7(uint64_t a0, uint64_t b0, uint32_t e, uint32_t 
f, uint32_t g)
 return h32;
 }
 
+static inline uint32_t qemu_xxhash2(uint64_t ab)
+{
+return qemu_xxhash7(ab, 0, 0, 0, 0);
+}
+
+static inline uint32_t qemu_xxhash4(uint64_t ab, uint64_t cd)
+{
+return qemu_xxhash7(ab, cd, 0, 0, 0);
+}
+
+static inline uint32_t qemu_xxhash5(uint64_t ab, uint64_t cd, uint32_t e)
+{
+return qemu_xxhash7(ab, cd, e, 0, 0);
+}
+
+static inline uint32_t qemu_xxhash6(uint64_t ab, uint64_t cd, uint32_t e,
+uint32_t f)
+{
+return qemu_xxhash7(ab, cd, e, f, 0);
+}
+
 #endif /* EXEC_TB_HASH_XX_H */
diff --git a/include/exec/tb-hash.h b/include/exec/tb-hash.h
index 0526c4f678..731ba4c272 100644
--- a/include/exec/tb-hash.h
+++ b/include/exec/tb-hash.h
@@ -61,7 +61,7 @@ static inline
 uint32_t tb_hash_func(tb_page_addr_t phys_pc, target_ulong pc, uint32_t flags,
   uint32_t cf_mask, uint32_t trace_vcpu_dstate)
 {
-return tb_hash_func7(phys_pc, pc, flags, cf_mask, trace_vcpu_dstate);
+return qemu_xxhash7(phys_pc, pc, flags, cf_mask, trace_vcpu_dstate);
 }
 
 #endif
diff --git a/tests/qht-bench.c b/tests/qht-bench.c
index 2089e2bed1..2ea132fe57 100644
--- a/tests/qht-bench.c
+++ b/tests/qht-bench.c
@@ -104,7 +104,7 @@ static bool is_equal(const void *ap, const void *bp)
 
 static uint32_t h(unsigned long v)
 {
-return tb_hash_func7(v, 0, 0, 0, 0);
+return qemu_xxhash2(v);
 }
 
 static uint32_t hval(unsigned long v)
diff --git a/util/qsp.c b/util/qsp.c
index a848b09c6d..dc29c41fde 100644
--- a/util/qsp.c
+++ b/util/qsp.c
@@ -135,13 +135,13 @@ QemuCondWaitFunc qemu_cond_wait_func = 
qemu_cond_wait_impl;
  * without it we still get a pretty unique hash.
  */
 static inline
-uint32_t do_qsp_callsite_hash(const QSPCallSite *callsite, uint64_t a)
+uint32_t do_qsp_callsite_hash(const QSPCallSite *callsite, uint64_t ab)
 {
-uint64_t b = (uint64_t)(uintptr_t)callsite->obj;
+uint64_t cd = (uint64_t)(uintptr_t)callsite->obj;
 uint32_t e = callsite->line;
 uint32_t f = callsite->type;
 
-return tb_hash_func7(a, b, e, f, 0);
+return qemu_xxhash6(ab, cd, e, f);
 }
 
 static inline
@@ -169,11 +169,11 @@ static uint32_t qsp_entry_no_thread_hash(const QSPEntry 
*entry)
 static uint32_t qsp_entry_no_thread_obj_hash(const QSPEntry *entry)
 {
 const QSPCallSite *callsite = entry->callsite;
-uint64_t a = g_str_hash(callsite->file);
-uint64_t b = callsite->line;
+uint64_t ab = g_str_hash(callsite->file);
+uint64_t cd = callsite->line;
 uint32_t e = callsite->type;
 
-return tb_hash_func7(a, b, e, 0, 0);
+return qemu_xxhash5(ab, cd, e);
 }
 
 static bool qsp_callsite_cmp(const void *ap, const void *bp)
-- 
2.17.1




[Qemu-devel] [RFC 19/48] translate-all: notify plugin code of tb_flush

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 accel/tcg/translate-all.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 3423cf74db..1690e3fd5b 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1233,6 +1233,8 @@ static gboolean tb_host_size_iter(gpointer key, gpointer 
value, gpointer data)
 /* flush all the translation blocks */
 void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count)
 {
+bool did_flush = false;
+
 mmap_lock();
 /* If it is already been done on request of another CPU,
  * just retry.
@@ -1240,6 +1242,7 @@ void do_tb_flush(CPUState *cpu, run_on_cpu_data 
tb_flush_count)
 if (tb_ctx.tb_flush_count != tb_flush_count.host_int) {
 goto done;
 }
+did_flush = true;
 
 if (DEBUG_TB_FLUSH_GATE) {
 size_t nb_tbs = tcg_nb_tbs();
@@ -1265,6 +1268,9 @@ void do_tb_flush(CPUState *cpu, run_on_cpu_data 
tb_flush_count)
 
 done:
 mmap_unlock();
+if (did_flush) {
+qemu_plugin_flush_cb();
+}
 }
 
 void tb_flush(CPUState *cpu)
-- 
2.17.1




[Qemu-devel] [RFC 03/48] tcg/README: fix typo s/afterwise/afterwards/

2018-10-25 Thread Emilio G. Cota
Afterwise is "wise after the fact", as in "hindsight".
Here we meant "afterwards" (as in "subsequently"). Fix it.

Signed-off-by: Emilio G. Cota 
---
 tcg/README | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tcg/README b/tcg/README
index d22ee084b8..3fa8a7059f 100644
--- a/tcg/README
+++ b/tcg/README
@@ -101,7 +101,7 @@ This can be overridden using the following function 
modifiers:
   canonical locations before calling the helper.
 - TCG_CALL_NO_WRITE_GLOBALS means that the helper does not modify any globals.
   They will only be saved to their canonical location before calling helpers,
-  but they won't be reloaded afterwise.
+  but they won't be reloaded afterwards.
 - TCG_CALL_NO_SIDE_EFFECTS means that the call to the function is removed if
   the return value is not used.
 
-- 
2.17.1




[Qemu-devel] [RFC 39/48] plugin: add API symbols to qemu-plugins.symbols

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 qemu-plugins.symbols | 32 
 1 file changed, 32 insertions(+)
 create mode 100644 qemu-plugins.symbols

diff --git a/qemu-plugins.symbols b/qemu-plugins.symbols
new file mode 100644
index 00..76a57e62bb
--- /dev/null
+++ b/qemu-plugins.symbols
@@ -0,0 +1,32 @@
+{
+  qemu_plugin_uninstall;
+  qemu_plugin_register_vcpu_init_cb;
+  qemu_plugin_register_vcpu_exit_cb;
+  qemu_plugin_register_vcpu_idle_cb;
+  qemu_plugin_register_vcpu_resume_cb;
+  qemu_plugin_register_vcpu_insn_exec_cb;
+  qemu_plugin_register_vcpu_mem_cb;
+  qemu_plugin_register_vcpu_mem_haddr_cb;
+  qemu_plugin_register_vcpu_mem_inline;
+  qemu_plugin_ram_addr_from_host;
+  qemu_plugin_register_vcpu_tb_trans_cb;
+  qemu_plugin_register_vcpu_tb_exec_cb;
+  qemu_plugin_register_vcpu_tb_exec_inline;
+  qemu_plugin_register_flush_cb;
+  qemu_plugin_register_vcpu_syscall_cb;
+  qemu_plugin_register_vcpu_syscall_ret_cb;
+  qemu_plugin_register_atexit_cb;
+  qemu_plugin_tb_n_insns;
+  qemu_plugin_tb_get_insn;
+  qemu_plugin_tb_vaddr;
+  qemu_plugin_insn_data;
+  qemu_plugin_insn_size;
+  qemu_plugin_insn_vaddr;
+  qemu_plugin_mem_size_shift;
+  qemu_plugin_mem_is_sign_extended;
+  qemu_plugin_mem_is_big_endian;
+  qemu_plugin_mem_is_store;
+  qemu_plugin_vcpu_for_each;
+  qemu_plugin_n_vcpus;
+  qemu_plugin_n_max_vcpus;
+};
-- 
2.17.1




[Qemu-devel] [RFC 06/48] tcg: use QHT for helper_table

2018-10-25 Thread Emilio G. Cota
This will allow us to add TCG helpers at run-time.

While at it, rename tcg_find_helper to tcg_helper_find for consistency
with the added tcg_helper_foo functions.

Signed-off-by: Emilio G. Cota 
---
 tcg/tcg.c | 59 +--
 1 file changed, 49 insertions(+), 10 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index e85133ef05..65da3c5dbf 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -33,6 +33,7 @@
 #include "qemu/error-report.h"
 #include "qemu/cutils.h"
 #include "qemu/host-utils.h"
+#include "qemu/xxhash.h"
 #include "qemu/timer.h"
 
 /* Note: the long term plan is to reduce the dependencies on the QEMU
@@ -879,13 +880,46 @@ typedef struct TCGHelperInfo {
 static const TCGHelperInfo all_helpers[] = {
 #include "exec/helper-tcg.h"
 };
-static GHashTable *helper_table;
+static struct qht helper_table;
+static bool helper_table_inited;
 
 static int indirect_reg_alloc_order[ARRAY_SIZE(tcg_target_reg_alloc_order)];
 static void process_op_defs(TCGContext *s);
 static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type,
 TCGReg reg, const char *name);
 
+static inline uint32_t tcg_helper_func_hash(const void *func)
+{
+return qemu_xxhash2((uint64_t)func);
+}
+
+static bool tcg_helper_cmp(const void *ap, const void *bp)
+{
+const TCGHelperInfo *a = ap;
+const TCGHelperInfo *b = bp;
+
+return a->func == b->func &&
+a->flags == b->flags &&
+a->sizemask == b->sizemask &&
+!strcmp(a->name, b->name);
+}
+
+static bool tcg_helper_lookup_cmp(const void *obj, const void *func)
+{
+const TCGHelperInfo *info = obj;
+
+return info->func == func;
+}
+
+static void tcg_helper_insert(const TCGHelperInfo *info)
+{
+uint32_t hash = tcg_helper_func_hash(info->func);
+bool inserted;
+
+inserted = qht_insert(_table, (void *)info, hash, NULL);
+g_assert(inserted);
+}
+
 void tcg_context_init(TCGContext *s)
 {
 int op, total_args, n, i;
@@ -919,13 +953,13 @@ void tcg_context_init(TCGContext *s)
 }
 
 /* Register helpers.  */
-/* Use g_direct_hash/equal for direct pointer comparisons on func.  */
-helper_table = g_hash_table_new(NULL, NULL);
+qht_init(_table, tcg_helper_cmp, ARRAY_SIZE(all_helpers),
+ QHT_MODE_AUTO_RESIZE);
 
 for (i = 0; i < ARRAY_SIZE(all_helpers); ++i) {
-g_hash_table_insert(helper_table, (gpointer)all_helpers[i].func,
-(gpointer)_helpers[i]);
+tcg_helper_insert(_helpers[i]);
 }
+helper_table_inited = true;
 
 tcg_target_init(s);
 process_op_defs(s);
@@ -1620,9 +1654,10 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, 
TCGTemp **args)
 int i, real_args, nb_rets, pi;
 unsigned sizemask, flags;
 TCGHelperInfo *info;
+uint32_t hash = tcg_helper_func_hash(func);
 TCGOp *op;
 
-info = g_hash_table_lookup(helper_table, (gpointer)func);
+info = qht_lookup_custom(_table, func, hash, tcg_helper_lookup_cmp);
 flags = info->flags;
 sizemask = info->sizemask;
 
@@ -1825,11 +1860,15 @@ static char *tcg_get_arg_str(TCGContext *s, char *buf,
 }
 
 /* Find helper name.  */
-static inline const char *tcg_find_helper(TCGContext *s, uintptr_t val)
+static inline const char *tcg_helper_find(TCGContext *s, uintptr_t val)
 {
 const char *ret = NULL;
-if (helper_table) {
-TCGHelperInfo *info = g_hash_table_lookup(helper_table, (gpointer)val);
+if (helper_table_inited) {
+uint32_t hash = tcg_helper_func_hash((void *)val);
+TCGHelperInfo *info;
+
+info = qht_lookup_custom(_table, (void *)val, hash,
+ tcg_helper_lookup_cmp);
 if (info) {
 ret = info->name;
 }
@@ -1919,7 +1958,7 @@ void tcg_dump_ops(TCGContext *s)
 
 /* function name, flags, out args */
 col += qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name,
-tcg_find_helper(s, op->args[nb_oargs + nb_iargs]),
+tcg_helper_find(s, op->args[nb_oargs + nb_iargs]),
 op->args[nb_oargs + nb_iargs + 1], nb_oargs);
 for (i = 0; i < nb_oargs; i++) {
 col += qemu_log(",%s", tcg_get_arg_str(s, buf, sizeof(buf),
-- 
2.17.1




[Qemu-devel] [RFC 13/48] xxhash: add qemu_xxhash8

2018-10-25 Thread Emilio G. Cota
It will be used for TB hashing soon.

Signed-off-by: Emilio G. Cota 
---
 include/qemu/xxhash.h | 40 +++-
 1 file changed, 27 insertions(+), 13 deletions(-)

diff --git a/include/qemu/xxhash.h b/include/qemu/xxhash.h
index fe35dde328..450427eeaa 100644
--- a/include/qemu/xxhash.h
+++ b/include/qemu/xxhash.h
@@ -49,7 +49,8 @@
  * contiguous in memory.
  */
 static inline uint32_t
-qemu_xxhash7(uint64_t ab, uint64_t cd, uint32_t e, uint32_t f, uint32_t g)
+qemu_xxhash8(uint64_t ab, uint64_t cd, uint32_t e, uint32_t f, uint32_t g,
+ uint32_t h)
 {
 uint32_t v1 = QEMU_XXHASH_SEED + PRIME32_1 + PRIME32_2;
 uint32_t v2 = QEMU_XXHASH_SEED + PRIME32_2;
@@ -77,17 +78,24 @@ qemu_xxhash7(uint64_t ab, uint64_t cd, uint32_t e, uint32_t 
f, uint32_t g)
 v4 = rol32(v4, 13);
 v4 *= PRIME32_1;
 
-h32 = rol32(v1, 1) + rol32(v2, 7) + rol32(v3, 12) + rol32(v4, 18);
-h32 += 28;
+v1 += e * PRIME32_2;
+v1 = rol32(v1, 13);
+v1 *= PRIME32_1;
 
-h32 += e * PRIME32_3;
-h32  = rol32(h32, 17) * PRIME32_4;
+v2 += f * PRIME32_2;
+v2 = rol32(v2, 13);
+v2 *= PRIME32_1;
+
+v3 += g * PRIME32_2;
+v3 = rol32(v3, 13);
+v3 *= PRIME32_1;
 
-h32 += f * PRIME32_3;
-h32  = rol32(h32, 17) * PRIME32_4;
+v4 += h * PRIME32_2;
+v4 = rol32(v4, 13);
+v4 *= PRIME32_1;
 
-h32 += g * PRIME32_3;
-h32  = rol32(h32, 17) * PRIME32_4;
+h32 = rol32(v1, 1) + rol32(v2, 7) + rol32(v3, 12) + rol32(v4, 18);
+h32 += 32;
 
 h32 ^= h32 >> 15;
 h32 *= PRIME32_2;
@@ -100,23 +108,29 @@ qemu_xxhash7(uint64_t ab, uint64_t cd, uint32_t e, 
uint32_t f, uint32_t g)
 
 static inline uint32_t qemu_xxhash2(uint64_t ab)
 {
-return qemu_xxhash7(ab, 0, 0, 0, 0);
+return qemu_xxhash8(ab, 0, 0, 0, 0, 0);
 }
 
 static inline uint32_t qemu_xxhash4(uint64_t ab, uint64_t cd)
 {
-return qemu_xxhash7(ab, cd, 0, 0, 0);
+return qemu_xxhash8(ab, cd, 0, 0, 0, 0);
 }
 
 static inline uint32_t qemu_xxhash5(uint64_t ab, uint64_t cd, uint32_t e)
 {
-return qemu_xxhash7(ab, cd, e, 0, 0);
+return qemu_xxhash8(ab, cd, e, 0, 0, 0);
 }
 
 static inline uint32_t qemu_xxhash6(uint64_t ab, uint64_t cd, uint32_t e,
 uint32_t f)
 {
-return qemu_xxhash7(ab, cd, e, f, 0);
+return qemu_xxhash8(ab, cd, e, f, 0, 0);
+}
+
+static inline uint32_t qemu_xxhash7(uint64_t ab, uint64_t cd, uint32_t e,
+uint32_t f, uint32_t g)
+{
+return qemu_xxhash8(ab, cd, e, f, g, 0);
 }
 
 #endif /* QEMU_XXHASH_H */
-- 
2.17.1




[Qemu-devel] [RFC 15/48] plugin: add core code

2018-10-25 Thread Emilio G. Cota
The goals are to:
- Have a simple implementation that shares nothing with tracing code.

- Make sure we cannot deadlock, particularly under MTTCG. For this,
  we acquire a lock when called from plugin code, and keep
  RCU lists of callbacks so that we do not have to hold the lock
  when calling the callbacks. This is also for performance, since
  some callbacks (e.g. memory access callbacks) might be called very
  frequently.
  * A consequence of this is that we keep our own list of CPUs, so that
we do not have to worry about locking order wrt cpu_list_lock.
  * Some functions such as vcpu_for_each will call plugin code with the
lock held. Instead of making the lock recursive, just document that
the function called by vcpu_for_each cannot call any other plugin API.

- Support as many plugins as the user wants (e.g. -plugin foo -plugin bar),
  just like other tools (e.g. dynamorio) do.

- Support the installation/uninstallation of a plugin any time (i.e. from
  any callback from the guest, or from QAPI/QMP).

- Avoid malicious plugins from abusing the API. This is done by:
  * Adding a qemu_plugin_id_t that all calls need to use. This is a unique
id per plugin.
  * Hiding CPUState * under cpu_index. Plugin code can keep per-vcpu
data by using said index (say to index an array).
  * Only exporting the relevant qemu_plugin symbols to the plugins by
passing --dynamic-file to the linker (when supported), instead of
exporting all symbols with -rdynamic.

- Performance: registering/unregistering callbacks is slow. But this is
  very infrequent; we want performance when calling (or not) callbacks.
  Using RCU is great for this. The only difficulty is when uninstalling
  a plugin, where some callbacks might still be called after the
  uninstall returns. An alternative would be to use r/w locks, but that
  would complicate code quite a bit for very little gain; I suspect most
  plugins will just run until QEMU exits.

Some design decisions:
- I considered registering callbacks per-vcpu, but really I don't see the
  use case for it (would complicate the API and 99% of plugins won't care, so
  I'd rather make that 1% slower by letting them discard unwanted callbacks).

- Using a per-vcpu mask is key to allow for maximum performance/scalability.
  With RCU callbacks and async work we can ensure no events are missed, and
  we keep maximum scalability (again, we assume callbacks are a lot more
  common than callback registration).

- Last, 'plugin' vs. 'instrumentation' naming: I think instrumentation is a
  subset of the functionality that plugins can provide. IOW, in the future
  not all plugins might be considered instrumentation, even if currently
  my goal is to use them for that purpose.

Signed-off-by: Emilio G. Cota 
---
 Makefile  |   7 +-
 Makefile.target   |   2 +
 include/qemu/plugin.h | 239 ++
 include/qom/cpu.h |   6 +
 plugin.c  | 981 ++
 5 files changed, 1234 insertions(+), 1 deletion(-)
 create mode 100644 include/qemu/plugin.h
 create mode 100644 plugin.c

diff --git a/Makefile b/Makefile
index f2947186a4..e4c0b0877e 100644
--- a/Makefile
+++ b/Makefile
@@ -862,8 +862,10 @@ ifneq (,$(findstring qemu-ga,$(TOOLS)))
 endif
 endif
 
+install-includedir:
+   $(INSTALL_DIR) "$(DESTDIR)$(includedir)"
 
-install: all $(if $(BUILD_DOCS),install-doc) install-datadir 
install-localstatedir
+install: all $(if $(BUILD_DOCS),install-doc) install-datadir 
install-localstatedir install-includedir
 ifneq ($(TOOLS),)
$(call install-prog,$(subst 
qemu-ga,qemu-ga$(EXESUF),$(TOOLS)),$(DESTDIR)$(bindir))
 endif
@@ -885,6 +887,9 @@ ifneq ($(BLOBS),)
 endif
 ifdef CONFIG_GTK
$(MAKE) -C po $@
+endif
+ifeq ($(CONFIG_PLUGINS),y)
+   $(INSTALL_DATA) $(SRC_PATH)/include/qemu/plugin-api.h 
"$(DESTDIR)$(includedir)/qemu-plugin.h"
 endif
$(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)/keymaps"
set -e; for x in $(KEYMAPS); do \
diff --git a/Makefile.target b/Makefile.target
index 4d56298bbf..75637c285c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -107,6 +107,8 @@ obj-y += target/$(TARGET_BASE_ARCH)/
 obj-y += disas.o
 obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
 
+obj-$(CONFIG_PLUGINS) += plugin.o
+
 #
 # Linux user emulator target
 
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
new file mode 100644
index 00..0da0f1b892
--- /dev/null
+++ b/include/qemu/plugin.h
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2017, Emilio G. Cota 
+ *
+ * License: GNU GPL, version 2 or later.
+ *   See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_PLUGIN_H
+#define QEMU_PLUGIN_H
+
+#include "qemu/config-file.h"
+#include "qemu/plugin-api.h"
+#include "qemu/error-report.h"
+#include "qemu/queue.h"
+#include "qemu/option.h"
+
+/*
+ * Option parsing/processing.
+ * Note that we can load an arbitrary number 

[Qemu-devel] [RFC 24/48] translator: add .ctx_base_offset and .ctx_size to TranslatorOps

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 include/exec/translator.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/include/exec/translator.h b/include/exec/translator.h
index a28147b3dd..e20ca9f854 100644
--- a/include/exec/translator.h
+++ b/include/exec/translator.h
@@ -106,6 +106,8 @@ typedef struct DisasContextBase {
  *
  * @disas_log:
  *  Print instruction disassembly to log.
+ * @ctx_base_offset: offset of DisasContextBase within DisasContext.
+ * @ctx_size: size of DisasContext.
  */
 typedef struct TranslatorOps {
 void (*init_disas_context)(DisasContextBase *db, CPUState *cpu);
@@ -117,6 +119,8 @@ typedef struct TranslatorOps {
struct qemu_plugin_insn *plugin_insn);
 void (*tb_stop)(DisasContextBase *db, CPUState *cpu);
 void (*disas_log)(const DisasContextBase *db, CPUState *cpu);
+size_t ctx_base_offset;
+size_t ctx_size;
 } TranslatorOps;
 
 /**
-- 
2.17.1




[Qemu-devel] [RFC 07/48] tcg: export TCGHelperInfo

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 tcg/tcg.h | 7 +++
 tcg/tcg.c | 7 ---
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/tcg/tcg.h b/tcg/tcg.h
index f4efbaa680..9f9643b470 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -480,6 +480,13 @@ typedef TCGv_ptr TCGv_env;
 /* Used to align parameters.  See the comment before tcgv_i32_temp.  */
 #define TCG_CALL_DUMMY_ARG  ((TCGArg)0)
 
+typedef struct TCGHelperInfo {
+void *func;
+const char *name;
+unsigned flags;
+unsigned sizemask;
+} TCGHelperInfo;
+
 /* Conditions.  Note that these are laid out for easy manipulation by
the functions below:
  bit 0 is used for inverting;
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 65da3c5dbf..08b6926894 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -868,13 +868,6 @@ void tcg_pool_reset(TCGContext *s)
 s->pool_current = NULL;
 }
 
-typedef struct TCGHelperInfo {
-void *func;
-const char *name;
-unsigned flags;
-unsigned sizemask;
-} TCGHelperInfo;
-
 #include "exec/helper-proto.h"
 
 static const TCGHelperInfo all_helpers[] = {
-- 
2.17.1




[Qemu-devel] [RFC 25/48] target/arm: prepare for 2-pass translation

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 target/arm/translate-a64.c |  8 ++--
 target/arm/translate.c | 25 +
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 8b1e20dd59..dab5f6efd3 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -13783,11 +13783,13 @@ static void disas_data_proc_simd_fp(DisasContext *s, 
uint32_t insn)
 }
 
 /* C3.1 A64 instruction index by encoding */
-static void disas_a64_insn(CPUARMState *env, DisasContext *s)
+static void disas_a64_insn(CPUARMState *env, DisasContext *s,
+   struct qemu_plugin_insn *plugin_insn)
 {
 uint32_t insn;
 
 insn = arm_ldl_code(env, s->pc, s->sctlr_b);
+qemu_plugin_insn_append(plugin_insn, , sizeof(insn));
 s->insn = insn;
 s->pc += 4;
 
@@ -13959,7 +13961,7 @@ static void aarch64_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu,
   default_exception_el(dc));
 dc->base.is_jmp = DISAS_NORETURN;
 } else {
-disas_a64_insn(env, dc);
+disas_a64_insn(env, dc, plugin_insn);
 }
 
 dc->base.pc_next = dc->pc;
@@ -14058,4 +14060,6 @@ const TranslatorOps aarch64_translator_ops = {
 .translate_insn = aarch64_tr_translate_insn,
 .tb_stop= aarch64_tr_tb_stop,
 .disas_log  = aarch64_tr_disas_log,
+.ctx_base_offset= offsetof(DisasContext, base),
+.ctx_size   = sizeof(DisasContext),
 };
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 2fd32a2684..015153a260 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -10198,7 +10198,8 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, 
uint32_t shifter_out,
 }
 
 /* Translate a 32-bit thumb instruction. */
-static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
+static void disas_thumb2_insn(DisasContext *s, uint32_t insn,
+  struct qemu_plugin_insn *plugin_insn)
 {
 uint32_t imm, shift, offset;
 uint32_t rd, rn, rm, rs;
@@ -11736,7 +11737,8 @@ illegal_op:
default_exception_el(s));
 }
 
-static void disas_thumb_insn(DisasContext *s, uint32_t insn)
+static void disas_thumb_insn(DisasContext *s, uint32_t insn,
+ struct qemu_plugin_insn *plugin_insn)
 {
 uint32_t val, op, rm, rn, rd, shift, cond;
 int32_t offset;
@@ -12800,6 +12802,7 @@ static void arm_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu,
 
 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
 dc->insn = insn;
+qemu_plugin_insn_append(plugin_insn, , sizeof(insn));
 dc->pc += 4;
 disas_arm_insn(dc, insn);
 
@@ -12870,11 +12873,21 @@ static void thumb_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu,
 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
 is_16bit = thumb_insn_is_16bit(dc, insn);
 dc->pc += 2;
+if (plugin_insn) {
+uint16_t insn16 = insn;
+
+qemu_plugin_insn_append(plugin_insn, , sizeof(insn16));
+}
 if (!is_16bit) {
 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
 
 insn = insn << 16 | insn2;
 dc->pc += 2;
+if (plugin_insn) {
+uint16_t insn16 = insn2;
+
+qemu_plugin_insn_append(plugin_insn, , sizeof(insn16));
+}
 }
 dc->insn = insn;
 
@@ -12887,9 +12900,9 @@ static void thumb_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu,
 }
 
 if (is_16bit) {
-disas_thumb_insn(dc, insn);
+disas_thumb_insn(dc, insn, plugin_insn);
 } else {
-disas_thumb2_insn(dc, insn);
+disas_thumb2_insn(dc, insn, plugin_insn);
 }
 
 /* Advance the Thumb condexec condition.  */
@@ -13064,6 +13077,8 @@ static const TranslatorOps arm_translator_ops = {
 .translate_insn = arm_tr_translate_insn,
 .tb_stop= arm_tr_tb_stop,
 .disas_log  = arm_tr_disas_log,
+.ctx_base_offset= offsetof(DisasContext, base),
+.ctx_size   = sizeof(DisasContext),
 };
 
 static const TranslatorOps thumb_translator_ops = {
@@ -13074,6 +13089,8 @@ static const TranslatorOps thumb_translator_ops = {
 .translate_insn = thumb_tr_translate_insn,
 .tb_stop= arm_tr_tb_stop,
 .disas_log  = arm_tr_disas_log,
+.ctx_base_offset= offsetof(DisasContext, base),
+.ctx_size   = sizeof(DisasContext),
 };
 
 /* generate intermediate code for basic block 'tb'.  */
-- 
2.17.1




[Qemu-devel] [RFC 01/48] cpu: introduce run_on_cpu_no_bql

2018-10-25 Thread Emilio G. Cota
This allows us to queue synchronous CPU work without the BQL.

Will gain a user soon.

Signed-off-by: Emilio G. Cota 
---
 include/qom/cpu.h | 13 +
 cpus-common.c | 28 ++--
 2 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 204bc94056..863aa2bff1 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -877,6 +877,19 @@ bool cpu_is_stopped(CPUState *cpu);
  */
 void run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data);
 
+/**
+ * run_on_cpu_no_bql
+ * @cpu: The vCPU to run on.
+ * @func: The function to be executed.
+ * @data: Data to pass to the function.
+ *
+ * Schedules the function @func for execution on the vCPU @cpu.
+ * This function is run outside the BQL.
+ * See also: run_on_cpu()
+ */
+void run_on_cpu_no_bql(CPUState *cpu, run_on_cpu_func func,
+   run_on_cpu_data data);
+
 /**
  * async_run_on_cpu:
  * @cpu: The vCPU to run on.
diff --git a/cpus-common.c b/cpus-common.c
index cffb2b71ac..b478fc8741 100644
--- a/cpus-common.c
+++ b/cpus-common.c
@@ -144,7 +144,8 @@ static void queue_work_on_cpu(CPUState *cpu, struct 
qemu_work_item *wi)
 cpu_mutex_unlock(cpu);
 }
 
-void run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data)
+static void do_run_on_cpu(CPUState *cpu, run_on_cpu_func func,
+  run_on_cpu_data data, bool bql)
 {
 struct qemu_work_item wi;
 bool has_bql = qemu_mutex_iothread_locked();
@@ -152,12 +153,16 @@ void run_on_cpu(CPUState *cpu, run_on_cpu_func func, 
run_on_cpu_data data)
 g_assert(no_cpu_mutex_locked());
 
 if (qemu_cpu_is_self(cpu)) {
-if (has_bql) {
-func(cpu, data);
+if (bql) {
+if (has_bql) {
+func(cpu, data);
+} else {
+qemu_mutex_lock_iothread();
+func(cpu, data);
+qemu_mutex_unlock_iothread();
+}
 } else {
-qemu_mutex_lock_iothread();
 func(cpu, data);
-qemu_mutex_unlock_iothread();
 }
 return;
 }
@@ -172,7 +177,7 @@ void run_on_cpu(CPUState *cpu, run_on_cpu_func func, 
run_on_cpu_data data)
 wi.done = false;
 wi.free = false;
 wi.exclusive = false;
-wi.bql = true;
+wi.bql = bql;
 
 cpu_mutex_lock(cpu);
 queue_work_on_cpu_locked(cpu, );
@@ -189,6 +194,17 @@ void run_on_cpu(CPUState *cpu, run_on_cpu_func func, 
run_on_cpu_data data)
 }
 }
 
+void run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data)
+{
+do_run_on_cpu(cpu, func, data, true);
+}
+
+void
+run_on_cpu_no_bql(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data)
+{
+do_run_on_cpu(cpu, func, data, false);
+}
+
 void async_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data 
data)
 {
 struct qemu_work_item *wi;
-- 
2.17.1




[Qemu-devel] [RFC 46/48] plugin: add plugin-chan PCI device

2018-10-25 Thread Emilio G. Cota
This will allow communication between guest and plugins.

Signed-off-by: Emilio G. Cota 
---
 Makefile.target |   2 +
 include/hw/pci/pci.h|   2 +
 include/qemu/plugin.h   |   1 +
 hw/plugin/plugin-chan.c | 136 
 plugin.c|   4 ++
 5 files changed, 145 insertions(+)
 create mode 100644 hw/plugin/plugin-chan.c

diff --git a/Makefile.target b/Makefile.target
index 75637c285c..719699696d 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -156,6 +156,8 @@ else
 obj-y += hw/$(TARGET_BASE_ARCH)/
 endif
 
+obj-$(CONFIG_PLUGINS) += hw/plugin/plugin-chan.o
+
 GENERATED_FILES += hmp-commands.h hmp-commands-info.h
 
 endif # CONFIG_SOFTMMU
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index e6514bba23..6878d02254 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -86,6 +86,8 @@ extern bool pci_available;
 #define PCI_DEVICE_ID_VIRTIO_9P  0x1009
 #define PCI_DEVICE_ID_VIRTIO_VSOCK   0x1012
 
+#define PCI_DEVICE_ID_QEMU_PLUGIN_CHAN   0x10f0
+
 #define PCI_VENDOR_ID_REDHAT 0x1b36
 #define PCI_DEVICE_ID_REDHAT_BRIDGE  0x0001
 #define PCI_DEVICE_ID_REDHAT_SERIAL  0x0002
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index c19071bdbe..f3c18d1032 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -196,6 +196,7 @@ void qemu_plugin_atexit_cb(void);
 void qemu_plugin_add_dyn_cb_arr(struct qemu_plugin_dyn_cb_arr *arr);
 int64_t plugin_get_clock(void);
 void plugin_lockstep_cb(void);
+void plugin_chan_xmit(uint32_t cmd, const void *data, size_t size);
 
 #else /* !CONFIG_PLUGINS */
 
diff --git a/hw/plugin/plugin-chan.c b/hw/plugin/plugin-chan.c
new file mode 100644
index 00..c0749ce089
--- /dev/null
+++ b/hw/plugin/plugin-chan.c
@@ -0,0 +1,136 @@
+#include "qemu/osdep.h"
+#include "hw/pci/pci.h"
+#include "qemu/plugin.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+
+#define PLUGIN_CHAN_CFG_BAR0
+#define PLUGIN_CHAN_CMD_BAR1
+#define PLUGIN_CHAN_DATA_BAR   2
+
+struct plugin_chan_cfg {
+uint32_t data_max_len;
+};
+
+struct plugin_chan {
+PCIDevice dev;
+MemoryRegion cfg_region;
+MemoryRegion cmd_region;
+MemoryRegion data_region;
+void *data;
+size_t data_size;
+struct plugin_chan_cfg cfg;
+};
+
+static uint64_t chan_cfg_read(void *obj, hwaddr addr, unsigned size)
+{
+struct plugin_chan *s = obj;
+
+g_assert(size == 4);
+switch (addr) {
+case 0:
+return s->cfg.data_max_len;
+break;
+}
+g_assert_not_reached();
+return 0;
+}
+
+static void chan_cmd_write(void *obj, hwaddr addr, uint64_t val, unsigned size)
+{
+struct plugin_chan *s = obj;
+
+g_assert(size == 4);
+switch (addr) {
+case 0:
+plugin_chan_xmit(val, s->data_size ? s->data : NULL, s->data_size);
+break;
+case 4:
+s->data_size = val;
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static const MemoryRegionOps chan_cfg_ops = {
+.read = chan_cfg_read,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.impl = {
+.min_access_size = 4,
+.max_access_size = 4,
+},
+};
+
+static const MemoryRegionOps chan_cmd_ops = {
+.write = chan_cmd_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.impl = {
+.min_access_size = 4,
+.max_access_size = 4,
+},
+};
+
+static void plugin_chan_realize(PCIDevice *pci_dev, Error **errp)
+{
+struct plugin_chan *s = DO_UPCAST(struct plugin_chan, dev, pci_dev);
+Error *err = NULL;
+
+s->cfg.data_max_len = 4096;
+
+pci_set_word(s->dev.config + PCI_COMMAND,
+ PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+
+/* data */
+memory_region_init_ram(>data_region, OBJECT(s), "plugin_chan.data",
+   pow2ceil(s->cfg.data_max_len), );
+if (err) {
+error_propagate(errp, err);
+return;
+}
+pci_register_bar(>dev, PLUGIN_CHAN_DATA_BAR,
+ PCI_BASE_ADDRESS_SPACE_MEMORY, >data_region);
+s->data = qemu_map_ram_ptr(s->data_region.ram_block, 0);
+
+/* config */
+memory_region_init_io(>cfg_region, OBJECT(s), _cfg_ops, s,
+  "plugin_chan.cfg", sizeof(struct plugin_chan_cfg));
+pci_register_bar(>dev, PLUGIN_CHAN_CFG_BAR,
+ PCI_BASE_ADDRESS_SPACE_MEMORY, >cfg_region);
+
+/* cmd */
+memory_region_init_io(>cmd_region, OBJECT(s), _cmd_ops, s,
+  "plugin_chan.cmd", 8);
+pci_register_bar(>dev, PLUGIN_CHAN_CMD_BAR,
+ PCI_BASE_ADDRESS_SPACE_MEMORY, >cmd_region);
+}
+
+static void plugin_chan_class_init(ObjectClass *class, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(class);
+PCIDeviceClass *p = PCI_DEVICE_CLASS(class);
+
+p->realize = plugin_chan_realize;
+p->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+p->device_id = PCI_DEVICE_ID_QEMU_PLUGIN_CHAN;
+p->class_id = 

[Qemu-devel] [RFC 10/48] exec: export do_tb_flush

2018-10-25 Thread Emilio G. Cota
This will be used by plugin code to flush the code cache as well
as doing other bookkeeping in a safe work environment.

Signed-off-by: Emilio G. Cota 
---
 include/exec/exec-all.h   | 1 +
 accel/tcg/translate-all.c | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 815e5b1e83..232e2f8966 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -427,6 +427,7 @@ void tb_invalidate_phys_range(target_ulong start, 
target_ulong end);
 void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs);
 #endif
 void tb_flush(CPUState *cpu);
+void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count);
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
 TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
target_ulong cs_base, uint32_t flags,
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index c8b3e0a491..db2d28f8d3 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1230,7 +1230,7 @@ static gboolean tb_host_size_iter(gpointer key, gpointer 
value, gpointer data)
 }
 
 /* flush all the translation blocks */
-static void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count)
+void do_tb_flush(CPUState *cpu, run_on_cpu_data tb_flush_count)
 {
 mmap_lock();
 /* If it is already been done on request of another CPU,
-- 
2.17.1




[Qemu-devel] [RFC 16/48] tcg: add plugin_mask to TB hash

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 include/exec/exec-all.h   | 2 ++
 include/exec/tb-hash.h| 6 --
 include/exec/tb-lookup.h  | 1 +
 accel/tcg/cpu-exec.c  | 6 +-
 accel/tcg/translate-all.c | 6 --
 5 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 232e2f8966..a1f60404b6 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -358,6 +358,8 @@ struct TranslationBlock {
 /* Per-vCPU dynamic tracing state used to generate this TB */
 uint32_t trace_vcpu_dstate;
 
+uint32_t plugin_mask;
+
 struct tb_tc tc;
 
 /* original tb when cflags has CF_NOCACHE */
diff --git a/include/exec/tb-hash.h b/include/exec/tb-hash.h
index 4f3a37d927..37292474b7 100644
--- a/include/exec/tb-hash.h
+++ b/include/exec/tb-hash.h
@@ -59,9 +59,11 @@ static inline unsigned int 
tb_jmp_cache_hash_func(target_ulong pc)
 
 static inline
 uint32_t tb_hash_func(tb_page_addr_t phys_pc, target_ulong pc, uint32_t flags,
-  uint32_t cf_mask, uint32_t trace_vcpu_dstate)
+  uint32_t cf_mask, uint32_t trace_vcpu_dstate,
+  uint32_t plugin_mask)
 {
-return qemu_xxhash7(phys_pc, pc, flags, cf_mask, trace_vcpu_dstate);
+return qemu_xxhash8(phys_pc, pc, flags, cf_mask, trace_vcpu_dstate,
+plugin_mask);
 }
 
 #endif
diff --git a/include/exec/tb-lookup.h b/include/exec/tb-lookup.h
index 492cb68289..dd1572f481 100644
--- a/include/exec/tb-lookup.h
+++ b/include/exec/tb-lookup.h
@@ -33,6 +33,7 @@ tb_lookup__cpu_state(CPUState *cpu, target_ulong *pc, 
target_ulong *cs_base,
tb->cs_base == *cs_base &&
tb->flags == *flags &&
tb->trace_vcpu_dstate == *cpu->trace_dstate &&
+   tb->plugin_mask == *cpu->plugin_mask &&
(tb_cflags(tb) & (CF_HASH_MASK | CF_INVALID)) == cf_mask)) {
 return tb;
 }
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index d590f1f6c0..27aa3451da 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -287,6 +287,7 @@ struct tb_desc {
 uint32_t flags;
 uint32_t cf_mask;
 uint32_t trace_vcpu_dstate;
+uint32_t plugin_mask;
 };
 
 static bool tb_lookup_cmp(const void *p, const void *d)
@@ -299,6 +300,7 @@ static bool tb_lookup_cmp(const void *p, const void *d)
 tb->cs_base == desc->cs_base &&
 tb->flags == desc->flags &&
 tb->trace_vcpu_dstate == desc->trace_vcpu_dstate &&
+tb->plugin_mask == desc->plugin_mask &&
 (tb_cflags(tb) & (CF_HASH_MASK | CF_INVALID)) == desc->cf_mask) {
 /* check next page if needed */
 if (tb->page_addr[1] == -1) {
@@ -330,13 +332,15 @@ TranslationBlock *tb_htable_lookup(CPUState *cpu, 
target_ulong pc,
 desc.flags = flags;
 desc.cf_mask = cf_mask;
 desc.trace_vcpu_dstate = *cpu->trace_dstate;
+desc.plugin_mask = *cpu->plugin_mask;
 desc.pc = pc;
 phys_pc = get_page_addr_code(desc.env, pc);
 if (phys_pc == -1) {
 return NULL;
 }
 desc.phys_page1 = phys_pc & TARGET_PAGE_MASK;
-h = tb_hash_func(phys_pc, pc, flags, cf_mask, *cpu->trace_dstate);
+h = tb_hash_func(phys_pc, pc, flags, cf_mask, *cpu->trace_dstate,
+ *cpu->plugin_mask);
 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 db2d28f8d3..3423cf74db 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1129,6 +1129,7 @@ static bool tb_cmp(const void *ap, const void *bp)
 a->flags == b->flags &&
 (tb_cflags(a) & CF_HASH_MASK) == (tb_cflags(b) & CF_HASH_MASK) &&
 a->trace_vcpu_dstate == b->trace_vcpu_dstate &&
+a->plugin_mask == b->plugin_mask &&
 a->page_addr[0] == b->page_addr[0] &&
 a->page_addr[1] == b->page_addr[1];
 }
@@ -1444,7 +1445,7 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, 
bool rm_from_page_list)
 /* remove the TB from the hash list */
 phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
 h = tb_hash_func(phys_pc, tb->pc, tb->flags, tb_cflags(tb) & CF_HASH_MASK,
- tb->trace_vcpu_dstate);
+ tb->trace_vcpu_dstate, tb->plugin_mask);
 if (!(tb->cflags & CF_NOCACHE) &&
 !qht_remove(_ctx.htable, tb, h)) {
 return;
@@ -1640,7 +1641,7 @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
 
 /* add in the hash table */
 h = tb_hash_func(phys_pc, tb->pc, tb->flags, tb->cflags & CF_HASH_MASK,
- tb->trace_vcpu_dstate);
+ tb->trace_vcpu_dstate, tb->plugin_mask);
 qht_insert(_ctx.htable, tb, h, _tb);
 
 /* remove TB from the page(s) if we couldn't insert it */
@@ -1712,6 +1713,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
 tb->cflags = cflags;
 tb->trace_vcpu_dstate 

[Qemu-devel] [RFC 21/48] *-user: plugin syscalls

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 bsd-user/syscall.c   | 9 +
 linux-user/syscall.c | 3 +++
 2 files changed, 12 insertions(+)

diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index b7818af450..4993f81b2b 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -323,6 +323,8 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 gemu_log("freebsd syscall %d\n", num);
 #endif
 trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 
arg7, arg8);
+qemu_plugin_vcpu_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 
arg7,
+ arg8);
 if(do_strace)
 print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
 
@@ -404,6 +406,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 if (do_strace)
 print_freebsd_syscall_ret(num, ret);
 trace_guest_user_syscall_ret(cpu, num, ret);
+qemu_plugin_vcpu_syscall_ret(cpu, num, ret);
 return ret;
  efault:
 ret = -TARGET_EFAULT;
@@ -422,6 +425,8 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long 
arg1,
 gemu_log("netbsd syscall %d\n", num);
 #endif
 trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0, 
0);
+qemu_plugin_vcpu_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0,
+ 0);
 if(do_strace)
 print_netbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
 
@@ -480,6 +485,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long 
arg1,
 if (do_strace)
 print_netbsd_syscall_ret(num, ret);
 trace_guest_user_syscall_ret(cpu, num, ret);
+qemu_plugin_vcpu_syscall_ret(cpu, num, ret);
 return ret;
  efault:
 ret = -TARGET_EFAULT;
@@ -498,6 +504,8 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 gemu_log("openbsd syscall %d\n", num);
 #endif
 trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0, 
0);
+qemu_plugin_vcpu_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0,
+ 0);
 if(do_strace)
 print_openbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
 
@@ -556,6 +564,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 if (do_strace)
 print_openbsd_syscall_ret(num, ret);
 trace_guest_user_syscall_ret(cpu, num, ret);
+qemu_plugin_vcpu_syscall_ret(cpu, num, ret);
 return ret;
  efault:
 ret = -TARGET_EFAULT;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ae3c0dfef7..a6d17a9f37 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -11232,6 +11232,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 
 trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4,
  arg5, arg6, arg7, arg8);
+qemu_plugin_vcpu_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 
arg7,
+ arg8);
 
 if (unlikely(do_strace)) {
 print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
@@ -11244,5 +11246,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
 }
 
 trace_guest_user_syscall_ret(cpu, num, ret);
+qemu_plugin_vcpu_syscall_ret(cpu, num, ret);
 return ret;
 }
-- 
2.17.1




[Qemu-devel] [RFC 47/48] plugin: support guest hooks

2018-10-25 Thread Emilio G. Cota
These "hooks" are callbacks from the guest to plugins. This is
useful when we need guest-host communication, for instance to
signal the beginning/end of a certain "region of interest" in
the guest program. Simulators typically would use "magic"
instructions for this, but that is painful to maintain across
ISAs. Instead, we use plugin-chan PCI device through which we can
relay guest messages to the host.

Signed-off-by: Emilio G. Cota 
---
 include/qemu/plugin-api.h |  6 ++
 include/qemu/plugin.h |  2 ++
 plugin.c  | 13 +
 qemu-plugins.symbols  |  1 +
 4 files changed, 22 insertions(+)

diff --git a/include/qemu/plugin-api.h b/include/qemu/plugin-api.h
index 5062e20e08..a5faff6a2a 100644
--- a/include/qemu/plugin-api.h
+++ b/include/qemu/plugin-api.h
@@ -234,6 +234,12 @@ void qemu_plugin_register_lockstep_cb(qemu_plugin_id_t id,
 
 void qemu_plugin_end_time_slice(void);
 
+typedef void (*qemu_plugin_hook_cb_t)(uint32_t cmd, const void *data,
+  size_t size);
+
+void qemu_plugin_register_hook_cb(qemu_plugin_id_t id,
+  qemu_plugin_hook_cb_t cb);
+
 /* returns -1 in user-mode */
 int qemu_plugin_n_vcpus(void);
 
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index f3c18d1032..ced265a127 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -61,12 +61,14 @@ enum qemu_plugin_event {
 QEMU_PLUGIN_EV_LOCKSTEP,
 QEMU_PLUGIN_EV_FLUSH,
 QEMU_PLUGIN_EV_ATEXIT,
+QEMU_PLUGIN_EV_HOOK,
 QEMU_PLUGIN_EV_MAX,
 };
 
 union qemu_plugin_cb_sig {
 qemu_plugin_simple_cb_t  simple;
 qemu_plugin_udata_cb_t   udata;
+qemu_plugin_hook_cb_thook;
 qemu_plugin_vcpu_simple_cb_t vcpu_simple;
 qemu_plugin_vcpu_udata_cb_t  vcpu_udata;
 qemu_plugin_vcpu_tb_trans_cb_t   vcpu_tb_trans;
diff --git a/plugin.c b/plugin.c
index 2bbc14e2f3..4004451bdb 100644
--- a/plugin.c
+++ b/plugin.c
@@ -1078,8 +1078,21 @@ void plugin_lockstep_cb(void)
 plugin_cb__simple(QEMU_PLUGIN_EV_LOCKSTEP);
 }
 
+void qemu_plugin_register_hook_cb(qemu_plugin_id_t id, qemu_plugin_hook_cb_t 
cb)
+{
+plugin_register_cb(id, QEMU_PLUGIN_EV_HOOK, cb);
+}
+
 void plugin_chan_xmit(uint32_t cmd, const void *data, size_t size)
 {
+struct qemu_plugin_cb *cb, *next;
+enum qemu_plugin_event ev = QEMU_PLUGIN_EV_HOOK;
+
+QLIST_FOREACH_SAFE_RCU(cb, _lists[ev], entry, next) {
+qemu_plugin_hook_cb_t func = cb->f.hook;
+
+func(cmd, data, size);
+}
 }
 
 static void __attribute__((__constructor__)) plugin_init(void)
diff --git a/qemu-plugins.symbols b/qemu-plugins.symbols
index a3268a40c7..2e17693da8 100644
--- a/qemu-plugins.symbols
+++ b/qemu-plugins.symbols
@@ -31,6 +31,7 @@
   qemu_plugin_mem_is_big_endian;
   qemu_plugin_mem_is_store;
   qemu_plugin_vcpu_for_each;
+  qemu_plugin_register_hook_cb;
   qemu_plugin_n_vcpus;
   qemu_plugin_n_max_vcpus;
 };
-- 
2.17.1




[Qemu-devel] [RFC 33/48] target/riscv: prepare for 2-pass translation

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 target/riscv/translate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a33cf6802b..6f5be8e7d7 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1851,6 +1851,7 @@ static void riscv_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu,
 
 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
 decode_opc(env, ctx);
+qemu_plugin_insn_append(plugin_insn, >opcode, sizeof(ctx->opcode));
 ctx->base.pc_next = ctx->pc_succ_insn;
 
 if (ctx->base.is_jmp == DISAS_NEXT) {
@@ -1892,6 +1893,8 @@ static const TranslatorOps riscv_tr_ops = {
 .translate_insn = riscv_tr_translate_insn,
 .tb_stop= riscv_tr_tb_stop,
 .disas_log  = riscv_tr_disas_log,
+.ctx_base_offset= offsetof(DisasContext, base),
+.ctx_size   = sizeof(DisasContext),
 };
 
 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
-- 
2.17.1




[Qemu-devel] [RFC 38/48] translator: implement 2-pass translation

2018-10-25 Thread Emilio G. Cota
The second pass only occurs when a plugin has subscribed to
TB translation events.

Signed-off-by: Emilio G. Cota 
---
 tcg/tcg.h  |  8 
 accel/tcg/translator.c | 91 +-
 2 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/tcg/tcg.h b/tcg/tcg.h
index d5afe25c97..479b57d65f 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -720,6 +720,14 @@ struct TCGContext {
 
 TCGLabel *exitreq_label;
 
+/*
+ * We keep one plugin_tb struct per TCGContext. Note that on every TB
+ * translation we clear but do not free its contents; this way we
+ * avoid a lot of malloc/free churn, since after a few TB's it's
+ * unlikely that we'll need to allocate either more instructions or more
+ * space for instructions (for variable-instruction-length ISAs).
+ */
+struct qemu_plugin_tb plugin_tb;
 struct qemu_plugin_dyn_cb_arr *plugin_mem_cb;
 struct qemu_plugin_insn *plugin_insn;
 
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
index 8591e4b72a..88f9ac62a3 100644
--- a/accel/tcg/translator.c
+++ b/accel/tcg/translator.c
@@ -17,6 +17,7 @@
 #include "exec/gen-icount.h"
 #include "exec/log.h"
 #include "exec/translator.h"
+#include "exec/plugin-gen.h"
 
 /* Pairs with tcg_clear_temp_count.
To be called by #TranslatorOps.{translate_insn,tb_stop} if
@@ -35,6 +36,21 @@ void translator_loop(const TranslatorOps *ops, 
DisasContextBase *db,
  CPUState *cpu, TranslationBlock *tb)
 {
 int bp_insn = 0;
+int insn_idx = 0;
+bool tb_trans_cb = false;
+bool first_pass = true; /* second pass otherwise */
+void *saved_dc = g_alloca(ops->ctx_size);
+/* tb->plugin_mask is a u32 */
+unsigned long plugin_mask = tb->plugin_mask;
+struct qemu_plugin_tb *plugin_tb = _ctx->plugin_tb;
+
+if (test_bit(QEMU_PLUGIN_EV_VCPU_TB_TRANS, _mask)) {
+tb_trans_cb = true;
+plugin_tb->cbs.n = 0;
+plugin_tb->n = 0;
+plugin_tb->vaddr = tb->pc;
+tcg_ctx->plugin_mem_cb = NULL;
+}
 
 /* Initialize DisasContext */
 db->tb = tb;
@@ -56,6 +72,21 @@ void translator_loop(const TranslatorOps *ops, 
DisasContextBase *db,
 db->max_insns = 1;
 }
 
+ translate:
+tcg_func_start(tcg_ctx);
+
+/* See the "2-pass translation" comment below */
+if (tb_trans_cb) {
+void *dc = db;
+
+dc -= ops->ctx_base_offset;
+if (first_pass) {
+memcpy(saved_dc, dc, ops->ctx_size);
+} else {
+memcpy(dc, saved_dc, ops->ctx_size);
+}
+}
+
 ops->init_disas_context(db, cpu);
 tcg_debug_assert(db->is_jmp == DISAS_NEXT);  /* no early exit */
 
@@ -67,7 +98,53 @@ void translator_loop(const TranslatorOps *ops, 
DisasContextBase *db,
 ops->tb_start(db, cpu);
 tcg_debug_assert(db->is_jmp == DISAS_NEXT);  /* no early exit */
 
+if (!first_pass && plugin_tb->cbs.n) {
+qemu_plugin_gen_vcpu_udata_callbacks(_tb->cbs);
+}
+
 while (true) {
+struct qemu_plugin_insn *plugin_insn = NULL;
+bool mem_helpers = false;
+
+/*
+ * 2-pass translation.
+ *
+ * In the first pass we fully determine the TB.
+ * If no plugins have subscribed to TB translation events, we're done.
+ *
+ * If they have, we first share with plugins a TB descriptor so
+ * that plugins can subscribe to instruction-related events, e.g.
+ * memory accesses of particular instructions, or TB execution.
+ * With this info, which is kept in plugin_tb, we then do a second 
pass,
+ * inserting the appropriate instrumentation into the translated TB.
+ *
+ * Since all translation state is kept in DisasContext, we copy it
+ * before the first pass, and restore it before the second.
+ */
+if (tb_trans_cb) {
+if (first_pass) {
+plugin_insn = qemu_plugin_tb_insn_get(plugin_tb);
+tcg_ctx->plugin_insn = plugin_insn;
+plugin_insn->vaddr = db->pc_next;
+g_assert(tcg_ctx->plugin_mem_cb == NULL);
+} else {
+struct qemu_plugin_insn *insn = _tb->insns[insn_idx++];
+
+tcg_ctx->plugin_insn = NULL;
+if (unlikely(insn->exec_cbs.n)) {
+qemu_plugin_gen_vcpu_udata_callbacks(>exec_cbs);
+}
+if (insn->mem_cbs.n) {
+tcg_ctx->plugin_mem_cb = >mem_cbs;
+if (insn->calls_helpers) {
+qemu_plugin_gen_enable_mem_helpers(>mem_cbs);
+mem_helpers = true;
+}
+} else {
+tcg_ctx->plugin_mem_cb = NULL;
+}
+}
+}
 db->num_insns++;
 ops->insn_start(db, cpu);
 tcg_debug_assert(db->is_jmp == DISAS_NEXT);  /* no early exit */
@@ -101,10 

[Qemu-devel] [RFC 18/48] tcg: add memory callbacks for plugins (WIP)

2018-10-25 Thread Emilio G. Cota
XXX: store hostaddr from non-i386 TCG backends
XXX: what hostaddr to return for I/O accesses?
XXX: what hostaddr to return for cross-page accesses?

Here the trickiest feature is passing the host address to
memory callbacks that request it. Perhaps it would be more
appropriate to pass a "physical" address to plugins, but since
in QEMU host addr ~= guest physical, I'm going with that for
simplicity.

To keep the implementation simple we piggy-back on the TLB fast path,
and thus can only provide the host address _after_ memory accesses
have occurred. For the slow path, it's a bit tedious because there
are many places to update, but it's fairly simple.

However, note that cross-page accesses are tricky, since the
access might be to non-contiguous host addresses. So I'm punting
on that and just passing NULL.

Signed-off-by: Emilio G. Cota 
---
 accel/tcg/atomic_template.h   |  8 -
 accel/tcg/softmmu_template.h  | 39 
 include/exec/cpu-defs.h   |  2 ++
 include/exec/cpu_ldst_template.h  | 43 +++
 include/exec/cpu_ldst_useronly_template.h | 42 +++---
 tcg/tcg-op.h  |  5 +++
 tcg/tcg.h |  4 +++
 tcg/i386/tcg-target.inc.c |  5 +++
 tcg/tcg-op.c  | 37 ++-
 tcg/tcg.c |  3 ++
 10 files changed, 152 insertions(+), 36 deletions(-)

diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h
index b13318c1ce..3de34dc462 100644
--- a/accel/tcg/atomic_template.h
+++ b/accel/tcg/atomic_template.h
@@ -18,6 +18,7 @@
  * License along with this library; if not, see .
  */
 
+#include "qemu/plugin.h"
 #include "trace/mem.h"
 
 #if DATA_SIZE == 16
@@ -66,17 +67,22 @@
 trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info | TRACE_MEM_ST); \
 } while (0)
 
-# define ATOMIC_TRACE_RMW_POST  \
+# define ATOMIC_TRACE_RMW_POST do {
\
+  qemu_plugin_vcpu_mem_cb(ENV_GET_CPU(env), addr, haddr, info);
\
+  qemu_plugin_vcpu_mem_cb(ENV_GET_CPU(env), addr, haddr, info | TRACE_MEM_ST); 
\
+} while (0)
 
 # define ATOMIC_TRACE_LD_PRE\
 trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info)
 
 # define ATOMIC_TRACE_LD_POST   \
+qemu_plugin_vcpu_mem_cb(ENV_GET_CPU(env), addr, haddr, info)
 
 # define ATOMIC_TRACE_ST_PRE\
 trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info)
 
 # define ATOMIC_TRACE_ST_POST   \
+qemu_plugin_vcpu_mem_cb(ENV_GET_CPU(env), addr, haddr, info)
 
 #endif /* ATOMIC_TRACE_RMW_PRE */
 
diff --git a/accel/tcg/softmmu_template.h b/accel/tcg/softmmu_template.h
index b0adea045e..f6d2f60b81 100644
--- a/accel/tcg/softmmu_template.h
+++ b/accel/tcg/softmmu_template.h
@@ -103,6 +103,11 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState 
*env,
   MMUAccessType access_type)
 {
 CPUIOTLBEntry *iotlbentry = >iotlb[mmu_idx][index];
+
+/* XXX Any sensible choice other than NULL? */
+if (tcg_ctx->plugin_mem_cb) {
+env->hostaddr = NULL;
+}
 return io_readx(env, iotlbentry, mmu_idx, addr, retaddr, recheck,
 access_type, DATA_SIZE);
 }
@@ -162,12 +167,23 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, 
target_ulong addr,
 res2 = helper_le_ld_name(env, addr2, oi, retaddr);
 shift = (addr & (DATA_SIZE - 1)) * 8;
 
+/*
+ * XXX cross-page accesses would have to be split into separate 
accesses
+ * for the host address to make sense. For now, just return NULL.
+ */
+if (tcg_ctx->plugin_mem_cb) {
+env->hostaddr = NULL;
+}
+
 /* Little-endian combine.  */
 res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift));
 return res;
 }
 
 haddr = addr + entry->addend;
+if (tcg_ctx->plugin_mem_cb) {
+env->hostaddr = (void *)haddr;
+}
 #if DATA_SIZE == 1
 res = glue(glue(ld, LSUFFIX), _p)((uint8_t *)haddr);
 #else
@@ -231,12 +247,19 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, 
target_ulong addr,
 res2 = helper_be_ld_name(env, addr2, oi, retaddr);
 shift = (addr & (DATA_SIZE - 1)) * 8;
 
+if (tcg_ctx->plugin_mem_cb) {
+env->hostaddr = NULL;
+}
+
 /* Big-endian combine.  */
 res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
 return res;
 }
 
 haddr = addr + entry->addend;
+if (tcg_ctx->plugin_mem_cb) {
+env->hostaddr = (void *)haddr;
+}
 res = glue(glue(ld, LSUFFIX), _be_p)((uint8_t *)haddr);
 return res;
 }
@@ -270,6 +293,10 @@ static 

[Qemu-devel] [RFC 48/48] plugin: add a couple of very simple examples

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 plugin-examples/bbcount_avgsize_racy.c | 50 ++
 plugin-examples/mem_count_racy_both.c  | 58 ++
 plugin-examples/Makefile   | 31 ++
 3 files changed, 139 insertions(+)
 create mode 100644 plugin-examples/bbcount_avgsize_racy.c
 create mode 100644 plugin-examples/mem_count_racy_both.c
 create mode 100644 plugin-examples/Makefile

diff --git a/plugin-examples/bbcount_avgsize_racy.c 
b/plugin-examples/bbcount_avgsize_racy.c
new file mode 100644
index 00..ccdf96c1fa
--- /dev/null
+++ b/plugin-examples/bbcount_avgsize_racy.c
@@ -0,0 +1,50 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+static uint64_t bb_count;
+static uint64_t insn_count;
+const char *filename;
+static int stdout_fd;
+
+static void plugin_exit(qemu_plugin_id_t id, void *p)
+{
+dprintf(stdout_fd, "insns: %" PRIu64", bb: %" PRIu64 ", "
+"avg insns/bb: %.2f\n",
+insn_count, bb_count, (double)insn_count / bb_count);
+}
+
+static void vcpu_tb_exec(unsigned int cpu_index, void *udata)
+{
+unsigned long n_insns = (unsigned long)udata;
+
+insn_count += n_insns;
+bb_count++;
+}
+
+static void vcpu_tb_trans(qemu_plugin_id_t id, unsigned int cpu_index,
+  struct qemu_plugin_tb *tb)
+{
+unsigned long n_insns = qemu_plugin_tb_n_insns(tb);
+
+qemu_plugin_register_vcpu_tb_exec_cb(tb, vcpu_tb_exec,
+ QEMU_PLUGIN_CB_NO_REGS,
+ (void *)n_insns);
+}
+
+QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, int argc,
+   char **argv)
+{
+/* plugin_exit might write to stdout after stdout has been closed */
+stdout_fd = dup(STDOUT_FILENO);
+assert(stdout_fd);
+
+qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans);
+qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
+return 0;
+}
diff --git a/plugin-examples/mem_count_racy_both.c 
b/plugin-examples/mem_count_racy_both.c
new file mode 100644
index 00..a47f2025bf
--- /dev/null
+++ b/plugin-examples/mem_count_racy_both.c
@@ -0,0 +1,58 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+static uint64_t mem_count;
+static int stdout_fd;
+static bool do_inline;
+
+static void plugin_exit(qemu_plugin_id_t id, void *p)
+{
+dprintf(stdout_fd, "accesses: %" PRIu64 "\n", mem_count);
+}
+
+static void vcpu_mem(unsigned int cpu_index, qemu_plugin_meminfo_t meminfo,
+ uint64_t vaddr, void *udata)
+{
+mem_count++;
+}
+
+static void vcpu_tb_trans(qemu_plugin_id_t id, unsigned int cpu_index,
+  struct qemu_plugin_tb *tb)
+{
+size_t n = qemu_plugin_tb_n_insns(tb);
+size_t i;
+
+for (i = 0; i < n; i++) {
+struct qemu_plugin_insn *insn = qemu_plugin_tb_get_insn(tb, i);
+
+if (do_inline) {
+qemu_plugin_register_vcpu_mem_inline(insn,
+ QEMU_PLUGIN_INLINE_ADD_U64,
+ _count, 1);
+} else {
+qemu_plugin_register_vcpu_mem_cb(insn, vcpu_mem,
+ QEMU_PLUGIN_CB_NO_REGS, NULL);
+}
+}
+}
+
+QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, int argc,
+   char **argv)
+{
+if (argc && strcmp(argv[0], "inline") == 0) {
+do_inline = true;
+}
+/* plugin_exit might write to stdout after stdout has been closed */
+stdout_fd = dup(STDOUT_FILENO);
+assert(stdout_fd);
+
+qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans);
+qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
+return 0;
+}
diff --git a/plugin-examples/Makefile b/plugin-examples/Makefile
new file mode 100644
index 00..71bbcda7a8
--- /dev/null
+++ b/plugin-examples/Makefile
@@ -0,0 +1,31 @@
+NAMES :=
+NAMES += bbcount_avgsize_racy
+NAMES += mem_count_racy_both
+
+SONAMES := $(addsuffix .so,$(addprefix lib,$(NAMES)))
+
+# QEMU installed path, set by --prefix during configure
+QEMU_PATH ?= /data/src/qemu-inst/plugin-test
+
+CC := gcc
+CFLAGS :=
+CFLAGS += -O2 -Werror -Wall
+CFLAGS += -Wundef -Wwrite-strings -Wmissing-prototypes
+CFLAGS += -Wstrict-prototypes -Wredundant-decls
+CFLAGS += -fno-strict-aliasing -fno-common -fwrapv
+CFLAGS += -I$(QEMU_PATH)/include
+LDLIBS := -lc
+
+all: $(SONAMES)
+
+%.o: %.c
+   $(CC) $(CFLAGS) -fPIC -c $< -o $@
+
+lib%.so: %.o
+   $(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDLIBS)
+
+clean:
+   $(RM) -f *.o *.so
+   $(RM) -Rf .libs
+
+.PHONY: all clean
-- 
2.17.1




[Qemu-devel] [RFC 17/48] plugin-gen: add TCG code generation helpers

2018-10-25 Thread Emilio G. Cota
Here we implement several features:

- Inlining TCG code for simple operations. Crucially, we do not
  export TCG ops to plugins. Instead, we give them a C API to
  insert inlined ops. So far we only support adding an immediate
  to a u64, e.g. to count events.

- "Direct" callbacks. These are callbacks that do not go via
  a helper. Instead, the helper is defined at run-time, so that
  the plugin code is directly called from TCG. This makes direct
  callbacks as efficient as possible; they are therefore used
  for very frequent events, e.g. memory callbacks.

- Passing the host address to memory callbacks. Most of this
  is implemented in a later patch though.

- Instrumentation of memory accesses performed from helpers. See comment.

Signed-off-by: Emilio G. Cota 
---
 include/exec/plugin-gen.h |  51 +
 accel/tcg/plugin-gen.c| 230 ++
 accel/tcg/Makefile.objs   |   1 +
 3 files changed, 282 insertions(+)
 create mode 100644 include/exec/plugin-gen.h
 create mode 100644 accel/tcg/plugin-gen.c

diff --git a/include/exec/plugin-gen.h b/include/exec/plugin-gen.h
new file mode 100644
index 00..46a167527e
--- /dev/null
+++ b/include/exec/plugin-gen.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017, Emilio G. Cota 
+ *
+ * License: GNU GPL, version 2 or later.
+ *   See the COPYING file in the top-level directory.
+ *
+ * plugin-gen.h - TCG-dependent definitions for generating plugin code
+ *
+ * This header should be included only from plugin.c and C files that emit
+ * TCG code.
+ */
+#ifndef QEMU_PLUGIN_GEN_H
+#define QEMU_PLUGIN_GEN_H
+
+#include "qemu/plugin.h"
+#include "tcg/tcg.h"
+
+#ifdef CONFIG_PLUGINS
+
+void qemu_plugin_gen_vcpu_mem_callbacks(struct qemu_plugin_dyn_cb_arr *arr,
+TCGv vaddr, uint8_t info);
+
+void qemu_plugin_gen_vcpu_udata_callbacks(struct qemu_plugin_dyn_cb_arr *arr);
+
+void qemu_plugin_gen_disable_mem_helpers(void);
+
+void
+qemu_plugin_gen_enable_mem_helpers(const struct qemu_plugin_dyn_cb_arr *orig);
+
+#else /* !CONFIG_PLUGINS */
+
+static inline void
+qemu_plugin_gen_vcpu_mem_callbacks(struct qemu_plugin_dyn_cb_arr *arr,
+   TCGv vaddr, uint8_t info)
+{ }
+
+static inline void
+qemu_plugin_gen_vcpu_udata_callbacks(struct qemu_plugin_dyn_cb_arr *arr)
+{ }
+
+static inline void qemu_plugin_gen_disable_mem_helpers(void)
+{ }
+
+static inline void
+qemu_plugin_gen_enable_mem_helpers(const struct qemu_plugin_dyn_cb_arr *orig)
+{ }
+
+#endif /* CONFIG_PLUGINS */
+
+#endif /* QEMU_PLUGIN_GEN_H */
+
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
new file mode 100644
index 00..75f182be37
--- /dev/null
+++ b/accel/tcg/plugin-gen.c
@@ -0,0 +1,230 @@
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "tcg/tcg.h"
+#include "tcg/tcg-op.h"
+#include "exec/exec-all.h"
+#include "exec/plugin-gen.h"
+
+static void gen_inline_op(struct qemu_plugin_dyn_cb *cb)
+{
+TCGv_i64 val = tcg_temp_new_i64();
+TCGv_ptr ptr = tcg_const_ptr(cb->userp);
+
+tcg_gen_ld_i64(val, ptr, 0);
+switch (cb->inline_insn.op) {
+case QEMU_PLUGIN_INLINE_ADD_U64:
+tcg_gen_addi_i64(val, val, cb->inline_insn.imm);
+break;
+default:
+g_assert_not_reached();
+}
+tcg_gen_st_i64(val, ptr, 0);
+
+tcg_temp_free_ptr(ptr);
+tcg_temp_free_i64(val);
+}
+
+static void gen_helper_mem_cb(const char *name, unsigned flags,
+  qemu_plugin_vcpu_mem_cb_t cb, TCGv_i32 cpu_index,
+  TCGv_i32 meminfo, TCGv_i64 vaddr, TCGv_ptr udata)
+{
+TCGHelperInfo info = {
+.func = cb,
+.name = name,
+.flags = flags,
+.sizemask = dh_sizemask(void, 0) |
+dh_sizemask(i32, 1) |
+dh_sizemask(i32, 2) |
+dh_sizemask(i64, 3) |
+dh_sizemask(ptr, 4),
+
+};
+TCGTemp *args[] = {
+tcgv_i32_temp(cpu_index),
+tcgv_i32_temp(meminfo),
+tcgv_i64_temp(vaddr),
+tcgv_ptr_temp(udata),
+};
+
+tcg_gen_runtime_helper(, NULL, ARRAY_SIZE(args), args);
+}
+
+static void gen_helper_mem_haddr_cb(const char *name, unsigned flags,
+qemu_plugin_vcpu_mem_haddr_cb_t cb,
+TCGv_i32 cpu_index, TCGv_i32 meminfo,
+TCGv_i64 vaddr, TCGv_ptr haddr,
+TCGv_ptr udata)
+{
+TCGHelperInfo info = {
+.func = cb,
+.name = name,
+.flags = flags,
+.sizemask = dh_sizemask(void, 0) |
+dh_sizemask(i32, 1) |
+dh_sizemask(i32, 2) |
+dh_sizemask(i64, 3) |
+dh_sizemask(ptr, 4) |
+dh_sizemask(ptr, 5),
+
+};
+TCGTemp *args[] = {
+tcgv_i32_temp(cpu_index),
+tcgv_i32_temp(meminfo),
+

[Qemu-devel] [RFC 14/48] plugin: preliminary user-facing API

2018-10-25 Thread Emilio G. Cota
Add the API first to ease review.

Signed-off-by: Emilio G. Cota 
---
 include/qemu/plugin-api.h | 227 ++
 1 file changed, 227 insertions(+)
 create mode 100644 include/qemu/plugin-api.h

diff --git a/include/qemu/plugin-api.h b/include/qemu/plugin-api.h
new file mode 100644
index 00..5c6bb45279
--- /dev/null
+++ b/include/qemu/plugin-api.h
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2017, Emilio G. Cota 
+ *
+ * License: GNU GPL, version 2 or later.
+ *   See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_PLUGIN_API_H
+#define QEMU_PLUGIN_API_H
+
+#include 
+#include 
+
+/*
+ * For best performance, build the plugin with -fvisibility=hidden so that
+ * QEMU_PLUGIN_LOCAL is implicit. Then, just mark qemu_plugin_install with
+ * QEMU_PLUGIN_EXPORT. For more info, see
+ *   https://gcc.gnu.org/wiki/Visibility
+ */
+#if defined _WIN32 || defined __CYGWIN__
+  #ifdef BUILDING_DLL
+#define QEMU_PLUGIN_EXPORT __declspec(dllexport)
+  #else
+#define QEMU_PLUGIN_EXPORT __declspec(dllimport)
+  #endif
+  #define QEMU_PLUGIN_LOCAL
+#else
+  #if __GNUC__ >= 4
+#define QEMU_PLUGIN_EXPORT __attribute__((visibility("default")))
+#define QEMU_PLUGIN_LOCAL  __attribute__((visibility("hidden")))
+  #else
+#define QEMU_PLUGIN_EXPORT
+#define QEMU_PLUGIN_LOCAL
+  #endif
+#endif
+
+typedef uint64_t qemu_plugin_id_t;
+
+/**
+ * qemu_plugin_install - Install a plugin
+ * @id: this plugin's opaque ID
+ * @argc: number of arguments
+ * @argv: array of arguments (@argc elements)
+ *
+ * All plugins must export this symbol.
+ *
+ * Note: @argv is freed after this function returns.
+ */
+QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, int argc,
+   char **argv);
+
+typedef void (*qemu_plugin_uninstall_cb_t)(qemu_plugin_id_t id);
+
+/**
+ * qemu_plugin_uninstall - Uninstall a plugin
+ * @id: this plugin's opaque ID
+ * @cb: callback to be called once the plugin has been removed
+ *
+ * Do NOT assume that the plugin has been uninstalled once this
+ * function returns. Plugins are uninstalled asynchronously,
+ * and therefore the given plugin might still receive callbacks
+ * from prior subscriptions _until_ @cb is called.
+ */
+void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_uninstall_cb_t cb);
+
+typedef void (*qemu_plugin_simple_cb_t)(qemu_plugin_id_t id);
+
+typedef void (*qemu_plugin_udata_cb_t)(qemu_plugin_id_t id, void *userdata);
+
+typedef void (*qemu_plugin_vcpu_simple_cb_t)(qemu_plugin_id_t id,
+ unsigned int vcpu_index);
+
+typedef void (*qemu_plugin_vcpu_udata_cb_t)(unsigned int vcpu_index,
+void *userdata);
+
+/**
+ * qemu_plugin_register_vcpu_init_cb - register a vCPU initialization callback
+ * @id: plugin ID
+ * @cb: callback function
+ *
+ * The @cb function is called every time a vCPU is initialized.
+ *
+ * See also: qemu_plugin_register_vcpu_exit_cb()
+ */
+void qemu_plugin_register_vcpu_init_cb(qemu_plugin_id_t id,
+   qemu_plugin_vcpu_simple_cb_t cb);
+
+/**
+ * qemu_plugin_register_vcpu_exit_cb - register a vCPU exit callback
+ * @id: plugin ID
+ * @cb: callback function
+ *
+ * The @cb function is called every time a vCPU exits.
+ *
+ * See also: qemu_plugin_register_vcpu_init_cb()
+ */
+void qemu_plugin_register_vcpu_exit_cb(qemu_plugin_id_t id,
+   qemu_plugin_vcpu_simple_cb_t cb);
+
+void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_t id,
+   qemu_plugin_vcpu_simple_cb_t cb);
+
+void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t id,
+ qemu_plugin_vcpu_simple_cb_t cb);
+
+struct qemu_plugin_tb;
+struct qemu_plugin_insn;
+
+enum qemu_plugin_cb_flags {
+QEMU_PLUGIN_CB_NO_REGS, /* callback does not access the CPU's regs */
+QEMU_PLUGIN_CB_R_REGS,  /* callback reads the CPU's regs */
+QEMU_PLUGIN_CB_RW_REGS, /* callback reads and writes the CPU's regs */
+};
+
+typedef void (*qemu_plugin_vcpu_tb_trans_cb_t)(qemu_plugin_id_t id,
+   unsigned int vcpu_index,
+   struct qemu_plugin_tb *tb);
+
+void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id,
+   qemu_plugin_vcpu_tb_trans_cb_t cb);
+
+/* can only call from tb_trans_cb callback */
+void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb,
+  qemu_plugin_vcpu_udata_cb_t cb,
+  enum qemu_plugin_cb_flags flags,
+  void *userdata);
+
+enum qemu_plugin_op {
+QEMU_PLUGIN_INLINE_ADD_U64,
+};
+
+void qemu_plugin_register_vcpu_tb_exec_inline(struct qemu_plugin_tb *tb,
+   

[Qemu-devel] [RFC 22/48] cpu: hook plugin vcpu events

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 cpus.c| 10 ++
 exec.c|  2 ++
 qom/cpu.c |  2 ++
 3 files changed, 14 insertions(+)

diff --git a/cpus.c b/cpus.c
index 28e39f045a..3efe89354d 100644
--- a/cpus.c
+++ b/cpus.c
@@ -43,6 +43,7 @@
 #include "exec/exec-all.h"
 
 #include "qemu/thread.h"
+#include "qemu/plugin.h"
 #include "sysemu/cpus.h"
 #include "sysemu/qtest.h"
 #include "qemu/main-loop.h"
@@ -1322,12 +1323,21 @@ static void qemu_tcg_rr_wait_io_event(CPUState *cpu)
 
 static void qemu_wait_io_event(CPUState *cpu)
 {
+bool asleep = false;
+
 g_assert(cpu_mutex_locked(cpu));
 g_assert(!qemu_mutex_iothread_locked());
 
 while (cpu_thread_is_idle(cpu)) {
+if (!asleep) {
+asleep = true;
+qemu_plugin_vcpu_idle_cb(cpu);
+}
 qemu_cond_wait(>halt_cond, >lock);
 }
+if (asleep) {
+qemu_plugin_vcpu_resume_cb(cpu);
+}
 
 #ifdef _WIN32
 /* Eat dummy APC queued by qemu_cpu_kick_thread.  */
diff --git a/exec.c b/exec.c
index cd171adb93..71fc76f55e 100644
--- a/exec.c
+++ b/exec.c
@@ -967,6 +967,8 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
 }
 tlb_init(cpu);
 
+qemu_plugin_vcpu_init_hook(cpu);
+
 #ifndef CONFIG_USER_ONLY
 if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
 vmstate_register(NULL, cpu->cpu_index, _cpu_common, cpu);
diff --git a/qom/cpu.c b/qom/cpu.c
index d1e6ecae03..062817c03b 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -32,6 +32,7 @@
 #include "hw/boards.h"
 #include "hw/qdev-properties.h"
 #include "trace-root.h"
+#include "qemu/plugin.h"
 
 CPUInterruptHandler cpu_interrupt_handler;
 
@@ -353,6 +354,7 @@ static void cpu_common_unrealizefn(DeviceState *dev, Error 
**errp)
 CPUState *cpu = CPU(dev);
 /* NOTE: latest generic point before the cpu is fully unrealized */
 trace_fini_vcpu(cpu);
+qemu_plugin_vcpu_exit_hook(cpu);
 cpu_exec_unrealizefn(cpu);
 }
 
-- 
2.17.1




[Qemu-devel] [RFC 41/48] configure: add --enable-plugins

2018-10-25 Thread Emilio G. Cota
For now only add it for ELF platforms, since we rely on the linker's
--dynamic-list flag to pass a list of symbols to be exported to the
executable. An alternative would be to use -rdynamic, but that would
expose all of QEMU's objects to plugins.

I have no experience with non-ELF systems but I suspect adding support
for those should be pretty easy.

Signed-off-by: Emilio G. Cota 
---
 configure | 51 +++
 1 file changed, 51 insertions(+)

diff --git a/configure b/configure
index 03bf719ca7..78e86098e5 100755
--- a/configure
+++ b/configure
@@ -30,6 +30,7 @@ TMPO="${TMPDIR1}/${TMPB}.o"
 TMPCXX="${TMPDIR1}/${TMPB}.cxx"
 TMPE="${TMPDIR1}/${TMPB}.exe"
 TMPMO="${TMPDIR1}/${TMPB}.mo"
+TMPTXT="${TMPDIR1}/${TMPB}.txt"
 
 rm -f config.log
 
@@ -477,6 +478,7 @@ libxml2=""
 docker="no"
 debug_mutex="no"
 libpmem=""
+plugins="no"
 
 # cross compilers defaults, can be overridden with --cross-cc-ARCH
 cross_cc_aarch64="aarch64-linux-gnu-gcc"
@@ -1443,6 +1445,10 @@ for opt do
   ;;
   --disable-libpmem) libpmem=no
   ;;
+  --enable-plugins) plugins="yes"
+  ;;
+  --disable-plugins) plugins="no"
+  ;;
   *)
   echo "ERROR: unknown option $opt"
   echo "Try '$0 --help' for more information"
@@ -1633,6 +1639,8 @@ Advanced options (experts only):
xen pv domain builder
   --enable-debug-stack-usage
track the maximum stack usage of stacks created by 
qemu_alloc_stack
+  --enable-plugins
+   enable plugins via shared library loading
 
 Optional features, enabled with --enable-FEATURE and
 disabled with --disable-FEATURE, default is enabled if available:
@@ -5204,6 +5212,42 @@ if compile_prog "" "" ; then
   atomic64=yes
 fi
 
+#
+# See if --dynamic-list is supported by the linker
+
+cat > $TMPTXT < $TMPC <
+void foo(void);
+
+void foo(void)
+{
+  printf("foo\n");
+}
+
+int main(void)
+{
+  foo();
+  return 0;
+}
+EOF
+
+if compile_prog "" "-Wl,--dynamic-list=$TMPTXT" ; then
+  ld_dynamic_list="yes"
+else
+  if test "$plugins" = "yes" ; then
+error_exit \
+"Plugin support requires specifying a set of symbols that " \
+"are exported to plugins. Unfortunately your linker doesn't " \
+"support the flag (--dynamic-list) used for this purpose."
+  fi
+fi
+
 
 # See if 16-byte vector operations are supported.
 # Even without a vector unit the compiler may expand these.
@@ -6091,6 +6135,7 @@ echo "VxHS block device $vxhs"
 echo "capstone  $capstone"
 echo "docker$docker"
 echo "libpmem support   $libpmem"
+echo "plugin support$plugins"
 
 if test "$sdl_too_old" = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -6849,6 +6894,12 @@ if test "$libpmem" = "yes" ; then
   echo "CONFIG_LIBPMEM=y" >> $config_host_mak
 fi
 
+if test "$plugins" = "yes" ; then
+echo "CONFIG_PLUGINS=y" >> $config_host_mak
+LIBS="-ldl $LIBS"
+LDFLAGS="-Wl,--dynamic-list=\$(SRC_PATH)/qemu-plugins.symbols $LDFLAGS"
+fi
+
 if test "$tcg_interpreter" = "yes"; then
   QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
 elif test "$ARCH" = "sparc64" ; then
-- 
2.17.1




[Qemu-devel] [RFC 26/48] target/ppc: prepare for 2-pass translation

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 target/ppc/translate.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 34c3ed0a41..88f88adaff 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7565,6 +7565,9 @@ static void ppc_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cs,
   ctx->opcode, opc1(ctx->opcode), opc2(ctx->opcode),
   opc3(ctx->opcode), opc4(ctx->opcode),
   ctx->le_mode ? "little" : "big");
+
+qemu_plugin_insn_append(plugin_insn, >opcode, sizeof(ctx->opcode));
+
 ctx->base.pc_next += 4;
 table = env->opcodes;
 handler = table[opc1(ctx->opcode)];
@@ -7664,6 +7667,8 @@ static const TranslatorOps ppc_tr_ops = {
 .translate_insn = ppc_tr_translate_insn,
 .tb_stop= ppc_tr_tb_stop,
 .disas_log  = ppc_tr_disas_log,
+.ctx_base_offset= offsetof(DisasContext, base),
+.ctx_size   = sizeof(DisasContext),
 };
 
 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
-- 
2.17.1




[Qemu-devel] [RFC 23/48] translator: add plugin_insn argument to translate_insn

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 include/exec/translator.h   | 4 +++-
 accel/tcg/translator.c  | 4 ++--
 target/alpha/translate.c| 3 ++-
 target/arm/translate-a64.c  | 3 ++-
 target/arm/translate.c  | 6 --
 target/hppa/translate.c | 3 ++-
 target/i386/translate.c | 3 ++-
 target/m68k/translate.c | 3 ++-
 target/mips/translate.c | 3 ++-
 target/openrisc/translate.c | 3 ++-
 target/ppc/translate.c  | 3 ++-
 target/riscv/translate.c| 3 ++-
 target/s390x/translate.c| 3 ++-
 target/sh4/translate.c  | 3 ++-
 target/sparc/translate.c| 3 ++-
 target/xtensa/translate.c   | 3 ++-
 16 files changed, 35 insertions(+), 18 deletions(-)

diff --git a/include/exec/translator.h b/include/exec/translator.h
index 71e7b2c347..a28147b3dd 100644
--- a/include/exec/translator.h
+++ b/include/exec/translator.h
@@ -20,6 +20,7 @@
 
 
 #include "exec/exec-all.h"
+#include "qemu/plugin.h"
 #include "tcg/tcg.h"
 
 
@@ -112,7 +113,8 @@ typedef struct TranslatorOps {
 void (*insn_start)(DisasContextBase *db, CPUState *cpu);
 bool (*breakpoint_check)(DisasContextBase *db, CPUState *cpu,
  const CPUBreakpoint *bp);
-void (*translate_insn)(DisasContextBase *db, CPUState *cpu);
+void (*translate_insn)(DisasContextBase *db, CPUState *cpu,
+   struct qemu_plugin_insn *plugin_insn);
 void (*tb_stop)(DisasContextBase *db, CPUState *cpu);
 void (*disas_log)(const DisasContextBase *db, CPUState *cpu);
 } TranslatorOps;
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
index afd0a49ea6..8591e4b72a 100644
--- a/accel/tcg/translator.c
+++ b/accel/tcg/translator.c
@@ -101,10 +101,10 @@ void translator_loop(const TranslatorOps *ops, 
DisasContextBase *db,
 && (tb_cflags(db->tb) & CF_LAST_IO)) {
 /* Accept I/O on the last instruction.  */
 gen_io_start();
-ops->translate_insn(db, cpu);
+ops->translate_insn(db, cpu, NULL);
 gen_io_end();
 } else {
-ops->translate_insn(db, cpu);
+ops->translate_insn(db, cpu, NULL);
 }
 
 /* Stop translation if translate_insn so indicated.  */
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 25cd95931d..72a302e102 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -2983,7 +2983,8 @@ static bool alpha_tr_breakpoint_check(DisasContextBase 
*dcbase, CPUState *cpu,
 return true;
 }
 
-static void alpha_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
+static void alpha_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu,
+struct qemu_plugin_insn *plugin_insn)
 {
 DisasContext *ctx = container_of(dcbase, DisasContext, base);
 CPUAlphaState *env = cpu->env_ptr;
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index bb9c4d8ac7..8b1e20dd59 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -13937,7 +13937,8 @@ static bool 
aarch64_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
 return true;
 }
 
-static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
+static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu,
+  struct qemu_plugin_insn *plugin_insn)
 {
 DisasContext *dc = container_of(dcbase, DisasContext, base);
 CPUARMState *env = cpu->env_ptr;
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 1b4bacb522..2fd32a2684 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -12787,7 +12787,8 @@ static void arm_post_translate_insn(DisasContext *dc)
 translator_loop_temp_check(>base);
 }
 
-static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
+static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu,
+  struct qemu_plugin_insn *plugin_insn)
 {
 DisasContext *dc = container_of(dcbase, DisasContext, base);
 CPUARMState *env = cpu->env_ptr;
@@ -12854,7 +12855,8 @@ static bool thumb_insn_is_unconditional(DisasContext 
*s, uint32_t insn)
 return false;
 }
 
-static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
+static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu,
+struct qemu_plugin_insn *plugin_insn)
 {
 DisasContext *dc = container_of(dcbase, DisasContext, base);
 CPUARMState *env = cpu->env_ptr;
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index df9179e70f..6c2a7fbc46 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -4737,7 +4737,8 @@ static bool hppa_tr_breakpoint_check(DisasContextBase 
*dcbase, CPUState *cs,
 return true;
 }
 
-static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
+static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState 

[Qemu-devel] [RFC 32/48] target/alpha: prepare for 2-pass translation

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 target/alpha/translate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 72a302e102..21405df2b8 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -2990,6 +2990,7 @@ static void alpha_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu,
 CPUAlphaState *env = cpu->env_ptr;
 uint32_t insn = cpu_ldl_code(env, ctx->base.pc_next);
 
+qemu_plugin_insn_append(plugin_insn, , sizeof(insn));
 ctx->base.pc_next += 4;
 ctx->base.is_jmp = translate_one(ctx, insn);
 
@@ -3046,6 +3047,8 @@ static const TranslatorOps alpha_tr_ops = {
 .translate_insn = alpha_tr_translate_insn,
 .tb_stop= alpha_tr_tb_stop,
 .disas_log  = alpha_tr_disas_log,
+.ctx_base_offset= offsetof(DisasContext, base),
+.ctx_size   = sizeof(DisasContext),
 };
 
 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
-- 
2.17.1




[Qemu-devel] [RFC 42/48] vl: support -plugin option

2018-10-25 Thread Emilio G. Cota
From: Lluís Vilanova 

Signed-off-by: Lluís Vilanova 
[ cota: s/instrument/plugin ]
Signed-off-by: Emilio G. Cota 
---
 vl.c| 11 +++
 qemu-options.hx | 17 +
 2 files changed, 28 insertions(+)

diff --git a/vl.c b/vl.c
index 4e25c78bff..ebb188552e 100644
--- a/vl.c
+++ b/vl.c
@@ -111,6 +111,7 @@ int main(int argc, char **argv)
 
 #include "trace-root.h"
 #include "trace/control.h"
+#include "qemu/plugin.h"
 #include "qemu/queue.h"
 #include "sysemu/arch_init.h"
 
@@ -2962,6 +2963,7 @@ int main(int argc, char **argv, char **envp)
 } BlockdevOptions_queue;
 QSIMPLEQ_HEAD(, BlockdevOptions_queue) bdo_queue
 = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
+struct qemu_plugin_list plugin_list = QTAILQ_HEAD_INITIALIZER(plugin_list);
 
 module_call_init(MODULE_INIT_TRACE);
 
@@ -2990,6 +2992,7 @@ int main(int argc, char **argv, char **envp)
 qemu_add_opts(_global_opts);
 qemu_add_opts(_mon_opts);
 qemu_add_opts(_trace_opts);
+qemu_plugin_add_opts();
 qemu_add_opts(_option_rom_opts);
 qemu_add_opts(_machine_opts);
 qemu_add_opts(_accel_opts);
@@ -3806,6 +3809,9 @@ int main(int argc, char **argv, char **envp)
 g_free(trace_file);
 trace_file = trace_opt_parse(optarg);
 break;
+case QEMU_OPTION_plugin:
+qemu_plugin_opt_parse(optarg, _list);
+break;
 case QEMU_OPTION_readconfig:
 {
 int ret = qemu_read_config_file(optarg);
@@ -4107,6 +4113,11 @@ int main(int argc, char **argv, char **envp)
machine_class->default_machine_opts, 0);
 }
 
+/* process plugin before CPUs are created, but once -smp has been parsed */
+if (qemu_plugin_load_list(_list)) {
+exit(1);
+}
+
 qemu_opts_foreach(qemu_find_opts("device"),
   default_driver_check, NULL, NULL);
 qemu_opts_foreach(qemu_find_opts("global"),
diff --git a/qemu-options.hx b/qemu-options.hx
index f139459e80..5cd1d84df4 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3838,6 +3838,23 @@ HXCOMM HX does not support conditional compilation of 
text.
 @findex -trace
 @include qemu-option-trace.texi
 ETEXI
+DEF("plugin", HAS_ARG, QEMU_OPTION_plugin,
+"-plugin [file=][,arg=]\n"
+"load a plugin\n",
+QEMU_ARCH_ALL)
+STEXI
+@item -plugin file=@var{file}[,arg=@var{string}]
+@findex -plugin
+
+Load a plugin.
+
+@table @option
+@item file=@var{file}
+Load the given plugin from a shared library file.
+@item arg=@var{string}
+Argument string passed to the plugin. (Can be given multiple times.)
+@end table
+ETEXI
 
 HXCOMM Internal use
 DEF("qtest", HAS_ARG, QEMU_OPTION_qtest, "", QEMU_ARCH_ALL)
-- 
2.17.1




[Qemu-devel] [RFC 35/48] target/sparc: prepare for 2-pass translation

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 target/sparc/translate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 2fa8b68e0a..74889de426 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -5902,6 +5902,7 @@ static void sparc_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cs,
 unsigned int insn;
 
 insn = cpu_ldl_code(env, dc->pc);
+qemu_plugin_insn_append(plugin_insn, , sizeof(insn));
 dc->base.pc_next += 4;
 disas_sparc_insn(dc, insn);
 
@@ -5961,6 +5962,8 @@ static const TranslatorOps sparc_tr_ops = {
 .translate_insn = sparc_tr_translate_insn,
 .tb_stop= sparc_tr_tb_stop,
 .disas_log  = sparc_tr_disas_log,
+.ctx_base_offset= offsetof(DisasContext, base),
+.ctx_size   = sizeof(DisasContext),
 };
 
 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
-- 
2.17.1




[Qemu-devel] [RFC 40/48] plugin: let plugins control the virtual clock

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 include/qemu/plugin-api.h |  9 +
 include/qemu/plugin.h |  5 +++
 plugin.c  | 79 +++
 stubs/plugin.c|  9 +
 util/qemu-timer.c |  3 ++
 qemu-plugins.symbols  |  1 +
 stubs/Makefile.objs   |  1 +
 7 files changed, 107 insertions(+)
 create mode 100644 stubs/plugin.c

diff --git a/include/qemu/plugin-api.h b/include/qemu/plugin-api.h
index 5c6bb45279..076353a2d2 100644
--- a/include/qemu/plugin-api.h
+++ b/include/qemu/plugin-api.h
@@ -218,6 +218,15 @@ void qemu_plugin_register_flush_cb(qemu_plugin_id_t id,
 void qemu_plugin_register_atexit_cb(qemu_plugin_id_t id,
 qemu_plugin_udata_cb_t cb, void *userdata);
 
+typedef int64_t (*qemu_plugin_clock_func_t)(void);
+
+/*
+ * Can only be called from plugin_init.
+ * Returns true on success
+ */
+bool qemu_plugin_register_virtual_clock(qemu_plugin_id_t id,
+qemu_plugin_clock_func_t clock);
+
 /* returns -1 in user-mode */
 int qemu_plugin_n_vcpus(void);
 
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index 0da0f1b892..617161329f 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -127,6 +127,8 @@ struct qemu_plugin_tb {
 struct qemu_plugin_dyn_cb_arr cbs;
 };
 
+extern bool use_plugin_clock;
+
 static inline void qemu_plugin_insn_append(struct qemu_plugin_insn *insn,
const void *from, size_t size)
 {
@@ -191,6 +193,7 @@ void qemu_plugin_flush_cb(void);
 void qemu_plugin_atexit_cb(void);
 
 void qemu_plugin_add_dyn_cb_arr(struct qemu_plugin_dyn_cb_arr *arr);
+int64_t plugin_get_clock(void);
 
 #else /* !CONFIG_PLUGINS */
 
@@ -234,6 +237,8 @@ static inline
 void qemu_plugin_add_dyn_cb_arr(struct qemu_plugin_dyn_cb_arr *arr)
 { }
 
+int64_t plugin_get_clock(void);
+
 #endif /* !CONFIG_PLUGINS */
 
 #endif /* QEMU_PLUGIN_H */
diff --git a/plugin.c b/plugin.c
index 76609f1da4..291767f2bb 100644
--- a/plugin.c
+++ b/plugin.c
@@ -71,6 +71,13 @@ struct qemu_plugin_state {
  * the code cache is flushed.
  */
 struct qht dyn_cb_arr_ht;
+/*
+ * We support a single clock reference from plugins. We keep a pointer
+ * to the context of the plugin that provides the reference,
+ * so that we can remove the reference when the plugin is uninstalled.
+ */
+qemu_plugin_clock_func_t clock_ref;
+struct qemu_plugin_ctx *clock_ctx;
 };
 
 /*
@@ -104,6 +111,8 @@ QemuOptsList qemu_plugin_opts = {
 typedef int (*qemu_plugin_install_func_t)(qemu_plugin_id_t, int, char **);
 
 static struct qemu_plugin_state plugin;
+bool use_plugin_clock;
+static bool plugin_installing;
 
 static bool plugin_dyn_cb_arr_cmp(const void *ap, const void *bp)
 {
@@ -251,7 +260,9 @@ static int plugin_load(struct qemu_plugin_desc *desc)
 QTAILQ_INSERT_TAIL(, ctx, entry);
 qemu_rec_mutex_unlock();
 
+plugin_installing = true;
 rc = install(ctx->id, desc->argc, desc->argv);
+plugin_installing = false;
 if (rc) {
 error_report("%s: qemu_plugin_install returned error code %d",
  __func__, rc);
@@ -418,6 +429,10 @@ void qemu_plugin_uninstall(qemu_plugin_id_t id, 
qemu_plugin_uninstall_cb_t cb)
 for (ev = 0; ev < QEMU_PLUGIN_EV_MAX; ev++) {
 plugin_unregister_cb__locked(ctx, ev);
 }
+if (ctx == plugin.clock_ctx) {
+atomic_set(_ref, NULL);
+plugin.clock_ctx = NULL;
+}
 qemu_rec_mutex_unlock();
 
 /* XXX how to flush when we're not in a vCPU thread? */
@@ -964,6 +979,70 @@ uint64_t qemu_plugin_ram_addr_from_host(void *haddr)
 #endif
 }
 
+#ifndef CONFIG_USER_ONLY
+static bool
+qemu_plugin_register_virtual_clock__locked(qemu_plugin_id_t id,
+   qemu_plugin_clock_func_t clock)
+{
+struct qemu_plugin_ctx *ctx = id_to_ctx__locked(id);
+
+if (!plugin_installing) {
+error_report("plugin: can only call %s during plugin installation",
+ __func__);
+return false;
+}
+if (use_plugin_clock) {
+error_report("plugin: clock reference already registered");
+return false;
+}
+if (clock == NULL) {
+error_report("%s: cannot pass NULL clock", __func__);
+return false;
+}
+plugin.clock_ctx = ctx;
+use_plugin_clock = true;
+atomic_set(_ref, clock);
+return true;
+}
+#endif /* !CONFIG_USER_ONLY */
+
+bool qemu_plugin_register_virtual_clock(qemu_plugin_id_t id,
+qemu_plugin_clock_func_t clock)
+{
+#ifdef CONFIG_USER_ONLY
+return false;
+#else
+bool ret;
+
+qemu_rec_mutex_lock();
+ret = qemu_plugin_register_virtual_clock__locked(id, clock);
+qemu_rec_mutex_unlock();
+return ret;
+#endif
+}
+
+#ifdef CONFIG_USER_ONLY
+int64_t plugin_get_clock(void)
+{
+abort();
+return 0;
+}
+#else
+/*
+ * Note: use_plugin_clock 

[Qemu-devel] [RFC 30/48] target/m68k: prepare for 2-pass translation

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 target/m68k/translate.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index dd7d868b25..9b5a4b1eb5 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -116,6 +116,7 @@ typedef struct DisasContext {
 int done_mac;
 int writeback_mask;
 TCGv writeback[8];
+struct qemu_plugin_insn *plugin_insn;
 #define MAX_TO_RELEASE 8
 int release_count;
 TCGv release[MAX_TO_RELEASE];
@@ -375,6 +376,7 @@ static inline uint16_t read_im16(CPUM68KState *env, 
DisasContext *s)
 uint16_t im;
 im = cpu_lduw_code(env, s->pc);
 s->pc += 2;
+qemu_plugin_insn_append(s->plugin_insn, , sizeof(im));
 return im;
 }
 
@@ -6092,7 +6094,10 @@ static void m68k_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu,
 {
 DisasContext *dc = container_of(dcbase, DisasContext, base);
 CPUM68KState *env = cpu->env_ptr;
-uint16_t insn = read_im16(env, dc);
+uint16_t insn;
+
+dc->plugin_insn = plugin_insn;
+insn = read_im16(env, dc);
 
 opcode_table[insn](env, dc, insn);
 do_writebacks(dc);
@@ -6167,6 +6172,8 @@ static const TranslatorOps m68k_tr_ops = {
 .translate_insn = m68k_tr_translate_insn,
 .tb_stop= m68k_tr_tb_stop,
 .disas_log  = m68k_tr_disas_log,
+.ctx_base_offset= offsetof(DisasContext, base),
+.ctx_size   = sizeof(DisasContext),
 };
 
 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
-- 
2.17.1




[Qemu-devel] [RFC 28/48] target/i386: prepare for 2-pass translation

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 target/i386/translate.c | 35 ---
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 86e59d7bf7..1d7b20bce3 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -142,6 +142,7 @@ typedef struct DisasContext {
 TCGv_i32 tmp3_i32;
 TCGv_i64 tmp1_i64;
 
+struct qemu_plugin_insn *plugin_insn;
 sigjmp_buf jmpbuf;
 } DisasContext;
 
@@ -1900,28 +1901,43 @@ static uint64_t advance_pc(CPUX86State *env, 
DisasContext *s, int num_bytes)
 
 static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s)
 {
-return cpu_ldub_code(env, advance_pc(env, s, 1));
+uint8_t ret = cpu_ldub_code(env, advance_pc(env, s, 1));
+
+qemu_plugin_insn_append(s->plugin_insn, , sizeof(ret));
+return ret;
 }
 
 static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s)
 {
-return cpu_ldsw_code(env, advance_pc(env, s, 2));
+int16_t ret = cpu_ldsw_code(env, advance_pc(env, s, 2));
+
+qemu_plugin_insn_append(s->plugin_insn, , sizeof(ret));
+return ret;
 }
 
 static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s)
 {
-return cpu_lduw_code(env, advance_pc(env, s, 2));
+uint16_t ret = cpu_lduw_code(env, advance_pc(env, s, 2));
+
+qemu_plugin_insn_append(s->plugin_insn, , sizeof(ret));
+return ret;
 }
 
 static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s)
 {
-return cpu_ldl_code(env, advance_pc(env, s, 4));
+uint32_t ret = cpu_ldl_code(env, advance_pc(env, s, 4));
+
+qemu_plugin_insn_append(s->plugin_insn, , sizeof(ret));
+return ret;
 }
 
 #ifdef TARGET_X86_64
 static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s)
 {
-return cpu_ldq_code(env, advance_pc(env, s, 8));
+uint64_t ret = cpu_ldq_code(env, advance_pc(env, s, 8));
+
+qemu_plugin_insn_append(s->plugin_insn, , sizeof(ret));
+return ret;
 }
 #endif
 
@@ -4473,7 +4489,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, 
int b,
 
 /* convert one instruction. s->base.is_jmp is set if the translation must
be stopped. Return the next pc value */
-static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
+static target_ulong disas_insn(DisasContext *s, CPUState *cpu,
+   struct qemu_plugin_insn *plugin_insn)
 {
 CPUX86State *env = cpu->env_ptr;
 int b, prefixes;
@@ -4484,6 +4501,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState 
*cpu)
 int rex_w, rex_r;
 target_ulong pc_start = s->base.pc_next;
 
+s->plugin_insn = plugin_insn;
+
 s->pc_start = s->pc = pc_start;
 s->override = -1;
 #ifdef TARGET_X86_64
@@ -8529,7 +8548,7 @@ static void i386_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu,
struct qemu_plugin_insn *plugin_insn)
 {
 DisasContext *dc = container_of(dcbase, DisasContext, base);
-target_ulong pc_next = disas_insn(dc, cpu);
+target_ulong pc_next = disas_insn(dc, cpu, plugin_insn);
 
 if (dc->tf || (dc->base.tb->flags & HF_INHIBIT_IRQ_MASK)) {
 /* if single step mode, we generate only one instruction and
@@ -8584,6 +8603,8 @@ static const TranslatorOps i386_tr_ops = {
 .translate_insn = i386_tr_translate_insn,
 .tb_stop= i386_tr_tb_stop,
 .disas_log  = i386_tr_disas_log,
+.ctx_base_offset= offsetof(DisasContext, base),
+.ctx_size   = sizeof(DisasContext),
 };
 
 /* generate intermediate code for basic block 'tb'.  */
-- 
2.17.1




[Qemu-devel] [RFC 45/48] plugin: lockstep execution support

2018-10-25 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 include/qemu/plugin-api.h |  7 +++
 include/qemu/plugin.h |  5 +
 cpus.c|  1 +
 plugin.c  | 35 +++
 qemu-plugins.symbols  |  3 +++
 5 files changed, 51 insertions(+)

diff --git a/include/qemu/plugin-api.h b/include/qemu/plugin-api.h
index 076353a2d2..5062e20e08 100644
--- a/include/qemu/plugin-api.h
+++ b/include/qemu/plugin-api.h
@@ -227,6 +227,13 @@ typedef int64_t (*qemu_plugin_clock_func_t)(void);
 bool qemu_plugin_register_virtual_clock(qemu_plugin_id_t id,
 qemu_plugin_clock_func_t clock);
 
+void qemu_plugin_enable_lockstep_execution(void);
+
+void qemu_plugin_register_lockstep_cb(qemu_plugin_id_t id,
+  qemu_plugin_simple_cb_t cb);
+
+void qemu_plugin_end_time_slice(void);
+
 /* returns -1 in user-mode */
 int qemu_plugin_n_vcpus(void);
 
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index 617161329f..c19071bdbe 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -58,6 +58,7 @@ enum qemu_plugin_event {
 QEMU_PLUGIN_EV_VCPU_RESUME,
 QEMU_PLUGIN_EV_VCPU_SYSCALL,
 QEMU_PLUGIN_EV_VCPU_SYSCALL_RET,
+QEMU_PLUGIN_EV_LOCKSTEP,
 QEMU_PLUGIN_EV_FLUSH,
 QEMU_PLUGIN_EV_ATEXIT,
 QEMU_PLUGIN_EV_MAX,
@@ -194,6 +195,7 @@ void qemu_plugin_atexit_cb(void);
 
 void qemu_plugin_add_dyn_cb_arr(struct qemu_plugin_dyn_cb_arr *arr);
 int64_t plugin_get_clock(void);
+void plugin_lockstep_cb(void);
 
 #else /* !CONFIG_PLUGINS */
 
@@ -237,6 +239,9 @@ static inline
 void qemu_plugin_add_dyn_cb_arr(struct qemu_plugin_dyn_cb_arr *arr)
 { }
 
+static inline void plugin_lockstep_cb(void)
+{ }
+
 int64_t plugin_get_clock(void);
 
 #endif /* !CONFIG_PLUGINS */
diff --git a/cpus.c b/cpus.c
index a446632a5c..8f490d1b11 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1359,6 +1359,7 @@ static void lockstep_check_stop(CPUState *cpu)
 /* wake up all waiting cpus */
 lockstep_ongoing_wakeup = true;
 n_lockstep_running_cpus = n_lockstep_cpus;
+plugin_lockstep_cb();
 qemu_mutex_unlock(_lock);
 cpu_mutex_unlock(cpu);
 for (i = 0; i < n_lockstep_cpus; i++) {
diff --git a/plugin.c b/plugin.c
index 291767f2bb..117f303249 100644
--- a/plugin.c
+++ b/plugin.c
@@ -472,6 +472,7 @@ static void plugin_cb__simple(enum qemu_plugin_event ev)
 
 switch (ev) {
 case QEMU_PLUGIN_EV_FLUSH:
+case QEMU_PLUGIN_EV_LOCKSTEP:
 QLIST_FOREACH_SAFE_RCU(cb, _lists[ev], entry, next) {
 qemu_plugin_simple_cb_t func = cb->f.simple;
 
@@ -1043,6 +1044,40 @@ int64_t plugin_get_clock(void)
 }
 #endif
 
+/*
+ * We manage the CPU state changes; the plugin will control the length of the
+ * execution windows.
+ */
+void qemu_plugin_enable_lockstep_execution(void)
+{
+#ifdef CONFIG_USER_ONLY
+abort();
+#else
+cpu_lockstep_enable();
+#endif
+}
+
+void qemu_plugin_end_time_slice(void)
+{
+#ifdef CONFIG_USER_ONLY
+abort();
+#else
+g_assert(current_cpu);
+cpu_lockstep_request_stop(current_cpu);
+#endif
+}
+
+void qemu_plugin_register_lockstep_cb(qemu_plugin_id_t id,
+  qemu_plugin_simple_cb_t cb)
+{
+plugin_register_cb(id, QEMU_PLUGIN_EV_LOCKSTEP, cb);
+}
+
+void plugin_lockstep_cb(void)
+{
+plugin_cb__simple(QEMU_PLUGIN_EV_LOCKSTEP);
+}
+
 static void __attribute__((__constructor__)) plugin_init(void)
 {
 int i;
diff --git a/qemu-plugins.symbols b/qemu-plugins.symbols
index 93587b07e1..a3268a40c7 100644
--- a/qemu-plugins.symbols
+++ b/qemu-plugins.symbols
@@ -1,5 +1,8 @@
 {
   qemu_plugin_uninstall;
+  qemu_plugin_enable_lockstep_execution;
+  qemu_plugin_end_time_slice;
+  qemu_plugin_register_lockstep_cb;
   qemu_plugin_register_vcpu_init_cb;
   qemu_plugin_register_vcpu_exit_cb;
   qemu_plugin_register_vcpu_idle_cb;
-- 
2.17.1




  1   2   3   >